Changed: #947 showCursor, setMousePos, improved window move, useOptimizedDrawing:YES, cleaned up comments

This commit is contained in:
rti 2010-06-09 23:15:14 +02:00
parent b9e7923226
commit cfecd694b9
7 changed files with 145 additions and 28 deletions

View file

@ -1006,8 +1006,8 @@ bool CDriverGL::release()
}
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
# warning "OpenGL Driver: Missing Mac Implementation"
nlwarning("OpenGL Driver: Missing Mac Implementation");
NL3D::MAC::release();
#elif defined (NL_OS_UNIX)
if(_FullScreen)

View file

@ -1288,8 +1288,8 @@ void CDriverGL::showCursor(bool b)
;
}
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
# warning "OpenGL Driver: Missing Mac Implementation"
nlwarning("OpenGL Driver: Missing Mac Implementation");
NL3D::MAC::showCursor(b);
#elif defined (NL_OS_UNIX)
@ -1335,8 +1335,8 @@ void CDriverGL::setMousePos(float x, float y)
SetCursorPos(pt.x, pt.y);
}
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
# warning "OpenGL Driver: Missing Mac Implementation"
nlwarning("OpenGL Driver: Missing Mac Implementation");
NL3D::MAC::setMousePos(x, y);
#elif defined (NL_OS_UNIX)
XWindowAttributes xwa;
@ -1459,8 +1459,8 @@ void CDriverGL::setCapture (bool b)
*/
#elif defined(NL_OS_MAC) && defined(NL_MAC_NATIVE)
# warning "OpenGL Driver: Missing Mac Implementation"
nlwarning("OpenGL Driver: Missing Mac Implementation");
NL3D::MAC::setCapture(b);
#elif defined (NL_OS_UNIX)

View file

@ -73,6 +73,18 @@ void setWindowTitle(const ucstring &title);
/// mac specific stuff while calling CDriverGL::swapBuffers()
void swapBuffers();
/// mac specific stuff while calling CDriverGL::setCapture()
void setCapture(bool b);
/// mac specific stuff while calling CDriverGL::showCursor()
void showCursor(bool b);
/// mac specific stuff while calling CDriverGL::setMousePos()
void setMousePos(float x, float y);
/// mac specific stuff while calling CDriverGL::release()
void release();
/// mac specific stuff while calling CCocoaEventEmitter::submitEvents()
void submitEvents(NLMISC::CEventServer& server,
bool allWindows, NLMISC::CCocoaEventEmitter* eventEmitter);

View file

