28#import "MyOpenGLView.h"
49#import <Sparkle/Sparkle.h>
54#elif (OOLITE_GNUSTEP && !defined(NDEBUG))
62@interface GameController (OOPrivate)
64- (void)reportUnhandledStartupException:(NSException *)exception;
88 [
NSException raise:NSInternalInconsistencyException format:@"%s: expected only one GameController to exist at a time.", __PRETTY_FUNCTION__];
91 if ((
self = [super
init]))
99 ranrot_srand((uint32_t)[[NSDate date] timeIntervalSince1970]);
111 [[[
NSWorkspace sharedWorkspace] notificationCenter] removeObserver:UNIVERSE];
118 [playerFileToLoad release];
119 [playerFileDirectory release];
120 [expansionPathsToInclude release];
132- (void) setGamePaused:(BOOL)value
139 [PLAYER doScriptEvent:OOJSID("gamePaused")];
145 [PLAYER doScriptEvent:OOJSID("gameResumed")];
132- (void) setGamePaused:(BOOL)value {
…}
159 if (
mode == oldMode)
return;
164#if OO_USE_FULLSCREEN_CONTROLLER
179 [
self setMouseInteractionMode:[PLAYER isMouseControlOn] ? MOUSE_MODE_FLIGHT_WITH_MOUSE_CONTROL : MOUSE_MODE_FLIGHT_NO_MOUSE_CONTROL];
183- (void) setMouseInteractionModeForUIWithMouseInteraction:(BOOL)interaction
185 [
self setMouseInteractionMode:interaction ? MOUSE_MODE_UI_SCREEN_WITH_INTERACTION : MOUSE_MODE_UI_SCREEN_NO_INTERACTION];
183- (void) setMouseInteractionModeForUIWithMouseInteraction:(BOOL)interaction {
…}
200 [UNIVERSE setGameView:gameView];
204- (void) applicationDidFinishLaunching:(NSNotification *)notification
206 NSAutoreleasePool *pool =
nil;
216#if OO_OXP_VERIFIER_ENABLED
241 for (i = 0; i < [expansionPathsToInclude count]; i++)
252 [[
Universe alloc] initWithGameView:gameView];
263 @catch (NSException *exception)
269 OOLog(
@"startup.complete",
@"========== Loading complete in %.2f seconds. ==========", -[
_splashStart timeIntervalSinceNow]);
271#if OO_USE_FULLSCREEN_CONTROLLER
204- (void) applicationDidFinishLaunching:(NSNotification *)notification {
…}
291 [UNIVERSE useGUILightSource:YES];
292 [UNIVERSE useGUILightSource:NO];
293 [PLAYER loadPlayerFromFile:playerFileToLoad asNew:NO];
316- (void) performGameTick:(
id)sender
316- (void) performGameTick:(
id)sender {
…}
324- (void) performGameTick:(
id)sender
326 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
328 [gameView pollControls];
329 [
self doPerformGameTick];
345 delta_t = [
NSDate timeIntervalSinceReferenceDate] - last_timeInterval;
346 last_timeInterval += delta_t;
351 [UNIVERSE update:delta_t];
354 [UNIVERSE reinitAndShowDemo:YES];
362 @catch (
id exception)
364 OOLog(
@"exception.backtrace",
@"%@",[exception callStackSymbols]);
371 @catch (
id exception) {}
381 timer = [[
NSTimer timerWithTimeInterval:ti target:
self selector:@selector(performGameTick:) userInfo:nil repeats:YES] retain];
383 [[
NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
385 [[
NSRunLoop currentRunLoop] addTimer:timer forMode:NSEventTrackingRunLoopMode];
409 [
gameView setVirtualJoystick:0.0 :0.0];
413- (IBAction) showLogAction:sender
415 [[
NSWorkspace sharedWorkspace] openFile:[OOLogHandlerGetLogBasePath() stringByAppendingPathComponent:@"Previous.log"]];
413- (IBAction) showLogAction:sender {
…}
419- (IBAction) showLogFolderAction:sender
421 [[
NSWorkspace sharedWorkspace] openFile:OOLogHandlerGetLogBasePath()];
419- (IBAction) showLogFolderAction:sender {
…}
428 id result = [[
NSUserDefaults standardUserDefaults] objectForKey:key];
429 if (expectedClass != Nil && ![result isKindOfClass:expectedClass]) result =
nil;
437 [[
NSUserDefaults standardUserDefaults] setObject:value forKey:key];
447#define kSnapshotsDirRefKey @"snapshots-directory-reference"
448#define kSnapshotsDirNameKey @"snapshots-directory-name"
450- (NSURL *) snapshotsURLCreatingIfNeeded:(BOOL)create
455 NSString *name =
DESC(
@"snapshots-directory-name-mac");
457 if (snapshotDirDict !=
nil)
462 NSString *existingName = [[
url path] lastPathComponent];
463 if ([existingName compare:name options:NSCaseInsensitiveSearch] != 0)
467 if (originalOldName ==
nil || [existingName compare:originalOldName options:NSCaseInsensitiveSearch] != 0)
474 Boolean inTrash =
false;
475 const UInt8 *utfPath = (
const UInt8 *)[[url path] UTF8String];
477 OSStatus err = DetermineIfPathIsEnclosedByFolder(kOnAppropriateDisk, kTrashFolderType, utfPath,
false, &inTrash);
479 if (err == noErr && inTrash ==
true) url =
nil;
485 NSString *path =
nil;
486 NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDesktopDirectory, NSUserDomainMask, YES);
487 if ([searchPaths
count] > 0)
489 path = [[
searchPaths objectAtIndex:0] stringByAppendingPathComponent:name];
491 url = [
NSURL fileURLWithPath:path];
499 if (![fmgr fileExistsAtPath:path])
501 [
fmgr oo_createDirectoryAtPath:path attributes:nil];
510 if (snapshotDirDict !=
nil)
450- (NSURL *) snapshotsURLCreatingIfNeeded:(BOOL)create {
…}
525- (IBAction) showSnapshotsAction:sender
525- (IBAction) showSnapshotsAction:sender {
…}
531- (IBAction) showAddOnsAction:sender
536 for (NSString *path in paths) {
537 if ([
self addOnsExistAtPath:path]) {
544 for (NSString *path in paths) {
545 if ([
self isDirectoryAtPath:path]) {
553 withIntermediateDirectories:YES
531- (IBAction) showAddOnsAction:sender {
…}
560- (BOOL) isDirectoryAtPath:(NSString *)path
560- (BOOL) isDirectoryAtPath:(NSString *)path {
…}
567- (BOOL) addOnsExistAtPath:(NSString *)path
569 if (![
self isDirectoryAtPath:path])
return NO;
571 NSWorkspace *workspace = NSWorkspace.sharedWorkspace;
572 for (NSString *subPath in [NSFileManager.defaultManager enumeratorAtPath:path]) {
573 subPath = [
path stringByAppendingPathComponent:subPath];
574 NSString *type = [
workspace typeOfFile:subPath error:NULL];
575 if ([workspace type:type conformsToType:
@"org.aegidian.oolite.expansion"])
return YES;
567- (BOOL) addOnsExistAtPath:(NSString *)path {
…}
582- (void) openPath:(NSString *)path
582- (void) openPath:(NSString *)path {
…}
588- (BOOL) validateMenuItem:(NSMenuItem *)menuItem
590 SEL action = menuItem.action;
592 if (action ==
@selector(showLogAction:))
595 return ([[NSFileManager defaultManager] fileExistsAtPath:[
OOLogHandlerGetLogBasePath() stringByAppendingPathComponent:
@"Previous.log"]]);
598 if (action ==
@selector(showAddOnsAction:))
604 if (action ==
@selector(showSnapshotsAction:))
606 BOOL pathIsDirectory;
607 if(![[NSFileManager defaultManager] fileExistsAtPath:[
self snapshotsURLCreatingIfNeeded:NO].path isDirectory:&pathIsDirectory])
611 return pathIsDirectory;
614 if (action ==
@selector(toggleFullScreenAction:))
619 menuItem.title = NSLocalizedString(
@"Exit Full Screen", NULL);
623 menuItem.title = NSLocalizedString(
@"Enter Full Screen", NULL);
588- (BOOL) validateMenuItem:(NSMenuItem *)menuItem {
…}
632- (NSMenu *)applicationDockMenu:(NSApplication *)sender
632- (NSMenu *)applicationDockMenu:(NSApplication *)sender {
…}
639- (NSURL *) snapshotsURLCreatingIfNeeded:(BOOL)create
641 NSURL *url = [NSURL fileURLWithPath:[NSHomeDirectory() stringByAppendingPathComponent:DESC(@"snapshots-directory-name")]];
645 NSString *path = [url path];
646 NSFileManager *fmgr = [NSFileManager defaultManager];
647 if (![fmgr fileExistsAtPath:path])
649 [fmgr createDirectoryAtPath:path attributes:nil];
656 #error Unknown environment!
659- (void) logProgress:(NSString *)message
661 if (![
UNIVERSE doingStartUp])
return;
664 [splashProgressTextField setStringValue:message];
665 [splashProgressTextField display];
667 if([message length] > 0)
669 OOLog(
@"startup.progress",
@"===== [%.2f s] %@", -[
_splashStart timeIntervalSinceNow], message);
659- (void) logProgress:(NSString *)message {
…}
676- (BOOL) debugMessageTrackingIsOn
678 return splashProgressTextField !=
nil;
682- (NSString *) debugMessageCurrentString
684 return [splashProgressTextField stringValue];
687- (BOOL) debugMessageTrackingIsOn
693- (NSString *) debugMessageCurrentString
699- (void) debugLogProgress:(NSString *)format, ...
702 va_start(args, format);
703 [
self debugLogProgress:format arguments:args];
708- (void) debugLogProgress:(NSString *)format arguments:(va_list)arguments
710 NSString *message = [[[NSString alloc] initWithFormat:format arguments:arguments] autorelease];
711 [
self logProgress:message];
715static NSMutableArray *sMessageStack;
717- (void) debugPushProgressMessage:(NSString *)format, ...
719 if ([
self debugMessageTrackingIsOn])
721 if (sMessageStack ==
nil) sMessageStack = [[NSMutableArray alloc] init];
722 [sMessageStack addObject:[
self debugMessageCurrentString]];
725 va_start(args, format);
726 [
self debugLogProgress:format arguments:args];
734- (void) debugPopProgressMessage
738 if ([sMessageStack
count] > 0)
740 NSString *message = [sMessageStack lastObject];
741 if ([message length] > 0) [
self logProgress:message];
742 [sMessageStack removeLastObject];
772 NSString *path =
nil;
775 path = [[
NSBundle mainBundle] pathForResource:@"OoliteReadMe" ofType:@"pdf"];
778 PDFDocument *document = [[
PDFDocument alloc] initWithURL:[
NSURL fileURLWithPath:path]];
787- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
789 if ([[
filename pathExtension] isEqual:
@"oolite-save"])
795 if ([[
filename pathExtension] isEqualToString:
@"oxp"])
798 [[
NSFileManager defaultManager] fileExistsAtPath:filename isDirectory:&dir_test];
805 [expansionPathsToInclude addObject:filename];
787- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename {
…}
813- (void) exitAppWithContext:(NSString *)context
817 [
NSApp terminate:
self];
813- (void) exitAppWithContext:(NSString *)context {
…}
821- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
825 return NSTerminateNow;
821- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
…}
830- (void) exitAppWithContext:(NSString *)context
832 OOLog(
@"exit.context",
@"Exiting: %@.", context);
833#if (OOLITE_GNUSTEP && !defined(NDEBUG))
839 if (![gameView atDesktopResolution])
841 OOLog(
@"gameController.exitApp",
@"%@",
@"Restoring desktop resolution.");
842 ChangeDisplaySettingsEx(NULL, NULL, NULL, 0, NULL);
845 [[NSUserDefaults standardUserDefaults] synchronize];
846 OOLog(
@"gameController.exitApp",
@"%@",
@".GNUstepDefaults synchronized.");
854 #error Unknown environment!
864- (void)windowDidResize:(NSNotification *)aNotification
864- (void)windowDidResize:(NSNotification *)aNotification {
…}
876- (void) setPlayerFileToLoad:(NSString *)filename
879 [playerFileToLoad autorelease];
881 if ([[[
filename pathExtension] lowercaseString] isEqual:
@"oolite-save"])
876- (void) setPlayerFileToLoad:(NSString *)filename {
…}
897 [playerFileDirectory retain];
904- (void) setPlayerFileDirectory:(NSString *)filename
908 [playerFileDirectory autorelease];
912 if ([[[
filename pathExtension] lowercaseString] isEqual:
@"oolite-save"])
914 filename = [filename stringByDeletingLastPathComponent];
918 [[
NSUserDefaults standardUserDefaults] setObject:filename forKey:@"save-directory"];
904- (void) setPlayerFileDirectory:(NSString *)filename {
…}
922- (void)reportUnhandledStartupException:(NSException *)exception
924 OOLog(
@"startup.exception",
@"***** Unhandled exception during startup: %@ (%@).", [exception name], [exception reason]);
929 NSRunCriticalAlertPanel(
@"Oolite failed to start up, because an unhandled exception occurred.",
@"An exception of type %@ occurred. If this problem persists, please file a bug report.",
@"OK", NULL, NULL, [exception name]);
922- (void)reportUnhandledStartupException:(NSException *)exception {
…}
934- (void)setUpBasicOpenGLStateWithSize:(NSSize)viewSize
939 float aspect = viewSize.height/viewSize.width;
941 OOGL(glClearColor(0.0, 0.0, 0.0, 0.0));
942 OOGL(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
944 OOGL(glClearDepth(1.0));
945 OOGL(glViewport(0, 0, viewSize.width, viewSize.height));
950 OOGL(glDepthFunc(GL_LESS));
954 [UNIVERSE setLighting];
958 GLfloat black[4] = {0.0, 0.0, 0.0, 1.0};
959 GLfloat white[] = {1.0, 1.0, 1.0, 1.0};
960 GLfloat stars_ambient[] = {0.25, 0.2, 0.25, 1.0};
962 OOGL(glLightfv(GL_LIGHT1, GL_AMBIENT, black));
963 OOGL(glLightfv(GL_LIGHT1, GL_SPECULAR, white));
964 OOGL(glLightfv(GL_LIGHT1, GL_DIFFUSE, white));
965 OOGL(glLightfv(GL_LIGHT1, GL_POSITION, black));
966 OOGL(glLightModelfv(GL_LIGHT_MODEL_AMBIENT, stars_ambient));
970 if ([extMgr usePointSmoothing])
OOGL(glEnable(GL_POINT_SMOOTH));
971 if ([extMgr useLineSmoothing])
OOGL(glEnable(GL_LINE_SMOOTH));
974#if GL_APPLE_transform_hint
975 if ([extMgr haveExtension:
@"GL_APPLE_transform_hint"])
977 OOGL(glHint(GL_TRANSFORM_HINT_APPLE, GL_FASTEST));
981 OOGL(glDisable(GL_NORMALIZE));
982 OOGL(glDisable(GL_RESCALE_NORMAL));
986 if ([extMgr versionIsAtLeastMajor:1 minor:2])
988 OOGL(glLightModeli(GL_LIGHT_MODEL_COLOR_CONTROL, GL_SEPARATE_SPECULAR_COLOR));
934- (void)setUpBasicOpenGLStateWithSize:(NSSize)viewSize {
…}
1012#define FEED_URL_BASE "http://www.oolite.org/updates/"
1013#define TEST_RELEASE_FEED_NAME "oolite-mac-test-release-appcast.xml"
1014#define DEPLOYMENT_FEED_NAME "oolite-mac-appcast.xml"
1016#define TEST_RELEASE_FEED_URL (@ FEED_URL_BASE TEST_RELEASE_FEED_NAME)
1017#define DEPLOYMENT_FEED_URL (@ FEED_URL_BASE DEPLOYMENT_FEED_NAME)
1021#define DEFAULT_TEST_RELEASE 0
1023#define DEFAULT_TEST_RELEASE 1
1026 BOOL useTestReleases = [[NSUserDefaults standardUserDefaults] oo_boolForKey:@"use-test-release-updates"
1027 defaultValue:DEFAULT_TEST_RELEASE];
1029 SUUpdater *updater = [SUUpdater sharedUpdater];
1030 [updater setFeedURL:[NSURL URLWithString:useTestReleases ? TEST_RELEASE_FEED_URL : DEPLOYMENT_FEED_URL]];
#define MINIMUM_GAME_TICK
static GameController * sSharedController
#define kSnapshotsDirNameKey
#define kSnapshotsDirRefKey
static void SetUpSparkle(void)
@ kJAPersistentFileReferenceWithoutUI
@ kJAPersistentFileReferenceWithoutMounting
NSURL * JAURLFromPersistentFileReference(NSDictionary *fileRef, JAPersistentFileReferenceResolveFlags flags, BOOL *isStale)
NSDictionary * JAPersistentFileReferenceFromURL(NSURL *url)
void OOJSFrameCallbacksInvoke(OOTimeDelta delta)
NSString * OOLogHandlerGetLogBasePath(void)
BOOL OOLogWillDisplayMessagesInClass(NSString *inMessageClass)
#define OOLogOutdentIf(class)
#define OOLog(class, format,...)
#define OOLogIndentIf(class)
void OOLoggingTerminate(void)
void OOLogSetDisplayMessagesInClass(NSString *inClass, BOOL inFlag)
NSString * OOStringFromMouseInteractionMode(OOMouseInteractionMode mode)
void OOGLFrustum(double left, double right, double bottom, double top, double near, double far)
void OOGLResetProjection(void)
void setMouseInteractionMode:(OOMouseInteractionMode mode)
void setMouseInteractionModeForUIWithMouseInteraction:(BOOL interaction)
IBOutlet NSTextField * splashProgressTextField
static id GetPreference(NSString *key, Class expectedClass)
OOMouseInteractionMode mouseInteractionMode()
NSString * playerFileToLoad
BOOL suppressClangStuff()
GameController * sharedController()
NSMutableArray * expansionPathsToInclude
OOMouseInteractionMode _resumeMode
NSTimeInterval last_timeInterval
void recenterVirtualJoystick()
NSString * playerFileDirectory
void stopAnimationTimer()
void reportUnhandledStartupException:(NSException *exception)
void openPath:(NSString *path)
void logProgress:(NSString *message)
NSTimeInterval _animationTimerInterval
void exitAppWithContext:(NSString *context)
static void SetPreference(NSString *key, id value)
OOMouseInteractionMode _mouseMode
void setPlayerFileDirectory:(NSString *filename)
void setMouseInteractionModeForFlight()
void startAnimationTimer()
void setFullScreenMode:(BOOL value)
NSURL * snapshotsURLCreatingIfNeeded:(BOOL create)
IBOutlet MyOpenGLView * gameView
void loadPlayerIfRequired()
static void RemovePreference(NSString *key)
void setPlayerFileToLoad:(NSString *filename)
IBOutlet NSView * splashView
OOFullScreenController * _fullScreenController
IBOutlet NSMenu * dockMenu
void noteMouseInteractionModeChangedFrom:to:(OOMouseInteractionMode oldMode,[to] OOMouseInteractionMode newMode)
void setGameController:(GameController *controller)
void finishOngoingFlush()
OOCacheManager * sharedCache()
OODebugMonitor * sharedDebugMonitor()
void noteMouseInteractionModeChangedFrom:to:(OOMouseInteractionMode oldMode,[to] OOMouseInteractionMode newMode)
BOOL setStickHandlerClass:(Class aClass)
OOOXZManager * sharedManager()
OOOpenALController * sharedController()
OOOpenGLExtensionManager * sharedManager()
void setExitContext:(NSString *exitContext)
void addExternalPath:(NSString *fileName)
NSArray * userRootPaths()
void ranrot_srand(uint32_t seed)