Initial commit

This commit is contained in:
2026-02-02 04:50:13 +01:00
commit 5b11698731
22592 changed files with 7677434 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef APPMENU_OSX_H
#define APPMENU_OSX_H
#if defined(MACOSX)
void replaceApplicationMenuItems();
void releaseMenu();
#endif // MACOSX
#endif

View File

@@ -0,0 +1,350 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
// Disable symbol overrides so that we can use system headers.
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#include "backends/platform/sdl/macosx/appmenu_osx.h"
#include "common/translation.h"
#include "common/ustr.h"
#include "backends/platform/sdl/macosx/macosx-compat.h"
#include <Cocoa/Cocoa.h>
#include <AppKit/NSWorkspace.h>
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_12
#define NSEventModifierFlagCommand NSCommandKeyMask
#define NSEventModifierFlagOption NSAlternateKeyMask
#endif
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_10
#define NSEventModifierFlags NSUInteger
#endif
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
// https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Cocoa64BitGuide/64BitChangesCocoa/64BitChangesCocoa.html
#if __LP64__ || NS_BUILD_32_LIKE_64
typedef unsigned long NSUInteger;
#else
typedef unsigned int NSUInteger;
#endif
// Those are not defined in the 10.4 SDK, but they are defined when targeting
// Mac OS X 10.4 or above in the 10.5 SDK, and they do work with 10.4.
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
enum {
NSUTF32StringEncoding = 0x8c000100,
NSUTF32BigEndianStringEncoding = 0x98000100,
NSUTF32LittleEndianStringEncoding = 0x9c000100
};
#endif
#endif
// Apple removed setAppleMenu from the header files in 10.4,
// but as the method still exists we declare it ourselves here.
// Yes, this works :)
@interface NSApplication(MissingFunction)
- (void)setAppleMenu:(NSMenu *)menu;
@end
// However maybe we should conditionally use it depending on the system on which we run ScummVM (and not
// the one on which we compile) to only do it on OS X 10.5.
// Here is the relevant bit from the release notes for 10.6:
// In Leopard and earlier, apps that tried to construct a menu bar without a nib would get an undesirable
// stubby application menu that could not be removed. To work around this problem on Leopard, you can call
// the undocumented setAppleMenu: method and pass it the application menu, like so:
// [NSApp setAppleMenu:[[[NSApp mainMenu] itemAtIndex:0] submenu]];
// In SnowLeopard, this workaround is unnecessary and should not be used. Under SnowLeopard, the first menu
// is always identified as the application menu.
static void openFromBundle(NSString *file, NSString *subdir = nil) {
NSString *path = nil;
NSArray *types = [NSArray arrayWithObjects:@"rtf", @"html", @"txt", @"", @"md", nil];
NSEnumerator *typeEnum = [types objectEnumerator];
NSString *type;
while ((type = [typeEnum nextObject])) {
if (subdir)
path = [[NSBundle mainBundle] pathForResource:file ofType:type inDirectory:subdir];
else
path = [[NSBundle mainBundle] pathForResource:file ofType:type];
if (path)
break;
}
// RTF, TXT, and HTML files are widely recognized and we can rely on the default
// file association working for those. For the other ones this might not be
// the case so we explicitly indicate they should be open with TextEdit.
if (path) {
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_15
if ([path hasSuffix:@".html"] || [path hasSuffix:@".rtf"] || [path hasSuffix:@".txt"])
[[NSWorkspace sharedWorkspace] openFile:path];
else
[[NSWorkspace sharedWorkspace] openFile:path withApplication:@"TextEdit"];
#else
NSURL *pathUrl = [NSURL fileURLWithPath:path isDirectory:NO];
if ([path hasSuffix:@".html"] || [path hasSuffix:@".rtf"] || [path hasSuffix:@".txt"]) {
[[NSWorkspace sharedWorkspace] openURL:pathUrl];
} else {
[[NSWorkspace sharedWorkspace] openURLs:[NSArray arrayWithObjects:pathUrl, nil]
withApplicationAtURL:[[NSWorkspace sharedWorkspace] URLForApplicationWithBundleIdentifier:@"com.apple.TextEdit"]
configuration:[NSWorkspaceOpenConfiguration configuration]
completionHandler:nil
];
}
#endif
}
}
@interface ScummVMMenuHandler : NSObject {
}
- (void) openReadme;
- (void) openLicenseGPL;
- (void) openLicenseApache;
- (void) openLicenseBSD;
- (void) openLicenseBSL;
- (void) openLicenseGLAD;
- (void) openLicenseISC;
- (void) openLicenseLGPL;
- (void) openLicenseLUA;
- (void) openLicenseMIT;
- (void) openLicenseMKV;
- (void) openLicenseMPL;
- (void) openLicenseOFL;
- (void) openLicenseTinyGL;
- (void) openLicenseCatharon;
- (void) openNews;
- (void) openUserManual;
- (void) openCredits;
@end
@implementation ScummVMMenuHandler : NSObject
- (void)openReadme {
openFromBundle(@"README");
}
- (void)openLicenseGPL {
openFromBundle(@"COPYING", @"licenses");
}
- (void)openLicenseApache {
openFromBundle(@"COPYING-Apache", @"licenses");
}
- (void)openLicenseBSD {
openFromBundle(@"COPYING-BSD", @"licenses");
}
- (void)openLicenseBSL {
openFromBundle(@"COPYING-BSL", @"licenses");
}
- (void)openLicenseGLAD {
openFromBundle(@"COPYING-GLAD", @"licenses");
}
- (void)openLicenseISC {
openFromBundle(@"COPYING-ISC", @"licenses");
}
- (void)openLicenseLGPL {
openFromBundle(@"COPYING-LGPL", @"licenses");
}
- (void)openLicenseLUA {
openFromBundle(@"COPYING-LUA", @"licenses");
}
- (void)openLicenseMIT {
openFromBundle(@"COPYING-MIT", @"licenses");
}
- (void)openLicenseMKV {
openFromBundle(@"COPYING-MKV", @"licenses");
}
- (void)openLicenseMPL {
openFromBundle(@"COPYING-MPL", @"licenses");
}
- (void)openLicenseOFL {
openFromBundle(@"COPYING-OFL", @"licenses");
}
- (void)openLicenseTinyGL {
openFromBundle(@"COPYING-TINYGL", @"licenses");
}
- (void)openLicenseCatharon {
openFromBundle(@"CatharonLicense", @"licenses");
}
- (void)openNews {
openFromBundle(@"NEWS");
}
- (void)openUserManual {
NSString *bundlePath = [[NSBundle mainBundle] resourcePath];
// If present locally in the bundle, open that file.
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
NSArray *dirContents = [[NSFileManager defaultManager] directoryContentsAtPath:bundlePath];
#else
NSArray *dirContents = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:bundlePath error:nil];
#endif
if (dirContents != nil) {
NSEnumerator *dirEnum = [dirContents objectEnumerator];
NSString *file;
while ((file = [dirEnum nextObject])) {
if ([file hasPrefix:@"ScummVM Manual"] && [file hasSuffix:@".pdf"]) {
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_15
[[NSWorkspace sharedWorkspace] openFile:[bundlePath stringByAppendingPathComponent:file]];
#else
NSURL *fileUrl = [NSURL fileURLWithPath:[bundlePath stringByAppendingPathComponent:file] isDirectory:NO];
[[NSWorkspace sharedWorkspace] openURL:fileUrl];
#endif
return;
}
}
}
// Otherwise try to access the only version.
[[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"https://docs.scummvm.org/"]];
}
- (void)openCredits {
openFromBundle(@"AUTHORS");
}
@end
NSString *constructNSStringFromU32String(const Common::U32String &rawU32String) {
#ifdef SCUMM_LITTLE_ENDIAN
NSStringEncoding stringEncoding = NSUTF32LittleEndianStringEncoding;
#else
NSStringEncoding stringEncoding = NSUTF32BigEndianStringEncoding;
#endif
return [[NSString alloc] initWithBytes:rawU32String.c_str() length:4*rawU32String.size() encoding: stringEncoding];
}
static NSMenu *addMenu(const Common::U32String &title, NSString *key, SEL setAs) {
if (setAs && ![NSApp respondsToSelector:setAs]) {
return nil;
}
NSString *str = constructNSStringFromU32String(title);
NSMenu *menu = [[NSMenu alloc] initWithTitle:str];
NSMenuItem *menuItem = [[NSMenuItem alloc] initWithTitle:str action:nil keyEquivalent:key];
[menuItem setSubmenu:menu];
[[NSApp mainMenu] addItem:menuItem];
if (setAs) {
[NSApp performSelector:setAs withObject:menu];
}
[str release];
[menuItem release];
return menu;
}
static void addMenuItem(const Common::U32String &title, id target, SEL selector, NSString *key, NSMenu *parent, NSEventModifierFlags flags = 0) {
NSString *nsString = constructNSStringFromU32String(title);
NSMenuItem *menuItem = [[NSMenuItem alloc]
initWithTitle:nsString
action:selector
keyEquivalent:key];
if (target) {
[menuItem setTarget:target];
}
if (flags) {
[menuItem setKeyEquivalentModifierMask:flags];
}
[parent addItem:menuItem];
[nsString release];
}
static ScummVMMenuHandler *delegate = nullptr;
void releaseMenu() {
[delegate release];
delegate = nullptr;
}
void replaceApplicationMenuItems() {
// We cannot use [[NSApp mainMenu] removeAllItems] as removeAllItems was added in OS X 10.6
// So remove the SDL generated menus one by one instead.
while ([[NSApp mainMenu] numberOfItems] > 0) {
[[NSApp mainMenu] removeItemAtIndex:0];
}
NSMenu *appleMenu = addMenu(Common::U32String("ScummVM"), @"", @selector(setAppleMenu:));
if (appleMenu) {
addMenuItem(_("About ScummVM"), nil, @selector(orderFrontStandardAboutPanel:), @"", appleMenu);
[appleMenu addItem:[NSMenuItem separatorItem]];
addMenuItem(_("Hide ScummVM"), nil, @selector(hide:), @"h", appleMenu);
addMenuItem(_("Hide Others"), nil, @selector(hideOtherApplications:), @"h", appleMenu, (NSEventModifierFlagOption|NSEventModifierFlagCommand));
addMenuItem(_("Show All"), nil, @selector(unhideAllApplications:), @"", appleMenu);
[appleMenu addItem:[NSMenuItem separatorItem]];
addMenuItem(_("Quit ScummVM"), nil, @selector(terminate:), @"q", appleMenu);
}
NSMenu *windowMenu = addMenu(_("Window"), @"", @selector(setWindowsMenu:));
if (windowMenu) {
addMenuItem(_("Minimize"), nil, @selector(performMiniaturize:), @"m", windowMenu);
}
// Note: special care must be taken for the Help menu before 10.6,
// as setHelpMenu didn't exist yet: give an explicit nil for it in
// addMenu(), and also make sure it's created last.
SEL helpMenuSelector = [NSApp respondsToSelector:@selector(setHelpMenu:)] ? @selector(setHelpMenu:) : nil;
NSMenu *helpMenu = addMenu(_("Help"), @"", helpMenuSelector);
if (helpMenu) {
if (!delegate) {
delegate = [[ScummVMMenuHandler alloc] init];
}
addMenuItem(_("User Manual"), delegate, @selector(openUserManual), @"", helpMenu);
[helpMenu addItem:[NSMenuItem separatorItem]];
addMenuItem(_("General Information"), delegate, @selector(openReadme), @"", helpMenu);
addMenuItem(_("What's New in ScummVM"), delegate, @selector(openNews), @"", helpMenu);
[helpMenu addItem:[NSMenuItem separatorItem]];
addMenuItem(_("Credits"), delegate, @selector(openCredits), @"", helpMenu);
addMenuItem(_("GPL License"), delegate, @selector(openLicenseGPL), @"", helpMenu);
addMenuItem(_("LGPL License"), delegate, @selector(openLicenseLGPL), @"", helpMenu);
addMenuItem(_("OFL License"), delegate, @selector(openLicenseOFL), @"", helpMenu);
addMenuItem(_("BSD License"), delegate, @selector(openLicenseBSD), @"", helpMenu);
addMenuItem(_("Apache License"), delegate, @selector(openLicenseApache), @"", helpMenu);
addMenuItem(_("BSL License"), delegate, @selector(openLicenseBSL), @"", helpMenu);
addMenuItem(_("GLAD License"), delegate, @selector(openLicenseGLAD), @"", helpMenu);
addMenuItem(_("ISC License"), delegate, @selector(openLicenseISC), @"", helpMenu);
addMenuItem(_("Lua License"), delegate, @selector(openLicenseLUA), @"", helpMenu);
addMenuItem(_("MIT License"), delegate, @selector(openLicenseMIT), @"", helpMenu);
addMenuItem(_("MKV License"), delegate, @selector(openLicenseMKV), @"", helpMenu);
addMenuItem(_("MPL License"), delegate, @selector(openLicenseMPL), @"", helpMenu);
addMenuItem(_("TinyGL License"), delegate, @selector(openLicenseTinyGL), @"", helpMenu);
addMenuItem(_("Catharon License"), delegate, @selector(openLicenseCatharon), @"", helpMenu);
}
[appleMenu release];
[windowMenu release];
[helpMenu release];
}

