From d8cccc7f9a96dc0d2f02646d6e20087968e5d7d0 Mon Sep 17 00:00:00 2001 From: Robert Konrad Date: Fri, 6 Dec 2013 15:47:17 +0100 Subject: [PATCH] Implemented support for changing resolutions and going fullscreen. --- project/include/Display.h | 2 + project/include/Utils.h | 50 ++++ project/src/backend/sdl2/SDL2Stage.cpp | 273 ++++++++++++++++++++++ project/src/common/ExternalInterface.cpp | 81 ++++++- project/src/platform/winrt/WinRTStage.cpp | 13 ++ 5 files changed, 417 insertions(+), 2 deletions(-) diff --git a/project/include/Display.h b/project/include/Display.h index d2b39ff2d..aba66802d 100644 --- a/project/include/Display.h +++ b/project/include/Display.h @@ -427,6 +427,8 @@ public: virtual void setOpaqueBackground(uint32 inBG); DisplayObject *HitTest(UserPoint inPoint,DisplayObject *inRoot=0,bool inRecurse=true); virtual void SetFullscreen(bool inFullscreen) { } + virtual void SetResolution(int inWidth, int inHeight) { } + virtual void SetScreenMode(ScreenMode mode) { } virtual void ShowCursor(bool inShow) { }; virtual void SetCursor(Cursor inCursor)=0; virtual void EnablePopupKeyboard(bool inEnable) { } diff --git a/project/include/Utils.h b/project/include/Utils.h index 391d9b654..3de67d096 100644 --- a/project/include/Utils.h +++ b/project/include/Utils.h @@ -90,6 +90,55 @@ const std::string GetUniqueDeviceIdentifier(); const std::string &GetResourcePath(); +enum ScreenFormat +{ + PIXELFORMAT_UNKNOWN, + PIXELFORMAT_INDEX1LSB, + PIXELFORMAT_INDEX1MSB, + PIXELFORMAT_INDEX4LSB, + PIXELFORMAT_INDEX4MSB, + PIXELFORMAT_INDEX8, + PIXELFORMAT_RGB332, + PIXELFORMAT_RGB444, + PIXELFORMAT_RGB555, + PIXELFORMAT_BGR555, + PIXELFORMAT_ARGB4444, + PIXELFORMAT_RGBA4444, + PIXELFORMAT_ABGR4444, + PIXELFORMAT_BGRA4444, + PIXELFORMAT_ARGB1555, + PIXELFORMAT_RGBA5551, + PIXELFORMAT_ABGR1555, + PIXELFORMAT_BGRA5551, + PIXELFORMAT_RGB565, + PIXELFORMAT_BGR565, + PIXELFORMAT_RGB24, + PIXELFORMAT_BGR24, + PIXELFORMAT_RGB888, + PIXELFORMAT_RGBX8888, + PIXELFORMAT_BGR888, + PIXELFORMAT_BGRX8888, + PIXELFORMAT_ARGB8888, + PIXELFORMAT_RGBA8888, + PIXELFORMAT_ABGR8888, + PIXELFORMAT_BGRA8888, + PIXELFORMAT_ARGB2101010, + PIXELFORMAT_YV12, + PIXELFORMAT_IYUV, + PIXELFORMAT_YUY2, + PIXELFORMAT_UYVY, + PIXELFORMAT_YVYU +}; + +struct ScreenMode +{ + int width; + int height; + ScreenFormat format; + int refreshRate; +}; + + enum SpecialDir { DIR_APP, @@ -152,6 +201,7 @@ double CapabilitiesGetScreenDPI (); double CapabilitiesGetScreenResolutionX (); double CapabilitiesGetScreenResolutionY (); QuickVec* CapabilitiesGetScreenResolutions (); +QuickVec* CapabilitiesGetScreenModes (); std::string CapabilitiesGetLanguage(); diff --git a/project/src/backend/sdl2/SDL2Stage.cpp b/project/src/backend/sdl2/SDL2Stage.cpp index 9c3066e1b..51ee47b78 100644 --- a/project/src/backend/sdl2/SDL2Stage.cpp +++ b/project/src/backend/sdl2/SDL2Stage.cpp @@ -332,7 +332,148 @@ public: } } } + + + void SetResolution(int inWidth, int inHeight) + { + fprintf(stderr, "SetResolution %i %i\n", inWidth, inHeight); + SDL_DisplayMode mode; + SDL_GetCurrentDisplayMode(0, &mode); + fprintf(stderr, "Current %i %i\n", mode.w, mode.h); + mode.w = inWidth; + mode.h = inHeight; + SDL_SetWindowFullscreen(mSDLWindow, 0); + SDL_SetWindowDisplayMode(mSDLWindow, &mode); + SDL_SetWindowFullscreen(mSDLWindow, SDL_WINDOW_FULLSCREEN); + } + + void SetScreenMode(ScreenMode m) + { + if (m.width <= 1 || m.height <= 1) + { + fprintf(stderr, "Stop calling me\n"); + return; + } + SDL_DisplayMode mode; + mode.w = m.width; + mode.h = m.height; + mode.refresh_rate = m.refreshRate; + switch (m.format) { + case PIXELFORMAT_UNKNOWN: + mode.format = SDL_PIXELFORMAT_UNKNOWN; + break; + case PIXELFORMAT_INDEX1LSB: + mode.format = SDL_PIXELFORMAT_INDEX1LSB; + break; + case PIXELFORMAT_INDEX1MSB: + mode.format = SDL_PIXELFORMAT_INDEX1MSB; + break; + case PIXELFORMAT_INDEX4LSB: + mode.format = SDL_PIXELFORMAT_INDEX4LSB; + break; + case PIXELFORMAT_INDEX4MSB: + mode.format = SDL_PIXELFORMAT_INDEX4MSB; + break; + case PIXELFORMAT_INDEX8: + mode.format = SDL_PIXELFORMAT_INDEX8; + break; + case PIXELFORMAT_RGB332: + mode.format = SDL_PIXELFORMAT_RGB332; + break; + case PIXELFORMAT_RGB444: + mode.format = SDL_PIXELFORMAT_RGB444; + break; + case PIXELFORMAT_RGB555: + mode.format = SDL_PIXELFORMAT_RGB555; + break; + case PIXELFORMAT_BGR555: + mode.format = SDL_PIXELFORMAT_BGR555; + break; + case PIXELFORMAT_ARGB4444: + mode.format = SDL_PIXELFORMAT_ARGB4444; + break; + case PIXELFORMAT_RGBA4444: + mode.format = SDL_PIXELFORMAT_RGBA4444; + break; + case PIXELFORMAT_ABGR4444: + mode.format = SDL_PIXELFORMAT_ABGR4444; + break; + case PIXELFORMAT_BGRA4444: + mode.format = SDL_PIXELFORMAT_BGRA4444; + break; + case PIXELFORMAT_ARGB1555: + mode.format = SDL_PIXELFORMAT_ARGB1555; + break; + case PIXELFORMAT_RGBA5551: + mode.format = SDL_PIXELFORMAT_RGBA5551; + break; + case PIXELFORMAT_ABGR1555: + mode.format = SDL_PIXELFORMAT_ABGR1555; + break; + case PIXELFORMAT_BGRA5551: + mode.format = SDL_PIXELFORMAT_BGRA5551; + break; + case PIXELFORMAT_RGB565: + mode.format = SDL_PIXELFORMAT_RGB565; + break; + case PIXELFORMAT_BGR565: + mode.format = SDL_PIXELFORMAT_BGR565; + break; + case PIXELFORMAT_RGB24: + mode.format = SDL_PIXELFORMAT_RGB24; + break; + case PIXELFORMAT_BGR24: + mode.format = SDL_PIXELFORMAT_BGR24; + break; + case PIXELFORMAT_RGB888: + mode.format = SDL_PIXELFORMAT_RGB888; + break; + case PIXELFORMAT_RGBX8888: + mode.format = SDL_PIXELFORMAT_RGBX8888; + break; + case PIXELFORMAT_BGR888: + mode.format = SDL_PIXELFORMAT_BGR888; + break; + case PIXELFORMAT_BGRX8888: + mode.format = SDL_PIXELFORMAT_BGRX8888; + break; + case PIXELFORMAT_ARGB8888: + mode.format = SDL_PIXELFORMAT_ARGB8888; + break; + case PIXELFORMAT_RGBA8888: + mode.format = SDL_PIXELFORMAT_RGBA8888; + break; + case PIXELFORMAT_ABGR8888: + mode.format = SDL_PIXELFORMAT_ABGR8888; + break; + case PIXELFORMAT_BGRA8888: + mode.format = SDL_PIXELFORMAT_BGRA8888; + break; + case PIXELFORMAT_ARGB2101010: + mode.format = SDL_PIXELFORMAT_ARGB2101010; + break; + case PIXELFORMAT_YV12: + mode.format = SDL_PIXELFORMAT_YV12; + break; + case PIXELFORMAT_IYUV: + mode.format = SDL_PIXELFORMAT_IYUV; + break; + case PIXELFORMAT_YUY2: + mode.format = SDL_PIXELFORMAT_YUY2; + break; + case PIXELFORMAT_UYVY: + mode.format = SDL_PIXELFORMAT_UYVY; + break; + case PIXELFORMAT_YVYU: + mode.format = SDL_PIXELFORMAT_YVYU; + break; + } + SDL_SetWindowFullscreen(mSDLWindow, 0); + SDL_SetWindowDisplayMode(mSDLWindow, &mode); + SDL_SetWindowFullscreen(mSDLWindow, SDL_WINDOW_FULLSCREEN); + } + bool isOpenGL() const { return mOpenGLContext; } @@ -1419,6 +1560,138 @@ QuickVec* CapabilitiesGetScreenResolutions() } +QuickVec* CapabilitiesGetScreenModes() +{ + InitSDL(); + QuickVec *out = new QuickVec(); + + int numModes = SDL_GetNumDisplayModes(0); + SDL_DisplayMode mode; + + for (int i = 0; i < numModes; i++) + { + SDL_GetDisplayMode(0, i, &mode); + ScreenMode screenMode; + screenMode.width = mode.w; + screenMode.height = mode.h; + switch (mode.format) { + case SDL_PIXELFORMAT_UNKNOWN: + screenMode.format = PIXELFORMAT_UNKNOWN; + break; + case SDL_PIXELFORMAT_INDEX1LSB: + screenMode.format = PIXELFORMAT_INDEX1LSB; + break; + case SDL_PIXELFORMAT_INDEX1MSB: + screenMode.format = PIXELFORMAT_INDEX1MSB; + break; + case SDL_PIXELFORMAT_INDEX4LSB: + screenMode.format = PIXELFORMAT_INDEX4LSB; + break; + case SDL_PIXELFORMAT_INDEX4MSB: + screenMode.format = PIXELFORMAT_INDEX4MSB; + break; + case SDL_PIXELFORMAT_INDEX8: + screenMode.format = PIXELFORMAT_INDEX8; + break; + case SDL_PIXELFORMAT_RGB332: + screenMode.format = PIXELFORMAT_RGB332; + break; + case SDL_PIXELFORMAT_RGB444: + screenMode.format = PIXELFORMAT_RGB444; + break; + case SDL_PIXELFORMAT_RGB555: + screenMode.format = PIXELFORMAT_RGB555; + break; + case SDL_PIXELFORMAT_BGR555: + screenMode.format = PIXELFORMAT_BGR555; + break; + case SDL_PIXELFORMAT_ARGB4444: + screenMode.format = PIXELFORMAT_ARGB4444; + break; + case SDL_PIXELFORMAT_RGBA4444: + screenMode.format = PIXELFORMAT_RGBA4444; + break; + case SDL_PIXELFORMAT_ABGR4444: + screenMode.format = PIXELFORMAT_ABGR4444; + break; + case SDL_PIXELFORMAT_BGRA4444: + screenMode.format = PIXELFORMAT_BGRA4444; + break; + case SDL_PIXELFORMAT_ARGB1555: + screenMode.format = PIXELFORMAT_ARGB1555; + break; + case SDL_PIXELFORMAT_RGBA5551: + screenMode.format = PIXELFORMAT_RGBA5551; + break; + case SDL_PIXELFORMAT_ABGR1555: + screenMode.format = PIXELFORMAT_ABGR1555; + break; + case SDL_PIXELFORMAT_BGRA5551: + screenMode.format = PIXELFORMAT_BGRA5551; + break; + case SDL_PIXELFORMAT_RGB565: + screenMode.format = PIXELFORMAT_RGB565; + break; + case SDL_PIXELFORMAT_BGR565: + screenMode.format = PIXELFORMAT_BGR565; + break; + case SDL_PIXELFORMAT_RGB24: + screenMode.format = PIXELFORMAT_RGB24; + break; + case SDL_PIXELFORMAT_BGR24: + screenMode.format = PIXELFORMAT_BGR24; + break; + case SDL_PIXELFORMAT_RGB888: + screenMode.format = PIXELFORMAT_RGB888; + break; + case SDL_PIXELFORMAT_RGBX8888: + screenMode.format = PIXELFORMAT_RGBX8888; + break; + case SDL_PIXELFORMAT_BGR888: + screenMode.format = PIXELFORMAT_BGR888; + break; + case SDL_PIXELFORMAT_BGRX8888: + screenMode.format = PIXELFORMAT_BGRX8888; + break; + case SDL_PIXELFORMAT_ARGB8888: + screenMode.format = PIXELFORMAT_ARGB8888; + break; + case SDL_PIXELFORMAT_RGBA8888: + screenMode.format = PIXELFORMAT_RGBA8888; + break; + case SDL_PIXELFORMAT_ABGR8888: + screenMode.format = PIXELFORMAT_ABGR8888; + break; + case SDL_PIXELFORMAT_BGRA8888: + screenMode.format = PIXELFORMAT_BGRA8888; + break; + case SDL_PIXELFORMAT_ARGB2101010: + screenMode.format = PIXELFORMAT_ARGB2101010; + break; + case SDL_PIXELFORMAT_YV12: + screenMode.format = PIXELFORMAT_YV12; + break; + case SDL_PIXELFORMAT_IYUV: + screenMode.format = PIXELFORMAT_IYUV; + break; + case SDL_PIXELFORMAT_YUY2: + screenMode.format = PIXELFORMAT_YUY2; + break; + case SDL_PIXELFORMAT_UYVY: + screenMode.format = PIXELFORMAT_UYVY; + break; + case SDL_PIXELFORMAT_YVYU: + screenMode.format = PIXELFORMAT_YVYU; + break; + } + screenMode.refreshRate = mode.refresh_rate; + out->push_back(screenMode); + } + + return out; + } + + double CapabilitiesGetScreenResolutionX() { InitSDL(); diff --git a/project/src/common/ExternalInterface.cpp b/project/src/common/ExternalInterface.cpp index f7070e161..b82222e87 100644 --- a/project/src/common/ExternalInterface.cpp +++ b/project/src/common/ExternalInterface.cpp @@ -877,7 +877,7 @@ value lime_capabilities_get_screen_resolutions () { //Only really makes sense on PC platforms - #if defined( HX_WINDOWS ) || defined( HX_MACOS ) + #if defined( HX_WINDOWS ) || defined( HX_MACOS ) || defined( HX_LINUX ) QuickVec* res = CapabilitiesGetScreenResolutions(); @@ -902,6 +902,37 @@ value lime_capabilities_get_screen_resolutions () { DEFINE_PRIM( lime_capabilities_get_screen_resolutions, 0 ); +value lime_capabilities_get_screen_modes () { + + + //Only really makes sense on PC platforms + #if defined( HX_WINDOWS ) || defined( HX_MACOS ) || defined( HX_LINUX ) + + + QuickVec* modes = CapabilitiesGetScreenModes(); + + value result = alloc_array( modes->size() * 4 ); + + for(int i=0;isize();i++) { + ScreenMode mode = (*modes)[ i ]; + val_array_set_i(result,i * 4 + 0,alloc_int( mode.width ) ); + val_array_set_i(result,i * 4 + 1,alloc_int( mode.height ) ); + val_array_set_i(result,i * 4 + 2,alloc_int( mode.refreshRate ) ); + val_array_set_i(result,i * 4 + 3,alloc_int( (int)mode.format ) ); + } + + return result; + + #endif + + return alloc_null(); + + +} + +DEFINE_PRIM( lime_capabilities_get_screen_modes, 0 ); + + value lime_capabilities_get_pixel_aspect_ratio () { return alloc_float (CapabilitiesGetPixelAspectRatio ()); @@ -1224,7 +1255,7 @@ value lime_stage_resize_window(value inStage, value inWidth, value inHeight) Stage *stage; if (AbstractToObject(inStage,stage)) { - stage->ResizeWindow(val_int(inHeight), val_int(inWidth)); + stage->ResizeWindow(val_int(inWidth), val_int(inHeight)); } #endif return alloc_null(); @@ -1232,6 +1263,52 @@ value lime_stage_resize_window(value inStage, value inWidth, value inHeight) DEFINE_PRIM(lime_stage_resize_window,3); +value lime_stage_set_resolution(value inStage, value inWidth, value inHeight) +{ + #if (defined(HX_WINDOWS) || defined(HX_MACOS) || defined(HX_LINUX)) + Stage *stage; + if (AbstractToObject(inStage,stage)) + { + stage->SetResolution(val_int(inWidth), val_int(inHeight)); + } + #endif + return alloc_null(); +} +DEFINE_PRIM(lime_stage_set_resolution,3); + + +value lime_stage_set_screenmode(value inStage, value inWidth, value inHeight, value inRefresh, value inFormat) +{printf("lime_stage_set_screenmode"); + #if (defined(HX_WINDOWS) || defined(HX_MACOS) || defined(HX_LINUX)) + Stage *stage; + if (AbstractToObject(inStage,stage)){ + ScreenMode mode; + mode.width = val_int(inWidth); + mode.height = val_int(inHeight); + mode.refreshRate = val_int(inRefresh); + mode.format = (ScreenFormat)val_int(inFormat); + stage->SetScreenMode(mode); + } + #endif + return alloc_null(); +} +DEFINE_PRIM(lime_stage_set_screenmode,5); + + +value lime_stage_set_fullscreen(value inStage, value inFull) +{ + #if (defined(HX_WINDOWS) || defined(HX_MACOS) || defined(HX_LINUX)) + Stage *stage; + if (AbstractToObject(inStage,stage)) + { + stage->setDisplayState(val_bool(inFull) ? sdsFullscreenInteractive : sdsNormal); + } + #endif + return alloc_null(); +} +DEFINE_PRIM(lime_stage_set_fullscreen,2); + + value lime_stage_get_focus_id(value inValue) { int result = -1; diff --git a/project/src/platform/winrt/WinRTStage.cpp b/project/src/platform/winrt/WinRTStage.cpp index 252d723dc..cbe760e5a 100644 --- a/project/src/platform/winrt/WinRTStage.cpp +++ b/project/src/platform/winrt/WinRTStage.cpp @@ -723,6 +723,19 @@ QuickVec *CapabilitiesGetScreenResolutions() return out; } +QuickVec* CapabilitiesGetScreenModes() +{ + // TODO + QuickVec *out = new QuickVec(); + ScreenMode screenMode; + screenMode.width = 1024; + screenMode.height = 768; + screenMode.format = PIXELFORMAT_UNKNOWN; + screenMode.refreshRate = 60; + out->push_back(screenMode); + return out; +} + double CapabilitiesGetScreenResolutionX() { return sgDesktopWidth; } double CapabilitiesGetScreenResolutionY() { return sgDesktopHeight; } void PauseAnimation() {}