Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 81 additions & 46 deletions CGame_Event.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,41 @@
#include "callbacks.h"
#include "globals.h"

namespace {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why am I using anonymous namespaces like this?

Please advice, my review overlords.

@morganchristiansson morganchristiansson Jun 30, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok it's just file local helper function that is not available from other object files.
So it's fine. Not needed but whatever.
I'd assumed that not being added to .h would've made it inaccessible but I guess this is explicit and goes further.
AI adds these on it's own initiative and then makes a mess and chokes on it when there's multiple namespace scopes in same file.

bool tryZoom(Position deltaTriangle, int deltaInc, CMap* mapObj)
{
if(!mapObj || !mapObj->getMap())
return false;
const int newInc = triangleIncrease + deltaInc;
if(newInc < 1 || newInc > 10)
return false;

callback::PleaseWait(INITIALIZING_CALL);
triangleWidth += deltaTriangle.x;
triangleHeight += deltaTriangle.y;
triangleIncrease += deltaInc;
bobMAP* myMap = mapObj->getMap();
myMap->updateVertexCoords();
CSurface::get_nodeVectors(*myMap);
callback::PleaseWait(WINDOW_QUIT_MESSAGE);
return true;
}

void resetZoom(CMap* mapObj)
{
if(!mapObj || !mapObj->getMap())
return;
callback::PleaseWait(INITIALIZING_CALL);
triangleWidth = TRIANGLE_WIDTH_DEFAULT;
triangleHeight = TRIANGLE_HEIGHT_DEFAULT;
triangleIncrease = TRIANGLE_INCREASE_DEFAULT;
bobMAP* myMap = mapObj->getMap();
myMap->updateVertexCoords();
CSurface::get_nodeVectors(*myMap);
callback::PleaseWait(WINDOW_QUIT_MESSAGE);
}
} // namespace

