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 
err(int ex,const char * fmt,...)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 
errx(int ex,const char * fmt,...)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 
rnd()32 double rnd()
33 {
34 	return rand() / (RAND_MAX + 1.0);
35 }
36 
softclip(double x,double a)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 
writepic(colorfunc_t f,const char * fn,int width,int height)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 
readpoints(const char * fn)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 
calcplot1(double x,double y,double * out,double sigma2)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 
calcplotp(double x,double y,double dx,double dy,double * out)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 
calcplot(double x,double y,double dx,double dy,double * r,double * g,double * b)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 
main(int argc,char ** argv)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 }
183