View File

@@ -0,0 +1,51 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PLATFORM_SDL_MACOSX_COMPAT_H
#define PLATFORM_SDL_MACOSX_COMPAT_H
#include <AvailabilityMacros.h>
#ifndef MAC_OS_X_VERSION_10_5
#define MAC_OS_X_VERSION_10_5 1050
#endif
#ifndef MAC_OS_X_VERSION_10_6
#define MAC_OS_X_VERSION_10_6 1060
#endif
#ifndef MAC_OS_X_VERSION_10_7
#define MAC_OS_X_VERSION_10_7 1070
#endif
#ifndef MAC_OS_X_VERSION_10_10
#define MAC_OS_X_VERSION_10_10 101000
#endif
#ifndef MAC_OS_X_VERSION_10_12
#define MAC_OS_X_VERSION_10_12 101200
#endif
#ifndef MAC_OS_X_VERSION_10_15
#define MAC_OS_X_VERSION_10_15 101500
#endif
#endif

View File

@@ -0,0 +1,52 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "common/scummsys.h"
#ifdef MACOSX
#include "backends/platform/sdl/macosx/macosx.h"
#include "backends/plugins/sdl/macosx/macosx-provider.h"
#include "base/main.h"
int main(int argc, char *argv[]) {
// Create our OSystem instance
g_system = new OSystem_MacOSX();
assert(g_system);
// Pre initialize the backend
g_system->init();
#ifdef DYNAMIC_MODULES
PluginManager::instance().addPluginProvider(new MacOSXPluginProvider());
#endif
// Invoke the actual ScummVM main entry point:
int res = scummvm_main(argc, argv);
// Free OSystem
g_system->destroy();
return res;
}
#endif

