openclonk/engine/inc/C4MapCreatorS2.h

411 lines
14 KiB
C++

/*
* OpenClonk, http://www.openclonk.org
*
* Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de
*
* Portions might be copyrighted by other authors who have contributed
* to OpenClonk.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* See isc_license.txt for full license and disclaimer.
*
* "Clonk" is a registered trademark of Matthes Bender.
* See clonk_trademark_license.txt for full license.
*/
// complex dynamic landscape creator
#ifndef INC_C4MapCreatorS2
#define INC_C4MapCreatorS2
#include <C4Group.h>
#include <C4Scenario.h>
#include <C4Surface.h>
#define C4MC_SizeRes 100 // positions in percent
#define C4MC_ZoomRes 100 // zoom resolution (-100 to +99)
// string consts
#define C4MC_Overlay "overlay" // overlay node
#define C4MC_Point "point" // polygon point
#define C4MC_Map "map" // map node
#define C4MC_DefAlgo "solid" // default overlay algorithm
// error messages
#define C4MCErr_404 "file not found"
#define C4MCErr_NoGroup "internal error: no group"
#define C4MCErr_EOF "unexpected end of file"
#define C4MCErr_NoDirGlobal "can't use directives in local scope"
#define C4MCErr_UnknownDir "unknown directive: %s"
#define C4MCErr_MapNoGlobal "can't declare map in local scope"
#define C4MCErr_OpTypeErr "operator type mismatch"
#define C4MCErr_IdtfExp "identifier expected"
#define C4MCErr_UnnamedNoGlbl "unnamed objects not allowed in global scope"
#define C4MCErr_BlOpenExp "'{' expected"
#define C4MCErr_OpsNoGlobal "operators not allowed in global scope"
#define C4MCErr_SColonOrOpExp "';' or operator expected"
#define C4MCErr_Obj2Exp "second operand expected"
#define C4MCErr_ReinstNoGlobal "can't reinstanciate object '%s' in global scope"
#define C4MCErr_UnknownObj "unknown object: %s"
#define C4MCErr_ReinstUnknown "can't reinstanciate '%s'; object type is unknown"
#define C4MCErr_EqSColonBlOpenExp "'=', ';' or '{' expected"
#define C4MCErr_FieldConstExp "constant for field '%s' expected"
#define C4MCErr_SColonExp "';' expected"
#define C4MCErr_Field404 "field '%s' not found"
#define C4MCErr_FieldValInvalid "'%s' is not a valid value for this field"
#define C4MCErr_MatNotFound "material '%s' not found"
#define C4MCErr_TexNotFound "texture '%s' not found"
#define C4MCErr_AlgoNotFound "algorithm '%s' not found"
#define C4MCErr_SFuncNotFound "script func '%s' not found in scenario script"
#define C4MCErr_PointOnlyOvl "point only allowed in overlays"
// predef
class C4MCCallbackArray;
class C4MCCallbackArrayList;
class C4MCNode;
class C4MCOverlay;
class C4MCPoint;
class C4MCMap;
class C4MapCreatorS2;
class C4MCParserErr;
class C4MCParser;
struct C4MCAlgorithm
{
char Identifier[C4MaxName];
bool (*Function) (C4MCOverlay*, int32_t, int32_t);
};
extern C4MCAlgorithm C4MCAlgoMap[];
// node type enum
enum C4MCNodeType { MCN_Node, MCN_Overlay, MCN_Point, MCN_Map };
// one token type
enum C4MCTokenType
{
MCT_NONE, // nothing
MCT_DIR, // directive (stored in CurrTokenIdtf)
MCT_IDTF, // identifier (stored in CurrTokenIdtf)
MCT_INT, // integer constant (stored in CurrTokenVal)
MCT_EQ, // =
MCT_BLOPEN, // {
MCT_BLCLOSE,// }
MCT_SCOLON, // ;
MCT_AND, // &
MCT_OR, // |
MCT_XOR, // ^
MCT_RANGE, // -
MCT_PERCENT,// integer constant (stored in CurrTokenVal) + %
MCT_PX, // integer constant (stored in CurrTokenVal) + px
MCT_EOF // end of file
};
// a callback array
// contains a script func, and a map to call the func for
class C4MCCallbackArray
{
public:
C4MCCallbackArray(C4AulFunc *pSFunc, C4MapCreatorS2 *pMapCreator); // ctor
~C4MCCallbackArray(); // dtor
protected:
C4MapCreatorS2 *pMapCreator; // map creator class to query current map of
BYTE *pMap; // bitmap whether or not to call the function for a map pixel
int32_t iWdt, iHgt; // size of the bitmap, when created
C4AulFunc *pSF; // script func to be called
C4MCCallbackArray *pNext; // next array in linked list
public:
void EnablePixel(int32_t iX, int32_t iY); // enable pixel in map; create map if necessary
void Execute(int32_t iMapZoom); // evaluate the array
friend class C4MCCallbackArrayList;
};
// callback array list: contains all callbacks
class C4MCCallbackArrayList
{
public:
C4MCCallbackArrayList() { pFirst=NULL; } // ctor
~C4MCCallbackArrayList() { Clear(); } // ctor
protected:
C4MCCallbackArray *pFirst; // first array in list
public:
void Add(C4MCCallbackArray *pNewArray); // add given array to list
void Clear(); // clear the list
void Execute(int32_t iMapZoom);// execute all arrays
};
// generic map creator tree node
// the code has been STL-free so far, so keep the line
class C4MCNode
{
public:
C4MCNode *Owner, *Child0, *ChildL, *Prev, *Next; // tree structure
C4MapCreatorS2 *MapCreator; // owning map creator
char Name[C4MaxName]; // name, if named
public:
C4MCNode(C4MCNode *pOwner=NULL); // constructor
C4MCNode(C4MCNode *pOwner, C4MCNode &rTemplate, bool fClone); // constructor using template
virtual ~C4MCNode(); // destructor
virtual C4MCNode *clone(C4MCNode *pToNode) { return new C4MCNode(pToNode, *this, true); }
void Clear(); // clear all child nodes
void Reg2Owner(C4MCNode *pOwner); // register into list
protected:
virtual BOOL GlobalScope() { return FALSE; } // whether node is a global scope
virtual BOOL SetOp(C4MCTokenType eOp) { return FALSE; } // set following operator
C4MCNode *GetNodeByName(const char *szName); // search node by name
virtual bool SetField(C4MCParser *pParser, const char *szField, const char *szSVal, int32_t iVal, C4MCTokenType ValType); // set field
int32_t IntPar(C4MCParser *pParser, const char *szSVal, int32_t iVal, C4MCTokenType ValType); // ensure par is int32_t
const char *StrPar(C4MCParser *pParser, const char *szSVal, int32_t iVal, C4MCTokenType ValType); // ensure par is string
virtual void Evaluate() { } // called when all fields are initialized
void ReEvaluate(); // evaluate everything again
// For Percents and Pixels
class int_bool {
public:
int32_t Evaluate(int32_t relative_to)
{ if (percent) return value * relative_to / C4MC_SizeRes; else return value; }
void Set(int32_t value, bool percent)
{ this->value = value; this->percent = percent; }
private:
int32_t value;
bool percent;
};
public:
virtual C4MCNodeType Type() { return MCN_Node; } // get node type
virtual C4MCOverlay *Overlay() { return NULL; } // return overlay, if this is one
C4MCOverlay *OwnerOverlay(); // return an owner who is an overlay
friend class C4MCParser;
};
// node attribute entry for SetField search
enum C4MCValueType
{
C4MCV_None,
C4MCV_Integer,
C4MCV_Percent,
C4MCV_Pixels,
C4MCV_Material,
C4MCV_Texture,
C4MCV_Algorithm,
C4MCV_Boolean,
C4MCV_Zoom,
C4MCV_ScriptFunc,
};
struct C4MCNodeAttr
{
char Name[C4MaxName]; // name of field
C4MCValueType Type; // type of field
int32_t iOff; // offset of field in overlay MCOverlay-class
};
extern C4MCNodeAttr C4MCOvrlMap[];
// overlay node
class C4MCOverlay : public C4MCNode
{
public:
C4MCOverlay(C4MCNode *pOwner=NULL); // constructor
C4MCOverlay(C4MCNode *pOwner, C4MCOverlay &rTemplate, bool fClone); // construct of template
C4MCNode *clone(C4MCNode *pToNode) { return new C4MCOverlay(pToNode, *this, true); }
protected:
void Default(); // set default values for default presets
public:
int32_t Seed; // random seed
int32_t FixedSeed; // fixed random seed set in def
int32_t X,Y,Wdt,Hgt,OffX,OffY; // extends/offset
int_bool RX, RY, RWdt, RHgt, ROffX, ROffY; // extends/offset relatively to owner
int32_t Material; // material index
bool Sub; // tunnel bg?
char Texture[C4M_MaxName+1]; // texture name
BYTE MatClr; // resolved mat-tex color
C4MCTokenType Op; // following operator
C4MCAlgorithm *Algorithm; // algorithm to calc whether filled or not
int32_t Turbulence, Lambda, Rotate; // turbulence factors; rotation angle
int_bool Alpha, Beta; // extra params
int32_t ZoomX, ZoomY; // zoom factor for algorithm
bool Invert, LooseBounds, Group, Mask; // extra algo behaviour
C4MCCallbackArray *pEvaluateFunc; // function called for nodes being evaluated and fulfilled
C4MCCallbackArray *pDrawFunc; // function called when this node is drawn - pass drawcolor as first param, return color to be actually used
BOOL SetOp(C4MCTokenType eOp) { Op=eOp; return TRUE; } // set following operator
C4MCAlgorithm *GetAlgo(const char *szName);
bool SetField(C4MCParser *pParser, const char *szField, const char *szSVal, int32_t iVal, C4MCTokenType ValType); // set field
void Evaluate(); // called when all fields are initialized
C4MCOverlay *Overlay() { return this; } // this is an overlay
C4MCOverlay *FirstOfChain(); // go backwards in op chain until first overlay of chain
bool CheckMask(int32_t iX, int32_t iY); // check whether algorithms succeeds at iX/iY
bool RenderPix(int32_t iX, int32_t iY, BYTE &rPix, C4MCTokenType eLastOp=MCT_NONE, bool fLastSet=false, bool fDraw=true, C4MCOverlay **ppPixelSetOverlay=NULL); // render this pixel
bool PeekPix(int32_t iX, int32_t iY); // check mask; regard operator chain
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
public:
C4MCNodeType Type() { return MCN_Overlay; } // get node type
friend class C4MapCreatorS2;
friend class C4MCParser;
};
// point of polygon node
class C4MCPoint : public C4MCNode
{
public:
C4MCPoint(C4MCNode *pOwner=NULL); // constructor
C4MCPoint(C4MCNode *pOwner, C4MCPoint &rTemplate, bool fClone); // construct of template
C4MCNode *clone(C4MCNode *pToNode) { return new C4MCPoint(pToNode, *this, true); }
protected:
void Default(); // set default values for default presets
public:
int32_t X,Y;
int_bool RX,RY;
virtual void Evaluate(); // called when all fields are initialized
bool SetField(C4MCParser *pParser, const char *szField, const char *szSVal, int32_t iVal, C4MCTokenType ValType); // set field
public:
C4MCNodeType Type() { return MCN_Point; } // get node type
friend class C4MapCreatorS2;
friend class C4MCParser;
};
// simply an overlay that can be rendered
class C4MCMap : public C4MCOverlay
{
public:
C4MCMap(C4MCNode *pOwner=NULL); // constructor
C4MCMap(C4MCNode *pOwner, C4MCMap &rTemplate, bool fClone); // construct of template
C4MCNode *clone(C4MCNode *pToNode) { return new C4MCMap(pToNode, *this, true); }
protected:
void Default(); // set default values for default presets
public:
bool RenderTo(BYTE *pToBuf, int32_t iPitch); // render to buffer
void SetSize(int32_t iWdt, int32_t iHgt);
public:
C4MCNodeType Type() { return MCN_Map; } // get node type
friend class C4MapCreatorS2;
friend class C4MCParser;
};
// main map creator class
class C4MapCreatorS2 : public C4MCNode
{
public:
C4MapCreatorS2(C4SLandscape *pLandscape, C4TextureMap *pTexMap, C4MaterialMap *pMatMap, int iPlayerCount); // constructor
~C4MapCreatorS2(); // destructor
void Default(); // set default data
void Clear(); // clear any data
BOOL ReadFile(const char *szFilename, C4Group *pGrp); // read defs of file
BOOL ReadScript(const char *szScript); // reads def directly from mem
public:
C4MCMap *GetMap(const char *szMapName); // get map by name
public:
#ifdef C4ENGINE
CSurface8 * Render(const char *szMapName); // create map surface
#endif
BYTE *RenderBuf(const char *szMapName, int32_t &sfcWdt, int32_t &sfcHgt); // create buffer and render it
void SetC4SLandscape(C4SLandscape *pLandscape) // update source for map size
{ Landscape=pLandscape; }
protected:
C4SLandscape *Landscape; // landsape presets
C4TextureMap *TexMap; // texture map
C4MaterialMap *MatMap; // material map
C4MCMap DefaultMap; // default template: landscape
C4MCOverlay DefaultOverlay; // default template: overlay
C4MCPoint DefaultPoint; // default template: point
C4MCMap *pCurrentMap; // map currently rendered
C4MCCallbackArrayList CallbackArrays; // list of callback arrays
int PlayerCount; // player count for MapPlayerExtend
BOOL GlobalScope() { return TRUE; } // it's the global node
public:
void ExecuteCallbacks(int32_t iMapZoom) { CallbackArrays.Execute(iMapZoom); }
friend class C4MCOverlay;
friend class C4MCMap;
friend class C4MCParser;
friend class C4MCCallbackArray;
};
// file parser for map creator
// parser error
class C4MCParserErr
{
public:
char Msg[C4MaxMessage]; // message string
C4MCParserErr(C4MCParser *pParser, const char *szMsg); // construct setting error msg
C4MCParserErr(C4MCParser *pParser, const char *szMsg, const char *szPar); // construct setting error msg
void show(); // log error
};
// the parser
class C4MCParser
{
private:
C4MapCreatorS2 *MapCreator; // map creator parsing into
char *Code; // loaded code
const char *CPos; // current parser pos in code
C4MCTokenType CurrToken; // last token read
char CurrTokenIdtf[C4MaxName]; // current token string
int32_t CurrTokenVal; // current token value
char Filename[C4MaxName]; // filename
BOOL AdvanceSpaces(); // advance to next token char; return whether EOF is reached
BOOL GetNextToken(); // get token, store in fields and advance to next; return whether not EOF
void ParseTo(C4MCNode *pToNode); // parse stuff into
void ParseValue(C4MCNode *pToNode, const char *szFieldName); // Set Field
public:
C4MCParser(C4MapCreatorS2 *pMapCreator); // constructor
~C4MCParser(); // destructor
void Clear(); // clear stuff
void ParseFile(const char *szFilename, C4Group *pGrp); // load and parse file
void Parse(const char *szScript); // load and parse from mem
friend class C4MCParserErr;
};
#endif