Skip to content

Commit c394a15

Browse files
committed
Add swap interval control to QtGame. There's no longer any need to restart to change vsync settings.
Refs #2815.
1 parent 6205899 commit c394a15

File tree

11 files changed

+162
-11
lines changed

11 files changed

+162
-11
lines changed

lib/framework/wzapp.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ WzMainWindow *WzMainWindow::instance()
218218

219219
void WzMainWindow::initializeGL()
220220
{
221+
QtGameWidget::initializeGL();
221222
}
222223

223224
void WzMainWindow::drawPixmap(int XPos, int YPos, QPixmap *pix)

lib/qtgame/Makefile.am

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
AM_CPPFLAGS = $(WZ_CPPFLAGS) $(QT4_CFLAGS)
1+
AM_CPPFLAGS = $(WZ_CPPFLAGS) $(QT4_CFLAGS) $(GLEW_CFLAGS)
22
AM_CFLAGS = $(WZ_CFLAGS)
33
AM_CXXFLAGS = $(WZ_CXXFLAGS) $(QT4_CFLAGS)
44

@@ -12,5 +12,5 @@ BUILT_SOURCES = $(MOCEDFILES)
1212
CLEANFILES = $(MOCEDFILES)
1313

1414
noinst_LIBRARIES = libqtgame.a
15-
noinst_HEADERS = qtgame.h $(MOCHEADER)
16-
libqtgame_a_SOURCES = qtgame.cpp qtgame_moc.cpp
15+
noinst_HEADERS = qtgame.h swapinterval.h $(MOCHEADER)
16+
libqtgame_a_SOURCES = qtgame.cpp qtgame_moc.cpp swapinterval.cpp

lib/qtgame/qtgame.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "qtgame.h"
22

33
#include "lib/framework/wzglobal.h"
4+
#include "swapinterval.h"
45

56
#if defined(WZ_CC_MSVC)
67
#include "qtgame.h.moc" // this is generated on the pre-build event.
@@ -196,14 +197,34 @@ void QtGameWidget::updateResolutionList()
196197
#endif
197198
}
198199

200+
QGLFormat QtGameWidget::adjustFormat(const QGLFormat &format)
201+
{
202+
QGLFormat adjusted(format);
203+
mSwapInterval = adjusted.swapInterval();
204+
adjusted.setSwapInterval(0);
205+
return adjusted;
206+
}
207+
208+
void QtGameWidget::initializeGL()
209+
{
210+
setSwapInterval(mSwapInterval);
211+
}
212+
199213
QtGameWidget::QtGameWidget(QSize curResolution, const QGLFormat &format, QWidget *parent, Qt::WindowFlags f, const QGLWidget *shareWidget)
200-
: QGLWidget(format, parent, shareWidget, f), mOriginalResolution(0, 0), mMinimumSize(0, 0)
214+
: QGLWidget(adjustFormat(format), parent, shareWidget, f), mOriginalResolution(0, 0), mMinimumSize(0, 0)
201215
{
202216
mWantedSize = curResolution;
203217
mResolutionChanged = false;
204218
updateResolutionList();
205219
}
206220

