tsoding / nothing

A simple platformer about nothing
MIT License
295 stars 76 forks source link

(#974) Support non-1x display resolution scale #1163

Closed zhiayang closed 4 years ago

zhiayang commented 4 years ago

As the title suggests; closes #974.

Overview of changes:

  1. Pass SDL_WINDOW_ALLOW_HIGHDPI to SDL_CreateWindow to give us a high-resolution-capable window context with OpenGL or whoever
  2. Introduce notion of display_scale, which is the size in physical pixels divided by the size in logical pixels. macbook retina displays are scaled at 2x, for example.
  3. Hook WINDOW_SIZE_CHANGED and WINDOW_MOVED events and recalculate the display scale. (if you're wondering why on move as well, the game may be moved to another monitor with different scale).
  4. Most importantly, at the top-level event loop (before any other subsystem/layer gets the events), hijack mouse events and scale the x and y values by the display scale. This keeps everybody happy because nobody needs to manually get the scale and multiply before using. I think this is the cleanest and most elegant solution.

Couple of other stuff:

  1. Fixed the positioning of the level picker, it now uses the scaled pixel width to get the centre of the screen.
  2. Cursor rendering needs to explicitly scale as well.
  3. Added a get_display_scale() function which might be useful for other people in the future. For now I put the declaration in game.h, but if there's a better place let me know.
  4. Also, changed the use of WINDOWEVENT_RESIZEDto WINDOWEVENT_SIZE_CHANGED. According to documention (https://wiki.libsdl.org/SDL_WindowEventID), SIZE_CHANGED is always sent, even when window is changed by API call or something. Probably more flexible than resize only.

@rexim pls test on normal screens uwu

rexim commented 4 years ago

@zhiayang looks good to me! :+1: Thank you so much for the contribution!