summaryrefslogtreecommitdiffstatshomepage
path: root/src/osd/sdl
diff options
context:
space:
mode:
Diffstat (limited to 'src/osd/sdl')
-rw-r--r--src/osd/sdl/SDLMain_tmpl.h13
-rw-r--r--src/osd/sdl/SDLMain_tmpl.mm386
-rw-r--r--src/osd/sdl/input.cpp246
-rw-r--r--src/osd/sdl/osdsdl.h8
-rw-r--r--src/osd/sdl/sdlfile.cpp2
-rw-r--r--src/osd/sdl/sdlinc.h9
-rw-r--r--src/osd/sdl/sdlmain.cpp60
-rw-r--r--src/osd/sdl/sdlos_unix.cpp106
-rw-r--r--src/osd/sdl/testkeys.cpp72
-rw-r--r--src/osd/sdl/video.cpp237
-rw-r--r--src/osd/sdl/video.h14
-rw-r--r--src/osd/sdl/window.cpp198
-rw-r--r--src/osd/sdl/window.h25
13 files changed, 1339 insertions, 37 deletions
diff --git a/src/osd/sdl/SDLMain_tmpl.h b/src/osd/sdl/SDLMain_tmpl.h
new file mode 100644
index 00000000000..c5ad2a346dd
--- /dev/null
+++ b/src/osd/sdl/SDLMain_tmpl.h
@@ -0,0 +1,13 @@
+// license:Zlib|LGPL-2.1+
+// copyright-holders:http://libsdl.org/
+/* 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>
+
+@interface SDLMain : NSObject
+@end
diff --git a/src/osd/sdl/SDLMain_tmpl.mm b/src/osd/sdl/SDLMain_tmpl.mm
new file mode 100644
index 00000000000..78b5d7f4937
--- /dev/null
+++ b/src/osd/sdl/SDLMain_tmpl.mm
@@ -0,0 +1,386 @@
+// license:Zlib|LGPL-2.1+
+// copyright-holders:http://libsdl.org/
+/* 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 "sdlinc.h"
+#import "SDLMain_tmpl.h"
+#import <sys/param.h> /* for MAXPATHLEN */
+#import <unistd.h>
+
+/* For some reason, Apple removed setAppleMenu from the headers in 10.4,
+ but the method still is there and works. To avoid warnings, we declare
+ it ourselves here. */
+@interface NSApplication(SDL_Missing_Methods)
+- (void)setAppleMenu:(NSMenu *)menu;
+@end
+
+/* 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 */
+#define SDL_USE_CPS 0
+#ifdef SDL_USE_CPS
+/* Portions of CPS.h */
+typedef struct CPSProcessSerNum
+{
+ UInt32 lo;
+ UInt32 hi;
+} CPSProcessSerNum;
+
+extern "C" OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn);
+extern "C" OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
+extern "C" 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);
+}
+@end
+
+/* The main class of the application, the application's delegate */
+@implementation SDLMain
+
+/* Set the working directory to the .app's parent directory */
+- (void) setupWorkingDirectory:(BOOL)shouldChdir
+{
+ if (shouldChdir)
+ {
+ char parentdir[MAXPATHLEN];
+ CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
+ CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url);
+ if (CFURLGetFileSystemRepresentation(url2, true, (UInt8 *)parentdir, MAXPATHLEN)) {
+ assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */
+ }
+ CFRelease(url);
+ CFRelease(url2);
+ }
+
+}
+
+#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];
+
+ /* Tell the application object that this is now the application menu */
+ [NSApp setAppleMenu:appleMenu];
+
+ /* 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];
+ }
+#endif /* SDL_USE_CPS */
+
+ /* Set up the menubar */
+ [NSApp setMainMenu:[[NSMenu alloc] init]];
+ 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;
+
+ 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 **) SDL_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 parent directory */
+ [self setupWorkingDirectory:gFinderLaunch];
+
+#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
+
+ /* 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 = (unichar *)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;
+ }
+
+#if SDL_USE_NIB_FILE
+ [SDLApplication poseAsClass:[NSApplication class]];
+ NSApplicationMain (argc, argv);
+#else
+ CustomApplicationMain (argc, argv);
+#endif
+ return 0;
+}
+
diff --git a/src/osd/sdl/input.cpp b/src/osd/sdl/input.cpp
index 9cfcdb1cf16..4dfb5bd0ad0 100644
--- a/src/osd/sdl/input.cpp
+++ b/src/osd/sdl/input.cpp
@@ -15,7 +15,6 @@
#include "sdlinc.h"
#include <ctype.h>
#include <stddef.h>
-#include <mutex>
#if USE_XINPUT
// for xinput
@@ -155,7 +154,7 @@ struct device_info
//============================================================
// global states
-static std::mutex input_lock;
+static osd_lock * input_lock;
static UINT8 input_paused;
static sdl_window_info * focus_window = NULL;
@@ -235,6 +234,7 @@ struct kt_table {
char * ui_name;
};
+#if (SDLMAME_SDL2)
#define OSD_SDL_INDEX(x) (x)
#define OSD_SDL_INDEX_KEYSYM(keysym) ((keysym)->scancode)
@@ -364,6 +364,132 @@ static kt_table sdl_key_trans_table[] =
KTT_ENTRY0( BACKSLASH2, NONUSBACKSLASH, 0xdc, '\\', "BACKSLASH2" ),
{ ITEM_ID_INVALID }
};
+#else
+
+#define OSD_SDL_INDEX(x) (SDLK_INDEX(x)-SDLK_FIRST)
+#define OSD_SDL_INDEX_KEYSYM(keysym) (OSD_SDL_INDEX((keysym)->sym))
+#define GET_WINDOW(ev) sdl_window_list
+#define GET_FOCUS_WINDOW(ev) sdl_window_list
+
+#define KTT_ENTRY0(MAME, SDL, VK, AS, UI) { ITEM_ID_ ## MAME, SDLK_ ## SDL, "ITEM_ID_" #MAME, (char *) UI }
+#define KTT_ENTRY1(MAME, SDL) KTT_ENTRY0(MAME, SDL, MAME, MAME, #MAME)
+// only for reference ...
+#define KTT_ENTRY2(MAME, SDL) KTT_ENTRY0(MAME, SDL, 0, 0, #MAME)
+
+
+static kt_table sdl_key_trans_table[] =
+{
+ // MAME key SDL key vkey ascii
+ KTT_ENTRY0( ESC, ESCAPE, 0x1b, 0x1b, "ESC" ),
+ KTT_ENTRY1( 1, 1 ),
+ KTT_ENTRY1( 2, 2 ),
+ KTT_ENTRY1( 3, 3 ),
+ KTT_ENTRY1( 4, 4 ),
+ KTT_ENTRY1( 5, 5 ),
+ KTT_ENTRY1( 6, 6 ),
+ KTT_ENTRY1( 7, 7 ),
+ KTT_ENTRY1( 8, 8 ),
+ KTT_ENTRY1( 9, 9 ),
+ KTT_ENTRY1( 0, 0 ),
+ KTT_ENTRY0( MINUS, MINUS, 0xbd, '-', "MINUS" ),
+ KTT_ENTRY0( EQUALS, EQUALS, 0xbb, '=', "EQUALS" ),
+ KTT_ENTRY0( BACKSPACE, BACKSPACE, 0x08, 0x08, "BACKSPACE" ),
+ KTT_ENTRY0( TAB, TAB, 0x09, 0x09, "TAB" ),
+ KTT_ENTRY1( Q, q ),
+ KTT_ENTRY1( W, w ),
+ KTT_ENTRY1( E, e ),
+ KTT_ENTRY1( R, r ),
+ KTT_ENTRY1( T, t ),
+ KTT_ENTRY1( Y, y ),
+ KTT_ENTRY1( U, u ),
+ KTT_ENTRY1( I, i ),
+ KTT_ENTRY1( O, o ),
+ KTT_ENTRY1( P, p ),
+ KTT_ENTRY0( OPENBRACE, LEFTBRACKET, 0xdb, '[', "OPENBRACE" ),
+ KTT_ENTRY0( CLOSEBRACE,RIGHTBRACKET, 0xdd, ']', "CLOSEBRACE" ),
+ KTT_ENTRY0( ENTER, RETURN, 0x0d, 0x0d, "RETURN" ),
+ KTT_ENTRY2( LCONTROL, LCTRL ),
+ KTT_ENTRY1( A, a ),
+ KTT_ENTRY1( S, s ),
+ KTT_ENTRY1( D, d ),
+ KTT_ENTRY1( F, f ),
+ KTT_ENTRY1( G, g ),
+ KTT_ENTRY1( H, h ),
+ KTT_ENTRY1( J, j ),
+ KTT_ENTRY1( K, k ),
+ KTT_ENTRY1( L, l ),
+ KTT_ENTRY0( COLON, SEMICOLON, 0xba, ';', "COLON" ),
+ KTT_ENTRY0( QUOTE, QUOTE, 0xde, '\'', "QUOTE" ),
+ KTT_ENTRY2( LSHIFT, LSHIFT ),
+ KTT_ENTRY0( BACKSLASH, BACKSLASH, 0xdc, '\\', "BACKSLASH" ),
+ KTT_ENTRY1( Z, z ),
+ KTT_ENTRY1( X, x ),
+ KTT_ENTRY1( C, c ),
+ KTT_ENTRY1( V, v ),
+ KTT_ENTRY1( B, b ),
+ KTT_ENTRY1( N, n ),
+ KTT_ENTRY1( M, m ),
+ KTT_ENTRY0( COMMA, COMMA, 0xbc, ',', "COMMA" ),
+ KTT_ENTRY0( STOP, PERIOD, 0xbe, '.', "STOP" ),
+ KTT_ENTRY0( SLASH, SLASH, 0xbf, '/', "SLASH" ),
+ KTT_ENTRY2( RSHIFT, RSHIFT ),
+ KTT_ENTRY0( ASTERISK, KP_MULTIPLY, '*', '*', "ASTERIX" ),
+ KTT_ENTRY2( LALT, LALT ),
+ KTT_ENTRY0( SPACE, SPACE, ' ', ' ', "SPACE" ),
+ KTT_ENTRY2( CAPSLOCK, CAPSLOCK ),
+ KTT_ENTRY2( F1, F1 ),
+ KTT_ENTRY2( F2, F2 ),
+ KTT_ENTRY2( F3, F3 ),
+ KTT_ENTRY2( F4, F4 ),
+ KTT_ENTRY2( F5, F5 ),
+ KTT_ENTRY2( F6, F6 ),
+ KTT_ENTRY2( F7, F7 ),
+ KTT_ENTRY2( F8, F8 ),
+ KTT_ENTRY2( F9, F9 ),
+ KTT_ENTRY2( F10, F10 ),
+ KTT_ENTRY2( NUMLOCK, NUMLOCK ),
+ KTT_ENTRY2( SCRLOCK, SCROLLOCK ),
+ KTT_ENTRY2( 7_PAD, KP7 ),
+ KTT_ENTRY2( 8_PAD, KP8 ),
+ KTT_ENTRY2( 9_PAD, KP9 ),
+ KTT_ENTRY2( MINUS_PAD, KP_MINUS ),
+ KTT_ENTRY2( 4_PAD, KP4 ),
+ KTT_ENTRY2( 5_PAD, KP5 ),
+ KTT_ENTRY2( 6_PAD, KP6 ),
+ KTT_ENTRY2( PLUS_PAD, KP_PLUS ),
+ KTT_ENTRY2( 1_PAD, KP1 ),
+ KTT_ENTRY2( 2_PAD, KP2 ),
+ KTT_ENTRY2( 3_PAD, KP3 ),
+ KTT_ENTRY2( 0_PAD, KP0 ),
+ KTT_ENTRY2( DEL_PAD, KP_PERIOD ),
+ KTT_ENTRY2( F11, F11 ),
+ KTT_ENTRY2( F12, F12 ),
+ KTT_ENTRY2( F13, F13 ),
+ KTT_ENTRY2( F14, F14 ),
+ KTT_ENTRY2( F15, F15 ),
+ KTT_ENTRY2( ENTER_PAD, KP_ENTER ),
+ KTT_ENTRY2( RCONTROL, RCTRL ),
+ KTT_ENTRY2( SLASH_PAD, KP_DIVIDE ),
+ KTT_ENTRY2( PRTSCR, PRINT ),
+ KTT_ENTRY2( RALT, RALT ),
+ KTT_ENTRY2( HOME, HOME ),
+ KTT_ENTRY2( UP, UP ),
+ KTT_ENTRY2( PGUP, PAGEUP ),
+ KTT_ENTRY2( LEFT, LEFT ),
+ KTT_ENTRY2( RIGHT, RIGHT ),
+ KTT_ENTRY2( END, END ),
+ KTT_ENTRY2( DOWN, DOWN ),
+ KTT_ENTRY2( PGDN, PAGEDOWN ),
+ KTT_ENTRY2( INSERT, INSERT ),
+ { ITEM_ID_DEL, SDLK_DELETE, "ITEM_ID_DEL", (char *)"DELETE" },
+ KTT_ENTRY2( LWIN, LSUPER ),
+ KTT_ENTRY2( RWIN, RSUPER ),
+ KTT_ENTRY2( MENU, MENU ),
+ KTT_ENTRY0( TILDE, BACKQUOTE, 0xc0, '`', "TILDE" ),
+ KTT_ENTRY0( BACKSLASH2, HASH, 0xdc, '\\', "BACKSLASH2" ),
+ { ITEM_ID_INVALID }
+};
+#endif
struct key_lookup_table
{
@@ -371,6 +497,7 @@ struct key_lookup_table
const char *name;
};
+#if (SDLMAME_SDL2)
#define KE(x) { SDL_SCANCODE_ ## x, "SDL_SCANCODE_" #x },
#define KE8(A, B, C, D, E, F, G, H) KE(A) KE(B) KE(C) KE(D) KE(E) KE(F) KE(G) KE(H)
#define KE7(A, B, C, D, E, F, G) KE(A) KE(B) KE(C) KE(D) KE(E) KE(F) KE(G)
@@ -399,6 +526,46 @@ static key_lookup_table sdl_lookup_table[] =
KE(UNDO)
{-1, ""}
};
+#else
+#define KE(x) { SDLK_ ## x, "SDLK_" #x },
+#define KE8(A, B, C, D, E, F, G, H) KE(A) KE(B) KE(C) KE(D) KE(E) KE(F) KE(G) KE(H)
+
+static key_lookup_table sdl_lookup_table[] =
+{
+ KE8(UNKNOWN, FIRST, BACKSPACE, TAB, CLEAR, RETURN, PAUSE, ESCAPE )
+ KE8(SPACE, EXCLAIM, QUOTEDBL, HASH, DOLLAR, AMPERSAND, QUOTE, LEFTPAREN )
+ KE8(RIGHTPAREN, ASTERISK, PLUS, COMMA, MINUS, PERIOD, SLASH, 0 )
+ KE8(1, 2, 3, 4, 5, 6, 7, 8 )
+ KE8(9, COLON, SEMICOLON, LESS, EQUALS, GREATER, QUESTION, AT )
+ KE8(LEFTBRACKET,BACKSLASH, RIGHTBRACKET, CARET, UNDERSCORE, BACKQUOTE, a, b )
+ KE8(c, d, e, f, g, h, i, j )
+ KE8(k, l, m, n, o, p, q, r )
+ KE8(s, t, u, v, w, x, y, z )
+ KE8(DELETE, WORLD_0, WORLD_1, WORLD_2, WORLD_3, WORLD_4, WORLD_5, WORLD_6 )
+ KE8(WORLD_7, WORLD_8, WORLD_9, WORLD_10, WORLD_11, WORLD_12, WORLD_13, WORLD_14 )
+ KE8(WORLD_15, WORLD_16, WORLD_17, WORLD_18, WORLD_19, WORLD_20, WORLD_21, WORLD_22 )
+ KE8(WORLD_23, WORLD_24, WORLD_25, WORLD_26, WORLD_27, WORLD_28, WORLD_29, WORLD_30 )
+ KE8(WORLD_31, WORLD_32, WORLD_33, WORLD_34, WORLD_35, WORLD_36, WORLD_37, WORLD_38 )
+ KE8(WORLD_39, WORLD_40, WORLD_41, WORLD_42, WORLD_43, WORLD_44, WORLD_45, WORLD_46 )
+ KE8(WORLD_47, WORLD_48, WORLD_49, WORLD_50, WORLD_51, WORLD_52, WORLD_53, WORLD_54 )
+ KE8(WORLD_55, WORLD_56, WORLD_57, WORLD_58, WORLD_59, WORLD_60, WORLD_61, WORLD_62 )
+ KE8(WORLD_63, WORLD_64, WORLD_65, WORLD_66, WORLD_67, WORLD_68, WORLD_69, WORLD_70 )
+ KE8(WORLD_71, WORLD_72, WORLD_73, WORLD_74, WORLD_75, WORLD_76, WORLD_77, WORLD_78 )
+ KE8(WORLD_79, WORLD_80, WORLD_81, WORLD_82, WORLD_83, WORLD_84, WORLD_85, WORLD_86 )
+ KE8(WORLD_87, WORLD_88, WORLD_89, WORLD_90, WORLD_91, WORLD_92, WORLD_93, WORLD_94 )
+ KE8(WORLD_95, KP0, KP1, KP2, KP3, KP4, KP5, KP6 )
+ KE8(KP7, KP8, KP9, KP_PERIOD, KP_DIVIDE, KP_MULTIPLY,KP_MINUS, KP_PLUS )
+ KE8(KP_ENTER, KP_EQUALS, UP, DOWN, RIGHT, LEFT, INSERT, HOME )
+ KE8(END, PAGEUP, PAGEDOWN, F1, F2, F3, F4, F5 )
+ KE8(F6, F7, F8, F9, F10, F11, F12, F13 )
+ KE8(F14, F15, NUMLOCK, CAPSLOCK, SCROLLOCK, RSHIFT, LSHIFT, RCTRL )
+ KE8(LCTRL, RALT, LALT, RMETA, LMETA, LSUPER, RSUPER, MODE )
+ KE8(COMPOSE, HELP, PRINT, SYSREQ, BREAK, MENU, POWER, EURO )
+ KE(UNDO)
+ KE(LAST)
+ {-1, ""}
+};
+#endif
//============================================================
// INLINE FUNCTIONS
@@ -550,9 +717,14 @@ static void sdlinput_register_joysticks(running_machine &machine)
{
char *joy_name;
+#if (SDLMAME_SDL2)
joy = SDL_JoystickOpen(physical_stick);
joy_name = remove_spaces(machine, SDL_JoystickName(joy));
SDL_JoystickClose(joy);
+#else
+ joy_name = remove_spaces(machine, SDL_JoystickName(physical_stick));
+#endif
+
devmap_register(&joy_map, physical_stick, joy_name);
}
@@ -1068,7 +1240,7 @@ static kt_table * sdlinput_read_keymap(running_machine &machine)
{
sdl2section = 1;
}
- else if (((1) ^ sdl2section) == 0)
+ else if (((SDLMAME_SDL2) ^ sdl2section) == 0)
{
mks[0]=0;
sks[0]=0;
@@ -1208,6 +1380,10 @@ bool sdl_osd_interface::input_init()
app_has_mouse_focus = 1;
+ // allocate a lock for input synchronizations
+ input_lock = osd_lock_alloc();
+ assert_always(input_lock != NULL, "Failed to allocate input_lock");
+
// register the keyboards
sdlinput_register_keyboards(machine());
@@ -1265,6 +1441,9 @@ void sdl_osd_interface::input_resume()
void sdl_osd_interface::input_exit()
{
+ // free the lock
+ osd_lock_free(input_lock);
+
// deregister
sdlinput_deregister_joysticks(machine());
@@ -1345,6 +1524,7 @@ INT32 normalize_absolute_axis(INT32 raw, INT32 rawmin, INT32 rawmax)
// sdlinput_poll
//============================================================
+#if (SDLMAME_SDL2)
static inline sdl_window_info * window_from_id(Uint32 windowID)
{
sdl_window_info *w;
@@ -1380,15 +1560,19 @@ static inline void resize_all_windows(void)
}
}
+#endif
+
void sdlinput_process_events_buf()
{
SDL_Event event;
if (SDLMAME_EVENTS_IN_WORKER_THREAD)
{
- std::lock_guard<std::mutex> lock(input_lock);
+ osd_lock_acquire(input_lock);
+ #if (SDLMAME_SDL2)
/* Make sure we get all pending events */
SDL_PumpEvents();
+ #endif
while(SDL_PollEvent(&event))
{
if (event_buf_count < MAX_BUF_EVENTS)
@@ -1396,6 +1580,7 @@ void sdlinput_process_events_buf()
else
osd_printf_warning("Event Buffer Overflow!\n");
}
+ osd_lock_release(input_lock);
}
else
SDL_PumpEvents();
@@ -1524,10 +1709,11 @@ void sdlinput_poll(running_machine &machine)
if (SDLMAME_EVENTS_IN_WORKER_THREAD)
{
- std::lock_guard<std::mutex> lock(input_lock);
+ osd_lock_acquire(input_lock);
memcpy(loc_event_buf, event_buf, sizeof(event_buf));
loc_event_buf_count = event_buf_count;
event_buf_count = 0;
+ osd_lock_release(input_lock);
bufp = 0;
}
@@ -1553,8 +1739,12 @@ void sdlinput_poll(running_machine &machine)
devinfo = generic_device_find_index( keyboard_list, keyboard_map.logical[0]);
#endif
devinfo->keyboard.state[OSD_SDL_INDEX_KEYSYM(&event.key.keysym)] = 0x80;
+#if (SDLMAME_SDL2)
if (event.key.keysym.sym < 0x20)
machine.ui_input().push_char_event(sdl_window_list->target(), event.key.keysym.sym);
+#else
+ ui_input_push_char_event(machine, sdl_window_list->target(), (unicode_char) event.key.keysym.unicode);
+#endif
break;
case SDL_KEYUP:
#ifdef SDL2_MULTIAPI
@@ -1673,19 +1863,6 @@ void sdlinput_poll(running_machine &machine)
}
}
break;
- case SDL_MOUSEWHEEL:
-#ifdef SDL2_MULTIAPI
- devinfo = generic_device_find_index(mouse_list, mouse_map.logical[event.wheel.which]);
-#else
- devinfo = generic_device_find_index(mouse_list, mouse_map.logical[0]);
-#endif
- if (devinfo)
- {
- sdl_window_info *window = GET_FOCUS_WINDOW(&event.wheel);
- if (window != NULL)
- machine.ui_input().push_mouse_wheel_event(window->target(), 0, 0, event.wheel.y, 3);
- }
- break;
case SDL_MOUSEBUTTONUP:
#ifdef SDL2_MULTIAPI
devinfo = generic_device_find_index(mouse_list, mouse_map.logical[event.button.which]);
@@ -1712,10 +1889,15 @@ void sdlinput_poll(running_machine &machine)
#else
devinfo = generic_device_find_index(mouse_list, mouse_map.logical[0]);
#endif
+#if (SDLMAME_SDL2)
// FIXME: may apply to 1.2 as well ...
//printf("Motion %d %d %d %s\n", event.motion.which, event.motion.x, event.motion.y, devinfo->name.c_str());
devinfo->mouse.lX += event.motion.xrel * INPUT_RELATIVE_PER_PIXEL;
devinfo->mouse.lY += event.motion.yrel * INPUT_RELATIVE_PER_PIXEL;
+#else
+ devinfo->mouse.lX = event.motion.xrel * INPUT_RELATIVE_PER_PIXEL;
+ devinfo->mouse.lY = event.motion.yrel * INPUT_RELATIVE_PER_PIXEL;
+#endif
{
int cx=-1, cy=-1;
sdl_window_info *window = GET_FOCUS_WINDOW(&event.motion);
@@ -1730,6 +1912,22 @@ void sdlinput_poll(running_machine &machine)
devinfo->joystick.balls[event.jball.ball * 2] = event.jball.xrel * INPUT_RELATIVE_PER_PIXEL;
devinfo->joystick.balls[event.jball.ball * 2 + 1] = event.jball.yrel * INPUT_RELATIVE_PER_PIXEL;
break;
+#if (!SDLMAME_SDL2)
+ case SDL_APPMOUSEFOCUS:
+ app_has_mouse_focus = event.active.gain;
+ if (!event.active.gain)
+ {
+ sdl_window_info *window = GET_FOCUS_WINDOW(&event.motion);
+ ui_input_push_mouse_leave_event(machine, window->target());
+ }
+ break;
+ case SDL_QUIT:
+ machine.schedule_exit();
+ break;
+ case SDL_VIDEORESIZE:
+ sdl_window_list->resize(event.resize.w, event.resize.h);
+ break;
+#else
case SDL_TEXTINPUT:
if (*event.text.text)
{
@@ -1780,8 +1978,8 @@ void sdlinput_poll(running_machine &machine)
#endif
{
//printf("event data1,data2 %d x %d %ld\n", event.window.data1, event.window.data2, sizeof(SDL_Event));
- window->resize(event.window.data1, event.window.data2);
- }
+ window->resize(event.window.data1, event.window.data2);
+ }
}
focus_window = window;
break;
@@ -1797,9 +1995,12 @@ void sdlinput_poll(running_machine &machine)
}
break;
}
+#endif
}
}
+#if (SDLMAME_SDL2)
resize_all_windows();
+#endif
}
@@ -1810,6 +2011,10 @@ void sdlinput_poll(running_machine &machine)
void sdlinput_release_keys()
{
+ // FIXME: SDL >= 1.3 will nuke the window event buffer when
+ // a window is closed. This will leave keys in a pressed
+ // state when a window is destroyed and recreated.
+#if (SDLMAME_SDL2)
device_info *devinfo;
int index;
@@ -1820,6 +2025,7 @@ void sdlinput_release_keys()
break;
memset(&devinfo->keyboard.state, 0, sizeof(devinfo->keyboard.state));
}
+#endif
}
diff --git a/src/osd/sdl/osdsdl.h b/src/osd/sdl/osdsdl.h
index bca299eb49d..e82c75406cc 100644
--- a/src/osd/sdl/osdsdl.h
+++ b/src/osd/sdl/osdsdl.h
@@ -17,9 +17,15 @@
#if defined(SDLMAME_WIN32)
+ #if (SDLMAME_SDL2)
#define SDLMAME_EVENTS_IN_WORKER_THREAD (0)
#define SDLMAME_INIT_IN_WORKER_THREAD (0)
#define SDL13_COMBINE_RESIZE (0) //(1) no longer needed
+ #else
+ #define SDLMAME_EVENTS_IN_WORKER_THREAD (0)
+ #define SDLMAME_INIT_IN_WORKER_THREAD (1)
+ #define SDL13_COMBINE_RESIZE (0)
+ #endif
#else
#define SDLMAME_EVENTS_IN_WORKER_THREAD (0)
#define SDLMAME_INIT_IN_WORKER_THREAD (0)
@@ -116,8 +122,10 @@ public:
const char *joy_index(int index) const { return value(strformat("%s%d", SDLOPTION_JOYINDEX, index).c_str()); }
bool sixaxis() const { return bool_value(SDLOPTION_SIXAXIS); }
+#if (SDLMAME_SDL2)
const char *mouse_index(int index) const { return value(strformat("%s%d", SDLOPTION_MOUSEINDEX, index).c_str()); }
const char *keyboard_index(int index) const { return value(strformat("%s%d", SDLOPTION_KEYBINDEX, index).c_str()); }
+#endif
const char *video_driver() const { return value(SDLOPTION_VIDEODRIVER); }
const char *render_driver() const { return value(SDLOPTION_RENDERDRIVER); }
diff --git a/src/osd/sdl/sdlfile.cpp b/src/osd/sdl/sdlfile.cpp
index 1f6832b03dd..b6088c8aa54 100644
--- a/src/osd/sdl/sdlfile.cpp
+++ b/src/osd/sdl/sdlfile.cpp
@@ -134,8 +134,6 @@ file_error osd_open(const char *path, UINT32 openflags, osd_file **file, UINT64
{
(*file)->type = SDLFILE_SOCKET;
filerr = sdl_open_socket(path, openflags, file, filesize);
- if(filerr != FILERR_NONE && (*file)->socket != -1)
- close((*file)->socket);
goto error;
}
diff --git a/src/osd/sdl/sdlinc.h b/src/osd/sdl/sdlinc.h
index 47ead42c0cf..2bb5dfd0954 100644
--- a/src/osd/sdl/sdlinc.h
+++ b/src/osd/sdl/sdlinc.h
@@ -3,11 +3,20 @@
#ifndef _sdlinc_h_
#define _sdlinc_h_
+#if (SDLMAME_SDL2)
#include <SDL2/SDL.h>
#include <SDL2/SDL_version.h>
// on win32 this includes windows.h by itself and breaks us!
#ifndef SDLMAME_WIN32
#include <SDL2/SDL_syswm.h>
#endif
+#else
+#include <SDL/SDL.h>
+#include <SDL/SDL_version.h>
+// on win32 this includes windows.h by itself and breaks us!
+#if !defined(SDLMAME_WIN32) && !defined(SDLMAME_DARWIN) && !defined(SDLMAME_MACOSX)
+#include <SDL/SDL_syswm.h>
+#endif
+#endif
#endif
diff --git a/src/osd/sdl/sdlmain.cpp b/src/osd/sdl/sdlmain.cpp
index 530aa41c9d4..2f382605cbb 100644
--- a/src/osd/sdl/sdlmain.cpp
+++ b/src/osd/sdl/sdlmain.cpp
@@ -101,7 +101,11 @@ const options_entry sdl_options::s_option_entries[] =
// OS X can be trusted to have working hardware OpenGL, so default to it on for the best user experience
{ SDLOPTION_CENTERH, "1", OPTION_BOOLEAN, "center horizontally within the view area" },
{ SDLOPTION_CENTERV, "1", OPTION_BOOLEAN, "center vertically within the view area" },
+#if (SDLMAME_SDL2)
{ SDLOPTION_SCALEMODE ";sm", OSDOPTVAL_NONE, OPTION_STRING, "Scale mode: none, hwblit, hwbest, yv12, yuy2, yv12x2, yuy2x2 (-video soft only)" },
+#else
+ { SDLOPTION_SCALEMODE ";sm", OSDOPTVAL_NONE, OPTION_STRING, "Scale mode: none, async, yv12, yuy2, yv12x2, yuy2x2 (-video soft only)" },
+#endif
// full screen options
#ifdef SDLMAME_X11
@@ -139,6 +143,7 @@ const options_entry sdl_options::s_option_entries[] =
{ SDLOPTION_LIGHTGUNINDEX "8", OSDOPTVAL_AUTO, OPTION_STRING, "name of lightgun mapped to lightgun #8" },
#endif
+#if (SDLMAME_SDL2)
{ NULL, NULL, OPTION_HEADER, "SDL MOUSE MAPPING" },
{ SDLOPTION_MOUSEINDEX "1", OSDOPTVAL_AUTO, OPTION_STRING, "name of mouse mapped to mouse #1" },
{ SDLOPTION_MOUSEINDEX "2", OSDOPTVAL_AUTO, OPTION_STRING, "name of mouse mapped to mouse #2" },
@@ -158,11 +163,13 @@ const options_entry sdl_options::s_option_entries[] =
{ SDLOPTION_KEYBINDEX "6", OSDOPTVAL_AUTO, OPTION_STRING, "name of keyboard mapped to keyboard #6" },
{ SDLOPTION_KEYBINDEX "7", OSDOPTVAL_AUTO, OPTION_STRING, "name of keyboard mapped to keyboard #7" },
{ SDLOPTION_KEYBINDEX "8", OSDOPTVAL_AUTO, OPTION_STRING, "name of keyboard mapped to keyboard #8" },
-
+#endif
// SDL low level driver options
{ NULL, NULL, OPTION_HEADER, "SDL LOWLEVEL DRIVER OPTIONS" },
{ SDLOPTION_VIDEODRIVER ";vd", OSDOPTVAL_AUTO, OPTION_STRING, "sdl video driver to use ('x11', 'directfb', ... or 'auto' for SDL default" },
+#if (SDLMAME_SDL2)
{ SDLOPTION_RENDERDRIVER ";rd", OSDOPTVAL_AUTO, OPTION_STRING, "sdl render driver to use ('software', 'opengl', 'directfb' ... or 'auto' for SDL default" },
+#endif
{ SDLOPTION_AUDIODRIVER ";ad", OSDOPTVAL_AUTO, OPTION_STRING, "sdl audio driver to use ('alsa', 'arts', ... or 'auto' for SDL default" },
#if USE_OPENGL
{ SDLOPTION_GL_LIB, SDLOPTVAL_GLLIB, OPTION_STRING, "alternative libGL.so to use; 'auto' for system default" },
@@ -218,6 +225,21 @@ int main(int argc, char *argv[])
{
int res = 0;
+#if defined(SDLMAME_X11) && !(SDLMAME_SDL2)
+ XInitThreads();
+#endif
+
+#if defined(SDLMAME_WIN32)
+#if !(SDLMAME_SDL2)
+ /* Load SDL dynamic link library */
+ if ( SDL_Init(SDL_INIT_NOPARACHUTE) < 0 ) {
+ fprintf(stderr, "WinMain() error: %s", SDL_GetError());
+ return(FALSE);
+ }
+ SDL_SetModuleHandle(GetModuleHandle(NULL));
+#endif
+#endif
+
// disable I/O buffering
setvbuf(stdout, (char *) NULL, _IONBF, 0);
setvbuf(stderr, (char *) NULL, _IONBF, 0);
@@ -235,6 +257,25 @@ int main(int argc, char *argv[])
MorphToPM();
#endif
+#if defined(SDLMAME_X11) && (SDL_MAJOR_VERSION == 1) && (SDL_MINOR_VERSION == 2)
+ if (SDL_Linked_Version()->patch < 10)
+ /* workaround for SDL choosing a 32-bit ARGB visual */
+ {
+ Display *display;
+ if ((display = XOpenDisplay(NULL)) && (DefaultDepth(display, DefaultScreen(display)) >= 24))
+ {
+ XVisualInfo vi;
+ char buf[130];
+ if (XMatchVisualInfo(display, DefaultScreen(display), 24, TrueColor, &vi)) {
+ snprintf(buf, sizeof(buf), "0x%lx", vi.visualid);
+ osd_setenv(SDLENV_VISUALID, buf, 0);
+ }
+ }
+ if (display)
+ XCloseDisplay(display);
+ }
+#endif
+
{
sdl_options options;
sdl_osd_interface osd(options);
@@ -299,7 +340,11 @@ void sdl_osd_interface::osd_exit()
if (!SDLMAME_INIT_IN_WORKER_THREAD)
{
/* FixMe: Bug in SDL2.0, Quitting joystick will cause SIGSEGV */
+#if SDLMAME_SDL2
SDL_QuitSubSystem(SDL_INIT_TIMER| SDL_INIT_VIDEO /*| SDL_INIT_JOYSTICK */);
+#else
+ SDL_Quit();
+#endif
}
}
@@ -374,6 +419,7 @@ static void defines_verbose(void)
static void osd_sdl_info(void)
{
+#if SDLMAME_SDL2
int i, num = SDL_GetNumVideoDrivers();
osd_printf_verbose("Available videodrivers: ");
@@ -410,6 +456,8 @@ static void osd_sdl_info(void)
{
osd_printf_verbose("\t%-20s\n", SDL_GetAudioDriver(i));
}
+
+#endif
}
@@ -464,6 +512,7 @@ void sdl_osd_interface::init(running_machine &machine)
osd_setenv(SDLENV_VIDEODRIVER, stemp, 1);
}
+#if (SDLMAME_SDL2)
stemp = options().render_driver();
if (stemp != NULL)
{
@@ -483,6 +532,7 @@ void sdl_osd_interface::init(running_machine &machine)
#endif
}
}
+#endif
/* Set the SDL environment variable for drivers wanting to load the
* lib at startup.
@@ -517,12 +567,16 @@ void sdl_osd_interface::init(running_machine &machine)
if (!SDLMAME_INIT_IN_WORKER_THREAD)
{
+#if (SDLMAME_SDL2)
#ifdef SDLMAME_EMSCRIPTEN
// timer brings in threads which are not supported in Emscripten
if (SDL_InitSubSystem(SDL_INIT_VIDEO| SDL_INIT_JOYSTICK|SDL_INIT_NOPARACHUTE)) {
#else
if (SDL_InitSubSystem(SDL_INIT_TIMER| SDL_INIT_VIDEO| SDL_INIT_JOYSTICK|SDL_INIT_NOPARACHUTE)) {
#endif
+#else
+ if (SDL_Init(SDL_INIT_TIMER|SDL_INIT_VIDEO| SDL_INIT_JOYSTICK|SDL_INIT_NOPARACHUTE)) {
+#endif
osd_printf_error("Could not initialize SDL %s\n", SDL_GetError());
exit(-1);
}
@@ -546,9 +600,13 @@ void sdl_osd_interface::init(running_machine &machine)
m_watchdog->setTimeout(watchdog_timeout);
}
+#if (SDLMAME_SDL2)
#ifdef SDLMAME_EMSCRIPTEN
SDL_EventState(SDL_TEXTINPUT, SDL_FALSE);
#else
SDL_EventState(SDL_TEXTINPUT, SDL_TRUE);
#endif
+#else
+ SDL_EnableUNICODE(SDL_TRUE);
+#endif
}
diff --git a/src/osd/sdl/sdlos_unix.cpp b/src/osd/sdl/sdlos_unix.cpp
index 23080512e91..5811e0c7dc5 100644
--- a/src/osd/sdl/sdlos_unix.cpp
+++ b/src/osd/sdl/sdlos_unix.cpp
@@ -23,6 +23,11 @@
// MAME headers
#include "osdcore.h"
+
+
+
+#if (SDLMAME_SDL2)
+
//============================================================
// osd_get_clipboard_text
//============================================================
@@ -40,3 +45,104 @@ char *osd_get_clipboard_text(void)
}
return result;
}
+
+#elif defined(SDL_VIDEO_DRIVER_X11) && defined(SDLMAME_X11)
+
+//============================================================
+// osd_get_clipboard_text
+//============================================================
+
+char *osd_get_clipboard_text(void)
+{
+ SDL_SysWMinfo info;
+ Display* display;
+ Window our_win;
+ Window selection_win;
+ Atom data_type;
+ int data_format;
+ unsigned long nitems;
+ unsigned long bytes_remaining;
+ unsigned char* prop;
+ char* result;
+ XEvent event;
+ Uint32 t0, t1;
+ Atom types[2];
+ int i;
+
+ /* get & validate SDL sys-wm info */
+ SDL_VERSION(&info.version);
+ if ( ! SDL_GetWMInfo( &info ) )
+ return NULL;
+ if ( info.subsystem != SDL_SYSWM_X11 )
+ return NULL;
+ if ( (display = info.info.x11.display) == NULL )
+ return NULL;
+ if ( (our_win = info.info.x11.window) == None )
+ return NULL;
+
+ /* request data to owner */
+ selection_win = XGetSelectionOwner( display, XA_PRIMARY );
+ if ( selection_win == None )
+ return NULL;
+
+ /* first, try UTF-8, then latin-1 */
+ types[0] = XInternAtom( display, "UTF8_STRING", False );
+ types[1] = XA_STRING; /* latin-1 */
+
+ for ( i = 0; i < ARRAY_LENGTH(types); i++ )
+ {
+ XConvertSelection( display, XA_PRIMARY, types[i], types[i], our_win, CurrentTime );
+
+ /* wait for SelectionNotify, but no more than 100 ms */
+ t0 = t1 = SDL_GetTicks();
+ while ( 1 )
+ {
+ if ( XCheckTypedWindowEvent( display, our_win, SelectionNotify, &event ) ) break;
+ SDL_Delay( 1 );
+ t1 = SDL_GetTicks();
+ if ( t1 - t0 > 100 )
+ return NULL;
+ }
+ if ( event.xselection.property == None )
+ continue;
+
+ /* get property & check its type */
+ if ( XGetWindowProperty( display, our_win, types[i], 0, 65536, False, types[i],
+ &data_type, &data_format, &nitems, &bytes_remaining, &prop )
+ != Success )
+ continue;
+ if ( ! prop )
+ continue;
+ if ( (data_format != 8) || (data_type != types[i]) )
+ {
+ XFree( prop );
+ continue;
+ }
+
+ /* return a copy & free original */
+ if (prop != NULL)
+ {
+ result = (char *) osd_malloc_array(strlen((char *)prop)+1);
+ strcpy(result, (char *)prop);
+ }
+ else
+ result = NULL;
+ XFree( prop );
+ return result;
+ }
+
+ return NULL;
+}
+
+#else
+//============================================================
+// osd_get_clipboard_text
+//============================================================
+
+char *osd_get_clipboard_text(void)
+{
+ char *result = NULL;
+
+ return result;
+}
+#endif
diff --git a/src/osd/sdl/testkeys.cpp b/src/osd/sdl/testkeys.cpp
index 850ec1ad506..444c1b9eeb2 100644
--- a/src/osd/sdl/testkeys.cpp
+++ b/src/osd/sdl/testkeys.cpp
@@ -24,6 +24,7 @@ struct key_lookup_table
const char *name;
};
+#if (SDLMAME_SDL2)
#define KE(x) { SDL_SCANCODE_ ## x, "SDL_SCANCODE_" #x },
#define KE8(A, B, C, D, E, F, G, H) KE(A) KE(B) KE(C) KE(D) KE(E) KE(F) KE(G) KE(H)
#define KE7(A, B, C, D, E, F, G) KE(A) KE(B) KE(C) KE(D) KE(E) KE(F) KE(G)
@@ -52,6 +53,46 @@ static key_lookup_table sdl_lookup[] =
KE5(MENU, NONUSBACKSLASH, UNDO, APOSTROPHE, GRAVE )
{-1, ""}
};
+#else
+#define KE(x) { SDLK_ ## x, "SDLK_" #x },
+#define KE8(A, B, C, D, E, F, G, H) KE(A) KE(B) KE(C) KE(D) KE(E) KE(F) KE(G) KE(H)
+
+static key_lookup_table sdl_lookup[] =
+{
+ KE8(UNKNOWN, FIRST, BACKSPACE, TAB, CLEAR, RETURN, PAUSE, ESCAPE )
+ KE8(SPACE, EXCLAIM, QUOTEDBL, HASH, DOLLAR, AMPERSAND, QUOTE, LEFTPAREN )
+ KE8(RIGHTPAREN, ASTERISK, PLUS, COMMA, MINUS, PERIOD, SLASH, 0 )
+ KE8(1, 2, 3, 4, 5, 6, 7, 8 )
+ KE8(9, COLON, SEMICOLON, LESS, EQUALS, GREATER, QUESTION, AT )
+ KE8(LEFTBRACKET,BACKSLASH, RIGHTBRACKET, CARET, UNDERSCORE, BACKQUOTE, a, b )
+ KE8(c, d, e, f, g, h, i, j )
+ KE8(k, l, m, n, o, p, q, r )
+ KE8(s, t, u, v, w, x, y, z )
+ KE8(DELETE, WORLD_0, WORLD_1, WORLD_2, WORLD_3, WORLD_4, WORLD_5, WORLD_6 )
+ KE8(WORLD_7, WORLD_8, WORLD_9, WORLD_10, WORLD_11, WORLD_12, WORLD_13, WORLD_14 )
+ KE8(WORLD_15, WORLD_16, WORLD_17, WORLD_18, WORLD_19, WORLD_20, WORLD_21, WORLD_22 )
+ KE8(WORLD_23, WORLD_24, WORLD_25, WORLD_26, WORLD_27, WORLD_28, WORLD_29, WORLD_30 )
+ KE8(WORLD_31, WORLD_32, WORLD_33, WORLD_34, WORLD_35, WORLD_36, WORLD_37, WORLD_38 )
+ KE8(WORLD_39, WORLD_40, WORLD_41, WORLD_42, WORLD_43, WORLD_44, WORLD_45, WORLD_46 )
+ KE8(WORLD_47, WORLD_48, WORLD_49, WORLD_50, WORLD_51, WORLD_52, WORLD_53, WORLD_54 )
+ KE8(WORLD_55, WORLD_56, WORLD_57, WORLD_58, WORLD_59, WORLD_60, WORLD_61, WORLD_62 )
+ KE8(WORLD_63, WORLD_64, WORLD_65, WORLD_66, WORLD_67, WORLD_68, WORLD_69, WORLD_70 )
+ KE8(WORLD_71, WORLD_72, WORLD_73, WORLD_74, WORLD_75, WORLD_76, WORLD_77, WORLD_78 )
+ KE8(WORLD_79, WORLD_80, WORLD_81, WORLD_82, WORLD_83, WORLD_84, WORLD_85, WORLD_86 )
+ KE8(WORLD_87, WORLD_88, WORLD_89, WORLD_90, WORLD_91, WORLD_92, WORLD_93, WORLD_94 )
+ KE8(WORLD_95, KP0, KP1, KP2, KP3, KP4, KP5, KP6 )
+ KE8(KP7, KP8, KP9, KP_PERIOD, KP_DIVIDE, KP_MULTIPLY,KP_MINUS, KP_PLUS )
+ KE8(KP_ENTER, KP_EQUALS, UP, DOWN, RIGHT, LEFT, INSERT, HOME )
+ KE8(END, PAGEUP, PAGEDOWN, F1, F2, F3, F4, F5 )
+ KE8(F6, F7, F8, F9, F10, F11, F12, F13 )
+ KE8(F14, F15, NUMLOCK, CAPSLOCK, SCROLLOCK, RSHIFT, LSHIFT, RCTRL )
+ KE8(LCTRL, RALT, LALT, RMETA, LMETA, LSUPER, RSUPER, MODE )
+ KE8(COMPOSE, HELP, PRINT, SYSREQ, BREAK, MENU, POWER, EURO )
+ KE(UNDO)
+ KE(LAST)
+ {-1, ""}
+};
+#endif
static const char * lookup_key_name(const key_lookup_table *kt, int kc)
{
@@ -73,14 +114,23 @@ int main(int argc, char *argv[])
{
SDL_Event event;
int quit = 0;
+#if (SDLMAME_SDL2)
char lasttext[20] = "";
+#else
+ char buf[20];
+#endif
if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
fprintf(stderr, "Couldn't initialize SDL: %s\n",
SDL_GetError());
exit(1);
}
+#if (SDLMAME_SDL2)
SDL_CreateWindow("Input Test", 0, 0, 100, 100,0 );
+#else
+ SDL_SetVideoMode(100, 50, 16, SDL_ANYFORMAT);
+ SDL_EnableUNICODE(1);
+#endif
while(SDL_PollEvent(&event) || !quit) {
switch(event.type) {
case SDL_QUIT:
@@ -91,24 +141,46 @@ int main(int argc, char *argv[])
quit=1;
else
{
+#if (SDLMAME_SDL2)
printf("ITEM_ID_XY %s 0x%x 0x%x %s\n",
lookup_key_name(sdl_lookup, event.key.keysym.scancode),
(int) event.key.keysym.scancode,
(int) event.key.keysym.sym,
"");
lasttext[0] = 0;
+#else
+ memset(buf, 0, 19);
+ utf8_from_uchar(buf, sizeof(buf), event.key.keysym.unicode);
+ printf("ITEM_ID_XY %s 0x%x 0x%x %s\n",
+ lookup_key_name(sdl_lookup, event.key.keysym.sym),
+ (int) event.key.keysym.scancode,
+ (int) event.key.keysym.unicode,
+ buf);
+#endif
}
break;
case SDL_KEYUP:
+#if (SDLMAME_SDL2)
printf("ITEM_ID_XY %s 0x%x 0x%x %s\n",
lookup_key_name(sdl_lookup, event.key.keysym.scancode),
(int) event.key.keysym.scancode,
(int) event.key.keysym.sym,
lasttext);
+#else
+ memset(buf, 0, 19);
+ utf8_from_uchar(buf, sizeof(buf), event.key.keysym.unicode);
+ printf("ITEM_ID_XY %s 0x%x 0x%x %s\n",
+ lookup_key_name(sdl_lookup, event.key.keysym.sym),
+ (int) event.key.keysym.scancode,
+ (int) event.key.keysym.unicode,
+ buf);
+#endif
break;
+#if (SDLMAME_SDL2)
case SDL_TEXTINPUT:
strcpy(lasttext, event.text.text);
break;
+#endif
}
event.type = 0;
diff --git a/src/osd/sdl/video.cpp b/src/osd/sdl/video.cpp
index ca7286d5696..c5de6be41d9 100644
--- a/src/osd/sdl/video.cpp
+++ b/src/osd/sdl/video.cpp
@@ -7,6 +7,33 @@
// SDLMAME by Olivier Galibert and R. Belmont
//
//============================================================
+
+#ifdef SDLMAME_X11
+#include <X11/extensions/Xinerama.h>
+#endif
+
+#ifdef SDLMAME_MACOSX
+#undef Status
+#include <Carbon/Carbon.h>
+#endif
+
+#ifdef SDLMAME_WIN32
+// for multimonitor
+#ifndef _WIN32_WINNT
+#define _WIN32_WINNT 0x501
+#endif
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+
+#include "strconv.h"
+#endif
+
+#ifdef SDLMAME_OS2
+#define INCL_WINSYS
+#include <os2.h>
+#endif
+
#include "sdlinc.h"
// MAME headers
@@ -107,9 +134,15 @@ void sdl_osd_interface::video_exit()
//============================================================
// sdlvideo_monitor_refresh
//============================================================
-
+#if defined(SDLMAME_WIN32) // Win32 version
+inline osd_rect RECT_to_osd_rect(const RECT &r)
+{
+ return osd_rect(r.left, r.top, r.right - r.left, r.bottom - r.top);
+}
+#endif
void sdl_monitor_info::refresh()
{
+ #if (SDLMAME_SDL2)
SDL_DisplayMode dmode;
#if defined(SDLMAME_WIN32)
@@ -123,8 +156,128 @@ void sdl_monitor_info::refresh()
m_pos_size = SDL_Rect_to_osd_rect(dimensions);
m_usuable_pos_size = SDL_Rect_to_osd_rect(dimensions);
m_is_primary = (m_handle == 0);
+
+ #else
+ #if defined(SDLMAME_WIN32) // Win32 version
+ MONITORINFOEX info;
+ info.cbSize = sizeof(info);
+ GetMonitorInfo((HMONITOR)m_handle, (LPMONITORINFO)&info);
+ m_pos_size = RECT_to_osd_rect(info.rcMonitor);
+ m_usuable_pos_size = RECT_to_osd_rect(info.rcWork);
+ m_is_primary = ((info.dwFlags & MONITORINFOF_PRIMARY) != 0);
+ char *temp = utf8_from_wstring(info.szDevice);
+ strncpy(m_name, temp, ARRAY_LENGTH(m_name) - 1);
+ osd_free(temp);
+ #elif defined(SDLMAME_MACOSX) // Mac OS X Core Imaging version
+ CGDirectDisplayID primary;
+ CGRect dbounds;
+
+ // get the main display
+ primary = CGMainDisplayID();
+ dbounds = CGDisplayBounds(primary);
+
+ m_is_primary = (m_handle == 0);
+ m_pos_size = osd_rect(0, 0, dbounds.size.width - dbounds.origin.x, dbounds.size.height - dbounds.origin.y);
+ m_usuable_pos_size = m_pos_size;
+ strncpy(m_name, "Mac OS X display", ARRAY_LENGTH(m_name) - 1);
+ #elif defined(SDLMAME_X11) || defined(SDLMAME_NO_X11) // X11 version
+ {
+ #if defined(SDLMAME_X11)
+ // X11 version
+ int screen;
+ SDL_SysWMinfo info;
+ SDL_VERSION(&info.version);
+
+ if ( SDL_GetWMInfo(&info) && (info.subsystem == SDL_SYSWM_X11) )
+ {
+ screen = DefaultScreen(info.info.x11.display);
+ SDL_VideoDriverName(m_name, ARRAY_LENGTH(m_name) - 1);
+ m_pos_size = osd_rect(0, 0,
+ DisplayWidth(info.info.x11.display, screen),
+ DisplayHeight(info.info.x11.display, screen));
+
+ /* FIXME: If Xinerame is used we should compile a list of monitors
+ * like we do for other targets and ignore SDL.
+ */
+ if ((XineramaIsActive(info.info.x11.display)) && video_config.restrictonemonitor)
+ {
+ XineramaScreenInfo *xineinfo;
+ int numscreens;
+
+ xineinfo = XineramaQueryScreens(info.info.x11.display, &numscreens);
+
+ m_pos_size = osd_rect(0, 0, xineinfo[0].width, xineinfo[0].height);
+
+ XFree(xineinfo);
+ }
+ m_usuable_pos_size = m_pos_size;
+ m_is_primary = (m_handle == 0);
+ }
+ else
+ #endif // defined(SDLMAME_X11)
+ {
+ static int first_call=0;
+ static int cw = 0, ch = 0;
+
+ SDL_VideoDriverName(m_name, ARRAY_LENGTH(m_name) - 1);
+ if (first_call==0)
+ {
+ const char *dimstr = osd_getenv(SDLENV_DESKTOPDIM);
+ const SDL_VideoInfo *sdl_vi;
+
+ sdl_vi = SDL_GetVideoInfo();
+ #if (SDL_VERSION_ATLEAST(1,2,10))
+ cw = sdl_vi->current_w;
+ ch = sdl_vi->current_h;
+ #endif
+ first_call=1;
+ if ((cw==0) || (ch==0))
+ {
+ if (dimstr != NULL)
+ {
+ sscanf(dimstr, "%dx%d", &cw, &ch);
+ }
+ if ((cw==0) || (ch==0))
+ {
+ osd_printf_warning("WARNING: SDL_GetVideoInfo() for driver <%s> is broken.\n", m_name);
+ osd_printf_warning(" You should set SDLMAME_DESKTOPDIM to your desktop size.\n");
+ osd_printf_warning(" e.g. export SDLMAME_DESKTOPDIM=800x600\n");
+ osd_printf_warning(" Assuming 1024x768 now!\n");
+ cw=1024;
+ ch=768;
+ }
+ }
+ }
+ m_pos_size = osd_rect(0, 0, cw, ch);
+ m_usuable_pos_size = m_pos_size;
+ m_is_primary = (m_handle == 0);
+ }
+ }
+ #elif defined(SDLMAME_OS2) // OS2 version
+ m_pos_size = osd_rect(0, 0,
+ WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN ),
+ WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN ) );
+ m_usuable_pos_size = m_pos_size;
+ m_is_primary = (m_handle == 0);
+ strncpy(m_name, "OS/2 display", ARRAY_LENGTH(m_name) - 1);
+ #else
+ #error Unknown SDLMAME_xx OS type!
+ #endif
+
+ {
+ static int info_shown=0;
+ if (!info_shown)
+ {
+ osd_printf_verbose("SDL Device Driver : %s\n", m_name);
+ osd_printf_verbose("SDL Monitor Dimensions: %d x %d\n", m_pos_size.width(), m_pos_size.height());
+ info_shown = 1;
+ }
+ }
+ #endif // (SDLMAME_SDL2)
}
+
+
//============================================================
// sdlvideo_monitor_get_aspect
//============================================================
@@ -172,6 +325,68 @@ void sdl_osd_interface::update(bool skip_redraw)
//============================================================
+// add_primary_monitor
+//============================================================
+
+#if !defined(SDLMAME_WIN32) && !(SDLMAME_SDL2)
+void sdl_monitor_info::add_primary_monitor(void *data)
+{
+ // make a list of monitors
+ osd_monitor_info::list = NULL;
+ osd_monitor_info **tailptr = &sdl_monitor_info::list;
+
+ // allocate a new monitor info
+ osd_monitor_info *monitor = global_alloc_clear<sdl_monitor_info>(0, "", 1.0f);
+
+ //monitor->refresh();
+ // guess the aspect ratio assuming square pixels
+ monitor->set_aspect((float)(monitor->position_size().width()) / (float)(monitor->position_size().height()));
+
+ // hook us into the list
+ *tailptr = monitor;
+ //tailptr = &monitor->m_next;
+}
+#endif
+
+
+//============================================================
+// monitor_enum_callback
+//============================================================
+
+#if defined(SDLMAME_WIN32) && !(SDLMAME_SDL2)
+BOOL CALLBACK sdl_monitor_info::monitor_enum_callback(HMONITOR handle, HDC dc, LPRECT rect, LPARAM data)
+{
+ osd_monitor_info ***tailptr = (osd_monitor_info ***)data;
+ osd_monitor_info *monitor;
+ MONITORINFOEX info;
+ BOOL result;
+
+ // get the monitor info
+ info.cbSize = sizeof(info);
+ result = GetMonitorInfo(handle, (LPMONITORINFO)&info);
+ assert(result);
+ (void)result; // to silence gcc 4.6
+
+ // guess the aspect ratio assuming square pixels
+ float aspect = (float)(info.rcMonitor.right - info.rcMonitor.left) / (float)(info.rcMonitor.bottom - info.rcMonitor.top);
+
+ // allocate a new monitor info
+ char *temp = utf8_from_wstring(info.szDevice);
+ // copy in the data
+ monitor = global_alloc(sdl_monitor_info((UINT64) handle, temp, aspect));
+ osd_free(temp);
+
+ // hook us into the list
+ **tailptr = monitor;
+ *tailptr = &monitor->m_next;
+
+ // enumerate all the available monitors so to list their names in verbose mode
+ return TRUE;
+}
+#endif
+
+
+//============================================================
// init_monitors
//============================================================
@@ -183,6 +398,7 @@ void sdl_monitor_info::init()
osd_monitor_info::list = NULL;
tailptr = &osd_monitor_info::list;
+ #if (SDLMAME_SDL2)
{
int i;
@@ -211,6 +427,11 @@ void sdl_monitor_info::init()
}
}
osd_printf_verbose("Leave init_monitors\n");
+ #elif defined(SDLMAME_WIN32)
+ EnumDisplayMonitors(NULL, NULL, monitor_enum_callback, (LPARAM)&tailptr);
+ #else
+ add_primary_monitor((void *)&tailptr);
+ #endif
}
void sdl_monitor_info::exit()
@@ -313,7 +534,7 @@ static void check_osd_inputs(running_machine &machine)
machine.ui().popup_time(1, "Keepaspect %s", video_config.keepaspect? "enabled":"disabled");
}
- #if (USE_OPENGL)
+ #if (USE_OPENGL || SDLMAME_SDL2)
//FIXME: on a per window basis
if (machine.ui_input().pressed(IPT_OSD_5))
{
@@ -379,14 +600,16 @@ void sdl_osd_interface::extract_video_config()
}
else if (USE_OPENGL && (strcmp(stemp, SDLOPTVAL_OPENGL) == 0))
video_config.mode = VIDEO_MODE_OPENGL;
- else if ((strcmp(stemp, SDLOPTVAL_SDL2ACCEL) == 0))
+ else if (SDLMAME_SDL2 && (strcmp(stemp, SDLOPTVAL_SDL2ACCEL) == 0))
{
video_config.mode = VIDEO_MODE_SDL2ACCEL;
}
+#ifdef USE_BGFX
else if (strcmp(stemp, SDLOPTVAL_BGFX) == 0)
{
video_config.mode = VIDEO_MODE_BGFX;
}
+#endif
else
{
osd_printf_warning("Invalid video value %s; reverting to software\n", stemp);
@@ -470,11 +693,19 @@ void sdl_osd_interface::extract_video_config()
// misc options: sanity check values
// global options: sanity check values
+#if (!SDLMAME_SDL2)
+ if (video_config.numscreens < 1 || video_config.numscreens > 1) //MAX_VIDEO_WINDOWS)
+ {
+ osd_printf_warning("Invalid numscreens value %d; reverting to 1\n", video_config.numscreens);
+ video_config.numscreens = 1;
+ }
+#else
if (video_config.numscreens < 1 || video_config.numscreens > MAX_VIDEO_WINDOWS)
{
osd_printf_warning("Invalid numscreens value %d; reverting to 1\n", video_config.numscreens);
video_config.numscreens = 1;
}
+#endif
// yuv settings ...
stemp = options().scale_mode();
video_config.scale_mode = drawsdl_scale_mode(stemp);
diff --git a/src/osd/sdl/video.h b/src/osd/sdl/video.h
index a811a417ef4..699f98512d1 100644
--- a/src/osd/sdl/video.h
+++ b/src/osd/sdl/video.h
@@ -11,6 +11,11 @@
#ifndef __SDLVIDEO__
#define __SDLVIDEO__
+#if defined(SDLMAME_WIN32) && !(SDLMAME_SDL2)
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
#include "osdsdl.h"
//============================================================
@@ -159,6 +164,12 @@ public:
// STATIC
static void init();
static void exit();
+#if !defined(SDLMAME_WIN32) && !(SDLMAME_SDL2)
+ static void add_primary_monitor(void *data);
+#endif
+#if defined(SDLMAME_WIN32) && !(SDLMAME_SDL2)
+ static BOOL CALLBACK monitor_enum_callback(HMONITOR handle, HDC dc, LPRECT rect, LPARAM data);
+#endif
private:
void virtual refresh() override;
@@ -181,6 +192,9 @@ struct osd_video_config
int fullstretch; // FXIME: implement in windows!
+ // ddraw options
+ int hwstretch; // stretch using the hardware
+
// d3d, accel, opengl
int filter; // enable filtering
//int filter; // enable filtering, disabled if glsl_filter>0
diff --git a/src/osd/sdl/window.cpp b/src/osd/sdl/window.cpp
index 113a00b47bf..47ab3cdd162 100644
--- a/src/osd/sdl/window.cpp
+++ b/src/osd/sdl/window.cpp
@@ -16,7 +16,11 @@
// standard SDL headers
#include "sdlinc.h"
+#if (SDLMAME_SDL2)
#include <SDL2/SDL_thread.h>
+#else
+#include <SDL/SDL_thread.h>
+#endif
// standard C headers
#include <math.h>
@@ -88,6 +92,10 @@ static sdl_window_info **last_window_ptr;
static int multithreading_enabled;
static osd_work_queue *work_queue;
+#if !(SDLMAME_SDL2) && (!defined(SDLMAME_EMSCRIPTEN))
+typedef int SDL_threadID;
+#endif
+
static SDL_threadID main_threadid;
static SDL_threadID window_threadid;
@@ -181,7 +189,11 @@ static OSDWORK_CALLBACK(sdlwindow_thread_id)
if (SDLMAME_INIT_IN_WORKER_THREAD)
{
+#if (SDLMAME_SDL2)
if (SDL_InitSubSystem(SDL_INIT_TIMER|SDL_INIT_AUDIO| SDL_INIT_VIDEO| SDL_INIT_JOYSTICK|SDL_INIT_NOPARACHUTE))
+#else
+ if (SDL_Init(SDL_INIT_TIMER|SDL_INIT_AUDIO| SDL_INIT_VIDEO| SDL_INIT_JOYSTICK|SDL_INIT_NOPARACHUTE))
+#endif
{
osd_printf_error("Could not initialize SDL: %s.\n", SDL_GetError());
exit(-1);
@@ -230,22 +242,27 @@ bool sdl_osd_interface::window_init()
video_config.mode = VIDEO_MODE_SOFT;
}
#endif
+#if SDLMAME_SDL2
if (video_config.mode == VIDEO_MODE_SDL2ACCEL)
{
if (drawsdl2_init(machine(), &draw))
video_config.mode = VIDEO_MODE_SOFT;
}
+#endif
+#ifdef USE_BGFX
if (video_config.mode == VIDEO_MODE_BGFX)
{
if (drawbgfx_init(machine(), &draw))
video_config.mode = VIDEO_MODE_SOFT;
}
+#endif
if (video_config.mode == VIDEO_MODE_SOFT)
{
if (drawsdl_init(&draw))
return false;
}
+#if SDLMAME_SDL2
/* We may want to set a number of the hints SDL2 provides.
* The code below will document which hints were set.
*/
@@ -277,6 +294,7 @@ bool sdl_osd_interface::window_init()
osd_printf_verbose("\nHints:\n");
for (int i = 0; hints[i] != NULL; i++)
osd_printf_verbose("\t%-40s %s\n", hints[i], SDL_GetHint(hints[i]));
+#endif
// set up the window list
last_window_ptr = &sdl_window_list;
@@ -460,7 +478,14 @@ OSDWORK_CALLBACK( sdl_window_info::sdlwindow_resize_wt )
ASSERT_WINDOW_THREAD();
+#if (SDLMAME_SDL2)
SDL_SetWindowSize(window->sdl_window(), width, height);
+#else
+ SDL_FreeSurface(window->m_sdlsurf);
+
+ window->m_sdlsurf = SDL_SetVideoMode(width, height, 0,
+ SDL_SWSURFACE | SDL_ANYFORMAT | window->m_extra_flags);
+#endif
window->renderer().notify_changed();
osd_free(wp);
@@ -534,6 +559,7 @@ OSDWORK_CALLBACK( sdl_window_info::sdlwindow_toggle_full_screen_wt )
global_free(window->m_renderer);
window->m_renderer = NULL;
+#if (SDLMAME_SDL2)
bool is_osx = false;
#ifdef SDLMAME_MACOSX
// FIXME: This is weird behaviour and certainly a bug in SDL
@@ -546,6 +572,15 @@ OSDWORK_CALLBACK( sdl_window_info::sdlwindow_toggle_full_screen_wt )
SDL_SetWindowFullscreen(window->sdl_window(), SDL_WINDOW_FULLSCREEN); // Try to set mode
}
SDL_DestroyWindow(window->sdl_window());
+#else
+ if (window->m_sdlsurf)
+ {
+ SDL_FreeSurface(window->m_sdlsurf);
+ window->m_sdlsurf = NULL;
+ }
+#endif
+
+
sdlinput_release_keys();
window->set_renderer(draw.create(window));
@@ -612,6 +647,7 @@ void sdl_window_info::update_cursor_state()
c=SDL_CreateCursor(data, data, 8, 8, 0, 0);
SDL_SetCursor(c);
#else
+#if (SDLMAME_SDL2)
// do not do mouse capture if the debugger's enabled to avoid
// the possibility of losing control
if (!(machine().debug_flags & DEBUG_FLAG_OSD_ENABLED))
@@ -634,6 +670,30 @@ void sdl_window_info::update_cursor_state()
}
SDL_SetCursor(NULL); // Force an update in case the underlying driver has changed visibility
}
+
+#else
+ // do not do mouse capture if the debugger's enabled to avoid
+ // the possibility of losing control
+ if (!(machine().debug_flags & DEBUG_FLAG_OSD_ENABLED))
+ {
+ if ( fullscreen() || sdlinput_should_hide_mouse() )
+ {
+ SDL_ShowCursor(SDL_DISABLE);
+ if (!SDL_WM_GrabInput(SDL_GRAB_QUERY))
+ {
+ SDL_WM_GrabInput(SDL_GRAB_ON);
+ }
+ }
+ else
+ {
+ SDL_ShowCursor(SDL_ENABLE);
+ if (SDL_WM_GrabInput(SDL_GRAB_QUERY))
+ {
+ SDL_WM_GrabInput(SDL_GRAB_OFF);
+ }
+ }
+ }
+#endif
#endif
}
@@ -733,6 +793,7 @@ OSDWORK_CALLBACK( sdl_window_info::sdlwindow_video_window_destroy_wt )
// free the textures etc
window->renderer().destroy();
+#if (SDLMAME_SDL2)
if (window->fullscreen() && video_config.switchres)
{
SDL_SetWindowFullscreen(window->sdl_window(), 0); // Try to set mode
@@ -740,6 +801,14 @@ OSDWORK_CALLBACK( sdl_window_info::sdlwindow_video_window_destroy_wt )
SDL_SetWindowFullscreen(window->sdl_window(), SDL_WINDOW_FULLSCREEN); // Try to set mode
}
SDL_DestroyWindow(window->sdl_window());
+#else
+ if (window->m_sdlsurf)
+ {
+ SDL_FreeSurface(window->m_sdlsurf);
+ window->m_sdlsurf = NULL;
+ }
+#endif
+
// release all keys ...
sdlinput_release_keys();
@@ -784,6 +853,7 @@ void sdl_window_info::destroy()
// pick_best_mode
//============================================================
+#if SDLMAME_SDL2
osd_dim sdl_window_info::pick_best_mode()
{
int minimum_width, minimum_height, target_width, target_height;
@@ -852,6 +922,82 @@ osd_dim sdl_window_info::pick_best_mode()
}
return ret;
}
+#else
+osd_dim sdl_window_info::pick_best_mode()
+{
+ int minimum_width, minimum_height, target_width, target_height;
+ int i;
+ float size_score, best_score = 0.0f;
+ int best_width = 0, best_height = 0;
+ SDL_Rect **modes;
+
+ // determine the minimum width/height for the selected target
+ m_target->compute_minimum_size(minimum_width, minimum_height);
+
+ // use those as the target for now
+ target_width = minimum_width * MAX(1, prescale());
+ target_height = minimum_height * MAX(1, prescale());
+
+ // if we're not stretching, allow some slop on the minimum since we can handle it
+ {
+ minimum_width -= 4;
+ minimum_height -= 4;
+ }
+
+#if 1 // defined(SDLMAME_WIN32)
+ /*
+ * We need to do this here. If SDL_ListModes is
+ * called in init_monitors, the call will crash
+ * on win32
+ */
+ modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_DOUBLEBUF);
+#else
+ modes = window->m_monitor->modes;
+#endif
+
+ if (modes == (SDL_Rect **)0)
+ {
+ osd_printf_error("SDL: No modes available?!\n");
+ exit(-1);
+ }
+ else if (modes == (SDL_Rect **)-1) // all modes are possible
+ {
+ return osd_dim(m_win_config.width, m_win_config.height);
+ }
+ else
+ {
+ for (i = 0; modes[i]; ++i)
+ {
+ // compute initial score based on difference between target and current
+ size_score = 1.0f / (1.0f + fabsf((INT32)modes[i]->w - target_width) + fabsf((INT32)modes[i]->h - target_height));
+
+ // if the mode is too small, give a big penalty
+ if (modes[i]->w < minimum_width || modes[i]->h < minimum_height)
+ size_score *= 0.01f;
+
+ // if mode is smaller than we'd like, it only scores up to 0.1
+ if (modes[i]->w < target_width || modes[i]->h < target_height)
+ size_score *= 0.1f;
+
+ // if we're looking for a particular mode, that's a winner
+ if (modes[i]->w == m_win_config.width && modes[i]->h == m_win_config.height)
+ size_score = 2.0f;
+
+ osd_printf_verbose("%4dx%4d -> %f\n", (int)modes[i]->w, (int)modes[i]->h, size_score);
+
+ // best so far?
+ if (size_score > best_score)
+ {
+ best_score = size_score;
+ best_width = modes[i]->w;
+ best_height = modes[i]->h;
+ }
+
+ }
+ }
+ return osd_dim(best_width, best_height);
+}
+#endif
//============================================================
// sdlwindow_video_window_update
@@ -996,6 +1142,8 @@ OSDWORK_CALLBACK( sdl_window_info::complete_create_wt )
*/
osd_printf_verbose("Enter sdl_info::create\n");
+#if (SDLMAME_SDL2)
+
if (window->renderer().has_flags(osd_renderer::FLAG_NEEDS_OPENGL))
{
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
@@ -1079,18 +1227,48 @@ OSDWORK_CALLBACK( sdl_window_info::complete_create_wt )
SDL_SetWindowGrab(window->sdl_window(), SDL_TRUE);
#endif
- // set main window
- if (window->m_index > 0)
+#else
+ window->m_extra_flags = (window->fullscreen() ? SDL_FULLSCREEN : SDL_RESIZABLE);
+
+ if (window->renderer().has_flags(osd_renderer::FLAG_NEEDS_DOUBLEBUF))
+ window->m_extra_flags |= SDL_DOUBLEBUF;
+ if (window->renderer().has_flags(osd_renderer::FLAG_NEEDS_ASYNCBLIT))
+ window->m_extra_flags |= SDL_ASYNCBLIT;
+
+ if (window->renderer().has_flags(osd_renderer::FLAG_NEEDS_OPENGL))
{
- for (auto w = sdl_window_list; w != NULL; w = w->m_next)
- {
- if (w->m_index == 0)
- {
- window->m_main = w;
- break;
- }
- }
+ window->m_extra_flags |= SDL_DOUBLEBUF | SDL_OPENGL;
+ SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
+ #if (SDL_VERSION_ATLEAST(1,2,10)) && (!defined(SDLMAME_EMSCRIPTEN))
+ SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, video_config.waitvsync ? 1 : 0);
+ #endif
+ // load_gl_lib(window->machine());
}
+
+ // create the SDL surface (which creates the window in windowed mode)
+#if 0
+ window->m_sdlsurf = SDL_SetVideoMode(tempwidth, tempheight,
+ 0, SDL_OPENGL | SDL_FULLSCREEN);// | window->m_extra_flags);
+ if (!window->m_sdlsurf)
+ printf("completely failed\n");
+#endif
+ window->m_sdlsurf = SDL_SetVideoMode(temp.width(), temp.height(),
+ 0, SDL_SWSURFACE | SDL_ANYFORMAT | window->m_extra_flags);
+
+ if (!window->m_sdlsurf)
+ {
+ osd_printf_error("SDL Error: %s\n", SDL_GetError());
+ return (void *) &result[1];
+ }
+ if ( (video_config.mode == VIDEO_MODE_OPENGL) && !(window->m_sdlsurf->flags & SDL_OPENGL) )
+ {
+ osd_printf_error("OpenGL not supported on this driver!\n");
+ return (void *) &result[1];
+ }
+ // set the window title
+ SDL_WM_SetCaption(window->m_title, "SDLMAME");
+#endif
+
window->monitor()->refresh();
// initialize the drawing backend
if (window->renderer().create())
diff --git a/src/osd/sdl/window.h b/src/osd/sdl/window.h
index bdaaa311330..3de110fe536 100644
--- a/src/osd/sdl/window.h
+++ b/src/osd/sdl/window.h
@@ -38,14 +38,21 @@ public:
const osd_window_config *config)
: osd_window(), m_next(NULL),
// Following three are used by input code to defer resizes
+#if (SDLMAME_SDL2)
m_resize_width(0),
m_resize_height(0),
m_last_resize(0),
+#endif
m_minimum_dim(0,0),
m_windowed_dim(0,0),
m_rendered_event(0), m_target(0),
+#if (SDLMAME_SDL2)
m_sdl_window(NULL),
- m_machine(a_machine), m_monitor(a_monitor), m_fullscreen(0)
+
+#else
+ m_sdlsurf(NULL),
+#endif
+ m_machine(a_machine), m_monitor(a_monitor), m_fullscreen(0), m_index(0)
{
m_win_config = *config;
m_index = index;
@@ -74,9 +81,13 @@ public:
osd_dim get_size() override
{
+#if (SDLMAME_SDL2)
int w=0; int h=0;
SDL_GetWindowSize(m_sdl_window, &w, &h);
return osd_dim(w,h);
+#else
+ return osd_dim(m_sdlsurf->w, m_sdlsurf->h);
+#endif
}
int xy_to_render_target(int x, int y, int *xt, int *yt);
@@ -86,7 +97,11 @@ public:
int fullscreen() const override { return m_fullscreen; }
render_target *target() override { return m_target; }
+#if (SDLMAME_SDL2)
SDL_Window *sdl_window() override { return m_sdl_window; }
+#else
+ SDL_Surface *sdl_surface() { return m_sdlsurf; }
+#endif
osd_dim blit_surface_size() override;
int prescale() const { return m_prescale; }
@@ -94,10 +109,12 @@ public:
// Pointer to next window
sdl_window_info * m_next;
+#if (SDLMAME_SDL2)
// These are used in combine resizing events ... #if SDL13_COMBINE_RESIZE
int m_resize_width;
int m_resize_height;
osd_ticks_t m_last_resize;
+#endif
private:
// window handle and info
@@ -112,10 +129,15 @@ private:
osd_event * m_rendered_event;
render_target * m_target;
+#if (SDLMAME_SDL2)
// Needs to be here as well so we can identify window
SDL_Window *m_sdl_window;
// Original display_mode
SDL_DisplayMode m_original_mode;
+#else
+ // SDL surface
+ SDL_Surface *m_sdlsurf;
+#endif
int m_extra_flags;
@@ -143,6 +165,7 @@ private:
// monitor info
osd_monitor_info * m_monitor;
int m_fullscreen;
+ int m_index;
osd_renderer * m_renderer;
// static callbacks ...