/
GameSetupPageIdTech.cpp
210 lines (170 loc) · 6.16 KB
/
GameSetupPageIdTech.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
#include "GameSetupPageIdTech.h"
#include "i18n.h"
#include "imodule.h"
#include "igame.h"
#include "wxutil/PathEntry.h"
#include <fmt/format.h>
#include <wx/sizer.h>
#include <wx/textctrl.h>
#include <wx/stattext.h>
#include <wx/panel.h>
#include "string/trim.h"
#include "os/file.h"
#include "os/path.h"
#include "settings/Win32Registry.h"
namespace ui
{
GameSetupPageIdTech::GameSetupPageIdTech(wxWindow* parent, const game::IGamePtr& game) :
GameSetupPage(parent, game),
_fsGameEntry(nullptr),
_fsGameBaseEntry(nullptr),
_enginePathEntry(nullptr)
{
wxFlexGridSizer* table = new wxFlexGridSizer(3, 2, wxSize(6, 6));
table->AddGrowableCol(1);
this->SetSizer(table);
_enginePathEntry = new wxutil::PathEntry(this, true);
_enginePathEntry->getEntryWidget()->SetMinClientSize(
wxSize(_enginePathEntry->getEntryWidget()->GetCharWidth() * 30, -1));
table->Add(new wxStaticText(this, wxID_ANY, _("Engine Path")), 0, wxALIGN_CENTRE_VERTICAL);
table->Add(_enginePathEntry, 1, wxEXPAND);
_fsGameEntry = new wxTextCtrl(this, wxID_ANY);
_fsGameEntry->SetMinClientSize(wxSize(_fsGameEntry->GetCharWidth() * 30, -1));
table->Add(new wxStaticText(this, wxID_ANY, _("Mod (fs_game)")), 0, wxALIGN_CENTRE_VERTICAL);
table->Add(_fsGameEntry, 1, wxEXPAND);
_fsGameBaseEntry = new wxTextCtrl(this, wxID_ANY);
_fsGameBaseEntry->SetMinClientSize(wxSize(_fsGameEntry->GetCharWidth() * 30, -1));
table->Add(new wxStaticText(this, wxID_ANY, _("Mod Base (fs_game_base)")), 0, wxALIGN_CENTRE_VERTICAL);
table->Add(_fsGameBaseEntry, 1, wxEXPAND);
}
const char* GameSetupPageIdTech::TYPE()
{
return "idTechGeneric";
}
const char* GameSetupPageIdTech::getType()
{
return TYPE();
}
void GameSetupPageIdTech::validateSettings()
{
constructPaths();
std::string errorMsg;
if (!os::fileOrDirExists(_config.enginePath))
{
// Engine path doesn't exist
errorMsg += fmt::format(_("Engine path \"{0}\" does not exist.\n"), _config.enginePath);
}
// Check the mod base path, if not empty
if (!_config.modBasePath.empty() && !os::fileOrDirExists(_config.modBasePath))
{
// Mod base name is not empty, but folder doesnt' exist
errorMsg += fmt::format(_("The mod base path \"{0}\" does not exist.\n"), _config.modBasePath);
}
// Check the mod path, if not empty
if (!_config.modPath.empty() && !os::fileOrDirExists(_config.modPath))
{
// Mod name is not empty, but mod folder doesnt' exist
errorMsg += fmt::format(_("The mod path \"{0}\" does not exist.\n"), _config.modPath);
}
if (!errorMsg.empty())
{
throw GameSettingsInvalidException(errorMsg);
}
}
void GameSetupPageIdTech::onPageShown()
{
// Load the values from the registry if the controls are still empty
if (_enginePathEntry->getValue().empty())
{
_config.enginePath = registry::getValue<std::string>(RKEY_ENGINE_PATH);
if (_config.enginePath.empty())
{
// No engine path known, but we have a valid game description
// Try to deduce the engine path from the Registry settings (Win32 only)
std::string regKey = _game->getKeyValue("registryKey");
std::string regValue = _game->getKeyValue("registryValue");
rMessage() << "GameSetupPageIdTech: Querying Windows Registry for game path: "
<< "HKEY_LOCAL_MACHINE\\" << regKey << "\\" << regValue << std::endl;
// Query the Windows Registry for a default installation path
// This will return "" for non-Windows environments
_config.enginePath = game::Win32Registry::getKeyValue(regKey, regValue);
rMessage() << "GameManager: Windows Registry returned result: " << _config.enginePath << std::endl;
}
// If the engine path is still empty, consult the .game file for a fallback value
if (_config.enginePath.empty())
{
// No engine path set so far, search the game file for default values
const std::string ENGINEPATH_ATTRIBUTE =
#if defined(WIN32)
"enginepath_win32"
#elif defined(__linux__) || defined (__FreeBSD__)
"enginepath_linux"
#elif defined(__APPLE__)
"enginepath_macos"
#else
#error "unknown platform"
#endif
;
_config.enginePath = os::standardPathWithSlash(_game->getKeyValue(ENGINEPATH_ATTRIBUTE));
}
_enginePathEntry->setValue(_config.enginePath);
}
if (_fsGameEntry->GetValue().empty())
{
// Check if we have a valid mod path
_config.modPath = registry::getValue<std::string>(RKEY_MOD_PATH);
if (!_config.modPath.empty())
{
// Extract the fs_game part from the absolute mod path, if possible
std::string fsGame = os::getRelativePath(_config.modPath, _config.enginePath);
string::trim_right(fsGame, "/");
_fsGameEntry->SetValue(fsGame);
}
}
if (_fsGameBaseEntry->GetValue().empty())
{
// Check if we have a valid mod base path
_config.modBasePath = registry::getValue<std::string>(RKEY_MOD_BASE_PATH);
if (!_config.modBasePath.empty())
{
std::string fsGameBase = os::getRelativePath(_config.modBasePath, _config.enginePath);
string::trim_right(fsGameBase, "/");
// Extract the fs_game part from the absolute mod base path, if possible
_fsGameBaseEntry->SetValue(fsGameBase);
}
}
}
void GameSetupPageIdTech::constructPaths()
{
_config.enginePath = _enginePathEntry->getEntryWidget()->GetValue().ToStdString();
// Make sure it's a well formatted path
_config.enginePath = os::standardPathWithSlash(_config.enginePath);
// Load the fsGame and fsGameBase values from the widgets
std::string fsGame = _fsGameEntry->GetValue().ToStdString();
std::string fsGameBase = _fsGameBaseEntry->GetValue().ToStdString();
if (!fsGameBase.empty())
{
// greebo: #3480 check if the mod base path is absolute. If not, append it to the engine path
_config.modBasePath = fs::path(fsGameBase).is_absolute() ? fsGameBase : _config.enginePath + fsGameBase;
// Normalise the path as last step
_config.modBasePath = os::standardPathWithSlash(_config.modBasePath);
}
else
{
// No fs_game_base, no mod base path
_config.modBasePath = "";
}
if (!fsGame.empty())
{
// greebo: #3480 check if the mod path is absolute. If not, append it to the engine path
_config.modPath = fs::path(fsGame).is_absolute() ? fsGame : _config.enginePath + fsGame;
// Normalise the path as last step
_config.modPath = os::standardPathWithSlash(_config.modPath);
}
else
{
// No fs_game, no modpath
_config.modPath = "";
}
}
}