Line data Source code
1 : /* Copyright (C) 2022 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
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.
8 : *
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.
13 : *
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/>.
16 : */
17 :
18 : #include "precompiled.h"
19 : #include "TerrainProperties.h"
20 :
21 : #include <string>
22 : #include <vector>
23 :
24 : #include <boost/tokenizer.hpp>
25 :
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"
32 :
33 0 : CTerrainProperties::CTerrainProperties(CTerrainPropertiesPtr parent):
34 : m_pParent(parent),
35 : m_BaseColor(0),
36 : m_HasBaseColor(false),
37 : m_TextureAngle((float)M_PI / 4.f),
38 0 : m_TextureSize(32.f)
39 : {
40 0 : if (m_pParent)
41 0 : m_Groups = m_pParent->m_Groups;
42 0 : }
43 :
44 0 : CTerrainPropertiesPtr CTerrainProperties::FromXML(const CTerrainPropertiesPtr& parent, const VfsPath& pathname)
45 : {
46 0 : CXeromyces XeroFile;
47 0 : if (XeroFile.Load(g_VFS, pathname, "terrain") != PSRETURN_OK)
48 0 : return CTerrainPropertiesPtr();
49 :
50 0 : XMBElement root = XeroFile.GetRoot();
51 0 : CStr rootName = XeroFile.GetElementString(root.GetNodeName());
52 :
53 : // Check that we've got the right kind of xml document
54 0 : if (rootName != "Terrains")
55 : {
56 0 : LOGERROR("TerrainProperties: Loading %s: Root node is not terrains (found \"%s\")",
57 : pathname.string8(),
58 : rootName);
59 0 : return CTerrainPropertiesPtr();
60 : }
61 :
62 : #define ELMT(x) int el_##x = XeroFile.GetElementID(#x)
63 0 : ELMT(terrain);
64 : #undef ELMT
65 :
66 : // Ignore all non-terrain nodes, loading the first terrain node and
67 : // returning it.
68 : // Really, we only expect there to be one child and it to be of the right
69 : // type, though.
70 0 : XERO_ITER_EL(root, child)
71 : {
72 0 : if (child.GetNodeName() == el_terrain)
73 : {
74 0 : CTerrainPropertiesPtr ret (new CTerrainProperties(parent));
75 0 : ret->LoadXml(child, &XeroFile, pathname);
76 0 : return ret;
77 : }
78 : else
79 : {
80 0 : LOGWARNING("TerrainProperties: Loading %s: Unexpected node %s\n",
81 : pathname.string8(),
82 : XeroFile.GetElementString(child.GetNodeName()));
83 : // Keep reading - typos shouldn't be showstoppers
84 : }
85 : }
86 :
87 0 : return CTerrainPropertiesPtr();
88 : }
89 :
90 0 : void CTerrainProperties::LoadXml(XMBElement node, CXeromyces *pFile, const VfsPath& UNUSED(pathname))
91 : {
92 : #define ELMT(x) int elmt_##x = pFile->GetElementID(#x)
93 : #define ATTR(x) int attr_##x = pFile->GetAttributeID(#x)
94 : // Terrain Attribs
95 0 : ATTR(mmap);
96 0 : ATTR(groups);
97 0 : ATTR(angle);
98 0 : ATTR(size);
99 : #undef ELMT
100 : #undef ATTR
101 :
102 0 : XERO_ITER_ATTR(node, attr)
103 : {
104 0 : if (attr.Name == attr_groups)
105 : {
106 : // Parse a comma-separated list of groups, add the new entry to
107 : // each of them
108 0 : m_Groups.clear();
109 0 : boost::char_separator<char> sep(", ");
110 : typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
111 0 : tokenizer tok(attr.Value, sep);
112 0 : for(tokenizer::iterator it = tok.begin(); it != tok.end(); ++it)
113 0 : m_Groups.push_back(g_TexMan.FindGroup(*it));
114 : }
115 0 : else if (attr.Name == attr_mmap)
116 : {
117 0 : CColor col;
118 0 : if (!col.ParseString(attr.Value, 255))
119 0 : continue;
120 :
121 : // m_BaseColor is BGRA
122 0 : u8 *baseColor = (u8*)&m_BaseColor;
123 0 : baseColor[0] = (u8)(col.b*255);
124 0 : baseColor[1] = (u8)(col.g*255);
125 0 : baseColor[2] = (u8)(col.r*255);
126 0 : baseColor[3] = (u8)(col.a*255);
127 0 : m_HasBaseColor = true;
128 : }
129 0 : else if (attr.Name == attr_angle)
130 : {
131 0 : m_TextureAngle = DEGTORAD(attr.Value.ToFloat());
132 : }
133 0 : else if (attr.Name == attr_size)
134 : {
135 0 : m_TextureSize = attr.Value.ToFloat();
136 : }
137 : }
138 0 : }
139 :
140 0 : bool CTerrainProperties::HasBaseColor()
141 : {
142 0 : return m_HasBaseColor || (m_pParent && m_pParent->HasBaseColor());
143 : }
144 :
145 0 : u32 CTerrainProperties::GetBaseColor()
146 : {
147 0 : if (m_HasBaseColor || !m_pParent)
148 0 : return m_BaseColor;
149 0 : else if (m_pParent)
150 0 : return m_pParent->GetBaseColor();
151 : else
152 : // White, full opacity.. but this value shouldn't ever be used
153 0 : return 0xFFFFFFFF;
154 3 : }
|