libsdl-org / sdl12-compat

An SDL-1.2 compatibility layer that uses SDL 2.0 behind the scenes.
Other
194 stars 40 forks source link

glTron: hangs on Alt+F4 (real SDL 1.2 segfaults instead) #237

Closed smcv closed 1 year ago

smcv commented 1 year ago

Prerequisites:

To reproduce:

Expected result: all work

Actual result: Gameplay works fine, the problem is when I exit with Alt+F4 rather than through the menu. With real SDL 1.2, the game segfaults. With sdl12-compat, instead it hangs and becomes unresponsive to SIGINT and SIGTERM.

This is probably a game bug rather than a sdl12-compat bug, I'm reporting it out of a sense of completeness. Don't prioritize this!

icculus commented 1 year ago

Don't prioritize this!

Sounds like a challenge. :P

This happens in glTron because it gets the SDL_QUIT event:

int SystemMainLoop() {
  SDL_Event event;

    return_code = -1;
  while(return_code == -1) {
    while(SDL_PollEvent(&event) && current) {
            switch(event.type) {
            case SDL_KEYDOWN:
            case SDL_KEYUP:
            case SDL_JOYAXISMOTION:
            case SDL_JOYBUTTONDOWN:
            case SDL_JOYBUTTONUP:
            case SDL_MOUSEBUTTONUP:
            case SDL_MOUSEBUTTONDOWN:
            case SDL_MOUSEMOTION:
                SystemHandleInput(&event);
                break;
            case SDL_QUIT:
                SystemExit();
                break;
            default:
                /* ignore event */
                break;
      }
    }
    if(redisplay) {
      current->display();
      redisplay = 0;
    } else
      current->idle();
  }
    if(current->exit)
        (current->exit)();
    return return_code;
}

...which calls SystemExit()...

void SystemExit() {
  fprintf(stderr, "[system] shutting down SDL now\n");
  SDL_Quit();
  fprintf(stderr, "[system] exiting application\n");
}

...but never sets return_code to exit the loop. It should probably just do that and not call SystemExit, as I assume leaving this loop will do that too without risking another call into SDL.

In real 1.2, it eventually calls SDL_GL_SwapBuffers after that SDL_Quit and dereferences a NULL pointer; in sdl12-compat, we just keep ending up back in current->idle() calling SDL_Delay() without crashing.

Nothing to be done here but patch glTron.

smcv commented 1 year ago

Downstream bug reported as https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1021712. glTron seems to be dead upstream.

sezero commented 1 year ago

Downstream bug reported as https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1021712. glTron seems to be dead upstream.

You possibly need something as simple as the following:

diff -up gltron-0.70/nebu/base/system.c~ gltron-0.70/nebu/base/system.c
--- gltron-0.70/nebu/base/system.c~
+++ gltron-0.70/nebu/base/system.c
@@ -37,4 +37,5 @@ int SystemMainLoop() {
                break;
            case SDL_QUIT:
+               SystemExitLoop(0);/* exit mainloop */
                SystemExit();
                break;