From cb982ee2edacbb1714a218515558f7b3e43e946d Mon Sep 17 00:00:00 2001 From: David Ludwig Date: Sat, 22 Jul 2017 20:29:30 -0400 Subject: [PATCH] use SDL 2.0.5+, rather than SDL 1.x This change may end up being a bit slower on some systems, as the SDL backend will now render its content to two, new, SDL_Surfaces: one of which is in the guest OS' resolution, the other of which is application defined. SDL2's SDL_Render API is used, which exposes some rudimentary elements of GPU + texture-based programming. Basilisk II now maintains a single 'SDL_Texture' object, which is an SDL representation of a GPU texture. The 'outer' surface will be used to update this texture, as requests to redraw are made. TODO: look into removing the 'outer' SDL surface, and see if we can just copy the 'inner' surface to the SDL_Texture. TODO: the entire SDL_Texture is updated, any time a request is made to draw. Look into minimizing this a bit. --- .../BasiliskII.xcodeproj/project.pbxproj | 40 +- BasiliskII/src/SDL/SDLMain.h | 16 - BasiliskII/src/SDL/SDLMain.m | 381 ----------------- BasiliskII/src/SDL/audio_sdl.cpp | 4 +- BasiliskII/src/SDL/video_sdl.cpp | 382 +++++++++++++----- BasiliskII/src/Unix/main_unix.cpp | 1 + 6 files changed, 305 insertions(+), 519 deletions(-) delete mode 100644 BasiliskII/src/SDL/SDLMain.h delete mode 100644 BasiliskII/src/SDL/SDLMain.m diff --git a/BasiliskII/src/MacOSX/BasiliskII.xcodeproj/project.pbxproj b/BasiliskII/src/MacOSX/BasiliskII.xcodeproj/project.pbxproj index 02e9485d..3069555a 100644 --- a/BasiliskII/src/MacOSX/BasiliskII.xcodeproj/project.pbxproj +++ b/BasiliskII/src/MacOSX/BasiliskII.xcodeproj/project.pbxproj @@ -7,6 +7,10 @@ objects = { /* Begin PBXBuildFile section */ + 752F26F11F240140001032B4 /* SDL2.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7539E1E51F23B288006B2DF2 /* SDL2.framework */; }; + 752F26F21F240140001032B4 /* SDL2.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7539E1E51F23B288006B2DF2 /* SDL2.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 752F26F91F240E51001032B4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 752F26F81F240E51001032B4 /* Foundation.framework */; }; + 752F26FB1F240E69001032B4 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 752F26FA1F240E69001032B4 /* IOKit.framework */; }; 7539DFBF1F23B17E006B2DF2 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7539DFBE1F23B17E006B2DF2 /* Assets.xcassets */; }; 7539E1251F23B25A006B2DF2 /* adb.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539DFC91F23B25A006B2DF2 /* adb.cpp */; }; 7539E1261F23B25A006B2DF2 /* audio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539DFCA1F23B25A006B2DF2 /* audio.cpp */; }; @@ -35,7 +39,6 @@ 7539E1731F23B25A006B2DF2 /* scsi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E0701F23B25A006B2DF2 /* scsi.cpp */; }; 7539E1741F23B25A006B2DF2 /* audio_sdl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E0721F23B25A006B2DF2 /* audio_sdl.cpp */; }; 7539E1751F23B25A006B2DF2 /* keycodes in Resources */ = {isa = PBXBuildFile; fileRef = 7539E0731F23B25A006B2DF2 /* keycodes */; }; - 7539E1761F23B25A006B2DF2 /* SDLMain.m in Sources */ = {isa = PBXBuildFile; fileRef = 7539E0751F23B25A006B2DF2 /* SDLMain.m */; }; 7539E1771F23B25A006B2DF2 /* video_sdl.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E0761F23B25A006B2DF2 /* video_sdl.cpp */; }; 7539E1781F23B25A006B2DF2 /* serial.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E0771F23B25A006B2DF2 /* serial.cpp */; }; 7539E18D1F23B25A006B2DF2 /* slot_rom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E0A21F23B25A006B2DF2 /* slot_rom.cpp */; }; @@ -79,8 +82,6 @@ 7539E26F1F23B32A006B2DF2 /* timer_unix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E2301F23B32A006B2DF2 /* timer_unix.cpp */; }; 7539E2701F23B32A006B2DF2 /* tinyxml2.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E2311F23B32A006B2DF2 /* tinyxml2.cpp */; }; 7539E2711F23B32A006B2DF2 /* tunconfig in Resources */ = {isa = PBXBuildFile; fileRef = 7539E2331F23B32A006B2DF2 /* tunconfig */; }; - 7539E27B1F23B488006B2DF2 /* SDL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7539E2771F23B469006B2DF2 /* SDL.framework */; }; - 7539E27C1F23B488006B2DF2 /* SDL.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7539E2771F23B469006B2DF2 /* SDL.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 7539E2801F23C4CA006B2DF2 /* main_unix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E27F1F23C4CA006B2DF2 /* main_unix.cpp */; }; 7539E28E1F23C56F006B2DF2 /* clip_dummy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E2851F23C56F006B2DF2 /* clip_dummy.cpp */; }; 7539E28F1F23C56F006B2DF2 /* ether_dummy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7539E2861F23C56F006B2DF2 /* ether_dummy.cpp */; }; @@ -102,13 +103,13 @@ /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ - 7539E27D1F23B489006B2DF2 /* Embed Frameworks */ = { + 752F26F31F240140001032B4 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; dstPath = ""; dstSubfolderSpec = 10; files = ( - 7539E27C1F23B488006B2DF2 /* SDL.framework in Embed Frameworks */, + 752F26F21F240140001032B4 /* SDL2.framework in Embed Frameworks */, ); name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; @@ -116,6 +117,8 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 752F26F81F240E51001032B4 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; + 752F26FA1F240E69001032B4 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; }; 7539DFB21F23B17E006B2DF2 /* BasiliskII.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BasiliskII.app; sourceTree = BUILT_PRODUCTS_DIR; }; 7539DFBE1F23B17E006B2DF2 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 7539DFC91F23B25A006B2DF2 /* adb.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = adb.cpp; path = ../adb.cpp; sourceTree = ""; }; @@ -182,8 +185,6 @@ 7539E0701F23B25A006B2DF2 /* scsi.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = scsi.cpp; path = ../scsi.cpp; sourceTree = ""; }; 7539E0721F23B25A006B2DF2 /* audio_sdl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = audio_sdl.cpp; sourceTree = ""; }; 7539E0731F23B25A006B2DF2 /* keycodes */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = keycodes; sourceTree = ""; }; - 7539E0741F23B25A006B2DF2 /* SDLMain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLMain.h; sourceTree = ""; }; - 7539E0751F23B25A006B2DF2 /* SDLMain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLMain.m; sourceTree = ""; }; 7539E0761F23B25A006B2DF2 /* video_sdl.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = video_sdl.cpp; sourceTree = ""; }; 7539E0771F23B25A006B2DF2 /* serial.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = serial.cpp; path = ../serial.cpp; sourceTree = ""; }; 7539E0A21F23B25A006B2DF2 /* slot_rom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = slot_rom.cpp; path = ../slot_rom.cpp; sourceTree = ""; }; @@ -258,7 +259,6 @@ 7539E2321F23B32A006B2DF2 /* tinyxml2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tinyxml2.h; sourceTree = ""; }; 7539E2331F23B32A006B2DF2 /* tunconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = tunconfig; sourceTree = ""; }; 7539E2351F23B32A006B2DF2 /* user_strings_unix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = user_strings_unix.h; sourceTree = ""; }; - 7539E2771F23B469006B2DF2 /* SDL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDL.framework; path = /Library/Frameworks/SDL.framework; sourceTree = ""; }; 7539E27E1F23BEB4006B2DF2 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = ""; }; 7539E27F1F23C4CA006B2DF2 /* main_unix.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = main_unix.cpp; sourceTree = ""; }; 7539E2851F23C56F006B2DF2 /* clip_dummy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = clip_dummy.cpp; sourceTree = ""; }; @@ -285,21 +285,32 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 7539E27B1F23B488006B2DF2 /* SDL.framework in Frameworks */, + 752F26FB1F240E69001032B4 /* IOKit.framework in Frameworks */, + 752F26F91F240E51001032B4 /* Foundation.framework in Frameworks */, + 752F26F11F240140001032B4 /* SDL2.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 752F26F71F240E51001032B4 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 752F26FA1F240E69001032B4 /* IOKit.framework */, + 752F26F81F240E51001032B4 /* Foundation.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; 7539DFA91F23B17E006B2DF2 = { isa = PBXGroup; children = ( 7539E1E41F23B25E006B2DF2 /* src */, 7539DFB41F23B17E006B2DF2 /* Assets */, 7539DFB31F23B17E006B2DF2 /* Products */, - 7539E2771F23B469006B2DF2 /* SDL.framework */, 7539E1E51F23B288006B2DF2 /* SDL2.framework */, + 752F26F71F240E51001032B4 /* Frameworks */, ); sourceTree = ""; }; @@ -403,8 +414,6 @@ children = ( 7539E0721F23B25A006B2DF2 /* audio_sdl.cpp */, 7539E0731F23B25A006B2DF2 /* keycodes */, - 7539E0741F23B25A006B2DF2 /* SDLMain.h */, - 7539E0751F23B25A006B2DF2 /* SDLMain.m */, 7539E0761F23B25A006B2DF2 /* video_sdl.cpp */, ); name = SDL; @@ -602,7 +611,7 @@ 7539DFAE1F23B17E006B2DF2 /* Sources */, 7539DFAF1F23B17E006B2DF2 /* Frameworks */, 7539DFB01F23B17E006B2DF2 /* Resources */, - 7539E27D1F23B489006B2DF2 /* Embed Frameworks */, + 752F26F31F240140001032B4 /* Embed Frameworks */, ); buildRules = ( ); @@ -710,7 +719,6 @@ 7539E2A71F23CB9B006B2DF2 /* cpustbl_nf.cpp in Sources */, 7539E1711F23B25A006B2DF2 /* rom_patches.cpp in Sources */, 7539E1281F23B25A006B2DF2 /* sigsegv.cpp in Sources */, - 7539E1761F23B25A006B2DF2 /* SDLMain.m in Sources */, 7539E1A21F23B25A006B2DF2 /* readcpu.cpp in Sources */, 7539E2701F23B32A006B2DF2 /* tinyxml2.cpp in Sources */, 7539E28F1F23C56F006B2DF2 /* ether_dummy.cpp in Sources */, @@ -816,7 +824,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ( - /Library/Frameworks/SDL.framework/Headers, + /Library/Frameworks/SDL2.framework/Headers, ../UNIX, ../include, ., @@ -865,7 +873,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ( - /Library/Frameworks/SDL.framework/Headers, + /Library/Frameworks/SDL2.framework/Headers, ../UNIX, ../include, ., diff --git a/BasiliskII/src/SDL/SDLMain.h b/BasiliskII/src/SDL/SDLMain.h deleted file mode 100644 index c56d90cb..00000000 --- a/BasiliskII/src/SDL/SDLMain.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SDLMain.m - main entry point for our Cocoa-ized SDL app - Initial Version: Darrell Walisser - Non-NIB-Code & other changes: Max Horn - - Feel free to customize this file to suit your needs -*/ - -#ifndef _SDLMain_h_ -#define _SDLMain_h_ - -#import - -@interface SDLMain : NSObject -@end - -#endif /* _SDLMain_h_ */ diff --git a/BasiliskII/src/SDL/SDLMain.m b/BasiliskII/src/SDL/SDLMain.m deleted file mode 100644 index 0f23664d..00000000 --- a/BasiliskII/src/SDL/SDLMain.m +++ /dev/null @@ -1,381 +0,0 @@ -/* SDLMain.m - main entry point for our Cocoa-ized SDL app - Initial Version: Darrell Walisser - Non-NIB-Code & other changes: Max Horn - - Feel free to customize this file to suit your needs -*/ - -#include "SDL.h" -#include "SDLMain.h" -#include /* for MAXPATHLEN */ -#include - -/* For some reaon, 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 1 -#ifdef SDL_USE_CPS -/* Portions of CPS.h */ -typedef struct CPSProcessSerNum -{ - UInt32 lo; - UInt32 hi; -} CPSProcessSerNum; - -extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn); -extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); -extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn); - -#endif /* SDL_USE_CPS */ - -static int gArgc; -static char **gArgv; -static BOOL gFinderLaunch; -static BOOL gCalledAppMainline = FALSE; - -static NSString *getApplicationName(void) -{ - const NSDictionary *dict; - NSString *appName = 0; - - /* Determine the application name */ - dict = (const 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 NSApplication (SDLApplication) -@end - -@implementation NSApplication (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, 1, (UInt8 *)parentdir, MAXPATHLEN)) { - chdir(parentdir); /* 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]; - } -} - -#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 */ - [NSApplication 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)) - [NSApplication sharedApplication]; - } -#endif /* SDL_USE_CPS */ - - /* Set up the menubar */ - [NSApp setMainMenu:[[[NSMenu alloc] init] autorelease]]; - setApplicationMenu(); - setupWindowMenu(); - - /* Create SDLMain and make it the app delegate */ - sdlMain = [[SDLMain alloc] init]; - [NSApp setDelegate:sdlMain]; - - /* Start the main event loop */ - [NSApp run]; - - [sdlMain release]; - [pool release]; -} - -#endif - - -/* - * Catch document open requests...this lets us notice files when the app - * was launched by double-clicking a document, or when a document was - * dragged/dropped on the app's icon. You need to have a - * CFBundleDocumentsType section in your Info.plist to get this message, - * apparently. - * - * Files are added to gArgv, so to the app, they'll look like command line - * arguments. Previously, apps launched from the finder had nothing but - * an argv[0]. - * - * This message may be received multiple times to open several docs on launch. - * - * This message is ignored once the app's mainline has been called. - */ -- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename -{ - const char *temparg; - size_t arglen; - char *arg; - char **newargv; - - if (!gFinderLaunch) /* MacOS is passing command line args. */ - return FALSE; - - if (gCalledAppMainline) /* app has started, ignore this document. */ - return FALSE; - - temparg = [filename UTF8String]; - arglen = SDL_strlen(temparg) + 1; - arg = (char *) SDL_malloc(arglen); - if (arg == NULL) - return FALSE; - - newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2)); - if (newargv == NULL) - { - SDL_free(arg); - return FALSE; - } - gArgv = newargv; - - SDL_strlcpy(arg, temparg, arglen); - gArgv[gArgc++] = arg; - gArgv[gArgc] = NULL; - return TRUE; -} - - -/* Called when the internal event loop has just started running */ -- (void) applicationDidFinishLaunching: (NSNotification *) note -{ - int status; - - /* Set the working directory to the .app's 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 - NSApplicationMain (argc, argv); -#else - CustomApplicationMain (argc, argv); -#endif - return 0; -} - diff --git a/BasiliskII/src/SDL/audio_sdl.cpp b/BasiliskII/src/SDL/audio_sdl.cpp index 921beb4c..bca3ff09 100644 --- a/BasiliskII/src/SDL/audio_sdl.cpp +++ b/BasiliskII/src/SDL/audio_sdl.cpp @@ -105,8 +105,8 @@ static bool open_sdl_audio(void) audio_spec.silence); #endif - char driver_name[32]; - printf("Using SDL/%s audio output\n", SDL_AudioDriverName(driver_name, sizeof(driver_name) - 1)); + const char * driver_name = SDL_GetCurrentAudioDriver(); + printf("Using SDL/%s audio output\n", driver_name ? driver_name : ""); silence_byte = audio_spec.silence; SDL_PauseAudio(0); diff --git a/BasiliskII/src/SDL/video_sdl.cpp b/BasiliskII/src/SDL/video_sdl.cpp index 99f3bfa6..b43ad49d 100644 --- a/BasiliskII/src/SDL/video_sdl.cpp +++ b/BasiliskII/src/SDL/video_sdl.cpp @@ -129,12 +129,16 @@ static bool use_keycodes = false; // Flag: Use keycodes rather than keysyms static int keycode_table[256]; // X keycode -> Mac keycode translation table // SDL variables +static SDL_Window * sdl_window = NULL; // Wraps an OS-native window +static SDL_Surface * inner_sdl_surface = NULL; // Surface in guest-OS display format +static SDL_Surface * outer_sdl_surface = NULL; // Surface in host-OS display format +static SDL_Renderer * sdl_renderer = NULL; // Handle to SDL2 renderer +static SDL_Texture * sdl_texture = NULL; // Handle to a GPU texture, with which to draw outer_sdl_surface to static int screen_depth; // Depth of current screen -static SDL_Cursor *sdl_cursor; // Copy of Mac cursor -static SDL_Color sdl_palette[256]; // Color palette to be used as CLUT and gamma table +//static SDL_Cursor *sdl_cursor; // Copy of Mac cursor +static SDL_Palette *sdl_palette = NULL; // Color palette to be used as CLUT and gamma table static bool sdl_palette_changed = false; // Flag: Palette changed, redraw thread must set new colors static bool toggle_fullscreen = false; -static const int sdl_eventmask = SDL_MOUSEEVENTMASK | SDL_KEYEVENTMASK | SDL_VIDEOEXPOSEMASK | SDL_QUITMASK | SDL_ACTIVEEVENTMASK; static bool mouse_grabbed = false; @@ -171,7 +175,7 @@ extern void SysMountFirstFloppy(void); #ifdef ENABLE_VOSF #define SDL_VIDEO_LOCK_VOSF_SURFACE(SURFACE) do { \ - if ((SURFACE)->flags & (SDL_HWSURFACE | SDL_FULLSCREEN)) \ + if ((SURFACE)->flags & (SDL_FULLSCREEN)) \ the_host_buffer = (uint8 *)(SURFACE)->pixels; \ } while (0) #else @@ -428,25 +432,15 @@ static int sdl_depth_of_video_depth(int video_depth) // Get screen dimensions static void sdl_display_dimensions(int &width, int &height) { - static int max_width, max_height; - if (max_width == 0 && max_height == 0) { - max_width = 640 ; max_height = 480; - SDL_Rect **modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE); - if (modes && modes != (SDL_Rect **)-1) { - // It turns out that on some implementations, and contrary to the documentation, - // the returned list is not sorted from largest to smallest (e.g. Windows) - for (int i = 0; modes[i] != NULL; i++) { - const int w = modes[i]->w; - const int h = modes[i]->h; - if (w > max_width && h > max_height) { - max_width = w; - max_height = h; - } - } - } + SDL_DisplayMode desktop_mode; + const int display_index = 0; // TODO: try supporting multiple displays + if (SDL_GetDesktopDisplayMode(display_index, &desktop_mode) != 0) { + // TODO: report a warning, here? + width = height = 0; + return; } - width = max_width; - height = max_height; + width = desktop_mode.w; + height = desktop_mode.h; } static inline int sdl_display_width(void) @@ -476,10 +470,8 @@ static bool has_mode(int type, int width, int height, int depth) if (width > sdl_display_width() || height > sdl_display_height()) return false; - // Rely on SDL capabilities - return SDL_VideoModeOK(width, height, - sdl_depth_of_video_depth(depth), - SDL_HWSURFACE | (type == DISPLAY_SCREEN ? SDL_FULLSCREEN : 0)) != 0; + // Whatever size it is, beyond what we've checked, we'll scale to/from as appropriate. + return true; } // Add mode to list of supported modes @@ -532,18 +524,20 @@ static void set_mac_frame_buffer(SDL_monitor_desc &monitor, int depth, bool nati // Set window name and class static void set_window_name(int name) { - const SDL_VideoInfo *vi = SDL_GetVideoInfo(); - if (vi && vi->wm_available) { - const char *str = GetString(name); - SDL_WM_SetCaption(str, str); + if (!sdl_window) { + return; } + const char *str = GetString(name); + SDL_SetWindowTitle(sdl_window, str); } // Set mouse grab mode -static SDL_GrabMode set_grab_mode(SDL_GrabMode mode) +static void set_grab_mode(bool grab) { - const SDL_VideoInfo *vi = SDL_GetVideoInfo(); - return (vi && vi->wm_available ? SDL_WM_GrabInput(mode) : SDL_GRAB_OFF); + if (!sdl_window) { + return; + } + SDL_SetWindowGrab(sdl_window, grab ? SDL_TRUE : SDL_FALSE); } // Migrate preferences items (XXX to be handled in MigratePrefs()) @@ -647,11 +641,149 @@ driver_base::driver_base(SDL_monitor_desc &m) the_buffer_copy = NULL; } +static void shutdown_sdl_video() +{ + if (sdl_texture) { + SDL_DestroyTexture(sdl_texture); + sdl_texture = NULL; + } + + if (sdl_renderer) { + SDL_DestroyRenderer(sdl_renderer); + sdl_renderer = NULL; + } + + if (inner_sdl_surface) { + if (inner_sdl_surface == outer_sdl_surface) { + outer_sdl_surface = NULL; + } + + SDL_FreeSurface(inner_sdl_surface); + inner_sdl_surface = NULL; + } + + if (outer_sdl_surface) { + SDL_FreeSurface(outer_sdl_surface); + outer_sdl_surface = NULL; + } + + if (sdl_window) { + SDL_DestroyWindow(sdl_window); + sdl_window = NULL; + } +} + +static SDL_Surface * init_sdl_video(int width, int height, int bpp, Uint32 flags) +{ + if (outer_sdl_surface) { + shutdown_sdl_video(); + } + + int window_width = width; + int window_height = height; + Uint32 window_flags = 0; + + if (flags & SDL_WINDOW_FULLSCREEN) { + SDL_DisplayMode desktop_mode; + if (SDL_GetDesktopDisplayMode(0, &desktop_mode) != 0) { + shutdown_sdl_video(); + return NULL; + } + window_flags |= SDL_WINDOW_FULLSCREEN; + window_width = desktop_mode.w; + window_height = desktop_mode.h; + } + + sdl_window = SDL_CreateWindow( + "Basilisk II", + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + window_width, + window_height, + window_flags); + if (!sdl_window) { + shutdown_sdl_video(); + return NULL; + } + + sdl_renderer = SDL_CreateRenderer(sdl_window, -1, SDL_RENDERER_ACCELERATED); + if (!sdl_renderer) { + shutdown_sdl_video(); + return NULL; + } + + sdl_texture = SDL_CreateTexture(sdl_renderer, SDL_PIXELFORMAT_RGB888, SDL_TEXTUREACCESS_STREAMING, width, height); + if (!sdl_texture) { + shutdown_sdl_video(); + return NULL; + } + + switch (bpp) { + case 8: + outer_sdl_surface = SDL_CreateRGBSurface(0, width, height, 8, 0, 0, 0, 0); + break; + case 16: + outer_sdl_surface = SDL_CreateRGBSurfaceWithFormat(0, width, height, 16, SDL_PIXELFORMAT_RGB565); + break; + case 32: + outer_sdl_surface = SDL_CreateRGBSurface(0, width, height, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); + inner_sdl_surface = outer_sdl_surface; + break; + default: + printf("WARNING: An unsupported bpp of %d was used\n", bpp); + break; + } + if (!outer_sdl_surface) { + shutdown_sdl_video(); + return NULL; + } + + if (!inner_sdl_surface) { + inner_sdl_surface = SDL_CreateRGBSurface(0, width, height, 32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); + if (!inner_sdl_surface) { + shutdown_sdl_video(); + return NULL; + } + } + + return outer_sdl_surface; +} + +static int update_sdl_video() +{ + if (!sdl_renderer || !sdl_texture || !outer_sdl_surface) { + printf("WARNING: A video mode does not appear to have been set.\n"); + return -1; + } + + if (inner_sdl_surface != outer_sdl_surface && + inner_sdl_surface != NULL && + outer_sdl_surface != NULL) + { + SDL_Rect destRect = {0, 0, inner_sdl_surface->w, inner_sdl_surface->h}; + if (SDL_BlitSurface(outer_sdl_surface, NULL, inner_sdl_surface, &destRect) != 0) { + return -1; + } + } + + if (SDL_UpdateTexture(sdl_texture, NULL, inner_sdl_surface->pixels, inner_sdl_surface->pitch) != 0) { + return -1; + } + + SDL_Rect src_rect = {0, 0, inner_sdl_surface->w, inner_sdl_surface->h}; + if (SDL_RenderCopy(sdl_renderer, sdl_texture, &src_rect, NULL) != 0) { + return -1; + } + + SDL_RenderPresent(sdl_renderer); + + return 0; +} + void driver_base::set_video_mode(int flags) { int depth = sdl_depth_of_video_depth(VIDEO_MODE_DEPTH); - if ((s = SDL_SetVideoMode(VIDEO_MODE_X, VIDEO_MODE_Y, depth, - SDL_HWSURFACE | flags)) == NULL) + if ((s = init_sdl_video(VIDEO_MODE_X, VIDEO_MODE_Y, depth, flags)) == NULL) return; #ifdef ENABLE_VOSF the_host_buffer = (uint8 *)s->pixels; @@ -660,7 +792,7 @@ void driver_base::set_video_mode(int flags) void driver_base::init() { - set_video_mode(display_type == DISPLAY_SCREEN ? SDL_FULLSCREEN : 0); + set_video_mode(display_type == DISPLAY_SCREEN ? SDL_WINDOW_FULLSCREEN : 0); int aligned_height = (VIDEO_MODE_Y + 15) & ~15; #ifdef ENABLE_VOSF @@ -785,8 +917,9 @@ void driver_base::update_palette(void) { const VIDEO_MODE &mode = monitor.get_current_mode(); - if ((int)VIDEO_MODE_DEPTH <= VIDEO_DEPTH_8BIT) - SDL_SetPalette(s, SDL_PHYSPAL, sdl_palette, 0, 256); + if ((int)VIDEO_MODE_DEPTH <= VIDEO_DEPTH_8BIT) { + SDL_SetSurfacePalette(s, sdl_palette); + } } // Disable mouse acceleration @@ -812,12 +945,10 @@ void driver_base::toggle_mouse_grab(void) void driver_base::grab_mouse(void) { if (!mouse_grabbed) { - SDL_GrabMode new_mode = set_grab_mode(SDL_GRAB_ON); - if (new_mode == SDL_GRAB_ON) { - set_window_name(STR_WINDOW_TITLE_GRABBED); - disable_mouse_accel(); - ADBSetRelMouseMode(mouse_grabbed = true); - } + set_grab_mode(true); + set_window_name(STR_WINDOW_TITLE_GRABBED); + disable_mouse_accel(); + ADBSetRelMouseMode(mouse_grabbed = true); } } @@ -825,12 +956,10 @@ void driver_base::grab_mouse(void) void driver_base::ungrab_mouse(void) { if (mouse_grabbed) { - SDL_GrabMode new_mode = set_grab_mode(SDL_GRAB_OFF); - if (new_mode == SDL_GRAB_OFF) { - set_window_name(STR_WINDOW_TITLE); - restore_mouse_accel(); - ADBSetRelMouseMode(mouse_grabbed = false); - } + set_grab_mode(false); + set_window_name(STR_WINDOW_TITLE); + restore_mouse_accel(); + ADBSetRelMouseMode(mouse_grabbed = false); } } @@ -861,8 +990,7 @@ static void keycode_init(void) keycode_table[i] = -1; // Search for server vendor string, then read keycodes - char video_driver[256]; - SDL_VideoDriverName(video_driver, sizeof(video_driver)); + const char * video_driver = SDL_GetCurrentVideoDriver(); bool video_driver_found = false; char line[256]; int n_keys = 0; @@ -895,7 +1023,7 @@ static void keycode_init(void) static const char sdl_str[] = "sdl"; if (strncmp(line, sdl_str, sizeof(sdl_str) - 1) == 0) { char *p = line + sizeof(sdl_str); - if (strstr(video_driver, p) == video_driver) + if (video_driver && strstr(video_driver, p) == video_driver) video_driver_found = true; } } @@ -908,12 +1036,12 @@ static void keycode_init(void) // Vendor not found? Then display warning if (!video_driver_found) { char str[256]; - snprintf(str, sizeof(str), GetString(STR_KEYCODE_VENDOR_WARN), video_driver, kc_path ? kc_path : KEYCODE_FILE_NAME); + snprintf(str, sizeof(str), GetString(STR_KEYCODE_VENDOR_WARN), video_driver ? video_driver : "", kc_path ? kc_path : KEYCODE_FILE_NAME); WarningAlert(str); return; } - D(bug("Using SDL/%s keycodes table, %d key mappings\n", video_driver, n_keys)); + D(bug("Using SDL/%s keycodes table, %d key mappings\n", video_driver ? video_driver : "", n_keys)); } } @@ -954,7 +1082,7 @@ bool SDL_monitor_desc::video_open(void) // Start redraw/input thread #ifndef USE_CPU_EMUL_SERVICES redraw_thread_cancel = false; - redraw_thread_active = ((redraw_thread = SDL_CreateThread(redraw_func, NULL)) != NULL); + redraw_thread_active = ((redraw_thread = SDL_CreateThread(redraw_func, "Redraw Thread", NULL)) != NULL); if (!redraw_thread_active) { printf("FATAL: cannot create redraw thread\n"); return false; @@ -1032,7 +1160,11 @@ bool VideoInit(bool classic) default_height = sdl_display_height(); // Mac screen depth follows X depth - screen_depth = SDL_GetVideoInfo()->vfmt->BitsPerPixel; + screen_depth = 32; + SDL_DisplayMode desktop_mode; + if (SDL_GetDesktopDisplayMode(0, &desktop_mode) == 0) { + screen_depth = SDL_BITSPERPIXEL(desktop_mode.format); + } int default_depth; switch (screen_depth) { case 8: @@ -1241,7 +1373,7 @@ static void do_toggle_fullscreen(void) // switch modes display_type = (display_type == DISPLAY_SCREEN) ? DISPLAY_WINDOW : DISPLAY_SCREEN; - drv->set_video_mode(display_type == DISPLAY_SCREEN ? SDL_FULLSCREEN : 0); + drv->set_video_mode(display_type == DISPLAY_SCREEN ? SDL_WINDOW_FULLSCREEN : 0); drv->adapt_to_video_mode(); // reset the palette @@ -1253,7 +1385,7 @@ static void do_toggle_fullscreen(void) // restore the screen contents SDL_BlitSurface(tmp_surface, NULL, drv->s, NULL); SDL_FreeSurface(tmp_surface); - SDL_UpdateRect(drv->s, 0, 0, 0, 0); + update_sdl_video(); // reset the video refresh handler VideoRefreshInit(); @@ -1262,7 +1394,7 @@ static void do_toggle_fullscreen(void) ADBKeyUp(0x36); // restore the mouse position - SDL_WarpMouse(x, y); + SDL_WarpMouseGlobal(x, y); // resume redraw thread toggle_fullscreen = false; @@ -1351,7 +1483,12 @@ void SDL_monitor_desc::set_palette(uint8 *pal, int num_in) // Convert colors to XColor array int num_out = 256; bool stretch = false; - SDL_Color *p = sdl_palette; + + if (!sdl_palette) { + sdl_palette = SDL_AllocPalette(num_out); + } + + SDL_Color *p = sdl_palette->colors; for (int i=0; ir = pal[c*3 + 0] * 0x0101; @@ -1523,27 +1660,25 @@ void video_set_cursor(void) static bool is_modifier_key(SDL_KeyboardEvent const & e) { switch (e.keysym.sym) { - case SDLK_NUMLOCK: + case SDLK_NUMLOCKCLEAR: case SDLK_CAPSLOCK: - case SDLK_SCROLLOCK: + case SDLK_SCROLLLOCK: case SDLK_RSHIFT: case SDLK_LSHIFT: case SDLK_RCTRL: case SDLK_LCTRL: case SDLK_RALT: case SDLK_LALT: - case SDLK_RMETA: - case SDLK_LMETA: - case SDLK_LSUPER: - case SDLK_RSUPER: + case SDLK_RGUI: + case SDLK_LGUI: case SDLK_MODE: - case SDLK_COMPOSE: + case SDLK_APPLICATION: return true; } return false; } -static bool is_ctrl_down(SDL_keysym const & ks) +static bool is_ctrl_down(SDL_Keysym const & ks) { return ctrl_down || (ks.mod & KMOD_CTRL); } @@ -1554,7 +1689,7 @@ static bool is_ctrl_down(SDL_keysym const & ks) * and -2 if the key was recognized as a hotkey */ -static int kc_decode(SDL_keysym const & ks, bool key_down) +static int kc_decode(SDL_Keysym const & ks, bool key_down) { switch (ks.sym) { case SDLK_a: return 0x00; @@ -1626,19 +1761,17 @@ static int kc_decode(SDL_keysym const & ks, bool key_down) #if (defined(__APPLE__) && defined(__MACH__)) case SDLK_LALT: return 0x3a; case SDLK_RALT: return 0x3a; - case SDLK_LMETA: return 0x37; - case SDLK_RMETA: return 0x37; + case SDLK_LGUI: return 0x37; + case SDLK_RGUI: return 0x37; #else case SDLK_LALT: return 0x37; case SDLK_RALT: return 0x37; - case SDLK_LMETA: return 0x3a; - case SDLK_RMETA: return 0x3a; + case SDLK_LGUI: return 0x3a; + case SDLK_RGUI: return 0x3a; #endif - case SDLK_LSUPER: return 0x3a; // "Windows" key - case SDLK_RSUPER: return 0x3a; case SDLK_MENU: return 0x32; case SDLK_CAPSLOCK: return 0x39; - case SDLK_NUMLOCK: return 0x47; + case SDLK_NUMLOCKCLEAR: return 0x47; case SDLK_UP: return 0x3e; case SDLK_DOWN: return 0x3d; @@ -1660,20 +1793,20 @@ static int kc_decode(SDL_keysym const & ks, bool key_down) case SDLK_F11: return 0x67; case SDLK_F12: return 0x6f; - case SDLK_PRINT: return 0x69; - case SDLK_SCROLLOCK: return 0x6b; + case SDLK_PRINTSCREEN: return 0x69; + case SDLK_SCROLLLOCK: return 0x6b; case SDLK_PAUSE: return 0x71; - case SDLK_KP0: return 0x52; - case SDLK_KP1: return 0x53; - case SDLK_KP2: return 0x54; - case SDLK_KP3: return 0x55; - case SDLK_KP4: return 0x56; - case SDLK_KP5: return 0x57; - case SDLK_KP6: return 0x58; - case SDLK_KP7: return 0x59; - case SDLK_KP8: return 0x5b; - case SDLK_KP9: return 0x5c; + case SDLK_KP_0: return 0x52; + case SDLK_KP_1: return 0x53; + case SDLK_KP_2: return 0x54; + case SDLK_KP_3: return 0x55; + case SDLK_KP_4: return 0x56; + case SDLK_KP_5: return 0x57; + case SDLK_KP_6: return 0x58; + case SDLK_KP_7: return 0x59; + case SDLK_KP_8: return 0x5b; + case SDLK_KP_9: return 0x5c; case SDLK_KP_PERIOD: return 0x41; case SDLK_KP_PLUS: return 0x45; case SDLK_KP_MINUS: return 0x4e; @@ -1713,15 +1846,52 @@ static void force_complete_window_refresh() * SDL event handling */ +static void scale_mouse_event_coordinates(void *userdata, SDL_Event * event) +{ + if (!inner_sdl_surface || !sdl_window) { + return; + } + + int window_width = 0; + int window_height = 0; + SDL_GetWindowSize(sdl_window, &window_width, &window_height); + if (window_width == 0 || window_height == 0) { + return; + } + + float scale_x = (float)inner_sdl_surface->w / (float)window_width; + float scale_y = (float)inner_sdl_surface->h / (float)window_height; + + switch (event->type) { + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + event->button.x = (int)(event->button.x * scale_x); + event->button.y = (int)(event->button.y * scale_y); + break; + + case SDL_MOUSEMOTION: + event->motion.x = (int)(event->motion.x * scale_x); + event->motion.y = (int)(event->motion.y * scale_y); + event->motion.xrel = (int)(event->motion.xrel * scale_x); + event->motion.yrel = (int)(event->motion.yrel * scale_y); + break; + } +} + static void handle_events(void) { SDL_Event events[10]; const int n_max_events = sizeof(events) / sizeof(events[0]); int n_events; - while ((n_events = SDL_PeepEvents(events, n_max_events, SDL_GETEVENT, sdl_eventmask)) > 0) { + while ((n_events = SDL_PeepEvents(events, n_max_events, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT)) > 0) { for (int i = 0; i < n_events; i++) { - SDL_Event const & event = events[i]; + SDL_Event & event = events[i]; + + // Make sure events with mouse coordinates get scaled, in case the Mac's + // display size is different than the host OS' window. + scale_mouse_event_coordinates(NULL, &events[i]); + switch (event.type) { // Mouse button @@ -1820,24 +1990,28 @@ static void handle_events(void) } break; } - - // Hidden parts exposed, force complete refresh of window - case SDL_VIDEOEXPOSE: - force_complete_window_refresh(); + + case SDL_WINDOWEVENT: { + switch (event.window.event) { + // Hidden parts exposed, force complete refresh of window + case SDL_WINDOWEVENT_EXPOSED: + force_complete_window_refresh(); + break; + + // Force a complete window refresh when activating, to avoid redraw artifacts otherwise. + case SDL_WINDOWEVENT_RESTORED: + force_complete_window_refresh(); + break; + + } break; + } // Window "close" widget clicked case SDL_QUIT: ADBKeyDown(0x7f); // Power key ADBKeyUp(0x7f); break; - - // Application activate/deactivate - case SDL_ACTIVEEVENT: - // Force a complete window refresh when activating, to avoid redraw artifacts otherwise. - if (event.active.gain && (event.active.state & SDL_APPACTIVE)) - force_complete_window_refresh(); - break; } } } @@ -1885,7 +2059,7 @@ static void update_display_static(driver_base *drv) SDL_UnlockSurface(drv->s); // Refresh display - SDL_UpdateRect(drv->s, 0, 0, 0, 0); + update_sdl_video(); /* // Incremental update code @@ -2091,7 +2265,7 @@ static void update_display_static_bbox(driver_base *drv) // Refresh display if (nr_boxes) - SDL_UpdateRects(drv->s, nr_boxes, boxes); + update_sdl_video(); } diff --git a/BasiliskII/src/Unix/main_unix.cpp b/BasiliskII/src/Unix/main_unix.cpp index 1f03b9a0..d996c6a5 100644 --- a/BasiliskII/src/Unix/main_unix.cpp +++ b/BasiliskII/src/Unix/main_unix.cpp @@ -27,6 +27,7 @@ #ifdef USE_SDL # include +# include #endif #ifndef USE_SDL_VIDEO