Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GameSetup.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2013 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "precompiled.h"
19 
20 #include "lib/app_hooks.h"
21 #include "lib/config2.h"
22 #include "lib/input.h"
23 #include "lib/ogl.h"
24 #include "lib/timer.h"
27 #include "lib/res/h_mgr.h"
29 #include "lib/sysdep/cursor.h"
30 #include "lib/sysdep/cpu.h"
31 #include "lib/sysdep/gfx.h"
32 #include "lib/sysdep/os_cpu.h"
33 #include "lib/tex/tex.h"
34 #if OS_WIN
36 #endif
37 
38 #include "graphics/CinemaTrack.h"
39 #include "graphics/GameView.h"
40 #include "graphics/LightEnv.h"
41 #include "graphics/MapReader.h"
44 #include "gui/GUI.h"
45 #include "gui/GUIManager.h"
49 #include "maths/MathUtil.h"
51 #include "network/NetServer.h"
52 #include "network/NetClient.h"
53 
54 #include "ps/CConsole.h"
55 #include "ps/CLogger.h"
56 #include "ps/ConfigDB.h"
57 #include "ps/Filesystem.h"
58 #include "ps/Font.h"
59 #include "ps/Game.h"
60 #include "ps/GameSetup/Atlas.h"
61 #include "ps/GameSetup/GameSetup.h"
62 #include "ps/GameSetup/Paths.h"
63 #include "ps/GameSetup/Config.h"
65 #include "ps/GameSetup/HWDetect.h"
66 #include "ps/Globals.h"
67 #include "ps/Hotkey.h"
68 #include "ps/Joystick.h"
69 #include "ps/Loader.h"
70 #include "ps/Overlay.h"
71 #include "ps/Profile.h"
72 #include "ps/ProfileViewer.h"
73 #include "ps/Profiler2.h"
74 #include "ps/Pyrogenesis.h" // psSetLogDir
76 #include "ps/TouchInput.h"
77 #include "ps/UserReport.h"
78 #include "ps/Util.h"
79 #include "ps/VideoMode.h"
80 #include "ps/World.h"
81 
82 #include "renderer/Renderer.h"
84 #include "renderer/ModelRenderer.h"
86 #include "scripting/ScriptGlue.h"
93 #include "tools/atlas/GameInterface/GameLoop.h"
94 #include "tools/atlas/GameInterface/View.h"
95 
96 #if !(OS_WIN || OS_MACOSX || OS_ANDROID) // assume all other platforms use X11 for wxWidgets
97 #define MUST_INIT_X11 1
98 #include <X11/Xlib.h>
99 #else
100 #define MUST_INIT_X11 0
101 #endif
102 
103 #if OS_WIN
104 extern void wmi_Shutdown();
105 #endif
106 
107 #include <iostream>
108 
109 ERROR_GROUP(System);
110 ERROR_TYPE(System, SDLInitFailed);
111 ERROR_TYPE(System, VmodeFailed);
112 ERROR_TYPE(System, RequiredExtensionsMissing);
113 
114 bool g_DoRenderGui = true;
115 bool g_DoRenderLogger = true;
116 bool g_DoRenderCursor = true;
117 
118 static const int SANE_TEX_QUALITY_DEFAULT = 5; // keep in sync with code
119 
120 static void SetTextureQuality(int quality)
121 {
122  int q_flags;
123  GLint filter;
124 
125 retry:
126  // keep this in sync with SANE_TEX_QUALITY_DEFAULT
127  switch(quality)
128  {
129  // worst quality
130  case 0:
132  filter = GL_NEAREST;
133  break;
134  // [perf] add bilinear filtering
135  case 1:
137  filter = GL_LINEAR;
138  break;
139  // [vmem] no longer reduce resolution
140  case 2:
141  q_flags = OGL_TEX_HALF_BPP;
142  filter = GL_LINEAR;
143  break;
144  // [vmem] add mipmaps
145  case 3:
146  q_flags = OGL_TEX_HALF_BPP;
147  filter = GL_NEAREST_MIPMAP_LINEAR;
148  break;
149  // [perf] better filtering
150  case 4:
151  q_flags = OGL_TEX_HALF_BPP;
152  filter = GL_LINEAR_MIPMAP_LINEAR;
153  break;
154  // [vmem] no longer reduce bpp
156  q_flags = OGL_TEX_FULL_QUALITY;
157  filter = GL_LINEAR_MIPMAP_LINEAR;
158  break;
159  // [perf] add anisotropy
160  case 6:
161  // TODO: add anisotropic filtering
162  q_flags = OGL_TEX_FULL_QUALITY;
163  filter = GL_LINEAR_MIPMAP_LINEAR;
164  break;
165  // invalid
166  default:
167  debug_warn(L"SetTextureQuality: invalid quality");
168  quality = SANE_TEX_QUALITY_DEFAULT;
169  // careful: recursion doesn't work and we don't want to duplicate
170  // the "sane" default values.
171  goto retry;
172  }
173 
174  ogl_tex_set_defaults(q_flags, filter);
175 }
176 
177 
178 //----------------------------------------------------------------------------
179 // GUI integration
180 //----------------------------------------------------------------------------
181 
182 // display progress / description in loading screen
183 void GUI_DisplayLoadProgress(int percent, const wchar_t* pending_task)
184 {
185  g_ScriptingHost.GetScriptInterface().SetGlobal("g_Progress", percent, true);
186  g_ScriptingHost.GetScriptInterface().SetGlobal("g_LoadDescription", pending_task, true);
187  g_GUI->SendEventToAll("progress");
188 }
189 
190 
191 
192 void Render()
193 {
194  PROFILE3("render");
195 
196  if (g_SoundManager)
198 
199  ogl_WarnIfError();
200 
202 
203  ogl_WarnIfError();
204 
205  // prepare before starting the renderer frame
206  if (g_Game && g_Game->IsGameStarted())
207  g_Game->GetView()->BeginFrame();
208 
209  if (g_Game)
210  g_Renderer.SetSimulation(g_Game->GetSimulation2());
211 
212  // start new frame
213  g_Renderer.BeginFrame();
214 
215  ogl_WarnIfError();
216 
217  if (g_Game && g_Game->IsGameStarted())
218  g_Game->GetView()->Render();
219 
220  ogl_WarnIfError();
221 
222  g_Renderer.RenderTextOverlays();
223 
224  if (g_DoRenderGui)
225  g_GUI->Draw();
226 
227  ogl_WarnIfError();
228 
229  // If we're in Atlas game view, render special overlays (e.g. editor bandbox)
230  if (g_AtlasGameLoop && g_AtlasGameLoop->view)
231  {
232  g_AtlasGameLoop->view->DrawOverlays();
233  ogl_WarnIfError();
234  }
235 
236  // Text:
237 
238  glDisable(GL_DEPTH_TEST);
239 
240  g_Console->Render();
241 
242  ogl_WarnIfError();
243 
244  if (g_DoRenderLogger)
245  g_Logger->Render();
246 
247  ogl_WarnIfError();
248 
249  // Profile information
250 
251  g_ProfileViewer.RenderProfile();
252 
253  ogl_WarnIfError();
254 
255  // Draw the cursor (or set the Windows cursor, on Windows)
256  if (g_DoRenderCursor)
257  {
258  PROFILE3_GPU("cursor");
259  CStrW cursorName = g_CursorName;
260  if (cursorName.empty())
261  {
262  cursor_draw(g_VFS, NULL, g_mouse_x, g_yres-g_mouse_y, false);
263  }
264  else
265  {
266  bool forceGL = false;
267  CFG_GET_VAL("nohwcursor", Bool, forceGL);
268 
269 #if CONFIG2_GLES
270 #warning TODO: implement cursors for GLES
271 #else
272  // set up transform for GL cursor
273  glMatrixMode(GL_PROJECTION);
274  glPushMatrix();
275  glLoadIdentity();
276  glMatrixMode(GL_MODELVIEW);
277  glPushMatrix();
278  glLoadIdentity();
279  CMatrix3D transform;
280  transform.SetOrtho(0.f, (float)g_xres, 0.f, (float)g_yres, -1.f, 1000.f);
281  glLoadMatrixf(&transform._11);
282 #endif
283 
284  if (cursor_draw(g_VFS, cursorName.c_str(), g_mouse_x, g_yres-g_mouse_y, forceGL) < 0)
285  LOGWARNING(L"Failed to draw cursor '%ls'", cursorName.c_str());
286 
287 #if CONFIG2_GLES
288 #warning TODO: implement cursors for GLES
289 #else
290  // restore transform
291  glMatrixMode(GL_PROJECTION);
292  glPopMatrix();
293  glMatrixMode(GL_MODELVIEW);
294  glPopMatrix();
295 #endif
296  }
297  }
298 
299  glEnable(GL_DEPTH_TEST);
300 
301  g_Renderer.EndFrame();
302 
303  PROFILE2_ATTR("draw calls: %d", (int)g_Renderer.GetStats().m_DrawCalls);
304  PROFILE2_ATTR("terrain tris: %d", (int)g_Renderer.GetStats().m_TerrainTris);
305  PROFILE2_ATTR("water tris: %d", (int)g_Renderer.GetStats().m_WaterTris);
306  PROFILE2_ATTR("model tris: %d", (int)g_Renderer.GetStats().m_ModelTris);
307  PROFILE2_ATTR("overlay tris: %d", (int)g_Renderer.GetStats().m_OverlayTris);
308  PROFILE2_ATTR("blend splats: %d", (int)g_Renderer.GetStats().m_BlendSplats);
309  PROFILE2_ATTR("particles: %d", (int)g_Renderer.GetStats().m_Particles);
310 
311  ogl_WarnIfError();
312 
314 
315  ogl_WarnIfError();
316 }
317 
318 
320 {
321  // maths
323 
324  // GUI
326 
327  GuiScriptingInit(g_ScriptingHost.GetScriptInterface());
329 }
330 
331 
332 static void InitScripting()
333 {
334  TIMER(L"InitScripting");
335 
336  // Create the scripting host. This needs to be done before the GUI is created.
337  // [7ms]
338  new ScriptingHost;
339 
341 }
342 
343 
345 {
346 #if OS_WIN
347  switch(wversion_Number())
348  {
349  case WVERSION_2K:
350  case WVERSION_XP:
351  return 150;
352  case WVERSION_XP64:
353  return 200;
354  default: // newer Windows version: assume the worst, and don't warn
355  case WVERSION_VISTA:
356  return 300;
357  case WVERSION_7:
358  return 250;
359  }
360 #else
361  return 200;
362 #endif
363 }
364 
365 static size_t ChooseCacheSize()
366 {
367  // (all sizes in MiB and signed to allow temporarily negative computations)
368 
369  const ssize_t total = (ssize_t)os_cpu_MemorySize();
370  // (NB: os_cpu_MemoryAvailable is useless on Linux because free memory
371  // is marked as "in use" by OS caches.)
373  const ssize_t game = 300; // estimated working set
374 
375  ssize_t cache = 500; // upper bound: total size of our data
376 
377  // the cache reserves contiguous address space, which is a precious
378  // resource on 32-bit systems, so don't use too much:
379  if(ARCH_IA32 || sizeof(void*) == 4)
380  cache = std::min(cache, (ssize_t)200);
381 
382  // try to leave over enough memory for the OS and game
383  cache = std::min(cache, total-os-game);
384 
385  // always provide at least this much to ensure correct operation
386  cache = std::max(cache, (ssize_t)64);
387 
388  debug_printf(L"Cache: %d (total: %d) MiB\n", (int)cache, (int)total);
389  return size_t(cache)*MiB;
390 }
391 
392 
393 ErrorReactionInternal psDisplayError(const wchar_t* UNUSED(text), size_t UNUSED(flags))
394 {
395  // If we're fullscreen, then sometimes (at least on some particular drivers on Linux)
396  // displaying the error dialog hangs the desktop since the dialog box is behind the
397  // fullscreen window. So we just force the game to windowed mode before displaying the dialog.
398  // (But only if we're in the main thread, and not if we're being reentrant.)
400  {
401  static bool reentering = false;
402  if (!reentering)
403  {
404  reentering = true;
405  g_VideoMode.SetFullscreen(false);
406  reentering = false;
407  }
408  }
409 
410  // We don't actually implement the error display here, so return appropriately
411  return ERI_NOT_IMPLEMENTED;
412 }
413 
414 static std::vector<CStr> GetMods(const CmdLineArgs& args, bool dev)
415 {
416  std::vector<CStr> mods = args.GetMultiple("mod");
417  // TODO: It would be nice to remove this hard-coding
418  mods.insert(mods.begin(), "public");
419 
420  // Add the user mod if not explicitly disabled or we have a dev copy so
421  // that saved files end up in version control and not in the user mod.
422  if (!dev && !args.Has("noUserMod"))
423  mods.push_back("user");
424 
425  return mods;
426 }
427 
428 static void InitVfs(const CmdLineArgs& args, int flags)
429 {
430  TIMER(L"InitVfs");
431 
432  const bool setup_error = (flags & INIT_HAVE_DISPLAY_ERROR) == 0;
433 
434  const Paths paths(args);
435 
436  OsPath logs(paths.Logs());
437  CreateDirectories(logs, 0700);
438 
439  psSetLogDir(logs);
440  // desired location for crashlog is now known. update AppHooks ASAP
441  // (particularly before the following error-prone operations):
442  AppHooks hooks = {0};
443  hooks.bundle_logs = psBundleLogs;
444  hooks.get_log_dir = psLogDir;
445  if (setup_error)
447  app_hooks_update(&hooks);
448 
449  const size_t cacheSize = ChooseCacheSize();
450  g_VFS = CreateVfs(cacheSize);
451 
452  // Work out whether we are a dev version to make sure saved files
453  // (maps, etc) end up in version control.
454  const OsPath readonlyConfig = paths.RData()/"config"/"";
455  g_VFS->Mount(L"config/", readonlyConfig);
456  bool dev = (g_VFS->GetFileInfo(L"config/dev.cfg", NULL) == INFO::OK);
457 
458  const std::vector<CStr> mods = GetMods(args, dev);
459 
460  OsPath modPath = paths.RData()/"mods";
461  OsPath modUserPath = paths.UserData()/"mods";
462  for (size_t i = 0; i < mods.size(); ++i)
463  {
464  size_t priority = (i+1)*2; // mods are higher priority than regular mountings, which default to priority 0
466  size_t baseFlags = userFlags|VFS_MOUNT_MUST_EXIST;
467 
468  OsPath modName(mods[i]);
469  if (dev)
470  {
471  // We are running a dev copy, so only mount mods in the user mod path
472  // if the mod does not exist in the data path.
473  if (DirectoryExists(modPath / modName/""))
474  g_VFS->Mount(L"", modPath / modName/"", baseFlags, priority);
475  else
476  g_VFS->Mount(L"", modUserPath / modName/"", userFlags, priority);
477  }
478  else
479  {
480  g_VFS->Mount(L"", modPath / modName/"", baseFlags, priority);
481  // Ensure that user modified files are loaded, if they are present
482  g_VFS->Mount(L"", modUserPath / modName/"", userFlags, priority+1);
483  }
484  }
485 
486  // We mount these dirs last as otherwise writing could result in files being placed in a mod's dir.
487  g_VFS->Mount(L"screenshots/", paths.UserData()/"screenshots"/"");
488  g_VFS->Mount(L"saves/", paths.UserData()/"saves"/"", VFS_MOUNT_WATCH);
489  // Mounting with highest priority, so that a mod supplied user.cfg is harmless
490  g_VFS->Mount(L"config/", readonlyConfig, 0, (size_t)-1);
491  if(readonlyConfig != paths.Config())
492  g_VFS->Mount(L"config/", paths.Config(), 0, (size_t)-1);
493 
494  g_VFS->Mount(L"cache/", paths.Cache(), VFS_MOUNT_ARCHIVABLE); // (adding XMBs to archive speeds up subsequent reads)
495 
496  // note: don't bother with g_VFS->TextRepresentation - directories
497  // haven't yet been populated and are empty.
498 }
499 
500 
501 static void InitPs(bool setup_gui, const CStrW& gui_page, CScriptVal initData)
502 {
503  {
504  // console
505  TIMER(L"ps_console");
506 
508 
509  // Calculate and store the line spacing
510  CFont font(CONSOLE_FONT);
514  // Offset by an arbitrary amount, to make it fit more nicely
516 
517  double blinkRate = 0.5;
518  CFG_GET_VAL("gui.cursorblinkrate", Double, blinkRate);
519  g_Console->SetCursorBlinkRate(blinkRate);
520  }
521 
522  // hotkeys
523  {
524  TIMER(L"ps_lang_hotkeys");
525  LoadHotkeys();
526  }
527 
528  if (!setup_gui)
529  {
530  // We do actually need *some* kind of GUI loaded, so use the
531  // (currently empty) Atlas one
532  g_GUI->SwitchPage(L"page_atlas.xml", initData);
533  return;
534  }
535 
536  // GUI uses VFS, so this must come after VFS init.
537  g_GUI->SwitchPage(gui_page, initData);
538 }
539 
540 
541 static void InitInput()
542 {
543 #if !SDL_VERSION_ATLEAST(2, 0, 0)
545 #endif
546 
548 
549  // register input handlers
550  // This stack is constructed so the first added, will be the last
551  // one called. This is important, because each of the handlers
552  // has the potential to block events to go further down
553  // in the chain. I.e. the last one in the list added, is the
554  // only handler that can block all messages before they are
555  // processed.
557 
559 
561 
563 
564  // gui_handler needs to be registered after (i.e. called before!) the
565  // hotkey handler so that input boxes can be typed in without
566  // setting off hotkeys.
568 
570 
571  // must be registered after (called before) the GUI which relies on these globals
573 }
574 
575 
576 static void ShutdownPs()
577 {
579 
581 
582  // disable the special Windows cursor, or free textures for OGL cursors
584 }
585 
586 
587 static void InitRenderer()
588 {
589  TIMER(L"InitRenderer");
590 
591  if(g_NoGLS3TC)
593  if(g_NoGLAutoMipmap)
595 
596  // create renderer
597  new CRenderer;
598 
599  // set renderer options from command line options - NOVBO must be set before opening the renderer
600  g_Renderer.SetOptionBool(CRenderer::OPT_NOVBO, g_NoGLVBO);
602 
610 
616 
617  // create terrain related stuff
619 
620  g_Renderer.Open(g_xres, g_yres);
621 
622  // Setup lighting environment. Since the Renderer accesses the
623  // lighting environment through a pointer, this has to be done before
624  // the first Frame.
625  g_Renderer.SetLightEnv(&g_LightEnv);
626 
627  // I haven't seen the camera affecting GUI rendering and such, but the
628  // viewport has to be updated according to the video mode
629  SViewPort vp;
630  vp.m_X = 0;
631  vp.m_Y = 0;
632  vp.m_Width = g_xres;
633  vp.m_Height = g_yres;
634  g_Renderer.SetViewport(vp);
635 
638 }
639 
640 static void InitSDL()
641 {
642 #if OS_LINUX
643  // In fullscreen mode when SDL is compiled with DGA support, the mouse
644  // sensitivity often appears to be unusably wrong (typically too low).
645  // (This seems to be reported almost exclusively on Ubuntu, but can be
646  // reproduced on Gentoo after explicitly enabling DGA.)
647  // Disabling the DGA mouse appears to fix that problem, and doesn't
648  // have any obvious negative effects.
649  setenv("SDL_VIDEO_X11_DGAMOUSE", "0", 0);
650 #endif
651 
653  {
654  LOGERROR(L"SDL library initialization failed: %hs", SDL_GetError());
656  }
657  atexit(SDL_Quit);
658 
659 #if SDL_VERSION_ATLEAST(2, 0, 0)
660  SDL_StartTextInput();
661 #else
663 #endif
664 }
665 
666 static void ShutdownSDL()
667 {
668  SDL_Quit();
670 }
671 
672 
673 void EndGame()
674 {
678 
680 }
681 
682 
683 void Shutdown(int UNUSED(flags))
684 {
685  EndGame();
686 
687  ShutdownPs(); // Must delete g_GUI before g_ScriptingHost
688 
690 
691  TIMER_BEGIN(L"shutdown TexMan");
692  delete &g_TexMan;
693  TIMER_END(L"shutdown TexMan");
694 
695  // destroy renderer
696  TIMER_BEGIN(L"shutdown Renderer");
697  delete &g_Renderer;
698  g_VBMan.Shutdown();
699  TIMER_END(L"shutdown Renderer");
700 
702 
704 
705  // Free cursors before shutting down SDL, as they may depend on SDL.
706  cursor_shutdown();
707 
708  TIMER_BEGIN(L"shutdown SDL");
709  ShutdownSDL();
710  TIMER_END(L"shutdown SDL");
711 
713 
714  TIMER_BEGIN(L"shutdown UserReporter");
716  TIMER_END(L"shutdown UserReporter");
717 
718  TIMER_BEGIN(L"shutdown ScriptingHost");
719  delete &g_ScriptingHost;
720  delete g_DebuggingServer;
721  TIMER_END(L"shutdown ScriptingHost");
722 
723  TIMER_BEGIN(L"shutdown ConfigDB");
724  delete &g_ConfigDB;
725  TIMER_END(L"shutdown ConfigDB");
726 
727  // resource
728  // first shut down all resource owners, and then the handle manager.
729  TIMER_BEGIN(L"resource modules");
730 
732 
733  g_VFS.reset();
734 
735  // this forcibly frees all open handles (thus preventing real leaks),
736  // and makes further access to h_mgr impossible.
737  h_mgr_shutdown();
738 
739  file_stats_dump();
740 
741  TIMER_END(L"resource modules");
742 
743  TIMER_BEGIN(L"shutdown misc");
745 
747 
749 
750  // should be last, since the above use them
752  delete &g_Profiler;
753  delete &g_ProfileViewer;
754  TIMER_END(L"shutdown misc");
755 
756 #if OS_WIN
757  TIMER_BEGIN(L"shutdown wmi");
758  wmi_Shutdown();
759  TIMER_END(L"shutdown wmi");
760 #endif
761 }
762 
763 #if OS_UNIX
764 static void FixLocales()
765 {
766 #if OS_MACOSX || OS_BSD
767  // OS X requires a UTF-8 locale in LC_CTYPE so that *wprintf can handle
768  // wide characters. Peculiarly the string "UTF-8" seems to be acceptable
769  // despite not being a real locale, and it's conveniently language-agnostic,
770  // so use that.
771  setlocale(LC_CTYPE, "UTF-8");
772 #endif
773 
774 
775  // On misconfigured systems with incorrect locale settings, we'll die
776  // with a C++ exception when some code (e.g. Boost) tries to use locales.
777  // To avoid death, we'll detect the problem here and warn the user and
778  // reset to the default C locale.
779 
780 
781  // For informing the user of the problem, use the list of env vars that
782  // glibc setlocale looks at. (LC_ALL is checked first, and LANG last.)
783  const char* const LocaleEnvVars[] = {
784  "LC_ALL",
785  "LC_COLLATE",
786  "LC_CTYPE",
787  "LC_MONETARY",
788  "LC_NUMERIC",
789  "LC_TIME",
790  "LC_MESSAGES",
791  "LANG"
792  };
793 
794  try
795  {
796  // this constructor is similar to setlocale(LC_ALL, ""),
797  // but instead of returning NULL, it throws runtime_error
798  // when the first locale env variable found contains an invalid value
799  std::locale("");
800  }
801  catch (std::runtime_error&)
802  {
803  LOGWARNING(L"Invalid locale settings");
804 
805  for (size_t i = 0; i < ARRAY_SIZE(LocaleEnvVars); i++)
806  {
807  if (char* envval = getenv(LocaleEnvVars[i]))
808  LOGWARNING(L" %hs=\"%hs\"", LocaleEnvVars[i], envval);
809  else
810  LOGWARNING(L" %hs=\"(unset)\"", LocaleEnvVars[i]);
811  }
812 
813  // We should set LC_ALL since it overrides LANG
814  if (setenv("LC_ALL", std::locale::classic().name().c_str(), 1))
815  debug_warn(L"Invalid locale settings, and unable to set LC_ALL env variable.");
816  else
817  LOGWARNING(L"Setting LC_ALL env variable to: %hs", getenv("LC_ALL"));
818  }
819 }
820 #else
821 static void FixLocales()
822 {
823  // Do nothing on Windows
824 }
825 #endif
826 
827 void EarlyInit()
828 {
829  // If you ever want to catch a particular allocation:
830  //_CrtSetBreakAlloc(232647);
831 
833 
834  debug_SetThreadName("main");
835  // add all debug_printf "tags" that we are interested in:
836  debug_filter_add(L"TIMER");
837 
839 
840  // initialise profiler early so it can profile startup,
841  // but only after LatchStartTime
843 
844  FixLocales();
845 
846  // Because we do GL calls from a secondary thread, Xlib needs to
847  // be told to support multiple threads safely.
848  // This is needed for Atlas, but we have to call it before any other
849  // Xlib functions (e.g. the ones used when drawing the main menu
850  // before launching Atlas)
851 #if MUST_INIT_X11
852  int status = XInitThreads();
853  if (status == 0)
854  debug_printf(L"Error enabling thread-safety via XInitThreads\n");
855 #endif
856 
857  // Initialise the low-quality rand function
858  srand(time(NULL)); // NOTE: this rand should *not* be used for simulation!
859 }
860 
861 bool Autostart(const CmdLineArgs& args);
862 
863 void Init(const CmdLineArgs& args, int flags)
864 {
865  h_mgr_init();
866 
867  // Do this as soon as possible, because it chdirs
868  // and will mess up the error reporting if anything
869  // crashes before the working directory is set.
870  InitVfs(args, flags);
871 
872  // This must come after VFS init, which sets the current directory
873  // (required for finding our output log files).
874  g_Logger = new CLogger;
875 
876  // Special command-line mode to dump the entity schemas instead of running the game.
877  // (This must be done after loading VFS etc, but should be done before wasting time
878  // on anything else.)
879  if (args.Has("dumpSchema"))
880  {
881  CSimulation2 sim(NULL, NULL);
882  sim.LoadDefaultScripts();
883  std::ofstream f("entity.rng", std::ios_base::out | std::ios_base::trunc);
884  f << sim.GenerateSchema();
885  std::cout << "Generated entity.rng\n";
886  exit(0);
887  }
888 
889  // override ah_translate with our i18n code.
890  AppHooks hooks = {0};
891  hooks.translate = psTranslate;
893  app_hooks_update(&hooks);
894 
895  // Set up the console early, so that debugging
896  // messages can be logged to it. (The console's size
897  // and fonts are set later in InitPs())
898  g_Console = new CConsole();
899 
901 
902  new CProfileViewer;
903  new CProfileManager; // before any script code
904 
906  g_ProfileViewer.AddRootTable(g_ScriptStatsTable);
907 
908 
909 #if CONFIG2_AUDIO
911 #endif
912 
913  // g_ConfigDB, command line args, globals
914  CONFIG_Init(args);
915 
916  // before scripting
919 
920  InitScripting(); // before GUI
921 
922  // Optionally start profiler HTTP output automatically
923  // (By default it's only enabled by a hotkey, for security/performance)
924  bool profilerHTTPEnable = false;
925  CFG_GET_VAL("profiler2.http.autoenable", Bool, profilerHTTPEnable);
926  if (profilerHTTPEnable)
928 
929  if (!g_Quickstart)
930  g_UserReporter.Initialize(); // after config
931 
932  PROFILE2_EVENT("Init finished");
933 }
934 
935 void InitGraphics(const CmdLineArgs& args, int flags)
936 {
937  const bool setup_vmode = (flags & INIT_HAVE_VMODE) == 0;
938 
939  if(setup_vmode)
940  {
941  InitSDL();
942 
943  if (!g_VideoMode.InitSDL())
944  throw PSERROR_System_VmodeFailed(); // abort startup
945 
946 #if !SDL_VERSION_ATLEAST(2, 0, 0)
947  SDL_WM_SetCaption("0 A.D.", "0 A.D.");
948 #endif
949  }
950 
952 
954 
955  const int quality = SANE_TEX_QUALITY_DEFAULT; // TODO: set value from config file
956  SetTextureQuality(quality);
957 
958  ogl_WarnIfError();
959 
960  // Optionally start profiler GPU timings automatically
961  // (By default it's only enabled by a hotkey, for performance/compatibility)
962  bool profilerGPUEnable = false;
963  CFG_GET_VAL("profiler2.gpu.autoenable", Bool, profilerGPUEnable);
964  if (profilerGPUEnable)
966 
967  if(!g_Quickstart)
968  {
969  WriteSystemInfo();
970  // note: no longer vfs_display here. it's dog-slow due to unbuffered
971  // file output and very rarely needed.
972  }
973 
974  if(g_DisableAudio)
976 
977  g_GUI = new CGUIManager(g_ScriptingHost.GetScriptInterface());
978 
979  // (must come after SetVideoMode, since it calls ogl_Init)
980  if (ogl_HaveExtensions(0, "GL_ARB_vertex_program", "GL_ARB_fragment_program", NULL) != 0 // ARB
981  && ogl_HaveExtensions(0, "GL_ARB_vertex_shader", "GL_ARB_fragment_shader", NULL) != 0) // GLSL
982  {
984  L"Your graphics card doesn't appear to be fully compatible with OpenGL shaders."
985  L" In the future, the game will not support pre-shader graphics cards."
986  L" You are advised to try installing newer drivers and/or upgrade your graphics card."
987  L" For more information, please see http://www.wildfiregames.com/forum/index.php?showtopic=16734"
988  );
989  // TODO: actually quit once fixed function support is dropped
990  }
991 
992  const char* missing = ogl_HaveExtensions(0,
993  "GL_ARB_multitexture",
994  "GL_EXT_draw_range_elements",
995  "GL_ARB_texture_env_combine",
996  "GL_ARB_texture_env_dot3",
997  NULL);
998  if(missing)
999  {
1000  wchar_t buf[500];
1001  swprintf_s(buf, ARRAY_SIZE(buf),
1002  L"The %hs extension doesn't appear to be available on your computer."
1003  L" The game may still work, though - you are welcome to try at your own risk."
1004  L" If not or it doesn't look right, upgrade your graphics card.",
1005  missing
1006  );
1007  DEBUG_DISPLAY_ERROR(buf);
1008  // TODO: i18n
1009  }
1010 
1011  if (!ogl_HaveExtension("GL_ARB_texture_env_crossbar"))
1012  {
1014  L"The GL_ARB_texture_env_crossbar extension doesn't appear to be available on your computer."
1015  L" Shadows are not available and overall graphics quality might suffer."
1016  L" You are advised to try installing newer drivers and/or upgrade your graphics card.");
1017  g_Shadows = false;
1018  }
1019 
1020  ogl_WarnIfError();
1021  InitRenderer();
1022 
1023  InitInput();
1024 
1025  ogl_WarnIfError();
1026 
1027  try
1028  {
1029  if (!Autostart(args))
1030  {
1031  const bool setup_gui = ((flags & INIT_NO_GUI) == 0);
1032  // We only want to display the splash screen at startup
1033  CScriptValRooted data;
1034  if (g_GUI)
1035  {
1036  ScriptInterface& scriptInterface = g_GUI->GetScriptInterface();
1037  scriptInterface.Eval("({})", data);
1038  scriptInterface.SetProperty(data.get(), "isStartup", true);
1039  }
1040  InitPs(setup_gui, L"page_pregame.xml", data.get());
1041  }
1042  }
1044  {
1045  // Map Loading failed
1046 
1047  // Start the engine so we have a GUI
1048  InitPs(true, L"page_pregame.xml", JSVAL_VOID);
1049 
1050  // Call script function to do the actual work
1051  // (delete game data, switch GUI page, show error, etc.)
1052  CancelLoad(CStr(e.what()).FromUTF8());
1053  }
1054 }
1055 
1056 void RenderGui(bool RenderingState)
1057 {
1058  g_DoRenderGui = RenderingState;
1059 }
1060 
1061 void RenderLogger(bool RenderingState)
1062 {
1063  g_DoRenderLogger = RenderingState;
1064 }
1065 
1066 void RenderCursor(bool RenderingState)
1067 {
1068  g_DoRenderCursor = RenderingState;
1069 }
1070 
1071 bool Autostart(const CmdLineArgs& args)
1072 {
1073  /*
1074  * Handle various command-line options, for quick testing of various features:
1075  * -autostart=name -- map name for scenario, or rms name for random map
1076  * -autostart-ai=1:dummybot -- adds the dummybot AI to player 1
1077  * -autostart-playername=name -- multiplayer player name
1078  * -autostart-host -- multiplayer host mode
1079  * -autostart-players=2 -- number of players
1080  * -autostart-client -- multiplayer client mode
1081  * -autostart-ip=127.0.0.1 -- multiplayer connect to 127.0.0.1
1082  * -autostart-random=104 -- random map, optional seed value = 104 (default is 0, random is -1)
1083  * -autostart-size=192 -- random map size in tiles = 192 (default is 192)
1084  * -autostart-civ=1:hele -- set player #1 civ to "hele"
1085  *
1086  * Examples:
1087  * -autostart=Acropolis -autostart-host -autostart-players=2 -- Host game on Acropolis map, 2 players
1088  * -autostart=latium -autostart-random=-1 -- Start single player game on latium random map, random rng seed
1089  */
1090 
1091  CStr autoStartName = args.Get("autostart");
1092 
1093 #if OS_ANDROID
1094  // HACK: currently the most convenient way to test maps on Android;
1095  // should find a better solution
1096  autoStartName = "Oasis";
1097 #endif
1098 
1099  if (autoStartName.empty())
1100  {
1101  return false;
1102  }
1103 
1104  g_Game = new CGame();
1105 
1106  ScriptInterface& scriptInterface = g_Game->GetSimulation2()->GetScriptInterface();
1107 
1108  CScriptValRooted attrs;
1109  scriptInterface.Eval("({})", attrs);
1110  CScriptVal settings;
1111  scriptInterface.Eval("({})", settings);
1112  CScriptVal playerData;
1113  scriptInterface.Eval("([])", playerData);
1114 
1115  // Set different attributes for random or scenario game
1116  if (args.Has("autostart-random"))
1117  {
1118  CStr seedArg = args.Get("autostart-random");
1119 
1120  // Default seed is 0
1121  uint32 seed = 0;
1122  if (!seedArg.empty())
1123  {
1124  if (seedArg.compare("-1") == 0)
1125  { // Random seed value
1126  seed = rand();
1127  }
1128  else
1129  {
1130  seed = seedArg.ToULong();
1131  }
1132  }
1133 
1134  // Random map definition will be loaded from JSON file, so we need to parse it
1135  std::wstring scriptPath = L"maps/random/" + autoStartName.FromUTF8() + L".json";
1136  CScriptValRooted scriptData = scriptInterface.ReadJSONFile(scriptPath);
1137  if (!scriptData.undefined() && scriptInterface.GetProperty(scriptData.get(), "settings", settings))
1138  {
1139  // JSON loaded ok - copy script name over to game attributes
1140  std::wstring scriptFile;
1141  scriptInterface.GetProperty(settings.get(), "Script", scriptFile);
1142  scriptInterface.SetProperty(attrs.get(), "script", scriptFile); // RMS filename
1143  }
1144  else
1145  {
1146  // Problem with JSON file
1147  LOGERROR(L"Error reading random map script '%ls'", scriptPath.c_str());
1148  throw PSERROR_Game_World_MapLoadFailed("Error reading random map script.\nCheck application log for details.");
1149  }
1150 
1151  // Get optional map size argument (default 192)
1152  uint mapSize = 192;
1153  if (args.Has("autostart-size"))
1154  {
1155  CStr size = args.Get("autostart-size");
1156  mapSize = size.ToUInt();
1157  }
1158 
1159  scriptInterface.SetProperty(attrs.get(), "map", std::string(autoStartName));
1160  scriptInterface.SetProperty(attrs.get(), "mapType", std::string("random"));
1161  scriptInterface.SetProperty(settings.get(), "Seed", seed); // Random seed
1162  scriptInterface.SetProperty(settings.get(), "Size", mapSize); // Random map size (in patches)
1163 
1164  // Get optional number of players (default 2)
1165  size_t numPlayers = 2;
1166  if (args.Has("autostart-players"))
1167  {
1168  CStr num = args.Get("autostart-players");
1169  numPlayers = num.ToUInt();
1170  }
1171 
1172  // Set up player data
1173  for (size_t i = 0; i < numPlayers; ++i)
1174  {
1175  CScriptVal player;
1176  scriptInterface.Eval("({})", player);
1177 
1178  // We could load player_defaults.json here, but that would complicate the logic
1179  // even more and autostart is only intended for developers anyway
1180  scriptInterface.SetProperty(player.get(), "Civ", std::string("athen"));
1181  scriptInterface.SetPropertyInt(playerData.get(), i, player);
1182  }
1183  }
1184  else
1185  {
1186  // TODO: support akirmish maps
1187  std::string mapFile = "maps/scenarios/" + autoStartName;
1188  scriptInterface.SetProperty(attrs.get(), "map", mapFile);
1189  scriptInterface.SetProperty(attrs.get(), "mapType", std::string("scenario"));
1190  }
1191 
1192  // Set player data for AIs
1193  // attrs.settings = { PlayerData: [ { AI: ... }, ... ] }:
1194  if (args.Has("autostart-ai"))
1195  {
1196  std::vector<CStr> aiArgs = args.GetMultiple("autostart-ai");
1197  for (size_t i = 0; i < aiArgs.size(); ++i)
1198  {
1199  // Instead of overwriting existing player data, modify the array
1200  CScriptVal player;
1201  if (!scriptInterface.GetPropertyInt(playerData.get(), i, player) || player.undefined())
1202  {
1203  scriptInterface.Eval("({})", player);
1204  }
1205 
1206  int playerID = aiArgs[i].BeforeFirst(":").ToInt();
1207  CStr name = aiArgs[i].AfterFirst(":");
1208 
1209  scriptInterface.SetProperty(player.get(), "AI", std::string(name));
1210  scriptInterface.SetProperty(player.get(), "AIDiff", 2);
1211  scriptInterface.SetPropertyInt(playerData.get(), playerID-1, player);
1212  }
1213  }
1214  // Set AI difficulty
1215  if (args.Has("autostart-aidiff"))
1216  {
1217  std::vector<CStr> civArgs = args.GetMultiple("autostart-aidiff");
1218  for (size_t i = 0; i < civArgs.size(); ++i)
1219  {
1220  // Instead of overwriting existing player data, modify the array
1221  CScriptVal player;
1222  if (!scriptInterface.GetPropertyInt(playerData.get(), i, player) || player.undefined())
1223  {
1224  scriptInterface.Eval("({})", player);
1225  }
1226 
1227  int playerID = civArgs[i].BeforeFirst(":").ToInt();
1228  int difficulty = civArgs[i].AfterFirst(":").ToInt();
1229 
1230  scriptInterface.SetProperty(player.get(), "AIDiff", difficulty);
1231  scriptInterface.SetPropertyInt(playerData.get(), playerID-1, player);
1232  }
1233  }
1234  // Set player data for Civs
1235  if (args.Has("autostart-civ"))
1236  {
1237  std::vector<CStr> civArgs = args.GetMultiple("autostart-civ");
1238  for (size_t i = 0; i < civArgs.size(); ++i)
1239  {
1240  // Instead of overwriting existing player data, modify the array
1241  CScriptVal player;
1242  if (!scriptInterface.GetPropertyInt(playerData.get(), i, player) || player.undefined())
1243  {
1244  scriptInterface.Eval("({})", player);
1245  }
1246 
1247  int playerID = civArgs[i].BeforeFirst(":").ToInt();
1248  CStr name = civArgs[i].AfterFirst(":");
1249 
1250  scriptInterface.SetProperty(player.get(), "Civ", std::string(name));
1251  scriptInterface.SetPropertyInt(playerData.get(), playerID-1, player);
1252  }
1253  }
1254 
1255  // Add player data to map settings
1256  scriptInterface.SetProperty(settings.get(), "PlayerData", playerData);
1257 
1258  // Add map settings to game attributes
1259  scriptInterface.SetProperty(attrs.get(), "settings", settings);
1260 
1261  CScriptVal mpInitData;
1262  g_GUI->GetScriptInterface().Eval("({isNetworked:true, playerAssignments:{}})", mpInitData);
1263  g_GUI->GetScriptInterface().SetProperty(mpInitData.get(), "attribs",
1264  CScriptVal(g_GUI->GetScriptInterface().CloneValueFromOtherContext(scriptInterface, attrs.get())));
1265 
1266  // Get optional playername
1267  CStrW userName = L"anonymous";
1268  if (args.Has("autostart-playername"))
1269  {
1270  userName = args.Get("autostart-playername").FromUTF8();
1271  }
1272 
1273  if (args.Has("autostart-host"))
1274  {
1275  InitPs(true, L"page_loading.xml", mpInitData.get());
1276 
1277  size_t maxPlayers = 2;
1278  if (args.Has("autostart-players"))
1279  {
1280  maxPlayers = args.Get("autostart-players").ToUInt();
1281  }
1282 
1283  g_NetServer = new CNetServer(maxPlayers);
1284 
1285  g_NetServer->UpdateGameAttributes(attrs.get(), scriptInterface);
1286 
1287  bool ok = g_NetServer->SetupConnection();
1288  ENSURE(ok);
1289 
1290  g_NetClient = new CNetClient(g_Game);
1291  g_NetClient->SetUserName(userName);
1292  g_NetClient->SetupConnection("127.0.0.1");
1293  }
1294  else if (args.Has("autostart-client"))
1295  {
1296  InitPs(true, L"page_loading.xml", mpInitData.get());
1297 
1298  g_NetClient = new CNetClient(g_Game);
1299  g_NetClient->SetUserName(userName);
1300 
1301  CStr ip = "127.0.0.1";
1302  if (args.Has("autostart-ip"))
1303  {
1304  ip = args.Get("autostart-ip");
1305  }
1306 
1307  bool ok = g_NetClient->SetupConnection(ip);
1308  ENSURE(ok);
1309  }
1310  else
1311  {
1312  g_Game->SetPlayerID(1);
1313  g_Game->StartGame(attrs, "");
1314 
1316 
1317  PSRETURN ret = g_Game->ReallyStartGame();
1318  ENSURE(ret == PSRETURN_OK);
1319 
1320  InitPs(true, L"page_session.xml", JSVAL_VOID);
1321  }
1322 
1323  return true;
1324 }
1325 
1326 void CancelLoad(const CStrW& message)
1327 {
1328  // Cancel loader
1329  LDR_Cancel();
1330 
1331  // Call the cancelOnError GUI function, defined in ..gui/common/functions_utility_error.js
1332  // So all GUI pages that load games should include this script
1333  if (g_GUI && g_GUI->HasPages())
1334  {
1335  JSContext* cx = g_ScriptingHost.getContext();
1336  jsval fval, rval;
1337  JSBool ok = JS_GetProperty(cx, g_GUI->GetScriptObject(), "cancelOnError", &fval);
1338  ENSURE(ok);
1339 
1340  jsval msgval = ScriptInterface::ToJSVal(cx, message);
1341 
1342  if (ok && !JSVAL_IS_VOID(fval))
1343  JS_CallFunctionValue(cx, g_GUI->GetScriptObject(), fval, 1, &msgval, &rval);
1344  }
1345 }
CDebuggingServer * g_DebuggingServer
The container that holds the rules, resources and attributes of the game.
Definition: Game.h:39
int GetLineSpacing()
Definition: Font.cpp:55
void InitGraphics(const CmdLineArgs &args, int flags)
Definition: GameSetup.cpp:935
const size_t WVERSION_XP
Definition: wversion.h:33
Error/warning/message logging class.
Definition: CLogger.h:45
#define PROFILE2_EVENT(name)
Record the named event at the current time.
Definition: Profiler2.h:453
void BeginFrame()
Definition: GameView.cpp:473
void WriteSystemInfo()
Definition: Util.cpp:73
#define g_TexMan
CScriptStatsTable * g_ScriptStatsTable
Definition: ScriptStats.cpp:26
InReaction gui_handler(const SDL_Event_ *ev)
Definition: GUIManager.cpp:45
CStr Get(const char *name) const
Get the value of the named parameter.
Definition: CmdLineArgs.cpp:71
void psBundleLogs(FILE *f)
Definition: Pyrogenesis.cpp:73
CUserReporter g_UserReporter
Definition: UserReport.cpp:73
void ogl_tex_override(OglTexOverrides what, OglTexAllow allow)
Override the default decision and force/disallow use of the given feature.
Definition: ogl_tex.cpp:711
static void InitScripting()
Definition: GameSetup.cpp:332
#define UNUSED(param)
mark a function parameter as unused and avoid the corresponding compiler warning. ...
bool Autostart(const CmdLineArgs &args)
Definition: GameSetup.cpp:1071
bool g_Silhouettes
Definition: Config.cpp:51
CNetClient * g_NetClient
Global network client for the standard game.
Definition: NetClient.cpp:37
const OsPath & psLogDir()
Definition: Pyrogenesis.cpp:96
const Status OK
Definition: status.h:386
#define LOGERROR
Definition: CLogger.h:35
Status LDR_NonprogressiveLoad()
Definition: Loader.cpp:308
ErrorReactionInternal(* display_error)(const wchar_t *text, size_t flags)
Definition: app_hooks.h:187
int m_iFontOffset
Definition: CConsole.h:92
void Initialise()
Initialises joystick support.
Definition: Joystick.cpp:33
bool g_DoRenderLogger
Definition: GameSetup.cpp:115
CStrW g_CursorName
Definition: Config.cpp:31
int setenv(const char *envname, const char *envval, int overwrite)
rationale: the Windows headers declare many POSIX functions (e.g.
Definition: wposix.cpp:34
const PSRETURN PSRETURN_OK
Definition: Errors.h:103
CLightEnv g_LightEnv
File : World.cpp Project : engine Description : Contains the CWorld Class implementation.
Definition: World.cpp:49
const wchar_t *(* translate)(const wchar_t *text)
Definition: app_hooks.h:184
bool SetupConnection()
Begin listening for network connections.
Definition: NetServer.cpp:928
ISoundManager * g_SoundManager
void GUI_DisplayLoadProgress(int percent, const wchar_t *pending_task)
Definition: GameSetup.cpp:183
int GetCharacterWidth(wchar_t c)
Definition: Font.cpp:65
void Shutdown()
Explicit shutdown of the vertex buffer subsystem; releases all currently-allocated buffers...
int g_xres
Definition: Config.cpp:58
CVertexBufferManager g_VBMan
static Status Init()
Definition: h_mgr.cpp:744
Status sys_cursor_reset()
reset any cached cursor data.
Definition: android.cpp:116
const OsPath & UserData() const
Returns directory for user-created data Only things created in response to an explicit user action sh...
Definition: Paths.h:61
std::vector< CStr > GetMultiple(const char *name) const
Get all the values given to the named parameter.
Definition: CmdLineArgs.cpp:80
int m_iFontWidth
Definition: CConsole.h:91
int m_Y
Definition: Camera.h:34
#define CFG_GET_VAL(name, type, destination)
Definition: ConfigDB.h:147
special return value for the display_error app hook stub to indicate that it has done nothing and tha...
Definition: debug.h:175
static void out(const wchar_t *fmt,...)
Definition: wdbg_sym.cpp:419
static LogFn g_Logger
Definition: DLL.cpp:33
void h_mgr_init()
Definition: h_mgr.cpp:811
void LDR_Cancel()
Definition: Loader.cpp:145
bool g_JSDebuggerEnabled
Definition: Config.cpp:64
virtual void IdleTask()=0
static RenderPath GetRenderPathByName(const CStr &name)
Definition: Renderer.cpp:817
const OsPath & RData() const
Returns directory for read-only data installed with the game.
Definition: Paths.h:43
static void ShutdownPs()
Definition: GameSetup.cpp:576
static void Shutdown()
Definition: h_mgr.cpp:762
void Render()
Definition: GameView.cpp:496
const jsval & get() const
Returns the current value.
Definition: ScriptVal.h:38
void GuiScriptingInit(ScriptInterface &scriptInterface)
const OsPath &(* get_log_dir)()
Definition: app_hooks.h:182
CNetServer * g_NetServer
Global network server for the standard game.
Definition: NetServer.cpp:46
void psSetLogDir(const OsPath &newLogDir)
Definition: Pyrogenesis.cpp:91
Class CProfileViewer: Manage and display profiling tables.
A trivial wrapper around a jsval.
Definition: ScriptVal.h:29
void RenderGui(bool RenderingState)
enable/disable rendering of the GUI (intended mainly for screenshots)
Definition: GameSetup.cpp:1056
GameLoopState * g_AtlasGameLoop
static void CloseGame()
InReaction touch_input_handler(const SDL_Event_ *ev)
Definition: TouchInput.cpp:293
std::string GenerateSchema()
static size_t OperatingSystemFootprint()
Definition: GameSetup.cpp:344
const size_t WVERSION_7
Definition: wversion.h:36
void EndGame()
Definition: GameSetup.cpp:673
void wmi_Shutdown()
Definition: wmi.cpp:100
int m_iFontHeight
Definition: CConsole.h:90
void in_add_handler(InHandler handler)
Definition: input.cpp:39
int swprintf_s(wchar_t *buf, size_t max_chars, const wchar_t *fmt,...) WPRINTF_ARGS(3)
void EnableHTTP()
Call in main thread to enable the HTTP server.
Definition: Profiler2.cpp:157
float _11
Definition: Matrix3D.h:42
CGUIManager * g_GUI
Definition: GUIManager.cpp:32
bool SetPropertyInt(jsval obj, int name, const T &value, bool constant=false, bool enumerate=true)
Set the integer-named property on the given object.
static void Initialize()
Initialize ENet.
Definition: NetHost.cpp:70
int m_Height
Definition: Camera.h:36
bool g_WaterRefraction
Definition: Config.cpp:46
bool LoadDefaultScripts()
Call LoadScripts for each of the game&#39;s standard simulation script paths.
void SDL_Quit()
Definition: wsdl.cpp:1505
bool g_WaterShadows
Definition: Config.cpp:48
static const int SANE_TEX_QUALITY_DEFAULT
Definition: GameSetup.cpp:118
static void InitRenderer()
Definition: GameSetup.cpp:587
#define ERROR_TYPE(a, b)
Definition: Errors.h:96
CJoystick g_Joystick
Definition: Joystick.cpp:26
#define ARRAY_SIZE(name)
#define ERROR_GROUP(a)
Definition: Errors.h:87
size_t m_charsPerPage
Definition: CConsole.h:93
Public API for simulation system.
Definition: Simulation2.h:46
static void InitPs(bool setup_gui, const CStrW &gui_page, CScriptVal initData)
Definition: GameSetup.cpp:501
size_t os_cpu_MemorySize()
Definition: os_cpu.cpp:63
static size_t ChooseCacheSize()
Definition: GameSetup.cpp:365
void SetCursorBlinkRate(double rate)
Definition: CConsole.cpp:108
size_t wversion_Number()
Definition: wversion.cpp:65
#define g_Renderer
Definition: Renderer.h:61
#define CONSOLE_FONT
Definition: CConsole.h:43
LIB_API void debug_SetThreadName(const char *name)
inform the debugger of the current thread&#39;s name.
Definition: bdbg.cpp:126
Hotkey system.
#define TIMER_BEGIN(description)
Measures the time taken to execute code between BEGIN and END markers; displays it via debug_printf...
Definition: timer.h:133
#define LOGWARNING
Definition: CLogger.h:34
return ERR::VFS_DIR_NOT_FOUND if the given real path doesn&#39;t exist.
Definition: vfs.h:60
#define ARCH_IA32
Definition: arch.h:35
bool g_Particles
Definition: Config.cpp:50
CVideoMode g_VideoMode
Definition: VideoMode.cpp:42
#define ENSURE(expr)
ensure the expression &lt;expr&gt; evaluates to non-zero.
Definition: debug.h:282
void SDL_WM_SetCaption(const char *title, const char *icon)
Definition: wsdl.cpp:1442
void Shutdown()
Shut down after InitSDL/InitNonSDL, so that they can be used again.
Definition: VideoMode.cpp:308
static void Init()
Initialise global settings.
void CONFIG_Init(const CmdLineArgs &args)
Definition: Config.cpp:209
#define g_ScriptingHost
PIVFS CreateVfs(size_t cacheSize)
create an instance of a Virtual File System.
Definition: vfs.cpp:321
Status cursor_draw(const PIVFS &vfs, const wchar_t *name, int x, int y, bool forceGL)
Draw the cursor on-screen.
Definition: cursor.cpp:309
#define g_Profiler
Definition: Profile.h:147
void SetPlayerID(int playerID)
Definition: Game.cpp:254
CStr g_RenderPath
Definition: Config.cpp:56
static void InitSDL()
Definition: GameSetup.cpp:640
static void InitVfs(const CmdLineArgs &args, int flags)
Definition: GameSetup.cpp:428
CConsole * g_Console
Definition: CConsole.cpp:46
CProfiler2 g_Profiler2
Definition: Profiler2.cpp:35
void in_reset_handlers()
Definition: input.cpp:49
u32 PSRETURN
Definition: Errors.h:75
static void ScriptingInit()
Initializes GUI script classes.
Definition: CGUI.cpp:67
#define SDL_DEFAULT_REPEAT_DELAY
Definition: wsdl.h:146
Definition: Font.h:28
bool Has(const char *name) const
Test whether the given name was specified, as either -name or -name=value
Definition: CmdLineArgs.cpp:66
Definition: path.h:75
New profiler (complementing the older CProfileManager)
CScriptValRooted ReadJSONFile(const VfsPath &path)
Read a JSON file.
void timer_LatchStartTime()
timer_Time will subsequently return values relative to the current time.
Definition: timer.cpp:74
#define TIMER_END(description)
Definition: timer.h:134
#define file_stats_dump()
Definition: file_stats.h:114
void LoadHotkeys()
Definition: Hotkey.cpp:145
bool g_WaterRealDepth
Definition: Config.cpp:43
void SetMainThread()
Set the current thread as the &#39;main&#39; thread.
Definition: ThreadUtil.cpp:35
void UpdateGameAttributes(const CScriptVal &attrs, ScriptInterface &scriptInterface)
Call from the GUI to update the game setup attributes.
Definition: NetServer.cpp:945
virtual const char * what() const
Definition: Errors.cpp:453
static const size_t MiB
Definition: alignment.h:72
InReaction GlobalsInputHandler(const SDL_Event_ *ev)
Definition: Globals.cpp:40
int g_yres
Definition: Config.cpp:58
void StartGame(const CScriptValRooted &attribs, const std::string &savedState)
Definition: Game.cpp:261
void SetUserName(const CStrW &username)
Set the user&#39;s name that will be displayed to all players.
Definition: NetClient.cpp:123
JSObject * GetScriptObject()
See CGUI::GetScriptObject; applies to the currently active page.
Definition: GUIManager.cpp:290
ScriptInterface & GetScriptInterface() const
bool g_Quickstart
Definition: Config.cpp:61
const OsPath & Cache() const
Returns cache directory.
Definition: Paths.h:77
bool g_WaterFoam
Definition: Config.cpp:44
#define SAFE_DELETE(p)
delete memory ensuing from new and set the pointer to zero (thus making double-frees safe / a no-op) ...
bool undefined() const
Returns whether the value is uninitialised or is JSVAL_VOID.
Definition: ScriptVal.cpp:58
emphatically require full quality for this texture.
Definition: ogl_tex.h:173
bool Eval(const char *code)
InReaction game_view_handler(const SDL_Event_ *ev)
Definition: GameView.cpp:1066
static jsval ToJSVal(JSContext *cx, T const &val)
Convert a C++ type to a jsval.
bool g_ShowSky
Definition: Config.cpp:52
anything mounted from here should be included when building archives.
Definition: vfs.h:54
all real directories mounted during this operation will be watched for changes.
Definition: vfs.h:49
void h_mgr_shutdown()
Definition: h_mgr.cpp:816
#define SDL_INIT_NOPARACHUTE
Definition: wsdl.h:47
void(* translate_free)(const wchar_t *text)
Definition: app_hooks.h:185
void debug_filter_add(const wchar_t *tag)
debug output is very useful, but &quot;too much of a good thing can kill you&quot;.
Definition: debug.cpp:77
void cursor_shutdown()
Forcibly frees all cursor handles.
Definition: cursor.cpp:298
bool g_WaterReflection
Definition: Config.cpp:47
CGame * g_Game
Globally accessible pointer to the CGame object.
Definition: Game.cpp:56
void ShutdownGPU()
Call in main thread to shut down the GPU profiling support, before shutting down OpenGL.
Definition: Profiler2.cpp:181
Network server interface.
Definition: NetServer.h:97
#define SDL_EnableKeyRepeat(delay, interval)
Definition: wsdl.h:148
void Render()
Definition: CConsole.cpp:190
#define g_ConfigDB
Definition: ConfigDB.h:52
void Initialise()
Call in main thread to set up the profiler, before calling any other profiler functions.
Definition: Profiler2.cpp:141
void Render()
Definition: GameSetup.cpp:192
void RenderCursor(bool RenderingState)
enable/disable rendering of the cursor - this does not hide cursor, but reverts to OS style ...
Definition: GameSetup.cpp:1066
void(* bundle_logs)(FILE *f)
Definition: app_hooks.h:183
bool g_DoRenderCursor
Definition: GameSetup.cpp:116
void CancelLoad(const CStrW &message)
Definition: GameSetup.cpp:1326
jsval CloneValueFromOtherContext(ScriptInterface &otherContext, jsval val)
Construct a new value (usable in this ScriptInterface&#39;s context) by cloning a value from a different ...
CSimulation2 * GetSimulation2()
Get the pointer to the simulation2 object.
Definition: Game.h:136
intptr_t ssize_t
Definition: wposix_types.h:82
ScriptInterface & GetScriptInterface()
Definition: GUIManager.h:52
static std::vector< CStr > GetMods(const CmdLineArgs &args, bool dev)
Definition: GameSetup.cpp:414
store the texture at half its original resolution.
Definition: ogl_tex.h:195
#define TIMER(description)
Measures the time taken to execute code up until end of the current scope; displays it via debug_prin...
Definition: timer.h:108
bool GetProperty(jsval obj, const char *name, T &out)
Get the named property on the given object.
static InReaction InputThunk(const SDL_Event_ *ev)
InputThunk: Delegate to the singleton&#39;s Input() member function if the singleton has been initialized...
bool g_WaterNormal
Definition: Config.cpp:42
void RunHardwareDetection()
Runs hardware-detection script to adjust default config settings and/or emit warnings depending on th...
Definition: HWDetect.cpp:165
int SDL_Init(Uint32 flags)
Definition: wsdl.cpp:1495
const size_t WVERSION_XP64
Definition: wversion.h:34
#define PROFILE2_ATTR
Associates a string (with printf-style formatting) with the current region or event.
Definition: Profiler2.h:461
int SDL_EnableUNICODE(int enable)
Definition: wsdl.cpp:717
#define SDL_DEFAULT_REPEAT_INTERVAL
Definition: wsdl.h:147
bool g_NoGLVBO
Definition: Config.cpp:35
CGameView * GetView()
Get the pointer to the game view object.
Definition: Game.h:128
bool SetupConnection(const CStr &server)
Set up a connection to the remote networked server.
Definition: NetClient.cpp:130
static void RegisterJavascriptInterfaces()
Definition: GameSetup.cpp:319
bool ogl_HaveExtension(const char *ext)
check if an extension is supported by the OpenGL implementation.
Definition: ogl.cpp:187
void RenderLogger(bool RenderingState)
Definition: GameSetup.cpp:1061
store the texture at half the normal bit depth (4 bits per pixel component, as opposed to 8)...
Definition: ogl_tex.h:182
Wrapper class for OS paths used by the game.
Definition: Paths.h:27
void SwitchPage(const CStrW &name, CScriptVal initData)
Load a new GUI page and make it active.
Definition: GUIManager.cpp:69
void RegisterScriptFunctions(ScriptInterface &scriptInterface)
#define PROFILE3(name)
Definition: Profile.h:201
InReaction HotkeyInputHandler(const SDL_Event_ *ev)
Definition: Hotkey.cpp:175
bool g_ShadowPCF
Definition: Config.cpp:40
static void SetEnabled(bool doEnable)
Network client.
Definition: NetClient.h:57
bool g_Shadows
Definition: Config.cpp:39
void RecordGPUFrameStart()
Definition: Profiler2.cpp:205
In-game console.
Definition: CConsole.h:52
void EnableGPU()
Call in main thread to enable the GPU profiling support, after OpenGL has been initialised.
Definition: Profiler2.cpp:174
bool g_DoRenderGui
Definition: GameSetup.cpp:114
int m_Width
Definition: Camera.h:35
bool GetPropertyInt(jsval obj, int name, T &out)
Get the integer-named property on the given object.
void EarlyInit()
initialize global modules that are be needed before Init.
Definition: GameSetup.cpp:827
bool IsGameStarted() const
Get m_GameStarted.
Definition: Game.h:110
#define g_ProfileViewer
static void FixLocales()
Definition: GameSetup.cpp:821
#define DEBUG_DISPLAY_ERROR(description)
Definition: debug.h:197
void psTranslateFree(const wchar_t *text)
Definition: Pyrogenesis.cpp:39
const OsPath & Config() const
Returns config file directory.
Definition: Paths.h:69
bool IsMainThread()
Returns whether the current thread is the &#39;main&#39; thread (i.e.
Definition: ThreadUtil.cpp:25
static void InitInput()
Definition: GameSetup.cpp:541
jsval get() const
Returns the current value (or JSVAL_VOID if uninitialised).
Definition: ScriptVal.cpp:45
int g_mouse_x
Definition: Globals.cpp:30
bool g_NoGLS3TC
Definition: Config.cpp:33
bool SetFullscreen(bool fullscreen)
Switch to fullscreen or windowed mode.
Definition: VideoMode.cpp:363
#define SDL_GetError()
Definition: wsdl.h:334
Abstraction around a SpiderMonkey JSContext.
void ogl_WarnIfError()
raise a warning (break into the debugger) if an OpenGL error is pending.
Definition: ogl.cpp:398
#define PROFILE3_GPU(name)
Definition: Profile.h:204
#define debug_warn(expr)
display the error dialog with the given text.
Definition: debug.h:324
void Draw()
See CGUI::Draw; applies to all loaded pages.
Definition: GUIManager.cpp:276
static void CreateSoundManager()
void tex_codec_register_all()
Manually register codecs.
Definition: tex_codec.cpp:134
void ogl_tex_set_defaults(int q_flags, GLint filter)
Change default settings - these affect performance vs.
Definition: ogl_tex.cpp:206
bool undefined() const
Returns whether the value is JSVAL_VOID.
Definition: ScriptVal.h:43
void SetOrtho(float l, float r, float b, float t, float n, float f)
Definition: Matrix3D.cpp:47
#define SDL_INIT_VIDEO
Definition: wsdl.h:43
External interface to the GUI system.
Definition: GUIManager.h:45
bool SetProperty(jsval obj, const char *name, const T &value, bool constant=false, bool enumerate=true)
Set the named property on the given object.
static void SetTextureQuality(int quality)
Definition: GameSetup.cpp:120
const wchar_t * psTranslate(const wchar_t *text)
Definition: Pyrogenesis.cpp:30
static void ShutdownSDL()
Definition: GameSetup.cpp:666
size_t rand(size_t min_inclusive, size_t max_exclusive)
return random integer in [min, max).
Definition: rand.cpp:53
void RecordGPUFrameEnd()
Definition: Profiler2.cpp:211
PSRETURN ReallyStartGame()
Game initialization has been completed.
Definition: Game.cpp:198
bool g_DisableAudio
Definition: Config.cpp:62
int g_mouse_y
Definition: Globals.cpp:30
const size_t WVERSION_2K
Definition: wversion.h:32
holds a function pointer (allowed to be NULL) for each hook.
Definition: app_hooks.h:179
Status CreateDirectories(const OsPath &path, mode_t mode)
int m_X
Definition: Camera.h:33
bool DirectoryExists(const OsPath &path)
Definition: file_system.cpp:37
PIVFS g_VFS
Definition: Filesystem.cpp:30
bool InitSDL()
Initialise the video mode, for use in an SDL-using application.
Definition: VideoMode.cpp:191
bool HasPages()
Returns whether there are any current pages.
Definition: GUIManager.cpp:64
void app_hooks_update(AppHooks *new_ah)
update the app hook function pointers.
Definition: app_hooks.cpp:115
void tex_codec_unregister_all()
remove all codecs that have been registered.
Definition: tex_codec.cpp:56
bool g_NoGLAutoMipmap
Definition: Config.cpp:34
void UpdateScreenSize(int w, int h)
Definition: CConsole.cpp:83
const size_t WVERSION_VISTA
Definition: wversion.h:35
void SendEventToAll(const CStr &eventName)
See CGUI::SendEventToAll; applies to the currently active page.
Definition: GUIManager.cpp:256
#define SDL_INIT_TIMER
Definition: wsdl.h:45
void Initialize()
Definition: UserReport.cpp:573
static void Deinitialize()
Deinitialize ENet.
Definition: NetHost.cpp:76
void debug_printf(const wchar_t *fmt,...)
write a formatted string to the debug channel, subject to filtering (see below).
Definition: debug.cpp:142
const OsPath & Logs() const
Returns logs directory.
Definition: Paths.h:85
ErrorReactionInternal psDisplayError(const wchar_t *text, size_t flags)
Definition: GameSetup.cpp:393
InReaction conInputHandler(const SDL_Event_ *ev)
Definition: CConsole.cpp:694
bool g_WaterCoastalWaves
Definition: Config.cpp:45
void timer_DisplayClientTotals()
display all clients&#39; totals; does not reset them.
Definition: timer.cpp:181
ErrorReactionInternal
all choices offered by the error dialog.
Definition: debug.h:154
void Deinitialize()
Definition: UserReport.cpp:590
void ColorActivateFastImpl()
Definition: Color.cpp:80
const char * ogl_HaveExtensions(int dummy,...)
check if a list of extensions are all supported (as determined by ogl_HaveExtension).
Definition: ogl.cpp:266
mark a directory replaceable, so that when writing a file to this path new real directories will be c...
Definition: vfs.h:77