JNIEXPORT void JNICALL Java_org_zoy_caca_Dither_setDitherPalette(JNIEnv *env, jclass vls, jlong ptr, jintArray red, jintArray green, jintArray blue, jintArray alpha) { jint *relems, *gelems, *belems, *aelems; relems = (*env)->GetIntArrayElements(env, red, 0); gelems = (*env)->GetIntArrayElements(env, green, 0); belems = (*env)->GetIntArrayElements(env, blue, 0); aelems = (*env)->GetIntArrayElements(env, alpha, 0); caca_set_dither_palette((caca_dither_t *)ptr, relems, gelems, belems, aelems); (*env)->ReleaseIntArrayElements(env, red, relems, 0); (*env)->ReleaseIntArrayElements(env, green, gelems, 0); (*env)->ReleaseIntArrayElements(env, blue, belems, 0); (*env)->ReleaseIntArrayElements(env, alpha, aelems, 0); }
void moire(enum action action, caca_canvas_t *cv) { static caca_dither_t *dither; static uint8_t *screen; static float d[6]; static uint32_t red[256], green[256], blue[256], alpha[256]; int i, x, y; switch(action) { case PREPARE: /* Fill various tables */ for(i = 0 ; i < 256; i++) red[i] = green[i] = blue[i] = alpha[i] = 0; for(i = 0; i < 6; i++) d[i] = ((float)caca_rand(50, 70)) / 1000.0; red[0] = green[0] = blue[0] = 0x777; red[1] = green[1] = blue[1] = 0xfff; /* Fill the circle */ for(i = DISCSIZ * 2; i > 0; i -= DISCTHICKNESS) { int t, dx, dy; for(t = 0, dx = 0, dy = i; dx <= dy; dx++) { draw_line(dx / 3, dy / 3, (i / DISCTHICKNESS) % 2); draw_line(dy / 3, dx / 3, (i / DISCTHICKNESS) % 2); t += t > 0 ? dx - dy-- : dx; } } break; case INIT: screen = malloc(XSIZ * YSIZ * sizeof(uint8_t)); dither = caca_create_dither(8, XSIZ, YSIZ, XSIZ, 0, 0, 0, 0); break; case UPDATE: memset(screen, 0, XSIZ * YSIZ); /* Set the palette */ red[0] = 0.5 * (1 + sin(d[0] * (frame + 1000))) * 0xfff; green[0] = 0.5 * (1 + cos(d[1] * frame)) * 0xfff; blue[0] = 0.5 * (1 + cos(d[2] * (frame + 3000))) * 0xfff; red[1] = 0.5 * (1 + sin(d[3] * (frame + 2000))) * 0xfff; green[1] = 0.5 * (1 + cos(d[4] * frame + 5.0)) * 0xfff; blue[1] = 0.5 * (1 + cos(d[5] * (frame + 4000))) * 0xfff; caca_set_dither_palette(dither, red, green, blue, alpha); /* Draw circles */ x = cos(d[0] * (frame + 1000)) * 128.0 + (XSIZ / 2); y = sin(0.11 * frame) * 128.0 + (YSIZ / 2); put_disc(screen, x, y); x = cos(0.13 * frame + 2.0) * 64.0 + (XSIZ / 2); y = sin(d[1] * (frame + 2000)) * 64.0 + (YSIZ / 2); put_disc(screen, x, y); break; case RENDER: caca_dither_bitmap(cv, 0, 0, caca_get_canvas_width(cv), caca_get_canvas_height(cv), dither, screen); break; case FREE: free(screen); caca_free_dither(dither); break; } }
void metaballs(enum action action, caca_canvas_t *cv) { static caca_dither_t *caca_dither; static uint8_t *screen; static uint32_t r[256], g[256], b[256], a[256]; static float dd[METABALLS], di[METABALLS], dj[METABALLS], dk[METABALLS]; static unsigned int x[METABALLS], y[METABALLS]; static float i = 10.0, j = 17.0, k = 11.0; static double offset[360 + 80]; static unsigned int angleoff; int n, angle; switch(action) { case PREPARE: /* Make the palette eatable by libcaca */ for(n = 0; n < 256; n++) r[n] = g[n] = b[n] = a[n] = 0x0; r[255] = g[255] = b[255] = 0xfff; /* Generate ball sprite */ create_ball(); for(n = 0; n < METABALLS; n++) { dd[n] = caca_rand(0, 100); di[n] = (float)caca_rand(500, 4000) / 6000.0; dj[n] = (float)caca_rand(500, 4000) / 6000.0; dk[n] = (float)caca_rand(500, 4000) / 6000.0; } angleoff = caca_rand(0, 360); for(n = 0; n < 360 + 80; n++) offset[n] = 1.0 + sin((double)(n * M_PI / 60)); break; case INIT: screen = malloc(XSIZ * YSIZ * sizeof(uint8_t)); /* Create a libcaca dither smaller than our pixel buffer, so that we * display only the interesting part of it */ caca_dither = caca_create_dither(8, XSIZ - METASIZE, YSIZ - METASIZE, XSIZ, 0, 0, 0, 0); break; case UPDATE: angle = (frame + angleoff) % 360; /* Crop the palette */ for(n = CROPBALL; n < 255; n++) { int t1, t2, t3; double c1 = offset[angle]; double c2 = offset[angle + 40]; double c3 = offset[angle + 80]; t1 = n < 0x40 ? 0 : n < 0xc0 ? (n - 0x40) * 0x20 : 0xfff; t2 = n < 0xe0 ? 0 : (n - 0xe0) * 0x80; t3 = n < 0x40 ? n * 0x40 : 0xfff; r[n] = (c1 * t1 + c2 * t2 + c3 * t3) / 4; g[n] = (c1 * t2 + c2 * t3 + c3 * t1) / 4; b[n] = (c1 * t3 + c2 * t1 + c3 * t2) / 4; } /* Set the palette */ caca_set_dither_palette(caca_dither, r, g, b, a); /* Silly paths for our balls */ for(n = 0; n < METABALLS; n++) { float u = di[n] * i + dj[n] * j + dk[n] * sin(di[n] * k); float v = dd[n] + di[n] * j + dj[n] * k + dk[n] * sin(dk[n] * i); u = sin(i + u * 2.1) * (1.0 + sin(u)); v = sin(j + v * 1.9) * (1.0 + sin(v)); x[n] = (XSIZ - METASIZE) / 2 + u * (XSIZ - METASIZE) / 4; y[n] = (YSIZ - METASIZE) / 2 + v * (YSIZ - METASIZE) / 4; } i += 0.011; j += 0.017; k += 0.019; memset(screen, 0, XSIZ * YSIZ); for(n = 0; n < METABALLS; n++) draw_ball(screen, x[n], y[n]); break; case RENDER: caca_dither_bitmap(cv, 0, 0, caca_get_canvas_width(cv), caca_get_canvas_height(cv), caca_dither, screen + (METASIZE / 2) * (1 + XSIZ)); break; case FREE: free(screen); caca_free_dither(caca_dither); break; } }
void plasma(enum action action, caca_canvas_t *cv) { static caca_dither_t *dither; static uint8_t *screen; static uint32_t red[256], green[256], blue[256], alpha[256]; static double r[3], R[6]; int i, x, y; switch(action) { case PREPARE: /* Fill various tables */ for(i = 0 ; i < 256; i++) red[i] = green[i] = blue[i] = alpha[i] = 0; for(i = 0; i < 3; i++) r[i] = (double)(caca_rand(1, 1000)) / 60000 * M_PI; for(i = 0; i < 6; i++) R[i] = (double)(caca_rand(1, 1000)) / 10000; for(y = 0 ; y < TABLEY ; y++) for(x = 0 ; x < TABLEX ; x++) { double tmp = (((double)((x - (TABLEX / 2)) * (x - (TABLEX / 2)) + (y - (TABLEX / 2)) * (y - (TABLEX / 2)))) * (M_PI / (TABLEX * TABLEX + TABLEY * TABLEY))); table[x + y * TABLEX] = (1.0 + sin(12.0 * sqrt(tmp))) * 256 / 6; } break; case INIT: screen = malloc(XSIZ * YSIZ * sizeof(uint8_t)); dither = caca_create_dither(8, XSIZ, YSIZ, XSIZ, 0, 0, 0, 0); break; case UPDATE: for(i = 0 ; i < 256; i++) { double z = ((double)i) / 256 * 6 * M_PI; red[i] = (1.0 + sin(z + r[1] * frame)) / 2 * 0xfff; blue[i] = (1.0 + cos(z + r[0] * (frame + 100))) / 2 * 0xfff; green[i] = (1.0 + cos(z + r[2] * (frame + 200))) / 2 * 0xfff; } /* Set the palette */ caca_set_dither_palette(dither, red, green, blue, alpha); do_plasma(screen, (1.0 + sin(((double)frame) * R[0])) / 2, (1.0 + sin(((double)frame) * R[1])) / 2, (1.0 + sin(((double)frame) * R[2])) / 2, (1.0 + sin(((double)frame) * R[3])) / 2, (1.0 + sin(((double)frame) * R[4])) / 2, (1.0 + sin(((double)frame) * R[5])) / 2); break; case RENDER: caca_dither_bitmap(cv, 0, 0, caca_get_canvas_width(cv), caca_get_canvas_height(cv), dither, screen); break; case FREE: free(screen); caca_free_dither(dither); break; } }
static VALUE set_dither_palette(VALUE self, VALUE palette) { int i; unsigned int *red, *blue, *green, *alpha; VALUE v, r, g, b, a; int error = 0; if(RARRAY(palette)->len != 256) { rb_raise(rb_eArgError, "Palette must contain 256 elements"); } red = ALLOC_N(unsigned int, 256); if(!red) rb_raise(rb_eNoMemError,"Out of memory"); green = ALLOC_N(unsigned int, 256); if(!green) { free(red); rb_raise(rb_eNoMemError,"Out of memory"); } blue = ALLOC_N(unsigned int, 256); if(!blue) { free(red); free(green); rb_raise(rb_eNoMemError,"Out of memory"); } alpha = ALLOC_N(unsigned int, 256); if(!alpha) { free(red); free(green); free(blue); rb_raise(rb_eNoMemError,"Out of memory"); } for(i=0; i<256; i++) { v = rb_ary_entry(palette, i); if((TYPE(v) == T_ARRAY) && (RARRAY(v)->len == 4)) { r = rb_ary_entry(v,0); g = rb_ary_entry(v,1); b = rb_ary_entry(v,2); a = rb_ary_entry(v,3); if(rb_obj_is_kind_of(r, rb_cInteger) && rb_obj_is_kind_of(g, rb_cInteger) && rb_obj_is_kind_of(b, rb_cInteger) && rb_obj_is_kind_of(a, rb_cInteger)) { red[i] = NUM2INT(r); green[i] = NUM2INT(g); blue[i] = NUM2INT(b); alpha[i] = NUM2INT(a); } else error = 1; } else error = 1; } if(error) { free(red); free(green); free(blue); free(alpha); rb_raise(rb_eArgError, "Invalid palette"); } if(caca_set_dither_palette(_SELF, red, green, blue, alpha)<0) { free(red); free(green); free(blue); free(alpha); rb_raise(rb_eRuntimeError, strerror(errno)); } free(red); free(green); free(blue); free(alpha); return palette; }