View File

@@ -0,0 +1,33 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PLATFORM_SDL_MACOSX_TOUCHBAR_H
#define PLATFORM_SDL_MACOSX_TOUCHBAR_H
#if defined(MACOSX)
void macOSTouchbarCreate();
void macOSTouchbarDestroy();
void macOSTouchbarUpdate(const char *message);
#endif // MACOSX
#endif

View File

@@ -0,0 +1,135 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
// Disable symbol overrides so that we can use system headers.
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#include "backends/platform/sdl/macosx/appmenu_osx.h"
#include "backends/platform/sdl/macosx/macosx-compat.h"
#include "common/system.h"
#include "common/events.h"
#include <Cocoa/Cocoa.h>
#include <AppKit/NSWorkspace.h>
#if defined(MAC_OS_X_VERSION_10_12_2) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_12_2
@interface ScummVMlTouchbarDelegate : NSResponder <NSTouchBarDelegate>
@end
@implementation ScummVMlTouchbarDelegate
NSColor *font_color;
NSColor *back_color;
NSButton *tbButton;
- (instancetype)init {
if (self = [super init]) {
font_color = [NSColor whiteColor];
back_color = [NSColor colorWithCalibratedRed:0 green:0.8 blue:0.2 alpha:1.0f];
tbButton = [[NSButton alloc] init];
[[tbButton cell] setBackgroundColor:back_color];
[tbButton setAction:@selector(actionKey:)];
[tbButton setTarget:self];
[self setButton:nil];
}
return self;
}
- (NSTouchBar *)makeTouchBar {
NSTouchBar *bar = [[NSTouchBar alloc] init];
bar.delegate = self;
bar.customizationIdentifier = @"org.ScummVM.Touchbar.Customization";
bar.defaultItemIdentifiers = @[@"textButton"];
return bar;
}
- (nullable NSTouchBarItem *)touchBar:(NSTouchBar *)touchBar makeItemForIdentifier:(NSTouchBarItemIdentifier)identifier {
NSCustomTouchBarItem *customItem = [[NSCustomTouchBarItem alloc] initWithIdentifier:@"textButton"];
customItem.view = tbButton;
customItem.visibilityPriority = NSTouchBarItemPriorityHigh;
return customItem;
}
- (void)setButton : (const char *)title {
NSString *ns_title = nil;
if (title) {
ns_title = [NSString stringWithUTF8String:title];
} else {
ns_title = [NSString stringWithUTF8String:"ScummVM"];
}
NSMutableAttributedString *att_title = [[NSMutableAttributedString alloc] initWithString:ns_title];
[tbButton setAttributedTitle:att_title];
[tbButton invalidateIntrinsicContentSize];
}
- (IBAction) actionKey : (id) sender {
Common::Event event;
event.type = Common::EVENT_MAINMENU;
g_system->getEventManager()->pushEvent(event);
}
@end
static ScummVMlTouchbarDelegate *g_tb_delegate = nil;
void macOSTouchbarUpdate(const char *message) {
[g_tb_delegate setButton:message];
}
void macOSTouchbarCreate() {
if (g_tb_delegate)
return;
if (NSAppKitVersionNumber < NSAppKitVersionNumber10_12_2)
return;
NSApplication *app = [NSApplication sharedApplication];
if (!app)
return;
g_tb_delegate = [[ScummVMlTouchbarDelegate alloc] init];
if (g_tb_delegate) {
g_tb_delegate.nextResponder = app.nextResponder;
app.nextResponder = g_tb_delegate;
}
}
void macOSTouchbarDestroy() {
}
#else
void macOSTouchbarCreate() {}
void macOSTouchbarDestroy() {}
void macOSTouchbarUpdate(const char *message) {}
#endif

