PolyCocoaCore.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. /*
  2. * PolyCocoaCore.cpp
  3. * Poly
  4. *
  5. * Created by Ivan Safrin on 2/16/10.
  6. * Copyright 2010 Ivan Safrin. All rights reserved.
  7. *
  8. */
  9. #include "PolyCocoaCore.h"
  10. #include <iostream>
  11. using namespace Polycode;
  12. long getThreadID() {
  13. return (long)pthread_self();
  14. }
  15. CocoaCore::CocoaCore(SubstanceView *view, int xRes, int yRes, bool fullScreen,int aaLevel, int frameRate) : Core(xRes, yRes, fullScreen,aaLevel, frameRate) {
  16. eventMutex = createMutex();
  17. // NSLog(@"BUNDLE: %@", [[NSBundle mainBundle] bundlePath]);
  18. chdir([[[NSBundle mainBundle] bundlePath] UTF8String]);
  19. NSOpenGLPixelFormatAttribute attrs[32];
  20. int atindx = 0;
  21. attrs[atindx++] = NSOpenGLPFADoubleBuffer;
  22. attrs[atindx++] = NSOpenGLPFADepthSize;
  23. attrs[atindx++] = 32;
  24. if(aaLevel > 0) {
  25. attrs[atindx++] = NSOpenGLPFASampleBuffers;
  26. attrs[atindx++] = 1;
  27. attrs[atindx++] = NSOpenGLPFASamples;
  28. attrs[atindx++] = aaLevel;
  29. attrs[atindx++] = NSOpenGLPFAMultisample;
  30. }
  31. attrs[atindx++] = NSOpenGLPFANoRecovery;
  32. if(fullScreen) {
  33. // attrs[atindx++] = NSOpenGLPFAFullScreen;
  34. // attrs[atindx++] = NSOpenGLPFAScreenMask;
  35. // attrs[atindx++] = CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay);
  36. }
  37. attrs[atindx++] = NSOpenGLPFAAccelerated;
  38. attrs[atindx++] = nil;
  39. /*
  40. NSOpenGLPixelFormatAttribute attrs[] =
  41. {
  42. NSOpenGLPFADoubleBuffer,
  43. NSOpenGLPFADepthSize, 16,
  44. // NSOpenGLPFAFullScreen,
  45. // NSOpenGLPFAScreenMask,
  46. // CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay),
  47. NSOpenGLPFASampleBuffers, 1,
  48. NSOpenGLPFASamples, aaLevel,
  49. NSOpenGLPFANoRecovery,
  50. // NSOpenGLPFAWindow,
  51. NSOpenGLPFAMultisample,
  52. // NSOpenGLPFAAccelerated,
  53. // NSOpenGLPFAAccumSize, 0,
  54. nil
  55. };
  56. */
  57. // [view lockContext];
  58. [view setCore:this];
  59. NSOpenGLPixelFormat *format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
  60. if(!format) {
  61. NSLog(@"Error creating pixel format!\n");
  62. }
  63. context = [[NSOpenGLContext alloc] initWithFormat: format shareContext:nil];
  64. if (context == nil) {
  65. NSLog(@"Failed to create open gl context");
  66. }
  67. if(false) {
  68. // [view enterFullScreenMode:[NSScreen mainScreen] withOptions:0];
  69. // [view removeFromSuperview];
  70. // [[view window] orderOut:nil];
  71. // CGDisplayCapture (kCGDirectMainDisplay ) ;
  72. // CGDisplaySwitchToMode (kCGDirectMainDisplay, CGDisplayBestModeForParameters (kCGDirectMainDisplay, 32, xRes, yRes, NULL) );
  73. // [context makeCurrentContext];
  74. // [context setFullScreen];
  75. // [context flushBuffer];
  76. // CGDisplayCapture (kCGDirectMainDisplay ) ;
  77. // [context clearDrawable];
  78. // [context release];
  79. } else {
  80. [view clearGLContext];
  81. [view setOpenGLContext:context];
  82. [context setView: view];
  83. }
  84. if(fullScreen) {
  85. // [view enterFullScreenMode:[NSScreen mainScreen] withOptions:0];
  86. }
  87. glView = view;
  88. initTime = mach_absolute_time();
  89. // while(![view isContextReady]) {
  90. // }
  91. renderer = new OpenGLRenderer();
  92. services->setRenderer(renderer);
  93. //[view unlockContext];
  94. setVideoMode(xRes,yRes,fullScreen,aaLevel);
  95. }
  96. void CocoaCore::copyStringToClipboard(String str) {
  97. NSPasteboard *pb = [NSPasteboard generalPasteboard];
  98. NSArray *types = [NSArray arrayWithObjects:NSStringPboardType, nil];
  99. [pb declareTypes:types owner:glView];
  100. //NSString *nsstr = [NSString stringWithCharacters: (unichar*) str.c_str() length: str.length()];
  101. char* data = (char*)str.data();
  102. unsigned size = str.size() * sizeof(wchar_t);
  103. NSString* nsstr = [[[NSString alloc] initWithBytes:data length:size encoding:NSUTF32LittleEndianStringEncoding] autorelease];
  104. [pb setString: nsstr forType:NSStringPboardType];
  105. }
  106. String CocoaCore::getClipboardString() {
  107. }
  108. void CocoaCore::setVideoMode(int xRes, int yRes, bool fullScreen, int aaLevel) {
  109. this->xRes = xRes;
  110. this->yRes = yRes;
  111. this->fullScreen = fullScreen;
  112. this->aaLevel = aaLevel;
  113. renderer->Resize(xRes, yRes);
  114. // CoreServices::getInstance()->getMaterialManager()->reloadProgramsAndTextures();
  115. dispatchEvent(new Event(), EVENT_CORE_RESIZE);
  116. // NSRect visibleFrame = [[NSScreen mainScreen] visibleFrame];
  117. // NSRect frame = NSMakeRect([[glView window] frame].origin.x, [[glView window] frame].origin.y, xRes, yRes);
  118. // frame.origin.x = (visibleFrame.size.width - frame.size.width) * 0.5;
  119. // frame.origin.y = (visibleFrame.size.height - frame.size.height) * (9.0/10.0);
  120. // [[glView window] setFrame: frame display: YES animate: NO];
  121. // if(!fullScreen) {
  122. [[glView window] setContentSize: NSMakeSize(xRes, yRes)];
  123. // } else {
  124. // CGDisplaySwitchToMode (kCGDirectMainDisplay, CGDisplayBestModeForParameters (kCGDirectMainDisplay, 32, xRes, yRes, NULL) );
  125. // }
  126. if(fullScreen) {
  127. CGDisplaySwitchToMode (kCGDirectMainDisplay, CGDisplayBestModeForParameters (kCGDirectMainDisplay, 32, xRes, yRes, NULL) );
  128. [glView enterFullScreenMode:[NSScreen mainScreen] withOptions:[NSDictionary dictionaryWithObjectsAndKeys:
  129. nil]];
  130. }
  131. /*
  132. if(aaLevel > 0) {
  133. glEnable( GL_MULTISAMPLE_ARB );
  134. } else {
  135. glDisable( GL_MULTISAMPLE_ARB );
  136. }
  137. */
  138. }
  139. void CocoaCore::resizeTo(int xRes, int yRes) {
  140. this->xRes = xRes;
  141. this->yRes = yRes;
  142. renderer->Resize(xRes, yRes);
  143. dispatchEvent(new Event(), EVENT_CORE_RESIZE);
  144. }
  145. vector<Polycode::Rectangle> CocoaCore::getVideoModes() {
  146. vector<Polycode::Rectangle> retVector;
  147. return retVector;
  148. }
  149. CocoaCore::~CocoaCore() {
  150. if(fullScreen) {
  151. [glView exitFullScreenModeWithOptions:nil];
  152. }
  153. [glView clearGLContext];
  154. [context release];
  155. }
  156. void *ManagedThreadFunc(void *data) {
  157. Threaded *target = static_cast<Threaded*>(data);
  158. target->runThread();
  159. return NULL;
  160. }
  161. void CocoaCore::createThread(Threaded *target) {
  162. pthread_t thread;
  163. pthread_create( &thread, NULL, ManagedThreadFunc, (void*)target);
  164. }
  165. void CocoaCore::lockMutex(CoreMutex *mutex) {
  166. PosixMutex *m = (PosixMutex*) mutex;
  167. pthread_mutex_lock(&m->pMutex);
  168. }
  169. void CocoaCore::unlockMutex(CoreMutex *mutex) {
  170. PosixMutex *m = (PosixMutex*) mutex;
  171. pthread_mutex_unlock(&m->pMutex);
  172. }
  173. CoreMutex *CocoaCore::createMutex() {
  174. PosixMutex *mutex = new PosixMutex();
  175. pthread_mutex_init(&mutex->pMutex, NULL);
  176. return mutex;
  177. }
  178. unsigned int CocoaCore::getTicks() {
  179. uint64_t time = mach_absolute_time();
  180. double conversion = 0.0;
  181. mach_timebase_info_data_t info;
  182. mach_timebase_info( &info );
  183. conversion = 1e-9 * (double) info.numer / (double) info.denom;
  184. return (((double)(time - initTime)) * conversion) * 1000.0f;
  185. }
  186. void CocoaCore::enableMouse(bool newval) {
  187. if(newval)
  188. CGDisplayShowCursor(kCGDirectMainDisplay);
  189. else
  190. CGDisplayHideCursor(kCGDirectMainDisplay);
  191. Core::enableMouse(newval);
  192. }
  193. void CocoaCore::setCursor(int cursorType) {
  194. NSCursor *newCursor;
  195. switch(cursorType) {
  196. case CURSOR_TEXT:
  197. newCursor = [NSCursor IBeamCursor];
  198. break;
  199. case CURSOR_POINTER:
  200. newCursor = [NSCursor pointingHandCursor];
  201. break;
  202. case CURSOR_CROSSHAIR:
  203. newCursor = [NSCursor crosshairCursor];
  204. break;
  205. case CURSOR_RESIZE_LEFT_RIGHT:
  206. newCursor = [NSCursor resizeLeftRightCursor];
  207. break;
  208. case CURSOR_RESIZE_UP_DOWN:
  209. newCursor = [NSCursor resizeUpDownCursor];
  210. break;
  211. default:
  212. newCursor = [NSCursor arrowCursor];
  213. break;
  214. }
  215. [glView setCurrentCursor:newCursor];
  216. [glView resetCursorRects];
  217. [[glView window] invalidateCursorRectsForView: glView];
  218. }
  219. void CocoaCore::checkEvents() {
  220. lockMutex(eventMutex);
  221. CocoaEvent event;
  222. for(int i=0; i < cocoaEvents.size(); i++) {
  223. event = cocoaEvents[i];
  224. switch(event.eventGroup) {
  225. case CocoaEvent::INPUT_EVENT:
  226. switch(event.eventCode) {
  227. case InputEvent::EVENT_MOUSEMOVE:
  228. input->setDeltaPosition(lastMouseX - event.mouseX, lastMouseY - event.mouseY);
  229. lastMouseX = event.mouseX;
  230. lastMouseY = event.mouseY;
  231. input->setMousePosition(event.mouseX, event.mouseY, getTicks());
  232. break;
  233. case InputEvent::EVENT_MOUSEDOWN:
  234. input->setMouseButtonState(event.mouseButton, true, getTicks());
  235. break;
  236. case InputEvent::EVENT_MOUSEWHEEL_UP:
  237. input->mouseWheelUp(getTicks());
  238. break;
  239. case InputEvent::EVENT_MOUSEWHEEL_DOWN:
  240. input->mouseWheelDown(getTicks());
  241. break;
  242. case InputEvent::EVENT_MOUSEUP:
  243. input->setMouseButtonState(event.mouseButton, false, getTicks());
  244. break;
  245. case InputEvent::EVENT_KEYDOWN:
  246. input->setKeyState(event.keyCode, event.unicodeChar, true, getTicks());
  247. break;
  248. case InputEvent::EVENT_KEYUP:
  249. input->setKeyState(event.keyCode, event.unicodeChar, false, getTicks());
  250. break;
  251. }
  252. break;
  253. }
  254. }
  255. cocoaEvents.clear();
  256. unlockMutex(eventMutex);
  257. }
  258. void CocoaCore::createFolder(String folderPath) {
  259. [[NSFileManager defaultManager] createDirectoryAtPath:[NSString stringWithUTF8String: folderPath.c_str()] withIntermediateDirectories:YES attributes:nil error:nil];
  260. }
  261. void CocoaCore::copyDiskItem(String itemPath, String destItemPath) {
  262. [[NSFileManager defaultManager] copyItemAtPath: [NSString stringWithUTF8String: itemPath.c_str()] toPath: [NSString stringWithUTF8String: destItemPath.c_str()] error: nil];
  263. }
  264. void CocoaCore::moveDiskItem(String itemPath, String destItemPath) {
  265. [[NSFileManager defaultManager] moveItemAtPath: [NSString stringWithUTF8String: itemPath.c_str()] toPath: [NSString stringWithUTF8String: destItemPath.c_str()] error: nil];
  266. }
  267. void CocoaCore::removeDiskItem(String itemPath) {
  268. [[NSFileManager defaultManager] removeItemAtPath: [NSString stringWithUTF8String: itemPath.c_str()] error:nil];
  269. }
  270. String CocoaCore::openFolderPicker() {
  271. NSOpenPanel *attachmentPanel = [NSOpenPanel openPanel];
  272. [attachmentPanel setCanChooseFiles:NO];
  273. [attachmentPanel setCanCreateDirectories: YES];
  274. [attachmentPanel setCanChooseDirectories:YES];
  275. if ( [attachmentPanel runModalForDirectory:nil file:nil] == NSOKButton )
  276. {
  277. // files and directories selected.
  278. NSArray* files = [attachmentPanel filenames];
  279. NSString* fileName = [files objectAtIndex:0];
  280. return [fileName UTF8String];
  281. } else {
  282. return [@"" UTF8String];
  283. }
  284. }
  285. vector<string> CocoaCore::openFilePicker(vector<CoreFileExtension> extensions, bool allowMultiple) {
  286. vector<string> retVector;
  287. NSOpenPanel *attachmentPanel = [NSOpenPanel openPanel];
  288. [attachmentPanel setCanChooseFiles:YES];
  289. [attachmentPanel setCanCreateDirectories: YES];
  290. [attachmentPanel setCanChooseDirectories:NO];
  291. [attachmentPanel setAllowsMultipleSelection: allowMultiple];
  292. NSMutableArray *types = [[NSMutableArray alloc] init];
  293. for(int i=0; i < extensions.size(); i++) {
  294. CoreFileExtension extInfo = extensions[i];
  295. [types addObject: [NSString stringWithUTF8String: extInfo.extension.c_str()]];
  296. }
  297. if ( [attachmentPanel runModalForDirectory:nil file:nil types:types] == NSOKButton )
  298. {
  299. NSArray* files = [attachmentPanel filenames];
  300. NSString* fileName = [files objectAtIndex:0];
  301. retVector.push_back([fileName UTF8String]);
  302. } else {
  303. retVector.push_back("");
  304. }
  305. return retVector;
  306. }
  307. bool CocoaCore::Update() {
  308. if(!running)
  309. return false;
  310. lockMutex(CoreServices::getRenderMutex());
  311. checkEvents();
  312. renderer->BeginRender();
  313. updateCore();
  314. renderer->EndRender();
  315. [context flushBuffer];
  316. unlockMutex(CoreServices::getRenderMutex());
  317. doSleep();
  318. return running;
  319. }