OpenClonk
C4MapCreatorS2.h
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
5  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
6  *
7  * Distributed under the terms of the ISC license; see accompanying file
8  * "COPYING" for details.
9  *
10  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11  * See accompanying file "TRADEMARK" for details.
12  *
13  * To redistribute this file separately, substitute the full license texts
14  * for the above references.
15  */
16 // complex dynamic landscape creator
17 
18 #ifndef INC_C4MapCreatorS2
19 #define INC_C4MapCreatorS2
20 
21 #define C4MC_SizeRes 100 // positions in percent
22 #define C4MC_ZoomRes 100 // zoom resolution (-100 to +99)
23 
24 // string consts
25 #define C4MC_Overlay "overlay" // overlay node
26 #define C4MC_Point "point" // polygon point
27 #define C4MC_Map "map" // map node
28 
29 #define C4MC_DefAlgo "solid" // default overlay algorithm
30 
31 // error messages
32 #define C4MCErr_404 "file not found"
33 #define C4MCErr_NoGroup "internal error: no group"
34 
35 #define C4MCErr_EOF "unexpected end of file"
36 #define C4MCErr_NoDirGlobal "can't use directives in local scope"
37 #define C4MCErr_UnknownDir "unknown directive: %s"
38 #define C4MCErr_MapNoGlobal "can't declare map in local scope"
39 #define C4MCErr_OpTypeErr "operator type mismatch"
40 #define C4MCErr_IdtfExp "identifier expected"
41 #define C4MCErr_UnnamedNoGlbl "unnamed objects not allowed in global scope"
42 #define C4MCErr_BlOpenExp "'{' expected"
43 #define C4MCErr_OpsNoGlobal "operators not allowed in global scope"
44 #define C4MCErr_SColonOrOpExp "';' or operator expected"
45 #define C4MCErr_Obj2Exp "second operand expected"
46 #define C4MCErr_ReinstNoGlobal "can't reinstanciate object '%s' in global scope"
47 #define C4MCErr_UnknownObj "unknown object: %s"
48 #define C4MCErr_ReinstUnknown "can't reinstanciate '%s'; object type is unknown"
49 #define C4MCErr_EqSColonBlOpenExp "'=', ';' or '{' expected"
50 #define C4MCErr_FieldConstExp "constant for field '%s' expected"
51 #define C4MCErr_SColonExp "';' expected"
52 #define C4MCErr_Field404 "field '%s' not found"
53 #define C4MCErr_FieldValInvalid "'%s' is not a valid value for this field"
54 #define C4MCErr_MatNotFound "material '%s' not found"
55 #define C4MCErr_TexNotFound "texture '%s' not found"
56 #define C4MCErr_AlgoNotFound "algorithm '%s' not found"
57 #define C4MCErr_SFuncNotFound "script func '%s' not found in scenario script"
58 #define C4MCErr_PointOnlyOvl "point only allowed in overlays"
59 #define C4MCErr_NoRecTemplate "cannot use template '%s' within itself"
60 
61 // predef
62 class C4MCCallbackArray;
64 class C4MCNode;
65 class C4MCOverlay;
66 class C4MCPoint;
67 class C4MCMap;
68 class C4MapCreatorS2;
69 class C4MCParserErr;
70 class C4MCParser;
71 
73 {
75  bool (*Function) (C4MCOverlay*, int32_t, int32_t);
76 };
77 
78 extern C4MCAlgorithm C4MCAlgoMap[];
79 
80 // node type enum
82 
83 // one token type
85 {
86  MCT_NONE, // nothing
87  MCT_DIR, // directive (stored in CurrTokenIdtf)
88  MCT_IDTF, // identifier (stored in CurrTokenIdtf)
89  MCT_INT, // integer constant (stored in CurrTokenVal)
90  MCT_EQ, // =
91  MCT_BLOPEN, // {
93  MCT_SCOLON, // ;
94  MCT_AND, // &
95  MCT_OR, // |
96  MCT_XOR, // ^
97  MCT_RANGE, // -
98  MCT_PERCENT,// integer constant (stored in CurrTokenVal) + %
99  MCT_PX, // integer constant (stored in CurrTokenVal) + px
100  MCT_EOF // end of file
101 };
102 
103 // a callback array
104 // contains a script func, and a map to call the func for
106 {
107 public:
109  ~C4MCCallbackArray(); // dtor
110 
111 protected:
112  C4MapCreatorS2 *pMapCreator; // map creator class to query current map of
113  BYTE *pMap; // bitmap whether or not to call the function for a map pixel
114  int32_t iWdt, iHgt; // size of the bitmap, when created
115  C4AulFunc *pSF; // script func to be called
116 
117  C4MCCallbackArray *pNext; // next array in linked list
118 
119 public:
120  void EnablePixel(int32_t iX, int32_t iY); // enable pixel in map; create map if necessary
121  void Execute(int32_t iMapZoom); // evaluate the array
122 
123  friend class C4MCCallbackArrayList;
124 };
125 
126 // callback array list: contains all callbacks
128 {
129 public:
130  C4MCCallbackArrayList() { pFirst=nullptr; } // ctor
131  ~C4MCCallbackArrayList() { Clear(); } // ctor
132 
133 protected:
134  C4MCCallbackArray *pFirst; // first array in list
135 
136 public:
137  void Add(C4MCCallbackArray *pNewArray); // add given array to list
138  void Clear(); // clear the list
139  void Execute(int32_t iMapZoom);// execute all arrays
140 };
141 
142 // generic map creator tree node
143 // the code has been STL-free so far, so keep the line
144 class C4MCNode
145 {
146 public:
147  C4MCNode *Owner, *Child0, *ChildL, *Prev, *Next; // tree structure
148  C4MapCreatorS2 *MapCreator; // owning map creator
149  char Name[C4MaxName]; // name, if named
150 
151 public:
152  C4MCNode(C4MCNode *pOwner=nullptr); // constructor
153  C4MCNode(C4MCParser* pParser, C4MCNode *pOwner, C4MCNode &rTemplate, bool fClone); // constructor using template
154  virtual ~C4MCNode(); // destructor
155 
156  virtual C4MCNode *clone(C4MCParser* pParser, C4MCNode *pToNode) { return new C4MCNode(pParser, pToNode, *this, true); }
157 
158  void Clear(); // clear all child nodes
159  void Reg2Owner(C4MCNode *pOwner); // register into list
160 
161 protected:
162  virtual bool GlobalScope() { return false; } // whether node is a global scope
163  virtual bool SetOp(C4MCTokenType eOp) { return false; } // set following operator
164  C4MCNode *GetNodeByName(const char *szName); // search node by name
165 
166  virtual bool SetField(C4MCParser *pParser, const char *szField, const char *szSVal, int32_t iVal, C4MCTokenType ValType); // set field
167  int32_t IntPar(C4MCParser *pParser, const char *szSVal, int32_t iVal, C4MCTokenType ValType); // ensure par is int32_t
168  const char *StrPar(C4MCParser *pParser, const char *szSVal, int32_t iVal, C4MCTokenType ValType); // ensure par is string
169 
170  virtual void Evaluate() { } // called when all fields are initialized
171  void ReEvaluate(); // evaluate everything again
172 
173  // For Percents and Pixels
174  class int_bool
175  {
176  public:
177  int32_t Evaluate(int32_t relative_to)
178  { if (percent) return value * relative_to / C4MC_SizeRes; else return value; }
179  void Set(int32_t value, bool percent)
180  { this->value = value; this->percent = percent; }
181  private:
182  int32_t value;
183  bool percent;
184  };
185 public:
186  virtual C4MCNodeType Type() { return MCN_Node; } // get node type
187  virtual C4MCOverlay *Overlay() { return nullptr; } // return overlay, if this is one
188  C4MCOverlay *OwnerOverlay(); // return an owner who is an overlay
189 
190  friend class C4MCParser;
191 };
192 
193 // overlay node
194 class C4MCOverlay : public C4MCNode
195 {
196 public:
197  C4MCOverlay(C4MCNode *pOwner=nullptr); // constructor
198  C4MCOverlay(C4MCParser* pParser, C4MCNode *pOwner, C4MCOverlay &rTemplate, bool fClone); // construct of template
199 
200  C4MCNode *clone(C4MCParser* pParser, C4MCNode *pToNode) override { return new C4MCOverlay(pParser, pToNode, *this, true); }
201 
202 protected:
203  void Default(); // set default values for default presets
204 
205 public:
206  int32_t Seed; // random seed
207  int32_t FixedSeed; // fixed random seed set in def
208  int32_t X,Y,Wdt,Hgt,OffX,OffY; // extends/offset
209  int_bool RX, RY, RWdt, RHgt, ROffX, ROffY; // extends/offset relatively to owner
210  int32_t Material; // material index
211  bool Sub; // tunnel bg?
212  char Texture[C4M_MaxName+1]; // texture name
213  BYTE MatClr; // resolved mat-tex color
214  BYTE MatClrBkg; // resolved mat-tex color
215  C4MCTokenType Op; // following operator
216  C4MCAlgorithm *Algorithm; // algorithm to calc whether filled or not
217  int32_t Turbulence, Lambda, Rotate; // turbulence factors; rotation angle
218  int_bool Alpha, Beta; // extra params
219  int32_t ZoomX, ZoomY; // zoom factor for algorithm
220  bool Invert, LooseBounds, Group, Mask; // extra algo behaviour
221  C4MCCallbackArray *pEvaluateFunc; // function called for nodes being evaluated and fulfilled
222  C4MCCallbackArray *pDrawFunc; // function called when this node is drawn - pass drawcolor as first param, return color to be actually used
223 
224  bool SetOp(C4MCTokenType eOp) override { Op=eOp; return true; } // set following operator
225 
226  C4MCAlgorithm *GetAlgo(const char *szName);
227 
228  bool SetField(C4MCParser *pParser, const char *szField, const char *szSVal, int32_t iVal, C4MCTokenType ValType) override; // set field
229 
230  void Evaluate() override; // called when all fields are initialized
231 
232  C4MCOverlay *Overlay() override { return this; } // this is an overlay
233  C4MCOverlay *FirstOfChain(); // go backwards in op chain until first overlay of chain
234 
235  bool CheckMask(int32_t iX, int32_t iY); // check whether algorithms succeeds at iX/iY
236  bool RenderPix(int32_t iX, int32_t iY, BYTE &rPix, BYTE &rPixBkg, C4MCTokenType eLastOp=MCT_NONE, bool fLastSet=false, bool fDraw=true, C4MCOverlay **ppPixelSetOverlay=nullptr); // render this pixel
237  bool PeekPix(int32_t iX, int32_t iY); // check mask; regard operator chain
238  bool InBounds(int32_t iX, int32_t iY) { return iX>=X && iY>=Y && iX<X+Wdt && iY<Y+Hgt; } // return whether point iX/iY is inside bounds
239 
240 public:
241  C4MCNodeType Type() override { return MCN_Overlay; } // get node type
242 
243  friend class C4MapCreatorS2;
244  friend class C4MCParser;
245 };
246 
247 // point of polygon node
248 class C4MCPoint : public C4MCNode
249 {
250 public:
251  C4MCPoint(C4MCNode *pOwner=nullptr); // constructor
252  C4MCPoint(C4MCParser* pParser, C4MCNode *pOwner, C4MCPoint &rTemplate, bool fClone); // construct of template
253 
254  C4MCNode *clone(C4MCParser* pParser, C4MCNode *pToNode) override { return new C4MCPoint(pParser, pToNode, *this, true); }
255 
256 protected:
257  void Default(); // set default values for default presets
258 
259 public:
260  int32_t X,Y;
262 
263  void Evaluate() override; // called when all fields are initialized
264  bool SetField(C4MCParser *pParser, const char *szField, const char *szSVal, int32_t iVal, C4MCTokenType ValType) override; // set field
265 
266 public:
267  C4MCNodeType Type() override { return MCN_Point; } // get node type
268 
269  friend class C4MapCreatorS2;
270  friend class C4MCParser;
271 };
272 
273 // simply an overlay that can be rendered
274 class C4MCMap : public C4MCOverlay
275 {
276 public:
277  C4MCMap(C4MCNode *pOwner=nullptr); // constructor
278  C4MCMap(C4MCParser* pParser, C4MCNode *pOwner, C4MCMap &rTemplate, bool fClone); // construct of template
279 
280  C4MCNode *clone(C4MCParser* pParser, C4MCNode *pToNode) override { return new C4MCMap(pParser, pToNode, *this, true); }
281 
282 protected:
283  void Default(); // set default values for default presets
284 
285 public:
286  bool RenderTo(BYTE *pToBuf, BYTE *pToBufBkg, int32_t iPitch); // render to buffer
287  void SetSize(int32_t iWdt, int32_t iHgt);
288 
289 public:
290  C4MCNodeType Type() override { return MCN_Map; } // get node type
291 
292  friend class C4MapCreatorS2;
293  friend class C4MCParser;
294 };
295 
296 // main map creator class
297 class C4MapCreatorS2 : public C4MCNode
298 {
299 public:
300  C4MapCreatorS2(C4SLandscape *pLandscape, C4TextureMap *pTexMap, C4MaterialMap *pMatMap, int iPlayerCount); // constructor
301  ~C4MapCreatorS2() override; // destructor
302 
303  void Default(); // set default data
304  void Clear(); // clear any data
305  bool ReadFile(const char *szFilename, C4Group *pGrp); // read defs of file
306  bool ReadScript(const char *szScript); // reads def directly from mem
307 
308 public:
309  C4MCMap *GetMap(const char *szMapName); // get map by name
310 
311 public:
312  bool Render(const char *szMapName, CSurface8*& sfcMap, CSurface8*& sfcMapBkg); // create map surface
313  BYTE *RenderBuf(const char *szMapName, int32_t &sfcWdt, int32_t &sfcHgt); // create buffer and render it
314 
315  void SetC4SLandscape(C4SLandscape *pLandscape) // update source for map size
316  { Landscape=pLandscape; }
317 
318 protected:
319  C4SLandscape *Landscape; // landsape presets
320  C4TextureMap *TexMap; // texture map
321  C4MaterialMap *MatMap; // material map
322  C4MCMap DefaultMap; // default template: landscape
323  C4MCOverlay DefaultOverlay; // default template: overlay
324  C4MCPoint DefaultPoint; // default template: point
325  C4MCMap *pCurrentMap; // map currently rendered
326  C4MCCallbackArrayList CallbackArrays; // list of callback arrays
327  int PlayerCount; // player count for MapPlayerExtend
328 
329  bool GlobalScope() override { return true; } // it's the global node
330 
331 public:
332  void ExecuteCallbacks(int32_t iMapZoom) { CallbackArrays.Execute(iMapZoom); }
333 
334  friend class C4MCOverlay;
335  friend class C4MCMap;
336  friend class C4MCParser;
337  friend class C4MCCallbackArray;
338 };
339 
340 
341 // file parser for map creator
342 
343 // parser error
345 {
346 public:
347  char Msg[C4MaxMessage]; // message string
348 
349  C4MCParserErr(C4MCParser *pParser, const char *szMsg); // construct setting error msg
350  C4MCParserErr(C4MCParser *pParser, const char *szMsg, const char *szPar); // construct setting error msg
351  void show(); // log error
352 };
353 
354 // the parser
356 {
357 private:
358  C4MapCreatorS2 *MapCreator; // map creator parsing into
359  char *Code; // loaded code, can be nullptr if externally owned
360  const char *BPos; // Beginning of code
361  const char *CPos; // current parser pos in code
362  C4MCTokenType CurrToken; // last token read
363  char CurrTokenIdtf[C4MaxName]; // current token string
364  int32_t CurrTokenVal; // current token value
365  char Filename[C4MaxName]; // filename
366 
367  bool AdvanceSpaces(); // advance to next token char; return whether EOF is reached
368  bool GetNextToken(); // get token, store in fields and advance to next; return whether not EOF
369  void ParseTo(C4MCNode *pToNode); // parse stuff into
370  void ParseValue(C4MCNode *pToNode, const char *szFieldName); // Set Field
371 
372 public:
373  C4MCParser(C4MapCreatorS2 *pMapCreator); // constructor
374  ~C4MCParser(); // destructor
375 
376  void Clear(); // clear stuff
377 
378  void ParseFile(const char *szFilename, C4Group *pGrp); // load and parse file
379  void Parse(const char *szScript); // load and parse from mem
380  void ParseMemFile(const char *szScript, const char *szFilename); // parse file previosuly loaded into mem
381 
382  friend class C4MCParserErr;
383 };
384 
385 #endif
const int C4M_MaxName
Definition: C4Constants.h:49
const int C4MaxMessage
Definition: C4Constants.h:28
const unsigned int C4MaxName
#define C4MC_SizeRes
C4MCAlgorithm C4MCAlgoMap[]
C4MCNodeType
@ MCN_Node
@ MCN_Point
@ MCN_Overlay
@ MCN_Map
C4MCTokenType
@ MCT_INT
@ MCT_OR
@ MCT_EOF
@ MCT_NONE
@ MCT_SCOLON
@ MCT_BLOPEN
@ MCT_DIR
@ MCT_BLCLOSE
@ MCT_AND
@ MCT_PX
@ MCT_XOR
@ MCT_RANGE
@ MCT_PERCENT
@ MCT_IDTF
@ MCT_EQ
uint8_t BYTE
C4MapCreatorS2 * pMapCreator
C4MCCallbackArray(C4AulFunc *pSFunc, C4MapCreatorS2 *pMapCreator)
void Execute(int32_t iMapZoom)
C4MCCallbackArray * pNext
void EnablePixel(int32_t iX, int32_t iY)
void Execute(int32_t iMapZoom)
C4MCCallbackArray * pFirst
void Add(C4MCCallbackArray *pNewArray)
C4MCMap(C4MCNode *pOwner=nullptr)
bool RenderTo(BYTE *pToBuf, BYTE *pToBufBkg, int32_t iPitch)
C4MCNodeType Type() override
C4MCNode * clone(C4MCParser *pParser, C4MCNode *pToNode) override
void Default()
void SetSize(int32_t iWdt, int32_t iHgt)
void Set(int32_t value, bool percent)
int32_t Evaluate(int32_t relative_to)
virtual bool SetField(C4MCParser *pParser, const char *szField, const char *szSVal, int32_t iVal, C4MCTokenType ValType)
C4MCNode * ChildL
char Name[C4MaxName]
virtual ~C4MCNode()
void ReEvaluate()
C4MCNode * GetNodeByName(const char *szName)
const char * StrPar(C4MCParser *pParser, const char *szSVal, int32_t iVal, C4MCTokenType ValType)
virtual bool SetOp(C4MCTokenType eOp)
C4MCOverlay * OwnerOverlay()
C4MCNode * Owner
C4MapCreatorS2 * MapCreator
C4MCNode * Next
virtual bool GlobalScope()
int32_t IntPar(C4MCParser *pParser, const char *szSVal, int32_t iVal, C4MCTokenType ValType)
C4MCNode(C4MCNode *pOwner=nullptr)
virtual C4MCOverlay * Overlay()
virtual void Evaluate()
C4MCNode * Child0
virtual C4MCNodeType Type()
virtual C4MCNode * clone(C4MCParser *pParser, C4MCNode *pToNode)
C4MCNode * Prev
void Reg2Owner(C4MCNode *pOwner)
C4MCNode * clone(C4MCParser *pParser, C4MCNode *pToNode) override
bool RenderPix(int32_t iX, int32_t iY, BYTE &rPix, BYTE &rPixBkg, C4MCTokenType eLastOp=MCT_NONE, bool fLastSet=false, bool fDraw=true, C4MCOverlay **ppPixelSetOverlay=nullptr)
int_bool Beta
int32_t Material
C4MCCallbackArray * pEvaluateFunc
bool SetField(C4MCParser *pParser, const char *szField, const char *szSVal, int32_t iVal, C4MCTokenType ValType) override
char Texture[C4M_MaxName+1]
int_bool RWdt
C4MCTokenType Op
C4MCCallbackArray * pDrawFunc
bool PeekPix(int32_t iX, int32_t iY)
int_bool Alpha
C4MCOverlay * Overlay() override
int32_t Rotate
void Evaluate() override
bool CheckMask(int32_t iX, int32_t iY)
C4MCOverlay * FirstOfChain()
int32_t FixedSeed
int_bool ROffX
C4MCOverlay(C4MCNode *pOwner=nullptr)
C4MCNodeType Type() override
bool InBounds(int32_t iX, int32_t iY)
C4MCAlgorithm * GetAlgo(const char *szName)
int32_t Lambda
bool SetOp(C4MCTokenType eOp) override
int32_t Turbulence
int_bool ROffY
int_bool RHgt
C4MCAlgorithm * Algorithm
char Msg[C4MaxMessage]
C4MCParserErr(C4MCParser *pParser, const char *szMsg)
C4MCParser(C4MapCreatorS2 *pMapCreator)
void ParseFile(const char *szFilename, C4Group *pGrp)
void ParseMemFile(const char *szScript, const char *szFilename)
void Parse(const char *szScript)
bool SetField(C4MCParser *pParser, const char *szField, const char *szSVal, int32_t iVal, C4MCTokenType ValType) override
int_bool RY
C4MCPoint(C4MCNode *pOwner=nullptr)
int_bool RX
void Evaluate() override
C4MCNodeType Type() override
C4MCNode * clone(C4MCParser *pParser, C4MCNode *pToNode) override
C4MCPoint DefaultPoint
C4MaterialMap * MatMap
~C4MapCreatorS2() override
C4MapCreatorS2(C4SLandscape *pLandscape, C4TextureMap *pTexMap, C4MaterialMap *pMatMap, int iPlayerCount)
C4MCCallbackArrayList CallbackArrays
BYTE * RenderBuf(const char *szMapName, int32_t &sfcWdt, int32_t &sfcHgt)
void SetC4SLandscape(C4SLandscape *pLandscape)
bool GlobalScope() override
bool ReadFile(const char *szFilename, C4Group *pGrp)
bool ReadScript(const char *szScript)
C4MCMap * pCurrentMap
C4MCOverlay DefaultOverlay
void ExecuteCallbacks(int32_t iMapZoom)
C4TextureMap * TexMap
C4MCMap * GetMap(const char *szMapName)
bool Render(const char *szMapName, CSurface8 *&sfcMap, CSurface8 *&sfcMapBkg)
C4SLandscape * Landscape
char Identifier[C4MaxName]
bool(* Function)(C4MCOverlay *, int32_t, int32_t)