Opened 13 years ago

Closed 10 years ago

#935 closed defect (fixed)

[PATCH] Use standard SDL in Windows (remove custom API)

Reported by: historic_bruno Owned by:
Priority: Nice to Have Milestone: Alpha 17
Component: Core engine Keywords: patch
Cc: stwf@… Patch:

Description (last modified by historic_bruno)

Via Philip in IRC (referring to #907):

It might be best to just try retiring wsdl and switching to standard SDL,
which would hopefully handle this stuff automatically
...
It should be pretty straightforward to set up (disable CONFIG2_WSDL
and provide the necessary DLLs etc) - the tricky bit is just
testing that everything still works (cursors, fullscreen, multi-
monitor, Atlas, etc)

Relevant code is source\lib\sysdep\os\win\wsdl.cpp

Attachments (1)

SDL2_color_cursors_wip.patch (4.7 KB ) - added by historic_bruno 11 years ago.
WIP patch to test SDL 2.0 color hw cursors

Download all attachments as: .zip

Change History (17)

comment:1 by historic_bruno, 13 years ago

Description: modified (diff)

comment:2 by historic_bruno, 13 years ago

Experimented with this a bit by disabling CONFIG2_WSDL. We already provide a DLL for SDL and premake handles it, so there's no need to worry about that unless upgrading to a newer version. This led me to some comments in config2.h:

// NOTE: the official SDL distribution has two problems on Windows:
// - it specifies "/defaultlib:msvcrt.lib". this is troublesome because
//   multiple heaps are active; errors result when allocated blocks are
//   (for reasons unknown) passed to a different heap to be freed.
//   one workaround is to add "/nodefaultlib:msvcrt.lib" to the linker
//   command line in debug configurations.
// - it doesn't support color hardware mouse cursors and clashes with
//   cursor.cpp's efforts by resetting the mouse cursor after movement.

I have no idea about the first point, but the second is confirmed: there appears to be two cursors when the mouse moves, the Windows cursor and the game cursor. That's weird but I'm sure there's a way to fix it.

Then I noticed that toggling fullscreen/windowed mode or stretching the window causes the same problem as on OS X: the textures are corrupted and it becomes unplayable. Our Windows implementation of SDL_SetVideoMode doesn't have this problem because we're careful not to destroy the GL context when changing video modes. From the SDL documentation:

Also note that, in Windows, setting the video mode resets the current OpenGL context. You must execute again the OpenGL initialization code (set the clear color or the shade model, or reload textures, for example) after calling SDL_SetVideoMode(). In Linux, however, it works fine, and the initialization code only needs to be executed after the first call to SDL_SetVideoMode() (although there is no harm in executing the initialization code after each call to SDL_SetVideoMode(), for example for a multiplatform application).

I think we can fix this for all OSes at the same time by fixing #741 and/or upgrading SDL (required anyway for OS X Lion?)

Finally there is a problem starting Atlas, at the point when the game loads GL extensions, it simply needs to load the GL library for SDL in InitGraphics as we currently do for both OS X and Linux.

comment:3 by Philip Taylor, 12 years ago

Looks like SVN contains SDL 1.2.12. The changelog for 1.2.14 says:

Prevent loss of OpenGL context when setting the video mode in response to a window resize event.

though it sounds like it may still lose the context when toggling fullscreen, so we'd need to fix #741 anyway.

in reply to:  2 comment:4 by historic_bruno, 12 years ago

Replying to historic_bruno:

there appears to be two cursors when the mouse moves, the Windows cursor and the game cursor. That's weird but I'm sure there's a way to fix it.

I tried SDL_ShowCursor with SDL_DISABLE as a solution to this. The result is the SDL cursor disappears but still has some rendering effects causing our hardware cursor to flicker when it moves.

comment:5 by historic_bruno, 11 years ago

Keywords: sdl simple removed

I tried the latest SDL 2.0 source snapshot on Windows, to see if it was a practical alternative. A few things of note:

  • When calling SDL_CreateWindow, we should use constants for x,y position (e.g. SDL_WINDOWPOS_UNDEFINED), otherwise the window starts off-screen in windowed mode.
  • Resizing and switching to fullscreen mode are completely broken, I haven't looked enough at our code to see where we're going wrong or if it's a problem with SDL (IIRC, SDL 2.0 support was mostly added for Android and probably not well tested). It seems to create a second window and the game crashes when you close them.
  • The cursor still blinks. According to what I've read in the SDL forums, the suggested way of creating a hardware cursor is to hide the SDL cursor, draw the desired cursor on an SDL surface and blit it onto the screen at the proper coordinates.
  • Mouse scrolling is broken.

in reply to:  5 ; comment:6 by historic_bruno, 11 years ago

As SDL 2.0 is due to be released in the coming months, I've looked at this again:

Replying to historic_bruno:

  • When calling SDL_CreateWindow, we should use constants for x,y position (e.g. SDL_WINDOWPOS_UNDEFINED), otherwise the window starts off-screen in windowed mode.
  • Resizing and switching to fullscreen mode are completely broken, I haven't looked enough at our code to see where we're going wrong or if it's a problem with SDL (IIRC, SDL 2.0 support was mostly added for Android and probably not well tested). It seems to create a second window and the game crashes when you close them.
  • Mouse scrolling is broken.

These were errors in our code, fixed by r13343.

  • The cursor still blinks. According to what I've read in the SDL forums, the suggested way of creating a hardware cursor is to hide the SDL cursor, draw the desired cursor on an SDL surface and blit it onto the screen at the proper coordinates.

This remains unresolved and is the only problem I've found to prevent us switching from wsdl to SDL 2.0 when it's released.

in reply to:  6 comment:7 by historic_bruno, 11 years ago

Replying to historic_bruno:

This remains unresolved and is the only problem I've found to prevent us switching from wsdl to SDL 2.0 when it's released.

Looks like the cursor flicker can be solved easily using SDL_CreateColorCursor, which could eventually replace all of our OS-specific hardware cursor implementations. I hacked up some code to test, it works somewhat like this:

// see load_sys_cursor() for how bgra_img is loaded
SDL_Surface* surface = SDL_CreateRGBSurfaceFrom(bgra_img, (int)t.w, (int)t.h, 32, (int)t.w*4, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000); // bgra_img is little endian
SDL_Cursor* cursor = SDL_CreateColorCursor(surface, hx, hy);

SDL_SetCursor(cursor);

SDL_FreeCursor(cursor);
SDL_FreeSurface(surface);

If we want to hide it or render a GL cursor instead, it only takes a call to SDL_ShowCursor. And there is no need to worry about restoring the original system cursor, because SDL manages that.

comment:8 by historic_bruno, 11 years ago

There's a WMI conflict between the game and SDL 2.0, we use it for enumerating sound and graphics devices, SDL2 uses it for enumerating joysticks. The conflict occurs when we shutdown WMI, maybe it has already been shutdown by SDL? (We do this because launching Atlas from within the game won't work without shutting down WMI first, it changes the engine thread so WMI must be shut down and re-init'd)

Last edited 11 years ago by historic_bruno (previous) (diff)

comment:9 by historic_bruno, 11 years ago

Cc: Jan Wassenberg added

comment:10 by stwf, 11 years ago

Cc: stwf@… added

by historic_bruno, 11 years ago

WIP patch to test SDL 2.0 color hw cursors

comment:11 by historic_bruno, 11 years ago

Keywords: patch added
Summary: Use standard SDL in Windows (remove custom API)[PATCH] Use standard SDL in Windows (remove custom API)

in reply to:  8 comment:12 by historic_bruno, 11 years ago

Replying to historic_bruno:

There's a WMI conflict between the game and SDL 2.0, we use it for enumerating sound and graphics devices, SDL2 uses it for enumerating joysticks.

Looked into this some more, we don't even have joystick support enabled by default, so that had nothing to do with it. It's related to SDL init/shutdown, I noticed we init WMI after SDL, so I tried shutting down WMI before SDL and the crash went away. Also tested joystick support and that still works, so I think we're all good to use SDL 2.0 now :)

Last edited 11 years ago by historic_bruno (previous) (diff)

comment:13 by Jan Wassenberg, 11 years ago

Glad it works and that SDL's cursor trouble is resolved.

comment:14 by historic_bruno, 11 years ago

Cc: Jan Wassenberg removed

Tracking some additional SDL2 issues on #2041

comment:15 by wraitii, 10 years ago

Milestone: BacklogAlpha 17

Bumping back since we want SDL2.

comment:16 by historic_bruno, 10 years ago

Resolution: fixed
Status: newclosed

WSDL is still there for a while, but SDL2 is the default on Windows since r15786.

Note: See TracTickets for help on using tickets.