File: background_element.cpp

package info (click to toggle)
freespace2 24.2.0%2Brepack-1
  • links: PTS, VCS
  • area: non-free
  • in suites: forky, sid
  • size: 43,716 kB
  • sloc: cpp: 595,001; ansic: 21,741; python: 1,174; sh: 457; makefile: 248; xml: 181
file content (175 lines) | stat: -rw-r--r-- 6,361 bytes parent folder | download
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
//
//

#include "starfield/starfield.h"
#include "background_element.h"
#include "vecmath.h"

namespace scripting {
namespace api {

ADE_OBJ(l_BackgroundElement, background_el_h, "background_element", "Background element handle");

background_el_h::background_el_h(BackgroundType in_type, int in_id) : type(in_type), id(in_id) {}

bool background_el_h::isValid() const
{
	switch (type)
	{
		case BackgroundType::Sun:
			return id >= 0 && id < stars_get_num_suns();
		case BackgroundType::Bitmap:
			return id >= 0 && id < stars_get_num_bitmaps();
		case BackgroundType::Invalid:
		default:
			return false;
	}
}

ADE_FUNC(isValid, l_BackgroundElement, nullptr, "Determines if this handle is valid", "boolean",
         "true if valid, false if not.")
{
	background_el_h* el = nullptr;
	if (!ade_get_args(L, "o", l_BackgroundElement.GetPtr(&el)))
		return ADE_RETURN_FALSE;

	return ade_set_args(L, "b", el->isValid());
}

ADE_VIRTVAR(Orientation, l_BackgroundElement, "orientation", "Backround element orientation (treating the angles as correctly calculated)", "orientation", "Orientation, or null orientation if handle is invalid")
{
	background_el_h* el = nullptr;
	matrix_h* mh = nullptr;
	if (!ade_get_args(L, "o|o", l_BackgroundElement.GetPtr(&el), l_Matrix.GetPtr(&mh)))
		return ade_set_error(L, "o", l_Matrix.Set(matrix_h(&vmd_identity_matrix)));

	if (!el->isValid())
		return ade_set_error(L, "o", l_Matrix.Set(matrix_h(&vmd_identity_matrix)));

	starfield_list_entry sle;
	stars_get_data(el->type == BackgroundType::Sun, el->id, sle);

	if (ADE_SETTING_VAR && mh != nullptr)
	{
		sle.ang = *mh->GetAngles();
		stars_set_data(el->type == BackgroundType::Sun, el->id, sle);
	}

	return ade_set_args(L, "o", l_Matrix.Set(matrix_h(&sle.ang)));
}

template <typename T>
static int background_element_getset_number_helper(lua_State* L, T starfield_list_entry::* field)
{
	constexpr char type_char = std::conditional<std::is_floating_point<T>::value, std::integral_constant<char, 'f'>, std::integral_constant<char, 'i'>>::type::value;
	constexpr char type_str[] = { type_char, '\0' };
	constexpr char object_and_type_str[] = { 'o', '|', type_char, '\0' };

	background_el_h* el = nullptr;
	T value{};
	if (!ade_get_args(L, object_and_type_str, l_BackgroundElement.GetPtr(&el), &value))
		return ade_set_error(L, type_str, value);

	if (!el->isValid())
		return ade_set_error(L, type_str, value);

	starfield_list_entry sle;
	stars_get_data(el->type == BackgroundType::Sun, el->id, sle);

	if (ADE_SETTING_VAR)
	{
		sle.*field = value;
		stars_set_data(el->type == BackgroundType::Sun, el->id, sle);
	}

	return ade_set_args(L, type_str, sle.*field);
}

template <typename T>
static int background_element_set_number_2x_helper(lua_State* L, T starfield_list_entry::* field1, T starfield_list_entry::* field2)
{
	constexpr char type_char = std::conditional<std::is_floating_point<T>::value, std::integral_constant<char, 'f'>, std::integral_constant<char, 'i'>>::type::value;
	constexpr char object_and_type_str[] = { 'o', type_char, type_char, '\0' };

	background_el_h* el = nullptr;
	T value1{};
	T value2{};
	if (!ade_get_args(L, object_and_type_str, l_BackgroundElement.GetPtr(&el), &value1, &value2))
		return ADE_RETURN_FALSE;

	if (!el->isValid())
		return ADE_RETURN_FALSE;

	starfield_list_entry sle;
	stars_get_data(el->type == BackgroundType::Sun, el->id, sle);

	sle.*field1 = value1;
	sle.*field2 = value2;
	stars_set_data(el->type == BackgroundType::Sun, el->id, sle);

	return ADE_RETURN_TRUE;
}

static int background_element_set_number_4x_helper(lua_State* L)
{
	background_el_h* el = nullptr;
	int div_x = 0;
	int div_y = 0;
	float scale_x = 0.0f;
	float scale_y = 0.0f;
	if (!ade_get_args(L, "offii", l_BackgroundElement.GetPtr(&el), &scale_x, &scale_y, &div_x, &div_y))
		return ADE_RETURN_FALSE;

	if (!el->isValid())
		return ADE_RETURN_FALSE;

	starfield_list_entry sle;
	stars_get_data(el->type == BackgroundType::Sun, el->id, sle);

	sle.scale_x = scale_x;
	sle.scale_y = scale_y;
	sle.div_x = div_x;
	sle.div_y = div_y;
	stars_set_data(el->type == BackgroundType::Sun, el->id, sle);

	return ADE_RETURN_TRUE;
}

ADE_VIRTVAR(DivX, l_BackgroundElement, "number", "Division X", "number", "Division X, or 0 if handle is invalid")
{
	return background_element_getset_number_helper(L, &starfield_list_entry::div_x);
}

ADE_VIRTVAR(DivY, l_BackgroundElement, "number", "Division Y", "number", "Division Y, or 0 if handle is invalid")
{
	return background_element_getset_number_helper(L, &starfield_list_entry::div_y);
}

ADE_VIRTVAR(ScaleX, l_BackgroundElement, "number", "Scale X", "number", "Scale X, or 0 if handle is invalid")
{
	return background_element_getset_number_helper(L, &starfield_list_entry::scale_x);
}

ADE_VIRTVAR(ScaleY, l_BackgroundElement, "number", "Scale Y", "number", "Scale Y, or 0 if handle is invalid")
{
	return background_element_getset_number_helper(L, &starfield_list_entry::scale_y);
}

ADE_FUNC(setDiv, l_BackgroundElement, "number, number", "Sets Division X and Division Y at the same time.  For Bitmaps this avoids a double recalculation of the vertex buffer, if both values need to be set.  For all background elements this also avoids fetching and setting the data twice.", "boolean", "True if the operation was successful")
{
	return background_element_set_number_2x_helper(L, &starfield_list_entry::div_x, &starfield_list_entry::div_y);
}

ADE_FUNC(setScale, l_BackgroundElement, "number, number", "Sets Scale X and Scale Y at the same time.  For Bitmaps this avoids a double recalculation of the vertex buffer, if both values need to be set.  For all background elements this also avoids fetching and setting the data twice.", "boolean", "True if the operation was successful")
{
	return background_element_set_number_2x_helper(L, &starfield_list_entry::scale_x, &starfield_list_entry::scale_y);
}

ADE_FUNC(setScaleAndDiv, l_BackgroundElement, "number, number, number, number", "Sets Scale X, Scale Y, Division X, and Division Y at the same time.  For Bitmaps this avoids a quadruple recalculation of the vertex buffer, if all four values need to be set.  For all background elements this also avoids fetching and setting the data four times.", "boolean", "True if the operation was successful")
{
	return background_element_set_number_4x_helper(L);
}


} // namespace api
} // namespace scripting