47 typedef char (T::*OffsetType);
49 MemberAdapter(T&
object, OffsetType offset)
50 :
Object(object), Offset(offset)
57 typedef U (T::*TargetPtrType);
58 return Object.*
reinterpret_cast<TargetPtrType
>(Offset);
66 typedef MemberAdapter<C4MCOverlay>::OffsetType C4MCOverlayOffsetType;
72 C4MCOverlayOffsetType Offset;
75 extern C4MCNodeAttr C4MCOvrlMap[];
107 if (!pCurrMap)
return;
116 if (iX<0 || iY<0 || iX>=
iWdt || iY>=
iHgt)
return;
118 int32_t iIndex = iX + iY*
iWdt;
119 pMap[iIndex/8] |= 1<<(iIndex%8);
132 if (
pMap[iIndex/8]&(1<<(iIndex%8)))
135 Pars[0] =
C4VInt((iIndex%
iWdt) * iMapZoom - (iMapZoom/2));
136 Pars[1] =
C4VInt((iIndex/
iWdt) * iMapZoom - (iMapZoom/2));
154 pLast->
pNext=pNewArray;
163 while ((pArray=pNext))
176 pArray->Execute(iMapZoom);
195 for(
C4MCNode* pParent = pOwner; pParent !=
nullptr; pParent = pParent->
Owner)
196 if(pParent == &rTemplate)
202 pChild->clone(pParser,
this);
260 if (
SEqual(pChild->Name, szName))
291 #define IntPar IntPar(pParser, szSVal, iVal, ValType)
292 #define StrPar StrPar(pParser, szSVal, iVal, ValType)
300 pChild->ReEvaluate();
378 for (C4MCNodeAttr *pAttr=&C4MCOvrlMap[0]; *pAttr->Name; pAttr++)
379 if (
SEqual(szField, pAttr->Name))
382 MemberAdapter<C4MCOverlay> Target(*
this, pAttr->Offset);
388 Target.As<int32_t>() =
IntPar;
402 Target.As<int32_t>() = iMat;
411 case C4MCV_Algorithm:
421 Target.As<
bool>()=
IntPar!=0;
427 case C4MCV_ScriptFunc:
451 if (
SEqual(pAlgo->Identifier, szName))
483 int32_t iOwnerWdt=pOwnrOvrl->
Wdt; int32_t iOwnerHgt=pOwnrOvrl->
Hgt;
534 int32_t Seed2; Seed2=
Seed;
535 for (int32_t l=0; l<
Lambda+1; ++l)
539 dX +=
Sin(((dX / 7 +
itofix(Seed2) /
ZoomX + dY) / j + d) * Rad2Grad) * j / 2;
540 dY +=
Cos(((dY / 7 +
itofix(Seed2) /
ZoomY + dX) / j - d) * Rad2Grad) * j / 2;
542 Seed2 = (
Seed * (Seed2<<3) + 0x4465) & 0xffff;
581 DoSet=SetThis&&fLastSet;
584 DoSet=SetThis||fLastSet;
587 DoSet=SetThis^fLastSet;
599 if (fDraw && DoSet && !
Mask)
603 if (ppPixelSetOverlay) *ppPixelSetOverlay =
this;
605 bool fLastSetC=
false; eLastOp=
MCT_NONE;
610 fLastSetC=pOvrl->RenderPix(iX, iY, rPix, rPixBkg, eLastOp, fLastSetC, fDraw, ppPixelSetOverlay);
629 fLastSetC=pOvrl->
RenderPix(iX, iY, Crap, Crap, eLastOp, fLastSetC,
false);
631 if (!pOvrl->
Op)
break;
651 X=rTemplate.
X;
Y=rTemplate.
Y;
663 if (ValType ==
MCT_INT)
return false;
664 if (
SEqual (szField,
"x"))
669 else if (
SEqual (szField,
"y"))
719 for (int32_t iY=0; iY<
Hgt; iY++)
721 for (int32_t iX=0; iX<
Wdt; iX++)
726 if (pToBufBkg) *pToBufBkg=0;
729 RenderPix(iX, iY, *pToBuf, pToBufBkg ? *pToBufBkg : dummyPix,
MCT_NONE,
false,
true, &pRenderedOverlay);
731 if (pRenderedOverlay)
736 if (pToBufBkg) pToBufBkg++;
740 if (pToBufBkg) pToBufBkg+=iPitch-
Wdt;
835 if (szMapName && *szMapName)
845 for (pNode =
ChildL; pNode; pNode=pNode->
Prev)
857 assert(sfcMap ==
nullptr);
858 assert(sfcMapBkg ==
nullptr);
862 if (!pMap)
return false;
865 int32_t sfcWdt, sfcHgt;
866 sfcWdt=pMap->
Wdt; sfcHgt=pMap->
Hgt;
867 if (!sfcWdt || !sfcHgt)
return false;
871 sfcMapBkg =
new CSurface8(sfcWdt, sfcHgt);
881 static inline void DWordAlign(
int &val)
883 if (val%4) { val>>=2; val<<=2; val+=4; }
890 if (!pMap)
return nullptr;
893 sfcWdt=pMap->
Wdt; sfcHgt=pMap->
Hgt;
894 if (!sfcWdt || !sfcHgt)
return nullptr;
895 int dwSfcWdt = sfcWdt;
896 DWordAlign(dwSfcWdt);
903 pMap->
RenderTo(buf,
nullptr, sfcWdt);
910 sprintf(
Msg,
"%s: %s (%d)", pParser->Filename, szMsg, pParser->BPos ?
SGetLine(pParser->BPos, pParser->CPos) : 0);
918 sprintf(
Msg,
"%s: %s (%d)", pParser->Filename, Buf, pParser->BPos ?
SGetLine(pParser->BPos, pParser->CPos) : 0);
933 MapCreator=pMapCreator;
935 Code=
nullptr; BPos =
nullptr; CPos=
nullptr; *Filename=0;
947 delete [] Code; Code=
nullptr; BPos =
nullptr; CPos=
nullptr;
952 bool C4MCParser::AdvanceSpaces()
954 char C, C2 = (char) 0;
956 int32_t InComment = 0;
969 case '/': InComment = 1;
break;
970 case '*': InComment = 2;
break;
971 default: CPos--;
return true;
974 else if ((
BYTE) C > 32)
return true;
977 if (((
BYTE) C == 13) || ((
BYTE) C == 10)) InComment = 0;
980 if ((C ==
'/') && (C2 ==
'*')) InComment = 0;
990 bool C4MCParser::GetNextToken()
993 if (!AdvanceSpaces()) { CurrToken=
MCT_EOF;
return false; }
995 const char *CPos0 = CPos;
1005 TokenGetState State = TGS_None;
1018 if ((((C >=
'0') && (C <=
'9')) || (C ==
'+') || (C ==
'-')))
1020 else if (C ==
'#') State = TGS_Dir;
1021 else if (C ==
';') {CPos++; CurrToken=
MCT_SCOLON;
return true; }
1022 else if (C ==
'=') {CPos++; CurrToken=
MCT_EQ;
return true; }
1023 else if (C ==
'{') {CPos++; CurrToken=
MCT_BLOPEN;
return true; }
1024 else if (C ==
'}') {CPos++; CurrToken=
MCT_BLCLOSE;
return true; }
1025 else if (C ==
'&') {CPos++; CurrToken=
MCT_AND;
return true; }
1026 else if (C ==
'|') {CPos++; CurrToken=
MCT_OR;
return true; }
1027 else if (C ==
'^') {CPos++; CurrToken=
MCT_XOR;
return true; }
1028 else if (C >=
'@') State = TGS_Ident;
1039 if (((C <
'0') || (C >
'9')) && ((C <
'a') || (C >
'z')) && ((C <
'A') || (C >
'Z')) && (C !=
'_'))
1042 Len = std::min<int32_t>(Len,
C4MaxName);
1043 SCopy(CPos0, CurrTokenIdtf, Len);
1050 if ((C <
'0') || (C >
'9'))
1053 Len = std::min<int32_t>(Len,
C4MaxName);
1056 if (Len == 1 && *CPos0 ==
'-')
1061 else if (
'%' == C) { CPos++; CurrToken=
MCT_PERCENT; }
1066 if (
'x' == *CPos) ++CPos;
1069 SCopy(CPos0, CurrTokenIdtf, Len);
1071 sscanf(CurrTokenIdtf,
"%d", &CurrTokenVal);
1083 static void PrintNodeTree(
C4MCNode *pNode,
int depth)
1085 for (
int i = 0; i < depth; ++i)
1087 switch (pNode->
Type())
1089 case MCN_Node: printf(
"Node %s\n", pNode->
Name);
break;
1092 case MCN_Map: printf(
"Map %s\n", pNode->
Name);
break;
1095 PrintNodeTree(pChild, depth + 1);
1098 void C4MCParser::ParseTo(
C4MCNode *pToNode)
1117 ParseState State = PS_NONE;
1119 while (GetNextToken())
1165 if (State==PS_GOTOP) State=PS_GOTOPIDTF;
else State=PS_GOTIDTF;
1168 if (State == PS_GOTOP && pNewNode)
1169 if (LastOperand != pNewNode->
Type())
1216 if (State==PS_GOTOPIDTF)
1235 switch (pCpyNode->
Type())
1252 if (State==PS_GOTOPIDTF)
1253 if (LastOperand != pNewNode->
Type())
1275 if (State != PS_AFTERNODE)
break;
1291 if (!pNewNode->
SetOp(CurrToken))
1293 LastOperand=pNewNode->
Type();
1308 ParseValue (pToNode, FieldName);
1338 if (State != PS_NONE)
1340 if (State == PS_GOTOP)
1347 void C4MCParser::ParseValue(
C4MCNode *pToNode,
const char *szFieldName)
1356 if (!pToNode->
SetField(
this, szFieldName, CurrTokenIdtf, 0, CurrToken))
1359 if (!GetNextToken())
1367 Value = CurrTokenVal;
1369 if (!GetNextToken())
1375 if (!GetNextToken())
1379 Value +=
Random (CurrTokenVal - Value);
1384 if (!GetNextToken())
1387 if (!pToNode->
SetField(
this, szFieldName, CurrTokenIdtf, Value, Type))
1468 Code =
new char[
iSize+1];
1475 ParseTo(MapCreator);
1476 if (
false) PrintNodeTree(MapCreator, 0);
1489 ParseTo(MapCreator);
1490 if (
false) PrintNodeTree(MapCreator, 0);
1506 ParseTo(MapCreator);
1518 iX/=(*ppOvrl)->ZoomX; iY/=(*ppOvrl)->ZoomY;
1521 if (!pOvrl2)
return false;
1524 for (*ppTopOvrl=pOvrl2; (pNextOvrl=(*ppTopOvrl)->
OwnerOverlay()); *ppTopOvrl=pNextOvrl) {}
1533 #define a pOvrl->Alpha
1534 #define b pOvrl->Beta
1535 #define s pOvrl->Seed
1536 #define z C4MC_ZoomRes
1537 #define z2 (C4MC_ZoomRes*C4MC_ZoomRes)
1548 return !((((
s ^ (iX<<2) ^ (iY<<5))^((
s>>16)+1+iX+(iY<<2)))/17)%(
a.Evaluate(
C4MC_SizeRes)+2));
1554 return !(((iX/(
z*10))%2)^((iY/(
z*10))%2));
1560 int32_t iXC=(iX/10+
s+(iY/80))%(
z*2)-
z;
1561 int32_t iYC=(iY/10+
s+(iX/80))%(
z*2)-
z;
1562 int32_t
id=
Abs(iXC*iYC);
1575 int32_t pxb =
b.Evaluate(pOvrl->
Wdt);
1576 int32_t pxa =
a.Evaluate(pOvrl->
Wdt);
1578 return Abs(iX+(
s%4738))%(pxb*
z+1)<pxa*
z+1 &&
Abs(iY+(
s/4738))%(pxb*
z+1)<pxa*
z+1;
1590 int32_t pxb =
b.Evaluate(pOvrl->
Wdt);
1591 int32_t pxa =
a.Evaluate(pOvrl->
Wdt);
1593 return Abs(iX+(
s%4738))%(pxb*
z+1)<pxa*
z+1;
1600 int32_t la=
a.Evaluate(pOvrl->
Wdt); int32_t lb=
b.Evaluate(pOvrl->
Hgt);
1602 if (!
PreparePeek(&pOvrl, iX, iY, &pTopOvrl))
return false;
1604 for (int32_t x=iX-la; x<=iX+la; x++)
if (pTopOvrl->
InBounds(x, iY))
if (!pOvrl->
PeekPix(x, iY))
return true;
1605 for (int32_t y=iY-lb; y<=iY+lb; y++)
if (pTopOvrl->
InBounds(iX, y))
if (!pOvrl->
PeekPix(iX, y))
return true;
1614 if (iMandelIter < 10) iMandelIter = 10;
1616 double c = ((double) iX /
z / pOvrl->
Wdt - .5 * ((
double) pOvrl->
ZoomX /
z)) * 4;
1617 double ci = ((double) iY /
z / pOvrl->
Hgt - .5 * ((
double) pOvrl->
ZoomY /
z)) * 4;
1619 double _z = c, _zi = ci;
1622 for (i=0; i<iMandelIter; i++)
1624 xz = _z * _z - _zi * _zi;
1625 _zi = 2 * _z * _zi + ci;
1627 if (_z * _z + _zi * _zi > 4)
break;
1629 return !(i<iMandelIter);
1634 return (std::abs((iX^(iY*3)) * 2531011L) % 214013L) %
z > iX / pOvrl->
Wdt;
1652 if (!pOvrl -> ChildL)
return false;
1658 bool ignore =
false;
1662 for (pChild = pOvrl -> ChildL; pChild->
Prev; pChild = pChild->
Prev)
1668 if (iY != uY)
break;
1670 pStartChild = pChild -> Next;
1671 if (!pStartChild) pStartChild = pOvrl->
Child0;
1672 if (!pStartChild)
return false;
1673 for (pChild = pStartChild; ; pChild=pChild -> Next)
1675 if (!pChild) pChild = pOvrl->
Child0;
1687 if (((lX < iX) == (iX < cX)) || (cX == iX))
return true;
1692 if ((uY < iY) == (iY < cY) && (lX >= iX)) count++;
1705 if (cX == iX)
return true;
1712 if ((uY < iY) == (iY <= cY))
1715 if (iX < std::min (uX, cX))
1720 else if (iX <= std::max (uX, cX))
1723 if (iX < (zX = ((cX - uX) * (iY - uY) / (cY - uY)) + uX)) count++;
1725 if (zX == iX)
return true;
1734 if (pChild -> Next == pStartChild)
break;
1735 if (!pChild -> Next)
if (pStartChild == pOvrl->
Child0)
break;
1738 if ((count & 1) > 0)
return true;
else return false;
1766 #define offsC4MCOvrl(x) reinterpret_cast<C4MCOverlayOffsetType>(&C4MCOverlay::x)
1769 C4MCNodeAttr C4MCOvrlMap[] =
1785 {
"turbulence", C4MCV_Integer,
offsC4MCOvrl(Turbulence) },
1790 {
"loosebounds", C4MCV_Boolean,
offsC4MCOvrl(LooseBounds) },
1793 {
"evalFn", C4MCV_ScriptFunc,
offsC4MCOvrl(pEvaluateFunc) },
1794 {
"drawFn", C4MCV_ScriptFunc,
offsC4MCOvrl(pDrawFunc) },
1795 {
"", C4MCV_None,
nullptr }
C4Object * Object(C4PropList *_this)
bool Log(const char *szMessage)
bool AlgoBoxes(C4MCOverlay *pOvrl, int32_t iX, int32_t iY)
bool PreparePeek(C4MCOverlay **ppOvrl, int32_t &iX, int32_t &iY, C4MCOverlay **ppTopOvrl)
bool AlgoChecker(C4MCOverlay *pOvrl, int32_t iX, int32_t iY)
bool AlgoRndChecker(C4MCOverlay *pOvrl, int32_t iX, int32_t iY)
bool AlgoSin(C4MCOverlay *pOvrl, int32_t iX, int32_t iY)
C4MCAlgorithm C4MCAlgoMap[]
bool AlgoRandom(C4MCOverlay *pOvrl, int32_t iX, int32_t iY)
bool AlgoLines(C4MCOverlay *pOvrl, int32_t iX, int32_t iY)
bool AlgoGradient(C4MCOverlay *pOvrl, int32_t iX, int32_t iY)
bool AlgoPolygon(C4MCOverlay *pOvrl, int32_t iX, int32_t iY)
bool AlgoBozo(C4MCOverlay *pOvrl, int32_t iX, int32_t iY)
bool AlgoRndAll(C4MCOverlay *pOvrl, int32_t iX, int32_t iY)
bool AlgoMandel(C4MCOverlay *pOvrl, int32_t iX, int32_t iY)
bool AlgoScript(C4MCOverlay *pOvrl, int32_t iX, int32_t iY)
bool AlgoSolid(C4MCOverlay *pOvrl, int32_t iX, int32_t iY)
bool AlgoBorder(C4MCOverlay *pOvrl, int32_t iX, int32_t iY)
#define C4MCErr_AlgoNotFound
#define C4MCErr_BlOpenExp
#define C4MCErr_PointOnlyOvl
#define C4MCErr_UnknownObj
#define C4MCErr_TexNotFound
#define C4MCErr_SColonOrOpExp
#define C4MCErr_NoDirGlobal
#define C4MCErr_OpsNoGlobal
#define C4MCErr_SFuncNotFound
#define C4MCErr_MapNoGlobal
#define C4MCErr_MatNotFound
#define C4MCErr_ReinstNoGlobal
#define C4MCErr_UnnamedNoGlbl
#define C4MCErr_FieldValInvalid
#define C4MCErr_ReinstUnknown
#define C4MCErr_EqSColonBlOpenExp
#define C4MCErr_SColonExp
#define C4MCErr_UnknownDir
#define C4MCErr_NoRecTemplate
#define C4MCErr_OpTypeErr
#define C4MCErr_FieldConstExp
BYTE Mat2PixColDefault(int32_t mat)
C4Fixed itofix(int32_t x)
C4Real Cos(const C4Real &fAngle)
int fixtoi(const C4Fixed &x)
C4Real Sin(const C4Real &fAngle)
void AddDbgRec(C4RecordChunkType eType, const void *pData, int iSize)
C4GameScriptHost GameScript
C4Value C4VInt(int32_t i)
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
int SGetLine(const char *szText, const char *cpPosition)
bool SEqual(const char *szStr1, const char *szStr2)
StdStrBuf FormatString(const char *szFmt,...)
void Rotate(MatrixType &mat, float angle, float x, float y, float z)
C4Value Exec(C4PropList *p=nullptr, C4AulParSet *pPars=nullptr, bool fPassErrors=false)
C4Value Call(const char *szFunction, C4AulParSet *pPars=nullptr, bool fPassError=false)
bool Read(void *buffer, size_t size) override
bool AccessEntry(const char *wildcard, size_t *size=nullptr, char *filename=nullptr, bool needs_to_be_a_group=false)
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)
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 * GetNodeByName(const char *szName)
const char * StrPar(C4MCParser *pParser, const char *szSVal, int32_t iVal, C4MCTokenType ValType)
virtual bool SetOp(C4MCTokenType eOp)
C4MCOverlay * OwnerOverlay()
C4MapCreatorS2 * MapCreator
virtual bool GlobalScope()
int32_t IntPar(C4MCParser *pParser, const char *szSVal, int32_t iVal, C4MCTokenType ValType)
C4MCNode(C4MCNode *pOwner=nullptr)
virtual C4MCOverlay * Overlay()
virtual C4MCNodeType Type()
void Reg2Owner(C4MCNode *pOwner)
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)
C4MCCallbackArray * pEvaluateFunc
bool SetField(C4MCParser *pParser, const char *szField, const char *szSVal, int32_t iVal, C4MCTokenType ValType) override
char Texture[C4M_MaxName+1]
C4MCCallbackArray * pDrawFunc
bool PeekPix(int32_t iX, int32_t iY)
C4MCOverlay * Overlay() override
bool CheckMask(int32_t iX, int32_t iY)
C4MCOverlay * FirstOfChain()
C4MCOverlay(C4MCNode *pOwner=nullptr)
bool InBounds(int32_t iX, int32_t iY)
C4MCAlgorithm * GetAlgo(const char *szName)
C4MCAlgorithm * Algorithm
C4MCParserErr(C4MCParser *pParser, const char *szMsg)
C4MCParser(C4MapCreatorS2 *pMapCreator)
void ParseFile(const char *szFilename, C4Group *pGrp)
friend class C4MCParserErr
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
C4MCPoint(C4MCNode *pOwner=nullptr)
~C4MapCreatorS2() override
C4MapCreatorS2(C4SLandscape *pLandscape, C4TextureMap *pTexMap, C4MaterialMap *pMatMap, int iPlayerCount)
C4MCCallbackArrayList CallbackArrays
BYTE * RenderBuf(const char *szMapName, int32_t &sfcWdt, int32_t &sfcHgt)
bool ReadFile(const char *szFilename, C4Group *pGrp)
bool ReadScript(const char *szScript)
C4MCOverlay DefaultOverlay
C4MCMap * GetMap(const char *szMapName)
bool Render(const char *szMapName, CSurface8 *&sfcMap, CSurface8 *&sfcMapBkg)
int32_t Get(const char *szMaterial)
C4AulFunc * GetFunc(C4PropertyName k) const
void GetMapSize(int32_t &rWdt, int32_t &rHgt, int32_t iPlayerNum)
bool CheckTexture(const char *szTexture)
int32_t GetIndexMatTex(const char *szMaterialTexture, const char *szDefaultTexture=nullptr, bool fAddIfNotExist=true, const char *szErrorIfFailed=nullptr)
C4PropList * _getPropList() const
const char * getData() const
bool(* Function)(C4MCOverlay *, int32_t, int32_t)