Branch data Line data Source code
1 : : /* ______ ___ ___
2 : : * /\ _ \ /\_ \ /\_ \
3 : : * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___
4 : : * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\
5 : : * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \
6 : : * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7 : : * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8 : : * /\____/
9 : : * \_/__/
10 : : *
11 : : * Core primitive addon functions.
12 : : *
13 : : *
14 : : * By Pavel Sountsov.
15 : : *
16 : : * See readme.txt for copyright information.
17 : : */
18 : :
19 : : #include "allegro5/allegro.h"
20 : : #include "allegro5/allegro_primitives.h"
21 : : #include "allegro5/internal/aintern_prim_opengl.h"
22 : : #include "allegro5/internal/aintern_prim_directx.h"
23 : : #include "allegro5/platform/alplatf.h"
24 : : #include "allegro5/internal/aintern_prim_soft.h"
25 : : #include "allegro5/internal/aintern_bitmap.h"
26 : : #include "allegro5/internal/aintern_prim.h"
27 : : #include "allegro5/internal/aintern.h"
28 : : #include <math.h>
29 : :
30 : : #ifdef ALLEGRO_CFG_OPENGL
31 : : #include "allegro5/allegro_opengl.h"
32 : : #endif
33 : :
34 : : /*
35 : : TODO: This is a hack... I need to know the values of these without actually including the respective system headers
36 : : */
37 : : #ifndef ALLEGRO_OPENGL
38 : : #define ALLEGRO_OPENGL 4
39 : : #endif
40 : : #ifndef ALLEGRO_DIRECT3D
41 : : #define ALLEGRO_DIRECT3D 8
42 : : #endif
43 : :
44 : : static bool addon_initialized = false;
45 : :
46 : : /* Function: al_init_primitives_addon
47 : : */
48 : 2 : bool al_init_primitives_addon(void)
49 : : {
50 : 2 : bool ret = true;
51 : 2 : ret &= _al_init_d3d_driver();
52 : :
53 : 2 : addon_initialized = ret;
54 : :
55 : 2 : _al_add_exit_func(al_shutdown_primitives_addon, "primitives_shutdown");
56 : :
57 : 2 : return ret;
58 : : }
59 : :
60 : : /* Function: al_shutdown_primitives_addon
61 : : */
62 : 2 : void al_shutdown_primitives_addon(void)
63 : : {
64 : 2 : _al_shutdown_d3d_driver();
65 : 2 : addon_initialized = false;
66 : 2 : }
67 : :
68 : : /* Function: al_draw_prim
69 : : */
70 : 4528 : int al_draw_prim(const void* vtxs, const ALLEGRO_VERTEX_DECL* decl,
71 : : ALLEGRO_BITMAP* texture, int start, int end, int type)
72 : : {
73 : : ALLEGRO_BITMAP *target;
74 : 4528 : int ret = 0;
75 : :
76 [ - + ][ # # ]: 4528 : ASSERT(addon_initialized);
[ # # ]
77 [ - + ][ # # ]: 4528 : ASSERT(vtxs);
[ # # ]
78 [ - + ][ # # ]: 4528 : ASSERT(end >= start);
[ # # ]
79 [ - + ][ # # ]: 4528 : ASSERT(type >= 0 && type < ALLEGRO_PRIM_NUM_TYPES);
[ # # ]
80 : :
81 : 4528 : target = al_get_target_bitmap();
82 : :
83 : : /* In theory, if we ever get a camera concept for this addon, the transformation into
84 : : * view space should occur here
85 : : */
86 : :
87 [ + + ][ + + ]: 4528 : if (target->flags & ALLEGRO_MEMORY_BITMAP || (texture && texture->flags & ALLEGRO_MEMORY_BITMAP)) {
[ - + ]
88 : 4312 : ret = _al_draw_prim_soft(texture, vtxs, decl, start, end, type);
89 : : } else {
90 : 216 : int flags = al_get_display_flags(target->display);
91 [ + - ]: 216 : if (flags & ALLEGRO_OPENGL) {
92 : 216 : ret = _al_draw_prim_opengl(target, texture, vtxs, decl, start, end, type);
93 [ # # ]: 0 : } else if (flags & ALLEGRO_DIRECT3D) {
94 : 0 : ret = _al_draw_prim_directx(target, texture, vtxs, decl, start, end, type);
95 : : }
96 : : }
97 : :
98 : 4528 : return ret;
99 : : }
100 : :
101 : : /* Function: al_draw_indexed_prim
102 : : */
103 : 0 : int al_draw_indexed_prim(const void* vtxs, const ALLEGRO_VERTEX_DECL* decl,
104 : : ALLEGRO_BITMAP* texture, const int* indices, int num_vtx, int type)
105 : : {
106 : : ALLEGRO_BITMAP *target;
107 : 0 : int ret = 0;
108 : :
109 [ # # ][ # # ]: 0 : ASSERT(addon_initialized);
[ # # ]
110 [ # # ][ # # ]: 0 : ASSERT(vtxs);
[ # # ]
111 [ # # ][ # # ]: 0 : ASSERT(indices);
[ # # ]
112 [ # # ][ # # ]: 0 : ASSERT(num_vtx > 0);
[ # # ]
113 [ # # ][ # # ]: 0 : ASSERT(type >= 0 && type < ALLEGRO_PRIM_NUM_TYPES);
[ # # ]
114 : :
115 : 0 : target = al_get_target_bitmap();
116 : :
117 : : /* In theory, if we ever get a camera concept for this addon, the transformation into
118 : : * view space should occur here
119 : : */
120 : :
121 [ # # ][ # # ]: 0 : if (target->flags & ALLEGRO_MEMORY_BITMAP || (texture && texture->flags & ALLEGRO_MEMORY_BITMAP)) {
[ # # ]
122 : 0 : ret = _al_draw_prim_indexed_soft(texture, vtxs, decl, indices, num_vtx, type);
123 : : } else {
124 : 0 : int flags = al_get_display_flags(target->display);
125 [ # # ]: 0 : if (flags & ALLEGRO_OPENGL) {
126 : 0 : ret = _al_draw_prim_indexed_opengl(target, texture, vtxs, decl, indices, num_vtx, type);
127 [ # # ]: 0 : } else if (flags & ALLEGRO_DIRECT3D) {
128 : 0 : ret = _al_draw_prim_indexed_directx(target, texture, vtxs, decl, indices, num_vtx, type);
129 : : }
130 : : }
131 : :
132 : 0 : return ret;
133 : : }
134 : :
135 : 0 : int _al_bitmap_region_is_locked(ALLEGRO_BITMAP* bmp, int x1, int y1, int w, int h)
136 : : {
137 [ # # ][ # # ]: 0 : ASSERT(bmp);
[ # # ]
138 : :
139 [ # # ]: 0 : if (!al_is_bitmap_locked(bmp))
140 : : return 0;
141 [ # # ][ # # ]: 0 : if (x1 + w > bmp->lock_x && y1 + h > bmp->lock_y && x1 < bmp->lock_x + bmp->lock_w && y1 < bmp->lock_y + bmp->lock_h)
[ # # ][ # # ]
142 : : return 1;
143 : 0 : return 0;
144 : : }
145 : :
146 : : /* Function: al_get_allegro_primitives_version
147 : : */
148 : 0 : uint32_t al_get_allegro_primitives_version(void)
149 : : {
150 : 0 : return ALLEGRO_VERSION_INT;
151 : : }
152 : :
153 : : /* Function: al_create_vertex_decl
154 : : */
155 : 0 : ALLEGRO_VERTEX_DECL* al_create_vertex_decl(const ALLEGRO_VERTEX_ELEMENT* elements, int stride)
156 : : {
157 : : ALLEGRO_VERTEX_DECL* ret;
158 : : ALLEGRO_DISPLAY* display;
159 : : int flags;
160 : :
161 [ # # ][ # # ]: 0 : ASSERT(addon_initialized);
[ # # ]
162 : :
163 : 0 : ret = al_malloc(sizeof(ALLEGRO_VERTEX_DECL));
164 : 0 : ret->elements = al_calloc(1, sizeof(ALLEGRO_VERTEX_ELEMENT) * ALLEGRO_PRIM_ATTR_NUM);
165 [ # # ]: 0 : while(elements->attribute) {
166 : 0 : ret->elements[elements->attribute] = *elements;
167 : 0 : elements++;
168 : : }
169 : :
170 : 0 : display = al_get_current_display();
171 : 0 : flags = al_get_display_flags(display);
172 [ # # ]: 0 : if (flags & ALLEGRO_DIRECT3D) {
173 : 0 : _al_set_d3d_decl(display, ret);
174 : : }
175 : :
176 : 0 : ret->stride = stride;
177 : 0 : return ret;
178 : : }
179 : :
180 : : /* Function: al_destroy_vertex_decl
181 : : */
182 : 0 : void al_destroy_vertex_decl(ALLEGRO_VERTEX_DECL* decl)
183 : : {
184 : 0 : al_free(decl->elements);
185 : : /*
186 : : * TODO: Somehow free the d3d_decl
187 : : */
188 : 0 : al_free(decl);
189 : 0 : }
190 : :
191 : : /* Function: al_create_vertex_buffer
192 : : */
193 : 0 : ALLEGRO_VERTEX_BUFFER* al_create_vertex_buffer(ALLEGRO_VERTEX_DECL* decl,
194 : : const void* initial_data, size_t num_vertices, bool write_only, int hints)
195 : : {
196 : : ALLEGRO_VERTEX_BUFFER* ret;
197 : 0 : int flags = al_get_display_flags(al_get_current_display());
198 [ # # ][ # # ]: 0 : ASSERT(addon_initialized);
[ # # ]
199 : 0 : ret = al_calloc(1, sizeof(ALLEGRO_VERTEX_BUFFER));
200 : 0 : ret->write_only = write_only;
201 : 0 : ret->decl = decl;
202 : :
203 : : #if defined ALLEGRO_IPHONE || defined ALLEGRO_ANDROID
204 : : if (!write_only)
205 : : goto fail;
206 : : #endif
207 : :
208 [ # # ]: 0 : if (flags & ALLEGRO_OPENGL) {
209 [ # # ]: 0 : if (_al_create_vertex_buffer_opengl(ret, initial_data, num_vertices, hints))
210 : : return ret;
211 : : }
212 [ # # ]: 0 : else if (flags & ALLEGRO_DIRECT3D) {
213 [ # # ]: 0 : if (_al_create_vertex_buffer_directx(ret, initial_data, num_vertices, hints))
214 : : return ret;
215 : : }
216 : :
217 : : /* Silence the warning */
218 : : goto fail;
219 : : fail:
220 : 0 : al_free(ret);
221 : 0 : return 0;
222 : : }
223 : :
224 : : /* Function: al_destroy_vertex_buffer
225 : : */
226 : 0 : void al_destroy_vertex_buffer(ALLEGRO_VERTEX_BUFFER* buffer)
227 : : {
228 : 0 : int flags = al_get_display_flags(al_get_current_display());
229 [ # # ][ # # ]: 0 : ASSERT(addon_initialized);
[ # # ]
230 : :
231 [ # # ]: 0 : if (buffer == 0)
232 : 0 : return;
233 : :
234 : 0 : al_unlock_vertex_buffer(buffer);
235 : :
236 [ # # ]: 0 : if (flags & ALLEGRO_OPENGL) {
237 : 0 : _al_destroy_vertex_buffer_opengl(buffer);
238 : : }
239 [ # # ]: 0 : else if (flags & ALLEGRO_DIRECT3D) {
240 : 0 : _al_destroy_vertex_buffer_directx(buffer);
241 : : }
242 : :
243 : 0 : al_free(buffer);
244 : : }
245 : :
246 : : /* Function: al_lock_vertex_buffer
247 : : */
248 : 0 : void* al_lock_vertex_buffer(ALLEGRO_VERTEX_BUFFER* buffer, size_t offset,
249 : : size_t length, int flags)
250 : : {
251 : : void* ret;
252 : : int stride;
253 : 0 : int disp_flags = al_get_display_flags(al_get_current_display());
254 [ # # ][ # # ]: 0 : ASSERT(buffer);
[ # # ]
255 [ # # ][ # # ]: 0 : ASSERT(addon_initialized);
[ # # ]
256 [ # # ][ # # ]: 0 : if (buffer->is_locked || (buffer->write_only && flags != ALLEGRO_LOCK_WRITEONLY))
[ # # ]
257 : : return 0;
258 : :
259 [ # # ]: 0 : stride = buffer->decl ? buffer->decl->stride : (int)sizeof(ALLEGRO_VERTEX);
260 : 0 : buffer->lock_offset = offset * stride;
261 : 0 : buffer->lock_length = length * stride;
262 : 0 : buffer->lock_flags = flags;
263 : :
264 [ # # ]: 0 : if (disp_flags & ALLEGRO_OPENGL) {
265 : 0 : ret = _al_lock_vertex_buffer_opengl(buffer);
266 : : }
267 [ # # ]: 0 : else if (disp_flags & ALLEGRO_DIRECT3D) {
268 : 0 : ret = _al_lock_vertex_buffer_directx(buffer);
269 : : }
270 : : else {
271 : : ret = NULL;
272 : : }
273 : :
274 : 0 : buffer->is_locked = true;
275 : :
276 : 0 : return ret;
277 : : }
278 : :
279 : : /* Function: al_unlock_vertex_buffer
280 : : */
281 : 0 : void al_unlock_vertex_buffer(ALLEGRO_VERTEX_BUFFER* buffer)
282 : : {
283 : 0 : int flags = al_get_display_flags(al_get_current_display());
284 [ # # ][ # # ]: 0 : ASSERT(buffer);
[ # # ]
285 [ # # ][ # # ]: 0 : ASSERT(addon_initialized);
[ # # ]
286 : :
287 [ # # ]: 0 : if (!buffer->is_locked)
288 : 0 : return;
289 : :
290 [ # # ]: 0 : if (flags & ALLEGRO_OPENGL) {
291 : 0 : _al_unlock_vertex_buffer_opengl(buffer);
292 : : }
293 [ # # ]: 0 : else if (flags & ALLEGRO_DIRECT3D) {
294 : 0 : _al_unlock_vertex_buffer_directx(buffer);
295 : : }
296 : :
297 : 0 : buffer->is_locked = false;
298 : : }
299 : :
300 : : /* Function: al_draw_vertex_buffer
301 : : */
302 : 0 : int al_draw_vertex_buffer(ALLEGRO_VERTEX_BUFFER* vertex_buffer,
303 : : ALLEGRO_BITMAP* texture, int start, int end, int type)
304 : : {
305 : : ALLEGRO_BITMAP *target;
306 : 0 : int ret = 0;
307 : :
308 [ # # ][ # # ]: 0 : ASSERT(addon_initialized);
[ # # ]
309 [ # # ][ # # ]: 0 : ASSERT(end >= start);
[ # # ]
310 [ # # ][ # # ]: 0 : ASSERT(type >= 0 && type < ALLEGRO_PRIM_NUM_TYPES);
[ # # ]
311 [ # # ][ # # ]: 0 : ASSERT(vertex_buffer);
[ # # ]
312 [ # # ][ # # ]: 0 : ASSERT(!vertex_buffer->is_locked);
[ # # ]
313 : :
314 : 0 : target = al_get_target_bitmap();
315 : :
316 [ # # ][ # # ]: 0 : if (target->flags & ALLEGRO_MEMORY_BITMAP || (texture && texture->flags & ALLEGRO_MEMORY_BITMAP)) {
[ # # ]
317 : : void* vtx;
318 [ # # ][ # # ]: 0 : ASSERT(!vertex_buffer->write_only);
[ # # ]
319 : 0 : vtx = al_lock_vertex_buffer(vertex_buffer, start, end, ALLEGRO_LOCK_READONLY);
320 [ # # ][ # # ]: 0 : ASSERT(vtx);
[ # # ]
321 : 0 : ret = _al_draw_prim_soft(texture, vtx, vertex_buffer->decl, 0, end - start, type);
322 : 0 : al_unlock_vertex_buffer(vertex_buffer);
323 : : } else {
324 : 0 : int flags = al_get_display_flags(al_get_current_display());
325 [ # # ]: 0 : if (flags & ALLEGRO_OPENGL) {
326 : 0 : ret = _al_draw_vertex_buffer_opengl(target, texture, vertex_buffer, start, end, type);
327 : : }
328 [ # # ]: 0 : else if (flags & ALLEGRO_DIRECT3D) {
329 : 0 : ret = _al_draw_vertex_buffer_directx(target, texture, vertex_buffer, start, end, type);
330 : : }
331 : : }
332 : :
333 : 0 : return ret;
334 : : }
|