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
131 changes: 81 additions & 50 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 {
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);
triangleHeight += deltaTriangle.y;
triangleWidth += deltaTriangle.x;
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);
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);
}
} // namespace

void CGame::EventHandling(SDL_Event* Event)
{
switch(Event->type)
Expand Down Expand Up @@ -83,47 +118,9 @@ void CGame::EventHandling(SDL_Event* Event)
break;
#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);
}
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_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);
}
break;
case SDLK_F5: tryZoom(Position(11, 5), 1, MapObj.get()); break;
case SDLK_F6: resetZoom(MapObj.get()); break;
case SDLK_F7: tryZoom(Position(-11, -5), -1, MapObj.get()); break;

default: break;
}
Expand All @@ -142,17 +139,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 +381,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
27 changes: 8 additions & 19 deletions CMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,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 @@ -501,10 +501,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.

// 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(motion.x, motion.y, motion.state);
Expand Down Expand Up @@ -994,24 +993,15 @@ void CMap::storeVerticesFromMouse(Uint16 MouseX, Uint16 MouseY, Uint8 /*MouseSta
// 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;
Xeven = (MouseX + 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;
// Add rows are already shifted by triangleWidth / 2
Xodd = (MouseX + displayRect.left) / triangleWidth;
// Xodd = (MouseX + 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 = MouseY + 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 = MouseY - (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 @@ -1085,9 +1075,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));

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.

Even though it may have been intended at some point: Why is this required?

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.

To draw black background for small map&large screen.
Otherwise mouse and map leave trails that are not drawn over.

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.

But this is due to buggy zoom I guess where it doesn't draw toroidal wrapping map correctly. There should be no empty space in terrain editor.

In OpenGL branch I fixed this now. But idk how review will go. morganchristiansson/s25edit@resize-window...opengl-small

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 why. With small map&large screen the map wrap doesn't work fully.
image


// 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 @@ -2711,7 +2711,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 @@ -2747,13 +2746,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 @@ -2785,7 +2786,6 @@ void callback::MinimapMenu(int Param)
WNDMinimap = nullptr;
}
MapObj = nullptr;
WndSurface = nullptr;
global::s2->UnregisterCallback(MinimapMenu);
break;

Expand Down