openclonk/src/config/C4Config.cpp

968 lines
40 KiB
C++
Raw Normal View History

2009-05-08 13:28:41 +00:00
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: t; c-basic-offset: 2 -*- */
/*
* OpenClonk, http://www.openclonk.org
* Copyright (c) 1998-2000, 2003-2004, 2007-2008 Matthes Bender
* Copyright (c) 2002, 2006-2008 Sven Eberhardt
* Copyright (c) 2003, 2005-2007 Peter Wortmann
* Copyright (c) 2005-2009 Günther Brammer
* Copyright (c) 2006 Alex
* Copyright (c) 2006-2007 Julian Raschke
* Copyright (c) 2008 Armin Burgmeier
* Copyright (c) 2009 Nicolas Hake
2009-05-08 13:28:41 +00:00
*
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de
*
* Portions might be copyrighted by other authors who have contributed
* to OpenClonk.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* See isc_license.txt for full license and disclaimer.
*
* "Clonk" is a registered trademark of Matthes Bender.
* See clonk_trademark_license.txt for full license.
*/
/* Game configuration as stored in registry */
#include <C4Include.h>
#include <C4Config.h>
#include <C4Version.h>
#include <C4Log.h>
#include <C4Components.h>
#include <C4Network2.h>
#include <C4Language.h>
2009-11-25 18:38:54 +00:00
#include <utility>
2009-05-08 13:28:41 +00:00
#include <StdFile.h>
#include <StdWindow.h>
#include <StdRegistry.h>
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
#include "MacUtility.h"
2009-05-08 13:28:41 +00:00
bool isGermanSystem()
{
#ifdef _WIN32
2010-03-28 18:58:01 +00:00
if (PRIMARYLANGID(GetUserDefaultLangID()) == LANG_GERMAN) return true;
#elif defined(__APPLE__)
return MacUtility::isGerman();
2009-05-08 13:28:41 +00:00
#else
2010-03-28 18:58:01 +00:00
if (strstr(setlocale(LC_MESSAGES, 0), "de")) return true;
2009-05-08 13:28:41 +00:00
#endif
2010-03-28 18:58:01 +00:00
return false;
2009-05-08 13:28:41 +00:00
}
C4Config *pConfig;
void C4ConfigGeneral::CompileFunc(StdCompiler *pComp)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// For those without the ability to intuitively guess what the falses and trues mean:
// its mkNamingAdapt(field, name, default, fPrefillDefault, fStoreDefault)
// where fStoreDefault writes out the value to the config even if it's the same as the default.
#define s mkStringAdaptM
2010-03-28 18:58:01 +00:00
pComp->Value(mkNamingAdapt(s(Name), "Name", "" ));
pComp->Value(mkNamingAdapt(s(Language), "Language", "", false, true));
pComp->Value(mkNamingAdapt(s(LanguageEx), "LanguageEx", "", false, true));
pComp->Value(mkNamingAdapt(s(Definitions), "Definitions", "" ));
pComp->Value(mkNamingAdapt(s(Participants), "Participants", "" ));
2009-05-08 13:28:41 +00:00
// deliberately not grandfathering UserPath setting, since it was written to config by default
pComp->Value(mkNamingAdapt(s(ConfigUserPath), "UserDataPath", "", false, true));
// assimilate old data
pComp->Value(mkNamingAdapt(s(Adopt.PlayerPath), "PlayerPath", ""));
2010-03-28 18:58:01 +00:00
pComp->Value(mkNamingAdapt(SaveGameFolder, "SaveGameFolder", "Savegames.c4f", false, true));
pComp->Value(mkNamingAdapt(SaveDemoFolder, "SaveDemoFolder", "Records.c4f", false, true ));
pComp->Value(mkNamingAdapt(s(MissionAccess), "MissionAccess", "", false, true));
pComp->Value(mkNamingAdapt(s(UpdateEngine), "UpdateEngine", "www.clonkx.de/" C4ENGINENICK "/cr_%d_%s.c4u"));
pComp->Value(mkNamingAdapt(s(UpdateObjects), "UpdateObjects", "www.clonkx.de/" C4ENGINENICK "/cr_%d%d%d%d_%d_%s.c4u"));
pComp->Value(mkNamingAdapt(s(UpdateMajor), "UpdateMajor", "www.clonkx.de/" C4ENGINENICK "/cr_%d%d%d%d_%s.c4u"));
pComp->Value(mkNamingAdapt(FPS, "FPS", 0 ));
pComp->Value(mkNamingAdapt(Record, "Record", 0 ));
pComp->Value(mkNamingAdapt(DefRec, "DefRec", 0 ));
pComp->Value(mkNamingAdapt(ScreenshotFolder, "ScreenshotFolder", "Screenshots", false, true));
pComp->Value(mkNamingAdapt(FairCrew, "NoCrew", 0 ));
pComp->Value(mkNamingAdapt(FairCrewStrength, "DefCrewStrength", 1000 ));
pComp->Value(mkNamingAdapt(MaxFairCrewStrength, "MaxFairCrewStrength",1000 ));
pComp->Value(mkNamingAdapt(ScrollSmooth, "ScrollSmooth", 4 ));
pComp->Value(mkNamingAdapt(AlwaysDebug, "DebugMode", 0 ));
2009-05-08 13:28:41 +00:00
#ifdef _WIN32
2010-03-28 18:58:01 +00:00
pComp->Value(mkNamingAdapt(MMTimer, "MMTimer", 1 ));
2009-05-08 13:28:41 +00:00
#endif
2010-03-28 18:58:01 +00:00
pComp->Value(mkNamingAdapt(s(RXFontName), "FontName", "Endeavour", false, true));
pComp->Value(mkNamingAdapt(RXFontSize, "FontSize", 14, false, true));
pComp->Value(mkNamingAdapt(GamepadEnabled, "GamepadEnabled", true ));
pComp->Value(mkNamingAdapt(FirstStart, "FirstStart", true ));
pComp->Value(mkNamingAdapt(UserPortraitsWritten,"UserPortraitsWritten",false ));
pComp->Value(mkNamingAdapt(ConfigResetSafety, "ConfigResetSafety", static_cast<int32_t>(ConfigResetSafetyVal) ));
}
2009-05-08 13:28:41 +00:00
void C4ConfigDeveloper::CompileFunc(StdCompiler *pComp)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
#ifdef _WIN32
2010-03-28 18:58:01 +00:00
pComp->Value(mkNamingAdapt(AutoEditScan, "AutoEditScan", 1 ));
2009-05-08 13:28:41 +00:00
#endif
2010-03-28 18:58:01 +00:00
pComp->Value(mkNamingAdapt(AutoFileReload, "AutoFileReload", 1 ));
pComp->Value(mkNamingAdapt(AllErrorsFatal, "AllErrorsFatal", 0 ));
}
2009-05-08 13:28:41 +00:00
void C4ConfigGraphics::CompileFunc(StdCompiler *pComp)
2010-03-28 18:58:01 +00:00
{
pComp->Value(mkNamingAdapt(ResX, "ResolutionX", 800 ,false, true));
pComp->Value(mkNamingAdapt(ResY, "ResolutionY", 600 ,false, true));
pComp->Value(mkNamingAdapt(GuiResX, "GuiResolutionX", 800 ,false, true));
pComp->Value(mkNamingAdapt(GuiResY, "GuiResolutionY", 600 ,false, true));
pComp->Value(mkNamingAdapt(ShowAllResolutions, "ShowAllResolutions", 0 ,false, true));
pComp->Value(mkNamingAdapt(SplitscreenDividers, "SplitscreenDividers", 1 ));
pComp->Value(mkNamingAdapt(AddNewCrewPortraits, "AddNewCrewPortraits", 0 ,false, true));
pComp->Value(mkNamingAdapt(SaveDefaultPortraits, "SaveDefaultPortraits", 0 ,false, true));
pComp->Value(mkNamingAdapt(ShowStartupMessages, "ShowStartupMessages", 1 ,false, true));
pComp->Value(mkNamingAdapt(ColorAnimation, "ColorAnimation", 0 ,false, true));
pComp->Value(mkNamingAdapt(HighResLandscape, "HighResLandscape", 0 ,false, true));
pComp->Value(mkNamingAdapt(SmokeLevel, "SmokeLevel", 200 ,false, true));
pComp->Value(mkNamingAdapt(VerboseObjectLoading, "VerboseObjectLoading", 0 ));
pComp->Value(mkNamingAdapt(VideoModule, "VideoModule", 0 ,false, true));
pComp->Value(mkNamingAdapt(MenuTransparency, "MenuTransparency", 1 ,false, true));
pComp->Value(mkNamingAdapt(UpperBoard, "UpperBoard", 1 ,false, true));
pComp->Value(mkNamingAdapt(ShowClock, "ShowClock", 0 ,false, true));
pComp->Value(mkNamingAdapt(ShowCrewNames, "ShowCrewNames", 1 ,false, true));
pComp->Value(mkNamingAdapt(ShowCrewCNames, "ShowCrewCNames", 1 ,false, true));
pComp->Value(mkNamingAdapt(BitDepth, "BitDepth", 32 ,false, true));
pComp->Value(mkNamingAdapt(Windowed, "Windowed", 0 ,false, true));
pComp->Value(mkNamingAdapt(MsgBoard, "MsgBoard" , 1 ));
pComp->Value(mkNamingAdapt(MsgBrdFadeDelay, "MsgBrdFadeDelay" , 10 ));
pComp->Value(mkNamingAdapt(PXSGfx, "PXSGfx" , 1 ));
pComp->Value(mkNamingAdapt(Engine, "Engine" , 1 ,false, true));
pComp->Value(mkNamingAdapt(Gamma1, "Gamma1" , 0 ));
pComp->Value(mkNamingAdapt(Gamma2, "Gamma2" , 0x808080 ));
pComp->Value(mkNamingAdapt(Gamma3, "Gamma3" , 0xffffff ));
pComp->Value(mkNamingAdapt(Currency, "Currency" , 0 ));
pComp->Value(mkNamingAdapt(RenderInactiveEM, "RenderInactiveEM", 1 ));
pComp->Value(mkNamingAdapt(DisableGamma, "DisableGamma", 0 ,false, true));
pComp->Value(mkNamingAdapt(Monitor, "Monitor", 0 )); // 0 = D3DADAPTER_DEFAULT
pComp->Value(mkNamingAdapt(FireParticles, "FireParticles", 1 ));
pComp->Value(mkNamingAdapt(MaxRefreshDelay, "MaxRefreshDelay", 30 ));
pComp->Value(mkNamingAdapt(EnableShaders, "Shader", 0 ,false, true));
}
2009-05-08 13:28:41 +00:00
void C4ConfigSound::CompileFunc(StdCompiler *pComp)
2010-03-28 18:58:01 +00:00
{
pComp->Value(mkNamingAdapt(RXSound, "Sound", 1 ,false, true));
pComp->Value(mkNamingAdapt(RXMusic, "Music", 1 ,false, true));
pComp->Value(mkNamingAdapt(FEMusic, "MenuMusic", 1 ,false, true));
pComp->Value(mkNamingAdapt(FESamples, "MenuSound", 1 ,false, true));
pComp->Value(mkNamingAdapt(FMMode, "FMMode", 1 ));
pComp->Value(mkNamingAdapt(Verbose, "Verbose", 0 ));
pComp->Value(mkNamingAdapt(MusicVolume, "MusicVolume", 100 ,false, true));
pComp->Value(mkNamingAdapt(SoundVolume, "SoundVolume", 100 ,false, true));
}
2009-05-08 13:28:41 +00:00
void C4ConfigNetwork::CompileFunc(StdCompiler *pComp)
2010-03-28 18:58:01 +00:00
{
pComp->Value(mkNamingAdapt(ControlRate, "ControlRate", 1 ,false, true));
pComp->Value(mkNamingAdapt(ControlPreSend, "ControlPreSend", -1 ));
pComp->Value(mkNamingAdapt(s(WorkPath), "WorkPath", "Network" ,false, true));
pComp->Value(mkNamingAdapt(Lobby, "Lobby", 0 ));
pComp->Value(mkNamingAdapt(NoRuntimeJoin, "NoRuntimeJoin", 0 ,false, true));
pComp->Value(mkNamingAdapt(NoReferenceRequest, "NoReferenceRequest", 0 ));
2009-05-08 13:28:41 +00:00
pComp->Value(mkNamingAdapt(MaxResSearchRecursion, "MaxResSearchRecursion",1 ,false, true));
2010-03-28 18:58:01 +00:00
pComp->Value(mkNamingAdapt(Comment, "Comment", "" ,false, true));
pComp->Value(mkNamingAdapt(PortTCP, "PortTCP", C4NetStdPortTCP ,false, true));
pComp->Value(mkNamingAdapt(PortUDP, "PortUDP", C4NetStdPortUDP ,false, true));
pComp->Value(mkNamingAdapt(PortDiscovery, "PortDiscovery", C4NetStdPortDiscovery ,false, true));
pComp->Value(mkNamingAdapt(PortRefServer, "PortRefServer", C4NetStdPortRefServer ,false, true));
pComp->Value(mkNamingAdapt(ControlMode, "ControlMode", 0 ));
pComp->Value(mkNamingAdapt(SendPortraits, "SendPortraits", 0 ,false, true));
pComp->Value(mkNamingAdapt(Nick, "Nick", "" ,false, true));
pComp->Value(mkNamingAdapt(MaxLoadFileSize, "MaxLoadFileSize", 5*1024*1024 ,false, true));
pComp->Value(mkNamingAdapt(MasterServerSignUp, "MasterServerSignUp", 1 ));
pComp->Value(mkNamingAdapt(MasterServerActive, "MasterServerActive", 0 ));
pComp->Value(mkNamingAdapt(MasterKeepPeriod, "MasterKeepPeriod", 60 ));
pComp->Value(mkNamingAdapt(MasterReferencePeriod, "MasterReferencePeriod",120 ));
pComp->Value(mkNamingAdapt(LeagueServerSignUp, "LeagueServerSignUp", 0 ));
pComp->Value(mkNamingAdapt(UseAlternateServer, "UseAlternateServer", 0 ));
2010-02-08 21:33:21 +00:00
pComp->Value(mkNamingAdapt(s(AlternateServerAddress),"AlternateServerAddress", "boom.openclonk.org:80/server/"));
pComp->Value(mkNamingAdapt(s(UpdateServerAddress), "UpdateServerAddress", "boom.openclonk.org:80/server/"));
2010-03-28 18:58:01 +00:00
pComp->Value(mkNamingAdapt(s(LastPassword), "LastPassword", "Wipf" ));
pComp->Value(mkNamingAdapt(AutomaticUpdate, "AutomaticUpdate", 0 ,false, true));
pComp->Value(mkNamingAdapt(LastUpdateTime, "LastUpdateTime", 0 ));
pComp->Value(mkNamingAdapt(AsyncMaxWait, "AsyncMaxWait", 2 ));
2009-05-08 13:28:41 +00:00
2010-03-28 18:58:01 +00:00
pComp->Value(mkNamingAdapt(s(PuncherAddress), "PuncherAddress", "clonk.de:11115")); // maybe store default for this one?
2009-05-08 13:28:41 +00:00
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4ConfigLobby::CompileFunc(StdCompiler *pComp)
2010-03-28 18:58:01 +00:00
{
pComp->Value(mkNamingAdapt(AllowPlayerSave, "AllowPlayerSave", 0 ,false, false));
pComp->Value(mkNamingAdapt(CountdownTime, "CountdownTime", 5 ,false, false));
}
2009-05-08 13:28:41 +00:00
void C4ConfigIRC::CompileFunc(StdCompiler *pComp)
2010-03-28 18:58:01 +00:00
{
pComp->Value(mkNamingAdapt(s(Server), "Server", "irc.ham.de.euirc.net", false, true));
pComp->Value(mkNamingAdapt(s(Nick), "Nick", "" , false, true));
pComp->Value(mkNamingAdapt(s(RealName), "RealName", "" , false, true));
pComp->Value(mkNamingAdapt(s(Channel), "Channel", "#clonken" , false, true));
pComp->Value(mkNamingAdapt(AllowAllChannels, "AllowAllChannels", 0 , false, true));
}
2009-05-08 13:28:41 +00:00
void C4ConfigSecurity::CompileFunc(StdCompiler *pComp)
2010-03-28 18:58:01 +00:00
{
pComp->Value(mkNamingAdapt(WasRegistered, "WasRegistered", 0 ));
2009-05-08 13:28:41 +00:00
#ifdef _WIN32
2010-03-28 18:58:01 +00:00
pComp->Value(mkNamingAdapt(s(KeyPath), "KeyPath", "%APPDATA%\\" C4ENGINENAME, false, true));
2009-05-08 13:28:41 +00:00
#elif defined(__linux__)
2010-03-28 18:58:01 +00:00
pComp->Value(mkNamingAdapt(s(KeyPath), "KeyPath", "$HOME/.clonk/" C4ENGINENICK, false, true));
2009-05-08 13:28:41 +00:00
#elif defined(__APPLE__)
2010-03-28 18:58:01 +00:00
pComp->Value(mkNamingAdapt(s(KeyPath), "KeyPath", "$HOME/Library/Application Support/" C4ENGINENAME, false, true));
2009-05-08 13:28:41 +00:00
#endif
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4ConfigGamepad::CompileFunc(StdCompiler *pComp, bool fButtonsOnly)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
/* The defaults here are for a Logitech Dual Action under Linux-SDL. Better than nothing, I guess. */
if (!fButtonsOnly)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
for (int i=0; i<6; ++i)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
pComp->Value(mkNamingAdapt(AxisMin[i], FormatString("Axis%dMin", i).getData(), 0u));
pComp->Value(mkNamingAdapt(AxisMax[i], FormatString("Axis%dMax", i).getData(), 0u));
pComp->Value(mkNamingAdapt(AxisCalibrated[i], FormatString("Axis%dCalibrated", i).getData(), false));
}
}
2010-03-28 18:58:01 +00:00
pComp->Value(mkNamingAdapt(Button[0], "Button1", -1 ));
pComp->Value(mkNamingAdapt(Button[1], "Button2", -1 ));
pComp->Value(mkNamingAdapt(Button[2], "Button3", -1 ));
pComp->Value(mkNamingAdapt(Button[3], "Button4", -1 ));
pComp->Value(mkNamingAdapt(Button[4], "Button5", -1 ));
pComp->Value(mkNamingAdapt(Button[5], "Button6", -1 ));
pComp->Value(mkNamingAdapt(Button[6], "Button7", -1 ));
pComp->Value(mkNamingAdapt(Button[7], "Button8", -1 ));
pComp->Value(mkNamingAdapt(Button[8], "Button9", -1 ));
pComp->Value(mkNamingAdapt(Button[9], "Button10", -1 ));
pComp->Value(mkNamingAdapt(Button[10], "Button11", -1 ));
pComp->Value(mkNamingAdapt(Button[11], "Button12", -1 ));
}
2009-05-08 13:28:41 +00:00
void C4ConfigGamepad::ResetButtons()
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// loads an empty config for the buttons
StdCompilerNull Comp; Comp.Compile(mkParAdapt(*this, true));
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4ConfigGamepad::Reset()
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// loads an empty config for the gamepad config
StdCompilerNull Comp; Comp.Compile(mkParAdapt(*this, false));
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4ConfigControls::CompileFunc(StdCompiler *pComp, bool fKeysOnly)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
#ifndef USE_CONSOLE
#ifdef _WIN32
#define KEY(win, x, sdl) win
#elif defined(USE_X11)
#define KEY(win, x, sdl) x
#else
#define KEY(win, x, sdl) sdl
#endif
bool fGer = isGermanSystem();
2010-03-28 18:58:01 +00:00
pComp->Value(mkNamingAdapt(Keyboard[0][0], "Kbd1Key1", KEY('Q', XK_q, SDLK_q)));
pComp->Value(mkNamingAdapt(Keyboard[0][1], "Kbd1Key2", KEY('W', XK_w, SDLK_w)));
pComp->Value(mkNamingAdapt(Keyboard[0][2], "Kbd1Key3", KEY('E', XK_e, SDLK_e)));
pComp->Value(mkNamingAdapt(Keyboard[0][3], "Kbd1Key4", KEY('A', XK_a, SDLK_a)));
pComp->Value(mkNamingAdapt(Keyboard[0][4], "Kbd1Key5", KEY('S', XK_s, SDLK_s)));
pComp->Value(mkNamingAdapt(Keyboard[0][5], "Kbd1Key6", KEY('D', XK_d, SDLK_d)));
pComp->Value(mkNamingAdapt(Keyboard[0][6], "Kbd1Key7", fGer ? KEY('Y', XK_y, SDLK_y) : KEY('Z', XK_z, SDLK_z)));
pComp->Value(mkNamingAdapt(Keyboard[0][7], "Kbd1Key8", KEY('X', XK_x, SDLK_x)));
pComp->Value(mkNamingAdapt(Keyboard[0][8], "Kbd1Key9", KEY('C', XK_c, SDLK_c)));
pComp->Value(mkNamingAdapt(Keyboard[0][9], "Kbd1Key10", fGer ? KEY(226, XK_less, SDLK_LESS) : KEY('R', XK_r, SDLK_r)));
pComp->Value(mkNamingAdapt(Keyboard[0][10], "Kbd1Key11", KEY('V', XK_v, SDLK_v)));
pComp->Value(mkNamingAdapt(Keyboard[0][11], "Kbd1Key12", KEY('F', XK_f, SDLK_f)));
pComp->Value(mkNamingAdapt(Keyboard[1][0], "Kbd2Key1", KEY(103, XK_KP_Home, SDLK_KP7)));
pComp->Value(mkNamingAdapt(Keyboard[1][1], "Kbd2Key2", KEY(104, XK_KP_Up, SDLK_KP8)));
pComp->Value(mkNamingAdapt(Keyboard[1][2], "Kbd2Key3", KEY(105, XK_KP_Page_Up, SDLK_KP9)));
pComp->Value(mkNamingAdapt(Keyboard[1][3], "Kbd2Key4", KEY(100, XK_KP_Left, SDLK_KP4)));
pComp->Value(mkNamingAdapt(Keyboard[1][4], "Kbd2Key5", KEY(101, XK_KP_Begin, SDLK_KP5)));
pComp->Value(mkNamingAdapt(Keyboard[1][5], "Kbd2Key6", KEY(102, XK_KP_Right, SDLK_KP6)));
pComp->Value(mkNamingAdapt(Keyboard[1][6], "Kbd2Key7", KEY(97, XK_KP_End, SDLK_KP1)));
pComp->Value(mkNamingAdapt(Keyboard[1][7], "Kbd2Key8", KEY(98, XK_KP_Down, SDLK_KP2)));
pComp->Value(mkNamingAdapt(Keyboard[1][8], "Kbd2Key9", KEY(99, XK_KP_Page_Down, SDLK_KP3)));
pComp->Value(mkNamingAdapt(Keyboard[1][9], "Kbd2Key10", KEY(96, XK_KP_Insert, SDLK_KP0)));
pComp->Value(mkNamingAdapt(Keyboard[1][10], "Kbd2Key11", KEY(110, XK_KP_Delete, SDLK_KP_PERIOD)));
pComp->Value(mkNamingAdapt(Keyboard[1][11], "Kbd2Key12", KEY(107, XK_KP_Add, SDLK_KP_PLUS)));
pComp->Value(mkNamingAdapt(Keyboard[2][0], "Kbd3Key1", KEY('I', XK_i, SDLK_i)));
pComp->Value(mkNamingAdapt(Keyboard[2][1], "Kbd3Key2", KEY('O', XK_o, SDLK_o)));
pComp->Value(mkNamingAdapt(Keyboard[2][2], "Kbd3Key3", KEY('P', XK_p, SDLK_p)));
pComp->Value(mkNamingAdapt(Keyboard[2][3], "Kbd3Key4", KEY('K', XK_k, SDLK_k)));
pComp->Value(mkNamingAdapt(Keyboard[2][4], "Kbd3Key5", KEY('L', XK_l, SDLK_l)));
pComp->Value(mkNamingAdapt(Keyboard[2][5], "Kbd3Key6", fGer ? KEY(192, XK_odiaeresis, SDLK_WORLD_4) : KEY(0xBA, XK_semicolon, SDLK_SEMICOLON)));
pComp->Value(mkNamingAdapt(Keyboard[2][6], "Kbd3Key7", KEY(188, XK_comma, SDLK_COMMA)));
pComp->Value(mkNamingAdapt(Keyboard[2][7], "Kbd3Key8", KEY(190, XK_period, SDLK_PERIOD)));
pComp->Value(mkNamingAdapt(Keyboard[2][8], "Kbd3Key9", fGer ? KEY(189, XK_minus, SDLK_MINUS) : KEY(0xBF, XK_slash, SDLK_SLASH)));
pComp->Value(mkNamingAdapt(Keyboard[2][9], "Kbd3Key10", KEY('M', XK_m, SDLK_m)));
pComp->Value(mkNamingAdapt(Keyboard[2][10], "Kbd3Key11", KEY(222, XK_adiaeresis, SDLK_WORLD_3)));
pComp->Value(mkNamingAdapt(Keyboard[2][11], "Kbd3Key12", KEY(186, XK_udiaeresis, SDLK_WORLD_2)));
pComp->Value(mkNamingAdapt(Keyboard[3][0], "Kbd4Key1", KEY(VK_INSERT, XK_Insert, SDLK_INSERT)));
pComp->Value(mkNamingAdapt(Keyboard[3][1], "Kbd4Key2", KEY(VK_HOME, XK_Home, SDLK_HOME)));
pComp->Value(mkNamingAdapt(Keyboard[3][2], "Kbd4Key3", KEY(VK_PRIOR, XK_Page_Up, SDLK_PAGEUP)));
pComp->Value(mkNamingAdapt(Keyboard[3][3], "Kbd4Key4", KEY(VK_DELETE, XK_Delete, SDLK_DELETE)));
pComp->Value(mkNamingAdapt(Keyboard[3][4], "Kbd4Key5", KEY(VK_UP, XK_Up, SDLK_UP)));
pComp->Value(mkNamingAdapt(Keyboard[3][5], "Kbd4Key6", KEY(VK_NEXT, XK_Page_Down, SDLK_PAGEDOWN)));
pComp->Value(mkNamingAdapt(Keyboard[3][6], "Kbd4Key7", KEY(VK_LEFT, XK_Left, SDLK_LEFT)));
pComp->Value(mkNamingAdapt(Keyboard[3][7], "Kbd4Key8", KEY(VK_DOWN, XK_Down, SDLK_DOWN)));
pComp->Value(mkNamingAdapt(Keyboard[3][8], "Kbd4Key9", KEY(VK_RIGHT, XK_Right, SDLK_RIGHT)));
pComp->Value(mkNamingAdapt(Keyboard[3][9], "Kbd4Key10", KEY(VK_END, XK_End, SDLK_END)));
pComp->Value(mkNamingAdapt(Keyboard[3][10], "Kbd4Key11", KEY(VK_RETURN, XK_Return, SDLK_RETURN)));
pComp->Value(mkNamingAdapt(Keyboard[3][11], "Kbd4Key12", KEY(VK_BACK, XK_BackSpace, SDLK_BACKSPACE)));
2009-05-08 13:28:41 +00:00
if (fKeysOnly) return;
2010-03-28 18:58:01 +00:00
pComp->Value(mkNamingAdapt(MouseAScroll, "MouseAutoScroll", 1));
pComp->Value(mkNamingAdapt(GamepadGuiControl, "GamepadGuiControl", 0, false, true));
2009-05-08 13:28:41 +00:00
#undef KEY
#undef s
#endif //USE_CONSOLE
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
const char *CfgAtTempPath(const char *szFilename)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// safety
if (!pConfig) return NULL;
// get at temp path
return pConfig->AtTempPath(szFilename);
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
C4Config::C4Config()
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
pConfig=this;
Default();
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
C4Config::~C4Config()
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
fConfigLoaded = false;
pConfig=NULL;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4Config::Default()
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// force default values
StdCompilerNull Comp; Comp.Compile(*this);
fConfigLoaded=false;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4Config::Load(bool forceWorkingDirectory, const char *szConfigFile)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
try
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
#ifdef _WIN32
// Windows: Default load from registry, if no explicit config file is specified
if (!szConfigFile)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
StdCompilerConfigRead CfgRead(HKEY_CURRENT_USER, "Software\\" C4CFG_Company "\\" C4ENGINENAME);
CfgRead.Compile(*this);
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
else
#endif
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Nonwindows or explicit config file: Determine filename to load config from
StdStrBuf filename;
if (szConfigFile)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Config filename is specified
filename.Ref(szConfigFile);
// make sure we're at the correct path to load it
if (forceWorkingDirectory) General.DeterminePaths(true);
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
else
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Config filename from home
StdStrBuf home(getenv("HOME"));
if (home) { home += "/"; }
filename.Copy(home);
#ifdef __APPLE__
filename += "Library/Preferences/de.clonk." C4ENGINENICK ".config";
#else
filename += ".clonk/" C4ENGINENICK "/config";
#endif
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Load config file into buf
StdStrBuf buf;
buf.LoadFromFile(filename.getData());
2010-03-28 18:58:01 +00:00
if (buf.isNull())
{
2009-05-08 13:28:41 +00:00
// Config file not present?
#ifdef __linux__
if (!szConfigFile)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
StdStrBuf filename(getenv("HOME"));
if (filename) { filename += "/"; }
filename += ".clonk/" C4ENGINENICK;
CreatePath(filename.getData());
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
#endif
// Buggy StdCompiler crashes when compiling a Null-StdStrBuf
buf.Ref(" ");
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Read config from buffer
StdCompilerINIRead IniRead;
IniRead.setInput(buf);
IniRead.Compile(*this);
}
2010-03-28 18:58:01 +00:00
}
catch (StdCompiler::Exception *pExc)
{
2009-05-08 13:28:41 +00:00
// Configuration file syntax error?
LogF("Error loading configuration: %s"/*LoadResStr("IDS_ERR_CONFREAD") - restbl not yet loaded*/, pExc->Msg.getData());
delete pExc;
return false;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Config postinit
General.DeterminePaths(forceWorkingDirectory);
General.AdoptOldSettings();
#ifdef HAVE_WINSOCK
// Setup WS manually, so c4group doesn't depend on C4NetIO
WSADATA wsadata;
bool fWinSock = !WSAStartup(WINSOCK_VERSION, &wsadata);
#endif
if (SEqual(Network.Nick.getData(), "Unknown"))
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
char LocalName[25+1]; *LocalName = 0;
gethostname(LocalName, 25);
if (*LocalName) Network.Nick.Copy(LocalName);
2010-03-28 18:58:01 +00:00
}
#ifdef HAVE_WINSOCK
if (fWinSock) WSACleanup();
#endif
2009-05-08 13:28:41 +00:00
General.DefaultLanguage();
#if defined USE_GL && !defined USE_DIRECTX
if (Graphics.Engine == GFXENGN_DIRECTX || Graphics.Engine == GFXENGN_DIRECTXS)
Graphics.Engine = GFXENGN_OPENGL;
#endif
// Warning against invalid ports
if (Config.Network.PortTCP>0 && Config.Network.PortTCP == Config.Network.PortRefServer)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
Log("Warning: Network TCP port and reference server port both set to same value - increasing reference server port!");
++Config.Network.PortRefServer;
if (Config.Network.PortRefServer>=65536) Config.Network.PortRefServer = C4NetStdPortRefServer;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
if (Config.Network.PortUDP>0 && Config.Network.PortUDP == Config.Network.PortDiscovery)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
Log("Warning: Network UDP port and LAN game discovery port both set to same value - increasing discovery port!");
++Config.Network.PortDiscovery;
if (Config.Network.PortDiscovery>=65536) Config.Network.PortDiscovery = C4NetStdPortDiscovery;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Empty nick already defaults to GetRegistrationData("Nick") or
// Network.LocalName at relevant places.
/*if (!Network.Nick.getLength())
2010-03-28 18:58:01 +00:00
Network.Nick.Copy(Network.LocalName); // assuming that LocalName will always contain some useful value*/
2009-05-08 13:28:41 +00:00
fConfigLoaded = true;
if (szConfigFile) ConfigFilename.Copy(szConfigFile); else ConfigFilename.Clear();
return true;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4Config::Save()
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
try
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
#ifdef _WIN32
if (!ConfigFilename.getLength())
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Windows: Default save to registry, if it wasn't loaded from file
StdCompilerConfigWrite CfgWrite(HKEY_CURRENT_USER, "Software\\" C4CFG_Company "\\" C4ENGINENAME);
CfgWrite.Decompile(*this);
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
else
#endif
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
StdStrBuf filename;
if (ConfigFilename.getLength())
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
filename.Ref(ConfigFilename);
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
else
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
filename.Copy(getenv("HOME"));
if (filename) { filename += "/"; }
#ifdef __APPLE__
filename += "Library/Preferences/de.clonk." C4ENGINENICK ".config";
#else
filename += ".clonk/" C4ENGINENICK "/config";
#endif
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
StdCompilerINIWrite IniWrite;
IniWrite.Decompile(*this);
IniWrite.getOutput().SaveToFile(filename.getData());
}
2010-03-28 18:58:01 +00:00
}
catch (StdCompiler::Exception *pExc)
{
2009-05-08 13:28:41 +00:00
LogF(LoadResStr("IDS_ERR_CONFSAVE"), pExc->Msg.getData());
delete pExc;
return false;
2009-05-08 13:28:41 +00:00
}
2010-03-28 18:58:01 +00:00
return true;
}
2009-05-08 13:28:41 +00:00
void C4ConfigGeneral::DeterminePaths(bool forceWorkingDirectory)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
#ifdef _WIN32
// Exe path
if (GetModuleFileName(NULL,ExePath,CFG_MaxString))
2010-03-28 18:58:01 +00:00
{ TruncatePath(ExePath); AppendBackslash(ExePath); }
2009-05-08 13:28:41 +00:00
// Temp path
GetTempPath(CFG_MaxString,TempPath);
if (TempPath[0]) AppendBackslash(TempPath);
#elif defined(__linux__)
GetParentPath(Application.Location, ExePath);
AppendBackslash(ExePath);
const char * t = getenv("TMPDIR");
if (t)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
SCopy(t, TempPath, sizeof(TempPath)-2);
AppendBackslash(TempPath);
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
else
SCopy("/tmp/", TempPath);
#else
2010-03-28 18:58:01 +00:00
// Mac: Just use the working directory as ExePath.
2009-05-08 13:28:41 +00:00
SCopy(GetWorkingDirectory(), ExePath);
2010-03-28 18:58:01 +00:00
AppendBackslash(ExePath);
2009-05-08 13:28:41 +00:00
SCopy("/tmp/", TempPath);
#endif
// Force working directory to exe path if desired
#ifndef _DEBUG
2009-05-08 13:28:41 +00:00
if (forceWorkingDirectory)
SetWorkingDirectory(ExePath);
#endif
2009-05-08 13:28:41 +00:00
// Find system-wide data path
#if defined(_WIN32) || defined(__APPLE__)
// Use workdir; in release builds, this is the exe dir
SCopy(GetWorkingDirectory(),SystemDataPath);
AppendBackslash(SystemDataPath);
2009-05-08 13:28:41 +00:00
#elif defined(__linux__)
// FIXME: Where to put this?
SCopy(ExePath,SystemDataPath);
#endif
// Find user-specific data path
if (ConfigUserPath[0])
SCopy(ConfigUserPath, UserDataPath);
else
#if defined(_WIN32)
SCopy("%APPDATA%\\" C4ENGINENAME, UserDataPath);
#elif defined(__linux__)
2010-03-28 18:58:01 +00:00
SCopy("$HOME/.clonk/" C4ENGINENICK, UserDataPath);
2009-05-08 13:28:41 +00:00
#elif defined(__APPLE__)
2010-03-28 18:58:01 +00:00
SCopy("$HOME/Library/Application Support/" C4ENGINENAME, UserDataPath);
2009-05-08 13:28:41 +00:00
#endif
C4Config::ExpandEnvironmentVariables(UserDataPath, CFG_MaxString);
AppendBackslash(UserDataPath);
// Screenshot path
SCopy(UserDataPath, ScreenshotPath, CFG_MaxString-1);
2010-01-25 04:00:59 +00:00
if (ScreenshotFolder.getLength()+std::strlen(ScreenshotPath)+1<=CFG_MaxString)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
SAppend(ScreenshotFolder.getData(), ScreenshotPath);
AppendBackslash(ScreenshotPath);
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Create user path if it doesn't already exist
CreatePath(UserDataPath);
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
static bool GrabOldPlayerFile(const char *fn)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
if (FileExists(Config.AtUserDataPath(GetFilename(fn))))
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// player already exists in user dir, skip
return true;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
if (!MoveItem(fn, Config.AtUserDataPath(GetFilename(fn))))
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// possibly unpacked
if (DirectoryExists(fn))
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
if (!C4Group_PackDirectoryTo(fn, Config.AtUserDataPath(GetFilename(fn))))
return true; // ignore errors
}
}
2010-03-28 18:58:01 +00:00
return true;
}
2009-05-08 13:28:41 +00:00
void C4ConfigGeneral::AdoptOldSettings()
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Copy over old player data
if (*Adopt.PlayerPath)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
ForEachFile(FormatString("%s/%s", Config.AtExePath(Adopt.PlayerPath), C4CFN_PlayerFiles).getData(), &GrabOldPlayerFile);
*Adopt.PlayerPath = '\0';
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
else if (!ItemIdentical(Config.General.ExePath, Config.General.UserDataPath))
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
ForEachFile(Config.AtExePath(C4CFN_PlayerFiles), &GrabOldPlayerFile);
}
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4ConfigGeneral::ClearAdditionalDataPaths()
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
for (PathList::iterator it = AdditionalDataPaths.begin(); it != AdditionalDataPaths.end(); ++it)
delete[] *it;
AdditionalDataPaths.clear();
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4ConfigGeneral::AddAdditionalDataPath(const char *szPath)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
char *clone = new char[SLen(szPath)+1];
SCopy(szPath,clone);
AdditionalDataPaths.push_back(clone);
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
char AtPathFilename[_MAX_PATH+1];
const char* C4Config::AtExePath(const char *szFilename)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
SCopy(General.ExePath,AtPathFilename,_MAX_PATH);
SAppend(szFilename,AtPathFilename,_MAX_PATH);
return AtPathFilename;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
const char* C4Config::AtUserDataPath(const char *szFilename)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
SCopy(General.UserDataPath, AtPathFilename, _MAX_PATH);
SAppend(szFilename, AtPathFilename, _MAX_PATH);
return AtPathFilename;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
const char* C4Config::AtSystemDataPath(const char *szFilename)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
SCopy(General.SystemDataPath, AtPathFilename, _MAX_PATH);
SAppend(szFilename, AtPathFilename, _MAX_PATH);
return AtPathFilename;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
const char* C4Config::AtTempPath(const char *szFilename)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
SCopy(General.TempPath,AtPathFilename,_MAX_PATH);
SAppend(szFilename,AtPathFilename,_MAX_PATH);
return AtPathFilename;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
const char* C4Config::AtNetworkPath(const char *szFilename)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
SCopy(General.UserDataPath,AtPathFilename,_MAX_PATH);
SAppend(Network.WorkPath,AtPathFilename,_MAX_PATH);
SAppend(szFilename,AtPathFilename,_MAX_PATH);
return AtPathFilename;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
const char *C4Config::AtScreenshotPath(const char *szFilename)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
int len;
SCopy(General.ScreenshotPath,AtPathFilename,_MAX_PATH);
2010-03-28 18:58:01 +00:00
if ((len = SLen(AtPathFilename)))
if (AtPathFilename[len-1] == DirectorySeparator)
2009-05-08 13:28:41 +00:00
AtPathFilename[len-1] = '\0';
if (!CreatePath(AtPathFilename))
2009-05-08 13:28:41 +00:00
{
SCopy(General.ExePath, General.ScreenshotPath, CFG_MaxString-1);
SCopy(General.ScreenshotPath,AtPathFilename,_MAX_PATH);
}
else
AppendBackslash(AtPathFilename);
SAppend(szFilename,AtPathFilename,_MAX_PATH);
return AtPathFilename;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4ConfigGeneral::CreateSaveFolder(const char *strDirectory, const char *strLanguageTitle)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Create directory if needed
if (!CreatePath(strDirectory))
return false;
2009-05-08 13:28:41 +00:00
// Create title component if needed
char lang[3]; SCopy(Config.General.Language, lang, 2);
StdStrBuf strTitleFile; strTitleFile.Format("%s%c%s", strDirectory, DirectorySeparator, C4CFN_WriteTitle);
StdStrBuf strTitleData; strTitleData.Format("%s:%s", lang, strLanguageTitle);
CStdFile hFile;
if (!FileExists(strTitleFile.getData()))
if (!hFile.Create(strTitleFile.getData()) || !hFile.WriteString(strTitleData.getData()) || !hFile.Close())
return false;
2009-05-08 13:28:41 +00:00
// Save folder seems okay
return true;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
const char* C4ConfigNetwork::GetLeagueServerAddress()
{
// Alternate (configurable) league server
if (UseAlternateServer)
return AlternateServerAddress;
// Standard (hardcoded) official league server
else
2010-02-08 21:33:21 +00:00
return "boom.openclonk.org:80/server/";
2009-05-08 13:28:41 +00:00
}
void C4ConfigNetwork::CheckPortsForCollisions()
{
// check for port collisions
2010-03-28 18:58:01 +00:00
if (PortTCP != -1 && PortTCP == PortRefServer)
{
LogSilentF("Network: TCP Port collision, setting defaults");
PortTCP = C4NetStdPortTCP;
PortRefServer = C4NetStdPortRefServer;
}
2010-03-28 18:58:01 +00:00
if (PortUDP != -1 && PortUDP == PortDiscovery)
{
LogSilentF("Network: UDP Port collision, setting defaults");
PortUDP = C4NetStdPortUDP;
PortDiscovery = C4NetStdPortDiscovery;
}
}
2009-05-08 13:28:41 +00:00
void C4ConfigControls::ResetKeys()
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
StdCompilerNull Comp; Comp.Compile(mkParAdapt(*this, true));
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
const char* C4Config::AtDataReadPath(const char *szFilename, bool fPreferWorkdir)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
if (IsGlobalPath(szFilename)) return szFilename;
StdCopyStrBuf sfn(szFilename);
do
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
const char *path = AtDataReadPathCore(sfn.getData(), fPreferWorkdir);
if (path)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
if (path != AtPathFilename) SCopy(path,AtPathFilename);
AtPathFilename[_MAX_PATH] = '\0';
AppendBackslash(AtPathFilename);
SAppend(szFilename,AtPathFilename,_MAX_PATH);
return AtPathFilename;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
}
2010-03-28 18:58:01 +00:00
while (TruncatePath(sfn.getMData()));
return szFilename;
}
2009-05-08 13:28:41 +00:00
const char* C4Config::AtDataReadPathCore(const char *szFilename, bool fPreferWorkdir)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
if (fPreferWorkdir && FileExists(szFilename))
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
SCopy(GetWorkingDirectory(),AtPathFilename,_MAX_PATH-1);
return AtPathFilename;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// Check extra data paths
for (C4ConfigGeneral::PathList::iterator it = General.AdditionalDataPaths.begin();
2010-03-28 18:58:01 +00:00
it != General.AdditionalDataPaths.end();
++it)
{
2009-05-08 13:28:41 +00:00
SCopy(*it, AtPathFilename, _MAX_PATH-1);
AppendBackslash(AtPathFilename);
SAppend(szFilename,AtPathFilename,_MAX_PATH);
if (FileExists(AtPathFilename))
return *it;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
if (FileExists(AtUserDataPath(szFilename))) return General.UserDataPath;
if (FileExists(AtSystemDataPath(szFilename))) return General.SystemDataPath;
if (!fPreferWorkdir && FileExists(szFilename))
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
SCopy(GetWorkingDirectory(),AtPathFilename,_MAX_PATH-1);
return AtPathFilename;
}
2010-03-28 18:58:01 +00:00
return NULL;
}
2009-05-08 13:28:41 +00:00
const char* C4Config::AtUserDataRelativePath(const char *szFilename)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Specified file is located in UserDataPath: return relative path
return GetRelativePathS(szFilename, General.UserDataPath);
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
const char* C4Config::AtSystemDataRelativePath(const char *szFilename)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Specified file is located in SystemDataPath: return relative path
return GetRelativePathS(szFilename, General.SystemDataPath);
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
const char* C4Config::AtRelativePath(const char *szFilename)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
const char *szPath = GetRelativePathS(szFilename, General.UserDataPath);
if (szPath == szFilename)
return GetRelativePathS(szFilename, General.SystemDataPath);
return szPath;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
void C4Config::ForceRelativePath(StdStrBuf *sFilename)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
assert(sFilename);
// Specified file is located in SystemDataPath?
const char *szRelative = GetRelativePathS(sFilename->getData(), General.SystemDataPath);
if (szRelative != sFilename->getData())
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// return relative path
StdStrBuf sTemp; sTemp.Copy(szRelative);
2009-11-25 18:38:54 +00:00
sFilename->Take(std::move(sTemp));
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
else
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// not in ExePath: Is it a global path?
if (IsGlobalPath(sFilename->getData()))
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// then shorten it (e.g. C:\Temp\Missions.c4f\Goldmine.c4s to Missions.c4f\Goldmine.c4s)
StdStrBuf sTemp; sTemp.Copy(GetC4Filename(sFilename->getData()));
2009-11-25 18:38:54 +00:00
sFilename->Take(std::move(sTemp));
2009-05-08 13:28:41 +00:00
}
}
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2010-03-28 18:58:01 +00:00
namespace
{
2009-05-08 13:28:41 +00:00
}
void C4ConfigGeneral::DefaultLanguage()
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// No language defined: default to German or English by system language
if (!Language[0])
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
if (isGermanSystem())
SCopy("DE - Deutsch", Language);
else
SCopy("US - English", Language);
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
// No fallback sequence defined: use primary language list
if (!LanguageEx[0])
GetLanguageSequence(Language, LanguageEx);
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4Config::Registered()
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
// Dummy function: to be overloaded in C4Config
return true;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4Config::Init()
2010-03-28 18:58:01 +00:00
{
return true;
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
const char* C4Config::GetSubkeyPath(const char *strSubkey)
{
static char key[1024 + 1];
#ifdef _WIN32
sprintf(key, "Software\\%s\\%s\\%s", C4CFG_Company, C4ENGINENAME, strSubkey);
#else
sprintf(key, "%s", strSubkey);
#endif
return key;
}
int C4ConfigGeneral::GetLanguageSequence(const char *strSource, char *strTarget)
{
// Copy a condensed list of language codes from the source list to the target string,
// skipping any whitespace or long language descriptions. Language sequences are
// comma separated.
int iCount = 0;
char strLang[2 + 1];
for (int i = 0; SCopySegment(strSource, i, strLang, ',', 2, true); i++)
if (strLang[0])
{
if (strTarget[0]) SAppendChar(',', strTarget);
SAppend(strLang, strTarget);
iCount++;
}
return iCount;
}
void C4ConfigStartup::CompileFunc(StdCompiler *pComp)
2010-03-28 18:58:01 +00:00
{
pComp->Value(mkNamingAdapt(HideMsgGfxEngineChange, "HideMsgGfxEngineChange", 0));
pComp->Value(mkNamingAdapt(HideMsgGfxBitDepthChange, "HideMsgGfxBitDepthChange", 0));
pComp->Value(mkNamingAdapt(HideMsgMMTimerChange, "HideMsgMMTimerChange", 0));
pComp->Value(mkNamingAdapt(HideMsgStartDedicated, "HideMsgStartDedicated", 0));
pComp->Value(mkNamingAdapt(HideMsgPlrTakeOver, "HideMsgPlrTakeOver", 0));
pComp->Value(mkNamingAdapt(HideMsgPlrNoTakeOver, "HideMsgPlrNoTakeOver", 0));
pComp->Value(mkNamingAdapt(HideMsgNoOfficialLeague, "HideMsgNoOfficialLeague", 0));
pComp->Value(mkNamingAdapt(HideMsgIRCDangerous, "HideMsgIRCDangerous", 0));
pComp->Value(mkNamingAdapt(NoSplash, "NoSplash", 1));
pComp->Value(mkNamingAdapt(AlphabeticalSorting, "AlphabeticalSorting", 0));
pComp->Value(mkNamingAdapt(LastPortraitFolderIdx, "LastPortraitFolderIdx", 0));
}
2009-05-08 13:28:41 +00:00
void C4Config::CompileFunc(StdCompiler *pComp)
2010-03-28 18:58:01 +00:00
{
pComp->Value(mkNamingAdapt(General, "General" ));
pComp->Value(mkNamingAdapt(Controls, "Controls" ));
2009-05-08 13:28:41 +00:00
for (int i=0; i<C4ConfigMaxGamepads; ++i)
2010-03-28 18:58:01 +00:00
pComp->Value(mkNamingAdapt(Gamepads[i], FormatString("Gamepad%d", i).getData()));
pComp->Value(mkNamingAdapt(Graphics, "Graphics" ));
pComp->Value(mkNamingAdapt(Sound, "Sound" ));
pComp->Value(mkNamingAdapt(Network, "Network" ));
pComp->Value(mkNamingAdapt(Lobby, "Lobby" ));
pComp->Value(mkNamingAdapt(IRC, "IRC" ));
pComp->Value(mkNamingAdapt(Developer, "Developer" ));
2009-05-08 13:28:41 +00:00
#ifdef _WIN32
2010-03-28 18:58:01 +00:00
pComp->Value(mkNamingAdapt(Explorer, "Explorer" ));
2009-05-08 13:28:41 +00:00
#endif
2010-03-28 18:58:01 +00:00
pComp->Value(mkNamingAdapt(Startup, "Startup" ));
pComp->Value(mkNamingAdapt(Security, "Security" ));
}
2009-05-08 13:28:41 +00:00
bool C4Config::AddModule(const char *szPath, char *szModules)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
return SAddModule(szModules,szPath);
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4Config::IsModule(const char *szPath, char *szModules)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
return SIsModule(szModules,szPath);
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
bool C4Config::RemoveModule(const char *szPath, char *szModules)
2010-03-28 18:58:01 +00:00
{
2009-05-08 13:28:41 +00:00
return SRemoveModule(szModules,szPath);
2010-03-28 18:58:01 +00:00
}
2009-05-08 13:28:41 +00:00
2010-01-25 04:00:59 +00:00
void C4Config::ExpandEnvironmentVariables(char *strPath, size_t iMaxLen)
2009-05-08 13:28:41 +00:00
{
#ifdef _WIN32
char buf[_MAX_PATH + 1];
ExpandEnvironmentStrings(strPath, buf, _MAX_PATH);
SCopy(buf, strPath, iMaxLen);
#else // __linux__ or __APPLE___
StdStrBuf home(getenv("HOME"));
char* rest;
2010-01-25 04:00:59 +00:00
if (home && (rest = const_cast<char *>(SSearch(strPath, "$HOME"))) && (std::strlen(strPath) - 5 + home.getLength() <= iMaxLen))
2009-05-08 13:28:41 +00:00
{
// String replace... there might be a more elegant way to do this.
memmove(rest + home.getLength() - SLen("$HOME"), rest, SLen(rest) + 1);
strncpy(rest - SLen("$HOME"), home.getData(), home.getLength());
}
#endif
}