Skip to content

Commit 620b915

Browse files
committed
Initial work on virtual display mode support
Saving out display mode ratio of max res, and adding support for client to set resolution in response to window events Initial work on virtual display mode support Saving out display mode ratio of max res, and adding support for client to set resolution in response to window events
1 parent 2a059e0 commit 620b915

File tree

9 files changed

+459
-7
lines changed

9 files changed

+459
-7
lines changed

Scripts/Python/xIniDisplay.py

+5-4
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,10 @@
6262
kGraphicsShadows = "Graphics.Shadow.Enable"
6363
kGraphicsVerticalSync = "Graphics.EnableVSync"
6464
kGraphicsShadowQuality = "Graphics.Shadow.VisibleDistance"
65+
kGraphicsOutputScale = "Graphics.OutputScale"
6566

66-
CmdList = [kGraphicsWidth, kGraphicsHeight, kGraphicsColorDepth, kGraphicsWindowed, kGraphicsTextureQuality, kGraphicsAntiAliasLevel, kGraphicsAnisotropicLevel, kGraphicsQualityLevel, kGraphicsShadows, kGraphicsVerticalSync, kGraphicsShadowQuality]
67-
DefaultsList = ["800", "600", "32", "false", "2", "0", "0", "2", "true", "false", "0"]
67+
CmdList = [kGraphicsWidth, kGraphicsHeight, kGraphicsColorDepth, kGraphicsWindowed, kGraphicsTextureQuality, kGraphicsAntiAliasLevel, kGraphicsAnisotropicLevel, kGraphicsQualityLevel, kGraphicsShadows, kGraphicsVerticalSync, kGraphicsShadowQuality, kGraphicsOutputScale]
68+
DefaultsList = ["800", "600", "32", "false", "2", "0", "0", "2", "true", "false", "0", "100"]
6869

6970
def ConstructFilenameAndPath():
7071
global gFilenameAndPath
@@ -120,9 +121,9 @@ def ReadIni():
120121
ConstructFilenameAndPath()
121122
gIniFile.writeFile(gFilenameAndPath)
122123

123-
def SetGraphicsOptions(width, heigth, colordepth, windowed, texquality, aaLevel, anisoLevel, qualityLevel, useShadows, vsync, shadowqual):
124+
def SetGraphicsOptions(width, heigth, colordepth, windowed, texquality, aaLevel, anisoLevel, qualityLevel, useShadows, vsync, shadowqual, outputScale):
124125
if gIniFile:
125-
paramList = [width, heigth, colordepth, windowed, texquality, aaLevel, anisoLevel, qualityLevel, useShadows, vsync, shadowqual]
126+
paramList = [width, heigth, colordepth, windowed, texquality, aaLevel, anisoLevel, qualityLevel, useShadows, vsync, shadowqual, outputScale]
126127
for idx in range(len(CmdList)):
127128
entry,junk = gIniFile.findByCommand(CmdList[idx])
128129
val = str(paramList[idx])

Scripts/Python/xOptionsMenu.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,7 @@
443443
gClickToTurn = "0"
444444
gAudioHack = 0
445445
gCurrentReleaseNotes = "Welcome to Myst Online: Uru Live!"
446+
gMaxVideoWidth = 0
446447

447448
class xOptionsMenu(ptModifier):
448449
"The Options dialog modifier"
@@ -1488,6 +1489,7 @@ def ResetVideoToDefault(self):
14881489
self.SetVidResField(vidRes)
14891490

14901491
def InitVideoControlsGUI(self):
1492+
global gMaxVideoWidth
14911493
xIniDisplay.ReadIni()
14921494
opts = xIniDisplay.GetGraphicsOptions()
14931495

@@ -1541,6 +1543,7 @@ def InitVideoControlsGUI(self):
15411543
if not vidRes in vidResList:
15421544
vidRes = vidResList[numRes-1]
15431545

1546+
gMaxVideoWidth = int(vidResList[numRes-1].split("x")[0])
15441547
for res in range(numRes):
15451548
if vidRes == vidResList[res]:
15461549
if numRes > 1:
@@ -1644,8 +1647,9 @@ def WriteVideoControls(self, setMode = 0):
16441647

