%ffp Category:"AmphiSoft" Title: "Life Waves" Author: "Ilyich the Toad \n(ilyich@snark.rinet.ru; ilyich@cacr.ioc.ac.ru)" Copyright: "© 1999 by Ilyich the Toad" Description: "Game-of-Life variation a-la Belousov reaction (FIR-optimized)" "Contact ilyich@cacr.ioc.ac.ru, ilyich@snark.rinet.ru, bufo@chat.ru" Version: "0.23" Dialog:color=silver ctl[0]:"Life &Cycles",range=(0,500),val=5,pagesize=5,linesize=1,pos=(266,8),size=(90,9), fontcolor=black ctl[6]:"&Maturation", range=(0,200), val=64, pagesize=8,pos=(266,19), size=(90,9), fontcolor=black ctl[4]:"&Spreading",range=(1,16),val=4,pagesize=4,linesize=1,pos=(266,30),size=(90,9), fontcolor=black //ctl[1]:"&Height", range=(0,200),val=230,pagesize=5,linesize=1,pos=(266,62),size=(90,9), fontcolor=black ctl[2]:"&Width", range=(0,128),val=2,pagesize=2,linesize=1,pos=(266,51),size=(90,9), fontcolor=black ctl(7):groupbox(group), "Growth:", pos=(190,0),size=(196, 43), fontcolor=navyblue, color=silver //ctl(5):groupbox(group), "Death Threshold:", pos=(190, 43),size=(196, 32), fontcolor=navyblue, color=silver ctl(5):groupbox(group), "Death Threshold:", pos=(190, 43),size=(196, 21), fontcolor=navyblue, color=silver ctl[3]:CHECKBOX, "Animate &Preview", val=1, pos=(290,67), size=(65,10), fontcolor=black ctl[11]:CHECKBOX, "Smooth Result", val=1, pos=(290,76), size=(58,10), fontcolor=black ctl[17]:CHECKBOX, "Enable Exhausting", val=0, pos=(290,85), size=(72,10), fontcolor=black ctl(8):RADIOBUTTON(group, tabstop), "Source", val=1,pos=(196,72),size=(38,10), fontcolor=black, action=preview ctl(9):RADIOBUTTON, "Random", val=0,pos=(240,72),size=(40,10), fontcolor=black, action=preview ctl(10):GROUPBOX(group), "Start from:", pos=(190,64),size=(95,20), fontcolor=navyblue, color=silver ctl(12):RADIOBUTTON(group, tabstop), "Grey", val=1,pos=(196,92),size=(38,10), fontcolor=black, action=preview ctl(13):RADIOBUTTON, "Host Colors", val=0,pos=(230,92),size=(50,10), fontcolor=black, action=preview ctl(14):GROUPBOX(group), "Colors:", pos=(190,84),size=(96,20), fontcolor=navyblue, color=silver ctl(15):STATICTEXT(notify), "http://photoshop.msk.ru", pos=(235, 112),size=(100,10), fontcolor=blue, action=preview ctl(16):GROUPBOX(group), "Home", pos=(190,105),size=(160,19), fontcolor=navyblue, color=silver OnCtl(n):{ if (n == 15 && e == FME_CLICKED && ctl(16) == 0) { // Help button was pressed int ret = shellExec("open", "http://photoshop.msk.ru", NULL, NULL); if (ret != -1) { Info("For a good time, point your browser to:\n\n" " http://photoshop.msk.ru"); } return true; } return false; } ForEveryTile:{ int iterations, die, grow, maturespeed=ctl(6); int i, brightest, darkest, exhaust; int temp, randx, randy; int currentcell; bool anim; int vWeight; int hWeight; int vBlurRadius; int hBlurRadius; setCtlRange(0,0,500); setCtlRange(1,0,255); setCtlRange(2,0,255); setCtlRange(4,1,16); iterations=ctl(0); die = 230/3+ctl(2)/2; grow = 230/3-ctl(2)/2; anim=ctl(3); vBlurRadius = max((2*ctl(4)+scaleFactor)/(2*scaleFactor), 1); //Vertical blur radius hBlurRadius = vBlurRadius; if (ctl(17)) { exhaust=155*maturespeed/100;} else { exhaust=0; } // ---------------------------------- // Checking for preview reliability // ---------------------------------- if (vBlurRadius==1) { setCtlFontColor(15, COLOR(red)); setCtlText(15, "Zoom too low - preview unreliable"); setCtlPos(15, 220, 112, 120, 10); setCtlText(16, "Oops!"); setCtlVal(16, 1); // flag to disable clickable URL } else { setCtlFontColor(15, COLOR(blue)); setCtlText(15, "http://photoshop.msk.ru"); setCtlPos(15, 235, 112, 100, 10); setCtlText(16, "Home:"); setCtlVal(16, 0); // flag to enable clickable URL } // --------------------- // Get source to buffers // --------------------- if (ctl(8)) { int br; for (y=y_start; y < y_end; y++) { for (x=x_start; x < x_end; x++) { br=0; for (z= 0; z < 3; z++) { br+=src(x,y,z); }//for z tset(x,y,0,br/3); //t2set(x,y,0,br/3); }//for x }//for y }//if if (ctl(9)) { for (y=y_start; y < y_end; y++) { for (x=x_start; x < x_end; x++) { int random=rnd(0,255); tset(x,y,0,random); //t2set(x,y,0,random); } } } //----------------------------------------------- //----------------------------------------------- // // Iteratively process buffer // //----------------------------------------------- //----------------------------------------------- for (i=0; iexhaust) { //is there anybody in there? // now make a decision if (temp>die) tset(x,y,0,0); else if (temp>grow) { tset((x-randx+X)%X,(y-randy+Y)%Y,1,tget((x-randx+X)%X,(y-randy+Y)%Y,1)+currentcell/2); tset((x+randx+X)%X,(y+randy+Y)%Y,1,tget((x+randx+X)%X,(y+randy+Y)%Y,1)+currentcell/2); tset(x,y,1,0);} else tset(x,y,1,currentcell+maturespeed); //endif - cell maturating } }//for x }//for y for (y=y_start; y < y_end; y++) { for (x=x_start; x < x_end; x++) { tset(x,y,0, tget(x,y,1)); } } // ------------------------------ // One more blur pass // on final image... // ------------------------------ if (ctl(11) && i==(iterations-1)) { { int intermed, vBlurRadius2=max(vBlurRadius/2,1), hBlurRadius2=max(hBlurRadius/2,1), vWeight2 = vBlurRadius2*2 + 1, hWeight2 = hBlurRadius2*2 + 1; for (x=x_start; x < x_end; x++) { // vertical blur... int sum = 0; for (intermed=-vBlurRadius2; intermed <= vBlurRadius2; intermed++) { sum += tget(x, (y_start-1+intermed+Y)%Y, 0); } for (y=y_start; y < y_end; y++) { sum += tget(x, (y+vBlurRadius2+Y)%Y, 0) - tget(x, (y-vBlurRadius2-1+Y)%Y, 0); tset(x,y,1,scl(sum/vWeight2,darkest,brightest,0,255)); } } for (y=y_start; y < y_end; y++) { // horizontal blur... int sum = 0; for (intermed=-hBlurRadius2; intermed <= hBlurRadius2; intermed++) { sum += tget((x_start-1+intermed+X)%X, y, 1); } for (x=x_start; x < x_end; x++) { sum += tget((x+hBlurRadius2+X)%X, y, 1) - tget((x-hBlurRadius2-1+X)%X, y, 1); tset(x,y,0,sum/hWeight2); brightest=max(brightest,sum/(hWeight2)); darkest=min(darkest,sum/(hWeight2)); } } } } // ------------------------------ // Copy first buffer to image // if preview set to interactive // ------------------------------ if (doingProxy && anim > 0) { // Copy buffer back to the image for (y=y_start; y < y_end; y++) { for (x=x_start; x < x_end; x++) { if (ctl(13)) { pset(x,y,0, scl(tget(x,y,0),darkest,brightest, Rval(fgColor), Rval(bgColor))); pset(x,y,1, scl(tget(x,y,0),darkest,brightest, Gval(fgColor), Gval(bgColor))); pset(x,y,2, scl(tget(x,y,0),darkest,brightest, Bval(fgColor), Bval(bgColor))); } else { for (y=y_start; y < y_end; y++) { for (x=x_start; x < x_end; x++) { for (z= 0; z < 3; z++) { pset(x,y,z, scl(tget(x,y,0),darkest,brightest,0,255)); } // for z } // for x } // for y } // if } } updatePreview(-99); }; }//for i if (doingProxy * anim == 0) { // Copy buffer back to the image for (y=y_start; y < y_end; y++) { for (x=x_start; x < x_end; x++) { if (ctl(13)) { pset(x,y,0, scl(tget(x,y,0),darkest,brightest, Rval(fgColor), Rval(bgColor))); pset(x,y,1, scl(tget(x,y,0),darkest,brightest, Gval(fgColor), Gval(bgColor))); pset(x,y,2, scl(tget(x,y,0),darkest,brightest, Bval(fgColor), Bval(bgColor))); } else { for (y=y_start; y < y_end; y++) { for (x=x_start; x < x_end; x++) { for (z= 0; z < 3; z++) { pset(x,y,z, scl(tget(x,y,0),darkest,brightest,0,255)); } // for z } // for x } // for y } // if } } }//if applied to final image updateProgress(0, 100); return true; }