Skip to content

Commit 0a1a0a4

Browse files
committed
Allow window dragging by ALT+WIN combination
Console command center_screen that centers game window on execute Dropped support for -draw_borders command line key
1 parent 7548af9 commit 0a1a0a4

File tree

8 files changed

+122
-69
lines changed

8 files changed

+122
-69
lines changed

src/xrEngine/Device_Initialize.cpp

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
#include "PerformanceAlert.hpp"
99
#include "xrCore/ModuleLookup.hpp"
1010

11+
SDL_HitTestResult WindowHitTest(SDL_Window* win, const SDL_Point* area, void* data);
12+
1113
void CRenderDevice::initialize_weather_editor()
1214
{
1315
m_editor_module = XRay::LoadModule("xrWeatherEditor");
@@ -43,14 +45,14 @@ void CRenderDevice::Initialize()
4345

4446
if (!m_sdlWnd)
4547
{
46-
Uint32 flags = SDL_WINDOW_BORDERLESS | SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL;
47-
#if SDL_VERSION_ATLEAST(2, 0, 5)
48-
flags |= SDL_WINDOW_ALWAYS_ON_TOP;
49-
#endif
48+
const Uint32 flags = SDL_WINDOW_BORDERLESS | SDL_WINDOW_HIDDEN |
49+
SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALWAYS_ON_TOP | SDL_WINDOW_OPENGL;
5050

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

5353
R_ASSERT3(m_sdlWnd, "Unable to create SDL window", SDL_GetError());
54+
SDL_SetWindowHitTest(m_sdlWnd, WindowHitTest, nullptr);
55+
SDL_SetWindowMinimumSize(m_sdlWnd, 256, 192);
5456
}
5557
}
5658

@@ -62,3 +64,51 @@ void CRenderDevice::DumpStatistics(IGameFont& font, IPerformanceAlert* alert)
6264
if (alert && stats.fFPS < 30)
6365
alert->Print(font, "FPS < 30: %3.1f", stats.fFPS);
6466
}
67+
68+
SDL_HitTestResult WindowHitTest(SDL_Window* /*window*/, const SDL_Point* area, void* /*data*/)
69+
{
70+
const auto& rect = Device.m_rcWindowClient;
71+
72+
// size of additional interactive area (in pixels)
73+
constexpr int hit = 15;
74+
75+
const bool leftSide = area->x < rect.x + hit;
76+
const bool topSide = area->y < rect.y + hit;
77+
const bool bottomSide = area->y > rect.h - hit;
78+
const bool rightSide = area->x > rect.w - hit;
79+
80+
if (leftSide && topSide)
81+
return SDL_HITTEST_RESIZE_TOPLEFT;
82+
83+
if (rightSide && topSide)
84+
return SDL_HITTEST_RESIZE_TOPRIGHT;
85+
86+
if (rightSide && bottomSide)
87+
return SDL_HITTEST_RESIZE_BOTTOMRIGHT;
88+
89+
if (leftSide && bottomSide)
90+
return SDL_HITTEST_RESIZE_BOTTOMLEFT;
91+
92+
if (topSide)
93+
return SDL_HITTEST_RESIZE_TOP;
94+
95+
if (rightSide)
96+
return SDL_HITTEST_RESIZE_RIGHT;
97+
98+
if (bottomSide)
99+
return SDL_HITTEST_RESIZE_BOTTOM;
100+
101+
if (leftSide)
102+
return SDL_HITTEST_RESIZE_LEFT;
103+
104+
const int centerX = rect.w / 2;
105+
const int centerY = rect.h / 2;
106+
107+
// Allow drag from any point except window center
108+
// For this case, 'hit' is a size of a square in the center
109+
if ((area->x > centerX + hit || area->x < centerX - hit)
110+
&& (area->y > centerY + hit || area->y < centerY - hit))
111+
return SDL_HITTEST_DRAGGABLE;
112+
113+
return SDL_HITTEST_NORMAL;
114+
}

src/xrEngine/Device_create.cpp

Lines changed: 25 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ void CRenderDevice::Create()
5858
psDeviceFlags.set(rsFullscreen, false);
5959

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

@@ -73,49 +72,20 @@ void CRenderDevice::Create()
7372
PreCache(0, false, false);
7473
}
7574

