Restoring Display Settings After Crashes

When using exclusive fullscreen, how can I ensure the display settings are properly restored if my game crashes?

When SDL needs to make system-level changes, it generally does a good job of reverting those settings to their original values when our program ends - even when it crashes.

However, it's not perfect, so we can add additional steps to minimise the risk of our program leaving the system in an altered state that our players will find frustrating.

This is especially true when using more impactful system-level changes, like exclusive fullscreen mode. We want to do as much as possible to prevent the player's monitor from being in the wrong resolution after our program terminates.

Using RAII for Safety

The most reliable approach is to use RAII (Resource Acquisition Is Initialization) to automatically restore display settings:

#include <SDL.h>
#include <iostream>
#include <stdexcept>

class DisplayModeGuard {
 public:
  DisplayModeGuard(SDL_Window* Window)
  : Window{Window} {
    // Store the initial display mode
    int DisplayIndex{
      SDL_GetWindowDisplayIndex(Window)};
    if (SDL_GetCurrentDisplayMode(
      DisplayIndex, &OriginalMode) != 0) {
      throw std::runtime_error{SDL_GetError()};
    }
  }

  ~DisplayModeGuard() {
    // Restore original display mode when
    // object is destroyed
    if (Window) {
      SDL_SetWindowDisplayMode(
        Window, &OriginalMode);  
    }
  }

 private:
  SDL_Window* Window;
  SDL_DisplayMode OriginalMode;
};

// Usage example
int main() {
  SDL_Init(SDL_INIT_VIDEO);
  SDL_Window* Window{SDL_CreateWindow(
    "Game",
    SDL_WINDOWPOS_UNDEFINED,
    SDL_WINDOWPOS_UNDEFINED,
    1920, 1080,
    SDL_WINDOW_FULLSCREEN
  )};

  // Create guard to restore display settings
  // even if we crash
  DisplayModeGuard Guard{Window};  

  // Game loop here...

  SDL_Quit();
  return 0;
}

System-Level Fallback

For additional safety, consider creating a small helper application that can restore display settings:

#include <SDL.h>
#include <fstream>
#include <iostream>

// Save current display settings to a file
void SaveDisplaySettings() {
  SDL_DisplayMode Mode;
  SDL_GetWindowDisplayMode(Window, &Mode);

  std::ofstream File{
    "display_backup.dat",
    std::ios::binary
  };
  File.write(reinterpret_cast<char*>(&Mode),
    sizeof(Mode));
}

// Restore display settings from file
void RestoreDisplaySettings() {
  SDL_DisplayMode Mode;

  std::ifstream File{"display_backup.dat",
    std::ios::binary};
  File.read(reinterpret_cast<char*>(&Mode),
    sizeof(Mode));

  SDL_SetWindowDisplayMode(Window, &Mode);
}

The key is to implement multiple layers of protection since exclusive fullscreen directly modifies system settings. The RAII approach handles normal program flow and most crash scenarios, while the helper application provides a manual recovery option if needed.

Fullscreen Windows

Learn how to create and manage fullscreen windows in SDL, including desktop and exclusive fullscreen modes.

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Desktop vs Exclusive Fullscreen
Why would we want to use desktop fullscreen mode if exclusive fullscreen has better performance?
Managing Different Aspect Ratios
What happens if a player has a monitor with a different aspect ratio than our game's resolution?
Smooth Fullscreen Transitions
How can I smoothly transition between windowed and fullscreen modes without the screen going black?
Using Bitwise AND with Window Flags
What's the purpose of the bitwise AND operator (&) when checking window flags? Why can't we use == instead?
Saving Display Preferences
How can I save the player's preferred fullscreen mode and restore it the next time they launch the game?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant