s25edit backports from s25client#37
Conversation
morganchristiansson
commented
Jun 16, 2026
- Allow window resizing
- Fix segfault with small map&large screen
- Fix black area with small map&large screen
- Fix mouse panning on Linux
- Zoom with mouse wheel
Flamefire
left a comment
There was a problem hiding this comment.
Thanks for the PR, that definitely improves it!
Some notes inline, a common theme is that any pair of x/y or width/height values should use either Point/PointF or Extent which avoids C&P errors and makes processing easier (single assignment instead of 2, operator support for combining with other Points)
Note: In some places fixed-size variants are used. That is historical and not necessary in almost all cases, so no need to introduce new uses of them unless there is a specific reason for the size requirement.
Thanks again!
| // we subtract "TRIANGLE_WIDTH/2" Xeven = (MouseX + displayRect.left) / TRIANGLE_WIDTH; | ||
| Xeven = (MouseX + displayRect.left - TRIANGLE_WIDTH / 2) / TRIANGLE_WIDTH; | ||
| if(Xeven < 0) | ||
| while(Xeven < 0) |
There was a problem hiding this comment.
IIRC this could be a module operation and a single check to account for negative results (possible because neg. values are implementation defined)
There was a problem hiding this comment.
Yeah agree. This was just smallest/simplest fix to a segfault and I didn't care to correct it.
But you're right we should use modulo operation.
| while(MousePosY < 0) | ||
| MousePosY += map->height_pixel; | ||
| else if(MousePosY > map->height_pixel) | ||
| while(MousePosY > map->height_pixel) |
There was a problem hiding this comment.
This might be an infinite loop
| moveMap(offset); | ||
|
|
||
| // this whole "warping-thing" is to prevent cursor-moving WITHIN the window while user moves over the map | ||
| SDL_EventState(SDL_MOUSEMOTION, SDL_IGNORE); |
There was a problem hiding this comment.
Why the change? Isn't handling this "issue" here better where it is caused than where mouse moves should be handled?
IIRC SDL offers a relative mouse mode. As we only support SDL here that might be the best solution if we change this
There was a problem hiding this comment.
This is matching current s25client VideoSDL2.cpp which doesn't use SDL_EventState.
| if(!mapObj || !mapObj->getMap()) | ||
| return; | ||
| callback::PleaseWait(INITIALIZING_CALL); | ||
| TRIANGLE_HEIGHT = 28; |
There was a problem hiding this comment.
Can we have constants for that? Best using e.g. constexpr Extent DEFAULT_TRIANGLE_SIZE(28, 56) and use that here and in the initialization
There was a problem hiding this comment.
This is how zoom is currently implemented in s25editor, by writing to uppercase variables.
I just extracted to shared function for mouse wheel zoom.
The zoom is listed as experimental in F1 help.
| if(y == 0) | ||
| break; | ||
|
|
||
| const int deltaTH = (y > 0) ? 5 : -5; |
There was a problem hiding this comment.
Please use the Point/Position/Extent for X/Y or W/H values. We had too many C&P issues in the past
| const float ratioX = TRIANGLE_WIDTH / oldWidth; | ||
| const float ratioY = TRIANGLE_HEIGHT / oldHeight; | ||
| const auto size = dr.getSize(); | ||
| dr.left = static_cast<Sint32>((dr.left + mouseX) * ratioX - mouseX); |
There was a problem hiding this comment.
This can then use the Point operators like (dr.origin + mousePos) * ratioX - mousPos
Maybe even just dr.move()
|
|
||
| case SDL_WINDOWEVENT: | ||
| { | ||
| switch(Event->window.event) |
There was a problem hiding this comment.
As long as this is the only even please use a simple if which is less verbose and avoids the double-break
There was a problem hiding this comment.
s25client also uses switch with single case and double-break https://github.com/Return-To-The-Roots/s25client/blob/f299328f2109b8cfb5c13edb8f1863eef6da4f07/extras/videoDrivers/SDL2/VideoSDL2.cpp#L340-L357
| GameResolution.x = width; | ||
| GameResolution.y = height; | ||
| displayTexture_.reset(); | ||
| displayTexture_ = makeSdlTexture(renderer_, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, width, height); |
There was a problem hiding this comment.
The same code is in ReCreateWindow, and maybe somewhere else. Can you make those call this function (or the other way round if better)?
| return true; | ||
| } | ||
|
|
||
| void CGame::UpdateDisplaySize(unsigned width, unsigned height) |
| // clear the surface before drawing new (in normal case not needed) | ||
| // SDL_FillRect( Surf_Map, nullptr, SDL_MapRGB(Surf_Map->format,0,0,0) ); | ||
| // Clear the surface before drawing so areas not covered by triangles stay black | ||
| SDL_FillRect(Surf_Map.get(), nullptr, SDL_MapRGBA(Surf_Map->format, 0, 0, 0, 0)); |
There was a problem hiding this comment.
Even though it may have been intended at some point: Why is this required?
There was a problem hiding this comment.
To draw black background for small map&large screen.
Otherwise mouse and map leave trails that are not drawn over.
67f2175 to
604b117
Compare
|
Maybe I should split this into smaller PRs. I was working on import heightmap as I posted about on Discord, not sure I will submit as PR. And these were some quality of life improvements that felt important. |