void SDLHardwareRenderDevice::destroyContext() { resetGamma(); // we need to free all loaded graphics as they may be tied to the current context RenderDevice::cacheRemoveAll(); reload_graphics = true; if (icons) { delete icons; icons = NULL; } if (curs) { delete curs; curs = NULL; } SDL_FreeSurface(titlebar_icon); titlebar_icon = NULL; SDL_DestroyTexture(texture); texture = NULL; SDL_DestroyRenderer(renderer); renderer = NULL; SDL_DestroyWindow(window); window = NULL; if (title) { free(title); title = NULL; } return; }
int SDLHardwareRenderDevice::createContextInternal() { bool settings_changed = (fullscreen != settings->fullscreen || hwsurface != settings->hwsurface || vsync != settings->vsync || texture_filter != settings->texture_filter || ignore_texture_filter != eset->resolutions.ignore_texture_filter); Uint32 w_flags = 0; Uint32 r_flags = 0; int window_w = settings->screen_w; int window_h = settings->screen_h; if (settings->fullscreen) { w_flags = w_flags | SDL_WINDOW_FULLSCREEN_DESKTOP; // make the window the same size as the desktop resolution SDL_DisplayMode desktop; if (SDL_GetDesktopDisplayMode(0, &desktop) == 0) { window_w = desktop.w; window_h = desktop.h; } } else if (fullscreen && is_initialized) { // if the game was previously in fullscreen, resize the window when returning to windowed mode window_w = eset->resolutions.min_screen_w; window_h = eset->resolutions.min_screen_h; w_flags = w_flags | SDL_WINDOW_SHOWN; } else { w_flags = w_flags | SDL_WINDOW_SHOWN; } w_flags = w_flags | SDL_WINDOW_RESIZABLE; if (settings->hwsurface) { r_flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE; } else { r_flags = SDL_RENDERER_SOFTWARE | SDL_RENDERER_TARGETTEXTURE; settings->vsync = false; // can't have software mode & vsync at the same time } if (settings->vsync) r_flags = r_flags | SDL_RENDERER_PRESENTVSYNC; if (settings_changed || !is_initialized) { destroyContext(); window = SDL_CreateWindow(NULL, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, window_w, window_h, w_flags); if (window) { renderer = SDL_CreateRenderer(window, -1, r_flags); if (renderer) { if (settings->texture_filter && !eset->resolutions.ignore_texture_filter) SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"); else SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); windowResize(); } SDL_SetWindowMinimumSize(window, eset->resolutions.min_screen_w, eset->resolutions.min_screen_h); // setting minimum size might move the window, so set position again SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); } if (window && renderer) { if (!is_initialized) { // save the system gamma levels if we just created the window SDL_GetWindowGammaRamp(window, gamma_r, gamma_g, gamma_b); Utils::logInfo("RenderDevice: Window size is %dx%d", settings->screen_w, settings->screen_h); } fullscreen = settings->fullscreen; hwsurface = settings->hwsurface; vsync = settings->vsync; texture_filter = settings->texture_filter; ignore_texture_filter = eset->resolutions.ignore_texture_filter; is_initialized = true; Utils::logInfo("RenderDevice: Fullscreen=%d, Hardware surfaces=%d, Vsync=%d, Texture Filter=%d", fullscreen, hwsurface, vsync, texture_filter); #if SDL_VERSION_ATLEAST(2, 0, 4) SDL_GetDisplayDPI(0, &ddpi, 0, 0); Utils::logInfo("RenderDevice: Display DPI is %f", ddpi); #else Utils::logError("RenderDevice: The SDL version used to compile Flare does not support SDL_GetDisplayDPI(). The virtual_dpi setting will be ignored."); #endif } } if (is_initialized) { // update minimum window size if it has changed if (min_screen.x != eset->resolutions.min_screen_w || min_screen.y != eset->resolutions.min_screen_h) { min_screen.x = eset->resolutions.min_screen_w; min_screen.y = eset->resolutions.min_screen_h; SDL_SetWindowMinimumSize(window, eset->resolutions.min_screen_w, eset->resolutions.min_screen_h); SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); } windowResize(); // update title bar text and icon updateTitleBar(); // load persistent resources delete icons; icons = new IconManager(); delete curs; curs = new CursorManager(); if (settings->change_gamma) setGamma(settings->gamma); else { resetGamma(); settings->change_gamma = false; settings->gamma = 1.0; } } return (is_initialized ? 0 : -1); }
int SDLHardwareRenderDevice::createContext(bool allow_fallback) { bool settings_changed = (fullscreen != FULLSCREEN || hwsurface != HWSURFACE || vsync != VSYNC || texture_filter != TEXTURE_FILTER); Uint32 w_flags = 0; Uint32 r_flags = 0; int window_w = SCREEN_W; int window_h = SCREEN_H; if (FULLSCREEN) { w_flags = w_flags | SDL_WINDOW_FULLSCREEN_DESKTOP; // make the window the same size as the desktop resolution SDL_DisplayMode desktop; if (SDL_GetDesktopDisplayMode(0, &desktop) == 0) { window_w = desktop.w; window_h = desktop.h; } } else if (fullscreen && is_initialized) { // if the game was previously in fullscreen, resize the window when returning to windowed mode window_w = MIN_SCREEN_W; window_h = MIN_SCREEN_H; w_flags = w_flags | SDL_WINDOW_SHOWN; } else { w_flags = w_flags | SDL_WINDOW_SHOWN; } w_flags = w_flags | SDL_WINDOW_RESIZABLE; if (HWSURFACE) { r_flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE; } else { r_flags = SDL_RENDERER_SOFTWARE | SDL_RENDERER_TARGETTEXTURE; VSYNC = false; // can't have software mode & vsync at the same time } if (VSYNC) r_flags = r_flags | SDL_RENDERER_PRESENTVSYNC; if (settings_changed || !is_initialized) { destroyContext(); window = SDL_CreateWindow(NULL, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, window_w, window_h, w_flags); if (window) { renderer = SDL_CreateRenderer(window, -1, r_flags); if (renderer) { if (TEXTURE_FILTER && !IGNORE_TEXTURE_FILTER) SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1"); else SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); windowResize(); } SDL_SetWindowMinimumSize(window, MIN_SCREEN_W, MIN_SCREEN_H); // setting minimum size might move the window, so set position again SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); } bool window_created = window != NULL && renderer != NULL; if (!window_created) { if (allow_fallback) { // try previous setting first FULLSCREEN = fullscreen; HWSURFACE = hwsurface; VSYNC = vsync; TEXTURE_FILTER = texture_filter; if (createContext(false) == -1) { // last resort, try turning everything off FULLSCREEN = false; HWSURFACE = false; VSYNC = false; TEXTURE_FILTER = false; int last_resort = createContext(false); if (last_resort == -1 && !is_initialized) { // If this is the first attempt and it failed we are not // getting anywhere. logError("SDLHardwareRenderDevice: createContext() failed: %s", SDL_GetError()); logErrorDialog("SDLHardwareRenderDevice: createContext() failed: %s", SDL_GetError()); Exit(1); } return last_resort; } else { return 0; } } } else { if (!is_initialized) { // save the system gamma levels if we just created the window SDL_GetWindowGammaRamp(window, gamma_r, gamma_g, gamma_b); logInfo("RenderDevice: Window size is %dx%d", SCREEN_W, SCREEN_H); } fullscreen = FULLSCREEN; hwsurface = HWSURFACE; vsync = VSYNC; texture_filter = TEXTURE_FILTER; is_initialized = true; logInfo("RenderDevice: Fullscreen=%d, Hardward surfaces=%d, Vsync=%d, Texture Filter=%d", fullscreen, hwsurface, vsync, texture_filter); } } if (is_initialized) { // update minimum window size if it has changed if (min_screen.x != MIN_SCREEN_W || min_screen.y != MIN_SCREEN_H) { min_screen.x = MIN_SCREEN_W; min_screen.y = MIN_SCREEN_H; SDL_SetWindowMinimumSize(window, MIN_SCREEN_W, MIN_SCREEN_H); SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED); } windowResize(); // update title bar text and icon updateTitleBar(); // load persistent resources delete icons; icons = new IconManager(); delete curs; curs = new CursorManager(); if (CHANGE_GAMMA) setGamma(GAMMA); else { resetGamma(); CHANGE_GAMMA = false; GAMMA = 1.0; } } return (is_initialized ? 0 : -1); }