Win32 Fullscreen


#1

Just trying to find out if there is a way to go fullscreen on Windows (desktop)? I read one post somebody had a hack they had done in an old version of the sdk and I see references to fullscreen support on OSX . If someone could help me that would be great.

Thanks


Did cocos2dx support Full Screen game ?(win32)
How to make full screen window?
#2

bump… Hoping someone can help.

Thanks


#3

You can do the fullscreen by using the GLFW library. https://github.com/honghui/cocos2d-x/tree/win32_es_2_gl - by this link you will find GLFW-version of cocos2dx, but it is very old (smth like v0.90), so, if you want to use new version of cocos2dx, you have to a little bit modify CCEGLView and CCApplication classes in libcocos2d by yourself like it has been made in that older version at link.
I can give you some tips if you have any difficulties with it.


#4

I just added fullscreen support! So far it works without problems. Source taken from here:
http://src.chromium.org/viewvc/chrome/trunk/src/ui/views/win/fullscreen_handler.cc?revision=HEAD&view=markup

Comments and suggestions are welcome!

Added to CCEGLView.cpp:

void CCEGLView::setFullScreen(bool fullscreen, bool for_metro)
{
    // taken from:
    // http://src.chromium.org/viewvc/chrome/trunk/src/ui/views/win/fullscreen_handler.cc?revision=HEAD&view=markup

    if (isFullScreen_ == fullscreen)
        return;

    // Save current window state if not already fullscreen.
    if (!isFullScreen_)
    {
        // Save current window information.  We force the window into restored mode
        // before going fullscreen because Windows doesn't seem to hide the
        // taskbar if the window is in the maximized state.
        saved_window_info_.maximized = !!::IsZoomed(m_hWnd);

        if (saved_window_info_.maximized)
            ::SendMessage(m_hWnd, WM_SYSCOMMAND, SC_RESTORE, 0);

        saved_window_info_.style = GetWindowLong(m_hWnd, GWL_STYLE);
        saved_window_info_.ex_style = GetWindowLong(m_hWnd, GWL_EXSTYLE);
        GetWindowRect(m_hWnd, &saved_window_info_.window_rect);
    }

    isFullScreen_ = fullscreen;

    if (isFullScreen_)
    {
        // Set new window style and size.
        SetWindowLong(m_hWnd, GWL_STYLE, saved_window_info_.style & ~(WS_CAPTION | WS_THICKFRAME));
        SetWindowLong(m_hWnd, GWL_EXSTYLE, saved_window_info_.ex_style & ~(WS_EX_DLGMODALFRAME |  WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE));

        // On expand, if we're given a window_rect, grow to it, otherwise do not resize.
        if (!for_metro)
        {
            MONITORINFO monitor_info;
            monitor_info.cbSize = sizeof(monitor_info);
            GetMonitorInfo(MonitorFromWindow(m_hWnd, MONITOR_DEFAULTTONEAREST), &monitor_info);
            RECT window_rect(monitor_info.rcMonitor);
            SetWindowPos(m_hWnd, NULL, window_rect.left, window_rect.top, window_rect.right - window_rect.left, window_rect.bottom - window_rect.top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
        }
    }
    else
    {
        // Reset original window style and size.  The multiple window size/moves
        // here are ugly, but if SetWindowPos() doesn't redraw, the taskbar won't be
        // repainted.  Better-looking methods welcome.
        SetWindowLong(m_hWnd, GWL_STYLE, saved_window_info_.style);
        SetWindowLong(m_hWnd, GWL_EXSTYLE, saved_window_info_.ex_style);

        if (!for_metro)
        {
            // On restore, resize to the previous saved rect size.
            RECT new_rect(saved_window_info_.window_rect);
            SetWindowPos(m_hWnd, NULL, new_rect.left, new_rect.top, new_rect.right - new_rect.left, new_rect.bottom - new_rect.top, SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
        }

        if (saved_window_info_.maximized)
            ::SendMessage(m_hWnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
    }
}

Added to CCEGLView.h:

public:
    void setFullScreen(bool fullscreen, bool for_metro);
    bool isFullScreen() { return isFullScreen_; }

private:
    // Information saved before going into fullscreen mode, used to restore the window afterwards.
    struct SavedWindowInfo {
        bool maximized;
        LONG style;
        LONG ex_style;
        RECT window_rect;
    };

    bool isFullScreen_;
    SavedWindowInfo saved_window_info_; // Saved window information from before entering fullscreen mode.

#5

Attila,

That solution is OK but it actually makes use of the taskbar to achieve full screen functionality. You don’t need anything that intrusive to accomplish what you want. Here’s an example I just got working:

CCEGLView.h

    bool enterFullscreen(int fullscreenWidth=0, int fullscreenHeight=0);
    bool exitFullscreen(int windowX, int windowY, int windowedWidth, int windowedHeight, int windowedPaddingX, int windowedPaddingY);
    int getFullscreenWidth();
    int getFullscreenHeight();

CCEGLView.cpp

int CCEGLView::getFullscreenWidth()
{
    return GetDeviceCaps(m_hDC, HORZRES);
}

int CCEGLView::getFullscreenHeight()
{
    return GetDeviceCaps(m_hDC, VERTRES);
}

bool CCEGLView::enterFullscreen(int fullscreenWidth, int fullscreenHeight)
{
    DEVMODE fullscreenSettings;
    bool isChangeSuccessful;

    if(fullscreenWidth == 0 || fullscreenHeight == 0)
    {
        fullscreenWidth  = GetDeviceCaps(m_hDC, HORZRES);
        fullscreenHeight = GetDeviceCaps(m_hDC, VERTRES);
    }

    int colourBits       = GetDeviceCaps(m_hDC, BITSPIXEL);
    int refreshRate      = GetDeviceCaps(m_hDC, VREFRESH);

    EnumDisplaySettings(NULL, 0, &fullscreenSettings);
    fullscreenSettings.dmPelsWidth        = fullscreenWidth;
    fullscreenSettings.dmPelsHeight       = fullscreenHeight;
    fullscreenSettings.dmBitsPerPel       = colourBits;
    fullscreenSettings.dmDisplayFrequency = refreshRate;
    fullscreenSettings.dmFields           = DM_PELSWIDTH |
                                            DM_PELSHEIGHT |
                                            DM_BITSPERPEL |
                                            DM_DISPLAYFREQUENCY;

    SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, WS_EX_APPWINDOW | WS_EX_TOPMOST);
    SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_POPUP | WS_VISIBLE);
    SetWindowPos(m_hWnd, HWND_TOPMOST, 0, 0, fullscreenWidth, fullscreenHeight, SWP_SHOWWINDOW);
    isChangeSuccessful = ChangeDisplaySettings(&fullscreenSettings, CDS_FULLSCREEN) == DISP_CHANGE_SUCCESSFUL;
    ShowWindow(m_hWnd, SW_MAXIMIZE);

    resize(fullscreenWidth, fullscreenHeight);

    return isChangeSuccessful;
}

bool CCEGLView::exitFullscreen(int windowX, int windowY, int windowedWidth, int windowedHeight, int windowedPaddingX, int windowedPaddingY)
{
    bool isChangeSuccessful;

    SetWindowLongPtr(m_hWnd, GWL_EXSTYLE, WS_EX_LEFT);
    SetWindowLongPtr(m_hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE);
    isChangeSuccessful = ChangeDisplaySettings(NULL, CDS_RESET) == DISP_CHANGE_SUCCESSFUL;
    SetWindowPos(m_hWnd, HWND_NOTOPMOST, windowX, windowY, windowedWidth + windowedPaddingX, windowedHeight + windowedPaddingY, SWP_SHOWWINDOW);
    ShowWindow(m_hWnd, SW_RESTORE);

    return isChangeSuccessful;
}

Example usage in main.cpp:

    // Create the application instance
    AppDelegate app;
    CCEGLView* eglView = CCEGLView::sharedOpenGLView();

    // Set the frame size to the full screen value
    eglView->setFrameSize(eglView->getFullscreenWidth(), eglView->getFullscreenHeight());

    // Enter full screen mode with the resolution size specified at exact fit
    eglView->setDesignResolutionSize(1024, 768, kResolutionExactFit);
    eglView->enterFullscreen(0, 0);

    int ret = CCApplication::sharedApplication()->run();

I haven’t even used the exitFullscreen function yet, so that may be a bit funky. I’d suggest caching off the specified sizes instead of passing them in. You have to set the screen size to the full resolution width/height at the moment. It’s the only way I could get around OpenGL not going crazy and losing its ability to render when you enter fullscreen mode. I’m sure there’s a way around that, but I’m not a graphic engineer. I mostly hang out in server land.


#6

It would be nice to see how to change the resolutions from the game’s options menu also.

So that Cocos2d-x could be a good alternative other than game maker studio for indie developers making games for windows.

Just a thought…

:slight_smile:


#7

For some reason, the code posted by @gnelson does not work if the taskbar is on the right or left of the primary monitor.

If it is on the bottom or top of the screen, the code works and the Cocos2d-x window correctly covers it. Move it to the left or the right, and it does not work.

Anyone have any idea why that is?


#8

After much testing and working on this, I have found the issue in my codebase

The method

  void CCEGLView::centerWindow()

contained this code

// substract the task bar
HWND hTaskBar = FindWindow(TEXT("Shell_TrayWnd"), NULL);
if (hTaskBar != NULL)
{
	APPBARDATA abd;

	abd.cbSize = sizeof(APPBARDATA);
	abd.hWnd = hTaskBar;

	SHAppBarMessage(ABM_GETTASKBARPOS, &abd);
	SubtractRect(&rcDesktop, &rcDesktop, &abd.rc);
}

which needed to be removed to make the fullscreen display work when the task bar is on the left or top of the screen.


#9

@corytrese OMG thanks so much. I have my taskbar on the left and I am having the same problem. I wanted to ask in the other post but thanks for posting it here. :slight_smile:


#10

You are welcome. I’ll be deploying this to Steam in a few days and will let you know if we have any issues in production.

So far, all tests have passed, and it looks like the right solution for all configurations.


#11

Ya looks good. So you will have windowed and fullscreen mode? Thats nice. So you have also included keyboard controls?

Best of luck for steam. I am also planning something similar but my game has a loooong way to go. Do let me know when you have it up on steam will check it out for sure.

(y)


#12

Here is our first Cocos2d-x game on steam (fullscreen and keyboard support)

And we’re trying to Greenlight our second game here:

http://steamcommunity.com/sharedfiles/filedetails/?id=267590365


#13

Thanks for the code! This is going to come in useful :smile:

Congratulations on getting on Steam and I hope the Greenlight goes well for you!

I was going to start a new thread to ask this, but I thought I’d ask here:

Why are there so few PC games made with Cocos2D-X? Why is it mainly targeted at mobile games? Is there something wrong with it? Should I not be trying to build a PC game with it? :wink:


#14

@corytrese: Wow good to see PC games been made using Cocos2d-x. I will check it out also will best of luck for your second game.

@KentuckyFriedKermit: Well… in v 2.2.x there is no keyboard support on the PC(not sure for MAc) and also getting the game running fullscreen is also not possible. If you are making a gamejam game it is ok but otherwise I would say fullscreen is a must.

But 3.0 is cool for both so I expect more PC games to made using it :slight_smile:


#15

My games are based on v2.2.x and I have added the following features:

  • Mac OS X Fullscreen toggle
  • Windows Fullscreen (at startup / as preference)
  • Mac OS X Keyboard Support
  • Windows Keyboard Support
  • Mousewheel Support (Win32)
  • Touchpad Support (Mac OS X)
  • Gamepad Support (Bluetooth, Win32)

I’m also working on support for

  • XBox Controllers
  • NVIDIA Shield
  • OUYA
  • Amazon Fire TV

It can be done with a bit of work. I wouldn’t say “game jam only.”


#16

That is very impressive. Hope you can share how to implement some of them.

Great going. With so many indie PC games being made lets see if we can made Cocos2d-x the most preferred way for making indie pc 2d games.