summary refs log tree commit diff stats
path: root/vendor
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2018-05-23 21:28:29 -0400
committerKelly Rauchenberger <fefferburbia@gmail.com>2018-05-23 21:28:29 -0400
commitf545cf0276e95c9dca33d36d1a0cfe3b4995473a (patch)
tree7ff4023bd6c9e22f82a230a358eb70521f4c2306 /vendor
downloadether-f545cf0276e95c9dca33d36d1a0cfe3b4995473a.tar.gz
ether-f545cf0276e95c9dca33d36d1a0cfe3b4995473a.tar.bz2
ether-f545cf0276e95c9dca33d36d1a0cfe3b4995473a.zip
somethign
Diffstat (limited to 'vendor')
-rw-r--r--vendor/fov.c427
-rw-r--r--vendor/fov.h245
2 files changed, 672 insertions, 0 deletions
diff --git a/vendor/fov.c b/vendor/fov.c new file mode 100644 index 0000000..74ed5c8 --- /dev/null +++ b/vendor/fov.c
@@ -0,0 +1,427 @@
1/*
2 * Copyright (C) 2006, Greg McIntyre
3 * All rights reserved. See the file named COPYING in the distribution
4 * for more details.
5 */
6
7#include <stdlib.h>
8#include <string.h>
9#include <stdio.h>
10#define __USE_ISOC99 1
11#include <math.h>
12#include <float.h>
13#include <assert.h>
14#include "fov.h"
15
16/*
17+---++---++---++---+
18| || || || |
19| || || || |
20| || || || |
21+---++---++---++---+ 2
22+---++---++---+#####
23| || || |#####
24| || || |#####
25| || || |#####
26+---++---++---+#####X 1 <-- y
27+---++---++---++---+
28| || || || |
29| @ || || || | <-- srcy centre -> dy = 0.5 = y - 0.5
30| || || || |
31+---++---++---++---+ 0
320 1 2 3 4
33 ^ ^
34 | |
35 srcx x -> dx = 3.5 = x + 0.5
36centre
37
38Slope from @ to X.
39
40+---++---++---++---+
41| || || || |
42| || || || |
43| || || || |
44+---++---++---++---+ 2
45+---++---++---++---+
46| || || || |
47| || || || |
48| || || || |
49+---++---++---+X---+ 1 <-- y
50+---++---++---+#####
51| || || |#####
52| @ || || |##### <-- srcy centre -> dy = 0.5 = y - 0.5
53| || || |#####
54+---++---++---+##### 0
550 1 2 3
56 ^ ^
57 | |
58 srcx x -> dx = 2.5 = x - 0.5
59centre
60
61Slope from @ to X
62*/
63
64
65/* Types ---------------------------------------------------------- */
66
67/** \cond INTERNAL */
68typedef struct {
69 /*@observer@*/ fov_settings_type *settings;
70 /*@observer@*/ void *map;
71 /*@observer@*/ void *source;
72 int source_x;
73 int source_y;
74 unsigned radius;
75} fov_private_data_type;
76/** \endcond */
77
78/* Options -------------------------------------------------------- */
79
80void fov_settings_init(fov_settings_type *settings) {
81 settings->shape = FOV_SHAPE_CIRCLE_PRECALCULATE;
82 settings->corner_peek = FOV_CORNER_NOPEEK;
83 settings->opaque_apply = FOV_OPAQUE_APPLY;
84 settings->opaque = NULL;
85 settings->apply = NULL;
86 settings->heights = NULL;
87 settings->numheights = 0;
88}
89
90void fov_settings_set_shape(fov_settings_type *settings,
91 fov_shape_type value) {
92 settings->shape = value;
93}
94
95void fov_settings_set_corner_peek(fov_settings_type *settings,
96 fov_corner_peek_type value) {
97 settings->corner_peek = value;
98}
99
100void fov_settings_set_opaque_apply(fov_settings_type *settings,
101 fov_opaque_apply_type value) {
102 settings->opaque_apply = value;
103}
104
105void fov_settings_set_opacity_test_function(fov_settings_type *settings,
106 bool (*f)(void *map,
107 int x, int y)) {
108 settings->opaque = f;
109}
110
111void fov_settings_set_apply_lighting_function(fov_settings_type *settings,
112 void (*f)(void *map,
113 int x, int y,
114 int dx, int dy,
115 void *src)) {
116 settings->apply = f;
117}
118
119/* Circular FOV --------------------------------------------------- */
120
121/*@null@*/ static unsigned *precalculate_heights(unsigned maxdist) {
122 unsigned i;
123 unsigned *result = (unsigned *)malloc((maxdist+2)*sizeof(unsigned));
124 if (result) {
125 for (i = 0; i <= maxdist; ++i) {
126 result[i] = (unsigned)sqrtf((float)(maxdist*maxdist - i*i));
127 }
128 result[maxdist+1] = 0;
129 }
130 return result;
131}
132
133static unsigned height(fov_settings_type *settings, int x,
134 unsigned maxdist) {
135 unsigned **newheights;
136
137 if (maxdist > settings->numheights) {
138 newheights = (unsigned **)calloc((size_t)maxdist, sizeof(unsigned*));
139 if (newheights != NULL) {
140 if (settings->heights != NULL && settings->numheights > 0) {
141 /* Copy the pointers to the heights arrays we've already
142 * calculated. Once copied out, we can free the old
143 * array of pointers. */
144 memcpy(newheights, settings->heights,
145 settings->numheights*sizeof(unsigned*));
146 free(settings->heights);
147 }
148 settings->heights = newheights;
149 settings->numheights = maxdist;
150 }
151 }
152 if (settings->heights) {
153 if (settings->heights[maxdist-1] == NULL) {
154 settings->heights[maxdist-1] = precalculate_heights(maxdist);
155 }
156 if (settings->heights[maxdist-1] != NULL) {
157 return settings->heights[maxdist-1][abs(x)];
158 }
159 }
160 return 0;
161}
162
163void fov_settings_free(fov_settings_type *settings) {
164 unsigned i;
165 if (settings != NULL) {
166 if (settings->heights != NULL && settings->numheights > 0) {
167 /*@+forloopexec@*/
168 for (i = 0; i < settings->numheights; ++i) {
169 unsigned *h = settings->heights[i];
170 if (h != NULL) {
171 free(h);
172 }
173 settings->heights[i] = NULL;
174 }
175 /*@=forloopexec@*/
176 free(settings->heights);
177 settings->heights = NULL;
178 settings->numheights = 0;
179 }
180 }
181}
182
183/* Slope ---------------------------------------------------------- */
184
185static float fov_slope(float dx, float dy) {
186 if (dx <= -FLT_EPSILON || dx >= FLT_EPSILON) {
187 return dy/dx;
188 } else {
189 return 0.0;
190 }
191}
192
193/* Octants -------------------------------------------------------- */
194
195#define FOV_DEFINE_OCTANT(signx, signy, rx, ry, nx, ny, nf, apply_edge, apply_diag) \
196 static void fov_octant_##nx##ny##nf( \
197 fov_private_data_type *data, \
198 int dx, \
199 float start_slope, \
200 float end_slope) { \
201 int x, y, dy, dy0, dy1; \
202 unsigned h; \
203 int prev_blocked = -1; \
204 float end_slope_next; \
205 fov_settings_type *settings = data->settings; \
206 \
207 if (dx == 0) { \
208 fov_octant_##nx##ny##nf(data, dx+1, start_slope, end_slope); \
209 return; \
210 } else if ((unsigned)dx > data->radius) { \
211 return; \
212 } \
213 \
214 dy0 = (int)(0.5f + ((float)dx)*start_slope); \
215 dy1 = (int)(0.5f + ((float)dx)*end_slope); \
216 \
217 rx = data->source_##rx signx dx; \
218 ry = data->source_##ry signy dy0; \
219 \
220 if (!apply_diag && dy1 == dx) { \
221 /* We do diagonal lines on every second octant, so they don't get done twice. */ \
222 --dy1; \
223 } \
224 \
225 switch (settings->shape) { \
226 case FOV_SHAPE_CIRCLE_PRECALCULATE: \
227 h = height(settings, dx, data->radius); \
228 break; \
229 case FOV_SHAPE_CIRCLE: \
230 h = (unsigned)sqrtf((float)(data->radius*data->radius - dx*dx)); \
231 break; \
232 case FOV_SHAPE_OCTAGON: \
233 h = (data->radius - dx)<<1; \
234 break; \
235 default: \
236 h = data->radius; \
237 break; \
238 }; \
239 if ((unsigned)dy1 > h) { \
240 if (h == 0) { \
241 return; \
242 } \
243 dy1 = (int)h; \
244 } \
245 \
246 /*fprintf(stderr, "(%2d) = [%2d .. %2d] (%f .. %f), h=%d,edge=%d\n", \
247 dx, dy0, dy1, ((float)dx)*start_slope, \
248 0.5f + ((float)dx)*end_slope, h, apply_edge);*/ \
249 \
250 for (dy = dy0; dy <= dy1; ++dy) { \
251 ry = data->source_##ry signy dy; \
252 \
253 if (settings->opaque(data->map, x, y)) { \
254 if (settings->opaque_apply == FOV_OPAQUE_APPLY && (apply_edge || dy > 0)) { \
255 settings->apply(data->map, x, y, x - data->source_x, y - data->source_y, data->source); \
256 } \
257 if (prev_blocked == 0) { \
258 end_slope_next = fov_slope((float)dx + 0.5f, (float)dy - 0.5f); \
259 fov_octant_##nx##ny##nf(data, dx+1, start_slope, end_slope_next); \
260 } \
261 prev_blocked = 1; \
262 } else { \
263 if (apply_edge || dy > 0) { \
264 settings->apply(data->map, x, y, x - data->source_x, y - data->source_y, data->source); \
265 } \
266 if (prev_blocked == 1) { \
267 start_slope = fov_slope((float)dx - 0.5f, (float)dy - 0.5f); \
268 } \
269 prev_blocked = 0; \
270 } \
271 } \
272 \
273 if (prev_blocked == 0) { \
274 fov_octant_##nx##ny##nf(data, dx+1, start_slope, end_slope); \
275 } \
276 }
277
278FOV_DEFINE_OCTANT(+,+,x,y,p,p,n,true,true)
279FOV_DEFINE_OCTANT(+,+,y,x,p,p,y,true,false)
280FOV_DEFINE_OCTANT(+,-,x,y,p,m,n,false,true)
281FOV_DEFINE_OCTANT(+,-,y,x,p,m,y,false,false)
282FOV_DEFINE_OCTANT(-,+,x,y,m,p,n,true,true)
283FOV_DEFINE_OCTANT(-,+,y,x,m,p,y,true,false)
284FOV_DEFINE_OCTANT(-,-,x,y,m,m,n,false,true)
285FOV_DEFINE_OCTANT(-,-,y,x,m,m,y,false,false)
286
287
288/* Circle --------------------------------------------------------- */
289
290static void _fov_circle(fov_private_data_type *data) {
291 /*
292 * Octants are defined by (x,y,r) where:
293 * x = [p]ositive or [n]egative x increment
294 * y = [p]ositive or [n]egative y increment
295 * r = [y]es or [n]o for reflecting on axis x = y
296 *
297 * \pmy|ppy/
298 * \ | /
299 * \ | /
300 * mpn\|/ppn
301 * ----@----
302 * mmn/|\pmn
303 * / | \
304 * / | \
305 * /mmy|mpy\
306 */
307 fov_octant_ppn(data, 1, (float)0.0f, (float)1.0f);
308 fov_octant_ppy(data, 1, (float)0.0f, (float)1.0f);
309 fov_octant_pmn(data, 1, (float)0.0f, (float)1.0f);
310 fov_octant_pmy(data, 1, (float)0.0f, (float)1.0f);
311 fov_octant_mpn(data, 1, (float)0.0f, (float)1.0f);
312 fov_octant_mpy(data, 1, (float)0.0f, (float)1.0f);
313 fov_octant_mmn(data, 1, (float)0.0f, (float)1.0f);
314 fov_octant_mmy(data, 1, (float)0.0f, (float)1.0f);
315}
316
317void fov_circle(fov_settings_type *settings,
318 void *map,
319 void *source,
320 int source_x,
321 int source_y,
322 unsigned radius) {
323 fov_private_data_type data;
324
325 data.settings = settings;
326 data.map = map;
327 data.source = source;
328 data.source_x = source_x;
329 data.source_y = source_y;
330 data.radius = radius;
331
332 _fov_circle(&data);
333}
334
335/**
336 * Limit x to the range [a, b].
337 */
338static float betweenf(float x, float a, float b) {
339 if (x - a < FLT_EPSILON) { /* x < a */
340 return a;
341 } else if (x - b > FLT_EPSILON) { /* x > b */
342 return b;
343 } else {
344 return x;
345 }
346}
347
348#define BEAM_DIRECTION(d, p1, p2, p3, p4, p5, p6, p7, p8) \
349 if (direction == d) { \
350 end_slope = betweenf(a, 0.0f, 1.0f); \
351 fov_octant_##p1(&data, 1, 0.0f, end_slope); \
352 fov_octant_##p2(&data, 1, 0.0f, end_slope); \
353 if (a - 1.0f > FLT_EPSILON) { /* a > 1.0f */ \
354 start_slope = betweenf(2.0f - a, 0.0f, 1.0f); \
355 fov_octant_##p3(&data, 1, start_slope, 1.0f); \
356 fov_octant_##p4(&data, 1, start_slope, 1.0f); \
357 } \
358 if (a - 2.0f > FLT_EPSILON) { /* a > 2.0f */ \
359 end_slope = betweenf(a - 2.0f, 0.0f, 1.0f); \
360 fov_octant_##p5(&data, 1, 0.0f, end_slope); \
361 fov_octant_##p6(&data, 1, 0.0f, end_slope); \
362 } \
363 if (a - 3.0f > FLT_EPSILON) { /* a > 3.0f */ \
364 start_slope = betweenf(4.0f - a, 0.0f, 1.0f); \
365 fov_octant_##p7(&data, 1, start_slope, 1.0f); \
366 fov_octant_##p8(&data, 1, start_slope, 1.0f); \
367 } \
368 }
369
370#define BEAM_DIRECTION_DIAG(d, p1, p2, p3, p4, p5, p6, p7, p8) \
371 if (direction == d) { \
372 start_slope = betweenf(1.0f - a, 0.0f, 1.0f); \
373 fov_octant_##p1(&data, 1, start_slope, 1.0f); \
374 fov_octant_##p2(&data, 1, start_slope, 1.0f); \
375 if (a - 1.0f > FLT_EPSILON) { /* a > 1.0f */ \
376 end_slope = betweenf(a - 1.0f, 0.0f, 1.0f); \
377 fov_octant_##p3(&data, 1, 0.0f, end_slope); \
378 fov_octant_##p4(&data, 1, 0.0f, end_slope); \
379 } \
380 if (a - 2.0f > FLT_EPSILON) { /* a > 2.0f */ \
381 start_slope = betweenf(3.0f - a, 0.0f, 1.0f); \
382 fov_octant_##p5(&data, 1, start_slope, 1.0f); \
383 fov_octant_##p6(&data, 1, start_slope, 1.0f); \
384 } \
385 if (a - 3.0f > FLT_EPSILON) { /* a > 3.0f */ \
386 end_slope = betweenf(a - 3.0f, 0.0f, 1.0f); \
387 fov_octant_##p7(&data, 1, 0.0f, end_slope); \
388 fov_octant_##p8(&data, 1, 0.0f, end_slope); \
389 } \
390 }
391
392void fov_beam(fov_settings_type *settings, void *map, void *source,
393 int source_x, int source_y, unsigned radius,
394 fov_direction_type direction, float angle) {
395
396 fov_private_data_type data;
397 float start_slope, end_slope, a;
398
399 data.settings = settings;
400 data.map = map;
401 data.source = source;
402 data.source_x = source_x;
403 data.source_y = source_y;
404 data.radius = radius;
405
406 if (angle <= 0.0f) {
407 return;
408 } else if (angle >= 360.0f) {
409 _fov_circle(&data);
410 return;
411 }
412
413 /* Calculate the angle as a percentage of 45 degrees, halved (for
414 * each side of the centre of the beam). e.g. angle = 180.0f means
415 * half the beam is 90.0 which is 2x45, so the result is 2.0.
416 */
417 a = angle/90.0f;
418
419 BEAM_DIRECTION(FOV_EAST, ppn, pmn, ppy, mpy, pmy, mmy, mpn, mmn);
420 BEAM_DIRECTION(FOV_WEST, mpn, mmn, pmy, mmy, ppy, mpy, ppn, pmn);
421 BEAM_DIRECTION(FOV_NORTH, mpy, mmy, mmn, pmn, mpn, ppn, pmy, ppy);
422 BEAM_DIRECTION(FOV_SOUTH, pmy, ppy, mpn, ppn, mmn, pmn, mmy, mpy);
423 BEAM_DIRECTION_DIAG(FOV_NORTHEAST, pmn, mpy, mmy, ppn, mmn, ppy, mpn, pmy);
424 BEAM_DIRECTION_DIAG(FOV_NORTHWEST, mmn, mmy, mpn, mpy, pmy, pmn, ppy, ppn);
425 BEAM_DIRECTION_DIAG(FOV_SOUTHEAST, ppn, ppy, pmy, pmn, mpn, mpy, mmn, mmy);
426 BEAM_DIRECTION_DIAG(FOV_SOUTHWEST, pmy, mpn, ppy, mmn, ppn, mmy, pmn, mpy);
427}
diff --git a/vendor/fov.h b/vendor/fov.h new file mode 100644 index 0000000..b27f59c --- /dev/null +++ b/vendor/fov.h
@@ -0,0 +1,245 @@
1/*
2 * Copyright (C) 2006-2007, Greg McIntyre. All rights reserved. See the file
3 * named COPYING in the distribution for more details.
4 */
5
6/**
7 * \mainpage Field of View Library
8 *
9 * \section about About
10 *
11 * This is a C library which implements a course-grained lighting
12 * algorithm suitable for tile-based games such as roguelikes.
13 *
14 * \section copyright Copyright
15 *
16 * \verbinclude COPYING
17 *
18 * \section thanks Thanks
19 *
20 * Thanks to Bj&ouml;rn Bergstr&ouml;m
21 * <bjorn.bergstrom@hyperisland.se> for the algorithm.
22 *
23 */
24
25/**
26 * \file fov.h
27 * Field-of-view algorithm for dynamically casting light/shadow on a
28 * low resolution 2D raster.
29 */
30#ifndef LIBFOV_HEADER
31#define LIBFOV_HEADER
32
33#include <stdbool.h>
34#include <stddef.h>
35
36#ifdef __cplusplus
37extern "C" {
38#endif
39
40/** Eight-way directions. */
41typedef enum {
42 FOV_EAST = 0,
43 FOV_NORTHEAST,
44 FOV_NORTH,
45 FOV_NORTHWEST,
46 FOV_WEST,
47 FOV_SOUTHWEST,
48 FOV_SOUTH,
49 FOV_SOUTHEAST
50} fov_direction_type;
51
52/** Values for the shape setting. */
53typedef enum {
54 FOV_SHAPE_CIRCLE_PRECALCULATE,
55 FOV_SHAPE_SQUARE,
56 FOV_SHAPE_CIRCLE,
57 FOV_SHAPE_OCTAGON
58} fov_shape_type;
59
60/** Values for the corner peek setting. */
61typedef enum {
62 FOV_CORNER_NOPEEK,
63 FOV_CORNER_PEEK
64} fov_corner_peek_type;
65
66/** Values for the opaque apply setting. */
67typedef enum {
68 FOV_OPAQUE_APPLY,
69 FOV_OPAQUE_NOAPPLY
70} fov_opaque_apply_type;
71
72/** @cond INTERNAL */
73typedef /*@null@*/ unsigned *height_array_t;
74/** @endcond */
75
76typedef struct {
77 /** Opacity test callback. */
78 /*@null@*/ bool (*opaque)(void *map, int x, int y);
79
80 /** Lighting callback to set lighting on a map tile. */
81 /*@null@*/ void (*apply)(void *map, int x, int y, int dx, int dy, void *src);
82
83 /** Shape setting. */
84 fov_shape_type shape;
85
86 /** Whether to peek around corners. */
87 fov_corner_peek_type corner_peek;
88
89 /** Whether to call apply on opaque tiles. */
90 fov_opaque_apply_type opaque_apply;
91
92 /** \cond INTERNAL */
93
94 /** Pre-calculated data. \internal */
95 /*@null@*/ height_array_t *heights;
96
97 /** Size of pre-calculated data. \internal */
98 unsigned numheights;
99
100 /** \endcond */
101} fov_settings_type;
102
103/** The opposite direction to that given. */
104#define fov_direction_opposite(direction) ((fov_direction_type)(((direction)+4)&0x7))
105
106/**
107 * Set all the default options. You must call this option when you
108 * create a new settings data structure.
109 *
110 * These settings are the defaults used:
111 *
112 * - shape: FOV_SHAPE_CIRCLE_PRECALCULATE
113 * - corner_peek: FOV_CORNER_NOPEEK
114 * - opaque_apply: FOV_OPAQUE_APPLY
115 *
116 * Callbacks still need to be set up after calling this function.
117 *
118 * \param settings Pointer to data structure containing settings.
119 */
120void fov_settings_init(fov_settings_type *settings);
121
122/**
123 * Set the shape of the field of view.
124 *
125 * \param settings Pointer to data structure containing settings.
126 * \param value One of the following values, where R is the radius:
127 *
128 * - FOV_SHAPE_CIRCLE_PRECALCULATE \b (default): Limit the FOV to a
129 * circle with radius R by precalculating, which consumes more memory
130 * at the rate of 4*(R+2) bytes per R used in calls to fov_circle.
131 * Each radius is only calculated once so that it can be used again.
132 * Use fov_free() to free this precalculated data's memory.
133 *
134 * - FOV_SHAPE_CIRCLE: Limit the FOV to a circle with radius R by
135 * calculating on-the-fly.
136 *
137 * - FOV_SHAPE_OCTOGON: Limit the FOV to an octogon with maximum radius R.
138 *
139 * - FOV_SHAPE_SQUARE: Limit the FOV to an R*R square.
140 */
141void fov_settings_set_shape(fov_settings_type *settings, fov_shape_type value);
142
143/**
144 * <em>NOT YET IMPLEMENTED</em>.
145 *
146 * Set whether sources will peek around corners.
147 *
148 * \param settings Pointer to data structure containing settings.
149 * \param value One of the following values:
150 *
151 * - FOV_CORNER_PEEK \b (default): Renders:
152\verbatim
153 ........
154 ........
155 ........
156 ..@#
157 ...#
158\endverbatim
159 * - FOV_CORNER_NOPEEK: Renders:
160\verbatim
161 ......
162 .....
163 ....
164 ..@#
165 ...#
166\endverbatim
167 */
168void fov_settings_set_corner_peek(fov_settings_type *settings, fov_corner_peek_type value);
169
170/**
171 * Whether to call the apply callback on opaque tiles.
172 *
173 * \param settings Pointer to data structure containing settings.
174 * \param value One of the following values:
175 *
176 * - FOV_OPAQUE_APPLY \b (default): Call apply callback on opaque tiles.
177 * - FOV_OPAQUE_NOAPPLY: Do not call the apply callback on opaque tiles.
178 */
179void fov_settings_set_opaque_apply(fov_settings_type *settings, fov_opaque_apply_type value);
180
181/**
182 * Set the function used to test whether a map tile is opaque.
183 *
184 * \param settings Pointer to data structure containing settings.
185 * \param f The function called to test whether a map tile is opaque.
186 */
187void fov_settings_set_opacity_test_function(fov_settings_type *settings, bool (*f)(void *map, int x, int y));
188
189/**
190 * Set the function used to apply lighting to a map tile.
191 *
192 * \param settings Pointer to data structure containing settings.
193 * \param f The function called to apply lighting to a map tile.
194 */
195void fov_settings_set_apply_lighting_function(fov_settings_type *settings, void (*f)(void *map, int x, int y, int dx, int dy, void *src));
196
197/**
198 * Free any memory that may have been cached in the settings
199 * structure.
200 *
201 * \param settings Pointer to data structure containing settings.
202 */
203void fov_settings_free(fov_settings_type *settings);
204
205/**
206 * Calculate a full circle field of view from a source at (x,y).
207 *
208 * \param settings Pointer to data structure containing settings.
209 * \param map Pointer to map data structure to be passed to callbacks.
210 * \param source Pointer to data structure holding source of light.
211 * \param source_x x-axis coordinate from which to start.
212 * \param source_y y-axis coordinate from which to start.
213 * \param radius Euclidean distance from (x,y) after which to stop.
214 */
215void fov_circle(fov_settings_type *settings, void *map, void *source,
216 int source_x, int source_y, unsigned radius
217);
218
219/**
220 * Calculate a field of view from source at (x,y), pointing
221 * in the given direction and with the given angle. The larger
222 * the angle, the wider, "less focused" the beam. Each side of the
223 * line pointing in the direction from the source will be half the
224 * angle given such that the angle specified will be represented on
225 * the raster.
226 *
227 * \param settings Pointer to data structure containing settings.
228 * \param map Pointer to map data structure to be passed to callbacks.
229 * \param source Pointer to data structure holding source of light.
230 * \param source_x x-axis coordinate from which to start.
231 * \param source_y y-axis coordinate from which to start.
232 * \param radius Euclidean distance from (x,y) after which to stop.
233 * \param direction One of eight directions the beam of light can point.
234 * \param angle The angle at the base of the beam of light, in degrees.
235 */
236void fov_beam(fov_settings_type *settings, void *map, void *source,
237 int source_x, int source_y, unsigned radius,
238 fov_direction_type direction, float angle
239);
240
241#ifdef __cplusplus
242} /* extern "C" */
243#endif
244
245#endif