Example #1
0
void life_frame(void) {
    int x, y;
    uint8_t sub_frame = life_frame_num++ & 0x1f;
    static bool reset_next = false;

    if (sub_frame == 0) {
        if (reset_next) {
            life_init();
            reset_next = false;
        }
        for (y = 0; y < HEIGHT; y++) {
            for (x = 0; x < WIDTH; x++) {
                bool alive = life_is_alive(x, y);
                uint8_t age = life_get_age(x, y);
                int neighbors = life_calc_neighbors(x, y);

                // Life rules from:
                //     https://en.wikipedia.org/wiki/Conway%27s_Game_of_Life
                // 1. Any live cell with fewer than two live neighbours dies, as if
                //    caused by under-population.
                // 2. Any live cell with two or three live neighbours lives on to
                //    the next generation.
                // 3. Any live cell with more than three live neighbours dies, as
                //    if by over-population.
                // 4. Any dead cell with exactly three live neighbours becomes a
                //    live cell, as if by reproduction.
                if (alive) {
                    if (neighbors == 2 || neighbors == 3) {
                        life_set(x, y, true, age < 0xff ? age + 1 : age);
                    } else {
                        life_set(x, y, false, 0);
                    }
                } else {
                    if (neighbors == 3) {
                        life_set(x, y, true, 0);
                    } else {
                        life_set(x, y, false, 0);
                    }
                }
            }
        }
        if (!memcmp(life_alive, life_new_alive, sizeof(life_alive))
            || !memcmp(life_last_alive, life_new_alive, sizeof(life_alive))) {
            reset_next = true;
        }
        memcpy(life_last_alive, life_alive, sizeof(life_alive));
        memcpy(life_alive, life_new_alive, sizeof(life_alive));
    }

    for (y = 0; y < HEIGHT; y++) {
        for (x = 0; x < WIDTH; x++) {
            uint32_t color;
            if (life_is_alive(x, y)) {
                int age = life_get_age(x, y);
                uint32_t index = hsv_inc(life_color_index, age * 0x20 * 4);
                color = hsv_pixel(index);
            } else {
                color = matrix_color(0, 0x00, 0x00);
            }
            matrix_set_pixel(x, y, color);
        }
    }
    life_color_index = hsv_inc(life_color_index, 4);
}
Example #2
0
/**
 * Perform an animated wipe left-to-right or right-to-left.
 */
static void wipe(uint8_t stage)
{
  uint8_t  last_tick;
  uint8_t  x, y;
  uint8_t  byte, bit;
  uint8_t  index, mask;
  matrix_color_t color;

  for (tick = 0, last_tick = 255; tick < MATRIX_WIDTH;)
  {
    if (last_tick == tick)
      continue;

    last_tick = tick;

    if (button_get_aux_state())
      button_pressed = 1;

    if (stage == 2)
     x = MATRIX_WIDTH - 1 - last_tick;  // wipe right to left
    else
      x = last_tick;                    // wipe left to right

    byte = x / 8;
    bit  = x % 8;
    mask = 1 << bit;

    for (y=0; y<MATRIX_HEIGHT; ++y)
    {
      index = (MATRIX_HEIGHT - 1 - y) * ROW_BYTES + byte;

      if (stage == 3)
      {
        color.red = 0;
        color.green = 0;
      }
      else
      {
        color.red = (pgm_read_byte(&vhs[index]) & mask) ? 255 : 0;

        index += ROW_BYTES / 2;  // move from red to green data

        color.green = (pgm_read_byte(&vhs[index]) & mask) ? 255 : 0;

        if (stage == 2)
        {
          // time to cycle some colors:

          if (color.red)
          {
            if (color.green)
              color.red = 0;    // yellow -> green
            else
              color.green = 255;  // red -> yellow
          }
          else
          {
            if (color.green)
            {
              color.red = 255;    // green -> red
              color.green = 0;
            }
          }
        }
      }

      matrix_set_pixel(x, y, color);
    }
  }
}