Complete.Org: Mailing Lists: Archives: freeciv-dev: February 2005:
[Freeciv-Dev] (PR#12214) generating unit selection animation frames
Home

[Freeciv-Dev] (PR#12214) generating unit selection animation frames

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#12214) generating unit selection animation frames
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Sun, 13 Feb 2005 11:46:32 -0800
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=12214 >

And this one supports alpha levels through multi-sampling.  Change the
alpha_sampling value to something like 16 to get good results.

-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, i;
  char *filename;
  int iso;

  const int alpha_sampling = 1, S = alpha_sampling;

  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]);
  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, xa, ya;
    const int x0 = i * W, y0 = 0;

    for (x = 0; x < W; x++) {
      for (y = 0; y < H; y++) {
        int count = 0;

        /* 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);

        for (xa = 0; xa < S; xa++) {
          for (ya = 0; ya < S; ya++) {
            const double WS = W * S;
            // const double HS = H * S;

            const int xb = x * S + xa;
            const int yb = y * S + ya;

            const double tx = xb - (iso ? (WS / 2.0) : 0);
            const double ty = yb;

            /* Transformed X/Y values. */
            const double mx = iso ? (tx + ty * 2.0) : tx;
            const double my = iso ? (ty * 2.0 - tx) : ty;

            const double center = (WS - (double)S) / 2.0;
            const double rx = mx - center;
            const double ry = my - center;

            const double min_r2 = center * center * 0.7;
            const double max_r2 = center * center * 1.0;

            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 */

            if (((circle && r2 >= min_r2 && r2 < max_r2)
                 || (!circle && (ABS(rx) > WS * 0.4 || ABS(ry) > WS * 0.4)))
                && (int)(angle * SEGMENTS * 2) % 2 == 0) {
              count++;
            }
          }
        }

        pixel[0] = pixel[1] = pixel[2] = 255;
        pixel[3] = 255 * count / (S * S);
      }
    }
  }

  

  gdk_pixbuf_save(fog, filename, "png", NULL, NULL);
  return 0;
}

[Prev in Thread] Current Thread [Next in Thread]