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; |
124 _frame = frame; |
124 _frame = frame; |
125 } |
125 } |
126 @end |
126 @end |
127 |
127 |
128 |
128 |
129 static void QZ_Draw(void); |
129 static void QZ_Draw(); |
130 static void QZ_UnsetVideoMode(void); |
130 static void QZ_UnsetVideoMode(); |
131 static void QZ_UpdatePalette(uint start, uint count); |
131 static void QZ_UpdatePalette(uint start, uint count); |
132 static void QZ_WarpCursor(int x, int y); |
132 static void QZ_WarpCursor(int x, int y); |
133 static void QZ_ShowMouse(void); |
133 static void QZ_ShowMouse(); |
134 static void QZ_HideMouse(void); |
134 static void QZ_HideMouse(); |
135 static void CocoaVideoFullScreen(bool full_screen); |
135 static void CocoaVideoFullScreen(bool full_screen); |
136 |
136 |
137 |
137 |
138 static NSAutoreleasePool *_ottd_autorelease_pool; |
138 static NSAutoreleasePool *_ottd_autorelease_pool; |
139 static OTTDMain *_ottd_main; |
139 static OTTDMain *_ottd_main; |
190 |
190 |
191 /****************************************************************************** |
191 /****************************************************************************** |
192 * Game loop and accessories * |
192 * Game loop and accessories * |
193 ******************************************************************************/ |
193 ******************************************************************************/ |
194 |
194 |
195 static uint32 GetTick(void) |
195 static uint32 GetTick() |
196 { |
196 { |
197 struct timeval tim; |
197 struct timeval tim; |
198 |
198 |
199 gettimeofday(&tim, NULL); |
199 gettimeofday(&tim, NULL); |
200 return tim.tv_usec / 1000 + tim.tv_sec * 1000; |
200 return tim.tv_usec / 1000 + tim.tv_sec * 1000; |
201 } |
201 } |
202 |
202 |
203 static void QZ_CheckPaletteAnim(void) |
203 static void QZ_CheckPaletteAnim() |
204 { |
204 { |
205 if (_pal_last_dirty != -1) { |
205 if (_pal_last_dirty != -1) { |
206 QZ_UpdatePalette(_pal_first_dirty, _pal_last_dirty - _pal_first_dirty + 1); |
206 QZ_UpdatePalette(_pal_first_dirty, _pal_last_dirty - _pal_first_dirty + 1); |
207 _pal_last_dirty = -1; |
207 _pal_last_dirty = -1; |
208 } |
208 } |
762 |
762 |
763 /* This function makes the *game region* of the window 100% opaque. |
763 /* This function makes the *game region* of the window 100% opaque. |
764 * The genie effect uses the alpha component. Otherwise, |
764 * The genie effect uses the alpha component. Otherwise, |
765 * it doesn't seem to matter what value it has. |
765 * it doesn't seem to matter what value it has. |
766 */ |
766 */ |
767 static void QZ_SetPortAlphaOpaque(void) |
767 static void QZ_SetPortAlphaOpaque() |
768 { |
768 { |
769 if (_cocoa_video_data.device_bpp == 32) { |
769 if (_cocoa_video_data.device_bpp == 32) { |
770 uint32* pixels = (uint32*)_cocoa_video_data.realpixels; |
770 uint32* pixels = (uint32*)_cocoa_video_data.realpixels; |
771 uint32 rowPixels = _cocoa_video_data.pitch / 4; |
771 uint32 rowPixels = _cocoa_video_data.pitch / 4; |
772 uint32 i; |
772 uint32 i; |
1030 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, |
1030 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, |
1031 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 |
1032 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0 |
1033 }; |
1033 }; |
1034 |
1034 |
1035 static void QZ_DrawResizeIcon(void) |
1035 static void QZ_DrawResizeIcon() |
1036 { |
1036 { |
1037 int xoff = _cocoa_video_data.width - 16; |
1037 int xoff = _cocoa_video_data.width - 16; |
1038 int yoff = _cocoa_video_data.height - 16; |
1038 int yoff = _cocoa_video_data.height - 16; |
1039 int x; |
1039 int x; |
1040 int y; |
1040 int y; |
1419 |
1419 |
1420 CGDisplaySetPalette(_cocoa_video_data.display_id, _cocoa_video_data.palette); |
1420 CGDisplaySetPalette(_cocoa_video_data.display_id, _cocoa_video_data.palette); |
1421 } |
1421 } |
1422 |
1422 |
1423 /* Wait for the VBL to occur (estimated since we don't have a hardware interrupt) */ |
1423 /* Wait for the VBL to occur (estimated since we don't have a hardware interrupt) */ |
1424 static void QZ_WaitForVerticalBlank(void) |
1424 static void QZ_WaitForVerticalBlank() |
1425 { |
1425 { |
1426 /* The VBL delay is based on Ian Ollmann's RezLib <iano@cco.caltech.edu> */ |
1426 /* The VBL delay is based on Ian Ollmann's RezLib <iano@cco.caltech.edu> */ |
1427 double refreshRate; |
1427 double refreshRate; |
1428 double linesPerSecond; |
1428 double linesPerSecond; |
1429 double target; |
1429 double target; |
1450 |
1450 |
1451 CSleep((uint32)(adjustment * 1000)); |
1451 CSleep((uint32)(adjustment * 1000)); |
1452 } |
1452 } |
1453 |
1453 |
1454 |
1454 |
1455 static void QZ_DrawScreen(void) |
1455 static void QZ_DrawScreen() |
1456 { |
1456 { |
1457 const uint8* src = _cocoa_video_data.pixels; |
1457 const uint8* src = _cocoa_video_data.pixels; |
1458 uint8* dst = (uint8*)_cocoa_video_data.realpixels; |
1458 uint8* dst = (uint8*)_cocoa_video_data.realpixels; |
1459 uint pitch = _cocoa_video_data.pitch; |
1459 uint pitch = _cocoa_video_data.pitch; |
1460 uint width = _cocoa_video_data.width; |
1460 uint width = _cocoa_video_data.width; |
1577 } else { |
1577 } else { |
1578 QZ_UpdateWindowPalette(start, count); |
1578 QZ_UpdateWindowPalette(start, count); |
1579 } |
1579 } |
1580 } |
1580 } |
1581 |
1581 |
1582 static void QZ_InitPalette(void) |
1582 static void QZ_InitPalette() |
1583 { |
1583 { |
1584 QZ_UpdatePalette(0, 256); |
1584 QZ_UpdatePalette(0, 256); |
1585 } |
1585 } |
1586 |
1586 |
1587 static void QZ_Draw(void) |
1587 static void QZ_Draw() |
1588 { |
1588 { |
1589 if (_cocoa_video_data.fullscreen) { |
1589 if (_cocoa_video_data.fullscreen) { |
1590 QZ_DrawScreen(); |
1590 QZ_DrawScreen(); |
1591 } else { |
1591 } else { |
1592 QZ_DrawWindow(); |
1592 QZ_DrawWindow(); |
1717 if (ret != NULL && wasset) QZ_SetVideoMode(oldwidth, oldheight, oldfullscreen); |
1717 if (ret != NULL && wasset) QZ_SetVideoMode(oldwidth, oldheight, oldfullscreen); |
1718 |
1718 |
1719 return ret; |
1719 return ret; |
1720 } |
1720 } |
1721 |
1721 |
1722 static void QZ_VideoInit(void) |
1722 static void QZ_VideoInit() |
1723 { |
1723 { |
1724 memset(&_cocoa_video_data, 0, sizeof(_cocoa_video_data)); |
1724 memset(&_cocoa_video_data, 0, sizeof(_cocoa_video_data)); |
1725 |
1725 |
1726 /* Initialize the video settings; this data persists between mode switches */ |
1726 /* Initialize the video settings; this data persists between mode switches */ |
1727 _cocoa_video_data.display_id = kCGDirectMainDisplay; |
1727 _cocoa_video_data.display_id = kCGDirectMainDisplay; |
1787 CGWarpMouseCursorPosition(cgp); |
1787 CGWarpMouseCursorPosition(cgp); |
1788 |
1788 |
1789 /* Generate the mouse moved event */ |
1789 /* Generate the mouse moved event */ |
1790 } |
1790 } |
1791 |
1791 |
1792 static void QZ_ShowMouse(void) |
1792 static void QZ_ShowMouse() |
1793 { |
1793 { |
1794 if (!_cocoa_video_data.cursor_visible) { |
1794 if (!_cocoa_video_data.cursor_visible) { |
1795 [ NSCursor unhide ]; |
1795 [ NSCursor unhide ]; |
1796 _cocoa_video_data.cursor_visible = true; |
1796 _cocoa_video_data.cursor_visible = true; |
1797 |
1797 |
1911 /* Finally give up our references to the objects */ |
1911 /* Finally give up our references to the objects */ |
1912 [windowMenu release]; |
1912 [windowMenu release]; |
1913 [windowMenuItem release]; |
1913 [windowMenuItem release]; |
1914 } |
1914 } |
1915 |
1915 |
1916 static void setupApplication(void) |
1916 static void setupApplication() |
1917 { |
1917 { |
1918 CPSProcessSerNum PSN; |
1918 CPSProcessSerNum PSN; |
1919 |
1919 |
1920 /* Ensure the application object is initialised */ |
1920 /* Ensure the application object is initialised */ |
1921 [NSApplication sharedApplication]; |
1921 [NSApplication sharedApplication]; |
1940 |
1940 |
1941 /****************************************************************************** |
1941 /****************************************************************************** |
1942 * Video driver interface * |
1942 * Video driver interface * |
1943 ******************************************************************************/ |
1943 ******************************************************************************/ |
1944 |
1944 |
1945 static void CocoaVideoStop(void) |
1945 static void CocoaVideoStop() |
1946 { |
1946 { |
1947 if (!_cocoa_video_started) return; |
1947 if (!_cocoa_video_started) return; |
1948 |
1948 |
1949 if (_cocoa_video_data.isset) QZ_UnsetVideoMode(); |
1949 if (_cocoa_video_data.isset) QZ_UnsetVideoMode(); |
1950 |
1950 |
2042 _cocoa_video_dialog = false; |
2042 _cocoa_video_dialog = false; |
2043 } |
2043 } |
2044 |
2044 |
2045 |
2045 |
2046 /* This is needed since OS X applications are started with the working dir set to / when double-clicked */ |
2046 /* This is needed since OS X applications are started with the working dir set to / when double-clicked */ |
2047 void cocoaSetWorkingDirectory(void) |
2047 void cocoaSetWorkingDirectory() |
2048 { |
2048 { |
2049 char parentdir[MAXPATHLEN]; |
2049 char parentdir[MAXPATHLEN]; |
2050 int chdir_ret; |
2050 int chdir_ret; |
2051 CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); |
2051 CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); |
2052 CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url); |
2052 CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url); |
2059 } |
2059 } |
2060 |
2060 |
2061 /* These are called from main() to prevent a _NSAutoreleaseNoPool error when |
2061 /* These are called from main() to prevent a _NSAutoreleaseNoPool error when |
2062 * exiting before the cocoa video driver has been loaded |
2062 * exiting before the cocoa video driver has been loaded |
2063 */ |
2063 */ |
2064 void cocoaSetupAutoreleasePool(void) |
2064 void cocoaSetupAutoreleasePool() |
2065 { |
2065 { |
2066 _ottd_autorelease_pool = [[NSAutoreleasePool alloc] init]; |
2066 _ottd_autorelease_pool = [[NSAutoreleasePool alloc] init]; |
2067 } |
2067 } |
2068 |
2068 |
2069 void cocoaReleaseAutoreleasePool(void) |
2069 void cocoaReleaseAutoreleasePool() |
2070 { |
2070 { |
2071 [_ottd_autorelease_pool release]; |
2071 [_ottd_autorelease_pool release]; |
2072 } |
2072 } |
2073 |
2073 |
2074 #endif /* WITH_COCOA */ |
2074 #endif /* WITH_COCOA */ |