sdl12-compat: Fallback to different-bpp modes more easily

From ca068299acc186c1c8871862fad0174d60632def Mon Sep 17 00:00:00 2001
From: David Gow <[EMAIL REDACTED]>
Date: Wed, 23 Jun 2021 16:28:43 +0800
Subject: [PATCH] Fallback to different-bpp modes more easily

A lot of games expect to be able to set the video mode to modes with a
variety of pixel formats, but X11 and Wayland do not permit the system
pixel format to be changed at runtime. Since SDL is able to convert
between these different formats, SDL 1.2 emulated a number of common
formats where the system bpp was >= the desired bpp.

For sdl12-compat, if no modes are available in the desired bpp:
- Expose the mode list from a higher bpp, in the knowledge it can be
  converted.
- Expose 24bpp modes as 32bpp modes if requested, as these are
  functionally identical.

This change mostly updates SDL_ListModes() to fallback to these mode
lists when necessary. It also lets SDL_VideoModeOK() find 24bpp modes if
a 32bpp mode is expected.

With these changes, a number of games which would error out trying to
set 16 and 32 bit modes on an X11/Wayland setup which exposes only
24-bit modes now work with all three bit depths.
---
 src/SDL12_compat.c | 18 +++++++++++++++---
 1 file changed, 15 insertions(+), 3 deletions(-)

diff --git a/src/SDL12_compat.c b/src/SDL12_compat.c
index f13f26d..087385a 100644
--- a/src/SDL12_compat.c
+++ b/src/SDL12_compat.c
@@ -3471,7 +3471,9 @@ SDL_VideoModeOK(int width, int height, int bpp, Uint32 sdl12flags)
                     if (!vmode->format) {
                         return bpp;
                     }
-                    if (SDL_BITSPERPIXEL(vmode->format) >= (Uint32) bpp) {
+                    if (SDL_BITSPERPIXEL(vmode->format) == 24 && bpp == 32) {
+                        actual_bpp = 32;
+                    } else if (SDL_BITSPERPIXEL(vmode->format) >= (Uint32) bpp) {
                         actual_bpp = SDL_BITSPERPIXEL(vmode->format);
                     }
                 }
@@ -3485,6 +3487,7 @@ SDL_VideoModeOK(int width, int height, int bpp, Uint32 sdl12flags)
 DECLSPEC SDL12_Rect ** SDLCALL
 SDL_ListModes(const SDL12_PixelFormat *format12, Uint32 flags)
 {
+    VideoModeList *best_modes = NULL;
     Uint32 bpp;
     int i;
 
@@ -3516,11 +3519,20 @@ SDL_ListModes(const SDL12_PixelFormat *format12, Uint32 flags)
         VideoModeList *modes = &VideoModes[i];
         if (SDL_BITSPERPIXEL(modes->format) == bpp) {
             return modes->modes12;
+        } else if (SDL_BITSPERPIXEL(modes->format) == 24 && bpp == 32) {
+            best_modes = modes;
+        } else if (SDL_BITSPERPIXEL(modes->format) > bpp) {
+            if (!best_modes || SDL_BITSPERPIXEL(modes->format) > SDL_BITSPERPIXEL(best_modes->format)) {
+                best_modes = modes;
+            }
         }
     }
 
-    SDL20_SetError("No modes support requested pixel format");
-    return NULL;
+    if (!best_modes) {
+        SDL20_SetError("No modes support requested pixel format");
+        return NULL;
+    }
+    return best_modes->modes12;
 }
 
 DECLSPEC void SDLCALL