You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

пре 18 година
пре 18 година
пре 18 година
пре 18 година
пре 18 година
пре 18 година
пре 18 година
пре 18 година
пре 18 година
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  1. /*
  2. * cacaball metaballs effect for libcaca
  3. * Copyright (c) 2003-2004 Jean-Yves Lamoureux <jylam@lnxscene.org>
  4. * All Rights Reserved
  5. *
  6. * $Id$
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the Do What The Fuck You Want To
  10. * Public License, Version 2, as published by Sam Hocevar. See
  11. * http://sam.zoy.org/wtfpl/COPYING for more details.
  12. */
  13. #include "config.h"
  14. #if !defined(__KERNEL__)
  15. # include <string.h>
  16. # include <math.h>
  17. # ifndef M_PI
  18. # define M_PI 3.14159265358979323846
  19. # endif
  20. #endif
  21. #include "cucul.h"
  22. #include "caca.h"
  23. /* Virtual buffer size */
  24. #define XSIZ 256
  25. #define YSIZ 256
  26. #define METASIZE 128
  27. #define METABALLS 12
  28. /* Colour index where to crop balls */
  29. #define CROPBALL 200
  30. static void create_ball(void);
  31. static void draw_ball(unsigned int, unsigned int);
  32. static unsigned char pixels[XSIZ * YSIZ];
  33. static unsigned char metaball[METASIZE * METASIZE];
  34. int main(int argc, char **argv)
  35. {
  36. cucul_t *qq; caca_t *kk;
  37. unsigned int r[256], g[256], b[256], a[256];
  38. float d[METABALLS], di[METABALLS], dj[METABALLS], dk[METABALLS];
  39. unsigned int x[METABALLS], y[METABALLS];
  40. struct cucul_dither *cucul_dither;
  41. float i = 10.0, j = 17.0, k = 11.0;
  42. int p, frame = 0, pause = 0;
  43. double frameOffset[360 + 80];
  44. double frameOffset40[360];
  45. double frameOffset80[360];
  46. qq = cucul_create(0, 0);
  47. if(!qq)
  48. return 1;
  49. kk = caca_attach(qq);
  50. if(!kk)
  51. return 1;
  52. caca_set_delay(kk, 20000);
  53. /* Make the palette eatable by libcaca */
  54. for(p = 0; p < 256; p++)
  55. r[p] = g[p] = b[p] = a[p] = 0x0;
  56. r[255] = g[255] = b[255] = 0xfff;
  57. /* Create a libcucul dither smaller than our pixel buffer, so that we
  58. * display only the interesting part of it */
  59. cucul_dither = cucul_create_dither(8, XSIZ - METASIZE, YSIZ - METASIZE,
  60. XSIZ, 0, 0, 0, 0);
  61. /* Generate ball sprite */
  62. create_ball();
  63. for(p = 0; p < METABALLS; p++)
  64. {
  65. d[p] = cucul_rand(0, 100);
  66. di[p] = (float)cucul_rand(500, 4000) / 6000.0;
  67. dj[p] = (float)cucul_rand(500, 4000) / 6000.0;
  68. dk[p] = (float)cucul_rand(500, 4000) / 6000.0;
  69. }
  70. for(frame = 0; frame < 360; frame++) {
  71. frameOffset[frame] = frame * M_PI / 60;
  72. frameOffset40[frame] = (frame + 40) * M_PI / 60;
  73. frameOffset80[frame] = (frame + 80) * M_PI / 60;
  74. }
  75. /* Go ! */
  76. for(;;)
  77. {
  78. struct caca_event ev;
  79. if(caca_get_event(kk, CACA_EVENT_KEY_PRESS, &ev, 0))
  80. {
  81. switch(ev.data.key.c)
  82. {
  83. case CACA_KEY_ESCAPE: goto end;
  84. case ' ': pause = !pause;
  85. }
  86. }
  87. if(pause)
  88. goto paused;
  89. frame++;
  90. if(frame >= 360)
  91. frame = 0;
  92. /* Crop the palette */
  93. for(p = CROPBALL; p < 255; p++)
  94. {
  95. int t1, t2, t3;
  96. double c1 = 1.0 + sin((double)frameOffset[frame]);
  97. double c2 = 1.0 + sin((double)frameOffset40[frame]);
  98. double c3 = 1.0 + sin((double)frameOffset80[frame]);
  99. t1 = p < 0x40 ? 0 : p < 0xc0 ? (p - 0x40) * 0x20 : 0xfff;
  100. t2 = p < 0xe0 ? 0 : (p - 0xe0) * 0x80;
  101. t3 = p < 0x40 ? p * 0x40 : 0xfff;
  102. r[p] = (c1 * t1 + c2 * t2 + c3 * t3) / 4;
  103. g[p] = (c1 * t2 + c2 * t3 + c3 * t1) / 4;
  104. b[p] = (c1 * t3 + c2 * t1 + c3 * t2) / 4;
  105. }
  106. /* Set the palette */
  107. cucul_set_dither_palette(cucul_dither, r, g, b, a);
  108. /* Silly paths for our balls */
  109. for(p = 0; p < METABALLS; p++)
  110. {
  111. float u = di[p] * i + dj[p] * j + dk[p] * sin(di[p] * k);
  112. float v = d[p] + di[p] * j + dj[p] * k + dk[p] * sin(dk[p] * i);
  113. u = sin(i + u * 2.1) * (1.0 + sin(u));
  114. v = sin(j + v * 1.9) * (1.0 + sin(v));
  115. x[p] = (XSIZ - METASIZE) / 2 + u * (XSIZ - METASIZE) / 4;
  116. y[p] = (YSIZ - METASIZE) / 2 + v * (YSIZ - METASIZE) / 4;
  117. }
  118. i += 0.011;
  119. j += 0.017;
  120. k += 0.019;
  121. memset(pixels, 0, XSIZ * YSIZ);
  122. /* Here is all the trick. Maybe if you're that
  123. * clever you'll understand. */
  124. for(p = 0; p < METABALLS; p++)
  125. draw_ball(x[p], y[p]);
  126. paused:
  127. /* Draw our virtual buffer to screen, letting libcucul resize it */
  128. cucul_dither_bitmap(qq, 0, 0,
  129. cucul_get_width(qq) - 1, cucul_get_height(qq) - 1,
  130. cucul_dither, pixels + (METASIZE / 2) * (1 + XSIZ));
  131. cucul_set_color(qq, CUCUL_COLOR_WHITE, CUCUL_COLOR_BLUE);
  132. cucul_putstr(qq, cucul_get_width(qq) - 30, cucul_get_height(qq) - 2,
  133. " -=[ Powered by libcaca ]=- ");
  134. caca_display(kk);
  135. }
  136. /* End, bye folks */
  137. end:
  138. cucul_free_dither(cucul_dither);
  139. caca_detach(kk);
  140. cucul_free(qq);
  141. return 0;
  142. }
  143. /* Generate ball sprite
  144. * You should read the comments, I already wrote that before ... */
  145. static void create_ball(void)
  146. {
  147. int x, y;
  148. float distance;
  149. for(y = 0; y < METASIZE; y++)
  150. for(x = 0; x < METASIZE; x++)
  151. {
  152. distance = ((METASIZE/2) - x) * ((METASIZE/2) - x)
  153. + ((METASIZE/2) - y) * ((METASIZE/2) - y);
  154. distance = sqrt(distance) * 64 / METASIZE;
  155. metaball[x + y * METASIZE] = distance > 15 ? 0 : (255 - distance) * 15;
  156. }
  157. }
  158. /* You missed the trick ? */
  159. static void draw_ball(unsigned int bx, unsigned int by)
  160. {
  161. unsigned int color;
  162. unsigned int i, e = 0;
  163. unsigned int b = (by * XSIZ) + bx;
  164. for(i = 0; i < METASIZE * METASIZE; i++)
  165. {
  166. color = pixels[b] + metaball[i];
  167. if(color > 255)
  168. color = 255;
  169. pixels[b] = color;
  170. if(e == METASIZE)
  171. {
  172. e = 0;
  173. b += XSIZ - METASIZE;
  174. }
  175. b++;
  176. e++;
  177. }
  178. }