Skip to content

Commit

Permalink
Allow window dragging by ALT+WIN combination
Browse files Browse the repository at this point in the history
Console command center_screen that centers game window on execute
Dropped support for -draw_borders command line key
  • Loading branch information
Xottab-DUTY committed Jul 24, 2018
1 parent 7548af9 commit 0a1a0a4
Show file tree
Hide file tree
Showing 8 changed files with 122 additions and 69 deletions.
60 changes: 55 additions & 5 deletions src/xrEngine/Device_Initialize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include "PerformanceAlert.hpp"
#include "xrCore/ModuleLookup.hpp"

SDL_HitTestResult WindowHitTest(SDL_Window* win, const SDL_Point* area, void* data);

void CRenderDevice::initialize_weather_editor()
{
m_editor_module = XRay::LoadModule("xrWeatherEditor");
Expand Down Expand Up @@ -43,14 +45,14 @@ void CRenderDevice::Initialize()

if (!m_sdlWnd)
{
Uint32 flags = SDL_WINDOW_BORDERLESS | SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL;
#if SDL_VERSION_ATLEAST(2, 0, 5)
flags |= SDL_WINDOW_ALWAYS_ON_TOP;
#endif
const Uint32 flags = SDL_WINDOW_BORDERLESS | SDL_WINDOW_HIDDEN |
SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_OPENGL;

m_sdlWnd = SDL_CreateWindow("S.T.A.L.K.E.R.: Call of Pripyat", 0, 0, 0, 0, flags);
m_sdlWnd = SDL_CreateWindow("S.T.A.L.K.E.R.: Call of Pripyat", 0, 0, 256, 192, flags);

R_ASSERT3(m_sdlWnd, "Unable to create SDL window", SDL_GetError());
SDL_SetWindowHitTest(m_sdlWnd, WindowHitTest, nullptr);
SDL_SetWindowMinimumSize(m_sdlWnd, 256, 192);
}
}

Expand All @@ -62,3 +64,51 @@ void CRenderDevice::DumpStatistics(IGameFont& font, IPerformanceAlert* alert)
if (alert && stats.fFPS < 30)
alert->Print(font, "FPS < 30: %3.1f", stats.fFPS);
}

SDL_HitTestResult WindowHitTest(SDL_Window* /*window*/, const SDL_Point* area, void* /*data*/)
{
const auto& rect = Device.m_rcWindowClient;

// size of additional interactive area (in pixels)
constexpr int hit = 15;

const bool leftSide = area->x < rect.x + hit;
const bool topSide = area->y < rect.y + hit;
const bool bottomSide = area->y > rect.h - hit;
const bool rightSide = area->x > rect.w - hit;

if (leftSide && topSide)
return SDL_HITTEST_RESIZE_TOPLEFT;

if (rightSide && topSide)
return SDL_HITTEST_RESIZE_TOPRIGHT;

if (rightSide && bottomSide)
return SDL_HITTEST_RESIZE_BOTTOMRIGHT;

if (leftSide && bottomSide)
return SDL_HITTEST_RESIZE_BOTTOMLEFT;

if (topSide)
return SDL_HITTEST_RESIZE_TOP;

if (rightSide)
return SDL_HITTEST_RESIZE_RIGHT;

if (bottomSide)
return SDL_HITTEST_RESIZE_BOTTOM;

if (leftSide)
return SDL_HITTEST_RESIZE_LEFT;

const int centerX = rect.w / 2;
const int centerY = rect.h / 2;

// Allow drag from any point except window center
// For this case, 'hit' is a size of a square in the center
if ((area->x > centerX + hit || area->x < centerX - hit)
&& (area->y > centerY + hit || area->y < centerY - hit))
return SDL_HITTEST_DRAGGABLE;

return SDL_HITTEST_NORMAL;
}
76 changes: 25 additions & 51 deletions src/xrEngine/Device_create.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ void CRenderDevice::Create()
psDeviceFlags.set(rsFullscreen, false);