16451648
gammaField = ptGUIControlKnob(GraphicsSettingsDlg.dialog.getControlFromTag(kGSDisplayGammaSlider))
16461649
gamma = gammaField.getValue()
1647-
1648-
xIniDisplay.SetGraphicsOptions(width, height, colordepth, windowed, tex_quality, antialias, aniso, quality, shadows, vsyncstr, shadow_quality)
1650+
resolutionScale = int(round((width / gMaxVideoWidth) * 100))
1651+
1652+
xIniDisplay.SetGraphicsOptions(width, height, colordepth, windowed, tex_quality, antialias, aniso, quality, shadows, vsyncstr, shadow_quality, resolutionScale)
16491653
xIniDisplay.WriteIni()
16501654
self.setNewChronicleVar("gamma", gamma)
16511655

Sources/Plasma/Apps/plClient/plClient.cpp

+46-1
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,6 @@ You can contact Cyan Worlds, Inc. by email [email protected]
150150
#include "pfPython/cyMisc.h"
151151
#include "pfPython/cyPythonInterface.h"
152152

153-
154153
#define MSG_LOADING_BAR
155154

156155
// static hsVector3 gAbsDown(0,0,-1.f);
@@ -221,6 +220,7 @@ plClient::~plClient()
221220
plClient::SetInstance(nullptr);
222221

223222
delete fPageMgr;
223+
delete fGraphicsIni;
224224
}
225225

226226
template<typename T>
@@ -443,6 +443,7 @@ bool plClient::InitPipeline(hsWindowHndl display, uint32_t devType)
443443

444444
hsG3DDeviceRecord *rec = (hsG3DDeviceRecord *)dmr.GetDevice();
445445

446+
#if !PLASMA_DISPLAY_INDEPENDENT_VIDEO_MODES
446447
if(!plPipeline::fInitialPipeParams.Windowed)
447448
{
448449
// find our resolution if we're not in windowed mode
@@ -467,6 +468,7 @@ bool plClient::InitPipeline(hsWindowHndl display, uint32_t devType)
467468
ISetGraphicsDefaults();
468469
}
469470
}
471+
#endif
470472

471473
if(plPipeline::fInitialPipeParams.TextureQuality == -1)
472474
{
@@ -1900,6 +1902,47 @@ void plClient::ResizeDisplayDevice(int Width, int Height, bool Windowed)
19001902
IResizeNativeDisplayDevice(Width, Height, Windowed);
19011903
}
19021904

1905+
void plClient::SetDisplayOptions(int Width, int Height, bool Windowed)
1906+
{
1907+
fGraphicsIni->readFile();
1908+
std::shared_ptr<hsIniEntry> entry = fGraphicsIni->findByCommand("Graphics.Windowed");
1909+
if (entry) {
1910+
entry->setValue(0, Windowed ? "true" : "false");
1911+
}
1912+
1913+
entry = fGraphicsIni->findByCommand("Graphics.OutputScale");
1914+
if (entry) {
1915+
double scale = entry->getValue(0)->to_uint() / 100.0;
1916+
Width *= scale;
1917+
Height *= scale;
1918+
}
1919+
1920+
entry = fGraphicsIni->findByCommand("Graphics.Width");
1921+
if (entry) {
1922+
entry->setValue(0, std::to_string(Width));
1923+
}
1924+
entry = fGraphicsIni->findByCommand("Graphics.Height");
1925+
if (entry) {
1926+
entry->setValue(0, std::to_string(Height));
1927+
}
1928+
fGraphicsIni->writeFile();
1929+
1930+
FlushGraphicsOptions();
1931+
}
1932+
1933+
void plClient::FlushGraphicsOptions()
1934+
{
1935+
int Width = fGraphicsIni->findByCommand("Graphics.Width")->getValue(0)->to_int();
1936+
int Height = fGraphicsIni->findByCommand("Graphics.Height")->getValue(0)->to_int();
1937+
int ColorDepth = fGraphicsIni->findByCommand("Graphics.ColorDepth")->getValue(0)->to_int();
1938+
int NumAASamples = fGraphicsIni->findByCommand("Graphics.AntiAliasAmount")->getValue(0)->to_int();
1939+
int MaxAnisotropicSamples = fGraphicsIni->findByCommand("Graphics.AnisotropicLevel")->getValue(0)->to_int();
1940+
bool VSync = (fGraphicsIni->findByCommand("Graphics.EnableVSync")->getValue(0) == "true");
1941+
bool Windowed = (fGraphicsIni->findByCommand("Graphics.Windowed")->getValue(0) == "true");
1942+
1943+
ResetDisplayDevice(Width, Height, ColorDepth, Windowed, NumAASamples, MaxAnisotropicSamples);
1944+
}
1945+
19031946
void WriteBool(hsStream *stream, const char *name, bool on )
19041947
{
19051948
char command[256];
@@ -1998,6 +2041,8 @@ void plClient::IDetectAudioVideoSettings()
19982041
s.Close();
19992042
else
20002043
IWriteDefaultGraphicsSettings(graphicsIniFile);
2044+
2045+
fGraphicsIni = new hsIniFile(graphicsIniFile);
20012046
}
20022047

