Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vid_listadapters and vid_adapter on SDL2 #1577

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
132 changes: 121 additions & 11 deletions src/common/platform/posix/sdl/sdlglvideo.cpp
Expand Up @@ -95,8 +95,6 @@ CUSTOM_CVAR(Bool, gl_es, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCA
Printf("This won't take effect until " GAMENAME " is restarted.\n");
}

CVAR (Int, vid_adapter, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)

CUSTOM_CVAR(String, vid_sdl_render_driver, "", CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
{
Printf("This won't take effect until " GAMENAME " is restarted.\n");
Expand All @@ -120,29 +118,61 @@ namespace Priv
bool vulkanEnabled;
bool softpolyEnabled;
bool fullscreenSwitch;
int numberOfDisplays;
SDL_Rect* displayBounds = nullptr;

void updateDisplayInfo()
{
Priv::numberOfDisplays = SDL_GetNumVideoDisplays();
if (Priv::numberOfDisplays <= 0) {
Printf("%sWrong number of displays detected.\n", TEXTCOLOR_BOLD);
return;
}
Printf("Number of detected displays %d .\n", Priv::numberOfDisplays);

if (Priv::displayBounds != nullptr) {
free(Priv::displayBounds);
}
Priv::displayBounds = (SDL_Rect*) calloc(Priv::numberOfDisplays, sizeof(SDL_Rect));

for (int i=0; i < Priv::numberOfDisplays; i++) {
if (0 != SDL_GetDisplayBounds(i, &Priv::displayBounds[i])) {
Printf("%sError getting display %d size: %s\n", TEXTCOLOR_BOLD, i, SDL_GetError());
if (i == 0) {
free(Priv::displayBounds);
displayBounds = nullptr;
}
Priv::numberOfDisplays = i;
return;
}
}
}

void CreateWindow(uint32_t extraFlags)
{
assert(Priv::window == nullptr);

// Set default size
SDL_Rect bounds;
SDL_GetDisplayBounds(vid_adapter, &bounds);
// Get displays and default display size
updateDisplayInfo();

// TODO control better when updateDisplayInfo fails
SDL_Rect* bounds = &displayBounds[vid_adapter % numberOfDisplays];

if (win_w <= 0 || win_h <= 0)
{
win_w = bounds.w * 8 / 10;
win_h = bounds.h * 8 / 10;
win_w = bounds->w * 8 / 10;
win_h = bounds->h * 8 / 10;
}

int xWindowPos = (win_x <= 0) ? SDL_WINDOWPOS_CENTERED_DISPLAY(vid_adapter) : win_x;
int yWindowPos = (win_y <= 0) ? SDL_WINDOWPOS_CENTERED_DISPLAY(vid_adapter) : win_y;
Printf("Creating window [%dx%d] on adapter %d\n", (*win_w), (*win_h), (*vid_adapter));

FString caption;
caption.Format(GAMENAME " %s (%s)", GetVersionString(), GetGitTime());

const uint32_t windowFlags = (win_maximized ? SDL_WINDOW_MAXIMIZED : 0) | SDL_WINDOW_RESIZABLE | extraFlags;
Priv::window = SDL_CreateWindow(caption,
(win_x <= 0) ? SDL_WINDOWPOS_CENTERED_DISPLAY(vid_adapter) : win_x,
(win_y <= 0) ? SDL_WINDOWPOS_CENTERED_DISPLAY(vid_adapter) : win_y,
win_w, win_h, windowFlags);
Priv::window = SDL_CreateWindow(caption, xWindowPos, yWindowPos, win_w, win_h, windowFlags);

if (Priv::window != nullptr)
{
Expand All @@ -159,6 +189,11 @@ namespace Priv

SDL_DestroyWindow(Priv::window);
Priv::window = nullptr;

if (Priv::displayBounds != nullptr) {
free(Priv::displayBounds);
Priv::displayBounds = nullptr;
}
}

void SetupPixelFormat(int multisample, const int *glver)
Expand Down Expand Up @@ -194,12 +229,70 @@ namespace Priv
}
}

CUSTOM_CVAR(Int, vid_adapter, 0, CVAR_ARCHIVE | CVAR_GLOBALCONFIG | CVAR_NOINITCALL)
{
if (Priv::window != nullptr) {
// Get displays and default display size
Priv::updateDisplayInfo();

int display = (*self) % Priv::numberOfDisplays;

// TODO control better when updateDisplayInfo fails
SDL_Rect* bounds = &Priv::displayBounds[vid_adapter % Priv::numberOfDisplays];

if (win_w <= 0 || win_h <= 0)
{
win_w = bounds->w * 8 / 10;
win_h = bounds->h * 8 / 10;
}
// Forces to set to the ini this vars to -1, so +vid_adapter keeps working the next time that the game it's launched
win_x = -1;
win_y = -1;

if ((SDL_GetWindowFlags(Priv::window) & SDL_WINDOW_FULLSCREEN_DESKTOP) != 0) {

// TODO This not works. For some reason keeps stuck on the previus screen
/*
SDL_DisplayMode currentDisplayMode;
SDL_GetWindowDisplayMode(Priv::window, &currentDisplayMode);
currentDisplayMode.w = win_w;
currentDisplayMode.h = win_h;
if ( 0 != SDL_SetWindowDisplayMode(Priv::window, &currentDisplayMode)) {
Printf("A problem occured trying to change of display %s\n", SDL_GetError());
}
*/

// TODO This workaround also isn't working
/*
SDL_SetWindowFullscreen(Priv::window, 0);
SDL_SetWindowSize(Priv::window, win_w, win_h);
SDL_SetWindowPosition(Priv::window, bounds->x , bounds->y);
SDL_SetWindowFullscreen(Priv::window, SDL_WINDOW_FULLSCREEN_DESKTOP);
*/
Printf("Changing adapter on fullscreen, isn't full supported by SDL. Instead try to switch to windowed mode, change the adapter and then switch again to fullscreen.\n");

} else {
SDL_SetWindowSize(Priv::window, win_w, win_h);
SDL_SetWindowPosition(Priv::window, SDL_WINDOWPOS_CENTERED_DISPLAY(display), SDL_WINDOWPOS_CENTERED_DISPLAY(display));
}

display = SDL_GetWindowDisplayIndex(Priv::window);
if (display >= 0) {
Printf("New display is %d\n", display );
} else {
Printf("A problem occured trying to change of display %s\n", SDL_GetError());
}
}
}

class SDLVideo : public IVideo
{
public:
SDLVideo ();
~SDLVideo ();

void DumpAdapters();

DFrameBuffer *CreateFrameBuffer ();

private:
Expand Down Expand Up @@ -436,6 +529,22 @@ SDLVideo::~SDLVideo ()
#endif
}

void SDLVideo::DumpAdapters()
{
Priv::updateDisplayInfo();
for (int i=0; i < Priv::numberOfDisplays; i++) {
Printf("%s%d. [%dx%d @ (%d,%d)]\n",
vid_adapter == i ? TEXTCOLOR_BOLD : "",
i,
Priv::displayBounds[i].w,
Priv::displayBounds[i].h,
Priv::displayBounds[i].x,
Priv::displayBounds[i].y
);
}
}


DFrameBuffer *SDLVideo::CreateFrameBuffer ()
{
SystemBaseFrameBuffer *fb = nullptr;
Expand Down Expand Up @@ -593,6 +702,7 @@ void SystemBaseFrameBuffer::SetWindowSize(int w, int h)
SDL_GetWindowPosition(Priv::window, &x, &y);
win_x = x;
win_y = y;

}
}

Expand Down