@ -74,6 +74,10 @@ bool init(uint windowIcon, emptyProc exitFunc)
bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable)
{
/*
TODO use show and resizable flags
*/
// create a cocoa window with the size provided by the mode parameter
g_window = [[CocoaWindow alloc]
initWithContentRect:NSMakeRect(0, 0, mode.Width, mode.Height)
@ -126,6 +130,9 @@ bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable)
// enable mouse move events, NeL wants them
[g_window setAcceptsMouseMovedEvents:YES];
// there are no overlapping subview, so we can use the magical optimization!
[g_window useOptimizedDrawing:YES];
// create a opengl context for the view
g_glctx = [g_glview openGLContext];
@ -138,6 +145,9 @@ bool setDisplay(nlWindow wnd, const GfxMode& mode, bool show, bool resizeable)
// put the window to the front and make it the key window
[g_window makeKeyAndOrderFront:nil];
// this is our main window
[g_window makeMainWindow];
// tell the application that we are running now
[g_app finishLaunching];
@ -168,11 +178,11 @@ bool setMode(const GfxMode& mode)
// leave fullscreen mode, enter windowed mode
if(mode.Windowed && [g_glview isInFullScreenMode])
{
// pull the view back from fullscreen restoring windows options
// pull the view back from fullscreen restoring window options
[g_glview exitFullScreenModeWithOptions:nil];
// disable manual setting of back buffer size, cocoa handles this
// automatically as soon as the window gets resized
// automatically as soon as the view gets resized
CGLError error = CGLDisable((CGLContextObj)[g_glctx CGLContextObj],
kCGLCESurfaceBackingSize);
@ -197,7 +207,7 @@ bool setMode(const GfxMode& mode)
// NOTE: withOptions:nil disables <CMD>+<Tab> application switching!
/*
TODO check if simply using NSView enterFullScreenMode is a good idea.
the context can be set to full screen as well? performance differences?
the context can be set to full screen as well, performance differences?
*/
[g_glview enterFullScreenMode:[NSScreen mainScreen] withOptions:
[NSDictionary dictionaryWithObjectsAndKeys:
@ -207,8 +217,8 @@ bool setMode(const GfxMode& mode)
NSFullScreenModeApplicationPresentationOptions, nil]];
}
#ifdef UGLY_BACKBUFFER_SIZE_WORKAROUND
// due to the back buffer size reading problem, just store the size
g_bufferSize[0] = mode.Width;
g_bufferSize[1] = mode.Height;
#endif
@ -226,11 +236,9 @@ void getWindowSize(uint32 &width, uint32 &height)
// changed, but the view still stays at full resolution. So the scaling of
// the image from the rendered resolution to the view's resolution is done
// by cocoa automatically while flushing buffers.
// That's why, in fullscreen mode, return the resolution from the back buffer,
// That's why, in fullscreen mode, return the resolution of the back buffer,
// not the one from the window.
// check if manual back buffer sizing is enabled (thats only in fullscreen)
#ifdef UGLY_BACKBUFFER_SIZE_WORKAROUND
if([g_glview isInFullScreenMode])
{
@ -244,10 +252,10 @@ void getWindowSize(uint32 &width, uint32 &height)
height = rect.size.height;
}
#else
/*
TODO does not work atm, "invalid enumeration"
*/
// check if manual back buffer sizing is enabled (thats only in fullscreen)
GLint surfaceBackingSizeSet = 0;
CGLError error = CGLIsEnabled((CGLContextObj)[g_glctx CGLContextObj],
kCGLCESurfaceBackingSize, &surfaceBackingSizeSet);
@ -291,10 +299,10 @@ void getWindowSize(uint32 &width, uint32 &height)
void getWindowPos(uint32 &x, uint32 &y)
{
// get the size of the screen
// get the rect (position, size) of the screen
NSRect screenRect = [[g_window screen] frame];
// get the size of the window
// get the rect (position, size) of the window
NSRect windowRect = [g_window frame];
// simply return x
@ -331,6 +339,92 @@ void swapBuffers()
[g_glctx flushBuffer];
}
void setCapture(bool b)
{
/*
TODO implement capture cursor, no need to fake using pull back to 0.5 / 0.5
set a flag and then act accordingly in event loop?
// no screen bounds...
void CGGetLastMouseDelta(CGMouseDelta* deltaX, CGMouseDelta* deltaY);
*/
nlwarning("not implemented");
}
void showCursor(bool b)
{
// Mac OS manages a show/hide counter for the cursor, so hiding the cursor
// twice requires two calls to show to make the cursor visible again.
// Since other platforms seem to not do this, the functionality is masked here
// by only calling hide if the cursor is visible and only calling show if
// the cursor was hidden.
CGDisplayErr error = kCGErrorSuccess;
static bool visible = true;
if(b && !visible)
{
error = CGDisplayShowCursor(kCGDirectMainDisplay);
visible = true;
}
else if(!b && visible)
{
error = CGDisplayHideCursor(kCGDirectMainDisplay);
visible = false;
}
if(error != kCGErrorSuccess)
nlerror("cannot get capture / un-capture cursor");
}
void setMousePos(float x, float y)
{
// CG wants absolute coordinates related to screen top left
CGFloat fromScreenLeft = 0.0;
CGFloat fromScreenTop = 0.0;
// get the gl view's rect for height and width
NSRect viewRect = [g_glview frame];
// if the view is not fullscreen, window top left is needed as offset
if(![g_glview isInFullScreenMode])
{
// get the rect (position, size) of the screen
NSRect screenRect = [[g_window screen] frame];
// get the rect (position, size) of the window
NSRect windowRect = [g_window frame];
// window's x is ok
fromScreenLeft = windowRect.origin.x;
// TODO this code assumes, that the view fills the window
// map window bottom to view top
fromScreenTop = screenRect.size.height -
viewRect.size.height - windowRect.origin.y;
}
// position inside the view
fromScreenLeft += (viewRect.size.width * x);
fromScreenTop += (viewRect.size.height * (1 - y));
// actually set the mouse position
CGDisplayErr error = CGDisplayMoveCursorToPoint(
kCGDirectMainDisplay, CGPointMake(fromScreenLeft, fromScreenTop));
if(error != kCGErrorSuccess)
nlerror("cannot set mouse position");
}
void release()
{
/*
TODO release some stuff
*/
nlwarning("not implemented");
}
/*
TODO: this function has to be moved to a more central place to handle key
mapping on mac x11 as well
@ -552,10 +646,19 @@ void submitEvents(NLMISC::CEventServer& server,
// get the views size
NSRect rect = [g_glview frame];
// TODO this code assumes, that the view fills the window
// convert the mouse position to NeL style (relative)
float mouseX = event.locationInWindow.x / (float)rect.size.width;
float mouseY = event.locationInWindow.y / (float)rect.size.height;
// if the mouse event was placed on the window's titlebar, ignore it
if(mouseY > 1.0 && event.type != NSKeyDown && event.type != NSKeyUp)
{
[g_app sendEvent:event];
[g_app updateWindows];
continue;
}
switch(event.type)
{
case NSLeftMouseDown:
@ -597,6 +700,8 @@ void submitEvents(NLMISC::CEventServer& server,
/*
TODO modifiers with mouse events
*/
// nldebug("mouse left drag %f %f", mouseX, mouseY);
server.postEvent(new NLMISC::CEventMouseMove(
mouseX, mouseY, NLMISC::leftButton /* modifiers */, eventEmitter));
break;

View file

@ -35,6 +35,7 @@
[characterStorage release];
[super dealloc];
}
-(BOOL)acceptsFirstResponder
{
return YES;

View file

@ -66,7 +66,7 @@ bool SetMousePosFirstTime = true;
uint DownMouseButtons = 0;
#ifdef NL_OS_UNIX
// on X11, store whether the mouse was captured or not
// on X11 and cocoa, store whether the mouse was captured or not
bool MouseCapture = false;
#endif
@ -251,8 +251,8 @@ void SetMouseFreeLook ()
}
#ifdef NL_OS_UNIX
// on X11 the mouse needs to get pulled into the middle each update, else
// the cursor would reach the border of the window / desktop
// on X11 and cocoa the mouse needs to get pulled into the middle each update,
// else the cursor would reach the border of the window / desktop
// and freelook would hang
Driver->setMousePos(0.5f, 0.5f);
#endif
@ -373,7 +373,7 @@ void CaptureSystemCursor()
if (!drvWnd) return;
SetCapture(drvWnd);
#else
// on X11, set driver mouse capture on and store it locally as well
// on X11 and cocoa, set driver mouse capture on and store it locally as well
Driver->setCapture(MouseCapture = true);
#endif
}
@ -392,7 +392,7 @@ void ReleaseSystemCursor()
}
ReleaseCapture();
#else
// on X11, set driver mouse capture off and store it locally as well
// on X11 and cocoa, set driver mouse capture off and store it locally as well
Driver->setCapture(MouseCapture = false);
#endif
}

View file

@ -458,25 +458,24 @@ void CUserControls::getMouseAngleMove(float &dx, float &dy)
{
float dmpx, dmpy;
#ifndef NL_MAC_NATIVE
// On X11 in free look mode, the mouse is pulled back to (0.5, 0.5)
// On X11 and Cocoa in free look mode, the mouse is pulled back to (0.5, 0.5)
// every update to prevent reaching a border and get stuck.
if(IsMouseFreeLook())
{
/*
TODO use setCapture to not fake it
TODO on X11, use setCapture to not fake it, capture on mac?
*/
dmpx = EventsListener.getMousePosX() - 0.5;
dmpy = EventsListener.getMousePosY() - 0.5;
}
else
#endif
{
dmpx = EventsListener.getMousePosX() - _LastFrameMousePosX;
dmpy = EventsListener.getMousePosY() - _LastFrameMousePosY;
}
// TODO: read desktop mouse speed value on X11 / implement X11MouseDevice
// TODO: read desktop mouse speed value on X11 and Cocoa
// implement X11MouseDevice/CocoaMouseDevice?
dmpx *= 450.0f;
dmpy *= 450.0f;