From: Matthias Braun Date: Sat, 20 Nov 2004 22:14:40 +0000 (+0000) Subject: The BIG COMMIT(tm) X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=d46c78c842ab4090a3f46e560c891234167f124b;p=supertux.git The BIG COMMIT(tm) This is it, expect a broken supertux I only fixed the most annoying issues so far, lots more are still waiting in the TODO list, but I had to bring this stuff to cvs sometime. Changes: - Completely new collision detection scheme, which collides all objects with each other once per frame, instead of single objects manually testing for collisions - New collision detection routines which support slopes and provide additional info on collisions: penetration depth, hit normal vector - Lots of general cleanup/refactoring - Splitted the monolithic badguy class and reimplemented most of them as single classes with a badguy base class. - Splitted the monolithic Special class into several classes - Rewrote the timer and all timing related stuff to work on float and seconds (not like the mixup before where you had frame_ratio, msecs and secs in different parts of the app) - Support for unisolid tiles - Created a flying platform prototype (doesn't work completely yet) - rename InteractiveObjects to triggers and implemented a new sequence trigger, (only supported sequence is endsequence at the moment) - transformed the bonusblocks and bricks into objects SVN-Revision: 2115 --- diff --git a/.cvsignore b/.cvsignore index 48189e2e7..fcc2f0816 100644 --- a/.cvsignore +++ b/.cvsignore @@ -18,3 +18,6 @@ libtool .project .cdtproject .sconsign +build_config.py +build + diff --git a/TODO b/TODO index 89138435f..17f32ef25 100644 --- a/TODO +++ b/TODO @@ -37,7 +37,76 @@ L: low priority g++ -Wall .... -o build/linux/src/error.o src/error.cpp +--Collision Detection Rewrite (all [H])-- + * make blocks bounce again - ok + * bonusblocks don't always bounce back to their original position (but stay a + few pixels higher) + * it's impossible to go into passages that have exactly the size of tux, + either reduce collision rectangle by DELTA or round collision coordinates to + integers... + ** implement 1up - ok + ** implement star - ok + * bring back the enemies + - add activation again + - make api simpler + - implement jumpy - ok + -* implement spiky - ok + - implement snowball - ok + - implement fish + - implement bouncingsnowball - ok + -* implement mriceblock - ~ok + - implement flame - ok + -* implement mrbomb - ok + - implement flyingsnowball + - implement wingling + - implement tree (really?) + - bring back stay on platform flag + - make enemies bounce of upon each other again + - make enemies fall again + -* activate/deactive enemies when on screen/away again - ok + ** implement ability to cary mriceblock (and other objects) around - delayed + for after big commit... + * smoke clouds are too fast + * some shots disappear in the ground with a "max collision depth reached" + message + * rework collision detection to take movement into account - this should fix + the egg suddenly turning directions and the somtimes strange behaviour + when hitting a block from the side when falling. + * rethink slopes collision feedback... tux becomes too slow when walking up + and starts jumping when walking down + * think about an attachement mechanism for moving platforms + * implement paths for the moving platform, implement simple moving platforms + ** activate level end sequence again - ok + ** make bullets kill enemies - ok + * fix bullet speed/behaviour + ** fix ducking - ok + * check if unducking is actually possible or if something is in the way + * fix flapping + ** having a star doesn't kill enemies - ok + +--Code Refactoring/Cleanup/Optimisation-- +[H] make the title using GameSession instead of reimplementing all the stuff +[L] rename gameloop.* files to gamesession.* +[L] rename GameObject::action to GameObject::update() +[L] use physfs for loading files +[L] eventually move over new lispreader code from tuxkart +[L] change physics class y-velocity-coordinate to be like all other + y-coordinates again (positive y to go down) +[M] harmonize to 1 single gameloop that switches between title, worldmap, + ingame mode and eventually leveleditor mode +[H] introduce a special mode in DrawingContext for objects that want to draw + themselfes. This could speed up rendering of tilemaps. +[H] implement quadtree to speed up collision detection +[?] remove badguyspecs and bitmask files + --Miscelaneous-- +[?] think about how to implement scripting, and how to make a simple and easy to + use api for the scripting interface + (language will probably be lua - just have to figure out how well we can do + without OO support in the scripting language. + Other candidates are python, ruby and less likely java, mono/.net, + surely no own invention, perl or 1 of these c-like scripting languages) + [?] Default keyboard setup should change. Up will be needed for other features like going through doors and looking up, etc. Up arrow - Look up / activate diff --git a/config.h.in b/config.h.in deleted file mode 100644 index 3354d9542..000000000 --- a/config.h.in +++ /dev/null @@ -1,276 +0,0 @@ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP - systems. This function is required for `alloca.c' support on those systems. - */ -#undef CRAY_STACKSEG_END - -/* Define to 1 if using `alloca.c'. */ -#undef C_ALLOCA - -/* Define to 1 if translation of program messages to the user's native - language is requested. */ -#undef ENABLE_NLS - -/* Define to 1 if you have `alloca', as a function or macro. */ -#undef HAVE_ALLOCA - -/* Define to 1 if you have and it should be used (not on Ultrix). - */ -#undef HAVE_ALLOCA_H - -/* Use the Apple OpenGL framework. */ -#undef HAVE_APPLE_OPENGL_FRAMEWORK - -/* Define to 1 if you have the header file. */ -#undef HAVE_ARGZ_H - -/* Define if the GNU dcgettext() function is already present or preinstalled. - */ -#undef HAVE_DCGETTEXT - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -#undef HAVE_DIRENT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_DLFCN_H - -/* Define to 1 if you have the `feof_unlocked' function. */ -#undef HAVE_FEOF_UNLOCKED - -/* Define to 1 if you have the `fgets_unlocked' function. */ -#undef HAVE_FGETS_UNLOCKED - -/* Define to 1 if you have the `getcwd' function. */ -#undef HAVE_GETCWD - -/* Define to 1 if you have the `getc_unlocked' function. */ -#undef HAVE_GETC_UNLOCKED - -/* Define to 1 if you have the `getegid' function. */ -#undef HAVE_GETEGID - -/* Define to 1 if you have the `geteuid' function. */ -#undef HAVE_GETEUID - -/* Define to 1 if you have the `getgid' function. */ -#undef HAVE_GETGID - -/* Define to 1 if you have the `getpagesize' function. */ -#undef HAVE_GETPAGESIZE - -/* Define if the GNU gettext() function is already present or preinstalled. */ -#undef HAVE_GETTEXT - -/* Define to 1 if you have the `getuid' function. */ -#undef HAVE_GETUID - -/* Define if you have the iconv() function. */ -#undef HAVE_ICONV - -/* Define if exists and doesn't clash with . */ -#undef HAVE_INTTYPES_H - -/* Define if exists, doesn't clash with , and - declares uintmax_t. */ -#undef HAVE_INTTYPES_H_WITH_UINTMAX - -/* Define if you have and nl_langinfo(CODESET). */ -#undef HAVE_LANGINFO_CODESET - -/* Define if your file defines LC_MESSAGES. */ -#undef HAVE_LC_MESSAGES - -/* Define to 1 if you have the `SDL_image' library (-lSDL_image). */ -#undef HAVE_LIBSDL_IMAGE - -/* Define to 1 if you have the `SDL_mixer' library (-lSDL_mixer). */ -#undef HAVE_LIBSDL_MIXER - -/* Define to 1 if you have the `z' library (-lz). */ -#undef HAVE_LIBZ - -/* Define to 1 if you have the header file. */ -#undef HAVE_LIMITS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_LOCALE_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_MALLOC_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_MEMORY_H - -/* Define to 1 if you have the `mempcpy' function. */ -#undef HAVE_MEMPCPY - -/* Define to 1 if you have the `mkdir' function. */ -#undef HAVE_MKDIR - -/* Define to 1 if you have a working `mmap' system call. */ -#undef HAVE_MMAP - -/* Define to 1 if you have the `munmap' function. */ -#undef HAVE_MUNMAP - -/* Define to 1 if you have the header file, and it defines `DIR'. */ -#undef HAVE_NDIR_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_NL_TYPES_H - -/* Define if you have POSIX threads libraries and header files. */ -#undef HAVE_PTHREAD - -/* Define to 1 if you have the `putenv' function. */ -#undef HAVE_PUTENV - -/* Define to 1 if you have the `setenv' function. */ -#undef HAVE_SETENV - -/* Define to 1 if you have the `setlocale' function. */ -#undef HAVE_SETLOCALE - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDDEF_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define if exists, doesn't clash with , and declares - uintmax_t. */ -#undef HAVE_STDINT_H_WITH_UINTMAX - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the `stpcpy' function. */ -#undef HAVE_STPCPY - -/* Define to 1 if you have the `strcasecmp' function. */ -#undef HAVE_STRCASECMP - -/* Define to 1 if you have the `strdup' function. */ -#undef HAVE_STRDUP - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the `strstr' function. */ -#undef HAVE_STRSTR - -/* Define to 1 if you have the `strtoul' function. */ -#undef HAVE_STRTOUL - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -#undef HAVE_SYS_DIR_H - -/* Define to 1 if you have the header file, and it defines `DIR'. - */ -#undef HAVE_SYS_NDIR_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_PARAM_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the `tsearch' function. */ -#undef HAVE_TSEARCH - -/* Define if you have the 'uintmax_t' type in or . */ -#undef HAVE_UINTMAX_T - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H - -/* Define if you have the unsigned long long type. */ -#undef HAVE_UNSIGNED_LONG_LONG - -/* Define to 1 if you have the header file. */ -#undef HAVE_WINDOWS_H - -/* Define to 1 if you have the `__argz_count' function. */ -#undef HAVE___ARGZ_COUNT - -/* Define to 1 if you have the `__argz_next' function. */ -#undef HAVE___ARGZ_NEXT - -/* Define to 1 if you have the `__argz_stringify' function. */ -#undef HAVE___ARGZ_STRINGIFY - -/* Define to 1 if you have the `__fsetlocking' function. */ -#undef HAVE___FSETLOCKING - -/* Define as const if the declaration of iconv() needs const. */ -#undef ICONV_CONST - -/* Define if integer division by zero raises signal SIGFPE. */ -#undef INTDIV0_RAISES_SIGFPE - -/* Name of package */ -#undef PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* Define if exists and defines unusable PRI* macros. */ -#undef PRI_MACROS_BROKEN - -/* Define to the necessary symbol if this constant uses a non-standard name on - your system. */ -#undef PTHREAD_CREATE_JOINABLE - -/* If using the C implementation of alloca, define if you know the - direction of stack growth for your system; otherwise it will be - automatically deduced at run-time. - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown */ -#undef STACK_DIRECTION - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* Version number of package */ -#undef VERSION - -/* Define to empty if `const' does not conform to ANSI C. */ -#undef const - -/* Define to `__inline__' or `__inline' if that's what the C compiler - calls it, or to nothing if 'inline' is not supported under any name. */ -#ifndef __cplusplus -#undef inline -#endif - -/* Define to `long' if does not define. */ -#undef off_t - -/* Define to `unsigned' if does not define. */ -#undef size_t - -/* Define to unsigned long or unsigned long long if and - don't define. */ -#undef uintmax_t diff --git a/configure.ac b/configure.ac index 61345ae58..f56ec9876 100644 --- a/configure.ac +++ b/configure.ac @@ -18,7 +18,10 @@ AC_CANONICAL_TARGET AM_INIT_AUTOMAKE dnl This is obsolete see automake1.7 // AM_CONFIG_HEADER -SDL_VERSION=1.2.4 +# we don't want the stupid autoconf default -g -O2 +test ".$CXXFLAGS" = "." && CXXFLAGS=" " + +CXXFLAGS="$CXXFLAGS -ffast-math" AC_PROG_CC AC_PROG_CXX @@ -40,7 +43,7 @@ AC_MSG_CHECKING(for gprof mode) AC_ARG_ENABLE(gprof, AC_HELP_STRING([--enable-gprof], [enable GNU profiling support]), [enable_gprof=$enableval], [enable_gprof=no]) -if test "$enable_gprof" = "no"; then +if test "$enable_gprof" = "yes"; then CXXFLAGS="$CXXFLAGS -pg" AC_MSG_RESULT([enabled]) else @@ -52,9 +55,11 @@ AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug], [enable debugging mode]), [enable_debug=$enableval], [enable_debug=no]) if test "$enable_debug" = "yes"; then - CXXFLAGS="$CXXFLAGS -Wall -Werror -DDEBUG -O0 -g3" + AC_DEFINE([DEBUG], 1, [define to compile in debug checks]) + CXXFLAGS="$CXXFLAGS -Wall -Werror -O0 -g3" AC_MSG_RESULT([enabled]) else + CXXFLAGS="$CXXFLAGS -O2 -g" AC_MSG_RESULT([disabled]) fi @@ -72,6 +77,7 @@ AM_GNU_GETTEXT dnl =========================================================================== dnl Check for SDL +SDL_VERSION=1.2.4 AM_PATH_SDL($SDL_VERSION, :, AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!])) diff --git a/data/images/supertux.strf b/data/images/supertux.strf index f153997af..a14eec12a 100644 --- a/data/images/supertux.strf +++ b/data/images/supertux.strf @@ -783,9 +783,9 @@ ;; Bad Guys follow - ;; Laptop + ;; MrIceBlock (sprite (name "mriceblock") - (action + (action (name "left") (x-offset 2) (y-offset 3) @@ -794,27 +794,27 @@ "shared/mriceblock-left-2.png" "shared/mriceblock-left-1.png")) - (action (name "right") + (action (name "right") (x-offset 2) (y-offset 3) (mirror-action "left")) - (action (name "falling-left") + (action (name "falling-left") (x-offset 2) (y-offset 3) (images "shared/mriceblock-flat-left.png")) - (action (name "falling-right") + (action (name "falling-right") (x-offset 2) (y-offset 3) (mirror-action "falling-left")) - (action (name "flat-left") + (action (name "flat-left") (x-offset 2) (y-offset 3) (images "shared/mriceblock-flat-left.png")) - (action (name "flat-right") + (action (name "flat-right") (x-offset 2) (y-offset 3) (mirror-action "falling-left"))) @@ -1162,10 +1162,79 @@ ; Door (sprite (name "door") (action + (name "default") (x-offset 0) (y-offset 64) - (images "shared/door-1.png") - )) + (images "shared/door-1.png")) + (action + (name "open") + (x-offset 0) + (y-offset 64) + (images "shared/door-1.png" + "shared/door-2.png" + "shared/door-3.png" + "shared/door-4.png" + "shared/door-5.png" + "shared/door-6.png" + "shared/door-7.png" + "shared/door-8.png" + "shared/door-7.png" + "shared/door-6.png" + "shared/door-5.png" + "shared/door-4.png" + "shared/door-3.png" + "shared/door-2.png" + "shared/door-1.png")) + ) + + ; coin + (sprite (name "coin") + (action + (name "default") + (images "tilesets/coin-1.png" + "tilesets/coin-2.png" + "tilesets/coin-3.png" + "tilesets/coin-4.png" + "tilesets/coin-5.png" + "tilesets/coin-6.png" + "tilesets/coin-7.png" + "tilesets/coin-8.png")) + (action + (name "still") + (images "tilesets/coin-1.png")) + ) + + (sprite (name "bonusblock") + (action + (name "default") + (images "tilesets/bonus2-1.png" + "tilesets/bonus2-2.png" + "tilesets/bonus2-3.png" + "tilesets/bonus2-4.png" + "tilesets/bonus2-5.png")) + (action + (name "empty") + (images "tilesets/bonus2-d.png")) + ) + + (sprite (name "brick") + (action + (name "empty") + (images "tilesets/bonus2-d.png")) + (action + (name "default") + (images "tilesets/brick0.png")) + ) + + (sprite (name "icedbrick") + (action + (name "empty") + (images "tilesets/bonus2-d.png")) + (action + (name "default") + (images "tilesets/brick1.png")) + ) + ; (sprite (name "openingdoor") ; (action ; (x-offset 0) diff --git a/data/images/tilesets/supertux.stgt b/data/images/tilesets/supertux.stgt index 91adf1580..c8d1cee50 100644 --- a/data/images/tilesets/supertux.stgt +++ b/data/images/tilesets/supertux.stgt @@ -23,7 +23,7 @@ (tilegroup (name "Waterfall") (tiles 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294)) (tilegroup (name "Waterfall-edgecloud") (tile 195 196 197 198 199)) (tile (id 0) - (images "notile.png")) + (editor-images "bonus-fireflower.png")) (tile (id 1) (solid #t) @@ -991,15 +991,18 @@ (tile (id 360) (images "mushrooms.png")) + (tile (id 359) + (unisolid #t) + (images "snow11.png")) ; Slopes - (tile (id 400) - (slope-angle 45) - (images "slope-right.png")) (tile (id 401) - (slope-angle 135) + (slope-type 0) (images "slope-left.png")) + (tile (id 400) + (slope-type 2) + (images "slope-right.png")) ) diff --git a/data/levels/contribs/level2.stl b/data/levels/contribs/level2.stl index c2c11c8e7..2017a92eb 100644 --- a/data/levels/contribs/level2.stl +++ b/data/levels/contribs/level2.stl @@ -1,128 +1,7 @@ -;SuperTux-Level +; Level made using SuperTux's built-in Level Editor (supertux-level - (version 1) - (name "Steamy mountain") - (author "NetsRot") - (music "Mortimers_chipdisko.mod") - (background "cave2.jpg") - (particle_system "clouds") - (bkgd_speed 50) - (bkgd_red_top 0) - (bkgd_green_top 0) - (bkgd_blue_top 0) - (bkgd_red_bottom 255) - (bkgd_green_bottom 255) - (bkgd_blue_bottom 255) - (time 150) - (width 450) - (back_scrolling #f) - (hor_autoscroll_speed 0.0) - (gravity 10.0) - (background-tm 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 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 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 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 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 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 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 17 17 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 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 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 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 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 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 17 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 0 0 0 0 130 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 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 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 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 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 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 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 0 129 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 293 294 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 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 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 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 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 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 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 129 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 291 292 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 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 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 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 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 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 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 129 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 289 290 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 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 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 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 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 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 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 129 0 0 0 0 0 0 0 279 279 279 279 0 0 0 0 0 0 0 0 17 17 0 0 0 0 0 0 0 0 0 0 0 287 288 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 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 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 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 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 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 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 129 0 0 0 0 0 0 0 279 279 279 279 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 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 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 279 279 279 0 0 0 0 0 0 0 0 0 279 279 279 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 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 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 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 129 0 0 0 0 0 0 0 279 279 279 279 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 0 0 0 0 0 0 0 0 0 0 0 0 8 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 16 18 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 279 279 279 0 0 0 0 0 0 0 0 0 279 279 279 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 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 76 76 76 76 76 76 76 76 76 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 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 0 129 0 0 0 0 0 0 0 279 279 279 279 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 76 0 0 0 0 0 0 76 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 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 279 279 279 0 0 0 0 0 0 0 0 0 279 279 279 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 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 75 75 75 75 75 75 75 75 75 0 76 0 0 0 0 76 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 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 129 8 0 0 0 0 0 0 279 279 279 279 0 0 0 0 0 0 0 0 8 8 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 75 0 0 0 0 0 0 75 76 0 0 0 0 0 0 76 76 0 0 0 76 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 76 0 0 0 0 76 0 76 0 0 0 0 0 76 0 0 76 0 0 0 0 76 76 0 0 0 76 0 76 0 0 76 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 279 279 279 0 0 0 0 0 0 0 0 0 279 279 279 0 0 0 0 0 0 0 0 0 0 76 0 0 0 0 0 0 0 76 0 0 76 0 0 0 0 76 0 76 0 0 0 0 76 0 76 0 0 0 76 76 0 0 0 0 0 76 0 0 76 0 0 0 76 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 75 0 0 0 0 75 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 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 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 75 0 0 0 0 0 0 75 75 0 0 0 0 0 0 75 75 0 0 0 75 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 75 0 0 0 0 75 0 75 0 0 0 0 0 75 0 0 75 0 0 0 0 75 75 0 0 0 75 0 75 0 0 75 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 279 279 279 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 75 0 0 0 0 0 0 0 75 0 0 75 0 0 0 0 75 0 75 0 0 0 0 75 0 75 0 0 0 75 75 0 0 0 0 0 75 0 0 75 0 0 0 75 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 75 0 0 0 0 75 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 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ) - (interactive-tm 12 0 0 0 0 0 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 21 8 9 0 7 8 8 22 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 21 8 8 9 0 7 8 8 8 8 8 8 8 9 0 0 0 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 12 0 0 0 0 0 10 11 11 11 30 17 17 17 17 17 17 17 17 0 0 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 31 11 30 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 31 11 11 11 11 11 20 14 15 128 13 14 14 23 11 30 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 31 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 30 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 31 20 14 14 15 102 13 14 14 14 14 14 14 14 15 0 0 0 10 11 11 11 11 11 11 30 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 31 11 11 11 11 11 11 11 11 11 30 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 31 11 11 11 11 11 11 11 11 11 30 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 17 133 17 17 17 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 12 0 0 0 0 0 10 11 11 11 12 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 10 11 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 83 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 10 11 11 11 30 17 17 17 18 0 16 17 17 17 17 18 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 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 16 17 17 17 18 0 16 17 17 17 17 17 17 17 18 0 0 0 16 17 17 17 17 17 17 18 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 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 10 11 11 11 11 11 11 11 11 11 12 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 10 11 11 11 11 11 11 11 11 11 12 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 128 0 0 0 0 0 0 0 0 0 0 0 133 0 0 0 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 12 0 0 0 0 0 10 11 11 11 12 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 83 83 83 83 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 10 11 12 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 10 11 11 11 12 0 0 0 0 0 0 0 0 0 0 44 44 44 44 44 44 44 44 44 0 0 0 0 0 0 0 0 0 105 105 83 0 0 0 0 0 0 0 0 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 12 103 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 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 0 0 0 0 0 0 0 0 0 10 11 11 11 11 11 11 11 11 11 12 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 10 11 11 11 11 30 17 17 17 17 18 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 133 0 0 0 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 12 0 0 0 0 0 10 11 11 11 12 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 7 8 8 8 8 8 8 9 0 0 0 10 11 12 0 0 0 7 8 8 8 83 8 8 8 8 8 9 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 10 11 11 11 12 0 0 0 0 0 0 0 0 0 0 27 28 28 28 28 28 28 28 29 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 12 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 0 0 0 0 0 27 28 28 28 28 28 28 28 28 29 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 16 17 17 17 17 17 17 17 17 17 18 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 10 11 11 11 11 12 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 133 0 0 0 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 12 0 0 0 0 0 10 11 11 11 12 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 13 14 14 14 14 14 14 15 0 0 0 10 11 12 0 0 0 13 14 14 14 14 14 14 14 14 14 15 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 10 11 11 11 12 0 0 0 83 83 83 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 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 12 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 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 27 28 28 28 28 28 28 29 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 47 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 16 17 17 17 17 18 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 48 48 0 0 0 0 0 0 47 0 47 0 47 0 47 0 0 0 0 0 0 0 0 0 0 0 133 0 0 0 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 12 0 0 0 0 0 16 17 17 17 18 0 83 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 7 8 8 8 8 8 8 8 8 9 0 0 0 0 0 0 0 0 0 0 0 0 10 11 11 11 11 11 11 12 0 0 0 10 11 12 0 0 0 16 17 17 31 30 17 17 17 17 31 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 27 28 28 28 28 28 29 0 0 0 0 0 16 17 17 17 18 0 0 0 0 0 0 0 0 0 0 0 0 0 0 83 0 0 0 0 0 0 0 0 0 7 8 8 8 8 8 8 8 9 0 0 0 0 0 0 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 12 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 83 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 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 47 0 0 0 47 0 0 0 0 0 0 0 0 47 0 47 0 47 0 27 28 28 28 28 28 28 28 28 28 28 29 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 104 104 102 104 104 104 104 104 0 0 0 0 0 0 0 0 0 0 48 48 48 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 133 0 0 0 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 12 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 13 14 14 14 14 14 14 14 14 15 0 0 0 0 0 0 0 0 7 8 8 8 22 30 17 17 17 17 31 12 0 0 0 10 11 21 8 8 9 0 0 0 10 12 0 0 0 0 10 12 0 0 27 28 28 28 28 28 28 29 0 0 0 0 0 27 28 28 28 29 0 0 0 0 0 0 44 44 44 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 13 14 14 14 14 14 14 14 15 0 0 0 0 0 0 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 12 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 83 83 83 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 44 44 44 44 0 0 0 0 0 0 0 0 27 28 28 28 28 28 28 28 29 0 0 0 0 47 0 47 0 47 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 48 48 48 0 0 0 0 0 0 0 0 83 104 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 48 48 48 48 0 0 0 0 0 44 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 133 0 0 0 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 12 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 7 8 8 8 8 8 22 11 11 11 11 11 11 11 11 12 0 0 0 0 0 0 0 0 13 14 14 14 23 12 44 44 0 0 16 18 0 0 0 10 11 20 14 14 15 0 0 0 10 12 0 0 0 0 10 12 0 0 0 0 0 44 44 44 0 0 0 0 0 0 0 0 44 44 44 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 10 11 11 11 11 11 11 11 12 0 0 0 0 0 0 10 11 11 11 11 30 17 17 17 17 17 17 17 31 11 11 11 12 83 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 7 8 8 9 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 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 44 44 44 44 0 7 8 9 0 0 0 0 0 0 0 44 44 44 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 48 48 48 48 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 48 48 48 48 48 0 0 0 0 0 44 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 133 0 0 0 16 17 17 17 17 17 17 17 17 17 17 17 17 17 17 132 132 17 17 17 17 21 8 8 8 8 8 8 8 8 8 8 8 9 0 0 0 0 0 0 7 9 0 0 0 0 0 0 0 0 0 0 0 13 14 14 14 14 14 23 11 11 11 11 11 11 11 11 21 8 8 8 8 8 8 8 102 22 11 11 11 11 12 44 44 0 0 0 0 0 0 0 16 17 17 17 17 18 0 0 0 10 12 0 0 0 0 10 12 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 7 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 9 0 0 0 0 0 0 0 0 0 0 10 11 11 11 11 11 11 11 12 0 0 0 0 0 0 10 11 11 11 11 12 0 0 0 0 0 0 0 10 11 11 11 12 0 0 0 0 0 0 7 8 8 9 0 0 0 0 0 0 0 13 14 14 15 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 27 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 29 0 7 8 8 9 0 0 0 0 0 0 0 13 14 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 47 0 47 0 47 0 47 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 48 48 48 48 48 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 48 48 48 48 48 48 0 0 0 0 0 44 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 133 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 132 132 0 0 0 0 20 14 14 14 14 14 14 14 14 14 14 14 15 0 0 0 0 0 0 13 15 0 0 0 0 0 0 0 0 0 0 0 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 20 14 14 14 14 14 14 14 14 23 11 11 11 11 12 44 44 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 12 0 0 0 0 10 12 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 13 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 15 0 0 0 0 0 0 0 0 0 102 10 11 11 11 11 11 11 11 12 0 0 0 0 0 0 16 17 17 17 17 18 0 0 0 0 0 0 0 16 17 17 17 18 0 0 0 0 0 0 13 14 14 15 0 0 0 0 0 0 0 10 11 11 12 0 0 0 0 7 8 9 0 0 0 0 7 8 9 0 0 0 7 9 0 0 0 0 0 7 8 8 9 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 13 14 14 15 0 0 0 0 0 0 0 10 11 12 0 0 0 0 7 8 8 8 8 8 8 8 8 9 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 47 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 48 48 48 48 48 48 0 0 0 0 83 104 83 104 0 0 0 0 0 0 83 83 83 83 83 83 83 83 0 0 0 0 0 0 48 48 48 48 48 48 48 0 0 0 0 0 44 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 133 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 132 132 0 0 0 0 11 11 11 11 11 11 11 11 11 11 11 11 12 0 0 0 0 0 0 10 12 0 0 0 0 0 0 0 0 0 0 0 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 21 44 44 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 22 21 128 8 8 8 8 8 8 8 8 9 0 0 0 0 7 8 9 0 0 0 0 0 7 8 8 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 12 0 0 0 0 0 0 0 0 0 0 10 11 11 11 11 11 11 11 12 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 10 11 11 12 0 0 0 0 0 0 0 10 11 11 12 0 0 0 0 13 14 15 0 0 0 0 13 14 15 0 0 0 13 15 0 0 0 0 0 13 14 14 15 0 0 0 7 8 8 8 9 0 0 44 44 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 10 11 11 12 0 0 0 0 0 0 0 10 11 12 0 0 0 0 13 14 14 14 14 14 14 14 14 15 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 48 48 48 48 48 48 48 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 48 48 48 48 48 48 48 48 0 0 0 0 0 44 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 133 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 132 132 0 0 0 0 11 11 11 11 11 11 11 11 11 11 11 11 12 76 76 76 76 76 76 10 12 0 0 0 0 0 0 7 9 0 0 0 10 11 11 11 19 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 115 116 11 20 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 23 20 14 14 14 14 14 14 14 14 14 15 0 0 0 0 13 14 15 0 0 0 0 0 13 14 14 15 0 0 0 0 7 9 0 0 0 7 8 9 0 0 10 11 11 11 11 11 11 11 11 11 11 11 11 11 19 11 11 11 11 11 12 0 0 0 0 0 0 0 0 0 0 10 11 11 11 11 11 11 11 12 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 10 11 11 12 0 0 0 0 0 0 0 10 11 11 12 0 0 0 0 10 11 12 0 0 0 0 10 11 12 0 0 0 10 12 0 0 0 0 0 10 11 11 12 0 0 0 13 14 14 14 15 0 0 0 0 0 0 0 0 0 0 0 0 0 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 0 0 0 10 11 11 21 8 8 8 8 8 8 8 22 11 12 76 76 76 76 10 11 11 11 11 11 11 11 11 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 47 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 48 48 48 48 48 48 48 48 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 48 48 48 48 48 48 48 48 48 9 0 0 0 0 47 0 0 0 0 47 0 47 0 47 0 0 7 8 8 8 8 8 8 133 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 8 132 132 8 8 8 8 11 11 11 11 11 11 11 11 11 11 11 11 12 75 75 75 75 75 75 10 12 76 76 76 76 76 76 13 15 76 76 76 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 117 118 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 12 76 76 76 76 10 11 12 76 76 76 76 76 10 11 11 12 76 76 76 76 13 15 76 76 76 13 14 15 76 76 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 21 8 8 8 8 8 8 8 8 8 8 22 11 11 11 11 11 11 11 12 0 0 0 0 7 8 9 0 0 0 0 0 7 8 8 8 8 8 8 8 8 8 8 8 8 9 0 0 0 0 10 11 11 12 76 76 76 76 76 76 76 10 11 11 12 76 76 76 76 10 11 12 76 76 76 76 10 11 12 76 76 76 10 12 76 76 76 76 76 10 11 11 12 76 76 76 10 11 11 11 12 0 0 0 0 0 0 0 0 0 0 0 0 0 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 44 0 0 0 10 11 11 20 14 14 14 14 14 14 14 23 11 12 75 75 75 75 10 11 11 11 11 11 11 11 11 12 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 13 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 15 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 13 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 11 11 11 11 11 11 11 11 11 11 11 11 12 75 75 75 75 75 75 10 12 75 75 75 75 75 75 10 12 75 75 75 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 12 75 75 75 75 10 11 12 75 75 75 75 75 10 11 11 12 75 75 75 75 10 12 75 75 75 10 11 12 75 75 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 20 14 14 14 14 14 14 14 14 14 14 23 11 11 11 11 11 11 11 12 0 0 0 0 13 14 15 0 0 0 0 0 13 14 14 14 14 14 14 14 14 14 14 14 14 15 0 0 0 0 10 11 11 12 75 75 75 75 75 75 75 10 11 11 12 75 75 75 75 10 11 12 75 75 75 75 10 11 12 75 75 75 10 12 75 75 75 75 75 10 11 11 12 75 75 75 10 11 11 11 12 0 0 0 0 0 0 0 0 0 0 0 0 0 47 0 47 0 47 0 47 0 47 0 47 0 47 0 47 0 47 0 47 0 47 0 47 0 47 0 47 10 11 11 11 11 11 11 11 11 11 11 11 11 12 75 75 75 75 10 11 11 11 11 11 11 11 11 12 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 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 12 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 10 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 11 ) - (foreground-tm 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 132 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 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 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 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 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 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 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 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 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 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 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 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 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 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 0 0 0 0 0 130 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 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 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 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 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 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 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 0 129 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 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 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 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 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 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 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 0 129 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 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 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 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 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 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 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 0 129 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 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 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 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 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 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 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 0 129 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 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 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 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 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 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 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 0 129 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 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 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 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 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 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 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 0 129 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 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 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 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 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 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 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 0 129 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 ) -(reset-points -) -(objects -(mrbomb (x 1760) (y 224) (stay-on-platform #f)) -(mriceblock (x 1579) (y 196) (stay-on-platform #f)) -(mriceblock (x 2047) (y 91) (stay-on-platform #t)) -(spiky (x 1441) (y 156) (stay-on-platform #f)) -(flyingsnowball (x 2387) (y 83) (stay-on-platform #f)) -(snowball (x 4441) (y 199) (stay-on-platform #t)) -(fish (x 765) (y 363) (stay-on-platform #f)) -(fish (x 959) (y 358) (stay-on-platform #f)) -(flyingsnowball (x 3215) (y 105) (stay-on-platform #f)) -(jumpy (x 4676) (y 277) (stay-on-platform #f)) -(jumpy (x 4738) (y 327) (stay-on-platform #f)) -(mrbomb (x 3756) (y 126) (stay-on-platform #t)) -(mrbomb (x 3673) (y 127) (stay-on-platform #t)) -(jumpy (x 5636) (y 316) (stay-on-platform #f)) -(jumpy (x 5710) (y 314) (stay-on-platform #f)) -(jumpy (x 5581) (y 307) (stay-on-platform #f)) -(jumpy (x 5394) (y -32) (stay-on-platform #f)) -(jumpy (x 5394) (y -32) (stay-on-platform #f)) -(mrbomb (x 2846) (y 313) (stay-on-platform #f)) -(mrbomb (x 2714) (y 292) (stay-on-platform #f)) -(mrbomb (x 2985) (y 118) (stay-on-platform #f)) -(fish (x 3513) (y 342) (stay-on-platform #f)) -(flyingsnowball (x 5334) (y 219) (stay-on-platform #f)) -(flyingsnowball (x 5266) (y 264) (stay-on-platform #f)) -(flyingsnowball (x 5210) (y 325) (stay-on-platform #f)) -(mriceblock (x 5376) (y -32) (stay-on-platform #f)) -(fish (x 6310) (y 213) (stay-on-platform #f)) -(fish (x 6372) (y 280) (stay-on-platform #f)) -(fish (x 6437) (y 355) (stay-on-platform #f)) -(fish (x 6644) (y 323) (stay-on-platform #f)) -(fish (x 6703) (y 257) (stay-on-platform #f)) -(fish (x 6872) (y 322) (stay-on-platform #f)) -(fish (x 6929) (y 293) (stay-on-platform #f)) -(fish (x 7109) (y 302) (stay-on-platform #f)) -(jumpy (x 7187) (y 232) (stay-on-platform #f)) -(flyingsnowball (x 7561) (y 184) (stay-on-platform #f)) -(flyingsnowball (x 7640) (y 186) (stay-on-platform #f)) -(snowball (x 7650) (y 315) (stay-on-platform #t)) -(snowball (x 7728) (y 305) (stay-on-platform #t)) -(jumpy (x 6582) (y 166) (stay-on-platform #f)) -(flyingsnowball (x 6834) (y 161) (stay-on-platform #f)) -(flyingsnowball (x 6057) (y 174) (stay-on-platform #f)) -(flyingsnowball (x 6004) (y 219) (stay-on-platform #f)) -(bouncingsnowball (x 8217) (y 207) (stay-on-platform #f)) -(snowball (x 8615) (y 229) (stay-on-platform #f)) -(snowball (x 9353) (y 306) (stay-on-platform #f)) -(snowball (x 9291) (y 310) (stay-on-platform #f)) -(snowball (x 9234) (y 310) (stay-on-platform #f)) -(snowball (x 8680) (y 230) (stay-on-platform #f)) -(snowball (x 8749) (y 232) (stay-on-platform #f)) -(snowball (x 8826) (y 238) (stay-on-platform #f)) -(snowball (x 8885) (y 238) (stay-on-platform #f)) -(snowball (x 8787) (y 234) (stay-on-platform #f)) -(jumpy (x 8981) (y 179) (stay-on-platform #f)) -(jumpy (x 8924) (y 152) (stay-on-platform #f)) -(flyingsnowball (x 9087) (y 120) (stay-on-platform #f)) -(flyingsnowball (x 7911) (y 385) (stay-on-platform #f)) -(flyingsnowball (x 7984) (y 388) (stay-on-platform #f)) -(flyingsnowball (x 8060) (y 392) (stay-on-platform #f)) -(flyingsnowball (x 8126) (y 389) (stay-on-platform #f)) -(bouncingsnowball (x 8367) (y 210) (stay-on-platform #f)) -(spiky (x 8211) (y 74) (stay-on-platform #t)) -(spiky (x 8431) (y 72) (stay-on-platform #t)) -(fish (x 9524) (y 315) (stay-on-platform #f)) -(fish (x 9585) (y 312) (stay-on-platform #f)) -(snowball (x 9755) (y 166) (stay-on-platform #t)) -(snowball (x 9837) (y 173) (stay-on-platform #t)) -(snowball (x 9689) (y 168) (stay-on-platform #t)) -(flyingsnowball (x 9971) (y 140) (stay-on-platform #f)) -(flyingsnowball (x 10229) (y 214) (stay-on-platform #f)) -(mrbomb (x 11411) (y 136) (stay-on-platform #t)) -(mrbomb (x 11482) (y 139) (stay-on-platform #t)) -(mriceblock (x 9822) (y 288) (stay-on-platform #t)) -(flyingsnowball (x 2766) (y 74) (stay-on-platform #f)) -(mriceblock (x 2209) (y 276) (stay-on-platform #f)) -(spiky (x 1371) (y 163) (stay-on-platform #f)) -(mriceblock (x 5078) (y 153) (stay-on-platform #t)) -(stalactite (x 625) (y 37) (stay-on-platform #f)) -(stalactite (x 2513) (y 199) (stay-on-platform #f)) -(stalactite (x 5203) (y 36) (stay-on-platform #f)) -(stalactite (x 10722) (y 37) (stay-on-platform #f)) -(stalactite (x 11012) (y 39) (stay-on-platform #f)) -(stalactite (x 11073) (y 35) (stay-on-platform #f)) -(stalactite (x 11139) (y 36) (stay-on-platform #f)) -(stalactite (x 11202) (y 38) (stay-on-platform #f)) -(stalactite (x 11266) (y 36) (stay-on-platform #f)) -(stalactite (x 11331) (y 37) (stay-on-platform #f)) -(stalactite (x 11395) (y 36) (stay-on-platform #f)) -(stalactite (x 11457) (y 36) (stay-on-platform #f)) -(stalactite (x 11521) (y 36) (stay-on-platform #f)) -(snowball (x 12013) (y 352) (stay-on-platform #f)) -(snowball (x 12105) (y 352) (stay-on-platform #f)) -(snowball (x 12194) (y 370) (stay-on-platform #f)) -(snowball (x 12239) (y 260) (stay-on-platform #t)) -(snowball (x 12319) (y 263) (stay-on-platform #t)) -(mrbomb (x 11903) (y 276) (stay-on-platform #t)) -(mrbomb (x 12275) (y 127) (stay-on-platform #t)) -(spiky (x 12794) (y 99) (stay-on-platform #f)) -(fish (x 3218) (y 327) (stay-on-platform #f)) -(fish (x 3856) (y 306) (stay-on-platform #f)) -) + (version 2) + (name "noname") + (author "mr. x") + (time 500) ) diff --git a/data/levels/test/level7.stl b/data/levels/test/level7.stl index 8a4473055..9e0d41f85 100644 --- a/data/levels/test/level7.stl +++ b/data/levels/test/level7.stl @@ -1,7 +1,7 @@ ;SuperTux level made using the built-in leveleditor (supertux-level (version 1) - (name "Fire Test") + (name "Slope/Platform Test") (author "Ingo Ruhnke") (music "Mortimers_chipdisko.mod") (background "") @@ -77,5 +77,6 @@ (fish (x 1726) (y 243) (stay-on-platform #f)) (spiky (x 1398) (y 315) (stay-on-platform #f)) (flyingsnowball (x 1490) (y 267) (stay-on-platform #f)) + (platform (x 50) (y 100)) ) ) diff --git a/data/levels/world1/level4.stl b/data/levels/world1/level4.stl index f48d3d5df..daae241a2 100644 --- a/data/levels/world1/level4.stl +++ b/data/levels/world1/level4.stl @@ -93,10 +93,10 @@ (point (x 4718) (y 336)) ) (objects - (money (x 6752) (y 32)) - (money (x 6528) (y 192)) - (money (x 288) (y 224)) - (money (x 608) (y 224)) + (jumpy (x 6752) (y 32)) + (jumpy (x 6528) (y 192)) + (jumpy (x 288) (y 224)) + (jumpy (x 608) (y 224)) (snowball (x 1376) (y 256)) (snowball (x 1504) (y 256)) (snowball (x 3040) (y 288)) diff --git a/lib/.cvsignore b/lib/.cvsignore index 9626b6008..1dbe0c7a5 100644 --- a/lib/.cvsignore +++ b/lib/.cvsignore @@ -4,4 +4,4 @@ Makefile Makefile.in *.lo *.la - +.sconsign diff --git a/lib/Makefile.am b/lib/Makefile.am index 7dbb1d199..0ceecbf1b 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -13,9 +13,16 @@ libsupertux_la_SOURCES =app/globals.cpp \ special/game_object.cpp \ special/moving_object.cpp \ special/sprite.cpp \ + special/sprite.h \ + special/sprite_data.cpp \ + special/sprite_data.h \ special/sprite_manager.cpp \ + special/sprite_manager.h \ special/timer.cpp \ special/frame_rate.cpp \ + special/collision.h \ + special/collision_hit.h \ + special/collision.cpp \ utils/configfile.cpp \ utils/lispreader.cpp \ utils/lispwriter.cpp \ @@ -41,8 +48,7 @@ libsupertuxgui_HEADERS =gui/button.h \ gui/mousecursor.h libsupertuxmath_HEADERS =math/physic.h \ math/vector.h -libsupertuxspecial_HEADERS =special/base.h \ - special/game_object.h \ +libsupertuxspecial_HEADERS = special/game_object.h \ special/moving_object.h \ special/sprite.h \ special/sprite_manager.h \ diff --git a/lib/app/globals.cpp b/lib/app/globals.cpp index 81ca98e58..51230e113 100644 --- a/lib/app/globals.cpp +++ b/lib/app/globals.cpp @@ -20,7 +20,8 @@ #include -#include "../app/globals.h" +#include "app/globals.h" +#include "special/timer.h" namespace SuperTux { diff --git a/lib/app/globals.h b/lib/app/globals.h index 246e1abc4..39299cda6 100644 --- a/lib/app/globals.h +++ b/lib/app/globals.h @@ -27,12 +27,12 @@ #include "SDL.h" #include "../video/font.h" -#include "../gui/menu.h" -#include "../gui/mousecursor.h" namespace SuperTux { + class MouseCursor; + extern std::string datadir; extern std::string package_symbol_name; extern std::string package_name; diff --git a/lib/app/setup.h b/lib/app/setup.h index 9d05267c1..29b58d218 100644 --- a/lib/app/setup.h +++ b/lib/app/setup.h @@ -23,7 +23,6 @@ #include #include #include -#include "../gui/menu.h" namespace SuperTux { diff --git a/lib/audio/musicref.cpp b/lib/audio/musicref.cpp index 0ff362bc6..e7b613e07 100644 --- a/lib/audio/musicref.cpp +++ b/lib/audio/musicref.cpp @@ -18,6 +18,8 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include + #include "../audio/musicref.h" using namespace SuperTux; diff --git a/lib/audio/sound_manager.cpp b/lib/audio/sound_manager.cpp index 344035b5e..f721f3fd9 100644 --- a/lib/audio/sound_manager.cpp +++ b/lib/audio/sound_manager.cpp @@ -17,6 +17,8 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include + #include #include diff --git a/lib/audio/sound_manager.h b/lib/audio/sound_manager.h index f5cfb3096..b9878e400 100644 --- a/lib/audio/sound_manager.h +++ b/lib/audio/sound_manager.h @@ -47,7 +47,6 @@ namespace SuperTux class SoundManager { public: - /// Play sound. void play_sound(Mix_Chunk* sound); /// Play sound relative to two Vectors. @@ -161,7 +160,6 @@ namespace SuperTux bool m_music_enabled; bool m_sound_enabled; bool audio_device; /* != 0: available and initialized */ - }; Mix_Chunk* IDToSound(int id); diff --git a/lib/gui/button.cpp b/lib/gui/button.cpp index 087cc4698..a2d84150a 100644 --- a/lib/gui/button.cpp +++ b/lib/gui/button.cpp @@ -15,6 +15,8 @@ * * ***************************************************************************/ +#include + #include "SDL.h" #include diff --git a/lib/gui/mousecursor.cpp b/lib/gui/mousecursor.cpp index e5252a45a..e1e936be6 100644 --- a/lib/gui/mousecursor.cpp +++ b/lib/gui/mousecursor.cpp @@ -17,6 +17,8 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include + #include "../video/drawing_context.h" #include "../gui/mousecursor.h" diff --git a/lib/math/physic.cpp b/lib/math/physic.cpp index 0873cdee0..7156aabd5 100644 --- a/lib/math/physic.cpp +++ b/lib/math/physic.cpp @@ -18,6 +18,8 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. +#include + #include #include "../math/physic.h" @@ -119,24 +121,18 @@ Physic::enable_gravity(bool enable_gravity) gravity_enabled = enable_gravity; } -void -Physic::apply(float elapsed_time, float &x, float &y, float gravity) +Vector +Physic::get_movement(float elapsed_time) { - float grav; - if(gravity_enabled) - grav = gravity / 100.0; - else - grav = 0; - - x += vx * elapsed_time + ax * elapsed_time * elapsed_time; - y += vy * elapsed_time + (ay + grav) * elapsed_time * elapsed_time; + float grav = gravity_enabled ? 1000 : 0; + + Vector result( + vx * elapsed_time + ax * elapsed_time * elapsed_time, + vy * elapsed_time + (ay + grav) * elapsed_time * elapsed_time + ); vx += ax * elapsed_time; - vy += (ay + grav) * elapsed_time; -} + vy += (ay + grav) * elapsed_time; -void -Physic::apply(Vector& vector, float elapsed_time, float gravity) -{ - apply(elapsed_time, vector.x, vector.y, gravity); + return result; } diff --git a/lib/math/physic.h b/lib/math/physic.h index f269cb85d..71d7ccd44 100644 --- a/lib/math/physic.h +++ b/lib/math/physic.h @@ -21,7 +21,7 @@ #ifndef SUPERTUX_PHYSIC_H #define SUPERTUX_PHYSIC_H -#include "../math/vector.h" +#include "math/vector.h" namespace SuperTux { @@ -67,11 +67,7 @@ namespace SuperTux /// Enables or disables handling of gravity. void enable_gravity(bool gravity_enabled); - /// Applies the physical simulation to given x and y coordinates. - void apply(float frame_ratio, float &x, float &y, float gravity = 10.0f); - - /// applies the physical simulation to given x and y coordinates. - void apply(Vector& vector, float frame_ratio, float gravity = 10.0f); + Vector get_movement(float elapsed_time); private: /// horizontal and vertical acceleration diff --git a/lib/math/vector.cpp b/lib/math/vector.cpp index 1b04518b5..c156402fd 100644 --- a/lib/math/vector.cpp +++ b/lib/math/vector.cpp @@ -17,6 +17,8 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include + #include #include "../math/vector.h" diff --git a/lib/math/vector.h b/lib/math/vector.h index dac4c95cd..31b171d69 100644 --- a/lib/math/vector.h +++ b/lib/math/vector.h @@ -1,7 +1,7 @@ // $Id$ // // SuperTux - A Jump'n Run -// Copyright (C) 2004 Matthias Braun // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -20,8 +20,6 @@ #ifndef SUPERTUX_VECTOR_H #define SUPERTUX_VECTOR_H -#include "../special/base.h" - namespace SuperTux { @@ -36,9 +34,6 @@ namespace SuperTux Vector(const Vector& other) : x(other.x), y(other.y) { } - Vector(const base_type& base) - : x(base.x), y(base.y) - { } Vector() : x(0), y(0) { } @@ -92,6 +87,20 @@ namespace SuperTux return *this; } + const Vector& operator *=(float val) + { + x *= val; + y *= val; + return *this; + } + + const Vector& operator /=(float val) + { + x /= val; + y /= val; + return *this; + } + /// Scalar product of 2 vectors float operator*(const Vector& other) const { diff --git a/lib/special/collision.cpp b/lib/special/collision.cpp new file mode 100644 index 000000000..521977012 --- /dev/null +++ b/lib/special/collision.cpp @@ -0,0 +1,108 @@ +#include + +#include "collision.h" + +#include +#include +#include +#include +#include +#include "math/vector.h" +#include "math/aatriangle.h" +#include "math/rectangle.h" +#include "collision_hit.h" + +namespace SuperTux +{ + +bool +Collision::rectangle_rectangle(CollisionHit& hit, const Rectangle& r1, + const Rectangle& r2) +{ + if(r1.p2.x < r2.p1.x || r1.p1.x > r2.p2.x) + return false; + if(r1.p2.y < r2.p1.y || r1.p1.y > r2.p2.y) + return false; + + hit.depth = r1.p2.x - r2.p1.x; + hit.normal.x = -1; + hit.normal.y = 0; + + float px2 = r2.p2.x - r1.p1.x; + if(px2 < hit.depth) { + hit.depth = px2; + hit.normal.x = 1; + hit.normal.y = 0; + } + + float py1 = r1.p2.y - r2.p1.y; + if(py1 < hit.depth) { + hit.depth = py1; + hit.normal.x = 0; + hit.normal.y = -1; + } + + float py2 = r2.p2.y - r1.p1.y; + if(py2 < hit.depth) { + hit.depth = py2; + hit.normal.x = 0; + hit.normal.y = 1; + } + + return true; +} + +//--------------------------------------------------------------------------- + +static void makePlane(const Vector& p1, const Vector& p2, Vector& n, float& c) +{ + n = Vector(p2.y-p1.y, p1.x-p2.x); + c = -(p2 * n); + float nval = n.norm(); + n /= nval; + c /= nval; +} + +bool +Collision::rectangle_aatriangle(CollisionHit& hit, const Rectangle& rect, + const AATriangle& triangle) +{ + if(!rectangle_rectangle(hit, rect, (const Rectangle&) triangle)) + return false; + + Vector normal; + float c; + Vector p1; + switch(triangle.dir) { + case AATriangle::SOUTHWEST: + p1 = Vector(rect.p1.x, rect.p2.y); + makePlane(triangle.p1, triangle.p2, normal, c); + break; + case AATriangle::NORTHEAST: + p1 = Vector(rect.p2.x, rect.p1.y); + makePlane(triangle.p2, triangle.p1, normal, c); + break; + case AATriangle::SOUTHEAST: + p1 = rect.p2; + makePlane(Vector(triangle.p1.x, triangle.p2.y), + Vector(triangle.p2.x, triangle.p1.y), normal, c); + break; + case AATriangle::NORTHWEST: + p1 = rect.p1; + makePlane(Vector(triangle.p2.x, triangle.p1.y), + Vector(triangle.p1.x, triangle.p2.y), normal, c); + break; + } + + float depth = -(normal * p1) - c; + if(depth < 0) + return false; + if(depth < hit.depth) { + hit.depth = depth; + hit.normal = normal; + } + + return true; +} + +} diff --git a/lib/special/collision.h b/lib/special/collision.h new file mode 100644 index 000000000..21dc52fae --- /dev/null +++ b/lib/special/collision.h @@ -0,0 +1,30 @@ +#ifndef __COLLISION_H__ +#define __COLLISION_H__ + +namespace SuperTux +{ + +class Rectangle; +class CollisionHit; +class AATriangle; + +class Collision +{ +public: + /** does collision detection between 2 rectangles. Returns true in case of + * collision and fills in the hit structure then. + */ + static bool rectangle_rectangle(CollisionHit& hit, const Rectangle& r1, + const Rectangle& r2); + + /** does collision detection between a rectangle and an axis aligned triangle + * Returns true in case of a collision and fills in the hit structure then. + */ + static bool rectangle_aatriangle(CollisionHit& hit, const Rectangle& rect, + const AATriangle& triangle); +}; + +} + +#endif + diff --git a/lib/special/collision_hit.h b/lib/special/collision_hit.h new file mode 100644 index 000000000..068965906 --- /dev/null +++ b/lib/special/collision_hit.h @@ -0,0 +1,54 @@ +// $Id$ +// +// SuperTux - A Jump'n Run +// Copyright (C) 2004 Matthias Braun + #include "SDL.h" #include "../special/frame_rate.h" diff --git a/lib/special/game_object.cpp b/lib/special/game_object.cpp index 5b27dab0b..b525bac06 100644 --- a/lib/special/game_object.cpp +++ b/lib/special/game_object.cpp @@ -1,7 +1,7 @@ // $Id$ // // SuperTux - A Jump'n Run -// Copyright (C) 2004 Matthias Braun // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -17,12 +17,15 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include + #include "../special/game_object.h" -using namespace SuperTux; +namespace SuperTux +{ GameObject::GameObject() - : wants_to_die(false) + : wants_to_die(false), flags(0) { } @@ -30,3 +33,4 @@ GameObject::~GameObject() { } +} diff --git a/lib/special/game_object.h b/lib/special/game_object.h index cb4bfd71c..88e1ccb52 100644 --- a/lib/special/game_object.h +++ b/lib/special/game_object.h @@ -1,7 +1,7 @@ // $Id$ // // SuperTux - A Jump'n Run -// Copyright (C) 2004 Matthias Braun // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License @@ -46,8 +46,9 @@ namespace SuperTux virtual ~GameObject(); /** This function is called once per frame and allows the object to update - * it's state. The elapsed_time is the time since the last frame and should be - * the base for all timed things. + * it's state. The elapsed_time is the time since the last frame in + * seconds and should be the base for all timed calculations (don't use + * SDL_GetTicks directly as this will fail in pause mode) */ virtual void action(float elapsed_time) = 0; @@ -67,11 +68,27 @@ namespace SuperTux wants_to_die = true; } + // flags + enum { + /// the tile so you can stand on it + FLAG_SOLID = 0x0001, + /// can be used to temporatily disable collision detection + FLAG_NO_COLLDET = 0x0002 + }; + + int get_flags() const + { + return flags; + } + private: /** this flag indicates if the object should be removed at the end of the * frame */ bool wants_to_die; + + protected: + int flags; }; } diff --git a/lib/special/moving_object.cpp b/lib/special/moving_object.cpp index b87440812..46edc5aeb 100644 --- a/lib/special/moving_object.cpp +++ b/lib/special/moving_object.cpp @@ -17,14 +17,14 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include + #include "../special/moving_object.h" using namespace SuperTux; MovingObject::MovingObject() { - base.x = base.y = base.width = base.height = 0; - old_base = base; } MovingObject::~MovingObject() diff --git a/lib/special/moving_object.h b/lib/special/moving_object.h index 03996009c..e1974d700 100644 --- a/lib/special/moving_object.h +++ b/lib/special/moving_object.h @@ -20,10 +20,12 @@ #ifndef SUPERTUX_MOVING_OBJECT_H #define SUPERTUX_MOVING_OBJECT_H -#include "../special/base.h" -#include "../special/game_object.h" -#include "../math/vector.h" -//#include "rectangle.h" +#include "game_object.h" +#include "collision_hit.h" +#include "math/vector.h" +#include "math/rectangle.h" + +class Sector; namespace SuperTux { @@ -40,26 +42,35 @@ namespace SuperTux /** this function is called when the object collided with any other object */ - virtual void collision(const MovingObject& other_object, - int collision_type) = 0; + virtual HitResponse collision(GameObject& other, + const CollisionHit& hit) = 0; - Vector get_pos() const + const Vector& get_pos() const { - return Vector(base.x, base.y); + return bbox.p1; } - base_type base; - base_type old_base; + /** returns the bounding box of the Object */ + const Rectangle& get_bbox() const + { + return bbox; + } + + const Vector& get_movement() const + { + return movement; + } protected: -#if 0 // this will be used in my collision detection rewrite later - /// the current position of the object - Vector pos; - /// the position we want to move until next frame - Vector new_pos; - /// the bounding box relative to the current position - Rectangle bounding_box; -#endif + friend class Sector; + + /** The bounding box of the object (as used for collision detection, this + * isn't necessarily the bounding box for graphics) + */ + Rectangle bbox; + /** The movement that will happen till next frame + */ + Vector movement; }; } //namespace SuperTux diff --git a/lib/special/sprite.cpp b/lib/special/sprite.cpp index f6cbdebfc..594cbd3c6 100644 --- a/lib/special/sprite.cpp +++ b/lib/special/sprite.cpp @@ -16,247 +16,141 @@ // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include #include #include +#include #include "../app/globals.h" #include "../app/setup.h" #include "../special/sprite.h" #include "../video/drawing_context.h" -using namespace SuperTux; - -Sprite::Sprite(lisp_object_t* cur) +namespace SuperTux { - for(; !lisp_nil_p(cur); cur = lisp_cdr(cur)) - { - std::string token = lisp_symbol(lisp_car(lisp_car(cur))); - lisp_object_t* data = lisp_car(lisp_cdr(lisp_car(cur))); - LispReader reader(lisp_cdr(lisp_car(cur))); - - if(token == "name") - name = lisp_string(data); - else if(token == "action") - parse_action(reader); - else - std::cerr << "Warning: Unknown sprite field: " << token << std::endl; - } - if(name.empty()) - Termination::abort("Error: Sprite wihtout name.", ""); - if(actions.empty()) - Termination::abort("Error: Sprite wihtout actions.", ""); -} - -Sprite::~Sprite() +Sprite::Sprite(SpriteData& newdata) + : data(newdata) { - for(Actions::iterator i_act = actions.begin(); i_act != actions.end(); ++i_act) - { - for(std::vector::iterator i_sur = i_act->second->surfaces.begin(); - i_sur != i_act->second->surfaces.end(); ++i_sur) - { - delete *i_sur; - } - delete i_act->second; - } + action = data.actions.begin()->second; + reset(); } -void -Sprite::parse_action(LispReader& lispreader) +Sprite::Sprite(const Sprite& other) + : data(other.data), frame(other.frame), + animation_loops(other.animation_loops), last_tick(other.last_tick), + action(other.action), next_action(other.next_action) { - action = new Action; - - init_defaults(action); - - if(!lispreader.read_string("name", action->name)) - if(!actions.empty()) - Termination::abort("Error: If there are more than one action, they need names!", ""); - lispreader.read_int("x-offset", action->x_offset); - lispreader.read_int("y-offset", action->y_offset); - lispreader.read_int("z-order", action->z_order); - lispreader.read_float("fps", action->fps); - - /* TODO: add a top filter entry */ - std::vector mask_color; - lispreader.read_int_vector("apply-mask", mask_color); - if(mask_color.size() == 4) - { - for(std::vector::iterator i = action->surfaces.begin(); - i < action->surfaces.end(); i++) - { - (*i)->apply_filter(MASK_FILTER, Color(mask_color)); - } - } - - std::string mirror_action; - lispreader.read_string("mirror-action", mirror_action); - if(!mirror_action.empty()) - { - Action* act_tmp = get_action(mirror_action); - if(act_tmp == NULL) - std::cerr << "Warning: Could not mirror action. Action not found\n" - "Mirror actions must be defined after the real one!\n"; - else - { - for(int i = 0; static_cast(i) < act_tmp->surfaces.size(); i++) - { - Surface* surface = new Surface(sdl_surface_from_sdl_surface( - act_tmp->surfaces[i]->impl->get_sdl_surface(), true), true); - surface->apply_filter(HORIZONTAL_FLIP_FILTER); - action->surfaces.push_back(surface); - } - } - } - else // Load images - { - std::vector images; - if(!lispreader.read_string_vector("images", images)) - Termination::abort("Sprite contains no images: ", action->name); - - for(std::vector::size_type i = 0; i < images.size(); i++) - { - action->surfaces.push_back( - new Surface(datadir + "/images/" + images[i], true)); - } - } - actions[action->name] = action; } -/*void Sprite::parse_filter(LispReader& lispreader) -{ - -}*/ - -void -Sprite::init_defaults(Action* act) +Sprite::~Sprite() { - act->x_offset = 0; - act->y_offset = 0; - act->z_order = 0; - act->fps = 10; - - start_animation(-1); } void -Sprite::set_action(std::string act) +Sprite::set_action(std::string name) { -if(!next_action.empty() && animation_loops > 0) - { - next_action = act; - return; + if(!next_action.empty() && animation_loops > 0) { + next_action = name; + return; } -Actions::iterator i = actions.find(act); -if(i == actions.end()) - { - std::cerr << "Warning: Action '" << act << "' not found on Sprite '" << name << "'\n"; - return; - } -action = i->second; -} + SpriteData::Action* newaction = data.get_action(name); + if(!action) + return; -Sprite::Action* -Sprite::get_action(std::string act) -{ -Actions::iterator i = actions.find(act); -if(i == actions.end()) - { - std::cerr << "Warning: Action '" << act << "' not found on Sprite '" << name << "'\n"; - return NULL; - } -return i->second; + action = newaction; } void Sprite::start_animation(int loops) { -reset(); -animation_loops = loops; + reset(); + animation_loops = loops; } void Sprite::reset() { -frame = 0; -last_tick = SDL_GetTicks(); -animation_reversed = false; -next_action.clear(); + frame = 0; + last_tick = SDL_GetTicks(); + animation_reversed = false; + animation_loops = -1; + next_action.clear(); } bool Sprite::check_animation() { -return animation_loops; + return animation_loops; } void Sprite::reverse_animation(bool reverse) { -animation_reversed = reverse; + animation_reversed = reverse; -if(animation_reversed) - frame = get_frames()-1; -else - frame = 0; + if(animation_reversed) + frame = get_frames()-1; + else + frame = 0; } void Sprite::update() { -if(animation_loops == 0) + if(animation_loops == 0) { - if(frame >= get_frames() || frame < 0) - frame = 0; - return; + if(frame >= get_frames() || frame < 0) + frame = 0; + return; } -float frame_inc = (action->fps/1000.0) * (SDL_GetTicks() - last_tick); -last_tick = SDL_GetTicks(); + float frame_inc = (action->fps/1000.0) * (SDL_GetTicks() - last_tick); + last_tick = SDL_GetTicks(); -if(animation_reversed) - frame -= frame_inc; -else - frame += frame_inc; - -if(animation_reversed) - { - if(frame < 0 || frame >= (float)get_frames()) - { // last case can happen when not used reverse_animation() - float excedent = frame - 0; - frame = get_frames() - 1; - if(animation_loops > 0) + if(animation_reversed) + frame -= frame_inc; + else + frame += frame_inc; + + if(animation_reversed) { + if(frame < 0 || frame >= (float)get_frames()) { + // last case can happen when not used reverse_animation() + float excedent = frame - 0; + frame = get_frames() - 1; + if(animation_loops > 0) { - animation_loops--; - if(animation_loops == 0 && !next_action.empty()) + animation_loops--; + if(animation_loops == 0 && !next_action.empty()) { - set_action(next_action); - start_animation(-1); + set_action(next_action); + start_animation(-1); } } - if(fabsf(excedent) < get_frames()) - frame += excedent; + if(fabsf(excedent) < get_frames()) + frame += excedent; } } -else + else { - if(frame >= (float)get_frames()) + if(frame >= (float)get_frames()) { - float excedent = frame - get_frames(); - frame = 0; - if(animation_loops > 0) + float excedent = frame - get_frames(); + frame = 0; + if(animation_loops > 0) { - animation_loops--; - if(animation_loops == 0 && !next_action.empty()) + animation_loops--; + if(animation_loops == 0 && !next_action.empty()) { - set_action(next_action); - start_animation(-1); + set_action(next_action); + start_animation(-1); } } - if(excedent < get_frames()) - frame += excedent; + if(excedent < get_frames()) + frame += excedent; } } } @@ -273,12 +167,13 @@ Sprite::draw(DrawingContext& context, const Vector& pos, int layer, << "/" << get_action_name() << std::endl; else context.draw_surface(action->surfaces[(int)frame], - pos - Vector(action->x_offset, action->y_offset), layer + action->z_order, drawing_effect); + pos - Vector(action->x_offset, action->y_offset), + layer + action->z_order, drawing_effect); } void -Sprite::draw_part(DrawingContext& context, const Vector& source, const Vector& size, - const Vector& pos, int layer, Uint32 drawing_effect) +Sprite::draw_part(DrawingContext& context, const Vector& source, + const Vector& size, const Vector& pos, int layer, Uint32 drawing_effect) { update(); @@ -288,19 +183,22 @@ Sprite::draw_part(DrawingContext& context, const Vector& source, const Vector& s << "/" << get_action_name() << std::endl; else context.draw_surface_part(action->surfaces[(int)frame], source, size, - pos - Vector(action->x_offset, action->y_offset), layer + action->z_order, drawing_effect); + pos - Vector(action->x_offset, action->y_offset), + layer + action->z_order, drawing_effect); } int -Sprite::get_width() +Sprite::get_width() const { return action->surfaces[get_frame()]->w; } int -Sprite::get_height() +Sprite::get_height() const { return action->surfaces[get_frame()]->h; } +} + /* EOF */ diff --git a/lib/special/sprite.h b/lib/special/sprite.h index 8239f49a0..2e18eb65b 100644 --- a/lib/special/sprite.h +++ b/lib/special/sprite.h @@ -27,115 +27,83 @@ #include "../utils/lispreader.h" #include "../video/surface.h" #include "../math/vector.h" +#include "sprite_data.h" namespace SuperTux - { - +{ class Sprite + { + public: + Sprite(SpriteData& data); + Sprite(const Sprite& other); + ~Sprite(); + + /** Draw sprite, automatically calculates next frame */ + void draw(DrawingContext& context, const Vector& pos, int layer, + Uint32 drawing_effect = NONE_EFFECT); + + void draw_part(DrawingContext& context, const Vector& source, + const Vector& size, const Vector& pos, int layer, + Uint32 drawing_effect = NONE_EFFECT); + + /** Set action (or state) */ + void set_action(std::string act); + + /* Start an animation + -1 - for infinite + 0 - stopped + 1,2,3 - one, two, three times... */ + void start_animation(int loops); + /* Stop animation */ + void stop_animation() + { start_animation(0); } + /** Check if animation is stopped or not */ + bool check_animation(); + /** Reverse the animation */ + void reverse_animation(bool reverse); + + float get_fps() const + { return action->fps; } + /** Get current action total frames */ + int get_frames() const + { return action->surfaces.size(); } + /** Get sprite's name */ + const std::string& get_name() const + { return data.name; } + /** Get current action name */ + const std::string& get_action_name() const + { return action->name; } + + int get_width() const; + int get_height() const; + + /** Get current frame */ + int get_frame() const + { return (int)frame; } + /** Set current frame */ + void set_frame(int frame_) + { if(frame_ > get_frames()) frame = 0; else frame = frame_; } + Surface* get_frame(unsigned int frame) { - private: - - struct Action - { - std::string name; - - /** Position correction */ - int x_offset; - int y_offset; - /** Drawing priority in queue */ - int z_order; - - /** Frames per second */ - float fps; - - /** Mirror is used to avoid duplicating left and right side - sprites */ -// bool mirror; - - std::vector surfaces; - }; - - public: - /** cur has to be a pointer to data in the form of ((x-offset 5) - (y-offset 10) ...) */ - Sprite(lisp_object_t* cur); - ~Sprite(); - - /** Draw sprite, automatically calculates next frame */ - void draw(DrawingContext& context, const Vector& pos, int layer, - Uint32 drawing_effect = NONE_EFFECT); - - void draw_part(DrawingContext& context, const Vector& source, - const Vector& size, const Vector& pos, int layer, - Uint32 drawing_effect = NONE_EFFECT); - - /** Set action (or state) */ - void set_action(std::string act); - - /* Start an animation - -1 - for infinite - 0 - stopped - 1,2,3 - one, two, three times... */ - void start_animation(int loops); - /* Stop animation */ - void stop_animation() - { start_animation(0); } - /** Check if animation is stopped or not */ - bool check_animation(); - /** Reverse the animation */ - void reverse_animation(bool reverse); - - float get_fps() - { return action->fps; } - /** Get current action total frames */ - int get_frames() - { return action->surfaces.size(); } - /** Get sprite's name */ - std::string get_name() const - { return name; } - /** Get current action name */ - std::string get_action_name() const - { return action->name; } - int get_width(); - int get_height(); - - /** Get current frame */ - int get_frame() - { return (int)frame; } - /** Set current frame */ - void set_frame(int frame_) - { if(frame_ > get_frames()) frame = 0; else frame = frame_; } - Surface* get_frame(unsigned int frame) - { - if(frame < action->surfaces.size()) - return action->surfaces[frame]; - else - return action->surfaces[0]; - } - private: - void init_defaults(Action* act); - void parse_action(LispReader& lispreader); - - /** Get an action */ - Action* get_action(std::string act); - - void update(); - void reset(); - - std::string name; - - float frame; - int animation_loops; - bool animation_reversed; - float last_tick; - - typedef std::map Actions; - Actions actions; - - Action* action; - std::string next_action; - }; - + if(frame < action->surfaces.size()) + return action->surfaces[frame]; + else + return action->surfaces[0]; + } + private: + void update(); + void reset(); + + SpriteData& data; + + float frame; + int animation_loops; + bool animation_reversed; + float last_tick; + + SpriteData::Action* action; + std::string next_action; + }; } //namespace SuperTux #endif /*SUPERTUX_SPRITE_H*/ diff --git a/lib/special/sprite_data.h b/lib/special/sprite_data.h new file mode 100644 index 000000000..a33cba74a --- /dev/null +++ b/lib/special/sprite_data.h @@ -0,0 +1,84 @@ +// $Id$ +// +// SuperTux +// Copyright (C) 2004 Ingo Ruhnke , +// (C) 2004 Matthias Braun +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#ifndef SUPERTUX_SPRITE_DATA_H +#define SUPERTUX_SPRITE_DATA_H + +#include +#include +#include + +#include "../utils/lispreader.h" +#include "../video/surface.h" + +namespace SuperTux +{ + + class SpriteData + { + public: + /** cur has to be a pointer to data in the form of ((x-offset 5) + (y-offset 10) ...) */ + SpriteData(lisp_object_t* cur); + ~SpriteData(); + + const std::string& get_name() const + { + return name; + } + + private: + friend class Sprite; + + struct Action + { + Action(); + ~Action(); + + std::string name; + + /** Position correction */ + int x_offset; + int y_offset; + /** Drawing priority in queue */ + int z_order; + + /** Frames per second */ + float fps; + + /** Mirror is used to avoid duplicating left and right side + sprites */ + // bool mirror; + + std::vector surfaces; + }; + + typedef std::map Actions; + Actions actions; + + void parse_action(LispReader& lispreader); + /** Get an action */ + Action* get_action(std::string act); + + std::string name; + }; +} + +#endif + diff --git a/lib/special/sprite_manager.cpp b/lib/special/sprite_manager.cpp index 195130ee0..8c9ee8139 100644 --- a/lib/special/sprite_manager.cpp +++ b/lib/special/sprite_manager.cpp @@ -16,13 +16,19 @@ // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include #include +#include +#include -#include "../utils/lispreader.h" -#include "../special/sprite_manager.h" +#include "utils/lispreader.h" +#include "sprite_manager.h" +#include "sprite_data.h" +#include "sprite.h" -using namespace SuperTux; +namespace SuperTux +{ SpriteManager::SpriteManager(const std::string& filename) { @@ -31,8 +37,7 @@ SpriteManager::SpriteManager(const std::string& filename) SpriteManager::~SpriteManager() { - for(std::map::iterator i = sprites.begin(); - i != sprites.end(); ++i) { + for(Sprites::iterator i = sprites.begin(); i != sprites.end(); ++i) { delete i->second; } } @@ -53,47 +58,42 @@ SpriteManager::load_resfile(const std::string& filename) return; cur = lisp_cdr(cur); - while(cur) - { - lisp_object_t* el = lisp_car(cur); - - if (strcmp(lisp_symbol(lisp_car(el)), "sprite") == 0) - { - Sprite* sprite = new Sprite(lisp_cdr(el)); - - Sprites::iterator i = sprites.find(sprite->get_name()); - if (i == sprites.end()) - { - sprites[sprite->get_name()] = sprite; - } - else - { - delete i->second; - i->second = sprite; - std::cout << "Warning: dulpicate entry: '" << sprite->get_name() << "'" << std::endl; - } - } - else - { - std::cout << "SpriteManager: Unknown tag" << std::endl; - } - - cur = lisp_cdr(cur); + while(cur) { + lisp_object_t* el = lisp_car(cur); + + if (strcmp(lisp_symbol(lisp_car(el)), "sprite") == 0) { + SpriteData* spritedata = new SpriteData(lisp_cdr(el)); + + Sprites::iterator i = sprites.find(spritedata->get_name()); + if (i == sprites.end()) { + sprites[spritedata->get_name()] = spritedata; + } else { + delete i->second; + i->second = spritedata; + std::cout << "Warning: dulpicate entry: '" << spritedata->get_name() + << "' in spritefile." << std::endl; + } + } else { + std::cout << "SpriteManager: Unknown tag in spritefile.\n"; } + cur = lisp_cdr(cur); + } + lisp_free(root_obj); } Sprite* -SpriteManager::load(const std::string& name) +SpriteManager::create(const std::string& name) { Sprites::iterator i = sprites.find(name); - if (i == sprites.end()) - { - std::cerr << "Warning: Sprite '" << name << "' not found" << std::endl; - return 0; - } - return i->second; + if(i == sprites.end()) { + std::stringstream msg; + msg << "Sprite '" << name << "' not found."; + throw std::runtime_error(msg.str()); + } + return new Sprite(*i->second); +} + } -/* EOF */ diff --git a/lib/special/sprite_manager.h b/lib/special/sprite_manager.h index 866308176..bc2e1e6f6 100644 --- a/lib/special/sprite_manager.h +++ b/lib/special/sprite_manager.h @@ -25,24 +25,23 @@ #include "../special/sprite.h" namespace SuperTux - { +{ class SpriteManager - { - private: - typedef std::map Sprites; - Sprites sprites; - public: - SpriteManager(const std::string& filename); - ~SpriteManager(); - - void load_resfile(const std::string& filename); - /** loads a sprite. - * WARNING: You must not delete the returned object. - */ - Sprite* load(const std::string& name); - }; - + { + private: + typedef std::map Sprites; + Sprites sprites; + public: + SpriteManager(const std::string& filename); + ~SpriteManager(); + + void load_resfile(const std::string& filename); + /** loads a sprite. + * (contrary to the old api you have to delete the sprite!) + */ + Sprite* create(const std::string& name); + }; } //namespace SuperTux #endif /*SUPERTUX_SPRITE_MANAGER_H*/ diff --git a/lib/special/timer.cpp b/lib/special/timer.cpp index ed3608ed6..5aa62bada 100644 --- a/lib/special/timer.cpp +++ b/lib/special/timer.cpp @@ -18,6 +18,8 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. +#include + #include "SDL.h" #include "../special/timer.h" diff --git a/lib/special/timer.h b/lib/special/timer.h index b3f78c25c..1866a2cc9 100644 --- a/lib/special/timer.h +++ b/lib/special/timer.h @@ -30,12 +30,12 @@ namespace SuperTux { public: /// Time a game is running. (Non-pause mode, etc.) - static unsigned int get(void); + static unsigned int get(); - static void pause_init(void); - static void pause_start(void); - static void pause_stop(void); - static bool pause_started(void); + static void pause_init(); + static void pause_start(); + static void pause_stop(); + static bool pause_started(); private: static unsigned int pause_ticks; diff --git a/lib/utils/configfile.cpp b/lib/utils/configfile.cpp index bbbb501d5..452f4cdbb 100644 --- a/lib/utils/configfile.cpp +++ b/lib/utils/configfile.cpp @@ -17,6 +17,8 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include + #include #include diff --git a/lib/utils/lispreader.cpp b/lib/utils/lispreader.cpp index 50fe768b2..68fd7602f 100644 --- a/lib/utils/lispreader.cpp +++ b/lib/utils/lispreader.cpp @@ -20,8 +20,11 @@ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ +#include + #include #include +#include #include #include #include @@ -68,7 +71,7 @@ static void _token_append (char c) { if (token_length >= MAX_TOKEN_LENGTH) - throw LispReaderException("_token_append()", __FILE__, __LINE__); + throw std::runtime_error("token too long."); token_string[token_length++] = c; token_string[token_length] = '\0'; @@ -98,7 +101,7 @@ _next_char (lisp_stream_t *stream) return stream->v.any.next_char(stream->v.any.data); } - throw LispReaderException("_next_char()", __FILE__, __LINE__); + assert(false); return EOF; } @@ -120,7 +123,7 @@ _unget_char (char c, lisp_stream_t *stream) break; default : - throw LispReaderException("_unget_char()", __FILE__, __LINE__); + assert(false); } } @@ -272,7 +275,7 @@ _scan (lisp_stream_t *stream) } } - throw LispReaderException("_scan()", __FILE__, __LINE__); + throw std::runtime_error("invalid token in lisp file"); return TOKEN_ERROR; } @@ -311,7 +314,7 @@ SuperTux::lisp_stream_init_any (lisp_stream_t *stream, void *data, void (*unget_char) (char c, void *data)) { if (next_char == 0 || unget_char == 0) - throw LispReaderException("lisp_stream_init_any()", __FILE__, __LINE__); + throw std::runtime_error("no data"); stream->type = LISP_STREAM_ANY; stream->v.any.data = data; @@ -499,7 +502,7 @@ SuperTux::lisp_read (lisp_stream_t *in) return lisp_make_boolean(0); } - throw LispReaderException("lisp_read()", __FILE__, __LINE__); + throw std::runtime_error("syntax error in lisp file"); return &error_object; } @@ -663,7 +666,7 @@ static int _match_pattern_var (lisp_object_t *pattern, lisp_object_t *obj, lisp_object_t **vars) { if (lisp_type(pattern) != LISP_TYPE_PATTERN_VAR) - throw LispReaderException("_match_pattern_var", __FILE__, __LINE__); + throw std::runtime_error("type is not a var"); switch (pattern->v.pattern.type) { @@ -708,7 +711,7 @@ _match_pattern_var (lisp_object_t *pattern, lisp_object_t *obj, lisp_object_t ** for (sub = pattern->v.pattern.sub; sub != 0; sub = lisp_cdr(sub)) { if (lisp_type(sub) != LISP_TYPE_CONS) - throw LispReaderException("_match_pattern_var()", __FILE__, __LINE__); + throw std::runtime_error("type isn't a car/cons"); if (_match_pattern(lisp_car(sub), obj, vars)) matched = 1; @@ -720,7 +723,7 @@ _match_pattern_var (lisp_object_t *pattern, lisp_object_t *obj, lisp_object_t ** break; default : - throw LispReaderException("_match_pattern_var()", __FILE__, __LINE__); + assert(false); } if (vars != 0) @@ -770,7 +773,7 @@ _match_pattern (lisp_object_t *pattern, lisp_object_t *obj, lisp_object_t **vars break; default : - throw LispReaderException("_match_pattern()", __FILE__, __LINE__); + assert(false); } return 0; @@ -826,7 +829,7 @@ int SuperTux::lisp_integer (lisp_object_t *obj) { if (obj->type != LISP_TYPE_INTEGER) - throw LispReaderException("lisp_integer()", __FILE__, __LINE__); + throw std::runtime_error("expected integer"); return obj->v.integer; } @@ -835,7 +838,7 @@ char* SuperTux::lisp_symbol (lisp_object_t *obj) { if (obj->type != LISP_TYPE_SYMBOL) - throw LispReaderException("lisp_symbol()", __FILE__, __LINE__); + throw std::runtime_error("expected symbol"); return obj->v.string; } @@ -844,7 +847,7 @@ char* SuperTux::lisp_string (lisp_object_t *obj) { if (obj->type != LISP_TYPE_STRING) - throw LispReaderException("lisp_string()", __FILE__, __LINE__); + throw std::runtime_error("expected string"); return obj->v.string; } @@ -853,7 +856,7 @@ int SuperTux::lisp_boolean (lisp_object_t *obj) { if (obj->type != LISP_TYPE_BOOLEAN) - throw LispReaderException("lisp_boolean()", __FILE__, __LINE__); + throw std::runtime_error("expected boolean"); return obj->v.integer; } @@ -862,7 +865,7 @@ float SuperTux::lisp_real (lisp_object_t *obj) { if (obj->type != LISP_TYPE_REAL && obj->type != LISP_TYPE_INTEGER) - throw LispReaderException("lisp_real()", __FILE__, __LINE__); + throw std::runtime_error("expected real"); if (obj->type == LISP_TYPE_INTEGER) return obj->v.integer; @@ -873,7 +876,7 @@ lisp_object_t* SuperTux::lisp_car (lisp_object_t *obj) { if (obj->type != LISP_TYPE_CONS && obj->type != LISP_TYPE_PATTERN_CONS) - throw LispReaderException("lisp_car()", __FILE__, __LINE__); + throw std::runtime_error("expected car"); return obj->v.cons.car; } @@ -882,7 +885,7 @@ lisp_object_t* SuperTux::lisp_cdr (lisp_object_t *obj) { if (obj->type != LISP_TYPE_CONS && obj->type != LISP_TYPE_PATTERN_CONS) - throw LispReaderException("lisp_cdr()", __FILE__, __LINE__); + throw std::runtime_error("expected cons"); return obj->v.cons.cdr; } @@ -898,7 +901,7 @@ SuperTux::lisp_cxr (lisp_object_t *obj, const char *x) else if (x[i] == 'd') obj = lisp_cdr(obj); else - throw LispReaderException("lisp_cxr()", __FILE__, __LINE__); + throw std::runtime_error("couldn't parse cxr"); return obj; } @@ -911,7 +914,7 @@ SuperTux::lisp_list_length (lisp_object_t *obj) while (obj != 0) { if (obj->type != LISP_TYPE_CONS && obj->type != LISP_TYPE_PATTERN_CONS) - throw LispReaderException("lisp_list_length()", __FILE__, __LINE__); + throw std::runtime_error("expected cons"); ++length; obj = obj->v.cons.cdr; @@ -926,9 +929,9 @@ SuperTux::lisp_list_nth_cdr (lisp_object_t *obj, int index) while (index > 0) { if (obj == 0) - throw LispReaderException("lisp_list_nth_cdr()", __FILE__, __LINE__); + throw std::runtime_error("list too short"); if (obj->type != LISP_TYPE_CONS && obj->type != LISP_TYPE_PATTERN_CONS) - throw LispReaderException("lisp_list_nth_cdr()", __FILE__, __LINE__); + throw std::runtime_error("expected cons"); --index; obj = obj->v.cons.cdr; @@ -943,7 +946,7 @@ SuperTux::lisp_list_nth (lisp_object_t *obj, int index) obj = lisp_list_nth_cdr(obj, index); if (obj == 0) - throw LispReaderException("lisp_list_nth()", __FILE__, __LINE__); + throw std::runtime_error("list too short"); return obj->v.cons.car; } @@ -1025,7 +1028,7 @@ SuperTux::lisp_dump (lisp_object_t *obj, FILE *out) break; default : - throw LispReaderException("lisp_dump()", __FILE__, __LINE__); + throw std::runtime_error("unknown list type"); } } @@ -1049,13 +1052,12 @@ LispReader::load(const std::string& filename, const std::string& toplevellist) if(obj->type == LISP_TYPE_EOF || obj->type == LISP_TYPE_PARSE_ERROR) { lisp_free(obj); - throw LispReaderException("LispReader::load", __FILE__, __LINE__); + throw std::runtime_error("Error while parsing lispfile"); } if(toplevellist != lisp_symbol(lisp_car(obj))) { lisp_car(obj); - throw LispReaderException("LispReader::load wrong toplevel symbol", - __FILE__, __LINE__); + throw std::runtime_error("Worng toplevel symbol in lisp file"); } LispReader* reader = new LispReader(lisp_cdr(obj)); @@ -1077,7 +1079,6 @@ LispReader::search_for(const char* name) if (!lisp_cons_p(cur) || !lisp_symbol_p (lisp_car(cur))) { lisp_dump(cur, stdout); - //throw ConstruoError (std::string("LispReader: Read error in search_for ") + name); printf("LispReader: Read error in search\n"); } else @@ -1108,6 +1109,20 @@ LispReader::read_int (const char* name, int& i) } bool +LispReader::read_uint (const char* name, unsigned int& i) +{ + lisp_object_t* obj = search_for (name); + if(!obj) + return false; + + if (!lisp_integer_p(lisp_car(obj))) + return false; + + i = (unsigned int) lisp_integer(lisp_car(obj)); + return true; +} + +bool LispReader::read_lisp(const char* name, lisp_object_t*& b) { lisp_object_t* obj = search_for (name); @@ -1291,5 +1306,3 @@ lisp_object_t* SuperTux::lisp_read_from_file(const std::string& filename) return obj; } - -// EOF // diff --git a/lib/utils/lispreader.h b/lib/utils/lispreader.h index eb7581c5f..704ff7829 100644 --- a/lib/utils/lispreader.h +++ b/lib/utils/lispreader.h @@ -61,14 +61,6 @@ namespace SuperTux { #define LISP_PATTERN_LIST 7 #define LISP_PATTERN_OR 8 -// Exception -class LispReaderException : public SuperTuxException -{ - public: - LispReaderException(const char* _message = "lispreader error", const char* _file = "", const unsigned int _line = 0) - : SuperTuxException(_message, _file, _line) { }; -}; - typedef struct { int type; @@ -191,6 +183,7 @@ public: bool read_string_vector(const char* name, std::vector& vec); bool read_string(const char* name, std::string& str, bool translatable = false); bool read_int(const char* name, int& i); + bool read_uint(const char* name, unsigned int& i); bool read_float(const char* name, float& f); bool read_bool(const char* name, bool& b); bool read_lisp(const char* name, lisp_object_t*& b); diff --git a/lib/utils/lispwriter.cpp b/lib/utils/lispwriter.cpp index c92b7c3de..72e201de1 100644 --- a/lib/utils/lispwriter.cpp +++ b/lib/utils/lispwriter.cpp @@ -17,6 +17,8 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include + #include #include "../utils/lispwriter.h" diff --git a/lib/video/drawing_context.cpp b/lib/video/drawing_context.cpp index 889b86377..f84949157 100644 --- a/lib/video/drawing_context.cpp +++ b/lib/video/drawing_context.cpp @@ -16,6 +16,8 @@ // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include + #include #include #include @@ -29,9 +31,9 @@ using namespace SuperTux; DrawingContext::DrawingContext() { -transform.draw_effect = NONE_EFFECT; -transform.zoom = 1; -transform.alpha = 255; + transform.draw_effect = NONE_EFFECT; + transform.zoom = 1; + transform.alpha = 255; } DrawingContext::~DrawingContext() @@ -50,6 +52,11 @@ DrawingContext::draw_surface(const Surface* surface, const Vector& position, request.layer = layer; request.request_data = const_cast (surface); request.pos = transform.apply(position); + + if(request.pos.x >= screen->w || request.pos.y >= screen->h + || request.pos.x + surface->w < 0 || request.pos.y + surface->h < 0) + return; + request.drawing_effect = drawing_effect; request.drawing_effect = transform.draw_effect | drawing_effect; request.zoom = transform.zoom; diff --git a/lib/video/font.cpp b/lib/video/font.cpp index 8f3499135..93e792568 100644 --- a/lib/video/font.cpp +++ b/lib/video/font.cpp @@ -18,6 +18,8 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. +#include + #include #include diff --git a/lib/video/screen.cpp b/lib/video/screen.cpp index 1714943da..2b6d23170 100644 --- a/lib/video/screen.cpp +++ b/lib/video/screen.cpp @@ -17,6 +17,8 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include + #include #include #include @@ -36,7 +38,6 @@ #include "../video/screen.h" #include "../app/globals.h" #include "../video/drawing_context.h" -#include "../special/base.h" #include "../math/vector.h" using namespace SuperTux; diff --git a/lib/video/surface.cpp b/lib/video/surface.cpp index c72b5a308..93e35091b 100644 --- a/lib/video/surface.cpp +++ b/lib/video/surface.cpp @@ -18,6 +18,8 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. +#include + #include #include #include diff --git a/ltmain.sh b/ltmain.sh deleted file mode 100644 index 47f816f2a..000000000 --- a/ltmain.sh +++ /dev/null @@ -1,4982 +0,0 @@ -# ltmain.sh - Provide generalized library-building support services. -# NOTE: Changing this file will not affect anything until you rerun configure. -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 -# Free Software Foundation, Inc. -# Originally by Gordon Matzigkeit , 1996 -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# Check that we have a working $echo. -if test "X$1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X$1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then - # Yippee, $echo works! - : -else - # Restart under the correct shell, and then maybe $echo will work. - exec $SHELL "$0" --no-reexec ${1+"$@"} -fi - -if test "X$1" = X--fallback-echo; then - # used as fallback echo - shift - cat <&2 - echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 - exit 1 -fi - -# Global variables. -mode=$default_mode -nonopt= -prev= -prevopt= -run= -show="$echo" -show_help= -execute_dlfiles= -lo2o="s/\\.lo\$/.${objext}/" -o2lo="s/\\.${objext}\$/.lo/" - -# Parse our command line options once, thoroughly. -while test $# -gt 0 -do - arg="$1" - shift - - case $arg in - -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; - *) optarg= ;; - esac - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - case $prev in - execute_dlfiles) - execute_dlfiles="$execute_dlfiles $arg" - ;; - *) - eval "$prev=\$arg" - ;; - esac - - prev= - prevopt= - continue - fi - - # Have we seen a non-optional argument yet? - case $arg in - --help) - show_help=yes - ;; - - --version) - echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" - exit 0 - ;; - - --config) - sed -e '1,/^# ### BEGIN LIBTOOL CONFIG/d' -e '/^# ### END LIBTOOL CONFIG/,$d' $0 - exit 0 - ;; - - --debug) - echo "$progname: enabling shell trace mode" - set -x - ;; - - --dry-run | -n) - run=: - ;; - - --features) - echo "host: $host" - if test "$build_libtool_libs" = yes; then - echo "enable shared libraries" - else - echo "disable shared libraries" - fi - if test "$build_old_libs" = yes; then - echo "enable static libraries" - else - echo "disable static libraries" - fi - exit 0 - ;; - - --finish) mode="finish" ;; - - --mode) prevopt="--mode" prev=mode ;; - --mode=*) mode="$optarg" ;; - - --quiet | --silent) - show=: - ;; - - -dlopen) - prevopt="-dlopen" - prev=execute_dlfiles - ;; - - -*) - $echo "$modename: unrecognized option \`$arg'" 1>&2 - $echo "$help" 1>&2 - exit 1 - ;; - - *) - nonopt="$arg" - break - ;; - esac -done - -if test -n "$prevopt"; then - $echo "$modename: option \`$prevopt' requires an argument" 1>&2 - $echo "$help" 1>&2 - exit 1 -fi - -# If this variable is set in any of the actions, the command in it -# will be execed at the end. This prevents here-documents from being -# left over by shells. -exec_cmd= - -if test -z "$show_help"; then - - # Infer the operation mode. - if test -z "$mode"; then - case $nonopt in - *cc | *++ | gcc* | *-gcc*) - mode=link - for arg - do - case $arg in - -c) - mode=compile - break - ;; - esac - done - ;; - *db | *dbx | *strace | *truss) - mode=execute - ;; - *install*|cp|mv) - mode=install - ;; - *rm) - mode=uninstall - ;; - *) - # If we have no mode, but dlfiles were specified, then do execute mode. - test -n "$execute_dlfiles" && mode=execute - - # Just use the default operation mode. - if test -z "$mode"; then - if test -n "$nonopt"; then - $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 - else - $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 - fi - fi - ;; - esac - fi - - # Only execute mode is allowed to have -dlopen flags. - if test -n "$execute_dlfiles" && test "$mode" != execute; then - $echo "$modename: unrecognized option \`-dlopen'" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - # Change the help message to a mode-specific one. - generic_help="$help" - help="Try \`$modename --help --mode=$mode' for more information." - - # These modes are in order of execution frequency so that they run quickly. - case $mode in - # libtool compile mode - compile) - modename="$modename: compile" - # Get the compilation command and the source file. - base_compile= - prev= - lastarg= - srcfile="$nonopt" - suppress_output= - - user_target=no - for arg - do - case $prev in - "") ;; - xcompiler) - # Aesthetically quote the previous argument. - prev= - lastarg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - - case $arg in - # Double-quote args containing other shell metacharacters. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - - # Add the previous argument to base_compile. - if test -z "$base_compile"; then - base_compile="$lastarg" - else - base_compile="$base_compile $lastarg" - fi - continue - ;; - esac - - # Accept any command-line options. - case $arg in - -o) - if test "$user_target" != "no"; then - $echo "$modename: you cannot specify \`-o' more than once" 1>&2 - exit 1 - fi - user_target=next - ;; - - -static) - build_old_libs=yes - continue - ;; - - -prefer-pic) - pic_mode=yes - continue - ;; - - -prefer-non-pic) - pic_mode=no - continue - ;; - - -Xcompiler) - prev=xcompiler - continue - ;; - - -Wc,*) - args=`$echo "X$arg" | $Xsed -e "s/^-Wc,//"` - lastarg= - IFS="${IFS= }"; save_ifs="$IFS"; IFS=',' - for arg in $args; do - IFS="$save_ifs" - - # Double-quote args containing other shell metacharacters. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - lastarg="$lastarg $arg" - done - IFS="$save_ifs" - lastarg=`$echo "X$lastarg" | $Xsed -e "s/^ //"` - - # Add the arguments to base_compile. - if test -z "$base_compile"; then - base_compile="$lastarg" - else - base_compile="$base_compile $lastarg" - fi - continue - ;; - esac - - case $user_target in - next) - # The next one is the -o target name - user_target=yes - continue - ;; - yes) - # We got the output file - user_target=set - libobj="$arg" - continue - ;; - esac - - # Accept the current argument as the source file. - lastarg="$srcfile" - srcfile="$arg" - - # Aesthetically quote the previous argument. - - # Backslashify any backslashes, double quotes, and dollar signs. - # These are the only characters that are still specially - # interpreted inside of double-quoted scrings. - lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` - - # Double-quote args containing other shell metacharacters. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - case $lastarg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - lastarg="\"$lastarg\"" - ;; - esac - - # Add the previous argument to base_compile. - if test -z "$base_compile"; then - base_compile="$lastarg" - else - base_compile="$base_compile $lastarg" - fi - done - - case $user_target in - set) - ;; - no) - # Get the name of the library object. - libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` - ;; - *) - $echo "$modename: you must specify a target with \`-o'" 1>&2 - exit 1 - ;; - esac - - # Recognize several different file suffixes. - # If the user specifies -o file.o, it is replaced with file.lo - xform='[cCFSfmso]' - case $libobj in - *.ada) xform=ada ;; - *.adb) xform=adb ;; - *.ads) xform=ads ;; - *.asm) xform=asm ;; - *.c++) xform=c++ ;; - *.cc) xform=cc ;; - *.cpp) xform=cpp ;; - *.cxx) xform=cxx ;; - *.f90) xform=f90 ;; - *.for) xform=for ;; - esac - - libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` - - case $libobj in - *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; - *) - $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 - exit 1 - ;; - esac - - if test -z "$base_compile"; then - $echo "$modename: you must specify a compilation command" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - # Delete any leftover library objects. - if test "$build_old_libs" = yes; then - removelist="$obj $libobj" - else - removelist="$libobj" - fi - - $run $rm $removelist - trap "$run $rm $removelist; exit 1" 1 2 15 - - # On Cygwin there's no "real" PIC flag so we must build both object types - case $host_os in - cygwin* | mingw* | pw32* | os2*) - pic_mode=default - ;; - esac - if test $pic_mode = no && test "$deplibs_check_method" != pass_all; then - # non-PIC code in shared libraries is not supported - pic_mode=default - fi - - # Calculate the filename of the output object if compiler does - # not support -o with -c - if test "$compiler_c_o" = no; then - output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\.[^.]*$%%'`.${objext} - lockfile="$output_obj.lock" - removelist="$removelist $output_obj $lockfile" - trap "$run $rm $removelist; exit 1" 1 2 15 - else - need_locks=no - lockfile= - fi - - # Lock this critical section if it is needed - # We use this script file to make the link, it avoids creating a new file - if test "$need_locks" = yes; then - until $run ln "$0" "$lockfile" 2>/dev/null; do - $show "Waiting for $lockfile to be removed" - sleep 2 - done - elif test "$need_locks" = warn; then - if test -f "$lockfile"; then - echo "\ -*** ERROR, $lockfile exists and contains: -`cat $lockfile 2>/dev/null` - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit 1 - fi - echo $srcfile > "$lockfile" - fi - - if test -n "$fix_srcfile_path"; then - eval srcfile=\"$fix_srcfile_path\" - fi - - # Only build a PIC object if we are building libtool libraries. - if test "$build_libtool_libs" = yes; then - # Without this assignment, base_compile gets emptied. - fbsd_hideous_sh_bug=$base_compile - - if test "$pic_mode" != no; then - # All platforms use -DPIC, to notify preprocessed assembler code. - command="$base_compile $srcfile $pic_flag -DPIC" - else - # Don't build PIC code - command="$base_compile $srcfile" - fi - if test "$build_old_libs" = yes; then - lo_libobj="$libobj" - dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$dir" = "X$libobj"; then - dir="$objdir" - else - dir="$dir/$objdir" - fi - libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` - - if test -d "$dir"; then - $show "$rm $libobj" - $run $rm $libobj - else - $show "$mkdir $dir" - $run $mkdir $dir - status=$? - if test $status -ne 0 && test ! -d $dir; then - exit $status - fi - fi - fi - if test "$compiler_o_lo" = yes; then - output_obj="$libobj" - command="$command -o $output_obj" - elif test "$compiler_c_o" = yes; then - output_obj="$obj" - command="$command -o $output_obj" - fi - - $run $rm "$output_obj" - $show "$command" - if $run eval "$command"; then : - else - test -n "$output_obj" && $run $rm $removelist - exit 1 - fi - - if test "$need_locks" = warn && - test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then - echo "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit 1 - fi - - # Just move the object if needed, then go on to compile the next one - if test x"$output_obj" != x"$libobj"; then - $show "$mv $output_obj $libobj" - if $run $mv $output_obj $libobj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - fi - - # If we have no pic_flag, then copy the object into place and finish. - if (test -z "$pic_flag" || test "$pic_mode" != default) && - test "$build_old_libs" = yes; then - # Rename the .lo from within objdir to obj - if test -f $obj; then - $show $rm $obj - $run $rm $obj - fi - - $show "$mv $libobj $obj" - if $run $mv $libobj $obj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - - xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$obj"; then - xdir="." - else - xdir="$xdir" - fi - baseobj=`$echo "X$obj" | $Xsed -e "s%.*/%%"` - libobj=`$echo "X$baseobj" | $Xsed -e "$o2lo"` - # Now arrange that obj and lo_libobj become the same file - $show "(cd $xdir && $LN_S $baseobj $libobj)" - if $run eval '(cd $xdir && $LN_S $baseobj $libobj)'; then - # Unlock the critical section if it was locked - if test "$need_locks" != no; then - $run $rm "$lockfile" - fi - exit 0 - else - error=$? - $run $rm $removelist - exit $error - fi - fi - - # Allow error messages only from the first compilation. - suppress_output=' >/dev/null 2>&1' - fi - - # Only build a position-dependent object if we build old libraries. - if test "$build_old_libs" = yes; then - if test "$pic_mode" != yes; then - # Don't build PIC code - command="$base_compile $srcfile" - else - # All platforms use -DPIC, to notify preprocessed assembler code. - command="$base_compile $srcfile $pic_flag -DPIC" - fi - if test "$compiler_c_o" = yes; then - command="$command -o $obj" - output_obj="$obj" - fi - - # Suppress compiler output if we already did a PIC compilation. - command="$command$suppress_output" - $run $rm "$output_obj" - $show "$command" - if $run eval "$command"; then : - else - $run $rm $removelist - exit 1 - fi - - if test "$need_locks" = warn && - test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then - echo "\ -*** ERROR, $lockfile contains: -`cat $lockfile 2>/dev/null` - -but it should contain: -$srcfile - -This indicates that another process is trying to use the same -temporary object file, and libtool could not work around it because -your compiler does not support \`-c' and \`-o' together. If you -repeat this compilation, it may succeed, by chance, but you had better -avoid parallel builds (make -j) in this platform, or get a better -compiler." - - $run $rm $removelist - exit 1 - fi - - # Just move the object if needed - if test x"$output_obj" != x"$obj"; then - $show "$mv $output_obj $obj" - if $run $mv $output_obj $obj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - fi - - # Create an invalid libtool object if no PIC, so that we do not - # accidentally link it into a program. - if test "$build_libtool_libs" != yes; then - $show "echo timestamp > $libobj" - $run eval "echo timestamp > \$libobj" || exit $? - else - # Move the .lo from within objdir - $show "$mv $libobj $lo_libobj" - if $run $mv $libobj $lo_libobj; then : - else - error=$? - $run $rm $removelist - exit $error - fi - fi - fi - - # Unlock the critical section if it was locked - if test "$need_locks" != no; then - $run $rm "$lockfile" - fi - - exit 0 - ;; - - # libtool link mode - link | relink) - modename="$modename: link" - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - # It is impossible to link a dll without this setting, and - # we shouldn't force the makefile maintainer to figure out - # which system we are compiling for in order to pass an extra - # flag for every libtool invokation. - # allow_undefined=no - - # FIXME: Unfortunately, there are problems with the above when trying - # to make a dll which has undefined symbols, in which case not - # even a static library is built. For now, we need to specify - # -no-undefined on the libtool link line when we can be certain - # that all symbols are satisfied, otherwise we get a static library. - allow_undefined=yes - ;; - *) - allow_undefined=yes - ;; - esac - libtool_args="$nonopt" - compile_command="$nonopt" - finalize_command="$nonopt" - - compile_rpath= - finalize_rpath= - compile_shlibpath= - finalize_shlibpath= - convenience= - old_convenience= - deplibs= - old_deplibs= - compiler_flags= - linker_flags= - dllsearchpath= - lib_search_path=`pwd` - - avoid_version=no - dlfiles= - dlprefiles= - dlself=no - export_dynamic=no - export_symbols= - export_symbols_regex= - generated= - libobjs= - ltlibs= - module=no - no_install=no - objs= - prefer_static_libs=no - preload=no - prev= - prevarg= - release= - rpath= - xrpath= - perm_rpath= - temp_rpath= - thread_safe=no - vinfo= - - # We need to know -static, to get the right output filenames. - for arg - do - case $arg in - -all-static | -static) - if test "X$arg" = "X-all-static"; then - if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then - $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2 - fi - if test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - else - if test -z "$pic_flag" && test -n "$link_static_flag"; then - dlopen_self=$dlopen_self_static - fi - fi - build_libtool_libs=no - build_old_libs=yes - prefer_static_libs=yes - break - ;; - esac - done - - # See if our shared archives depend on static archives. - test -n "$old_archive_from_new_cmds" && build_old_libs=yes - - # Go through the arguments, transforming them on the way. - while test $# -gt 0; do - arg="$1" - shift - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - qarg=\"`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`\" ### testsuite: skip nested quoting test - ;; - *) qarg=$arg ;; - esac - libtool_args="$libtool_args $qarg" - - # If the previous option needs an argument, assign it. - if test -n "$prev"; then - case $prev in - output) - compile_command="$compile_command @OUTPUT@" - finalize_command="$finalize_command @OUTPUT@" - ;; - esac - - case $prev in - dlfiles|dlprefiles) - if test "$preload" = no; then - # Add the symbol object into the linking commands. - compile_command="$compile_command @SYMFILE@" - finalize_command="$finalize_command @SYMFILE@" - preload=yes - fi - case $arg in - *.la | *.lo) ;; # We handle these cases below. - force) - if test "$dlself" = no; then - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - self) - if test "$prev" = dlprefiles; then - dlself=yes - elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then - dlself=yes - else - dlself=needless - export_dynamic=yes - fi - prev= - continue - ;; - *) - if test "$prev" = dlfiles; then - dlfiles="$dlfiles $arg" - else - dlprefiles="$dlprefiles $arg" - fi - prev= - continue - ;; - esac - ;; - expsyms) - export_symbols="$arg" - if test ! -f "$arg"; then - $echo "$modename: symbol file \`$arg' does not exist" - exit 1 - fi - prev= - continue - ;; - expsyms_regex) - export_symbols_regex="$arg" - prev= - continue - ;; - release) - release="-$arg" - prev= - continue - ;; - rpath | xrpath) - # We need an absolute path. - case $arg in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - $echo "$modename: only absolute run-paths are allowed" 1>&2 - exit 1 - ;; - esac - if test "$prev" = rpath; then - case "$rpath " in - *" $arg "*) ;; - *) rpath="$rpath $arg" ;; - esac - else - case "$xrpath " in - *" $arg "*) ;; - *) xrpath="$xrpath $arg" ;; - esac - fi - prev= - continue - ;; - xcompiler) - compiler_flags="$compiler_flags $qarg" - prev= - compile_command="$compile_command $qarg" - finalize_command="$finalize_command $qarg" - continue - ;; - xlinker) - linker_flags="$linker_flags $qarg" - compiler_flags="$compiler_flags $wl$qarg" - prev= - compile_command="$compile_command $wl$qarg" - finalize_command="$finalize_command $wl$qarg" - continue - ;; - *) - eval "$prev=\"\$arg\"" - prev= - continue - ;; - esac - fi # test -n $prev - - prevarg="$arg" - - case $arg in - -all-static) - if test -n "$link_static_flag"; then - compile_command="$compile_command $link_static_flag" - finalize_command="$finalize_command $link_static_flag" - fi - continue - ;; - - -allow-undefined) - # FIXME: remove this flag sometime in the future. - $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 - continue - ;; - - -avoid-version) - avoid_version=yes - continue - ;; - - -dlopen) - prev=dlfiles - continue - ;; - - -dlpreopen) - prev=dlprefiles - continue - ;; - - -export-dynamic) - export_dynamic=yes - continue - ;; - - -export-symbols | -export-symbols-regex) - if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - $echo "$modename: more than one -exported-symbols argument is not allowed" - exit 1 - fi - if test "X$arg" = "X-export-symbols"; then - prev=expsyms - else - prev=expsyms_regex - fi - continue - ;; - - # The native IRIX linker understands -LANG:*, -LIST:* and -LNO:* - # so, if we see these flags be careful not to treat them like -L - -L[A-Z][A-Z]*:*) - case $with_gcc/$host in - no/*-*-irix*) - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - ;; - esac - continue - ;; - - -L*) - dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - $echo "$modename: cannot determine absolute directory name of \`$dir'" 1>&2 - exit 1 - fi - dir="$absdir" - ;; - esac - case "$deplibs " in - *" -L$dir "*) ;; - *) - deplibs="$deplibs -L$dir" - lib_search_path="$lib_search_path $dir" - ;; - esac - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - case :$dllsearchpath: in - *":$dir:"*) ;; - *) dllsearchpath="$dllsearchpath:$dir";; - esac - ;; - esac - continue - ;; - - -l*) - if test "X$arg" = "X-lc" || test "X$arg" = "X-lm"; then - case $host in - *-*-cygwin* | *-*-pw32* | *-*-beos*) - # These systems don't actually have a C or math library (as such) - continue - ;; - *-*-mingw* | *-*-os2*) - # These systems don't actually have a C library (as such) - test "X$arg" = "X-lc" && continue - ;; - *-*-openbsd*) - # Do not include libc due to us having libc/libc_r. - test "X$arg" = "X-lc" && continue - ;; - esac - fi - if test "X$arg" = "X-lc_r"; then - case $host in - *-*-openbsd*) - # Do not include libc_r directly, use -pthread flag. - continue - ;; - esac - fi - deplibs="$deplibs $arg" - continue - ;; - - -module) - module=yes - continue - ;; - - -no-fast-install) - fast_install=no - continue - ;; - - -no-install) - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - # The PATH hackery in wrapper scripts is required on Windows - # in order for the loader to find any dlls it needs. - $echo "$modename: warning: \`-no-install' is ignored for $host" 1>&2 - $echo "$modename: warning: assuming \`-no-fast-install' instead" 1>&2 - fast_install=no - ;; - *) no_install=yes ;; - esac - continue - ;; - - -no-undefined) - allow_undefined=no - continue - ;; - - -o) prev=output ;; - - -release) - prev=release - continue - ;; - - -rpath) - prev=rpath - continue - ;; - - -R) - prev=xrpath - continue - ;; - - -R*) - dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - $echo "$modename: only absolute run-paths are allowed" 1>&2 - exit 1 - ;; - esac - case "$xrpath " in - *" $dir "*) ;; - *) xrpath="$xrpath $dir" ;; - esac - continue - ;; - - -static) - # The effects of -static are defined in a previous loop. - # We used to do the same as -all-static on platforms that - # didn't have a PIC flag, but the assumption that the effects - # would be equivalent was wrong. It would break on at least - # Digital Unix and AIX. - continue - ;; - - -thread-safe) - thread_safe=yes - continue - ;; - - -version-info) - prev=vinfo - continue - ;; - - -Wc,*) - args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wc,//'` - arg= - IFS="${IFS= }"; save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - case $flag in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - flag="\"$flag\"" - ;; - esac - arg="$arg $wl$flag" - compiler_flags="$compiler_flags $flag" - done - IFS="$save_ifs" - arg=`$echo "X$arg" | $Xsed -e "s/^ //"` - ;; - - -Wl,*) - args=`$echo "X$arg" | $Xsed -e "$sed_quote_subst" -e 's/^-Wl,//'` - arg= - IFS="${IFS= }"; save_ifs="$IFS"; IFS=',' - for flag in $args; do - IFS="$save_ifs" - case $flag in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - flag="\"$flag\"" - ;; - esac - arg="$arg $wl$flag" - compiler_flags="$compiler_flags $wl$flag" - linker_flags="$linker_flags $flag" - done - IFS="$save_ifs" - arg=`$echo "X$arg" | $Xsed -e "s/^ //"` - ;; - - -Xcompiler) - prev=xcompiler - continue - ;; - - -Xlinker) - prev=xlinker - continue - ;; - - # Some other compiler flag. - -* | +*) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - ;; - - *.lo | *.$objext) - # A library or standard object. - if test "$prev" = dlfiles; then - # This file was specified with -dlopen. - if test "$build_libtool_libs" = yes && test "$dlopen_support" = yes; then - dlfiles="$dlfiles $arg" - prev= - continue - else - # If libtool objects are unsupported, then we need to preload. - prev=dlprefiles - fi - fi - - if test "$prev" = dlprefiles; then - # Preload the old-style object. - dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"` - prev= - else - case $arg in - *.lo) libobjs="$libobjs $arg" ;; - *) objs="$objs $arg" ;; - esac - fi - ;; - - *.$libext) - # An archive. - deplibs="$deplibs $arg" - old_deplibs="$old_deplibs $arg" - continue - ;; - - *.la) - # A libtool-controlled library. - - if test "$prev" = dlfiles; then - # This library was specified with -dlopen. - dlfiles="$dlfiles $arg" - prev= - elif test "$prev" = dlprefiles; then - # The library was specified with -dlpreopen. - dlprefiles="$dlprefiles $arg" - prev= - else - deplibs="$deplibs $arg" - fi - continue - ;; - - # Some other compiler argument. - *) - # Unknown arguments in both finalize_command and compile_command need - # to be aesthetically quoted because they are evaled later. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - arg="\"$arg\"" - ;; - esac - ;; - esac # arg - - # Now actually substitute the argument into the commands. - if test -n "$arg"; then - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - fi - done # argument parsing loop - - if test -n "$prev"; then - $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then - eval arg=\"$export_dynamic_flag_spec\" - compile_command="$compile_command $arg" - finalize_command="$finalize_command $arg" - fi - - # calculate the name of the file, without its directory - outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` - libobjs_save="$libobjs" - - if test -n "$shlibpath_var"; then - # get the directories listed in $shlibpath_var - eval shlib_search_path=\`\$echo \"X\${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\` - else - shlib_search_path= - fi - eval sys_lib_search_path=\"$sys_lib_search_path_spec\" - eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\" - - output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` - if test "X$output_objdir" = "X$output"; then - output_objdir="$objdir" - else - output_objdir="$output_objdir/$objdir" - fi - # Create the object directory. - if test ! -d $output_objdir; then - $show "$mkdir $output_objdir" - $run $mkdir $output_objdir - status=$? - if test $status -ne 0 && test ! -d $output_objdir; then - exit $status - fi - fi - - # Determine the type of output - case $output in - "") - $echo "$modename: you must specify an output file" 1>&2 - $echo "$help" 1>&2 - exit 1 - ;; - *.$libext) linkmode=oldlib ;; - *.lo | *.$objext) linkmode=obj ;; - *.la) linkmode=lib ;; - *) linkmode=prog ;; # Anything else should be a program. - esac - - specialdeplibs= - libs= - # Find all interdependent deplibs by searching for libraries - # that are linked more than once (e.g. -la -lb -la) - for deplib in $deplibs; do - case "$libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - libs="$libs $deplib" - done - deplibs= - newdependency_libs= - newlib_search_path= - need_relink=no # whether we're linking any uninstalled libtool libraries - notinst_deplibs= # not-installed libtool libraries - notinst_path= # paths that contain not-installed libtool libraries - case $linkmode in - lib) - passes="conv link" - for file in $dlfiles $dlprefiles; do - case $file in - *.la) ;; - *) - $echo "$modename: libraries can \`-dlopen' only libtool libraries: $file" 1>&2 - exit 1 - ;; - esac - done - ;; - prog) - compile_deplibs= - finalize_deplibs= - alldeplibs=no - newdlfiles= - newdlprefiles= - passes="conv scan dlopen dlpreopen link" - ;; - *) passes="conv" - ;; - esac - for pass in $passes; do - if test $linkmode = prog; then - # Determine which files to process - case $pass in - dlopen) - libs="$dlfiles" - save_deplibs="$deplibs" # Collect dlpreopened libraries - deplibs= - ;; - dlpreopen) libs="$dlprefiles" ;; - link) libs="$deplibs %DEPLIBS% $dependency_libs" ;; - esac - fi - for deplib in $libs; do - lib= - found=no - case $deplib in - -l*) - if test $linkmode = oldlib && test $linkmode = obj; then - $echo "$modename: warning: \`-l' is ignored for archives/objects: $deplib" 1>&2 - continue - fi - if test $pass = conv; then - deplibs="$deplib $deplibs" - continue - fi - name=`$echo "X$deplib" | $Xsed -e 's/^-l//'` - for searchdir in $newlib_search_path $lib_search_path $sys_lib_search_path $shlib_search_path; do - # Search the libtool library - lib="$searchdir/lib${name}.la" - if test -f "$lib"; then - found=yes - break - fi - done - if test "$found" != yes; then - # deplib doesn't seem to be a libtool library - if test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - deplibs="$deplib $deplibs" - test $linkmode = lib && newdependency_libs="$deplib $newdependency_libs" - fi - continue - fi - ;; # -l - -L*) - case $linkmode in - lib) - deplibs="$deplib $deplibs" - test $pass = conv && continue - newdependency_libs="$deplib $newdependency_libs" - newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` - ;; - prog) - if test $pass = conv; then - deplibs="$deplib $deplibs" - continue - fi - if test $pass = scan; then - deplibs="$deplib $deplibs" - newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'` - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - ;; - *) - $echo "$modename: warning: \`-L' is ignored for archives/objects: $deplib" 1>&2 - ;; - esac # linkmode - continue - ;; # -L - -R*) - if test $pass = link; then - dir=`$echo "X$deplib" | $Xsed -e 's/^-R//'` - # Make sure the xrpath contains only unique directories. - case "$xrpath " in - *" $dir "*) ;; - *) xrpath="$xrpath $dir" ;; - esac - fi - deplibs="$deplib $deplibs" - continue - ;; - *.la) lib="$deplib" ;; - *.$libext) - if test $pass = conv; then - deplibs="$deplib $deplibs" - continue - fi - case $linkmode in - lib) - if test "$deplibs_check_method" != pass_all; then - echo - echo "*** Warning: This library needs some functionality provided by $deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have." - else - echo - echo "*** Warning: Linking the shared library $output against the" - echo "*** static library $deplib is not portable!" - deplibs="$deplib $deplibs" - fi - continue - ;; - prog) - if test $pass != link; then - deplibs="$deplib $deplibs" - else - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - fi - continue - ;; - esac # linkmode - ;; # *.$libext - *.lo | *.$objext) - if test $pass = dlpreopen || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then - # If there is no dlopen support or we're linking statically, - # we need to preload. - newdlprefiles="$newdlprefiles $deplib" - compile_deplibs="$deplib $compile_deplibs" - finalize_deplibs="$deplib $finalize_deplibs" - else - newdlfiles="$newdlfiles $deplib" - fi - continue - ;; - %DEPLIBS%) - alldeplibs=yes - continue - ;; - esac # case $deplib - if test $found = yes || test -f "$lib"; then : - else - $echo "$modename: cannot find the library \`$lib'" 1>&2 - exit 1 - fi - - # Check to see that this really is a libtool archive. - if (sed -e '2q' $lib | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit 1 - fi - - ladir=`$echo "X$lib" | $Xsed -e 's%/[^/]*$%%'` - test "X$ladir" = "X$lib" && ladir="." - - dlname= - dlopen= - dlpreopen= - libdir= - library_names= - old_library= - # If the library was installed with an old release of libtool, - # it will not redefine variable installed. - installed=yes - - # Read the .la file - case $lib in - */* | *\\*) . $lib ;; - *) . ./$lib ;; - esac - - if test "$linkmode,$pass" = "lib,link" || - test "$linkmode,$pass" = "prog,scan" || - { test $linkmode = oldlib && test $linkmode = obj; }; then - # Add dl[pre]opened files of deplib - test -n "$dlopen" && dlfiles="$dlfiles $dlopen" - test -n "$dlpreopen" && dlprefiles="$dlprefiles $dlpreopen" - fi - - if test $pass = conv; then - # Only check for convenience libraries - deplibs="$lib $deplibs" - if test -z "$libdir"; then - if test -z "$old_library"; then - $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 - exit 1 - fi - # It is a libtool convenience library, so add in its objects. - convenience="$convenience $ladir/$objdir/$old_library" - old_convenience="$old_convenience $ladir/$objdir/$old_library" - tmp_libs= - for deplib in $dependency_libs; do - deplibs="$deplib $deplibs" - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - tmp_libs="$tmp_libs $deplib" - done - elif test $linkmode != prog && test $linkmode != lib; then - $echo "$modename: \`$lib' is not a convenience library" 1>&2 - exit 1 - fi - continue - fi # $pass = conv - - # Get the name of the library we link against. - linklib= - for l in $old_library $library_names; do - linklib="$l" - done - if test -z "$linklib"; then - $echo "$modename: cannot find name of link library for \`$lib'" 1>&2 - exit 1 - fi - - # This library was specified with -dlopen. - if test $pass = dlopen; then - if test -z "$libdir"; then - $echo "$modename: cannot -dlopen a convenience library: \`$lib'" 1>&2 - exit 1 - fi - if test -z "$dlname" || test "$dlopen_support" != yes || test "$build_libtool_libs" = no; then - # If there is no dlname, no dlopen support or we're linking - # statically, we need to preload. - dlprefiles="$dlprefiles $lib" - else - newdlfiles="$newdlfiles $lib" - fi - continue - fi # $pass = dlopen - - # We need an absolute path. - case $ladir in - [\\/]* | [A-Za-z]:[\\/]*) abs_ladir="$ladir" ;; - *) - abs_ladir=`cd "$ladir" && pwd` - if test -z "$abs_ladir"; then - $echo "$modename: warning: cannot determine absolute directory name of \`$ladir'" 1>&2 - $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 - abs_ladir="$ladir" - fi - ;; - esac - laname=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - - # Find the relevant object directory and library name. - if test "X$installed" = Xyes; then - if test ! -f "$libdir/$linklib" && test -f "$abs_ladir/$linklib"; then - $echo "$modename: warning: library \`$lib' was moved." 1>&2 - dir="$ladir" - absdir="$abs_ladir" - libdir="$abs_ladir" - else - dir="$libdir" - absdir="$libdir" - fi - else - dir="$ladir/$objdir" - absdir="$abs_ladir/$objdir" - # Remove this search path later - notinst_path="$notinst_path $abs_ladir" - fi # $installed = yes - name=`$echo "X$laname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` - - # This library was specified with -dlpreopen. - if test $pass = dlpreopen; then - if test -z "$libdir"; then - $echo "$modename: cannot -dlpreopen a convenience library: \`$lib'" 1>&2 - exit 1 - fi - # Prefer using a static library (so that no silly _DYNAMIC symbols - # are required to link). - if test -n "$old_library"; then - newdlprefiles="$newdlprefiles $dir/$old_library" - # Otherwise, use the dlname, so that lt_dlopen finds it. - elif test -n "$dlname"; then - newdlprefiles="$newdlprefiles $dir/$dlname" - else - newdlprefiles="$newdlprefiles $dir/$linklib" - fi - fi # $pass = dlpreopen - - if test -z "$libdir"; then - # Link the convenience library - if test $linkmode = lib; then - deplibs="$dir/$old_library $deplibs" - elif test "$linkmode,$pass" = "prog,link"; then - compile_deplibs="$dir/$old_library $compile_deplibs" - finalize_deplibs="$dir/$old_library $finalize_deplibs" - else - deplibs="$lib $deplibs" - fi - continue - fi - - if test $linkmode = prog && test $pass != link; then - newlib_search_path="$newlib_search_path $ladir" - deplibs="$lib $deplibs" - - linkalldeplibs=no - if test "$link_all_deplibs" != no || test -z "$library_names" || - test "$build_libtool_libs" = no; then - linkalldeplibs=yes - fi - - tmp_libs= - for deplib in $dependency_libs; do - case $deplib in - -L*) newlib_search_path="$newlib_search_path "`$echo "X$deplib" | $Xsed -e 's/^-L//'`;; ### testsuite: skip nested quoting test - esac - # Need to link against all dependency_libs? - if test $linkalldeplibs = yes; then - deplibs="$deplib $deplibs" - else - # Need to hardcode shared library paths - # or/and link against static libraries - newdependency_libs="$deplib $newdependency_libs" - fi - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - tmp_libs="$tmp_libs $deplib" - done # for deplib - continue - fi # $linkmode = prog... - - link_static=no # Whether the deplib will be linked statically - if test -n "$library_names" && - { test "$prefer_static_libs" = no || test -z "$old_library"; }; then - # Link against this shared library - - if test "$linkmode,$pass" = "prog,link" || - { test $linkmode = lib && test $hardcode_into_libs = yes; }; then - # Hardcode the library path. - # Skip directories that are in the system default run-time - # search path. - case " $sys_lib_dlsearch_path " in - *" $absdir "*) ;; - *) - case "$compile_rpath " in - *" $absdir "*) ;; - *) compile_rpath="$compile_rpath $absdir" - esac - ;; - esac - case " $sys_lib_dlsearch_path " in - *" $libdir "*) ;; - *) - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" - esac - ;; - esac - if test $linkmode = prog; then - # We need to hardcode the library path - if test -n "$shlibpath_var"; then - # Make sure the rpath contains only unique directories. - case "$temp_rpath " in - *" $dir "*) ;; - *" $absdir "*) ;; - *) temp_rpath="$temp_rpath $dir" ;; - esac - fi - fi - fi # $linkmode,$pass = prog,link... - - if test "$alldeplibs" = yes && - { test "$deplibs_check_method" = pass_all || - { test "$build_libtool_libs" = yes && - test -n "$library_names"; }; }; then - # We only need to search for static libraries - continue - fi - - if test "$installed" = no; then - notinst_deplibs="$notinst_deplibs $lib" - need_relink=yes - fi - - if test -n "$old_archive_from_expsyms_cmds"; then - # figure out the soname - set dummy $library_names - realname="$2" - shift; shift - libname=`eval \\$echo \"$libname_spec\"` - # use dlname if we got it. it's perfectly good, no? - if test -n "$dlname"; then - soname="$dlname" - elif test -n "$soname_spec"; then - # bleh windows - case $host in - *cygwin*) - major=`expr $current - $age` - versuffix="-$major" - ;; - esac - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - - # Make a new name for the extract_expsyms_cmds to use - soroot="$soname" - soname=`echo $soroot | sed -e 's/^.*\///'` - newlib="libimp-`echo $soname | sed 's/^lib//;s/\.dll$//'`.a" - - # If the library has no export list, then create one now - if test -f "$output_objdir/$soname-def"; then : - else - $show "extracting exported symbol list from \`$soname'" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - eval cmds=\"$extract_expsyms_cmds\" - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - - # Create $newlib - if test -f "$output_objdir/$newlib"; then :; else - $show "generating import library for \`$soname'" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - eval cmds=\"$old_archive_from_expsyms_cmds\" - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - # make sure the library variables are pointing to the new library - dir=$output_objdir - linklib=$newlib - fi # test -n $old_archive_from_expsyms_cmds - - if test $linkmode = prog || test "$mode" != relink; then - add_shlibpath= - add_dir= - add= - lib_linked=yes - case $hardcode_action in - immediate | unsupported) - if test "$hardcode_direct" = no; then - add="$dir/$linklib" - elif test "$hardcode_minus_L" = no; then - case $host in - *-*-sunos*) add_shlibpath="$dir" ;; - esac - add_dir="-L$dir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = no; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - relink) - if test "$hardcode_direct" = yes; then - add="$dir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$dir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - add_shlibpath="$dir" - add="-l$name" - else - lib_linked=no - fi - ;; - *) lib_linked=no ;; - esac - - if test "$lib_linked" != yes; then - $echo "$modename: configuration error: unsupported hardcode properties" - exit 1 - fi - - if test -n "$add_shlibpath"; then - case :$compile_shlibpath: in - *":$add_shlibpath:"*) ;; - *) compile_shlibpath="$compile_shlibpath$add_shlibpath:" ;; - esac - fi - if test $linkmode = prog; then - test -n "$add_dir" && compile_deplibs="$add_dir $compile_deplibs" - test -n "$add" && compile_deplibs="$add $compile_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - if test "$hardcode_direct" != yes && \ - test "$hardcode_minus_L" != yes && \ - test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; - esac - fi - fi - fi - - if test $linkmode = prog || test "$mode" = relink; then - add_shlibpath= - add_dir= - add= - # Finalize command for both is simple: just hardcode it. - if test "$hardcode_direct" = yes; then - add="$libdir/$linklib" - elif test "$hardcode_minus_L" = yes; then - add_dir="-L$libdir" - add="-l$name" - elif test "$hardcode_shlibpath_var" = yes; then - case :$finalize_shlibpath: in - *":$libdir:"*) ;; - *) finalize_shlibpath="$finalize_shlibpath$libdir:" ;; - esac - add="-l$name" - else - # We cannot seem to hardcode it, guess we'll fake it. - add_dir="-L$libdir" - add="-l$name" - fi - - if test $linkmode = prog; then - test -n "$add_dir" && finalize_deplibs="$add_dir $finalize_deplibs" - test -n "$add" && finalize_deplibs="$add $finalize_deplibs" - else - test -n "$add_dir" && deplibs="$add_dir $deplibs" - test -n "$add" && deplibs="$add $deplibs" - fi - fi - elif test $linkmode = prog; then - if test "$alldeplibs" = yes && - { test "$deplibs_check_method" = pass_all || - { test "$build_libtool_libs" = yes && - test -n "$library_names"; }; }; then - # We only need to search for static libraries - continue - fi - - # Try to link the static library - # Here we assume that one of hardcode_direct or hardcode_minus_L - # is not unsupported. This is valid on all known static and - # shared platforms. - if test "$hardcode_direct" != unsupported; then - test -n "$old_library" && linklib="$old_library" - compile_deplibs="$dir/$linklib $compile_deplibs" - finalize_deplibs="$dir/$linklib $finalize_deplibs" - else - compile_deplibs="-l$name -L$dir $compile_deplibs" - finalize_deplibs="-l$name -L$dir $finalize_deplibs" - fi - elif test "$build_libtool_libs" = yes; then - # Not a shared library - if test "$deplibs_check_method" != pass_all; then - # We're trying link a shared library against a static one - # but the system doesn't support it. - - # Just print a warning and add the library to dependency_libs so - # that the program can be linked against the static library. - echo - echo "*** Warning: This library needs some functionality provided by $lib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have." - if test "$module" = yes; then - echo "*** Therefore, libtool will create a static module, that should work " - echo "*** as long as the dlopening application is linked with the -dlopen flag." - if test -z "$global_symbol_pipe"; then - echo - echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - echo "*** not find such a program. So, this module is probably useless." - echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - else - convenience="$convenience $dir/$old_library" - old_convenience="$old_convenience $dir/$old_library" - deplibs="$dir/$old_library $deplibs" - link_static=yes - fi - fi # link shared/static library? - - if test $linkmode = lib; then - if test -n "$dependency_libs" && - { test $hardcode_into_libs != yes || test $build_old_libs = yes || - test $link_static = yes; }; then - # Extract -R from dependency_libs - temp_deplibs= - for libdir in $dependency_libs; do - case $libdir in - -R*) temp_xrpath=`$echo "X$libdir" | $Xsed -e 's/^-R//'` - case " $xrpath " in - *" $temp_xrpath "*) ;; - *) xrpath="$xrpath $temp_xrpath";; - esac;; - *) temp_deplibs="$temp_deplibs $libdir";; - esac - done - dependency_libs="$temp_deplibs" - fi - - newlib_search_path="$newlib_search_path $absdir" - # Link against this library - test "$link_static" = no && newdependency_libs="$abs_ladir/$laname $newdependency_libs" - # ... and its dependency_libs - tmp_libs= - for deplib in $dependency_libs; do - newdependency_libs="$deplib $newdependency_libs" - case "$tmp_libs " in - *" $deplib "*) specialdeplibs="$specialdeplibs $deplib" ;; - esac - tmp_libs="$tmp_libs $deplib" - done - - if test $link_all_deplibs != no; then - # Add the search paths of all dependency libraries - for deplib in $dependency_libs; do - case $deplib in - -L*) path="$deplib" ;; - *.la) - dir=`$echo "X$deplib" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$deplib" && dir="." - # We need an absolute path. - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) absdir="$dir" ;; - *) - absdir=`cd "$dir" && pwd` - if test -z "$absdir"; then - $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 - absdir="$dir" - fi - ;; - esac - if grep "^installed=no" $deplib > /dev/null; then - path="-L$absdir/$objdir" - else - eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - if test -z "$libdir"; then - $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 - exit 1 - fi - if test "$absdir" != "$libdir"; then - $echo "$modename: warning: \`$deplib' seems to be moved" 1>&2 - fi - path="-L$absdir" - fi - ;; - *) continue ;; - esac - case " $deplibs " in - *" $path "*) ;; - *) deplibs="$deplibs $path" ;; - esac - done - fi # link_all_deplibs != no - fi # linkmode = lib - done # for deplib in $libs - if test $pass = dlpreopen; then - # Link the dlpreopened libraries before other libraries - for deplib in $save_deplibs; do - deplibs="$deplib $deplibs" - done - fi - if test $pass != dlopen; then - test $pass != scan && dependency_libs="$newdependency_libs" - if test $pass != conv; then - # Make sure lib_search_path contains only unique directories. - lib_search_path= - for dir in $newlib_search_path; do - case "$lib_search_path " in - *" $dir "*) ;; - *) lib_search_path="$lib_search_path $dir" ;; - esac - done - newlib_search_path= - fi - - if test "$linkmode,$pass" != "prog,link"; then - vars="deplibs" - else - vars="compile_deplibs finalize_deplibs" - fi - for var in $vars dependency_libs; do - # Add libraries to $var in reverse order - eval tmp_libs=\"\$$var\" - new_libs= - for deplib in $tmp_libs; do - case $deplib in - -L*) new_libs="$deplib $new_libs" ;; - *) - case " $specialdeplibs " in - *" $deplib "*) new_libs="$deplib $new_libs" ;; - *) - case " $new_libs " in - *" $deplib "*) ;; - *) new_libs="$deplib $new_libs" ;; - esac - ;; - esac - ;; - esac - done - tmp_libs= - for deplib in $new_libs; do - case $deplib in - -L*) - case " $tmp_libs " in - *" $deplib "*) ;; - *) tmp_libs="$tmp_libs $deplib" ;; - esac - ;; - *) tmp_libs="$tmp_libs $deplib" ;; - esac - done - eval $var=\"$tmp_libs\" - done # for var - fi - if test "$pass" = "conv" && - { test "$linkmode" = "lib" || test "$linkmode" = "prog"; }; then - libs="$deplibs" # reset libs - deplibs= - fi - done # for pass - if test $linkmode = prog; then - dlfiles="$newdlfiles" - dlprefiles="$newdlprefiles" - fi - - case $linkmode in - oldlib) - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 - fi - - if test -n "$rpath"; then - $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 - fi - - if test -n "$xrpath"; then - $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 - fi - - if test -n "$export_symbols" || test -n "$export_symbols_regex"; then - $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 - fi - - # Now set the variables for building old libraries. - build_libtool_libs=no - oldlibs="$output" - objs="$objs$old_deplibs" - ;; - - lib) - # Make sure we only generate libraries of the form `libNAME.la'. - case $outputname in - lib*) - name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` - eval libname=\"$libname_spec\" - ;; - *) - if test "$module" = no; then - $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - if test "$need_lib_prefix" != no; then - # Add the "lib" prefix for modules if required - name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` - eval libname=\"$libname_spec\" - else - libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` - fi - ;; - esac - - if test -n "$objs"; then - if test "$deplibs_check_method" != pass_all; then - $echo "$modename: cannot build libtool library \`$output' from non-libtool objects on this host:$objs" 2>&1 - exit 1 - else - echo - echo "*** Warning: Linking the shared library $output against the non-libtool" - echo "*** objects $objs is not portable!" - libobjs="$libobjs $objs" - fi - fi - - if test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen self' is ignored for libtool libraries" 1>&2 - fi - - set dummy $rpath - if test $# -gt 2; then - $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 - fi - install_libdir="$2" - - oldlibs= - if test -z "$rpath"; then - if test "$build_libtool_libs" = yes; then - # Building a libtool convenience library. - libext=al - oldlibs="$output_objdir/$libname.$libext $oldlibs" - build_libtool_libs=convenience - build_old_libs=yes - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 - fi - else - - # Parse the version information argument. - IFS="${IFS= }"; save_ifs="$IFS"; IFS=':' - set dummy $vinfo 0 0 0 - IFS="$save_ifs" - - if test -n "$8"; then - $echo "$modename: too many parameters to \`-version-info'" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - current="$2" - revision="$3" - age="$4" - - # Check that each of the things are valid numbers. - case $current in - 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; - *) - $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit 1 - ;; - esac - - case $revision in - 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; - *) - $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit 1 - ;; - esac - - case $age in - 0 | [1-9] | [1-9][0-9] | [1-9][0-9][0-9]) ;; - *) - $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit 1 - ;; - esac - - if test $age -gt $current; then - $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 - $echo "$modename: \`$vinfo' is not valid version information" 1>&2 - exit 1 - fi - - # Calculate the version variables. - major= - versuffix= - verstring= - case $version_type in - none) ;; - - darwin) - # Like Linux, but with the current version available in - # verstring for coding it into the library header - major=.`expr $current - $age` - versuffix="$major.$age.$revision" - # Darwin ld doesn't like 0 for these options... - minor_current=`expr $current + 1` - verstring="-compatibility_version $minor_current -current_version $minor_current.$revision" - ;; - - freebsd-aout) - major=".$current" - versuffix=".$current.$revision"; - ;; - - freebsd-elf) - major=".$current" - versuffix=".$current"; - ;; - - irix) - major=`expr $current - $age + 1` - verstring="sgi$major.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$revision - while test $loop != 0; do - iface=`expr $revision - $loop` - loop=`expr $loop - 1` - verstring="sgi$major.$iface:$verstring" - done - - # Before this point, $major must not contain `.'. - major=.$major - versuffix="$major.$revision" - ;; - - linux) - major=.`expr $current - $age` - versuffix="$major.$age.$revision" - ;; - - osf) - major=`expr $current - $age` - versuffix=".$current.$age.$revision" - verstring="$current.$age.$revision" - - # Add in all the interfaces that we are compatible with. - loop=$age - while test $loop != 0; do - iface=`expr $current - $loop` - loop=`expr $loop - 1` - verstring="$verstring:${iface}.0" - done - - # Make executables depend on our current version. - verstring="$verstring:${current}.0" - ;; - - sunos) - major=".$current" - versuffix=".$current.$revision" - ;; - - windows) - # Use '-' rather than '.', since we only want one - # extension on DOS 8.3 filesystems. - major=`expr $current - $age` - versuffix="-$major" - ;; - - *) - $echo "$modename: unknown library version type \`$version_type'" 1>&2 - echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 - exit 1 - ;; - esac - - # Clear the version info if we defaulted, and they specified a release. - if test -z "$vinfo" && test -n "$release"; then - major= - verstring="0.0" - case $version_type in - darwin) - # we can't check for "0.0" in archive_cmds due to quoting - # problems, so we reset it completely - verstring="" - ;; - *) - verstring="0.0" - ;; - esac - if test "$need_version" = no; then - versuffix= - else - versuffix=".0.0" - fi - fi - - # Remove version info from name if versioning should be avoided - if test "$avoid_version" = yes && test "$need_version" = no; then - major= - versuffix= - verstring="" - fi - - # Check to see if the archive will have undefined symbols. - if test "$allow_undefined" = yes; then - if test "$allow_undefined_flag" = unsupported; then - $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 - build_libtool_libs=no - build_old_libs=yes - fi - else - # Don't allow undefined symbols. - allow_undefined_flag="$no_undefined_flag" - fi - fi - - if test "$mode" != relink; then - # Remove our outputs. - $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*" - $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.* - fi - - # Now set the variables for building old libraries. - if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then - oldlibs="$oldlibs $output_objdir/$libname.$libext" - - # Transform .lo files to .o files. - oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` - fi - - # Eliminate all temporary directories. - for path in $notinst_path; do - lib_search_path=`echo "$lib_search_path " | sed -e 's% $path % %g'` - deplibs=`echo "$deplibs " | sed -e 's% -L$path % %g'` - dependency_libs=`echo "$dependency_libs " | sed -e 's% -L$path % %g'` - done - - if test -n "$xrpath"; then - # If the user specified any rpath flags, then add them. - temp_xrpath= - for libdir in $xrpath; do - temp_xrpath="$temp_xrpath -R$libdir" - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" ;; - esac - done - if test $hardcode_into_libs != yes || test $build_old_libs = yes; then - dependency_libs="$temp_xrpath $dependency_libs" - fi - fi - - # Make sure dlfiles contains only unique files that won't be dlpreopened - old_dlfiles="$dlfiles" - dlfiles= - for lib in $old_dlfiles; do - case " $dlprefiles $dlfiles " in - *" $lib "*) ;; - *) dlfiles="$dlfiles $lib" ;; - esac - done - - # Make sure dlprefiles contains only unique files - old_dlprefiles="$dlprefiles" - dlprefiles= - for lib in $old_dlprefiles; do - case "$dlprefiles " in - *" $lib "*) ;; - *) dlprefiles="$dlprefiles $lib" ;; - esac - done - - if test "$build_libtool_libs" = yes; then - if test -n "$rpath"; then - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-*-beos*) - # these systems don't actually have a c library (as such)! - ;; - *-*-rhapsody* | *-*-darwin1.[012]) - # Rhapsody C library is in the System framework - deplibs="$deplibs -framework System" - ;; - *-*-netbsd*) - # Don't link with libc until the a.out ld.so is fixed. - ;; - *-*-openbsd*) - # Do not include libc due to us having libc/libc_r. - ;; - *) - # Add libc to deplibs on all other systems if necessary. - if test $build_libtool_need_lc = "yes"; then - deplibs="$deplibs -lc" - fi - ;; - esac - fi - - # Transform deplibs into only deplibs that can be linked in shared. - name_save=$name - libname_save=$libname - release_save=$release - versuffix_save=$versuffix - major_save=$major - # I'm not sure if I'm treating the release correctly. I think - # release should show up in the -l (ie -lgmp5) so we don't want to - # add it in twice. Is that correct? - release="" - versuffix="" - major="" - newdeplibs= - droppeddeps=no - case $deplibs_check_method in - pass_all) - # Don't check for shared/static. Everything works. - # This might be a little naive. We might want to check - # whether the library exists or not. But this is on - # osf3 & osf4 and I'm not really sure... Just - # implementing what was already the behaviour. - newdeplibs=$deplibs - ;; - test_compile) - # This code stresses the "libraries are programs" paradigm to its - # limits. Maybe even breaks it. We compile a program, linking it - # against the deplibs as a proxy for the library. Then we can check - # whether they linked in statically or dynamically with ldd. - $rm conftest.c - cat > conftest.c </dev/null` - for potent_lib in $potential_libs; do - # Follow soft links. - if ls -lLd "$potent_lib" 2>/dev/null \ - | grep " -> " >/dev/null; then - continue - fi - # The statement above tries to avoid entering an - # endless loop below, in case of cyclic links. - # We might still enter an endless loop, since a link - # loop can be closed while we follow links, - # but so what? - potlib="$potent_lib" - while test -h "$potlib" 2>/dev/null; do - potliblink=`ls -ld $potlib | sed 's/.* -> //'` - case $potliblink in - [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; - *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; - esac - done - if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ - | sed 10q \ - | egrep "$file_magic_regex" > /dev/null; then - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - break 2 - fi - done - done - if test -n "$a_deplib" ; then - droppeddeps=yes - echo - echo "*** Warning: This library needs some functionality provided by $a_deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have." - fi - else - # Add a -L argument. - newdeplibs="$newdeplibs $a_deplib" - fi - done # Gone through all deplibs. - ;; - match_pattern*) - set dummy $deplibs_check_method - match_pattern_regex=`expr "$deplibs_check_method" : "$2 \(.*\)"` - for a_deplib in $deplibs; do - name="`expr $a_deplib : '-l\(.*\)'`" - # If $name is empty we are operating on a -L argument. - if test -n "$name" && test "$name" != "0"; then - libname=`eval \\$echo \"$libname_spec\"` - for i in $lib_search_path $sys_lib_search_path $shlib_search_path; do - potential_libs=`ls $i/$libname[.-]* 2>/dev/null` - for potent_lib in $potential_libs; do - if eval echo \"$potent_lib\" 2>/dev/null \ - | sed 10q \ - | egrep "$match_pattern_regex" > /dev/null; then - newdeplibs="$newdeplibs $a_deplib" - a_deplib="" - break 2 - fi - done - done - if test -n "$a_deplib" ; then - droppeddeps=yes - echo - echo "*** Warning: This library needs some functionality provided by $a_deplib." - echo "*** I have the capability to make that library automatically link in when" - echo "*** you link to this library. But I can only do this if you have a" - echo "*** shared version of the library, which you do not appear to have." - fi - else - # Add a -L argument. - newdeplibs="$newdeplibs $a_deplib" - fi - done # Gone through all deplibs. - ;; - none | unknown | *) - newdeplibs="" - if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ - -e 's/ -[LR][^ ]*//g' -e 's/[ ]//g' | - grep . >/dev/null; then - echo - if test "X$deplibs_check_method" = "Xnone"; then - echo "*** Warning: inter-library dependencies are not supported in this platform." - else - echo "*** Warning: inter-library dependencies are not known to be supported." - fi - echo "*** All declared inter-library dependencies are being dropped." - droppeddeps=yes - fi - ;; - esac - versuffix=$versuffix_save - major=$major_save - release=$release_save - libname=$libname_save - name=$name_save - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library is the System framework - newdeplibs=`$echo "X $newdeplibs" | $Xsed -e 's/ -lc / -framework System /'` - ;; - esac - - if test "$droppeddeps" = yes; then - if test "$module" = yes; then - echo - echo "*** Warning: libtool could not satisfy all declared inter-library" - echo "*** dependencies of module $libname. Therefore, libtool will create" - echo "*** a static module, that should work as long as the dlopening" - echo "*** application is linked with the -dlopen flag." - if test -z "$global_symbol_pipe"; then - echo - echo "*** However, this would only work if libtool was able to extract symbol" - echo "*** lists from a program, using \`nm' or equivalent, but libtool could" - echo "*** not find such a program. So, this module is probably useless." - echo "*** \`nm' from GNU binutils and a full rebuild may help." - fi - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - else - echo "*** The inter-library dependencies that have been dropped here will be" - echo "*** automatically added whenever a program is linked with this library" - echo "*** or is declared to -dlopen it." - - if test $allow_undefined = no; then - echo - echo "*** Since this library must not contain undefined symbols," - echo "*** because either the platform does not support them or" - echo "*** it was explicitly requested with -no-undefined," - echo "*** libtool will only create a static version of it." - if test "$build_old_libs" = no; then - oldlibs="$output_objdir/$libname.$libext" - build_libtool_libs=module - build_old_libs=yes - else - build_libtool_libs=no - fi - fi - fi - fi - # Done checking deplibs! - deplibs=$newdeplibs - fi - - # All the library-specific variables (install_libdir is set above). - library_names= - old_library= - dlname= - - # Test again, we may have decided not to build it any more - if test "$build_libtool_libs" = yes; then - if test $hardcode_into_libs = yes; then - # Hardcode the library paths - hardcode_libdirs= - dep_rpath= - rpath="$finalize_rpath" - test "$mode" != relink && rpath="$compile_rpath$rpath" - for libdir in $rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - dep_rpath="$dep_rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) perm_rpath="$perm_rpath $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval dep_rpath=\"$hardcode_libdir_flag_spec\" - fi - if test -n "$runpath_var" && test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - rpath="$rpath$dir:" - done - eval "$runpath_var='$rpath\$$runpath_var'; export $runpath_var" - fi - test -n "$dep_rpath" && deplibs="$dep_rpath $deplibs" - fi - - shlibpath="$finalize_shlibpath" - test "$mode" != relink && shlibpath="$compile_shlibpath$shlibpath" - if test -n "$shlibpath"; then - eval "$shlibpath_var='$shlibpath\$$shlibpath_var'; export $shlibpath_var" - fi - - # Get the real and link names of the library. - eval library_names=\"$library_names_spec\" - set dummy $library_names - realname="$2" - shift; shift - - if test -n "$soname_spec"; then - eval soname=\"$soname_spec\" - else - soname="$realname" - fi - test -z "$dlname" && dlname=$soname - - lib="$output_objdir/$realname" - for link - do - linknames="$linknames $link" - done - - # Ensure that we have .o objects for linkers which dislike .lo - # (e.g. aix) in case we are running --disable-static - for obj in $libobjs; do - xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$obj"; then - xdir="." - else - xdir="$xdir" - fi - baseobj=`$echo "X$obj" | $Xsed -e 's%^.*/%%'` - oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` - if test ! -f $xdir/$oldobj; then - $show "(cd $xdir && ${LN_S} $baseobj $oldobj)" - $run eval '(cd $xdir && ${LN_S} $baseobj $oldobj)' || exit $? - fi - done - - # Use standard objects if they are pic - test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then - $show "generating symbol list for \`$libname.la'" - export_symbols="$output_objdir/$libname.exp" - $run $rm $export_symbols - eval cmds=\"$export_symbols_cmds\" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - if test -n "$export_symbols_regex"; then - $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" - $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' - $show "$mv \"${export_symbols}T\" \"$export_symbols\"" - $run eval '$mv "${export_symbols}T" "$export_symbols"' - fi - fi - fi - - if test -n "$export_symbols" && test -n "$include_expsyms"; then - $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' - fi - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec"; then - eval libobjs=\"\$libobjs $whole_archive_flag_spec\" - else - gentop="$output_objdir/${outputname}x" - $show "${rm}r $gentop" - $run ${rm}r "$gentop" - $show "mkdir $gentop" - $run mkdir "$gentop" - status=$? - if test $status -ne 0 && test ! -d "$gentop"; then - exit $status - fi - generated="$generated $gentop" - - for xlib in $convenience; do - # Extract the objects. - case $xlib in - [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; - *) xabs=`pwd`"/$xlib" ;; - esac - xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` - xdir="$gentop/$xlib" - - $show "${rm}r $xdir" - $run ${rm}r "$xdir" - $show "mkdir $xdir" - $run mkdir "$xdir" - status=$? - if test $status -ne 0 && test ! -d "$xdir"; then - exit $status - fi - $show "(cd $xdir && $AR x $xabs)" - $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? - - libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` - done - fi - fi - - if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then - eval flag=\"$thread_safe_flag_spec\" - linker_flags="$linker_flags $flag" - fi - - # Make a backup of the uninstalled library when relinking - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}U && $mv $realname ${realname}U)' || exit $? - fi - - # Do each of the archive commands. - if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then - eval cmds=\"$archive_expsym_cmds\" - else - eval cmds=\"$archive_cmds\" - fi - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - - # Restore the uninstalled library and exit - if test "$mode" = relink; then - $run eval '(cd $output_objdir && $rm ${realname}T && $mv $realname ${realname}T && $mv "$realname"U $realname)' || exit $? - exit 0 - fi - - # Create links to the real library. - for linkname in $linknames; do - if test "$realname" != "$linkname"; then - $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" - $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? - fi - done - - # If -module or -export-dynamic was specified, set the dlname. - if test "$module" = yes || test "$export_dynamic" = yes; then - # On all known operating systems, these are identical. - dlname="$soname" - fi - fi - ;; - - obj) - if test -n "$deplibs"; then - $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 - fi - - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 - fi - - if test -n "$rpath"; then - $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 - fi - - if test -n "$xrpath"; then - $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 - fi - - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 - fi - - case $output in - *.lo) - if test -n "$objs$old_deplibs"; then - $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 - exit 1 - fi - libobj="$output" - obj=`$echo "X$output" | $Xsed -e "$lo2o"` - ;; - *) - libobj= - obj="$output" - ;; - esac - - # Delete the old objects. - $run $rm $obj $libobj - - # Objects from convenience libraries. This assumes - # single-version convenience libraries. Whenever we create - # different ones for PIC/non-PIC, this we'll have to duplicate - # the extraction. - reload_conv_objs= - gentop= - # reload_cmds runs $LD directly, so let us get rid of - # -Wl from whole_archive_flag_spec - wl= - - if test -n "$convenience"; then - if test -n "$whole_archive_flag_spec"; then - eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" - else - gentop="$output_objdir/${obj}x" - $show "${rm}r $gentop" - $run ${rm}r "$gentop" - $show "mkdir $gentop" - $run mkdir "$gentop" - status=$? - if test $status -ne 0 && test ! -d "$gentop"; then - exit $status - fi - generated="$generated $gentop" - - for xlib in $convenience; do - # Extract the objects. - case $xlib in - [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; - *) xabs=`pwd`"/$xlib" ;; - esac - xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` - xdir="$gentop/$xlib" - - $show "${rm}r $xdir" - $run ${rm}r "$xdir" - $show "mkdir $xdir" - $run mkdir "$xdir" - status=$? - if test $status -ne 0 && test ! -d "$xdir"; then - exit $status - fi - $show "(cd $xdir && $AR x $xabs)" - $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? - - reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` - done - fi - fi - - # Create the old-style object. - reload_objs="$objs$old_deplibs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" ### testsuite: skip nested quoting test - - output="$obj" - eval cmds=\"$reload_cmds\" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - - # Exit if we aren't doing a library object file. - if test -z "$libobj"; then - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - exit 0 - fi - - if test "$build_libtool_libs" != yes; then - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - # Create an invalid libtool object if no PIC, so that we don't - # accidentally link it into a program. - $show "echo timestamp > $libobj" - $run eval "echo timestamp > $libobj" || exit $? - exit 0 - fi - - if test -n "$pic_flag" || test "$pic_mode" != default; then - # Only do commands if we really have different PIC objects. - reload_objs="$libobjs $reload_conv_objs" - output="$libobj" - eval cmds=\"$reload_cmds\" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - else - # Just create a symlink. - $show $rm $libobj - $run $rm $libobj - xdir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$libobj"; then - xdir="." - else - xdir="$xdir" - fi - baseobj=`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` - oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"` - $show "(cd $xdir && $LN_S $oldobj $baseobj)" - $run eval '(cd $xdir && $LN_S $oldobj $baseobj)' || exit $? - fi - - if test -n "$gentop"; then - $show "${rm}r $gentop" - $run ${rm}r $gentop - fi - - exit 0 - ;; - - prog) - case $host in - *cygwin*) output=`echo $output | sed -e 's,.exe$,,;s,$,.exe,'` ;; - esac - if test -n "$vinfo"; then - $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 - fi - - if test -n "$release"; then - $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 - fi - - if test "$preload" = yes; then - if test "$dlopen_support" = unknown && test "$dlopen_self" = unknown && - test "$dlopen_self_static" = unknown; then - $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." - fi - fi - - case $host in - *-*-rhapsody* | *-*-darwin1.[012]) - # On Rhapsody replace the C library is the System framework - compile_deplibs=`$echo "X $compile_deplibs" | $Xsed -e 's/ -lc / -framework System /'` - finalize_deplibs=`$echo "X $finalize_deplibs" | $Xsed -e 's/ -lc / -framework System /'` - ;; - esac - - compile_command="$compile_command $compile_deplibs" - finalize_command="$finalize_command $finalize_deplibs" - - if test -n "$rpath$xrpath"; then - # If the user specified any rpath flags, then add them. - for libdir in $rpath $xrpath; do - # This is the magic to use -rpath. - case "$finalize_rpath " in - *" $libdir "*) ;; - *) finalize_rpath="$finalize_rpath $libdir" ;; - esac - done - fi - - # Now hardcode the library paths - rpath= - hardcode_libdirs= - for libdir in $compile_rpath $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - rpath="$rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$perm_rpath " in - *" $libdir "*) ;; - *) perm_rpath="$perm_rpath $libdir" ;; - esac - fi - case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2*) - case :$dllsearchpath: in - *":$libdir:"*) ;; - *) dllsearchpath="$dllsearchpath:$libdir";; - esac - ;; - esac - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - compile_rpath="$rpath" - - rpath= - hardcode_libdirs= - for libdir in $finalize_rpath; do - if test -n "$hardcode_libdir_flag_spec"; then - if test -n "$hardcode_libdir_separator"; then - if test -z "$hardcode_libdirs"; then - hardcode_libdirs="$libdir" - else - # Just accumulate the unique libdirs. - case $hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator in - *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) - ;; - *) - hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" - ;; - esac - fi - else - eval flag=\"$hardcode_libdir_flag_spec\" - rpath="$rpath $flag" - fi - elif test -n "$runpath_var"; then - case "$finalize_perm_rpath " in - *" $libdir "*) ;; - *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; - esac - fi - done - # Substitute the hardcoded libdirs into the rpath. - if test -n "$hardcode_libdir_separator" && - test -n "$hardcode_libdirs"; then - libdir="$hardcode_libdirs" - eval rpath=\" $hardcode_libdir_flag_spec\" - fi - finalize_rpath="$rpath" - - if test -n "$libobjs" && test "$build_old_libs" = yes; then - # Transform all the library objects into standard objects. - compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - fi - - dlsyms= - if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then - if test -n "$NM" && test -n "$global_symbol_pipe"; then - dlsyms="${outputname}S.c" - else - $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 - fi - fi - - if test -n "$dlsyms"; then - case $dlsyms in - "") ;; - *.c) - # Discover the nlist of each of the dlfiles. - nlist="$output_objdir/${outputname}.nm" - - $show "$rm $nlist ${nlist}S ${nlist}T" - $run $rm "$nlist" "${nlist}S" "${nlist}T" - - # Parse the name list into a source file. - $show "creating $output_objdir/$dlsyms" - - test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ -/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ -/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ - -#ifdef __cplusplus -extern \"C\" { -#endif - -/* Prevent the only kind of declaration conflicts we can make. */ -#define lt_preloaded_symbols some_other_symbol - -/* External symbol declarations for the compiler. */\ -" - - if test "$dlself" = yes; then - $show "generating symbol list for \`$output'" - - test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" - - # Add our own program objects to the symbol list. - progfiles=`$echo "X$objs$old_deplibs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` - for arg in $progfiles; do - $show "extracting global C symbols from \`$arg'" - $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" - done - - if test -n "$exclude_expsyms"; then - $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' - $run eval '$mv "$nlist"T "$nlist"' - fi - - if test -n "$export_symbols_regex"; then - $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T' - $run eval '$mv "$nlist"T "$nlist"' - fi - - # Prepare the list of exported symbols - if test -z "$export_symbols"; then - export_symbols="$output_objdir/$output.exp" - $run $rm $export_symbols - $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' - else - $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"' - $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T' - $run eval 'mv "$nlist"T "$nlist"' - fi - fi - - for arg in $dlprefiles; do - $show "extracting global C symbols from \`$arg'" - name=`echo "$arg" | sed -e 's%^.*/%%'` - $run eval 'echo ": $name " >> "$nlist"' - $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" - done - - if test -z "$run"; then - # Make sure we have at least an empty file. - test -f "$nlist" || : > "$nlist" - - if test -n "$exclude_expsyms"; then - egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T - $mv "$nlist"T "$nlist" - fi - - # Try sorting and uniquifying the output. - if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then - : - else - grep -v "^: " < "$nlist" > "$nlist"S - fi - - if test -f "$nlist"S; then - eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' - else - echo '/* NONE */' >> "$output_objdir/$dlsyms" - fi - - $echo >> "$output_objdir/$dlsyms" "\ - -#undef lt_preloaded_symbols - -#if defined (__STDC__) && __STDC__ -# define lt_ptr void * -#else -# define lt_ptr char * -# define const -#endif - -/* The mapping between symbol names and symbols. */ -const struct { - const char *name; - lt_ptr address; -} -lt_preloaded_symbols[] = -{\ -" - - eval "$global_symbol_to_c_name_address" < "$nlist" >> "$output_objdir/$dlsyms" - - $echo >> "$output_objdir/$dlsyms" "\ - {0, (lt_ptr) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif\ -" - fi - - pic_flag_for_symtable= - case $host in - # compiling the symbol table file with pic_flag works around - # a FreeBSD bug that causes programs to crash when -lm is - # linked before any other PIC object. But we must not use - # pic_flag when linking with -static. The problem exists in - # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. - *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*) - case "$compile_command " in - *" -static "*) ;; - *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";; - esac;; - *-*-hpux*) - case "$compile_command " in - *" -static "*) ;; - *) pic_flag_for_symtable=" $pic_flag -DPIC";; - esac - esac - - # Now compile the dynamic symbol file. - $show "(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" - $run eval '(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? - - # Clean up the generated files. - $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" - $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" - - # Transform the symbol file into the correct name. - compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` - finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` - ;; - *) - $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 - exit 1 - ;; - esac - else - # We keep going just in case the user didn't refer to - # lt_preloaded_symbols. The linker will fail if global_symbol_pipe - # really was required. - - # Nullify the symbol file. - compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` - finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` - fi - - if test $need_relink = no || test "$build_libtool_libs" != yes; then - # Replace the output file specification. - compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` - link_command="$compile_command$compile_rpath" - - # We have no uninstalled library dependencies, so finalize right now. - $show "$link_command" - $run eval "$link_command" - status=$? - - # Delete the generated files. - if test -n "$dlsyms"; then - $show "$rm $output_objdir/${outputname}S.${objext}" - $run $rm "$output_objdir/${outputname}S.${objext}" - fi - - exit $status - fi - - if test -n "$shlibpath_var"; then - # We should set the shlibpath_var - rpath= - for dir in $temp_rpath; do - case $dir in - [\\/]* | [A-Za-z]:[\\/]*) - # Absolute path. - rpath="$rpath$dir:" - ;; - *) - # Relative path: add a thisdir entry. - rpath="$rpath\$thisdir/$dir:" - ;; - esac - done - temp_rpath="$rpath" - fi - - if test -n "$compile_shlibpath$finalize_shlibpath"; then - compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" - fi - if test -n "$finalize_shlibpath"; then - finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" - fi - - compile_var= - finalize_var= - if test -n "$runpath_var"; then - if test -n "$perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $perm_rpath; do - rpath="$rpath$dir:" - done - compile_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - if test -n "$finalize_perm_rpath"; then - # We should set the runpath_var. - rpath= - for dir in $finalize_perm_rpath; do - rpath="$rpath$dir:" - done - finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " - fi - fi - - if test "$no_install" = yes; then - # We don't need to create a wrapper script. - link_command="$compile_var$compile_command$compile_rpath" - # Replace the output file specification. - link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` - # Delete the old output file. - $run $rm $output - # Link the executable and exit - $show "$link_command" - $run eval "$link_command" || exit $? - exit 0 - fi - - if test "$hardcode_action" = relink; then - # Fast installation is not supported - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - - $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 - $echo "$modename: \`$output' will be relinked during installation" 1>&2 - else - if test "$fast_install" != no; then - link_command="$finalize_var$compile_command$finalize_rpath" - if test "$fast_install" = yes; then - relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` - else - # fast_install is set to needless - relink_command= - fi - else - link_command="$compile_var$compile_command$compile_rpath" - relink_command="$finalize_var$finalize_command$finalize_rpath" - fi - fi - - # Replace the output file specification. - link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` - - # Delete the old output files. - $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname - - $show "$link_command" - $run eval "$link_command" || exit $? - - # Now create the wrapper script. - $show "creating $output" - - # Quote the relink command for shipping. - if test -n "$relink_command"; then - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` - relink_command="$var=\"$var_value\"; export $var; $relink_command" - fi - done - relink_command="cd `pwd`; $relink_command" - relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` - fi - - # Quote $echo for shipping. - if test "X$echo" = "X$SHELL $0 --fallback-echo"; then - case $0 in - [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";; - *) qecho="$SHELL `pwd`/$0 --fallback-echo";; - esac - qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` - else - qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` - fi - - # Only actually do things if our run command is non-null. - if test -z "$run"; then - # win32 will think the script is a binary if it has - # a .exe suffix, so we strip it off here. - case $output in - *.exe) output=`echo $output|sed 's,.exe$,,'` ;; - esac - # test for cygwin because mv fails w/o .exe extensions - case $host in - *cygwin*) exeext=.exe ;; - *) exeext= ;; - esac - $rm $output - trap "$rm $output; exit 1" 1 2 15 - - $echo > $output "\ -#! $SHELL - -# $output - temporary wrapper script for $objdir/$outputname -# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP -# -# The $output program cannot be directly executed until all the libtool -# libraries that it depends on are installed. -# -# This wrapper script should never be moved out of the build directory. -# If it is, it will not operate correctly. - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -Xsed='sed -e 1s/^X//' -sed_quote_subst='$sed_quote_subst' - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi - -relink_command=\"$relink_command\" - -# This environment variable determines our operation mode. -if test \"\$libtool_install_magic\" = \"$magic\"; then - # install mode needs the following variable: - notinst_deplibs='$notinst_deplibs' -else - # When we are sourced in execute mode, \$file and \$echo are already set. - if test \"\$libtool_execute_magic\" != \"$magic\"; then - echo=\"$qecho\" - file=\"\$0\" - # Make sure echo works. - if test \"X\$1\" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift - elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then - # Yippee, \$echo works! - : - else - # Restart under the correct shell, and then maybe \$echo will work. - exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} - fi - fi\ -" - $echo >> $output "\ - - # Find the directory that this script lives in. - thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` - test \"x\$thisdir\" = \"x\$file\" && thisdir=. - - # Follow symbolic links until we get to the real thisdir. - file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\` - while test -n \"\$file\"; do - destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` - - # If there was a directory component, then change thisdir. - if test \"x\$destdir\" != \"x\$file\"; then - case \"\$destdir\" in - [\\\\/]* | [A-Za-z]:[\\\\/]*) thisdir=\"\$destdir\" ;; - *) thisdir=\"\$thisdir/\$destdir\" ;; - esac - fi - - file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` - file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\` - done - - # Try to get the absolute directory name. - absdir=\`cd \"\$thisdir\" && pwd\` - test -n \"\$absdir\" && thisdir=\"\$absdir\" -" - - if test "$fast_install" = yes; then - echo >> $output "\ - program=lt-'$outputname'$exeext - progdir=\"\$thisdir/$objdir\" - - if test ! -f \"\$progdir/\$program\" || \\ - { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\ - test \"X\$file\" != \"X\$progdir/\$program\"; }; then - - file=\"\$\$-\$program\" - - if test ! -d \"\$progdir\"; then - $mkdir \"\$progdir\" - else - $rm \"\$progdir/\$file\" - fi" - - echo >> $output "\ - - # relink executable if necessary - if test -n \"\$relink_command\"; then - if relink_command_output=\`eval \$relink_command 2>&1\`; then : - else - $echo \"\$relink_command_output\" >&2 - $rm \"\$progdir/\$file\" - exit 1 - fi - fi - - $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || - { $rm \"\$progdir/\$program\"; - $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } - $rm \"\$progdir/\$file\" - fi" - else - echo >> $output "\ - program='$outputname' - progdir=\"\$thisdir/$objdir\" -" - fi - - echo >> $output "\ - - if test -f \"\$progdir/\$program\"; then" - - # Export our shlibpath_var if we have one. - if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then - $echo >> $output "\ - # Add our own library path to $shlibpath_var - $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" - - # Some systems cannot cope with colon-terminated $shlibpath_var - # The second colon is a workaround for a bug in BeOS R4 sed - $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` - - export $shlibpath_var -" - fi - - # fixup the dll searchpath if we need to. - if test -n "$dllsearchpath"; then - $echo >> $output "\ - # Add the dll search path components to the executable PATH - PATH=$dllsearchpath:\$PATH -" - fi - - $echo >> $output "\ - if test \"\$libtool_execute_magic\" != \"$magic\"; then - # Run the actual program with our arguments. -" - case $host in - # win32 systems need to use the prog path for dll - # lookup to work - *-*-cygwin* | *-*-pw32*) - $echo >> $output "\ - exec \$progdir/\$program \${1+\"\$@\"} -" - ;; - - # Backslashes separate directories on plain windows - *-*-mingw | *-*-os2*) - $echo >> $output "\ - exec \$progdir\\\\\$program \${1+\"\$@\"} -" - ;; - - *) - $echo >> $output "\ - # Export the path to the program. - PATH=\"\$progdir:\$PATH\" - export PATH - - exec \$program \${1+\"\$@\"} -" - ;; - esac - $echo >> $output "\ - \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" - exit 1 - fi - else - # The program doesn't exist. - \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 - \$echo \"This script is just a wrapper for \$program.\" 1>&2 - echo \"See the $PACKAGE documentation for more information.\" 1>&2 - exit 1 - fi -fi\ -" - chmod +x $output - fi - exit 0 - ;; - esac - - # See if we need to build an old-fashioned archive. - for oldlib in $oldlibs; do - - if test "$build_libtool_libs" = convenience; then - oldobjs="$libobjs_save" - addlibs="$convenience" - build_libtool_libs=no - else - if test "$build_libtool_libs" = module; then - oldobjs="$libobjs_save" - build_libtool_libs=no - else - oldobjs="$objs$old_deplibs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP` - fi - addlibs="$old_convenience" - fi - - if test -n "$addlibs"; then - gentop="$output_objdir/${outputname}x" - $show "${rm}r $gentop" - $run ${rm}r "$gentop" - $show "mkdir $gentop" - $run mkdir "$gentop" - status=$? - if test $status -ne 0 && test ! -d "$gentop"; then - exit $status - fi - generated="$generated $gentop" - - # Add in members from convenience archives. - for xlib in $addlibs; do - # Extract the objects. - case $xlib in - [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; - *) xabs=`pwd`"/$xlib" ;; - esac - xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` - xdir="$gentop/$xlib" - - $show "${rm}r $xdir" - $run ${rm}r "$xdir" - $show "mkdir $xdir" - $run mkdir "$xdir" - status=$? - if test $status -ne 0 && test ! -d "$xdir"; then - exit $status - fi - $show "(cd $xdir && $AR x $xabs)" - $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? - - oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP` - done - fi - - # Do each command in the archive commands. - if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then - eval cmds=\"$old_archive_from_new_cmds\" - else - # Ensure that we have .o objects in place in case we decided - # not to build a shared library, and have fallen back to building - # static libs even though --disable-static was passed! - for oldobj in $oldobjs; do - if test ! -f $oldobj; then - xdir=`$echo "X$oldobj" | $Xsed -e 's%/[^/]*$%%'` - if test "X$xdir" = "X$oldobj"; then - xdir="." - else - xdir="$xdir" - fi - baseobj=`$echo "X$oldobj" | $Xsed -e 's%^.*/%%'` - obj=`$echo "X$baseobj" | $Xsed -e "$o2lo"` - $show "(cd $xdir && ${LN_S} $obj $baseobj)" - $run eval '(cd $xdir && ${LN_S} $obj $baseobj)' || exit $? - fi - done - - eval cmds=\"$old_archive_cmds\" - fi - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - done - - if test -n "$generated"; then - $show "${rm}r$generated" - $run ${rm}r$generated - fi - - # Now create the libtool archive. - case $output in - *.la) - old_library= - test "$build_old_libs" = yes && old_library="$libname.$libext" - $show "creating $output" - - # Preserve any variables that may affect compiler behavior - for var in $variables_saved_for_relink; do - if eval test -z \"\${$var+set}\"; then - relink_command="{ test -z \"\${$var+set}\" || unset $var || { $var=; export $var; }; }; $relink_command" - elif eval var_value=\$$var; test -z "$var_value"; then - relink_command="$var=; export $var; $relink_command" - else - var_value=`$echo "X$var_value" | $Xsed -e "$sed_quote_subst"` - relink_command="$var=\"$var_value\"; export $var; $relink_command" - fi - done - # Quote the link command for shipping. - relink_command="cd `pwd`; $SHELL $0 --mode=relink $libtool_args" - relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` - - # Only create the output if not a dry run. - if test -z "$run"; then - for installed in no yes; do - if test "$installed" = yes; then - if test -z "$install_libdir"; then - break - fi - output="$output_objdir/$outputname"i - # Replace all uninstalled libtool libraries with the installed ones - newdependency_libs= - for deplib in $dependency_libs; do - case $deplib in - *.la) - name=`$echo "X$deplib" | $Xsed -e 's%^.*/%%'` - eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $deplib` - if test -z "$libdir"; then - $echo "$modename: \`$deplib' is not a valid libtool archive" 1>&2 - exit 1 - fi - newdependency_libs="$newdependency_libs $libdir/$name" - ;; - *) newdependency_libs="$newdependency_libs $deplib" ;; - esac - done - dependency_libs="$newdependency_libs" - newdlfiles= - for lib in $dlfiles; do - name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - if test -z "$libdir"; then - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit 1 - fi - newdlfiles="$newdlfiles $libdir/$name" - done - dlfiles="$newdlfiles" - newdlprefiles= - for lib in $dlprefiles; do - name=`$echo "X$lib" | $Xsed -e 's%^.*/%%'` - eval libdir=`sed -n -e 's/^libdir=\(.*\)$/\1/p' $lib` - if test -z "$libdir"; then - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - exit 1 - fi - newdlprefiles="$newdlprefiles $libdir/$name" - done - dlprefiles="$newdlprefiles" - fi - $rm $output - # place dlname in correct position for cygwin - tdlname=$dlname - case $host,$output,$installed,$module,$dlname in - *cygwin*,*lai,yes,no,*.dll) tdlname=../bin/$dlname ;; - esac - $echo > $output "\ -# $outputname - a libtool library file -# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP -# -# Please DO NOT delete this file! -# It is necessary for linking the library. - -# The name that we can dlopen(3). -dlname='$tdlname' - -# Names of this library. -library_names='$library_names' - -# The name of the static archive. -old_library='$old_library' - -# Libraries that this one depends upon. -dependency_libs='$dependency_libs' - -# Version information for $libname. -current=$current -age=$age -revision=$revision - -# Is this an already installed library? -installed=$installed - -# Files to dlopen/dlpreopen -dlopen='$dlfiles' -dlpreopen='$dlprefiles' - -# Directory that this library needs to be installed in: -libdir='$install_libdir'" - if test "$installed" = no && test $need_relink = yes; then - $echo >> $output "\ -relink_command=\"$relink_command\"" - fi - done - fi - - # Do a symbolic link so that the libtool archive can be found in - # LD_LIBRARY_PATH before the program is installed. - $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" - $run eval '(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)' || exit $? - ;; - esac - exit 0 - ;; - - # libtool install mode - install) - modename="$modename: install" - - # There may be an optional sh(1) argument at the beginning of - # install_prog (especially on Windows NT). - if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh || - # Allow the use of GNU shtool's install command. - $echo "X$nonopt" | $Xsed | grep shtool > /dev/null; then - # Aesthetically quote it. - arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) - arg="\"$arg\"" - ;; - esac - install_prog="$arg " - arg="$1" - shift - else - install_prog= - arg="$nonopt" - fi - - # The real first argument should be the name of the installation program. - # Aesthetically quote it. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) - arg="\"$arg\"" - ;; - esac - install_prog="$install_prog$arg" - - # We need to accept at least all the BSD install flags. - dest= - files= - opts= - prev= - install_type= - isdir=no - stripme= - for arg - do - if test -n "$dest"; then - files="$files $dest" - dest="$arg" - continue - fi - - case $arg in - -d) isdir=yes ;; - -f) prev="-f" ;; - -g) prev="-g" ;; - -m) prev="-m" ;; - -o) prev="-o" ;; - -s) - stripme=" -s" - continue - ;; - -*) ;; - - *) - # If the previous option needed an argument, then skip it. - if test -n "$prev"; then - prev= - else - dest="$arg" - continue - fi - ;; - esac - - # Aesthetically quote the argument. - arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` - case $arg in - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) - arg="\"$arg\"" - ;; - esac - install_prog="$install_prog $arg" - done - - if test -z "$install_prog"; then - $echo "$modename: you must specify an install program" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - if test -n "$prev"; then - $echo "$modename: the \`$prev' option requires an argument" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - if test -z "$files"; then - if test -z "$dest"; then - $echo "$modename: no file or destination specified" 1>&2 - else - $echo "$modename: you must specify a destination" 1>&2 - fi - $echo "$help" 1>&2 - exit 1 - fi - - # Strip any trailing slash from the destination. - dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` - - # Check to see that the destination is a directory. - test -d "$dest" && isdir=yes - if test "$isdir" = yes; then - destdir="$dest" - destname= - else - destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` - test "X$destdir" = "X$dest" && destdir=. - destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` - - # Not a directory, so check to see that there is only one file specified. - set dummy $files - if test $# -gt 2; then - $echo "$modename: \`$dest' is not a directory" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - fi - case $destdir in - [\\/]* | [A-Za-z]:[\\/]*) ;; - *) - for file in $files; do - case $file in - *.lo) ;; - *) - $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 - $echo "$help" 1>&2 - exit 1 - ;; - esac - done - ;; - esac - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - staticlibs= - future_libdirs= - current_libdirs= - for file in $files; do - - # Do each installation. - case $file in - *.$libext) - # Do the static libraries later. - staticlibs="$staticlibs $file" - ;; - - *.la) - # Check to see that this really is a libtool archive. - if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - library_names= - old_library= - relink_command= - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Add the libdir to current_libdirs if it is the destination. - if test "X$destdir" = "X$libdir"; then - case "$current_libdirs " in - *" $libdir "*) ;; - *) current_libdirs="$current_libdirs $libdir" ;; - esac - else - # Note the libdir as a future libdir. - case "$future_libdirs " in - *" $libdir "*) ;; - *) future_libdirs="$future_libdirs $libdir" ;; - esac - fi - - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/ - test "X$dir" = "X$file/" && dir= - dir="$dir$objdir" - - if test -n "$relink_command"; then - $echo "$modename: warning: relinking \`$file'" 1>&2 - $show "$relink_command" - if $run eval "$relink_command"; then : - else - $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 - continue - fi - fi - - # See the names of the shared library. - set dummy $library_names - if test -n "$2"; then - realname="$2" - shift - shift - - srcname="$realname" - test -n "$relink_command" && srcname="$realname"T - - # Install the shared library and build the symlinks. - $show "$install_prog $dir/$srcname $destdir/$realname" - $run eval "$install_prog $dir/$srcname $destdir/$realname" || exit $? - if test -n "$stripme" && test -n "$striplib"; then - $show "$striplib $destdir/$realname" - $run eval "$striplib $destdir/$realname" || exit $? - fi - - if test $# -gt 0; then - # Delete the old symlinks, and create new ones. - for linkname - do - if test "$linkname" != "$realname"; then - $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" - $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" - fi - done - fi - - # Do each command in the postinstall commands. - lib="$destdir/$realname" - eval cmds=\"$postinstall_cmds\" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - fi - - # Install the pseudo-library for information purposes. - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - instname="$dir/$name"i - $show "$install_prog $instname $destdir/$name" - $run eval "$install_prog $instname $destdir/$name" || exit $? - - # Maybe install the static library, too. - test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" - ;; - - *.lo) - # Install (i.e. copy) a libtool object. - - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - destfile="$destdir/$destfile" - fi - - # Deduce the name of the destination old-style object file. - case $destfile in - *.lo) - staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` - ;; - *.$objext) - staticdest="$destfile" - destfile= - ;; - *) - $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 - $echo "$help" 1>&2 - exit 1 - ;; - esac - - # Install the libtool object if requested. - if test -n "$destfile"; then - $show "$install_prog $file $destfile" - $run eval "$install_prog $file $destfile" || exit $? - fi - - # Install the old object if enabled. - if test "$build_old_libs" = yes; then - # Deduce the name of the old-style object file. - staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` - - $show "$install_prog $staticobj $staticdest" - $run eval "$install_prog \$staticobj \$staticdest" || exit $? - fi - exit 0 - ;; - - *) - # Figure out destination file name, if it wasn't already specified. - if test -n "$destname"; then - destfile="$destdir/$destname" - else - destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - destfile="$destdir/$destfile" - fi - - # Do a test to see if this is really a libtool program. - if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - notinst_deplibs= - relink_command= - - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Check the variables that should have been set. - if test -z "$notinst_deplibs"; then - $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2 - exit 1 - fi - - finalize=yes - for lib in $notinst_deplibs; do - # Check to see that each library is installed. - libdir= - if test -f "$lib"; then - # If there is no directory component, then add one. - case $lib in - */* | *\\*) . $lib ;; - *) . ./$lib ;; - esac - fi - libfile="$libdir/"`$echo "X$lib" | $Xsed -e 's%^.*/%%g'` ### testsuite: skip nested quoting test - if test -n "$libdir" && test ! -f "$libfile"; then - $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 - finalize=no - fi - done - - relink_command= - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - outputname= - if test "$fast_install" = no && test -n "$relink_command"; then - if test "$finalize" = yes && test -z "$run"; then - tmpdir="/tmp" - test -n "$TMPDIR" && tmpdir="$TMPDIR" - tmpdir="$tmpdir/libtool-$$" - if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then : - else - $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 - continue - fi - file=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - outputname="$tmpdir/$file" - # Replace the output file specification. - relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` - - $show "$relink_command" - if $run eval "$relink_command"; then : - else - $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 - ${rm}r "$tmpdir" - continue - fi - file="$outputname" - else - $echo "$modename: warning: cannot relink \`$file'" 1>&2 - fi - else - # Install the binary that we compiled earlier. - file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` - fi - fi - - # remove .exe since cygwin /usr/bin/install will append another - # one anyways - case $install_prog,$host in - /usr/bin/install*,*cygwin*) - case $file:$destfile in - *.exe:*.exe) - # this is ok - ;; - *.exe:*) - destfile=$destfile.exe - ;; - *:*.exe) - destfile=`echo $destfile | sed -e 's,.exe$,,'` - ;; - esac - ;; - esac - $show "$install_prog$stripme $file $destfile" - $run eval "$install_prog\$stripme \$file \$destfile" || exit $? - test -n "$outputname" && ${rm}r "$tmpdir" - ;; - esac - done - - for file in $staticlibs; do - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - - # Set up the ranlib parameters. - oldlib="$destdir/$name" - - $show "$install_prog $file $oldlib" - $run eval "$install_prog \$file \$oldlib" || exit $? - - if test -n "$stripme" && test -n "$striplib"; then - $show "$old_striplib $oldlib" - $run eval "$old_striplib $oldlib" || exit $? - fi - - # Do each command in the postinstall commands. - eval cmds=\"$old_postinstall_cmds\" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || exit $? - done - IFS="$save_ifs" - done - - if test -n "$future_libdirs"; then - $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 - fi - - if test -n "$current_libdirs"; then - # Maybe just do a dry run. - test -n "$run" && current_libdirs=" -n$current_libdirs" - exec_cmd='$SHELL $0 --finish$current_libdirs' - else - exit 0 - fi - ;; - - # libtool finish mode - finish) - modename="$modename: finish" - libdirs="$nonopt" - admincmds= - - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then - for dir - do - libdirs="$libdirs $dir" - done - - for libdir in $libdirs; do - if test -n "$finish_cmds"; then - # Do each command in the finish commands. - eval cmds=\"$finish_cmds\" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" || admincmds="$admincmds - $cmd" - done - IFS="$save_ifs" - fi - if test -n "$finish_eval"; then - # Do the single finish_eval. - eval cmds=\"$finish_eval\" - $run eval "$cmds" || admincmds="$admincmds - $cmds" - fi - done - fi - - # Exit here if they wanted silent mode. - test "$show" = ":" && exit 0 - - echo "----------------------------------------------------------------------" - echo "Libraries have been installed in:" - for libdir in $libdirs; do - echo " $libdir" - done - echo - echo "If you ever happen to want to link against installed libraries" - echo "in a given directory, LIBDIR, you must either use libtool, and" - echo "specify the full pathname of the library, or use the \`-LLIBDIR'" - echo "flag during linking and do at least one of the following:" - if test -n "$shlibpath_var"; then - echo " - add LIBDIR to the \`$shlibpath_var' environment variable" - echo " during execution" - fi - if test -n "$runpath_var"; then - echo " - add LIBDIR to the \`$runpath_var' environment variable" - echo " during linking" - fi - if test -n "$hardcode_libdir_flag_spec"; then - libdir=LIBDIR - eval flag=\"$hardcode_libdir_flag_spec\" - - echo " - use the \`$flag' linker flag" - fi - if test -n "$admincmds"; then - echo " - have your system administrator run these commands:$admincmds" - fi - if test -f /etc/ld.so.conf; then - echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" - fi - echo - echo "See any operating system documentation about shared libraries for" - echo "more information, such as the ld(1) and ld.so(8) manual pages." - echo "----------------------------------------------------------------------" - exit 0 - ;; - - # libtool execute mode - execute) - modename="$modename: execute" - - # The first argument is the command name. - cmd="$nonopt" - if test -z "$cmd"; then - $echo "$modename: you must specify a COMMAND" 1>&2 - $echo "$help" - exit 1 - fi - - # Handle -dlopen flags immediately. - for file in $execute_dlfiles; do - if test ! -f "$file"; then - $echo "$modename: \`$file' is not a file" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - dir= - case $file in - *.la) - # Check to see that this really is a libtool archive. - if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : - else - $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - # Read the libtool library. - dlname= - library_names= - - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Skip this library if it cannot be dlopened. - if test -z "$dlname"; then - # Warn if it was a shared library. - test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" - continue - fi - - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$file" && dir=. - - if test -f "$dir/$objdir/$dlname"; then - dir="$dir/$objdir" - else - $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 - exit 1 - fi - ;; - - *.lo) - # Just add the directory containing the .lo file. - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - test "X$dir" = "X$file" && dir=. - ;; - - *) - $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 - continue - ;; - esac - - # Get the absolute pathname. - absdir=`cd "$dir" && pwd` - test -n "$absdir" && dir="$absdir" - - # Now add the directory to shlibpath_var. - if eval "test -z \"\$$shlibpath_var\""; then - eval "$shlibpath_var=\"\$dir\"" - else - eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" - fi - done - - # This variable tells wrapper scripts just to set shlibpath_var - # rather than running their programs. - libtool_execute_magic="$magic" - - # Check if any of the arguments is a wrapper script. - args= - for file - do - case $file in - -*) ;; - *) - # Do a test to see if this is really a libtool program. - if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - # If there is no directory component, then add one. - case $file in - */* | *\\*) . $file ;; - *) . ./$file ;; - esac - - # Transform arg to wrapped name. - file="$progdir/$program" - fi - ;; - esac - # Quote arguments (to preserve shell metacharacters). - file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` - args="$args \"$file\"" - done - - if test -z "$run"; then - if test -n "$shlibpath_var"; then - # Export the shlibpath_var. - eval "export $shlibpath_var" - fi - - # Restore saved enviroment variables - if test "${save_LC_ALL+set}" = set; then - LC_ALL="$save_LC_ALL"; export LC_ALL - fi - if test "${save_LANG+set}" = set; then - LANG="$save_LANG"; export LANG - fi - - # Now prepare to actually exec the command. - exec_cmd='"$cmd"$args' - else - # Display what would be done. - if test -n "$shlibpath_var"; then - eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" - $echo "export $shlibpath_var" - fi - $echo "$cmd$args" - exit 0 - fi - ;; - - # libtool clean and uninstall mode - clean | uninstall) - modename="$modename: $mode" - rm="$nonopt" - files= - rmforce= - exit_status=0 - - # This variable tells wrapper scripts just to set variables rather - # than running their programs. - libtool_install_magic="$magic" - - for arg - do - case $arg in - -f) rm="$rm $arg"; rmforce=yes ;; - -*) rm="$rm $arg" ;; - *) files="$files $arg" ;; - esac - done - - if test -z "$rm"; then - $echo "$modename: you must specify an RM program" 1>&2 - $echo "$help" 1>&2 - exit 1 - fi - - rmdirs= - - for file in $files; do - dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` - if test "X$dir" = "X$file"; then - dir=. - objdir="$objdir" - else - objdir="$dir/$objdir" - fi - name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` - test $mode = uninstall && objdir="$dir" - - # Remember objdir for removal later, being careful to avoid duplicates - if test $mode = clean; then - case " $rmdirs " in - *" $objdir "*) ;; - *) rmdirs="$rmdirs $objdir" ;; - esac - fi - - # Don't error if the file doesn't exist and rm -f was used. - if (test -L "$file") >/dev/null 2>&1 \ - || (test -h "$file") >/dev/null 2>&1 \ - || test -f "$file"; then - : - elif test -d "$file"; then - exit_status=1 - continue - elif test "$rmforce" = yes; then - continue - fi - - rmfiles="$file" - - case $name in - *.la) - # Possibly a libtool archive, so verify it. - if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - . $dir/$name - - # Delete the libtool libraries and symlinks. - for n in $library_names; do - rmfiles="$rmfiles $objdir/$n" - done - test -n "$old_library" && rmfiles="$rmfiles $objdir/$old_library" - test $mode = clean && rmfiles="$rmfiles $objdir/$name $objdir/${name}i" - - if test $mode = uninstall; then - if test -n "$library_names"; then - # Do each command in the postuninstall commands. - eval cmds=\"$postuninstall_cmds\" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" - if test $? != 0 && test "$rmforce" != yes; then - exit_status=1 - fi - done - IFS="$save_ifs" - fi - - if test -n "$old_library"; then - # Do each command in the old_postuninstall commands. - eval cmds=\"$old_postuninstall_cmds\" - IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' - for cmd in $cmds; do - IFS="$save_ifs" - $show "$cmd" - $run eval "$cmd" - if test $? != 0 && test "$rmforce" != yes; then - exit_status=1 - fi - done - IFS="$save_ifs" - fi - # FIXME: should reinstall the best remaining shared library. - fi - fi - ;; - - *.lo) - if test "$build_old_libs" = yes; then - oldobj=`$echo "X$name" | $Xsed -e "$lo2o"` - rmfiles="$rmfiles $dir/$oldobj" - fi - ;; - - *) - # Do a test to see if this is a libtool program. - if test $mode = clean && - (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then - relink_command= - . $dir/$file - - rmfiles="$rmfiles $objdir/$name $objdir/${name}S.${objext}" - if test "$fast_install" = yes && test -n "$relink_command"; then - rmfiles="$rmfiles $objdir/lt-$name" - fi - fi - ;; - esac - $show "$rm $rmfiles" - $run $rm $rmfiles || exit_status=1 - done - - # Try to remove the ${objdir}s in the directories where we deleted files - for dir in $rmdirs; do - if test -d "$dir"; then - $show "rmdir $dir" - $run rmdir $dir >/dev/null 2>&1 - fi - done - - exit $exit_status - ;; - - "") - $echo "$modename: you must specify a MODE" 1>&2 - $echo "$generic_help" 1>&2 - exit 1 - ;; - esac - - if test -z "$exec_cmd"; then - $echo "$modename: invalid operation mode \`$mode'" 1>&2 - $echo "$generic_help" 1>&2 - exit 1 - fi -fi # test -z "$show_help" - -if test -n "$exec_cmd"; then - eval exec $exec_cmd - exit 1 -fi - -# We need to display help for each of the modes. -case $mode in -"") $echo \ -"Usage: $modename [OPTION]... [MODE-ARG]... - -Provide generalized library-building support services. - - --config show all configuration variables - --debug enable verbose shell tracing --n, --dry-run display commands without modifying any files - --features display basic configuration information and exit - --finish same as \`--mode=finish' - --help display this help message and exit - --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] - --quiet same as \`--silent' - --silent don't print informational messages - --version print version information - -MODE must be one of the following: - - clean remove files from the build directory - compile compile a source file into a libtool object - execute automatically set library path, then run a program - finish complete the installation of libtool libraries - install install libraries or executables - link create a library or an executable - uninstall remove libraries from an installed directory - -MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for -a more detailed description of MODE." - exit 0 - ;; - -clean) - $echo \ -"Usage: $modename [OPTION]... --mode=clean RM [RM-OPTION]... FILE... - -Remove files from the build directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, object or program, all the files associated -with it are deleted. Otherwise, only FILE itself is deleted using RM." - ;; - -compile) - $echo \ -"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE - -Compile a source file into a libtool library object. - -This mode accepts the following additional options: - - -o OUTPUT-FILE set the output file name to OUTPUT-FILE - -prefer-pic try to building PIC objects only - -prefer-non-pic try to building non-PIC objects only - -static always build a \`.o' file suitable for static linking - -COMPILE-COMMAND is a command to be used in creating a \`standard' object file -from the given SOURCEFILE. - -The output file name is determined by removing the directory component from -SOURCEFILE, then substituting the C source code suffix \`.c' with the -library object suffix, \`.lo'." - ;; - -execute) - $echo \ -"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... - -Automatically set library path, then run a program. - -This mode accepts the following additional options: - - -dlopen FILE add the directory containing FILE to the library path - -This mode sets the library path environment variable according to \`-dlopen' -flags. - -If any of the ARGS are libtool executable wrappers, then they are translated -into their corresponding uninstalled binary, and any of their required library -directories are added to the library path. - -Then, COMMAND is executed, with ARGS as arguments." - ;; - -finish) - $echo \ -"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... - -Complete the installation of libtool libraries. - -Each LIBDIR is a directory that contains libtool libraries. - -The commands that this mode executes may require superuser privileges. Use -the \`--dry-run' option if you just want to see what would be executed." - ;; - -install) - $echo \ -"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... - -Install executables or libraries. - -INSTALL-COMMAND is the installation command. The first component should be -either the \`install' or \`cp' program. - -The rest of the components are interpreted as arguments to that command (only -BSD-compatible install options are recognized)." - ;; - -link) - $echo \ -"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... - -Link object files or libraries together to form another library, or to -create an executable program. - -LINK-COMMAND is a command using the C compiler that you would use to create -a program from several object files. - -The following components of LINK-COMMAND are treated specially: - - -all-static do not do any dynamic linking at all - -avoid-version do not add a version suffix if possible - -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime - -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols - -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) - -export-symbols SYMFILE - try to export only the symbols listed in SYMFILE - -export-symbols-regex REGEX - try to export only the symbols matching REGEX - -LLIBDIR search LIBDIR for required installed libraries - -lNAME OUTPUT-FILE requires the installed library libNAME - -module build a library that can dlopened - -no-fast-install disable the fast-install mode - -no-install link a not-installable executable - -no-undefined declare that a library does not refer to external symbols - -o OUTPUT-FILE create OUTPUT-FILE from the specified objects - -release RELEASE specify package release information - -rpath LIBDIR the created library will eventually be installed in LIBDIR - -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries - -static do not do any dynamic linking of libtool libraries - -version-info CURRENT[:REVISION[:AGE]] - specify library version info [each variable defaults to 0] - -All other options (arguments beginning with \`-') are ignored. - -Every other argument is treated as a filename. Files ending in \`.la' are -treated as uninstalled libtool libraries, other files are standard or library -object files. - -If the OUTPUT-FILE ends in \`.la', then a libtool library is created, -only library objects (\`.lo' files) may be specified, and \`-rpath' is -required, except when creating a convenience library. - -If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created -using \`ar' and \`ranlib', or on Windows using \`lib'. - -If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file -is created, otherwise an executable program is created." - ;; - -uninstall) - $echo \ -"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... - -Remove libraries from an installation directory. - -RM is the name of the program to use to delete files associated with each FILE -(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed -to RM. - -If FILE is a libtool library, all the files associated with it are deleted. -Otherwise, only FILE itself is deleted using RM." - ;; - -*) - $echo "$modename: invalid operation mode \`$mode'" 1>&2 - $echo "$help" 1>&2 - exit 1 - ;; -esac - -echo -$echo "Try \`$modename --help' for more information about other modes." - -exit 0 - -# Local Variables: -# mode:shell-script -# sh-indentation:2 -# End: diff --git a/src/.cvsignore b/src/.cvsignore index 32cb9b9f0..8357ffed2 100644 --- a/src/.cvsignore +++ b/src/.cvsignore @@ -4,4 +4,4 @@ Makefile Makefile.in supertux *.exe - +.sconsign diff --git a/src/Makefile.am b/src/Makefile.am index 7108c23f8..96d4ff34d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -2,12 +2,11 @@ localedir = $(datadir)/locale bin_PROGRAMS = supertux supertux_CXXFLAGS = -DLOCALEDIR=\"$(localedir)\" -#supertux_LDADD = $(top_builddir)/lib/.libs/libsupertux @LIBINTL@ supertux_LDADD = $(top_builddir)/lib/libsupertux.la @LIBINTL@ supertux_SOURCES = badguy.cpp badguy.h bitmask.cpp bitmask.h camera.cpp \ - camera.h collision.cpp collision.h door.cpp door.h intro.cpp intro.h \ + camera.h collision.cpp collision.h intro.cpp intro.h \ gameloop.cpp gameloop.h high_scores.cpp high_scores.h interactive_object.cpp \ interactive_object.h level.cpp level.h level_subset.cpp level_subset.h leveleditor.cpp \ leveleditor.h particlesystem.cpp particlesystem.h player.cpp player.h scene.cpp \ @@ -15,7 +14,14 @@ supertux_SOURCES = badguy.cpp badguy.h bitmask.cpp bitmask.h camera.cpp \ worldmap.h tile.h tile.cpp tile_manager.h tile_manager.cpp resources.h \ resources.cpp gameobjs.h gameobjs.cpp background.h background.cpp tilemap.h \ tilemap.cpp serializable.h sector.cpp sector.h misc.h misc.cpp defines.h \ - statistics.cpp badguy_specs.cpp + statistics.cpp badguy_specs.cpp \ + timer.cpp timer.h \ + object/coin.h object/coin.cpp \ + object/block.h object/block.cpp \ + object/platform.h object/platform.cpp \ + object/door.h object/door.cpp \ + object/fireworks.h object/fireworks.cpp \ + object/bullet.h object/bullet.cpp # EOF # INCLUDES = -I$(top_srcdir)/lib diff --git a/src/SConscript b/src/SConscript index d8f978216..60c3684ed 100644 --- a/src/SConscript +++ b/src/SConscript @@ -1,7 +1,7 @@ Import('*') supertux_src = Glob( - dirs=[".", "object", "badguy"], + dirs=[".", "object", "badguy", "trigger"], pattern="*.cpp" ) app = env.Program( diff --git a/src/background.cpp b/src/background.cpp index b8d0ecc94..87ce973ad 100644 --- a/src/background.cpp +++ b/src/background.cpp @@ -17,6 +17,8 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include + #include "background.h" #include "app/globals.h" #include "camera.h" @@ -116,10 +118,11 @@ Background::draw(DrawingContext& context) context.pop_transform(); } } else if(type == IMAGE) { - int sx = int(-context.get_translation().x * speed) - % image->w - image->w; - int sy = int(-context.get_translation().y * speed) - % image->h - image->h; + if(!image) + return; + + int sx = int(-context.get_translation().x * speed) % image->w - image->w; + int sy = int(-context.get_translation().y * speed) % image->h - image->h; context.push_transform(); context.set_translation(Vector(0, 0)); for(int x = sx; x < screen->w; x += image->w) diff --git a/src/badguy.cpp b/src/badguy.cpp index 5e496ec4a..1fe2e2372 100644 --- a/src/badguy.cpp +++ b/src/badguy.cpp @@ -20,6 +20,8 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. +#include + #include #include @@ -126,8 +128,9 @@ std::string badguykind_to_string(BadGuyKind kind) } } +#if 0 BadGuy::BadGuy(BadGuyKind kind_, LispReader& lispreader) - : removable(false), squishcount(0) + : squishcount(0) { lispreader.read_float("x", start_position.x); lispreader.read_float("y", start_position.y); @@ -141,7 +144,7 @@ BadGuy::BadGuy(BadGuyKind kind_, LispReader& lispreader) } BadGuy::BadGuy(BadGuyKind kind_, float x, float y) - : removable(false), squishcount(0) + : squishcount(0) { start_position.x = x; start_position.y = y; @@ -159,12 +162,10 @@ BadGuy::~BadGuy() void BadGuy::init() { - base.x = start_position.x; - base.y = start_position.y; - base.width = 32; - base.height = 32; + bbox.set_pos(start_position); + bbox.set_size(32, 32); - mode = NORMAL; + state = NORMAL; old_base = base; dir = LEFT; seen = false; @@ -175,17 +176,6 @@ BadGuy::init() timer.init(true); specs = badguyspecs_manager->load(badguykind_to_string(kind)); - - // if we're in a solid tile at start correct that now - if(Sector::current()) { - if(kind != BAD_FLAME && kind != BAD_FISH && kind != BAD_FLAMEFISH && collision_object_map(base)) - { - std::cout << "Warning: badguy started in wall: kind: " << badguykind_to_string(kind) - << " pos: (" << base.x << ", " << base.y << ")" << std::endl; - while(collision_object_map(base)) - --base.y; - } - } } void @@ -203,12 +193,12 @@ BadGuy::write(LispWriter& writer) void BadGuy::activate(Direction activation_dir) { - mode = NORMAL; + state = NORMAL; animation_offset = 0; target.x = target.y = -1; physic.reset(); - frozen_timer.init(true); - timer.init(true); + frozen_timer.start(0); + timer.start(0); dying = DYING_NOT; seen = true; @@ -225,7 +215,7 @@ BadGuy::activate(Direction activation_dir) set_action("left-up", "right-up"); } else if(kind == BAD_BOMB) { set_action("ticking-left", "ticking-right"); - // hack so that the bomb doesn't hurt until it expldes... + // hack so that the bomb doesn't hurt until it explodes... dying = DYING_SQUISHED; } else if(kind == BAD_FLAME) { angle = 0; @@ -255,51 +245,51 @@ BadGuy::activate(Direction activation_dir) } else if (kind == BAD_WALKINGTREE) { // TODO: why isn't the height/width being set properly in set_action? physic.set_velocity(dirsign * BADGUY_WALK_SPEED, 0); - mode = BGM_BIG; + state = BGM_BIG; set_action("left", "left"); - base.width = 66; - base.height = 66; + bbox.set_size(66, 66); } } Surface* BadGuy::get_image() { -// Set action as the "default" one. -specs->sprite->set_action("left"); -if(BAD_JUMPY) - specs->sprite->set_action("left-up"); -else if(kind == BAD_BOMB) - specs->sprite->set_action("ticking-left"); -else if(kind == BAD_FLAME) - specs->sprite->set_action("normal"); -else if(kind == BAD_STALACTITE) - specs->sprite->set_action("normal"); -else if(kind == BAD_FISH) - specs->sprite->set_action("normal"); -else if(kind == BAD_FLAMEFISH) - specs->sprite->set_action("normal"); - -return specs->sprite->get_frame(0); + // Set action as the "default" one. + specs->sprite->set_action("left"); + if(BAD_JUMPY) + specs->sprite->set_action("left-up"); + else if(kind == BAD_BOMB) + specs->sprite->set_action("ticking-left"); + else if(kind == BAD_FLAME) + specs->sprite->set_action("normal"); + else if(kind == BAD_STALACTITE) + specs->sprite->set_action("normal"); + else if(kind == BAD_FISH) + specs->sprite->set_action("normal"); + else if(kind == BAD_FLAMEFISH) + specs->sprite->set_action("normal"); + + return specs->sprite->get_frame(0); } +#if 0 void BadGuy::action_mriceblock(double elapsed_time) { Player& tux = *Sector::current()->player; - if(mode != HELD) + if(state != HELD) fall(); /* Move left/right: */ - if (mode != HELD) + if (state != HELD) { // move physic.apply(elapsed_time, base.x, base.y, Sector::current()->gravity); if (dying != DYING_FALLING) collision_swept_object_map(&old_base,&base); } - else if (mode == HELD) + else if (state == HELD) { /* FIXME: The pbad object shouldn't know about pplayer objects. */ /* If we're holding the iceblock */ dir = tux.dir; @@ -334,7 +324,7 @@ BadGuy::action_mriceblock(double elapsed_time) base.x = tux.base.x + tux.base.width; old_base = base; - mode=KICK; + state=KICK; tux.kick_timer.start(KICKING_TIME); set_action("flat-left", "flat-right"); physic.set_velocity_x((dir == LEFT) ? -3.5 : 3.5); @@ -346,18 +336,18 @@ BadGuy::action_mriceblock(double elapsed_time) { int changed = dir; check_horizontal_bump(); - if(mode == KICK && changed != dir) + if(state == KICK && changed != dir) { SoundManager::get()->play_sound(IDToSound(SND_RICOCHET), get_pos(), Sector::current()->player->get_pos()); } } - /* Handle mode timer: */ - if (mode == FLAT) + /* Handle state timer: */ + if (state == FLAT) { if(!timer.check()) { - mode = NORMAL; + state = NORMAL; set_action("left", "right"); physic.set_velocity( (dir == LEFT) ? -.8 : .8, 0); } @@ -370,7 +360,7 @@ BadGuy::check_horizontal_bump(bool checkcliff) float halfheight = base.height / 2; if (dir == LEFT && issolid( base.x, base.y + halfheight)) { - if (kind == BAD_MRICEBLOCK && mode == KICK) + if (kind == BAD_MRICEBLOCK && state == KICK) { Sector::current()->trybreakbrick(Vector(base.x, base.y + halfheight), false); Sector::current()->tryemptybox(Vector(base.x, base.y + halfheight), dir); @@ -382,7 +372,7 @@ BadGuy::check_horizontal_bump(bool checkcliff) } if (dir == RIGHT && issolid( base.x + base.width, base.y + halfheight)) { - if (kind == BAD_MRICEBLOCK && mode == KICK) + if (kind == BAD_MRICEBLOCK && state == KICK) { Sector::current()->trybreakbrick( Vector(base.x + base.width, base.y + halfheight), false); @@ -438,7 +428,7 @@ BadGuy::fall() // no gravity anymore please physic.enable_gravity(false); - if (stay_on_platform && mode == NORMAL) + if (stay_on_platform && state == NORMAL) { if (!issolid(base.x + ((dir == LEFT) ? 0 : base.width), base.y + base.height)) @@ -462,22 +452,22 @@ BadGuy::fall() physic.enable_gravity(true); } } +#endif void BadGuy::action_jumpy(double elapsed_time) { - if(frozen_timer.check()) - { + if(frozen_timer.check()) { set_action("left-iced", "right-iced"); return; - } + } const float vy = physic.get_velocity_y(); // XXX: These tests *should* use location from ground, not velocity - if (fabsf(vy) > 5.6f) + if (fabsf(vy) > 560) set_action("left-down", "right-down"); - else if (fabsf(vy) > 5.3f) + else if (fabsf(vy) > 530) set_action("left-middle", "right-middle"); else set_action("left-up", "right-up"); @@ -493,21 +483,20 @@ BadGuy::action_jumpy(double elapsed_time) physic.set_velocity_y(JUMPV); physic.enable_gravity(true); - mode = JUMPY_JUMP; + state = JUMPY_JUMP; } - else if(mode == JUMPY_JUMP) + else if(state == JUMPY_JUMP) { - mode = NORMAL; + state = NORMAL; } // set direction based on tux - if(dying == DYING_NOT) - { + if(dying == DYING_NOT) { if(tux.base.x > base.x) dir = RIGHT; else dir = LEFT; - } + } // move physic.apply(elapsed_time, base.x, base.y, Sector::current()->gravity); @@ -542,18 +531,18 @@ BadGuy::action_bomb(double elapsed_time) fall(); - if(mode == NORMAL) { - mode = BOMB_TICKING; + if(state == NORMAL) { + state = BOMB_TICKING; timer.start(TICKINGTIME); } else if(!timer.check()) { - if(mode == BOMB_TICKING) { - mode = BOMB_EXPLODE; + if(state == BOMB_TICKING) { + state = BOMB_EXPLODE; set_action("explosion", "explosion"); dying = DYING_NOT; // now the bomb hurts timer.start(EXPLODETIME); SoundManager::get()->play_sound(IDToSound(SND_EXPLODE), this, Sector::current()->player->get_pos()); - } else if(mode == BOMB_EXPLODE) { + } else if(state == BOMB_EXPLODE) { remove_me(); return; } @@ -572,31 +561,31 @@ BadGuy::action_stalactite(double elapsed_time) static const int SHAKETIME = 800; static const int RANGE = 40; - if(mode == NORMAL) { + if(state == NORMAL) { // start shaking when tux is below the stalactite and at least 40 pixels // near if(tux.base.x + 32 > base.x - RANGE && tux.base.x < base.x + 32 + RANGE && tux.base.y + tux.base.height > base.y && tux.dying == DYING_NOT) { timer.start(SHAKETIME); - mode = STALACTITE_SHAKING; + state = STALACTITE_SHAKING; } - } if(mode == STALACTITE_SHAKING) { + } if(state == STALACTITE_SHAKING) { base.x = old_base.x + (rand() % 6) - 3; // TODO this could be done nicer... if(!timer.check()) { - mode = STALACTITE_FALL; + state = STALACTITE_FALL; } - } else if(mode == STALACTITE_FALL) { + } else if(state == STALACTITE_FALL) { fall(); /* Destroy if we collides with land */ if(issolid(base.x+base.width/2, base.y+base.height)) { timer.start(2000); dying = DYING_SQUISHED; - mode = FLAT; + state = FLAT; set_action("broken", "broken"); } - } else if(mode == FLAT) { + } else if(state == FLAT) { fall(); } @@ -634,23 +623,23 @@ BadGuy::action_fish(double elapsed_time) static const float JUMPV = 6; static const int WAITTIME = 1000; - // go in wait mode when back in water + // go in wait state when back in water if(dying == DYING_NOT && gettile(base.x, base.y + base.height) && gettile(base.x, base.y + base.height)->attributes & Tile::WATER - && physic.get_velocity_y() <= 0 && mode == NORMAL) + && physic.get_velocity_y() <= 0 && state == NORMAL) { - mode = FISH_WAIT; + state = FISH_WAIT; set_action("hide", "hide"); physic.set_velocity(0, 0); physic.enable_gravity(false); timer.start(WAITTIME); } - else if(mode == FISH_WAIT && !timer.check()) + else if(state == FISH_WAIT && !timer.check()) { // jump again set_action("normal", "normal"); - mode = NORMAL; + state = NORMAL; physic.set_velocity(0, JUMPV); physic.enable_gravity(true); } @@ -680,7 +669,7 @@ BadGuy::action_bouncingsnowball(double elapsed_time) } else { - mode = NORMAL; + state = NORMAL; } // check for right/left collisions @@ -701,19 +690,19 @@ BadGuy::action_flyingsnowball(double elapsed_time) static const float FLYINGSPEED = 1; static const int DIRCHANGETIME = 1000; - // go into flyup mode if none specified yet - if(dying == DYING_NOT && mode == NORMAL) { - mode = FLY_UP; + // go into flyup state if none specified yet + if(dying == DYING_NOT && state == NORMAL) { + state = FLY_UP; physic.set_velocity_y(FLYINGSPEED); timer.start(DIRCHANGETIME/2); } if(dying == DYING_NOT && !timer.check()) { - if(mode == FLY_UP) { - mode = FLY_DOWN; + if(state == FLY_UP) { + state = FLY_DOWN; physic.set_velocity_y(-FLYINGSPEED); - } else if(mode == FLY_DOWN) { - mode = FLY_UP; + } else if(state == FLY_DOWN) { + state = FLY_UP; physic.set_velocity_y(FLYINGSPEED); } timer.start(DIRCHANGETIME); @@ -986,7 +975,7 @@ BadGuy::draw(DrawingContext& context) else specs->sprite->draw(context, Vector(base.x, base.y), LAYER_OBJECTS); - if(debug_mode) + if(debug_state) context.draw_filled_rect(Vector(base.x, base.y), Vector(base.width, base.height), Color(75,0,75, 150), LAYER_OBJECTS+1); } @@ -1079,16 +1068,16 @@ BadGuy::squish(Player* player) return; } else if (kind == BAD_MRICEBLOCK) { - if (mode == NORMAL || mode == KICK) + if (state == NORMAL || state == KICK) { /* Flatten! */ SoundManager::get()->play_sound(IDToSound(SND_STOMP), get_pos(), Sector::current()->player->get_pos()); - mode = FLAT; + state = FLAT; set_action("flat-left", "flat-right"); physic.set_velocity_x(0); timer.start(4000); - } else if (mode == FLAT) { + } else if (state == FLAT) { /* Kick! */ SoundManager::get()->play_sound(IDToSound(SND_KICK), this, Sector::current()->player->get_pos()); @@ -1100,7 +1089,7 @@ BadGuy::squish(Player* player) dir = LEFT; } - mode = KICK; + state = KICK; player->kick_timer.start(KICKING_TIME); set_action("flat-left", "flat-right"); } @@ -1148,7 +1137,7 @@ BadGuy::squish(Player* player) squish_me(player); set_action("left", "right"); } else if(kind == BAD_WALKINGTREE) { - if (mode == BGM_BIG) + if (state == BGM_BIG) { set_action("left-small", "left-small"); physic.set_velocity_x(physic.get_velocity_x() * 2.0f); @@ -1167,7 +1156,7 @@ BadGuy::squish(Player* player) 25 * player_status.score_multiplier); player_status.score_multiplier++; - mode = BGM_SMALL; + state = BGM_SMALL; } else squish_me(player); @@ -1180,14 +1169,14 @@ BadGuy::kill_me(int score) if(kind == BAD_BOMB) return; - if(mode != HELD) + if(state != HELD) global_stats.add_points(BADGUYS_KILLED_STAT, 1); dying = DYING_FALLING; if(kind == BAD_MRICEBLOCK) { set_action("falling-left", "falling-right"); - if(mode == HELD) { - mode = NORMAL; + if(state == HELD) { + state = NORMAL; Player& tux = *Sector::current()->player; tux.holding_something = false; } @@ -1211,7 +1200,7 @@ BadGuy::explode(bool right_way) if(right_way) { badguy->timer.start(0); - badguy->mode = BOMB_TICKING; + badguy->state = BOMB_TICKING; } badguy->dir = dir; @@ -1267,14 +1256,14 @@ BadGuy::collision(void *p_c_object, int c_object, CollisionType type) /* If we're a kicked mriceblock, kill [almost] any badguys we hit */ - if(kind == BAD_MRICEBLOCK && mode == KICK && + if(kind == BAD_MRICEBLOCK && state == KICK && kind != BAD_FLAME && kind != BAD_BOMB && kind != BAD_STALACTITE) { pbad_c->kill_me(25); } // a held mriceblock kills the enemy too but falls to ground then - else if(kind == BAD_MRICEBLOCK && mode == HELD) + else if(kind == BAD_MRICEBLOCK && state == HELD) { pbad_c->kill_me(25); kill_me(0); @@ -1366,7 +1355,7 @@ BadGuy::collision(void *p_c_object, int c_object, CollisionType type) case CO_PLAYER: Player* player = static_cast(p_c_object); /* Get kicked if were flat */ - if (mode == FLAT && !dying) + if (state == FLAT && !dying) { SoundManager::get()->play_sound(IDToSound(SND_KICK), this, Sector::current()->player->get_pos()); @@ -1381,7 +1370,7 @@ BadGuy::collision(void *p_c_object, int c_object, CollisionType type) dir = LEFT; } - mode = KICK; + state = KICK; player->kick_timer.start(KICKING_TIME); set_action("flat-left", "flat-right"); } @@ -1390,4 +1379,4 @@ BadGuy::collision(void *p_c_object, int c_object, CollisionType type) } } -// EOF // +#endif diff --git a/src/badguy.h b/src/badguy.h index 3ec189bbe..5b9444570 100644 --- a/src/badguy.h +++ b/src/badguy.h @@ -26,7 +26,7 @@ #include "SDL.h" #include "utils/lispreader.h" -#include "special/timer.h" +#include "timer.h" #include "math/physic.h" #include "defines.h" #include "special/moving_object.h" @@ -36,9 +36,8 @@ using namespace SuperTux; -/* Timing constants (in ms): */ - -#define KICKING_TIME 200 +/* Timing constants */ +#define KICKING_TIME .2 /* Bad guy kinds: */ enum BadGuyKind { @@ -64,6 +63,8 @@ enum BadGuyKind { BadGuyKind badguykind_from_string(const std::string& str); std::string badguykind_to_string(BadGuyKind kind); +#if 0 + class Player; class BadGuySpecs; @@ -72,7 +73,7 @@ class BadGuy : public MovingObject, public Serializable { public: /* Enemy modes: */ - enum BadGuyMode { + enum BadGuyState { NORMAL=0, FLAT, KICK, @@ -95,9 +96,9 @@ public: BGM_SMALL }; public: - DyingType dying; - BadGuyKind kind; - BadGuyMode mode; + DyingType dying; + BadGuyKind kind; + BadGuyState state; /** If true the enemy will stay on its current platform, ie. if he reaches the edge he will turn around and walk into the other @@ -110,7 +111,6 @@ public: Timer frozen_timer; // gets frozen when a ice shot hits it private: - bool removable; bool seen; int squishcount; /// number of times this enemy was squiched Vector target; // Target that badguy is aiming for (wingling uses this) @@ -186,9 +186,6 @@ private: void set_action(std::string action_left, std::string action_right); }; -#endif /*SUPERTUX_BADGUY_H*/ - -/* Local Variables: */ -/* mode:c++ */ -/* End: */ +#endif +#endif /*SUPERTUX_BADGUY_H*/ diff --git a/src/badguy/badguy.cpp b/src/badguy/badguy.cpp new file mode 100644 index 000000000..375441415 --- /dev/null +++ b/src/badguy/badguy.cpp @@ -0,0 +1,254 @@ +#include + +#include "badguy.h" +#include "camera.h" + +static const float SQUISH_TIME = 2; +static const float X_OFFSCREEN_DISTANCE = 1600; +static const float Y_OFFSCREEN_DISTANCE = 1200; + +BadGuy::BadGuy() + : sprite(0), dir(LEFT), state(STATE_INIT) +{ +} + +BadGuy::~BadGuy() +{ + delete sprite; +} + +void +BadGuy::draw(DrawingContext& context) +{ + if(!sprite) + return; + if(state == STATE_INIT || state == STATE_INACTIVE) + return; + + sprite->draw(context, get_pos(), LAYER_OBJECTS); +} + +void +BadGuy::action(float elapsed_time) +{ + if(!Sector::current()->inside(bbox)) { + remove_me(); + return; + } + if(is_offscreen()) { + set_state(STATE_INACTIVE); + } + + switch(state) { + case STATE_ACTIVE: + active_action(elapsed_time); + break; + case STATE_INIT: + case STATE_INACTIVE: + inactive_action(elapsed_time); + try_activate(); + break; + case STATE_SQUISHED: + if(state_timer.check()) { + remove_me(); + break; + } + movement = physic.get_movement(elapsed_time); + break; + case STATE_FALLING: + movement = physic.get_movement(elapsed_time); + break; + } +} + +void +BadGuy::activate() +{ +} + +void +BadGuy::deactivate() +{ +} + +void +BadGuy::active_action(float elapsed_time) +{ + movement = physic.get_movement(elapsed_time); +} + +void +BadGuy::inactive_action(float elapsed_time) +{ +} + +HitResponse +BadGuy::collision(GameObject& other, const CollisionHit& hit) +{ + switch(state) { + case STATE_INIT: + case STATE_INACTIVE: + return ABORT_MOVE; + case STATE_ACTIVE: { + if(other.get_flags() & FLAG_SOLID) + return collision_solid(other, hit); + + BadGuy* badguy = dynamic_cast (&other); + if(badguy) + return collision_badguy(*badguy, hit); + + Player* player = dynamic_cast (&other); + if(player) + return collision_player(*player, hit); + + return FORCE_MOVE; + } + case STATE_SQUISHED: + if(other.get_flags() & FLAG_SOLID) + return CONTINUE; + return FORCE_MOVE; + case STATE_FALLING: + return FORCE_MOVE; + } + + return ABORT_MOVE; +} + +HitResponse +BadGuy::collision_solid(GameObject& other, const CollisionHit& hit) +{ + return FORCE_MOVE; +} + +HitResponse +BadGuy::collision_player(Player& player, const CollisionHit& hit) +{ + if(player.is_invincible()) { + kill_fall(); + return ABORT_MOVE; + } + if(hit.normal.y > .9) { + if(collision_squished(player)) + return ABORT_MOVE; + } + player.kill(Player::SHRINK); + return FORCE_MOVE; +} + +HitResponse +BadGuy::collision_badguy(BadGuy& other, const CollisionHit& hit) +{ + return FORCE_MOVE; +} + +bool +BadGuy::collision_squished(Player& player) +{ + return false; +} + +void +BadGuy::kill_squished(Player& player) +{ + SoundManager::get()->play_sound(IDToSound(SND_SQUISH), get_pos(), + player.get_pos()); + physic.set_velocity_x(0); + physic.set_velocity_y(0); + set_state(STATE_SQUISHED); + player.bounce(*this); +} + +void +BadGuy::kill_fall() +{ + physic.set_velocity_y(0); + physic.enable_gravity(true); + set_state(STATE_FALLING); + remove_me(); +} + +void +BadGuy::set_state(State state) +{ + if(this->state == state) + return; + + State laststate = this->state; + this->state = state; + switch(state) { + case STATE_SQUISHED: + state_timer.start(SQUISH_TIME); + break; + case STATE_ACTIVE: + flags &= ~FLAG_NO_COLLDET; + bbox.set_pos(start_position); + break; + case STATE_INACTIVE: + // was the badguy dead anyway? + if(laststate == STATE_SQUISHED || laststate == STATE_SQUISHED) { + remove_me(); + } + flags |= FLAG_NO_COLLDET; + break; + default: + break; + } +} + +bool +BadGuy::is_offscreen() +{ + float scroll_x = Sector::current()->camera->get_translation().x; + float scroll_y = Sector::current()->camera->get_translation().y; + + if(bbox.p2.x < scroll_x - X_OFFSCREEN_DISTANCE + || bbox.p1.x > scroll_x + X_OFFSCREEN_DISTANCE + || bbox.p2.y < scroll_y - Y_OFFSCREEN_DISTANCE + || bbox.p1.y > scroll_y + Y_OFFSCREEN_DISTANCE) + return true; + + return false; +} + +void +BadGuy::try_activate() +{ + float scroll_x = Sector::current()->camera->get_translation().x; + float scroll_y = Sector::current()->camera->get_translation().y; + + /* Activate badguys if they're just around the screen to avoid + * the effect of having badguys suddenly popping up from nowhere. + */ + if (start_position.x > scroll_x - X_OFFSCREEN_DISTANCE && + start_position.x < scroll_x - bbox.get_width() && + start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE && + start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE) { + dir = RIGHT; + set_state(STATE_ACTIVE); + activate(); + } else if (start_position.x > scroll_x && + start_position.x < scroll_x + X_OFFSCREEN_DISTANCE && + start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE && + start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE) { + dir = LEFT; + set_state(STATE_ACTIVE); + activate(); + } else if (start_position.x > scroll_x - X_OFFSCREEN_DISTANCE && + start_position.x < scroll_x + X_OFFSCREEN_DISTANCE && + ((start_position.y > scroll_y && + start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE) || + (start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE && + start_position.y < scroll_y))) { + dir = start_position.x < scroll_x ? RIGHT : LEFT; + set_state(STATE_ACTIVE); + activate(); + } else if(state == STATE_INIT + && start_position.x > scroll_x - X_OFFSCREEN_DISTANCE + && start_position.x < scroll_x + X_OFFSCREEN_DISTANCE + && start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE + && start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE) { + dir = LEFT; + set_state(STATE_ACTIVE); + activate(); + } +} diff --git a/src/badguy/badguy.h b/src/badguy/badguy.h new file mode 100644 index 000000000..d92d6b2ff --- /dev/null +++ b/src/badguy/badguy.h @@ -0,0 +1,99 @@ +#ifndef __BADGUY_H__ +#define __BADGUY_H__ + +// moved them here to make it less typing when implementing new badguys +#include +#include "timer.h" +#include "special/moving_object.h" +#include "special/sprite.h" +#include "math/physic.h" +#include "player.h" +#include "serializable.h" +#include "resources.h" +#include "sector.h" +#include "utils/lispwriter.h" +#include "utils/lispreader.h" +#include "video/drawing_context.h" +#include "special/sprite_manager.h" + +using namespace SuperTux; + +class BadGuy : public MovingObject, public Serializable +{ +public: + BadGuy(); + ~BadGuy(); + + //virtual void action_activated(float elapsed_time); + + virtual void draw(DrawingContext& context); + virtual void action(float elapsed_time); + virtual HitResponse collision(GameObject& other, + const CollisionHit& hit); + + virtual void kill_fall(); + +protected: + enum State { + STATE_INIT, + STATE_INACTIVE, + STATE_ACTIVE, + STATE_SQUISHED, + STATE_FALLING + }; + + virtual HitResponse collision_player(Player& player, + const CollisionHit& hit); + virtual HitResponse collision_solid(GameObject& other, + const CollisionHit& hit); + virtual HitResponse collision_badguy(BadGuy& other, + const CollisionHit& hit); + + virtual bool collision_squished(Player& player); + + virtual void active_action(float elapsed_time); + virtual void inactive_action(float elapsed_time); + + /** + * called when the badguy has been activated. (As a side effect the dir + * variable might have been changed so that it faces towards the player. + */ + virtual void activate(); + /** caleed when the badguy has been deactivated */ + virtual void deactivate(); + + void kill_squished(Player& player); + + void set_state(State state); + State get_state() const + { return state; } + + /** + * returns a pointer to the player, try to avoid this function to avoid + * problems later when we have multiple players or no player in scripted + * sequence. + */ + Player* get_player(); + + Sprite* sprite; + Physic physic; + + /// is the enemy activated + bool activated; + /** + * initial position of the enemy. Also the position where enemy respawns when + * after being deactivated. + */ + Vector start_position; + + Direction dir; +private: + bool is_offscreen(); + void try_activate(); + + State state; + Timer2 state_timer; +}; + +#endif + diff --git a/src/badguy/bomb.cpp b/src/badguy/bomb.cpp new file mode 100644 index 000000000..88ed94e06 --- /dev/null +++ b/src/badguy/bomb.cpp @@ -0,0 +1,66 @@ +#include + +#include "bomb.h" + +static const float TICKINGTIME = 1; +static const float EXPLOSIONTIME = 1; + +Bomb::Bomb(const Vector& pos, Direction dir) +{ + start_position = pos; + bbox.set_pos(pos); + bbox.set_size(32, 32); + sprite = sprite_manager->create("bomb"); + state = 0; + timer.start(TICKINGTIME); + this->dir = dir; + sprite->set_action(dir == LEFT ? "ticking-left" : "ticking-right"); +} + +void +Bomb::write(LispWriter& writer) +{ + // bombs are only temporarily so don't write them out... +} + +HitResponse +Bomb::collision_solid(GameObject& other, const CollisionHit& hit) +{ + if(fabsf(hit.normal.y) > .5) + physic.set_velocity_y(0); + + return CONTINUE; +} + +HitResponse +Bomb::collision_player(Player& player, const CollisionHit& hit) +{ + if(state == 1) { + player.kill(Player::SHRINK); + } + return ABORT_MOVE; +} + +void +Bomb::active_action(float elapsed_time) +{ + switch(state) { + case 0: + if(timer.check()) { + state = 1; + sprite->set_action("explosion"); + timer.start(EXPLOSIONTIME); + } + break; + case 1: + if(timer.check()) { + remove_me(); + } + break; + } +} + +void +Bomb::kill_fall() +{ +} diff --git a/src/badguy/bomb.h b/src/badguy/bomb.h new file mode 100644 index 000000000..9d0959930 --- /dev/null +++ b/src/badguy/bomb.h @@ -0,0 +1,23 @@ +#ifndef __BOMB_H__ +#define __BOMB_H__ + +#include "badguy.h" + +class Bomb : public BadGuy +{ +public: + Bomb(const Vector& pos, Direction dir); + + void write(LispWriter& writer); + HitResponse collision_solid(GameObject& other, const CollisionHit& hit); + HitResponse collision_player(Player& player, const CollisionHit& hit); + void active_action(float elapsed_time); + void kill_fall(); + +private: + int state; + Timer2 timer; +}; + +#endif + diff --git a/src/badguy/bouncing_snowball.cpp b/src/badguy/bouncing_snowball.cpp new file mode 100644 index 000000000..97f40c301 --- /dev/null +++ b/src/badguy/bouncing_snowball.cpp @@ -0,0 +1,57 @@ +#include + +#include "bouncing_snowball.h" + +static const float JUMPSPEED = 450; +static const float WALKSPEED = 80; + +BouncingSnowball::BouncingSnowball(LispReader& reader) +{ + reader.read_float("x", start_position.x); + reader.read_float("y", start_position.y); + bbox.set_size(32, 32); + sprite = sprite_manager->create("bouncingsnowball"); +} + +void +BouncingSnowball::write(LispWriter& writer) +{ + writer.start_list("bouncingsnowball"); + + writer.write_float("x", get_pos().x); + writer.write_float("y", get_pos().y); + + writer.end_list("bouncingsnowball"); +} + +void +BouncingSnowball::activate() +{ + physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED); + sprite->set_action(dir == LEFT ? "left" : "right"); +} + +bool +BouncingSnowball::collision_squished(Player& player) +{ + sprite->set_action("squished"); + kill_squished(player); + return true; +} + +HitResponse +BouncingSnowball::collision_solid(GameObject& other, const CollisionHit& hit) +{ + if(hit.normal.y < -.5) { // hit floor + physic.set_velocity_y(JUMPSPEED); + } else if(hit.normal.y > .5) { // bumped on roof + physic.set_velocity_y(0); + } else { // left or right collision + dir = dir == LEFT ? RIGHT : LEFT; + sprite->set_action(dir == LEFT ? "left" : "right"); + physic.set_velocity_x(-physic.get_velocity_x()); + } + + return CONTINUE; +} + diff --git a/src/badguy/bouncing_snowball.h b/src/badguy/bouncing_snowball.h new file mode 100644 index 000000000..5bc7c1156 --- /dev/null +++ b/src/badguy/bouncing_snowball.h @@ -0,0 +1,20 @@ +#ifndef __BOUNCING_SNOWBALL_H__ +#define __BOUNCING_SNOWBALL_H__ + +#include "badguy.h" + +class BouncingSnowball : public BadGuy +{ +public: + BouncingSnowball(LispReader& reader); + + void activate(); + void write(LispWriter& writer); + HitResponse collision_solid(GameObject& other, const CollisionHit& hit); + +protected: + bool collision_squished(Player& player); +}; + +#endif + diff --git a/src/badguy/flame.cpp b/src/badguy/flame.cpp new file mode 100644 index 000000000..83845a6dd --- /dev/null +++ b/src/badguy/flame.cpp @@ -0,0 +1,44 @@ +#include + +#include "flame.h" + +Flame::Flame(LispReader& reader) + : angle(0), radius(100), speed(2) +{ + reader.read_float("x", start_position.x); + reader.read_float("y", start_position.y); + reader.read_float("radius", radius); + reader.read_float("speed", speed); + bbox.set_pos(Vector(start_position.x + cos(angle) * radius, + start_position.y + sin(angle) * radius)); + bbox.set_size(32, 32); + sprite = sprite_manager->create("flame"); +} + +void +Flame::write(LispWriter& writer) +{ + writer.start_list("flame"); + + writer.write_float("x", start_position.x); + writer.write_float("y", start_position.y); + writer.write_float("radius", radius); + writer.write_float("speed", speed); + + writer.end_list("flame"); +} + +void +Flame::active_action(float elapsed_time) +{ + angle = fmodf(angle + elapsed_time * speed, 2*M_PI); + Vector newpos(start_position.x + cos(angle) * radius, + start_position.y + sin(angle) * radius); + movement = newpos - get_pos(); +} + +void +Flame::kill_fall() +{ +} + diff --git a/src/badguy/flame.h b/src/badguy/flame.h new file mode 100644 index 000000000..b27e1f0c7 --- /dev/null +++ b/src/badguy/flame.h @@ -0,0 +1,22 @@ +#ifndef __FLAME_H__ +#define __FLAME_H__ + +#include "badguy.h" + +class Flame : public BadGuy +{ +public: + Flame(LispReader& reader); + + void write(LispWriter& write); + void active_action(float elapsed_time); + void kill_fall(); + +private: + float angle; + float radius; + float speed; +}; + +#endif + diff --git a/src/badguy/jumpy.cpp b/src/badguy/jumpy.cpp new file mode 100644 index 000000000..4ac9960f0 --- /dev/null +++ b/src/badguy/jumpy.cpp @@ -0,0 +1,38 @@ +#include + +#include "jumpy.h" + +static const float JUMPSPEED=600; + +Jumpy::Jumpy(LispReader& reader) +{ + reader.read_float("x", start_position.x); + reader.read_float("y", start_position.y); + bbox.set_size(32, 32); + sprite = sprite_manager->create("jumpy"); +} + +void +Jumpy::write(LispWriter& writer) +{ + writer.start_list("jumpy"); + + writer.write_float("x", get_pos().x); + writer.write_float("y", get_pos().y); + + writer.end_list("jumpy"); +} + +HitResponse +Jumpy::collision_solid(GameObject& other, const CollisionHit& hit) +{ + // hit floor? + if(hit.normal.y < -.5) { + physic.set_velocity_y(JUMPSPEED); + } else if(hit.normal.y < .5) { // bumped on roof + physic.set_velocity_y(0); + } + + return CONTINUE; +} + diff --git a/src/badguy/jumpy.h b/src/badguy/jumpy.h new file mode 100644 index 000000000..8abd10c70 --- /dev/null +++ b/src/badguy/jumpy.h @@ -0,0 +1,21 @@ +#ifndef __JUMPY_H__ +#define __JUMPY_H__ + +#include "badguy.h" +#include "utils/lispreader.h" +#include "utils/lispwriter.h" +#include "serializable.h" + +class Jumpy : public BadGuy +{ +public: + Jumpy(LispReader& reader); + + virtual HitResponse collision_solid(GameObject& other, + const CollisionHit& hit); + + virtual void write(LispWriter& writer); +}; + +#endif + diff --git a/src/badguy/mrbomb.cpp b/src/badguy/mrbomb.cpp new file mode 100644 index 000000000..27c0d6568 --- /dev/null +++ b/src/badguy/mrbomb.cpp @@ -0,0 +1,56 @@ +#include + +#include "mrbomb.h" +#include "bomb.h" + +static const float WALKSPEED = 80; + +MrBomb::MrBomb(LispReader& reader) +{ + reader.read_float("x", start_position.x); + reader.read_float("y", start_position.y); + bbox.set_size(32, 32); + sprite = sprite_manager->create("mrbomb"); +} + +void +MrBomb::write(LispWriter& writer) +{ + writer.start_list("snowball"); + + writer.write_float("x", get_pos().x); + writer.write_float("y", get_pos().y); + + writer.end_list("snowball"); +} + +void +MrBomb::activate() +{ + physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED); + sprite->set_action(dir == LEFT ? "left" : "right"); +} + +bool +MrBomb::collision_squished(Player& player) +{ + remove_me(); + Sector::current()->add_object(new Bomb(get_pos(), dir)); + player.bounce(*this); + return true; +} + +HitResponse +MrBomb::collision_solid(GameObject& other, const CollisionHit& hit) +{ + if(fabsf(hit.normal.y) > .5) { // hit floor or roof? + physic.set_velocity_y(0); + } else { // hit right or left + dir = dir == LEFT ? RIGHT : LEFT; + sprite->set_action(dir == LEFT ? "left" : "right"); + physic.set_velocity_x(-physic.get_velocity_x()); + } + + return CONTINUE; +} + diff --git a/src/badguy/mrbomb.h b/src/badguy/mrbomb.h new file mode 100644 index 000000000..a20b253d3 --- /dev/null +++ b/src/badguy/mrbomb.h @@ -0,0 +1,20 @@ +#ifndef __MRBOMB_H__ +#define __MRBOMB_H__ + +#include "badguy.h" + +class MrBomb : public BadGuy +{ +public: + MrBomb(LispReader& reader); + + void activate(); + void write(LispWriter& writer); + HitResponse collision_solid(GameObject& other, const CollisionHit& hit); + +protected: + bool collision_squished(Player& player); +}; + +#endif + diff --git a/src/badguy/mriceblock.cpp b/src/badguy/mriceblock.cpp new file mode 100644 index 000000000..5e7141367 --- /dev/null +++ b/src/badguy/mriceblock.cpp @@ -0,0 +1,120 @@ +#include + +#include "mriceblock.h" + +static const float WALKSPEED = 80; +static const float KICKSPEED = 500; +static const int MAXSQUISHES = 10; + +MrIceBlock::MrIceBlock(LispReader& reader) + : ice_state(ICESTATE_NORMAL), squishcount(0) +{ + reader.read_float("x", start_position.x); + reader.read_float("y", start_position.y); + bbox.set_size(32, 32); + sprite = sprite_manager->create("mriceblock"); +} + +void +MrIceBlock::write(LispWriter& writer) +{ + writer.start_list("mriceblock"); + + writer.write_float("x", get_pos().x); + writer.write_float("y", get_pos().y); + + writer.end_list("mriceblock"); +} + +void +MrIceBlock::activate() +{ + physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED); + sprite->set_action(dir == LEFT ? "left" : "right"); +} + +void +MrIceBlock::active_action(float elapsed_time) +{ + if(ice_state == ICESTATE_FLAT && flat_timer.check()) { + printf("unflat.\n"); + ice_state = ICESTATE_NORMAL; + physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED); + sprite->set_action(dir == LEFT ? "left" : "right"); + } + BadGuy::active_action(elapsed_time); +} + +HitResponse +MrIceBlock::collision_solid(GameObject& other, const CollisionHit& hit) +{ + if(fabsf(hit.normal.y) > .5) { // floor or roof + physic.set_velocity_y(0); + return CONTINUE; + } + // hit left or right + switch(ice_state) { + case ICESTATE_NORMAL: + dir = dir == LEFT ? RIGHT : LEFT; + sprite->set_action(dir == LEFT ? "left" : "right"); + physic.set_velocity_x(-physic.get_velocity_x()); + break; + case ICESTATE_KICKED: + dir = dir == LEFT ? RIGHT : LEFT; + sprite->set_action(dir == LEFT ? "flat-left" : "flat-right"); + physic.set_velocity_x(-physic.get_velocity_x()); + SoundManager::get()->play_sound(IDToSound(SND_RICOCHET), get_pos(), + Sector::current()->player->get_pos()); + break; + case ICESTATE_FLAT: + physic.set_velocity_x(0); + break; + } + + return CONTINUE; +} + +bool +MrIceBlock::collision_squished(Player& player) +{ + switch(ice_state) { + case ICESTATE_KICKED: + case ICESTATE_NORMAL: + squishcount++; + if(squishcount >= MAXSQUISHES) { + kill_fall(); + return true; + } + + // flatten + SoundManager::get()->play_sound(IDToSound(SND_STOMP), get_pos(), + player.get_pos()); + physic.set_velocity_x(0); + physic.set_velocity_y(0); + + sprite->set_action(dir == LEFT ? "flat-left" : "flat-right"); + flat_timer.start(4); + ice_state = ICESTATE_FLAT; + printf("flat.\n"); + break; + case ICESTATE_FLAT: + // kick + SoundManager::get()->play_sound(IDToSound(SND_KICK), this, + player.get_pos()); + + if(player.get_pos().x < get_pos().x) { + dir = RIGHT; + } else { + dir = LEFT; + } + physic.set_velocity_x(dir == LEFT ? -KICKSPEED : KICKSPEED); + sprite->set_action(dir == LEFT ? "flat-left" : "flat-right"); + ice_state = ICESTATE_KICKED; + printf("kicked.\n"); + break; + } + + player.bounce(*this); + return true; +} + diff --git a/src/badguy/mriceblock.h b/src/badguy/mriceblock.h new file mode 100644 index 000000000..3b9169003 --- /dev/null +++ b/src/badguy/mriceblock.h @@ -0,0 +1,32 @@ +#ifndef __MRICEBLOCK_H__ +#define __MRICEBLOCK_H__ + +#include "badguy.h" + +class MrIceBlock : public BadGuy +{ +public: + MrIceBlock(LispReader& reader); + + void activate(); + void write(LispWriter& writer); + HitResponse collision_solid(GameObject& other, const CollisionHit& hit); + + void active_action(float elapsed_time); + +protected: + bool collision_squished(Player& player); + +private: + enum IceState { + ICESTATE_NORMAL, + ICESTATE_FLAT, + ICESTATE_KICKED + }; + IceState ice_state; + Timer2 flat_timer; + int squishcount; +}; + +#endif + diff --git a/src/badguy/snowball.cpp b/src/badguy/snowball.cpp new file mode 100644 index 000000000..4c9bdea96 --- /dev/null +++ b/src/badguy/snowball.cpp @@ -0,0 +1,54 @@ +#include + +#include "snowball.h" + +static const float WALKSPEED = 80; + +SnowBall::SnowBall(LispReader& reader) +{ + reader.read_float("x", start_position.x); + reader.read_float("y", start_position.y); + bbox.set_size(32, 32); + sprite = sprite_manager->create("snowball"); +} + +void +SnowBall::write(LispWriter& writer) +{ + writer.start_list("snowball"); + + writer.write_float("x", get_pos().x); + writer.write_float("y", get_pos().y); + + writer.end_list("snowball"); +} + +void +SnowBall::activate() +{ + physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED); + sprite->set_action(dir == LEFT ? "left" : "right"); +} + +bool +SnowBall::collision_squished(Player& player) +{ + sprite->set_action(dir == LEFT ? "squished-left" : "squished-right"); + kill_squished(player); + return true; +} + +HitResponse +SnowBall::collision_solid(GameObject& other, const CollisionHit& hit) +{ + if(fabsf(hit.normal.y) > .5) { // hit floor or roof? + physic.set_velocity_y(0); + } else { // hit right or left + dir = dir == LEFT ? RIGHT : LEFT; + sprite->set_action(dir == LEFT ? "left" : "right"); + physic.set_velocity_x(-physic.get_velocity_x()); + } + + return CONTINUE; +} + diff --git a/src/badguy/snowball.h b/src/badguy/snowball.h new file mode 100644 index 000000000..99a65d651 --- /dev/null +++ b/src/badguy/snowball.h @@ -0,0 +1,20 @@ +#ifndef __SNOWBALL_H__ +#define __SNOWBALL_H__ + +#include "badguy.h" + +class SnowBall : public BadGuy +{ +public: + SnowBall(LispReader& reader); + + void activate(); + void write(LispWriter& writer); + HitResponse collision_solid(GameObject& other, const CollisionHit& hit); + +protected: + bool collision_squished(Player& player); +}; + +#endif + diff --git a/src/badguy/spiky.cpp b/src/badguy/spiky.cpp new file mode 100644 index 000000000..44bb3766a --- /dev/null +++ b/src/badguy/spiky.cpp @@ -0,0 +1,46 @@ +#include + +#include "spiky.h" + +static const float WALKSPEED = 80; + +Spiky::Spiky(LispReader& reader) +{ + reader.read_float("x", start_position.x); + reader.read_float("y", start_position.y); + bbox.set_size(32, 32); + sprite = sprite_manager->create("spiky"); +} + +void +Spiky::write(LispWriter& writer) +{ + writer.start_list("spiky"); + + writer.write_float("x", get_pos().x); + writer.write_float("y", get_pos().y); + + writer.end_list("spiky"); +} + +void +Spiky::activate() +{ + physic.set_velocity_x(dir == LEFT ? -WALKSPEED : WALKSPEED); + sprite->set_action(dir == LEFT ? "left" : "right"); +} + +HitResponse +Spiky::collision_solid(GameObject& other, const CollisionHit& hit) +{ + if(fabsf(hit.normal.y) > .5) { // hit floor or roof? + physic.set_velocity_y(0); + } else { // hit right or left + dir = dir == LEFT ? RIGHT : LEFT; + sprite->set_action(dir == LEFT ? "left" : "right"); + physic.set_velocity_x(-physic.get_velocity_x()); + } + + return CONTINUE; +} + diff --git a/src/badguy/spiky.h b/src/badguy/spiky.h new file mode 100644 index 000000000..547ea13cb --- /dev/null +++ b/src/badguy/spiky.h @@ -0,0 +1,16 @@ +#ifndef __SPIKY_H__ +#define __SPIKY_H__ + +#include "badguy.h" + +class Spiky : public BadGuy +{ +public: + Spiky(LispReader& reader); + + void activate(); + void write(LispWriter& writer); + HitResponse collision_solid(GameObject& other, const CollisionHit& hit); +}; + +#endif diff --git a/src/badguy_specs.cpp b/src/badguy_specs.cpp index bf139b1f5..62f2cace4 100644 --- a/src/badguy_specs.cpp +++ b/src/badguy_specs.cpp @@ -15,6 +15,8 @@ * * ***************************************************************************/ +#include + #include #include "special/sprite_manager.h" @@ -124,12 +126,11 @@ BadGuySpecs::BadGuySpecs(LispReader& reader) if(str.empty()) std::cerr << "Warning: No sprite has been set to badguy " << kind << std::endl; else - sprite = sprite_manager->load(str); + sprite = sprite_manager->create(str); - if(!sprite) - { + if(!sprite) { std::cerr << "Warning: Sprite '" << str << "' could not be loaded.\n"; - } + } } BadGuySpecs::BadGuySpecs(std::string& kind_) @@ -140,6 +141,7 @@ BadGuySpecs::BadGuySpecs(std::string& kind_) BadGuySpecs::~BadGuySpecs() { + delete sprite; } void diff --git a/src/bitmask.cpp b/src/bitmask.cpp index 65500903b..76983a0af 100644 --- a/src/bitmask.cpp +++ b/src/bitmask.cpp @@ -23,6 +23,8 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include + #include #include #include diff --git a/src/camera.cpp b/src/camera.cpp index 52481fc6f..458d7031f 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -17,6 +17,8 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include + #include #include #include @@ -68,7 +70,7 @@ Camera::read(LispReader& reader) if(cur == 0) { throw std::runtime_error("No path specified in autoscroll camera."); } - float speed = .5; + float speed = 50; while(!lisp_nil_p(cur)) { if(strcmp(lisp_symbol(lisp_car(lisp_car(cur))), "point") != 0) { std::cerr << "Warning: unknown token in camera path.\n"; @@ -134,7 +136,7 @@ Camera::reset(const Vector& tuxpos) } static const float EPSILON = .00001; -static const float max_speed_y = 1.4; +static const float max_speed_y = 140; void Camera::action(float elapsed_time) @@ -181,12 +183,13 @@ Camera::scroll_normal(float elapsed_time) if(do_y_scrolling) { // target_y is the high we target our scrolling at. This is not always the // high of the player, but if he is jumping upwards we should use the - // position where he last touched the ground. - float target_y; + // position where he last touched the ground. (this probably needs + // exceptions for trampolines and similar things in the future) + float target_y; if(player->fall_mode == Player::JUMPING) - target_y = player->last_ground_y + player->base.height; + target_y = player->last_ground_y + player->get_bbox().get_height(); else - target_y = player->base.y + player->base.height; + target_y = player->get_bbox().p2.y; // delta_y is the distance we'd have to travel to directly reach target_y float delta_y = translation.y - (target_y - screen->h/2); @@ -217,28 +220,29 @@ Camera::scroll_normal(float elapsed_time) || (player->dir == ::RIGHT && scrollchange == LEFT)) scrollchange = NONE; // when in left 1/3rd of screen scroll left - if(player->base.x < translation.x + screen->w/3 - 16 && do_backscrolling) + if(player->get_bbox().get_middle().x < translation.x + screen->w/3 - 16 + && do_backscrolling) scrollchange = LEFT; // scroll right when in right 1/3rd of screen - else if(player->base.x > translation.x + screen->w/3*2 + 16) + else if(player->get_bbox().get_middle().x > translation.x + screen->w/3*2+16) scrollchange = RIGHT; // calculate our scroll target depending on scroll mode float target_x; if(scrollchange == LEFT) - target_x = player->base.x - screen->w/3*2; + target_x = player->get_bbox().get_middle().x - screen->w/3*2; else if(scrollchange == RIGHT) - target_x = player->base.x - screen->w/3; + target_x = player->get_bbox().get_middle().x - screen->w/3; else target_x = translation.x; // that's the distance we would have to travel to reach target_x float delta_x = translation.x - target_x; // the speed we'd need to travel to reach target_x in this frame - float speed_x = 1.3 * delta_x / elapsed_time; + float speed_x = delta_x / elapsed_time; // limit our speed - float maxv = 1.3 * (1 + fabsf(player->physic.get_velocity_x() * 1.3)); + float maxv = 130 + (fabsf(player->physic.get_velocity_x() * 1.3)); if(speed_x > maxv) speed_x = maxv; else if(speed_x < -maxv) diff --git a/src/camera.h b/src/camera.h index bad7fdf2a..07656260d 100644 --- a/src/camera.h +++ b/src/camera.h @@ -56,9 +56,8 @@ public: virtual void action(float elapsed_time); - virtual void draw(DrawingContext& context) + virtual void draw(DrawingContext& ) { - UNUSED_ARG(context); } void set_scrolling(int scroll_x, int scroll_y) diff --git a/src/collision.cpp b/src/collision.cpp index 716c05aa5..7b93e8246 100644 --- a/src/collision.cpp +++ b/src/collision.cpp @@ -18,6 +18,8 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. +#include + #include #include "defines.h" #include "collision.h" @@ -27,12 +29,7 @@ #include "tilemap.h" #include "tile.h" -struct TileInfo -{ - Tile *tile; - int x, y; -} tileinfo; - +#if 0 bool rectcollision(const base_type& one, const base_type& two) { return (one.x >= two.x - one.width + 1 && @@ -49,6 +46,16 @@ bool rectcollision_offset(const base_type& one, const base_type& two, float off_ one.y <= two.y + two.height + off_y - 1); } +bool collision_object_map(const Rectangle& rect) +{ + base_type base; + base.x = rect.p1.x; + base.y = rect.p1.y; + base.width = rect.get_width(); + base.height = rect.get_height(); + return collision_object_map(base); +} + bool collision_object_map(const base_type& base) { const TileMap& tilemap = *Sector::current()->solids; @@ -59,18 +66,11 @@ bool collision_object_map(const base_type& base) int max_x = int(base.x + base.width); int max_y = int(base.y + base.height); - tileinfo.tile = NULL; - for(int x = starttilex; x*32 < max_x; ++x) { for(int y = starttiley; y*32 < max_y; ++y) { - Tile* tile = tilemap.get_tile(x, y); + const Tile* tile = tilemap.get_tile(x, y); if(tile && tile->attributes & Tile::SOLID) - { - tileinfo.tile = tile; - tileinfo.x = x*32; - tileinfo.y = y*32; return true; - } } } @@ -88,7 +88,7 @@ void* collision_func(const base_type& base, tiletestfunction function) for(int x = starttilex; x*32 < max_x; ++x) { for(int y = starttiley; y*32 < max_y; ++y) { - Tile* tile = tilemap.get_tile(x, y); + const Tile* tile = tilemap.get_tile(x, y); void* result = function(tile); if(result != 0) return result; @@ -98,16 +98,22 @@ void* collision_func(const base_type& base, tiletestfunction function) return 0; } -static void* test_goal_tile_function(Tile* tile) +static void* test_goal_tile_function(const Tile* tile) { if(tile && (tile->attributes & Tile::GOAL)) - return tile; + return const_cast ((const void*) tile); // evil cast... return 0; } -Tile* collision_goal(const base_type& base) +const Tile* collision_goal(const Rectangle& rect) { - return (Tile*) collision_func(base, test_goal_tile_function); + // too lazy to rewrite for now, so we transform to base_type... + base_type base; + base.x = rect.p1.x; + base.y = rect.p1.y; + base.width = rect.get_width(); + base.height = rect.get_height(); + return (const Tile*) collision_func(base, test_goal_tile_function); } void collision_swept_object_map(base_type* old, base_type* current) @@ -189,21 +195,6 @@ void collision_swept_object_map(base_type* old, base_type* current) if(collision_object_map(*old)) { - if(tileinfo.tile->slope_angle != 0) - { // in case this is a slope, set the right Y position - // left-right slope: - if(tileinfo.tile->slope_angle > 0 && tileinfo.tile->slope_angle < M_PI/2) - current->y = tileinfo.y - current->height + - (tileinfo.x - current->x)*tan(M_PI/2 - tileinfo.tile->slope_angle) - - 1; - // right-left slope: - if(tileinfo.tile->slope_angle > M_PI/2 && tileinfo.tile->slope_angle < M_PI) - current->y = tileinfo.y - current->height + - (current->x - tileinfo.x)*tan(M_PI - tileinfo.tile->slope_angle) - - 1; - } - else - { switch(h) { case 1: @@ -254,7 +245,6 @@ void collision_swept_object_map(base_type* old, base_type* current) } break; } - } } if((xd > 0 && current->x < orig_x) || (xd < 0 && current->x > orig_x)) @@ -265,7 +255,7 @@ void collision_swept_object_map(base_type* old, base_type* current) *old = *current; } -Tile* gettile(float x, float y) +const Tile* gettile(float x, float y) { const TileMap& tilemap = *Sector::current()->solids; return tilemap.get_tile_at(Vector(x, y)); @@ -273,40 +263,39 @@ Tile* gettile(float x, float y) bool issolid(float x, float y) { - Tile* tile = gettile(x,y); + const Tile* tile = gettile(x,y); return tile && (tile->attributes & Tile::SOLID); } bool isbrick(float x, float y) { - Tile* tile = gettile(x,y); + const Tile* tile = gettile(x,y); return tile && (tile->attributes & Tile::BRICK); } bool isice(float x, float y) { - Tile* tile = gettile(x,y); + const Tile* tile = gettile(x,y); return tile && (tile->attributes & Tile::ICE); } bool isspike(float x, float y) { - Tile* tile = gettile(x,y); + const Tile* tile = gettile(x,y); return tile && (tile->attributes & Tile::SPIKE); } bool isfullbox(float x, float y) { - Tile* tile = gettile(x,y); + const Tile* tile = gettile(x,y); return tile && (tile->attributes & Tile::FULLBOX); } bool iscoin(float x, float y) { - Tile* tile = gettile(x,y); + const Tile* tile = gettile(x,y); return tile && (tile->attributes & Tile::COIN); } -/* EOF */ - +#endif diff --git a/src/collision.h b/src/collision.h index 85b89d7bd..39d658b9e 100644 --- a/src/collision.h +++ b/src/collision.h @@ -21,36 +21,20 @@ #ifndef SUPERTUX_COLLISION_H #define SUPERTUX_COLLISION_H -#include "special/base.h" +#include "math/rectangle.h" using namespace SuperTux; -class Tile; - -/* Collision objects */ -enum -{ - CO_BULLET, - CO_BADGUY, - CO_PLAYER, - CO_TRAMPOLINE, - CO_FLYING_PLATFORM -}; - -enum CollisionType { - COLLISION_NORMAL, - COLLISION_BUMP, - COLLISION_SQUISH -}; - +#if 0 bool rectcollision(const base_type& one, const base_type& two); bool rectcollision_offset(const base_type& one, const base_type& two, float off_x, float off_y); void collision_swept_object_map(base_type* old, base_type* current); bool collision_object_map(const base_type& object); +bool collision_object_map(const Rectangle& rect); /** Return a pointer to the tile at the given x/y coordinates */ -Tile* gettile(float x, float y); +const Tile* gettile(float x, float y); // Some little helper function to check for tile properties bool issolid(float x, float y); @@ -59,14 +43,14 @@ bool isice(float x, float y); bool isspike(float x, float y); bool isfullbox(float x, float y); -typedef void* (*tiletestfunction)(Tile* tile); +typedef void* (*tiletestfunction)(const Tile* tile); /** invokes the function for each tile the baserectangle collides with. The * function aborts and returns true as soon as the tiletestfunction returns * != 0 then this value is returned. returns 0 if all tests failed. */ void* collision_func(const base_type& base, tiletestfunction* function); - -Tile* collision_goal(const base_type& base); +const Tile* collision_goal(const Rectangle& rect); +#endif #endif /*SUPERTUX_COLLISION_H*/ diff --git a/src/defines.h b/src/defines.h index 8d1e18459..f0b880c24 100644 --- a/src/defines.h +++ b/src/defines.h @@ -18,18 +18,11 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. - #ifndef SUPERTUX_DEFINES_H -#define SUPERTUX_DEFINES_H 1 +#define SUPERTUX_DEFINES_H #include -/* Version: */ - -#ifndef VERSION - #define VERSION "0.1.1" -#endif - enum Direction { LEFT = 0, RIGHT = 1 }; /* Direction (keyboard/joystick) states: */ @@ -46,23 +39,12 @@ enum DyingType { DYING_FALLING = 2 }; -/* Screen-related stuff */ -// +1 is needed because when tiles are wrapping around the screen there -// are two partial tiles on the screen -#define VISIBLE_TILES_X (25 +1) -#define VISIBLE_TILES_Y (19 +1) - /* Speed constraints: */ - -#define MAX_WALK_XM 2.3 -#define MAX_RUN_XM 3.2 -#define MAX_YM 20.0 -#define MAX_JUMP_TIME 375 +#define MAX_WALK_XM 230 +#define MAX_RUN_XM 320 #define MAX_LIVES 99 -#define WALK_SPEED 1.0 -#define RUN_SPEED 1.5 -#define JUMP_SPEED 1.2 +#define WALK_SPEED 100 /* gameplay related defines */ @@ -70,32 +52,13 @@ enum DyingType { #define MAX_FIRE_BULLETS 2 #define MAX_ICE_BULLETS 1 -#define FROZEN_TIME 3000 - -#define YM_FOR_JUMP 6.0 -#define WALK_ACCELERATION_X 0.03 -#define RUN_ACCELERATION_X 0.04 -#define KILL_BOUNCE_YM 8.0 - -#define SKID_XM 2.0 -#define SKID_TIME 200 - -/* Size constraints: */ - -#define X_OFFSCREEN_DISTANCE (screen->w/2) -#define Y_OFFSCREEN_DISTANCE (screen->h/2) - -/* Debugging */ +#define FROZEN_TIME 3.0 -#ifdef DEBUG - #define DEBUG_MSG( msg ) { \ - printf( msg ); printf("\n"); \ - } - #else - #define DEBUG_MSG( msg ) {} -#endif +#define WALK_ACCELERATION_X 300 +#define RUN_ACCELERATION_X 400 -#define UNUSED_ARG(a) do {/* null */} while (&a == 0) +#define SKID_XM 200 +#define SKID_TIME .3 #endif /*SUPERTUX_DEFINES_H*/ diff --git a/src/door.cpp b/src/door.cpp deleted file mode 100644 index 4feec95d5..000000000 --- a/src/door.cpp +++ /dev/null @@ -1,118 +0,0 @@ -// $Id$ -// -// SuperTux - A Jump'n Run -// Copyright (C) 2004 Matthias Braun h/2)), LAYER_TILES); - else - door->draw(context, Vector(area.x, area.y), LAYER_TILES); - - //Check if door animation is complete - //TODO: Move this out of the "draw" method as this is extremely dirty :) - if ((!animation_timer.check()) && (door_activated)) { - door_activated = false; - GameSession::current()->respawn(target_sector, target_spawnpoint); - } -} - -void -Door::interaction(InteractionType type) -{ - //Animate the door on activation - //TODO: Resetting the animation doesn't work correctly - // Tux and badguys should stop moving while the door is opening - if(type == INTERACTION_ACTIVATE) { - animation_timer.start(DOOR_OPENING_TIME); - door_activated = true; - } -} - diff --git a/src/door.h b/src/door.h deleted file mode 100644 index 50d013899..000000000 --- a/src/door.h +++ /dev/null @@ -1,62 +0,0 @@ -// $Id$ -// -// SuperTux - A Jump'n Run -// Copyright (C) 2004 Matthias Braun - -#include "video/surface.h" -#include "interactive_object.h" -#include "serializable.h" -#include "special/timer.h" - -namespace SuperTux { -class Sprite; -class LispReader; -} - -/** data images */ -#define DOOR_OPENING_TIME 1500 -#define DOOR_OPENING_FRAMES 8 -extern Sprite* door; -extern Surface* door_opening[DOOR_OPENING_FRAMES]; - -class Door : public InteractiveObject, public Serializable -{ -public: - Door(LispReader& reader); - Door(int x, int y); - virtual ~Door(); - - virtual void write(LispWriter& writer); - - virtual void action(float elapsed_time); - virtual void draw(DrawingContext& context); - virtual void interaction(InteractionType type); - -private: - std::string target_sector; - std::string target_spawnpoint; - Timer animation_timer; //Used for door animation - bool door_activated; -}; - -#endif /*SUPERTUX_DOOR_H*/ - diff --git a/src/gameloop.cpp b/src/gameloop.cpp index d05379f9d..850000196 100644 --- a/src/gameloop.cpp +++ b/src/gameloop.cpp @@ -19,6 +19,8 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include + #include #include #include @@ -46,7 +48,6 @@ #include "gui/menu.h" #include "badguy.h" #include "sector.h" -#include "special.h" #include "player.h" #include "level.h" #include "scene.h" @@ -62,23 +63,26 @@ #include "misc.h" #include "camera.h" #include "statistics.h" +#include "timer.h" +#include "object/fireworks.h" GameSession* GameSession::current_ = 0; bool compare_last(std::string& haystack, std::string needle) { -int haystack_size = haystack.size(); -int needle_size = needle.size(); + int haystack_size = haystack.size(); + int needle_size = needle.size(); -if(haystack_size < needle_size) - return false; + if(haystack_size < needle_size) + return false; -if(haystack.compare(haystack_size-needle_size, needle_size, needle) == 0) - return true; -return false; + if(haystack.compare(haystack_size-needle_size, needle_size, needle) == 0) + return true; + return false; } -GameSession::GameSession(const std::string& levelname_, int mode, bool flip_level_, Statistics* statistics) +GameSession::GameSession(const std::string& levelname_, int mode, + bool flip_level_, Statistics* statistics) : level(0), currentsector(0), st_gl_mode(mode), end_sequence(NO_ENDSEQUENCE), levelname(levelname_), flip_level(flip_level_), best_level_statistics(statistics) @@ -89,11 +93,6 @@ GameSession::GameSession(const std::string& levelname_, int mode, bool flip_leve game_pause = false; fps_fps = 0; - fps_timer.init(true); - frame_timer.init(true); - random_timer.init(true); - frame_rate.set_fps(100); - context = new DrawingContext(); if(flip_levels_mode) @@ -112,17 +111,16 @@ GameSession::restart_level() exit_status = ES_NONE; end_sequence = NO_ENDSEQUENCE; - fps_timer.init(true); - frame_timer.init(true); - random_timer.init(true); - last_keys.clear(); +#if 0 Vector tux_pos = Vector(-1,-1); if (currentsector) - { // Tux has lost a life, so we try to respawn him at the nearest reset point + { + // Tux has lost a life, so we try to respawn him at the nearest reset point tux_pos = currentsector->player->base; } +#endif delete level; currentsector = 0; @@ -135,13 +133,14 @@ GameSession::restart_level() global_stats.reset(); global_stats.set_total_points(COINS_COLLECTED_STAT, level->get_total_coins()); global_stats.set_total_points(BADGUYS_KILLED_STAT, level->get_total_badguys()); - global_stats.set_total_points(TIME_NEEDED_STAT, level->time_left); + global_stats.set_total_points(TIME_NEEDED_STAT, level->timelimit); currentsector = level->get_sector("main"); if(!currentsector) Termination::abort("Level has no main sector.", ""); currentsector->activate("main"); +#if 0 // Set Tux to the nearest reset point if(tux_pos.x != -1) { @@ -163,6 +162,7 @@ GameSession::restart_level() currentsector->camera->reset(Vector(currentsector->player->base.x, currentsector->player->base.y)); } +#endif if (st_gl_mode != ST_GL_DEMO_GAME) { @@ -170,7 +170,6 @@ GameSession::restart_level() levelintro(); } - time_left.init(true); start_timers(); currentsector->play_music(LEVEL_MUSIC); } @@ -189,7 +188,8 @@ GameSession::levelintro(void) char str[60]; DrawingContext context; - currentsector->background->draw(context); + if(currentsector->background) + currentsector->background->draw(context); // context.draw_text(gold_text, level->get_name(), Vector(screen->w/2, 160), // CENTER_ALLIGN, LAYER_FOREGROUND1); @@ -224,9 +224,8 @@ GameSession::levelintro(void) void GameSession::start_timers() { - time_left.start(level->time_left*1000); + time_left.start(level->timelimit); Ticks::pause_init(); - frame_rate.start(); } void @@ -272,12 +271,12 @@ GameSession::process_events() tux.input.right = DOWN; tux.input.down = UP; - if (int(last_x_pos) == int(tux.base.x)) + if (int(last_x_pos) == int(tux.get_pos().x)) tux.input.up = DOWN; else tux.input.up = UP; - last_x_pos = tux.base.x; + last_x_pos = tux.get_pos().x; SDL_Event event; while (SDL_PollEvent(&event)) @@ -373,7 +372,7 @@ GameSession::process_events() { char buf[160]; snprintf(buf, sizeof(buf), "P: %4.1f,%4.1f", - tux.base.x, tux.base.y); + tux.get_pos().x, tux.get_pos().y); context->draw_text(white_text, buf, Vector(0, screen->h - white_text->get_height()), LEFT_ALLIGN, LAYER_FOREGROUND1); @@ -451,7 +450,7 @@ GameSession::process_events() } if(compare_last(last_keys, "invincible")) { // be invincle for the rest of the level - tux.invincible_timer.start(time_left.get_left()); + tux.invincible_timer.start(10000); last_keys.clear(); } if(compare_last(last_keys, "shrink")) @@ -472,9 +471,12 @@ GameSession::process_events() } if(compare_last(last_keys, "gotoend")) { // goes to the end of the level - tux.base.x = (currentsector->solids->get_width()*32) - (screen->w*2); - tux.base.y = 0; - currentsector->camera->reset(Vector(tux.base.x, tux.base.y)); + tux.move(Vector( + (currentsector->solids->get_width()*32) + - (screen->w*2), + 0)); + currentsector->camera->reset( + Vector(tux.get_pos().x, tux.get_pos().y)); last_keys.clear(); } // temporary to help player's choosing a flapping @@ -584,55 +586,31 @@ GameSession::check_end_conditions() Player* tux = currentsector->player; /* End of level? */ - Tile* endtile = collision_goal(tux->base); - - if(end_sequence && !endsequence_timer.check()) - { + if(end_sequence && endsequence_timer.check()) { exit_status = ES_LEVEL_FINISHED; global_stats += last_swap_stats; // add swap points stats return; - } - else if(end_sequence == ENDSEQUENCE_RUNNING && endtile && endtile->data >= 1) - { - end_sequence = ENDSEQUENCE_WAITING; - } - else if(!end_sequence && endtile && endtile->data == 0) - { - end_sequence = ENDSEQUENCE_RUNNING; - endsequence_timer.start(7000); // 5 seconds until we finish the map - last_x_pos = -1; - SoundManager::get()->play_music(level_end_song, 0); - tux->invincible_timer.start(7000); //FIXME: Implement a winning timer for the end sequence (with special winning animation etc.) + } else if (!end_sequence && tux->is_dead()) { + player_status.bonus = PlayerStatus::NO_BONUS; - // add left time to stats - global_stats.set_points(TIME_NEEDED_STAT, time_left.get_gone() / 1000); - - random_timer.start(200); // start 1st firework - } - else if (!end_sequence && tux->is_dead()) - { - player_status.bonus = PlayerStatus::NO_BONUS; - - if (player_status.lives < 0) - { // No more lives!? - exit_status = ES_GAME_OVER; - } - else - { // Still has lives, so reset Tux to the levelstart - restart_level(); - } - - return; + if (player_status.lives < 0) { // No more lives!? + exit_status = ES_GAME_OVER; + } else { // Still has lives, so reset Tux to the levelstart + restart_level(); } + + return; + } } void -GameSession::action(double frame_ratio) +GameSession::action(float elapsed_time) { + // advance timers if (exit_status == ES_NONE && !currentsector->player->growing_timer.check()) { // Update Tux and the World - currentsector->action(frame_ratio); + currentsector->action(elapsed_time); } // respawning in new sector? @@ -643,24 +621,6 @@ GameSession::action(double frame_ratio) currentsector->play_music(LEVEL_MUSIC); newsector = newspawnpoint = ""; } - - // on end sequence make a few fireworks - if(end_sequence == ENDSEQUENCE_RUNNING && !random_timer.check() && - currentsector->end_sequence_animation() == FIREWORKS_ENDSEQ_ANIM) - { - Vector epicenter = currentsector->camera->get_translation(); - epicenter.x += screen->w * ((float)rand() / RAND_MAX); - epicenter.y += (screen->h/2) * ((float)rand() / RAND_MAX); - - int red = rand() % 255; // calculate firework color - int green = rand() % red; - currentsector->add_particles(epicenter, 0, 360, Vector(1.4,1.4), - Vector(0,0), 45, Color(red,green,0), 3, 1300, - LAYER_FOREGROUND1+1); - - SoundManager::get()->play_sound(IDToSound(SND_FIREWORKS)); - random_timer.start(rand() % 400 + 600); // next firework - } } void @@ -749,94 +709,99 @@ GameSession::run() int fps_cnt = 0; - frame_rate.start(); - // Eat unneeded events SDL_Event event; - while (SDL_PollEvent(&event)) {} + while(SDL_PollEvent(&event)) + {} draw(); - while (exit_status == ES_NONE) - { - /* Calculate the movement-factor */ - double frame_ratio = frame_rate.get(); - - if(!frame_timer.check()) - { - frame_timer.start(25); - ++global_frame_counter; - } - - /* Handle events: */ - currentsector->player->input.old_fire - = currentsector->player->input.fire; - - process_events(); - process_menu(); - - // Update the world state and all objects in the world - // Do that with a constante time-delta so that the game will run - // determistic and not different on different machines - if(!game_pause && !Menu::current()) - { - // Update the world - check_end_conditions(); - if (end_sequence == ENDSEQUENCE_RUNNING) - action(frame_ratio/2); - else if(end_sequence == NO_ENDSEQUENCE) - action(frame_ratio); - } - else - { - ++pause_menu_frame; - SDL_Delay(50); - } + Uint32 lastticks = SDL_GetTicks(); + fps_ticks = SDL_GetTicks(); + + frame_timer.start(.025, true); + while (exit_status == ES_NONE) { + Uint32 ticks = SDL_GetTicks(); + float elapsed_time = float(ticks - lastticks) / 1000.; + global_time += elapsed_time; + lastticks = ticks; + // 40fps is minimum + if(elapsed_time > .05) + elapsed_time = .05; + + if(frame_timer.check()) { + ++global_frame_counter; + } - draw(); + /* Handle events: */ + currentsector->player->input.old_fire = currentsector->player->input.fire; + currentsector->player->input.old_up = currentsector->player->input.old_up; - /* Time stops in pause mode */ - if(game_pause || Menu::current()) - { - continue; - } + process_events(); + process_menu(); - frame_rate.update(); + // Update the world state and all objects in the world + // Do that with a constante time-delta so that the game will run + // determistic and not different on different machines + if(!game_pause && !Menu::current()) + { + // Update the world + check_end_conditions(); + if (end_sequence == ENDSEQUENCE_RUNNING) + action(elapsed_time/2); + else if(end_sequence == NO_ENDSEQUENCE) + action(elapsed_time); + } + else + { + ++pause_menu_frame; + SDL_Delay(50); + } - /* Handle time: */ - if (!time_left.check() && currentsector->player->dying == DYING_NOT - && !end_sequence) - currentsector->player->kill(Player::KILL); + draw(); - /* Handle music: */ - if(currentsector->player->invincible_timer.check() && !end_sequence) - { - currentsector->play_music(HERRING_MUSIC); - } - /* are we low on time ? */ - else if (time_left.get_left() < TIME_WARNING && !end_sequence) - { - currentsector->play_music(HURRYUP_MUSIC); - } - /* or just normal music? */ - else if(currentsector->get_music_type() != LEVEL_MUSIC && !end_sequence) - { - currentsector->play_music(LEVEL_MUSIC); - } + /* Time stops in pause mode */ + if(game_pause || Menu::current()) + { + continue; + } - /* Calculate frames per second */ - if(show_fps) - { - ++fps_cnt; - fps_fps = (1000.0 / (float)fps_timer.get_gone()) * (float)fps_cnt; + //frame_rate.update(); + + /* Handle time: */ + if (time_left.check() && currentsector->player->dying == DYING_NOT + && !end_sequence) + currentsector->player->kill(Player::KILL); + + /* Handle music: */ + if(currentsector->player->invincible_timer.check() && !end_sequence) + { + currentsector->play_music(HERRING_MUSIC); + } + /* are we low on time ? */ + else if (time_left.get_timeleft() < TIME_WARNING && !end_sequence) + { + currentsector->play_music(HURRYUP_MUSIC); + } + /* or just normal music? */ + else if(currentsector->get_music_type() != LEVEL_MUSIC && !end_sequence) + { + currentsector->play_music(LEVEL_MUSIC); + } - if(!fps_timer.check()) - { - fps_timer.start(1000); - fps_cnt = 0; - } - } + /* Calculate frames per second */ + if(show_fps) + { + ++fps_cnt; + + if(SDL_GetTicks() - fps_ticks >= 500) + { + fps_fps = (float) fps_cnt / .5; + fps_cnt = 0; + fps_ticks = SDL_GetTicks(); + } } + } return exit_status; } @@ -848,13 +813,29 @@ GameSession::respawn(const std::string& sector, const std::string& spawnpoint) newspawnpoint = spawnpoint; } -/* Bounce a brick: */ -void bumpbrick(float x, float y) +void +GameSession::start_sequence(const std::string& sequencename) { - Sector::current()->add_bouncy_brick(Vector(((int)(x + 1) / 32) * 32, - (int)(y / 32) * 32)); - - SoundManager::get()->play_sound(IDToSound(SND_BRICK), Vector(x, y), Sector::current()->player->get_pos()); + if(sequencename == "endsequence") { + if(end_sequence) + return; + + end_sequence = ENDSEQUENCE_RUNNING; + endsequence_timer.start(7.0); // 7 seconds until we finish the map + last_x_pos = -1; + SoundManager::get()->play_music(level_end_song, 0); + currentsector->player->invincible_timer.start(7.0); + + // add left time to stats + global_stats.set_points(TIME_NEEDED_STAT, + int(time_left.get_period() - time_left.get_timeleft())); + + if(level->get_end_sequence_type() == Level::FIREWORKS_ENDSEQ_ANIM) { + currentsector->add_object(new Fireworks()); + } + } else { + std::cout << "Unknown sequence '" << sequencename << "'.\n"; + } } /* (Status): */ @@ -873,11 +854,12 @@ GameSession::drawstatus(DrawingContext& context) LEFT_ALLIGN, LAYER_FOREGROUND1); } - if(!time_left.check()) { + if(time_left.check()) { context.draw_text(white_text, _("TIME's UP"), Vector(screen->w/2, 0), CENTER_ALLIGN, LAYER_FOREGROUND1); - } else if (time_left.get_left() > TIME_WARNING || (global_frame_counter % 10) < 5) { - sprintf(str, " %d", time_left.get_left() / 1000 ); + } else if (time_left.get_timeleft() > TIME_WARNING + || (global_frame_counter % 10) < 5) { + sprintf(str, " %d", int(time_left.get_timeleft())); context.draw_text(white_text, _("TIME"), Vector(screen->w/2, 0), CENTER_ALLIGN, LAYER_FOREGROUND1); context.draw_text(gold_text, str, diff --git a/src/gameloop.h b/src/gameloop.h index d98ff54f4..a5263d86f 100644 --- a/src/gameloop.h +++ b/src/gameloop.h @@ -22,9 +22,7 @@ #ifndef SUPERTUX_GAMELOOP_H #define SUPERTUX_GAMELOOP_H -#include "special/timer.h" -#include "special/base.h" -#include "special/frame_rate.h" +#include "timer.h" #include "statistics.h" using namespace SuperTux; @@ -58,16 +56,15 @@ class DrawingContext; class GameSession { private: - Timer fps_timer; - Timer frame_timer; - Timer endsequence_timer; + Uint32 fps_ticks; + Timer2 frame_timer; + Timer2 endsequence_timer; Level* level; Sector* currentsector; int st_gl_mode; int levelnb; float fps_fps; - FrameRate frame_rate; int pause_menu_frame; /** If true the end_sequence will be played, user input will be @@ -95,7 +92,7 @@ private: ExitStatus exit_status; public: DrawingContext* context; - Timer time_left; + Timer2 time_left; GameSession(const std::string& level, int mode, bool flip_level_ = false, Statistics* statistics = NULL); ~GameSession(); @@ -104,7 +101,7 @@ public: ExitStatus run(); void draw(); - void action(double frame_ratio); + void action(float frame_ratio); void set_current() { current_ = this; } @@ -114,14 +111,14 @@ public: const std::string& spawnpointname); Sector* get_current_sector() { return currentsector; } + + void start_sequence(const std::string& sequencename); private: static GameSession* current_; // for cheating std::string last_keys; - // for fire works - Timer random_timer; // swap points Vector last_swap_point; @@ -146,7 +143,6 @@ private: std::string slotinfo(int slot); -bool rectcollision(base_type* one, base_type* two); void bumpbrick(float x, float y); /** Return true if the gameloop() was entered, false otherwise */ diff --git a/src/gameobjs.cpp b/src/gameobjs.cpp index ce71deede..6e7b552ac 100644 --- a/src/gameobjs.cpp +++ b/src/gameobjs.cpp @@ -18,6 +18,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. +#include #include #include @@ -35,33 +36,46 @@ #include "video/drawing_context.h" #include "camera.h" -BouncyDistro::BouncyDistro(const Vector& pos) +BouncyCoin::BouncyCoin(const Vector& pos) : position(pos) { - ym = -2; + timer.start(.3); + sprite = sprite_manager->create("coin"); + sprite->set_action("still"); +} + +BouncyCoin::~BouncyCoin() +{ + delete sprite; } void -BouncyDistro::action(float elapsed_time) +BouncyCoin::action(float elapsed_time) { - position.y += ym * elapsed_time; + position.y += -200 * elapsed_time; - ym += 0.1 * elapsed_time; // not framerate independent... but who really cares - if(ym >= 0) + if(timer.check()) remove_me(); } void -BouncyDistro::draw(DrawingContext& context) +BouncyCoin::draw(DrawingContext& context) { - context.draw_surface(img_distro[0], position, LAYER_OBJECTS); + sprite->draw(context, position, LAYER_OBJECTS); } +//--------------------------------------------------------------------------- + +BrokenBrick::BrokenBrick(Sprite* nsprite, + const Vector& pos, const Vector& nmovement) + : sprite(new Sprite(*nsprite)), position(pos), movement(nmovement) +{ + timer.start(.2); +} -BrokenBrick::BrokenBrick(Tile* ntile,const Vector& pos, const Vector& nmovement) - : tile(ntile), position(pos), movement(nmovement) +BrokenBrick::~BrokenBrick() { - timer.start(200); + delete sprite; } void @@ -69,62 +83,31 @@ BrokenBrick::action(float elapsed_time) { position += movement * elapsed_time; - if (!timer.check()) + if (timer.check()) remove_me(); } void BrokenBrick::draw(DrawingContext& context) { - if (tile->images.size() > 0) - context.draw_surface_part(tile->images[0], - Vector(rand() % 16, rand() % 16), - Vector(16, 16), - position, LAYER_OBJECTS + 1); -} - -BouncyBrick::BouncyBrick(const Vector& pos) - : position(pos), offset(0), offset_m(-BOUNCY_BRICK_SPEED), - shape(Sector::current()->solids->get_tile_id_at(pos)) -{ - shape.hidden = true; + sprite->draw_part(context, + Vector(rand() % 16, rand() % 16), Vector(16, 16), + position, LAYER_OBJECTS + 1); } -void -BouncyBrick::action(float elapsed_time) -{ - offset += offset_m * elapsed_time; - - /* Go back down? */ - if (offset < -BOUNCY_BRICK_MAX_OFFSET) - offset_m = BOUNCY_BRICK_SPEED; - - /* Stop bouncing? */ - if (offset >= 0) - { - shape.hidden = false; - remove_me(); - } -} - -void -BouncyBrick::draw(DrawingContext& context) -{ - TileManager::instance()-> - draw_tile(context, shape.id, position + Vector(0, offset), LAYER_TILES+1); -} +//--------------------------------------------------------------------------- FloatingText::FloatingText(const Vector& pos, const std::string& text_) : position(pos), text(text_) { - timer.start(1000); + timer.start(.1); position.x -= text.size() * 8; } FloatingText::FloatingText(const Vector& pos, int score) : position(pos) { - timer.start(1000); + timer.start(.1); // turn int into a string char str[10]; @@ -139,19 +122,19 @@ FloatingText::action(float elapsed_time) { position.y -= 1.4 * elapsed_time; - if(!timer.check()) + if(timer.check()) remove_me(); } -#define FADING_TIME 350 +#define FADING_TIME .350 void FloatingText::draw(DrawingContext& context) { // make an alpha animation when disapearing int alpha; - if(timer.get_left() < FADING_TIME) - alpha = timer.get_left() * 255 / FADING_TIME; + if(timer.get_timeleft() < FADING_TIME) + alpha = int(timer.get_timeleft() * 255 / FADING_TIME); else alpha = 255; @@ -165,6 +148,7 @@ FloatingText::draw(DrawingContext& context) /* Trampoline */ +#if 0 Sprite *img_trampoline; Trampoline::Trampoline(LispReader& reader) @@ -313,9 +297,11 @@ Trampoline::collision(void *p_c_object, int c_object, CollisionType type) } } +#endif /* Flying Platform */ +#if 0 Sprite *img_flying_platform; FlyingPlatform::FlyingPlatform(LispReader& reader) @@ -441,21 +427,22 @@ FlyingPlatform::collision(void *p_c_object, int c_object, CollisionType type) } } +#endif -Sprite *img_smoke_cloud; +Sprite *img_smoke_cloud = 0; SmokeCloud::SmokeCloud(const Vector& pos) : position(pos) { - timer.start(300); + timer.start(.3); } void SmokeCloud::action(float elapsed_time) { - position.y -= 1.2 * elapsed_time; + position.y -= 120 * elapsed_time; - if(!timer.check()) + if(timer.check()) remove_me(); } @@ -468,15 +455,12 @@ SmokeCloud::draw(DrawingContext& context) Particles::Particles(const Vector& epicenter, int min_angle, int max_angle, const Vector& initial_velocity, const Vector& acceleration, int number, Color color_, int size_, int life_time, int drawing_layer_) : accel(acceleration), color(color_), size(size_), drawing_layer(drawing_layer_) { - if(life_time == 0) - { + if(life_time == 0) { live_forever = true; - } - else - { + } else { live_forever = false; timer.start(life_time); - } + } // create particles for(int p = 0; p < number; p++) @@ -511,8 +495,8 @@ Particles::action(float elapsed_time) Vector camera = Sector::current()->camera->get_translation(); // update particles - for(std::vector::iterator i = particles.begin(); i < particles.end(); i++) - { + for(std::vector::iterator i = particles.begin(); + i != particles.end(); ) { (*i)->pos.x += (*i)->vel.x * elapsed_time; (*i)->pos.y += (*i)->vel.y * elapsed_time; @@ -520,14 +504,15 @@ Particles::action(float elapsed_time) (*i)->vel.y += accel.y * elapsed_time; if((*i)->pos.x < camera.x || (*i)->pos.x > screen->w + camera.x || - (*i)->pos.y < camera.y || (*i)->pos.y > screen->h + camera.y) - { + (*i)->pos.y < camera.y || (*i)->pos.y > screen->h + camera.y) { delete (*i); - particles.erase(i); - } + i = particles.erase(i); + } else { + ++i; } + } - if((!timer.check() && !live_forever) || particles.size() == 0) + if((timer.check() && !live_forever) || particles.size() == 0) remove_me(); } @@ -535,16 +520,24 @@ void Particles::draw(DrawingContext& context) { // draw particles - for(std::vector::iterator i = particles.begin(); i < particles.end(); i++) - { - context.draw_filled_rect((*i)->pos, Vector(size,size), color, drawing_layer); - } + for(std::vector::iterator i = particles.begin(); + i != particles.end(); i++) { + context.draw_filled_rect((*i)->pos, Vector(size,size), color,drawing_layer); + } } void load_object_gfx() { +#if 0 img_trampoline = sprite_manager->load("trampoline"); img_trampoline->start_animation(0); img_flying_platform = sprite_manager->load("flying_platform"); - img_smoke_cloud = sprite_manager->load("stomp"); +#endif + img_smoke_cloud = sprite_manager->create("stomp"); } + +void free_object_gfx() +{ + delete img_smoke_cloud; +} + diff --git a/src/gameobjs.h b/src/gameobjs.h index 0831dc7bb..bb4168f64 100644 --- a/src/gameobjs.h +++ b/src/gameobjs.h @@ -22,9 +22,8 @@ #ifndef SUPERTUX_GAMEOBJS_H #define SUPERTUX_GAMEOBJS_H -#include "special/base.h" #include "video/surface.h" -#include "special/timer.h" +#include "timer.h" #include "scene.h" #include "math/physic.h" #include "collision.h" @@ -41,56 +40,36 @@ namespace SuperTux { class Sprite; } -struct TileId; - -class BouncyDistro : public GameObject +class BouncyCoin : public GameObject { public: - BouncyDistro(const Vector& pos); + BouncyCoin(const Vector& pos); + ~BouncyCoin(); virtual void action(float elapsed_time); virtual void draw(DrawingContext& context); private: + Sprite* sprite; Vector position; - float ym; + Timer2 timer; }; -extern Surface* img_distro[4]; - -#define BOUNCY_BRICK_MAX_OFFSET 8 -#define BOUNCY_BRICK_SPEED 0.9 - -class Tile; - class BrokenBrick : public GameObject { public: - BrokenBrick(Tile* tile, const Vector& pos, const Vector& movement); + BrokenBrick(Sprite* sprite, const Vector& pos, const Vector& movement); + ~BrokenBrick(); virtual void action(float elapsed_time); virtual void draw(DrawingContext& context); private: - Timer timer; - Tile* tile; + Timer2 timer; + Sprite* sprite; Vector position; Vector movement; }; -class BouncyBrick : public GameObject -{ -public: - BouncyBrick(const Vector& pos); - virtual void action(float elapsed_time); - virtual void draw(DrawingContext& context); - -private: - Vector position; - float offset; - float offset_m; - TileId& shape; -}; - class FloatingText : public GameObject { public: @@ -103,9 +82,10 @@ public: private: Vector position; std::string text; - Timer timer; + Timer2 timer; }; +#if 0 extern Sprite *img_trampoline; class Trampoline : public MovingObject, public Serializable @@ -128,39 +108,7 @@ public: float power; unsigned int frame; }; - -extern Sprite *img_flying_platform; - -class FlyingPlatform : public MovingObject, public Serializable -{ -public: - FlyingPlatform(LispReader& reader); - FlyingPlatform(int x, int y); - - virtual void write(LispWriter& writer); - virtual void action(float frame_ratio); - virtual void draw(DrawingContext& context); - - virtual void collision(const MovingObject& other, int); - void collision(void *p_c_object, int c_object, CollisionType type); - - float get_vel_x() { return vel_x; } - float get_vel_y() { return vel_y; } - - Physic physic; - enum { M_NORMAL, M_HELD } mode; - - private: - std::vector pos_x; - std::vector pos_y; - float velocity; - - float vel_x, vel_y; // calculated based in the velocity - - int point; - bool move; - unsigned int frame; -}; +#endif extern Sprite *img_smoke_cloud; @@ -173,7 +121,7 @@ public: virtual void draw(DrawingContext& context); private: - Timer timer; + Timer2 timer; Vector position; }; @@ -190,7 +138,7 @@ public: private: Vector accel; - Timer timer; + Timer2 timer; bool live_forever; Color color; @@ -205,6 +153,7 @@ private: }; void load_object_gfx(); +void free_object_gfx(); #endif diff --git a/src/high_scores.cpp b/src/high_scores.cpp index 674e8dfbc..86b1eb699 100644 --- a/src/high_scores.cpp +++ b/src/high_scores.cpp @@ -20,6 +20,8 @@ /* Open the highscore file: */ +#include + #include #include diff --git a/src/interactive_object.cpp b/src/interactive_object.cpp deleted file mode 100644 index ad8636c18..000000000 --- a/src/interactive_object.cpp +++ /dev/null @@ -1,29 +0,0 @@ -// $Id$ -// -// SuperTux - A Jump'n Run -// Copyright (C) 2004 Matthias Braun #include "intro.h" #include "app/globals.h" diff --git a/src/level.cpp b/src/level.cpp index 5ad193c33..fd954a707 100644 --- a/src/level.cpp +++ b/src/level.cpp @@ -18,6 +18,8 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. +#include + #include #include #include @@ -44,8 +46,8 @@ using namespace std; Level::Level() - : name("noname"), author("mr. x"), time_left(500) - + : name("noname"), author("mr. x"), timelimit(500), + end_sequence_type(NONE_ENDSEQ_ANIM) { } @@ -90,16 +92,28 @@ Level::load(const std::string& filename) lisp_object_t* data = lisp_car(lisp_cdr(lisp_car(cur))); LispReader reader(lisp_cdr(lisp_car(cur))); - if(token == "name") { + if(token == "version") { + if(lisp_integer(data) > 2) { + std::cerr << "Warning: level format newer than application.\n"; + } + } else if(token == "name") { name = lisp_string(data); } else if(token == "author") { author = lisp_string(data); } else if(token == "time") { - time_left = lisp_integer(data); + timelimit = lisp_integer(data); } else if(token == "sector") { Sector* sector = new Sector; sector->parse(reader); add_sector(sector); + } else if(token == "end-sequence-animation") { + std::string endsequencename = lisp_string(data); + if(endsequencename == "fireworks") { + end_sequence_type = FIREWORKS_ENDSEQ_ANIM; + } else { + std::cout << "Unknown endsequence type: '" << endsequencename << + "'.\n"; + } } else { std::cerr << "Unknown token '" << token << "' in level file.\n"; continue; @@ -114,7 +128,7 @@ Level::load_old_format(LispReader& reader) { reader.read_string("name", name, true); reader.read_string("author", author); - reader.read_int("time", time_left); + reader.read_int("time", timelimit); Sector* sector = new Sector; sector->parse_old_format(reader); @@ -140,14 +154,15 @@ Level::save(const std::string& filename) writer->write_string("name", name); writer->write_string("author", author); - writer->write_int("time", time_left); + writer->write_int("time", timelimit); + writer->write_string("end-sequence-animation", + end_sequence_type == FIREWORKS_ENDSEQ_ANIM ? "fireworks" : "none"); - for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i) - { + for(Sectors::iterator i = sectors.begin(); i != sectors.end(); ++i) { writer->start_list("sector"); i->second->write(*writer); writer->end_list("sector"); - } + } writer->end_list("supertux-level"); diff --git a/src/level.h b/src/level.h index 0f81e910d..cc280b5e3 100644 --- a/src/level.h +++ b/src/level.h @@ -35,11 +35,17 @@ class LispReader; class Level { public: + enum EndSequenceType{ + NONE_ENDSEQ_ANIM, + FIREWORKS_ENDSEQ_ANIM + }; + std::string name; std::string author; - int time_left; + int timelimit; typedef std::map Sectors; Sectors sectors; + EndSequenceType end_sequence_type; public: Level(); @@ -49,6 +55,9 @@ public: void save(const std::string& filename); static void create(const std::string& filename); + EndSequenceType get_end_sequence_type() const + { return end_sequence_type; } + const std::string& get_name() const { return name; } diff --git a/src/level_subset.cpp b/src/level_subset.cpp index 4b3378db7..0a67f1daf 100644 --- a/src/level_subset.cpp +++ b/src/level_subset.cpp @@ -18,6 +18,8 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. +#include + #include #include #include "app/setup.h" diff --git a/src/leveleditor.cpp b/src/leveleditor.cpp index 065b8c78a..f17fbe1b5 100644 --- a/src/leveleditor.cpp +++ b/src/leveleditor.cpp @@ -15,6 +15,8 @@ * * ***************************************************************************/ +#include + #include #include @@ -36,128 +38,129 @@ #include "gameloop.h" #include "badguy.h" #include "gameobjs.h" -#include "door.h" #include "camera.h" LevelEditor::LevelEditor() { -show_grid = true; - -selection.clear(); -global_frame_counter = 0; -frame_timer.init(true); -level_name_timer.init(true); -selection_end = selection_ini = Vector(0,0); -left_button = middle_button = mouse_moved = false; -level = 0; -level_subset = 0; - -cur_layer = LAYER_TILES; -level_changed = false; - -sector = 0; -zoom = 1.0; - -/* Creating menus */ -level_subsets = FileSystem::dsubdirs("/levels", "info"); -subset_menu = new Menu(); -subset_menu->additem(MN_LABEL,_("Load Subset"),0,0); -subset_menu->additem(MN_HL,"",0,0); -int i = 0; -for(std::set::iterator it = level_subsets.begin(); it != level_subsets.end(); ++it, ++i) - subset_menu->additem(MN_ACTION, (*it),0,0,i); -subset_menu->additem(MN_HL,"",0,0); -subset_menu->additem(MN_BACK,_("Back"),0,0); - -create_subset_menu = new Menu(); -create_subset_menu->additem(MN_LABEL,_("New Level Subset"),0,0); -create_subset_menu->additem(MN_HL,"",0,0); -create_subset_menu->additem(MN_TEXTFIELD,_("Filename "),0,0,MN_ID_FILENAME_SUBSET); -create_subset_menu->additem(MN_TEXTFIELD,_("Title "),0,0,MN_ID_TITLE_SUBSET); -create_subset_menu->additem(MN_TEXTFIELD,_("Description"),0,0,MN_ID_DESCRIPTION_SUBSET); -create_subset_menu->additem(MN_ACTION,_("Create"),0,0, MN_ID_CREATE_SUBSET); -create_subset_menu->additem(MN_HL,"",0,0); -create_subset_menu->additem(MN_BACK,_("Back"),0,0); - -main_menu = new Menu(); -main_menu->additem(MN_LABEL,_("Level Editor Menu"),0,0); -main_menu->additem(MN_HL,"",0,0); -main_menu->additem(MN_ACTION,_("Return to Level Editor"),0,0,MN_ID_RETURN); -main_menu->additem(MN_GOTO,_("Create Level Subset"),0,create_subset_menu); -main_menu->additem(MN_GOTO,_("Load Level Subset"),0,subset_menu); -main_menu->additem(MN_HL,"",0,0); -main_menu->additem(MN_ACTION,_("Quit Level Editor"),0,0,MN_ID_QUIT); - -settings_menu = new Menu(); -settings_menu->additem(MN_LABEL,_("Level Settings"),0,0); -settings_menu->additem(MN_HL,"",0,0); -settings_menu->additem(MN_TEXTFIELD,_("Name "),0,0,MN_ID_NAME); -settings_menu->additem(MN_TEXTFIELD,_("Author "),0,0,MN_ID_AUTHOR); -settings_menu->additem(MN_NUMFIELD, _("Width "),0,0,MN_ID_WIDTH); -settings_menu->additem(MN_NUMFIELD, _("Height "),0,0,MN_ID_HEIGHT); -settings_menu->additem(MN_HL,"",0,0); -settings_menu->additem(MN_ACTION,_("Apply"),0,0,MN_ID_APPLY_SETTINGS); - -/* Creating button groups */ -load_buttons_gfx(); - -tiles_board = new ButtonGroup(Vector(screen->w - 140, 100), - Vector(32,32), Vector(4,8)); - -TileManager* tilemanager = TileManager::instance(); - -tiles_board->add_button(Button(img_rubber_bt, _("Eraser"), SDLKey(SDLK_DELETE)), 0); -for(unsigned int id = 1; id < tilemanager->total_ids(); id++) - { - Tile* tile = tilemanager->get(id); - if(!tile) - continue; + show_grid = true; + + selection.clear(); + global_frame_counter = 0; + selection_end = selection_ini = Vector(0,0); + left_button = middle_button = mouse_moved = false; + level = 0; + level_subset = 0; + + cur_layer = LAYER_TILES; + level_changed = false; + + sector = 0; + zoom = 1.0; + + /* Creating menus */ + level_subsets = FileSystem::dsubdirs("/levels", "info"); + subset_menu = new Menu(); + subset_menu->additem(MN_LABEL,_("Load Subset"),0,0); + subset_menu->additem(MN_HL,"",0,0); + int i = 0; + for(std::set::iterator it = level_subsets.begin(); it != level_subsets.end(); ++it, ++i) + subset_menu->additem(MN_ACTION, (*it),0,0,i); + subset_menu->additem(MN_HL,"",0,0); + subset_menu->additem(MN_BACK,_("Back"),0,0); + + create_subset_menu = new Menu(); + create_subset_menu->additem(MN_LABEL,_("New Level Subset"),0,0); + create_subset_menu->additem(MN_HL,"",0,0); + create_subset_menu->additem(MN_TEXTFIELD,_("Filename "),0,0,MN_ID_FILENAME_SUBSET); + create_subset_menu->additem(MN_TEXTFIELD,_("Title "),0,0,MN_ID_TITLE_SUBSET); + create_subset_menu->additem(MN_TEXTFIELD,_("Description"),0,0,MN_ID_DESCRIPTION_SUBSET); + create_subset_menu->additem(MN_ACTION,_("Create"),0,0, MN_ID_CREATE_SUBSET); + create_subset_menu->additem(MN_HL,"",0,0); + create_subset_menu->additem(MN_BACK,_("Back"),0,0); + + main_menu = new Menu(); + main_menu->additem(MN_LABEL,_("Level Editor Menu"),0,0); + main_menu->additem(MN_HL,"",0,0); + main_menu->additem(MN_ACTION,_("Return to Level Editor"),0,0,MN_ID_RETURN); + main_menu->additem(MN_GOTO,_("Create Level Subset"),0,create_subset_menu); + main_menu->additem(MN_GOTO,_("Load Level Subset"),0,subset_menu); + main_menu->additem(MN_HL,"",0,0); + main_menu->additem(MN_ACTION,_("Quit Level Editor"),0,0,MN_ID_QUIT); + + settings_menu = new Menu(); + settings_menu->additem(MN_LABEL,_("Level Settings"),0,0); + settings_menu->additem(MN_HL,"",0,0); + settings_menu->additem(MN_TEXTFIELD,_("Name "),0,0,MN_ID_NAME); + settings_menu->additem(MN_TEXTFIELD,_("Author "),0,0,MN_ID_AUTHOR); + settings_menu->additem(MN_NUMFIELD, _("Width "),0,0,MN_ID_WIDTH); + settings_menu->additem(MN_NUMFIELD, _("Height "),0,0,MN_ID_HEIGHT); + settings_menu->additem(MN_HL,"",0,0); + settings_menu->additem(MN_ACTION,_("Apply"),0,0,MN_ID_APPLY_SETTINGS); + + /* Creating button groups */ + load_buttons_gfx(); + + tiles_board = new ButtonGroup(Vector(screen->w - 140, 100), + Vector(32,32), Vector(4,8)); + + TileManager* tilemanager = TileManager::instance(); + + tiles_board->add_button(Button(img_rubber_bt, _("Eraser"), SDLKey(SDLK_DELETE)), 0); + for(unsigned int id = 1; id < tilemanager->get_max_tileid(); id++) + { + const Tile* tile = tilemanager->get(id); + if(!tile) + continue; - Surface* surface; - if(tile->editor_images.size()) - surface = tile->editor_images[0]; - else if(tile->images.size()) - surface = tile->images[0]; - else - continue; + Surface* surface; + if(tile->editor_images.size()) + surface = tile->editor_images[0]; + else if(tile->images.size()) + surface = tile->images[0]; + else + continue; - Button button = Button(surface, "", SDLKey(0)); - tiles_board->add_button(button, id); - } -for(int i = 0; i < NUM_BadGuyKinds; i++) - { - // filter bomb, since it is only for internal use, not for levels - if(i == BAD_BOMB) - continue; + Button button = Button(surface, "", SDLKey(0)); + tiles_board->add_button(button, id); + } - BadGuyKind kind = BadGuyKind(i); - BadGuy badguy(kind, 0,0); - badguy.activate(LEFT); + #if 0 + for(int i = 0; i < NUM_BadGuyKinds; i++) + { + // filter bomb, since it is only for internal use, not for levels + if(i == BAD_BOMB) + continue; - Surface *img = badguy.get_image(); - tiles_board->add_button(Button(img, "", SDLKey(SDLK_1+i)), -(i+1)); - } + BadGuyKind kind = BadGuyKind(i); + BadGuy badguy(kind, 0,0); + badguy.activate(LEFT); -tiles_board->add_button(Button(img_trampoline[0].get_frame(0), _("Trampoline"), SDLKey(0)), OBJ_TRAMPOLINE); -tiles_board->add_button(Button(img_flying_platform->get_frame(0), _("Flying Platform"), SDLKey(0)), OBJ_FLYING_PLATFORM); -tiles_board->add_button(Button(door->get_frame(0), _("Door"), SDLKey(0)), OBJ_DOOR); - -tiles_layer = new ButtonGroup(Vector(12, screen->h-64), Vector(80,20), Vector(1,3)); -tiles_layer->add_button(Button(img_foreground_bt, _("Edtit foreground tiles"), - SDLK_F10), LAYER_FOREGROUNDTILES); -tiles_layer->add_button(Button(img_interactive_bt, _("Edit interactive tiles"), - SDLK_F11), LAYER_TILES, true); -tiles_layer->add_button(Button(img_background_bt, _("Edit background tiles"), - SDLK_F12), LAYER_BACKGROUNDTILES); - -level_options = new ButtonGroup(Vector(screen->w-164, screen->h-36), Vector(32,32), Vector(5,1)); -level_options->add_pair_of_buttons(Button(img_next_sector_bt, _("Next sector"), SDLKey(0)), BT_NEXT_SECTOR, - Button(img_previous_sector_bt, _("Prevous sector"), SDLKey(0)), BT_PREVIOUS_SECTOR); -level_options->add_pair_of_buttons(Button(img_next_level_bt, _("Next level"), SDLKey(0)), BT_NEXT_LEVEL, - Button(img_previous_level_bt, _("Prevous level"), SDLKey(0)), BT_PREVIOUS_LEVEL); -level_options->add_button(Button(img_save_level_bt, _("Save level"), SDLK_F5), BT_LEVEL_SAVE); -level_options->add_button(Button(img_test_level_bt, _("Test level"), SDLK_F6), BT_LEVEL_TEST); -level_options->add_button(Button(img_setup_level_bt, _("Setup level"), SDLK_F7), BT_LEVEL_SETUP); + Surface *img = badguy.get_image(); + tiles_board->add_button(Button(img, "", SDLKey(SDLK_1+i)), -(i+1)); + } + #endif + + #if 0 + tiles_board->add_button(Button(img_trampoline[0].get_frame(0), _("Trampoline"), SDLKey(0)), OBJ_TRAMPOLINE); + tiles_board->add_button(Button(img_flying_platform->get_frame(0), _("Flying Platform"), SDLKey(0)), OBJ_FLYING_PLATFORM); + #endif + + tiles_layer = new ButtonGroup(Vector(12, screen->h-64), Vector(80,20), Vector(1,3)); + tiles_layer->add_button(Button(img_foreground_bt, _("Edtit foreground tiles"), + SDLK_F10), LAYER_FOREGROUNDTILES); + tiles_layer->add_button(Button(img_interactive_bt, _("Edit interactive tiles"), + SDLK_F11), LAYER_TILES, true); + tiles_layer->add_button(Button(img_background_bt, _("Edit background tiles"), + SDLK_F12), LAYER_BACKGROUNDTILES); + + level_options = new ButtonGroup(Vector(screen->w-164, screen->h-36), Vector(32,32), Vector(5,1)); + level_options->add_pair_of_buttons(Button(img_next_sector_bt, _("Next sector"), SDLKey(0)), BT_NEXT_SECTOR, + Button(img_previous_sector_bt, _("Prevous sector"), SDLKey(0)), BT_PREVIOUS_SECTOR); + level_options->add_pair_of_buttons(Button(img_next_level_bt, _("Next level"), SDLKey(0)), BT_NEXT_LEVEL, + Button(img_previous_level_bt, _("Prevous level"), SDLKey(0)), BT_PREVIOUS_LEVEL); + level_options->add_button(Button(img_save_level_bt, _("Save level"), SDLK_F5), BT_LEVEL_SAVE); + level_options->add_button(Button(img_test_level_bt, _("Test level"), SDLK_F6), BT_LEVEL_TEST); + level_options->add_button(Button(img_setup_level_bt, _("Setup level"), SDLK_F7), BT_LEVEL_SETUP); } LevelEditor::~LevelEditor() @@ -230,6 +233,7 @@ else mouse_cursor->set_state(MC_NORMAL); +frame_timer.start(.25, true); done = false; while(!done) { @@ -531,10 +535,8 @@ if(tiles_board->is_hover() || tiles_layer->is_hover() || level_options->is_hover if(sector) { - if(!frame_timer.check()) - { - frame_timer.start(25); - ++global_frame_counter; + if(frame_timer.check()) { + ++global_frame_counter; } // don't scroll before the start or after the level's end @@ -562,7 +564,7 @@ if(sector) } } -#define FADING_TIME 600 +#define FADING_TIME .6 void LevelEditor::draw(DrawingContext& context) { @@ -575,8 +577,8 @@ context.draw_filled_rect(Vector(0,0), Vector(screen->w,screen->h), Color(60,60,6 if(level_name_timer.check()) { context.push_transform(); - if(level_name_timer.get_left() < FADING_TIME) - context.set_alpha(level_name_timer.get_left() * 255 / FADING_TIME); + if(level_name_timer.get_timeleft() < FADING_TIME) + context.set_alpha(int(level_name_timer.get_timeleft() * 255 / FADING_TIME)); context.draw_text(gold_text, level->name, Vector(screen->w/2, 30), CENTER_ALLIGN, LAYER_GUI); if(level_nb != -1) @@ -619,17 +621,22 @@ if(sector) { int id = selection[0][0]; +#if 0 if(id == OBJ_TRAMPOLINE) context.draw_surface(img_trampoline[0].get_frame(0), Vector(event.button.x - 8, event.button.y - 8), LAYER_GUI-2); else if(id == OBJ_FLYING_PLATFORM) context.draw_surface(img_flying_platform->get_frame(0), Vector(event.button.x - 8, event.button.y - 8), LAYER_GUI-2); - else if(id == OBJ_DOOR) - context.draw_surface(door->get_frame(0), Vector(event.button.x - 8, - event.button.y - 8), LAYER_GUI-2); + else +#endif + if(id == OBJ_DOOR) + /*context.draw_surface(door->get_frame(0), Vector(event.button.x - 8, + event.button.y - 8), LAYER_GUI-2);*/ + ; else { +#if 0 BadGuyKind kind = BadGuyKind((-id)-1); BadGuy badguy(kind, 0,0); badguy.activate(LEFT); @@ -637,16 +644,19 @@ if(sector) context.draw_surface(img, Vector(event.button.x - 8, event.button.y - 8), LAYER_GUI-2); +#endif } } else { TileManager* tilemanager = TileManager::instance(); for(unsigned int x = 0; x < selection.size(); x++) - for(unsigned int y = 0; y < selection[x].size(); y++) - tilemanager->draw_tile(context, selection[x][y], + for(unsigned int y = 0; y < selection[x].size(); y++) { + const Tile* tile = tilemanager->get(selection[x][y]); + tile->draw(context, Vector(event.button.x + x*32 - 8, event.button.y + y*32 - 8), LAYER_GUI-2); + } } } context.set_drawing_effect(NONE_EFFECT); @@ -791,9 +801,11 @@ foregrounds = solids = backgrounds = 0; /* Point foregrounds, backgrounds, solids to its layer */ for(Sector::GameObjects::iterator i = sector->gameobjects.begin(); i != sector->gameobjects.end(); i++) { +#if 0 BadGuy* badguy = dynamic_cast (*i); if(badguy) badguy->activate(LEFT); +#endif TileMap* tilemap = dynamic_cast (*i); if(tilemap) @@ -835,83 +847,88 @@ level_changed = false; void LevelEditor::test_level() { -if(level_changed) - { - if(confirm_dialog(NULL, _("Level not saved. Wanna to?"))) - save_level(); - else - return; + if(level_changed) { + if(confirm_dialog(NULL, _("Level not saved. Wanna to?"))) + save_level(); + else + return; } -GameSession session(level_filename, ST_GL_TEST); -session.run(); -// player_status.reset(); -if(sound_manager) - sound_manager->halt_music(); + GameSession session(level_filename, ST_GL_TEST); + session.run(); + // player_status.reset(); + SoundManager::get()->halt_music(); } void LevelEditor::change(int x, int y, int newtile, int layer) -{ // find the tilemap of the current layer, and then change the tile -if(x < 0 || (unsigned int)x >= sector->solids->get_width()*32 || - y < 0 || (unsigned int)y >= sector->solids->get_height()*32) - return; - -level_changed = true; +{ + // find the tilemap of the current layer, and then change the tile + if(x < 0 || (unsigned int)x >= sector->solids->get_width()*32 || + y < 0 || (unsigned int)y >= sector->solids->get_height()*32) + return; -if(zoom != 1) + level_changed = true; + + if(zoom != 1) { // no need to do this for normal view (no zoom) - x = (int)(x * (zoom*32) / 32); - y = (int)(y * (zoom*32) / 32); + x = (int)(x * (zoom*32) / 32); + y = (int)(y * (zoom*32) / 32); } -if(newtile < 0) // add object + if(newtile < 0) // add object { - // remove an active tile or object that might be there - change(x, y, 0, LAYER_TILES); - - if(newtile == OBJ_TRAMPOLINE) - sector->add_object(new Trampoline(x, y)); - else if(newtile == OBJ_FLYING_PLATFORM) - sector->add_object(new FlyingPlatform(x, y)); - else if(newtile == OBJ_DOOR) - sector->add_object(new Door(x, y)); - else - sector->add_bad_guy(x, y, BadGuyKind((-newtile)-1), true); - - sector->update_game_objects(); - } -else if(cur_layer == LAYER_FOREGROUNDTILES) - foregrounds->change(x/32, y/32, newtile); -else if(cur_layer == LAYER_TILES) - { - // remove a bad guy if it's there - // we /32 in order to round numbers - for(Sector::GameObjects::iterator i = sector->gameobjects.begin(); i < sector->gameobjects.end(); i++) - { - BadGuy* badguy = dynamic_cast (*i); - if(badguy) - if((int)badguy->base.x/32 == x/32 && (int)badguy->base.y/32 == y/32) - sector->gameobjects.erase(i); - Trampoline* trampoline = dynamic_cast (*i); - if(trampoline) - { - if((int)trampoline->base.x/32 == x/32 && (int)trampoline->base.y/32 == y/32) - sector->gameobjects.erase(i); - } - FlyingPlatform* flying_platform = dynamic_cast (*i); - if(flying_platform) - if((int)flying_platform->base.x/32 == x/32 && (int)flying_platform->base.y/32 == y/32) - sector->gameobjects.erase(i); - Door* door = dynamic_cast (*i); - if(door) - if((int)door->get_area().x/32 == x/32 && (int)door->get_area().y/32 == y/32) - sector->gameobjects.erase(i); + // remove an active tile or object that might be there + change(x, y, 0, LAYER_TILES); + +#if 0 + if(newtile == OBJ_TRAMPOLINE) + sector->add_object(new Trampoline(x, y)); + else if(newtile == OBJ_FLYING_PLATFORM) + sector->add_object(new FlyingPlatform(x, y)); + else + if(newtile == OBJ_DOOR) + sector->add_object(new Door(x, y)); + else + sector->add_bad_guy(x, y, BadGuyKind((-newtile)-1), true); +#endif + + sector->update_game_objects(); + } else if(cur_layer == LAYER_FOREGROUNDTILES) { + foregrounds->change(x/32, y/32, newtile); + } else if(cur_layer == LAYER_TILES) { + // remove a bad guy if it's there + // we /32 in order to round numbers + for(Sector::GameObjects::iterator i = sector->gameobjects.begin(); + i < sector->gameobjects.end(); i++) { +#if 0 + BadGuy* badguy = dynamic_cast (*i); + if(badguy) + if((int)badguy->base.x/32 == x/32 && (int)badguy->base.y/32 == y/32) + sector->gameobjects.erase(i); +#endif +#if 0 + Trampoline* trampoline = dynamic_cast (*i); + if(trampoline) + { + if((int)trampoline->base.x/32 == x/32 && (int)trampoline->base.y/32 == y/32) + sector->gameobjects.erase(i); + } + FlyingPlatform* flying_platform = dynamic_cast (*i); + if(flying_platform) + if((int)flying_platform->base.x/32 == x/32 && (int)flying_platform->base.y/32 == y/32) + sector->gameobjects.erase(i); +#endif +#if 0 + Door* door = dynamic_cast (*i); + if(door) + if((int)door->get_area().x/32 == x/32 && (int)door->get_area().y/32 == y/32) + sector->gameobjects.erase(i); +#endif } - sector->update_game_objects(); - solids->change(x/32, y/32, newtile); - } -else if(cur_layer == LAYER_BACKGROUNDTILES) - backgrounds->change(x/32, y/32, newtile); + sector->update_game_objects(); + solids->change(x/32, y/32, newtile); + } else if(cur_layer == LAYER_BACKGROUNDTILES) + backgrounds->change(x/32, y/32, newtile); } void LevelEditor::show_help() diff --git a/src/leveleditor.h b/src/leveleditor.h index 11e2bd215..0527f7aa6 100644 --- a/src/leveleditor.h +++ b/src/leveleditor.h @@ -24,7 +24,7 @@ #include #include "video/drawing_context.h" -#include "special/timer.h" +#include "timer.h" #include "level.h" #include "level_subset.h" @@ -129,8 +129,8 @@ private: float zoom; SDL_Event event; - Timer frame_timer; - Timer level_name_timer; + Timer2 frame_timer; + Timer2 level_name_timer; Surface *img_background_bt, *img_foreground_bt, *img_interactive_bt; Surface *img_save_level_bt, *img_setup_level_bt, *img_test_level_bt; diff --git a/src/misc.cpp b/src/misc.cpp index ce553ede9..b03fca10b 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -15,7 +15,10 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include + #include "misc.h" +#include "app/globals.h" void MyConfig::customload(LispReader& reader) { diff --git a/src/misc.h b/src/misc.h index c95cb9151..e74a85450 100644 --- a/src/misc.h +++ b/src/misc.h @@ -19,7 +19,6 @@ #define SUPERTUX_MISC_H #include "app/setup.h" -#include "app/globals.h" #include "resources.h" #include "gui/menu.h" #include "utils/configfile.h" @@ -44,16 +43,11 @@ enum OptionsMenuIDs { MNID_SHOWFPS }; -/* Screen proprities: */ -/* Don't use this to test for the actual screen sizes. Use screen->w/h instead! */ -#define SCREEN_W 800 -#define SCREEN_H 600 - /* Handle changes made to global settings in the options menu. */ -void process_options_menu(void); +void process_options_menu(); /* Create and setup menus. */ -void st_menu(void); +void st_menu(); void st_menu_free(); #endif //SUPERTUX_MISC_H diff --git a/src/object/block.cpp b/src/object/block.cpp new file mode 100644 index 000000000..0a8b03776 --- /dev/null +++ b/src/object/block.cpp @@ -0,0 +1,201 @@ +#include + +#include "block.h" +#include "resources.h" +#include "player.h" +#include "sector.h" +#include "special/sprite.h" +#include "special/sprite_manager.h" +#include "video/drawing_context.h" +#include "gameobjs.h" +#include "specialriser.h" +#include "growup.h" +#include "flower.h" +#include "oneup.h" +#include "star.h" + +static const float BOUNCY_BRICK_MAX_OFFSET=8; +static const float BOUNCY_BRICK_SPEED=90; +static const float EPSILON = .0001; + +Block::Block(const Vector& pos, Sprite* newsprite) + : sprite(newsprite), bouncing(false), bounce_dir(0), bounce_offset(0) +{ + bbox.set_pos(pos); + bbox.set_size(32, 32); + flags |= FLAG_SOLID; + original_y = pos.y; +} + +Block::~Block() +{ + delete sprite; +} + +HitResponse +Block::collision(GameObject& other, const CollisionHit& hitdata) +{ + if(bouncing) + return FORCE_MOVE; + + // TODO kill badguys when bumping them... + + Player* player = dynamic_cast (&other); + if(!player) + return ABORT_MOVE; + + // collided from below? + if(hitdata.normal.x == 0 && hitdata.normal.y < 0 + && player->get_movement().y < 0) { + hit(player); + } + + return ABORT_MOVE; +} + +void +Block::action(float elapsed_time) +{ + if(!bouncing) + return; + + float offset = original_y - get_pos().y; + if(offset > BOUNCY_BRICK_MAX_OFFSET) { + bounce_dir *= -1; + movement = Vector(0, bounce_dir * elapsed_time); + } else if(offset < -EPSILON) { + movement = Vector(0, offset); + bounce_dir = 0; + bouncing = false; + } else { + movement = Vector(0, bounce_dir * elapsed_time); + } +} + +void +Block::draw(DrawingContext& context) +{ + sprite->draw(context, get_pos(), LAYER_OBJECTS+1); +} + +void +Block::start_bounce() +{ + bouncing = true; + bounce_dir = -BOUNCY_BRICK_SPEED; + bounce_offset = 0; +} + +//--------------------------------------------------------------------------- + +BonusBlock::BonusBlock(const Vector& pos, int newdata) + : Block(pos, sprite_manager->create("bonusblock")), data(newdata) +{ + sprite->set_action("default"); +} + +void +BonusBlock::hit(Player* player) +{ + if(sprite->get_action_name() == "empty") { + SoundManager::get()->play_sound(IDToSound(SND_BRICK)); + return; + } + + Sector* sector = Sector::current(); + switch(data) { + case 1: // coin + Sector::current()->add_object(new BouncyCoin(get_pos())); + player->get_status().incCoins(); + break; + + case 2: // grow/fireflower + if(player->size == SMALL) { + SpecialRiser* riser = new SpecialRiser( + new GrowUp(get_pos() + Vector(0, -32))); + sector->add_object(riser); + } else { + SpecialRiser* riser = new SpecialRiser( + new Flower(get_pos() + Vector(0, -32), Flower::FIREFLOWER)); + sector->add_object(riser); + } + SoundManager::get()->play_sound(IDToSound(SND_UPGRADE)); + break; + + case 5: // grow/iceflower + if(player->size == SMALL) { + SpecialRiser* riser = new SpecialRiser( + new GrowUp(get_pos() + Vector(0, -32))); + sector->add_object(riser); + } else { + SpecialRiser* riser = new SpecialRiser( + new Flower(get_pos() + Vector(0, -32), Flower::ICEFLOWER)); + sector->add_object(riser); + } + SoundManager::get()->play_sound(IDToSound(SND_UPGRADE)); + break; + + case 3: // star + sector->add_object(new Star(get_pos())); + break; + + case 4: // 1up + sector->add_object(new OneUp(get_pos())); + break; + + default: + assert(false); + } + + start_bounce(); + sprite->set_action("empty"); +} + +//--------------------------------------------------------------------------- + +Brick::Brick(const Vector& pos, int data) + : Block(pos, sprite_manager->create("brick")), + breakable(false), coin_counter(0) +{ + if(data == 1) + coin_counter = 5; + else + breakable = true; +} + +void +Brick::hit(Player* player) +{ + if(sprite->get_action_name() == "empty") + return; + + SoundManager::get()->play_sound(IDToSound(SND_BRICK)); + Sector* sector = Sector::current(); + if(coin_counter > 0) { + sector->add_object(new BouncyCoin(get_pos())); + coin_counter--; + player->get_status().incCoins(); + if(coin_counter == 0) + sprite->set_action("empty"); + start_bounce(); + } else if(breakable) { + if(player->size == SMALL) { + start_bounce(); + return; + } + + sector->add_object( + new BrokenBrick(new Sprite(*sprite), get_pos(), Vector(-100, -400))); + sector->add_object( + new BrokenBrick(new Sprite(*sprite), get_pos() + Vector(0, 16), + Vector(-150, -300))); + sector->add_object( + new BrokenBrick(new Sprite(*sprite), get_pos() + Vector(16, 0), + Vector(100, -400))); + sector->add_object( + new BrokenBrick(new Sprite(*sprite), get_pos() + Vector(16, 16), + Vector(150, -300))); + remove_me(); + } +} + diff --git a/src/object/block.h b/src/object/block.h new file mode 100644 index 000000000..bd750a026 --- /dev/null +++ b/src/object/block.h @@ -0,0 +1,60 @@ +#ifndef __BOX_H__ +#define __BOX_H__ + +#include "special/moving_object.h" + +namespace SuperTux { + class Sprite; +} +class Player; + +using namespace SuperTux; + +class Block : public MovingObject +{ +public: + Block(const Vector& pos, Sprite* sprite); + ~Block(); + + virtual HitResponse collision(GameObject& other, const CollisionHit& hit); + virtual void action(float elapsed_time); + virtual void draw(DrawingContext& context); + +protected: + virtual void hit(Player* player) = 0; + void start_bounce(); + + Sprite* sprite; + bool bouncing; + float bounce_dir; + float bounce_offset; + float original_y; +}; + +class BonusBlock : public Block +{ +public: + BonusBlock(const Vector& pos, int data); + +protected: + virtual void hit(Player* player); + +private: + int data; +}; + +class Brick : public Block +{ +public: + Brick(const Vector& pos, int data); + +protected: + virtual void hit(Player* player); + +private: + bool breakable; + int coin_counter; +}; + +#endif + diff --git a/src/object/bullet.cpp b/src/object/bullet.cpp new file mode 100644 index 000000000..bceed3ccb --- /dev/null +++ b/src/object/bullet.cpp @@ -0,0 +1,101 @@ +#include + +#include +#include "bullet.h" +#include "defines.h" +#include "resources.h" +#include "camera.h" +#include "sector.h" +#include "app/globals.h" +#include "special/sprite_manager.h" +#include "badguy/badguy.h" + +static const float BULLET_XM = 300; +static const float BULLET_STARTING_YM = 0; + +Bullet::Bullet(const Vector& pos, float xm, int dir, int kind_) + : kind(kind_), life_count(3), sprite(0) +{ + bbox.set_pos(pos); + bbox.set_size(4, 4); + + float speed = dir == RIGHT ? BULLET_XM : -BULLET_XM; + physic.set_velocity_x(speed + xm); + physic.set_velocity_y(-BULLET_STARTING_YM); + + if (kind == ICE_BULLET) { + life_count = 6; //ice-bullets get "extra lives" for bumping off walls + sprite = sprite_manager->create("icebullet"); + } else if(kind == FIRE_BULLET) { + sprite = sprite_manager->create("firebullet"); + } +} + +Bullet::~Bullet() +{ + delete sprite; +} + +void +Bullet::action(float elapsed_time) +{ + if(kind == FIRE_BULLET) { + // @not completely framerate independant :-/ + physic.set_velocity_y(physic.get_velocity_y() - 50 * elapsed_time); + } + if(physic.get_velocity_y() > 900) + physic.set_velocity_y(900); + else if(physic.get_velocity_y() < -900) + physic.set_velocity_y(-900); + + float scroll_x = + Sector::current()->camera->get_translation().x; + float scroll_y = + Sector::current()->camera->get_translation().y; + if (get_pos().x < scroll_x || + get_pos().x > scroll_x + screen->w || +// get_pos().y < scroll_y || + get_pos().y > scroll_y + screen->h || + life_count <= 0) { + remove_me(); + return; + } + + movement = physic.get_movement(elapsed_time); +} + +void +Bullet::draw(DrawingContext& context) +{ + sprite->draw(context, get_pos(), LAYER_OBJECTS); +} + +HitResponse +Bullet::collision(GameObject& other, const CollisionHit& hit) +{ + if(other.get_flags() & FLAG_SOLID) { + if(fabsf(hit.normal.y) > .5) { // roof or floor bump + physic.set_velocity_y(-physic.get_velocity_y()); + life_count -= 1; + } else { // bumped left or right + if(kind == FIRE_BULLET) + remove_me(); + else + physic.set_velocity_x(-physic.get_velocity_x()); + } + + return CONTINUE; + } + + BadGuy* badguy = dynamic_cast (&other); + if(badguy) { + badguy->kill_fall(); + remove_me(); + return FORCE_MOVE; + } + + // TODO kill badguys + return FORCE_MOVE; +} + + diff --git a/src/object/bullet.h b/src/object/bullet.h new file mode 100644 index 000000000..ce356caf2 --- /dev/null +++ b/src/object/bullet.h @@ -0,0 +1,33 @@ +#ifndef __BULLET_H__ +#define __BULLET_H__ + +#include "special/moving_object.h" +#include "math/physic.h" +#include "special/sprite.h" + +using namespace SuperTux; + +enum BulletsKind { + FIRE_BULLET, + ICE_BULLET +}; + +class Bullet : public MovingObject +{ +public: + Bullet(const Vector& pos, float xm, int dir, int kind); + ~Bullet(); + + void action(float elapsed_time); + void draw(DrawingContext& context); + HitResponse collision(GameObject& other, const CollisionHit& hit); + + int kind; + +private: + int life_count; + Physic physic; + Sprite* sprite; +}; + +#endif diff --git a/src/object/coin.cpp b/src/object/coin.cpp new file mode 100644 index 000000000..04beb66da --- /dev/null +++ b/src/object/coin.cpp @@ -0,0 +1,44 @@ +#include + +#include "coin.h" +#include "resources.h" +#include "video/drawing_context.h" +#include "special/sprite_manager.h" +#include "player.h" +#include "scene.h" + +Coin::Coin(const Vector& pos) +{ + bbox.set_pos(pos); + bbox.set_size(32, 32); + sprite = sprite_manager->create("coin"); +} + +Coin::~Coin() +{ + delete sprite; +} + +void +Coin::action(float ) +{ +} + +void +Coin::draw(DrawingContext& context) +{ + sprite->draw(context, get_pos(), LAYER_TILES); +} + +HitResponse +Coin::collision(GameObject& other, const CollisionHit& hit) +{ + Player* player = dynamic_cast(&other); + if(player == 0) + return ABORT_MOVE; + + player->get_status().incCoins(); + remove_me(); + return ABORT_MOVE; +} + diff --git a/src/object/coin.h b/src/object/coin.h new file mode 100644 index 000000000..a4157a4c4 --- /dev/null +++ b/src/object/coin.h @@ -0,0 +1,27 @@ +#ifndef __COIN_H__ +#define __COIN_H__ + +#include "special/moving_object.h" + +namespace SuperTux { + class Sprite; +} + +using namespace SuperTux; + +class Coin : public MovingObject +{ +public: + Coin(const Vector& pos); + ~Coin(); + + virtual HitResponse collision(GameObject& other, const CollisionHit& hit); + virtual void action(float elapsed_time); + virtual void draw(DrawingContext& context); + +private: + Sprite* sprite; +}; + +#endif + diff --git a/src/object/fireworks.cpp b/src/object/fireworks.cpp new file mode 100644 index 000000000..e6369e1a5 --- /dev/null +++ b/src/object/fireworks.cpp @@ -0,0 +1,44 @@ +#include + +#include "fireworks.h" +#include "resources.h" +#include "sector.h" +#include "camera.h" +#include "app/globals.h" +#include "video/drawing_context.h" +#include "audio/sound_manager.h" + +using namespace SuperTux; + +Fireworks::Fireworks() +{ + timer.start(.2); +} + +Fireworks::~Fireworks() +{ +} + +void +Fireworks::action(float ) +{ + if(timer.check()) { + Sector* sector = Sector::current(); + Vector pos = sector->camera->get_translation(); + pos += Vector(screen->w * ((float) rand() / RAND_MAX), + screen->h/2 * ((float) rand() / RAND_MAX)); + + int red = rand() % 255; + int green = rand() % red; + sector->add_particles(pos, 0, 360, Vector(140, 140), + Vector(0, 0), 45, Color(red, green, 0), 3, 1300, + LAYER_FOREGROUND1+1); + SoundManager::get()->play_sound(IDToSound(SND_FIREWORKS)); + timer.start(((float) rand() / RAND_MAX) + .5); + } +} + +void +Fireworks::draw(DrawingContext& ) +{ +} diff --git a/src/object/fireworks.h b/src/object/fireworks.h new file mode 100644 index 000000000..0aedc098d --- /dev/null +++ b/src/object/fireworks.h @@ -0,0 +1,22 @@ +#ifndef __FIREWORKS_H__ +#define __FIREWORKS_H__ + +#include "video/drawing_context.h" +#include "special/game_object.h" +#include "timer.h" + +class Fireworks : public SuperTux::GameObject +{ +public: + Fireworks(); + ~Fireworks(); + + virtual void action(float elapsed_time); + virtual void draw(SuperTux::DrawingContext& context); + +private: + Timer2 timer; +}; + +#endif + diff --git a/src/object/flower.cpp b/src/object/flower.cpp new file mode 100644 index 000000000..8230f76cf --- /dev/null +++ b/src/object/flower.cpp @@ -0,0 +1,56 @@ +#include + +#include +#include "flower.h" +#include "defines.h" +#include "resources.h" +#include "camera.h" +#include "sector.h" +#include "player.h" +#include "app/globals.h" +#include "special/sprite_manager.h" + +Flower::Flower(const Vector& pos, Type _type) + : type(_type) +{ + bbox.set_pos(pos); + bbox.set_size(32, 32); + + if(_type == FIREFLOWER) + sprite = sprite_manager->create("fireflower"); + else + sprite = sprite_manager->create("iceflower"); +} + +Flower::~Flower() +{ + delete sprite; +} + +void +Flower::action(float ) +{ +} + +void +Flower::draw(DrawingContext& context) +{ + sprite->draw(context, get_pos(), LAYER_OBJECTS); +} + +HitResponse +Flower::collision(GameObject& other, const CollisionHit& hit) +{ + Player* player = dynamic_cast(&other); + if(!player) + return ABORT_MOVE; + + if(type == FIREFLOWER) + player->got_power = Player::FIRE_POWER; + else + player->got_power = Player::ICE_POWER; + SoundManager::get()->play_sound(IDToSound(SND_COFFEE)); + remove_me(); + return ABORT_MOVE; +} + diff --git a/src/object/flower.h b/src/object/flower.h new file mode 100644 index 000000000..6d69ec0ec --- /dev/null +++ b/src/object/flower.h @@ -0,0 +1,29 @@ +#ifndef __FLOWER_H__ +#define __FLOWER_H__ + +#include "special/moving_object.h" +#include "special/sprite.h" +#include "math/physic.h" + +using namespace SuperTux; + +class Flower : public MovingObject +{ +public: + enum Type { + FIREFLOWER, ICEFLOWER + }; + Flower(const Vector& pos, Type type); + ~Flower(); + + virtual void action(float elapsed_time); + virtual void draw(DrawingContext& context); + virtual HitResponse collision(GameObject& other, const CollisionHit& hit); + +private: + Type type; + Sprite* sprite; +}; + +#endif + diff --git a/src/object/growup.cpp b/src/object/growup.cpp new file mode 100644 index 000000000..a7f748214 --- /dev/null +++ b/src/object/growup.cpp @@ -0,0 +1,64 @@ +#include + +#include +#include "growup.h" +#include "defines.h" +#include "resources.h" +#include "camera.h" +#include "sector.h" +#include "player.h" +#include "app/globals.h" +#include "special/sprite_manager.h" + +GrowUp::GrowUp(const Vector& pos) +{ + bbox.set_pos(pos); + bbox.set_size(32, 32); + + sprite = sprite_manager->create("egg"); + physic.enable_gravity(true); + physic.set_velocity_x(100); +} + +GrowUp::~GrowUp() +{ + delete sprite; +} + +void +GrowUp::action(float elapsed_time) +{ + movement = physic.get_movement(elapsed_time); +} + +HitResponse +GrowUp::collision(GameObject& other, const CollisionHit& hit) +{ + if(other.get_flags() & FLAG_SOLID) { + if(fabsf(hit.normal.y) > .5) { // roof + physic.set_velocity_y(0); + } else { // bumped left or right + physic.set_velocity_x(-physic.get_velocity_x()); + } + + return CONTINUE; + } + + Player* player = dynamic_cast(&other); + if(player != 0) { + player->grow(); + SoundManager::get()->play_sound(IDToSound(SND_EXCELLENT)); + remove_me(); + + return ABORT_MOVE; + } + + return FORCE_MOVE; +} + +void +GrowUp::draw(DrawingContext& context) +{ + sprite->draw(context, get_pos(), LAYER_OBJECTS); +} + diff --git a/src/object/growup.h b/src/object/growup.h new file mode 100644 index 000000000..297100474 --- /dev/null +++ b/src/object/growup.h @@ -0,0 +1,26 @@ +#ifndef __GROWUP_H__ +#define __GROWUP_H__ + +#include "special/moving_object.h" +#include "special/sprite.h" +#include "math/physic.h" + +using namespace SuperTux; + +class GrowUp : public MovingObject +{ +public: + GrowUp(const Vector& pos); + ~GrowUp(); + + virtual void action(float elapsed_time); + virtual void draw(DrawingContext& context); + virtual HitResponse collision(GameObject& other, const CollisionHit& hit); + +private: + Sprite* sprite; + Physic physic; +}; + +#endif + diff --git a/src/object/oneup.cpp b/src/object/oneup.cpp new file mode 100644 index 000000000..5a027a0f2 --- /dev/null +++ b/src/object/oneup.cpp @@ -0,0 +1,46 @@ +#include + +#include "oneup.h" +#include "resources.h" +#include "player.h" +#include "scene.h" +#include "special/sprite_manager.h" +#include "video/drawing_context.h" + +OneUp::OneUp(const Vector& pos) +{ + bbox.set_pos(pos); + bbox.set_size(32, 32); + sprite = sprite_manager->create("1up"); + physic.set_velocity(100, 400); +} + +OneUp::~OneUp() +{ + delete sprite; +} + +void +OneUp::action(float elapsed_time) +{ + movement = physic.get_movement(elapsed_time); +} + +void +OneUp::draw(DrawingContext& context) +{ + sprite->draw(context, get_pos(), LAYER_OBJECTS); +} + +HitResponse +OneUp::collision(GameObject& other, const CollisionHit& hit) +{ + Player* player = dynamic_cast (&other); + if(player) { + player->get_status().incLives(); + remove_me(); + return ABORT_MOVE; + } + return FORCE_MOVE; +} + diff --git a/src/object/oneup.h b/src/object/oneup.h new file mode 100644 index 000000000..9f92871e9 --- /dev/null +++ b/src/object/oneup.h @@ -0,0 +1,25 @@ +#ifndef __ONEUP_H__ +#define __ONEUP_H__ + +#include "special/moving_object.h" +#include "special/sprite.h" +#include "math/physic.h" + +using namespace SuperTux; + +class OneUp : public MovingObject +{ +public: + OneUp(const Vector& pos); + ~OneUp(); + + virtual void action(float elapsed_time); + virtual void draw(DrawingContext& context); + virtual HitResponse collision(GameObject& other, const CollisionHit& hit); + +private: + Sprite* sprite; + Physic physic; +}; + +#endif diff --git a/src/object/platform.cpp b/src/object/platform.cpp new file mode 100644 index 000000000..e1a868dad --- /dev/null +++ b/src/object/platform.cpp @@ -0,0 +1,75 @@ +#include + +#include "platform.h" +#include "video/drawing_context.h" +#include "resources.h" +#include "player.h" +#include "special/sprite_manager.h" +#include "utils/lispreader.h" + +Platform::Platform(LispReader& reader) +{ + sprite = sprite_manager->create("flying_platform"); + movement = Vector(0, 1); + reader.read_float("x", bbox.p1.x); + reader.read_float("y", bbox.p1.y); + bbox.set_size(sprite->get_width(), sprite->get_height()); + + flags |= FLAG_SOLID; + + state = 0; +} + +Platform::~Platform() +{ + delete sprite; +} + +HitResponse +Platform::collision(GameObject& object, const CollisionHit& hit) +{ +#if 0 + if(typeid(object) == typeid(Player)) { + Player* player = (Player*) &object; + //player->movement += movement; + } +#endif + return FORCE_MOVE; +} + +void +Platform::action(float elapsed_time) +{ + // just some test code... + if(state == 0) { + movement = Vector(0, 1); + if(bbox.p1.y > 250) + state = 1; + } + if(state == 1) { + movement = Vector(0, -1); + if(bbox.p1.y < 50) + state = 2; + } + if(state == 2) { + movement = Vector(1, 0); + if(bbox.p1.x > 800) + state = 3; + } + if(state == 3) { + movement = Vector(-1, 0); + if(bbox.p1.x < 400) + state = 4; + } + if(state == 4) { + movement = Vector(-1, 1); + if(bbox.p1.x < 0) + state = 0; + } +} + +void +Platform::draw(DrawingContext& context) +{ + sprite->draw(context, get_pos(), LAYER_OBJECTS); +} diff --git a/src/object/platform.h b/src/object/platform.h new file mode 100644 index 000000000..be4119b84 --- /dev/null +++ b/src/object/platform.h @@ -0,0 +1,28 @@ +#ifndef __PLATFORM_H__ +#define __PLATFORM_H__ + +#include "special/moving_object.h" +#include "special/sprite.h" + +using namespace SuperTux; + +/** + * This class is the base class for platforms that tux can stand on + */ +class Platform : public SuperTux::MovingObject +{ +public: + Platform(LispReader& reader); + ~Platform(); + + virtual HitResponse collision(GameObject& other, const CollisionHit& hit); + virtual void action(float elapsed_time); + virtual void draw(DrawingContext& context); + +private: + int state; + Sprite* sprite; +}; + +#endif + diff --git a/src/object/specialriser.cpp b/src/object/specialriser.cpp new file mode 100644 index 000000000..8d84f6af7 --- /dev/null +++ b/src/object/specialriser.cpp @@ -0,0 +1,41 @@ +#include + +#include +#include "specialriser.h" +#include "defines.h" +#include "resources.h" +#include "camera.h" +#include "sector.h" +#include "app/globals.h" +#include "special/sprite_manager.h" + +SpecialRiser::SpecialRiser(MovingObject* _child) + : child(_child) +{ + offset = 0; +} + +SpecialRiser::~SpecialRiser() +{ +} + +void +SpecialRiser::action(float elapsed_time) +{ + offset += 50 * elapsed_time; + if(offset > 32) { + Sector::current()->add_object(child); + remove_me(); + } +} + +void +SpecialRiser::draw(DrawingContext& context) +{ + context.push_transform(); + context.set_translation( + context.get_translation() + Vector(0, -32 + offset)); + child->draw(context); + context.pop_transform(); +} + diff --git a/src/object/specialriser.h b/src/object/specialriser.h new file mode 100644 index 000000000..9cc104f7f --- /dev/null +++ b/src/object/specialriser.h @@ -0,0 +1,27 @@ +#ifndef __SPECIALRISE_H__ +#define __SPECIALRISE_H__ + +#include "special/moving_object.h" + +using namespace SuperTux; + +/** + * special object that contains another object and slowly rises it out of a + * bonus block. + */ +class SpecialRiser : public GameObject +{ +public: + SpecialRiser(MovingObject* child); + ~SpecialRiser(); + + virtual void action(float elapsed_time); + virtual void draw(DrawingContext& context); + +private: + float offset; + MovingObject* child; +}; + +#endif + diff --git a/src/object/star.cpp b/src/object/star.cpp new file mode 100644 index 000000000..522c08af4 --- /dev/null +++ b/src/object/star.cpp @@ -0,0 +1,63 @@ +#include + +#include "star.h" +#include "resources.h" +#include "player.h" +#include "scene.h" +#include "special/sprite_manager.h" +#include "video/drawing_context.h" + +static const float INITIALJUMP = 400; +static const float SPEED = 150; +static const float JUMPSPEED = 300; + +Star::Star(const Vector& pos) +{ + bbox.set_pos(pos); + bbox.set_size(32, 32); + sprite = sprite_manager->create("star"); + physic.set_velocity(SPEED, INITIALJUMP); +} + +Star::~Star() +{ + delete sprite; +} + +void +Star::action(float elapsed_time) +{ + movement = physic.get_movement(elapsed_time); +} + +void +Star::draw(DrawingContext& context) +{ + sprite->draw(context, get_pos(), LAYER_OBJECTS); +} + +HitResponse +Star::collision(GameObject& other, const CollisionHit& hit) +{ + if(other.get_flags() & FLAG_SOLID) { + if(hit.normal.y < -.5) { // ground + physic.set_velocity_y(JUMPSPEED); + } else if(hit.normal.y > .5) { // roof + physic.set_velocity_y(0); + } else { // bumped left or right + physic.set_velocity_x(-physic.get_velocity_x()); + } + + return CONTINUE; + } + + Player* player = dynamic_cast (&other); + if(player) { + player->make_invincible(); + remove_me(); + return ABORT_MOVE; + } + + return FORCE_MOVE; +} + diff --git a/src/object/star.h b/src/object/star.h new file mode 100644 index 000000000..3b88888fc --- /dev/null +++ b/src/object/star.h @@ -0,0 +1,25 @@ +#ifndef __STAR_H__ +#define __STAR_H__ + +#include "special/moving_object.h" +#include "special/sprite.h" +#include "math/physic.h" + +using namespace SuperTux; + +class Star : public MovingObject +{ +public: + Star(const Vector& pos); + ~Star(); + + virtual void action(float elapsed_time); + virtual void draw(DrawingContext& context); + virtual HitResponse collision(GameObject& other, const CollisionHit& hit); + +private: + Sprite* sprite; + Physic physic; +}; + +#endif diff --git a/src/particlesystem.cpp b/src/particlesystem.cpp index ea301d871..5bda1bcc4 100644 --- a/src/particlesystem.cpp +++ b/src/particlesystem.cpp @@ -18,6 +18,8 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include + #include #include diff --git a/src/player.cpp b/src/player.cpp index bb033adf2..9200ae6ce 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -17,6 +17,9 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include + +#include #include #include #include @@ -33,35 +36,33 @@ #include "camera.h" #include "gameobjs.h" #include "resources.h" -#include "interactive_object.h" #include "video/screen.h" #include "statistics.h" #include "gameloop.h" +#include "trigger/trigger_base.h" // behavior definitions: #define TILES_FOR_BUTTJUMP 3 // animation times (in ms): -#define SHOOTING_TIME 320 -// others stuff: -#define AUTOSCROLL_DEAD_INTERVAL 300 +#define SHOOTING_TIME .150 // time before idle animation starts -#define IDLE_TIME 2500 +#define IDLE_TIME 2.500 // growing animation Surface* growingtux_left[GROWING_FRAMES]; Surface* growingtux_right[GROWING_FRAMES]; -Surface* tux_life; +Surface* tux_life = 0; -Sprite* smalltux_gameover; -Sprite* smalltux_star; -Sprite* bigtux_star; +Sprite* smalltux_gameover = 0; +Sprite* smalltux_star = 0; +Sprite* bigtux_star = 0; -TuxBodyParts* small_tux; -TuxBodyParts* big_tux; -TuxBodyParts* fire_tux; -TuxBodyParts* ice_tux; +TuxBodyParts* small_tux = 0; +TuxBodyParts* big_tux = 0; +TuxBodyParts* fire_tux = 0; +TuxBodyParts* ice_tux = 0; PlayerKeymap keymap; @@ -79,6 +80,7 @@ PlayerKeymap::PlayerKeymap() void player_input_init(player_input_type* pplayer_input) { pplayer_input->up = UP; + pplayer_input->old_up = UP; pplayer_input->down = UP; pplayer_input->fire = UP; pplayer_input->left = UP; @@ -143,15 +145,11 @@ Player::init() { holding_something = false; - base.width = 32; - base.height = 32; + bbox.set_size(32, 32); size = SMALL; got_power = NONE_POWER; - base.x = 0; - base.y = 0; - previous_base = old_base = base; dir = RIGHT; old_dir = dir; duck = false; @@ -176,20 +174,14 @@ Player::init() // Ricardo's flapping flaps_nb = 0; + on_ground_flag = false; + frame_main = 0; frame_ = 0; player_input_init(&input); - invincible_timer.init(true); - skidding_timer.init(true); - safe_timer.init(true); - frame_timer.init(true); - kick_timer.init(true); - shooting_timer.init(true); - growing_timer.init(true); - idle_timer.init(true); - flapping_timer.init(true); + frame_timer.start(.025, true); physic.reset(); } @@ -197,7 +189,7 @@ Player::init() int Player::key_event(SDLKey key, int state) { - idle_timer.start(IDLE_TIME); + idle_timer.start(IDLE_TIME, true); if(key == keymap.right) { @@ -211,22 +203,11 @@ Player::key_event(SDLKey key, int state) } else if(key == keymap.up) { + if(state == UP) + input.old_up = UP; input.up = state; - /* Up key also opens activates stuff */ input.activate = state; - - if(state == DOWN) { - /** check for interactive objects */ - for(Sector::InteractiveObjects::iterator i - = Sector::current()->interactive_objects.begin(); - i != Sector::current()->interactive_objects.end(); ++i) { - if(rectcollision(base, (*i)->get_area())) { - (*i)->interaction(INTERACTION_ACTIVATE); - } - } - } - return true; } else if(key == keymap.down) @@ -256,31 +237,28 @@ Player::key_event(SDLKey key, int state) void Player::level_begin() { - base.x = 100; - base.y = 170; - previous_base = old_base = base; + move(Vector(100, 170)); duck = false; dying = DYING_NOT; player_input_init(&input); - invincible_timer.init(true); - skidding_timer.init(true); - safe_timer.init(true); - frame_timer.init(true); - growing_timer.init(true); - idle_timer.init(true); + on_ground_flag = false; physic.reset(); } +PlayerStatus& +Player::get_status() +{ + return player_status; +} + void Player::action(float elapsed_time) { - bool jumped_in_solid = false; - - if(dying && !dying_timer.check()) { + if(dying && dying_timer.check()) { dead = true; return; } @@ -288,19 +266,15 @@ Player::action(float elapsed_time) if (input.fire == UP) holding_something = false; - /* Move tux: */ - previous_base = base; - /* --- HANDLE TUX! --- */ if(dying == DYING_NOT) handle_input(); - physic.apply(elapsed_time, base.x, base.y, Sector::current()->gravity); + movement = physic.get_movement(elapsed_time); if(dying == DYING_NOT) { - base_type target = base; - +#if 0 collision_swept_object_map(&old_base, &base); if ((!invincible_timer.started() && !safe_timer.started()) @@ -313,9 +287,9 @@ Player::action(float elapsed_time) // Don't accelerate Tux if he is running against a wall if (target.x != base.x) - { - physic.set_velocity_x(0); - } + { + physic.set_velocity_x(0); + } // special exception for cases where we're stuck under tiles after // being ducked. In this case we drift out @@ -396,9 +370,11 @@ Player::action(float elapsed_time) Sector::current()->tryemptybox(Vector(base.x+ 31, base.y), LEFT); } } +#endif grabdistros(); +#if 0 if (jumped_in_solid) { ++base.y; @@ -410,44 +386,16 @@ Player::action(float elapsed_time) flapping = false; } } +#endif } - /* ---- DONE HANDLING TUX! --- */ - - // check some timers - skidding_timer.check(); - invincible_timer.check(); - safe_timer.check(); - kick_timer.check(); + on_ground_flag = false; } bool Player::on_ground() { - return ( issolid(base.x + base.width / 2, base.y + base.height) || - issolid(base.x + 1, base.y + base.height) || - issolid(base.x + base.width - 1, base.y + base.height)); -} - -bool -Player::under_solid() -{ - return ( issolid(base.x + base.width / 2, base.y) || - issolid(base.x + 1, base.y) || - issolid(base.x + base.width - 1, base.y) ); -} - -bool -Player::tiles_on_air(int tiles) -{ - for(int t = 0; t != tiles; t++) - { - if(issolid(base.x + base.width / 2, base.y + base.height + (tiles*32)) || - issolid(base.x + 1, base.y + base.height + (tiles*32)) || - issolid(base.x + base.width - 1, base.y + base.height + (tiles*32))) - return false; - } - return true; + return on_ground_flag; } void @@ -500,15 +448,16 @@ Player::handle_horizontal_input() if(on_ground() && ((vx < 0 && dirsign >0) || (vx>0 && dirsign<0))) { // let's skid! - if(fabs(vx)>SKID_XM && !skidding_timer.check()) + if(fabs(vx)>SKID_XM && !skidding_timer.started()) { skidding_timer.start(SKID_TIME); SoundManager::get()->play_sound(IDToSound(SND_SKID)); // dust some partcles Sector::current()->add_particles( - Vector(base.x + (dir == RIGHT ? base.width : 0), base.y+base.height), + Vector(bbox.p1.x + (dir == RIGHT ? bbox.get_width() : 0), + bbox.p2.y), dir == RIGHT ? 270+20 : 90-40, dir == RIGHT ? 270+40 : 90-20, - Vector(2.8,-2.6), Vector(0,0.030), 3, Color(100,100,100), 3, 800, + Vector(280,-260), Vector(0,0.030), 3, Color(100,100,100), 3, 800, LAYER_OBJECTS+1); ax *= 2.5; @@ -531,6 +480,7 @@ Player::handle_horizontal_input() } } +#if 0 // if we're on ice slow down acceleration or deceleration if (isice(base.x, base.y + base.height)) { @@ -543,6 +493,7 @@ Player::handle_horizontal_input() // must stay above zero, though if (ax != 0) ax *= 1 / fabs(vx); } +#endif physic.set_velocity(vx, vy); physic.set_acceleration(ax, ay); @@ -551,13 +502,12 @@ Player::handle_horizontal_input() void Player::handle_vertical_input() { - // set fall mode... if(on_ground()) { fall_mode = ON_GROUND; - last_ground_y = base.y; + last_ground_y = get_pos().y; } else { - if(base.y > last_ground_y) + if(get_pos().y > last_ground_y) fall_mode = FALLING; else if(fall_mode == ON_GROUND) fall_mode = JUMPING; @@ -567,16 +517,16 @@ Player::handle_vertical_input() if(input.jump == DOWN && can_jump && on_ground()) { if(duck) { // only jump a little bit when in duck mode { - physic.set_velocity_y(3); + physic.set_velocity_y(300); } else { // jump higher if we are running if (fabs(physic.get_velocity_x()) > MAX_WALK_XM) - physic.set_velocity_y(5.8); + physic.set_velocity_y(580); else - physic.set_velocity_y(5.2); + physic.set_velocity_y(520); } - --base.y; + //bbox.move(Vector(0, -1)); jumping = true; flapping = false; can_jump = false; @@ -609,8 +559,8 @@ Player::handle_vertical_input() if(input.jump == DOWN && input.old_jump == UP && can_flap && flaps_nb < 3) { - physic.set_velocity_y(3.5); - physic.set_velocity_x(physic.get_velocity_x() * 0.35); + physic.set_velocity_y(350); + physic.set_velocity_x(physic.get_velocity_x() * 35); flaps_nb++; } } @@ -624,23 +574,26 @@ Player::handle_vertical_input() flapping_timer.start(TUX_FLAPPING_TIME); flapping_velocity = physic.get_velocity_x(); } - if (!flapping_timer.check()) + if (flapping_timer.check()) { can_flap = false; falling_from_flap = true; } jumping = true; flapping = true; - if (flapping_timer.get_gone() <= TUX_FLAPPING_TIME) - { - float cv; - if (flapping_velocity == 0) {cv = 0;} - else {cv = flapping_velocity*(sqrt(TUX_FLAPPING_TIME-(float)flapping_timer.get_gone()))/sqrt(TUX_FLAPPING_TIME);} - //Handle change of direction while flapping - if (((dir == LEFT) && (cv > 0)) || (dir == RIGHT) && (cv < 0)) {cv *= (-1);} - physic.set_velocity_x(cv); - physic.set_velocity_y((float)flapping_timer.get_gone()/850); - } + if (!flapping_timer.check()) { + float cv = flapping_velocity * sqrt( + TUX_FLAPPING_TIME - flapping_timer.get_timegone() + / TUX_FLAPPING_TIME); + + //Handle change of direction while flapping + if (((dir == LEFT) && (cv > 0)) || (dir == RIGHT) && (cv < 0)) { + cv *= (-1); + } + physic.set_velocity_x(cv); + physic.set_velocity_y( + flapping_timer.get_timegone()/.850); + } } } else if(flapping_mode == RYAN_FLAP) @@ -652,14 +605,14 @@ Player::handle_vertical_input() { flapping_timer.start(TUX_FLAPPING_TIME); } - if (!flapping_timer.check()) + if (flapping_timer.check()) { can_flap = false; falling_from_flap = true; } jumping = true; flapping = true; - if (flapping && flapping_timer.get_gone() <= TUX_FLAPPING_TIME + if (flapping && flapping_timer.get_timegone() <= TUX_FLAPPING_TIME && physic.get_velocity_y() < 0) { float gravity = Sector::current()->gravity; @@ -668,7 +621,7 @@ Player::handle_vertical_input() // XXX: magic numbers. should be a percent of gravity // gravity is (by default) -0.1f - physic.set_acceleration_y(.12 + .01f*xr); + physic.set_acceleration_y(12 + 1*xr); #if 0 // To slow down x-vel when flapping (not working) @@ -688,20 +641,21 @@ Player::handle_vertical_input() } } - // Hover //(disabled by default, use cheat code "hover" to toggle on/off) //TODO: needs some tweaking, especially when used together with double jump and jumping off badguys if (enable_hover && input.jump == DOWN && !jumping && !butt_jump && physic.get_velocity_y() <= 0) { - physic.set_velocity_y(-1); + physic.set_velocity_y(-100); } +#if 0 /* In case the player has pressed Down while in a certain range of air, enable butt jump action */ if (input.down == DOWN && !butt_jump && !duck) if(tiles_on_air(TILES_FOR_BUTTJUMP) && jumping) butt_jump = true; +#endif /* When Down is not held anymore, disable butt jump */ if(butt_jump && input.down == UP) @@ -712,12 +666,14 @@ Player::handle_vertical_input() { // Add a smoke cloud if (duck) - Sector::current()->add_smoke_cloud(Vector(base.x - 32, base.y)); + Sector::current()->add_smoke_cloud(Vector(get_pos().x - 32, get_pos().y)); else - Sector::current()->add_smoke_cloud(Vector(base.x - 32, base.y + 32)); + Sector::current()->add_smoke_cloud( + Vector(get_pos().x - 32, get_pos().y + 32)); butt_jump = false; +#if 0 // Break bricks beneath Tux if(Sector::current()->trybreakbrick( Vector(base.x + 1, base.y + base.height), false) @@ -727,7 +683,9 @@ Player::handle_vertical_input() physic.set_velocity_y(2); butt_jump = true; } +#endif +#if 0 // Kill nearby badguys std::vector gameobjects = Sector::current()->gameobjects; for (std::vector::iterator i = gameobjects.begin(); @@ -747,11 +705,19 @@ Player::handle_vertical_input() } } } +#endif } - if ( (issolid(base.x + base.width / 2, base.y + base.height + 64) || - issolid(base.x + 1, base.y + base.height + 64) || - issolid(base.x + base.width - 1, base.y + base.height + 64)) + /** jumping is only allowed if we're about to touch ground soon and if the + * button has been up in between the last jump + */ + // FIXME +#if 0 + if ( (issolid(get_pos().x + bbox.get_width() / 2, + get_pos().y + bbox.get_height() + 64) || + issolid(get_pos().x + 1, get_pos().y + bbox.get_height() + 64) || + issolid(get_pos().x + bbox.get_width() - 1, + get_pos().y + bbox.get_height() + 64)) && jumping == false && can_jump == false && input.jump == DOWN @@ -759,13 +725,16 @@ Player::handle_vertical_input() { can_jump = true; } +#endif if(on_ground()) /* Make sure jumping is off. */ { jumping = false; flapping = false; falling_from_flap = false; - if (flapping_timer.started()) {flapping_timer.stop();} + if (flapping_timer.started()) { + flapping_timer.start(0); + } physic.set_acceleration_y(0); //for flapping } @@ -788,58 +757,58 @@ Player::handle_input() /* Shoot! */ if (input.fire == DOWN && input.old_fire == UP && got_power != NONE_POWER) { - if(Sector::current()->add_bullet(Vector(base.x, base.y + (base.height/2)), + if(Sector::current()->add_bullet( + get_pos() + Vector(0, bbox.get_height()/2), physic.get_velocity_x(), dir)) shooting_timer.start(SHOOTING_TIME); input.old_fire = DOWN; } /* tux animations: */ - if(!frame_timer.check()) + if(frame_timer.check()) { + if (input.right == UP && input.left == UP) { - frame_timer.start(25); - if (input.right == UP && input.left == UP) - { - frame_main = 1; - frame_ = 1; - } - else - { - if ((input.fire == DOWN && (global_frame_counter % 2) == 0) || - (global_frame_counter % 4) == 0) - frame_main = (frame_main + 1) % 4; + frame_main = 1; + frame_ = 1; + } + else + { + if ((input.fire == DOWN && (global_frame_counter % 2) == 0) || + (global_frame_counter % 4) == 0) + frame_main = (frame_main + 1) % 4; - frame_ = frame_main; + frame_ = frame_main; - if (frame_ == 3) - frame_ = 1; - } + if (frame_ == 3) + frame_ = 1; } + } /* Duck! */ - if (input.down == DOWN && size == BIG && !duck && physic.get_velocity_y() == 0 && on_ground()) + if (input.down == DOWN && size == BIG && !duck + && physic.get_velocity_y() == 0 && on_ground()) { duck = true; - base.height = 32; - base.y += 32; - // changing base size confuses collision otherwise - old_base = previous_base = base; + bbox.move(Vector(0, 32)); + bbox.set_height(32); } else if(input.down == UP && size == BIG && duck) { // try if we can really unduck - base.y -= 32; - base.height = 64; + bbox.move(Vector(0, -32)); + bbox.set_height(64); + duck = false; + // FIXME +#if 0 // when unducking in air we need some space to do so - if(on_ground() || !collision_object_map(base)) { + if(on_ground() || !collision_object_map(bbox)) { duck = false; - // changing base size confuses collision otherwise - old_base = previous_base = base; } else { // undo the ducking changes - base.y += 32; - base.height = 32; - } + bbox.move(Vector(0, 32)); + bbox.set_height(32); + } +#endif } } @@ -850,47 +819,16 @@ Player::grow(bool animate) return; size = BIG; - base.height = 64; - base.y -= 32; + bbox.set_height(64); + bbox.move(Vector(0, -32)); if(animate) growing_timer.start(GROWING_TIME); - - old_base = previous_base = base; } void Player::grabdistros() { - /* Grab distros: */ - if (!dying) - { - Sector::current()->trygrabdistro(Vector(base.x, base.y), NO_BOUNCE); - Sector::current()->trygrabdistro(Vector(base.x+ 31, base.y), NO_BOUNCE); - Sector::current()->trygrabdistro( - Vector(base.x, base.y + base.height), NO_BOUNCE); - Sector::current()->trygrabdistro( - Vector(base.x+ 31, base.y + base.height), NO_BOUNCE); - - if(size == BIG) - { - Sector::current()->trygrabdistro( - Vector(base.x, base.y + base.height / 2), NO_BOUNCE); - Sector::current()->trygrabdistro( - Vector(base.x+ 31, base.y + base.height / 2), NO_BOUNCE); - } - - } - - /* Enough distros for a One-up? */ - if (player_status.distros >= DISTROS_LIFEUP) - { - player_status.distros = player_status.distros - DISTROS_LIFEUP; - if(player_status.lives < MAX_LIVES) - ++player_status.lives; - /*We want to hear the sound even, if MAX_LIVES is reached*/ - SoundManager::get()->play_sound(IDToSound(SND_LIFEUP)); - } } void @@ -908,7 +846,6 @@ Player::draw(DrawingContext& context) tux_body = big_tux; int layer = LAYER_OBJECTS - 1; - Vector pos = Vector(base.x, base.y); /* Set Tux sprite action */ if (duck && size == BIG) @@ -918,14 +855,14 @@ Player::draw(DrawingContext& context) else // dir == RIGHT tux_body->set_action("duck-right"); } - else if (skidding_timer.started()) + else if (skidding_timer.started() && !skidding_timer.check()) { if(dir == LEFT) tux_body->set_action("skid-left"); else // dir == RIGHT tux_body->set_action("skid-right"); } - else if (kick_timer.started()) + else if (kick_timer.started() && !kick_timer.check()) { if(dir == LEFT) tux_body->set_action("kick-left"); @@ -964,7 +901,7 @@ Player::draw(DrawingContext& context) } } - if(idle_timer.get_left() < 0) + if(idle_timer.check()) { if(size == BIG) { @@ -976,12 +913,11 @@ Player::draw(DrawingContext& context) tux_body->head->start_animation(1); } - idle_timer.start(IDLE_TIME); } // Tux is holding something if ((holding_something && physic.get_velocity_y() == 0) || - shooting_timer.check()) + (shooting_timer.get_timeleft() > 0 && !shooting_timer.check())) { if (duck) { @@ -1000,68 +936,96 @@ Player::draw(DrawingContext& context) } /* Draw Tux */ - if (dying == DYING_SQUISHED) - { - smalltux_gameover->draw(context, pos, LAYER_FOREGROUNDTILES+1); - } - else if(growing_timer.check()) - { + if (dying == DYING_SQUISHED) { + smalltux_gameover->draw(context, get_pos(), LAYER_FOREGROUNDTILES+1); + } else if(growing_timer.get_timeleft() > 0) { if(size == SMALL) { if (dir == RIGHT) context.draw_surface(growingtux_right[GROWING_FRAMES-1 - - ((growing_timer.get_gone() * - GROWING_FRAMES) / GROWING_TIME)], pos, layer); + int((growing_timer.get_timegone() * + GROWING_FRAMES) / GROWING_TIME)], get_pos(), layer); else context.draw_surface(growingtux_left[GROWING_FRAMES-1 - - ((growing_timer.get_gone() * - GROWING_FRAMES) / GROWING_TIME)], pos, layer); + int((growing_timer.get_timegone() * + GROWING_FRAMES) / GROWING_TIME)], get_pos(), layer); } else { if (dir == RIGHT) - context.draw_surface(growingtux_right[(growing_timer.get_gone() * - GROWING_FRAMES) / GROWING_TIME], pos, layer); + context.draw_surface(growingtux_right[ + int((growing_timer.get_timegone() * + GROWING_FRAMES) / GROWING_TIME)], get_pos(), layer); else - context.draw_surface(growingtux_left[(growing_timer.get_gone() * - GROWING_FRAMES) / GROWING_TIME], pos, layer); + context.draw_surface(growingtux_left[ + int((growing_timer.get_timegone() * + GROWING_FRAMES) / GROWING_TIME)], + get_pos(), layer); } } else if (safe_timer.started() && global_frame_counter%2) ; // don't draw Tux else - tux_body->draw(context, pos, layer); + tux_body->draw(context, get_pos(), layer); // Draw blinking star overlay if (invincible_timer.started() && - (invincible_timer.get_left() > TUX_INVINCIBLE_TIME_WARNING || global_frame_counter % 3) + (invincible_timer.get_timeleft() > TUX_INVINCIBLE_TIME_WARNING + || global_frame_counter % 3) && !dying) { if (size == SMALL || duck) - smalltux_star->draw(context, pos, LAYER_OBJECTS + 2); + smalltux_star->draw(context, get_pos(), LAYER_OBJECTS + 2); else - bigtux_star->draw(context, pos, LAYER_OBJECTS + 2); + bigtux_star->draw(context, get_pos(), LAYER_OBJECTS + 2); } if (debug_mode) - context.draw_filled_rect(Vector(base.x, base.y), - Vector(base.width, base.height), Color(75,75,75, 150), LAYER_OBJECTS+1); + context.draw_filled_rect(get_pos(), + Vector(bbox.get_width(), bbox.get_height()), + Color(75,75,75, 150), LAYER_OBJECTS+1); } -void -Player::collision(const MovingObject& other, int collision_type) +HitResponse +Player::collision(GameObject& other, const CollisionHit& hit) { - (void) other; - (void) collision_type; - // will be implemented later + if(dying) { + return FORCE_MOVE; + } + + if(other.get_flags() & FLAG_SOLID) { + if(hit.normal.y < 0) { // landed on floor? + if (physic.get_velocity_y() < 0) + physic.set_velocity_y(0); + on_ground_flag = true; + } else if(hit.normal.y > 0) { // bumped against the roof + physic.set_velocity_y(0); + } + + if(hit.normal.x != 0) { // hit on the side? + if(hit.normal.y > 0.6) // limits the slopes we can move up... + physic.set_velocity_x(0); + } + + return CONTINUE; + } + + TriggerBase* trigger = dynamic_cast (&other); + if(trigger) { + if(input.up == DOWN && input.old_up == UP) + trigger->event(*this, TriggerBase::EVENT_ACTIVATE); + } + + return FORCE_MOVE; } +#if 0 void Player::collision(void* p_c_object, int c_object) { - BadGuy* pbad_c = NULL; - Trampoline* ptramp_c = NULL; - FlyingPlatform* pplatform_c = NULL; + //BadGuy* pbad_c = NULL; + //Trampoline* ptramp_c = NULL; + //FlyingPlatform* pplatform_c = NULL; switch (c_object) { @@ -1094,7 +1058,7 @@ Player::collision(void* p_c_object, int c_object) else pbad_c->kill_me(20); } - else if (pbad_c->frozen_timer.check() && (pbad_c->kind == BAD_MRBOMB + else if (!pbad_c->frozen_timer.check() && (pbad_c->kind == BAD_MRBOMB || pbad_c->kind == BAD_JUMPY || pbad_c->kind == BAD_FISH || pbad_c->kind == BAD_SPIKY)) pbad_c->kill_me(20); @@ -1169,14 +1133,25 @@ Player::collision(void* p_c_object, int c_object) } } +#endif -/* Kill Player! */ +void +Player::make_invincible() +{ + SoundManager::get()->play_sound(IDToSound(SND_HERRING)); + invincible_timer.start(TUX_INVINCIBLE_TIME); + Sector::current()->play_music(HERRING_MUSIC); +} +/* Kill Player! */ void Player::kill(HurtMode mode) { if(dying) return; + + if(safe_timer.get_timeleft() > 0 || invincible_timer.get_timeleft() > 0) + return; SoundManager::get()->play_sound(IDToSound(SND_HURT)); @@ -1194,7 +1169,7 @@ Player::kill(HurtMode mode) growing_timer.start(GROWING_TIME); safe_timer.start(TUX_SAFE_TIME + GROWING_TIME); size = SMALL; - base.height = 32; + bbox.set_height(32); duck = false; } } @@ -1202,10 +1177,10 @@ Player::kill(HurtMode mode) { physic.enable_gravity(true); physic.set_acceleration(0, 0); - physic.set_velocity(0, 7); + physic.set_velocity(0, 700); --player_status.lives; dying = DYING_SQUISHED; - dying_timer.start(3000); + dying_timer.start(3.0); } } @@ -1215,29 +1190,27 @@ Player::remove_powerups() { got_power = NONE_POWER; size = SMALL; - base.height = 32; + bbox.set_height(32); } void Player::move(const Vector& vector) { - base.x = vector.x; - base.y = vector.y; - old_base = previous_base = base; + bbox.set_pos(vector); } void Player::check_bounds(Camera* camera) { /* Keep tux in bounds: */ - if (base.x < 0) + if (get_pos().x < 0) { // Lock Tux to the size of the level, so that he doesn't fall of // on the left side - base.x = 0; + bbox.set_pos(Vector(0, get_pos().y)); } /* Keep in-bounds, vertically: */ - if (base.y > Sector::current()->solids->get_height() * 32) + if (get_pos().y > Sector::current()->solids->get_height() * 32) { kill(KILL); return; @@ -1245,40 +1218,40 @@ Player::check_bounds(Camera* camera) bool adjust = false; // can happen if back scrolling is disabled - if(base.x < camera->get_translation().x) { - base.x = camera->get_translation().x; + if(get_pos().x < camera->get_translation().x) { + bbox.set_pos(Vector(camera->get_translation().x, get_pos().y)); adjust = true; } - if(base.x >= camera->get_translation().x + screen->w - base.width) { - base.x = camera->get_translation().x + screen->w - base.width; + if(get_pos().x >= camera->get_translation().x + screen->w - bbox.get_width()) + { + bbox.set_pos(Vector( + camera->get_translation().x + screen->w - bbox.get_width(), + get_pos().y)); adjust = true; } if(adjust) { + // FIXME +#if 0 // squished now? - if(collision_object_map(base)) { + if(collision_object_map(bbox)) { kill(KILL); return; } +#endif } } void -Player::bounce(BadGuy* badguy) +Player::bounce(BadGuy& badguy) { //Make sure we stopped flapping flapping = false; falling_from_flap = false; if (input.jump) - physic.set_velocity_y(5.2); + physic.set_velocity_y(520); else - physic.set_velocity_y(2); - - // Move the player a little bit above the badguy to avoid collision - // between badguy and player directly after the bounce has happend - base.y = badguy->base.y - base.height - 2; + physic.set_velocity_y(200); } -/* EOF */ - diff --git a/src/player.h b/src/player.h index e76b93b0e..cf9fe19c0 100644 --- a/src/player.h +++ b/src/player.h @@ -16,18 +16,17 @@ // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - #ifndef SUPERTUX_PLAYER_H #define SUPERTUX_PLAYER_H #include "SDL.h" #include "bitmask.h" -#include "special/timer.h" -#include "special/base.h" +#include "timer.h" #include "video/surface.h" #include "collision.h" #include "special/moving_object.h" +#include "special/sprite.h" #include "math/physic.h" #include "defines.h" @@ -37,15 +36,11 @@ class BadGuy; /* Times: */ -#define TUX_SAFE_TIME 1250 -#define TUX_INVINCIBLE_TIME 10000 -#define TUX_INVINCIBLE_TIME_WARNING 2000 -#define TUX_FLAPPING_TIME 1000 /* How long Tux can flap his wings to gain additional jump height */ -#define TIME_WARNING 20000 /* When to alert player they're low on time! */ - -/* One-ups... */ - -#define DISTROS_LIFEUP 100 +#define TUX_SAFE_TIME 1.250 +#define TUX_INVINCIBLE_TIME 10.0 +#define TUX_INVINCIBLE_TIME_WARNING 2.0 +#define TUX_FLAPPING_TIME 1 /* How long Tux can flap his wings to gain additional jump height */ +#define TIME_WARNING 20 /* When to alert player they're low on time! */ /* Scores: */ @@ -79,6 +74,7 @@ struct player_input_type int right; int left; int up; + int old_up; int down; int fire; int old_fire; @@ -89,10 +85,8 @@ struct player_input_type void player_input_init(player_input_type* pplayer_input); -namespace SuperTux { -class Sprite; -} class Camera; +class PlayerStatus; extern Surface* tux_life; @@ -100,7 +94,7 @@ extern Sprite* smalltux_gameover; extern Sprite* smalltux_star; extern Sprite* bigtux_star; -#define GROWING_TIME 1000 +#define GROWING_TIME 1.0 #define GROWING_FRAMES 7 extern Surface* growingtux_left[GROWING_FRAMES]; extern Surface* growingtux_right[GROWING_FRAMES]; @@ -108,8 +102,15 @@ extern Surface* growingtux_right[GROWING_FRAMES]; class TuxBodyParts { public: - TuxBodyParts() { }; - ~TuxBodyParts() { }; + TuxBodyParts() + : head(0), body(0), arms(0), feet(0) + { } + ~TuxBodyParts() { + delete head; + delete body; + delete arms; + delete feet; + } void set_action(std::string action); void one_time_animation(); @@ -148,6 +149,7 @@ public: float last_ground_y; FallMode fall_mode; + bool on_ground_flag; bool jumping; bool flapping; bool can_jump; @@ -167,17 +169,16 @@ public: enum { MAREK_FLAP, RICARDO_FLAP, RYAN_FLAP, NONE_FLAP }; int flapping_mode; - base_type previous_base; - Timer invincible_timer; - Timer skidding_timer; - Timer safe_timer; - Timer frame_timer; - Timer kick_timer; - Timer shooting_timer; // used to show the arm when Tux is shooting - Timer dying_timer; - Timer growing_timer; - Timer idle_timer; - Timer flapping_timer; + Timer2 invincible_timer; + Timer2 skidding_timer; + Timer2 safe_timer; + Timer2 frame_timer; + Timer2 kick_timer; + Timer2 shooting_timer; // used to show the arm when Tux is shooting + Timer2 dying_timer; + Timer2 growing_timer; + Timer2 idle_timer; + Timer2 flapping_timer; Physic physic; public: @@ -189,24 +190,26 @@ public: void handle_input(); void grabdistros(); + PlayerStatus& get_status(); + virtual void action(float elapsed_time); virtual void draw(DrawingContext& context); - virtual void collision(const MovingObject& other_object, - int collision_type); + virtual HitResponse collision(GameObject& other, const CollisionHit& hit); - void collision(void* p_c_object, int c_object); + void make_invincible(); + bool is_invincible() const + { + return invincible_timer.started(); + } void kill(HurtMode mode); void player_remove_powerups(); void check_bounds(Camera* camera); bool on_ground(); bool under_solid(); - bool tiles_on_air(int tiles); - void grow(bool animate); + void grow(bool animate = false); void move(const Vector& vector); - /** let the player jump a bit or more if jump button is hold down - (used when you hit a badguy) */ - void bounce(BadGuy* badguy); + void bounce(BadGuy& badguy); bool is_dead() const { return dead; } diff --git a/src/resources.cpp b/src/resources.cpp index a39da2af3..d6e73647f 100644 --- a/src/resources.cpp +++ b/src/resources.cpp @@ -17,18 +17,18 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include + #include "app/globals.h" #include "special/sprite_manager.h" -#include "audio/sound_manager.h" #include "app/setup.h" +#include "gui/menu.h" #include "gui/button.h" #include "scene.h" #include "player.h" #include "badguy.h" #include "gameobjs.h" -#include "special.h" #include "resources.h" -#include "door.h" #include "badguy_specs.h" Surface* img_waves[3]; @@ -54,7 +54,6 @@ MusicRef herring_song; MusicRef level_end_song; SpriteManager* sprite_manager = 0; -SoundManager* sound_manager = 0; char * soundfilenames[NUM_SOUNDS] = { "/sounds/jump.wav", @@ -120,9 +119,9 @@ void loadshared() sprite_manager = new SpriteManager(datadir + "/images/supertux.strf"); /* Tuxes: */ - smalltux_star = sprite_manager->load("smalltux-star"); - bigtux_star = sprite_manager->load("bigtux-star"); - smalltux_gameover = sprite_manager->load("smalltux-gameover"); + smalltux_star = sprite_manager->create("smalltux-star"); + bigtux_star = sprite_manager->create("bigtux-star"); + smalltux_gameover = sprite_manager->create("smalltux-gameover"); char img_name[1024]; for (int i = 0; i < GROWING_FRAMES; i++) @@ -135,28 +134,28 @@ void loadshared() } small_tux = new TuxBodyParts(); - small_tux->head = NULL; - small_tux->body = sprite_manager->load("small-tux-body"); - small_tux->arms = sprite_manager->load("small-tux-arms"); - small_tux->feet = NULL; + small_tux->head = 0; + small_tux->body = sprite_manager->create("small-tux-body"); + small_tux->arms = sprite_manager->create("small-tux-arms"); + small_tux->feet = 0; big_tux = new TuxBodyParts(); - big_tux->head = sprite_manager->load("big-tux-head"); - big_tux->body = sprite_manager->load("big-tux-body"); - big_tux->arms = sprite_manager->load("big-tux-arms"); - big_tux->feet = sprite_manager->load("big-tux-feet"); + big_tux->head = sprite_manager->create("big-tux-head"); + big_tux->body = sprite_manager->create("big-tux-body"); + big_tux->arms = sprite_manager->create("big-tux-arms"); + big_tux->feet = sprite_manager->create("big-tux-feet"); fire_tux = new TuxBodyParts(); - fire_tux->head = sprite_manager->load("big-fire-tux-head"); - fire_tux->body = sprite_manager->load("big-tux-body"); - fire_tux->arms = sprite_manager->load("big-tux-arms"); - fire_tux->feet = sprite_manager->load("big-tux-feet"); + fire_tux->head = sprite_manager->create("big-fire-tux-head"); + fire_tux->body = sprite_manager->create("big-tux-body"); + fire_tux->arms = sprite_manager->create("big-tux-arms"); + fire_tux->feet = sprite_manager->create("big-tux-feet"); ice_tux = new TuxBodyParts(); - ice_tux->head = sprite_manager->load("big-tux-head"); - ice_tux->body = sprite_manager->load("big-tux-body"); - ice_tux->arms = sprite_manager->load("big-tux-arms"); - ice_tux->feet = sprite_manager->load("big-tux-feet"); + ice_tux->head = sprite_manager->create("big-tux-head"); + ice_tux->body = sprite_manager->create("big-tux-body"); + ice_tux->arms = sprite_manager->create("big-tux-arms"); + ice_tux->feet = sprite_manager->create("big-tux-feet"); /* Load Bad Guys resources */ badguyspecs_manager = new BadGuySpecsManager(datadir + "/badguys.strf"); @@ -217,20 +216,9 @@ void loadshared() img_cloud[1][3] = new Surface(datadir + "/images/shared/cloud-13.png", true); - /* Upgrades: */ - load_special_gfx(); - /* Objects */ load_object_gfx(); - // load the door object graphics: - door = sprite_manager->load("door"); - for (int i = 0; i < DOOR_OPENING_FRAMES; i++) - { - sprintf(img_name, "%s/images/shared/door-%i.png", datadir.c_str(), i+1); - door_opening[i] = new Surface(img_name, true); - } - /* Distros: */ img_distro[0] = new Surface(datadir + "/images/tilesets/coin1.png", true); @@ -274,6 +262,10 @@ void loadshared() /* Free shared data: */ void unloadshared(void) { + delete smalltux_star; + delete bigtux_star; + delete smalltux_gameover; + /* Free global images: */ delete gold_text; delete white_text; @@ -283,26 +275,23 @@ void unloadshared(void) delete white_big_text; delete yellow_nums; - int i; - - free_special_gfx(); + free_object_gfx(); delete img_water; - for (i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) delete img_waves[i]; delete img_pole; delete img_poletop; - for (i = 0; i < 2; i++) + for (int i = 0; i < 2; i++) delete img_flag[i]; - for (i = 0; i < 4; i++) - { - delete img_distro[i]; - delete img_cloud[0][i]; - delete img_cloud[1][i]; - } + for (int i = 0; i < 4; i++) { + delete img_distro[i]; + delete img_cloud[0][i]; + delete img_cloud[1][i]; + } delete tux_life; @@ -311,20 +300,12 @@ void unloadshared(void) delete fire_tux; delete ice_tux; - for (int i = 0; i < GROWING_FRAMES; i++) - { + for (int i = 0; i < GROWING_FRAMES; i++) { delete growingtux_left[i]; delete growingtux_right[i]; } - // door game object: - - for (int i = 0; i < DOOR_OPENING_FRAMES; i++) - delete door_opening[i]; - delete sprite_manager; sprite_manager = 0; - sound_manager = 0; } -/* EOF */ diff --git a/src/resources.h b/src/resources.h index 1287060a9..2519b046f 100644 --- a/src/resources.h +++ b/src/resources.h @@ -21,13 +21,15 @@ #define SUPERTUX_RESOURCES_H #include "audio/musicref.h" -#include "gui/menu.h" using namespace SuperTux; namespace SuperTux { class SpriteManager; class SoundManager; +class Menu; +class Font; +class Surface; } /* Sound files: */ @@ -71,7 +73,6 @@ extern MusicRef herring_song; extern MusicRef level_end_song; extern SpriteManager* sprite_manager; -extern SoundManager* sound_manager; extern Menu* contrib_menu; extern Menu* contrib_subset_menu; @@ -97,5 +98,3 @@ void unloadshared(); #endif -/* EOF */ - diff --git a/src/scene.cpp b/src/scene.cpp index a2350355f..429abd07d 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -17,10 +17,13 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include + #include #include "scene.h" #include "defines.h" +#include "resources.h" PlayerStatus player_status; @@ -42,6 +45,25 @@ void PlayerStatus::reset() max_score_multiplier = 1; } +void +PlayerStatus::incLives() +{ + if(lives < MAX_LIVES) + ++lives; + SoundManager::get()->play_sound(IDToSound(SND_LIFEUP)); +} + +void +PlayerStatus::incCoins() +{ + distros++; + if(distros >= 100) { + incLives(); + distros = 0; + } + SoundManager::get()->play_sound(IDToSound(SND_DISTRO)); +} + std::string bonus_to_string(PlayerStatus::BonusType b) { switch (b) diff --git a/src/scene.h b/src/scene.h index 23bbb28d8..9ea2dc1c5 100644 --- a/src/scene.h +++ b/src/scene.h @@ -21,7 +21,7 @@ #define SUPERTUX_SCENE_H #include "video/surface.h" -#include "special/timer.h" +#include "timer.h" #define FRAME_RATE 10 // 100 Frames per second (10ms) @@ -37,8 +37,9 @@ struct PlayerStatus int max_score_multiplier; PlayerStatus(); - void reset(); + void incLives(); + void incCoins(); }; std::string bonus_to_string(PlayerStatus::BonusType b); diff --git a/src/sector.cpp b/src/sector.cpp index 4cde14196..37a9e39ec 100644 --- a/src/sector.cpp +++ b/src/sector.cpp @@ -17,6 +17,8 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include + #include #include #include @@ -28,7 +30,6 @@ #include "sector.h" #include "utils/lispreader.h" #include "badguy.h" -#include "special.h" #include "gameobjs.h" #include "camera.h" #include "background.h" @@ -38,15 +39,27 @@ #include "audio/sound_manager.h" #include "gameloop.h" #include "resources.h" -#include "interactive_object.h" -#include "door.h" #include "statistics.h" +#include "special/collision.h" +#include "math/rectangle.h" +#include "math/aatriangle.h" +#include "object/coin.h" +#include "object/block.h" +#include "object/platform.h" +#include "trigger/door.h" +#include "object/bullet.h" +#include "badguy/jumpy.h" +#include "badguy/snowball.h" +#include "badguy/bouncing_snowball.h" +#include "badguy/flame.h" +#include "badguy/mriceblock.h" +#include "badguy/mrbomb.h" +#include "trigger/sequence_trigger.h" Sector* Sector::_current = 0; Sector::Sector() - : end_sequence_animation_type(NONE_ENDSEQ_ANIM), - gravity(10), player(0), solids(0), background(0), camera(0), + : gravity(10), player(0), solids(0), background(0), camera(0), currentmusic(LEVEL_MUSIC) { song_title = "Mortimers_chipdisko.mod"; @@ -57,8 +70,9 @@ Sector::Sector() Sector::~Sector() { for(GameObjects::iterator i = gameobjects.begin(); i != gameobjects.end(); - ++i) + ++i) { delete *i; + } for(SpawnPoints::iterator i = spawnpoints.begin(); i != spawnpoints.end(); ++i) @@ -85,6 +99,69 @@ Sector *Sector::create(const std::string& name, size_t width, size_t height) return sector; } +GameObject* +Sector::parseObject(const std::string& name, LispReader& reader) +{ + if(name == "background") { + background = new Background(reader); + return background; + } else if(name == "camera") { + if(camera) { + std::cerr << "Warning: More than 1 camera defined in sector.\n"; + return 0; + } + camera = new Camera(this); + camera->read(reader); + return camera; + } else if(name == "tilemap") { + TileMap* tilemap = new TileMap(reader); + + if(tilemap->is_solid()) { + if(solids) { + std::cerr << "Warning multiple solid tilemaps in sector.\n"; + return 0; + } + solids = tilemap; + } + return tilemap; + } else if(name == "particles-snow") { + SnowParticleSystem* partsys = new SnowParticleSystem(); + partsys->parse(reader); + return partsys; + } else if(name == "particles-clouds") { + CloudParticleSystem* partsys = new CloudParticleSystem(); + partsys->parse(reader); + return partsys; + } else if(name == "door") { + return new Door(reader); + } else if(name == "platform") { + return new Platform(reader); + } else if(name == "jumpy" || name == "money") { + return new Jumpy(reader); + } else if(name == "snowball") { + return new SnowBall(reader); + } else if(name == "bouncingsnowball") { + return new BouncingSnowball(reader); + } else if(name == "flame") { + return new Flame(reader); + } else if(name == "mriceblock") { + return new MrIceBlock(reader); + } else if(name == "mrbomb") { + return new MrBomb(reader); + } +#if 0 + else if(badguykind_from_string(name) != BAD_INVALID) { + return new BadGuy(badguykind_from_string(name), reader); + } else if(name == "trampoline") { + return new Trampoline(reader); + } else if(name == "flying-platform") { + return new FlyingPlatform(reader); +#endif + + std::cerr << "Unknown object type '" << name << "'.\n"; + return 0; +} + void Sector::parse(LispReader& lispreader) { @@ -104,56 +181,17 @@ Sector::parse(LispReader& lispreader) } else if(token == "music") { song_title = lisp_string(data); load_music(); - } else if(token == "end-sequence-animation") { - std::string end_seq_anim = lisp_string(data); - if(end_seq_anim == "fireworks") - end_sequence_animation_type = FIREWORKS_ENDSEQ_ANIM; - } else if(token == "camera") { - if(camera) { - std::cerr << "Warning: More than 1 camera defined in sector.\n"; - continue; - } - camera = new Camera(this); - camera->read(reader); - add_object(camera); - } else if(token == "background") { - background = new Background(reader); - add_object(background); } else if(token == "spawn-points") { SpawnPoint* sp = new SpawnPoint; reader.read_string("name", sp->name); reader.read_float("x", sp->pos.x); reader.read_float("y", sp->pos.y); spawnpoints.push_back(sp); - } else if(token == "tilemap") { - TileMap* tilemap = new TileMap(reader); - add_object(tilemap); - - if(tilemap->is_solid()) { - if(solids) { - std::cerr << "Warning multiple solid tilemaps in sector.\n"; - continue; - } - solids = tilemap; - } - } else if(badguykind_from_string(token) != BAD_INVALID) { - add_object(new BadGuy(badguykind_from_string(token), reader)); - } else if(token == "trampoline") { - add_object(new Trampoline(reader)); - } else if(token == "flying-platform") { - add_object(new FlyingPlatform(reader)); - } else if(token == "particles-snow") { - SnowParticleSystem* partsys = new SnowParticleSystem(); - partsys->parse(reader); - add_object(partsys); - } else if(token == "particles-clouds") { - CloudParticleSystem* partsys = new CloudParticleSystem(); - partsys->parse(reader); - add_object(partsys); - } else if(token == "door") { - add_object(new Door(reader)); } else { - std::cerr << "Unknown object type '" << token << "'.\n"; + GameObject* object = parseObject(token, reader); + if(object) { + add_object(object); + } } } @@ -206,13 +244,6 @@ Sector::parse_old_format(LispReader& reader) add_object(background); } - std::string end_seq_anim; - reader.read_string("end-sequence-animation", end_seq_anim); - if(end_seq_anim == "fireworks") - end_sequence_animation_type = FIREWORKS_ENDSEQ_ANIM; -// else -// end_sequence_animation = NONE_ENDSEQ_ANIM; - std::string particlesystem; reader.read_string("particle_system", particlesystem); if(particlesystem == "clouds") @@ -244,6 +275,32 @@ Sector::parse_old_format(LispReader& reader) tilemap->set(width, height, tiles, LAYER_TILES, true); solids = tilemap; add_object(tilemap); + + // hack for now... + for(size_t x=0; x < solids->get_width(); ++x) { + for(size_t y=0; y < solids->get_height(); ++y) { + const Tile* tile = solids->get_tile(x, y); + + if(tile->attributes & Tile::COIN) { + Coin* coin = new Coin(Vector(x*32, y*32)); + add_object(coin); + solids->change(x, y, 0); + } else if(tile->attributes & Tile::FULLBOX) { + BonusBlock* block = new BonusBlock(Vector(x*32, y*32), tile->data); + add_object(block); + solids->change(x, y, 0); + } else if(tile->attributes & Tile::BRICK) { + Brick* brick = new Brick(Vector(x*32, y*32), tile->data); + add_object(brick); + solids->change(x, y, 0); + } else if(tile->attributes & Tile::GOAL) { + SequenceTrigger* trigger = new SequenceTrigger(Vector(x*32, y*32), + "endsequence"); + add_object(trigger); + solids->change(x, y, 0); + } + } + } } if(reader.read_int_vector("background-tm", tiles)) { @@ -289,18 +346,14 @@ Sector::parse_old_format(LispReader& reader) std::string object_type = lisp_symbol(lisp_car(data)); LispReader reader(lisp_cdr(data)); - - if(object_type == "trampoline") { - add_object(new Trampoline(reader)); - } - else if(object_type == "flying-platform") { - add_object(new FlyingPlatform(reader)); - } - else { - BadGuyKind kind = badguykind_from_string(object_type); - add_object(new BadGuy(kind, reader)); + + GameObject* object = parseObject(object_type, reader); + if(object) { + add_object(object); + } else { + std::cerr << "Unknown object '" << object_type << "' in level.\n"; } - + cur = lisp_cdr(cur); } } @@ -341,6 +394,8 @@ Sector::write(LispWriter& writer) void Sector::do_vertical_flip() { + // remove or fix later +#if 0 for(GameObjects::iterator i = gameobjects_new.begin(); i != gameobjects_new.end(); ++i) { TileMap* tilemap = dynamic_cast (*i); @@ -368,11 +423,28 @@ Sector::do_vertical_flip() SpawnPoint* spawn = *i; spawn->pos.y = solids->get_height()*32 - spawn->pos.y - 32; } +#endif } void Sector::add_object(GameObject* object) { + // make sure the object isn't already in the list +#ifdef DEBUG + for(GameObjects::iterator i = gameobjects.begin(); i != gameobjects.end(); + ++i) { + if(*i == object) { + assert("object already added to sector" == 0); + } + } + for(GameObjects::iterator i = gameobjects_new.begin(); + i != gameobjects_new.end(); ++i) { + if(*i == object) { + assert("object already added to sector" == 0); + } + } +#endif + gameobjects_new.push_back(object); } @@ -410,23 +482,23 @@ Sector::activate(const std::string& spawnpoint) player->move(sp->pos); } - camera->reset(Vector(player->base.x, player->base.y)); + camera->reset(player->get_pos()); } Vector Sector::get_best_spawn_point(Vector pos) { -Vector best_reset_point = Vector(-1,-1); + Vector best_reset_point = Vector(-1,-1); -for(SpawnPoints::iterator i = spawnpoints.begin(); i != spawnpoints.end(); + for(SpawnPoints::iterator i = spawnpoints.begin(); i != spawnpoints.end(); ++i) { - if((*i)->name != "main") - continue; - if((*i)->pos.x > best_reset_point.x && (*i)->pos.x < pos.x) - best_reset_point = (*i)->pos; + if((*i)->name != "main") + continue; + if((*i)->pos.x > best_reset_point.x && (*i)->pos.x < pos.x) + best_reset_point = (*i)->pos; } -return best_reset_point; + return best_reset_point; } void @@ -434,12 +506,15 @@ Sector::action(float elapsed_time) { player->check_bounds(camera); - /* update objects (don't use iterators here, because the list might change - * during the iteration) - */ - for(size_t i = 0; i < gameobjects.size(); ++i) - if(gameobjects[i]->is_valid()) - gameobjects[i]->action(elapsed_time); + /* update objects */ + for(GameObjects::iterator i = gameobjects.begin(); + i != gameobjects.end(); ++i) { + GameObject* object = *i; + if(!object->is_valid()) + continue; + + object->action(elapsed_time); + } /* Handle all possible collisions. */ collision_handler(); @@ -454,17 +529,13 @@ Sector::update_game_objects() for(std::vector::iterator i = gameobjects.begin(); i != gameobjects.end(); /* nothing */) { if((*i)->is_valid() == false) { - BadGuy* badguy = dynamic_cast (*i); - if(badguy) { - badguys.erase(std::remove(badguys.begin(), badguys.end(), badguy), - badguys.end()); - } Bullet* bullet = dynamic_cast (*i); if(bullet) { bullets.erase( std::remove(bullets.begin(), bullets.end(), bullet), bullets.end()); } +#if 0 InteractiveObject* interactive_object = dynamic_cast (*i); if(interactive_object) { @@ -472,37 +543,7 @@ Sector::update_game_objects() std::remove(interactive_objects.begin(), interactive_objects.end(), interactive_object), interactive_objects.end()); } - Upgrade* upgrade = dynamic_cast (*i); - if(upgrade) { - upgrades.erase( - std::remove(upgrades.begin(), upgrades.end(), upgrade), - upgrades.end()); - } - Trampoline* trampoline = dynamic_cast (*i); - if(trampoline) { - trampolines.erase( - std::remove(trampolines.begin(), trampolines.end(), trampoline), - trampolines.end()); - } - FlyingPlatform* flying_platform= dynamic_cast (*i); - if(flying_platform) { - flying_platforms.erase( - std::remove(flying_platforms.begin(), flying_platforms.end(), flying_platform), - flying_platforms.end()); - } - SmokeCloud* smoke_cloud = dynamic_cast (*i); - if(smoke_cloud) { - smoke_clouds.erase( - std::remove(smoke_clouds.begin(), smoke_clouds.end(), smoke_cloud), - smoke_clouds.end()); - } - Particles* particle = dynamic_cast (*i); - if(particle) { - particles.erase( - std::remove(particles.begin(), particles.end(), particle), - particles.end()); - } - +#endif delete *i; i = gameobjects.erase(i); } else { @@ -514,31 +555,15 @@ Sector::update_game_objects() for(std::vector::iterator i = gameobjects_new.begin(); i != gameobjects_new.end(); ++i) { - BadGuy* badguy = dynamic_cast (*i); - if(badguy) - badguys.push_back(badguy); Bullet* bullet = dynamic_cast (*i); if(bullet) bullets.push_back(bullet); - Upgrade* upgrade = dynamic_cast (*i); - if(upgrade) - upgrades.push_back(upgrade); - Trampoline* trampoline = dynamic_cast (*i); - if(trampoline) - trampolines.push_back(trampoline); - FlyingPlatform* flying_platform = dynamic_cast (*i); - if(flying_platform) - flying_platforms.push_back(flying_platform); +#if 0 InteractiveObject* interactive_object = dynamic_cast (*i); if(interactive_object) interactive_objects.push_back(interactive_object); - SmokeCloud* smoke_cloud = dynamic_cast (*i); - if(smoke_cloud) - smoke_clouds.push_back(smoke_cloud); - Particles* particle = dynamic_cast (*i); - if(particle) - particles.push_back(particle); +#endif gameobjects.push_back(*i); } @@ -553,199 +578,198 @@ Sector::draw(DrawingContext& context) for(GameObjects::iterator i = gameobjects.begin(); i != gameobjects.end(); ++i) { - if( (*i)->is_valid() ) - (*i)->draw(context); + GameObject* object = *i; + if(!object->is_valid()) + continue; + + object->draw(context); } context.pop_transform(); } void -Sector::collision_handler() +Sector::collision_tilemap(MovingObject* object, int depth) { - // CO_BULLET & CO_BADGUY check - for(unsigned int i = 0; i < bullets.size(); ++i) - { - for (BadGuys::iterator j = badguys.begin(); j != badguys.end(); ++j) - { - if((*j)->dying != DYING_NOT) - continue; - - if(rectcollision(bullets[i]->base, (*j)->base)) - { - // We have detected a collision and now call the - // collision functions of the collided objects. - (*j)->collision(bullets[i], CO_BULLET, COLLISION_NORMAL); - bullets[i]->collision(CO_BADGUY); - break; // bullet is invalid now, so break - } - } - } - - /* CO_BADGUY & CO_BADGUY check */ - for (BadGuys::iterator i = badguys.begin(); i != badguys.end(); ++i) - { - if((*i)->dying != DYING_NOT) + if(depth >= 4) { +#ifdef DEBUG + std::cout << "Max collision depth reached.\n"; +#endif + object->movement = Vector(0, 0); + return; + } + + // calculate rectangle where the object will move + float x1, x2; + if(object->get_movement().x >= 0) { + x1 = object->get_pos().x; + x2 = object->get_bbox().p2.x + object->get_movement().x; + } else { + x1 = object->get_pos().x + object->get_movement().x; + x2 = object->get_bbox().p2.x; + } + float y1, y2; + if(object->get_movement().y >= 0) { + y1 = object->get_pos().y; + y2 = object->get_bbox().p2.y + object->get_movement().y; + } else { + y1 = object->get_pos().y + object->get_movement().y; + y2 = object->get_bbox().p2.y; + } + + // test with all tiles in this rectangle + int starttilex = int(x1-1) / 32; + int starttiley = int(y1-1) / 32; + int max_x = int(x2+1); + int max_y = int(y2+1); + + CollisionHit temphit, hit; + Rectangle dest = object->get_bbox(); + dest.move(object->movement); + hit.depth = -1; + for(int x = starttilex; x*32 < max_x; ++x) { + for(int y = starttiley; y*32 < max_y; ++y) { + const Tile* tile = solids->get_tile(x, y); + if(!tile) continue; - - BadGuys::iterator j = i; - ++j; - for (; j != badguys.end(); ++j) - { - if(j == i || (*j)->dying != DYING_NOT) - continue; - - if(rectcollision((*i)->base, (*j)->base)) - { - // We have detected a collision and now call the - // collision functions of the collided objects. - (*j)->collision(*i, CO_BADGUY); - (*i)->collision(*j, CO_BADGUY); - } - } - } - if(player->dying != DYING_NOT) return; - - // CO_BADGUY & CO_PLAYER check - for (BadGuys::iterator i = badguys.begin(); i != badguys.end(); ++i) - { - if((*i)->dying != DYING_NOT) + if(!(tile->attributes & Tile::SOLID)) continue; - - if(rectcollision_offset((*i)->base, player->base, 0, 0)) - { - // We have detected a collision and now call the collision - // functions of the collided objects. - if (player->previous_base.y < player->base.y && - player->previous_base.y + player->previous_base.height - < (*i)->base.y + (*i)->base.height/2 - && !player->invincible_timer.started()) - { - (*i)->collision(player, CO_PLAYER, COLLISION_SQUISH); - } - else - { - player->collision(*i, CO_BADGUY); - (*i)->collision(player, CO_PLAYER, COLLISION_NORMAL); - } + if((tile->attributes & Tile::UNISOLID) && object->movement.y < 0) + continue; + + if(tile->attributes & Tile::SLOPE) { // slope tile + AATriangle triangle; + Vector p1(x*32, y*32); + Vector p2((x+1)*32, (y+1)*32); + switch(tile->data) { + case 0: + triangle = AATriangle(p1, p2, AATriangle::SOUTHWEST); + break; + case 1: + triangle = AATriangle(p1, p2, AATriangle::NORTHEAST); + break; + case 2: + triangle = AATriangle(p1, p2, AATriangle::SOUTHEAST); + break; + case 3: + triangle = AATriangle(p1, p2, AATriangle::NORTHWEST); + break; + default: + printf("Invalid slope angle in tile %d !\n", tile->id); + break; } - } - - // CO_UPGRADE & CO_PLAYER check - for(unsigned int i = 0; i < upgrades.size(); ++i) - { - if(rectcollision(upgrades[i]->base, player->base)) - { - // We have detected a collision and now call the collision - // functions of the collided objects. - upgrades[i]->collision(player, CO_PLAYER, COLLISION_NORMAL); + + if(Collision::rectangle_aatriangle(temphit, dest, triangle)) { + if(temphit.depth > hit.depth) + hit = temphit; + } + } else { // normal rectangular tile + Rectangle rect(x*32, y*32, (x+1)*32, (y+1)*32); + if(Collision::rectangle_rectangle(temphit, dest, rect)) { + if(temphit.depth > hit.depth) + hit = temphit; } - } - - // CO_TRAMPOLINE & (CO_PLAYER or CO_BADGUY) - for (Trampolines::iterator i = trampolines.begin(); i != trampolines.end(); ++i) - { - if (rectcollision((*i)->base, player->base)) - { - if (player->previous_base.y < player->base.y && - player->previous_base.y + player->previous_base.height - < (*i)->base.y + (*i)->base.height/2) - { - (*i)->collision(player, CO_PLAYER, COLLISION_SQUISH); - } - else if (player->previous_base.y <= player->base.y) - { - player->collision(*i, CO_TRAMPOLINE); - (*i)->collision(player, CO_PLAYER, COLLISION_NORMAL); } } } - - // CO_FLYING_PLATFORM & (CO_PLAYER or CO_BADGUY) - for (FlyingPlatforms::iterator i = flying_platforms.begin(); i != flying_platforms.end(); ++i) - { - if (rectcollision((*i)->base, player->base)) - { - if (player->previous_base.y < player->base.y && - player->previous_base.y + player->previous_base.height - < (*i)->base.y + (*i)->base.height/2) - { - (*i)->collision(player, CO_PLAYER, COLLISION_SQUISH); - player->collision(*i, CO_FLYING_PLATFORM); - } -/* else if (player->previous_base.y <= player->base.y) - { - }*/ - } + + // did we collide at all? + if(hit.depth == -1) + return; + + // call collision function + HitResponse response = object->collision(*solids, hit); + if(response == ABORT_MOVE) { + object->movement = Vector(0, 0); + return; + } + if(response == FORCE_MOVE) { + return; } + // move out of collision and try again + object->movement += hit.normal * (hit.depth + .001); + collision_tilemap(object, depth+1); } void -Sector::add_score(const Vector& pos, int s) -{ - global_stats.add_points(SCORE_STAT, s); - - add_object(new FloatingText(pos, s)); -} - -void -Sector::add_bouncy_distro(const Vector& pos) -{ - add_object(new BouncyDistro(pos)); -} - -void -Sector::add_broken_brick(const Vector& pos, Tile* tile) -{ - add_broken_brick_piece(pos, Vector(-1, -4), tile); - add_broken_brick_piece(pos + Vector(0, 16), Vector(-1.5, -3), tile); - - add_broken_brick_piece(pos + Vector(16, 0), Vector(1, -4), tile); - add_broken_brick_piece(pos + Vector(16, 16), Vector(1.5, -3), tile); -} - -void -Sector::add_broken_brick_piece(const Vector& pos, const Vector& movement, - Tile* tile) -{ - add_object(new BrokenBrick(tile, pos, movement)); +Sector::collision_object(MovingObject* object1, MovingObject* object2) +{ + CollisionHit hit; + Rectangle dest1 = object1->get_bbox(); + dest1.move(object1->get_movement()); + Rectangle dest2 = object2->get_bbox(); + dest2.move(object2->get_movement()); + if(Collision::rectangle_rectangle(hit, dest1, dest2)) { + HitResponse response = object1->collision(*object2, hit); + if(response == ABORT_MOVE) { + object1->movement = Vector(0, 0); + } else if(response == CONTINUE) { + object1->movement += hit.normal * (hit.depth/2 + .001); + } + hit.normal *= -1; + response = object2->collision(*object1, hit); + if(response == ABORT_MOVE) { + object2->movement = Vector(0, 0); + } else if(response == CONTINUE) { + object2->movement += hit.normal * (hit.depth/2 + .001); + } + } } - + void -Sector::add_bouncy_brick(const Vector& pos) +Sector::collision_handler() { - add_object(new BouncyBrick(pos)); -} + for(std::vector::iterator i = gameobjects.begin(); + i != gameobjects.end(); ++i) { + GameObject* gameobject = *i; + if(!gameobject->is_valid() + || gameobject->get_flags() & GameObject::FLAG_NO_COLLDET) + continue; + MovingObject* movingobject = dynamic_cast (gameobject); + if(!movingobject) + continue; + + // collision with tilemap + if(! (movingobject->movement == Vector(0, 0))) + collision_tilemap(movingobject, 0); + + // collision with other objects + for(std::vector::iterator i2 = i+1; + i2 != gameobjects.end(); ++i2) { + GameObject* other_object = *i2; + if(!other_object->is_valid() + || other_object->get_flags() & GameObject::FLAG_NO_COLLDET) + continue; + MovingObject* movingobject2 = dynamic_cast (other_object); + if(!movingobject2) + continue; -BadGuy* -Sector::add_bad_guy(float x, float y, BadGuyKind kind, bool activate) -{ - BadGuy* badguy = new BadGuy(kind, x, y); - add_object(badguy); - if(activate) - badguy->activate(LEFT); - return badguy; + collision_object(movingobject, movingobject2); + } + + movingobject->bbox.move(movingobject->get_movement()); + movingobject->movement = Vector(0, 0); + } } - + void -Sector::add_upgrade(const Vector& pos, Direction dir, UpgradeKind kind) +Sector::add_score(const Vector& pos, int s) { - add_object(new Upgrade(pos, dir, kind)); + global_stats.add_points(SCORE_STAT, s); + + add_object(new FloatingText(pos, s)); } bool Sector::add_bullet(const Vector& pos, float xm, Direction dir) { - if(player->got_power == Player::FIRE_POWER) - { + if(player->got_power == Player::FIRE_POWER) { if(bullets.size() > MAX_FIRE_BULLETS-1) return false; - } - else if(player->got_power == Player::ICE_POWER) - { + } else if(player->got_power == Player::ICE_POWER) { if(bullets.size() > MAX_ICE_BULLETS-1) return false; - } + } Bullet* new_bullet = 0; if(player->got_power == Player::FIRE_POWER) @@ -757,7 +781,7 @@ Sector::add_bullet(const Vector& pos, float xm, Direction dir) add_object(new_bullet); SoundManager::get()->play_sound(IDToSound(SND_SHOOT)); - + return true; } @@ -781,197 +805,6 @@ Sector::add_floating_text(const Vector& pos, const std::string& text) add_object(new FloatingText(pos, text)); } -/* Break a brick: */ -bool -Sector::trybreakbrick(const Vector& pos, bool small) -{ - Tile* tile = solids->get_tile_at(pos); - if (!tile) - { - char errmsg[64]; - sprintf(errmsg, "Invalid tile at %i,%i", (int)((pos.x+1)/32*32), (int)((pos.y+1)/32*32)); - throw SuperTuxException(errmsg, __FILE__, __LINE__); - } - - if (tile->attributes & Tile::BRICK) - { - if (tile->data > 0) - { - /* Get a distro from it: */ - add_bouncy_distro( - Vector(((int)(pos.x + 1) / 32) * 32, (int)(pos.y / 32) * 32)); - - // TODO: don't handle this in a global way but per-tile... - if (!counting_distros) - { - counting_distros = true; - distro_counter = 5; - } - else - { - distro_counter--; - } - - if (distro_counter <= 0) - { - counting_distros = false; - solids->change_at(pos, tile->next_tile); - } - - SoundManager::get()->play_sound(IDToSound(SND_DISTRO)); - global_stats.add_points(SCORE_STAT, SCORE_DISTRO); - global_stats.add_points(COINS_COLLECTED_STAT, 1); - player_status.distros++; - return true; - } - else if (!small) - { - /* Get rid of it: */ - solids->change_at(pos, tile->next_tile); - - /* Replace it with broken bits: */ - add_broken_brick(Vector( - ((int)(pos.x + 1) / 32) * 32, - (int)(pos.y / 32) * 32), tile); - - /* Get some score: */ - SoundManager::get()->play_sound(IDToSound(SND_BRICK)); - global_stats.add_points(SCORE_STAT, SCORE_BRICK); - - return true; - } - } - - return false; -} - -/* Empty a box: */ -void -Sector::tryemptybox(const Vector& pos, Direction col_side) -{ - Tile* tile = solids->get_tile_at(pos); - if (!tile) - { - char errmsg[64]; - sprintf(errmsg, "Invalid tile at %i,%i", (int)((pos.x+1)/32*32), (int)((pos.y+1)/32*32)); - throw SuperTuxException(errmsg, __FILE__, __LINE__); - } - - - if (!(tile->attributes & Tile::FULLBOX)) - return; - - // according to the collision side, set the upgrade direction - if(col_side == LEFT) - col_side = RIGHT; - else - col_side = LEFT; - - int posx = ((int)(pos.x+1) / 32) * 32; - int posy = (int)(pos.y/32) * 32 - 32; - switch(tile->data) - { - case 1: // Box with a distro! - add_bouncy_distro(Vector(posx, posy)); - SoundManager::get()->play_sound(IDToSound(SND_DISTRO)); - global_stats.add_points(SCORE_STAT, SCORE_DISTRO); - global_stats.add_points(COINS_COLLECTED_STAT, 1); - player_status.distros++; - break; - - case 2: // Add a fire flower upgrade! - if (player->size == SMALL) /* Tux is small, add mints! */ - add_upgrade(Vector(posx, posy), col_side, UPGRADE_GROWUP); - else /* Tux is big, add a fireflower: */ - add_upgrade(Vector(posx, posy), col_side, UPGRADE_FIREFLOWER); - SoundManager::get()->play_sound(IDToSound(SND_UPGRADE)); - break; - - case 5: // Add an ice flower upgrade! - if (player->size == SMALL) /* Tux is small, add mints! */ - add_upgrade(Vector(posx, posy), col_side, UPGRADE_GROWUP); - else /* Tux is big, add an iceflower: */ - add_upgrade(Vector(posx, posy), col_side, UPGRADE_ICEFLOWER); - SoundManager::get()->play_sound(IDToSound(SND_UPGRADE)); - break; - - case 3: // Add a golden herring - add_upgrade(Vector(posx, posy), col_side, UPGRADE_STAR); - break; - - case 4: // Add a 1up extra - add_upgrade(Vector(posx, posy), col_side, UPGRADE_1UP); - break; - default: - break; - } - - /* Empty the box: */ - solids->change_at(pos, tile->next_tile); -} - -/* Try to grab a distro: */ -void -Sector::trygrabdistro(const Vector& pos, int bounciness) -{ - Tile* tile = solids->get_tile_at(pos); - if (!tile) - { - /*char errmsg[64]; - sprintf(errmsg, "Invalid tile at %i,%i", (int)((pos.x+1)/32*32), (int)((pos.y+1)/32*32)); - throw SuperTuxException(errmsg, __FILE__, __LINE__); */ - - //Bad tiles (i.e. tiles that are not defined in supertux.stgt but appear in the map) are changed to ID 0 (blank tile) - std::cout << "Warning: Undefined tile at " <<(int)pos.x/32 << "/" << (int)pos.y/32 << " (ID: " << (int)solids->get_tile_id_at(pos).id << ")" << std::endl; - solids->change_at(pos,0); - tile = solids->get_tile_at(pos); - } - - - if (!(tile->attributes & Tile::COIN)) - return; - - solids->change_at(pos, tile->next_tile); - SoundManager::get()->play_sound(IDToSound(SND_DISTRO)); - - if (bounciness == BOUNCE) - { - add_bouncy_distro(Vector(((int)(pos.x + 1) / 32) * 32, - (int)(pos.y / 32) * 32)); - } - - global_stats.add_points(SCORE_STAT, SCORE_DISTRO); - global_stats.add_points(COINS_COLLECTED_STAT, 1); - player_status.distros++; - -} - -/* Try to bump a bad guy from below: */ -void -Sector::trybumpbadguy(const Vector& pos) -{ - // Bad guys: - for (BadGuys::iterator i = badguys.begin(); i != badguys.end(); ++i) - { - if ((*i)->base.x >= pos.x - 32 && (*i)->base.x <= pos.x + 32 && - (*i)->base.y >= pos.y - 16 && (*i)->base.y <= pos.y + 16) - { - (*i)->collision(player, CO_PLAYER, COLLISION_BUMP); - } - } - - // Upgrades: - for (unsigned int i = 0; i < upgrades.size(); i++) - { - if (upgrades[i]->base.height == 32 && - upgrades[i]->base.x >= pos.x - 32 && upgrades[i]->base.x <= pos.x + 32 && - upgrades[i]->base.y >= pos.y - 16 && upgrades[i]->base.y <= pos.y + 16) - { - upgrades[i]->collision(player, CO_PLAYER, COLLISION_BUMP); - } - } -} - void Sector::load_music() { @@ -1025,11 +858,24 @@ int Sector::get_total_badguys() { int total_badguys = 0; +#if 0 for(GameObjects::iterator i = gameobjects_new.begin(); i != gameobjects_new.end(); ++i) { BadGuy* badguy = dynamic_cast (*i); if(badguy) total_badguys++; } +#endif return total_badguys; } + +bool +Sector::inside(const Rectangle& rect) const +{ + if(rect.p1.x > solids->get_width() * 32 + || rect.p1.y > solids->get_height() * 32 + || rect.p2.x < 0 || rect.p2.y < 0) + return false; + + return true; +} diff --git a/src/sector.h b/src/sector.h index 21a9c028e..05595abd0 100644 --- a/src/sector.h +++ b/src/sector.h @@ -25,7 +25,6 @@ #include "math/vector.h" #include "badguy.h" -#include "special.h" #include "audio/musicref.h" #include "video/drawing_context.h" @@ -34,6 +33,7 @@ using namespace SuperTux; namespace SuperTux { class GameObject; class LispReader; +class Sprite; } class InteractiveObject; @@ -56,11 +56,6 @@ struct SpawnPoint Vector pos; }; -enum { - NONE_ENDSEQ_ANIM, - FIREWORKS_ENDSEQ_ANIM - }; - /** This class holds a sector (a part of a level) and all the game objects * (badguys, player, background, tilemap, ...) */ @@ -94,6 +89,9 @@ public: const std::string& get_name() const { return name; } + /// tests if a given rectangle is inside the sector + bool inside(const Rectangle& rectangle) const; + void play_music(int musictype); int get_music_type(); @@ -101,52 +99,33 @@ public: collision_handlers, which the collision_objects provide for this case (or not). */ void collision_handler(); - + void add_score(const Vector& pos, int s); - void add_bouncy_distro(const Vector& pos); - void add_broken_brick(const Vector& pos, Tile* tile); - void add_broken_brick_piece(const Vector& pos, - const Vector& movement, Tile* tile); - void add_bouncy_brick(const Vector& pos); - - BadGuy* add_bad_guy(float x, float y, BadGuyKind kind, bool activate); - - void add_upgrade(const Vector& pos, Direction dir, UpgradeKind kind); + bool add_bullet(const Vector& pos, float xm, Direction dir); bool add_smoke_cloud(const Vector& pos); - bool add_particles(const Vector& epicenter, int min_angle, int max_angle, const Vector& initial_velocity, const Vector& acceleration, int number, Color color, int size, int life_time, int drawing_layer); + bool add_particles(const Vector& epicenter, int min_angle, int max_angle, + const Vector& initial_velocity, const Vector& acceleration, int number, + Color color, int size, int life_time, int drawing_layer); void add_floating_text(const Vector& pos, const std::string& text); - /** Try to grab the coin at the given coordinates */ - void trygrabdistro(const Vector& pos, int bounciness); - - /** Try to break the brick at the given coordinates */ - bool trybreakbrick(const Vector& pos, bool small); - - /** Try to get the content out of a bonus box, thus emptying it */ - void tryemptybox(const Vector& pos, Direction col_side); - - /** Try to bumb a badguy that might we walking above Tux, thus shaking - the tile which the badguy is walking on an killing him this way */ - void trybumpbadguy(const Vector& pos); - /** Flip the all the sector vertically. The purpose of this is to let player to play the same level in a different way :) */ void do_vertical_flip(); - /** Get end sequence animation */ - int end_sequence_animation() - { return end_sequence_animation_type; } - - /** @evil@ */ + /** @evil@ but can#t always be avoided in current design... */ static Sector* current() { return _current; } - /** Get total number of some stuff */ + /** Get total number of badguys */ int get_total_badguys(); private: + void collision_tilemap(MovingObject* object, int depth); + void collision_object(MovingObject* object1, MovingObject* object2); + void load_music(); + GameObject* parseObject(const std::string& name, LispReader& reader); static Sector* _current; @@ -155,8 +134,6 @@ private: MusicRef level_song; MusicRef level_song_fast; - int end_sequence_animation_type; - public: std::string song_title; float gravity; @@ -168,31 +145,21 @@ public: Camera* camera; private: - typedef std::vector BadGuys; - BadGuys badguys; - typedef std::vector Trampolines; - Trampolines trampolines; - typedef std::vector FlyingPlatforms; - FlyingPlatforms flying_platforms; - - std::vector upgrades; std::vector bullets; - std::vector smoke_clouds; - std::vector particles; -public: // ugly +public: // TODO make this private again typedef std::vector InteractiveObjects; InteractiveObjects interactive_objects; typedef std::vector GameObjects; GameObjects gameobjects; - GameObjects gameobjects_new; // For newly created objects private: + /// container for newly created objects, they'll be added in Sector::action + GameObjects gameobjects_new; + typedef std::vector SpawnPoints; SpawnPoints spawnpoints; - int distro_counter; - bool counting_distros; int currentmusic; }; diff --git a/src/special.cpp b/src/special.cpp deleted file mode 100644 index 8d698151d..000000000 --- a/src/special.cpp +++ /dev/null @@ -1,385 +0,0 @@ -// $Id$ -// -// SuperTux - A Jump'n Run -// Copyright (C) 2003 Tobias Glaesser -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#include -#include - -#include "SDL.h" - -#include "defines.h" -#include "special.h" -#include "camera.h" -#include "gameloop.h" -#include "video/screen.h" -#include "scene.h" -#include "app/globals.h" -#include "player.h" -#include "sector.h" -#include "special/sprite_manager.h" -#include "resources.h" - -Sprite* img_firebullet; -Sprite* img_icebullet; -Sprite* img_star; -Sprite* img_growup; -Sprite* img_iceflower; -Sprite* img_fireflower; -Sprite* img_1up; - -#define GROWUP_SPEED 1.0f - -#define BULLET_STARTING_YM 0 -#define BULLET_XM 6 - -Bullet::Bullet(const Vector& pos, float xm, int dir, int kind_) -{ - life_count = 3; - base.width = 4; - base.height = 4; - - if (kind == ICE_BULLET) - life_count = 6; //ice-bullets get "extra lives" for bumping off walls - - if (dir == RIGHT) - { - base.x = pos.x + 32; - physic.set_velocity_x(BULLET_XM + xm); - } - else - { - base.x = pos.x; - physic.set_velocity_x(-BULLET_XM + xm); - } - - base.y = pos.y; - physic.set_velocity_y(-BULLET_STARTING_YM); - old_base = base; - kind = kind_; -} - -void -Bullet::action(float elapsed_time) -{ - elapsed_time *= 0.5f; - - float old_y = base.y; - - physic.apply(elapsed_time, base.x, base.y, Sector::current()->gravity); - collision_swept_object_map(&old_base,&base); - - if (issolid(base.x+2, base.y + 4) || issolid(base.x+2, base.y)) - { - base.y = old_y; - physic.set_velocity_y(-physic.get_velocity_y()); - life_count -= 1; - } - - if(kind == FIRE_BULLET) - // @not framerate independant :-/ - physic.set_velocity_y(physic.get_velocity_y() - 0.5 * elapsed_time); - if(physic.get_velocity_y() > 9) - physic.set_velocity_y(9); - else if(physic.get_velocity_y() < -9) - physic.set_velocity_y(-9); - - float scroll_x = - Sector::current()->camera->get_translation().x; - float scroll_y = - Sector::current()->camera->get_translation().y; - if (base.x < scroll_x || - base.x > scroll_x + screen->w || -// base.y < scroll_y || - base.y > scroll_y + screen->h || - life_count <= 0) - { - remove_me(); - } - if (issolid(base.x + 4, base.y + 2) || - issolid(base.x, base.y + 2)) - { - if (kind == FIRE_BULLET) - remove_me(); - else if (kind == ICE_BULLET) - { - physic.set_velocity_x(-physic.get_velocity_x()); - //physic.set_velocity_y(-physic.get_velocity_y()); - } - } -} - -void -Bullet::draw(DrawingContext& context) -{ - Sprite* sprite = kind == FIRE_BULLET ? img_firebullet : img_icebullet; - - sprite->draw(context, Vector(base.x, base.y), LAYER_OBJECTS); -} - -void -Bullet::collision(const MovingObject& , int) -{ - // later -} - -void -Bullet::collision(int c_object) -{ - if(c_object == CO_BADGUY) { - remove_me(); - } -} - -//--------------------------------------------------------------------------- - -Upgrade::Upgrade(const Vector& pos, Direction dir_, UpgradeKind kind_) -{ - kind = kind_; - dir = dir_; - - base.width = 32; - base.height = 0; - base.x = pos.x; - base.y = pos.y; - old_base = base; - - physic.reset(); - physic.enable_gravity(false); - - if(kind == UPGRADE_1UP || kind == UPGRADE_STAR) { - physic.set_velocity(dir == LEFT ? -1 : 1, 4); - physic.enable_gravity(true); - base.height = 32; - } else if (kind == UPGRADE_ICEFLOWER || kind == UPGRADE_FIREFLOWER) { - // nothing - } else if (kind == UPGRADE_GROWUP) { - physic.set_velocity(dir == LEFT ? -GROWUP_SPEED : GROWUP_SPEED, 0); - } else { - physic.set_velocity(dir == LEFT ? -2 : 2, 0); - } -} - -Upgrade::~Upgrade() -{ -} - -void -Upgrade::action(float elapsed_time) -{ - if (kind == UPGRADE_ICEFLOWER || kind == UPGRADE_FIREFLOWER - || kind == UPGRADE_GROWUP) { - if (base.height < 32) { - /* Rise up! */ - base.height = base.height + 0.7 * elapsed_time; - if(base.height > 32) - base.height = 32; - - return; - } - } - - /* Away from the screen? Kill it! */ - float scroll_x = - Sector::current()->camera->get_translation().x; - float scroll_y = - Sector::current()->camera->get_translation().y; - - if(base.x < scroll_x - X_OFFSCREEN_DISTANCE || - base.x > scroll_x + screen->w + X_OFFSCREEN_DISTANCE || - base.y < scroll_y - Y_OFFSCREEN_DISTANCE || - base.y > scroll_y + screen->h + Y_OFFSCREEN_DISTANCE) - { - remove_me(); - return; - } - - /* Move around? */ - physic.apply(elapsed_time, base.x, base.y, Sector::current()->gravity); - if(kind == UPGRADE_GROWUP || kind == UPGRADE_STAR) { - collision_swept_object_map(&old_base, &base); - } - - // fall down? - if(kind == UPGRADE_GROWUP || kind == UPGRADE_STAR) { - // falling? - if(physic.get_velocity_y() != 0) { - if(issolid(base.x, base.y + base.height)) { - base.y = int(base.y / 32) * 32; - old_base = base; - if(kind == UPGRADE_GROWUP) { - physic.enable_gravity(false); - physic.set_velocity(dir == LEFT ? -GROWUP_SPEED : GROWUP_SPEED, 0); - } else if(kind == UPGRADE_STAR) { - physic.set_velocity(dir == LEFT ? -2 : 2, 3); - } - } - } else { - if((physic.get_velocity_x() < 0 - && !issolid(base.x+base.width, base.y + base.height)) - || (physic.get_velocity_x() > 0 - && !issolid(base.x, base.y + base.height))) { - physic.enable_gravity(true); - } - } - } - - // horizontal bounce? - if(kind == UPGRADE_GROWUP || kind == UPGRADE_STAR) { - if ( (physic.get_velocity_x() < 0 - && issolid(base.x, (int) base.y + base.height/2)) - || (physic.get_velocity_x() > 0 - && issolid(base.x + base.width, (int) base.y + base.height/2))) { - physic.set_velocity(-physic.get_velocity_x(),physic.get_velocity_y()); - dir = dir == LEFT ? RIGHT : LEFT; - } - } -} - -void -Upgrade::draw(DrawingContext& context) -{ - Sprite* sprite; - switch(kind) { - case UPGRADE_GROWUP: sprite = img_growup; break; - case UPGRADE_ICEFLOWER: sprite = img_iceflower; break; - case UPGRADE_FIREFLOWER: sprite = img_fireflower; break; - case UPGRADE_STAR: sprite = img_star; break; - case UPGRADE_1UP: sprite = img_1up; break; - default: - assert(!"wrong type in Powerup::draw()"); - sprite = NULL; // added by neoneurone, g++ likes this ! - } - - if(base.height < 32) // still raising up? - sprite->draw(context, Vector(base.x, base.y + (32 - base.height)), - LAYER_TILES - 10); - else - sprite->draw(context, Vector(base.x, base.y), LAYER_OBJECTS); -} - -void -Upgrade::bump(Player* player) -{ - // these can't be bumped - if(kind != UPGRADE_GROWUP) - return; - - SoundManager::get()->play_sound(IDToSound(SND_BUMP_UPGRADE), Vector(base.x, base.y), Sector::current()->player->get_pos()); - - // determine new direction - Direction old_dir = dir; - if (player->base.x + player->base.width/2 > base.x + base.width/2) - dir = LEFT; - else - dir = RIGHT; - - // do a little jump and change direction (if necessary) - if (dir != old_dir) - physic.set_velocity(-physic.get_velocity_x(), 3); - else - physic.set_velocity_y(3); - - physic.enable_gravity(true); -} - -void -Upgrade::collision(const MovingObject& , int) -{ - // later -} - -void -Upgrade::collision(void* p_c_object, int c_object, CollisionType type) -{ - Player* pplayer = NULL; - - if(type == COLLISION_BUMP) { - if(c_object == CO_PLAYER) - pplayer = (Player*) p_c_object; - bump(pplayer); - return; - } - - switch (c_object) - { - case CO_PLAYER: - /* Remove the upgrade: */ - - /* p_c_object is CO_PLAYER, so assign it to pplayer */ - pplayer = (Player*) p_c_object; - - /* Affect the player: */ - - if (kind == UPGRADE_GROWUP) - { - SoundManager::get()->play_sound(IDToSound(SND_EXCELLENT)); - pplayer->grow(true); - } - else if (kind == UPGRADE_FIREFLOWER) - { - SoundManager::get()->play_sound(IDToSound(SND_COFFEE)); - pplayer->grow(true); - pplayer->got_power = pplayer->FIRE_POWER; - } - else if (kind == UPGRADE_ICEFLOWER) - { - SoundManager::get()->play_sound(IDToSound(SND_COFFEE)); - pplayer->grow(true); - pplayer->got_power = pplayer->ICE_POWER; - } - else if (kind == UPGRADE_FIREFLOWER) - { - SoundManager::get()->play_sound(IDToSound(SND_COFFEE)); - pplayer->grow(true); - pplayer->got_power = pplayer->FIRE_POWER; - } - else if (kind == UPGRADE_STAR) - { - SoundManager::get()->play_sound(IDToSound(SND_HERRING)); - pplayer->invincible_timer.start(TUX_INVINCIBLE_TIME); - Sector::current()->play_music(HERRING_MUSIC); - } - else if (kind == UPGRADE_1UP) - { - if(player_status.lives < MAX_LIVES) { - player_status.lives++; - SoundManager::get()->play_sound(IDToSound(SND_LIFEUP)); - } - } - - remove_me(); - return; - } -} - -void load_special_gfx() -{ - img_growup = sprite_manager->load("egg"); - img_iceflower = sprite_manager->load("iceflower"); - img_fireflower = sprite_manager->load("fireflower"); - img_star = sprite_manager->load("star"); - img_1up = sprite_manager->load("1up"); - - img_firebullet = sprite_manager->load("firebullet"); - img_icebullet = sprite_manager->load("icebullet"); -} - -void free_special_gfx() -{ -} - diff --git a/src/special.h b/src/special.h deleted file mode 100644 index 0e69b8914..000000000 --- a/src/special.h +++ /dev/null @@ -1,89 +0,0 @@ -// $Id$ -// -// SuperTux - A Jump'n Run -// Copyright (C) 2003 Tobias Glaesser -// -// This program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License -// as published by the Free Software Foundation; either version 2 -// of the License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#ifndef SUPERTUX_SPECIAL_H -#define SUPERTUX_SPECIAL_H - -#include "SDL.h" - -#include "bitmask.h" -#include "special/base.h" -#include "video/surface.h" -#include "collision.h" -#include "player.h" -#include "math/physic.h" - -/* Upgrade types: */ - -enum UpgradeKind { - UPGRADE_GROWUP, - UPGRADE_FIREFLOWER, - UPGRADE_ICEFLOWER, - UPGRADE_STAR, - UPGRADE_1UP -}; - -void load_special_gfx(); -void free_special_gfx(); - -class Upgrade : public MovingObject -{ -public: - UpgradeKind kind; - Direction dir; - Physic physic; - - Upgrade(const Vector& pos, Direction dir, UpgradeKind kind); - virtual ~Upgrade(); - - virtual void action(float frame_ratio); - virtual void draw(DrawingContext& context); - - virtual void collision(const MovingObject& other, int); - void collision(void* p_c_object, int c_object, CollisionType type); - -private: - void bump(Player* player); -}; - -enum BulletsKind { - FIRE_BULLET, - ICE_BULLET -}; - -class Bullet : public MovingObject -{ -public: - Bullet(const Vector& pos, float xm, int dir, - int kind); - - virtual void action(float frame_ratio); - virtual void draw(DrawingContext& context); - void collision(int c_object); - - virtual void collision(const MovingObject& other_object, int type); - - int kind; - -private: - int life_count; - Physic physic; -}; - -#endif /*SUPERTUX_SPECIAL_H*/ diff --git a/src/statistics.cpp b/src/statistics.cpp index 0b9cc0a25..0b1498dc1 100644 --- a/src/statistics.cpp +++ b/src/statistics.cpp @@ -17,6 +17,8 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. +#include + #include "utils/lispreader.h" #include "utils/lispwriter.h" #include "video/drawing_context.h" @@ -56,7 +58,6 @@ return std::min(a, b); Statistics::Statistics() { - timer.init(true); display_stat = 1; for(int i = 0; i < NUM_STATS; i++) @@ -100,7 +101,7 @@ Statistics::draw_worldmap_info(DrawingContext& context) if(stats[SCORE_STAT][SPLAYER] == -1) // not initialized yet return; - if(!timer.check()) + if(timer.check()) { timer.start(TOTAL_DISPLAY_TIME); display_stat++; @@ -123,10 +124,10 @@ Statistics::draw_worldmap_info(DrawingContext& context) // draw other small info int alpha; - if(timer.get_gone() < FADING_TIME) - alpha = timer.get_gone() * 255 / FADING_TIME; - else if(timer.get_left() < FADING_TIME) - alpha = timer.get_left() * 255 / FADING_TIME; + if(timer.get_timegone() < FADING_TIME) + alpha = int(timer.get_timegone() * 255 / FADING_TIME); + else if(timer.get_timeleft() < FADING_TIME) + alpha = int(timer.get_timeleft() * 255 / FADING_TIME); else alpha = 255; diff --git a/src/statistics.h b/src/statistics.h index bb123734b..9f1533236 100644 --- a/src/statistics.h +++ b/src/statistics.h @@ -20,7 +20,7 @@ #ifndef SUPERTUX_STATISTICS_H #define SUPERTUX_STATISTICS_H -#include "special/timer.h" +#include "timer.h" using namespace SuperTux; @@ -81,7 +81,7 @@ public: private: int stats[NUM_STATS][2]; - Timer timer; + Timer2 timer; int display_stat; }; diff --git a/src/supertux.cpp b/src/supertux.cpp index c29d7f3b7..088222ff2 100644 --- a/src/supertux.cpp +++ b/src/supertux.cpp @@ -17,6 +17,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. +#include #include #include @@ -48,17 +49,17 @@ int main(int argc, char * argv[]) #endif config = new MyConfig; setlocale(LC_ALL, ""); - bindtextdomain(PACKAGE, LOCALEDIR); - textdomain(PACKAGE); - bind_textdomain_codeset(PACKAGE, "ISO-8859-1"); + (void) bindtextdomain(PACKAGE, LOCALEDIR); + (void) textdomain(PACKAGE); + (void) bind_textdomain_codeset(PACKAGE, "ISO-8859-1"); - Setup::info(PACKAGE_NAME,PACKAGE,PACKAGE_VERSION); + Setup::info(PACKAGE_NAME, PACKAGE, PACKAGE_VERSION); Setup::directories(); Setup::parseargs(argc, argv); Setup::audio(); - Setup::video(SCREEN_W,SCREEN_H); + Setup::video(800, 600); Setup::joystick(); Setup::general(); st_menu(); @@ -95,25 +96,18 @@ int main(int argc, char * argv[]) title(); } - SDL_FillRect(screen, 0, 0); - //SDL_Flip(screen); - unloadshared(); Setup::general_free(); st_menu_free(); TileManager::destroy_instance(); - #ifdef DEBUG +#ifdef DEBUG Surface::debug_check(); - #endif +#endif Termination::shutdown(); #ifndef DEBUG // we want to see the backtrace in gdb when in debug mode - } - catch (SuperTuxException &e) - { + } catch (SuperTuxException &e) { std::cerr << "Unhandled SuperTux exception:\n " << e.what_file() << ":" << e.what_line() << ": " << e.what() << std::endl; - } - catch (std::exception &e) - { + } catch (std::exception &e) { std:: cerr << "Unhandled exception: " << e.what() << std::endl; } #endif diff --git a/src/tile.cpp b/src/tile.cpp index 2bd161d98..29575a04e 100644 --- a/src/tile.cpp +++ b/src/tile.cpp @@ -18,9 +18,12 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. +#include + #include #include #include +#include #include "app/globals.h" #include "tile.h" @@ -98,7 +101,7 @@ std::vector create_surfaces(lisp_object_t* cur) } Tile::Tile() - : id(-1), attributes(0), data(0), next_tile(0), anim_speed(25) + : id(0), attributes(0), data(0), next_tile(0), anim_speed(25) { } @@ -114,19 +117,18 @@ Tile::~Tile() } } -int +void Tile::read(LispReader& reader) { - if(!reader.read_int("id", id)) { - std::cerr << "Missing tile-id.\n"; - return -1; + if(!reader.read_uint("id", id)) { + throw std::runtime_error("Missing tile-id."); } bool value; if(reader.read_bool("solid", value) && value) attributes |= SOLID; if(reader.read_bool("unisolid", value) && value) - attributes |= GOAL; + attributes |= UNISOLID | SOLID; if(reader.read_bool("brick", value) && value) attributes |= BRICK; if(reader.read_bool("ice", value) && value) @@ -148,20 +150,22 @@ Tile::read(LispReader& reader) reader.read_int("anim-speed", anim_speed); reader.read_int("next-tile", next_tile); - slope_angle = 0; - reader.read_float("slope-angle", slope_angle); - if(slope_angle != 0) - { // convert angle to radians from degrees: - slope_angle = (slope_angle * M_PI) / 180; - attributes |= SOLID; - } + if(reader.read_int("slope-type", data)) { + attributes |= SOLID | SLOPE; + } - // FIXME: make images and editor_images a sprite images = create_surfaces(reader.read_lisp("images")); editor_images = create_surfaces(reader.read_lisp("editor-images")); - - return id; } -/* EOF */ +void +Tile::draw(DrawingContext& context, const Vector& pos, int layer) const +{ + if(images.size() > 1) { + size_t frame = ((global_frame_counter*25) / anim_speed) % images.size(); + context.draw_surface(images[frame], pos, layer); + } else if (images.size() == 1) { + context.draw_surface(images[0], pos, layer); + } +} diff --git a/src/tile.h b/src/tile.h index 692bfe804..b34e67154 100644 --- a/src/tile.h +++ b/src/tile.h @@ -41,9 +41,9 @@ public: ~Tile(); /// parses the tile and returns it's id number - int read(LispReader& reader); + void read(LispReader& reader); - int id; + unsigned int id; std::vector images; std::vector editor_images; @@ -70,7 +70,9 @@ public: * if data is 0 then the endsequence should be triggered, if data is 1 * then we can finish the level instantly. */ - GOAL = 0x0100 + GOAL = 0x0100, + /** slope tile */ + SLOPE = 0x0200 }; /** tile attributes */ @@ -85,11 +87,8 @@ public: int anim_speed; - /** This is the angle of the slope. Set to 0, if this is no slope. */ - float slope_angle; - - /** Draw a tile on the screen: */ - static void draw(const Vector& pos, unsigned int c, Uint8 alpha = 255); + /** Draw a tile on the screen */ + void draw(DrawingContext& context, const Vector& pos, int layer) const; /// returns the width of the tile in pixels int getWidth() const diff --git a/src/tile_manager.cpp b/src/tile_manager.cpp index 0c87f4e3f..1cd860207 100644 --- a/src/tile_manager.cpp +++ b/src/tile_manager.cpp @@ -18,6 +18,8 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. +#include + #include #include "video/drawing_context.h" #include "app/setup.h" @@ -28,7 +30,6 @@ #include "scene.h" TileManager* TileManager::instance_ = 0; -std::set* TileManager::tilegroups_ = 0; TileManager::TileManager() { @@ -39,9 +40,7 @@ TileManager::TileManager() TileManager::~TileManager() { for(Tiles::iterator i = tiles.begin(); i != tiles.end(); ++i) - delete i->second; - - delete tilegroups_; + delete *i; } void TileManager::load_tileset(std::string filename) @@ -51,7 +50,7 @@ void TileManager::load_tileset(std::string filename) // free old tiles for(Tiles::iterator i = tiles.begin(); i != tiles.end(); ++i) - delete i->second; + delete *i; tiles.clear(); lisp_object_t* root_obj = lisp_read_from_file(filename); @@ -59,102 +58,59 @@ void TileManager::load_tileset(std::string filename) if (!root_obj) Termination::abort("Couldn't load file", filename); - if (strcmp(lisp_symbol(lisp_car(root_obj)), "supertux-tiles") == 0) - { - lisp_object_t* cur = lisp_cdr(root_obj); - int tileset_id = 0; - - while(!lisp_nil_p(cur)) - { - lisp_object_t* element = lisp_car(cur); - - if (strcmp(lisp_symbol(lisp_car(element)), "tile") == 0) - { - LispReader reader(lisp_cdr(element)); - - Tile* tile = new Tile; - int tile_id = tile->read(reader); -/* if(tile_id < 0) { - std::cerr - << "Warning: parse error when reading a tile (id < 0), skipping.\n"; - continue; - }*/ - - tiles[tile_id] = tile; - } - else if (strcmp(lisp_symbol(lisp_car(element)), "tileset") == 0) - { - LispReader reader(lisp_cdr(element)); - std::string filename; - reader.read_string("file", filename); - filename = datadir + "/images/tilesets/" + filename; - load_tileset(filename); - } - else if (strcmp(lisp_symbol(lisp_car(element)), "tilegroup") == 0) - { - TileGroup new_; - LispReader reader(lisp_cdr(element)); - reader.read_string("name", new_.name); - reader.read_int_vector("tiles", new_.tiles); - if(!tilegroups_) - tilegroups_ = new std::set; - tilegroups_->insert(new_).first; - } - else if (strcmp(lisp_symbol(lisp_car(element)), "properties") == 0) - { - LispReader reader(lisp_cdr(element)); - reader.read_int("id", tileset_id); - tileset_id *= 1000; - } - else - { - std::cerr << "Unknown symbol: " << - lisp_symbol(lisp_car(element)) << "\n"; - } - - cur = lisp_cdr(cur); - } - } - else - { - assert(0); - } + if (strcmp(lisp_symbol(lisp_car(root_obj)), "supertux-tiles") != 0) + assert(false); - lisp_free(root_obj); - current_tileset = filename; -} + lisp_object_t* cur = lisp_cdr(root_obj); + int tileset_id = 0; -void -TileManager::draw_tile(DrawingContext& context, unsigned int c, - const Vector& pos, int layer) -{ - if(c == 0) - return; + while(!lisp_nil_p(cur)) { + lisp_object_t* element = lisp_car(cur); - Tile* tile = get(c); + if (strcmp(lisp_symbol(lisp_car(element)), "tile") == 0) + { + LispReader reader(lisp_cdr(element)); - if(!tile->images.size()) - return; + Tile* tile = new Tile; + tile->read(reader); - if(tile->images.size() > 1) - { - size_t frame - = ((global_frame_counter*25) / tile->anim_speed) % tile->images.size(); - context.draw_surface(tile->images[frame], pos, layer); - } - else if (tile->images.size() == 1) - { - context.draw_surface(tile->images[0], pos, layer); + while(tile->id >= tiles.size()) { + tiles.push_back(0); + } + tiles[tile->id] = tile; + } + else if (strcmp(lisp_symbol(lisp_car(element)), "tileset") == 0) + { + LispReader reader(lisp_cdr(element)); + std::string filename; + reader.read_string("file", filename); + filename = datadir + "/images/tilesets/" + filename; + load_tileset(filename); + } + else if (strcmp(lisp_symbol(lisp_car(element)), "tilegroup") == 0) + { + TileGroup new_; + LispReader reader(lisp_cdr(element)); + reader.read_string("name", new_.name); + reader.read_int_vector("tiles", new_.tiles); + tilegroups.insert(new_).first; + } + else if (strcmp(lisp_symbol(lisp_car(element)), "properties") == 0) + { + LispReader reader(lisp_cdr(element)); + reader.read_int("id", tileset_id); + tileset_id *= 1000; + } + else + { + std::cerr << "Unknown symbol: " << + lisp_symbol(lisp_car(element)) << "\n"; + } + + cur = lisp_cdr(cur); } -} -Tile* -TileManager::get(unsigned int id) -{ -Tiles::iterator i = tiles.find(id); -if(i == tiles.end()) - return 0; -return i->second; + lisp_free(root_obj); + current_tileset = filename; } -/* EOF */ diff --git a/src/tile_manager.h b/src/tile_manager.h index e05f6b38f..3e9052f67 100644 --- a/src/tile_manager.h +++ b/src/tile_manager.h @@ -25,6 +25,8 @@ #include #include #include +#include +#include class Tile; @@ -45,11 +47,11 @@ class TileManager TileManager(); ~TileManager(); - typedef std::map Tiles; + typedef std::vector Tiles; Tiles tiles; static TileManager* instance_ ; - static std::set* tilegroups_; + std::set tilegroups; void load_tileset(std::string filename); std::string current_tileset; @@ -60,15 +62,21 @@ class TileManager static void destroy_instance() { delete instance_; instance_ = 0; } - void draw_tile(DrawingContext& context, unsigned int id, - const Vector& pos, int layer); - - static std::set* tilegroups() { if(!instance_) { instance_ = new TileManager(); } return tilegroups_ ? tilegroups_ : tilegroups_ = new std::set; } + const std::set& get_tilegroups() const + { + return tilegroups; + } - unsigned int total_ids() - { return tiles.size(); } + const Tile* get(uint32_t id) const + { + assert(id < tiles.size()); + return tiles[id]; + } - Tile* get(unsigned int id); + uint32_t get_max_tileid() const + { + return tiles.size(); + } }; #endif diff --git a/src/tilemap.cpp b/src/tilemap.cpp index 818ba31e8..b7f3c5a46 100644 --- a/src/tilemap.cpp +++ b/src/tilemap.cpp @@ -16,6 +16,7 @@ // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +#include #include #include @@ -33,13 +34,18 @@ #include "utils/lispwriter.h" TileMap::TileMap() - : solid(false), speed(1), width(0), height(0), layer(LAYER_TILES), vertical_flip(false) + : solid(false), speed(1), width(0), height(0), layer(LAYER_TILES), + vertical_flip(false) { tilemanager = TileManager::instance(); + + if(solid) + flags |= FLAG_SOLID; } TileMap::TileMap(LispReader& reader) - : solid(false), speed(1), width(0), height(0), layer(LAYER_TILES), vertical_flip(false) + : solid(false), speed(1), width(0), height(0), layer(LAYER_TILES), + vertical_flip(false) { tilemanager = TileManager::instance(); @@ -62,33 +68,30 @@ TileMap::TileMap(LispReader& reader) std::cout << "Speed of solid tilemap is not 1. fixing.\n"; speed = 1; } + if(solid) + flags |= FLAG_SOLID; if(!reader.read_int("width", width) || !reader.read_int("height", height)) throw std::runtime_error("No width or height specified in tilemap."); - std::vector tmp_tiles; - - if(!reader.read_int_vector("tiles", tmp_tiles)) + if(!reader.read_int_vector("tiles", tiles)) throw std::runtime_error("No tiles in tilemap."); - tiles.resize(tmp_tiles.size()); - for(unsigned int i = 0; i < tmp_tiles.size(); ++i) - { - tiles[i].hidden = false; - tiles[i].id = tmp_tiles[i]; - } - if(int(tiles.size()) != width*height) throw std::runtime_error("wrong number of tiles in tilemap."); } TileMap::TileMap(int layer_, bool solid_, size_t width_, size_t height_) - : solid(solid_), speed(1), width(0), height(0), layer(layer_), vertical_flip(false) + : solid(solid_), speed(1), width(0), height(0), layer(layer_), + vertical_flip(false) { tilemanager = TileManager::instance(); resize(width_, height_); + + if(solid) + flags |= FLAG_SOLID; } TileMap::~TileMap() @@ -115,14 +118,7 @@ TileMap::write(LispWriter& writer) writer.write_float("speed", speed); writer.write_int("width", width); writer.write_int("height", height); - - std::vector tmp_tiles; - tmp_tiles.resize(tiles.size()); - for(unsigned int i = 0; i < tmp_tiles.size(); ++i) - { - tmp_tiles[i] = tiles[i].id; - } - writer.write_int_vector("tiles", tmp_tiles); + writer.write_int_vector("tiles", tiles); writer.end_list("tilemap"); } @@ -135,71 +131,36 @@ TileMap::action(float ) void TileMap::draw(DrawingContext& context) { - if (speed == 1.0) - { - if(vertical_flip) // flip vertically the tiles, in case we are playing this - { // level upside down - context.push_transform(); - context.set_drawing_effect(VERTICAL_FLIP); - } - - /** if we don't round here, we'll have a 1 pixel gap on screen sometimes. - * I have no idea why */ - float start_x = roundf(context.get_translation().x); - float start_y = roundf(context.get_translation().y); - float end_x = std::min(start_x + screen->w, float(width * 32)); - float end_y = std::min(start_y + screen->h, float(height * 32)); - start_x -= int(start_x) % 32; - start_y -= int(start_y) % 32; - int tsx = int(start_x / 32); // tilestartindex x - int tsy = int(start_y / 32); // tilestartindex y - - Vector pos; - int tx, ty; - for(pos.x = start_x, tx = tsx; pos.x < end_x; pos.x += 32, ++tx) { - for(pos.y = start_y, ty = tsy; pos.y < end_y; pos.y += 32, ++ty) { - if(tx < 0 || tx > width || ty < 0 || ty > height) - continue; // outside tilemap - if (!tiles[ty*width + tx].hidden) - tilemanager->draw_tile(context, tiles[ty*width + tx].id, pos, layer); - } - } - - if(vertical_flip) // disable flipping, if applied - context.pop_transform(); + context.push_transform(); + + if(vertical_flip) + context.set_drawing_effect(VERTICAL_FLIP); + float trans_x = roundf(context.get_translation().x); + float trans_y = roundf(context.get_translation().y); + context.set_translation(Vector(trans_x * speed, trans_y * speed)); + + /** if we don't round here, we'll have a 1 pixel gap on screen sometimes. + * I have no idea why */ + float start_x = roundf(context.get_translation().x); + float start_y = roundf(context.get_translation().y); + float end_x = std::min(start_x + screen->w, float(width * 32)); + float end_y = std::min(start_y + screen->h, float(height * 32)); + start_x -= int(start_x) % 32; + start_y -= int(start_y) % 32; + int tsx = int(start_x / 32); // tilestartindex x + int tsy = int(start_y / 32); // tilestartindex y + + Vector pos; + int tx, ty; + for(pos.x = start_x, tx = tsx; pos.x < end_x; pos.x += 32, ++tx) { + for(pos.y = start_y, ty = tsy; pos.y < end_y; pos.y += 32, ++ty) { + const Tile* tile = tilemanager->get(tiles[ty*width + tx]); + assert(tile != 0); + tile->draw(context, pos, layer); } - else - { - float trans_x = roundf(context.get_translation().x); - float trans_y = roundf(context.get_translation().y); - - context.push_transform(); - context.set_translation(Vector(trans_x * speed, trans_y * speed)); - if(vertical_flip) - context.set_drawing_effect(VERTICAL_FLIP); - - float start_x = roundf(context.get_translation().x); - float start_y = roundf(context.get_translation().y); - float end_x = std::min(start_x + screen->w, float(width * 32)); - float end_y = std::min(start_y + screen->h, float(height * 32)); - start_x -= int(start_x) % 32; - start_y -= int(start_y) % 32; - int tsx = int(start_x / 32); // tilestartindex x - int tsy = int(start_y / 32); // tilestartindex y - - Vector pos; - int tx, ty; - for(pos.x = start_x, tx = tsx; pos.x < end_x; pos.x += 32, ++tx) { - for(pos.y = start_y, ty = tsy; pos.y < end_y; pos.y += 32, ++ty) { - if(tx < 0 || tx > width || ty < 0 || ty > height) - continue; // outside tilemap - if (!tiles[ty*width + tx].hidden) - tilemanager->draw_tile(context, tiles[ty*width + tx].id, pos, layer); - } - } + } - context.pop_transform(); - } + context.pop_transform(); } void @@ -212,14 +173,12 @@ TileMap::set(int newwidth, int newheight, const std::vector&newt, height = newheight; tiles.resize(newt.size()); - for(unsigned int i = 0; i < newt.size(); ++i) - { - tiles[i].hidden = false; - tiles[i].id = newt[i]; - } + tiles = newt; layer = newlayer; solid = newsolid; + if(solid) + flags |= FLAG_SOLID; } void @@ -241,10 +200,11 @@ TileMap::resize(int new_width, int new_height) for(int y = std::min(height, new_height)-1; y >= 0; --y) { for(int x = new_width-1; x >= 0; --x) { if(x >= width) { - tiles[y * new_width + x] = TileId(); - } else { - tiles[y * new_width + x] = tiles[y * width + x]; + tiles[y * new_width + x] = 0; + continue; } + + tiles[y * new_width + x] = tiles[y * width + x]; } } } @@ -260,45 +220,40 @@ TileMap::do_vertical_flip() for(int y = 0; y < height / 2; ++y) { for(int x = 0; x < width; ++x) { std::swap(tiles[y*width + x], tiles[(((height-1)*width) - (y*width)) + x]); - } } + } vertical_flip = true; } -Tile* +const Tile* TileMap::get_tile(int x, int y) const { - if(x < 0 || x >= width || y < 0 || y >= height) + if(x < 0 || x >= width || y < 0 || y >= height) { +#ifdef DEBUG + std::cout << "Warning: tile outside tilemap requested!\n"; +#endif return tilemanager->get(0); + } - return tilemanager->get(tiles[y*width + x].id); + return tilemanager->get(tiles[y*width + x]); } -Tile* +const Tile* TileMap::get_tile_at(const Vector& pos) const { return get_tile(int(pos.x)/32, int(pos.y)/32); } -TileId& -TileMap::get_tile_id_at(const Vector& pos) -{ - int x = int(pos.x)/32; - int y = int(pos.y)/32; - - return tiles[y*width + x]; -} - void -TileMap::change(int x, int y, unsigned int newtile) +TileMap::change(int x, int y, uint32_t newtile) { assert(x >= 0 && x < width && y >= 0 && y < height); - tiles[y*width + x].id = newtile; + tiles[y*width + x] = newtile; } void -TileMap::change_at(const Vector& pos, unsigned int newtile) +TileMap::change_at(const Vector& pos, uint32_t newtile) { change(int(pos.x)/32, int(pos.y)/32, newtile); } diff --git a/src/tilemap.h b/src/tilemap.h index 92d121dfc..8aa2b481a 100644 --- a/src/tilemap.h +++ b/src/tilemap.h @@ -21,6 +21,7 @@ #define SUPERTUX_TILEMAP_H #include +#include #include "special/game_object.h" #include "serializable.h" @@ -36,15 +37,6 @@ class Level; class TileManager; class Tile; -struct TileId -{ - TileId() : id(0), hidden(0) {} - explicit TileId(unsigned int i, bool hidden_ = false) : id(i), hidden(hidden_) {} - - unsigned id :31; - unsigned hidden :1; -}; - /** * This class is reponsible for drawing the level tiles */ @@ -85,19 +77,17 @@ public: bool is_solid() const { return solid; } - TileId& get_tile_id_at(const Vector& pos); - /// returns tile in row y and column y (of the tilemap) - Tile* get_tile(int x, int y) const; + const Tile* get_tile(int x, int y) const; /// returns tile at position pos (in world coordinates) - Tile* get_tile_at(const Vector& pos) const; + const Tile* get_tile_at(const Vector& pos) const; - void change(int x, int y, unsigned int newtile); + void change(int x, int y, uint32_t newtile); - void change_at(const Vector& pos, unsigned int newtile); + void change_at(const Vector& pos, uint32_t newtile); private: - std::vector tiles; + std::vector tiles; private: TileManager* tilemanager; diff --git a/src/timer.cpp b/src/timer.cpp new file mode 100644 index 000000000..ee63f83c9 --- /dev/null +++ b/src/timer.cpp @@ -0,0 +1,42 @@ +#include + +#include +#include "timer.h" + +float global_time = 0; + +Timer2::Timer2() + : period(0), cycle_start(0), cyclic(false) +{ +} + +Timer2::~Timer2() +{ +} + +void +Timer2::start(float period, bool cyclic) +{ + this->period = period; + this->cyclic = cyclic; + cycle_start = global_time; +} + +bool +Timer2::check() +{ + if(period == 0) + return false; + + if(global_time - cycle_start >= period) { + if(cyclic) { + cycle_start = global_time - fmodf(global_time - cycle_start, period); + } else { + period = 0; + } + return true; + } + + return false; +} + diff --git a/src/timer.h b/src/timer.h new file mode 100644 index 000000000..9b44b304d --- /dev/null +++ b/src/timer.h @@ -0,0 +1,40 @@ +#ifndef __SUPERTUX_TIMER_H__ +#define __SUPERTUX_TIMER_H__ + +extern float global_time; + +/** + * new simpler timer designed to be used in the update functions of objects + */ +class Timer2 // TODO rename later +{ +public: + Timer2(); + ~Timer2(); + + /** start the timer with the given period. If cyclic=true then the timer willl + * be reset after each period. + * Set period to zero if you want to disable the timer. + */ + void start(float period, bool cyclic = false); + /** returns true if a period (or more) passed during the last tick command */ + bool check(); + + /** returns the period of the timer or 0 if it isn't started */ + float get_period() const + { return period; } + float get_timeleft() const + { return period - (global_time - cycle_start); } + float get_timegone() const + { return global_time - cycle_start; } + bool started() const + { return period != 0 && get_timeleft() > 0; } + +private: + float period; + float cycle_start; + bool cyclic; +}; + +#endif + diff --git a/src/title.cpp b/src/title.cpp index 9e4504912..a1739666e 100644 --- a/src/title.cpp +++ b/src/title.cpp @@ -18,6 +18,7 @@ // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA // 02111-1307, USA. +#include #include #include @@ -42,7 +43,7 @@ #include "video/surface.h" #include "high_scores.h" #include "gui/menu.h" -#include "special/timer.h" +#include "timer.h" #include "special/frame_rate.h" #include "app/setup.h" #include "level.h" @@ -56,7 +57,6 @@ #include "sector.h" #include "tilemap.h" #include "resources.h" -#include "special/base.h" #include "app/gettext.h" #include "misc.h" #include "camera.h" @@ -66,7 +66,7 @@ static Surface* logo; static Surface* img_choose_subset; static bool walking; -static Timer random_timer; +static Timer2 random_timer; static int frame; @@ -118,7 +118,7 @@ void free_contrib_menu() void generate_contrib_menu() { - /** Generating contrib levels list by making use of Level Subset */ + /** Generating contrib levels list by making use of Level Subset */ std::set level_subsets = FileSystem::dsubdirs("/levels", "info"); free_contrib_menu(); @@ -272,7 +272,7 @@ void check_contrib_subset_menu() } } -void draw_demo(double frame_ratio) +void draw_demo(float elapsed_time) { Sector* world = titlesession->get_current_sector(); Player* tux = world->player; @@ -282,35 +282,32 @@ void draw_demo(double frame_ratio) global_frame_counter++; tux->key_event((SDLKey) keymap.right,DOWN); - if(random_timer.check()) - { + if(random_timer.check()) { + random_timer.start(float(rand() % 3000 + 3000) / 1000.); + walking = !walking; + } else { if(walking) tux->key_event((SDLKey) keymap.jump,UP); else tux->key_event((SDLKey) keymap.jump,DOWN); - } - else - { - random_timer.start(rand() % 3000 + 3000); - walking = !walking; - } + } // Wrap around at the end of the level back to the beginnig - if(world->solids->get_width() * 32 - 320 < tux->base.x) + if(world->solids->get_width() * 32 - 320 < tux->get_pos().x) { tux->level_begin(); - world->camera->reset(Vector(tux->base.x, tux->base.y)); + world->camera->reset(tux->get_pos()); } tux->can_jump = true; - float last_tux_x_pos = tux->base.x; - world->action(frame_ratio); + float last_tux_x_pos = tux->get_pos().x; + world->action(elapsed_time); // disabled for now, since with the new jump code we easily get deadlocks // Jump if tux stays in the same position for one loop, ie. if he is // stuck behind a wall - if (last_tux_x_pos == tux->base.x) + if (last_tux_x_pos == tux->get_pos().x) { walking = false; } @@ -324,7 +321,6 @@ void title(void) walking = true; LevelEditor* leveleditor; - random_timer.init(true); Ticks::pause_init(); titlesession = new GameSession("misc/menu.stl", ST_GL_DEMO_GAME); @@ -343,24 +339,26 @@ void title(void) /* --- Main title loop: --- */ frame = 0; - frame_rate.set_frame_limit(false); - - random_timer.start(rand() % 2000 + 2000); + random_timer.start(float(rand() % 2000 + 2000) / 1000.0); + Uint32 lastticks = SDL_GetTicks(); + Menu::set_current(main_menu); DrawingContext& context = *titlesession->context; while (Menu::current()) { - // if we spent to much time on a menu entry - frame_rate.smooth_hanger(); - // Calculate the movement-factor - double frame_ratio = frame_rate.get(); + Uint32 ticks = SDL_GetTicks(); + float elapsed_time = float(ticks - lastticks) / 1000.; + global_time += elapsed_time; + lastticks = ticks; + // 40fps is minimum + if(elapsed_time > .04) + elapsed_time = .04; - if(frame_ratio > 1.5) /* Quick hack to correct the unprecise CPU clocks a little bit. */ - frame_ratio = 1.5 + (frame_ratio - 1.5) * 0.85; - /* Lower the frame_ratio that Tux doesn't jump to hectically throught the demo. */ - frame_ratio /= 2; + /* Lower the speed so that Tux doesn't jump too hectically throught + the demo. */ + elapsed_time /= 2; SDL_Event event; while (SDL_PollEvent(&event)) @@ -375,14 +373,15 @@ void title(void) } /* Draw the background: */ - draw_demo(frame_ratio); + draw_demo(elapsed_time); if (Menu::current() == main_menu) context.draw_surface(logo, Vector(screen->w/2 - logo->w/2, 30), LAYER_FOREGROUND1+1); - context.draw_text(white_small_text, " SuperTux " VERSION "\n", Vector(0, screen->h - 70), LEFT_ALLIGN, LAYER_FOREGROUND1); + context.draw_text(white_small_text, " SuperTux " PACKAGE_VERSION "\n", + Vector(0, screen->h - 70), LEFT_ALLIGN, LAYER_FOREGROUND1); context.draw_text(white_small_text, _("Copyright (c) 2003 SuperTux Devel Team\n" "This game comes with ABSOLUTELY NO WARRANTY. This is free software, and you\n" @@ -474,7 +473,6 @@ void title(void) /* Pause: */ frame++; - SDL_Delay(25); } /* Free surfaces: */ diff --git a/src/trigger/door.cpp b/src/trigger/door.cpp new file mode 100644 index 000000000..79bfef8c0 --- /dev/null +++ b/src/trigger/door.cpp @@ -0,0 +1,97 @@ +// $Id$ +// +// SuperTux - A Jump'n Run +// Copyright (C) 2004 Matthias Braun + +#include "door.h" +#include "utils/lispreader.h" +#include "utils/lispwriter.h" +#include "gameloop.h" +#include "resources.h" +#include "special/sprite.h" +#include "special/sprite_manager.h" +#include "video/drawing_context.h" +#include "app/globals.h" + +using namespace SuperTux; + +Door::Door(LispReader& reader) +{ + reader.read_float("x", bbox.p1.x); + reader.read_float("y", bbox.p1.y); + bbox.set_size(32, 64); + + reader.read_string("sector", target_sector); + reader.read_string("spawnpoint", target_spawnpoint); + + sprite = sprite_manager->create("door"); +} + +Door::Door(int x, int y) +{ + bbox.set_pos(Vector(x, y)); + bbox.set_size(32, 64); + + sprite = sprite_manager->create("door"); +} + +Door::~Door() +{ + delete sprite; +} + +void +Door::write(LispWriter& writer) +{ + writer.start_list("door"); + + writer.write_float("x", bbox.p1.x); + writer.write_float("y", bbox.p1.y); + writer.write_float("width", bbox.get_width()); + writer.write_float("height", bbox.get_height()); + + writer.write_string("sector", target_sector); + writer.write_string("spawnpoint", target_spawnpoint); + + writer.end_list("door"); +} + +void +Door::action(float ) +{ + //Check if door animation is complete + if (!sprite->check_animation()) { + GameSession::current()->respawn(target_sector, target_spawnpoint); + } +} + +void +Door::draw(DrawingContext& context) +{ + sprite->draw(context, bbox.p1, LAYER_TILES); +} + +void +Door::event(Player& player, EventType type) +{ + if(type == EVENT_ACTIVATE) { + sprite->set_action("open"); + sprite->start_animation(1); + } +} + diff --git a/src/trigger/door.h b/src/trigger/door.h new file mode 100644 index 000000000..151773561 --- /dev/null +++ b/src/trigger/door.h @@ -0,0 +1,49 @@ +// $Id$ +// +// SuperTux - A Jump'n Run +// Copyright (C) 2004 Matthias Braun + +#include "video/surface.h" +#include "special/sprite.h" +#include "trigger_base.h" +#include "serializable.h" +#include "timer.h" + +class Door : public TriggerBase, public Serializable +{ +public: + Door(LispReader& reader); + Door(int x, int y); + virtual ~Door(); + + virtual void write(LispWriter& writer); + + virtual void action(float elapsed_time); + virtual void draw(DrawingContext& context); + virtual void event(Player& player, EventType type); + +private: + std::string target_sector; + std::string target_spawnpoint; + Sprite* sprite; +}; + +#endif diff --git a/src/trigger/sequence_trigger.cpp b/src/trigger/sequence_trigger.cpp new file mode 100644 index 000000000..e173457a7 --- /dev/null +++ b/src/trigger/sequence_trigger.cpp @@ -0,0 +1,46 @@ +#include + +#include "sequence_trigger.h" +#include "utils/lispwriter.h" +#include "gameloop.h" + +SequenceTrigger::SequenceTrigger(LispReader& reader, + const std::string& sequence) +{ + // TODO +} + +SequenceTrigger::SequenceTrigger(const Vector& pos, + const std::string& sequence) +{ + bbox.set_pos(pos); + bbox.set_size(32, 32); + sequence_name = sequence; + triggerevent = EVENT_TOUCH; +} + +SequenceTrigger::~SequenceTrigger() +{ +} + +void +SequenceTrigger::write(LispWriter& writer) +{ + writer.start_list("sequencetrigger"); + + writer.write_float("x", bbox.p1.x); + writer.write_float("y", bbox.p1.y); + writer.write_float("width", bbox.get_width()); + writer.write_float("height", bbox.get_height()); + writer.write_string("sequence", sequence_name); + + writer.end_list("sequencetrigger"); +} + +void +SequenceTrigger::event(Player& player, EventType type) +{ + if(type == triggerevent) { + GameSession::current()->start_sequence(sequence_name); + } +} diff --git a/src/trigger/sequence_trigger.h b/src/trigger/sequence_trigger.h new file mode 100644 index 000000000..35b86eb10 --- /dev/null +++ b/src/trigger/sequence_trigger.h @@ -0,0 +1,23 @@ +#ifndef __SEQUENCE_TRIGGER_H__ +#define __SEQUENCE_TRIGGER_H__ + +#include "trigger_base.h" +#include "serializable.h" + +class SequenceTrigger : public TriggerBase, public Serializable +{ +public: + SequenceTrigger(LispReader& reader, const std::string& sequence); + SequenceTrigger(const Vector& pos, const std::string& sequence); + ~SequenceTrigger(); + + void write(LispWriter& writer); + void event(Player& player, EventType type); + +private: + EventType triggerevent; + std::string sequence_name; +}; + +#endif + diff --git a/src/trigger/trigger_base.cpp b/src/trigger/trigger_base.cpp new file mode 100644 index 000000000..c99444869 --- /dev/null +++ b/src/trigger/trigger_base.cpp @@ -0,0 +1,62 @@ +// $Id$ +// +// SuperTux - A Jump'n Run +// Copyright (C) 2004 Matthias Braun + +#include "trigger_base.h" +#include "player.h" +#include "video/drawing_context.h" + +TriggerBase::TriggerBase() + : sprite(0) +{ +} + +TriggerBase::~TriggerBase() +{ +} + +void +TriggerBase::action(float ) +{ + lasthit = hit; + hit = false; +} + +void +TriggerBase::draw(DrawingContext& context) +{ + if(!sprite) + return; + + sprite->draw(context, get_pos(), LAYER_TILES+1); +} + +HitResponse +TriggerBase::collision(GameObject& other, const CollisionHit& collhit) +{ + Player* player = dynamic_cast (&other); + if(player) { + hit = true; + if(!lasthit) + event(*player, EVENT_TOUCH); + } + + return ABORT_MOVE; +} + diff --git a/src/trigger/trigger_base.h b/src/trigger/trigger_base.h new file mode 100644 index 000000000..b4d8df59b --- /dev/null +++ b/src/trigger/trigger_base.h @@ -0,0 +1,58 @@ +// $Id$ +// +// SuperTux - A Jump'n Run +// Copyright (C) 2004 Matthias Braun + #include #include #include @@ -39,7 +41,7 @@ #include "app/gettext.h" #include "misc.h" -#define map_message_TIME 2800 +#define map_message_TIME 2.8 Menu* worldmap_menu = 0; @@ -359,7 +361,7 @@ Tux::action(float delta) { if(special_tile && !special_tile->map_message.empty() && !special_tile->passive_message) - worldmap->passive_message_timer.stop(); + worldmap->passive_message_timer.start(0); stop(); } else @@ -488,7 +490,6 @@ WorldMap::WorldMap() music = "SALCON.MOD"; global_frame_counter = 0; - frame_timer.init(true); total_stats.reset(); } @@ -829,11 +830,9 @@ std::cerr << "one way only\n"; void WorldMap::update(float delta) { - if(!frame_timer.check()) - { - frame_timer.start(25); + if(!frame_timer.check()) { global_frame_counter++; - } + } if (enter_level && !tux->is_moving()) { @@ -1184,6 +1183,7 @@ WorldMap::display() frame_rate.set_frame_limit(false); frame_rate.start(); + frame_timer.start(.25, true); DrawingContext context; while(!quit) diff --git a/src/worldmap.h b/src/worldmap.h index f44ba5060..45431d786 100644 --- a/src/worldmap.h +++ b/src/worldmap.h @@ -27,7 +27,11 @@ #include "audio/musicref.h" #include "video/screen.h" #include "statistics.h" -#include "special/timer.h" +#include "timer.h" + +namespace SuperTux { + class Menu; +} extern Menu* worldmap_menu; @@ -216,7 +220,7 @@ public: }; /** Variables to deal with the passive map messages */ - Timer passive_message_timer; + Timer2 passive_message_timer; std::string passive_message; private: @@ -244,7 +248,7 @@ private: Statistics total_stats; void calculate_total_stats(); - Timer frame_timer; + Timer2 frame_timer; public: WorldMap();