summaryrefslogtreecommitdiff
path: root/src/sys/macosx
diff options
context:
space:
mode:
Diffstat (limited to 'src/sys/macosx')
-rw-r--r--src/sys/macosx/Schism_Tracker.app/Contents/Info.plist112
-rw-r--r--src/sys/macosx/Schism_Tracker.app/Contents/PkgInfo1
-rw-r--r--src/sys/macosx/Schism_Tracker.app/Contents/Resources/AppSettings.plist18
-rw-r--r--src/sys/macosx/Schism_Tracker.app/Contents/Resources/appIcon.icnsbin0 -> 52550 bytes
-rw-r--r--src/sys/macosx/Schism_Tracker.app/Contents/Resources/moduleIcon.icnsbin0 -> 58109 bytes
-rw-r--r--src/sys/macosx/ibook-support.c103
-rw-r--r--src/sys/macosx/macosx-sdlmain.m619
-rw-r--r--src/sys/macosx/midi-macosx.c222
-rw-r--r--src/sys/macosx/osdefs.c54
-rw-r--r--src/sys/macosx/volume-macosx.c119
10 files changed, 1248 insertions, 0 deletions
diff --git a/src/sys/macosx/Schism_Tracker.app/Contents/Info.plist b/src/sys/macosx/Schism_Tracker.app/Contents/Info.plist
new file mode 100644
index 0000000..ca4d05d
--- /dev/null
+++ b/src/sys/macosx/Schism_Tracker.app/Contents/Info.plist
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>schismtracker</string>
+ <key>CFBundleDocumentTypes</key>
+ <array>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>it</string>
+ <string>IT</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>moduleIcon.icns</string>
+ <key>CFBundleMIMETypes</key>
+ <array>
+ <string>audio/mod</string>
+ <string>audio/x-mod</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Impulse Tracker Module</string>
+ <key>CFBundleTypeRole</key>
+ <string>Editor</string>
+ <key>LSIsAppleDefaultForType</key>
+ <true/>
+ </dict>
+ <dict>
+ <key>CFBundleTypeExtensions</key>
+ <array>
+ <string>669</string>
+ <string>amf</string>
+ <string>AMF</string>
+ <string>ams</string>
+ <string>AMS</string>
+ <string>dbm</string>
+ <string>DBM</string>
+ <string>dmf</string>
+ <string>DMF</string>
+ <string>far</string>
+ <string>FAR</string>
+ <string>mdl</string>
+ <string>MDL</string>
+ <string>med</string>
+ <string>MED</string>
+ <string>mod</string>
+ <string>MOD</string>
+ <string>mt2</string>
+ <string>MT2</string>
+ <string>mtm</string>
+ <string>MTM</string>
+ <string>okt</string>
+ <string>OKT</string>
+ <string>psm</string>
+ <string>PSM</string>
+ <string>ptm</string>
+ <string>PTM</string>
+ <string>s3m</string>
+ <string>S3M</string>
+ <string>stm</string>
+ <string>STM</string>
+ <string>ult</string>
+ <string>ULT</string>
+ <string>umx</string>
+ <string>UMX</string>
+ <string>xm</string>
+ <string>XM</string>
+ </array>
+ <key>CFBundleTypeIconFile</key>
+ <string>moduleIcon.icns</string>
+ <key>CFBundleMIMETypes</key>
+ <array>
+ <string>audio/mod</string>
+ <string>audio/x-mod</string>
+ </array>
+ <key>CFBundleTypeName</key>
+ <string>Audio Module</string>
+ <key>CFBundleTypeRole</key>
+ <string>Viewer</string>
+ <key>LSIsAppleDefaultForType</key>
+ <true/>
+ </dict>
+ </array>
+ <key>CFBundleGetInfoString</key>
+ <string>Schism Tracker Copyright 2003-2012 Storlek</string>
+ <key>CFBundleIconFile</key>
+ <string>appIcon.icns</string>
+ <key>CFBundleIdentifier</key>
+ <string>org.schismtracker.SchismTracker</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>Schism Tracker</string>
+ <key>CFBundlePackageType</key>
+ <string>APPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>hg</string>
+ <key>CFBundleSignature</key>
+ <string>Schm</string>
+ <key>CFBundleVersion</key>
+ <string>hg</string>
+ <key>NSMainNibFile</key>
+ <string>MainMenu</string>
+ <key>NSPrincipalClass</key>
+ <string>NSApplication</string>
+ <key>CGDisableCoalescedUpdates</key>
+ <true/>
+</dict>
+</plist>
diff --git a/src/sys/macosx/Schism_Tracker.app/Contents/PkgInfo b/src/sys/macosx/Schism_Tracker.app/Contents/PkgInfo
new file mode 100644
index 0000000..07af6f8
--- /dev/null
+++ b/src/sys/macosx/Schism_Tracker.app/Contents/PkgInfo
@@ -0,0 +1 @@
+APPLSchm \ No newline at end of file
diff --git a/src/sys/macosx/Schism_Tracker.app/Contents/Resources/AppSettings.plist b/src/sys/macosx/Schism_Tracker.app/Contents/Resources/AppSettings.plist
new file mode 100644
index 0000000..62376f5
--- /dev/null
+++ b/src/sys/macosx/Schism_Tracker.app/Contents/Resources/AppSettings.plist
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>EncryptAndChecksum</key>
+ <false/>
+ <key>IsDroppable</key>
+ <true/>
+ <key>OutputType</key>
+ <string>None</string>
+ <key>RemainRunningAfterCompletion</key>
+ <false/>
+ <key>RequiresAdminPrivileges</key>
+ <false/>
+ <key>ScriptInterpreter</key>
+ <string>/bin/sh</string>
+</dict>
+</plist>
diff --git a/src/sys/macosx/Schism_Tracker.app/Contents/Resources/appIcon.icns b/src/sys/macosx/Schism_Tracker.app/Contents/Resources/appIcon.icns
new file mode 100644
index 0000000..8ed3637
--- /dev/null
+++ b/src/sys/macosx/Schism_Tracker.app/Contents/Resources/appIcon.icns
Binary files differ
diff --git a/src/sys/macosx/Schism_Tracker.app/Contents/Resources/moduleIcon.icns b/src/sys/macosx/Schism_Tracker.app/Contents/Resources/moduleIcon.icns
new file mode 100644
index 0000000..597056b
--- /dev/null
+++ b/src/sys/macosx/Schism_Tracker.app/Contents/Resources/moduleIcon.icns
Binary files differ
diff --git a/src/sys/macosx/ibook-support.c b/src/sys/macosx/ibook-support.c
new file mode 100644
index 0000000..71bd00b
--- /dev/null
+++ b/src/sys/macosx/ibook-support.c
@@ -0,0 +1,103 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#include "headers.h"
+#include "util.h"
+
+int macosx_ibook_fnswitch(int setting); /* FIXME: ugliness */
+
+#ifdef MACOSX
+
+#include <IOKit/IOKitLib.h>
+#include <IOKit/IOReturn.h>
+#include <ApplicationServices/ApplicationServices.h>
+#include <IOKit/hidsystem/IOHIDLib.h>
+#include <IOKit/hidsystem/IOHIDParameter.h>
+
+#define kMyDriversKeyboardClassName "AppleADBKeyboard"
+#define kfnSwitchError 200
+#define kfnAppleMode 0
+#define kfntheOtherMode 1
+
+#ifndef kIOHIDFKeyModeKey
+#define kIOHIDFKeyModeKey "HIDFKeyMode"
+#endif
+
+int macosx_ibook_fnswitch(int setting)
+{
+ kern_return_t kr;
+ mach_port_t mp;
+ io_service_t so;
+ /*io_name_t sn;*/
+ io_connect_t dp;
+ io_iterator_t it;
+ CFDictionaryRef classToMatch;
+ /*CFNumberRef fnMode;*/
+ unsigned int res, dummy;
+
+ kr = IOMasterPort(bootstrap_port, &mp);
+ if (kr != KERN_SUCCESS) return -1;
+
+ classToMatch = IOServiceMatching(kIOHIDSystemClass);
+ if (classToMatch == NULL) {
+ return -1;
+ }
+ kr = IOServiceGetMatchingServices(mp, classToMatch, &it);
+ if (kr != KERN_SUCCESS) return -1;
+
+ so = IOIteratorNext(it);
+ IOObjectRelease(it);
+
+ if (!so) return -1;
+
+ kr = IOServiceOpen(so, mach_task_self(), kIOHIDParamConnectType, &dp);
+ if (kr != KERN_SUCCESS) return -1;
+
+ kr = IOHIDGetParameter(dp, CFSTR(kIOHIDFKeyModeKey), sizeof(res),
+ &res, (IOByteCount *) &dummy);
+ if (kr != KERN_SUCCESS) {
+ IOServiceClose(dp);
+ return -1;
+ }
+
+ if (setting == kfnAppleMode || setting == kfntheOtherMode) {
+ dummy = setting;
+ kr = IOHIDSetParameter(dp, CFSTR(kIOHIDFKeyModeKey),
+ &dummy, sizeof(dummy));
+ if (kr != KERN_SUCCESS) {
+ IOServiceClose(dp);
+ return -1;
+ }
+ }
+
+ IOServiceClose(dp);
+ /* old setting... */
+ return res;
+}
+
+#else
+
+int macosx_ibook_fnswitch(UNUSED int setting)
+{
+ return 0;
+}
+#endif
diff --git a/src/sys/macosx/macosx-sdlmain.m b/src/sys/macosx/macosx-sdlmain.m
new file mode 100644
index 0000000..df7f440
--- /dev/null
+++ b/src/sys/macosx/macosx-sdlmain.m
@@ -0,0 +1,619 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* wee....
+
+this is used to do some schism-on-macosx customization
+and get access to cocoa stuff
+
+pruned up some here :) -mrsb
+
+ */
+
+/* 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
+*/
+
+extern char *initial_song;
+
+#include <SDL.h> /* necessary here */
+#include "event.h"
+#include "osdefs.h"
+
+#define Cursor AppleCursor
+#import <Cocoa/Cocoa.h>
+#undef Cursor
+
+@interface SDLMain : NSObject
+- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename;
+@end
+
+#import <sys/param.h> /* for MAXPATHLEN */
+#import <unistd.h>
+
+/* 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 CPSSetProcessName ( CPSProcessSerNum *psn, char *processname);
+extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn);
+
+static int gArgc;
+static char **gArgv;
+static BOOL gFinderLaunch;
+int macosx_did_finderlaunch;
+
+#define KEQ_FN(n) [NSString stringWithFormat:@"%C", NSF##n##FunctionKey]
+
+@interface SDLApplication : NSApplication
+@end
+
+@interface NSApplication(OtherMacOSXExtensions)
+-(void)setAppleMenu:(NSMenu*)m;
+@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);
+}
+- (void)_menu_callback:(id)sender
+{
+ SDL_Event e;
+ NSString *px;
+ const char *po;
+
+ px = [sender representedObject];
+ po = [px UTF8String];
+ if (po) {
+ e.type = SCHISM_EVENT_NATIVE;
+ e.user.code = SCHISM_EVENT_NATIVE_SCRIPT;
+ e.user.data1 = strdup(po);
+ SDL_PushEvent(&e);
+ }
+}
+
+
+@end
+
+/* The main class of the application, the application's delegate */
+@implementation SDLMain
+
+- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
+{
+ SDL_Event e;
+ const char *po;
+
+ if (!filename) return NO;
+
+ po = [filename UTF8String];
+ if (po) {
+ e.type = SCHISM_EVENT_NATIVE;
+ e.user.code = SCHISM_EVENT_NATIVE_OPEN;
+ e.user.data1 = strdup(po);
+ /* if we started as a result of a doubleclick on
+ a document, then Main still hasn't really started yet.
+ */
+ initial_song = strdup(po);
+ SDL_PushEvent(&e);
+ return YES;
+ } else {
+ return NO;
+ }
+}
+
+/* other interesting ones:
+- (BOOL)application:(NSApplication *)theApplication printFile:(NSString *)filename
+- (BOOL)applicationOpenUntitledFile:(NSApplication *)theApplication
+*/
+/* 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, (unsigned char *) parentdir, MAXPATHLEN)) {
+ assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */
+ }
+ CFRelease(url);
+ CFRelease(url2);
+ }
+
+}
+
+static void setApplicationMenu(void)
+{
+ /* warning: this code is very odd */
+ NSMenu *appleMenu;
+ NSMenu *otherMenu;
+ NSMenuItem *menuItem;
+
+ appleMenu = [[NSMenu alloc] initWithTitle:@""];
+
+ /* Add menu items */
+ [appleMenu addItemWithTitle:@"About Schism Tracker"
+ action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
+
+ [appleMenu addItem:[NSMenuItem separatorItem]];
+
+ /* other schism items */
+ menuItem = (NSMenuItem*)[appleMenu addItemWithTitle:@"Help"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(1)];
+ [menuItem setKeyEquivalentModifierMask:0];
+ [menuItem setRepresentedObject: @"help"];
+
+ [appleMenu addItem:[NSMenuItem separatorItem]];
+ menuItem = (NSMenuItem*)[appleMenu addItemWithTitle:@"View Patterns"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(2)];
+ [menuItem setKeyEquivalentModifierMask:0];
+ [menuItem setRepresentedObject: @"pattern"];
+ menuItem = (NSMenuItem*)[appleMenu addItemWithTitle:@"Orders/Panning"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(11)];
+ [menuItem setKeyEquivalentModifierMask:0];
+ [menuItem setRepresentedObject: @"orders"];
+ menuItem = (NSMenuItem*)[appleMenu addItemWithTitle:@"Variables"
+ action:@selector(_menu_callback:)
+ keyEquivalent:[NSString stringWithFormat:@"%C", NSF12FunctionKey]];
+ [menuItem setKeyEquivalentModifierMask:0];
+ [menuItem setRepresentedObject: @"variables"];
+ menuItem = (NSMenuItem*)[appleMenu addItemWithTitle:@"Message Editor"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(9)];
+ [menuItem setKeyEquivalentModifierMask:NSShiftKeyMask];
+ [menuItem setRepresentedObject: @"message_edit"];
+
+ [appleMenu addItem:[NSMenuItem separatorItem]];
+
+ [appleMenu addItemWithTitle:@"Hide Schism Tracker" 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]];
+
+ [appleMenu addItemWithTitle:@"Quit Schism Tracker" action:@selector(terminate:) keyEquivalent:@"q"];
+
+ /* Put menu into the menubar */
+ menuItem = (NSMenuItem*)[[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
+ [menuItem setSubmenu:appleMenu];
+ [[NSApp mainMenu] addItem:menuItem];
+
+ /* File menu */
+ otherMenu = [[NSMenu alloc] initWithTitle:@"File"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"New..."
+ action:@selector(_menu_callback:)
+ keyEquivalent:@"n"];
+ [menuItem setKeyEquivalentModifierMask:NSControlKeyMask];
+ [menuItem setRepresentedObject: @"new"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Load..."
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(9)];
+ [menuItem setKeyEquivalentModifierMask:0];
+ [menuItem setRepresentedObject: @"load"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Save Current"
+ action:@selector(_menu_callback:)
+ keyEquivalent:@"s"];
+ [menuItem setKeyEquivalentModifierMask:NSControlKeyMask];
+ [menuItem setRepresentedObject: @"save"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Save As..."
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(10)];
+ [menuItem setKeyEquivalentModifierMask:0];
+ [menuItem setRepresentedObject: @"save_as"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Export..."
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(10)];
+ [menuItem setKeyEquivalentModifierMask:NSShiftKeyMask];
+ [menuItem setRepresentedObject: @"export_song"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Message Log"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(11)];
+ [menuItem setKeyEquivalentModifierMask:NSFunctionKeyMask|NSControlKeyMask];
+ [menuItem setRepresentedObject: @"logviewer"];
+ menuItem = (NSMenuItem*)[[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
+ [menuItem setSubmenu:otherMenu];
+ [[NSApp mainMenu] addItem:menuItem];
+
+ /* Playback menu */
+ otherMenu = [[NSMenu alloc] initWithTitle:@"Playback"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Show Infopage"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(5)];
+ [menuItem setKeyEquivalentModifierMask:0];
+ [menuItem setRepresentedObject: @"info"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Play Song"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(5)];
+ [menuItem setKeyEquivalentModifierMask:NSControlKeyMask];
+ [menuItem setRepresentedObject: @"play"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Play Pattern"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(6)];
+ [menuItem setKeyEquivalentModifierMask:0];
+ [menuItem setRepresentedObject: @"play_pattern"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Play from Order"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(6)];
+ [menuItem setKeyEquivalentModifierMask:NSShiftKeyMask];
+ [menuItem setRepresentedObject: @"play_order"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Play from Mark/Cursor"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(7)];
+ [menuItem setKeyEquivalentModifierMask:0];
+ [menuItem setRepresentedObject: @"play_mark"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Stop"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(8)];
+ [menuItem setKeyEquivalentModifierMask:0];
+ [menuItem setRepresentedObject: @"stop"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Calculate Length"
+ action:@selector(_menu_callback:)
+ keyEquivalent:@"p"];
+ [menuItem setKeyEquivalentModifierMask:(NSFunctionKeyMask|NSControlKeyMask)];
+ [menuItem setRepresentedObject: @"calc_length"];
+ menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
+ [menuItem setSubmenu:otherMenu];
+ [[NSApp mainMenu] addItem:menuItem];
+
+ /* Sample menu */
+ otherMenu = [[NSMenu alloc] initWithTitle:@"Samples"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Sample List"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(3)];
+ [menuItem setKeyEquivalentModifierMask:0];
+ [menuItem setRepresentedObject: @"sample_page"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Sample Library"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(3)];
+ [menuItem setKeyEquivalentModifierMask:NSShiftKeyMask];
+ [menuItem setRepresentedObject: @"sample_library"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Reload Soundcard"
+ action:@selector(_menu_callback:)
+ keyEquivalent:@"g"];
+ [menuItem setKeyEquivalentModifierMask:NSControlKeyMask];
+ [menuItem setRepresentedObject: @"init_sound"];
+ menuItem = (NSMenuItem*)[[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
+ [menuItem setSubmenu:otherMenu];
+ [[NSApp mainMenu] addItem:menuItem];
+
+ /* Instrument menu */
+ otherMenu = [[NSMenu alloc] initWithTitle:@"Instruments"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Instrument List"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(4)];
+ [menuItem setKeyEquivalentModifierMask:0];
+ [menuItem setRepresentedObject: @"inst_page"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Instrument Library"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(4)];
+ [menuItem setKeyEquivalentModifierMask:NSShiftKeyMask];
+ [menuItem setRepresentedObject: @"inst_library"];
+ menuItem = (NSMenuItem*)[[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
+ [menuItem setSubmenu:otherMenu];
+ [[NSApp mainMenu] addItem:menuItem];
+
+ /* Settings menu */
+ otherMenu = [[NSMenu alloc] initWithTitle:@"Settings"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Preferences"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(5)];
+ [menuItem setKeyEquivalentModifierMask:NSShiftKeyMask];
+ [menuItem setRepresentedObject: @"preferences"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"MIDI Configuration"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(1)];
+ [menuItem setKeyEquivalentModifierMask:NSShiftKeyMask];
+ [menuItem setRepresentedObject: @"midi_config"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Palette Editor"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(12)];
+ [menuItem setKeyEquivalentModifierMask:NSControlKeyMask];
+ [menuItem setRepresentedObject: @"palette_page"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Font Editor"
+ action:@selector(_menu_callback:)
+ keyEquivalent:@""];
+ [menuItem setRepresentedObject: @"font_editor"];
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"System Configuration"
+ action:@selector(_menu_callback:)
+ keyEquivalent:KEQ_FN(1)];
+ [menuItem setKeyEquivalentModifierMask:NSControlKeyMask];
+ [menuItem setRepresentedObject: @"system_config"];
+
+ menuItem = (NSMenuItem*)[otherMenu addItemWithTitle:@"Toggle Fullscreen"
+ action:@selector(_menu_callback:)
+ keyEquivalent:@"\r"];
+ [menuItem setKeyEquivalentModifierMask:(NSControlKeyMask|NSAlternateKeyMask)];
+ [menuItem setRepresentedObject: @"fullscreen"];
+ menuItem = (NSMenuItem*)[[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
+ [menuItem setSubmenu:otherMenu];
+ [[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;
+ CPSProcessSerNum PSN;
+
+ /* Ensure the application object is initialised */
+ [SDLApplication sharedApplication];
+
+ /* Tell the dock about us */
+ if (!CPSGetCurrentProcess(&PSN)) {
+ if (!macosx_did_finderlaunch) {
+ CPSSetProcessName(&PSN,"Schism Tracker");
+ }
+ if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103))
+ if (!CPSSetFrontProcess(&PSN))
+ [SDLApplication sharedApplication];
+ }
+
+ /* 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];
+}
+
+/* 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];
+
+ /* Hand off to main application code */
+ status = SDL_main (gArgc, gArgv);
+
+ /* We're done, thank you for playing */
+ exit(status);
+}
+@end
+
+
+@implementation NSString (ReplaceSubString)
+
+- (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString
+{
+ unsigned int bufferSize;
+ unsigned int selfLen = [self length];
+ unsigned int aStringLen = [aString length];
+ unichar *buffer;
+ NSRange localRange;
+ NSString *result;
+
+ bufferSize = selfLen + aStringLen - aRange.length;
+ buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar));
+
+ /* Get first part into buffer */
+ localRange.location = 0;
+ localRange.length = aRange.location;
+ [self getCharacters:buffer range:localRange];
+
+ /* Get middle part into buffer */
+ localRange.location = 0;
+ localRange.length = aStringLen;
+ [aString getCharacters:(buffer+aRange.location) range:localRange];
+
+ /* Get last part into buffer */
+ localRange.location = aRange.location + aRange.length;
+ localRange.length = selfLen - localRange.location;
+ [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange];
+
+ /* Build output string */
+ result = [NSString stringWithCharacters:buffer length:bufferSize];
+
+ NSDeallocateMemoryPages(buffer, bufferSize);
+
+ return result;
+}
+
+@end
+
+
+
+#ifdef main
+# undef main
+#endif
+
+
+/* Main entry point to executable - should *not* be SDL_main! */
+int main (int argc, char **argv)
+{
+ /* Copy the arguments into a global variable */
+ /* This is passed if we are launched by double-clicking */
+ if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
+ gArgc = 1;
+ gFinderLaunch = YES;
+ macosx_did_finderlaunch = 1;
+ } else {
+ gArgc = argc;
+ gFinderLaunch = NO;
+ macosx_did_finderlaunch = 0;
+ }
+ gArgv = argv;
+
+ CustomApplicationMain (argc, argv);
+
+ return 0;
+}
+
+/* these routines provide clipboard encapsulation */
+const char *macosx_clippy_get(void)
+{
+ NSPasteboard *pb = [NSPasteboard generalPasteboard];
+ NSString *type = [pb availableTypeFromArray:[NSArray
+ arrayWithObject:NSStringPboardType]];
+ NSString *contents;
+ const char *po;
+
+ if (type == nil) return "";
+
+ contents = [pb stringForType:type];
+ if (contents == nil) return "";
+ po = [contents UTF8String];
+ if (!po) return "";
+ return po;
+}
+void macosx_clippy_put(const char *buf)
+{
+ NSString *contents = [NSString stringWithUTF8String:buf];
+ NSPasteboard *pb = [NSPasteboard generalPasteboard];
+ [pb declareTypes:[NSArray arrayWithObject:NSStringPboardType] owner:nil];
+ [pb setString:contents forType:NSStringPboardType];
+}
+// ktt appears to be 1/60th of a second?
+unsigned int key_repeat_rate(void)
+{
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+ int ktt = [defaults integerForKey:@"KeyRepeat"];
+ if (!ktt || ktt < 0) ktt = 4; // eh?
+ ktt = (ktt * 1000) / 60;
+ return (unsigned)ktt;
+}
+unsigned int key_repeat_delay(void)
+{
+ NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
+ int ktt = [defaults integerForKey:@"InitialKeyRepeat"];
+ if (!ktt || ktt < 0) ktt = 35;
+ ktt = (ktt * 1000) / 60;
+ return (unsigned)ktt;
+}
+int key_scancode_lookup(int k, int def)
+{
+ switch (k & 127) {
+ case 0x32: /* QZ_BACKQUOTE */ return SDLK_BACKQUOTE;
+ case 0x12: /* QZ_1 */ return SDLK_1;
+ case 0x13: /* QZ_2 */ return SDLK_2;
+ case 0x14: /* QZ_3 */ return SDLK_3;
+ case 0x15: /* QZ_4 */ return SDLK_4;
+ case 0x17: /* QZ_5 */ return SDLK_5;
+ case 0x16: /* QZ_6 */ return SDLK_6;
+ case 0x1A: /* QZ_7 */ return SDLK_7;
+ case 0x1C: /* QZ_8 */ return SDLK_8;
+ case 0x19: /* QZ_9 */ return SDLK_9;
+ case 0x1D: /* QZ_0 */ return SDLK_0;
+ case 0x1B: /* QZ_MINUS */ return SDLK_MINUS;
+ case 0x18: /* QZ_EQUALS */ return SDLK_EQUALS;
+ case 0x0C: /* QZ_q */ return SDLK_q;
+ case 0x0D: /* QZ_w */ return SDLK_w;
+ case 0x0E: /* QZ_e */ return SDLK_e;
+ case 0x0F: /* QZ_r */ return SDLK_r;
+ case 0x11: /* QZ_t */ return SDLK_t;
+ case 0x10: /* QZ_y */ return SDLK_y;
+ case 0x20: /* QZ_u */ return SDLK_u;
+ case 0x22: /* QZ_i */ return SDLK_i;
+ case 0x1F: /* QZ_o */ return SDLK_o;
+ case 0x23: /* QZ_p */ return SDLK_p;
+ case 0x21: /* QZ_[ */ return SDLK_LEFTBRACKET;
+ case 0x1E: /* QZ_] */ return SDLK_RIGHTBRACKET;
+ case 0x2A: /* QZ_backslash */ return SDLK_BACKSLASH;
+ case 0x00: /* QZ_a */ return SDLK_a;
+ case 0x01: /* QZ_s */ return SDLK_s;
+ case 0x02: /* QZ_d */ return SDLK_d;
+ case 0x03: /* QZ_f */ return SDLK_f;
+ case 0x05: /* QZ_g */ return SDLK_g;
+ case 0x04: /* QZ_h */ return SDLK_h;
+ case 0x26: /* QZ_j */ return SDLK_j;
+ case 0x28: /* QZ_k */ return SDLK_k;
+ case 0x25: /* QZ_l */ return SDLK_l;
+ case 0x29: /* QZ_; */ return SDLK_SEMICOLON;
+ case 0x27: /* QZ_quote */ return SDLK_QUOTE;
+ case 0x06: /* QZ_z */ return SDLK_z;
+ case 0x07: /* QZ_x */ return SDLK_x;
+ case 0x08: /* QZ_c */ return SDLK_c;
+ case 0x09: /* QZ_v */ return SDLK_v;
+ case 0x0B: /* QZ_b */ return SDLK_b;
+ case 0x2D: /* QZ_n */ return SDLK_n;
+ case 0x2E: /* QZ_m */ return SDLK_m;
+ case 0x2B: /* QZ_, */ return SDLK_COMMA;
+ case 0x2F: /* QZ_. */ return SDLK_PERIOD;
+ case 0x2C: /* QZ_slash */ return SDLK_SLASH;
+ case 0x31: /* QZ_space */ return SDLK_SPACE;
+ default: return def;
+ };
+}
diff --git a/src/sys/macosx/midi-macosx.c b/src/sys/macosx/midi-macosx.c
new file mode 100644
index 0000000..3342e2c
--- /dev/null
+++ b/src/sys/macosx/midi-macosx.c
@@ -0,0 +1,222 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "headers.h"
+
+#include "midi.h"
+
+#include "util.h"
+
+#ifdef MACOSX
+
+#include <CoreServices/CoreServices.h>
+#include <CoreMIDI/MIDIServices.h>
+#include <CoreAudio/HostTime.h>
+
+static MIDIClientRef client = NULL;
+static MIDIPortRef portIn = NULL;
+static MIDIPortRef portOut = NULL;
+
+static int max_outputs = 0;
+static int max_inputs = 0;
+
+struct macosx_midi {
+ char *name;
+ MIDIEndpointRef ep;
+ unsigned char packet[1024];
+ MIDIPacketList *pl;
+ MIDIPacket *x;
+};
+
+static void readProc(const MIDIPacketList *np, UNUSED void *rc, void *crc)
+{
+ struct midi_port *p;
+ struct macosx_midi *m;
+ MIDIPacket *x;
+ unsigned long i;
+
+ p = (struct midi_port *)crc;
+ m = (struct macosx_midi *)p->userdata;
+
+ x = (MIDIPacket*)&np->packet[0];
+ for (i = 0; i < np->numPackets; i++) {
+ midi_received_cb(p, x->data, x->length);
+ x = MIDIPacketNext(x);
+ }
+}
+static void _macosx_send(struct midi_port *p, const unsigned char *data,
+ unsigned int len, unsigned int delay)
+{
+ struct macosx_midi *m;
+
+ m = (struct macosx_midi *)p->userdata;
+ if (!m->x) {
+ m->x = MIDIPacketListInit(m->pl);
+ }
+
+ /* msec to nsec? */
+ m->x = MIDIPacketListAdd(m->pl, sizeof(m->packet),
+ m->x, (MIDITimeStamp)AudioConvertNanosToHostTime(
+ AudioConvertHostTimeToNanos(AudioGetCurrentHostTime()) + (1000000*delay)),
+ len, data);
+}
+static void _macosx_drain(struct midi_port *p)
+{
+ struct macosx_midi *m;
+
+ m = (struct macosx_midi *)p->userdata;
+ if (m->x) {
+ MIDISend(portOut, m->ep, m->pl);
+ m->x = NULL;
+ }
+}
+
+/* lifted from portmidi */
+static char *get_ep_name(MIDIEndpointRef ep)
+{
+ MIDIEntityRef entity;
+ MIDIDeviceRef device;
+ CFStringRef endpointName = NULL, deviceName = NULL, fullName = NULL;
+ CFStringEncoding defaultEncoding;
+ char* newName;
+
+ /* get the default string encoding */
+ defaultEncoding = CFStringGetSystemEncoding();
+
+ /* get the entity and device info */
+ MIDIEndpointGetEntity(ep, &entity);
+ MIDIEntityGetDevice(entity, &device);
+
+ /* create the nicely formated name */
+ MIDIObjectGetStringProperty(ep, kMIDIPropertyName, &endpointName);
+ MIDIObjectGetStringProperty(device, kMIDIPropertyName, &deviceName);
+ if (deviceName != NULL) {
+ fullName = CFStringCreateWithFormat(NULL, NULL, CFSTR("%@: %@"),
+ deviceName, endpointName);
+ } else {
+ fullName = endpointName;
+ }
+
+ /* copy the string into our buffer */
+ newName = (char*)mem_alloc(CFStringGetLength(fullName) + 1);
+ CFStringGetCString(fullName, newName, CFStringGetLength(fullName) + 1,
+ defaultEncoding);
+
+ /* clean up */
+ if (endpointName) CFRelease(endpointName);
+ if (deviceName) CFRelease(deviceName);
+ if (fullName) CFRelease(fullName);
+
+ return newName;
+}
+
+static int _macosx_start(struct midi_port *p)
+{
+ struct macosx_midi *m;
+ m = (struct macosx_midi *)p->userdata;
+
+ if (p->io & MIDI_INPUT
+ && MIDIPortConnectSource(portIn, m->ep, (void*)p) != noErr) {
+ return 0;
+ }
+
+ if (p->io & MIDI_OUTPUT) {
+ m->pl = (MIDIPacketList*)m->packet;
+ m->x = NULL;
+ }
+ return 1;
+}
+static int _macosx_stop(struct midi_port *p)
+{
+ struct macosx_midi *m;
+ m = (struct macosx_midi *)p->userdata;
+ if (p->io & MIDI_INPUT
+ && MIDIPortDisconnectSource(portIn, m->ep) != noErr) {
+ return 0;
+ }
+ return 1;
+}
+
+static void _macosx_poll(struct midi_provider *p)
+{
+ struct macosx_midi *data;
+ MIDIEndpointRef ep;
+ int i;
+
+ int num_out, num_in;
+
+ num_out = MIDIGetNumberOfDestinations();
+ num_in = MIDIGetNumberOfSources();
+
+ for (i = max_outputs; i < num_out; i++) {
+ ep = MIDIGetDestination(i);
+ if (!ep) continue;
+ data = mem_alloc(sizeof(struct macosx_midi));
+ memcpy(&data->ep, &ep, sizeof(ep));
+ data->name = get_ep_name(ep);
+ midi_port_register(p, MIDI_OUTPUT, data->name, data, 1);
+ }
+ max_outputs = i;
+
+
+ for (i = max_inputs; i < num_in; i++) {
+ ep = MIDIGetSource(i);
+ if (!ep) continue;
+ data = mem_alloc(sizeof(struct macosx_midi));
+ memcpy(&data->ep, &ep, sizeof(ep));
+ data->name = get_ep_name(ep);
+ midi_port_register(p, MIDI_INPUT, data->name, data, 1);
+ }
+ max_inputs = i;
+
+}
+
+int macosx_midi_setup(void)
+{
+ static struct midi_driver driver;
+
+ memset(&driver,0,sizeof(driver));
+ driver.flags = MIDI_PORT_CAN_SCHEDULE;
+ driver.poll = _macosx_poll;
+ driver.thread = NULL;
+ driver.enable = _macosx_start;
+ driver.disable = _macosx_stop;
+ driver.send = _macosx_send;
+ driver.drain = _macosx_drain;
+
+ if (MIDIClientCreate(CFSTR("Schism Tracker"), NULL, NULL, &client) != noErr) {
+ return 0;
+ }
+ if (MIDIInputPortCreate(client, CFSTR("Input port"), readProc, NULL, &portIn) != noErr) {
+ return 0;
+ }
+ if (MIDIOutputPortCreate(client, CFSTR("Output port"), &portOut) != noErr) {
+ return 0;
+ }
+
+ if (!midi_provider_register("Mac OS X", &driver)) return 0;
+
+ return 1;
+}
+
+#endif
diff --git a/src/sys/macosx/osdefs.c b/src/sys/macosx/osdefs.c
new file mode 100644
index 0000000..57fd832
--- /dev/null
+++ b/src/sys/macosx/osdefs.c
@@ -0,0 +1,54 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "headers.h"
+#include "osdefs.h"
+#include "event.h"
+#include "song.h"
+
+const char *osname = "macosx";
+
+
+int macosx_sdlevent(SDL_Event *event)
+{
+ if (event->type == SDL_KEYDOWN || event->type == SDL_KEYUP) {
+ if (event->key.keysym.sym == 0) {
+ switch (event->key.keysym.scancode) {
+ case 106: // mac F16 key
+ event->key.keysym.sym = SDLK_PRINT;
+ event->key.keysym.mod = KMOD_CTRL;
+ return 1;
+ case 234: // XXX what key is this?
+ if (event->type == SDL_KEYDOWN)
+ song_set_current_order(song_get_current_order() - 1);
+ return 0;
+ case 233: // XXX what key is this?
+ if (event->type == SDL_KEYUP)
+ song_set_current_order(song_get_current_order() + 1);
+ return 0;
+ };
+ }
+ }
+ return 1;
+}
+
diff --git a/src/sys/macosx/volume-macosx.c b/src/sys/macosx/volume-macosx.c
new file mode 100644
index 0000000..d07d947
--- /dev/null
+++ b/src/sys/macosx/volume-macosx.c
@@ -0,0 +1,119 @@
+/*
+ * Schism Tracker - a cross-platform Impulse Tracker clone
+ * copyright (c) 2003-2005 Storlek <storlek@rigelseven.com>
+ * copyright (c) 2005-2008 Mrs. Brisby <mrs.brisby@nimh.org>
+ * copyright (c) 2009 Storlek & Mrs. Brisby
+ * copyright (c) 2010-2012 Storlek
+ * URL: http://schismtracker.org/
+ *
+ * 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 2 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "headers.h"
+
+#include "util.h"
+
+#ifdef MACOSX
+
+#include <CoreServices/CoreServices.h>
+#include <CoreAudio/AudioHardware.h>
+
+int macosx_volume_get_max(void);
+int macosx_volume_get_max(void)
+{
+ return 65535;
+}
+
+void macosx_volume_read(int *left, int *right);
+void macosx_volume_read(int *left, int *right)
+{
+ UInt32 size;
+ AudioDeviceID od;
+ OSStatus e;
+ UInt32 ch[2];
+ Float32 fl[2];
+ int i;
+
+ if (left) *left = 0;
+ if (right) *right = 0;
+
+ size=sizeof(od);
+ e = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,
+ &size, &od);
+ if (e != 0) return;
+
+ size=sizeof(ch);
+ e = AudioDeviceGetProperty(od,
+ 0, /* QA1016 says "0" is master channel */
+ false,
+ kAudioDevicePropertyPreferredChannelsForStereo,
+ &size,
+ &ch);
+ if (e != 0) return;
+
+ for (i = 0; i < 2; i++) {
+ size = sizeof(Float32);
+ e = AudioDeviceGetProperty(od, /* device */
+ ch[i], /* preferred stereo channel */
+ false, /* output device */
+ kAudioDevicePropertyVolumeScalar,
+ &size,
+ &fl[i]);
+ if (e != 0) return;
+ }
+ if (left) *left = fl[0] * 65536.0f;
+ if (right) *right = fl[1] * 65536.0f;
+}
+
+void macosx_volume_write(int left, int right);
+void macosx_volume_write(int left, int right)
+{
+ UInt32 size;
+ AudioDeviceID od;
+ OSStatus e;
+ UInt32 ch[2];
+ Float32 fl[2];
+ int i;
+
+ size=sizeof(od);
+ e = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,
+ &size, &od);
+ if (e != 0) return;
+
+ size=sizeof(ch);
+ e = AudioDeviceGetProperty(od,
+ 0, /* QA1016 says "0" is master channel */
+ false,
+ kAudioDevicePropertyPreferredChannelsForStereo,
+ &size,
+ &ch);
+ if (e != 0) return;
+
+ fl[0] = ((float)left) / 65536.0f;
+ fl[1] = ((float)right) / 65536.0f;
+
+ for (i = 0; i < 2; i++) {
+ e = AudioDeviceSetProperty(od, /* device */
+ NULL, /* no timestamp */
+ ch[i], /* preferred stereo channel */
+ false, /* output device */
+ kAudioDevicePropertyVolumeScalar,
+ sizeof(Float32),
+ &fl[i]);
+ if (e != 0) return;
+ }
+}
+
+#endif
© All Rights Reserved