diff options
67 files changed, 2248 insertions, 137 deletions
@@ -10,9 +10,12 @@ config.log config.status config.h autom4te.cache +rpm.spec stamp-h stamp-h.in stamp-h1 +tags +TAGS # These are the default patterns globally ignored by Subversion: *.o @@ -23,7 +23,7 @@ Building Chocolate Doom On a Unix system, follow the standard instructions for installing an autotools-based package: - 1. Run './configure' to initialise the package. + 1. Run './configure' to initialize the package. 2. Run 'make' to compile the package. 3. Run 'make install' to install the package. diff --git a/Makefile.am b/Makefile.am index 5de8d88c..13e8bddb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -24,9 +24,12 @@ CODEBLOCKS_FILES= \ codeblocks/textscreen.cbp DATA_FILES= \ + data/README \ data/doom.ico \ + data/doom8.ico \ data/doom.png \ data/setup.ico \ + data/setup8.ico \ data/setup.png \ data/convert-icon @@ -35,12 +38,14 @@ EXTRA_DIST= \ $(MSVC_FILES) \ $(CODEBLOCKS_FILES) \ $(DATA_FILES) \ + .lvimrc \ config.h \ CMDLINE \ HACKING \ README.OPL \ TODO \ - BUGS + BUGS \ + rpm.spec MAINTAINERCLEANFILES = $(AUX_DIST_GEN) @@ -50,6 +55,8 @@ DIST_SUBDIRS=pkg $(SUBDIRS) if HAVE_PYTHON +noinst_DATA=CMDLINE + CMDLINE : src/ ./man/docgen -p man/CMDLINE.template src/ > $@ @@ -1,48 +1,93 @@ ... * Chocolate Doom now runs on Windows Mobile/Windows CE! - * It is possible to rebind most/all of the keys that control - the menu, shortcuts, automap and weapon switching. The - main reason for this is to support the Windows CE port - and other platforms where a full keyboard may not be present. - * Memory-mapped WAD I/O is disabled by default, as it caused - various issues, including a slowdown/crash with Plutonia 2 - MAP23. It can be explicitly re-enabled using the '-mmap' - command line parameter. + * It is possible to rebind most/all of the keys that control the + menu, shortcuts, automap and weapon switching. The main + reason for this is to support the Windows CE port and other + platforms where a full keyboard may not be present. + * Chocolate Doom now includes a proper Mac OS X package; it is + no longer necessary to compile binaries for this system by + hand. The package includes a simple graphical launcher + program and can be installed simply by dragging the "Chocolate + Doom" icon to the Applications folder. * The video mode auto-adjust code will automatically choose windowed mode if no fullscreen video modes are available. - * The zone memory size is automatically reduced on systems - with a small amount of memory. - * There is now a second, small textscreen font, so that the - ENDOOM screen and setup tool can be used on low resolution - devices (eg. PDAs/embedded devices) - * The textscreen library now has a scrollable pane widget. - * Doxygen documentation was added for the textscreen library. - * The "join game" window in the setup tool now has an option - to automatically join a game on the local network. + * The zone memory size is automatically reduced on systems with + a small amount of memory. + * The "join game" window in the setup tool now has an option to + automatically join a game on the local network. + * Chocolate Doom includes some initial hacks for compiling under + SDL 1.3. + * Recent versions of SDL_mixer include rewritten MIDI code on Mac + OS X. If you are using a version of SDL_mixer with the new + code, music will now be enabled by default. + * Windows Vista and Windows 7 no longer prompt for elevated + privileges when running the setup tool (thanks hobbs and + MikeRS). + * The Windows binaries now have better looking icons (thanks + MikeRS). + * Magic values specified using the -spechit command line + parameter can now be hexadecimal. + * DOOMWADDIR/DOOMWADPATH can now specify the complete path to + IWAD files, rather than the path to the directory that contains + them. + * When recording shorttics demos, errors caused by the reduced + turning resolution are carried forward, possibly making turning + smoother. Compatibility: * The A_BossDeath behavior in v1.9 emulation mode was fixed (thanks entryway) + * The "loading" disk icon is drawn more like how it is drawn in + Vanilla Doom, also fixing a bug with chook3.wad. + * Desync on 64-bit systems with ep1-0500.lmp has (at long last) + been fixed (thanks exp(x)). + * Donut overrun emulation code imported from Prboom+ (thanks + entryway). + * The correct level name should now be shown in the automap for + pl2.wad MAP33 (thanks Janizdreg). + * In Chex Quest, the green radiation suit colormap is now used + instead of the red colormaps normally used when taking damage + or using the berserk pack. This matches Vanilla chex.exe + behavior (thanks Fuzztooth). + * Impassible glass now displays and works the same as in Vanilla, + fixing wads such as OTTAWAU.WAD (thanks Never_Again). Bugs fixed: + * Memory-mapped WAD I/O is disabled by default, as it caused + various issues, including a slowdown/crash with Plutonia 2 + MAP23. It can be explicitly re-enabled using the '-mmap' + command line parameter. * Crash when saving games due to the ~/.chocolate-doom/savegames directory not being created (thanks to everyone who reported this). - * Chocolate Doom will now under Win95/98, as the + * Chocolate Doom will now run under Win95/98, as the SetProcessAffinityMask function is looked up dynamically. * Compilation under Linux with older versions of libc will now work (the semantics for sched_setaffinity were different in older versions) * Sound clipping when using libsamplerate was improved (thanks David Flater) - * The audio buffer size is now calculated based on the sample rate, - so there is not a noticeable delay when using a lower sample - rate. - * The manpage documentation for the DOOMWADPATH variable was fixed - (thanks MikeRS). - * Compilation with FEATURE_MULTIPLAYER and FEATURE_SOUND disabled - was fixed. + * The audio buffer size is now calculated based on the sample + rate, so there is not a noticeable delay when using a lower + sample rate. + * The manpage documentation for the DOOMWADPATH variable was + fixed (thanks MikeRS). + * Compilation with FEATURE_MULTIPLAYER and FEATURE_SOUND + disabled was fixed. + * Fixed crash when using the donut special type and the joining + linedef is one sided (thanks Alexander Waldmann). + * Key settings in a configuration file that are out of range + do not cause a crash (thanks entryway). + + libtextscreen: + * There is now a second, small textscreen font, so that the + ENDOOM screen and setup tool can be used on low resolution + devices (eg. PDAs/embedded devices) + * The textscreen library now has a scrollable pane widget. Thanks + to LionsPhil for contributing code to scroll up and down using + the keyboard. + * Doxygen documentation was added for the textscreen library. 1.2.1 (2008-12-10): @@ -1,17 +1,22 @@ +Currently in progress: + +* OPL MIDI playback (see: opl-branch) +* Heretic/Hexen support (see: raven-branch) +* Strife support (see: strife-branch) + To do: -* Install packages: - - Debian/Ubuntu .deb packages, Fedora .rpm packages. - - Windows NSIS installer. - - MacOS X .dmg packages (should be universal binaries!) +* Demo hashes for regression testing of this and other ports. * File selector for chocolate-setup, so that WADs can be selected from a browser, instead of simply typing the filenames. * Multiplayer: - Master server for locating servers automatically - makes setting up public servers easier. + - Use UPnP to automatically configure port forwarding for NATted + networks. - Incorporate local LAN search into setup interface. - Multiplayer options and configuration file (server name, etc) -* Improve multiplayer startup: +* Improve multiplayer startup: - Select an IWAD automatically from the server's game type rather than all players having to specify -iwad. - Send list of WADs to load instead of all clients having to specify -file. @@ -20,16 +25,14 @@ To do: - Test on and fix for architectures where ((-2) >> 1) != -1 - Use size-specific types (eg. int32_t instead of int) - Don't make structure packing assumptions when loading levels. -* Port to every OS and architecture under the sun + - Port to every OS and architecture under the sun Crazy pie in the sky ideas: * Automatic WAD installer - download and run TCs from a list automatically (automating the current "instructions on wiki" system). -* Textscreen interface to the Compet-N database: menu driven system to +* Textscreen interface to the Compet-N database: menu driven system to automatically download and play speedruns. * DWANGO-like interface for finding players and setting up games. -* Demo hashes for regression testing of this and other ports. -* OPL emulation * Video capture mode? @@ -8,5 +8,5 @@ automake -a -c autoconf automake -./configure $@ +./configure "$@" diff --git a/configure.in b/configure.in index 0327c0c3..b097bb2f 100644 --- a/configure.in +++ b/configure.in @@ -1,5 +1,11 @@ AC_INIT(Chocolate Doom, 1.2.1, fraggle@gmail.com, chocolate-doom) +PACKAGE_SHORTDESC="Conservative Doom source port" +PACKAGE_COPYRIGHT="Copyright (C) 1993-2010" +PACKAGE_LICENSE="GNU General Public License, version 2" +PACKAGE_MAINTAINER="Simon Howard" +PACKAGE_URL="http://www.chocolate-doom.org/" + AC_CONFIG_AUX_DIR(autotools) orig_CFLAGS="$CFLAGS" @@ -80,6 +86,7 @@ AC_SDL_MAIN_WORKAROUND([ ]) AC_CHECK_TOOL(WINDRES, windres, ) +AC_CHECK_TOOL(STRIP, strip, ) # Windows CE build? @@ -115,24 +122,34 @@ AC_SUBST(SDLNET_LIBS) AC_SUBST(ac_aux_dir) +AC_SUBST(PACKAGE_SHORTDESC) +AC_SUBST(PACKAGE_COPYRIGHT) +AC_SUBST(PACKAGE_LICENSE) +AC_SUBST(PACKAGE_MAINTAINER) +AC_SUBST(PACKAGE_URL) +AC_SUBST(PACKAGE_LONGDESC) + dnl Shut up the datarootdir warnings. AC_DEFUN([AC_DATAROOTDIR_CHECKED]) AC_OUTPUT([ Makefile -wince/Makefile -textscreen/Makefile -textscreen/examples/Makefile -setup/Makefile +rpm.spec man/Makefile opl/Makefile opl/examples/Makefile -src/Makefile pcsound/Makefile pkg/Makefile -pkg/wince/GNUmakefile -src/resource.rc -src/doom-screensaver.desktop +pkg/config.make +pkg/osx/Info.plist +pkg/osx/Info-gnustep.plist +setup/Makefile setup/setup-res.rc +src/Makefile +src/doom-screensaver.desktop +src/resource.rc +textscreen/Makefile +textscreen/examples/Makefile +wince/Makefile ]) diff --git a/data/README b/data/README index 8b927335..82fac17e 100644 --- a/data/README +++ b/data/README @@ -3,3 +3,10 @@ The Chocolate Doom icon is based on an image by Chris Metcalf http://www.flickr.com/photos/laffy4k/448920776/ +The "foo8.ico" files are 8-bit depth only, while the "foo.ico" files +contain full 32-bit versions, scaled to different sizes and with proper +alpha masks (as well as the 8-bit versions). The 8-bit versions are +used when setting the icon within SDL, as SDL under Windows displays +full color icons in a very poor quality. The full-color versions are +used in the resource files. + diff --git a/data/doom.ico b/data/doom.ico Binary files differindex f55ff28f..025cb698 100644 --- a/data/doom.ico +++ b/data/doom.ico diff --git a/data/doom8.ico b/data/doom8.ico Binary files differnew file mode 100644 index 00000000..f55ff28f --- /dev/null +++ b/data/doom8.ico diff --git a/data/setup.ico b/data/setup.ico Binary files differindex 6d734a11..dae4e5ec 100644 --- a/data/setup.ico +++ b/data/setup.ico diff --git a/data/setup8.ico b/data/setup8.ico Binary files differnew file mode 100644 index 00000000..6d734a11 --- /dev/null +++ b/data/setup8.ico diff --git a/man/Makefile.am b/man/Makefile.am index d3c90f7e..698c0862 100644 --- a/man/Makefile.am +++ b/man/Makefile.am @@ -5,9 +5,9 @@ if HAVE_PYTHON man_MANS=chocolate-doom.6 \ chocolate-server.6 \ - chocolate-setup.6 \ - default.cfg.5 \ - $(PACKAGE).cfg.5 + chocolate-setup.6 \ + default.cfg.5 \ + $(PACKAGE).cfg.5 chocolate-doom.6: ../src $(MANPAGE_GEN_FILES) ./docgen -m manpage.template ../src > $@ @@ -21,5 +21,6 @@ $(PACKAGE).cfg.5: ../src extra.cfg.template endif EXTRA_DIST = $(man_MANS) $(MANPAGE_GEN_FILES) \ - wikipages + wikipages \ + CMDLINE.template diff --git a/pcsound/.gitignore b/pcsound/.gitignore index 9889f6d5..022c663e 100644 --- a/pcsound/.gitignore +++ b/pcsound/.gitignore @@ -3,4 +3,6 @@ Makefile .deps libpcsound.a *.rc +tags +TAGS diff --git a/pkg/.gitignore b/pkg/.gitignore new file mode 100644 index 00000000..a1dd1cde --- /dev/null +++ b/pkg/.gitignore @@ -0,0 +1,3 @@ +Makefile +Makefile.in +config.make diff --git a/pkg/Makefile.am b/pkg/Makefile.am index 00ab5d6f..9775fa77 100644 --- a/pkg/Makefile.am +++ b/pkg/Makefile.am @@ -1,3 +1,32 @@ -DIST_SUBDIRS=wince +OSX_FILES= \ +osx/Resources/128x128.png \ +osx/Resources/app.icns \ +osx/Resources/app.png \ +osx/Resources/wadfile.icns \ +osx/Resources/wadfile.png \ +osx/Resources/launcher.nib/classes.nib \ +osx/Resources/launcher.nib/info.nib \ +osx/Resources/launcher.nib/keyedobjects.nib \ +osx/GNUmakefile \ +osx/Info.plist.in osx/Info-gnustep.plist.in \ +osx/PkgInfo \ +osx/cp-with-libs \ +osx/main.m \ +osx/AppController.m osx/AppController.h \ +osx/Execute.m osx/Execute.h \ +osx/IWADController.m osx/IWADController.h \ +osx/IWADLocation.m osx/IWADLocation.h \ +osx/LauncherManager.m osx/LauncherManager.h + +WINCE_FILES= \ +wince/GNUmakefile \ +wince/wince-cab.cfg \ +wince/wince-cabgen + +WIN32_FILES= \ +win32/GNUmakefile \ +win32/README + +EXTRA_DIST=$(OSX_FILES) $(WINCE_FILES) $(WIN32_FILES) diff --git a/pkg/config.make.in b/pkg/config.make.in new file mode 100644 index 00000000..d8d72c60 --- /dev/null +++ b/pkg/config.make.in @@ -0,0 +1,28 @@ +# Shared file included by the makefiles used to build packages. +# This contains various information needed by the makefiles, +# and is autogenerated by configure to include various +# necessary details. + +# Tools needed: + +CC = @CC@ +STRIP = @STRIP@ + +# Package name and version number: + +PACKAGE = @PACKAGE@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_VERSION = @PACKAGE_VERSION@ + +# Documentation files to distribute with packages. + +DOC_FILES = README \ + COPYING \ + ChangeLog \ + NEWS \ + BUGS \ + CMDLINE \ + TODO + diff --git a/pkg/osx/.gitignore b/pkg/osx/.gitignore new file mode 100644 index 00000000..ca1a7908 --- /dev/null +++ b/pkg/osx/.gitignore @@ -0,0 +1,7 @@ +Info.plist +Info-gnustep.plist +launcher +*.o +*.d +*.dmg +staging diff --git a/pkg/osx/AppController.h b/pkg/osx/AppController.h new file mode 100644 index 00000000..88b59043 --- /dev/null +++ b/pkg/osx/AppController.h @@ -0,0 +1,53 @@ +/* ... */ +//----------------------------------------------------------------------------- +// +// Copyright(C) 2009 Simon Howard +// +// 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 LAUNCHER_APPCONTROLLER_H +#define LAUNCHER_APPCONTROLLER_H + +#include <AppKit/AppKit.h> + +#include "LauncherManager.h" + +@interface AppController : NSObject +{ + LauncherManager *launcherManager; + BOOL filesAdded; +} + ++ (void)initialize; + +- (id)init; +- (void)dealloc; + +- (void)awakeFromNib; + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotif; +- (BOOL)applicationShouldTerminate:(id)sender; +- (void)applicationWillTerminate:(NSNotification *)aNotif; +- (BOOL)application:(NSApplication *)application openFile:(NSString *)fileName; + +- (void)showPrefPanel:(id)sender; + +@end + +#endif + diff --git a/pkg/osx/AppController.m b/pkg/osx/AppController.m new file mode 100644 index 00000000..a26a7c9e --- /dev/null +++ b/pkg/osx/AppController.m @@ -0,0 +1,124 @@ +/* ... */ +//----------------------------------------------------------------------------- +// +// Copyright(C) 2009 Simon Howard +// +// 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 "AppController.h" + +#include "config.h" + +@implementation AppController + ++ (void)initialize +{ + NSMutableDictionary *defaults = [NSMutableDictionary dictionary]; + + /* + * Register your app's defaults here by adding objects to the + * dictionary, eg + * + * [defaults setObject:anObject forKey:keyForThatObject]; + * + */ + + [[NSUserDefaults standardUserDefaults] registerDefaults:defaults]; + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +- (id)init +{ + if ((self = [super init])) + { + } + + self->filesAdded = NO; + + return self; +} + +- (void)dealloc +{ + [super dealloc]; +} + +- (void)awakeFromNib +{ + [[NSApp mainMenu] setTitle:@PACKAGE_NAME]; +} + +- (void)applicationDidFinishLaunching:(NSNotification *)aNotif +{ +// Uncomment if your application is Renaissance-based +// [NSBundle loadGSMarkupNamed:@"Main" owner:self]; +} + +- (BOOL)applicationShouldTerminate:(id)sender +{ + return YES; +} + +- (void)applicationWillTerminate:(NSNotification *)aNotif +{ +} + +- (BOOL) application:(NSApplication *) application + openFile:(NSString *) fileName +{ + NSString *extension; + + // If this is the first file added, clear out the existing + // command line. This allows us to select multiple files + // in the finder and open them all together (for TCs, etc). + + if (!self->filesAdded) + { + [self->launcherManager clearCommandLine]; + } + + // Add file with appropriate command line option based on extension: + + extension = [fileName pathExtension]; + + if (![extension caseInsensitiveCompare: @"wad"]) + { + [self->launcherManager addFileToCommandLine: fileName + forArgument: @"-merge"]; + } + else if (![extension caseInsensitiveCompare: @"deh"]) + { + [self->launcherManager addFileToCommandLine: fileName + forArgument: @"-deh"]; + } + else + { + return NO; + } + + self->filesAdded = YES; + + return YES; +} + +- (void)showPrefPanel:(id)sender +{ +} + +@end + diff --git a/pkg/osx/Execute.h b/pkg/osx/Execute.h new file mode 100644 index 00000000..2098be8a --- /dev/null +++ b/pkg/osx/Execute.h @@ -0,0 +1,31 @@ +/* ... */ +//----------------------------------------------------------------------------- +// +// Copyright(C) 2009 Simon Howard +// +// 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 LAUNCHER_EXECUTE_H +#define LAUNCHER_EXECUTE_H + +void SetProgramLocation(const char *path); +void ExecuteProgram(const char *executable, const char *iwad, const char *args); +void OpenTerminalWindow(const char *doomwadpath); + +#endif /* #ifndef LAUNCHER_EXECUTE_H */ + diff --git a/pkg/osx/Execute.m b/pkg/osx/Execute.m new file mode 100644 index 00000000..bb4eed45 --- /dev/null +++ b/pkg/osx/Execute.m @@ -0,0 +1,197 @@ +/* ... */ +//----------------------------------------------------------------------------- +// +// Copyright(C) 2009 Simon Howard +// +// 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 <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/wait.h> + +#include <AppKit/AppKit.h> + +#include "config.h" + +#define RESPONSE_FILE "/tmp/launcher.rsp" +#define TEMP_SCRIPT "/tmp/tempscript.sh" + +static char *executable_path; + +// Called on startup to save the location of the launcher program +// (within a package, other executables should be in the same directory) + +void SetProgramLocation(const char *path) +{ + char *p; + + executable_path = strdup(path); + + p = strrchr(executable_path, '/'); + *p = '\0'; +} + +// Write out the response file containing command line arguments. + +static void WriteResponseFile(const char *iwad, const char *args) +{ + FILE *fstream; + + fstream = fopen(RESPONSE_FILE, "w"); + + if (iwad != NULL) + { + fprintf(fstream, "-iwad \"%s\"", iwad); + } + + if (args != NULL) + { + fprintf(fstream, "%s", args); + } + + fclose(fstream); +} + +static void DoExec(const char *executable, const char *iwad, const char *args) +{ + char *argv[3]; + + argv[0] = malloc(strlen(executable_path) + strlen(executable) + 3); + sprintf(argv[0], "%s/%s", executable_path, executable); + + if (iwad != NULL || args != NULL) + { + WriteResponseFile(iwad, args); + + argv[1] = "@" RESPONSE_FILE; + argv[2] = NULL; + } + else + { + argv[1] = NULL; + } + + execv(argv[0], argv); + exit(-1); +} + +// Execute the specified executable contained in the same directory +// as the launcher, with the specified arguments. + +void ExecuteProgram(const char *executable, const char *iwad, const char *args) +{ + pid_t childpid; + + childpid = fork(); + + if (childpid == 0) + { + signal(SIGCHLD, SIG_DFL); + + DoExec(executable, iwad, args); + } + else + { + signal(SIGCHLD, SIG_IGN); + } +} + +// Write a sequence of commands that will display the specified message +// via shell commands. + +static void WriteMessage(FILE *script, char *msg) +{ + char *p; + + fprintf(script, "echo \""); + + for (p=msg; *p != '\0'; ++p) + { + // Start new line? + + if (*p == '\n') + { + fprintf(script, "\"\necho \""); + continue; + } + + // Escaped character? + + if (*p == '\\' || *p == '\"') + { + fprintf(script, "\\"); + } + + fprintf(script, "%c", *p); + } + + fprintf(script, "\"\n"); +} + +// Open a terminal window with the PATH set appropriately, and DOOMWADPATH +// set to the specified value. + +void OpenTerminalWindow(const char *doomwadpath) +{ + FILE *stream; + + // Generate a shell script that sets the PATH to include the location + // where the Doom binaries are, and DOOMWADPATH to include the + // IWAD files that have been configured in the launcher interface. + // The script then deletes itself and starts a shell. + + stream = fopen(TEMP_SCRIPT, "w"); + + fprintf(stream, "#!/bin/sh\n"); + //fprintf(stream, "set -x\n"); + fprintf(stream, "PATH=\"%s:$PATH\"\n", executable_path); + fprintf(stream, "DOOMWADPATH=\"%s\"\n", doomwadpath); + fprintf(stream, "export DOOMWADPATH\n"); + fprintf(stream, "rm -f \"%s\"\n", TEMP_SCRIPT); + + // Display a useful message: + + fprintf(stream, "clear\n"); + WriteMessage(stream, + "\n" + "This command line has the PATH variable configured so that you may\n" + "launch the game with whatever parameters you desire.\n" + "\n" + "For example:\n" + "\n" + " " PACKAGE_TARNAME " -iwad doom2.wad -file sid.wad -warp 1\n" + "\n" + "Type 'exit' to exit.\n"); + + fprintf(stream, "exec $SHELL\n"); + fprintf(stream, "\n"); + + fclose(stream); + + chmod(TEMP_SCRIPT, 0755); + + // Tell the terminal to open a window to run the script. + + [[NSWorkspace sharedWorkspace] openFile: @TEMP_SCRIPT + withApplication: @"Terminal"]; +} + diff --git a/pkg/osx/GNUmakefile b/pkg/osx/GNUmakefile new file mode 100644 index 00000000..d119efa1 --- /dev/null +++ b/pkg/osx/GNUmakefile @@ -0,0 +1,101 @@ + +# Makefile for building the OS X launcher program and DMG package. +# It is also possible to build and run the launcher under Unix +# systems using GNUstep, although this is only here for development +# and debugging purposes. + +include ../config.make + +STAGING_DIR=staging +DMG=$(PACKAGE_TARNAME)-$(PACKAGE_VERSION).dmg + +TOPLEVEL=../.. +TOPLEVEL_DOCS=$(patsubst %,../../%,$(DOC_FILES)) + +ifndef GNUSTEP_MAKEFILES + +# DMG file containing package: + +$(DMG) : $(STAGING_DIR) + rm -f $@ + hdiutil create -volname "$(PACKAGE_STRING)" -srcdir $(STAGING_DIR) $@ + +endif + +# Staging dir build for package: + +APP_DIR=$(STAGING_DIR)/$(PACKAGE_NAME).app + +# OS X and GNUstep apps have a slightly different internal structure: +# OS X apps have their files within a containing "Contents" directory +# that does not exist in GNUstep apps. Similarly, the binaries are +# installed at the top level, rather than in a "MacOS" directory. +# Finally, we must install a different Info.plist file. + +ifdef GNUSTEP_MAKEFILES +APP_TOP_DIR=$(APP_DIR) +APP_BIN_DIR=$(APP_DIR) +SRC_INFO_PLIST=Info-gnustep.plist +else +APP_TOP_DIR=$(APP_DIR)/Contents +APP_BIN_DIR=$(APP_DIR)/Contents/MacOS +SRC_INFO_PLIST=Info.plist +endif + +$(STAGING_DIR): launcher $(TOPLEVEL_DOCS) + rm -rf $(STAGING_DIR) + mkdir $(STAGING_DIR) + + cp $(TOPLEVEL_DOCS) "$(STAGING_DIR)" + + mkdir -p "$(APP_TOP_DIR)" + cp -R Resources "$(APP_TOP_DIR)" + cp PkgInfo "$(APP_TOP_DIR)" + cp $(SRC_INFO_PLIST) "$(APP_TOP_DIR)" + + mkdir -p "$(APP_BIN_DIR)" + + cp launcher "$(APP_BIN_DIR)" + $(STRIP) "$(APP_BIN_DIR)/launcher" + + ./cp-with-libs $(TOPLEVEL)/src/$(PACKAGE_TARNAME) "$(APP_BIN_DIR)" + $(STRIP) "$(APP_BIN_DIR)/$(PACKAGE_TARNAME)" + ./cp-with-libs $(TOPLEVEL)/setup/chocolate-setup "$(APP_BIN_DIR)" + $(STRIP) "$(APP_BIN_DIR)/chocolate-setup" + + find $(STAGING_DIR) -name .svn -delete -exec rm -rf {} \; || true + +clean : launcher_clean + rm -f $(DMG) + rm -rf $(STAGING_DIR) + +# Launcher build: + +CFLAGS = -Wall -I$(TOPLEVEL) + +# Are we building using gs_make? + +ifdef GNUSTEP_MAKEFILES +CFLAGS += $(shell gnustep-config --objc-flags) +LDFLAGS = $(shell gnustep-config --gui-libs) +else +LDFLAGS = -framework Cocoa +endif + +LAUNCHER_OBJS= \ + AppController.o \ + Execute.o \ + IWADController.o \ + IWADLocation.o \ + LauncherManager.o \ + main.o + +launcher : $(LAUNCHER_OBJS) + $(CC) $(LDFLAGS) $(LAUNCHER_OBJS) -o $@ + +%.o : %.m + $(CC) -c $(CFLAGS) $^ -o $@ + +launcher_clean : + rm -f $(LAUNCHER_OBJS) launcher + diff --git a/pkg/osx/IWADController.h b/pkg/osx/IWADController.h new file mode 100644 index 00000000..90f44667 --- /dev/null +++ b/pkg/osx/IWADController.h @@ -0,0 +1,54 @@ +/* ... */ +//----------------------------------------------------------------------------- +// +// Copyright(C) 2009 Simon Howard +// +// 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 LAUNCHER_IWADCONTROLLER_H +#define LAUNCHER_IWADCONTROLLER_H + +#include <AppKit/AppKit.h> +#include <AppKit/NSNibLoading.h> + +@interface IWADController : NSObject +{ + id iwadSelector; + id configWindow; + + id chex; + id doom1; + id doom2; + id plutonia; + id tnt; +} + +- (void) closeConfigWindow: (id)sender; +- (void) openConfigWindow: (id)sender; +- (NSString *) getIWADLocation; +- (void) awakeFromNib; +- (BOOL) setDropdownList; +- (void) setDropdownSelection; +- (void) saveConfig; +- (char *) doomWadPath; +- (void) setEnvironment; + +@end + +#endif /* #ifndef LAUNCHER_IWADCONTROLLER_H */ + diff --git a/pkg/osx/IWADController.m b/pkg/osx/IWADController.m new file mode 100644 index 00000000..3c596850 --- /dev/null +++ b/pkg/osx/IWADController.m @@ -0,0 +1,347 @@ +/* ... */ +//----------------------------------------------------------------------------- +// +// Copyright(C) 2009 Simon Howard +// +// 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 <stdlib.h> +#include <string.h> +#include <AppKit/AppKit.h> +#include "IWADController.h" +#include "IWADLocation.h" + +typedef enum +{ + IWAD_DOOM1, + IWAD_DOOM2, + IWAD_TNT, + IWAD_PLUTONIA, + IWAD_CHEX, + NUM_IWAD_TYPES +} IWAD; + +static NSString *IWADLabels[NUM_IWAD_TYPES] = +{ + @"Doom", + @"Doom II: Hell on Earth", + @"Final Doom: TNT: Evilution", + @"Final Doom: Plutonia Experiment", + @"Chex Quest" +}; + +static NSString *IWADFilenames[NUM_IWAD_TYPES + 1] = +{ + @"doom.wad", + @"doom2.wad", + @"tnt.wad", + @"plutonia.wad", + @"chex.wad", + @"undefined" +}; + +@implementation IWADController + +- (void) getIWADList: (IWADLocation **) iwadList +{ + iwadList[IWAD_DOOM1] = self->doom1; + iwadList[IWAD_DOOM2] = self->doom2; + iwadList[IWAD_TNT] = self->tnt; + iwadList[IWAD_PLUTONIA] = self->plutonia; + iwadList[IWAD_CHEX] = self->chex; +} + +- (IWAD) getSelectedIWAD +{ + unsigned int i; + + for (i=0; i<NUM_IWAD_TYPES; ++i) + { + if ([self->iwadSelector titleOfSelectedItem] == IWADLabels[i]) + { + return i; + } + } + + return NUM_IWAD_TYPES; +} + +// Get the location of the selected IWAD. + +- (NSString *) getIWADLocation +{ + IWAD selectedIWAD; + IWADLocation *iwadList[NUM_IWAD_TYPES]; + + selectedIWAD = [self getSelectedIWAD]; + + if (selectedIWAD == NUM_IWAD_TYPES) + { + return nil; + } + else + { + [self getIWADList: iwadList]; + + return [iwadList[selectedIWAD] getLocation]; + } +} + +- (void) setIWADConfig +{ + IWADLocation *iwadList[NUM_IWAD_TYPES]; + NSUserDefaults *defaults; + NSString *key; + NSString *value; + unsigned int i; + + [self getIWADList: iwadList]; + + // Load IWAD filename paths + + defaults = [NSUserDefaults standardUserDefaults]; + + for (i=0; i<NUM_IWAD_TYPES; ++i) + { + key = IWADFilenames[i]; + value = [defaults stringForKey:key]; + + if (value != nil) + { + [iwadList[i] setLocation:value]; + } + } +} + +// On startup, set the selected item in the IWAD dropdown + +- (void) setDropdownSelection +{ + NSUserDefaults *defaults; + NSString *selected; + unsigned int i; + + defaults = [NSUserDefaults standardUserDefaults]; + selected = [defaults stringForKey: @"selected_iwad"]; + + if (selected == nil) + { + return; + } + + // Find this IWAD in the filenames list, and select it. + + for (i=0; i<NUM_IWAD_TYPES; ++i) + { + if ([selected isEqualToString:IWADFilenames[i]]) + { + [self->iwadSelector selectItemWithTitle:IWADLabels[i]]; + break; + } + } +} + +// Set the dropdown list to include an entry for each IWAD that has +// been configured. Returns true if at least one IWAD is configured. + +- (BOOL) setDropdownList +{ + IWADLocation *iwadList[NUM_IWAD_TYPES]; + BOOL have_wads; + id location; + unsigned int i; + unsigned int enabled_wads; + + // Build the new list. + + [self getIWADList: iwadList]; + [self->iwadSelector removeAllItems]; + + enabled_wads = 0; + + for (i=0; i<NUM_IWAD_TYPES; ++i) + { + location = [iwadList[i] getLocation]; + + if (location != nil && [location length] > 0) + { + [self->iwadSelector addItemWithTitle: IWADLabels[i]]; + ++enabled_wads; + } + } + + // Enable/disable the dropdown depending on whether there + // were any configured IWADs. + + have_wads = enabled_wads > 0; + [self->iwadSelector setEnabled: have_wads]; + + // Restore the old selection. + + [self setDropdownSelection]; + + return have_wads; +} + +- (void) saveConfig +{ + IWADLocation *iwadList[NUM_IWAD_TYPES]; + IWAD selectedIWAD; + NSUserDefaults *defaults; + NSString *key; + NSString *value; + unsigned int i; + + [self getIWADList: iwadList]; + + // Store all IWAD locations to user defaults. + + defaults = [NSUserDefaults standardUserDefaults]; + + for (i=0; i<NUM_IWAD_TYPES; ++i) + { + key = IWADFilenames[i]; + value = [iwadList[i] getLocation]; + + [defaults setObject:value forKey:key]; + } + + // Save currently selected IWAD. + + selectedIWAD = [self getSelectedIWAD]; + [defaults setObject:IWADFilenames[selectedIWAD] + forKey:@"selected_iwad"]; +} + +// Callback method invoked when the configuration button in the main +// window is clicked. + +- (void) openConfigWindow: (id)sender +{ + if (![self->configWindow isVisible]) + { + [self->configWindow makeKeyAndOrderFront: sender]; + } +} + +// Callback method invoked when the close button is clicked. + +- (void) closeConfigWindow: (id)sender +{ + [self->configWindow orderOut: sender]; + [self saveConfig]; + [self setDropdownList]; +} + +- (void) awakeFromNib +{ + [self->configWindow center]; + + // Set configuration for all IWADs from configuration file. + + [self setIWADConfig]; + + // Populate the dropdown IWAD list. + + if ([self setDropdownList]) + { + [self setDropdownSelection]; + } +} + +// Generate a value to set for the DOOMWADPATH environment variable +// that contains each of the configured IWAD files. + +- (char *) doomWadPath +{ + IWADLocation *iwadList[NUM_IWAD_TYPES]; + NSString *location; + unsigned int i; + unsigned int len; + BOOL first; + char *env; + + [self getIWADList: iwadList]; + + // Calculate length of environment string. + + len = 0; + + for (i=0; i<NUM_IWAD_TYPES; ++i) + { + location = [iwadList[i] getLocation]; + + if (location != nil && [location length] > 0) + { + len += [location length] + 1; + } + } + + // Build string. + + env = malloc(len); + strcpy(env, ""); + + first = YES; + + for (i=0; i<NUM_IWAD_TYPES; ++i) + { + location = [iwadList[i] getLocation]; + + if (location != nil && [location length] > 0) + { + if (!first) + { + strcat(env, ":"); + } + + strcat(env, [location UTF8String]); + first = NO; + } + } + + return env; +} + +// Set the DOOMWADPATH environment variable to contain the path to each +// of the configured IWAD files. + +- (void) setEnvironment +{ + char *doomwadpath; + char *env; + + // Get the value for the path. + + doomwadpath = [self doomWadPath]; + + env = malloc(strlen(doomwadpath) + 15); + + sprintf(env, "DOOMWADPATH=%s", doomwadpath); + + free(doomwadpath); + + // Load into environment: + + putenv(env); + + //free(env); +} + +@end + diff --git a/pkg/osx/IWADLocation.h b/pkg/osx/IWADLocation.h new file mode 100644 index 00000000..4ddfebc2 --- /dev/null +++ b/pkg/osx/IWADLocation.h @@ -0,0 +1,44 @@ +/* ... */ +//----------------------------------------------------------------------------- +// +// Copyright(C) 2009 Simon Howard +// +// 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 LAUNCHER_IWADLOCATION_H +#define LAUNCHER_IWADLOCATION_H + +#include <AppKit/AppKit.h> + +#include "IWADController.h" + +@interface IWADLocation : NSObject +{ + IWADController *iwadController; + + id locationConfigBox; +} + +- (void) setButtonClicked: (id)sender; +- (NSString *) getLocation; +- (void) setLocation: (NSString *) value; + +@end + +#endif /* #ifndef LAUNCHER_IWADLOCATION_H */ + diff --git a/pkg/osx/IWADLocation.m b/pkg/osx/IWADLocation.m new file mode 100644 index 00000000..3f2ac188 --- /dev/null +++ b/pkg/osx/IWADLocation.m @@ -0,0 +1,74 @@ +/* ... */ +//----------------------------------------------------------------------------- +// +// Copyright(C) 2009 Simon Howard +// +// 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 <AppKit/AppKit.h> +#include "IWADLocation.h" + +static id WAD_TYPES[] = +{ + @"wad", @"WAD" +}; + +@implementation IWADLocation + +- (void) setButtonClicked: (id)sender +{ + NSArray *wadTypes = [NSArray arrayWithObjects: WAD_TYPES count: 2]; + NSOpenPanel *openPanel; + NSArray *filenames; + int result; + + [wadTypes retain]; + + // Open a file selector for the new file. + + openPanel = [NSOpenPanel openPanel]; + [openPanel setTitle: @"Add IWAD file"]; + [openPanel setCanChooseFiles: YES]; + [openPanel setCanChooseDirectories: NO]; + + result = [openPanel runModalForTypes: wadTypes]; + + // If the "OK" button was clicked, add the new IWAD file to the list. + + if (result == NSOKButton) + { + filenames = [openPanel filenames]; + [self setLocation: [filenames lastObject]]; + + [self->iwadController saveConfig]; + [self->iwadController setDropdownList]; + } +} + +- (NSString *) getLocation +{ + return [self->locationConfigBox stringValue]; +} + +- (void) setLocation: (NSString *) filename +{ + [self->locationConfigBox setStringValue: filename]; +} + +@end + diff --git a/pkg/osx/Info-gnustep.plist.in b/pkg/osx/Info-gnustep.plist.in new file mode 100644 index 00000000..da6675ba --- /dev/null +++ b/pkg/osx/Info-gnustep.plist.in @@ -0,0 +1,36 @@ +{ + ApplicationName = "@PACKAGE_NAME@"; + ApplicationDescription = "@PACKAGE_SHORTDESC@"; + ApplicationIcon = app.png; + ApplicationRelease = @PACKAGE_VERSION@; + ApplicationURL = "@PACKAGE_URL@"; + Authors = ( + "@PACKAGE_MAINTAINER@ <@PACKAGE_BUGREPORT@>" + ); + Copyright = "@PACKAGE_COPYRIGHT@"; + CopyrightDescription = "@PACKAGE_LICENSE@"; + FullVersionID = @PACKAGE_VERSION@; + GSMainMarkupFile = ""; + NSExecutable = "launcher"; + NSIcon = app.png; + NSMainNibFile = launcher.nib; + NSPrincipalClass = NSApplication; + NSRole = Application; + NSTypes = ( + { + NSHumanReadableName = "Doom WAD file"; + NSUnixExtensions = ( wad ); + NSRole = Viewer; + NSMimeTypes = ( + "application/x-doom" + ); + NSIcon = "wadfile.png"; + }, + { + NSHumanReadableName = "Dehacked patch"; + NSUnixExtensions = ( deh ); + NSRole = Viewer; + NSIcon = "wadfile.png"; + } + ); +} diff --git a/pkg/osx/Info.plist.in b/pkg/osx/Info.plist.in new file mode 100644 index 00000000..8b8436f7 --- /dev/null +++ b/pkg/osx/Info.plist.in @@ -0,0 +1,60 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleDisplayName</key> + <string>@PACKAGE_NAME@</string> + <key>CFBundleExecutable</key> + <string>launcher</string> + <key>CFBundleGetInfoString</key> + <string>@PACKAGE_STRING@</string> + <key>CFBundleIconFile</key> + <string>app.icns</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>@PACKAGE_NAME@</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>@PACKAGE_VERSION@</string> + <key>CFBundleVersion</key> + <string>@PACKAGE_VERSION@</string> + <key>NSPrincipalClass</key> + <string>NSApplication</string> + <key>NSMainNibFile</key> + <string>launcher</string> + + <!-- file associations: --> + + <key>CFBundleDocumentTypes</key> + <array> + <dict> + <key>CFBundleTypeName</key> + <string>Doom WAD file</string> + <key>CFBundleTypeIconFile</key> + <string>wadfile.icns</string> + <key>CFBundleTypeRole</key> + <string>Viewer</string> + <key>CFBundleTypeExtensions</key> + <array> + <string>wad</string> + </array> + </dict> + <dict> + <key>CFBundleTypeName</key> + <string>Dehacked patch</string> + <key>CFBundleTypeIconFile</key> + <string>wadfile.icns</string> + <key>CFBundleTypeRole</key> + <string>Viewer</string> + <key>CFBundleTypeExtensions</key> + <array> + <string>deh</string> + </array> + </dict> + </array> +</dict> +</plist> diff --git a/pkg/osx/LauncherManager.h b/pkg/osx/LauncherManager.h new file mode 100644 index 00000000..76c74624 --- /dev/null +++ b/pkg/osx/LauncherManager.h @@ -0,0 +1,51 @@ +/* ... */ +//----------------------------------------------------------------------------- +// +// Copyright(C) 2009 Simon Howard +// +// 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 LAUNCHER_LAUNCHERMANAGER_H +#define LAUNCHER_LAUNCHERMANAGER_H + +#include <AppKit/AppKit.h> +#include <AppKit/NSNibLoading.h> +#include "IWADController.h" + +@interface LauncherManager : NSObject +{ + IWADController *iwadController; + + id launcherWindow; + + id commandLineArguments; + id packageLabel; +} + +- (void) launch: (id)sender; +- (void) runSetup: (id)sender; +- (void) awakeFromNib; +- (void) clearCommandLine; +- (void) addFileToCommandLine: (NSString *) fileName + forArgument: (NSString *) args; +- (void) openTerminal: (id) sender; + +@end + +#endif /* #ifndef LAUNCHER_LAUNCHERMANAGER_H */ + diff --git a/pkg/osx/LauncherManager.m b/pkg/osx/LauncherManager.m new file mode 100644 index 00000000..ee7ed3dc --- /dev/null +++ b/pkg/osx/LauncherManager.m @@ -0,0 +1,337 @@ +/* ... */ +//----------------------------------------------------------------------------- +// +// Copyright(C) 2009 Simon Howard +// +// 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 <AppKit/AppKit.h> +#include "Execute.h" +#include "LauncherManager.h" +#include "config.h" + +@implementation LauncherManager + +// Save configuration. Invoked when we launch the game or quit. + +- (void) saveConfig +{ + NSUserDefaults *defaults; + + // Save IWAD configuration and selected IWAD. + + [self->iwadController saveConfig]; + + // Save command line arguments. + + defaults = [NSUserDefaults standardUserDefaults]; + [defaults setObject:[self->commandLineArguments stringValue] + forKey:@"command_line_args"]; +} + +// Load configuration, invoked on startup. + +- (void) setConfig +{ + NSUserDefaults *defaults; + NSString *args; + + defaults = [NSUserDefaults standardUserDefaults]; + + args = [defaults stringForKey:@"command_line_args"]; + + if (args != nil) + { + [self->commandLineArguments setStringValue:args]; + } +} + +// Get the next command line argument from the command line. +// The position counter used to iterate over arguments is in 'pos'. +// The index of the argument that was found is saved in arg_pos. + +static NSString *GetNextArgument(NSString *commandLine, int *pos, int *arg_pos) +{ + NSRange arg_range; + + // Skip past any whitespace + + while (*pos < [commandLine length] + && isspace([commandLine characterAtIndex: *pos])) + { + ++*pos; + } + + if (*pos >= [commandLine length]) + { + *arg_pos = *pos; + return nil; + } + + // We are at the start of the argument. This may be a quoted + // string argument, or a "normal" one. + + if ([commandLine characterAtIndex: *pos] == '\"') + { + // Quoted string, skip past first quote + + ++*pos; + + // Save start position: + + *arg_pos = *pos; + + while (*pos < [commandLine length] + && [commandLine characterAtIndex: *pos] != '\"') + { + ++*pos; + } + + // Unexpected end of string? + + if (*pos >= [commandLine length]) + { + return nil; + } + + arg_range = NSMakeRange(*arg_pos, *pos - *arg_pos); + + // Skip past last quote + + ++*pos; + } + else + { + // Normal argument + + // Save position: + + *arg_pos = *pos; + + // Read until end: + + while (*pos < [commandLine length] + && !isspace([commandLine characterAtIndex: *pos])) + { + ++*pos; + } + + arg_range = NSMakeRange(*arg_pos, *pos - *arg_pos); + } + + return [commandLine substringWithRange: arg_range]; +} + +// Given the specified command line argument, find the index +// to insert the new file within the command line. Returns -1 if the +// argument is not already within the arguments string. + +static int GetFileInsertIndex(NSString *commandLine, NSString *needle) +{ + NSString *arg; + int arg_pos; + int pos; + + pos = 0; + + // Find the command line parameter we are searching + // for (-merge, -deh, etc) + + for (;;) + { + arg = GetNextArgument(commandLine, &pos, &arg_pos); + + // Searched to end of string and never found? + + if (arg == nil) + { + return -1; + } + + if (![arg caseInsensitiveCompare: needle]) + { + break; + } + } + + // Now skip over existing files. For example, if we + // have -file foo.wad bar.wad, the new file should be appended + // to the end of the list. + + for (;;) + { + arg = GetNextArgument(commandLine, &pos, &arg_pos); + + // If we search to the end of the string now, it is fine; + // the new string should be added to the end of the command + // line. Otherwise, if we find an argument that begins + // with '-', it is a new command line parameter and the end + // of the list. + + if (arg == nil || [arg characterAtIndex: 0] == '-') + { + break; + } + } + + // arg_pos should now contain the offset to insert the new filename. + + return arg_pos; +} + +// Given the specified string, append a filename, quoted if necessary. + +static NSString *AppendQuotedFilename(NSString *str, NSString *fileName) +{ + int i; + + // Search the filename for spaces, and quote if necessary. + + for (i=0; i<[fileName length]; ++i) + { + if (isspace([fileName characterAtIndex: i])) + { + str = [str stringByAppendingString: @" \""]; + str = [str stringByAppendingString: fileName]; + str = [str stringByAppendingString: @"\" "]; + + return str; + } + } + + str = [str stringByAppendingString: @" "]; + str = [str stringByAppendingString: fileName]; + + return str; +} + +// Clear out the existing command line options. +// Invoked before the first file is added. + +- (void) clearCommandLine +{ + [self->commandLineArguments setStringValue: @""]; +} + +// Add a file to the command line to load with the game. + +- (void) addFileToCommandLine: (NSString *) fileName + forArgument: (NSString *) arg +{ + NSString *commandLine; + int insert_pos; + + // Get the current command line + + commandLine = [self->commandLineArguments stringValue]; + + // Find the location to insert the new filename: + + insert_pos = GetFileInsertIndex(commandLine, arg); + + // If position < 0, we should add the new argument and filename + // to the end. Otherwise, append the new filename to the existing + // list of files. + + if (insert_pos < 0) + { + commandLine = [commandLine stringByAppendingString: @" "]; + commandLine = [commandLine stringByAppendingString: arg]; + commandLine = AppendQuotedFilename(commandLine, fileName); + } + else + { + NSString *start; + NSString *end; + + // Divide existing command line in half: + + start = [commandLine substringToIndex: insert_pos]; + end = [commandLine substringFromIndex: insert_pos]; + + // Construct new command line: + + commandLine = AppendQuotedFilename(start, fileName); + commandLine = [commandLine stringByAppendingString: @" "]; + commandLine = [commandLine stringByAppendingString: end]; + } + + [self->commandLineArguments setStringValue: commandLine]; +} + +- (void) launch: (id)sender +{ + NSString *iwad; + NSString *args; + + [self saveConfig]; + + iwad = [self->iwadController getIWADLocation]; + args = [self->commandLineArguments stringValue]; + + if (iwad == nil) + { + NSRunAlertPanel(@"No IWAD selected", + @"You have not selected an IWAD (game) file.\n\n" + "You must configure and select a valid IWAD file " + "in order to launch the game.", + @"OK", nil, nil); + return; + } + + ExecuteProgram(PACKAGE_TARNAME, [iwad UTF8String], + [args UTF8String]); + [NSApp terminate:sender]; +} + +// Invoked when the "Setup Tool" button is clicked, to run the setup tool: + +- (void) runSetup: (id)sender +{ + [self saveConfig]; + + [self->iwadController setEnvironment]; + ExecuteProgram("chocolate-setup", NULL, NULL); +} + +// Invoked when the "Terminal" option is selected from the menu, to open +// a terminal window. + +- (void) openTerminal: (id) sender +{ + char *doomwadpath; + + [self saveConfig]; + + doomwadpath = [self->iwadController doomWadPath]; + + OpenTerminalWindow(doomwadpath); + + free(doomwadpath); +} + +- (void) awakeFromNib +{ + [self->packageLabel setStringValue: @PACKAGE_STRING]; + [self->launcherWindow setTitle: @PACKAGE_NAME " Launcher"]; + [self->launcherWindow center]; + [self setConfig]; +} + +@end + diff --git a/pkg/osx/PkgInfo b/pkg/osx/PkgInfo new file mode 100644 index 00000000..6f749b0f --- /dev/null +++ b/pkg/osx/PkgInfo @@ -0,0 +1 @@ +APPL???? diff --git a/pkg/osx/Resources/128x128.png b/pkg/osx/Resources/128x128.png Binary files differnew file mode 100644 index 00000000..0ef1fe9c --- /dev/null +++ b/pkg/osx/Resources/128x128.png diff --git a/pkg/osx/Resources/app.icns b/pkg/osx/Resources/app.icns Binary files differnew file mode 100644 index 00000000..9b535a25 --- /dev/null +++ b/pkg/osx/Resources/app.icns diff --git a/pkg/osx/Resources/app.png b/pkg/osx/Resources/app.png Binary files differnew file mode 100644 index 00000000..5b932e8c --- /dev/null +++ b/pkg/osx/Resources/app.png diff --git a/pkg/osx/Resources/launcher.nib/classes.nib b/pkg/osx/Resources/launcher.nib/classes.nib new file mode 100644 index 00000000..236f6b67 --- /dev/null +++ b/pkg/osx/Resources/launcher.nib/classes.nib @@ -0,0 +1,46 @@ +{ + IBClasses = ( + { + CLASS = AppController; + LANGUAGE = ObjC; + OUTLETS = {launcherManager = id; }; + SUPERCLASS = NSObject; + }, + {CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }, + { + ACTIONS = {closeConfigWindow = id; openConfigWindow = id; }; + CLASS = IWADController; + LANGUAGE = ObjC; + OUTLETS = { + chex = id; + configWindow = id; + doom1 = id; + doom2 = id; + iwadSelector = id; + plutonia = id; + tnt = id; + }; + SUPERCLASS = NSObject; + }, + { + ACTIONS = {setButtonClicked = id; }; + CLASS = IWADLocation; + LANGUAGE = ObjC; + OUTLETS = {locationConfigBox = id; }; + SUPERCLASS = NSObject; + }, + { + ACTIONS = {launch = id; openTerminal = id; runSetup = id; }; + CLASS = LauncherManager; + LANGUAGE = ObjC; + OUTLETS = { + commandLineArguments = id; + iwadController = id; + launcherWindow = id; + packageLabel = id; + }; + SUPERCLASS = NSObject; + } + ); + IBVersion = 1; +}
\ No newline at end of file diff --git a/pkg/osx/Resources/launcher.nib/info.nib b/pkg/osx/Resources/launcher.nib/info.nib new file mode 100644 index 00000000..32b331f5 --- /dev/null +++ b/pkg/osx/Resources/launcher.nib/info.nib @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>IBDocumentLocation</key> + <string>484 105 612 260 0 0 1440 878 </string> + <key>IBEditorPositions</key> + <dict> + <key>29</key> + <string>221 322 205 44 0 0 1440 878 </string> + </dict> + <key>IBFramework Version</key> + <string>446.1</string> + <key>IBOpenObjects</key> + <array> + <integer>29</integer> + <integer>21</integer> + <integer>227</integer> + </array> + <key>IBSystem Version</key> + <string>8S2167</string> +</dict> +</plist> diff --git a/pkg/osx/Resources/launcher.nib/keyedobjects.nib b/pkg/osx/Resources/launcher.nib/keyedobjects.nib Binary files differnew file mode 100644 index 00000000..4f078d7c --- /dev/null +++ b/pkg/osx/Resources/launcher.nib/keyedobjects.nib diff --git a/pkg/osx/Resources/wadfile.icns b/pkg/osx/Resources/wadfile.icns Binary files differnew file mode 100644 index 00000000..13502a55 --- /dev/null +++ b/pkg/osx/Resources/wadfile.icns diff --git a/pkg/osx/Resources/wadfile.png b/pkg/osx/Resources/wadfile.png Binary files differnew file mode 100644 index 00000000..394a3e33 --- /dev/null +++ b/pkg/osx/Resources/wadfile.png diff --git a/pkg/osx/cp-with-libs b/pkg/osx/cp-with-libs new file mode 100755 index 00000000..04fb5bc6 --- /dev/null +++ b/pkg/osx/cp-with-libs @@ -0,0 +1,100 @@ +#!/bin/bash +# +# Copy a program to the specified destination, along +# with libraries it depends upon. + +src_bin=$1 +dest_dir=$2 + +# Returns true if the specified file is a dylib. + +is_dylib() { + case "$1" in + *.dylib) + true + ;; + *) + false + ;; + esac +} + +# Returns true if the specified file is in a system location +# (/System or /usr): + +is_sys_lib() { + case "$1" in + /System/*) + true + ;; + /usr/*) + true + ;; + *) + false + ;; + esac +} + +# Install the specified file to the location in dest_dir, along with +# any libraries it depends upon (recursively): + +install_with_deps() { + local src_file + local bin_name + local dest_file + local lib_name + + src_file=$1 + bin_name=$(basename "$src_file") + dest_file="$dest_dir/$bin_name" + + # Already copied into the package? Don't copy again. + # Prevents endless recursion. + + if [ -e "$dest_file" ]; then + return + fi + + echo "Installing $bin_name..." + + # Copy file into package. + + cp "$src_file" "$dest_file" + + # Copy libraries that this file depends on: + + otool -L "$src_file" | tail -n +2 | sed 's/^.//; s/ (.*//' | while read; do + + # Don't copy system libraries + + if is_sys_lib "$REPLY"; then + continue + fi + + #echo " - $bin_name depends on $REPLY" + + # Copy this library into the package, and: + # recursively install any libraries that _this_ library depends on: + + install_with_deps "$REPLY" + + # Change destination binary to depend on the + # copy inside the package: + + lib_name=$(basename "$REPLY") + install_name_tool -change "$REPLY" "@executable_path/$lib_name" \ + "$dest_file" + done + + # If this is a library that we have installed, change its id: + + if is_dylib "$dest_file"; then + install_name_tool -id "@executable_path/$bin_name" "$dest_file" + fi +} + +# Install the file, and recursively install any libraries: + +install_with_deps "$src_bin" + diff --git a/pkg/osx/main.m b/pkg/osx/main.m new file mode 100644 index 00000000..e3c70dc1 --- /dev/null +++ b/pkg/osx/main.m @@ -0,0 +1,32 @@ +/* ... */ +//----------------------------------------------------------------------------- +// +// Copyright(C) 2009 Simon Howard +// +// 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 <AppKit/AppKit.h> +#include "Execute.h" + +int main(int argc, const char *argv[]) +{ + SetProgramLocation(argv[0]); + + return NSApplicationMain (argc, argv); +} + diff --git a/pkg/win32/GNUmakefile b/pkg/win32/GNUmakefile new file mode 100644 index 00000000..626f1845 --- /dev/null +++ b/pkg/win32/GNUmakefile @@ -0,0 +1,32 @@ + +include ../config.make + +TOPLEVEL=../.. + +EXE_FILES=$(TOPLEVEL)/src/$(PACKAGE_TARNAME).exe \ + $(TOPLEVEL)/src/chocolate-server.exe \ + $(TOPLEVEL)/setup/chocolate-setup.exe + +DLL_FILES=$(TOPLEVEL)/src/SDL.dll \ + $(TOPLEVEL)/src/SDL_mixer.dll \ + $(TOPLEVEL)/src/SDL_net.dll + +ZIP=$(PACKAGE_TARNAME)-$(PACKAGE_VERSION)-win32.zip + +$(ZIP) : staging + zip -j -r $@ staging/ + +staging: $(EXE_FILES) $(DLL_FILES) $(patsubst %,../../%,$(DOC_FILES)) + rm -rf staging + mkdir staging + cp $(EXE_FILES) $(DLL_FILES) staging/ + $(STRIP) staging/*.exe + for f in $(DOC_FILES); do \ + cp $(TOPLEVEL)/$$f staging/$$f.txt; \ + unix2dos staging/$$f.txt; \ + done + +clean: + rm -f $(ZIP) + rm -rf staging + diff --git a/pkg/win32/README b/pkg/win32/README new file mode 100644 index 00000000..1f43f52c --- /dev/null +++ b/pkg/win32/README @@ -0,0 +1,4 @@ + +Makefile to build Windows packages. Requires zip and unix2dos cygwin +packages to be installed. + diff --git a/pkg/wince/GNUmakefile b/pkg/wince/GNUmakefile new file mode 100644 index 00000000..b6acc3b8 --- /dev/null +++ b/pkg/wince/GNUmakefile @@ -0,0 +1,15 @@ + +include ../config.make + +DEPS=$(shell ./wince-cabgen -d $(CONFIG_FILE)) +EXECUTABLES=$(filter %.exe, $(DEPS)) +CONFIG_FILE=wince-cab.cfg +OUTPUT_FILE=$(PACKAGE_TARNAME)-$(PACKAGE_VERSION).cab + +$(OUTPUT_FILE) : $(CONFIG_FILE) $(DEPS) + $(STRIP) $(EXECUTABLES) + ./wince-cabgen $< $@ + +clean: + rm -f $(OUTPUT_FILE) + diff --git a/pkg/wince/GNUmakefile.am b/pkg/wince/GNUmakefile.am deleted file mode 100644 index e710e679..00000000 --- a/pkg/wince/GNUmakefile.am +++ /dev/null @@ -1,12 +0,0 @@ - -DEPS=$(shell ./wince-cabgen -d $(CONFIG_FILE)) -CONFIG_FILE=wince-cab.cfg -OUTPUT_FILE=@PACKAGE_TARNAME@-@PACKAGE_VERSION@.cab - -EXTRA_DIST=wince-cabgen $(CONFIG_FILE) - -noinst_DATA = $(OUTPUT_FILE) - -$(OUTPUT_FILE) : $(CONFIG_FILE) $(DEPS) - ./wince-cabgen $< $@ - diff --git a/rpm.spec.in b/rpm.spec.in new file mode 100644 index 00000000..1b7e90c7 --- /dev/null +++ b/rpm.spec.in @@ -0,0 +1,59 @@ + +Name: @PACKAGE@ +Summary: @PACKAGE_SHORTDESC@ +Version: @VERSION@ +Release: 1 +Source: http://mesh.dl.sourceforge.net/project/chocolate-doom/@PACKAGE@/@VERSION@/@PACKAGE@-@VERSION@.tar.gz +URL: @PACKAGE_URL@ +Group: Amusements/Games +BuildRoot: /var/tmp/@PACKAGE@-buildroot +License: @PACKAGE_LICENSE@ +Packager: @PACKAGE_MAINTAINER@ <@PACKAGE_BUGREPORT@> +Prefix: %{_prefix} +Autoreq: 0 +Requires: libSDL-1.2.so.0, libSDL_mixer-1.2.so.0, libSDL_net-1.2.so.0 + +%description +%(sed -n "/==/ q; p " < README) + +See @PACKAGE_URL@ for more information. + +%prep +rm -rf $RPM_BUILD_ROOT + +%setup -q + +%build +./configure \ + --prefix=/usr \ + --exec-prefix=/usr \ + --bindir=/usr/bin \ + --sbindir=/usr/sbin \ + --sysconfdir=/etc \ + --datadir=/usr/share \ + --includedir=/usr/include \ + --libdir=/usr/lib \ + --libexecdir=/usr/lib \ + --localstatedir=/var/lib \ + --sharedstatedir=/usr/com \ + --mandir=/usr/share/man \ + --infodir=/usr/share/info +make + +%install +%makeinstall + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%doc %{_mandir}/man5/* +%doc %{_mandir}/man6/* +%doc NEWS +%doc AUTHORS +%doc README +%doc COPYING +%doc CMDLINE +%doc BUGS +/usr/games/* + diff --git a/setup/.gitignore b/setup/.gitignore index e2da8a59..37c8e4c1 100644 --- a/setup/.gitignore +++ b/setup/.gitignore @@ -4,3 +4,5 @@ Makefile chocolate-setup *.rc *.exe +tags +TAGS diff --git a/setup/Makefile.am b/setup/Makefile.am index 92b4e394..91c7449a 100644 --- a/setup/Makefile.am +++ b/setup/Makefile.am @@ -44,7 +44,7 @@ chocolate_setup_LDADD = \ if HAVE_PYTHON -setup_icon.c : ../data/setup.ico +setup_icon.c : ../data/setup8.ico ../data/convert-icon $^ $@ endif diff --git a/setup/execute.c b/setup/execute.c index fb9885fa..8e753f60 100644 --- a/setup/execute.c +++ b/setup/execute.c @@ -185,29 +185,38 @@ static void ConcatWCString(wchar_t *buf, const char *value) static wchar_t *BuildCommandLine(const char *program, const char *arg) { + wchar_t exe_path[MAX_PATH]; wchar_t *result; - char *sep; + wchar_t *sep; + + // Get the path to this .exe file. + + GetModuleFileNameW(NULL, exe_path, MAX_PATH); - result = calloc(strlen(myargv[0]) + strlen(program) + strlen(arg) + 6, + // Allocate buffer to contain result string. + + result = calloc(wcslen(exe_path) + strlen(program) + strlen(arg) + 6, sizeof(wchar_t)); wcscpy(result, L"\""); - sep = strrchr(myargv[0], DIR_SEPARATOR); + // Copy the path part of the filename (including ending \) + // into the result buffer: + + sep = wcsrchr(exe_path, DIR_SEPARATOR); if (sep != NULL) { - ConcatWCString(result, myargv[0]); - - // Cut off the string after the last directory separator, - // before appending the actual program. - - result[sep - myargv[0] + 2] = '\0'; - + wcsncpy(result + 1, exe_path, sep - exe_path + 1); + result[sep - exe_path + 2] = '\0'; } + // Concatenate the name of the program: + ConcatWCString(result, program); + // End of program name, start of argument: + wcscat(result, L"\" \""); ConcatWCString(result, arg); @@ -301,9 +310,9 @@ static int ExecuteCommand(const char *program, const char *arg) argv[1] = arg; argv[2] = NULL; - execv(argv[0], (char **) argv); + execvp(argv[0], (char **) argv); - exit(-1); + exit(0x80); } else { @@ -312,7 +321,7 @@ static int ExecuteCommand(const char *program, const char *arg) waitpid(childpid, &result, 0); - if (WIFEXITED(result)) + if (WIFEXITED(result) && WEXITSTATUS(result) != 0x80) { return WEXITSTATUS(result); } diff --git a/setup/setup-manifest.xml b/setup/setup-manifest.xml index 409a142b..c2788306 100644 --- a/setup/setup-manifest.xml +++ b/setup/setup-manifest.xml @@ -1,16 +1,33 @@ <?xml version="1.0" encoding="UTF-8" standalone="yes"?> + +<!-- Magic manifest file that should make Windows Vista/7 not + attempt to gain elevated privileges for chocolate-setup. + + Based on: + + http://www.cygwin.com/ml/cygwin/2006-12/msg00580.html + --> + <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <!-- The "name" field in this tag should be the same as the executable's name --> - <assemblyIdentity version="1.2.1.0" processorArchitecture="*" - name="chocolate-setup" type="win32"/> + <assemblyIdentity version="0.0.0.0" processorArchitecture="X86" + name="chocolate-setup.exe" type="win32"/> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3"> <security> <requestedPrivileges> - <!-- Hi Vista! We don't require elevated privileges. Thanks! --> - <requestedExecutionLevel level="asInvoker"/> + <requestedExecutionLevel level="asInvoker" uiAccess="false" /> </requestedPrivileges> </security> </trustInfo> + + <!-- Stop the Program Compatibility Assistant appearing: --> + + <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> + <application> + <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/> <!-- 7 --> + <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/> <!-- Vista --> + </application> + </compatibility> </assembly> diff --git a/setup/setup-res.rc.in b/setup/setup-res.rc.in index dc25135a..2bc3106c 100644 --- a/setup/setup-res.rc.in +++ b/setup/setup-res.rc.in @@ -1,6 +1,6 @@ 1 ICON "../data/setup.ico" -CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "setup-manifest.xml" +1 24 MOVEABLE PURE "setup-manifest.xml" 1 VERSIONINFO PRODUCTVERSION @WINDOWS_RC_VERSION@ diff --git a/src/.gitignore b/src/.gitignore index d7e732ad..973a0073 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -5,3 +5,5 @@ Makefile.in chocolate-doom chocolate-server *.exe +tags +TAGS diff --git a/src/Makefile.am b/src/Makefile.am index 7deed766..8b827131 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -191,7 +191,7 @@ EXTRA_DIST = \ if HAVE_PYTHON -icon.c : ../data/doom.ico +icon.c : ../data/doom8.ico ../data/convert-icon $^ $@ endif diff --git a/src/d_iwad.c b/src/d_iwad.c index 0e48420d..ea0d29d0 100644 --- a/src/d_iwad.c +++ b/src/d_iwad.c @@ -338,40 +338,81 @@ static void CheckChex(char *iwad_name) } } +// Returns true if the specified path is a path to a file +// of the specified name. + +static boolean DirIsFile(char *path, char *filename) +{ + size_t path_len; + size_t filename_len; + + path_len = strlen(path); + filename_len = strlen(filename); + + return path_len >= filename_len + 1 + && path[path_len - filename_len - 1] == DIR_SEPARATOR + && !strcasecmp(&path[path_len - filename_len], filename); +} + +// Check if the specified directory contains the specified IWAD +// file, returning the full path to the IWAD if found, or NULL +// if not found. + +static char *CheckDirectoryHasIWAD(char *dir, char *iwadname) +{ + char *filename; + + // As a special case, the "directory" may refer directly to an + // IWAD file if the path comes from DOOMWADDIR or DOOMWADPATH. + + if (DirIsFile(dir, iwadname) && M_FileExists(dir)) + { + return strdup(dir); + } + + // Construct the full path to the IWAD if it is located in + // this directory, and check if it exists. + + filename = malloc(strlen(dir) + strlen(iwadname) + 3); + + if (!strcmp(dir, ".")) + { + strcpy(filename, iwadname); + } + else + { + sprintf(filename, "%s%c%s", dir, DIR_SEPARATOR, iwadname); + } + + if (M_FileExists(filename)) + { + return filename; + } + + free(filename); + + return NULL; +} + // Search a directory to try to find an IWAD // Returns the location of the IWAD if found, otherwise NULL. static char *SearchDirectoryForIWAD(char *dir) { + char *filename; size_t i; for (i=0; i<arrlen(iwads); ++i) { - char *filename; - char *iwadname; - - iwadname = DEH_String(iwads[i].name); - - filename = malloc(strlen(dir) + strlen(iwadname) + 3); + filename = CheckDirectoryHasIWAD(dir, DEH_String(iwads[i].name)); - if (!strcmp(dir, ".")) - { - strcpy(filename, iwadname); - } - else - { - sprintf(filename, "%s%c%s", dir, DIR_SEPARATOR, iwadname); - } - - if (M_FileExists(filename)) + if (filename != NULL) { CheckChex(iwads[i].name); gamemission = iwads[i].mission; return filename; } - - free(filename); } return NULL; @@ -525,7 +566,6 @@ char *D_FindWADByName(char *name) { char *buf; int i; - boolean exists; // Absolute path? @@ -540,14 +580,21 @@ char *D_FindWADByName(char *name) for (i=0; i<num_iwad_dirs; ++i) { + // As a special case, if this is in DOOMWADDIR or DOOMWADPATH, + // the "directory" may actually refer directly to an IWAD + // file. + + if (DirIsFile(iwad_dirs[i], name) && M_FileExists(iwad_dirs[i])) + { + return strdup(iwad_dirs[i]); + } + // Construct a string for the full path buf = malloc(strlen(iwad_dirs[i]) + strlen(name) + 5); sprintf(buf, "%s%c%s", iwad_dirs[i], DIR_SEPARATOR, name); - exists = M_FileExists(buf); - - if (exists) + if (M_FileExists(buf)) { return buf; } diff --git a/src/g_game.c b/src/g_game.c index 8255fdd0..542c1a7d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -650,10 +650,20 @@ void G_BuildTiccmd (ticcmd_t* cmd) if (lowres_turn) { - // round angleturn to the nearest 256 boundary + static signed short carry = 0; + signed short desired_angleturn; + + desired_angleturn = cmd->angleturn + carry; + + // round angleturn to the nearest 256 unit boundary // for recording demos with single byte values for turn - cmd->angleturn = (cmd->angleturn + 128) & 0xff00; + cmd->angleturn = (desired_angleturn + 128) & 0xff00; + + // Carry forward the error from the reduced resolution to the + // next tic, so that successive small movements can accumulate. + + carry = desired_angleturn - cmd->angleturn; } } diff --git a/src/hu_stuff.c b/src/hu_stuff.c index 0ab750fb..9f86c0b9 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -50,9 +50,9 @@ // Locally used constants, shortcuts. // #define HU_TITLE (mapnames[(gameepisode-1)*9+gamemap-1]) -#define HU_TITLE2 (mapnames2[gamemap-1]) -#define HU_TITLEP (mapnamesp[gamemap-1]) -#define HU_TITLET (mapnamest[gamemap-1]) +#define HU_TITLE2 (mapnames_commercial[gamemap-1]) +#define HU_TITLEP (mapnames_commercial[gamemap-1 + 32]) +#define HU_TITLET (mapnames_commercial[gamemap-1 + 64]) #define HU_TITLE_CHEX (mapnames[gamemap - 1]) #define HU_TITLEHEIGHT 1 #define HU_TITLEX 0 @@ -171,8 +171,16 @@ char* mapnames[] = // DOOM shareware/registered/retail (Ultimate) names. "NEWLEVEL" }; -char* mapnames2[] = // DOOM 2 map names. +// List of names for levels in commercial IWADs +// (doom2.wad, plutonia.wad, tnt.wad). These are stored in a +// single large array; WADs like pl2.wad have a MAP33, and rely on +// the layout in the Vanilla executable, where it is possible to +// overflow the end of one array into the next. + +char *mapnames_commercial[] = { + // DOOM 2 map names. + HUSTR_1, HUSTR_2, HUSTR_3, @@ -206,12 +214,10 @@ char* mapnames2[] = // DOOM 2 map names. HUSTR_29, HUSTR_30, HUSTR_31, - HUSTR_32 -}; + HUSTR_32, + // Plutonia WAD map names. -char* mapnamesp[] = // Plutonia WAD map names. -{ PHUSTR_1, PHUSTR_2, PHUSTR_3, @@ -245,12 +251,10 @@ char* mapnamesp[] = // Plutonia WAD map names. PHUSTR_29, PHUSTR_30, PHUSTR_31, - PHUSTR_32 -}; - + PHUSTR_32, + + // TNT WAD map names. -char *mapnamest[] = // TNT WAD map names. -{ THUSTR_1, THUSTR_2, THUSTR_3, diff --git a/src/i_video.c b/src/i_video.c index 481ee0ea..6936532d 100644 --- a/src/i_video.c +++ b/src/i_video.c @@ -402,6 +402,7 @@ void I_ShutdownGraphics(void) { if (initialized) { + SDL_SetCursor(cursors[1]); SDL_ShowCursor(1); SDL_WM_GrabInput(SDL_GRAB_OFF); diff --git a/src/p_map.c b/src/p_map.c index 89f8f3f8..b50fff2c 100644 --- a/src/p_map.c +++ b/src/p_map.c @@ -885,7 +885,17 @@ PTR_AimTraverse (intercept_t* in) dist = FixedMul (attackrange, in->frac); - if (li->frontsector->floorheight != li->backsector->floorheight) + // Return false if there is no back sector. This should never + // be the case if the line is two-sided; however, some WADs + // (eg. ottawau.wad) use this as an "impassible glass" trick + // and rely on Vanilla Doom's (unintentional) support for this. + + if (li->backsector == NULL) + { + return false; + } + + if (li->frontsector->floorheight != li->backsector->floorheight) { slope = FixedDiv (openbottom - shootz , dist); if (slope > bottomslope) @@ -973,7 +983,14 @@ boolean PTR_ShootTraverse (intercept_t* in) dist = FixedMul (attackrange, in->frac); - if (li->frontsector->floorheight != li->backsector->floorheight) + // Check if backsector is NULL. See comment in PTR_AimTraverse. + + if (li->backsector == NULL) + { + goto hitline; + } + + if (li->frontsector->floorheight != li->backsector->floorheight) { slope = FixedDiv (openbottom - shootz , dist); if (slope > aimslope) diff --git a/src/p_setup.c b/src/p_setup.c index 5cf7a628..2a3a8f85 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -167,6 +167,7 @@ void P_LoadSegs (int lump) line_t* ldef; int linedef; int side; + int sidenum; numsegs = W_LumpLength (lump) / sizeof(mapseg_t); segs = Z_Malloc (numsegs*sizeof(seg_t),PU_LEVEL,0); @@ -179,7 +180,7 @@ void P_LoadSegs (int lump) { li->v1 = &vertexes[SHORT(ml->v1)]; li->v2 = &vertexes[SHORT(ml->v2)]; - + li->angle = (SHORT(ml->angle))<<16; li->offset = (SHORT(ml->offset))<<16; linedef = SHORT(ml->linedef); @@ -188,10 +189,28 @@ void P_LoadSegs (int lump) side = SHORT(ml->side); li->sidedef = &sides[ldef->sidenum[side]]; li->frontsector = sides[ldef->sidenum[side]].sector; - if (ldef-> flags & ML_TWOSIDED) - li->backsector = sides[ldef->sidenum[side^1]].sector; - else + + if (ldef-> flags & ML_TWOSIDED) + { + sidenum = ldef->sidenum[side ^ 1]; + + // If the sidenum is out of range, this may be a "glass hack" + // impassible window. Point at side #0 (this may not be + // the correct Vanilla behavior; however, it seems to work for + // OTTAWAU.WAD, which is the one place I've seen this trick + // used). + + if (sidenum < 0 || sidenum >= numsides) + { + sidenum = 0; + } + + li->backsector = sides[sidenum].sector; + } + else + { li->backsector = 0; + } } W_ReleaseLumpNum(lump); diff --git a/src/p_sight.c b/src/p_sight.c index e192567b..79c1bb1d 100644 --- a/src/p_sight.c +++ b/src/p_sight.c @@ -173,7 +173,7 @@ boolean P_CrossSubsector (int num) continue; line->validcount = validcount; - + v1 = line->v1; v2 = line->v2; s1 = P_DivlineSide (v1->x,v1->y, &strace); @@ -194,6 +194,14 @@ boolean P_CrossSubsector (int num) if (s1 == s2) continue; + // Backsector may be NULL if this is an "impassible + // glass" hack line. + + if (line->backsector == NULL) + { + return false; + } + // stop because it is not two sided anyway // might do this after updating validcount? if ( !(line->flags & ML_TWOSIDED) ) diff --git a/src/st_stuff.c b/src/st_stuff.c index f92d2dda..d48609b4 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -259,9 +259,6 @@ // Height, in lines. #define ST_OUTHEIGHT 1 -#define ST_MAPWIDTH \ - (strlen(mapnames[(gameepisode-1)*9+(gamemap-1)])) - #define ST_MAPTITLEX \ (SCREENWIDTH - ST_MAPWIDTH * ST_CHATFONTWIDTH) @@ -418,10 +415,6 @@ cheatseq_t cheat_clev = CHEAT("idclev", 2); cheatseq_t cheat_mypos = CHEAT("idmypos", 0); -// -extern char* mapnames[]; - - // // STATUS BAR CODE // @@ -981,6 +974,17 @@ void ST_doPaletteStuff(void) else palette = 0; + // In Chex Quest, the player never sees red. Instead, the + // radiation suit palette is used to tint the screen green, + // as though the player is being covered in goo by an + // attacking flemoid. + + if (gameversion == exe_chex + && palette >= STARTREDPALS && palette < STARTREDPALS + NUMREDPALS) + { + palette = RADIATIONPAL; + } + if (palette != st_palette) { st_palette = palette; diff --git a/textscreen/.gitignore b/textscreen/.gitignore index 6f6e5b3b..3be8ec0c 100644 --- a/textscreen/.gitignore +++ b/textscreen/.gitignore @@ -2,3 +2,5 @@ Makefile Makefile.in .deps *.a +tags +TAGS diff --git a/textscreen/examples/.gitignore b/textscreen/examples/.gitignore index b75bfc6b..cb0fd52c 100644 --- a/textscreen/examples/.gitignore +++ b/textscreen/examples/.gitignore @@ -4,3 +4,5 @@ Makefile guitest calculator *.exe +tags +TAGS diff --git a/textscreen/txt_sdl.c b/textscreen/txt_sdl.c index cd7dd77d..0df9fc93 100644 --- a/textscreen/txt_sdl.c +++ b/textscreen/txt_sdl.c @@ -285,10 +285,10 @@ void TXT_UpdateScreenArea(int x, int y, int w, int h) int x_end; int y_end; - x_end = LimitToRange(x + w, 0, TXT_SCREEN_W - 1); - y_end = LimitToRange(y + h, 0, TXT_SCREEN_H - 1); - x = LimitToRange(x, 0, TXT_SCREEN_W - 1); - y = LimitToRange(y, 0, TXT_SCREEN_H - 1); + x_end = LimitToRange(x + w, 0, TXT_SCREEN_W); + y_end = LimitToRange(y + h, 0, TXT_SCREEN_H); + x = LimitToRange(x, 0, TXT_SCREEN_W); + y = LimitToRange(y, 0, TXT_SCREEN_H); for (y1=y; y1<y_end; ++y1) { diff --git a/wince/.gitignore b/wince/.gitignore new file mode 100644 index 00000000..d4e88e5a --- /dev/null +++ b/wince/.gitignore @@ -0,0 +1,5 @@ +Makefile +Makefile.in +.deps +tags +TAGS diff --git a/wince/Makefile.am b/wince/Makefile.am index 476b9a67..c19471ca 100644 --- a/wince/Makefile.am +++ b/wince/Makefile.am @@ -4,6 +4,7 @@ noinst_LIBRARIES=libc_wince.a if WINDOWS_CE libc_wince_a_SOURCES = \ + libc_wince.h \ env.c env.h \ errno.c errno.h \ fileops.c fileops.h |