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

Hyperspace Delivery Boy [LGP] colorkeys are broken on >16bpp displays #317

Closed sulix closed 1 year ago

sulix commented 1 year ago

This looks like a game bug, not an sdl12-compat bug, but since it works with the bundled SDL 1.2, who knows.

Hyperspace Delivery Boy's colour keys do not work at all under sdl12-compat, or under a freshly built SDL 1.2, but do work with the game's bundled version of SDL 1.2.13. Screenshot of the HDB title screen under sdl12-compat, with everything surrounded by magenta boxes

The game is setting the colour key to 0xF800F8, but the actual colour of the key in the images is 0xFFFF (they're 16-bit). This would work, but the game appears to be using SDL_ConvertSurface to convert the surfaces to the screen surface's colour depth, before calling SDL_MapRGB(screen_format, 0xF8, 0x00, 0xF8), so if the screen surface is >16-bit, the colour key no longer matches.

Hacking the game to use 16-bit (by modifying SDL_SetVideoMode()) fixes the issue, but it persists in using 32-bit by default, as it:

The bundled version of SDL 1.2, however, does seem to return a 32-bit format from SDL_GetVideoInfo() as well, so maybe there's something else going on.

My feeling is that the closest thing to a "correct" hack here is to add a quirk which overrides the bit depth to 16, but I think what's going on with the bundled SDL 1.2 is possibly a bit more subtle.

sulix commented 1 year ago

Dropped my quick hack to force 16bpp here: https://github.com/sulix/sdl12-compat/commit/forcebpp

If I can't find a better solution, I'll clean this up, add a quirk, and send it in.

sulix commented 1 year ago

Okay, I've sent out #321 to report a max BPP of 16 to the game, which works around the issue.

The root cause is, as suspected, the game relying heavily on the imprecise RGB565->RGB888 conversion in earlier SDL 1.2 versions when running in 32-bpp mode.

The game's assets are all in 565 format, and the game converts these to the screen's format on load. It then sets a colour key. This presents a problem, because:

Since the conversion behaviour is different even between SDL 1.2 versions, it's not worth trying to imitate it here, so we just force the game to run in 16-bpp mode, which works fine.

(And the game's README recommends it, too.)