src/video/cocoa_v.mm
branchgamebalance
changeset 9895 7bd07f43b0e3
parent 6514 634933c84aef
child 9913 e79cd19772dd
equal deleted inserted replaced
9894:70d78ac95d6c 9895:7bd07f43b0e3
    29  * Read http://developer.apple.com/releasenotes/Cocoa/Objective-C++.html for more information.
    29  * Read http://developer.apple.com/releasenotes/Cocoa/Objective-C++.html for more information.
    30  */
    30  */
    31 
    31 
    32 
    32 
    33 /* Portions of CPS.h */
    33 /* Portions of CPS.h */
    34 typedef struct CPSProcessSerNum {
    34 struct CPSProcessSerNum {
    35 	UInt32 lo;
    35 	UInt32 lo;
    36 	UInt32 hi;
    36 	UInt32 hi;
    37 } CPSProcessSerNum;
    37 };
    38 
    38 
    39 extern "C" OSErr CPSGetCurrentProcess(CPSProcessSerNum* psn);
    39 extern "C" OSErr CPSGetCurrentProcess(CPSProcessSerNum* psn);
    40 extern "C" OSErr CPSEnableForegroundOperation(CPSProcessSerNum* psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
    40 extern "C" OSErr CPSEnableForegroundOperation(CPSProcessSerNum* psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
    41 extern "C" OSErr CPSSetFrontProcess(CPSProcessSerNum* psn);
    41 extern "C" OSErr CPSSetFrontProcess(CPSProcessSerNum* psn);
    42 
    42 
    43 /* From Menus.h (according to Xcode Developer Documentation) */
    43 /* From Menus.h (according to Xcode Developer Documentation) */
    44 extern "C" void ShowMenuBar(void);
    44 extern "C" void ShowMenuBar();
    45 extern "C" void HideMenuBar(void);
    45 extern "C" void HideMenuBar();
    46 
    46 
    47 /* Disables a warning. This is needed since the method exists but has been dropped from the header, supposedly as of 10.4. */
    47 /* Disables a warning. This is needed since the method exists but has been dropped from the header, supposedly as of 10.4. */
    48 #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
    48 #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4)
    49 @interface NSApplication(NSAppleMenu)
    49 @interface NSApplication(NSAppleMenu)
    50 - (void)setAppleMenu:(NSMenu *)menu;
    50 - (void)setAppleMenu:(NSMenu *)menu;
    66 
    66 
    67 #include "../stdafx.h"
    67 #include "../stdafx.h"
    68 #include "../debug.h"
    68 #include "../debug.h"
    69 #include "../macros.h"
    69 #include "../macros.h"
    70 #include "../os/macosx/splash.h"
    70 #include "../os/macosx/splash.h"
       
    71 #include "../variables.h"
    71 #include "cocoa_v.h"
    72 #include "cocoa_v.h"
    72 #include "cocoa_keys.h"
    73 #include "cocoa_keys.h"
    73 
    74 
    74 #undef Point
    75 #undef Point
    75 #undef Rect
    76 #undef Rect
   101 /* Structure for rez switch gamma fades
   102 /* Structure for rez switch gamma fades
   102  * We can hide the monitor flicker by setting the gamma tables to 0
   103  * We can hide the monitor flicker by setting the gamma tables to 0
   103  */
   104  */
   104 #define QZ_GAMMA_TABLE_SIZE 256
   105 #define QZ_GAMMA_TABLE_SIZE 256
   105 
   106 
   106 typedef struct {
   107 struct OTTD_QuartzGammaTable {
   107 	CGGammaValue red[QZ_GAMMA_TABLE_SIZE];
   108 	CGGammaValue red[QZ_GAMMA_TABLE_SIZE];
   108 	CGGammaValue green[QZ_GAMMA_TABLE_SIZE];
   109 	CGGammaValue green[QZ_GAMMA_TABLE_SIZE];
   109 	CGGammaValue blue[QZ_GAMMA_TABLE_SIZE];
   110 	CGGammaValue blue[QZ_GAMMA_TABLE_SIZE];
   110 } OTTD_QuartzGammaTable;
   111 };
   111 
   112 
   112 /* Add methods to get at private members of NSScreen.
   113 /* Add methods to get at private members of NSScreen.
   113  * Since there is a bug in Apple's screen switching code that does not update
   114  * Since there is a bug in Apple's screen switching code that does not update
   114  * this variable when switching to fullscreen, we'll set it manually (but only
   115  * this variable when switching to fullscreen, we'll set it manually (but only
   115  * for the main screen).
   116  * for the main screen).
   124 	_frame = frame;
   125 	_frame = frame;
   125 }
   126 }
   126 @end
   127 @end
   127 
   128 
   128 
   129 
   129 static void QZ_Draw(void);
   130 static void QZ_Draw();
   130 static void QZ_UnsetVideoMode(void);
   131 static void QZ_UnsetVideoMode();
   131 static void QZ_UpdatePalette(uint start, uint count);
   132 static void QZ_UpdatePalette(uint start, uint count);
   132 static void QZ_WarpCursor(int x, int y);
   133 static void QZ_WarpCursor(int x, int y);
   133 static void QZ_ShowMouse(void);
   134 static void QZ_ShowMouse();
   134 static void QZ_HideMouse(void);
   135 static void QZ_HideMouse();
   135 static void CocoaVideoFullScreen(bool full_screen);
   136 static void CocoaVideoFullScreen(bool full_screen);
   136 
   137 
   137 
   138 
   138 static NSAutoreleasePool *_ottd_autorelease_pool;
   139 static NSAutoreleasePool *_ottd_autorelease_pool;
   139 static OTTDMain *_ottd_main;
   140 static OTTDMain *_ottd_main;
   190 
   191 
   191 /******************************************************************************
   192 /******************************************************************************
   192  *                             Game loop and accessories                      *
   193  *                             Game loop and accessories                      *
   193  ******************************************************************************/
   194  ******************************************************************************/
   194 
   195 
   195 static uint32 GetTick(void)
   196 static uint32 GetTick()
   196 {
   197 {
   197 	struct timeval tim;
   198 	struct timeval tim;
   198 
   199 
   199 	gettimeofday(&tim, NULL);
   200 	gettimeofday(&tim, NULL);
   200 	return tim.tv_usec / 1000 + tim.tv_sec * 1000;
   201 	return tim.tv_usec / 1000 + tim.tv_sec * 1000;
   201 }
   202 }
   202 
   203 
   203 static void QZ_CheckPaletteAnim(void)
   204 static void QZ_CheckPaletteAnim()
   204 {
   205 {
   205 	if (_pal_last_dirty != -1) {
   206 	if (_pal_last_dirty != -1) {
   206 		QZ_UpdatePalette(_pal_first_dirty, _pal_last_dirty - _pal_first_dirty + 1);
   207 		QZ_UpdatePalette(_pal_first_dirty, _pal_last_dirty - _pal_first_dirty + 1);
   207 		_pal_last_dirty = -1;
   208 		_pal_last_dirty = -1;
   208 	}
   209 	}
   209 }
   210 }
   210 
   211 
   211 
   212 
   212 
   213 
   213 typedef struct VkMapping {
   214 struct VkMapping {
   214 	unsigned short vk_from;
   215 	unsigned short vk_from;
   215 	byte map_to;
   216 	byte map_to;
   216 } VkMapping;
   217 };
   217 
   218 
   218 #define AS(x, z) {x, z}
   219 #define AS(x, z) {x, z}
   219 
   220 
   220 static const VkMapping _vk_mapping[] = {
   221 static const VkMapping _vk_mapping[] = {
   221 	AS(QZ_BACKQUOTE,  WKC_BACKQUOTE), // key left of '1'
   222 	AS(QZ_BACKQUOTE,  WKC_BACKQUOTE), // key left of '1'
   467 		return [ _cocoa_video_data.qdview mouse:*pt inRect:[ _cocoa_video_data.qdview bounds ] ];
   468 		return [ _cocoa_video_data.qdview mouse:*pt inRect:[ _cocoa_video_data.qdview bounds ] ];
   468 	}
   469 	}
   469 }
   470 }
   470 
   471 
   471 
   472 
   472 static bool QZ_PollEvent(void)
   473 static bool QZ_PollEvent()
   473 {
   474 {
   474 	NSEvent *event;
   475 	NSEvent *event;
   475 	NSPoint pt;
   476 	NSPoint pt;
   476 	NSString *chars;
   477 	NSString *chars;
   477 #ifdef _DEBUG
   478 #ifdef _DEBUG
   651 			if ([ event deltaY ] > 0.0) { /* Scroll up */
   652 			if ([ event deltaY ] > 0.0) { /* Scroll up */
   652 				_cursor.wheel--;
   653 				_cursor.wheel--;
   653 			} else if ([ event deltaY ] < 0.0) { /* Scroll down */
   654 			} else if ([ event deltaY ] < 0.0) { /* Scroll down */
   654 				_cursor.wheel++;
   655 				_cursor.wheel++;
   655 			} /* else: deltaY was 0.0 and we don't want to do anything */
   656 			} /* else: deltaY was 0.0 and we don't want to do anything */
       
   657 
       
   658 			/* Set the scroll count for scrollwheel scrolling */
       
   659 			_cursor.h_wheel -= (int)([ event deltaX ]* 5 * _patches.scrollwheel_multiplier);
       
   660 			_cursor.v_wheel -= (int)([ event deltaY ]* 5 * _patches.scrollwheel_multiplier);
   656 			break;
   661 			break;
   657 
   662 
   658 		default:
   663 		default:
   659 			[NSApp sendEvent:event];
   664 			[NSApp sendEvent:event];
   660 	}
   665 	}
   661 
   666 
   662 	return true;
   667 	return true;
   663 }
   668 }
   664 
   669 
   665 
   670 
   666 static void QZ_GameLoop(void)
   671 static void QZ_GameLoop()
   667 {
   672 {
   668 	uint32 cur_ticks = GetTick();
   673 	uint32 cur_ticks = GetTick();
   669 	uint32 next_tick = cur_ticks + 30;
   674 	uint32 next_tick = cur_ticks + 30;
   670 	uint32 pal_tick = 0;
   675 	uint32 pal_tick = 0;
   671 #ifdef _DEBUG
   676 #ifdef _DEBUG
   710 		} else if (_fast_forward & 2) {
   715 		} else if (_fast_forward & 2) {
   711 			_fast_forward = 0;
   716 			_fast_forward = 0;
   712 		}
   717 		}
   713 
   718 
   714 		cur_ticks = GetTick();
   719 		cur_ticks = GetTick();
   715 		if (cur_ticks >= next_tick || (_fast_forward && !_pause) || cur_ticks < prev_cur_ticks) {
   720 		if (cur_ticks >= next_tick || (_fast_forward && !_pause_game) || cur_ticks < prev_cur_ticks) {
   716 			next_tick = cur_ticks + 30;
   721 			next_tick = cur_ticks + 30;
   717 
   722 
   718 			_ctrl_pressed = !!(_cocoa_video_data.current_mods & NSControlKeyMask);
   723 			_ctrl_pressed = !!(_cocoa_video_data.current_mods & NSControlKeyMask);
   719 			_shift_pressed = !!(_cocoa_video_data.current_mods & NSShiftKeyMask);
   724 			_shift_pressed = !!(_cocoa_video_data.current_mods & NSShiftKeyMask);
   720 #ifdef _DEBUG
   725 #ifdef _DEBUG
   762 
   767 
   763 /* This function makes the *game region* of the window 100% opaque.
   768 /* This function makes the *game region* of the window 100% opaque.
   764  * The genie effect uses the alpha component. Otherwise,
   769  * The genie effect uses the alpha component. Otherwise,
   765  * it doesn't seem to matter what value it has.
   770  * it doesn't seem to matter what value it has.
   766  */
   771  */
   767 static void QZ_SetPortAlphaOpaque(void)
   772 static void QZ_SetPortAlphaOpaque()
   768 {
   773 {
   769 	if (_cocoa_video_data.device_bpp == 32) {
   774 	if (_cocoa_video_data.device_bpp == 32) {
   770 		uint32* pixels = (uint32*)_cocoa_video_data.realpixels;
   775 		uint32* pixels = (uint32*)_cocoa_video_data.realpixels;
   771 		uint32 rowPixels = _cocoa_video_data.pitch / 4;
   776 		uint32 rowPixels = _cocoa_video_data.pitch / 4;
   772 		uint32 i;
   777 		uint32 i;
  1030 	0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
  1035 	0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1,
  1031 	0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0,
  1036 	0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0,
  1032 	1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0
  1037 	1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0
  1033 };
  1038 };
  1034 
  1039 
  1035 static void QZ_DrawResizeIcon(void)
  1040 static void QZ_DrawResizeIcon()
  1036 {
  1041 {
  1037 	int xoff = _cocoa_video_data.width - 16;
  1042 	int xoff = _cocoa_video_data.width - 16;
  1038 	int yoff = _cocoa_video_data.height - 16;
  1043 	int yoff = _cocoa_video_data.height - 16;
  1039 	int x;
  1044 	int x;
  1040 	int y;
  1045 	int y;
  1052 			}
  1057 			}
  1053 		}
  1058 		}
  1054 	}
  1059 	}
  1055 }
  1060 }
  1056 
  1061 
  1057 static void QZ_DrawWindow(void)
  1062 static void QZ_DrawWindow()
  1058 {
  1063 {
  1059 	int i;
  1064 	int i;
  1060 	RgnHandle dirty, temp;
  1065 	RgnHandle dirty, temp;
  1061 
  1066 
  1062 	/* Check if we need to do anything */
  1067 	/* Check if we need to do anything */
  1419 
  1424 
  1420 	CGDisplaySetPalette(_cocoa_video_data.display_id, _cocoa_video_data.palette);
  1425 	CGDisplaySetPalette(_cocoa_video_data.display_id, _cocoa_video_data.palette);
  1421 }
  1426 }
  1422 
  1427 
  1423 /* Wait for the VBL to occur (estimated since we don't have a hardware interrupt) */
  1428 /* Wait for the VBL to occur (estimated since we don't have a hardware interrupt) */
  1424 static void QZ_WaitForVerticalBlank(void)
  1429 static void QZ_WaitForVerticalBlank()
  1425 {
  1430 {
  1426 	/* The VBL delay is based on Ian Ollmann's RezLib <iano@cco.caltech.edu> */
  1431 	/* The VBL delay is based on Ian Ollmann's RezLib <iano@cco.caltech.edu> */
  1427 	double refreshRate;
  1432 	double refreshRate;
  1428 	double linesPerSecond;
  1433 	double linesPerSecond;
  1429 	double target;
  1434 	double target;
  1450 
  1455 
  1451 	CSleep((uint32)(adjustment * 1000));
  1456 	CSleep((uint32)(adjustment * 1000));
  1452 }
  1457 }
  1453 
  1458 
  1454 
  1459 
  1455 static void QZ_DrawScreen(void)
  1460 static void QZ_DrawScreen()
  1456 {
  1461 {
  1457 	const uint8* src = _cocoa_video_data.pixels;
  1462 	const uint8* src = _cocoa_video_data.pixels;
  1458 	uint8* dst       = (uint8*)_cocoa_video_data.realpixels;
  1463 	uint8* dst       = (uint8*)_cocoa_video_data.realpixels;
  1459 	uint pitch       = _cocoa_video_data.pitch;
  1464 	uint pitch       = _cocoa_video_data.pitch;
  1460 	uint width       = _cocoa_video_data.width;
  1465 	uint width       = _cocoa_video_data.width;
  1577 	} else {
  1582 	} else {
  1578 		QZ_UpdateWindowPalette(start, count);
  1583 		QZ_UpdateWindowPalette(start, count);
  1579 	}
  1584 	}
  1580 }
  1585 }
  1581 
  1586 
  1582 static void QZ_InitPalette(void)
  1587 static void QZ_InitPalette()
  1583 {
  1588 {
  1584 	QZ_UpdatePalette(0, 256);
  1589 	QZ_UpdatePalette(0, 256);
  1585 }
  1590 }
  1586 
  1591 
  1587 static void QZ_Draw(void)
  1592 static void QZ_Draw()
  1588 {
  1593 {
  1589 	if (_cocoa_video_data.fullscreen) {
  1594 	if (_cocoa_video_data.fullscreen) {
  1590 		QZ_DrawScreen();
  1595 		QZ_DrawScreen();
  1591 	} else {
  1596 	} else {
  1592 		QZ_DrawWindow();
  1597 		QZ_DrawWindow();
  1606 	{1600, 1200},
  1611 	{1600, 1200},
  1607 	{1680, 1050},
  1612 	{1680, 1050},
  1608 	{1920, 1200}
  1613 	{1920, 1200}
  1609 };
  1614 };
  1610 
  1615 
  1611 static void QZ_UpdateVideoModes(void)
  1616 static void QZ_UpdateVideoModes()
  1612 {
  1617 {
  1613 	uint i, j, count;
  1618 	uint i, j, count;
  1614 	OTTDPoint modes[32];
  1619 	OTTDPoint modes[32];
  1615 	const OTTDPoint *current_modes;
  1620 	const OTTDPoint *current_modes;
  1616 
  1621 
  1634 	}
  1639 	}
  1635 
  1640 
  1636 	_num_resolutions = j;
  1641 	_num_resolutions = j;
  1637 }
  1642 }
  1638 
  1643 
  1639 static void QZ_UnsetVideoMode(void)
  1644 static void QZ_UnsetVideoMode()
  1640 {
  1645 {
  1641 	if (_cocoa_video_data.fullscreen) {
  1646 	if (_cocoa_video_data.fullscreen) {
  1642 		/* Release fullscreen resources */
  1647 		/* Release fullscreen resources */
  1643 		OTTD_QuartzGammaTable gamma_table;
  1648 		OTTD_QuartzGammaTable gamma_table;
  1644 		int gamma_error;
  1649 		int gamma_error;
  1717 	if (ret != NULL && wasset) QZ_SetVideoMode(oldwidth, oldheight, oldfullscreen);
  1722 	if (ret != NULL && wasset) QZ_SetVideoMode(oldwidth, oldheight, oldfullscreen);
  1718 
  1723 
  1719 	return ret;
  1724 	return ret;
  1720 }
  1725 }
  1721 
  1726 
  1722 static void QZ_VideoInit(void)
  1727 static void QZ_VideoInit()
  1723 {
  1728 {
  1724 	memset(&_cocoa_video_data, 0, sizeof(_cocoa_video_data));
  1729 	memset(&_cocoa_video_data, 0, sizeof(_cocoa_video_data));
  1725 
  1730 
  1726 	/* Initialize the video settings; this data persists between mode switches */
  1731 	/* Initialize the video settings; this data persists between mode switches */
  1727 	_cocoa_video_data.display_id = kCGDirectMainDisplay;
  1732 	_cocoa_video_data.display_id = kCGDirectMainDisplay;
  1787 	CGWarpMouseCursorPosition(cgp);
  1792 	CGWarpMouseCursorPosition(cgp);
  1788 
  1793 
  1789 	/* Generate the mouse moved event */
  1794 	/* Generate the mouse moved event */
  1790 }
  1795 }
  1791 
  1796 
  1792 static void QZ_ShowMouse(void)
  1797 static void QZ_ShowMouse()
  1793 {
  1798 {
  1794 	if (!_cocoa_video_data.cursor_visible) {
  1799 	if (!_cocoa_video_data.cursor_visible) {
  1795 		[ NSCursor unhide ];
  1800 		[ NSCursor unhide ];
  1796 		_cocoa_video_data.cursor_visible = true;
  1801 		_cocoa_video_data.cursor_visible = true;
  1797 
  1802 
  1800 			UndrawMouseCursor();
  1805 			UndrawMouseCursor();
  1801 		_cursor.in_window = false;
  1806 		_cursor.in_window = false;
  1802 	}
  1807 	}
  1803 }
  1808 }
  1804 
  1809 
  1805 static void QZ_HideMouse(void)
  1810 static void QZ_HideMouse()
  1806 {
  1811 {
  1807 	if (_cocoa_video_data.cursor_visible) {
  1812 	if (_cocoa_video_data.cursor_visible) {
  1808 #ifndef _DEBUG
  1813 #ifndef _DEBUG
  1809 		[ NSCursor hide ];
  1814 		[ NSCursor hide ];
  1810 #endif
  1815 #endif
  1840 
  1845 
  1841 	return NSTerminateCancel; // NSTerminateLater ?
  1846 	return NSTerminateCancel; // NSTerminateLater ?
  1842 }
  1847 }
  1843 @end
  1848 @end
  1844 
  1849 
  1845 static void setApplicationMenu(void)
  1850 static void setApplicationMenu()
  1846 {
  1851 {
  1847 	/* warning: this code is very odd */
  1852 	/* warning: this code is very odd */
  1848 	NSMenu *appleMenu;
  1853 	NSMenu *appleMenu;
  1849 	NSMenuItem *menuItem;
  1854 	NSMenuItem *menuItem;
  1850 	NSString *title;
  1855 	NSString *title;
  1885 	[appleMenu release];
  1890 	[appleMenu release];
  1886 	[menuItem release];
  1891 	[menuItem release];
  1887 }
  1892 }
  1888 
  1893 
  1889 /* Create a window menu */
  1894 /* Create a window menu */
  1890 static void setupWindowMenu(void)
  1895 static void setupWindowMenu()
  1891 {
  1896 {
  1892 	NSMenu* windowMenu;
  1897 	NSMenu* windowMenu;
  1893 	NSMenuItem* windowMenuItem;
  1898 	NSMenuItem* windowMenuItem;
  1894 	NSMenuItem* menuItem;
  1899 	NSMenuItem* menuItem;
  1895 
  1900 
  1911 	/* Finally give up our references to the objects */
  1916 	/* Finally give up our references to the objects */
  1912 	[windowMenu release];
  1917 	[windowMenu release];
  1913 	[windowMenuItem release];
  1918 	[windowMenuItem release];
  1914 }
  1919 }
  1915 
  1920 
  1916 static void setupApplication(void)
  1921 static void setupApplication()
  1917 {
  1922 {
  1918 	CPSProcessSerNum PSN;
  1923 	CPSProcessSerNum PSN;
  1919 
  1924 
  1920 	/* Ensure the application object is initialised */
  1925 	/* Ensure the application object is initialised */
  1921 	[NSApplication sharedApplication];
  1926 	[NSApplication sharedApplication];
  1940 
  1945 
  1941 /******************************************************************************
  1946 /******************************************************************************
  1942  *                             Video driver interface                         *
  1947  *                             Video driver interface                         *
  1943  ******************************************************************************/
  1948  ******************************************************************************/
  1944 
  1949 
  1945 static void CocoaVideoStop(void)
  1950 static void CocoaVideoStop()
  1946 {
  1951 {
  1947 	if (!_cocoa_video_started) return;
  1952 	if (!_cocoa_video_started) return;
  1948 
  1953 
  1949 	if (_cocoa_video_data.isset) QZ_UnsetVideoMode();
  1954 	if (_cocoa_video_data.isset) QZ_UnsetVideoMode();
  1950 
  1955 
  1984 		_cocoa_video_data.dirty_rects[_cocoa_video_data.num_dirty_rects].bottom = top + height;
  1989 		_cocoa_video_data.dirty_rects[_cocoa_video_data.num_dirty_rects].bottom = top + height;
  1985 	}
  1990 	}
  1986 	_cocoa_video_data.num_dirty_rects++;
  1991 	_cocoa_video_data.num_dirty_rects++;
  1987 }
  1992 }
  1988 
  1993 
  1989 static void CocoaVideoMainLoop(void)
  1994 static void CocoaVideoMainLoop()
  1990 {
  1995 {
  1991 	/* Start the main event loop */
  1996 	/* Start the main event loop */
  1992 	[NSApp run];
  1997 	[NSApp run];
  1993 }
  1998 }
  1994 
  1999 
  2040 	if (!wasstarted) CocoaVideoStop();
  2045 	if (!wasstarted) CocoaVideoStop();
  2041 
  2046 
  2042 	_cocoa_video_dialog = false;
  2047 	_cocoa_video_dialog = false;
  2043 }
  2048 }
  2044 
  2049 
  2045 
       
  2046 /* This is needed since OS X applications are started with the working dir set to / when double-clicked */
       
  2047 void cocoaSetWorkingDirectory(void)
       
  2048 {
       
  2049 	char parentdir[MAXPATHLEN];
       
  2050 	int chdir_ret;
       
  2051 	CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
       
  2052 	CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url);
       
  2053 	if (CFURLGetFileSystemRepresentation(url2, true, (unsigned char*)parentdir, MAXPATHLEN)) {
       
  2054 		chdir_ret = chdir(parentdir); /* chdir to the binary app's parent */
       
  2055 		assert(chdir_ret == 0);
       
  2056 	}
       
  2057 	CFRelease(url);
       
  2058 	CFRelease(url2);
       
  2059 }
       
  2060 
       
  2061 /* These are called from main() to prevent a _NSAutoreleaseNoPool error when
  2050 /* These are called from main() to prevent a _NSAutoreleaseNoPool error when
  2062  * exiting before the cocoa video driver has been loaded
  2051  * exiting before the cocoa video driver has been loaded
  2063  */
  2052  */
  2064 void cocoaSetupAutoreleasePool(void)
  2053 void cocoaSetupAutoreleasePool()
  2065 {
  2054 {
  2066 	_ottd_autorelease_pool = [[NSAutoreleasePool alloc] init];
  2055 	_ottd_autorelease_pool = [[NSAutoreleasePool alloc] init];
  2067 }
  2056 }
  2068 
  2057 
  2069 void cocoaReleaseAutoreleasePool(void)
  2058 void cocoaReleaseAutoreleasePool()
  2070 {
  2059 {
  2071 	[_ottd_autorelease_pool release];
  2060 	[_ottd_autorelease_pool release];
  2072 }
  2061 }
  2073 
  2062 
  2074 #endif /* WITH_COCOA */
  2063 #endif /* WITH_COCOA */