LCOV - code coverage report
Current view: top level - Cocoa - MyOpenGLView.m (source / functions) Hit Total Coverage
Test: coverxygen.info Lines: 0 38 0.0 %
Date: 2025-05-28 07:50:54 Functions: 0 0 -

          Line data    Source code
       1           0 : /*
       2             : 
       3             : MyOpenGLView.m
       4             : 
       5             : Oolite
       6             : Copyright (C) 2004-2013 Giles C Williams and contributors
       7             : 
       8             : This program is free software; you can redistribute it and/or
       9             : modify it under the terms of the GNU General Public License
      10             : as published by the Free Software Foundation; either version 2
      11             : of the License, or (at your option) any later version.
      12             : 
      13             : This program is distributed in the hope that it will be useful,
      14             : but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             : GNU General Public License for more details.
      17             : 
      18             : You should have received a copy of the GNU General Public License
      19             : along with this program; if not, write to the Free Software
      20             : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
      21             : MA 02110-1301, USA.
      22             : 
      23             : */
      24             : 
      25             : #import "MyOpenGLView.h"
      26             : 
      27             : #import "GameController.h"
      28             : #import "Universe.h"
      29             : #import "Entity.h"
      30             : #import "OOPlanetEntity.h"
      31             : #import "ResourceManager.h"
      32             : #import "GuiDisplayGen.h"
      33             : #import <Carbon/Carbon.h>
      34             : #import "NSFileManagerOOExtensions.h"
      35             : #import "OOGraphicsResetManager.h"
      36             : #import "PlayerEntity.h"
      37             : 
      38             : #ifndef NDEBUG
      39             : #import <Foundation/NSDebug.h>
      40             : #endif
      41             : 
      42             : 
      43           0 : static NSString * kOOLogKeyCodeOutOfRange       = @"input.keyMapping.codeOutOfRange";
      44           0 : static NSString * kOOLogKeyUp                           = @"input.keyMapping.keyPress.keyUp";
      45           0 : static NSString * kOOLogKeyDown                         = @"input.keyMapping.keyPress.keyDown";
      46             : 
      47             : 
      48           0 : static void GetDesiredCursorState(OOMouseInteractionMode mode, BOOL *outHidden, BOOL *outObscured);
      49           0 : static void ApplyCursorState(OOMouseInteractionMode mode);
      50           0 : static void UnapplyCursorState(OOMouseInteractionMode mode);
      51             : 
      52             : 
      53             : @interface MyOpenGLView(Internal)
      54             : 
      55           0 : - (int) translateKeyCode:(int)input;
      56             : 
      57           0 : - (void) recenterVirtualJoystick;
      58             : 
      59             : @end
      60             : 
      61             : 
      62             : #if !OOLITE_MAC_OS_X_10_7
      63             : @interface NSView (Lion)
      64             : 
      65           0 : - (BOOL) wantsBestResolutionOpenGLSurface;
      66           0 : - (void) setWantsBestResolutionOpenGLSurface:(BOOL)flag;
      67             : 
      68           0 : - (NSPoint) convertPointToBacking:(NSPoint)aPoint;
      69           0 : - (NSPoint) convertPointFromBacking:(NSPoint)aPoint;
      70           0 : - (NSSize) convertSizeToBacking:(NSSize)aSize;
      71           0 : - (NSSize) convertSizeFromBacking:(NSSize)aSize;
      72           0 : - (NSRect) convertRectToBacking:(NSRect)aRect;
      73           0 : - (NSRect) convertRectFromBacking:(NSRect)aRect;
      74             : 
      75             : @end
      76             : #endif
      77             : 
      78             : 
      79             : @implementation MyOpenGLView
      80             : 
      81           0 : - (id) initWithFrame:(NSRect)frameRect
      82             : {
      83             : #ifndef NDEBUG
      84             :         if (NSZombieEnabled)
      85             :         {
      86             :                 OOLog(@"debug.zombieEnabled", @"*** ZOMBIES WILL EAT YOUR BRAIN ***");
      87             :         }
      88             : #endif
      89             :         
      90             :         // Pixel Format Attributes for the View-based (non-FullScreen) NSOpenGLContext
      91             :         NSOpenGLPixelFormatAttribute attrs[] =
      92             :         {
      93             :                 // Specify that we want a windowed OpenGL context.
      94             :                 // Must be first or we'll hit an assert in the legacy fullscreen controller.
      95             :                 NSOpenGLPFAWindow,
      96             :                 
      97             :                 // We may be on a multi-display system (and each screen may be driven by a different renderer), so we need to specify which screen we want to take over.
      98             :                 // For this demo, we'll specify the main screen.
      99             :                 NSOpenGLPFAScreenMask, CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay),
     100             :                 
     101             :                 // Specifying "NoRecovery" gives us a context that cannot fall back to the software renderer.
     102             :                 // This makes the View-based context a compatible with the fullscreen context, enabling us to use the "shareContext"
     103             :                 // feature to share textures, display lists, and other OpenGL objects between the two.
     104             :                 NSOpenGLPFANoRecovery,
     105             :                 
     106             :                 // Attributes Common to FullScreen and non-FullScreen
     107             :                 NSOpenGLPFACompliant,
     108             :                 
     109             :                 NSOpenGLPFAColorSize, 32,
     110             :                 NSOpenGLPFADepthSize, 32,
     111             :                 NSOpenGLPFADoubleBuffer,
     112             :                 NSOpenGLPFAAccelerated,
     113             : #if FSAA
     114             :                 // Need a preference or other sane way to activate this
     115             :                 NSOpenGLPFAMultisample,
     116             :                 NSOpenGLPFASampleBuffers, 1,
     117             :                 NSOpenGLPFASamples,4,
     118             : #endif
     119             :                 0
     120             :         };
     121             :         
     122             :         // Create our non-FullScreen pixel format.
     123             :         NSOpenGLPixelFormat *pixelFormat = [[[NSOpenGLPixelFormat alloc] initWithAttributes:attrs] autorelease];
     124             :         
     125             :         if ((self = [super initWithFrame:frameRect pixelFormat:pixelFormat]))
     126             :         {
     127             :                 if ([self respondsToSelector:@selector(setAcceptsTouchEvents:)])
     128             :                 {
     129             :                         [self setAcceptsTouchEvents:YES];
     130             :                 }
     131             :                 
     132             :                 if ([self respondsToSelector:@selector(setWantsBestResolutionOpenGLSurface:)])
     133             :                 {
     134             :                         // Enable high resolution on Retina displays.
     135             :                         [self setWantsBestResolutionOpenGLSurface:YES];
     136             :                 }
     137             :                 
     138             :                 matrixManager = [[OOOpenGLMatrixManager alloc] init];
     139             :                 _pixelFormatAttributes = [[NSData alloc] initWithBytes:attrs length:sizeof attrs];
     140             :                 virtualJoystickPosition = NSMakePoint(0.0,0.0);
     141             :                 
     142             :                 typedString = [[NSMutableString alloc] initWithString:@""];
     143             :                 allowingStringInput = gvStringInputNo;
     144             :                 isAlphabetKeyDown = NO;
     145             :                         
     146             :                 timeIntervalAtLastClick = [NSDate timeIntervalSinceReferenceDate];
     147             :                 
     148             :                 _virtualScreen = [[self openGLContext] currentVirtualScreen];
     149             :         }
     150             :         
     151             :         // preload the printscreen key into our translation array because SDLK_PRINTSCREEN isn't available
     152             :         scancode2Unicode[55] = gvPrintScreenKey;
     153             :         [self initKeyMappingData];
     154             : 
     155             :         return self;
     156             : }
     157             : 
     158             : - (void) initKeyMappingData
     159             : {
     160             :         NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];
     161             :         NSDictionary *kmap = [NSDictionary dictionaryWithDictionary:[ResourceManager dictionaryFromFilesNamed:@"keymappings_mac.plist" inFolder:@"Config" mergeMode:MERGE_BASIC cache:NO]];
     162             :         // get the stored keyboard code from preferences
     163             :         NSString *kbd = [prefs oo_stringForKey:@"keyboard-code" defaultValue:@"default"];
     164             :         NSDictionary *subset = [kmap objectForKey:kbd];
     165             : 
     166             :         [keyMappings_normal release];
     167             :         keyMappings_normal = [[subset objectForKey:@"mapping_normal"] copy];
     168             :         [keyMappings_shifted release];
     169             :         keyMappings_shifted = [[subset objectForKey:@"mapping_shifted"] copy];
     170             : }
     171             : 
     172             : 
     173           0 : - (void) dealloc
     174             : {
     175             :         DESTROY(typedString);
     176             :         DESTROY(_pixelFormatAttributes);
     177             :         DESTROY(matrixManager);
     178             :         
     179             :         if (keyMappings_normal)
     180             :                 [keyMappings_normal release];
     181             :         if (keyMappings_shifted)
     182             :                 [keyMappings_shifted release];
     183             : 
     184             :         [super dealloc];
     185             : }
     186             : 
     187             : 
     188             : - (void) setStringInput:(enum StringInput)value
     189             : {
     190             :         allowingStringInput = value;
     191             : }
     192             : 
     193             : 
     194             : - (void) allowStringInput:(BOOL)value
     195             : {
     196             :         if (value)
     197             :         {
     198             :                 allowingStringInput = gvStringInputAlpha;
     199             :         }
     200             :         else
     201             :         {
     202             :                 allowingStringInput = gvStringInputNo;
     203             :         }
     204             : }
     205             : 
     206             : - (enum StringInput) allowingStringInput
     207             : {
     208             :         return allowingStringInput;
     209             : }
     210             : 
     211             : 
     212             : - (NSString *) typedString
     213             : {
     214             :         return typedString;
     215             : }
     216             : 
     217             : 
     218             : - (void) resetTypedString
     219             : {
     220             :         [typedString setString:@""];
     221             : }
     222             : 
     223             : 
     224             : - (void) setTypedString:(NSString *)value
     225             : {
     226             :         [typedString setString:value];
     227             : }
     228             : 
     229             : 
     230             : - (NSSize) viewSize
     231             : {
     232             :         return viewSize;
     233             : }
     234             : 
     235             : 
     236             : - (NSSize) backingViewSize
     237             : {
     238             :         return backingViewSize;
     239             : }
     240             : 
     241             : 
     242             : - (GLfloat) display_z
     243             : {
     244             :         return display_z;
     245             : }
     246             : 
     247             : 
     248             : - (GLfloat) x_offset
     249             : {
     250             :         return x_offset;
     251             : }
     252             : 
     253             : 
     254             : - (GLfloat) y_offset
     255             : {
     256             :         return y_offset;
     257             : }
     258             : 
     259             : 
     260             : - (GameController *) gameController
     261             : {
     262             :         return gameController;
     263             : }
     264             : 
     265             : 
     266             : - (void) setGameController:(GameController *) controller
     267             : {
     268             :         gameController = controller;
     269             : }
     270             : 
     271             : 
     272             : - (void) noteMouseInteractionModeChangedFrom:(OOMouseInteractionMode)oldMode to:(OOMouseInteractionMode)newMode
     273             : {
     274             :         UnapplyCursorState(oldMode);
     275             :         ApplyCursorState(newMode);
     276             : }
     277             : 
     278             : 
     279             : - (void) updateScreen
     280             : {
     281             :         if ([[self window] isVisible])
     282             :         {
     283             :                 [self drawRect:NSMakeRect(0, 0, viewSize.width, viewSize.height)];
     284             :         }
     285             : }
     286             : 
     287             : - (void) pollControls
     288             : {
     289             :         if ([NSDate timeIntervalSinceReferenceDate] > timeIntervalAtLastMouseWheel + OOMOUSEWHEEL_EVENTS_DELAY_INTERVAL)
     290             :                 _mouseWheelDelta = 0.0f;
     291             : }
     292             : 
     293             : - (void) drawRect:(NSRect)rect
     294             : {
     295             :         if ((viewSize.width != [self frame].size.width)||(viewSize.height != [self frame].size.height)) // resized
     296             :         {
     297             :                 m_glContextInitialized = NO;
     298             :                 viewSize = [self frame].size;
     299             :         }
     300             :         
     301             :         if (!m_glContextInitialized)  [self initialiseGLWithSize:viewSize];
     302             :         
     303             :         // do all the drawing!
     304             :         if (UNIVERSE != nil)  [UNIVERSE drawUniverse];
     305             :         else
     306             :         {
     307             :                 // not set up yet, draw a black screen
     308             :                 OOGL(glClearColor(0.0, 0.0, 0.0, 0.0));
     309             :                 OOGL(glClear(GL_COLOR_BUFFER_BIT));
     310             :         }
     311             :         
     312             :         [[self openGLContext] flushBuffer];
     313             : }
     314             : 
     315             : 
     316           0 : - (void) noteMovedToBadDisplay
     317             : {
     318             :         NSRunInformationalAlertPanel(DESC(@"oolite-mac-bad-display"), @"%@", nil, nil, nil, DESC(@"oolite-mac-bad-display-2"));
     319             : }
     320             : 
     321             : 
     322           0 : - (void) update
     323             : {
     324             :         NSOpenGLContext *context = [self openGLContext];
     325             :         
     326             :         [context update];
     327             :         int virtualScreen = [context currentVirtualScreen];
     328             :         if (virtualScreen != _virtualScreen)
     329             :         {
     330             :                 @try
     331             :                 {
     332             :                         [[OOGraphicsResetManager sharedManager] resetGraphicsState];
     333             :                         _virtualScreen = virtualScreen;
     334             :                 }
     335             :                 @catch (NSException *exception)
     336             :                 {
     337             :                         /*      Graphics reset failed, most likely because of OpenGL context
     338             :                                 incompatibility. Reset to previous "virtual screen" (i.e.,
     339             :                                 renderer). OS X's OpenGL implementation will take care of
     340             :                                 copying 
     341             :                         */
     342             :                         [context setCurrentVirtualScreen:_virtualScreen];
     343             :                         [[OOGraphicsResetManager sharedManager] resetGraphicsState];    // If this throws, we're screwed.
     344             :                         
     345             :                         if ([[self gameController] inFullScreenMode])
     346             :                         {
     347             :                                 [[self gameController] pauseFullScreenModeToPerform:@selector(noteMovedToBadDisplay) onTarget:self];
     348             :                         }
     349             :                         else
     350             :                         {
     351             :                                 [self noteMovedToBadDisplay];
     352             :                         }
     353             :                 }
     354             :         }
     355             : }
     356             : 
     357             : 
     358             : - (void) initialiseGLWithSize:(NSSize)v_size
     359             : {
     360             :         viewSize = v_size;
     361             :         if (viewSize.width/viewSize.height > 4.0/3.0) {
     362             :                 display_z = 480.0 * viewSize.width/viewSize.height;
     363             :                 x_offset = 240.0 * viewSize.width/viewSize.height;
     364             :                 y_offset = 240.0;
     365             :         } else {
     366             :                 display_z = 640.0;
     367             :                 x_offset = 320.0;
     368             :                 y_offset = 320.0 * viewSize.height/viewSize.width;
     369             :         }
     370             :         
     371             :         if ([self respondsToSelector:@selector(convertSizeToBacking:)])
     372             :         {
     373             :                 // High resolution mode support.
     374             :                 backingViewSize = [self convertSizeToBacking:viewSize];
     375             :         }
     376             :         else
     377             :         {
     378             :                 backingViewSize = viewSize;
     379             :         }
     380             :         
     381             :         [self openGLContext];   // Force lazy setup if needed.
     382             :         [[self gameController] setUpBasicOpenGLStateWithSize:v_size];
     383             :         [[self openGLContext] flushBuffer];
     384             :         
     385             :         m_glContextInitialized = YES;
     386             : }
     387             : 
     388             : 
     389             : - (NSData *)pixelFormatAttributes
     390             : {
     391             :         return _pixelFormatAttributes;
     392             : }
     393             : 
     394             : 
     395             : #ifdef MAC_OS_X_VERSION_10_7    // If building against 10.7 SDK, where relevant symbols are defined...
     396             : - (void) viewDidMoveToWindow
     397             : {
     398             :         /*      Subscribe to NSWindowDidChangeBackingPropertiesNotification on systems
     399             :                 which support it (10.7 and later). This notification fires when the
     400             :                 scale factor or colour space of the window's backing store changes.
     401             :                 We use it to track scale factor changes.
     402             :         */
     403             :         if (&NSWindowDidChangeBackingPropertiesNotification != NULL && [self.window respondsToSelector:@selector(backingScaleFactor)])
     404             :         {
     405             :                 [[NSNotificationCenter defaultCenter] addObserver:self
     406             :                                                                                                  selector:@selector(backingPropertiesChanged:)
     407             :                                                                                                          name:NSWindowDidChangeBackingPropertiesNotification
     408             :                                                                                                    object:self.window];
     409             :                 
     410             :                 // Also, ensure the initial state makes sense.
     411             :                 [self backingPropertiesChanged:nil];
     412             :         }
     413             : }
     414             : 
     415             : 
     416             : - (void) backingPropertiesChanged:(NSNotification *)notification
     417             : {
     418             :         GLSetDisplayScaleFactor(self.window.backingScaleFactor);
     419             : }
     420             : #endif
     421             : 
     422             : 
     423             : - (BOOL) snapShot:(NSString *)filename
     424             : {
     425             :         BOOL snapShotOK = YES;
     426             :         NSSize v_size = backingViewSize;
     427             :         
     428             :         int w = v_size.width;
     429             :         int h = v_size.height;
     430             :         
     431             :         if (w & 3)
     432             :                 w = w + 4 - (w & 3);
     433             :         
     434             :         long nPixels = w * h + 1;       
     435             :         
     436             :         unsigned char   *red = (unsigned char *)malloc(nPixels);
     437             :         unsigned char   *green = (unsigned char *)malloc(nPixels);
     438             :         unsigned char   *blue = (unsigned char *)malloc(nPixels);
     439             :         
     440             :         // backup the previous directory
     441             :         NSString *originalDirectory = [[NSFileManager defaultManager] currentDirectoryPath];
     442             :         // use the snapshots directory
     443             :         NSString *snapshotsDirectory = [[[GameController sharedController] snapshotsURLCreatingIfNeeded:YES] path];
     444             :         if (![[NSFileManager defaultManager] changeCurrentDirectoryPath:snapshotsDirectory])
     445             :         {
     446             :                 NSBeep();
     447             :                 OOLog(@"savedSnapshot.defaultPath.chdir.failed", @"Could not navigate to %@", snapshotsDirectory);
     448             :                 snapShotOK = NO;
     449             :                 goto FAIL;
     450             :         }
     451             :         
     452             :         BOOL                            withFilename = (filename != nil);
     453             :         static unsigned         imageNo = 0;
     454             :         unsigned                        tmpImageNo = 0;
     455             :         NSString                        *pathToPic = nil;
     456             :         NSString                        *baseName = @"oolite";
     457             :         
     458             :         if (withFilename) 
     459             :         {
     460             :                 baseName = filename;
     461             :                 pathToPic = [filename stringByAppendingString:@".png"];
     462             :         }
     463             :         else
     464             :         {
     465             :                 tmpImageNo = imageNo;
     466             :         }
     467             :         
     468             :         if (withFilename && [[NSFileManager defaultManager] fileExistsAtPath:pathToPic])
     469             :         {
     470             :                 OOLog(@"screenshot.filenameExists", @"Snapshot \"%@.png\" already exists - adding numerical sequence.", pathToPic);
     471             :                 pathToPic = nil;
     472             :         }
     473             :         
     474             :         if (pathToPic == nil) 
     475             :         {
     476             :                 do
     477             :                 {
     478             :                         tmpImageNo++;
     479             :                         pathToPic = [NSString stringWithFormat:@"%@-%03d.png", baseName, tmpImageNo];
     480             :                 } while ([[NSFileManager defaultManager] fileExistsAtPath:pathToPic]);
     481             :         }
     482             :         
     483             :         if (!withFilename)
     484             :         {
     485             :                 imageNo = tmpImageNo;
     486             :         }
     487             :         
     488             :         OOLog(@"screenshot", @"Saved screen shot \"%@\" (%u x %u pixels).", pathToPic, w, h);
     489             :         
     490             :         NSBitmapImageRep* bitmapRep = 
     491             :                 [[NSBitmapImageRep alloc]
     492             :                         initWithBitmapDataPlanes:NULL   // --> let the class allocate it
     493             :                         pixelsWide:                     w
     494             :                         pixelsHigh:                     h
     495             :                         bitsPerSample:          8                       // each component is 8 bits (1 byte)
     496             :                         samplesPerPixel:        3                       // number of components (R, G, B)
     497             :                         hasAlpha:                       NO                      // no transparency
     498             :                         isPlanar:                       NO                      // data integrated into single plane
     499             :                         colorSpaceName:         NSDeviceRGBColorSpace
     500             :                         bytesPerRow:            3*w                     // can no longer let the class figure it out
     501             :                         bitsPerPixel:           24                      // can no longer let the class figure it out
     502             :                 ];
     503             :         
     504             :         unsigned char *pixels = [bitmapRep bitmapData];
     505             :                 
     506             :         OOGL(glReadPixels(0,0, w,h, GL_RED,   GL_UNSIGNED_BYTE, red));
     507             :         OOGL(glReadPixels(0,0, w,h, GL_GREEN, GL_UNSIGNED_BYTE, green));
     508             :         OOGL(glReadPixels(0,0, w,h, GL_BLUE,  GL_UNSIGNED_BYTE, blue));
     509             :         
     510             :         int x,y;
     511             :         for (y = 0; y < h; y++)
     512             :         {
     513             :                 long index = (h - y - 1)*w;
     514             :                 for (x = 0; x < w; x++)              // set bitmap pixels
     515             :                 {
     516             :                         *pixels++ = red[index];
     517             :                         *pixels++ = green[index];
     518             :                         *pixels++ = blue[index++];
     519             :                 }
     520             :         }
     521             :         
     522             :         [[bitmapRep representationUsingType:NSPNGFileType properties:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSImageInterlaced, NULL]]
     523             :                 writeToFile:pathToPic atomically:YES];                  // save PNG representation of image
     524             :         
     525             :         // free allocated objects and memory
     526             :         [bitmapRep release];
     527             :         
     528             : FAIL:
     529             :         free(red);
     530             :         free(green);
     531             :         free(blue);
     532             :         
     533             :         // return to the previous directory
     534             :         [[NSFileManager defaultManager] changeCurrentDirectoryPath:originalDirectory];
     535             :         return snapShotOK;
     536             : }
     537             : 
     538             : 
     539             : - (void) stringToClipboard:(NSString *)stringToCopy
     540             : {
     541             :         NSPasteboard *clipBoard = [NSPasteboard generalPasteboard];
     542             :         [clipBoard declareTypes:[NSArray arrayWithObject:NSPasteboardTypeString] owner:nil];
     543             :         [clipBoard setString:stringToCopy forType:NSPasteboardTypeString];
     544             : }
     545             : 
     546             : 
     547           0 : - (BOOL) acceptsFirstResponder
     548             : {
     549             :         return YES;
     550             : }
     551             : 
     552             : 
     553           0 : - (void) keyUp:(NSEvent *)theEvent
     554             : {
     555             :         NSString        *stringValue = nil;
     556             :         int                     key;
     557             :         int                     keycode;
     558             :         
     559             :         stringValue = [theEvent charactersIgnoringModifiers];
     560             :         
     561             :         /*      Bug: exception when releasing accent key.
     562             :                 Analysis: Dead keys (accents and similar) return an empty string.
     563             :                 Fix: reject zero-length strings. This is the Wrong Thing - we should
     564             :                 really be using KeyTranslate()/UCKeyTranslate() to find out what the
     565             :                 string would be if you pressed the key and then space.
     566             :                 -- Ahruman 20070714
     567             :         */
     568             :         if ([stringValue length] < 1)  return;
     569             :         
     570             :         suppressKeys = NO;
     571             :         
     572             :         keycode = [theEvent keyCode] & 255;
     573             :         key = keycodetrans[keycode];    // retrieve the character we got for pressing the hardware at key location 'keycode'
     574             :         
     575             :         OOLog(kOOLogKeyUp, @"Key up: stringValue = \"%@\", keyCode = %d, key = %u", stringValue, keycode, key);
     576             :         
     577             :         // Special handling of command keys used in full-screen mode.
     578             :         if ([theEvent modifierFlags] & NSCommandKeyMask)
     579             :         {
     580             :                 switch (key)
     581             :                 {
     582             :                         case 'q':
     583             :                                 commandQ = NO;
     584             :                                 break;
     585             :                                 
     586             :                         case 'f':
     587             :                                 commandF = NO;
     588             :                                 break;
     589             :                 }
     590             :                 // Pass through to allow clearing of normal key as well.
     591             :         }
     592             :         
     593             :         /*      HACK: treat f12 as alias to cmd-F for compatibility with helpful forum
     594             :                 advice etc.
     595             :         */
     596             :         if (key == NSF12FunctionKey)
     597             :         {
     598             :                 commandF = NO;
     599             :                 f12 = NO;
     600             :                 return;
     601             :         };
     602             :         
     603             :         isAlphabetKeyDown = NO;
     604             :         if ((key >= 0)&&(key < [self numKeys])&&(keys[key]))
     605             :         {
     606             :                 keys[key] = NO;
     607             :         }
     608             :         else
     609             :         {
     610             :                 if (key > [self numKeys])
     611             :                         OOLog(kOOLogKeyCodeOutOfRange, @"Translated key: %d out of range", key);
     612             :         }
     613             : }
     614             : 
     615             : 
     616           0 : - (void) keyDown:(NSEvent *)theEvent
     617             : {
     618             :         NSString        *stringValue = nil;
     619             :         int                     key;
     620             :         int                     keycode;
     621             :         
     622             :         stringValue = [theEvent charactersIgnoringModifiers];
     623             :         
     624             :         /*      Bug: exception when pressing accent key.
     625             :                 Analysis: Dead keys (accents and similar) return an empty string.
     626             :                 Fix: reject zero-length strings. This is the Wrong Thing - we should
     627             :                 really be using KeyTranslate()/UCKeyTranslate() to find out what the
     628             :                 string would be if you pressed the key and then space.
     629             :                 -- Ahruman 20070714
     630             :         */
     631             :         //if ([stringValue length] < 1)  return;
     632             :         
     633             :         keycode = [theEvent keyCode] & 255;
     634             :         
     635             :         if ([stringValue length] < 1)
     636             :         {
     637             :                 if (!shift)
     638             :                 {
     639             :                         NSString *keyNormal = [keyMappings_normal objectForKey:[NSString stringWithFormat:@"%d", keycode]];
     640             :                         if (keyNormal) stringValue = [NSString stringWithFormat:@"%c", [keyNormal integerValue]];
     641             :                 }
     642             :                 else
     643             :                 {
     644             :                         NSString *keyShifted = [keyMappings_shifted objectForKey:[NSString stringWithFormat:@"%d", keycode]];
     645             :                         if (keyShifted) stringValue = [NSString stringWithFormat:@"%c", [keyShifted integerValue]];
     646             :                 }               
     647             :                 // if we still have a zero-length string, return at this point
     648             :                 if ([stringValue length] < 1) return;
     649             :         }
     650             : 
     651             :         key = [stringValue characterAtIndex:0];
     652             :         key = [self translateKeyCode:key];
     653             :         
     654             :         OOLog(kOOLogKeyDown, @"Key down: stringValue = \"%@\", keyCode = %d, key = %u", stringValue, keycode, key);
     655             :         
     656             :         // Special handling of command keys used in full-screen mode.
     657             :         if ([theEvent modifierFlags] & NSCommandKeyMask)
     658             :         {
     659             :                 switch (key)
     660             :                 {
     661             :                         case 'q':
     662             :                                 commandQ = YES;
     663             :                                 break;
     664             :                                 
     665             :                         case 'f':
     666             :                                 commandF = YES;
     667             :                                 break;
     668             :                 }
     669             :                 
     670             :                 return;
     671             :         }
     672             :         
     673             :         keycodetrans[keycode] = key;    // record the character we got for pressing the hardware at key location 'keycode'
     674             :         
     675             :         /*      HACK: treat f12 as alias to cmd-F for compatibility with helpful forum
     676             :                 advice etc.
     677             :         */
     678             :         if (key == NSF12FunctionKey)
     679             :         {
     680             :                 if (!f12)
     681             :                 {
     682             :                         f12 = YES;
     683             :                         [gameController performSelector:@selector(toggleFullScreenAction:) withObject:nil afterDelay:0.0];
     684             :                 }
     685             :                 
     686             :                 return;
     687             :         };
     688             :         
     689             :         if ((key >= 0)&&(key < [self numKeys])&&(!keys[key]))
     690             :         {
     691             :                 keys[key] = YES;
     692             :                 
     693             :                 if (allowingStringInput)
     694             :                 {
     695             :                         if ((key == gvDeleteKey || key == gvBackspaceKey) && [typedString length] > 0)
     696             :                         {
     697             :                                 // delete
     698             :                                 [typedString deleteCharactersInRange:NSMakeRange([typedString length] - 1, 1)];
     699             :                         }
     700             : 
     701             :                         isAlphabetKeyDown = NO;
     702             :                         lastKeyShifted = shift;
     703             : 
     704             :                         // limited input for planet find screen
     705             :                         if (allowingStringInput == gvStringInputAlpha)
     706             :                         {
     707             :                                 if (isalpha(key))
     708             :                                 {
     709             :                                         isAlphabetKeyDown = YES;
     710             :                                         // convert to lower case
     711             :                                         [typedString appendFormat:@"%c", tolower(key)];
     712             :                                 }
     713             :                         }
     714             :                         
     715             :                         // full input for load-save screen or 'all' input
     716             :                         if (allowingStringInput >= gvStringInputLoadSave)
     717             :                         {
     718             :                                 // except '/' for loadsave
     719             :                                 if (isprint(key) && key != '/')
     720             :                                 {
     721             :                                         isAlphabetKeyDown = YES;
     722             :                                         [typedString appendFormat:@"%c", key];
     723             :                                 }
     724             :                                 else if (key == '/' && allowingStringInput == gvStringInputAll)
     725             :                                 {
     726             :                                         isAlphabetKeyDown = YES;
     727             :                                         [typedString appendFormat:@"%c", key];
     728             :                                 }
     729             :                         }
     730             :                         
     731             :                 }
     732             :         }
     733             :         else
     734             :         {
     735             :                 if (key > [self numKeys])
     736             :                 {
     737             :                         OOLog(kOOLogKeyCodeOutOfRange, @"Translated key: %d out of range", key);
     738             :                 }
     739             :         }
     740             : } 
     741             : 
     742             : /* Capture shift, ctrl, opt and command press & release */
     743           0 : - (void)flagsChanged:(NSEvent *)theEvent
     744             : {
     745             :         NSUInteger flags = [theEvent modifierFlags];
     746             :         opt = (flags & NSAlternateKeyMask) ? YES : NO;
     747             :         ctrl = (flags & NSControlKeyMask) ? YES : NO;
     748             :         command = (flags & NSCommandKeyMask) ? YES : NO;
     749             :         shift = ( flags & NSShiftKeyMask ) ? YES : NO;
     750             :         if ([theEvent keyCode] == 0x39) // 57 = key code for caps lock
     751             :         {
     752             :                 capsLockOn = (flags & NSAlphaShiftKeyMask) ? YES : NO;
     753             :         }
     754             : }
     755             : 
     756             : 
     757             : - (void)mouseDown:(NSEvent *)theEvent
     758             : {
     759             :         if (doubleClick)
     760             :         {
     761             :                 doubleClick = NO;
     762             :                 keys[gvMouseDoubleClick] = NO;
     763             :         }
     764             :         keys[gvMouseLeftButton] = YES; // 'a' down
     765             : }
     766             : 
     767             : 
     768             : - (void)mouseUp:(NSEvent *)theEvent
     769             : {
     770             :         NSTimeInterval timeBetweenClicks = [NSDate timeIntervalSinceReferenceDate] - timeIntervalAtLastClick;
     771             :         timeIntervalAtLastClick += timeBetweenClicks;
     772             :         
     773             :         if (!doubleClick)
     774             :         {
     775             :                 doubleClick = (timeBetweenClicks < MOUSE_DOUBLE_CLICK_INTERVAL);     // One fifth of a second
     776             :                 keys[gvMouseDoubleClick] = doubleClick;
     777             :         }
     778             :         
     779             :         keys[gvMouseLeftButton] = NO;  // 'a' up
     780             : }
     781             : 
     782             : 
     783             : - (void)resetMouse
     784             : {
     785             :         CGPoint centerPoint = CGPointMake(viewSize.width / 2.0, viewSize.height / 2.0);
     786             :         CGWarpMouseCursorPosition(centerPoint);
     787             :         [self setVirtualJoystick:0.0 :0.0];
     788             : }
     789             : 
     790             : 
     791           0 : - (void)mouseMoved:(NSEvent *)theEvent
     792             : {
     793             :         double mx = [theEvent locationInWindow].x - viewSize.width/2.0;
     794             :         double my = [theEvent locationInWindow].y - viewSize.height/2.0;
     795             : 
     796             :         if (display_z > 640.0)
     797             :         {
     798             :                 mx /= viewSize.width * MAIN_GUI_PIXEL_WIDTH / display_z;
     799             :                 my /= viewSize.height;
     800             :         }
     801             :         else
     802             :         {
     803             :                 mx /= MAIN_GUI_PIXEL_WIDTH * viewSize.width / 640.0;
     804             :                 my /= MAIN_GUI_PIXEL_HEIGHT * viewSize.width / 640.0;
     805             :         }
     806             :         
     807             :         [self setVirtualJoystick:mx :-my];
     808             : }
     809             : 
     810             : 
     811           0 : - (void) mouseDragged:(NSEvent *)theEvent
     812             : {
     813             :         [self mouseMoved:theEvent];
     814             : }
     815             : 
     816           0 : - (void)scrollWheel:(NSEvent *)theEvent
     817             : {
     818             :         float dy = [theEvent scrollingDeltaY];
     819             :         
     820             :         if (dy == 0)
     821             :                 return;
     822             :         
     823             :         if (dy > 0)
     824             :         {
     825             :                 if (_mouseWheelDelta >= 0)
     826             :                         _mouseWheelDelta += dy;
     827             :                 else
     828             :                         _mouseWheelDelta = 0;
     829             :         }
     830             :         else
     831             :         {
     832             :                 if (_mouseWheelDelta <= 0)
     833             :                         _mouseWheelDelta += dy;
     834             :                 else
     835             :                         _mouseWheelDelta = 0;
     836             :         }
     837             :         timeIntervalAtLastMouseWheel = [NSDate timeIntervalSinceReferenceDate];
     838             : }
     839             : 
     840           0 : - (void) otherMouseDragged:(NSEvent *)theEvent
     841             : {
     842             :         [self mouseMoved:theEvent];
     843             : }
     844             : 
     845             : 
     846           0 : - (void) rightMouseDown:(NSEvent *)theEvent
     847             : {
     848             :         [self resetMouse];
     849             : }
     850             : 
     851             : 
     852           0 : - (void) rightMouseUp:(NSEvent *)theEvent
     853             : {
     854             :         [self recenterVirtualJoystick];
     855             : }
     856             : 
     857             : 
     858           0 : - (void) touchesEndedWithEvent:(NSEvent *)theEvent
     859             : {
     860             :         [self recenterVirtualJoystick];
     861             : }
     862             : 
     863             : 
     864           0 : - (void) recenterVirtualJoystick
     865             : {
     866             :         if ([PLAYER guiScreen] == GUI_SCREEN_MAIN)
     867             :         {
     868             :                 [[GameController sharedController] recenterVirtualJoystick];
     869             :         }
     870             : }
     871             : 
     872             : 
     873             : /////////////////////////////////////////////////////////////
     874             : /*  Turn the Cocoa ArrowKeys into our arrow key constants. */
     875           0 : - (int) translateKeyCode: (int) input
     876             : {
     877             :         int key = input;
     878             :         switch ( input )
     879             :         {
     880             :                 case NSUpArrowFunctionKey:
     881             :                         key = gvArrowKeyUp;
     882             :                         break;
     883             :                 
     884             :                 case NSDownArrowFunctionKey:
     885             :                         key = gvArrowKeyDown;
     886             :                         break;
     887             :                         
     888             :                 case NSLeftArrowFunctionKey:
     889             :                         key = gvArrowKeyLeft;
     890             :                         break;
     891             :                         
     892             :                 case NSRightArrowFunctionKey:
     893             :                         key = gvArrowKeyRight;
     894             :                         break;
     895             :                 
     896             :                 case NSF1FunctionKey:
     897             :                         key = gvFunctionKey1;
     898             :                         break;
     899             :                         
     900             :                 case NSF2FunctionKey:
     901             :                         key = gvFunctionKey2;
     902             :                         break;
     903             :                         
     904             :                 case NSF3FunctionKey:
     905             :                         key = gvFunctionKey3;
     906             :                         break;
     907             :                         
     908             :                 case NSF4FunctionKey:
     909             :                         key = gvFunctionKey4;
     910             :                         break;
     911             :                         
     912             :                 case NSF5FunctionKey:
     913             :                         key = gvFunctionKey5;
     914             :                         break;
     915             :                         
     916             :                 case NSF6FunctionKey:
     917             :                         key = gvFunctionKey6;
     918             :                         break;
     919             :                         
     920             :                 case NSF7FunctionKey:
     921             :                         key = gvFunctionKey7;
     922             :                         break;
     923             :                         
     924             :                 case NSF8FunctionKey:
     925             :                         key = gvFunctionKey8;
     926             :                         break;
     927             :                         
     928             :                 case NSF9FunctionKey:
     929             :                         key = gvFunctionKey9;
     930             :                         break;
     931             :                         
     932             :                 case NSF10FunctionKey:
     933             :                         key = gvFunctionKey10;
     934             :                         break;
     935             :                         
     936             :                 case NSF11FunctionKey:
     937             :                         key = gvFunctionKey11;
     938             :                         break;
     939             :                         
     940             :                 case NSHomeFunctionKey:
     941             :                         key = gvHomeKey;
     942             :                         break;
     943             :                 
     944             :                 case NSBackspaceCharacter:
     945             :                         key = gvBackspaceKey;
     946             :                         break;
     947             : 
     948             :                 case NSDeleteCharacter:
     949             :                         key = gvDeleteKey;
     950             :                         break;
     951             :                         
     952             :                 case NSInsertFunctionKey:
     953             :                         key = gvInsertKey;
     954             :                         break;
     955             :                         
     956             :                 case NSEndFunctionKey:
     957             :                         key = gvEndKey;
     958             :                         break;
     959             :                         
     960             :                 case NSPageUpFunctionKey:
     961             :                         key = gvPageUpKey;
     962             :                         break;
     963             :                         
     964             :                 case NSPageDownFunctionKey:
     965             :                         key = gvPageDownKey;
     966             :                         break;
     967             :                 
     968             :                 case NSPrintScreenFunctionKey:
     969             :                         key = gvPrintScreenKey;
     970             :                         break;
     971             :                 
     972             :                 case NSPauseFunctionKey:
     973             :                         key = gvPauseKey;
     974             :                         break;
     975             : 
     976             :                 default:
     977             :                         break;
     978             :         }
     979             :         return key;
     980             : }
     981             : 
     982             : 
     983             : - (void) setVirtualJoystick:(double) vmx :(double) vmy
     984             : {
     985             :         virtualJoystickPosition.x = vmx;
     986             :         virtualJoystickPosition.y = vmy;
     987             : }
     988             : 
     989             : 
     990             : - (NSPoint) virtualJoystickPosition
     991             : {
     992             :         return virtualJoystickPosition;
     993             : }
     994             : 
     995             : 
     996             : /////////////////////////////////////////////////////////////
     997             : 
     998             : - (void) clearKeys
     999             : {
    1000             :         int i;
    1001             :         lastKeyShifted = NO;
    1002             :         for (i = 0; i < [self numKeys]; i++)
    1003             :                 keys[i] = NO;
    1004             : }
    1005             : 
    1006             : 
    1007             : - (void) clearMouse
    1008             : {
    1009             :         keys[gvMouseDoubleClick] = NO;
    1010             :         keys[gvMouseLeftButton] = NO;
    1011             :         doubleClick = NO;
    1012             : }
    1013             : 
    1014             : 
    1015             : - (void) clearKey: (int)theKey
    1016             : {
    1017             :         if (theKey >= 0 && theKey < [self numKeys])
    1018             :         {
    1019             :                 keys[theKey] = NO;
    1020             :         }
    1021             : }
    1022             : 
    1023             : 
    1024             : - (BOOL) isAlphabetKeyDown
    1025             : {
    1026             :         return isAlphabetKeyDown = NO;
    1027             : }
    1028             : 
    1029             : // DJS: When entering submenus in the gui, it is not helpful if the
    1030             : // key down that brought you into the submenu is still registered
    1031             : // as down when we're in. This makes isDown return NO until a key up
    1032             : // event has been received from SDL.
    1033             : - (void) suppressKeysUntilKeyUp
    1034             : {
    1035             :         if (keys[gvMouseDoubleClick] == NO)
    1036             :         {
    1037             :                 suppressKeys = YES;
    1038             :                 [self clearKeys];
    1039             :         }
    1040             :         else
    1041             :         {
    1042             :                 [self clearMouse];
    1043             :         }
    1044             : }
    1045             : 
    1046             : 
    1047             : - (BOOL) isDown: (int) key
    1048             : {
    1049             :         if( suppressKeys )
    1050             :                 return NO;
    1051             :         if ( key < 0 )
    1052             :                 return NO;
    1053             :         if ( key >= [self numKeys] )
    1054             :                 return NO;
    1055             :         return keys[key];
    1056             : }
    1057             : 
    1058             : 
    1059             : - (BOOL) isOptDown
    1060             : {
    1061             :         return opt;
    1062             : }
    1063             : 
    1064             : 
    1065             : - (BOOL) isCtrlDown
    1066             : {
    1067             :         return ctrl;
    1068             : }
    1069             : 
    1070             : 
    1071             : - (BOOL) isCommandDown
    1072             : {
    1073             :         return command;
    1074             : }
    1075             : 
    1076             : 
    1077             : - (BOOL) isShiftDown
    1078             : {
    1079             :         return shift;
    1080             : }
    1081             : 
    1082             : 
    1083             : - (BOOL) isCapsLockOn
    1084             : {
    1085             :         return capsLockOn;
    1086             : }
    1087             : 
    1088             : 
    1089             : - (BOOL) lastKeyWasShifted
    1090             : {
    1091             :         return lastKeyShifted;
    1092             : }
    1093             : 
    1094             : 
    1095             : - (int) numKeys
    1096             : {
    1097             :         return NUM_KEYS;
    1098             : }
    1099             : 
    1100             : 
    1101             : - (int) mouseWheelState
    1102             : {
    1103             :         if (_mouseWheelDelta > 0.0f)
    1104             :                 return gvMouseWheelUp;
    1105             :         else if (_mouseWheelDelta < 0.0f)
    1106             :                 return gvMouseWheelDown;
    1107             :         else
    1108             :                 return gvMouseWheelNeutral;
    1109             : }
    1110             : 
    1111             : 
    1112             : - (float) mouseWheelDelta
    1113             : {
    1114             :         return _mouseWheelDelta / OOMOUSEWHEEL_DELTA;
    1115             : }
    1116             : 
    1117             : 
    1118             : - (void) setMouseWheelDelta: (float) newWheelDelta
    1119             : {
    1120             :         _mouseWheelDelta = newWheelDelta * OOMOUSEWHEEL_DELTA;
    1121             : }
    1122             : 
    1123             : 
    1124             : - (BOOL) isCommandQDown
    1125             : {
    1126             :         return commandQ;
    1127             : }
    1128             : 
    1129             : 
    1130             : - (BOOL) isCommandFDown
    1131             : {
    1132             :         return commandF;
    1133             : }
    1134             : 
    1135             : 
    1136             : - (void) clearCommandF
    1137             : {
    1138             :         commandF = NO;
    1139             : }
    1140             : 
    1141             : 
    1142             : + (BOOL)pollShiftKey
    1143             : {
    1144           0 :         #define KEYMAP_GET(m, index) ((((uint8_t*)(m))[(index) >> 3] & (1L << ((index) & 7))) ? 1 : 0)
    1145             :         
    1146             :         KeyMap                          map;
    1147             :         
    1148             :         GetKeys(map);
    1149             :         return KEYMAP_GET(map, 56) || KEYMAP_GET(map, 60);      // Left shift or right shift -- although 60 shouldn't occur.
    1150             : }
    1151             : 
    1152             : - (OOOpenGLMatrixManager *) getOpenGLMatrixManager
    1153             : {
    1154             :         return matrixManager;
    1155             : }
    1156             : 
    1157             : #ifndef NDEBUG
    1158             : // General image-dumping method.
    1159             : - (void) dumpRGBAToFileNamed:(NSString *)name
    1160             :                                            bytes:(uint8_t *)bytes
    1161             :                                            width:(NSUInteger)width
    1162             :                                           height:(NSUInteger)height
    1163             :                                         rowBytes:(NSUInteger)rowBytes
    1164             : {
    1165             :         if (name == nil || bytes == NULL || width == 0 || height == 0 || rowBytes < width * 4)  return;
    1166             :         
    1167             :         NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:&bytes
    1168             :                                                                                                                                            pixelsWide:width
    1169             :                                                                                                                                            pixelsHigh:height
    1170             :                                                                                                                                         bitsPerSample:8
    1171             :                                                                                                                                   samplesPerPixel:4
    1172             :                                                                                                                                                  hasAlpha:YES
    1173             :                                                                                                                                                  isPlanar:NO
    1174             :                                                                                                                                    colorSpaceName:NSCalibratedRGBColorSpace
    1175             :                                                                                                                                           bytesPerRow:rowBytes
    1176             :                                                                                                                                          bitsPerPixel:32];
    1177             :         
    1178             :         if (bitmap != nil)
    1179             :         {
    1180             :                 [bitmap autorelease];
    1181             :                 
    1182             :                 NSString *filepath = [[[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:name] stringByAppendingPathExtension:@"png"];
    1183             :                 [[bitmap representationUsingType:NSPNGFileType properties:[NSDictionary dictionary]] writeToFile:filepath atomically:YES];
    1184             :         }
    1185             : }
    1186             : 
    1187             : - (void) dumpRGBToFileNamed:(NSString *)name
    1188             :                                           bytes:(uint8_t *)bytes
    1189             :                                           width:(NSUInteger)width
    1190             :                                          height:(NSUInteger)height
    1191             :                                    rowBytes:(NSUInteger)rowBytes
    1192             : {
    1193             :         if (name == nil || bytes == NULL || width == 0 || height == 0 || rowBytes < width * 3)  return;
    1194             :         
    1195             :         NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:&bytes
    1196             :                                                                                                                                            pixelsWide:width
    1197             :                                                                                                                                            pixelsHigh:height
    1198             :                                                                                                                                         bitsPerSample:8
    1199             :                                                                                                                                   samplesPerPixel:3
    1200             :                                                                                                                                                  hasAlpha:NO
    1201             :                                                                                                                                                  isPlanar:NO
    1202             :                                                                                                                                    colorSpaceName:NSCalibratedRGBColorSpace
    1203             :                                                                                                                                           bytesPerRow:rowBytes
    1204             :                                                                                                                                          bitsPerPixel:24];
    1205             :         
    1206             :         if (bitmap != nil)
    1207             :         {
    1208             :                 [bitmap autorelease];
    1209             :                 
    1210             :                 NSString *filepath = [[[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:name] stringByAppendingPathExtension:@"png"];
    1211             :                 [[bitmap representationUsingType:NSPNGFileType properties:[NSDictionary dictionary]] writeToFile:filepath atomically:YES];
    1212             :         }
    1213             : }
    1214             : 
    1215             : 
    1216             : - (void) dumpGrayToFileNamed:(NSString *)name
    1217             :                                            bytes:(uint8_t *)bytes
    1218             :                                            width:(NSUInteger)width
    1219             :                                           height:(NSUInteger)height
    1220             :                                         rowBytes:(NSUInteger)rowBytes
    1221             : {
    1222             :         if (name == nil || bytes == NULL || width == 0 || height == 0 || rowBytes < width)  return;
    1223             :         
    1224             :         NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:&bytes
    1225             :                                                                                                                                            pixelsWide:width
    1226             :                                                                                                                                            pixelsHigh:height
    1227             :                                                                                                                                         bitsPerSample:8
    1228             :                                                                                                                                   samplesPerPixel:1
    1229             :                                                                                                                                                  hasAlpha:NO
    1230             :                                                                                                                                                  isPlanar:NO
    1231             :                                                                                                                                    colorSpaceName:NSCalibratedWhiteColorSpace
    1232             :                                                                                                                                           bytesPerRow:rowBytes
    1233             :                                                                                                                                          bitsPerPixel:8];
    1234             :         
    1235             :         if (bitmap != nil)
    1236             :         {
    1237             :                 [bitmap autorelease];
    1238             :                 
    1239             :                 NSString *filepath = [[[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:name] stringByAppendingPathExtension:@"png"];
    1240             :                 [[bitmap representationUsingType:NSPNGFileType properties:[NSDictionary dictionary]] writeToFile:filepath atomically:YES];
    1241             :         }
    1242             : }
    1243             : 
    1244             : 
    1245             : - (void) dumpGrayAlphaToFileNamed:(NSString *)name
    1246             :                                                         bytes:(uint8_t *)bytes
    1247             :                                                         width:(NSUInteger)width
    1248             :                                                    height:(NSUInteger)height
    1249             :                                                  rowBytes:(NSUInteger)rowBytes
    1250             : {
    1251             :         if (name == nil || bytes == NULL || width == 0 || height == 0 || rowBytes < width * 2)  return;
    1252             :         
    1253             :         NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:&bytes
    1254             :                                                                                                                                            pixelsWide:width
    1255             :                                                                                                                                            pixelsHigh:height
    1256             :                                                                                                                                         bitsPerSample:8
    1257             :                                                                                                                                   samplesPerPixel:2
    1258             :                                                                                                                                                  hasAlpha:YES
    1259             :                                                                                                                                                  isPlanar:NO
    1260             :                                                                                                                                    colorSpaceName:NSCalibratedWhiteColorSpace
    1261             :                                                                                                                                           bytesPerRow:rowBytes
    1262             :                                                                                                                                          bitsPerPixel:16];
    1263             :         
    1264             :         if (bitmap != nil)
    1265             :         {
    1266             :                 [bitmap autorelease];
    1267             :                 
    1268             :                 NSString *filepath = [[[[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent] stringByAppendingPathComponent:name] stringByAppendingPathExtension:@"png"];
    1269             :                 [[bitmap representationUsingType:NSPNGFileType properties:[NSDictionary dictionary]] writeToFile:filepath atomically:YES];
    1270             :         }
    1271             : }
    1272             : 
    1273             : 
    1274             : - (void) dumpRGBAToRGBFileNamed:(NSString *)rgbName
    1275             :                            andGrayFileNamed:(NSString *)grayName
    1276             :                                                   bytes:(uint8_t *)bytes
    1277             :                                                   width:(NSUInteger)width
    1278             :                                                  height:(NSUInteger)height
    1279             :                                            rowBytes:(NSUInteger)rowBytes
    1280             : {
    1281             :         if ((rgbName == nil && grayName == nil) || bytes == NULL || width == 0 || height == 0 || rowBytes < width * 4)  return;
    1282             :         
    1283             :         uint8_t                         *rgbBytes, *rgbPx, *grayBytes, *grayPx, *srcPx;
    1284             :         NSUInteger                      x, y;
    1285             :         BOOL                            trivalAlpha = YES;
    1286             :         
    1287             :         rgbPx = rgbBytes = malloc(width * height * 3);
    1288             :         if (rgbBytes == NULL)  return;
    1289             :         
    1290             :         grayPx = grayBytes = malloc(width * height);
    1291             :         if (grayBytes == NULL)
    1292             :         {
    1293             :                 free(rgbBytes);
    1294             :                 return;
    1295             :         }
    1296             :         
    1297             :         for (y = 0; y < height; y++)
    1298             :         {
    1299             :                 srcPx = bytes + rowBytes * y;
    1300             :                 
    1301             :                 for (x = 0; x < width; x++)
    1302             :                 {
    1303             :                         *rgbPx++ = *srcPx++;
    1304             :                         *rgbPx++ = *srcPx++;
    1305             :                         *rgbPx++ = *srcPx++;
    1306             :                         trivalAlpha = trivalAlpha && ((*srcPx == 0xFF) || (*srcPx == 0x00));    // Look for any "interesting" pixels in alpha.
    1307             :                         *grayPx++ = *srcPx++;
    1308             :                 }
    1309             :         }
    1310             :         
    1311             :         [self dumpRGBToFileNamed:rgbName
    1312             :                                            bytes:rgbBytes
    1313             :                                            width:width
    1314             :                                           height:height
    1315             :                                         rowBytes:width * 3];
    1316             :         free(rgbBytes);
    1317             :         
    1318             :         if (!trivalAlpha)
    1319             :         {
    1320             :                 [self dumpGrayToFileNamed:grayName
    1321             :                                                         bytes:grayBytes
    1322             :                                                         width:width
    1323             :                                                    height:height
    1324             :                                                  rowBytes:width];
    1325             :         }
    1326             :         free(grayBytes);
    1327             : }
    1328             : 
    1329             : #endif
    1330             : 
    1331             : 
    1332           0 : static void GetDesiredCursorState(OOMouseInteractionMode mode, BOOL *outHidden, BOOL *outObscured)
    1333             : {
    1334             :         NSCParameterAssert(outHidden != NULL && outObscured != NULL);
    1335             :         
    1336             :         *outHidden = (mode == MOUSE_MODE_FLIGHT_WITH_MOUSE_CONTROL);
    1337             :         *outObscured = (mode == MOUSE_MODE_FLIGHT_NO_MOUSE_CONTROL);
    1338             : }
    1339             : 
    1340             : 
    1341           0 : static void ApplyCursorState(OOMouseInteractionMode mode)
    1342             : {
    1343             :         BOOL hidden, obscured;
    1344             :         GetDesiredCursorState(mode, &hidden, &obscured);
    1345             :         if (hidden)  [NSCursor hide];
    1346             :         if (obscured)  [NSCursor setHiddenUntilMouseMoves:YES];
    1347             : }
    1348             : 
    1349             : 
    1350           0 : static void UnapplyCursorState(OOMouseInteractionMode mode)
    1351             : {
    1352             :         BOOL hidden, obscured;
    1353             :         GetDesiredCursorState(mode, &hidden, &obscured);
    1354             :         if (hidden)  [NSCursor unhide];
    1355             :         if (obscured)  [NSCursor setHiddenUntilMouseMoves:NO];
    1356             : }
    1357             : 
    1358             : 
    1359             : - (void) setGammaValue: (float) value
    1360             : {
    1361             :         // no-op
    1362             : }
    1363             : 
    1364             : - (float) gammaValue
    1365             : {
    1366             :         return 1.0;
    1367             : }
    1368             : 
    1369             : 
    1370             : - (void) setFov:(float)value fromFraction:(BOOL)fromFraction
    1371             : {
    1372             :         _fov = fromFraction ? value : tanf((value / 2.0f) * M_PI / 180.0f);
    1373             : }
    1374             : 
    1375             : 
    1376             : - (float) fov:(BOOL)inFraction
    1377             : {
    1378             :         return inFraction ? _fov : 2 * atanf(_fov) * 180.0f / M_PI;
    1379             : }
    1380             : 
    1381             : @end

Generated by: LCOV version 1.14