shithub: choc

Download patch

ref: 6921f30a44e0bdf1c3a2f8982e4a8cd290c22462
parent: 9b0b0629e02deba1788d4a4e190b31977f7c0b1f
author: Simon Howard <[email protected]>
date: Mon Jan 4 17:01:32 EST 2010

Import OS X launcher code to trunk.

Subversion-branch: /trunk/chocolate-doom
Subversion-revision: 1784

--- /dev/null
+++ b/pkg/osx/AppController.h
@@ -1,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_APPCONTROLLER_H
+#define LAUNCHER_APPCONTROLLER_H
+
+#include <AppKit/AppKit.h>
+// Uncomment if your application is Renaissance-based
+//#include <Renaissance/Renaissance.h>
+
+@interface AppController : NSObject
+{
+}
+
++ (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
+
--- /dev/null
+++ b/pkg/osx/AppController.m
@@ -1,0 +1,87 @@
+/* ... */
+//-----------------------------------------------------------------------------
+//
+// 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"
+
+@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]))
+    {
+    }
+
+    return self;
+}
+
+- (void)dealloc
+{
+    [super dealloc];
+}
+
+- (void)awakeFromNib
+{
+    [[NSApp mainMenu] setTitle:@"ChocolateDoom"];
+}
+
+- (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
+{
+    return NO;
+}
+
+- (void)showPrefPanel:(id)sender
+{
+}
+
+@end
+
--- /dev/null
+++ b/pkg/osx/Execute.h
@@ -1,0 +1,30 @@
+/* ... */
+//-----------------------------------------------------------------------------
+//
+// 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);
+
+#endif /* #ifndef LAUNCHER_EXECUTE_H */
+
--- /dev/null
+++ b/pkg/osx/Execute.m
@@ -1,0 +1,111 @@
+/* ... */
+//-----------------------------------------------------------------------------
+//
+// 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/types.h>
+#include <sys/wait.h>
+
+#define RESPONSE_FILE "/tmp/launcher.rsp"
+
+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);
+    }
+}
+
--- /dev/null
+++ b/pkg/osx/GNUmakefile
@@ -1,0 +1,52 @@
+
+include config.make
+
+STAGING_DIR=staging
+DMG=$(PACKAGE_TARNAME)-$(PACKAGE_VERSION).dmg
+
+# DMG file containing package:
+
+$(DMG) : $(STAGING_DIR)
+	rm -f $@
+	hdiutil create -volname "$(PACKAGE_STRING)" -srcdir $(STAGING_DIR) $@
+
+clean : launcher_clean
+	rm -f $(DMG)
+	rm -rf $(STAGING_DIR)
+
+# Staging dir build for package:
+
+APP_DIR=$(STAGING_DIR)/$(PACKAGE_NAME).app
+
+$(STAGING_DIR): launcher
+	rm -rf $(STAGING_DIR)
+	mkdir $(STAGING_DIR)
+	cp -R app-skeleton "$(APP_DIR)"
+	cp Info.plist "$(APP_DIR)/Contents/"
+	cp launcher "$(APP_DIR)/Contents/MacOS/"
+	# TODO: copy Doom and setup binaries into app dir
+	# TODO: copy other documentation into staging dir
+	find $(STAGING_DIR) -name .svn -delete -exec rm -rf {} \;
+
+# Launcher build:
+
+CFLAGS=-Wall
+LDFLAGS=-framework Cocoa
+
+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
+
--- /dev/null
+++ b/pkg/osx/IWADController.h
@@ -1,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_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;
+- (void) setEnvironment;
+
+@end
+
+#endif /* #ifndef LAUNCHER_IWADCONTROLLER_H */
+
--- /dev/null
+++ b/pkg/osx/IWADController.m
@@ -1,0 +1,329 @@
+/* ... */
+//-----------------------------------------------------------------------------
+//
+// 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
+{
+    // Set configuration for all IWADs from configuration file.
+
+    [self setIWADConfig];
+
+    // Populate the dropdown IWAD list, and open the configuration
+    // dialog if not yet configured.
+
+    if ([self setDropdownList])
+    {
+        [self setDropdownSelection];
+    }
+    else
+    {
+        [self openConfigWindow: nil];
+    }
+}
+
+// Set the DOOMWADPATH environment variable to contain the path to each
+// of the configured IWAD files.
+
+- (void) setEnvironment
+{
+    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 = 30;
+
+    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, "DOOMWADPATH=");
+
+    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;
+        }
+    }
+
+    // Load into environment:
+
+    putenv(env);
+
+    //free(env);
+}
+
+@end
+
--- /dev/null
+++ b/pkg/osx/IWADLocation.h
@@ -1,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 */
+
--- /dev/null
+++ b/pkg/osx/IWADLocation.m
@@ -1,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
+
--- /dev/null
+++ b/pkg/osx/Info.plist
@@ -1,0 +1,32 @@
+<?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">
+<!-- This is a temporary Info.plist file that will be removed.
+     It will eventually be generated by configure. -->
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleDisplayName</key>
+	<string>Cocoa Doom</string>
+	<key>CFBundleExecutable</key>
+	<string>launcher</string>
+	<key>CFBundleGetInfoString</key>
+	<string>Cocoa Doom 1.2.1</string>
+	<key>CFBundleIconFile</key>
+	<string>app.icns</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>Cocoa Doom</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>1.2.1</string>
+	<key>CFBundleVersion</key>
+	<string>1.2.1</string>
+	<key>NSPrincipalClass</key>
+	<string>NSApplication</string>
+	<key>NSMainNibFile</key>
+	<string>launcher</string>
+</dict>
+</plist>
--- /dev/null
+++ b/pkg/osx/Info.plist.in
@@ -1,0 +1,30 @@
+<?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>
+</dict>
+</plist>
--- /dev/null
+++ b/pkg/osx/LauncherManager.h
@@ -1,0 +1,47 @@
+/* ... */
+//-----------------------------------------------------------------------------
+//
+// 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;
+
+@end
+
+#endif /* #ifndef LAUNCHER_LAUNCHERMANAGER_H */
+
--- /dev/null
+++ b/pkg/osx/LauncherManager.m
@@ -1,0 +1,98 @@
+/* ... */
+//-----------------------------------------------------------------------------
+//
+// 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];
+    }
+}
+
+- (void) launch: (id)sender
+{
+    NSString *iwad;
+    NSString *args;
+
+    [self saveConfig];
+
+    iwad = [self->iwadController getIWADLocation];
+    args = [self->commandLineArguments stringValue];
+
+    if (iwad != nil)
+    {
+        ExecuteProgram(PACKAGE_TARNAME, [iwad UTF8String],
+                                        [args UTF8String]);
+        [NSApp terminate:sender];
+    }
+}
+
+- (void) runSetup: (id)sender
+{
+    [self saveConfig];
+
+    [self->iwadController setEnvironment];
+    ExecuteProgram("chocolate-setup", NULL, NULL);
+}
+
+- (void) awakeFromNib
+{
+    [self->packageLabel setStringValue: @PACKAGE_STRING];
+    [self->launcherWindow setTitle: @PACKAGE_NAME " Launcher"];
+    [self setConfig];
+}
+
+@end
+
--- /dev/null
+++ b/pkg/osx/app-skeleton/Contents/PkgInfo
@@ -1,0 +1,1 @@
+APPL????
binary files /dev/null b/pkg/osx/app-skeleton/Contents/Resources/128x128.png differ
binary files /dev/null b/pkg/osx/app-skeleton/Contents/Resources/app.icns differ
--- /dev/null
+++ b/pkg/osx/app-skeleton/Contents/Resources/launcher.nib/classes.nib
@@ -1,0 +1,40 @@
+{
+    IBClasses = (
+        {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; 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
--- /dev/null
+++ b/pkg/osx/app-skeleton/Contents/Resources/launcher.nib/info.nib
@@ -1,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>172 70 612 260 0 0 1440 878 </string>
+	<key>IBEditorPositions</key>
+	<dict>
+		<key>29</key>
+		<string>108 337 163 44 0 0 1440 878 </string>
+	</dict>
+	<key>IBFramework Version</key>
+	<string>446.1</string>
+	<key>IBOpenObjects</key>
+	<array>
+		<integer>29</integer>
+		<integer>227</integer>
+		<integer>21</integer>
+	</array>
+	<key>IBSystem Version</key>
+	<string>8S2167</string>
+</dict>
+</plist>
binary files /dev/null b/pkg/osx/app-skeleton/Contents/Resources/launcher.nib/keyedobjects.nib differ
--- /dev/null
+++ b/pkg/osx/config.h
@@ -1,0 +1,27 @@
+// Dummy config.h for developing launcher.  Eventually, the launcher
+// will include the top-level config.h for the program.
+
+/* Name of package */
+#define PACKAGE "cocoa-doom"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "[email protected]"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "Cocoa Doom"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "Cocoa Doom 1.2.1"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "cocoa-doom"
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "1.2.1"
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Version number of package */
+#define VERSION "1.2.1"
+
--- /dev/null
+++ b/pkg/osx/config.make
@@ -1,0 +1,10 @@
+# File included by the main makefile that contains details
+# about the package name.  This will eventuall be generated
+# by configure.
+
+PACKAGE = cocoa-doom
+PACKAGE_NAME = Cocoa Doom
+PACKAGE_STRING = Cocoa Doom 1.2.1
+PACKAGE_TARNAME = cocoa-doom
+PACKAGE_VERSION = 1.2.1
+
--- /dev/null
+++ b/pkg/osx/config.make.in
@@ -1,0 +1,9 @@
+# File included by the main makefile that contains details
+# about the package name, generated by configure.
+
+PACKAGE = @PACKAGE@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+
--- /dev/null
+++ b/pkg/osx/main.m
@@ -1,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);
+}
+