View File

@@ -0,0 +1,38 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef BACKENDS_PLATFORM_SDL_MACOSX_MACOSX_WINDOW_H
#define BACKENDS_PLATFORM_SDL_MACOSX_MACOSX_WINDOW_H
#ifdef MACOSX
#include "backends/platform/sdl/sdl-window.h"
class SdlWindow_MacOSX final : public SdlWindow {
public:
// Use an iconless window on macOS, as we use a nicer external icon there.
void setupIcon() override {}
float getDpiScalingFactor() const override;
};
#endif
#endif

View File

@@ -0,0 +1,42 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
// Disable symbol overrides so that we can use system headers.
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#include "backends/platform/sdl/macosx/macosx-window.h"
#include "backends/platform/sdl/macosx/macosx-compat.h"
#include <AppKit/NSWindow.h>
float SdlWindow_MacOSX::getDpiScalingFactor() const {
#if !SDL_VERSION_ATLEAST(3, 0, 0) && SDL_VERSION_ATLEAST(2, 0, 0) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
SDL_SysWMinfo wmInfo;
if (getSDLWMInformation(&wmInfo)) {
NSWindow *nswindow = wmInfo.info.cocoa.window;
if ([nswindow respondsToSelector:@selector(backingScaleFactor)]) {
debug(4, "Reported DPI ratio: %g", [nswindow backingScaleFactor]);
return [nswindow backingScaleFactor];
}
}
#endif
return SdlWindow::getDpiScalingFactor();
}

View File