FillVidModesToken(Vid_SelectedMonitor);
SelectResolution(!psDeviceFlags.is(rsFullscreen));
UpdateWindowProps(!psDeviceFlags.is(rsFullscreen));
GEnv.Render->Create(m_sdlWnd, dwWidth, dwHeight, fWidth_2, fHeight_2);

Expand All @@ -73,49 +72,20 @@ void CRenderDevice::Create()
PreCache(0, false, false);
}

void CRenderDevice::UpdateWindowProps(bool windowed)
void CRenderDevice::UpdateWindowProps(const bool windowed)
{
SelectResolution(windowed);

SDL_SetWindowFullscreen(m_sdlWnd, windowed ? 0 : SDL_WINDOW_FULLSCREEN);
SDL_Rect rect;

// Set window properties depending on what mode were in.
if (windowed)
{
const bool drawBorders = strstr(Core.Params, "-draw_borders");
if (drawBorders)
SDL_SetWindowBordered(m_sdlWnd, SDL_TRUE);

SDL_SetWindowSize(m_sdlWnd, psCurrentVidMode[0], psCurrentVidMode[1]);

if (GEnv.isDedicatedServer || strstr(Core.Params, "-center_screen"))
SDL_SetWindowPosition(m_sdlWnd, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
else
{
SDL_GetDisplayUsableBounds(Vid_SelectedMonitor, &rect);

int top = 0, left = 0, right = 0, bottom = 0;
// SDL_GetWindowBordersSize(m_sdlWnd, &top, &left, &bottom, &right);
#ifdef WINDOWS
// XXX: Currently SDL_GetWindowBordersSize is supported only on X11
// For now we must use method below.
if (drawBorders)
top = GetSystemMetrics(SM_CYCAPTION); // size of the window title bar
#else
#pragma TODO("Implement for other platforms")
#endif
SDL_SetWindowPosition(m_sdlWnd, rect.x + left, rect.y + top);
}

SDL_GetWindowPosition(m_sdlWnd, &m_rcWindowClient.x, &m_rcWindowClient.y);
int w = 0, h = 0;
SDL_GetWindowSize(m_sdlWnd, &w, &h);
m_rcWindowClient.w = m_rcWindowClient.x + w;
m_rcWindowClient.h = m_rcWindowClient.y + h;
}
else
{
// XXX: fix monitor selection
// it appears to be buggy
SDL_Rect rect;
SDL_GetDisplayBounds(Vid_SelectedMonitor, &rect);
SDL_SetWindowPosition(m_sdlWnd, rect.x, rect.y);
SDL_DisplayMode mode;
Expand All @@ -126,31 +96,35 @@ void CRenderDevice::UpdateWindowProps(bool windowed)
SDL_SetWindowDisplayMode(m_sdlWnd, &mode);
}

if (!GEnv.isDedicatedServer)
SDL_SetWindowGrab(m_sdlWnd, SDL_TRUE);

UpdateWindowRect();
UpdateWindowRects();
SDL_FlushEvents(SDL_WINDOWEVENT, SDL_SYSWMEVENT);
}


void CRenderDevice::UpdateWindowRect()
void CRenderDevice::UpdateWindowRects()
{
SDL_GetWindowPosition(m_sdlWnd, &m_rcWindowClient.x, &m_rcWindowClient.y);
m_rcWindowClient.x = 0;
m_rcWindowClient.y = 0;
SDL_GetWindowSize(m_sdlWnd, &m_rcWindowClient.w, &m_rcWindowClient.h);
m_rcWindowClient.w += m_rcWindowClient.x;
m_rcWindowClient.h += m_rcWindowClient.y;

SDL_GetWindowPosition(m_sdlWnd, &m_rcWindowBounds.x, &m_rcWindowBounds.y);
SDL_GetWindowSize(m_sdlWnd, &m_rcWindowBounds.w, &m_rcWindowBounds.h);
m_rcWindowBounds.w += m_rcWindowBounds.x;
m_rcWindowBounds.h += m_rcWindowBounds.y;

// Do we need code below?
int top, left, bottom, right;
SDL_GetWindowBordersSize(m_sdlWnd, &top, &left, &bottom, &right);
m_rcWindowBounds.x -= left;
m_rcWindowBounds.y -= top;
m_rcWindowBounds.w += right;
m_rcWindowBounds.h += bottom;
// XXX: check if we need this code when SDL_GetWindowBordersSize
// will be available for Windows
}

void CRenderDevice::SelectResolution(bool windowed)
void CRenderDevice::SelectResolution(const bool windowed)
{
if (GEnv.isDedicatedServer)
{
dwWidth = 640;
dwHeight = 480;
return;
}

if (windowed)
{
dwWidth = psCurrentVidMode[0];
Expand All @@ -172,7 +146,7 @@ void CRenderDevice::SelectResolution(bool windowed)
if (SDL_GetClosestDisplayMode(Vid_SelectedMonitor, &current, &closest))
xr_sprintf(buff, sizeof(buff), "vid_mode %dx%d", closest.w, closest.h);
else
xr_sprintf(buff, sizeof(buff), "vid_mode %s", VidModesToken[0].name);
xr_sprintf(buff, sizeof(buff), "vid_mode %s", VidModesToken.back());

Console->Execute(buff);
}
Expand Down
9 changes: 5 additions & 4 deletions src/xrEngine/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ void CRenderDevice::message_loop()
switch (event.window.event)
{
case SDL_WINDOWEVENT_MOVED:
UpdateWindowRect();
UpdateWindowRects();
break;

case SDL_WINDOWEVENT_RESIZED:
Expand All @@ -362,21 +362,19 @@ void CRenderDevice::message_loop()
Reset();
}
else
UpdateWindowRect();
UpdateWindowRects();

break;
}

case SDL_WINDOWEVENT_SHOWN:
case SDL_WINDOWEVENT_ENTER:
case SDL_WINDOWEVENT_FOCUS_GAINED:
case SDL_WINDOWEVENT_RESTORED:
case SDL_WINDOWEVENT_MAXIMIZED:
OnWM_Activate(1, event.window.data2);
break;

case SDL_WINDOWEVENT_HIDDEN:
case SDL_WINDOWEVENT_LEAVE:
case SDL_WINDOWEVENT_FOCUS_LOST:
case SDL_WINDOWEVENT_MINIMIZED:
OnWM_Activate(0, event.window.data2);
Expand Down Expand Up @@ -418,6 +416,9 @@ void CRenderDevice::Run()
seqAppStart.Process();
GEnv.Render->ClearTarget();
splash::hide();
if (GEnv.isDedicatedServer)
SDL_SetWindowPosition(m_sdlWnd, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
SDL_HideWindow(m_sdlWnd);
SDL_FlushEvents(SDL_WINDOWEVENT, SDL_SYSWMEVENT);
SDL_ShowWindow(m_sdlWnd);
SDL_RaiseWindow(m_sdlWnd);
Expand Down
9 changes: 6 additions & 3 deletions src/xrEngine/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ class ENGINE_API CRenderDeviceData
u32 dwWidth;
u32 dwHeight;

// Real application window resolution
SDL_Rect m_rcWindowBounds;

// Real game window resolution
SDL_Rect m_rcWindowClient;

Expand Down Expand Up @@ -248,9 +251,9 @@ class ENGINE_API CRenderDevice : public CRenderDeviceBase
void Destroy(void);
void Reset(bool precache = true);

void UpdateWindowProps(bool windowed);
void UpdateWindowRect();
void SelectResolution(bool windowed);
void UpdateWindowProps(const bool windowed);
void UpdateWindowRects();
void SelectResolution(const bool windowed);

void Initialize(void);
void ShutDown(void);
Expand Down
7 changes: 2 additions & 5 deletions src/xrEngine/xr_input.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ CInput::CInput(bool exclusive, int deviceForInit)
//===================== Dummy pack
iCapture(&dummyController);

SDL_SetRelativeMouseMode(SDL_TRUE);

xrDebug::SetDialogHandler(on_error_dialog);

#ifdef ENGINE_BUILD
Expand All @@ -66,7 +64,6 @@ CInput::CInput(bool exclusive, int deviceForInit)

CInput::~CInput(void)
{
SDL_SetRelativeMouseMode(SDL_FALSE);
#ifdef ENGINE_BUILD
Device.seqFrame.Remove(this);
Device.seqAppDeactivate.Remove(this);
Expand Down Expand Up @@ -232,12 +229,12 @@ void CInput::ClipCursor(bool clip)
{
if (clip)
{
SDL_ShowCursor(SDL_DISABLE);
SDL_SetWindowGrab(Device.m_sdlWnd, SDL_TRUE);
SDL_SetRelativeMouseMode(SDL_TRUE);
}
else
{
SDL_ShowCursor(SDL_ENABLE);
SDL_SetWindowGrab(Device.m_sdlWnd, SDL_FALSE);
SDL_SetRelativeMouseMode(SDL_FALSE);
}
}
Expand Down
11 changes: 11 additions & 0 deletions src/xrEngine/xr_ioc_cmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -657,6 +657,16 @@ class ENGINE_API CCC_HideConsole : public IConsole_Command
virtual void Info(TInfo& I) { xr_sprintf(I, sizeof(I), "hide console"); }
};

class CCC_CenterScreen : public IConsole_Command
{
public:
CCC_CenterScreen(pcstr name) : IConsole_Command(name) { bEmptyArgsHandled = true; }
void Execute(pcstr args) override
{
SDL_SetWindowPosition(Device.m_sdlWnd, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
}
};

ENGINE_API float psHUD_FOV = 0.45f;

// extern int psSkeletonUpdate;
Expand Down Expand Up @@ -787,6 +797,7 @@ void CCC_Register()
CMD2(CCC_Float, "cam_inert", &psCamInert);
CMD2(CCC_Float, "cam_slide_inert", &psCamSlideInert);

CMD1(CCC_CenterScreen, "center_screen");
CMD4(CCC_Integer, "always_active", &ps_always_active, 0, 1);

CMD1(CCC_r2, "renderer");
Expand Down
17 changes: 17 additions & 0 deletions src/xrGame/MainMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "profile_store.h"
#include "stats_submitter.h"
#include "atlas_submit_queue.h"
#include "xrEngine/xr_input.h"

// fwd. decl.
extern ENGINE_API BOOL bShowPauseString;
Expand Down Expand Up @@ -333,6 +334,7 @@ void CMainMenu::IR_OnMouseMove(int x, int y)

void CMainMenu::IR_OnMouseStop(int x, int y){};

bool IWantMyMouseBackScreamed = false;
void CMainMenu::IR_OnKeyboardPress(int dik)
{
if (!IsActive())
Expand All @@ -343,6 +345,14 @@ void CMainMenu::IR_OnKeyboardPress(int dik)
Console->Show();
return;
}

if (pInput->iGetAsyncKeyState(SDL_SCANCODE_LALT) || pInput->iGetAsyncKeyState(SDL_SCANCODE_RALT)
&& pInput->iGetAsyncKeyState(SDL_SCANCODE_LGUI) || pInput->iGetAsyncKeyState(SDL_SCANCODE_RGUI))
{
IWantMyMouseBackScreamed = true;
pInput->ClipCursor(false);
}

if (SDL_SCANCODE_F12 == dik)
{
GEnv.Render->Screenshot();
Expand All @@ -357,6 +367,13 @@ void CMainMenu::IR_OnKeyboardRelease(int dik)
if (!IsActive())
return;

if (IWantMyMouseBackScreamed)
{
IWantMyMouseBackScreamed = false;
pInput->ClipCursor(true);
}


CDialogHolder::IR_UIOnKeyboardRelease(dik);
};

Expand Down
2 changes: 1 addition & 1 deletion src/xrGame/UICursor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ void CUICursor::InitInternal()
const u32 screen_size_y = display.h - display.y;
m_b_use_win_cursor = screen_size_y >= Device.dwHeight && screen_size_x >= Device.dwWidth;
if (m_b_use_win_cursor) // sanity
Device.UpdateWindowRect();
Device.UpdateWindowRects();
}

//--------------------------------------------------------------------
Expand Down

0 comments on commit 0a1a0a4

Please sign in to comment.