if $(USE_STLPORT_DEBUG)
{
- CPPFLAGS += -I/usr/include/stlport ;
- CPPFLAGS += -D_STLP_DEBUG=1 -D_STLP_DEBUG_UNINITIALIZED=1 ;
- CPPFLAGS += -D_STLP_SHRED_BYTE=0xA3 ;
+ CXXFLAGS += -I/usr/include/stlport ;
+ CXXFLAGS += -D_STLP_DEBUG=1 -D_STLP_DEBUG_UNINITIALIZED=1 ;
+ CXXFLAGS += -D_STLP_SHRED_BYTE=0xA3 ;
LIBS += -lstlport_gcc_debug ;
}
-COMPILER_CFLAGS += -Wall -W ;
-COMPILER_CFLAGS_optimize += -O3 -g3 ;
-COMPILER_C++FLAGS_optimize += -O3 -g3 ;
-COMPILER_LFLAGS_optimize += -O3 -g3 ;
-COMPILER_CFLAGS_debug += -DDEBUG -Werror -g3 ;
-COMPILER_CXXFLAGS_debug += -DDEBUG -Werror -g3 ;
-COMPILER_LFLAGS_debug += -g3 ;
-COMPILER_CFLAGS_profile += -O2 -g3 -pg ;
-COMPILER_CXXFLAGS_profile += -O2 -g3 -pg ;
-COMPILER_LFLAGS_profile += -g3 -pg ;
+switch $(VARIANT) {
+ case optimize :
+ CFLAGS += -O3 -g ;
+ CXXFLAGS += -O3 -g ;
+ LIBS += -g ;
+ case debug :
+ CFLAGS += -O0 -g3 -DDEBUG ;
+ CXXFLAGS += -O0 -g3 -DDEBUG ;
+ LIBS += -g3 ;
+ case profile :
+ CFLAGS += -O3 -g3 -pg ;
+ CXXFLAGS += -O3 -g3 -pg ;
+ LIBS += -g3 -pg ;
+ case * :
+ EXIT "Invalid variant $(VARIANT) selected" ;
+}
LINK = $(CXX) ;
+++ /dev/null
-# needed so that scons -U works correctly
-Default(".")
-
+++ /dev/null
-#
-# SConstruct build file. See http://www.scons.org for details.
-import os
-import glob
-
-class ConfigHeader:
- def __init__(self):
- self.defines = { }
- self.prefix = ""
- self.postfix = ""
-
- def SetPrefix(self, prefix):
- self.prefix = prefix
-
- def SetPostfix(self, postfix):
- self.postfix = postfix
-
- def Define(self, name, value = ""):
- self.defines[name] = value
-
- def Save(self, filename):
- file = open(filename, 'w')
- file.write("/* %s. Generated by SConstruct */\n" % (filename))
- file.write("\n")
- file.write(self.prefix + "\n")
- for key, value in self.defines.iteritems():
- file.write("#define %s \"%s\"\n" % (key, value))
- file.write(self.postfix + "\n")
- file.close()
-
-def Glob(pattern):
- path = GetBuildPath('SConscript').replace('SConscript', '')
-
- result = []
- for i in glob.glob(path + pattern):
- result.append(i.replace(path, ''))
-
- return result
-
-def InstallData(files):
- for file in files:
- dir = os.path.dirname(file)
- destdir = os.path.join(env.subst('$DESTDIR/$APPDATADIR'), dir)
- env.Install(destdir, file)
-
-def InstallExec(files):
- for file in files:
- destfile = env.subst('$DESTDIR/$BINDIR/$PROGRAM_PREFIX') + file + \
- env.subst('$PROGRAM_POSTFIX')
- env.InstallAs(destfile, file)
-
-# thanks to Michael P Jung
-def CheckSDLConfig(context, minVersion):
- context.Message('Checking for sdl-config >= %s... ' % minVersion)
- from popen2 import Popen3
- p = Popen3(['sdl-config', '--version'])
- ret = p.wait()
- out = p.fromchild.readlines()
- if ret != 0:
- context.Result(False)
- return False
- if len(out) != 1:
- # unable to parse output!
- context.Result(False)
- return False
- # TODO validate output and catch exceptions
- version = map(int, out[0].strip().split('.'))
- minVersion = map(int, minVersion.split('.'))
- # TODO comparing versions that way only works for pure numeric version
- # numbers and fails for custom extensions. I don't care about this at
- # the moment as sdl-config never used such version numbers afaik.
- ret = (version >= minVersion)
- context.Result(ret)
- return ret
-
-# User configurable options
-opts = Options('build_config.py')
-opts.Add('CXX', 'The C++ compiler', 'g++')
-opts.Add('CXXFLAGS', 'Additional C++ compiler flags', '')
-opts.Add('CPPPATH', 'Additional preprocessor paths', '')
-opts.Add('CPPFLAGS', 'Additional preprocessor flags', '')
-opts.Add('CPPDEFINES', 'defined constants', '')
-opts.Add('LIBPATH', 'Additional library paths', '')
-opts.Add('LIBS', 'Additional libraries', '')
-
-# installation path options
-opts.Add('PREFIX', 'prefix for architecture-independent files', '/usr/local')
-opts.Add('EPREFIX', 'prefix for architecture-dependent files', '$PREFIX')
-opts.Add('BINDIR', 'user executables directory', '$EPREFIX/bin')
-#opts.Add('SBINDIR', 'system admin executables directory', '$EPREFIX/sbin')
-#opts.Add('LIBEXECDIR', 'program executables directory', '$EPREFIX/libexec')
-opts.Add('DATADIR', 'read-only architecture-independent data directory',
- '$PREFIX/share')
-#opts.Add('SYSCONFDIR', 'read-only single-machine data directory', '$PREFIX/etc')
-#opts.Add('SHAREDSTATEDIR', 'modifiable architecture-independent data directory',
-# '$PREFIX/com')
-#opts.Add('LOCALSTATEDIR', 'modifiable single-machine data directory',
-# '$PREFIX/var')
-opts.Add('LIBDIR', 'object code libraries directory', '$EPREFIX/lib')
-opts.Add('INCLUDEDIR', 'C header files directory', '$PREFIX/include')
-#opts.Add('OLDINCLUDEDIR', 'C header files for non-gcc directory',
-# '$PREFIX/include')
-#opts.Add('INFODIR', 'info documentation directory', '$PREFIX/info')
-#opts.Add('MANDIR', 'man documentation directory', '$PREFIX/man')
-opts.Add('DESTDIR', \
- 'destination directory for installation. It is prepended to PREFIX', '')
-
-# misc options
-opts.Add('PROGRAM_PREFIX', 'prepend PREFIX to installed program names', '')
-opts.Add('PROGRAM_SUFFIX', 'append SUFFIX to installed program names', '')
-opts.Add(EnumOption('VARIANT', 'Build variant', 'optimize',
- ['optimize', 'debug', 'profile']))
-
-env = Environment(options = opts)
-Help(opts.GenerateHelpText(env))
-
-# Package options
-env['PACKAGE_NAME'] = 'SuperTux'
-env['PACKAGE_VERSION'] = '0.2-cvs'
-env['PACKAGE_BUGREPORT'] = 'supertux-devel@lists.berlios.de'
-env['PACKAGE'] = env['PACKAGE_NAME'].lower()
-env['PACKAGE_STRING'] = env['PACKAGE_NAME'] + " " + env['PACKAGE_VERSION']
-
-# directories
-env['APPDATADIR'] = "$DATADIR/$PACKAGE"
-env['LOCALEDIR'] = "$DATADIR/locale"
-
-
-# Create build_config.py and config.h
-if not os.path.exists("build_config.py") or not os.path.exists("config.h"):
- print "build_config.py or config.h don't exist - Generating new build config..."
-
- header = ConfigHeader()
- header.Define("PACKAGE", env['PACKAGE'])
- header.Define("PACKAGE_NAME", env['PACKAGE_NAME'])
- header.Define("PACKAGE_VERSION", env['PACKAGE_VERSION'])
- header.Define("PACKAGE_BUGREPORT", env['PACKAGE_BUGREPORT'])
- header.Define("PACKAGE_STRING", env['PACKAGE_STRING'])
-
- conf = Configure(env, custom_tests = {
- 'CheckSDLConfig' : CheckSDLConfig
- })
- if not conf.CheckSDLConfig('1.2.4'):
- print "Couldn't find libSDL >= 1.2.4"
- Exit(1)
- if not conf.CheckLib('SDL_mixer'):
- print "Couldn't find SDL_mixer library!"
- Exit(1)
- if not conf.CheckLib('SDL_image'):
- print "Couldn't find SDL_image library!"
- Exit(1)
- if not conf.CheckLib('GL'):
- print "Couldn't find OpenGL library!"
- Exit(1)
-
- env = conf.Finish()
-
- env.ParseConfig('sdl-config --cflags --libs')
- env.Append(CPPDEFINES = \
- {'DATA_PREFIX':"'\"" + env.subst('$APPDATADIR') + "\"'" ,
- 'LOCALEDIR' :"'\"" + env.subst('$LOCALEDIR') + "\"'"})
- opts.Save("build_config.py", env)
- header.Save("config.h")
-else:
- print "Using build_config.py"
-
-if env['VARIANT'] == "optimize":
- env.Append(CXXFLAGS = "-O2 -g -Wall")
-elif env['VARIANT'] == "debug":
- env.Append(CXXFLAGS = "-O0 -g3 -Wall -Werror")
- env.Append(CPPDEFINES = { "DEBUG":"1" })
-elif env['VARIANT'] == "profile":
- env.Append(CXXFLAGS = "-pg -O2")
-
-build_dir="build/" + env['PLATFORM'] + "/" + env['VARIANT']
-
-# create some install aliases (only add paths here that are really used)
-env.Alias('install-data', env.subst('$DESTDIR/$APPDATADIR'))
-env.Alias('install-exec', env.subst('$DESTDIR/$BINDIR'))
-env.Alias('install', ['install-data', 'install-exec'])
-
-# append some include dirs and link libsupertux with main app
-env.Append(CPPPATH = ["#", "#/src", "#/lib"])
-env.Append(LIBS = ["supertux"])
-env.Append(LIBPATH=["#" + build_dir + "/lib"])
-
-env.Export(["env", "Glob", "InstallData", "InstallExec"])
-env.SConscript("lib/SConscript", build_dir=build_dir + "/lib", duplicate=0)
-env.SConscript("src/SConscript", build_dir=build_dir + "/src", duplicate=0)
-env.SConscript("data/SConscript", build_dir=build_dir + "/data", duplicate=0)
-env.SConscript("SConscript", build_dir=build_dir, duplicate=0)
+++ /dev/null
-import os
-Import('*')
-
-if 'install' in BUILD_TARGETS:
- patterns = ["*.txt", "levels/*/*.stl", "levels/*/*.stwm", "levelts/*/info",
- "sounds/*.wav", "music/*.mod", "music/*.ogg",
- "images/*/*.jpg", "images/*/*.png", "images/*/*/*.png",
- "images/*.xpm", "images/*.png", "images/*.strf",
- "images/tilesets/*.stgt"]
-
- files = []
- for pattern in patterns:
- files = files + Glob(pattern)
-
- InstallData(files)
"coin-7.png"
"coin-8.png"
)
- (distro #t)
+ (coin #t)
(anim-fps 10)
)
(tile
"coin3.png"
"coin2.png"
)
- (distro #t)
+ (coin #t)
(anim-fps 10)
)
(tile
[ Wildcard video : *.cpp *.h ]
[ Wildcard lisp : *.cpp *.h ]
;
-TRANSLATABLE_SOURCES += [ DoSourceGrist $(sources) ] ;
+TRANSLATABLE_SOURCES += [ SearchSource $(sources) ] ;
Library supertuxlib : $(sources) : noinstall ;
ExternalLibs supertuxlib : SDL SDLMIXER SDLIMAGE GL ;
+++ /dev/null
-Import('*')
-
-libsupertux_src = Glob("app/*.cpp") \
- + Glob("audio/*.cpp") \
- + Glob("gui/*.cpp") \
- + Glob("math/*.cpp") \
- + Glob("special/*.cpp") \
- + Glob("utils/*.cpp") \
- + Glob("video/*.cpp") \
- + Glob("lisp/*.cpp")
-
-lib = env.Library(
- target="supertux",
- source=libsupertux_src
-)
-Default(lib)
-
SDL_Surface * screen;
MouseCursor * mouse_cursor;
-bool use_gl;
-bool use_joystick;
-bool use_fullscreen;
-bool debug_mode;
-bool show_fps;
-bool debug_grid = false;
-
+#if 0
int joystick_num = 0;
char* level_startup_file = 0;
bool launch_leveleditor_mode = false;
bool launch_worldmap_mode = false;
bool flip_levels_mode = false;
+#endif
/* SuperTux directory ($HOME/.supertux) and save directory($HOME/.supertux/save) */
-std::string st_dir, st_save_dir;
+std::string user_dir;
SDL_Joystick * js;
class MouseCursor;
extern std::string datadir;
- extern std::string package_symbol_name;
- extern std::string package_name;
- extern std::string package_version;
struct JoystickKeymap
{
extern JoystickKeymap joystick_keymap;
- extern SDL_Surface* screen;
-
extern MouseCursor * mouse_cursor;
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600
- extern bool use_gl;
- extern bool use_joystick;
- extern bool use_fullscreen;
- extern int screen_width;
- extern int screen_height;
- extern bool debug_mode;
- extern bool show_fps;
- extern bool debug_grid;
-
/** The number of the joystick that will be use in the game */
extern int joystick_num;
- extern char* level_startup_file;
- extern bool launch_leveleditor_mode;
- extern bool launch_worldmap_mode;
- extern bool flip_levels_mode;
-
- /* SuperTux directory ($HOME/.supertux) and save directory($HOME/.supertux/save) */
- extern std::string st_dir;
- extern std::string st_save_dir;
+
+ /* SuperTux directory ($HOME/.supertux) */
+ extern std::string user_dir;
extern SDL_Joystick * js;
// 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 <config.h>
#include <cassert>
#include <cerrno>
#include <unistd.h>
-#include "SDL.h"
-#include "SDL_image.h"
-#ifndef NOOPENGL
-#include "SDL_opengl.h"
-#endif
-
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include "globals.h"
#include "setup.h"
-#include "video/screen.h"
-#include "video/surface.h"
-#include "gui/menu.h"
-#include "utils/configfile.h"
-#include "audio/sound_manager.h"
-#include "gettext.h"
using namespace SuperTux;
#ifdef WIN32
#define mkdir(dir, mode) mkdir(dir)
-// on win32 we typically don't want LFS paths
-#undef DATA_PREFIX
-#define DATA_PREFIX "./data/"
#endif
-/* Local function prototypes: */
-
-void seticon(void);
-void usage(char * prog, int ret);
-
/* Does the given file exist and is it accessible? */
bool FileSystem::faccessible(const std::string& filename)
{
/* Makes sure a directory is created in either the SuperTux home directory or the SuperTux base directory.*/
bool FileSystem::fcreatedir(const std::string& relative_dir)
{
- std::string path = st_dir + "/" + relative_dir + "/";
+ std::string path = user_dir + "/" + relative_dir + "/";
if(mkdir(path.c_str(),0755) != 0)
{
path = datadir + "/" + relative_dir + "/";
struct dirent *direntp;
std::set<std::string> sdirs;
std::string filename;
- std::string path = st_dir + "/" + rel_path;
+ std::string path = user_dir + "/" + rel_path;
if((dirStructP = opendir(path.c_str())) != NULL)
{
}
else
{
- filename = st_dir + "/" + rel_path + "/" + direntp->d_name + "/" + expected_file;
+ filename = user_dir + "/" + rel_path + "/" + direntp->d_name + "/" + expected_file;
if(faccessible(filename.c_str()))
continue;
}
DIR *dirStructP;
struct dirent *direntp;
std::set<std::string> sdirs;
- std::string path = st_dir + "/" + rel_path;
+ std::string path = user_dir + "/" + rel_path;
if((dirStructP = opendir(path.c_str())) != NULL)
{
return filename.substr(0, p+1);
}
-void Setup::init(const std::string& _package_name,
- const std::string& _package_symbol_name,
- const std::string& _package_version)
-{
- package_name = _package_name;
- package_symbol_name = _package_symbol_name;
- package_version = _package_version;
-
- directories();
- dictionary_manager.add_directory(datadir + "/locale");
- dictionary_manager.set_charset("iso8859-1");
-}
-
-/* --- SETUP --- */
-/* Set SuperTux configuration and save directories */
-void Setup::directories()
-{
- std::string home;
- /* Get home directory (from $HOME variable)... if we can't determine it,
- use the current directory ("."): */
- if (getenv("HOME") != NULL)
- home = getenv("HOME");
- else
- home = ".";
-
- st_dir = home + "/." + package_symbol_name;
-
- /* Remove .supertux config-file from old SuperTux versions */
- if(FileSystem::faccessible(st_dir)) {
- remove(st_dir.c_str());
- }
-
- st_save_dir = st_dir + "/save";
-
- /* Create them. In the case they exist they won't destroy anything. */
- mkdir(st_dir.c_str(), 0755);
- mkdir(st_save_dir.c_str(), 0755);
-
- mkdir((st_dir + "/levels").c_str(), 0755);
-
- // try current directory as datadir
- if(datadir.empty()) {
- if(FileSystem::faccessible("./data/credits.txt"))
- datadir = "./data/";
- }
-
- // User has not that a datadir, so we try some magic
- if (datadir.empty())
- {
-#ifndef WIN32
- // Detect datadir
- char exe_file[PATH_MAX];
- if (readlink("/proc/self/exe", exe_file, PATH_MAX) < 0)
- {
- puts("Couldn't read /proc/self/exe, using default path: " DATA_PREFIX);
- datadir = DATA_PREFIX;
- }
- else
- {
- std::string exedir = std::string(dirname(exe_file)) + "/";
-
- datadir = exedir + "./data/"; // SuperTux run from source dir
- if (access(datadir.c_str(), F_OK) != 0)
- {
- datadir = exedir + "../../../../data/"; //SuperTux run from source dir (with libtool script)
-
- if (access(datadir.c_str(), F_OK) != 0)
- {
- datadir = exedir + "../share/" + package_symbol_name + "/"; // SuperTux run from PATH
- if (access(datadir.c_str(), F_OK) != 0)
- { // If all fails, fall back to compiled path
- datadir = DATA_PREFIX;
- datadir += "/";
- }
- }
- }
- }
-#else
- datadir = DATA_PREFIX;
- datadir += "/";
-#endif
- }
- printf("Datadir: %s\n", datadir.c_str());
-}
-
-void Setup::general(void)
-{
- /* Seed random number generator: */
-
- srand(SDL_GetTicks());
-
- /* Set icon image: */
-
- seticon();
-
- /* Unicode needed for input handling: */
-
- SDL_EnableUNICODE(1);
-
- /* Load GUI/menu images: */
- checkbox = new Surface(datadir + "/images/status/checkbox.png", true);
- checkbox_checked = new Surface(datadir + "/images/status/checkbox-checked.png", true);
- back = new Surface(datadir + "/images/status/back.png", true);
- arrow_left = new Surface(datadir + "/images/icons/left.png", true);
- arrow_right = new Surface(datadir + "/images/icons/right.png", true);
-
- /* Load the mouse-cursor */
- mouse_cursor = new MouseCursor( datadir + "/images/status/mousecursor.png",1);
- MouseCursor::set_current(mouse_cursor);
-
-}
-
-void Setup::general_free(void)
-{
-
- /* Free GUI/menu images: */
- delete checkbox;
- delete checkbox_checked;
- delete back;
- delete arrow_left;
- delete arrow_right;
-
- /* Free mouse-cursor */
- delete mouse_cursor;
-
-}
-
-void Setup::video(unsigned int screen_w, unsigned int screen_h)
-{
- /* Init SDL Video: */
- if (SDL_Init(SDL_INIT_VIDEO) < 0)
- {
- fprintf(stderr,
- "\nError: I could not initialize video!\n"
- "The Simple DirectMedia error that occured was:\n"
- "%s\n\n", SDL_GetError());
- exit(1);
- }
-
- /* Open display: */
- if(use_gl)
- video_gl(screen_w, screen_h);
- else
- video_sdl(screen_w, screen_h);
-
- Surface::reload_all();
-
- /* Set window manager stuff: */
- SDL_WM_SetCaption((package_name + " " + package_version).c_str(), package_name.c_str());
-}
-
-void Setup::video_sdl(unsigned int screen_w, unsigned int screen_h)
-{
- if (use_fullscreen)
- {
- screen = SDL_SetVideoMode(screen_w, screen_h, 0, SDL_FULLSCREEN ) ; /* | SDL_HWSURFACE); */
- if (screen == NULL)
- {
- fprintf(stderr,
- "\nWarning: I could not set up fullscreen video for "
- "800x600 mode.\n"
- "The Simple DirectMedia error that occured was:\n"
- "%s\n\n", SDL_GetError());
- use_fullscreen = false;
- }
- }
- else
- {
- screen = SDL_SetVideoMode(screen_w, screen_h, 0, SDL_HWSURFACE | SDL_DOUBLEBUF );
-
- if (screen == NULL)
- {
- fprintf(stderr,
- "\nError: I could not set up video for 800x600 mode.\n"
- "The Simple DirectMedia error that occured was:\n"
- "%s\n\n", SDL_GetError());
- exit(1);
- }
- }
-}
-
-void Setup::video_gl(unsigned int screen_w, unsigned int screen_h)
-{
-#ifndef NOOPENGL
-
- SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
- SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
- SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
- SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
- SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
-
- if (use_fullscreen)
- {
- screen = SDL_SetVideoMode(screen_w, screen_h, 0, SDL_FULLSCREEN | SDL_OPENGL) ; /* | SDL_HWSURFACE); */
- if (screen == NULL)
- {
- fprintf(stderr,
- "\nWarning: I could not set up fullscreen video for "
- "640x480 mode.\n"
- "The Simple DirectMedia error that occured was:\n"
- "%s\n\n", SDL_GetError());
- use_fullscreen = false;
- }
- }
- else
- {
- screen = SDL_SetVideoMode(screen_w, screen_h, 0, SDL_OPENGL);
-
- if (screen == NULL)
- {
- fprintf(stderr,
- "\nError: I could not set up video for 640x480 mode.\n"
- "The Simple DirectMedia error that occured was:\n"
- "%s\n\n", SDL_GetError());
- exit(1);
- }
- }
-
- /*
- * Set up OpenGL for 2D rendering.
- */
- glDisable(GL_DEPTH_TEST);
- glDisable(GL_CULL_FACE);
-
- glViewport(0, 0, screen->w, screen->h);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0, 800, 600, 0, -1.0, 1.0);
- //glOrtho(0, 800SCREEN_WIDTH, SCREEN_HEIGHT, 0, -1.0, 1.0);
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glTranslatef(0.0f, 0.0f, 0.0f);
-
-#endif
-
-}
-
-void Setup::joystick(void)
-{
-
- /* Init Joystick: */
-
- use_joystick = true;
-
- if (SDL_Init(SDL_INIT_JOYSTICK) < 0)
- {
- fprintf(stderr, "Warning: I could not initialize joystick!\n"
- "The Simple DirectMedia error that occured was:\n"
- "%s\n\n", SDL_GetError());
-
- use_joystick = false;
- }
- else
- {
- /* Open joystick: */
- if (SDL_NumJoysticks() <= 0)
- {
- fprintf(stderr, "Info: No joysticks were found.\n");
-
- use_joystick = false;
- }
- else
- {
- js = SDL_JoystickOpen(joystick_num);
-
- if (js == NULL)
- {
- fprintf(stderr, "Warning: Could not open joystick %d.\n"
- "The Simple DirectMedia error that occured was:\n"
- "%s\n\n", joystick_num, SDL_GetError());
-
- use_joystick = false;
- }
- else
- {
- if (SDL_JoystickNumAxes(js) < 2)
- {
- fprintf(stderr,
- "Warning: Joystick does not have enough axes!\n");
-
- use_joystick = false;
- }
- else
- {
- if (SDL_JoystickNumButtons(js) < 2)
- {
- fprintf(stderr,
- "Warning: "
- "Joystick does not have enough buttons!\n");
-
- use_joystick = false;
- }
- }
- }
- }
- }
-}
-
-void Setup::audio(void)
-{
-
- /* Init SDL Audio silently even if --disable-sound : */
-
- if (SoundManager::get()->audio_device_available())
- {
- if (SDL_Init(SDL_INIT_AUDIO) < 0)
- {
- /* only print out message if sound or music
- was not disabled at command-line
- */
- if (SoundManager::get()->sound_enabled() || SoundManager::get()->music_enabled())
- {
- fprintf(stderr,
- "\nWarning: I could not initialize audio!\n"
- "The Simple DirectMedia error that occured was:\n"
- "%s\n\n", SDL_GetError());
- }
- /* keep the programming logic the same :-)
- because in this case, use_sound & use_music' values are ignored
- when there's no available audio device
- */
- SoundManager::get()->enable_sound(false);
- SoundManager::get()->enable_music(false);
- SoundManager::get()->set_audio_device_available(false);
- }
- }
-
-
- /* Open sound silently regarless the value of "use_sound": */
-
- if (SoundManager::get()->audio_device_available())
- {
- if (SoundManager::get()->open_audio(44100, AUDIO_S16, 2, 2048) < 0)
- {
- /* only print out message if sound or music
- was not disabled at command-line
- */
- if (SoundManager::get()->sound_enabled() || SoundManager::get()->music_enabled())
- {
- fprintf(stderr,
- "\nWarning: I could not set up audio for 44100 Hz "
- "16-bit stereo.\n"
- "The Simple DirectMedia error that occured was:\n"
- "%s\n\n", SDL_GetError());
- }
- SoundManager::get()->enable_sound(false);
- SoundManager::get()->enable_music(false);
- SoundManager::get()->set_audio_device_available(false);
- }
- }
-
-}
-
-
-/* --- SHUTDOWN --- */
-
-void Termination::shutdown(void)
-{
- config->save();
- SoundManager::get()->close_audio();
- SDL_Quit();
-}
-
-/* --- ABORT! --- */
-
-void Termination::abort(const std::string& reason, const std::string& details)
-{
- fprintf(stderr, "\nError: %s\n%s\n\n", reason.c_str(), details.c_str());
- shutdown();
- ::abort();
-}
-
-/* Set Icon (private) */
-
-void seticon(void)
-{
-// int masklen;
-// Uint8 * mask;
- SDL_Surface * icon;
-
-
- /* Load icon into a surface: */
-
- icon = IMG_Load((datadir + "/images/" + package_symbol_name + ".xpm").c_str());
- if (icon == NULL)
- {
- fprintf(stderr,
- "\nError: I could not load the icon image: %s%s\n"
- "The Simple DirectMedia error that occured was:\n"
- "%s\n\n", datadir.c_str(), ("/images/" + package_symbol_name + ".xpm").c_str(), SDL_GetError());
- exit(1);
- }
-
-
- /* Create mask: */
-/*
- masklen = (((icon -> w) + 7) / 8) * (icon -> h);
- mask = (Uint8*) malloc(masklen * sizeof(Uint8));
- memset(mask, 0xFF, masklen);
-*/
-
- /* Set icon: */
-
- SDL_WM_SetIcon(icon, NULL);//mask);
-
-
- /* Free icon surface & mask: */
-
-// free(mask);
- SDL_FreeSurface(icon);
-}
-
-
-/* Parse command-line arguments: */
-
-void Setup::parseargs(int argc, char * argv[])
-{
- int i;
-
- config->load();
-
- /* Parse arguments: */
-
- for (i = 1; i < argc; i++)
- {
- if (strcmp(argv[i], "--fullscreen") == 0 ||
- strcmp(argv[i], "-f") == 0)
- {
- use_fullscreen = true;
- }
- else if (strcmp(argv[i], "--window") == 0 ||
- strcmp(argv[i], "-w") == 0)
- {
- use_fullscreen = false;
- }
- else if (strcmp(argv[i], "--geometry") == 0 ||
- strcmp(argv[i], "-g") == 0)
- {
- assert(i+1 < argc);
- if (sscanf(argv[++i],
- "%dx%d", &screen_width, &screen_height) != 2)
- {
- puts("Warning: Invalid geometry spec, should be \"WIDTHxHEIGHT\"");
- }
- }
- else if (strcmp(argv[i], "--joystick") == 0 || strcmp(argv[i], "-j") == 0)
- {
- assert(i+1 < argc);
- joystick_num = atoi(argv[++i]);
- }
- else if (strcmp(argv[i], "--joymap") == 0)
- {
- assert(i+1 < argc);
- if (sscanf(argv[++i],
- "%d:%d:%d:%d:%d",
- &joystick_keymap.x_axis,
- &joystick_keymap.y_axis,
- &joystick_keymap.a_button,
- &joystick_keymap.b_button,
- &joystick_keymap.start_button) != 5)
- {
- puts("Warning: Invalid or incomplete joymap, should be: 'XAXIS:YAXIS:A:B:START'");
- }
- else
- {
- std::cout << "Using new joymap:\n"
- << " X-Axis: " << joystick_keymap.x_axis << "\n"
- << " Y-Axis: " << joystick_keymap.y_axis << "\n"
- << " A-Button: " << joystick_keymap.a_button << "\n"
- << " B-Button: " << joystick_keymap.b_button << "\n"
- << " Start-Button: " << joystick_keymap.start_button << std::endl;
- }
- }
- else if (strcmp(argv[i], "--leveleditor") == 0)
- {
- launch_leveleditor_mode = true;
- }
- else if (strcmp(argv[i], "--worldmap") == 0)
- {
- launch_worldmap_mode = true;
- }
- else if (strcmp(argv[i], "--flip-levels") == 0)
- {
- flip_levels_mode = true;
- }
- else if (strcmp(argv[i], "--datadir") == 0
- || strcmp(argv[i], "-d") == 0 )
- {
- assert(i+1 < argc);
- datadir = argv[++i];
- }
- else if (strcmp(argv[i], "--show-fps") == 0)
- {
- /* Use full screen: */
- show_fps = true;
- }
- else if (strcmp(argv[i], "--opengl") == 0 ||
- strcmp(argv[i], "-gl") == 0)
- {
-#ifndef NOOPENGL
- /* Use OpengGL: */
- use_gl = true;
-#endif
- }
- else if (strcmp(argv[i], "--sdl") == 0)
- {
- use_gl = false;
- }
- else if (strcmp(argv[i], "--usage") == 0)
- {
- /* Show usage: */
- usage(argv[0], 0);
- }
- else if (strcmp(argv[i], "--version") == 0)
- {
- /* Show version: */
- printf((package_name + " " + package_version + "\n").c_str() );
- exit(0);
- }
- else if (strcmp(argv[i], "--disable-sound") == 0)
- {
- /* Disable the compiled in sound feature */
- printf("Sounds disabled \n");
- SoundManager::get()->enable_sound(false);
- }
- else if (strcmp(argv[i], "--disable-music") == 0)
- {
- /* Disable the compiled in sound feature */
- printf("Music disabled \n");
- SoundManager::get()->enable_music(false);
- }
- else if (strcmp(argv[i], "--debug") == 0)
- {
- /* Enable the debug-mode */
- debug_mode = true;
-
- }
- else if (strcmp(argv[i], "--help") == 0)
- { /* Show help: */
- puts(_((" SuperTux " + package_version + "\n"
- " Please see the file \"README.txt\" for more details.\n").c_str()));
- printf(_("Usage: %s [OPTIONS] FILENAME\n\n"), argv[0]);
- puts(_("Display Options:\n"
- " -f, --fullscreen Run in fullscreen mode.\n"
- " -w, --window Run in window mode.\n"
- " --opengl If OpenGL support was compiled in, this will tell\n"
- " SuperTux to make use of it.\n"
- " --sdl Use the SDL software graphical renderer\n"
- " --geometry WIDTHxHEIGHT Run SuperTux in the given resolution\n"
- "\n"
- "Sound Options:\n"
- " --disable-sound If sound support was compiled in, this will\n"
- " disable sound for this session of the game.\n"
- " --disable-music Like above, but this will disable music.\n"
- "\n"
- "Misc Options:\n"
- " -j, --joystick NUM Use joystick NUM (default: 0)\n"
- " --joymap XAXIS:YAXIS:A:B:START\n"
- " Define how joystick buttons and axis should be mapped\n"
- " --leveleditor Opens the leveleditor in a file.\n"
- " --worldmap Opens the specified worldmap file.\n"
- " --flip-levels Flip levels upside-down.\n"
- " -d, --datadir DIR Load Game data from DIR (default: automatic)\n"
- " --debug Enables the debug mode, which is useful for developers.\n"
- " --help Display a help message summarizing command-line\n"
- " options, license and game controls.\n"
- " --usage Display a brief message summarizing command-line options.\n"
- " --version Display the version of SuperTux you're running.\n\n"
- ));
- exit(0);
- }
- else if (argv[i][0] != '-')
- {
- level_startup_file = argv[i];
- }
- else
- {
- /* Unknown - complain! */
-
- usage(argv[0], 1);
- }
- }
-}
-
-
-/* Display usage: */
-
-void usage(char * prog, int ret)
-{
- FILE * fi;
-
-
- /* Determine which stream to write to: */
-
- if (ret == 0)
- fi = stdout;
- else
- fi = stderr;
-
-
- /* Display the usage message: */
-
- fprintf(fi, _("Usage: %s [--fullscreen] [--opengl] [--geometry WIDTHxHEIGHT] [--disable-sound] [--disable-music] [--debug] | [--usage | --help | --version] [--leveleditor] [--worldmap] [--flip-levels] FILENAME\n"),
- prog);
-
-
- /* Quit! */
-
- exit(ret);
-}
-
std::set<std::string> FileSystem::read_directory(const std::string& pathname)
{
std::set<std::string> dirnames;
return dirnames;
}
-
-/* EOF */
static std::string dirname(const std::string& filename);
};
-/// All you need to get an application up and running
-struct Setup
- {
- static void init(const std::string& _package_name, const std::string& _package_symbol_name, const std::string& _package_version);
- static void directories(void);
- static void general(void);
- static void general_free();
- static void video(unsigned int screen_w, unsigned int screen_h);
- static void audio(void);
- static void joystick(void);
- static void parseargs(int argc, char * argv[]);
-
- private:
- static void video_sdl(unsigned int screen_w, unsigned int screen_h);
- static void video_gl(unsigned int screen_w, unsigned int screen_h);
- };
-
-/// Termination handling
-struct Termination
- {
- static void shutdown(void);
- static void abort(const std::string& reason, const std::string& details);
- };
-
} //namespace SuperTux
#endif /*SUPERTUX_SETUP_H*/
iconv_t cd = iconv_open(to_charset.c_str(), from_charset.c_str());
size_t in_len = text.length();
- size_t out_len = text.length()*2;
+ size_t out_len = text.length()*3; // FIXME: cross fingers that this is enough
- char* out_orig = new char[out_len]; // FIXME: cross fingers that this is enough
+ char* out_orig = new char[out_len];
char* in_orig = new char[in_len+1];
strcpy(in_orig, text.c_str());
char* out = out_orig;
char* in = in_orig;
+ size_t out_len_temp = out_len; // iconv is counting down the bytes it has
+ // written from this...
- //std::cout << "IN: " << (int)in << " " << in_len << " " << (int)out << " " << out_len << std::endl;
- int retval = iconv(cd, &in, &in_len, &out, &out_len);
- //std::cout << "OUT: " << (int)in << " " << in_len << " " << (int)out << " " << out_len << std::endl;
-
- if (retval != 0)
+ size_t retval = iconv(cd, &in, &in_len, &out, &out_len_temp);
+ out_len -= out_len_temp; // see above
+ if (retval == (size_t) -1)
{
std::cerr << strerror(errno) << std::endl;
std::cerr << "Error: conversion from " << from_charset
<< " to " << to_charset << " went wrong: " << retval << std::endl;
+ return "";
}
iconv_close(cd);
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2000 Bill Kendrick <bill@newbreedsoftware.com>
-// Copyright (C) 2004 Matthias Braun <matze@braunis.de>
-//
-// 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 <config.h>
-
-#include "audio/musicref.h"
-
-using namespace SuperTux;
-
-MusicRef::MusicRef()
- : music(0)
-{
-}
-
-MusicRef::MusicRef(SoundManager::MusicResource* newmusic)
- : music(newmusic)
-{
- if(music)
- music->refcount++;
-}
-
-MusicRef::~MusicRef()
-{
- if(music) {
- music->refcount--;
- if(music->refcount == 0)
- music->manager->free_music(music);
- }
-}
-
-MusicRef::MusicRef(const MusicRef& other)
- : music(other.music)
-{
- if(music)
- music->refcount++;
-}
-
-MusicRef&
-MusicRef::operator =(const MusicRef& other)
-{
- SoundManager::MusicResource* oldres = music;
- music = other.music;
- if(music)
- music->refcount++;
- if(oldres) {
- oldres->refcount--;
- if(oldres->refcount == 0)
- music->manager->free_music(music);
- }
-
- return *this;
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2004 Matthias Braun <matze@braunis.de>
-//
-// 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_MUSICREF_H
-#define SUPERTUX_MUSICREF_H
-
-#include "sound_manager.h"
-
-namespace SuperTux
- {
-
- /** This class holds a reference to a music file and maintains a correct
- * refcount for that file.
- */
- class MusicRef
- {
- public:
- MusicRef();
- MusicRef(const MusicRef& other);
- ~MusicRef();
-
- MusicRef& operator= (const MusicRef& other);
-
- private:
- friend class SoundManager;
- MusicRef(SoundManager::MusicResource* music);
-
- SoundManager::MusicResource* music;
- };
-
-} //namespace SuperTux
-
-#endif /*SUPERTUX_MUSICREF_H*/
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2004 Matthias Braun <matze@braunis.de
-//
-// 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 <config.h>
-
-#include <cmath>
-#include <cassert>
-
-#include "audio/sound_manager.h"
-#include "audio/musicref.h"
-#include "app/globals.h"
-#include "app/setup.h"
-#include "special/moving_object.h"
-
-using namespace SuperTux;
-
-SoundManager* SoundManager::instance_ = 0;
-
-SoundManager::SoundManager()
- : current_music(0), m_music_enabled(true) , m_sound_enabled(true),
- audio_device(true)
-{
-}
-
-SoundManager::~SoundManager()
-{
- if(audio_device)
- Mix_HaltMusic();
-
- sounds.clear();
-}
-
-void
-SoundManager::play_sound(Mix_Chunk* sound)
-{
- if(!audio_device || !m_sound_enabled)
- return;
-
- Mix_PlayChannel(-1, sound, 0);
-}
-
-void
-SoundManager::play_sound(Mix_Chunk* sound, const MovingObject* object, const Vector& pos)
-{
- // TODO keep track of the object later and move the sound along with the
- // object.
- play_sound(sound, object->get_pos(), pos);
-}
-
-void
-SoundManager::play_sound(Mix_Chunk* sound, const Vector& pos, const Vector& pos2)
-{
- if(!audio_device || !m_sound_enabled)
- return;
-
- // TODO make sure this formula is good
- float distance
- = pos2.x- pos.x;
- int loud = int(255.0/float(SCREEN_WIDTH*2) * fabsf(distance));
- if(loud > 255)
- return;
-
- int chan = Mix_PlayChannel(-1, sound, 0);
- if(chan < 0)
- return;
- Mix_SetDistance(chan, loud);
-
- // very bad way to do this...
- if(distance > 100)
- Mix_SetPanning(chan, 230, 24);
- else if(distance < -100)
- Mix_SetPanning(chan, 24, 230);
-}
-
-MusicRef
-SoundManager::load_music(const std::string& file)
-{
- if(!audio_device)
- return MusicRef(0);
-
- if(!exists_music(file))
- Termination::abort("Couldn't load musicfile ", file.c_str());
-
- std::map<std::string, MusicResource>::iterator i = musics.find(file);
- assert(i != musics.end());
- return MusicRef(& (i->second));
-}
-
-bool
-SoundManager::exists_music(const std::string& file)
-{
- if(!audio_device)
- return true;
-
- // song already loaded?
- std::map<std::string, MusicResource>::iterator i = musics.find(file);
- if(i != musics.end()) {
- return true;
- }
-
- Mix_Music* song = Mix_LoadMUS(file.c_str());
- if(song == 0)
- return false;
-
- // insert into music list
- std::pair<std::map<std::string, MusicResource>::iterator, bool> result =
- musics.insert(
- std::make_pair<std::string, MusicResource> (file, MusicResource()));
- MusicResource& resource = result.first->second;
- resource.manager = this;
- resource.music = song;
-
- return true;
-}
-
-void
-SoundManager::free_music(MusicResource* )
-{
- // TODO free music, currently we can't do this since SDL_mixer seems to have
- // some bugs if you load/free alot of mod files.
-}
-
-void
-SoundManager::play_music(const MusicRef& musicref, int loops)
-{
- if(!audio_device)
- return;
-
- if(musicref.music == 0 || current_music == musicref.music)
- return;
-
- if(current_music)
- current_music->refcount--;
-
- current_music = musicref.music;
- current_music->refcount++;
-
- if(m_music_enabled)
- Mix_PlayMusic(current_music->music, loops);
-}
-
-void
-SoundManager::halt_music()
-{
- if(!audio_device)
- return;
-
- Mix_HaltMusic();
-
- if(current_music) {
- current_music->refcount--;
- if(current_music->refcount == 0)
- free_music(current_music);
- current_music = 0;
- }
-}
-
-void
-SoundManager::enable_music(bool enable)
-{
- if(!audio_device)
- return;
-
- if(enable == m_music_enabled)
- return;
-
- m_music_enabled = enable;
- if(m_music_enabled == false) {
- Mix_HaltMusic();
- } else {
- if(current_music)
- Mix_PlayMusic(current_music->music, -1);
- }
-}
-
-void
-SoundManager::enable_sound(bool enable)
-{
- if(!audio_device)
- return;
-
- m_sound_enabled = enable;
-}
-
-SoundManager::MusicResource::~MusicResource()
-{
- // don't free music buggy SDL_Mixer crashs for some mod files
- // Mix_FreeMusic(music);
-}
-
-/* --- LOAD A SOUND --- */
-
-Mix_Chunk* SoundManager::load_sound(const std::string& file)
-{
- if(!audio_device)
- return 0;
-
- Mix_Chunk* snd = Mix_LoadWAV(file.c_str());
-
- /*if (snd == 0)
- Termination::abort("Can't load", file);*/
-
- return(snd);
-}
-
-void SoundManager::free_chunk(Mix_Chunk *chunk)
-{
- Mix_FreeChunk( chunk );
-}
-
-
-/* --- OPEN THE AUDIO DEVICE --- */
-
-int SoundManager::open_audio (int frequency, Uint16 format, int channels, int chunksize)
-{
- if (Mix_OpenAudio( frequency, format, channels, chunksize ) < 0)
- return -1;
-
- // allocate 16 channels for mixing
- if (Mix_AllocateChannels(8) != 8)
- return -2;
-
- return 0;
-}
-
-
-/* --- CLOSE THE AUDIO DEVICE --- */
-
-void SoundManager::close_audio( void )
-{
- if (audio_device) {
- Mix_CloseAudio();
- }
-}
-
-Mix_Chunk* SuperTux::IDToSound(int id)
-{
- return SoundManager::get()->sounds[id];
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2004 Matthias Braun <matze@braunis.de
-//
-// 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_SOUND_MANAGER_H
-#define SUPERTUX_SOUND_MANAGER_H
-
-#include <string>
-#include <vector>
-#include <map>
-
-#include "SDL_mixer.h"
-#include "math/vector.h"
-
-namespace SuperTux
- {
-
- class MusicRef;
- class MovingObject;
-
- /// enum of different internal music types
- enum Music_Type {
- NO_MUSIC,
- LEVEL_MUSIC,
- HURRYUP_MUSIC,
- HERRING_MUSIC
- };
-
- /// Sound manager
- /** This class handles all sounds that are played
- */
- class SoundManager
- {
- public:
- /// Play sound.
- void play_sound(Mix_Chunk* sound);
- /// Play sound relative to two Vectors.
- void play_sound(Mix_Chunk* sound, const Vector& pos, const Vector& pos2);
- /// Play sound relative to a MovingObject and a Vector.
- void play_sound(Mix_Chunk* sound, const MovingObject* object, const Vector& pos);
-
- /// Load music.
- /** Is used to load the music for a MusicRef. */
- MusicRef load_music(const std::string& file);
-
- /// Load sound.
- Mix_Chunk* load_sound(const std::string& file);
-
- /// Test if a certain music file exists.
- bool exists_music(const std::string& filename);
-
- /// Play music.
- /** @param loops: Defaults to -1, which means endless loops. */
- void play_music(const MusicRef& music, int loops = -1);
-
- /// Halt music.
- void halt_music();
-
- /// Enable/Disable music.
- void enable_music(bool enable);
-
- /// Is music enabled?
- bool music_enabled()
- {
- return m_music_enabled;
- }
-
- /// Enable/Disable sound.
- void enable_sound(bool enable);
-
- /// Is sound enabled?
- bool sound_enabled()
- {
- return m_sound_enabled;
- }
-
- /* functions handling the sound and music */
- int open_audio(int frequency, Uint16 format, int channels, int chunksize);
- void close_audio( void );
-
- /// Is audio available?
- bool audio_device_available()
- {
- return audio_device;
- }
-
- void set_audio_device_available(bool available)
- {
- audio_device = available;
- }
-
- static SoundManager* get()
- {
- return instance_ ? instance_ : instance_ = new SoundManager();
- }
- static void destroy_instance()
- {
- delete instance_;
- instance_ = 0;
- }
-
- void add_sound(Mix_Chunk* sound, int id)
- {
- sounds[id] = sound;
- }
-
- Mix_Chunk* get_sound(int id)
- {
- return sounds[id];
- }
-
- private:
- SoundManager();
- ~SoundManager();
-
- // music part
- friend class MusicRef;
- friend class Setup;
- friend Mix_Chunk* IDToSound(int id);
-
- static SoundManager* instance_ ;
-
- void free_chunk(Mix_Chunk* chunk);
-
- /// Resource for music.
- /** Contains the raw music data and
- information for music reference
- counting. */
- class MusicResource
- {
- public:
- ~MusicResource();
-
- SoundManager* manager;
- Mix_Music* music;
- int refcount;
- };
-
- void free_music(MusicResource* music);
-
- /*variables for stocking the sound and music*/
- std::map<int, Mix_Chunk*> sounds;
- std::map<std::string, MusicResource> musics;
- MusicResource* current_music;
- bool m_music_enabled;
- bool m_sound_enabled;
- bool audio_device; /* != 0: available and initialized */
- };
-
- Mix_Chunk* IDToSound(int id);
-
-} // namespace SuperTux
-#endif /*SUPERTUX_SOUND_MANAGER_H*/
-
+++ /dev/null
-/***************************************************************************
- button.cpp - graphical buttons
- -------------------
- begin : June, 23 2004
- copyright : (C) 2004 by Ricardo Cruz
- email : rick2@aeiou.pt
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * 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. *
- * *
- ***************************************************************************/
-
-#include <config.h>
-
-#include "SDL.h"
-#include <iostream>
-
-#include "button.h"
-#include "mousecursor.h"
-#include "app/globals.h"
-#include "video/font.h"
-
-using namespace SuperTux;
-
-Font* Button::info_font = 0;
-
-/* Buttons */
-
-Button::Button(Surface* image_, std::string info_, SDLKey binding_)
- : binding(binding_)
-{
-image = image_;
-size = Vector(image->w, image->h);
-id = 0;
-info = info_;
-}
-
-Button::~Button()
-{
-}
-
-void Button::draw(DrawingContext &context, bool selected)
-{
-if(selected)
- context.draw_filled_rect(pos, size, Color (200,240,220), LAYER_GUI);
-else
- context.draw_filled_rect(pos, size, Color (200,200,220), LAYER_GUI);
-
-Vector tanslation = -context.get_translation();
-if(state == BT_SHOW_INFO)
- {
- Vector offset;
- if(pos.x + tanslation.x < 100 && pos.y + tanslation.y > SCREEN_HEIGHT - 20)
- offset = Vector(size.x, - 10);
- else if(pos.x + tanslation.x < 100)
- offset = Vector(size.x, 0);
- else
- offset = Vector(-30, -size.y/2);
- context.draw_text(info_font, info, pos + offset, LEFT_ALLIGN, LAYER_GUI+2);
- if(binding != 0)
- context.draw_text(info_font, "(" + std::string(SDL_GetKeyName(binding)) +
- ")", pos + offset + Vector(0,12),
- LEFT_ALLIGN, LAYER_GUI+2);
- }
-
-context.draw_surface_part(image, Vector(0,0), size, pos, LAYER_GUI+1);
-}
-
-int Button::event(SDL_Event &event, int x_offset, int y_offset)
-{
-state = BT_NONE;
-switch(event.type)
- {
- case SDL_MOUSEBUTTONDOWN:
- if(event.button.x > pos.x + x_offset && event.button.x < pos.x + x_offset + size.x &&
- event.button.y > pos.y + y_offset && event.button.y < pos.y + y_offset + size.y)
- {
- if(event.button.button == SDL_BUTTON_RIGHT)
- state = BT_SHOW_INFO;
- }
- break;
- case SDL_MOUSEBUTTONUP:
- if(event.button.x > pos.x + x_offset && event.button.x < pos.x + x_offset + size.x &&
- event.button.y > pos.y + y_offset && event.button.y < pos.y + y_offset + size.y)
- {
- if(event.button.button == SDL_BUTTON_LEFT)
- state = BT_SELECTED;
- }
- break;
- case SDL_KEYDOWN: // key pressed
- if(event.key.keysym.sym == binding)
- state = BT_SELECTED;
- break;
- default:
- break;
- }
-return state;
-}
-
-/* Group of buttons */
-
-ButtonGroup::ButtonGroup(Vector pos_, Vector buttons_size_, Vector buttons_box_)
- : pos(pos_), buttons_size(buttons_size_), buttons_box(buttons_box_)
-{
-buttons.clear();
-row = 0;
-button_selected = -1;
-mouse_hover = false;
-mouse_left_button = false;
-buttons_pair_nb = 0;
-}
-
-ButtonGroup::~ButtonGroup()
-{
-}
-
-void ButtonGroup::add_button(Button button, int id, bool select)
-{
-button.pos.x = ((buttons.size()-buttons_pair_nb) % (int)buttons_box.x) * buttons_size.x;
-button.pos.y = ((int)((buttons.size()-buttons_pair_nb) / buttons_box.x)) * buttons_size.y;
-button.size = buttons_size;
-button.id = id;
-if(select)
- button_selected = id;
-
-buttons.push_back(button);
-}
-
-void ButtonGroup::add_pair_of_buttons(Button button1, int id1, Button button2, int id2)
-{
-button1.pos.x = button2.pos.x = ((buttons.size()-buttons_pair_nb) % (int)buttons_box.x) * buttons_size.x;
-button1.pos.y = button2.pos.y = ((int)((buttons.size()-buttons_pair_nb) / buttons_box.x)) * buttons_size.y;
-button1.size.x = button2.size.x = buttons_size.x;
-button1.size.y = button2.size.y = buttons_size.y / 2;
-button2.pos.y += buttons_size.y / 2;
-button1.id = id1;
-button2.id = id2;
-
-buttons_pair_nb++;
-buttons.push_back(button1);
-buttons.push_back(button2);
-}
-
-void ButtonGroup::draw(DrawingContext &context)
-{
-context.draw_filled_rect(pos - Vector(12,4),
- Vector(buttons_size.x*buttons_box.x + 16, buttons_size.y*buttons_box.y + 8),
- Color (0,0,0, 128), LAYER_GUI-1);
-
-context.push_transform();
-context.set_translation(Vector(-pos.x, -pos.y + buttons_size.y*row));
-for(Buttons::iterator i = buttons.begin(); i != buttons.end(); ++i)
- {
- if(i->pos.y < row*buttons_size.y ||
- i->pos.y + i->size.y > (row + buttons_box.y) * buttons_size.y)
- continue;
-
- i->draw(context, i->id == button_selected ? true : false);
- }
-context.pop_transform();
-}
-
-bool ButtonGroup::event(SDL_Event &event)
-{
-bool caught_event = false;
-
-switch(event.type)
- {
- case SDL_MOUSEMOTION:
- mouse_hover = false;
-
- if(mouse_left_button)
- {
- pos.x += int(event.motion.xrel * float(SCREEN_WIDTH)/screen->w);
- pos.y += int(event.motion.yrel * float(SCREEN_HEIGHT)/screen->h);
- caught_event = true;
- }
- if(event.button.x > pos.x-12 && event.button.x < pos.x+16 + buttons_box.x*buttons_size.x &&
- event.button.y > pos.y-4 && event.button.y < pos.y+8 + buttons_box.y*buttons_size.y)
- mouse_hover = true;
- break;
- case SDL_MOUSEBUTTONDOWN:
- if(event.button.x < pos.x-12 || event.button.x > pos.x+16 +
- buttons_box.x*buttons_size.x || event.button.y < pos.y-4 ||
- event.button.y > pos.y+8 + buttons_box.y*buttons_size.y)
- break;
-
- caught_event = true;
-
- if(event.button.button == SDL_BUTTON_WHEELUP)
- {
- row--;
- if(row < 0)
- row = 0;
- }
- else if(event.button.button == SDL_BUTTON_WHEELDOWN)
- {
- row++;
- if(row > (int)((buttons.size()-buttons_pair_nb)/buttons_box.x) - (int)buttons_box.y +
- ((int)(buttons.size()-buttons_pair_nb)%(int)buttons_box.x != 0 ? 1 : 0))
- row = (int)((buttons.size()-buttons_pair_nb)/buttons_box.x) - (int)buttons_box.y +
- ((int)(buttons.size()-buttons_pair_nb)%(int)buttons_box.x != 0 ? 1 : 0);
- }
- else if(event.button.button == SDL_BUTTON_LEFT)
- mouse_left_button = true;
- else
- caught_event = false;
- break;
- case SDL_MOUSEBUTTONUP:
- mouse_left_button = false;
- break;
- default:
- break;
- }
-
-if(caught_event)
- return true;
-
-for(Buttons::iterator i = buttons.begin(); i != buttons.end(); ++i)
- {
- if(i->pos.y < row*buttons_size.y ||
- i->pos.y + i->size.y > (row + buttons_box.y) * buttons_size.y)
- continue;
-
- if(i->event(event, (int)pos.x,
- (int)pos.y - row*(int)buttons_size.y) == BT_SELECTED)
- {
- button_selected = i->id;
- caught_event = true;
- break;
- }
- }
-
-return caught_event;
-}
-
-int ButtonGroup::selected_id()
-{
-return button_selected;
-}
-
-void ButtonGroup::set_unselected()
-{
-button_selected = -1;
-}
-
-bool ButtonGroup::is_hover()
-{
-return mouse_hover;
-}
+++ /dev/null
-/***************************************************************************
- button.h - graphical buttons
- -------------------
- begin : June, 23 2004
- copyright : (C) 2004 by Ricardo Cruz
- email : rick2@aeiou.pt
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * 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. *
- * *
- ***************************************************************************/
-
-#ifndef SUPERTUX_BUTTON_H
-#define SUPERTUX_BUTTON_H
-
-#include <vector>
-#include <string>
-
-#include "math/vector.h"
-#include "video/drawing_context.h"
-
-namespace SuperTux
- {
-class Surface;
-class ButtonGroup;
-
-enum {
- BT_NONE,
- BT_HOVER,
- BT_SELECTED,
- BT_SHOW_INFO
- };
-
-class Button
-{
-public:
- Button(Surface* image_, std::string info_, SDLKey binding_);
- ~Button();
-
- void draw(DrawingContext& context, bool selected);
- int event(SDL_Event& event, int x_offset = 0, int y_offset = 0);
-
- static Font* info_font;
-
-private:
- friend class ButtonGroup;
-
- Vector pos, size;
-
- Surface* image;
- SDLKey binding;
-
- int id;
- int state;
- std::string info;
-};
-
-class ButtonGroup
-{
-public:
- ButtonGroup(Vector pos_, Vector size_, Vector button_box_);
- ~ButtonGroup();
-
- void draw(DrawingContext& context);
- bool event(SDL_Event& event);
-
- void add_button(Button button, int id, bool select = false);
- void add_pair_of_buttons(Button button1, int id1, Button button2, int id2);
-
- int selected_id();
- void set_unselected();
- bool is_hover();
-
-private:
- Vector pos, buttons_size, buttons_box;
- typedef std::vector <Button> Buttons;
- Buttons buttons;
-
- int button_selected, row;
- bool mouse_hover, mouse_left_button;
-
- int buttons_pair_nb;
-};
-
-} //namespace SuperTux
-
-#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-//
-// 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 WIN32
-#include <config.h>
-
-#include <sys/types.h>
-#include <ctype.h>
-#endif
-
-#include <iostream>
-#include <sstream>
-#include <cstdlib>
-#include <cstdio>
-#include <string>
-#include <cassert>
-
-#include "app/globals.h"
-#include "menu.h"
-#include "video/screen.h"
-#include "video/drawing_context.h"
-#include "app/setup.h"
-#include "app/gettext.h"
-#include "math/vector.h"
-
-using namespace SuperTux;
-
-#define FLICK_CURSOR_TIME 500
-
-Surface* SuperTux::checkbox;
-Surface* SuperTux::checkbox_checked;
-Surface* SuperTux::back;
-Surface* SuperTux::arrow_left;
-Surface* SuperTux::arrow_right;
-
-std::vector<Menu*> Menu::last_menus;
-Menu* Menu::current_ = 0;
-Font* Menu::default_font;
-Font* Menu::active_font;
-Font* Menu::deactive_font;
-Font* Menu::label_font;
-Font* Menu::field_font;
-
-/* just displays a Yes/No text that can be used to confirm stuff */
-bool SuperTux::confirm_dialog(Surface *background, std::string text)
-{
- //Surface* cap_screen = Surface::CaptureScreen();
-
- Menu* dialog = new Menu;
- dialog->additem(MN_DEACTIVE, text,0,0);
- dialog->additem(MN_HL,"",0,0);
- dialog->additem(MN_ACTION,_("Yes"),0,0,true);
- dialog->additem(MN_ACTION,_("No"),0,0,false);
- dialog->additem(MN_HL,"",0,0);
-
- Menu::set_current(dialog);
-
- DrawingContext context;
-
- while(true)
- {
- SDL_Event event;
-
- while (SDL_PollEvent(&event))
- {
- dialog->event(event);
- }
-
- if(background == NULL)
- context.draw_gradient(Color(200,240,220), Color(200,200,220), LAYER_BACKGROUND0);
- else
- context.draw_surface(background, Vector(0,0), LAYER_BACKGROUND0);
-
- dialog->draw(context);
- dialog->action();
-
- switch (dialog->check())
- {
- case true:
- //delete cap_screen;
- Menu::set_current(0);
- delete dialog;
- return true;
- break;
- case false:
- //delete cap_screen;
- Menu::set_current(0);
- delete dialog;
- return false;
- break;
- default:
- break;
- }
-
- mouse_cursor->draw(context);
- context.do_drawing();
- SDL_Delay(25);
- }
-
- return false;
-}
-
-void
-Menu::push_current(Menu* pmenu)
-{
- if (current_)
- last_menus.push_back(current_);
-
- current_ = pmenu;
- current_->effect.start(500);
-}
-
-void
-Menu::pop_current()
-{
- if (!last_menus.empty())
- {
- current_ = last_menus.back();
- current_->effect.start(500);
-
- last_menus.pop_back();
- }
- else
- {
- current_ = 0;
- }
-}
-
-void
-Menu::set_current(Menu* menu)
-{
- last_menus.clear();
-
- if (menu)
- menu->effect.start(500);
-
- current_ = menu;
-}
-
-MenuItem::MenuItem(MenuItemKind _kind, int _id)
- : kind(_kind) , id(_id)
-{
-}
-
-MenuItem::MenuItem(MenuItemKind _kind, int _id, const std::string& _text)
- : kind(_kind) , id(_id) , text(_text)
-{
-}
-
-/* Return a pointer to a new menu item */
-MenuItem*
-MenuItem::create(MenuItemKind kind_, const std::string& text_, int init_toggle_, Menu* target_menu_, int id_, int* int_p_)
-{
- MenuItem *pnew_item = new MenuItem(kind_,id_);
-
- pnew_item->text = text_;
-
- if(kind_ == MN_TOGGLE)
- pnew_item->toggled = init_toggle_;
- else
- pnew_item->toggled = false;
-
- pnew_item->target_menu = target_menu_;
-
- pnew_item->int_p = int_p_;
-
- pnew_item->selected = 0;
-
- pnew_item->input_flickering = false;
- pnew_item->input_flickering_timer.init(true);
- pnew_item->input_flickering_timer.start(FLICK_CURSOR_TIME);
-
- return pnew_item;
-}
-
-void
-MenuItem::change_text(const std::string& text_)
-{
- text = text_;
-}
-
-void
-MenuItem::change_input(const std::string& text_)
-{
- input = text_;
-}
-
-std::string MenuItem::get_input_with_symbol(bool active_item)
-{
- if(!active_item)
- input_flickering = true;
- else
- {
- if(input_flickering_timer.get_left() < 0)
- {
- if(input_flickering)
- input_flickering = false;
- else
- input_flickering = true;
- input_flickering_timer.start(FLICK_CURSOR_TIME);
- }
- }
-
- char str[1024];
- if(input_flickering)
- sprintf(str,"%s ",input.c_str());
- else
- sprintf(str,"%s_",input.c_str());
-
- std::string string = str;
-
- return string;
-}
-
-/* Set ControlField for keyboard key */
-void Menu::get_controlfield_key_into_input(MenuItem *item)
-{
- switch(*item->int_p)
- {
- case SDLK_UP:
- item->change_input(_("Up cursor"));
- break;
- case SDLK_DOWN:
- item->change_input(_("Down cursor"));
- break;
- case SDLK_LEFT:
- item->change_input(_("Left cursor"));
- break;
- case SDLK_RIGHT:
- item->change_input(_("Right cursor"));
- break;
- case SDLK_RETURN:
- item->change_input(_("Return"));
- break;
- case SDLK_SPACE:
- item->change_input(_("Space"));
- break;
- case SDLK_RSHIFT:
- item->change_input(_("Right Shift"));
- break;
- case SDLK_LSHIFT:
- item->change_input(_("Left Shift"));
- break;
- case SDLK_RCTRL:
- item->change_input(_("Right Control"));
- break;
- case SDLK_LCTRL:
- item->change_input(_("Left Control"));
- break;
- case SDLK_RALT:
- item->change_input(_("Right Alt"));
- break;
- case SDLK_LALT:
- item->change_input(_("Left Alt"));
- break;
- default:
- {
- char tmp[64];
- snprintf(tmp, 64, "%d", *item->int_p);
- item->change_input(tmp);
- }
- break;
- }
-}
-
-/* Set ControlField for joystick button */
-void Menu::get_controlfield_js_into_input(MenuItem *item)
-{
- std::ostringstream oss;
- oss << "Button " << *item->int_p;
- item->change_input(oss.str().c_str());
-}
-
-Menu::~Menu()
-{
-}
-
-Menu::Menu()
-{
- hit_item = -1;
- menuaction = MENU_ACTION_NONE;
- delete_character = 0;
- mn_input_char = '\0';
-
- pos_x = SCREEN_WIDTH/2;
- pos_y = SCREEN_HEIGHT/2;
- arrange_left = 0;
- active_item = 0;
- effect.init(false);
-
- joystick_timer.init(true);
-}
-
-void Menu::set_pos(int x, int y, float rw, float rh)
-{
- pos_x = x + (int)((float)get_width() * rw);
- pos_y = y + (int)((float)get_height() * rh);
-}
-
-void
-Menu::additem(MenuItemKind kind_, const std::string& text_, int toggle_, Menu* menu_, int id, int* int_p)
-{
- additem(MenuItem::create(kind_, text_.c_str(), toggle_, menu_, id, int_p));
-
- /* If a new menu is being built, the active item shouldn't be set to something
- that isnt selectable. Keep setting the active item to the most recently
- added item until a selectable entry is found.
- */
- if (item[active_item].kind == MN_HL
- || item[active_item].kind == MN_LABEL
- || item[active_item].kind == MN_DEACTIVE)
- active_item = item.size() - 1;
-}
-
-/* Add an item to a menu */
-void
-Menu::additem(MenuItem* pmenu_item)
-{
- item.push_back(*pmenu_item);
- delete pmenu_item;
-}
-
-/* Add an item to a menu */
-void
-Menu::additem(const MenuItem& pmenu_item)
-{
- item.push_back(pmenu_item);
-}
-
-void
-Menu::clear()
-{
- item.clear();
- active_item = 0;
-}
-
-/* Process actions done on the menu */
-void
-Menu::action()
-{
- hit_item = -1;
- if(item.size() != 0)
- {
- int last_active_item = active_item;
- switch(menuaction)
- {
- case MENU_ACTION_UP:
- do {
- if (active_item > 0)
- --active_item;
- else
- active_item = int(item.size())-1;
- } while ((item[active_item].kind == MN_HL
- || item[active_item].kind == MN_LABEL
- || item[active_item].kind == MN_DEACTIVE)
- && (active_item != last_active_item));
-
- break;
-
- case MENU_ACTION_DOWN:
- do {
- if(active_item < int(item.size())-1 )
- ++active_item;
- else
- active_item = 0;
- } while ((item[active_item].kind == MN_HL
- || item[active_item].kind == MN_LABEL
- || item[active_item].kind == MN_DEACTIVE)
- && (active_item != last_active_item));
-
- break;
-
- case MENU_ACTION_LEFT:
- if(item[active_item].kind == MN_STRINGSELECT) {
- if(item[active_item].selected > 0)
- item[active_item].selected--;
- else
- item[active_item].selected = item[active_item].list.size()-1;
- }
- break;
-
- case MENU_ACTION_RIGHT:
- if(item[active_item].kind == MN_STRINGSELECT) {
- if(item[active_item].selected+1 < item[active_item].list.size())
- item[active_item].selected++;
- else
- item[active_item].selected = 0;
- }
- break;
-
- case MENU_ACTION_HIT:
- {
- hit_item = active_item;
- switch (item[active_item].kind)
- {
- case MN_GOTO:
- if (item[active_item].target_menu != NULL)
- Menu::push_current(item[active_item].target_menu);
- else
- puts("NULLL");
- break;
-
- case MN_TOGGLE:
- item[active_item].toggled = !item[active_item].toggled;
- break;
-
- case MN_ACTION:
- Menu::set_current(0);
- item[active_item].toggled = true;
- break;
- case MN_TEXTFIELD:
- case MN_NUMFIELD:
- menuaction = MENU_ACTION_DOWN;
- action();
- break;
-
- case MN_BACK:
- Menu::pop_current();
- break;
- default:
- break;
- }
- }
- break;
-
- case MENU_ACTION_REMOVE:
- if(item[active_item].kind == MN_TEXTFIELD
- || item[active_item].kind == MN_NUMFIELD)
- {
- if(!item[active_item].input.empty())
- {
- int i = item[active_item].input.size();
-
- while(delete_character > 0) /* remove charactes */
- {
- item[active_item].input.resize(i-1);
- delete_character--;
- }
- }
- }
- break;
-
- case MENU_ACTION_INPUT:
- if(item[active_item].kind == MN_TEXTFIELD
- || (item[active_item].kind == MN_NUMFIELD && mn_input_char >= '0' && mn_input_char <= '9'))
- {
- item[active_item].input.push_back(mn_input_char);
- }
-
- case MENU_ACTION_NONE:
- break;
- }
- }
-
-
- menuaction = MENU_ACTION_NONE;
-
- if (active_item >= int(item.size()))
- active_item = int(item.size()) - 1;
-}
-
-int
-Menu::check()
-{
- if (hit_item != -1)
- return item[hit_item].id;
- else
- return -1;
-}
-
-void
-Menu::draw_item(DrawingContext& context,
- int index, // Position of the current item in the menu
- int menu_width, int menu_height)
-{
- MenuItem& pitem = item[index];
-
- int effect_offset = 0;
- {
- int effect_time = 0;
-
- if(effect.check())
- effect_time = effect.get_left() / 4;
-
- effect_offset = (index % 2) ? effect_time : -effect_time;
- }
-
- Font* text_font = default_font;
- int x_pos = pos_x;
- int y_pos = pos_y + 24*index - menu_height/2 + 12 + effect_offset;
- int shadow_size = 2;
- int text_width = int(text_font->get_text_width(pitem.text));
- int input_width = int(text_font->get_text_width(pitem.input) + 10);
- int list_width = 0;
- if(pitem.list.size() > 0) {
- list_width = (int) text_font->get_text_width(pitem.list[pitem.selected]);
- }
-
- if (arrange_left)
- x_pos += 24 - menu_width/2 + (text_width + input_width + list_width)/2;
-
- if(index == active_item)
- {
- shadow_size = 3;
- text_font = active_font;
- }
-
- switch (pitem.kind)
- {
- case MN_DEACTIVE:
- {
- context.draw_text(deactive_font, pitem.text,
- Vector(SCREEN_WIDTH/2, y_pos - int(deactive_font->get_height()/2)),
- CENTER_ALLIGN, LAYER_GUI);
- break;
- }
-
- case MN_HL:
- {
- // TODO
- int x = pos_x - menu_width/2;
- int y = y_pos - 12 - effect_offset;
- /* Draw a horizontal line with a little 3d effect */
- context.draw_filled_rect(Vector(x, y + 6),
- Vector(menu_width, 4), Color(150,200,255,225), LAYER_GUI);
- context.draw_filled_rect(Vector(x, y + 6),
- Vector(menu_width, 2), Color(255,255,255,255), LAYER_GUI);
- break;
- }
- case MN_LABEL:
- {
- context.draw_text(label_font, pitem.text,
- Vector(SCREEN_WIDTH/2, y_pos - int(label_font->get_height()/2)),
- CENTER_ALLIGN, LAYER_GUI);
- break;
- }
- case MN_TEXTFIELD:
- case MN_NUMFIELD:
- case MN_CONTROLFIELD_KB:
- case MN_CONTROLFIELD_JS:
- {
- int width = text_width + input_width + 5;
- int text_pos = SCREEN_WIDTH/2 - width/2;
- int input_pos = text_pos + text_width + 10;
-
- context.draw_filled_rect(
- Vector(input_pos - 5, y_pos - 10),
- Vector(input_width + 10, 20),
- Color(255,255,255,255), LAYER_GUI-5);
- context.draw_filled_rect(
- Vector(input_pos - 4, y_pos - 9),
- Vector(input_width + 8, 18),
- Color(0,0,0,128), LAYER_GUI-4);
-
- if(pitem.kind == MN_CONTROLFIELD_KB)
- get_controlfield_key_into_input(&pitem);
- else if (pitem.kind == MN_CONTROLFIELD_JS)
- get_controlfield_js_into_input(&pitem);
-
- if(pitem.kind == MN_TEXTFIELD || pitem.kind == MN_NUMFIELD)
- {
- if(active_item == index)
- context.draw_text(field_font,
- pitem.get_input_with_symbol(true),
- Vector(input_pos, y_pos - int(field_font->get_height()/2)),
- LEFT_ALLIGN, LAYER_GUI);
- else
- context.draw_text(field_font,
- pitem.get_input_with_symbol(false),
- Vector(input_pos, y_pos - int(field_font->get_height()/2)),
- LEFT_ALLIGN, LAYER_GUI);
- }
- else
- context.draw_text(field_font, pitem.input,
- Vector(input_pos, y_pos - int(field_font->get_height()/2)),
- LEFT_ALLIGN, LAYER_GUI);
-
- context.draw_text(text_font, pitem.text,
- Vector(text_pos, y_pos - int(text_font->get_height()/2)),
- LEFT_ALLIGN, LAYER_GUI);
- break;
- }
- case MN_STRINGSELECT:
- {
- int list_pos_2 = list_width + 16;
- int list_pos = list_width/2;
- int text_pos = (text_width + 16)/2;
-
- /* Draw arrows */
- context.draw_surface(arrow_left,
- Vector(x_pos - list_pos + text_pos - 17, y_pos - 8),
- LAYER_GUI);
- context.draw_surface(arrow_right,
- Vector(x_pos - list_pos + text_pos - 1 + list_pos_2, y_pos - 8),
- LAYER_GUI);
-
- /* Draw input background */
- context.draw_filled_rect(
- Vector(x_pos - list_pos + text_pos - 1, y_pos - 10),
- Vector(list_pos_2 + 2, 20),
- Color(255,255,255,255), LAYER_GUI - 4);
- context.draw_filled_rect(
- Vector(x_pos - list_pos + text_pos, y_pos - 9),
- Vector(list_pos_2, 18),
- Color(0,0,0,128), LAYER_GUI - 5);
-
- context.draw_text(text_font, pitem.list[pitem.selected],
- Vector(SCREEN_WIDTH/2 + text_pos, y_pos - int(text_font->get_height()/2)),
- CENTER_ALLIGN, LAYER_GUI);
- context.draw_text(text_font, pitem.text,
- Vector(SCREEN_WIDTH/2 + list_pos_2/2, y_pos - int(text_font->get_height()/2)),
- CENTER_ALLIGN, LAYER_GUI);
- break;
- }
- case MN_BACK:
- {
- context.draw_text(text_font, pitem.text,
- Vector(SCREEN_WIDTH/2, y_pos - int(text_font->get_height()/2)),
- CENTER_ALLIGN, LAYER_GUI);
- context.draw_surface(back,
- Vector(x_pos + text_width/2 + 16, y_pos - 8),
- LAYER_GUI);
- break;
- }
-
- case MN_TOGGLE:
- {
- context.draw_text(text_font, pitem.text,
- Vector(SCREEN_WIDTH/2, y_pos - (text_font->get_height()/2)),
- CENTER_ALLIGN, LAYER_GUI);
-
- if(pitem.toggled)
- context.draw_surface(checkbox_checked,
- Vector(x_pos + (text_width+16)/2, y_pos - 8),
- LAYER_GUI + 1);
- else
- context.draw_surface(checkbox,
- Vector(x_pos + (text_width+16)/2, y_pos - 8),
- LAYER_GUI + 1);
- break;
- }
- case MN_ACTION:
- context.draw_text(text_font, pitem.text,
- Vector(SCREEN_WIDTH/2, y_pos - int(text_font->get_height()/2)),
- CENTER_ALLIGN, LAYER_GUI);
- break;
-
- case MN_GOTO:
- context.draw_text(text_font, pitem.text,
- Vector(SCREEN_WIDTH/2, y_pos - int(text_font->get_height()/2)),
- CENTER_ALLIGN, LAYER_GUI);
- break;
- }
-}
-
-int Menu::get_width() const
- {
- /* The width of the menu has to be more than the width of the text
- with the most characters */
- int menu_width = 0;
- for(unsigned int i = 0; i < item.size(); ++i)
- {
- int w = item[i].text.size() + item[i].input.size() + 1;
- if( w > menu_width )
- {
- menu_width = w;
- if( item[i].kind == MN_TOGGLE)
- menu_width += 2;
- }
- }
-
- return (menu_width * 16 + 24);
- }
-
-int Menu::get_height() const
- {
- return item.size() * 24;
- }
-
-/* Draw the current menu. */
-void
-Menu::draw(DrawingContext& context)
-{
-
- int menu_height = get_height();
- int menu_width = get_width();
-
- /* Draw a transparent background */
- context.draw_filled_rect(
- Vector(pos_x - menu_width/2, pos_y - 24*item.size()/2 - 10),
- Vector(menu_width,menu_height + 20),
- Color(150,180,200,125), LAYER_GUI-10);
-
- for(unsigned int i = 0; i < item.size(); ++i)
- {
- draw_item(context, i, menu_width, menu_height);
- }
-}
-
-MenuItem&
-Menu::get_item_by_id(int id)
-{
- for(std::vector<MenuItem>::iterator i = item.begin(); i != item.end(); ++i)
- {
- if(i->id == id)
- return *i;
- }
-
- assert(false);
- static MenuItem dummyitem;
- return dummyitem;
-}
-
-int Menu::get_active_item_id()
-{
- return item[active_item].id;
-}
-
-bool
-Menu::isToggled(int id)
-{
- return get_item_by_id(id).toggled;
-}
-
-/* Check for menu event */
-void
-Menu::event(SDL_Event& event)
-{
- switch(event.type)
- {
- case SDL_KEYDOWN:
- {
- SDLKey key = event.key.keysym.sym;
- SDLMod keymod;
- char ch[2];
- keymod = SDL_GetModState();
-
- /* If the current unicode character is an ASCII character,
- assign it to ch. */
- if ( (event.key.keysym.unicode & 0xFF80) == 0 )
- {
- ch[0] = event.key.keysym.unicode & 0x7F;
- ch[1] = '\0';
- }
- else
- {
- /* An International Character. */
- }
-
- if(item.size() > 0 && item[active_item].kind == MN_CONTROLFIELD_KB)
- {
- if(key == SDLK_ESCAPE)
- {
- Menu::pop_current();
- return;
- }
- *item[active_item].int_p = key;
- menuaction = MENU_ACTION_DOWN;
- return;
- }
-
-
- switch(key)
- {
- case SDLK_UP: /* Menu Up */
- menuaction = MENU_ACTION_UP;
- break;
- case SDLK_DOWN: /* Menu Down */
- menuaction = MENU_ACTION_DOWN;
- break;
- case SDLK_LEFT: /* Menu Up */
- menuaction = MENU_ACTION_LEFT;
- break;
- case SDLK_RIGHT: /* Menu Down */
- menuaction = MENU_ACTION_RIGHT;
- break;
- case SDLK_SPACE:
- if(item.size() > 0 && item[active_item].kind == MN_TEXTFIELD)
- {
- menuaction = MENU_ACTION_INPUT;
- mn_input_char = ' ';
- break;
- }
- case SDLK_RETURN: /* Menu Hit */
- menuaction = MENU_ACTION_HIT;
- break;
- case SDLK_DELETE:
- case SDLK_BACKSPACE:
- menuaction = MENU_ACTION_REMOVE;
- delete_character++;
- break;
- case SDLK_ESCAPE:
- Menu::pop_current();
- break;
- default:
- if( (key >= SDLK_0 && key <= SDLK_9) || (key >= SDLK_a && key <= SDLK_z) || (key >= SDLK_SPACE && key <= SDLK_SLASH))
- {
- menuaction = MENU_ACTION_INPUT;
- mn_input_char = *ch;
- }
- else
- {
- mn_input_char = '\0';
- }
- break;
- }
- }
- break;
-
- case SDL_JOYAXISMOTION:
- if(event.jaxis.axis == joystick_keymap.y_axis)
- {
- if (event.jaxis.value > joystick_keymap.dead_zone && !joystick_timer.started())
- {
- menuaction = MENU_ACTION_DOWN;
- joystick_timer.start(JOYSTICK_MENU_DELAY);
- }
- else if (event.jaxis.value < -joystick_keymap.dead_zone && !joystick_timer.started())
- {
- menuaction = MENU_ACTION_UP;
- joystick_timer.start(JOYSTICK_MENU_DELAY);
- }
- else
- joystick_timer.stop();
- }
- break;
- case SDL_JOYHATMOTION:
- if(event.jhat.value & SDL_HAT_UP) {
- menuaction = MENU_ACTION_UP;
- } else if(event.jhat.value & SDL_HAT_DOWN) {
- menuaction = MENU_ACTION_DOWN;
- }
- break;
- case SDL_JOYBUTTONDOWN:
- if (item.size() > 0 && item[active_item].kind == MN_CONTROLFIELD_JS)
- {
- // FIXME: This next line does nothing useable, right?
- // *item[active_item].int_p = key;
- menuaction = MENU_ACTION_DOWN;
- }
- menuaction = MENU_ACTION_HIT;
- break;
-
- case SDL_MOUSEBUTTONDOWN:
- {
- int x = int(event.motion.x * float(SCREEN_WIDTH)/screen->w);
- int y = int(event.motion.y * float(SCREEN_HEIGHT)/screen->h);
-
- if(x > pos_x - get_width()/2 &&
- x < pos_x + get_width()/2 &&
- y > pos_y - get_height()/2 &&
- y < pos_y + get_height()/2)
- {
- menuaction = MENU_ACTION_HIT;
- }
- }
- break;
-
- case SDL_MOUSEMOTION:
- {
- int x = int(event.motion.x * float(SCREEN_WIDTH)/screen->w);
- int y = int(event.motion.y * float(SCREEN_HEIGHT)/screen->h);
-
- if(x > pos_x - get_width()/2 &&
- x < pos_x + get_width()/2 &&
- y > pos_y - get_height()/2 &&
- y < pos_y + get_height()/2)
- {
- int new_active_item = (y - (pos_y - get_height()/2)) / 24;
-
- /* only change the mouse focus to a selectable item */
- if ((item[new_active_item].kind != MN_HL)
- && (item[new_active_item].kind != MN_LABEL)
- && (item[new_active_item].kind != MN_DEACTIVE))
- active_item = new_active_item;
-
- if(MouseCursor::current())
- MouseCursor::current()->set_state(MC_LINK);
- }
- else
- {
- if(MouseCursor::current())
- MouseCursor::current()->set_state(MC_NORMAL);
- }
- }
- break;
-
- default:
- break;
- }
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-//
-// 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_MENU_H
-#define SUPERTUX_MENU_H
-
-#include <vector>
-#include <set>
-#include <string>
-#include <utility>
-
-#include "SDL.h"
-
-#include "video/surface.h"
-#include "video/font.h"
-#include "special/timer.h"
-#include "mousecursor.h"
-
-namespace SuperTux
- {
-
- /* Joystick menu delay */
-#define JOYSTICK_MENU_DELAY 500
-
- /* IDs for menus */
-
- bool confirm_dialog(Surface* background, std::string text);
-
- /* Kinds of menu items */
- enum MenuItemKind {
- MN_ACTION,
- MN_GOTO,
- MN_TOGGLE,
- MN_BACK,
- MN_DEACTIVE,
- MN_TEXTFIELD,
- MN_NUMFIELD,
- MN_CONTROLFIELD_KB,
- MN_CONTROLFIELD_JS,
- MN_STRINGSELECT,
- MN_LABEL,
- MN_HL, /* horizontal line */
- };
-
- class Menu;
-
- class MenuItem
- {
- public:
- MenuItem() {};
- MenuItem(MenuItemKind kind, int id = -1);
- MenuItem(MenuItemKind kind, int id, const std::string& text);
- MenuItemKind kind;
- int id; // item id
- int toggled;
- std::string text;
- std::string input;
- int *int_p; // used for setting keys (can be used for more stuff...)
-
- std::vector<std::string> list; // list of values for a STRINGSELECT item
- size_t selected; // currently selected item
-
- Menu* target_menu;
-
- void change_text (const std::string& text);
- void change_input(const std::string& text);
-
- static MenuItem* create(MenuItemKind kind, const std::string& text,
- int init_toggle, Menu* target_menu, int id, int* int_p);
-
- std::string get_input_with_symbol(bool active_item); // returns the text with an input symbol
- private:
- bool input_flickering;
- Timer input_flickering_timer;
- };
-
- class Menu
- {
- private:
- static std::vector<Menu*> last_menus;
- static Menu* current_;
-
- static void push_current(Menu* pmenu);
- static void pop_current();
-
- public:
- /** Set the current menu, if pmenu is NULL, hide the current menu */
- static void set_current(Menu* pmenu);
-
- /** Return the current active menu or NULL if none is active */
- static Menu* current()
- {
- return current_;
- }
-
- private:
- /* Action done on the menu */
- enum MenuAction {
- MENU_ACTION_NONE = -1,
- MENU_ACTION_UP,
- MENU_ACTION_DOWN,
- MENU_ACTION_LEFT,
- MENU_ACTION_RIGHT,
- MENU_ACTION_HIT,
- MENU_ACTION_INPUT,
- MENU_ACTION_REMOVE
- };
-
- /** Number of the item that got 'hit' (ie. pressed) in the last
- event()/action() call, -1 if none */
- int hit_item;
-
- // position of the menu (ie. center of the menu, not top/left)
- int pos_x;
- int pos_y;
-
- /** input event for the menu (up, down, left, right, etc.) */
- MenuAction menuaction;
-
- /* input implementation variables */
- int delete_character;
- char mn_input_char;
- Timer joystick_timer;
-
- public:
- static Font* default_font;
- static Font* active_font;
- static Font* deactive_font;
- static Font* label_font;
- static Font* field_font;
-
- Timer effect;
- int arrange_left;
- int active_item;
-
- std::vector<MenuItem> item;
-
- Menu();
- ~Menu();
-
- void additem(const MenuItem& menu_item);
- void additem(MenuItem* pmenu_item);
- void additem(MenuItemKind kind, const std::string& text, int init_toggle, Menu* target_menu, int id = -1, int *int_p = NULL);
-
- void action ();
-
- /** Remove all entries from the menu */
- void clear();
-
- /** Return the index of the menu item that was 'hit' (ie. the user
- clicked on it) in the last event() call */
- int check ();
-
- MenuItem& get_item(int index)
- {
- return item[index];
- }
- MenuItem& get_item_by_id(int id);
-
- int get_active_item_id();
-
- bool isToggled(int id);
-
- void Menu::get_controlfield_key_into_input(MenuItem *item);
- void Menu::get_controlfield_js_into_input(MenuItem *item);
-
- void draw(DrawingContext& context);
- void draw_item(DrawingContext& context,
- int index, int menu_width, int menu_height);
- void set_pos(int x, int y, float rw = 0, float rh = 0);
-
- /** translate a SDL_Event into a menu_action */
- void event(SDL_Event& event);
-
- int get_width() const;
- int get_height() const;
-
- bool is_toggled(int id) const;
- };
-
- extern Surface* checkbox;
- extern Surface* checkbox_checked;
- extern Surface* back;
- extern Surface* arrow_left;
- extern Surface* arrow_right;
-
-} //namespace SuperTux
-
-#endif /*SUPERTUX_MENU_H*/
-
-/* Local Variables: */
-/* mode: c++ */
-/* End: */
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2004 Ricardo Cruz <rick2@aeiou.pt>
-//
-// 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 <config.h>
-
-#include "app/globals.h"
-#include "video/drawing_context.h"
-#include "gui/mousecursor.h"
-
-using namespace SuperTux;
-
-MouseCursor* MouseCursor::current_ = 0;
-
-MouseCursor::MouseCursor(std::string cursor_file, int frames) : mid_x(0), mid_y(0)
-{
- cursor = new Surface(cursor_file, true);
-
- cur_state = MC_NORMAL;
- cur_frame = 0;
- tot_frames = frames;
-
- timer.init(false);
- timer.start(MC_FRAME_PERIOD);
-
- SDL_ShowCursor(SDL_DISABLE);
-}
-
-MouseCursor::~MouseCursor()
-{
- delete cursor;
-
- SDL_ShowCursor(SDL_ENABLE);
-}
-
-int MouseCursor::state()
-{
- return cur_state;
-}
-
-void MouseCursor::set_state(int nstate)
-{
- cur_state = nstate;
-}
-
-void MouseCursor::set_mid(int x, int y)
-{
- mid_x = x;
- mid_y = y;
-}
-
-void MouseCursor::draw(DrawingContext& context)
-{
- if(cur_state == MC_HIDE)
- return;
-
- int x,y,w,h;
- Uint8 ispressed = SDL_GetMouseState(&x,&y);
-
- x = int(x * float(SCREEN_WIDTH)/screen->w);
- y = int(y * float(SCREEN_HEIGHT)/screen->h);
-
- w = cursor->w / tot_frames;
- h = cursor->h / MC_STATES_NB;
- if(ispressed &SDL_BUTTON(1) || ispressed &SDL_BUTTON(2))
- {
- if(cur_state != MC_CLICK)
- {
- state_before_click = cur_state;
- cur_state = MC_CLICK;
- }
- }
- else
- {
- if(cur_state == MC_CLICK)
- cur_state = state_before_click;
- }
-
- if(timer.get_left() < 0 && tot_frames > 1)
- {
- cur_frame++;
- if(cur_frame++ >= tot_frames)
- cur_frame = 0;
-
- timer.start(MC_FRAME_PERIOD);
- }
-
- context.draw_surface_part(cursor, Vector(w*cur_frame, h*cur_state), Vector(w,
- h), Vector(x-mid_x, y-mid_y), LAYER_GUI+100);
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2004 Ricardo Cruz <rick2@aeiou.pt>
-//
-// 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_MOUSECURSOR_H
-#define SUPERTUX_MOUSECURSOR_H
-
-#include <string>
-
-#include "special/timer.h"
-#include "video/surface.h"
-
-namespace SuperTux
- {
-
- #define MC_FRAME_PERIOD 800 // in ms
-
- #define MC_STATES_NB 3
-
- enum {
- MC_NORMAL,
- MC_CLICK,
- MC_LINK,
- MC_HIDE
- };
-
- /// Mouse cursor.
- /** Used to create mouse cursors.
- The mouse cursors can be animated
- and can be used in four different states.
- (MC_NORMAL, MC_CLICK, MC_LINK or MC_HIDE) */
- class MouseCursor
- {
- public:
- /// Constructor of MouseCursor.
- /** Expects an imagefile for the cursor and the number of animation frames it contains. */
- MouseCursor(std::string cursor_file, int frames);
- ~MouseCursor();
- /// Get MouseCursor state.
- /** (MC_NORMAL, MC_CLICK, MC_LINK or MC_HIDE) */
- int state();
- /// Set MouseCursor state.
- /** (MC_NORMAL, MC_CLICK, MC_LINK or MC_HIDE) */
- void set_state(int nstate);
- /// Define the middle of a MouseCursor.
- /** Useful for cross mouse cursor images in example. */
- void set_mid(int x, int y);
-
- /// Draw MouseCursor on screen.
- void draw(DrawingContext& context);
-
- /// Return the current cursor.
- static MouseCursor* current()
- { return current_; };
- /// Set current cursor.
- static void set_current(MouseCursor* pcursor)
- { current_ = pcursor; };
-
- private:
- int mid_x, mid_y;
- static MouseCursor* current_;
- int state_before_click;
- int cur_state;
- int cur_frame, tot_frames;
- Surface* cursor;
- Timer timer;
- };
-
-} // namespace SuperTux
-
-#endif /*SUPERTUX_MOUSECURSOR_H*/
+++ /dev/null
-// $Id$
-//
-// Copyright (C) 2004 Matthias Braun <matze@braunis.de>
-// code in this file based on lispreader from Mark Probst
-//
-// 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 <config.h>
-
-#include <sstream>
-#include <stdexcept>
-#include <iostream>
-
-#include "lexer.h"
-
-namespace lisp
-{
-
-class EOFException
-{
-};
-
-Lexer::Lexer(std::istream& newstream)
- : stream(newstream), eof(false), linenumber(0)
-{
- try {
- // trigger a refill of the buffer
- c = 0;
- bufend = 0;
- nextChar();
- } catch(EOFException& e) {
- }
-}
-
-Lexer::~Lexer()
-{
-}
-
-void
-Lexer::nextChar()
-{
- ++c;
- if(c >= bufend) {
- if(eof)
- throw EOFException();
- stream.read(buffer, BUFFER_SIZE);
- size_t bytes_read = stream.gcount();
-
- c = buffer;
- bufend = buffer + bytes_read;
-
- // the following is a hack that appends an additional ' ' at the end of
- // the file to avoid problems when parsing symbols/elements and a sudden
- // EOF. This is faster than relying on unget and IMO also nicer.
- if(bytes_read == 0 || stream.eof()) {
- eof = true;
- *bufend = ' ';
- ++bufend;
- }
- }
-}
-
-Lexer::TokenType
-Lexer::getNextToken()
-{
- static const char* delims = "\"();";
-
- try {
- while(isspace(*c)) {
- if(*c == '\n')
- ++linenumber;
- nextChar();
- };
-
- token_length = 0;
-
- switch(*c) {
- case ';': // comment
- while(true) {
- nextChar();
- if(*c == '\n') {
- ++linenumber;
- break;
- }
- }
- return getNextToken(); // and again
- case '(':
- nextChar();
- return TOKEN_OPEN_PAREN;
- case ')':
- nextChar();
- return TOKEN_CLOSE_PAREN;
- case '"': { // string
- int startline = linenumber;
- try {
- while(1) {
- nextChar();
- if(*c == '"')
- break;
- else if(*c == '\n')
- linenumber++;
- else if(*c == '\\') {
- nextChar();
- switch(*c) {
- case 'n':
- *c = '\n';
- break;
- case 't':
- *c = '\t';
- break;
- }
- }
- if(token_length < MAX_TOKEN_LENGTH)
- token_string[token_length++] = *c;
- }
- token_string[token_length] = 0;
- } catch(EOFException& ) {
- std::stringstream msg;
- msg << "Parse error in line " << startline << ": "
- << "EOF while parsing string.";
- throw std::runtime_error(msg.str());
- }
- nextChar();
- return TOKEN_STRING;
- }
- case '#': // constant
- try {
- nextChar();
-
- while(isalnum(*c) || *c == '_') {
- if(token_length < MAX_TOKEN_LENGTH)
- token_string[token_length++] = *c;
- nextChar();
- }
- token_string[token_length] = 0;
- } catch(EOFException& ) {
- std::stringstream msg;
- msg << "Parse Error in line " << linenumber << ": "
- << "EOF while parsing constant.";
- throw std::runtime_error(msg.str());
- }
-
- if(strcmp(token_string, "t") == 0)
- return TOKEN_TRUE;
- if(strcmp(token_string, "f") == 0)
- return TOKEN_FALSE;
-
- // we only handle #t and #f constants at the moment...
-
- {
- std::stringstream msg;
- msg << "Parse Error in line " << linenumber << ": "
- << "Unknown constant '" << token_string << "'.";
- throw std::runtime_error(msg.str());
- }
-
- default:
- if(isdigit(*c) || *c == '-') {
- bool have_nondigits = false;
- bool have_digits = false;
- int have_floating_point = 0;
-
- do {
- if(isdigit(*c))
- have_digits = true;
- else if(*c == '.')
- ++have_floating_point;
- else if(isalnum(*c) || *c == '_')
- have_nondigits = true;
-
- if(token_length < MAX_TOKEN_LENGTH)
- token_string[token_length++] = *c;
-
- nextChar();
- } while(!isspace(*c) && !strchr(delims, *c));
-
- token_string[token_length] = 0;
-
- // no nextChar
-
- if(have_nondigits || !have_digits || have_floating_point > 1)
- return TOKEN_SYMBOL;
- else if(have_floating_point == 1)
- return TOKEN_REAL;
- else
- return TOKEN_INTEGER;
- } else {
- do {
- if(token_length < MAX_TOKEN_LENGTH)
- token_string[token_length++] = *c;
- nextChar();
- } while(!isspace(*c) && !strchr(delims, *c));
- token_string[token_length] = 0;
-
- // no nextChar
-
- return TOKEN_SYMBOL;
- }
- }
- } catch(EOFException& ) {
- return TOKEN_EOF;
- }
-}
-
-} // end of namespace lisp
-
+++ /dev/null
-// $Id$
-//
-// Copyright (C) 2004 Matthias Braun <matze@braunis.de>
-// code in this file based on lispreader from Mark Probst
-//
-// 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 __LISPLEXER_H__
-#define __LISPLEXER_H__
-
-namespace lisp
-{
-
-class Lexer
-{
-public:
- enum TokenType {
- TOKEN_EOF,
- TOKEN_OPEN_PAREN,
- TOKEN_CLOSE_PAREN,
- TOKEN_SYMBOL,
- TOKEN_STRING,
- TOKEN_INTEGER,
- TOKEN_REAL,
- TOKEN_TRUE,
- TOKEN_FALSE
- };
-
- Lexer(std::istream& stream);
- ~Lexer();
-
- TokenType getNextToken();
- const char* getString() const
- { return token_string; }
- int getLineNumber() const
- { return linenumber; }
-
-private:
- enum {
- MAX_TOKEN_LENGTH = 16384,
- BUFFER_SIZE = 1024
- };
-
- inline void nextChar();
-
- std::istream& stream;
- bool eof;
- int linenumber;
- char buffer[BUFFER_SIZE+1];
- char* bufend;
- char* c;
- char token_string[MAX_TOKEN_LENGTH + 1];
- int token_length;
-};
-
-} // end of namespace lisp
-
-#endif
-
+++ /dev/null
-// $Id$
-//
-// TuxKart - a fun racing game with go-kart
-// Copyright (C) 2004 Matthias Braun <matze@braunis.de>
-// code in this file based on lispreader from Mark Probst
-//
-// 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 <config.h>
-
-#include "lisp.h"
-
-namespace lisp
-{
-
-Lisp::Lisp(LispType newtype)
- : type(newtype)
-{
-}
-
-Lisp::~Lisp()
-{
- if(type == TYPE_SYMBOL || type == TYPE_STRING)
- delete[] v.string;
- if(type == TYPE_CONS) {
- delete v.cons.cdr;
- delete v.cons.car;
- }
-}
-
-Lisp*
-Lisp::get_lisp(const char* name) const
-{
- for(const Lisp* p = this; p != 0; p = p->get_cdr()) {
- Lisp* child = p->get_car();
- if(!child || child->get_type() != TYPE_CONS)
- continue;
- Lisp* childname = child->get_car();
- if(!childname)
- continue;
- std::string childName;
- if(!childname->get(childName))
- continue;
- if(childName == name) {
- return child->get_cdr();
- }
- }
-
- return 0;
-}
-
-void
-Lisp::print(int indent) const
-{
- for(int i = 0; i < indent; ++i)
- printf(" ");
-
- if(type == TYPE_CONS) {
- printf("(\n");
- const Lisp* lisp = this;
- while(lisp) {
- if(lisp->v.cons.car)
- lisp->v.cons.car->print(indent + 1);
- lisp = lisp->v.cons.cdr;
- }
- for(int i = 0; i < indent; ++i)
- printf(" ");
- printf(")");
- }
- if(type == TYPE_STRING) {
- printf("'%s' ", v.string);
- }
- if(type == TYPE_INTEGER) {
- printf("%d", v.integer);
- }
- if(type == TYPE_REAL) {
- printf("%f", v.real);
- }
- if(type == TYPE_SYMBOL) {
- printf("%s ", v.string);
- }
- if(type == TYPE_BOOLEAN) {
- printf("%s ", v.boolean ? "true" : "false");
- }
- printf("\n");
-}
-
-} // end of namespace lisp
+++ /dev/null
-// $Id$
-//
-// TuxKart - a fun racing game with go-kart
-// Copyright (C) 2004 Matthias Braun <matze@braunis.de>
-// code in this file based on lispreader from Mark Probst
-//
-// 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 __LISPREADER_H__
-#define __LISPREADER_H__
-
-#include <string>
-#include <vector>
-
-namespace lisp
-{
-
-class Lisp
-{
-public:
- ~Lisp();
-
- enum LispType {
- TYPE_CONS,
- TYPE_SYMBOL,
- TYPE_INTEGER,
- TYPE_STRING,
- TYPE_REAL,
- TYPE_BOOLEAN
- };
-
- LispType get_type() const
- { return type; }
-
- Lisp* get_car() const
- { return v.cons.car; }
- Lisp* get_cdr() const
- { return v.cons.cdr; }
- bool get(std::string& val) const
- {
- if(type != TYPE_STRING && type != TYPE_SYMBOL)
- return false;
- val = v.string;
- return true;
- }
- bool get(unsigned int& val) const
- {
- if(type != TYPE_INTEGER)
- return false;
- val = v.integer;
- return true;
- }
- bool get(int& val) const
- {
- if(type != TYPE_INTEGER)
- return false;
- val = v.integer;
- return true;
- }
- bool get(float& val) const
- {
- if(type != TYPE_REAL) {
- if(type == TYPE_INTEGER) {
- val = v.integer;
- return true;
- }
- return false;
- }
- val = v.real;
- return true;
- }
- bool get(bool& val) const
- {
- if(type != TYPE_BOOLEAN)
- return false;
- val = v.boolean;
- return true;
- }
-
- /* conveniance functions which traverse the list until a child with a
- * specified name is found. The value part is then interpreted in a specific
- * way. The functions return true, if a child was found and could be
- * interpreted correctly, otherwise false is returned and the variable value
- * is not changed.
- * (Please note that searching the lisp structure is O(n) so these functions
- * are no good idea for performance critical areas)
- */
- template<class T>
- bool get(const char* name, T& val) const
- {
- const Lisp* lisp = get_lisp(name);
- if(!lisp)
- return false;
-
- if(lisp->get_type() != TYPE_CONS)
- return false;
- lisp = lisp->get_car();
- if(!lisp)
- return false;
- return lisp->get(val);
- }
-
- template<class T>
- bool get_vector(const char* name, std::vector<T>& vec) const
- {
- vec.clear();
-
- const Lisp* child = get_lisp(name);
- if(!child)
- return false;
-
- for( ; child != 0; child = child->get_cdr()) {
- T val;
- if(!child->get_car())
- continue;
- if(child->get_car()->get(val)) {
- vec.push_back(val);
- }
- }
-
- return true;
- }
-
- Lisp* get_lisp(const char* name) const;
- Lisp* get_lisp(const std::string& name) const
- { return get_lisp(name.c_str()); }
-
- // for debugging
- void print(int indent = 0) const;
-
-private:
- friend class Parser;
- Lisp(LispType newtype);
-
- LispType type;
- union
- {
- struct
- {
- Lisp* car;
- Lisp* cdr;
- } cons;
-
- char* string;
- int integer;
- bool boolean;
- float real;
- } v;
-};
-
-} // end of namespace lisp
-
-#endif
-
+++ /dev/null
-#include <config.h>
-
-#include "list_iterator.h"
-#include <stdexcept>
-
-namespace lisp
-{
-
-ListIterator::ListIterator(const lisp::Lisp* newlisp)
- : current_lisp(0), cur(newlisp)
-{
-}
-
-bool
-ListIterator::next()
-{
- if(cur == 0)
- return false;
-
- const lisp::Lisp* child = cur->get_car();
- if(!child)
- throw new std::runtime_error("child is 0 in list entry");
- if(child->get_type() != lisp::Lisp::TYPE_CONS)
- throw new std::runtime_error("Expected CONS");
- const lisp::Lisp* name = child->get_car();
- if(!name || name->get_type() != lisp::Lisp::TYPE_SYMBOL)
- throw new std::runtime_error("Expected symbol");
- name->get(current_item);
- current_lisp = child->get_cdr();
-
- cur = cur->get_cdr();
- return true;
-}
-
-}
+++ /dev/null
-#ifndef __LISP_ITERATOR_H__
-#define __LISP_ITERATOR_H__
-
-#include "lisp/lisp.h"
-
-namespace lisp
-{
-
-/**
- * Small and a bit hacky helper class that helps parsing lisp lists where all
- * entries are lists again themselves
- */
-class ListIterator
-{
-public:
- ListIterator(const lisp::Lisp* cur);
-
- const std::string& item() const
- { return current_item; }
- lisp::Lisp* lisp() const
- { return current_lisp; }
- lisp::Lisp* value() const
- { return current_lisp->get_car(); }
- bool next();
-
-private:
- std::string current_item;
- lisp::Lisp* current_lisp;
- const lisp::Lisp* cur;
-};
-
-}
-
-#endif
-
+++ /dev/null
-// $Id$
-//
-// TuxKart - a fun racing game with go-kart
-// Copyright (C) 2004 Matthias Braun <matze@braunis.de>
-// code in this file based on lispreader from Mark Probst
-//
-// 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 <config.h>
-
-#include <sstream>
-#include <stdexcept>
-#include <fstream>
-#include <cassert>
-#include <iostream>
-
-#include "app/setup.h"
-#include "app/tinygettext.h"
-#include "parser.h"
-#include "lisp.h"
-
-namespace lisp
-{
-
-Parser::Parser(bool translate)
- : lexer(0), dictionary_manager(0), dictionary(0)
-{
- if(translate) {
- dictionary_manager = new TinyGetText::DictionaryManager();
- }
-}
-
-Parser::~Parser()
-{
- delete lexer;
- delete dictionary_manager;
-}
-
-Lisp*
-Parser::parse(const std::string& filename)
-{
- std::ifstream in(filename.c_str());
- if(!in.good()) {
- std::stringstream msg;
- msg << "Parser problem: Couldn't open file '" << filename << "'.";
- throw std::runtime_error(msg.str());
- }
-
- if(dictionary_manager) {
- dictionary_manager->add_directory(SuperTux::FileSystem::dirname(filename));
- dictionary = & (dictionary_manager->get_dictionary());
- }
-
- return parse(in);
-}
-
-Lisp*
-Parser::parse(std::istream& stream)
-{
- delete lexer;
- lexer = new Lexer(stream);
-
- token = lexer->getNextToken();
- Lisp* result = new Lisp(Lisp::TYPE_CONS);
- result->v.cons.car = read();
- result->v.cons.cdr = 0;
-
- delete lexer;
- lexer = 0;
-
- return result;
-}
-
-Lisp*
-Parser::read()
-{
- Lisp* result;
- switch(token) {
- case Lexer::TOKEN_EOF: {
- std::stringstream msg;
- msg << "Parse Error at line " << lexer->getLineNumber() << ": "
- << "Unexpected EOF.";
- throw std::runtime_error(msg.str());
- }
- case Lexer::TOKEN_CLOSE_PAREN: {
- std::stringstream msg;
- msg << "Parse Error at line " << lexer->getLineNumber() << ": "
- << "Unexpected ')'.";
- throw std::runtime_error(msg.str());
- }
- case Lexer::TOKEN_OPEN_PAREN: {
- result = new Lisp(Lisp::TYPE_CONS);
-
- token = lexer->getNextToken();
- if(token == Lexer::TOKEN_CLOSE_PAREN) {
- result->v.cons.car = 0;
- result->v.cons.cdr = 0;
- break;
- }
-
- if(token == Lexer::TOKEN_SYMBOL &&
- strcmp(lexer->getString(), "_") == 0) {
- // evaluate translation function (_ str) in place here
- token = lexer->getNextToken();
- if(token != Lexer::TOKEN_STRING)
- throw new std::runtime_error("Expected string after '(_'");
-
- result = new Lisp(Lisp::TYPE_STRING);
- if(dictionary) {
- std::string translation = dictionary->translate(lexer->getString());
- result->v.string = new char[translation.size()+1];
- memcpy(result->v.string, translation.c_str(), translation.size()+1);
- } else {
- size_t len = strlen(lexer->getString()) + 1;
- result->v.string = new char[len];
- memcpy(result->v.string, lexer->getString(), len);
- }
- token = lexer->getNextToken();
- if(token != Lexer::TOKEN_CLOSE_PAREN)
- throw new std::runtime_error("Expected ')' after '(_ string'");
- break;
- }
-
- Lisp* cur = result;
- do {
- cur->v.cons.car = read();
- if(token == Lexer::TOKEN_CLOSE_PAREN) {
- cur->v.cons.cdr = 0;
- break;
- }
- cur->v.cons.cdr = new Lisp(Lisp::TYPE_CONS);
- cur = cur->v.cons.cdr;
- } while(1);
-
- break;
- }
- case Lexer::TOKEN_SYMBOL: {
- result = new Lisp(Lisp::TYPE_SYMBOL);
- size_t len = strlen(lexer->getString()) + 1;
- result->v.string = new char[len];
- memcpy(result->v.string, lexer->getString(), len);
- break;
- }
- case Lexer::TOKEN_STRING: {
- result = new Lisp(Lisp::TYPE_STRING);
- size_t len = strlen(lexer->getString()) + 1;
- result->v.string = new char[len];
- memcpy(result->v.string, lexer->getString(), len);
- break;
- }
- case Lexer::TOKEN_INTEGER:
- result = new Lisp(Lisp::TYPE_INTEGER);
- sscanf(lexer->getString(), "%d", &result->v.integer);
- break;
- case Lexer::TOKEN_REAL:
- result = new Lisp(Lisp::TYPE_REAL);
- sscanf(lexer->getString(), "%f", &result->v.real);
- break;
- case Lexer::TOKEN_TRUE:
- result = new Lisp(Lisp::TYPE_BOOLEAN);
- result->v.boolean = true;
- break;
- case Lexer::TOKEN_FALSE:
- result = new Lisp(Lisp::TYPE_BOOLEAN);
- result->v.boolean = false;
- break;
-
- default:
- // this should never happen
- assert(false);
- }
-
- token = lexer->getNextToken();
- return result;
-}
-
-} // end of namespace lisp
+++ /dev/null
-// $Id$
-//
-// TuxKart - a fun racing game with go-kart
-// Copyright (C) 2004 Matthias Braun <matze@braunis.de>
-// code in this file based on lispreader from Mark Probst
-//
-// 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 __LISPPARSER_H__
-#define __LISPPARSER_H__
-
-#include <string>
-#include "lexer.h"
-
-namespace TinyGetText {
-class Dictionary;
-class DictionaryManager;
-}
-
-namespace lisp
-{
-
-class Lisp;
-
-class Parser
-{
-public:
- Parser(bool translate = true);
- ~Parser();
-
- Lisp* parse(const std::string& filename);
- Lisp* parse(std::istream& stream);
-
-private:
- Lisp* read();
-
- Lexer* lexer;
- TinyGetText::DictionaryManager* dictionary_manager;
- TinyGetText::Dictionary* dictionary;
- Lexer::TokenType token;
-};
-
-} // end of namespace lisp
-
-#endif
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2004 Matthias Braun <matze@braunis.de
-//
-// 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 <config.h>
-
-#include <iostream>
-
-#include "writer.h"
-
-namespace lisp
-{
-
-Writer::Writer(std::ostream& newout)
- : out(newout), indent_depth(0)
-{
-}
-
-Writer::~Writer()
-{
- if(lists.size() > 0) {
- std::cerr << "Warning: Not all sections closed in lispwriter!\n";
- }
-}
-
-void
-Writer::write_comment(const std::string& comment)
-{
- out << "; " << comment << "\n";
-}
-
-void
-Writer::start_list(const std::string& listname)
-{
- indent();
- out << '(' << listname << '\n';
- indent_depth += 2;
-
- lists.push_back(listname);
-}
-
-void
-Writer::end_list(const std::string& listname)
-{
- if(lists.size() == 0) {
- std::cerr << "Trying to close list '" << listname
- << "', which is not open.\n";
- return;
- }
- if(lists.back() != listname) {
- std::cerr << "Warning: trying to close list '" << listname
- << "' while list '" << lists.back() << "' is open.\n";
- return;
- }
- lists.pop_back();
-
- indent_depth -= 2;
- indent();
- out << ")\n";
-}
-
-void
-Writer::write_int(const std::string& name, int value)
-{
- indent();
- out << '(' << name << ' ' << value << ")\n";
-}
-
-void
-Writer::write_float(const std::string& name, float value)
-{
- indent();
- out << '(' << name << ' ' << value << ")\n";
-}
-
-void
-Writer::write_string(const std::string& name, const std::string& value,
- bool translatable)
-{
- indent();
- out << '(' << name;
- if(translatable) {
- out << " (_ \"" << value << "\"))\n";
- } else {
- out << " \"" << value << "\")\n";
- }
-}
-
-void
-Writer::write_bool(const std::string& name, bool value)
-{
- indent();
- out << '(' << name << ' ' << (value ? "#t" : "#f") << ")\n";
-}
-
-void
-Writer::write_int_vector(const std::string& name,
- const std::vector<int>& value)
-{
- indent();
- out << '(' << name;
- for(std::vector<int>::const_iterator i = value.begin(); i != value.end(); ++i)
- out << " " << *i;
- out << ")\n";
-}
-
-void
-Writer::write_int_vector(const std::string& name,
- const std::vector<unsigned int>& value)
-{
- indent();
- out << '(' << name;
- for(std::vector<unsigned int>::const_iterator i = value.begin(); i != value.end(); ++i)
- out << " " << *i;
- out << ")\n";
-}
-
-void
-Writer::indent()
-{
- for(int i = 0; i<indent_depth; ++i)
- out << ' ';
-}
-
-} // end of namespace lisp
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2004 Matthias Braun <matze@braunis.de
-//
-// 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_LISPWRITER_H
-#define SUPERTUX_LISPWRITER_H
-
-#include <iostream>
-#include <string>
-#include <vector>
-
-namespace lisp
-{
-
- class Writer
- {
- public:
- Writer(std::ostream& out);
- ~Writer();
-
- void write_comment(const std::string& comment);
-
- void start_list(const std::string& listname);
-
- void write_int(const std::string& name, int value);
- void write_float(const std::string& name, float value);
- void write_string(const std::string& name, const std::string& value,
- bool translatable = false);
- void write_bool(const std::string& name, bool value);
- void write_int_vector(const std::string& name, const std::vector<int>& value);
- void write_int_vector(const std::string& name, const std::vector<unsigned int>& value);
- // add more write-functions when needed...
-
- void end_list(const std::string& listname);
-
- private:
- void indent();
-
- std::ostream& out;
- int indent_depth;
- std::vector<std::string> lists;
- };
-
-} //namespace lisp
-
-#endif //SUPERTUX_LISPWRITER_H
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-//
-// 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_BASE_H
-#define SUPERTUX_BASE_H
-
-#include <string>
-
-#include "SDL.h"
-
-namespace SuperTux
- {
-
- /// 'Base' type for game objects.
- /** Mainly for layered use in game objects.
- Contains upper left X and Y coordinates of an
- object along with its width and height. */
- struct base_type
- {
- float x;
- float y;
- float width;
- float height;
- };
-
-}
-
-#endif /*SUPERTUX_BASE_H*/
-
+++ /dev/null
-#include <config.h>
-
-#include "collision.h"
-
-#include <algorithm>
-#include <iostream>
-#include <stdio.h>
-#include <float.h>
-#include <math.h>
-#include "math/vector.h"
-#include "math/aatriangle.h"
-#include "math/rectangle.h"
-#include "collision_hit.h"
-
-namespace SuperTux
-{
-
-static const float DELTA = .0001;
-
-bool
-Collision::rectangle_rectangle(CollisionHit& hit, const Rectangle& r1,
- const Vector& movement, 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;
-
- if(movement.x > DELTA) {
- hit.depth = r1.p2.x - r2.p1.x;
- hit.time = hit.depth / movement.x;
- hit.normal.x = -1;
- hit.normal.y = 0;
- } else if(movement.x < -DELTA) {
- hit.depth = r2.p2.x - r1.p1.x;
- hit.time = hit.depth / -movement.x;
- hit.normal.x = 1;
- hit.normal.y = 0;
- } else {
- if(movement.y > -DELTA && movement.y < DELTA) {
- hit.time = 0;
- hit.depth = 0;
- hit.normal.x = 1;
- hit.normal.y = 0;
- return true;
- }
- hit.time = FLT_MAX;
- }
-
- if(movement.y > DELTA) {
- float ydepth = r1.p2.y - r2.p1.y;
- float yt = ydepth / movement.y;
- if(yt < hit.time) {
- hit.depth = ydepth;
- hit.time = yt;
- hit.normal.x = 0;
- hit.normal.y = -1;
- }
- } else if(movement.y < -DELTA) {
- float ydepth = r2.p2.y - r1.p1.y;
- float yt = ydepth / -movement.y;
- if(yt < hit.time) {
- hit.depth = ydepth;
- hit.time = yt;
- 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 Vector& movement, const AATriangle& triangle)
-{
- if(!rectangle_rectangle(hit, rect, movement, (const Rectangle&) triangle))
- return false;
-
- Vector normal;
- float c;
- Vector p1;
- Vector tp1, tp2;
- switch(triangle.dir & AATriangle::DEFORM_MASK) {
- case 0:
- tp1 = triangle.p1;
- tp2 = triangle.p2;
- break;
- case AATriangle::DEFORM1:
- tp1 = Vector(triangle.p1.x, triangle.p1.y + triangle.get_height()/2);
- tp2 = triangle.p2;
- break;
- case AATriangle::DEFORM2:
- tp1 = triangle.p1;
- tp2 = Vector(triangle.p2.x, triangle.p1.y + triangle.get_height()/2);
- break;
- case AATriangle::DEFORM3:
- tp1 = triangle.p1;
- tp2 = Vector(triangle.p1.x + triangle.get_width()/2, triangle.p2.y);
- break;
- case AATriangle::DEFORM4:
- tp1 = Vector(triangle.p1.x + triangle.get_width()/2, triangle.p1.y);
- tp2 = triangle.p2;
- break;
- default:
- assert(false);
- }
-
- switch(triangle.dir & AATriangle::DIRECTION_MASK) {
- case AATriangle::SOUTHWEST:
- p1 = Vector(rect.p1.x, rect.p2.y);
- makePlane(tp1, tp2, normal, c);
- break;
- case AATriangle::NORTHEAST:
- p1 = Vector(rect.p2.x, rect.p1.y);
- makePlane(tp2, tp1, normal, c);
- break;
- case AATriangle::SOUTHEAST:
- p1 = rect.p2;
- makePlane(Vector(tp1.x, tp2.y),
- Vector(tp2.x, tp1.y), normal, c);
- break;
- case AATriangle::NORTHWEST:
- p1 = rect.p1;
- makePlane(Vector(tp2.x, tp1.y),
- Vector(tp1.x, tp2.y), normal, c);
- break;
- default:
- assert(false);
- }
-
- float n_p1 = -(normal * p1);
- float depth = n_p1 - c;
- if(depth < 0)
- return false;
- float time = depth / -(normal * movement);
- if(time < hit.time) {
- hit.depth = depth;
- hit.time = time;
- hit.normal = normal;
- }
-
- return true;
-}
-
-}
+++ /dev/null
-#ifndef __COLLISION_H__
-#define __COLLISION_H__
-
-namespace SuperTux
-{
-
-class Vector;
-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 Vector& movement, 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 Vector& movement, const AATriangle& triangle);
-};
-
-}
-
-#endif
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2004 Matthias Braun <matze@braunis.de
-//
-// 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_COLLISION_HIT_H
-#define SUPERTUX_COLLISION_HIT_H
-
-#include "math/vector.h"
-
-namespace SuperTux
-{
-
-/**
- * Used as return value for the collision functions, to indicate how the
- * collision should be handled
- */
-enum HitResponse
-{
- // note: keep the elements in this order
-
- /// don't move the object
- ABORT_MOVE = 0,
- /// move object out of collision and check for collisions again
- /// if this happens to often then the move will just be aborted
- CONTINUE,
- /// do the move ignoring the collision
- FORCE_MOVE
-};
-
-/**
- * This class collects data about a collision
- */
-class CollisionHit
-{
-public:
- /// penetration depth
- float depth;
- /// time of the collision (between 0 and 1 in relation to movement)
- float time;
- /// The normal of the side we collided with
- Vector normal;
-};
-
-}
-
-#endif
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2004 Matthias Braun <matze@braunis.de>
-//
-// 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 <config.h>
-
-#include "game_object.h"
-#include "object_remove_listener.h"
-
-namespace SuperTux
-{
-
-GameObject::GameObject()
- : wants_to_die(false), remove_listeners(0), flags(0)
-{
-}
-
-GameObject::~GameObject()
-{
- // call remove listeners (and remove them from the list)
- RemoveListenerListEntry* entry = remove_listeners;
- while(entry != 0) {
- RemoveListenerListEntry* next = entry->next;
- entry->listener->object_removed(this);
- delete entry;
- entry = next;
- }
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2004 Matthias Braun <matze@braunis.de>
-//
-// 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_GAMEOBJECT_H
-#define SUPERTUX_GAMEOBJECT_H
-
-#include <string>
-
-namespace SuperTux
- {
-
- class DrawingContext;
-
- class ObjectRemoveListener;
-
- /**
- * Base class for all game objects. This contains functions for:
- * -querying the actual type of the object
- * -a flag that indicates if the object wants to be removed. Objects with this
- * flag will be removed at the end of each frame. This is alot safer than
- * having some uncontrollable "delete this" in the code.
- * -an action function that is called once per frame and allows the object to
- * update it's state.
- *
- * Most GameObjects will also implement the DrawableObject interface so that
- * they can actually be drawn on screen.
- */
- class GameObject
- {
- public:
- GameObject();
- 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 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;
-
- /** The GameObject should draw itself onto the provided DrawingContext if this
- * function is called.
- */
- virtual void draw(DrawingContext& context) = 0;
-
- /** returns true if the object is not scheduled to be removed yet */
- bool is_valid() const
- {
- return !wants_to_die;
- }
- /** schedules this object to be removed at the end of the frame */
- void remove_me()
- {
- wants_to_die = true;
- }
- /** registers a remove listener which will be called if the object
- * gets removed/destroyed
- */
- void add_remove_listener(ObjectRemoveListener* listener)
- {
- RemoveListenerListEntry* entry = new RemoveListenerListEntry();
- entry->next = remove_listeners;
- entry->listener = listener;
-
- remove_listeners = entry;
- }
-
- // 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;
-
- struct RemoveListenerListEntry
- {
- RemoveListenerListEntry* next;
- ObjectRemoveListener* listener;
- };
- RemoveListenerListEntry* remove_listeners;
-
- protected:
- int flags;
- };
-
-}
-#endif /*SUPERTUX_GAMEOBJECT_H*/
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2004 Matthias Braun <matze@braunis.de
-//
-// 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 <config.h>
-
-#include "moving_object.h"
-
-using namespace SuperTux;
-
-MovingObject::MovingObject()
-{
-}
-
-MovingObject::~MovingObject()
-{
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2004 Matthias Braun <matze@braunis.de
-//
-// 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_MOVING_OBJECT_H
-#define SUPERTUX_MOVING_OBJECT_H
-
-#include "game_object.h"
-#include "collision_hit.h"
-#include "math/vector.h"
-#include "math/rectangle.h"
-
-class FlipLevelTransformer;
-class Sector;
-class CollisionGrid;
-
-namespace SuperTux
- {
-
- /**
- * Base class for all dynamic/moving game objects. This class contains things
- * for handling the bounding boxes and collision feedback.
- */
- class MovingObject : public GameObject
- {
- public:
- MovingObject();
- virtual ~MovingObject();
-
- /** this function is called when the object collided with any other object
- */
- virtual HitResponse collision(GameObject& other,
- const CollisionHit& hit) = 0;
-
- const Vector& get_pos() const
- {
- return bbox.p1;
- }
-
- /** returns the bounding box of the Object */
- const Rectangle& get_bbox() const
- {
- return bbox;
- }
-
- const Vector& get_movement() const
- {
- return movement;
- }
-
- /** places the moving object at a specific position. Be carefull when
- * using this function. There are no collision detection checks performed
- * here so bad things could happen.
- */
- virtual void set_pos(const Vector& pos)
- {
- bbox.set_pos(pos);
- }
-
- protected:
- friend class Sector;
- friend class CollisionGrid;
-
- /** 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
-
-#endif /*SUPERTUX_MOVING_OBJECT_H*/
-
+++ /dev/null
-#ifndef __OBJECT_REMOVE_LISTENER_H__
-#define __OBJECT_REMOVE_LISTENER_H__
-
-namespace SuperTux
-{
-
-class GameObject;
-
-class ObjectRemoveListener
-{
-public:
- virtual ~ObjectRemoveListener()
- { }
-
- virtual void object_removed(GameObject* object) = 0;
-};
-
-}
-
-#endif
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
-//
-// 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 <config.h>
-
-#include <iostream>
-#include <cmath>
-#include <cassert>
-#include <stdexcept>
-
-#include "app/globals.h"
-#include "app/setup.h"
-#include "sprite.h"
-#include "video/drawing_context.h"
-
-namespace SuperTux
-{
-
-Sprite::Sprite(SpriteData& newdata)
- : data(newdata), frame(0), animation_loops(-1)
-{
- action = data.get_action("normal");
- if(!action)
- action = data.actions.begin()->second;
- last_ticks = SDL_GetTicks();
-}
-
-Sprite::Sprite(const Sprite& other)
- : data(other.data), frame(other.frame),
- animation_loops(other.animation_loops),
- action(other.action)
-{
- last_ticks = SDL_GetTicks();
-}
-
-Sprite::~Sprite()
-{
-}
-
-void
-Sprite::set_action(std::string name, int loops)
-{
- if(action && action->name == name)
- return;
-
- SpriteData::Action* newaction = data.get_action(name);
- if(!newaction) {
-#ifdef DEBUG
- std::cerr << "Action '" << name << "' not found.\n";
-#endif
- return;
- }
-
- action = newaction;
- animation_loops = loops;
- frame = 0;
-}
-
-bool
-Sprite::check_animation()
-{
- return animation_loops == 0;
-}
-
-void
-Sprite::update()
-{
- if(animation_loops == 0)
- return;
-
- Uint32 ticks = SDL_GetTicks();
- float frame_inc = action->fps * float(ticks - last_ticks)/1000.0;
- last_ticks = ticks;
-
- frame += frame_inc;
-
- if(frame >= get_frames()) {
- frame = fmodf(frame+get_frames(), get_frames());
-
- animation_loops--;
- if(animation_loops == 0)
- frame = 0;
- }
-}
-
-void
-Sprite::draw(DrawingContext& context, const Vector& pos, int layer,
- Uint32 drawing_effect)
-{
- assert(action != 0);
- update();
-
- if((int)frame >= get_frames() || (int)frame < 0)
- std::cerr << "Warning: frame out of range: " << (int)frame
- << "/" << get_frames() << " at " << get_name()
- << "/" << 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);
-}
-
-void
-Sprite::draw_part(DrawingContext& context, const Vector& source,
- const Vector& size, const Vector& pos, int layer, Uint32 drawing_effect)
-{
- assert(action != 0);
- update();
-
- if((int)frame >= get_frames() || (int)frame < 0)
- std::cerr << "Warning: frame out of range: " << (int)frame
- << "/" << get_frames() << " at sprite: " << get_name()
- << "/" << 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);
-}
-
-int
-Sprite::get_width() const
-{
- return action->surfaces[get_frame()]->w;
-}
-
-int
-Sprite::get_height() const
-{
- return action->surfaces[get_frame()]->h;
-}
-
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
-//
-// 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_H
-#define SUPERTUX_SPRITE_H
-
-#include <string>
-#include <vector>
-#include <cassert>
-#include <map>
-
-#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, int loops = -1);
-
- /* Stop animation */
- void stop_animation()
- { animation_loops = 0; }
- /** Check if animation is stopped or not */
- bool check_animation();
-
- 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)
- {
- assert(frame < action->surfaces.size());
- return action->surfaces[frame];
- }
-
- private:
- void update();
-
- SpriteData& data;
-
- float frame;
- int animation_loops;
- Uint32 last_ticks;
-
- SpriteData::Action* action;
- };
-} //namespace SuperTux
-
-#endif /*SUPERTUX_SPRITE_H*/
-
-/* Local Variables: */
-/* mode:c++ */
-/* End: */
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
-//
-// 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 <config.h>
-
-#include <iostream>
-#include <cmath>
-#include <sstream>
-#include <stdexcept>
-
-#include "sprite_data.h"
-#include "app/globals.h"
-#include "app/setup.h"
-#include "video/drawing_context.h"
-#include "lisp/list_iterator.h"
-
-namespace SuperTux
-{
-
-SpriteData::Action::Action()
-{
- x_offset = 0;
- y_offset = 0;
- z_order = 0;
- fps = 10;
-}
-
-SpriteData::Action::~Action()
-{
- for(std::vector<Surface*>::iterator i = surfaces.begin();
- i != surfaces.end(); ++i)
- delete *i;
-}
-
-SpriteData::SpriteData(const lisp::Lisp* lisp)
-{
- lisp::ListIterator iter(lisp);
- while(iter.next()) {
- if(iter.item() == "name") {
- iter.value()->get(name);
- } else if(iter.item() == "action") {
- parse_action(iter.lisp());
- } else {
- std::cerr << "Unknown sprite field: " << iter.item() << "\n";
- }
- }
- if(name.empty())
- throw std::runtime_error("Error: Sprite wihtout name.");
- if(actions.empty())
- throw std::runtime_error("Error: Sprite wihtout actions.");
-}
-
-SpriteData::~SpriteData()
-{
- for(Actions::iterator i=actions.begin(); i != actions.end(); ++i)
- delete i->second;
-}
-
-void
-SpriteData::parse_action(const lisp::Lisp* lisp)
-{
- Action* action = new Action;
-
- if(!lisp->get("name", action->name)) {
- if(!actions.empty())
- throw std::runtime_error(
- "If there are more than one action, they need names!");
- }
- lisp->get("x-offset", action->x_offset);
- lisp->get("y-offset", action->y_offset);
- lisp->get("z-order", action->z_order);
- lisp->get("fps", action->fps);
-
- std::string mirror_action;
- lisp->get("mirror-action", mirror_action);
- if(!mirror_action.empty()) {
- Action* act_tmp = get_action(mirror_action);
- if(act_tmp == NULL) {
- throw std::runtime_error("Could not mirror action. Action not found\n"
- "Mirror actions must be defined after the real one!");
- } else {
- for(int i = 0; static_cast<unsigned int>(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<std::string> images;
- if(!lisp->get_vector("images", images)) {
- std::stringstream msg;
- msg << "Sprite '" << name << "' contains no images in action '"
- << action->name << "'.";
- throw std::runtime_error(msg.str());
- }
-
- for(std::vector<std::string>::size_type i = 0; i < images.size(); i++) {
- action->surfaces.push_back(
- new Surface(datadir + "/images/" + images[i], true));
- }
- }
- actions[action->name] = action;
-}
-
-SpriteData::Action*
-SpriteData::get_action(std::string act)
-{
- Actions::iterator i = actions.find(act);
- if(i == actions.end()) {
- return 0;
- }
- return i->second;
-}
-
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>,
-// (C) 2004 Matthias Braun <matze@braunis.de>
-//
-// 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 <string>
-#include <vector>
-#include <map>
-
-#include "lisp/lisp.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(const lisp::Lisp* 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<Surface*> surfaces;
- };
-
- typedef std::map <std::string, Action*> Actions;
- Actions actions;
-
- void parse_action(const lisp::Lisp* lispreader);
- /** Get an action */
- Action* get_action(std::string act);
-
- std::string name;
- };
-}
-
-#endif
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
-//
-// 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 <config.h>
-
-#include <iostream>
-#include <sstream>
-#include <stdexcept>
-
-#include "sprite_manager.h"
-#include "sprite_data.h"
-#include "sprite.h"
-#include "lisp/lisp.h"
-#include "lisp/parser.h"
-#include "lisp/list_iterator.h"
-
-namespace SuperTux
-{
-
-SpriteManager::SpriteManager(const std::string& filename)
-{
- load_resfile(filename);
-}
-
-SpriteManager::~SpriteManager()
-{
- for(Sprites::iterator i = sprites.begin(); i != sprites.end(); ++i) {
- delete i->second;
- }
-}
-
-void
-SpriteManager::load_resfile(const std::string& filename)
-{
- lisp::Parser parser;
- try {
- std::auto_ptr<lisp::Lisp> root (parser.parse(filename));
-
- const lisp::Lisp* resources = root->get_lisp("supertux-resources");
- if(!resources)
- throw std::runtime_error("file is not a supertux-resources files");
-
- lisp::ListIterator iter(resources);
- while(iter.next()) {
- if(iter.item() == "sprite") {
- SpriteData* spritedata = new SpriteData(iter.lisp());
-
- 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 '" << iter.item()
- << "' in spritefile.\n";
- }
- }
- } catch(std::exception& e) {
- std::stringstream msg;
- msg << "Couldn't load file '" << filename << "': " << e.what() << "\n";
- throw std::runtime_error(msg.str());
- }
-}
-
-Sprite*
-SpriteManager::create(const std::string& name)
-{
- Sprites::iterator i = sprites.find(name);
- if(i == sprites.end()) {
- std::stringstream msg;
- msg << "Sprite '" << name << "' not found.";
- throw std::runtime_error(msg.str());
- }
- return new Sprite(*i->second);
-}
-
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
-//
-// 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_MANAGER_H
-#define SUPERTUX_SPRITE_MANAGER_H
-
-#include <map>
-
-#include "sprite.h"
-
-namespace SuperTux
-{
-
- class SpriteManager
- {
- private:
- typedef std::map<std::string, SpriteData*> 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*/
-
-/* Local Variables: */
-/* mode:c++ */
-/* End: */
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2004 Michael George <mike@georgetech.com>
-//
-// 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 <config.h>
-
-#include <cstdlib>
-#include <string>
-#include <stdexcept>
-
-#include "configfile.h"
-#include "app/setup.h"
-#include "app/globals.h"
-#include "audio/sound_manager.h"
-#include "lisp/parser.h"
-
-using namespace SuperTux;
-
-#ifdef WIN32
-const char * config_filename = ("/"+ package_symbol_name + "_config.dat").c_str();
-#else
-const char * config_filename = "/config";
-#endif
-
-Config* SuperTux::config = 0;
-
-static void defaults ()
-{
- /* Set defaults: */
- debug_mode = false;
- SoundManager::get()->set_audio_device_available(true);
-
- use_fullscreen = false;
- show_fps = false;
- use_gl = false;
-
- SoundManager::get()->enable_sound(true);
- SoundManager::get()->enable_music(true);
-}
-
-FILE * SuperTux::opendata(const std::string& rel_filename, const char *mode)
-{
- std::string filename;
- FILE * fi;
-
- filename = st_dir + rel_filename;
-
- /* Try opening the file: */
- fi = fopen(filename.c_str(), mode);
-
- if (fi == NULL)
- {
- fprintf(stderr, "Warning: Unable to open the file \"%s\" ", filename.c_str());
-
- if (strcmp(mode, "r") == 0)
- fprintf(stderr, "for read!!!\n");
- else if (strcmp(mode, "w") == 0)
- fprintf(stderr, "for write!!!\n");
- }
-
- return(fi);
-}
-
-void Config::load()
-{
- defaults();
-
- lisp::Parser parser;
- try {
- std::auto_ptr<lisp::Lisp> root (parser.parse(st_dir + config_filename));
-
- const lisp::Lisp* config_lisp = root->get_lisp(
- package_symbol_name + "-config");
- if(!config_lisp)
- throw new std::runtime_error("Config file is not a supertux-config file");
-
- config_lisp->get("fullscreen", use_fullscreen);
- bool temp = false;
- if(config_lisp->get("sound", temp))
- SoundManager::get()->enable_sound(temp);
- if(config_lisp->get("music", temp))
- SoundManager::get()->enable_music(temp);
- config_lisp->get("show_fps", show_fps);
-
- std::string video;
- if(config_lisp->get("video", video)) {
- if (video == "opengl")
- use_gl = true;
- else
- use_gl = false;
- }
-
- joystick_num = 0;
- config_lisp->get("joystick", joystick_num);
-
- if (joystick_num >= 0) {
- config_lisp->get("joystick-x", joystick_keymap.x_axis);
- config_lisp->get("joystick-y", joystick_keymap.y_axis);
- config_lisp->get("joystick-a", joystick_keymap.a_button);
- config_lisp->get("joystick-b", joystick_keymap.b_button);
- config_lisp->get("joystick-start", joystick_keymap.start_button);
- config_lisp->get("joystick-deadzone", joystick_keymap.dead_zone);
- }
-
- customload(config_lisp);
- } catch(std::exception& e) {
- std::cerr << "Couldn't load configfile: " << e.what() << "\n";
- }
-}
-
-void Config::save ()
-{
- /* write settings to config file */
- FILE * config = opendata(config_filename, "w");
-
- if(config)
- {
- fprintf(config, ("("+package_symbol_name+"-config\n").c_str());
- fprintf(config, "\t;; the following options can be set to #t or #f:\n");
- fprintf(config, "\t(fullscreen %s)\n", use_fullscreen ? "#t" : "#f");
- fprintf(config, "\t(sound %s)\n", SoundManager::get()->sound_enabled() ? "#t" : "#f");
- fprintf(config, "\t(music %s)\n", SoundManager::get()->music_enabled() ? "#t" : "#f");
- fprintf(config, "\t(show_fps %s)\n", show_fps ? "#t" : "#f");
-
- fprintf(config, "\n\t;; either \"opengl\" or \"sdl\"\n");
- fprintf(config, "\t(video \"%s\")\n", use_gl ? "opengl" : "sdl");
-
- if(use_joystick)
- {
- fprintf(config, "\n\t;; joystick number:\n");
- fprintf(config, "\t(joystick %d)\n", joystick_num);
-
- fprintf(config, "\t(joystick-x %d)\n", joystick_keymap.x_axis);
- fprintf(config, "\t(joystick-y %d)\n", joystick_keymap.y_axis);
- fprintf(config, "\t(joystick-a %d)\n", joystick_keymap.a_button);
- fprintf(config, "\t(joystick-b %d)\n", joystick_keymap.b_button);
- fprintf(config, "\t(joystick-start %d)\n", joystick_keymap.start_button);
- fprintf(config, "\t(joystick-deadzone %d)\n", joystick_keymap.dead_zone);
- }
-
- customsave(config);
-
- fprintf(config, ")\n");
- fclose(config);
- }
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2004 Michael George <mike@georgetech.com>
-//
-// 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_CONFIGFILE_H
-#define SUPERTUX_CONFIGFILE_H
-
-#include "lisp/lisp.h"
-
-namespace SuperTux {
-
-FILE * opendata(const std::string& filename, const char * mode);
-
-class Config {
-public:
- virtual ~Config()
- { }
- void load ();
- void save ();
- virtual void customload(const lisp::Lisp* )
- {};
- virtual void customsave(FILE* )
- {};
-};
-
-extern Config* config;
-
-} //namespace SuperTux
-
-#endif
-
-/* Local Variables: */
-/* mode:c++ */
-/* End: */
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2004 Matthias Braun <matze@braunis.de
-//
-// 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 <config.h>
-
-#include <algorithm>
-#include <cassert>
-#include <iostream>
-
-#include "drawing_context.h"
-#include "surface.h"
-#include "app/globals.h"
-#include "font.h"
-
-using namespace SuperTux;
-
-DrawingContext::DrawingContext()
-{
-}
-
-DrawingContext::~DrawingContext()
-{
-}
-
-void
-DrawingContext::draw_surface(const Surface* surface, const Vector& position,
- int layer, uint32_t drawing_effect)
-{
- assert(surface != 0);
-
- DrawingRequest request;
-
- request.type = SURFACE;
- request.pos = transform.apply(position);
-
- if(request.pos.x >= SCREEN_WIDTH || request.pos.y >= SCREEN_HEIGHT
- || request.pos.x + surface->w < 0 || request.pos.y + surface->h < 0)
- return;
-
- request.layer = layer;
- request.drawing_effect = transform.drawing_effect | drawing_effect;
- request.zoom = transform.zoom;
- request.alpha = transform.alpha;
- request.request_data = const_cast<Surface*> (surface);
-
- drawingrequests.push_back(request);
-}
-
-void
-DrawingContext::draw_surface_part(const Surface* surface, const Vector& source,
- const Vector& size, const Vector& dest, int layer, uint32_t drawing_effect)
-{
- assert(surface != 0);
-
- DrawingRequest request;
-
- request.type = SURFACE_PART;
- request.pos = transform.apply(dest);
- request.layer = layer;
- request.drawing_effect = transform.drawing_effect | drawing_effect;
- request.alpha = transform.alpha;
-
- SurfacePartRequest* surfacepartrequest = new SurfacePartRequest();
- surfacepartrequest->size = size;
- surfacepartrequest->source = source;
- surfacepartrequest->surface = surface;
-
- // clip on screen borders
- if(request.pos.x < 0) {
- surfacepartrequest->size.x += request.pos.x;
- if(surfacepartrequest->size.x <= 0)
- return;
- surfacepartrequest->source.x -= request.pos.x;
- request.pos.x = 0;
- }
- if(request.pos.y < 0) {
- surfacepartrequest->size.y += request.pos.y;
- if(surfacepartrequest->size.y <= 0)
- return;
- surfacepartrequest->source.y -= request.pos.y;
- request.pos.y = 0;
- }
- request.request_data = surfacepartrequest;
-
- drawingrequests.push_back(request);
-}
-
-void
-DrawingContext::draw_text(const Font* font, const std::string& text,
- const Vector& position, FontAlignment alignment, int layer,
- uint32_t drawing_effect)
-{
- DrawingRequest request;
-
- request.type = TEXT;
- request.pos = transform.apply(position);
- request.layer = layer;
- request.drawing_effect = transform.drawing_effect | drawing_effect;
- request.zoom = transform.zoom;
- request.alpha = transform.alpha;
-
- TextRequest* textrequest = new TextRequest;
- textrequest->font = font;
- textrequest->text = text;
- textrequest->alignment = alignment;
- request.request_data = textrequest;
-
- drawingrequests.push_back(request);
-}
-
-void
-DrawingContext::draw_center_text(const Font* font, const std::string& text,
- const Vector& position, int layer, uint32_t drawing_effect)
-{
- draw_text(font, text, Vector(position.x + SCREEN_WIDTH/2, position.y),
- CENTER_ALLIGN, layer, drawing_effect);
-}
-
-void
-DrawingContext::draw_gradient(Color top, Color bottom, int layer)
-{
- DrawingRequest request;
-
- request.type = GRADIENT;
- request.pos = Vector(0,0);
- request.layer = layer;
-
- request.drawing_effect = transform.drawing_effect;
- request.zoom = transform.zoom;
- request.alpha = transform.alpha;
-
- GradientRequest* gradientrequest = new GradientRequest;
- gradientrequest->top = top;
- gradientrequest->bottom = bottom;
- request.request_data = gradientrequest;
-
- drawingrequests.push_back(request);
-}
-
-void
-DrawingContext::draw_filled_rect(const Vector& topleft, const Vector& size,
- Color color, int layer)
-{
- DrawingRequest request;
-
- request.type = FILLRECT;
- request.pos = transform.apply(topleft);
- request.layer = layer;
-
- request.drawing_effect = transform.drawing_effect;
- request.zoom = transform.zoom;
- request.alpha = transform.alpha;
-
- FillRectRequest* fillrectrequest = new FillRectRequest;
- fillrectrequest->size = size;
- fillrectrequest->color = color;
- request.request_data = fillrectrequest;
-
- drawingrequests.push_back(request);
-}
-
-void
-DrawingContext::draw_surface_part(DrawingRequest& request)
-{
- SurfacePartRequest* surfacepartrequest
- = (SurfacePartRequest*) request.request_data;
-
- surfacepartrequest->surface->impl->draw_part(
- surfacepartrequest->source.x, surfacepartrequest->source.y,
- request.pos.x, request.pos.y,
- surfacepartrequest->size.x, surfacepartrequest->size.y, request.alpha,
- request.drawing_effect);
-
- delete surfacepartrequest;
-}
-
-void
-DrawingContext::draw_gradient(DrawingRequest& request)
-{
- GradientRequest* gradientrequest = (GradientRequest*) request.request_data;
- const Color& top = gradientrequest->top;
- const Color& bottom = gradientrequest->bottom;
-
-#ifndef NOOPENGL
- if(use_gl)
- {
- glBegin(GL_QUADS);
- glColor3ub(top.red, top.green, top.blue);
- glVertex2f(0, 0);
- glVertex2f(SCREEN_WIDTH, 0);
- glColor3ub(bottom.red, bottom.green, bottom.blue);
- glVertex2f(SCREEN_WIDTH, SCREEN_HEIGHT);
- glVertex2f(0, SCREEN_HEIGHT);
- glEnd();
- }
- else
- {
-#endif
- if(&top == &bottom)
- {
- fillrect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, top.red, top.green, top.blue);
- }
- else
- {
- float redstep = (float(bottom.red)-float(top.red)) / float(SCREEN_HEIGHT);
- float greenstep = (float(bottom.green)-float(top.green)) / float(SCREEN_HEIGHT);
- float bluestep = (float(bottom.blue) - float(top.blue)) / float(SCREEN_HEIGHT);
-
- for(float y = 0; y < SCREEN_HEIGHT; y += 2)
- fillrect(0, (int)y, SCREEN_WIDTH, 2,
- int(float(top.red) + redstep * y),
- int(float(top.green) + greenstep * y),
- int(float(top.blue) + bluestep * y), 255);
- }
-#ifndef NOOPENGL
-
- }
-#endif
-
- delete gradientrequest;
-}
-
-void
-DrawingContext::draw_text(DrawingRequest& request)
-{
- TextRequest* textrequest = (TextRequest*) request.request_data;
-
- textrequest->font->draw(textrequest->text, request.pos,
- textrequest->alignment, request.drawing_effect, request.alpha);
-
- delete textrequest;
-}
-
-void
-DrawingContext::draw_filled_rect(DrawingRequest& request)
-{
- FillRectRequest* fillrectrequest = (FillRectRequest*) request.request_data;
-
- float x = request.pos.x;
- float y = request.pos.y;
- float w = fillrectrequest->size.x;
- float h = fillrectrequest->size.y;
-
-#ifndef NOOPENGL
- if(use_gl)
- {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glColor4ub(fillrectrequest->color.red, fillrectrequest->color.green,
- fillrectrequest->color.blue, fillrectrequest->color.alpha);
-
- glBegin(GL_POLYGON);
- glVertex2f(x, y);
- glVertex2f(x+w, y);
- glVertex2f(x+w, y+h);
- glVertex2f(x, y+h);
- glEnd();
- glDisable(GL_BLEND);
- }
- else
- {
-#endif
- SDL_Rect src, rect;
- SDL_Surface *temp = NULL;
-
- rect.x = (int)x;
- rect.y = (int)y;
- rect.w = (int)w;
- rect.h = (int)h;
-
- if(fillrectrequest->color.alpha != 255)
- {
- temp = SDL_CreateRGBSurface(screen->flags, rect.w, rect.h, screen->format->BitsPerPixel,
- screen->format->Rmask,
- screen->format->Gmask,
- screen->format->Bmask,
- screen->format->Amask);
-
-
- src.x = 0;
- src.y = 0;
- src.w = rect.w;
- src.h = rect.h;
-
- SDL_FillRect(temp, &src, SDL_MapRGB(screen->format,
- fillrectrequest->color.red, fillrectrequest->color.green,
- fillrectrequest->color.blue));
-
- SDL_SetAlpha(temp, SDL_SRCALPHA, fillrectrequest->color.alpha);
-
- SDL_BlitSurface(temp,0,screen,&rect);
-
- SDL_FreeSurface(temp);
- }
- else
- SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format,
- fillrectrequest->color.red, fillrectrequest->color.green,
- fillrectrequest->color.blue));
-
-#ifndef NOOPENGL
-
- }
-#endif
-
- delete fillrectrequest;
-}
-
-void
-DrawingContext::do_drawing()
-{
-#ifdef DEBUG
- assert(transformstack.empty());
-#endif
- transformstack.clear();
-
- std::stable_sort(drawingrequests.begin(), drawingrequests.end());
-
- for(DrawingRequests::iterator i = drawingrequests.begin();
- i != drawingrequests.end(); ++i) {
- switch(i->type) {
- case SURFACE:
- {
- const Surface* surface = (const Surface*) i->request_data;
-
- if(i->zoom != 1.0)
- surface->impl->draw_stretched(i->pos.x * i->zoom, i->pos.y * i->zoom,
- (int)(surface->w * i->zoom), (int)(surface->h * i->zoom),
- i->alpha, i->drawing_effect);
- else
- surface->impl->draw(i->pos.x, i->pos.y, i->alpha, i->drawing_effect);
- break;
- }
- case SURFACE_PART:
- draw_surface_part(*i);
- break;
- case GRADIENT:
- draw_gradient(*i);
- break;
- case TEXT:
- draw_text(*i);
- break;
- case FILLRECT:
- draw_filled_rect(*i);
- break;
- }
- }
-
- // update screen
- if(use_gl)
- SDL_GL_SwapBuffers();
- else
- SDL_Flip(screen);
-
- drawingrequests.clear();
-}
-
-void
-DrawingContext::push_transform()
-{
- transformstack.push_back(transform);
-}
-
-void
-DrawingContext::pop_transform()
-{
- assert(!transformstack.empty());
-
- transform = transformstack.back();
- transformstack.pop_back();
-}
-
-void
-DrawingContext::set_drawing_effect(int effect)
-{
- transform.drawing_effect = effect;
-}
-
-void
-DrawingContext::set_zooming(float zoom)
-{
- transform.zoom = zoom;
-}
-
-void
-DrawingContext::set_alpha(int alpha)
-{
- transform.alpha = alpha;
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2004 Matthias Braun <matze@braunis.de
-//
-// 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_DRAWINGCONTEXT_H
-#define SUPERTUX_DRAWINGCONTEXT_H
-
-#include <vector>
-#include <string>
-#include <stdint.h>
-
-#include "SDL.h"
-
-#include "math/vector.h"
-#include "video/screen.h"
-#include "video/surface.h"
-#include "video/font.h"
-
-namespace SuperTux
- {
-
- class Surface;
-
- // some constants for predefined layer values
- enum {
- LAYER_BACKGROUND0 = -300,
- LAYER_BACKGROUND1 = -200,
- LAYER_BACKGROUNDTILES = -100,
- LAYER_TILES = 0,
- LAYER_OBJECTS = 100,
- LAYER_FOREGROUNDTILES = 200,
- LAYER_FOREGROUND0 = 300,
- LAYER_FOREGROUND1 = 400,
- LAYER_GUI = 500
- };
-
- /// Handles drawing of things.
- /**
- * This class provides functions for drawing things on screen. It also
- * maintains a stack of transforms that are applied to graphics.
- */
- class DrawingContext
- {
- public:
- DrawingContext();
- ~DrawingContext();
-
- /// Adds a drawing request for a surface into the request list.
- void draw_surface(const Surface* surface, const Vector& position,
- int layer, uint32_t drawing_effect = NONE_EFFECT);
- /// Adds a drawing request for part of a surface.
- void draw_surface_part(const Surface* surface, const Vector& source,
- const Vector& size, const Vector& dest, int layer,
- uint32_t drawing_effect = NONE_EFFECT);
- /// Draws a text.
- void draw_text(const Font* font, const std::string& text,
- const Vector& position, FontAlignment alignment, int layer,
- uint32_t drawing_effect = NONE_EFFECT);
-
- /// Draws text on screen center (feed Vector.x with a 0).
- /// This is the same as draw_text() with a SCREEN_WIDTH/2 position and
- /// alignment set to LEFT_ALLIGN
- void draw_center_text(const Font* font, const std::string& text,
- const Vector& position, int layer,
- uint32_t drawing_effect = NONE_EFFECT);
- /// Draws a color gradient onto the whole screen */
- void draw_gradient(Color from, Color to, int layer);
- /// Fills a rectangle.
- void draw_filled_rect(const Vector& topleft, const Vector& size,
- Color color, int layer);
-
- /// Processes all pending drawing requests and flushes the list.
- void do_drawing();
-
- const Vector& get_translation() const
- { return transform.translation; }
- uint32_t get_drawing_effect() const
- { return transform.drawing_effect; }
-
- void set_translation(const Vector& newtranslation)
- { transform.translation = newtranslation; }
-
- void push_transform();
- void pop_transform();
-
- /// Apply that effect in the next draws (effects are listed on surface.h).
- void set_drawing_effect(int effect);
- /// apply that zoom in the next draws */
- void set_zooming(float zoom);
- /// apply that alpha in the next draws */
- void set_alpha(int alpha);
-
- private:
- class Transform
- {
- public:
- Vector translation;
- uint32_t drawing_effect;
- float zoom;
- int alpha;
-
- Transform()
- : drawing_effect(NONE_EFFECT), zoom(1), alpha(255)
- { }
-
- Vector apply(const Vector& v) const
- {
- return v - translation;
- }
- };
-
- /// the transform stack
- std::vector<Transform> transformstack;
- /// the currently active transform
- Transform transform;
-
- enum RequestType
- {
- SURFACE, SURFACE_PART, TEXT, GRADIENT, FILLRECT
- };
-
- struct SurfacePartRequest
- {
- const Surface* surface;
- Vector source, size;
- };
-
- struct TextRequest
- {
- const Font* font;
- std::string text;
- FontAlignment alignment;
- };
-
- struct GradientRequest
- {
- Color top, bottom;
- Vector size;
- };
-
- struct FillRectRequest
- {
- Color color;
- Vector size;
- };
-
- struct DrawingRequest
- {
- RequestType type;
- Vector pos;
-
- int layer;
- uint32_t drawing_effect;
- float zoom;
- int alpha;
-
- void* request_data;
-
- bool operator<(const DrawingRequest& other) const
- {
- return layer < other.layer;
- }
- };
-
- void draw_surface_part(DrawingRequest& request);
- void draw_text(DrawingRequest& request);
- void draw_text_center(DrawingRequest& request);
- void draw_gradient(DrawingRequest& request);
- void draw_filled_rect(DrawingRequest& request);
-
- typedef std::vector<DrawingRequest> DrawingRequests;
- DrawingRequests drawingrequests;
- };
-
-} //namespace SuperTux
-
-#endif /*SUPERTUX_DRAWINGCONTEXT_H*/
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-//
-// 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 <config.h>
-
-#include <cstdlib>
-#include <cstring>
-#include <stdexcept>
-
-#include "app/globals.h"
-#include "lisp/parser.h"
-#include "lisp/lisp.h"
-#include "screen.h"
-#include "font.h"
-#include "drawing_context.h"
-
-using namespace SuperTux;
-
-Font::Font(const std::string& file, FontType ntype, int nw, int nh,
- int nshadowsize)
- : chars(0), shadow_chars(0), type(ntype), w(nw), h(nh),
- shadowsize(nshadowsize)
-{
- chars = new Surface(file, true);
-
- switch(type) {
- case TEXT:
- first_char = 32;
- break;
- case NUM:
- first_char = 48;
- break;
- }
- last_char = first_char + (chars->h / h) * 16;
- if(last_char > 127) // we have left out some control chars at 128-159
- last_char += 32;
-
- // Load shadow font.
- if(shadowsize > 0) {
- SDL_Surface* conv = SDL_DisplayFormatAlpha(chars->impl->get_sdl_surface());
- int pixels = conv->w * conv->h;
- SDL_LockSurface(conv);
- for(int i = 0; i < pixels; ++i) {
- Uint32 *p = (Uint32 *)conv->pixels + i;
- *p = *p & conv->format->Amask;
- }
- SDL_UnlockSurface(conv);
- SDL_SetAlpha(conv, SDL_SRCALPHA, 128);
- shadow_chars = new Surface(conv, true);
- SDL_FreeSurface(conv);
- }
-}
-
-Font::~Font()
-{
- delete chars;
- delete shadow_chars;
-}
-
-float
-Font::get_text_width(const std::string& text) const
-{
- /** Let's calculate the size of the biggest paragraph */
- std::string::size_type l, hl, ol;
- hl = 0; l = 0;
- while(true)
- {
- ol = l;
- l = text.find("\n", l+1);
- if(l == std::string::npos)
- break;
- if(hl < l-ol)
- hl = l-ol;
- }
- if(hl == 0)
- hl = text.size();
-
- return hl * w;
-}
-
-float
-Font::get_text_height(const std::string& text) const
-{
- /** Let's calculate height of the text */
- std::string::size_type l, hh;
- hh = h; l = 0;
- while(true)
- {
- l = text.find("\n", l+1);
- if(l == std::string::npos)
- break;
- hh += h + 2;
- }
-
- return hh;
-}
-
-float
-Font::get_height() const
-{
- return h;
-}
-
-void
-Font::draw(const std::string& text, const Vector& pos_, FontAlignment alignment,
- uint32_t drawing_effect, uint8_t alpha) const
-{
- /* Cut lines changes into seperate strings, needed to support center/right text
- alignments with break lines.
- Feel free to replace this hack with a more elegant solution
- */
- char temp[1024];
- std::string::size_type l, i, y;
- bool done = false;
- i = y = 0;
-
- while(!done)
- {
- l = text.find("\n", i);
- if(l == std::string::npos)
- {
- l = text.size();
- done = true;
- }
-
- temp[text.copy(temp, l - i, i)] = '\0';
-
- // calculate X positions based on the alignment type
- Vector pos = Vector(pos_);
- if(alignment == CENTER_ALLIGN)
- pos.x -= get_text_width(temp) / 2;
- else if(alignment == RIGHT_ALLIGN)
- pos.x -= get_text_width(temp);
-
- draw_text(temp, pos + Vector(0,y), drawing_effect, alpha);
-
- i = l+1;
- y += h + 2;
- }
-}
-
-void
-Font::draw_text(const std::string& text, const Vector& pos,
- uint32_t drawing_effect, uint8_t alpha) const
-{
- if(shadowsize > 0)
- draw_chars(shadow_chars, text, pos + Vector(shadowsize, shadowsize),
- drawing_effect, alpha);
-
- draw_chars(chars, text, pos, drawing_effect, alpha);
-}
-
-void
-Font::draw_chars(Surface* pchars, const std::string& text, const Vector& pos,
- uint32_t drawing_effect, uint8_t alpha) const
-{
- SurfaceImpl* impl = pchars->impl;
-
- Vector p = pos;
- for(size_t i = 0; i < text.size(); ++i)
- {
- int c = (unsigned char) text[i];
- if(c > 127) // correct for the 32 controlchars at 128-159
- c -= 32;
- // a non-printable character?
- if(c == '\n') {
- p.x = pos.x;
- p.y += h + 2;
- continue;
- }
- if(c == ' ' || c < first_char || c > last_char) {
- p.x += w;
- continue;
- }
-
- int index = c - first_char;
- int source_x = (index % 16) * w;
- int source_y = (index / 16) * h;
-
- impl->draw_part(source_x, source_y, p.x, p.y, w, h, alpha, drawing_effect);
- p.x += w;
- }
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-//
-// 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_FONT_H
-#define SUPERTUX_FONT_H
-
-#include <string>
-#include <stdint.h>
-
-#include "video/surface.h"
-#include "math/vector.h"
-
-namespace SuperTux
- {
-
- enum FontAlignment {
- LEFT_ALLIGN,
- CENTER_ALLIGN,
- RIGHT_ALLIGN
- };
-
- /// Font
- class Font
- {
- public:
- /// Kinds of texts.
- enum FontType {
- TEXT, // images for all characters
- NUM // only images for numbers
- };
-
- Font(const std::string& file, FontType type, int w, int h,
- int shadowsize=2);
- ~Font();
-
- /** returns the width of a given text. (Note that I won't add a normal
- * get_width function here, as we might switch to variable width fonts in the
- * future.)
- * Supports breaklines.
- */
- float get_text_width(const std::string& text) const;
-
- /** returns the height of a given text. (Note that I won't add a normal
- * get_width function here, as we might switch to variable width fonts in the
- * future.)
- * Supports breaklines.
- * In case, you are positive that your text doesn't use break lines, you can
- * just use get_height().
- */
- float get_text_height(const std::string& text) const;
- /// returns the height of the font.
- float get_height() const;
-
- /** Draws the given text to the screen. Also needs the position.
- * Type of alignment, drawing effect and alpha are optional. */
- void draw(const std::string& text, const Vector& pos,
- FontAlignment allignment = LEFT_ALLIGN,
- uint32_t drawing_effect = NONE_EFFECT, uint8_t alpha = 255) const;
-
- private:
- friend class DrawingContext;
-
- void draw_text(const std::string& text, const Vector& pos,
- uint32_t drawing_effect = NONE_EFFECT, uint8_t alpha = 255) const;
-
- void draw_chars(Surface* pchars, const std::string& text,
- const Vector& position, uint32_t drawing_effect, uint8_t alpha) const;
-
- Surface* chars;
- Surface* shadow_chars;
- FontType type;
- int w;
- int h;
- int shadowsize;
-
- /// the number of the first character that is represented in the font
- int first_char;
- /// the number of the last character that is represented in the font
- int last_char;
- };
-} //namespace SuperTux
-
-#endif /*SUPERTUX_FONT_H*/
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2000 Bill Kendrick <bill@newbreedsoftware.com>
-//
-// 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 <config.h>
-
-#include <iostream>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-#include <cerrno>
-
-#include <unistd.h>
-
-#include "SDL.h"
-#include "SDL_image.h"
-
-#ifndef WIN32
-#include <sys/types.h>
-#include <ctype.h>
-#endif
-
-#include "screen.h"
-#include "app/globals.h"
-#include "video/drawing_context.h"
-#include "math/vector.h"
-
-using namespace SuperTux;
-
-/* 'Stolen' from the SDL documentation.
- * Return the pixel value at (x, y)
- * NOTE: The surface must be locked before calling this!
- */
-Uint32 SuperTux::getpixel(SDL_Surface *surface, int x, int y)
-{
- int bpp = surface->format->BytesPerPixel;
- /* Here p is the address to the pixel we want to retrieve */
- Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
-
- switch(bpp) {
- case 1:
- return *p;
-
- case 2:
- return *(Uint16 *)p;
-
- case 3:
- if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
- return p[0] << 16 | p[1] << 8 | p[2];
- else
- return p[0] | p[1] << 8 | p[2] << 16;
-
- case 4:
- return *(Uint32 *)p;
-
- default:
- return 0; /* shouldn't happen, but avoids warnings */
- }
-}
-
-/* 'Stolen' from the SDL documentation.
- * Set the pixel at (x, y) to the given value
- * NOTE: The surface must be locked before calling this!
- */
-void SuperTux::putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
-{
- int bpp = surface->format->BytesPerPixel;
- /* Here p is the address to the pixel we want to set */
- Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
-
- switch(bpp)
- {
- case 1:
- *p = pixel;
- break;
-
- case 2:
- *(Uint16 *)p = pixel;
- break;
-
- case 3:
- if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
- {
- p[0] = (pixel >> 16) & 0xff;
- p[1] = (pixel >> 8) & 0xff;
- p[2] = pixel & 0xff;
- }
- else
- {
- p[0] = pixel & 0xff;
- p[1] = (pixel >> 8) & 0xff;
- p[2] = (pixel >> 16) & 0xff;
- }
- break;
-
- case 4:
- *(Uint32 *)p = pixel;
- break;
- }
-}
-
-/* Draw a single pixel on the screen. */
-void SuperTux::drawpixel(int x, int y, Uint32 pixel)
-{
- /* Lock the screen for direct access to the pixels */
- if ( SDL_MUSTLOCK(screen) )
- {
- if ( SDL_LockSurface(screen) < 0 )
- {
- fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError());
- return;
- }
- }
-
- if(!(x < 0 || y < 0 || x > SCREEN_WIDTH || y > SCREEN_HEIGHT))
- putpixel(screen, x, y, pixel);
-
- if ( SDL_MUSTLOCK(screen) )
- {
- SDL_UnlockSurface(screen);
- }
- /* Update just the part of the display that we've changed */
- SDL_UpdateRect(screen, x, y, 1, 1);
-}
-
-/* --- FILL A RECT --- */
-
-void SuperTux::fillrect(float x, float y, float w, float h, int r, int g, int b, int a)
-{
-if(w < 0)
- {
- x += w;
- w = -w;
- }
-if(h < 0)
- {
- y += h;
- h = -h;
- }
-
-#ifndef NOOPENGL
- if(use_gl)
- {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glColor4ub(r, g, b,a);
-
- glBegin(GL_POLYGON);
- glVertex2f(x, y);
- glVertex2f(x+w, y);
- glVertex2f(x+w, y+h);
- glVertex2f(x, y+h);
- glEnd();
- glDisable(GL_BLEND);
- }
- else
- {
-#endif
- SDL_Rect src, rect;
- SDL_Surface *temp = NULL;
-
- rect.x = (int)x;
- rect.y = (int)y;
- rect.w = (int)w;
- rect.h = (int)h;
-
- if(a != 255)
- {
- temp = SDL_CreateRGBSurface(screen->flags, rect.w, rect.h, screen->format->BitsPerPixel,
- screen->format->Rmask,
- screen->format->Gmask,
- screen->format->Bmask,
- screen->format->Amask);
-
-
- src.x = 0;
- src.y = 0;
- src.w = rect.w;
- src.h = rect.h;
-
- SDL_FillRect(temp, &src, SDL_MapRGB(screen->format, r, g, b));
-
- SDL_SetAlpha(temp, SDL_SRCALPHA, a);
-
- SDL_BlitSurface(temp,0,screen,&rect);
-
- SDL_FreeSurface(temp);
- }
- else
- SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, r, g, b));
-
-#ifndef NOOPENGL
-
- }
-#endif
-}
-
-/* Needed for line calculations */
-#define SGN(x) ((x)>0 ? 1 : ((x)==0 ? 0:(-1)))
-#define ABS(x) ((x)>0 ? (x) : (-x))
-
-void SuperTux::draw_line(float x1, float y1, float x2, float y2, int r, int g, int b, int a)
-{
-#ifndef NOOPENGL
- if(use_gl)
- {
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glColor4ub(r, g, b,a);
-
- glBegin(GL_LINES);
- glVertex2f(x1, y1);
- glVertex2f(x2, y2);
- glEnd();
- glDisable(GL_BLEND);
- }
- else
- {
-#endif
- /* Basic unantialiased Bresenham line algorithm */
- int lg_delta, sh_delta, cycle, lg_step, sh_step;
- Uint32 color = SDL_MapRGBA(screen->format, r, g, b, a);
-
- lg_delta = (int)(x2 - x1);
- sh_delta = (int)(y2 - y1);
- lg_step = SGN(lg_delta);
- lg_delta = ABS(lg_delta);
- sh_step = SGN(sh_delta);
- sh_delta = ABS(sh_delta);
- if (sh_delta < lg_delta)
- {
- cycle = lg_delta >> 1;
- while (x1 != x2)
- {
- drawpixel((int)x1, (int)y1, color);
- cycle += sh_delta;
- if (cycle > lg_delta)
- {
- cycle -= lg_delta;
- y1 += sh_step;
- }
- x1 += lg_step;
- }
- drawpixel((int)x1, (int)y1, color);
- }
- cycle = sh_delta >> 1;
- while (y1 != y2)
- {
- drawpixel((int)x1, (int)y1, color);
- cycle += lg_delta;
- if (cycle > sh_delta)
- {
- cycle -= sh_delta;
- x1 += lg_step;
- }
- y1 += sh_step;
- }
- drawpixel((int)x1, (int)y1, color);
-#ifndef NOOPENGL
-
- }
-#endif
-}
-
-#define LOOP_DELAY 20.0
-
-void SuperTux::fadeout(int fade_time)
-{
- float alpha_inc = 256 / (fade_time / LOOP_DELAY);
- float alpha = 256;
-
- while(alpha > 0)
- {
- alpha -= alpha_inc;
- fillrect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0,0,0, (int)alpha_inc); // left side
-
- DrawingContext context; // ugly...
- context.do_drawing();
-
- SDL_Delay(int(LOOP_DELAY));
- }
-
- fillrect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 0, 255);
-
-}
-
-void SuperTux::shrink_fade(const Vector& point, int fade_time)
-{
- float left_inc = point.x / ((float)fade_time / LOOP_DELAY);
- float right_inc = (SCREEN_WIDTH - point.x) / ((float)fade_time / LOOP_DELAY);
- float up_inc = point.y / ((float)fade_time / LOOP_DELAY);
- float down_inc = (SCREEN_HEIGHT - point.y) / ((float)fade_time / LOOP_DELAY);
-
- float left_cor = 0, right_cor = 0, up_cor = 0, down_cor = 0;
-
- while(left_cor < point.x && right_cor < SCREEN_WIDTH - point.x &&
- up_cor < point.y && down_cor < SCREEN_HEIGHT - point.y)
- {
- left_cor += left_inc;
- right_cor += right_inc;
- up_cor += up_inc;
- down_cor += down_inc;
-
- fillrect(0, 0, left_cor, SCREEN_HEIGHT, 0,0,0); // left side
- fillrect(SCREEN_WIDTH - right_cor, 0, right_cor, SCREEN_HEIGHT, 0,0,0); // right side
- fillrect(0, 0, SCREEN_WIDTH, up_cor, 0,0,0); // up side
- fillrect(0, SCREEN_HEIGHT - down_cor, SCREEN_WIDTH, down_cor+1, 0,0,0); // down side
- DrawingContext context; // ugly...
- context.do_drawing();
-
- SDL_Delay(int(LOOP_DELAY));
- }
-}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux - A Jump'n Run
-// Copyright (C) 2000 Bill Kendrick <bill@newbreedsoftware.com>
-//
-// 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_SCREEN_H
-#define SUPERTUX_SCREEN_H
-
-#include <SDL.h>
-#ifndef NOOPENGL
-#include <SDL_opengl.h>
-#endif
-#include <iostream>
-
-#include <vector>
-
-namespace SuperTux
- {
-
- /// Color RGBA
- /** Stores 8bit RGBA values. */
- class Color
- {
- public:
- Color()
- : red(0), green(0), blue(0), alpha(255)
- {}
-
- Color(Uint8 red_, Uint8 green_, Uint8 blue_, Uint8 alpha_ = 255)
- : red(red_), green(green_), blue(blue_), alpha(alpha_)
- {}
-
- Color(std::vector <unsigned int> color)
- : red(0), green(0), blue(0), alpha(255)
- { if(color.size() >= 3) { red = color[0]; green = color[1]; blue = color[2]; }
- if(color.size() == 4) alpha = color[3]; }
-
- Color(std::vector <int> color)
- : red(0), green(0), blue(0), alpha(255)
- { if(color.size() >= 3) { red = color[0]; green = color[1]; blue = color[2]; }
- if(color.size() == 4) alpha = color[3]; }
-
- Color(const Color& o)
- : red(o.red), green(o.green), blue(o.blue), alpha(o.alpha)
- { }
-
- bool operator==(const Color& o)
- {
- if(red == o.red && green == o.green &&
- blue == o.blue && alpha == o.alpha)
- return true;
- return false;
- }
-
- Uint32 map_rgb(SDL_Surface* surface)
- { return SDL_MapRGB(surface->format, red, green, blue); }
- Uint32 map_rgba(SDL_Surface* surface)
- { return SDL_MapRGBA(surface->format, red, green, blue, alpha); }
-
- Uint8 red, green, blue, alpha;
- };
-
-
- class Vector;
-
- Uint32 getpixel(SDL_Surface* surface, int x, int y);
- void putpixel(SDL_Surface* surface, int x, int y, Uint32 pixel);
- void drawpixel(int x, int y, Uint32 pixel);
- void fillrect(float x, float y, float w, float h, int r, int g, int b, int a = 255);
- void draw_line(float x1, float y1, float x2, float y2, int r, int g, int b, int a = 255);
-
- void fadeout(int fade_time);
- void shrink_fade(const Vector& point, int fade_time);
-
-} //namespace SuperTux
-
-#endif /*SUPERTUX_SCREEN_H*/
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-//
-// 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 <config.h>
-
-#include <cassert>
-#include <iostream>
-#include <algorithm>
-
-#include "SDL.h"
-#include "SDL_image.h"
-
-#include "video/surface.h"
-#include "video/screen.h"
-#include "app/globals.h"
-#include "app/setup.h"
-
-using namespace SuperTux;
-
-Surface::Surfaces Surface::surfaces;
-
-SurfaceData::SurfaceData(SDL_Surface* temp, bool use_alpha_)
- : type(SURFACE), surface(0), use_alpha(use_alpha_),
- x(0), y(0), w(0), h(0)
-{
- // Copy the given surface and make sure that it is not stored in
- // video memory
- surface = SDL_CreateRGBSurface(temp->flags & (~SDL_HWSURFACE),
- temp->w, temp->h,
- temp->format->BitsPerPixel,
- temp->format->Rmask,
- temp->format->Gmask,
- temp->format->Bmask,
- temp->format->Amask);
- if(!surface)
- Termination::abort("No memory left.", "");
- SDL_SetAlpha(temp,0,0);
- SDL_BlitSurface(temp, NULL, surface, NULL);
-}
-
-SurfaceData::SurfaceData(const std::string& file_, bool use_alpha_)
- : type(LOAD), surface(0), file(file_), use_alpha(use_alpha_)
-{}
-
-SurfaceData::SurfaceData(const std::string& file_, int x_, int y_,
- int w_, int h_, bool use_alpha_)
- : type(LOAD_PART), surface(0), file(file_), use_alpha(use_alpha_),
- x(x_), y(y_), w(w_), h(h_)
-{}
-
-SurfaceData::SurfaceData(Color top_gradient_, Color bottom_gradient_,
- int w_, int h_)
- : type(GRADIENT), surface(0), use_alpha(false), w(w_), h(h_)
-{
- top_gradient = top_gradient_;
- bottom_gradient = bottom_gradient_;
-}
-
-
-SurfaceData::~SurfaceData()
-{
- SDL_FreeSurface(surface);
-}
-
-SurfaceImpl*
-SurfaceData::create()
-{
-#ifndef NOOPENGL
- if (use_gl)
- return create_SurfaceOpenGL();
- else
- return create_SurfaceSDL();
-#else
- return create_SurfaceSDL();
-#endif
-}
-
-SurfaceSDL*
-SurfaceData::create_SurfaceSDL()
-{
- switch(type)
- {
- case LOAD:
- return new SurfaceSDL(file, use_alpha);
- case LOAD_PART:
- return new SurfaceSDL(file, x, y, w, h, use_alpha);
- case SURFACE:
- return new SurfaceSDL(surface, use_alpha);
- case GRADIENT:
- return new SurfaceSDL(top_gradient, bottom_gradient, w, h);
- }
- assert(0);
-}
-
-SurfaceOpenGL*
-SurfaceData::create_SurfaceOpenGL()
-{
-#ifndef NOOPENGL
- switch(type)
- {
- case LOAD:
- return new SurfaceOpenGL(file, use_alpha);
- case LOAD_PART:
- return new SurfaceOpenGL(file, x, y, w, h, use_alpha);
- case SURFACE:
- return new SurfaceOpenGL(surface, use_alpha);
- case GRADIENT:
- return new SurfaceOpenGL(top_gradient, bottom_gradient, w, h);
- }
-#endif
- assert(0);
-}
-
-#ifndef NOOPENGL
-/* Quick utility function for texture creation */
-static int power_of_two(int input)
-{
- int value = 1;
-
- while ( value < input )
- {
- value <<= 1;
- }
- return value;
-}
-#endif
-
-Surface::Surface(SDL_Surface* surf, bool use_alpha)
- : data(surf, use_alpha), w(0), h(0)
-{
- impl = data.create();
- if (impl)
- {
- w = impl->w;
- h = impl->h;
- }
- surfaces.push_back(this);
-}
-
-Surface::Surface(const std::string& file, bool use_alpha)
- : data(file, use_alpha), w(0), h(0)
-{
- impl = data.create();
- if (impl)
- {
- w = impl->w;
- h = impl->h;
- }
- surfaces.push_back(this);
-}
-
-Surface::Surface(const std::string& file, int x, int y, int w_, int h_, bool use_alpha)
- : data(file, x, y, w_, h_, use_alpha), w(0), h(0)
-{
- impl = data.create();
- if (impl)
- {
- w = impl->w;
- h = impl->h;
- }
- surfaces.push_back(this);
-}
-
-Surface::Surface(Color top_background, Color bottom_background, int w_, int h_)
- : data(top_background, bottom_background, w_, h_), w(0), h(0)
-{
- impl = data.create();
- if (impl)
- {
- w = impl->w;
- h = impl->h;
- }
- surfaces.push_back(this);
-}
-
-void
-Surface::reload()
-{
- delete impl;
- impl = data.create();
- if (impl)
- {
- w = impl->w;
- h = impl->h;
- for(std::vector<SurfaceData::Filter>::iterator i =
- data.applied_filters.begin(); i != data.applied_filters.end();
- i++)
- impl->apply_filter(i->type, i->color);
- }
-}
-
-void Surface::apply_filter(int filter, Color color)
-{
- impl->apply_filter(filter, color);
-
- SurfaceData::Filter apply_filter;
- apply_filter.type = filter;
- apply_filter.color = color;
- data.applied_filters.push_back(apply_filter);
-}
-
-Surface::~Surface()
-{
-#ifdef DEBUG
- bool found = false;
- for(std::list<Surface*>::iterator i = surfaces.begin(); i != surfaces.end();
- ++i)
- {
- if(*i == this)
- {
- found = true; break;
- }
- }
- if(!found)
- printf("Error: Surface freed twice!!!\n");
-#endif
- surfaces.remove(this);
- delete impl;
-}
-
-void
-Surface::reload_all()
-{
- for(Surfaces::iterator i = surfaces.begin(); i != surfaces.end(); ++i)
- {
- (*i)->reload();
- }
-}
-
-void
-Surface::debug_check()
-{
- for(Surfaces::iterator i = surfaces.begin(); i != surfaces.end(); ++i)
- {
- printf("Surface not freed: T:%d F:%s.\n", (*i)->data.type,
- (*i)->data.file.c_str());
- }
-}
-
-void
-apply_filter_to_surface(SDL_Surface* surface, int filter, Color color)
-{
- if(filter == HORIZONTAL_FLIP_FILTER) {
- SDL_Surface* sur_copy = sdl_surface_from_sdl_surface(surface, true);
- SDL_BlitSurface(surface, NULL, sur_copy, NULL);
- SDL_SetAlpha(sur_copy,0,0);
-
- SDL_Rect src, dst;
- src.y = dst.y = 0;
- src.w = dst.w = 1;
- src.h = dst.h = sur_copy->h;
- for(int x = 0; x < sur_copy->w; x++)
- {
- src.x = x; dst.x = sur_copy->w-1 - x;
- SDL_BlitSurface(sur_copy, &src, surface, &dst);
- }
-
- SDL_FreeSurface(sur_copy);
- } else if(filter == MASK_FILTER) {
- SDL_Surface* sur_copy = sdl_surface_from_sdl_surface(surface, true);
-
- Uint8 r,g,b,a;
-
- SDL_LockSurface(sur_copy);
- for(int x = 0; x < sur_copy->w; x++)
- for(int y = 0; y < sur_copy->h; y++) {
- SDL_GetRGBA(getpixel(sur_copy,x,y), sur_copy->format, &r,&g,&b,&a);
- if(a != 0) {
- putpixel(sur_copy, x,y, color.map_rgba(sur_copy));
- }
- }
- SDL_UnlockSurface(sur_copy);
-
- SDL_BlitSurface(sur_copy, NULL, surface, NULL);
- SDL_FreeSurface(sur_copy);
- }
-}
-
-SDL_Surface*
-sdl_surface_part_from_file(const std::string& file, int x, int y, int w, int h, bool use_alpha)
-{
- SDL_Rect src;
- SDL_Surface * sdl_surface;
- SDL_Surface * temp;
- SDL_Surface * conv;
-
- temp = IMG_Load(file.c_str());
-
- if (temp == NULL)
- Termination::abort("Can't load", file);
-
- /* Set source rectangle for conv: */
-
- src.x = x;
- src.y = y;
- src.w = w;
- src.h = h;
-
- conv = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, temp->format->BitsPerPixel,
- temp->format->Rmask,
- temp->format->Gmask,
- temp->format->Bmask,
- temp->format->Amask);
-
- SDL_SetAlpha(temp,0,0);
-
- SDL_BlitSurface(temp, &src, conv, NULL);
- if(use_alpha == false && !use_gl)
- sdl_surface = SDL_DisplayFormat(conv);
- else
- sdl_surface = SDL_DisplayFormatAlpha(conv);
-
- if (sdl_surface == NULL)
- Termination::abort("Can't covert to display format", file);
-
- if (use_alpha == false && !use_gl)
- SDL_SetAlpha(sdl_surface, 0, 0);
-
- SDL_FreeSurface(temp);
- SDL_FreeSurface(conv);
-
- return sdl_surface;
-}
-
-SDL_Surface*
-sdl_surface_from_file(const std::string& file, bool use_alpha)
-{
- SDL_Surface* sdl_surface;
- SDL_Surface* temp;
-
- temp = IMG_Load(file.c_str());
-
- if (temp == NULL)
- Termination::abort("Can't load", file);
-
- if(use_alpha == false && !use_gl)
- sdl_surface = SDL_DisplayFormat(temp);
- else
- sdl_surface = SDL_DisplayFormatAlpha(temp);
-
- if (sdl_surface == NULL)
- Termination::abort("Can't covert to display format", file);
-
- if (use_alpha == false && !use_gl)
- SDL_SetAlpha(sdl_surface, 0, 0);
-
- SDL_FreeSurface(temp);
-
- return sdl_surface;
-}
-
-SDL_Surface*
-SuperTux::sdl_surface_from_sdl_surface(SDL_Surface* sdl_surf, bool use_alpha)
-{
- SDL_Surface* sdl_surface;
-#if 0
- Uint32 saved_flags;
- Uint8 saved_alpha;
-
- /* Save the alpha blending attributes */
- saved_flags = sdl_surf->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
- saved_alpha = sdl_surf->format->alpha;
- if ( (saved_flags & SDL_SRCALPHA)
- == SDL_SRCALPHA )
- {
- SDL_SetAlpha(sdl_surf, 0, 0);
- }
-#endif
-
- if(use_alpha == false && !use_gl)
- sdl_surface = SDL_DisplayFormat(sdl_surf);
- else
- sdl_surface = SDL_DisplayFormatAlpha(sdl_surf);
-
-#if 0
- /* Restore the alpha blending attributes */
- if ( (saved_flags & SDL_SRCALPHA)
- == SDL_SRCALPHA )
- {
- SDL_SetAlpha(sdl_surface, saved_flags, saved_alpha);
- }
-#endif
-
- if (sdl_surface == NULL)
- Termination::abort("Can't covert to display format", "SURFACE");
-
- if (use_alpha == false && !use_gl)
- SDL_SetAlpha(sdl_surface, 0, 0);
-
- return sdl_surface;
-}
-
-SDL_Surface*
-sdl_surface_from_gradient(Color top, Color bottom, int w, int h)
-{
- SDL_Surface* sdl_surface
- = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h,
- screen->format->BitsPerPixel, screen->format->Rmask,
- screen->format->Gmask, screen->format->Bmask, 0);
-
- if(sdl_surface == 0)
- Termination::abort("Cannot create surface for the gradient", "SURFACE");
-
- if(top == bottom) {
- SDL_FillRect(sdl_surface, NULL, SDL_MapRGB(sdl_surface->format,
- top.red, top.green, top.blue));
- } else {
- float redstep = (float(bottom.red)-float(top.red)) / float(h);
- float greenstep = (float(bottom.green)-float(top.green)) / float(h);
- float bluestep = (float(bottom.blue) - float(top.blue)) / float(h);
-
- SDL_Rect rect;
- rect.x = 0;
- rect.w = w;
- rect.h = 1;
- for(float y = 0; y < h; y++) {
- rect.y = (int)y;
- SDL_FillRect(sdl_surface, &rect, SDL_MapRGB(sdl_surface->format,
- int(float(top.red) + redstep * y),
- int(float(top.green) + greenstep * y),
- int(float(top.blue) + bluestep * y)));
- }
- }
-
- return sdl_surface;
-}
-
-//---------------------------------------------------------------------------
-
-SurfaceImpl::SurfaceImpl()
-{}
-
-SurfaceImpl::~SurfaceImpl()
-{
- SDL_FreeSurface(sdl_surface);
-}
-
-SDL_Surface* SurfaceImpl::get_sdl_surface() const
-{
- return sdl_surface;
-}
-
-#ifndef NOOPENGL
-SurfaceOpenGL::SurfaceOpenGL(SDL_Surface* surf, bool use_alpha)
-{
- sdl_surface = sdl_surface_from_sdl_surface(surf, use_alpha);
- create_gl(sdl_surface,&gl_texture);
-
- w = sdl_surface->w;
- h = sdl_surface->h;
-}
-
-SurfaceOpenGL::SurfaceOpenGL(const std::string& file, bool use_alpha)
-{
- sdl_surface = sdl_surface_from_file(file, use_alpha);
- create_gl(sdl_surface,&gl_texture);
-
- w = sdl_surface->w;
- h = sdl_surface->h;
-}
-
-SurfaceOpenGL::SurfaceOpenGL(const std::string& file_, int x_, int y_,
- int w_, int h_, bool use_alpha_)
-{
- sdl_surface = sdl_surface_part_from_file(file_,x_,y_,w_,h_,use_alpha_);
-
- create_gl(sdl_surface, &gl_texture);
- w = sdl_surface->w;
- h = sdl_surface->h;
-}
-
-SurfaceOpenGL::SurfaceOpenGL(Color top_gradient, Color bottom_gradient,
- int _w, int _h)
-{
- sdl_surface = sdl_surface_from_gradient(top_gradient, bottom_gradient,_w,_h);
- create_gl(sdl_surface, &gl_texture);
- w = sdl_surface->w;
- h = sdl_surface->h;
-}
-
-SurfaceOpenGL::~SurfaceOpenGL()
-{
- glDeleteTextures(1, &gl_texture);
-}
-
-void
-SurfaceOpenGL::create_gl(SDL_Surface * surf, GLuint * tex)
-{
- Uint32 saved_flags;
- Uint8 saved_alpha;
- int w, h;
- SDL_Surface *conv;
-
- w = power_of_two(surf->w);
- h = power_of_two(surf->h),
-
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- conv = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, surf->format->BitsPerPixel,
- 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
-#else
- conv = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, surf->format->BitsPerPixel,
- 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
-#endif
-
- /* Save the alpha blending attributes */
- saved_flags = surf->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
- saved_alpha = surf->format->alpha;
- if ( (saved_flags & SDL_SRCALPHA)
- == SDL_SRCALPHA )
- {
- SDL_SetAlpha(surf, 0, 0);
- }
-
- SDL_BlitSurface(surf, 0, conv, 0);
-
- /* Restore the alpha blending attributes */
- if ( (saved_flags & SDL_SRCALPHA)
- == SDL_SRCALPHA )
- {
- SDL_SetAlpha(surf, saved_flags, saved_alpha);
- }
-
- // We check all the pixels of the surface to figure out which
- // internal format OpenGL should use for storing it, ie. if no alpha
- // is present store in RGB instead of RGBA, this saves a few bytes
- // of memory, but much more importantly it makes the game look
- // *much* better in 16bit color mode
- int internal_format = GL_RGB10_A2;
- bool has_alpha = false;
-
- unsigned char* buf = static_cast<unsigned char*>(conv->pixels);
- for (int y = 0; y < surf->h; ++y)
- for (int x = 0; x < surf->w; ++x)
- {
- if (buf[(conv->pitch*y + x*4) + 3] != 255)
- {
- has_alpha = true;
- break;
- }
- }
-
- if (!has_alpha)
- {
- internal_format = GL_RGB;
- }
-
- glGenTextures(1, &*tex);
- glBindTexture(GL_TEXTURE_2D , *tex);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, conv->pitch / conv->format->BytesPerPixel);
- glTexImage2D(GL_TEXTURE_2D, 0, internal_format, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, conv->pixels);
- glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
-
- SDL_FreeSurface(conv);
-}
-
-int
-SurfaceOpenGL::draw(float x, float y, Uint8 alpha, Uint32 effect)
-{
- float pw = power_of_two(w);
- float ph = power_of_two(h);
-
- if(effect & SEMI_TRANSPARENT)
- alpha = 128;
-
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- glColor4ub(alpha, alpha, alpha, alpha);
-
- glBindTexture(GL_TEXTURE_2D, gl_texture);
-
- glBegin(GL_QUADS);
-
- if(effect & VERTICAL_FLIP & HORIZONTAL_FLIP)
- {
- glTexCoord2f(0, 0);
- glVertex2f((float)w+x, (float)h+y);
-
- glTexCoord2f((float)w / pw, 0);
- glVertex2f(x, (float)h+y);
-
- glTexCoord2f((float)w / pw, (float)h / ph);
- glVertex2f(x, y);
-
- glTexCoord2f(0, (float)h / ph);
- glVertex2f((float)w+x, y);
- }
- else if(effect & VERTICAL_FLIP)
- {
- glTexCoord2f(0, 0);
- glVertex2f(x, (float)h+y);
-
- glTexCoord2f((float)w / pw, 0);
- glVertex2f((float)w+x, (float)h+y);
-
- glTexCoord2f((float)w / pw, (float)h / ph);
- glVertex2f((float)w+x, y);
-
- glTexCoord2f(0, (float)h / ph);
- glVertex2f(x, y);
- }
- else if(effect & HORIZONTAL_FLIP)
- {
- glTexCoord2f(0, 0);
- glVertex2f((float)w+x, y);
-
- glTexCoord2f((float)w / pw, 0);
- glVertex2f(x, y);
-
- glTexCoord2f((float)w / pw, (float)h / ph);
- glVertex2f(x, (float)h+y);
-
- glTexCoord2f(0, (float)h / ph);
- glVertex2f((float)w+x, (float)h+y);
- }
- else
- {
- glTexCoord2f(0, 0);
- glVertex2f(x, y);
-
- glTexCoord2f((float)w / pw, 0);
- glVertex2f((float)w+x, y);
-
- glTexCoord2f((float)w / pw, (float)h / ph);
- glVertex2f((float)w+x, (float)h+y);
-
- glTexCoord2f(0, (float)h / ph);
- glVertex2f(x, (float)h+y);
- }
- glEnd();
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
-
- return 0;
-}
-
-int
-SurfaceOpenGL::draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha, Uint32 effect)
-{
- float pw = power_of_two(int(this->w));
- float ph = power_of_two(int(this->h));
-
- if(effect & SEMI_TRANSPARENT)
- alpha = 128;
-
- glBindTexture(GL_TEXTURE_2D, gl_texture);
-
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- glColor4ub(alpha, alpha, alpha, alpha);
-
- glEnable(GL_TEXTURE_2D);
-
-
- glBegin(GL_QUADS);
-
- if(effect & VERTICAL_FLIP & HORIZONTAL_FLIP)
- {
- glTexCoord2f(sx / pw, (float)(sy+h) / ph);
- glVertex2f((float)w+x, (float)h+y);
-
- glTexCoord2f((sx+w) / pw, (sy+h) / ph);
- glVertex2f(x, (float)h+y);
-
- glTexCoord2f((float)(sx + w) / pw, sy / ph);
- glVertex2f(x, y);
-
- glTexCoord2f(sx / pw, sy / ph);
- glVertex2f((float)w+x, y);
- }
- else if(effect & VERTICAL_FLIP)
- {
- glTexCoord2f(sx / pw, sy / ph);
- glVertex2f(x, y);
-
- glTexCoord2f((float)(sx + w) / pw, sy / ph);
- glVertex2f(w+x, y);
-
- glTexCoord2f((sx+w) / pw, (sy+h) / ph);
- glVertex2f(w +x, h+y);
-
- glTexCoord2f(sx / pw, (float)(sy+h) / ph);
- glVertex2f(x, h+y);
- }
- else if(effect & HORIZONTAL_FLIP)
- {
- glTexCoord2f(sx / pw, sy / ph);
- glVertex2f((float)w+x, y);
-
- glTexCoord2f((float)(sx + w) / pw, sy / ph);
- glVertex2f(x, y);
-
- glTexCoord2f((sx+w) / pw, (sy+h) / ph);
- glVertex2f(x, (float)h+y);
-
- glTexCoord2f(sx / pw, (float)(sy+h) / ph);
- glVertex2f((float)w+x, (float)h+y);
- }
- else
- {
- glTexCoord2f(sx / pw, (float)(sy+h) / ph);
- glVertex2f(x, h+y);
-
- glTexCoord2f((sx+w) / pw, (sy+h) / ph);
- glVertex2f(w +x, h+y);
-
- glTexCoord2f((float)(sx + w) / pw, sy / ph);
- glVertex2f(w+x, y);
-
- glTexCoord2f(sx / pw, sy / ph);
- glVertex2f(x, y);
- }
-
- glEnd();
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
-
- return 0;
-}
-
-int
-SurfaceOpenGL::draw_stretched(float x, float y, int sw, int sh, Uint8 alpha, Uint32 effect)
-{
- float pw = power_of_two(sw);
- float ph = power_of_two(sh);
-
- if(effect & SEMI_TRANSPARENT)
- alpha = 128;
-
- glEnable(GL_TEXTURE_2D);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-
- glColor4ub(alpha, alpha, alpha, alpha);
-
- glBindTexture(GL_TEXTURE_2D, gl_texture);
-
- glBegin(GL_QUADS);
-
- if(effect & VERTICAL_FLIP & HORIZONTAL_FLIP)
- {
- glTexCoord2f(0, 0);
- glVertex2f((float)sw+x, (float)sh+y);
-
- glTexCoord2f((float)w / pw, 0);
- glVertex2f(x, (float)sh+y);
-
- glTexCoord2f((float)w / pw, (float)h / ph);
- glVertex2f(x, y);
-
- glTexCoord2f(0, (float)h / ph);
- glVertex2f((float)sw+x, y);
- }
- else if(effect & VERTICAL_FLIP)
- {
- glTexCoord2f(0, 0);
- glVertex2f(x, (float)sh+y);
-
- glTexCoord2f((float)w / pw, 0);
- glVertex2f((float)sw+x, (float)sh+y);
-
- glTexCoord2f((float)w / pw, (float)h / ph);
- glVertex2f((float)sw+x, y);
-
- glTexCoord2f(0, (float)h / ph);
- glVertex2f(x, y);
- }
- else if(effect & HORIZONTAL_FLIP)
- {
- glTexCoord2f(0, 0);
- glVertex2f((float)sw+x, y);
-
- glTexCoord2f((float)w / pw, 0);
- glVertex2f(x, y);
-
- glTexCoord2f((float)w / pw, (float)h / ph);
- glVertex2f(x, (float)sh+y);
-
- glTexCoord2f(0, (float)h / ph);
- glVertex2f((float)sw+x, (float)sh+y);
- }
- else
- {
- glTexCoord2f(0, 0);
- glVertex2f(x, y);
-
- glTexCoord2f((float)w / pw, 0);
- glVertex2f((float)sw+x, y);
-
- glTexCoord2f((float)w / pw, (float)h / ph);
- glVertex2f((float)sw+x, (float)sh+y);
-
- glTexCoord2f(0, (float)h / ph);
- glVertex2f(x, (float)sh+y);
- }
- glEnd();
-
- glDisable(GL_TEXTURE_2D);
- glDisable(GL_BLEND);
-
- return 0;
-}
-
-void
-SurfaceOpenGL::apply_filter(int filter, Color color)
-{
- ::apply_filter_to_surface(sdl_surface, filter, color);
- create_gl(sdl_surface,&gl_texture);
-
- w = sdl_surface->w;
- h = sdl_surface->h;
-}
-
-#endif
-
-SurfaceSDL::SurfaceSDL(SDL_Surface* surf, bool use_alpha)
-{
- sdl_surface = sdl_surface_from_sdl_surface(surf, use_alpha);
- w = sdl_surface->w;
- h = sdl_surface->h;
-}
-
-SurfaceSDL::SurfaceSDL(const std::string& file, bool use_alpha)
-{
- sdl_surface = sdl_surface_from_file(file, use_alpha);
- w = sdl_surface->w;
- h = sdl_surface->h;
-}
-
-SurfaceSDL::SurfaceSDL(const std::string& file, int x, int y, int _w, int _h,
- bool use_alpha)
-{
- sdl_surface = sdl_surface_part_from_file(file, x, y, _w, _h, use_alpha);
- w = sdl_surface->w;
- h = sdl_surface->h;
-}
-
-SurfaceSDL::SurfaceSDL(Color top_gradient, Color bottom_gradient,
- int _w, int _h)
-{
- sdl_surface = sdl_surface_from_gradient(top_gradient, bottom_gradient,_w,_h);
- w = sdl_surface->w;
- h = sdl_surface->h;
-}
-
-int
-SurfaceSDL::draw(float x, float y, Uint8 alpha, Uint32 effect)
-{
- SDL_Rect dest;
-
- dest.x = (int)x;
- dest.y = (int)y;
- dest.w = w;
- dest.h = h;
-
- if(effect & SEMI_TRANSPARENT)
- alpha = 128;
-
- if(effect & VERTICAL_FLIP & HORIZONTAL_FLIP)
- {
- // FIXME: this hack is damn slow. Just keep it cause it isn't that used.
- for(float sx = 0; sx < w; sx++)
- for(float sy = 0; sy < h; sy++)
- if(draw_part(sx, sy, x+(w-sx), y+(h-sy), 1, 1, alpha, NONE_EFFECT) == -2)
- return -2;
- return 0;
- }
- else if(effect & VERTICAL_FLIP) // FIXME: feel free to replace this hack
- {
- for(float sy = 0; sy < h; sy++)
- if(draw_part(0, sy, x, y+(h-sy), w, 1, alpha, NONE_EFFECT) == -2)
- return -2;
- return 0;
- }
- else if(effect & HORIZONTAL_FLIP) // FIXME: feel free to replace this hack
- {
- for(float sx = 0; sx < w; sx++)
- if(draw_part(sx, 0, x+(w-sx), y, 1, h, alpha, NONE_EFFECT) == -2)
- return -2;
- return 0;
- }
-
- if(alpha != 255)
- {
- /* Create a Surface, make it using colorkey, blit surface into temp, apply alpha
- to temp sur, blit the temp into the screen */
- /* Note: this has to be done, since SDL doesn't allow to set alpha to surfaces that
- already have an alpha mask yet... */
-
- SDL_Surface* sdl_surface_copy = SDL_CreateRGBSurface (sdl_surface->flags,
- sdl_surface->w, sdl_surface->h, sdl_surface->format->BitsPerPixel,
- sdl_surface->format->Rmask, sdl_surface->format->Gmask,
- sdl_surface->format->Bmask,
- 0);
- int colorkey = SDL_MapRGB(sdl_surface_copy->format, 255, 0, 255);
- SDL_FillRect(sdl_surface_copy, NULL, colorkey);
- SDL_SetColorKey(sdl_surface_copy, SDL_SRCCOLORKEY, colorkey);
-
-
- SDL_BlitSurface(sdl_surface, NULL, sdl_surface_copy, NULL);
- SDL_SetAlpha(sdl_surface_copy ,SDL_SRCALPHA,alpha);
-
- int ret = SDL_BlitSurface(sdl_surface_copy, NULL, screen, &dest);
-
- SDL_FreeSurface (sdl_surface_copy);
- return ret;
- }
-
- int ret = SDL_BlitSurface(sdl_surface, NULL, screen, &dest);
-
- return ret;
-}
-
-int
-SurfaceSDL::draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha, Uint32 effect)
-{
- SDL_Rect src, dest;
-
- src.x = (int)sx;
- src.y = (int)sy;
- src.w = (int)w;
- src.h = (int)h;
-
- dest.x = (int)x;
- dest.y = (int)y;
- dest.w = (int)w;
- dest.h = (int)h;
-
- if(effect & SEMI_TRANSPARENT)
- alpha = 128;
-
- if(effect & VERTICAL_FLIP & HORIZONTAL_FLIP)
- {
- // FIXME: this hack is damn slow. Just keep it cause it isn't that used.
- for(float sx_ = 0; sx_ < w; sx++)
- for(float sy_ = 0; sy_ < h; sy++)
- if(draw_part(sx_, sy_, sx+(w-sx_), sy+(h-sy_), 1, 1, alpha, NONE_EFFECT) == -2)
- return -2;
- return 0;
- }
- else if(effect & VERTICAL_FLIP) // FIXME: feel free to replace this hack
- {
- for(float sy_ = sy; sy_ < h; sy_++)
- if(draw_part(sx, sy_, x, y+(h-sy_), w, 1, alpha, NONE_EFFECT) == -2)
- return -2;
- return 0;
- }
- else if(effect & HORIZONTAL_FLIP) // FIXME: feel free to replace this hack
- {
- for(float sx_ = 0; sx_ < w; sx_++)
- if(draw_part(sx_, 0, sx+(w-sx_), sy, 1, h, alpha, NONE_EFFECT) == -2)
- return -2;
- return 0;
- }
-
- if(alpha != 255)
- {
- /* Create a Surface, make it using colorkey, blit surface into temp, apply alpha
- to temp sur, blit the temp into the screen */
- /* Note: this has to be done, since SDL doesn't allow to set alpha to surfaces that
- already have an alpha mask, yet... */
-
- SDL_Surface* sdl_surface_copy = SDL_CreateRGBSurface (sdl_surface->flags,
- (int)w, (int)h, sdl_surface->format->BitsPerPixel,
- sdl_surface->format->Rmask, sdl_surface->format->Gmask,
- sdl_surface->format->Bmask,
- 0);
- int colorkey = SDL_MapRGB(sdl_surface_copy->format, 255, 0, 255);
- SDL_FillRect(sdl_surface_copy, NULL, colorkey);
- SDL_SetColorKey(sdl_surface_copy, SDL_SRCCOLORKEY, colorkey);
-
-
- SDL_BlitSurface(sdl_surface, &src, sdl_surface_copy, NULL);
- SDL_SetAlpha(sdl_surface_copy ,SDL_SRCALPHA,alpha);
-
- int ret = SDL_BlitSurface(sdl_surface_copy, NULL, screen, &dest);
-
- SDL_FreeSurface (sdl_surface_copy);
- return ret;
- }
-
- int ret = SDL_BlitSurface(sdl_surface, &src, screen, &dest);
-
- return ret;
-}
-
-int
-SurfaceSDL::draw_stretched(float x, float y, int sw, int sh, Uint8 alpha, Uint32 effect)
-{
- SDL_Rect dest;
-
- dest.x = (int)x;
- dest.y = (int)y;
- dest.w = (int)sw;
- dest.h = (int)sh;
-
- if(effect & SEMI_TRANSPARENT)
- alpha = 128;
-
- SDL_Surface* sdl_surface_copy = SDL_CreateRGBSurface (sdl_surface->flags,
- sw, sh, sdl_surface->format->BitsPerPixel,
- sdl_surface->format->Rmask, sdl_surface->format->Gmask,
- sdl_surface->format->Bmask,
- 0);
-
- SDL_BlitSurface(sdl_surface, NULL, sdl_surface_copy, NULL);
- SDL_SoftStretch(sdl_surface_copy, NULL, sdl_surface_copy, &dest);
-
- if(alpha != 255)
- SDL_SetAlpha(sdl_surface_copy,SDL_SRCALPHA,alpha);
-
- int ret = SDL_BlitSurface(sdl_surface_copy,NULL,screen,&dest);
- SDL_FreeSurface(sdl_surface_copy);
-
- return ret;
-}
-
-void
-SurfaceSDL::apply_filter(int filter, Color color)
-{
- ::apply_filter_to_surface(sdl_surface, filter, color);
-
- w = sdl_surface->w;
- h = sdl_surface->h;
-}
-
-SurfaceSDL::~SurfaceSDL()
-{}
-
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-//
-// 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_TEXTURE_H
-#define SUPERTUX_TEXTURE_H
-
-#include <string>
-#include <list>
-
-#ifndef NOOPENGL
-#include <SDL_opengl.h>
-#endif
-
-#include "SDL.h"
-
-#include "math/vector.h"
-#include "video/screen.h"
-
-namespace SuperTux
- {
-
- void apply_filter_to_surface(SDL_Surface *surface, int filter, int value);
- SDL_Surface* sdl_surface_from_sdl_surface(SDL_Surface* sdl_surf, bool use_alpha);
- SDL_Surface* sdl_surface_from_nothing();
-
- class SurfaceImpl;
- class SurfaceSDL;
- class SurfaceOpenGL;
- class DrawingContext;
-
- /// bitset for drawing effects
- enum {
- /** Don't apply anything */
- NONE_EFFECT = 0x0000,
- /** Draw the Surface upside down */
- VERTICAL_FLIP = 0x0001,
- /** Draw the Surface from left to down */
- HORIZONTAL_FLIP = 0x0002,
- /** Draw the Surface with alpha equal to 128 */
- SEMI_TRANSPARENT = 0x0004
- };
-
- /// types of filters
- enum {
- HORIZONTAL_FLIP_FILTER,
- MASK_FILTER,
- NONE_FILTER
- };
-
- /** This class holds all the data necessary to construct a surface */
- class SurfaceData
- {
- public:
- enum ConstructorType { LOAD, LOAD_PART, SURFACE, GRADIENT };
- ConstructorType type;
- SDL_Surface* surface;
- std::string file;
-
- struct Filter { int type; Color color; };
- std::vector<Filter> applied_filters;
-
- bool use_alpha;
- int x;
- int y;
- int w;
- int h;
- Color top_gradient;
- Color bottom_gradient;
-
- SurfaceData(SDL_Surface* surf, bool use_alpha_);
- SurfaceData(const std::string& file_, bool use_alpha_);
- SurfaceData(const std::string& file_, int x_, int y_, int w_, int h_, bool use_alpha_);
- SurfaceData(Color top_gradient_, Color bottom_gradient_, int w_, int h_);
- ~SurfaceData();
-
- SurfaceSDL* create_SurfaceSDL();
- SurfaceOpenGL* create_SurfaceOpenGL();
- SurfaceImpl* create();
- };
-
-
- /// Surface
- /** Container class that holds a surface, necessary so that we can
- switch Surface implementations (OpenGL, SDL) on the fly */
- class Surface
- {
- public:
- SurfaceData data;
- SurfaceImpl* impl;
- int w;
- int h;
-
- typedef std::list<Surface*> Surfaces;
- static Surfaces surfaces;
- public:
- static void reload_all();
- static void debug_check();
-
- Surface(SDL_Surface* surf, bool use_alpha);
- Surface(const std::string& file, bool use_alpha);
- Surface(const std::string& file, int x, int y, int w, int h, bool use_alpha);
- Surface(Color top_gradient, Color bottom_gradient, int w_, int h_);
- ~Surface();
-
- /** Reload the surface, which is necesarry in case of a mode swich */
- void reload();
-
- void apply_filter(int filter, Color color = Color(0,0,0));
- };
-
- /** Surface implementation, all implementation have to inherit from
- this class */
- class SurfaceImpl
- {
- protected:
- SDL_Surface* sdl_surface;
-
- public:
- int w;
- int h;
-
- public:
- SurfaceImpl();
- virtual ~SurfaceImpl();
-
- /** Return 0 on success, -2 if surface needs to be reloaded */
- virtual int draw(float x, float y, Uint8 alpha, Uint32 effect = NONE_EFFECT) = 0;
- virtual int draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha, Uint32 effect = NONE_EFFECT) = 0;
- virtual int draw_stretched(float x, float y, int w, int h, Uint8 alpha, Uint32 effect = NONE_EFFECT) = 0;
-
-
- SDL_Surface* get_sdl_surface() const; // @evil@ try to avoid this function
-
- virtual void apply_filter(int filter, Color color = Color(0,0,0)) = 0;
- };
-
- class SurfaceSDL : public SurfaceImpl
- {
- public:
- SurfaceSDL(SDL_Surface* surf, bool use_alpha);
- SurfaceSDL(const std::string& file, bool use_alpha);
- SurfaceSDL(const std::string& file, int x, int y, int w_, int h_, bool use_alpha);
- SurfaceSDL(Color top_gradient, Color bottom_gradient, int w, int h);
- virtual ~SurfaceSDL();
-
- int draw(float x, float y, Uint8 alpha, Uint32 effect = NONE_EFFECT);
- int draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha, Uint32 effect = NONE_EFFECT);
- int draw_stretched(float x, float y, int w, int h, Uint8 alpha, Uint32 effect = NONE_EFFECT);
-
- void apply_filter(int filter, Color color);
- };
-
-#ifndef NOOPENGL
- class SurfaceOpenGL : public SurfaceImpl
- {
- public:
- GLuint gl_texture;
-
- public:
- SurfaceOpenGL(SDL_Surface* surf, bool use_alpha);
- SurfaceOpenGL(const std::string& file, bool use_alpha);
- SurfaceOpenGL(const std::string& file, int x, int y, int w, int h, bool use_alpha);
- SurfaceOpenGL(Color top_gradient, Color bottom_gradient, int w, int h);
-
- virtual ~SurfaceOpenGL();
-
- int draw(float x, float y, Uint8 alpha, Uint32 effect = NONE_EFFECT);
- int draw_part(float sx, float sy, float x, float y, float w, float h, Uint8 alpha, Uint32 effect = NONE_EFFECT);
- int draw_stretched(float x, float y, int w, int h, Uint8 alpha, Uint32 effect = NONE_EFFECT);
-
- void apply_filter(int filter, Color color);
-
- private:
- void create_gl(SDL_Surface * surf, GLuint * tex);
- };
-#endif
-
-} //namespace SuperTux
-
-#endif /*SUPERTUX_TEXTURE_H*/
-
-/* Local Variables: */
-/* mode: c++ */
-/* End: */
CheckOptions noinstall console independent : $(3) : $(<) ;
local target = [ ConstructApplicationTarget $(<) : $(3) ] ;
- local sources = [ DoSourceGrist $(>) ] ;
+ local sources = [ SearchSource $(>) ] ;
local objects = [ CompileObjects $(sources) ] ;
$(<)_TYPE = application ;
SystemLinkApplication $(<) : $(objects) : $(3) ;
# Import default flags
- CppFlags $(<) : $(CPPFLAGS) $(APPLICTION_CPPFLAGS) ;
- CFlags $(<) : $(CFLAGS) $(APPLICATION_CFLAGS) ;
- C++Flags $(<) : $(C++FLAGS) $(APPLICATION_C++FLAGS) ;
- LFlags $(<) : $(LFLAGS) $(APPLICATION_LFLAGS) ;
+ CppFlags $(<) : $(APPLICTION_CPPFLAGS) ;
+ CFlags $(<) : $(APPLICATION_CFLAGS) ;
+ C++Flags $(<) : $(APPLICATION_CXXFLAGS) ;
+ LFlags $(<) : $(APPLICATION_LIBS) ;
# Sources are part of the package
if ! [ IsElem nopackage : $(3) ]
{
Package $(sources) ;
}
+
+ return $(target) ;
}
#----------------------------------------------------------------------------
--- /dev/null
+#============================================================================
+# Rules for flex and bison
+#============================================================================
+
+if $(LEX)
+{
+ rule LexRule
+ {
+ local cfile = [ LocateTarget $(<:S=.c) ] ;
+ local object = [ CompileObjects $(cfile) ] ;
+
+ Lex $(cfile) : $(<) ;
+
+ return $(object) ;
+ }
+ RegisterFileType LexRule : .l ;
+
+ rule Lex++Rule
+ {
+ local cppfile = [ LocateTarget $(<:S=.cpp) ] ;
+ local object = [ CompileObjects $(cppfile) ] ;
+
+ Lex $(cppfile) : $(<) ;
+
+ return $(object) ;
+ }
+ RegisterFileType Flex++Rule : .ll ;
+
+ if $(COMPILER_TYPE) != "GCC"
+ {
+ # compilers like msvc don't like #line statements.
+ LEX_FLAGS += -L ;
+ }
+
+ rule Lex
+ {
+ Depends $(<) : $(>) ;
+ LEX_FLAGS on $(cfile) += $(LEX_FLAGS) ;
+ Clean clean : $(cfile) ;
+ }
+
+ # Use -t and output redirection to avoid flex choosing stupid names for it's
+ # output files.
+ actions Lex
+ {
+ $(LEX) -t $(LEX_FLAGS) $(>) > $(<)
+ }
+}
+
+if $(BISON)
+{
+ rule BisonRule
+ {
+ local cfile = [ LocateTarget $(<:S=.c) ] ;
+ local headerfile = [ LocateTarget $(<:S=.h) ] ;
+ local object = [ CompileObjects $(cfile) ] ;
+
+ Includes $(headerfile:G=) : $(headerfile) ;
+
+ Bison $(cfile) $(headerfile) : $(<) ;
+ # work around jam warning about independent target
+ Includes $(cfile) : $(headerfile) ;
+
+ return $(object) ;
+ }
+ RegisterFileType BisonRule : .y ;
+
+ rule Bison++Rule
+ {
+ local cppfile = [ LocateTarget $(<:S=.cpp) ] ;
+ local headerfile = [ LocateTarget $(<:S=.hpp) ] ;
+ headerfile = $(headerfile:G=) ;
+ local object = [ CompileObjects $(cppfile) ] ;
+
+ # jams header file scannning doesn't use grist so we have to workaround this
+ # here
+ Includes $(headerfile:G=) : $(headerfile) ;
+
+ Bison $(cppfile) $(headerfile) : $(<) ;
+ Includes $(cppfile) : $(headerfile) ;
+
+ return $(object) ;
+ }
+ RegisterFileType Bison++Rule : .yy ;
+
+ rule Bison
+ {
+ Depends $(<) : $(>) ;
+ BISON_FLAGS on $(<) += $(BISON_FLAGS) ;
+ Clean clean : $(<) ;
+ }
+ rule BisonFlags
+ {
+ local target ;
+
+ if $(<:S) = .yy
+ {
+ target = [ LocateTarget $(<:S=.cpp) $(<:S=.hpp) ] ;
+ }
+ else
+ {
+ target = [ LocateTarget $(<:S=.c) $(<:S=.h) ] ;
+ }
+ BISON_FLAGS on $(target) += $(>) ;
+ }
+
+ if $(COMPILER_TYPE) != "GCC"
+ {
+ # compilers like msvc don't like #line statements.
+ BISON_FLAGS += --no-lines ;
+ }
+ actions Bison
+ {
+ $(BISON) -d $(BISON_FLAGS) -o $(<[1]) $(>)
+ }
+}
+
include $(jamrulesdir)/objects.jam ;
include $(jamrulesdir)/compiler.jam ;
+include $(jamrulesdir)/bisonflex.jam ;
include $(jamrulesdir)/autoconf.jam ;
# Rules for C and C++ files
#============================================================================
-# convert autoconf style variablenames to jam style ones
-CCFLAGS += $(CFLAGS) ;
-C++FLAGS += $(CXXFLAGS) ;
-LFLAGS += $(LIBS) ;
-
if $(CC)
{
if [ IsElem shared : $(2) ]
{
- object = [ DoObjectGrist $(<:S=.lo) ] ;
+ object = [ LocateTarget $(<:S=.lo) ] ;
CC on $(object) = "$(LIBTOOL) --mode=compile $(CC)" ;
} else {
- object = [ DoObjectGrist $(<:S=.o) ] ;
+ object = [ LocateTarget $(<:S=.o) ] ;
}
+ CFLAGS on $(object) = $(CFLAGS) ;
+ CPPFLAGS on $(object) = $(CPPFLAGS) ;
Cc $(object) : $(<) ;
+ Depends $(object) : $(<) ;
return $(object) ;
}
RegisterFileType CcRule : .c ;
RegisterHeaderRule HeaderRule : $(HDRPATTERN) : .c ;
-rule Cc
-{
- Depends $(<) : $(>) ;
-}
-
actions Cc
{
$(CC) -c -o $(<) $(CPPFLAGS) $(CFLAGS) $(>)
local object ;
if [ IsElem shared : $(2) ] {
- object = [ DoObjectGrist $(<:S=.lo) ] ;
+ object = [ LocateTarget $(<:S=.lo) ] ;
CXX on $(object) = "$(LIBTOOL) --mode=compile $(CXX)" ;
} else {
- object = [ DoObjectGrist $(<:S=.o) ] ;
+ object = [ LocateTarget $(<:S=.o) ] ;
}
+ CXXFLAGS on $(object) = $(CXXFLAGS) ;
+ CPPFLAGS on $(object) = $(CPPFLAGS) ;
C++ $(object) : $(<) ;
+ Depends $(object) : $(<) ;
return $(object) ;
}
RegisterFileType C++Rule : .cpp .cc .c++ ; # we can't register .C here because
# of windows being case-insensitive.
RegisterHeaderRule HeaderRule : $(HDRPATTERN) : .cpp .cc .c++ ;
-rule C++
-{
- Depends $(<) : $(>) ;
-}
-
actions C++
{
- $(CXX) -c -o $(<) $(CPPFLAGS) $(C++FLAGS) $(>)
+ $(CXX) -c -o $(<) $(CPPFLAGS) $(CXXFLAGS) $(>)
}
} # end if $(CXX)
# inherit the exported flags
CppFlags $(<) : $($(i)_CPPFLAGS) : $(3) ;
CFlags $(<) : $($(i)_CFLAGS) : $(3) ;
- C++Flags $(<) : $($(i)_C++FLAGS) : $(3) ;
- LFlags $(<) : $($(i)_LFLAGS) : $(3) ;
+ C++Flags $(<) : $($(i)_CXXFLAGS) : $(3) ;
+ LFlags $(<) : $($(i)_LIBS) : $(3) ;
}
} else {
echo "WARNING: Trying to link" $(i)
rule C++Flags
{
- C++FLAGS on $($(<)_OBJECTS) += $(>) ;
+ CXXFLAGS on $($(<)_OBJECTS) += $(>) ;
if [ IsElem export : $(3) ] {
- $(<)_C++FLAGS = $(>) ;
+ $(<)_CXXFLAGS = $(>) ;
}
}
## Sets linker flags for a library, plugin or application target
rule LFlags
{
- LFLAGS on $($(<)_TARGET) += $(>) ;
+ LIBS on $($(<)_TARGET) += $(>) ;
if [ IsElem export : $(3) ] {
- $(<)_LFLAGS = $(>) ;
+ $(<)_LIBS = $(>) ;
}
}
actions Install1
{
- $(INSTALL) "$(>)" "$(<:D)" $(INSTALLFLAGS) ;
+ $(INSTALL) "$(>)" "$(<:D)" $(INSTALLIBS) ;
}
actions CopyDirs
# boostjam is evil: It is compatible to jam 2.4 but has a version number 3.1, we# try to detect boostjam with the ARGV extension
if $(ARGV[0])
{
-# boostjam hacks
- JAMVERSION = 2.4 ;
- rule FIncludes
- {
- return -I$(<) ;
- }
- rule FDefines
- {
- return -D$(<) ;
- }
+ EXIT "Error: You can't use boostjam for this build." ;
}
# we can't use boostjam at the moment as it still has the bug from jam 2.4 where
{
EXIT "Error: This buildsystem requires jam version 2.5 or later." ;
}
-# don't confuse users for now...
-#if $(JAMVERSION) = 2.4 & $(JAM_DEBUG)
-#{
-# echo "Warning: It is recommended to use jam2.5rc3 or later." ;
-#}
# All scripts invoked by the build system expect a Bourne or compatible shell.
# Reject C-shell and its variants (such as tcsh). Unfortunately, this is a bit
SHELL = "/bin/sh" ;
}
-# jam 2.4s SubDir rule had some problems and misses the usefull SUBDIRRULES
-# extension. So we override it here with a better version (from jam 2.5rc3)
-if $(JAMVERSION) = 2.4
-{
-
-rule SubDir
-{
- #
- # SubDir TOP d1 d2 ... ;
- #
- # Support for a project tree spanning multiple directories.
- #
- # SubDir declares a Jamfile's location in a project tree, setting
- # Jambase variables (SEARCH_SOURCE, LOCATE_TARGET) so that source
- # files can be found.
- #
- # TOP is a user-select variable name for root of the tree, and
- # d1 d2 ... are the directory elements that lead from the root
- # of the tree to the directory of the Jamfile.
- #
- # TOP can be set externally, but normally the first SubDir call
- # computes TOP as the path up from the current directory; the
- # path contains one ../ for each of d1 d2 ...
- #
- # SubDir reads once the project-specific rules file Jamrules
- # in the TOP directory, if present. This can be overridden
- # with the variable TOPRULES.
- #
- # SubDir supports multiple, overlaid project trees: SubDir
- # invocations with different TOPs can appear in the same Jamfile.
- # The location established by the first SubDir call is used set
- # the TOPs for the subsequent SubDir calls.
- #
- # SubDir's public variables:
- #
- # $(TOP) = path from CWD to root.
- # $(SUBDIR) = path from CWD to the directory SubDir names.
- # $(SUBDIR_TOKENS) = path from $(TOP) to $(SUBDIR) as dir names
- # $(SEARCH_SOURCE) = $(SUBDIR)
- # $(LOCATE_SOURCE) = $(ALL_LOCATE_TARGET) $(SUBDIR)
- # $(LOCATE_TARGET) = $(ALL_LOCATE_TARGET) $(SUBDIR)
- # $(SOURCE_GRIST) = $(SUBDIR_TOKENS) with !'s
- #
-
- local _top = $(<[1]) ;
- local _tokens = $(<[2-]) ;
-
- #
- # First time through sets up relative root and includes Jamrules.
- #
-
- if ! $(_top)
- {
- Exit SubDir syntax error ;
- }
-
- if ! $($(_top)-SET)
- {
- $(_top)-SET = true ;
-
- # First time we've seen this TOP.
- # We'll initialize a number of internal variables:
- #
- # $(TOP-UP) = directories from ROOT to a common point
- # $(TOP-DOWN) = directories from common point to TOP
- # $(TOP-ROOT) = root directory for UP/DOWN -- normally CWD
- # $(SUBDIR_UP) = current value of $(TOP-UP)
- # $(SUBDIR_DOWN) = current value of $(TOP-DOWN)
- # $(SUBDIR_ROOT) = current value of $(TOP-ROOT)
- #
-
- if $($(_top))
- {
- # TOP externally set.
- # We'll ignore the relative (UP/DOWN) path that
- # got us here, and instead remember the hard ROOT.
-
- $(_top)-UP = ;
- $(_top)-DOWN = ;
- $(_top)-ROOT = $($(_top)) ;
- }
- else
- {
- # TOP not preset.
-
- # Establishing a new TOP. In the simplest case,
- # (SUBDIR_UP/SUBDIR_DOWN/SUBDIR_ROOT unset), it's
- # merely a certain number of directories down from
- # the current directory, and FSubDirPath will set
- # TOP to a path consisting of ../ for each of the
- # elements of _tokens, because that represents how
- # far below TOP the current directory sits.
- #
- # In the more complicated case, the starting directory
- # isn't the directory of jam's invocation but an
- # location established by previous SubDir call. The
- # starting directory is SUBDIR_UP directories up from
- # SUBDIR_ROOT, and then SUBDIR_DOWN directories down
- # from that. If SUBDIR_ROOT is not set, that means
- # SUBDIR_DOWN and SUBDIR_UP represent the path from
- # the directory of jam's invocation.
- #
- # In the most complicated case, the _tokens also
- # represents directories down, because TOP is being
- # estalished in a directory other than TOP's root.
- # Hopefully, _tokens and SUBDIR_DOWN represent the
- # same final directory, relative to the new TOP and
- # the previous SubDIr's TOP. To find the new TOP,
- # we have to chop off any common directories from
- # then ends of _tokens and SUBDIR_DOWN. To do so,
- # we reverse each of them, call FStripCommon to
- # remove the initial common elements, and then
- # reverse them again. After this process, if
- # both _tokens and SUBDIR_DOWN have elements, it
- # means the directory names estalished by the two
- # SubDir calls don't match, and a warning is issued.
- # All hell will likely break loose at this point,
- # since the whole SubDir scheme relies on the SubDir
- # calls accurately naming the current directory.
-
- # Strip common trailing elements of _tokens and SUBDIR_DOWN.
-
- _tokens = [ FReverse $(_tokens) ] ;
- SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ;
- FStripCommon _tokens : SUBDIR_DOWN ;
- SUBDIR_DOWN = [ FReverse $(SUBDIR_DOWN) ] ;
- _tokens = [ FReverse $(_tokens) ] ;
-
- if $(SUBDIR_DOWN) && $(_tokens)
- {
- Echo Warning: SubDir $(<) misplaced! ;
- }
-
- # We'll remember the relative (UP/DOWN) path that
- # got us here, plus any hard ROOT starting point
- # for the UP/DOWN. If TOP is never set externally,
- # ROOT will always be "" (directory of jam's invocation).
-
- $(_top)-UP = $(SUBDIR_UP) $(_tokens) ;
- $(_top)-DOWN = $(SUBDIR_DOWN) ;
- $(_top)-ROOT = $(SUBDIR_ROOT:E="") ;
- $(_top) = [ FSubDirPath $(_top) ] ;
- }
-
- # Set subdir vars for the inclusion of the Jamrules,
- # just in case they have SubDir rules of their own.
- # Note that SUBDIR_DOWN is empty: it's all the way
- # up where the Jamrules live. These gets overrided
- # just after the inclusion.
-
- SUBDIR_UP = $($(_top)-UP) ;
- SUBDIR_DOWN = ;
- SUBDIR_ROOT = $($(_top)-ROOT) ;
-
- # Include $(TOPRULES) or $(TOP)/Jamrules.
- # Include $(TOPRULES) if set.
- # Otherwise include $(TOP)/Jamrules if present.
-
- if $($(_top)RULES) {
- include $($(_top)RULES) ;
- } else {
- NoCare $(JAMRULES:R=$($(_top)):G=$(_top)) ;
- include $(JAMRULES:R=$($(_top)):G=$(_top)) ;
- }
- }
-
- # Get path from $(TOP) to named directory.
- # Save dir tokens for other potential uses.
-
- SUBDIR_UP = $($(_top)-UP) ;
- SUBDIR_DOWN = $($(_top)-DOWN) $(_tokens) ;
- SUBDIR_ROOT = $($(_top)-ROOT) ;
- SUBDIR_TOKENS = $(SUBDIR_DOWN) ;
-
- SUBDIR = [ FSubDirPath $(<) ] ;
-
- # Now set up SEARCH_SOURCE, LOCATE_TARGET, SOURCE_GRIST
- # These can be reset if needed. For example, if the source
- # directory should not hold object files, LOCATE_TARGET can
- # subsequently be redefined.
-
- SEARCH_SOURCE = $(SUBDIR) ;
- LOCATE_SOURCE = $(ALL_LOCATE_TARGET) $(SUBDIR) ;
- LOCATE_TARGET = $(ALL_LOCATE_TARGET) $(SUBDIR) ;
- SOURCE_GRIST = [ FGrist $(SUBDIR_TOKENS) ] ;
-
- # Reset per-directory ccflags, hdrs, etc,
- # listed in SUBDIRRESET.
- # Note use of variable expanded assignment var
-
- SUBDIR$(SUBDIRRESET) = ;
-
- # Invoke user-specific SubDir extensions,
- # rule names listed in SUBDIRRULES.
- # Note use of variable expanded rule invocation
-
- $(SUBDIRRULES) $(<) ;
-}
-
-rule FSubDirPath
-{
- # FSubDirPath TOP d1 ... ;
-
- # Returns path to named directory.
-
- # If jam is invoked in a subdirectory of the TOP, then we
- # need to prepend a ../ for every level we must climb up
- # (TOP-UP), and then append the directory names we must
- # climb down (TOP-DOWN), plus the named directories d1 ...
- # If TOP was set externally, or computed from another TOP
- # that was, we'll have to reroot the whole thing at TOP-ROOT.
-
- local _r = [ FRelPath $($(<[1])-UP) : $($(<[1])-DOWN) $(<[2-]) ] ;
-
- return $(_r:R=$($(<[1])-ROOT)) ;
-}
-
-rule SubInclude
-{
- # SubInclude TOP d1 ... ;
- #
- # Include a subdirectory's Jamfile.
-
- # We use SubDir to get there, in case the included Jamfile
- # either doesn't have its own SubDir (naughty) or is a subtree
- # with its own TOP.
-
- if ! $($(<[1]))
- {
- Exit SubInclude $(<[1]) without prior SubDir $(<[1]) ;
- }
-
- SubDir $(<) ;
-
- include $(JAMFILE:D=$(SUBDIR)) ;
-}
-
-rule SubRules
-{
- # SubRules TOP d1 ... : Other-TOP ;
- #
- # Read another tree's Jamrules, by giving it's path according
- # to this tree and it's own name.
-
- if ! $($(<[1]))
- {
- Exit SubRules $(<[1]) without prior SubDir $(<[1]) ;
- }
-
- SubDir $(<) ;
- SubDir $(>) ;
-}
-
-## Now we try to fix up the already messed settings
-## XXX We can only hope that jam2.4 users don't try starting jam from
-## subdirectories
-TOP-SET = true ;
-TOP-UP = ;
-TOP-DOWN = ;
-TOP-ROOT = $(TOP) ;
-SUBDIR_UP = $(TOP-UP) ;
-SUBDIR_DOWN = ;
-SUBDIR_ROOT = $(TOP-ROOT) ;
-
-#SubDir TOP ;
-
-} # end if $(JAMVERSION) = 2.4
-
-# MakeLocate rule from jam 2.4 isn't optimal. Use improved version from jam
-# 2.5
-if $(JAMVERSION) = 2.4
-{
-
-rule MakeLocate
-{
- # MakeLocate targets : directory ;
-
- # Sets special variable LOCATE on targets, and arranges
- # with MkDir to create target directory.
-
- # Note we grist the directory name with 'dir',
- # so that directory path components and other
- # targets don't conflict.
-
- if $(>)
- {
- LOCATE on $(<) = $(>) ;
- Depends $(<) : $(>[1]:G=dir) ;
- MkDir $(>[1]:G=dir) ;
- }
-}
-
-}
-
local no_scan_archive = $(NOARSCAN) ;
local target = [ ConstructLibraryTarget $(<) : $(3) ] ;
- local sources = [ DoSourceGrist $(>) ] ;
+ local sources = [ SearchSource $(>) ] ;
local objects = [ CompileObjects $(sources) : $(3) ] ;
local install_targets ;
}
# Import default flags
- CppFlags $(<) : $(CPPFLAGS) $(LIBRARY_CPPFLAGS) ;
- CFlags $(<) : $(CFLAGS) $(LIBRARY_CFLAGS) ;
- C++Flags $(<) : $(C++FLAGS) $(LIBRARY_C++FLAGS) ;
- LFlags $(<) : $(LFLAGS) $(LIBRARY_LFLAGS) ;
+ CppFlags $(<) : $(LIBRARY_CPPFLAGS) ;
+ CFlags $(<) : $(LIBRARY_CFLAGS) ;
+ C++Flags $(<) : $(LIBRARY_CXXFLAGS) ;
+ LFlags $(<) : $(LIBRARY_LIBS) ;
# Sources are part of the package
if ! [ IsElem nopackage : $(3) ]
{
Package $(sources) ;
}
+
+ return $(target) ;
}
## LibraryVersion
## major:minor:patchlevel
rule LibraryVersion
{
- LFLAGS on $($(<)_TARGET) = -version-info $(>) ;
+ LIBS on $($(<)_TARGET) = -version-info $(>) ;
}
#----------------------------------------------------------------------------
actions LinkLibrary bind NEEDLIBS bind EXTRAOBJECTS
{
- $(LINK) -o $(<) $(>) $(EXTRAOBJECTS) $(NEEDLIBS) $(LFLAGS)
+ $(LINK) -o $(<) $(>) $(EXTRAOBJECTS) $(NEEDLIBS) $(LIBS)
}
# Construct pseudo target libs which is used instead of the pseudo target lib
Depends $(target) : $(>) ;
LinkApplication $(target) : $(>) ;
+ LIBS on $(target) = $(LIBS) ;
Clean clean : $(target) ;
Clean $(<)clean : $(target) ;
}
actions LinkApplication bind NEEDLIBS bind EXTRAOBJECTS
{
$(MACOSX.ENVIRON)
- $(LINK) -o $(<) $(>) $(EXTRAOBJECTS) $(NEEDLIBS) $(LFLAGS)
+ $(LINK) -o $(<) $(>) $(EXTRAOBJECTS) $(NEEDLIBS) $(LIBS)
}
## RegisterFileType Rulename : extensions
## Register a rule which is used to compile a filetype into object
## files. The registered rule is called with the name of the
-## sourcefile as argument and should return a list of objectfiles which are
-## created. You should set the grist of the object files by using the
-## DoObjectGrist function.
+## sourcefile as argument (completely gristed and SEARCH is set already).
+## The rule should return the object files created completely gristed and
+## with LOCATE set (use the LocateTarget rule to do this).
rule RegisterFileType
{
local suffix ;
}
## CompileObjects sources [ : options ]
-## Compile a set of sourcefiles into objectfiles (extension: SUFOBJ,
-## usually .o). This rule takes care of setting LOCATE and SEARCH
-## variables to the $(SEARCH_SOURCE) and $(LOCATE_SOURCE) variables.
-## The Application, Plugin and Library rules already use this rule
-## internally. You should only use this rule if you have to avoid the
-## Application, Plugin or Library rules.
+## Compile a set of sourcefiles into objectfiles (usually .o extension).
+## For ungristed sourcefiles $(SEARCH) will be set to $(SEARCH_SOURCE).
+## The function returns the names of the targets being built (gristed and
+## with LOCATE set.
+## Normally you don't have to use this rule. The Application or Library rules
+## are taking care of calling it for you.
rule CompileObjects
{
- local source ;
+ local s ;
+ local sources = [ SearchSource $(<) ] ;
local targets ;
- # Search the source
- SEARCH on $(<) = $(SEARCH_SOURCE) ;
-
- for source in $(<)
+ for s in $(sources)
{
# compile the sourcefile to targetfile
- targets += [ CompileObject $(source) : $(2) ] ;
+ targets += [ CompileObject $(s) : $(2) ] ;
}
-
- # locate the targets
- MakeLocate $(targets) : $(LOCATE_TARGET) ;
return $(targets) ;
}
# private part
# CompileObject sourcefile [ : options ]
-# helper rule: Compiles a source file to an object file. Does header file
-# scanning, sets LOCATE and SEARCH for source and target, grists the files
-# with the current subdir and searches for the correct registered rule.
+# helper rule: Compiles a source file to an object file. The source should be
+# correctly gristed and SEARCH should be set. The function will return the
+# target names gristed and with LOCATE set.
rule CompileObject
{
# handle #includes for source: Jam scans for headers with
local targets ;
# Invoke filetype specific rule
- if $(FILETYPE_$(<:S))
- {
+ if $(FILETYPE_$(<:S)) {
targets = [ $(FILETYPE_$(<:S)) $(<) : $(2) ] ;
- }
- else
- {
- echo "Warning: no rules for filetype $(>:S) defined (at file $(>))." ;
+ } else {
+ echo "Warning: no rules for filetype $(<:S) defined (at file $(<))." ;
}
- if $(targets)
- {
+ if $(targets) {
# construct clean target
Clean clean : $(targets) ;
}
}
}
-if $(JAMVERSION) < 2.5
-{
-## XXX XXX XXX a bug in jam 2.4 let's the version above fail. I'll let this
-## non-optimal version in here until jam 2.5 is out.
-
-rule HeaderRule
-{
- local s = $(>:G=$(HDRGRIST)) ;
-
- Includes $(<) : $(s) ;
- SEARCH on $(s) = $(HDRSEARCH) ;
- NoCare $(s) ;
-
- local i ;
- for i in $(s)
- {
- if $(HDRRULE_$(i:S))
- {
- HDRGRIST on $(s) = $(HDRGRIST) ;
- HDRSEARCH on $(s) = $(HDRSEARCH) ;
- HDRRULE on $(s) = $(HDRRULE_$(i:S)) ;
- HDRSCAN on $(s) = $(HDRPATTERN_$(i:S)) ;
- }
- else if $(JAM_DEBUG)
- {
- #echo "No Header rule for $(i:S) file $(i) " ;
- }
- }
-}
-
-} # end of if $(JAMVERSION) < 1.5
-
# Dummy rule: .o files are used as is.
rule UseObjectFile
{
RegisterFileType UseHeaderFile : .h .hpp ;
RegisterHeaderRule HeaderRule : $(HDRPATTERN) : .h .hpp .inc ;
-# Generates a grist suitable for output objects based on
-# SUBVARIANT and SUBDIR variable.
-rule DoObjectGrist
+## SearchSource
+## Sets search path of the sourcefiles to the current SUBDIR and sets a
+## suitable grist on the sources. Ignores source files that already have
+## grist set.
+rule SearchSource
{
- return $(<:G=$(SOURCE_GRIST:E)!$(SUBVARIANT)) ;
+ local sources ;
+
+ for f in $(<) {
+ if $(f:G) {
+ sources += $(f) ;
+ } else {
+ local source = $(f:G=$(SOURCE_GRIST:E)) ;
+ sources += $(source) ;
+ SEARCH on $(source) = $(SEARCH_SOURCE) ;
+ }
+ }
+ return $(sources) ;
}
-# Generates a grist suitable for source files based on SUBDIR variable.
-rule DoSourceGrist
+## LocateTarget
+## Sets LOCATE on the current output directory (depending on builddir,
+## variant and current subdir), sets a suitable grist and makes sure the
+## target directory is created if it doesn't exist.
+rule LocateTarget
{
- return $(<:G=$(SOURCE_GRIST:E)) ;
+ local targetdir ;
+ if $(>) {
+ targetdir = $(>) ;
+ } else {
+ targetdir = $(LOCATE_TARGET) ;
+ }
+
+ local targets = $(<:G=T!$(SOURCE_GRIST:E)!$(SUBVARIANT)) ;
+ MakeLocate $(targets) : $(targetdir) ;
+
+ return $(targets) ;
}
Depends $(target) : $(>) ;
LinkApplication $(target) : $(>) ;
+ LIBS on $(target) = $(LIBS) ;
# setup clean rules
Clean clean : $(target) ;
Clean $(<)clean : $(target) ;
actions LinkApplication bind NEEDLIBS bind EXTRAOBJECTS
{
- $(LINK) -o $(<) $(>) $(EXTRAOBJECTS) $(NEEDLIBS) $(LFLAGS)
+ $(LINK) -o $(<) $(>) $(EXTRAOBJECTS) $(NEEDLIBS) $(LIBS)
}
#============================================================================
VARIANT ?= optimize ;
-if $(VARIANT) != "debug" && $(VARIANT) != "optimize" && $(VARIANT) != "profile"
-{
- exit "Invalid modus set, please set VARIANT to debug, profile or optimize" ;
-}
-
-switch $(VARIANT)
-{
-case optimize :
- SHORTVARIANT = opt ;
-case debug :
- SHORTVARIANT = dbg ;
-case profile :
- SHORTVARIANT = prof ;
-}
# Set modus related flags
-CCFLAGS += $(COMPILER_CFLAGS) $(COMPILER_CFLAGS_$(VARIANT)) ;
-C++FLAGS += $(COMPILER_CFLAGS) $(COMPILER_C++FLAGS)
- $(COMPILER_CFLAGS_$(VARIANT)) $(COMPILER_C++FLAGS_$(VARIANT)) ;
-LFLAGS += $(LDFLAGS) $(COMPILER_LFLAGS) $(COMPILER_LFLAGS_$(VARIANT)) ;
-LOCATE_OBJECTS = $(LOCATE_OBJECTS)/$(SHORTVARIANT) ;
+CFLAGS += $(COMPILER_CFLAGS) $(COMPILER_CFLAGS_$(VARIANT)) ;
+CXXFLAGS += $(COMPILER_CFLAGS) $(COMPILER_CXXFLAGS)
+ $(COMPILER_CFLAGS_$(VARIANT)) $(COMPILER_CXXFLAGS_$(VARIANT)) ;
+LIBS += $(LDFLAGS) $(COMPILER_LIBS) $(COMPILER_LIBS_$(VARIANT)) ;
+LOCATE_OBJECTS = $(LOCATE_OBJECTS)/$(VARIANT) ;
## SubVariant variantname
## Specify subvarianet which are placed in separate compilation directories.
rule Win32Resource
{
local target = $($(<)_TARGET) ;
- local rcobject = [ DoObjectGrist _resource.o ] ;
- LOCATE on $(rcobject) = $(LOCATE_TARGET) ;
- SEARCH on $(rcobject) = $(LOCATE_TARGET) ;
+ local rcobject = [ LocateTarget _resource.o ] ;
# only add 1 resource object per target
if ! $($(<)_HASWIN32RESOURCE)
Depends $(target) : $(>) ;
LinkApplication $(target) : $(>) ;
+ LIBS on $(target) = $(LIBS) ;
# setup clean rules
Clean clean : $(target) ;
Clean $(<)clean : $(target) ;
actions LinkApplication bind NEEDLIBS bind EXTRAOBJECTS
{
- $(LINK) -o $(<) $(>) $(EXTRAOBJECTS) $(NEEDLIBS) $(LFLAGS)
+ $(LINK) -o $(<) $(>) $(EXTRAOBJECTS) $(NEEDLIBS) $(LIBS)
}
sources =
[ Wildcard *.cpp *.h ]
+ [ Wildcard video : *.cpp *.h ]
+ [ Wildcard audio : *.cpp *.h ]
+ [ Wildcard gui : *.cpp *.h ]
+ [ Wildcard lisp : *.cpp *.h ]
[ Wildcard object : *.cpp *.h ]
[ Wildcard badguy : *.cpp *.h ]
+ [ Wildcard sprite : *.cpp *.h ]
[ Wildcard trigger : *.cpp *.h ]
+ [ Wildcard control : *.cpp *.h ]
;
-TRANSLATABLE_SOURCES += [ DoSourceGrist $(sources) ] ;
+TRANSLATABLE_SOURCES += [ SearchSource $(sources) ] ;
Application supertux : $(sources) ;
LinkWith supertux : supertuxlib ;
+++ /dev/null
-import os
-Import('*')
-
-supertux_src = Glob("*.cpp") \
- + Glob("object/*.cpp") \
- + Glob("badguy/*.cpp") \
- + Glob("trigger/*.cpp")
-app = env.Program(
- target="supertux",
- source = supertux_src
-)
-AddPostAction(app, "ln -sf $TARGET .")
-InstallExec(["supertux"])
-
-Default(app)
-
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "badguy.h"
return FORCE_MOVE;
}
}
- std::cout << "COLLISION - HITPOINTS: " << hitpoints << ", BULLET HP: " << bullet_hitpoints << std::endl;
player.kill(Player::SHRINK);
return FORCE_MOVE;
}
void
BadGuy::kill_squished(Player& player)
{
- SoundManager::get()->play_sound(IDToSound(SND_SQUISH), get_pos(),
- player.get_pos());
+ sound_manager->play_sound("squish", get_pos(), player.get_pos());
physic.enable_gravity(true);
physic.set_velocity_x(0);
physic.set_velocity_y(0);
bullet_hitpoints--;
if (bullet_hitpoints <= 0) {
hitpoints = 0;
- SoundManager::get()->play_sound(IDToSound(SND_FALL), this,
- Sector::current()->player->get_pos());
+ sound_manager->play_sound("fall", this,
+ Sector::current()->player->get_pos());
physic.set_velocity_y(0);
physic.enable_gravity(true);
set_state(STATE_FALLING);
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __BADGUY_H__
#define __BADGUY_H__
// moved them here to make it less typing when implementing new badguys
#include <math.h>
#include "timer.h"
-#include "special/moving_object.h"
-#include "special/sprite.h"
+#include "moving_object.h"
+#include "sprite/sprite.h"
#include "math/physic.h"
#include "object/player.h"
#include "serializable.h"
#include "lisp/lisp.h"
#include "lisp/writer.h"
#include "video/drawing_context.h"
-#include "special/sprite_manager.h"
+#include "sprite/sprite_manager.h"
using namespace SuperTux;
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "bomb.h"
{
state = 1;
sprite->set_action("explosion");
- SoundManager::get()->play_sound(IDToSound(SND_EXPLODE), get_pos(),
- Sector::current()->player->get_pos());
+ sound_manager->play_sound("explosion", get_pos(),
+ Sector::current()->player->get_pos());
timer.start(EXPLOSIONTIME);
}
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __BOMB_H__
#define __BOMB_H__
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "bouncing_snowball.h"
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __BOUNCING_SNOWBALL_H__
#define __BOUNCING_SNOWBALL_H__
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "dispenser.h"
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __DISPENSER_H__
#define __DISPENSER_H__
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "flame.h"
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __FLAME_H__
#define __FLAME_H__
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include <stdio.h>
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __FLYINGSNOWBALL_H__
#define __FLYINGSNOWBALL_H__
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "jumpy.h"
// hit floor?
if(chit.normal.y < -.5) {
physic.set_velocity_y(JUMPSPEED);
- SoundManager::get()->play_sound(IDToSound(SND_SKID));
+ // TODO create a nice sound for this...
+ //sound_manager->play_sound("skid");
} else if(chit.normal.y < .5) { // bumped on roof
physic.set_velocity_y(0);
}
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __JUMPY_H__
#define __JUMPY_H__
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "mrbomb.h"
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __MRBOMB_H__
#define __MRBOMB_H__
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "mriceblock.h"
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());
+ sound_manager->play_sound("ricochet", get_pos(),
+ Sector::current()->player->get_pos());
break;
}
case ICESTATE_FLAT:
}
// flatten
- SoundManager::get()->play_sound(IDToSound(SND_STOMP), get_pos(),
- player.get_pos());
+ sound_manager->play_sound("stomp", get_pos(), player.get_pos());
physic.set_velocity_x(0);
physic.set_velocity_y(0);
break;
case ICESTATE_FLAT:
// kick
- SoundManager::get()->play_sound(IDToSound(SND_KICK), this,
- player.get_pos());
+ sound_manager->play_sound("kick", this, player.get_pos());
if(player.get_pos().x < get_pos().x) {
dir = RIGHT;
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __MRICEBLOCK_H__
#define __MRICEBLOCK_H__
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "mrrocket.h"
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __MRROCKET_H__
#define __MRROCKET_H__
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "mrtree.h"
mystate = STATE_NORMAL;
activate();
- SoundManager::get()->play_sound(IDToSound(SND_SQUISH), get_pos(),
- player.get_pos());
+ sound_manager->play_sound("squish", get_pos(), player.get_pos());
player.bounce(*this);
} else {
sprite->set_action(dir == LEFT ? "squished-left" : "squished-right");
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __MRTREE_H__
#define __MRTREE_H__
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "nolok_01.h"
bullet_hitpoints--;
if (bullet_hitpoints <= 0) {
hitpoints = 0;
- SoundManager::get()->play_sound(IDToSound(SND_FALL), this,
- Sector::current()->player->get_pos());
+ sound_manager->play_sound("fall", this,
+ Sector::current()->player->get_pos());
physic.set_velocity_y(0);
physic.enable_gravity(true);
set_state(STATE_FALLING);
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __NOLOK01_H__
#define __NOLOK01_H__
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "poisonivy.h"
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __POISONIVY_H__
#define __POISONIVY_H__
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "rocketexplosion.h"
RocketExplosion::explode()
{
sprite->set_action(dir == LEFT ? "explosion-left" : "explosion-right");
- SoundManager::get()->play_sound(IDToSound(SND_EXPLODE), get_pos(),
- Sector::current()->player->get_pos());
+ sound_manager->play_sound("explode", get_pos(),
+ Sector::current()->player->get_pos());
timer.start(EXPLOSIONTIME, true);
}
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __BOMB_H__
#define __BOMB_H__
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "snowball.h"
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __SNOWBALL_H__
#define __SNOWBALL_H__
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 "spike.h"
Spike::Spike(const Vector& pos, Direction dir)
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __SPIKE_H__
#define __SPIKE_H__
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "spiky.h"
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __SPIKY_H__
#define __SPIKY_H__
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "stalactite.h"
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __STALACTITE_H__
#define __STALACTITE_H__
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include <float.h>
side = LEFT;
hitpoints = INITIAL_HITPOINTS;
bullet_hitpoints = INITIAL_BULLET_HP;
- sound_gna = SoundManager::get()->load_sound(
- get_resource_filename("sounds/yeti_gna.wav"));
- sound_roar = SoundManager::get()->load_sound(
- get_resource_filename("sounds/yeti_roar.wav"));
+ sound_manager->preload_sound("yeti_gna");
+ sound_manager->preload_sound("yeti_roar");
}
Yeti::~Yeti()
case ANGRY_JUMPING:
if(timer.check()) {
// jump
- SoundManager::get()->play_sound(sound_gna);
+ sound_manager->play_sound("yeti_gna");
physic.set_velocity_y(JUMP_VEL1);
}
break;
if(hit.normal.y > .9) {
hitpoints--;
bullet_hitpoints--;
- SoundManager::get()->play_sound(sound_roar);
+ sound_manager->play_sound("yeti_roar");
if(collision_squished(player))
return ABORT_MOVE;
else if (hitpoints <= 0) {
return FORCE_MOVE;
}
}
- std::cout << "COLLISION - HITPOINTS: " << hitpoints << ", BULLET HP: " << bullet_hitpoints << std::endl;
player.kill(Player::SHRINK);
return FORCE_MOVE;
}
void
Yeti::kill_fall()
{
- SoundManager::get()->play_sound(sound_roar);
+ sound_manager->play_sound("yeti_roar");
bullet_hitpoints--;
if (bullet_hitpoints <= 0) {
- SoundManager::get()->play_sound(IDToSound(SND_FALL), this,
- Sector::current()->player->get_pos());
+ sound_manager->play_sound("fall", this,
+ Sector::current()->player->get_pos());
physic.set_velocity_y(0);
physic.enable_gravity(true);
set_state(STATE_FALLING);
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __YETI_H__
#define __YETI_H__
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 "yeti_stalactite.h"
static const float SHAKE_TIME = .8;
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __YETI_STALACTITE_H__
#define __YETI_STALACTITE_H__
--- /dev/null
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __COLLISION_H__
+#define __COLLISION_H__
+
+namespace SuperTux {
+class Vector;
+class Rectangle;
+class AATriangle;
+}
+
+using namespace SuperTux;
+
+class CollisionHit;
+
+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 Vector& movement, 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 Vector& movement, const AATriangle& triangle);
+};
+
+#endif
+
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include <iostream>
#include "collision_grid.h"
-#include "special/collision.h"
+#include "collision.h"
#include "sector.h"
#include "collision_grid_iterator.h"
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __COLLISION_GRID_H__
#define __COLLISION_GRID_H__
#include <vector>
-#include "special/moving_object.h"
+#include "moving_object.h"
using namespace SuperTux;
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __COLLISION_GRID_ITERATOR_H__
#define __COLLISION_GRID_ITERATOR_H__
--- /dev/null
+// $Id: collision_hit.h 2177 2004-11-24 23:10:09Z matzebraun $
+//
+// SuperTux - A Jump'n Run
+// Copyright (C) 2004 Matthias Braun <matze@braunis.de
+//
+// 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_COLLISION_HIT_H
+#define SUPERTUX_COLLISION_HIT_H
+
+#include "math/vector.h"
+
+using namespace SuperTux;
+
+/**
+ * Used as return value for the collision functions, to indicate how the
+ * collision should be handled
+ */
+enum HitResponse
+{
+ // note: keep the elements in this order
+
+ /// don't move the object
+ ABORT_MOVE = 0,
+ /// move object out of collision and check for collisions again
+ /// if this happens to often then the move will just be aborted
+ CONTINUE,
+ /// do the move ignoring the collision
+ FORCE_MOVE
+};
+
+/**
+ * This class collects data about a collision
+ */
+class CollisionHit
+{
+public:
+ /// penetration depth
+ float depth;
+ /// time of the collision (between 0 and 1 in relation to movement)
+ float time;
+ /// The normal of the side we collided with
+ Vector normal;
+};
+
+#endif
+
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "flip_level_transformer.h"
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __FLIP_LEVEL_TRANSFORMER_H__
#define __FLIP_LEVEL_TRANSFORMER_H__
class TileMap;
class BadGuy;
class SpawnPoint;
-namespace SuperTux {
class MovingObject;
-}
-
-using namespace SuperTux;
/** Vertically or horizontally flip a level */
class FlipLevelTransformer : public LevelTransformer
--- /dev/null
+// $Id: game_object.cpp 2277 2005-01-16 12:11:22Z matzebraun $
+//
+// SuperTux - A Jump'n Run
+// Copyright (C) 2004 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
+
+#include "game_object.h"
+#include "object_remove_listener.h"
+
+GameObject::GameObject()
+ : wants_to_die(false), remove_listeners(0), flags(0)
+{
+}
+
+GameObject::~GameObject()
+{
+ // call remove listeners (and remove them from the list)
+ RemoveListenerListEntry* entry = remove_listeners;
+ while(entry != 0) {
+ RemoveListenerListEntry* next = entry->next;
+ entry->listener->object_removed(this);
+ delete entry;
+ entry = next;
+ }
+}
--- /dev/null
+// $Id: game_object.h 2293 2005-03-25 20:39:56Z matzebraun $
+//
+// SuperTux - A Jump'n Run
+// Copyright (C) 2004 Matthias Braun <matze@braunis.de>
+//
+// 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_GAMEOBJECT_H
+#define SUPERTUX_GAMEOBJECT_H
+
+#include <string>
+
+class DrawingContext;
+class ObjectRemoveListener;
+
+/**
+ * Base class for all game objects. This contains functions for:
+ * -querying the actual type of the object
+ * -a flag that indicates if the object wants to be removed. Objects with this
+ * flag will be removed at the end of each frame. This is alot safer than
+ * having some uncontrollable "delete this" in the code.
+ * -an action function that is called once per frame and allows the object to
+ * update it's state.
+ *
+ * Most GameObjects will also implement the DrawableObject interface so that
+ * they can actually be drawn on screen.
+ */
+class GameObject
+{
+public:
+ GameObject();
+ 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 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;
+
+ /** The GameObject should draw itself onto the provided DrawingContext if this
+ * function is called.
+ */
+ virtual void draw(DrawingContext& context) = 0;
+
+ /** returns true if the object is not scheduled to be removed yet */
+ bool is_valid() const
+ {
+ return !wants_to_die;
+ }
+ /** schedules this object to be removed at the end of the frame */
+ void remove_me()
+ {
+ wants_to_die = true;
+ }
+ /** registers a remove listener which will be called if the object
+ * gets removed/destroyed
+ */
+ void add_remove_listener(ObjectRemoveListener* listener)
+ {
+ RemoveListenerListEntry* entry = new RemoveListenerListEntry();
+ entry->next = remove_listeners;
+ entry->listener = listener;
+
+ remove_listeners = entry;
+ }
+
+ // 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;
+
+ struct RemoveListenerListEntry
+ {
+ RemoveListenerListEntry* next;
+ ObjectRemoveListener* listener;
+ };
+ RemoveListenerListEntry* remove_listeners;
+
+protected:
+ int flags;
+};
+
+#endif /*SUPERTUX_GAMEOBJECT_H*/
+
--- /dev/null
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2000 Bill Kendrick <bill@newbreedsoftware.com>
+// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
+// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
+//
+// 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 <config.h>
+
+#include <iostream>
+#include <sstream>
+#include <cassert>
+#include <cstdio>
+#include <cstdlib>
+#include <cmath>
+#include <cstring>
+#include <cerrno>
+#include <unistd.h>
+#include <ctime>
+#include <stdexcept>
+
+#include <SDL.h>
+
+#ifndef WIN32
+#include <sys/types.h>
+#include <ctype.h>
+#endif
+
+#include "app/globals.h"
+#include "game_session.h"
+#include "video/screen.h"
+#include "app/setup.h"
+#include "gui/menu.h"
+#include "sector.h"
+#include "level.h"
+#include "tile.h"
+#include "player_status.h"
+#include "object/particlesystem.h"
+#include "object/background.h"
+#include "object/tilemap.h"
+#include "object/camera.h"
+#include "object/player.h"
+#include "lisp/lisp.h"
+#include "lisp/parser.h"
+#include "resources.h"
+#include "app/gettext.h"
+#include "worldmap.h"
+#include "misc.h"
+#include "statistics.h"
+#include "timer.h"
+#include "object/fireworks.h"
+#include "textscroller.h"
+#include "control/codecontroller.h"
+#include "control/joystickkeyboardcontroller.h"
+#include "main.h"
+
+GameSession* GameSession::current_ = 0;
+
+GameSession::GameSession(const std::string& levelfile_, GameSessionMode mode,
+ Statistics* statistics)
+ : level(0), currentsector(0), mode(mode),
+ end_sequence(NO_ENDSEQUENCE), end_sequence_controller(0),
+ levelfile(levelfile_), best_level_statistics(statistics)
+{
+ current_ = this;
+
+ game_pause = false;
+ fps_fps = 0;
+
+ context = new DrawingContext();
+
+ restart_level();
+}
+
+void
+GameSession::restart_level()
+{
+ game_pause = false;
+ exit_status = ES_NONE;
+ end_sequence = NO_ENDSEQUENCE;
+
+ main_controller->reset();
+ last_keys.clear();
+
+ delete level;
+ currentsector = 0;
+
+ level = new Level;
+ level->load(levelfile);
+
+ 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->timelimit);
+
+ if(reset_sector != "") {
+ currentsector = level->get_sector(reset_sector);
+ if(!currentsector) {
+ std::stringstream msg;
+ msg << "Couldn't find sector '" << reset_sector << "' for resetting tux.";
+ throw std::runtime_error(msg.str());
+ }
+ currentsector->activate(reset_pos);
+ } else {
+ currentsector = level->get_sector("main");
+ if(!currentsector)
+ throw std::runtime_error("Couldn't find main sector");
+ currentsector->activate("main");
+ }
+
+ if(mode == ST_GL_PLAY || mode == ST_GL_LOAD_LEVEL_FILE)
+ levelintro();
+
+ start_timers();
+ currentsector->play_music(LEVEL_MUSIC);
+}
+
+GameSession::~GameSession()
+{
+ delete end_sequence_controller;
+ delete level;
+ delete context;
+}
+
+void
+GameSession::levelintro()
+{
+ sound_manager->halt_music();
+
+ char str[60];
+
+ DrawingContext context;
+ for(Sector::GameObjects::iterator i = currentsector->gameobjects.begin();
+ i != currentsector->gameobjects.end(); ++i) {
+ Background* background = dynamic_cast<Background*> (*i);
+ if(background) {
+ background->draw(context);
+ }
+ }
+
+// context.draw_text(gold_text, level->get_name(), Vector(SCREEN_WIDTH/2, 160),
+// CENTER_ALLIGN, LAYER_FOREGROUND1);
+ context.draw_center_text(gold_text, level->get_name(), Vector(0, 160),
+ LAYER_FOREGROUND1);
+
+ sprintf(str, "TUX x %d", player_status.lives);
+ context.draw_text(white_text, str, Vector(SCREEN_WIDTH/2, 210),
+ CENTER_ALLIGN, LAYER_FOREGROUND1);
+
+ if((level->get_author().size()) && (level->get_author() != "SuperTux Team"))
+ //TODO make author check case/blank-insensitive
+ context.draw_text(white_small_text,
+ std::string(_("contributed by ")) + level->get_author(),
+ Vector(SCREEN_WIDTH/2, 350), CENTER_ALLIGN, LAYER_FOREGROUND1);
+
+
+ if(best_level_statistics != NULL)
+ best_level_statistics->draw_message_info(context, _("Best Level Statistics"));
+
+ context.do_drawing();
+
+ SDL_Event event;
+ wait_for_event(event,1000,3000,true);
+}
+
+/* Reset Timers */
+void
+GameSession::start_timers()
+{
+ time_left.start(level->timelimit);
+ Ticks::pause_init();
+}
+
+void
+GameSession::on_escape_press()
+{
+ if(currentsector->player->is_dying() || end_sequence != NO_ENDSEQUENCE)
+ return; // don't let the player open the menu, when he is dying
+
+ if(mode == ST_GL_TEST) {
+ exit_status = ES_LEVEL_ABORT;
+ } else if (!Menu::current()) {
+ Menu::set_current(game_menu);
+ game_menu->set_active_item(MNID_CONTINUE);
+ Ticks::pause_start();
+ game_pause = true;
+ } else {
+ Ticks::pause_stop();
+ game_pause = false;
+ }
+}
+
+void
+GameSession::process_events()
+{
+ Player& tux = *currentsector->player;
+ main_controller->update();
+
+ // end of pause mode?
+ if(!Menu::current() && game_pause) {
+ game_pause = false;
+ Ticks::pause_stop();
+ }
+
+ if (end_sequence != NO_ENDSEQUENCE) {
+ if(end_sequence_controller == 0) {
+ end_sequence_controller = new CodeController();
+ tux.set_controller(end_sequence_controller);
+ }
+
+ end_sequence_controller->press(Controller::RIGHT);
+
+ if (int(last_x_pos) == int(tux.get_pos().x))
+ end_sequence_controller->press(Controller::JUMP);
+ last_x_pos = tux.get_pos().x;
+ }
+
+ main_controller->update();
+ SDL_Event event;
+ while (SDL_PollEvent(&event)) {
+ /* Check for menu-events, if the menu is shown */
+ if (Menu::current())
+ Menu::current()->event(event);
+ main_controller->process_event(event);
+ if(event.type == SDL_QUIT)
+ throw std::runtime_error("Received window close");
+ }
+}
+
+void
+GameSession::try_cheats()
+{
+ Player& tux = *currentsector->player;
+
+ // Cheating words (the goal of this is really for debugging,
+ // but could be used for some cheating, nothing wrong with that)
+ if(main_controller->check_cheatcode("grow")) {
+ tux.set_bonus(GROWUP_BONUS, false);
+ last_keys.clear();
+ }
+ if(main_controller->check_cheatcode("fire")) {
+ tux.set_bonus(FIRE_BONUS, false);
+ last_keys.clear();
+ }
+ if(main_controller->check_cheatcode("ice")) {
+ tux.set_bonus(ICE_BONUS, false);
+ last_keys.clear();
+ }
+ if(main_controller->check_cheatcode("lifeup")) {
+ player_status.lives++;
+ last_keys.clear();
+ }
+ if(main_controller->check_cheatcode("lifedown")) {
+ player_status.lives--;
+ last_keys.clear();
+ }
+ if(main_controller->check_cheatcode("grease")) {
+ tux.physic.set_velocity_x(tux.physic.get_velocity_x()*3);
+ last_keys.clear();
+ }
+ if(main_controller->check_cheatcode("invincible")) {
+ // be invincle for the rest of the level
+ tux.invincible_timer.start(10000);
+ last_keys.clear();
+ }
+ if(main_controller->check_cheatcode("shrink")) {
+ // remove powerups
+ tux.kill(tux.SHRINK);
+ last_keys.clear();
+ }
+ if(main_controller->check_cheatcode("kill")) {
+ // kill Tux, but without losing a life
+ player_status.lives++;
+ tux.kill(tux.KILL);
+ last_keys.clear();
+ }
+#if 0
+ if(main_controller->check_cheatcode("grid")) {
+ // toggle debug grid
+ debug_grid = !debug_grid;
+ last_keys.clear();
+ }
+#endif
+ if(main_controller->check_cheatcode("hover")) {
+ // toggle hover ability on/off
+ tux.enable_hover = !tux.enable_hover;
+ last_keys.clear();
+ }
+ if(main_controller->check_cheatcode("gotoend")) {
+ // goes to the end of the level
+ tux.move(Vector(
+ (currentsector->solids->get_width()*32) - (SCREEN_WIDTH*2), 0));
+ currentsector->camera->reset(
+ Vector(tux.get_pos().x, tux.get_pos().y));
+ last_keys.clear();
+ }
+ if(main_controller->check_cheatcode("finish")) {
+ // finish current sector
+ exit_status = ES_LEVEL_FINISHED;
+ // don't add points to stats though...
+ }
+ // temporary to help player's choosing a flapping
+ if(main_controller->check_cheatcode("marek")) {
+ tux.flapping_mode = Player::MAREK_FLAP;
+ last_keys.clear();
+ }
+ if(main_controller->check_cheatcode("ricardo")) {
+ tux.flapping_mode = Player::RICARDO_FLAP;
+ last_keys.clear();
+ }
+ if(main_controller->check_cheatcode("ryan")) {
+ tux.flapping_mode = Player::RYAN_FLAP;
+ last_keys.clear();
+ }
+}
+
+void
+GameSession::check_end_conditions()
+{
+ Player* tux = currentsector->player;
+
+ /* End of level? */
+ if(end_sequence && endsequence_timer.check()) {
+ exit_status = ES_LEVEL_FINISHED;
+ return;
+ } else if (!end_sequence && tux->is_dead()) {
+ 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(float elapsed_time)
+{
+ // handle controller
+ if(main_controller->pressed(Controller::PAUSE_MENU))
+ on_escape_press();
+
+ // advance timers
+ if(!currentsector->player->growing_timer.started()) {
+ // Update Tux and the World
+ currentsector->action(elapsed_time);
+ }
+
+ // respawning in new sector?
+ if(newsector != "" && newspawnpoint != "") {
+ Sector* sector = level->get_sector(newsector);
+ if(sector == 0) {
+ std::cerr << "Sector '" << newsector << "' not found.\n";
+ }
+ sector->activate(newspawnpoint);
+ sector->play_music(LEVEL_MUSIC);
+ currentsector = sector;
+ newsector = "";
+ newspawnpoint = "";
+ }
+}
+
+void
+GameSession::draw()
+{
+ currentsector->draw(*context);
+ drawstatus(*context);
+
+ if(game_pause)
+ draw_pause();
+
+ if(Menu::current()) {
+ Menu::current()->draw(*context);
+ mouse_cursor->draw(*context);
+ }
+
+ context->do_drawing();
+}
+
+void
+GameSession::draw_pause()
+{
+ int x = SCREEN_HEIGHT / 20;
+ for(int i = 0; i < x; ++i) {
+ context->draw_filled_rect(
+ Vector(i % 2 ? (pause_menu_frame * i)%SCREEN_WIDTH :
+ -((pause_menu_frame * i)%SCREEN_WIDTH)
+ ,(i*20+pause_menu_frame)%SCREEN_HEIGHT),
+ Vector(SCREEN_WIDTH,10),
+ Color(20,20,20, rand() % 20 + 1), LAYER_FOREGROUND1+1);
+ }
+
+ context->draw_filled_rect(
+ Vector(0,0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
+ Color(rand() % 50, rand() % 50, rand() % 50, 128), LAYER_FOREGROUND1);
+#if 0
+ context->draw_text(blue_text, _("PAUSE - Press 'P' To Play"),
+ Vector(SCREEN_WIDTH/2, 230), CENTER_ALLIGN, LAYER_FOREGROUND1+2);
+
+ const char* str1 = _("Playing: ");
+ const char* str2 = level->get_name().c_str();
+
+ context->draw_text(blue_text, str1,
+ Vector((SCREEN_WIDTH - (blue_text->get_text_width(str1) + white_text->get_text_width(str2)))/2, 340),
+ LEFT_ALLIGN, LAYER_FOREGROUND1+2);
+ context->draw_text(white_text, str2,
+ Vector(((SCREEN_WIDTH - (blue_text->get_text_width(str1) + white_text->get_text_width(str2)))/2)+blue_text->get_text_width(str1), 340),
+ LEFT_ALLIGN, LAYER_FOREGROUND1+2);
+#endif
+}
+
+void
+GameSession::process_menu()
+{
+ Menu* menu = Menu::current();
+ if(menu) {
+ menu->action();
+
+ if(menu == game_menu) {
+ switch (game_menu->check()) {
+ case MNID_CONTINUE:
+ Menu::set_current(0);
+ break;
+ case MNID_ABORTLEVEL:
+ Menu::set_current(0);
+ exit_status = ES_LEVEL_ABORT;
+ break;
+ }
+ } else if(menu == options_menu) {
+ process_options_menu();
+ } else if(menu == load_game_menu ) {
+ process_load_game_menu();
+ }
+ }
+}
+
+
+GameSession::ExitStatus
+GameSession::run()
+{
+ Menu::set_current(0);
+ current_ = this;
+
+ int fps_cnt = 0;
+ double fps_nextframe_ticks; // fps regulating code
+
+ // Eat unneeded events
+ SDL_Event event;
+ while(SDL_PollEvent(&event))
+ {}
+
+ draw();
+
+ Uint32 lastticks = SDL_GetTicks();
+ fps_ticks = SDL_GetTicks();
+ fps_nextframe_ticks = SDL_GetTicks(); // fps regulating code
+
+ while (exit_status == ES_NONE) {
+ Uint32 ticks = SDL_GetTicks();
+ float elapsed_time = float(ticks - lastticks) / 1000.;
+ if(!game_pause)
+ global_time += elapsed_time;
+ lastticks = ticks;
+
+ // 40fps is minimum
+ if(elapsed_time > 0.025){
+ elapsed_time = 0.025;
+ }
+
+ // fps regualting code
+ const double wantedFps= 60.0; // set to 60 by now
+ while (fps_nextframe_ticks > SDL_GetTicks()){
+ /* just wait */
+ // If we really have to wait long, then do an imprecise SDL_Delay()
+ if (fps_nextframe_ticks - SDL_GetTicks() > 15){
+ SDL_Delay(5);
+ }
+
+ }
+ float diff = SDL_GetTicks() - fps_nextframe_ticks;
+ if (diff > 5.0)
+ fps_nextframe_ticks = SDL_GetTicks() + (1000.0 / wantedFps); // sets the ticks that must have elapsed
+ else
+ fps_nextframe_ticks += 1000.0 / wantedFps; // sets the ticks that must have elapsed
+ // in order for the next frame to start.
+
+ 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(elapsed_time/2);
+ else if(end_sequence == NO_ENDSEQUENCE)
+ action(elapsed_time);
+ }
+ else
+ {
+ ++pause_menu_frame;
+ SDL_Delay(50);
+ }
+
+ draw();
+
+ /* Time stops in pause mode */
+ if(game_pause || Menu::current())
+ {
+ continue;
+ }
+
+ //frame_rate.update();
+
+ /* Handle time: */
+ if (time_left.check() && !end_sequence)
+ currentsector->player->kill(Player::KILL);
+
+ /* Handle music: */
+ if (currentsector->player->invincible_timer.started() && !end_sequence)
+ {
+ currentsector->play_music(HERRING_MUSIC);
+ }
+ /* or just normal music? */
+ else if(currentsector->get_music_type() != LEVEL_MUSIC && !end_sequence)
+ {
+ currentsector->play_music(LEVEL_MUSIC);
+ }
+
+ /* Calculate frames per second */
+ if(config->show_fps)
+ {
+ ++fps_cnt;
+
+ if(SDL_GetTicks() - fps_ticks >= 500)
+ {
+ fps_fps = (float) fps_cnt / .5;
+ fps_cnt = 0;
+ fps_ticks = SDL_GetTicks();
+ }
+ }
+ }
+
+ // just in case
+ main_controller->reset();
+ return exit_status;
+}
+
+void
+GameSession::respawn(const std::string& sector, const std::string& spawnpoint)
+{
+ newsector = sector;
+ newspawnpoint = spawnpoint;
+}
+
+void
+GameSession::set_reset_point(const std::string& sector, const Vector& pos)
+{
+ reset_sector = sector;
+ reset_pos = pos;
+}
+
+void
+GameSession::display_info_box(const std::string& text)
+{
+ InfoBox* box = new InfoBox(text);
+
+ bool running = true;
+ while(running) {
+
+ main_controller->update();
+ SDL_Event event;
+ while (SDL_PollEvent(&event)) {
+ main_controller->process_event(event);
+ if(event.type == SDL_QUIT)
+ throw std::runtime_error("Received window close event");
+ }
+
+ if(main_controller->pressed(Controller::JUMP)
+ || main_controller->pressed(Controller::ACTION)
+ || main_controller->pressed(Controller::PAUSE_MENU)
+ || main_controller->pressed(Controller::MENU_SELECT))
+ running = false;
+ box->draw(*context);
+ draw();
+ }
+
+ delete box;
+}
+
+void
+GameSession::start_sequence(const std::string& sequencename)
+{
+ if(sequencename == "endsequence" || sequencename == "fireworks") {
+ if(end_sequence)
+ return;
+
+ end_sequence = ENDSEQUENCE_RUNNING;
+ endsequence_timer.start(7.0); // 7 seconds until we finish the map
+ last_x_pos = -1;
+ sound_manager->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(sequencename == "fireworks") {
+ currentsector->add_object(new Fireworks());
+ }
+ } else if(sequencename == "stoptux") {
+ end_sequence = ENDSEQUENCE_WAITING;
+ } else {
+ std::cout << "Unknown sequence '" << sequencename << "'.\n";
+ }
+}
+
+/* (Status): */
+void
+GameSession::drawstatus(DrawingContext& context)
+{
+ char str[60];
+
+ snprintf(str, 60, " %d", global_stats.get_points(SCORE_STAT));
+ context.draw_text(white_text, _("SCORE"), Vector(0, 0), LEFT_ALLIGN, LAYER_FOREGROUND1);
+ context.draw_text(gold_text, str, Vector(96, 0), LEFT_ALLIGN, LAYER_FOREGROUND1);
+
+ if(mode == ST_GL_TEST) {
+ context.draw_text(white_text, _("Press ESC To Return"), Vector(0,20),
+ LEFT_ALLIGN, LAYER_FOREGROUND1);
+ }
+
+ if(time_left.get_timeleft() < 0) {
+ context.draw_text(white_text, _("TIME's UP"), Vector(SCREEN_WIDTH/2, 0),
+ CENTER_ALLIGN, LAYER_FOREGROUND1);
+ } else if (time_left.get_timeleft() > TIME_WARNING
+ || int(global_time * 2.5) % 2) {
+ sprintf(str, " %d", int(time_left.get_timeleft()));
+ context.draw_text(white_text, _("TIME"),
+ Vector(SCREEN_WIDTH/2, 0), CENTER_ALLIGN, LAYER_FOREGROUND1);
+ context.draw_text(gold_text, str,
+ Vector(SCREEN_WIDTH/2 + 4*16, 0), CENTER_ALLIGN, LAYER_FOREGROUND1);
+ }
+
+ sprintf(str, " %d", player_status.coins);
+ context.draw_text(white_text, _("COINS"),
+ Vector(SCREEN_WIDTH - white_text->get_text_width(_("COINS"))-white_text->get_text_width(" 99"), 0),
+ LEFT_ALLIGN, LAYER_FOREGROUND1);
+ context.draw_text(gold_text, str,
+ Vector(SCREEN_WIDTH - gold_text->get_text_width(" 99"), 0),LEFT_ALLIGN, LAYER_FOREGROUND1);
+
+ if (player_status.lives >= 5)
+ {
+ sprintf(str, "%dx", player_status.lives);
+ float x = SCREEN_WIDTH - gold_text->get_text_width(str) - tux_life->w;
+ context.draw_text(gold_text, str, Vector(x, 20), LEFT_ALLIGN, LAYER_FOREGROUND1);
+ context.draw_surface(tux_life, Vector(SCREEN_WIDTH - 16, 20),
+ LAYER_FOREGROUND1);
+ }
+ else
+ {
+ for(int i= 0; i < player_status.lives; ++i)
+ context.draw_surface(tux_life,
+ Vector(SCREEN_WIDTH - tux_life->w*4 +(tux_life->w*i), 20),
+ LAYER_FOREGROUND1);
+ }
+
+ context.draw_text(white_text, _("LIVES"),
+ Vector(SCREEN_WIDTH - white_text->get_text_width(_("LIVES")) - white_text->get_text_width(" 99"), 20),
+ LEFT_ALLIGN, LAYER_FOREGROUND1);
+
+ if(config->show_fps) {
+ sprintf(str, "%2.1f", fps_fps);
+ context.draw_text(white_text, "FPS",
+ Vector(SCREEN_WIDTH -
+ white_text->get_text_width("FPS "), 40),
+ LEFT_ALLIGN, LAYER_FOREGROUND1);
+ context.draw_text(gold_text, str,
+ Vector(SCREEN_WIDTH-4*16, 40),
+ LEFT_ALLIGN, LAYER_FOREGROUND1);
+ }
+}
+
+void
+GameSession::drawresultscreen()
+{
+ char str[80];
+
+ DrawingContext context;
+ for(Sector::GameObjects::iterator i = currentsector->gameobjects.begin();
+ i != currentsector->gameobjects.end(); ++i) {
+ Background* background = dynamic_cast<Background*> (*i);
+ if(background) {
+ background->draw(context);
+ }
+ }
+
+ context.draw_text(blue_text, _("Result:"), Vector(SCREEN_WIDTH/2, 200),
+ CENTER_ALLIGN, LAYER_FOREGROUND1);
+
+ sprintf(str, _("SCORE: %d"), global_stats.get_points(SCORE_STAT));
+ context.draw_text(gold_text, str, Vector(SCREEN_WIDTH/2, 224), CENTER_ALLIGN, LAYER_FOREGROUND1);
+
+ sprintf(str, _("COINS: %d"), player_status.coins);
+ context.draw_text(gold_text, str, Vector(SCREEN_WIDTH/2, 256), CENTER_ALLIGN, LAYER_FOREGROUND1);
+
+ context.do_drawing();
+
+ SDL_Event event;
+ wait_for_event(event,2000,5000,true);
+}
+
+std::string slotinfo(int slot)
+{
+ std::string tmp;
+ std::string slotfile;
+ std::string title;
+ std::stringstream stream;
+ stream << slot;
+ slotfile = user_dir + "/save/slot" + stream.str() + ".stsg";
+
+ try {
+ lisp::Parser parser;
+ std::auto_ptr<lisp::Lisp> root (parser.parse(slotfile));
+
+ const lisp::Lisp* savegame = root->get_lisp("supertux-savegame");
+ if(!savegame)
+ throw std::runtime_error("file is not a supertux-savegame.");
+
+ savegame->get("title", title);
+ } catch(std::exception& e) {
+ return std::string(_("Slot")) + " " + stream.str() + " - " +
+ std::string(_("Free"));
+ }
+
+ return std::string("Slot ") + stream.str() + " - " + title;
+}
+
+bool process_load_game_menu()
+{
+ int slot = load_game_menu->check();
+
+ if(slot != -1 && load_game_menu->get_item_by_id(slot).kind == MN_ACTION)
+ {
+ std::stringstream stream;
+ stream << slot;
+ std::string slotfile = user_dir + "/save/slot" + stream.str() + ".stsg";
+
+ fadeout(256);
+ DrawingContext context;
+ context.draw_text(white_text, "Loading...",
+ Vector(SCREEN_WIDTH/2, SCREEN_HEIGHT/2), CENTER_ALLIGN, LAYER_FOREGROUND1);
+ context.do_drawing();
+
+ WorldMapNS::WorldMap worldmap;
+
+ worldmap.set_map_filename("/levels/world1/worldmap.stwm");
+ // Load the game or at least set the savegame_file variable
+ worldmap.loadgame(slotfile);
+
+ worldmap.display();
+
+ Menu::set_current(main_menu);
+
+ Ticks::pause_stop();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
--- /dev/null
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2004 Bill Kendrick <bill@newbreedsoftware.com>
+// Tobias Glaesser <tobi.web@gmx.de>
+// Ingo Ruhnke <grumbel@gmx.de>
+//
+// 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_GAMELOOP_H
+#define SUPERTUX_GAMELOOP_H
+
+#include <SDL.h>
+#include "timer.h"
+#include "statistics.h"
+
+using namespace SuperTux;
+
+/* GameLoop modes */
+
+enum GameSessionMode {
+ ST_GL_PLAY,
+ ST_GL_TEST,
+ ST_GL_LOAD_GAME,
+ ST_GL_LOAD_LEVEL_FILE,
+ ST_GL_DEMO_GAME
+};
+
+enum GameMenuIDs {
+ MNID_CONTINUE,
+ MNID_ABORTLEVEL
+};
+
+extern int game_started;
+
+class Level;
+class Sector;
+class Statistics;
+class DrawingContext;
+class CodeController;
+
+/** The GameSession class controlls the controll flow of a World, ie.
+ present the menu on specifc keypresses, render and update it while
+ keeping the speed and framerate sane, etc. */
+class GameSession
+{
+public:
+ enum ExitStatus { ES_NONE, ES_LEVEL_FINISHED, ES_GAME_OVER, ES_LEVEL_ABORT };
+
+public:
+ DrawingContext* context;
+ Timer2 time_left;
+
+ GameSession(const std::string& levelfile, GameSessionMode mode,
+ Statistics* statistics=0);
+ ~GameSession();
+
+ /** Enter the busy loop */
+ ExitStatus run();
+
+ void draw();
+ void action(float frame_ratio);
+
+ void set_current()
+ { current_ = this; }
+ static GameSession* current() { return current_; }
+
+ void respawn(const std::string& sectorname,
+ const std::string& spawnpointname);
+ void set_reset_point(const std::string& sectorname,
+ const Vector& pos);
+ void display_info_box(const std::string& text);
+ Sector* get_current_sector()
+ { return currentsector; }
+
+ void start_sequence(const std::string& sequencename);
+ /// called by JoystickKeyboardController after an ascii key has been pressed
+ void try_cheats();
+
+private:
+ void restart_level();
+
+ void check_end_conditions();
+ void start_timers();
+ void process_events();
+
+ void levelintro();
+ void drawstatus(DrawingContext& context);
+ void drawendscreen();
+ void drawresultscreen();
+ void draw_pause();
+
+ void on_escape_press();
+ void process_menu();
+
+ Uint32 fps_ticks;
+ Timer2 endsequence_timer;
+ Level* level;
+ Sector* currentsector;
+
+ GameSessionMode mode;
+ int levelnb;
+ float fps_fps;
+ int pause_menu_frame;
+
+ /** If true the end_sequence will be played, user input will be
+ ignored while doing that */
+ enum EndSequenceState {
+ NO_ENDSEQUENCE,
+ ENDSEQUENCE_RUNNING, // tux is running right
+ ENDSEQUENCE_WAITING // waiting for the end of the music
+ };
+ EndSequenceState end_sequence;
+ float last_x_pos;
+ CodeController* end_sequence_controller;
+
+ bool game_pause;
+
+ std::string levelfile;
+
+ // reset point (the point where tux respawns if he dies)
+ std::string reset_sector;
+ Vector reset_pos;
+
+ // the sector and spawnpoint we should spawn after this frame
+ std::string newsector;
+ std::string newspawnpoint;
+
+ static GameSession* current_;
+
+ // for cheating
+ std::string last_keys;
+
+ Statistics* best_level_statistics;
+
+ ExitStatus exit_status;
+};
+
+std::string slotinfo(int slot);
+
+/** Return true if the gameloop() was entered, false otherwise */
+bool process_load_game_menu();
+
+#endif /*SUPERTUX_GAMELOOP_H*/
+
--- /dev/null
+// $Id: configfile.cpp 2212 2004-11-28 14:57:45Z matzebraun $
+//
+// SuperTux - A Jump'n Run
+// Copyright (C) 2004 Michael George <mike@georgetech.com>
+//
+// 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 <config.h>
+
+#include "gameconfig.h"
+
+#include <cstdlib>
+#include <string>
+#include <stdexcept>
+#include <sstream>
+#include <fstream>
+
+#include "app/setup.h"
+#include "app/globals.h"
+#include "audio/sound_manager.h"
+#include "lisp/parser.h"
+#include "lisp/lisp.h"
+#include "lisp/writer.h"
+#include "control/joystickkeyboardcontroller.h"
+#include "main.h"
+
+using namespace SuperTux;
+
+Config* config = 0;
+
+Config::Config()
+{
+ use_fullscreen = true;
+ show_fps = false;
+ sound_enabled = true;
+ music_enabled = true;
+ cheats_enabled = false;
+
+ screenwidth = 800;
+ screenheight = 600;
+ use_gl = true;
+
+ audio_frequency = MIX_DEFAULT_FREQUENCY;
+ audio_channels = MIX_DEFAULT_CHANNELS;
+ audio_chunksize = 2048;
+ audio_voices = MIX_CHANNELS;
+}
+
+Config::~Config()
+{}
+
+void
+Config::load()
+{
+ lisp::Parser parser;
+ std::auto_ptr<lisp::Lisp> root (parser.parse(user_dir + "/config"));
+
+ const lisp::Lisp* config_lisp = root->get_lisp("supertux-config");
+ if(!config_lisp)
+ throw std::runtime_error("File is not a supertux-config file");
+
+ config_lisp->get("show_fps", show_fps);
+ config_lisp->get("cheats", cheats_enabled);
+
+ const lisp::Lisp* config_video_lisp = config_lisp->get_lisp("video");
+ if(config_video_lisp) {
+ config_video_lisp->get("fullscreen", use_fullscreen);
+ config_video_lisp->get("width", screenwidth);
+ config_video_lisp->get("height", screenheight);
+ }
+
+ const lisp::Lisp* config_audio_lisp = config_lisp->get_lisp("audio");
+ if(config_audio_lisp) {
+ config_audio_lisp->get("sound_enabled", sound_enabled);
+ config_audio_lisp->get("music_enabled", music_enabled);
+ config_audio_lisp->get("frequency", audio_frequency);
+ config_audio_lisp->get("channels", audio_channels);
+ config_audio_lisp->get("voices", audio_voices);
+ config_audio_lisp->get("chunksize", audio_chunksize);
+ }
+
+ const lisp::Lisp* config_control_lisp = config_lisp->get_lisp("control");
+ if(config_control_lisp && main_controller) {
+ main_controller->read(*config_control_lisp);
+ }
+}
+
+void
+Config::save()
+{
+ std::string configfile = user_dir + "/config";
+ std::ofstream file( (user_dir + "/config").c_str() );
+ if(!file.good()) {
+ std::stringstream msg;
+ msg << "Couldn't write config file '" << configfile << "'";
+ throw std::runtime_error(msg.str());
+ }
+ lisp::Writer writer(file);
+
+ writer.start_list("supertux-config");
+
+ writer.write_bool("show_fps", show_fps);
+ writer.write_bool("cheats", cheats_enabled);
+
+ writer.start_list("video");
+ writer.write_bool("fullscreen", use_fullscreen);
+ writer.write_int("width", screenwidth);
+ writer.write_int("height", screenheight);
+ writer.end_list("video");
+
+ writer.start_list("audio");
+ writer.write_bool("sound_enabled", sound_enabled);
+ writer.write_bool("music_enabled", music_enabled);
+ writer.write_int("frequency", audio_frequency);
+ writer.write_int("channels", audio_channels);
+ writer.write_int("voices", audio_voices);
+ writer.write_int("chunksize", audio_chunksize);
+ writer.end_list("audio");
+
+ if(main_controller) {
+ writer.start_list("control");
+ main_controller->write(writer);
+ writer.end_list("control");
+ }
+
+ writer.end_list("supertux-config");
+}
--- /dev/null
+// $Id: configfile.h 2293 2005-03-25 20:39:56Z matzebraun $
+//
+// SuperTux - A Jump'n Run
+// Copyright (C) 2004 Michael George <mike@georgetech.com>
+//
+// 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_CONFIG_H
+#define SUPERTUX_CONFIG_H
+
+#include <string>
+
+class Config {
+public:
+ Config();
+ ~Config();
+
+ void load();
+ void save();
+
+ /** screen width in pixel (warning: this is the real screen width+height,
+ * supertux is using a logical width+height and not this one)
+ */
+ int screenwidth;
+ int screenheight;
+ bool use_gl;
+
+ int audio_frequency;
+ int audio_channels;
+ int audio_voices;
+ int audio_chunksize;
+
+ bool use_fullscreen;
+ bool show_fps;
+ bool sound_enabled;
+ bool music_enabled;
+ bool cheats_enabled;
+
+ /** this variable is set if supertux should start in a specific level */
+ std::string start_level;
+};
+
+extern Config* config;
+
+#endif
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2000 Bill Kendrick <bill@newbreedsoftware.com>
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
-//
-// 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 <config.h>
-
-#include <iostream>
-#include <sstream>
-#include <cassert>
-#include <cstdio>
-#include <cstdlib>
-#include <cmath>
-#include <cstring>
-#include <cerrno>
-#include <unistd.h>
-#include <ctime>
-#include <stdexcept>
-
-#include <SDL.h>
-
-#ifndef WIN32
-#include <sys/types.h>
-#include <ctype.h>
-#endif
-
-#include "app/globals.h"
-#include "gameloop.h"
-#include "video/screen.h"
-#include "app/setup.h"
-#include "gui/menu.h"
-#include "sector.h"
-#include "level.h"
-#include "tile.h"
-#include "player_status.h"
-#include "object/particlesystem.h"
-#include "object/background.h"
-#include "object/tilemap.h"
-#include "object/camera.h"
-#include "object/player.h"
-#include "lisp/lisp.h"
-#include "lisp/parser.h"
-#include "resources.h"
-#include "app/gettext.h"
-#include "worldmap.h"
-#include "misc.h"
-#include "statistics.h"
-#include "timer.h"
-#include "object/fireworks.h"
-#include "textscroller.h"
-
-GameSession* GameSession::current_ = 0;
-
-bool compare_last(std::string& haystack, std::string needle)
-{
- int haystack_size = haystack.size();
- int needle_size = needle.size();
-
- if(haystack_size < needle_size)
- return false;
-
- if(haystack.compare(haystack_size-needle_size, needle_size, needle) == 0)
- return true;
- return false;
-}
-
-GameSession::GameSession(const std::string& levelfile_, int mode,
- Statistics* statistics)
- : level(0), currentsector(0), st_gl_mode(mode),
- end_sequence(NO_ENDSEQUENCE), levelfile(levelfile_),
- best_level_statistics(statistics)
-{
- current_ = this;
-
- game_pause = false;
- fps_fps = 0;
-
- context = new DrawingContext();
-
- restart_level();
-}
-
-void
-GameSession::restart_level()
-{
- game_pause = false;
- exit_status = ES_NONE;
- end_sequence = NO_ENDSEQUENCE;
-
- last_keys.clear();
-
- delete level;
- currentsector = 0;
-
- level = new Level;
- level->load(levelfile);
-
- 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->timelimit);
-
- if(reset_sector != "") {
- currentsector = level->get_sector(reset_sector);
- if(!currentsector) {
- std::stringstream msg;
- msg << "Couldn't find sector '" << reset_sector << "' for resetting tux.";
- throw std::runtime_error(msg.str());
- }
- currentsector->activate(reset_pos);
- } else {
- currentsector = level->get_sector("main");
- if(!currentsector)
- throw std::runtime_error("Couldn't find main sector");
- currentsector->activate("main");
- }
-
- if(st_gl_mode == ST_GL_PLAY || st_gl_mode == ST_GL_LOAD_LEVEL_FILE)
- levelintro();
-
- start_timers();
- currentsector->play_music(LEVEL_MUSIC);
-}
-
-GameSession::~GameSession()
-{
- delete level;
- delete context;
-}
-
-void
-GameSession::levelintro()
-{
- SoundManager::get()->halt_music();
-
- char str[60];
-
- DrawingContext context;
- for(Sector::GameObjects::iterator i = currentsector->gameobjects.begin();
- i != currentsector->gameobjects.end(); ++i) {
- Background* background = dynamic_cast<Background*> (*i);
- if(background) {
- background->draw(context);
- }
- }
-
-// context.draw_text(gold_text, level->get_name(), Vector(SCREEN_WIDTH/2, 160),
-// CENTER_ALLIGN, LAYER_FOREGROUND1);
- context.draw_center_text(gold_text, level->get_name(), Vector(0, 160),
- LAYER_FOREGROUND1);
-
- sprintf(str, "TUX x %d", player_status.lives);
- context.draw_text(white_text, str, Vector(SCREEN_WIDTH/2, 210),
- CENTER_ALLIGN, LAYER_FOREGROUND1);
-
- if((level->get_author().size()) && (level->get_author() != "SuperTux Team"))
- //TODO make author check case/blank-insensitive
- context.draw_text(white_small_text,
- std::string(_("contributed by ")) + level->get_author(),
- Vector(SCREEN_WIDTH/2, 350), CENTER_ALLIGN, LAYER_FOREGROUND1);
-
-
- if(best_level_statistics != NULL)
- best_level_statistics->draw_message_info(context, _("Best Level Statistics"));
-
- context.do_drawing();
-
- SDL_Event event;
- wait_for_event(event,1000,3000,true);
-}
-
-/* Reset Timers */
-void
-GameSession::start_timers()
-{
- time_left.start(level->timelimit);
- Ticks::pause_init();
-}
-
-void
-GameSession::on_escape_press()
-{
- if(currentsector->player->is_dying() || end_sequence != NO_ENDSEQUENCE)
- return; // don't let the player open the menu, when he is dying
-
- if(game_pause)
- return;
-
- if(st_gl_mode == ST_GL_TEST) {
- exit_status = ES_LEVEL_ABORT;
- } else if (!Menu::current()) {
- Menu::set_current(game_menu);
- Ticks::pause_start();
- }
-}
-
-void
-GameSession::process_events()
-{
- if (end_sequence != NO_ENDSEQUENCE)
- {
- Player& tux = *currentsector->player;
-
- tux.input.fire = false;
- tux.input.left = false;
- tux.input.right = true;
- tux.input.down = false;
-
- if (int(last_x_pos) == int(tux.get_pos().x))
- tux.input.up = true;
- else
- tux.input.up = false;
-
- last_x_pos = tux.get_pos().x;
-
- SDL_Event event;
- while (SDL_PollEvent(&event))
- {
- /* Check for menu-events, if the menu is shown */
- if (Menu::current())
- {
- Menu::current()->event(event);
- if(!Menu::current())
- Ticks::pause_stop();
- }
-
- switch(event.type)
- {
- case SDL_QUIT: /* Quit event - quit: */
- Termination::abort("Received window close", "");
- break;
-
- case SDL_KEYDOWN: /* A keypress! */
- {
- SDLKey key = event.key.keysym.sym;
-
- switch(key)
- {
- case SDLK_ESCAPE: /* Escape: Open/Close the menu: */
- on_escape_press();
- break;
- default:
- break;
- }
- }
-
- case SDL_JOYBUTTONDOWN:
- if (event.jbutton.button == joystick_keymap.start_button)
- on_escape_press();
- break;
- }
- }
- }
- else // normal mode
- {
- if(!Menu::current() && !game_pause)
- Ticks::pause_stop();
-
- SDL_Event event;
- while (SDL_PollEvent(&event))
- {
- /* Check for menu-events, if the menu is shown */
- if (Menu::current())
- {
- Menu::current()->event(event);
- if(!Menu::current())
- Ticks::pause_stop();
- }
- else
- {
- Player& tux = *currentsector->player;
-
- switch(event.type)
- {
- case SDL_QUIT: /* Quit event - quit: */
- Termination::abort("Received window close", "");
- break;
-
- case SDL_KEYDOWN: /* A keypress! */
- {
- SDLKey key = event.key.keysym.sym;
-
- if(tux.key_event(key, true))
- break;
-
- switch(key)
- {
- case SDLK_ESCAPE: /* Escape: Open/Close the menu: */
- on_escape_press();
- break;
- default:
- break;
- }
- }
- break;
- case SDL_KEYUP: /* A keyrelease! */
- {
- SDLKey key = event.key.keysym.sym;
-
- if(tux.key_event(key, false))
- break;
-
- switch(key)
- {
- case SDLK_a:
- if(debug_mode)
- {
- char buf[160];
- snprintf(buf, sizeof(buf), "P: %4.1f,%4.1f",
- tux.get_pos().x, tux.get_pos().y);
- context->draw_text(white_text, buf,
- Vector(0, SCREEN_HEIGHT - white_text->get_height()),
- LEFT_ALLIGN, LAYER_FOREGROUND1);
- context->do_drawing();
- SDL_Delay(1000);
- }
- break;
- case SDLK_p:
- if(!Menu::current())
- {
- // "lifeup" cheat activates pause cause of the 'p'
- // so work around to ignore it
- if(compare_last(last_keys, "lifeu"))
- break;
-
- if(game_pause)
- {
- game_pause = false;
- Ticks::pause_stop();
- }
- else
- {
- game_pause = true;
- Ticks::pause_start();
- }
- }
- break;
- default:
- break;
- }
- }
-
- /* Check if chacrater is ASCII */
- char ch[2];
- if((event.key.keysym.unicode & 0xFF80) == 0)
- {
- ch[0] = event.key.keysym.unicode & 0x7F;
- ch[1] = '\0';
- }
- last_keys.append(ch); // add to cheat keys
- handle_cheats();
- break;
-
- case SDL_JOYAXISMOTION:
- if (event.jaxis.axis == joystick_keymap.x_axis)
- {
- if (event.jaxis.value < -joystick_keymap.dead_zone)
- {
- tux.input.left = true;
- tux.input.right = false;
- }
- else if (event.jaxis.value > joystick_keymap.dead_zone)
- {
- tux.input.left = false;
- tux.input.right = true;
- }
- else
- {
- tux.input.left = false;
- tux.input.right = false;
- }
- }
- else if (event.jaxis.axis == joystick_keymap.y_axis)
- {
- if (event.jaxis.value > joystick_keymap.dead_zone)
- {
- tux.input.up = true;
- tux.input.down = false;
- }
- else if (event.jaxis.value < -joystick_keymap.dead_zone)
- {
- tux.input.up = false;
- tux.input.down = true;
- }
- else
- {
- tux.input.up = false;
- tux.input.down = false;
- }
- }
- break;
-
- case SDL_JOYHATMOTION:
- if(event.jhat.value & SDL_HAT_UP) {
- tux.input.up = true;
- tux.input.down = false;
- } else if(event.jhat.value & SDL_HAT_DOWN) {
- tux.input.up = false;
- tux.input.down = true;
- } else if(event.jhat.value & SDL_HAT_LEFT) {
- tux.input.left = true;
- tux.input.right = false;
- } else if(event.jhat.value & SDL_HAT_RIGHT) {
- tux.input.left = false;
- tux.input.right = true;
- } else if(event.jhat.value == SDL_HAT_CENTERED) {
- tux.input.left = false;
- tux.input.right = false;
- tux.input.up = false;
- tux.input.down = false;
- }
- break;
-
- case SDL_JOYBUTTONDOWN:
- // FIXME: I assume we have to set old_jump and stuff here?!?
- if (event.jbutton.button == joystick_keymap.a_button)
- tux.input.jump = true;
- else if (event.jbutton.button == joystick_keymap.b_button)
- tux.input.fire = true;
- else if (event.jbutton.button == joystick_keymap.start_button)
- on_escape_press();
- break;
- case SDL_JOYBUTTONUP:
- if (event.jbutton.button == joystick_keymap.a_button)
- tux.input.jump = false;
- else if (event.jbutton.button == joystick_keymap.b_button)
- tux.input.fire = false;
- break;
-
- default:
- break;
- } /* switch */
- }
- } /* while */
- }
-}
-
-void
-GameSession::handle_cheats()
-{
- Player& tux = *currentsector->player;
-
- // Cheating words (the goal of this is really for debugging,
- // but could be used for some cheating, nothing wrong with that)
- if(compare_last(last_keys, "grow")) {
- tux.set_bonus(GROWUP_BONUS, false);
- last_keys.clear();
- }
- if(compare_last(last_keys, "fire")) {
- tux.set_bonus(FIRE_BONUS, false);
- last_keys.clear();
- }
- if(compare_last(last_keys, "ice")) {
- tux.set_bonus(ICE_BONUS, false);
- last_keys.clear();
- }
- if(compare_last(last_keys, "lifeup")) {
- player_status.lives++;
- last_keys.clear();
- }
- if(compare_last(last_keys, "lifedown")) {
- player_status.lives--;
- last_keys.clear();
- }
- if(compare_last(last_keys, "grease")) {
- tux.physic.set_velocity_x(tux.physic.get_velocity_x()*3);
- last_keys.clear();
- }
- if(compare_last(last_keys, "invincible")) {
- // be invincle for the rest of the level
- tux.invincible_timer.start(10000);
- last_keys.clear();
- }
- if(compare_last(last_keys, "shrink")) {
- // remove powerups
- tux.kill(tux.SHRINK);
- last_keys.clear();
- }
- if(compare_last(last_keys, "kill")) {
- // kill Tux, but without losing a life
- player_status.lives++;
- tux.kill(tux.KILL);
- last_keys.clear();
- }
- if(compare_last(last_keys, "grid")) {
- // toggle debug grid
- debug_grid = !debug_grid;
- last_keys.clear();
- }
- if(compare_last(last_keys, "hover")) {
- // toggle hover ability on/off
- tux.enable_hover = !tux.enable_hover;
- last_keys.clear();
- }
- if(compare_last(last_keys, "gotoend")) {
- // goes to the end of the level
- tux.move(Vector(
- (currentsector->solids->get_width()*32) - (SCREEN_WIDTH*2), 0));
- currentsector->camera->reset(
- Vector(tux.get_pos().x, tux.get_pos().y));
- last_keys.clear();
- }
- if(compare_last(last_keys, "finish")) {
- // finish current sector
- exit_status = ES_LEVEL_FINISHED;
- // don't add points to stats though...
- }
- // temporary to help player's choosing a flapping
- if(compare_last(last_keys, "marek")) {
- tux.flapping_mode = Player::MAREK_FLAP;
- last_keys.clear();
- }
- if(compare_last(last_keys, "ricardo")) {
- tux.flapping_mode = Player::RICARDO_FLAP;
- last_keys.clear();
- }
- if(compare_last(last_keys, "ryan")) {
- tux.flapping_mode = Player::RYAN_FLAP;
- last_keys.clear();
- }
-}
-
-void
-GameSession::check_end_conditions()
-{
- Player* tux = currentsector->player;
-
- /* End of level? */
- if(end_sequence && endsequence_timer.check()) {
- exit_status = ES_LEVEL_FINISHED;
- return;
- } else if (!end_sequence && tux->is_dead()) {
- 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(float elapsed_time)
-{
- // advance timers
- if(!currentsector->player->growing_timer.started()) {
- // Update Tux and the World
- currentsector->action(elapsed_time);
- }
-
- // respawning in new sector?
- if(newsector != "" && newspawnpoint != "") {
- Sector* sector = level->get_sector(newsector);
- if(sector == 0) {
- std::cerr << "Sector '" << newsector << "' not found.\n";
- }
- sector->activate(newspawnpoint);
- sector->play_music(LEVEL_MUSIC);
- currentsector = sector;
- newsector = "";
- newspawnpoint = "";
- }
-}
-
-void
-GameSession::draw()
-{
- currentsector->draw(*context);
- drawstatus(*context);
-
- if(game_pause)
- draw_pause();
-
- if(Menu::current()) {
- Menu::current()->draw(*context);
- mouse_cursor->draw(*context);
- }
-
- context->do_drawing();
-}
-
-void
-GameSession::draw_pause()
-{
- int x = SCREEN_HEIGHT / 20;
- for(int i = 0; i < x; ++i) {
- context->draw_filled_rect(
- Vector(i % 2 ? (pause_menu_frame * i)%SCREEN_WIDTH :
- -((pause_menu_frame * i)%SCREEN_WIDTH)
- ,(i*20+pause_menu_frame)%SCREEN_HEIGHT),
- Vector(SCREEN_WIDTH,10),
- Color(20,20,20, rand() % 20 + 1), LAYER_FOREGROUND1+1);
- }
- context->draw_filled_rect(
- Vector(0,0), Vector(SCREEN_WIDTH, SCREEN_HEIGHT),
- Color(rand() % 50, rand() % 50, rand() % 50, 128), LAYER_FOREGROUND1);
- context->draw_text(blue_text, _("PAUSE - Press 'P' To Play"),
- Vector(SCREEN_WIDTH/2, 230), CENTER_ALLIGN, LAYER_FOREGROUND1+2);
-
- const char* str1 = _("Playing: ");
- const char* str2 = level->get_name().c_str();
-
- context->draw_text(blue_text, str1,
- Vector((SCREEN_WIDTH - (blue_text->get_text_width(str1) + white_text->get_text_width(str2)))/2, 340),
- LEFT_ALLIGN, LAYER_FOREGROUND1+2);
- context->draw_text(white_text, str2,
- Vector(((SCREEN_WIDTH - (blue_text->get_text_width(str1) + white_text->get_text_width(str2)))/2)+blue_text->get_text_width(str1), 340),
- LEFT_ALLIGN, LAYER_FOREGROUND1+2);
-}
-
-void
-GameSession::process_menu()
-{
- Menu* menu = Menu::current();
- if(menu)
- {
- menu->action();
-
- if(menu == game_menu)
- {
- switch (game_menu->check())
- {
- case MNID_CONTINUE:
- Ticks::pause_stop();
- break;
- case MNID_ABORTLEVEL:
- Ticks::pause_stop();
- exit_status = ES_LEVEL_ABORT;
- break;
- }
- }
- else if(menu == options_menu)
- {
- process_options_menu();
- }
- else if(menu == load_game_menu )
- {
- process_load_game_menu();
- }
- }
-}
-
-
-GameSession::ExitStatus
-GameSession::run()
-{
- Menu::set_current(0);
- current_ = this;
-
- int fps_cnt = 0;
- double fps_nextframe_ticks; // fps regulating code
-
- // Eat unneeded events
- SDL_Event event;
- while(SDL_PollEvent(&event))
- {}
-
- draw();
-
- Uint32 lastticks = SDL_GetTicks();
- fps_ticks = SDL_GetTicks();
- fps_nextframe_ticks = SDL_GetTicks(); // fps regulating code
-
- while (exit_status == ES_NONE) {
- Uint32 ticks = SDL_GetTicks();
- float elapsed_time = float(ticks - lastticks) / 1000.;
- if(!game_pause)
- global_time += elapsed_time;
- lastticks = ticks;
-
- // 40fps is minimum
- if(elapsed_time > 0.025){
- elapsed_time = 0.025;
- }
-
- // fps regualting code
- const double wantedFps= 60.0; // set to 60 by now
- while (fps_nextframe_ticks > SDL_GetTicks()){
- /* just wait */
- // If we really have to wait long, then do an imprecise SDL_Delay()
- if (fps_nextframe_ticks - SDL_GetTicks() > 15){
- SDL_Delay(5);
- }
-
- }
- float diff = SDL_GetTicks() - fps_nextframe_ticks;
- if (diff > 5.0)
- fps_nextframe_ticks = SDL_GetTicks() + (1000.0 / wantedFps); // sets the ticks that must have elapsed
- else
- fps_nextframe_ticks += 1000.0 / wantedFps; // sets the ticks that must have elapsed
- // in order for the next frame to start.
-
-
- /* Handle events: */
- currentsector->player->input.old_fire = currentsector->player->input.fire;
- currentsector->player->input.old_up = currentsector->player->input.old_up;
-
- 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(elapsed_time/2);
- else if(end_sequence == NO_ENDSEQUENCE)
- action(elapsed_time);
- }
- else
- {
- ++pause_menu_frame;
- SDL_Delay(50);
- }
-
- draw();
-
- /* Time stops in pause mode */
- if(game_pause || Menu::current())
- {
- continue;
- }
-
- //frame_rate.update();
-
- /* Handle time: */
- if (time_left.check() && !end_sequence)
- currentsector->player->kill(Player::KILL);
-
- /* Handle music: */
- if (currentsector->player->invincible_timer.started() && !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);
- }
-
- /* 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;
-}
-
-void
-GameSession::respawn(const std::string& sector, const std::string& spawnpoint)
-{
- newsector = sector;
- newspawnpoint = spawnpoint;
-}
-
-void
-GameSession::set_reset_point(const std::string& sector, const Vector& pos)
-{
- reset_sector = sector;
- reset_pos = pos;
-}
-
-void
-GameSession::display_info_box(const std::string& text)
-{
- InfoBox* box = new InfoBox(text);
-
- bool running = true;
- while(running) {
- SDL_Event event;
- while (SDL_PollEvent(&event)) {
- switch(event.type) {
- case SDL_KEYDOWN:
- running = false;
- break;
- }
- }
-
- box->draw(*context);
- draw();
- }
-
- delete box;
-}
-
-void
-GameSession::start_sequence(const std::string& sequencename)
-{
- if(sequencename == "endsequence" || sequencename == "fireworks") {
- 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(sequencename == "fireworks") {
- currentsector->add_object(new Fireworks());
- }
- } else if(sequencename == "stoptux") {
- end_sequence = ENDSEQUENCE_WAITING;
- } else {
- std::cout << "Unknown sequence '" << sequencename << "'.\n";
- }
-}
-
-/* (Status): */
-void
-GameSession::drawstatus(DrawingContext& context)
-{
- char str[60];
-
- snprintf(str, 60, " %d", global_stats.get_points(SCORE_STAT));
- context.draw_text(white_text, _("SCORE"), Vector(0, 0), LEFT_ALLIGN, LAYER_FOREGROUND1);
- context.draw_text(gold_text, str, Vector(96, 0), LEFT_ALLIGN, LAYER_FOREGROUND1);
-
- if(st_gl_mode == ST_GL_TEST)
- {
- context.draw_text(white_text, _("Press ESC To Return"), Vector(0,20),
- LEFT_ALLIGN, LAYER_FOREGROUND1);
- }
-
- if(time_left.get_timeleft() < 0) {
- context.draw_text(white_text, _("TIME's UP"), Vector(SCREEN_WIDTH/2, 0),
- CENTER_ALLIGN, LAYER_FOREGROUND1);
- } else if (time_left.get_timeleft() > TIME_WARNING
- || int(global_time * 2.5) % 2) {
- sprintf(str, " %d", int(time_left.get_timeleft()));
- context.draw_text(white_text, _("TIME"),
- Vector(SCREEN_WIDTH/2, 0), CENTER_ALLIGN, LAYER_FOREGROUND1);
- context.draw_text(gold_text, str,
- Vector(SCREEN_WIDTH/2 + 4*16, 0), CENTER_ALLIGN, LAYER_FOREGROUND1);
- }
-
- sprintf(str, " %d", player_status.distros);
- context.draw_text(white_text, _("COINS"),
- Vector(SCREEN_WIDTH - white_text->get_text_width(_("COINS"))-white_text->get_text_width(" 99"), 0),
- LEFT_ALLIGN, LAYER_FOREGROUND1);
- context.draw_text(gold_text, str,
- Vector(SCREEN_WIDTH - gold_text->get_text_width(" 99"), 0),LEFT_ALLIGN, LAYER_FOREGROUND1);
-
- if (player_status.lives >= 5)
- {
- sprintf(str, "%dx", player_status.lives);
- float x = SCREEN_WIDTH - gold_text->get_text_width(str) - tux_life->w;
- context.draw_text(gold_text, str, Vector(x, 20), LEFT_ALLIGN, LAYER_FOREGROUND1);
- context.draw_surface(tux_life, Vector(SCREEN_WIDTH - 16, 20),
- LAYER_FOREGROUND1);
- }
- else
- {
- for(int i= 0; i < player_status.lives; ++i)
- context.draw_surface(tux_life,
- Vector(SCREEN_WIDTH - tux_life->w*4 +(tux_life->w*i), 20),
- LAYER_FOREGROUND1);
- }
-
- context.draw_text(white_text, _("LIVES"),
- Vector(SCREEN_WIDTH - white_text->get_text_width(_("LIVES")) - white_text->get_text_width(" 99"), 20),
- LEFT_ALLIGN, LAYER_FOREGROUND1);
-
- if(show_fps)
- {
- sprintf(str, "%2.1f", fps_fps);
- context.draw_text(white_text, "FPS",
- Vector(SCREEN_WIDTH - white_text->get_text_width("FPS "), 40),
- LEFT_ALLIGN, LAYER_FOREGROUND1);
- context.draw_text(gold_text, str,
- Vector(SCREEN_WIDTH-4*16, 40), LEFT_ALLIGN, LAYER_FOREGROUND1);
- }
-}
-
-void
-GameSession::drawresultscreen()
-{
- char str[80];
-
- DrawingContext context;
- for(Sector::GameObjects::iterator i = currentsector->gameobjects.begin();
- i != currentsector->gameobjects.end(); ++i) {
- Background* background = dynamic_cast<Background*> (*i);
- if(background) {
- background->draw(context);
- }
- }
-
- context.draw_text(blue_text, _("Result:"), Vector(SCREEN_WIDTH/2, 200),
- CENTER_ALLIGN, LAYER_FOREGROUND1);
-
- sprintf(str, _("SCORE: %d"), global_stats.get_points(SCORE_STAT));
- context.draw_text(gold_text, str, Vector(SCREEN_WIDTH/2, 224), CENTER_ALLIGN, LAYER_FOREGROUND1);
-
- sprintf(str, _("COINS: %d"), player_status.distros);
- context.draw_text(gold_text, str, Vector(SCREEN_WIDTH/2, 256), CENTER_ALLIGN, LAYER_FOREGROUND1);
-
- context.do_drawing();
-
- SDL_Event event;
- wait_for_event(event,2000,5000,true);
-}
-
-std::string slotinfo(int slot)
-{
- std::string tmp;
- std::string slotfile;
- std::string title;
- std::stringstream stream;
- stream << slot;
- slotfile = st_save_dir + "/slot" + stream.str() + ".stsg";
-
- try {
- lisp::Parser parser;
- std::auto_ptr<lisp::Lisp> root (parser.parse(slotfile));
-
- const lisp::Lisp* savegame = root->get_lisp("supertux-savegame");
- if(!savegame)
- throw std::runtime_error("file is not a supertux-savegame.");
-
- savegame->get("title", title);
- } catch(std::exception& e) {
- return std::string(_("Slot")) + " " + stream.str() + " - " +
- std::string(_("Free"));
- }
-
- return std::string("Slot ") + stream.str() + " - " + title;
-}
-
-bool process_load_game_menu()
-{
- int slot = load_game_menu->check();
-
- if(slot != -1 && load_game_menu->get_item_by_id(slot).kind == MN_ACTION)
- {
- std::stringstream stream;
- stream << slot;
- std::string slotfile = st_save_dir + "/slot" + stream.str() + ".stsg";
-
- fadeout(256);
- DrawingContext context;
- context.draw_text(white_text, "Loading...",
- Vector(SCREEN_WIDTH/2, SCREEN_HEIGHT/2), CENTER_ALLIGN, LAYER_FOREGROUND1);
- context.do_drawing();
-
- WorldMapNS::WorldMap worldmap;
-
- worldmap.set_map_filename("/levels/world1/worldmap.stwm");
- // Load the game or at least set the savegame_file variable
- worldmap.loadgame(slotfile);
-
- worldmap.display();
-
- Menu::set_current(main_menu);
-
- Ticks::pause_stop();
- return true;
- }
- else
- {
- return false;
- }
-}
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Bill Kendrick <bill@newbreedsoftware.com>
-// Tobias Glaesser <tobi.web@gmx.de>
-// Ingo Ruhnke <grumbel@gmx.de>
-//
-// 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_GAMELOOP_H
-#define SUPERTUX_GAMELOOP_H
-
-#include <SDL.h>
-#include "timer.h"
-#include "statistics.h"
-
-using namespace SuperTux;
-
-/* GameLoop modes */
-
-#define ST_GL_PLAY 0
-#define ST_GL_TEST 1
-#define ST_GL_LOAD_GAME 2
-#define ST_GL_LOAD_LEVEL_FILE 3
-#define ST_GL_DEMO_GAME 4
-
-enum GameMenuIDs {
- MNID_CONTINUE,
- MNID_ABORTLEVEL
- };
-
-extern int game_started;
-
-class Level;
-class Sector;
-class Statistics;
-
-namespace SuperTux {
-class DrawingContext;
-}
-
-/** The GameSession class controlls the controll flow of a World, ie.
- present the menu on specifc keypresses, render and update it while
- keeping the speed and framerate sane, etc. */
-class GameSession
-{
-public:
- enum ExitStatus { ES_NONE, ES_LEVEL_FINISHED, ES_GAME_OVER, ES_LEVEL_ABORT };
-
-public:
- DrawingContext* context;
- Timer2 time_left;
-
- GameSession(const std::string& levelfile, int mode, Statistics* statistics=0);
- ~GameSession();
-
- /** Enter the busy loop */
- ExitStatus run();
-
- void draw();
- void action(float frame_ratio);
-
- void set_current()
- { current_ = this; }
- static GameSession* current() { return current_; }
-
- void respawn(const std::string& sectorname,
- const std::string& spawnpointname);
- void set_reset_point(const std::string& sectorname,
- const Vector& pos);
- void display_info_box(const std::string& text);
- Sector* get_current_sector()
- { return currentsector; }
-
- void start_sequence(const std::string& sequencename);
-
-private:
- void restart_level();
-
- void check_end_conditions();
- void start_timers();
- void process_events();
- void handle_cheats();
-
- void levelintro();
- void drawstatus(DrawingContext& context);
- void drawendscreen();
- void drawresultscreen();
- void draw_pause();
-
- void on_escape_press();
- void process_menu();
-
- Uint32 fps_ticks;
- Timer2 endsequence_timer;
- Level* level;
- Sector* currentsector;
-
- int st_gl_mode;
- int levelnb;
- float fps_fps;
- int pause_menu_frame;
-
- /** If true the end_sequence will be played, user input will be
- ignored while doing that */
- enum EndSequenceState {
- NO_ENDSEQUENCE,
- ENDSEQUENCE_RUNNING, // tux is running right
- ENDSEQUENCE_WAITING // waiting for the end of the music
- };
- EndSequenceState end_sequence;
- float last_x_pos;
-
- bool game_pause;
-
- std::string levelfile;
-
- // reset point (the point where tux respawns if he dies)
- std::string reset_sector;
- Vector reset_pos;
-
- // the sector and spawnpoint we should spawn after this frame
- std::string newsector;
- std::string newspawnpoint;
-
- static GameSession* current_;
-
- // for cheating
- std::string last_keys;
-
- Statistics* best_level_statistics;
-
- ExitStatus exit_status;
-};
-
-std::string slotinfo(int slot);
-
-/** Return true if the gameloop() was entered, false otherwise */
-bool process_load_game_menu();
-
-#endif /*SUPERTUX_GAMELOOP_H*/
-
--- /dev/null
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
+
+#include "SDL.h"
+#include <iostream>
+
+#include "button.h"
+#include "mousecursor.h"
+#include "app/globals.h"
+#include "video/font.h"
+#include "video/surface.h"
+
+using namespace SuperTux;
+
+Font* Button::info_font = 0;
+extern SDL_Surface* screen;
+
+/* Buttons */
+
+Button::Button(Surface* image_, std::string info_, SDLKey binding_)
+ : binding(binding_)
+{
+ image = image_;
+ size = Vector(image->w, image->h);
+ id = 0;
+ info = info_;
+}
+
+Button::~Button()
+{
+}
+
+void Button::draw(DrawingContext &context, bool selected)
+{
+if(selected)
+ context.draw_filled_rect(pos, size, Color (200,240,220), LAYER_GUI);
+else
+ context.draw_filled_rect(pos, size, Color (200,200,220), LAYER_GUI);
+
+Vector tanslation = -context.get_translation();
+if(state == BT_SHOW_INFO)
+ {
+ Vector offset;
+ if(pos.x + tanslation.x < 100 && pos.y + tanslation.y > SCREEN_HEIGHT - 20)
+ offset = Vector(size.x, - 10);
+ else if(pos.x + tanslation.x < 100)
+ offset = Vector(size.x, 0);
+ else
+ offset = Vector(-30, -size.y/2);
+ context.draw_text(info_font, info, pos + offset, LEFT_ALLIGN, LAYER_GUI+2);
+ if(binding != 0)
+ context.draw_text(info_font, "(" + std::string(SDL_GetKeyName(binding)) +
+ ")", pos + offset + Vector(0,12),
+ LEFT_ALLIGN, LAYER_GUI+2);
+ }
+
+context.draw_surface_part(image, Vector(0,0), size, pos, LAYER_GUI+1);
+}
+
+int Button::event(SDL_Event &event, int x_offset, int y_offset)
+{
+state = BT_NONE;
+switch(event.type)
+ {
+ case SDL_MOUSEBUTTONDOWN:
+ if(event.button.x > pos.x + x_offset && event.button.x < pos.x + x_offset + size.x &&
+ event.button.y > pos.y + y_offset && event.button.y < pos.y + y_offset + size.y)
+ {
+ if(event.button.button == SDL_BUTTON_RIGHT)
+ state = BT_SHOW_INFO;
+ }
+ break;
+ case SDL_MOUSEBUTTONUP:
+ if(event.button.x > pos.x + x_offset && event.button.x < pos.x + x_offset + size.x &&
+ event.button.y > pos.y + y_offset && event.button.y < pos.y + y_offset + size.y)
+ {
+ if(event.button.button == SDL_BUTTON_LEFT)
+ state = BT_SELECTED;
+ }
+ break;
+ case SDL_KEYDOWN: // key pressed
+ if(event.key.keysym.sym == binding)
+ state = BT_SELECTED;
+ break;
+ default:
+ break;
+ }
+return state;
+}
+
+/* Group of buttons */
+
+ButtonGroup::ButtonGroup(Vector pos_, Vector buttons_size_, Vector buttons_box_)
+ : pos(pos_), buttons_size(buttons_size_), buttons_box(buttons_box_)
+{
+buttons.clear();
+row = 0;
+button_selected = -1;
+mouse_hover = false;
+mouse_left_button = false;
+buttons_pair_nb = 0;
+}
+
+ButtonGroup::~ButtonGroup()
+{
+}
+
+void ButtonGroup::add_button(Button button, int id, bool select)
+{
+button.pos.x = ((buttons.size()-buttons_pair_nb) % (int)buttons_box.x) * buttons_size.x;
+button.pos.y = ((int)((buttons.size()-buttons_pair_nb) / buttons_box.x)) * buttons_size.y;
+button.size = buttons_size;
+button.id = id;
+if(select)
+ button_selected = id;
+
+buttons.push_back(button);
+}
+
+void ButtonGroup::add_pair_of_buttons(Button button1, int id1, Button button2, int id2)
+{
+button1.pos.x = button2.pos.x = ((buttons.size()-buttons_pair_nb) % (int)buttons_box.x) * buttons_size.x;
+button1.pos.y = button2.pos.y = ((int)((buttons.size()-buttons_pair_nb) / buttons_box.x)) * buttons_size.y;
+button1.size.x = button2.size.x = buttons_size.x;
+button1.size.y = button2.size.y = buttons_size.y / 2;
+button2.pos.y += buttons_size.y / 2;
+button1.id = id1;
+button2.id = id2;
+
+buttons_pair_nb++;
+buttons.push_back(button1);
+buttons.push_back(button2);
+}
+
+void ButtonGroup::draw(DrawingContext &context)
+{
+context.draw_filled_rect(pos - Vector(12,4),
+ Vector(buttons_size.x*buttons_box.x + 16, buttons_size.y*buttons_box.y + 8),
+ Color (0,0,0, 128), LAYER_GUI-1);
+
+context.push_transform();
+context.set_translation(Vector(-pos.x, -pos.y + buttons_size.y*row));
+for(Buttons::iterator i = buttons.begin(); i != buttons.end(); ++i)
+ {
+ if(i->pos.y < row*buttons_size.y ||
+ i->pos.y + i->size.y > (row + buttons_box.y) * buttons_size.y)
+ continue;
+
+ i->draw(context, i->id == button_selected ? true : false);
+ }
+context.pop_transform();
+}
+
+bool ButtonGroup::event(SDL_Event &event)
+{
+bool caught_event = false;
+
+switch(event.type)
+ {
+ case SDL_MOUSEMOTION:
+ mouse_hover = false;
+
+ if(mouse_left_button)
+ {
+ pos.x += int(event.motion.xrel * float(SCREEN_WIDTH)/screen->w);
+ pos.y += int(event.motion.yrel * float(SCREEN_HEIGHT)/screen->h);
+ caught_event = true;
+ }
+ if(event.button.x > pos.x-12 && event.button.x < pos.x+16 + buttons_box.x*buttons_size.x &&
+ event.button.y > pos.y-4 && event.button.y < pos.y+8 + buttons_box.y*buttons_size.y)
+ mouse_hover = true;
+ break;
+ case SDL_MOUSEBUTTONDOWN:
+ if(event.button.x < pos.x-12 || event.button.x > pos.x+16 +
+ buttons_box.x*buttons_size.x || event.button.y < pos.y-4 ||
+ event.button.y > pos.y+8 + buttons_box.y*buttons_size.y)
+ break;
+
+ caught_event = true;
+
+ if(event.button.button == SDL_BUTTON_WHEELUP)
+ {
+ row--;
+ if(row < 0)
+ row = 0;
+ }
+ else if(event.button.button == SDL_BUTTON_WHEELDOWN)
+ {
+ row++;
+ if(row > (int)((buttons.size()-buttons_pair_nb)/buttons_box.x) - (int)buttons_box.y +
+ ((int)(buttons.size()-buttons_pair_nb)%(int)buttons_box.x != 0 ? 1 : 0))
+ row = (int)((buttons.size()-buttons_pair_nb)/buttons_box.x) - (int)buttons_box.y +
+ ((int)(buttons.size()-buttons_pair_nb)%(int)buttons_box.x != 0 ? 1 : 0);
+ }
+ else if(event.button.button == SDL_BUTTON_LEFT)
+ mouse_left_button = true;
+ else
+ caught_event = false;
+ break;
+ case SDL_MOUSEBUTTONUP:
+ mouse_left_button = false;
+ break;
+ default:
+ break;
+ }
+
+if(caught_event)
+ return true;
+
+for(Buttons::iterator i = buttons.begin(); i != buttons.end(); ++i)
+ {
+ if(i->pos.y < row*buttons_size.y ||
+ i->pos.y + i->size.y > (row + buttons_box.y) * buttons_size.y)
+ continue;
+
+ if(i->event(event, (int)pos.x,
+ (int)pos.y - row*(int)buttons_size.y) == BT_SELECTED)
+ {
+ button_selected = i->id;
+ caught_event = true;
+ break;
+ }
+ }
+
+return caught_event;
+}
+
+int ButtonGroup::selected_id()
+{
+return button_selected;
+}
+
+void ButtonGroup::set_unselected()
+{
+button_selected = -1;
+}
+
+bool ButtonGroup::is_hover()
+{
+return mouse_hover;
+}
--- /dev/null
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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_BUTTON_H
+#define SUPERTUX_BUTTON_H
+
+#include <vector>
+#include <string>
+
+#include "math/vector.h"
+#include "video/drawing_context.h"
+
+class Surface;
+
+namespace SuperTux
+ {
+class ButtonGroup;
+
+enum {
+ BT_NONE,
+ BT_HOVER,
+ BT_SELECTED,
+ BT_SHOW_INFO
+ };
+
+class Button
+{
+public:
+ Button(Surface* image_, std::string info_, SDLKey binding_);
+ ~Button();
+
+ void draw(DrawingContext& context, bool selected);
+ int event(SDL_Event& event, int x_offset = 0, int y_offset = 0);
+
+ static Font* info_font;
+
+private:
+ friend class ButtonGroup;
+
+ Vector pos, size;
+
+ Surface* image;
+ SDLKey binding;
+
+ int id;
+ int state;
+ std::string info;
+};
+
+class ButtonGroup
+{
+public:
+ ButtonGroup(Vector pos_, Vector size_, Vector button_box_);
+ ~ButtonGroup();
+
+ void draw(DrawingContext& context);
+ bool event(SDL_Event& event);
+
+ void add_button(Button button, int id, bool select = false);
+ void add_pair_of_buttons(Button button1, int id1, Button button2, int id2);
+
+ int selected_id();
+ void set_unselected();
+ bool is_hover();
+
+private:
+ Vector pos, buttons_size, buttons_box;
+ typedef std::vector <Button> Buttons;
+ Buttons buttons;
+
+ int button_selected, row;
+ bool mouse_hover, mouse_left_button;
+
+ int buttons_pair_nb;
+};
+
+} //namespace SuperTux
+
+#endif
--- /dev/null
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
+//
+// 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 <config.h>
+
+#include <sys/types.h>
+#include <ctype.h>
+
+#include <iostream>
+#include <sstream>
+#include <cstdlib>
+#include <cstdio>
+#include <string>
+#include <cassert>
+#include <stdexcept>
+
+#include "app/globals.h"
+#include "menu.h"
+#include "video/screen.h"
+#include "video/drawing_context.h"
+#include "app/setup.h"
+#include "app/gettext.h"
+#include "math/vector.h"
+#include "main.h"
+#include "control/joystickkeyboardcontroller.h"
+
+static const int MENU_REPEAT_INITIAL = 400;
+static const int MENU_REPEAT_RATE = 200;
+static const int FLICK_CURSOR_TIME=500;
+
+extern SDL_Surface* screen;
+
+using namespace SuperTux;
+
+Surface* checkbox;
+Surface* checkbox_checked;
+Surface* back;
+Surface* arrow_left;
+Surface* arrow_right;
+
+std::vector<Menu*> Menu::last_menus;
+Menu* Menu::current_ = 0;
+Font* Menu::default_font;
+Font* Menu::active_font;
+Font* Menu::deactive_font;
+Font* Menu::label_font;
+Font* Menu::field_font;
+
+/* just displays a Yes/No text that can be used to confirm stuff */
+bool confirm_dialog(Surface *background, std::string text)
+{
+ //Surface* cap_screen = Surface::CaptureScreen();
+ Menu* dialog = new Menu;
+ dialog->add_deactive(-1, text);
+ dialog->add_hl();
+ dialog->add_entry(true, _("Yes"));
+ dialog->add_entry(false, _("No"));
+ dialog->add_hl();
+
+ Menu::set_current(dialog);
+
+ DrawingContext context;
+
+ while(true)
+ {
+ SDL_Event event;
+
+ if(event.type == SDL_QUIT)
+ throw std::runtime_error("received window close event");
+
+ while (SDL_PollEvent(&event)) {
+ dialog->event(event);
+ }
+
+ if(background == NULL)
+ context.draw_gradient(Color(200,240,220), Color(200,200,220), LAYER_BACKGROUND0);
+ else
+ context.draw_surface(background, Vector(0,0), LAYER_BACKGROUND0);
+
+ dialog->draw(context);
+ dialog->action();
+
+ switch (dialog->check())
+ {
+ case true:
+ //delete cap_screen;
+ Menu::set_current(0);
+ delete dialog;
+ return true;
+ break;
+ case false:
+ //delete cap_screen;
+ Menu::set_current(0);
+ delete dialog;
+ return false;
+ break;
+ default:
+ break;
+ }
+
+ mouse_cursor->draw(context);
+ context.do_drawing();
+ SDL_Delay(25);
+ }
+
+ return false;
+}
+
+void
+Menu::push_current(Menu* pmenu)
+{
+ if (current_)
+ last_menus.push_back(current_);
+
+ current_ = pmenu;
+ current_->effect.start(500);
+}
+
+void
+Menu::pop_current()
+{
+ if (last_menus.size() >= 1) {
+ current_ = last_menus.back();
+ current_->effect.start(500);
+
+ last_menus.pop_back();
+ }
+}
+
+void
+Menu::set_current(Menu* menu)
+{
+ last_menus.clear();
+
+ if (menu)
+ menu->effect.start(500);
+
+ current_ = menu;
+ // just to be sure...
+ main_controller->reset();
+}
+
+MenuItem::MenuItem(MenuItemKind _kind, int _id)
+ : kind(_kind) , id(_id)
+{
+ toggled = false;
+ selected = false;
+ target_menu = 0;
+ input_flickering = false;
+ input_flickering_timer.init(true);
+ input_flickering_timer.start(FLICK_CURSOR_TIME);
+}
+
+void
+MenuItem::change_text(const std::string& text_)
+{
+ text = text_;
+}
+
+void
+MenuItem::change_input(const std::string& text_)
+{
+ input = text_;
+}
+
+std::string MenuItem::get_input_with_symbol(bool active_item)
+{
+ if(!active_item)
+ input_flickering = true;
+ else
+ {
+ if(input_flickering_timer.get_left() < 0)
+ {
+ if(input_flickering)
+ input_flickering = false;
+ else
+ input_flickering = true;
+ input_flickering_timer.start(FLICK_CURSOR_TIME);
+ }
+ }
+
+ char str[1024];
+ if(input_flickering)
+ sprintf(str,"%s ",input.c_str());
+ else
+ sprintf(str,"%s_",input.c_str());
+
+ std::string string = str;
+
+ return string;
+}
+
+Menu::~Menu()
+{
+ for(std::vector<MenuItem*>::iterator i = items.begin();
+ i != items.end(); ++i)
+ delete *i;
+}
+
+Menu::Menu()
+{
+ hit_item = -1;
+ menuaction = MENU_ACTION_NONE;
+ delete_character = 0;
+ mn_input_char = '\0';
+
+ pos_x = SCREEN_WIDTH/2;
+ pos_y = SCREEN_HEIGHT/2;
+ arrange_left = 0;
+ active_item = -1;
+ effect.init(false);
+
+ repeat_timer.init(true);
+}
+
+void Menu::set_pos(int x, int y, float rw, float rh)
+{
+ pos_x = x + (int)((float)get_width() * rw);
+ pos_y = y + (int)((float)get_height() * rh);
+}
+
+/* Add an item to a menu */
+void
+Menu::additem(MenuItem* item)
+{
+ items.push_back(item);
+
+ /* If a new menu is being built, the active item shouldn't be set to
+ * something that isnt selectable. Set the active_item to the first
+ * selectable item added
+ */
+ if (active_item == -1
+ && item->kind != MN_HL
+ && item->kind != MN_LABEL
+ && item->kind != MN_DEACTIVE) {
+ active_item = items.size() - 1;
+ }
+}
+
+void
+Menu::add_hl()
+{
+ additem(new MenuItem(MN_HL));
+}
+
+void
+Menu::add_label(const std::string& text)
+{
+ MenuItem* item = new MenuItem(MN_LABEL);
+ item->text = text;
+ additem(item);
+}
+
+void
+Menu::add_controlfield(int id, const std::string& text,
+ const std::string& mapping)
+{
+ MenuItem* item = new MenuItem(MN_CONTROLFIELD, id);
+ item->change_text(text);
+ item->change_input(mapping);
+ additem(item);
+}
+
+void
+Menu::add_entry(int id, const std::string& text)
+{
+ MenuItem* item = new MenuItem(MN_ACTION, id);
+ item->text = text;
+ additem(item);
+}
+
+void
+Menu::add_deactive(int id, const std::string& text)
+{
+ MenuItem* item = new MenuItem(MN_DEACTIVE, id);
+ item->text = text;
+ additem(item);
+}
+
+void
+Menu::add_toggle(int id, const std::string& text, bool toogled)
+{
+ MenuItem* item = new MenuItem(MN_TOGGLE, id);
+ item->text = text;
+ item->toggled = toogled;
+ additem(item);
+}
+
+void
+Menu::add_back(const std::string& text)
+{
+ MenuItem* item = new MenuItem(MN_BACK);
+ item->text = text;
+ additem(item);
+}
+
+void
+Menu::add_submenu(const std::string& text, Menu* submenu, int id)
+{
+ MenuItem* item = new MenuItem(MN_GOTO, id);
+ item->text = text;
+ item->target_menu = submenu;
+ additem(item);
+}
+
+void
+Menu::clear()
+{
+ for(std::vector<MenuItem*>::iterator i = items.begin();
+ i != items.end(); ++i) {
+ delete *i;
+ }
+ items.clear();
+ active_item = -1;
+}
+
+/* Process actions done on the menu */
+void
+Menu::action()
+{
+ /** check main input controller... */
+ if(main_controller->pressed(Controller::UP)) {
+ menuaction = MENU_ACTION_UP;
+ repeat_timer.start(MENU_REPEAT_INITIAL);
+ }
+ if(main_controller->hold(Controller::UP) && !repeat_timer.check()) {
+ menuaction = MENU_ACTION_UP;
+ repeat_timer.start(MENU_REPEAT_RATE);
+ }
+ if(main_controller->pressed(Controller::DOWN)) {
+ menuaction = MENU_ACTION_DOWN;
+ repeat_timer.start(MENU_REPEAT_INITIAL);
+ }
+ if(main_controller->hold(Controller::DOWN) && !repeat_timer.check()) {
+ menuaction = MENU_ACTION_DOWN;
+ repeat_timer.start(MENU_REPEAT_RATE);
+ }
+ if(main_controller->pressed(Controller::JUMP)
+ || main_controller->pressed(Controller::ACTION)
+ || main_controller->pressed(Controller::MENU_SELECT)) {
+ menuaction = MENU_ACTION_HIT;
+ }
+ if(main_controller->pressed(Controller::PAUSE_MENU)) {
+ menuaction = MENU_ACTION_BACK;
+ }
+
+ hit_item = -1;
+ if(items.size() == 0)
+ return;
+
+ int last_active_item = active_item;
+ switch(menuaction) {
+ case MENU_ACTION_UP:
+ do {
+ if (active_item > 0)
+ --active_item;
+ else
+ active_item = int(items.size())-1;
+ } while ((items[active_item]->kind == MN_HL
+ || items[active_item]->kind == MN_LABEL
+ || items[active_item]->kind == MN_DEACTIVE)
+ && (active_item != last_active_item));
+
+ break;
+
+ case MENU_ACTION_DOWN:
+ do {
+ if(active_item < int(items.size())-1 )
+ ++active_item;
+ else
+ active_item = 0;
+ } while ((items[active_item]->kind == MN_HL
+ || items[active_item]->kind == MN_LABEL
+ || items[active_item]->kind == MN_DEACTIVE)
+ && (active_item != last_active_item));
+
+ break;
+
+ case MENU_ACTION_LEFT:
+ if(items[active_item]->kind == MN_STRINGSELECT) {
+ if(items[active_item]->selected > 0)
+ items[active_item]->selected--;
+ else
+ items[active_item]->selected = items[active_item]->list.size()-1;
+ }
+ break;
+
+ case MENU_ACTION_RIGHT:
+ if(items[active_item]->kind == MN_STRINGSELECT) {
+ if(items[active_item]->selected+1 < items[active_item]->list.size())
+ items[active_item]->selected++;
+ else
+ items[active_item]->selected = 0;
+ }
+ break;
+
+ case MENU_ACTION_HIT: {
+ hit_item = active_item;
+ switch (items[active_item]->kind) {
+ case MN_GOTO:
+ assert(items[active_item]->target_menu != 0);
+ Menu::push_current(items[active_item]->target_menu);
+ break;
+
+ case MN_TOGGLE:
+ items[active_item]->toggled = !items[active_item]->toggled;
+ menu_action(items[active_item]);
+ break;
+
+ case MN_CONTROLFIELD:
+ menu_action(items[active_item]);
+ break;
+
+ case MN_ACTION:
+ menu_action(items[active_item]);
+ break;
+
+ case MN_TEXTFIELD:
+ case MN_NUMFIELD:
+ menuaction = MENU_ACTION_DOWN;
+ action();
+ break;
+
+ case MN_BACK:
+ Menu::pop_current();
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+
+ case MENU_ACTION_REMOVE:
+ if(items[active_item]->kind == MN_TEXTFIELD
+ || items[active_item]->kind == MN_NUMFIELD)
+ {
+ if(!items[active_item]->input.empty())
+ {
+ int i = items[active_item]->input.size();
+
+ while(delete_character > 0) /* remove charactes */
+ {
+ items[active_item]->input.resize(i-1);
+ delete_character--;
+ }
+ }
+ }
+ break;
+
+ case MENU_ACTION_INPUT:
+ if(items[active_item]->kind == MN_TEXTFIELD
+ || (items[active_item]->kind == MN_NUMFIELD
+ && mn_input_char >= '0' && mn_input_char <= '9'))
+ {
+ items[active_item]->input.push_back(mn_input_char);
+ }
+ break;
+
+ case MENU_ACTION_BACK:
+ Menu::pop_current();
+ break;
+
+ case MENU_ACTION_NONE:
+ break;
+ }
+ menuaction = MENU_ACTION_NONE;
+
+ assert(active_item < int(items.size()));
+}
+
+int
+Menu::check()
+{
+ if (hit_item != -1)
+ return items[hit_item]->id;
+ else
+ return -1;
+}
+
+void
+Menu::menu_action(MenuItem* )
+{}
+
+void
+Menu::draw_item(DrawingContext& context, int index)
+{
+ int menu_height = get_height();
+ int menu_width = get_width();
+
+ MenuItem& pitem = *(items[index]);
+
+ int effect_offset = 0;
+ {
+ int effect_time = 0;
+
+ if(effect.check())
+ effect_time = effect.get_left() / 4;
+
+ effect_offset = (index % 2) ? effect_time : -effect_time;
+ }
+
+ Font* text_font = default_font;
+ int x_pos = pos_x;
+ int y_pos = pos_y + 24*index - menu_height/2 + 12 + effect_offset;
+ int shadow_size = 2;
+ int text_width = int(text_font->get_text_width(pitem.text));
+ int input_width = int(text_font->get_text_width(pitem.input) + 10);
+ int list_width = 0;
+ if(pitem.list.size() > 0) {
+ list_width = (int) text_font->get_text_width(pitem.list[pitem.selected]);
+ }
+
+ if (arrange_left)
+ x_pos += 24 - menu_width/2 + (text_width + input_width + list_width)/2;
+
+ if(index == active_item)
+ {
+ shadow_size = 3;
+ text_font = active_font;
+ }
+
+ switch (pitem.kind)
+ {
+ case MN_DEACTIVE:
+ {
+ context.draw_text(deactive_font, pitem.text,
+ Vector(SCREEN_WIDTH/2, y_pos - int(deactive_font->get_height()/2)),
+ CENTER_ALLIGN, LAYER_GUI);
+ break;
+ }
+
+ case MN_HL:
+ {
+ // TODO
+ int x = pos_x - menu_width/2;
+ int y = y_pos - 12 - effect_offset;
+ /* Draw a horizontal line with a little 3d effect */
+ context.draw_filled_rect(Vector(x, y + 6),
+ Vector(menu_width, 4), Color(150,200,255,225), LAYER_GUI);
+ context.draw_filled_rect(Vector(x, y + 6),
+ Vector(menu_width, 2), Color(255,255,255,255), LAYER_GUI);
+ break;
+ }
+ case MN_LABEL:
+ {
+ context.draw_text(label_font, pitem.text,
+ Vector(SCREEN_WIDTH/2, y_pos - int(label_font->get_height()/2)),
+ CENTER_ALLIGN, LAYER_GUI);
+ break;
+ }
+ case MN_TEXTFIELD:
+ case MN_NUMFIELD:
+ case MN_CONTROLFIELD:
+ {
+ int width = text_width + input_width + 5;
+ int text_pos = SCREEN_WIDTH/2 - width/2;
+ int input_pos = text_pos + text_width + 10;
+
+ context.draw_filled_rect(
+ Vector(input_pos - 5, y_pos - 10),
+ Vector(input_width + 10, 20),
+ Color(255,255,255,255), LAYER_GUI-5);
+ context.draw_filled_rect(
+ Vector(input_pos - 4, y_pos - 9),
+ Vector(input_width + 8, 18),
+ Color(0,0,0,128), LAYER_GUI-4);
+
+ if(pitem.kind == MN_TEXTFIELD || pitem.kind == MN_NUMFIELD)
+ {
+ if(active_item == index)
+ context.draw_text(field_font,
+ pitem.get_input_with_symbol(true),
+ Vector(input_pos, y_pos - int(field_font->get_height()/2)),
+ LEFT_ALLIGN, LAYER_GUI);
+ else
+ context.draw_text(field_font,
+ pitem.get_input_with_symbol(false),
+ Vector(input_pos, y_pos - int(field_font->get_height()/2)),
+ LEFT_ALLIGN, LAYER_GUI);
+ }
+ else
+ context.draw_text(field_font, pitem.input,
+ Vector(input_pos, y_pos - int(field_font->get_height()/2)),
+ LEFT_ALLIGN, LAYER_GUI);
+
+ context.draw_text(text_font, pitem.text,
+ Vector(text_pos, y_pos - int(text_font->get_height()/2)),
+ LEFT_ALLIGN, LAYER_GUI);
+ break;
+ }
+ case MN_STRINGSELECT:
+ {
+ int list_pos_2 = list_width + 16;
+ int list_pos = list_width/2;
+ int text_pos = (text_width + 16)/2;
+
+ /* Draw arrows */
+ context.draw_surface(arrow_left,
+ Vector(x_pos - list_pos + text_pos - 17, y_pos - 8),
+ LAYER_GUI);
+ context.draw_surface(arrow_right,
+ Vector(x_pos - list_pos + text_pos - 1 + list_pos_2, y_pos - 8),
+ LAYER_GUI);
+
+ /* Draw input background */
+ context.draw_filled_rect(
+ Vector(x_pos - list_pos + text_pos - 1, y_pos - 10),
+ Vector(list_pos_2 + 2, 20),
+ Color(255,255,255,255), LAYER_GUI - 4);
+ context.draw_filled_rect(
+ Vector(x_pos - list_pos + text_pos, y_pos - 9),
+ Vector(list_pos_2, 18),
+ Color(0,0,0,128), LAYER_GUI - 5);
+
+ context.draw_text(text_font, pitem.list[pitem.selected],
+ Vector(SCREEN_WIDTH/2 + text_pos, y_pos - int(text_font->get_height()/2)),
+ CENTER_ALLIGN, LAYER_GUI);
+ context.draw_text(text_font, pitem.text,
+ Vector(SCREEN_WIDTH/2 + list_pos_2/2, y_pos - int(text_font->get_height()/2)),
+ CENTER_ALLIGN, LAYER_GUI);
+ break;
+ }
+ case MN_BACK:
+ {
+ context.draw_text(text_font, pitem.text,
+ Vector(SCREEN_WIDTH/2, y_pos - int(text_font->get_height()/2)),
+ CENTER_ALLIGN, LAYER_GUI);
+ context.draw_surface(back,
+ Vector(x_pos + text_width/2 + 16, y_pos - 8),
+ LAYER_GUI);
+ break;
+ }
+
+ case MN_TOGGLE:
+ {
+ context.draw_text(text_font, pitem.text,
+ Vector(SCREEN_WIDTH/2, y_pos - (text_font->get_height()/2)),
+ CENTER_ALLIGN, LAYER_GUI);
+
+ if(pitem.toggled)
+ context.draw_surface(checkbox_checked,
+ Vector(x_pos + (text_width+16)/2, y_pos - 8),
+ LAYER_GUI + 1);
+ else
+ context.draw_surface(checkbox,
+ Vector(x_pos + (text_width+16)/2, y_pos - 8),
+ LAYER_GUI + 1);
+ break;
+ }
+ case MN_ACTION:
+ context.draw_text(text_font, pitem.text,
+ Vector(SCREEN_WIDTH/2, y_pos - int(text_font->get_height()/2)),
+ CENTER_ALLIGN, LAYER_GUI);
+ break;
+
+ case MN_GOTO:
+ context.draw_text(text_font, pitem.text,
+ Vector(SCREEN_WIDTH/2, y_pos - int(text_font->get_height()/2)),
+ CENTER_ALLIGN, LAYER_GUI);
+ break;
+ }
+}
+
+int Menu::get_width() const
+ {
+ /* The width of the menu has to be more than the width of the text
+ with the most characters */
+ int menu_width = 0;
+ for(unsigned int i = 0; i < items.size(); ++i)
+ {
+ int w = items[i]->text.size() + items[i]->input.size() + 1;
+ if(w > menu_width)
+ {
+ menu_width = w;
+ if( items[i]->kind == MN_TOGGLE)
+ menu_width += 2;
+ }
+ }
+
+ return (menu_width * 16 + 24);
+ }
+
+int Menu::get_height() const
+ {
+ return items.size() * 24;
+ }
+
+/* Draw the current menu. */
+void
+Menu::draw(DrawingContext& context)
+{
+ int menu_height = get_height();
+ int menu_width = get_width();
+
+ /* Draw a transparent background */
+ context.draw_filled_rect(
+ Vector(pos_x - menu_width/2, pos_y - 24*items.size()/2 - 10),
+ Vector(menu_width,menu_height + 20),
+ Color(150,180,200,125), LAYER_GUI-10);
+
+ for(unsigned int i = 0; i < items.size(); ++i)
+ {
+ draw_item(context, i);
+ }
+}
+
+MenuItem&
+Menu::get_item_by_id(int id)
+{
+ for(std::vector<MenuItem*>::iterator i = items.begin();
+ i != items.end(); ++i) {
+ MenuItem& item = **i;
+
+ if(item.id == id)
+ return item;
+ }
+
+ throw std::runtime_error("MenuItem not found");
+}
+
+const MenuItem&
+Menu::get_item_by_id(int id) const
+{
+ for(std::vector<MenuItem*>::const_iterator i = items.begin();
+ i != items.end(); ++i) {
+ const MenuItem& item = **i;
+
+ if(item.id == id)
+ return item;
+ }
+
+ throw std::runtime_error("MenuItem not found");
+}
+
+int Menu::get_active_item_id()
+{
+ return items[active_item]->id;
+}
+
+bool
+Menu::is_toggled(int id) const
+{
+ return get_item_by_id(id).toggled;
+}
+
+/* Check for menu event */
+void
+Menu::event(const SDL_Event& event)
+{
+ if(effect.started())
+ return;
+
+ switch(event.type) {
+ case SDL_MOUSEBUTTONDOWN:
+ {
+ int x = int(event.motion.x * float(SCREEN_WIDTH)/screen->w);
+ int y = int(event.motion.y * float(SCREEN_HEIGHT)/screen->h);
+
+ if(x > pos_x - get_width()/2 &&
+ x < pos_x + get_width()/2 &&
+ y > pos_y - get_height()/2 &&
+ y < pos_y + get_height()/2)
+ {
+ menuaction = MENU_ACTION_HIT;
+ }
+ }
+ break;
+
+ case SDL_MOUSEMOTION:
+ {
+ int x = int(event.motion.x * float(SCREEN_WIDTH)/screen->w);
+ int y = int(event.motion.y * float(SCREEN_HEIGHT)/screen->h);
+
+ if(x > pos_x - get_width()/2 &&
+ x < pos_x + get_width()/2 &&
+ y > pos_y - get_height()/2 &&
+ y < pos_y + get_height()/2)
+ {
+ int new_active_item = (y - (pos_y - get_height()/2)) / 24;
+
+ /* only change the mouse focus to a selectable item */
+ if ((items[new_active_item]->kind != MN_HL)
+ && (items[new_active_item]->kind != MN_LABEL)
+ && (items[new_active_item]->kind != MN_DEACTIVE))
+ active_item = new_active_item;
+
+ if(MouseCursor::current())
+ MouseCursor::current()->set_state(MC_LINK);
+ }
+ else
+ {
+ if(MouseCursor::current())
+ MouseCursor::current()->set_state(MC_NORMAL);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void
+Menu::set_active_item(int id)
+{
+ for(int i = 0; i < items.size(); ++i) {
+ MenuItem* item = items[i];
+ if(item->id == id) {
+ active_item = i;
+ break;
+ }
+ }
+}
+
--- /dev/null
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
+//
+// 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_MENU_H
+#define SUPERTUX_MENU_H
+
+#include <vector>
+#include <set>
+#include <string>
+#include <utility>
+
+#include "SDL.h"
+
+#include "video/surface.h"
+#include "video/font.h"
+#include "special/timer.h"
+#include "mousecursor.h"
+
+bool confirm_dialog(Surface* background, std::string text);
+
+/* Kinds of menu items */
+enum MenuItemKind {
+ MN_ACTION,
+ MN_GOTO,
+ MN_TOGGLE,
+ MN_BACK,
+ MN_DEACTIVE,
+ MN_TEXTFIELD,
+ MN_NUMFIELD,
+ MN_CONTROLFIELD,
+ MN_STRINGSELECT,
+ MN_LABEL,
+ MN_HL, /* horizontal line */
+};
+
+class Menu;
+
+class MenuItem
+{
+public:
+ MenuItem(MenuItemKind kind, int id = -1);
+ MenuItemKind kind;
+ int id; // item id
+ bool toggled;
+ std::string text;
+ std::string input;
+
+ std::vector<std::string> list; // list of values for a STRINGSELECT item
+ size_t selected; // currently selected item
+
+ Menu* target_menu;
+
+ void change_text (const std::string& text);
+ void change_input(const std::string& text);
+
+ static MenuItem* create(MenuItemKind kind, const std::string& text,
+ int init_toggle, Menu* target_menu, int id, int key);
+
+ std::string get_input_with_symbol(bool active_item); // returns the text with an input symbol
+
+private:
+ /// copy-construction not allowed
+ MenuItem(const MenuItem& other) { assert(false); }
+ /// assignment not allowed
+ void operator= (const MenuItem& other) { assert(false); }
+
+ /// keyboard key or joystick button
+ bool input_flickering;
+ Timer input_flickering_timer;
+};
+
+class Menu
+{
+private:
+ static std::vector<Menu*> last_menus;
+ static Menu* current_;
+
+ static void push_current(Menu* pmenu);
+ static void pop_current();
+
+public:
+ /** Set the current menu, if pmenu is NULL, hide the current menu */
+ static void set_current(Menu* pmenu);
+
+ /** Return the current active menu or NULL if none is active */
+ static Menu* current()
+ {
+ return current_;
+ }
+
+private:
+ /* Action done on the menu */
+ enum MenuAction {
+ MENU_ACTION_NONE = -1,
+ MENU_ACTION_UP,
+ MENU_ACTION_DOWN,
+ MENU_ACTION_LEFT,
+ MENU_ACTION_RIGHT,
+ MENU_ACTION_HIT,
+ MENU_ACTION_INPUT,
+ MENU_ACTION_REMOVE,
+ MENU_ACTION_BACK
+ };
+
+ /** Number of the item that got 'hit' (ie. pressed) in the last
+ event()/action() call, -1 if none */
+ int hit_item;
+
+ // position of the menu (ie. center of the menu, not top/left)
+ int pos_x;
+ int pos_y;
+
+ /** input event for the menu (up, down, left, right, etc.) */
+ MenuAction menuaction;
+
+ /* input implementation variables */
+ int delete_character;
+ char mn_input_char;
+ Timer repeat_timer;
+
+public:
+ static Font* default_font;
+ static Font* active_font;
+ static Font* deactive_font;
+ static Font* label_font;
+ static Font* field_font;
+
+ std::vector<MenuItem*> items;
+
+ Menu();
+ ~Menu();
+
+ void add_hl();
+ void add_label(const std::string& text);
+ void add_entry(int id, const std::string& text);
+ void add_toggle(int id, const std::string& text, bool toggled = false);
+ void add_deactive(int id, const std::string& text);
+ void add_back(const std::string& text);
+ void add_submenu(const std::string& text, Menu* submenu, int id = -1);
+ void add_controlfield(int id, const std::string& text,
+ const std::string& mapping = "");
+
+ virtual void menu_action(MenuItem* item);
+
+ void action();
+
+ /** Remove all entries from the menu */
+ void clear();
+
+ /** Return the index of the menu item that was 'hit' (ie. the user
+ clicked on it) in the last event() call */
+ int check ();
+
+ MenuItem& get_item(int index)
+ {
+ return *(items[index]);
+ }
+ MenuItem& get_item_by_id(int id);
+ const MenuItem& get_item_by_id(int id) const;
+
+ int get_active_item_id();
+ void set_active_item(int id);
+
+ void draw(DrawingContext& context);
+ void set_pos(int x, int y, float rw = 0, float rh = 0);
+
+ void event(const SDL_Event& event);
+
+ bool is_toggled(int id) const;
+
+protected:
+ void additem(MenuItem* pmenu_item);
+ int get_width() const;
+ int get_height() const;
+
+private:
+ void check_controlfield_change_event(const SDL_Event& event);
+ void draw_item(DrawingContext& context, int index);
+ Timer effect;
+ int arrange_left;
+ int active_item;
+};
+
+extern Surface* checkbox;
+extern Surface* checkbox_checked;
+extern Surface* back;
+extern Surface* arrow_left;
+extern Surface* arrow_right;
+
+#endif
--- /dev/null
+// $Id$
+//
+// SuperTux - A Jump'n Run
+// Copyright (C) 2004 Ricardo Cruz <rick2@aeiou.pt>
+//
+// 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 <config.h>
+
+#include "app/globals.h"
+#include "video/drawing_context.h"
+#include "gui/mousecursor.h"
+
+using namespace SuperTux;
+
+MouseCursor* MouseCursor::current_ = 0;
+extern SDL_Surface* screen;
+
+MouseCursor::MouseCursor(std::string cursor_file, int frames) : mid_x(0), mid_y(0)
+{
+ cursor = new Surface(cursor_file, true);
+
+ cur_state = MC_NORMAL;
+ cur_frame = 0;
+ tot_frames = frames;
+
+ timer.init(false);
+ timer.start(MC_FRAME_PERIOD);
+
+ SDL_ShowCursor(SDL_DISABLE);
+}
+
+MouseCursor::~MouseCursor()
+{
+ delete cursor;
+
+ SDL_ShowCursor(SDL_ENABLE);
+}
+
+int MouseCursor::state()
+{
+ return cur_state;
+}
+
+void MouseCursor::set_state(int nstate)
+{
+ cur_state = nstate;
+}
+
+void MouseCursor::set_mid(int x, int y)
+{
+ mid_x = x;
+ mid_y = y;
+}
+
+void MouseCursor::draw(DrawingContext& context)
+{
+ if(cur_state == MC_HIDE)
+ return;
+
+ int x,y,w,h;
+ Uint8 ispressed = SDL_GetMouseState(&x,&y);
+
+ x = int(x * float(SCREEN_WIDTH)/screen->w);
+ y = int(y * float(SCREEN_HEIGHT)/screen->h);
+
+ w = cursor->w / tot_frames;
+ h = cursor->h / MC_STATES_NB;
+ if(ispressed &SDL_BUTTON(1) || ispressed &SDL_BUTTON(2))
+ {
+ if(cur_state != MC_CLICK)
+ {
+ state_before_click = cur_state;
+ cur_state = MC_CLICK;
+ }
+ }
+ else
+ {
+ if(cur_state == MC_CLICK)
+ cur_state = state_before_click;
+ }
+
+ if(timer.get_left() < 0 && tot_frames > 1)
+ {
+ cur_frame++;
+ if(cur_frame++ >= tot_frames)
+ cur_frame = 0;
+
+ timer.start(MC_FRAME_PERIOD);
+ }
+
+ context.draw_surface_part(cursor, Vector(w*cur_frame, h*cur_state), Vector(w,
+ h), Vector(x-mid_x, y-mid_y), LAYER_GUI+100);
+}
--- /dev/null
+// $Id$
+//
+// SuperTux - A Jump'n Run
+// Copyright (C) 2004 Ricardo Cruz <rick2@aeiou.pt>
+//
+// 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_MOUSECURSOR_H
+#define SUPERTUX_MOUSECURSOR_H
+
+#include <string>
+
+#include "special/timer.h"
+#include "video/surface.h"
+
+namespace SuperTux
+ {
+
+ #define MC_FRAME_PERIOD 800 // in ms
+
+ #define MC_STATES_NB 3
+
+ enum {
+ MC_NORMAL,
+ MC_CLICK,
+ MC_LINK,
+ MC_HIDE
+ };
+
+ /// Mouse cursor.
+ /** Used to create mouse cursors.
+ The mouse cursors can be animated
+ and can be used in four different states.
+ (MC_NORMAL, MC_CLICK, MC_LINK or MC_HIDE) */
+ class MouseCursor
+ {
+ public:
+ /// Constructor of MouseCursor.
+ /** Expects an imagefile for the cursor and the number of animation frames it contains. */
+ MouseCursor(std::string cursor_file, int frames);
+ ~MouseCursor();
+ /// Get MouseCursor state.
+ /** (MC_NORMAL, MC_CLICK, MC_LINK or MC_HIDE) */
+ int state();
+ /// Set MouseCursor state.
+ /** (MC_NORMAL, MC_CLICK, MC_LINK or MC_HIDE) */
+ void set_state(int nstate);
+ /// Define the middle of a MouseCursor.
+ /** Useful for cross mouse cursor images in example. */
+ void set_mid(int x, int y);
+
+ /// Draw MouseCursor on screen.
+ void draw(DrawingContext& context);
+
+ /// Return the current cursor.
+ static MouseCursor* current()
+ { return current_; };
+ /// Set current cursor.
+ static void set_current(MouseCursor* pcursor)
+ { current_ = pcursor; };
+
+ private:
+ int mid_x, mid_y;
+ static MouseCursor* current_;
+ int state_before_click;
+ int cur_state;
+ int cur_frame, tot_frames;
+ Surface* cursor;
+ Timer timer;
+ };
+
+} // namespace SuperTux
+
+#endif /*SUPERTUX_MOUSECURSOR_H*/
std::string filepath = "levels/" + filename;
int last_slash = filepath.find_last_of('/');
FileSystem::fcreatedir(filepath.substr(0,last_slash).c_str());
- filepath = st_dir + "/" + filepath;
+ filepath = user_dir + "/" + filepath;
ofstream file(filepath.c_str(), ios::out);
lisp::Writer* writer = new lisp::Writer(file);
filename = datadir + "/levels/" + subset + "/";
files = FileSystem::read_directory(filename);
- filename = st_dir + "/levels/" + subset + "/";
+ filename = user_dir + "/levels/" + subset + "/";
std::set<std::string> user_files = FileSystem::read_directory(filename);
files.insert(user_files.begin(), user_files.end());
filename = "/levels/" + name + "/";
FileSystem::fcreatedir(filename.c_str());
- filename = std::string(st_dir) + "/levels/" + name + "/info";
+ filename = std::string(user_dir) + "/levels/" + name + "/info";
if(!FileSystem::fwriteable(filename.c_str()))
filename = datadir + "/levels/" + name + "/info";
if(FileSystem::fwriteable(filename.c_str()))
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "level_transformer.h"
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __LEVEL_TRANSFORMER_H__
#define __LEVEL_TRANSFORMER_H__
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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.
+
/***************************************************************************
leveleditor.cpp - built'in leveleditor
-------------------
* (at your option) any later version. *
* *
***************************************************************************/
-
+#if 0
#include <config.h>
#include <stdlib.h>
#include "app/gettext.h"
#include "app/setup.h"
#include "app/globals.h"
-#include "special/sprite.h"
+#include "sprite/sprite.h"
#include "leveleditor.h"
#include "resources.h"
#include "tile.h"
#include "tile_manager.h"
#include "sector.h"
-#include "gameloop.h"
+#include "game_session.h"
#include "object_factory.h"
#include "object/gameobjs.h"
#include "object/camera.h"
/* Creating menus */
level_subsets = FileSystem::dsubdirs("/levels", "info");
subset_menu = new Menu();
- subset_menu->additem(MN_LABEL,_("Load Subset"),0,0);
+ subset_menu->add_label(_("Load Subset"));
subset_menu->additem(MN_HL,"",0,0);
int i = 0;
for(std::set<std::string>::iterator it = level_subsets.begin(); it != level_subsets.end(); ++it, ++i)
void LevelEditor::run(const std::string filename)
{
- SoundManager::get()->halt_music();
+ sound_manager->halt_music();
Menu::set_current(0);
DrawingContext context;
GameSession session(level_filename, ST_GL_TEST);
session.run();
// player_status.reset();
- SoundManager::get()->halt_music();
+ sound_manager->halt_music();
}
void LevelEditor::change(int x, int y, int newtile, int layer)
return sector;
}
+#endif
-/***************************************************************************
- leveleditor.h - built'in level editor
- -------------------
- begin : June, 23 2004
- copyright : (C) 2004 by Ricardo Cruz
- email : rick2@aeiou.pt
- ***************************************************************************/
-
-/***************************************************************************
- * *
- * 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. *
- * *
- ***************************************************************************/
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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_LEVELEDITOR_H
#define SUPERTUX_LEVELEDITOR_H
namespace SuperTux {
class ButtonGroup;
-class Menu;
-class Surface;
}
+class Menu;
class Sector;
class TileMap;
+class Surface;
enum {
MN_ID_RETURN,
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2004 Matthias Braun <matze@braunis.de>
+// code in this file based on lispreader from Mark Probst
+//
+// 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 <config.h>
+
+#include <sstream>
+#include <stdexcept>
+#include <iostream>
+
+#include "lexer.h"
+
+namespace lisp
+{
+
+class EOFException
+{
+};
+
+Lexer::Lexer(std::istream& newstream)
+ : stream(newstream), eof(false), linenumber(0)
+{
+ try {
+ // trigger a refill of the buffer
+ c = 0;
+ bufend = 0;
+ nextChar();
+ } catch(EOFException& e) {
+ }
+}
+
+Lexer::~Lexer()
+{
+}
+
+void
+Lexer::nextChar()
+{
+ ++c;
+ if(c >= bufend) {
+ if(eof)
+ throw EOFException();
+ stream.read(buffer, BUFFER_SIZE);
+ size_t bytes_read = stream.gcount();
+
+ c = buffer;
+ bufend = buffer + bytes_read;
+
+ // the following is a hack that appends an additional ' ' at the end of
+ // the file to avoid problems when parsing symbols/elements and a sudden
+ // EOF. This is faster than relying on unget and IMO also nicer.
+ if(bytes_read == 0 || stream.eof()) {
+ eof = true;
+ *bufend = ' ';
+ ++bufend;
+ }
+ }
+}
+
+Lexer::TokenType
+Lexer::getNextToken()
+{
+ static const char* delims = "\"();";
+
+ try {
+ while(isspace(*c)) {
+ if(*c == '\n')
+ ++linenumber;
+ nextChar();
+ };
+
+ token_length = 0;
+
+ switch(*c) {
+ case ';': // comment
+ while(true) {
+ nextChar();
+ if(*c == '\n') {
+ ++linenumber;
+ break;
+ }
+ }
+ return getNextToken(); // and again
+ case '(':
+ nextChar();
+ return TOKEN_OPEN_PAREN;
+ case ')':
+ nextChar();
+ return TOKEN_CLOSE_PAREN;
+ case '"': { // string
+ int startline = linenumber;
+ try {
+ while(1) {
+ nextChar();
+ if(*c == '"')
+ break;
+ else if(*c == '\n')
+ linenumber++;
+ else if(*c == '\\') {
+ nextChar();
+ switch(*c) {
+ case 'n':
+ *c = '\n';
+ break;
+ case 't':
+ *c = '\t';
+ break;
+ }
+ }
+ if(token_length < MAX_TOKEN_LENGTH)
+ token_string[token_length++] = *c;
+ }
+ token_string[token_length] = 0;
+ } catch(EOFException& ) {
+ std::stringstream msg;
+ msg << "Parse error in line " << startline << ": "
+ << "EOF while parsing string.";
+ throw std::runtime_error(msg.str());
+ }
+ nextChar();
+ return TOKEN_STRING;
+ }
+ case '#': // constant
+ try {
+ nextChar();
+
+ while(isalnum(*c) || *c == '_') {
+ if(token_length < MAX_TOKEN_LENGTH)
+ token_string[token_length++] = *c;
+ nextChar();
+ }
+ token_string[token_length] = 0;
+ } catch(EOFException& ) {
+ std::stringstream msg;
+ msg << "Parse Error in line " << linenumber << ": "
+ << "EOF while parsing constant.";
+ throw std::runtime_error(msg.str());
+ }
+
+ if(strcmp(token_string, "t") == 0)
+ return TOKEN_TRUE;
+ if(strcmp(token_string, "f") == 0)
+ return TOKEN_FALSE;
+
+ // we only handle #t and #f constants at the moment...
+
+ {
+ std::stringstream msg;
+ msg << "Parse Error in line " << linenumber << ": "
+ << "Unknown constant '" << token_string << "'.";
+ throw std::runtime_error(msg.str());
+ }
+
+ default:
+ if(isdigit(*c) || *c == '-') {
+ bool have_nondigits = false;
+ bool have_digits = false;
+ int have_floating_point = 0;
+
+ do {
+ if(isdigit(*c))
+ have_digits = true;
+ else if(*c == '.')
+ ++have_floating_point;
+ else if(isalnum(*c) || *c == '_')
+ have_nondigits = true;
+
+ if(token_length < MAX_TOKEN_LENGTH)
+ token_string[token_length++] = *c;
+
+ nextChar();
+ } while(!isspace(*c) && !strchr(delims, *c));
+
+ token_string[token_length] = 0;
+
+ // no nextChar
+
+ if(have_nondigits || !have_digits || have_floating_point > 1)
+ return TOKEN_SYMBOL;
+ else if(have_floating_point == 1)
+ return TOKEN_REAL;
+ else
+ return TOKEN_INTEGER;
+ } else {
+ do {
+ if(token_length < MAX_TOKEN_LENGTH)
+ token_string[token_length++] = *c;
+ nextChar();
+ } while(!isspace(*c) && !strchr(delims, *c));
+ token_string[token_length] = 0;
+
+ // no nextChar
+
+ return TOKEN_SYMBOL;
+ }
+ }
+ } catch(EOFException& ) {
+ return TOKEN_EOF;
+ }
+}
+
+} // end of namespace lisp
+
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2004 Matthias Braun <matze@braunis.de>
+// code in this file based on lispreader from Mark Probst
+//
+// 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 __LISPLEXER_H__
+#define __LISPLEXER_H__
+
+namespace lisp
+{
+
+class Lexer
+{
+public:
+ enum TokenType {
+ TOKEN_EOF,
+ TOKEN_OPEN_PAREN,
+ TOKEN_CLOSE_PAREN,
+ TOKEN_SYMBOL,
+ TOKEN_STRING,
+ TOKEN_INTEGER,
+ TOKEN_REAL,
+ TOKEN_TRUE,
+ TOKEN_FALSE
+ };
+
+ Lexer(std::istream& stream);
+ ~Lexer();
+
+ TokenType getNextToken();
+ const char* getString() const
+ { return token_string; }
+ int getLineNumber() const
+ { return linenumber; }
+
+private:
+ enum {
+ MAX_TOKEN_LENGTH = 16384,
+ BUFFER_SIZE = 1024
+ };
+
+ inline void nextChar();
+
+ std::istream& stream;
+ bool eof;
+ int linenumber;
+ char buffer[BUFFER_SIZE+1];
+ char* bufend;
+ char* c;
+ char token_string[MAX_TOKEN_LENGTH + 1];
+ int token_length;
+};
+
+} // end of namespace lisp
+
+#endif
+
--- /dev/null
+// $Id$
+//
+// TuxKart - a fun racing game with go-kart
+// Copyright (C) 2004 Matthias Braun <matze@braunis.de>
+// code in this file based on lispreader from Mark Probst
+//
+// 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 <config.h>
+
+#include "lisp.h"
+
+namespace lisp
+{
+
+Lisp::Lisp(LispType newtype)
+ : type(newtype)
+{
+}
+
+Lisp::~Lisp()
+{
+ if(type == TYPE_SYMBOL || type == TYPE_STRING)
+ delete[] v.string;
+ if(type == TYPE_CONS) {
+ delete v.cons.cdr;
+ delete v.cons.car;
+ }
+}
+
+Lisp*
+Lisp::get_lisp(const char* name) const
+{
+ for(const Lisp* p = this; p != 0; p = p->get_cdr()) {
+ Lisp* child = p->get_car();
+ if(!child || child->get_type() != TYPE_CONS)
+ continue;
+ Lisp* childname = child->get_car();
+ if(!childname)
+ continue;
+ std::string childName;
+ if(!childname->get(childName))
+ continue;
+ if(childName == name) {
+ return child->get_cdr();
+ }
+ }
+
+ return 0;
+}
+
+void
+Lisp::print(int indent) const
+{
+ for(int i = 0; i < indent; ++i)
+ printf(" ");
+
+ if(type == TYPE_CONS) {
+ printf("(\n");
+ const Lisp* lisp = this;
+ while(lisp) {
+ if(lisp->v.cons.car)
+ lisp->v.cons.car->print(indent + 1);
+ lisp = lisp->v.cons.cdr;
+ }
+ for(int i = 0; i < indent; ++i)
+ printf(" ");
+ printf(")");
+ }
+ if(type == TYPE_STRING) {
+ printf("'%s' ", v.string);
+ }
+ if(type == TYPE_INTEGER) {
+ printf("%d", v.integer);
+ }
+ if(type == TYPE_REAL) {
+ printf("%f", v.real);
+ }
+ if(type == TYPE_SYMBOL) {
+ printf("%s ", v.string);
+ }
+ if(type == TYPE_BOOLEAN) {
+ printf("%s ", v.boolean ? "true" : "false");
+ }
+ printf("\n");
+}
+
+} // end of namespace lisp
--- /dev/null
+// $Id$
+//
+// TuxKart - a fun racing game with go-kart
+// Copyright (C) 2004 Matthias Braun <matze@braunis.de>
+// code in this file based on lispreader from Mark Probst
+//
+// 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 __LISPREADER_H__
+#define __LISPREADER_H__
+
+#include <string>
+#include <vector>
+
+namespace lisp
+{
+
+class Lisp
+{
+public:
+ ~Lisp();
+
+ enum LispType {
+ TYPE_CONS,
+ TYPE_SYMBOL,
+ TYPE_INTEGER,
+ TYPE_STRING,
+ TYPE_REAL,
+ TYPE_BOOLEAN
+ };
+
+ LispType get_type() const
+ { return type; }
+
+ Lisp* get_car() const
+ { return v.cons.car; }
+ Lisp* get_cdr() const
+ { return v.cons.cdr; }
+ bool get(std::string& val) const
+ {
+ if(type != TYPE_STRING && type != TYPE_SYMBOL)
+ return false;
+ val = v.string;
+ return true;
+ }
+ bool get(unsigned int& val) const
+ {
+ if(type != TYPE_INTEGER)
+ return false;
+ val = v.integer;
+ return true;
+ }
+ bool get(int& val) const
+ {
+ if(type != TYPE_INTEGER)
+ return false;
+ val = v.integer;
+ return true;
+ }
+ bool get(float& val) const
+ {
+ if(type != TYPE_REAL) {
+ if(type == TYPE_INTEGER) {
+ val = v.integer;
+ return true;
+ }
+ return false;
+ }
+ val = v.real;
+ return true;
+ }
+ bool get(bool& val) const
+ {
+ if(type != TYPE_BOOLEAN)
+ return false;
+ val = v.boolean;
+ return true;
+ }
+
+ /* conveniance functions which traverse the list until a child with a
+ * specified name is found. The value part is then interpreted in a specific
+ * way. The functions return true, if a child was found and could be
+ * interpreted correctly, otherwise false is returned and the variable value
+ * is not changed.
+ * (Please note that searching the lisp structure is O(n) so these functions
+ * are no good idea for performance critical areas)
+ */
+ template<class T>
+ bool get(const char* name, T& val) const
+ {
+ const Lisp* lisp = get_lisp(name);
+ if(!lisp)
+ return false;
+
+ if(lisp->get_type() != TYPE_CONS)
+ return false;
+ lisp = lisp->get_car();
+ if(!lisp)
+ return false;
+ return lisp->get(val);
+ }
+
+ template<class T>
+ bool get_vector(const char* name, std::vector<T>& vec) const
+ {
+ vec.clear();
+
+ const Lisp* child = get_lisp(name);
+ if(!child)
+ return false;
+
+ for( ; child != 0; child = child->get_cdr()) {
+ T val;
+ if(!child->get_car())
+ continue;
+ if(child->get_car()->get(val)) {
+ vec.push_back(val);
+ }
+ }
+
+ return true;
+ }
+
+ Lisp* get_lisp(const char* name) const;
+ Lisp* get_lisp(const std::string& name) const
+ { return get_lisp(name.c_str()); }
+
+ // for debugging
+ void print(int indent = 0) const;
+
+private:
+ friend class Parser;
+ Lisp(LispType newtype);
+
+ LispType type;
+ union
+ {
+ struct
+ {
+ Lisp* car;
+ Lisp* cdr;
+ } cons;
+
+ char* string;
+ int integer;
+ bool boolean;
+ float real;
+ } v;
+};
+
+} // end of namespace lisp
+
+#endif
+
--- /dev/null
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
+
+#include "list_iterator.h"
+#include <stdexcept>
+
+namespace lisp
+{
+
+ListIterator::ListIterator(const lisp::Lisp* newlisp)
+ : current_lisp(0), cur(newlisp)
+{
+}
+
+bool
+ListIterator::next()
+{
+ if(cur == 0)
+ return false;
+
+ const lisp::Lisp* child = cur->get_car();
+ if(!child)
+ throw new std::runtime_error("child is 0 in list entry");
+ if(child->get_type() != lisp::Lisp::TYPE_CONS)
+ throw new std::runtime_error("Expected CONS");
+ const lisp::Lisp* name = child->get_car();
+ if(!name || name->get_type() != lisp::Lisp::TYPE_SYMBOL)
+ throw new std::runtime_error("Expected symbol");
+ name->get(current_item);
+ current_lisp = child->get_cdr();
+
+ cur = cur->get_cdr();
+ return true;
+}
+
+}
--- /dev/null
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __LISP_ITERATOR_H__
+#define __LISP_ITERATOR_H__
+
+#include "lisp/lisp.h"
+
+namespace lisp
+{
+
+/**
+ * Small and a bit hacky helper class that helps parsing lisp lists where all
+ * entries are lists again themselves
+ */
+class ListIterator
+{
+public:
+ ListIterator(const lisp::Lisp* cur);
+
+ const std::string& item() const
+ { return current_item; }
+ lisp::Lisp* lisp() const
+ { return current_lisp; }
+ lisp::Lisp* value() const
+ { return current_lisp->get_car(); }
+ bool next();
+
+private:
+ std::string current_item;
+ lisp::Lisp* current_lisp;
+ const lisp::Lisp* cur;
+};
+
+}
+
+#endif
+
--- /dev/null
+// $Id$
+//
+// TuxKart - a fun racing game with go-kart
+// Copyright (C) 2004 Matthias Braun <matze@braunis.de>
+// code in this file based on lispreader from Mark Probst
+//
+// 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 <config.h>
+
+#include <sstream>
+#include <stdexcept>
+#include <fstream>
+#include <cassert>
+#include <iostream>
+
+#include "app/setup.h"
+#include "app/tinygettext.h"
+#include "parser.h"
+#include "lisp.h"
+
+namespace lisp
+{
+
+Parser::Parser(bool translate)
+ : lexer(0), dictionary_manager(0), dictionary(0)
+{
+ if(translate) {
+ dictionary_manager = new TinyGetText::DictionaryManager();
+ }
+}
+
+Parser::~Parser()
+{
+ delete lexer;
+ delete dictionary_manager;
+}
+
+Lisp*
+Parser::parse(const std::string& filename)
+{
+ std::ifstream in(filename.c_str());
+ if(!in.good()) {
+ std::stringstream msg;
+ msg << "Parser problem: Couldn't open file '" << filename << "'.";
+ throw std::runtime_error(msg.str());
+ }
+
+ if(dictionary_manager) {
+ dictionary_manager->add_directory(SuperTux::FileSystem::dirname(filename));
+ dictionary = & (dictionary_manager->get_dictionary());
+ }
+
+ return parse(in);
+}
+
+Lisp*
+Parser::parse(std::istream& stream)
+{
+ delete lexer;
+ lexer = new Lexer(stream);
+
+ token = lexer->getNextToken();
+ Lisp* result = new Lisp(Lisp::TYPE_CONS);
+ result->v.cons.car = read();
+ result->v.cons.cdr = 0;
+
+ delete lexer;
+ lexer = 0;
+
+ return result;
+}
+
+Lisp*
+Parser::read()
+{
+ Lisp* result;
+ switch(token) {
+ case Lexer::TOKEN_EOF: {
+ std::stringstream msg;
+ msg << "Parse Error at line " << lexer->getLineNumber() << ": "
+ << "Unexpected EOF.";
+ throw std::runtime_error(msg.str());
+ }
+ case Lexer::TOKEN_CLOSE_PAREN: {
+ std::stringstream msg;
+ msg << "Parse Error at line " << lexer->getLineNumber() << ": "
+ << "Unexpected ')'.";
+ throw std::runtime_error(msg.str());
+ }
+ case Lexer::TOKEN_OPEN_PAREN: {
+ result = new Lisp(Lisp::TYPE_CONS);
+
+ token = lexer->getNextToken();
+ if(token == Lexer::TOKEN_CLOSE_PAREN) {
+ result->v.cons.car = 0;
+ result->v.cons.cdr = 0;
+ break;
+ }
+
+ if(token == Lexer::TOKEN_SYMBOL &&
+ strcmp(lexer->getString(), "_") == 0) {
+ // evaluate translation function (_ str) in place here
+ token = lexer->getNextToken();
+ if(token != Lexer::TOKEN_STRING)
+ throw new std::runtime_error("Expected string after '(_'");
+
+ result = new Lisp(Lisp::TYPE_STRING);
+ if(dictionary) {
+ std::string translation = dictionary->translate(lexer->getString());
+ result->v.string = new char[translation.size()+1];
+ memcpy(result->v.string, translation.c_str(), translation.size()+1);
+ } else {
+ size_t len = strlen(lexer->getString()) + 1;
+ result->v.string = new char[len];
+ memcpy(result->v.string, lexer->getString(), len);
+ }
+ token = lexer->getNextToken();
+ if(token != Lexer::TOKEN_CLOSE_PAREN)
+ throw new std::runtime_error("Expected ')' after '(_ string'");
+ break;
+ }
+
+ Lisp* cur = result;
+ do {
+ cur->v.cons.car = read();
+ if(token == Lexer::TOKEN_CLOSE_PAREN) {
+ cur->v.cons.cdr = 0;
+ break;
+ }
+ cur->v.cons.cdr = new Lisp(Lisp::TYPE_CONS);
+ cur = cur->v.cons.cdr;
+ } while(1);
+
+ break;
+ }
+ case Lexer::TOKEN_SYMBOL: {
+ result = new Lisp(Lisp::TYPE_SYMBOL);
+ size_t len = strlen(lexer->getString()) + 1;
+ result->v.string = new char[len];
+ memcpy(result->v.string, lexer->getString(), len);
+ break;
+ }
+ case Lexer::TOKEN_STRING: {
+ result = new Lisp(Lisp::TYPE_STRING);
+ size_t len = strlen(lexer->getString()) + 1;
+ result->v.string = new char[len];
+ memcpy(result->v.string, lexer->getString(), len);
+ break;
+ }
+ case Lexer::TOKEN_INTEGER:
+ result = new Lisp(Lisp::TYPE_INTEGER);
+ sscanf(lexer->getString(), "%d", &result->v.integer);
+ break;
+ case Lexer::TOKEN_REAL:
+ result = new Lisp(Lisp::TYPE_REAL);
+ sscanf(lexer->getString(), "%f", &result->v.real);
+ break;
+ case Lexer::TOKEN_TRUE:
+ result = new Lisp(Lisp::TYPE_BOOLEAN);
+ result->v.boolean = true;
+ break;
+ case Lexer::TOKEN_FALSE:
+ result = new Lisp(Lisp::TYPE_BOOLEAN);
+ result->v.boolean = false;
+ break;
+
+ default:
+ // this should never happen
+ assert(false);
+ }
+
+ token = lexer->getNextToken();
+ return result;
+}
+
+} // end of namespace lisp
--- /dev/null
+// $Id$
+//
+// TuxKart - a fun racing game with go-kart
+// Copyright (C) 2004 Matthias Braun <matze@braunis.de>
+// code in this file based on lispreader from Mark Probst
+//
+// 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 __LISPPARSER_H__
+#define __LISPPARSER_H__
+
+#include <string>
+#include "lexer.h"
+
+namespace TinyGetText {
+class Dictionary;
+class DictionaryManager;
+}
+
+namespace lisp
+{
+
+class Lisp;
+
+class Parser
+{
+public:
+ Parser(bool translate = true);
+ ~Parser();
+
+ Lisp* parse(const std::string& filename);
+ Lisp* parse(std::istream& stream);
+
+private:
+ Lisp* read();
+
+ Lexer* lexer;
+ TinyGetText::DictionaryManager* dictionary_manager;
+ TinyGetText::Dictionary* dictionary;
+ Lexer::TokenType token;
+};
+
+} // end of namespace lisp
+
+#endif
+
--- /dev/null
+// $Id$
+//
+// SuperTux - A Jump'n Run
+// Copyright (C) 2004 Matthias Braun <matze@braunis.de
+//
+// 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 <config.h>
+
+#include <iostream>
+
+#include "writer.h"
+
+namespace lisp
+{
+
+Writer::Writer(std::ostream& newout)
+ : out(newout), indent_depth(0)
+{
+}
+
+Writer::~Writer()
+{
+ if(lists.size() > 0) {
+ std::cerr << "Warning: Not all sections closed in lispwriter!\n";
+ }
+}
+
+void
+Writer::write_comment(const std::string& comment)
+{
+ out << "; " << comment << "\n";
+}
+
+void
+Writer::start_list(const std::string& listname)
+{
+ indent();
+ out << '(' << listname << '\n';
+ indent_depth += 2;
+
+ lists.push_back(listname);
+}
+
+void
+Writer::end_list(const std::string& listname)
+{
+ if(lists.size() == 0) {
+ std::cerr << "Trying to close list '" << listname
+ << "', which is not open.\n";
+ return;
+ }
+ if(lists.back() != listname) {
+ std::cerr << "Warning: trying to close list '" << listname
+ << "' while list '" << lists.back() << "' is open.\n";
+ return;
+ }
+ lists.pop_back();
+
+ indent_depth -= 2;
+ indent();
+ out << ")\n";
+}
+
+void
+Writer::write_int(const std::string& name, int value)
+{
+ indent();
+ out << '(' << name << ' ' << value << ")\n";
+}
+
+void
+Writer::write_float(const std::string& name, float value)
+{
+ indent();
+ out << '(' << name << ' ' << value << ")\n";
+}
+
+void
+Writer::write_string(const std::string& name, const std::string& value,
+ bool translatable)
+{
+ indent();
+ out << '(' << name;
+ if(translatable) {
+ out << " (_ \"" << value << "\"))\n";
+ } else {
+ out << " \"" << value << "\")\n";
+ }
+}
+
+void
+Writer::write_bool(const std::string& name, bool value)
+{
+ indent();
+ out << '(' << name << ' ' << (value ? "#t" : "#f") << ")\n";
+}
+
+void
+Writer::write_int_vector(const std::string& name,
+ const std::vector<int>& value)
+{
+ indent();
+ out << '(' << name;
+ for(std::vector<int>::const_iterator i = value.begin(); i != value.end(); ++i)
+ out << " " << *i;
+ out << ")\n";
+}
+
+void
+Writer::write_int_vector(const std::string& name,
+ const std::vector<unsigned int>& value)
+{
+ indent();
+ out << '(' << name;
+ for(std::vector<unsigned int>::const_iterator i = value.begin(); i != value.end(); ++i)
+ out << " " << *i;
+ out << ")\n";
+}
+
+void
+Writer::indent()
+{
+ for(int i = 0; i<indent_depth; ++i)
+ out << ' ';
+}
+
+} // end of namespace lisp
--- /dev/null
+// $Id$
+//
+// SuperTux - A Jump'n Run
+// Copyright (C) 2004 Matthias Braun <matze@braunis.de
+//
+// 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_LISPWRITER_H
+#define SUPERTUX_LISPWRITER_H
+
+#include <iostream>
+#include <string>
+#include <vector>
+
+namespace lisp
+{
+
+ class Writer
+ {
+ public:
+ Writer(std::ostream& out);
+ ~Writer();
+
+ void write_comment(const std::string& comment);
+
+ void start_list(const std::string& listname);
+
+ void write_int(const std::string& name, int value);
+ void write_float(const std::string& name, float value);
+ void write_string(const std::string& name, const std::string& value,
+ bool translatable = false);
+ void write_bool(const std::string& name, bool value);
+ void write_int_vector(const std::string& name, const std::vector<int>& value);
+ void write_int_vector(const std::string& name, const std::vector<unsigned int>& value);
+ // add more write-functions when needed...
+
+ void end_list(const std::string& listname);
+
+ private:
+ void indent();
+
+ std::ostream& out;
+ int indent_depth;
+ std::vector<std::string> lists;
+ };
+
+} //namespace lisp
+
+#endif //SUPERTUX_LISPWRITER_H
+
--- /dev/null
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
+
+#include "main.h"
+
+#include <stdexcept>
+#include <iostream>
+#include <sstream>
+#include <time.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <unistd.h>
+#ifndef WIN32
+#include <libgen.h>
+#endif
+#include <SDL.h>
+#include <SDL_mixer.h>
+#include <SDL_image.h>
+
+#include "gameconfig.h"
+#include "resources.h"
+#include "app/globals.h"
+#include "app/setup.h"
+#include "app/gettext.h"
+#include "audio/sound_manager.h"
+#include "control/joystickkeyboardcontroller.h"
+#include "misc.h"
+#include "game_session.h"
+
+SDL_Surface* screen = 0;
+JoystickKeyboardController* main_controller = 0;
+
+static void init_config()
+{
+ config = new Config();
+ try {
+ config->load();
+ } catch(std::exception& e) {
+#ifdef DEBUG
+ std::cerr << "Couldn't load config file: " << e.what() << "\n";
+#endif
+ }
+}
+
+static void find_directories()
+{
+ const char* home = getenv("HOME");
+ if(home == 0) {
+#ifdef DEBUG
+ std::cerr << "Couldn't find home directory.\n";
+#endif
+ home = ".";
+ }
+
+ user_dir = home;
+ user_dir += "/.supertux";
+
+ // Remove .supertux config file from old versions
+ if(FileSystem::faccessible(user_dir)) {
+ std::cerr << "Removing old config file " << user_dir << "\n";
+ remove(user_dir.c_str());
+ }
+
+ // create directories
+ std::string savedir = user_dir + "/save";
+ mkdir(user_dir.c_str(), 0755);
+ mkdir(savedir.c_str(), 0755);
+
+ // try current directory as datadir
+ if(datadir.empty()) {
+ if(FileSystem::faccessible("./data/credits.txt")) {
+ datadir = "./data/";
+ }
+ }
+
+ // Detect datadir with some linux magic
+#ifndef WIN32
+ if(datadir.empty()) {
+ char exe_file[PATH_MAX];
+ if(readlink("/proc/self/exe", exe_file, PATH_MAX) < 0) {
+#ifdef DEBUG
+ std::cerr << "Couldn't read /proc/self/exe \n";
+#endif
+ } else {
+ std::string exedir = std::string(dirname(exe_file)) + "/";
+ std::string testdir = exedir + "./data/";
+ if(access(testdir.c_str(), F_OK) == 0) {
+ datadir = testdir;
+ }
+
+ testdir = exedir + "../share/supertux/";
+ if(datadir.empty() && access(testdir.c_str(), F_OK) == 0) {
+ datadir = testdir;
+ }
+ }
+ }
+#endif
+
+#ifdef DATA_PREFIX
+ // use default location
+ if(datadir.empty()) {
+ datadir = DATA_PREFIX;
+ }
+#endif
+
+ if(datadir.empty())
+ throw std::runtime_error("Couldn't find datadir");
+}
+
+static void init_tinygettext()
+{
+ dictionary_manager.add_directory(datadir + "/locale");
+ dictionary_manager.set_charset("iso8859-1");
+}
+
+static void print_usage(const char* argv0)
+{
+ fprintf(stderr, _("Usage: %s [OPTIONS] LEVELFILE\n\n"), argv0);
+ fprintf(stderr,
+ _("Options:\n"
+ " -f, --fullscreen Run in fullscreen mode.\n"
+ " -w, --window Run in window mode.\n"
+ " -g, --geometry WIDTHxHEIGHT Run SuperTux in give resolution\n"
+ " --help Show this help message\n"
+ " --version Display SuperTux version and quit\n"
+ "\n"));
+}
+
+static void parse_commandline(int argc, char** argv)
+{
+ for(int i = 1; i < argc; ++i) {
+ std::string arg = argv[i];
+
+ if(arg == "--fullscreen" || arg == "-f") {
+ config->use_fullscreen = true;
+ } else if(arg == "--window" || arg == "-w") {
+ config->use_fullscreen = false;
+ } else if(arg == "--geometry" || arg == "-g") {
+ if(i+1 >= argc) {
+ print_usage(argv[0]);
+ throw std::runtime_error("Need to specify a parameter for geometry switch");
+ }
+ if(sscanf(argv[++i], "%dx%d", &config->screenwidth, &config->screenheight)
+ != 2) {
+ print_usage(argv[0]);
+ throw std::runtime_error("Invalid geometry spec, should be WIDTHxHEIGHT");
+ }
+ } else if(arg == "--show-fps") {
+ config->show_fps = true;
+ } else if(arg == "--help") {
+ print_usage(argv[0]);
+ throw std::runtime_error("");
+ } else if(arg == "--version") {
+ std::cerr << PACKAGE_NAME << " " << PACKAGE_VERSION << "\n";
+ throw std::runtime_error("");
+ } else if(arg[0] != '-') {
+ config->start_level = arg;
+ } else {
+ std::cerr << "Unknown option '" << arg << "'.\n";
+ std::cerr << "Use --help to see a list of options.\n";
+ }
+ }
+
+ // TODO joystick switchyes...
+}
+
+static void init_sdl()
+{
+ if(SDL_Init(SDL_INIT_EVERYTHING) < 0) {
+ std::stringstream msg;
+ msg << "Couldn't initialize SDL: " << SDL_GetError();
+ throw std::runtime_error(msg.str());
+ }
+
+ SDL_EnableUNICODE(1);
+}
+
+static void check_gl_error()
+{
+ GLenum glerror = glGetError();
+ std::string errormsg;
+
+ if(glerror != GL_NO_ERROR) {
+ switch(glerror) {
+ case GL_INVALID_ENUM:
+ errormsg = "Invalid enumeration value";
+ break;
+ case GL_INVALID_VALUE:
+ errormsg = "Numeric argzment out of range";
+ break;
+ case GL_INVALID_OPERATION:
+ errormsg = "Invalid operation";
+ break;
+ case GL_STACK_OVERFLOW:
+ errormsg = "stack overflow";
+ break;
+ case GL_STACK_UNDERFLOW:
+ errormsg = "stack underflow";
+ break;
+ case GL_OUT_OF_MEMORY:
+ errormsg = "out of memory";
+ break;
+ case GL_TABLE_TOO_LARGE:
+ errormsg = "table too large";
+ break;
+ default:
+ errormsg = "unknown error number";
+ break;
+ }
+ std::stringstream msg;
+ msg << "OpenGL Error: " << errormsg;
+ throw std::runtime_error(msg.str());
+ }
+}
+
+void init_video()
+{
+ SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
+ SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
+ SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
+ SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
+
+ int flags = SDL_OPENGL;
+ if(config->use_fullscreen)
+ flags |= SDL_FULLSCREEN;
+ int width = config->screenwidth;
+ int height = config->screenheight;
+ int bpp = 0;
+
+ screen = SDL_SetVideoMode(width, height, bpp, flags);
+ if(screen == 0) {
+ std::stringstream msg;
+ msg << "Couldn't set video mode (" << width << "x" << height
+ << "-" << bpp << "bpp): " << SDL_GetError();
+ throw std::runtime_error(msg.str());
+ }
+
+ SDL_WM_SetCaption(PACKAGE_NAME " " PACKAGE_VERSION, 0);
+
+ // set icon
+ SDL_Surface* icon = IMG_Load(
+ get_resource_filename("images/supertux.xpm").c_str());
+ if(icon != 0) {
+ SDL_WM_SetIcon(icon, 0);
+ SDL_FreeSurface(icon);
+ }
+#ifdef DEBUG
+ else {
+ std::cerr << "Warning: Couldn't find icon 'images/supertux.xpm'.\n";
+ }
+#endif
+
+ // setup opengl state and transform
+ glDisable(GL_DEPTH_TEST);
+ glDisable(GL_CULL_FACE);
+
+ glViewport(0, 0, screen->w, screen->h);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ // logical resolution here not real monitor resolution
+ glOrtho(0, 800, 600, 0, -1.0, 1.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0, 0, 0);
+
+ check_gl_error();
+
+ Surface::reload_all();
+}
+
+static void init_audio()
+{
+ sound_manager = new SoundManager();
+
+ int format = MIX_DEFAULT_FORMAT;
+ if(Mix_OpenAudio(config->audio_frequency, format, config->audio_channels,
+ config->audio_chunksize) < 0) {
+ std::cerr << "Couldn't initialize audio ("
+ << config->audio_frequency << "HZ, " << config->audio_channels
+ << " Channels, Format " << format << ", ChunkSize "
+ << config->audio_chunksize << "): " << SDL_GetError() << "\n";
+ return;
+ }
+ sound_manager->set_audio_device_available(true);
+ sound_manager->enable_sound(config->sound_enabled);
+ sound_manager->enable_music(config->music_enabled);
+
+ if(Mix_AllocateChannels(config->audio_voices) < 0) {
+ std::cerr << "Couldn't allocate '" << config->audio_voices << "' audio voices: "
+ << SDL_GetError() << "\n";
+ return;
+ }
+}
+
+static void quit_audio()
+{
+ if(sound_manager) {
+ if(sound_manager->audio_device_available())
+ Mix_CloseAudio();
+
+ delete sound_manager;
+ sound_manager = 0;
+ }
+}
+
+int main(int argc, char** argv)
+{
+#ifndef DEBUG // we want backtraces in debug mode so don't catch exceptions
+ try {
+#endif
+ srand(time(0));
+ init_sdl();
+ main_controller = new JoystickKeyboardController();
+ find_directories();
+ init_config();
+ init_tinygettext();
+ parse_commandline(argc, argv);
+ init_audio();
+ init_video();
+
+ setup_menu();
+ load_shared();
+ if(config->start_level != "") {
+ GameSession session(config->start_level, ST_GL_LOAD_LEVEL_FILE);
+ session.run();
+ } else {
+ // normal game
+ title();
+ }
+
+#ifndef DEBUG
+ } catch(std::exception& e) {
+ std::cerr << "Unexpected exception: " << e.what() << std::endl;
+ return 1;
+ } catch(...) {
+ std::cerr << "Unexpected exception." << std::endl;
+ return 1;
+ }
+#endif
+
+ free_menu();
+ unload_shared();
+#ifdef DEBUG
+ Surface::debug_check();
+#endif
+ quit_audio();
+
+ if(config)
+ config->save();
+ delete config;
+ delete main_controller;
+ SDL_Quit();
+
+ return 0;
+}
--- /dev/null
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __MAIN_H__
+#define __MAIN_H__
+
+enum GlobalGameState {
+ /** the title screen is showing */
+ STATE_TITLE,
+ /** the worldmap is shown */
+ STATE_WORLDMAP,
+ /** a level is played */
+ STATE_GAMESESSION
+};
+
+void init_video();
+
+class JoystickKeyboardController;
+
+// global variables
+extern JoystickKeyboardController* main_controller;
+
+#endif
// 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 <config.h>
#include "misc.h"
+#include "main.h"
+#include "gameconfig.h"
#include "app/globals.h"
-
-void MyConfig::customload(const lisp::Lisp& reader)
-{
- reader.get("keyboard-up", keymap.up);
- reader.get("keyboard-down", keymap.down);
- reader.get("keyboard-left", keymap.left);
- reader.get("keyboard-right", keymap.right);
- reader.get("keyboard-jump", keymap.jump);
- reader.get("keyboard-power", keymap.power);
-}
-
-void MyConfig::customsave(FILE * config)
+#include "game_session.h"
+#include "control/joystickkeyboardcontroller.h"
+
+Menu* main_menu = 0;
+Menu* game_menu = 0;
+Menu* options_menu = 0;
+Menu* options_keys_menu = 0;
+Menu* options_joystick_menu = 0;
+Menu* highscore_menu = 0;
+Menu* load_game_menu = 0;
+Menu* save_game_menu = 0;
+Menu* contrib_menu = 0;
+Menu* contrib_subset_menu = 0;
+
+void process_options_menu()
{
- fprintf(config, "\t(keyboard-up %d)\n", keymap.up);
- fprintf(config, "\t(keyboard-down %d)\n", keymap.down);
- fprintf(config, "\t(keyboard-left %d)\n", keymap.left);
- fprintf(config, "\t(keyboard-right %d)\n", keymap.right);
- fprintf(config, "\t(keyboard-jump %d)\n", keymap.jump);
- fprintf(config, "\t(keyboard-power %d)\n", keymap.power);
-}
-
-void process_options_menu(void)
-{
- switch (options_menu->check())
- {
- case MNID_OPENGL:
-#ifndef NOOPENGL
- if(use_gl != options_menu->isToggled(MNID_OPENGL))
- {
- use_gl = !use_gl;
- Setup::video(SCREEN_WIDTH,SCREEN_HEIGHT);
- }
-#else
- options_menu->get_item_by_id(MNID_OPENGL).toggled = false;
-#endif
- break;
+ switch (options_menu->check()) {
case MNID_FULLSCREEN:
- if(use_fullscreen != options_menu->isToggled(MNID_FULLSCREEN))
- {
- use_fullscreen = !use_fullscreen;
- Setup::video(SCREEN_WIDTH,SCREEN_HEIGHT);
- }
+ if(config->use_fullscreen != options_menu->is_toggled(MNID_FULLSCREEN)) {
+ config->use_fullscreen = !config->use_fullscreen;
+ init_video();
+ }
break;
case MNID_SOUND:
- if(SoundManager::get()->sound_enabled() != options_menu->isToggled(MNID_SOUND))
- SoundManager::get()->enable_sound(!SoundManager::get()->sound_enabled());
+ if(config->sound_enabled != options_menu->is_toggled(MNID_SOUND)) {
+ config->sound_enabled = !config->sound_enabled;
+ sound_manager->enable_sound(config->sound_enabled);
+ }
break;
case MNID_MUSIC:
- if(SoundManager::get()->music_enabled() != options_menu->isToggled(MNID_MUSIC))
- {
- SoundManager::get()->enable_music(!SoundManager::get()->music_enabled());
- }
+ if(config->music_enabled != options_menu->is_toggled(MNID_MUSIC)) {
+ config->music_enabled = !config->music_enabled;
+ sound_manager->enable_music(config->music_enabled);
+ }
break;
- case MNID_SHOWFPS:
- if(show_fps != options_menu->isToggled(MNID_SHOWFPS))
- show_fps = !show_fps;
+ default:
break;
- }
+ }
}
-void st_menu(void)
+void setup_menu()
{
main_menu = new Menu();
options_menu = new Menu();
- options_keys_menu = new Menu();
- options_joystick_menu = new Menu();
load_game_menu = new Menu();
- save_game_menu = new Menu();
game_menu = new Menu();
- highscore_menu = new Menu();
contrib_menu = new Menu();
contrib_subset_menu = new Menu();
worldmap_menu = new Menu();
main_menu->set_pos(SCREEN_WIDTH/2, 335);
- main_menu->additem(MN_GOTO, _("Start Game"),0,load_game_menu, MNID_STARTGAME);
- main_menu->additem(MN_GOTO, _("Contrib Levels"),0,contrib_menu, MNID_LEVELS_CONTRIB);
- main_menu->additem(MN_GOTO, _("Options"),0,options_menu, MNID_OPTIONMENU);
- main_menu->additem(MN_ACTION, _("Level Editor"),0,0, MNID_LEVELEDITOR);
- main_menu->additem(MN_ACTION, _("Credits"),0,0, MNID_CREDITS);
- main_menu->additem(MN_ACTION, _("Quit"),0,0, MNID_QUITMAINMENU);
-
- options_menu->additem(MN_LABEL,_("Options"),0,0);
- options_menu->additem(MN_HL,"",0,0);
-#ifndef NOOPENGL
- options_menu->additem(MN_TOGGLE,_("OpenGL "),use_gl,0, MNID_OPENGL);
-#else
- options_menu->additem(MN_DEACTIVE,_("OpenGL (not supported)"),use_gl, 0, MNID_OPENGL);
-#endif
- options_menu->additem(MN_TOGGLE,_("Fullscreen"),use_fullscreen,0, MNID_FULLSCREEN);
- if(SoundManager::get()->audio_device_available())
- {
- options_menu->additem(MN_TOGGLE,_("Sound "), SoundManager::get()->sound_enabled(),0, MNID_SOUND);
- options_menu->additem(MN_TOGGLE,_("Music "), SoundManager::get()->music_enabled(),0, MNID_MUSIC);
- }
- else
- {
- options_menu->additem(MN_DEACTIVE,_("Sound "), false,0, MNID_SOUND);
- options_menu->additem(MN_DEACTIVE,_("Music "), false,0, MNID_MUSIC);
- }
- options_menu->additem(MN_TOGGLE,_("Show FPS "),show_fps,0, MNID_SHOWFPS);
- options_menu->additem(MN_GOTO,_("Setup Keys"),0,options_keys_menu);
-
- if(use_joystick)
- options_menu->additem(MN_GOTO,_("Setup Joystick"),0,options_joystick_menu);
-
- options_menu->additem(MN_HL,"",0,0);
- options_menu->additem(MN_BACK,_("Back"),0,0);
+ main_menu->add_submenu(_("Start Game"), load_game_menu, MNID_STARTGAME);
+ main_menu->add_submenu(_("Contrib Levels"), contrib_menu, MNID_LEVELS_CONTRIB);
+ main_menu->add_submenu(_("Options"), options_menu);
+ main_menu->add_entry(MNID_LEVELEDITOR, _("Level Editor"));
+ main_menu->add_entry(MNID_CREDITS, _("Credits"));
+ main_menu->add_entry(MNID_QUITMAINMENU, _("Quit"));
- options_keys_menu->additem(MN_LABEL,_("Keyboard Setup"),0,0);
- options_keys_menu->additem(MN_HL,"",0,0);
- options_keys_menu->additem(MN_CONTROLFIELD_KB,_("Left move"), 0,0, 0,&keymap.left);
- options_keys_menu->additem(MN_CONTROLFIELD_KB,_("Right move"), 0,0, 0,&keymap.right);
- options_keys_menu->additem(MN_CONTROLFIELD_KB,_("Up/Activate"), 0,0, 0,&keymap.up);
- options_keys_menu->additem(MN_CONTROLFIELD_KB,_("Down/Duck"), 0,0, 0,&keymap.down);
- options_keys_menu->additem(MN_CONTROLFIELD_KB,_("Jump"), 0,0, 0,&keymap.jump);
- options_keys_menu->additem(MN_CONTROLFIELD_KB,_("Power/Run"), 0,0, 0,&keymap.power);
- options_keys_menu->additem(MN_HL,"",0,0);
- options_keys_menu->additem(MN_BACK,_("Back"),0,0);
-
- if(use_joystick)
- {
- options_joystick_menu->additem(MN_LABEL,_("Joystick Setup"),0,0);
- options_joystick_menu->additem(MN_HL,"",0,0);
- //options_joystick_menu->additem(MN_CONTROLFIELD_JS,"X axis", 0,0, 0,&joystick_keymap.x_axis);
- //options_joystick_menu->additem(MN_CONTROLFIELD_JS,"Y axis", 0,0, 0,&joystick_keymap.y_axis);
- options_joystick_menu->additem(MN_CONTROLFIELD_JS,_("A button"), 0,0, 0,&joystick_keymap.a_button);
- options_joystick_menu->additem(MN_CONTROLFIELD_JS,_("B button"), 0,0, 0,&joystick_keymap.b_button);
- //options_joystick_menu->additem(MN_CONTROLFIELD_JS,"Start", 0,0, 0,&joystick_keymap.start_button);
- //options_joystick_menu->additem(MN_CONTROLFIELD_JS,"DeadZone", 0,0, 0,&joystick_keymap.dead_zone);
- options_joystick_menu->additem(MN_HL,"",0,0);
- options_joystick_menu->additem(MN_BACK,_("Back"),0,0);
- }
+ options_menu->add_label(_("Options"));
+ options_menu->add_hl();
+ options_menu->add_toggle(MNID_FULLSCREEN,_("Fullscreen"), config->use_fullscreen);
+ options_menu->add_toggle(MNID_SOUND, _("Sound"), config->sound_enabled);
+ options_menu->add_toggle(MNID_MUSIC, _("Music"), config->music_enabled);
+ options_menu->add_submenu(_("Setup Keys"),
+ main_controller->get_key_options_menu());
+ options_menu->add_submenu(_("Setup Joystick"),
+ main_controller->get_joystick_options_menu());
+ options_menu->add_hl();
+ options_menu->add_back(_("Back"));
- load_game_menu->additem(MN_LABEL,_("Start Game"),0,0);
- load_game_menu->additem(MN_HL,"",0,0);
- load_game_menu->additem(MN_DEACTIVE,"Slot 1",0,0, 1);
- load_game_menu->additem(MN_DEACTIVE,"Slot 2",0,0, 2);
- load_game_menu->additem(MN_DEACTIVE,"Slot 3",0,0, 3);
- load_game_menu->additem(MN_DEACTIVE,"Slot 4",0,0, 4);
- load_game_menu->additem(MN_DEACTIVE,"Slot 5",0,0, 5);
- load_game_menu->additem(MN_HL,"",0,0);
- load_game_menu->additem(MN_BACK,_("Back"),0,0);
-
- save_game_menu->additem(MN_LABEL,_("Save Game"),0,0);
- save_game_menu->additem(MN_HL,"",0,0);
- save_game_menu->additem(MN_DEACTIVE,"Slot 1",0,0, 1);
- save_game_menu->additem(MN_DEACTIVE,"Slot 2",0,0, 2);
- save_game_menu->additem(MN_DEACTIVE,"Slot 3",0,0, 3);
- save_game_menu->additem(MN_DEACTIVE,"Slot 4",0,0, 4);
- save_game_menu->additem(MN_DEACTIVE,"Slot 5",0,0, 5);
- save_game_menu->additem(MN_HL,"",0,0);
- save_game_menu->additem(MN_BACK,"Back",0,0);
-
- game_menu->additem(MN_LABEL,_("Pause"),0,0);
- game_menu->additem(MN_HL,"",0,0);
- game_menu->additem(MN_ACTION,_("Continue"),0,0,MNID_CONTINUE);
- game_menu->additem(MN_GOTO,_("Options"),0,options_menu);
- game_menu->additem(MN_HL,"",0,0);
- game_menu->additem(MN_ACTION,_("Abort Level"),0,0,MNID_ABORTLEVEL);
-
- worldmap_menu->additem(MN_LABEL,_("Pause"),0,0);
- worldmap_menu->additem(MN_HL,"",0,0);
- worldmap_menu->additem(MN_ACTION,_("Continue"),0,0, WorldMapNS::MNID_RETURNWORLDMAP);
- worldmap_menu->additem(MN_GOTO,_("Options"),0, options_menu);
- worldmap_menu->additem(MN_HL,"",0,0);
- worldmap_menu->additem(MN_ACTION,_("Quit Game"),0,0, WorldMapNS::MNID_QUITWORLDMAP);
-
- highscore_menu->additem(MN_TEXTFIELD,_("Enter your name:"),0,0);
+ load_game_menu->add_label(_("Start Game"));
+ load_game_menu->add_hl();
+ load_game_menu->add_deactive(1, "Slot 1");
+ load_game_menu->add_deactive(2, "Slot 2");
+ load_game_menu->add_deactive(3, "Slot 3");
+ load_game_menu->add_deactive(4, "Slot 4");
+ load_game_menu->add_deactive(5, "Slot 5");
+ load_game_menu->add_hl();
+ load_game_menu->add_back(_("Back"));
+
+ game_menu->add_label(_("Pause"));
+ game_menu->add_hl();
+ game_menu->add_entry(MNID_CONTINUE, _("Continue"));
+ game_menu->add_submenu(_("Options"), options_menu);
+ game_menu->add_hl();
+ game_menu->add_entry(MNID_ABORTLEVEL, _("Abort Level"));
+
+ worldmap_menu->add_label(_("Pause"));
+ worldmap_menu->add_hl();
+ worldmap_menu->add_entry(WorldMapNS::MNID_RETURNWORLDMAP, _("Continue"));
+ worldmap_menu->add_submenu(_("Options"), options_menu);
+ worldmap_menu->add_hl();
+ worldmap_menu->add_entry(WorldMapNS::MNID_QUITWORLDMAP, _("Quit Game"));
}
-/* Free menus */
-void st_menu_free()
+void free_menu()
{
delete worldmap_menu;
delete main_menu;
delete game_menu;
delete options_menu;
- delete options_keys_menu;
- delete options_joystick_menu;
- delete highscore_menu;
delete contrib_menu;
delete contrib_subset_menu;
- delete save_game_menu;
delete load_game_menu;
}
+
#include "app/setup.h"
#include "app/gettext.h"
#include "gui/menu.h"
-#include "utils/configfile.h"
+#include "gameconfig.h"
#include "title.h"
#include "resources.h"
#include "worldmap.h"
-#include "gameloop.h"
#include "object/player.h"
-class MyConfig : public Config
-{
- public:
- void customload(const lisp::Lisp& reader);
- void customsave(FILE * config);
-};
-
enum OptionsMenuIDs {
- MNID_OPENGL,
MNID_FULLSCREEN,
MNID_SOUND,
- MNID_MUSIC,
- MNID_SHOWFPS
- };
+ MNID_MUSIC
+};
/* Handle changes made to global settings in the options menu. */
void process_options_menu();
/* Create and setup menus. */
-void st_menu();
-void st_menu_free();
+void setup_menu();
+void free_menu();
-#endif //SUPERTUX_MISC_H
+#endif
--- /dev/null
+// $Id: moving_object.cpp 2168 2004-11-24 14:10:27Z matzebraun $
+//
+// SuperTux - A Jump'n Run
+// Copyright (C) 2004 Matthias Braun <matze@braunis.de
+//
+// 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 <config.h>
+
+#include "moving_object.h"
+
+MovingObject::MovingObject()
+{
+}
+
+MovingObject::~MovingObject()
+{
+}
#include "video/surface.h"
#include "video/drawing_context.h"
-#include "special/game_object.h"
+#include "game_object.h"
#include "serializable.h"
using namespace SuperTux;
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "bell.h"
#include "resources.h"
-#include "special/sprite_manager.h"
+#include "sprite/sprite_manager.h"
#include "video/drawing_context.h"
#include "player.h"
#include "object_factory.h"
-#include "gameloop.h"
+#include "game_session.h"
#include "sector.h"
Bell::Bell(const lisp::Lisp& lisp)
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __BELL_H__
#define __BELL_H__
#include "lisp/lisp.h"
-#include "special/moving_object.h"
-#include "special/sprite.h"
+#include "moving_object.h"
+#include "sprite/sprite.h"
#include "serializable.h"
using namespace SuperTux;
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "block.h"
#include "resources.h"
#include "player.h"
#include "sector.h"
-#include "special/sprite.h"
-#include "special/sprite_manager.h"
+#include "sprite/sprite.h"
+#include "sprite/sprite_manager.h"
#include "video/drawing_context.h"
#include "lisp/lisp.h"
#include "gameobjs.h"
BonusBlock::try_open()
{
if(sprite->get_action_name() == "empty") {
- SoundManager::get()->play_sound(IDToSound(SND_BRICK));
+ sound_manager->play_sound("brick");
return;
}
new Flower(get_pos() + Vector(0, -32), Flower::FIREFLOWER));
sector->add_object(riser);
}
- SoundManager::get()->play_sound(IDToSound(SND_UPGRADE));
+ sound_manager->play_sound("upgrade");
break;
case CONTENT_ICEGROW:
new Flower(get_pos() + Vector(0, -32), Flower::ICEFLOWER));
sector->add_object(riser);
}
- SoundManager::get()->play_sound(IDToSound(SND_UPGRADE));
+ sound_manager->play_sound("upgrade");
break;
case CONTENT_STAR:
if(sprite->get_action_name() == "empty")
return;
- SoundManager::get()->play_sound(IDToSound(SND_BRICK));
+ sound_manager->play_sound("brick");
Sector* sector = Sector::current();
Player& player = *(sector->player);
if(coin_counter > 0) {
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __BLOCK_H__
#define __BLOCK_H__
-#include "special/moving_object.h"
+#include "moving_object.h"
#include "lisp/lisp.h"
-namespace SuperTux {
- class Sprite;
-}
+class Sprite;
class Player;
using namespace SuperTux;
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include <math.h>
#include "camera.h"
#include "sector.h"
#include "app/globals.h"
-#include "special/sprite_manager.h"
+#include "sprite/sprite_manager.h"
#include "badguy/badguy.h"
static const float BULLET_XM = 300;
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __BULLET_H__
#define __BULLET_H__
-#include "special/moving_object.h"
+#include "moving_object.h"
#include "math/physic.h"
-#include "special/sprite.h"
+#include "sprite/sprite.h"
using namespace SuperTux;
#include "camera.h"
#include "player.h"
#include "tilemap.h"
-#include "gameloop.h"
+#include "game_session.h"
#include "app/globals.h"
#include "sector.h"
#include "object_factory.h"
#include <cassert>
#include "math/vector.h"
-#include "special/game_object.h"
+#include "game_object.h"
#include "video/drawing_context.h"
#include "serializable.h"
#include "timer.h"
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "coin.h"
#include "resources.h"
#include "video/drawing_context.h"
-#include "special/sprite_manager.h"
+#include "sprite/sprite_manager.h"
#include "player.h"
#include "sector.h"
#include "player_status.h"
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __COIN_H__
#define __COIN_H__
-#include "special/moving_object.h"
+#include "moving_object.h"
#include "lisp/lisp.h"
-namespace SuperTux {
- class Sprite;
-}
+class Sprite;
using namespace SuperTux;
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "fireworks.h"
sector->add_object(new Particles(pos, 0, 360, Vector(140, 140),
Vector(0, 0), 45, Color(red, green, 0), 3, 1.3,
LAYER_FOREGROUND1+1));
- SoundManager::get()->play_sound(IDToSound(SND_FIREWORKS));
+ sound_manager->play_sound("fireworks");
timer.start(((float) rand() / RAND_MAX) + .5);
}
}
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __FIREWORKS_H__
#define __FIREWORKS_H__
#include "video/drawing_context.h"
-#include "special/game_object.h"
+#include "game_object.h"
#include "timer.h"
-class Fireworks : public SuperTux::GameObject
+class Fireworks : public GameObject
{
public:
- Fireworks();
- ~Fireworks();
+ Fireworks();
+ ~Fireworks();
- virtual void action(float elapsed_time);
- virtual void draw(SuperTux::DrawingContext& context);
+ virtual void action(float elapsed_time);
+ virtual void draw(DrawingContext& context);
private:
- Timer2 timer;
+ Timer2 timer;
};
#endif
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include <math.h>
#include "sector.h"
#include "player.h"
#include "app/globals.h"
-#include "special/sprite_manager.h"
+#include "sprite/sprite_manager.h"
Flower::Flower(const Vector& pos, Type _type)
: type(_type)
else
player->set_bonus(ICE_BONUS, true);
- SoundManager::get()->play_sound(IDToSound(SND_COFFEE));
+ sound_manager->play_sound("fire-flower");
remove_me();
return ABORT_MOVE;
}
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __FLOWER_H__
#define __FLOWER_H__
-#include "special/moving_object.h"
-#include "special/sprite.h"
+#include "moving_object.h"
+#include "sprite/sprite.h"
#include "math/physic.h"
using namespace SuperTux;
#include "app/globals.h"
#include "tile.h"
#include "tile_manager.h"
-#include "gameloop.h"
+#include "game_session.h"
#include "gameobjs.h"
-#include "special/sprite_manager.h"
+#include "sprite/sprite_manager.h"
#include "resources.h"
#include "sector.h"
#include "tilemap.h"
#include "video/surface.h"
#include "timer.h"
#include "math/physic.h"
-#include "special/game_object.h"
-#include "special/moving_object.h"
+#include "game_object.h"
+#include "moving_object.h"
#include "serializable.h"
/* Bounciness of distros: */
#define NO_BOUNCE 0
#define BOUNCE 1
-namespace SuperTux {
class Sprite;
-}
class BouncyCoin : public GameObject
{
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include <math.h>
#include "sector.h"
#include "player.h"
#include "app/globals.h"
-#include "special/sprite_manager.h"
+#include "sprite/sprite_manager.h"
GrowUp::GrowUp(const Vector& pos)
{
Player* player = dynamic_cast<Player*>(&other);
if(player != 0) {
player->set_bonus(GROWUP_BONUS, true);
- SoundManager::get()->play_sound(IDToSound(SND_EXCELLENT));
+ sound_manager->play_sound("grow");
remove_me();
return ABORT_MOVE;
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __GROWUP_H__
#define __GROWUP_H__
-#include "special/moving_object.h"
-#include "special/sprite.h"
+#include "moving_object.h"
+#include "sprite/sprite.h"
#include "math/physic.h"
using namespace SuperTux;
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "infoblock.h"
-#include "gameloop.h"
+#include "game_session.h"
#include "resources.h"
-#include "special/sprite_manager.h"
+#include "sprite/sprite_manager.h"
#include "object_factory.h"
#include "lisp/lisp.h"
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __INFOBLOCK_H__
#define __INFOBLOCK_H__
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "invisible_block.h"
#include "resources.h"
-#include "special/sprite.h"
-#include "special/sprite_manager.h"
+#include "sprite/sprite.h"
+#include "sprite/sprite_manager.h"
#include "video/drawing_context.h"
#include "object_factory.h"
return;
sprite->set_action("empty");
- SoundManager::get()->play_sound(IDToSound(SND_BRICK));
+ sound_manager->play_sound("brick");
start_bounce();
flags |= FLAG_SOLID;
visible = true;
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __INVISIBLE_BLOCK_H__
#define __INVISIBLE_BLOCK_H__
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "oneup.h"
#include "player.h"
#include "player_status.h"
#include "sector.h"
-#include "special/sprite_manager.h"
+#include "sprite/sprite_manager.h"
#include "video/drawing_context.h"
OneUp::OneUp(const Vector& pos)
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __ONEUP_H__
#define __ONEUP_H__
-#include "special/moving_object.h"
-#include "special/sprite.h"
+#include "moving_object.h"
+#include "sprite/sprite.h"
#include "math/physic.h"
using namespace SuperTux;
#include <vector>
#include "video/surface.h"
-#include "special/game_object.h"
+#include "game_object.h"
#include "serializable.h"
using namespace SuperTux;
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "platform.h"
#include "video/drawing_context.h"
#include "resources.h"
#include "player.h"
-#include "special/sprite_manager.h"
+#include "sprite/sprite_manager.h"
#include "lisp/lisp.h"
#include "lisp/writer.h"
#include "object_factory.h"
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __PLATFORM_H__
#define __PLATFORM_H__
-#include "special/moving_object.h"
-#include "special/sprite.h"
+#include "moving_object.h"
+#include "sprite/sprite.h"
using namespace SuperTux;
/**
* This class is the base class for platforms that tux can stand on
*/
-class Platform : public SuperTux::MovingObject
+class Platform : public MovingObject
{
public:
Platform(const lisp::Lisp& reader);
#include "app/globals.h"
#include "app/gettext.h"
-#include "special/sprite_manager.h"
+#include "sprite/sprite_manager.h"
#include "player.h"
#include "tile.h"
-#include "special/sprite.h"
+#include "sprite/sprite.h"
#include "sector.h"
#include "resources.h"
#include "video/screen.h"
#include "statistics.h"
-#include "gameloop.h"
+#include "game_session.h"
#include "object/tilemap.h"
#include "object/camera.h"
#include "object/gameobjs.h"
#include "object/portable.h"
#include "trigger/trigger_base.h"
+#include "control/joystickkeyboardcontroller.h"
+#include "main.h"
static const int TILES_FOR_BUTTJUMP = 3;
static const float SHOOTING_TIME = .150;
TuxBodyParts* fire_tux = 0;
TuxBodyParts* ice_tux = 0;
-PlayerKeymap keymap;
-
-PlayerKeymap::PlayerKeymap()
-{
- keymap.up = SDLK_UP;
- keymap.down = SDLK_DOWN;
- keymap.left = SDLK_LEFT;
- keymap.right = SDLK_RIGHT;
-
- keymap.power = SDLK_LCTRL;
- keymap.jump = SDLK_SPACE;
-}
-
-PlayerInputType::PlayerInputType()
-{
- reset();
-}
-
-void
-PlayerInputType::reset()
-{
- up = false;
- old_up = false;
- down = false;
- fire = false;
- old_fire = false;
- left = false;
- right = false;
- jump = false;
- old_jump = false;
- activate = false;
-}
-
void
TuxBodyParts::set_action(std::string action, int loops)
{
Player::Player(PlayerStatus* _player_status)
: player_status(_player_status), grabbed_object(0)
{
+ controller = main_controller;
smalltux_gameover = sprite_manager->create("smalltux-gameover");
smalltux_star = sprite_manager->create("smalltux-star");
bigtux_star = sprite_manager->create("bigtux-star");
on_ground_flag = false;
grabbed_object = 0;
- input.reset();
physic.reset();
}
-bool
-Player::key_event(SDLKey key, bool state)
+void
+Player::set_controller(Controller* controller)
{
- idle_timer.start(IDLE_TIME, true);
-
- if(key == keymap.right)
- {
- input.right = state;
- return true;
- }
- else if(key == keymap.left)
- {
- input.left = state;
- return true;
- }
- else if(key == keymap.up)
- {
- if(state == false)
- input.old_up = false;
- input.up = state;
- /* Up key also opens activates stuff */
- input.activate = state;
- return true;
- }
- else if(key == keymap.down)
- {
- input.down = state;
- return true;
- }
- else if(key == keymap.power)
- {
- if(state == false)
- input.old_fire = false;
- input.fire = state;
-
- return true;
- }
- else if(key == keymap.jump)
- {
- if(state == false)
- input.old_jump = false;
- input.jump = state;
- return true;
- }
- else
- return false;
+ this->controller = controller;
}
void
return;
}
- if(input.fire == false && grabbed_object) {
+ if(!controller->hold(Controller::ACTION) && grabbed_object) {
grabbed_object = 0;
// move the grabbed object a bit away from tux
Vector pos = get_pos() +
float dirsign = 0;
if(!duck || physic.get_velocity_y() != 0) {
- if(input.left && !input.right) {
+ if(controller->hold(Controller::LEFT) && !controller->hold(Controller::RIGHT)) {
old_dir = dir;
dir = LEFT;
dirsign = -1;
- } else if(!input.left && input.right) {
+ } else if(!controller->hold(Controller::LEFT)
+ && controller->hold(Controller::RIGHT)) {
old_dir = dir;
dir = RIGHT;
dirsign = 1;
}
}
- if (!input.fire) {
+ if (!controller->hold(Controller::ACTION)) {
ax = dirsign * WALK_ACCELERATION_X;
// limit speed
if(vx >= MAX_WALK_XM && dirsign > 0) {
// let's skid!
if(fabs(vx)>SKID_XM && !skidding_timer.started()) {
skidding_timer.start(SKID_TIME);
- SoundManager::get()->play_sound(IDToSound(SND_SKID));
+ sound_manager->play_sound("skid");
// dust some partcles
Sector::current()->add_object(
new Particles(
}
// Press jump key
- if(input.jump && can_jump && on_ground())
+ if(controller->pressed(Controller::JUMP) && can_jump && on_ground()) {
+ if(duck) { // only jump a little bit when in duck mode {
+ 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(580);
+ else
+ physic.set_velocity_y(520);
+ }
+
+ //bbox.move(Vector(0, -1));
+ jumping = true;
+ flapping = false;
+ can_jump = false;
+ can_flap = false;
+ flaps_nb = 0; // Ricardo's flapping
+ if (is_big())
+ sound_manager->play_sound("bigjump");
+ else
+ sound_manager->play_sound("jump");
+ } else if(!controller->hold(Controller::JUMP)) { // Let go of jump key
+ if (!flapping && !duck && !falling_from_flap && !on_ground()) {
+ can_flap = true;
+ }
+ if (jumping && physic.get_velocity_y() > 0) {
+ jumping = false;
+ physic.set_velocity_y(0);
+ }
+ }
+
+ // temporary to help player's choosing a flapping
+ if(flapping_mode == RICARDO_FLAP) {
+ // Flapping, Ricardo's version
+ // similar to SM3 Fox
+ if(controller->pressed(Controller::JUMP) && can_flap && flaps_nb < 3) {
+ physic.set_velocity_y(350);
+ physic.set_velocity_x(physic.get_velocity_x() * 35);
+ flaps_nb++;
+ }
+ } else if(flapping_mode == MAREK_FLAP) {
+ // Flapping, Marek's version
+ if (controller->hold(Controller::JUMP) && can_flap)
{
- if(duck) { // only jump a little bit when in duck mode {
- 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(580);
- else
- physic.set_velocity_y(520);
+ if (!flapping_timer.started())
+ {
+ flapping_timer.start(TUX_FLAPPING_TIME);
+ flapping_velocity = physic.get_velocity_x();
+ }
+ if (flapping_timer.check())
+ {
+ can_flap = false;
+ falling_from_flap = true;
}
-
- //bbox.move(Vector(0, -1));
jumping = true;
- flapping = false;
- can_jump = false;
- can_flap = false;
- flaps_nb = 0; // Ricardo's flapping
- if (is_big())
- SoundManager::get()->play_sound(IDToSound(SND_BIGJUMP));
- else
- SoundManager::get()->play_sound(IDToSound(SND_JUMP));
+ flapping = true;
+ 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);
+ }
}
- // Let go of jump key
- else if(!input.jump)
+ } else if(flapping_mode == RYAN_FLAP) {
+ // Flapping, Ryan's version
+ if (controller->hold(Controller::JUMP) && can_flap)
{
- if (!flapping && !duck && !falling_from_flap && !on_ground())
- {
- can_flap = true;
- }
- if (jumping && physic.get_velocity_y() > 0)
- {
- jumping = false;
- physic.set_velocity_y(0);
- }
- }
-
- // temporary to help player's choosing a flapping
- if(flapping_mode == RICARDO_FLAP)
- {
- // Flapping, Ricardo's version
- // similar to SM3 Fox
- if(input.jump && !input.old_jump && can_flap && flaps_nb < 3)
- {
- physic.set_velocity_y(350);
- physic.set_velocity_x(physic.get_velocity_x() * 35);
- flaps_nb++;
- }
- }
- else if(flapping_mode == MAREK_FLAP)
- {
- // Flapping, Marek's version
- if (input.jump && can_flap)
- {
- if (!flapping_timer.started())
- {
- flapping_timer.start(TUX_FLAPPING_TIME);
- flapping_velocity = physic.get_velocity_x();
- }
- if (flapping_timer.check())
- {
- can_flap = false;
- falling_from_flap = true;
- }
- jumping = true;
- flapping = true;
- 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)
- {
- // Flapping, Ryan's version
- if (input.jump && can_flap)
- {
- if (!flapping_timer.started())
- {
- flapping_timer.start(TUX_FLAPPING_TIME);
- }
- if (flapping_timer.check())
- {
- can_flap = false;
- falling_from_flap = true;
- }
- jumping = true;
- flapping = true;
- if (flapping && flapping_timer.get_timegone() <= TUX_FLAPPING_TIME
- && physic.get_velocity_y() < 0)
- {
- float gravity = Sector::current()->gravity;
- (void)gravity;
- float xr = (fabsf(physic.get_velocity_x()) / MAX_RUN_XM);
-
- // XXX: magic numbers. should be a percent of gravity
- // gravity is (by default) -0.1f
- physic.set_acceleration_y(12 + 1*xr);
-
+ if (!flapping_timer.started())
+ {
+ flapping_timer.start(TUX_FLAPPING_TIME);
+ }
+ if (flapping_timer.check())
+ {
+ can_flap = false;
+ falling_from_flap = true;
+ }
+ jumping = true;
+ flapping = true;
+ if (flapping && flapping_timer.get_timegone() <= TUX_FLAPPING_TIME
+ && physic.get_velocity_y() < 0)
+ {
+ float gravity = Sector::current()->gravity;
+ (void)gravity;
+ float xr = (fabsf(physic.get_velocity_x()) / MAX_RUN_XM);
+
+ // XXX: magic numbers. should be a percent of gravity
+ // gravity is (by default) -0.1f
+ physic.set_acceleration_y(12 + 1*xr);
+
#if 0
- // To slow down x-vel when flapping (not working)
- if (fabsf(physic.get_velocity_x()) > MAX_WALK_XM)
- {
- if (physic.get_velocity_x() < 0)
- physic.set_acceleration_x(1.0f);
- else if (physic.get_velocity_x() > 0)
- physic.set_acceleration_x(-1.0f);
- }
+ // To slow down x-vel when flapping (not working)
+ if (fabsf(physic.get_velocity_x()) > MAX_WALK_XM)
+ {
+ if (physic.get_velocity_x() < 0)
+ physic.set_acceleration_x(1.0f);
+ else if (physic.get_velocity_x() > 0)
+ physic.set_acceleration_x(-1.0f);
+ }
#endif
- }
- }
- else
- {
- physic.set_acceleration_y(0);
- }
- }
-
- /* In case the player has pressed Down while in a certain range of air,
- enable butt jump action */
- if (input.down && !butt_jump && !duck)
- //if(tiles_on_air(TILES_FOR_BUTTJUMP) && jumping)
- butt_jump = true;
+ }
+ } else {
+ physic.set_acceleration_y(0);
+ }
+ }
- /* When Down is not held anymore, disable butt jump */
- if(butt_jump && !input.down)
+ /* In case the player has pressed Down while in a certain range of air,
+ enable butt jump action */
+ if (controller->hold(Controller::DOWN) && !butt_jump && !duck)
+ //if(tiles_on_air(TILES_FOR_BUTTJUMP) && jumping)
+ butt_jump = true;
+
+ /* When Down is not held anymore, disable butt jump */
+ if(butt_jump && !controller->hold(Controller::DOWN))
butt_jump = false;
-
+
#if 0
// Do butt jump
- if (butt_jump && on_ground() && is_big())
- {
+ if (butt_jump && on_ground() && is_big()) {
// Add a smoke cloud
if (duck)
Sector::current()->add_smoke_cloud(Vector(get_pos().x - 32, get_pos().y));
else
Sector::current()->add_smoke_cloud(
- Vector(get_pos().x - 32, get_pos().y + 32));
+ Vector(get_pos().x - 32, get_pos().y + 32));
butt_jump = false;
-
+
// Break bricks beneath Tux
if(Sector::current()->trybreakbrick(
- Vector(base.x + 1, base.y + base.height), false)
- || Sector::current()->trybreakbrick(
- Vector(base.x + base.width - 1, base.y + base.height), false))
- {
+ Vector(base.x + 1, base.y + base.height), false)
+ || Sector::current()->trybreakbrick(
+ Vector(base.x + base.width - 1, base.y + base.height), false)) {
physic.set_velocity_y(2);
butt_jump = true;
}
-
+
// Kill nearby badguys
std::vector<GameObject*> gameobjects = Sector::current()->gameobjects;
for (std::vector<GameObject*>::iterator i = gameobjects.begin();
i != gameobjects.end();
- i++)
- {
+ i++) {
BadGuy* badguy = dynamic_cast<BadGuy*> (*i);
- if(badguy)
- {
+ if(badguy) {
// don't kill when badguys are already dying or in a certain mode
if(badguy->dying == DYING_NOT && badguy->mode != BadGuy::BOMB_TICKING &&
- badguy->mode != BadGuy::BOMB_EXPLODE)
- {
- if (fabsf(base.x - badguy->base.x) < 96 &&
- fabsf(base.y - badguy->base.y) < 64)
- badguy->kill_me(25);
- }
+ badguy->mode != BadGuy::BOMB_EXPLODE) {
+ if (fabsf(base.x - badguy->base.x) < 96 &&
+ fabsf(base.y - badguy->base.y) < 64)
+ badguy->kill_me(25);
+ }
}
}
}
can_jump = true;
}
#endif
-
- // FIXME: why the heck is this here and not somewhere where the keys are
- // checked?!?
- input.old_jump = input.jump;
}
void
handle_horizontal_input();
/* Jump/jumping? */
- if (on_ground() && !input.jump)
+ if (on_ground() && !controller->hold(Controller::JUMP))
can_jump = true;
handle_vertical_input();
/* Shoot! */
- if (input.fire && !input.old_fire && player_status->bonus == FIRE_BONUS) {
+ if (controller->pressed(Controller::ACTION) && player_status->bonus == FIRE_BONUS) {
if(Sector::current()->add_bullet(
-// get_pos() + Vector(0, bbox.get_height()/2),
- get_pos() + ((dir == LEFT)? Vector(0, bbox.get_height()/2)
- : Vector(32, bbox.get_height()/2)),
- physic.get_velocity_x(), dir))
+ get_pos() + ((dir == LEFT)? Vector(0, bbox.get_height()/2)
+ : Vector(32, bbox.get_height()/2)),
+ physic.get_velocity_x(), dir))
shooting_timer.start(SHOOTING_TIME);
- // FIXME: why the heck is this here
- input.old_fire = false;
}
-
+
/* Duck! */
- if (input.down && is_big() && !duck
- && physic.get_velocity_y() == 0 && on_ground())
- {
- duck = true;
+ if (controller->hold(Controller::DOWN) && is_big() && !duck
+ && physic.get_velocity_y() == 0 && on_ground()) {
+ duck = true;
+ bbox.move(Vector(0, 32));
+ bbox.set_height(31.8);
+ } else if(!controller->hold(Controller::DOWN) && is_big() && duck) {
+ // try if we can really unduck
+ bbox.move(Vector(0, -32));
+ bbox.set_height(63.8);
+ duck = false;
+ // FIXME
+#if 0
+ // when unducking in air we need some space to do so
+ if(on_ground() || !collision_object_map(bbox)) {
+ duck = false;
+ } else {
+ // undo the ducking changes
bbox.move(Vector(0, 32));
bbox.set_height(31.8);
}
- else if(!input.down && is_big() && duck)
- {
- // try if we can really unduck
- bbox.move(Vector(0, -32));
- bbox.set_height(63.8);
- duck = false;
- // FIXME
-#if 0
- // when unducking in air we need some space to do so
- if(on_ground() || !collision_object_map(bbox)) {
- duck = false;
- } else {
- // undo the ducking changes
- bbox.move(Vector(0, 32));
- bbox.set_height(31.8);
- }
#endif
- }
+ }
}
void
return;
if(player_status->bonus == NO_BONUS) {
- bbox.set_height(63.8);
- bbox.move(Vector(0, -32));
- if(animate)
- growing_timer.start(GROWING_TIME);
+ bbox.set_height(63.8);
+ bbox.move(Vector(0, -32));
+ if(animate)
+ growing_timer.start(GROWING_TIME);
}
-
+
player_status->bonus = type;
}
smalltux_star->draw(context, get_pos(), layer + 5);
else
bigtux_star->draw(context, get_pos(), layer + 5);
- }
-
- if (debug_mode)
- context.draw_filled_rect(get_pos(),
- Vector(bbox.get_width(), bbox.get_height()),
- Color(75,75,75, 150), LAYER_OBJECTS+20);
+ }
}
HitResponse
Player::collision(GameObject& other, const CollisionHit& hit)
{
Portable* portable = dynamic_cast<Portable*> (&other);
- if(portable && grabbed_object == 0 && input.fire
- && fabsf(hit.normal.x) > .9) {
+ if(portable && grabbed_object == 0 && controller->hold(Controller::ACTION)
+ && fabsf(hit.normal.x) > .9) {
grabbed_object = portable;
return CONTINUE;
}
TriggerBase* trigger = dynamic_cast<TriggerBase*> (&other);
if(trigger) {
- if(input.up && !input.old_up)
+ if(controller->pressed(Controller::UP))
trigger->event(*this, TriggerBase::EVENT_ACTIVATE);
}
void
Player::make_invincible()
{
- SoundManager::get()->play_sound(IDToSound(SND_HERRING));
+ sound_manager->play_sound("invincible");
invincible_timer.start(TUX_INVINCIBLE_TIME);
Sector::current()->play_music(HERRING_MUSIC);
}
if(dying)
return;
- if(safe_timer.get_timeleft() > 0 || invincible_timer.get_timeleft() > 0)
+ if(mode != KILL &&
+ safe_timer.get_timeleft() > 0 || invincible_timer.get_timeleft() > 0)
return;
- SoundManager::get()->play_sound(IDToSound(SND_HURT));
+ sound_manager->play_sound("hurt");
physic.set_velocity_x(0);
duck = false;
last_ground_y = vector.y;
- input.reset();
physic.reset();
}
flapping = false;
falling_from_flap = false;
- if (input.jump)
+ if(controller->hold(Controller::JUMP))
physic.set_velocity_y(520);
else
physic.set_velocity_y(200);
#include "timer.h"
#include "direction.h"
#include "video/surface.h"
-#include "special/moving_object.h"
-#include "special/sprite.h"
+#include "moving_object.h"
+#include "sprite/sprite.h"
#include "math/physic.h"
+#include "control/controller.h"
#include "player_status.h"
using namespace SuperTux;
class Portable;
/* Times: */
-
-#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! */
-
-struct PlayerKeymap
-{
-public:
- int jump;
- int up;
- int down;
- int left;
- int right;
- int power;
-
- PlayerKeymap();
-};
-
-extern PlayerKeymap keymap;
-
-/** Contains a field of booleans that indicate wheter a button is pressed or
- * released. The old_ fields contain the state of the button at the previous
- * frame.
- */
-struct PlayerInputType
-{
-public:
- PlayerInputType();
- void reset();
-
- bool left;
- bool right;
- bool up;
- bool old_up;
- bool down;
- bool fire;
- bool old_fire;
- bool activate;
- bool jump;
- bool old_jump;
-};
+static const float TUX_SAFE_TIME = 1.250;
+static const float TUX_INVINCIBLE_TIME = 10.0;
+static const float TUX_INVINCIBLE_TIME_WARNING = 2.0;
+static const float TUX_FLAPPING_TIME = 1; /* How long Tux can flap his wings to gain additional jump height */
+static const float TIME_WARNING = 20; /* When to alert player they're low on time! */
+static const float GROWING_TIME = 1.0;
+static const int GROWING_FRAMES = 7;
class Camera;
class PlayerStatus;
-extern Surface* tux_life;
-
-#define GROWING_TIME 1.0
-#define GROWING_FRAMES 7
extern Surface* growingtux_left[GROWING_FRAMES];
extern Surface* growingtux_right[GROWING_FRAMES];
enum HurtMode { KILL, SHRINK };
enum FallMode { ON_GROUND, JUMPING, TRAMPOLINE_JUMP, FALLING };
- PlayerInputType input;
+ Controller* controller;
PlayerStatus* player_status;
bool duck;
bool dead;
public:
Player(PlayerStatus* player_status);
virtual ~Player();
-
- bool key_event(SDLKey key, bool state);
- void handle_input();
+
+ void set_controller(Controller* controller);
virtual void action(float elapsed_time);
virtual void draw(DrawingContext& context);
}
void kill(HurtMode mode);
- void player_remove_powerups();
void check_bounds(Camera* camera);
void move(const Vector& vector);
void set_bonus(BonusType type, bool animate = false);
bool is_big();
private:
+ void handle_input();
bool on_ground();
void init();
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __PORTABLE_H__
#define __PORTABLE_H__
-#include "special/moving_object.h"
+#include "moving_object.h"
using namespace SuperTux;
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "rock.h"
-#include "special/sprite.h"
-#include "special/sprite_manager.h"
+#include "sprite/sprite.h"
+#include "sprite/sprite_manager.h"
#include "lisp/writer.h"
#include "video/drawing_context.h"
#include "resources.h"
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __ROCK_H__
#define __ROCK_H__
-#include "special/moving_object.h"
+#include "moving_object.h"
#include "math/physic.h"
#include "lisp/lisp.h"
#include "portable.h"
#include "serializable.h"
-namespace SuperTux {
- class Sprite;
-}
+class Sprite;
class Rock : public MovingObject, public Portable, public Serializable
{
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include <math.h>
#include "camera.h"
#include "sector.h"
#include "app/globals.h"
-#include "special/sprite_manager.h"
+#include "sprite/sprite_manager.h"
SpecialRiser::SpecialRiser(MovingObject* _child)
: child(_child)
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __SPECIALRISE_H__
#define __SPECIALRISE_H__
-#include "special/moving_object.h"
+#include "moving_object.h"
using namespace SuperTux;
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "star.h"
#include "resources.h"
#include "player.h"
#include "player_status.h"
-#include "special/sprite_manager.h"
+#include "sprite/sprite_manager.h"
#include "video/drawing_context.h"
static const float INITIALJUMP = 400;
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __STAR_H__
#define __STAR_H__
-#include "special/moving_object.h"
-#include "special/sprite.h"
+#include "moving_object.h"
+#include "sprite/sprite.h"
#include "math/physic.h"
using namespace SuperTux;
}
}
+#if 0
if (debug_grid)
{
for (pos.x = start_x; pos.x < end_x; pos.x += 32)
Color(225, 225, 225), LAYER_GUI-50);
}
}
+#endif
context.pop_transform();
}
#include <vector>
#include <stdint.h>
-#include "special/game_object.h"
+#include "game_object.h"
#include "serializable.h"
#include "math/vector.h"
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "unstable_tile.h"
#include "player.h"
#include "sector.h"
#include "resources.h"
-#include "special/sprite_manager.h"
-#include "special/sprite.h"
+#include "sprite/sprite_manager.h"
+#include "sprite/sprite.h"
static const float CRACKTIME = 0.3;
static const float FALLTIME = 0.8;
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __UNSTABLE_TILE_H__
#define __UNSTABLE_TILE_H__
-#include "special/moving_object.h"
+#include "moving_object.h"
#include "lisp/lisp.h"
#include "math/physic.h"
#include "timer.h"
-namespace SuperTux {
- class Sprite;
-}
+class Sprite;
class Player;
using namespace SuperTux;
#include <map>
#include "lisp/lisp.h"
-#include "special/game_object.h"
+#include "game_object.h"
#include "math/vector.h"
using namespace SuperTux;
--- /dev/null
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __OBJECT_REMOVE_LISTENER_H__
+#define __OBJECT_REMOVE_LISTENER_H__
+
+class GameObject;
+
+class ObjectRemoveListener
+{
+public:
+ virtual ~ObjectRemoveListener()
+ {}
+
+ virtual void object_removed(GameObject* object) = 0;
+};
+
+#endif
+
PlayerStatus player_status;
PlayerStatus::PlayerStatus()
- : distros(0),
+ : coins(0),
lives(START_LIVES),
bonus(NO_BONUS),
score_multiplier(1),
void PlayerStatus::reset()
{
- distros = 0;
+ coins = 0;
lives = START_LIVES;
bonus = NO_BONUS;
score_multiplier = 1;
{
if(lives < MAX_LIVES)
++lives;
- SoundManager::get()->play_sound(IDToSound(SND_LIFEUP));
+ sound_manager->play_sound("lifeup");
}
void
PlayerStatus::incCoins()
{
- distros++;
- if(distros >= 100) {
+ coins++;
+ if(coins >= 100) {
incLives();
- distros = 0;
+ coins = 0;
}
- SoundManager::get()->play_sound(IDToSound(SND_DISTRO));
+ sound_manager->play_sound("coin");
}
void
}
writer.write_int("lives", lives);
- writer.write_int("distros", distros);
+ writer.write_int("coins", coins);
writer.write_int("max-score-multiplier", max_score_multiplier);
}
}
lisp.get("lives", lives);
- lisp.get("distros", distros);
+ lisp.get("coins", coins);
lisp.get("max-score-multiplier", max_score_multiplier);
}
void write(lisp::Writer& writer);
void read(const lisp::Lisp& lisp);
- int distros;
+ int coins;
int lives;
BonusType bonus;
#include <config.h>
#include "app/globals.h"
-#include "special/sprite_manager.h"
+#include "sprite/sprite_manager.h"
#include "app/setup.h"
#include "gui/menu.h"
#include "gui/button.h"
#include "object/gameobjs.h"
#include "object/player.h"
-Menu* main_menu = 0;
-Menu* game_menu = 0;
-Menu* options_menu = 0;
-Menu* options_keys_menu = 0;
-Menu* options_joystick_menu = 0;
-Menu* highscore_menu = 0;
-Menu* load_game_menu = 0;
-Menu* save_game_menu = 0;
-Menu* contrib_menu = 0;
-Menu* contrib_subset_menu = 0;
-
MusicRef herring_song;
MusicRef level_end_song;
MusicRef credits_song;
SpriteManager* sprite_manager = 0;
TileManager* tile_manager = 0;
-
-char * soundfilenames[NUM_SOUNDS] = {
- "/sounds/jump.wav",
- "/sounds/bigjump.wav",
- "/sounds/skid.wav",
- "/sounds/coin.wav",
- "/sounds/invincible.wav",
- "/sounds/brick.wav",
- "/sounds/hurt.wav",
- "/sounds/squish.wav",
- "/sounds/fall.wav",
- "/sounds/ricochet.wav",
- "/sounds/bump-upgrade.wav",
- "/sounds/upgrade.wav",
- "/sounds/grow.wav",
- "/sounds/fire-flower.wav",
- "/sounds/shoot.wav",
- "/sounds/lifeup.wav",
- "/sounds/stomp.wav",
- "/sounds/kick.wav",
- "/sounds/explosion.wav",
- "/sounds/warp.wav",
- "/sounds/fireworks.wav"
- };
-
+SoundManager* sound_manager = 0;
Font* gold_text;
Font* blue_text;
Font* white_big_text;
/* Load graphics/sounds shared between all levels: */
-void loadshared()
+void load_shared()
{
+ /* Load GUI/menu images: */
+ checkbox = new Surface(datadir + "/images/status/checkbox.png", true);
+ checkbox_checked = new Surface(datadir + "/images/status/checkbox-checked.png", true);
+ back = new Surface(datadir + "/images/status/back.png", true);
+ arrow_left = new Surface(datadir + "/images/icons/left.png", true);
+ arrow_right = new Surface(datadir + "/images/icons/right.png", true);
+
+ /* Load the mouse-cursor */
+ mouse_cursor = new MouseCursor( datadir + "/images/status/mousecursor.png",1);
+ MouseCursor::set_current(mouse_cursor);
+
/* Load global images: */
gold_text = new Font(datadir + "/images/fonts/gold.png", Font::TEXT, 16,18);
blue_text = new Font(datadir + "/images/fonts/blue.png", Font::TEXT, 16,18,3);
true);
/* Sound effects: */
- for (i = 0; i < NUM_SOUNDS; i++)
- SoundManager::get()->add_sound(SoundManager::get
- ()->load_sound(datadir + soundfilenames[i]),i);
+ sound_manager->preload_sound("jump");
+ sound_manager->preload_sound("bigjump");
+ sound_manager->preload_sound("skid");
+ sound_manager->preload_sound("coin");
+ sound_manager->preload_sound("invincible");
+ sound_manager->preload_sound("brick");
+ sound_manager->preload_sound("hurt");
+ sound_manager->preload_sound("squish");
+ sound_manager->preload_sound("fall");
+ sound_manager->preload_sound("ricochet");
+ sound_manager->preload_sound("bump-upgrade");
+ sound_manager->preload_sound("upgrade");
+ sound_manager->preload_sound("grow");
+ sound_manager->preload_sound("fire-flower");
+ sound_manager->preload_sound("shoot");
+ sound_manager->preload_sound("lifeup");
+ sound_manager->preload_sound("stomp");
+ sound_manager->preload_sound("kick");
+ sound_manager->preload_sound("explosion");
+ sound_manager->preload_sound("warp");
+ sound_manager->preload_sound("fireworks");
/* Herring song */
- herring_song = SoundManager::get
- ()->load_music(datadir + "/music/salcon.mod");
- level_end_song = SoundManager::get
- ()->load_music(datadir + "/music/leveldone.mod");
+ herring_song = sound_manager->load_music(datadir + "/music/salcon.mod");
+ level_end_song = sound_manager->load_music(datadir + "/music/leveldone.mod");
}
/* Free shared data: */
-void unloadshared(void)
+void unload_shared()
{
/* Free global images: */
delete gold_text;
sprite_manager = 0;
delete tile_manager;
tile_manager = 0;
+
+ /* Free GUI/menu images: */
+ delete checkbox;
+ delete checkbox_checked;
+ delete back;
+ delete arrow_left;
+ delete arrow_right;
+
+ /* Free mouse-cursor */
+ delete mouse_cursor;
}
std::string get_resource_filename(const std::string& resource)
{
- std::string filepath = st_dir + resource;
+ std::string filepath = user_dir + resource;
if(FileSystem::faccessible(filepath))
return filepath;
// 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_RESOURCES_H
#define SUPERTUX_RESOURCES_H
using namespace SuperTux;
-namespace SuperTux {
class SpriteManager;
-class SoundManager;
class Menu;
class Font;
class Surface;
-}
-
+class SoundManager;
class TileManager;
-/* Sound files: */
-enum {
- SND_JUMP,
- SND_BIGJUMP,
- SND_SKID,
- SND_DISTRO,
- SND_HERRING,
- SND_BRICK,
- SND_HURT,
- SND_SQUISH,
- SND_FALL,
- SND_RICOCHET,
- SND_BUMP_UPGRADE,
- SND_UPGRADE,
- SND_EXCELLENT,
- SND_COFFEE,
- SND_SHOOT,
- SND_LIFEUP,
- SND_STOMP,
- SND_KICK,
- SND_EXPLODE,
- SND_WARP,
- SND_FIREWORKS,
- NUM_SOUNDS
-};
-
-extern char* soundfilenames[NUM_SOUNDS];
-
extern Surface* img_super_bkgd;
+extern Surface* tux_life;
extern MusicRef herring_song;
extern MusicRef level_end_song;
extern SpriteManager* sprite_manager;
extern TileManager* tile_manager;
+extern SoundManager* sound_manager;
extern Menu* contrib_menu;
extern Menu* contrib_subset_menu;
extern Menu* main_menu;
extern Menu* game_menu;
extern Menu* options_menu;
-extern Menu* options_keys_menu;
-extern Menu* options_joystick_menu;
-extern Menu* highscore_menu;
extern Menu* load_game_menu;
-extern Menu* save_game_menu;
extern Font* gold_text;
extern Font* white_text;
*/
std::string get_resource_filename(const std::string& resource);
-void loadshared();
-void unloadshared();
+void load_shared();
+void unload_shared();
#endif
#include "lisp/list_iterator.h"
#include "tile.h"
#include "audio/sound_manager.h"
-#include "gameloop.h"
+#include "game_session.h"
#include "resources.h"
#include "statistics.h"
#include "collision_grid.h"
#include "collision_grid_iterator.h"
#include "object_factory.h"
-#include "special/collision.h"
+#include "collision.h"
#include "math/rectangle.h"
#include "math/aatriangle.h"
#include "object/coin.h"
}
add_object(new_bullet);
- SoundManager::get()->play_sound(IDToSound(SND_SHOOT));
+ sound_manager->play_sound("shoot");
return true;
}
void
Sector::load_music()
{
- char* song_path;
- char* song_subtitle;
-
- level_song = SoundManager::get()->load_music(datadir + "/music/" + song_title);
-
- song_path = (char *) malloc(sizeof(char) * datadir.length() +
- strlen(song_title.c_str()) + 8 + 5);
- song_subtitle = strdup(song_title.c_str());
- strcpy(strstr(song_subtitle, "."), "\0");
- sprintf(song_path, "%s/music/%s-fast%s", datadir.c_str(),
- song_subtitle, strstr(song_title.c_str(), "."));
- if(!SoundManager::get()->exists_music(song_path)) {
- level_song_fast = level_song;
- } else {
- level_song_fast = SoundManager::get()->load_music(song_path);
- }
- free(song_subtitle);
- free(song_path);
+ level_song = sound_manager->load_music(
+ get_resource_filename("/music/" + song_title));
}
void
-Sector::play_music(int type)
+Sector::play_music(MusicType type)
{
currentmusic = type;
switch(currentmusic) {
- case HURRYUP_MUSIC:
- SoundManager::get()->play_music(level_song_fast);
- break;
case LEVEL_MUSIC:
- SoundManager::get()->play_music(level_song);
+ sound_manager->play_music(level_song);
break;
case HERRING_MUSIC:
- SoundManager::get()->play_music(herring_song);
+ sound_manager->play_music(herring_song);
break;
default:
- SoundManager::get()->halt_music();
+ sound_manager->halt_music();
break;
}
}
-int
+MusicType
Sector::get_music_type()
{
return currentmusic;
// 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_SECTOR_H
#define SUPERTUX_SECTOR_H
using namespace SuperTux;
namespace SuperTux {
-class GameObject;
-class Sprite;
class Rectangle;
}
namespace lisp {
class Writer;
}
+class Sprite;
+class GameObject;
class Player;
class Camera;
class TileMap;
Vector pos;
};
+enum MusicType {
+ LEVEL_MUSIC,
+ HERRING_MUSIC
+};
+
/** This class holds a sector (a part of a level) and all the game objects
* (badguys, player, background, tilemap, ...)
*/
/// tests if a given rectangle is inside the sector
bool inside(const Rectangle& rectangle) const;
- void play_music(int musictype);
- int get_music_type();
+ void play_music(MusicType musictype);
+ MusicType get_music_type();
/** Checks for all possible collisions. And calls the
collision_handlers, which the collision_objects provide for this
std::string name;
MusicRef level_song;
- MusicRef level_song_fast;
public:
std::string song_title;
/// container for newly created objects, they'll be added in Sector::action
GameObjects gameobjects_new;
-
- int currentmusic;
+
+ MusicType currentmusic;
CollisionGrid* grid;
};
--- /dev/null
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
+//
+// 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 <config.h>
+
+#include <iostream>
+#include <cmath>
+#include <cassert>
+#include <stdexcept>
+
+#include "app/globals.h"
+#include "app/setup.h"
+#include "sprite.h"
+#include "video/drawing_context.h"
+
+Sprite::Sprite(SpriteData& newdata)
+ : data(newdata), frame(0), animation_loops(-1)
+{
+ action = data.get_action("normal");
+ if(!action)
+ action = data.actions.begin()->second;
+ last_ticks = SDL_GetTicks();
+}
+
+Sprite::Sprite(const Sprite& other)
+ : data(other.data), frame(other.frame),
+ animation_loops(other.animation_loops),
+ action(other.action)
+{
+ last_ticks = SDL_GetTicks();
+}
+
+Sprite::~Sprite()
+{
+}
+
+void
+Sprite::set_action(std::string name, int loops)
+{
+ if(action && action->name == name)
+ return;
+
+ SpriteData::Action* newaction = data.get_action(name);
+ if(!newaction) {
+#ifdef DEBUG
+ std::cerr << "Action '" << name << "' not found.\n";
+#endif
+ return;
+ }
+
+ action = newaction;
+ animation_loops = loops;
+ frame = 0;
+}
+
+bool
+Sprite::check_animation()
+{
+ return animation_loops == 0;
+}
+
+void
+Sprite::update()
+{
+ if(animation_loops == 0)
+ return;
+
+ Uint32 ticks = SDL_GetTicks();
+ float frame_inc = action->fps * float(ticks - last_ticks)/1000.0;
+ last_ticks = ticks;
+
+ frame += frame_inc;
+
+ if(frame >= get_frames()) {
+ frame = fmodf(frame+get_frames(), get_frames());
+
+ animation_loops--;
+ if(animation_loops == 0)
+ frame = 0;
+ }
+}
+
+void
+Sprite::draw(DrawingContext& context, const Vector& pos, int layer,
+ Uint32 drawing_effect)
+{
+ assert(action != 0);
+ update();
+
+ if((int)frame >= get_frames() || (int)frame < 0)
+ std::cerr << "Warning: frame out of range: " << (int)frame
+ << "/" << get_frames() << " at " << get_name()
+ << "/" << 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);
+}
+
+void
+Sprite::draw_part(DrawingContext& context, const Vector& source,
+ const Vector& size, const Vector& pos, int layer, Uint32 drawing_effect)
+{
+ assert(action != 0);
+ update();
+
+ if((int)frame >= get_frames() || (int)frame < 0)
+ std::cerr << "Warning: frame out of range: " << (int)frame
+ << "/" << get_frames() << " at sprite: " << get_name()
+ << "/" << 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);
+}
+
+int
+Sprite::get_width() const
+{
+ return action->surfaces[get_frame()]->w;
+}
+
+int
+Sprite::get_height() const
+{
+ return action->surfaces[get_frame()]->h;
+}
+
+
--- /dev/null
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
+//
+// 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_H
+#define SUPERTUX_SPRITE_H
+
+#include <string>
+#include <vector>
+#include <cassert>
+#include <map>
+
+#include "video/surface.h"
+#include "math/vector.h"
+#include "sprite_data.h"
+
+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, int loops = -1);
+
+ /* Stop animation */
+ void stop_animation()
+ { animation_loops = 0; }
+ /** Check if animation is stopped or not */
+ bool check_animation();
+
+ 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)
+ {
+ assert(frame < action->surfaces.size());
+ return action->surfaces[frame];
+ }
+
+private:
+ void update();
+
+ SpriteData& data;
+
+ float frame;
+ int animation_loops;
+ Uint32 last_ticks;
+
+ SpriteData::Action* action;
+};
+
+#endif
+
--- /dev/null
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
+//
+// 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 <config.h>
+
+#include <iostream>
+#include <cmath>
+#include <sstream>
+#include <stdexcept>
+
+#include "sprite_data.h"
+#include "app/globals.h"
+#include "app/setup.h"
+#include "video/drawing_context.h"
+#include "lisp/list_iterator.h"
+
+SpriteData::Action::Action()
+{
+ x_offset = 0;
+ y_offset = 0;
+ z_order = 0;
+ fps = 10;
+}
+
+SpriteData::Action::~Action()
+{
+ for(std::vector<Surface*>::iterator i = surfaces.begin();
+ i != surfaces.end(); ++i)
+ delete *i;
+}
+
+SpriteData::SpriteData(const lisp::Lisp* lisp)
+{
+ lisp::ListIterator iter(lisp);
+ while(iter.next()) {
+ if(iter.item() == "name") {
+ iter.value()->get(name);
+ } else if(iter.item() == "action") {
+ parse_action(iter.lisp());
+ } else {
+ std::cerr << "Unknown sprite field: " << iter.item() << "\n";
+ }
+ }
+ if(name.empty())
+ throw std::runtime_error("Error: Sprite wihtout name.");
+ if(actions.empty())
+ throw std::runtime_error("Error: Sprite wihtout actions.");
+}
+
+SpriteData::~SpriteData()
+{
+ for(Actions::iterator i=actions.begin(); i != actions.end(); ++i)
+ delete i->second;
+}
+
+void
+SpriteData::parse_action(const lisp::Lisp* lisp)
+{
+ Action* action = new Action;
+
+ if(!lisp->get("name", action->name)) {
+ if(!actions.empty())
+ throw std::runtime_error(
+ "If there are more than one action, they need names!");
+ }
+ lisp->get("x-offset", action->x_offset);
+ lisp->get("y-offset", action->y_offset);
+ lisp->get("z-order", action->z_order);
+ lisp->get("fps", action->fps);
+
+ std::string mirror_action;
+ lisp->get("mirror-action", mirror_action);
+ if(!mirror_action.empty()) {
+ Action* act_tmp = get_action(mirror_action);
+ if(act_tmp == NULL) {
+ throw std::runtime_error("Could not mirror action. Action not found\n"
+ "Mirror actions must be defined after the real one!");
+ } else {
+ for(int i = 0; static_cast<unsigned int>(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<std::string> images;
+ if(!lisp->get_vector("images", images)) {
+ std::stringstream msg;
+ msg << "Sprite '" << name << "' contains no images in action '"
+ << action->name << "'.";
+ throw std::runtime_error(msg.str());
+ }
+
+ for(std::vector<std::string>::size_type i = 0; i < images.size(); i++) {
+ action->surfaces.push_back(
+ new Surface(datadir + "/images/" + images[i], true));
+ }
+ }
+ actions[action->name] = action;
+}
+
+SpriteData::Action*
+SpriteData::get_action(std::string act)
+{
+ Actions::iterator i = actions.find(act);
+ if(i == actions.end()) {
+ return 0;
+ }
+ return i->second;
+}
+
--- /dev/null
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>,
+// (C) 2004 Matthias Braun <matze@braunis.de>
+//
+// 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 <string>
+#include <vector>
+#include <map>
+
+#include "lisp/lisp.h"
+#include "video/surface.h"
+
+class SpriteData
+{
+public:
+ /** cur has to be a pointer to data in the form of ((x-offset 5)
+ (y-offset 10) ...) */
+ SpriteData(const lisp::Lisp* 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<Surface*> surfaces;
+ };
+
+ typedef std::map <std::string, Action*> Actions;
+ Actions actions;
+
+ void parse_action(const lisp::Lisp* lispreader);
+ /** Get an action */
+ Action* get_action(std::string act);
+
+ std::string name;
+};
+
+#endif
+
--- /dev/null
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
+//
+// 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 <config.h>
+
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+
+#include "sprite_manager.h"
+#include "sprite_data.h"
+#include "sprite.h"
+#include "lisp/lisp.h"
+#include "lisp/parser.h"
+#include "lisp/list_iterator.h"
+
+SpriteManager::SpriteManager(const std::string& filename)
+{
+ load_resfile(filename);
+}
+
+SpriteManager::~SpriteManager()
+{
+ for(Sprites::iterator i = sprites.begin(); i != sprites.end(); ++i) {
+ delete i->second;
+ }
+}
+
+void
+SpriteManager::load_resfile(const std::string& filename)
+{
+ lisp::Parser parser;
+ try {
+ std::auto_ptr<lisp::Lisp> root (parser.parse(filename));
+
+ const lisp::Lisp* resources = root->get_lisp("supertux-resources");
+ if(!resources)
+ throw std::runtime_error("file is not a supertux-resources files");
+
+ lisp::ListIterator iter(resources);
+ while(iter.next()) {
+ if(iter.item() == "sprite") {
+ SpriteData* spritedata = new SpriteData(iter.lisp());
+
+ 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 '" << iter.item()
+ << "' in spritefile.\n";
+ }
+ }
+ } catch(std::exception& e) {
+ std::stringstream msg;
+ msg << "Couldn't load file '" << filename << "': " << e.what() << "\n";
+ throw std::runtime_error(msg.str());
+ }
+}
+
+Sprite*
+SpriteManager::create(const std::string& name)
+{
+ Sprites::iterator i = sprites.find(name);
+ if(i == sprites.end()) {
+ std::stringstream msg;
+ msg << "Sprite '" << name << "' not found.";
+ throw std::runtime_error(msg.str());
+ }
+ return new Sprite(*i->second);
+}
+
--- /dev/null
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2004 Ingo Ruhnke <grumbel@gmx.de>
+//
+// 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_MANAGER_H
+#define SUPERTUX_SPRITE_MANAGER_H
+
+#include <map>
+
+#include "sprite.h"
+
+class SpriteManager
+{
+private:
+ typedef std::map<std::string, SpriteData*> 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);
+};
+
+#endif
using namespace SuperTux;
-namespace SuperTux {
class DrawingContext;
-}
#define SPLAYER 0
#define STOTAL 1
+++ /dev/null
-// $Id$
-//
-// SuperTux
-// Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
-//
-// 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 <config.h>
-
-#include <sys/types.h>
-#include <cctype>
-#include <iostream>
-#include <exception>
-#include <locale.h>
-
-#include "app/globals.h"
-#include "app/setup.h"
-#include "title.h"
-#include "gameloop.h"
-#include "leveleditor.h"
-#include "video/screen.h"
-#include "worldmap.h"
-#include "resources.h"
-#include "video/surface.h"
-#include "tile_manager.h"
-#include "app/gettext.h"
-#include "misc.h"
-#include "utils/configfile.h"
-
-int main(int argc, char * argv[])
-{
-#ifndef DEBUG
- try {
-#endif
- config = new MyConfig;
-
- Setup::init(PACKAGE_NAME, PACKAGE_NAME, PACKAGE_VERSION);
-
- Setup::parseargs(argc, argv);
-
- Setup::audio();
- Setup::video(screen_width, screen_height);
- Setup::joystick();
- Setup::general();
- st_menu();
- loadshared();
-
- if (launch_leveleditor_mode)
- {
- LevelEditor leveleditor;
-
- if(level_startup_file)
- leveleditor.run(level_startup_file);
- else
- leveleditor.run();
- }
- else if (launch_worldmap_mode && level_startup_file)
- {
- // hack to make it possible for someone to give an absolute path
- std::string str(level_startup_file);
- unsigned int i = str.find_last_of("/", str.size());
- if(i != std::string::npos)
- str.erase(0, i+1);
-
- WorldMapNS::WorldMap worldmap;
- worldmap.loadmap(str);
- worldmap.display();
- }
- else if (level_startup_file)
- {
- GameSession session(level_startup_file, ST_GL_LOAD_LEVEL_FILE);
- session.run();
- }
- else
- {
- title();
- }
-
- unloadshared();
- Setup::general_free();
- st_menu_free();
-#ifdef DEBUG
- Surface::debug_check();
-#endif
- Termination::shutdown();
-#ifndef DEBUG // we want to see the backtrace in gdb when in debug mode
- } catch (std::exception &e) {
- std:: cerr << "Unhandled exception: " << e.what() << std::endl;
- }
-#endif
-
- return 0;
-}
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "textscroller.h"
#include "app/globals.h"
#include "lisp/parser.h"
#include "lisp/lisp.h"
+#include "main.h"
+#include "control/joystickkeyboardcontroller.h"
-static const float DEFAULT_SPEED = 1.0;
-static const float MAX_VEL = 10;
-static const float SPEED_INC = 0.01;
+static const float DEFAULT_SPEED = .02;
static const float SCROLL = 60;
static const float ITEMS_SPACE = 4;
const Font* normal_font = white_text;
const Font* small_font = white_small_text;
const Font* reference_font = blue_text;
- float speed = DEFAULT_SPEED;
+ float defaultspeed = DEFAULT_SPEED;
+ float speed = defaultspeed;
std::string text;
std::string background_file;
throw std::runtime_error("file doesn't contain a text field");
if(!text_lisp->get("background", background_file))
throw std::runtime_error("file doesn't contain a background file");
- text_lisp->get("speed", speed);
+ if(text_lisp->get("speed", defaultspeed))
+ defaultspeed /= 50;
} catch(std::exception& e) {
std::cerr << "Couldn't load file '" << filename << "': " << e.what() <<
"\n";
Surface* background = new Surface(
get_resource_filename("images/background/" + background_file), false);
- int done = 0;
+ bool done = false;
float scroll = 0;
- speed /= 50.0;
float left_border = 50;
DrawingContext context;
SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
Uint32 lastticks = SDL_GetTicks();
- while(!done)
- {
- /* in case of input, exit */
- SDL_Event event;
- while(SDL_PollEvent(&event))
- switch(event.type)
- {
- case SDL_KEYDOWN:
- switch(event.key.keysym.sym)
- {
- case SDLK_UP:
- speed -= SPEED_INC;
- break;
- case SDLK_DOWN:
- speed += SPEED_INC;
- break;
- case SDLK_SPACE:
- case SDLK_RETURN:
- if(speed >= 0)
- scroll += SCROLL;
- break;
- case SDLK_ESCAPE:
- done = 1;
- break;
- default:
- break;
- }
- break;
- case SDL_QUIT:
- done = 1;
- break;
- default:
- break;
- }
-
- if(speed > MAX_VEL)
- speed = MAX_VEL;
- else if(speed < -MAX_VEL)
- speed = -MAX_VEL;
-
- /* draw the credits */
- context.draw_surface(background, Vector(0,0), 0);
-
- float y = 0;
- for(size_t i = 0; i < lines.size(); i++) {
- const std::string& line = lines[i];
- if(line.size() == 0) {
- y += normal_font->get_height() + ITEMS_SPACE;
- continue;
- }
+ while(!done) {
+ main_controller->update();
+ /* in case of input, exit */
+ SDL_Event event;
+ while(SDL_PollEvent(&event)) {
+ main_controller->process_event(event);
+ if(event.type == SDL_QUIT)
+ throw std::runtime_error("received window close");
+ }
- const Font* font = 0;
- bool center = true;
- switch(line[0])
- {
- case ' ': font = small_font; break;
- case '\t': font = normal_font; break;
- case '-': font = heading_font; break;
- case '*': font = reference_font; break;
- case '#': font = normal_font; center = false; break;
- default:
- std::cerr << "Warning: text contains an unformated line.\n";
- font = normal_font;
- center = false;
- break;
- }
-
- if(center) {
- context.draw_text(font,
- line.substr(1, line.size()-1),
- Vector(SCREEN_WIDTH/2, SCREEN_HEIGHT + y - scroll),
- CENTER_ALLIGN, LAYER_FOREGROUND1);
- } else {
- context.draw_text(font,
- line.substr(1, line.size()-1),
- Vector(left_border, SCREEN_HEIGHT + y - scroll),
- LEFT_ALLIGN, LAYER_FOREGROUND1);
- }
-
- y += font->get_height() + ITEMS_SPACE;
+ if(main_controller->hold(Controller::UP)) {
+ speed = -defaultspeed*5;
+ } else if(main_controller->hold(Controller::DOWN)) {
+ speed = defaultspeed*5;
+ } else {
+ speed = defaultspeed;
+ }
+ if(main_controller->pressed(Controller::JUMP)
+ || main_controller->pressed(Controller::ACTION)
+ || main_controller->pressed(Controller::MENU_SELECT))
+ scroll += SCROLL;
+ if(main_controller->pressed(Controller::PAUSE_MENU))
+ done = true;
+
+ /* draw the credits */
+ context.draw_surface(background, Vector(0,0), 0);
+
+ float y = 0;
+ for(size_t i = 0; i < lines.size(); i++) {
+ const std::string& line = lines[i];
+ if(line.size() == 0) {
+ y += normal_font->get_height() + ITEMS_SPACE;
+ continue;
}
-
- context.do_drawing();
-
- if(SCREEN_HEIGHT+y-scroll < 0 && 20+SCREEN_HEIGHT+y-scroll < 0)
- done = 1;
-
- Uint32 ticks = SDL_GetTicks();
- scroll += speed * (ticks - lastticks);
- lastticks = ticks;
- if(scroll < 0)
- scroll = 0;
-
- SDL_Delay(10);
+
+ const Font* font = 0;
+ bool center = true;
+ switch(line[0])
+ {
+ case ' ': font = small_font; break;
+ case '\t': font = normal_font; break;
+ case '-': font = heading_font; break;
+ case '*': font = reference_font; break;
+ case '#': font = normal_font; center = false; break;
+ default:
+ std::cerr << "Warning: text contains an unformated line.\n";
+ font = normal_font;
+ center = false;
+ break;
+ }
+
+ if(center) {
+ context.draw_text(font,
+ line.substr(1, line.size()-1),
+ Vector(SCREEN_WIDTH/2, SCREEN_HEIGHT + y - scroll),
+ CENTER_ALLIGN, LAYER_FOREGROUND1);
+ } else {
+ context.draw_text(font,
+ line.substr(1, line.size()-1),
+ Vector(left_border, SCREEN_HEIGHT + y - scroll),
+ LEFT_ALLIGN, LAYER_FOREGROUND1);
+ }
+
+ y += font->get_height() + ITEMS_SPACE;
}
-
+
+ context.do_drawing();
+
+ if(SCREEN_HEIGHT+y-scroll < 0 && 20+SCREEN_HEIGHT+y-scroll < 0)
+ done = 1;
+
+ Uint32 ticks = SDL_GetTicks();
+ scroll += speed * (ticks - lastticks);
+ lastticks = ticks;
+ if(scroll < 0)
+ scroll = 0;
+
+ SDL_Delay(10);
+ }
+
SDL_EnableKeyRepeat(0, 0); // disables key repeating
delete background;
}
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __TEXTSCROLLER_H__
#define __TEXTSCROLLER_H__
#include <vector>
#include <string>
-namespace SuperTux {
class DrawingContext;
-}
-
-using namespace SuperTux;
/** This class is displaying a box with information text inside the game
*/
attributes |= SPIKE;
if(reader.get("fullbox", value) && value)
attributes |= FULLBOX;
- if(reader.get("distro", value) && value)
- attributes |= COIN;
if(reader.get("coin", value) && value)
attributes |= COIN;
if(reader.get("goal", value) && value)
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include <math.h>
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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_TIMER_H__
#define __SUPERTUX_TIMER_H__
#include <iostream>
#include <sstream>
+#include <stdexcept>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "lisp/parser.h"
#include "level.h"
#include "level_subset.h"
-#include "gameloop.h"
+#include "game_session.h"
#include "worldmap.h"
#include "leveleditor.h"
#include "player_status.h"
#include "app/gettext.h"
#include "misc.h"
#include "textscroller.h"
+#include "control/joystickkeyboardcontroller.h"
+#include "control/codecontroller.h"
+#include "main.h"
static Surface* bkg_title;
static Surface* logo;
static int frame;
static GameSession* titlesession;
+static CodeController* controller;
static std::vector<LevelSubset*> contrib_subsets;
static LevelSubset* current_contrib_subset = 0;
-static FrameRate frame_rate(100);
+static FrameRate frame_rate(100);
/* If the demo was stopped - because game started, level
editor was excuted, etc - call this when you get back
frame_rate.update();
}
-void update_load_save_game_menu(Menu* pmenu)
+void update_load_save_game_menu(Menu* menu)
{
- for(int i = 2; i < 7; ++i)
- {
- // FIXME: Insert a real savegame struct/class here instead of
- // doing string vodoo
- std::string tmp = slotinfo(i - 1);
- pmenu->item[i].kind = MN_ACTION;
- pmenu->item[i].change_text(tmp.c_str());
- }
+ printf("update loadsavemenu.\n");
+ for(int i = 1; i < 6; ++i) {
+ MenuItem& item = menu->get_item_by_id(i);
+ item.kind = MN_ACTION;
+ item.change_text(slotinfo(i));
+ }
}
void free_contrib_menu()
free_contrib_menu();
- contrib_menu->additem(MN_LABEL,_("Contrib Levels"),0,0);
- contrib_menu->additem(MN_HL,"",0,0);
+ contrib_menu->add_label(_("Contrib Levels"));
+ contrib_menu->add_hl();
int i = 0;
for (std::set<std::string>::iterator it = level_subsets.begin();
delete subset;
continue;
}
- contrib_menu->additem(MN_GOTO, subset->title, 0, contrib_subset_menu, i);
+ contrib_menu->add_submenu(subset->title, contrib_subset_menu);
contrib_subsets.push_back(subset);
++i;
}
- contrib_menu->additem(MN_HL,"",0,0);
- contrib_menu->additem(MN_BACK,_("Back"),0,0);
-
+ contrib_menu->add_hl();
+ contrib_menu->add_back(_("Back"));
+
level_subsets.clear();
}
context.do_drawing();
// TODO: slots should be available for contrib maps
- worldmap.loadgame(st_save_dir + "/" + subset.name + "-slot1.stsg");
+ worldmap.loadgame(user_dir + "/save/" + subset.name + "-slot1.stsg");
worldmap.display(); // run the map
contrib_subset_menu->clear();
- contrib_subset_menu->additem(MN_LABEL, subset.title, 0,0);
- contrib_subset_menu->additem(MN_HL,"",0,0);
+ contrib_subset_menu->add_label(subset.title);
+ contrib_subset_menu->add_hl();
for (int i = 0; i < subset.get_num_levels(); ++i)
{
/** get level's title */
std::string filename = subset.get_level_filename(i);
std::string title = get_level_name(filename);
- contrib_subset_menu->additem(MN_ACTION, title, 0, 0, i);
+ contrib_subset_menu->add_entry(i, title);
}
- contrib_subset_menu->additem(MN_HL,"",0,0);
- contrib_subset_menu->additem(MN_BACK, _("Back"), 0, 0);
+ contrib_subset_menu->add_hl();
+ contrib_subset_menu->add_back(_("Back"));
titlesession->get_current_sector()->activate("main");
titlesession->set_current();
void draw_demo(float elapsed_time)
{
- Sector* world = titlesession->get_current_sector();
- Player* tux = world->player;
+ static float last_tux_x_pos = -1;
+ Sector* sector = titlesession->get_current_sector();
+ Player* tux = sector->player;
- world->play_music(LEVEL_MUSIC);
-
- tux->key_event((SDLKey) keymap.right, true);
+ sector->play_music(LEVEL_MUSIC);
+
+ controller->update();
+ controller->press(Controller::RIGHT);
- if(random_timer.check()) {
+ if(random_timer.check() || (int) last_tux_x_pos == (int) tux->get_pos().x) {
random_timer.start(float(rand() % 3000 + 3000) / 1000.);
walking = !walking;
} else {
- if(walking)
- tux->key_event((SDLKey) keymap.jump, false);
- else
- tux->key_event((SDLKey) keymap.jump, true);
+ if(!walking)
+ controller->press(Controller::JUMP);
}
+ last_tux_x_pos = tux->get_pos().x;
// Wrap around at the end of the level back to the beginnig
- if(world->solids->get_width() * 32 - 320 < tux->get_pos().x)
- {
- world->activate("main");
- world->camera->reset(tux->get_pos());
- }
-
- tux->can_jump = true;
- 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->get_pos().x)
- {
- walking = false;
- }
+ if(sector->solids->get_width() * 32 - 320 < tux->get_pos().x) {
+ sector->activate("main");
+ sector->camera->reset(tux->get_pos());
+ }
- world->draw(*titlesession->context);
+ sector->action(elapsed_time);
+ sector->draw(*titlesession->context);
}
/* --- TITLE SCREEN --- */
-void title(void)
+void title()
{
walking = true;
LevelEditor* leveleditor;
MusicRef credits_music;
+ controller = new CodeController();
Ticks::pause_init();
titlesession->get_current_sector()->activate("main");
titlesession->set_current();
+ Player* player = titlesession->get_current_sector()->player;
+ player->set_controller(controller);
+
/* --- Main title loop: --- */
frame = 0;
elapsed_time /= 2;
SDL_Event event;
- while (SDL_PollEvent(&event))
- {
- if (Menu::current())
- {
- Menu::current()->event(event);
- }
- // FIXME: QUIT signal should be handled more generic, not locally
- if (event.type == SDL_QUIT)
- Menu::set_current(0);
+ main_controller->update();
+ while (SDL_PollEvent(&event)) {
+ if (Menu::current()) {
+ Menu::current()->event(event);
}
+ main_controller->process_event(event);
+ // FIXME: QUIT signal should be handled more generic, not locally
+ if (event.type == SDL_QUIT)
+ throw std::runtime_error("Received window close");
+ }
/* Draw the background: */
draw_demo(elapsed_time);
-
-
+
if (Menu::current() == main_menu)
context.draw_surface(logo, Vector(SCREEN_WIDTH/2 - logo->w/2, 30),
LAYER_FOREGROUND1+1);
puts("Entering contrib menu");
generate_contrib_menu();
break;
+#if 0
case MNID_LEVELEDITOR:
leveleditor = new LevelEditor();
leveleditor->run();
Menu::set_current(main_menu);
resume_demo();
break;
+#endif
case MNID_CREDITS:
fadeout(500);
- credits_music = SoundManager::get()->load_music(datadir + "/music/credits.ogg");
- SoundManager::get()->play_music(credits_music);
+ credits_music = sound_manager->load_music(
+ get_resource_filename("/music/credits.ogg"));
+ sound_manager->play_music(credits_music);
display_text_file("credits.txt");
fadeout(500);
Menu::set_current(main_menu);
if(confirm_dialog(bkg_title, str.c_str()))
{
- str = st_save_dir + "/slot" + stream.str() + ".stsg";
+ str = user_dir + "/save/slot" + stream.str() + ".stsg";
printf("Removing: %s\n",str.c_str());
remove(str.c_str());
}
delete logo;
delete img_choose_subset;
}
-
// 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_TITLE_H
#define SUPERTUX_TITLE_H
#include <config.h>
#include "door.h"
-#include "gameloop.h"
+#include "game_session.h"
#include "resources.h"
#include "object_factory.h"
-#include "special/sprite.h"
-#include "special/sprite_manager.h"
+#include "sprite/sprite.h"
+#include "sprite/sprite_manager.h"
#include "video/drawing_context.h"
#include "app/globals.h"
#include "lisp/lisp.h"
#include <string>
#include "video/surface.h"
-#include "special/sprite.h"
+#include "sprite/sprite.h"
#include "trigger_base.h"
#include "serializable.h"
#include "timer.h"
#include <config.h>
#include "hatch.h"
-#include "gameloop.h"
+#include "game_session.h"
#include "resources.h"
#include "object_factory.h"
-#include "special/sprite.h"
-#include "special/sprite_manager.h"
+#include "sprite/sprite.h"
+#include "sprite/sprite_manager.h"
#include "video/drawing_context.h"
#include "app/globals.h"
#include "lisp/lisp.h"
#include <string>
#include "video/surface.h"
-#include "special/sprite.h"
+#include "sprite/sprite.h"
#include "trigger_base.h"
#include "serializable.h"
#include "timer.h"
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "secretarea_trigger.h"
-#include "gameloop.h"
+#include "game_session.h"
#include "lisp/lisp.h"
#include "lisp/writer.h"
#include "object_factory.h"
if (message_timer.started()) {
context.push_transform();
context.set_translation(Vector(0, 0));
- Vector pos = Vector(0, screen->h/2 - gold_text->get_height()/2);
+ Vector pos = Vector(0, SCREEN_HEIGHT/2 - gold_text->get_height()/2);
context.draw_center_text(gold_text, message, pos, LAYER_GUI);
context.pop_transform();
}
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __SECRETAREA_TRIGGER_H__
#define __SECRETAREA_TRIGGER_H__
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 <config.h>
#include "sequence_trigger.h"
-#include "gameloop.h"
+#include "game_session.h"
#include "lisp/lisp.h"
#include "lisp/writer.h"
#include "object_factory.h"
+// $Id$
+//
+// SuperTux
+// Copyright (C) 2005 Matthias Braun <matze@braunis.de>
+//
+// 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 __SEQUENCE_TRIGGER_H__
#define __SEQUENCE_TRIGGER_H__
#ifndef SUPERTUX_TRIGGER_BASE_H
#define SUPERTUX_TRIGGER_BASE_H
-#include "special/moving_object.h"
+#include "moving_object.h"
#include "math/rectangle.h"
-#include "special/sprite.h"
+#include "sprite/sprite.h"
class Player;
using namespace SuperTux;
#include "video/screen.h"
#include "video/drawing_context.h"
#include "special/frame_rate.h"
-#include "special/sprite_manager.h"
+#include "sprite/sprite_manager.h"
#include "audio/sound_manager.h"
#include "lisp/parser.h"
#include "lisp/lisp.h"
#include "lisp/list_iterator.h"
#include "lisp/writer.h"
-#include "gameloop.h"
+#include "game_session.h"
#include "sector.h"
#include "worldmap.h"
#include "resources.h"
#include "misc.h"
#include "player_status.h"
#include "textscroller.h"
-
-#define map_message_TIME 2.8
+#include "main.h"
+#include "control/joystickkeyboardcontroller.h"
Menu* worldmap_menu = 0;
static const float TUXSPEED = 200;
+static const float map_message_TIME = 2.8;
namespace WorldMapNS {
void
Tux::set_direction(Direction dir)
{
-input_direction = dir;
+ input_direction = dir;
}
void
Tux::action(float delta)
{
- if (!moving)
+ // check controller
+ if(main_controller->pressed(Controller::UP))
+ input_direction = D_NORTH;
+ else if(main_controller->pressed(Controller::DOWN))
+ input_direction = D_SOUTH;
+ else if(main_controller->pressed(Controller::LEFT))
+ input_direction = D_WEST;
+ else if(main_controller->pressed(Controller::RIGHT))
+ input_direction = D_EAST;
+
+ if(!moving)
{
if (input_direction != D_NONE)
{
messagedot = new Surface(datadir + "/images/worldmap/messagedot.png", true);
teleporterdot = new Surface(datadir + "/images/worldmap/teleporterdot.png", true);
- enter_level = false;
-
name = "<no title>";
music = "salcon.mod";
intro_displayed = false;
WorldMap::on_escape_press()
{
// Show or hide the menu
- if(!Menu::current())
- {
- Menu::set_current(worldmap_menu);
+ if(!Menu::current()) {
+ Menu::set_current(worldmap_menu);
tux->set_direction(D_NONE); // stop tux movement when menu is called
- }
- else
- Menu::set_current(0);
+ } else {
+ Menu::set_current(0);
+ }
}
void
WorldMap::get_input()
{
- enter_level = false;
- SDLKey key;
+ main_controller->update();
SDL_Event event;
- while (SDL_PollEvent(&event))
- {
- if (Menu::current())
- {
- Menu::current()->event(event);
- }
- else
- {
- switch(event.type)
- {
- case SDL_QUIT:
- Termination::abort("Received window close", "");
- break;
-
- case SDL_KEYDOWN:
- key = event.key.keysym.sym;
-
- if(key == SDLK_ESCAPE)
- on_escape_press();
- else if(key == SDLK_RETURN || key == keymap.power)
- enter_level = true;
- else if(key == SDLK_LEFT || key == keymap.power)
- tux->set_direction(D_WEST);
- else if(key == SDLK_RIGHT || key == keymap.right)
- tux->set_direction(D_EAST);
- else if(key == SDLK_UP || key == keymap.up ||
- key == keymap.jump)
- // there might be ppl that use jump as up key
- tux->set_direction(D_NORTH);
- else if(key == SDLK_DOWN || key == keymap.down)
- tux->set_direction(D_SOUTH);
- break;
-
- case SDL_JOYHATMOTION:
- if(event.jhat.value & SDL_HAT_UP) {
- tux->set_direction(D_NORTH);
- } else if(event.jhat.value & SDL_HAT_DOWN) {
- tux->set_direction(D_SOUTH);
- } else if(event.jhat.value & SDL_HAT_LEFT) {
- tux->set_direction(D_WEST);
- } else if(event.jhat.value & SDL_HAT_RIGHT) {
- tux->set_direction(D_EAST);
- }
- break;
-
- case SDL_JOYAXISMOTION:
- if (event.jaxis.axis == joystick_keymap.x_axis)
- {
- if (event.jaxis.value < -joystick_keymap.dead_zone)
- tux->set_direction(D_WEST);
- else if (event.jaxis.value > joystick_keymap.dead_zone)
- tux->set_direction(D_EAST);
- }
- else if (event.jaxis.axis == joystick_keymap.y_axis)
- {
- if (event.jaxis.value > joystick_keymap.dead_zone)
- tux->set_direction(D_SOUTH);
- else if (event.jaxis.value < -joystick_keymap.dead_zone)
- tux->set_direction(D_NORTH);
- }
- break;
-
- case SDL_JOYBUTTONDOWN:
- if (event.jbutton.button == joystick_keymap.b_button)
- enter_level = true;
- else if (event.jbutton.button == joystick_keymap.start_button)
- on_escape_press();
- break;
-
- default:
- break;
- }
- }
- }
+ while (SDL_PollEvent(&event)) {
+ if (Menu::current())
+ Menu::current()->event(event);
+ main_controller->process_event(event);
+ if(event.type == SDL_QUIT)
+ throw std::runtime_error("Received window close");
+ }
}
Vector
WorldMap::get_next_tile(Vector pos, Direction direction)
{
- switch(direction)
- {
+ switch(direction) {
case D_WEST:
pos.x -= 1;
break;
break;
case D_NONE:
break;
- }
+ }
return pos;
}
void
WorldMap::update(float delta)
{
+ Menu* menu = Menu::current();
+ if(menu) {
+ menu->action();
+
+ if(menu == worldmap_menu) {
+ switch (worldmap_menu->check())
+ {
+ case MNID_RETURNWORLDMAP: // Return to game
+ Menu::set_current(0);
+ break;
+ case MNID_QUITWORLDMAP: // Quit Worldmap
+ quit = true;
+ break;
+ }
+ } else if(menu == options_menu) {
+ process_options_menu();
+ }
+
+ return;
+ }
+
+ bool enter_level = false;
+ if(main_controller->pressed(Controller::ACTION)
+ || main_controller->pressed(Controller::JUMP)
+ || main_controller->pressed(Controller::MENU_SELECT))
+ enter_level = true;
+ if(main_controller->pressed(Controller::PAUSE_MENU))
+ on_escape_press();
+
if (enter_level && !tux->is_moving())
{
/* Check special tile action */
if (special_tile->teleport_dest != Vector(-1,-1))
{
// TODO: an animation, camera scrolling or a fading would be a nice touch
- SoundManager::get()->play_sound(IDToSound(SND_WARP));
+ sound_manager->play_sound("warp");
tux->back_direction = D_NONE;
tux->set_tile_pos(special_tile->teleport_dest);
SDL_Delay(1000);
level_finished = false;
/* In case the player's abort the level, keep it using the old
status. But the minimum lives and no bonus. */
- player_status.distros = old_player_status.distros;
+ player_status.coins = old_player_status.coins;
player_status.lives = std::min(old_player_status.lives, player_status.lives);
player_status.bonus = NO_BONUS;
context.draw_text(blue_text, _("GAMEOVER"),
Vector(SCREEN_WIDTH/2, 200), CENTER_ALLIGN, LAYER_FOREGROUND1);
- sprintf(str, _("COINS: %d"), player_status.distros);
+ sprintf(str, _("COINS: %d"), player_status.coins);
context.draw_text(gold_text, str,
Vector(SCREEN_WIDTH/2, SCREEN_WIDTH - 32), CENTER_ALLIGN,
LAYER_FOREGROUND1);
break;
}
- SoundManager::get()->play_music(song);
+ sound_manager->play_music(song);
Menu::set_current(0);
if (!savegame_file.empty())
savegame(savegame_file);
tux->action(delta);
// tux->set_direction(input_direction);
}
-
- Menu* menu = Menu::current();
- if(menu)
- {
- menu->action();
-
- if(menu == worldmap_menu)
- {
- switch (worldmap_menu->check())
- {
- case MNID_RETURNWORLDMAP: // Return to game
- break;
- case MNID_QUITWORLDMAP: // Quit Worldmap
- quit = true;
- break;
- }
- }
- else if(menu == options_menu)
- {
- process_options_menu();
- }
- }
}
const Tile*
context.draw_text(white_text, _("SCORE"), Vector(0, 0), LEFT_ALLIGN, LAYER_FOREGROUND1);
context.draw_text(gold_text, str, Vector(96, 0), LEFT_ALLIGN, LAYER_FOREGROUND1);
- sprintf(str, "%d", player_status.distros);
+ sprintf(str, "%d", player_status.coins);
context.draw_text(white_text, _("COINS"), Vector(SCREEN_WIDTH/2 - 16*5, 0),
LEFT_ALLIGN, LAYER_FOREGROUND1);
context.draw_text(gold_text, str, Vector(SCREEN_WIDTH/2 + (16*5)/2, 0),
quit = false;
- song = SoundManager::get()->load_music(datadir + "/music/" + music);
- SoundManager::get()->play_music(song);
+ song = sound_manager->load_music(datadir + "/music/" + music);
+ sound_manager->play_music(song);
if(!intro_displayed && intro_filename != "") {
std::string filename = levels_path + intro_filename;
savegame->get("intro-displayed", intro_displayed);
savegame->get("lives", player_status.lives);
- savegame->get("distros", player_status.distros);
+ savegame->get("coins", player_status.coins);
savegame->get("max-score-multiplier", player_status.max_score_multiplier);
if (player_status.lives < 0)
player_status.reset();
#include "audio/musicref.h"
#include "video/screen.h"
#include "lisp/lisp.h"
+#include "control/controller.h"
#include "statistics.h"
#include "timer.h"
#include "tile_manager.h"
-namespace SuperTux {
- class Menu;
- class Sprite;
-}
-
+class Sprite;
+class Menu;
extern Menu* worldmap_menu;
namespace WorldMapNS {
private:
WorldMap* worldmap;
Sprite* tux_sprite;
+ Controller* controller;
Direction input_direction;
Direction direction;
MusicRef song;
- bool enter_level;
-
Vector offset;
std::string savegame_file;
--- /dev/null
+# -*-shell-script-*-
+# Autopackage spec file
+
+[Meta]
+RootName: @supertux.berlios.de/supertux:$SOFTWAREVERSION
+DisplayName: SuperTux platform game
+ShortName: supertux
+Maintainer: SuperTux Development Team <supertux-devel@lists.berlios.de>
+Packager: Matthis Braun <matze@braunis.de>
+Summary: The SuperTux platform game is a cute penguin-oriented clone of Super Mario Bros
+SoftwareVersion: 0.1.2
+PackageVersion: 1
+AutopackageTarget: 1.0
+
+[Description]
+SuperTux is a jump'n run like game, with strong inspiration from the
+Super Mario Bros games for Nintendo.
+
+Run and jump through multiple worlds, fighting off enemies by jumping
+on them or bumping them from below. Grabbing power-ups and other stuff
+on the way.
+
+[BuildPrepare]
+prepareBuild
+
+[BuildUnprepare]
+unprepareBuild
+
+[Imports]
+echo '*' | import
+import share/pixmaps <<EOF
+$source_dir/data/images/supertux.png
+$source_dir/data/images/supertux.xpm
+EOF
+import share/applications <<EOF
+$source_dir/supertux.desktop
+EOF
+
+[Prepare]
+# Dependency checking
+require @libsdl.org/sdl 1.2
+require @gnu.org/libstdc++ 3
+require @opengl.org/opengl 1.2
+
+[Install]
+# Put your installation script here
+installExe bin/*
+installData share/supertux
+installIcon share/pixmaps/*.png
+installIcon share/pixmaps/*.xpm
+installDesktop "Games" share/applications/supertux.desktop
+
+[Uninstall]
+# Usually just the following line is enough to uninstall everything
+uninstallFromLog
if(Spike)
writer.Write("spike", true);
if(Coin)
- writer.Write("distro", true);
+ writer.Write("coin", true);
if(FullBox)
writer.Write("fullbox", true);
if(Brick)
case "fullbox":
FullBox = parser.BoolValue;
break;
- case "distro":
+ case "coin":
Coin = parser.BoolValue;
break;
case "goal":