@@ -0,0 +1,303 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
// Disable symbol overrides so that we can use system headers.
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#include "common/scummsys.h"
#ifdef MACOSX
#include "backends/audiocd/macosx/macosx-audiocd.h"
#include "backends/platform/sdl/macosx/appmenu_osx.h"
#include "backends/platform/sdl/macosx/macosx.h"
#include "backends/platform/sdl/macosx/macosx-touchbar.h"
#include "backends/platform/sdl/macosx/macosx-window.h"
#include "backends/updates/macosx/macosx-updates.h"
#include "backends/taskbar/macosx/macosx-taskbar.h"
#include "backends/text-to-speech/macosx/macosx-text-to-speech.h"
#include "backends/dialogs/macosx/macosx-dialogs.h"
#include "backends/platform/sdl/macosx/macosx_wrapper.h"
#include "backends/fs/posix/posix-fs.h"
#include "common/archive.h"
#include "common/config-manager.h"
#include "common/fs.h"
#include "common/translation.h"
#include <ApplicationServices/ApplicationServices.h> // for LSOpenFSRef
#include <CoreFoundation/CoreFoundation.h> // for CF* stuff
// For querying number of MIDI devices
#include <pthread.h>
#include <CoreMIDI/CoreMIDI.h>
void *coreMIDIthread(void *threadarg) {
(void)MIDIGetNumberOfDestinations();
pthread_exit(NULL);
return NULL;
}
OSystem_MacOSX::~OSystem_MacOSX() {
releaseMenu();
#if defined(USE_OSD)
macOSTouchbarDestroy();
#endif
}
void OSystem_MacOSX::init() {
initSDL();
_window = new SdlWindow_MacOSX();
#if defined(USE_TASKBAR)
// Initialize taskbar manager
_taskbarManager = new MacOSXTaskbarManager();
#endif
#if defined(USE_SYSDIALOGS)
// Initialize dialog manager
_dialogManager = new MacOSXDialogManager();
#endif
#if defined(USE_OSD)
macOSTouchbarCreate();
#endif
// The call to query the number of MIDI devices is ubiquitously slow
// on the first run. This is apparent when opening Options in GUI,
// which takes 2-3 secs.
//
// Thus, we are launching it now, in a separate thread, so
// the subsequent calls are instantaneous
pthread_t thread;
pthread_create(&thread, NULL, coreMIDIthread, NULL);
// Invoke parent implementation of this method
OSystem_POSIX::init();
}
void OSystem_MacOSX::initBackend() {
#ifdef USE_TRANSLATION
// We need to initialize the translation manager here for the following
// call to replaceApplicationMenuItems() work correctly
TransMan.setLanguage(ConfMan.get("gui_language").c_str());
#endif // USE_TRANSLATION
// Replace the SDL generated menu items with our own translated ones on macOS
replaceApplicationMenuItems();
#ifdef USE_SPARKLE
// Initialize updates manager
_updateManager = new MacOSXUpdateManager();
#endif
#ifdef USE_TTS
// Initialize Text to Speech manager
_textToSpeechManager = new MacOSXTextToSpeechManager();
#endif
// Migrate savepath.
// It used to be in ~/Documents/ScummVM Savegames/, but was changed to use the application support
// directory. To migrate old config files we use a flag to indicate if the config file was migrated.
// This allows detecting old config files. If the flag is not set we:
// 1. Set the flag
// 2. If the config file has no custom savepath and has some games, we set the savepath to the old default.
if (!ConfMan.hasKey("macos_savepath_migrated", Common::ConfigManager::kApplicationDomain)) {
if (!ConfMan.hasKey("savepath", Common::ConfigManager::kApplicationDomain) && !ConfMan.getGameDomains().empty()) {
ConfMan.set("savepath", getDocumentsPathMacOSX() + "/ScummVM Savegames", Common::ConfigManager::kApplicationDomain);
}
ConfMan.setBool("macos_savepath_migrated", true, Common::ConfigManager::kApplicationDomain);
ConfMan.flushToDisk();
}
// Invoke parent implementation of this method
OSystem_POSIX::initBackend();
}
#ifdef USE_OPENGL
OSystem_SDL::GraphicsManagerType OSystem_MacOSX::getDefaultGraphicsManager() const {
return GraphicsManagerOpenGL;
}
#endif
void OSystem_MacOSX::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
// Invoke parent implementation of this method
OSystem_POSIX::addSysArchivesToSearchSet(s, priority);
// Get URL of the Resource directory of the .app bundle
Common::Path bundlePath(getResourceAppBundlePathMacOSX(), Common::Path::kNativeSeparator);
if (!bundlePath.empty()) {
// Success: search with a depth of 2 so the shaders are found
s.add("__OSX_BUNDLE__", new Common::FSDirectory(bundlePath, 2), priority);
}
}
bool OSystem_MacOSX::hasFeature(Feature f) {
if (f == kFeatureDisplayLogFile || f == kFeatureClipboardSupport || f == kFeatureOpenUrl)
return true;
#ifdef USE_SYSDIALOGS
if (f == kFeatureSystemBrowserDialog)
return true;
#endif
return OSystem_POSIX::hasFeature(f);
}
bool OSystem_MacOSX::displayLogFile() {
// Use LaunchServices to open the log file, if possible.
if (_logFilePath.empty())
return false;
Common::String logFilePath(_logFilePath.toString(Common::Path::kNativeSeparator));
CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8 *)logFilePath.c_str(), logFilePath.size(), false);
OSStatus err = LSOpenCFURLRef(url, NULL);
CFRelease(url);
return err != noErr;
}
bool OSystem_MacOSX::openUrl(const Common::String &url) {
CFURLRef urlRef = CFURLCreateWithBytes (NULL, (const UInt8*)url.c_str(), url.size(), kCFStringEncodingASCII, NULL);
OSStatus err = LSOpenCFURLRef(urlRef, NULL);
CFRelease(urlRef);
return err == noErr;
}
Common::String OSystem_MacOSX::getSystemLanguage() const {
#if defined(USE_DETECTLANG) && defined(USE_TRANSLATION)
CFArrayRef availableLocalizations = CFBundleCopyBundleLocalizations(CFBundleGetMainBundle());
if (availableLocalizations) {
CFArrayRef preferredLocalizations = CFBundleCopyPreferredLocalizationsFromArray(availableLocalizations);
CFRelease(availableLocalizations);
if (preferredLocalizations) {
CFIndex localizationsSize = CFArrayGetCount(preferredLocalizations);
// Since we have a list of sorted preferred localization, I would like here to
// check that they are supported by the TranslationManager and take the first
// one that is supported. The listed localizations are taken from the Bundle
// plist file, so they should all be supported, unless the plist file is not
// synchronized with the translations.dat file. So this is not really a big
// issue. And because getSystemLanguage() is called from the constructor of
// TranslationManager (therefore before the instance pointer is set), calling
// TransMan here results in an infinite loop and creation of a lot of TransMan
// instances.
/*
for (CFIndex i = 0 ; i < localizationsSize ; ++i) {
CFStringRef language = (CFStringRef)CFArrayGetValueAtIndex(preferredLocalizations, i);
char buffer[10];
CFStringGetCString(language, buffer, sizeof(buffer), kCFStringEncodingASCII);
int32 languageId = TransMan.findMatchingLanguage(buffer);
if (languageId != -1) {
CFRelease(preferredLocalizations);
return TransMan.getLangById(languageId);
}
}
*/
if (localizationsSize > 0) {
CFStringRef language = (CFStringRef)CFArrayGetValueAtIndex(preferredLocalizations, 0);
char buffer[10];
CFStringGetCString(language, buffer, sizeof(buffer), kCFStringEncodingASCII);
CFRelease(preferredLocalizations);
return buffer;
}
CFRelease(preferredLocalizations);
}
}
// Fallback to POSIX implementation
return OSystem_POSIX::getSystemLanguage();
#else // USE_DETECTLANG
return OSystem_POSIX::getSystemLanguage();
#endif // USE_DETECTLANG
}
Common::Path OSystem_MacOSX::getDefaultConfigFileName() {
const Common::String baseConfigName = "Library/Preferences/" + getMacBundleName() + " Preferences";
Common::Path configFile;
Common::String prefix = getenv("HOME");
if (!prefix.empty() && (prefix.size() + 1 + baseConfigName.size()) < MAXPATHLEN) {
configFile = prefix;
configFile.joinInPlace(baseConfigName);
} else {
configFile = baseConfigName;
}
return configFile;
}
Common::Path OSystem_MacOSX::getDefaultLogFileName() {
const char *prefix = getenv("HOME");
if (prefix == nullptr) {
return Common::Path();
}
if (!Posix::assureDirectoryExists("Library/Logs", prefix)) {
return Common::Path();
}
Common::String appName = getMacBundleName();
appName.toLowercase();
return Common::Path(prefix).join(Common::String("Library/Logs/") + appName + ".log");
}
Common::Path OSystem_MacOSX::getDefaultIconsPath() {
const Common::String defaultIconsPath = getAppSupportPathMacOSX() + "/Icons";
if (!Posix::assureDirectoryExists(defaultIconsPath)) {
return Common::Path();
}
return Common::Path(defaultIconsPath);
}
Common::Path OSystem_MacOSX::getDefaultDLCsPath() {
const Common::Path defaultDLCsPath(getAppSupportPathMacOSX() + "/DLCs");
if (!Posix::assureDirectoryExists(defaultDLCsPath.toString(Common::Path::kNativeSeparator))) {
return Common::Path();
}
return defaultDLCsPath;
}
Common::Path OSystem_MacOSX::getScreenshotsPath() {
// If the user has configured a screenshots path, use it
const Common::Path path = OSystem_SDL::getScreenshotsPath();
if (!path.empty())
return path;
Common::Path desktopPath(getDesktopPathMacOSX(), Common::Path::kNativeSeparator);
return desktopPath;
}
AudioCDManager *OSystem_MacOSX::createAudioCDManager() {
return createMacOSXAudioCDManager();
}
#endif