221+
void QtGameWidget::setSwapInterval(int interval)
222+
{
223+
mSwapInterval = interval;
224+
makeCurrent();
225+
::setSwapInterval(*this, &mSwapInterval);
226+
}
227+
207228
bool QtGameWidget::setResolution(const QSize res, int rate, int depth)
208229
{
209230
#ifdef WZ_WS_X11

lib/qtgame/qtgame.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ class QtGameWidget : public QGLWidget
1010
private:
1111
QSize mOriginalResolution, mCurrentResolution, mWantedSize, mMinimumSize;
1212
int mOriginalRefreshRate, mCurrentRefreshRate;
13+
int mSwapInterval;
1314
int mOriginalDepth, mCurrentDepth;
1415
QList<QSize> mResolutions;
1516
bool mResolutionChanged;
@@ -19,12 +20,19 @@ class QtGameWidget : public QGLWidget
1920
void updateResolutionList();
2021
bool setResolution(const QSize res, int rate, int depth);
2122

23+
QGLFormat adjustFormat(const QGLFormat &format);
24+
protected:
25+
virtual void initializeGL();
26+
2227
public:
2328
QtGameWidget(QSize curResolution, const QGLFormat &format, QWidget *parent = 0, Qt::WindowFlags f = 0, const QGLWidget *shareWidget = 0);
2429
~QtGameWidget() { if (mResolutionChanged) restoreResolution(); }
2530
QList<QSize> availableResolutions() const { return mResolutions; }
2631
bool isMouseTrapped() { return mCursorTrapped; }
2732

33+
int swapInterval() const { return mSwapInterval; }
34+
void setSwapInterval(int interval);
35+
2836
public slots:
2937
void setMinimumResolution(QSize res);
3038

lib/qtgame/swapinterval.cpp

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
#include "swapinterval.h"
2+
#include "lib/framework/wzglobal.h"
3+
#include "lib/framework/opengl.h"
4+
5+
#if defined(WZ_WS_X11)
6+
7+
#include <GL/glxew.h>
8+
// X11 polution
9+
#ifdef Status
10+
#undef Status
11+
#endif
12+
#ifdef CursorShape
13+
#undef CursorShape
14+
#endif
15+
#ifdef Bool
16+
#undef Bool
17+
#endif
18+
19+
#include <QtGui/QX11Info>
20+
#include <QtOpenGL/QGLWidget>
21+
22+
23+
void setSwapInterval(QGLWidget const &glWidget, int * interval)
24+
{
25+
QGLContext const &context = *glWidget.context();
26+
QX11Info const &xinfo = glWidget.x11Info();
27+
if (GLXEW_EXT_swap_control)
28+
{
29+
unsigned clampedInterval;
30+
if (*interval < 0)
31+
*interval = 0;
32+
glXSwapIntervalEXT(xinfo.display(), glWidget.winId(), *interval);
33+
glXQueryDrawable(xinfo.display(), glWidget.winId(), GLX_SWAP_INTERVAL_EXT, &clampedInterval);
34+
*interval = clampedInterval;
35+
}
36+
else if (xinfo.display() && strstr(glXQueryExtensionsString(xinfo.display(), xinfo.screen()), "GLX_MESA_swap_control"))
37+
{
38+
typedef int (* PFNGLXSWAPINTERVALMESAPROC)(unsigned);
39+
typedef int (* PFNGLXGETSWAPINTERVALMESAPROC)(void);
40+
PFNGLXSWAPINTERVALMESAPROC glXSwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC) context.getProcAddress("glXSwapIntervalMESA");
41+
PFNGLXGETSWAPINTERVALMESAPROC glXGetSwapIntervalMESA = (PFNGLXGETSWAPINTERVALMESAPROC) context.getProcAddress("glXGetSwapIntervalMESA");
42+
43+
if (glXSwapIntervalMESA && glXGetSwapIntervalMESA)
44+
{
45+
if (*interval < 0)
46+
*interval = 0;
47+
glXSwapIntervalMESA(*interval);
48+
*interval = glXGetSwapIntervalMESA();
49+
}
50+
}
51+
else if (GLXEW_SGI_swap_control)
52+
{
53+
if (*interval < 1)
54+
*interval = 1;
55+
if (glXSwapIntervalSGI(*interval))
56+
{
57+
// Error, revert to default
58+
*interval = 1;
59+
glXSwapIntervalSGI(1);
60+
}
61+
}
62+
else
63+
{
64+
*interval = -1;
65+
}
66+
}
67+
68+
#elif defined(WZ_WS_WIN)
69+
#include <GL/wglew.h>
70+
#include <QtOpenGL/QGLWidget>
71+
72+
void setSwapInterval(QGLWidget const &, int * interval)
73+
{
74+
if (WGLEW_EXT_swap_control)
75+
{
76+
if (*interval < 0)
77+
*interval = 0;
78+
wglSwapIntervalEXT(*interval);
79+
*interval = wglGetSwapIntervalEXT();
80+
}
81+
else
82+
{
83+
*interval = -1;
84+
}
85+
}
86+
#endif

lib/qtgame/swapinterval.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#ifndef QTGAME_SWAPINTERVAL_H
2+
#define QTGAME_SWAPINTERVAL_H
3+
4+
class QGLWidget;
5+
extern void setSwapInterval(QGLWidget const &glWidget, int * interval);
6+
7+
#endif // QTGAME_SWAPINTERVAL_H

lib/qtgame/swapinterval.mm

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#import "swapinterval.h"
2+
#import "lib/framework/wzglobal.h"
3+
4+
#ifdef WZ_OS_MAC
5+
6+
#import <AppKit/NSOpenGL.h>
7+
8+
void setSwapInterval(QGLWidget const &, int * interval)
9+
{
10+
NSOpenGLContext *context = [NSOpenGLContext currentContext];
11+
if (*interval >= 0)
12+
{
13+
[context setValues:interval forParameter:NSOpenGLCPSwapInterval];
14+
}
15+
[context getValues:interval forParameter:NSOpenGLCPSwapInterval];
16+
}
17+
18+
#endif // WZ_OS_MAC

