2005-04-19 19:53:18 +00:00
|
|
|
|
/*
|
|
|
|
|
*
|
|
|
|
|
* Oolite
|
|
|
|
|
*
|
|
|
|
|
* Created by Giles Williams on Sat Apr 03 2004.
|
|
|
|
|
* Copyright (c) 2004 for aegidian.org. All rights reserved.
|
|
|
|
|
*
|
|
|
|
|
|
|
|
|
|
Copyright (c) 2004, Giles C Williams
|
|
|
|
|
All rights reserved.
|
|
|
|
|
|
|
|
|
|
This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike License.
|
|
|
|
|
To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/2.0/
|
|
|
|
|
or send a letter to Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
|
|
|
|
|
|
|
|
|
|
You are free:
|
|
|
|
|
|
|
|
|
|
<EFBFBD> to copy, distribute, display, and perform the work
|
|
|
|
|
<EFBFBD> to make derivative works
|
|
|
|
|
|
|
|
|
|
Under the following conditions:
|
|
|
|
|
|
|
|
|
|
<EFBFBD> Attribution. You must give the original author credit.
|
|
|
|
|
|
|
|
|
|
<EFBFBD> Noncommercial. You may not use this work for commercial purposes.
|
|
|
|
|
|
|
|
|
|
<EFBFBD> Share Alike. If you alter, transform, or build upon this work,
|
|
|
|
|
you may distribute the resulting work only under a license identical to this one.
|
|
|
|
|
|
|
|
|
|
For any reuse or distribution, you must make clear to others the license terms of this work.
|
|
|
|
|
|
|
|
|
|
Any of these conditions can be waived if you get permission from the copyright holder.
|
|
|
|
|
|
|
|
|
|
Your fair use and other rights are in no way affected by the above.
|
|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
//#import <OpenGL/glext.h>
|
|
|
|
|
|
|
|
|
|
#import "MyOpenGLView.h"
|
|
|
|
|
|
|
|
|
|
#import "GameController.h"
|
|
|
|
|
//#import "AppDelegate.h"
|
|
|
|
|
#import "Universe.h"
|
|
|
|
|
#import "TextureStore.h"
|
|
|
|
|
#import "Entity.h"
|
|
|
|
|
#import "PlanetEntity.h"
|
|
|
|
|
#import "OpenGLSprite.h"
|
|
|
|
|
#import "ResourceManager.h"
|
|
|
|
|
|
|
|
|
|
@interface MyOpenGLView(Internal)
|
|
|
|
|
|
|
|
|
|
- (int) translateKeyCode: (int) input;
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@implementation MyOpenGLView
|
|
|
|
|
|
|
|
|
|
- (id) initWithFrame:(NSRect)frameRect
|
|
|
|
|
{
|
|
|
|
|
//NSLog(@"-- initWithFrame MyOpenGLView");
|
|
|
|
|
|
|
|
|
|
// Pixel Format Attributes for the View-based (non-FullScreen) NSOpenGLContext
|
|
|
|
|
NSOpenGLPixelFormatAttribute attrs[] = {
|
|
|
|
|
|
|
|
|
|
// Specifying "NoRecovery" gives us a context that cannot fall back to the software renderer.
|
|
|
|
|
//This makes the View-based context a compatible with the fullscreen context, enabling us to use the "shareContext"
|
|
|
|
|
// feature to share textures, display lists, and other OpenGL objects between the two.
|
|
|
|
|
NSOpenGLPFANoRecovery,
|
|
|
|
|
|
|
|
|
|
// Attributes Common to FullScreen and non-FullScreen
|
|
|
|
|
NSOpenGLPFAColorSize, 32,
|
|
|
|
|
NSOpenGLPFADepthSize, 32,
|
|
|
|
|
NSOpenGLPFADoubleBuffer,
|
|
|
|
|
NSOpenGLPFAAccelerated,
|
|
|
|
|
0
|
|
|
|
|
};
|
|
|
|
|
long rendererID;
|
|
|
|
|
|
|
|
|
|
// Create our non-FullScreen pixel format.
|
|
|
|
|
NSOpenGLPixelFormat* pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
|
|
|
|
|
|
|
|
|
|
// Just as a diagnostic, report the renderer ID that this pixel format binds to. CGLRenderers.h contains a list of known renderers
|
|
|
|
|
// and their corresponding RendererID codes.
|
|
|
|
|
[pixelFormat getValues:&rendererID forAttribute:NSOpenGLPFARendererID forVirtualScreen:0];
|
|
|
|
|
//NSLog(@" init! NSOpenGLView pixelFormat RendererID = %08x", (unsigned)rendererID);
|
|
|
|
|
|
|
|
|
|
self = [super initWithFrame:frameRect pixelFormat:pixelFormat];
|
|
|
|
|
|
|
|
|
|
virtualJoystickPosition = NSMakePoint(0.0,0.0);
|
|
|
|
|
|
|
|
|
|
typedString = [[NSMutableString alloc] initWithString:@""];
|
|
|
|
|
allowingStringInput = NO;
|
|
|
|
|
isAlphabetKeyDown = NO;
|
|
|
|
|
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) dealloc
|
|
|
|
|
{
|
|
|
|
|
if (typedString)
|
|
|
|
|
[typedString release];
|
|
|
|
|
[super dealloc];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) allowStringInput: (BOOL) value
|
|
|
|
|
{
|
|
|
|
|
allowingStringInput = value;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
-(BOOL) allowingStringInput
|
|
|
|
|
{
|
|
|
|
|
return allowingStringInput;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (NSString *) typedString
|
|
|
|
|
{
|
|
|
|
|
return typedString;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) resetTypedString
|
|
|
|
|
{
|
|
|
|
|
[typedString setString:@""];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) setTypedString:(NSString*) value
|
|
|
|
|
{
|
|
|
|
|
// NSLog(@"DEBUG setTypedString:%@",value);
|
|
|
|
|
[typedString setString:value];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- (NSSize) viewSize
|
|
|
|
|
{
|
|
|
|
|
return viewSize;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (GLfloat) display_z
|
|
|
|
|
{
|
|
|
|
|
return display_z;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- (GameController *) gameController
|
|
|
|
|
{
|
|
|
|
|
return gameController;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) setGameController:(GameController *) controller
|
|
|
|
|
{
|
|
|
|
|
gameController = controller;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)drawRect:(NSRect)rect
|
|
|
|
|
{
|
|
|
|
|
// AppDelegate *deleg = (AppDelegate *)[NSApp delegate];
|
|
|
|
|
|
|
|
|
|
if ((viewSize.width != [self frame].size.width)||(viewSize.height != [self frame].size.height)) // resized
|
|
|
|
|
{
|
|
|
|
|
m_glContextInitialized = NO;
|
|
|
|
|
viewSize = [self frame].size;
|
|
|
|
|
|
|
|
|
|
//NSLog(@"DEBUG resized to %.0f x %.0f", viewSize.width, viewSize.height);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!m_glContextInitialized)
|
|
|
|
|
[self initialiseGLWithSize:viewSize];
|
|
|
|
|
|
|
|
|
|
// do all the drawing!
|
|
|
|
|
//
|
|
|
|
|
if ([gameController universe])
|
|
|
|
|
[[gameController universe] drawFromEntity:0];
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
// not set up yet, draw a black screen
|
|
|
|
|
glClearColor( 0.0, 0.0, 0.0, 0.0);
|
|
|
|
|
glClear( GL_COLOR_BUFFER_BIT);
|
|
|
|
|
}
|
|
|
|
|
//
|
|
|
|
|
////
|
|
|
|
|
|
|
|
|
|
[[self openGLContext] flushBuffer];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) initialiseGLWithSize:(NSSize) v_size
|
|
|
|
|
{
|
|
|
|
|
// AppDelegate *deleg = (AppDelegate *)[NSApp delegate];
|
|
|
|
|
GLfloat sun_ambient[] = {0.1, 0.1, 0.1, 1.0};
|
|
|
|
|
GLfloat sun_diffuse[] = {1.0, 1.0, 1.0, 1.0};
|
|
|
|
|
GLfloat sun_specular[] = {1.0, 1.0, 1.0, 1.0};
|
|
|
|
|
GLfloat sun_center_position[] = {4000000.0, 0.0, 0.0, 1.0};
|
|
|
|
|
|
|
|
|
|
viewSize = v_size;
|
|
|
|
|
if (viewSize.width/viewSize.height > 4.0/3.0)
|
|
|
|
|
display_z = 480.0 * viewSize.width/viewSize.height;
|
|
|
|
|
else
|
|
|
|
|
display_z = 640.0;
|
|
|
|
|
|
|
|
|
|
// NSLog(@">>>>> display_z = %.1f", display_z);
|
|
|
|
|
|
|
|
|
|
float ratio = 0.5;
|
|
|
|
|
float aspect = viewSize.height/viewSize.width;
|
|
|
|
|
|
|
|
|
|
glShadeModel(GL_FLAT);
|
|
|
|
|
glClearColor(0.0, 0.0, 0.0, 0.0);
|
|
|
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
|
|
|
[[self openGLContext] flushBuffer];
|
|
|
|
|
|
|
|
|
|
glClearDepth(MAX_CLEAR_DEPTH);
|
|
|
|
|
glViewport( 0, 0, viewSize.width, viewSize.height);
|
|
|
|
|
|
|
|
|
|
squareX = 0.0;
|
|
|
|
|
glMatrixMode(GL_PROJECTION);
|
|
|
|
|
glLoadIdentity(); // reset matrix
|
|
|
|
|
glFrustum( -ratio, ratio, -aspect*ratio, aspect*ratio, 1.0, MAX_CLEAR_DEPTH); // set projection matrix
|
|
|
|
|
|
|
|
|
|
glMatrixMode( GL_MODELVIEW);
|
|
|
|
|
|
|
|
|
|
glEnable( GL_DEPTH_TEST); // depth buffer
|
|
|
|
|
glDepthFunc( GL_LESS); // depth buffer
|
|
|
|
|
|
|
|
|
|
glFrontFace( GL_CCW); // face culling - front faces are AntiClockwise!
|
|
|
|
|
glCullFace( GL_BACK); // face culling
|
|
|
|
|
glEnable( GL_CULL_FACE); // face culling
|
|
|
|
|
|
|
|
|
|
glEnable( GL_BLEND); // alpha blending
|
|
|
|
|
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha blending
|
|
|
|
|
|
|
|
|
|
if ([gameController universe])
|
|
|
|
|
{
|
|
|
|
|
Vector sun_pos = [[[gameController universe] sun] getPosition];
|
|
|
|
|
sun_center_position[0] = sun_pos.x;
|
|
|
|
|
sun_center_position[1] = sun_pos.y;
|
|
|
|
|
sun_center_position[2] = sun_pos.z;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
glLightfv(GL_LIGHT1, GL_AMBIENT, sun_ambient);
|
|
|
|
|
glLightfv(GL_LIGHT1, GL_SPECULAR, sun_specular);
|
|
|
|
|
glLightfv(GL_LIGHT1, GL_DIFFUSE, sun_diffuse);
|
|
|
|
|
glLightfv(GL_LIGHT1, GL_POSITION, sun_center_position);
|
|
|
|
|
|
|
|
|
|
glEnable(GL_LIGHTING); // lighting
|
|
|
|
|
glEnable(GL_LIGHT1); // lighting
|
|
|
|
|
|
|
|
|
|
// world's simplest OpenGL optimisations...
|
|
|
|
|
glHint(GL_TRANSFORM_HINT_APPLE, GL_FASTEST);
|
|
|
|
|
glDisable(GL_NORMALIZE);
|
|
|
|
|
glDisable(GL_RESCALE_NORMAL);
|
|
|
|
|
|
|
|
|
|
m_glContextInitialized = YES;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) snapShot
|
|
|
|
|
{
|
|
|
|
|
//NSRect boundsRect = [self bounds];
|
|
|
|
|
int w = viewSize.width;
|
|
|
|
|
int h = viewSize.height;
|
|
|
|
|
|
|
|
|
|
if (w & 3)
|
|
|
|
|
w = w + 4 - (w & 3);
|
|
|
|
|
|
|
|
|
|
long nPixels = w * h + 1;
|
|
|
|
|
|
|
|
|
|
unsigned char *red = (unsigned char *) malloc( nPixels);
|
|
|
|
|
unsigned char *green = (unsigned char *) malloc( nPixels);
|
|
|
|
|
unsigned char *blue = (unsigned char *) malloc( nPixels);
|
|
|
|
|
|
|
|
|
|
NSString *filepath = [[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent];
|
|
|
|
|
int imageNo = 1;
|
2005-04-30 16:42:09 +00:00
|
|
|
|
|
|
|
|
|
// In the GNUstep source, representationUsingType is marked as
|
|
|
|
|
// TODO: and does nothing but return NIL! So for GNUstep we fall
|
|
|
|
|
// back to the methods used in oolite 1.30.
|
|
|
|
|
#ifdef GNUSTEP
|
|
|
|
|
NSString *pathToPic =
|
|
|
|
|
[filepath stringByAppendingPathComponent:
|
|
|
|
|
[NSString stringWithFormat:@"oolite-%03d.tiff",imageNo]];
|
|
|
|
|
while ([[NSFileManager defaultManager] fileExistsAtPath:pathToPic])
|
|
|
|
|
{
|
|
|
|
|
imageNo++;
|
|
|
|
|
pathToPic = [filepath stringByAppendingPathComponent:[NSString stringWithFormat:@"oolite-%03d.tiff",imageNo]];
|
|
|
|
|
}
|
|
|
|
|
#else
|
2005-04-19 19:53:18 +00:00
|
|
|
|
NSString *pathToPic = [filepath stringByAppendingPathComponent:[NSString stringWithFormat:@"oolite-%03d.png",imageNo]];
|
|
|
|
|
|
|
|
|
|
while ([[NSFileManager defaultManager] fileExistsAtPath:pathToPic])
|
|
|
|
|
{
|
|
|
|
|
imageNo++;
|
|
|
|
|
pathToPic = [filepath stringByAppendingPathComponent:[NSString stringWithFormat:@"oolite-%03d.png",imageNo]];
|
|
|
|
|
}
|
2005-04-30 16:42:09 +00:00
|
|
|
|
|
|
|
|
|
NSString *pathToPng = [[pathToPic stringByDeletingPathExtension] stringByAppendingPathExtension:@"png"];
|
|
|
|
|
#endif
|
2005-04-19 19:53:18 +00:00
|
|
|
|
|
|
|
|
|
NSLog(@">>>>> Snapshot %d x %d file path chosen = %@", w, h, pathToPic);
|
|
|
|
|
|
|
|
|
|
NSBitmapImageRep* bitmapRep =
|
|
|
|
|
[[NSBitmapImageRep alloc]
|
2005-04-30 23:25:21 +00:00
|
|
|
|
initWithBitmapDataPlanes:NULL // --> let the class allocate it
|
2005-04-19 19:53:18 +00:00
|
|
|
|
pixelsWide: w
|
|
|
|
|
pixelsHigh: h
|
|
|
|
|
bitsPerSample: 8 // each component is 8 bits (1 byte)
|
|
|
|
|
samplesPerPixel: 3 // number of components (R, G, B)
|
|
|
|
|
hasAlpha: NO // no transparency
|
|
|
|
|
isPlanar: NO // data integrated into single plane
|
|
|
|
|
colorSpaceName: NSDeviceRGBColorSpace
|
|
|
|
|
bytesPerRow: 0 // --> let the class figure it out
|
|
|
|
|
bitsPerPixel: 0 // --> let the class figure it out
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
unsigned char *pixels = [bitmapRep bitmapData];
|
|
|
|
|
|
|
|
|
|
glReadPixels(0,0, w,h, GL_RED, GL_UNSIGNED_BYTE, red);
|
|
|
|
|
glReadPixels(0,0, w,h, GL_GREEN, GL_UNSIGNED_BYTE, green);
|
|
|
|
|
glReadPixels(0,0, w,h, GL_BLUE, GL_UNSIGNED_BYTE, blue);
|
|
|
|
|
|
|
|
|
|
int x,y;
|
|
|
|
|
for (y = 0; y < h; y++)
|
|
|
|
|
{
|
|
|
|
|
long index = (h - y - 1)*w;
|
|
|
|
|
for (x = 0; x < w; x++) // set bitmap pixels
|
|
|
|
|
{
|
|
|
|
|
*pixels++ = red[index];
|
|
|
|
|
*pixels++ = green[index];
|
|
|
|
|
*pixels++ = blue[index++];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// [[bitmapRep representationUsingType:NSTIFFFileType properties:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithInt:NSTIFFCompressionNone], NSImageCompressionMethod, NULL]]
|
|
|
|
|
// writeToFile:pathToTiff atomically:YES]; // save TIFF representation of Image
|
|
|
|
|
//
|
|
|
|
|
// [[bitmapRep representationUsingType:NSJPEGFileType properties:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithFloat:0.75], NSImageCompressionFactor, NULL]]
|
|
|
|
|
// writeToFile:pathToJpeg atomically:YES]; // save JPEG representation of Image
|
2005-04-30 16:42:09 +00:00
|
|
|
|
#ifdef GNUSTEP
|
|
|
|
|
NSImage *image=[[NSImage alloc] initWithSize:NSMakeSize(w,h)];
|
|
|
|
|
[image addRepresentation:bitmapRep];
|
|
|
|
|
[[image TIFFRepresentation] writeToFile:pathToPic atomically:YES];
|
|
|
|
|
[image release];
|
2005-04-19 19:53:18 +00:00
|
|
|
|
#else
|
|
|
|
|
[[bitmapRep representationUsingType:NSPNGFileType properties:[NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSImageInterlaced, NULL]]
|
|
|
|
|
writeToFile:pathToPng atomically:YES]; // save PNG representation of Image
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
// free allocated objects and memory
|
|
|
|
|
[bitmapRep release];
|
|
|
|
|
free(red);
|
|
|
|
|
free(green);
|
|
|
|
|
free(blue);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (BOOL) acceptsFirstResponder
|
|
|
|
|
{
|
|
|
|
|
return YES;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//- (BOOL)performKeyEquivalent:(NSEvent *)theEvent
|
|
|
|
|
//{
|
|
|
|
|
// if ([gameController inFullScreenMode])
|
|
|
|
|
// {
|
|
|
|
|
// NSLog(@"DEBUG [gameController inFullScreenMode] MyOpenGLView trying to performKeyEquivalent:%@", [theEvent description]);
|
|
|
|
|
// return YES; // simply ignores KeyEquivalent requests which would otherwise be passed to the main menu
|
|
|
|
|
// }
|
|
|
|
|
// else
|
|
|
|
|
// {
|
|
|
|
|
//// NSLog(@"DEBUG [gameController in windowed mode] MyOpenGLView trying to performKeyEquivalent:%@", [theEvent description]);
|
|
|
|
|
// return [super performKeyEquivalent: theEvent];
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|
|
|
|
|
|
- (void) keyUp:(NSEvent *)theEvent
|
|
|
|
|
{
|
|
|
|
|
int key = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
|
|
|
|
|
int keycode = [theEvent keyCode] & 255;
|
|
|
|
|
|
|
|
|
|
// NSLog(@"DEBUG keyUp [theEvent charactersIgnoringModifiers] = %@ keyCode = %d",[theEvent charactersIgnoringModifiers],[theEvent keyCode]);
|
|
|
|
|
|
|
|
|
|
//key = [self translateKeyCode: key];
|
|
|
|
|
key = keycodetrans[keycode]; // retrieve the character we got for pressing the hardware at key location 'keycode'
|
|
|
|
|
|
|
|
|
|
isAlphabetKeyDown = NO;
|
|
|
|
|
if ( key >= 0 && key < [self numKeys] )
|
|
|
|
|
{
|
|
|
|
|
keys[key] = NO;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
NSLog(@"***** translated key: %d out of range\n", key);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) keyDown:(NSEvent *)theEvent
|
|
|
|
|
{
|
|
|
|
|
int key = [[theEvent charactersIgnoringModifiers] characterAtIndex:0];
|
|
|
|
|
int keycode = [theEvent keyCode] & 255;
|
|
|
|
|
|
|
|
|
|
// NSLog(@"DEBUG keyDown [theEvent charactersIgnoringModifiers] = %@ keyCode = %d",[theEvent charactersIgnoringModifiers],[theEvent keyCode]);
|
|
|
|
|
|
|
|
|
|
key = [self translateKeyCode: key];
|
|
|
|
|
|
|
|
|
|
keycodetrans[keycode] = key; // record the chracter we got for pressing the hardware at key location 'keycode'
|
|
|
|
|
|
|
|
|
|
if ((key >= 0)&&(key < [self numKeys]))
|
|
|
|
|
{
|
|
|
|
|
//NSLog( @"key : %d", key );
|
|
|
|
|
keys[key] = YES;
|
|
|
|
|
|
|
|
|
|
if (allowingStringInput)
|
|
|
|
|
{
|
|
|
|
|
if (((key > 64)&&(key < 91))||((key > 96)&&(key < 123)))
|
|
|
|
|
{
|
|
|
|
|
// alphanumeric
|
|
|
|
|
isAlphabetKeyDown = YES;
|
|
|
|
|
// convert to lowercase
|
|
|
|
|
[typedString appendFormat:@"%c", (key | 64)];
|
|
|
|
|
//NSLog(@"accumulated string '%@'",typedString);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
isAlphabetKeyDown = NO;
|
|
|
|
|
if (key == NSDeleteCharacter)
|
|
|
|
|
{
|
|
|
|
|
//delete
|
|
|
|
|
[typedString setString:@""];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
NSLog(@"***** translated key: %d out of range\n", key);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Capture shift, ctrl, opt and command press & release */
|
|
|
|
|
- (void)flagsChanged:(NSEvent *)theEvent
|
|
|
|
|
{
|
|
|
|
|
int flags = [theEvent modifierFlags];
|
|
|
|
|
opt = (flags & NSAlternateKeyMask) ? YES : NO;
|
|
|
|
|
ctrl = (flags & NSControlKeyMask) ? YES : NO;
|
|
|
|
|
command = (flags & NSCommandKeyMask) ? YES : NO;
|
|
|
|
|
shift = ( flags & NSShiftKeyMask ) ? YES : NO;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)mouseDown:(NSEvent *)theEvent
|
|
|
|
|
{
|
|
|
|
|
keys[gvMouseLeftButton] = YES; // 'a' down
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)mouseUp:(NSEvent *)theEvent
|
|
|
|
|
{
|
|
|
|
|
keys[gvMouseLeftButton] = NO; // 'a' up
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)mouseDragged:(NSEvent *)theEvent
|
|
|
|
|
{
|
|
|
|
|
squareX = [theEvent locationInWindow].x - mouseDragStartPoint.x;
|
|
|
|
|
squareY = [theEvent locationInWindow].y - mouseDragStartPoint.y;
|
|
|
|
|
[self setNeedsDisplay:YES];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void)mouseMoved:(NSEvent *)theEvent
|
|
|
|
|
{
|
|
|
|
|
double mx = [theEvent locationInWindow].x - viewSize.width/2.0;
|
|
|
|
|
double my = [theEvent locationInWindow].y - viewSize.height/2.0;
|
|
|
|
|
|
|
|
|
|
if (display_z > 640.0)
|
|
|
|
|
{
|
|
|
|
|
mx /= viewSize.width * MAIN_GUI_PIXEL_WIDTH / display_z;
|
|
|
|
|
my /= viewSize.height;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
mx /= MAIN_GUI_PIXEL_WIDTH * viewSize.width / 640.0;
|
|
|
|
|
my /= MAIN_GUI_PIXEL_HEIGHT * viewSize.width / 640.0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
[self setVirtualJoystick:mx :-my];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////
|
|
|
|
|
/* Turn the Cocoa ArrowKeys into our arrow key constants. */
|
|
|
|
|
- (int) translateKeyCode: (int) input
|
|
|
|
|
{
|
|
|
|
|
int key = input;
|
|
|
|
|
switch ( input )
|
|
|
|
|
{
|
|
|
|
|
case NSUpArrowFunctionKey:
|
|
|
|
|
key = gvArrowKeyUp;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NSDownArrowFunctionKey:
|
|
|
|
|
key = gvArrowKeyDown;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NSLeftArrowFunctionKey:
|
|
|
|
|
key = gvArrowKeyLeft;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NSRightArrowFunctionKey:
|
|
|
|
|
key = gvArrowKeyRight;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NSF1FunctionKey:
|
|
|
|
|
key = gvFunctionKey1;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NSF2FunctionKey:
|
|
|
|
|
key = gvFunctionKey2;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NSF3FunctionKey:
|
|
|
|
|
key = gvFunctionKey3;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NSF4FunctionKey:
|
|
|
|
|
key = gvFunctionKey4;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NSF5FunctionKey:
|
|
|
|
|
key = gvFunctionKey5;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NSF6FunctionKey:
|
|
|
|
|
key = gvFunctionKey6;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NSF7FunctionKey:
|
|
|
|
|
key = gvFunctionKey7;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NSF8FunctionKey:
|
|
|
|
|
key = gvFunctionKey8;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NSF9FunctionKey:
|
|
|
|
|
key = gvFunctionKey9;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NSF10FunctionKey:
|
|
|
|
|
key = gvFunctionKey10;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NSF11FunctionKey:
|
|
|
|
|
key = gvFunctionKey11;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NSHomeFunctionKey:
|
|
|
|
|
key = gvHomeKey;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return key;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) setVirtualJoystick:(double) vmx :(double) vmy
|
|
|
|
|
{
|
|
|
|
|
virtualJoystickPosition.x = vmx;
|
|
|
|
|
virtualJoystickPosition.y = vmy;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (NSPoint) virtualJoystickPosition
|
|
|
|
|
{
|
|
|
|
|
return virtualJoystickPosition;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
- (void) clearKeys
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
for (i = 0; i < [self numKeys]; i++)
|
|
|
|
|
keys[i] = NO;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (BOOL) isAlphabetKeyDown
|
|
|
|
|
{
|
|
|
|
|
return isAlphabetKeyDown = NO;;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (BOOL) isDown: (int) key
|
|
|
|
|
{
|
|
|
|
|
if ( key < 0 )
|
|
|
|
|
return NO;
|
|
|
|
|
if ( key >= [self numKeys] )
|
|
|
|
|
return NO;
|
|
|
|
|
return keys[key];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (BOOL) isOptDown
|
|
|
|
|
{
|
|
|
|
|
return opt;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (BOOL) isCtrlDown
|
|
|
|
|
{
|
|
|
|
|
return ctrl;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (BOOL) isCommandDown
|
|
|
|
|
{
|
|
|
|
|
return command;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (BOOL) isShiftDown
|
|
|
|
|
{
|
|
|
|
|
return shift;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (int) numKeys
|
|
|
|
|
{
|
|
|
|
|
return NUM_KEYS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|