This issue shows up when launching the game on Mac OS X fullscreen with the option --display-scale 1.5.
In the city map moving the mouse cursor to the far right should scroll the screen, but it doesn't, instead you need to move the mouse back a few pixels to start scrolling the map.
Not sure if this is only on Mac OS, but I added that detail until I can confirm otherwise.
Seems to work fine on Windows, maybe it's a macOS-specific issue...
I didn't get to test Windows yet, so it might well be Mac OS specific.
Pretty sure it was working properly at normal and 2x scale on the Mac.
What's your screen resolution?
I tried to reproduce on my MacBook with retina screen (still running Mojave) but scrolling works properly in all directions.
It is with display resolution 2560x1440, so maybe it's the resolution causing a rounding error. It is off by only one pixel.
This may be due to the integer truncation when scaling. 1.5x means both width and height are multiplied by 2/3, which may not result in a whole number.
So the problem may only appear on certain resolutions...
Classic off-by-one error? LOL.
Well I did the division on my computer and it definitely ends in a remainder.
This is a 27" Retina display iMac with a display size of 5120x2880 set to half resolution.
I can change the scale to 1.6 for now if that is supported which will avoid the rounding error for now.
Confirmed that changing the scale to 1.6 avoids the bug.
Good to hear. I'll test different display scales and see if I can reproduce.
I tried to reproduce this but I simply can't... I tried different display scale values, with or without external monitor.
Which version of Julius are you running, and which version of macOS? Did you download the julius dmg or did you compile it yourself?
This is a 27" Retina display iMac with a display size of 5120x2880 set to half resolution.
What exactly do you mean by "set to half resolution"?
Which version of Julius are you running, and which version of macOS? Did you download the julius dmg or did you compile it yourself?
Using Mac OS X 10.13.6 High Sierra. I downloaded the Julius 1.3.1 stable dmg. I could try the latest build release if you think it was fixed by a recent commit.
This is a 27" Retina display iMac with a display size of 5120x2880 set to half resolution.
What exactly do you mean by "set to half resolution"?
The maximum resolution of the screen is 5120x2880, but it's currently set to 2560x1440.
I also tried the latest dmg published and the issue is still there.
High Sierra... it might be caused by a combination of old macOS + new SDL.
I'm running Mojave myself (not upgrading to Catalina because of the dropped 32-bit support) and there it works properly. I'll see if I can set up a virtual machine with High Sierra.
Reading through the SDL bug history it seems like Mojave caused considerable trouble with full-screen windows overlapping the screen boundary. It may be that one of the fixes is causing trouble for older Macs or isn't applied to older Macs.
I would upgrade, but then we might lose a corner case.
May be related: https://bugzilla.libsdl.org/show_bug.cgi?id=4272
They talk about window sizing issues. Could be their patch for that is causing grief now.
I'm trying to install High Sierra in VirtualBox on my MacBook so I can possibly reproduce the issue, but the installation doesn't really like me, since it already failed 4 times at four different points in the installation 馃槖
Meanwhile, could you perhaps try this image? It's using SDL 2.0.8, that's before the issue you linked to was fixed.
I just confirmed, this happens in Windows too with 2560x1440 resolution and --display-scale 1.5. I'll have a look!
Yeah, tried the older SDL package and it behaves the same. This is definitely a window mapping calculation error.
I'll have a look too. Maybe I can help you find it.
We think we fixed the issue, at least on @crudelios' Windows display it's fixed now. Could you try this version?
I should get a chance to test it around 18:00UTC. Busy with family right now.
That fixes it alright.
Although I'm pretty sure that patch is the wrong fix. Seems more like there is an issue with the calculated width to me.
I think I found the actual issue. it is with platform/screen.c in scale_logical_to_pixels(). That method doesn't handle the rounding properly.
Try changing the methods to include rounding and see if that fixes it.
static int scale_logical_to_pixels(int logical_value)
{
// Add 50 to force 0.5 rounding.
return (logical_value * scale_percentage + 50) / 100;
}
static int scale_pixels_to_logical(int pixel_value)
{
return (pixel_value * 100 + scale_percentage / 2) / scale_percentage;
}
I might be wrong about one of the methods. I need to verify the rounding calculation still.
EDIT: I think the edit I made should be correct, but I will need to test a build with these changes and not the former changes.
You're right about your conclusion, we haven't fixed the underlying issue, but simlly rounding up will result in wrong values being calculated for other screen sizes. The only perfect solution would be to use floats instead of ints for pixel values which would be its own can of worms :/
I disagree. Rounding half-way should not break other screen sizes.
Although, if there is a concern there maybe a few tests are needed to verify this is safe to change.
In effect what I am doing is close to a float 0.5 rounding method.
After doing all the calculations I realize what you are saying. I think using the second method gets the correct results. Using them together compounds rounding errors.
I tested your code:
#include <stdio.h>
static int scale_percentage = 150;
static int scale_logical_to_pixels(int logical_value)
{
// Add 50 to force 0.5 rounding.
return (logical_value * scale_percentage + 50) / 100;
}
static int scale_pixels_to_logical(int pixel_value)
{
return (pixel_value * 100 + scale_percentage / 2) / scale_percentage;
}
int main(void) {
int x = 2560;
int y = scale_pixels_to_logical(x);
int z = scale_logical_to_pixels(y);
printf("Original: %i\nRescaled: %i\n", x, z);
return 0;
}
2560 gets converted to 2561 :/
Try using just the scale_pixels_to_logical() modifications. It does seem like we need to preserve more decimals to get this right though even if they are stored as integers.
If none of this works, just go ahead with your changes @crudelios since they will work around the issue for now.
Just using scale_pixels_to_logical turns 2558 to 2557, and will round down every three numbers.
To be honest, it seems like two logical mappings are needed here:
The scaled actual would be mapped back to the screen whenever possible not losing pixel accuracy instead of trying to remap the degraded logical mapping to the screen. it is basically integer encoded fixed point math.
I found the cause of this. From the SDL 1.2 to 2.0 migration guide with regard to SDL_RenderSetLogicalSize, which we are using for the scaling:
On my 1920x1200 monitor, this app thinks it's talking to a 640x480 resolution now, but SDL is using the GPU to scale it up to use all those pixels. Note that 640x480 and 1920x1200 aren't the same aspect ratio: SDL takes care of that, too, scaling as much as possible and letterboxing the difference.
The letterboxing causes SDL to add one black pixel to the right in our case, which causes that pixel to not be scrollable without the fix we did today.
I'll have a look at the SDL source to see how they map the pixels when using SDL_RenderSetLogicalSize. If we duplicate that, we should be ok, but I think we should keep today's fix just to be safe.
I did some experiments: with the original code, we get these results when attempting to scale (where "letterbox" means an additional pixel at the bottom, and "sidebar" means an additional pixel at the right):
2560 x 1440 at scale 105: exact scale
2560 x 1440 at scale 110: exact scale
2560 x 1440 at scale 115: exact scale
2560 x 1440 at scale 120: exact scale
2560 x 1440 at scale 125: exact scale
2560 x 1440 at scale 130: exact scale
2560 x 1440 at scale 135: exact scale
2560 x 1440 at scale 140: exact scale
2560 x 1440 at scale 145: exact scale
2560 x 1440 at scale 150: sidebar of 1px
2560 x 1440 at scale 155: exact scale
2560 x 1440 at scale 160: exact scale
2560 x 1440 at scale 165: exact scale
2560 x 1440 at scale 170: sidebar of 1px
2560 x 1440 at scale 175: exact scale
2560 x 1440 at scale 180: exact scale
2560 x 1440 at scale 185: exact scale
2560 x 1440 at scale 190: letterbox of 1px
2560 x 1440 at scale 195: exact scale
And with @daflame76's suggestion:
2560 x 1440 at scale 105: exact scale
2560 x 1440 at scale 110: exact scale
2560 x 1440 at scale 115: exact scale
2560 x 1440 at scale 120: exact scale
2560 x 1440 at scale 125: exact scale
2560 x 1440 at scale 130: sidebar of 1px
2560 x 1440 at scale 135: sidebar of 1px
2560 x 1440 at scale 140: exact scale
2560 x 1440 at scale 145: exact scale
2560 x 1440 at scale 150: exact scale
2560 x 1440 at scale 155: exact scale
2560 x 1440 at scale 160: exact scale
2560 x 1440 at scale 165: exact scale
2560 x 1440 at scale 170: exact scale
2560 x 1440 at scale 175: exact scale
2560 x 1440 at scale 180: exact scale
2560 x 1440 at scale 185: exact scale
2560 x 1440 at scale 190: sidebar of 1px
2560 x 1440 at scale 195: letterbox of 1px
Conclusion: it doesn't matter how you do the scaling, there will always be cases where there is a 1px discrepancy between what we want and what SDL wants. So I suggest leaving the current calculations (and the fix) in place. I'll update the comment in scroll.c with some more clarification.
This fix works for all the corner cases that I've tried. Thank you both you for this.
Most helpful comment
This fix works for all the corner cases that I've tried. Thank you both you for this.