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