Merged SDL2 changes from bartbes/love-experiments/SDL2 into default.

- Added love.system module, including clipboard functions.

- Added custom hardware cursors (love.mouse.newCursor, love.mouse.setCursor.)

- Revamped love.joystick:
-- added Joystick objects and moved love.joystick functions which operated on individual joysticks to methods on the Joystick objects.
-- Added love.joystick.getJoystick and love.joystick.getJoystickCount.
-- Added events for when joysticks are connected and disconnected.
-- Added 'Gamepad' methods to Joystick objects: Joystick:isGamepad, Joystick:getGamepadAxis, and Joystick:isGamepadDown. They're a common abstraction for xbox controller-like joystick across operating systems.

- Added monitor choosing support and "fullscreen desktop" mode to love.window.

- Moved unicode text input events to their own callback function (love.textinput), removed the key repeat functions from love.keyboard and made the second argument of love.keypressed a boolean saying whether the keypress was a repeat.

- liblove now works with love.window and love.graphics in OS X
This commit is contained in:
Alex Szpakowski
2013-08-25 16:51:42 -03:00
parent 035130533b
commit 113ed1cfe7
67 changed files with 4691 additions and 1665 deletions
+47
View File
@@ -0,0 +1,47 @@
/**
* Copyright (c) 2006-2013 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_OSX_H
#define LOVE_OSX_H
#include <string>
namespace love
{
namespace osx
{
/**
* Returns the filepath of the first detected love file in the Resources folder
* in love.app.
* Returns an empty string if no love file is found.
**/
std::string getLoveInResources();
/**
* Checks for drop-file events. Returns the filepath if an event occurred, or
* an empty string otherwise.
**/
std::string checkDropEvents();
} // osx
} // love
#endif // LOVE_OSX_H
+72
View File
@@ -0,0 +1,72 @@
/**
* Copyright (c) 2006-2013 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#import "osx.h"
#import <Foundation/Foundation.h>
#include <SDL2/SDL.h>
namespace love
{
namespace osx
{
std::string getLoveInResources()
{
std::string path;
// check to see if there are any .love files in Resources - props to stevejohnson/diordna
NSArray *lovePaths = [[NSBundle mainBundle] pathsForResourcesOfType:@"love" inDirectory:nil];
if ([lovePaths count] > 0)
{
NSString *firstLovePath = [lovePaths objectAtIndex:0];
path = std::string([firstLovePath UTF8String]);
}
return path;
}
std::string checkDropEvents()
{
std::string dropstr;
SDL_Event event;
bool initvideo = SDL_WasInit(SDL_INIT_VIDEO) != 0;
if (!initvideo)
SDL_InitSubSystem(SDL_INIT_VIDEO);
SDL_PumpEvents();
if (SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_DROPFILE, SDL_DROPFILE) > 0)
{
if (event.type == SDL_DROPFILE)
{
dropstr = std::string(event.drop.file);
SDL_free(event.drop.file);
}
}
if (!initvideo)
SDL_QuitSubSystem(SDL_INIT_VIDEO);
return dropstr;
}
} // osx
} // love
-12
View File
@@ -1,12 +0,0 @@
/* SDLMain.m - main entry point for our Cocoa-ized SDL app
Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
Non-NIB-Code & other changes: Max Horn <max@quendi.de>
Feel free to customize this file to suit your needs
*/
#import <Cocoa/Cocoa.h>
#include "SDL/SDL.h"
@interface SDLMain : NSObject
@end
-464
View File
@@ -1,464 +0,0 @@
/* SDLMain.m - main entry point for our Cocoa-ized SDL app
Initial Version: Darrell Walisser <dwaliss1@purdue.edu>
Non-NIB-Code & other changes: Max Horn <max@quendi.de>
Feel free to customize this file to suit your needs
*/
//#import "SDL.h"
#import "SDLMain.h"
#import <sys/param.h> /* for MAXPATHLEN */
#import <unistd.h>
/* Use this flag to determine whether we use SDLMain.nib or not */
#define SDL_USE_NIB_FILE 0
/* Use this flag to determine whether we use CPS (docking) or not */
/* We can't submit to the Mac App Store with this enabled: */
/* http://www.philhassey.com/blog/2011/02/ */
/*#define SDL_USE_CPS 1 */
#ifdef SDL_USE_CPS
/* Portions of CPS.h */
typedef struct CPSProcessSerNum
{
UInt32 lo;
UInt32 hi;
} CPSProcessSerNum;
extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);
extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);
#endif /* SDL_USE_CPS */
static int gArgc;
static char **gArgv;
static BOOL gFinderLaunch;
static BOOL gCalledAppMainline = FALSE;
static NSString *getApplicationName(void)
{
NSDictionary *dict;
NSString *appName = 0;
/* Determine the application name */
dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
if (dict)
appName = [dict objectForKey: @"CFBundleName"];
if (![appName length])
appName = [[NSProcessInfo processInfo] processName];
return appName;
}
#if SDL_USE_NIB_FILE
/* A helper category for NSString */
@interface NSString (ReplaceSubString)
- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString;
@end
#endif
@interface SDLApplication : NSApplication
@end
@implementation SDLApplication
/* Invoked from the Quit menu item */
- (void)terminate:(id)sender
{
/* Post a SDL_QUIT event */
SDL_Event event;
event.type = SDL_QUIT;
SDL_PushEvent(&event);
}
/* Hack to make Cocoa ignore keystrokes that aren't shortcuts, otherwise it beeps on every key press */
- (void)sendEvent:(NSEvent *)theEvent {
if (NSKeyDown == [theEvent type] || NSKeyUp == [theEvent type]) {
if ([theEvent modifierFlags] & NSCommandKeyMask)
[super sendEvent: theEvent];
} else {
[super sendEvent: theEvent];
}
}
@end
/* The main class of the application, the application's delegate */
@implementation SDLMain
/* Set the working directory to the .app's parent directory */
/*CHANGED to Bundle's Resource Directory. */
- (void) setupWorkingDirectory:(BOOL)shouldChdir
{
if (shouldChdir)
{
/*
char parentdir[PATH_MAX];
//CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
CFURLRef url = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle());
CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url);
if (CFURLGetFileSystemRepresentation(url2, true, (UInt8 *)parentdir, PATH_MAX)) {
assert ( chdir (parentdir) == 0 ); // chdir to the binary app's parent //
}
CFRelease(url);
CFRelease(url2);
*/
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle);
char path[PATH_MAX];
if (!CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8 *)path, PATH_MAX))
{
// error!
}
CFRelease(resourcesURL);
chdir(path);
}
}
#if SDL_USE_NIB_FILE
/* Fix menu to contain the real app name instead of "SDL App" */
- (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName
{
NSRange aRange;
NSEnumerator *enumerator;
NSMenuItem *menuItem;
aRange = [[aMenu title] rangeOfString:@"SDL App"];
if (aRange.length != 0)
[aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]];
enumerator = [[aMenu itemArray] objectEnumerator];
while ((menuItem = [enumerator nextObject]))
{
aRange = [[menuItem title] rangeOfString:@"SDL App"];
if (aRange.length != 0)
[menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]];
if ([menuItem hasSubmenu])
[self fixMenu:[menuItem submenu] withAppName:appName];
}
[ aMenu sizeToFit ];
}
#else
static void setApplicationMenu(void)
{
/* warning: this code is very odd */
NSMenu *appleMenu;
NSMenuItem *menuItem;
NSString *title;
NSString *appName;
appName = getApplicationName();
appleMenu = [[NSMenu alloc] initWithTitle:@""];
/* Add menu items */
title = [@"About " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
[appleMenu addItem:[NSMenuItem separatorItem]];
title = [@"Hide " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
[menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
[appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
[appleMenu addItem:[NSMenuItem separatorItem]];
title = [@"Quit " stringByAppendingString:appName];
[appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
/* Put menu into the menubar */
menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
[menuItem setSubmenu:appleMenu];
[[NSApp mainMenu] addItem:menuItem];
/* Finally give up our references to the objects */
[appleMenu release];
[menuItem release];
}
/* Create a window menu */
static void setupWindowMenu(void)
{
NSMenu *windowMenu;
NSMenuItem *windowMenuItem;
NSMenuItem *menuItem;
windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
/* "Minimize" item */
menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
[windowMenu addItem:menuItem];
[menuItem release];
/* Put menu into the menubar */
windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
[windowMenuItem setSubmenu:windowMenu];
[[NSApp mainMenu] addItem:windowMenuItem];
/* Tell the application object that this is now the window menu */
[NSApp setWindowsMenu:windowMenu];
/* Finally give up our references to the objects */
[windowMenu release];
[windowMenuItem release];
}
/* Replacement for NSApplicationMain */
static void CustomApplicationMain (int argc, char **argv)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
SDLMain *sdlMain;
/* Ensure the application object is initialised */
[SDLApplication sharedApplication];
#ifdef SDL_USE_CPS
{
CPSProcessSerNum PSN;
/* Tell the dock about us */
if (!CPSGetCurrentProcess(&PSN))
if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
if (!CPSSetFrontProcess(&PSN))
[SDLApplication sharedApplication];
}
#else
{
ProcessSerialNumber psn;
if (!GetCurrentProcess(&psn)) {
TransformProcessType(&psn, kProcessTransformToForegroundApplication);
SetFrontProcess(&psn);
}
}
#endif /* SDL_USE_CPS */
/* Set up the menubar */
[NSApp setMainMenu:[[[NSMenu alloc] init] autorelease]];
setApplicationMenu();
setupWindowMenu();
/* Create SDLMain and make it the app delegate */
sdlMain = [[SDLMain alloc] init];
[NSApp setDelegate:sdlMain];
/* Start the main event loop */
[NSApp run];
[sdlMain release];
[pool release];
}
#endif
/*
* Catch document open requests...this lets us notice files when the app
* was launched by double-clicking a document, or when a document was
* dragged/dropped on the app's icon. You need to have a
* CFBundleDocumentsType section in your Info.plist to get this message,
* apparently.
*
* Files are added to gArgv, so to the app, they'll look like command line
* arguments. Previously, apps launched from the finder had nothing but
* an argv[0].
*
* This message may be received multiple times to open several docs on launch.
*
* This message is ignored once the app's mainline has been called.
*/
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
{
const char *temparg;
size_t arglen;
char *arg;
char **newargv;
// Disabled because the method for detecting this doesn't work in OS 10.9.
// if (!gFinderLaunch) /* MacOS is passing command line args. */
// return FALSE;
if (gCalledAppMainline) /* app has started, ignore this document. */
return FALSE;
temparg = [filename UTF8String];
arglen = SDL_strlen(temparg) + 1;
arg = (char *) SDL_malloc(arglen);
if (arg == NULL)
return FALSE;
newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2));
if (newargv == NULL)
{
SDL_free(arg);
return FALSE;
}
gArgv = newargv;
SDL_strlcpy(arg, temparg, arglen);
gArgv[gArgc++] = arg;
gArgv[gArgc] = NULL;
return TRUE;
}
/* Called when the internal event loop has just started running */
- (void) applicationDidFinishLaunching: (NSNotification *) note
{
int status;
/* Set the working directory to the .app's Resources folder */
[self setupWorkingDirectory:gCalledAppMainline];
#if SDL_USE_NIB_FILE
/* Set the main menu to contain the real app name instead of "SDL App" */
[self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()];
#endif
/* Set up the app to receive menu events via keyboard shortcut */
setenv("SDL_ENABLEAPPEVENTS", "1", 1);
/* Hand off to main application code */
gCalledAppMainline = TRUE;
status = SDL_main (gArgc, gArgv);
/* We're done, thank you for playing */
exit(status);
}
@end
@implementation NSString (ReplaceSubString)
- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
{
unsigned int bufferSize;
unsigned int selfLen = [self length];
unsigned int aStringLen = [aString length];
unichar *buffer;
NSRange localRange;
NSString *result;
bufferSize = selfLen + aStringLen - aRange.length;
buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar));
/* Get first part into buffer */
localRange.location = 0;
localRange.length = aRange.location;
[self getCharacters:buffer range:localRange];
/* Get middle part into buffer */
localRange.location = 0;
localRange.length = aStringLen;
[aString getCharacters:(buffer+aRange.location) range:localRange];
/* Get last part into buffer */
localRange.location = aRange.location + aRange.length;
localRange.length = selfLen - localRange.location;
[self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];
/* Build output string */
result = [NSString stringWithCharacters:buffer length:bufferSize];
NSDeallocateMemoryPages(buffer, bufferSize);
return result;
}
@end
#ifdef main
# undef main
#endif
/* Main entry point to executable - should *not* be SDL_main! */
int main (int argc, char **argv)
{
/* Copy the arguments into a global variable */
/* This is passed if we are launched by double-clicking */
if (argc >= 2 && strncmp (argv[1], "-psn", 4) == 0)
{
gArgv = (char **) SDL_malloc(sizeof (char *) * 2);
gArgv[0] = argv[0];
gArgv[1] = NULL;
gArgc = 1;
gFinderLaunch = YES;
}
else
{
int i;
gArgc = argc;
gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1));
for (i = 0; i <= argc; i++)
gArgv[i] = argv[i];
gFinderLaunch = NO;
}
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
/* check to see if there are any .love files in Resources - props to stevejohnson/diordna */
NSArray *lovePaths = [[NSBundle mainBundle] pathsForResourcesOfType:@"love" inDirectory:nil];
if ([lovePaths count] > 0) /* there are, load the first one we found and run it */
{
NSString *firstLovePath = [lovePaths objectAtIndex:0];
gCalledAppMainline = YES;
const char *temparg;
size_t arglen;
char *arg;
char **newargv;
temparg = [firstLovePath UTF8String];
arglen = SDL_strlen(temparg) + 1;
arg = (char *)SDL_malloc(arglen);
if (arg == NULL)
return FALSE;
const char *fusedstr = "--fused";
size_t fusedarglen = SDL_strlen(fusedstr) + 1;
char *fusedarg = (char *) SDL_malloc(fusedarglen);
if (fusedarg == NULL)
{
SDL_free(arg);
return FALSE;
}
newargv = (char **) realloc(gArgv, sizeof(char *) * (gArgc + 3));
if (newargv == NULL)
{
SDL_free(arg);
SDL_free(fusedarg);
return FALSE;
}
gArgv = newargv;
SDL_strlcpy(arg, temparg, arglen);
SDL_strlcpy(fusedarg, fusedstr, fusedarglen);
gArgv[gArgc++] = arg;
gArgv[gArgc++] = fusedarg; // run in pseudo-fused mode
gArgv[gArgc] = NULL;
}
[pool drain];
#if SDL_USE_NIB_FILE
[SDLApplication poseAsClass:[NSApplication class]];
NSApplicationMain (argc, argv);
#else
CustomApplicationMain (argc, argv);
#endif
return 0;
}
@@ -135,9 +135,8 @@
FA08F63016C7542600F007B5 /* DevilHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1AA7781A230065F346E2313A /* DevilHandler.cpp */; };
FA08F63116C7542600F007B5 /* wrap_Image.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0B0728FA73B107B37A956A09 /* wrap_Image.cpp */; };
FA08F63216C7542600F007B5 /* wrap_ImageData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 076840774B0B6E721D0C18D0 /* wrap_ImageData.cpp */; };
FA08F63316C7542D00F007B5 /* Joystick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 677F545C76EA3B247329358D /* Joystick.cpp */; };
FA08F63416C7542D00F007B5 /* Joystick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 55B425307C0C1C4B3EFC3A5F /* Joystick.cpp */; };
FA08F63516C7542D00F007B5 /* wrap_Joystick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 139411436818381E493F00F5 /* wrap_Joystick.cpp */; };
FA08F63416C7542D00F007B5 /* JoystickModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 55B425307C0C1C4B3EFC3A5F /* JoystickModule.cpp */; };
FA08F63516C7542D00F007B5 /* wrap_JoystickModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 139411436818381E493F00F5 /* wrap_JoystickModule.cpp */; };
FA08F63616C7543400F007B5 /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 524741891BB93848039F4174 /* Keyboard.cpp */; };
FA08F63716C7543400F007B5 /* Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43BC2B1C505E5EFF650C31E3 /* Keyboard.cpp */; };
FA08F63816C7543400F007B5 /* wrap_Keyboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 19F40DF6507028212FEB1D77 /* wrap_Keyboard.cpp */; };
@@ -208,6 +207,18 @@
FA08F67B16C754BA00F007B5 /* Window.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 351B09E51FDC338622F44624 /* Window.cpp */; };
FA08F67C16C754BA00F007B5 /* Window.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6CDD4F3320303D222C180CD0 /* Window.cpp */; };
FA0CDE3D1710F9A50056E8D7 /* FormatHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = FA0CDE3B1710F9A50056E8D7 /* FormatHandler.h */; };
FA1EF7C41799FEAC00FF380C /* wrap_System.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA34E7D4174B55AF00E04D3F /* wrap_System.cpp */; };
FA1EF7C51799FEB200FF380C /* wrap_System.h in Headers */ = {isa = PBXBuildFile; fileRef = FA34E7D5174B55AF00E04D3F /* wrap_System.h */; };
FA34E7CD174B513F00E04D3F /* System.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA34E7CB174B513F00E04D3F /* System.cpp */; };
FA34E7CE174B513F00E04D3F /* System.h in Headers */ = {isa = PBXBuildFile; fileRef = FA34E7CC174B513F00E04D3F /* System.h */; };
FA34E7D2174B515D00E04D3F /* System.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA34E7D0174B515D00E04D3F /* System.cpp */; };
FA34E7D3174B515D00E04D3F /* System.h in Headers */ = {isa = PBXBuildFile; fileRef = FA34E7D1174B515D00E04D3F /* System.h */; };
FA3D9E0D16E68DE600CA6630 /* Cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA3D9E0B16E68DE600CA6630 /* Cursor.cpp */; };
FA3D9E0E16E68DE600CA6630 /* Cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = FA3D9E0C16E68DE600CA6630 /* Cursor.h */; };
FA3D9E1116E68EAE00CA6630 /* Cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA3D9E0F16E68EAE00CA6630 /* Cursor.cpp */; };
FA3D9E1216E68EAE00CA6630 /* Cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = FA3D9E1016E68EAE00CA6630 /* Cursor.h */; };
FA3D9E1516E6D41100CA6630 /* wrap_Cursor.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA3D9E1316E6D41000CA6630 /* wrap_Cursor.cpp */; };
FA3D9E1616E6D41100CA6630 /* wrap_Cursor.h in Headers */ = {isa = PBXBuildFile; fileRef = FA3D9E1416E6D41000CA6630 /* wrap_Cursor.h */; };
FA435EA317B36E9C004C3F22 /* Polyline.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA435EA117B36E9C004C3F22 /* Polyline.cpp */; };
FA435EA417B36E9C004C3F22 /* Polyline.h in Headers */ = {isa = PBXBuildFile; fileRef = FA435EA217B36E9C004C3F22 /* Polyline.h */; };
FA5454C216F1310000D30303 /* MathModule.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA5454C016F1310000D30303 /* MathModule.cpp */; };
@@ -222,7 +233,6 @@
FA577AC816C7513C00860150 /* Ogg.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7116C719F400860150 /* Ogg.framework */; };
FA577ACA16C7514100860150 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7C16C71A2600860150 /* OpenGL.framework */; };
FA577ACB16C7514400860150 /* physfs.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7316C719F900860150 /* physfs.framework */; };
FA577ACC16C7514700860150 /* SDL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7516C719FF00860150 /* SDL.framework */; };
FA577ACD16C7514C00860150 /* Vorbis.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA577A7716C71A0800860150 /* Vorbis.framework */; };
FA5FDC791788D548002F0ED2 /* enet.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC5F1788D548002F0ED2 /* enet.cpp */; };
FA5FDC7A1788D548002F0ED2 /* callbacks.c in Sources */ = {isa = PBXBuildFile; fileRef = FA5FDC611788D548002F0ED2 /* callbacks.c */; };
@@ -251,11 +261,18 @@
FA7175AA178E8418001FE7FE /* lua.h in Headers */ = {isa = PBXBuildFile; fileRef = FA7175A9178E8418001FE7FE /* lua.h */; };
FA7C937A16DCC6C2006F2BEE /* wrap_Math.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA7C937516DCC6C2006F2BEE /* wrap_Math.cpp */; };
FA7C937B16DCC6C2006F2BEE /* wrap_Math.h in Headers */ = {isa = PBXBuildFile; fileRef = FA7C937616DCC6C2006F2BEE /* wrap_Math.h */; };
FA9B4A0816E1578300074F42 /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA9B4A0716E1578300074F42 /* SDL2.framework */; };
FA9FC0B0173D6E3E005027FF /* wrap_Window.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FA9FC0AE173D6E3E005027FF /* wrap_Window.cpp */; };
FA9FC0B1173D6E3E005027FF /* wrap_Window.h in Headers */ = {isa = PBXBuildFile; fileRef = FA9FC0AF173D6E3E005027FF /* wrap_Window.h */; };
FAAC6B02170A373B008A61C5 /* CompressedData.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAAC6B00170A373A008A61C5 /* CompressedData.cpp */; };
FAAC6B03170A373B008A61C5 /* CompressedData.h in Headers */ = {isa = PBXBuildFile; fileRef = FAAC6B01170A373A008A61C5 /* CompressedData.h */; };
FAAFF04416CB11C700CCDE45 /* OpenAL-Soft.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAAFF04316CB11C700CCDE45 /* OpenAL-Soft.framework */; };
FAB0078F1740C12D00A9664D /* Joystick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB0078D1740C12D00A9664D /* Joystick.cpp */; };
FAB007901740C12D00A9664D /* Joystick.h in Headers */ = {isa = PBXBuildFile; fileRef = FAB0078E1740C12D00A9664D /* Joystick.h */; };
FAB007931740C28900A9664D /* Joystick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB007911740C28900A9664D /* Joystick.cpp */; };
FAB007941740C28900A9664D /* Joystick.h in Headers */ = {isa = PBXBuildFile; fileRef = FAB007921740C28900A9664D /* Joystick.h */; };
FAB007971740C87D00A9664D /* wrap_Joystick.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB007951740C87D00A9664D /* wrap_Joystick.cpp */; };
FAB007981740C87D00A9664D /* wrap_Joystick.h in Headers */ = {isa = PBXBuildFile; fileRef = FAB007961740C87D00A9664D /* wrap_Joystick.h */; };
FAC5710017402D1100D147E4 /* BezierCurve.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC570FC17402D1100D147E4 /* BezierCurve.cpp */; };
FAC5710117402D1100D147E4 /* BezierCurve.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC570FD17402D1100D147E4 /* BezierCurve.h */; };
FAC5710217402D1100D147E4 /* wrap_BezierCurve.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC570FE17402D1100D147E4 /* wrap_BezierCurve.cpp */; };
@@ -373,7 +390,7 @@
131F69C3368C4B8A55EE0DAD /* wrap_WeldJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_WeldJoint.h; sourceTree = "<group>"; };
135801A6483528800C676492 /* io.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = io.c; sourceTree = "<group>"; };
138913BE5126483748FA43D0 /* Joint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Joint.h; sourceTree = "<group>"; };
139411436818381E493F00F5 /* wrap_Joystick.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Joystick.cpp; sourceTree = "<group>"; };
139411436818381E493F00F5 /* wrap_JoystickModule.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_JoystickModule.cpp; sourceTree = "<group>"; };
14AE68E14C2C74526A612FA0 /* wrap_Image.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Image.cpp; sourceTree = "<group>"; };
15093E1B1A14176374C81299 /* wrap_CircleShape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_CircleShape.h; sourceTree = "<group>"; };
153957EB332E1269671E7F4A /* b2CircleShape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2CircleShape.h; sourceTree = "<group>"; };
@@ -453,7 +470,7 @@
2CAE75B079B828FE6892684A /* udp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = udp.h; sourceTree = "<group>"; };
2CEC5ED5211174C7583849AD /* Reference.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Reference.h; sourceTree = "<group>"; };
2D290E902C451D6849051FEF /* b2WeldJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2WeldJoint.h; sourceTree = "<group>"; };
2D7B7DEC4FC87878332E41B3 /* wrap_Joystick.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_Joystick.h; sourceTree = "<group>"; };
2D7B7DEC4FC87878332E41B3 /* wrap_JoystickModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_JoystickModule.h; sourceTree = "<group>"; };
2D8E6FAE2A100B5866E96BFF /* runtime.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = runtime.h; sourceTree = "<group>"; };
2D9475890CDA3D3776435622 /* Timer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Timer.h; sourceTree = "<group>"; };
2DC90F3C6160198256795C75 /* luasocket.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = luasocket.cpp; sourceTree = "<group>"; };
@@ -523,7 +540,7 @@
415E1438178736BE0EA908D5 /* select.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = select.c; sourceTree = "<group>"; };
426B1C4475DC54505B824B7F /* VertexBuffer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = VertexBuffer.cpp; sourceTree = "<group>"; };
427B4B2517C0516844370E3D /* b2CollidePolygon.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2CollidePolygon.cpp; sourceTree = "<group>"; };
439E46D768A266780E894800 /* Joystick.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Joystick.h; sourceTree = "<group>"; };
439E46D768A266780E894800 /* JoystickModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JoystickModule.h; sourceTree = "<group>"; };
43A258C229C75C15238E520C /* Decoder.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Decoder.h; sourceTree = "<group>"; };
43BC2B1C505E5EFF650C31E3 /* Keyboard.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Keyboard.cpp; sourceTree = "<group>"; };
448C492C7AEB7840504F1C9D /* b2EdgeShape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2EdgeShape.h; sourceTree = "<group>"; };
@@ -554,7 +571,7 @@
4B41232F7AF7793540F46C58 /* timeout.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = timeout.c; sourceTree = "<group>"; };
4B5F4DF8110020A96B5D3EAB /* b2BroadPhase.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2BroadPhase.cpp; sourceTree = "<group>"; };
4B731754147B27AF73AC5358 /* Volatile.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Volatile.cpp; sourceTree = "<group>"; };
4C606AEC342457600C3F0741 /* Joystick.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Joystick.h; sourceTree = "<group>"; };
4C606AEC342457600C3F0741 /* JoystickModule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JoystickModule.h; sourceTree = "<group>"; };
4D700D182EAA46273D1E2CC4 /* SpriteBatch.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = SpriteBatch.cpp; sourceTree = "<group>"; };
4D81102E7ABD1C282BE42CE3 /* wrap_MouseJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_MouseJoint.cpp; sourceTree = "<group>"; };
4DAB28A9235E2CBE75F56848 /* CircleShape.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = CircleShape.cpp; sourceTree = "<group>"; };
@@ -585,7 +602,7 @@
54E85987318206E93DC8189F /* PolygonShape.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = PolygonShape.cpp; sourceTree = "<group>"; };
55A759CE711E157339930E58 /* b2BlockAllocator.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2BlockAllocator.cpp; sourceTree = "<group>"; };
55AE226405CC1A55462E1D89 /* threads.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = threads.h; sourceTree = "<group>"; };
55B425307C0C1C4B3EFC3A5F /* Joystick.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Joystick.cpp; sourceTree = "<group>"; };
55B425307C0C1C4B3EFC3A5F /* JoystickModule.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JoystickModule.cpp; sourceTree = "<group>"; };
561D4A4722E36BAA16D17CC8 /* EdgeShape.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EdgeShape.h; sourceTree = "<group>"; };
567C0A0C58931DE54733011B /* b2StackAllocator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2StackAllocator.h; sourceTree = "<group>"; };
56D6030A0B8F7397715062B9 /* Image.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Image.cpp; sourceTree = "<group>"; };
@@ -641,7 +658,6 @@
6590063A6E4B3AEF4550443C /* b2GearJoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = b2GearJoint.h; sourceTree = "<group>"; };
66EC3C0463A703A97445193B /* b2PulleyJoint.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = b2PulleyJoint.cpp; sourceTree = "<group>"; };
66F8479E6D2D587A592F2024 /* socket.lua.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = socket.lua.h; sourceTree = "<group>"; };
677F545C76EA3B247329358D /* Joystick.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = Joystick.cpp; sourceTree = "<group>"; };
678E42771C9B415628A3234D /* wrap_ParticleSystem.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = wrap_ParticleSystem.h; sourceTree = "<group>"; };
68616BD516DB124312B47EB3 /* Image.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Image.h; sourceTree = "<group>"; };
691C5C5828550E2F60754EF2 /* wrap_Event.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Event.cpp; sourceTree = "<group>"; };
@@ -722,6 +738,18 @@
FA03546B1731F3A700284828 /* simplexnoise1234.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = simplexnoise1234.h; sourceTree = "<group>"; };
FA08F5AE16C7525600F007B5 /* Info-Framework.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Info-Framework.plist"; sourceTree = "<group>"; };
FA0CDE3B1710F9A50056E8D7 /* FormatHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormatHandler.h; sourceTree = "<group>"; };
FA34E7CB174B513F00E04D3F /* System.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = System.cpp; sourceTree = "<group>"; };
FA34E7CC174B513F00E04D3F /* System.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = System.h; sourceTree = "<group>"; };
FA34E7D0174B515D00E04D3F /* System.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = System.cpp; sourceTree = "<group>"; };
FA34E7D1174B515D00E04D3F /* System.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = System.h; sourceTree = "<group>"; };
FA34E7D4174B55AF00E04D3F /* wrap_System.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_System.cpp; sourceTree = "<group>"; };
FA34E7D5174B55AF00E04D3F /* wrap_System.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_System.h; sourceTree = "<group>"; };
FA3D9E0B16E68DE600CA6630 /* Cursor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Cursor.cpp; sourceTree = "<group>"; };
FA3D9E0C16E68DE600CA6630 /* Cursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Cursor.h; sourceTree = "<group>"; };
FA3D9E0F16E68EAE00CA6630 /* Cursor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Cursor.cpp; sourceTree = "<group>"; };
FA3D9E1016E68EAE00CA6630 /* Cursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Cursor.h; sourceTree = "<group>"; };
FA3D9E1316E6D41000CA6630 /* wrap_Cursor.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Cursor.cpp; sourceTree = "<group>"; };
FA3D9E1416E6D41000CA6630 /* wrap_Cursor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Cursor.h; sourceTree = "<group>"; };
FA435EA117B36E9C004C3F22 /* Polyline.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Polyline.cpp; sourceTree = "<group>"; };
FA435EA217B36E9C004C3F22 /* Polyline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Polyline.h; sourceTree = "<group>"; };
FA5454C016F1310000D30303 /* MathModule.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MathModule.cpp; sourceTree = "<group>"; };
@@ -733,7 +761,6 @@
FA577A6F16C719F000860150 /* mpg123.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mpg123.framework; path = /Library/Frameworks/mpg123.framework; sourceTree = "<absolute>"; };
FA577A7116C719F400860150 /* Ogg.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Ogg.framework; path = /Library/Frameworks/Ogg.framework; sourceTree = "<absolute>"; };
FA577A7316C719F900860150 /* physfs.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = physfs.framework; path = /Library/Frameworks/physfs.framework; sourceTree = "<absolute>"; };
FA577A7516C719FF00860150 /* SDL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL.framework; path = /Library/Frameworks/SDL.framework; sourceTree = "<absolute>"; };
FA577A7716C71A0800860150 /* Vorbis.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Vorbis.framework; path = /Library/Frameworks/Vorbis.framework; sourceTree = "<absolute>"; };
FA577A7916C71A1700860150 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
FA577A7C16C71A2600860150 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = "<absolute>"; };
@@ -773,11 +800,18 @@
FA7175A9178E8418001FE7FE /* lua.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lua.h; sourceTree = "<group>"; };
FA7C937516DCC6C2006F2BEE /* wrap_Math.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Math.cpp; sourceTree = "<group>"; };
FA7C937616DCC6C2006F2BEE /* wrap_Math.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Math.h; sourceTree = "<group>"; };
FA9B4A0716E1578300074F42 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = /Library/Frameworks/SDL2.framework; sourceTree = "<absolute>"; };
FA9FC0AE173D6E3E005027FF /* wrap_Window.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Window.cpp; sourceTree = "<group>"; };
FA9FC0AF173D6E3E005027FF /* wrap_Window.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Window.h; sourceTree = "<group>"; };
FAAC6B00170A373A008A61C5 /* CompressedData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CompressedData.cpp; sourceTree = "<group>"; };
FAAC6B01170A373A008A61C5 /* CompressedData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CompressedData.h; sourceTree = "<group>"; };
FAAFF04316CB11C700CCDE45 /* OpenAL-Soft.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "OpenAL-Soft.framework"; path = "/Library/Frameworks/OpenAL-Soft.framework"; sourceTree = "<absolute>"; };
FAB0078D1740C12D00A9664D /* Joystick.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Joystick.cpp; sourceTree = "<group>"; };
FAB0078E1740C12D00A9664D /* Joystick.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Joystick.h; sourceTree = "<group>"; };
FAB007911740C28900A9664D /* Joystick.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Joystick.cpp; sourceTree = "<group>"; };
FAB007921740C28900A9664D /* Joystick.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Joystick.h; sourceTree = "<group>"; };
FAB007951740C87D00A9664D /* wrap_Joystick.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_Joystick.cpp; sourceTree = "<group>"; };
FAB007961740C87D00A9664D /* wrap_Joystick.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = wrap_Joystick.h; sourceTree = "<group>"; };
FAC570FC17402D1100D147E4 /* BezierCurve.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = BezierCurve.cpp; sourceTree = "<group>"; };
FAC570FD17402D1100D147E4 /* BezierCurve.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BezierCurve.h; sourceTree = "<group>"; };
FAC570FE17402D1100D147E4 /* wrap_BezierCurve.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = wrap_BezierCurve.cpp; sourceTree = "<group>"; };
@@ -822,6 +856,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
FA9B4A0816E1578300074F42 /* SDL2.framework in Frameworks */,
FAAFF04416CB11C700CCDE45 /* OpenAL-Soft.framework in Frameworks */,
FA577AB016C7507900860150 /* Cocoa.framework in Frameworks */,
FA577AC216C7512D00860150 /* FreeType.framework in Frameworks */,
@@ -833,7 +868,6 @@
FA577AC816C7513C00860150 /* Ogg.framework in Frameworks */,
FA577ACA16C7514100860150 /* OpenGL.framework in Frameworks */,
FA577ACB16C7514400860150 /* physfs.framework in Frameworks */,
FA577ACC16C7514700860150 /* SDL.framework in Frameworks */,
FA577ACD16C7514C00860150 /* Vorbis.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -952,9 +986,13 @@
130737AF4BD12D0356A65C87 /* mouse */ = {
isa = PBXGroup;
children = (
FA3D9E0B16E68DE600CA6630 /* Cursor.cpp */,
FA3D9E0C16E68DE600CA6630 /* Cursor.h */,
31E0110E5797041465FF5F95 /* Mouse.cpp */,
63A63DFB339266AC401B545A /* Mouse.h */,
1E017A8673D531394B5A3B16 /* sdl */,
FA3D9E1316E6D41000CA6630 /* wrap_Cursor.cpp */,
FA3D9E1416E6D41000CA6630 /* wrap_Cursor.h */,
22EF17981EBD442773FE41B6 /* wrap_Mouse.cpp */,
4E972C114A6C25A63B5B6EF2 /* wrap_Mouse.h */,
);
@@ -1080,6 +1118,8 @@
1E017A8673D531394B5A3B16 /* sdl */ = {
isa = PBXGroup;
children = (
FA3D9E0F16E68EAE00CA6630 /* Cursor.cpp */,
FA3D9E1016E68EAE00CA6630 /* Cursor.h */,
584E16AE09E12536206C46FE /* Mouse.cpp */,
198A44BD71BB61EE517C2A39 /* Mouse.h */,
);
@@ -1344,8 +1384,9 @@
501126AD67DC2A4B527654EA /* joystick */ = {
isa = PBXGroup;
children = (
677F545C76EA3B247329358D /* Joystick.cpp */,
4C606AEC342457600C3F0741 /* Joystick.h */,
FAB0078D1740C12D00A9664D /* Joystick.cpp */,
FAB0078E1740C12D00A9664D /* Joystick.h */,
4C606AEC342457600C3F0741 /* JoystickModule.h */,
687216AD6FA406C838284B91 /* sdl */,
);
path = joystick;
@@ -1381,6 +1422,7 @@
130737AF4BD12D0356A65C87 /* mouse */,
67F10C1D58A96C1C53563B5C /* physics */,
4BAB08EE4A6B4A1A01DA50A4 /* sound */,
FA34E7CA174B512200E04D3F /* system */,
02E0744773D13AD65E7C49DC /* thread */,
6D590DDD41E72A60262E4A4F /* timer */,
153D76205F7A4ACD12FB4C0E /* window */,
@@ -1522,10 +1564,14 @@
687216AD6FA406C838284B91 /* sdl */ = {
isa = PBXGroup;
children = (
55B425307C0C1C4B3EFC3A5F /* Joystick.cpp */,
439E46D768A266780E894800 /* Joystick.h */,
139411436818381E493F00F5 /* wrap_Joystick.cpp */,
2D7B7DEC4FC87878332E41B3 /* wrap_Joystick.h */,
FAB007911740C28900A9664D /* Joystick.cpp */,
FAB007921740C28900A9664D /* Joystick.h */,
55B425307C0C1C4B3EFC3A5F /* JoystickModule.cpp */,
439E46D768A266780E894800 /* JoystickModule.h */,
FAB007951740C87D00A9664D /* wrap_Joystick.cpp */,
FAB007961740C87D00A9664D /* wrap_Joystick.h */,
139411436818381E493F00F5 /* wrap_JoystickModule.cpp */,
2D7B7DEC4FC87878332E41B3 /* wrap_JoystickModule.h */,
);
path = sdl;
sourceTree = "<group>";
@@ -1708,9 +1754,31 @@
name = Resources;
sourceTree = "<group>";
};
FA34E7CA174B512200E04D3F /* system */ = {
isa = PBXGroup;
children = (
FA34E7CF174B514F00E04D3F /* sdl */,
FA34E7CB174B513F00E04D3F /* System.cpp */,
FA34E7CC174B513F00E04D3F /* System.h */,
FA34E7D4174B55AF00E04D3F /* wrap_System.cpp */,
FA34E7D5174B55AF00E04D3F /* wrap_System.h */,
);
path = system;
sourceTree = "<group>";
};
FA34E7CF174B514F00E04D3F /* sdl */ = {
isa = PBXGroup;
children = (
FA34E7D0174B515D00E04D3F /* System.cpp */,
FA34E7D1174B515D00E04D3F /* System.h */,
);
path = sdl;
sourceTree = "<group>";
};
FA577A6616C7199700860150 /* Frameworks */ = {
isa = PBXGroup;
children = (
FA9B4A0716E1578300074F42 /* SDL2.framework */,
FA577A7916C71A1700860150 /* Cocoa.framework */,
FA577A6716C719D900860150 /* FreeType.framework */,
FA577A6B16C719E400860150 /* Game_Music_Emu.framework */,
@@ -1722,7 +1790,6 @@
FAAFF04316CB11C700CCDE45 /* OpenAL-Soft.framework */,
FA577A7C16C71A2600860150 /* OpenGL.framework */,
FA577A7316C719F900860150 /* physfs.framework */,
FA577A7516C719FF00860150 /* SDL.framework */,
FA577A7716C71A0800860150 /* Vorbis.framework */,
);
name = Frameworks;
@@ -1850,7 +1917,13 @@
FAC86E6A1724555D00EED715 /* DrawGable.h in Headers */,
FAC86E6C1724555D00EED715 /* Geometry.h in Headers */,
FA03546D1731F3A700284828 /* simplexnoise1234.h in Headers */,
FA3D9E0E16E68DE600CA6630 /* Cursor.h in Headers */,
FA3D9E1216E68EAE00CA6630 /* Cursor.h in Headers */,
FA3D9E1616E6D41100CA6630 /* wrap_Cursor.h in Headers */,
FA9FC0B1173D6E3E005027FF /* wrap_Window.h in Headers */,
FAB007901740C12D00A9664D /* Joystick.h in Headers */,
FAB007941740C28900A9664D /* Joystick.h in Headers */,
FAB007981740C87D00A9664D /* wrap_Joystick.h in Headers */,
FAC5710117402D1100D147E4 /* BezierCurve.h in Headers */,
FAC5710317402D1100D147E4 /* wrap_BezierCurve.h in Headers */,
FA5FDC7E1788D548002F0ED2 /* callbacks.h in Headers */,
@@ -1864,6 +1937,9 @@
FA5FDC861788D548002F0ED2 /* win32.h in Headers */,
FA5FDC8F1788D548002F0ED2 /* lua-enet.h in Headers */,
FA7175AA178E8418001FE7FE /* lua.h in Headers */,
FA34E7CE174B513F00E04D3F /* System.h in Headers */,
FA34E7D3174B515D00E04D3F /* System.h in Headers */,
FA1EF7C51799FEB200FF380C /* wrap_System.h in Headers */,
FA435EA417B36E9C004C3F22 /* Polyline.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -2054,9 +2130,8 @@
FA08F63016C7542600F007B5 /* DevilHandler.cpp in Sources */,
FA08F63116C7542600F007B5 /* wrap_Image.cpp in Sources */,
FA08F63216C7542600F007B5 /* wrap_ImageData.cpp in Sources */,
FA08F63316C7542D00F007B5 /* Joystick.cpp in Sources */,
FA08F63416C7542D00F007B5 /* Joystick.cpp in Sources */,
FA08F63516C7542D00F007B5 /* wrap_Joystick.cpp in Sources */,
FA08F63416C7542D00F007B5 /* JoystickModule.cpp in Sources */,
FA08F63516C7542D00F007B5 /* wrap_JoystickModule.cpp in Sources */,
FA08F63616C7543400F007B5 /* Keyboard.cpp in Sources */,
FA08F63716C7543400F007B5 /* Keyboard.cpp in Sources */,
FA08F63816C7543400F007B5 /* wrap_Keyboard.cpp in Sources */,
@@ -2148,7 +2223,13 @@
FAC86E691724555D00EED715 /* DrawGable.cpp in Sources */,
FAC86E6B1724555D00EED715 /* Geometry.cpp in Sources */,
FA03546C1731F3A700284828 /* simplexnoise1234.cpp in Sources */,
FA3D9E0D16E68DE600CA6630 /* Cursor.cpp in Sources */,
FA3D9E1116E68EAE00CA6630 /* Cursor.cpp in Sources */,
FA3D9E1516E6D41100CA6630 /* wrap_Cursor.cpp in Sources */,
FA9FC0B0173D6E3E005027FF /* wrap_Window.cpp in Sources */,
FAB0078F1740C12D00A9664D /* Joystick.cpp in Sources */,
FAB007931740C28900A9664D /* Joystick.cpp in Sources */,
FAB007971740C87D00A9664D /* wrap_Joystick.cpp in Sources */,
FAC5710017402D1100D147E4 /* BezierCurve.cpp in Sources */,
FAC5710217402D1100D147E4 /* wrap_BezierCurve.cpp in Sources */,
FA5FDC791788D548002F0ED2 /* enet.cpp in Sources */,
@@ -2161,6 +2242,9 @@
FA5FDC8B1788D548002F0ED2 /* protocol.c in Sources */,
FA5FDC8D1788D548002F0ED2 /* unix.c in Sources */,
FA5FDC8E1788D548002F0ED2 /* win32.c in Sources */,
FA34E7CD174B513F00E04D3F /* System.cpp in Sources */,
FA34E7D2174B515D00E04D3F /* System.cpp in Sources */,
FA1EF7C41799FEAC00FF380C /* wrap_System.cpp in Sources */,
FA435EA317B36E9C004C3F22 /* Polyline.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -2190,7 +2274,7 @@
"\"$(SRCROOT)/../../src/libraries/enet/libenet/include\"",
/Library/Frameworks/FreeType.framework/Headers,
/Library/Frameworks/Lua.framework/Headers,
/Library/Frameworks/SDL.framework/Headers,
/Library/Frameworks/SDL2.framework/Headers,
);
LD_RUNPATH_SEARCH_PATHS = "@rpath";
LIBRARY_SEARCH_PATHS = "";
@@ -2223,7 +2307,7 @@
"\"$(SRCROOT)/../../src/libraries/enet/libenet/include\"",
/Library/Frameworks/FreeType.framework/Headers,
/Library/Frameworks/Lua.framework/Headers,
/Library/Frameworks/SDL.framework/Headers,
/Library/Frameworks/SDL2.framework/Headers,
);
LD_RUNPATH_SEARCH_PATHS = "@rpath";
LIBRARY_SEARCH_PATHS = "";
+14 -36
View File
@@ -10,14 +10,11 @@
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; };
A911D3C915DFF25D005B7EB8 /* Game_Music_Emu.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A911D3C715DFF24D005B7EB8 /* Game_Music_Emu.framework */; };
A9255DD11043183600BA1496 /* FreeType.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E4810420B4A007D418B /* FreeType.framework */; };
A9255DD21043183600BA1496 /* SDL.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E5210420B57007D418B /* SDL.framework */; };
A9255DD31043183600BA1496 /* Lua.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E5310420B57007D418B /* Lua.framework */; };
A9255DEC1043188D00BA1496 /* SDLMain.m in Sources */ = {isa = PBXBuildFile; fileRef = A9255DEA1043188D00BA1496 /* SDLMain.m */; };
A9255E031043195A00BA1496 /* Vorbis.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9255E021043195A00BA1496 /* Vorbis.framework */; };
A9255F431043240F00BA1496 /* IL.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9255F421043240F00BA1496 /* IL.framework */; };
A9255F58104324E100BA1496 /* Ogg.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9255F51104324D700BA1496 /* Ogg.framework */; };
A93E6E4A10420B4A007D418B /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E4710420B4A007D418B /* OpenGL.framework */; };
A93E6E5410420B57007D418B /* SDL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E5210420B57007D418B /* SDL.framework */; };
A93E6E5510420B57007D418B /* Lua.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A93E6E5310420B57007D418B /* Lua.framework */; };
A93E6EED10420BA8007D418B /* love.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A93E6A3410420AC0007D418B /* love.cpp */; };
A9D307F2106635D3004FEDF8 /* physfs.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9D307E9106635C3004FEDF8 /* physfs.framework */; };
@@ -27,7 +24,10 @@
A9F169AD109E825000FC83D1 /* libmodplug.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = A9F16926109E7BAD00FC83D1 /* libmodplug.framework */; };
FA08F69616C766E000F007B5 /* love.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA08F69116C765A200F007B5 /* love.framework */; };
FA08F69716C766E700F007B5 /* love.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FA08F69116C765A200F007B5 /* love.framework */; };
FA9B4A0A16E1579F00074F42 /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FA9B4A0916E1579F00074F42 /* SDL2.framework */; };
FA9B4A0B16E157B500074F42 /* SDL2.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FA9B4A0916E1579F00074F42 /* SDL2.framework */; };
FAAFF04716CB120000CCDE45 /* OpenAL-Soft.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = FAAFF04616CB120000CCDE45 /* OpenAL-Soft.framework */; };
FAC8E8D416F3C468004DADF3 /* osx.mm in Sources */ = {isa = PBXBuildFile; fileRef = FAC8E8D316F3C468004DADF3 /* osx.mm */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -48,6 +48,7 @@
dstSubfolderSpec = 10;
files = (
FA08F69716C766E700F007B5 /* love.framework in Copy Frameworks */,
FA9B4A0B16E157B500074F42 /* SDL2.framework in Copy Frameworks */,
FAAFF04716CB120000CCDE45 /* OpenAL-Soft.framework in Copy Frameworks */,
A9F169AC109E825000FC83D1 /* mpg123.framework in Copy Frameworks */,
A9F169AD109E825000FC83D1 /* libmodplug.framework in Copy Frameworks */,
@@ -56,7 +57,6 @@
A9255F431043240F00BA1496 /* IL.framework in Copy Frameworks */,
A9255E031043195A00BA1496 /* Vorbis.framework in Copy Frameworks */,
A9255DD11043183600BA1496 /* FreeType.framework in Copy Frameworks */,
A9255DD21043183600BA1496 /* SDL.framework in Copy Frameworks */,
A9255DD31043183600BA1496 /* Lua.framework in Copy Frameworks */,
A911D3C915DFF25D005B7EB8 /* Game_Music_Emu.framework in Copy Frameworks */,
);
@@ -69,18 +69,14 @@
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
8D1107320486CEB800E47090 /* love.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = love.app; sourceTree = BUILT_PRODUCTS_DIR; };
A911D3C715DFF24D005B7EB8 /* Game_Music_Emu.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Game_Music_Emu.framework; path = /Library/Frameworks/Game_Music_Emu.framework; sourceTree = "<absolute>"; };
A9255DEA1043188D00BA1496 /* SDLMain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLMain.m; sourceTree = "<group>"; };
A9255DEB1043188D00BA1496 /* SDLMain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLMain.h; sourceTree = "<group>"; };
A9255E021043195A00BA1496 /* Vorbis.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Vorbis.framework; path = /Library/Frameworks/Vorbis.framework; sourceTree = "<absolute>"; };
A9255F421043240F00BA1496 /* IL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IL.framework; path = /Library/Frameworks/IL.framework; sourceTree = "<absolute>"; };
A9255F51104324D700BA1496 /* Ogg.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Ogg.framework; path = /Library/Frameworks/Ogg.framework; sourceTree = "<absolute>"; };
A93E6A3410420AC0007D418B /* love.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = love.cpp; path = ../../src/love.cpp; sourceTree = "<group>"; };
A93E6E4710420B4A007D418B /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = "<absolute>"; };
A93E6E4810420B4A007D418B /* FreeType.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = FreeType.framework; path = /Library/Frameworks/FreeType.framework; sourceTree = "<absolute>"; };
A93E6E5210420B57007D418B /* SDL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL.framework; path = /Library/Frameworks/SDL.framework; sourceTree = "<absolute>"; };
A93E6E5310420B57007D418B /* Lua.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Lua.framework; path = /Library/Frameworks/Lua.framework; sourceTree = "<absolute>"; };
A97E3842132A9EDE00198A2F /* love-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "love-Info.plist"; sourceTree = "<group>"; };
A9B1AE451197293000D496EB /* love_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = love_Prefix.pch; sourceTree = "<group>"; };
A9D307E9106635C3004FEDF8 /* physfs.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = physfs.framework; path = /Library/Frameworks/physfs.framework; sourceTree = "<absolute>"; };
A9DEC1BF1046EFA60049C70C /* Love.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = Love.icns; path = icons/Love.icns; sourceTree = "<group>"; };
A9DEC1C01046EFA70049C70C /* LoveDocument.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = LoveDocument.icns; path = icons/LoveDocument.icns; sourceTree = "<group>"; };
@@ -88,7 +84,10 @@
A9F169A6109E824900FC83D1 /* mpg123.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = mpg123.framework; path = /Library/Frameworks/mpg123.framework; sourceTree = "<absolute>"; };
FA08F69116C765A200F007B5 /* love.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; path = love.framework; sourceTree = BUILT_PRODUCTS_DIR; };
FA577A9316C7217800860150 /* love-framework.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = "love-framework.xcodeproj"; sourceTree = "<group>"; };
FA9B4A0916E1579F00074F42 /* SDL2.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL2.framework; path = /Library/Frameworks/SDL2.framework; sourceTree = "<absolute>"; };
FAAFF04616CB120000CCDE45 /* OpenAL-Soft.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "OpenAL-Soft.framework"; path = "/Library/Frameworks/OpenAL-Soft.framework"; sourceTree = "<absolute>"; };
FAC8E8D316F3C468004DADF3 /* osx.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = osx.mm; sourceTree = "<group>"; };
FAC8E8D616F3C46E004DADF3 /* osx.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = osx.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -99,8 +98,8 @@
FA08F69616C766E000F007B5 /* love.framework in Frameworks */,
8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */,
A93E6E4A10420B4A007D418B /* OpenGL.framework in Frameworks */,
A93E6E5410420B57007D418B /* SDL.framework in Frameworks */,
A93E6E5510420B57007D418B /* Lua.framework in Frameworks */,
FA9B4A0A16E1579F00074F42 /* SDL2.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -110,6 +109,7 @@
1058C7A0FEA54F0111CA2CBB /* Frameworks */ = {
isa = PBXGroup;
children = (
FA9B4A0916E1579F00074F42 /* SDL2.framework */,
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */,
A93E6E4810420B4A007D418B /* FreeType.framework */,
A911D3C715DFF24D005B7EB8 /* Game_Music_Emu.framework */,
@@ -122,7 +122,6 @@
FAAFF04616CB120000CCDE45 /* OpenAL-Soft.framework */,
A93E6E4710420B4A007D418B /* OpenGL.framework */,
A9D307E9106635C3004FEDF8 /* physfs.framework */,
A93E6E5210420B57007D418B /* SDL.framework */,
A9255E021043195A00BA1496 /* Vorbis.framework */,
);
name = Frameworks;
@@ -171,9 +170,8 @@
isa = PBXGroup;
children = (
A93E6A3410420AC0007D418B /* love.cpp */,
A9255DEA1043188D00BA1496 /* SDLMain.m */,
A9255DEB1043188D00BA1496 /* SDLMain.h */,
A9B1AE451197293000D496EB /* love_Prefix.pch */,
FAC8E8D616F3C46E004DADF3 /* osx.h */,
FAC8E8D316F3C468004DADF3 /* osx.mm */,
);
name = Source;
sourceTree = "<group>";
@@ -261,7 +259,7 @@
buildActionMask = 2147483647;
files = (
A93E6EED10420BA8007D418B /* love.cpp in Sources */,
A9255DEC1043188D00BA1496 /* SDLMain.m in Sources */,
FAC8E8D416F3C468004DADF3 /* osx.mm in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -279,15 +277,6 @@
);
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = love_Prefix.pch;
HEADER_SEARCH_PATHS = (
"\"$(SRCROOT)/../../src\"",
"\"$(SRCROOT)/../../src/libraries\"",
"\"$(SRCROOT)/../../src/modules\"",
/Library/Frameworks/Lua.framework/Headers,
/Library/Frameworks/SDL.framework/Headers,
);
INSTALL_PATH = /Applications;
PRODUCT_NAME = love;
};
@@ -303,15 +292,6 @@
"\"$(SRCROOT)/build/Release\"",
"\"$(SRCROOT)/build/Debug\"",
);
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = love_Prefix.pch;
HEADER_SEARCH_PATHS = (
"\"$(SRCROOT)/../../src\"",
"\"$(SRCROOT)/../../src/libraries\"",
"\"$(SRCROOT)/../../src/modules\"",
/Library/Frameworks/Lua.framework/Headers,
/Library/Frameworks/SDL.framework/Headers,
);
INSTALL_PATH = /Applications;
PRODUCT_NAME = love;
};
@@ -346,8 +326,7 @@
"\"$(SRCROOT)/../../src/libraries\"",
"\"$(SRCROOT)/../../src/modules\"",
/Library/Frameworks/Lua.framework/Headers,
/Library/Frameworks/FreeType.framework/Headers,
/Library/Frameworks/SDL.framework/Headers,
/Library/Frameworks/SDL2.framework/Headers,
);
INFOPLIST_FILE = "love-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
@@ -400,8 +379,7 @@
"\"$(SRCROOT)/../../src/libraries\"",
"\"$(SRCROOT)/../../src/modules\"",
/Library/Frameworks/Lua.framework/Headers,
/Library/Frameworks/FreeType.framework/Headers,
/Library/Frameworks/SDL.framework/Headers,
/Library/Frameworks/SDL2.framework/Headers,
);
INFOPLIST_FILE = "love-Info.plist";
LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks";
-7
View File
@@ -1,7 +0,0 @@
//
// Prefix header for all source files of the 'love' target in the 'love' project
//
#ifdef __OBJC__
#import <Cocoa/Cocoa.h>
#endif
+4 -2
View File
@@ -26,12 +26,14 @@ namespace love
const char REFERENCE_TABLE_NAME[] = "love-references";
Reference::Reference()
: L(0), idx(LUA_REFNIL)
: L(0)
, idx(LUA_REFNIL)
{
}
Reference::Reference(lua_State *L)
: L(0), idx(LUA_REFNIL)
: L(L)
, idx(LUA_REFNIL)
{
ref(L);
}
+1
View File
@@ -72,6 +72,7 @@
#if defined(LOVE_MACOSX)
# define LOVE_LEGENDARY_LIBSTDCXX_HACK
# define LOVE_LEGENDARY_APP_ARGV_HACK
#endif
// Autotools config.h
+6
View File
@@ -571,6 +571,9 @@ StringMap<Type, TYPE_MAX_ENUM>::Entry typeEntries[] =
{"ImageData", IMAGE_IMAGE_DATA_ID},
{"CompressedData", IMAGE_COMPRESSED_DATA_ID},
// Joystick
{"Joystick", JOYSTICK_JOYSTICK_ID},
// Math
{"RandomGenerator", MATH_RANDOM_GENERATOR_ID},
{"BezierCurve", MATH_BEZIER_CURVE_ID},
@@ -582,6 +585,9 @@ StringMap<Type, TYPE_MAX_ENUM>::Entry typeEntries[] =
{"SoundData", SOUND_SOUND_DATA_ID},
{"Decoder", SOUND_DECODER_ID},
// Mouse
{"Cursor", MOUSE_CURSOR_ID},
// Physics
{"World", PHYSICS_WORLD_ID},
{"Contact", PHYSICS_CONTACT_ID},
+12
View File
@@ -58,6 +58,9 @@ enum Type
IMAGE_IMAGE_DATA_ID,
IMAGE_COMPRESSED_DATA_ID,
// Joystick
JOYSTICK_JOYSTICK_ID,
// Math
MATH_RANDOM_GENERATOR_ID,
MATH_BEZIER_CURVE_ID,
@@ -69,6 +72,9 @@ enum Type
SOUND_SOUND_DATA_ID,
SOUND_DECODER_ID,
// Mouse
MOUSE_CURSOR_ID,
// Physics
PHYSICS_WORLD_ID,
PHYSICS_CONTACT_ID,
@@ -135,6 +141,9 @@ const bits GRAPHICS_SHADER_T = (bits(1) << GRAPHICS_SHADER_ID) | OBJECT_T;
const bits IMAGE_IMAGE_DATA_T = (bits(1) << IMAGE_IMAGE_DATA_ID) | DATA_T;
const bits IMAGE_COMPRESSED_DATA_T = (bits(1) << IMAGE_COMPRESSED_DATA_ID) | DATA_T;
// Joystick.
const bits JOYSTICK_JOYSTICK_T = (bits(1) << JOYSTICK_JOYSTICK_ID) | OBJECT_T;
// Math.
const bits MATH_RANDOM_GENERATOR_T = (bits(1) << MATH_RANDOM_GENERATOR_ID) | OBJECT_T;
const bits MATH_BEZIER_CURVE_T = (bits(1) << MATH_BEZIER_CURVE_ID) | OBJECT_T;
@@ -146,6 +155,9 @@ const bits AUDIO_SOURCE_T = (bits(1) << AUDIO_SOURCE_ID) | OBJECT_T;
const bits SOUND_SOUND_DATA_T = (bits(1) << SOUND_SOUND_DATA_ID) | DATA_T;
const bits SOUND_DECODER_T = bits(1) << SOUND_DECODER_ID;
// Mouse.
const bits MOUSE_CURSOR_T = (bits(1) << MOUSE_CURSOR_ID) | OBJECT_T;
// Physics.
const bits PHYSICS_WORLD_T = (bits(1) << PHYSICS_WORLD_ID) | OBJECT_T;
const bits PHYSICS_CONTACT_T = (bits(1) << PHYSICS_CONTACT_ID) | OBJECT_T;
+62 -2
View File
@@ -34,6 +34,10 @@ extern "C" {
#include <windows.h>
#endif // LOVE_WINDOWS
#ifdef LOVE_MACOSX
#include "osx.h"
#endif // LOVE_MACOSX
#ifdef LOVE_LEGENDARY_UTF8_ARGV_HACK
void get_utf8_arguments(int &argc, char **&argv)
@@ -71,6 +75,54 @@ void get_utf8_arguments(int &argc, char **&argv)
#endif // LOVE_LEGENDARY_UTF8_ARGV_HACK
#ifdef LOVE_LEGENDARY_APP_ARGV_HACK
#include <vector>
static void get_app_arguments(int argc, char **argv, int &new_argc, char **&new_argv)
{
std::vector<std::string> temp_argv;
for (int i = 0; i < argc; i++)
{
// Don't copy -psn_xxx argument from argv.
if (i == 0 || strncmp(argv[i], "-psn_", 5) != 0)
temp_argv.push_back(std::string(argv[i]));
}
// Check for a drop file string.
std::string dropfilestr = love::osx::checkDropEvents();
if (!dropfilestr.empty())
{
temp_argv.insert(temp_argv.begin() + 1, dropfilestr);
}
else
{
// If it exists, add the love file in love.app/Contents/Resources/ to argv.
std::string loveResourcesPath = love::osx::getLoveInResources();
if (!loveResourcesPath.empty())
{
// Run in pseudo-fused mode.
std::vector<std::string>::iterator it = temp_argv.begin();
it = temp_argv.insert(it + 1, loveResourcesPath);
temp_argv.insert(it + 1, std::string("--fused"));
}
}
// Copy temp argv vector to new argv array.
new_argc = (int) temp_argv.size();
new_argv = new char *[new_argc+1];
for (int i = 0; i < new_argc; i++)
{
new_argv[i] = new char[temp_argv[i].length() + 1];
strcpy(new_argv[i], temp_argv[i].c_str());
}
new_argv[new_argc+1] = NULL;
}
#endif // LOVE_LEGENDARY_APP_ARGV_HACK
static int love_preload(lua_State *L, lua_CFunction f, const char *name)
{
lua_getglobal(L, "package");
@@ -90,6 +142,14 @@ int main(int argc, char **argv)
argv = hack_argv;
#endif // LOVE_LEGENDARY_UTF8_ARGV_HACK
#ifdef LOVE_LEGENDARY_APP_ARGV_HACK
int hack_argc = 0;
char **hack_argv = 0;
get_app_arguments(argc, argv, hack_argc, hack_argv);
argc = hack_argc;
argv = hack_argv;
#endif // LOVE_LEGENDARY_APP_ARGV_HACK
// Oh, you just want the version? Okay!
if (argc > 1 && strcmp(argv[1],"--version") == 0)
{
@@ -148,14 +208,14 @@ int main(int argc, char **argv)
lua_close(L);
#ifdef LOVE_LEGENDARY_UTF8_ARGV_HACK
#if defined(LOVE_LEGENDARY_UTF8_ARGV_HACK) || defined(LOVE_LEGENDARY_APP_ARGV_HACK)
if (hack_argv)
{
for (int i = 0; i<hack_argc; ++i)
delete [] hack_argv[i];
delete [] hack_argv;
}
#endif // LOVE_LEGENDARY_UTF8_ARGV_HACK
#endif // LOVE_LEGENDARY_UTF8_ARGV_HACK || LOVE_LEGENDARY_APP_ARGV_HACK
return retval;
}
+445 -238
View File
@@ -22,11 +22,13 @@
#include "keyboard/Keyboard.h"
#include "mouse/Mouse.h"
#include "libraries/utf8/utf8.h"
#include "joystick/JoystickModule.h"
#include "joystick/sdl/Joystick.h"
#include "graphics/Graphics.h"
#include "window/Window.h"
#include "common/Exception.h"
#include <cmath>
#include <cstddef>
namespace love
{
@@ -42,7 +44,13 @@ const char *Event::getName() const
Event::Event()
{
SDL_EnableUNICODE(1);
if (SDL_InitSubSystem(SDL_INIT_EVENTS) < 0)
throw love::Exception("%s", SDL_GetError());
}
Event::~Event()
{
SDL_QuitSubSystem(SDL_INIT_EVENTS);
}
void Event::pump()
@@ -50,7 +58,6 @@ void Event::pump()
SDL_PumpEvents();
static SDL_Event e;
SDL_EnableUNICODE(1);
Message *msg;
@@ -86,46 +93,65 @@ void Event::clear()
love::event::Event::clear();
}
Message *Event::convert(SDL_Event &e)
Message *Event::convert(const SDL_Event &e) const
{
Message *msg = 0;
Message *msg = NULL;
love::keyboard::Keyboard::Key key;
love::mouse::Mouse::Button button;
love::joystick::Joystick::Hat hat;
Variant *arg1 = 0, *arg2 = 0, *arg3 = 0;
Variant *arg1, *arg2, *arg3;
const char *txt;
std::map<SDL_Keycode, love::keyboard::Keyboard::Key>::const_iterator keyit;
switch (e.type)
{
case SDL_KEYDOWN:
if (!keys.find(e.key.keysym.sym, key))
keyit = keys.find(e.key.keysym.sym);
if (keyit != keys.end())
key = keyit->second;
else
key = love::keyboard::Keyboard::KEY_UNKNOWN;
if (!love::keyboard::Keyboard::getConstant(key, txt))
txt = "unknown";
arg1 = new Variant(txt, strlen(txt));
txt = convertUnicode(e.key.keysym.unicode);
// We don't want to send unprintable unicode text.
if (txt && (txt[0] >= ' ' && txt[0] != 127))
{
arg2 = new Variant(txt, strlen(txt));
msg = new Message("keypressed", arg1, arg2);
arg2->release();
}
else
msg = new Message("keypressed", arg1);
arg2 = new Variant(e.key.repeat == SDL_TRUE);
msg = new Message("keypressed", arg1, arg2);
arg1->release();
arg2->release();
break;
case SDL_KEYUP:
if (!keys.find(e.key.keysym.sym, key))
keyit = keys.find(e.key.keysym.sym);
if (keyit != keys.end())
key = keyit->second;
else
key = love::keyboard::Keyboard::KEY_UNKNOWN;
if (!love::keyboard::Keyboard::getConstant(key, txt))
txt = "unknown";
arg1 = new Variant(txt, strlen(txt));
msg = new Message("keyreleased", arg1);
arg1->release();
break;
case SDL_TEXTINPUT:
txt = e.text.text;
arg1 = new Variant(txt, strlen(txt));
msg = new Message("textinput", arg1);
arg1->release();
break;
case SDL_TEXTEDITING:
txt = e.edit.text;
arg1 = new Variant(txt, strlen(txt));
arg2 = new Variant((double) e.edit.start);
arg3 = new Variant((double) e.edit.length);
msg = new Message("textedit", arg1, arg2, arg3);
arg1->release();
arg2->release();
arg3->release();
break;
case SDL_MOUSEBUTTONDOWN:
case SDL_MOUSEBUTTONUP:
if (buttons.find(e.button.button, button) && love::mouse::Mouse::getConstant(button, txt))
if (buttons.find(e.button.button, button) && mouse::Mouse::getConstant(button, txt))
{
arg1 = new Variant((double) e.button.x);
arg2 = new Variant((double) e.button.y);
@@ -138,9 +164,77 @@ Message *Event::convert(SDL_Event &e)
arg3->release();
}
break;
case SDL_MOUSEWHEEL:
if (e.wheel.y != 0)
{
button = (e.wheel.y > 0) ? mouse::Mouse::BUTTON_WHEELUP : mouse::Mouse::BUTTON_WHEELDOWN;
if (!love::mouse::Mouse::getConstant(button, txt))
break;
int mx, my;
SDL_GetMouseState(&mx, &my);
arg1 = new Variant((double) mx);
arg2 = new Variant((double) my);
arg3 = new Variant(txt, strlen(txt));
msg = new Message("mousepressed", arg1, arg2, arg3);
arg1->release();
arg2->release();
arg3->release();
}
break;
case SDL_JOYBUTTONDOWN:
case SDL_JOYBUTTONUP:
arg1 = new Variant((double)(e.jbutton.which+1));
case SDL_JOYAXISMOTION:
case SDL_JOYBALLMOTION:
case SDL_JOYHATMOTION:
case SDL_JOYDEVICEADDED:
case SDL_JOYDEVICEREMOVED:
case SDL_CONTROLLERBUTTONDOWN:
case SDL_CONTROLLERBUTTONUP:
case SDL_CONTROLLERAXISMOTION:
msg = convertJoystickEvent(e);
break;
case SDL_WINDOWEVENT:
msg = convertWindowEvent(e);
break;
case SDL_DROPFILE:
SDL_free(e.drop.file);
break;
case SDL_QUIT:
msg = new Message("quit");
break;
default:
break;
}
return msg;
}
Message *Event::convertJoystickEvent(const SDL_Event &e) const
{
joystick::JoystickModule *joymodule = (joystick::JoystickModule *) Module::findInstance("love.joystick.");
if (!joymodule)
return 0;
Message *msg = 0;
Proxy proxy;
love::joystick::Joystick::Hat hat;
love::joystick::Joystick::GamepadButton padbutton;
love::joystick::Joystick::GamepadAxis padaxis;
Variant *arg1, *arg2, *arg3;
const char *txt;
switch (e.type)
{
case SDL_JOYBUTTONDOWN:
case SDL_JOYBUTTONUP:
proxy.flags = JOYSTICK_JOYSTICK_T;
proxy.data = joymodule->getJoystickFromID(e.jbutton.which);
if (!proxy.data)
break;
arg1 = new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy);
arg2 = new Variant((double)(e.jbutton.button+1));
msg = new Message((e.type == SDL_JOYBUTTONDOWN) ?
"joystickpressed" : "joystickreleased",
@@ -150,7 +244,12 @@ Message *Event::convert(SDL_Event &e)
break;
case SDL_JOYAXISMOTION:
{
arg1 = new Variant((double)(e.jaxis.which+1));
proxy.flags = JOYSTICK_JOYSTICK_T;
proxy.data = joymodule->getJoystickFromID(e.jaxis.which);
if (!proxy.data)
break;
arg1 = new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy);
arg2 = new Variant((double)(e.jaxis.axis+1));
float value = e.jaxis.value / 32768.0f;
if (fabsf(value) < 0.001f) value = 0.0f;
@@ -164,52 +263,144 @@ Message *Event::convert(SDL_Event &e)
}
break;
case SDL_JOYHATMOTION:
if (hats.find(e.jhat.value, hat) && love::joystick::Joystick::getConstant(hat, txt))
if (!joystick::sdl::Joystick::getConstant(e.jhat.value, hat) || !joystick::Joystick::getConstant(hat, txt))
break;
proxy.flags = JOYSTICK_JOYSTICK_T;
proxy.data = joymodule->getJoystickFromID(e.jhat.which);
if (!proxy.data)
break;
arg1 = new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy);
arg2 = new Variant((double)(e.jhat.hat+1));
arg3 = new Variant(txt, strlen(txt));
msg = new Message("joystickhat", arg1, arg2, arg3);
arg1->release();
arg2->release();
arg3->release();
break;
case SDL_CONTROLLERBUTTONDOWN:
case SDL_CONTROLLERBUTTONUP:
if (!joystick::sdl::Joystick::getConstant((SDL_GameControllerButton) e.cbutton.button, padbutton))
break;
if (!joystick::Joystick::getConstant(padbutton, txt))
break;
proxy.flags = JOYSTICK_JOYSTICK_T;
proxy.data = joymodule->getJoystickFromID(e.cbutton.which);
if (!proxy.data)
break;
arg1 = new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy);
arg2 = new Variant(txt, strlen(txt));
msg = new Message(e.type == SDL_CONTROLLERBUTTONDOWN ?
"gamepadpressed" : "gamepadreleased", arg1, arg2);
arg1->release();
arg2->release();
break;
case SDL_CONTROLLERAXISMOTION:
if (joystick::sdl::Joystick::getConstant((SDL_GameControllerAxis) e.caxis.axis, padaxis))
{
arg1 = new Variant((double)(e.jhat.which+1));
arg2 = new Variant((double)(e.jhat.hat+1));
arg3 = new Variant(txt, strlen(txt));
msg = new Message("joystickhat", arg1, arg2, arg3);
if (!joystick::Joystick::getConstant(padaxis, txt))
break;
proxy.flags = JOYSTICK_JOYSTICK_T;
proxy.data = joymodule->getJoystickFromID(e.caxis.which);
if (!proxy.data)
break;
arg1 = new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy);
arg2 = new Variant(txt, strlen(txt));
float value = e.jaxis.value / 32768.0f;
if (fabsf(value) < 0.001f) value = 0.0f;
if (value < -0.99f) value = -1.0f;
if (value > 0.99f) value = 1.0f;
arg3 = new Variant((double) value);
msg = new Message("gamepadaxis", arg1, arg2, arg3);
arg1->release();
arg2->release();
arg3->release();
}
break;
case SDL_ACTIVEEVENT:
case SDL_JOYDEVICEADDED:
// jdevice.which is the joystick device index.
proxy.data = joymodule->addJoystick(e.jdevice.which);
proxy.flags = JOYSTICK_JOYSTICK_T;
if (proxy.data)
{
// SDL can send multiple ACTIVEEVENTS in a single SDL_event... we
// have to work around that by re-sending the ones we miss.
SDL_Event e2 = e;
arg1 = new Variant(e.active.gain != 0);
if (e.active.state & SDL_APPINPUTFOCUS)
{
msg = new Message("focus", arg1);
e2.active.state &= ~SDL_APPINPUTFOCUS;
}
else if (e.active.state & SDL_APPMOUSEFOCUS)
{
msg = new Message("mousefocus", arg1);
e2.active.state &= ~SDL_APPMOUSEFOCUS;
}
else if (e.active.state & SDL_APPACTIVE)
{
msg = new Message("visible", arg1);
e2.active.state &= ~SDL_APPACTIVE;
}
arg1 = new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy);
msg = new Message("joystickadded", arg1);
arg1->release();
// Put any missing active events back in SDL's queue.
if (e2.active.state != 0)
SDL_PushEvent(&e2);
}
break;
case SDL_QUIT:
msg = new Message("quit");
case SDL_JOYDEVICEREMOVED:
// jdevice.which is the joystick instance ID now.
proxy.data = joymodule->getJoystickFromID(e.jdevice.which);
proxy.flags = JOYSTICK_JOYSTICK_T;
if (proxy.data)
{
joymodule->removeJoystick((joystick::Joystick *) proxy.data);
arg1 = new Variant(JOYSTICK_JOYSTICK_ID, (void *) &proxy);
msg = new Message("joystickremoved", arg1);
arg1->release();
}
break;
case SDL_VIDEORESIZE:
arg1 = new Variant((double) e.resize.w);
arg2 = new Variant((double) e.resize.h);
default:
break;
}
return msg;
}
Message *Event::convertWindowEvent(const SDL_Event &e) const
{
Message *msg = 0;
Variant *arg1, *arg2;
window::Window *win = 0;
if (e.type != SDL_WINDOWEVENT)
return 0;
switch (e.window.event)
{
case SDL_WINDOWEVENT_FOCUS_GAINED:
case SDL_WINDOWEVENT_FOCUS_LOST:
// Users won't expect the screensaver to activate if a game is in
// focus. Also, joystick input may not delay the screensaver timer.
if (e.window.event == SDL_WINDOWEVENT_FOCUS_GAINED)
SDL_DisableScreenSaver();
else
SDL_EnableScreenSaver();
arg1 = new Variant(e.window.event == SDL_WINDOWEVENT_FOCUS_GAINED);
msg = new Message("focus", arg1);
arg1->release();
break;
case SDL_WINDOWEVENT_ENTER:
case SDL_WINDOWEVENT_LEAVE:
arg1 = new Variant(e.window.event == SDL_WINDOWEVENT_ENTER);
msg = new Message("mousefocus", arg1);
arg1->release();
break;
case SDL_WINDOWEVENT_SHOWN:
case SDL_WINDOWEVENT_HIDDEN:
arg1 = new Variant(e.window.event == SDL_WINDOWEVENT_SHOWN);
msg = new Message("visible", arg1);
arg1->release();
break;
case SDL_WINDOWEVENT_RESIZED:
win = (window::Window *) Module::findInstance("love.window.");
if (win)
{
win->onWindowResize(e.window.data1, e.window.data2);
graphics::Graphics *gfx = (graphics::Graphics *) Module::findInstance("love.graphics.");
if (gfx)
gfx->setViewportSize(e.window.data1, e.window.data2);
}
arg1 = new Variant((double) e.window.data1);
arg2 = new Variant((double) e.window.data2);
msg = new Message("resize", arg1, arg2);
arg1->release();
arg2->release();
@@ -219,205 +410,221 @@ Message *Event::convert(SDL_Event &e)
return msg;
}
const char *Event::convertUnicode(Uint16 codepoint) const
std::map<SDL_Keycode, love::keyboard::Keyboard::Key> Event::createKeyMap()
{
// A single unicode character can use up to 4 bytes.
static char str[5] = {'\0'};
ptrdiff_t length = 0;
using love::keyboard::Keyboard;
if (codepoint == 0)
return 0;
std::map<SDL_Keycode, Keyboard::Key> k;
char *end = utf8::unchecked::append(codepoint, str);
length = end - str;
k[SDLK_UNKNOWN] = Keyboard::KEY_UNKNOWN;
if (length <= 0 || !utf8::is_valid(str, str + length))
return 0;
k[SDLK_RETURN] = Keyboard::KEY_RETURN;
k[SDLK_ESCAPE] = Keyboard::KEY_ESCAPE;
k[SDLK_BACKSPACE] = Keyboard::KEY_BACKSPACE;
k[SDLK_TAB] = Keyboard::KEY_TAB;
k[SDLK_SPACE] = Keyboard::KEY_SPACE;
k[SDLK_EXCLAIM] = Keyboard::KEY_EXCLAIM;
k[SDLK_QUOTEDBL] = Keyboard::KEY_QUOTEDBL;
k[SDLK_HASH] = Keyboard::KEY_HASH;
k[SDLK_DOLLAR] = Keyboard::KEY_DOLLAR;
k[SDLK_AMPERSAND] = Keyboard::KEY_AMPERSAND;
k[SDLK_QUOTE] = Keyboard::KEY_QUOTE;
k[SDLK_LEFTPAREN] = Keyboard::KEY_LEFTPAREN;
k[SDLK_RIGHTPAREN] = Keyboard::KEY_RIGHTPAREN;
k[SDLK_ASTERISK] = Keyboard::KEY_ASTERISK;
k[SDLK_PLUS] = Keyboard::KEY_PLUS;
k[SDLK_COMMA] = Keyboard::KEY_COMMA;
k[SDLK_MINUS] = Keyboard::KEY_MINUS;
k[SDLK_PERIOD] = Keyboard::KEY_PERIOD;
k[SDLK_SLASH] = Keyboard::KEY_SLASH;
k[SDLK_0] = Keyboard::KEY_0;
k[SDLK_1] = Keyboard::KEY_1;
k[SDLK_2] = Keyboard::KEY_2;
k[SDLK_3] = Keyboard::KEY_3;
k[SDLK_4] = Keyboard::KEY_4;
k[SDLK_5] = Keyboard::KEY_5;
k[SDLK_6] = Keyboard::KEY_6;
k[SDLK_7] = Keyboard::KEY_7;
k[SDLK_8] = Keyboard::KEY_8;
k[SDLK_9] = Keyboard::KEY_9;
k[SDLK_COLON] = Keyboard::KEY_COLON;
k[SDLK_SEMICOLON] = Keyboard::KEY_SEMICOLON;
k[SDLK_LESS] = Keyboard::KEY_LESS;
k[SDLK_EQUALS] = Keyboard::KEY_EQUALS;
k[SDLK_GREATER] = Keyboard::KEY_GREATER;
k[SDLK_QUESTION] = Keyboard::KEY_QUESTION;
k[SDLK_AT] = Keyboard::KEY_AT;
// Zero out the rest of the string.
for (ptrdiff_t i = length; i < 5; i++)
str[i] = '\0';
k[SDLK_LEFTBRACKET] = Keyboard::KEY_LEFTBRACKET;
k[SDLK_BACKSLASH] = Keyboard::KEY_BACKSLASH;
k[SDLK_RIGHTBRACKET] = Keyboard::KEY_RIGHTBRACKET;
k[SDLK_CARET] = Keyboard::KEY_CARET;
k[SDLK_UNDERSCORE] = Keyboard::KEY_UNDERSCORE;
k[SDLK_BACKQUOTE] = Keyboard::KEY_BACKQUOTE;
k[SDLK_a] = Keyboard::KEY_A;
k[SDLK_b] = Keyboard::KEY_B;
k[SDLK_c] = Keyboard::KEY_C;
k[SDLK_d] = Keyboard::KEY_D;
k[SDLK_e] = Keyboard::KEY_E;
k[SDLK_f] = Keyboard::KEY_F;
k[SDLK_g] = Keyboard::KEY_G;
k[SDLK_h] = Keyboard::KEY_H;
k[SDLK_i] = Keyboard::KEY_I;
k[SDLK_j] = Keyboard::KEY_J;
k[SDLK_k] = Keyboard::KEY_K;
k[SDLK_l] = Keyboard::KEY_L;
k[SDLK_m] = Keyboard::KEY_M;
k[SDLK_n] = Keyboard::KEY_N;
k[SDLK_o] = Keyboard::KEY_O;
k[SDLK_p] = Keyboard::KEY_P;
k[SDLK_q] = Keyboard::KEY_Q;
k[SDLK_r] = Keyboard::KEY_R;
k[SDLK_s] = Keyboard::KEY_S;
k[SDLK_t] = Keyboard::KEY_T;
k[SDLK_u] = Keyboard::KEY_U;
k[SDLK_v] = Keyboard::KEY_V;
k[SDLK_w] = Keyboard::KEY_W;
k[SDLK_x] = Keyboard::KEY_X;
k[SDLK_y] = Keyboard::KEY_Y;
k[SDLK_z] = Keyboard::KEY_Z;
return str;
k[SDLK_CAPSLOCK] = Keyboard::KEY_CAPSLOCK;
k[SDLK_F1] = Keyboard::KEY_F1;
k[SDLK_F2] = Keyboard::KEY_F2;
k[SDLK_F3] = Keyboard::KEY_F3;
k[SDLK_F4] = Keyboard::KEY_F4;
k[SDLK_F5] = Keyboard::KEY_F5;
k[SDLK_F6] = Keyboard::KEY_F6;
k[SDLK_F7] = Keyboard::KEY_F7;
k[SDLK_F8] = Keyboard::KEY_F8;
k[SDLK_F9] = Keyboard::KEY_F9;
k[SDLK_F10] = Keyboard::KEY_F10;
k[SDLK_F11] = Keyboard::KEY_F11;
k[SDLK_F12] = Keyboard::KEY_F12;
k[SDLK_PRINTSCREEN] = Keyboard::KEY_PRINTSCREEN;
k[SDLK_SCROLLLOCK] = Keyboard::KEY_SCROLLLOCK;
k[SDLK_PAUSE] = Keyboard::KEY_PAUSE;
k[SDLK_INSERT] = Keyboard::KEY_INSERT;
k[SDLK_HOME] = Keyboard::KEY_HOME;
k[SDLK_PAGEUP] = Keyboard::KEY_PAGEUP;
k[SDLK_DELETE] = Keyboard::KEY_DELETE;
k[SDLK_END] = Keyboard::KEY_END;
k[SDLK_PAGEDOWN] = Keyboard::KEY_PAGEDOWN;
k[SDLK_RIGHT] = Keyboard::KEY_RIGHT;
k[SDLK_LEFT] = Keyboard::KEY_LEFT;
k[SDLK_DOWN] = Keyboard::KEY_DOWN;
k[SDLK_UP] = Keyboard::KEY_UP;
k[SDLK_NUMLOCKCLEAR] = Keyboard::KEY_NUMLOCKCLEAR;
k[SDLK_KP_DIVIDE] = Keyboard::KEY_KP_DIVIDE;
k[SDLK_KP_MULTIPLY] = Keyboard::KEY_KP_MULTIPLY;
k[SDLK_KP_MINUS] = Keyboard::KEY_KP_MINUS;
k[SDLK_KP_PLUS] = Keyboard::KEY_KP_PLUS;
k[SDLK_KP_ENTER] = Keyboard::KEY_KP_ENTER;
k[SDLK_KP_0] = Keyboard::KEY_KP_0;
k[SDLK_KP_1] = Keyboard::KEY_KP_1;
k[SDLK_KP_2] = Keyboard::KEY_KP_2;
k[SDLK_KP_3] = Keyboard::KEY_KP_3;
k[SDLK_KP_4] = Keyboard::KEY_KP_4;
k[SDLK_KP_5] = Keyboard::KEY_KP_5;
k[SDLK_KP_6] = Keyboard::KEY_KP_6;
k[SDLK_KP_7] = Keyboard::KEY_KP_7;
k[SDLK_KP_8] = Keyboard::KEY_KP_8;
k[SDLK_KP_9] = Keyboard::KEY_KP_9;
k[SDLK_KP_PERIOD] = Keyboard::KEY_KP_PERIOD;
k[SDLK_KP_COMMA] = Keyboard::KEY_KP_COMMA;
k[SDLK_KP_EQUALS] = Keyboard::KEY_KP_EQUALS;
k[SDLK_APPLICATION] = Keyboard::KEY_APPLICATION;
k[SDLK_POWER] = Keyboard::KEY_POWER;
k[SDLK_F13] = Keyboard::KEY_F13;
k[SDLK_F14] = Keyboard::KEY_F14;
k[SDLK_F15] = Keyboard::KEY_F15;
k[SDLK_F16] = Keyboard::KEY_F16;
k[SDLK_F17] = Keyboard::KEY_F17;
k[SDLK_F18] = Keyboard::KEY_F18;
k[SDLK_F19] = Keyboard::KEY_F19;
k[SDLK_F20] = Keyboard::KEY_F20;
k[SDLK_F21] = Keyboard::KEY_F21;
k[SDLK_F22] = Keyboard::KEY_F22;
k[SDLK_F23] = Keyboard::KEY_F23;
k[SDLK_F24] = Keyboard::KEY_F24;
k[SDLK_EXECUTE] = Keyboard::KEY_EXECUTE;
k[SDLK_HELP] = Keyboard::KEY_HELP;
k[SDLK_MENU] = Keyboard::KEY_MENU;
k[SDLK_SELECT] = Keyboard::KEY_SELECT;
k[SDLK_STOP] = Keyboard::KEY_STOP;
k[SDLK_AGAIN] = Keyboard::KEY_AGAIN;
k[SDLK_UNDO] = Keyboard::KEY_UNDO;
k[SDLK_CUT] = Keyboard::KEY_CUT;
k[SDLK_COPY] = Keyboard::KEY_COPY;
k[SDLK_PASTE] = Keyboard::KEY_PASTE;
k[SDLK_FIND] = Keyboard::KEY_FIND;
k[SDLK_MUTE] = Keyboard::KEY_MUTE;
k[SDLK_VOLUMEUP] = Keyboard::KEY_VOLUMEUP;
k[SDLK_VOLUMEDOWN] = Keyboard::KEY_VOLUMEDOWN;
k[SDLK_ALTERASE] = Keyboard::KEY_ALTERASE;
k[SDLK_SYSREQ] = Keyboard::KEY_SYSREQ;
k[SDLK_CANCEL] = Keyboard::KEY_CANCEL;
k[SDLK_CLEAR] = Keyboard::KEY_CLEAR;
k[SDLK_PRIOR] = Keyboard::KEY_PRIOR;
k[SDLK_RETURN2] = Keyboard::KEY_RETURN2;
k[SDLK_SEPARATOR] = Keyboard::KEY_SEPARATOR;
k[SDLK_OUT] = Keyboard::KEY_OUT;
k[SDLK_OPER] = Keyboard::KEY_OPER;
k[SDLK_CLEARAGAIN] = Keyboard::KEY_CLEARAGAIN;
k[SDLK_THOUSANDSSEPARATOR] = Keyboard::KEY_THOUSANDSSEPARATOR;
k[SDLK_DECIMALSEPARATOR] = Keyboard::KEY_DECIMALSEPARATOR;
k[SDLK_CURRENCYUNIT] = Keyboard::KEY_CURRENCYUNIT;
k[SDLK_CURRENCYSUBUNIT] = Keyboard::KEY_CURRENCYSUBUNIT;
k[SDLK_LCTRL] = Keyboard::KEY_LCTRL;
k[SDLK_LSHIFT] = Keyboard::KEY_LSHIFT;
k[SDLK_LALT] = Keyboard::KEY_LALT;
k[SDLK_LGUI] = Keyboard::KEY_LGUI;
k[SDLK_RCTRL] = Keyboard::KEY_RCTRL;
k[SDLK_RSHIFT] = Keyboard::KEY_RSHIFT;
k[SDLK_RALT] = Keyboard::KEY_RALT;
k[SDLK_RGUI] = Keyboard::KEY_RGUI;
k[SDLK_MODE] = Keyboard::KEY_MODE;
k[SDLK_AUDIONEXT] = Keyboard::KEY_AUDIONEXT;
k[SDLK_AUDIOPREV] = Keyboard::KEY_AUDIOPREV;
k[SDLK_AUDIOSTOP] = Keyboard::KEY_AUDIOSTOP;
k[SDLK_AUDIOPLAY] = Keyboard::KEY_AUDIOPLAY;
k[SDLK_AUDIOMUTE] = Keyboard::KEY_AUDIOMUTE;
k[SDLK_MEDIASELECT] = Keyboard::KEY_MEDIASELECT;
k[SDLK_BRIGHTNESSDOWN] = Keyboard::KEY_BRIGHTNESSDOWN;
k[SDLK_BRIGHTNESSUP] = Keyboard::KEY_BRIGHTNESSUP;
k[SDLK_DISPLAYSWITCH] = Keyboard::KEY_DISPLAYSWITCH;
k[SDLK_KBDILLUMTOGGLE] = Keyboard::KEY_KBDILLUMTOGGLE;
k[SDLK_KBDILLUMDOWN] = Keyboard::KEY_KBDILLUMDOWN;
k[SDLK_KBDILLUMUP] = Keyboard::KEY_KBDILLUMUP;
k[SDLK_EJECT] = Keyboard::KEY_EJECT;
k[SDLK_SLEEP] = Keyboard::KEY_SLEEP;
return k;
}
EnumMap<love::keyboard::Keyboard::Key, SDLKey, love::keyboard::Keyboard::KEY_MAX_ENUM>::Entry Event::keyEntries[] =
{
{ love::keyboard::Keyboard::KEY_BACKSPACE, SDLK_BACKSPACE},
{ love::keyboard::Keyboard::KEY_TAB, SDLK_TAB},
{ love::keyboard::Keyboard::KEY_CLEAR, SDLK_CLEAR},
{ love::keyboard::Keyboard::KEY_RETURN, SDLK_RETURN},
{ love::keyboard::Keyboard::KEY_PAUSE, SDLK_PAUSE},
{ love::keyboard::Keyboard::KEY_ESCAPE, SDLK_ESCAPE },
{ love::keyboard::Keyboard::KEY_SPACE, SDLK_SPACE },
{ love::keyboard::Keyboard::KEY_EXCLAIM, SDLK_EXCLAIM },
{ love::keyboard::Keyboard::KEY_QUOTEDBL, SDLK_QUOTEDBL },
{ love::keyboard::Keyboard::KEY_HASH, SDLK_HASH },
{ love::keyboard::Keyboard::KEY_DOLLAR, SDLK_DOLLAR },
{ love::keyboard::Keyboard::KEY_AMPERSAND, SDLK_AMPERSAND },
{ love::keyboard::Keyboard::KEY_QUOTE, SDLK_QUOTE },
{ love::keyboard::Keyboard::KEY_LEFTPAREN, SDLK_LEFTPAREN },
{ love::keyboard::Keyboard::KEY_RIGHTPAREN, SDLK_RIGHTPAREN },
{ love::keyboard::Keyboard::KEY_ASTERISK, SDLK_ASTERISK },
{ love::keyboard::Keyboard::KEY_PLUS, SDLK_PLUS },
{ love::keyboard::Keyboard::KEY_COMMA, SDLK_COMMA },
{ love::keyboard::Keyboard::KEY_MINUS, SDLK_MINUS },
{ love::keyboard::Keyboard::KEY_PERIOD, SDLK_PERIOD },
{ love::keyboard::Keyboard::KEY_SLASH, SDLK_SLASH },
{ love::keyboard::Keyboard::KEY_0, SDLK_0 },
{ love::keyboard::Keyboard::KEY_1, SDLK_1 },
{ love::keyboard::Keyboard::KEY_2, SDLK_2 },
{ love::keyboard::Keyboard::KEY_3, SDLK_3 },
{ love::keyboard::Keyboard::KEY_4, SDLK_4 },
{ love::keyboard::Keyboard::KEY_5, SDLK_5 },
{ love::keyboard::Keyboard::KEY_6, SDLK_6 },
{ love::keyboard::Keyboard::KEY_7, SDLK_7 },
{ love::keyboard::Keyboard::KEY_8, SDLK_8 },
{ love::keyboard::Keyboard::KEY_9, SDLK_9 },
{ love::keyboard::Keyboard::KEY_COLON, SDLK_COLON },
{ love::keyboard::Keyboard::KEY_SEMICOLON, SDLK_SEMICOLON },
{ love::keyboard::Keyboard::KEY_LESS, SDLK_LESS },
{ love::keyboard::Keyboard::KEY_EQUALS, SDLK_EQUALS },
{ love::keyboard::Keyboard::KEY_GREATER, SDLK_GREATER },
{ love::keyboard::Keyboard::KEY_QUESTION, SDLK_QUESTION },
{ love::keyboard::Keyboard::KEY_AT, SDLK_AT },
{ love::keyboard::Keyboard::KEY_LEFTBRACKET, SDLK_LEFTBRACKET },
{ love::keyboard::Keyboard::KEY_BACKSLASH, SDLK_BACKSLASH },
{ love::keyboard::Keyboard::KEY_RIGHTBRACKET, SDLK_RIGHTBRACKET },
{ love::keyboard::Keyboard::KEY_CARET, SDLK_CARET },
{ love::keyboard::Keyboard::KEY_UNDERSCORE, SDLK_UNDERSCORE },
{ love::keyboard::Keyboard::KEY_BACKQUOTE, SDLK_BACKQUOTE },
{ love::keyboard::Keyboard::KEY_A, SDLK_a },
{ love::keyboard::Keyboard::KEY_B, SDLK_b },
{ love::keyboard::Keyboard::KEY_C, SDLK_c },
{ love::keyboard::Keyboard::KEY_D, SDLK_d },
{ love::keyboard::Keyboard::KEY_E, SDLK_e },
{ love::keyboard::Keyboard::KEY_F, SDLK_f },
{ love::keyboard::Keyboard::KEY_G, SDLK_g },
{ love::keyboard::Keyboard::KEY_H, SDLK_h },
{ love::keyboard::Keyboard::KEY_I, SDLK_i },
{ love::keyboard::Keyboard::KEY_J, SDLK_j },
{ love::keyboard::Keyboard::KEY_K, SDLK_k },
{ love::keyboard::Keyboard::KEY_L, SDLK_l },
{ love::keyboard::Keyboard::KEY_M, SDLK_m },
{ love::keyboard::Keyboard::KEY_N, SDLK_n },
{ love::keyboard::Keyboard::KEY_O, SDLK_o },
{ love::keyboard::Keyboard::KEY_P, SDLK_p },
{ love::keyboard::Keyboard::KEY_Q, SDLK_q },
{ love::keyboard::Keyboard::KEY_R, SDLK_r },
{ love::keyboard::Keyboard::KEY_S, SDLK_s },
{ love::keyboard::Keyboard::KEY_T, SDLK_t },
{ love::keyboard::Keyboard::KEY_U, SDLK_u },
{ love::keyboard::Keyboard::KEY_V, SDLK_v },
{ love::keyboard::Keyboard::KEY_W, SDLK_w },
{ love::keyboard::Keyboard::KEY_X, SDLK_x },
{ love::keyboard::Keyboard::KEY_Y, SDLK_y },
{ love::keyboard::Keyboard::KEY_Z, SDLK_z },
{ love::keyboard::Keyboard::KEY_DELETE, SDLK_DELETE },
{ love::keyboard::Keyboard::KEY_KP0, SDLK_KP0 },
{ love::keyboard::Keyboard::KEY_KP1, SDLK_KP1 },
{ love::keyboard::Keyboard::KEY_KP2, SDLK_KP2 },
{ love::keyboard::Keyboard::KEY_KP3, SDLK_KP3 },
{ love::keyboard::Keyboard::KEY_KP4, SDLK_KP4 },
{ love::keyboard::Keyboard::KEY_KP5, SDLK_KP5 },
{ love::keyboard::Keyboard::KEY_KP6, SDLK_KP6 },
{ love::keyboard::Keyboard::KEY_KP7, SDLK_KP7 },
{ love::keyboard::Keyboard::KEY_KP8, SDLK_KP8 },
{ love::keyboard::Keyboard::KEY_KP9, SDLK_KP9 },
{ love::keyboard::Keyboard::KEY_KP_PERIOD, SDLK_KP_PERIOD },
{ love::keyboard::Keyboard::KEY_KP_DIVIDE, SDLK_KP_DIVIDE },
{ love::keyboard::Keyboard::KEY_KP_MULTIPLY, SDLK_KP_MULTIPLY},
{ love::keyboard::Keyboard::KEY_KP_MINUS, SDLK_KP_MINUS },
{ love::keyboard::Keyboard::KEY_KP_PLUS, SDLK_KP_PLUS },
{ love::keyboard::Keyboard::KEY_KP_ENTER, SDLK_KP_ENTER },
{ love::keyboard::Keyboard::KEY_KP_EQUALS, SDLK_KP_EQUALS },
{ love::keyboard::Keyboard::KEY_UP, SDLK_UP },
{ love::keyboard::Keyboard::KEY_DOWN, SDLK_DOWN },
{ love::keyboard::Keyboard::KEY_RIGHT, SDLK_RIGHT },
{ love::keyboard::Keyboard::KEY_LEFT, SDLK_LEFT },
{ love::keyboard::Keyboard::KEY_INSERT, SDLK_INSERT },
{ love::keyboard::Keyboard::KEY_HOME, SDLK_HOME },
{ love::keyboard::Keyboard::KEY_END, SDLK_END },
{ love::keyboard::Keyboard::KEY_PAGEUP, SDLK_PAGEUP },
{ love::keyboard::Keyboard::KEY_PAGEDOWN, SDLK_PAGEDOWN },
{ love::keyboard::Keyboard::KEY_F1, SDLK_F1 },
{ love::keyboard::Keyboard::KEY_F2, SDLK_F2 },
{ love::keyboard::Keyboard::KEY_F3, SDLK_F3 },
{ love::keyboard::Keyboard::KEY_F4, SDLK_F4 },
{ love::keyboard::Keyboard::KEY_F5, SDLK_F5 },
{ love::keyboard::Keyboard::KEY_F6, SDLK_F6 },
{ love::keyboard::Keyboard::KEY_F7, SDLK_F7 },
{ love::keyboard::Keyboard::KEY_F8, SDLK_F8 },
{ love::keyboard::Keyboard::KEY_F9, SDLK_F9 },
{ love::keyboard::Keyboard::KEY_F10, SDLK_F10 },
{ love::keyboard::Keyboard::KEY_F11, SDLK_F11 },
{ love::keyboard::Keyboard::KEY_F12, SDLK_F12 },
{ love::keyboard::Keyboard::KEY_F13, SDLK_F13 },
{ love::keyboard::Keyboard::KEY_F14, SDLK_F14 },
{ love::keyboard::Keyboard::KEY_F15, SDLK_F15 },
{ love::keyboard::Keyboard::KEY_NUMLOCK, SDLK_NUMLOCK },
{ love::keyboard::Keyboard::KEY_CAPSLOCK, SDLK_CAPSLOCK },
{ love::keyboard::Keyboard::KEY_SCROLLOCK, SDLK_SCROLLOCK },
{ love::keyboard::Keyboard::KEY_RSHIFT, SDLK_RSHIFT },
{ love::keyboard::Keyboard::KEY_LSHIFT, SDLK_LSHIFT },
{ love::keyboard::Keyboard::KEY_RCTRL, SDLK_RCTRL },
{ love::keyboard::Keyboard::KEY_LCTRL, SDLK_LCTRL },
{ love::keyboard::Keyboard::KEY_RALT, SDLK_RALT },
{ love::keyboard::Keyboard::KEY_LALT, SDLK_LALT },
{ love::keyboard::Keyboard::KEY_RMETA, SDLK_RMETA },
{ love::keyboard::Keyboard::KEY_LMETA, SDLK_LMETA },
{ love::keyboard::Keyboard::KEY_LSUPER, SDLK_LSUPER },
{ love::keyboard::Keyboard::KEY_RSUPER, SDLK_RSUPER },
{ love::keyboard::Keyboard::KEY_MODE, SDLK_MODE },
{ love::keyboard::Keyboard::KEY_COMPOSE, SDLK_COMPOSE },
{ love::keyboard::Keyboard::KEY_HELP, SDLK_HELP },
{ love::keyboard::Keyboard::KEY_PRINT, SDLK_PRINT },
{ love::keyboard::Keyboard::KEY_SYSREQ, SDLK_SYSREQ },
{ love::keyboard::Keyboard::KEY_BREAK, SDLK_BREAK },
{ love::keyboard::Keyboard::KEY_MENU, SDLK_MENU },
{ love::keyboard::Keyboard::KEY_POWER, SDLK_POWER },
{ love::keyboard::Keyboard::KEY_EURO, SDLK_EURO },
{ love::keyboard::Keyboard::KEY_UNDO, SDLK_UNDO },
{ love::keyboard::Keyboard::KEY_UNKNOWN, SDLK_UNKNOWN },
};
EnumMap<love::keyboard::Keyboard::Key, SDLKey, love::keyboard::Keyboard::KEY_MAX_ENUM> Event::keys(Event::keyEntries, sizeof(Event::keyEntries));
std::map<SDL_Keycode, love::keyboard::Keyboard::Key> Event::keys = Event::createKeyMap();
EnumMap<love::mouse::Mouse::Button, Uint8, love::mouse::Mouse::BUTTON_MAX_ENUM>::Entry Event::buttonEntries[] =
{
{ love::mouse::Mouse::BUTTON_LEFT, SDL_BUTTON_LEFT},
{ love::mouse::Mouse::BUTTON_MIDDLE, SDL_BUTTON_MIDDLE},
{ love::mouse::Mouse::BUTTON_RIGHT, SDL_BUTTON_RIGHT},
{ love::mouse::Mouse::BUTTON_WHEELUP, SDL_BUTTON_WHEELUP},
{ love::mouse::Mouse::BUTTON_WHEELDOWN, SDL_BUTTON_WHEELDOWN},
{ love::mouse::Mouse::BUTTON_X1, SDL_BUTTON_X1},
{ love::mouse::Mouse::BUTTON_X2, SDL_BUTTON_X2},
};
EnumMap<love::mouse::Mouse::Button, Uint8, love::mouse::Mouse::BUTTON_MAX_ENUM> Event::buttons(Event::buttonEntries, sizeof(Event::buttonEntries));
EnumMap<love::joystick::Joystick::Hat, Uint8, love::joystick::Joystick::HAT_MAX_ENUM>::Entry Event::hatEntries[] =
{
{love::joystick::Joystick::HAT_CENTERED, SDL_HAT_CENTERED},
{love::joystick::Joystick::HAT_UP, SDL_HAT_UP},
{love::joystick::Joystick::HAT_RIGHT, SDL_HAT_RIGHT},
{love::joystick::Joystick::HAT_DOWN, SDL_HAT_DOWN},
{love::joystick::Joystick::HAT_LEFT, SDL_HAT_LEFT},
{love::joystick::Joystick::HAT_RIGHTUP, SDL_HAT_RIGHTUP},
{love::joystick::Joystick::HAT_RIGHTDOWN, SDL_HAT_RIGHTDOWN},
{love::joystick::Joystick::HAT_LEFTUP, SDL_HAT_LEFTUP},
{love::joystick::Joystick::HAT_LEFTDOWN, SDL_HAT_LEFTDOWN},
};
EnumMap<love::joystick::Joystick::Hat, Uint8, love::joystick::Joystick::HAT_MAX_ENUM> Event::hats(Event::hatEntries, sizeof(Event::hatEntries));
} // sdl
} // event
} // love
+10 -6
View File
@@ -29,6 +29,9 @@
// SDL
#include <SDL.h>
// STL
#include <map>
namespace love
{
namespace event
@@ -44,6 +47,7 @@ public:
const char *getName() const;
Event();
virtual ~Event();
/**
* Pumps the event queue. This function gathers all the pending input information
@@ -66,15 +70,15 @@ public:
private:
Message *convert(SDL_Event &e);
const char *convertUnicode(Uint16 codepoint) const;
Message *convert(const SDL_Event &e) const;
Message *convertJoystickEvent(const SDL_Event &e) const;
Message *convertWindowEvent(const SDL_Event &e) const;
static std::map<SDL_Keycode, love::keyboard::Keyboard::Key> createKeyMap();
static std::map<SDL_Keycode, love::keyboard::Keyboard::Key> keys;
static EnumMap<love::keyboard::Keyboard::Key, SDLKey, love::keyboard::Keyboard::KEY_MAX_ENUM>::Entry keyEntries[];
static EnumMap<love::keyboard::Keyboard::Key, SDLKey, love::keyboard::Keyboard::KEY_MAX_ENUM> keys;
static EnumMap<love::mouse::Mouse::Button, Uint8, love::mouse::Mouse::BUTTON_MAX_ENUM>::Entry buttonEntries[];
static EnumMap<love::mouse::Mouse::Button, Uint8, love::mouse::Mouse::BUTTON_MAX_ENUM> buttons;
static EnumMap<love::joystick::Joystick::Hat, Uint8, love::joystick::Joystick::HAT_MAX_ENUM>::Entry hatEntries[];
static EnumMap<love::joystick::Joystick::Hat, Uint8, love::joystick::Joystick::HAT_MAX_ENUM> hats;
}; // System
+2 -2
View File
@@ -127,9 +127,9 @@ extern "C" int luaopen_love_event(lua_State *L)
{
instance = new Event();
}
catch(Exception &e)
catch (love::Exception &e)
{
return luaL_error(L, e.what());
return luaL_error(L, "%s", e.what());
}
}
else
+5
View File
@@ -108,6 +108,11 @@ public:
virtual ~Graphics();
/**
* Sets the current graphics display viewport dimensions.
**/
virtual void setViewportSize(int width, int height) = 0;
/**
* Sets the current graphics display viewport and initializes the renderer.
* @param width The viewport width.
+26 -13
View File
@@ -52,7 +52,7 @@ Graphics::Graphics()
, created(false)
, savedState()
{
currentWindow = love::window::sdl::Window::getSingleton();
currentWindow = love::window::sdl::Window::createSingleton();
if (currentWindow->isCreated())
setMode(currentWindow->getWidth(), currentWindow->getHeight());
@@ -113,6 +113,27 @@ void Graphics::restoreState(const DisplayState &s)
setColorMask(s.colorMask[0], s.colorMask[1], s.colorMask[2], s.colorMask[3]);
}
void Graphics::setViewportSize(int width, int height)
{
this->width = width;
this->height = height;
if (!isCreated())
return;
// Set the viewport to top-left corner
gl.setViewport(OpenGL::Viewport(0, 0, width, height));
// Reset the projection matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Set up orthographic view (no depth)
glOrtho(0.0, width, height, 0.0, -1.0, 1.0);
glMatrixMode(GL_MODELVIEW);
}
bool Graphics::setMode(int width, int height)
{
this->width = width;
@@ -121,6 +142,10 @@ bool Graphics::setMode(int width, int height)
// Okay, setup OpenGL.
gl.initContext();
created = true;
setViewportSize(width, height);
// Make sure antialiasing works when set elsewhere
if (GLEE_VERSION_1_3 || GLEE_ARB_multisample)
glEnable(GL_MULTISAMPLE);
@@ -147,16 +172,6 @@ bool Graphics::setMode(int width, int height)
glEnable(GL_TEXTURE_2D);
gl.setTextureUnit(0);
// Set the viewport to top-left corner
gl.setViewport(OpenGL::Viewport(0, 0, width, height));
// Reset the projection matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Set up orthographic view (no depth)
glOrtho(0.0, width, height, 0.0, -1.0, 1.0);
// Reset modelview matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
@@ -179,8 +194,6 @@ bool Graphics::setMode(int width, int height)
glGetIntegerv(GL_MAX_MODELVIEW_STACK_DEPTH, &matrixLimit);
matrixLimit -= 5;
created = true;
return true;
}
+1
View File
@@ -112,6 +112,7 @@ public:
void restoreState(const DisplayState &s);
virtual void setViewportSize(int width, int height);
virtual bool setMode(int width, int height);
virtual void unSetMode();
+85 -2
View File
@@ -18,15 +18,26 @@
* 3. This notice may not be removed or altered from any source distribution.
**/
// LOVE
#include "Joystick.h"
// STL
#include <cmath>
namespace love
{
namespace joystick
{
Joystick::~Joystick()
float Joystick::clampval(float x) const
{
if (fabsf(x) < 0.01)
return 0.0f;
if (x < -0.99f) return -1.0f;
if (x > 0.99f) return 1.0f;
return x;
}
bool Joystick::getConstant(const char *in, Joystick::Hat &out)
@@ -34,11 +45,41 @@ bool Joystick::getConstant(const char *in, Joystick::Hat &out)
return hats.find(in, out);
}
bool Joystick::getConstant(Joystick::Hat in, const char *&out)
bool Joystick::getConstant(Joystick::Hat in, const char *&out)
{
return hats.find(in, out);
}
bool Joystick::getConstant(const char *in, Joystick::GamepadAxis &out)
{
return gpAxes.find(in, out);
}
bool Joystick::getConstant(Joystick::GamepadAxis in, const char *&out)
{
return gpAxes.find(in, out);
}
bool Joystick::getConstant(const char *in, Joystick::GamepadButton &out)
{
return gpButtons.find(in, out);
}
bool Joystick::getConstant(Joystick::GamepadButton in, const char *&out)
{
return gpButtons.find(in, out);
}
bool Joystick::getConstant(const char *in, Joystick::InputType &out)
{
return inputTypes.find(in, out);
}
bool Joystick::getConstant(Joystick::InputType in, const char *&out)
{
return inputTypes.find(in, out);
}
StringMap<Joystick::Hat, Joystick::HAT_MAX_ENUM>::Entry Joystick::hatEntries[] =
{
{"c", Joystick::HAT_CENTERED},
@@ -54,5 +95,47 @@ StringMap<Joystick::Hat, Joystick::HAT_MAX_ENUM>::Entry Joystick::hatEntries[] =
StringMap<Joystick::Hat, Joystick::HAT_MAX_ENUM> Joystick::hats(Joystick::hatEntries, sizeof(Joystick::hatEntries));
StringMap<Joystick::GamepadAxis, Joystick::GAMEPAD_AXIS_MAX_ENUM>::Entry Joystick::gpAxisEntries[] =
{
{"leftx", GAMEPAD_AXIS_LEFTX},
{"lefty", GAMEPAD_AXIS_LEFTY},
{"rightx", GAMEPAD_AXIS_RIGHTX},
{"righty", GAMEPAD_AXIS_RIGHTY},
{"triggerleft", GAMEPAD_AXIS_TRIGGERLEFT},
{"triggerright", GAMEPAD_AXIS_TRIGGERRIGHT},
};
StringMap<Joystick::GamepadAxis, Joystick::GAMEPAD_AXIS_MAX_ENUM> Joystick::gpAxes(Joystick::gpAxisEntries, sizeof(Joystick::gpAxisEntries));
StringMap<Joystick::GamepadButton, Joystick::GAMEPAD_BUTTON_MAX_ENUM>::Entry Joystick::gpButtonEntries[] =
{
{"a", GAMEPAD_BUTTON_A},
{"b", GAMEPAD_BUTTON_B},
{"x", GAMEPAD_BUTTON_X},
{"y", GAMEPAD_BUTTON_Y},
{"back", GAMEPAD_BUTTON_BACK},
{"guide", GAMEPAD_BUTTON_GUIDE},
{"start", GAMEPAD_BUTTON_START},
{"leftstick", GAMEPAD_BUTTON_LEFTSTICK},
{"rightstick", GAMEPAD_BUTTON_RIGHTSTICK},
{"leftshoulder", GAMEPAD_BUTTON_LEFTSHOULDER},
{"rightshoulder", GAMEPAD_BUTTON_RIGHTSHOULDER},
{"dpup", GAMEPAD_BUTTON_DPAD_UP},
{"dpdown", GAMEPAD_BUTTON_DPAD_DOWN},
{"dpleft", GAMEPAD_BUTTON_DPAD_LEFT},
{"dpright", GAMEPAD_BUTTON_DPAD_RIGHT},
};
StringMap<Joystick::GamepadButton, Joystick::GAMEPAD_BUTTON_MAX_ENUM> Joystick::gpButtons(Joystick::gpButtonEntries, sizeof(Joystick::gpButtonEntries));
StringMap<Joystick::InputType, Joystick::INPUT_TYPE_MAX_ENUM>::Entry Joystick::inputTypeEntries[] =
{
{"axis", Joystick::INPUT_TYPE_AXIS},
{"button", Joystick::INPUT_TYPE_BUTTON},
{"hat", Joystick::INPUT_TYPE_HAT},
};
StringMap<Joystick::InputType, Joystick::INPUT_TYPE_MAX_ENUM> Joystick::inputTypes(Joystick::inputTypeEntries, sizeof(Joystick::inputTypeEntries));
} // joystick
} // love
+133 -5
View File
@@ -22,18 +22,23 @@
#define LOVE_JOYSTICK_JOYSTICK_H
// LOVE
#include "common/Module.h"
#include "common/Object.h"
#include "common/StringMap.h"
// stdlib
#include <vector>
#include <string>
namespace love
{
namespace joystick
{
class Joystick : public Module
class Joystick : public Object
{
public:
// Joystick hat values.
enum Hat
{
HAT_INVALID,
@@ -49,19 +54,142 @@ public:
HAT_MAX_ENUM = 16
};
virtual ~Joystick();
// Valid Gamepad axes.
enum GamepadAxis
{
GAMEPAD_AXIS_INVALID,
GAMEPAD_AXIS_LEFTX,
GAMEPAD_AXIS_LEFTY,
GAMEPAD_AXIS_RIGHTX,
GAMEPAD_AXIS_RIGHTY,
GAMEPAD_AXIS_TRIGGERLEFT,
GAMEPAD_AXIS_TRIGGERRIGHT,
GAMEPAD_AXIS_MAX_ENUM
};
// Valid Gamepad buttons.
enum GamepadButton
{
GAMEPAD_BUTTON_INVALID,
GAMEPAD_BUTTON_A,
GAMEPAD_BUTTON_B,
GAMEPAD_BUTTON_X,
GAMEPAD_BUTTON_Y,
GAMEPAD_BUTTON_BACK,
GAMEPAD_BUTTON_GUIDE,
GAMEPAD_BUTTON_START,
GAMEPAD_BUTTON_LEFTSTICK,
GAMEPAD_BUTTON_RIGHTSTICK,
GAMEPAD_BUTTON_LEFTSHOULDER,
GAMEPAD_BUTTON_RIGHTSHOULDER,
GAMEPAD_BUTTON_DPAD_UP,
GAMEPAD_BUTTON_DPAD_DOWN,
GAMEPAD_BUTTON_DPAD_LEFT,
GAMEPAD_BUTTON_DPAD_RIGHT,
GAMEPAD_BUTTON_MAX_ENUM
};
// Different types of inputs for a joystick.
enum InputType
{
INPUT_TYPE_AXIS,
INPUT_TYPE_BUTTON,
INPUT_TYPE_HAT,
INPUT_TYPE_MAX_ENUM
};
// Represents a gamepad input value, e.g. the "x" button or the left trigger.
struct GamepadInput
{
InputType type;
union
{
GamepadAxis axis;
GamepadButton button;
};
};
// Represents a joystick input value, e.g. button 6 or axis 1.
struct JoystickInput
{
InputType type;
union
{
int axis;
int button;
struct
{
int index;
Hat value;
} hat;
};
};
virtual ~Joystick() {}
virtual bool open(int deviceindex) = 0;
virtual void close() = 0;
virtual bool isConnected() const = 0;
virtual const char *getName() const = 0;
virtual int getAxisCount() const = 0;
virtual int getButtonCount() const = 0;
virtual int getHatCount() const = 0;
virtual float getAxis(int axisindex) const = 0;
virtual std::vector<float> getAxes() const = 0;
virtual Hat getHat(int hatindex) const = 0;
virtual bool isDown(const std::vector<int> &buttonlist) const = 0;
virtual bool openGamepad(int deviceindex) = 0;
virtual bool isGamepad() const = 0;
virtual float getGamepadAxis(GamepadAxis axis) const = 0;
virtual bool isGamepadDown(const std::vector<GamepadButton> &blist) const = 0;
virtual void *getHandle() const = 0;
virtual std::string getGUID() const = 0;
virtual int getInstanceID() const = 0;
virtual int getID() const = 0;
static bool getConstant(const char *in, Hat &out);
static bool getConstant(Hat in, const char *&out);
static bool getConstant(Hat in, const char *&out);
static bool getConstant(const char *in, GamepadAxis &out);
static bool getConstant(GamepadAxis in, const char *&out);
static bool getConstant(const char *in, GamepadButton &out);
static bool getConstant(GamepadButton in, const char *&out);
static bool getConstant(const char *in, InputType &out);
static bool getConstant(InputType in, const char *&out);
protected:
float clampval(float x) const;
private:
static StringMap<Hat, HAT_MAX_ENUM>::Entry hatEntries[];
static StringMap<Hat, HAT_MAX_ENUM> hats;
static StringMap<GamepadAxis, GAMEPAD_AXIS_MAX_ENUM>::Entry gpAxisEntries[];
static StringMap<GamepadAxis, GAMEPAD_AXIS_MAX_ENUM> gpAxes;
static StringMap<GamepadButton, GAMEPAD_BUTTON_MAX_ENUM>::Entry gpButtonEntries[];
static StringMap<GamepadButton, GAMEPAD_BUTTON_MAX_ENUM> gpButtons;
static StringMap<InputType, INPUT_TYPE_MAX_ENUM>::Entry inputTypeEntries[];
static StringMap<InputType, INPUT_TYPE_MAX_ENUM> inputTypes;
}; // Joystick
} // joystick
} // love
#endif // LOVE_JOYSTICK_JOYSTICK_H
#endif // LOVE_JOYSTICK_JOYSTICK_H
+99
View File
@@ -0,0 +1,99 @@
/**
* Copyright (c) 2006-2013 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_JOYSTICK_JOYSTICK_MODULE_H
#define LOVE_JOYSTICK_JOYSTICK_MODULE_H
// LOVE
#include "common/Module.h"
#include "Joystick.h"
namespace love
{
namespace joystick
{
class JoystickModule : public Module
{
public:
virtual ~JoystickModule() {}
/**
* Adds a connected Joystick device and opens it for use.
* Returns NULL if the Joystick could not be added.
**/
virtual Joystick *addJoystick(int deviceindex) = 0;
/**
* Removes a disconnected Joystick device.
**/
virtual void removeJoystick(Joystick *joystick) = 0;
/**
* Gets a connected Joystick from its unique Instance ID.
* Returns NULL if the instance ID does not correspond to a connected stick.
**/
virtual Joystick *getJoystickFromID(int instanceid) = 0;
/**
* Gets a connected Joystick.
* Returns NULL if joyindex is not in the range of [0, getJoystickCount()).
**/
virtual Joystick *getJoystick(int joyindex) = 0;
/**
* Gets the index of a connected joystick.
* Returns -1 if the joystick is not connected.
**/
virtual int getIndex(const Joystick *joystick) = 0;
/**
* Gets the number of currently connected Joysticks.
**/
virtual int getJoystickCount() const = 0;
/**
* Determines whether the Joystick at the specified index is a recognized
* Gamepad.
**/
virtual bool isGamepad(int joyindex) const = 0;
/**
* Sets the virtual Gamepad mapping for a joystick input value for all
* joystick devices with the specified joystick GUID.
* If any joysticks with the specified GUID are connected, they will be
* added as Gamepads if they aren't already, otherwise their Gamepad mapping
* will be updated.
**/
virtual bool setGamepadMapping(const std::string &guid, Joystick::GamepadInput gpinput, Joystick::JoystickInput joyinput) = 0;
/**
* Gets the joystick input value the gamepad input value is bound to for the
* specified joystick GUID.
**/
virtual Joystick::JoystickInput getGamepadMapping(const std::string &guid, Joystick::GamepadInput gpinput) = 0;
}; // JoystickModule
} // joystick
} // love
#endif // LOVE_JOYSTICK_JOYSTICK_MODULE_H
+225 -141
View File
@@ -20,9 +20,6 @@
#include "Joystick.h"
// STD
#include <cmath>
namespace love
{
namespace joystick
@@ -30,206 +27,260 @@ namespace joystick
namespace sdl
{
Joystick::Joystick()
: joysticks(0)
Joystick::Joystick(int id)
: joyhandle(0)
, controller(0)
, instanceid(-1)
, id(id)
{
// Init the SDL joystick system.
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0)
throw love::Exception("%s", SDL_GetError());
}
// Start joystick event watching.
SDL_JoystickEventState(SDL_ENABLE);
// Open all connected joysticks.
int numjoysticks = getJoystickCount();
if (numjoysticks > 0)
this->joysticks = (SDL_Joystick **)calloc(numjoysticks, sizeof(SDL_Joystick *));
for (int i = 0; i<numjoysticks; i++)
this->open(i);
Joystick::Joystick(int id, int joyindex)
: joyhandle(0)
, controller(0)
, instanceid(-1)
, id(id)
{
open(joyindex);
}
Joystick::~Joystick()
{
// Closes any open joysticks.
for (int i = 0; i != getJoystickCount(); i++)
{
if (isOpen(i))
close(i);
}
free(joysticks);
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
close();
}
void Joystick::reload()
bool Joystick::open(int deviceindex)
{
// Closes any open joysticks.
for (int i = 0; i != getJoystickCount(); i++)
close();
joyhandle = SDL_JoystickOpen(deviceindex);
if (joyhandle)
{
if (isOpen(i))
close(i);
instanceid = SDL_JoystickInstanceID(joyhandle);
// SDL_JoystickGetGUIDString uses 32 bytes plus the null terminator.
char cstr[33];
SDL_JoystickGUID sdlguid = SDL_JoystickGetGUID(joyhandle);
SDL_JoystickGetGUIDString(sdlguid, cstr, (int) sizeof(cstr));
guid = std::string(cstr);
// See if SDL thinks this is a Game Controller.
openGamepad(deviceindex);
// Prefer the GameController name.
if (controller)
name = SDL_GameControllerName(controller);
else
name = SDL_JoystickName(joyhandle);
}
free(joysticks);
return isConnected();
}
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
void Joystick::close()
{
if (controller)
SDL_GameControllerClose(controller);
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) < 0)
throw love::Exception("%s", SDL_GetError());
if (joyhandle)
SDL_JoystickClose(joyhandle);
int numjoysticks = this->getJoystickCount();
if (numjoysticks > 0)
this->joysticks = (SDL_Joystick **)calloc(numjoysticks, sizeof(SDL_Joystick *));
joyhandle = 0;
controller = 0;
instanceid = -1;
}
for (int i = 0; i<numjoysticks; i++)
this->open(i);
bool Joystick::isConnected() const
{
return joyhandle != 0 && SDL_JoystickGetAttached(joyhandle);
}
const char *Joystick::getName() const
{
return "love.joystick.sdl";
// Use the saved name if this Joystick isn't connected anymore.
if (!isConnected())
return name.c_str();
// Prefer SDL's GameController name, if possible.
if (isGamepad())
return SDL_GameControllerName(controller);
return SDL_JoystickName(joyhandle);
}
bool Joystick::checkIndex(int index)
int Joystick::getAxisCount() const
{
return index >= 0 && index < getJoystickCount();
return isConnected() ? SDL_JoystickNumAxes(joyhandle) : 0;
}
int Joystick::getJoystickCount()
int Joystick::getButtonCount() const
{
int num = SDL_NumJoysticks();
return num < 0 ? 0 : num;
return isConnected() ? SDL_JoystickNumButtons(joyhandle) : 0;
}
const char *Joystick::getName(int index)
int Joystick::getHatCount() const
{
return SDL_JoystickName(index);
return isConnected() ? SDL_JoystickNumHats(joyhandle) : 0;
}
bool Joystick::open(int index)
float Joystick::getAxis(int axisindex) const
{
if (isOpen(index))
return true;
if (!checkIndex(index))
return false;
if (!(joysticks[index] = SDL_JoystickOpen(index)))
return false;
return true;
}
bool Joystick::isOpen(int index)
{
if (!checkIndex(index))
return false;
return joysticks[index] != 0 ? true : false;
}
bool Joystick::verifyJoystick(int index)
{
if (!checkIndex(index))
return false;
if (!isOpen(index))
return false;
return true;
}
int Joystick::getAxisCount(int index)
{
return verifyJoystick(index) ? SDL_JoystickNumAxes(joysticks[index]) : 0;
}
int Joystick::getButtonCount(int index)
{
return verifyJoystick(index) ? SDL_JoystickNumButtons(joysticks[index]) : 0;
}
int Joystick::getHatCount(int index)
{
return verifyJoystick(index) ? SDL_JoystickNumHats(joysticks[index]) : 0;
}
float Joystick::clampval(float x)
{
if (fabs((double)x) < 0.01) return 0.0f;
if (x < -0.99f) return -1.0f;
if (x > 0.99f) return 1.0f;
return x;
}
float Joystick::getAxis(int index, int axis)
{
if (!verifyJoystick(index))
if (!isConnected() || axisindex < 0 || axisindex >= getAxisCount())
return 0;
if (axis >= getAxisCount(index))
return 0;
return clampval(((float)SDL_JoystickGetAxis(joysticks[index], axis))/32768.0f);
return clampval(((float) SDL_JoystickGetAxis(joyhandle, axisindex))/32768.0f);
}
int Joystick::getAxes(lua_State *L)
std::vector<float> Joystick::getAxes() const
{
int index = luaL_checkint(L, 1) - 1;
std::vector<float> axes;
int count = getAxisCount();
if (!verifyJoystick(index))
return 0;
if (!isConnected() || count <= 0)
return axes;
int num = getAxisCount(index);
axes.reserve(count);
for (int i = 0; i<num; i++)
lua_pushnumber(L, clampval(((float)SDL_JoystickGetAxis(joysticks[index], i))/32768.0f));
return num;
for (int i = 0; i < count; i++)
axes.push_back(clampval(((float) SDL_JoystickGetAxis(joyhandle, i))/32768.0f));
return axes;
}
bool Joystick::isDown(int index, int *buttonlist)
Joystick::Hat Joystick::getHat(int hatindex) const
{
if (!verifyJoystick(index))
Hat h = HAT_INVALID;
if (!isConnected() || hatindex < 0 || hatindex >= getHatCount())
return h;
getConstant(SDL_JoystickGetHat(joyhandle, hatindex), h);
return h;
}
bool Joystick::isDown(const std::vector<int> &buttonlist) const
{
if (!isConnected())
return false;
int num = getButtonCount(index);
int num = getButtonCount();
for (int button = *buttonlist; button != -1; button = *(++buttonlist))
for (size_t i = 0; i < buttonlist.size(); i++)
{
if (button >= 0 && button < num && SDL_JoystickGetButton(joysticks[index], button) == 1)
int button = buttonlist[i];
if (button >= 0 && button < num && SDL_JoystickGetButton(joyhandle, button) == 1)
return true;
}
return false;
}
Joystick::Hat Joystick::getHat(int index, int hat)
bool Joystick::openGamepad(int deviceindex)
{
Hat h = HAT_INVALID;
if (!SDL_IsGameController(deviceindex))
return false;
if (!verifyJoystick(index))
return h;
if (isGamepad())
{
SDL_GameControllerClose(controller);
controller = 0;
}
if (hat >= getHatCount(index))
return h;
hats.find(SDL_JoystickGetHat(joysticks[index], hat), h);
return h;
controller = SDL_GameControllerOpen(deviceindex);
return isGamepad();
}
void Joystick::close(int index)
bool Joystick::isGamepad() const
{
if (!checkIndex(index))
return;
return controller != 0;
}
if (joysticks[index]!=0)
float Joystick::getGamepadAxis(love::joystick::Joystick::GamepadAxis axis) const
{
if (!isConnected() || !isGamepad())
return 0.f;
SDL_GameControllerAxis sdlaxis;
if (!getConstant(axis, sdlaxis))
return 0.f;
Sint16 value = SDL_GameControllerGetAxis(controller, sdlaxis);
return clampval((float) value / 32768.0f);
}
bool Joystick::isGamepadDown(const std::vector<GamepadButton> &blist) const
{
if (!isConnected() || !isGamepad())
return false;
SDL_GameControllerButton sdlbutton;
for (size_t i = 0; i < blist.size(); i++)
{
SDL_JoystickClose(joysticks[index]);
joysticks[index] = 0;
if (!getConstant(blist[i], sdlbutton))
continue;
if (SDL_GameControllerGetButton(controller, sdlbutton) == 1)
return true;
}
return false;
}
void *Joystick::getHandle() const
{
return joyhandle;
}
std::string Joystick::getGUID() const
{
// SDL2's GUIDs identify *classes* of devices, instead of unique devices.
return guid;
}
int Joystick::getInstanceID() const
{
return instanceid;
}
int Joystick::getID() const
{
return id;
}
bool Joystick::getConstant(Uint8 in, Joystick::Hat &out)
{
return hats.find(in, out);
}
bool Joystick::getConstant(Joystick::Hat in, Uint8 &out)
{
return hats.find(in, out);
}
bool Joystick::getConstant(SDL_GameControllerAxis in, Joystick::GamepadAxis &out)
{
return gpAxes.find(in, out);
}
bool Joystick::getConstant(Joystick::GamepadAxis in, SDL_GameControllerAxis &out)
{
return gpAxes.find(in, out);
}
bool Joystick::getConstant(SDL_GameControllerButton in, Joystick::GamepadButton &out)
{
return gpButtons.find(in, out);
}
bool Joystick::getConstant(Joystick::GamepadButton in, SDL_GameControllerButton &out)
{
return gpButtons.find(in, out);
}
EnumMap<Joystick::Hat, Uint8, Joystick::HAT_MAX_ENUM>::Entry Joystick::hatEntries[] =
@@ -247,6 +298,39 @@ EnumMap<Joystick::Hat, Uint8, Joystick::HAT_MAX_ENUM>::Entry Joystick::hatEntrie
EnumMap<Joystick::Hat, Uint8, Joystick::HAT_MAX_ENUM> Joystick::hats(Joystick::hatEntries, sizeof(Joystick::hatEntries));
EnumMap<Joystick::GamepadAxis, SDL_GameControllerAxis, Joystick::GAMEPAD_AXIS_MAX_ENUM>::Entry Joystick::gpAxisEntries[] =
{
{Joystick::GAMEPAD_AXIS_LEFTX, SDL_CONTROLLER_AXIS_LEFTX},
{Joystick::GAMEPAD_AXIS_LEFTY, SDL_CONTROLLER_AXIS_LEFTY},
{Joystick::GAMEPAD_AXIS_RIGHTX, SDL_CONTROLLER_AXIS_RIGHTX},
{Joystick::GAMEPAD_AXIS_RIGHTY, SDL_CONTROLLER_AXIS_RIGHTY},
{Joystick::GAMEPAD_AXIS_TRIGGERLEFT, SDL_CONTROLLER_AXIS_TRIGGERLEFT},
{Joystick::GAMEPAD_AXIS_TRIGGERRIGHT, SDL_CONTROLLER_AXIS_TRIGGERRIGHT},
};
EnumMap<Joystick::GamepadAxis, SDL_GameControllerAxis, Joystick::GAMEPAD_AXIS_MAX_ENUM> Joystick::gpAxes(Joystick::gpAxisEntries, sizeof(Joystick::gpAxisEntries));
EnumMap<Joystick::GamepadButton, SDL_GameControllerButton, Joystick::GAMEPAD_BUTTON_MAX_ENUM>::Entry Joystick::gpButtonEntries[] =
{
{Joystick::GAMEPAD_BUTTON_A, SDL_CONTROLLER_BUTTON_A},
{Joystick::GAMEPAD_BUTTON_B, SDL_CONTROLLER_BUTTON_B},
{Joystick::GAMEPAD_BUTTON_X, SDL_CONTROLLER_BUTTON_X},
{Joystick::GAMEPAD_BUTTON_Y, SDL_CONTROLLER_BUTTON_Y},
{Joystick::GAMEPAD_BUTTON_BACK, SDL_CONTROLLER_BUTTON_BACK},
{Joystick::GAMEPAD_BUTTON_GUIDE, SDL_CONTROLLER_BUTTON_GUIDE},
{Joystick::GAMEPAD_BUTTON_START, SDL_CONTROLLER_BUTTON_START},
{Joystick::GAMEPAD_BUTTON_LEFTSTICK, SDL_CONTROLLER_BUTTON_LEFTSTICK},
{Joystick::GAMEPAD_BUTTON_RIGHTSTICK, SDL_CONTROLLER_BUTTON_RIGHTSTICK},
{Joystick::GAMEPAD_BUTTON_LEFTSHOULDER, SDL_CONTROLLER_BUTTON_LEFTSHOULDER},
{Joystick::GAMEPAD_BUTTON_RIGHTSHOULDER, SDL_CONTROLLER_BUTTON_RIGHTSHOULDER},
{Joystick::GAMEPAD_BUTTON_DPAD_UP, SDL_CONTROLLER_BUTTON_DPAD_UP},
{Joystick::GAMEPAD_BUTTON_DPAD_DOWN, SDL_CONTROLLER_BUTTON_DPAD_DOWN},
{Joystick::GAMEPAD_BUTTON_DPAD_LEFT, SDL_CONTROLLER_BUTTON_DPAD_LEFT},
{Joystick::GAMEPAD_BUTTON_DPAD_RIGHT, SDL_CONTROLLER_BUTTON_DPAD_RIGHT},
};
EnumMap<Joystick::GamepadButton, SDL_GameControllerButton, Joystick::GAMEPAD_BUTTON_MAX_ENUM> Joystick::gpButtons(Joystick::gpButtonEntries, sizeof(Joystick::gpButtonEntries));
} // sdl
} // joystick
} // love
+59 -22
View File
@@ -26,7 +26,8 @@
#include "common/EnumMap.h"
// SDL
#include <SDL.h>
#include <SDL_joystick.h>
#include <SDL_gamecontroller.h>
namespace love
{
@@ -37,38 +38,74 @@ namespace sdl
class Joystick : public love::joystick::Joystick
{
private:
SDL_Joystick **joysticks;
public:
Joystick();
Joystick(int id);
Joystick(int id, int joyindex);
virtual ~Joystick();
// Implements Module.
bool open(int deviceindex);
void close();
bool isConnected() const;
const char *getName() const;
void reload();
bool checkIndex(int index);
int getJoystickCount();
const char *getName(int index);
bool open(int index);
bool isOpen(int index);
bool verifyJoystick(int index);
int getAxisCount(int index);
int getButtonCount(int index);
int getHatCount(int index);
float clampval(float x);
float getAxis(int index, int axis);
int getAxes(lua_State *L);
bool isDown(int index, int *buttonlist);
Hat getHat(int index, int hat);
void close(int index);
int getAxisCount() const;
int getButtonCount() const;
int getHatCount() const;
float getAxis(int axisindex) const;
std::vector<float> getAxes() const;
Hat getHat(int hatindex) const;
bool isDown(const std::vector<int> &buttonlist) const;
bool openGamepad(int deviceindex);
bool isGamepad() const;
float getGamepadAxis(GamepadAxis axis) const;
bool isGamepadDown(const std::vector<GamepadButton> &blist) const;
void *getHandle() const;
std::string getGUID() const;
int getInstanceID() const;
int getID() const;
static bool getConstant(Hat in, Uint8 &out);
static bool getConstant(Uint8 in, Hat &out);
static bool getConstant(SDL_GameControllerAxis in, GamepadAxis &out);
static bool getConstant(GamepadAxis in, SDL_GameControllerAxis &out);
static bool getConstant(SDL_GameControllerButton in, GamepadButton &out);
static bool getConstant(GamepadButton in, SDL_GameControllerButton &out);
private:
Joystick() {}
SDL_Joystick *joyhandle;
SDL_GameController *controller;
SDL_JoystickID instanceid;
std::string guid;
int id;
std::string name;
static EnumMap<Hat, Uint8, Joystick::HAT_MAX_ENUM>::Entry hatEntries[];
static EnumMap<Hat, Uint8, Joystick::HAT_MAX_ENUM> hats;
}; // Joystick
static EnumMap<GamepadAxis, SDL_GameControllerAxis, GAMEPAD_AXIS_MAX_ENUM>::Entry gpAxisEntries[];
static EnumMap<GamepadAxis, SDL_GameControllerAxis, GAMEPAD_AXIS_MAX_ENUM> gpAxes;
static EnumMap<GamepadButton, SDL_GameControllerButton, GAMEPAD_BUTTON_MAX_ENUM>::Entry gpButtonEntries[];
static EnumMap<GamepadButton, SDL_GameControllerButton, GAMEPAD_BUTTON_MAX_ENUM> gpButtons;
};
} // sdl
} // joystick
+450
View File
@@ -0,0 +1,450 @@
/**
* Copyright (c) 2006-2013 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "common/config.h"
#include "JoystickModule.h"
#include "Joystick.h"
// SDL
#include <SDL.h>
// C++
#include <sstream>
#include <algorithm>
// C
#include <cstdlib>
namespace love
{
namespace joystick
{
namespace sdl
{
JoystickModule::JoystickModule()
{
// Init the SDL Joystick and Game Controller systems.
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER) < 0)
throw love::Exception("%s", SDL_GetError());
// Start joystick event watching. Joysticks are automatically added and
// removed via love.event.
SDL_JoystickEventState(SDL_ENABLE);
SDL_GameControllerEventState(SDL_ENABLE);
}
JoystickModule::~JoystickModule()
{
// Close any open Joysticks.
for (size_t i = 0; i < joysticks.size(); i++)
{
joysticks[i]->close();
joysticks[i]->release();
}
SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER);
}
const char *JoystickModule::getName() const
{
return "love.joystick.sdl";
}
love::joystick::Joystick *JoystickModule::getJoystick(int joyindex)
{
if (joyindex < 0 || (size_t) joyindex >= activeSticks.size())
return 0;
return activeSticks[joyindex];
}
int JoystickModule::getIndex(const love::joystick::Joystick *joystick)
{
for (size_t i = 0; i < activeSticks.size(); i++)
{
if (activeSticks[i] == joystick)
return i;
}
// Joystick is not connected.
return -1;
}
int JoystickModule::getJoystickCount() const
{
return (int) activeSticks.size();
}
bool JoystickModule::isGamepad(int joyindex) const
{
if (joyindex < 0 || (size_t) joyindex >= activeSticks.size())
return false;
return activeSticks[joyindex]->isGamepad();
}
love::joystick::Joystick *JoystickModule::getJoystickFromID(int instanceid)
{
for (size_t i = 0; i < activeSticks.size(); i++)
{
if (instanceid == activeSticks[i]->getInstanceID())
return activeSticks[i];
}
return 0;
}
love::joystick::Joystick *JoystickModule::addJoystick(int deviceindex)
{
if (deviceindex < 0 || deviceindex >= SDL_NumJoysticks())
return 0;
std::string guidstr = getDeviceGUID(deviceindex);
joystick::Joystick *joystick = 0;
for (size_t i = 0; i < joysticks.size(); i++)
{
// Try to re-use a disconnected Joystick with the same GUID.
if (!joysticks[i]->isConnected() && joysticks[i]->getGUID() == guidstr)
{
joystick = joysticks[i];
joystick->open(deviceindex);
break;
}
}
if (!joystick)
{
// Make a new Joystick and add it to the persistent list, if we can't
// re-use one.
joystick = new Joystick(joysticks.size(), deviceindex);
joysticks.push_back(joystick);
}
// Add the Joystick to the connected list, if it's not there already.
if (std::find(activeSticks.begin(), activeSticks.end(), joystick) == activeSticks.end())
activeSticks.push_back(joystick);
return joystick;
}
void JoystickModule::removeJoystick(love::joystick::Joystick *joystick)
{
if (!joystick)
return;
// Close the Joystick and remove it from the active joystick list.
std::vector<joystick::Joystick *>::iterator it = std::find(activeSticks.begin(), activeSticks.end(), joystick);
if (it != activeSticks.end())
{
(*it)->close();
activeSticks.erase(it);
}
}
bool JoystickModule::setGamepadMapping(const std::string &guid, Joystick::GamepadInput gpinput, Joystick::JoystickInput joyinput)
{
// All SDL joystick GUID strings are 32 characters.
if (guid.length() != 32)
throw love::Exception("Invalid joystick GUID: %s", guid.c_str());
SDL_JoystickGUID sdlguid = SDL_JoystickGetGUIDFromString(guid.c_str());
std::string mapstr;
char *sdlmapstr = SDL_GameControllerMappingForGUID(sdlguid);
if (sdlmapstr)
{
mapstr = sdlmapstr;
SDL_free(sdlmapstr);
}
else
{
// Use a generic name if we have to create a new mapping string.
mapstr = guid + ",Controller,";
}
std::stringstream joyinputstream;
Uint8 sdlhat;
// We can't have negative int values in the bind string.
switch (joyinput.type)
{
case Joystick::INPUT_TYPE_AXIS:
if (joyinput.axis >= 0)
joyinputstream << "a" << joyinput.axis;
break;
case Joystick::INPUT_TYPE_BUTTON:
if (joyinput.button >= 0)
joyinputstream << "b" << joyinput.button;
break;
case Joystick::INPUT_TYPE_HAT:
if (joyinput.hat.value >= 0 && Joystick::getConstant(joyinput.hat.value, sdlhat))
joyinputstream << "h" << joyinput.hat.value << "." << int(sdlhat);
break;
default:
break;
}
std::string joyinputstr = joyinputstream.str();
if (joyinputstr.length() == 0)
throw love::Exception("Invalid joystick input value.");
// SDL's name for the gamepad input value, e.g. "guide".
std::string gpinputname = stringFromGamepadInput(gpinput);
// We should remove any existing joystick bind for this gamepad buttton/axis
// so SDL's parser doesn't get mixed up.
removeBindFromMapString(mapstr, joyinputstr);
// The string we'll be adding to the mapping string, e.g. "guide:b10,"
std::string insertstr = gpinputname + ":" + joyinputstr + ",";
// We should replace any existing gamepad bind.
size_t findpos = mapstr.find(gpinputname + ":");
if (findpos != std::string::npos)
{
// The bind string ends at the next comma, or the end of the string.
size_t endpos = mapstr.find_first_of(',', findpos);
if (endpos == std::string::npos)
endpos = mapstr.length() - 1;
mapstr.replace(findpos, endpos - findpos + 1, insertstr);
}
else
{
// Just append to the end if we don't need to replace anything.
mapstr += insertstr;
}
// 1 == added, 0 == updated, -1 == error.
int status = SDL_GameControllerAddMapping(mapstr.c_str());
// FIXME: massive hack until missing APIs are added to SDL 2:
// https://bugzilla.libsdl.org/show_bug.cgi?id=1975
if (status == 1)
checkGamepads(guid);
return status >= 0;
}
Joystick::JoystickInput JoystickModule::getGamepadMapping(const std::string &guid, Joystick::GamepadInput gpinput)
{
// All SDL joystick GUID strings are 32 characters.
if (guid.length() != 32)
throw love::Exception("Invalid joystick GUID: %s", guid.c_str());
Joystick::JoystickInput jinput;
jinput.type = Joystick::INPUT_TYPE_MAX_ENUM;
SDL_JoystickGUID sdlguid = SDL_JoystickGetGUIDFromString(guid.c_str());
std::string mapstr;
char *sdlmapstr = SDL_GameControllerMappingForGUID(sdlguid);
if (!sdlmapstr)
return jinput;
mapstr = sdlmapstr;
SDL_free(sdlmapstr);
std::string gpbindname = stringFromGamepadInput(gpinput);
size_t findpos = mapstr.find(std::string(",") + gpbindname + ":");
if (findpos == std::string::npos)
return jinput;
size_t endpos = mapstr.find_first_of(',', findpos);
if (endpos == std::string::npos)
{
// Assume end-of-string if we can't find the next comma.
endpos = mapstr.length() - 1;
}
if (endpos >= mapstr.length())
return jinput; // Something went wrong.
// Strip out the trailing comma from our search position, if it exists.
if (mapstr[endpos] == ',')
endpos--;
// New start position: comma + gamepadinputlength + ":".
findpos += 1 + gpbindname.length() + 1;
std::string jbindstr = mapstr.substr(findpos, endpos - findpos + 1);
jinput = JoystickInputFromString(jbindstr);
return jinput;
}
std::string JoystickModule::stringFromGamepadInput(Joystick::GamepadInput gpinput) const
{
SDL_GameControllerAxis sdlaxis;
SDL_GameControllerButton sdlbutton;
const char *gpinputname = 0;
switch (gpinput.type)
{
case Joystick::INPUT_TYPE_AXIS:
if (Joystick::getConstant(gpinput.axis, sdlaxis))
gpinputname = SDL_GameControllerGetStringForAxis(sdlaxis);
break;
case Joystick::INPUT_TYPE_BUTTON:
if (Joystick::getConstant(gpinput.button, sdlbutton))
gpinputname = SDL_GameControllerGetStringForButton(sdlbutton);
break;
default:
break;
}
if (!gpinputname)
throw love::Exception("Invalid gamepad axis/button.");
return std::string(gpinputname);
}
Joystick::JoystickInput JoystickModule::JoystickInputFromString(const std::string &str) const
{
Joystick::JoystickInput jinput;
jinput.type = Joystick::INPUT_TYPE_MAX_ENUM;
// Return an invalid value rather than throwing an exception.
if (str.length() < 2)
return jinput;
// The input type will always be the first character in the string.
char inputtype = str[0];
std::string bindvalues = str.substr(1);
Uint8 sdlhat;
switch (inputtype)
{
case 'a':
jinput.type = Joystick::INPUT_TYPE_AXIS;
jinput.axis = atoi(bindvalues.c_str());
break;
case 'b':
jinput.type = Joystick::INPUT_TYPE_BUTTON;
jinput.button = atoi(bindvalues.c_str());
break;
case 'h':
// Hat string syntax is "index.value".
if (bindvalues.length() < 3)
break;
jinput.type = Joystick::INPUT_TYPE_HAT;
jinput.hat.index = atoi(bindvalues.substr(0, 1).c_str());
sdlhat = (Uint8) atoi(bindvalues.substr(2, 1).c_str());
if (!Joystick::getConstant(sdlhat, jinput.hat.value))
{
// Return an invalid value if we can't find the hat constant.
jinput.type = Joystick::INPUT_TYPE_MAX_ENUM;
return jinput;
}
break;
default:
break;
}
return jinput;
}
void JoystickModule::removeBindFromMapString(std::string &mapstr, const std::string &joybindstr) const
{
// Find the joystick part of the bind in the string.
size_t joybindpos = mapstr.find(joybindstr + ",");
if (joybindpos == std::string::npos)
{
joybindpos = mapstr.rfind(joybindstr);
if (joybindpos != mapstr.length() - joybindstr.length())
return;
}
if (joybindpos == std::string::npos)
return;
// Find the start of the entire bind.
size_t bindstart = mapstr.rfind(',', joybindpos);
if (bindstart != std::string::npos && bindstart < mapstr.length() - 1)
{
size_t bindend = mapstr.find(',', bindstart + 1);
if (bindend == std::string::npos)
bindend = mapstr.length() - 1;
// Replace it with an empty string (remove it.)
mapstr.replace(bindstart, bindend - bindstart + 1, "");
}
}
void JoystickModule::checkGamepads(const std::string &guid) const
{
// FIXME: massive hack until missing APIs are added to SDL 2:
// https://bugzilla.libsdl.org/show_bug.cgi?id=1975
// Make sure all connected joysticks of a certain guid that are
// gamepad-capable are opened as such.
for (int d_index = 0; d_index < SDL_NumJoysticks(); d_index++)
{
if (!SDL_IsGameController(d_index))
continue;
if (guid.compare(getDeviceGUID(d_index)) != 0)
continue;
std::vector<love::joystick::Joystick *>::const_iterator it;
for (it = activeSticks.begin(); it != activeSticks.end(); ++it)
{
if ((*it)->isGamepad() || guid.compare((*it)->getGUID()) != 0)
continue;
// Big hack time: open the index as a game controller and compare
// the underlying joystick handle to the active stick's.
SDL_GameController *ctrl = SDL_GameControllerOpen(d_index);
if (ctrl == NULL)
continue;
SDL_Joystick *stick = SDL_GameControllerGetJoystick(ctrl);
if (stick == (SDL_Joystick *) (*it)->getHandle())
(*it)->openGamepad(d_index);
SDL_GameControllerClose(ctrl);
}
}
}
std::string JoystickModule::getDeviceGUID(int deviceindex) const
{
if (deviceindex < 0 || deviceindex >= SDL_NumJoysticks())
return std::string("");
// SDL_JoystickGetGUIDString uses 32 bytes plus the null terminator.
char guidstr[33] = {'\0'};
// SDL2's GUIDs identify *classes* of devices, instead of unique devices.
SDL_JoystickGUID guid = SDL_JoystickGetDeviceGUID(deviceindex);
SDL_JoystickGetGUIDString(guid, guidstr, sizeof(guidstr));
return std::string(guidstr);
}
} // sdl
} // joystick
} // love
+81
View File
@@ -0,0 +1,81 @@
/**
* Copyright (c) 2006-2013 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_JOYSTICK_SDL_JOYSTICK_MODULE_H
#define LOVE_JOYSTICK_SDL_JOYSTICK_MODULE_H
// LOVE
#include "joystick/JoystickModule.h"
// STL
#include <string>
#include <map>
namespace love
{
namespace joystick
{
namespace sdl
{
class JoystickModule : public love::joystick::JoystickModule
{
public:
JoystickModule();
virtual ~JoystickModule();
// Implements Module.
const char *getName() const;
// Implements JoystickModule.
love::joystick::Joystick *addJoystick(int deviceindex);
void removeJoystick(love::joystick::Joystick *joystick);
love::joystick::Joystick *getJoystickFromID(int instanceid);
love::joystick::Joystick *getJoystick(int joyindex);
int getIndex(const love::joystick::Joystick *joystick);
int getJoystickCount() const;
bool isGamepad(int joyindex) const;
bool setGamepadMapping(const std::string &guid, Joystick::GamepadInput gpinput, Joystick::JoystickInput joyinput);
Joystick::JoystickInput getGamepadMapping(const std::string &guid, Joystick::GamepadInput gpinput);
private:
std::string stringFromGamepadInput(Joystick::GamepadInput gpinput) const;
Joystick::JoystickInput JoystickInputFromString(const std::string &str) const;
void removeBindFromMapString(std::string &mapstr, const std::string &joybindstr) const;
void checkGamepads(const std::string &guid) const;
// SDL2's GUIDs identify *classes* of devices, instead of unique devices.
std::string getDeviceGUID(int deviceindex) const;
// Lists of currently connected Joysticks.
std::vector<Joystick *> activeSticks;
// Persistent list of all Joysticks which have been connected at some point.
std::vector<Joystick *> joysticks;
}; // JoystickModule
} // sdl
} // joystick
} // love
#endif // LOVE_JOYSTICK_SDL_JOYSTICK_MODULE_H
+132 -90
View File
@@ -18,7 +18,11 @@
* 3. This notice may not be removed or altered from any source distribution.
**/
// LOVE
#include "wrap_Joystick.h"
#include "wrap_JoystickModule.h"
#include <vector>
namespace love
{
@@ -27,141 +31,179 @@ namespace joystick
namespace sdl
{
static Joystick *instance = 0;
int w_reload(lua_State *L)
Joystick *luax_checkjoystick(lua_State *L, int idx)
{
try
{
instance->reload();
}
catch(love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
return 0;
return luax_checktype<Joystick>(L, idx, "Joystick", JOYSTICK_JOYSTICK_T);
}
int w_getJoystickCount(lua_State *L)
int w_Joystick_isConnected(lua_State *L)
{
lua_pushinteger(L, instance->getJoystickCount());
Joystick *j = luax_checkjoystick(L, 1);
luax_pushboolean(L, j->isConnected());
return 1;
}
int w_getName(lua_State *L)
int w_Joystick_getName(lua_State *L)
{
int index = luaL_checkint(L, 1) - 1;
lua_pushstring(L, instance->getName(index));
Joystick *j = luax_checkjoystick(L, 1);
lua_pushstring(L, j->getName());
return 1;
}
int w_getAxisCount(lua_State *L)
int w_Joystick_getID(lua_State *L)
{
int index = luaL_checkint(L, 1) - 1;
lua_pushinteger(L, instance->getAxisCount(index));
Joystick *j = luax_checkjoystick(L, 1);
lua_pushinteger(L, j->getID());
return 1;
}
int w_getButtonCount(lua_State *L)
int w_Joystick_getGUID(lua_State *L)
{
int index = luaL_checkint(L, 1) - 1;
lua_pushinteger(L, instance->getButtonCount(index));
Joystick *j = luax_checkjoystick(L, 1);
luax_pushstring(L, j->getGUID());
return 1;
}
int w_getHatCount(lua_State *L)
int w_Joystick_getAxisCount(lua_State *L)
{
int index = luaL_checkint(L, 1) - 1;
lua_pushinteger(L, instance->getHatCount(index));
Joystick *j = luax_checkjoystick(L, 1);
lua_pushinteger(L, j->getAxisCount());
return 1;
}
int w_getAxis(lua_State *L)
int w_Joystick_getButtonCount(lua_State *L)
{
int index = luaL_checkint(L, 1) - 1;
int axis = luaL_checkint(L, 2) - 1;
lua_pushnumber(L, instance->getAxis(index, axis));
Joystick *j = luax_checkjoystick(L, 1);
lua_pushinteger(L, j->getButtonCount());
return 1;
}
int w_getAxes(lua_State *L)
int w_Joystick_getHatCount(lua_State *L)
{
return instance->getAxes(L);
}
int w_isDown(lua_State *L)
{
int index = luaL_checkint(L, 1) - 1;
int num = lua_gettop(L);
int *buttonlist = new int[num];
int counter = 0;
for (int i = 1; i < num; i++)
buttonlist[counter++] = luaL_checkint(L, i + 1) - 1;
buttonlist[counter] = -1;
luax_pushboolean(L, instance->isDown(index, buttonlist));
delete[] buttonlist;
Joystick *j = luax_checkjoystick(L, 1);
lua_pushinteger(L, j->getHatCount());
return 1;
}
int w_getHat(lua_State *L)
int w_Joystick_getAxis(lua_State *L)
{
int index = luaL_checkint(L, 1)-1;
int hat = luaL_checkint(L, 2)-1;
Joystick *j = luax_checkjoystick(L, 1);
int axisindex = luaL_checkint(L, 2) - 1;
lua_pushnumber(L, j->getAxis(axisindex));
return 1;
}
Joystick::Hat h = instance->getHat(index, hat);
int w_Joystick_getAxes(lua_State *L)
{
Joystick *j = luax_checkjoystick(L, 1);
std::vector<float> axes = j->getAxes();
for (size_t i = 0; i < axes.size(); i++)
lua_pushnumber(L, axes[i]);
return (int) axes.size();
}
int w_Joystick_getHat(lua_State *L)
{
Joystick *j = luax_checkjoystick(L, 1);
int hatindex = luaL_checkint(L, 2) - 1;
Joystick::Hat h = j->getHat(hatindex);
const char *direction = "";
Joystick::getConstant(h, direction);
lua_pushstring(L, direction);
love::joystick::Joystick::getConstant(h, direction);
lua_pushstring(L, direction);
return 1;
}
int w_Joystick_isDown(lua_State *L)
{
Joystick *j = luax_checkjoystick(L, 1);
luaL_checkinteger(L, 2);
std::vector<int> buttons;
for (int i = 2; i <= lua_gettop(L); i++)
buttons.push_back(luaL_checkint(L, i));
luax_pushboolean(L, j->isDown(buttons));
return 1;
}
int w_Joystick_isGamepad(lua_State *L)
{
Joystick *j = luax_checkjoystick(L, 1);
luax_pushboolean(L, j->isGamepad());
return 1;
}
int w_Joystick_getGamepadAxis(lua_State *L)
{
Joystick *j = luax_checkjoystick(L, 1);
const char *str = luaL_checkstring(L, 2);
Joystick::GamepadAxis axis;
if (!joystick::Joystick::getConstant(str, axis))
return luaL_error(L, "Invalid gamepad axis: %s", str);
lua_pushnumber(L, j->getGamepadAxis(axis));
return 1;
}
int w_Joystick_isGamepadDown(lua_State *L)
{
Joystick *j = luax_checkjoystick(L, 1);
std::vector<Joystick::GamepadButton> buttons;
buttons.reserve(lua_gettop(L) - 1);
luaL_checkstring(L, 2);
for (int i = 2; i <= lua_gettop(L); i++)
{
const char *str = luaL_checkstring(L, i);
Joystick::GamepadButton button;
if (!joystick::Joystick::getConstant(str, button))
return luaL_error(L, "Invalid gamepad button: %s", str);
buttons.push_back(button);
}
luax_pushboolean(L, j->isGamepadDown(buttons));
return 1;
}
// List of functions to wrap.
static const luaL_Reg functions[] =
{
{ "reload", w_reload },
{ "getJoystickCount", w_getJoystickCount },
{ "getName", w_getName },
{ "getAxisCount", w_getAxisCount },
{ "getButtonCount", w_getButtonCount },
{ "getHatCount", w_getHatCount },
{ "getAxis", w_getAxis },
{ "getAxes", w_getAxes },
{ "isDown", w_isDown },
{ "getHat", w_getHat },
{ 0, 0 }
{ "isConnected", w_Joystick_isConnected },
{ "getName", w_Joystick_getName },
{ "getID", w_Joystick_getID },
{ "getGUID", w_Joystick_getGUID },
{ "getAxisCount", w_Joystick_getAxisCount },
{ "getButtonCount", w_Joystick_getButtonCount },
{ "getHatCount", w_Joystick_getHatCount },
{ "getAxis", w_Joystick_getAxis },
{ "getAxes", w_Joystick_getAxes },
{ "getHat", w_Joystick_getHat },
{ "isDown", w_Joystick_isDown },
{ "isGamepad", w_Joystick_isGamepad },
{ "getGamepadAxis", w_Joystick_getGamepadAxis },
{ "isGamepadDown", w_Joystick_isGamepadDown },
// From wrap_JoystickModule.
{ "getIndex", w_getIndex },
{ "getGamepadMapping", w_getGamepadMapping },
{ 0, 0 },
};
extern "C" int luaopen_love_joystick(lua_State *L)
extern "C" int luaopen_joystick(lua_State *L)
{
if (instance == 0)
{
try
{
instance = new Joystick();
}
catch(Exception &e)
{
return luaL_error(L, e.what());
}
}
else
instance->retain();
WrappedModule w;
w.module = instance;
w.name = "joystick";
w.flags = MODULE_T;
w.functions = functions;
w.types = 0;
return luax_register_module(L, w);
return luax_register_type(L, "Joystick", functions);
}
} // sdl
+17 -11
View File
@@ -24,6 +24,7 @@
// LOVE
#include "common/config.h"
#include "Joystick.h"
#include "common/runtime.h"
namespace love
{
@@ -32,17 +33,22 @@ namespace joystick
namespace sdl
{
int w_reload(lua_State *L);
int w_getJoystickCount(lua_State *L);
int w_getName(lua_State *L);
int w_getAxisCount(lua_State *L);
int w_getButtonCount(lua_State *L);
int w_getHatCount(lua_State *L);
int w_getAxis(lua_State *L);
int w_getAxes(lua_State *L);
int w_isDown(lua_State *L);
int w_getHat(lua_State *L);
extern "C" LOVE_EXPORT int luaopen_love_joystick(lua_State *L);
Joystick *luax_checkjoystick(lua_State *L, int idx);
int w_Joystick_isConnected(lua_State *L);
int w_Joystick_getName(lua_State *L);
int w_Joystick_getID(lua_State *L);
int w_Joystick_getGUID(lua_State *L);
int w_Joystick_getAxisCount(lua_State *L);
int w_Joystick_getButtonCount(lua_State *L);
int w_Joystick_getHatCount(lua_State *L);
int w_Joystick_getAxis(lua_State *L);
int w_Joystick_getAxes(lua_State *L);
int w_Joystick_getHat(lua_State *L);
int w_Joystick_isDown(lua_State *L);
int w_Joystick_isGamepad(lua_State *L);
int w_Joystick_getGamepadAxis(lua_State *L);
int w_Joystick_isGamepadDown(lua_State *L);
extern "C" int luaopen_joystick(lua_State *L);
} // sdl
} // joystick
@@ -0,0 +1,244 @@
/**
* Copyright (c) 2006-2013 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "wrap_JoystickModule.h"
#include "wrap_Joystick.h"
namespace love
{
namespace joystick
{
namespace sdl
{
static JoystickModule *instance = 0;
int w_getJoystick(lua_State *L)
{
int index = luaL_checkint(L, 1) - 1;
love::joystick::Joystick *stick = instance->getJoystick(index);
if (!stick)
return luaL_error(L, "Invalid joystick index");
stick->retain();
luax_newtype(L, "Joystick", JOYSTICK_JOYSTICK_T, (void *) stick);
return 1;
}
int w_getIndex(lua_State *L)
{
love::joystick::Joystick *j = luax_checkjoystick(L, 1);
int index = instance->getIndex(j);
if (index >= 0)
lua_pushinteger(L, index + 1);
else
lua_pushinteger(L, -1);
return 1;
}
int w_getJoystickCount(lua_State *L)
{
lua_pushinteger(L, instance->getJoystickCount());
return 1;
}
int w_isGamepad(lua_State *L)
{
int index = luaL_checkint(L, 1) - 1;
luax_pushboolean(L, instance->isGamepad(index));
return 1;
}
int w_setGamepadMapping(lua_State *L)
{
// Only accept a GUID string. We don't accept a Joystick object because
// the gamepad mapping applies to all joysticks with the same GUID (e.g. all
// Xbox 360 controllers on the system), rather than individual objects.
std::string guid = luax_checkstring(L, 1);
const char *gpbindstr = luaL_checkstring(L, 2);
Joystick::GamepadInput gpinput;
if (love::joystick::Joystick::getConstant(gpbindstr, gpinput.axis))
gpinput.type = Joystick::INPUT_TYPE_AXIS;
else if (love::joystick::Joystick::getConstant(gpbindstr, gpinput.button))
gpinput.type = Joystick::INPUT_TYPE_BUTTON;
else
return luaL_error(L, "Invalid gamepad axis/button: %s", gpbindstr);
const char *jinputtypestr = luaL_checkstring(L, 3);
Joystick::JoystickInput jinput;
if (!love::joystick::Joystick::getConstant(jinputtypestr, jinput.type))
return luaL_error(L, "Invalid joystick input type: %s", jinputtypestr);
const char *hatstr;
switch (jinput.type)
{
case Joystick::INPUT_TYPE_AXIS:
jinput.axis = luaL_checkint(L, 4) - 1;
break;
case Joystick::INPUT_TYPE_BUTTON:
jinput.button = luaL_checkint(L, 4) - 1;
break;
case Joystick::INPUT_TYPE_HAT:
// Hats need both a hat index and a hat value.
jinput.hat.index = luaL_checkint(L, 4) - 1;
hatstr = luaL_checkstring(L, 5);
if (!love::joystick::Joystick::getConstant(hatstr, jinput.hat.value))
return luaL_error(L, "Invalid joystick hat: %s", hatstr);
break;
default:
return luaL_error(L, "Invalid joystick input type: %s", jinputtypestr);
}
bool success = false;
try
{
success = instance->setGamepadMapping(guid, gpinput, jinput);
}
catch (love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
luax_pushboolean(L, success);
return 1;
}
int w_getGamepadMapping(lua_State *L)
{
std::string guid;
// Accept either a GUID string or a Joystick object. This way we can re-use
// the function for Joystick:getGamepadMapping.
if (lua_type(L, 1) == LUA_TSTRING)
guid = luax_checkstring(L, 1);
else
{
love::joystick::Joystick *stick = luax_checkjoystick(L, 1);
guid = stick->getGUID();
}
const char *gpbindstr = luaL_checkstring(L, 2);
Joystick::GamepadInput gpinput;
if (love::joystick::Joystick::getConstant(gpbindstr, gpinput.axis))
gpinput.type = Joystick::INPUT_TYPE_AXIS;
else if (love::joystick::Joystick::getConstant(gpbindstr, gpinput.button))
gpinput.type = Joystick::INPUT_TYPE_BUTTON;
else
return luaL_error(L, "Invalid gamepad axis/button: %s", gpbindstr);
Joystick::JoystickInput jinput;
jinput.type = Joystick::INPUT_TYPE_MAX_ENUM;
try
{
jinput = instance->getGamepadMapping(guid, gpinput);
}
catch (love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
if (jinput.type == Joystick::INPUT_TYPE_MAX_ENUM)
return 0;
const char *inputtypestr;
if (!love::joystick::Joystick::getConstant(jinput.type, inputtypestr))
return luaL_error(L, "Unknown joystick input type.");
lua_pushstring(L, inputtypestr);
const char *hatstr;
switch (jinput.type)
{
case Joystick::INPUT_TYPE_AXIS:
lua_pushinteger(L, jinput.axis + 1);
return 2;
case Joystick::INPUT_TYPE_BUTTON:
lua_pushinteger(L, jinput.button + 1);
return 2;
case Joystick::INPUT_TYPE_HAT:
lua_pushinteger(L, jinput.hat.index + 1);
if (love::joystick::Joystick::getConstant(jinput.hat.value, hatstr))
{
lua_pushstring(L, hatstr);
return 3;
}
else
return luaL_error(L, "Unknown joystick hat.");
default:
break; // ?
}
return 1;
}
// List of functions to wrap.
static const luaL_Reg functions[] =
{
{ "getJoystick", w_getJoystick },
{ "getIndex", w_getIndex },
{ "getJoystickCount", w_getJoystickCount },
{ "isGamepad", w_isGamepad },
{ "setGamepadMapping", w_setGamepadMapping },
{ "getGamepadMapping", w_getGamepadMapping },
{ 0, 0 }
};
static const lua_CFunction types[] =
{
luaopen_joystick,
0,
};
extern "C" int luaopen_love_joystick(lua_State *L)
{
if (instance == 0)
{
try
{
instance = new JoystickModule();
}
catch (Exception &e)
{
return luaL_error(L, e.what());
}
}
else
instance->retain();
WrappedModule w;
w.module = instance;
w.name = "joystick";
w.flags = MODULE_T;
w.functions = functions;
w.types = types;
return luax_register_module(L, w);
}
} // sdl
} // joystick
} // love
@@ -0,0 +1,47 @@
/**
* Copyright (c) 2006-2013 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_JOYSTICK_SDL_WRAP_JOYSTICK_MODULE_H
#define LOVE_JOYSTICK_SDL_WRAP_JOYSTICK_MODULE_H
// LOVE
#include "common/config.h"
#include "JoystickModule.h"
namespace love
{
namespace joystick
{
namespace sdl
{
int w_getJoystick(lua_State *L);
int w_getIndex(lua_State *L);
int w_getJoystickCount(lua_State *L);
int w_isGamepad(lua_State *L);
int w_setGamepadMapping(lua_State *L);
int w_getGamepadMapping(lua_State *L);
extern "C" LOVE_EXPORT int luaopen_love_joystick(lua_State *L);
} // sdl
} // joystick
} // love
#endif // LOVE_JOYSTICK_SDL_WRAP_JOYSTICK_MODULE_H
+103 -54
View File
@@ -39,12 +39,10 @@ bool Keyboard::getConstant(Keyboard::Key in, const char *&out)
StringMap<Keyboard::Key, Keyboard::KEY_MAX_ENUM>::Entry Keyboard::keyEntries[] =
{
{"return", Keyboard::KEY_RETURN},
{"escape", Keyboard::KEY_ESCAPE},
{"backspace", Keyboard::KEY_BACKSPACE},
{"tab", Keyboard::KEY_TAB},
{"clear", Keyboard::KEY_CLEAR},
{"return", Keyboard::KEY_RETURN},
{"pause", Keyboard::KEY_PAUSE},
{"escape", Keyboard::KEY_ESCAPE},
{" ", Keyboard::KEY_SPACE},
{"!", Keyboard::KEY_EXCLAIM},
{"\"", Keyboard::KEY_QUOTEDBL},
@@ -110,35 +108,8 @@ StringMap<Keyboard::Key, Keyboard::KEY_MAX_ENUM>::Entry Keyboard::keyEntries[] =
{"x", Keyboard::KEY_X},
{"y", Keyboard::KEY_Y},
{"z", Keyboard::KEY_Z},
{"delete", Keyboard::KEY_DELETE},
{"kp0", Keyboard::KEY_KP0},
{"kp1", Keyboard::KEY_KP1},
{"kp2", Keyboard::KEY_KP2},
{"kp3", Keyboard::KEY_KP3},
{"kp4", Keyboard::KEY_KP4},
{"kp5", Keyboard::KEY_KP5},
{"kp6", Keyboard::KEY_KP6},
{"kp7", Keyboard::KEY_KP7},
{"kp8", Keyboard::KEY_KP8},
{"kp9", Keyboard::KEY_KP9},
{"kp.", Keyboard::KEY_KP_PERIOD},
{"kp/", Keyboard::KEY_KP_DIVIDE},
{"kp*", Keyboard::KEY_KP_MULTIPLY},
{"kp-", Keyboard::KEY_KP_MINUS},
{"kp+", Keyboard::KEY_KP_PLUS},
{"kpenter", Keyboard::KEY_KP_ENTER},
{"kp=", Keyboard::KEY_KP_EQUALS},
{"up", Keyboard::KEY_UP},
{"down", Keyboard::KEY_DOWN},
{"right", Keyboard::KEY_RIGHT},
{"left", Keyboard::KEY_LEFT},
{"insert", Keyboard::KEY_INSERT},
{"home", Keyboard::KEY_HOME},
{"end", Keyboard::KEY_END},
{"pageup", Keyboard::KEY_PAGEUP},
{"pagedown", Keyboard::KEY_PAGEDOWN},
{"capslock", Keyboard::KEY_CAPSLOCK},
{"f1", Keyboard::KEY_F1},
{"f2", Keyboard::KEY_F2},
@@ -152,34 +123,112 @@ StringMap<Keyboard::Key, Keyboard::KEY_MAX_ENUM>::Entry Keyboard::keyEntries[] =
{"f10", Keyboard::KEY_F10},
{"f11", Keyboard::KEY_F11},
{"f12", Keyboard::KEY_F12},
{"printscreen", Keyboard::KEY_PRINTSCREEN},
{"scrolllock", Keyboard::KEY_SCROLLLOCK},
{"pause", Keyboard::KEY_PAUSE},
{"insert", Keyboard::KEY_INSERT},
{"home", Keyboard::KEY_HOME},
{"pageup", Keyboard::KEY_PAGEUP},
{"delete", Keyboard::KEY_DELETE},
{"end", Keyboard::KEY_END},
{"pagedown", Keyboard::KEY_PAGEDOWN},
{"right", Keyboard::KEY_RIGHT},
{"left", Keyboard::KEY_LEFT},
{"down", Keyboard::KEY_DOWN},
{"up", Keyboard::KEY_UP},
{"numlock", Keyboard::KEY_NUMLOCKCLEAR},
{"kp/", Keyboard::KEY_KP_DIVIDE},
{"kp*", Keyboard::KEY_KP_MULTIPLY},
{"kp-", Keyboard::KEY_KP_MINUS},
{"kp+", Keyboard::KEY_KP_PLUS},
{"kpenter", Keyboard::KEY_KP_ENTER},
{"kp0", Keyboard::KEY_KP_0},
{"kp1", Keyboard::KEY_KP_1},
{"kp2", Keyboard::KEY_KP_2},
{"kp3", Keyboard::KEY_KP_3},
{"kp4", Keyboard::KEY_KP_4},
{"kp5", Keyboard::KEY_KP_5},
{"kp6", Keyboard::KEY_KP_6},
{"kp7", Keyboard::KEY_KP_7},
{"kp8", Keyboard::KEY_KP_8},
{"kp9", Keyboard::KEY_KP_9},
{"kp.", Keyboard::KEY_KP_PERIOD},
{"kp,", Keyboard::KEY_KP_COMMA},
{"kp=", Keyboard::KEY_KP_EQUALS},
{"application", Keyboard::KEY_APPLICATION},
{"power", Keyboard::KEY_POWER},
{"f13", Keyboard::KEY_F13},
{"f14", Keyboard::KEY_F14},
{"f15", Keyboard::KEY_F15},
{"numlock", Keyboard::KEY_NUMLOCK},
{"capslock", Keyboard::KEY_CAPSLOCK},
{"scrollock", Keyboard::KEY_SCROLLOCK},
{"rshift", Keyboard::KEY_RSHIFT},
{"lshift", Keyboard::KEY_LSHIFT},
{"rctrl", Keyboard::KEY_RCTRL},
{"lctrl", Keyboard::KEY_LCTRL},
{"ralt", Keyboard::KEY_RALT},
{"lalt", Keyboard::KEY_LALT},
{"rmeta", Keyboard::KEY_RMETA},
{"lmeta", Keyboard::KEY_LMETA},
{"lsuper", Keyboard::KEY_LSUPER},
{"rsuper", Keyboard::KEY_RSUPER},
{"mode", Keyboard::KEY_MODE},
{"compose", Keyboard::KEY_COMPOSE},
{"f16", Keyboard::KEY_F16},
{"f17", Keyboard::KEY_F17},
{"f18", Keyboard::KEY_F18},
{"f19", Keyboard::KEY_F19},
{"f20", Keyboard::KEY_F20},
{"f21", Keyboard::KEY_F21},
{"f22", Keyboard::KEY_F22},
{"f23", Keyboard::KEY_F23},
{"f24", Keyboard::KEY_F24},
{"execute", Keyboard::KEY_EXECUTE},
{"help", Keyboard::KEY_HELP},
{"print", Keyboard::KEY_PRINT},
{"sysreq", Keyboard::KEY_SYSREQ},
{"break", Keyboard::KEY_BREAK},
{"menu", Keyboard::KEY_MENU},
{"power", Keyboard::KEY_POWER},
{"euro", Keyboard::KEY_EURO},
{"select", Keyboard::KEY_SELECT},
{"stop", Keyboard::KEY_STOP},
{"again", Keyboard::KEY_AGAIN},
{"undo", Keyboard::KEY_UNDO},
{"cut", Keyboard::KEY_CUT},
{"copy", Keyboard::KEY_COPY},
{"paste", Keyboard::KEY_PASTE},
{"find", Keyboard::KEY_FIND},
{"mute", Keyboard::KEY_MUTE},
{"volumeup", Keyboard::KEY_VOLUMEUP},
{"volumedown", Keyboard::KEY_VOLUMEDOWN},
{"alterase", Keyboard::KEY_ALTERASE},
{"sysreq", Keyboard::KEY_SYSREQ},
{"cancel", Keyboard::KEY_CANCEL},
{"clear", Keyboard::KEY_CLEAR},
{"prior", Keyboard::KEY_PRIOR},
{"return2", Keyboard::KEY_RETURN2},
{"separator", Keyboard::KEY_SEPARATOR},
{"out", Keyboard::KEY_OUT},
{"oper", Keyboard::KEY_OPER},
{"clearagain", Keyboard::KEY_CLEARAGAIN},
{"thsousandsseparator", Keyboard::KEY_THOUSANDSSEPARATOR},
{"decimalseparator", Keyboard::KEY_DECIMALSEPARATOR},
{"currencyunit", Keyboard::KEY_CURRENCYUNIT},
{"currencysubunit", Keyboard::KEY_CURRENCYSUBUNIT},
{"lctrl", Keyboard::KEY_LCTRL},
{"lshift", Keyboard::KEY_LSHIFT},
{"lalt", Keyboard::KEY_LALT},
{"lgui", Keyboard::KEY_LGUI},
{"rctrl", Keyboard::KEY_RCTRL},
{"rshift", Keyboard::KEY_RSHIFT},
{"ralt", Keyboard::KEY_RALT},
{"rgui", Keyboard::KEY_RGUI},
{"mode", Keyboard::KEY_MODE},
{"audionext", Keyboard::KEY_AUDIONEXT},
{"audioprev", Keyboard::KEY_AUDIOPREV},
{"audiostop", Keyboard::KEY_AUDIOSTOP},
{"audioplay", Keyboard::KEY_AUDIOPLAY},
{"audiomute", Keyboard::KEY_AUDIOMUTE},
{"mediaselect", Keyboard::KEY_MEDIASELECT},
{"brightnessdown", Keyboard::KEY_BRIGHTNESSDOWN},
{"brightnessup", Keyboard::KEY_BRIGHTNESSUP},
{"displayswitch", Keyboard::KEY_DISPLAYSWITCH},
{"kbdillumtoggle", Keyboard::KEY_KBDILLUMTOGGLE},
{"kbdillumdown", Keyboard::KEY_KBDILLUMDOWN},
{"kbdillumup", Keyboard::KEY_KBDILLUMUP},
{"eject", Keyboard::KEY_EJECT},
{"sleep", Keyboard::KEY_SLEEP},
};
StringMap<Keyboard::Key, Keyboard::KEY_MAX_ENUM> Keyboard::keys(Keyboard::keyEntries, sizeof(Keyboard::keyEntries));
+106 -75
View File
@@ -37,16 +37,16 @@ public:
enum Key
{
KEY_UNKNOWN,
KEY_RETURN,
KEY_ESCAPE,
KEY_BACKSPACE,
KEY_TAB,
KEY_CLEAR,
KEY_RETURN,
KEY_PAUSE,
KEY_ESCAPE,
KEY_SPACE,
KEY_EXCLAIM,
KEY_QUOTEDBL,
KEY_HASH,
KEY_PERCENT,
KEY_DOLLAR,
KEY_AMPERSAND,
KEY_QUOTE,
@@ -108,35 +108,8 @@ public:
KEY_X,
KEY_Y,
KEY_Z,
KEY_DELETE,
KEY_KP0,
KEY_KP1,
KEY_KP2,
KEY_KP3,
KEY_KP4,
KEY_KP5,
KEY_KP6,
KEY_KP7,
KEY_KP8,
KEY_KP9,
KEY_KP_PERIOD,
KEY_KP_DIVIDE,
KEY_KP_MULTIPLY,
KEY_KP_MINUS,
KEY_KP_PLUS,
KEY_KP_ENTER,
KEY_KP_EQUALS,
KEY_UP,
KEY_DOWN,
KEY_RIGHT,
KEY_LEFT,
KEY_INSERT,
KEY_HOME,
KEY_END,
KEY_PAGEUP,
KEY_PAGEDOWN,
KEY_CAPSLOCK,
KEY_F1,
KEY_F2,
@@ -150,39 +123,116 @@ public:
KEY_F10,
KEY_F11,
KEY_F12,
KEY_PRINTSCREEN,
KEY_SCROLLLOCK,
KEY_PAUSE,
KEY_INSERT,
KEY_HOME,
KEY_PAGEUP,
KEY_DELETE,
KEY_END,
KEY_PAGEDOWN,
KEY_RIGHT,
KEY_LEFT,
KEY_DOWN,
KEY_UP,
KEY_NUMLOCKCLEAR,
KEY_KP_DIVIDE,
KEY_KP_MULTIPLY,
KEY_KP_MINUS,
KEY_KP_PLUS,
KEY_KP_ENTER,
KEY_KP_1,
KEY_KP_2,
KEY_KP_3,
KEY_KP_4,
KEY_KP_5,
KEY_KP_6,
KEY_KP_7,
KEY_KP_8,
KEY_KP_9,
KEY_KP_0,
KEY_KP_PERIOD,
KEY_KP_COMMA,
KEY_KP_EQUALS,
KEY_APPLICATION,
KEY_POWER,
KEY_F13,
KEY_F14,
KEY_F15,
KEY_NUMLOCK,
KEY_CAPSLOCK,
KEY_SCROLLOCK,
KEY_RSHIFT,
KEY_LSHIFT,
KEY_RCTRL,
KEY_LCTRL,
KEY_RALT,
KEY_LALT,
KEY_RMETA,
KEY_LMETA,
KEY_LSUPER,
KEY_RSUPER,
KEY_MODE,
KEY_COMPOSE,
KEY_F16,
KEY_F17,
KEY_F18,
KEY_F19,
KEY_F20,
KEY_F21,
KEY_F22,
KEY_F23,
KEY_F24,
KEY_EXECUTE,
KEY_HELP,
KEY_PRINT,
KEY_SYSREQ,
KEY_BREAK,
KEY_MENU,
KEY_POWER,
KEY_EURO,
KEY_SELECT,
KEY_STOP,
KEY_AGAIN,
KEY_UNDO,
KEY_CUT,
KEY_COPY,
KEY_PASTE,
KEY_FIND,
KEY_MUTE,
KEY_VOLUMEUP,
KEY_VOLUMEDOWN,
KEY_ALTERASE,
KEY_SYSREQ,
KEY_CANCEL,
KEY_CLEAR,
KEY_PRIOR,
KEY_RETURN2,
KEY_SEPARATOR,
KEY_OUT,
KEY_OPER,
KEY_CLEARAGAIN,
KEY_THOUSANDSSEPARATOR,
KEY_DECIMALSEPARATOR,
KEY_CURRENCYUNIT,
KEY_CURRENCYSUBUNIT,
KEY_LCTRL,
KEY_LSHIFT,
KEY_LALT,
KEY_LGUI,
KEY_RCTRL,
KEY_RSHIFT,
KEY_RALT,
KEY_RGUI,
KEY_MODE,
KEY_AUDIONEXT,
KEY_AUDIOPREV,
KEY_AUDIOSTOP,
KEY_AUDIOPLAY,
KEY_AUDIOMUTE,
KEY_MEDIASELECT,
KEY_BRIGHTNESSDOWN,
KEY_BRIGHTNESSUP,
KEY_DISPLAYSWITCH,
KEY_KBDILLUMTOGGLE,
KEY_KBDILLUMDOWN,
KEY_KBDILLUMUP,
KEY_EJECT,
KEY_SLEEP,
KEY_MAX_ENUM = 512
};
static const int DEFAULT = -1;
virtual ~Keyboard() {}
/**
@@ -192,25 +242,6 @@ public:
**/
virtual bool isDown(Key *keylist) const = 0;
/**
* Enables key repeating.
* @param delay The amount of delay before repeating the key (in milliseconds)
* @param interval Specifies the amount of time between repeats (in milliseconds)
**/
virtual void setKeyRepeat(int delay, int interval) const = 0;
/**
* Gets the specified delay for the key repeat.
* @return int
**/
virtual int getKeyRepeatDelay() const = 0;
/**
* Gets the specified interval for the key repeat.
* @return int
**/
virtual int getKeyRepeatInterval() const = 0;
static bool getConstant(const char *in, Key &out);
static bool getConstant(Key in, const char *&out);
+201 -168
View File
@@ -36,187 +36,220 @@ const char *Keyboard::getName() const
bool Keyboard::isDown(Key *keylist) const
{
SDLKey k;
Uint8 *keystate = SDL_GetKeyState(0);
const Uint8 *keystate = SDL_GetKeyboardState(0);
std::map<Key, SDL_Keycode>::const_iterator it;
for (Key key = *keylist; key != KEY_MAX_ENUM; key = *(++keylist))
{
if (keys.find(key, k) && keystate[(unsigned)k] == 1)
it = keys.find(key);
if (it != keys.end() && keystate[SDL_GetScancodeFromKey(it->second)])
return true;
}
return false;
}
void Keyboard::setKeyRepeat(int delay, int interval) const
std::map<Keyboard::Key, SDL_Keycode> Keyboard::createKeyMap()
{
delay = (delay == DEFAULT) ? SDL_DEFAULT_REPEAT_DELAY : delay;
interval = (interval == DEFAULT) ? SDL_DEFAULT_REPEAT_INTERVAL : interval;
std::map<Keyboard::Key, SDL_Keycode> k;
SDL_EnableKeyRepeat(delay, interval);
k[Keyboard::KEY_UNKNOWN] = SDLK_UNKNOWN;
k[Keyboard::KEY_RETURN] = SDLK_RETURN;
k[Keyboard::KEY_ESCAPE] = SDLK_ESCAPE;
k[Keyboard::KEY_BACKSPACE] = SDLK_BACKSPACE;
k[Keyboard::KEY_TAB] = SDLK_TAB;
k[Keyboard::KEY_SPACE] = SDLK_SPACE;
k[Keyboard::KEY_EXCLAIM] = SDLK_EXCLAIM;
k[Keyboard::KEY_QUOTEDBL] = SDLK_QUOTEDBL;
k[Keyboard::KEY_HASH] = SDLK_HASH;
k[Keyboard::KEY_DOLLAR] = SDLK_DOLLAR;
k[Keyboard::KEY_AMPERSAND] = SDLK_AMPERSAND;
k[Keyboard::KEY_QUOTE] = SDLK_QUOTE;
k[Keyboard::KEY_LEFTPAREN] = SDLK_LEFTPAREN;
k[Keyboard::KEY_RIGHTPAREN] = SDLK_RIGHTPAREN;
k[Keyboard::KEY_ASTERISK] = SDLK_ASTERISK;
k[Keyboard::KEY_PLUS] = SDLK_PLUS;
k[Keyboard::KEY_COMMA] = SDLK_COMMA;
k[Keyboard::KEY_MINUS] = SDLK_MINUS;
k[Keyboard::KEY_PERIOD] = SDLK_PERIOD;
k[Keyboard::KEY_SLASH] = SDLK_SLASH;
k[Keyboard::KEY_0] = SDLK_0;
k[Keyboard::KEY_1] = SDLK_1;
k[Keyboard::KEY_2] = SDLK_2;
k[Keyboard::KEY_3] = SDLK_3;
k[Keyboard::KEY_4] = SDLK_4;
k[Keyboard::KEY_5] = SDLK_5;
k[Keyboard::KEY_6] = SDLK_6;
k[Keyboard::KEY_7] = SDLK_7;
k[Keyboard::KEY_8] = SDLK_8;
k[Keyboard::KEY_9] = SDLK_9;
k[Keyboard::KEY_COLON] = SDLK_COLON;
k[Keyboard::KEY_SEMICOLON] = SDLK_SEMICOLON;
k[Keyboard::KEY_LESS] = SDLK_LESS;
k[Keyboard::KEY_EQUALS] = SDLK_EQUALS;
k[Keyboard::KEY_GREATER] = SDLK_GREATER;
k[Keyboard::KEY_QUESTION] = SDLK_QUESTION;
k[Keyboard::KEY_AT] = SDLK_AT;
k[Keyboard::KEY_LEFTBRACKET] = SDLK_LEFTBRACKET;
k[Keyboard::KEY_BACKSLASH] = SDLK_BACKSLASH;
k[Keyboard::KEY_RIGHTBRACKET] = SDLK_RIGHTBRACKET;
k[Keyboard::KEY_CARET] = SDLK_CARET;
k[Keyboard::KEY_UNDERSCORE] = SDLK_UNDERSCORE;
k[Keyboard::KEY_BACKQUOTE] = SDLK_BACKQUOTE;
k[Keyboard::KEY_A] = SDLK_a;
k[Keyboard::KEY_B] = SDLK_b;
k[Keyboard::KEY_C] = SDLK_c;
k[Keyboard::KEY_D] = SDLK_d;
k[Keyboard::KEY_E] = SDLK_e;
k[Keyboard::KEY_F] = SDLK_f;
k[Keyboard::KEY_G] = SDLK_g;
k[Keyboard::KEY_H] = SDLK_h;
k[Keyboard::KEY_I] = SDLK_i;
k[Keyboard::KEY_J] = SDLK_j;
k[Keyboard::KEY_K] = SDLK_k;
k[Keyboard::KEY_L] = SDLK_l;
k[Keyboard::KEY_M] = SDLK_m;
k[Keyboard::KEY_N] = SDLK_n;
k[Keyboard::KEY_O] = SDLK_o;
k[Keyboard::KEY_P] = SDLK_p;
k[Keyboard::KEY_Q] = SDLK_q;
k[Keyboard::KEY_R] = SDLK_r;
k[Keyboard::KEY_S] = SDLK_s;
k[Keyboard::KEY_T] = SDLK_t;
k[Keyboard::KEY_U] = SDLK_u;
k[Keyboard::KEY_V] = SDLK_v;
k[Keyboard::KEY_W] = SDLK_w;
k[Keyboard::KEY_X] = SDLK_x;
k[Keyboard::KEY_Y] = SDLK_y;
k[Keyboard::KEY_Z] = SDLK_z;
k[Keyboard::KEY_CAPSLOCK] = SDLK_CAPSLOCK;
k[Keyboard::KEY_F1] = SDLK_F1;
k[Keyboard::KEY_F2] = SDLK_F2;
k[Keyboard::KEY_F3] = SDLK_F3;
k[Keyboard::KEY_F4] = SDLK_F4;
k[Keyboard::KEY_F5] = SDLK_F5;
k[Keyboard::KEY_F6] = SDLK_F6;
k[Keyboard::KEY_F7] = SDLK_F7;
k[Keyboard::KEY_F8] = SDLK_F8;
k[Keyboard::KEY_F9] = SDLK_F9;
k[Keyboard::KEY_F10] = SDLK_F10;
k[Keyboard::KEY_F11] = SDLK_F11;
k[Keyboard::KEY_F12] = SDLK_F12;
k[Keyboard::KEY_PRINTSCREEN] = SDLK_PRINTSCREEN;
k[Keyboard::KEY_SCROLLLOCK] = SDLK_SCROLLLOCK;
k[Keyboard::KEY_PAUSE] = SDLK_PAUSE;
k[Keyboard::KEY_INSERT] = SDLK_INSERT;
k[Keyboard::KEY_HOME] = SDLK_HOME;
k[Keyboard::KEY_PAGEUP] = SDLK_PAGEUP;
k[Keyboard::KEY_DELETE] = SDLK_DELETE;
k[Keyboard::KEY_END] = SDLK_END;
k[Keyboard::KEY_PAGEDOWN] = SDLK_PAGEDOWN;
k[Keyboard::KEY_RIGHT] = SDLK_RIGHT;
k[Keyboard::KEY_LEFT] = SDLK_LEFT;
k[Keyboard::KEY_DOWN] = SDLK_DOWN;
k[Keyboard::KEY_UP] = SDLK_UP;
k[Keyboard::KEY_NUMLOCKCLEAR] = SDLK_NUMLOCKCLEAR;
k[Keyboard::KEY_KP_DIVIDE] = SDLK_KP_DIVIDE;
k[Keyboard::KEY_KP_MULTIPLY] = SDLK_KP_MULTIPLY;
k[Keyboard::KEY_KP_MINUS] = SDLK_KP_MINUS;
k[Keyboard::KEY_KP_PLUS] = SDLK_KP_PLUS;
k[Keyboard::KEY_KP_ENTER] = SDLK_KP_ENTER;
k[Keyboard::KEY_KP_0] = SDLK_KP_0;
k[Keyboard::KEY_KP_1] = SDLK_KP_1;
k[Keyboard::KEY_KP_2] = SDLK_KP_2;
k[Keyboard::KEY_KP_3] = SDLK_KP_3;
k[Keyboard::KEY_KP_4] = SDLK_KP_4;
k[Keyboard::KEY_KP_5] = SDLK_KP_5;
k[Keyboard::KEY_KP_6] = SDLK_KP_6;
k[Keyboard::KEY_KP_7] = SDLK_KP_7;
k[Keyboard::KEY_KP_8] = SDLK_KP_8;
k[Keyboard::KEY_KP_9] = SDLK_KP_9;
k[Keyboard::KEY_KP_PERIOD] = SDLK_KP_PERIOD;
k[Keyboard::KEY_KP_COMMA] = SDLK_KP_COMMA;
k[Keyboard::KEY_KP_EQUALS] = SDLK_KP_EQUALS;
k[Keyboard::KEY_APPLICATION] = SDLK_APPLICATION;
k[Keyboard::KEY_POWER] = SDLK_POWER;
k[Keyboard::KEY_F13] = SDLK_F13;
k[Keyboard::KEY_F14] = SDLK_F14;
k[Keyboard::KEY_F15] = SDLK_F15;
k[Keyboard::KEY_F16] = SDLK_F16;
k[Keyboard::KEY_F17] = SDLK_F17;
k[Keyboard::KEY_F18] = SDLK_F18;
k[Keyboard::KEY_F19] = SDLK_F19;
k[Keyboard::KEY_F20] = SDLK_F20;
k[Keyboard::KEY_F21] = SDLK_F21;
k[Keyboard::KEY_F22] = SDLK_F22;
k[Keyboard::KEY_F23] = SDLK_F23;
k[Keyboard::KEY_F24] = SDLK_F24;
k[Keyboard::KEY_EXECUTE] = SDLK_EXECUTE;
k[Keyboard::KEY_HELP] = SDLK_HELP;
k[Keyboard::KEY_MENU] = SDLK_MENU;
k[Keyboard::KEY_SELECT] = SDLK_SELECT;
k[Keyboard::KEY_STOP] = SDLK_STOP;
k[Keyboard::KEY_AGAIN] = SDLK_AGAIN;
k[Keyboard::KEY_UNDO] = SDLK_UNDO;
k[Keyboard::KEY_CUT] = SDLK_CUT;
k[Keyboard::KEY_COPY] = SDLK_COPY;
k[Keyboard::KEY_PASTE] = SDLK_PASTE;
k[Keyboard::KEY_FIND] = SDLK_FIND;
k[Keyboard::KEY_MUTE] = SDLK_MUTE;
k[Keyboard::KEY_VOLUMEUP] = SDLK_VOLUMEUP;
k[Keyboard::KEY_VOLUMEDOWN] = SDLK_VOLUMEDOWN;
k[Keyboard::KEY_ALTERASE] = SDLK_ALTERASE;
k[Keyboard::KEY_SYSREQ] = SDLK_SYSREQ;
k[Keyboard::KEY_CANCEL] = SDLK_CANCEL;
k[Keyboard::KEY_CLEAR] = SDLK_CLEAR;
k[Keyboard::KEY_PRIOR] = SDLK_PRIOR;
k[Keyboard::KEY_RETURN2] = SDLK_RETURN2;
k[Keyboard::KEY_SEPARATOR] = SDLK_SEPARATOR;
k[Keyboard::KEY_OUT] = SDLK_OUT;
k[Keyboard::KEY_OPER] = SDLK_OPER;
k[Keyboard::KEY_CLEARAGAIN] = SDLK_CLEARAGAIN;
k[Keyboard::KEY_THOUSANDSSEPARATOR] = SDLK_THOUSANDSSEPARATOR;
k[Keyboard::KEY_DECIMALSEPARATOR] = SDLK_DECIMALSEPARATOR;
k[Keyboard::KEY_CURRENCYUNIT] = SDLK_CURRENCYUNIT;
k[Keyboard::KEY_CURRENCYSUBUNIT] = SDLK_CURRENCYSUBUNIT;
k[Keyboard::KEY_LCTRL] = SDLK_LCTRL;
k[Keyboard::KEY_LSHIFT] = SDLK_LSHIFT;
k[Keyboard::KEY_LALT] = SDLK_LALT;
k[Keyboard::KEY_LGUI] = SDLK_LGUI;
k[Keyboard::KEY_RCTRL] = SDLK_RCTRL;
k[Keyboard::KEY_RSHIFT] = SDLK_RSHIFT;
k[Keyboard::KEY_RALT] = SDLK_RALT;
k[Keyboard::KEY_RGUI] = SDLK_RGUI;
k[Keyboard::KEY_MODE] = SDLK_MODE;
k[Keyboard::KEY_AUDIONEXT] = SDLK_AUDIONEXT;
k[Keyboard::KEY_AUDIOPREV] = SDLK_AUDIOPREV;
k[Keyboard::KEY_AUDIOSTOP] = SDLK_AUDIOSTOP;
k[Keyboard::KEY_AUDIOPLAY] = SDLK_AUDIOPLAY;
k[Keyboard::KEY_AUDIOMUTE] = SDLK_AUDIOMUTE;
k[Keyboard::KEY_MEDIASELECT] = SDLK_MEDIASELECT;
k[Keyboard::KEY_BRIGHTNESSDOWN] = SDLK_BRIGHTNESSDOWN;
k[Keyboard::KEY_BRIGHTNESSUP] = SDLK_BRIGHTNESSUP;
k[Keyboard::KEY_DISPLAYSWITCH] = SDLK_DISPLAYSWITCH;
k[Keyboard::KEY_KBDILLUMTOGGLE] = SDLK_KBDILLUMTOGGLE;
k[Keyboard::KEY_KBDILLUMDOWN] = SDLK_KBDILLUMDOWN;
k[Keyboard::KEY_KBDILLUMUP] = SDLK_KBDILLUMUP;
k[Keyboard::KEY_EJECT] = SDLK_EJECT;
k[Keyboard::KEY_SLEEP] = SDLK_SLEEP;
return k;
}
int Keyboard::getKeyRepeatDelay() const
{
int delay, interval;
SDL_GetKeyRepeat(&delay, &interval);
return delay;
}
int Keyboard::getKeyRepeatInterval() const
{
int delay, interval;
SDL_GetKeyRepeat(&delay, &interval);
return interval;
}
EnumMap<Keyboard::Key, SDLKey, Keyboard::KEY_MAX_ENUM>::Entry Keyboard::keyEntries[] =
{
{ Keyboard::KEY_BACKSPACE, SDLK_BACKSPACE},
{ Keyboard::KEY_TAB, SDLK_TAB},
{ Keyboard::KEY_CLEAR, SDLK_CLEAR},
{ Keyboard::KEY_RETURN, SDLK_RETURN},
{ Keyboard::KEY_PAUSE, SDLK_PAUSE},
{ Keyboard::KEY_ESCAPE, SDLK_ESCAPE },
{ Keyboard::KEY_SPACE, SDLK_SPACE },
{ Keyboard::KEY_EXCLAIM, SDLK_EXCLAIM },
{ Keyboard::KEY_QUOTEDBL, SDLK_QUOTEDBL },
{ Keyboard::KEY_HASH, SDLK_HASH },
{ Keyboard::KEY_DOLLAR, SDLK_DOLLAR },
{ Keyboard::KEY_AMPERSAND, SDLK_AMPERSAND },
{ Keyboard::KEY_QUOTE, SDLK_QUOTE },
{ Keyboard::KEY_LEFTPAREN, SDLK_LEFTPAREN },
{ Keyboard::KEY_RIGHTPAREN, SDLK_RIGHTPAREN },
{ Keyboard::KEY_ASTERISK, SDLK_ASTERISK },
{ Keyboard::KEY_PLUS, SDLK_PLUS },
{ Keyboard::KEY_COMMA, SDLK_COMMA },
{ Keyboard::KEY_MINUS, SDLK_MINUS },
{ Keyboard::KEY_PERIOD, SDLK_PERIOD },
{ Keyboard::KEY_SLASH, SDLK_SLASH },
{ Keyboard::KEY_0, SDLK_0 },
{ Keyboard::KEY_1, SDLK_1 },
{ Keyboard::KEY_2, SDLK_2 },
{ Keyboard::KEY_3, SDLK_3 },
{ Keyboard::KEY_4, SDLK_4 },
{ Keyboard::KEY_5, SDLK_5 },
{ Keyboard::KEY_6, SDLK_6 },
{ Keyboard::KEY_7, SDLK_7 },
{ Keyboard::KEY_8, SDLK_8 },
{ Keyboard::KEY_9, SDLK_9 },
{ Keyboard::KEY_COLON, SDLK_COLON },
{ Keyboard::KEY_SEMICOLON, SDLK_SEMICOLON },
{ Keyboard::KEY_LESS, SDLK_LESS },
{ Keyboard::KEY_EQUALS, SDLK_EQUALS },
{ Keyboard::KEY_GREATER, SDLK_GREATER },
{ Keyboard::KEY_QUESTION, SDLK_QUESTION },
{ Keyboard::KEY_AT, SDLK_AT },
{ Keyboard::KEY_LEFTBRACKET, SDLK_LEFTBRACKET },
{ Keyboard::KEY_BACKSLASH, SDLK_BACKSLASH },
{ Keyboard::KEY_RIGHTBRACKET, SDLK_RIGHTBRACKET },
{ Keyboard::KEY_CARET, SDLK_CARET },
{ Keyboard::KEY_UNDERSCORE, SDLK_UNDERSCORE },
{ Keyboard::KEY_BACKQUOTE, SDLK_BACKQUOTE },
{ Keyboard::KEY_A, SDLK_a },
{ Keyboard::KEY_B, SDLK_b },
{ Keyboard::KEY_C, SDLK_c },
{ Keyboard::KEY_D, SDLK_d },
{ Keyboard::KEY_E, SDLK_e },
{ Keyboard::KEY_F, SDLK_f },
{ Keyboard::KEY_G, SDLK_g },
{ Keyboard::KEY_H, SDLK_h },
{ Keyboard::KEY_I, SDLK_i },
{ Keyboard::KEY_J, SDLK_j },
{ Keyboard::KEY_K, SDLK_k },
{ Keyboard::KEY_L, SDLK_l },
{ Keyboard::KEY_M, SDLK_m },
{ Keyboard::KEY_N, SDLK_n },
{ Keyboard::KEY_O, SDLK_o },
{ Keyboard::KEY_P, SDLK_p },
{ Keyboard::KEY_Q, SDLK_q },
{ Keyboard::KEY_R, SDLK_r },
{ Keyboard::KEY_S, SDLK_s },
{ Keyboard::KEY_T, SDLK_t },
{ Keyboard::KEY_U, SDLK_u },
{ Keyboard::KEY_V, SDLK_v },
{ Keyboard::KEY_W, SDLK_w },
{ Keyboard::KEY_X, SDLK_x },
{ Keyboard::KEY_Y, SDLK_y },
{ Keyboard::KEY_Z, SDLK_z },
{ Keyboard::KEY_DELETE, SDLK_DELETE },
{ Keyboard::KEY_KP0, SDLK_KP0 },
{ Keyboard::KEY_KP1, SDLK_KP1 },
{ Keyboard::KEY_KP2, SDLK_KP2 },
{ Keyboard::KEY_KP3, SDLK_KP3 },
{ Keyboard::KEY_KP4, SDLK_KP4 },
{ Keyboard::KEY_KP5, SDLK_KP5 },
{ Keyboard::KEY_KP6, SDLK_KP6 },
{ Keyboard::KEY_KP7, SDLK_KP7 },
{ Keyboard::KEY_KP8, SDLK_KP8 },
{ Keyboard::KEY_KP9, SDLK_KP9 },
{ Keyboard::KEY_KP_PERIOD, SDLK_KP_PERIOD },
{ Keyboard::KEY_KP_DIVIDE, SDLK_KP_DIVIDE },
{ Keyboard::KEY_KP_MULTIPLY, SDLK_KP_MULTIPLY},
{ Keyboard::KEY_KP_MINUS, SDLK_KP_MINUS },
{ Keyboard::KEY_KP_PLUS, SDLK_KP_PLUS },
{ Keyboard::KEY_KP_ENTER, SDLK_KP_ENTER },
{ Keyboard::KEY_KP_EQUALS, SDLK_KP_EQUALS },
{ Keyboard::KEY_UP, SDLK_UP },
{ Keyboard::KEY_DOWN, SDLK_DOWN },
{ Keyboard::KEY_RIGHT, SDLK_RIGHT },
{ Keyboard::KEY_LEFT, SDLK_LEFT },
{ Keyboard::KEY_INSERT, SDLK_INSERT },
{ Keyboard::KEY_HOME, SDLK_HOME },
{ Keyboard::KEY_END, SDLK_END },
{ Keyboard::KEY_PAGEUP, SDLK_PAGEUP },
{ Keyboard::KEY_PAGEDOWN, SDLK_PAGEDOWN },
{ Keyboard::KEY_F1, SDLK_F1 },
{ Keyboard::KEY_F2, SDLK_F2 },
{ Keyboard::KEY_F3, SDLK_F3 },
{ Keyboard::KEY_F4, SDLK_F4 },
{ Keyboard::KEY_F5, SDLK_F5 },
{ Keyboard::KEY_F6, SDLK_F6 },
{ Keyboard::KEY_F7, SDLK_F7 },
{ Keyboard::KEY_F8, SDLK_F8 },
{ Keyboard::KEY_F9, SDLK_F9 },
{ Keyboard::KEY_F10, SDLK_F10 },
{ Keyboard::KEY_F11, SDLK_F11 },
{ Keyboard::KEY_F12, SDLK_F12 },
{ Keyboard::KEY_F13, SDLK_F13 },
{ Keyboard::KEY_F14, SDLK_F14 },
{ Keyboard::KEY_F15, SDLK_F15 },
{ Keyboard::KEY_NUMLOCK, SDLK_NUMLOCK },
{ Keyboard::KEY_CAPSLOCK, SDLK_CAPSLOCK },
{ Keyboard::KEY_SCROLLOCK, SDLK_SCROLLOCK },
{ Keyboard::KEY_RSHIFT, SDLK_RSHIFT },
{ Keyboard::KEY_LSHIFT, SDLK_LSHIFT },
{ Keyboard::KEY_RCTRL, SDLK_RCTRL },
{ Keyboard::KEY_LCTRL, SDLK_LCTRL },
{ Keyboard::KEY_RALT, SDLK_RALT },
{ Keyboard::KEY_LALT, SDLK_LALT },
{ Keyboard::KEY_RMETA, SDLK_RMETA },
{ Keyboard::KEY_LMETA, SDLK_LMETA },
{ Keyboard::KEY_LSUPER, SDLK_LSUPER },
{ Keyboard::KEY_RSUPER, SDLK_RSUPER },
{ Keyboard::KEY_MODE, SDLK_MODE },
{ Keyboard::KEY_COMPOSE, SDLK_COMPOSE },
{ Keyboard::KEY_HELP, SDLK_HELP },
{ Keyboard::KEY_PRINT, SDLK_PRINT },
{ Keyboard::KEY_SYSREQ, SDLK_SYSREQ },
{ Keyboard::KEY_BREAK, SDLK_BREAK },
{ Keyboard::KEY_MENU, SDLK_MENU },
{ Keyboard::KEY_POWER, SDLK_POWER },
{ Keyboard::KEY_EURO, SDLK_EURO },
{ Keyboard::KEY_UNDO, SDLK_UNDO },
};
EnumMap<Keyboard::Key, SDLKey, Keyboard::KEY_MAX_ENUM> Keyboard::keys(Keyboard::keyEntries, sizeof(Keyboard::keyEntries));
std::map<Keyboard::Key, SDL_Keycode> Keyboard::keys = Keyboard::createKeyMap();
} // sdl
} // keyboard
+5 -5
View File
@@ -28,6 +28,9 @@
// SDL
#include <SDL.h>
// STL
#include <map>
namespace love
{
namespace keyboard
@@ -42,14 +45,11 @@ public:
// Implements Module.
const char *getName() const;
bool isDown(Key *keylist) const;
void setKeyRepeat(int delay, int interval) const;
int getKeyRepeatDelay() const;
int getKeyRepeatInterval() const;
private:
static EnumMap<Key, SDLKey, Keyboard::KEY_MAX_ENUM>::Entry keyEntries[];
static EnumMap<Key, SDLKey, Keyboard::KEY_MAX_ENUM> keys;
static std::map<Key, SDL_Keycode> createKeyMap();
static std::map<Key, SDL_Keycode> keys;
}; // Keyboard
-24
View File
@@ -50,34 +50,10 @@ int w_isDown(lua_State *L)
return 1;
}
int w_setKeyRepeat(lua_State *L)
{
if (lua_gettop(L) == 0)
{
// Disables key repeat.
instance->setKeyRepeat(0, 0);
return 0;
}
int delay = lua_isnumber(L, 1) ? (int)(lua_tonumber(L, 1) * 1000 + 0.5) : Keyboard::DEFAULT;
int interval = lua_isnumber(L, 2) ? (int)(lua_tonumber(L, 2) * 1000 + 0.5) : Keyboard::DEFAULT;
instance->setKeyRepeat(delay, interval);
return 0;
}
int w_getKeyRepeat(lua_State *L)
{
lua_pushnumber(L, (lua_Number) instance->getKeyRepeatDelay() * 0.001);
lua_pushnumber(L, (lua_Number) instance->getKeyRepeatInterval() * 0.001);
return 2;
}
// List of functions to wrap.
static const luaL_Reg functions[] =
{
{ "isDown", w_isDown },
{ "setKeyRepeat", w_setKeyRepeat },
{ "getKeyRepeat", w_getKeyRepeat },
{ 0, 0 }
};
-2
View File
@@ -30,8 +30,6 @@ namespace keyboard
{
int w_isDown(lua_State *L);
int w_setKeyRepeat(lua_State *L);
int w_getKeyRepeat(lua_State *L);
extern "C" LOVE_EXPORT int luaopen_love_keyboard(lua_State *L);
} // keyboard
+2
View File
@@ -103,6 +103,7 @@ extern "C"
extern int luaopen_love_mouse(lua_State*);
extern int luaopen_love_physics(lua_State*);
extern int luaopen_love_sound(lua_State*);
extern int luaopen_love_system(lua_State*);
extern int luaopen_love_timer(lua_State*);
extern int luaopen_love_thread(lua_State*);
extern int luaopen_love_window(lua_State*);
@@ -122,6 +123,7 @@ static const luaL_Reg modules[] = {
{ "love.mouse", luaopen_love_mouse },
{ "love.physics", luaopen_love_physics },
{ "love.sound", luaopen_love_sound },
{ "love.system", luaopen_love_system },
{ "love.timer", luaopen_love_timer },
{ "love.thread", luaopen_love_thread },
{ "love.window", luaopen_love_window },
+79
View File
@@ -0,0 +1,79 @@
/**
* Copyright (c) 2006-2013 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "Cursor.h"
namespace love
{
namespace mouse
{
Cursor::~Cursor()
{
}
bool Cursor::getConstant(const char *in, SystemCursor &out)
{
return systemCursors.find(in, out);
}
bool Cursor::getConstant(SystemCursor in, const char *&out)
{
return systemCursors.find(in, out);
}
bool Cursor::getConstant(const char *in, CursorType &out)
{
return types.find(in, out);
}
bool Cursor::getConstant(CursorType in, const char *&out)
{
return types.find(in, out);
}
StringMap<Cursor::SystemCursor, Cursor::CURSOR_MAX_ENUM>::Entry Cursor::systemCursorEntries[] =
{
{"arrow", Cursor::CURSOR_ARROW},
{"ibeam", Cursor::CURSOR_IBEAM},
{"wait", Cursor::CURSOR_WAIT},
{"crosshair", Cursor::CURSOR_CROSSHAIR},
{"waitarrow", Cursor::CURSOR_WAITARROW},
{"sizenwse", Cursor::CURSOR_SIZENWSE},
{"sizenesw", Cursor::CURSOR_SIZENESW},
{"sizewe", Cursor::CURSOR_SIZEWE},
{"sizens", Cursor::CURSOR_SIZENS},
{"sizeall", Cursor::CURSOR_SIZEALL},
{"no", Cursor::CURSOR_NO},
{"hand", Cursor::CURSOR_HAND},
};
StringMap<Cursor::SystemCursor, Cursor::CURSOR_MAX_ENUM> Cursor::systemCursors(Cursor::systemCursorEntries, sizeof(Cursor::systemCursorEntries));
StringMap<Cursor::CursorType, Cursor::CURSORTYPE_MAX_ENUM>::Entry Cursor::typeEntries[] =
{
{"system", Cursor::CURSORTYPE_SYSTEM},
{"image", Cursor::CURSORTYPE_IMAGE},
};
StringMap<Cursor::CursorType, Cursor::CURSORTYPE_MAX_ENUM> Cursor::types(Cursor::typeEntries, sizeof(Cursor::typeEntries));
} // mouse
} // love
+100
View File
@@ -0,0 +1,100 @@
/**
* Copyright (c) 2006-2013 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_MOUSE_CURSOR_H
#define LOVE_MOUSE_CURSOR_H
// LOVE
#include "image/ImageData.h"
#include "common/Object.h"
#include "common/StringMap.h"
namespace love
{
namespace mouse
{
class Cursor : public Object
{
public:
// Types of system cursors.
enum SystemCursor
{
CURSOR_ARROW,
CURSOR_IBEAM,
CURSOR_WAIT,
CURSOR_CROSSHAIR,
CURSOR_WAITARROW,
CURSOR_SIZENWSE,
CURSOR_SIZENESW,
CURSOR_SIZEWE,
CURSOR_SIZENS,
CURSOR_SIZEALL,
CURSOR_NO,
CURSOR_HAND,
CURSOR_MAX_ENUM
};
enum CursorType
{
CURSORTYPE_SYSTEM,
CURSORTYPE_IMAGE,
CURSORTYPE_MAX_ENUM
};
virtual ~Cursor();
/**
* Returns a pointer to the implementation-dependent handle of this Cursor.
**/
virtual void *getHandle() const = 0;
/**
* Returns whether this Cursor is system-defined or a custom image.
**/
virtual CursorType getType() const = 0;
/**
* Returns the type type of system cursor used, if this Cursor is using a
* system-defined image.
**/
virtual SystemCursor getSystemType() const = 0;
static bool getConstant(const char *in, SystemCursor &out);
static bool getConstant(SystemCursor in, const char *&out);
static bool getConstant(const char *in, CursorType &out);
static bool getConstant(CursorType in, const char *&out);
private:
static StringMap<SystemCursor, CURSOR_MAX_ENUM>::Entry systemCursorEntries[];
static StringMap<SystemCursor, CURSOR_MAX_ENUM> systemCursors;
static StringMap<CursorType, CURSORTYPE_MAX_ENUM>::Entry typeEntries[];
static StringMap<CursorType, CURSORTYPE_MAX_ENUM> types;
};
} // mouse
} // love
#endif // LOVE_MOUSE_CURSOR_H
+10
View File
@@ -22,8 +22,10 @@
#define LOVE_MOUSE_MOUSE_H
// LOVE
#include "Cursor.h"
#include "common/Module.h"
#include "common/StringMap.h"
#include "image/ImageData.h"
namespace love
{
@@ -49,6 +51,14 @@ public:
virtual ~Mouse() {};
virtual Cursor *newCursor(love::image::ImageData *data, int hotx, int hoty) = 0;
virtual Cursor *newCursor(Cursor::SystemCursor cursortype) = 0;
virtual void setCursor(Cursor *cursor) = 0;
virtual void setCursor() = 0;
virtual Cursor *getCursor() const = 0;
virtual int getX() const = 0;
virtual int getY() const = 0;
virtual void getPosition(int &x, int &y) const = 0;
+122
View File
@@ -0,0 +1,122 @@
/**
* Copyright (c) 2006-2013 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
// LOVE
#include "Cursor.h"
#include "common/config.h"
namespace love
{
namespace mouse
{
namespace sdl
{
Cursor::Cursor(image::ImageData *data, int hotx, int hoty)
: cursor(0)
, type(CURSORTYPE_IMAGE)
, systemType(CURSOR_MAX_ENUM)
{
Uint32 rmask, gmask, bmask, amask;
#ifdef LOVE_BIG_ENDIAN
rmask = 0xFF000000;
gmask = 0x00FF0000;
bmask = 0x0000FF00;
amask = 0x000000FF;
#else
rmask = 0x000000FF;
gmask = 0x0000FF00;
bmask = 0x00FF0000;
amask = 0xFF000000;
#endif
int w = data->getWidth();
int h = data->getHeight();
int pitch = w * 4;
SDL_Surface *surface = SDL_CreateRGBSurfaceFrom(data->getData(), w, h, 32, pitch, rmask, gmask, bmask, amask);
if (!surface)
throw love::Exception("Cannot create cursor: out of memory!");
cursor = SDL_CreateColorCursor(surface, hotx, hoty);
SDL_FreeSurface(surface);
if (!cursor)
throw love::Exception("Cannot create cursor: %s", SDL_GetError());
}
Cursor::Cursor(mouse::Cursor::SystemCursor cursortype)
: cursor(0)
, type(CURSORTYPE_SYSTEM)
, systemType(cursortype)
{
SDL_SystemCursor sdlcursortype;
if (systemCursors.find(cursortype, sdlcursortype))
cursor = SDL_CreateSystemCursor(sdlcursortype);
else
throw love::Exception("Cannot create system cursor: invalid type.");
if (!cursor)
throw love::Exception("Cannot create system cursor: %s", SDL_GetError());
}
Cursor::~Cursor()
{
if (cursor)
SDL_FreeCursor(cursor);
}
void *Cursor::getHandle() const
{
return cursor;
}
Cursor::CursorType Cursor::getType() const
{
return type;
}
Cursor::SystemCursor Cursor::getSystemType() const
{
return systemType;
}
EnumMap<Cursor::SystemCursor, SDL_SystemCursor, Cursor::CURSOR_MAX_ENUM>::Entry Cursor::systemCursorEntries[] =
{
{Cursor::CURSOR_ARROW, SDL_SYSTEM_CURSOR_ARROW},
{Cursor::CURSOR_IBEAM, SDL_SYSTEM_CURSOR_IBEAM},
{Cursor::CURSOR_WAIT, SDL_SYSTEM_CURSOR_WAIT},
{Cursor::CURSOR_CROSSHAIR, SDL_SYSTEM_CURSOR_CROSSHAIR},
{Cursor::CURSOR_WAITARROW, SDL_SYSTEM_CURSOR_WAITARROW},
{Cursor::CURSOR_SIZENWSE, SDL_SYSTEM_CURSOR_SIZENWSE},
{Cursor::CURSOR_SIZENESW, SDL_SYSTEM_CURSOR_SIZENESW},
{Cursor::CURSOR_SIZEWE, SDL_SYSTEM_CURSOR_SIZEWE},
{Cursor::CURSOR_SIZENS, SDL_SYSTEM_CURSOR_SIZENS},
{Cursor::CURSOR_SIZEALL, SDL_SYSTEM_CURSOR_SIZEALL},
{Cursor::CURSOR_NO, SDL_SYSTEM_CURSOR_NO},
{Cursor::CURSOR_HAND, SDL_SYSTEM_CURSOR_HAND},
};
EnumMap<Cursor::SystemCursor, SDL_SystemCursor, Cursor::CURSOR_MAX_ENUM> Cursor::systemCursors(Cursor::systemCursorEntries, sizeof(Cursor::systemCursorEntries));
} // sdl
} // mouse
} // love
+64
View File
@@ -0,0 +1,64 @@
/**
* Copyright (c) 2006-2013 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_MOUSE_SDL_CURSOR_H
#define LOVE_MOUSE_SDL_CURSOR_H
// LOVE
#include "mouse/Cursor.h"
#include "common/EnumMap.h"
// SDL
#include <SDL_mouse.h>
namespace love
{
namespace mouse
{
namespace sdl
{
class Cursor : public love::mouse::Cursor
{
public:
Cursor(image::ImageData *imageData, int hotx, int hoty);
Cursor(SystemCursor cursortype);
~Cursor();
void *getHandle() const;
CursorType getType() const;
SystemCursor getSystemType() const;
private:
SDL_Cursor *cursor;
CursorType type;
SystemCursor systemType;
static EnumMap<SystemCursor, SDL_SystemCursor, CURSOR_MAX_ENUM>::Entry systemCursorEntries[];
static EnumMap<SystemCursor, SDL_SystemCursor, CURSOR_MAX_ENUM> systemCursors;
};
} // sdl
} // mouse
} // love
#endif // LOVE_MOUSE_SDL_CURSOR_H
+63 -5
View File
@@ -18,10 +18,12 @@
* 3. This notice may not be removed or altered from any source distribution.
**/
// LOVE
#include "Mouse.h"
#include "window/sdl/Window.h"
// SDL
#include <SDL.h>
#include <SDL_mouse.h>
namespace love
{
@@ -35,6 +37,50 @@ const char *Mouse::getName() const
return "love.mouse.sdl";
}
Mouse::Mouse()
: curCursor(0)
{
}
Mouse::~Mouse()
{
if (curCursor)
setCursor();
}
love::mouse::Cursor *Mouse::newCursor(love::image::ImageData *data, int hotx, int hoty)
{
return new Cursor(data, hotx, hoty);
}
love::mouse::Cursor *Mouse::newCursor(love::mouse::Cursor::SystemCursor cursortype)
{
return new Cursor(cursortype);
}
void Mouse::setCursor(love::mouse::Cursor *cursor)
{
Object::AutoRelease cursorrelease(curCursor);
curCursor = cursor;
curCursor->retain();
SDL_SetCursor((SDL_Cursor *) cursor->getHandle());
}
void Mouse::setCursor()
{
Object::AutoRelease cursorrelease(curCursor);
curCursor = NULL;
SDL_SetCursor(SDL_GetDefaultCursor());
}
love::mouse::Cursor *Mouse::getCursor() const
{
return curCursor;
}
int Mouse::getX() const
{
int x;
@@ -56,7 +102,13 @@ void Mouse::getPosition(int &x, int &y) const
void Mouse::setPosition(int x, int y)
{
SDL_WarpMouse(x, y);
love::window::Window *window = love::window::sdl::Window::getSingleton();
SDL_Window *handle = NULL;
if (window)
handle = (SDL_Window *) window->getHandle();
SDL_WarpMouseInWindow(handle, x, y);
}
void Mouse::setX(int x)
@@ -91,17 +143,23 @@ bool Mouse::isDown(Button *buttonlist) const
bool Mouse::isVisible() const
{
return (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE) ? true : false;
return SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE;
}
void Mouse::setGrab(bool grab)
{
SDL_WM_GrabInput(grab ? SDL_GRAB_ON : SDL_GRAB_OFF);
love::window::Window *window = love::window::sdl::Window::getSingleton();
if (window)
window->setMouseGrab(grab);
}
bool Mouse::isGrabbed() const
{
return (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON ? true : false);
love::window::Window *window = love::window::sdl::Window::getSingleton();
if (window)
return window->isMouseGrabbed();
else
return false;
}
} // sdl
+17
View File
@@ -23,6 +23,7 @@
// LOVE
#include "mouse/Mouse.h"
#include "Cursor.h"
namespace love
{
@@ -38,6 +39,17 @@ public:
// Implements Module.
const char *getName() const;
Mouse();
~Mouse();
love::mouse::Cursor *newCursor(love::image::ImageData *data, int hotx, int hoty);
love::mouse::Cursor *newCursor(love::mouse::Cursor::SystemCursor cursortype);
void setCursor(love::mouse::Cursor *cursor);
void setCursor();
love::mouse::Cursor *getCursor() const;
int getX() const;
int getY() const;
void getPosition(int &x, int &y) const;
@@ -49,6 +61,11 @@ public:
bool isVisible() const;
void setGrab(bool grab);
bool isGrabbed() const;
private:
love::mouse::Cursor *curCursor;
}; // Mouse
} // sdl
+66
View File
@@ -0,0 +1,66 @@
/**
* Copyright (c) 2006-2013 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
// LOVE
#include "wrap_Cursor.h"
#include "Cursor.h"
namespace love
{
namespace mouse
{
int w_getType(lua_State *L)
{
mouse::Cursor *cursor = luax_checktype<mouse::Cursor>(L, 1, "Cursor", MOUSE_CURSOR_T);
Cursor::CursorType ctype = cursor->getType();
const char *ctypestr;
if (!mouse::Cursor::getConstant(ctype, ctypestr))
return luaL_error(L, "Unknown cursor type.");
lua_pushstring(L, ctypestr);
Cursor::SystemCursor systype = cursor->getSystemType();
const char *systypestr;
if (mouse::Cursor::getConstant(systype, systypestr))
{
lua_pushstring(L, systypestr);
return 2;
}
return 1;
};
static const luaL_Reg functions[] =
{
{ "getType", w_getType },
{ 0, 0 },
};
extern "C" int luaopen_cursor(lua_State *L)
{
return luax_register_type(L, "Cursor", functions);
}
} // mouse
} // love
+39
View File
@@ -0,0 +1,39 @@
/**
* Copyright (c) 2006-2013 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_MOUSE_WRAP_CURSOR_H
#define LOVE_MOUSE_WRAP_CURSOR_H
// LOVE
#include "common/runtime.h"
namespace love
{
namespace mouse
{
int w_getType(lua_State *L);
extern "C" int luaopen_cursor(lua_State *L);
} // mouse
} // love
#endif // LOVE_MOUSE_WRAP_CURSOR_H
+86 -3
View File
@@ -18,12 +18,13 @@
* 3. This notice may not be removed or altered from any source distribution.
**/
// LOVE
#include "wrap_Mouse.h"
#include "wrap_Cursor.h"
#include "common/config.h"
#include "sdl/Mouse.h"
#include "wrap_Mouse.h"
namespace love
{
namespace mouse
@@ -31,6 +32,78 @@ namespace mouse
static Mouse *instance = 0;
int w_newCursor(lua_State *L)
{
Cursor *cursor = 0;
if (lua_isstring(L, 1))
{
// System cursor type.
const char *str = luaL_checkstring(L, 1);
Cursor::SystemCursor systemCursor;
if (!Cursor::getConstant(str, systemCursor))
return luaL_error(L, "Invalid cursor type %s", str);
try
{
cursor = instance->newCursor(systemCursor);
}
catch (love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
}
else
{
// Custom image.
love::image::ImageData *data = luax_checktype<love::image::ImageData>(L, 1, "ImageData", IMAGE_IMAGE_DATA_T);
int hotx = luaL_optint(L, 2, 0);
int hoty = luaL_optint(L, 3, 0);
try
{
cursor = instance->newCursor(data, hotx, hoty);
}
catch (love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
}
luax_newtype(L, "Cursor", MOUSE_CURSOR_T, (void *) cursor);
return 1;
}
int w_setCursor(lua_State *L)
{
// Revert to the default system cursor if no argument is given.
if (lua_isnoneornil(L, 1))
{
instance->setCursor();
return 0;
}
Cursor *cursor = luax_checktype<Cursor>(L, 1, "Cursor", MOUSE_CURSOR_T);
instance->setCursor(cursor);
return 0;
}
int w_getCursor(lua_State *L)
{
Cursor *cursor = instance->getCursor();
if (cursor)
{
cursor->retain();
luax_newtype(L, "Cursor", MOUSE_CURSOR_T, (void *) cursor);
}
else
lua_pushnil(L);
return 1;
}
int w_getX(lua_State *L)
{
lua_pushnumber(L, instance->getX());
@@ -122,6 +195,9 @@ int w_isGrabbed(lua_State *L)
// List of functions to wrap.
static const luaL_Reg functions[] =
{
{ "newCursor", w_newCursor },
{ "setCursor", w_setCursor },
{ "getCursor", w_getCursor },
{ "getX", w_getX },
{ "getY", w_getY },
{ "setX", w_setX },
@@ -136,6 +212,13 @@ static const luaL_Reg functions[] =
{ 0, 0 }
};
// Types for this module.
static const lua_CFunction types[] =
{
luaopen_cursor,
0,
};
extern "C" int luaopen_love_mouse(lua_State *L)
{
if (instance == 0)
@@ -157,7 +240,7 @@ extern "C" int luaopen_love_mouse(lua_State *L)
w.name = "mouse";
w.flags = MODULE_T;
w.functions = functions;
w.types = 0;
w.types = types;
return luax_register_module(L, w);
}
+5 -1
View File
@@ -22,13 +22,17 @@
#define LOVE_MOUSE_WRAP_MOUSE_H
// LOVE
#include "Mouse.h"
#include "common/runtime.h"
#include "common/config.h"
namespace love
{
namespace mouse
{
int w_newCursor(lua_State *L);
int w_setCursor(lua_State *L);
int w_getCursor(lua_State *L);
int w_getX(lua_State *L);
int w_getY(lua_State *L);
int w_getPosition(lua_State *L);
+63
View File
@@ -0,0 +1,63 @@
/**
* Copyright (c) 2006-2013 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#include "System.h"
namespace love
{
namespace system
{
std::string System::getOS() const
{
#ifdef LOVE_MACOSX
return "OS X";
#elif LOVE_WINDOWS
return "Windows";
#elif LOVE_LINUX
return "Linux";
#else
return "Unknown";
#endif
}
bool System::getConstant(const char *in, System::PowerState &out)
{
return powerStates.find(in, out);
}
bool System::getConstant(System::PowerState in, const char *&out)
{
return powerStates.find(in, out);
}
StringMap<System::PowerState, System::POWER_MAX_ENUM>::Entry System::powerEntries[] =
{
{"unknown", System::POWER_UNKNOWN},
{"battery", System::POWER_BATTERY},
{"nobattery", System::POWER_NO_BATTERY},
{"charging", System::POWER_CHARGING},
{"charged", System::POWER_CHARGED},
};
StringMap<System::PowerState, System::POWER_MAX_ENUM> System::powerStates(System::powerEntries, sizeof(System::powerEntries));
} // system
} // love
+101
View File
@@ -0,0 +1,101 @@
/**
* Copyright (c) 2006-2013 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_SYSTEM_H
#define LOVE_SYSTEM_H
// LOVE
#include "common/config.h"
#include "common/Module.h"
#include "common/StringMap.h"
// stdlib
#include <string>
namespace love
{
namespace system
{
class System : public Module
{
public:
enum PowerState
{
POWER_UNKNOWN,
POWER_BATTERY,
POWER_NO_BATTERY,
POWER_CHARGING,
POWER_CHARGED,
POWER_MAX_ENUM
};
virtual ~System() {}
/**
* Gets the current operating system.
**/
std::string getOS() const;
/**
* Gets the number of reported CPU cores on the current system.
* Does not account for technologies such as Hyperthreading: a 4-core
* Hyperthreading-enabled Intel CPU will report 8, instead of 4.
**/
virtual int getProcessorCount() const = 0;
/**
* Replaces the contents of the system's text clipboard with a string.
* @param text The clipboard text to set.
**/
virtual void setClipboardText(const std::string &text) const = 0;
/**
* Gets the contents of the system's text clipboard.
**/
virtual std::string getClipboardText() const = 0;
/**
* Gets information about the system's power supply.
*
* @param[out] seconds Time in seconds of battery life left.
* -1 if a value can't be determined.
* @param[out] percent The percentage of battery life left (0-100.)
* -1 if a value can't be determined.
*
* @return The current state of the battery.
**/
virtual PowerState getPowerInfo(int &seconds, int &percent) const = 0;
static bool getConstant(const char *in, PowerState &out);
static bool getConstant(PowerState in, const char *&out);
private:
static StringMap<PowerState, POWER_MAX_ENUM>::Entry powerEntries[];
static StringMap<PowerState, POWER_MAX_ENUM> powerStates;
}; // System
} // system
} // love
#endif // LOVE_SYSTEM_H
+91
View File
@@ -0,0 +1,91 @@
/**
* Copyright (c) 2006-2013 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
// LOVE
#include "System.h"
// SDL
#include <SDL_clipboard.h>
#include <SDL_cpuinfo.h>
namespace love
{
namespace system
{
namespace sdl
{
System::System()
{
}
const char *System::getName() const
{
return "love.system.sdl";
}
int System::getProcessorCount() const
{
return SDL_GetCPUCount();
}
void System::setClipboardText(const std::string &text) const
{
SDL_SetClipboardText(text.c_str());
}
std::string System::getClipboardText() const
{
std::string text("");
char *ctext = SDL_GetClipboardText();
if (ctext)
{
text = std::string(ctext);
SDL_free(ctext);
}
return text;
}
love::system::System::PowerState System::getPowerInfo(int &seconds, int &percent) const
{
SDL_PowerState sdlstate = SDL_GetPowerInfo(&seconds, &percent);
PowerState state = POWER_UNKNOWN;
powerStates.find(sdlstate, state);
return state;
}
EnumMap<System::PowerState, SDL_PowerState, System::POWER_MAX_ENUM>::Entry System::powerEntries[] =
{
{System::POWER_UNKNOWN, SDL_POWERSTATE_UNKNOWN},
{System::POWER_BATTERY, SDL_POWERSTATE_ON_BATTERY},
{System::POWER_NO_BATTERY, SDL_POWERSTATE_NO_BATTERY},
{System::POWER_CHARGING, SDL_POWERSTATE_CHARGING},
{System::POWER_CHARGED, SDL_POWERSTATE_CHARGED},
};
EnumMap<System::PowerState, SDL_PowerState, System::POWER_MAX_ENUM> System::powerStates(System::powerEntries, sizeof(System::powerEntries));
} // sdl
} // system
} // love
+66
View File
@@ -0,0 +1,66 @@
/**
* Copyright (c) 2006-2013 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_SYSTEM_SDL_SYSTEM_H
#define LOVE_SYSTEM_SDL_SYSTEM_H
// LOVE
#include "system/System.h"
#include "common/EnumMap.h"
// SDL
#include <SDL_power.h>
namespace love
{
namespace system
{
namespace sdl
{
class System : public love::system::System
{
public:
System();
virtual ~System() {}
// Implements Module.
const char *getName() const;
int getProcessorCount() const;
void setClipboardText(const std::string &text) const;
std::string getClipboardText() const;
PowerState getPowerInfo(int &seconds, int &percent) const;
private:
static EnumMap<PowerState, SDL_PowerState, POWER_MAX_ENUM>::Entry powerEntries[];
static EnumMap<PowerState, SDL_PowerState, POWER_MAX_ENUM> powerStates;
}; // System
} // sdl
} // system
} // love
#endif // LOVE_SYSTEM_SDL_SYSTEM_H
+112
View File
@@ -0,0 +1,112 @@
/**
* Copyright (c) 2006-2013 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
// LOVE
#include "wrap_System.h"
#include "sdl/System.h"
namespace love
{
namespace system
{
static System *instance = 0;
int w_getOS(lua_State *L)
{
luax_pushstring(L, instance->getOS());
return 1;
}
int w_getProcessorCount(lua_State *L)
{
lua_pushinteger(L, instance->getProcessorCount());
return 1;
}
int w_setClipboardText(lua_State *L)
{
const char *text = luaL_checkstring(L, 1);
instance->setClipboardText(text);
return 0;
}
int w_getClipboardText(lua_State *L)
{
luax_pushstring(L, instance->getClipboardText());
return 1;
}
int w_getPowerInfo(lua_State *L)
{
int seconds = -1, percent = -1;
const char *str;
System::PowerState state = instance->getPowerInfo(seconds, percent);
if (!System::getConstant(state, str))
str = "unknown";
lua_pushstring(L, str);
if (percent >= 0)
lua_pushinteger(L, percent);
else
lua_pushnil(L);
if (seconds >= 0)
lua_pushinteger(L, seconds);
else
lua_pushnil(L);
return 3;
}
static const luaL_Reg functions[] =
{
{ "getOS", w_getOS },
{ "getProcessorCount", w_getProcessorCount },
{ "setClipboardText", w_setClipboardText },
{ "getClipboardText", w_getClipboardText },
{ "getPowerInfo", w_getPowerInfo },
{ 0, 0 }
};
extern "C" int luaopen_love_system(lua_State *L)
{
if (instance == 0)
{
instance = new love::system::sdl::System();
}
else
instance->retain();
WrappedModule w;
w.module = instance;
w.name = "system";
w.flags = MODULE_T;
w.functions = functions;
w.types = 0;
return luax_register_module(L, w);
}
} // system
} // love
+43
View File
@@ -0,0 +1,43 @@
/**
* Copyright (c) 2006-2013 LOVE Development Team
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
**/
#ifndef LOVE_WRAP_SYSTEM_H
#define LOVE_WRAP_SYSTEM_H
// LOVE
#include "System.h"
#include "common/runtime.h"
namespace love
{
namespace system
{
int w_getOS(lua_State *L);
int w_getProcessorCount(lua_State *L);
int w_setClipboardText(lua_State *L);
int w_getClipboardText(lua_State *L);
int w_getPowerInfo(lua_State *L);
extern "C" LOVE_EXPORT int luaopen_love_system(lua_State *L);
} // system
} // love
#endif // LOVE_WRAP_SYSTEM_H
+6 -4
View File
@@ -24,10 +24,6 @@ namespace love
{
namespace thread
{
const char *ThreadModule::getName() const
{
return "love.thread.sdl";
}
LuaThread *ThreadModule::newThread(const std::string &name, love::Data *data)
{
@@ -44,5 +40,11 @@ Channel *ThreadModule::getChannel(const std::string &name)
{
return Channel::getChannel(name);
}
const char *ThreadModule::getName() const
{
return "love.thread.sdl";
}
} // thread
} // love
+17 -11
View File
@@ -25,12 +25,14 @@
#include <string>
// LOVE
#include <common/Data.h>
#include <common/Module.h>
#include <thread/Thread.h>
#include <thread/Channel.h>
#include <thread/LuaThread.h>
#include <thread/threads.h>
#include "common/Data.h"
#include "common/Module.h"
#include "common/StringMap.h"
#include "Thread.h"
#include "Channel.h"
#include "LuaThread.h"
#include "threads.h"
namespace love
{
@@ -39,13 +41,17 @@ namespace thread
class ThreadModule : public love::Module
{
public:
virtual ~ThreadModule() {}
LuaThread *newThread(const std::string &name, love::Data *data);
Channel *newChannel();
Channel *getChannel(const std::string &name);
const char *getName() const;
virtual ~ThreadModule() {}
virtual LuaThread *newThread(const std::string &name, love::Data *data);
virtual Channel *newChannel();
virtual Channel *getChannel(const std::string &name);
// Implements Module.
virtual const char *getName() const;
}; // ThreadModule
} // thread
} // love
+1 -1
View File
@@ -51,7 +51,7 @@ bool Thread::start()
return false;
if (thread) // Clean old handle up
SDL_WaitThread(thread, 0);
thread = SDL_CreateThread(thread_runner, this);
thread = SDL_CreateThread(thread_runner, NULL, this);
running = (thread != 0);
return running;
}
+2 -2
View File
@@ -39,12 +39,12 @@ Mutex::~Mutex()
void Mutex::lock()
{
SDL_mutexP(mutex);
SDL_LockMutex(mutex);
}
void Mutex::unlock()
{
SDL_mutexV(mutex);
SDL_UnlockMutex(mutex);
}
Conditional::Conditional()
+10 -5
View File
@@ -18,16 +18,20 @@
* 3. This notice may not be removed or altered from any source distribution.
**/
// LOVE
#include "wrap_ThreadModule.h"
#include "wrap_LuaThread.h"
#include "wrap_Channel.h"
#include <filesystem/File.h>
#include <filesystem/FileData.h>
#include "ThreadModule.h"
#include "filesystem/File.h"
#include "filesystem/FileData.h"
namespace love
{
namespace thread
{
static ThreadModule *instance = 0;
int w_newThread(lua_State *L)
@@ -89,7 +93,7 @@ extern "C" int luaopen_love_thread(lua_State *L)
{
try
{
instance = new ThreadModule();
instance = new love::thread::ThreadModule();
}
catch (Exception & e)
{
@@ -108,5 +112,6 @@ extern "C" int luaopen_love_thread(lua_State *L)
return luax_register_module(L, w);
}
}
}
} // thread
} // love
+2 -1
View File
@@ -22,7 +22,8 @@
#define LOVE_THREAD_WRAP_THREADMODULE_H
// LOVE
#include "ThreadModule.h"
#include "common/config.h"
#include "common/runtime.h"
namespace love
{
+22
View File
@@ -40,13 +40,35 @@ void Window::swapBuffers()
WindowFlags::WindowFlags()
: fullscreen(false)
, fstype(Window::FULLSCREEN_TYPE_NORMAL)
, vsync(true)
, fsaa(0)
, resizable(false)
, minwidth(100)
, minheight(100)
, borderless(false)
, centered(true)
, display(0)
{
}
bool Window::getConstant(const char *in, Window::FullscreenType &out)
{
return fullscreenTypes.find(in, out);
}
bool Window::getConstant(Window::FullscreenType in, const char *&out)
{
return fullscreenTypes.find(in, out);
}
StringMap<Window::FullscreenType, Window::FULLSCREEN_TYPE_MAX_ENUM>::Entry Window::fullscreenTypeEntries[] =
{
{"normal", Window::FULLSCREEN_TYPE_NORMAL},
{"desktop", Window::FULLSCREEN_TYPE_DESKTOP},
};
StringMap<Window::FullscreenType, Window::FULLSCREEN_TYPE_MAX_ENUM> Window::fullscreenTypes(Window::fullscreenTypeEntries, sizeof(Window::fullscreenTypeEntries));
} // window
} // love
+61 -18
View File
@@ -21,32 +21,35 @@
#ifndef LOVE_WINDOW_WINDOW_H
#define LOVE_WINDOW_WINDOW_H
// STL
#include <string>
// LOVE
#include "common/Module.h"
#include "common/StringMap.h"
#include "image/ImageData.h"
// C++
#include <string>
#include <vector>
namespace love
{
namespace window
{
struct WindowFlags
{
WindowFlags();
bool fullscreen; // = false
bool vsync; // = true
int fsaa; // = 0
bool resizable; // = false
bool borderless; // = false
bool centered; // = true
}; // WindowFlags
// Forward-declared so it can be used in the class methods. We can't define the
// whole thing here because it uses the Window::Type enum.
struct WindowFlags;
class Window : public Module
{
public:
enum FullscreenType
{
FULLSCREEN_TYPE_NORMAL,
FULLSCREEN_TYPE_DESKTOP,
FULLSCREEN_TYPE_MAX_ENUM
};
struct WindowSize
{
int width;
@@ -56,18 +59,27 @@ public:
virtual ~Window();
virtual bool setWindow(int width = 800, int height = 600, WindowFlags *flags = 0) = 0;
virtual void getWindow(int &width, int &height, WindowFlags &flags) const = 0;
virtual void getWindow(int &width, int &height, WindowFlags &flags) = 0;
virtual bool checkWindowSize(int width, int height, bool fullscreen) const = 0;
virtual WindowSize *getFullscreenSizes(int &n) const = 0;
virtual bool setFullscreen(bool fullscreen, FullscreenType fstype) = 0;
virtual bool setFullscreen(bool fullscreen) = 0;
virtual bool onWindowResize(int width, int height) = 0;
virtual int getDisplayCount() const = 0;
virtual bool checkWindowSize(int width, int height, bool fullscreen, int displayindex) const = 0;
virtual std::vector<WindowSize> getFullscreenSizes(int displayindex) const = 0;
virtual int getWidth() const = 0;
virtual int getHeight() const = 0;
virtual void getDesktopDimensions(int displayindex, int &width, int &height) const = 0;
virtual bool isCreated() const = 0;
virtual void setWindowTitle(const std::string &title) = 0;
virtual std::string getWindowTitle() const = 0;
virtual const std::string &getWindowTitle() const = 0;
virtual bool setIcon(love::image::ImageData *imgd) = 0;
virtual love::image::ImageData *getIcon() = 0;
@@ -83,13 +95,44 @@ public:
virtual void setMouseVisible(bool visible) = 0;
virtual bool getMouseVisible() const = 0;
virtual void setMouseGrab(bool grab) = 0;
virtual bool isMouseGrabbed() const = 0;
virtual const void *getHandle() const = 0;
//virtual static Window *createSingleton() = 0;
//virtual static Window *getSingleton() = 0;
// No virtual statics, of course, but you are supposed to implement this static.
// No virtual statics, of course, but you are supposed to implement these statics.
static bool getConstant(const char *in, FullscreenType &out);
static bool getConstant(FullscreenType in, const char *&out);
protected:
static Window *singleton;
private:
static StringMap<FullscreenType, FULLSCREEN_TYPE_MAX_ENUM>::Entry fullscreenTypeEntries[];
static StringMap<FullscreenType, FULLSCREEN_TYPE_MAX_ENUM> fullscreenTypes;
}; // Window
struct WindowFlags
{
WindowFlags();
bool fullscreen; // = false
Window::FullscreenType fstype; // = FULLSCREEN_TYPE_NORMAL
bool vsync; // = true
int fsaa; // = 0
bool resizable; // = false
int minwidth; // = 100
int minheight; // = 100
bool borderless; // = false
bool centered; // = true
int display; // = 0
}; // WindowFlags
} // window
} // love
+392 -155
View File
@@ -23,11 +23,10 @@
#include "graphics/Graphics.h"
#include "Window.h"
// SDL
#include <SDL.h>
// STL
// C++
#include <iostream>
#include <vector>
#include <algorithm>
namespace love
{
@@ -39,15 +38,30 @@ namespace sdl
Window::Window()
: windowTitle("")
, created(false)
, mouseGrabbed(false)
, window(0)
, context(0)
{
#ifdef LOVE_MACOSX
// SDL 2 minimizes the window at weird times on OSX if this isn't disabled.
// TODO: do Linux and/or Windows need this as well (multi-monitor)?
SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, "0");
#endif
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
throw love::Exception(SDL_GetError());
throw love::Exception("%s", SDL_GetError());
}
Window::~Window()
{
if (currentMode.icon)
currentMode.icon->release();
if (curMode.icon)
curMode.icon->release();
if (window)
SDL_DestroyWindow(window);
if (context)
SDL_GL_DeleteContext(context);
SDL_QuitSubSystem(SDL_INIT_VIDEO);
}
@@ -66,109 +80,181 @@ bool Window::setWindow(int width, int height, WindowFlags *flags)
if (gfx)
gfx->unSetMode();
bool fullscreen = false;
bool vsync = true;
int fsaa = 0;
bool resizable = false;
bool borderless = false;
bool centered = true;
WindowFlags f;
if (flags)
f = *flags;
f.minwidth = std::max(f.minwidth, 0);
f.minheight = std::max(f.minheight, 0);
f.display = std::min(std::max(f.display, 0), getDisplayCount());
// Use the desktop resolution if a width or height of 0 is specified.
if (width == 0 || height == 0)
{
fullscreen = flags->fullscreen;
vsync = flags->vsync;
fsaa = flags->fsaa;
resizable = flags->resizable;
borderless = flags->borderless;
centered = flags->centered;
SDL_DisplayMode mode = {};
SDL_GetDesktopDisplayMode(f.display, &mode);
width = mode.w;
height = mode.h;
}
bool mouseVisible = getMouseVisible();
int keyrepeatDelay, keyrepeatInterval;
SDL_GetKeyRepeat(&keyrepeatDelay, &keyrepeatInterval);
Uint32 sdlflags = SDL_WINDOW_OPENGL;
// We need to restart the subsystem for two reasons:
// 1) Special case for fullscreen -> windowed. Windows XP did not
// work well with "normal" display mode change in this case.
// The application window does leave fullscreen, but the desktop
// resolution does not revert to the correct one. Restarting the
// SDL video subsystem does the trick, though.
// 2) Restart the event system (for whatever reason the event system
// started and stopped with SDL_INIT_VIDEO, see:
// http://sdl.beuc.net/sdl.wiki/Introduction_to_Events)
// because the mouse position will not be able to exceed
// the previous' video mode window size (i.e. alway
// love.mouse.getX() < 800 when switching from 800x600 to a
// higher resolution)
SDL_QuitSubSystem(SDL_INIT_VIDEO);
if (centered) // Window should be centered.
SDL_putenv(const_cast<char *>("SDL_VIDEO_CENTERED=center"));
else
SDL_putenv(const_cast<char *>("SDL_VIDEO_CENTERED="));
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
if (f.fullscreen)
{
std::cout << "Could not init SDL_VIDEO: " << SDL_GetError() << std::endl;
switch (f.fstype)
{
case FULLSCREEN_TYPE_NORMAL:
default:
sdlflags |= SDL_WINDOW_FULLSCREEN;
break;
case FULLSCREEN_TYPE_DESKTOP:
sdlflags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
break;
}
}
if (f.resizable)
sdlflags |= SDL_WINDOW_RESIZABLE;
if (f.borderless)
sdlflags |= SDL_WINDOW_BORDERLESS;
// Destroy and recreate the window if the dimensions or flags have changed.
if (window)
{
int curdisplay = SDL_GetWindowDisplayIndex(window);
Uint32 wflags = SDL_GetWindowFlags(window);
wflags &= (SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_RESIZABLE | SDL_WINDOW_BORDERLESS);
if (sdlflags != wflags || width != curMode.width || height != curMode.height
|| f.display != curdisplay || f.fsaa != curMode.flags.fsaa)
{
SDL_DestroyWindow(window);
window = 0;
// The old window may have generated pending events which are no
// longer relevant. Destroy them all!
SDL_FlushEvent(SDL_WINDOWEVENT);
}
}
int centeredpos = SDL_WINDOWPOS_CENTERED_DISPLAY(f.display);
int uncenteredpos = SDL_WINDOWPOS_UNDEFINED_DISPLAY(f.display);
if (!window)
{
// In Windows and Linux, some GL attributes are set on window creation.
setWindowGLAttributes(f.fsaa);
const char *title = windowTitle.c_str();
int pos = f.centered ? centeredpos : uncenteredpos;
window = SDL_CreateWindow(title, pos, pos, width, height, sdlflags);
if (!window && f.fsaa > 0)
{
// FSAA might have caused the failure, disable it and try again.
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
window = SDL_CreateWindow(title, pos, pos, width, height, sdlflags);
f.fsaa = 0;
}
// Make sure the window keeps any previously set icon.
if (window && curMode.icon)
setIcon(curMode.icon);
}
if (!window)
{
std::cerr << "Could not set video mode: " << SDL_GetError() << std::endl;
return false;
}
// Set caption.
setWindowTitle(windowTitle);
setMouseVisible(mouseVisible);
setIcon(currentMode.icon);
SDL_EnableKeyRepeat(keyrepeatDelay, keyrepeatInterval);
// Enforce minimum window dimensions.
SDL_SetWindowMinimumSize(window, f.minwidth, f.minheight);
// Set GL attributes
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, (vsync ? 1 : 0));
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);
if (f.centered && !f.fullscreen)
SDL_SetWindowPosition(window, centeredpos, centeredpos);
// FSAA
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (fsaa > 0) ? 1 : 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, (fsaa > 0) ? fsaa : 0);
SDL_RaiseWindow(window);
Uint32 sdlflags = SDL_OPENGL;
// Flags
if (fullscreen)
sdlflags |= SDL_FULLSCREEN;
if (resizable)
sdlflags |= SDL_RESIZABLE;
if (borderless)
sdlflags |= SDL_NOFRAME;
// Have SDL set the video mode.
SDL_Surface *surface;
if ((surface = SDL_SetVideoMode(width, height, 32, sdlflags)) == 0)
{
bool failed = true;
if (fsaa > 0)
{
// FSAA might have caused the failure, disable it and try again
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
failed = (surface = SDL_SetVideoMode(width, height, 32, sdlflags)) == 0;
}
if (failed)
{
std::cerr << "Could not set video mode: " << SDL_GetError() << std::endl;
return false;
}
}
if (!setContext(f.fsaa, f.vsync))
return false;
created = true;
const SDL_VideoInfo *videoinfo = SDL_GetVideoInfo();
width = videoinfo->current_w;
height = videoinfo->current_h;
updateWindowFlags(f);
if (gfx)
gfx->setMode(curMode.width, curMode.height);
// Make sure the mouse keeps its previous grab setting.
setMouseGrab(mouseGrabbed);
return true;
}
bool Window::onWindowResize(int width, int height)
{
if (!window)
return false;
curMode.width = width;
curMode.height = height;
return true;
}
bool Window::setContext(int fsaa, bool vsync)
{
// We need to recreate the context if FSAA changes,
// or if the existing context has been invalidated.
if (context && (fsaa != curMode.flags.fsaa || SDL_GL_MakeCurrent(window, context) < 0))
{
SDL_GL_DeleteContext(context);
context = 0;
}
// Create a new OpenGL context.
if (!context)
{
setWindowGLAttributes(fsaa);
context = SDL_GL_CreateContext(window);
if (!context && fsaa > 0)
{
// FSAA might have caused the failure, disable it and try again.
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
context = SDL_GL_CreateContext(window);
}
}
if (!context)
{
std::cerr << "Could not set video mode: " << SDL_GetError() << std::endl;
return false;
}
// Set vertical synchronization.
if (vsync)
{
// Prefer EXT_swap_control_tear (late swaps happen immediately),
// otherwise fall back to regular vsync.
if (SDL_GL_SetSwapInterval(-1) < 0 || SDL_GL_GetSwapInterval() != -1)
SDL_GL_SetSwapInterval(1);
}
else
SDL_GL_SetSwapInterval(0);
// Verify FSAA setting.
int buffers;
int samples;
SDL_GL_GetAttribute(SDL_GL_MULTISAMPLEBUFFERS, &buffers);
SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &samples);
@@ -179,65 +265,173 @@ bool Window::setWindow(int width, int height, WindowFlags *flags)
fsaa = (buffers > 0) ? samples : 0;
}
// Get the actual vsync status
int real_vsync;
SDL_GL_GetAttribute(SDL_GL_SWAP_CONTROL, &real_vsync);
// Set the new display mode as the current display mode.
currentMode.width = width;
currentMode.height = height;
currentMode.flags.fsaa = fsaa;
currentMode.flags.fullscreen = fullscreen;
currentMode.flags.vsync = (real_vsync != 0);
currentMode.flags.resizable = ((surface->flags & SDL_RESIZABLE) != 0);
currentMode.flags.borderless = ((surface->flags & SDL_NOFRAME) != 0);
currentMode.flags.centered = centered;
if (gfx)
gfx->setMode(width, height);
curMode.flags.fsaa = fsaa;
curMode.flags.vsync = SDL_GL_GetSwapInterval() != 0;
return true;
}
void Window::getWindow(int &width, int &height, WindowFlags &flags) const
void Window::setWindowGLAttributes(int fsaa) const
{
width = currentMode.width;
height = currentMode.height;
flags = currentMode.flags;
// Set GL window attributes.
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);
// FSAA.
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, (fsaa > 0) ? 1 : 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, (fsaa > 0) ? fsaa : 0);
}
bool Window::checkWindowSize(int width, int height, bool fullscreen) const
void Window::updateWindowFlags(const WindowFlags &newflags)
{
Uint32 sdlflags = fullscreen ? (SDL_OPENGL | SDL_FULLSCREEN) : SDL_OPENGL;
Uint32 wflags = SDL_GetWindowFlags(window);
// Check if mode is supported
int bpp = SDL_VideoModeOK(width, height, 32, sdlflags);
// Set the new display mode as the current display mode.
SDL_GetWindowSize(window, &curMode.width, &curMode.height);
return (bpp >= 16);
if ((wflags & SDL_WINDOW_FULLSCREEN_DESKTOP) == SDL_WINDOW_FULLSCREEN_DESKTOP)
{
curMode.flags.fullscreen = true;
curMode.flags.fstype = FULLSCREEN_TYPE_DESKTOP;
}
else if ((wflags & SDL_WINDOW_FULLSCREEN) == SDL_WINDOW_FULLSCREEN)
{
curMode.flags.fullscreen = true;
curMode.flags.fstype = FULLSCREEN_TYPE_NORMAL;
}
else
{
curMode.flags.fullscreen = false;
curMode.flags.fstype = newflags.fstype;
}
// The min width/height is set to 0 internally in SDL when in fullscreen.
if (curMode.flags.fullscreen)
{
curMode.flags.minwidth = newflags.minwidth;
curMode.flags.minheight = newflags.minheight;
}
else
SDL_GetWindowMinimumSize(window, &curMode.flags.minwidth, &curMode.flags.minheight);
curMode.flags.resizable = (wflags & SDL_WINDOW_RESIZABLE) != 0;
curMode.flags.borderless = (wflags & SDL_WINDOW_BORDERLESS) != 0;
curMode.flags.centered = newflags.centered;
curMode.flags.display = std::max(SDL_GetWindowDisplayIndex(window), 0);
}
void Window::getWindow(int &width, int &height, WindowFlags &flags)
{
// Window position may be different from creation - update display index.
if (window)
curMode.flags.display = std::max(SDL_GetWindowDisplayIndex(window), 0);
width = curMode.width;
height = curMode.height;
flags = curMode.flags;
}
bool Window::setFullscreen(bool fullscreen, Window::FullscreenType fstype)
{
if (!window)
return false;
WindowFlags newflags = curMode.flags;
newflags.fullscreen = fullscreen;
newflags.fstype = fstype;
Uint32 sdlflags = 0;
if (fullscreen)
{
if (fstype == FULLSCREEN_TYPE_DESKTOP)
sdlflags = SDL_WINDOW_FULLSCREEN_DESKTOP;
else
{
sdlflags = SDL_WINDOW_FULLSCREEN;
SDL_DisplayMode mode = {};
mode.w = curMode.width;
mode.h = curMode.height;
SDL_GetClosestDisplayMode(SDL_GetWindowDisplayIndex(window), &mode, &mode);
SDL_SetWindowDisplayMode(window, &mode);
}
}
if (SDL_SetWindowFullscreen(window, sdlflags) == 0)
{
SDL_GL_MakeCurrent(window, context);
updateWindowFlags(newflags);
return true;
}
return false;
}
bool Window::setFullscreen(bool fullscreen)
{
return setFullscreen(fullscreen, curMode.flags.fstype);
}
int Window::getDisplayCount() const
{
return SDL_GetNumVideoDisplays();
}
bool Window::checkWindowSize(int width, int height, bool fullscreen, int displayindex) const
{
if (fullscreen)
{
SDL_DisplayMode mode = {}, closest = {};
mode.w = width;
mode.h = height;
SDL_GetClosestDisplayMode(displayindex, &mode, &closest);
return (mode.w == closest.w && mode.h == closest.h);
}
else
{
SDL_DisplayMode mode = {};
SDL_GetDesktopDisplayMode(displayindex, &mode);
return (width <= mode.w && height <= mode.h);
}
}
typedef Window::WindowSize WindowSize;
WindowSize *Window::getFullscreenSizes(int &n) const
std::vector<WindowSize> Window::getFullscreenSizes(int displayindex) const
{
SDL_Rect **modes = SDL_ListModes(0, SDL_OPENGL | SDL_FULLSCREEN);
std::vector<WindowSize> sizes;
if (modes == (SDL_Rect **)0 || modes == (SDL_Rect **)-1)
SDL_DisplayMode mode = {};
std::vector<WindowSize>::const_iterator it;
for (int i = 0; i < SDL_GetNumDisplayModes(displayindex); i++)
{
n = 0;
return NULL;
}
SDL_GetDisplayMode(displayindex, i, &mode);
n = 0;
for (int i = 0; modes[i]; i++)
n++;
// SDL2's display mode list has multiple entries for modes of the same
// size with different bits per pixel, so we need to filter those out.
bool alreadyhassize = false;
for (it = sizes.begin(); it != sizes.end(); ++it)
{
if (it->width == mode.w && it->height == mode.h)
{
alreadyhassize = true;
break;
}
}
WindowSize *sizes = new WindowSize[n];
for (int i = 0; i < n; i++)
{
WindowSize w = {modes[i]->w, modes[i]->h};
sizes[i] = w;
if (!alreadyhassize)
{
WindowSize w = {mode.w, mode.h};
sizes.push_back(w);
}
}
return sizes;
@@ -245,12 +439,28 @@ WindowSize *Window::getFullscreenSizes(int &n) const
int Window::getWidth() const
{
return currentMode.width;
return curMode.width;
}
int Window::getHeight() const
{
return currentMode.height;
return curMode.height;
}
void Window::getDesktopDimensions(int displayindex, int &width, int &height) const
{
if (displayindex >= 0 && displayindex < getDisplayCount())
{
SDL_DisplayMode mode = {};
SDL_GetDesktopDisplayMode(displayindex, &mode);
width = mode.w;
height = mode.h;
}
else
{
width = 0;
height = 0;
}
}
bool Window::isCreated() const
@@ -261,14 +471,13 @@ bool Window::isCreated() const
void Window::setWindowTitle(const std::string &title)
{
windowTitle = title;
SDL_WM_SetCaption(windowTitle.c_str(), 0);
if (window)
SDL_SetWindowTitle(window, title.c_str());
}
std::string Window::getWindowTitle() const
const std::string &Window::getWindowTitle() const
{
// not a reference
// because we want this untouched
// const std::string& might be an option
return windowTitle;
}
@@ -277,6 +486,14 @@ bool Window::setIcon(love::image::ImageData *imgd)
if (!imgd)
return false;
imgd->retain();
if (curMode.icon)
curMode.icon->release();
curMode.icon = imgd;
if (!window)
return false;
Uint32 rmask, gmask, bmask, amask;
#ifdef LOVE_BIG_ENDIAN
rmask = 0xFF000000;
@@ -294,51 +511,46 @@ bool Window::setIcon(love::image::ImageData *imgd)
int h = imgd->getHeight();
int pitch = imgd->getWidth() * 4;
SDL_Surface *icon = 0;
SDL_Surface *sdlicon = 0;
{
// We don't want another thread modifying the ImageData mid-copy.
love::thread::Lock lock(imgd->getMutex());
icon = SDL_CreateRGBSurfaceFrom(imgd->getData(), w, h, 32, pitch, rmask, gmask, bmask, amask);
sdlicon = SDL_CreateRGBSurfaceFrom(imgd->getData(), w, h, 32, pitch, rmask, gmask, bmask, amask);
}
if (!icon)
if (!sdlicon)
return false;
SDL_WM_SetIcon(icon, NULL);
SDL_FreeSurface(icon);
imgd->retain();
if (currentMode.icon)
currentMode.icon->release();
currentMode.icon = imgd;
SDL_SetWindowIcon(window, sdlicon);
SDL_FreeSurface(sdlicon);
return true;
}
love::image::ImageData *Window::getIcon()
{
return currentMode.icon;
return curMode.icon;
}
void Window::swapBuffers()
{
SDL_GL_SwapBuffers();
SDL_GL_SwapWindow(window);
}
bool Window::hasFocus() const
{
return (SDL_GetAppState() & SDL_APPINPUTFOCUS) != 0;
return (window && SDL_GetKeyboardFocus() == window);
}
bool Window::hasMouseFocus() const
{
return (SDL_GetAppState() & SDL_APPMOUSEFOCUS) != 0;
return (window && SDL_GetMouseFocus() == window);
}
bool Window::isVisible() const
{
return (SDL_GetAppState() & SDL_APPACTIVE) != 0;
return window && (SDL_GetWindowFlags(window) & SDL_WINDOW_SHOWN) != 0;
}
void Window::setMouseVisible(bool visible)
@@ -348,10 +560,30 @@ void Window::setMouseVisible(bool visible)
bool Window::getMouseVisible() const
{
return (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE) ? true : false;
return (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE);
}
love::window::Window *Window::getSingleton()
void Window::setMouseGrab(bool grab)
{
mouseGrabbed = grab;
if (window)
SDL_SetWindowGrab(window, (SDL_bool) grab);
}
bool Window::isMouseGrabbed() const
{
if (window)
return (bool) SDL_GetWindowGrab(window);
else
return mouseGrabbed;
}
const void *Window::getHandle() const
{
return window;
}
love::window::Window *Window::createSingleton()
{
if (!singleton)
singleton = new Window();
@@ -361,6 +593,11 @@ love::window::Window *Window::getSingleton()
return singleton;
}
love::window::Window *Window::getSingleton()
{
return singleton;
}
const char *Window::getName() const
{
return "love.window.sdl";
+34 -5
View File
@@ -24,6 +24,9 @@
// LOVE
#include "window/Window.h"
// SDL
#include <SDL.h>
namespace love
{
namespace window
@@ -39,18 +42,27 @@ public:
~Window();
bool setWindow(int width = 800, int height = 600, WindowFlags *flags = 0);
void getWindow(int &width, int &height, WindowFlags &flags) const;
void getWindow(int &width, int &height, WindowFlags &flags);
bool checkWindowSize(int width, int height, bool fullscreen) const;
WindowSize *getFullscreenSizes(int &n) const;
bool setFullscreen(bool fullscreen, FullscreenType fstype);
bool setFullscreen(bool fullscreen);
bool onWindowResize(int width, int height);
int getDisplayCount() const;
bool checkWindowSize(int width, int height, bool fullscreen, int displayindex) const;
std::vector<WindowSize> getFullscreenSizes(int displayindex) const;
int getWidth() const;
int getHeight() const;
void getDesktopDimensions(int displayindex, int &width, int &height) const;
bool isCreated() const;
void setWindowTitle(const std::string &title);
std::string getWindowTitle() const;
const std::string &getWindowTitle() const;
bool setIcon(love::image::ImageData *imgd);
love::image::ImageData *getIcon();
@@ -65,12 +77,24 @@ public:
void setMouseVisible(bool visible);
bool getMouseVisible() const;
void setMouseGrab(bool grab);
bool isMouseGrabbed() const;
const void *getHandle() const;
static love::window::Window *createSingleton();
static love::window::Window *getSingleton();
const char *getName() const;
private:
bool setContext(int fsaa, bool vsync);
void setWindowGLAttributes(int fsaa) const;
// Update the window flags based on the window's actual state.
void updateWindowFlags(const WindowFlags &newflags);
std::string windowTitle;
struct _currentMode
@@ -82,10 +106,15 @@ private:
WindowFlags flags;
love::image::ImageData *icon;
} currentMode;
} curMode;
bool created;
bool mouseGrabbed;
SDL_Window *window;
SDL_GLContext context;
}; // Window
} // sdl
+104 -28
View File
@@ -28,23 +28,37 @@ namespace window
static Window *instance = 0;
int w_getDisplayCount(lua_State *L)
{
lua_pushinteger(L, instance->getDisplayCount());
return 1;
}
int w_checkMode(lua_State *L)
{
int w = luaL_checkint(L, 1);
int h = luaL_checkint(L, 2);
bool fs = false;
int displayindex = 0;
if (lua_istable(L, 3))
{
lua_getfield(L, 3, "fullscreen");
fs = luax_toboolean(L, -1);
lua_pop(L, 1);
lua_getfield(L, 3, "display");
displayindex = luaL_optint(L, -1, 1) - 1;
lua_pop(L, 2);
}
else
{
fs = luax_toboolean(L, 3);
displayindex = luaL_optint(L, 4, 1) - 1;
}
luax_pushboolean(L, instance->checkWindowSize(w, h, fs));
luax_pushboolean(L, instance->checkWindowSize(w, h, fs, displayindex));
return 1;
}
@@ -63,12 +77,33 @@ int w_setMode(lua_State *L)
WindowFlags flags;
lua_getfield(L, 3, "fullscreentype");
if (!lua_isnoneornil(L, -1))
{
const char *typestr = luaL_checkstring(L, -1);
if (!Window::getConstant(typestr, flags.fstype))
return luaL_error(L, "Invalid fullscreen type: %s", typestr);
}
else
{
// Default to "normal" fullscreen.
flags.fstype = Window::FULLSCREEN_TYPE_NORMAL;
}
lua_pop(L, 1);
flags.fullscreen = luax_boolflag(L, 3, "fullscreen", false);
flags.vsync = luax_boolflag(L, 3, "vsync", true);
flags.fsaa = luax_intflag(L, 3, "fsaa", 0);
flags.resizable = luax_boolflag(L, 3, "resizable", false);
flags.minwidth = luax_intflag(L, 3, "minwidth", 100);
flags.minheight = luax_intflag(L, 3, "minheight", 100);
flags.borderless = luax_boolflag(L, 3, "borderless", false);
flags.centered = luax_boolflag(L, 3, "centered", true);
flags.display = luax_intflag(L, 3, "display", 1);
// Display index is 1-based in Lua and 0-based internally.
flags.display--;
try
{
@@ -92,38 +127,52 @@ int w_getMode(lua_State *L)
lua_newtable(L);
const char *fstypestr = "normal";
Window::getConstant(flags.fstype, fstypestr);
lua_pushstring(L, fstypestr);
lua_setfield(L, -2, "fullscreentype");
luax_pushboolean(L, flags.fullscreen);
lua_setfield(L, -2, "fullscreen");
luax_pushboolean(L, flags.vsync);
lua_setfield(L, -2, "vsync");
lua_pushnumber(L, flags.fsaa);
lua_pushinteger(L, flags.fsaa);
lua_setfield(L, -2, "fsaa");
luax_pushboolean(L, flags.resizable);
lua_setfield(L, -2, "resizable");
lua_pushinteger(L, flags.minwidth);
lua_setfield(L, -2, "minwidth");
lua_pushinteger(L, flags.minheight);
lua_setfield(L, -2, "minheight");
luax_pushboolean(L, flags.borderless);
lua_setfield(L, -2, "borderless");
luax_pushboolean(L, flags.centered);
lua_setfield(L, -2, "centered");
// Display index is 0-based internally and 1-based in Lua.
lua_pushinteger(L, flags.display + 1);
lua_setfield(L, -2, "display");
return 3;
}
int w_getModes(lua_State *L)
{
int n;
Window::WindowSize *modes = instance->getFullscreenSizes(n);
int displayindex = luaL_optint(L, 1, 1);
if (modes == 0)
return 0;
std::vector<Window::WindowSize> modes = instance->getFullscreenSizes(displayindex - 1);
lua_createtable(L, n, 0);
lua_createtable(L, modes.size(), 0);
for (int i = 0; i < n ; i++)
for (size_t i = 0; i < modes.size(); i++)
{
lua_pushinteger(L, i+1);
lua_createtable(L, 0, 2);
@@ -141,29 +190,43 @@ int w_getModes(lua_State *L)
lua_settable(L, -3);
}
delete[] modes;
return 1;
}
int w_toggleFullscreen(lua_State *L)
int w_setFullscreen(lua_State *L)
{
int width, height;
WindowFlags flags;
instance->getWindow(width, height, flags);
flags.fullscreen = !flags.fullscreen;
bool fullscreen = luax_toboolean(L, 1);
Window::FullscreenType fstype = Window::FULLSCREEN_TYPE_MAX_ENUM;
try
{
luax_pushboolean(L, instance->setWindow(width, height, &flags));
}
catch (love::Exception &e)
{
return luaL_error(L, "%s", e.what());
}
const char *typestr = lua_isnoneornil(L, 2) ? 0 : lua_tostring(L, 2);
if (typestr && !Window::getConstant(typestr, fstype))
return luaL_error(L, "Invalid fullscreen type: %s", typestr);
bool success = false;
if (fstype == Window::FULLSCREEN_TYPE_MAX_ENUM)
success = instance->setFullscreen(fullscreen);
else
success = instance->setFullscreen(fullscreen, fstype);
luax_pushboolean(L, success);
return 1;
}
int w_isFullscreen(lua_State *L)
{
int w, h;
WindowFlags flags;
instance->getWindow(w, h, flags);
const char *typestr;
if (!Window::getConstant(flags.fstype, typestr))
luaL_error(L, "Unknown fullscreen type.");
luax_pushboolean(L, flags.fullscreen);
lua_pushstring(L, typestr);
return 2;
}
int w_isCreated(lua_State *L)
{
luax_pushboolean(L, instance->isCreated());
@@ -189,11 +252,21 @@ int w_getDimensions(lua_State *L)
return 2;
}
int w_getDesktopDimensions(lua_State *L)
{
int width = 0, height = 0;
int displayindex = luaL_optint(L, 1, 1) - 1;
instance->getDesktopDimensions(displayindex, width, height);
lua_pushinteger(L, width);
lua_pushinteger(L, height);
return 2;
}
int w_setIcon(lua_State *L)
{
image::ImageData *i = luax_checktype<image::ImageData>(L, 1, "ImageData", IMAGE_IMAGE_DATA_T);
instance->setIcon(i);
return 0;
luax_pushboolean(L, instance->setIcon(i));
return 1;
}
int w_getIcon(lua_State *L)
@@ -242,15 +315,18 @@ int w_isVisible(lua_State *L)
static const luaL_Reg functions[] =
{
{ "getDisplayCount", w_getDisplayCount },
{ "checkMode", w_checkMode },
{ "setMode", w_setMode },
{ "getMode", w_getMode },
{ "getModes", w_getModes },
{ "toggleFullscreen", w_toggleFullscreen },
{ "setFullscreen", w_setFullscreen },
{ "isFullscreen", w_isFullscreen },
{ "isCreated", w_isCreated },
{ "getWidth", w_getWidth },
{ "getHeight", w_getHeight },
{ "getDimensions", w_getDimensions },
{ "getDesktopDimensions", w_getDesktopDimensions },
{ "setIcon", w_setIcon },
{ "getIcon", w_getIcon },
{ "setTitle", w_setTitle },
@@ -265,7 +341,7 @@ extern "C" int luaopen_love_window(lua_State *L)
{
try
{
instance = sdl::Window::getSingleton();
instance = sdl::Window::createSingleton();
}
catch (love::Exception &e)
{
+4 -1
View File
@@ -29,15 +29,18 @@ namespace love
namespace window
{
int w_getDisplayCount(lua_State *L);
int w_checkMode(lua_State *L);
int w_setMode(lua_State *L);
int w_getMode(lua_State *L);
int w_getModes(lua_State *L);
int w_toggleFullscreen(lua_State *L);
int w_setFullscreen(lua_State *L);
int w_isFullscreen(lua_State *L);
int w_isCreated(lua_State *L);
int w_getWidth(lua_State *L);
int w_getHeight(lua_State *L);
int w_getDimensions(lua_State *L);
int w_getDesktopDimensions(lua_State *L);
int w_setIcon(lua_State *L);
int w_getIcon(lua_State *L);
int w_setTitle(lua_State *L);
+34 -7
View File
@@ -158,6 +158,12 @@ function love.createhandlers()
keyreleased = function (b)
if love.keyreleased then return love.keyreleased(b) end
end,
textinput = function (t)
if love.textinput then return love.textinput(t) end
end,
textedit = function (t,s,l)
if love.textedit then return love.textedit(t,s,l) end
end,
mousepressed = function (x,y,b)
if love.mousepressed then return love.mousepressed(x,y,b) end
end,
@@ -173,9 +179,24 @@ function love.createhandlers()
joystickaxis = function (j,a,v)
if love.joystickaxis then return love.joystickaxis(j,a,v) end
end,
joystickhat = function(j,h,v)
joystickhat = function (j,h,v)
if love.joystickhat then return love.joystickhat(j,h,v) end
end,
gamepadpressed = function (j,b)
if love.gamepadpressed then return love.gamepadpressed(j,b) end
end,
gamepadreleased = function (j,b)
if love.gamepadreleased then return love.gamepadreleased(j,b) end
end,
gamepadaxis = function (j,a,v)
if love.gamepadaxis then return love.gamepadaxis(j,a,v) end
end,
joystickadded = function (j)
if love.joystickadded then return love.joystickadded(j) end
end,
joystickremoved = function(j)
if love.joystickremoved then return love.joystickremoved(j) end
end,
focus = function (f)
if love.focus then return love.focus(f) end
end,
@@ -192,11 +213,7 @@ function love.createhandlers()
if love.threaderror then return love.threaderror(t, err) end
end,
resize = function(w, h)
local ow, oh, flags = love.window.getMode()
if flags.resizable then
love.window.setMode(w, h, flags)
if love.resize then return love.resize(w, h) end
end
if love.resize then return love.resize(w, h) end
end,
}, {
__index = function(self, name)
@@ -266,7 +283,11 @@ function love.init()
window = {
width = 800,
height = 600,
minwidth = 100,
minheight = 100,
fullscreen = false,
fullscreentype = "normal",
display = 1,
vsync = true,
fsaa = 0,
borderless = false,
@@ -285,6 +306,7 @@ function love.init()
math = true,
physics = true,
sound = true,
system = true,
font = true,
thread = true,
window = true,
@@ -322,6 +344,7 @@ function love.init()
"joystick",
"mouse",
"sound",
"system",
"audio",
"image",
"font",
@@ -347,15 +370,19 @@ function love.init()
-- Setup window here.
local has_window = false
if c.window and c.modules.window then
if love.window.checkMode(c.window.width, c.window.height, c.window.fullscreen) or (c.window.width == 0 and c.window.height == 0) then
if love.window.checkMode(c.window.width, c.window.height, c.window.fullscreen, c.window.display) or (c.window.width == 0 and c.window.height == 0) then
assert(love.window.setMode(c.window.width, c.window.height,
{
fullscreen = c.window.fullscreen,
fullscreentype = c.window.fullscreentype,
vsync = c.window.vsync,
fsaa = c.window.fsaa,
resizable = c.window.resizable,
minwidth = c.window.minwidth,
minheight = c.window.minheight,
borderless = c.window.borderless,
centered = c.window.centered,
display = c.window.display,
}), "Could not set window mode")
else
error("Could not set window mode")
+71 -13
View File
@@ -270,6 +270,19 @@ const unsigned char boot_lua[] =
0x6f, 0x76, 0x65, 0x2e, 0x6b, 0x65, 0x79, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x28, 0x62, 0x29,
0x20, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a,
0x09, 0x09, 0x74, 0x65, 0x78, 0x74, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63,
0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x74, 0x29, 0x0a,
0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x69, 0x6e, 0x70,
0x75, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76,
0x65, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x28, 0x74, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a,
0x09, 0x09, 0x74, 0x65, 0x78, 0x74, 0x65, 0x64, 0x69, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x20, 0x28, 0x74, 0x2c, 0x73, 0x2c, 0x6c, 0x29, 0x0a,
0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x74, 0x65, 0x78, 0x74, 0x65, 0x64, 0x69,
0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65,
0x2e, 0x74, 0x65, 0x78, 0x74, 0x65, 0x64, 0x69, 0x74, 0x28, 0x74, 0x2c, 0x73, 0x2c, 0x6c, 0x29, 0x20, 0x65,
0x6e, 0x64, 0x0a,
0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a,
0x09, 0x09, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x66,
0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x78, 0x2c, 0x79, 0x2c, 0x62, 0x29, 0x0a,
0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x70, 0x72,
@@ -306,12 +319,47 @@ const unsigned char boot_lua[] =
0x6a, 0x2c, 0x61, 0x2c, 0x76, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a,
0x09, 0x09, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x68, 0x61, 0x74, 0x20, 0x3d, 0x20, 0x66, 0x75,
0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6a, 0x2c, 0x68, 0x2c, 0x76, 0x29, 0x0a,
0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6a, 0x2c, 0x68, 0x2c, 0x76, 0x29, 0x0a,
0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63,
0x6b, 0x68, 0x61, 0x74, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c,
0x6f, 0x76, 0x65, 0x2e, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x68, 0x61, 0x74, 0x28, 0x6a, 0x2c,
0x68, 0x2c, 0x76, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a,
0x09, 0x09, 0x67, 0x61, 0x6d, 0x65, 0x70, 0x61, 0x64, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x3d,
0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6a, 0x2c, 0x62, 0x29, 0x0a,
0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x61, 0x6d, 0x65, 0x70, 0x61, 0x64,
0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72,
0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x61, 0x6d, 0x65, 0x70, 0x61, 0x64, 0x70, 0x72, 0x65, 0x73,
0x73, 0x65, 0x64, 0x28, 0x6a, 0x2c, 0x62, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a,
0x09, 0x09, 0x67, 0x61, 0x6d, 0x65, 0x70, 0x61, 0x64, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x20,
0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6a, 0x2c, 0x62, 0x29, 0x0a,
0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x61, 0x6d, 0x65, 0x70, 0x61, 0x64,
0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75,
0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x61, 0x6d, 0x65, 0x70, 0x61, 0x64, 0x72, 0x65, 0x6c,
0x65, 0x61, 0x73, 0x65, 0x64, 0x28, 0x6a, 0x2c, 0x62, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a,
0x09, 0x09, 0x67, 0x61, 0x6d, 0x65, 0x70, 0x61, 0x64, 0x61, 0x78, 0x69, 0x73, 0x20, 0x3d, 0x20, 0x66, 0x75,
0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6a, 0x2c, 0x61, 0x2c, 0x76, 0x29, 0x0a,
0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x67, 0x61, 0x6d, 0x65, 0x70, 0x61, 0x64,
0x61, 0x78, 0x69, 0x73, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c,
0x6f, 0x76, 0x65, 0x2e, 0x67, 0x61, 0x6d, 0x65, 0x70, 0x61, 0x64, 0x61, 0x78, 0x69, 0x73, 0x28, 0x6a, 0x2c,
0x61, 0x2c, 0x76, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a,
0x09, 0x09, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x61, 0x64, 0x64, 0x65, 0x64, 0x20, 0x3d, 0x20,
0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x28, 0x6a, 0x29, 0x0a,
0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63,
0x6b, 0x61, 0x64, 0x64, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x61, 0x64, 0x64, 0x65,
0x64, 0x28, 0x6a, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a,
0x09, 0x09, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20,
0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x6a, 0x29, 0x0a,
0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63,
0x6b, 0x72, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x64, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75,
0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x72, 0x65,
0x6d, 0x6f, 0x76, 0x65, 0x64, 0x28, 0x6a, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a,
0x09, 0x09, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x20, 0x28, 0x66, 0x29, 0x0a,
0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x66, 0x6f, 0x63, 0x75, 0x73, 0x20, 0x74,
@@ -344,17 +392,9 @@ const unsigned char boot_lua[] =
0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a,
0x09, 0x09, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f,
0x6e, 0x28, 0x77, 0x2c, 0x20, 0x68, 0x29, 0x0a,
0x09, 0x09, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x20, 0x6f, 0x77, 0x2c, 0x20, 0x6f, 0x68, 0x2c, 0x20, 0x66,
0x6c, 0x61, 0x67, 0x73, 0x20, 0x3d, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77,
0x2e, 0x67, 0x65, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x28, 0x29, 0x0a,
0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x2e, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x61,
0x62, 0x6c, 0x65, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
0x09, 0x09, 0x09, 0x09, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x73, 0x65,
0x74, 0x4d, 0x6f, 0x64, 0x65, 0x28, 0x77, 0x2c, 0x20, 0x68, 0x2c, 0x20, 0x66, 0x6c, 0x61, 0x67, 0x73, 0x29, 0x0a,
0x09, 0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65,
0x20, 0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e,
0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x77, 0x2c, 0x20, 0x68, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x09, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x09, 0x69, 0x66, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x65, 0x20,
0x74, 0x68, 0x65, 0x6e, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6c, 0x6f, 0x76, 0x65, 0x2e, 0x72,
0x65, 0x73, 0x69, 0x7a, 0x65, 0x28, 0x77, 0x2c, 0x20, 0x68, 0x29, 0x20, 0x65, 0x6e, 0x64, 0x0a,
0x09, 0x09, 0x65, 0x6e, 0x64, 0x2c, 0x0a,
0x09, 0x7d, 0x2c, 0x20, 0x7b, 0x0a,
0x09, 0x09, 0x5f, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x20, 0x3d, 0x20, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
@@ -471,8 +511,14 @@ const unsigned char boot_lua[] =
0x09, 0x09, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x7b, 0x0a,
0x09, 0x09, 0x09, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x38, 0x30, 0x30, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x3d, 0x20, 0x36, 0x30, 0x30, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x6d, 0x69, 0x6e, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x31, 0x30, 0x30, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x6d, 0x69, 0x6e, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x3d, 0x20, 0x31, 0x30, 0x30,
0x2c, 0x0a,
0x09, 0x09, 0x09, 0x66, 0x75, 0x6c, 0x6c, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x3d, 0x20, 0x66, 0x61,
0x6c, 0x73, 0x65, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x66, 0x75, 0x6c, 0x6c, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x74, 0x79, 0x70, 0x65, 0x20,
0x3d, 0x20, 0x22, 0x6e, 0x6f, 0x72, 0x6d, 0x61, 0x6c, 0x22, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x3d, 0x20, 0x31, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x76, 0x73, 0x79, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x66, 0x73, 0x61, 0x61, 0x20, 0x3d, 0x20, 0x30, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x6c, 0x65, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x66, 0x61,
@@ -497,6 +543,7 @@ const unsigned char boot_lua[] =
0x09, 0x09, 0x09, 0x6d, 0x61, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x70, 0x68, 0x79, 0x73, 0x69, 0x63, 0x73, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x73, 0x6f, 0x75, 0x6e, 0x64, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x66, 0x6f, 0x6e, 0x74, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x74, 0x68, 0x72, 0x65, 0x61, 0x64, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x3d, 0x20, 0x74, 0x72, 0x75, 0x65, 0x2c, 0x0a,
@@ -553,6 +600,7 @@ const unsigned char boot_lua[] =
0x09, 0x09, 0x22, 0x6a, 0x6f, 0x79, 0x73, 0x74, 0x69, 0x63, 0x6b, 0x22, 0x2c, 0x0a,
0x09, 0x09, 0x22, 0x6d, 0x6f, 0x75, 0x73, 0x65, 0x22, 0x2c, 0x0a,
0x09, 0x09, 0x22, 0x73, 0x6f, 0x75, 0x6e, 0x64, 0x22, 0x2c, 0x0a,
0x09, 0x09, 0x22, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x22, 0x2c, 0x0a,
0x09, 0x09, 0x22, 0x61, 0x75, 0x64, 0x69, 0x6f, 0x22, 0x2c, 0x0a,
0x09, 0x09, 0x22, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x22, 0x2c, 0x0a,
0x09, 0x09, 0x22, 0x66, 0x6f, 0x6e, 0x74, 0x22, 0x2c, 0x0a,
@@ -590,7 +638,8 @@ const unsigned char boot_lua[] =
0x68, 0x65, 0x63, 0x6b, 0x4d, 0x6f, 0x64, 0x65, 0x28, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e,
0x77, 0x69, 0x64, 0x74, 0x68, 0x2c, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x68, 0x65,
0x69, 0x67, 0x68, 0x74, 0x2c, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x66, 0x75, 0x6c,
0x6c, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x28, 0x63, 0x2e, 0x77, 0x69, 0x6e,
0x6c, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x2c, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e,
0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x29, 0x20, 0x6f, 0x72, 0x20, 0x28, 0x63, 0x2e, 0x77, 0x69, 0x6e,
0x64, 0x6f, 0x77, 0x2e, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x3d, 0x20, 0x30, 0x20, 0x61, 0x6e, 0x64,
0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x3d,
0x3d, 0x20, 0x30, 0x29, 0x20, 0x74, 0x68, 0x65, 0x6e, 0x0a,
@@ -602,17 +651,26 @@ const unsigned char boot_lua[] =
0x09, 0x09, 0x09, 0x09, 0x66, 0x75, 0x6c, 0x6c, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x20, 0x3d, 0x20, 0x63,
0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x66, 0x75, 0x6c, 0x6c, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e,
0x2c, 0x0a,
0x09, 0x09, 0x09, 0x09, 0x66, 0x75, 0x6c, 0x6c, 0x73, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x74, 0x79, 0x70, 0x65,
0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x66, 0x75, 0x6c, 0x6c, 0x73, 0x63,
0x72, 0x65, 0x65, 0x6e, 0x74, 0x79, 0x70, 0x65, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x09, 0x76, 0x73, 0x79, 0x6e, 0x63, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64,
0x6f, 0x77, 0x2e, 0x76, 0x73, 0x79, 0x6e, 0x63, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x09, 0x66, 0x73, 0x61, 0x61, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f,
0x77, 0x2e, 0x66, 0x73, 0x61, 0x61, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x09, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x61, 0x62, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0x63, 0x2e,
0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x72, 0x65, 0x73, 0x69, 0x7a, 0x61, 0x62, 0x6c, 0x65, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x09, 0x6d, 0x69, 0x6e, 0x77, 0x69, 0x64, 0x74, 0x68, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77,
0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x6d, 0x69, 0x6e, 0x77, 0x69, 0x64, 0x74, 0x68, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x09, 0x6d, 0x69, 0x6e, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x20, 0x3d, 0x20, 0x63, 0x2e,
0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x6d, 0x69, 0x6e, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x09, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x6c, 0x65, 0x73, 0x73, 0x20, 0x3d, 0x20, 0x63,
0x2e, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x62, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x6c, 0x65, 0x73, 0x73,
0x2c, 0x0a,
0x09, 0x09, 0x09, 0x09, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x64, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77,
0x69, 0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x65, 0x64, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x09, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x20, 0x3d, 0x20, 0x63, 0x2e, 0x77, 0x69,
0x6e, 0x64, 0x6f, 0x77, 0x2e, 0x64, 0x69, 0x73, 0x70, 0x6c, 0x61, 0x79, 0x2c, 0x0a,
0x09, 0x09, 0x09, 0x7d, 0x29, 0x2c, 0x20, 0x22, 0x43, 0x6f, 0x75, 0x6c, 0x64, 0x20, 0x6e, 0x6f, 0x74, 0x20,
0x73, 0x65, 0x74, 0x20, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x22, 0x29, 0x0a,
0x09, 0x09, 0x65, 0x6c, 0x73, 0x65, 0x0a,