File Coverage

lib/Game/RaycastFOV.xs
Criterion Covered Total %
statement 72 72 100.0
branch 64 100 64.0
condition n/a
subroutine n/a
pod n/a
total 136 172 79.0


line stmt bran cond sub pod time code
1             #define PERL_NO_GET_CONTEXT
2              
3             #include "EXTERN.h"
4             #include "perl.h"
5             #include "XSUB.h"
6              
7             #include "ppport.h"
8              
9             #define CALLTWOUP \
10             ENTER; \
11             SAVETMPS; \
12             PUSHMARK(SP); \
13             EXTEND(SP, 2)
14             #define TWOUPDONE \
15             FREETMPS; \
16             LEAVE
17             #define CIRCLECB(x, y) \
18             PUSHMARK(SP); \
19             EXTEND(SP, 2); \
20             mPUSHs(newSViv(x)); \
21             mPUSHs(newSViv(y)); \
22             PUTBACK; \
23             call_sv(callback, G_DISCARD); \
24             SPAGAIN
25              
26             MODULE = Game::RaycastFOV PACKAGE = Game::RaycastFOV
27             PROTOTYPES: ENABLE
28              
29             void
30             bypair (callback, ...)
31             SV *callback;
32             PREINIT:
33             int answer, i;
34             SV *x, *y;
35             PROTOTYPE: &@
36             PPCODE:
37 6 100         if (!(items & 1)) croak("uneven number of arguments");
38             dSP;
39 9 100         for (i = 1; i < items; i += 2) {
40 5           x = ST(i);
41 5           y = ST(i + 1);
42 5 50         CALLTWOUP;
    50          
43 5           PUSHs(x);
44 5           PUSHs(y);
45 5           PUTBACK;
46 5           call_sv(callback, G_SCALAR);
47 5           SPAGAIN;
48 5 50         answer = POPi;
49 5 50         TWOUPDONE;
50 5 100         if (answer == -1) break;
51             }
52              
53             void
54             bypairall (callback, ...)
55             SV *callback;
56             PREINIT:
57             int i;
58             SV *x, *y;
59             PROTOTYPE: &@
60             PPCODE:
61 5 100         if (!(items & 1)) croak("uneven number of arguments");
62             dSP;
63 47 100         for (i = 1; i < items; i += 2) {
64 43           x = ST(i);
65 43           y = ST(i + 1);
66 43 50         CALLTWOUP;
    50          
67 43           PUSHs(x);
68 43           PUSHs(y);
69 43           PUTBACK;
70 43           call_sv(callback, G_DISCARD);
71 43           SPAGAIN;
72 43 50         TWOUPDONE;
73             }
74              
75             void
76             circle(callback, int x0, int y0, int radius)
77             SV *callback;
78             PREINIT:
79             int f, ddF_x, ddF_y, x, y;
80             PROTOTYPE: &$$$
81             PPCODE:
82 4           dSP;
83 4           ENTER;
84 4           SAVETMPS;
85 4           f = 1 - radius;
86             ddF_x = 0;
87 4           ddF_y = -2 * radius;
88             x = 0;
89             y = radius;
90 4 50         CIRCLECB(x0, y0 + radius);
    50          
91 4 50         CIRCLECB(x0, y0 - radius);
    50          
92 4 50         CIRCLECB(x0 + radius, y0);
    50          
93 4 50         CIRCLECB(x0 - radius, y0);
    50          
94 9 100         while (x < y) {
95 5 100         if (f >= 0) {
96 4           y--;
97 4           ddF_y += 2;
98 4           f += ddF_y;
99             }
100 5           x++;
101 5           ddF_x += 2;
102 5           f += ddF_x + 1;
103 5 50         CIRCLECB(x0 + x, y0 + y);
    50          
104 5 50         CIRCLECB(x0 - x, y0 + y);
    50          
105 5 50         CIRCLECB(x0 + x, y0 - y);
    50          
106 5 50         CIRCLECB(x0 - x, y0 - y);
    50          
107 5 50         CIRCLECB(x0 + y, y0 + x);
    50          
108 5 50         CIRCLECB(x0 - y, y0 + x);
    50          
109 5 50         CIRCLECB(x0 + y, y0 - x);
    50          
110 5 50         CIRCLECB(x0 - y, y0 - x);
    50          
111             }
112 4 50         FREETMPS;
113 4           LEAVE;
114              
115             void
116             line (callback, int x0, int y0, int x1, int y1)
117             SV *callback;
118             PREINIT:
119             int answer, dx, dy, err, e2, sx, sy;
120             PROTOTYPE: &$$$$
121             PPCODE:
122 59           dSP;
123 59           dx = abs(x1 - x0);
124 59           dy = abs(y1 - y0);
125 59 100         sx = x0 < x1 ? 1 : -1;
126 59 100         sy = y0 < y1 ? 1 : -1;
127 144 100         err = (dx > dy ? dx : -dy) / 2;
128             while (1) {
129 144 50         CALLTWOUP;
    50          
130 144           mPUSHs(newSViv(x0));
131 144           mPUSHs(newSViv(y0));
132 144           PUTBACK;
133 144           call_sv(callback, G_SCALAR);
134 144           SPAGAIN;
135 144 50         answer = POPi;
136 144 50         TWOUPDONE;
137 144 100         if (answer == -1 || (x0 == x1 && y0 == y1)) break;
    100          
138             e2 = err;
139 85 100         if (e2 > -dx) {
140 57           err -= dy;
141 57           x0 += sx;
142             }
143 85 100         if (e2 < dy) {
144 56           err += dx;
145 56           y0 += sy;
146             }
147             }