1 | /** |
2 | * Copyright (c) 2006-2023 LOVE Development Team |
3 | * |
4 | * This software is provided 'as-is', without any express or implied |
5 | * warranty. In no event will the authors be held liable for any damages |
6 | * arising from the use of this software. |
7 | * |
8 | * Permission is granted to anyone to use this software for any purpose, |
9 | * including commercial applications, and to alter it and redistribute it |
10 | * freely, subject to the following restrictions: |
11 | * |
12 | * 1. The origin of this software must not be misrepresented; you must not |
13 | * claim that you wrote the original software. If you use this software |
14 | * in a product, an acknowledgment in the product documentation would be |
15 | * appreciated but is not required. |
16 | * 2. Altered source versions must be plainly marked as such, and must not be |
17 | * misrepresented as being the original software. |
18 | * 3. This notice may not be removed or altered from any source distribution. |
19 | **/ |
20 | |
21 | // LOVE |
22 | #include "wrap_SpriteBatch.h" |
23 | #include "Image.h" |
24 | #include "Canvas.h" |
25 | #include "wrap_Texture.h" |
26 | |
27 | namespace love |
28 | { |
29 | namespace graphics |
30 | { |
31 | |
32 | SpriteBatch *luax_checkspritebatch(lua_State *L, int idx) |
33 | { |
34 | return luax_checktype<SpriteBatch>(L, idx); |
35 | } |
36 | |
37 | static inline int w_SpriteBatch_add_or_set(lua_State *L, SpriteBatch *t, int startidx, int index) |
38 | { |
39 | Quad *quad = nullptr; |
40 | |
41 | if (luax_istype(L, startidx, Quad::type)) |
42 | { |
43 | quad = luax_totype<Quad>(L, startidx); |
44 | startidx++; |
45 | } |
46 | else if (lua_isnil(L, startidx) && !lua_isnoneornil(L, startidx + 1)) |
47 | return luax_typerror(L, startidx, "Quad" ); |
48 | |
49 | luax_checkstandardtransform(L, startidx, [&](const Matrix4 &m) |
50 | { |
51 | luax_catchexcept(L, [&]() |
52 | { |
53 | if (quad) |
54 | index = t->add(quad, m, index); |
55 | else |
56 | index = t->add(m, index); |
57 | }); |
58 | }); |
59 | |
60 | return index; |
61 | } |
62 | |
63 | static int w_SpriteBatch_addLayer_or_setLayer(lua_State *L, SpriteBatch *t, int startidx, int index) |
64 | { |
65 | Quad *quad = nullptr; |
66 | int layer = (int) luaL_checkinteger(L, startidx) - 1; |
67 | startidx++; |
68 | |
69 | if (luax_istype(L, startidx, Quad::type)) |
70 | { |
71 | quad = luax_totype<Quad>(L, startidx); |
72 | startidx++; |
73 | } |
74 | else if (lua_isnil(L, startidx) && !lua_isnoneornil(L, startidx + 1)) |
75 | return luax_typerror(L, startidx, "Quad" ); |
76 | |
77 | luax_checkstandardtransform(L, startidx, [&](const Matrix4 &m) |
78 | { |
79 | luax_catchexcept(L, [&]() |
80 | { |
81 | if (quad) |
82 | index = t->addLayer(layer, quad, m, index); |
83 | else |
84 | index = t->addLayer(layer, m, index); |
85 | }); |
86 | }); |
87 | |
88 | return index; |
89 | } |
90 | |
91 | int w_SpriteBatch_add(lua_State *L) |
92 | { |
93 | SpriteBatch *t = luax_checkspritebatch(L, 1); |
94 | |
95 | int index = w_SpriteBatch_add_or_set(L, t, 2, -1); |
96 | lua_pushinteger(L, index + 1); |
97 | |
98 | return 1; |
99 | } |
100 | |
101 | int w_SpriteBatch_set(lua_State *L) |
102 | { |
103 | SpriteBatch *t = luax_checkspritebatch(L, 1); |
104 | int index = (int) luaL_checkinteger(L, 2) - 1; |
105 | |
106 | w_SpriteBatch_add_or_set(L, t, 3, index); |
107 | |
108 | return 0; |
109 | } |
110 | |
111 | int w_SpriteBatch_addLayer(lua_State *L) |
112 | { |
113 | SpriteBatch *t = luax_checkspritebatch(L, 1); |
114 | |
115 | int index = w_SpriteBatch_addLayer_or_setLayer(L, t, 2, -1); |
116 | lua_pushinteger(L, index + 1); |
117 | |
118 | return 1; |
119 | } |
120 | |
121 | int w_SpriteBatch_setLayer(lua_State *L) |
122 | { |
123 | SpriteBatch *t = luax_checkspritebatch(L, 1); |
124 | int index = (int) luaL_checkinteger(L, 2) - 1; |
125 | |
126 | w_SpriteBatch_addLayer_or_setLayer(L, t, 3, index); |
127 | |
128 | return 0; |
129 | } |
130 | |
131 | int w_SpriteBatch_clear(lua_State *L) |
132 | { |
133 | SpriteBatch *t = luax_checkspritebatch(L, 1); |
134 | t->clear(); |
135 | return 0; |
136 | } |
137 | |
138 | int w_SpriteBatch_flush(lua_State *L) |
139 | { |
140 | SpriteBatch *t = luax_checkspritebatch(L, 1); |
141 | t->flush(); |
142 | return 0; |
143 | } |
144 | |
145 | int w_SpriteBatch_setTexture(lua_State *L) |
146 | { |
147 | SpriteBatch *t = luax_checkspritebatch(L, 1); |
148 | Texture *tex = luax_checktexture(L, 2); |
149 | luax_catchexcept(L, [&](){ t->setTexture(tex); }); |
150 | return 0; |
151 | } |
152 | |
153 | int w_SpriteBatch_getTexture(lua_State *L) |
154 | { |
155 | SpriteBatch *t = luax_checkspritebatch(L, 1); |
156 | Texture *tex = t->getTexture(); |
157 | |
158 | // FIXME: big hack right here. |
159 | if (dynamic_cast<Image *>(tex) != nullptr) |
160 | luax_pushtype(L, Image::type, tex); |
161 | else if (dynamic_cast<Canvas *>(tex) != nullptr) |
162 | luax_pushtype(L, Canvas::type, tex); |
163 | else |
164 | return luaL_error(L, "Unable to determine texture type." ); |
165 | |
166 | return 1; |
167 | } |
168 | |
169 | int w_SpriteBatch_setColor(lua_State *L) |
170 | { |
171 | SpriteBatch *t = luax_checkspritebatch(L, 1); |
172 | Colorf c; |
173 | |
174 | if (lua_gettop(L) <= 1) |
175 | { |
176 | t->setColor(); |
177 | return 0; |
178 | } |
179 | else if (lua_istable(L, 2)) |
180 | { |
181 | for (int i = 1; i <= 4; i++) |
182 | lua_rawgeti(L, 2, i); |
183 | |
184 | c.r = (float) luaL_checknumber(L, -4); |
185 | c.g = (float) luaL_checknumber(L, -3); |
186 | c.b = (float) luaL_checknumber(L, -2); |
187 | c.a = (float) luaL_optnumber(L, -1, 1.0); |
188 | |
189 | lua_pop(L, 4); |
190 | } |
191 | else |
192 | { |
193 | c.r = (float) luaL_checknumber(L, 2); |
194 | c.g = (float) luaL_checknumber(L, 3); |
195 | c.b = (float) luaL_checknumber(L, 4); |
196 | c.a = (float) luaL_optnumber(L, 5, 1.0); |
197 | } |
198 | |
199 | t->setColor(c); |
200 | |
201 | return 0; |
202 | } |
203 | |
204 | int w_SpriteBatch_getColor(lua_State *L) |
205 | { |
206 | SpriteBatch *t = luax_checkspritebatch(L, 1); |
207 | bool active = false; |
208 | Colorf color = t->getColor(active); |
209 | |
210 | // getColor returns null if no color is set. |
211 | if (!active) |
212 | return 0; |
213 | |
214 | lua_pushnumber(L, color.r); |
215 | lua_pushnumber(L, color.g); |
216 | lua_pushnumber(L, color.b); |
217 | lua_pushnumber(L, color.a); |
218 | |
219 | return 4; |
220 | } |
221 | |
222 | int w_SpriteBatch_getCount(lua_State *L) |
223 | { |
224 | SpriteBatch *t = luax_checkspritebatch(L, 1); |
225 | lua_pushinteger(L, t->getCount()); |
226 | return 1; |
227 | } |
228 | |
229 | int w_SpriteBatch_getBufferSize(lua_State *L) |
230 | { |
231 | SpriteBatch *t = luax_checkspritebatch(L, 1); |
232 | lua_pushinteger(L, t->getBufferSize()); |
233 | return 1; |
234 | } |
235 | |
236 | int w_SpriteBatch_attachAttribute(lua_State *L) |
237 | { |
238 | SpriteBatch *t = luax_checkspritebatch(L, 1); |
239 | const char *name = luaL_checkstring(L, 2); |
240 | Mesh *m = luax_checktype<Mesh>(L, 3); |
241 | |
242 | luax_catchexcept(L, [&](){ t->attachAttribute(name, m); }); |
243 | return 0; |
244 | } |
245 | |
246 | int w_SpriteBatch_setDrawRange(lua_State *L) |
247 | { |
248 | SpriteBatch *t = luax_checkspritebatch(L, 1); |
249 | |
250 | if (lua_isnoneornil(L, 2)) |
251 | t->setDrawRange(); |
252 | else |
253 | { |
254 | int start = (int) luaL_checkinteger(L, 2) - 1; |
255 | int count = (int) luaL_checkinteger(L, 3); |
256 | luax_catchexcept(L, [&](){ t->setDrawRange(start, count); }); |
257 | } |
258 | |
259 | return 0; |
260 | } |
261 | |
262 | int w_SpriteBatch_getDrawRange(lua_State *L) |
263 | { |
264 | SpriteBatch *t = luax_checkspritebatch(L, 1); |
265 | |
266 | int start = 0; |
267 | int count = 1; |
268 | if (!t->getDrawRange(start, count)) |
269 | return 0; |
270 | |
271 | lua_pushnumber(L, start + 1); |
272 | lua_pushnumber(L, count); |
273 | return 2; |
274 | } |
275 | |
276 | static const luaL_Reg w_SpriteBatch_functions[] = |
277 | { |
278 | { "add" , w_SpriteBatch_add }, |
279 | { "set" , w_SpriteBatch_set }, |
280 | { "addLayer" , w_SpriteBatch_addLayer }, |
281 | { "setLayer" , w_SpriteBatch_setLayer }, |
282 | { "clear" , w_SpriteBatch_clear }, |
283 | { "flush" , w_SpriteBatch_flush }, |
284 | { "setTexture" , w_SpriteBatch_setTexture }, |
285 | { "getTexture" , w_SpriteBatch_getTexture }, |
286 | { "setColor" , w_SpriteBatch_setColor }, |
287 | { "getColor" , w_SpriteBatch_getColor }, |
288 | { "getCount" , w_SpriteBatch_getCount }, |
289 | { "getBufferSize" , w_SpriteBatch_getBufferSize }, |
290 | { "attachAttribute" , w_SpriteBatch_attachAttribute }, |
291 | { "setDrawRange" , w_SpriteBatch_setDrawRange }, |
292 | { "getDrawRange" , w_SpriteBatch_getDrawRange }, |
293 | { 0, 0 } |
294 | }; |
295 | |
296 | extern "C" int luaopen_spritebatch(lua_State *L) |
297 | { |
298 | return luax_register_type(L, &SpriteBatch::type, w_SpriteBatch_functions, nullptr); |
299 | } |
300 | |
301 | } // graphics |
302 | } // love |
303 | |