http://ftp.x.org/contrib/applications/xscreensaver-3.24.tar.gz
[xscreensaver] / hacks / xflame.c
index c32e6a5f0103cf47ca947f9f4116c777537a4f7b..2e569e07cb959ea3be9ae81dca8dbcd3271d45c7 100644 (file)
@@ -38,6 +38,9 @@
          behavioral constants.
 
        - General cleanup and portability tweaks.
+
+   * 4-Oct-99, jwz: added support for packed-24bpp (versus 32bpp.)
+
  */
 
 
@@ -67,6 +70,8 @@
 # endif /* VMS */
 #endif /* HAVE_XMU */
 
+#include "images/bob.xbm"
+
 #define MAX_VAL             255
 
 static Display         *display;
@@ -319,6 +324,55 @@ Flame2Image32(void)
     }
 }
 
+static void
+Flame2Image24(void)
+{
+  int x,y;
+  unsigned char *ptr;
+  unsigned char *ptr1;
+  int v1,v2,v3,v4;
+
+  ptr  = (unsigned char *)xim->data;
+  ptr += (top << 1) * xim->bytes_per_line;
+  ptr1 = flame + 1 + (top * (fwidth + 2));
+
+  for( y = top; y < fheight; y++)
+    {
+      unsigned char *last_ptr = ptr;
+      for( x = 0; x < fwidth; x++)
+        {
+          v1 = (int)*ptr1;
+          v2 = (int)*(ptr1 + 1);
+          v3 = (int)*(ptr1 + fwidth + 2);
+          v4 = (int)*(ptr1 + fwidth + 2 + 1);
+          ptr1++;
+
+          ptr[2] = ((unsigned int)ctab[v1] & 0x00FF0000) >> 16;
+          ptr[1] = ((unsigned int)ctab[v1] & 0x0000FF00) >> 8;
+          ptr[0] = ((unsigned int)ctab[v1] & 0x000000FF);
+          ptr += 3;
+
+          ptr[2] = ((unsigned int)ctab[(v1 + v2) >> 1] & 0x00FF0000) >> 16;
+          ptr[1] = ((unsigned int)ctab[(v1 + v2) >> 1] & 0x0000FF00) >> 8;
+          ptr[0] = ((unsigned int)ctab[(v1 + v2) >> 1] & 0x000000FF);
+          ptr += ((width - 1) * 3);
+
+          ptr[2] = ((unsigned int)ctab[(v1 + v3) >> 1] & 0x00FF0000) >> 16;
+          ptr[1] = ((unsigned int)ctab[(v1 + v3) >> 1] & 0x0000FF00) >> 8;
+          ptr[0] = ((unsigned int)ctab[(v1 + v3) >> 1] & 0x000000FF);
+          ptr += 3;
+
+          ptr[2] = ((unsigned int)ctab[(v1 + v4) >> 1] & 0x00FF0000) >> 16;
+          ptr[1] = ((unsigned int)ctab[(v1 + v4) >> 1] & 0x0000FF00) >> 8;
+          ptr[0] = ((unsigned int)ctab[(v1 + v4) >> 1] & 0x000000FF);
+          ptr -= ((width - 1) * 3);
+        }
+
+      ptr = last_ptr + (xim->bytes_per_line << 1);
+      ptr1 += 2;
+    }
+}
+
 static void
 Flame2Image8(void)
 {
@@ -381,14 +435,22 @@ Flame2Image1234567(void)
 static void
 Flame2Image(void)
 {
-  if (depth >= 24)      Flame2Image32();
-  else if (depth == 16) Flame2Image16();
-  else if (depth == 8)  Flame2Image8();
-  else if (depth == 15) Flame2Image16(); 
-  else if (depth <  8)  Flame2Image1234567();
-  else if (depth == 12) Flame2Image16();
+  switch (xim->bits_per_pixel)
+    {
+    case 32: Flame2Image32(); break;
+    case 24: Flame2Image24(); break;
+    case 16: Flame2Image16(); break;
+    case 8:  Flame2Image8();  break;
+    default:
+      if (xim->bits_per_pixel <= 7)
+        Flame2Image1234567();
+      else
+        abort();
+      break;
+    }
 }
 
+
 static void
 FlameActive(void)
 {
@@ -543,9 +605,33 @@ loadBitmap(int *w, int *h)
 {
   char *bitmap_name = get_string_resource ("bitmap", "Bitmap");
 
-  if (bitmap_name &&
-      *bitmap_name &&
-      !!strcmp(bitmap_name, "none"))
+  if (!bitmap_name ||
+      !*bitmap_name ||
+      !strcmp(bitmap_name, "none"))
+    ;
+  else if (!strcmp(bitmap_name, "(default)"))   /* use the builtin */
+    {
+      XImage *ximage;
+      unsigned char *result, *o;
+      char *bits = (char *) malloc (sizeof(bob_bits));
+      int x, y;
+      int scale = ((width > bob_width * 11) ? 2 : 1);
+      memcpy (bits, bob_bits, sizeof(bob_bits));
+      ximage = XCreateImage (display, visual, 1, XYBitmap, 0, bits,
+                             bob_width, bob_height, 8, 0);
+      ximage->byte_order = LSBFirst;
+      ximage->bitmap_bit_order = LSBFirst;
+      *w = ximage->width * scale;
+      *h = ximage->height * scale;
+      o = result = (unsigned char *) malloc ((*w * scale) * (*h * scale));
+      for (y = 0; y < *h; y++)
+        for (x = 0; x < *w; x++)
+          *o++ = (XGetPixel(ximage, x/scale, y/scale) ? 255 : 0);
+       
+      return result;
+    }
+  else  /* load a bitmap file */
     {
 #ifdef HAVE_XPM
       XpmInfo xpm_info = { 0, };
@@ -671,7 +757,7 @@ char *progclass = "XFlame";
 char *defaults [] = {
   ".background:     black",
   ".foreground:     #FFAF5F",
-  "*bitmap:         none",
+  "*bitmap:         (default)",
   "*bitmapBaseline: 20",
   "*delay:          10000",
   "*hspread:        30",