// Ryzom - MMORPG Framework // Copyright (C) 2010-2020 Winch Gate Property Limited // // This source file has been modified by the following contributors: // Copyright (C) 2013-2014 Jan BOON (Kaetemi) // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . #include "stdpch.h" #include "main_loop_utilities.h" #include #include #include #include #include "game_share/scenario_entry_points.h" #include "client_cfg.h" #include "misc.h" #include "global.h" #include "world_database_manager.h" #include "continent_manager.h" #include "user_entity.h" #include "view.h" #include "ig_client.h" #include "entities.h" #include "input.h" #include "sound_manager.h" #include "camera.h" #include "interface_v3/interface_manager.h" using namespace NLMISC; using namespace NL3D; void updateVRDevicesComboUI(); // from action_handler_game.cpp void initStereoDisplayDevice(); // from init.cpp void releaseStereoDisplayDevice(); // from release.cpp //--------------------------------------------------- // Compare ClientCfg and LastClientCfg to know what we must update //--------------------------------------------------- void updateFromClientCfg() { CClientConfig::setValues(); ClientCfg.IsInvalidated = false; if ((ClientCfg.VREnable != LastClientCfg.VREnable) || (ClientCfg.VREnable && ( ClientCfg.VRDisplayDevice != LastClientCfg.VRDisplayDevice || ClientCfg.VRDisplayDeviceId != LastClientCfg.VRDisplayDeviceId ))) { nldebug("Apply VR device change"); // detach display mode if (StereoDisplay && StereoDisplayAttached) StereoDisplay->detachFromDisplay(); StereoDisplayAttached = false; // re-init releaseStereoDisplayDevice(); initStereoDisplayDevice(); // try attach display mode if (StereoDisplay) StereoDisplayAttached = StereoDisplay->attachToDisplay(); // set latest config display mode if not attached if (!StereoDisplayAttached) setVideoMode(UDriver::CMode(ClientCfg.Width, ClientCfg.Height, (uint8)ClientCfg.Depth, ClientCfg.Windowed, ClientCfg.Frequency, -1, ClientCfg.MonitorName)); // force software cursor when attached InitMouseWithCursor(ClientCfg.HardwareCursor && !StereoDisplayAttached); } // GRAPHICS - GENERAL //--------------------------------------------------- if ((ClientCfg.Windowed != LastClientCfg.Windowed) || (ClientCfg.Width != LastClientCfg.Width) || (ClientCfg.Height != LastClientCfg.Height) || (ClientCfg.Depth != LastClientCfg.Depth) || (ClientCfg.Frequency != LastClientCfg.Frequency)|| (ClientCfg.MonitorName != LastClientCfg.MonitorName)) { if (!StereoDisplayAttached) { setVideoMode(UDriver::CMode(ClientCfg.Width, ClientCfg.Height, (uint8)ClientCfg.Depth, ClientCfg.Windowed, ClientCfg.Frequency, -1, ClientCfg.MonitorName)); } } if (ClientCfg.DivideTextureSizeBy2 != LastClientCfg.DivideTextureSizeBy2) { if (ClientCfg.DivideTextureSizeBy2) Driver->forceTextureResize(2); else Driver->forceTextureResize(1); } if (ClientCfg.InterfaceScale != LastClientCfg.InterfaceScale) CInterfaceManager::getInstance()->setInterfaceScale(ClientCfg.InterfaceScale); if (ClientCfg.BilinearUI != LastClientCfg.BilinearUI) CViewRenderer::getInstance()->setBilinearFiltering(ClientCfg.BilinearUI); CWidgetManager::getInstance()->setWindowSnapInvert(ClientCfg.WindowSnapInvert); CWidgetManager::getInstance()->setWindowSnapDistance(ClientCfg.WindowSnapDistance); //--------------------------------------------------- if (ClientCfg.WaitVBL != LastClientCfg.WaitVBL) { if(ClientCfg.WaitVBL) Driver->setSwapVBLInterval(1); else Driver->setSwapVBLInterval(0); } // GRAPHICS - LANDSCAPE //--------------------------------------------------- if (ClientCfg.LandscapeThreshold != LastClientCfg.LandscapeThreshold) { if (Landscape) Landscape->setThreshold(ClientCfg.getActualLandscapeThreshold()); } //--------------------------------------------------- if (ClientCfg.LandscapeTileNear != LastClientCfg.LandscapeTileNear) { if (Landscape) Landscape->setTileNear(ClientCfg.LandscapeTileNear); } //--------------------------------------------------- if (Landscape) { if (ClientCfg.Vision != LastClientCfg.Vision) { if (!ClientCfg.Light) { // Not in an indoor ? if (ContinentMngr.cur() && !ContinentMngr.cur()->Indoor) { // Refresh All Zone in streaming according to the refine position std::vector zonesAdded; std::vector zonesRemoved; const R2::CScenarioEntryPoints::CCompleteIsland *ci = R2::CScenarioEntryPoints::getInstance().getCompleteIslandFromCoords(CVector2f((float) UserEntity->pos().x, (float) UserEntity->pos().y)); Landscape->refreshAllZonesAround(View.refinePos(), ClientCfg.Vision + ExtraZoneLoadingVision, zonesAdded, zonesRemoved, ProgressBar, ci ? &(ci->ZoneIDs) : NULL); LandscapeIGManager.unloadArrayZoneIG(zonesRemoved); LandscapeIGManager.loadArrayZoneIG(zonesAdded); } } } } //--------------------------------------------------- if (ClientCfg.Vision != LastClientCfg.Vision || ClientCfg.FoV!=LastClientCfg.FoV || ClientCfg.Windowed != LastClientCfg.Windowed || ClientCfg.ScreenAspectRatio != LastClientCfg.ScreenAspectRatio ) { updateCameraPerspective(); } //--------------------------------------------------- if (Landscape) { if (ClientCfg.MicroVeget != LastClientCfg.MicroVeget) { if(ClientCfg.MicroVeget) { // if configured, enable the vegetable and load the texture. Landscape->enableVegetable(true); // Default setup. TODO later by gameDev. Landscape->setVegetableWind(CVector(0.5, 0.5, 0).normed(), 0.5, 1, 0); // Default setup. should work well for night/day transition in 30 minutes. // Because all vegetables will be updated every 20 seconds => 90 steps. Landscape->setVegetableUpdateLightingFrequency(1/20.f); // Density (percentage to ratio) Landscape->setVegetableDensity(ClientCfg.MicroVegetDensity/100.f); } else { Landscape->enableVegetable(false); } } } //--------------------------------------------------- if (ClientCfg.MicroVegetDensity != LastClientCfg.MicroVegetDensity) { // Density (percentage to ratio) if (Landscape) Landscape->setVegetableDensity(ClientCfg.MicroVegetDensity/100.f); } // GRAPHICS - SPECIAL EFFECTS //--------------------------------------------------- if (ClientCfg.FxNbMaxPoly != LastClientCfg.FxNbMaxPoly) { if (Scene->getGroupLoadMaxPolygon("Fx") != ClientCfg.FxNbMaxPoly) Scene->setGroupLoadMaxPolygon("Fx", ClientCfg.FxNbMaxPoly); } //--------------------------------------------------- if (ClientCfg.Cloud != LastClientCfg.Cloud) { if (ClientCfg.Cloud) { InitCloudScape = true; CloudScape = Scene->createCloudScape(); } else { if (CloudScape != NULL) Scene->deleteCloudScape(CloudScape); CloudScape = NULL; } } //--------------------------------------------------- if (ClientCfg.CloudQuality != LastClientCfg.CloudQuality) { if (CloudScape != NULL) CloudScape->setQuality(ClientCfg.CloudQuality); } //--------------------------------------------------- if (ClientCfg.CloudUpdate != LastClientCfg.CloudUpdate) { if (CloudScape != NULL) CloudScape->setNbCloudToUpdateIn80ms(ClientCfg.CloudUpdate); } //--------------------------------------------------- if (ClientCfg.Shadows != LastClientCfg.Shadows) { // Enable/Disable Receive on Landscape if(Landscape) { Landscape->enableReceiveShadowMap(ClientCfg.Shadows); } // Enable/Disable Cast for all entities for(uint i=0;iupdateCastShadowMap(); } } //--------------------------------------------------- if (ClientCfg.AnisotropicFilter != LastClientCfg.AnisotropicFilter) { Driver->setAnisotropicFilter(ClientCfg.AnisotropicFilter); } //--------------------------------------------------- if (ClientCfg.FXAA != LastClientCfg.FXAA) { if (ClientCfg.FXAA) { nlassert(!FXAA); FXAA = new NL3D::CFXAA(Driver); } else { nlassert(FXAA); delete FXAA; FXAA = NULL; } } // GRAPHICS - CHARACTERS //--------------------------------------------------- if (ClientCfg.SkinNbMaxPoly != LastClientCfg.SkinNbMaxPoly) { if (Scene->getGroupLoadMaxPolygon("Skin") != ClientCfg.SkinNbMaxPoly) Scene->setGroupLoadMaxPolygon("Skin", ClientCfg.SkinNbMaxPoly); } //--------------------------------------------------- if (ClientCfg.NbMaxSkeletonNotCLod != LastClientCfg.NbMaxSkeletonNotCLod ) { Scene->setMaxSkeletonsInNotCLodForm(ClientCfg.NbMaxSkeletonNotCLod); } //--------------------------------------------------- if (ClientCfg.CharacterFarClip != LastClientCfg.CharacterFarClip) { // Nothing to do } //--------------------------------------------------- if (ClientCfg.HDEntityTexture != LastClientCfg.HDEntityTexture) { // Don't reload Texture, will be done at next Game Start } // INTERFACE works // INPUTS //--------------------------------------------------- if (ClientCfg.CursorSpeed != LastClientCfg.CursorSpeed) SetMouseSpeed (ClientCfg.CursorSpeed); if (ClientCfg.CursorAcceleration != LastClientCfg.CursorAcceleration) SetMouseAcceleration (ClientCfg.CursorAcceleration); if (ClientCfg.HardwareCursor != LastClientCfg.HardwareCursor) { if (ClientCfg.HardwareCursor != IsMouseCursorHardware()) { InitMouseWithCursor (ClientCfg.HardwareCursor && !StereoDisplayAttached); } } // SOUND //--------------------------------------------------- bool mustReloadSoundMngrContinent= false; // disable/enable sound? if (ClientCfg.SoundOn != LastClientCfg.SoundOn) { if (SoundMngr && !ClientCfg.SoundOn) { nlwarning("Deleting sound manager..."); delete SoundMngr; SoundMngr = NULL; } else if (SoundMngr == NULL && ClientCfg.SoundOn) { nlwarning("Creating sound manager..."); SoundMngr = new CSoundManager(); try { SoundMngr->init(NULL); } catch(const Exception &e) { nlwarning("init : Error when creating 'SoundMngr' : %s", e.what()); delete SoundMngr; SoundMngr = NULL; } // re-init with good SFX/Music Volume if(SoundMngr) { SoundMngr->setSFXVolume(ClientCfg.SoundSFXVolume); SoundMngr->setGameMusicVolume(ClientCfg.SoundGameMusicVolume); } } else { nlwarning("Sound config error !"); } mustReloadSoundMngrContinent= true; } // change EAX? if ( SoundMngr && LastClientCfg.SoundOn && (ClientCfg.UseEax != LastClientCfg.UseEax) ) { SoundMngr->reset(); mustReloadSoundMngrContinent= true; } // change SoundForceSoftwareBuffer? if ( SoundMngr && LastClientCfg.SoundOn && (ClientCfg.SoundForceSoftwareBuffer != LastClientCfg.SoundForceSoftwareBuffer) ) { SoundMngr->reset(); mustReloadSoundMngrContinent= true; } // change MaxTrack? don't reset if ( SoundMngr && LastClientCfg.SoundOn && (ClientCfg.MaxTrack != LastClientCfg.MaxTrack)) { SoundMngr->getMixer()->changeMaxTrack(ClientCfg.MaxTrack); } // change SoundFX Volume? don't reset if (SoundMngr && ClientCfg.SoundSFXVolume != LastClientCfg.SoundSFXVolume) { SoundMngr->setSFXVolume(ClientCfg.SoundSFXVolume); } // change Game Music Volume? don't reset if (SoundMngr && ClientCfg.SoundGameMusicVolume != LastClientCfg.SoundGameMusicVolume) { SoundMngr->setGameMusicVolume(ClientCfg.SoundGameMusicVolume); } // reload only if active and reseted if (mustReloadSoundMngrContinent && SoundMngr && ContinentMngr.cur() && !ContinentMngr.cur()->Indoor && UserEntity) { SoundMngr->loadContinent(ContinentMngr.getCurrentContinentSelectName(), UserEntity->pos()); } // Ok backup the new clientcfg LastClientCfg = ClientCfg; } /* end of file */