PolyCocoaCore.cpp 9.4 KB

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