void CGame::EventHandling(SDL_Event* Event)
{
switch(Event->type)
Expand Down Expand Up @@ -84,45 +119,11 @@ void CGame::EventHandling(SDL_Event* Event)
#endif
// F5 - F7 is ZOOM, F5 = zoom in, F6 = normal view, F7 = zoom out
case SDLK_F5:
if(triangleIncrease < ZOOM_INCREASE_MAX && MapObj->getMap())
{
callback::PleaseWait(INITIALIZING_CALL);
triangleHeight += ZOOM_STEP_HEIGHT;
triangleWidth += ZOOM_STEP_WIDTH;
triangleIncrease += ZOOM_STEP_INCREASE;
bobMAP* myMap = MapObj->getMap();
myMap->updateVertexCoords();
CSurface::get_nodeVectors(*myMap);
callback::PleaseWait(WINDOW_QUIT_MESSAGE);
}
tryZoom(Position(ZOOM_STEP_WIDTH, ZOOM_STEP_HEIGHT), ZOOM_STEP_INCREASE, MapObj.get());
break;
case SDLK_F6:
{
if(MapObj->getMap())
{
callback::PleaseWait(INITIALIZING_CALL);
triangleHeight = TRIANGLE_HEIGHT_DEFAULT;
triangleWidth = TRIANGLE_WIDTH_DEFAULT;
triangleIncrease = TRIANGLE_INCREASE_DEFAULT;
bobMAP* myMap = MapObj->getMap();
myMap->updateVertexCoords();
CSurface::get_nodeVectors(*myMap);
callback::PleaseWait(WINDOW_QUIT_MESSAGE);
}
}
break;
case SDLK_F6: resetZoom(MapObj.get()); break;
case SDLK_F7:
if(triangleIncrease > ZOOM_INCREASE_MIN && MapObj->getMap())
{
callback::PleaseWait(INITIALIZING_CALL);
triangleHeight -= ZOOM_STEP_HEIGHT;
triangleWidth -= ZOOM_STEP_WIDTH;
triangleIncrease -= ZOOM_STEP_INCREASE;
bobMAP* myMap = MapObj->getMap();
myMap->updateVertexCoords();
CSurface::get_nodeVectors(*myMap);
callback::PleaseWait(WINDOW_QUIT_MESSAGE);
}
tryZoom(Position(-ZOOM_STEP_WIDTH, -ZOOM_STEP_HEIGHT), -ZOOM_STEP_INCREASE, MapObj.get());
break;

default: break;
Expand All @@ -142,17 +143,17 @@ void CGame::EventHandling(SDL_Event* Event)

case SDL_MOUSEMOTION:
{
// setup mouse cursor data
if(MapObj && MapObj->isActive())
// Avoid duplicate events especially when warping the mouse back during panning
{
if((Event->motion.state & SDL_BUTTON(SDL_BUTTON_RIGHT)) == 0)
{
Cursor.pos = Position(Event->motion.x, Event->motion.y);
}
} else
{
Cursor.pos = Position(Event->motion.x, Event->motion.y);
static Position lastMousePos = Position::Invalid();
const Position newPos(Event->motion.x, Event->motion.y);
if(newPos == lastMousePos)
break;
lastMousePos = newPos;
}

// setup mouse cursor data
Cursor.pos = Position(Event->motion.x, Event->motion.y);
/*
//NOTE: we will now deliver the data to menus, windows, map etc., sometimes we have to break the
switch and stop
Expand Down Expand Up @@ -384,6 +385,40 @@ void CGame::EventHandling(SDL_Event* Event)
break;
}

case SDL_MOUSEWHEEL:
{
if(!MapObj)
break;

int y = Event->wheel.y;
if(Event->wheel.direction == SDL_MOUSEWHEEL_FLIPPED)
y = -y;
if(y == 0)
break;

const Position deltaTri = (y > 0) ? Position(11, 5) : Position(-11, -5);
const int deltaInc = (y > 0) ? 1 : -1;

// Save values before zoom for cursor-centered adjustment
const PointF oldTriSize(triangleWidth, triangleHeight);
const PointF mousePos(Cursor.pos);

if(!tryZoom(deltaTri, deltaInc, MapObj.get()))
break;

// Keep the map point under the cursor stable after zoom
DisplayRectangle dr = MapObj->getDisplayRect();
const PointF ratio(triangleWidth / oldTriSize.x, triangleHeight / oldTriSize.y);
const auto size = dr.getSize();
const PointF newOrigin = (PointF(dr.getOrigin()) + mousePos) * ratio - mousePos;
dr.left = static_cast<Sint32>(newOrigin.x);
dr.top = static_cast<Sint32>(newOrigin.y);
dr.right = dr.left + size.x;
dr.bottom = dr.top + size.y;
MapObj->setDisplayRect(dr);
break;
}

case SDL_WINDOWEVENT:
{
if(Event->window.event == SDL_WINDOWEVENT_RESIZED)
Expand Down
29 changes: 9 additions & 20 deletions CMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,7 @@ void CMap::moveMap(Position offset)
void CMap::setMouseData(const SDL_MouseMotionEvent& motion)
{
// following code important for blitting the right field of the map
// Are we scrolling?
// Are we scrolling? (right mouse button held)
if(startScrollPos)
{
assert(motion.state & SDL_BUTTON(3));
Expand All @@ -504,10 +504,9 @@ void CMap::setMouseData(const SDL_MouseMotionEvent& motion)
offset.y = 0;
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);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is matching current s25client VideoSDL2.cpp which doesn't use SDL_EventState.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is not a good reason to me.

// Warp mouse back to start position so we can keep scrolling
// Duplicate motion events generated by this warp are filtered in CGame::EventHandling
SDL_WarpMouseInWindow(nullptr, startScrollPos->x, startScrollPos->y);
SDL_EventState(SDL_MOUSEMOTION, SDL_ENABLE);
}

storeVerticesFromMouse(Position(motion.x, motion.y), motion.state);
Expand Down Expand Up @@ -995,26 +994,17 @@ void CMap::storeVerticesFromMouse(Position mousePos, Uint8 /*MouseState*/)

// get X
// following out commented lines are the correct ones, but for tolerance (to prevent to early jumps of the cursor)
// we subtract "triangleWidth/2" Xeven = (MouseX + displayRect.left) / triangleWidth;
// we subtract "triangleWidth/2" Xeven = (mousePos.x + displayRect.left) / triangleWidth;
Xeven = (mousePos.x + displayRect.left - triangleWidth / 2) / triangleWidth;
if(Xeven < 0)
Xeven += (map->width);
else if(Xeven > map->width - 1)
Xeven -= (map->width - 1);
Xeven = ((Xeven % map->width) + map->width) % map->width;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a function for that please? Something like int positiveIntegerModulo(int,int) or see if your AI can come up with a better name. I'm worried about repeating the same value 3 times per line which at least makes review hard as there might be a C&P mistake somewhere

// Add rows are already shifted by triangleWidth / 2
Xodd = (mousePos.x + displayRect.left) / triangleWidth;
// Xodd = (mousePos.x + displayRect.left) / triangleWidth;
if(Xodd < 0)
Xodd += (map->width - 1);
else if(Xodd > map->width - 1)
Xodd -= (map->width);
Xodd = ((Xodd % (map->width - 1)) + (map->width - 1)) % (map->width - 1);

MousePosY = mousePos.y + displayRect.top;
// correct mouse position Y if displayRect is outside map edges
if(MousePosY < 0)
MousePosY += map->height_pixel;
else if(MousePosY > map->height_pixel)
MousePosY = mousePos.y - (map->height_pixel - displayRect.top);
MousePosY = ((MousePosY % map->height_pixel) + map->height_pixel) % map->height_pixel;

// get Y
for(int j = 0; j < map->height; j++)
Expand Down Expand Up @@ -1088,9 +1078,8 @@ void CMap::render()
else
Surf_Map = makeRGBSurface(displayRect.getSize().x, displayRect.getSize().y);
}
// else
// 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));
Comment thread
Flamefire marked this conversation as resolved.

// touch vertex data if user modifies it
if(modify)
Expand Down
10 changes: 5 additions & 5 deletions callbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2819,7 +2819,6 @@ void callback::MinimapMenu(int Param)
{
static CWindow* WNDMinimap = nullptr;
static CMap* MapObj = nullptr;
static SDL_Surface* WndSurface = nullptr;
static int scaleNum = 1;
// only in case INITIALIZING_CALL needed to create the window
int width;
Expand Down Expand Up @@ -2855,13 +2854,15 @@ void callback::MinimapMenu(int Param)
std::make_unique<CWindow>(MinimapMenu, WINDOWQUIT, WindowPos::Center, Extent(width + 12, height + 30),
"Overview", WINDOW_NOTHING, WINDOW_CLOSE | WINDOW_MOVE));
global::s2->RegisterCallback(MinimapMenu);
WndSurface = WNDMinimap->getSurface();
}
break;

case CALL_FROM_GAMELOOP:
if(MapObj && WndSurface)
MapObj->drawMinimap(WndSurface);
if(MapObj && WNDMinimap)
{
if(SDL_Surface* surf = WNDMinimap->getSurface())
MapObj->drawMinimap(surf);
}
break;

case WINDOW_CLICKED_CALL:
Expand Down Expand Up @@ -2893,7 +2894,6 @@ void callback::MinimapMenu(int Param)
WNDMinimap = nullptr;
}
MapObj = nullptr;
WndSurface = nullptr;
global::s2->UnregisterCallback(MinimapMenu);
break;

Expand Down