OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
C4MapScript.h
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) 2013-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 /* Handles scripted map creation */
19 
20 #ifndef INC_C4MapScript
21 #define INC_C4MapScript
22 
24 #include "script/C4Aul.h"
25 #include "script/C4ScriptHost.h"
26 #include "lib/C4Rect.h"
27 #include "graphics/CSurface8.h"
28 #include "landscape/C4Landscape.h"
29 
30 // mattex masks: Array of bools for each possible material-texture index
32 {
33  std::vector<bool> sky_mask; // vector of size C4M_MaxTexIndex + 1: true means pixel color is let through; false means it is blocked
34  std::vector<bool> tunnel_mask; // vector of size C4M_MaxTexIndex + 1: true means pixel color is let through; false means it is blocked
35 
36  // sky_mask stores the mask for pixels with sky or transparent background, and tunnel_mask
37  // stores the mask for pixels with non-sky background. We don't allow
38  // different masks for different background materials since this would
39  // need a C4M_MaxTexIndex + 1 x C4M_MaxTexIndex + 1 matrix to account
40  // for each possible combination of foreground and background pixel.
41 
42  void UnmaskSpec(C4String *spec);
43 public:
44  C4MapScriptMatTexMask() : sky_mask(C4M_MaxTexIndex + 1,false), tunnel_mask(C4M_MaxTexIndex + 1, false) { }
45  C4MapScriptMatTexMask(const C4Value &spec) : sky_mask(C4M_MaxTexIndex + 1, false), tunnel_mask(C4M_MaxTexIndex + 1, false) { Init(spec); }
46  void Init(const C4Value &spec);
47 
48  bool operator()(uint8_t fg, uint8_t bg) const { if (bg == C4M_MaxTexIndex) return sky_mask[fg]; else return tunnel_mask[fg]; }
49 };
50 
51 // algorithms may be either indicator functions (int,int)->bool that tell whether a map pixel should be
52 // set (to be used in C4MapScriptLayer::Fill) or functions (int,int)->int that tell which material should
53 // be set (to be used in Fill or C4MapScriptLayer::Blit).
55 {
56 protected:
57  bool GetXYProps(const C4PropList *props, C4PropertyName k, int32_t *out_xy, bool zero_defaults);
58 public:
59  virtual bool operator () (int32_t x, int32_t y, uint8_t& fg, uint8_t& bg) const = 0;
60  virtual ~C4MapScriptAlgo() {}
61 };
62 
63 // List of possible algorithms. Also registered as script constants in void C4MapScriptHost::InitFunctionMap.
65 {
67 
69 
71 
76 
78  MAPALGO_Or = 31,
81 
86 
89 };
90 
91 // MAPALGO_Layer: Just query pixel in layer. Pixels outside the layer range are zero.
93 {
94  const class C4MapScriptLayer *layer;
95 public:
96  C4MapScriptAlgoLayer(const C4MapScriptLayer *layer) : layer(layer) {}
97  C4MapScriptAlgoLayer(const C4PropList *props);
98 
99  virtual bool operator () (int32_t x, int32_t y, uint8_t& fg, uint8_t& bg) const;
100 };
101 
102 // MAPALGO_RndChecker: checkerboard on which areas are randomly set or unset
104 {
105  int32_t seed, set_percentage, checker_wdt, checker_hgt;
106  bool is_fixed_offset;
107 public:
109 
110  virtual bool operator () (int32_t x, int32_t y, uint8_t& fg, uint8_t& bg) const;
111 };
112 
113 // MAPALGO_Rect: 1 for pixels contained in rect, 0 otherwise
115 {
116  C4Rect rect;
117 public:
118  C4MapScriptAlgoRect(const C4PropList *props);
119 
120  virtual bool operator () (int32_t x, int32_t y, uint8_t& fg, uint8_t& bg) const;
121 };
122 
123 // MAPALGO_Ellipsis: 1 for pixels within ellipsis, 0 otherwise
125 {
126  int32_t cx,cy;
127  int32_t wdt,hgt;
128 public:
129  C4MapScriptAlgoEllipsis(const C4PropList *props);
130 
131  virtual bool operator () (int32_t x, int32_t y, uint8_t& fg, uint8_t& bg) const;
132 };
133 
134 // MAPALGO_Polygon: 1 for pixels within polygon or on border, 0 otherwise
136 {
137  struct Pt { int32_t x,y; };
138  std::vector<Pt> poly;
139  int32_t wdt;
140  bool empty; // don't fill inside of polygon
141  bool open; // don't draw closing segment. only valid if empty=true
142 public:
143  C4MapScriptAlgoPolygon(const C4PropList *props);
144 
145  virtual bool operator () (int32_t x, int32_t y, uint8_t& fg, uint8_t& bg) const;
146 };
147 
148 // MAPALGO_Lines: 1 for pixels on stripes in direction ("X","Y"). Stripe distance "Distance". Optional offset "OffX", "OffY"
150 {
151  int32_t lx,ly,distance,ox,oy;
152  int64_t ll,dl; // (line width)^2 and distance * line width
153 public:
154  C4MapScriptAlgoLines(const C4PropList *props);
155 
156  virtual bool operator () (int32_t x, int32_t y, uint8_t& fg, uint8_t& bg) const;
157 };
158 
159 // base class for algo that takes one or more operands
161 {
162 protected:
163  std::vector<C4MapScriptAlgo *> operands;
164 public:
165  C4MapScriptAlgoModifier(const C4PropList *props, int32_t min_ops=0, int32_t max_ops=0);
167  void Clear();
168 };
169 
170 // MAPALGO_And: 0 if any of the operands is 0. Otherwise, returns value of last operand.
172 {
173 public:
175 
176  virtual bool operator () (int32_t x, int32_t y, uint8_t& fg, uint8_t& bg) const;
177 };
178 
179 // MAPALGO_Or: First nonzero operand
181 {
182 public:
184 
185  virtual bool operator () (int32_t x, int32_t y, uint8_t& fg, uint8_t& bg) const;
186 };
187 
188 // MAPALGO_Not: 1 if operand is 0, 0 otherwise.
190 {
191 public:
193 
194  virtual bool operator () (int32_t x, int32_t y, uint8_t& fg, uint8_t& bg) const;
195 };
196 
197 // MAPALGO_Xor: If exactly one of the two operands is nonzero, return it. Otherwise, return zero.
199 {
200 public:
202 
203  virtual bool operator () (int32_t x, int32_t y, uint8_t& fg, uint8_t& bg) const;
204 };
205 
206 // MAPALGO_Offset: Base layer shifted by ox,oy
208 {
209  int32_t ox,oy;
210 public:
211  C4MapScriptAlgoOffset(const C4PropList *props);
212 
213  virtual bool operator () (int32_t x, int32_t y, uint8_t& fg, uint8_t& bg) const;
214 };
215 
216 // MAPALGO_Scale: Base layer scaled by sx,sy percent from fixed point cx,cy
218 {
219  int32_t sx,sy,cx,cy;
220 public:
221  C4MapScriptAlgoScale(const C4PropList *props);
222 
223  virtual bool operator () (int32_t x, int32_t y, uint8_t& fg, uint8_t& bg) const;
224 };
225 
226 // MAPALGO_Rotate: Base layer rotated by angle r around point ox,oy
228 {
229  int32_t sr,cr,ox,oy;
230  enum {Precision=1000};
231 public:
232  C4MapScriptAlgoRotate(const C4PropList *props);
233 
234  virtual bool operator () (int32_t x, int32_t y, uint8_t& fg, uint8_t& bg) const;
235 };
236 
237 // MAPALGO_Turbulence: move by a random offset iterations times
239 {
240  int32_t amp[2], scale[2], seed, iterations;
241 public:
243 
244  virtual bool operator () (int32_t x, int32_t y, uint8_t& fg, uint8_t& bg) const;
245 };
246 
247 // MAPALGO_Border: Border of operand layer
249 {
250  int32_t left[2], top[2], right[2], bottom[2];
251  void ResolveBorderProps(int32_t *p);
252 public:
253  C4MapScriptAlgoBorder(const C4PropList *props);
254 
255  virtual bool operator () (int32_t x, int32_t y, uint8_t& fg, uint8_t& bg) const;
256 };
257 
258 // MAPALGO_Filter: Original color of operand if it's marked to go through filter. 0 otherwise.
260 {
261  C4MapScriptMatTexMask filter;
262 public:
263  C4MapScriptAlgoFilter(const C4PropList *props);
264 
265  virtual bool operator () (int32_t x, int32_t y, uint8_t& fg, uint8_t& bg) const;
266 };
267 
268 // layer of a script-controlled map
269 // C4M_MaxTexIndex can be used to mark Sky
271 {
272  std::unique_ptr<CSurface8> fg_surface;
273  std::unique_ptr<CSurface8> bg_surface;
274 protected:
276 
277 public:
278  C4MapScriptLayer(C4PropList *prototype, C4MapScriptMap *map);
280  virtual C4MapScriptLayer * GetMapScriptLayer() { return this; }
281  class C4MapScriptMap *GetMap() { return map; }
282 
283  // Surface management
284  bool CreateSurface(int32_t wdt, int32_t hgt);
285  void ClearSurface();
286  void SetSurfaces(std::unique_ptr<CSurface8> fg, std::unique_ptr<CSurface8> bg)
287  {
288  fg_surface = std::move(fg);
289  bg_surface = std::move(bg);
291  }
292  std::pair<std::unique_ptr<CSurface8>, std::unique_ptr<CSurface8>> ReleaseSurfaces()
293  {
294  return std::make_pair(std::move(fg_surface), std::move(bg_surface));
295  }
296  bool HasSurface() const { return fg_surface && fg_surface->Bits && bg_surface && bg_surface->Bits; }
297 
298  // Size management
299  void UpdateSurfaceSize(); // updates width and height properties by current surface
300  C4Rect GetBounds () const;
301  int32_t GetWdt() const { return fg_surface ? fg_surface->Wdt : 0; }
302  int32_t GetHgt() const { return fg_surface ? fg_surface->Hgt : 0; }
303 
304  // Pixel functions
305  uint8_t GetPix(int32_t x, int32_t y, uint8_t outside_col) const { return (!HasSurface()||x<0||y<0||x>=fg_surface->Wdt||y>=fg_surface->Hgt) ? outside_col : fg_surface->_GetPix(x,y); }
306  uint8_t GetBackPix(int32_t x, int32_t y, uint8_t outside_col) const { return (!HasSurface()||x<0||y<0||x>=bg_surface->Wdt||y>=bg_surface->Hgt) ? outside_col : bg_surface->_GetPix(x,y); }
307  bool SetPix(int32_t x, int32_t y, uint8_t fg, uint8_t bg) const { if (!HasSurface()||x<0||y<0||x>=bg_surface->Wdt||y>=bg_surface->Hgt) return false; fg_surface->_SetPix(x,y,fg); bg_surface->_SetPix(x,y,bg); return true; }
308  bool IsPixMasked(int32_t x, int32_t y) const { return GetPix(x,y,0) != 0 || GetBackPix(x,y,0) != 0; } // masking: If pixel is inside surface and not transparent
309  void ConvertSkyToTransparent(); // change all pixels that are C4M_MaxTexIndex to 0
310  int32_t GetPixCount(const C4Rect &rcBounds, const C4MapScriptMatTexMask &mask); // return number of pixels that match mask
311 
312  // Drawing functions
313  bool Fill(uint8_t fg, uint8_t bg, const C4Rect &rcBounds, const C4MapScriptAlgo *algo);
314  bool Blit(const C4Rect &rcBounds, const C4MapScriptAlgo *algo);
315  bool Blit(const C4MapScriptLayer *src, const C4Rect &src_rect, const C4MapScriptMatTexMask &mask, int32_t tx, int32_t ty);
316 
317  // Search functions
318  bool FindPos(const C4Rect &search_rect, const C4MapScriptMatTexMask &mask, int32_t *out_x, int32_t *out_y, int32_t max_tries);
319 };
320 
322 {
323  std::list<C4MapScriptLayer *> layers;
324 public:
325  C4MapScriptMap(C4PropList *prototype) : C4MapScriptLayer(prototype, nullptr) { map=this; }
327  void Clear();
328  virtual C4MapScriptMap * GetMapScriptMap() { return this; }
329 
330  C4MapScriptLayer *CreateLayer(int32_t wdt, int32_t hgt);
331 };
332 
333 // Script host for scenario Map.c, parsed in static MapLayer prop list context
334 // Also hosts engine functions MapLayer prop list.
336 {
337 private:
338  C4PropListStaticMember *LayerPrototype, *MapPrototype;
339 
340  C4MapScriptMap *CreateMap();
341 public:
342  C4MapScriptHost();
344  void InitFunctionMap(C4AulScriptEngine *pEngine);
345  virtual void AddEngineFunctions();
346  virtual bool Load(C4Group &, const char *, const char *, C4LangStringTable *);
347  virtual bool LoadData(const char *, const char *, C4LangStringTable *);
348  void Clear();
349  virtual C4PropListStatic * GetPropList();
350  bool InitializeMap(C4SLandscape *pLandscape, C4TextureMap *pTexMap, C4MaterialMap *pMatMap, uint32_t iPlayerCount, std::unique_ptr<CSurface8> *pmap_fg_surface, std::unique_ptr<CSurface8>* pmap_bg_surface);
351  C4PropListStatic *GetLayerPrototype() { return LayerPrototype; }
352 
355 };
356 
358 
359 #endif
void SetSurfaces(std::unique_ptr< CSurface8 > fg, std::unique_ptr< CSurface8 > bg)
Definition: C4MapScript.h:286
virtual bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const
bool Fill(uint8_t fg, uint8_t bg, const C4Rect &rcBounds, const C4MapScriptAlgo *algo)
C4MapScriptAlgoLines(const C4PropList *props)
bool HasSurface() const
Definition: C4MapScript.h:296
virtual bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const
bool IsPixMasked(int32_t x, int32_t y) const
Definition: C4MapScript.h:308
virtual bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const
C4MapScriptAlgoNot(const C4PropList *props)
Definition: C4MapScript.h:192
int32_t GetPixCount(const C4Rect &rcBounds, const C4MapScriptMatTexMask &mask)
virtual ~C4MapScriptLayer()
Definition: C4MapScript.h:279
C4MapScriptMap(C4PropList *prototype)
Definition: C4MapScript.h:325
virtual void AddEngineFunctions()
Definition: C4Rect.h:29
C4MapScriptAlgoRndChecker(const C4PropList *props)
bool InitializeMap(C4SLandscape *pLandscape, C4TextureMap *pTexMap, C4MaterialMap *pMatMap, uint32_t iPlayerCount, std::unique_ptr< CSurface8 > *pmap_fg_surface, std::unique_ptr< CSurface8 > *pmap_bg_surface)
C4Rect GetBounds() const
C4MapScriptAlgoAnd(const C4PropList *props)
Definition: C4MapScript.h:174
C4MapScriptAlgoRotate(const C4PropList *props)
C4MapScriptAlgoModifier(const C4PropList *props, int32_t min_ops=0, int32_t max_ops=0)
void InitFunctionMap(C4AulScriptEngine *pEngine)
C4MapScriptMatTexMask(const C4Value &spec)
Definition: C4MapScript.h:45
bool SetPix(int32_t x, int32_t y, uint8_t fg, uint8_t bg) const
Definition: C4MapScript.h:307
int32_t GetHgt() const
Definition: C4MapScript.h:302
C4MapScriptAlgoEllipsis(const C4PropList *props)
virtual bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const
bool FindPos(const C4Rect &search_rect, const C4MapScriptMatTexMask &mask, int32_t *out_x, int32_t *out_y, int32_t max_tries)
C4MaterialMap * pMatMap
Definition: C4MapScript.h:354
virtual C4MapScriptMap * GetMapScriptMap()
Definition: C4MapScript.h:328
int32_t GetWdt() const
Definition: C4MapScript.h:301
virtual ~C4MapScriptAlgoModifier()
Definition: C4MapScript.h:166
virtual bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const
virtual bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const
void ConvertSkyToTransparent()
C4TextureMap * pTexMap
Definition: C4MapScript.h:353
class C4MapScriptMap * GetMap()
Definition: C4MapScript.h:281
virtual C4PropListStatic * GetPropList()
const int C4M_MaxTexIndex
Definition: C4Constants.h:51
C4MapScriptLayer(C4PropList *prototype, C4MapScriptMap *map)
C4MapScriptAlgoRect(const C4PropList *props)
C4MapScriptLayer * CreateLayer(int32_t wdt, int32_t hgt)
virtual ~C4MapScriptAlgo()
Definition: C4MapScript.h:60
C4MapScriptAlgoType
Definition: C4MapScript.h:64
void UpdateSurfaceSize()
virtual bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const
virtual C4MapScriptLayer * GetMapScriptLayer()
Definition: C4MapScript.h:280
bool CreateSurface(int32_t wdt, int32_t hgt)
uint8_t GetBackPix(int32_t x, int32_t y, uint8_t outside_col) const
Definition: C4MapScript.h:306
std::pair< std::unique_ptr< CSurface8 >, std::unique_ptr< CSurface8 > > ReleaseSurfaces()
Definition: C4MapScript.h:292
C4MapScriptAlgoXor(const C4PropList *props)
Definition: C4MapScript.h:201
C4MapScriptAlgoLayer(const C4MapScriptLayer *layer)
Definition: C4MapScript.h:96
bool Blit(const C4Rect &rcBounds, const C4MapScriptAlgo *algo)
C4PropertyName
virtual bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const
C4MapScriptHost MapScript
C4MapScriptAlgoBorder(const C4PropList *props)
virtual bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const
C4MapScriptAlgoScale(const C4PropList *props)
C4MapScriptAlgoTurbulence(const C4PropList *props)
C4MapScriptAlgoOr(const C4PropList *props)
Definition: C4MapScript.h:183
virtual bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const
bool GetXYProps(const C4PropList *props, C4PropertyName k, int32_t *out_xy, bool zero_defaults)
std::vector< C4MapScriptAlgo * > operands
Definition: C4MapScript.h:163
virtual bool LoadData(const char *, const char *, C4LangStringTable *)
C4MapScriptAlgoOffset(const C4PropList *props)
virtual bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const =0
virtual bool Load(C4Group &, const char *, const char *, C4LangStringTable *)
C4MapScriptAlgoFilter(const C4PropList *props)
void Init(const C4Value &spec)
bool operator()(uint8_t fg, uint8_t bg) const
Definition: C4MapScript.h:48
virtual bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const
virtual bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const
virtual bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const
virtual bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const
class C4MapScriptMap * map
Definition: C4MapScript.h:275
virtual bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const
C4PropListStatic * GetLayerPrototype()
Definition: C4MapScript.h:351
C4MapScriptAlgoPolygon(const C4PropList *props)
virtual bool operator()(int32_t x, int32_t y, uint8_t &fg, uint8_t &bg) const
uint8_t GetPix(int32_t x, int32_t y, uint8_t outside_col) const
Definition: C4MapScript.h:305