| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421 |
- /*
- Copyright (C) 2011 by Ivan Safrin
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- */
- #include "PolyCocoaCore.h"
- #include <iostream>
- using namespace Polycode;
- long getThreadID() {
- return (long)pthread_self();
- }
- CocoaCore::CocoaCore(PolycodeView *view, int xRes, int yRes, bool fullScreen,int aaLevel, int frameRate) : Core(xRes, yRes, fullScreen,aaLevel, frameRate) {
- eventMutex = createMutex();
-
- // NSLog(@"BUNDLE: %@", [[NSBundle mainBundle] bundlePath]);
- chdir([[[NSBundle mainBundle] bundlePath] UTF8String]);
-
- NSOpenGLPixelFormatAttribute attrs[32];
-
- int atindx = 0;
- attrs[atindx++] = NSOpenGLPFADoubleBuffer;
-
- attrs[atindx++] = NSOpenGLPFADepthSize;
- attrs[atindx++] = 32;
-
- if(aaLevel > 0) {
- attrs[atindx++] = NSOpenGLPFASampleBuffers;
- attrs[atindx++] = 1;
-
- attrs[atindx++] = NSOpenGLPFASamples;
- attrs[atindx++] = aaLevel;
-
- attrs[atindx++] = NSOpenGLPFAMultisample;
- }
-
- attrs[atindx++] = NSOpenGLPFANoRecovery;
- if(fullScreen) {
-
- // attrs[atindx++] = NSOpenGLPFAFullScreen;
- // attrs[atindx++] = NSOpenGLPFAScreenMask;
- // attrs[atindx++] = CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay);
-
- }
-
- attrs[atindx++] = NSOpenGLPFAAccelerated;
-
-
- attrs[atindx++] = nil;
- /*
- NSOpenGLPixelFormatAttribute attrs[] =
- {
- NSOpenGLPFADoubleBuffer,
- NSOpenGLPFADepthSize, 16,
- // NSOpenGLPFAFullScreen,
- // NSOpenGLPFAScreenMask,
- // CGDisplayIDToOpenGLDisplayMask(kCGDirectMainDisplay),
- NSOpenGLPFASampleBuffers, 1,
- NSOpenGLPFASamples, aaLevel,
- NSOpenGLPFANoRecovery,
- // NSOpenGLPFAWindow,
- NSOpenGLPFAMultisample,
- // NSOpenGLPFAAccelerated,
- // NSOpenGLPFAAccumSize, 0,
- nil
- };
- */
- // [view lockContext];
-
- [view setCore:this];
- NSOpenGLPixelFormat *format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
-
- if(!format) {
- NSLog(@"Error creating pixel format!\n");
- }
-
- context = [[NSOpenGLContext alloc] initWithFormat: format shareContext:nil];
- if (context == nil) {
- NSLog(@"Failed to create open gl context");
- }
-
- if(false) {
- // [view enterFullScreenMode:[NSScreen mainScreen] withOptions:0];
- // [view removeFromSuperview];
- // [[view window] orderOut:nil];
-
- // CGDisplayCapture (kCGDirectMainDisplay ) ;
- // CGDisplaySwitchToMode (kCGDirectMainDisplay, CGDisplayBestModeForParameters (kCGDirectMainDisplay, 32, xRes, yRes, NULL) );
-
-
- // [context makeCurrentContext];
- // [context setFullScreen];
- // [context flushBuffer];
- // CGDisplayCapture (kCGDirectMainDisplay ) ;
-
- // [context clearDrawable];
- // [context release];
- } else {
- [view clearGLContext];
- [view setOpenGLContext:context];
- [context setView: view];
- }
-
- if(fullScreen) {
- // [view enterFullScreenMode:[NSScreen mainScreen] withOptions:0];
- }
-
-
- glView = view;
-
- initTime = mach_absolute_time();
-
- // while(![view isContextReady]) {
-
- // }
-
- renderer = new OpenGLRenderer();
- services->setRenderer(renderer);
- //[view unlockContext];
- setVideoMode(xRes,yRes,fullScreen,aaLevel);
- }
- void CocoaCore::copyStringToClipboard(String str) {
- NSPasteboard *pb = [NSPasteboard generalPasteboard];
- NSArray *types = [NSArray arrayWithObjects:NSStringPboardType, nil];
- [pb declareTypes:types owner:glView];
-
- //NSString *nsstr = [NSString stringWithCharacters: (unichar*) str.c_str() length: str.length()];
-
- char* data = (char*)str.data();
- unsigned size = str.size() * sizeof(wchar_t);
-
- NSString* nsstr = [[[NSString alloc] initWithBytes:data length:size encoding:NSUTF32LittleEndianStringEncoding] autorelease];
- [pb setString: nsstr forType:NSStringPboardType];
- }
- String CocoaCore::getClipboardString() {
-
- }
- void CocoaCore::setVideoMode(int xRes, int yRes, bool fullScreen, int aaLevel) {
- this->xRes = xRes;
- this->yRes = yRes;
- this->fullScreen = fullScreen;
- this->aaLevel = aaLevel;
-
- renderer->Resize(xRes, yRes);
- // CoreServices::getInstance()->getMaterialManager()->reloadProgramsAndTextures();
- dispatchEvent(new Event(), EVENT_CORE_RESIZE);
-
- // NSRect visibleFrame = [[NSScreen mainScreen] visibleFrame];
- // NSRect frame = NSMakeRect([[glView window] frame].origin.x, [[glView window] frame].origin.y, xRes, yRes);
-
- // frame.origin.x = (visibleFrame.size.width - frame.size.width) * 0.5;
- // frame.origin.y = (visibleFrame.size.height - frame.size.height) * (9.0/10.0);
-
- // [[glView window] setFrame: frame display: YES animate: NO];
- // if(!fullScreen) {
- [[glView window] setContentSize: NSMakeSize(xRes, yRes)];
- // } else {
- // CGDisplaySwitchToMode (kCGDirectMainDisplay, CGDisplayBestModeForParameters (kCGDirectMainDisplay, 32, xRes, yRes, NULL) );
- // }
- if(fullScreen) {
- CGDisplaySwitchToMode (kCGDirectMainDisplay, CGDisplayBestModeForParameters (kCGDirectMainDisplay, 32, xRes, yRes, NULL) );
- [glView enterFullScreenMode:[NSScreen mainScreen] withOptions:[NSDictionary dictionaryWithObjectsAndKeys:
- nil]];
-
- }
-
- /*
- if(aaLevel > 0) {
- glEnable( GL_MULTISAMPLE_ARB );
- } else {
- glDisable( GL_MULTISAMPLE_ARB );
- }
- */
- }
- void CocoaCore::resizeTo(int xRes, int yRes) {
- this->xRes = xRes;
- this->yRes = yRes;
- renderer->Resize(xRes, yRes);
- dispatchEvent(new Event(), EVENT_CORE_RESIZE);
- }
- vector<Polycode::Rectangle> CocoaCore::getVideoModes() {
- vector<Polycode::Rectangle> retVector;
- return retVector;
- }
- CocoaCore::~CocoaCore() {
-
- if(fullScreen) {
- [glView exitFullScreenModeWithOptions:nil];
-
- }
-
- [glView clearGLContext];
- [context release];
- }
- void *ManagedThreadFunc(void *data) {
- Threaded *target = static_cast<Threaded*>(data);
- target->runThread();
- return NULL;
- }
- void CocoaCore::createThread(Threaded *target) {
- pthread_t thread;
- pthread_create( &thread, NULL, ManagedThreadFunc, (void*)target);
- }
- void CocoaCore::lockMutex(CoreMutex *mutex) {
- PosixMutex *m = (PosixMutex*) mutex;
- pthread_mutex_lock(&m->pMutex);
- }
- void CocoaCore::unlockMutex(CoreMutex *mutex) {
- PosixMutex *m = (PosixMutex*) mutex;
- pthread_mutex_unlock(&m->pMutex);
- }
- CoreMutex *CocoaCore::createMutex() {
- PosixMutex *mutex = new PosixMutex();
- pthread_mutex_init(&mutex->pMutex, NULL);
- return mutex;
- }
- unsigned int CocoaCore::getTicks() {
- uint64_t time = mach_absolute_time();
- double conversion = 0.0;
-
- mach_timebase_info_data_t info;
- mach_timebase_info( &info );
- conversion = 1e-9 * (double) info.numer / (double) info.denom;
-
- return (((double)(time - initTime)) * conversion) * 1000.0f;
- }
- void CocoaCore::enableMouse(bool newval) {
-
- if(newval)
- CGDisplayShowCursor(kCGDirectMainDisplay);
- else
- CGDisplayHideCursor(kCGDirectMainDisplay);
- Core::enableMouse(newval);
- }
- void CocoaCore::setCursor(int cursorType) {
-
- NSCursor *newCursor;
-
- switch(cursorType) {
- case CURSOR_TEXT:
- newCursor = [NSCursor IBeamCursor];
- break;
- case CURSOR_POINTER:
- newCursor = [NSCursor pointingHandCursor];
- break;
- case CURSOR_CROSSHAIR:
- newCursor = [NSCursor crosshairCursor];
- break;
- case CURSOR_RESIZE_LEFT_RIGHT:
- newCursor = [NSCursor resizeLeftRightCursor];
- break;
- case CURSOR_RESIZE_UP_DOWN:
- newCursor = [NSCursor resizeUpDownCursor];
- break;
- default:
- newCursor = [NSCursor arrowCursor];
- break;
- }
- [glView setCurrentCursor:newCursor];
- [glView resetCursorRects];
- [[glView window] invalidateCursorRectsForView: glView];
- }
- void CocoaCore::checkEvents() {
- lockMutex(eventMutex);
- CocoaEvent event;
- for(int i=0; i < cocoaEvents.size(); i++) {
- event = cocoaEvents[i];
- switch(event.eventGroup) {
- case CocoaEvent::INPUT_EVENT:
- switch(event.eventCode) {
- case InputEvent::EVENT_MOUSEMOVE:
- input->setDeltaPosition(lastMouseX - event.mouseX, lastMouseY - event.mouseY);
- lastMouseX = event.mouseX;
- lastMouseY = event.mouseY;
- input->setMousePosition(event.mouseX, event.mouseY, getTicks());
- break;
- case InputEvent::EVENT_MOUSEDOWN:
- input->setMouseButtonState(event.mouseButton, true, getTicks());
- break;
- case InputEvent::EVENT_MOUSEWHEEL_UP:
- input->mouseWheelUp(getTicks());
- break;
- case InputEvent::EVENT_MOUSEWHEEL_DOWN:
- input->mouseWheelDown(getTicks());
- break;
- case InputEvent::EVENT_MOUSEUP:
- input->setMouseButtonState(event.mouseButton, false, getTicks());
- break;
- case InputEvent::EVENT_KEYDOWN:
- input->setKeyState(event.keyCode, event.unicodeChar, true, getTicks());
- break;
- case InputEvent::EVENT_KEYUP:
- input->setKeyState(event.keyCode, event.unicodeChar, false, getTicks());
- break;
- }
- break;
- }
- }
- cocoaEvents.clear();
- unlockMutex(eventMutex);
- }
- void CocoaCore::createFolder(String folderPath) {
- [[NSFileManager defaultManager] createDirectoryAtPath:[NSString stringWithUTF8String: folderPath.c_str()] withIntermediateDirectories:YES attributes:nil error:nil];
- }
- void CocoaCore::copyDiskItem(String itemPath, String destItemPath) {
- [[NSFileManager defaultManager] copyItemAtPath: [NSString stringWithUTF8String: itemPath.c_str()] toPath: [NSString stringWithUTF8String: destItemPath.c_str()] error: nil];
- }
- void CocoaCore::moveDiskItem(String itemPath, String destItemPath) {
- [[NSFileManager defaultManager] moveItemAtPath: [NSString stringWithUTF8String: itemPath.c_str()] toPath: [NSString stringWithUTF8String: destItemPath.c_str()] error: nil];
- }
- void CocoaCore::removeDiskItem(String itemPath) {
- [[NSFileManager defaultManager] removeItemAtPath: [NSString stringWithUTF8String: itemPath.c_str()] error:nil];
- }
-
- String CocoaCore::openFolderPicker() {
- NSOpenPanel *attachmentPanel = [NSOpenPanel openPanel];
- [attachmentPanel setCanChooseFiles:NO];
- [attachmentPanel setCanCreateDirectories: YES];
- [attachmentPanel setCanChooseDirectories:YES];
-
- if ( [attachmentPanel runModalForDirectory:nil file:nil] == NSOKButton )
- {
- // files and directories selected.
- NSArray* files = [attachmentPanel filenames];
- NSString* fileName = [files objectAtIndex:0];
- return [fileName UTF8String];
- } else {
- return [@"" UTF8String];
- }
- }
- vector<string> CocoaCore::openFilePicker(vector<CoreFileExtension> extensions, bool allowMultiple) {
-
- vector<string> retVector;
-
- NSOpenPanel *attachmentPanel = [NSOpenPanel openPanel];
- [attachmentPanel setCanChooseFiles:YES];
- [attachmentPanel setCanCreateDirectories: YES];
- [attachmentPanel setCanChooseDirectories:NO];
- [attachmentPanel setAllowsMultipleSelection: allowMultiple];
-
- NSMutableArray *types = [[NSMutableArray alloc] init];
-
- for(int i=0; i < extensions.size(); i++) {
- CoreFileExtension extInfo = extensions[i];
- [types addObject: [NSString stringWithUTF8String: extInfo.extension.c_str()]];
- }
-
- if ( [attachmentPanel runModalForDirectory:nil file:nil types:types] == NSOKButton )
- {
- NSArray* files = [attachmentPanel filenames];
- NSString* fileName = [files objectAtIndex:0];
- retVector.push_back([fileName UTF8String]);
- } else {
- retVector.push_back("");
- }
-
- return retVector;
- }
- bool CocoaCore::Update() {
- if(!running)
- return false;
-
- lockMutex(CoreServices::getRenderMutex());
- checkEvents();
- renderer->BeginRender();
- updateCore();
- renderer->EndRender();
- [context flushBuffer];
- unlockMutex(CoreServices::getRenderMutex());
- doSleep();
- return running;
- }
|