Rigs of Rods 2023.09
Soft-body Physics Simulation
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
Loading...
Searching...
No Matches
AppContext.cpp
Go to the documentation of this file.
1/*
2 This source file is part of Rigs of Rods
3 Copyright 2005-2012 Pierre-Michel Ricordel
4 Copyright 2007-2012 Thomas Fischer
5 Copyright 2013-2020 Petr Ohlidal
6
7 For more information, see http://www.rigsofrods.org/
8
9 Rigs of Rods is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License version 3, as
11 published by the Free Software Foundation.
12
13 Rigs of Rods is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with Rigs of Rods. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include "AppContext.h"
23
24#include "AdvancedScreen.h"
25#include "Actor.h"
26#include "CameraManager.h"
27#include "ChatSystem.h"
28#include "Console.h"
29#include "ContentManager.h"
30#include "DashBoardManager.h"
31#include "Engine.h"
32#include "ErrorUtils.h"
33#include "GameContext.h"
34#include "GUIManager.h"
35#include "GUI_LoadingWindow.h"
36#include "GUI_MainSelector.h"
39#include "InputEngine.h"
40#include "Language.h"
41#include "PlatformUtils.h"
42#include "RoRVersion.h"
43#include "OverlayWrapper.h"
44
45#ifdef USE_ANGELSCRIPT
46# include "ScriptEngine.h"
47#endif
48
49#ifdef _WIN32
50# include <windows.h>
51#endif
52
53#include <iomanip>
54#include <sstream>
55#include <string>
56#include <ctime>
57
58using namespace RoR;
59
60// --------------------------
61// Input handling
62
76
77bool AppContext::mouseMoved(const OIS::MouseEvent& arg) // overrides OIS::MouseListener
78{
82
83 if (!ImGui::GetIO().WantCaptureMouse) // true if mouse is over any window
84 {
85 if (!App::GetOverlayWrapper() || !App::GetOverlayWrapper()->handleMouseMoved()) // update the old airplane / autopilot gui
86 {
87 if (!App::GetCameraManager()->handleMouseMoved())
88 {
90 }
91 }
92 }
93
94 return true;
95}
96
97bool AppContext::mousePressed(const OIS::MouseEvent& arg, OIS::MouseButtonID _id) // overrides OIS::MouseListener
98{
100 App::GetGuiManager()->GetImGui().SetMouseButtonState(_id, /*down:*/true);
102
103 if (!ImGui::GetIO().WantCaptureMouse) // true if mouse is over any window
104 {
105 if (!App::GetOverlayWrapper() || !App::GetOverlayWrapper()->handleMousePressed()) // update the old airplane / autopilot gui
106 {
107 if (App::app_state->getEnum<AppState>() == AppState::SIMULATION)
108 {
111 }
112 }
113 }
114
115 return true;
116}
117
118bool AppContext::mouseReleased(const OIS::MouseEvent& arg, OIS::MouseButtonID _id) // overrides OIS::MouseListener
119{
121 App::GetGuiManager()->GetImGui().SetMouseButtonState(_id, /*down:*/false);
123
124 if (!ImGui::GetIO().WantCaptureMouse) // true if mouse is over any window
125 {
126 if (!App::GetOverlayWrapper() || !App::GetOverlayWrapper()->handleMouseReleased()) // update the old airplane / autopilot gui
127 {
128 if (App::app_state->getEnum<AppState>() == AppState::SIMULATION)
129 {
131 }
132 }
133 }
134
135 return true;
136}
137
138bool AppContext::keyPressed(const OIS::KeyEvent& arg)
139{
141
142 if (!App::GetGuiManager()->IsGuiCaptureKeyboardRequested() &&
143 !ImGui::GetIO().WantCaptureKeyboard)
144 {
146 }
147
148 return true;
149}
150
151bool AppContext::keyReleased(const OIS::KeyEvent& arg)
152{
154
155 if (!App::GetGuiManager()->IsGuiCaptureKeyboardRequested() &&
156 !ImGui::GetIO().WantCaptureKeyboard)
157 {
159 }
160 else if (App::GetInputEngine()->isKeyDownEffective(arg.key))
161 {
162 // If capturing is requested, still pass release events for already-pressed keys.
164 }
165
166 return true;
167}
168
169bool AppContext::buttonPressed(const OIS::JoyStickEvent& arg, int) { App::GetInputEngine()->ProcessJoystickEvent(arg); return true; }
170bool AppContext::buttonReleased(const OIS::JoyStickEvent& arg, int) { App::GetInputEngine()->ProcessJoystickEvent(arg); return true; }
171bool AppContext::axisMoved(const OIS::JoyStickEvent& arg, int) { App::GetInputEngine()->ProcessJoystickEvent(arg); return true; }
172bool AppContext::sliderMoved(const OIS::JoyStickEvent& arg, int) { App::GetInputEngine()->ProcessJoystickEvent(arg); return true; }
173bool AppContext::povMoved(const OIS::JoyStickEvent& arg, int) { App::GetInputEngine()->ProcessJoystickEvent(arg); return true; }
174
175void AppContext::windowResized(Ogre::RenderWindow* rw)
176{
177 App::GetInputEngine()->windowResized(rw); // Update mouse area
179 {
181 }
182 if (App::sim_state->getEnum<AppState>() == RoR::AppState::SIMULATION)
183 {
185 {
186 actor->ar_dashboard->windowResized();
187 }
188 }
189}
190
191void AppContext::windowFocusChange(Ogre::RenderWindow* rw)
192{
193 // If you alt+TAB out of the window while any mouse button is down, OIS will not release it until you click in the window again.
194 // See https://github.com/RigsOfRods/rigs-of-rods/issues/2468
195 // To work around, we reset all internal mouse button states here and pay attention not to get them polluted by OIS again.
197 // Same applies to keyboard keys - reset them manually otherwise OIS will hold them 'down' the entire time.
199}
200
201// --------------------------
202// Rendering
203
204void AppContext::SetRenderWindowIcon(Ogre::RenderWindow* rw)
205{
206#ifdef _WIN32
207 size_t hWnd = 0;
208 rw->getCustomAttribute("WINDOW", &hWnd);
209
210 char buf[MAX_PATH];
211 ::GetModuleFileNameA(0, (LPCH)&buf, MAX_PATH);
212
213 HINSTANCE instance = ::GetModuleHandleA(buf);
214 HICON hIcon = ::LoadIconA(instance, MAKEINTRESOURCEA(101));
215 if (hIcon)
216 {
217 ::SendMessageA((HWND)hWnd, WM_SETICON, 1, (LPARAM)hIcon);
218 ::SendMessageA((HWND)hWnd, WM_SETICON, 0, (LPARAM)hIcon);
219 }
220#endif // _WIN32
221}
222
224{
225 // Create 'OGRE root' facade
226 // * leave 'plugins' param empty, we load manually below
227 // * note file 'ogre.cfg' isn't read immediatelly but only after calling 'restoreConfig()' below.
228 std::string log_filepath = PathCombine(App::sys_logs_dir->getStr(), "RoR.log");
229 std::string cfg_filepath = PathCombine(App::sys_config_dir->getStr(), "ogre.cfg");
230 LOG(fmt::format("[RoR|Startup|Rendering] Creating OGRE renderer Root object, config='{}'", cfg_filepath));
231 m_ogre_root = new Ogre::Root("", cfg_filepath, log_filepath);
232
233 // load OGRE plugins manually
234#ifdef _DEBUG
235 std::string plugins_path = PathCombine(RoR::App::sys_process_dir->getStr(), "plugins_d.cfg");
236#else
237 std::string plugins_path = PathCombine(RoR::App::sys_process_dir->getStr(), "plugins.cfg");
238#endif
239 LOG(fmt::format("[RoR|Startup|Rendering] Loading OGRE renderer plugins config '{}'.", plugins_path));
240 try
241 {
242 Ogre::ConfigFile cfg;
243 cfg.load(plugins_path);
244 std::string plugin_dir = cfg.getSetting("PluginFolder", /*section=*/"", /*default=*/App::sys_process_dir->getStr());
245 Ogre::StringVector plugins = cfg.getMultiSetting("Plugin");
246 for (Ogre::String plugin_filename: plugins)
247 {
248 try
249 {
250 m_ogre_root->loadPlugin(PathCombine(plugin_dir, plugin_filename));
251 }
252 catch (Ogre::Exception&) {} // Logged by OGRE
253 }
254 }
255 catch (Ogre::Exception& e)
256 {
258 _L("Startup error"),
259 fmt::format(_L("Could not load file '{}' - make sure the game is installed correctly.\n\nDetailed info: {}"), plugins_path, e.getDescription()));
260 return false;
261 }
262
263 // Load renderer configuration
264 bool autodetect_resolution = false;
265 try
266 {
267 if (!m_ogre_root->restoreConfig())
268 {
269 autodetect_resolution = true;
270 LOG(fmt::format("[RoR|Startup|Rendering] WARNING - invalid 'ogre.cfg', selecting render plugin manually..."));
271
272 const auto render_systems = App::GetAppContext()->GetOgreRoot()->getAvailableRenderers();
273 if (!render_systems.empty())
274 {
275 LOG(fmt::format("[RoR|Startup|Rendering] Auto-selected renderer plugin '{}'", render_systems.front()->getName()));
276 m_ogre_root->setRenderSystem(render_systems.front());
277 }
278 else
279 {
280 ErrorUtils::ShowError (_L("Startup error"), _L("No render system plugin available. Check your plugins.cfg"));
281 return false;
282 }
283 }
284 }
285 catch (Ogre::Exception& e)
286 {
287 ErrorUtils::ShowError (_L("Error restoring settings from 'ogre.cfg'"), e.getDescription());
288 return false;
289 }
290
291 const auto rs = m_ogre_root->getRenderSystemByName(App::app_rendersys_override->getStr());
292 if (rs != nullptr && rs != m_ogre_root->getRenderSystem())
293 {
294 LOG(fmt::format("[RoR|Startup|Rendering] Setting renderer '{}' on behalf of 'app_rendersys_override' (user selection via Settings UI)", rs->getName()));
295 // The user has selected a different render system during the previous session.
296 m_ogre_root->setRenderSystem(rs);
297 m_ogre_root->saveConfig();
298 }
300
301 // Start the renderer
302 LOG(fmt::format("[RoR|Startup|Rendering] Starting renderer '{}' (without auto-creating render window)", m_ogre_root->getRenderSystem()->getName()));
303 m_ogre_root->initialise(/*createWindow=*/false);
304
305 // Review configuration options
306 Ogre::ConfigOptionMap ropts = m_ogre_root->getRenderSystem()->getConfigOptions();
307 std::stringstream ropts_log;
308 for (auto& pair: ropts)
309 {
310 ropts_log << " " << pair.first << " = " << pair.second.currentValue << " (";
311 for (auto& val: pair.second.possibleValues)
312 {
313 ropts_log << val << ", ";
314 }
315 ropts_log << ")\n";
316 }
317 LOG(fmt::format("[RoR|Startup|Rendering] Renderer options as reported by OGRE:\n{}", ropts_log.str()));
318
319 // Configure the render window
320 Ogre::NameValuePairList miscParams;
321 miscParams["FSAA"] = ropts["FSAA"].currentValue;
322 miscParams["vsync"] = ropts["VSync"].currentValue;
323 miscParams["gamma"] = ropts["sRGB Gamma Conversion"].currentValue;
324 if (!App::diag_allow_window_resize->getBool())
325 {
326 miscParams["border"] = "fixed";
327 }
328#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
329 const auto rd = ropts["Rendering Device"];
330 const auto it = std::find(rd.possibleValues.begin(), rd.possibleValues.end(), rd.currentValue);
331 const int idx = std::distance(rd.possibleValues.begin(), it);
332 miscParams["monitorIndex"] = Ogre::StringConverter::toString(idx);
333 miscParams["windowProc"] = Ogre::StringConverter::toString((size_t)OgreBites::WindowEventUtilities::_WndProc);
334#endif
335
336 // Validate rendering resolution
337 Ogre::uint32 width, height;
338 std::istringstream mode (ropts["Video Mode"].currentValue);
339 Ogre::String token;
340 mode >> width;
341 mode >> token; // 'x' as seperator between width and height
342 mode >> height;
343
344 if(width < 800) width = 800;
345 if(height < 600) height = 600;
346
347 if (autodetect_resolution)
348 {
349 for (auto& p_mode_str: ropts["Video Mode"].possibleValues)
350 {
351 Ogre::uint32 p_width, p_height;
352 std::istringstream p_mode (p_mode_str);
353 p_mode >> p_width;
354 p_mode >> token; // 'x' as seperator between width and height
355 p_mode >> p_height;
356 if (p_width >= width && p_height >= height)
357 {
358 width = p_width;
359 height = p_height;
360 m_ogre_root->getRenderSystem()->setConfigOption("Video Mode", p_mode_str);
361 }
362 }
363
364 LOG(fmt::format("[RoR|Startup|Rendering] WARNING - invalid 'ogre.cfg', auto-detected resolution {}x{}", width, height));
365 m_ogre_root->saveConfig();
366 }
367
368 // Review render window settings
369 std::stringstream miscParams_log;
370 for (auto& pair: miscParams)
371 {
372 miscParams_log << " " << pair.first << " = " << pair.second << "\n";
373 }
374 LOG(fmt::format("[RoR|Startup|Rendering] Creating render window with settings:\n{}", miscParams_log.str()));
375
376 // Create render window
377 m_render_window = Ogre::Root::getSingleton().createRenderWindow (
378 "Rigs of Rods version " + Ogre::String (ROR_VERSION_STRING),
379 width, height, ropts["Full Screen"].currentValue == "Yes", &miscParams);
380 OgreBites::WindowEventUtilities::_addRenderWindow(m_render_window);
381 OgreBites::WindowEventUtilities::addWindowEventListener(m_render_window, this);
382
384 m_render_window->setActive(true);
385
386 // Create viewport (without camera)
387 m_viewport = m_render_window->addViewport(/*camera=*/nullptr);
388 m_viewport->setBackgroundColour(Ogre::ColourValue::Black);
389
390 return true;
391}
392
393Ogre::RenderWindow* AppContext::CreateCustomRenderWindow(std::string const& window_name, int width, int height)
394{
395 Ogre::NameValuePairList misc;
396 Ogre::ConfigOptionMap ropts = m_ogre_root->getRenderSystem()->getConfigOptions();
397 misc["FSAA"] = Ogre::StringConverter::parseInt(ropts["FSAA"].currentValue, 0);
398
399 Ogre::RenderWindow* rw = Ogre::Root::getSingleton().createRenderWindow(window_name, width, height, false, &misc);
400 return rw;
401}
402
404{
405 const std::time_t time = std::time(nullptr);
406 const int index = (time == m_prev_screenshot_time) ? m_prev_screenshot_index+1 : 1;
407
408 std::stringstream stamp;
409 stamp << std::put_time(std::localtime(&time), "%Y-%m-%d_%H-%M-%S") << "_" << index
411 std::string path = PathCombine(App::sys_screenshot_dir->getStr(), "screenshot_") + stamp.str();
412
413 if (App::app_screenshot_format->getStr() == "png")
414 {
416
417 png.addData("User_NickName", App::mp_player_name->getStr());
418 png.addData("User_Language", App::app_language->getStr());
419
420 if (App::app_state->getEnum<AppState>() == AppState::SIMULATION &&
421 App::GetGameContext()->GetPlayerActor())
422 {
423 png.addData("Truck_file", App::GetGameContext()->GetPlayerActor()->ar_filename);
424 png.addData("Truck_name", App::GetGameContext()->GetPlayerActor()->getTruckName());
425 }
426 if (App::GetGameContext()->GetTerrain())
427 {
428 png.addData("Terrn_file", App::sim_terrain_name->getStr());
429 png.addData("Terrn_name", App::sim_terrain_gui_name->getStr());
430 }
431 if (App::mp_state->getEnum<MpState>() == MpState::CONNECTED)
432 {
433 png.addData("MP_ServerName", App::mp_server_host->getStr());
434 }
435
436 png.write();
437 }
438 else
439 {
440 m_render_window->writeContentsToFile(path);
441 }
442
444 _L("Screenshot: ") + stamp.str());
445
448}
449
451{
452 if (!val && !m_windowed_fix)
453 {
454 // Workaround OGRE glitch - badly aligned viewport after first full->window switch
455 // Observed on Win10/OpenGL (GeForce GTX 660)
456 m_render_window->setFullscreen(false, m_render_window->getWidth()-1, m_render_window->getHeight()-1);
457 m_render_window->setFullscreen(false, m_render_window->getWidth()+1, m_render_window->getHeight()+1);
458 }
459 else
460 {
461 m_render_window->setFullscreen(val, m_render_window->getWidth(), m_render_window->getHeight());
462 }
463}
464
465// --------------------------
466// Program paths and logging
467
469{
470 // Process directory
471 std::string exe_path = RoR::GetExecutablePath();
472 if (exe_path.empty())
473 {
474 ErrorUtils::ShowError(_L("Startup error"), _L("Error while retrieving program directory path"));
475 return false;
476 }
477 App::sys_process_dir->setStr(RoR::GetParentDirectory(exe_path.c_str()).c_str());
478
479 // RoR's home directory
480 std::string local_userdir = PathCombine(App::sys_process_dir->getStr(), "config"); // TODO: Think of a better name, this is ambiguious with ~/.rigsofrods/config which stores configfiles! ~ only_a_ptr, 02/2018
481 if (FolderExists(local_userdir))
482 {
483 // It's a portable installation
484 App::sys_user_dir->setStr(local_userdir.c_str());
485 }
486 else
487 {
488 // Default location - user's home directory
489 std::string user_home = RoR::GetUserHomeDirectory();
490 if (user_home.empty())
491 {
492 ErrorUtils::ShowError(_L("Startup error"), _L("Error while retrieving user directory path"));
493 return false;
494 }
495 RoR::Str<500> ror_homedir;
496#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
497 ror_homedir << user_home << PATH_SLASH << "My Games";
498 CreateFolder(ror_homedir.ToCStr());
499 ror_homedir << PATH_SLASH << "Rigs of Rods";
500#elif OGRE_PLATFORM == OGRE_PLATFORM_LINUX
501 char* env_SNAP = getenv("SNAP_USER_COMMON");
502 if(env_SNAP)
503 ror_homedir = env_SNAP;
504 else
505 ror_homedir << user_home << PATH_SLASH << ".rigsofrods";
506#elif OGRE_PLATFORM == OGRE_PLATFORM_APPLE
507 ror_homedir << user_home << PATH_SLASH << "RigsOfRods";
508#endif
509 CreateFolder(ror_homedir.ToCStr ());
510 App::sys_user_dir->setStr(ror_homedir.ToCStr ());
511 }
512
513 return true;
514}
515
517{
518 std::string logs_dir = PathCombine(App::sys_user_dir->getStr(), "logs");
519 CreateFolder(logs_dir);
520 App::sys_logs_dir->setStr(logs_dir.c_str());
521
522 auto ogre_log_manager = OGRE_NEW Ogre::LogManager();
523 std::string rorlog_path = PathCombine(logs_dir, "RoR.log");
524 Ogre::Log* rorlog = ogre_log_manager->createLog(rorlog_path, true, true);
525 rorlog->stream() << "[RoR] Rigs of Rods (www.rigsofrods.org) version " << ROR_VERSION_STRING;
526 std::time_t t = std::time(nullptr);
527 rorlog->stream() << "[RoR] Current date: " << std::put_time(std::localtime(&t), "%Y-%m-%d");
528
529 rorlog->addListener(App::GetConsole()); // Allow console to intercept log messages
530}
531
533{
534 std::string process_dir = PathCombine(App::sys_process_dir->getStr(), "resources");
535#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
536 if (!FolderExists(process_dir))
537 {
538 process_dir = "/usr/share/rigsofrods/resources/";
539 }
540#endif
541 if (!FolderExists(process_dir))
542 {
543 ErrorUtils::ShowError(_L("Startup error"), _L("Resources folder not found. Check if correctly installed."));
544 return false;
545 }
546 App::sys_resources_dir->setStr(process_dir);
547 return true;
548}
549
551{
552 Ogre::String src_path = PathCombine(App::sys_resources_dir->getStr(), "skeleton.zip");
553 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(src_path, "Zip", "SrcRG");
554 Ogre::FileInfoListPtr fl = Ogre::ResourceGroupManager::getSingleton().findResourceFileInfo("SrcRG", "*", true);
555 if (fl->empty())
556 {
557 ErrorUtils::ShowError(_L("Startup error"), _L("Faulty resource folder. Check if correctly installed."));
558 return false;
559 }
560 Ogre::String dst_path = PathCombine(App::sys_user_dir->getStr(), "");
561 for (auto file : *fl)
562 {
563 CreateFolder(dst_path + file.basename);
564 }
565 fl = Ogre::ResourceGroupManager::getSingleton().findResourceFileInfo("SrcRG", "*");
566 if (fl->empty())
567 {
568 ErrorUtils::ShowError(_L("Startup error"), _L("Faulty resource folder. Check if correctly installed."));
569 return false;
570 }
571 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(dst_path, "FileSystem", "DstRG", false, false);
572 for (auto file : *fl)
573 {
574 if (file.uncompressedSize == 0)
575 continue;
576 Ogre::String path = file.path + file.basename;
577 if (!Ogre::ResourceGroupManager::getSingleton().findResourceFileInfo("DstRG", path)->empty())
578 continue;
579 Ogre::DataStreamPtr src_ds = Ogre::ResourceGroupManager::getSingleton().openResource(path, "SrcRG");
580 Ogre::DataStreamPtr dst_ds = Ogre::ResourceGroupManager::getSingleton().createResource(path, "DstRG");
581 std::vector<char> buf(src_ds->size());
582 size_t read = src_ds->read(buf.data(), src_ds->size());
583 if (read > 0)
584 {
585 dst_ds->write(buf.data(), read);
586 }
587 }
588 Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup("SrcRG");
589 Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup("DstRG");
590
591 return true;
592}
593
595{
596#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
597 Ogre::String old_ror_homedir = Ogre::StringUtil::format("%s\\Rigs of Rods 0.4", RoR::GetUserHomeDirectory().c_str());
598 if(FolderExists(old_ror_homedir))
599 {
600 if (!FileExists(Ogre::StringUtil::format("%s\\OBSOLETE_FOLDER.txt", old_ror_homedir.c_str())))
601 {
602 Ogre::String obsoleteMessage = Ogre::StringUtil::format("This folder is obsolete, please move your mods to %s", App::sys_user_dir->getStr());
603 try
604 {
605 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(old_ror_homedir, "FileSystem", "homedir", false, false);
606 Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton().createResource("OBSOLETE_FOLDER.txt", "homedir");
607 stream->write(obsoleteMessage.c_str(), obsoleteMessage.length());
608 Ogre::ResourceGroupManager::getSingleton().destroyResourceGroup("homedir");
609 }
610 catch (std::exception & e)
611 {
612 RoR::LogFormat("Error writing to %s, message: '%s'", old_ror_homedir.c_str(), e.what());
613 }
614 Ogre::String message = Ogre::StringUtil::format(
615 "Welcome to Rigs of Rods %s\nPlease note that the mods folder has moved to:\n\"%s\"\nPlease move your mods to the new folder to continue using them",
617 App::sys_user_dir->getStr()
618 );
619
620 RoR::App::GetGuiManager()->ShowMessageBox("Obsolete folder detected", message.c_str());
621 }
622 }
623#endif // OGRE_PLATFORM_WIN32
624}
625
627{
628 m_mainthread_id = std::this_thread::get_id();
629
630 // This cannot be done earlier as it uses the above thread ID to assert() against invalid access.
632}
System integration layer; inspired by OgreBites::ApplicationContext.
void LOG(const char *msg)
Legacy alias - formerly a macro.
#define _L
Game state manager and message-queue provider.
Handles controller inputs from player.
Platform-specific utilities. We use narrow UTF-8 encoded strings as paths. Inspired by http://utf8eve...
const char *const ROR_VERSION_STRING_SHORT
const char *const ROR_VERSION_STRING
void addData(Ogre::String name, Ogre::String value)
void InjectKeyReleased(const OIS::KeyEvent &arg)
void InjectMouseMoved(const OIS::MouseEvent &arg)
Definition OgreImGui.cpp:89
void ResetAllMouseButtons()
void SetMouseButtonState(OIS::MouseButtonID id, bool down)
Definition OgreImGui.cpp:99
void InjectKeyPressed(const OIS::KeyEvent &arg)
ActorPtrVec & GetActors()
Ogre::Root * GetOgreRoot()
Definition AppContext.h:65
RoR::ForceFeedback m_force_feedback
Definition AppContext.h:105
bool SetUpConfigSkeleton()
virtual bool buttonPressed(const OIS::JoyStickEvent &arg, int button) override
void SetUpObsoleteConfMarker()
virtual bool mouseMoved(const OIS::MouseEvent &arg) override
Ogre::RenderWindow * CreateCustomRenderWindow(std::string const &name, int width, int height)
bool SetUpProgramPaths()
bool m_windowed_fix
Workaround OGRE glitch when switching from fullscreen.
Definition AppContext.h:100
virtual bool mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id) override
bool SetUpResourcesDir()
virtual bool sliderMoved(const OIS::JoyStickEvent &arg, int) override
Ogre::Viewport * m_viewport
Definition AppContext.h:99
virtual bool povMoved(const OIS::JoyStickEvent &arg, int) override
virtual bool buttonReleased(const OIS::JoyStickEvent &arg, int button) override
virtual bool axisMoved(const OIS::JoyStickEvent &arg, int axis) override
virtual bool mouseReleased(const OIS::MouseEvent &arg, OIS::MouseButtonID id) override
int m_prev_screenshot_index
Definition AppContext.h:103
void SetRenderWindowIcon(Ogre::RenderWindow *rw)
virtual void windowFocusChange(Ogre::RenderWindow *rw) override
void CaptureScreenshot()
virtual bool keyPressed(const OIS::KeyEvent &arg) override
Ogre::RenderWindow * m_render_window
Definition AppContext.h:98
virtual bool keyReleased(const OIS::KeyEvent &arg) override
std::thread::id m_mainthread_id
Definition AppContext.h:107
Ogre::Root * m_ogre_root
Definition AppContext.h:97
std::time_t m_prev_screenshot_time
Definition AppContext.h:102
void ActivateFullscreen(bool val)
virtual void windowResized(Ogre::RenderWindow *rw) override
std::string const & getStr() const
Definition CVar.h:95
void setStr(std::string const &str)
Definition CVar.h:83
Definition CacheSystem.h:56
@ CONSOLE_MSGTYPE_INFO
Generic message.
Definition Console.h:60
void putMessage(MessageArea area, MessageType type, std::string const &msg, std::string icon="")
Definition Console.cpp:103
@ CONSOLE_SYSTEM_NOTICE
Definition Console.h:51
OgreImGui & GetImGui()
Definition GUIManager.h:167
void ShowMessageBox(const char *title, const char *text, bool allow_close=true, const char *btn1_text="OK", const char *btn2_text=nullptr)
SceneMouse & GetSceneMouse()
CacheEntryPtr m_dummy_cache_selection
ActorManager * GetActorManager()
void SetKeyboardListener(OIS::KeyListener *obj)
void ProcessKeyRelease(const OIS::KeyEvent &arg)
void processMouseMotionEvent(const OIS::MouseEvent &arg)
void SetJoystickListener(OIS::JoyStickListener *obj)
void ProcessJoystickEvent(const OIS::JoyStickEvent &arg)
void windowResized(Ogre::RenderWindow *rw)
void processMouseReleaseEvent(const OIS::MouseEvent &arg, OIS::MouseButtonID _id)
void resetKeysAndMouseButtons()
void ProcessKeyPress(const OIS::KeyEvent &arg)
void SetMouseListener(OIS::MouseListener *obj)
void processMousePressEvent(const OIS::MouseEvent &arg, OIS::MouseButtonID _id)
bool handleMousePressed()
bool handleMouseMoved()
bool handleMouseReleased()
Wrapper for classic c-string (local buffer) Refresher: strlen() excludes '\0' terminator; strncat() A...
Definition Str.h:36
const char * ToCStr() const
Definition Str.h:46
void CreateFolder(const char *path)
Path must be UTF-8 encoded.
std::string GetExecutablePath()
Returns UTF-8 path or empty string on error.
std::string GetUserHomeDirectory()
Returns UTF-8 path or empty string on error.
bool FolderExists(const char *path)
Path must be UTF-8 encoded.
char PATH_SLASH
std::string GetParentDirectory(const char *src_buff)
Returns UTF-8 path without trailing slash.
std::string PathCombine(std::string a, std::string b)
bool FileExists(const char *path)
Path must be UTF-8 encoded.
CVar * mp_player_name
CVar * io_ffb_enabled
AppContext * GetAppContext()
CVar * app_screenshot_format
CVar * sim_state
OverlayWrapper * GetOverlayWrapper()
InputEngine * GetInputEngine()
CVar * diag_allow_window_resize
CVar * app_language
CVar * sys_logs_dir
CVar * sim_terrain_name
CVar * app_rendersys_override
CVar * sim_terrain_gui_name
CameraManager * GetCameraManager()
GUIManager * GetGuiManager()
GameContext * GetGameContext()
CVar * sys_config_dir
CVar * app_state
CVar * mp_state
CVar * sys_user_dir
Console * GetConsole()
CVar * sys_screenshot_dir
void CreateInputEngine()
CVar * sys_resources_dir
CVar * mp_server_host
CVar * sys_process_dir
void LogFormat(const char *format,...)
Improved logging utility. Uses fixed 2Kb buffer.
static int ShowError(const std::string &title, const std::string &message)
shows a simple error message box