summaryrefslogtreecommitdiff
path: root/ZAPD/ZVector.cpp
blob: 092b876d20bb03911c4e30973d865ac400742790 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include "ZVector.h"

#include <cassert>

#include "Globals.h"
#include "Utils/BitConverter.h"
#include <Utils/DiskFile.h>
#include "Utils/StringHelper.h"
#include "WarningHandler.h"
#include "ZFile.h"

REGISTER_ZFILENODE(Vector, ZVector);

ZVector::ZVector(ZFile* nParent) : ZResource(nParent)
{
	scalarType = ZScalarType::ZSCALAR_NONE;
	dimensions = 0;

	RegisterRequiredAttribute("Type");
	RegisterRequiredAttribute("Dimensions");
}

void ZVector::ExtractFromBinary(uint32_t nRawDataIndex, ZScalarType nScalarType,
                                uint32_t nDimensions)
{
	rawDataIndex = nRawDataIndex;
	scalarType = nScalarType;
	dimensions = nDimensions;

	// Don't parse raw data of external files
	if (parent->GetMode() == ZFileMode::ExternalFile)
		return;

	ParseRawData();
}

void ZVector::ParseXML(tinyxml2::XMLElement* reader)
{
	ZResource::ParseXML(reader);

	this->scalarType = ZScalar::MapOutputTypeToScalarType(registeredAttributes.at("Type").value);

	this->dimensions = StringHelper::StrToL(registeredAttributes.at("Dimensions").value, 16);
}

void ZVector::ParseRawData()
{
	int32_t currentRawDataIndex = rawDataIndex;
	// TODO: this shouldn't be necessary.
	scalars.clear();
	scalars.reserve(dimensions);
	for (uint32_t i = 0; i < dimensions; i++)
	{
		ZScalar scalar(parent);
		scalar.ExtractFromBinary(currentRawDataIndex, scalarType);
		currentRawDataIndex += scalar.GetRawDataSize();

		scalars.push_back(scalar);
	}

	// Ensure the scalars vector has the same number of elements as the vector dimension.
	assert(scalars.size() == dimensions);
}

size_t ZVector::GetRawDataSize() const
{
	size_t size = 0;

	for (size_t i = 0; i < this->scalars.size(); i++)
		size += this->scalars[i].GetRawDataSize();

	return size;
}

bool ZVector::DoesSupportArray() const
{
	return true;
}

std::string ZVector::GetSourceTypeName() const
{
	if (dimensions == 3 && scalarType == ZScalarType::ZSCALAR_F32)
		return "Vec3f";
	else if (dimensions == 3 && scalarType == ZScalarType::ZSCALAR_S16)
		return "Vec3s";
	else if (dimensions == 3 && scalarType == ZScalarType::ZSCALAR_S32)
		return "Vec3i";
	else
	{
		std::string msgHeader = StringHelper::Sprintf(
			"encountered unsupported vector type: %d dimensions, %s type", dimensions,
			ZScalar::MapScalarTypeToOutputType(scalarType).c_str());

		HANDLE_ERROR_RESOURCE(WarningType::NotImplemented, parent, this, rawDataIndex, msgHeader,
		                      "");
	}
}

std::string ZVector::GetBodySourceCode() const
{
	std::string body = "";

	for (size_t i = 0; i < scalars.size(); i++)
	{
		body += StringHelper::Sprintf("%6s", scalars[i].GetBodySourceCode().c_str());

		if (i + 1 < scalars.size())
			body += ", ";
	}

	return body;
}

ZResourceType ZVector::GetResourceType() const
{
	return ZResourceType::Vector;
}

DeclarationAlignment ZVector::GetDeclarationAlignment() const
{
	if (scalars.size() == 0)
	{
		return DeclarationAlignment::Align4;
	}
	return scalars.at(0).GetDeclarationAlignment();
}