Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 
 
 

220 řádky
6.0 KiB

  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. #include "common.h"
  15. #if !defined(__KERNEL__)
  16. # include <string.h>
  17. # include <math.h>
  18. # ifndef M_PI
  19. # define M_PI 3.14159265358979323846
  20. # endif
  21. #endif
  22. #include "cucul.h"
  23. #include "caca.h"
  24. /* Virtual buffer size */
  25. #define XSIZ 256
  26. #define YSIZ 256
  27. #define METASIZE 128
  28. #define METABALLS 12
  29. /* Colour index where to crop balls */
  30. #define CROPBALL 200
  31. static void create_ball(void);
  32. static void draw_ball(unsigned int, unsigned int);
  33. static unsigned char pixels[XSIZ * YSIZ];
  34. static unsigned char metaball[METASIZE * METASIZE];
  35. int main(int argc, char **argv)
  36. {
  37. cucul_canvas_t *cv; caca_display_t *dp;
  38. unsigned int r[256], g[256], b[256], a[256];
  39. float dd[METABALLS], di[METABALLS], dj[METABALLS], dk[METABALLS];
  40. unsigned int x[METABALLS], y[METABALLS];
  41. cucul_dither_t *cucul_dither;
  42. float i = 10.0, j = 17.0, k = 11.0;
  43. int p, frame = 0, pause = 0;
  44. double frameOffset[360 + 80];
  45. double frameOffset40[360];
  46. double frameOffset80[360];
  47. cv = cucul_create_canvas(0, 0);
  48. if(!cv)
  49. return 1;
  50. dp = caca_create_display(cv);
  51. if(!dp)
  52. return 1;
  53. caca_set_delay(dp, 20000);
  54. /* Make the palette eatable by libcaca */
  55. for(p = 0; p < 256; p++)
  56. r[p] = g[p] = b[p] = a[p] = 0x0;
  57. r[255] = g[255] = b[255] = 0xfff;
  58. /* Create a libcucul dither smaller than our pixel buffer, so that we
  59. * display only the interesting part of it */
  60. cucul_dither = cucul_create_dither(8, XSIZ - METASIZE, YSIZ - METASIZE,
  61. XSIZ, 0, 0, 0, 0);
  62. /* Generate ball sprite */
  63. create_ball();
  64. for(p = 0; p < METABALLS; p++)
  65. {
  66. dd[p] = cucul_rand(0, 100);
  67. di[p] = (float)cucul_rand(500, 4000) / 6000.0;
  68. dj[p] = (float)cucul_rand(500, 4000) / 6000.0;
  69. dk[p] = (float)cucul_rand(500, 4000) / 6000.0;
  70. }
  71. for(frame = 0; frame < 360; frame++) {
  72. frameOffset[frame] = frame * M_PI / 60;
  73. frameOffset40[frame] = (frame + 40) * M_PI / 60;
  74. frameOffset80[frame] = (frame + 80) * M_PI / 60;
  75. }
  76. /* Go ! */
  77. for(;;)
  78. {
  79. caca_event_t ev;
  80. if(caca_get_event(dp, CACA_EVENT_KEY_PRESS, &ev, 0))
  81. {
  82. switch(ev.data.key.ch)
  83. {
  84. case CACA_KEY_ESCAPE: goto end;
  85. case ' ': pause = !pause;
  86. }
  87. }
  88. if(pause)
  89. goto paused;
  90. frame++;
  91. if(frame >= 360)
  92. frame = 0;
  93. /* Crop the palette */
  94. for(p = CROPBALL; p < 255; p++)
  95. {
  96. int t1, t2, t3;
  97. double c1 = 1.0 + sin((double)frameOffset[frame]);
  98. double c2 = 1.0 + sin((double)frameOffset40[frame]);
  99. double c3 = 1.0 + sin((double)frameOffset80[frame]);
  100. t1 = p < 0x40 ? 0 : p < 0xc0 ? (p - 0x40) * 0x20 : 0xfff;
  101. t2 = p < 0xe0 ? 0 : (p - 0xe0) * 0x80;
  102. t3 = p < 0x40 ? p * 0x40 : 0xfff;
  103. r[p] = (c1 * t1 + c2 * t2 + c3 * t3) / 4;
  104. g[p] = (c1 * t2 + c2 * t3 + c3 * t1) / 4;
  105. b[p] = (c1 * t3 + c2 * t1 + c3 * t2) / 4;
  106. }
  107. /* Set the palette */
  108. cucul_set_dither_palette(cucul_dither, r, g, b, a);
  109. /* Silly paths for our balls */
  110. for(p = 0; p < METABALLS; p++)
  111. {
  112. float u = di[p] * i + dj[p] * j + dk[p] * sin(di[p] * k);
  113. float v = dd[p] + di[p] * j + dj[p] * k + dk[p] * sin(dk[p] * i);
  114. u = sin(i + u * 2.1) * (1.0 + sin(u));
  115. v = sin(j + v * 1.9) * (1.0 + sin(v));
  116. x[p] = (XSIZ - METASIZE) / 2 + u * (XSIZ - METASIZE) / 4;
  117. y[p] = (YSIZ - METASIZE) / 2 + v * (YSIZ - METASIZE) / 4;
  118. }
  119. i += 0.011;
  120. j += 0.017;
  121. k += 0.019;
  122. memset(pixels, 0, XSIZ * YSIZ);
  123. /* Here is all the trick. Maybe if you're that
  124. * clever you'll understand. */
  125. for(p = 0; p < METABALLS; p++)
  126. draw_ball(x[p], y[p]);
  127. paused:
  128. /* Draw our virtual buffer to screen, letting libcucul resize it */
  129. cucul_dither_bitmap(cv, 0, 0,
  130. cucul_get_canvas_width(cv),
  131. cucul_get_canvas_height(cv),
  132. cucul_dither, pixels + (METASIZE / 2) * (1 + XSIZ));
  133. cucul_set_color(cv, CUCUL_COLOR_WHITE, CUCUL_COLOR_BLUE);
  134. cucul_putstr(cv, cucul_get_canvas_width(cv) - 30,
  135. cucul_get_canvas_height(cv) - 2,
  136. " -=[ Powered by libcaca ]=- ");
  137. caca_refresh_display(dp);
  138. }
  139. /* End, bye folks */
  140. end:
  141. cucul_free_dither(cucul_dither);
  142. caca_free_display(dp);
  143. cucul_free_canvas(cv);
  144. return 0;
  145. }
  146. /* Generate ball sprite
  147. * You should read the comments, I already wrote that before ... */
  148. static void create_ball(void)
  149. {
  150. int x, y;
  151. float distance;
  152. for(y = 0; y < METASIZE; y++)
  153. for(x = 0; x < METASIZE; x++)
  154. {
  155. distance = ((METASIZE/2) - x) * ((METASIZE/2) - x)
  156. + ((METASIZE/2) - y) * ((METASIZE/2) - y);
  157. distance = sqrt(distance) * 64 / METASIZE;
  158. metaball[x + y * METASIZE] = distance > 15 ? 0 : (255 - distance) * 15;
  159. }
  160. }
  161. /* You missed the trick ? */
  162. static void draw_ball(unsigned int bx, unsigned int by)
  163. {
  164. unsigned int color;
  165. unsigned int i, e = 0;
  166. unsigned int b = (by * XSIZ) + bx;
  167. for(i = 0; i < METASIZE * METASIZE; i++)
  168. {
  169. color = pixels[b] + metaball[i];
  170. if(color > 255)
  171. color = 255;
  172. pixels[b] = color;
  173. if(e == METASIZE)
  174. {
  175. e = 0;
  176. b += XSIZ - METASIZE;
  177. }
  178. b++;
  179. e++;
  180. }
  181. }