diff options
Diffstat (limited to 'src/osd/sdl')
-rw-r--r-- | src/osd/sdl/SDLMain_tmpl.h | 13 | ||||
-rw-r--r-- | src/osd/sdl/SDLMain_tmpl.mm | 386 | ||||
-rw-r--r-- | src/osd/sdl/input.cpp | 246 | ||||
-rw-r--r-- | src/osd/sdl/osdsdl.h | 8 | ||||
-rw-r--r-- | src/osd/sdl/sdlfile.cpp | 2 | ||||
-rw-r--r-- | src/osd/sdl/sdlinc.h | 9 | ||||
-rw-r--r-- | src/osd/sdl/sdlmain.cpp | 60 | ||||
-rw-r--r-- | src/osd/sdl/sdlos_unix.cpp | 106 | ||||
-rw-r--r-- | src/osd/sdl/testkeys.cpp | 72 | ||||
-rw-r--r-- | src/osd/sdl/video.cpp | 237 | ||||
-rw-r--r-- | src/osd/sdl/video.h | 14 | ||||
-rw-r--r-- | src/osd/sdl/window.cpp | 198 | ||||
-rw-r--r-- | src/osd/sdl/window.h | 25 |
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 ... |