| 1 | /* |
|---|
| 2 | ================================================================================= |
|---|
| 3 | This file is part of Cafu, the open-source game engine and graphics engine |
|---|
| 4 | for multiplayer, cross-platform, real-time 3D action. |
|---|
| 5 | Copyright (C) 2002-2012 Carsten Fuchs Software. |
|---|
| 6 | |
|---|
| 7 | Cafu is free software: you can redistribute it and/or modify it under the terms |
|---|
| 8 | of the GNU General Public License as published by the Free Software Foundation, |
|---|
| 9 | either version 3 of the License, or (at your option) any later version. |
|---|
| 10 | |
|---|
| 11 | Cafu is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
|---|
| 12 | without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
|---|
| 13 | PURPOSE. See the GNU General Public License for more details. |
|---|
| 14 | |
|---|
| 15 | You should have received a copy of the GNU General Public License |
|---|
| 16 | along with Cafu. If not, see <http://www.gnu.org/licenses/>. |
|---|
| 17 | |
|---|
| 18 | For support and more information about Cafu, visit us at <http://www.cafu.de>. |
|---|
| 19 | ================================================================================= |
|---|
| 20 | */ |
|---|
| 21 | |
|---|
| 22 | #include "AppCafu.hpp" |
|---|
| 23 | #include "MainFrame.hpp" |
|---|
| 24 | |
|---|
| 25 | #include "ClipSys/CollisionModelMan_impl.hpp" |
|---|
| 26 | #include "ConsoleCommands/ConsoleInterpreterImpl.hpp" |
|---|
| 27 | #include "ConsoleCommands/ConsoleComposite.hpp" |
|---|
| 28 | #include "ConsoleCommands/ConsoleFile.hpp" |
|---|
| 29 | #include "ConsoleCommands/ConsoleStdout.hpp" |
|---|
| 30 | #include "ConsoleCommands/ConsoleStringBuffer.hpp" |
|---|
| 31 | #include "ConsoleCommands/ConVar.hpp" |
|---|
| 32 | #include "ConsoleCommands/ConFunc.hpp" |
|---|
| 33 | #include "FileSys/FileManImpl.hpp" |
|---|
| 34 | #include "GuiSys/GuiMan.hpp" |
|---|
| 35 | #include "GuiSys/Window.hpp" |
|---|
| 36 | #include "MaterialSystem/MaterialManagerImpl.hpp" |
|---|
| 37 | #include "Network/Network.hpp" |
|---|
| 38 | #include "SoundSystem/SoundShaderManagerImpl.hpp" |
|---|
| 39 | #include "SoundSystem/SoundSys.hpp" |
|---|
| 40 | #include "TypeSys.hpp" |
|---|
| 41 | #include "../Games/Game.hpp" |
|---|
| 42 | |
|---|
| 43 | #include "wx/cmdline.h" |
|---|
| 44 | #include "wx/filename.h" |
|---|
| 45 | #include "wx/msgdlg.h" |
|---|
| 46 | #include "wx/stdpaths.h" |
|---|
| 47 | |
|---|
| 48 | |
|---|
| 49 | // For each interface that is globally available to the application, |
|---|
| 50 | // provide a definition for the pointer instance and have it point to an implementation. |
|---|
| 51 | static cf::CompositeConsoleT s_CompositeConsole; |
|---|
| 52 | cf::ConsoleI* Console=&s_CompositeConsole; |
|---|
| 53 | |
|---|
| 54 | static cf::FileSys::FileManImplT s_FileManImpl; |
|---|
| 55 | cf::FileSys::FileManI* cf::FileSys::FileMan=&s_FileManImpl; |
|---|
| 56 | |
|---|
| 57 | static cf::ClipSys::CollModelManImplT s_CCM; |
|---|
| 58 | cf::ClipSys::CollModelManI* cf::ClipSys::CollModelMan=&s_CCM; |
|---|
| 59 | |
|---|
| 60 | static ConsoleInterpreterImplT s_ConInterpreterImpl; |
|---|
| 61 | ConsoleInterpreterI* ConsoleInterpreter=&s_ConInterpreterImpl; // TODO: Put it into a proper namespace. |
|---|
| 62 | |
|---|
| 63 | static MaterialManagerImplT s_MaterialManagerImpl; |
|---|
| 64 | MaterialManagerI* MaterialManager=&s_MaterialManagerImpl; // TODO: Put it into a proper namespace. |
|---|
| 65 | |
|---|
| 66 | static SoundShaderManagerImplT s_SoundShaderManagerImpl; |
|---|
| 67 | SoundShaderManagerI* SoundShaderManager=&s_SoundShaderManagerImpl; // TODO: Put it into a proper namespace. |
|---|
| 68 | |
|---|
| 69 | // static WinSockT WinSock; // This unfortunately can throw. |
|---|
| 70 | WinSockT* g_WinSock=NULL; |
|---|
| 71 | |
|---|
| 72 | |
|---|
| 73 | // Implementations for these interfaces are obtained later at run-time. |
|---|
| 74 | // MatSys::RendererI* MatSys::Renderer=NULL; // TODO: Don't have it predefine the global pointer instance. |
|---|
| 75 | // MatSys::TextureMapManagerI* MatSys::TextureMapManager=NULL; // TODO: Don't have it predefine the global pointer instance. |
|---|
| 76 | SoundSysI* SoundSystem=NULL; |
|---|
| 77 | cf::GuiSys::GuiManI* cf::GuiSys::GuiMan=NULL; |
|---|
| 78 | cf::GameSys::GameI* cf::GameSys::Game=NULL; |
|---|
| 79 | |
|---|
| 80 | |
|---|
| 81 | static bool CompareModes(const wxVideoMode& Mode1, const wxVideoMode& Mode2) |
|---|
| 82 | { |
|---|
| 83 | // Compare the widths. |
|---|
| 84 | if (Mode1.w < Mode2.w) return true; |
|---|
| 85 | if (Mode1.w > Mode2.w) return false; |
|---|
| 86 | |
|---|
| 87 | // The widths are equal, now compare the heights. |
|---|
| 88 | if (Mode1.h < Mode2.h) return true; |
|---|
| 89 | if (Mode1.h > Mode2.h) return false; |
|---|
| 90 | |
|---|
| 91 | // The widths and heights are equal, now compare the BPP. |
|---|
| 92 | if (Mode1.bpp < Mode2.bpp) return true; |
|---|
| 93 | if (Mode1.bpp > Mode2.bpp) return false; |
|---|
| 94 | |
|---|
| 95 | // The widths, heights and BPPs are equal, now compare the refresh rate. |
|---|
| 96 | if (Mode1.refresh < Mode2.refresh) return true; |
|---|
| 97 | if (Mode1.refresh > Mode2.refresh) return false; |
|---|
| 98 | |
|---|
| 99 | // The modes are equal. |
|---|
| 100 | return false; |
|---|
| 101 | } |
|---|
| 102 | |
|---|
| 103 | |
|---|
| 104 | static std::string GetVideoModes() |
|---|
| 105 | { |
|---|
| 106 | ArrayT<wxVideoMode> Modes; |
|---|
| 107 | |
|---|
| 108 | { |
|---|
| 109 | wxDisplay Display; |
|---|
| 110 | wxArrayVideoModes wxModes=Display.GetModes(); |
|---|
| 111 | |
|---|
| 112 | for (size_t ModeNr=0; ModeNr<wxModes.GetCount(); ModeNr++) |
|---|
| 113 | Modes.PushBack(wxModes[ModeNr]); |
|---|
| 114 | } |
|---|
| 115 | |
|---|
| 116 | // Remove modes according to certain filter criteria, cutting excessively long mode lists. |
|---|
| 117 | for (unsigned long ModeNr=0; ModeNr<Modes.Size(); ModeNr++) |
|---|
| 118 | { |
|---|
| 119 | const wxVideoMode& Mode=Modes[ModeNr]; |
|---|
| 120 | |
|---|
| 121 | if (Mode.w==0 || Mode.h==0 || Mode.bpp<15) |
|---|
| 122 | { |
|---|
| 123 | Modes.RemoveAt(ModeNr); |
|---|
| 124 | ModeNr--; |
|---|
| 125 | continue; |
|---|
| 126 | } |
|---|
| 127 | |
|---|
| 128 | for (unsigned long OtherNr=0; OtherNr<Modes.Size(); OtherNr++) |
|---|
| 129 | { |
|---|
| 130 | if (OtherNr==ModeNr) continue; |
|---|
| 131 | |
|---|
| 132 | const wxVideoMode& Other=Modes[OtherNr]; |
|---|
| 133 | |
|---|
| 134 | if (Mode==Other || (Mode.w==Other.w && Mode.h==Other.h && Mode.bpp<32 && Mode.bpp<Other.bpp)) |
|---|
| 135 | { |
|---|
| 136 | Modes.RemoveAt(ModeNr); |
|---|
| 137 | ModeNr--; |
|---|
| 138 | break; |
|---|
| 139 | } |
|---|
| 140 | } |
|---|
| 141 | |
|---|
| 142 | // Note that the above loop is written in a way that allows no additional statements here. |
|---|
| 143 | } |
|---|
| 144 | |
|---|
| 145 | // Sort the modes by increasing width, height, BPP and refresh rate. |
|---|
| 146 | Modes.QuickSort(CompareModes); |
|---|
| 147 | |
|---|
| 148 | // Build the result string. |
|---|
| 149 | wxString List; |
|---|
| 150 | |
|---|
| 151 | for (unsigned long ModeNr=0; ModeNr<Modes.Size(); ModeNr++) |
|---|
| 152 | { |
|---|
| 153 | const wxVideoMode& Mode=Modes[ModeNr]; |
|---|
| 154 | |
|---|
| 155 | List+=wxString::Format("%i x %i, %i bpp, %i Hz\n", Mode.w, Mode.h, Mode.bpp, Mode.refresh); |
|---|
| 156 | } |
|---|
| 157 | |
|---|
| 158 | return List.ToStdString(); |
|---|
| 159 | } |
|---|
| 160 | |
|---|
| 161 | |
|---|
| 162 | IMPLEMENT_APP(AppCafuT) |
|---|
| 163 | |
|---|
| 164 | |
|---|
| 165 | AppCafuT::AppCafuT() |
|---|
| 166 | : wxApp(), |
|---|
| 167 | m_Locale(NULL), |
|---|
| 168 | m_ConBuffer(new cf::ConsoleStringBufferT()), |
|---|
| 169 | m_ConFile(NULL), |
|---|
| 170 | m_IsCustomVideoMode(false), |
|---|
| 171 | m_MainFrame(NULL) |
|---|
| 172 | { |
|---|
| 173 | s_CompositeConsole.Attach(m_ConBuffer); |
|---|
| 174 | |
|---|
| 175 | #ifdef __WXGTK__ |
|---|
| 176 | { |
|---|
| 177 | static cf::ConsoleStdoutT s_ConStdout; |
|---|
| 178 | s_CompositeConsole.Attach(&s_ConStdout); |
|---|
| 179 | } |
|---|
| 180 | #endif |
|---|
| 181 | |
|---|
| 182 | // All global convars and confuncs have registered themselves in linked lists. |
|---|
| 183 | // Register them with the console interpreter now. |
|---|
| 184 | ConFuncT::RegisterStaticList(); |
|---|
| 185 | ConVarT ::RegisterStaticList(); |
|---|
| 186 | |
|---|
| 187 | // The one-time init of the GuiSys' windows type info manager. |
|---|
| 188 | cf::GuiSys::GetWindowTIM().Init(); |
|---|
| 189 | |
|---|
| 190 | SetAppName("Cafu"); |
|---|
| 191 | SetAppDisplayName("Cafu Engine"); |
|---|
| 192 | SetVendorName("Carsten Fuchs Software"); |
|---|
| 193 | wxStandardPaths::Get().UseAppInfo(wxStandardPaths::AppInfo_VendorName | wxStandardPaths::AppInfo_AppName); |
|---|
| 194 | |
|---|
| 195 | Console->Print("Cafu Engine, "__DATE__"\n"); |
|---|
| 196 | } |
|---|
| 197 | |
|---|
| 198 | |
|---|
| 199 | AppCafuT::~AppCafuT() |
|---|
| 200 | { |
|---|
| 201 | s_CompositeConsole.Detach(m_ConFile); |
|---|
| 202 | delete m_ConFile; |
|---|
| 203 | |
|---|
| 204 | s_CompositeConsole.Detach(m_ConBuffer); |
|---|
| 205 | delete m_ConBuffer; |
|---|
| 206 | } |
|---|
| 207 | |
|---|
| 208 | |
|---|
| 209 | cf::CompositeConsoleT& AppCafuT::GetConComposite() const |
|---|
| 210 | { |
|---|
| 211 | return s_CompositeConsole; |
|---|
| 212 | } |
|---|
| 213 | |
|---|
| 214 | |
|---|
| 215 | bool AppCafuT::OnInit() |
|---|
| 216 | { |
|---|
| 217 | const wxString UserDataDir=wxStandardPaths::Get().GetUserDataDir(); |
|---|
| 218 | |
|---|
| 219 | if (!wxFileName::Mkdir(UserDataDir, 0777, wxPATH_MKDIR_FULL)) |
|---|
| 220 | wxMessageBox(wxString("Config file storage path \n")+UserDataDir+"\n doesn't exist, and it could not be created, either.", "Warning!"); |
|---|
| 221 | |
|---|
| 222 | // Undo the wx locale initialization, as we want to be sure to use the same (default) locale "C" always and everywhere. |
|---|
| 223 | // Using other locales introduces a lot of subtle errors. E.g. reading floating point numbers from anywhere |
|---|
| 224 | // (like map files!) fails because e.g. "1.4" is no proper floating point string in the German locale (but "1,4" is). |
|---|
| 225 | // setlocale(LC_ALL, "C"); // This alone is not enough, see http://trac.wxwidgets.org/ticket/12970 for details. |
|---|
| 226 | for (int LangNr=wxLANGUAGE_ENGLISH; LangNr<=wxLANGUAGE_ENGLISH_ZIMBABWE; LangNr++) |
|---|
| 227 | { |
|---|
| 228 | if (wxLocale::IsAvailable(LangNr)) |
|---|
| 229 | { |
|---|
| 230 | m_Locale=new wxLocale(LangNr, wxLOCALE_DONT_LOAD_DEFAULT); |
|---|
| 231 | |
|---|
| 232 | wxLogDebug("Program locale set to %s (%s, %s).", m_Locale->GetName(), m_Locale->GetCanonicalName(), m_Locale->GetLocale()); |
|---|
| 233 | break; |
|---|
| 234 | } |
|---|
| 235 | } |
|---|
| 236 | |
|---|
| 237 | if (!m_Locale) |
|---|
| 238 | { |
|---|
| 239 | // If the above for some reason didn't work, set at least the CRT to the "C" locale. |
|---|
| 240 | setlocale(LC_ALL, "C"); |
|---|
| 241 | wxLogDebug("Program locale set to \"C\"."); |
|---|
| 242 | } |
|---|
| 243 | |
|---|
| 244 | ConsoleInterpreter->RunCommand("dofile('config.lua');"); |
|---|
| 245 | |
|---|
| 246 | // Parse the command line. |
|---|
| 247 | if (!wxApp::OnInit()) { OnExit(); return false; } |
|---|
| 248 | |
|---|
| 249 | // Insert legacy dialog here... |
|---|
| 250 | |
|---|
| 251 | try |
|---|
| 252 | { |
|---|
| 253 | g_WinSock=new WinSockT; |
|---|
| 254 | } |
|---|
| 255 | catch (const WinSockT::InitFailure& /*E*/) { wxMessageBox("Unable to initialize WinSock 2.0." ); OnExit(); return false; } |
|---|
| 256 | catch (const WinSockT::BadVersion& /*E*/) { wxMessageBox("WinSock version 2.0 not supported."); OnExit(); return false; } |
|---|
| 257 | |
|---|
| 258 | cf::FileSys::FileMan->MountFileSystem(cf::FileSys::FS_TYPE_LOCAL_PATH, "./", ""); |
|---|
| 259 | // cf::FileSys::FileMan->MountFileSystem(cf::FileSys::FS_TYPE_LOCAL_PATH, "Games/DeathMatch/", ""); |
|---|
| 260 | cf::FileSys::FileMan->MountFileSystem(cf::FileSys::FS_TYPE_ZIP_ARCHIVE, "Games/DeathMatch/Textures/TechDemo.zip", "Games/DeathMatch/Textures/TechDemo/", "Ca3DE"); |
|---|
| 261 | cf::FileSys::FileMan->MountFileSystem(cf::FileSys::FS_TYPE_ZIP_ARCHIVE, "Games/DeathMatch/Textures/SkyDomes.zip", "Games/DeathMatch/Textures/SkyDomes/", "Ca3DE"); |
|---|
| 262 | |
|---|
| 263 | extern ConVarT Options_ServerGameName; |
|---|
| 264 | const std::string& GameName=Options_ServerGameName.GetValueString(); |
|---|
| 265 | |
|---|
| 266 | MaterialManager->RegisterMaterialScriptsInDir("Games/"+GameName+"/Materials", "Games/"+GameName+"/"); |
|---|
| 267 | SoundShaderManager->RegisterSoundShaderScriptsInDir("Games/"+GameName+"/SoundShader", "Games/"+GameName+"/"); |
|---|
| 268 | |
|---|
| 269 | |
|---|
| 270 | // The console variable VideoModes is initialized here, because under wxGTK, using wxDisplay requires |
|---|
| 271 | // that the wxWidgets library (and thus GTK) is initialized first. |
|---|
| 272 | // Note that the format of the VideoModes string is fixed - it is parsed by the Main Menu GUI in order to populate the choice box. |
|---|
| 273 | static ConVarT VideoModes("VideoModes", GetVideoModes(), ConVarT::FLAG_MAIN_EXE | ConVarT::FLAG_READ_ONLY, "The list of video modes that are available on your system."); |
|---|
| 274 | |
|---|
| 275 | |
|---|
| 276 | // Change the video mode. Although the two actions |
|---|
| 277 | // |
|---|
| 278 | // (a) change the screen resolution (video mode) and |
|---|
| 279 | // (b) show the Cafu window full-screen |
|---|
| 280 | // |
|---|
| 281 | // are theoretically independent of each other, case "(a) but not (b)" does not make sense at all; |
|---|
| 282 | // case "not (a) but (b)" makes more sense but is atypical as well, and is easily switched from case |
|---|
| 283 | // "neither (a) nor (b)" by pressing F11. Thus, we are effectively only concerned by two cases: |
|---|
| 284 | // |
|---|
| 285 | // (1) windowed mode: "neither (a) nor (b)" |
|---|
| 286 | // (2) full-screen mode: "both (a) and (b)" |
|---|
| 287 | // |
|---|
| 288 | // For case (1), we simply open a normal application window with dimensions Options_ClientWindowSize[X/Y]. |
|---|
| 289 | // For case (2), we change the video mode as specified by Options_Client* and show the application |
|---|
| 290 | // window full-screen. |
|---|
| 291 | wxDisplay Display; |
|---|
| 292 | extern ConVarT Options_ClientFullScreen; |
|---|
| 293 | |
|---|
| 294 | if (Options_ClientFullScreen.GetValueBool()) |
|---|
| 295 | { |
|---|
| 296 | extern ConVarT Options_ClientWindowSizeX; |
|---|
| 297 | extern ConVarT Options_ClientWindowSizeY; |
|---|
| 298 | extern ConVarT Options_ClientDisplayBPP; |
|---|
| 299 | extern ConVarT Options_ClientDisplayRefresh; |
|---|
| 300 | |
|---|
| 301 | const wxVideoMode VideoMode1(Options_ClientWindowSizeX.GetValueInt(), |
|---|
| 302 | Options_ClientWindowSizeY.GetValueInt(), |
|---|
| 303 | Options_ClientDisplayBPP.GetValueInt(), |
|---|
| 304 | Options_ClientDisplayRefresh.GetValueInt()); |
|---|
| 305 | |
|---|
| 306 | const wxVideoMode VideoMode2(Options_ClientWindowSizeX.GetValueInt(), |
|---|
| 307 | Options_ClientWindowSizeY.GetValueInt(), |
|---|
| 308 | Options_ClientDisplayBPP.GetValueInt(), 0); |
|---|
| 309 | |
|---|
| 310 | const wxVideoMode VideoMode3(Options_ClientWindowSizeX.GetValueInt(), |
|---|
| 311 | Options_ClientWindowSizeY.GetValueInt(), 0, 0); |
|---|
| 312 | |
|---|
| 313 | if (Display.ChangeMode(VideoMode1)) |
|---|
| 314 | { |
|---|
| 315 | m_IsCustomVideoMode=true; |
|---|
| 316 | } |
|---|
| 317 | else if (Display.ChangeMode(VideoMode2)) |
|---|
| 318 | { |
|---|
| 319 | Options_ClientDisplayRefresh.SetValue(Display.GetCurrentMode().refresh); |
|---|
| 320 | m_IsCustomVideoMode=true; |
|---|
| 321 | } |
|---|
| 322 | else if (Display.ChangeMode(VideoMode3)) |
|---|
| 323 | { |
|---|
| 324 | Options_ClientDisplayBPP.SetValue(Display.GetCurrentMode().bpp); |
|---|
| 325 | Options_ClientDisplayRefresh.SetValue(Display.GetCurrentMode().refresh); |
|---|
| 326 | m_IsCustomVideoMode=true; |
|---|
| 327 | } |
|---|
| 328 | else |
|---|
| 329 | { |
|---|
| 330 | wxMessageBox("Cafu tried to change the video mode to\n"+ |
|---|
| 331 | wxString::Format(" %i x %i, %i bpp at %i Hz,\n", VideoMode1.w, VideoMode1.h, VideoMode1.bpp, VideoMode1.refresh)+ |
|---|
| 332 | wxString::Format(" %i x %i, %i bpp at any refresh rate,\n", VideoMode2.w, VideoMode2.h, VideoMode2.bpp)+ |
|---|
| 333 | wxString::Format(" %i x %i at any color depth and refresh rate,\n", VideoMode3.w, VideoMode3.h)+ |
|---|
| 334 | "but it didn't work out (zero values mean system defaults).\n"+ |
|---|
| 335 | "We will continue with the currently active video mode instead, where you can press F11 to toggle full-screen mode.\n\n"+ |
|---|
| 336 | "Alternatively, you can set a different video mode at the Options menu, or tweak the video mode details via the console variables.\n", |
|---|
| 337 | "Could not change the video mode", wxOK | wxICON_EXCLAMATION); |
|---|
| 338 | |
|---|
| 339 | Options_ClientFullScreen.SetValue(false); |
|---|
| 340 | } |
|---|
| 341 | } |
|---|
| 342 | |
|---|
| 343 | m_CurrentMode=Display.GetCurrentMode(); |
|---|
| 344 | |
|---|
| 345 | if (m_CurrentMode.w==0) { m_CurrentMode.w=wxGetDisplaySize().x; wxLogDebug("Set m_CurrentMode.w from 0 to %i", m_CurrentMode.w); } |
|---|
| 346 | if (m_CurrentMode.h==0) { m_CurrentMode.h=wxGetDisplaySize().y; wxLogDebug("Set m_CurrentMode.h from 0 to %i", m_CurrentMode.h); } |
|---|
| 347 | |
|---|
| 348 | if (m_CurrentMode.w<200) { m_CurrentMode.w=1024; wxLogDebug("Set m_CurrentMode.w from <200 to %i", m_CurrentMode.w); } |
|---|
| 349 | if (m_CurrentMode.h<150) { m_CurrentMode.h= 768; wxLogDebug("Set m_CurrentMode.h from <150 to %i", m_CurrentMode.h); } |
|---|
| 350 | |
|---|
| 351 | |
|---|
| 352 | // Create the main frame. |
|---|
| 353 | m_MainFrame=new MainFrameT(); |
|---|
| 354 | SetTopWindow(m_MainFrame); |
|---|
| 355 | |
|---|
| 356 | return true; |
|---|
| 357 | } |
|---|
| 358 | |
|---|
| 359 | |
|---|
| 360 | int AppCafuT::OnExit() |
|---|
| 361 | { |
|---|
| 362 | if (m_IsCustomVideoMode) |
|---|
| 363 | { |
|---|
| 364 | wxDisplay Display; |
|---|
| 365 | |
|---|
| 366 | // Reset the display to default (desktop) video mode. |
|---|
| 367 | Display.ChangeMode(); |
|---|
| 368 | } |
|---|
| 369 | |
|---|
| 370 | delete g_WinSock; |
|---|
| 371 | g_WinSock=NULL; |
|---|
| 372 | |
|---|
| 373 | // Setting the ConsoleInterpreter to NULL is very important, to make sure that no ConFuncT |
|---|
| 374 | // or ConVarT dtor accesses the ConsoleInterpreter that might already have been destroyed then. |
|---|
| 375 | ConsoleInterpreter=NULL; |
|---|
| 376 | |
|---|
| 377 | delete m_Locale; |
|---|
| 378 | m_Locale=NULL; |
|---|
| 379 | |
|---|
| 380 | return wxApp::OnExit(); |
|---|
| 381 | } |
|---|
| 382 | |
|---|
| 383 | |
|---|
| 384 | extern ConVarT Options_ServerGameName; |
|---|
| 385 | extern ConVarT Options_ServerWorldName; |
|---|
| 386 | extern ConVarT Options_ServerPortNr; |
|---|
| 387 | extern ConVarT Options_ClientPortNr; |
|---|
| 388 | extern ConVarT Options_ClientRemoteName; |
|---|
| 389 | extern ConVarT Options_ClientRemotePortNr; |
|---|
| 390 | |
|---|
| 391 | extern ConVarT Options_ClientWindowSizeX; |
|---|
| 392 | extern ConVarT Options_ClientWindowSizeY; |
|---|
| 393 | extern ConVarT Options_ClientDisplayBPP; // TODO |
|---|
| 394 | extern ConVarT Options_ClientDisplayRefresh; // TODO |
|---|
| 395 | extern ConVarT Options_ClientFullScreen; |
|---|
| 396 | |
|---|
| 397 | extern ConVarT Options_ClientDesiredRenderer; |
|---|
| 398 | extern ConVarT Options_ClientDesiredSoundSystem; |
|---|
| 399 | extern ConVarT Options_ClientTextureDetail; |
|---|
| 400 | extern ConVarT Options_DeathMatchPlayerName; |
|---|
| 401 | extern ConVarT Options_DeathMatchModelName; |
|---|
| 402 | |
|---|
| 403 | |
|---|
| 404 | void AppCafuT::OnInitCmdLine(wxCmdLineParser& Parser) |
|---|
| 405 | { |
|---|
| 406 | Parser.AddOption("con", "", "Runs the given commands in the console. -con \"x=3;\" is equivalent to appending x=3; to the end of the config.lua file.", wxCMD_LINE_VAL_STRING); |
|---|
| 407 | Parser.AddOption("svGame", "", "Name of the MOD / game the server should run ["+Options_ServerGameName.GetValueString()+"]. Case sensitive!", wxCMD_LINE_VAL_STRING); |
|---|
| 408 | Parser.AddOption("svWorld", "", "Name of the world the server should run ["+Options_ServerWorldName.GetValueString()+"]. Case sensitive!", wxCMD_LINE_VAL_STRING); |
|---|
| 409 | Parser.AddOption("svPort", "", wxString::Format("Server port number [%i].", Options_ServerPortNr.GetValueInt()), wxCMD_LINE_VAL_NUMBER); |
|---|
| 410 | Parser.AddSwitch("noFS", "clNoFullscreen", "Don't run full-screen, but rather in a window."); |
|---|
| 411 | Parser.AddOption("clPort", "", wxString::Format("Client port number [%i].", Options_ClientPortNr.GetValueInt()), wxCMD_LINE_VAL_NUMBER); |
|---|
| 412 | Parser.AddOption("clRemoteName", "", "Name or IP of the server we connect to ["+Options_ClientRemoteName.GetValueString()+"].", wxCMD_LINE_VAL_STRING); |
|---|
| 413 | Parser.AddOption("clRemotePort", "", wxString::Format("Port number of the remote server [%i].", Options_ClientRemotePortNr.GetValueInt()), wxCMD_LINE_VAL_NUMBER); |
|---|
| 414 | Parser.AddOption("clTexDetail", "", wxString::Format("0 high detail, 1 medium detail, 2 low detail [%i].", Options_ClientTextureDetail.GetValueInt()), wxCMD_LINE_VAL_NUMBER); |
|---|
| 415 | Parser.AddOption("clWinSizeX", "", wxString::Format("If not full-screen, this is the width of the window [%i].", Options_ClientWindowSizeX.GetValueInt()), wxCMD_LINE_VAL_NUMBER); |
|---|
| 416 | Parser.AddOption("clWinSizeY", "", wxString::Format("If not full-screen, this is the height of the window [%i].", Options_ClientWindowSizeY.GetValueInt()), wxCMD_LINE_VAL_NUMBER); |
|---|
| 417 | Parser.AddOption("clRenderer", "", "Override the auto-selection of the best available renderer [auto].", wxCMD_LINE_VAL_STRING); |
|---|
| 418 | Parser.AddOption("clSoundSystem", "", "Override the auto-selection of the best available sound system [auto].", wxCMD_LINE_VAL_STRING); |
|---|
| 419 | Parser.AddOption("clPlayerName", "", "Player name ["+Options_DeathMatchPlayerName.GetValueString()+"].", wxCMD_LINE_VAL_STRING); |
|---|
| 420 | Parser.AddOption("clModelName", "", "Name of the players model ["+Options_DeathMatchModelName.GetValueString()+"].", wxCMD_LINE_VAL_STRING); |
|---|
| 421 | Parser.AddOption("log", "", "Logs all console message into the specified file."); |
|---|
| 422 | Parser.AddParam("worldname", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL); |
|---|
| 423 | |
|---|
| 424 | wxApp::OnInitCmdLine(Parser); |
|---|
| 425 | Parser.AddUsageText("\nDefault values are enclosed in [brackets]."); |
|---|
| 426 | Parser.AddUsageText("It is also ok to omit the \"-svWorld\" option for specifying a world name: \"Cafu MyWorld\" is the same as \"Cafu -svWorld MyWorld\".\n"); |
|---|
| 427 | Parser.SetSwitchChars("-"); |
|---|
| 428 | } |
|---|
| 429 | |
|---|
| 430 | |
|---|
| 431 | bool AppCafuT::OnCmdLineParsed(wxCmdLineParser& Parser) |
|---|
| 432 | { |
|---|
| 433 | long int i=0; |
|---|
| 434 | wxString s=""; |
|---|
| 435 | |
|---|
| 436 | if (Parser.Found("con", &s)) ConsoleInterpreter->RunCommand(s.ToStdString()); |
|---|
| 437 | if (Parser.Found("svGame", &s)) Options_ServerGameName=s.ToStdString(); |
|---|
| 438 | if (Parser.Found("svWorld", &s)) Options_ServerWorldName=s.ToStdString(); |
|---|
| 439 | if (Parser.Found("svPort", &i)) Options_ServerPortNr=int(i); |
|---|
| 440 | if (Parser.Found("noFS") ) Options_ClientFullScreen=false; |
|---|
| 441 | if (Parser.Found("clPort", &i)) Options_ClientPortNr=int(i); |
|---|
| 442 | if (Parser.Found("clRemoteName", &s)) Options_ClientRemoteName=s.ToStdString(); |
|---|
| 443 | if (Parser.Found("clRemotePort", &i)) Options_ClientRemotePortNr=int(i); |
|---|
| 444 | if (Parser.Found("clTexDetail", &i)) Options_ClientTextureDetail=int(i % 3); |
|---|
| 445 | if (Parser.Found("clWinSizeX", &i)) Options_ClientWindowSizeX=int(i); |
|---|
| 446 | if (Parser.Found("clWinSizeY", &i)) Options_ClientWindowSizeY=int(i); |
|---|
| 447 | if (Parser.Found("clRenderer", &s)) Options_ClientDesiredRenderer=s.ToStdString(); |
|---|
| 448 | if (Parser.Found("clSoundSystem", &s)) Options_ClientDesiredSoundSystem=s.ToStdString(); |
|---|
| 449 | if (Parser.Found("clPlayerName", &s)) Options_DeathMatchPlayerName=s.ToStdString(); |
|---|
| 450 | if (Parser.Found("clModelName", &s)) Options_DeathMatchModelName=s.ToStdString(); |
|---|
| 451 | |
|---|
| 452 | if (Parser.Found("log", &s) && m_ConFile==NULL) |
|---|
| 453 | { |
|---|
| 454 | m_ConFile=new cf::ConsoleFileT(s.ToStdString()); |
|---|
| 455 | m_ConFile->SetAutoFlush(true); |
|---|
| 456 | m_ConFile->Print(m_ConBuffer->GetBuffer()); |
|---|
| 457 | |
|---|
| 458 | s_CompositeConsole.Attach(m_ConFile); |
|---|
| 459 | } |
|---|
| 460 | |
|---|
| 461 | if (!Parser.Found("svWorld") && Parser.GetParamCount()==1) |
|---|
| 462 | Options_ServerWorldName=Parser.GetParam(0).ToStdString(); |
|---|
| 463 | |
|---|
| 464 | return wxApp::OnCmdLineParsed(Parser); |
|---|
| 465 | } |
|---|