OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4Sky.cpp
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 1998-2000, Matthes Bender
5  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
6  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
7  *
8  * Distributed under the terms of the ISC license; see accompanying file
9  * "COPYING" for details.
10  *
11  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
12  * See accompanying file "TRADEMARK" for details.
13  *
14  * To redistribute this file separately, substitute the full license texts
15  * for the above references.
16  */
17 
18 /* Small member of the landscape class to handle the sky background */
19 
20 #include "C4Include.h"
21 #include "landscape/C4Sky.h"
22 
23 #include "game/C4Game.h"
24 #include "lib/C4Random.h"
25 #include "c4group/C4Components.h"
26 #include "landscape/C4Weather.h"
28 #include "graphics/C4Draw.h"
29 #include "lib/StdColors.h"
30 
31 void C4Sky::SetFadePalette(int32_t *ipColors)
32 {
33  // If colors all zero, use game palette default blue
34  if (ipColors[0]+ipColors[1]+ipColors[2]+ipColors[3]+ipColors[4]+ipColors[5]==0)
35  {
36  FadeClr1=C4RGB(0x1c, 0x40, 0x99);
37  FadeClr2=C4RGB(0xc2, 0xc6, 0xff);
38  }
39  else
40  {
41  // set colors
42  FadeClr1=C4RGB(ipColors[0], ipColors[1], ipColors[2]);
43  FadeClr2=C4RGB(ipColors[3], ipColors[4], ipColors[5]);
44  }
45 }
46 
47 bool C4Sky::Init(bool fSavegame, std::string names)
48 {
49  // reset scrolling pos+speed
50  // not in savegame, because it will have been loaded from game data there
51  if (!fSavegame)
52  {
53  x=y=xdir=ydir=0; ParX=ParY=10; ParallaxMode=0;
54  }
55 
56  // Check for sky bitmap in scenario file
57  Surface = new C4Surface();
58  bool loaded = false;
59  if (names.empty())
60  {
62  }
63 
64  // Else, evaluate scenario core landscape sky default list
65  if (!loaded)
66  {
67  if (names.empty()) names = Game.C4S.Landscape.SkyDef;
68  static std::regex separator(R"([,;\s]+)");
69  std::vector<std::string> parts;
70  std::copy(
71  std::sregex_token_iterator(names.begin(), names.end(), separator, -1),
72  std::sregex_token_iterator(),
73  std::back_inserter(parts));
74 
75  auto name = parts.at(SeededRandom(Game.RandomSeed, parts.size()));
76  // Sky tile specified, try load
77  if (name != "Default")
78  {
79  // Check for sky tile in scenario file
80  loaded = !!Surface->LoadAny(Game.ScenarioFile, name.c_str(), true, true, C4SF_Tileable | C4SF_MipMap);
81  if (!loaded)
82  {
83  loaded = !!Surface->LoadAny(::GraphicsResource.Files, name.c_str(), true, false, C4SF_Tileable | C4SF_MipMap);
84  }
85  }
86  }
87 
88  if (loaded)
89  {
90  // surface loaded, store first color index
91  FadeClr1=FadeClr2=0xffffffff;
92 
93  // set parallax scroll mode
95  {
96  case 0: // default: no scrolling
97  break;
98  case 1: // go with the wind in xdir, and do some parallax scrolling in ydir
100  ParY=20;
101  break;
102  case 2: // parallax in both directions
103  ParX=ParY=20;
104  break;
105  }
106 
107  }
108 
109 
110  // Else, try creating default Surface
111  if (!loaded)
112  {
114  delete Surface;
115  Surface = 0;
116  }
117 
118  // Load sky shaders: regular sprite shaders with OC_SKY define
119  const char* const SkyDefines[] = { "OC_SKY", nullptr };
120  if (!pDraw->PrepareSpriteShader(Shader, "Sky", Surface ? C4SSC_BASE : 0, &::GraphicsResource.Files, SkyDefines, nullptr))
121  return false;
122  if (!pDraw->PrepareSpriteShader(ShaderLight, "SkyLight", (Surface ? C4SSC_BASE : 0) | C4SSC_LIGHT, &::GraphicsResource.Files, SkyDefines, nullptr))
123  return false;
124 
125  // no sky - using fade in newgfx
126  if (!Surface)
127  return true;
128 
129  // Store size
130  if (Surface)
131  {
132  int iWdt,iHgt;
133  if (Surface->GetSurfaceSize(iWdt, iHgt))
134  {
135  Width = iWdt; Height = iHgt;
136  }
137  }
138 
139  // Success
140  return true;
141 }
142 
144 {
145  Width=Height=0;
146  Surface=nullptr;
147  x=y=xdir=ydir=0;
148  Modulation=0xffffffff;
149  ParX=ParY=10;
151  BackClr=0;
152  BackClrEnabled=false;
153 }
154 
156 {
157  Clear();
158 }
159 
161 {
162  Shader.Clear();
163  ShaderLight.Clear();
164  delete Surface; Surface=nullptr;
165  Modulation=0xffffffff;
166 }
167 
169 {
170  // surface exists?
171  if (!Surface) return;
172  // advance pos
173  x+=xdir; y+=ydir;
174  // clip by bounds
175  if (x>=itofix(Width)) x-=itofix(Width);
176  if (y>=itofix(Height)) y-=itofix(Height);
177  // update speed
179 }
180 
182 {
183  // background color?
184  if (BackClrEnabled) pDraw->DrawBoxDw(cgo.Surface, cgo.X, cgo.Y, cgo.X+cgo.Wdt, cgo.Y+cgo.Hgt, BackClr);
185  // sky surface?
186  if (Modulation != 0xffffffff) pDraw->ActivateBlitModulation(Modulation);
187  C4ShaderCall call(pDraw->GetFoW() ? &ShaderLight : &Shader); // call is started in C4Draw
188  if (Surface)
189  {
190  // blit parallax sky
191  float zoom = cgo.Zoom;
192  float targetx = cgo.TargetX; float targety = cgo.TargetY;
193 
194  float parx = 10.0f / ParX; float pary = 10.0f / ParY;
195  float par = parx; //todo: pary?
196 
197  // Step 1: project to landscape coordinates
198  float resultzoom = 1.0 / (1.0 - (par - par/zoom));
199 
200  float rx = ((1 - parx) * targetx) * resultzoom + fixtof(x) / (parx + zoom - parx * zoom);
201  float ry = ((1 - pary) * targety) * resultzoom + fixtof(y) / (pary + zoom - pary * zoom);
202 
203  // Step 2: convert to screen coordinates
204  float resultx = (rx - targetx) * zoom / resultzoom;
205  float resulty = (ry - targety) * zoom / resultzoom;
206 
207  ZoomDataStackItem zdsi(resultzoom);
208 
209  pDraw->BlitSurfaceTile(Surface, cgo.Surface, cgo.X, cgo.Y, cgo.Wdt * zoom / resultzoom, cgo.Hgt * zoom / resultzoom, -resultx, -resulty, &call);
210  }
211  else
212  {
213  // no sky surface: blit sky fade
214  DWORD dwClr1=GetSkyFadeClr(cgo.TargetY);
215  DWORD dwClr2=GetSkyFadeClr(cgo.TargetY+cgo.Hgt);
216  pDraw->DrawBoxFade(cgo.Surface, cgo.X, cgo.Y, cgo.Wdt, cgo.Hgt, dwClr1, dwClr1, dwClr2, dwClr2, &call);
217  }
218  if (Modulation != 0xffffffff) pDraw->DeactivateBlitModulation();
219  // done
220 }
221 
223 {
224  int32_t iPos2=(iY*256)/::Landscape.GetHeight(); int32_t iPos1=256-iPos2;
225  return (((((FadeClr1&0xff00ff)*iPos1 + (FadeClr2&0xff00ff)*iPos2) & 0xff00ff00)
226  | (((FadeClr1&0x00ff00)*iPos1 + (FadeClr2&0x00ff00)*iPos2) & 0x00ff0000))>>8)
227  | (FadeClr1 & 0xff000000);
228 }
229 
230 bool C4Sky::SetModulation(DWORD dwWithClr, DWORD dwBackClr)
231 {
232  Modulation=dwWithClr;
233  BackClr=dwBackClr;
234  BackClrEnabled=(Modulation>>24 != 0xff) ? true : false;
235  return true;
236 }
237 
239 {
240  pComp->Value(mkNamingAdapt(mkCastIntAdapt(x), "X", Fix0));
241  pComp->Value(mkNamingAdapt(mkCastIntAdapt(y), "Y", Fix0));
242  pComp->Value(mkNamingAdapt(mkCastIntAdapt(xdir),"XDir", Fix0));
243  pComp->Value(mkNamingAdapt(mkCastIntAdapt(ydir),"YDir", Fix0));
244  pComp->Value(mkNamingAdapt(Modulation, "Modulation", 0xffffffffU));
245  pComp->Value(mkNamingAdapt(ParX, "ParX", 10));
246  pComp->Value(mkNamingAdapt(ParY, "ParY", 10));
247  pComp->Value(mkNamingAdapt(ParallaxMode, "ParMode", C4SkyPM_Fixed));
248  pComp->Value(mkNamingAdapt(BackClr, "BackClr", 0));
249  pComp->Value(mkNamingAdapt(BackClrEnabled, "BackClrEnabled", false));
250 }
int32_t RandomSeed
Definition: C4Game.h:136
float Y
Definition: C4Facet.h:120
float Zoom
Definition: C4Facet.h:167
~C4Sky()
Definition: C4Sky.cpp:155
class C4Surface * Surface
Definition: C4Sky.h:53
C4Game Game
Definition: C4Globals.cpp:52
C4Scenario C4S
Definition: C4Game.h:76
C4SLandscape Landscape
Definition: C4Scenario.h:234
int32_t ParallaxMode
Definition: C4Sky.h:60
void Execute()
Definition: C4Sky.cpp:168
C4Real C4REAL100(int x)
Definition: C4Real.h:267
void Default()
Definition: C4Sky.cpp:143
C4Shader ShaderLight
Definition: C4Sky.h:55
int32_t Wind
Definition: C4Weather.h:31
void Clear()
Definition: C4Sky.cpp:160
C4GraphicsResource GraphicsResource
void CompileFunc(StdCompiler *pComp)
Definition: C4Sky.cpp:238
StdCastAdapt< T, int32_t > mkCastIntAdapt(T &rValue)
Definition: StdAdaptors.h:253
int32_t SkyScrollMode
Definition: C4Scenario.h:184
C4Real x
Definition: C4Sky.h:57
bool LoadAny(C4Group &hGroup, const char *szFilename, bool fOwnPal, bool fNoErrIfNotFound, int iFlags)
StdNamingAdapt< T > mkNamingAdapt(T &&rValue, const char *szName)
Definition: StdAdaptors.h:93
const C4FoWRegion * GetFoW() const
Definition: C4Draw.h:194
void SetFadePalette(int32_t *ipColors)
Definition: C4Sky.cpp:31
#define C4CFN_Sky
Definition: C4Components.h:65
C4Real y
Definition: C4Sky.h:57
uint32_t FadeClr1
Definition: C4Sky.h:59
bool BlitSurfaceTile(C4Surface *sfcSurface, C4Surface *sfcTarget, float iToX, float iToY, float iToWdt, float iToHgt, float iOffsetX, float iOffsetY, C4ShaderCall *shader_call)
Definition: C4Draw.cpp:538
void Draw(C4TargetFacet &cgo)
Definition: C4Sky.cpp:181
C4Landscape Landscape
void Clear()
Definition: C4Shader.cpp:337
bool GetSurfaceSize(int &irX, int &irY)
Definition: C4Surface.cpp:454
void DrawBoxDw(C4Surface *sfcDest, int iX1, int iY1, int iX2, int iY2, DWORD dwClr)
Definition: C4Draw.cpp:849
const int C4SF_Tileable
Definition: C4Surface.h:51
C4Group ScenarioFile
Definition: C4Game.h:88
const int C4SF_MipMap
Definition: C4Surface.h:52
int32_t SkyDefFade[6]
Definition: C4Scenario.h:172
C4Shader Shader
Definition: C4Sky.h:54
C4Fixed itofix(int32_t x)
Definition: C4Real.h:261
C4Draw * pDraw
Definition: C4Draw.cpp:45
C4Weather Weather
Definition: C4Weather.cpp:207
#define C4RGB(r, g, b)
Definition: StdColors.h:28
#define C4SkyPM_Wind
Definition: C4Sky.h:27
void Value(const T &rStruct)
Definition: StdCompiler.h:171
void DrawBoxFade(C4Surface *sfcDest, float iX, float iY, float iWdt, float iHgt, DWORD dwClr1, DWORD dwClr2, DWORD dwClr3, DWORD dwClr4, C4ShaderCall *shader_call)
Definition: C4Draw.cpp:833
int32_t ParX
Definition: C4Sky.h:58
virtual bool PrepareSpriteShader(C4Shader &shader, const char *name, int ssc, C4GroupSet *pGroups, const char *const *additionalDefines, const char *const *additionalSlices)=0
C4Real ydir
Definition: C4Sky.h:56
int32_t GetHeight() const
bool SetModulation(DWORD dwWithClr, DWORD dwBackClr)
Definition: C4Sky.cpp:230
bool BackClrEnabled
Definition: C4Sky.h:51
bool Init(bool fSavegame, std::string names="")
Definition: C4Sky.cpp:47
float TargetX
Definition: C4Facet.h:167
int32_t BackClr
Definition: C4Sky.h:50
#define C4SkyPM_Fixed
Definition: C4Sky.h:26
int32_t ParY
Definition: C4Sky.h:58
float Hgt
Definition: C4Facet.h:120
uint32_t Modulation
Definition: C4Sky.h:49
float fixtof(const C4Fixed &x)
Definition: C4Real.h:257
C4Real xdir
Definition: C4Sky.h:56
void DeactivateBlitModulation()
Definition: C4Draw.h:189
DWORD GetSkyFadeClr(int32_t iY)
Definition: C4Sky.cpp:222
void ActivateBlitModulation(DWORD dwWithClr)
Definition: C4Draw.h:188
C4Surface * Surface
Definition: C4Facet.h:119
float TargetY
Definition: C4Facet.h:167
uint32_t DWORD
uint32_t SeededRandom(uint64_t iSeed, uint32_t iRange)
Definition: C4Random.cpp:69
std::string SkyDef
Definition: C4Scenario.h:171
float Wdt
Definition: C4Facet.h:120
float X
Definition: C4Facet.h:120
int32_t Width
Definition: C4Sky.h:48
uint32_t FadeClr2
Definition: C4Sky.h:59
const C4Real Fix0
Definition: C4Real.h:312
int32_t Height
Definition: C4Sky.h:48