76-
void CRenderDevice::UpdateWindowProps(bool windowed)
75+
void CRenderDevice::UpdateWindowProps(const bool windowed)
7776
{
7877
SelectResolution(windowed);
7978

8079
SDL_SetWindowFullscreen(m_sdlWnd, windowed ? 0 : SDL_WINDOW_FULLSCREEN);
81-
SDL_Rect rect;
8280

8381
// Set window properties depending on what mode were in.
8482
if (windowed)
85-
{
86-
const bool drawBorders = strstr(Core.Params, "-draw_borders");
87-
if (drawBorders)
88-
SDL_SetWindowBordered(m_sdlWnd, SDL_TRUE);
89-
9083
SDL_SetWindowSize(m_sdlWnd, psCurrentVidMode[0], psCurrentVidMode[1]);
91-
92-
if (GEnv.isDedicatedServer || strstr(Core.Params, "-center_screen"))
93-
SDL_SetWindowPosition(m_sdlWnd, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
94-
else
95-
{
96-
SDL_GetDisplayUsableBounds(Vid_SelectedMonitor, &rect);
97-
98-
int top = 0, left = 0, right = 0, bottom = 0;
99-
// SDL_GetWindowBordersSize(m_sdlWnd, &top, &left, &bottom, &right);
100-
#ifdef WINDOWS
101-
// XXX: Currently SDL_GetWindowBordersSize is supported only on X11
102-
// For now we must use method below.
103-
if (drawBorders)
104-
top = GetSystemMetrics(SM_CYCAPTION); // size of the window title bar
105-
#else
106-
#pragma TODO("Implement for other platforms")
107-
#endif
108-
SDL_SetWindowPosition(m_sdlWnd, rect.x + left, rect.y + top);
109-
}
110-
111-
SDL_GetWindowPosition(m_sdlWnd, &m_rcWindowClient.x, &m_rcWindowClient.y);
112-
int w = 0, h = 0;
113-
SDL_GetWindowSize(m_sdlWnd, &w, &h);
114-
m_rcWindowClient.w = m_rcWindowClient.x + w;
115-
m_rcWindowClient.h = m_rcWindowClient.y + h;
116-
}
11784
else
11885
{
86+
// XXX: fix monitor selection
87+
// it appears to be buggy
88+
SDL_Rect rect;
11989
SDL_GetDisplayBounds(Vid_SelectedMonitor, &rect);
12090
SDL_SetWindowPosition(m_sdlWnd, rect.x, rect.y);
12191
SDL_DisplayMode mode;
@@ -126,31 +96,35 @@ void CRenderDevice::UpdateWindowProps(bool windowed)
12696
SDL_SetWindowDisplayMode(m_sdlWnd, &mode);
12797
}
12898

129-
if (!GEnv.isDedicatedServer)
130-
SDL_SetWindowGrab(m_sdlWnd, SDL_TRUE);
131-
132-
UpdateWindowRect();
99+
UpdateWindowRects();
133100
SDL_FlushEvents(SDL_WINDOWEVENT, SDL_SYSWMEVENT);
134101
}
135102

136103

137-
void CRenderDevice::UpdateWindowRect()
104+
void CRenderDevice::UpdateWindowRects()
138105
{
139-
SDL_GetWindowPosition(m_sdlWnd, &m_rcWindowClient.x, &m_rcWindowClient.y);
106+
m_rcWindowClient.x = 0;
107+
m_rcWindowClient.y = 0;
140108
SDL_GetWindowSize(m_sdlWnd, &m_rcWindowClient.w, &m_rcWindowClient.h);
141-
m_rcWindowClient.w += m_rcWindowClient.x;
142-
m_rcWindowClient.h += m_rcWindowClient.y;
109+
110+
SDL_GetWindowPosition(m_sdlWnd, &m_rcWindowBounds.x, &m_rcWindowBounds.y);
111+
SDL_GetWindowSize(m_sdlWnd, &m_rcWindowBounds.w, &m_rcWindowBounds.h);
112+
m_rcWindowBounds.w += m_rcWindowBounds.x;
113+
m_rcWindowBounds.h += m_rcWindowBounds.y;
114+
115+
// Do we need code below?
116+
int top, left, bottom, right;
117+
SDL_GetWindowBordersSize(m_sdlWnd, &top, &left, &bottom, &right);
118+
m_rcWindowBounds.x -= left;
119+
m_rcWindowBounds.y -= top;
120+
m_rcWindowBounds.w += right;
121+
m_rcWindowBounds.h += bottom;
122+
// XXX: check if we need this code when SDL_GetWindowBordersSize
123+
// will be available for Windows
143124
}
144125

145-
void CRenderDevice::SelectResolution(bool windowed)
126+
void CRenderDevice::SelectResolution(const bool windowed)
146127
{
147-
if (GEnv.isDedicatedServer)
148-
{
149-
dwWidth = 640;
150-
dwHeight = 480;
151-
return;
152-
}
153-
154128
if (windowed)
155129
{
156130
dwWidth = psCurrentVidMode[0];
@@ -172,7 +146,7 @@ void CRenderDevice::SelectResolution(bool windowed)
172146
if (SDL_GetClosestDisplayMode(Vid_SelectedMonitor, &current, &closest))
173147
xr_sprintf(buff, sizeof(buff), "vid_mode %dx%d", closest.w, closest.h);
174148
else
175-
xr_sprintf(buff, sizeof(buff), "vid_mode %s", VidModesToken[0].name);
149+
xr_sprintf(buff, sizeof(buff), "vid_mode %s", VidModesToken.back());
176150

177151
Console->Execute(buff);
178152
}

src/xrEngine/device.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ void CRenderDevice::message_loop()
348348
switch (event.window.event)
349349
{
350350
case SDL_WINDOWEVENT_MOVED:
351-
UpdateWindowRect();
351+
UpdateWindowRects();
352352
break;
353353

354354
case SDL_WINDOWEVENT_RESIZED:
@@ -362,21 +362,19 @@ void CRenderDevice::message_loop()
362362
Reset();
363363
}
364364
else
365-
UpdateWindowRect();
365+
UpdateWindowRects();
366366

367367
break;
368368
}
369369

370370
case SDL_WINDOWEVENT_SHOWN:
371-
case SDL_WINDOWEVENT_ENTER:
372371
case SDL_WINDOWEVENT_FOCUS_GAINED:
373372
case SDL_WINDOWEVENT_RESTORED:
374373
case SDL_WINDOWEVENT_MAXIMIZED:
375374
OnWM_Activate(1, event.window.data2);
376375
break;
377376

378377
case SDL_WINDOWEVENT_HIDDEN:
379-
case SDL_WINDOWEVENT_LEAVE:
380378
case SDL_WINDOWEVENT_FOCUS_LOST:
381379
case SDL_WINDOWEVENT_MINIMIZED:
382380
OnWM_Activate(0, event.window.data2);
@@ -418,6 +416,9 @@ void CRenderDevice::Run()
418416
seqAppStart.Process();
419417
GEnv.Render->ClearTarget();
420418
splash::hide();
419+
if (GEnv.isDedicatedServer)
420+
SDL_SetWindowPosition(m_sdlWnd, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
421+
SDL_HideWindow(m_sdlWnd);
421422
SDL_FlushEvents(SDL_WINDOWEVENT, SDL_SYSWMEVENT);
422423
SDL_ShowWindow(m_sdlWnd);
423424
SDL_RaiseWindow(m_sdlWnd);

src/xrEngine/device.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ class ENGINE_API CRenderDeviceData
6262
u32 dwWidth;
6363
u32 dwHeight;
6464

65+
// Real application window resolution
66+
SDL_Rect m_rcWindowBounds;
67+
6568
// Real game window resolution
6669
SDL_Rect m_rcWindowClient;
6770

@@ -248,9 +251,9 @@ class ENGINE_API CRenderDevice : public CRenderDeviceBase
248251
void Destroy(void);
249252
void Reset(bool precache = true);
250253

251-
void UpdateWindowProps(bool windowed);
252-
void UpdateWindowRect();
253-
void SelectResolution(bool windowed);
254+
void UpdateWindowProps(const bool windowed);
255+
void UpdateWindowRects();
256+
void SelectResolution(const bool windowed);
254257

255258
void Initialize(void);
256259
void ShutDown(void);

src/xrEngine/xr_input.cpp

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ CInput::CInput(bool exclusive, int deviceForInit)
5353
//===================== Dummy pack
5454
iCapture(&dummyController);
5555

56-
SDL_SetRelativeMouseMode(SDL_TRUE);
57-
5856
xrDebug::SetDialogHandler(on_error_dialog);
5957

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

6765
CInput::~CInput(void)
6866
{
69-
SDL_SetRelativeMouseMode(SDL_FALSE);
7067
#ifdef ENGINE_BUILD
7168
Device.seqFrame.Remove(this);
7269
Device.seqAppDeactivate.Remove(this);
@@ -232,12 +229,12 @@ void CInput::ClipCursor(bool clip)
232229
{
233230
if (clip)
234231
{
235-
SDL_ShowCursor(SDL_DISABLE);
232+
SDL_SetWindowGrab(Device.m_sdlWnd, SDL_TRUE);
236233
SDL_SetRelativeMouseMode(SDL_TRUE);
237234
}
238235
else
239236
{
240-
SDL_ShowCursor(SDL_ENABLE);
237+
SDL_SetWindowGrab(Device.m_sdlWnd, SDL_FALSE);
241238
SDL_SetRelativeMouseMode(SDL_FALSE);
242239
}
243240
}

src/xrEngine/xr_ioc_cmd.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -657,6 +657,16 @@ class ENGINE_API CCC_HideConsole : public IConsole_Command
657657
virtual void Info(TInfo& I) { xr_sprintf(I, sizeof(I), "hide console"); }
658658
};
659659

660+
class CCC_CenterScreen : public IConsole_Command
661+
{
662+
public:
663+
CCC_CenterScreen(pcstr name) : IConsole_Command(name) { bEmptyArgsHandled = true; }
664+
void Execute(pcstr args) override
665+
{
666+
SDL_SetWindowPosition(Device.m_sdlWnd, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED);
667+
}
668+
};
669+
660670
ENGINE_API float psHUD_FOV = 0.45f;
661671

662672
// extern int psSkeletonUpdate;
@@ -787,6 +797,7 @@ void CCC_Register()
787797
CMD2(CCC_Float, "cam_inert", &psCamInert);
788798
CMD2(CCC_Float, "cam_slide_inert", &psCamSlideInert);
789799

800+
CMD1(CCC_CenterScreen, "center_screen");
790801
CMD4(CCC_Integer, "always_active", &ps_always_active, 0, 1);
791802

792803
CMD1(CCC_r2, "renderer");

src/xrGame/MainMenu.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "profile_store.h"
3737
#include "stats_submitter.h"
3838
#include "atlas_submit_queue.h"
39+
#include "xrEngine/xr_input.h"
3940

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

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

337+
bool IWantMyMouseBackScreamed = false;
336338
void CMainMenu::IR_OnKeyboardPress(int dik)
337339
{
338340
if (!IsActive())
@@ -343,6 +345,14 @@ void CMainMenu::IR_OnKeyboardPress(int dik)
343345
Console->Show();
344346
return;
345347
}
348+
349+
if (pInput->iGetAsyncKeyState(SDL_SCANCODE_LALT) || pInput->iGetAsyncKeyState(SDL_SCANCODE_RALT)
350+
&& pInput->iGetAsyncKeyState(SDL_SCANCODE_LGUI) || pInput->iGetAsyncKeyState(SDL_SCANCODE_RGUI))
351+
{
352+
IWantMyMouseBackScreamed = true;
353+
pInput->ClipCursor(false);
354+
}
355+
346356
if (SDL_SCANCODE_F12 == dik)
347357
{
348358
GEnv.Render->Screenshot();
@@ -357,6 +367,13 @@ void CMainMenu::IR_OnKeyboardRelease(int dik)
357367
if (!IsActive())
358368
return;
359369

370+
if (IWantMyMouseBackScreamed)
371+
{
372+
IWantMyMouseBackScreamed = false;
373+
pInput->ClipCursor(true);
374+
}
375+
376+
360377
CDialogHolder::IR_UIOnKeyboardRelease(dik);
361378
};
362379

src/xrGame/UICursor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ void CUICursor::InitInternal()
6363
const u32 screen_size_y = display.h - display.y;
6464
m_b_use_win_cursor = screen_size_y >= Device.dwHeight && screen_size_x >= Device.dwWidth;
6565
if (m_b_use_win_cursor) // sanity
66-
Device.UpdateWindowRect();
66+
Device.UpdateWindowRects();
6767
}
6868

6969
//--------------------------------------------------------------------

0 commit comments

Comments
 (0)