Logo Search packages:      
Sourcecode: lebiniou version File versions  Download package

translation.c

/*
 *  Copyright 1994-2011 Olivier Girondel
 *
 *  This file is part of lebiniou.
 *
 *  lebiniou is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  lebiniou is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with lebiniou. If not, see <http://www.gnu.org/licenses/>.
 */

#include "translation.h"

#define BATCH_LINES 20   /* lines per turn */
#define FADE_STEPS  50.0 /* fade stuff */


static void
Translation_build(Translation_t *t)
{
  u_short i, j;
  M_wPoint_t *wp = t->point;

  for (j = 0; j < HEIGHT; j++)
    for (i = 0; i < WIDTH; i++) {
      wp->x = i;
      wp->y = j;
      wp->dx = 0;
      wp->dy = 0;
      wp++;
    }
}


Translation_t *
Translation_new(Map_t(*f)(const u_short, const u_short), void (*init)())
{
  Translation_t *t = NULL;

  assert(init != NULL);

  t = xcalloc(1, sizeof(Translation_t));
  t->f = f;
  t->point = xcalloc(BUFFSIZE, sizeof(M_wPoint_t));
  t->line = t->fading = 0;
  t->init = init;

  Translation_build(t);
  (*init)();

  return t;
}


static void
Translation_init_fade(Translation_t *t)
{
  t->fading = FADE_STEPS;
}


static void
Translation_idle(const Translation_t *t, const Context_t *ctx)
{
  const Buffer8_t *src = active_buffer(ctx);
  Buffer8_t *dst = passive_buffer(ctx);
  M_wPoint_t *p = t->point;
  u_short i, j;

  /* printf("Translation_idle\n"); */

  for (j = 0; j < HEIGHT; j++)
    for (i = 0; i < WIDTH; i++) {
      set_pixel_nc(dst, i, j,
               get_pixel_nc(src,
                        (u_short)p[j*WIDTH+i].x,
                        (u_short)p[j*WIDTH+i].y));
    }
}


static void
Translation_fade(Translation_t *t, const Context_t *ctx)
{
  const Buffer8_t *src = active_buffer(ctx);
  Buffer8_t *dst = passive_buffer(ctx);
  M_wPoint_t *p = t->point;
  u_short i, j;

  /* printf("Translation_fade\n"); */
      
  for (j = 0; j < HEIGHT; j++)
    for (i = 0; i < WIDTH; i++) {
      p[j*WIDTH+i].x += p[j*WIDTH+i].dx;
      p[j*WIDTH+i].y += p[j*WIDTH+i].dy;
      /* FIXME using get_pixel_nc here causes a segfault when compiled
       with --disable-sanity-checks */
      set_pixel_nc(dst, i, j, get_pixel_nc(src,
                                 (u_short)p[j*WIDTH+i].x,
                                 (u_short)p[j*WIDTH+i].y));
    }
      
  --t->fading;
}


void
Translation_compute(Translation_t *t)
{
  u_short k;

  assert(t != NULL);
  for (k = 0; (k < BATCH_LINES) && !Translation_batch_done(t); k++)
    if (Translation_batch_line(t))
      return;
}


int
Translation_run(Translation_t *t, const Context_t *ctx)
{
  if (!Translation_batch_done(t))
    Translation_compute(t);
      
  if (t->fading)
    Translation_fade(t, ctx);
  else
    Translation_idle(t, ctx);
      
  return t->fading;
}


void
Translation_delete(Translation_t *t)
{
  xfree(t->point);
  xfree(t);
}


void
Translation_batch_init(Translation_t *t)
{
  t->line = t->fading = 0;
  (*t->init)();
  Translation_build(t);
}


u_char
Translation_batch_line(Translation_t *t)
{
  u_short i;
  M_wPoint_t *wp = &t->point[t->line * WIDTH];

  for (i = 0; i < WIDTH; i++) {
    Map_t m = t->f(wp->x, wp->y);
    wp->dx = (float)((float)m.map_x - (float)wp->x) / FADE_STEPS;
    wp->dy = (float)((float)m.map_y - (float)wp->y) / FADE_STEPS;
    wp++;
  }
  
  if (++t->line == HEIGHT) {
    Translation_init_fade(t);
    return 1;
  } else
    return 0;
}


u_char
Translation_batch_done(const Translation_t *t)
{
  return (t->line == HEIGHT);
}

Generated by  Doxygen 1.6.0   Back to index