20032048
void plClient::IWriteDefaultAudioSettings(const plFileName& destFile)

Sources/Plasma/Apps/plClient/plClient.h

+5
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ You can contact Cyan Worlds, Inc. by email [email protected]
4848

4949
#include "HeadSpin.h"
5050
#include "hsBitVector.h"
51+
#include "hsIniHelper.h"
5152
#include "plFileSystem.h"
5253

5354
#include <list>
@@ -157,6 +158,8 @@ class plClient : public hsKeyedObject
157158

158159
plMessagePumpProc fMessagePumpProc;
159160

161+
hsIniFile *fGraphicsIni;
162+
160163
#ifndef PLASMA_EXTERNAL_RELEASE
161164
bool bPythonDebugConnected;
162165
#endif
@@ -223,6 +226,7 @@ class plClient : public hsKeyedObject
223226
void IResizeNativeDisplayDevice(int width, int height, bool windowed);
224227
void IChangeResolution(int width, int height);
225228
void IUpdateProgressIndicator(plOperationProgress* progress);
229+
void FlushGraphicsOptions();
226230

227231
public:
228232

@@ -310,6 +314,7 @@ class plClient : public hsKeyedObject
310314
void SetMessagePumpProc(plMessagePumpProc proc) { fMessagePumpProc = proc; }
311315
void ResetDisplayDevice(int Width, int Height, int ColorDepth, bool Windowed, int NumAASamples, int MaxAnisotropicSamples, bool VSync = false);
312316
void ResizeDisplayDevice(int Width, int Height, bool Windowed);
317+
void SetDisplayOptions(int Width, int Height, bool Windowed);
313318

314319
plAnimDebugList *fAnimDebugList;
315320
};

