43#define STB_IMAGE_WRITE_IMPLEMENTATION
46#define kOOLogUnconvertedNSLog @"unclassified.MyOpenGLView"
48extern int SaveEXRSnapshot(
const char* outfilename,
int width,
int height,
const float* rgb);
50static NSString *
kOOLogKeyUp =
@"input.keyMapping.keyPress.keyUp";
56#ifndef DWMWA_USE_IMMERSIVE_DARK_MODE
57#define DWMWA_USE_IMMERSIVE_DARK_MODE 20
59HRESULT WINAPI DwmSetWindowAttribute (HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute);
61#define USE_UNDOCUMENTED_DARKMODE_API 1
63#if USE_UNDOCUMENTED_DARKMODE_API
64#ifndef LOAD_LIBRARY_SEARCH_SYSTEM32
65#define LOAD_LIBRARY_SEARCH_SYSTEM32 0x00000800
67typedef DWORD(WINAPI* pfnSetPreferredAppMode)(DWORD appMode);
79@interface MyOpenGLView (OOPrivate)
82- (void) setWindowBorderless:(BOOL)borderless;
83- (void) handleStringInput: (SDL_KeyboardEvent *) kbd_event keyID:(Uint16)key_id;
91 int nativeDisplayWidth = 1024;
92 int nativeDisplayHeight = 768;
95 SDL_SysWMinfo dpyInfo;
96 SDL_VERSION(&dpyInfo.version);
97 if(SDL_GetWMInfo(&dpyInfo))
99 nativeDisplayWidth = DisplayWidth(dpyInfo.info.x11.display, 0);
100 nativeDisplayHeight = DisplayHeight(dpyInfo.info.x11.display, 0);
101 OOLog(
@"display.mode.list.native",
@"X11 native resolution detected: %d x %d", nativeDisplayWidth, nativeDisplayHeight);
105 OOLog(
@"display.mode.list.native.failed",
@"%@",
@"SDL_GetWMInfo failed, defaulting to 1024x768 for native size");
108 nativeDisplayWidth = GetSystemMetrics(SM_CXSCREEN);
109 nativeDisplayHeight = GetSystemMetrics(SM_CYSCREEN);
110 OOLog(
@"display.mode.list.native",
@"Windows native resolution detected: %d x %d", nativeDisplayWidth, nativeDisplayHeight);
112 OOLog(
@"display.mode.list.native.unknown",
@"Unknown architecture, defaulting to 1024x768");
114 [mode setValue: [
NSNumber numberWithInt: nativeDisplayWidth] forKey:kOODisplayWidth];
115 [mode setValue: [
NSNumber numberWithInt: nativeDisplayHeight] forKey: kOODisplayHeight];
116 [mode setValue: [
NSNumber numberWithInt: 0] forKey: kOODisplayRefreshRate];
118 return [mode autorelease];
125 const int videoModeFlags = SDL_HWSURFACE | SDL_OPENGL | SDL_RESIZABLE;
132 ShowWindow(SDL_Window,SW_SHOWMINIMIZED);
142 surface = SDL_SetVideoMode(8, 8, 32, videoModeFlags);
164 char * errStr = SDL_GetError();
165 OOLogWARN(
@"gamma.set.failed",
@"Could not set gamma: %s", errStr);
170 SDL_EnableUNICODE(1);
179 SDL_Surface *icon=NULL;
181 NSString *cmdLineArgsStr =
@"Startup command: ";
187 BOOL vSyncPreference = [
prefs oo_boolForKey:@"v-sync" defaultValue:YES];
188 int bitsPerColorComponent = [
prefs oo_boolForKey:@"hdr" defaultValue:NO] ? 16 : 8;
191 NSArray *arguments =
nil;
192 NSEnumerator *argEnum =
nil;
194 BOOL noSplashArgFound = NO;
205 for (argEnum = [arguments objectEnumerator]; (arg = [
argEnum nextObject]); )
207 if ([arg isEqual:
@"-nosplash"] || [arg isEqual:
@"--nosplash"])
210 noSplashArgFound = YES;
212 else if (([arg isEqual:
@"-splash"] || [arg isEqual:
@"--splash"]) && !noSplashArgFound)
218 if ([arg isEqual:
@"-novsync"] || [arg isEqual:
@"--novsync"]) vSyncPreference = NO;
220 if ([arg isEqual:
@"-hdr"]) bitsPerColorComponent = 16;
223 cmdLineArgsStr = [
cmdLineArgsStr stringByAppendingFormat:@"%@ ", arg];
226 OOLog(
@"process.args",
@"%@", cmdLineArgsStr);
232 OOLog(
@"sdl.init",
@"%@",
@"initialising SDL");
233 if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK) < 0)
235 OOLog(
@"sdl.init.failed",
@"Unable to init SDL: %s\n", SDL_GetError());
240 SDL_putenv (
"SDL_VIDEO_WINDOW_POS=center");
246 if (![
OOSound isSoundOK])
OOLog(
@"sound.init",
@"%@",
@"Sound system disabled.");
249 static char windowCaption[128];
250 NSString *versionString = [
NSString stringWithFormat:@"Oolite v%@", [[[
NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"]];
252 strcpy (windowCaption, [versionString UTF8String]);
253 strcat (windowCaption,
" - "__DATE__);
254 SDL_WM_SetCaption (windowCaption,
"Oolite");
258 SDL_EventState (SDL_SYSWMEVENT, SDL_ENABLE);
261 static SDL_SysWMinfo wInfo;
262 SDL_VERSION(&wInfo.version);
263 SDL_GetWMInfo(&wInfo);
264 SDL_Window = wInfo.window;
267 if (![
self getCurrentMonitorInfo:&monitorInfo])
269 OOLogWARN(
@"display.initGL.monitorInfoWarning",
@"Could not get current monitor information.");
272 atDesktopResolution = YES;
274#if USE_UNDOCUMENTED_DARKMODE_API
276 HMODULE hUxTheme = LoadLibraryExW(L
"uxtheme.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
280 pfnSetPreferredAppMode SetPreferredAppMode = (pfnSetPreferredAppMode)GetProcAddress(hUxTheme, MAKEINTRESOURCEA(135));
281 if (SetPreferredAppMode) SetPreferredAppMode(AllowDark);
282 FreeLibrary(hUxTheme);
289 imagesDir = [[[
NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Images"];
290 icon = SDL_LoadBMP([[imagesDir stringByAppendingPathComponent:
@"WMicon.bmp"] UTF8String]);
294 colorkey = SDL_MapRGB(icon->format, 128, 0, 128);
295 SDL_SetColorKey(icon, SDL_SRCCOLORKEY, colorkey);
296 SDL_WM_SetIcon(icon, NULL);
298 SDL_FreeSurface(icon);
300 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, bitsPerColorComponent);
301 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, bitsPerColorComponent);
302 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, bitsPerColorComponent);
303 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, bitsPerColorComponent);
304 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
305 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
311 _hdrMaxBrightness = [
prefs oo_floatForKey:@"hdr-max-brightness" defaultValue:1000.0f];
312 _hdrPaperWhiteBrightness = [
prefs oo_floatForKey:@"hdr-paperwhite-brightness" defaultValue:200.0f];
313 _hdrToneMapper =
OOHDRToneMapperFromString([prefs oo_stringForKey:
@"hdr-tone-mapper" defaultValue:
@"OOHDR_TONEMAPPER_ACES_APPROX"]);
314 if (bitsPerColorComponent == 16)
317 SDL_GL_SetAttribute(SDL_GL_PIXEL_TYPE_FLOAT, 1);
325 SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, vSyncPreference);
326 OOLog(
@"display.initGL",
@"V-Sync %@requested.", vSyncPreference ?
@"" :
@"not ");
335 if ([prefs oo_boolForKey:
@"anti-aliasing" defaultValue:NO])
337 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 1);
338 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 4);
341 OOLog(
@"display.mode.list",
@"%@",
@"CREATING MODE LIST");
354 OOLog(
@"display.initGL",
@"Trying %d-bpcc, 24-bit depth buffer", bitsPerColorComponent);
360 OOLog(
@"display.initGL",
@"%@",
@"Trying 8-bpcc, 32-bit depth buffer");
361 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
362 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
363 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
364 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
365 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 32);
372 OOLog(
@"display.initGL",
@"%@",
@"Trying 5-bpcc, 16-bit depth buffer");
373 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
374 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
375 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
376 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
378 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
379 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
385 char * errStr = SDL_GetError();
386 OOLogERR(
@"display.mode.error",
@"Could not create display surface: %s", errStr);
390 [[
NSUserDefaults standardUserDefaults] setBool:NO forKey:@"splash-screen"];
392 OOLogWARN(
@"display.mode.conflict",
@"Possible incompatibility between the splash screen and video drivers detected.");
393 OOLogWARN(
@"display.mode.conflict",
@"Oolite will start without showing the splash screen from now on. Override with 'oolite.exe -splash'");
402 OOLog(
@"display.initGL",
@"%@",
@"Achieved color / depth buffer sizes (bits):");
403 SDL_GL_GetAttribute(SDL_GL_RED_SIZE, &testAttrib);
404 OOLog(
@"display.initGL",
@"Red: %d", testAttrib);
405 SDL_GL_GetAttribute(SDL_GL_GREEN_SIZE, &testAttrib);
406 OOLog(
@"display.initGL",
@"Green: %d", testAttrib);
407 SDL_GL_GetAttribute(SDL_GL_BLUE_SIZE, &testAttrib);
408 OOLog(
@"display.initGL",
@"Blue: %d", testAttrib);
409 SDL_GL_GetAttribute(SDL_GL_ALPHA_SIZE, &testAttrib);
410 OOLog(
@"display.initGL",
@"Alpha: %d", testAttrib);
411 SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &testAttrib);
412 OOLog(
@"display.initGL",
@"Depth Buffer: %d", testAttrib);
414 SDL_GL_GetAttribute(SDL_GL_PIXEL_TYPE_FLOAT, &testAttrib);
415 OOLog(
@"display.initGL",
@"Pixel type is float : %d", testAttrib);
417 OOLog(
@"display.initGL",
@"Pixel format index: %d", GetPixelFormat(GetDC(SDL_Window)));
421 if (vSyncPreference && SDL_GL_GetAttribute(SDL_GL_SWAP_CONTROL, &vSyncValue) == -1)
423 OOLogWARN(
@"display.initGL",
@"Could not enable V-Sync. Please check that your graphics driver supports the %@_swap_control extension.",
457 if (MessageBox(NULL,
"No primary display in HDR mode was detected.\n\n"
458 "If you continue, graphics will not be rendered as intended.\n"
459 "Click OK to launch anyway, or Cancel to exit.",
"oolite.exe - HDR requested",
460 MB_OKCANCEL | MB_ICONWARNING) == IDCANCEL)
473 ShowWindow(SDL_Window,SW_RESTORE);
478 int videoModeFlags = SDL_HWSURFACE | SDL_OPENGL;
480 videoModeFlags |= (
fullScreen) ? SDL_FULLSCREEN : SDL_RESIZABLE;
486 videoModeFlags &= ~SDL_FULLSCREEN;
487 videoModeFlags |= SDL_RESIZABLE;
491 SDL_putenv (
"SDL_VIDEO_WINDOW_POS=none");
500 SDL_Event dummyEvent;
501 while (SDL_PollEvent(&dummyEvent))
527 NSString *kbd = [
prefs oo_stringForKey:@"keyboard-code" defaultValue:@"default"];
528 NSDictionary *subset = [
kmap objectForKey:kbd];
530 [keyMappings_normal release];
532 [keyMappings_shifted release];
540 [typedString release];
543 [screenSizes release];
547 SDL_FreeSurface(surface);
551 if (keyMappings_normal)
552 [keyMappings_normal release];
554 if (keyMappings_shifted)
555 [keyMappings_shifted release];
561 [matrixManager release];
572 if (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE)
573 SDL_ShowCursor(SDL_DISABLE);
577 if (SDL_ShowCursor(SDL_QUERY) == SDL_DISABLE)
578 SDL_ShowCursor(SDL_ENABLE);
588- (void) allowStringInput: (BOOL) value
610 [typedString setString:@""];
614- (void) setTypedString:(NSString*) value
616 [typedString setString:value];
681- (void) setFullScreenMode:(BOOL)fsm
686 [[NSUserDefaults standardUserDefaults]
687 setBool: fullScreen forKey:@"fullscreen"];
688 [[NSUserDefaults standardUserDefaults] synchronize];
692- (void) toggleScreenMode
694 [
self setFullScreenMode: !fullScreen];
696 [
self getCurrentMonitorInfo:&monitorInfo];
701 if(![
self isRunningOnPrimaryDisplayDevice])
703 [
self initialiseGLWithSize:NSMakeSize(monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left,
704 monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top)];
706 else [
self initialiseGLWithSize:[
self modeAsSize: currentSize]];
708 [
self initialiseGLWithSize:[
self modeAsSize: currentSize]];
712 [
self initialiseGLWithSize: currentWindowSize];
716 if ([PlayerEntity sharedPlayer])
723- (void) setDisplayMode:(
int)mode fullScreen:(BOOL)fsm
725 [
self setFullScreenMode: fsm];
728 [
self initialiseGLWithSize: [
self modeAsSize: mode]];
732- (
int) indexOfCurrentSize
738- (void) setScreenSize: (
int)sizeIndex
740 currentSize=sizeIndex;
742 [
self initialiseGLWithSize: [
self modeAsSize: currentSize]];
746- (NSMutableArray *)getScreenSizeArray
752- (NSSize) modeAsSize:(
int)sizeIndex
754 NSDictionary *
mode=[screenSizes objectAtIndex: sizeIndex];
768 [
self drawRect: NSMakeRect(0, 0, viewSize.width, viewSize.height)];
771- (void) drawRect:(NSRect)rect
776- (void) updateScreenWithVideoMode:(BOOL) v_mode
797 if (
UNIVERSE) [UNIVERSE drawUniverse];
801 glClearColor( 0.0, 0.0, 0.0, 0.0);
802 glClear( GL_COLOR_BUFFER_BIT);
805 SDL_GL_SwapBuffers();
813 SDL_Surface *image=NULL;
816 NSString *imagesDir = [[[
NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"Images"];
818 image = SDL_LoadBMP([[imagesDir stringByAppendingPathComponent:
@"splash.bmp"] UTF8String]);
822 SDL_FreeSurface(image);
823 OOLogWARN(
@"sdl.gameStart",
@"%@",
@"image 'splash.bmp' not found!");
835 dest.x = (GetSystemMetrics(SM_CXSCREEN)- dest.w)/2;
836 dest.y = (GetSystemMetrics(SM_CYSCREEN)-dest.h)/2;
837 SetWindowLong(SDL_Window,GWL_STYLE,GetWindowLong(SDL_Window,GWL_STYLE) & ~WS_CAPTION & ~WS_THICKFRAME);
838 ShowWindow(SDL_Window,SW_RESTORE);
839 MoveWindow(SDL_Window,dest.x,dest.y,dest.w,dest.h,TRUE);
851 surface = SDL_SetVideoMode(dest.w, dest.h, 32, SDL_HWSURFACE | SDL_OPENGL);
857 glViewport( 0, 0, dest.w, dest.h);
859 glEnable( GL_TEXTURE_2D );
860 glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
861 glClear( GL_COLOR_BUFFER_BIT );
871 GLenum texture_format;
875 nOfColors = image->format->BytesPerPixel;
878 if (image->format->Rmask == 0x000000ff)
879 texture_format = GL_RGBA;
881 texture_format = GL_BGRA;
883 else if (nOfColors == 3)
885 if (image->format->Rmask == 0x000000ff)
886 texture_format = GL_RGB;
888 texture_format = GL_BGR;
890 SDL_FreeSurface(image);
891 OOLog(
@"Sdl.GameStart",
@"%@",
@"----- Encoding error within image 'splash.bmp'");
896 glGenTextures( 1, &texture );
897 glBindTexture( GL_TEXTURE_2D, texture );
900 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
901 glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
904 glTexImage2D( GL_TEXTURE_2D, 0, nOfColors, image->w, image->h, 0,
905 texture_format, GL_UNSIGNED_BYTE, image->pixels );
907 glBindTexture( GL_TEXTURE_2D, texture );
910 glTexCoord2i( 0, 0 );
912 glTexCoord2i( 1, 0 );
913 glVertex2i( dest.w, 0 );
914 glTexCoord2i( 1, 1 );
915 glVertex2i( dest.w, dest.h );
916 glTexCoord2i( 0, 1 );
917 glVertex2i( 0, dest.h );
921 SDL_GL_SwapBuffers();
926 SDL_FreeSurface( image );
928 glDeleteTextures(1, &texture);
930 glDisable( GL_TEXTURE_2D );
936- (MONITORINFOEX) currentMonitorInfo
942- (BOOL) getCurrentMonitorInfo:(MONITORINFOEX *)mInfo
944 HMONITOR hMon = MonitorFromWindow(SDL_Window, MONITOR_DEFAULTTOPRIMARY);
945 ZeroMemory(mInfo,
sizeof(MONITORINFOEX));
946 mInfo->cbSize =
sizeof(MONITORINFOEX);
947 if (GetMonitorInfo (hMon, (LPMONITORINFO)mInfo))
955- (BOOL) isRunningOnPrimaryDisplayDevice
958 [
self getCurrentMonitorInfo:&monitorInfo];
959 if (!(monitorInfo.dwFlags & MONITORINFOF_PRIMARY))
967- (void) grabMouseInsideGameWindow:(BOOL) value
972 GetWindowRect(SDL_Window, &gameWindowRect);
973 ClipCursor(&gameWindowRect);
979 grabMouseStatus = !!value;
983- (void) stringToClipboard:(NSString *)stringToCopy
987 const char *clipboardText = [stringToCopy cStringUsingEncoding:NSUTF8StringEncoding];
988 const size_t clipboardTextLength = strlen(clipboardText) + 1;
989 HGLOBAL clipboardMem = GlobalAlloc(GMEM_MOVEABLE, clipboardTextLength);
992 memcpy(GlobalLock(clipboardMem), clipboardText, clipboardTextLength);
993 GlobalUnlock(clipboardMem);
996 if (!SetClipboardData(CF_TEXT, clipboardMem))
998 OOLog(
@"stringToClipboard.failed",
@"Failed to copy string %@ to clipboard", stringToCopy);
1003 GlobalFree(clipboardMem);
1015 SDLMod modState = SDL_GetModState();
1016 Uint8 *keyState = SDL_GetKeyState(NULL);
1017 BYTE keyboardStatus[256];
1018 #define OO_RESET_SDLKEY_MODIFIER(vkCode, kModCode, sdlkCode) do {\
1019 if (keyboardStatus[vkCode] & 0x0080) \
1021 modState |= kModCode; \
1022 keyState[sdlkCode] = SDL_PRESSED; \
1026 modState &= ~kModCode; \
1027 keyState[sdlkCode] = SDL_RELEASED; \
1030 if (GetKeyboardState(keyboardStatus))
1043 OO_RESET_SDLKEY_MODIFIER(VK_LCONTROL, KMOD_LCTRL, SDLK_LCTRL);
1044 OO_RESET_SDLKEY_MODIFIER(VK_RCONTROL, KMOD_RCTRL, SDLK_RCTRL);
1045 ctrl = (modState & KMOD_LCTRL || modState & KMOD_RCTRL);
1048 OO_RESET_SDLKEY_MODIFIER(VK_LSHIFT, KMOD_LSHIFT, SDLK_LSHIFT);
1049 OO_RESET_SDLKEY_MODIFIER(VK_RSHIFT, KMOD_RSHIFT, SDLK_RSHIFT);
1050 shift = (modState & KMOD_LSHIFT || modState & KMOD_RSHIFT);
1053 if (GetKeyState(VK_CAPITAL) & 0x0001)
1055 modState |= KMOD_CAPS;
1056 keyState[SDLK_CAPSLOCK] = SDL_PRESSED;
1060 modState &= ~KMOD_CAPS;
1061 keyState[SDLK_CAPSLOCK] = SDL_RELEASED;
1065 SDL_SetModState(modState);
1069- (void) setWindowBorderless:(BOOL)borderless
1071 LONG currentWindowStyle = GetWindowLong(SDL_Window, GWL_STYLE);
1074 if ((!borderless && (currentWindowStyle & WS_CAPTION)) ||
1075 (borderless && !(currentWindowStyle & WS_CAPTION)))
return;
1079 SetWindowLong(SDL_Window, GWL_STYLE, currentWindowStyle & ~WS_CAPTION & ~WS_THICKFRAME);
1083 SetWindowLong(SDL_Window, GWL_STYLE, currentWindowStyle |
1084 WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX );
1085 [
self refreshDarKOrLightMode];
1087 SetWindowPos(SDL_Window, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED);
1091- (void) refreshDarKOrLightMode
1093 int shouldSetDarkMode = [
self isDarkModeOn];
1094 DwmSetWindowAttribute (SDL_Window, DWMWA_USE_IMMERSIVE_DARK_MODE, &shouldSetDarkMode,
sizeof(shouldSetDarkMode));
1098- (BOOL) isDarkModeOn
1101 DWORD bufferSize =
sizeof(buffer);
1104 HRESULT resultRegGetValue = RegGetValueW(HKEY_CURRENT_USER, L
"Software\\Microsoft\\Windows\\CurrentVersion\\Themes\\Personalize",
1105 L
"AppsUseLightTheme", RRF_RT_REG_DWORD, NULL, buffer, &bufferSize);
1106 if (resultRegGetValue != ERROR_SUCCESS)
1112 int i = (
int)(buffer[3] << 24 | buffer[2] << 16 | buffer[1] << 8 | buffer[0]);
1119- (BOOL) atDesktopResolution
1121 return atDesktopResolution;
1131- (BOOL) isOutputDisplayHDREnabled
1133 UINT32 pathCount, modeCount;
1134 DISPLAYCONFIG_PATH_INFO *pPathInfoArray;
1135 DISPLAYCONFIG_MODE_INFO *pModeInfoArray;
1136 UINT32 flags = QDC_ONLY_ACTIVE_PATHS | QDC_VIRTUAL_MODE_AWARE;
1137 LONG tempResult = ERROR_SUCCESS;
1138 BOOL isAdvColorInfo2DetectionSuccess = NO;
1144 tempResult = GetDisplayConfigBufferSizes(flags, &pathCount, &modeCount);
1146 if (tempResult != ERROR_SUCCESS)
1148 OOLog(
@"gameView.isOutputDisplayHDREnabled",
@"Error! Code: %d", HRESULT_FROM_WIN32(tempResult));
1153 pPathInfoArray = (DISPLAYCONFIG_PATH_INFO *)malloc(pathCount *
sizeof(DISPLAYCONFIG_PATH_INFO));
1154 if (!pPathInfoArray)
1156 OOLog(
@"gameView.isOutputDisplayHDREnabled",
@"Error! Code: -1");
1160 pModeInfoArray = (DISPLAYCONFIG_MODE_INFO *)malloc(modeCount *
sizeof(DISPLAYCONFIG_MODE_INFO));
1161 if (!pModeInfoArray)
1164 free(pPathInfoArray);
1165 OOLog(
@"gameView.isOutputDisplayHDREnabled",
@"Error! Code: -1");
1170 tempResult = QueryDisplayConfig(flags, &pathCount, pPathInfoArray, &modeCount, pModeInfoArray, NULL);
1172 if (tempResult != ERROR_SUCCESS)
1174 OOLog(
@"gameView.isOutputDisplayHDREnabled",
@"Error! Code: %d", HRESULT_FROM_WIN32(tempResult));
1179 pPathInfoArray = realloc(pPathInfoArray, pathCount *
sizeof(DISPLAYCONFIG_PATH_INFO));
1180 if (!pPathInfoArray)
1182 OOLogERR(
@"gameView.isOutputDisplayHDREnabled",
@"Failed ro reallocate pPathInfoArray");
1185 pModeInfoArray = realloc(pModeInfoArray, modeCount *
sizeof(DISPLAYCONFIG_MODE_INFO));
1186 if (!pModeInfoArray)
1188 OOLogERR(
@"gameView.isOutputDisplayHDREnabled",
@"Failed to reallocate pModeInfoArray");
1194 }
while (tempResult == ERROR_INSUFFICIENT_BUFFER);
1196 if (tempResult != ERROR_SUCCESS)
1198 OOLog(
@"gameView.isOutputDisplayHDREnabled",
@"Error! Code: %d", HRESULT_FROM_WIN32(tempResult));
1204 wchar_t wcsPrimaryDeviceID[256] = L
"OOUnknownDevice";
1209 for (i = 0; i < pathCount; i++)
1212 char saveDeviceName[64];
1214 ZeroMemory(&dd,
sizeof(dd));
1216 EnumDisplayDevices(NULL, i, &dd, 0);
1217 if (dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE)
1220 strncpy(saveDeviceName, dd.DeviceName, 33);
1221 while (EnumDisplayDevices(saveDeviceName, j, &dd, 0x00000001))
1223 if (
EXPECT(dd.StateFlags & DISPLAY_DEVICE_ACTIVE))
1226 mbstowcs(wcsPrimaryDeviceID, dd.DeviceID, 129);
1232 OOLogWARN(
@"gameView.isOutputDisplayHDREnabled",
@"Primary monitor candidate %s (%s %s) not active.", dd.DeviceName, dd.DeviceString, dd.DeviceID);
1242 for (i = 0; i < pathCount; i++)
1244 DISPLAYCONFIG_PATH_INFO *path = &pPathInfoArray[i];
1246 DISPLAYCONFIG_TARGET_DEVICE_NAME targetName = {};
1247 targetName.header.adapterId = path->targetInfo.adapterId;
1248 targetName.header.id = path->targetInfo.id;
1249 targetName.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_TARGET_NAME;
1250 targetName.header.size =
sizeof(targetName);
1251 tempResult = DisplayConfigGetDeviceInfo(&targetName.header);
1253 if (tempResult != ERROR_SUCCESS)
1255 OOLog(
@"gameView.isOutputDisplayHDREnabled",
@"Error! Code: %d", HRESULT_FROM_WIN32(tempResult));
1260 DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO_2 advColorInfo2 = {};
1261 advColorInfo2.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO_2;
1262 advColorInfo2.header.adapterId = path->targetInfo.adapterId;
1263 advColorInfo2.header.id = path->targetInfo.id;
1264 advColorInfo2.header.size =
sizeof(advColorInfo2);
1266 tempResult = DisplayConfigGetDeviceInfo(&advColorInfo2.header);
1268 if (tempResult == ERROR_SUCCESS) isAdvColorInfo2DetectionSuccess = YES;
1271 OOLogWARN(
@"gameView.isOutputDisplayHDREnabled",
@"Received 0x%08X while attempting to detect HDR mode using Advanced Color Info 2 API. Retrying detection using legacy API.", HRESULT_FROM_WIN32(tempResult));
1276 DISPLAYCONFIG_GET_ADVANCED_COLOR_INFO advColorInfo = {};
1277 advColorInfo.header.type = DISPLAYCONFIG_DEVICE_INFO_GET_ADVANCED_COLOR_INFO;
1278 advColorInfo.header.adapterId = path->targetInfo.adapterId;
1279 advColorInfo.header.id = path->targetInfo.id;
1280 advColorInfo.header.size =
sizeof(advColorInfo);
1282 tempResult = DisplayConfigGetDeviceInfo(&advColorInfo.header);
1284 if (tempResult != ERROR_SUCCESS)
1286 OOLog(
@"gameView.isOutputDisplayHDREnabled",
@"Error! Code: %d", HRESULT_FROM_WIN32(tempResult));
1290 BOOL isPrimaryDisplayDevice = !wcscmp(targetName.monitorDevicePath, wcsPrimaryDeviceID);
1293 if (isPrimaryDisplayDevice &&
1294 ((isAdvColorInfo2DetectionSuccess && advColorInfo2.highDynamicRangeSupported && advColorInfo2.activeColorMode == DISPLAYCONFIG_ADVANCED_COLOR_MODE_HDR) ||
1295 (!isAdvColorInfo2DetectionSuccess && advColorInfo.advancedColorSupported && advColorInfo.advancedColorEnabled && !advColorInfo.wideColorEnforced)))
1302 OOLog(
@"gameView.isOutputDisplayHDREnabled",
@"HDR display output requested - checking availability: %@", result ?
@"YES" :
@"NO");
1304 free (pModeInfoArray);
1305 free (pPathInfoArray);
1311- (float) hdrMaxBrightness
1313 return _hdrMaxBrightness;
1317- (void) setHDRMaxBrightness: (
float)newMaxBrightness
1321 _hdrMaxBrightness = newMaxBrightness;
1323 [[NSUserDefaults standardUserDefaults] setFloat:_hdrMaxBrightness forKey:@"hdr-max-brightness"];
1327- (float) hdrPaperWhiteBrightness
1329 return _hdrPaperWhiteBrightness;
1333- (void) setHDRPaperWhiteBrightness: (
float)newPaperWhiteBrightness
1337 _hdrPaperWhiteBrightness = newPaperWhiteBrightness;
1339 [[NSUserDefaults standardUserDefaults] setFloat:_hdrPaperWhiteBrightness forKey:@"hdr-paperwhite-brightness"];
1345 return _hdrToneMapper;
1353 _hdrToneMapper = newToneMapper;
1366- (void) grabMouseInsideGameWindow:(BOOL) value
1372- (void) stringToClipboard:(NSString *)stringToCopy
1384- (void) setWindowBorderless:(BOOL)borderless
1418- (void) initialiseGLWithSize:(NSSize) v_size
1424- (void) initialiseGLWithSize:(NSSize) v_size useVideoMode:(BOOL) v_mode
1430 OOLog(
@"display.initGL",
@"Requested a new surface of %d x %d, %@.", (
int)
viewSize.width, (
int)
viewSize.height,(
fullScreen ?
@"fullscreen" :
@"windowed"));
1431 SDL_GL_SwapBuffers();
1434 if (!updateContext)
return;
1437 settings.dmSize =
sizeof(DEVMODE);
1438 settings.dmDriverExtra = 0;
1439 EnumDisplaySettings(0, ENUM_CURRENT_SETTINGS, &settings);
1441 WINDOWPLACEMENT windowPlacement;
1442 windowPlacement.length =
sizeof(WINDOWPLACEMENT);
1443 GetWindowPlacement(SDL_Window, &windowPlacement);
1445 static BOOL lastWindowPlacementMaximized = NO;
1446 if (
fullScreen && (windowPlacement.showCmd == SW_SHOWMAXIMIZED))
1450 lastWindowPlacementMaximized = YES;
1454 if (lastWindowPlacementMaximized)
1456 windowPlacement.showCmd = SW_SHOWMAXIMIZED;
1463 (wasFullScreen && (settings.dmPelsWidth != [[[screenSizes objectAtIndex:0] objectForKey: kOODisplayWidth] intValue]
1464 || settings.dmPelsHeight != [[[screenSizes objectAtIndex:0] objectForKey: kOODisplayHeight] intValue])));
1476 [
self getCurrentMonitorInfo: &monitorInfo];
1478 settings.dmPelsWidth =
viewSize.width;
1479 settings.dmPelsHeight =
viewSize.height;
1480 settings.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
1485 if(lastWindowPlacementMaximized)
1487 CopyRect(&lastGoodRect, &windowPlacement.rcNormalPosition);
1489 windowPlacement.showCmd = SW_SHOWNORMAL;
1490 SetWindowPlacement(SDL_Window, &windowPlacement);
1492 else GetWindowRect(SDL_Window, &lastGoodRect);
1495 SetForegroundWindow(SDL_Window);
1496 if (changingResolution)
1498 if (ChangeDisplaySettingsEx(monitorInfo.szDevice, &settings, NULL, CDS_FULLSCREEN, NULL) != DISP_CHANGE_SUCCESSFUL)
1501 OOLogERR(
@"displayMode.change.error",
@"Could not switch to requested display mode.");
1504 atDesktopResolution = settings.dmPelsWidth == [[[screenSizes objectAtIndex:0] objectForKey: kOODisplayWidth] intValue]
1505 && settings.dmPelsHeight == [[[screenSizes objectAtIndex:0] objectForKey: kOODisplayHeight] intValue];
1508 MoveWindow(SDL_Window, monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top, (
int)
viewSize.width, (
int)
viewSize.height, TRUE);
1515 else if ( wasFullScreen )
1517 if (changingResolution)
1520 if (ChangeDisplaySettingsEx(NULL, NULL, NULL, 0, NULL) == DISP_CHANGE_SUCCESSFUL)
1522 atDesktopResolution = YES;
1534 [
self getCurrentMonitorInfo: &monitorInfo];
1536 if (lastWindowPlacementMaximized) CopyRect(&windowPlacement.rcNormalPosition, &lastGoodRect);
1537 SetWindowPlacement(SDL_Window, &windowPlacement);
1538 if (!lastWindowPlacementMaximized)
1540 MoveWindow(SDL_Window, (monitorInfo.rcMonitor.right - monitorInfo.rcMonitor.left - (
int)
viewSize.width)/2 +
1541 monitorInfo.rcMonitor.left,
1542 (monitorInfo.rcMonitor.bottom - monitorInfo.rcMonitor.top - (
int)
viewSize.height)/2 +
1543 monitorInfo.rcMonitor.top,
1549 lastWindowPlacementMaximized = NO;
1550 ShowWindow(SDL_Window,SW_SHOW);
1554 saveSize = !wasFullScreen;
1556 GetClientRect(SDL_Window, &wDC);
1559 ||
bounds.size.height != wDC.bottom - wDC.top))
1568 RECT desiredClientRect;
1569 GetWindowRect(SDL_Window, &desiredClientRect);
1570 AdjustWindowRect(&desiredClientRect, WS_CAPTION | WS_THICKFRAME, FALSE);
1571 SetWindowPos(SDL_Window, NULL, desiredClientRect.left, desiredClientRect.top,
1572 desiredClientRect.right - desiredClientRect.left,
1573 desiredClientRect.bottom - desiredClientRect.top, 0);
1575 GetClientRect(SDL_Window, &wDC);
1576 viewSize.width = wDC.right - wDC.left;
1577 viewSize.height = wDC.bottom - wDC.top;
1586 bounds.origin.x = monitorInfo.rcMonitor.left;
1587 bounds.origin.y = monitorInfo.rcMonitor.top;
1593 int videoModeFlags = SDL_HWSURFACE | SDL_OPENGL;
1596 videoModeFlags |= SDL_NOFRAME;
1599 videoModeFlags |= SDL_FULLSCREEN;
1603 videoModeFlags |= SDL_RESIZABLE;
1611 videoModeFlags &= ~SDL_FULLSCREEN;
1612 videoModeFlags |= SDL_RESIZABLE;
1619 OOLogERR(
@"display.mode.error",
@"Unable to change display mode: %s",SDL_GetError());
1627 OOLog(
@"display.initGL",
@"Created a new surface of %d x %d, %@.", (
int)
viewSize.width, (
int)
viewSize.height,(
fullScreen ?
@"fullscreen" :
@"windowed"));
1644 SDL_GL_SwapBuffers();
1657- (void) adjustColorSaturation:(
float)colorSaturationAdjustment;
1664- (BOOL) snapShot:(NSString *)filename
1666 BOOL snapShotOK = YES;
1667 SDL_Surface* tmpSurface;
1670 NSString* originalDirectory = [[
NSFileManager defaultManager] currentDirectoryPath];
1675 static unsigned imageNo = 0;
1676 unsigned tmpImageNo = 0;
1677 NSString *pathToPic =
nil;
1678 NSString *baseName =
@"oolite";
1680#if SNAPSHOTS_PNG_FORMAT
1681 NSString *extension =
@".png";
1683 NSString *extension =
@".bmp";
1689 pathToPic = [filename stringByAppendingString:extension];
1693 tmpImageNo = imageNo;
1696 if (withFilename && [[NSFileManager defaultManager] fileExistsAtPath:pathToPic])
1698 OOLog(
@"screenshot.filenameExists",
@"Snapshot \"%@%@\
" already exists - adding numerical sequence.", pathToPic, extension);
1702 if (pathToPic ==
nil)
1707 pathToPic = [
NSString stringWithFormat:@"%@-%03d%@", baseName, tmpImageNo, extension];
1708 }
while ([[NSFileManager defaultManager] fileExistsAtPath:pathToPic]);
1713 imageNo = tmpImageNo;
1716 OOLog(
@"screenshot",
@"Saving screen shot \"%@\
" (%u x %u pixels).", pathToPic,
surface->w,
surface->h);
1719 unsigned char *pixls = malloc(pitch *
surface->h);
1723 if (
surface->w % 4) glPixelStorei(GL_PACK_ALIGNMENT,1);
1724 else glPixelStorei(GL_PACK_ALIGNMENT,4);
1725 for (
y=
surface->h-1, off=0;
y>=0;
y--, off+=pitch)
1727 glReadPixels(0,
y,
surface->w, 1, GL_RGB, GL_UNSIGNED_BYTE, pixls + off);
1730 tmpSurface=SDL_CreateRGBSurfaceFrom(pixls,
surface->w,
surface->h,24,
surface->w*3,0xFF,0xFF00,0xFF0000,0x0);
1731#if SNAPSHOTS_PNG_FORMAT
1732 if(![
self pngSaveSurface:pathToPic withSurface:tmpSurface])
1734 OOLog(
@"screenshotPNG",
@"Failed to save %@", pathToPic);
1738 if (SDL_SaveBMP(tmpSurface, [pathToPic UTF8String]) == -1)
1740 OOLog(
@"screenshotBMP",
@"Failed to save %@", pathToPic);
1744 SDL_FreeSurface(tmpSurface);
1750 NSString *fileExtension = [[
NSUserDefaults standardUserDefaults] oo_stringForKey:@"hdr-snapshot-format" defaultValue:SNAPSHOTHDR_EXTENSION_DEFAULT];
1753 if (![[fileExtension substringToIndex:1] isEqual:
@"."]) fileExtension = [@"."
stringByAppendingString:fileExtension];
1761 NSString *pathToPicHDR = [
pathToPic stringByReplacingString:@".png" withString:fileExtension];
1762 OOLog(
@"screenshot",
@"Saving screen shot \"%@\
" (%u x %u pixels).", pathToPicHDR,
surface->w,
surface->h);
1763 GLfloat *pixlsf = (GLfloat *)malloc(pitch *
surface->h *
sizeof(GLfloat));
1764 for (
y=
surface->h-1, off=0;
y>=0;
y--, off+=pitch)
1766 glReadPixels(0,
y,
surface->w, 1, GL_RGB, GL_FLOAT, pixlsf + off);
1772 OOLog(
@"screenshotHDR",
@"Failed to save %@", pathToPicHDR);
1780 [[
NSFileManager defaultManager] changeCurrentDirectoryPath:originalDirectory];
1785#if SNAPSHOTS_PNG_FORMAT
1787- (BOOL) pngSaveSurface:(NSString *)fileName withSurface:(SDL_Surface *)surf
1793 png_bytep *rowPointers;
1795 fp = fopen([fileName UTF8String],
"wb");
1798 OOLog(
@"pngSaveSurface.fileCreate.failed",
@"Failed to create output screenshot file %@", fileName);
1803 pngPtr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1809 infoPtr = png_create_info_struct(pngPtr);
1810 if (infoPtr == NULL) {
1811 png_destroy_write_struct(&pngPtr, (png_infopp)NULL);
1812 OOLog(
@"pngSaveSurface.info_struct.failed",
@"%@",
@"png_create_info_struct error");
1816 if (setjmp(png_jmpbuf(pngPtr)))
1818 png_destroy_write_struct(&pngPtr, &infoPtr);
1823 png_init_io(pngPtr, fp);
1825 colorType = PNG_COLOR_MASK_COLOR;
1826 if (surf->format->palette)
1828 colorType |= PNG_COLOR_MASK_PALETTE;
1830 else if (surf->format->Amask)
1832 colorType |= PNG_COLOR_MASK_ALPHA;
1835 png_set_IHDR(pngPtr, infoPtr, surf->w, surf->h, 8, colorType, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
1839 if ([
self hdrOutput]) png_set_gAMA(pngPtr, infoPtr, 1.0f);
1842 png_write_info(pngPtr, infoPtr);
1843 png_set_packing(pngPtr);
1845 rowPointers = (png_bytep*) malloc(
sizeof(png_bytep)*surf->h);
1846 for (i = 0; i < surf->h; i++)
1848 rowPointers[
i] = (png_bytep)(Uint8 *)surf->pixels + i*surf->pitch;
1850 png_write_image(pngPtr, rowPointers);
1851 png_write_end(pngPtr, infoPtr);
1854 png_destroy_write_struct(&pngPtr, &infoPtr);
1863- (
int) translateKeyCode: (
int) input
1868 case NSUpArrowFunctionKey:
1872 case NSDownArrowFunctionKey:
1876 case NSLeftArrowFunctionKey:
1880 case NSRightArrowFunctionKey:
1884 case NSF1FunctionKey:
1888 case NSF2FunctionKey:
1892 case NSF3FunctionKey:
1896 case NSF4FunctionKey:
1900 case NSF5FunctionKey:
1904 case NSF6FunctionKey:
1908 case NSF7FunctionKey:
1912 case NSF8FunctionKey:
1916 case NSF9FunctionKey:
1920 case NSF10FunctionKey:
1924 case NSF11FunctionKey:
1928 case NSHomeFunctionKey:
1939- (void) setVirtualJoystick:(
double) vmx :(
double) vmy
1958 for (i = 0; i < [
self numKeys]; i++)
1965 keys[gvMouseDoubleClick] = NO;
1966 keys[gvMouseLeftButton] = NO;
1971- (void) clearKey: (
int)theKey
1973 if (theKey >= 0 && theKey < [
self numKeys])
1982 [
self setVirtualJoystick:0.0 :0.0];
2015- (BOOL) isDown: (
int) key
2059 return (SDL_GetModState() & KMOD_CAPS) == KMOD_CAPS;
2091- (void) setMouseWheelDelta: (
float) newWheelDelta
2118 SDL_KeyboardEvent *kbd_event;
2119 SDL_MouseButtonEvent *mbtn_event;
2120 SDL_MouseMotionEvent *mmove_event;
2121 int mxdelta, mydelta;
2124 NSTimeInterval timeNow = [
NSDate timeIntervalSinceReferenceDate];
2128 while (SDL_PollEvent(&event))
2130 switch (event.type) {
2131 case SDL_JOYAXISMOTION:
2132 case SDL_JOYBUTTONUP:
2133 case SDL_JOYBUTTONDOWN:
2134 case SDL_JOYHATMOTION:
2138 case SDL_MOUSEBUTTONDOWN:
2139 mbtn_event = (SDL_MouseButtonEvent*)&event;
2144 short inDelta = mbtn_event->wheelDelta;
2146 switch(mbtn_event->button)
2148 case SDL_BUTTON_LEFT:
2149 keys[gvMouseLeftButton] = YES;
2151 case SDL_BUTTON_RIGHT:
2163 case SDL_BUTTON_WHEELUP:
2166 case SDL_BUTTON_WHEELDOWN:
2169 case SDL_BUTTON_WHEELUP:
2170 case SDL_BUTTON_WHEELDOWN:
2179 else if (inDelta < 0)
2190 case SDL_MOUSEBUTTONUP:
2191 mbtn_event = (SDL_MouseButtonEvent*)&event;
2194 if (mbtn_event->button == SDL_BUTTON_LEFT)
2201 keys[gvMouseLeftButton] = NO;
2209 if (mbtn_event->button == SDL_BUTTON_WHEELUP || mbtn_event->button == SDL_BUTTON_WHEELDOWN)
2216 case SDL_MOUSEMOTION:
2229 SDL_GetRelativeMouseState(&mxdelta, &mydelta);
2230 double mxd=(double)mxdelta / mouseVirtualStickSensitivityX;
2231 double myd=(double)mydelta / mouseVirtualStickSensitivityY;
2260 mmove_event = (SDL_MouseMotionEvent*)&event;
2263 int h=
bounds.size.height;
2267 double mx = mmove_event->x - w/2.0;
2268 double my = mmove_event->y - h/2.0;
2280 [
self setVirtualJoystick:mx :my];
2291 kbd_event = (SDL_KeyboardEvent*)&event;
2292 key_id = (Uint16)kbd_event->keysym.unicode;
2293 scan_code = kbd_event->keysym.scancode;
2297 BOOL modifier_pressed = NO;
2298 BOOL special_key = NO;
2301 switch (kbd_event->keysym.sym)
2306 modifier_pressed = YES;
2312 modifier_pressed = YES;
2318 modifier_pressed = YES;
2338 case SDLK_HOME: key_id =
gvHomeKey; special_key = YES;
break;
2339 case SDLK_END: key_id =
gvEndKey; special_key = YES;
break;
2340 case SDLK_INSERT: key_id =
gvInsertKey; special_key = YES;
break;
2341 case SDLK_PAGEUP: key_id =
gvPageUpKey; special_key = YES;
break;
2342 case SDLK_PAGEDOWN: key_id =
gvPageDownKey; special_key = YES;
break;
2343 case SDLK_SPACE: key_id = 32; special_key = YES;
break;
2344 case SDLK_RETURN: key_id = 13; special_key = YES;
break;
2345 case SDLK_TAB: key_id = 9; special_key = YES;
break;
2346 case SDLK_UP: key_id =
gvArrowKeyUp; special_key = YES;
break;
2347 case SDLK_DOWN: key_id =
gvArrowKeyDown; special_key = YES;
break;
2348 case SDLK_LEFT: key_id =
gvArrowKeyLeft; special_key = YES;
break;
2350 case SDLK_PAUSE: key_id =
gvPauseKey; special_key = YES;
break;
2351 case SDLK_BACKSPACE: key_id =
gvBackspaceKey; special_key = YES;
break;
2352 case SDLK_DELETE: key_id =
gvDeleteKey; special_key = YES;
break;
2391 if (
ctrl && key_id >=1 && key_id <= 26)
2411 NSString *keyNormal = [keyMappings_normal objectForKey:[
NSString stringWithFormat:@"%d", scan_code]];
2412 if (keyNormal) key_id = [
keyNormal integerValue];
2416 NSString *keyShifted = [keyMappings_shifted objectForKey:[
NSString stringWithFormat:@"%d", scan_code]];
2417 if (keyShifted) key_id = [
keyShifted integerValue];
2429 OOLog(
kOOLogKeyDown,
@"Keydown scancode = %d, unicode = %i, sym = %i, character = %c, shift = %d, ctrl = %d, alt = %d", scan_code, key_id, kbd_event->keysym.sym, key_id,
shift,
ctrl,
opt);
2432 if (key_id > 0 && key_id <= [
self numKeys])
2444 kbd_event = (SDL_KeyboardEvent*)&event;
2445 scan_code = kbd_event->keysym.scancode;
2451 switch (kbd_event->keysym.sym)
2470 OOLog(
kOOLogKeyUp,
@"Keyup scancode = %d, unicode = %i, sym = %i, character = %c, shift = %d, ctrl = %d, alt = %d", scan_code, key_id, kbd_event->keysym.sym, key_id,
shift,
ctrl,
opt);
2474 switch (kbd_event->keysym.sym)
2493 case SDLK_HOME: key_id =
gvHomeKey;
break;
2494 case SDLK_END: key_id =
gvEndKey;
break;
2498 case SDLK_SPACE: key_id = 32;
break;
2499 case SDLK_RETURN: key_id = 13;
break;
2500 case SDLK_TAB: key_id = 9;
break;
2501 case SDLK_ESCAPE: key_id = 27;
break;
2518 case SDLK_F12: key_id = 327;
break;
2527 if (key_id > 0 && key_id <= [
self numKeys])
2537 case SDL_VIDEORESIZE:
2539 SDL_ResizeEvent *rsevt=(SDL_ResizeEvent *)&event;
2540 NSSize newSize=NSMakeSize(rsevt->w, rsevt->h);
2576 case SDL_ACTIVEEVENT:
2578 if ((event.active.state & SDL_APPACTIVE) &&
fullScreen)
2589 case SDL_SYSWMEVENT:
2591 DWORD dwLastError = 0;
2592 switch (event.syswm.msg->msg)
2594 case WM_WINDOWPOSCHANGING:
2614 wp.length =
sizeof(WINDOWPLACEMENT);
2615 GetWindowPlacement(SDL_Window, &wp);
2617 GetWindowRect(SDL_Window, &rDC);
2618 if (rDC.left != monitorInfo.rcMonitor.left || rDC.top != monitorInfo.rcMonitor.top)
2620 BOOL fullScreenMaximized = NO;
2621 if (wp.showCmd == SW_SHOWMAXIMIZED && !fullScreenMaximized)
2623 fullScreenMaximized = YES;
2624 wp.showCmd = SW_SHOWNORMAL;
2625 SetWindowPlacement(SDL_Window, &wp);
2628 if (wp.showCmd != SW_SHOWMINIMIZED && wp.showCmd != SW_MINIMIZE)
2630 MoveWindow(SDL_Window, monitorInfo.rcMonitor.left, monitorInfo.rcMonitor.top,
2634 if (fullScreenMaximized)
2636 GetWindowPlacement(SDL_Window, &wp);
2637 wp.showCmd = SW_SHOWMAXIMIZED;
2638 CopyRect(&wp.rcNormalPosition, &lastGoodRect);
2639 SetWindowPlacement(SDL_Window, &wp);
2642 else if (wp.showCmd == SW_SHOWMAXIMIZED)
2644 CopyRect(&wp.rcNormalPosition, &lastGoodRect);
2645 SetWindowPlacement(SDL_Window, &wp);
2660 case WM_ACTIVATEAPP:
2664 case WM_SETTINGCHANGE:
2674 [
self refreshDarKOrLightMode];
2686 if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL))
2688 dwLastError = GetLastError();
2689 OOLog(
@"wm_setfocus.message",
@"Setting thread priority to time critical failed! (error code: %d)", dwLastError);
2694 if (!SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL))
2696 dwLastError = GetLastError();
2697 OOLog(
@"wm_killfocus.message",
@"Setting thread priority to normal failed! (error code: %d)", dwLastError);
2728- (void) handleStringInput: (SDL_KeyboardEvent *) kbd_event keyID:(Uint16)key_id;
2730 SDLKey key=kbd_event->keysym.sym;
2733 if((key == SDLK_BACKSPACE || key == SDLK_DELETE) && [typedString length] > 0)
2739 isAlphabetKeyDown=NO;
2742 if([typedString length] < 40)
2744 lastKeyShifted = shift;
2748 if(key >= SDLK_a && key <= SDLK_z)
2750 isAlphabetKeyDown=YES;
2759 if (key_id >= 32 && key_id <= 255)
2763 isAlphabetKeyDown=YES;
2777 NSMutableDictionary *
mode;
2784 [screenSizes addObject: mode];
2786 modes=SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_HWSURFACE);
2787 if(modes == (SDL_Rect **)NULL)
2789 OOLog(
@"display.mode.list.none",
@"%@",
@"SDL didn't return any screen modes");
2793 if(modes == (SDL_Rect **)-1)
2795 OOLog(
@"display.mode.list.none",
@"%@",
@"SDL claims 'all resolutions available' which is unhelpful in the extreme");
2799 int lastw=[[mode objectForKey: kOODisplayWidth] intValue];
2800 int lasth=[[mode objectForKey: kOODisplayHeight] intValue];
2801 for(i=0; modes[
i]; i++)
2807 if(modes[i]->w != lastw || modes[i]->h != lasth)
2811 [mode setValue: [
NSNumber numberWithInt: (int)modes[
i]->w]
2812 forKey: kOODisplayWidth];
2813 [mode setValue: [
NSNumber numberWithInt: (int)modes[
i]->h]
2814 forKey: kOODisplayHeight];
2815 [mode setValue: [
NSNumber numberWithInt: 0]
2816 forKey: kOODisplayRefreshRate];
2819 [screenSizes addObject: mode];
2820 OOLog(
@"display.mode.list",
@"Added res %d x %d", modes[i]->w, modes[i]->h);
2830- (void) saveWindowSize: (NSSize) windowSize
2833 [
defaults setInteger: (int)windowSize.width forKey: @"window_width"];
2834 [
defaults setInteger: (int)windowSize.height forKey: @"window_height"];
2843 if([defaults objectForKey:
@"window_width"] && [defaults objectForKey:
@"window_height"])
2845 windowSize=NSMakeSize([defaults integerForKey:
@"window_width"],
2846 [defaults integerForKey:
@"window_height"]);
2860 int width=0, height=0, refresh=0;
2863 NSArray* cmdline_arguments = [[
NSProcessInfo processInfo] arguments];
2865 NSUserDefaults *userDefaults = [
NSUserDefaults standardUserDefaults];
2866 if ([userDefaults objectForKey:
@"display_width"])
2868 if ([userDefaults objectForKey:
@"display_height"])
2869 height = [
userDefaults integerForKey:@"display_height"];
2870 if ([userDefaults objectForKey:
@"display_refresh"])
2871 refresh = [
userDefaults integerForKey:@"display_refresh"];
2872 if([userDefaults objectForKey:
@"fullscreen"])
2880 if ([[cmdline_arguments objectAtIndex:i] isEqual:
@"-fullscreen"])
fullScreen = YES;
2881 if ([[cmdline_arguments objectAtIndex:i] isEqual:
@"-windowed"])
fullScreen = NO;
2893- (
int) findDisplayModeForWidth:(
unsigned int) d_width Height:(
unsigned int) d_height Refresh:(
unsigned int) d_refresh
2897 unsigned int modeWidth, modeHeight, modeRefresh;
2899 modeCount = [screenSizes count];
2901 for (i = 0; i < modeCount; i++)
2903 mode = [screenSizes objectAtIndex: i];
2904 modeWidth = [[mode objectForKey: kOODisplayWidth] intValue];
2905 modeHeight = [[mode objectForKey: kOODisplayHeight] intValue];
2906 modeRefresh = [[mode objectForKey: kOODisplayRefreshRate] intValue];
2907 if ((modeWidth == d_width)&&(modeHeight == d_height)&&(modeRefresh == d_refresh))
2909 OOLog(
@"display.mode.found",
@"Found mode %@",
mode);
2914 OOLog(
@"display.mode.found.failed",
@"Failed to find mode: width=%d height=%d refresh=%d", d_width, d_height, d_refresh);
2915 OOLog(
@"display.mode.found.failed.list",
@"Contents of list: %@",
screenSizes);
2922 NSDictionary *
mode=[screenSizes objectAtIndex: currentSize];
2929 OOLog(
@"display.mode.unknown",
@"%@",
@"Screen size unknown!");
2934- (void) setMouseInDeltaMode: (BOOL) inDelta
2940- (void) setGammaValue: (
float) value
2942 if (value < 0.2f) value = 0.2f;
2943 if (value > 4.0f) value = 4.0f;
2948 [[
NSUserDefaults standardUserDefaults] setFloat:_gamma forKey:@"gamma-value"];
2958- (void) setFov:(
float)value fromFraction:(BOOL)fromFraction
2960 _fov = fromFraction ? value : tan((value / 2) *
M_PI / 180);
2964- (float) fov:(BOOL)inFraction
2966 return inFraction ?
_fov : 2 * atan(
_fov) * 180 /
M_PI;
2976- (void) setMsaa:(BOOL)newMsaa
2990 return 0 != (SDL_GetModState() & (KMOD_LSHIFT | KMOD_RSHIFT));
2995- (void) dumpRGBAToFileNamed:(NSString *)name
2996 bytes:(uint8_t *)bytes
2997 width:(NSUInteger)width
2998 height:(NSUInteger)height
2999 rowBytes:(NSUInteger)rowBytes
3001 if (name ==
nil || bytes == NULL || width == 0 || height == 0 || rowBytes < width * 4)
return;
3004 NSString *dumpFile = [[
NSHomeDirectory() stringByAppendingPathComponent:@SAVEDIR] stringByAppendingPathComponent:@SNAPSHOTDIR];
3005 dumpFile = [
dumpFile stringByAppendingPathComponent: [
NSString stringWithFormat:@"%@.bmp", name]];
3008 SDL_Surface* tmpSurface = SDL_CreateRGBSurfaceFrom(bytes, width, height, 32, rowBytes, 0xFF, 0xFF00, 0xFF0000, 0xFF000000);
3009 SDL_SaveBMP(tmpSurface, [dumpFile UTF8String]);
3010 SDL_FreeSurface(tmpSurface);
3014- (void) dumpRGBToFileNamed:(NSString *)name
3015 bytes:(uint8_t *)bytes
3016 width:(NSUInteger)width
3017 height:(NSUInteger)height
3018 rowBytes:(NSUInteger)rowBytes
3020 if (name ==
nil || bytes == NULL || width == 0 || height == 0 || rowBytes < width * 3)
return;
3023 NSString *dumpFile = [[
NSHomeDirectory() stringByAppendingPathComponent:@SAVEDIR] stringByAppendingPathComponent:@SNAPSHOTDIR];
3024 dumpFile = [
dumpFile stringByAppendingPathComponent: [
NSString stringWithFormat:@"%@.bmp", name]];
3026 SDL_Surface* tmpSurface = SDL_CreateRGBSurfaceFrom(bytes, width, height, 24, rowBytes, 0xFF, 0xFF00, 0xFF0000, 0x0);
3027 SDL_SaveBMP(tmpSurface, [dumpFile UTF8String]);
3028 SDL_FreeSurface(tmpSurface);
3032- (void) dumpGrayToFileNamed:(NSString *)name
3033 bytes:(uint8_t *)bytes
3034 width:(NSUInteger)width
3035 height:(NSUInteger)height
3036 rowBytes:(NSUInteger)rowBytes
3038 if (name ==
nil || bytes == NULL || width == 0 || height == 0 || rowBytes < width)
return;
3041 NSString *dumpFile = [[
NSHomeDirectory() stringByAppendingPathComponent:@SAVEDIR] stringByAppendingPathComponent:@SNAPSHOTDIR];
3042 dumpFile = [
dumpFile stringByAppendingPathComponent: [
NSString stringWithFormat:@"%@.bmp", name]];
3044 SDL_Surface* tmpSurface = SDL_CreateRGBSurfaceFrom(bytes, width, height, 8, rowBytes, 0xFF, 0xFF, 0xFF, 0x0);
3045 SDL_SaveBMP(tmpSurface, [dumpFile UTF8String]);
3046 SDL_FreeSurface(tmpSurface);
3050- (void) dumpGrayAlphaToFileNamed:(NSString *)name
3051 bytes:(uint8_t *)bytes
3052 width:(NSUInteger)width
3053 height:(NSUInteger)height
3054 rowBytes:(NSUInteger)rowBytes
3056 if (name ==
nil || bytes == NULL || width == 0 || height == 0 || rowBytes < width * 2)
return;
3059 NSString *dumpFile = [[
NSHomeDirectory() stringByAppendingPathComponent:@SAVEDIR] stringByAppendingPathComponent:@SNAPSHOTDIR];
3060 dumpFile = [
dumpFile stringByAppendingPathComponent: [
NSString stringWithFormat:@"%@.bmp", name]];
3062 SDL_Surface* tmpSurface = SDL_CreateRGBSurfaceFrom(bytes, width, height, 16, rowBytes, 0xFF, 0xFF, 0xFF, 0xFF);
3063 SDL_SaveBMP(tmpSurface, [dumpFile UTF8String]);
3064 SDL_FreeSurface(tmpSurface);
3068- (void) dumpRGBAToRGBFileNamed:(NSString *)rgbName
3069 andGrayFileNamed:(NSString *)grayName
3070 bytes:(uint8_t *)bytes
3071 width:(NSUInteger)width
3072 height:(NSUInteger)height
3073 rowBytes:(NSUInteger)rowBytes
3075 if ((rgbName ==
nil && grayName ==
nil) || bytes == NULL || width == 0 || height == 0 || rowBytes < width * 4)
return;
3077 uint8_t *rgbBytes, *rgbPx, *grayBytes, *grayPx, *srcPx;
3079 BOOL trivalAlpha = YES;
3081 rgbPx = rgbBytes = malloc(width * height * 3);
3082 if (rgbBytes == NULL)
return;
3084 grayPx = grayBytes = malloc(width * height);
3085 if (grayBytes == NULL)
3091 for (
y = 0;
y < height;
y++)
3093 srcPx = bytes + rowBytes *
y;
3095 for (
x = 0;
x < width;
x++)
3097 *rgbPx++ = *srcPx++;
3098 *rgbPx++ = *srcPx++;
3099 *rgbPx++ = *srcPx++;
3100 trivalAlpha = trivalAlpha && ((*srcPx == 0xFF) || (*srcPx == 0x00));
3101 *grayPx++ = *srcPx++;
static NSString * kOOLogKeyDown
static NSString * kOOLogKeyUp
#define MAIN_GUI_PIXEL_WIDTH
#define MAIN_GUI_PIXEL_HEIGHT
OOSDRToneMapper OOSDRToneMapperFromString(NSString *string)
OOHDRToneMapper OOHDRToneMapperFromString(NSString *string)
#define OOLogWARN(class, format,...)
#define OOLogERR(class, format,...)
#define OOLog(class, format,...)
#define OOVerifyOpenGLState()
#define OOSetOpenGLState(STATE)
int SaveEXRSnapshot(const char *outfilename, int width, int height, const float *rgb)
#define MOUSE_DOUBLE_CLICK_INTERVAL
#define SNAPSHOTHDR_EXTENSION_HDR
@ OOHDR_TONEMAPPER_REINHARD
#define MAX_COLOR_SATURATION
@ OOSDR_TONEMAPPER_REINHARD
#define SNAPSHOTHDR_EXTENSION_DEFAULT
#define OOMOUSEWHEEL_EVENTS_DELAY_INTERVAL
#define WINDOW_SIZE_DEFAULT_HEIGHT
#define MIN_HDR_MAXBRIGHTNESS
#define MIN_HDR_PAPERWHITE
#define WINDOW_SIZE_DEFAULT_WIDTH
#define OOMOUSEWHEEL_DELTA
#define SNAPSHOTHDR_EXTENSION_EXR
#define MAX_HDR_MAXBRIGHTNESS
#define MAX_HDR_PAPERWHITE
int SaveEXRSnapshot(const char *outfilename, int width, int height, const float *rgb)
void resetSDLKeyModifiers()
void setUpBasicOpenGLStateWithSize:(NSSize viewSize)
void exitAppWithContext:(NSString *context)
BOOL m_glContextInitialized
void saveWindowSize:(NSSize windowSize)
void initialiseGLWithSize:(NSSize v_size)
void grabMouseInsideGameWindow:(BOOL value)
void handleStringInput:keyID:(SDL_KeyboardEvent *kbd_event, [keyID] Uint16 key_id)
void setFullScreenMode:(BOOL fsm)
void suppressKeysUntilKeyUp()
BOOL isOutputDisplayHDREnabled()
void drawRect:(NSRect rect)
void initKeyMappingData()
int loadFullscreenSettings()
NSMutableDictionary * getNativeSize()
NSDictionary * keyMappings_shifted
float _mouseVirtualStickSensitivityFactor
void populateFullScreenModelist()
int findDisplayModeForWidth:Height:Refresh:(unsigned int d_width,[Height] unsigned int d_height,[Refresh] unsigned int d_refresh)
NSMutableString * typedString
NSMutableArray * screenSizes
int scancode2Unicode[NUM_KEYS]
void setMouseInDeltaMode:(BOOL inDelta)
void initialiseGLWithSize:useVideoMode:(NSSize v_size,[useVideoMode] BOOL v_mode)
NSPoint virtualJoystickPosition
BOOL isRunningOnPrimaryDisplayDevice()
void setWindowBorderless:(BOOL borderless)
OOOpenGLMatrixManager * getOpenGLMatrixManager()
NSTimeInterval timeSinceLastMouseWheel
OOOpenGLMatrixManager * matrixManager
NSTimeInterval timeIntervalAtLastClick
NSSize currentScreenSize()
void updateScreenWithVideoMode:(BOOL v_mode)
void resetSDLKeyModifiers()
void dumpGrayToFileNamed:bytes:width:height:rowBytes:(NSString *name,[bytes] uint8_t *bytes,[width] NSUInteger width,[height] NSUInteger height,[rowBytes] NSUInteger rowBytes)
OOSDRToneMapper sdrToneMapper()
void dumpRGBToFileNamed:bytes:width:height:rowBytes:(NSString *name,[bytes] uint8_t *bytes,[width] NSUInteger width,[height] NSUInteger height,[rowBytes] NSUInteger rowBytes)
NSDictionary * keyMappings_normal
GameController * gameController
BOOL setStickHandlerClass:(Class aClass)
void orthoLeft:right:bottom:top:near:far:(double l,[right] double r,[bottom] double b,[top] double t,[near] double n,[far] double f)
BOOL handleSDLEvent:(SDL_Event *evt)
void doGuiScreenResizeUpdates()
PlayerEntity * sharedPlayer()
NSDictionary * dictionaryFromFilesNamed:inFolder:mergeMode:cache:(NSString *fileName,[inFolder] NSString *folderName,[mergeMode] OOResourceMergeMode mergeMode,[cache] BOOL useCache)
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data)