Skip to content

Commit

Permalink
Add system-offset options
Browse files Browse the repository at this point in the history
While currently the existing window handling code is technically correct,
on Android opertating sytem certain devices (or SDL on them) behave weirdly.

In the engine we have two types of coordinates, screen and script:
- Screen coordinates are coordinates the game window runs in (needed
  to translate e.g. mouse pointer hover area).
- Script coordinates are coordinates the game runs in (always 1080p).

So, for a 2400x1080 screen, as found in Redmi Note9 Pro in landscape
mode, the following values are set:

- script_width / script_height = 1920 / 1080 (game resolution)
- screen_width / screen_height = 1920 / 1080 (windowed game resolution,
  unused in fullscreen really)
- screen_ratio1 / screen_ratio2 = 1080 / 1080 (native screen height
  / game script height)
- fullscript_width / fullscript_height = 2400 / 1080 (screen resolution
  in game coordinates)
- fullscreen_width / fullscreen_height = 1920 / 1080 (game resolution
  in screen coordinates)
- fullscript_offset_x / fullscript_offset_y =  240 / 0 (offset to game
  on device screen in game coordinates)

What we actually observe on the device is padding of 420 pixels to the
left and 210 pixels to the right with the game width cut to 1770 pixels
wide.  If fullscript_offset_x becomes 0 on a normal device that would
have meant the game would run in the top left corner, but it is absolutely
not what happens on Redmi Note9 Pro. What we observe after the change is
left padding of 180 pixels and right padding of 300 pixels with the game
width being 1920 as normal. I guess, neither is correct, but the latter
is at least useable.

What we concluded from these values is that on this device the game
always runs at 180 pixel offset to the right (420 - 240 = 180) enforced
by some system software (or maybe SDL). This is horrifying but not much
we can do about it. To handle the issue as such and get a perfectly centred
image fullscript_offset_x should be 60 as calculated from (2400 - 1920)
/ 2 - 180. Here 180 is so called system_offset_x.

This patch introduces such a variable and makes it user-configurable
via engine arguments or ons.cfg.
  • Loading branch information
ndgnuh authored and vit9696 committed Mar 10, 2021
1 parent 919a08e commit e902723
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 2 deletions.
11 changes: 9 additions & 2 deletions Engine/Components/Window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@
WindowController window;

int WindowController::ownInit() {
auto system_offset_x_str = ons.ons_cfg_options.find("system-offset-x");
if (system_offset_x_str != ons.ons_cfg_options.end())
system_offset_x = std::stoi(system_offset_x_str->second);

auto system_offset_y_str = ons.ons_cfg_options.find("system-offset-y");
if (system_offset_y_str != ons.ons_cfg_options.end())
system_offset_y = std::stoi(system_offset_y_str->second);

if (ons.ons_cfg_options.count("scale"))
scaled_flag = true;
Expand Down Expand Up @@ -243,8 +250,8 @@ bool WindowController::updateDisplayData(bool getpos) {
if (displayData.fullscreenDisplay) {
fullscript_width = script_width * displayData.fullscreenDisplay->native_width / static_cast<float>(fullscreen_width);
fullscript_height = script_height * displayData.fullscreenDisplay->native_height / static_cast<float>(fullscreen_height);
fullscript_offset_x = (fullscript_width - script_width) / 2;
fullscript_offset_y = (fullscript_height - script_height) / 2;
fullscript_offset_x = (fullscript_width - script_width) / 2 - system_offset_x;
fullscript_offset_y = (fullscript_height - script_height) / 2 - system_offset_y;
// A hack for some resolutions to solve scaling issues like random stripes
// e. g. 1366x768
// bg white,1
Expand Down
2 changes: 2 additions & 0 deletions Engine/Components/Window.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ class WindowController : public BaseController {
bool fullscreen_reduce_clip{false};
// Fullscreen offsets (for image centering) (in the script_width coordinate system)
int fullscript_offset_x{0}, fullscript_offset_y{0};
// Offset to compensate for system-forced offset, x->left, y->top
int system_offset_x{0}, system_offset_y{0};
// Native screen resolution (in the script_width coordinate system)
int fullscript_width{0}, fullscript_height{0};
// Actual size of the window. (Current.)
Expand Down
10 changes: 10 additions & 0 deletions Engine/Core/Loader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,8 @@ void *__wrap_SDL_LoadObject(const char *sofile) {
printf(" --font-multiplier provides custom font scaling interface\n");
printf(" --lang-dir provides language-specific game directory\n");
printf(" --font-dir provides language-specific font directory\n");
printf(" --system-offset-x left offset to compensate for system forced offset\n");
printf(" --system-offset-y top offset to compensate for system forced offset\n");
printf(" -h, --help show this help and exit\n");
printf(" -v, --version show the version information and exit\n");
FileIO::waitConsole();
Expand Down Expand Up @@ -486,6 +488,14 @@ static void parseOptions(int argc, char **argv, bool &hasArchivePath) {
// Ignore macOS debugger shit.
argc--;
argv++;
} else if (!std::strcmp(argv[0] + 1, "-system-offset-x")) {
argc--;
argv++;
ons.ons_cfg_options["system-offset-x"] = argv[0];
} else if (!std::strcmp(argv[0] + 1, "-system-offset-y")) {
argc--;
argv++;
ons.ons_cfg_options["system-offset-y"] = argv[0];
} else {
char errstr[256];
std::snprintf(errstr, sizeof(errstr), "unknown option %s", argv[0]);
Expand Down

0 comments on commit e902723

Please sign in to comment.