packages feed

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 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&ouml;rn Bergstr&ouml;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&ouml;rn Bergstr&ouml;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+