1 /* Copyright (C) 2016 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "precompiled.h"
19 
20 #include "MessageHandler.h"
21 
22 #include "../CommandProc.h"
23 
24 #include "graphics/LightEnv.h"
25 #include "graphics/Terrain.h"
26 #include "maths/MathUtil.h"
27 #include "ps/CStr.h"
28 #include "ps/Game.h"
29 #include "ps/World.h"
30 #include "renderer/PostprocManager.h"
31 #include "renderer/Renderer.h"
32 #include "renderer/SkyManager.h"
33 #include "renderer/WaterManager.h"
34 #include "simulation2/Simulation2.h"
35 #include "simulation2/components/ICmpWaterManager.h"
36 
37 namespace AtlasMessage {
38 
GetSettings()39 sEnvironmentSettings GetSettings()
40 {
41 	sEnvironmentSettings s;
42 
43 	CmpPtr<ICmpWaterManager> cmpWaterManager(*g_Game->GetSimulation2(), SYSTEM_ENTITY);
44 	ENSURE(cmpWaterManager);
45 
46 	s.waterheight = cmpWaterManager->GetExactWaterLevel(0, 0) / (65536.f * HEIGHT_SCALE);
47 
48 	WaterManager* wm = g_Renderer.GetWaterManager();
49 	s.watertype = wm->m_WaterType;
50 	s.waterwaviness = wm->m_Waviness;
51 	s.watermurkiness = wm->m_Murkiness;
52 	s.windangle = wm->m_WindAngle;
53 
54 	// CColor colors
55 #define COLOR(A, B) A = Color((int)(B.r*255), (int)(B.g*255), (int)(B.b*255))
56 	COLOR(s.watercolor, wm->m_WaterColor);
57 	COLOR(s.watertint, wm->m_WaterTint);
58 #undef COLOR
59 
60 	float sunrotation = g_LightEnv.GetRotation();
61 	if (sunrotation > (float)M_PI)
62 		sunrotation -= (float)M_PI*2;
63 	s.sunrotation = sunrotation;
64 	s.sunelevation = g_LightEnv.GetElevation();
65 
66 	s.posteffect = g_Renderer.GetPostprocManager().GetPostEffect();
67 
68 	s.skyset = g_Renderer.GetSkyManager()->GetSkySet();
69 
70 	s.fogfactor = g_LightEnv.m_FogFactor;
71 	s.fogmax = g_LightEnv.m_FogMax;
72 
73 	s.brightness = g_LightEnv.m_Brightness;
74 	s.contrast = g_LightEnv.m_Contrast;
75 	s.saturation = g_LightEnv.m_Saturation;
76 	s.bloom = g_LightEnv.m_Bloom;
77 
78 	// RGBColor (CVector3D) colors
79 #define COLOR(A, B) A = Color((int)(B.X*255), (int)(B.Y*255), (int)(B.Z*255))
80 	s.sunoverbrightness = MaxComponent(g_LightEnv.m_SunColor);
81 	// clamp color to [0..1] before packing into u8 triplet
82 	if(s.sunoverbrightness > 1.0f)
83 		g_LightEnv.m_SunColor *= 1.0/s.sunoverbrightness;	// (there's no operator/=)
84 	// no component was above 1.0, so reset scale factor (don't want to darken)
85 	else
86 		s.sunoverbrightness = 1.0f;
87 	COLOR(s.suncolor, g_LightEnv.m_SunColor);
88 	COLOR(s.terraincolor, g_LightEnv.m_TerrainAmbientColor);
89 	COLOR(s.unitcolor, g_LightEnv.m_UnitsAmbientColor);
90 	COLOR(s.fogcolor, g_LightEnv.m_FogColor);
91 #undef COLOR
92 
93 	return s;
94 }
95 
SetSettings(const sEnvironmentSettings & s)96 void SetSettings(const sEnvironmentSettings& s)
97 {
98 	CmpPtr<ICmpWaterManager> cmpWaterManager(*g_Game->GetSimulation2(), SYSTEM_ENTITY);
99 	ENSURE(cmpWaterManager);
100 
101 	cmpWaterManager->SetWaterLevel(entity_pos_t::FromFloat(s.waterheight * (65536.f * HEIGHT_SCALE)));
102 
103 	WaterManager* wm = g_Renderer.GetWaterManager();
104 	wm->m_Waviness = s.waterwaviness;
105 	wm->m_Murkiness = s.watermurkiness;
106 	wm->m_WindAngle = s.windangle;
107 	if (wm->m_WaterType != *s.watertype)
108 	{
109 		wm->m_WaterType = *s.watertype;
110 		wm->ReloadWaterNormalTextures();
111 	}
112 
113 #define COLOR(A, B) B = CColor(A->r/255.f, A->g/255.f, A->b/255.f, 1.f)
114 	COLOR(s.watercolor, wm->m_WaterColor);
115 	COLOR(s.watertint, wm->m_WaterTint);
116 #undef COLOR
117 
118 	g_LightEnv.SetRotation(s.sunrotation);
119 	g_LightEnv.SetElevation(s.sunelevation);
120 
121 	CStrW posteffect = *s.posteffect;
122 	if (posteffect.length() == 0)
123 		posteffect = L"default";
124 	g_Renderer.GetPostprocManager().SetPostEffect(posteffect);
125 
126 	CStrW skySet = *s.skyset;
127 	if (skySet.length() == 0)
128 		skySet = L"default";
129 	g_Renderer.GetSkyManager()->SetSkySet(skySet);
130 
131 	g_LightEnv.m_FogFactor = s.fogfactor;
132 	g_LightEnv.m_FogMax = s.fogmax;
133 
134 	g_LightEnv.m_Brightness = s.brightness;
135 	g_LightEnv.m_Contrast = s.contrast;
136 	g_LightEnv.m_Saturation = s.saturation;
137 	g_LightEnv.m_Bloom = s.bloom;
138 
139 #define COLOR(A, B) B = RGBColor(A->r/255.f, A->g/255.f, A->b/255.f)
140 	COLOR(s.suncolor, g_LightEnv.m_SunColor);
141 	g_LightEnv.m_SunColor *= s.sunoverbrightness;
142 	COLOR(s.terraincolor, g_LightEnv.m_TerrainAmbientColor);
143 	COLOR(s.unitcolor, g_LightEnv.m_UnitsAmbientColor);
144 	COLOR(s.fogcolor, g_LightEnv.m_FogColor);
145 #undef COLOR
146 
147 	cmpWaterManager->RecomputeWaterData();
148 }
149 
BEGIN_COMMAND(SetEnvironmentSettings)150 BEGIN_COMMAND(SetEnvironmentSettings)
151 {
152 	sEnvironmentSettings m_OldSettings, m_NewSettings;
153 
154 	void Do()
155 	{
156 		m_OldSettings = GetSettings();
157 		m_NewSettings = msg->settings;
158 		Redo();
159 	}
160 
161 	void Redo()
162 	{
163 		SetSettings(m_NewSettings);
164 	}
165 
166 	void Undo()
167 	{
168 		SetSettings(m_OldSettings);
169 	}
170 
171 	void MergeIntoPrevious(cSetEnvironmentSettings* prev)
172 	{
173 		prev->m_NewSettings = m_NewSettings;
174 	}
175 };
176 END_COMMAND(SetEnvironmentSettings)
177 
BEGIN_COMMAND(RecalculateWaterData)178 BEGIN_COMMAND(RecalculateWaterData)
179 {
180 	void Do()
181 	{
182 		Redo();
183 	}
184 
185 	void Redo()
186 	{
187 		CmpPtr<ICmpWaterManager> cmpWaterManager(*g_Game->GetSimulation2(), SYSTEM_ENTITY);
188 		ENSURE(cmpWaterManager);
189 
190 		cmpWaterManager->RecomputeWaterData();
191 	}
192 
193 	void Undo()
194 	{
195 		Redo();
196 	}
197 
198 };
199 END_COMMAND(RecalculateWaterData)
200 
201 
QUERYHANDLER(GetEnvironmentSettings)202 QUERYHANDLER(GetEnvironmentSettings)
203 {
204 	msg->settings = GetSettings();
205 }
206 
QUERYHANDLER(GetSkySets)207 QUERYHANDLER(GetSkySets)
208 {
209 	std::vector<CStrW> skies = g_Renderer.GetSkyManager()->GetSkySets();
210 	msg->skysets = std::vector<std::wstring>(skies.begin(), skies.end());
211 }
212 
213 
QUERYHANDLER(GetPostEffects)214 QUERYHANDLER(GetPostEffects)
215 {
216 	std::vector<CStrW> effects = g_Renderer.GetPostprocManager().GetPostEffects();
217 	msg->posteffects = std::vector<std::wstring>(effects.begin(), effects.end());
218 }
219 
220 }
221