hfov 1.0.1 → 1.0.2
raw patch · 9 files changed
+770/−712 lines, 9 filesdep ~basesetup-changed
Dependency ranges changed: base
Files
- FOV.hsc +7/−6
- LICENSE +26/−16
- Setup.hs +2/−0
- Setup.lhs +0/−3
- cfov.c +429/−0
- cfov.h +238/−0
- fov.c +0/−429
- fov.h +0/−238
- hfov.cabal +68/−20
FOV.hsc view
@@ -1,4 +1,5 @@-{-# OPTIONS -fffi -fglasgow-exts #-}+{-# LANGUAGE ForeignFunctionInterface #-}+{-# LANGUAGE EmptyDataDecls #-} -- | HFOV is a library for calculating field of view in a 2D raster grid, such -- as those found in roguelike games. --@@ -18,7 +19,7 @@ import Foreign.Ptr import Foreign.ForeignPtr -#include "fov.h"+#include "cfov.h" type OpacityTestFn a = Ptr a -> Int -> Int -> IO Bool foreign import ccall "wrapper" mkOpacityTestFn :: OpacityTestFn a -> IO (FunPtr (OpacityTestFn a))@@ -95,8 +96,8 @@ -> (Int -> Int -> IO Bool) -- ^The function to determine the opacity of a certain cell -> IO () circle (Settings fps) (x,y) r apply opaque = withForeignPtr fps $ \s -> do- fov_settings_set_apply_lighting_function s =<< mkApplyFn (\_ x y _ _ _ -> apply x y)- fov_settings_set_opacity_test_function s =<< mkOpacityTestFn (\_ x y -> opaque x y)+ fov_settings_set_apply_lighting_function s =<< mkApplyFn (\_ x' y' _ _ _ -> apply x' y')+ fov_settings_set_opacity_test_function s =<< mkOpacityTestFn (\_ x' y' -> opaque x' y') fov_circle s nullPtr nullPtr x y r -- | Cast a beam.@@ -109,6 +110,6 @@ -> (Int -> Int -> IO Bool) -- ^Opacity test function -> IO () beam (Settings fps) (x,y) r dir angle apply opaque = withForeignPtr fps $ \s -> do- fov_settings_set_apply_lighting_function s =<< mkApplyFn (\_ x y _ _ _ -> apply x y)- fov_settings_set_opacity_test_function s =<< mkOpacityTestFn (\_ x y -> opaque x y)+ fov_settings_set_apply_lighting_function s =<< mkApplyFn (\_ x' y' _ _ _ -> apply x' y')+ fov_settings_set_opacity_test_function s =<< mkOpacityTestFn (\_ x' y' -> opaque x' y') fov_beam s nullPtr nullPtr x y r (rawdirection dir) angle
LICENSE view
@@ -1,20 +1,30 @@-Copyright (c) 2006-2007 Greg McIntyre, 2008 Jeremy Apthorp+Copyright (c) 2013, Jeremy Apthorp+ All rights reserved. -Permission is hereby granted, free of charge, to any person obtaining a copy-of this software and associated documentation files (the "Software"), to deal-in the Software without restriction, including without limitation the rights-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell-copies of the Software, and to permit persons to whom the Software is-furnished to do so, subject to the following conditions:+Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met: -The above copyright notice and this permission notice shall be included in-all copies or substantial portions of the Software.+ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN-THE SOFTWARE.+ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Jeremy Apthorp nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
− Setup.lhs
@@ -1,3 +0,0 @@-#!/usr/bin/env runhaskell-> import Distribution.Simple-> main = defaultMain
+ cfov.c view
@@ -0,0 +1,429 @@+/*+ * Copyright (C) 2006, Greg McIntyre+ * All rights reserved. See the file named COPYING in the distribution+ * for more details.+ */++#include <stdlib.h>+#include <string.h>+#include <stdio.h>+#define __USE_ISOC99 1+#include <math.h>+#include <float.h>+#include <assert.h>+#include "cfov.h"++/*++---++---++---++---++| || || || |+| || || || |+| || || || |++---++---++---++---+ 2++---++---++---+#####+| || || |#####+| || || |#####+| || || |#####++---++---++---+#####X 1 <-- y++---++---++---++---++| || || || |+| @ || || || | <-- srcy centre -> dy = 0.5 = y - 0.5+| || || || |++---++---++---++---+ 0+0 1 2 3 4+ ^ ^+ | |+ srcx x -> dx = 3.5 = x + 0.5+centre++Slope from @ to X.+++---++---++---++---++| || || || |+| || || || |+| || || || |++---++---++---++---+ 2++---++---++---++---++| || || || |+| || || || |+| || || || |++---++---++---+X---+ 1 <-- y++---++---++---+#####+| || || |#####+| @ || || |##### <-- srcy centre -> dy = 0.5 = y - 0.5+| || || |#####++---++---++---+##### 0+0 1 2 3+ ^ ^+ | |+ srcx x -> dx = 2.5 = x - 0.5+centre++Slope from @ to X+*/+++/* Types ---------------------------------------------------------- */++typedef struct {+ /*@observer@*/ fov_settings_type *settings;+ /*@observer@*/ void *map;+ /*@observer@*/ void *source;+ int source_x;+ int source_y;+ unsigned radius;+} fov_private_data_type;++/* Options -------------------------------------------------------- */++void fov_settings_init(fov_settings_type *settings) { + settings->shape = FOV_SHAPE_CIRCLE_PRECALCULATE;+ settings->corner_peek = FOV_CORNER_NOPEEK;+ settings->opaque_apply = FOV_OPAQUE_APPLY;+ settings->opaque = NULL;+ settings->apply = NULL;+ settings->numheights = 0;+}++fov_settings_type *new_fov_settings() {+ fov_settings_type *s = malloc(sizeof(fov_settings_type));+ fov_settings_init(s);+ return s;+}++void fov_settings_set_shape(fov_settings_type *settings,+ fov_shape_type value) { + settings->shape = value;+}++void fov_settings_set_corner_peek(fov_settings_type *settings,+ fov_corner_peek_type value) {+ settings->corner_peek = value;+}++void fov_settings_set_opaque_apply(fov_settings_type *settings,+ fov_opaque_apply_type value) {+ settings->opaque_apply = value;+}++void fov_settings_set_opacity_test_function(fov_settings_type *settings,+ bool (*f)(void *map,+ int x, int y)) {+ settings->opaque = f;+}++void fov_settings_set_apply_lighting_function(fov_settings_type *settings,+ void (*f)(void *map,+ int x, int y,+ int dx, int dy,+ void *src)) {+ settings->apply = f;+}++/* Circular FOV --------------------------------------------------- */++/*@null@*/ static unsigned *precalculate_heights(unsigned maxdist) {+ unsigned i;+ unsigned *result = (unsigned *)malloc((maxdist+2)*sizeof(unsigned));+ if (result) {+ for (i = 0; i <= maxdist; ++i) {+ result[i] = (unsigned)sqrtf((float)(maxdist*maxdist - i*i));+ }+ result[maxdist+1] = 0;+ }+ return result;+}++static unsigned height(fov_settings_type *settings, int x,+ unsigned maxdist) {+ unsigned **newheights;++ if (maxdist > settings->numheights) {+ newheights = (unsigned **)calloc((size_t)maxdist, sizeof(unsigned*));+ if (newheights != NULL) {+ if (settings->heights != NULL && settings->numheights > 0) {+ /* Copy the pointers to the heights arrays we've already+ * calculated. Once copied out, we can free the old+ * array of pointers. */+ memcpy(newheights, settings->heights,+ settings->numheights*sizeof(unsigned*));+ free(settings->heights);+ }+ settings->heights = newheights;+ settings->numheights = maxdist;+ }+ }+ if (settings->heights) {+ if (settings->heights[maxdist-1] == NULL) {+ settings->heights[maxdist-1] = precalculate_heights(maxdist);+ }+ if (settings->heights[maxdist-1] != NULL) {+ return settings->heights[maxdist-1][abs(x)];+ }+ }+ return 0;+}++void fov_settings_free(fov_settings_type *settings) {+ unsigned i;+ if (settings != NULL) {+ if (settings->heights != NULL && settings->numheights > 0) {+ /*@+forloopexec@*/+ for (i = 0; i < settings->numheights; ++i) {+ unsigned *h = settings->heights[i];+ if (h != NULL) {+ free(h);+ }+ settings->heights[i] = NULL;+ }+ /*@=forloopexec@*/+ free(settings->heights);+ settings->heights = NULL;+ settings->numheights = 0;+ }+ }+}++/* Slope ---------------------------------------------------------- */++static float fov_slope(float dx, float dy) {+ if (dx <= -FLT_EPSILON || dx >= FLT_EPSILON) {+ return dy/dx;+ } else {+ return 0.0;+ }+}++/* Octants -------------------------------------------------------- */++#define FOV_DEFINE_OCTANT(signx, signy, rx, ry, nx, ny, nf, apply_edge, apply_diag) \+ static void fov_octant_##nx##ny##nf( \+ fov_private_data_type *data, \+ int dx, \+ float start_slope, \+ float end_slope) { \+ int x, y, dy, dy0, dy1; \+ unsigned h; \+ int prev_blocked = -1; \+ float end_slope_next; \+ fov_settings_type *settings = data->settings; \+ \+ if (dx == 0) { \+ fov_octant_##nx##ny##nf(data, dx+1, start_slope, end_slope); \+ return; \+ } else if ((unsigned)dx > data->radius) { \+ return; \+ } \+ \+ dy0 = (int)(0.5f + ((float)dx)*start_slope); \+ dy1 = (int)(0.5f + ((float)dx)*end_slope); \+ \+ rx = data->source_##rx signx dx; \+ ry = data->source_##ry signy dy0; \+ \+ if (!apply_diag && dy1 == dx) { \+ /* We do diagonal lines on every second octant, so they don't get done twice. */ \+ --dy1; \+ } \+ \+ switch (settings->shape) { \+ case FOV_SHAPE_CIRCLE_PRECALCULATE: \+ h = height(settings, dx, data->radius); \+ break; \+ case FOV_SHAPE_CIRCLE: \+ h = (unsigned)sqrtf((float)(data->radius*data->radius - dx*dx)); \+ break; \+ case FOV_SHAPE_OCTAGON: \+ h = (data->radius - dx)<<1; \+ break; \+ default: \+ h = data->radius; \+ break; \+ }; \+ if ((unsigned)dy1 > h) { \+ if (h == 0) { \+ return; \+ } \+ dy1 = (int)h; \+ } \+ \+ /*fprintf(stderr, "(%2d) = [%2d .. %2d] (%f .. %f), h=%d,edge=%d\n", \+ dx, dy0, dy1, ((float)dx)*start_slope, \+ 0.5f + ((float)dx)*end_slope, h, apply_edge);*/ \+ \+ for (dy = dy0; dy <= dy1; ++dy) { \+ ry = data->source_##ry signy dy; \+ \+ if (settings->opaque(data->map, x, y)) { \+ if (settings->opaque_apply == FOV_OPAQUE_APPLY && (apply_edge || dy > 0)) { \+ settings->apply(data->map, x, y, dx, dy, data->source); \+ } \+ if (prev_blocked == 0) { \+ end_slope_next = fov_slope((float)dx + 0.5f, (float)dy - 0.5f); \+ fov_octant_##nx##ny##nf(data, dx+1, start_slope, end_slope_next); \+ } \+ prev_blocked = 1; \+ } else { \+ if (apply_edge || dy > 0) { \+ settings->apply(data->map, x, y, dx, dy, data->source); \+ } \+ if (prev_blocked == 1) { \+ start_slope = fov_slope((float)dx - 0.5f, (float)dy - 0.5f); \+ } \+ prev_blocked = 0; \+ } \+ } \+ \+ if (prev_blocked == 0) { \+ fov_octant_##nx##ny##nf(data, dx+1, start_slope, end_slope); \+ } \+ }++FOV_DEFINE_OCTANT(+,+,x,y,p,p,n,true,true)+FOV_DEFINE_OCTANT(+,+,y,x,p,p,y,true,false)+FOV_DEFINE_OCTANT(+,-,x,y,p,m,n,false,true)+FOV_DEFINE_OCTANT(+,-,y,x,p,m,y,false,false)+FOV_DEFINE_OCTANT(-,+,x,y,m,p,n,true,true)+FOV_DEFINE_OCTANT(-,+,y,x,m,p,y,true,false)+FOV_DEFINE_OCTANT(-,-,x,y,m,m,n,false,true)+FOV_DEFINE_OCTANT(-,-,y,x,m,m,y,false,false)+++/* Circle --------------------------------------------------------- */++static void _fov_circle(fov_private_data_type *data) {+ /*+ * Octants are defined by (x,y,r) where:+ * x = [p]ositive or [n]egative x increment+ * y = [p]ositive or [n]egative y increment+ * r = [y]es or [n]o for reflecting on axis x = y+ *+ * \pmy|ppy/+ * \ | /+ * \ | /+ * mpn\|/ppn+ * ----@----+ * mmn/|\pmn+ * / | \+ * / | \+ * /mmy|mpy\+ */+ fov_octant_ppn(data, 1, (float)0.0f, (float)1.0f);+ fov_octant_ppy(data, 1, (float)0.0f, (float)1.0f);+ fov_octant_pmn(data, 1, (float)0.0f, (float)1.0f);+ fov_octant_pmy(data, 1, (float)0.0f, (float)1.0f);+ fov_octant_mpn(data, 1, (float)0.0f, (float)1.0f);+ fov_octant_mpy(data, 1, (float)0.0f, (float)1.0f);+ fov_octant_mmn(data, 1, (float)0.0f, (float)1.0f);+ fov_octant_mmy(data, 1, (float)0.0f, (float)1.0f);+}++void fov_circle(fov_settings_type *settings,+ void *map,+ void *source,+ int source_x,+ int source_y,+ unsigned radius) {+ fov_private_data_type data;++ data.settings = settings;+ data.map = map;+ data.source = source;+ data.source_x = source_x;+ data.source_y = source_y;+ data.radius = radius;++ _fov_circle(&data);+}++/**+ * Limit x to the range [a, b].+ */+static float betweenf(float x, float a, float b) {+ if (x - a < FLT_EPSILON) { /* x < a */+ return a;+ } else if (x - b > FLT_EPSILON) { /* x > b */+ return b;+ } else {+ return x;+ }+}++#define BEAM_DIRECTION(d, p1, p2, p3, p4, p5, p6, p7, p8) \+ if (direction == d) { \+ end_slope = betweenf(a, 0.0f, 1.0f); \+ fov_octant_##p1(&data, 1, 0.0f, end_slope); \+ fov_octant_##p2(&data, 1, 0.0f, end_slope); \+ if (a - 1.0f > FLT_EPSILON) { /* a > 1.0f */ \+ start_slope = betweenf(2.0f - a, 0.0f, 1.0f); \+ fov_octant_##p3(&data, 1, start_slope, 1.0f); \+ fov_octant_##p4(&data, 1, start_slope, 1.0f); \+ } \+ if (a - 2.0f > FLT_EPSILON) { /* a > 2.0f */ \+ end_slope = betweenf(a - 2.0f, 0.0f, 1.0f); \+ fov_octant_##p5(&data, 1, 0.0f, end_slope); \+ fov_octant_##p6(&data, 1, 0.0f, end_slope); \+ } \+ if (a - 3.0f > FLT_EPSILON) { /* a > 3.0f */ \+ start_slope = betweenf(4.0f - a, 0.0f, 1.0f); \+ fov_octant_##p7(&data, 1, start_slope, 1.0f); \+ fov_octant_##p8(&data, 1, start_slope, 1.0f); \+ } \+ }++#define BEAM_DIRECTION_DIAG(d, p1, p2, p3, p4, p5, p6, p7, p8) \+ if (direction == d) { \+ start_slope = betweenf(1.0f - a, 0.0f, 1.0f); \+ fov_octant_##p1(&data, 1, start_slope, 1.0f); \+ fov_octant_##p2(&data, 1, start_slope, 1.0f); \+ if (a - 1.0f > FLT_EPSILON) { /* a > 1.0f */ \+ end_slope = betweenf(a - 1.0f, 0.0f, 1.0f); \+ fov_octant_##p3(&data, 1, 0.0f, end_slope); \+ fov_octant_##p4(&data, 1, 0.0f, end_slope); \+ } \+ if (a - 2.0f > FLT_EPSILON) { /* a > 2.0f */ \+ start_slope = betweenf(3.0f - a, 0.0f, 1.0f); \+ fov_octant_##p5(&data, 1, start_slope, 1.0f); \+ fov_octant_##p6(&data, 1, start_slope, 1.0f); \+ } \+ if (a - 3.0f > FLT_EPSILON) { /* a > 3.0f */ \+ end_slope = betweenf(a - 3.0f, 0.0f, 1.0f); \+ fov_octant_##p7(&data, 1, 0.0f, end_slope); \+ fov_octant_##p8(&data, 1, 0.0f, end_slope); \+ } \+ }++void fov_beam(fov_settings_type *settings, void *map, void *source,+ int source_x, int source_y, unsigned radius,+ fov_direction_type direction, float angle) {++ fov_private_data_type data;+ float start_slope, end_slope, a;++ data.settings = settings;+ data.map = map;+ data.source = source;+ data.source_x = source_x;+ data.source_y = source_y;+ data.radius = radius;++ if (angle <= 0.0f) {+ return;+ } else if (angle >= 360.0f) {+ _fov_circle(&data);+ }++ /* Calculate the angle as a percentage of 45 degrees, halved (for+ * each side of the centre of the beam). e.g. angle = 180.0f means+ * half the beam is 90.0 which is 2x45, so the result is 2.0.+ */+ a = angle/90.0f;++ BEAM_DIRECTION(FOV_EAST, ppn, pmn, ppy, mpy, pmy, mmy, mpn, mmn);+ BEAM_DIRECTION(FOV_WEST, mpn, mmn, pmy, mmy, ppy, mpy, ppn, pmn);+ BEAM_DIRECTION(FOV_NORTH, mpy, mmy, mmn, pmn, mpn, ppn, pmy, ppy);+ BEAM_DIRECTION(FOV_SOUTH, pmy, ppy, mpn, ppn, mmn, pmn, mmy, mpy);+ BEAM_DIRECTION_DIAG(FOV_NORTHEAST, pmn, mpy, mmy, ppn, mmn, ppy, mpn, pmy);+ BEAM_DIRECTION_DIAG(FOV_NORTHWEST, mmn, mmy, mpn, mpy, pmy, pmn, ppy, ppn);+ BEAM_DIRECTION_DIAG(FOV_SOUTHEAST, ppn, ppy, pmy, pmn, mpn, mpy, mmn, mmy);+ BEAM_DIRECTION_DIAG(FOV_SOUTHWEST, pmy, mpn, ppy, mmn, ppn, mmy, pmn, mpy);+}
+ cfov.h view
@@ -0,0 +1,238 @@+/*+ * Copyright (C) 2006-2007, Greg McIntyre. All rights reserved. See the file+ * named COPYING in the distribution for more details.+ */++/**+ * \mainpage Field of View Library+ * + * \section about About+ * + * This is a C library which implements a course-grained lighting+ * algorithm suitable for tile-based games such as roguelikes.+ * + * \section copyright Copyright+ * + * \verbinclude COPYING+ * + * \section thanks Thanks+ * + * Thanks to Björn Bergström+ * <bjorn.bergstrom@hyperisland.se> for the algorithm.+ * + */++/**+ * \file fov.h+ * Field-of-view algorithm for dynamically casting light/shadow on a+ * low resolution 2D raster.+ */+#ifndef LIBFOV_HEADER+#define LIBFOV_HEADER++#include <stdbool.h>+#include <stddef.h>++#ifdef __cplusplus+extern "C" {+#endif++/** Eight-way directions. */+typedef enum {+ FOV_EAST = 0,+ FOV_NORTHEAST,+ FOV_NORTH,+ FOV_NORTHWEST,+ FOV_WEST,+ FOV_SOUTHWEST,+ FOV_SOUTH,+ FOV_SOUTHEAST+} fov_direction_type;++/** Values for the shape setting. */+typedef enum {+ FOV_SHAPE_CIRCLE_PRECALCULATE,+ FOV_SHAPE_SQUARE,+ FOV_SHAPE_CIRCLE,+ FOV_SHAPE_OCTAGON+} fov_shape_type;++/** Values for the corner peek setting. */+typedef enum {+ FOV_CORNER_NOPEEK,+ FOV_CORNER_PEEK+} fov_corner_peek_type;++/** Values for the opaque apply setting. */+typedef enum {+ FOV_OPAQUE_APPLY,+ FOV_OPAQUE_NOAPPLY+} fov_opaque_apply_type;++/** @cond INTERNAL */+typedef /*@null@*/ unsigned *height_array_t;+/** @endcond */++typedef struct {+ /** Opacity test callback. */+ /*@null@*/ bool (*opaque)(void *map, int x, int y);++ /** Lighting callback to set lighting on a map tile. */+ /*@null@*/ void (*apply)(void *map, int x, int y, int dx, int dy, void *src);++ /** Shape setting. */+ fov_shape_type shape;+ fov_corner_peek_type corner_peek;+ fov_opaque_apply_type opaque_apply;++ /* Pre-calculated data. */+ /*@null@*/ height_array_t *heights;++ /* Size of pre-calculated data. */+ unsigned numheights;+} fov_settings_type;++/** The opposite direction to that given. */+#define fov_direction_opposite(direction) ((fov_direction_type)(((direction)+4)&0x7))++/**+ * Set all the default options. You must call this option when you+ * create a new settings data structure.+ *+ * These settings are the defaults used:+ *+ * - shape: FOV_SHAPE_CIRCLE_PRECALCULATE+ * - corner_peek: FOV_CORNER_NOPEEK+ * - opaque_apply: FOV_OPAQUE_APPLY+ *+ * Callbacks still need to be set up after calling this function.+ *+ * \param settings Pointer to data structure containing settings.+ */+void fov_settings_init(fov_settings_type *settings);+fov_settings_type *new_fov_settings();++/**+ * Set the shape of the field of view.+ *+ * \param settings Pointer to data structure containing settings.+ * \param value One of the following values, where R is the radius:+ *+ * - FOV_SHAPE_CIRCLE_PRECALCULATE \b (default): Limit the FOV to a+ * circle with radius R by precalculating, which consumes more memory+ * at the rate of 4*(R+2) bytes per R used in calls to fov_circle. + * Each radius is only calculated once so that it can be used again. + * Use fov_free() to free this precalculated data's memory.+ *+ * - FOV_SHAPE_CIRCLE: Limit the FOV to a circle with radius R by+ * calculating on-the-fly.+ *+ * - FOV_SHAPE_OCTOGON: Limit the FOV to an octogon with maximum radius R.+ *+ * - FOV_SHAPE_SQUARE: Limit the FOV to an R*R square.+ */+void fov_settings_set_shape(fov_settings_type *settings, fov_shape_type value);++/**+ * <em>NOT YET IMPLEMENTED</em>.+ *+ * Set whether sources will peek around corners.+ *+ * \param settings Pointer to data structure containing settings.+ * \param value One of the following values:+ *+ * - FOV_CORNER_PEEK \b (default): Renders:+\verbatim+ ........+ ........+ ........+ ..@# + ...# +\endverbatim+ * - FOV_CORNER_NOPEEK: Renders:+\verbatim+ ......+ .....+ ....+ ..@#+ ...#+\endverbatim+ */+void fov_settings_set_corner_peek(fov_settings_type *settings, fov_corner_peek_type value);++/**+ * Whether to call the apply callback on opaque tiles.+ *+ * \param settings Pointer to data structure containing settings.+ * \param value One of the following values:+ *+ * - FOV_OPAQUE_APPLY \b (default): Call apply callback on opaque tiles.+ * - FOV_OPAQUE_NOAPPLY: Do not call the apply callback on opaque tiles.+ */+void fov_settings_set_opaque_apply(fov_settings_type *settings, fov_opaque_apply_type value);++/**+ * Set the function used to test whether a map tile is opaque.+ *+ * \param settings Pointer to data structure containing settings.+ * \param f The function called to test whether a map tile is opaque.+ */+void fov_settings_set_opacity_test_function(fov_settings_type *settings, bool (*f)(void *map, int x, int y));++/**+ * Set the function used to apply lighting to a map tile.+ *+ * \param settings Pointer to data structure containing settings.+ * \param f The function called to apply lighting to a map tile.+ */+void fov_settings_set_apply_lighting_function(fov_settings_type *settings, void (*f)(void *map, int x, int y, int dx, int dy, void *src));++/**+ * Free any memory that may have been cached in the settings+ * structure.+ *+ * \param settings Pointer to data structure containing settings.+ */+void fov_settings_free(fov_settings_type *settings);++/**+ * Calculate a full circle field of view from a source at (x,y).+ *+ * \param settings Pointer to data structure containing settings.+ * \param map Pointer to map data structure to be passed to callbacks.+ * \param source Pointer to data structure holding source of light.+ * \param source_x x-axis coordinate from which to start.+ * \param source_y y-axis coordinate from which to start.+ * \param radius Euclidean distance from (x,y) after which to stop.+ */+void fov_circle(fov_settings_type *settings, void *map, void *source,+ int source_x, int source_y, unsigned radius+);++/**+ * Calculate a field of view from source at (x,y), pointing+ * in the given direction and with the given angle. The larger+ * the angle, the wider, "less focused" the beam. Each side of the+ * line pointing in the direction from the source will be half the+ * angle given such that the angle specified will be represented on+ * the raster.+ *+ * \param settings Pointer to data structure containing settings.+ * \param map Pointer to map data structure to be passed to callbacks.+ * \param source Pointer to data structure holding source of light.+ * \param source_x x-axis coordinate from which to start.+ * \param source_y y-axis coordinate from which to start.+ * \param radius Euclidean distance from (x,y) after which to stop.+ * \param direction One of eight directions the beam of light can point.+ * \param angle The angle at the base of the beam of light, in degrees.+ */+void fov_beam(fov_settings_type *settings, void *map, void *source,+ int source_x, int source_y, unsigned radius,+ fov_direction_type direction, float angle+);++#ifdef __cplusplus+} /* extern "C" */+#endif++#endif
− fov.c
@@ -1,429 +0,0 @@-/*- * Copyright (C) 2006, Greg McIntyre- * All rights reserved. See the file named COPYING in the distribution- * for more details.- */--#include <stdlib.h>-#include <string.h>-#include <stdio.h>-#define __USE_ISOC99 1-#include <math.h>-#include <float.h>-#include <assert.h>-#include "fov.h"--/*-+---++---++---++---+-| || || || |-| || || || |-| || || || |-+---++---++---++---+ 2-+---++---++---+#####-| || || |#####-| || || |#####-| || || |#####-+---++---++---+#####X 1 <-- y-+---++---++---++---+-| || || || |-| @ || || || | <-- srcy centre -> dy = 0.5 = y - 0.5-| || || || |-+---++---++---++---+ 0-0 1 2 3 4- ^ ^- | |- srcx x -> dx = 3.5 = x + 0.5-centre--Slope from @ to X.--+---++---++---++---+-| || || || |-| || || || |-| || || || |-+---++---++---++---+ 2-+---++---++---++---+-| || || || |-| || || || |-| || || || |-+---++---++---+X---+ 1 <-- y-+---++---++---+#####-| || || |#####-| @ || || |##### <-- srcy centre -> dy = 0.5 = y - 0.5-| || || |#####-+---++---++---+##### 0-0 1 2 3- ^ ^- | |- srcx x -> dx = 2.5 = x - 0.5-centre--Slope from @ to X-*/---/* Types ---------------------------------------------------------- */--typedef struct {- /*@observer@*/ fov_settings_type *settings;- /*@observer@*/ void *map;- /*@observer@*/ void *source;- int source_x;- int source_y;- unsigned radius;-} fov_private_data_type;--/* Options -------------------------------------------------------- */--void fov_settings_init(fov_settings_type *settings) { - settings->shape = FOV_SHAPE_CIRCLE_PRECALCULATE;- settings->corner_peek = FOV_CORNER_NOPEEK;- settings->opaque_apply = FOV_OPAQUE_APPLY;- settings->opaque = NULL;- settings->apply = NULL;- settings->numheights = 0;-}--fov_settings_type *new_fov_settings() {- fov_settings_type *s = malloc(sizeof(fov_settings_type));- fov_settings_init(s);- return s;-}--void fov_settings_set_shape(fov_settings_type *settings,- fov_shape_type value) { - settings->shape = value;-}--void fov_settings_set_corner_peek(fov_settings_type *settings,- fov_corner_peek_type value) {- settings->corner_peek = value;-}--void fov_settings_set_opaque_apply(fov_settings_type *settings,- fov_opaque_apply_type value) {- settings->opaque_apply = value;-}--void fov_settings_set_opacity_test_function(fov_settings_type *settings,- bool (*f)(void *map,- int x, int y)) {- settings->opaque = f;-}--void fov_settings_set_apply_lighting_function(fov_settings_type *settings,- void (*f)(void *map,- int x, int y,- int dx, int dy,- void *src)) {- settings->apply = f;-}--/* Circular FOV --------------------------------------------------- */--/*@null@*/ static unsigned *precalculate_heights(unsigned maxdist) {- unsigned i;- unsigned *result = (unsigned *)malloc((maxdist+2)*sizeof(unsigned));- if (result) {- for (i = 0; i <= maxdist; ++i) {- result[i] = (unsigned)sqrtf((float)(maxdist*maxdist - i*i));- }- result[maxdist+1] = 0;- }- return result;-}--static unsigned height(fov_settings_type *settings, int x,- unsigned maxdist) {- unsigned **newheights;-- if (maxdist > settings->numheights) {- newheights = (unsigned **)calloc((size_t)maxdist, sizeof(unsigned*));- if (newheights != NULL) {- if (settings->heights != NULL && settings->numheights > 0) {- /* Copy the pointers to the heights arrays we've already- * calculated. Once copied out, we can free the old- * array of pointers. */- memcpy(newheights, settings->heights,- settings->numheights*sizeof(unsigned*));- free(settings->heights);- }- settings->heights = newheights;- settings->numheights = maxdist;- }- }- if (settings->heights) {- if (settings->heights[maxdist-1] == NULL) {- settings->heights[maxdist-1] = precalculate_heights(maxdist);- }- if (settings->heights[maxdist-1] != NULL) {- return settings->heights[maxdist-1][abs(x)];- }- }- return 0;-}--void fov_settings_free(fov_settings_type *settings) {- unsigned i;- if (settings != NULL) {- if (settings->heights != NULL && settings->numheights > 0) {- /*@+forloopexec@*/- for (i = 0; i < settings->numheights; ++i) {- unsigned *h = settings->heights[i];- if (h != NULL) {- free(h);- }- settings->heights[i] = NULL;- }- /*@=forloopexec@*/- free(settings->heights);- settings->heights = NULL;- settings->numheights = 0;- }- }-}--/* Slope ---------------------------------------------------------- */--static float fov_slope(float dx, float dy) {- if (dx <= -FLT_EPSILON || dx >= FLT_EPSILON) {- return dy/dx;- } else {- return 0.0;- }-}--/* Octants -------------------------------------------------------- */--#define FOV_DEFINE_OCTANT(signx, signy, rx, ry, nx, ny, nf, apply_edge, apply_diag) \- static void fov_octant_##nx##ny##nf( \- fov_private_data_type *data, \- int dx, \- float start_slope, \- float end_slope) { \- int x, y, dy, dy0, dy1; \- unsigned h; \- int prev_blocked = -1; \- float end_slope_next; \- fov_settings_type *settings = data->settings; \- \- if (dx == 0) { \- fov_octant_##nx##ny##nf(data, dx+1, start_slope, end_slope); \- return; \- } else if ((unsigned)dx > data->radius) { \- return; \- } \- \- dy0 = (int)(0.5f + ((float)dx)*start_slope); \- dy1 = (int)(0.5f + ((float)dx)*end_slope); \- \- rx = data->source_##rx signx dx; \- ry = data->source_##ry signy dy0; \- \- if (!apply_diag && dy1 == dx) { \- /* We do diagonal lines on every second octant, so they don't get done twice. */ \- --dy1; \- } \- \- switch (settings->shape) { \- case FOV_SHAPE_CIRCLE_PRECALCULATE: \- h = height(settings, dx, data->radius); \- break; \- case FOV_SHAPE_CIRCLE: \- h = (unsigned)sqrtf((float)(data->radius*data->radius - dx*dx)); \- break; \- case FOV_SHAPE_OCTAGON: \- h = (data->radius - dx)<<1; \- break; \- default: \- h = data->radius; \- break; \- }; \- if ((unsigned)dy1 > h) { \- if (h == 0) { \- return; \- } \- dy1 = (int)h; \- } \- \- /*fprintf(stderr, "(%2d) = [%2d .. %2d] (%f .. %f), h=%d,edge=%d\n", \- dx, dy0, dy1, ((float)dx)*start_slope, \- 0.5f + ((float)dx)*end_slope, h, apply_edge);*/ \- \- for (dy = dy0; dy <= dy1; ++dy) { \- ry = data->source_##ry signy dy; \- \- if (settings->opaque(data->map, x, y)) { \- if (settings->opaque_apply == FOV_OPAQUE_APPLY && (apply_edge || dy > 0)) { \- settings->apply(data->map, x, y, dx, dy, data->source); \- } \- if (prev_blocked == 0) { \- end_slope_next = fov_slope((float)dx + 0.5f, (float)dy - 0.5f); \- fov_octant_##nx##ny##nf(data, dx+1, start_slope, end_slope_next); \- } \- prev_blocked = 1; \- } else { \- if (apply_edge || dy > 0) { \- settings->apply(data->map, x, y, dx, dy, data->source); \- } \- if (prev_blocked == 1) { \- start_slope = fov_slope((float)dx - 0.5f, (float)dy - 0.5f); \- } \- prev_blocked = 0; \- } \- } \- \- if (prev_blocked == 0) { \- fov_octant_##nx##ny##nf(data, dx+1, start_slope, end_slope); \- } \- }--FOV_DEFINE_OCTANT(+,+,x,y,p,p,n,true,true)-FOV_DEFINE_OCTANT(+,+,y,x,p,p,y,true,false)-FOV_DEFINE_OCTANT(+,-,x,y,p,m,n,false,true)-FOV_DEFINE_OCTANT(+,-,y,x,p,m,y,false,false)-FOV_DEFINE_OCTANT(-,+,x,y,m,p,n,true,true)-FOV_DEFINE_OCTANT(-,+,y,x,m,p,y,true,false)-FOV_DEFINE_OCTANT(-,-,x,y,m,m,n,false,true)-FOV_DEFINE_OCTANT(-,-,y,x,m,m,y,false,false)---/* Circle --------------------------------------------------------- */--static void _fov_circle(fov_private_data_type *data) {- /*- * Octants are defined by (x,y,r) where:- * x = [p]ositive or [n]egative x increment- * y = [p]ositive or [n]egative y increment- * r = [y]es or [n]o for reflecting on axis x = y- *- * \pmy|ppy/- * \ | /- * \ | /- * mpn\|/ppn- * ----@----- * mmn/|\pmn- * / | \- * / | \- * /mmy|mpy\- */- fov_octant_ppn(data, 1, (float)0.0f, (float)1.0f);- fov_octant_ppy(data, 1, (float)0.0f, (float)1.0f);- fov_octant_pmn(data, 1, (float)0.0f, (float)1.0f);- fov_octant_pmy(data, 1, (float)0.0f, (float)1.0f);- fov_octant_mpn(data, 1, (float)0.0f, (float)1.0f);- fov_octant_mpy(data, 1, (float)0.0f, (float)1.0f);- fov_octant_mmn(data, 1, (float)0.0f, (float)1.0f);- fov_octant_mmy(data, 1, (float)0.0f, (float)1.0f);-}--void fov_circle(fov_settings_type *settings,- void *map,- void *source,- int source_x,- int source_y,- unsigned radius) {- fov_private_data_type data;-- data.settings = settings;- data.map = map;- data.source = source;- data.source_x = source_x;- data.source_y = source_y;- data.radius = radius;-- _fov_circle(&data);-}--/**- * Limit x to the range [a, b].- */-static float betweenf(float x, float a, float b) {- if (x - a < FLT_EPSILON) { /* x < a */- return a;- } else if (x - b > FLT_EPSILON) { /* x > b */- return b;- } else {- return x;- }-}--#define BEAM_DIRECTION(d, p1, p2, p3, p4, p5, p6, p7, p8) \- if (direction == d) { \- end_slope = betweenf(a, 0.0f, 1.0f); \- fov_octant_##p1(&data, 1, 0.0f, end_slope); \- fov_octant_##p2(&data, 1, 0.0f, end_slope); \- if (a - 1.0f > FLT_EPSILON) { /* a > 1.0f */ \- start_slope = betweenf(2.0f - a, 0.0f, 1.0f); \- fov_octant_##p3(&data, 1, start_slope, 1.0f); \- fov_octant_##p4(&data, 1, start_slope, 1.0f); \- } \- if (a - 2.0f > FLT_EPSILON) { /* a > 2.0f */ \- end_slope = betweenf(a - 2.0f, 0.0f, 1.0f); \- fov_octant_##p5(&data, 1, 0.0f, end_slope); \- fov_octant_##p6(&data, 1, 0.0f, end_slope); \- } \- if (a - 3.0f > FLT_EPSILON) { /* a > 3.0f */ \- start_slope = betweenf(4.0f - a, 0.0f, 1.0f); \- fov_octant_##p7(&data, 1, start_slope, 1.0f); \- fov_octant_##p8(&data, 1, start_slope, 1.0f); \- } \- }--#define BEAM_DIRECTION_DIAG(d, p1, p2, p3, p4, p5, p6, p7, p8) \- if (direction == d) { \- start_slope = betweenf(1.0f - a, 0.0f, 1.0f); \- fov_octant_##p1(&data, 1, start_slope, 1.0f); \- fov_octant_##p2(&data, 1, start_slope, 1.0f); \- if (a - 1.0f > FLT_EPSILON) { /* a > 1.0f */ \- end_slope = betweenf(a - 1.0f, 0.0f, 1.0f); \- fov_octant_##p3(&data, 1, 0.0f, end_slope); \- fov_octant_##p4(&data, 1, 0.0f, end_slope); \- } \- if (a - 2.0f > FLT_EPSILON) { /* a > 2.0f */ \- start_slope = betweenf(3.0f - a, 0.0f, 1.0f); \- fov_octant_##p5(&data, 1, start_slope, 1.0f); \- fov_octant_##p6(&data, 1, start_slope, 1.0f); \- } \- if (a - 3.0f > FLT_EPSILON) { /* a > 3.0f */ \- end_slope = betweenf(a - 3.0f, 0.0f, 1.0f); \- fov_octant_##p7(&data, 1, 0.0f, end_slope); \- fov_octant_##p8(&data, 1, 0.0f, end_slope); \- } \- }--void fov_beam(fov_settings_type *settings, void *map, void *source,- int source_x, int source_y, unsigned radius,- fov_direction_type direction, float angle) {-- fov_private_data_type data;- float start_slope, end_slope, a;-- data.settings = settings;- data.map = map;- data.source = source;- data.source_x = source_x;- data.source_y = source_y;- data.radius = radius;-- if (angle <= 0.0f) {- return;- } else if (angle >= 360.0f) {- _fov_circle(&data);- }-- /* Calculate the angle as a percentage of 45 degrees, halved (for- * each side of the centre of the beam). e.g. angle = 180.0f means- * half the beam is 90.0 which is 2x45, so the result is 2.0.- */- a = angle/90.0f;-- BEAM_DIRECTION(FOV_EAST, ppn, pmn, ppy, mpy, pmy, mmy, mpn, mmn);- BEAM_DIRECTION(FOV_WEST, mpn, mmn, pmy, mmy, ppy, mpy, ppn, pmn);- BEAM_DIRECTION(FOV_NORTH, mpy, mmy, mmn, pmn, mpn, ppn, pmy, ppy);- BEAM_DIRECTION(FOV_SOUTH, pmy, ppy, mpn, ppn, mmn, pmn, mmy, mpy);- BEAM_DIRECTION_DIAG(FOV_NORTHEAST, pmn, mpy, mmy, ppn, mmn, ppy, mpn, pmy);- BEAM_DIRECTION_DIAG(FOV_NORTHWEST, mmn, mmy, mpn, mpy, pmy, pmn, ppy, ppn);- BEAM_DIRECTION_DIAG(FOV_SOUTHEAST, ppn, ppy, pmy, pmn, mpn, mpy, mmn, mmy);- BEAM_DIRECTION_DIAG(FOV_SOUTHWEST, pmy, mpn, ppy, mmn, ppn, mmy, pmn, mpy);-}
− fov.h
@@ -1,238 +0,0 @@-/*- * Copyright (C) 2006-2007, Greg McIntyre. All rights reserved. See the file- * named COPYING in the distribution for more details.- */--/**- * \mainpage Field of View Library- * - * \section about About- * - * This is a C library which implements a course-grained lighting- * algorithm suitable for tile-based games such as roguelikes.- * - * \section copyright Copyright- * - * \verbinclude COPYING- * - * \section thanks Thanks- * - * Thanks to Björn Bergström- * <bjorn.bergstrom@hyperisland.se> for the algorithm.- * - */--/**- * \file fov.h- * Field-of-view algorithm for dynamically casting light/shadow on a- * low resolution 2D raster.- */-#ifndef LIBFOV_HEADER-#define LIBFOV_HEADER--#include <stdbool.h>-#include <stddef.h>--#ifdef __cplusplus-extern "C" {-#endif--/** Eight-way directions. */-typedef enum {- FOV_EAST = 0,- FOV_NORTHEAST,- FOV_NORTH,- FOV_NORTHWEST,- FOV_WEST,- FOV_SOUTHWEST,- FOV_SOUTH,- FOV_SOUTHEAST-} fov_direction_type;--/** Values for the shape setting. */-typedef enum {- FOV_SHAPE_CIRCLE_PRECALCULATE,- FOV_SHAPE_SQUARE,- FOV_SHAPE_CIRCLE,- FOV_SHAPE_OCTAGON-} fov_shape_type;--/** Values for the corner peek setting. */-typedef enum {- FOV_CORNER_NOPEEK,- FOV_CORNER_PEEK-} fov_corner_peek_type;--/** Values for the opaque apply setting. */-typedef enum {- FOV_OPAQUE_APPLY,- FOV_OPAQUE_NOAPPLY-} fov_opaque_apply_type;--/** @cond INTERNAL */-typedef /*@null@*/ unsigned *height_array_t;-/** @endcond */--typedef struct {- /** Opacity test callback. */- /*@null@*/ bool (*opaque)(void *map, int x, int y);-- /** Lighting callback to set lighting on a map tile. */- /*@null@*/ void (*apply)(void *map, int x, int y, int dx, int dy, void *src);-- /** Shape setting. */- fov_shape_type shape;- fov_corner_peek_type corner_peek;- fov_opaque_apply_type opaque_apply;-- /* Pre-calculated data. */- /*@null@*/ height_array_t *heights;-- /* Size of pre-calculated data. */- unsigned numheights;-} fov_settings_type;--/** The opposite direction to that given. */-#define fov_direction_opposite(direction) ((fov_direction_type)(((direction)+4)&0x7))--/**- * Set all the default options. You must call this option when you- * create a new settings data structure.- *- * These settings are the defaults used:- *- * - shape: FOV_SHAPE_CIRCLE_PRECALCULATE- * - corner_peek: FOV_CORNER_NOPEEK- * - opaque_apply: FOV_OPAQUE_APPLY- *- * Callbacks still need to be set up after calling this function.- *- * \param settings Pointer to data structure containing settings.- */-void fov_settings_init(fov_settings_type *settings);-fov_settings_type *new_fov_settings();--/**- * Set the shape of the field of view.- *- * \param settings Pointer to data structure containing settings.- * \param value One of the following values, where R is the radius:- *- * - FOV_SHAPE_CIRCLE_PRECALCULATE \b (default): Limit the FOV to a- * circle with radius R by precalculating, which consumes more memory- * at the rate of 4*(R+2) bytes per R used in calls to fov_circle. - * Each radius is only calculated once so that it can be used again. - * Use fov_free() to free this precalculated data's memory.- *- * - FOV_SHAPE_CIRCLE: Limit the FOV to a circle with radius R by- * calculating on-the-fly.- *- * - FOV_SHAPE_OCTOGON: Limit the FOV to an octogon with maximum radius R.- *- * - FOV_SHAPE_SQUARE: Limit the FOV to an R*R square.- */-void fov_settings_set_shape(fov_settings_type *settings, fov_shape_type value);--/**- * <em>NOT YET IMPLEMENTED</em>.- *- * Set whether sources will peek around corners.- *- * \param settings Pointer to data structure containing settings.- * \param value One of the following values:- *- * - FOV_CORNER_PEEK \b (default): Renders:-\verbatim- ........- ........- ........- ..@# - ...# -\endverbatim- * - FOV_CORNER_NOPEEK: Renders:-\verbatim- ......- .....- ....- ..@#- ...#-\endverbatim- */-void fov_settings_set_corner_peek(fov_settings_type *settings, fov_corner_peek_type value);--/**- * Whether to call the apply callback on opaque tiles.- *- * \param settings Pointer to data structure containing settings.- * \param value One of the following values:- *- * - FOV_OPAQUE_APPLY \b (default): Call apply callback on opaque tiles.- * - FOV_OPAQUE_NOAPPLY: Do not call the apply callback on opaque tiles.- */-void fov_settings_set_opaque_apply(fov_settings_type *settings, fov_opaque_apply_type value);--/**- * Set the function used to test whether a map tile is opaque.- *- * \param settings Pointer to data structure containing settings.- * \param f The function called to test whether a map tile is opaque.- */-void fov_settings_set_opacity_test_function(fov_settings_type *settings, bool (*f)(void *map, int x, int y));--/**- * Set the function used to apply lighting to a map tile.- *- * \param settings Pointer to data structure containing settings.- * \param f The function called to apply lighting to a map tile.- */-void fov_settings_set_apply_lighting_function(fov_settings_type *settings, void (*f)(void *map, int x, int y, int dx, int dy, void *src));--/**- * Free any memory that may have been cached in the settings- * structure.- *- * \param settings Pointer to data structure containing settings.- */-void fov_settings_free(fov_settings_type *settings);--/**- * Calculate a full circle field of view from a source at (x,y).- *- * \param settings Pointer to data structure containing settings.- * \param map Pointer to map data structure to be passed to callbacks.- * \param source Pointer to data structure holding source of light.- * \param source_x x-axis coordinate from which to start.- * \param source_y y-axis coordinate from which to start.- * \param radius Euclidean distance from (x,y) after which to stop.- */-void fov_circle(fov_settings_type *settings, void *map, void *source,- int source_x, int source_y, unsigned radius-);--/**- * Calculate a field of view from source at (x,y), pointing- * in the given direction and with the given angle. The larger- * the angle, the wider, "less focused" the beam. Each side of the- * line pointing in the direction from the source will be half the- * angle given such that the angle specified will be represented on- * the raster.- *- * \param settings Pointer to data structure containing settings.- * \param map Pointer to map data structure to be passed to callbacks.- * \param source Pointer to data structure holding source of light.- * \param source_x x-axis coordinate from which to start.- * \param source_y y-axis coordinate from which to start.- * \param radius Euclidean distance from (x,y) after which to stop.- * \param direction One of eight directions the beam of light can point.- * \param angle The angle at the base of the beam of light, in degrees.- */-void fov_beam(fov_settings_type *settings, void *map, void *source,- int source_x, int source_y, unsigned radius,- fov_direction_type direction, float angle-);--#ifdef __cplusplus-} /* extern "C" */-#endif--#endif
hfov.cabal view
@@ -1,22 +1,70 @@-Name: hfov-Version: 1.0.1-Category: Game-Synopsis: Field-of-view calculation for low-resolution 2D raster grids.-Description: A Haskell binding to a Field of View calculation library+-- Initial hfov.cabal generated by cabal init. For further documentation, +-- see http://haskell.org/cabal/users-guide/++-- The name of the package.+name: hfov++-- The package version. See the Haskell package versioning policy (PVP) +-- for standards guiding when and how versions should be incremented.+-- http://www.haskell.org/haskellwiki/Package_versioning_policy+-- PVP summary: +-+------- breaking API changes+-- | | +----- non-breaking API additions+-- | | | +--- code changes with no API change+version: 1.0.2++-- A short (one-line) description of the package.+synopsis: Field-of-view calculation for low-resolution 2D raster grids.++-- A longer description of the package.+description: A Haskell binding to a Field of View calculation library written by Greg McIntyre (blue_puyo) in C.-Stability: Unstable-License: BSD3-License-file: LICENSE-Author: Jeremy Apthorp <nornagon@nornagon.net>, Greg McIntyre-Maintainer: nornagon@nornagon.net-Build-Depends: base >= 1.0 && < 3-Build-Type: Simple-Tested-with: GHC==6.8.2 -Exposed-Modules: FOV-C-sources: fov.c-Includes: fov.h-Extra-source-files: fov.h-Extensions: CPP, ForeignFunctionInterface-Include-dirs: .-ghc-options: -Wall+-- URL for the project homepage or repository.+homepage: https://github.com/nornagon/hfov++-- The license under which the package is released.+license: BSD3++-- The file containing the license text.+license-file: LICENSE++-- The package author(s).+author: Jeremy Apthorp++-- An email address to which users can send suggestions, bug reports, and +-- patches.+maintainer: nornagon@nornagon.net++-- A copyright notice.+-- copyright: ++category: Game++build-type: Simple++-- Constraint on the version of Cabal needed to build this package.+cabal-version: >=1.8++extra-source-files: cfov.h+source-repository head+ type: git+ location: https://github.com/nornagon/hfov++library+ -- Modules exported by the library.+ exposed-modules: FOV+ c-sources: cfov.c+ includes: cfov.h+ extensions: CPP, ForeignFunctionInterface+ include-dirs: .+ ghc-options: -Wall+ + -- Modules included in this library but not exported.+ -- other-modules: + + -- Other library packages from which modules are imported.+ build-depends: base ==4.6.*+ + -- Extra tools (e.g. alex, hsc2hs, ...) needed to build the source.+ build-tools: hsc2hs+