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_frontend + " 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 int 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;
590 if (filtermode == 0)
591 filter = Ogre::TFO_NONE;
592 else if (filtermode == 1)
593 filter = Ogre::TFO_BILINEAR;
594 else if (filtermode == 2)
595 filter = Ogre::TFO_TRILINEAR;
596 else if (filtermode == 3)
597 filter = Ogre::TFO_ANISOTROPIC;
598
599 Ogre::MaterialManager::getSingleton().setDefaultTextureFiltering(filter);
600 Ogre::MaterialManager::getSingleton().setDefaultAnisotropy(maxanisotropy);
601
602#ifndef DISABLE_SOUND
603 //initialize FMOD (sound)
604 DisableSound = GetConfigBool(configfile, "Skyscraper.Frontend.DisableSound", false);
605 if (DisableSound == false)
606 {
607 Report("");
608 Report("FMOD Sound System, copyright (C) Firelight Technologies Pty, Ltd., 1994-2024\n");
609
610 FMOD_RESULT result = FMOD::System_Create(&soundsys);
611 if (result != FMOD_OK)
612 {
613 std::string fmod_result = FMOD_ErrorString(result);
614 ReportFatalError("Error initializing sound:\n" + fmod_result);
615 DisableSound = true;
616 }
617 else
618 {
619 char name [] = "Skyscraper"; //set name for PulseAudio on Linux
620 result = soundsys->init(100, FMOD_INIT_NORMAL, &name);
621 if (result != FMOD_OK)
622 {
623 std::string fmod_result = FMOD_ErrorString(result);
624 ReportFatalError("Error initializing sound:\n" + fmod_result);
625 DisableSound = true;
626 }
627 else
628 {
629 //get FMOD version information
630 unsigned int version;
631 soundsys->getVersion(&version);
632 int major = version >> 16;
633 int minor = (version >> 8) & 255;
634 int rev = version & 255;
635
636 std::string s_version;
637 char hexString[25];
638
639 snprintf(hexString, 25, "%x.%x.%x", major, minor, rev);
640 s_version = std::string(hexString);
641
642 Report("Sound initialized: FMOD Engine version " + s_version);
643 }
644 }
645 }
646 else
647#endif
648 Report("Sound Disabled");
649
650 try
651 {
652 mTrayMgr = new OgreBites::TrayManager("InterfaceName", mRenderWindow);
653 }
654 catch (Ogre::Exception &e)
655 {
656 ReportFatalError("Error starting tray manager:\nDetails: " + e.getDescription());
657 }
658
659 if (mTrayMgr)
660 {
661 mTrayMgr->hideCursor();
662 }
663
664 //report hardware concurrency
665 int c = std::thread::hardware_concurrency();
666 Report("Reported hardware concurrency: " + ToString(c) + "\n");
667
668 Report("Initialization complete");
669 Report("");
670
671 return true;
672}
673
675{
676 SBS_PROFILE_MAIN("Render");
677
678 //render to the frame buffer
679 try
680 {
681 mRoot->renderOneFrame();
682 }
683 catch (Ogre::Exception &e)
684 {
685 return ReportFatalError("Error in render operation\nDetails: " + e.getDescription());
686 }
687
688 //update frame statistics
689 Ogre::FrameEvent a;
690 if (mTrayMgr)
691 mTrayMgr->frameRendered(a);
692
693 return true;
694}
695
696bool HAL::PlaySound(const std::string &filename, Real volume)
697{
698 //play a sound
699#ifndef DISABLE_SOUND
700
701 //load new sound
702#if (FMOD_VERSION >> 16 == 4)
703 FMOD_RESULT result = soundsys->createSound(filename.c_str(), (FMOD_MODE)(FMOD_2D | FMOD_ACCURATETIME | FMOD_SOFTWARE | FMOD_LOOP_NORMAL), 0, &sound);
704#else
705 FMOD_RESULT result = soundsys->createSound(filename.c_str(), (FMOD_MODE)(FMOD_2D | FMOD_ACCURATETIME | FMOD_LOOP_NORMAL), 0, &sound);
706#endif
707 if (result != FMOD_OK)
708 {
709 return ReportError("Can't load file '" + filename + "':\n" + FMOD_ErrorString(result));
710 }
711
712#if (FMOD_VERSION >> 16 == 4)
713 result = soundsys->playSound(FMOD_CHANNEL_FREE, sound, true, &channel);
714#else
715 result = soundsys->playSound(sound, 0, true, &channel);
716#endif
717
718 if (result != FMOD_OK)
719 {
720 return ReportError("Error playing " + filename);
721 }
722
723 channel->setLoopCount(-1);
724 channel->setVolume(volume);
725 channel->setPaused(false);
726
727#endif
728 return true;
729}
730
732{
733 //stop and unload sound
734#ifndef DISABLE_SOUND
735 if (channel)
736 channel->stop();
737 if (sound)
738 sound->release();
739 sound = 0;
740#endif
741}
742
744{
745 //clear scene
746 if (mSceneMgr)
747 mSceneMgr->clearScene();
748}
749
751{
752 //toggle frame statistics
753
754 show_stats++;
755
756 if (!mTrayMgr)
757 return;
758
759 if (show_stats == 0)
760 {
761 mTrayMgr->showFrameStats(OgreBites::TrayLocation::TL_TOPRIGHT);
762 mTrayMgr->toggleAdvancedFrameStats();
763 }
764 else if (show_stats == 1)
765 mTrayMgr->toggleAdvancedFrameStats();
766 else if (show_stats == 2)
767 {
768 mTrayMgr->hideFrameStats();
769 show_stats = -1;
770 }
771}
772
773void HAL::EnableStats(bool value)
774{
775 //turn on or off frame statistics
776
777 if (value == true)
778 {
779 show_stats = -1;
780 ToggleStats();
781 }
782 else
783 {
784 show_stats = 1;
785 ToggleStats();
786 }
787}
788
790{
791 //reinitialize HAL system
792
793 EnableStats(false);
794
795 delete mTrayMgr;
796 mTrayMgr = 0;
797
798 //reinit overlay system
799 try
800 {
801 mSceneMgr->removeRenderQueueListener(mOverlaySystem);
802 delete mOverlaySystem;
803 mOverlaySystem = new Ogre::OverlaySystem();
804 mSceneMgr->addRenderQueueListener(mOverlaySystem);
805 }
806 catch (Ogre::Exception &e)
807 {
808 ReportFatalError("Error creating overlay system\nDetails: " + e.getDescription());
809 }
810
811 //initialize system resources
812 try
813 {
814 Ogre::ResourceGroupManager::getSingleton().clearResourceGroup("Materials");
815 Ogre::ResourceGroupManager::getSingleton().initialiseResourceGroup("Materials");
816 Ogre::ResourceGroupManager::getSingleton().clearResourceGroup("Trays");
817 Ogre::ResourceGroupManager::getSingleton().initialiseResourceGroup("Trays");
818 }
819 catch (Ogre::Exception &e)
820 {
821 ReportFatalError("Error initializing resources\nDetails:" + e.getDescription());
822 }
823
824 //reinit tray manager
825 try
826 {
827 mTrayMgr = new OgreBites::TrayManager("Tray", mRenderWindow);
828 }
829 catch (Ogre::Exception &e)
830 {
831 ReportFatalError("Error starting tray manager:\n" + e.getDescription());
832 }
833
834 if (mTrayMgr)
835 {
836 mTrayMgr->hideCursor();
837 }
838
839 show_stats = -1;
840}
841
842FMOD::System* HAL::GetSoundSystem()
843{
844 return soundsys;
845}
846
847Ogre::RenderWindow* HAL::GetRenderWindow()
848{
849 return mRenderWindow;
850}
851
853{
854 //do a full clear of Ogre objects
855
856 //remove all meshes
857 Ogre::MeshManager::getSingleton().removeAll();
858
859 //remove all materials
860 if (RTSS)
861 Ogre::RTShader::ShaderGenerator::getSingleton().removeAllShaderBasedTechniques();
862 Ogre::MaterialManager::getSingleton().removeAll();
863 Ogre::MaterialManager::getSingleton().initialise(); //restore default materials
864
865 //remove all fonts
866 Ogre::FontManager::getSingleton().removeAll();
867
868 //remove all textures
869 Ogre::TextureManager::getSingleton().removeAll();
870
871 //clear scene manager
872 if (mSceneMgr)
873 mSceneMgr->clearScene();
874
875 //free unused hardware buffers
876 Ogre::HardwareBufferManager::getSingleton()._freeUnusedBufferCopies();
877
878#ifndef DISABLE_SOUND
879 //reset FMOD reverb
880 soundsys->setReverbProperties(0, 0);
881#endif
882
883 ReInit();
884
885#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX
886#ifdef __linux__
887 //release free memory to OS on Linux
888 malloc_trim(0);
889#else
890 //freebsd
891#endif
892#endif
893}
894
895Ogre::SceneManager* HAL::GetSceneManager()
896{
897 return mSceneMgr;
898}
899
900Ogre::RenderWindow* HAL::CreateRenderWindow(const std::string &name, int width, int height, const Ogre::NameValuePairList &params)
901{
902 //create the render window
903#if USING_OPENXR
904 if (GetConfigBool(configfile, "Skyscraper.Frontend.VR", false) == true)
905 {
906 Ogre::RenderWindow* win2 = Ogre::Root::getSingleton().createRenderWindow(name, width, height, false, &params);
907 mRenderWindow = CreateOpenXRRenderWindow(mRoot->getRenderSystem());
908 mRenderWindow->create(name, width, height, false, &params);
909 }
910 else
911#endif
912 mRenderWindow = Ogre::Root::getSingleton().createRenderWindow(name, width, height, false, &params);
913
914 mRenderWindow->setActive(true);
915 mRenderWindow->windowMovedOrResized();
916
917 return mRenderWindow;
918}
919
921{
922 if (mRenderWindow)
923 Ogre::Root::getSingleton().detachRenderTarget(mRenderWindow);
924
925 mRenderWindow->destroy();
926 mRenderWindow = 0;
927}
928
930{
931 //refresh viewport to prevent rendering issues
932
933 for (size_t i = 0; i < mViewports.size(); i++)
934 {
935 mViewports[i]->_updateDimensions();
936 }
937}
938
939void HAL::Report(const std::string &message)
940{
941 Report(message, "hal:");
942}
943
944bool HAL::ReportError(const std::string &message)
945{
946 return ReportError(message, "hal:");
947}
948
949bool HAL::ReportFatalError(const std::string &message)
950{
951 return ReportFatalError(message, "hal:");
952}
953
954void HAL::LoadConfiguration(const std::string data_path, bool show_console)
955{
956 //load configuration files
957
958 configfile = ConfigLoad(data_path + "skyscraper.ini");
959 keyconfigfile = ConfigLoad(data_path + "keyboard.ini");
960 joyconfigfile = ConfigLoad(data_path + "joystick.ini");
961 ConfigLoad("plugins.cfg", true);
962 ConfigLoad("resources.cfg", true);
963
964 if (show_console == false)
965 return;
966
967 vm->showconsole = GetConfigBool(configfile, "Skyscraper.Frontend.ShowConsole", true);
968
969 //create console window
970#ifdef USING_WX
971 if (vm->showconsole == true)
972 vm->GetGUI()->ShowConsole(false);
973#endif
974}
975
976void HAL::messageLogged(const std::string &message, Ogre::LogMessageLevel lml, bool maskDebug, const std::string &logName, bool &skipThisMessage)
977{
978 //callback function that receives OGRE log messages
979
980#ifdef USING_WX
981 vm->GetGUI()->WriteToConsole(message);
982#endif
983}
984
985void HAL::ConsoleOut(const std::string &message, const std::string &color)
986{
987 //console output
988 std::string mod = GetColors(color);
989 std::string reset = GetColors("reset");
990 std::cout << mod << message << reset;
991}
992
993std::string HAL::GetColors(const std::string &color)
994{
995 //get colors
996 std::string mod;
997 if (color == "blue")
998 mod = "\033[1;34m";
999 else if (color == "green")
1000 mod = "\033[1;32m";
1001 else if (color == "yellow")
1002 mod = "\033[1;33m";
1003 else if (color == "red")
1004 mod = "\033[1;31m";
1005 else if (color == "magenta")
1006 mod = "\033[1;35m";
1007 else if (color == "cyan")
1008 mod = "\033[1;36m";
1009 else if (color == "white")
1010 mod = "\033[1;37m";
1011 else if (color == "black")
1012 mod = "\033[1;30m";
1013 else if (color == "reset")
1014 mod = "\033[0m";
1015
1016 return mod;
1017}
1018
1019unsigned long HAL::GetCurrentTime()
1020{
1021 //get current time
1022 return timer->getMilliseconds();
1023}
1024
1025}
_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:1626
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:240
Camera * camera
Definition sbs.h:160
Real ToRemote(Real local_value)
Definition sbs.cpp:2407
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:330
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:993
void LoadConfiguration(const std::string data_path, bool show_console)
Definition hal.cpp:954
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:976
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:789
Ogre::ConfigFile * joyconfigfile
Definition hal.h:99
void Clear()
Definition hal.cpp:852
void ToggleStats()
Definition hal.cpp:750
Ogre::ConfigFile * keyconfigfile
Definition hal.h:98
Ogre::RenderWindow * GetRenderWindow()
Definition hal.cpp:847
void EnableStats(bool value)
Definition hal.cpp:773
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:920
unsigned long GetCurrentTime()
Definition hal.cpp:1019
bool LoadSystem(const std::string &data_path, Ogre::RenderWindow *renderwindow)
Definition hal.cpp:438
Ogre::SceneManager * GetSceneManager()
Definition hal.cpp:895
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:743
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:985
bool PlaySound(const std::string &filename, Real volume=1.0)
Definition hal.cpp:696
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:929
bool Render()
Definition hal.cpp:674
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:900
FMOD::System * GetSoundSystem()
Definition hal.cpp:842
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:731
bool showconsole
Definition vm.h:121
GUI * GetGUI()
Definition vm.cpp:142
int GetEngineCount(bool loading_only=false)
Definition vm.cpp:442
std::string version_frontend
Definition vm.h:129
EngineContext * GetActiveEngine()
Definition vm.h:81
EngineContext * GetEngine(int number)
Definition vm.cpp:432
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