[SOLVED] SDL_FULLSCREEN_WINDOW only sometimes work

I am pretty sure i am doing something wrong, but here is the deal.

I modified the examples to show the Window in Fullscreen by setting the SDL_WINDOW_FULLSCREEN flag and it works flawless. I could run every single application in fullscreen.

I also used SDL_SetRenderLogicalPresentation to make the Renderer scale up and its flawless. I tested it with every single example and it just works. Good =) Now i am trying to write my own Application and it suddenly just no longer works.

This is my AppInit

SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
{
	///////////////////////
	// All the SDL stuff //
	///////////////////////
	SDL_SetLogPriorities(SDL_LOG_PRIORITY_VERBOSE);
	if (!SDL_SetAppMetadata("IGE", "0.8.15", "space.ikaros.ige")) {
		SDL_Log("SDL_SetAppMetadata: %s", SDL_GetError());
		return SDL_APP_FAILURE;
	}
	if (!SDL_Init(SDL_INIT_VIDEO)) {
		SDL_Log("SDL_Init: %s", SDL_GetError());
		return SDL_APP_FAILURE;
	}
	AppState *state = (AppState*)SDL_calloc(1, sizeof(AppState));
	if (!state) { return SDL_APP_FAILURE; }
	*appstate = state;
	if (!SDL_CreateWindowAndRenderer("IGE", 320, 240, SDL_WINDOW_FULLSCREEN, &state->window, &state->renderer)) {
		SDL_Log("SDL_CreateWindowAndRenderer: %s", SDL_GetError());
		return SDL_APP_FAILURE;
	}
	if (!SDL_SetWindowFullscreenMode(state->window, NULL)) {
		SDL_Log("SDL_SetWindowFullscreenMode: %s", SDL_GetError());
		return SDL_APP_FAILURE;
	}
	uint32_t window_flags = SDL_GetWindowFlags(state->window);
	if (window_flags & SDL_WINDOW_FULLSCREEN) {
		SDL_Log("Window is in fullscreen mode.");
	} else {
		SDL_Log("Window is NOT in fullscreen mode. Flags: %u", window_flags);
	}
	if (!SDL_SetRenderLogicalPresentation(state->renderer, 320, 240, SDL_LOGICAL_PRESENTATION_LETTERBOX)) {
		SDL_Log("SDL_SetRenderLogicalPresentation: %s", SDL_GetError());
		return SDL_APP_FAILURE;
	}
	///////////////////////
	// All the IGE stuff //
	///////////////////////
	state->intro = true;
	return SDL_APP_CONTINUE;
}

And this is the output when running it

App name: IGE
App version: 0.8.15
App ID: space.ikaros.ige
SDL revision: release-3.2.16-0-gc9a6709bd
OpenGL shaders: ENABLED
Created renderer: opengl
Window is NOT in fullscreen mode. Flags: 2

I tried what feels like a 100 things, even asked the AI out of desparation but nothing, the AI says my code is fine and its a bug in SDL (which i doubt as it works in the examples).

Pretty sure i am just doing something wrong but i have no idea what.

The AppIterate just checks for the defined bool. If its true, it shows an image (That works fine by the way, its in window mode but it works), sets it to false and then uses SDL_Delay to not waste CPU/GPU Cycles. Thats it.

I have no idea what i am doing wrong and why it is only shown in Window mode. Please feel free to point out where i am doing things wrong^^

For reference, this is the modified AppInit from the Snake Demo where Fullscreen works fine and as expected (i am using 320x240 there too)

SDL_AppResult SDL_AppInit(void **appstate, int argc, char *argv[])
{
    size_t i;

    if (!SDL_SetAppMetadata("Example Snake game", "1.0", "com.example.Snake")) {
	return SDL_APP_FAILURE;
    }

    for (i = 0; i < SDL_arraysize(extended_metadata); i++) {
	if (!SDL_SetAppMetadataProperty(extended_metadata[i].key, extended_metadata[i].value)) {
	    return SDL_APP_FAILURE;
	}
    }

    if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK)) {
	SDL_Log("Couldn't initialize SDL: %s", SDL_GetError());
	return SDL_APP_FAILURE;
    }

    AppState *as = (AppState *)SDL_calloc(1, sizeof(AppState));
    if (!as) {
	return SDL_APP_FAILURE;
    }

    *appstate = as;

    if (!SDL_CreateWindowAndRenderer("examples/demo/snake", SDL_WINDOW_WIDTH, SDL_WINDOW_HEIGHT, SDL_WINDOW_FULLSCREEN, &as->window, &as->renderer)) {
	return SDL_APP_FAILURE;
    }
    SDL_SetRenderLogicalPresentation(as->renderer, SDL_WINDOW_WIDTH, SDL_WINDOW_HEIGHT, SDL_LOGICAL_PRESENTATION_LETTERBOX);

    snake_initialize(&as->snake_ctx);

    as->last_step = SDL_GetTicks();

    return SDL_APP_CONTINUE;
}

I found the cause.

SDL_AppIterate needs to run at least once after the window is created and shown.

The issue is that i am playing an Intro graphics and sound and i stopped the application afterwards (Its just testing).

But if i make the intro loop, after the intro played once, the Window goes into fullscreen and from there, stays into fullscreen. So it seems like i have to ensure that AppIterate is executed at least once before i actually play the Intro

To run window in fullscreen mode, simply call the SDL_SetWindowFullscreen function.

Is there any particular reason you want to manually manipulate window flags?

1 Like

I actually do not want^^ i just tried a lot of different things in hope that any of it works. I just tried SDL_SetWindowFullscreen but same behavior.

AppIterate executes the Intro function β†’ The Intro plays in an non-fullscreen window β†’ Intro finishes β†’ AppIterate finishes and runs again β†’ Window turns into Fullscreen.

But that logic is wrong to begin with. I should time all timed events in the AppIterate anyway, otherwise i risk getting an unresponsive application error. So this error exists because i do it wrong, its as simple as that^^

This description suggests that you are doing the entire intro in one call to SDL_AppIterate. Especially since you wrote earlier that you use SDL_Delay to create delays between frames so as not to waste CPU time.

This approach is wrong because if you use SDL callbacks, then a single call to SDL_AppIterate is used to update the game logic once, and then the function is supposed to return, because for the next frame SDL will call this callback on its own again. SDL internally handles the main loop, so you should not use SDL_Delay within an SDL_AppIterate call and process multiple game frames.


If you want to implement the main loop yourself, you can do that (this is the typical approach), but then don’t use SDL callbacks. However, if you want SDL to handle the main game loop for you, then don’t implement your own loop on top of it β€” just place your logic in the SDL_AppIterate and SDL_AppEvent callbacks.