[Freeciv-Dev] (PR#12214) generating unit selection animation frames
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=12214 >
And here is the final program that I used.
-jason
/* By Jason Dorje Short. Distributed under the GPL. */
/* Compile as
gcc -Wall -g `pkg-config --cflags --libs gtk+-2.0` select.c -o select
*/
#include <assert.h>
#include <stdlib.h>
#include <math.h>
#include <gtk/gtk.h>
#define FRAMES 4
#define SEGMENTS 6
#define PI 3.14159265359
/* Return the angle, on the scale of 0..1 */
double get_angle(double x, double y)
{
if (x == 0.0) {
if (y >= 0.0) {
return 0.25;
} else {
return 0.75;
}
}
return atan(y / x) / (2 * PI);
}
int main(int argc, char **argv)
{
GdkPixbuf *fog;
int W, H, WH, i;
char *filename;
int iso;
if (argc < 4) {
printf("Usage: %s <width> <height> <output PNG>\n", argv[0]);
printf("\n");
printf("Give this program a tile size and filename and it will create\n");
printf("a set of 4 selected-unit sprites.\n");
exit(1);
}
W = atoi(argv[1]);
H = atoi(argv[2]);
WH = W * H;
filename = argv[3];
printf("Converting %d x %d sprites in %s.\n", W, H, filename);
if (W != H) {
iso = 1;
assert(W == 2 * H);
} else {
iso = 0;
}
gtk_init(&argc, &argv);
fog = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, W * FRAMES, H);
for (i = 0; i < FRAMES; i++) {
int x, y;
const int x0 = i * W, y0 = 0;
double min_r2 = (WH / 2) * (WH / 2) * 0.7;
double max_r2 = (WH / 2) * (WH / 2) * 1.0;
for (x = 0; x < W; x++) {
for (y = 0; y < H; y++) {
const long long tx = x - (iso ? (W / 2) : 0);
const long long ty = y;
/* Transformed X/Y values. */
const long long mx = iso ? (tx * H + ty * W) : tx * H;
const long long my = iso ? (ty * W - tx * H) : ty * W;
/* Pixbuf X/Y values. */
const int px = x + x0;
const int py = y + y0;
guchar *pixel = gdk_pixbuf_get_pixels(fog)
+ py * gdk_pixbuf_get_rowstride(fog)
+ px * gdk_pixbuf_get_n_channels(fog);
double rx = (mx - WH / 2), ry = (my - WH / 2);
double r2 = rx * rx + ry * ry;
double angle = get_angle(rx, ry) + 10000.0;
int circle = iso; /* Otherwise square. */
angle += (double) i / (double)(FRAMES * SEGMENTS);
assert(angle >= 0.0); /* otherwise we get rounding errors */
pixel[0] = pixel[1] = pixel[2] = 255;
if (mx < 0 || my < 0 || mx >= WH || my >= WH) {
pixel[3] = 0;
continue;
}
if (((circle && r2 >= min_r2 && r2 < max_r2)
|| (!circle && (ABS(rx) > WH * 0.4 || ABS(ry) > WH * 0.4)))
&& (int)(angle * SEGMENTS * 2) % 2 == 0) {
pixel[3] = 255;
} else {
pixel[3] = 0;
}
}
}
}
gdk_pixbuf_save(fog, filename, "png", NULL, NULL);
return 0;
}
|
|