Move all other sources in a separate subfolder
[voretournament/voretournament.git] / misc / tools / hitplot2tga.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdint.h>
4 #include <string.h>
5 #include <math.h>
6 #include <stdarg.h>
7 #include <errno.h>
8
9 void err(int ex, const char *fmt, ...)
10 {
11         va_list list;
12         int e = errno;
13         va_start(list, fmt);
14         vfprintf(stderr, fmt, list);
15         fputs(": ", stderr);
16         fputs(strerror(e), stderr);
17         fputs("\n", stderr);
18         exit(ex);
19 }
20
21 void errx(int ex, const char *fmt, ...)
22 {
23     va_list list;
24     va_start(list, fmt);
25     vfprintf(stderr, fmt, list);
26     fputs("\n", stderr);
27     exit(ex);
28 }
29
30 typedef void (*colorfunc_t) (double x, double y, double dx, double dy, double *r, double *g, double *b);
31
32 double rnd()
33 {
34         return rand() / (RAND_MAX + 1.0);
35 }
36
37 double softclip(double x, double a)
38 {
39         // don't ask what this does - but it works
40         double cse = (2*a*x - x - a + 1) * x;
41         return cse / (cse + (1 - a));
42 }
43
44 void writepic(colorfunc_t f, const char *fn, int width, int height)
45 {
46         int x, y;
47         uint8_t tga[18];
48
49         FILE *file = fopen(fn, "wb");
50         if(!file)
51                 err(1, "fopen >%s", fn);
52
53         memset(tga, 0, sizeof(tga));
54         tga[2] = 2;          // uncompressed type
55         tga[12] = (width >> 0) & 0xFF;
56         tga[13] = (width >> 8) & 0xFF;
57         tga[14] = (height >> 0) & 0xFF;
58         tga[15] = (height >> 8) & 0xFF;
59         tga[16] = 24;        // pixel size
60
61         if(fwrite(&tga, sizeof(tga), 1, file) != 1)
62                 err(1, "fwrite >%s", fn);
63         //for(y = height-1; y >= 0; --y)
64         for(y = 0; y < height; ++y)
65                 for(x = 0; x < width; ++x)
66                 {
67                         uint8_t rgb[3];
68                         double rr, gg, bb;
69                         double xx, yy;
70                         xx = (x + 0.5) / width;
71                         yy = (y + 0.5) / height;
72                         f(xx, yy, 0.5 / width, 0.5 / height, &rr, &gg, &bb);
73                         rgb[2] = floor(rnd() + rr * 255);
74                         rgb[1] = floor(rnd() + gg * 255);
75                         rgb[0] = floor(rnd() + bb * 255);
76                         if(fwrite(rgb, sizeof(rgb), 1, file) != 1)
77                                 err(1, "fwrite >%s", fn);
78                 }
79         
80         fclose(file);
81 }
82
83 typedef struct
84
85         double x, y, dist;
86         int weapon;
87 }
88 plotpoint_t;
89
90 plotpoint_t *plotpoints;
91 size_t nPlotpoints, allocatedPlotpoints;
92
93 void readpoints(const char *fn)
94 {
95         char buf[1024];
96
97         FILE *infile = fopen(fn, "r");
98         if(!infile)
99                 err(1, "fopen <%s", fn);
100
101         nPlotpoints = allocatedPlotpoints = 0;
102         plotpoints = NULL;
103
104         while(fgets(buf, sizeof(buf), infile))
105         {
106                 if(*buf == '#') 
107                 {
108                         fputs(buf + 1, stdout);
109                         continue;
110                 }
111                 if(nPlotpoints >= allocatedPlotpoints)
112                 {
113                         if(allocatedPlotpoints == 0)
114                                 allocatedPlotpoints = 1024;
115                         else
116                                 allocatedPlotpoints = nPlotpoints * 2;
117                         plotpoints = (plotpoint_t *) realloc(plotpoints, allocatedPlotpoints * sizeof(*plotpoints));
118                 }
119                 if(sscanf(buf, "%lf %lf %lf %d", &plotpoints[nPlotpoints].x, &plotpoints[nPlotpoints].y, &plotpoints[nPlotpoints].dist, &plotpoints[nPlotpoints].weapon) != 4)
120                         continue;
121                 ++nPlotpoints;
122         }
123 }
124
125 void calcplot1(double x, double y, double *out, double sigma2)
126 {
127         size_t i;
128         double dist2;
129         double val, totalval = 0, weight, totalweight = 0;
130
131         for(i = 0; i < nPlotpoints; ++i)
132         {
133                 dist2 = (x - plotpoints[i].x) * (x - plotpoints[i].x) + (y - plotpoints[i].y) * (y - plotpoints[i].y);
134                 weight = 1; // / plotpoints[i].dist;
135                 val = exp(-dist2 / sigma2);
136
137                 totalweight += weight;
138                 totalval += weight * val;
139         }
140
141         *out = softclip(totalval / (totalweight * sqrt(sigma2 * 2 * M_PI)), 0.8);
142 }
143
144 void calcplotp(double x, double y, double dx, double dy, double *out)
145 {
146         size_t i;
147         double distx, disty;
148
149         for(i = 0; i < nPlotpoints; ++i)
150         {
151                 distx = x - plotpoints[i].x;
152                 disty = y - plotpoints[i].y;
153
154                 if(distx < dx)
155                 if(distx > -dx)
156                 if(disty < dy)
157                 if(disty > -dy)
158                 {
159                         *out = 1;
160                         break;
161                 }
162         }
163 }
164
165 void calcplot(double x, double y, double dx, double dy, double *r, double *g, double *b)
166 {
167         calcplot1(x, y, r, 1/64.0);
168         calcplot1(x, y, g, 1/512.0);
169         calcplot1(x, y, b, 1/4096.0);
170         calcplotp(x, y, dx, dy, b);
171 }
172
173 int main(int argc, char **argv)
174 {
175         if(argc != 3)
176                 errx(1, "Usage: %s infile.plot outfile.tga", *argv);
177         
178         readpoints(argv[1]);
179         writepic(calcplot, argv[2], 512, 512);
180
181         return 0;
182 }