選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 
 
 

174 行
4.7 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 GNU Lesser General Public
  10. * License as published by the Free Software Foundation; either
  11. * version 2 of the License, or (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * Lesser General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU Lesser General Public
  19. * License along with this program; if not, write to the Free Software
  20. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  21. * 02111-1307 USA
  22. */
  23. #include "config.h"
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <math.h>
  28. #include "caca.h"
  29. /* Virtual buffer size */
  30. #define XSIZ 256
  31. #define YSIZ 256
  32. #define METASIZE 100
  33. #define METABALLS 24
  34. /* Colour index where to crop balls */
  35. #define CROPBALL 180
  36. static void create_ball(void);
  37. static void draw_ball(unsigned int, unsigned int);
  38. static unsigned char pixels[XSIZ * YSIZ];
  39. static unsigned char metaball[METASIZE * METASIZE];
  40. int main(int argc, char **argv)
  41. {
  42. int r[256], g[256], b[256], a[256];
  43. float d[METABALLS], di[METABALLS], dj[METABALLS], dk[METABALLS];
  44. unsigned int x[METABALLS], y[METABALLS];
  45. struct caca_bitmap *caca_bitmap;
  46. float i = 10.0, j = 17.0, k = 11.0;
  47. int p;
  48. if(caca_init())
  49. return 1;
  50. caca_set_delay(10000);
  51. /* Make the palette eatable by libcaca */
  52. for(p = 0; p < 256; p++)
  53. {
  54. r[p] = p < 0x40 ? 0 : p < 0xc0 ? (p - 0x40) * 0x20 : 0xfff;
  55. g[p] = p < 0xc0 ? 0 : (p - 0xc0) * 0x40;
  56. b[p] = p < 0x40 ? p * 0x40 : 0xfff;
  57. a[p] = 0x0;
  58. }
  59. /* Crop the palette */
  60. for(p = 0; p < CROPBALL; p++)
  61. r[p] = g[p] = b[p] = a[p] = 0x0;
  62. /* Create a libcaca bitmap smaller than our pixel buffer, so that we
  63. * display only the interesting part of it */
  64. caca_bitmap = caca_create_bitmap(8, XSIZ - METASIZE, YSIZ - METASIZE,
  65. XSIZ, 0, 0, 0, 0);
  66. /* Set the palette */
  67. caca_set_bitmap_palette(caca_bitmap, r, g, b, a);
  68. /* Generate ball sprite */
  69. create_ball();
  70. for(p = 0; p < METABALLS; p++)
  71. {
  72. d[p] = caca_rand(0, 100);
  73. di[p] = (float)caca_rand(500, 4000) / 6000.0;
  74. dj[p] = (float)caca_rand(500, 4000) / 6000.0;
  75. dk[p] = (float)caca_rand(500, 4000) / 6000.0;
  76. }
  77. /* Go ! */
  78. while(!caca_get_event(CACA_EVENT_KEY_PRESS))
  79. {
  80. /* Silly paths for our balls */
  81. for(p = 0; p < METABALLS; p++)
  82. {
  83. float u = di[p] * i + dj[p] * j + dk[p] * sin(di[p] * k);
  84. float v = d[p] + di[p] * j + dj[p] * k + dk[p] * sin(dk[p] * i);
  85. u = sin(i + u * 2.1) * (1.0 + sin(u));
  86. v = sin(j + v * 1.9) * (1.0 + sin(v));
  87. x[p] = (XSIZ - METASIZE) / 2 + u * (XSIZ - METASIZE) / 4;
  88. y[p] = (YSIZ - METASIZE) / 2 + v * (YSIZ - METASIZE) / 4;
  89. }
  90. i += 0.011;
  91. j += 0.017;
  92. k += 0.019;
  93. memset(pixels, 0, XSIZ * YSIZ);
  94. /* Here is all the trick. Maybe if you're that
  95. * clever you'll understand. */
  96. for(p = 0; p < METABALLS; p++)
  97. draw_ball(x[p], y[p]);
  98. /* Draw our virtual buffer to screen, letting libcaca resize it */
  99. caca_draw_bitmap(0, 0, caca_get_width() - 1, caca_get_height() - 1,
  100. caca_bitmap, pixels + (METASIZE / 2) * (1 + XSIZ));
  101. caca_refresh();
  102. }
  103. /* End, bye folks */
  104. caca_end();
  105. return 0;
  106. }
  107. /* Generate ball sprite
  108. * You should read the comments, I already wrote that before ... */
  109. static void create_ball(void)
  110. {
  111. int x, y;
  112. float distance;
  113. for(y = 0; y < METASIZE; y++)
  114. for(x = 0; x < METASIZE; x++)
  115. {
  116. distance = ((METASIZE/2) - x) * ((METASIZE/2) - x)
  117. + ((METASIZE/2) - y) * ((METASIZE/2) - y);
  118. distance = sqrt(distance) * 64 / METASIZE;
  119. metaball[x + y * METASIZE] = distance > 15 ? 0 : (255 - distance) * 15;
  120. }
  121. }
  122. /* You missed the trick ? */
  123. static void draw_ball(unsigned int bx, unsigned int by)
  124. {
  125. unsigned int color;
  126. unsigned int i, e = 0;
  127. unsigned int b = (by * XSIZ) + bx;
  128. for(i = 0; i < METASIZE * METASIZE; i++)
  129. {
  130. color = pixels[b] + metaball[i];
  131. if(color > 255)
  132. color = 255;
  133. pixels[b] = color;
  134. if(e == METASIZE)
  135. {
  136. e = 0;
  137. b += XSIZ - METASIZE;
  138. }
  139. b++;
  140. e++;
  141. }
  142. }