From bbe2f5d00d688c309cf472a304d12b1464dc715d Mon Sep 17 00:00:00 2001 From: Thomas Perl Date: Sun, 28 Jul 2013 02:16:53 +0200 Subject: [PATCH] Version 1.2.0 with new build/configure system --- README.MacOSX | 15 -- README.Maemo | 13 -- README.win32 | 84 -------- SDLMain.h | 11 - SDLMain.m | 384 ---------------------------------- configure | 334 +++++++++++++++++++++++++++++ data/Tennix.icns | Bin 42884 -> 0 bytes defaultbot.py => data/defaultbot.py | 0 data/icon.ico | Bin 4286 -> 0 bytes data/icon.svg | 147 ------------- tennix.6 => data/tennix.6 | 0 tennix.desktop => data/tennix.desktop | 0 data/{icon.png => tennix.png} | Bin {data => doc}/court.xcf | Bin {data => doc}/data2csrc.c | 0 {data => doc}/stadium.xcf | Bin makefile | 302 +++++++++++--------------- osxapp.plist | 26 --- SDL_rotozoom.c => src/SDL_rotozoom.cc | 14 +- SDL_rotozoom.h => src/SDL_rotozoom.h | 0 animation.c => src/animation.cc | 0 animation.h => src/animation.h | 0 archive.cc => src/archive.cc | 67 +++--- archive.hh => src/archive.h | 8 +- archivetool.cc => src/archivetool.cc | 26 +-- credits.h => src/credits.h | 2 +- game.c => src/game.cc | 54 ++--- game.h => src/game.h | 0 graphics.cc => src/graphics.cc | 32 ++- graphics.h => src/graphics.h | 2 +- input.c => src/input.cc | 77 +++---- input.h => src/input.h | 19 +- locations.h => src/locations.h | 0 network.c => src/network.cc | 5 + network.h => src/network.h | 4 + sound.cc => src/sound.cc | 2 +- sound.h => src/sound.h | 2 +- tennix.cc => src/tennix.cc | 88 ++------ tennix.h => src/tennix.h | 42 ++-- tennixpy.cc => src/tennixpy.cc | 77 ++++++- tennixpy.h => src/tennixpy.h | 32 ++- util.c => src/util.cc | 0 util.h => src/util.h | 15 -- tennix-installer.iss.in | 47 ----- tennix.res | Bin 4924 -> 0 bytes 45 files changed, 702 insertions(+), 1229 deletions(-) delete mode 100644 README.MacOSX delete mode 100644 README.Maemo delete mode 100644 README.win32 delete mode 100644 SDLMain.h delete mode 100644 SDLMain.m create mode 100755 configure delete mode 100644 data/Tennix.icns rename defaultbot.py => data/defaultbot.py (100%) delete mode 100644 data/icon.ico delete mode 100644 data/icon.svg rename tennix.6 => data/tennix.6 (100%) rename tennix.desktop => data/tennix.desktop (100%) rename data/{icon.png => tennix.png} (100%) rename {data => doc}/court.xcf (100%) rename {data => doc}/data2csrc.c (100%) rename {data => doc}/stadium.xcf (100%) rewrite makefile (84%) delete mode 100644 osxapp.plist rename SDL_rotozoom.c => src/SDL_rotozoom.cc (95%) rename SDL_rotozoom.h => src/SDL_rotozoom.h (100%) rename animation.c => src/animation.cc (100%) rename animation.h => src/animation.h (100%) rename archive.cc => src/archive.cc (81%) rename archive.hh => src/archive.h (94%) rename archivetool.cc => src/archivetool.cc (85%) rename credits.h => src/credits.h (97%) rename game.c => src/game.cc (97%) rename game.h => src/game.h (100%) rename graphics.cc => src/graphics.cc (97%) rename graphics.h => src/graphics.h (99%) rename input.c => src/input.cc (82%) rename input.h => src/input.h (90%) rename locations.h => src/locations.h (100%) rename network.c => src/network.cc (99%) rename network.h => src/network.h (98%) rename sound.cc => src/sound.cc (99%) rename sound.h => src/sound.h (99%) rename tennix.cc => src/tennix.cc (94%) rename tennix.h => src/tennix.h (85%) rename tennixpy.cc => src/tennixpy.cc (79%) rename tennixpy.h => src/tennixpy.h (56%) rename util.c => src/util.cc (100%) rename util.h => src/util.h (75%) delete mode 100644 tennix-installer.iss.in delete mode 100644 tennix.res diff --git a/README.MacOSX b/README.MacOSX deleted file mode 100644 index be7c324..0000000 --- a/README.MacOSX +++ /dev/null @@ -1,15 +0,0 @@ -Build instructions for Tennix on Mac OS X -========================================= - -Install Xcode tools (so you get gcc et al.) and then compile SDL, SDL_mixer, -SDL_image and SDL_ttf from source. You should install the additional libraries -in the same $PREFIX as SDL itself, so that "sdl-config --prefix" returns the -correct prefix for all libraries. After this you should be able to compile -Tennix with the following commands: - - make - make release-osx - -This should result in a Tennix.app bundle in the build directory that should -not depend on anything that is not included with a default Mac OS X install. - diff --git a/README.Maemo b/README.Maemo deleted file mode 100644 index da72db6..0000000 --- a/README.Maemo +++ /dev/null @@ -1,13 +0,0 @@ -To enable some code tweaks for the Maemo Platform (Nokia Internet Tablets), -compile with "make MAEMO=1". This will enable (and disable) some features -that are needed or unnecessary on Nokia Internet Tablets (i.e. Multiplayer). - -For audio to work, you have to convert the .ogg files in the "data/" folder -to .wav files (Maemo's SDL seems to not have Ogg support compiled in). For -the background.ogg file, you can create a dummy file with the following -command: "arecord -twav -d1 background.wav". This makes the binary smaller. - -For all other .ogg files in the "data/" folder, you can use "oggdec *.ogg". - -Don't forget to update both "makefile" and "data/makefile" to ".wav" instead -of ".ogg" for it to work correctly. diff --git a/README.win32 b/README.win32 deleted file mode 100644 index 2aea90a..0000000 --- a/README.win32 +++ /dev/null @@ -1,84 +0,0 @@ -Tennix can now be built on win32! :) - -Guide on installing SDL + MSYS + MinGW on Win32: -http://www.netadelica.com/coding/sdl/install.html - -Cross-compiling on a Debian System (untested!) -http://wiki.njh.eu/MinGW-Cross-Compiling_mit_SDL - -You also need the win32 development packages of -SDL_mixer, SDL_image and SDL_ttf, these can be found here: - -http://www.libsdl.org/projects/SDL_mixer/ -http://www.libsdl.org/projects/SDL_image/ -http://www.libsdl.org/projects/SDL_ttf/ - -For these libraries, copy the *.h files -to c:\mingw\include\SDL\ and the *.lib files to -c:\mingw\lib\. The .dll files have to be copied -to the tennix source folder, so they can be -found and copied to the binary release archive. - - -You should also consider installing UPX and ZIP -into your $PATH, so the .exe file can be compressed -and the "zip" utility (from InfoZIP) is needed for -the "release-win32" makefile target, which will create -a zipfile with the binary release, ready to be distributed :) - -===================== -Additional notes on Git + Win32 resources + InnoSetup -===================== -** GIT ** -You can download and bootstrap Git ported to Windows from -http://code.google.com/p/msysgit/. Simply download the -"GitMe-0.4.2.exe" (or newer) and run it to install Git and -a local version of msys to c:\msysgit\. - -You will be able to use Git on tennix's public repository, -see the Tennix website for more information. - -** Win32 resources ** -We are now using Win32 resource files to have an icon in the -Windows executable an to store the layout of the startup -dialog (that is only displayed in Windows atm). - -I've edited the "tennix.res" file (which contains the icon and -the dialog layout) with "XN Resource Editor", which is a freeware -resource editor for Windows, but you might want to use another -resource editor of you choice. - -URL: http://www.wilsonc.demon.co.uk/d10resourceeditor.htm - -** InnoSetup ** -Make sure you have installed InnoSetup 5 if you -want to generate a setup installer. You also have to set -the $PATH variable to point to the Inno Setup install dir -on your hard drive (eg c:\program files\inno setup 5\). -To check if you have set it up correctly, open your msys -shell and type "iscc". It should respond with "Inno Setup -5 Command-Line Compiler" and some generic information. - -When you have set up iscc correctly, simply do a "make -release-win32-setup" to compile a single setup executable -with innosetup and tennix. - -Thomas Perl , 2007-11-21 -===================== - - -#######======------ --- -- - - -Additional notes on libraries on Win32 -#######======------ --- -- - - - -You might have to add some libraries for Tennix 1.0 (and later) to compile -correctly under mingw32: - - -lws2_32 -lkernel32 - -This can be set as LDFLAGS and/or LIBS variable in the makefile. For some -specific makefile targets (e.g. the "archive" utility), you might have to -specify "-lws2_32" directly in the target to get the build going. - -#######======------ --- -- - - - diff --git a/SDLMain.h b/SDLMain.h deleted file mode 100644 index 4683df5..0000000 --- a/SDLMain.h +++ /dev/null @@ -1,11 +0,0 @@ -/* SDLMain.m - main entry point for our Cocoa-ized SDL app - Initial Version: Darrell Walisser - Non-NIB-Code & other changes: Max Horn - - Feel free to customize this file to suit your needs -*/ - -#import - -@interface SDLMain : NSObject -@end diff --git a/SDLMain.m b/SDLMain.m deleted file mode 100644 index 2eaa1c1..0000000 --- a/SDLMain.m +++ /dev/null @@ -1,384 +0,0 @@ -/* SDLMain.m - main entry point for our Cocoa-ized SDL app - Initial Version: Darrell Walisser - Non-NIB-Code & other changes: Max Horn - - Feel free to customize this file to suit your needs -*/ - -#import "SDL.h" -#import "SDLMain.h" -#import /* for MAXPATHLEN */ -#import - -/* For some reaon, Apple removed setAppleMenu from the headers in 10.4, - but the method still is there and works. To avoid warnings, we declare - it ourselves here. */ -@interface NSApplication(SDL_Missing_Methods) -- (void)setAppleMenu:(NSMenu *)menu; -@end - -/* Use this flag to determine whether we use SDLMain.nib or not */ -#define SDL_USE_NIB_FILE 0 - -/* Use this flag to determine whether we use CPS (docking) or not */ -#define SDL_USE_CPS 1 -#ifdef SDL_USE_CPS -/* Portions of CPS.h */ -typedef struct CPSProcessSerNum -{ - UInt32 lo; - UInt32 hi; -} CPSProcessSerNum; - -extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn); -extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); -extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn); - -#endif /* SDL_USE_CPS */ - -static int gArgc; -static char **gArgv; -static BOOL gFinderLaunch; -static BOOL gCalledAppMainline = FALSE; - -static NSString *getApplicationName(void) -{ - NSDictionary *dict; - NSString *appName = 0; - - /* Determine the application name */ - dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle()); - if (dict) - appName = [dict objectForKey: @"CFBundleName"]; - - if (![appName length]) - appName = [[NSProcessInfo processInfo] processName]; - - return appName; -} - -#if SDL_USE_NIB_FILE -/* A helper category for NSString */ -@interface NSString (ReplaceSubString) -- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString; -@end -#endif - -@interface SDLApplication : NSApplication -@end - -@implementation SDLApplication -/* Invoked from the Quit menu item */ -- (void)terminate:(id)sender -{ - /* Post a SDL_QUIT event */ - SDL_Event event; - event.type = SDL_QUIT; - SDL_PushEvent(&event); -} -@end - -/* The main class of the application, the application's delegate */ -@implementation SDLMain - -/* Set the working directory to the .app's parent directory */ -- (void) setupWorkingDirectory:(BOOL)shouldChdir -{ - if (shouldChdir) - { - char parentdir[MAXPATHLEN]; - CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); - CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url); - if (CFURLGetFileSystemRepresentation(url2, true, (UInt8 *)parentdir, MAXPATHLEN)) { - assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */ - } - CFRelease(url); - CFRelease(url2); - } - -} - -#if SDL_USE_NIB_FILE - -/* Fix menu to contain the real app name instead of "SDL App" */ -- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName -{ - NSRange aRange; - NSEnumerator *enumerator; - NSMenuItem *menuItem; - - aRange = [[aMenu title] rangeOfString:@"SDL App"]; - if (aRange.length != 0) - [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]]; - - enumerator = [[aMenu itemArray] objectEnumerator]; - while ((menuItem = [enumerator nextObject])) - { - aRange = [[menuItem title] rangeOfString:@"SDL App"]; - if (aRange.length != 0) - [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]]; - if ([menuItem hasSubmenu]) - [self fixMenu:[menuItem submenu] withAppName:appName]; - } - [ aMenu sizeToFit ]; -} - -#else - -static void setApplicationMenu(void) -{ - /* warning: this code is very odd */ - NSMenu *appleMenu; - NSMenuItem *menuItem; - NSString *title; - NSString *appName; - - appName = getApplicationName(); - appleMenu = [[NSMenu alloc] initWithTitle:@""]; - - /* Add menu items */ - title = [@"About " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; - - [appleMenu addItem:[NSMenuItem separatorItem]]; - - title = [@"Hide " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; - - menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; - [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; - - [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; - - [appleMenu addItem:[NSMenuItem separatorItem]]; - - title = [@"Quit " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"]; - - - /* Put menu into the menubar */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; - [menuItem setSubmenu:appleMenu]; - [[NSApp mainMenu] addItem:menuItem]; - - /* Tell the application object that this is now the application menu */ - [NSApp setAppleMenu:appleMenu]; - - /* Finally give up our references to the objects */ - [appleMenu release]; - [menuItem release]; -} - -/* Create a window menu */ -static void setupWindowMenu(void) -{ - NSMenu *windowMenu; - NSMenuItem *windowMenuItem; - NSMenuItem *menuItem; - - windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; - - /* "Minimize" item */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; - [windowMenu addItem:menuItem]; - [menuItem release]; - - /* Put menu into the menubar */ - windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; - [windowMenuItem setSubmenu:windowMenu]; - [[NSApp mainMenu] addItem:windowMenuItem]; - - /* Tell the application object that this is now the window menu */ - [NSApp setWindowsMenu:windowMenu]; - - /* Finally give up our references to the objects */ - [windowMenu release]; - [windowMenuItem release]; -} - -/* Replacement for NSApplicationMain */ -static void CustomApplicationMain (int argc, char **argv) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - SDLMain *sdlMain; - - /* Ensure the application object is initialised */ - [SDLApplication sharedApplication]; - -#ifdef SDL_USE_CPS - { - CPSProcessSerNum PSN; - /* Tell the dock about us */ - if (!CPSGetCurrentProcess(&PSN)) - if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103)) - if (!CPSSetFrontProcess(&PSN)) - [SDLApplication sharedApplication]; - } -#endif /* SDL_USE_CPS */ - - /* Set up the menubar */ - [NSApp setMainMenu:[[NSMenu alloc] init]]; - setApplicationMenu(); - setupWindowMenu(); - - /* Create SDLMain and make it the app delegate */ - sdlMain = [[SDLMain alloc] init]; - [NSApp setDelegate:sdlMain]; - - /* Start the main event loop */ - [NSApp run]; - - [sdlMain release]; - [pool release]; -} - -#endif - - -/* - * Catch document open requests...this lets us notice files when the app - * was launched by double-clicking a document, or when a document was - * dragged/dropped on the app's icon. You need to have a - * CFBundleDocumentsType section in your Info.plist to get this message, - * apparently. - * - * Files are added to gArgv, so to the app, they'll look like command line - * arguments. Previously, apps launched from the finder had nothing but - * an argv[0]. - * - * This message may be received multiple times to open several docs on launch. - * - * This message is ignored once the app's mainline has been called. - */ -- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename -{ - const char *temparg; - size_t arglen; - char *arg; - char **newargv; - - if (!gFinderLaunch) /* MacOS is passing command line args. */ - return FALSE; - - if (gCalledAppMainline) /* app has started, ignore this document. */ - return FALSE; - - temparg = [filename UTF8String]; - arglen = SDL_strlen(temparg) + 1; - arg = (char *) SDL_malloc(arglen); - if (arg == NULL) - return FALSE; - - newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2)); - if (newargv == NULL) - { - SDL_free(arg); - return FALSE; - } - gArgv = newargv; - - SDL_strlcpy(arg, temparg, arglen); - gArgv[gArgc++] = arg; - gArgv[gArgc] = NULL; - return TRUE; -} - - -/* Called when the internal event loop has just started running */ -- (void) applicationDidFinishLaunching: (NSNotification *) note -{ - int status; - - /* Set the working directory to the .app's parent directory */ - [self setupWorkingDirectory:gFinderLaunch]; - -#if SDL_USE_NIB_FILE - /* Set the main menu to contain the real app name instead of "SDL App" */ - [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()]; -#endif - - /* Hand off to main application code */ - gCalledAppMainline = TRUE; - status = SDL_main (gArgc, gArgv); - - /* We're done, thank you for playing */ - exit(status); -} -@end - - -@implementation NSString (ReplaceSubString) - -- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString -{ - unsigned int bufferSize; - unsigned int selfLen = [self length]; - unsigned int aStringLen = [aString length]; - unichar *buffer; - NSRange localRange; - NSString *result; - - bufferSize = selfLen + aStringLen - aRange.length; - buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar)); - - /* Get first part into buffer */ - localRange.location = 0; - localRange.length = aRange.location; - [self getCharacters:buffer range:localRange]; - - /* Get middle part into buffer */ - localRange.location = 0; - localRange.length = aStringLen; - [aString getCharacters:(buffer+aRange.location) range:localRange]; - - /* Get last part into buffer */ - localRange.location = aRange.location + aRange.length; - localRange.length = selfLen - localRange.location; - [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange]; - - /* Build output string */ - result = [NSString stringWithCharacters:buffer length:bufferSize]; - - NSDeallocateMemoryPages(buffer, bufferSize); - - return result; -} - -@end - - - -#ifdef main -# undef main -#endif - - -/* Main entry point to executable - should *not* be SDL_main! */ -int main (int argc, char **argv) -{ - /* Copy the arguments into a global variable */ - /* This is passed if we are launched by double-clicking */ - if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) { - gArgv = (char **) SDL_malloc(sizeof (char *) * 2); - gArgv[0] = argv[0]; - gArgv[1] = NULL; - gArgc = 1; - gFinderLaunch = YES; - } else { - int i; - gArgc = argc; - gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1)); - for (i = 0; i <= argc; i++) - gArgv[i] = argv[i]; - gFinderLaunch = NO; - } - -#if SDL_USE_NIB_FILE - [SDLApplication poseAsClass:[NSApplication class]]; - NSApplicationMain (argc, argv); -#else - CustomApplicationMain (argc, argv); -#endif - return 0; -} - diff --git a/configure b/configure new file mode 100755 index 0000000..4c19a64 --- /dev/null +++ b/configure @@ -0,0 +1,334 @@ +#!/bin/sh +# Configuration script for Tennix +# 2013-07-27 Thomas Perl + +V="1.2.0" +SILENT="1" +PREFIX="/usr/local" +DEFAULT_CFLAGS="-I. -Wno-char-subscripts -Wno-maybe-uninitialized" + +if [ -z "$CC" ]; then + CC="gcc" +fi + +if [ -z "$CXX" ]; then + CXX="g++" +fi + +if [ -z "$CFLAGS" ]; then + CFLAGS="" +fi + +if [ -z "$LDFLAGS" ]; then + LDFLAGS="" +fi + +CFLAGS="$DEFAULT_CFLAGS $CFLAGS" + +PLATFORM="" + +GENERATED_HEADER="Generated: $(date)" +CONFIG_H="/* $GENERATED_HEADER */" +CONFIG_MK="# $GENERATED_HEADER" + +NL=' +' + +fail() { + echo "ERROR: $1" + exit 1 +} + +set_make_variable() { + CONFIG_MK="$CONFIG_MK$NL$1 := $2" +} + +define_macro() { + CONFIG_H="$CONFIG_H$NL#define $1" +} + +undefine_macro() { + CONFIG_H="$CONFIG_H$NL#undef $1" +} + +add_definition() { + define_macro $1 + set_make_variable $1 1 +} + +no_definition() { + undefine_macro $1 + set_make_variable $1 0 +} + +cond_definition() { + if [ $1 -eq 0 ]; then + add_definition $2 + else + no_definition $2 + fi +} + +check_cc() { + echo "int main() { return 0; }" | $CC $CFLAGS -x c -c -o /dev/null - 2>/dev/null +} + +check_cxx() { + echo "class A { public: A() {} }; int main() { A a; }" | $CXX $CFLAGS -x c++ -c -o /dev/null - +} + +check_linker_cc() { + echo "int main() { return 0; }" | $CC $CFLAGS $LDFLAGS -l$1 -x c -o /dev/null - 2>/dev/null +} + +check_header_cc() { + echo "#include <$1>" | $CC $CFLAGS -c -x c -o /dev/null -c - 2>/dev/null +} + +message_wrapper() { + echo -n "$1 ... " + shift + $* + if [ $? -eq 0 ]; then + echo "yes" + return 0 + else + echo "no" + return 1 + fi +} + +check_sdl_lib() { + if ! which sdl-config >/dev/null 2>&1; then + return 1 + fi + + CFLAGS="$(sdl-config --cflags) $CFLAGS" + LDFLAGS="$(sdl-config --libs) $LDFLAGS" + return 0 +} + +check_os() { + echo -n "Detecting operating system ... " + UNAME=$(uname -s) + case $UNAME in + Linux) + echo "Linux" + PLATFORM="linux" + ;; + Darwin) + echo "Mac OS X" + PLATFORM="osx" + ;; + *) + echo "???" + fail "Unknown platform: $UNAME" + ;; + esac +} + +check_compiler() { + message_wrapper "Testing working C compiler ($CC)" check_cc || fail "C compiler ($CC) not working" + message_wrapper "Testing working C++ compiler ($CXX)" check_cxx || fail "C++ compiler ($CXX) not working" +} + +check_sdl() { + message_wrapper "Checking for SDL 1.2" check_sdl_lib + cond_definition $? HAVE_SDL +} + +require_sdl() { + check_sdl || fail "SDL not found" +} + +check_voice_files() { + message_wrapper "Checking for voice files" [ -f voice/deuce.ogg ] + cond_definition $? HAVE_VOICE_FILES +} + +check_python_lib() { + if ! which python-config >/dev/null 2>&1; then + return 1 + fi + + CFLAGS="$(python-config --cflags) $CFLAGS" + LDFLAGS="$(python-config --libs) $LDFLAGS" + return 0 +} + +check_tool_path() { + COMMAND=$1 + VARIABLE=$2 + + if ! which $COMMAND >/dev/null 2>&1; then + return 1 + fi + + if [ "$VARIABLE" != "" ]; then + set_make_variable $VARIABLE $(which $COMMAND 2>/dev/null) + fi +} + +check_tool() { + message_wrapper "Checking for $1" check_tool_path $* +} + +require_tool() { + check_tool $* || fail "Required command '$1' not found" +} + +check_python() { + message_wrapper "Checking for libpython" check_python_lib + cond_definition $? HAVE_PYTHON +} + +check_header() { + message_wrapper "Checking for $1" check_header_cc $1 +} + +check_linker() { + message_wrapper "Checking for -l$1" check_linker_cc $1 +} + +check_library() { + LIBRARY=$1 + HEADER=$2 + DEFINE=$3 + check_linker $LIBRARY + HAVE_LINKER=$? + check_header $HEADER + HAVE_HEADER=$? + if [ $HAVE_LINKER -eq 0 -a $HAVE_HEADER -eq 0 ]; then + add_definition $DEFINE + LDFLAGS="-l$LIBRARY $LDFLAGS" + else + no_definition $DEFINE + return 1 + fi + return 0 +} + +require_library() { + check_library $* || fail "Library $1 ($2) not found" +} + +generate_dependencies() { + echo "Generating dependencies.mk" + rm -f dependencies.mk + ( + echo "# $GENERATED_HEADER" + for filename in src/*.cc; do $CXX -MM $filename $CFLAGS -o -; done + )>dependencies.mk +} + +write_config() { + echo "Writing config.h" + rm -f config.h + ( + echo "$CONFIG_H" + echo "#define VERSION \"$V\"" + echo "#define PREFIX \"$PREFIX\"" + )>config.h + + echo "Writing config.mk" + rm -f config.mk + ( + echo "$CONFIG_MK" + echo "V = $V" + echo "SILENT = $SILENT" + echo "PREFIX = $PREFIX" + echo "PLATFORM = $PLATFORM" + echo "CC = $CC" + echo "CXX = $CXX" + echo "CFLAGS = $CFLAGS" + echo "CXXFLAGS = $CFLAGS" + echo "LDFLAGS = $LDFLAGS" + )>config.mk +} + +usage() { + cat <%wPM4HVgV)es?w283ZaG$Qj}gL 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 J{%8HL{|B_FK1l!o diff --git a/defaultbot.py b/data/defaultbot.py similarity index 100% rename from defaultbot.py rename to data/defaultbot.py diff --git a/data/icon.ico b/data/icon.ico deleted file mode 100644 index 31494a7af37874d7c595bafd4a8fa7660e08983b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcwPel00001 literal 4286 zcwViT3sh8f9>=fv1VjkY9=mDV>6D#T$x~>hX_-VC`9K2{%+kyU*1BrXEp^N4Y}?s2 z+3K{%vR3P;wQjs$!(-;o4D+6Wc`^(zFJ^{$Ac`ge_TAt84{*@3+SC3$KZm*8`~Q6Z z|NrlG;kYsM@0MFQ;eYN#630#FIBpghUE&_%qSt@zm^g6)cf<85+`N0|T+@W#3-|p$ zN6OUeuI6Ca?wfZvMt>iDpYYtT8HrO8u3$d;*dr+Tpb&=@I-F=}N447rsXqh}eO9%$ zKl9ZV6bEqGT(cH|OCsC->f$xey8Vo^3#s|BZNrPd8dU|l?>{(ds zb~Kqxko$u8r%H!ac{w9G9$IuiH*VaxpTlx7F)_qUW$c9yq~Tzt2;xAP*xe9!1@TFz z19|Npq}eU_jm3{?HXFpfy%-oA#K{H;zAY|-+U0>J)D3l47>8@>uy8>d)39jad@e37 z?kD-f>rP*uj$>BG5VsqzyS-1{GsQif2 zSP`qXVT>w($yzfeYTK}?-OTvCvrkPh%MU%BN0H4jau!pQldj;WMc0nE%W9zL@Sxb)iDa=4oG3u% zM|?vQCdeGbHG^vmB2I3`qy{T);2Ute%7A}#xftJcCc^k@p31{IofMf)5jHv<%y$J1 zf7_VqYvOO6)b=r}Y zP0y{%#TK~;*-izvIztqf0ce5|WDrl_3b|VNEcn|8;C&%{;P4|w)`30kZrIQDp}Thg z|0*g&*7{tgVeyNv;bvtqrs}1*)liQ+bw;FV6(;92}m@(pfpF2n351?K6+SfHsvhFXq1T{EgFCkmsdzaJZS?`F@ed;MiR(OQOm zUM2BE_*5A^gITxV%J?UnZQ#8@+^bR`MOjV0twUUc1`})AaKzP#@VNmvoF3%t*umy| zeETNcrWGT#nfBgb#u7~<7ON`oguWJ=O)_};&NB_|XU|~6kT0x#bq}_+8OR3$D7LpV z{+!?6!T8k<7xB9=lb0dBP6n>Rf+VRJ@nRKX>vTBaXh+Y5K{)&oWIneo>JOhB!rc}V zmYT!JY_?#fL4g8`4R5qrQRp+`;^jf6!F8?|Pwm*wp4oKZ&(H^gkWicn+8*2-&eL_w#o=s>c?tpE7n>R*l3eu zAFcldw+JtJYVbwKfeV)hn1*nF9}a%{8LN>>wQ6Mj!siKt1v0M>i?!uQk(467MuO>$ zCA1F~OsSJ%9G%CQs#YAdd(q1AxvT}2L8?YxNWcm5i!HGg>@%gKLNG%N7O<{);O%-CS9!uF0@yydZBn@5K2 zZUgGb5BjK1gnG{6xJ)tH|G6FSAA*c(RH3OIN!1ldtgc3KZ51Y!$dOo4hu9JYVkNx51~>leHISVVPwGVMEe zf@1NjX2g(izo|f9a_&vBXNTXy%b`bR*Ab##0tE*4y-0 z?=aFnn5h1Ruc&{c`{OyYqkeesKjq*(0hD<=@Y`w`#un+2P(^vDT!y%EB@#sBk0K4e zYCpsHYu|m3@gM%;V=S=LA%kk@a-$aMR2!BVc&s&BkWam$&cvh>wk1+ z$b3E=ZS~@2u^iLnWtdzi$7G2T@lqA0D(g`cIFEDR4I=x%e#T#P@;DZlZCGUG@t~y$ znG^#VCI#{+&zAawFkIFD2)wJujGJ#_8kSP8SZsH)eEco-LGx6kL0O6M^+xK)8jz&s zVLX2cLTX#Jdl%!URhD5My%Q{?KIGw6EmpLIu%j)=dS+qW4IckU4=Ql3HHPC+&~Qv| zVKq@qwy)KM=`tIVH4TW7Q7ssZ=GB#(o?-mijS{5NJ@Xx6EN^SWN1ia%x$cp^Z}&~Okb2!#mlN647vvXg$C6gcxh^k`1w2qu zd}&#)6~Tw1`jI^s<`w4uC1dz31YcP}aZxB$L+a}S?+?Qk?q=^hc9)Cga;>8kjr2~W z2nL~~+O8t*XKFpxveWGHmzHpNsivsTg&Q-IF?J)-QhljW$a& zfdgalJ$)VIxcz+`x44JnW;$sb8tBzuumc=7cGx)KPYTzt(f18ME6gLzC(J9%FK`5& G!2K_6+{42F diff --git a/data/icon.svg b/data/icon.svg deleted file mode 100644 index efd874e..0000000 --- a/data/icon.svg +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tennix.6 b/data/tennix.6 similarity index 100% rename from tennix.6 rename to data/tennix.6 diff --git a/tennix.desktop b/data/tennix.desktop similarity index 100% rename from tennix.desktop rename to data/tennix.desktop diff --git a/data/icon.png b/data/tennix.png similarity index 100% rename from data/icon.png rename to data/tennix.png diff --git a/data/court.xcf b/doc/court.xcf similarity index 100% rename from data/court.xcf rename to doc/court.xcf diff --git a/data/data2csrc.c b/doc/data2csrc.c similarity index 100% rename from data/data2csrc.c rename to doc/data2csrc.c diff --git a/data/stadium.xcf b/doc/stadium.xcf similarity index 100% rename from data/stadium.xcf rename to doc/stadium.xcf diff --git a/makefile b/makefile dissimilarity index 84% index 28986ba..7d1891d 100644 --- a/makefile +++ b/makefile @@ -1,180 +1,122 @@ - -# -# Tennix! SDL Port -# Copyright (C) 2003, 2007, 2008, 2009 Thomas Perl -# -# 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., 51 Franklin Street, Fifth Floor, Boston, -# MA 02110-1301, USA. -# - -CC = g++ - - -ifeq ($(MKCALLGRAPH),1) - CC = nccgen -ncgcc -ncld -ncfabs - LD = nccld -endif - -RELEASE = 1.1.1 - -PREFIX ?= /usr/local -BINDIR ?= $(PREFIX)/bin -DATAROOTDIR ?= $(PREFIX)/share -DATADIR ?= $(DATAROOTDIR)/games - -CFLAGS += -W -Wall -DVERSION=\"$(RELEASE)\" -O2 -DPREFIX=\"$(PREFIX)\" -CXXFLAGS += $(CFLAGS) - -USE_PYTHON ?= 1 - -ifeq ($(USE_PYTHON),1) - PYTHON_INCLUDES := $(shell python-config --includes) - PYTHON_LIBS := $(shell python-config --libs) - CFLAGS += $(PYTHON_INCLUDES) -DTENNIX_PYTHON - LIBS += $(PYTHON_LIBS) -endif - -ifeq ($(NONFREE_LOCATIONS),1) - CFLAGS += -DNONFREE_LOCATIONS -endif - -ifeq ($(UPDRECTANGLE),1) - CFLAGS += -DDRAW_UPDATE_RECTANGLE -endif - -ifeq ($(DELUXE),1) - CFLAGS += -DDELUXE_EDITION -endif - -ifeq ($(DEBUG),1) - CFLAGS += -DDEBUG -endif - -ifeq ($(MAEMO),1) - CFLAGS += -DMAEMO -endif - -SDL_LIBS := $(shell sdl-config --libs) -SDL_CFLAGS := $(shell sdl-config --cflags) - -LIBS += $(SDL_LIBS) -lSDL_mixer -lSDL_image -lSDL_ttf -lSDL_net -CFLAGS += $(SDL_CFLAGS) - -OBJ = tennix.o game.o graphics.o input.o util.o sound.o animation.o archive.o SDL_rotozoom.o network.o - -ifeq ($(MSYSTEM),MINGW32) - OBJ += tennixres.o -endif -ifeq ($(USE_PYTHON),1) - OBJ += tennixpy.o -endif - -TOARCHIVE=$(wildcard data/*.ogg data/*.ttf wildcard data/*.png voice/*.ogg *.py) - -WIN32LIBS = *.dll -OSXAPP = Tennix.app - -DATAFILES = README README.* -DATAFILES_OSX = $(DATAFILES) data/Tennix.icns - -tennix: $(OBJ) tennix.tnx - $(CC) $(CFLAGS) $(LDFLAGS) -o tennix $(OBJ) $(LIBS) - test -f tennix.exe && upx tennix.exe || true - -ChangeLog: - git log >ChangeLog - -install: tennix - install -d -m 755 $(DESTDIR)$(BINDIR) - install -d -m 755 $(DESTDIR)$(DATAROOTDIR)/pixmaps - install -d -m 755 $(DESTDIR)$(DATAROOTDIR)/applications - install -d -m 755 $(DESTDIR)$(DATAROOTDIR)/man/man6 - install -d -m 755 $(DESTDIR)$(DATAROOTDIR)/icons/hicolor/scalable/apps - install -d -m 755 $(DESTDIR)$(DATADIR)/tennix - install -m 755 tennix $(DESTDIR)$(BINDIR)/ - install -m 644 tennix.6 $(DESTDIR)$(DATAROOTDIR)/man/man6/ - install -m 644 data/icon.png $(DESTDIR)$(DATAROOTDIR)/pixmaps/tennix.png - install -m 644 data/icon.svg $(DESTDIR)$(DATAROOTDIR)/icons/hicolor/scalable/apps/tennix.svg - install -m 644 tennix.desktop $(DESTDIR)$(DATAROOTDIR)/applications/ - install -m 644 tennix.tnx $(DESTDIR)$(DATADIR)/tennix/ - -archive.o: archive.cc archive.cc -tennix.o: tennix.cc tennix.h game.h graphics.h input.h util.h animation.h sound.h locations.h util.h archive.hh -graphics.o: graphics.cc graphics.h tennix.h archive.hh sound.h -game.o: game.c game.h graphics.h tennix.h sound.h input.h util.h network.h -sound.o: sound.cc sound.h tennix.h archive.hh graphics.h -input.o: input.c input.h tennix.h graphics.h game.h util.h tennixpy.h archive.hh -util.o: util.c util.h tennix.h -animation.o: animation.c animation.h graphics.h tennix.h credits.h -tennixpy.o: tennixpy.cc tennix.h game.h archive.hh -network.o: network.c network.h game.h -SDL_rotozoom.o: SDL_rotozoom.c SDL_rotozoom.h - -tennixar: archive dump - -archive: archivetool.cc archive.o archive.hh - -dump: archive - ln -s archive dump - -tennix.tnx: archive $(TOARCHIVE) - rm -f tennix.tnx - ./archive $@ $(TOARCHIVE) - -# Mac OS X-specific targets -release-osx: tennix tennix.tnx ChangeLog - mkdir -p $(OSXAPP)/Contents/{MacOS,/Resources} - cp -rpv tennix $(OSXAPP)/Contents/MacOS/Tennix - cp -rpv tennix.tnx $(DATAFILES_OSX) ChangeLog $(OSXAPP)/Contents/Resources/ - sed -e 's/TENNIX_VERSION/$(RELEASE)/' osxapp.plist >$(OSXAPP)/Contents/Info.plist - echo 'APPL????' >$(OSXAPP)/Contents/PkgInfo - zip -r tennix-$(RELEASE)-macosx.zip $(OSXAPP) -# End Mac OS X-specific targets - -# Windows-specific targets -release-win32: tennix ChangeLog - zip tennix-$(RELEASE)-win32.zip tennix.exe $(WIN32LIBS) $(DATAFILES) ChangeLog - -tennix-installer.iss: tennix-installer.iss.in - sed tennix-installer.iss.in -e 's/{version}/$(RELEASE)/g' >tennix-installer.iss - -release-win32-setup: tennix ChangeLog tennix-installer.iss - iscc tennix-installer.iss - -tennixres.o: tennix.res - windres tennix.res tennixres.o -# End Windows-specific targets - -release-bin: tennix ChangeLog - tar czvf tennix-$(RELEASE)-bin.tar.gz tennix $(DATAFILES) ChangeLog - -release: distclean ChangeLog - mkdir -p .release-tmp/tennix-$(RELEASE)/ - cp -rv * .release-tmp/tennix-$(RELEASE)/ - rm -rf .release-tmp/tennix-$(RELEASE)/.git - tar czvf tennix-$(RELEASE).tar.gz -C .release-tmp tennix-$(RELEASE) - rm -rf .release-tmp - -clean: - rm -f *.o tennix tennix.exe archive archive.exe dump dump.exe - rm -rf $(OSXAPP) tennix-*-macosx.zip - rm -f tennixres.o tennix-installer.iss tennix-*-win32-setup.exe - rm -f tennix.tnx - -distclean: clean - rm -rf tennix-$(RELEASE).zip tennix-$(RELEASE)-bin.tar.gz .release-tmp tennix-$(RELEASE).tar.gz - -.PHONY: distclean clean release-bin release-win32 release-win32-setup release-osx install tennixar - + +# +# Tennix! SDL Port +# Copyright (C) 2003, 2007, 2008, 2009 Thomas Perl +# +# 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., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. +# + +-include config.mk + +CONFIGURE_OUTPUT := config.mk config.h dependencies.mk + +ifeq ($(SILENT),0) + SILENTMSG := @true + SILENTCMD := +else + SILENTMSG := @echo + SILENTCMD := @ +endif + +# Object files for "tennix" +TENNIX_BIN := tennix +TENNIX_OBJ += src/tennix.o src/game.o src/graphics.o src/input.o +TENNIX_OBJ += src/util.o src/sound.o src/animation.o src/archive.o +TENNIX_OBJ += src/SDL_rotozoom.o src/network.o src/tennixpy.o + +# Object files for "archive" +ARCHIVE_BIN := archive +ARCHIVE_OBJ += src/archivetool.o src/archive.o + +# Target filename for "dump" +DUMP_BIN := dump + +# Data files for tennix.tnx +TENNIX_TNX := tennix.tnx +TENNIX_TNX_DATA += $(wildcard data/*.ogg) +TENNIX_TNX_DATA += $(wildcard data/*.ttf) +TENNIX_TNX_DATA += $(wildcard data/*.png) + +ifeq ($(HAVE_VOICE_FILES),1) +TENNIX_TNX_DATA += $(wildcard voice/*.ogg) +endif + +ifeq ($(HAVE_PYTHON),1) +TENNIX_TNX_DATA += $(wildcard data/*.py) +endif + +# Installable files +TENNIX_PNG := data/tennix.png +TENNIX_DESKTOP := data/tennix.desktop +TENNIX_MAN := data/tennix.6 + +all: $(TENNIX_BIN) $(ARCHIVE_BIN) $(DUMP_BIN) $(TENNIX_TNX) + +%.o: %.cc + $(SILENTMSG) " CXX $@" + $(SILENTCMD)$(CXX) -c $(CFLAGS) -o $@ $< + +$(TENNIX_BIN): $(TENNIX_OBJ) + $(SILENTMSG) " LD $@" + $(SILENTCMD)$(CXX) $(LDFLAGS) -o $@ $^ + +$(ARCHIVE_BIN): $(ARCHIVE_OBJ) + $(SILENTMSG) " LD $@" + $(SILENTCMD)$(CXX) -o $@ $^ + +$(DUMP_BIN): $(ARCHIVE_BIN) + $(SILENTMSG) " SYMLINK $@" + $(SILENTCMD)$(LN) -s $< $@ + +$(TENNIX_TNX): $(ARCHIVE_BIN) $(TENNIX_TNX_DATA) + $(SILENTMSG) " ARCHIVE $@" + $(SILENTCMD)./$(ARCHIVE_BIN) $@ $(TENNIX_TNX_DATA) + +install: $(TENNIX_BIN) $(TENNIX_TNX) $(TENNIX_PNG) $(TENNIX_DESKTOP) $(TENNIX_MAN) + $(SILENTMSG) " INSTALL $(TENNIX_BIN)" + $(SILENTCMD)$(INSTALL) -d $(DESTDIR)$(PREFIX)/bin/ + $(SILENTCMD)$(INSTALL) -m 755 $(TENNIX_BIN) $(DESTDIR)$(PREFIX)/bin/ + $(SILENTMSG) " INSTALL $(TENNIX_TNX)" + $(SILENTCMD)$(INSTALL) -d $(DESTDIR)$(PREFIX)/share/tennix/ + $(SILENTCMD)$(INSTALL) -m 644 $(TENNIX_TNX) $(DESTDIR)$(PREFIX)/share/tennix/ + $(SILENTMSG) " INSTALL $(TENNIX_PNG)" + $(SILENTCMD)$(INSTALL) -d $(DESTDIR)$(PREFIX)/share/pixmaps/ + $(SILENTCMD)$(INSTALL) -m 644 $(TENNIX_PNG) $(DESTDIR)$(PREFIX)/share/pixmaps/ + $(SILENTMSG) " INSTALL $(TENNIX_DESKTOP)" + $(SILENTCMD)$(INSTALL) -d $(DESTDIR)$(PREFIX)/share/applications/ + $(SILENTCMD)$(INSTALL) -m 644 $(TENNIX_DESKTOP) $(DESTDIR)$(PREFIX)/share/applications/ + $(SILENTMSG) " INSTALL $(TENNIX_MAN)" + $(SILENTCMD)$(INSTALL) -d $(DESTDIR)$(PREFIX)/share/man/man6/ + $(SILENTCMD)$(INSTALL) -m 644 $(TENNIX_MAN) $(DESTDIR)$(PREFIX)/share/man/man6/ + +clean: + $(SILENTMSG) " CLEAN" + $(SILENTCMD)$(RM) -f $(TENNIX_BIN) $(TENNIX_OBJ) + $(SILENTCMD)$(RM) -f $(ARCHIVE_BIN) $(ARCHIVE_OBJ) + $(SILENTCMD)$(RM) -f $(DUMP_BIN) + $(SILENTCMD)$(RM) -f $(TENNIX_TNX) + +distclean: clean + $(SILENTMSG) " DISTCLEAN" + $(SILENTCMD)$(RM) -f $(CONFIGURE_OUTPUT) + +$(CONFIGURE_OUTPUT): configure + $(SILENTMSG) " CONFIGURE" + $(SILENTCMD)./$< + +-include dependencies.mk + +.PHONY: install clean distclean diff --git a/osxapp.plist b/osxapp.plist deleted file mode 100644 index 08980be..0000000 --- a/osxapp.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - Tennix - CFBundleIdentifier - com.thpinfo.2007.TennixSDL - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - Tennix - CFBundlePackageType - APPL - CFBundleSignature - ???? - CFBundleVersion - TENNIX_VERSION - CFBundleIconFile - Tennix.icns - NSPrincipalClass - NSApplication - - diff --git a/SDL_rotozoom.c b/src/SDL_rotozoom.cc similarity index 95% rename from SDL_rotozoom.c rename to src/SDL_rotozoom.cc index baff64d..041efb0 100644 --- a/SDL_rotozoom.c +++ b/src/SDL_rotozoom.cc @@ -24,7 +24,7 @@ int shrinkSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int factorx, int factory) { - int x, y, dx, dy, sgap, dgap, ra, ga, ba, aa; + int x, y, dx, dy, /*sgap, */dgap, ra, ga, ba, aa; int n_average; tColorRGBA *sp, *osp, *oosp; tColorRGBA *dp; @@ -40,7 +40,7 @@ int shrinkSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int factorx, int fac * Scan destination */ sp = (tColorRGBA *) src->pixels; - sgap = src->pitch - src->w * 4; + //sgap = src->pitch - src->w * 4; dp = (tColorRGBA *) dst->pixels; dgap = dst->pitch - dst->w * 4; @@ -102,7 +102,7 @@ int shrinkSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int factorx, int fac int shrinkSurfaceY(SDL_Surface * src, SDL_Surface * dst, int factorx, int factory) { - int x, y, dx, dy, sgap, dgap, a; + int x, y, dx, dy, /*sgap, */dgap, a; int n_average; Uint8 *sp, *osp, *oosp; Uint8 *dp; @@ -118,7 +118,7 @@ int shrinkSurfaceY(SDL_Surface * src, SDL_Surface * dst, int factorx, int factor * Scan destination */ sp = (Uint8 *) src->pixels; - sgap = src->pitch - src->w; + //sgap = src->pitch - src->w; dp = (Uint8 *) dst->pixels; dgap = dst->pitch - dst->w; @@ -640,7 +640,7 @@ void transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, void transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos) { - int x, y, dx, dy, xd, yd, sdx, sdy, ax, ay, sw, sh; + int x, y, dx, dy, xd, yd, sdx, sdy, ax, ay/*, sw, sh*/; tColorY *pc, *sp; int gap; @@ -651,8 +651,8 @@ void transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int yd = ((src->h - dst->h) << 15); ax = (cx << 16) - (icos * cx); ay = (cy << 16) - (isin * cx); - sw = src->w - 1; - sh = src->h - 1; + //sw = src->w - 1; + //sh = src->h - 1; pc = (tColorY*)dst->pixels; gap = dst->pitch - dst->w; /* diff --git a/SDL_rotozoom.h b/src/SDL_rotozoom.h similarity index 100% rename from SDL_rotozoom.h rename to src/SDL_rotozoom.h diff --git a/animation.c b/src/animation.cc similarity index 100% rename from animation.c rename to src/animation.cc diff --git a/animation.h b/src/animation.h similarity index 100% rename from animation.h rename to src/animation.h diff --git a/archive.cc b/src/archive.cc similarity index 81% rename from archive.cc rename to src/archive.cc index 5546173..962a950 100644 --- a/archive.cc +++ b/src/archive.cc @@ -21,12 +21,13 @@ * **/ +#include "tennix.h" + #include #include #include #include -#include #include #include #include @@ -35,26 +36,46 @@ #include -#include "archive.hh" +#include "archive.h" + +TennixArchive::TennixArchive() + : fp(NULL) + , header() + , items(NULL) + , blobs(NULL) + , offset(0) + , current_item(0) + , building(1) +{ + strcpy(header.header, TENNIX_ARCHIVE_HEADER); + header.items = 0; +} TennixArchive::TennixArchive(const char* filename, const char* fallback) + : fp(NULL) + , header() + , items(NULL) + , blobs(NULL) + , offset(0) + , current_item(0) + , building(0) { fp = fopen(filename, "rb"); if (fp == NULL && fallback != NULL) { fp = fopen(fallback, "rb"); } - assert(fp != NULL); + tnx_assert(fp != NULL); offset = sizeof(TennixArchiveHeader)*fread(&(header), sizeof(TennixArchiveHeader), 1, fp); - assert(offset == sizeof(TennixArchiveHeader)); - assert(strncmp(header.header, TENNIX_ARCHIVE_HEADER, TENNIX_ARCHIVE_HEADER_LEN) == 0); - assert(header.versionmajor == TENNIX_ARCHIVE_VERSIONMAJOR); - assert(header.versionminor == TENNIX_ARCHIVE_VERSIONMINOR); + tnx_assert(offset == sizeof(TennixArchiveHeader)); + tnx_assert(strncmp(header.header, TENNIX_ARCHIVE_HEADER, TENNIX_ARCHIVE_HEADER_LEN) == 0); + tnx_assert(header.versionmajor == TENNIX_ARCHIVE_VERSIONMAJOR); + tnx_assert(header.versionminor == TENNIX_ARCHIVE_VERSIONMINOR); items = (TennixArchiveItem*)calloc(header.items, sizeof(TennixArchiveItem)); - assert(items != NULL); + tnx_assert(items != NULL); offset += sizeof(TennixArchiveItem)*fread(items, sizeof(TennixArchiveItem), header.items, fp); - assert(offset == sizeof(TennixArchiveHeader) + header.items*sizeof(TennixArchiveItem)); + tnx_assert(offset == sizeof(TennixArchiveHeader) + header.items*sizeof(TennixArchiveItem)); xormem((char*)(items), header.items*sizeof(TennixArchiveItem), header.key); @@ -63,10 +84,6 @@ TennixArchive::TennixArchive(const char* filename, const char* fallback) items[i].offset = ntohl(items[i].offset); items[i].length = ntohl(items[i].length); } - - current_item = 0; - - building = 0; } std::ostream& @@ -116,7 +133,7 @@ TennixArchive::getItemBytes() /* the last char is a null character, so this works for strings, too */ data[size]='\0'; fseek(fp, items[current_item].offset, SEEK_SET); - assert(fread(data, size, 1, fp) == 1); + tnx_assert(fread(data, size, 1, fp) == 1); xormem(data, size, items[current_item].key); return data; } @@ -158,7 +175,7 @@ TennixArchive::buildFile(char* filename) memsize = (size_t*)calloc(header.items, sizeof(size_t)); fp = fopen(filename, "wb"); - assert(fp != NULL); + tnx_assert(fp != NULL); offset += sizeof(TennixArchiveHeader) + header.items*sizeof(TennixArchiveItem); @@ -167,9 +184,7 @@ TennixArchive::buildFile(char* filename) header.key = (0xaa + 0x77*header.items*3) % 0xff; - fprintf(stderr, "Packing: "); for (int i=0; i +#include "tennix.h" + #include #include #include #include -#include "archive.hh" +#include "archive.h" int main(int argc, char* argv[]) { @@ -37,7 +38,6 @@ int main(int argc, char* argv[]) const char* filename; char *bn = (char*)basename(argv[0]); int len, i; - struct stat st; if(strcmp(bn, "archive") == 0) { if (argc < 2) { @@ -48,26 +48,26 @@ int main(int argc, char* argv[]) exit(EXIT_FAILURE); } - if (stat(argv[1], &st) != -1) { - fprintf(stderr, "File %s already exists. Aborting.\n", argv[1]); + if (strcmp(".tnx", argv[1] + strlen(argv[1]) - 4) != 0) { + fprintf(stderr, "Wrong file extension: %s\n", argv[1]); exit(EXIT_FAILURE); } - tnxar = new TennixArchive(); + TennixArchive archive; - fprintf(stderr, "Creating %s with %d files\n", argv[1], argc-2); + //fprintf(stderr, "Creating %s with %d files\n", argv[1], argc-2); for (i=2; iappendItem((char*)basename(argv[i]), data, len); + char *filename = strdup(basename(argv[i])); + archive.appendItem(filename, data, len); } - tnxar->buildFile(argv[1]); - delete tnxar; + archive.buildFile(argv[1]); } else if(strcmp(bn, "dump") == 0) { if (argc < 2) { fprintf(stderr, "Usage: %s archive.tnx\n", bn); @@ -90,7 +90,7 @@ int main(int argc, char* argv[]) fprintf(stderr, " (%d bytes)", len); fp = fopen(filename, "wb"); fputc('.', stderr); - assert(fwrite(data, len, 1, fp) == 1); + tnx_assert(fwrite(data, len, 1, fp) == 1); fputc('.', stderr); fclose(fp); fprintf(stderr, ".OK\n"); @@ -106,7 +106,7 @@ int main(int argc, char* argv[]) fprintf(stderr, " (%d bytes)", len); fp = fopen(filename, "wb"); fputc('.', stderr); - assert(fwrite(data, len, 1, fp) == 1); + tnx_assert(fwrite(data, len, 1, fp) == 1); fputc('.', stderr); fclose(fp); fprintf(stderr, ".OK\n"); diff --git a/credits.h b/src/credits.h similarity index 97% rename from credits.h rename to src/credits.h index 2c646ed..39557dc 100644 --- a/credits.h +++ b/src/credits.h @@ -29,7 +29,7 @@ const char* credits_text[] = { "Tennix Classic Championship Tour 2011", - "Version " VERSION " (2011-02-10)", + "Version " VERSION " (2013-07-28)", CREDITS_EMPTY_TEXT, "Code, graphics and idea by", "Thomas Perl (thp.io)", diff --git a/game.c b/src/game.cc similarity index 97% rename from game.c rename to src/game.cc index 11aa799..9b0e73d 100644 --- a/game.c +++ b/src/game.cc @@ -24,7 +24,6 @@ #include #include #include -#include #include #include "tennix.h" @@ -76,12 +75,6 @@ int gamestate_save(GameState* s, const char* filename) InputDevice* input_devices[MAXPLAYERS]; int i, result = 0; FILE* fp = NULL; -#ifndef WIN32 - char tmp[MAXPATHLEN]; - - assert(getcwd(tmp, MAXPATHLEN) == tmp); - assert(chdir(getenv("HOME")) == 0); -#endif /** * Process-specific data (pointers to data @@ -116,10 +109,6 @@ int gamestate_save(GameState* s, const char* filename) fclose(fp); -#ifndef WIN32 - assert(chdir(tmp) == 0); -#endif - return result; } @@ -128,12 +117,6 @@ GameState* gamestate_load(const char* filename) { FILE* fp; GameState* s = NULL; -#ifndef WIN32 - char tmp[MAXPATHLEN]; - - assert(getcwd(tmp, MAXPATHLEN) == tmp); - assert(chdir(getenv("HOME")) == 0); -#endif fp = fopen(filename, "r"); @@ -151,10 +134,6 @@ GameState* gamestate_load(const char* filename) fclose(fp); } -#ifndef WIN32 - assert(chdir(tmp) == 0); -#endif - return s; } @@ -165,9 +144,11 @@ void gameloop(GameState *s, TennixNet* c) { Uint32 dt = GAME_TICKS; Uint32 diff; Uint32 accumulator = 0; +#ifdef HAVE_SDL_NET + int i = 0; +#endif /* HAVE_SDL_NET */ bool quit = false; int p; - int i=0; RenderState r = { SOUND_EVENT_NONE, REFEREE_COUNT, @@ -214,12 +195,14 @@ void gameloop(GameState *s, TennixNet* c) { while( accumulator >= dt) { step(s); +#ifdef HAVE_SDL_NET network_receive(c); network_get_gamestate(c, s); if ((i++) % 10 == 0) { network_send_state(c, s); } +#endif /* HAVE_SDL_NET */ quit = handle_input(s, c); accumulator -= dt; @@ -352,7 +335,7 @@ void step(GameState* s) { s->referee = REFEREE_PLAYER2; break; default: - assert(0); + tnx_assert(0); break; } s->score_time = 0; @@ -389,7 +372,7 @@ void step(GameState* s) { s->ball.move_z = 1.1*PLAYER(s, p).power/PLAYER_POWER_MAX; break; default: - assert(false); + tnx_assert(false); break; } s->ball.move_y = get_move_y( s, p); @@ -406,14 +389,16 @@ void step(GameState* s) { } bool handle_input(GameState* s, TennixNet* c) { - static NetworkGameState tmp; - static NetworkInputData net_input; Uint8* keys = NULL; int p; SDL_PumpEvents(); keys = SDL_GetKeyState(NULL); +#ifdef HAVE_SDL_NET + static NetworkGameState tmp; + static NetworkInputData net_input; + if (keys['1']) { net_serialize_gamestate(s, &tmp); } else if (keys['2']) { @@ -421,17 +406,22 @@ bool handle_input(GameState* s, TennixNet* c) { } network_get_input(c, &net_input); +#endif /* HAVE_SDL_NET */ if (s->winner == WINNER_NONE) { for (p=1; p<=MAXPLAYERS; p++) { if( PLAYER(s, p).type == PLAYER_TYPE_HUMAN) { +#ifdef HAVE_SDL_NET if (PLAYER(s, p).input->type == INPUT_TYPE_NETWORK) { memcpy(&(PLAYER(s, p).input->net), &net_input, sizeof(NetworkInputData)); } +#endif /* HAVE_SDL_NET */ input_human(s, p); +#ifdef HAVE_SDL_NET if (PLAYER(s, p).input->type != INPUT_TYPE_NETWORK) { network_send_input(c, &(PLAYER(s, p).input->net)); } +#endif /* HAVE_SDL_NET */ } else { input_ai(s, p); } @@ -450,7 +440,7 @@ bool handle_input(GameState* s, TennixNet* c) { } void render(const GameState* s, RenderState* r) { - int x, y, b; + int x, y; unsigned int i; float zoom; float rotate; @@ -571,14 +561,6 @@ void render(const GameState* s, RenderState* r) { rectangle(10, HEIGHT-30, (int)(PLAYER(s, 1).power), 10, 200, 200, 200); rectangle(WIDTH-PLAYER_POWER_MAX-10, HEIGHT-30, (int)(PLAYER(s, 2).power), 10, 200, 200, 200); - if( s->ball.move_x > 0) { - b = (time/100)%BALL_STATES; - } else if( s->ball.move_x < 0) { - b = BALL_STATES-1-(time/100)%BALL_STATES; - } else { - b = 0; - } - rotate = 0.0; zoom = fmaxf(0.5, fminf(1.0, (float)(30.-(s->ball.z))/10.)); show_image_rotozoom(GR_SHADOW, s->ball.x, s->ball.y+3, rotate, zoom); @@ -805,7 +787,7 @@ int score_game(GameState* s) { } /* we cannot be in an "impossibly high" set */ - assert(s->current_set < SETS_TO_WIN*2-1); + tnx_assert(s->current_set < SETS_TO_WIN*2-1); winner->game++; s->ec_game++; diff --git a/game.h b/src/game.h similarity index 100% rename from game.h rename to src/game.h diff --git a/graphics.cc b/src/graphics.cc similarity index 97% rename from graphics.cc rename to src/graphics.cc index 49937a8..9789600 100644 --- a/graphics.cc +++ b/src/graphics.cc @@ -25,14 +25,12 @@ #include #include #include -#include #include #include -#include #include "tennix.h" #include "graphics.h" -#include "archive.hh" +#include "archive.h" #include "sound.h" #include "SDL_rotozoom.h" @@ -151,16 +149,16 @@ void init_graphics(TennixArchive& tnxar) { /* Load fonts from resource file */ for (i=0; ihead = NULL; @@ -244,8 +242,8 @@ void freelist_append(FreeList* list, const char* data) { FreeListItem* new_item = (FreeListItem*)malloc(sizeof(FreeListItem)); - assert(list != NULL); - assert(data != NULL); + tnx_assert(list != NULL); + tnx_assert(data != NULL); new_item->data = data; @@ -258,7 +256,7 @@ void freelist_free_all(FreeList* list) { FreeListItem* next; - assert(list != NULL); + tnx_assert(list != NULL); while (list->head != NULL) { /* Remove one item from the head of the list */ @@ -287,7 +285,7 @@ int get_sprite_width( image_id id, int items) { void show_sprite( image_id id, int pos, int items, int x_offset, int y_offset, int opacity) { - assert(id < GR_COUNT); + tnx_assert(id < GR_COUNT); SDL_SetAlpha(images[id].data, SDL_SRCALPHA | SDL_RLEACCEL, opacity); blit_surface(images[id].data, x_offset, y_offset, pos, items); } @@ -297,7 +295,7 @@ void show_image_rotozoom(image_id id, int x, int y, float rotate, float zoom) SDL_Surface* tmp; SDL_Rect src, dst; - assert(id < GR_COUNT); + tnx_assert(id < GR_COUNT); tmp = rotozoomSurface(images[id].data, rotate, zoom, SMOOTHING_OFF); @@ -591,11 +589,11 @@ SDL_Surface* font_render_surface(font_id id, const char* text, Uint8 r, color.g = g; color.b = b; - assert(id < FONT_COUNT); + tnx_assert(id < FONT_COUNT); result = TTF_RenderText_Blended(fonts[id].data, text, color); - assert(result != NULL); + tnx_assert(result != NULL); return result; } @@ -617,7 +615,7 @@ void blit_surface(SDL_Surface* surface, int x, int y, int pos, int count) SDL_Surface* get_surface(image_id id) { - assert(id < GR_COUNT); + tnx_assert(id < GR_COUNT); return images[id].data; } @@ -632,7 +630,7 @@ void font_draw_string_color(font_id id, const char* s, int x_offset, int y_offse int font_get_string_width(font_id id, const char* s) { int w, h; - assert(id < FONT_COUNT); + tnx_assert(id < FONT_COUNT); if (TTF_SizeText(fonts[id].data, s, &w, &h) != 0) { return 0; @@ -642,7 +640,7 @@ int font_get_string_width(font_id id, const char* s) { } int font_get_height(font_id id) { - assert(id < FONT_COUNT); + tnx_assert(id < FONT_COUNT); return TTF_FontHeight(fonts[id].data); } diff --git a/graphics.h b/src/graphics.h similarity index 99% rename from graphics.h rename to src/graphics.h index c95f85f..25f4c77 100644 --- a/graphics.h +++ b/src/graphics.h @@ -24,7 +24,7 @@ #ifndef __GRAPHICS_H #define __GRAPHICS_H -#include "archive.hh" +#include "archive.h" #include "tennix.h" #include "SDL_image.h" diff --git a/input.c b/src/input.cc similarity index 82% rename from input.c rename to src/input.cc index ef2c175..3eb9d02 100644 --- a/input.c +++ b/src/input.cc @@ -28,12 +28,13 @@ #include "game.h" #include "input.h" #include "util.h" -#include "archive.hh" +#include "archive.h" + static InputDevice devices[MAX_INPUT_DEVICES]; static int devices_count; -#ifdef TENNIX_PYTHON +#ifdef HAVE_PYTHON #include "tennixpy.h" #endif @@ -43,7 +44,6 @@ void init_input(TennixArchive& tnxar) SDL_JoystickEventState(SDL_ENABLE); -#ifndef MAEMO /* keyboard presets */ devices[devices_count].type = INPUT_TYPE_KEYBOARD; devices[devices_count].up_key = 'w'; @@ -67,7 +67,6 @@ void init_input(TennixArchive& tnxar) devices[devices_count].exclusive_to_player = 2; strcpy(devices[devices_count].name, "Keyboard (OL/KIJ)"); devices_count++; -#endif /* keyboard presets */ devices[devices_count].type = INPUT_TYPE_KEYBOARD; @@ -76,15 +75,8 @@ void init_input(TennixArchive& tnxar) devices[devices_count].input_keys[INPUT_KEY_HIT]= SDLK_SPACE; devices[devices_count].input_keys[INPUT_KEY_TOPSPIN] = SDLK_LCTRL; devices[devices_count].input_keys[INPUT_KEY_SMASH] = SDLK_LALT; -#ifdef MAEMO - devices[devices_count].icon = GR_INPUT_MAEMO_DPAD; - strcpy(devices[devices_count].name, "D-Pad"); - devices[devices_count].input_keys[INPUT_KEY_HIT]= SDLK_RETURN; - /* FIXME: No TOPSPIN and SMASH keys on Maemo yet with d-pad */ -#else devices[devices_count].icon = GR_INPUT_KEYBOARD_ARROWS; strcpy(devices[devices_count].name, "Keyboard (arrows)"); -#endif devices_count++; /* mouse */ @@ -92,13 +84,8 @@ void init_input(TennixArchive& tnxar) devices[devices_count].input_keys[INPUT_KEY_HIT]= SDL_BUTTON(1); devices[devices_count].input_keys[INPUT_KEY_TOPSPIN] = SDL_BUTTON(2); devices[devices_count].input_keys[INPUT_KEY_SMASH] = SDL_BUTTON(3); -#ifdef MAEMO - devices[devices_count].icon = GR_INPUT_TOUCHSCREEN; - strcpy(devices[devices_count].name, "Touchscreen"); -#else devices[devices_count].icon = GR_INPUT_MOUSE; strcpy(devices[devices_count].name, "Mouse"); -#endif devices_count++; /* network peer */ @@ -122,7 +109,7 @@ void init_input(TennixArchive& tnxar) devices_count++; } -#ifdef TENNIX_PYTHON +#ifdef HAVE_PYTHON /* This will init Python and load all available bots */ tennixpy_init(tnxar); #endif @@ -137,14 +124,14 @@ void uninit_input() for (i=0; i= min && v < max); + tnx_assert(v >= min && v < max); return (Uint8)((1U<<7) * (v-min) / (max-min)); } @@ -165,7 +152,7 @@ input_unpack_axis(Uint8 v) { static const float min = -1.2; static const float max = 1.2; - assert(v < (1U<<7)); + tnx_assert(v < (1U<<7)); return v * (max-min) / (1U<<7) + min; } @@ -183,9 +170,9 @@ void input_device_join_game(InputDevice* device, void* gamestate, int player_id) return; } fprintf(stderr, "Input Device %s joins the game\n", device->name); -#ifdef TENNIX_PYTHON +#ifdef HAVE_PYTHON if (device->type == INPUT_TYPE_AI_PYTHON) { - device->py_bot = tennixpy_create_bot(device->py_bot_class, (GameState*)gamestate, player_id); + tennixpy_create_bot(device, (GameState*)gamestate, player_id); } #endif } @@ -196,10 +183,9 @@ void input_device_part_game(InputDevice* device) /* player is a c-style bot with no device attached */ return; } -#ifdef TENNIX_PYTHON +#ifdef HAVE_PYTHON if (device->type == INPUT_TYPE_AI_PYTHON) { - tennixpy_destroy_bot(device->py_bot); - device->py_bot = NULL; + tennixpy_destroy_bot(device); } #endif fprintf(stderr, "Input Device %s leaves the game\n", device->name); @@ -212,7 +198,7 @@ const char* input_device_get_name(InputDevice* d) float input_device_get_axis(InputDevice* d, unsigned const char axis) { Uint8 *keystate; - Uint8 mb; + //Uint8 mb; Uint8 net_value; float result = 0.0; @@ -232,7 +218,7 @@ float input_device_get_axis(InputDevice* d, unsigned const char axis) { result = JOYSTICK_PERCENTIZE(SDL_JoystickGetAxis(d->joystick, 1+d->y_axis*2)); } } else if (d->type == INPUT_TYPE_MOUSE) { - mb = SDL_GetMouseState(&d->mx, &d->my); + //mb = SDL_GetMouseState(&d->mx, &d->my); if (axis == INPUT_AXIS_X) { /* Not x-movement yet (PLAYER_MOVE_X is not defined!) */ /*if (fabsf(d->mx - d->player_x) > PLAYER_MOVE_X) { @@ -251,9 +237,9 @@ float input_device_get_axis(InputDevice* d, unsigned const char axis) { } } } -#ifdef TENNIX_PYTHON +#ifdef HAVE_PYTHON } else if (d->type == INPUT_TYPE_AI_PYTHON) { - result = tennixpy_bot_get_axis(d->py_bot, axis); + result = tennixpy_bot_get_axis(d, axis); #endif } else if (d->type == INPUT_TYPE_NETWORK) { if (axis == INPUT_AXIS_X) { @@ -262,7 +248,7 @@ float input_device_get_axis(InputDevice* d, unsigned const char axis) { result = input_unpack_axis(d->net.y); } } else { - assert(0/*unimplemented*/); + tnx_assert(0/*unimplemented*/); } net_value = input_pack_axis(result); @@ -287,14 +273,14 @@ char input_device_get_key(InputDevice* d, unsigned const char key) { } else if (d->type == INPUT_TYPE_MOUSE) { mb = SDL_GetMouseState(NULL, NULL); result = (mb & d->input_keys[key]) != 0; -#ifdef TENNIX_PYTHON +#ifdef HAVE_PYTHON } else if (d->type == INPUT_TYPE_AI_PYTHON) { - result = tennixpy_bot_get_key(d->py_bot, key); + result = tennixpy_bot_get_key(d, key); #endif } else if (d->type == INPUT_TYPE_NETWORK) { result = (d->net.keys & (1< -#endif - #define JOYSTICK_PERCENTIZE(x) ((float)(x)/(float)(32768)) #define MAX_INPUT_DEVICES 16 @@ -45,7 +41,7 @@ enum { INPUT_TYPE_JOYSTICK, INPUT_TYPE_MOUSE, INPUT_TYPE_NETWORK, -#ifdef TENNIX_PYTHON +#ifdef HAVE_PYTHON INPUT_TYPE_AI_PYTHON, #endif INPUT_TYPE_MAX @@ -98,11 +94,8 @@ typedef struct { /* Network-specific items */ NetworkInputData net; -#ifdef TENNIX_PYTHON - /* Python-specific items */ - PyObject* py_bot_class; - PyObject* py_bot; -#endif + /* Plugin-specific data */ + void *user_data; /* The picture for this input device */ image_id icon; @@ -114,9 +107,7 @@ typedef struct { void init_input(TennixArchive& tnxar); void uninit_input(); -#ifdef TENNIX_PYTHON -void input_add_python_bot(PyObject* pyclass); -#endif +InputDevice *input_add_device(); InputDevice* find_input_devices(unsigned int*); diff --git a/locations.h b/src/locations.h similarity index 100% rename from locations.h rename to src/locations.h diff --git a/network.c b/src/network.cc similarity index 99% rename from network.c rename to src/network.cc index e860230..5538593 100644 --- a/network.c +++ b/src/network.cc @@ -21,6 +21,10 @@ * **/ +#include "config.h" + +#ifdef HAVE_SDL_NET + #include "game.h" #include "network.h" @@ -271,3 +275,4 @@ net_unserialize_gamestate(NetworkGameState* src, GameState* dest) dest->status_message = src->status_message; } +#endif /* HAVE_SDL_NET */ diff --git a/network.h b/src/network.h similarity index 98% rename from network.h rename to src/network.h index 6110faf..7e3331b 100644 --- a/network.h +++ b/src/network.h @@ -24,10 +24,14 @@ #ifndef __NETWORK_H #define __NETWORK_H +#include "config.h" + #include "game.h" #include "input.h" +#ifdef HAVE_SDL_NET #include +#endif /* Vanity ports "STNX" and "MTNX" */ #define TENNIXNET_PORT_SLAVE 7869 diff --git a/sound.cc b/src/sound.cc similarity index 99% rename from sound.cc rename to src/sound.cc index f36c620..96f64bc 100644 --- a/sound.cc +++ b/src/sound.cc @@ -23,7 +23,7 @@ #include "tennix.h" #include "sound.h" -#include "archive.hh" +#include "archive.h" #include "graphics.h" #include diff --git a/sound.h b/src/sound.h similarity index 99% rename from sound.h rename to src/sound.h index 87b765a..6ea3cf6 100644 --- a/sound.h +++ b/src/sound.h @@ -24,7 +24,7 @@ #ifndef __SOUND_H #define __SOUND_H -#include "archive.hh" +#include "archive.h" #include "SDL_mixer.h" diff --git a/tennix.cc b/src/tennix.cc similarity index 94% rename from tennix.cc rename to src/tennix.cc index 8f5f730..9090d43 100644 --- a/tennix.cc +++ b/src/tennix.cc @@ -27,12 +27,8 @@ #include #include -#ifdef WIN32 -#include -#endif - #include "tennix.h" -#include "archive.hh" +#include "archive.h" #include "game.h" #include "graphics.h" #include "sound.h" @@ -45,47 +41,7 @@ SDL_Surface *screen; -#ifdef WIN32 - -/* IDs from the resource file */ -#define START_BUTTON 1 -#define CHECKBOX_FULLSCREEN 2 -#define QUIT_BUTTON 3 - -BOOL CALLBACK ConfigDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - static int checkbox_is_checked; - - switch (uMsg) { - case WM_CLOSE: - EndDialog(hwndDlg, IDCANCEL); - break; - case WM_COMMAND: - switch (wParam) { - case START_BUTTON: - EndDialog(hwndDlg, (checkbox_is_checked)?(IDYES):(IDNO)); - break; - case QUIT_BUTTON: - EndDialog(hwndDlg, IDCANCEL); - break; - case CHECKBOX_FULLSCREEN: - checkbox_is_checked ^= 1; - break; - } - break; - default: - return FALSE; - } - return TRUE; -} -#endif - -#ifdef WIN32 -int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, - LPSTR lpCmdLine, int nCmdShow) { -#else int main( int argc, char** argv) { -#endif int i, slide, slide_direction; unsigned int x; Uint32 ticks; @@ -108,8 +64,10 @@ int main( int argc, char** argv) { AnimationState *intro_playback; float wiggle; TennixNet* connection = NULL; +#ifdef HAVE_SDL_NET char* net_host = NULL; bool net_master = false; +#endif /* HAVE_SDL_NET */ TennixArchive* tnxar = NULL; MenuButton btn_back = { @@ -161,25 +119,6 @@ int main( int argc, char** argv) { Uint32 ft, frames; /* frame timer and frames */ #endif -#if defined(MAEMO) || defined(MACOSX) - sdl_flags |= SDL_FULLSCREEN; -#endif - -#ifdef WIN32 - int mb_result; - mb_result = DialogBox(hInstance, "CONFIG", 0, (DLGPROC)ConfigDialogProc); - - switch (mb_result) { - case IDYES: - sdl_flags |= SDL_FULLSCREEN; - break; - case IDCANCEL: - return 0; - break; - default: - break; - } -#else fprintf(stderr, "Tennix Classic Championship Tour 2011 (v" VERSION ")\n" COPYRIGHT "\n" URL "\n\n"); i = 1; @@ -200,6 +139,7 @@ int main( int argc, char** argv) { else if (OPTION_SET("--benchmark", "-b")) { benchmark = true; } +#ifdef HAVE_SDL_NET else if (OPTION_SET("--slave", "-s")) { net_host = OPTION_VALUE; if (OPTION_VALUE != NULL) { @@ -222,6 +162,7 @@ int main( int argc, char** argv) { break; } } +#endif /* HAVE_SDL_NET */ else { fprintf(stderr, "Unknown option: %s\n", argv[i]); do_help = true; @@ -234,13 +175,14 @@ int main( int argc, char** argv) { " Where [OPTIONS] are zero or more of the following:\n\n" " [--fullscreen|-f] Fullscreen mode\n" " [--benchmark|-b] Run in benchmark/attract mode\n" +#ifdef HAVE_SDL_NET " [--master|-m ] Network play as master\n" " [--slave|-s ] Network play as slave\n" +#endif /* HAVE_SDL_NET */ " [--help|-h] Show help information\n\n" " See tennix(6) for details.\n", argv[0]); return 0; } -#endif if (benchmark) { srand(100); @@ -267,12 +209,16 @@ int main( int argc, char** argv) { init_graphics(*tnxar); init_sound(*tnxar); init_input(*tnxar); +#ifdef HAVE_SDL_NET init_network(); +#endif /* HAVE_SDL_NET */ delete tnxar; +#ifdef HAVE_SDL_NET if (net_host != NULL) { connection = network_connect(net_host, net_master); } +#endif /* HAVE_SDL_NET */ menu_button_init(&btn_back); menu_button_init(&btn_start); @@ -409,11 +355,7 @@ int main( int argc, char** argv) { /* FIXME - this should not be written here, but taken from the input devices */ btn_player1.text = "Keyboard (arrows)"; btn_player2.text = "Carl Van Court"; -#ifdef MAEMO - PLAYER(prepared_game, 1).input_device_index = 0; -#else PLAYER(prepared_game, 1).input_device_index = 2; -#endif PLAYER(prepared_game, 1).type = PLAYER_TYPE_HUMAN; PLAYER(prepared_game, 1).input = &(input_devices[PLAYER(prepared_game, 1).input_device_index]); location_info_visible = false; @@ -619,7 +561,6 @@ int main( int argc, char** argv) { /* No menu screen - no hovering. */ btn_hovering = 0; } -#ifndef MAEMO /* On Maemo, we cannot really "hover" (touchscreen!) */ if (btn_hovering_old != btn_hovering && btn_hovering != 0) { #ifdef HAVE_VOICE_FILES if (btn_hovering == MENU_QUIT) { @@ -630,10 +571,9 @@ int main( int argc, char** argv) { play_sample(SOUND_MOUSEOVER); } #else - /*play_sample(SOUND_MOUSEOVER);*/ + play_sample(SOUND_MOUSEOVER); #endif } -#endif if( keys[SDLK_ESCAPE] || keys['q']) { /* FIXME: do the state thingie! */ @@ -644,11 +584,9 @@ int main( int argc, char** argv) { SDL_WM_ToggleFullScreen( screen); } -#ifndef MAEMO /* No mouse cursor on Maemo (we have a touchscreen) */ if (state == MENU_STATE_MAINMENU || state == MENU_STATE_OPTIONS || state == MENU_STATE_LOCATION) { show_image(GR_CURSOR, mx-2, my-1, 255); } -#endif /* Draw the "real" mouse coordinates */ /*rectangle(mx-1, my-1, 2, 2, 255, 255, 255);*/ @@ -800,7 +738,9 @@ int main( int argc, char** argv) { uninit_graphics(); uninit_input(); +#ifdef HAVE_SDL_NET uninit_network(); +#endif /* HAVE_SDL_NET */ SDL_Quit(); return 0; diff --git a/tennix.h b/src/tennix.h similarity index 85% rename from tennix.h rename to src/tennix.h index 0fb30f4..a547aee 100644 --- a/tennix.h +++ b/src/tennix.h @@ -24,10 +24,22 @@ #ifndef __TENNIX_H #define __TENNIX_H +#include "config.h" + +#define tnx_assert(x) do { \ + if (!(x)) { \ + fprintf(stderr, "Assertion fail: %s\n", #x); \ + exit(1); \ + } \ +} while(0) + #include #include + +#ifdef HAVE_SDL_NET #include +#endif typedef struct { unsigned char x; @@ -35,7 +47,7 @@ typedef struct { unsigned char keys; /* bitfield (0 = key pressed, 1 = not pressed) */ } NetworkInputData; - +#ifdef HAVE_SDL_NET typedef struct { UDPsocket send_socket; UDPsocket recv_input_socket; @@ -56,30 +68,16 @@ typedef struct { bool master; } TennixNet; - -#ifdef DELUXE_EDITION -# define HAVE_VOICE_FILES -# define NONFREE_LOCATIONS -#endif - -#if defined(__MACH__) && defined(__APPLE__) -# define MACOSX -#endif +#else +typedef void TennixNet; +#endif /* HAVE_SDL_NET */ #define ARCHIVE_FILE "tennix.tnx" -#ifdef MACOSX -# define ARCHIVE_FILE_INSTALLED "Tennix.app/Contents/Resources/" ARCHIVE_FILE -#else -# define ARCHIVE_FILE_INSTALLED "/" PREFIX "/share/games/tennix/" ARCHIVE_FILE -#endif +#define ARCHIVE_FILE_INSTALLED "/" PREFIX "/share/tennix/" ARCHIVE_FILE -#ifdef WIN32 -# define GAMESTATE_FILE "current_match-" VERSION ".tennix" -#else -# define GAMESTATE_FILE ".tennix-current_match-" VERSION -#endif +#define GAMESTATE_FILE ".tennix-current_match-" VERSION -#define COPYRIGHT "Copyright 2003, 2007-2011 Thomas Perl" +#define COPYRIGHT "Copyright 2003, 2007-2011, 2013 Thomas Perl" #define URL "http://icculus.org/tennix/" #define WIDTH 640 @@ -137,8 +135,6 @@ enum { MENU_STATE_QUIT }; -/* Comment the following #define to disable FPS limiting */ -/*#define ENABLE_FPS_LIMIT*/ #define DEFAULT_FPS 33 diff --git a/tennixpy.cc b/src/tennixpy.cc similarity index 79% rename from tennixpy.cc rename to src/tennixpy.cc index 7f2c87e..8aea008 100644 --- a/tennixpy.cc +++ b/src/tennixpy.cc @@ -22,14 +22,29 @@ * **/ -#ifdef TENNIX_PYTHON +#include "config.h" + +#ifdef HAVE_PYTHON #include #include "game.h" -#include "archive.hh" +#include "archive.h" #include "tennixpy.h" +PyObject* tennixpy_register_bot(PyObject* self, PyObject* bot_class); +PyObject* tennixpy_get_ball_pos(PyObject* self, PyObject* gamestate); +PyObject* tennixpy_get_power(PyObject* self, PyObject* args); +PyObject* tennixpy_get_position(PyObject* self, PyObject* args); +PyObject* tennixpy_create_module(void); + + +struct InputDevicePython { + PyObject* py_bot_class; + PyObject* py_bot; +}; + + /* This saves our current Python thread state */ PyThreadState* _py_save; @@ -53,8 +68,12 @@ PyObject* tennixpy_create_module(void) return module; } -PyObject* tennixpy_create_bot(PyObject* bot_class, GameState* s, int player_id) +void +tennixpy_create_bot(InputDevice *device, GameState *s, int player_id) { + InputDevicePython *pydevice = (InputDevicePython*)device->user_data; + PyObject *bot_class = pydevice->py_bot_class; + PyObject* o = NULL; PyObject* args; PyObject* gamestate; @@ -77,11 +96,14 @@ PyObject* tennixpy_create_bot(PyObject* bot_class, GameState* s, int player_id) } _py_save = PyEval_SaveThread(); - return o; + pydevice->py_bot = o; } -void tennixpy_destroy_bot(PyObject* bot) +void tennixpy_destroy_bot(InputDevice *device) { + InputDevicePython *pydevice = (InputDevicePython*)device->user_data; + PyObject *bot = pydevice->py_bot; + PyObject* finish_func; PyEval_RestoreThread(_py_save); finish_func = PyObject_GetAttrString(bot, "finish"); @@ -92,8 +114,11 @@ void tennixpy_destroy_bot(PyObject* bot) _py_save = PyEval_SaveThread(); } -float tennixpy_bot_get_axis(PyObject* bot, int axis) +float tennixpy_bot_get_axis(InputDevice *device, int axis) { + InputDevicePython *pydevice = (InputDevicePython*)device->user_data; + PyObject *bot = pydevice->py_bot; + PyObject* args; PyObject* get_axis_func; PyObject* r; @@ -124,8 +149,11 @@ float tennixpy_bot_get_axis(PyObject* bot, int axis) return result; } -char tennixpy_bot_get_key(PyObject* bot, int key) +char tennixpy_bot_get_key(InputDevice *device, int key) { + InputDevicePython *pydevice = (InputDevicePython*)device->user_data; + PyObject *bot = pydevice->py_bot; + PyObject* args; PyObject* get_key_func; PyObject* r; @@ -158,6 +186,29 @@ char tennixpy_bot_get_key(PyObject* bot, int key) return result; } +static void +input_add_python_bot(PyObject* bot_class) +{ + InputDevice *device = input_add_device(); + + if (device == NULL) { + fprintf(stderr, "Warning: Cannot add any more Python bots.\n"); + // We carry a ref of bot_class, so give it up here + Py_DECREF(bot_class); + return; + } + + device->type = INPUT_TYPE_AI_PYTHON; + device->icon = GR_INPUT_AI; + + InputDevicePython *pydevice = new InputDevicePython; + pydevice->py_bot_class = bot_class; + pydevice->py_bot = NULL; + device->user_data = (void*)pydevice; + tennixpy_get_bot_name(device, device->name, INPUT_DEVICE_NAME_MAX); + fprintf(stderr, " %s", device->name); +} + PyObject* tennixpy_register_bot(PyObject* self, PyObject* bot_class) { assert(self == NULL); @@ -172,8 +223,10 @@ PyObject* tennixpy_register_bot(PyObject* self, PyObject* bot_class) Py_RETURN_NONE; } -void tennixpy_get_bot_name(PyObject* bot_class, char* dest, int maxlen) +void tennixpy_get_bot_name(InputDevice *device, char* dest, int maxlen) { + InputDevicePython *pydevice = (InputDevicePython*)device->user_data; + PyObject *bot_class = pydevice->py_bot_class; PyObject *name; name = PyObject_GetAttrString(bot_class, "name"); @@ -305,11 +358,13 @@ void tennixpy_init(TennixArchive& tnxar) _py_save = PyEval_SaveThread(); } -void tennixpy_unregister_bot(PyObject* bot) +void tennixpy_unregister_bot(InputDevice *device) { + InputDevicePython *pydevice = (InputDevicePython*)device->user_data; PyEval_RestoreThread(_py_save); - Py_DECREF(bot); + Py_XDECREF(pydevice->py_bot); _py_save = PyEval_SaveThread(); + delete pydevice; } void tennixpy_uninit() @@ -322,4 +377,4 @@ void tennixpy_uninit() /*Py_Finalize();*/ } -#endif +#endif /* HAVE_PYTHON */ diff --git a/tennixpy.h b/src/tennixpy.h similarity index 56% rename from tennixpy.h rename to src/tennixpy.h index a3ab98d..2a5e463 100644 --- a/tennixpy.h +++ b/src/tennixpy.h @@ -25,31 +25,27 @@ #ifndef __TENNIXPY_H #define __TENNIXPY_H -#ifdef TENNIX_PYTHON +#include "config.h" -#include "archive.hh" +#ifdef HAVE_PYTHON -extern PyThreadState* _py_save; +#include "archive.h" +#include "input.h" -PyObject* tennixpy_register_bot(PyObject* self, PyObject* bot_class); -void tennixpy_unregister_bot(PyObject* bot); -void tennixpy_get_bot_name(PyObject* bot_class, char* dest, int maxlen); +void tennixpy_unregister_bot(InputDevice *device); +void tennixpy_get_bot_name(InputDevice *device, char *dest, int maxlen); -PyObject* tennixpy_create_bot(PyObject* bot_class, GameState* s, int player_id); -void tennixpy_destroy_bot(PyObject* bot); +void tennixpy_create_bot(InputDevice *device, GameState *s, int player_id); +void tennixpy_destroy_bot(InputDevice *device); -float tennixpy_bot_get_axis(PyObject* bot, int axis); -char tennixpy_bot_get_key(PyObject* bot, int key); - -PyObject* tennixpy_get_ball_pos(PyObject* self, PyObject* gamestate); -PyObject* tennixpy_get_power(PyObject* self, PyObject* args); -PyObject* tennixpy_get_position(PyObject* self, PyObject* args); - -PyObject* tennixpy_create_module(void); +//float tennixpy_bot_get_axis(PyObject* bot, int axis); +float tennixpy_bot_get_axis(InputDevice *device, int axis); +//char tennixpy_bot_get_key(PyObject* bot, int key); +char tennixpy_bot_get_key(InputDevice *device, int key); void tennixpy_init(TennixArchive& tnxar); void tennixpy_uninit(); -#endif +#endif /* HAVE_PYTHON */ -#endif +#endif /* __TENNIXPY_H */ diff --git a/util.c b/src/util.cc similarity index 100% rename from util.c rename to src/util.cc diff --git a/util.h b/src/util.h similarity index 75% rename from util.h rename to src/util.h index 048708c..2a3e21f 100644 --- a/util.h +++ b/src/util.h @@ -26,19 +26,4 @@ void day_night(unsigned int width, unsigned int* start, unsigned int* end); -/** - * On Maemo, we somehow don't get these defined in any of the header files, - * so we define the prototypes here - if we don't do that, bad things will - * happen. - **/ -#ifdef MAEMO -float fminf(float, float); -float fmaxf(float, float); -float fabsf(float); -float sinf(float); -float cosf(float); -#endif - - #endif - diff --git a/tennix-installer.iss.in b/tennix-installer.iss.in deleted file mode 100644 index 9adbc2c..0000000 --- a/tennix-installer.iss.in +++ /dev/null @@ -1,47 +0,0 @@ -; Inno Setup Script Template for Tennix (on Windows) -; Copyright (c) 2007 Thomas Perl -; Licensed under the same terms as Tennix iself - -[Setup] -AppName=Tennix -AppVerName=Tennix {version} -AppPublisher=Thomas Perl -AppPublisherURL=http://icculus.org/tennix/ -AppSupportURL=http://icculus.org/tennix/ -AppUpdatesURL=http://icculus.org/tennix/ -DefaultDirName={pf}\Tennix -DefaultGroupName=Tennix -LicenseFile=COPYING -OutputDir=. -OutputBaseFilename=tennix-{version}-win32-setup -Compression=lzma -SolidCompression=yes - -[Languages] -Name: "english"; MessagesFile: "compiler:Default.isl" - -[Tasks] -Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked - -[Files] -Source: "tennix.exe"; DestDir: "{app}"; Flags: ignoreversion -Source: "zlib1.dll"; DestDir: "{app}"; Flags: ignoreversion -Source: "SDL.dll"; DestDir: "{app}"; Flags: ignoreversion -Source: "SDL_image.dll"; DestDir: "{app}"; Flags: ignoreversion -Source: "SDL_mixer.dll"; DestDir: "{app}"; Flags: ignoreversion -Source: "libpng12.dll"; DestDir: "{app}"; Flags: ignoreversion -Source: "COPYING"; DestDir: "{app}"; Flags: ignoreversion -Source: "ChangeLog"; DestDir: "{app}"; Flags: ignoreversion -Source: "README.win32"; DestDir: "{app}"; Flags: ignoreversion -Source: "README"; DestDir: "{app}"; Flags: ignoreversion -; NOTE: Don't use "Flags: ignoreversion" on any shared system files - -[Icons] -Name: "{group}\Tennix"; Filename: "{app}\tennix.exe" -Name: "{group}\{cm:ProgramOnTheWeb,Tennix}"; Filename: "http://icculus.org/tennix/" -Name: "{group}\{cm:UninstallProgram,Tennix}"; Filename: "{uninstallexe}" -Name: "{commondesktop}\Tennix"; Filename: "{app}\tennix.exe"; Tasks: desktopicon - -[Run] -Filename: "{app}\tennix.exe"; Description: "{cm:LaunchProgram,Tennix}"; Flags: nowait postinstall skipifsilent - diff --git a/tennix.res b/tennix.res deleted file mode 100644 index 919e42dcf979f994dc24352ae7fc87abc837bde2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcwPel00001 literal 4924 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