| 1 | /* |
| 2 | * LegacyClonk |
| 3 | * |
| 4 | * Copyright (c) 1998-2000, Matthes Bender (RedWolf Design) |
| 5 | * Copyright (c) 2017-2022, The LegacyClonk Team and contributors |
| 6 | * |
| 7 | * Distributed under the terms of the ISC license; see accompanying file |
| 8 | * "COPYING" for details. |
| 9 | * |
| 10 | * "Clonk" is a registered trademark of Matthes Bender, used with permission. |
| 11 | * See accompanying file "TRADEMARK" for details. |
| 12 | * |
| 13 | * To redistribute this file separately, substitute the full license texts |
| 14 | * for the above references. |
| 15 | */ |
| 16 | |
| 17 | /* Game configuration as stored in registry */ |
| 18 | |
| 19 | #pragma once |
| 20 | |
| 21 | #include "C4Constants.h" |
| 22 | #include "C4Cooldown.h" |
| 23 | #include "C4InputValidation.h" |
| 24 | #include "StdConfig.h" |
| 25 | |
| 26 | #ifdef C4ENGINE |
| 27 | #include "C4AulScriptStrict.h" |
| 28 | #include "C4Log.h" |
| 29 | #include "StdWindow.h" |
| 30 | #endif |
| 31 | |
| 32 | #define C4CFG_Company "LegacyClonk Team" |
| 33 | #define C4CFG_Product "LegacyClonk" |
| 34 | |
| 35 | #define C4CFG_OfficialLeagueServer "league.clonkspot.org" |
| 36 | #define C4CFG_LeagueServer "https://" C4CFG_OfficialLeagueServer |
| 37 | #define C4CFG_FallbackServer C4CFG_LeagueServer |
| 38 | |
| 39 | #define C4CFG_UpdateServer "https://update.clonkspot.org/lc/update" // for download files, replace 'update' with the below |
| 40 | |
| 41 | #define C4CFG_UpdateEngine "lc_{}_{}.c4u" |
| 42 | #define C4CFG_UpdateObjects "lc_{}{}{}{}_{}_{}.c4u" |
| 43 | #define C4CFG_UpdateMajor "lc_{}{}{}{}_{}.c4u" |
| 44 | |
| 45 | class C4ConfigGeneral |
| 46 | { |
| 47 | public: |
| 48 | enum { ConfigResetSafetyVal = 42 }; |
| 49 | |
| 50 | uint32_t Version; // config version number for compatibility changes |
| 51 | char Name[CFG_MaxString + 1]; |
| 52 | char Language[CFG_MaxString + 1]; // entered by user in frontend options (may contain comma separated list or long language descriptions) |
| 53 | char LanguageEx[CFG_MaxString + 1]; // full fallback list composed by frontend options (condensed comma separated list) |
| 54 | char LanguageCharset[CFG_MaxString + 1]; |
| 55 | char Definitions[CFG_MaxString + 1]; |
| 56 | char Participants[CFG_MaxString + 1]; |
| 57 | bool AlwaysDebug; // if set: turns on debugmode whenever engine is started |
| 58 | bool AllowScriptingInReplays; // allow /script in replays (scripts can cause desyncs) |
| 59 | char RXFontName[CFG_MaxString + 1]; |
| 60 | int32_t RXFontSize; |
| 61 | char PlayerPath[CFG_MaxString + 1]; |
| 62 | char DefinitionPath[CFG_MaxString + 1]; |
| 63 | char UserPath[CFG_MaxString + 1]; // absolute path; environment variables are stored and only expanded upon evaluation |
| 64 | StdStrBuf SaveGameFolder; |
| 65 | StdStrBuf SaveDemoFolder; |
| 66 | StdStrBuf ScreenshotFolder; |
| 67 | char MissionAccess[CFG_MaxString + 1]; |
| 68 | bool FPS; |
| 69 | bool Record; |
| 70 | bool FairCrew; // don't use permanent crew physicals |
| 71 | int32_t FairCrewStrength; // strength of clonks in fair crew mode |
| 72 | int32_t MouseAScroll; // auto scroll strength |
| 73 | int32_t ScrollSmooth; // view movement smoothing |
| 74 | int32_t ConfigResetSafety; // safety value: If this value is screwed, the config got currupted and must be reset |
| 75 | // Determined at run-time |
| 76 | char ExePath[CFG_MaxString + 1]; |
| 77 | char TempPath[CFG_MaxString + 1]; |
| 78 | char LogPath[CFG_MaxString + 1]; |
| 79 | char ScreenshotPath[CFG_MaxString + 1]; |
| 80 | bool GamepadEnabled; |
| 81 | bool FirstStart; |
| 82 | bool fUTF8; |
| 83 | bool UserPortraitsWritten; // set when default portraits have been copied to the UserPath (this is only done once) |
| 84 | bool UseWhiteIngameChat; |
| 85 | bool UseWhiteLobbyChat; |
| 86 | bool ShowLogTimestamps; |
| 87 | bool Preloading; |
| 88 | #ifndef _WIN32 |
| 89 | std::uint32_t ThreadPoolThreadCount; |
| 90 | #endif |
| 91 | |
| 92 | public: |
| 93 | static int GetLanguageSequence(const char *strSource, char *strTarget); |
| 94 | void DefaultLanguage(); |
| 95 | bool CreateSaveFolder(const char *strDirectory, const char *strLanguageTitle); |
| 96 | void DeterminePaths(bool forceWorkingDirectory); |
| 97 | void CompileFunc(StdCompiler *pComp); |
| 98 | }; |
| 99 | |
| 100 | #ifdef C4ENGINE |
| 101 | |
| 102 | class C4ConfigDeveloper |
| 103 | { |
| 104 | public: |
| 105 | struct ConsoleScriptStrictnessWrapper |
| 106 | { |
| 107 | C4AulScriptStrict Strictness; |
| 108 | |
| 109 | void CompileFunc(StdCompiler *comp); |
| 110 | |
| 111 | operator C4AulScriptStrict() const noexcept { return Strictness == MaxStrictSentinel ? C4AulScriptStrict::MAXSTRICT : Strictness; } |
| 112 | |
| 113 | static constexpr auto MaxStrictSentinel = static_cast<C4AulScriptStrict>(255); |
| 114 | }; |
| 115 | |
| 116 | public: |
| 117 | bool AutoFileReload; |
| 118 | ConsoleScriptStrictnessWrapper ConsoleScriptStrictness; |
| 119 | |
| 120 | void CompileFunc(StdCompiler *pComp); |
| 121 | }; |
| 122 | |
| 123 | class C4ConfigGraphics |
| 124 | { |
| 125 | public: |
| 126 | enum RenderInactive : uint32_t |
| 127 | { |
| 128 | Fullscreen = 1 << 0, |
| 129 | Console = 1 << 1 |
| 130 | }; |
| 131 | |
| 132 | int32_t SplitscreenDividers; |
| 133 | bool ShowPlayerHUDAlways; |
| 134 | bool ShowCommands; |
| 135 | bool ShowCommandKeys; |
| 136 | bool ShowPortraits; |
| 137 | bool AddNewCrewPortraits; |
| 138 | bool SaveDefaultPortraits; |
| 139 | int32_t VerboseObjectLoading; |
| 140 | bool ColorAnimation; |
| 141 | int32_t SmokeLevel; |
| 142 | int32_t UpperBoard; |
| 143 | bool ShowClock; |
| 144 | int32_t ResX, ResY; |
| 145 | int32_t Scale; |
| 146 | bool ShowCrewNames; // show player name above clonks? |
| 147 | bool ShowCrewCNames; // show clonk names above clonks? |
| 148 | bool NoAlphaAdd; // always modulate alpha values instead of assing them (->no custom modulated alpha) |
| 149 | bool PointFiltering; // don't use linear filtering, because some crappy graphic cards can't handle it... |
| 150 | bool NoBoxFades; // map all DrawBoxFade-calls to DrawBoxDw |
| 151 | uint32_t AllowedBlitModes; // bit mask for allowed blitting modes |
| 152 | bool NoAcceleration; // whether direct rendering is used (X11) |
| 153 | bool Shader; // whether to use pixelshaders |
| 154 | bool MsgBoard; |
| 155 | bool PXSGfx; // show PXS-graphics (instead of sole pixels) |
| 156 | int32_t Engine; // 0: OpenGL; 3: disabled graphics |
| 157 | std::int32_t BlitOffset; // blit offset (percent) (OpenGL) |
| 158 | std::int32_t TexIndent; // blit offset (per mille) (OpenGL) |
| 159 | int32_t Gamma1, Gamma2, Gamma3; // gamma ramps |
| 160 | uint32_t RenderInactive; // draw viewports even if inactive. 1 = Fullscreen, 2 = EM, 1 | 2 = both |
| 161 | bool DisableGamma; |
| 162 | int32_t Monitor; // monitor index to play on |
| 163 | bool FireParticles; // draw extended fire particles if enabled (defualt on) |
| 164 | int32_t MaxRefreshDelay; // minimum time after which graphics should be refreshed (ms) |
| 165 | bool AutoFrameSkip; // if true, gfx frames are skipped when they would slow down the game |
| 166 | int32_t CacheTexturesInRAM; // -1 for disabled; otherwise after CacheTexturesInRAM times of Locking, Unlock(true) keeps the texture in RAM |
| 167 | DisplayMode UseDisplayMode; |
| 168 | #ifdef _WIN32 |
| 169 | bool Maximized; |
| 170 | int PositionX; |
| 171 | int PositionY; |
| 172 | #endif |
| 173 | bool ShowFolderMaps; // if true, folder maps are shown |
| 174 | bool UseShaderGamma; // whether to use shader-based gamma correction |
| 175 | |
| 176 | void CompileFunc(StdCompiler *pComp); |
| 177 | }; |
| 178 | |
| 179 | class C4ConfigSound |
| 180 | { |
| 181 | public: |
| 182 | bool RXSound; |
| 183 | bool RXMusic; |
| 184 | bool FEMusic; |
| 185 | bool FESamples; |
| 186 | int32_t MusicVolume; |
| 187 | int32_t SoundVolume; |
| 188 | int32_t MaxChannels; |
| 189 | bool PreferLinearResampling; |
| 190 | bool MuteSoundCommand; // whether to mute /sound by default |
| 191 | void CompileFunc(StdCompiler *pComp); |
| 192 | }; |
| 193 | |
| 194 | class C4ConfigNetwork |
| 195 | { |
| 196 | public: |
| 197 | int32_t ControlRate; |
| 198 | bool NoRuntimeJoin; |
| 199 | int32_t MaxResSearchRecursion; |
| 200 | char WorkPath[CFG_MaxString + 1]; |
| 201 | ValidatedStdStrBuf<C4InVal::VAL_Comment> ; |
| 202 | bool MasterServerSignUp; |
| 203 | int32_t MasterReferencePeriod; |
| 204 | bool LeagueServerSignUp; |
| 205 | bool UseAlternateServer; |
| 206 | int32_t PortTCP, PortUDP, PortDiscovery, PortRefServer; |
| 207 | int32_t ControlMode; |
| 208 | ValidatedStdStrBuf<C4InVal::VAL_NameNoEmpty> LocalName; |
| 209 | ValidatedStdStrBuf<C4InVal::VAL_NameAllowEmpty> Nick; |
| 210 | int32_t MaxLoadFileSize; |
| 211 | char LastPassword[CFG_MaxString + 1]; |
| 212 | char ServerAddress[CFG_MaxString + 1]; |
| 213 | char AlternateServerAddress[CFG_MaxString + 1]; |
| 214 | char UpdateServerAddress[CFG_MaxString + 1]; |
| 215 | char PuncherAddress[CFG_MaxString + 1]; |
| 216 | |
| 217 | StdStrBuf LeagueAccount; |
| 218 | StdStrBuf LeaguePassword; |
| 219 | bool LeagueAutoLogin; |
| 220 | |
| 221 | bool AutomaticUpdate; |
| 222 | uint64_t LastUpdateTime; |
| 223 | int32_t AsyncMaxWait; |
| 224 | bool UseCurl; |
| 225 | bool EnableUPnP; |
| 226 | |
| 227 | static constexpr auto DefaultPuncherServer = "netpuncher.openclonk.org:11115" ; |
| 228 | |
| 229 | public: |
| 230 | void CompileFunc(StdCompiler *pComp); |
| 231 | const char *GetLeagueServerAddress(); |
| 232 | }; |
| 233 | |
| 234 | class C4ConfigStartup |
| 235 | { |
| 236 | public: |
| 237 | // config for do-not-show-this-msg-again-messages |
| 238 | bool HideMsgStartDedicated; |
| 239 | bool HideMsgPlrTakeOver; |
| 240 | bool HideMsgPlrNoTakeOver; |
| 241 | bool HideMsgNoOfficialLeague; |
| 242 | bool HideMsgIRCDangerous; |
| 243 | bool AlphabeticalSorting; // if set, Folder.txt-sorting is ignored in scenario selection |
| 244 | int32_t LastPortraitFolderIdx; |
| 245 | void CompileFunc(StdCompiler *pComp); |
| 246 | }; |
| 247 | |
| 248 | class C4ConfigLobby |
| 249 | { |
| 250 | public: |
| 251 | int32_t CountdownTime; |
| 252 | bool AllowPlayerSave; // whether save-to-disk function is enabled for player ressources |
| 253 | void CompileFunc(StdCompiler *pComp); |
| 254 | }; |
| 255 | |
| 256 | class C4ConfigIRC |
| 257 | { |
| 258 | public: |
| 259 | char Server[CFG_MaxString + 1]; |
| 260 | char Nick[CFG_MaxString + 1]; |
| 261 | char RealName[CFG_MaxString + 1]; |
| 262 | char Channel[CFG_MaxString + 1]; |
| 263 | void CompileFunc(StdCompiler *pComp); |
| 264 | }; |
| 265 | |
| 266 | const int C4ConfigMaxGamepads = 4; |
| 267 | |
| 268 | class C4ConfigGamepad |
| 269 | { |
| 270 | public: |
| 271 | int32_t Button[C4MaxKey]; |
| 272 | uint32_t AxisMin[6], AxisMax[6]; |
| 273 | bool AxisCalibrated[6]; |
| 274 | void CompileFunc(StdCompiler *pComp, bool fButtonsOnly = false); |
| 275 | void Reset(); // reset all buttons and axis calibration to default |
| 276 | }; |
| 277 | |
| 278 | class C4ConfigControls |
| 279 | { |
| 280 | public: |
| 281 | int32_t GamepadGuiControl; |
| 282 | int32_t MouseAScroll; // auto scroll strength |
| 283 | int32_t Keyboard[C4MaxKeyboardSet][C4MaxKey]; |
| 284 | void CompileFunc(StdCompiler *pComp, bool fKeysOnly = false); |
| 285 | void ResetKeys(); // reset all keys to default |
| 286 | }; |
| 287 | |
| 288 | class C4ConfigCooldowns |
| 289 | { |
| 290 | public: |
| 291 | C4CooldownSeconds SoundCommand; |
| 292 | C4CooldownSeconds ReadyCheck; |
| 293 | void CompileFunc(StdCompiler *comp); |
| 294 | }; |
| 295 | |
| 296 | class C4ConfigToasts |
| 297 | { |
| 298 | public: |
| 299 | bool ReadyCheck; |
| 300 | void CompileFunc(StdCompiler *comp); |
| 301 | }; |
| 302 | |
| 303 | class C4ConfigLogging |
| 304 | { |
| 305 | public: |
| 306 | spdlog::level::level_enum LogLevelStdout; |
| 307 | |
| 308 | C4LoggerConfig::Config<class C4AudioSystem> AudioSystem; |
| 309 | C4LoggerConfig::Config<class C4AulExec> AulExec; |
| 310 | C4LoggerConfig::Config<class C4AulProfiler> AulProfiler; |
| 311 | C4LoggerConfig::Config<class CStdDDraw> DDraw; |
| 312 | C4LoggerConfig::Config<class C4GameControl> GameControl; |
| 313 | C4LoggerConfig::Config<class C4Network2> Network; |
| 314 | C4LoggerConfig::Config<class C4Network2IO> Network2IO; |
| 315 | C4LoggerConfig::Config<class C4Network2HTTPClient> Network2HTTPClient; |
| 316 | C4LoggerConfig::Config<class C4Network2UPnP> Network2UPnP; |
| 317 | C4LoggerConfig::Config<class C4Playback> Playback; |
| 318 | C4LoggerConfig::Config<class CPNGFile> PNGFile; |
| 319 | |
| 320 | #ifdef WITH_GLIB |
| 321 | C4LoggerConfig::Config<struct _GMainLoop> GLib; |
| 322 | #endif |
| 323 | |
| 324 | void CompileFunc(StdCompiler *comp); |
| 325 | }; |
| 326 | |
| 327 | #endif |
| 328 | |
| 329 | class C4Config |
| 330 | { |
| 331 | public: |
| 332 | C4Config(); |
| 333 | ~C4Config(); |
| 334 | |
| 335 | public: |
| 336 | C4ConfigGeneral General; |
| 337 | #ifdef C4ENGINE |
| 338 | C4ConfigDeveloper Developer; |
| 339 | C4ConfigGraphics Graphics; |
| 340 | C4ConfigSound Sound; |
| 341 | C4ConfigNetwork Network; |
| 342 | C4ConfigLobby Lobby; |
| 343 | C4ConfigIRC IRC; |
| 344 | C4ConfigGamepad Gamepads[C4ConfigMaxGamepads]; |
| 345 | C4ConfigControls Controls; |
| 346 | C4ConfigStartup Startup; |
| 347 | C4ConfigCooldowns Cooldowns; |
| 348 | C4ConfigToasts Toasts; |
| 349 | C4ConfigLogging Logging; |
| 350 | #endif |
| 351 | bool fConfigLoaded; // true if config has been successfully loaded |
| 352 | StdStrBuf ConfigFilename; // set for configs loaded from a nondefault config file |
| 353 | |
| 354 | public: |
| 355 | const char *GetSubkeyPath(const char *strSubkey); |
| 356 | void Default(); |
| 357 | bool Save(); |
| 358 | bool Load(bool forceWorkingDirectory = true, const char *szConfigFile = nullptr); |
| 359 | bool Init(); |
| 360 | const char *AtExePath(const char *szFilename); |
| 361 | const char *AtTempPath(const char *szFilename); |
| 362 | #ifdef C4ENGINE |
| 363 | const char *AtNetworkPath(const char *szFilename); |
| 364 | #endif |
| 365 | const char *AtExeRelativePath(const char *szFilename); |
| 366 | const char *AtScreenshotPath(const char *szFilename); |
| 367 | const char *AtUserPath(const char *szFilename); // this one will expand environment variables on-the-fly |
| 368 | void ForceRelativePath(StdStrBuf *sFilename); // try AtExeRelativePath; force GetC4Filename if not possible |
| 369 | void CompileFunc(StdCompiler *pComp); |
| 370 | bool IsCorrupted() |
| 371 | { |
| 372 | return (General.ConfigResetSafety != C4ConfigGeneral::ConfigResetSafetyVal) |
| 373 | #ifdef C4ENGINE |
| 374 | || !Graphics.ResX |
| 375 | #endif |
| 376 | ; |
| 377 | } |
| 378 | |
| 379 | static const char *GetCharsetCodeName(const char *charset) noexcept; |
| 380 | static std::uint8_t GetCharsetCode(const char *charset) noexcept; |
| 381 | static std::int32_t GetCharsetCodePage(const char *charset) noexcept; |
| 382 | |
| 383 | protected: |
| 384 | void ExpandEnvironmentVariables(char *strPath, int iMaxLen); |
| 385 | |
| 386 | #ifdef C4ENGINE |
| 387 | private: |
| 388 | void AdaptToCurrentVersion(); |
| 389 | #endif |
| 390 | }; |
| 391 | |
| 392 | extern C4Config Config; |
| 393 | |