int SDL_VideoModeOK(int width, int height, int bpp, Uint32 flags) { int i, actual_bpp = 0; if (!SDL_GetVideoDevice()) { return 0; } if (!(flags & SDL_FULLSCREEN)) { SDL_DisplayMode mode; SDL_GetDesktopDisplayMode(GetVideoDisplay(), &mode); return SDL_BITSPERPIXEL(mode.format); } for (i = 0; i < SDL_GetNumDisplayModes(GetVideoDisplay()); ++i) { SDL_DisplayMode mode; SDL_GetDisplayMode(GetVideoDisplay(), i, &mode); if (!mode.w || !mode.h || (width == mode.w && height == mode.h)) { if (!mode.format) { return bpp; } if (SDL_BITSPERPIXEL(mode.format) >= (Uint32) bpp) { actual_bpp = SDL_BITSPERPIXEL(mode.format); } } } return actual_bpp; }
const SDL_VideoInfo * SDL_GetVideoInfo(void) { static SDL_VideoInfo info; SDL_DisplayMode mode; /* Memory leak, compatibility code, who cares? */ if (!info.vfmt && SDL_GetDesktopDisplayMode(GetVideoDisplay(), &mode) == 0) { info.vfmt = SDL_AllocFormat(mode.format); info.current_w = mode.w; info.current_h = mode.h; } return &info; }
static void GetEnvironmentWindowPosition(int w, int h, int *x, int *y) { int display = GetVideoDisplay(); const char *window = SDL_getenv("SDL_VIDEO_WINDOW_POS"); const char *center = SDL_getenv("SDL_VIDEO_CENTERED"); if (window) { if (SDL_sscanf(window, "%d,%d", x, y) == 2) { return; } if (SDL_strcmp(window, "center") == 0) { center = window; } } if (center) { *x = SDL_WINDOWPOS_CENTERED_DISPLAY(display); *y = SDL_WINDOWPOS_CENTERED_DISPLAY(display); } }
void Window::ChangeDisplay( int width, int height, int bpp, int dbpp, bool fullscreen, unsigned int antialiasing, std::ostream & info_output, std::ostream & error_output) { SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, dbpp); fsaa = 1; if (antialiasing > 1) { fsaa = antialiasing; SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, fsaa); info_output << "Enabling antialiasing: " << fsaa << "X" << std::endl; } else { info_output << "Disabling antialiasing" << std::endl; } SDL_DisplayMode desktop_mode; int display = GetVideoDisplay(); SDL_GetDesktopDisplayMode(display, &desktop_mode); if (width == 0) width = desktop_mode.w; if (height == 0) height = desktop_mode.h; if (bpp == 0) bpp = SDL_BITSPERPIXEL(desktop_mode.format); // Try to resize the existing window and surface if (!fullscreen && ResizeWindow(width, height)) return; if (glcontext) { SDL_GL_DeleteContext(glcontext); glcontext = NULL; } if (window) { SDL_DestroyWindow(window); } // Create a new window Uint32 window_flags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL; if (fullscreen) window_flags |= SDL_WINDOW_FULLSCREEN; window = SDL_CreateWindow(NULL, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, window_flags); if (!window) { assert(0); } glcontext = SDL_GL_CreateContext(window); if (!glcontext) { assert(0); } if (SDL_GL_MakeCurrent(window, glcontext) < 0) { assert(0); } w = width; h = height; }
SDL_Surface * SDL_SetVideoMode(int width, int height, int bpp, Uint32 flags) { SDL_DisplayMode desktop_mode; int display = GetVideoDisplay(); int window_x = SDL_WINDOWPOS_UNDEFINED_DISPLAY(display); int window_y = SDL_WINDOWPOS_UNDEFINED_DISPLAY(display); int window_w; int window_h; Uint32 window_flags; Uint32 surface_flags; if (!SDL_GetVideoDevice()) { if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE) < 0) { return NULL; } } SDL_GetDesktopDisplayMode(display, &desktop_mode); if (width == 0) { width = desktop_mode.w; } if (height == 0) { height = desktop_mode.h; } if (bpp == 0) { bpp = SDL_BITSPERPIXEL(desktop_mode.format); } /* See if we can simply resize the existing window and surface */ if (SDL_ResizeVideoMode(width, height, bpp, flags) == 0) { return SDL_PublicSurface; } /* Destroy existing window */ SDL_PublicSurface = NULL; if (SDL_ShadowSurface) { SDL_ShadowSurface->flags &= ~SDL_DONTFREE; SDL_FreeSurface(SDL_ShadowSurface); SDL_ShadowSurface = NULL; } if (SDL_VideoSurface) { SDL_VideoSurface->flags &= ~SDL_DONTFREE; SDL_FreeSurface(SDL_VideoSurface); SDL_VideoSurface = NULL; } if (SDL_VideoContext) { /* SDL_GL_MakeCurrent(0, NULL); *//* Doesn't do anything */ SDL_GL_DeleteContext(SDL_VideoContext); SDL_VideoContext = NULL; } if (SDL_VideoWindow) { SDL_GetWindowPosition(SDL_VideoWindow, &window_x, &window_y); SDL_DestroyWindow(SDL_VideoWindow); } /* Set up the event filter */ if (!SDL_GetEventFilter(NULL, NULL)) { SDL_SetEventFilter(SDL_CompatEventFilter, NULL); } /* Create a new window */ window_flags = SDL_WINDOW_SHOWN; if (flags & SDL_FULLSCREEN) { window_flags |= SDL_WINDOW_FULLSCREEN; } if (flags & SDL_OPENGL) { window_flags |= SDL_WINDOW_OPENGL; } if (flags & SDL_RESIZABLE) { window_flags |= SDL_WINDOW_RESIZABLE; } if (flags & SDL_NOFRAME) { window_flags |= SDL_WINDOW_BORDERLESS; } GetEnvironmentWindowPosition(width, height, &window_x, &window_y); SDL_VideoWindow = SDL_CreateWindow(wm_title, window_x, window_y, width, height, window_flags); if (!SDL_VideoWindow) { return NULL; } SDL_SetWindowIcon(SDL_VideoWindow, SDL_VideoIcon); SetupScreenSaver(flags); window_flags = SDL_GetWindowFlags(SDL_VideoWindow); surface_flags = 0; if (window_flags & SDL_WINDOW_FULLSCREEN) { surface_flags |= SDL_FULLSCREEN; } if ((window_flags & SDL_WINDOW_OPENGL) && (flags & SDL_OPENGL)) { surface_flags |= SDL_OPENGL; } if (window_flags & SDL_WINDOW_RESIZABLE) { surface_flags |= SDL_RESIZABLE; } if (window_flags & SDL_WINDOW_BORDERLESS) { surface_flags |= SDL_NOFRAME; } SDL_VideoFlags = flags; /* If we're in OpenGL mode, just create a stub surface and we're done! */ if (flags & SDL_OPENGL) { SDL_VideoContext = SDL_GL_CreateContext(SDL_VideoWindow); if (!SDL_VideoContext) { return NULL; } if (SDL_GL_MakeCurrent(SDL_VideoWindow, SDL_VideoContext) < 0) { return NULL; } SDL_VideoSurface = SDL_CreateRGBSurfaceFrom(NULL, width, height, bpp, 0, 0, 0, 0, 0); if (!SDL_VideoSurface) { return NULL; } SDL_VideoSurface->flags |= surface_flags; SDL_PublicSurface = SDL_VideoSurface; return SDL_PublicSurface; } /* Create the screen surface */ SDL_WindowSurface = SDL_GetWindowSurface(SDL_VideoWindow); if (!SDL_WindowSurface) { return NULL; } /* Center the public surface in the window surface */ SDL_GetWindowSize(SDL_VideoWindow, &window_w, &window_h); SDL_VideoViewport.x = (window_w - width)/2; SDL_VideoViewport.y = (window_h - height)/2; SDL_VideoViewport.w = width; SDL_VideoViewport.h = height; SDL_VideoSurface = SDL_CreateRGBSurfaceFrom(NULL, 0, 0, 32, 0, 0, 0, 0, 0); SDL_VideoSurface->flags |= surface_flags; SDL_VideoSurface->flags |= SDL_DONTFREE; SDL_FreeFormat(SDL_VideoSurface->format); SDL_VideoSurface->format = SDL_WindowSurface->format; SDL_VideoSurface->format->refcount++; SDL_VideoSurface->w = width; SDL_VideoSurface->h = height; SDL_VideoSurface->pitch = SDL_WindowSurface->pitch; SDL_VideoSurface->pixels = (void *)((Uint8 *)SDL_WindowSurface->pixels + SDL_VideoViewport.y * SDL_VideoSurface->pitch + SDL_VideoViewport.x * SDL_VideoSurface->format->BytesPerPixel); SDL_SetClipRect(SDL_VideoSurface, NULL); /* Create a shadow surface if necessary */ if ((bpp != SDL_VideoSurface->format->BitsPerPixel) && !(flags & SDL_ANYFORMAT)) { SDL_ShadowSurface = SDL_CreateRGBSurface(0, width, height, bpp, 0, 0, 0, 0); if (!SDL_ShadowSurface) { return NULL; } SDL_ShadowSurface->flags |= surface_flags; SDL_ShadowSurface->flags |= SDL_DONTFREE; /* 8-bit SDL_ShadowSurface surfaces report that they have exclusive palette */ if (SDL_ShadowSurface->format->palette) { SDL_ShadowSurface->flags |= SDL_HWPALETTE; SDL_DitherColors(SDL_ShadowSurface->format->palette->colors, SDL_ShadowSurface->format->BitsPerPixel); } SDL_FillRect(SDL_ShadowSurface, NULL, SDL_MapRGB(SDL_ShadowSurface->format, 0, 0, 0)); } SDL_PublicSurface = (SDL_ShadowSurface ? SDL_ShadowSurface : SDL_VideoSurface); ClearVideoSurface(); /* We're finally done! */ return SDL_PublicSurface; }
void WINDOW_SDL::ChangeDisplay( int width, int height, int bpp, int dbpp, bool fullscreen, unsigned int antialiasing, std::ostream & info_output, std::ostream & error_output) { SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, dbpp); fsaa = 1; if (antialiasing > 1) { fsaa = antialiasing; SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, fsaa); info_output << "Enabling antialiasing: " << fsaa << "X" << std::endl; } else { info_output << "Disabling antialiasing" << std::endl; } #if SDL_VERSION_ATLEAST(2,0,0) SDL_DisplayMode desktop_mode; int display = GetVideoDisplay(); SDL_GetDesktopDisplayMode(display, &desktop_mode); if (width == 0) width = desktop_mode.w; if (height == 0) height = desktop_mode.h; if (bpp == 0) bpp = SDL_BITSPERPIXEL(desktop_mode.format); // Try to resize the existing window and surface if (!fullscreen && ResizeWindow(width, height)) return; if (glcontext) { SDL_GL_DeleteContext(glcontext); glcontext = NULL; } if (window) { SDL_DestroyWindow(window); } // Create a new window Uint32 window_flags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL; if (fullscreen) window_flags |= SDL_WINDOW_FULLSCREEN; window = SDL_CreateWindow(NULL, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, width, height, window_flags); if (!window) { assert(0); } glcontext = SDL_GL_CreateContext(window); if (!glcontext) { assert(0); } if (SDL_GL_MakeCurrent(window, glcontext) < 0) { assert(0); } #else const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo(); if (!videoInfo) { error_output << "SDL video query failed: " << SDL_GetError() << std::endl; assert (0); } int videoFlags = SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_HWPALETTE; if (fullscreen) videoFlags |= (SDL_HWSURFACE | SDL_ANYFORMAT | SDL_FULLSCREEN); else videoFlags |= (SDL_SWSURFACE | SDL_ANYFORMAT); if (surface != NULL) { SDL_FreeSurface(surface); surface = NULL; } surface = SDL_SetVideoMode(width, height, bpp, videoFlags); if (!surface) { error_output << "Display change failed: " << width << "x" << height << "x" << bpp << " " << dbpp << "z fullscreen=" << fullscreen << std::endl << "Error: " << SDL_GetError() << std::endl; assert (0); } else { info_output << "Display change was successful: " << width << "x" << height << "x" << bpp << " " << dbpp << "z fullscreen=" << fullscreen << std::endl; } #endif w = width; h = height; }