foo
[gbajam22] / tools / vistab.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <math.h>
4
5 #define NUM_DIRS        8
6 #define MAX_DIST        4
7 #define FOV                     92
8
9 struct cell {
10         int dx, dy;
11 };
12
13 void calc_vis(int dir);
14 int is_visible(float x, float y, float dir);
15
16 int main(void)
17 {
18         int i;
19
20         printf("struct {int dx, dy;} visoffs[%d][32] = {\n", NUM_DIRS);
21
22         for(i=0; i<NUM_DIRS; i++) {
23
24                 printf("\t/* dir %d */\n", i);
25                 calc_vis(i);
26         }
27
28         printf("};\n");
29         return 0;
30 }
31
32 int cellcmp(const void *a, const void *b)
33 {
34         const struct cell *ca = a;
35         const struct cell *cb = b;
36         int za = ca->dx * ca->dx + ca->dy * ca->dy;
37         int zb = cb->dx * cb->dx + cb->dy * cb->dy;
38         return zb - za;
39 }
40
41 void calc_vis(int dir)
42 {
43         int i, j, count, col;
44         struct cell vis[512];
45         int x, y;
46         float theta = (float)(dir + 2) / NUM_DIRS * M_PI * 2.0f;
47
48         fprintf(stderr, "DIR: %d (angle: %g)\n", dir, theta * 180.0f / M_PI);
49         count = 0;
50         for(i=0; i<MAX_DIST*2+1; i++) {
51                 y = i - MAX_DIST;
52                 for(j=0; j<MAX_DIST*2+1; j++) {
53                         x = j - MAX_DIST;
54
55                         if(is_visible(x, y, theta)) {
56                                 vis[count].dx = x;
57                                 vis[count].dy = y;
58                                 count++;
59
60                                 fputc('#', stderr);
61                         } else {
62                                 fputc('.', stderr);
63                         }
64                 }
65                 fputc('\n', stderr);
66         }
67         fputc('\n', stderr);
68
69         qsort(vis, count, sizeof *vis, cellcmp);
70
71         printf("\t{");
72         col = 5;
73         for(i=0; i<count; i++) {
74                 col += printf("{%d,%d}", vis[i].dx, vis[i].dy);
75                 if(i < count - 1) {
76                         if(col > 72) {
77                                 fputs(",\n\t ", stdout);
78                                 col = 5;
79                         } else {
80                                 fputs(", ", stdout);
81                                 col += 2;
82                         }
83                 }
84         }
85         fputs(dir < NUM_DIRS - 1 ? "},\n" : "}\n", stdout);
86 }
87
88 #define RAD 1.42
89
90 float ptlinedist(float x, float y, float dir)
91 {
92         return -y * cos(dir) + sin(dir) * x;
93 }
94
95 int is_visible(float x, float y, float dir)
96 {
97         static const char voffs[][2] = {{-0.5, -0.5}, {0.5, -0.5}, {0.5, 0.5}, {-0.5, 0.5}};
98         float d0, d1;
99         int i;
100         float hfov = 0.5f * FOV * M_PI / 180.0f;
101
102         d0 = ptlinedist(x, y, dir - hfov);
103         d1 = ptlinedist(x, y, dir + hfov);
104         if(d0 >= 0 && d1 <= 0) {
105                 return 1;
106         }
107
108         for(i=0; i<4; i++) {
109                 d0 = ptlinedist(x + voffs[i][0], y + voffs[i][1], dir - hfov);
110                 d1 = ptlinedist(x + voffs[i][0], y + voffs[i][1], dir + hfov);
111
112                 if(d0 >= 0 && d1 <= 0) {
113                         return 1;
114                 }
115         }
116         return 0;
117 }