Skyscraper 2.0
hal.cpp
Go to the documentation of this file.
1/*
2 Skyscraper 2.0 - Hardware Abstraction Layer
3 Copyright (C)2004-2024 Ryan Thoryk
4 https://www.skyscrapersim.net
5 https://sourceforge.net/projects/skyscraper/
6 Contact - ryan@skyscrapersim.net
7
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
12
13 This program 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 this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21*/
22
23//OGRE interfaces
24#include <OgreRoot.h>
25#include <OgreRenderWindow.h>
26#include <OgreConfigFile.h>
27#include <OgreFontManager.h>
28#include <OgreRectangle2D.h>
29#include <OgreRTShaderSystem.h>
30#include <OgreBitesConfigDialog.h>
31#include <OgreSGTechniqueResolverListener.h>
32#include <OgreOverlaySystem.h>
33
34#ifndef DISABLE_SOUND
35 //FMOD
36 #include <fmod_errors.h>
37#endif
38
39//OpenXR interfaces
40#if USING_OPENXR
42#endif
43
44//Linux malloc support
45#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
46#include "malloc.h"
47#endif
48
49#include <iostream>
50
51//simulator interfaces
52#include "globals.h"
53#include "sbs.h"
54#include "vm.h"
55#include "camera.h"
56#include "scenenode.h"
57#include "enginecontext.h"
58#include "hal.h"
59#include "gui.h"
60#include "profiler.h"
61
62using namespace SBS;
63
64namespace Skyscraper {
65
66//Hardware Abstraction Layer
67
69{
70 this->vm = vm;
72 mRoot = 0;
73 mRenderWindow = 0;
74 mSceneMgr = 0;
75 sound = 0;
76 channel = 0;
77 soundsys = 0;
78 RTSS = false;
79 mTrayMgr = 0;
80 show_stats = -1;
81 logger = 0;
82 log = 0;
83 DisableSound = false;
84 configfile = 0;
85 keyconfigfile = 0;
86 joyconfigfile = 0;
87 DX11 = false;
88 timer = new Ogre::Timer();
89}
90
92{
93#ifndef DISABLE_SOUND
94 if (soundsys)
95 soundsys->release();
96#endif
97
98 delete mOverlaySystem;
99
100 Ogre::ResourceGroupManager::getSingleton().shutdownAll();
101
102 if (configfile)
103 delete configfile;
104 configfile = 0;
105
106 if (keyconfigfile)
107 delete keyconfigfile;
108 keyconfigfile = 0;
109
110 if (joyconfigfile)
111 delete joyconfigfile;
112 joyconfigfile = 0;
113
114 log->removeListener(this);
115
116 //shutdown Ogre
117#if OGRE_PLATFORM != OGRE_PLATFORM_APPLE
118 delete mRoot;
119#endif
120
121 delete logger;
122}
123
124void HAL::ClickedObject(bool left, bool shift, bool ctrl, bool alt, bool right, Real scale, bool center_only)
125{
126 //click on an object
127
128 EngineContext *engine = vm->GetActiveEngine();
129
130 if (!engine)
131 return;
132
133 //get SBS camera
134 Camera *camera = engine->GetSystem()->camera;
135
136 if (!camera)
137 return;
138
139 if (left == true)
140 camera->MouseLeftDown = true;
141 else
142 camera->MouseRightDown = true;
143
144 Real result = -1;
145 Real nearest = 1000;
146 Camera *nearest_cam = 0;
147
148 for (int i = 0; i < vm->GetEngineCount(); i++)
149 {
150 //go through each engine and try a mouse click, find which hit is nearest
151 EngineContext *engine = vm->GetEngine(i);
152 if (engine)
153 {
154 Camera *camera2 = engine->GetSystem()->camera;
155 if (camera2)
156 result = camera2->ClickedObject(camera, shift, ctrl, alt, right, scale, center_only, true);
157
158 if (result < nearest && result >= 0)
159 {
160 nearest = result;
161 nearest_cam = camera2;
162 }
163 }
164 }
165
166 //perform a mouseclick on the nearest result
167 if (nearest_cam)
168 nearest_cam->ClickedObject(camera, shift, ctrl, alt, right, scale, center_only);
169}
170
172{
173 //unclick the clicked object
174
175 EngineContext *engine = vm->GetActiveEngine();
176
177 if (!engine)
178 return;
179
180 //get SBS camera
181 Camera *camera = engine->GetSystem()->camera;
182
183 if (!camera)
184 return;
185
186 camera->UnclickedObject();
187 camera->MouseLeftDown = false;
188 camera->MouseRightDown = false;
189}
190
192{
193#if USING_OPENXR
194 SBS_PROFILE_MAIN("UpdateOpenXR");
195
196 //update OpenXR camera transformations
197 if (GetConfigBool(configfile, "Skyscraper.Frontend.VR", false) == true)
198 {
199 EngineContext* engine = vm->GetActiveEngine();
200
201 if (engine)
202 {
203 ::SBS::SBS* Simcore = engine->GetSystem();
204
205 if (Simcore->camera)
206 {
207 for (int i = 0; i < 2; i++)
208 {
209 Ogre::Camera* camera = Simcore->camera->GetOgreCamera(i);
210 Vector3 cameranode_pos = Simcore->camera->GetSceneNode()->GetPosition() - Simcore->camera->GetPosition();
211 SetOpenXRParameters(i, Simcore->ToRemote(cameranode_pos), camera->getDerivedOrientation());
212 }
213 }
214 }
215 }
216#endif
217}
218
219void HAL::Report(const std::string &message, const std::string &prompt)
220{
221 std::string delim = "";
222 if (prompt.size() > 0)
223 delim = " ";
224 try
225 {
226 if (Ogre::LogManager::getSingletonPtr())
227 Ogre::LogManager::getSingleton().logMessage(prompt + delim + message);
228 }
229 catch (Ogre::Exception &e)
230 {
231#ifdef USING_WX
232 vm->GetGUI()->ShowError("VM: Error writing message to log\n" + e.getDescription());
233#endif
234 }
235}
236
237bool HAL::ReportError(const std::string &message, const std::string &prompt)
238{
239 std::string delim = "";
240 if (prompt.size() > 0)
241 delim = " ";
242 try
243 {
244 if (Ogre::LogManager::getSingletonPtr())
245 Ogre::LogManager::getSingleton().logMessage(prompt + delim + message, Ogre::LML_CRITICAL);
246 }
247 catch (Ogre::Exception &e)
248 {
249#ifdef USING_WX
250 vm->GetGUI()->ShowError("VM: Error writing message to log\n" + e.getDescription());
251#endif
252 }
253 return false;
254}
255
256bool HAL::ReportFatalError(const std::string &message, const std::string &prompt)
257{
258 ReportError(message, prompt);
259#ifdef USING_WX
260 vm->GetGUI()->ShowError(message);
261#endif
262 return false;
263}
264
265Ogre::ConfigFile* HAL::ConfigLoad(const std::string &filename, bool delete_after_use)
266{
267 //load a config file
268 try
269 {
270 Ogre::ConfigFile* file = new Ogre::ConfigFile();
271 file->load(filename);
272 if (delete_after_use == true)
273 {
274 delete file;
275 file = 0;
276 }
277 return file;
278 }
279 catch (Ogre::Exception &e)
280 {
281 ReportFatalError("Error loading configuration files\nDetails: " + e.getDescription());
282 return 0;
283 }
284}
285
286int HAL::GetConfigInt(Ogre::ConfigFile *file, const std::string &key, int default_value)
287{
288 std::string result = file->getSetting(key, "", ToString(default_value));
289 return ToInt(result);
290}
291
292std::string HAL::GetConfigString(Ogre::ConfigFile *file, const std::string &key, const std::string &default_value)
293{
294 if (!file)
295 return "";
296 return file->getSetting(key, "", default_value);
297}
298
299bool HAL::GetConfigBool(Ogre::ConfigFile *file, const std::string &key, bool default_value)
300{
301 if (!file)
302 return false;
303 std::string result = file->getSetting(key, "", BoolToString(default_value));
304 return ToBool(result);
305}
306
307Real HAL::GetConfigFloat(Ogre::ConfigFile *file, const std::string &key, Real default_value)
308{
309 if (!file)
310 return 0.0;
311 std::string result = file->getSetting(key, "", ToString(default_value));
312 return ToFloat(result);
313}
314
315bool HAL::Initialize(const std::string &data_path, Ogre::Root *root, Ogre::OverlaySystem *overlay)
316{
317 //initialize HAL system
318
319 mRoot = root;
320
321 //initialize OGRE
322 try
323 {
324 if (!mRoot)
325 mRoot = Ogre::Root::getSingletonPtr();
326 }
327 catch (Ogre::Exception &e)
328 {
329 return ReportFatalError("Error during initial OGRE check\nDetails: " + e.getDescription());
330 }
331
332 if(!mRoot)
333 {
334 try
335 {
336 //set up custom logger
337 if (!logger)
338 {
339 logger = new Ogre::LogManager();
340 log = logger->createLog(data_path + "skyscraper.log", true, !vm->showconsole, false);
341 log->addListener(this);
342 }
343
344 //report on system startup
345 Report("Skyscraper version " + vm->version_full + " starting...\n", "");
346
347 //load OGRE
348 Report("Loading OGRE...");
349 mRoot = new Ogre::Root();
350 }
351 catch (Ogre::Exception &e)
352 {
353 return ReportFatalError("Error initializing OGRE\nDetails: " + e.getDescription());
354 }
355 catch (...)
356 {
357 return ReportFatalError("Error initializing OGRE");
358 }
359 }
360
361 //set up overlay system
362 try
363 {
364 Report("");
365 Report("Loading Overlay System...");
366 mOverlaySystem = overlay;
367 if (!mOverlaySystem)
368 mOverlaySystem = new Ogre::OverlaySystem();
369 }
370 catch (Ogre::Exception &e)
371 {
372 return ReportFatalError("Error creating overlay system\nDetails: " + e.getDescription());
373 }
374
375 //configure render system
376 try
377 {
378 if(!mRoot->getRenderSystem())
379 {
380 //if no render systems are loaded, try to load previous config
381 if(!mRoot->restoreConfig())
382 {
383 //show dialog if load failed
384 mRoot->showConfigDialog(OgreBites::getNativeConfigDialog());
385 }
386 }
387 }
388 catch (Ogre::Exception &e)
389 {
390 return ReportFatalError("Error configuring render system\nDetails: " + e.getDescription());
391 }
392
393#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
394 //set rendersystem options
395 Ogre::RenderSystem *rendersystem = mRoot->getRenderSystem();
396 if (rendersystem)
397 {
398 Ogre::ConfigOptionMap CurrentRendererOptions = mRoot->getRenderSystem()->getConfigOptions();
399 Ogre::ConfigOptionMap::iterator configItr = CurrentRendererOptions.begin();
400
401 for (; configItr != CurrentRendererOptions.end(); configItr++)
402 {
403 if ((configItr)->first == "Floating-point mode")
404 {
405 //if using DirectX, prevent it from switching into single-point floating point mode
406 rendersystem->setConfigOption("Floating-point mode", "Consistent");
407 break;
408 }
409
410 if ((configItr)->first == "Auto hardware buffer management")
411 {
412 //fix black screen when resizing window using DirectX on Windows
413 rendersystem->setConfigOption("Auto hardware buffer management", "Yes");
414 }
415 }
416 }
417#endif
418
419 //initialize render window
420 try
421 {
422 Report("");
423 Report("Initializing OGRE...");
424 mRoot->initialise(false);
425 }
426 catch (Ogre::Exception &e)
427 {
428 return ReportFatalError("Error initializing render window\nDetails: " + e.getDescription());
429 }
430 catch (...)
431 {
432 return ReportFatalError("Error initializing render window");
433 }
434
435 return true;
436}
437
438bool HAL::LoadSystem(const std::string &data_path, Ogre::RenderWindow *renderwindow)
439{
440 //load HAL system resources
441
442 mRenderWindow = renderwindow;
443
444 //get renderer info
445 Renderer = mRoot->getRenderSystem()->getCapabilities()->getRenderSystemName();
446
447 //shorten name
448 size_t loc = Renderer.find("Rendering Subsystem");
449 Renderer = Renderer.substr(0, loc - 1);
450
451 //load resource configuration
452 Ogre::ConfigFile cf;
453 try
454 {
455 Report("");
456 Report("Loading resources...");
457 cf.load("resources.cfg");
458 }
459 catch (Ogre::Exception &e)
460 {
461 return ReportFatalError("Error loading resources.cfg\nDetails: " + e.getDescription());
462 }
463
464 //add resource locations
465 try
466 {
467 std::string name, locationType;
468 Ogre::ConfigFile::SettingsBySection_ settingsBySection = cf.getSettingsBySection();
469 for (const auto& p : settingsBySection) {
470 for (const auto& r : p.second) {
471 locationType = r.first;
472 name = r.second;
473 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(name, locationType);
474 }
475 }
476
477 //add app's directory to resource manager
478 Ogre::ResourceGroupManager::getSingleton().initialiseResourceGroup("General");
479 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(".", "FileSystem", "General", true);
480 if (data_path != "")
481 Ogre::ResourceGroupManager::getSingleton().addResourceLocation(data_path, "FileSystem", "General", true);
482
483 //add materials group, and autoload
484#ifdef USING_WX
485 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("data/materials", "FileSystem", "Materials", true);
486 Ogre::ResourceGroupManager::getSingleton().initialiseResourceGroup("Materials");
487
488 Ogre::ResourceGroupManager::getSingleton().addResourceLocation("media/packs/SdkTrays.zip", "Zip", "Trays", true);
489 Ogre::ResourceGroupManager::getSingleton().initialiseResourceGroup("Trays");
490#endif
491 }
492 catch (Ogre::Exception &e)
493 {
494 return ReportFatalError("Error initializing resources\nDetails: " + e.getDescription());
495 }
496
497 //create scene manager
498 try
499 {
500 mSceneMgr = mRoot->createSceneManager();
501 }
502 catch (Ogre::Exception &e)
503 {
504 return ReportFatalError("Error creating scene manager\nDetails: " + e.getDescription());
505 }
506
507 mSceneMgr->addRenderQueueListener(mOverlaySystem);
508
509 //enable shadows
510 if (GetConfigBool(configfile, "Skyscraper.Frontend.Shadows", false) == true)
511 {
512 try
513 {
514 Report("Enabling shadows");
515 mSceneMgr->setShadowTechnique(Ogre::SHADOWTYPE_STENCIL_ADDITIVE);
516 }
517 catch (Ogre::Exception &e)
518 {
519 ReportFatalError("Error setting shadow technique\nDetails: " + e.getDescription());
520 }
521 }
522
523 std::string renderer = mRoot->getRenderSystem()->getName();
524
525 if (renderer != "Direct3D9 Rendering Subsystem" && renderer != "OpenGL Rendering Subsystem" && renderer != "Metal Rendering Subsystem")
526 RTSS = true;
527
528 if (RTSS == true)
529 {
530 //Enable the RT Shader System
531 if (Ogre::RTShader::ShaderGenerator::initialize())
532 {
533 Ogre::RTShader::ShaderGenerator* shaderGenerator = Ogre::RTShader::ShaderGenerator::getSingletonPtr();
534 shaderGenerator->addSceneManager(mSceneMgr);
535
536 // forward scheme not found events to the RTSS
537 OgreBites::SGTechniqueResolverListener* schemeNotFoundHandler = new OgreBites::SGTechniqueResolverListener(shaderGenerator);
538 Ogre::MaterialManager::getSingleton().addListener(schemeNotFoundHandler);
539
540 //uncomment this to dump RTSS shaders
541 //shaderGenerator->setShaderCachePath("shaders/");
542 }
543 }
544
545 if (renderer == "Direct3D11 Rendering Subsystem")
546 DX11 = true;
547
548 try
549 {
550 //define camera configuration
551 int cameras = 1; //use one camera for standard mode
552 if (GetConfigBool(configfile, "Skyscraper.Frontend.VR", false) == true)
553 cameras = 2; //use two cameras for VR mode
554
555 for (int i = 0; i < cameras; i++)
556 {
557 mCameras.emplace_back(mSceneMgr->createCamera("Camera " + ToString(i + 1)));
558 if (mRenderWindow)
559 {
560 mViewports.emplace_back(mRenderWindow->addViewport(mCameras[i], (cameras - 1) - i, 0, 0, 1, 1));
561 mCameras[i]->setAspectRatio(Real(mViewports[i]->getActualWidth()) / Real(mViewports[i]->getActualHeight()));
562 }
563 }
564 }
565 catch (Ogre::Exception &e)
566 {
567 return ReportFatalError("Error creating camera and viewport\nDetails: " + e.getDescription());
568 }
569
570 //set up default material shader scheme
571 if (RTSS == true)
572 {
573 for (size_t i = 0; i < mViewports.size(); i++)
574 {
575 mViewports[i]->setMaterialScheme(Ogre::RTShader::ShaderGenerator::DEFAULT_SCHEME_NAME);
576 }
577 }
578
579 //setup texture filtering
580 int filtermode = GetConfigInt(configfile, "Skyscraper.Frontend.TextureFilter", 3);
581 int maxanisotropy = GetConfigInt(configfile, "Skyscraper.Frontend.MaxAnisotropy", 8);
582
583 if (filtermode < 0 || filtermode > 3)
584 filtermode = 3;
585
586 if (filtermode < 3)
587 maxanisotropy = 1;
588
589 Ogre::TextureFilterOptions filter = Ogre::TFO_NONE;
590 if (filtermode == 1)
591 filter = Ogre::TFO_BILINEAR;
592 else if (filtermode == 2)
593 filter = Ogre::TFO_TRILINEAR;
594 else if (filtermode == 3)
595 filter = Ogre::TFO_ANISOTROPIC;
596
597 Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(filter);
598 Ogre::MaterialManager::getSingleton().setDefaultAnisotropy(maxanisotropy);
599
600#ifndef DISABLE_SOUND
601 //initialize FMOD (sound)
602 DisableSound = GetConfigBool(configfile, "Skyscraper.Frontend.DisableSound", false);
603 if (DisableSound == false)
604 {
605 Report("");
606 Report("FMOD Sound System, copyright (C) Firelight Technologies Pty, Ltd., 1994-2024\n");
607
608 FMOD_RESULT result = FMOD::System_Create(&soundsys);
609 if (result != FMOD_OK)
610 {
611 std::string fmod_result = FMOD_ErrorString(result);
612 ReportFatalError("Error initializing sound:\n" + fmod_result);
613 DisableSound = true;
614 }
615 else
616 {
617 char name [] = "Skyscraper"; //set name for PulseAudio on Linux
618 result = soundsys->init(100, FMOD_INIT_NORMAL, &name);
619 if (result != FMOD_OK)
620 {
621 std::string fmod_result = FMOD_ErrorString(result);
622 ReportFatalError("Error initializing sound:\n" + fmod_result);
623 DisableSound = true;
624 }
625 else
626 {
627 //get FMOD version information
628 unsigned int version;
629 soundsys->getVersion(&version);
630 int major = version >> 16;
631 int minor = (version >> 8) & 255;
632 int rev = version & 255;
633
634 std::string s_version;
635 char hexString[25];
636
637 snprintf(hexString, 25, "%x.%x.%x", major, minor, rev);
638 s_version = std::string(hexString);
639
640 Report("Sound initialized: FMOD Engine version " + s_version);
641 }
642 }
643 }
644 else
645#endif
646 Report("Sound Disabled");
647
648 try
649 {
650 mTrayMgr = new OgreBites::TrayManager("InterfaceName", mRenderWindow);
651 }
652 catch (Ogre::Exception &e)
653 {
654 ReportFatalError("Error starting tray manager:\nDetails: " + e.getDescription());
655 }
656
657 if (mTrayMgr)
658 {
659 mTrayMgr->hideCursor();
660 }
661
662 //report hardware concurrency
663 int c = std::thread::hardware_concurrency();
664 Report("Reported hardware concurrency: " + ToString(c) + "\n");
665
666 Report("Initialization complete");
667 Report("");
668
669 return true;
670}
671
673{
674 SBS_PROFILE_MAIN("Render");
675
676 //render to the frame buffer
677 try
678 {
679 mRoot->renderOneFrame();
680 }
681 catch (Ogre::Exception &e)
682 {
683 return ReportFatalError("Error in render operation\nDetails: " + e.getDescription());
684 }
685
686 //update frame statistics
687 Ogre::FrameEvent a;
688 if (mTrayMgr)
689 mTrayMgr->frameRendered(a);
690
691 return true;
692}
693
694bool HAL::PlaySound(const std::string &filename, Real volume)
695{
696 //play a sound
697#ifndef DISABLE_SOUND
698
699 //load new sound
700#if (FMOD_VERSION >> 16 == 4)
701 FMOD_RESULT result = soundsys->createSound(filename.c_str(), (FMOD_MODE)(FMOD_2D | FMOD_ACCURATETIME | FMOD_SOFTWARE | FMOD_LOOP_NORMAL), 0, &sound);
702#else
703 FMOD_RESULT result = soundsys->createSound(filename.c_str(), (FMOD_MODE)(FMOD_2D | FMOD_ACCURATETIME | FMOD_LOOP_NORMAL), 0, &sound);
704#endif
705 if (result != FMOD_OK)
706 {
707 return ReportError("Can't load file '" + filename + "':\n" + FMOD_ErrorString(result));
708 }
709
710#if (FMOD_VERSION >> 16 == 4)
711 result = soundsys->playSound(FMOD_CHANNEL_FREE, sound, true, &channel);
712#else
713 result = soundsys->playSound(sound, 0, true, &channel);
714#endif
715
716 if (result != FMOD_OK)
717 {
718 return ReportError("Error playing " + filename);
719 }
720
721 channel->setLoopCount(-1);
722 channel->setVolume(volume);
723 channel->setPaused(false);
724
725#endif
726 return true;
727}
728
730{
731 //stop and unload sound
732#ifndef DISABLE_SOUND
733 if (channel)
734 channel->stop();
735 if (sound)
736 sound->release();
737 sound = 0;
738#endif
739}
740
742{
743 //clear scene
744 if (mSceneMgr)
745 mSceneMgr->clearScene();
746}
747
749{
750 //toggle frame statistics
751
752 show_stats++;
753
754 if (!mTrayMgr)
755 return;
756
757 if (show_stats == 0)
758 {
759 mTrayMgr->showFrameStats(OgreBites::TrayLocation::TL_TOPRIGHT);
760 mTrayMgr->toggleAdvancedFrameStats();
761 }
762 else if (show_stats == 1)
763 mTrayMgr->toggleAdvancedFrameStats();
764 else if (show_stats == 2)
765 {
766 mTrayMgr->hideFrameStats();
767 show_stats = -1;
768 }
769}
770
771void HAL::EnableStats(bool value)
772{
773 //turn on or off frame statistics
774
775 if (value == true)
776 {
777 show_stats = -1;
778 ToggleStats();
779 }
780 else
781 {
782 show_stats = 1;
783 ToggleStats();
784 }
785}
786
788{
789 //reinitialize HAL system
790
791 EnableStats(false);
792
793 delete mTrayMgr;
794 mTrayMgr = 0;
795
796 //reinit overlay system
797 try
798 {
799 mSceneMgr->removeRenderQueueListener(mOverlaySystem);
800 delete mOverlaySystem;
801 mOverlaySystem = new Ogre::OverlaySystem();
802 mSceneMgr->addRenderQueueListener(mOverlaySystem);
803 }
804 catch (Ogre::Exception &e)
805 {
806 ReportFatalError("Error creating overlay system\nDetails: " + e.getDescription());
807 }
808
809 //initialize system resources
810 try
811 {
812 Ogre::ResourceGroupManager::getSingleton().clearResourceGroup("Materials");
813 Ogre::ResourceGroupManager::getSingleton().initialiseResourceGroup("Materials");
814 Ogre::ResourceGroupManager::getSingleton().clearResourceGroup("Trays");
815 Ogre::ResourceGroupManager::getSingleton().initialiseResourceGroup("Trays");
816 }
817 catch (Ogre::Exception &e)
818 {
819 ReportFatalError("Error initializing resources\nDetails:" + e.getDescription());
820 }
821
822 //reinit tray manager
823 try
824 {
825 mTrayMgr = new OgreBites::TrayManager("Tray", mRenderWindow);
826 }
827 catch (Ogre::Exception &e)
828 {
829 ReportFatalError("Error starting tray manager:\n" + e.getDescription());
830 }
831
832 if (mTrayMgr)
833 {
834 mTrayMgr->hideCursor();
835 }
836
837 show_stats = -1;
838}
839
840FMOD::System* HAL::GetSoundSystem()
841{
842 return soundsys;
843}
844
845Ogre::RenderWindow* HAL::GetRenderWindow()
846{
847 return mRenderWindow;
848}
849
851{
852 //do a full clear of Ogre objects
853
854 //remove all meshes
855 Ogre::MeshManager::getSingleton().removeAll();
856
857 //remove all materials
858 if (RTSS)
859 Ogre::RTShader::ShaderGenerator::getSingleton().removeAllShaderBasedTechniques();
860 Ogre::MaterialManager::getSingleton().removeAll();
861 Ogre::MaterialManager::getSingleton().initialise(); //restore default materials
862
863 //remove all fonts
864 Ogre::FontManager::getSingleton().removeAll();
865
866 //remove all textures
867 Ogre::TextureManager::getSingleton().removeAll();
868
869 //clear scene manager
870 if (mSceneMgr)
871 mSceneMgr->clearScene();
872
873 //free unused hardware buffers
874 Ogre::HardwareBufferManager::getSingleton()._freeUnusedBufferCopies();
875
876#ifndef DISABLE_SOUND
877 //reset FMOD reverb
878 soundsys->setReverbProperties(0, 0);
879#endif
880
881 ReInit();
882
883#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
884#ifdef __linux__
885 //release free memory to OS on Linux
886 malloc_trim(0);
887#else
888 //freebsd
889#endif
890#endif
891}
892
893Ogre::SceneManager* HAL::GetSceneManager()
894{
895 return mSceneMgr;
896}
897
898Ogre::RenderWindow* HAL::CreateRenderWindow(const std::string &name, int width, int height, const Ogre::NameValuePairList &params)
899{
900 //create the render window
901#if USING_OPENXR
902 if (GetConfigBool(configfile, "Skyscraper.Frontend.VR", false) == true)
903 {
904 Ogre::RenderWindow* win2 = Ogre::Root::getSingleton().createRenderWindow(name, width, height, false, &params);
905 mRenderWindow = CreateOpenXRRenderWindow(mRoot->getRenderSystem());
906 mRenderWindow->create(name, width, height, false, &params);
907 }
908 else
909#endif
910 mRenderWindow = Ogre::Root::getSingleton().createRenderWindow(name, width, height, false, &params);
911
912 mRenderWindow->setActive(true);
913 mRenderWindow->windowMovedOrResized();
914
915 return mRenderWindow;
916}
917
919{
920 if (mRenderWindow)
921 Ogre::Root::getSingleton().detachRenderTarget(mRenderWindow);
922
923 mRenderWindow->destroy();
924 mRenderWindow = 0;
925}
926
928{
929 //refresh viewport to prevent rendering issues
930
931 for (size_t i = 0; i < mViewports.size(); i++)
932 {
933 mViewports[i]->_updateDimensions();
934 }
935}
936
937void HAL::Report(const std::string &message)
938{
939 Report(message, "hal:");
940}
941
942bool HAL::ReportError(const std::string &message)
943{
944 return ReportError(message, "hal:");
945}
946
947bool HAL::ReportFatalError(const std::string &message)
948{
949 return ReportFatalError(message, "hal:");
950}
951
952void HAL::LoadConfiguration(const std::string data_path, bool show_console)
953{
954 //load configuration files
955
956 configfile = ConfigLoad(data_path + "skyscraper.ini");
957 keyconfigfile = ConfigLoad(data_path + "keyboard.ini");
958 joyconfigfile = ConfigLoad(data_path + "joystick.ini");
959 ConfigLoad("plugins.cfg", true);
960 ConfigLoad("resources.cfg", true);
961
962 if (show_console == false)
963 return;
964
965 vm->showconsole = GetConfigBool(configfile, "Skyscraper.Frontend.ShowConsole", true);
966
967 //create console window
968#ifdef USING_WX
969 if (vm->showconsole == true)
970 vm->GetGUI()->ShowConsole(false);
971#endif
972}
973
974void HAL::messageLogged(const std::string &message, Ogre::LogMessageLevel lml, bool maskDebug, const std::string &logName, bool &skipThisMessage)
975{
976 //callback function that receives OGRE log messages
977
978#ifdef USING_WX
979 vm->GetGUI()->WriteToConsole(message);
980#endif
981}
982
983void HAL::ConsoleOut(const std::string &message, const std::string &color)
984{
985 //console output
986 std::string mod = GetColors(color);
987 std::string reset = GetColors("reset");
988 std::cout << mod << message << reset;
989}
990
991std::string HAL::GetColors(const std::string &color)
992{
993 //get colors
994 std::string mod;
995 if (color == "blue")
996 mod = "\033[1;34m";
997 else if (color == "green")
998 mod = "\033[1;32m";
999 else if (color == "yellow")
1000 mod = "\033[1;33m";
1001 else if (color == "red")
1002 mod = "\033[1;31m";
1003 else if (color == "magenta")
1004 mod = "\033[1;35m";
1005 else if (color == "cyan")
1006 mod = "\033[1;36m";
1007 else if (color == "white")
1008 mod = "\033[1;37m";
1009 else if (color == "black")
1010 mod = "\033[1;30m";
1011 else if (color == "reset")
1012 mod = "\033[0m";
1013
1014 return mod;
1015}
1016
1017unsigned long HAL::GetCurrentTime()
1018{
1019 //get current time
1020 return timer->getMilliseconds();
1021}
1022
1023}
_OgreOpenXRExport Ogre::RenderWindow * CreateOpenXRRenderWindow(Ogre::RenderSystem *rsys)
_OgreOpenXRExport void SetOpenXRParameters(int index, const Ogre::Vector3 &position, const Ogre::Quaternion &orientation)
Ogre::Camera * GetOgreCamera(int index=0)
Definition camera.cpp:1625
bool MouseLeftDown
Definition camera.h:82
Real ClickedObject(Camera *camera, bool shift, bool ctrl, bool alt, bool right, Real scale, bool center_only=false, bool hit_only=false)
Definition camera.cpp:552
void UnclickedObject()
Definition camera.cpp:688
Vector3 GetPosition(bool relative=false)
Definition camera.cpp:250
bool MouseRightDown
Definition camera.h:83
SceneNode * GetSceneNode()
Definition object.cpp:246
Camera * camera
Definition sbs.h:160
Real ToRemote(Real local_value)
Definition sbs.cpp:2437
Vector3 GetPosition(bool relative=false)
void ShowError(const std::string &message)
Definition gui.cpp:84
void WriteToConsole(const std::string &message, const std::string &color="white")
Definition gui.cpp:332
void ShowConsole(bool send_button=true)
Definition gui.cpp:214
OgreBites::TrayManager * mTrayMgr
Definition hal.h:124
std::string GetColors(const std::string &color)
Definition hal.cpp:991
void LoadConfiguration(const std::string data_path, bool show_console)
Definition hal.cpp:952
bool ReportFatalError(const std::string &message, const std::string &prompt)
Definition hal.cpp:256
bool DX11
Definition hal.h:94
bool DisableSound
Definition hal.h:89
Ogre::LogManager * logger
Definition hal.h:108
std::string GetConfigString(Ogre::ConfigFile *file, const std::string &key, const std::string &default_value)
Definition hal.cpp:292
void messageLogged(const std::string &message, Ogre::LogMessageLevel lml, bool maskDebug, const std::string &logName, bool &skipThisMessage)
Definition hal.cpp:974
int GetConfigInt(Ogre::ConfigFile *file, const std::string &key, int default_value)
Definition hal.cpp:286
void UpdateOpenXR()
Definition hal.cpp:191
void ReInit()
Definition hal.cpp:787
Ogre::ConfigFile * joyconfigfile
Definition hal.h:99
void Clear()
Definition hal.cpp:850
void ToggleStats()
Definition hal.cpp:748
Ogre::ConfigFile * keyconfigfile
Definition hal.h:98
Ogre::RenderWindow * GetRenderWindow()
Definition hal.cpp:845
void EnableStats(bool value)
Definition hal.cpp:771
std::string Renderer
Definition hal.h:88
bool RTSS
Definition hal.h:87
Ogre::ConfigFile * ConfigLoad(const std::string &filename, bool delete_after_use=false)
Definition hal.cpp:265
void DestroyRenderWindow()
Definition hal.cpp:918
unsigned long GetCurrentTime()
Definition hal.cpp:1017
bool LoadSystem(const std::string &data_path, Ogre::RenderWindow *renderwindow)
Definition hal.cpp:438
Ogre::SceneManager * GetSceneManager()
Definition hal.cpp:893
FMOD::Sound * sound
Definition hal.h:113
std::vector< Ogre::Viewport * > mViewports
Definition hal.h:93
Real GetConfigFloat(Ogre::ConfigFile *file, const std::string &key, Real default_value)
Definition hal.cpp:307
void ClearScene()
Definition hal.cpp:741
bool GetConfigBool(Ogre::ConfigFile *file, const std::string &key, bool default_value)
Definition hal.cpp:299
Ogre::RenderWindow * mRenderWindow
Definition hal.h:92
HAL(VM *vm)
Definition hal.cpp:68
Ogre::Timer * timer
Definition hal.h:128
FMOD::Channel * channel
Definition hal.h:114
void ConsoleOut(const std::string &message, const std::string &color="white")
Definition hal.cpp:983
bool PlaySound(const std::string &filename, Real volume=1.0)
Definition hal.cpp:694
std::vector< Ogre::Camera * > mCameras
Definition hal.h:90
void Report(const std::string &message, const std::string &prompt)
Definition hal.cpp:219
bool Initialize(const std::string &data_path, Ogre::Root *root=0, Ogre::OverlaySystem *overlay=0)
Definition hal.cpp:315
Ogre::SceneManager * mSceneMgr
Definition hal.h:104
void RefreshViewport()
Definition hal.cpp:927
bool Render()
Definition hal.cpp:672
bool ReportError(const std::string &message, const std::string &prompt)
Definition hal.cpp:237
Ogre::RenderWindow * CreateRenderWindow(const std::string &name, int width, int height, const Ogre::NameValuePairList &params)
Definition hal.cpp:898
FMOD::System * GetSoundSystem()
Definition hal.cpp:840
int show_stats
Definition hal.h:125
FMOD::System * soundsys
Definition hal.h:112
Ogre::Root * mRoot
Definition hal.h:91
Ogre::OverlaySystem * mOverlaySystem
Definition hal.h:105
Ogre::Log * log
Definition hal.h:109
Ogre::ConfigFile * configfile
Definition hal.h:97
void UnclickedObject()
Definition hal.cpp:171
void ClickedObject(bool left, bool shift, bool ctrl, bool alt, bool right, Real scale, bool center_only)
Definition hal.cpp:124
void StopSound()
Definition hal.cpp:729
bool showconsole
Definition vm.h:122
GUI * GetGUI()
Definition vm.cpp:148
int GetEngineCount(bool loading_only=false)
Definition vm.cpp:448
EngineContext * GetActiveEngine()
Definition vm.h:81
EngineContext * GetEngine(int number)
Definition vm.cpp:438
std::string version_full
Definition vm.h:130
Ogre::Vector3 Vector3
Definition globals.h:58
Ogre::Real Real
Definition globals.h:57
int ToInt(const std::string &string)
Definition globals.cpp:402
std::string ToString(int number)
Definition globals.cpp:279
Real ToFloat(const std::string &string)
Definition globals.cpp:397
std::string BoolToString(bool item)
Definition globals.cpp:101
bool ToBool(std::string string)
Definition globals.cpp:407
std::string prompt
Definition vmconsole.cpp:44
#define SBS_PROFILE_MAIN(name)
Definition profiler.h:132