View File

@@ -0,0 +1,66 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PLATFORM_SDL_MACOSX_H
#define PLATFORM_SDL_MACOSX_H
#include "backends/platform/sdl/posix/posix.h"
class OSystem_MacOSX : public OSystem_POSIX {
public:
~OSystem_MacOSX();
bool hasFeature(Feature f) override;
bool displayLogFile() override;
bool hasTextInClipboard() override;
Common::U32String getTextFromClipboard() override;
bool setTextInClipboard(const Common::U32String &text) override;
bool openUrl(const Common::String &url) override;
Common::String getSystemLanguage() const override;
void init() override;
void initBackend() override;
void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0) override;
void updateStartSettings(const Common::String &executable, Common::String &command, Common::StringMap &settings, Common::StringArray& additionalArgs) override;
#ifdef USE_OPENGL
GraphicsManagerType getDefaultGraphicsManager() const override;
#endif
// Default paths
Common::Path getDefaultIconsPath() override;
Common::Path getDefaultDLCsPath() override;
Common::Path getScreenshotsPath() override;
protected:
Common::Path getDefaultConfigFileName() override;
Common::Path getDefaultLogFileName() override;
// Override createAudioCDManager() to get our Mac-specific
// version.
AudioCDManager *createAudioCDManager() override;
};
#endif

