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

[Freeciv-Dev] Re: (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] Re: (PR#12214) generating unit selection animation frames
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 11 Feb 2005 08:38:38 -0800
Reply-to: bugs@xxxxxxxxxxx

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

Jason Short wrote:
> <URL: http://bugs.freeciv.org/Ticket/Display.html?id=12214 >
> 
> Many people have had the idea of using a spinning circle underneath the 
> focus unit to show the focus (rather than the blinking unit).
> 
> This program generates such a circle.  It uses no alpha levels (with 
> alpha it could be a bit prettier).  It generates 4 frames of a 6-dashed 
> circle.  I haven't played with the parameters much but attached are 
> trident and isotrident versions of the graphics.

Here's a new program that will optionally generate squares.  Attached is 
the squares for trident.

It's a bit ugly since all the math is still done in polar coordinates. 
This could be improved.

-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.5;
    double max_r2 = (WH / 2) * (WH / 2) * 0.9;

    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;
}

PNG image


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