Want to praise Simutrans?
Your feedback is important for us ;D.

New zoom out level, mouse pointer <> tile misalignment

Started by hreintke, February 28, 2023, 03:32:34 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.



I always played with pak64 but now seeing how pak128 is working.

One thing that struck me is that the possibility of zoom out is rather limited.

I added an addional zoom out level and that (seems) working OK for now.
Except that the mouse pointer is not aligned with the selected tile.
The height is OK, but the seleted tile is to far to the right.

Can someone point me to the source location where the mouse to tile translation is handled ?


This is done in viewport_t class, i.e., viewport_t::get_ground_on_screen_coordinate, in src/simutrans/display/

However, this routines only need to know the current tile size (scaled size of the standard zoomed 64/128 tile). So adding additional zoom levels should work with respect to mouse handling.
Parsley, sage, rosemary, and maggikraut.



Will check there.
There is a difference when using pak64 vs pak128.

I have added the 1/12, 1/16, 1/20 zoom levels.

Pak64, 1/12, tile display OK, cursor/tile OK, main display see attachments.
Pak64, 1/16, to small

Pak128, 1/12, tile display OK, cursor/tile off, main display OK,
Pak128, 1/16, tile display not OK (don't know yet whether is is just the zooming), cursor/tile OK, main display OK.
Pak128, 1/16, tile display not OK (don't know yet whether is is just the zooming), cursor/tile not OK, main display OK.

1/12 and 1/20 zoom doesn't get to integer number of bits (10.67, 6.4) but 4/3 zoom level doesn't either and has cursor/tile OK.

I will investigate further and give feedback here.



The important part is that the tile is even, since the front slope is 0.5.
With 4/3 no problem new tile size is 170, half tile is 85.

That fails to work (the slope of 2) as soon as the tile size becomes odd: 64/20=3(.2) or 64/12=5(.3333).

1/16 should work for both paks. 1/12 should work for pak128 and pak72.


1/ Got some further on the zoomed image display when using zoom level 16 and up.

This is a part of the display at level 12 :


This is a part of the display at level 16.


Size is correct but colors are completely off.

In the code of, static void rezoom_img(const image_id n) is handling the actual zoom in/out of the image.

After having added colors in the "to be cominined area using :
if(*(p)<255  &&  valid<255)
valid = 255; r = g = b = 0;
} else {
valid ++;
r += (p)[1];
g += (p)[2];
b += (p)[3];
It is caluculated using :

if(  valid == 0  ) {
*dest++ = 0x73FE;
else if(  valid == 255  ) {
*dest++ = (0x8000 | r) + (((uint16)g)<<5) + (((uint16)b)<<10);
else {
*dest++ = (r/valid) | (((uint16)(g/valid))<<5) | (((uint16)(b/valid))<<10);
This calculation gives wrong results on the (valid == 255) path.
And the zoom level 16 is the first level in which the (valid == 255) is passed.

Did some first tests with :

if (valid == 0) {
*dest++ = 0x73FE;
*dest++ = (r / valid) | (((uint16)(g / valid)) << 5) | (((uint16)(b / valid)) << 10);
That seems to give correct display, of course not sure on any side effects yet.


Questions :
- What is the use of the color code 0x73FE ?
- What is the use of the MSB bit id the PIXVAL, which is set by the current code in case of (valid == 255)

2/ Still struggling the the cursor/selected tile mismatch.

Mismatch only on pak128, not pak64

This occurs on the zoom 12 and 20 level, 16 is OK.
This mismatch is only in the horizontal direction, vertical is OK.
The mismatch is getting larger from left to right on the screen.
Left is (almost) OK, right is way off.

Checking futher, hints are welcome.


Could it be that these SubSumPixel calls lead to overflow of the 8bit variable valid, and also to overflows in the r,g,b variables?

I think that magic value is used to mark transparent pixels (i.e. pixels that do not exist in the sprite).
Parsley, sage, rosemary, and maggikraut.


valid is an uint8 and is checked for overflow.
r, g, b are uint16;
dest is PIXVAL which is uint16

PIXVAL is (msb to lsb)

1 bit ?
5 bits blue
5 bits green
5 bits red

r, g and b are the sum of (at most 255) colorvalues in the area.

To my knowledge, zooming out is averaging the r, g, and b values of an area.

I do not understand how the

*dest++ = (0x8000 | r) + (((uint16)g) << 5) + (((uint16)b) << 10);

which uses the sum, can ever lead to averaging values.
Think this will (always) overrun.

But this part of the code is very very old, so it is never reached or I have a misunderstanding of the working.


For zooming out, pixel were simply omitted. Otherwise special colors would not survive.