View File

@@ -0,0 +1,187 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
// Disable symbol overrides so that we can use system headers.
#define FORBIDDEN_SYMBOL_ALLOW_ALL
// Needs to be included first as system headers redefine NO and YES, which clashes
// with the DisposeAfterUse::Flag enum used in Common stream classes.
#include "common/file.h"
#include "backends/platform/sdl/macosx/macosx.h"
#include "backends/platform/sdl/macosx/macosx-compat.h"
#include "base/version.h"
#include <Foundation/NSBundle.h>
#include <Foundation/NSData.h>
#include <Foundation/NSFileManager.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSPathUtilities.h>
#include <Foundation/NSUserDefaults.h>
#include <AppKit/NSPasteboard.h>
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
#define NSPasteboardTypeString NSStringPboardType
#endif
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
// https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Cocoa64BitGuide/64BitChangesCocoa/64BitChangesCocoa.html
#if __LP64__ || NS_BUILD_32_LIKE_64
typedef unsigned long NSUInteger;
#else
typedef unsigned int NSUInteger;
#endif
// Those are not defined in the 10.4 SDK, but they are defined when targeting
// Mac OS X 10.4 or above in the 10.5 SDK, and they do work with 10.4.
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
enum {
NSUTF32StringEncoding = 0x8c000100,
NSUTF32BigEndianStringEncoding = 0x98000100,
NSUTF32LittleEndianStringEncoding = 0x9c000100
};
#endif
#endif
void OSystem_MacOSX::updateStartSettings(const Common::String & executable, Common::String &command, Common::StringMap &settings, Common::StringArray& additionalArgs) {
NSBundle* bundle = [NSBundle mainBundle];
// Check if scummvm is running from an app bundle
if (!bundle || ![bundle bundleIdentifier]) {
// Use default autostart implementation
OSystem_POSIX::updateStartSettings(executable, command, settings, additionalArgs);
return;
}
// If the bundle contains a scummvm.ini, use it as initial config
NSString *iniPath = [bundle pathForResource:@"scummvm" ofType:@"ini"];
if (iniPath && !settings.contains("initial-cfg"))
settings["initial-cfg"] = Common::String([iniPath fileSystemRepresentation]);
// If a command was specified on the command line, do not override it
if (!command.empty())
return;
// Check if we have an autorun file with additional arguments
NSString *autorunPath = [bundle pathForResource:@"scummvm-autorun" ofType:nil];
if (autorunPath) {
Common::File autorun;
Common::String line;
if (autorun.open(Common::FSNode([autorunPath fileSystemRepresentation]))) {
while (!autorun.eos()) {
line = autorun.readLine();
if (!line.empty() && line[0] != '#')
additionalArgs.push_back(line);
}
}
autorun.close();
}
// If the bundle contains a game directory, auto-detect it
NSString *gamePath = [[bundle resourcePath] stringByAppendingPathComponent:@"game"];
BOOL isDir = false;
BOOL exists = [[NSFileManager defaultManager] fileExistsAtPath:gamePath isDirectory:&isDir];
if (exists && isDir) {
// Use auto-detection
command = "auto-detect";
settings["path"] = [gamePath fileSystemRepresentation];
return;
}
// The rest of the function has some commands executed only the first time after each version change
// Check the last version stored in the user settings.
NSString *versionString = [NSString stringWithUTF8String:gScummVMFullVersion];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *lastVersion = [defaults stringForKey:@"lastVersion"];
if (lastVersion && [lastVersion isEqualToString:versionString])
return;
[defaults setObject:versionString forKey:@"lastVersion"];
// If the bundle contains a games directory, add them to the launcher
NSString *gamesPath = [[bundle resourcePath] stringByAppendingPathComponent:@"games"];
isDir = false;
exists = [[NSFileManager defaultManager] fileExistsAtPath:gamesPath isDirectory:&isDir];
if (exists && isDir) {
// Detect and add games
command = "add";
settings["path"] = [gamesPath fileSystemRepresentation];
settings["recursive"] = "true";
settings["exit"] = "false";
return;
}
}
bool OSystem_MacOSX::hasTextInClipboard() {
return [[NSPasteboard generalPasteboard] availableTypeFromArray:[NSArray arrayWithObject:NSPasteboardTypeString]] != nil;
}
Common::U32String OSystem_MacOSX::getTextFromClipboard() {
if (!hasTextInClipboard())
return Common::U32String();
NSPasteboard *pb = [NSPasteboard generalPasteboard];
NSString *str = [pb stringForType:NSPasteboardTypeString];
if (str == nil)
return Common::U32String();
// If translations are supported, use the current TranslationManager charset and otherwise
// use ASCII. If the string cannot be represented using the requested encoding we get a null
// pointer below, which is fine as ScummVM would not know what to do with the string anyway.
#ifdef SCUMM_LITTLE_ENDIAN
NSStringEncoding stringEncoding = NSUTF32LittleEndianStringEncoding;
#else
NSStringEncoding stringEncoding = NSUTF32BigEndianStringEncoding;
#endif
NSData *data = [str dataUsingEncoding:stringEncoding];
if (data == nil)
return Common::U32String();
NSUInteger byteLength = [data length];
if (byteLength % 4 != 0)
return Common::U32String();
NSUInteger textLength = byteLength / 4;
Common::u32char_type_t *text = new Common::u32char_type_t[textLength];
// note: Using the `-getBytes:...:remainingRange:` API would make this code
// a bit simpler, but it's missing from the 10.4 SDK headers (although the
// Foundation framework seems to contain some hidden symbol for it...)
[data getBytes:text length:byteLength];
Common::U32String u32String(text, textLength);
delete[] text;
return u32String;
}
bool OSystem_MacOSX::setTextInClipboard(const Common::U32String &text) {
NSPasteboard *pb = [NSPasteboard generalPasteboard];
[pb declareTypes:[NSArray arrayWithObject:NSPasteboardTypeString] owner:nil];
#ifdef SCUMM_LITTLE_ENDIAN
NSStringEncoding stringEncoding = NSUTF32LittleEndianStringEncoding;
#else
NSStringEncoding stringEncoding = NSUTF32BigEndianStringEncoding;
#endif
NSString *nsstring = [[NSString alloc] initWithBytes:text.c_str() length:4*text.size() encoding: stringEncoding];
bool status = [pb setString:nsstring forType:NSPasteboardTypeString];
[nsstring release];
return status;
}

