Open evertvorster opened 3 days ago
What happens if you try 1024x768 (or some other low resolution) in full screen? Why do we have both this and #883 ?
Maybe a screenshot will show you what I mean. Here I used 1366x768, on a 4K monitor with 125% scaling:
A little nuance here. When picking a display size of 3840x2160 which is the monitor's native resolution, it displays too big, because the display is being scaled by the window manager.
Obligatory screenshot:
To get the properly sized display, I have to get the display resolution from a website that checks this sort of thing, and that says my display size is 3200x1800. That resolution does not exist in the vesettings, and so I have to edit vegastrike.config, make the resolution, and then only can I get a proper full screen resolution.
If I have to make a new screen resolution for every scaling factor, the amount of resolutions in the config file becomes a little cumbersome.
So, it is a different problem than the full screen not being scaled to the full monitor in fullscreen mode.
OK. See if you can find a reference in SDL as well as a discussion or code snippet to implement this. If you can find it, I'll implement this. Contingent on approval by @BenjamenMeyer.
I asked ChatGPT about it, and here is the response: In SDL (Simple DirectMedia Layer), handling various screen resolutions and scaled displays involves detecting available screen resolutions, setting the display mode accordingly, and managing proper scaling for different resolutions. Here’s a step-by-step approach to achieve this:
SDL provides a function to get the available display modes for each connected monitor. You can query the modes and then allow the user to select the preferred resolution.
Here’s an example of how to detect the available screen resolutions:
#include <SDL2/SDL.h>
#include <stdio.h>
void listAvailableResolutions(int displayIndex) {
int numDisplayModes = SDL_GetNumDisplayModes(displayIndex);
if (numDisplayModes < 0) {
printf("SDL_GetNumDisplayModes failed: %s\n", SDL_GetError());
return;
}
printf("Available resolutions for display %d:\n", displayIndex);
for (int i = 0; i < numDisplayModes; i++) {
SDL_DisplayMode mode;
if (SDL_GetDisplayMode(displayIndex, i, &mode) != 0) {
printf("SDL_GetDisplayMode failed: %s\n", SDL_GetError());
continue;
}
printf("%d x %d @ %dHz\n", mode.w, mode.h, mode.refresh_rate);
}
}
int main() {
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
printf("SDL_Init Error: %s\n", SDL_GetError());
return 1;
}
int numDisplays = SDL_GetNumVideoDisplays();
if (numDisplays < 0) {
printf("SDL_GetNumVideoDisplays failed: %s\n", SDL_GetError());
return 1;
}
// List available resolutions for each display
for (int i = 0; i < numDisplays; i++) {
listAvailableResolutions(i);
}
SDL_Quit();
return 0;
}
This code initializes SDL, retrieves the available resolutions for each display, and prints them out. You can select a resolution from this list and apply it later.
Once you've selected a resolution, you can set the SDL window to that resolution. Here’s how you do it:
void setDisplayMode(int displayIndex, int width, int height) {
SDL_Window *window = SDL_CreateWindow("Game Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, width, height, SDL_WINDOW_FULLSCREEN_DESKTOP);
if (!window) {
printf("SDL_CreateWindow failed: %s\n", SDL_GetError());
return;
}
SDL_DisplayMode displayMode;
if (SDL_GetCurrentDisplayMode(displayIndex, &displayMode) != 0) {
printf("SDL_GetCurrentDisplayMode failed: %s\n", SDL_GetError());
} else {
SDL_SetWindowDisplayMode(window, &displayMode);
}
// Game loop and rendering goes here...
SDL_DestroyWindow(window);
}
Here, SDL_CreateWindow
sets the window to fullscreen with the desktop resolution, and then you apply the selected display mode using SDL_SetWindowDisplayMode
.
If you are working with different resolutions, SDL provides an easy way to render at a consistent resolution, regardless of the screen size, using the SDL_RenderSetLogicalSize()
function. This function scales the rendering output to match the window’s resolution.
Example for handling scaling:
void setLogicalScaling(SDL_Renderer *renderer, int logicalWidth, int logicalHeight) {
SDL_RenderSetLogicalSize(renderer, logicalWidth, logicalHeight);
}
int main() {
SDL_Window *window;
SDL_Renderer *renderer;
SDL_Init(SDL_INIT_VIDEO);
// Create window at some base resolution, here 1920x1080
window = SDL_CreateWindow("Game Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1920, 1080, SDL_WINDOW_SHOWN);
// Create renderer
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
// Set logical size to scale rendering to 1920x1080 regardless of window resolution
setLogicalScaling(renderer, 1920, 1080);
// Rendering loop
int running = 1;
SDL_Event event;
while (running) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
running = 0;
}
}
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
// Your game rendering logic here...
SDL_RenderPresent(renderer);
}
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
To switch between fullscreen and windowed modes dynamically, you can use SDL_SetWindowFullscreen
:
void toggleFullscreen(SDL_Window *window) {
Uint32 fullscreenFlag = SDL_WINDOW_FULLSCREEN_DESKTOP;
int isFullscreen = SDL_GetWindowFlags(window) & fullscreenFlag;
SDL_SetWindowFullscreen(window, isFullscreen ? 0 : fullscreenFlag);
}
SDL_GetNumDisplayModes
and SDL_GetDisplayMode
.SDL_SetWindowDisplayMode
and SDL_CreateWindow
.SDL_RenderSetLogicalSize
to scale rendering for different screen resolutions.SDL_SetWindowFullscreen
to toggle fullscreen mode.By combining these techniques, your game engine can detect and adapt to various screen resolutions and handle proper scaling across different display setups.
OK. That looks good. Let's give Ben a chance to think about this.
One of my monitors is fairly high resolution, and so it is scaled so that it is usable. Unfortunately this causes issues with VegaStrike which is strictly pixel based.
SDL has a fairly straightforward way of dealing with this that should not impact non-scaled displays: https://wiki.libsdl.org/SDL2/SDL_HINT_WINDOWS_DPI_SCALING