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.
 
 
 
 
 
 

160 lines
4.3 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 128
  33. static void create_ball(void);
  34. static void draw_ball(unsigned int, unsigned int);
  35. static unsigned char pixels[XSIZ * YSIZ];
  36. static unsigned char metaball[METASIZE * METASIZE];
  37. int main(int argc, char **argv)
  38. {
  39. struct caca_bitmap *caca_bitmap;
  40. float i = 0, j = 0, k = 0;
  41. int p;
  42. unsigned int x[5], y[5];
  43. int r[256], g[256], b[256], a[256];
  44. if(caca_init())
  45. return 1;
  46. caca_set_delay(0);
  47. /* Make the palette eatable by libcaca */
  48. for(p = 0; p < 256; p++)
  49. {
  50. r[p] = p < 0xc0 ? 0 : (p - 0xc0) * 0x40;
  51. g[p] = p < 0x40 ? 0 : p < 0xc0 ? (p - 0x40) * 0x20 : 0xfff;
  52. b[p] = p < 0x40 ? p * 0x40 : 0xfff;
  53. a[p] = 0x0;
  54. }
  55. /* Crop the palette */
  56. for(p = 0; p < 150; p++)
  57. r[p] = g[p] = b[p] = a[p] = 0x0;
  58. /* Create the bitmap */
  59. caca_bitmap = caca_create_bitmap(8, XSIZ, YSIZ, XSIZ, 0, 0, 0, 0);
  60. /* Set the palette */
  61. caca_set_bitmap_palette(caca_bitmap, r, g, b, a);
  62. /* Generate ball sprite */
  63. create_ball();
  64. /* Go ! */
  65. while(!caca_get_event(CACA_EVENT_KEY_PRESS))
  66. {
  67. /* Silly paths for our balls */
  68. x[0] = (1 + sin(i + k)) * (XSIZ-METASIZE) / 2;
  69. y[0] = (1 + cos(1 + j)) * (YSIZ-METASIZE) / 2;
  70. x[1] = (1 + cos(2 + j * 2 + k)) * (XSIZ-METASIZE) / 2;
  71. y[1] = (1 + cos(3 + i / 2 + j)) * (YSIZ-METASIZE) / 2;
  72. x[2] = (1 + cos(4 + k * 2)) * (XSIZ-METASIZE) / 2;
  73. y[2] = (1 + cos(i + j / 2)) * (YSIZ-METASIZE) / 2;
  74. x[3] = (1 + sin(6 + j * 2)) * (XSIZ-METASIZE) / 2;
  75. y[3] = (1 + cos(7 + i / 2)) * (YSIZ-METASIZE) / 2;
  76. x[4] = (1 + cos(i - k / 2)) * (XSIZ-METASIZE) / 2;
  77. y[4] = (1 + sin(i + k / 2)) * (YSIZ-METASIZE) / 2;
  78. i += 0.011;
  79. j += 0.021;
  80. k += 0.029;
  81. memset(pixels, 0, XSIZ * YSIZ);
  82. /* Here is all the trick. Maybe if you're that
  83. * clever you'll understand. */
  84. for(p = 0; p < 5; p++)
  85. draw_ball(x[p], y[p]);
  86. /* Draw our virtual buffer to screen, letting libcaca resize it */
  87. caca_draw_bitmap(-10, -10, caca_get_width() + 9, caca_get_height() + 9,
  88. caca_bitmap, pixels);
  89. caca_refresh();
  90. }
  91. /* End, bye folks */
  92. caca_end();
  93. return 0;
  94. }
  95. /* Generate ball sprite
  96. * You should read the comments, I already wrote that before ... */
  97. static void create_ball(void)
  98. {
  99. int x, y;
  100. float distance;
  101. for(y = 0; y < METASIZE; y++)
  102. for(x = 0; x < METASIZE; x++)
  103. {
  104. distance = ((METASIZE/2) - x) * ((METASIZE/2) - x)
  105. + ((METASIZE/2) - y) * ((METASIZE/2) - y);
  106. distance = sqrt(distance) * 64 / METASIZE;
  107. metaball[x + y * METASIZE] = distance > 15 ? 0 : (255 - distance) * 15;
  108. }
  109. }
  110. /* You missed the trick ? */
  111. static void draw_ball(unsigned int bx, unsigned int by)
  112. {
  113. unsigned int color;
  114. unsigned int i, e = 0;
  115. unsigned int b = (by * XSIZ) + bx;
  116. for(i = 0; i < METASIZE * METASIZE; i++)
  117. {
  118. color = pixels[b] + metaball[i];
  119. if(color > 255)
  120. color = 255;
  121. pixels[b] = color;
  122. if(e == METASIZE)
  123. {
  124. e = 0;
  125. b += XSIZ - METASIZE;
  126. }
  127. b++;
  128. e++;
  129. }
  130. }