Sources/Plasma/CoreLib/CMakeLists.txt

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ set(CoreLib_SOURCES
77
hsExceptionStack.cpp
88
hsFastMath.cpp
99
hsGeometry3.cpp
10+
hsIniHelper.cpp
1011
hsMatrix33.cpp
1112
hsMatrix44.cpp
1213
hsMemory.cpp
@@ -48,6 +49,7 @@ set(CoreLib_HEADERS
4849
hsExceptionStack.h
4950
hsFastMath.h
5051
hsGeometry3.h
52+
hsIniHelper.h
5153
hsLockGuard.h
5254
hsMatrix44.h
5355
hsMemory.h
+165
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
/*==LICENSE==*
2+
3+
CyanWorlds.com Engine - MMOG client, server and tools
4+
Copyright (C) 2011 Cyan Worlds, Inc.
5+
6+
This program is free software: you can redistribute it and/or modify
7+
it under the terms of the GNU General Public License as published by
8+
the Free Software Foundation, either version 3 of the License, or
9+
(at your option) any later version.
10+
11+
This program is distributed in the hope that it will be useful,
12+
but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
GNU General Public License for more details.
15+
16+
You should have received a copy of the GNU General Public License
17+
along with this program. If not, see <http://www.gnu.org/licenses/>.
18+
19+
Additional permissions under GNU GPL version 3 section 7
20+
21+
If you modify this Program, or any covered work, by linking or
22+
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
23+
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
24+
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
25+
(or a modified version of those libraries),
26+
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
27+
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
28+
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
29+
licensors of this Program grant you additional
30+
permission to convey the resulting work. Corresponding Source for a
31+
non-source form of such a combination shall include the source code for
32+
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
33+
work.
34+
35+
You can contact Cyan Worlds, Inc. by email [email protected]
36+
or by snail mail at:
37+
Cyan Worlds, Inc.
38+
14617 N Newport Hwy
39+
Mead, WA 99021
40+
41+
*==LICENSE==*/
42+
43+
#include "hsIniHelper.h"
44+
#include "hsStringTokenizer.h"
45+
46+
hsIniEntry::hsIniEntry(ST::string line):
47+
fCommand(), fComment() {
48+
if(line.size() == 0) {
49+
fType = kBlankLine;
50+
} else if(line[0] == '#') {
51+
fType = kComment;
52+
fComment = line.after_first('#');
53+
} else if(line == "\n") {
54+
fType = kBlankLine;
55+
} else {
56+
fType = kCommandValue;
57+
hsStringTokenizer tokenizer = hsStringTokenizer(line.c_str(), " ");
58+
char *str;
59+
int i = 0;
60+
while((str = tokenizer.next())) {
61+
if (i==0) {
62+
fCommand = str;
63+
} else {
64+
fValues.push_back(str);
65+
}
66+
i++;
67+
}
68+
}
69+
}
70+
71+
void hsIniEntry::setValue(size_t idx, ST::string value) {
72+
if (fValues.size() >= idx) {
73+
fValues[idx] = value;
74+
} else {
75+
for (int i=fValues.size(); i<idx; i++) {
76+
fValues.push_back("");
77+
}
78+
fValues.push_back(value);
79+
}
80+
}
81+
82+
std::optional<ST::string> hsIniEntry::getValue(size_t idx) {
83+
if (fValues.size() < idx) {
84+
return std::optional<ST::string>();
85+
} else {
86+
return fValues[idx];
87+
}
88+
}
89+
90+
91+
hsIniFile::hsIniFile(plFileName filename) {
92+
93+
this->filename = filename;
94+
readFile();
95+
}
96+
97+
98+
hsIniFile::hsIniFile(hsStream& stream) {
99+
readStream(stream);
100+
}
101+
102+
void hsIniFile::readStream(hsStream& stream) {
103+
ST::string line;
104+
while(stream.ReadLn(line)) {
105+
std::shared_ptr<hsIniEntry> entry = std::make_shared<hsIniEntry>(line);
106+
fEntries.push_back(entry);
107+
}
108+
}
109+
110+
void hsIniFile::writeFile() {
111+
hsAssert(filename.GetSize() > 0, "writeFile requires contructor with filename");
112+
113+
hsBufferedStream s;
114+
s.Open(filename, "w");
115+
writeStream(s);
116+
s.Close();
117+
}
118+
119+
void hsIniFile::readFile() {
120+
hsAssert(filename.GetSize() > 0, "writeFile requires contructor with filename");
121+
122+
fEntries.clear();
123+
124+
hsBufferedStream s;
125+
s.Open(filename);
126+
readStream(s);
127+
s.Close();
128+
}
129+
130+
void hsIniFile::writeFile(plFileName filename) {
131+
hsBufferedStream s;
132+
s.Open(filename, "w");
133+
writeStream(s);
134+
s.Close();
135+
}
136+
137+
void hsIniFile::writeStream(hsStream& stream) {
138+
for (std::shared_ptr<hsIniEntry> entry: fEntries) {
139+
switch (entry->fType) {
140+
case hsIniEntry::kBlankLine:
141+
stream.WriteSafeString("\n");
142+
break;
143+
case hsIniEntry::kComment:
144+
stream.WriteSafeString("#" + entry.get()->fComment + "\n");
145+
break;
146+
case hsIniEntry::kCommandValue:
147+
ST::string line = entry->fCommand;
148+
for (ST::string value: entry->fValues) {
149+
line += " " + value;
150+
}
151+
line += "\n";
152+
stream.WriteString(line);
153+
break;
154+
}
155+
}
156+
}
157+
158+
std::shared_ptr<hsIniEntry> hsIniFile::findByCommand(ST::string command) {
159+
for (std::shared_ptr<hsIniEntry> entry: fEntries) {
160+
if(entry->fCommand == command) {
161+
return entry;
162+
}
163+
}
164+
return std::shared_ptr<hsIniEntry>(nullptr);
165+
}

0 commit comments

Comments
 (0)