/* * EffecTV - Realtime Digital Video Effector * Copyright (C) 2001-2003 FUKUCHI Kentaro * * dice.c: a 'dicing' effect * copyright (c) 2001 Sam Mertens. This code is subject to the provisions of * the GNU Public License. * * I suppose this looks similar to PuzzleTV, but it's not. The screen is * divided into small squares, each of which is rotated either 0, 90, 180 or * 270 degrees. The amount of rotation for each square is chosen at random. * * Controls: * c - shrink the size of the squares, down to 1x1. * v - enlarge the size of the squares, up to 32x32. * space - generate a new random rotation map. * */ #include #include #include #include "EffecTV.h" #include "utils.h" #ifndef max #define max(a,b) (((a) > (b)) ? (a) : (b)) #endif #define DEFAULT_CUBE_BITS 4 #define MAX_CUBE_BITS 5 #define MIN_CUBE_BITS 0 typedef enum _dice_dir { Up = 0, Right = 1, Down = 2, Left = 3 } DiceDir; static int start(void); static int stop(void); static int draw(RGB32 *src, RGB32 *dest); //static int event(); static void diceCreateMap(); static char *effectname = "DiceTV"; static int state = 0; static char* dicemap; static int g_cube_bits = DEFAULT_CUBE_BITS; static int g_cube_size = 0; static int g_map_height = 0; static int g_map_width = 0; effect *diceRegister() { effect *entry; sharedbuffer_reset(); dicemap = (char*)sharedbuffer_alloc(video_height * video_width * sizeof(char)); if(dicemap == NULL) { return NULL; } diceCreateMap(); entry = (effect *)malloc(sizeof(effect)); if(entry == NULL) { return NULL; } entry->name = effectname; entry->start = start; entry->stop = stop; entry->draw = draw; entry->event = 0;//event; return entry; } static int start() { diceCreateMap(); #ifdef DEBUG v4lprint(&vd); #endif state = 1; return 0; } static int stop() { state = 0; return 0; } static int draw(RGB32 *src, RGB32 *dest) { int i; int map_x, map_y, map_i; int base; int dx, dy, di; map_i = 0; for(map_y = 0; map_y < g_map_height; map_y++) { for(map_x = 0; map_x < g_map_width; map_x++) { base = (map_y << g_cube_bits) * video_width + (map_x << g_cube_bits); switch (dicemap[map_i]) { case Up: // fprintf(stderr, "U"); for (dy = 0; dy < g_cube_size; dy++) { i = base + dy * video_width; for (dx = 0; dx < g_cube_size; dx++) { dest[i] = src[i]; i++; } } break; case Left: // fprintf(stderr, "L"); for (dy = 0; dy < g_cube_size; dy++) { i = base + dy * video_width; for (dx = 0; dx < g_cube_size; dx++) { di = base + (dx * video_width) + (g_cube_size - dy - 1); dest[di] = src[i]; i++; } } break; case Down: // fprintf(stderr, "D"); for (dy = 0; dy < g_cube_size; dy++) { di = base + dy * video_width; i = base + (g_cube_size - dy - 1) * video_width + g_cube_size; for (dx = 0; dx < g_cube_size; dx++) { i--; dest[di] = src[i]; di++; } } break; case Right: // fprintf(stderr, "R"); for (dy = 0; dy < g_cube_size; dy++) { i = base + (dy * video_width); for (dx = 0; dx < g_cube_size; dx++) { di = base + dy + (g_cube_size - dx - 1) * video_width; dest[di] = src[i]; i++; } } break; default: // fprintf(stderr, "E"); // This should never occur break; } map_i++; } // fprintf(stderr,"\n"); } return 0; } static void diceCreateMap() { int x; int y; int i; g_map_height = video_height >> g_cube_bits; g_map_width = video_width >> g_cube_bits; g_cube_size = 1 << g_cube_bits; i = 0; for (y=0; y> 24) & 0x03; i++; } } return; }