Fixed out-of-bounds crash for pathfinding spline algorithm. If the game's window is out-of-bounds when setting the position, the game will try to move the window to an appropriate spot to be on-screen, or to a default location if it has trouble finding a spot. Release Build 8723.

pull/57/head
sigonasr2 8 months ago
parent 8c759f0367
commit 254b4b3ea0
  1. 2
      Adventures in Lestoria/Pathfinding.cpp
  2. 2
      Adventures in Lestoria/Version.h
  3. 59
      Adventures in Lestoria/olcPixelGameEngine.h
  4. BIN
      x64/Release/Adventures in Lestoria.exe

@ -224,7 +224,7 @@ Pathfinding::sPoint2D Pathfinding::sSpline::GetSplinePoint(float t, bool bLooped
}
else
{
p1 = (int)t1;
p1 = std::clamp(size_t(t1),size_t(0),points.size()-1);
p2 = (p1 + 1) % points.size();
p3 = (p2 + 1) % points.size();
p0 = p1 >= 1 ? p1 - 1 : points.size() - 1;

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 1
#define VERSION_MINOR 1
#define VERSION_PATCH 0
#define VERSION_BUILD 8706
#define VERSION_BUILD 8723
#define stringify(a) stringify_(a)
#define stringify_(a) #a

@ -1608,6 +1608,7 @@ namespace olc
std::string PixelGameEngine::White;
std::string PixelGameEngine::Black;
std::string PixelGameEngine::Reset; //Will render the original color provided when used.
// O------------------------------------------------------------------------------O
// | olc::Pixel IMPLEMENTATION |
// O------------------------------------------------------------------------------O
@ -6437,6 +6438,17 @@ namespace olc
private:
HWND olc_hWnd = nullptr;
std::wstring wsAppName;
static RECT resultRect;
static bool monitorFound;
static BOOL CALLBACK monitorCallback(HMONITOR monitor, HDC deviceContext, LPRECT rectPtr, LPARAM data){
monitorFound=true;
tagMONITORINFO monitorInfo;
monitorInfo.cbSize=sizeof(MONITORINFO);
GetMonitorInfoA(monitor,&monitorInfo);
resultRect=monitorInfo.rcWork;
return FALSE; //Return false here because we will use the first monitor that EnumDisplayMonitors gives us. By returning false, we are ending the enumeration immediately.
};
std::wstring ConvertS2W(std::string s)
{
@ -6526,6 +6538,24 @@ namespace olc
olc_hWnd = CreateWindowEx(dwExStyle, olcT("OLC_PIXEL_GAME_ENGINE"), olcT(""), dwStyle,
vTopLeft.x, vTopLeft.y, width, height, NULL, NULL, GetModuleHandle(nullptr), this);
monitorFound=false; //After calling EnumDisplayMonitors, monitorCallback will set this variable to true if the clipping rectangle region intersects any monitor.
RECT monitorClippingRect{vTopLeft.x,vTopLeft.y,vTopLeft.x+width,vTopLeft.y+height};
EnumDisplayMonitors(NULL,&monitorClippingRect,monitorCallback,NULL);
if(monitorFound){
vTopLeft.x=std::clamp(long(vTopLeft.x),resultRect.left,resultRect.right);
vTopLeft.y=std::clamp(long(vTopLeft.y),resultRect.top,resultRect.bottom);
int monitorWidth=resultRect.right-resultRect.left;
int monitorHeight=resultRect.bottom-resultRect.top;
bool rightEdgeOutsideBounds_AND_windowWidthFitsOnScreen=vTopLeft.x+width>resultRect.right&&width<monitorWidth;
if(rightEdgeOutsideBounds_AND_windowWidthFitsOnScreen)vTopLeft.x=resultRect.left+(monitorWidth-width);
bool topEdgeOutsideBounds_AND_windowHeightFitsOnScreen=vTopLeft.y+height>resultRect.bottom&&height<monitorHeight;
if(topEdgeOutsideBounds_AND_windowHeightFitsOnScreen)vTopLeft.y=resultRect.top+(monitorHeight-height);
}else vTopLeft={0,0}; //We just give up and put the window back to the default location.
MoveWindow(olc_hWnd,vTopLeft.x,vTopLeft.y,width,height,false); //A hack to get the window's position updated in the correct spot (WM_MOVE reports the correct upper-left corner of the client area)
DragAcceptFiles(olc_hWnd, true);
@ -6613,13 +6643,31 @@ namespace olc
return olc::OK;
}
virtual void SetWindowPos(vi2d pos)override{
if(!ptrPGE->IsFullscreen()){
RECT rWndRect = { 0, 0, ptrPGE->GetWindowSize().x, ptrPGE->GetWindowSize().y };
int width = rWndRect.right - rWndRect.left;
int height = rWndRect.bottom - rWndRect.top;
MoveWindow(olc_hWnd,pos.x, pos.y, width, height,true);
int windowWidth = rWndRect.right - rWndRect.left;
int windowHeight = rWndRect.bottom - rWndRect.top;
monitorFound=false; //After calling EnumDisplayMonitors, monitorCallback will set this variable to true if the clipping rectangle region intersects any monitor.
RECT monitorClippingRect{pos.x,pos.y,pos.x+windowWidth,pos.y+windowHeight};
EnumDisplayMonitors(NULL,&monitorClippingRect,monitorCallback,NULL);
if(monitorFound){
pos.x=std::clamp(long(pos.x),resultRect.left,resultRect.right);
pos.y=std::clamp(long(pos.y),resultRect.top,resultRect.bottom);
int monitorWidth=resultRect.right-resultRect.left;
int monitorHeight=resultRect.bottom-resultRect.top;
bool rightEdgeOutsideBounds_AND_windowWidthFitsOnScreen=pos.x+windowWidth>resultRect.right&&windowWidth<monitorWidth;
if(rightEdgeOutsideBounds_AND_windowWidthFitsOnScreen)pos.x=resultRect.left+(monitorWidth-windowWidth);
bool topEdgeOutsideBounds_AND_windowHeightFitsOnScreen=pos.y+windowHeight>resultRect.bottom&&windowHeight<monitorHeight;
if(topEdgeOutsideBounds_AND_windowHeightFitsOnScreen)pos.y=resultRect.top+(monitorHeight-windowHeight);
}else pos={0,0}; //We just give up and put the window back to the default location.
MoveWindow(olc_hWnd,pos.x, pos.y, windowWidth, windowHeight,true);
}
}
virtual void SetWindowSize(vi2d size)override{
@ -6746,6 +6794,9 @@ namespace olc
return DefWindowProc(hWnd, uMsg, wParam, lParam);
}
};
RECT Platform_Windows::resultRect;
bool Platform_Windows::monitorFound=false;
}
#endif
// O------------------------------------------------------------------------------O

Loading…
Cancel
Save