View File

@@ -0,0 +1,33 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef PLATFORM_SDL_MACOSX_WRAPPER_H
#define PLATFORM_SDL_MACOSX_WRAPPER_H
#include "common/str.h"
Common::String getDesktopPathMacOSX();
Common::String getDocumentsPathMacOSX();
Common::String getResourceAppBundlePathMacOSX();
Common::String getAppSupportPathMacOSX();
Common::String getMacBundleName();
#endif

View File

@@ -0,0 +1,84 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
// Disable symbol overrides so that we can use system headers.
#define FORBIDDEN_SYMBOL_ALLOW_ALL
#include "backends/platform/sdl/macosx/macosx_wrapper.h"
#include "backends/platform/sdl/macosx/macosx-compat.h"
#include <Foundation/NSArray.h>
#include <Foundation/NSBundle.h>
#include <Foundation/NSDictionary.h>
#include <Foundation/NSPathUtilities.h>
#include <AvailabilityMacros.h>
#include <CoreFoundation/CFString.h>
#include <CoreFoundation/CFBundle.h>
Common::String getDesktopPathMacOSX() {
// The recommended method is to use NSFileManager.
// NSUrl *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDesktopDirectory inDomains:NSUserDomainMask] firstObject];
// However it is only available in OS X 10.6+. So use NSSearchPathForDirectoriesInDomains instead (available since OS X 10.0)
// [NSArray firstObject] is also only available in OS X 10.6+. So we need to use [NSArray count] and [NSArray objectAtIndex:]
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDesktopDirectory, NSUserDomainMask, YES);
if ([paths count] == 0)
return Common::String();
NSString *path = [paths objectAtIndex:0];
if (path == nil)
return Common::String();
return Common::String([path fileSystemRepresentation]);
}
Common::String getDocumentsPathMacOSX() {
// See comment in getDesktopPathMacOSX()
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
if ([paths count] == 0)
return Common::String();
NSString *path = [paths objectAtIndex:0];
if (path == nil)
return Common::String();
return Common::String([path fileSystemRepresentation]);
}
Common::String getResourceAppBundlePathMacOSX() {
NSString *bundlePath = [[NSBundle mainBundle] resourcePath];
if (bundlePath == nil)
return Common::String();
return Common::String([bundlePath fileSystemRepresentation]);
}
Common::String getAppSupportPathMacOSX() {
// See comments in getDesktopPathMacOSX() as we use the same methods
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
if ([paths count] == 0)
return Common::String();
NSString *path = [paths objectAtIndex:0];
if (path == nil)
return Common::String();
return Common::String([path fileSystemRepresentation]) + "/ScummVM";
}
Common::String getMacBundleName() {
NSString *appName = [[[NSBundle mainBundle] infoDictionary] objectForKey:(id)kCFBundleNameKey];
if (!appName)
return Common::String("ScummVM");
return Common::String([appName UTF8String]);
}