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