summaryrefslogtreecommitdiffstats
path: root/thk04/gen_layer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'thk04/gen_layer.cpp')
-rw-r--r--thk04/gen_layer.cpp324
1 files changed, 324 insertions, 0 deletions
diff --git a/thk04/gen_layer.cpp b/thk04/gen_layer.cpp
new file mode 100644
index 0000000..c762f32
--- /dev/null
+++ b/thk04/gen_layer.cpp
@@ -0,0 +1,324 @@
+/* FreeJ
+ * Particle generator layer
+ * (c) Copyright 2004 Denis Roio aka jaromil <jaromil@dyne.org>
+ *
+ * blossom original algo is (c) 2003 by ragnar (waves 1.2)
+ * http://home.uninet.ee/~ragnar/waves
+ * further optimizations and changes followed
+ *
+ * This source code is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Public License as published
+ * by the Free Software Foundation; either version 2 of the License,
+ * or (at your option) any later version.
+ *
+ * This source code 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.
+ * Please refer to the GNU Public License for more details.
+ *
+ * You should have received a copy of the GNU Public License along with
+ * this source code; if not, write to:
+ * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * "$Id: gen_layer.cpp,v 1.2 2004/05/02 10:43:03 jaromil Exp $"
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <gen_layer.h>
+#include <jutils.h>
+#include <context.h>
+#include <config.h>
+
+/* defines for blob size and roundness */
+#define LIM 8 // 25
+#define NB_BLOB 16 // 25
+
+
+GenLayer::GenLayer()
+ :Layer() {
+
+ /* initialize prime numbers */
+ prime[0] = 2;
+ prime[1] = 3;
+ prime[2] = 5;
+ prime[3] = 7;
+ prime[4] = 11;
+ prime[5] = 13;
+ prime[6] = 17;
+ prime[7] = 19;
+ prime[8] = 23;
+ prime[9] = 29;
+ prime[10] = 31;
+
+ /* blossom vars */
+ blossom_count = 0;
+ blossom_m = 0;
+ blossom_n = 0;
+ blossom_i = 0;
+ blossom_j = 0;
+ blossom_k = 0;
+ blossom_l = 0;
+ blossom_r = 0.7;
+ blossom_a = 0;
+
+ /* initialize color masks */
+#if SDL_BYTEORDER == SDL_BIG_ENDIAN
+ rmask = 0xff000000;
+ gmask = 0x00ff0000;
+ bmask = 0x0000ff00;
+ amask = 0x00000000;
+#else
+ rmask = 0x000000ff;
+ gmask = 0x0000ff00;
+ bmask = 0x00ff0000;
+ amask = 0x00000000;
+#endif
+
+ surf = NULL;
+ blob_buf = NULL;
+
+ pi2 = 2.0*M_PI;
+
+ setname("GEO");
+}
+
+GenLayer::~GenLayer() {
+ close();
+}
+
+bool GenLayer::open(char *file) {
+ /* we don't need this */
+ return true;
+}
+
+void GenLayer::close() {
+ if(surf) SDL_FreeSurface(surf);
+ if(blob_buf) free(blob_buf);
+ return;
+}
+
+bool GenLayer::init(Context *scr) {
+
+ close(); // reentrancy
+
+ /* allocate the buffer on which the layer will write */
+
+ fastsrand( time(NULL) );
+
+ /* internal initalization */
+ _init(scr,scr->screen->w,scr->screen->h,32);
+
+ surf = SDL_CreateRGBSurface
+ (SDL_HWSURFACE|SDL_HWACCEL,geo.w,geo.h,32,bmask,gmask,rmask,amask);
+ if(!surf) {
+ error("can't create GenLayer surface: %s",SDL_GetError());
+ return(false);
+ }
+
+ pixels = (uint32_t*)surf->pixels;
+
+ blossom_recal(true);
+
+ /* blob initialization */
+ blob_buf = NULL;
+
+ blob_init(8);
+
+ return(true);
+}
+
+void *GenLayer::feed() {
+ /* automatic random recalculation:
+ if( !blossom_count ) {
+ recalculate();
+ blossom_count = 100+(50.0)*rand()/RAND_MAX;
+ } else {
+ blossom_count--;
+ */
+ blossom_a += 0.01;
+ if( blossom_a > pi2 )
+ blossom_a -= pi2;
+
+
+ SDL_FillRect(surf,NULL,0x0);
+
+ if (SDL_MUSTLOCK(surf))
+ if (SDL_LockSurface(surf) < 0) {
+ error("%s", SDL_GetError());
+ return NULL;
+ }
+
+ blossom();
+ return(surf->pixels);
+
+ if (SDL_MUSTLOCK(surf)) {
+ SDL_UnlockSurface(surf);
+ }
+
+}
+
+void GenLayer::blossom_recal(bool r) {
+ lock_feed();
+ float z = ((PRIMES-2)*fastrand()/RAND_MAX)+1;
+ blossom_m = 1.0+(30.0)*fastrand()/RAND_MAX;
+ blossom_n = 1.0+(30.0)*fastrand()/RAND_MAX;
+ blossom_i = prime[ (int) (z*fastrand()/RAND_MAX) ];
+ blossom_j = prime[ (int) (z*fastrand()/RAND_MAX) ];
+ blossom_k = prime[ (int) (z*fastrand()/RAND_MAX) ];
+ blossom_l = prime[ (int) (z*fastrand()/RAND_MAX) ];
+ wd = (double)geo.w;
+ hd = (double)geo.h;
+ if(r)
+ blossom_r = (blossom_r>=1.0)?1.0:blossom_r+0.1;
+ else
+ blossom_r = (blossom_r<=0.1)?0.1:blossom_r-0.1;
+ unlock_feed();
+}
+
+void GenLayer::blossom() {
+
+ float a;
+ int x, y;
+ double zx, zy;
+
+ /* here place a formula that draws on the screen
+ the surface being drawed at this point is always blank */
+ for( a=0.0 ; a<pi2; a+=0.006 ) {
+ zx = blossom_m*a;
+ zy = blossom_n*a;
+ x = (int)(wd*(0.47+ (blossom_r*sin(blossom_i*zx+blossom_a)+
+ (1.0-blossom_r)*sin(blossom_k*zy+blossom_a)) /2.2 ));
+
+ y = (int)(hd*(0.47+ (blossom_r*cos(blossom_j*zx+blossom_a)+
+ (1.0-blossom_r)*cos(blossom_l*zy+blossom_a)) /2.2 ));
+
+ //point(x,y);
+ blob(x,y);
+
+ }
+
+}
+
+void GenLayer::point(int x, int y) {
+
+ pixels[ (y*geo.w)+x ] += 0x99999999;
+
+}
+
+
+void GenLayer::blob_init(int ray) {
+ uint8_t col;
+
+ blob_size = ray*2;
+
+ /* @TODO
+ there should be a gradient sphere here
+ Niels helps me with this: calculating a circle
+ while(theta <= 360) {
+ double radians = (theta / 180.0) * PI;
+ double dx = ( origin[0] + cos( radians ) * radius );
+ double dy = ( origin[1] + sin( radians ) * radius );
+ */
+ uint32_t dx,dy;
+ double rad, th;
+ int c;
+ srand(time(NULL));
+ if(blob_buf) free(blob_buf);
+ blob_buf = (uint32_t*) calloc(ray*2*ray*2,sizeof(uint32_t));
+
+ for(th=1;th<=360;th++) {
+ rad = (th / 180.0) * M_PI;
+ for(c=ray;c>0;c--) {
+ dx = (uint32_t)( (ray) + cos( rad ) * c );
+ dy = (uint32_t)( (ray) + sin( rad ) * c );
+ col = (uint8_t)( 0x99/c * 0.8);
+ blob_buf[ (dx+((ray*2)*dy)) ] =
+ SDL_MapRGB(surf->format,col,col,col*1.3);
+ }
+ }
+
+}
+
+void GenLayer::blob(int x, int y) {
+ // if(y>geo.h-blob_size) return;
+ // if(x>geo.w-blob_size) return;
+
+ int i, j;
+ int stride = (geo.w-blob_size)>>1;
+
+ uint64_t *tmp_scr = (uint64_t*)pixels + ((x + y*geo.w)>>1);
+ uint64_t *tmp_blob = (uint64_t*)blob_buf;
+
+#ifdef HAVE_MMX
+
+ /* using mmx packed unsaturated addition on bytes
+ for cleaner and shiny result */
+ for(j=blob_size; j>0; j--) {
+ for(i=blob_size>>4; i>0; i--) {
+
+ asm volatile("movq (%1),%%mm0;"
+ "movq 8(%1),%%mm1;"
+ "movq 16(%1),%%mm2;"
+ "movq 24(%1),%%mm3;"
+ "movq 32(%1),%%mm4;"
+ "movq 40(%1),%%mm5;"
+ "movq 48(%1),%%mm6;"
+ "movq 56(%1),%%mm7;"
+ "paddusb (%0),%%mm0;" //addizione perfetta senza clipping
+ "paddusb 8(%0),%%mm1;" //addizione perfetta senza clipping
+ "paddusb 16(%0),%%mm2;" //addizione perfetta senza clipping
+ "paddusb 24(%0),%%mm3;" //addizione perfetta senza clipping
+ "paddusb 32(%0),%%mm4;" //addizione perfetta senza clipping
+ "paddusb 40(%0),%%mm5;" //addizione perfetta senza clipping
+ "paddusb 48(%0),%%mm6;" //addizione perfetta senza clipping
+ "paddusb 56(%0),%%mm7;" //addizione perfetta senza clipping
+ "movq %%mm0,(%0);"
+ "movq %%mm1,8(%0);"
+ "movq %%mm2,16(%0);"
+ "movq %%mm3,24(%0);"
+ "movq %%mm4,32(%0);"
+ "movq %%mm5,40(%0);"
+ "movq %%mm6,48(%0);"
+ "movq %%mm7,56(%0);"
+ // "paddsw %0, %%mm0;"// halo violetto
+ :
+ :"r"(tmp_scr),"r"(tmp_blob)
+ :"memory");
+ tmp_scr+=8;
+ tmp_blob+=8;
+ }
+ tmp_scr += stride;
+ }
+ asm("emms;");
+#else
+ for(j=blob_size; j>0; j--) {
+ for(i=blob_size>>1; i>0; i--) {
+ *(tmp_scr++) += *(tmp_blob++);
+ }
+ tmp_scr += stride;
+ }
+#endif
+
+}
+
+bool GenLayer::keypress(SDL_keysym *keysym) {
+ switch(keysym->sym) {
+
+ case SDLK_RIGHT:
+ blossom_recal(true);
+ break;
+
+ case SDLK_LEFT:
+ blossom_recal(false);
+ break;
+
+ default: return(false);
+
+ }
+
+ return(true);
+}
+