macosx/Warzone.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,7 @@
440440
4355E13210D6028C00A19EE4 /* theoradec.h in Headers */ = {isa = PBXBuildFile; fileRef = 4355E12E10D6028C00A19EE4 /* theoradec.h */; settings = {ATTRIBUTES = (Public, ); }; };
441441
4355E13310D6028C00A19EE4 /* theoraenc.h in Headers */ = {isa = PBXBuildFile; fileRef = 4355E12F10D6028C00A19EE4 /* theoraenc.h */; settings = {ATTRIBUTES = (Public, ); }; };
442442
4371B60F11D93FD1005A67AB /* pngpriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 4371B60D11D93FD0005A67AB /* pngpriv.h */; };
443+
437FB24D13CE5CA900E7EF5B /* swapinterval.mm in Sources */ = {isa = PBXBuildFile; fileRef = 437FB24B13CE5CA900E7EF5B /* swapinterval.mm */; };
443444
438BDDF31129DC9A00998660 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 438BDDD71129DC9A00998660 /* InfoPlist.strings */; };
444445
43A6285B13A6C4A400C6B786 /* geometry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43A6285913A6C4A400C6B786 /* geometry.cpp */; };
445446
43A8417811028EDD00733CCB /* pointtree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 43A8417611028EDD00733CCB /* pointtree.cpp */; };
@@ -1525,6 +1526,9 @@
15251526
4355E12E10D6028C00A19EE4 /* theoradec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = theoradec.h; path = external/libtheora/include/theora/theoradec.h; sourceTree = "<group>"; };
15261527
4355E12F10D6028C00A19EE4 /* theoraenc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = theoraenc.h; path = external/libtheora/include/theora/theoraenc.h; sourceTree = "<group>"; };
15271528
4371B60D11D93FD0005A67AB /* pngpriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pngpriv.h; path = external/libpng/pngpriv.h; sourceTree = "<group>"; };
1529+
437FB24913CE5CA900E7EF5B /* swapinterval.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = swapinterval.cpp; path = ../lib/qtgame/swapinterval.cpp; sourceTree = SOURCE_ROOT; };
1530+
437FB24A13CE5CA900E7EF5B /* swapinterval.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = swapinterval.h; path = ../lib/qtgame/swapinterval.h; sourceTree = SOURCE_ROOT; };
1531+
437FB24B13CE5CA900E7EF5B /* swapinterval.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = swapinterval.mm; path = ../lib/qtgame/swapinterval.mm; sourceTree = SOURCE_ROOT; };
15281532
438BDDD81129DC9A00998660 /* cs */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = cs; path = cs.lproj/InfoPlist.strings; sourceTree = "<group>"; };
15291533
438BDDD91129DC9A00998660 /* da */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = da; path = da.lproj/InfoPlist.strings; sourceTree = "<group>"; };
15301534
438BDDDA1129DC9A00998660 /* de */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/InfoPlist.strings; sourceTree = "<group>"; };
@@ -2633,6 +2637,9 @@
26332637
4313231513BE86360023280C /* QtGame */ = {
26342638
isa = PBXGroup;
26352639
children = (
2640+
437FB24913CE5CA900E7EF5B /* swapinterval.cpp */,
2641+
437FB24A13CE5CA900E7EF5B /* swapinterval.h */,
2642+
437FB24B13CE5CA900E7EF5B /* swapinterval.mm */,
26362643
4313231713BE866B0023280C /* qtgame.cpp */,
26372644
4313231813BE866B0023280C /* qtgame.h */,
26382645
4313231913BE866B0023280C /* qtgame.h.qwth */,
@@ -4171,6 +4178,7 @@
41714178
43A6285B13A6C4A400C6B786 /* geometry.cpp in Sources */,
41724179
4313231A13BE866B0023280C /* qtgame.cpp in Sources */,
41734180
43DD1BCE13662006003AA9EC /* netlobby.cpp in Sources */,
4181+
437FB24D13CE5CA900E7EF5B /* swapinterval.mm in Sources */,
41744182
);
41754183
runOnlyForDeploymentPostprocessing = 0;
41764184
};

po/POTFILES.in

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ lib/netplay/netqueue.cpp
186186
lib/netplay/netsocket.cpp
187187
lib/netplay/nettypes.cpp
188188
lib/qtgame/qtgame.cpp
189+
lib/qtgame/swapinterval.cpp
189190
lib/script/codeprint.cpp
190191
lib/script/event.cpp
191192
lib/script/eventsave.cpp
@@ -210,6 +211,8 @@ lib/widget/label.cpp
210211
lib/widget/slider.cpp
211212
lib/widget/tip.cpp
212213
lib/widget/widget.cpp
214+
po/custom/mac-infoplist.txt
215+
po/custom/warzone2100.desktop.txt
213216
src/action.cpp
214217
src/advvis.cpp
215218
src/ai.cpp
@@ -316,5 +319,3 @@ src/warcam.cpp
316319
src/warzoneconfig.cpp
317320
src/wavecast.cpp
318321
src/wrappers.cpp
319-
po/custom/warzone2100.desktop.txt
320-
po/custom/mac-infoplist.txt

src/frontend.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,7 @@ static bool startVideoOptionsMenu(void)
765765
addTextButton(FRONTEND_TEXTURESZ_R, FRONTEND_POS4M-55, FRONTEND_POS4Y, textureSize, 0);
766766

767767
// Vsync
768-
addTextButton(FRONTEND_VSYNC, FRONTEND_POS5X-35, FRONTEND_POS5Y, _("Vertical sync*"), 0);
768+
addTextButton(FRONTEND_VSYNC, FRONTEND_POS5X-35, FRONTEND_POS5Y, _("Vertical sync"), 0);
769769

770770
if (war_GetVsync())
771771
{
@@ -954,6 +954,7 @@ bool runVideoOptionsMenu(void)
954954
war_SetVsync(true);
955955
widgSetString(psWScreen, FRONTEND_VSYNC_R, _("On"));
956956
}
957+
WzMainWindow::instance()->setSwapInterval(war_GetVsync());
957958
break;
958959
}
959960

0 commit comments

Comments
 (0)