Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a SDL12COMPAT_MAX_BPP hint, and use it to restrict Hyperspace Delivery Boy to 16bpp (fixes #317) #321

Merged
merged 2 commits into from
Sep 14, 2023

Commits on Sep 14, 2023

  1. Add a hint to clamp the reported screen bit depth

    Some games (e.g. Hyperspace Delivery Boy) only work on a 16-bit display,
    but request the highest bit-depth available. Add a hint which makes all
    queries for a mode (including the current mode, and the implicit format
    chosen by providng SDL_SetVideoMode() a bpp of 0) report a bit depth
    less than or equal to the value of SDL12COMPAT_FORCE_BPP.
    
    For example:
    SDL12COMPAT_FORCE_BPP=16 ./hdb
    
    There are a few interesting "features" of this implementation:
    - All video modes are now clamped to 32bit, which is the default value
      of the hint. This seems like something we'd probably want anyway, as
      many SDL 1.2 apps would have trouble with >32bit video modes anway
      (and we never properly supported them).
    - This is our first proper integer hint, so add an SDL_GetHintInt()
      function.
    - Split the BPP -> format conversion into its own helper function.
    - This doesn't clamp the bit depth of user-created surfaces, or of the
      screen if the application specifically requests a bit depth. It only
      changes defaults and reported modes.
    sulix committed Sep 14, 2023
    Configuration menu
    Copy the full SHA
    fbb79e6 View commit details
    Browse the repository at this point in the history
  2. Quirks: Hyperspace Delivery Boy should run in 16bpp mode

    The LGP port of Hyperspace Delivery Boy has broken colour keys if run in
    32-bpp mode (see bug libsdl-org#317). This is because it relies 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:
    - The generic BlitNToN implementation in SDL 1.2 just shifted the
      values, so the resulting image was not at full range. Magenta became
      (F800F8).
    - Early versions of SDL 1.2 fell back to the BlitNToN blitter very
      frequently:
      libsdl-org/SDL-1.2@6f4a75d
    - So, Hyperspace Delivery Boy calls SDL_MapRGB(0xF8, 0, 0xF8) to get the
      colour key, then sets it on the converted surface.
    - In SDL 2.0, the blitters now properly do a full-range conversion, so
      the magenta becomes (FF00FF), which now doesn't match the hardcoded
      (F800F8).
    - That being said, in general, it's not guaranteed that SDL_MapRGB()
      will do the same format conversion as SDL_CovertSurface(), so the
      "correct" way of handling this is to set the colour key before
      converting, which works (albeit slowly) in SDL2:
      libsdl-org/SDL#1854
    - 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.)
    sulix committed Sep 14, 2023
    Configuration menu
    Copy the full SHA
    8dc5130 View commit details
    Browse the repository at this point in the history