1 /* Copyright (C) 2022 Wildfire Games.
2 * This file is part of 0 A.D.
4 * 0 A.D. is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * 0 A.D. is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
18 #include "precompiled.h"
19 #include "TerrainProperties.h"
24 #include <boost/tokenizer.hpp>
26 #include "graphics/Color.h"
27 #include "graphics/TerrainTextureManager.h"
28 #include "maths/MathUtil.h"
29 #include "ps/CLogger.h"
30 #include "ps/Filesystem.h"
31 #include "ps/XML/Xeromyces.h"
33 CTerrainProperties::CTerrainProperties(CTerrainPropertiesPtr parent
):
36 m_HasBaseColor(false),
37 m_TextureAngle((float)M_PI
/ 4.f
),
41 m_Groups
= m_pParent
->m_Groups
;
44 CTerrainPropertiesPtr
CTerrainProperties::FromXML(const CTerrainPropertiesPtr
& parent
, const VfsPath
& pathname
)
47 if (XeroFile
.Load(g_VFS
, pathname
, "terrain") != PSRETURN_OK
)
48 return CTerrainPropertiesPtr();
50 XMBElement root
= XeroFile
.GetRoot();
51 CStr rootName
= XeroFile
.GetElementString(root
.GetNodeName());
53 // Check that we've got the right kind of xml document
54 if (rootName
!= "Terrains")
56 LOGERROR("TerrainProperties: Loading %s: Root node is not terrains (found \"%s\")",
59 return CTerrainPropertiesPtr();
62 #define ELMT(x) int el_##x = XeroFile.GetElementID(#x)
66 // Ignore all non-terrain nodes, loading the first terrain node and
68 // Really, we only expect there to be one child and it to be of the right
70 XERO_ITER_EL(root
, child
)
72 if (child
.GetNodeName() == el_terrain
)
74 CTerrainPropertiesPtr
ret (new CTerrainProperties(parent
));
75 ret
->LoadXml(child
, &XeroFile
, pathname
);
80 LOGWARNING("TerrainProperties: Loading %s: Unexpected node %s\n",
82 XeroFile
.GetElementString(child
.GetNodeName()));
83 // Keep reading - typos shouldn't be showstoppers
87 return CTerrainPropertiesPtr();
90 void CTerrainProperties::LoadXml(XMBElement node
, CXeromyces
*pFile
, const VfsPath
& UNUSED(pathname
))
92 #define ELMT(x) int elmt_##x = pFile->GetElementID(#x)
93 #define ATTR(x) int attr_##x = pFile->GetAttributeID(#x)
102 XERO_ITER_ATTR(node
, attr
)
104 if (attr
.Name
== attr_groups
)
106 // Parse a comma-separated list of groups, add the new entry to
109 boost::char_separator
<char> sep(", ");
110 typedef boost::tokenizer
<boost::char_separator
<char> > tokenizer
;
111 tokenizer
tok(attr
.Value
, sep
);
112 for(tokenizer::iterator it
= tok
.begin(); it
!= tok
.end(); ++it
)
113 m_Groups
.push_back(g_TexMan
.FindGroup(*it
));
115 else if (attr
.Name
== attr_mmap
)
118 if (!col
.ParseString(attr
.Value
, 255))
121 // m_BaseColor is BGRA
122 u8
*baseColor
= (u8
*)&m_BaseColor
;
123 baseColor
[0] = (u8
)(col
.b
*255);
124 baseColor
[1] = (u8
)(col
.g
*255);
125 baseColor
[2] = (u8
)(col
.r
*255);
126 baseColor
[3] = (u8
)(col
.a
*255);
127 m_HasBaseColor
= true;
129 else if (attr
.Name
== attr_angle
)
131 m_TextureAngle
= DEGTORAD(attr
.Value
.ToFloat());
133 else if (attr
.Name
== attr_size
)
135 m_TextureSize
= attr
.Value
.ToFloat();
140 bool CTerrainProperties::HasBaseColor()
142 return m_HasBaseColor
|| (m_pParent
&& m_pParent
->HasBaseColor());
145 u32
CTerrainProperties::GetBaseColor()
147 if (m_HasBaseColor
|| !m_pParent
)
150 return m_pParent
->GetBaseColor();
152 // White, full opacity.. but this value shouldn't ever be used