diff --git a/GNUmakefile b/GNUmakefile index 95b4b28e3..70969c206 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -1,9 +1,21 @@ include $(GNUSTEP_MAKEFILES)/common.make include config.make -vpath %.m src/SDL:src/Core:src/Core/Entities:src/Core/Materials:src/Core/Scripting:src/Core/OXPVerifier:src/Core/Debug -vpath %.h src/SDL:src/Core:src/Core/Entities:src/Core/Materials:src/Core/Scripting:src/Core/OXPVerifier:src/Core/Debug:src/Core/MiniZip -vpath %.c src/SDL:src/Core:src/BSDCompat:src/Core/Debug:src/Core/MiniZip +ifeq ($(OO_SDL2_ENABLED),yes) + OO_SDL_DIR = src/SDL2 + SDL_CFLAGS = `sdl2-config --cflags` -DOO_ENABLE_SDL2 + SDL_OBJCFLAGS = `sdl2-config --cflags` -DOO_ENABLE_SDL2 + SDL_OBJC_LIBS = -lSDL2main -lSDL2 +else + OO_SDL_DIR = src/SDL + SDL_CFLAGS = `sdl-config --cflags` + SDL_OBJCFLAGS = `sdl-config --cflags` + SDL_OBJC_LIBS = -lSDLmain -lSDL +endif + +vpath %.m $(OO_SDL_DIR):src/Core:src/Core/Entities:src/Core/Materials:src/Core/Scripting:src/Core/OXPVerifier:src/Core/Debug +vpath %.h $(OO_SDL_DIR):src/Core:src/Core/Entities:src/Core/Materials:src/Core/Scripting:src/Core/OXPVerifier:src/Core/Debug:src/Core/MiniZip +vpath %.c $(OO_SDL_DIR):src/Core:src/BSDCompat:src/Core/Debug:src/Core/MiniZip GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_USER_ROOT) ifeq ($(GNUSTEP_HOST_OS),mingw32) GNUSTEP_OBJ_DIR_NAME := $(GNUSTEP_OBJ_DIR_NAME).win @@ -23,11 +35,11 @@ ifeq ($(GNUSTEP_HOST_OS),mingw32) else JS_IMPORT_LIBRARY = js32ECMAv5 endif - ADDITIONAL_INCLUDE_DIRS = -I$(WIN_DEPS_DIR)/include -I$(JS_INC_DIR) -Isrc/SDL -Isrc/Core -Isrc/BSDCompat -Isrc/Core/Scripting -Isrc/Core/Materials -Isrc/Core/Entities -Isrc/Core/OXPVerifier -Isrc/Core/Debug -Isrc/Core/Tables -Isrc/Core/MiniZip - ADDITIONAL_OBJC_LIBS = -lglu32 -lopengl32 -lopenal32.dll -lpng14.dll -lmingw32 -lSDLmain -lSDL -lvorbisfile.dll -lvorbis.dll -lz -lgnustep-base -l$(JS_IMPORT_LIBRARY) -lwinmm -mwindows - ADDITIONAL_CFLAGS = -DWIN32 -DNEED_STRLCPY `sdl-config --cflags` -mtune=generic + ADDITIONAL_INCLUDE_DIRS = -I$(WIN_DEPS_DIR)/include -I$(JS_INC_DIR) -I$(OO_SDL_DIR) -Isrc/Core -Isrc/BSDCompat -Isrc/Core/Scripting -Isrc/Core/Materials -Isrc/Core/Entities -Isrc/Core/OXPVerifier -Isrc/Core/Debug -Isrc/Core/Tables -Isrc/Core/MiniZip + ADDITIONAL_OBJC_LIBS = -lglu32 -lopengl32 -lopenal32.dll -lpng14.dll -lmingw32 $(SDL_OBJC_LIBS) -lvorbisfile.dll -lvorbis.dll -lz -lgnustep-base -l$(JS_IMPORT_LIBRARY) -lwinmm -mwindows + ADDITIONAL_CFLAGS = -DWIN32 -DNEED_STRLCPY $(SDL_CFLAGS) -mtune=generic # note the vpath stuff above isn't working for me, so adding src/SDL and src/Core explicitly - ADDITIONAL_OBJCFLAGS = -DLOADSAVEGUI -DWIN32 -DXP_WIN -Wno-import -std=gnu99 `sdl-config --cflags` -mtune=generic + ADDITIONAL_OBJCFLAGS = -DLOADSAVEGUI -DWIN32 -DXP_WIN -Wno-import -std=gnu99 $(SDL_OBJCFLAGS) -mtune=generic ifneq ($(GNUSTEP_HOST_CPU),x86_64) ADDITIONAL_LDFLAGS += -Wl,--large-address-aware else @@ -49,10 +61,10 @@ else LIBJS_LIB_DIR = $(LIBJS_ROOT)/dist/lib LIBJS = js_static - ADDITIONAL_INCLUDE_DIRS = -I$(LIBJS_INC_DIR) -Isrc/SDL -Isrc/Core -Isrc/BSDCompat -Isrc/Core/Scripting -Isrc/Core/Materials -Isrc/Core/Entities -Isrc/Core/OXPVerifier -Isrc/Core/Debug -Isrc/Core/Tables -Isrc/Core/MiniZip - ADDITIONAL_OBJC_LIBS = -lGLU -lGL -lX11 -lSDL -lgnustep-base -l$(LIBJS) `nspr-config --libs` -lstdc++ -lopenal -lz -lvorbisfile - ADDITIONAL_CFLAGS = -Wall -DLINUX -DNEED_STRLCPY `sdl-config --cflags` `nspr-config --cflags` - ADDITIONAL_OBJCFLAGS = -Wall -std=gnu99 -DLOADSAVEGUI -DLINUX -DXP_UNIX -Wno-import `sdl-config --cflags` `nspr-config --cflags` + ADDITIONAL_INCLUDE_DIRS = -I$(LIBJS_INC_DIR) -I$(OO_SDL_DIR) -Isrc/Core -Isrc/BSDCompat -Isrc/Core/Scripting -Isrc/Core/Materials -Isrc/Core/Entities -Isrc/Core/OXPVerifier -Isrc/Core/Debug -Isrc/Core/Tables -Isrc/Core/MiniZip + ADDITIONAL_OBJC_LIBS = -lGLU -lGL -lX11 $(SDL_OBJC_LIBS) -lgnustep-base -l$(LIBJS) `nspr-config --libs` -lstdc++ -lopenal -lz -lvorbisfile + ADDITIONAL_CFLAGS = -Wall -DLINUX -DNEED_STRLCPY $(SDL_CFLAGS) `nspr-config --cflags` + ADDITIONAL_OBJCFLAGS = -Wall -std=gnu99 -DLOADSAVEGUI -DLINUX -DXP_UNIX -Wno-import $(SDL_OBJCFLAGS) `nspr-config --cflags` oolite_LIB_DIRS += -L$(LIBJS_LIB_DIR) -L/usr/X11R6/lib/ ifeq ($(use_deps),yes) diff --git a/config.make b/config.make index 297e7c3df..9d17c73c8 100644 --- a/config.make +++ b/config.make @@ -22,3 +22,4 @@ OO_LOCALIZATION_TOOLS = yes DEBUG_GRAPHVIZ = yes OO_JAVASCRIPT_TRACE = yes OO_FOV_INFLIGHT_CONTROL_ENABLED = no +OO_SDL2_ENABLED = no diff --git a/src/Core/OOJoystickManager.h b/src/Core/OOJoystickManager.h index 530783ed4..71cf285c5 100644 --- a/src/Core/OOJoystickManager.h +++ b/src/Core/OOJoystickManager.h @@ -151,7 +151,6 @@ enum { //SDL Abstracted constants #if OOLITE_SDL - #import enum diff --git a/src/Core/OOOpenGLOnly.h b/src/Core/OOOpenGLOnly.h index 367b4fbc7..f7f77fc50 100644 --- a/src/Core/OOOpenGLOnly.h +++ b/src/Core/OOOpenGLOnly.h @@ -57,6 +57,10 @@ MA 02110-1301, USA. // the standard SDL_opengl.h #include +#if OO_ENABLE_SDL2 +#include +#endif + // include an up-to-date version of glext.h #include diff --git a/src/SDL2/MyOpenGLView.h b/src/SDL2/MyOpenGLView.h index ecfb6dadd..19f1918ad 100644 --- a/src/SDL2/MyOpenGLView.h +++ b/src/SDL2/MyOpenGLView.h @@ -166,7 +166,8 @@ extern int debug; // Windowed mode NSSize currentWindowSize; - SDL_Surface *surface; + SDL_Window *mainWindow; + SDL_GLContext *glContext; BOOL showSplashScreen; @@ -176,7 +177,7 @@ extern int debug; BOOL updateContext; BOOL saveSize; unsigned keyboardMap; - HWND SDL_Window; + HWND Main_Window; MONITORINFOEX monitorInfo; RECT lastGoodRect; diff --git a/src/SDL2/MyOpenGLView.m b/src/SDL2/MyOpenGLView.m index e7933155e..39d784804 100644 --- a/src/SDL2/MyOpenGLView.m +++ b/src/SDL2/MyOpenGLView.m @@ -58,17 +58,18 @@ + (NSMutableDictionary *) getNativeSize int nativeDisplayHeight = 768; #if OOLITE_LINUX - SDL_SysWMinfo dpyInfo; - SDL_VERSION(&dpyInfo.version); - if(SDL_GetWMInfo(&dpyInfo)) - { - nativeDisplayWidth = DisplayWidth(dpyInfo.info.x11.display, 0); - nativeDisplayHeight = DisplayHeight(dpyInfo.info.x11.display, 0); - OOLog(@"display.mode.list.native", @"X11 native resolution detected: %d x %d", nativeDisplayWidth, nativeDisplayHeight); - } - else - { - OOLog(@"display.mode.list.native.failed", @"%@", @"SDL_GetWMInfo failed, defaulting to 1024x768 for native size"); + SDL_DisplayMode dpyMode; + // This gets the native resolution of the primary display, there may be SDL_GetNumVideoDisplays() + // (TODO?) Support multiple outputs + if(SDL_GetDesktopDisplayMode(0, &dpyMode) == 0) + { + nativeDisplayWidth = dpyMode.w; + nativeDisplayHeight = dpyMode.h; + OOLog(@"display.mode.list.native", @"Native resolution detected: %d x %d", nativeDisplayWidth, nativeDisplayHeight); + } + else + { + OOLog(@"display.mode.list.native.failed", @"%@", @"SDL_GetDesktopDisplayMode failed, defaulting to 1024x768 for native size"); } #elif OOLITE_WINDOWS nativeDisplayWidth = GetSystemMetrics(SM_CXSCREEN); @@ -87,8 +88,15 @@ + (NSMutableDictionary *) getNativeSize - (void) createSurface { - // Changing these flags can trigger texture bugs. - const int videoModeFlags = SDL_HWSURFACE | SDL_OPENGL | SDL_RESIZABLE; + + if (glContext == NULL) + glContext = SDL_GL_CreateContext(mainWindow); + if (glContext == NULL) + { + // we should have a valid GL context, but in case we don't + OOLogERR(@"display.mode.error",@"Unable to create GL context: %s",SDL_GetError()); + return; + } if (showSplashScreen) { @@ -98,17 +106,11 @@ - (void) createSurface ShowWindow(SDL_Window,SW_SHOWMINIMIZED); updateContext = NO; //don't update the (splash screen) window yet! - // Initialise the SDL surface. (need custom SDL.dll) - surface = SDL_SetVideoMode(firstScreen.width, firstScreen.height, 32, videoModeFlags); + // Resize the SDL surface? + //SDL_SetWindowSize(mainWindow, (int)firstScreen.width, (int)firstScreen.height); // Post setVideoMode adjustments. currentWindowSize=tmp; -#else - // Changing the flags can trigger texture bugs. - surface = SDL_SetVideoMode(8, 8, 32, videoModeFlags); - if (!surface) { - return; - } #endif } else @@ -116,24 +118,22 @@ - (void) createSurface #if OOLITE_WINDOWS updateContext = YES; #endif - surface = SDL_SetVideoMode(firstScreen.width, firstScreen.height, 32, videoModeFlags); - if (!surface) { - return; - } - // blank the surface / go to fullscreen + // blank the output / go to fullscreen [self initialiseGLWithSize: firstScreen]; } + Uint16* gamma_ramp = (Uint16 *)SDL_malloc(256 * sizeof(Uint16)); _gamma = 1.0f; - if (SDL_SetGamma(_gamma, _gamma, _gamma) < 0 ) + SDL_CalculateGammaRamp(_gamma, gamma_ramp); + + if (SDL_SetWindowGammaRamp(mainWindow, gamma_ramp, gamma_ramp, gamma_ramp) < 0 ) { - char * errStr = SDL_GetError(); + const char * errStr = SDL_GetError(); OOLogWARN(@"gamma.set.failed", @"Could not set gamma: %s", errStr); // CIM: this doesn't seem to necessarily be fatal. Gamma settings // mostly work on mine despite this function failing. // exit(1); } - SDL_EnableUNICODE(1); } @@ -150,13 +150,14 @@ - (id) init NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults]; showSplashScreen = [prefs oo_boolForKey:@"splash-screen" defaultValue:YES]; BOOL vSyncPreference = [prefs oo_boolForKey:@"v-sync" defaultValue:YES]; - int vSyncValue; NSArray *arguments = nil; NSEnumerator *argEnum = nil; NSString *arg = nil; BOOL noSplashArgFound = NO; + SDL_Rect drawable; + arguments = [[NSProcessInfo processInfo] arguments]; // scan for splash screen overrides: -nosplash || --nosplash , -splash || --splash @@ -195,7 +196,18 @@ - (id) init return nil; } - SDL_putenv ("SDL_VIDEO_WINDOW_POS=center"); + // Generate the window caption, containing the version number and the date the executable was compiled. + static char windowCaption[128]; + NSString *versionString = [NSString stringWithFormat:@"Oolite v%@", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]]; + + strcpy (windowCaption, [versionString UTF8String]); + strcat (windowCaption, " - "__DATE__); + + mainWindow = SDL_CreateWindow(windowCaption, + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + 8, 8, + SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI); [OOJoystickManager setStickHandlerClass:[OOSDLJoystickManager class]]; // end TODO @@ -203,13 +215,6 @@ - (id) init [OOSound setUp]; if (![OOSound isSoundOK]) OOLog(@"sound.init", @"Sound system disabled."); - // Generate the window caption, containing the version number and the date the executable was compiled. - static char windowCaption[128]; - NSString *versionString = [NSString stringWithFormat:@"Oolite v%@", [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]]; - - strcpy (windowCaption, [versionString UTF8String]); - strcat (windowCaption, " - "__DATE__); - SDL_WM_SetCaption (windowCaption, "Oolite"); // Set window title. #if OOLITE_WINDOWS // needed for enabling system window manager events, which is needed for handling window movement messages @@ -218,10 +223,10 @@ - (id) init //capture the window handle for later static SDL_SysWMinfo wInfo; SDL_VERSION(&wInfo.version); - SDL_GetWMInfo(&wInfo); - SDL_Window = wInfo.window; + SDL_GetWindowWMInfo(mainWindow, &wInfo); + Main_Window = wInfo.window; - // This must be inited after SDL_Window has been set - we need the main window handle in order to get monitor info + // This must be inited after Main_Window has been set - we need the main window handle in order to get monitor info if (![self getCurrentMonitorInfo:&monitorInfo]) { OOLogWARN(@"display.initGL.monitorInfoWarning", @"Could not get current monitor information."); @@ -236,8 +241,8 @@ - (id) init if (icon != NULL) { colorkey = SDL_MapRGB(icon->format, 128, 0, 128); - SDL_SetColorKey(icon, SDL_SRCCOLORKEY, colorkey); - SDL_WM_SetIcon(icon, NULL); + SDL_SetColorKey(icon, SDL_TRUE, colorkey); + SDL_SetWindowIcon(mainWindow, icon); } SDL_FreeSurface(icon); @@ -247,10 +252,6 @@ - (id) init SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); - // V-sync settings - we set here, but can only verify after SDL_SetVideoMode has been called. - SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, vSyncPreference); // V-sync on by default. - OOLog(@"display.initGL", @"V-Sync %@requested.", vSyncPreference ? @"" : @"not "); - /* Multisampling significantly improves graphics quality with * basically no extra programming effort on our part, especially * for curved surfaces like the planet, but is also expensive - in @@ -279,13 +280,13 @@ - (id) init OOLog(@"display.initGL", @"%@", @"Trying 32-bit depth buffer"); [self createSurface]; - if (surface == NULL) + if (glContext == NULL) { // Retry with a 24-bit depth buffer OOLog(@"display.initGL", @"%@", @"Trying 24-bit depth buffer"); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24); [self createSurface]; - if (surface == NULL) + if (glContext == NULL) { // Still not working? One last go... // Retry, allowing 16-bit contexts. @@ -300,10 +301,10 @@ - (id) init [self createSurface]; - if (surface == NULL) + if (glContext == NULL) { - char * errStr = SDL_GetError(); - OOLogERR(@"display.mode.error", @"Could not create display surface: %s", errStr); + const char * errStr = SDL_GetError(); + OOLogERR(@"display.mode.error", @"Could not create display GL context: %s", errStr); #if OOLITE_WINDOWS if (showSplashScreen) { @@ -316,16 +317,22 @@ - (id) init } } } + + SDL_GL_SetSwapInterval(vSyncPreference); // V-sync on by default. + OOLog(@"display.initGL", @"V-Sync %@requested.", vSyncPreference ? @"" : @"not "); + // Verify V-sync successfully set - report it if not - if (vSyncPreference && SDL_GL_GetAttribute(SDL_GL_SWAP_CONTROL, &vSyncValue) == -1) + if (vSyncPreference && SDL_GL_GetSwapInterval() == -1) { OOLogWARN(@"display.initGL", @"Could not enable V-Sync. Please check that your graphics driver supports the %@_swap_control extension.", OOLITE_WINDOWS ? @"WGL_EXT" : @"[GLX_SGI/GLX_MESA]"); } - bounds.size.width = surface->w; - bounds.size.height = surface->h; + SDL_GL_GetDrawableSize(mainWindow, &drawable.w, &drawable.h); + + bounds.size.width = drawable.w; + bounds.size.height = drawable.h; [self autoShowMouse]; @@ -357,21 +364,37 @@ - (void) endSplashScreen [self initialiseGLWithSize: firstScreen]; #else + [self setWindowBorderless:NO]; - int videoModeFlags = SDL_HWSURFACE | SDL_OPENGL; - - videoModeFlags |= (fullScreen) ? SDL_FULLSCREEN : SDL_RESIZABLE; - surface = SDL_SetVideoMode(firstScreen.width, firstScreen.height, 32, videoModeFlags); + SDL_SetWindowResizable(mainWindow, SDL_TRUE); + SDL_SetWindowSize(mainWindow, (int)firstScreen.width, (int)firstScreen.height); + if (fullScreen) + { + SDL_DisplayMode target, closest; + target.w = (int)firstScreen.width; + target.h = (int)firstScreen.height; + target.format = 0; + target.refresh_rate = 0; //FIXME: maybe replace viewSize with SDL_DisplayMode? + target.driverdata = 0; + if (SDL_GetClosestDisplayMode(0, &target, &closest) != NULL) + { + if(SDL_SetWindowDisplayMode(mainWindow, &closest) == 0) + { + OOLog(@"display.initGL", @"Fullscreen resolution set to %d x %d.", (int)viewSize.width, (int)viewSize.height); + if (SDL_SetWindowFullscreen(mainWindow, SDL_WINDOW_FULLSCREEN)) + { + [self setFullScreenMode: NO]; + } + } + } + } - if (!surface && fullScreen == YES) + if (!(SDL_GetWindowFlags(mainWindow) & SDL_WINDOW_FULLSCREEN) && fullScreen == YES) { [self setFullScreenMode: NO]; - videoModeFlags &= ~SDL_FULLSCREEN; - videoModeFlags |= SDL_RESIZABLE; - surface = SDL_SetVideoMode(currentWindowSize.width, currentWindowSize.height, 32, videoModeFlags); } - SDL_putenv ("SDL_VIDEO_WINDOW_POS=none"); //stop linux from auto centering on resize + SDL_SetWindowPosition(mainWindow, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED); //stop linux from auto centering on resize /* MKW 2011.11.11 * Eat all SDL events to gobble up any resize events while the @@ -404,10 +427,10 @@ - (void) dealloc if (screenSizes) [screenSizes release]; - if (surface != 0) + if (glContext != NULL) { - SDL_FreeSurface(surface); - surface = 0; + SDL_GL_DeleteContext(glContext); + glContext = NULL; } SDL_Quit(); @@ -631,13 +654,16 @@ - (void) drawRect:(NSRect)rect - (void) updateScreenWithVideoMode:(BOOL) v_mode { - if ((viewSize.width != surface->w)||(viewSize.height != surface->h)) // resized + int v_width, v_height; + + SDL_GetWindowSize(mainWindow, &v_width, &v_height); + if ((viewSize.width != v_width)||(viewSize.height != v_height)) // resized { #if OOLITE_LINUX m_glContextInitialized = NO; //probably not needed #endif - viewSize.width = surface->w; - viewSize.height = surface->h; + viewSize.width = v_width; + viewSize.height = v_height; } if (m_glContextInitialized == NO) @@ -645,7 +671,7 @@ - (void) updateScreenWithVideoMode:(BOOL) v_mode [self initialiseGLWithSize:viewSize useVideoMode:v_mode]; } - if (surface == 0) + if (glContext == NULL) return; // do all the drawing! @@ -658,7 +684,7 @@ - (void) updateScreenWithVideoMode:(BOOL) v_mode glClear( GL_COLOR_BUFFER_BIT); } - SDL_GL_SwapBuffers(); + SDL_GL_SwapWindow(mainWindow); } - (void) initSplashScreen @@ -668,6 +694,7 @@ - (void) initSplashScreen //too early for OOTexture! SDL_Surface *image=NULL; SDL_Rect dest; + SDL_Rect drawable; NSString *imagesDir = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Images"]; @@ -704,20 +731,31 @@ - (void) initSplashScreen * Changed to SDL_NOFRAME, throwing caution to the wind - Kaks 2012.03.23 * Took SDL_NOFRAME out, since it still causes strange problems here - cim 2012.04.09 */ - surface = SDL_SetVideoMode(dest.w, dest.h, 32, SDL_HWSURFACE | SDL_OPENGL); + [self setWindowBorderless:YES]; + + SDL_SetWindowSize(mainWindow, dest.w, dest.h); + SDL_SetWindowResizable(mainWindow, SDL_FALSE); + SDL_SetWindowPosition(mainWindow, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); #endif + if(SDL_GL_MakeCurrent(mainWindow, glContext)) + { + OOLogERR(@"display.mode.error",@"Unable to create GL context: %s",SDL_GetError()); + exit(1); + } + SDL_GL_GetDrawableSize(mainWindow, &drawable.w, &drawable.h); + OOSetOpenGLState(OPENGL_STATE_OVERLAY); - glViewport( 0, 0, dest.w, dest.h); + glViewport( 0, 0, drawable.w, drawable.h); glEnable( GL_TEXTURE_2D ); glClearColor( 0.0f, 0.0f, 0.0f, 0.0f ); glClear( GL_COLOR_BUFFER_BIT ); [matrixManager resetProjection]; - [matrixManager orthoLeft: 0.0f right: dest.w bottom: dest.h top: 0.0 near: -1.0 far: 1.0]; + [matrixManager orthoLeft: 0.0f right: drawable.w bottom: drawable.h top: 0.0 near: -1.0 far: 1.0]; [matrixManager syncProjection]; [matrixManager resetModelView]; @@ -766,15 +804,16 @@ - (void) initSplashScreen glTexCoord2i( 0, 0 ); glVertex2i( 0, 0 ); glTexCoord2i( 1, 0 ); - glVertex2i( dest.w, 0 ); + glVertex2i( drawable.w, 0 ); glTexCoord2i( 1, 1 ); - glVertex2i( dest.w, dest.h ); + glVertex2i( drawable.w, drawable.h ); glTexCoord2i( 0, 1 ); - glVertex2i( 0, dest.h ); + glVertex2i( 0, drawable.h ); glEnd(); - SDL_GL_SwapBuffers(); + SDL_GL_SwapWindow(mainWindow); + [matrixManager resetModelView]; [matrixManager syncModelView]; @@ -843,7 +882,7 @@ - (MONITORINFOEX) currentMonitorInfo - (BOOL) getCurrentMonitorInfo:(MONITORINFOEX *)mInfo { - HMONITOR hMon = MonitorFromWindow(SDL_Window, MONITOR_DEFAULTTOPRIMARY); + HMONITOR hMon = MonitorFromWindow(Main_Window, MONITOR_DEFAULTTOPRIMARY); ZeroMemory(mInfo, sizeof(MONITORINFOEX)); mInfo->cbSize = sizeof(MONITORINFOEX); if (GetMonitorInfo (hMon, (LPMONITORINFO)mInfo)) @@ -871,7 +910,7 @@ - (void) grabMouseInsideGameWindow:(BOOL) value if(value) { RECT gameWindowRect; - GetWindowRect(SDL_Window, &gameWindowRect); + GetWindowRect(Main_Window, &gameWindowRect); ClipCursor(&gameWindowRect); } else @@ -965,7 +1004,7 @@ - (void) resetSDLKeyModifiers - (void) setWindowBorderless:(BOOL)borderless { - LONG currentWindowStyle = GetWindowLong(SDL_Window, GWL_STYLE); + LONG currentWindowStyle = GetWindowLong(Main_Window, GWL_STYLE); // window already has the desired style? if ((!borderless && (currentWindowStyle & WS_CAPTION)) || @@ -973,14 +1012,14 @@ - (void) setWindowBorderless:(BOOL)borderless if (borderless) { - SetWindowLong(SDL_Window, GWL_STYLE, currentWindowStyle & ~WS_CAPTION & ~WS_THICKFRAME); + SetWindowLong(Main_Window, GWL_STYLE, currentWindowStyle & ~WS_CAPTION & ~WS_THICKFRAME); } else { - SetWindowLong(SDL_Window, GWL_STYLE, currentWindowStyle | + SetWindowLong(Main_Window, GWL_STYLE, currentWindowStyle | WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX ); } - SetWindowPos(SDL_Window, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); + SetWindowPos(Main_Window, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); } @@ -1019,7 +1058,18 @@ - (void) resetSDLKeyModifiers - (void) setWindowBorderless:(BOOL)borderless { - // do nothing on Linux + // window already has the desired style? + if ((!borderless && !(SDL_GetWindowFlags(mainWindow) & SDL_WINDOW_BORDERLESS)) || + (borderless && (SDL_GetWindowFlags(mainWindow) & SDL_WINDOW_BORDERLESS))) return; + + if (borderless) + { + SDL_SetWindowBordered(mainWindow, SDL_FALSE); + } + else + { + SDL_SetWindowBordered(mainWindow, SDL_TRUE); + } } #endif //OOLITE_WINDOWS @@ -1035,11 +1085,12 @@ - (void) initialiseGLWithSize:(NSSize) v_size useVideoMode:(BOOL) v_mode { #if OOLITE_LINUX NSSize oldViewSize = viewSize; + int width, height; #endif viewSize = v_size; - OOLog(@"display.initGL", @"Requested a new surface of %d x %d, %@.", (int)viewSize.width, (int)viewSize.height,(fullScreen ? @"fullscreen" : @"windowed")); - SDL_GL_SwapBuffers(); // clear the buffer before resize - + OOLog(@"display.initGL", @"Requested a new output of %d x %d, %@.", (int)viewSize.width, (int)viewSize.height,(fullScreen ? @"fullscreen" : @"windowed")); + SDL_GL_SwapWindow(mainWindow); // clear the buffer before resize + #if OOLITE_WINDOWS if (!updateContext) return; @@ -1190,41 +1241,40 @@ - (void) initialiseGLWithSize:(NSSize) v_size useVideoMode:(BOOL) v_mode #else //OOLITE_LINUX - int videoModeFlags = SDL_HWSURFACE | SDL_OPENGL; - if (v_mode == NO) - videoModeFlags |= SDL_NOFRAME; + [self setWindowBorderless:YES]; if (fullScreen == YES) { - videoModeFlags |= SDL_FULLSCREEN; + SDL_DisplayMode target, closest; + target.w = (int)viewSize.width; + target.h = (int)viewSize.height; + target.format = 0; + target.refresh_rate = 0; //(int)viewSize.RefreshRate; FIXME: maybe replace viewSize with SDL_DisplayMode? + target.driverdata = 0; + //SDL_SetWindowFullscreen(mainWindow, 0); + if (SDL_GetClosestDisplayMode(0, &target, &closest) != NULL) + { + if(SDL_SetWindowDisplayMode(mainWindow, &closest) == 0) + { + OOLog(@"display.initGL", @"Fullscreen resolution set to %d x %d.", (int)viewSize.width, (int)viewSize.height); + if (SDL_SetWindowFullscreen(mainWindow, SDL_WINDOW_FULLSCREEN)) + { + [self setFullScreenMode: NO]; + viewSize = oldViewSize; + } + } + } } else { - videoModeFlags |= SDL_RESIZABLE; - } - surface = SDL_SetVideoMode((int)viewSize.width, (int)viewSize.height, 32, videoModeFlags); - - if (!surface && fullScreen == YES) - { - [self setFullScreenMode: NO]; - viewSize = oldViewSize; - videoModeFlags &= ~SDL_FULLSCREEN; - videoModeFlags |= SDL_RESIZABLE; - surface = SDL_SetVideoMode((int)viewSize.width, (int)viewSize.height, 32, videoModeFlags); + SDL_SetWindowFullscreen(mainWindow, 0); } - if (!surface) - { - // we should always have a valid surface, but in case we don't - OOLogERR(@"display.mode.error",@"Unable to change display mode: %s",SDL_GetError()); - exit(1); - } - - bounds.size.width = surface->w; - bounds.size.height = surface->h; - + SDL_GL_GetDrawableSize(mainWindow, &width, &height); + bounds.size.width = width; + bounds.size.height = height; #endif - OOLog(@"display.initGL", @"Created a new surface of %d x %d, %@.", (int)viewSize.width, (int)viewSize.height,(fullScreen ? @"fullscreen" : @"windowed")); + OOLog(@"display.initGL", @"Created a new output of %d x %d, %@.", (int)viewSize.width, (int)viewSize.height,(fullScreen ? @"fullscreen" : @"windowed")); if (viewSize.width/viewSize.height > 4.0/3.0) { display_z = 480.0 * bounds.size.width/bounds.size.height; @@ -1236,12 +1286,10 @@ - (void) initialiseGLWithSize:(NSSize) v_size useVideoMode:(BOOL) v_mode y_offset = 320.0 * bounds.size.height/bounds.size.width; } - if (surface != 0) SDL_FreeSurface(surface); - [self autoShowMouse]; [[self gameController] setUpBasicOpenGLStateWithSize:viewSize]; - SDL_GL_SwapBuffers(); + SDL_GL_SwapWindow(mainWindow); squareX = 0.0f; m_glContextInitialized = YES; @@ -1251,7 +1299,9 @@ - (void) initialiseGLWithSize:(NSSize) v_size useVideoMode:(BOOL) v_mode - (BOOL) snapShot:(NSString *)filename { BOOL snapShotOK = YES; - SDL_Surface* tmpSurface; + SDL_Surface *surface, *tmpSurface; + + surface = SDL_GetWindowSurface(mainWindow); // backup the previous directory NSString* originalDirectory = [[NSFileManager defaultManager] currentDirectoryPath]; @@ -1329,6 +1379,7 @@ - (BOOL) snapShot:(NSString *)filename } #endif SDL_FreeSurface(tmpSurface); + SDL_FreeSurface(surface); free(pixls); // return to the previous directory @@ -1532,7 +1583,7 @@ - (void) resetMouse [self setVirtualJoystick:0.0 :0.0]; if ([[PlayerEntity sharedPlayer] isMouseControlOn]) { - SDL_WarpMouse([self viewSize].width / 2, [self viewSize].height / 2); + SDL_WarpMouseInWindow(mainWindow, [self viewSize].width / 2, [self viewSize].height / 2); mouseWarped = YES; } } @@ -1659,13 +1710,15 @@ - (void) setKeyboardTo: (NSString *) value - (void)pollControls { SDL_Event event; - SDL_KeyboardEvent *kbd_event; - SDL_MouseButtonEvent *mbtn_event; - SDL_MouseMotionEvent *mmove_event; - int mxdelta, mydelta; + SDL_KeyboardEvent *kbd_event; + SDL_MouseButtonEvent *mbtn_event; + SDL_MouseWheelEvent *mwheel_event; + SDL_WindowEvent *window_event; + SDL_MouseMotionEvent *mmove_event; + int mxdelta, mydelta; float mouseVirtualStickSensitivityX = viewSize.width * MOUSEVIRTUALSTICKSENSITIVITYFACTOR; float mouseVirtualStickSensitivityY = viewSize.height * MOUSEVIRTUALSTICKSENSITIVITYFACTOR; - NSTimeInterval timeNow = [NSDate timeIntervalSinceReferenceDate]; + NSTimeInterval timeNow = [NSDate timeIntervalSinceReferenceDate]; while (SDL_PollEvent(&event)) @@ -1695,13 +1748,6 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call */ [self resetMouse]; // Will set mouseWarped to YES break; - // mousewheel stuff - case SDL_BUTTON_WHEELUP: - _mouseWheelState = gvMouseWheelUp; - break; - case SDL_BUTTON_WHEELDOWN: - _mouseWheelState = gvMouseWheelDown; - break; } break; @@ -1718,17 +1764,23 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call } keys[gvMouseLeftButton] = NO; } + break; + + case SDL_MOUSEWHEEL: + mwheel_event = (SDL_MouseWheelEvent*)&event; /* - Mousewheel handling - just note time since last use here and mark as inactive, - if needed, at the end of this method. Note that the mousewheel button up event is - kind of special, as in, it is sent at the same time as its corresponding mousewheel - button down one - Nikos 20140809 + Mousewheel handling - SDL2 Supports delta movement of mouse wheel. + For now just emulate the old behaviour. */ - if (mbtn_event->button == SDL_BUTTON_WHEELUP || mbtn_event->button == SDL_BUTTON_WHEELDOWN) + if (mwheel_event->y != 0) { NSTimeInterval timeBetweenMouseWheels = timeNow - timeSinceLastMouseWheel; timeSinceLastMouseWheel += timeBetweenMouseWheels; } + if (mwheel_event->y <0) + _mouseWheelState = gvMouseWheelDown; + else + _mouseWheelState = gvMouseWheelUp; break; case SDL_MOUSEMOTION: @@ -1938,16 +1990,16 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call case SDLK_KP_MULTIPLY: keys[42] = YES; break; // * - case SDLK_KP1: keys[gvNumberPadKey1] = YES; break; - case SDLK_KP2: keys[gvNumberPadKey2] = YES; break; - case SDLK_KP3: keys[gvNumberPadKey3] = YES; break; - case SDLK_KP4: keys[gvNumberPadKey4] = YES; break; - case SDLK_KP5: keys[gvNumberPadKey5] = YES; break; - case SDLK_KP6: keys[gvNumberPadKey6] = YES; break; - case SDLK_KP7: keys[gvNumberPadKey7] = YES; break; - case SDLK_KP8: keys[gvNumberPadKey8] = YES; break; - case SDLK_KP9: keys[gvNumberPadKey9] = YES; break; - case SDLK_KP0: keys[gvNumberPadKey0] = YES; break; + case SDLK_KP_1: keys[gvNumberPadKey1] = YES; break; + case SDLK_KP_2: keys[gvNumberPadKey2] = YES; break; + case SDLK_KP_3: keys[gvNumberPadKey3] = YES; break; + case SDLK_KP_4: keys[gvNumberPadKey4] = YES; break; + case SDLK_KP_5: keys[gvNumberPadKey5] = YES; break; + case SDLK_KP_6: keys[gvNumberPadKey6] = YES; break; + case SDLK_KP_7: keys[gvNumberPadKey7] = YES; break; + case SDLK_KP_8: keys[gvNumberPadKey8] = YES; break; + case SDLK_KP_9: keys[gvNumberPadKey9] = YES; break; + case SDLK_KP_0: keys[gvNumberPadKey0] = YES; break; case SDLK_F1: keys[gvFunctionKey1] = YES; break; case SDLK_F2: keys[gvFunctionKey2] = YES; break; @@ -1987,7 +2039,7 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call case SDLK_ESCAPE: if (shift) { - SDL_FreeSurface(surface); + if (glContext != NULL) SDL_GL_DeleteContext(glContext); [gameController exitAppWithContext:@"Shift-escape pressed"]; } else @@ -2128,16 +2180,16 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call case SDLK_KP_MULTIPLY: keys[42] = NO; break; // * - case SDLK_KP1: keys[gvNumberPadKey1] = NO; break; - case SDLK_KP2: keys[gvNumberPadKey2] = NO; break; - case SDLK_KP3: keys[gvNumberPadKey3] = NO; break; - case SDLK_KP4: keys[gvNumberPadKey4] = NO; break; - case SDLK_KP5: keys[gvNumberPadKey5] = NO; break; - case SDLK_KP6: keys[gvNumberPadKey6] = NO; break; - case SDLK_KP7: keys[gvNumberPadKey7] = NO; break; - case SDLK_KP8: keys[gvNumberPadKey8] = NO; break; - case SDLK_KP9: keys[gvNumberPadKey9] = NO; break; - case SDLK_KP0: keys[gvNumberPadKey0] = NO; break; + case SDLK_KP_1: keys[gvNumberPadKey1] = NO; break; + case SDLK_KP_2: keys[gvNumberPadKey2] = NO; break; + case SDLK_KP_3: keys[gvNumberPadKey3] = NO; break; + case SDLK_KP_4: keys[gvNumberPadKey4] = NO; break; + case SDLK_KP_5: keys[gvNumberPadKey5] = NO; break; + case SDLK_KP_6: keys[gvNumberPadKey6] = NO; break; + case SDLK_KP_7: keys[gvNumberPadKey7] = NO; break; + case SDLK_KP_8: keys[gvNumberPadKey8] = NO; break; + case SDLK_KP_9: keys[gvNumberPadKey9] = NO; break; + case SDLK_KP_0: keys[gvNumberPadKey0] = NO; break; case SDLK_F1: keys[gvFunctionKey1] = NO; break; case SDLK_F2: keys[gvFunctionKey2] = NO; break; @@ -2181,34 +2233,41 @@ reset the virtual joystick (mouse) coordinates, we need to send a WarpMouse call } break; - case SDL_VIDEORESIZE: + case SDL_WINDOWEVENT: { - SDL_ResizeEvent *rsevt=(SDL_ResizeEvent *)&event; - NSSize newSize=NSMakeSize(rsevt->w, rsevt->h); -#if OOLITE_WINDOWS - if (!fullScreen && updateContext) - { - if (saveSize == NO) - { - // event triggered by caption & frame - // next event will be a real resize. - saveSize = YES; - } - else + window_event = (SDL_WindowEvent*)&event; + switch (window_event->event) { + case SDL_WINDOWEVENT_RESIZED: + case SDL_WINDOWEVENT_SIZE_CHANGED: { + NSSize newSize=NSMakeSize(window_event->data1, window_event->data2); +#if OOLITE_WINDOWS + if (!fullScreen && updateContext) + { + if (saveSize == NO) + { + // event triggered by caption & frame + // next event will be a real resize. + saveSize = YES; + } + else + { + [self initialiseGLWithSize: newSize]; + [self saveWindowSize: newSize]; + } + } +#else [self initialiseGLWithSize: newSize]; [self saveWindowSize: newSize]; - } - } -#else - [self initialiseGLWithSize: newSize]; - [self saveWindowSize: newSize]; #endif - // certain gui screens will require an immediate redraw after - // a resize event - Nikos 20140129 - if ([PlayerEntity sharedPlayer]) - { - [[PlayerEntity sharedPlayer] doGuiScreenResizeUpdates]; + // certain gui screens will require an immediate redraw after + // a resize event - Nikos 20140129 + if ([PlayerEntity sharedPlayer]) + { + [[PlayerEntity sharedPlayer] doGuiScreenResizeUpdates]; + } + } + break; } break; } @@ -2258,9 +2317,9 @@ detect that our (fullscreen) window has moved, we immediately bring it back to i */ WINDOWPLACEMENT wp; wp.length = sizeof(WINDOWPLACEMENT); - GetWindowPlacement(SDL_Window, &wp); + GetWindowPlacement(Main_Window, &wp); - GetWindowRect(SDL_Window, &rDC); + GetWindowRect(Main_Window, &rDC); if (rDC.left != monitorInfo.rcMonitor.left || rDC.top != monitorInfo.rcMonitor.top) { BOOL fullScreenMaximized = NO; @@ -2268,27 +2327,27 @@ detect that our (fullscreen) window has moved, we immediately bring it back to i { fullScreenMaximized = YES; wp.showCmd = SW_SHOWNORMAL; - SetWindowPlacement(SDL_Window, &wp); + SetWindowPlacement(Main_Window, &wp); } if (wp.showCmd != SW_SHOWMINIMIZED && wp.showCmd != SW_MINIMIZE) { - MoveWindow(SDL_Window, monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top, + MoveWindow(Main_Window, monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top, (int)viewSize.width, (int)viewSize.height, TRUE); } if (fullScreenMaximized) { - GetWindowPlacement(SDL_Window, &wp); + GetWindowPlacement(Main_Window, &wp); wp.showCmd = SW_SHOWMAXIMIZED; CopyRect(&wp.rcNormalPosition, &lastGoodRect); - SetWindowPlacement(SDL_Window, &wp); + SetWindowPlacement(Main_Window, &wp); } } else if (wp.showCmd == SW_SHOWMAXIMIZED) { CopyRect(&wp.rcNormalPosition, &lastGoodRect); - SetWindowPlacement(SDL_Window, &wp); + SetWindowPlacement(Main_Window, &wp); } } // it is important that this gets done after we've dealt with possible fullscreen movements, @@ -2328,7 +2387,7 @@ detect that our (fullscreen) window has moved, we immediately bring it back to i // caused by INTR or someone hitting close case SDL_QUIT: { - SDL_FreeSurface(surface); + if (glContext != NULL) SDL_GL_DeleteContext(glContext); [gameController exitAppWithContext:@"SDL_QUIT event received"]; } } @@ -2347,7 +2406,7 @@ detect that our (fullscreen) window has moved, we immediately bring it back to i // versions. - (void) handleStringInput: (SDL_KeyboardEvent *) kbd_event; { - SDLKey key=kbd_event->keysym.sym; + SDL_Keycode key=kbd_event->keysym.sym; // Del, Backspace if((key == SDLK_BACKSPACE || key == SDLK_DELETE) && [typedString length] > 0) @@ -2373,7 +2432,7 @@ - (void) handleStringInput: (SDL_KeyboardEvent *) kbd_event; } else { - Uint16 unicode = kbd_event->keysym.unicode; + Uint16 unicode = kbd_event->keysym.sym; // printable range if (unicode >= 32 && unicode <= 126) { @@ -2392,7 +2451,9 @@ - (void) handleStringInput: (SDL_KeyboardEvent *) kbd_event; - (void) populateFullScreenModelist { int i; - SDL_Rect **modes; + static int display_num = 0; // TODO: Support multiple displays? + SDL_DisplayMode display_mode; + int mode_count; NSMutableDictionary *mode; screenSizes=[[NSMutableArray alloc] init]; @@ -2402,49 +2463,33 @@ - (void) populateFullScreenModelist mode=[MyOpenGLView getNativeSize]; [screenSizes addObject: mode]; - modes=SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_HWSURFACE); - if(modes == (SDL_Rect **)NULL) + mode_count = SDL_GetNumDisplayModes(display_num); + if (mode_count < 1) { - OOLog(@"display.mode.list.none", @"%@", @"SDL didn't return any screen modes"); + OOLog(@"display.mode.list.none", @"SDL didn't return any screen modes"); return; } - if(modes == (SDL_Rect **)-1) - { - OOLog(@"display.mode.list.none", @"%@", @"SDL claims 'all resolutions available' which is unhelpful in the extreme"); - return; - } - - int lastw=[[mode objectForKey: kOODisplayWidth] intValue]; - int lasth=[[mode objectForKey: kOODisplayHeight] intValue]; - for(i=0; modes[i]; i++) - { - // SDL_ListModes often lists a mode several times, - // presumably because each mode has several refresh rates. - // But the modes pointer is an SDL_Rect which can't represent - // refresh rates. WHY!? - if(modes[i]->w != lastw || modes[i]->h != lasth) + for (i = 0; i < mode_count; ++i) { + if (SDL_GetDisplayMode(display_num, i, &display_mode) == 0) { // new resolution, save it mode=[NSMutableDictionary dictionary]; - [mode setValue: [NSNumber numberWithInt: (int)modes[i]->w] + [mode setValue: [NSNumber numberWithInt: display_mode.w] forKey: kOODisplayWidth]; - [mode setValue: [NSNumber numberWithInt: (int)modes[i]->h] + [mode setValue: [NSNumber numberWithInt: display_mode.h] forKey: kOODisplayHeight]; - [mode setValue: [NSNumber numberWithInt: 0] + [mode setValue: [NSNumber numberWithInt: display_mode.refresh_rate] forKey: kOODisplayRefreshRate]; if (![screenSizes containsObject:mode]) { [screenSizes addObject: mode]; - OOLog(@"display.mode.list", @"Added res %d x %d", modes[i]->w, modes[i]->h); - lastw=modes[i]->w; - lasth=modes[i]->h; + OOLog(@"display.mode.list", @"Added res %d x %d @%dhz", display_mode.w, display_mode.h, display_mode.refresh_rate); } } } } - // Save and restore window sizes to/from defaults. - (void) saveWindowSize: (NSSize) windowSize { @@ -2558,11 +2603,15 @@ - (void) setMouseInDeltaMode: (BOOL) inDelta - (void) setGammaValue: (float) value { + Uint16* gamma_ramp; + if (value < 0.2f) value = 0.2f; if (value > 4.0f) value = 4.0f; + gamma_ramp = (Uint16 *)SDL_malloc(256 * sizeof(Uint16)); _gamma = value; - SDL_SetGamma(_gamma, _gamma, _gamma); + SDL_CalculateGammaRamp(_gamma, gamma_ramp); + SDL_SetWindowGammaRamp(mainWindow, gamma_ramp, gamma_ramp, gamma_ramp); [[NSUserDefaults standardUserDefaults] setFloat:_gamma forKey:@"gamma-value"]; } diff --git a/src/SDL2/OOSDLJoystickManager.m b/src/SDL2/OOSDLJoystickManager.m index 0f56d108b..1fc8216af 100644 --- a/src/SDL2/OOSDLJoystickManager.m +++ b/src/SDL2/OOSDLJoystickManager.m @@ -99,7 +99,7 @@ - (NSUInteger) joystickCount - (NSString *) nameOfJoystick:(NSUInteger)stickNumber { - return [NSString stringWithUTF8String:SDL_JoystickName((int)stickNumber)]; + return [NSString stringWithUTF8String:SDL_JoystickNameForIndex((int)stickNumber)]; }