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

hodge.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 "context.h"


u_long id = 1184941398;
u_long options = BE_DISPLACE|BE_LENS;
char dname[] = "Hodge";
u_long mode = XOR;
char desc[] = "Cellular automaton";

/*
 * Based on:
 * http://www.fourmilab.ch/cellab/manual/rules.html#Hodge
 */

#define B    5
#define N    ((1 << B) - 1)
#define SHFT (8*sizeof(Pixel_t) - B)
#define G    5


static Buffer8_t *game[2] = { NULL, NULL };
static u_char initialized = 0;


void
create(__attribute__ ((unused)) Context_t *ctx)
{
  game[0] = Buffer8_new();
  game[1] = Buffer8_new();
}


void
destroy(__attribute__ ((unused)) Context_t *ctx)
{
  Buffer8_delete(game[0]);
  Buffer8_delete(game[1]);
}


void
on_switch_on(Context_t *ctx)
{
  Pixel_t *p;

  if (initialized)
    return;

  if (b_rand_boolean())
    Buffer8_copy(active_buffer(ctx), game[0]);
  else
    Buffer8_randomize(game[0]);

  for (p = game[0]->buffer; p < (game[0]->buffer + BUFFSIZE*sizeof(Pixel_t)); p++)
    *p &= N;

  initialized = 1;
}


static inline Pixel_t
five_bits(const Buffer8_t *buff, const int x, const int y)
{
  const Pixel_t p = get_pixel_nc(buff, x, y);

  return (p & N);
}


static inline u_short
sum(const Buffer8_t *buff, const int x, const int y)
{
  u_short s = 0;
  int dx, dy;

  for (dy = -1; dy <= 1; dy++)
    for (dx = -1; dx <= 1; dx++) {
      if (!dx && !dy)
      continue;
      else
      s += get_pixel_nc(buff, x+dx, y+dy);
    }

  return s;
}


void
run(Context_t *ctx)
{
  /* Quick version, no pointers. Left as an exercise
   * to the reader :)
   */
  int x, y;
  Buffer8_t *tmp, *dst;

  dst = passive_buffer(ctx);

#define game_src game[0]
#define game_dst game[1]

  for (y = 1; y < MAXY; y++)
    for (x = 1; x < MAXX; x++) {
      const Pixel_t old = five_bits(game_src, x, y);
      Pixel_t new;

      if (old == N)
      new = 0;
      else {
      const u_short s = sum(game_src, x, y);
      assert(old < N);
      new = ((s >> SHFT) + G) & 255;
      if (new > N)
        new = N;
      }

      set_pixel_nc(game_dst, x, y, new);
      set_pixel_nc(dst, x, y, new);
    }

  tmp = game[0];
  game[0] = game[1];
  game[1] = tmp;
}

Generated by  Doxygen 1.6.0   Back to index