/* * EffecTV - Realtime Digital Video Effector * Copyright (C) 2001-2003 FUKUCHI Kentaro * * RadioacTV - motion-enlightment effect. * Copyright (C) 2001-2002 FUKUCHI Kentaro * * I referred to "DUNE!" by QuoVadis for this effect. */ #include #include #include "EffecTV.h" #include "utils.h" #define COLORS 32 #define PATTERN 4 #define MAGIC_THRESHOLD 40 #define RATIO 0.95 static int start(void); static int stop(void); static int draw(RGB32 *src, RGB32 *dest); static int event(); extern void blurzoomcore(); unsigned char *blurzoombuf; int *blurzoomx; int *blurzoomy; int buf_width_blocks; int buf_width; int buf_height; int buf_area; int buf_margin_right; int buf_margin_left; static char *effectname = "RadioacTV"; static int stat; static RGB32 *palette; static RGB32 palettes[COLORS*PATTERN]; static int mode = 0; /* 0=normal/1=strobe/2=strobe2/3=trigger */ static int snapTime = 0; static int snapInterval = 3; static RGB32 *snapframe; #define VIDEO_HWIDTH (buf_width/2) #define VIDEO_HHEIGHT (buf_height/2) /* this table assumes that video_width is times of 32 */ static void setTable() { unsigned int bits; int x, y, tx, ty, xx; int ptr, prevptr; prevptr = (int)(0.5+RATIO*(-VIDEO_HWIDTH)+VIDEO_HWIDTH); for(xx=0; xx<(buf_width_blocks); xx++){ bits = 0; for(x=0; x<32; x++){ ptr= (int)(0.5+RATIO*(xx*32+x-VIDEO_HWIDTH)+VIDEO_HWIDTH); #ifdef USE_NASM bits = bits<<1; if(ptr != prevptr) bits |= 1; #else bits = bits>>1; if(ptr != prevptr) bits |= 0x80000000; #endif /* USE_NASM */ prevptr = ptr; } blurzoomx[xx] = bits; } ty = (int)(0.5+RATIO*(-VIDEO_HHEIGHT)+VIDEO_HHEIGHT); tx = (int)(0.5+RATIO*(-VIDEO_HWIDTH)+VIDEO_HWIDTH); xx=(int)(0.5+RATIO*(buf_width-1-VIDEO_HWIDTH)+VIDEO_HWIDTH); blurzoomy[0] = ty * buf_width + tx; prevptr = ty * buf_width + xx; for(y=1; y0; y--) { for(x=width-2; x>0; x--) { v = (*(p-width) + *(p-1) + *(p+1) + *(p+width))/4 - 1; if(v == 255) v = 0; *q = v; p++; q++; } p += 2; q += 2; } } static void zoom() { int b, x, y; unsigned char *p, *q; int blocks, height; int dx; p = blurzoombuf + buf_area; q = blurzoombuf; height = buf_height; blocks = buf_width_blocks; for(y=0; y>1; } } } } void blurzoomcore() { blur(); zoom(); } #endif /* USE_NASM */ static void makePalette() { int i; #define DELTA (255/(COLORS/2-1)) for(i=0; i 255) { return NULL; } buf_width = buf_width_blocks * 32; buf_height = video_height; buf_area = buf_width * buf_height; buf_margin_left = (video_width - buf_width)/2; buf_margin_right = video_width - buf_width - buf_margin_left; sharedbuffer_reset(); blurzoombuf = (unsigned char *)sharedbuffer_alloc(buf_area * 2); if(blurzoombuf == NULL) { return NULL; } blurzoomx = (int *)malloc(buf_width*sizeof(int)); blurzoomy = (int *)malloc(buf_height*sizeof(int)); if(blurzoomx == NULL || blurzoomy == NULL) { return NULL; } entry = (effect *)malloc(sizeof(effect)); if(entry == NULL) { return NULL; } entry->name = effectname; entry->start = start; entry->stop = stop; entry->draw = draw; entry->event = event; setTable(); makePalette(); palette = palettes; return entry; } static int start() { memset(blurzoombuf, 0, buf_area * 2); image_set_threshold_y(MAGIC_THRESHOLD); snapframe = (RGB32 *)malloc(video_area*PIXEL_SIZE); if(snapframe == NULL) return -1; stat = 1; return 0; } static int stop() { if(stat) { free(snapframe); stat = 0; } return 0; } static int draw(RGB32 *src, RGB32 *dest) { int x, y; RGB32 a, b; unsigned char *diff, *p; if(mode != 2 || snapTime <= 0) { diff = image_bgsubtract_update_y(src); if(mode == 0 || snapTime <= 0) { diff += buf_margin_left; p = blurzoombuf; for(y=0; y> 3; } diff += video_width; p += buf_width; } if(mode == 1 || mode == 2) { memcpy(snapframe, src, video_area * PIXEL_SIZE); } } } blurzoomcore(); if(mode == 1 || mode == 2) { src = snapframe; } p = blurzoombuf; for(y=0; y> 8)); } for(x=0; xtype == SDL_KEYDOWN) { switch(event->key.keysym.sym) { case SDLK_1: case SDLK_2: case SDLK_3: case SDLK_4: mode = event->key.keysym.sym - SDLK_1; if(mode == 3) snapTime = 1; else snapTime = 0; break; case SDLK_KP1: case SDLK_KP2: case SDLK_KP3: case SDLK_KP4: mode = event->key.keysym.sym - SDLK_KP1; if(mode == 3) snapTime = 1; else snapTime = 0; break; case SDLK_r: palette = &palettes[COLORS*2]; break; case SDLK_g: palette = &palettes[COLORS]; break; case SDLK_b: palette = &palettes[0]; break; case SDLK_w: palette = &palettes[COLORS*3]; break; case SDLK_SPACE: if(mode == 3) snapTime = 0; break; case SDLK_INSERT: snapInterval++; break; case SDLK_DELETE: snapInterval--; if(snapInterval < 1) { snapInterval = 1; } break; default: break; } } else if(event->type == SDL_KEYUP) { switch(event->key.keysym.sym) { case SDLK_SPACE: if(mode == 3) snapTime = 1; break; default: break; } } return 0; }