390 lines
9.2 KiB
Mathematica
390 lines
9.2 KiB
Mathematica
|
//
|
||
|
// Copyright(C) 2005-2014 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.
|
||
|
//
|
||
|
|
||
|
#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;
|
||
|
char *executable_name;
|
||
|
const char *game_name;
|
||
|
|
||
|
[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;
|
||
|
}
|
||
|
|
||
|
game_name = [self->iwadController getGameName];
|
||
|
asprintf(&executable_name, "%s%s", PROGRAM_PREFIX, game_name);
|
||
|
|
||
|
ExecuteProgram(executable_name, [iwad UTF8String],
|
||
|
[args UTF8String]);
|
||
|
[NSApp terminate:sender];
|
||
|
}
|
||
|
|
||
|
// Invoked when the "Setup Tool" button is clicked, to run the setup tool:
|
||
|
|
||
|
- (void) runSetup: (id)sender
|
||
|
{
|
||
|
const char *game_name;
|
||
|
char *arg;
|
||
|
|
||
|
[self saveConfig];
|
||
|
[self->iwadController setEnvironment];
|
||
|
|
||
|
// Provide the -game command line parameter to select the game
|
||
|
// to configure, based on the game selected in the dropdown.
|
||
|
|
||
|
game_name = [self->iwadController getGameName];
|
||
|
asprintf(&arg, "-game %s", game_name);
|
||
|
|
||
|
ExecuteProgram(PROGRAM_PREFIX "setup", NULL, arg);
|
||
|
|
||
|
free(arg);
|
||
|
}
|
||
|
|
||
|
// 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) openREADME: (id) sender
|
||
|
{
|
||
|
OpenDocumentation("README");
|
||
|
}
|
||
|
|
||
|
- (void) openINSTALL: (id) sender
|
||
|
{
|
||
|
OpenDocumentation("INSTALL");
|
||
|
}
|
||
|
|
||
|
- (void) openCMDLINE: (id) sender
|
||
|
{
|
||
|
const char *game_name;
|
||
|
char filename[32];
|
||
|
|
||
|
// We need to open the appropriate doc file for the currently
|
||
|
// selected game.
|
||
|
|
||
|
game_name = [self->iwadController getGameName];
|
||
|
snprintf(filename, sizeof(filename), "CMDLINE-%s", game_name);
|
||
|
|
||
|
OpenDocumentation(filename);
|
||
|
}
|
||
|
|
||
|
- (void) openCOPYING: (id) sender
|
||
|
{
|
||
|
OpenDocumentation("COPYING");
|
||
|
}
|
||
|
|
||
|
- (void) openDocumentation: (id) sender
|
||
|
{
|
||
|
OpenDocumentation("");
|
||
|
}
|
||
|
|
||
|
- (void) awakeFromNib
|
||
|
{
|
||
|
[self->launcherWindow setTitle: @PACKAGE_NAME " Launcher"];
|
||
|
[self->launcherWindow center];
|
||
|
[self->launcherWindow setDefaultButtonCell: [self->launchButton cell]];
|
||
|
[self setConfig];
|
||
|
}
|
||
|
|
||
|
- (BOOL) addIWADPath: (NSString *) path
|
||
|
{
|
||
|
return [self->iwadController addIWADPath: path];
|
||
|
}
|
||
|
|
||
|
- (BOOL) selectGameByName: (const char *) name
|
||
|
{
|
||
|
return [self->iwadController selectGameByName: name];
|
||
|
}
|
||
|
|
||
|
@end
|
||
|
|