rnd-19980904-1
authorHolger Schemel <info@artsoft.org>
Fri, 4 Sep 1998 02:06:03 +0000 (04:06 +0200)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:30:31 +0000 (10:30 +0200)
25 files changed:
src/Makefile
src/events.c
src/events.h
src/files.c
src/game.c
src/gfxload.c [new file with mode: 0644]
src/gfxload.h [new file with mode: 0644]
src/gfxloader.c [deleted file]
src/gfxloader.h [deleted file]
src/gif.c [new file with mode: 0644]
src/gif.h [new file with mode: 0644]
src/gifload.c [new file with mode: 0644]
src/gifload.h [new file with mode: 0644]
src/init.c
src/joystick.c
src/main.c
src/main.h
src/new.c [new file with mode: 0644]
src/random.c
src/screens.c
src/send.c [new file with mode: 0644]
src/sound.c
src/sound.h
src/tools.c
src/xli.h [new file with mode: 0644]

index 27bcd6fcb8004d408b9f13477d1428d2577c591d..4edb1937dfeaf2f63ef28d01bb7b38493efe5b99 100644 (file)
@@ -59,7 +59,11 @@ SRCS =       main.c          \
        sound.c         \
        joystick.c      \
        cartoons.c      \
-       gfxloader.c     \
+       gfxload.c       \
+       gifload.c       \
+       gif.c           \
+       send.c          \
+       new.c           \
        random.c
 
 OBJS = main.o          \
@@ -76,7 +80,11 @@ OBJS =       main.o          \
        sound.o         \
        joystick.o      \
        cartoons.o      \
-       gfxloader.o     \
+       gfxload.o       \
+       gifload.o       \
+       gif.o           \
+       send.o          \
+       new.o           \
        random.o
 
 all:   $(OBJS)
index 4fecf14437dd6b978217d74840d7f6fcc37734d0..edce9a9c4ac35ae3a8026938199847e2e3f24c10 100644 (file)
@@ -13,6 +13,7 @@
 ***********************************************************/
 
 #include "events.h"
+#include "init.h"
 #include "screens.h"
 #include "tools.h"
 #include "game.h"
@@ -54,6 +55,9 @@ void EventLoop(void)
        case FocusOut:
          HandleFocusEvent((XFocusChangeEvent *) &event);
          break;
+        case ClientMessage:
+         HandleClientMessageEvent((XClientMessageEvent *) &event);
+         break;
        default:
          break;
       }
@@ -97,6 +101,9 @@ void ClearEventQueue()
       case FocusOut:
        HandleFocusEvent((XFocusChangeEvent *) &event);
        break;
+      case ClientMessage:
+       HandleClientMessageEvent((XClientMessageEvent *) &event);
+       break;
       default:
        break;
     }
@@ -129,6 +136,9 @@ void SleepWhileUnmapped()
       case MapNotify:
        window_unmapped = FALSE;
        break;
+      case ClientMessage:
+       HandleClientMessageEvent((XClientMessageEvent *) &event);
+       break;
       default:
        break;
     }
@@ -218,6 +228,13 @@ void HandleFocusEvent(XFocusChangeEvent *event)
   }
 }
 
+void HandleClientMessageEvent(XClientMessageEvent *event)
+{
+  if ((event->window == window) &&
+      (event->data.l[0] == XInternAtom(display, "WM_DELETE_WINDOW", FALSE)))
+    CloseAll();
+}
+
 void HandleButton(int mx, int my, int button)
 {
   static int old_mx = 0, old_my = 0;
@@ -284,7 +301,9 @@ void HandleKey(KeySym key, int key_status)
     case XK_KP_Left:
 #endif
     case XK_KP_4:
+#ifndef MSDOS
     case XK_J:
+#endif
     case XK_j:
       joy |= JOY_LEFT;
       break;
@@ -293,7 +312,9 @@ void HandleKey(KeySym key, int key_status)
     case XK_KP_Right:
 #endif
     case XK_KP_6:
+#ifndef MSDOS
     case XK_K:
+#endif
     case XK_k:
       joy |= JOY_RIGHT;
       break;
@@ -302,7 +323,9 @@ void HandleKey(KeySym key, int key_status)
     case XK_KP_Up:
 #endif
     case XK_KP_8:
+#ifndef MSDOS
     case XK_I:
+#endif
     case XK_i:
       joy |= JOY_UP;
       break;
@@ -311,7 +334,9 @@ void HandleKey(KeySym key, int key_status)
     case XK_KP_Down:
 #endif
     case XK_KP_2:
+#ifndef MSDOS
     case XK_M:
+#endif
     case XK_m:
       joy |= JOY_DOWN;
       break;
@@ -339,35 +364,47 @@ void HandleKey(KeySym key, int key_status)
     case XK_KP_3:
       joy |= JOY_DOWN | JOY_RIGHT;
       break;
+#ifndef MSDOS
     case XK_S:                 /* Feld entfernen */
+#endif
     case XK_s:
       joy |= JOY_BUTTON_1 | JOY_LEFT;
       break;
+#ifndef MSDOS
     case XK_D:
+#endif
     case XK_d:
       joy |= JOY_BUTTON_1 | JOY_RIGHT;
       break;
+#ifndef MSDOS
     case XK_E:
+#endif
     case XK_e:
       joy |= JOY_BUTTON_1 | JOY_UP;
       break;
+#ifndef MSDOS
     case XK_X:
+#endif
     case XK_x:
       joy |= JOY_BUTTON_1 | JOY_DOWN;
       break;
     case XK_Shift_L:           /* Linker Feuerknopf */
+#ifndef MSDOS
     case XK_Control_L:
     case XK_Alt_L:
     case XK_Meta_L:
+#endif
       joy |= JOY_BUTTON_1;
       break;
     case XK_Shift_R:           /* Rechter Feuerknopf */
+#ifndef MSDOS
     case XK_Control_R:
     case XK_Alt_R:
     case XK_Meta_R:
     case XK_Mode_switch:
     case XK_Multi_key:
     case XK_B:                 /* (Bombe legen) */
+#endif
     case XK_b:
       joy |= JOY_BUTTON_2;
       break;
@@ -500,7 +537,9 @@ void HandleKey(KeySym key, int key_status)
          printf("ScrollStepSize == %d (1/1)\n", ScrollStepSize);
          break;
 
+#ifndef MSDOS
        case XK_Q:
+#endif
        case XK_q:
          Dynamite = 1000;
          break;
@@ -573,6 +612,29 @@ void HandleKey(KeySym key, int key_status)
            Delay(1000000);
          }
 
+         break;
+
+       case XK_z:
+         {
+           static int test_picture_pos = 0;
+
+           printf("test picture %d\n", test_picture_pos);
+
+           XCopyArea(display,test_pix[test_picture_pos],window,gc,
+                     0,0, 100,100,
+                     0,0);
+           /*
+           XCopyArea(display,test_clipmask[test_picture_pos],window,gc,
+                     0,0, 100,100,
+                     100,0);
+                     */
+           XFlush(display);
+           XSync(display,FALSE);
+           Delay(1000000);
+
+           test_picture_pos = (test_picture_pos + 1) % test_picture_count;
+         }
+
          break;
 #endif
 
index 700f8ae26c667df1fb066063ddce5bd60017c37a..88c627d97bc78dca8daface2def81a200c657d50 100644 (file)
@@ -26,6 +26,8 @@ void HandleButtonEvent(XButtonEvent *);
 void HandleMotionEvent(XMotionEvent *);
 void HandleKeyEvent(XKeyEvent *);
 void HandleFocusEvent(XFocusChangeEvent *);
+void HandleClientMessageEvent(XClientMessageEvent *event);
+
 void HandleNoXEvent(void);
 
 void HandleButton(int, int, int);
index bbd282a399dbd1e76e9c984fbf263714600e26cc..9a50079c3598bf5d9cea9dcbba0dd66bd7ecf271 100644 (file)
@@ -221,8 +221,13 @@ void LoadLevelTape(int level_nr)
   char cookie[MAX_FILENAME];
   FILE *file;
 
+#ifndef MSDOS
   sprintf(filename,"%s/%s/%d.tape",
          level_directory,leveldir[leveldir_nr].filename,level_nr);
+#else
+  sprintf(filename,"%s/%s/%d.tap",
+         level_directory,leveldir[leveldir_nr].filename,level_nr);
+#endif
 
   if ((file=fopen(filename,"r")))
   {
@@ -521,8 +526,13 @@ void SaveLevelTape(int level_nr)
   FILE *file;
   BOOL new_tape = TRUE;
 
+#ifndef MSDOS
   sprintf(filename,"%s/%s/%d.tape",
          level_directory,leveldir[leveldir_nr].filename,level_nr);
+#else
+  sprintf(filename,"%s/%s/%d.tap",
+         level_directory,leveldir[leveldir_nr].filename,level_nr);
+#endif
 
   /* Testen, ob bereits eine Aufnahme existiert */
   if ((file=fopen(filename,"r")))
@@ -694,6 +704,7 @@ void LoadJoystickData()
   if (joystick_status==JOYSTICK_OFF)
     return;
 
+#ifndef MSDOS
   if (!(file=fopen(JOYDAT_FILE,"r")))
     return;
 
@@ -716,6 +727,9 @@ void LoadJoystickData()
   fclose(file);
 
   CheckJoystickData();
+#else
+  load_joystick_data(JOYDAT_FILE);
+#endif
 }
 
 void SaveJoystickData()
@@ -726,6 +740,7 @@ void SaveJoystickData()
   if (joystick_status==JOYSTICK_OFF)
     return;
 
+#ifndef MSDOS
   CheckJoystickData();
 
   if (!(file=fopen(JOYDAT_FILE,"w")))
@@ -746,4 +761,8 @@ void SaveJoystickData()
   fclose(file);
 
   chmod(JOYDAT_FILE, JOYDAT_PERMS);
+#else
+  save_joystick_data(JOYDAT_FILE);
+#endif
+
 }
index 424ca530d32b6650498dfe2de6a3cbcb52cbd4d8..802c9f5b7874dd4ae8c5641b9e4468c750f335f6 100644 (file)
@@ -57,12 +57,14 @@ void GetPlayerConfig()
   scroll_delay_on = SETUP_SCROLL_DELAY_ON(player.setup);
   soft_scrolling_on = SETUP_SOFT_SCROLL_ON(player.setup);
 
+#ifndef MSDOS
   if (joystick_nr != old_joystick_nr)
   {
     if (joystick_device)
       close(joystick_device);
     InitJoystick();
   }
+#endif
 }
 
 void InitGame()
@@ -3674,7 +3676,13 @@ void PlaySoundLevel(int x, int y, int sound_nr)
     return;
 
   volume = PSND_MAX_VOLUME;
+#ifndef MSDOS
   stereo = (sx-SCR_FIELDX/2)*12;
+#else
+  stereo = PSND_MIDDLE+(2*sx-(SCR_FIELDX-1))*5;
+  if(stereo > PSND_MAX_RIGHT) stereo = PSND_MAX_RIGHT;
+  if(stereo < PSND_MAX_LEFT) stereo = PSND_MAX_LEFT;
+#endif
 
   if (!IN_SCR_FIELD(sx,sy))
   {
diff --git a/src/gfxload.c b/src/gfxload.c
new file mode 100644 (file)
index 0000000..05e72a1
--- /dev/null
@@ -0,0 +1,1121 @@
+/***********************************************************
+*  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
+*----------------------------------------------------------*
+*  ©1995 Artsoft Development                               *
+*        Holger Schemel                                    *
+*        33659 Bielefeld-Senne                             *
+*        Telefon: (0521) 493245                            *
+*        eMail: aeglos@valinor.owl.de                      *
+*               aeglos@uni-paderborn.de                    *
+*               q99492@pbhrzx.uni-paderborn.de             *
+*----------------------------------------------------------*
+*  gfxload.c                                               *
+***********************************************************/
+
+#ifndef MSDOS
+#include "gfxload.h"
+
+
+
+
+
+
+extern Window                  window;
+extern void Delay(long);
+
+
+
+
+
+
+#ifdef DEBUG
+/*
+#define DEBUG_GIF
+#define DEBUG_ILBM
+*/
+#endif
+
+struct IFF_ILBM_FORM_big_endian
+{
+  char magic_FORM[4];
+  unsigned char chunk_size[4];
+  char magic_ILBM[4];
+};
+
+struct IFF_ILBM_BMHD_big_endian
+{
+  char Width[2], Height[2];
+  char LeftEdge[2], TopEdge[2];
+  char Depth;
+  char Mask;
+  char Compression;
+  char pad1;
+  char transparentColor[2];
+  char xAspect, yAspect;
+  char pageWidth[2], pageHeight[2];
+};
+
+struct IFF_ILBM_BMHD
+{
+  unsigned int Width, Height;
+  int LeftEdge, TopEdge;
+  unsigned int Depth;
+  unsigned int Mask;
+  unsigned int Compression;
+  unsigned char pad1;
+  unsigned int transparentColor;
+  unsigned int xAspect, yAspect;
+  int pageWidth, pageHeight;
+};
+
+static int ConvertXImageDepth(Display *, XImage **);
+static int Read_GIF_to_Pixmap_or_Bitmap(Display *, char *, Pixmap *, int);
+
+#define READ_GIF_TO_BITMAP     0
+#define READ_GIF_TO_PIXMAP     1
+
+int Read_GIF_to_Bitmap(Display *display, char *filename, Pixmap *pixmap)
+{
+  return(Read_GIF_to_Pixmap_or_Bitmap(display, filename,
+                                     pixmap, READ_GIF_TO_BITMAP));
+}
+
+int Read_GIF_to_Pixmap(Display *display, char *filename, Pixmap *pixmap)
+{
+  return(Read_GIF_to_Pixmap_or_Bitmap(display, filename,
+                                     pixmap, READ_GIF_TO_PIXMAP));
+}
+
+int Read_GIF_to_Pixmap_or_Bitmap(Display *display, char *filename,
+                                Pixmap *pixmap, int mode)
+{
+  XImage *image = NULL;
+  Pixmap new_pixmap = 0;
+  int return_code;
+
+  *pixmap = 0;
+  return_code = Read_GIF_to_XImage(display, filename, &image);
+  if (return_code != GIF_Success)
+    return(return_code);
+
+  if (image)
+  {
+    int screen = DefaultScreen(display);
+    Drawable root = RootWindow(display,screen);
+    int depth = DefaultDepth(display, screen);
+    int width = image->width;
+    int height = image->height;
+
+    if (mode == READ_GIF_TO_BITMAP)
+    {
+      int i,x,y;
+      unsigned long black_pixel = BlackPixel(display,screen);
+      int bytes_per_line = (width+7) / 8;
+      int size = bytes_per_line * height;
+      char *data, *ptr;
+
+      data = (char *)malloc(size);
+      if (!data)
+       return(GIF_NoMemory);
+
+      ptr = data;
+      for(i=0;i<size;i++)
+       *ptr++ = 0;
+
+      for(y=0;y<height;y++)
+      {
+       for(x=0;x<width;x++)
+       {
+         if (XGetPixel(image,x,y) == black_pixel)
+           data[y * bytes_per_line + x/8] |= (1 << (x%8));
+       }
+      }
+
+      new_pixmap = XCreateBitmapFromData(display,root,data,width,height);
+      free(data);
+
+      if (!new_pixmap)
+       return(GIF_NoMemory);
+    }
+    else
+    {
+      GC gc;
+      XGCValues gcv;
+
+      if (ConvertXImageDepth(display, &image) != GIF_Success)
+       return(GIF_ColorFailed);
+
+      new_pixmap = XCreatePixmap(display,root,width,height,depth);
+
+      if (!new_pixmap)
+       return(GIF_NoMemory);
+
+      gcv.foreground = BlackPixel(display,screen);
+      gcv.background = WhitePixel(display,screen);
+      gc = XCreateGC(display, root, GCForeground | GCBackground, &gcv);
+      XPutImage(display,new_pixmap,gc,image,0,0,0,0,width,height);
+
+      XFreeGC(display, gc);
+    }
+
+    XDestroyImage(image);
+  }
+
+  *pixmap = new_pixmap;
+  return(return_code);
+}
+
+
+/*
+ * Read_GIF_to_XImage()  -  based strongly on...
+ *
+ * xgifload.c  -  based strongly on...
+ *
+ * gif2ras.c - Converts from a Compuserve GIF (tm) image to a Sun Raster image.
+ *
+ * Copyright (c) 1988, 1989 by Patrick J. Naughton
+ *
+ * Author: Patrick J. Naughton
+ * naughton@wind.sun.com
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and that
+ * both that copyright notice and this permission notice appear in
+ * supporting documentation.
+ *
+ * This file is provided AS IS with no warranties of any kind.  The author
+ * shall have no liability with respect to the infringement of copyrights,
+ * trade secrets or any patents by this file or any part thereof.  In no
+ * event will the author be liable for any lost revenue or profits or
+ * other special, indirect and consequential damages.
+ *
+ */
+
+typedef int boolean;
+typedef unsigned char byte;
+
+static int ReadCode(void);
+static void AddToPixel(byte);
+static int ColorDicking(Display *);
+
+#define NEXTBYTE       (*ptr++)
+#define IMAGESEP       0x2c
+#define INTERLACEMASK  0x40
+#define COLORMAPMASK   0x80
+
+static
+int BitOffset,                 /* Bit Offset of next code */
+    XC, YC,                    /* Output X and Y coords of current pixel */
+    Pass,                      /* Used by output routine if interlaced pic */
+    OutCount,                  /* Decompressor output 'stack count' */
+    RWidth, RHeight,           /* screen dimensions */
+    Width, Height,             /* image dimensions */
+    LeftOfs, TopOfs,           /* image offset */
+    BitsPerPixel,              /* Bits per pixel, read from GIF header */
+    BytesPerScanline,          /* bytes per scanline in output raster */
+    ColorMapSize,              /* number of colors */
+    Background,                        /* background color */
+    CodeSize,                  /* Code size, read from GIF header */
+    InitCodeSize,              /* Starting code size, used during Clear */
+    Code,                      /* Value returned by ReadCode */
+    MaxCode,                   /* limiting value for current code size */
+    ClearCode,                 /* GIF clear code */
+    EOFCode,                   /* GIF end-of-information code */
+    CurCode, OldCode, InCode,  /* Decompressor variables */
+    FirstFree,                 /* First free code, generated per GIF spec */
+    FreeCode,                  /* Decompressor, next free slot in hash table*/
+    FinChar,                   /* Decompressor variable */
+    BitMask,                   /* AND mask for data size */
+    ReadMask;                  /* Code AND mask for current code size */
+
+static boolean Interlace, HasColormap;
+
+static byte *ImageData;                /* The result array */
+static byte *RawGIF;           /* The heap array to hold it, raw */
+static byte *Raster;           /* The raster data stream, unblocked */
+
+/* The color map, read from the GIF header */
+static byte Red[256], Green[256], Blue[256], used[256];
+static int  numused;
+
+extern char *progname;
+
+static int numcols;
+static unsigned long cols[256];
+static XColor defs[256];
+
+int Read_GIF_to_XImage(Display *display, char *filename, XImage **image)
+{
+  int filesize;
+  register byte ch, ch1;
+  register byte *ptr, *ptr1;
+  register int i;
+  int screen = DefaultScreen(display);
+  Visual *visual = DefaultVisual(display,screen);
+  XImage *new_image = NULL;
+  char *id = "GIF87a";
+  FILE *file;
+  int Prefix[4096];    /* The hash table used by the decompressor */
+  int Suffix[4096];
+  int OutCode[1025];   /* An output array used by the decompressor */
+
+  BitOffset = XC = YC = Pass = OutCount = 0;
+  *image = NULL;
+
+  if (strcmp(filename,"-")==0)
+  {
+    file = stdin;
+    filename = "<stdin>";
+  }
+  else
+    file = fopen(filename,"r");
+
+  if (!file)
+    return(GIF_OpenFailed);
+
+  /* find the size of the file */
+  fseek(file, 0L, 2);
+  filesize = ftell(file);
+  fseek(file, 0L, 0);
+
+  if (!(ptr = RawGIF = (byte *) malloc(filesize)))
+    return(GIF_NoMemory);
+
+  if (!(Raster = (byte *) malloc(filesize)))
+    return(GIF_NoMemory);
+
+  if (fread(ptr, filesize, 1, file) != 1)
+    return(GIF_ReadFailed);
+
+  if (strncmp(ptr, id, 6))
+    return(GIF_FileInvalid);
+
+  ptr += 6;
+
+  /* Get variables from the GIF screen descriptor */
+
+  ch = NEXTBYTE;
+  RWidth = ch + 0x100 * NEXTBYTE;    /* screen dimensions... not used. */
+  ch = NEXTBYTE;
+  RHeight = ch + 0x100 * NEXTBYTE;
+
+  ch = NEXTBYTE;
+  HasColormap = ((ch & COLORMAPMASK) ? True : False);
+
+  BitsPerPixel = (ch & 7) + 1;
+  numcols = ColorMapSize = 1 << BitsPerPixel;
+  BitMask = ColorMapSize - 1;
+
+  Background = NEXTBYTE;             /* background color... not used. */
+
+  if (NEXTBYTE)              /* supposed to be NULL */
+    return(GIF_FileInvalid);
+
+  /* Read in global colormap. */
+
+  if (HasColormap)
+  {
+    for (i = 0; i < ColorMapSize; i++)
+    {
+      Red[i] = NEXTBYTE;
+      Green[i] = NEXTBYTE;
+      Blue[i] = NEXTBYTE;
+      used[i] = 0;
+    }
+    numused = 0;
+  }
+  else
+  {
+    /* no colormap in GIF file */
+    fprintf(stderr,"%s:  warning!  no colortable in this file.  Winging it.\n",
+           progname);
+    if (!numcols)
+      numcols=256;
+    for (i=0; i<numcols; i++)
+      cols[i] = (unsigned long) i;
+  }
+
+  /* Check for image seperator */
+
+  if (NEXTBYTE != IMAGESEP)
+    return(GIF_FileInvalid);
+
+  /* Now read in values from the image descriptor */
+
+  ch = NEXTBYTE;
+  LeftOfs = ch + 0x100 * NEXTBYTE;
+  ch = NEXTBYTE;
+  TopOfs = ch + 0x100 * NEXTBYTE;
+  ch = NEXTBYTE;
+  Width = ch + 0x100 * NEXTBYTE;
+  ch = NEXTBYTE;
+  Height = ch + 0x100 * NEXTBYTE;
+  Interlace = ((NEXTBYTE & INTERLACEMASK) ? True : False);
+
+#ifdef DEBUG_GIF
+  fprintf(stderr, "%s:\n", filename);
+  fprintf(stderr, "   %dx%d, %d bpp / %d colors, %sinterlaced\n",
+         Width,Height, BitsPerPixel,ColorMapSize,(Interlace ? "" : "non-"));
+  fprintf(stderr, "   Reading file... ");
+#endif
+
+  /* Note that I ignore the possible existence of a local color map.
+   * I'm told there aren't many files around that use them, and the spec
+   * says it's defined for future use.  This could lead to an error
+   * reading some files. 
+   */
+
+  /* Start reading the raster data. First we get the intial code size
+   * and compute decompressor constant values, based on this code size.
+   */
+
+  CodeSize = NEXTBYTE;
+  ClearCode = (1 << CodeSize);
+  EOFCode = ClearCode + 1;
+    FreeCode = FirstFree = ClearCode + 2;
+
+  /* The GIF spec has it that the code size is the code size used to
+   * compute the above values is the code size given in the file, but the
+   * code size used in compression/decompression is the code size given in
+   * the file plus one. (thus the ++).
+   */
+
+  CodeSize++;
+  InitCodeSize = CodeSize;
+  MaxCode = (1 << CodeSize);
+  ReadMask = MaxCode - 1;
+
+  /* Read the raster data.  Here we just transpose it from the GIF array
+   * to the Raster array, turning it from a series of blocks into one long
+   * data stream, which makes life much easier for ReadCode().
+   */
+
+  ptr1 = Raster;
+  do
+  {
+    ch = ch1 = NEXTBYTE;
+    while (ch--) *ptr1++ = NEXTBYTE;
+    if ((Raster - ptr1) > filesize)
+      return(GIF_FileInvalid);
+  }
+  while(ch1);
+
+  free(RawGIF);              /* We're done with the raw data now... */
+
+#ifdef DEBUG_GIF
+  fprintf(stderr, "done\n");
+  fprintf(stderr, "   Decompressing... ");
+#endif
+
+  /* Allocate the X Image */
+  ImageData = (byte *) malloc(Width*Height);
+  if (!ImageData)
+    return(GIF_NoMemory);
+
+  new_image = XCreateImage(display,visual,8,ZPixmap,0,ImageData,
+                          Width,Height,8,Width);
+  if (!new_image)
+    return(GIF_NoMemory);
+
+  BytesPerScanline = Width;
+
+
+  /* Decompress the file, continuing until you see the GIF EOF code.
+   * One obvious enhancement is to add checking for corrupt files here.
+   */
+
+  Code = ReadCode();
+  while (Code != EOFCode)
+  {
+    /* Clear code sets everything back to its initial value, then reads the
+     * immediately subsequent code as uncompressed data.
+     */
+
+    if (Code == ClearCode)
+    {
+      CodeSize = InitCodeSize;
+      MaxCode = (1 << CodeSize);
+      ReadMask = MaxCode - 1;
+      FreeCode = FirstFree;
+      CurCode = OldCode = Code = ReadCode();
+      FinChar = CurCode & BitMask;
+      AddToPixel(FinChar);
+    }
+    else
+    {
+      /* If not a clear code, then must be data:
+       * save same as CurCode and InCode
+       */
+
+      CurCode = InCode = Code;
+
+      /* If greater or equal to FreeCode, not in the hash table yet;
+       * repeat the last character decoded
+       */
+
+      if (CurCode >= FreeCode)
+      {
+       CurCode = OldCode;
+       OutCode[OutCount++] = FinChar;
+      }
+
+      /* Unless this code is raw data, pursue the chain pointed to by CurCode
+       * through the hash table to its end; each code in the chain puts its
+       * associated output code on the output queue.
+       */
+
+      while (CurCode > BitMask)
+      {
+       if (OutCount > 1024)
+         return(GIF_FileInvalid);
+
+       OutCode[OutCount++] = Suffix[CurCode];
+       CurCode = Prefix[CurCode];
+      }
+
+      /* The last code in the chain is treated as raw data. */
+
+      FinChar = CurCode & BitMask;
+      OutCode[OutCount++] = FinChar;
+
+      /* Now we put the data out to the Output routine.
+       * It's been stacked LIFO, so deal with it that way...
+       */
+
+      for (i = OutCount - 1; i >= 0; i--)
+       AddToPixel(OutCode[i]);
+      OutCount = 0;
+
+      /* Build the hash table on-the-fly. No table is stored in the file. */
+
+      Prefix[FreeCode] = OldCode;
+      Suffix[FreeCode] = FinChar;
+      OldCode = InCode;
+
+      /* Point to the next slot in the table.  If we exceed the current
+       * MaxCode value, increment the code size unless it's already 12.  If it
+       * is, do nothing: the next code decompressed better be CLEAR
+       */
+
+      FreeCode++;
+      if (FreeCode >= MaxCode)
+      {
+       if (CodeSize < 12)
+       {
+         CodeSize++;
+         MaxCode *= 2;
+         ReadMask = (1 << CodeSize) - 1;
+       }
+      }
+    }
+    Code = ReadCode();
+  }
+
+  free(Raster);
+
+#ifdef DEBUG_GIF
+  fprintf(stderr, "done\n");
+  fprintf(stderr,"   %d colors used\n",numused);
+#endif
+
+  if (file != stdin)
+    fclose(file);
+
+  if (ColorDicking(display) != GIF_Success)
+    return(GIF_ColorFailed);
+
+  *image = new_image;
+  return(GIF_Success);
+}
+
+
+/* Fetch the next code from the raster data stream.  The codes can be
+ * any length from 3 to 12 bits, packed into 8-bit bytes, so we have to
+ * maintain our location in the Raster array as a BIT Offset.  We compute
+ * the byte Offset into the raster array by dividing this by 8, pick up
+ * three bytes, compute the bit Offset into our 24-bit chunk, shift to
+ * bring the desired code to the bottom, then mask it off and return it. 
+ */
+
+static int ReadCode()
+{
+  int RawCode, ByteOffset;
+
+  ByteOffset = BitOffset / 8;
+  RawCode = Raster[ByteOffset] + (0x100 * Raster[ByteOffset + 1]);
+  if (CodeSize >= 8)
+    RawCode += (0x10000 * Raster[ByteOffset + 2]);
+  RawCode >>= (BitOffset % 8);
+  BitOffset += CodeSize;
+  return(RawCode & ReadMask);
+}
+
+
+static void AddToPixel(byte Index)
+{
+  if (YC<Height)
+    *(ImageData + YC * BytesPerScanline + XC) = Index;
+
+  if (!used[Index])
+  {
+    used[Index]=1;
+    numused++;
+  }
+
+  /* Update the X-coordinate, and if it overflows, update the Y-coordinate */
+
+  if (++XC == Width)
+  {
+    /* If a non-interlaced picture, just increment YC to the next scan line. 
+     * If it's interlaced, deal with the interlace as described in the GIF
+     * spec.  Put the decoded scan line out to the screen if we haven't gone
+     * past the bottom of it
+     */
+
+    XC = 0;
+    if (!Interlace)
+      YC++;
+    else
+    {
+      switch (Pass)
+      {
+       case 0:
+         YC += 8;
+         if (YC >= Height)
+         {
+           Pass++;
+           YC = 4;
+         }
+         break;
+
+       case 1:
+         YC += 8;
+         if (YC >= Height)
+         {
+           Pass++;
+           YC = 2;
+         }
+         break;
+
+       case 2:
+         YC += 4;
+         if (YC >= Height)
+         {
+           Pass++;
+           YC = 1;
+         }
+         break;
+
+       case 3:
+         YC += 2;
+         break;
+
+       default:
+         break;
+       }
+    }
+  }
+}
+
+
+static int ColorDicking(Display *display)
+{
+  /* we've got the picture loaded, we know what colors are needed. get 'em */
+
+  register int i,j;
+  static byte lmasks[8] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80};
+  byte lmask, *ptr;
+  int screen = DefaultScreen(display);
+  Colormap cmap = DefaultColormap(display,screen);
+  int dispcells = DisplayCells(display,screen);
+
+  int strip = 0;
+  int nostrip = 0; 
+
+  if (!HasColormap)
+    return(GIF_Success);
+  /* no need to allocate any colors if no colormap in GIF file */
+
+  /* Allocate the X colors for this picture */
+
+  if (nostrip)
+  {
+    /* nostrip was set.  try REAL hard to do it */
+    for (i=j=0; i<numcols; i++)
+    {
+      if (used[i])
+      {
+       defs[i].red   = Red[i]<<8;
+       defs[i].green = Green[i]<<8;
+       defs[i].blue  = Blue[i]<<8;
+       defs[i].flags = DoRed | DoGreen | DoBlue;
+       if (!XAllocColor(display,cmap,&defs[i]))
+       { 
+         j++;
+         defs[i].pixel = 0xffff;
+       }
+       cols[i] = defs[i].pixel;
+      }
+    }
+
+    if (j)
+    {
+      /* failed to pull it off */
+
+      XColor ctab[256];
+      int dc;
+
+      dc = (dispcells<256) ? dispcells : 256;
+
+      fprintf(stderr,
+             "failed to allocate %d out of %d colors.  Trying extra hard.\n",
+             j,numused);
+
+      /* read in the color table */
+      for (i=0; i<dc; i++)
+       ctab[i].pixel = i;
+      XQueryColors(display,cmap,ctab,dc);
+                
+      /* run through the used colors.  any used color that has a pixel
+        value of 0xffff wasn't allocated.  for such colors, run through
+        the entire X colormap and pick the closest color */
+
+      for (i=0; i<numcols; i++)
+       if (used[i] && cols[i]==0xffff)
+       {
+         /* an unallocated pixel */
+
+         int d, mdist, close;
+         unsigned long r,g,b;
+
+         mdist = 100000;   close = -1;
+         r =  Red[i];
+         g =  Green[i];
+         b =  Blue[i];
+         for (j=0; j<dc; j++)
+         {
+           d = abs(r - (ctab[j].red>>8)) +
+             abs(g - (ctab[j].green>>8)) +
+               abs(b - (ctab[j].blue>>8));
+           if (d<mdist)
+           {
+             mdist=d;
+             close=j;
+           }
+         }
+
+         if (close<0)
+           return(GIF_ColorFailed);
+
+         bcopy(&defs[close],&defs[i],sizeof(XColor));
+         cols[i] = ctab[close].pixel;
+       }
+    }  /* end 'failed to pull it off' */
+  }
+  else
+  {
+    /* strip wasn't set, do the best auto-strip */
+
+    j = 0;
+    while (strip<8)
+    {
+      lmask = lmasks[strip];
+      for (i=0; i<numcols; i++)
+      {
+       if (used[i])
+       {
+         defs[i].red   = (Red[i]  &lmask)<<8;
+         defs[i].green = (Green[i]&lmask)<<8;
+         defs[i].blue  = (Blue[i] &lmask)<<8;
+         defs[i].flags = DoRed | DoGreen | DoBlue;
+         if (!XAllocColor(display,cmap,&defs[i]))
+           break;
+         cols[i] = defs[i].pixel;
+       }
+      }
+
+      if (i<numcols)
+      {
+       /* failed */
+       strip++;
+       j++;
+       for (i--; i>=0; i--)
+         if (used[i])
+           XFreeColors(display,cmap,cols+i,1,0L);
+      }
+      else
+       break;
+    }
+
+#ifdef DEBUG_GIF
+    if (j && strip<8)
+      fprintf(stderr,"%s: stripped %d bits\n",progname,strip);
+#endif
+
+    if (strip==8)
+    {
+      fprintf(stderr,"UTTERLY failed to allocate the desired colors.\n");
+      for (i=0; i<numcols; i++) cols[i]=i;
+    }
+  }
+
+  ptr = ImageData;
+  for (i=0; i<Height; i++)
+    for (j=0; j<Width; j++,ptr++) 
+      *ptr = (byte) cols[*ptr];
+
+  return(GIF_Success);
+}
+
+
+/******************************************************************************
+ *  This makes sure the display's depth is the same as the
+ * depth of the default 8 bit image.  If not, we build a new image
+ * that has the correct depth.  This works on the fact that
+ * the color mapper has already changed every pixel value in the
+ * image into the proper number of bits (to fit into the pallet)
+ * so we can just chop down the number of bits.
+ *   This changes the global variable 'expImage' if necessary.
+ */
+
+static int ConvertXImageDepth(Display *display, XImage **image)
+{
+  int screen = DefaultScreen(display);
+  int depth = DefaultDepth(display, screen);
+
+
+
+
+
+
+  printf("ConvertXImageDepth:\n");
+  printf("(*image)->depth == %d\n",
+        (*image)->depth);
+  printf("DefaultDepth(display, screen) == %d\n",
+        DefaultDepth(display, screen));
+
+
+
+
+  if ((*image)->depth != depth)
+  {
+    XImage *old_image, *new_image;
+
+    Visual *visual = DefaultVisual(display,screen);
+
+    int width = (*image)->width;
+    int height = (*image)->height;
+    register int dwx, dwy;
+    byte *data;
+
+
+
+
+
+    printf("ConvertXImageDepth: ---------> CONVERTING...\n");
+
+
+
+
+
+
+    data = (byte *)malloc(width * height * depth);
+    old_image = *image;
+
+#if 1
+    new_image = XCreateImage(display,visual,depth,
+                            ZPixmap,0,data,width,height,8,0);
+#else
+    new_image = XGetImage(display,RootWindow(display,screen),
+                         0,0,width,height,0xffffffff,ZPixmap);
+#endif
+
+    if (!new_image)
+      return(GIF_NoMemory);
+
+    if (old_image->depth == 8 && new_image->depth == 4)
+    {
+      /* speedup for the most common format change */
+
+      register byte *sptr = (byte *)old_image->data;
+      register byte *dptr = (byte *)new_image->data;
+
+      for (dwy=1; dwy<=height; dwy++)
+      {
+       for (dwx=1; dwx<width; dwx+=2)
+       {
+         *dptr = (*sptr) | (*(sptr+1)<<4);
+         dptr++;
+         sptr+=2;
+       }
+       if (width & 1)
+       {
+         /* if extra pixal at end of line, just move it */
+         *dptr = *sptr;
+         sptr++; dptr++;
+       }
+      }
+    }
+    else       /* other format change than 8 bit -> 4 bit */
+    {
+      unsigned long pixel_value;
+
+      for (dwx=0; dwx<width; dwx++)
+      {
+       for (dwy=0; dwy<height; dwy++)
+       {
+         pixel_value = XGetPixel(old_image, dwx, dwy);
+
+         if (pixel_value > 0xff)
+           printf("pixel = %lx", pixel_value);
+
+         XPutPixel(new_image, dwx, dwy, pixel_value);
+       }
+      }
+    }
+
+    free(old_image->data);
+    old_image->data = NULL;
+    XDestroyImage(old_image);
+
+    *image = new_image;
+  }
+
+  return(GIF_Success);
+}
+
+
+static unsigned long be2long(unsigned char *be) /* big-endian -> long int */
+{
+  return((be[0]<<24) | (be[1]<<16) | (be[2]<<8) | be[3]);
+}
+
+static unsigned short be2short(unsigned char *be) /* big-endian -> short int */
+{
+  return((be[0]<<8) | be[1]);
+}
+
+static struct IFF_ILBM_BMHD *ConvertBMHD(unsigned char *header_data)
+{
+  struct IFF_ILBM_BMHD_big_endian *bmhd_be;
+  struct IFF_ILBM_BMHD *bmhd;
+
+  bmhd_be = (struct IFF_ILBM_BMHD_big_endian *)header_data;
+  bmhd = (struct IFF_ILBM_BMHD *)malloc(sizeof(struct IFF_ILBM_BMHD));
+  if (!bmhd)
+    return(NULL);
+
+  bmhd->Width = be2short(bmhd_be->Width);
+  bmhd->Height = be2short(bmhd_be->Height);
+  bmhd->LeftEdge = be2short(bmhd_be->LeftEdge);
+  bmhd->TopEdge = be2short(bmhd_be->TopEdge);
+  bmhd->Depth = (int)bmhd_be->Depth;
+  bmhd->Mask = (int)bmhd_be->Mask;
+  bmhd->Compression = (int)bmhd_be->Compression;
+  bmhd->pad1 = bmhd_be->pad1;
+  bmhd->transparentColor = be2short(bmhd_be->transparentColor);
+  bmhd->xAspect = (int)bmhd_be->xAspect;
+  bmhd->yAspect = (int)bmhd_be->yAspect;
+  bmhd->pageWidth = be2short(bmhd_be->pageWidth);
+  bmhd->pageHeight = be2short(bmhd_be->pageHeight);
+
+  return(bmhd);
+}
+
+static unsigned char MSBitFirst2LSBitFirst(unsigned char msb_byte)
+{
+  unsigned char lsb_byte = 0;
+  int i;
+
+  for(i=7;i>=0;i--)
+  {
+    lsb_byte |= (msb_byte & 1) << i;
+    msb_byte >>= 1;
+  }
+
+  return(lsb_byte);
+}
+
+int Read_ILBM_to_Bitmap(Display *display, char *filename, Pixmap *pixmap)
+{
+  Pixmap new_pixmap = 0;
+  int screen = DefaultScreen(display);
+  Drawable root = RootWindow(display,screen);
+  struct IFF_ILBM_FORM_big_endian *form_header;
+  struct IFF_ILBM_BMHD *bitmap_header;
+  unsigned long file_len, body_len;
+  unsigned char *file_data, *bitmap_data;
+  unsigned char *file_ptr, *bitmap_ptr, *body_ptr;
+  unsigned char byte_count, byte_value;
+  int i,x,y,z;
+  int width, height, depth;
+  int bytes_per_line, bitmap_size;
+  FILE *file;
+
+  if (!(file = fopen(filename,"r")))
+    return(ILBM_OpenFailed);
+
+  if (fseek(file,0,SEEK_END) < 0)
+  {
+    fclose(file);
+    return(ILBM_ReadFailed);
+  }
+
+  file_len = ftell(file);
+  rewind(file);
+
+  if (!(file_data = (unsigned char *)malloc(file_len)))
+  {
+    fclose(file);
+    return(ILBM_NoMemory);
+  }
+
+  if (fread(file_data,1,file_len,file) != file_len)
+  {
+    free(file_data);
+    fclose(file);
+    return(ILBM_ReadFailed);
+  }
+
+  fclose(file);
+
+  form_header = (struct IFF_ILBM_FORM_big_endian *)file_data;
+
+  if (strncmp(form_header->magic_FORM,"FORM",4) ||
+      file_len != be2long(form_header->chunk_size)+8 ||
+      strncmp(form_header->magic_ILBM,"ILBM",4))
+  {
+#ifdef DEBUG_ILBM
+      printf("%s: IFF chunk 'FORM' and/or 'ILBM' not found.\n",filename);
+#endif
+    free(file_data);
+    return(ILBM_FileInvalid);
+  }
+
+  bitmap_header = NULL;
+  body_ptr = NULL;
+  file_ptr = file_data + 12;
+
+  while(file_ptr < (unsigned char *)(file_data + file_len))
+  {
+    if (!strncmp(file_ptr,"BMHD",4))
+    {
+#ifdef DEBUG_ILBM
+      printf("%s: IFF chunk 'BMHD' found.\n",filename);
+#endif
+      bitmap_header = ConvertBMHD(file_ptr + 8);
+      file_ptr += be2long(file_ptr + 4) + 8;
+      continue;
+    }
+    else if (!strncmp(file_ptr,"BODY",4))
+    {
+#ifdef DEBUG_ILBM
+      printf("%s: IFF chunk 'BODY' found.\n",filename);
+#endif
+      body_ptr = file_ptr + 8;
+      body_len = be2long(file_ptr + 4);
+      file_ptr += be2long(file_ptr + 4) + 8;
+      continue;
+    }
+    else
+    {
+#ifdef DEBUG_ILBM
+      printf("%s: IFF chunk '%c%c%c%c' found (but not used).\n",filename,
+            file_ptr[0],file_ptr[1],file_ptr[2],file_ptr[3]);
+#endif
+      /* other chunk not recognized here */
+      file_ptr += be2long(file_ptr + 4) + 8;
+      continue;
+    }
+  }
+
+  if (!bitmap_header || !body_ptr)
+  {
+#ifdef DEBUG_ILBM
+      printf("%s: IFF chunk 'BMHD' and/or 'BODY' not found.\n",filename);
+#endif
+    free(file_data);
+    return(ILBM_FileInvalid);
+  }
+
+  width = bitmap_header->Width;
+  height = bitmap_header->Height;
+  depth = bitmap_header->Depth;
+
+#ifdef DEBUG_ILBM
+  if (depth > 1)
+    printf("%s: %d bitplanes found; using only the first plane.\n",
+          filename,depth);
+#endif
+
+  bytes_per_line = ((width + 15) / 16) * 2;
+  bitmap_size = bytes_per_line * height;
+
+  bitmap_data = (char *)malloc(bitmap_size);
+  if (!bitmap_data)
+  {
+    free(file_data);
+    free(bitmap_header);
+    return(ILBM_NoMemory);
+  }
+
+  bitmap_ptr = bitmap_data;
+  for(i=0;i<bitmap_size;i++)
+    *bitmap_ptr++ = 0;
+
+  for(y=0;y<height;y++)
+  {
+    /* we only read the first bitplane here to create a black/white bitmap */
+
+    for(z=0;z<depth;z++)
+    {
+      bitmap_ptr = bitmap_data + y * bytes_per_line;
+      x = 0;
+
+      if (!bitmap_header->Compression)
+      {
+       while(x++ < bytes_per_line)
+         *bitmap_ptr++ |= MSBitFirst2LSBitFirst(*body_ptr++);
+      }
+      else
+      {
+       while(x < bytes_per_line)
+       {
+         byte_count = *body_ptr++;
+
+         if (byte_count <= 128)
+         {
+           for(i=0;i<byte_count+1;i++)
+             *bitmap_ptr++ |= MSBitFirst2LSBitFirst(*body_ptr++);
+           x += byte_count + 1;
+         }
+         else
+         {
+           byte_value = *body_ptr++;
+           for(i=0;i<257-byte_count;i++)
+             *bitmap_ptr++ |= MSBitFirst2LSBitFirst(byte_value);
+           x += 257 - byte_count;
+         }
+       }
+      }
+    }
+  }
+
+  bitmap_ptr = bitmap_data;
+  for(i=0;i<bitmap_size;i++)
+    *bitmap_ptr++ ^= 0xff;
+
+  new_pixmap = XCreateBitmapFromData(display,root,bitmap_data,width,height);
+
+  free(file_data);
+  free(bitmap_data);
+  free(bitmap_header);
+
+  if (!new_pixmap)
+    return(ILBM_NoMemory);
+
+  *pixmap = new_pixmap;
+  return(ILBM_Success);
+}
+#endif
diff --git a/src/gfxload.h b/src/gfxload.h
new file mode 100644 (file)
index 0000000..654dacd
--- /dev/null
@@ -0,0 +1,45 @@
+/***********************************************************
+*  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
+*----------------------------------------------------------*
+*  ©1995 Artsoft Development                               *
+*        Holger Schemel                                    *
+*        33659 Bielefeld-Senne                             *
+*        Telefon: (0521) 493245                            *
+*        eMail: aeglos@valinor.owl.de                      *
+*               aeglos@uni-paderborn.de                    *
+*               q99492@pbhrzx.uni-paderborn.de             *
+*----------------------------------------------------------*
+*  gfxload.h                                               *
+***********************************************************/
+
+#ifndef GFXLOAD_H
+#define GFXLOAD_H
+
+#ifndef MSDOS
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#define GIF_Success             0
+#define GIF_OpenFailed         -1
+#define GIF_ReadFailed         -2
+#define        GIF_FileInvalid         -3
+#define GIF_NoMemory           -4
+#define GIF_ColorFailed                -5
+
+#define ILBM_Success            0
+#define ILBM_OpenFailed                -1
+#define ILBM_ReadFailed                -2
+#define        ILBM_FileInvalid        -3
+#define ILBM_NoMemory          -4
+#define ILBM_ColorFailed       -5
+
+int Read_ILBM_to_Bitmap(Display *, char *, Pixmap *);
+int Read_GIF_to_Bitmap(Display *, char *, Pixmap *);
+int Read_GIF_to_Pixmap(Display *, char *, Pixmap *);
+int Read_GIF_to_XImage(Display *, char *, XImage **);
+
+#endif
+#endif
diff --git a/src/gfxloader.c b/src/gfxloader.c
deleted file mode 100644 (file)
index 9a28f43..0000000
+++ /dev/null
@@ -1,1155 +0,0 @@
-/***********************************************************
-*  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
-*----------------------------------------------------------*
-*  ©1995 Artsoft Development                               *
-*        Holger Schemel                                    *
-*        33659 Bielefeld-Senne                             *
-*        Telefon: (0521) 493245                            *
-*        eMail: aeglos@valinor.owl.de                      *
-*               aeglos@uni-paderborn.de                    *
-*               q99492@pbhrzx.uni-paderborn.de             *
-*----------------------------------------------------------*
-*  gfxloader.c                                             *
-***********************************************************/
-
-#include "gfxloader.h"
-
-
-
-
-
-
-extern Window                  window;
-extern void Delay(long);
-
-
-
-
-
-
-#ifdef DEBUG
-/*
-#define DEBUG_GIF
-#define DEBUG_ILBM
-*/
-#endif
-
-struct IFF_ILBM_FORM_big_endian
-{
-  char magic_FORM[4];
-  unsigned char chunk_size[4];
-  char magic_ILBM[4];
-};
-
-struct IFF_ILBM_BMHD_big_endian
-{
-  char Width[2], Height[2];
-  char LeftEdge[2], TopEdge[2];
-  char Depth;
-  char Mask;
-  char Compression;
-  char pad1;
-  char transparentColor[2];
-  char xAspect, yAspect;
-  char pageWidth[2], pageHeight[2];
-};
-
-struct IFF_ILBM_BMHD
-{
-  unsigned int Width, Height;
-  int LeftEdge, TopEdge;
-  unsigned int Depth;
-  unsigned int Mask;
-  unsigned int Compression;
-  unsigned char pad1;
-  unsigned int transparentColor;
-  unsigned int xAspect, yAspect;
-  int pageWidth, pageHeight;
-};
-
-static int ConvertXImageDepth(Display *, XImage **);
-static int Read_GIF_to_Pixmap_or_Bitmap(Display *, char *, Pixmap *, int);
-
-#define READ_GIF_TO_BITMAP     0
-#define READ_GIF_TO_PIXMAP     1
-
-
-int Read_GIF_to_Bitmap(Display *display, char *filename, Pixmap *pixmap)
-{
-  printf("Read_GIF_to_Bitmap\n");
-
-
-
-
-  return(Read_GIF_to_Pixmap_or_Bitmap(display, filename,
-                                     pixmap, READ_GIF_TO_BITMAP));
-}
-
-int Read_GIF_to_Pixmap(Display *display, char *filename, Pixmap *pixmap)
-{
-  printf("Read_GIF_to_Pixmap\n");
-
-
-
-
-  return(Read_GIF_to_Pixmap_or_Bitmap(display, filename,
-                                     pixmap, READ_GIF_TO_PIXMAP));
-}
-
-int Read_GIF_to_Pixmap_or_Bitmap(Display *display, char *filename,
-                                Pixmap *pixmap, int mode)
-{
-  XImage *image = NULL;
-  Pixmap new_pixmap = 0;
-  int return_code;
-
-  *pixmap = 0;
-  return_code = Read_GIF_to_XImage(display, filename, &image);
-  if (return_code != GIF_Success)
-    return(return_code);
-
-  if (image)
-  {
-    int screen = DefaultScreen(display);
-    Drawable root = RootWindow(display,screen);
-    int depth = DefaultDepth(display, screen);
-    int width = image->width;
-    int height = image->height;
-
-    if (mode == READ_GIF_TO_BITMAP)
-    {
-      int i,x,y;
-      unsigned long black_pixel = BlackPixel(display,screen);
-      int bytes_per_line = (width+7) / 8;
-      int size = bytes_per_line * height;
-      char *data, *ptr;
-
-      data = (char *)malloc(size);
-      if (!data)
-       return(GIF_NoMemory);
-
-      ptr = data;
-      for(i=0;i<size;i++)
-       *ptr++ = 0;
-
-      for(y=0;y<height;y++)
-      {
-       for(x=0;x<width;x++)
-       {
-         if (XGetPixel(image,x,y) == black_pixel)
-           data[y * bytes_per_line + x/8] |= (1 << (x%8));
-       }
-      }
-
-      new_pixmap = XCreateBitmapFromData(display,root,data,width,height);
-      free(data);
-
-      if (!new_pixmap)
-       return(GIF_NoMemory);
-    }
-    else
-    {
-      GC gc;
-      XGCValues gcv;
-
-      if (ConvertXImageDepth(display, &image) != GIF_Success)
-       return(GIF_ColorFailed);
-
-      new_pixmap = XCreatePixmap(display,root,width,height,depth);
-
-      if (!new_pixmap)
-       return(GIF_NoMemory);
-
-      gcv.foreground = BlackPixel(display,screen);
-      gcv.background = WhitePixel(display,screen);
-      gc = XCreateGC(display, root, GCForeground | GCBackground, &gcv);
-      XPutImage(display,new_pixmap,gc,image,0,0,0,0,width,height);
-
-
-
-
-
-
-      Delay(1000000);
-
-      XPutImage(display,window,gc,image,0,0,0,0,width,height);
-
-      Delay(3000000);
-
-
-
-
-
-      XFreeGC(display, gc);
-    }
-
-    XDestroyImage(image);
-  }
-
-  *pixmap = new_pixmap;
-  return(return_code);
-}
-
-
-/*
- * Read_GIF_to_XImage()  -  based strongly on...
- *
- * xgifload.c  -  based strongly on...
- *
- * gif2ras.c - Converts from a Compuserve GIF (tm) image to a Sun Raster image.
- *
- * Copyright (c) 1988, 1989 by Patrick J. Naughton
- *
- * Author: Patrick J. Naughton
- * naughton@wind.sun.com
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice appear in
- * supporting documentation.
- *
- * This file is provided AS IS with no warranties of any kind.  The author
- * shall have no liability with respect to the infringement of copyrights,
- * trade secrets or any patents by this file or any part thereof.  In no
- * event will the author be liable for any lost revenue or profits or
- * other special, indirect and consequential damages.
- *
- */
-
-typedef int boolean;
-typedef unsigned char byte;
-
-static int ReadCode(void);
-static void AddToPixel(byte);
-static int ColorDicking(Display *);
-
-#define NEXTBYTE       (*ptr++)
-#define IMAGESEP       0x2c
-#define INTERLACEMASK  0x40
-#define COLORMAPMASK   0x80
-
-static
-int BitOffset,                 /* Bit Offset of next code */
-    XC, YC,                    /* Output X and Y coords of current pixel */
-    Pass,                      /* Used by output routine if interlaced pic */
-    OutCount,                  /* Decompressor output 'stack count' */
-    RWidth, RHeight,           /* screen dimensions */
-    Width, Height,             /* image dimensions */
-    LeftOfs, TopOfs,           /* image offset */
-    BitsPerPixel,              /* Bits per pixel, read from GIF header */
-    BytesPerScanline,          /* bytes per scanline in output raster */
-    ColorMapSize,              /* number of colors */
-    Background,                        /* background color */
-    CodeSize,                  /* Code size, read from GIF header */
-    InitCodeSize,              /* Starting code size, used during Clear */
-    Code,                      /* Value returned by ReadCode */
-    MaxCode,                   /* limiting value for current code size */
-    ClearCode,                 /* GIF clear code */
-    EOFCode,                   /* GIF end-of-information code */
-    CurCode, OldCode, InCode,  /* Decompressor variables */
-    FirstFree,                 /* First free code, generated per GIF spec */
-    FreeCode,                  /* Decompressor, next free slot in hash table*/
-    FinChar,                   /* Decompressor variable */
-    BitMask,                   /* AND mask for data size */
-    ReadMask;                  /* Code AND mask for current code size */
-
-static boolean Interlace, HasColormap;
-
-static byte *ImageData;                /* The result array */
-static byte *RawGIF;           /* The heap array to hold it, raw */
-static byte *Raster;           /* The raster data stream, unblocked */
-
-/* The color map, read from the GIF header */
-static byte Red[256], Green[256], Blue[256], used[256];
-static int  numused;
-
-extern char *progname;
-
-static int numcols;
-static unsigned long cols[256];
-static XColor defs[256];
-
-int Read_GIF_to_XImage(Display *display, char *filename, XImage **image)
-{
-  int filesize;
-  register byte ch, ch1;
-  register byte *ptr, *ptr1;
-  register int i;
-  int screen = DefaultScreen(display);
-  Visual *visual = DefaultVisual(display,screen);
-  XImage *new_image = NULL;
-  char *id = "GIF87a";
-  FILE *file;
-  int Prefix[4096];    /* The hash table used by the decompressor */
-  int Suffix[4096];
-  int OutCode[1025];   /* An output array used by the decompressor */
-
-  BitOffset = XC = YC = Pass = OutCount = 0;
-  *image = NULL;
-
-  if (strcmp(filename,"-")==0)
-  {
-    file = stdin;
-    filename = "<stdin>";
-  }
-  else
-    file = fopen(filename,"r");
-
-  if (!file)
-    return(GIF_OpenFailed);
-
-  /* find the size of the file */
-  fseek(file, 0L, 2);
-  filesize = ftell(file);
-  fseek(file, 0L, 0);
-
-  if (!(ptr = RawGIF = (byte *) malloc(filesize)))
-    return(GIF_NoMemory);
-
-  if (!(Raster = (byte *) malloc(filesize)))
-    return(GIF_NoMemory);
-
-  if (fread(ptr, filesize, 1, file) != 1)
-    return(GIF_ReadFailed);
-
-  if (strncmp(ptr, id, 6))
-    return(GIF_FileInvalid);
-
-  ptr += 6;
-
-  /* Get variables from the GIF screen descriptor */
-
-  ch = NEXTBYTE;
-  RWidth = ch + 0x100 * NEXTBYTE;    /* screen dimensions... not used. */
-  ch = NEXTBYTE;
-  RHeight = ch + 0x100 * NEXTBYTE;
-
-  ch = NEXTBYTE;
-  HasColormap = ((ch & COLORMAPMASK) ? True : False);
-
-  BitsPerPixel = (ch & 7) + 1;
-  numcols = ColorMapSize = 1 << BitsPerPixel;
-  BitMask = ColorMapSize - 1;
-
-  Background = NEXTBYTE;             /* background color... not used. */
-
-  if (NEXTBYTE)              /* supposed to be NULL */
-    return(GIF_FileInvalid);
-
-  /* Read in global colormap. */
-
-  if (HasColormap)
-  {
-    for (i = 0; i < ColorMapSize; i++)
-    {
-      Red[i] = NEXTBYTE;
-      Green[i] = NEXTBYTE;
-      Blue[i] = NEXTBYTE;
-      used[i] = 0;
-    }
-    numused = 0;
-  }
-  else
-  {
-    /* no colormap in GIF file */
-    fprintf(stderr,"%s:  warning!  no colortable in this file.  Winging it.\n",
-           progname);
-    if (!numcols)
-      numcols=256;
-    for (i=0; i<numcols; i++)
-      cols[i] = (unsigned long) i;
-  }
-
-  /* Check for image seperator */
-
-  if (NEXTBYTE != IMAGESEP)
-    return(GIF_FileInvalid);
-
-  /* Now read in values from the image descriptor */
-
-  ch = NEXTBYTE;
-  LeftOfs = ch + 0x100 * NEXTBYTE;
-  ch = NEXTBYTE;
-  TopOfs = ch + 0x100 * NEXTBYTE;
-  ch = NEXTBYTE;
-  Width = ch + 0x100 * NEXTBYTE;
-  ch = NEXTBYTE;
-  Height = ch + 0x100 * NEXTBYTE;
-  Interlace = ((NEXTBYTE & INTERLACEMASK) ? True : False);
-
-#ifdef DEBUG_GIF
-  fprintf(stderr, "%s:\n", filename);
-  fprintf(stderr, "   %dx%d, %d bpp / %d colors, %sinterlaced\n",
-         Width,Height, BitsPerPixel,ColorMapSize,(Interlace ? "" : "non-"));
-  fprintf(stderr, "   Reading file... ");
-#endif
-
-  /* Note that I ignore the possible existence of a local color map.
-   * I'm told there aren't many files around that use them, and the spec
-   * says it's defined for future use.  This could lead to an error
-   * reading some files. 
-   */
-
-  /* Start reading the raster data. First we get the intial code size
-   * and compute decompressor constant values, based on this code size.
-   */
-
-  CodeSize = NEXTBYTE;
-  ClearCode = (1 << CodeSize);
-  EOFCode = ClearCode + 1;
-    FreeCode = FirstFree = ClearCode + 2;
-
-  /* The GIF spec has it that the code size is the code size used to
-   * compute the above values is the code size given in the file, but the
-   * code size used in compression/decompression is the code size given in
-   * the file plus one. (thus the ++).
-   */
-
-  CodeSize++;
-  InitCodeSize = CodeSize;
-  MaxCode = (1 << CodeSize);
-  ReadMask = MaxCode - 1;
-
-  /* Read the raster data.  Here we just transpose it from the GIF array
-   * to the Raster array, turning it from a series of blocks into one long
-   * data stream, which makes life much easier for ReadCode().
-   */
-
-  ptr1 = Raster;
-  do
-  {
-    ch = ch1 = NEXTBYTE;
-    while (ch--) *ptr1++ = NEXTBYTE;
-    if ((Raster - ptr1) > filesize)
-      return(GIF_FileInvalid);
-  }
-  while(ch1);
-
-  free(RawGIF);              /* We're done with the raw data now... */
-
-#ifdef DEBUG_GIF
-  fprintf(stderr, "done\n");
-  fprintf(stderr, "   Decompressing... ");
-#endif
-
-  /* Allocate the X Image */
-  ImageData = (byte *) malloc(Width*Height);
-  if (!ImageData)
-    return(GIF_NoMemory);
-
-  new_image = XCreateImage(display,visual,8,ZPixmap,0,ImageData,
-                          Width,Height,8,Width);
-  if (!new_image)
-    return(GIF_NoMemory);
-
-  BytesPerScanline = Width;
-
-
-  /* Decompress the file, continuing until you see the GIF EOF code.
-   * One obvious enhancement is to add checking for corrupt files here.
-   */
-
-  Code = ReadCode();
-  while (Code != EOFCode)
-  {
-    /* Clear code sets everything back to its initial value, then reads the
-     * immediately subsequent code as uncompressed data.
-     */
-
-    if (Code == ClearCode)
-    {
-      CodeSize = InitCodeSize;
-      MaxCode = (1 << CodeSize);
-      ReadMask = MaxCode - 1;
-      FreeCode = FirstFree;
-      CurCode = OldCode = Code = ReadCode();
-      FinChar = CurCode & BitMask;
-      AddToPixel(FinChar);
-    }
-    else
-    {
-      /* If not a clear code, then must be data:
-       * save same as CurCode and InCode
-       */
-
-      CurCode = InCode = Code;
-
-      /* If greater or equal to FreeCode, not in the hash table yet;
-       * repeat the last character decoded
-       */
-
-      if (CurCode >= FreeCode)
-      {
-       CurCode = OldCode;
-       OutCode[OutCount++] = FinChar;
-      }
-
-      /* Unless this code is raw data, pursue the chain pointed to by CurCode
-       * through the hash table to its end; each code in the chain puts its
-       * associated output code on the output queue.
-       */
-
-      while (CurCode > BitMask)
-      {
-       if (OutCount > 1024)
-         return(GIF_FileInvalid);
-
-       OutCode[OutCount++] = Suffix[CurCode];
-       CurCode = Prefix[CurCode];
-      }
-
-      /* The last code in the chain is treated as raw data. */
-
-      FinChar = CurCode & BitMask;
-      OutCode[OutCount++] = FinChar;
-
-      /* Now we put the data out to the Output routine.
-       * It's been stacked LIFO, so deal with it that way...
-       */
-
-      for (i = OutCount - 1; i >= 0; i--)
-       AddToPixel(OutCode[i]);
-      OutCount = 0;
-
-      /* Build the hash table on-the-fly. No table is stored in the file. */
-
-      Prefix[FreeCode] = OldCode;
-      Suffix[FreeCode] = FinChar;
-      OldCode = InCode;
-
-      /* Point to the next slot in the table.  If we exceed the current
-       * MaxCode value, increment the code size unless it's already 12.  If it
-       * is, do nothing: the next code decompressed better be CLEAR
-       */
-
-      FreeCode++;
-      if (FreeCode >= MaxCode)
-      {
-       if (CodeSize < 12)
-       {
-         CodeSize++;
-         MaxCode *= 2;
-         ReadMask = (1 << CodeSize) - 1;
-       }
-      }
-    }
-    Code = ReadCode();
-  }
-
-  free(Raster);
-
-#ifdef DEBUG_GIF
-  fprintf(stderr, "done\n");
-  fprintf(stderr,"   %d colors used\n",numused);
-#endif
-
-  if (file != stdin)
-    fclose(file);
-
-  if (ColorDicking(display) != GIF_Success)
-    return(GIF_ColorFailed);
-
-  *image = new_image;
-  return(GIF_Success);
-}
-
-
-/* Fetch the next code from the raster data stream.  The codes can be
- * any length from 3 to 12 bits, packed into 8-bit bytes, so we have to
- * maintain our location in the Raster array as a BIT Offset.  We compute
- * the byte Offset into the raster array by dividing this by 8, pick up
- * three bytes, compute the bit Offset into our 24-bit chunk, shift to
- * bring the desired code to the bottom, then mask it off and return it. 
- */
-
-static int ReadCode()
-{
-  int RawCode, ByteOffset;
-
-  ByteOffset = BitOffset / 8;
-  RawCode = Raster[ByteOffset] + (0x100 * Raster[ByteOffset + 1]);
-  if (CodeSize >= 8)
-    RawCode += (0x10000 * Raster[ByteOffset + 2]);
-  RawCode >>= (BitOffset % 8);
-  BitOffset += CodeSize;
-  return(RawCode & ReadMask);
-}
-
-
-static void AddToPixel(byte Index)
-{
-  if (YC<Height)
-    *(ImageData + YC * BytesPerScanline + XC) = Index;
-
-  if (!used[Index])
-  {
-    used[Index]=1;
-    numused++;
-  }
-
-  /* Update the X-coordinate, and if it overflows, update the Y-coordinate */
-
-  if (++XC == Width)
-  {
-    /* If a non-interlaced picture, just increment YC to the next scan line. 
-     * If it's interlaced, deal with the interlace as described in the GIF
-     * spec.  Put the decoded scan line out to the screen if we haven't gone
-     * past the bottom of it
-     */
-
-    XC = 0;
-    if (!Interlace)
-      YC++;
-    else
-    {
-      switch (Pass)
-      {
-       case 0:
-         YC += 8;
-         if (YC >= Height)
-         {
-           Pass++;
-           YC = 4;
-         }
-         break;
-
-       case 1:
-         YC += 8;
-         if (YC >= Height)
-         {
-           Pass++;
-           YC = 2;
-         }
-         break;
-
-       case 2:
-         YC += 4;
-         if (YC >= Height)
-         {
-           Pass++;
-           YC = 1;
-         }
-         break;
-
-       case 3:
-         YC += 2;
-         break;
-
-       default:
-         break;
-       }
-    }
-  }
-}
-
-
-static int ColorDicking(Display *display)
-{
-  /* we've got the picture loaded, we know what colors are needed. get 'em */
-
-  register int i,j;
-  static byte lmasks[8] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80};
-  byte lmask, *ptr;
-  int screen = DefaultScreen(display);
-  Colormap cmap = DefaultColormap(display,screen);
-  int dispcells = DisplayCells(display,screen);
-
-  int strip = 0;
-  int nostrip = 0; 
-
-  if (!HasColormap)
-    return(GIF_Success);
-  /* no need to allocate any colors if no colormap in GIF file */
-
-  /* Allocate the X colors for this picture */
-
-  if (nostrip)
-  {
-    /* nostrip was set.  try REAL hard to do it */
-    for (i=j=0; i<numcols; i++)
-    {
-      if (used[i])
-      {
-       defs[i].red   = Red[i]<<8;
-       defs[i].green = Green[i]<<8;
-       defs[i].blue  = Blue[i]<<8;
-       defs[i].flags = DoRed | DoGreen | DoBlue;
-       if (!XAllocColor(display,cmap,&defs[i]))
-       { 
-         j++;
-         defs[i].pixel = 0xffff;
-       }
-       cols[i] = defs[i].pixel;
-      }
-    }
-
-    if (j)
-    {
-      /* failed to pull it off */
-
-      XColor ctab[256];
-      int dc;
-
-      dc = (dispcells<256) ? dispcells : 256;
-
-      fprintf(stderr,
-             "failed to allocate %d out of %d colors.  Trying extra hard.\n",
-             j,numused);
-
-      /* read in the color table */
-      for (i=0; i<dc; i++)
-       ctab[i].pixel = i;
-      XQueryColors(display,cmap,ctab,dc);
-                
-      /* run through the used colors.  any used color that has a pixel
-        value of 0xffff wasn't allocated.  for such colors, run through
-        the entire X colormap and pick the closest color */
-
-      for (i=0; i<numcols; i++)
-       if (used[i] && cols[i]==0xffff)
-       {
-         /* an unallocated pixel */
-
-         int d, mdist, close;
-         unsigned long r,g,b;
-
-         mdist = 100000;   close = -1;
-         r =  Red[i];
-         g =  Green[i];
-         b =  Blue[i];
-         for (j=0; j<dc; j++)
-         {
-           d = abs(r - (ctab[j].red>>8)) +
-             abs(g - (ctab[j].green>>8)) +
-               abs(b - (ctab[j].blue>>8));
-           if (d<mdist)
-           {
-             mdist=d;
-             close=j;
-           }
-         }
-
-         if (close<0)
-           return(GIF_ColorFailed);
-
-         bcopy(&defs[close],&defs[i],sizeof(XColor));
-         cols[i] = ctab[close].pixel;
-       }
-    }  /* end 'failed to pull it off' */
-  }
-  else
-  {
-    /* strip wasn't set, do the best auto-strip */
-
-    j = 0;
-    while (strip<8)
-    {
-      lmask = lmasks[strip];
-      for (i=0; i<numcols; i++)
-      {
-       if (used[i])
-       {
-         defs[i].red   = (Red[i]  &lmask)<<8;
-         defs[i].green = (Green[i]&lmask)<<8;
-         defs[i].blue  = (Blue[i] &lmask)<<8;
-         defs[i].flags = DoRed | DoGreen | DoBlue;
-         if (!XAllocColor(display,cmap,&defs[i]))
-           break;
-         cols[i] = defs[i].pixel;
-       }
-      }
-
-      if (i<numcols)
-      {
-       /* failed */
-       strip++;
-       j++;
-       for (i--; i>=0; i--)
-         if (used[i])
-           XFreeColors(display,cmap,cols+i,1,0L);
-      }
-      else
-       break;
-    }
-
-#ifdef DEBUG_GIF
-    if (j && strip<8)
-      fprintf(stderr,"%s: stripped %d bits\n",progname,strip);
-#endif
-
-    if (strip==8)
-    {
-      fprintf(stderr,"UTTERLY failed to allocate the desired colors.\n");
-      for (i=0; i<numcols; i++) cols[i]=i;
-    }
-  }
-
-  ptr = ImageData;
-  for (i=0; i<Height; i++)
-    for (j=0; j<Width; j++,ptr++) 
-      *ptr = (byte) cols[*ptr];
-
-  return(GIF_Success);
-}
-
-
-/******************************************************************************
- *  This makes sure the display's depth is the same as the
- * depth of the default 8 bit image.  If not, we build a new image
- * that has the correct depth.  This works on the fact that
- * the color mapper has already changed every pixel value in the
- * image into the proper number of bits (to fit into the pallet)
- * so we can just chop down the number of bits.
- *   This changes the global variable 'expImage' if necessary.
- */
-
-static int ConvertXImageDepth(Display *display, XImage **image)
-{
-  int screen = DefaultScreen(display);
-  int depth = DefaultDepth(display, screen);
-
-
-
-
-
-
-  printf("ConvertXImageDepth:\n");
-  printf("(*image)->depth == %d\n",
-        (*image)->depth);
-  printf("DefaultDepth(display, screen) == %d\n",
-        DefaultDepth(display, screen));
-
-
-
-
-  if ((*image)->depth != depth)
-  {
-    XImage *old_image, *new_image;
-    /*
-    Visual *visual = DefaultVisual(display,screen);
-    */
-    int width = (*image)->width;
-    int height = (*image)->height;
-    register int dwx, dwy;
-    byte *data;
-
-
-
-
-
-    printf("ConvertXImageDepth: ---------> CONVERTING...\n");
-
-
-
-
-
-
-    data = (byte *)malloc(width * height * depth);
-    old_image = *image;
-
-    /*
-    new_image = XCreateImage(display,visual,depth,
-                            ZPixmap,0,data,width,height,8,0);
-                            */
-
-    new_image = XGetImage(display,RootWindow(display,screen),
-                         0,0,width,height,0xffffffff,ZPixmap);
-
-
-    if (!new_image)
-      return(GIF_NoMemory);
-
-    if (old_image->depth == 8 && new_image->depth == 4)
-    {
-      /* speedup for the most common format change */
-
-      register byte *sptr = (byte *)old_image->data;
-      register byte *dptr = (byte *)new_image->data;
-
-      for (dwy=1; dwy<=height; dwy++)
-      {
-       for (dwx=1; dwx<width; dwx+=2)
-       {
-         *dptr = (*sptr) | (*(sptr+1)<<4);
-         dptr++;
-         sptr+=2;
-       }
-       if (width & 1)
-       {
-         /* if extra pixal at end of line, just move it */
-         *dptr = *sptr;
-         sptr++; dptr++;
-       }
-      }
-    }
-    else       /* other format change than 8 bit -> 4 bit */
-    {
-      unsigned long pixel_value;
-
-      for (dwx=0; dwx<width; dwx++)
-      {
-       for (dwy=0; dwy<height; dwy++)
-       {
-         pixel_value = XGetPixel(old_image, dwx, dwy);
-
-         if (pixel_value > 0xff)
-           printf("pixel = %lx", pixel_value);
-
-         XPutPixel(new_image, dwx, dwy, pixel_value);
-       }
-      }
-    }
-
-    free(old_image->data);
-    old_image->data = NULL;
-    XDestroyImage(old_image);
-
-    *image = new_image;
-  }
-
-  return(GIF_Success);
-}
-
-
-static unsigned long be2long(unsigned char *be) /* big-endian -> long int */
-{
-  return((be[0]<<24) | (be[1]<<16) | (be[2]<<8) | be[3]);
-}
-
-static unsigned short be2short(unsigned char *be) /* big-endian -> short int */
-{
-  return((be[0]<<8) | be[1]);
-}
-
-static struct IFF_ILBM_BMHD *ConvertBMHD(unsigned char *header_data)
-{
-  struct IFF_ILBM_BMHD_big_endian *bmhd_be;
-  struct IFF_ILBM_BMHD *bmhd;
-
-  bmhd_be = (struct IFF_ILBM_BMHD_big_endian *)header_data;
-  bmhd = (struct IFF_ILBM_BMHD *)malloc(sizeof(struct IFF_ILBM_BMHD));
-  if (!bmhd)
-    return(NULL);
-
-  bmhd->Width = be2short(bmhd_be->Width);
-  bmhd->Height = be2short(bmhd_be->Height);
-  bmhd->LeftEdge = be2short(bmhd_be->LeftEdge);
-  bmhd->TopEdge = be2short(bmhd_be->TopEdge);
-  bmhd->Depth = (int)bmhd_be->Depth;
-  bmhd->Mask = (int)bmhd_be->Mask;
-  bmhd->Compression = (int)bmhd_be->Compression;
-  bmhd->pad1 = bmhd_be->pad1;
-  bmhd->transparentColor = be2short(bmhd_be->transparentColor);
-  bmhd->xAspect = (int)bmhd_be->xAspect;
-  bmhd->yAspect = (int)bmhd_be->yAspect;
-  bmhd->pageWidth = be2short(bmhd_be->pageWidth);
-  bmhd->pageHeight = be2short(bmhd_be->pageHeight);
-
-  return(bmhd);
-}
-
-static unsigned char MSBitFirst2LSBitFirst(unsigned char msb_byte)
-{
-  unsigned char lsb_byte = 0;
-  int i;
-
-  for(i=7;i>=0;i--)
-  {
-    lsb_byte |= (msb_byte & 1) << i;
-    msb_byte >>= 1;
-  }
-
-  return(lsb_byte);
-}
-
-int Read_ILBM_to_Bitmap(Display *display, char *filename, Pixmap *pixmap)
-{
-  Pixmap new_pixmap = 0;
-  int screen = DefaultScreen(display);
-  Drawable root = RootWindow(display,screen);
-  struct IFF_ILBM_FORM_big_endian *form_header;
-  struct IFF_ILBM_BMHD *bitmap_header;
-  unsigned long file_len, body_len;
-  unsigned char *file_data, *bitmap_data;
-  unsigned char *file_ptr, *bitmap_ptr, *body_ptr;
-  unsigned char byte_count, byte_value;
-  int i,x,y,z;
-  int width, height, depth;
-  int bytes_per_line, bitmap_size;
-  FILE *file;
-
-
-
-
-
-  printf("Read_ILBM_to_Bitmap\n");
-
-
-
-
-  if (!(file = fopen(filename,"r")))
-    return(ILBM_OpenFailed);
-
-  if (fseek(file,0,SEEK_END) < 0)
-  {
-    fclose(file);
-    return(ILBM_ReadFailed);
-  }
-
-  file_len = ftell(file);
-  rewind(file);
-
-  if (!(file_data = (unsigned char *)malloc(file_len)))
-  {
-    fclose(file);
-    return(ILBM_NoMemory);
-  }
-
-  if (fread(file_data,1,file_len,file) != file_len)
-  {
-    free(file_data);
-    fclose(file);
-    return(ILBM_ReadFailed);
-  }
-
-  fclose(file);
-
-  form_header = (struct IFF_ILBM_FORM_big_endian *)file_data;
-
-  if (strncmp(form_header->magic_FORM,"FORM",4) ||
-      file_len != be2long(form_header->chunk_size)+8 ||
-      strncmp(form_header->magic_ILBM,"ILBM",4))
-  {
-#ifdef DEBUG_ILBM
-      printf("%s: IFF chunk 'FORM' and/or 'ILBM' not found.\n",filename);
-#endif
-    free(file_data);
-    return(ILBM_FileInvalid);
-  }
-
-  bitmap_header = NULL;
-  body_ptr = NULL;
-  file_ptr = file_data + 12;
-
-  while(file_ptr < (unsigned char *)(file_data + file_len))
-  {
-    if (!strncmp(file_ptr,"BMHD",4))
-    {
-#ifdef DEBUG_ILBM
-      printf("%s: IFF chunk 'BMHD' found.\n",filename);
-#endif
-      bitmap_header = ConvertBMHD(file_ptr + 8);
-      file_ptr += be2long(file_ptr + 4) + 8;
-      continue;
-    }
-    else if (!strncmp(file_ptr,"BODY",4))
-    {
-#ifdef DEBUG_ILBM
-      printf("%s: IFF chunk 'BODY' found.\n",filename);
-#endif
-      body_ptr = file_ptr + 8;
-      body_len = be2long(file_ptr + 4);
-      file_ptr += be2long(file_ptr + 4) + 8;
-      continue;
-    }
-    else
-    {
-#ifdef DEBUG_ILBM
-      printf("%s: IFF chunk '%c%c%c%c' found (but not used).\n",filename,
-            file_ptr[0],file_ptr[1],file_ptr[2],file_ptr[3]);
-#endif
-      /* other chunk not recognized here */
-      file_ptr += be2long(file_ptr + 4) + 8;
-      continue;
-    }
-  }
-
-  if (!bitmap_header || !body_ptr)
-  {
-#ifdef DEBUG_ILBM
-      printf("%s: IFF chunk 'BMHD' and/or 'BODY' not found.\n",filename);
-#endif
-    free(file_data);
-    return(ILBM_FileInvalid);
-  }
-
-  width = bitmap_header->Width;
-  height = bitmap_header->Height;
-  depth = bitmap_header->Depth;
-
-#ifdef DEBUG_ILBM
-  if (depth > 1)
-    printf("%s: %d bitplanes found; using only the first plane.\n",
-          filename,depth);
-#endif
-
-  bytes_per_line = ((width + 15) / 16) * 2;
-  bitmap_size = bytes_per_line * height;
-
-  bitmap_data = (char *)malloc(bitmap_size);
-  if (!bitmap_data)
-  {
-    free(file_data);
-    free(bitmap_header);
-    return(ILBM_NoMemory);
-  }
-
-  bitmap_ptr = bitmap_data;
-  for(i=0;i<bitmap_size;i++)
-    *bitmap_ptr++ = 0;
-
-  for(y=0;y<height;y++)
-  {
-    /* we only read the first bitplane here to create a black/white bitmap */
-
-    for(z=0;z<depth;z++)
-    {
-      bitmap_ptr = bitmap_data + y * bytes_per_line;
-      x = 0;
-
-      if (!bitmap_header->Compression)
-      {
-       while(x++ < bytes_per_line)
-         *bitmap_ptr++ |= MSBitFirst2LSBitFirst(*body_ptr++);
-      }
-      else
-      {
-       while(x < bytes_per_line)
-       {
-         byte_count = *body_ptr++;
-
-         if (byte_count <= 128)
-         {
-           for(i=0;i<byte_count+1;i++)
-             *bitmap_ptr++ |= MSBitFirst2LSBitFirst(*body_ptr++);
-           x += byte_count + 1;
-         }
-         else
-         {
-           byte_value = *body_ptr++;
-           for(i=0;i<257-byte_count;i++)
-             *bitmap_ptr++ |= MSBitFirst2LSBitFirst(byte_value);
-           x += 257 - byte_count;
-         }
-       }
-      }
-    }
-  }
-
-  bitmap_ptr = bitmap_data;
-  for(i=0;i<bitmap_size;i++)
-    *bitmap_ptr++ ^= 0xff;
-
-  new_pixmap = XCreateBitmapFromData(display,root,bitmap_data,width,height);
-
-  free(file_data);
-  free(bitmap_data);
-  free(bitmap_header);
-
-  if (!new_pixmap)
-    return(ILBM_NoMemory);
-
-  *pixmap = new_pixmap;
-  return(ILBM_Success);
-}
diff --git a/src/gfxloader.h b/src/gfxloader.h
deleted file mode 100644 (file)
index d5b2257..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/***********************************************************
-*  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
-*----------------------------------------------------------*
-*  ©1995 Artsoft Development                               *
-*        Holger Schemel                                    *
-*        33659 Bielefeld-Senne                             *
-*        Telefon: (0521) 493245                            *
-*        eMail: aeglos@valinor.owl.de                      *
-*               aeglos@uni-paderborn.de                    *
-*               q99492@pbhrzx.uni-paderborn.de             *
-*----------------------------------------------------------*
-*  gfxloader.h                                             *
-***********************************************************/
-
-#ifndef GFXLOADER_H
-#define GFXLOADER_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
-#define GIF_Success             0
-#define GIF_OpenFailed         -1
-#define GIF_ReadFailed         -2
-#define        GIF_FileInvalid         -3
-#define GIF_NoMemory           -4
-#define GIF_ColorFailed                -5
-
-#define ILBM_Success            0
-#define ILBM_OpenFailed                -1
-#define ILBM_ReadFailed                -2
-#define        ILBM_FileInvalid        -3
-#define ILBM_NoMemory          -4
-#define ILBM_ColorFailed       -5
-
-int Read_ILBM_to_Bitmap(Display *, char *, Pixmap *);
-int Read_GIF_to_Bitmap(Display *, char *, Pixmap *);
-int Read_GIF_to_Pixmap(Display *, char *, Pixmap *);
-int Read_GIF_to_XImage(Display *, char *, XImage **);
-
-#endif
diff --git a/src/gif.c b/src/gif.c
new file mode 100644 (file)
index 0000000..2462e13
--- /dev/null
+++ b/src/gif.c
@@ -0,0 +1,632 @@
+
+/* gif.c:
+ *
+ * adapted from code by kirk johnson (tuna@athena.mit.edu).  most of this
+ * code is unchanged. -- jim frost 12.31.89
+ *
+ * gifin.c
+ * kirk johnson
+ * november 1989
+ *
+ * routines for reading GIF files
+ *
+ * Copyright 1989 Kirk L. Johnson (see the included file
+ * "kljcpyrght.h" for complete copyright information)
+ */
+
+#define GIF_C
+
+#include "xli.h"
+#include "gif.h"
+
+#define PUSH_PIXEL(p)                                       \
+{                                                           \
+  if (pstk_idx == PSTK_SIZE)                                \
+    return GIFIN_ERR_PSO;                                   \
+  else                                                      \
+    pstk[pstk_idx++] = (p);                                 \
+}
+
+/*
+ * push a string (denoted by a code) onto the pixel stack
+ * (returns the code of the first pixel in the string in ps_rslt)
+ */
+
+int ps_rslt;   /* return result */
+
+#define GIFIN_PUSH_STRING(code)                             \
+{                                                           \
+  int ps_code;                                              \
+  ps_code = code;                                           \
+                                                            \
+  while (((unsigned int)ps_code) < STAB_SIZE && prefix[ps_code] != NULL_CODE) \
+  {                                                         \
+    PUSH_PIXEL(extnsn[ps_code]);                            \
+    ps_code = prefix[ps_code];                              \
+  }                                                         \
+                                                            \
+  if (((unsigned int)ps_code) >= STAB_SIZE)                                 \
+    return GIFIN_ERR_TAO;                                   \
+  PUSH_PIXEL(extnsn[ps_code]);                              \
+  ps_rslt = extnsn[ps_code];                                \
+  if (((unsigned int)ps_rslt) >= STAB_SIZE)                                 \
+    return GIFIN_ERR_TAO;                                   \
+}
+
+/*
+ * Look up the ascii message coresponding to
+ * the error number.
+ */
+static char *get_err_string(int errno)
+{
+  int i;
+  for (i=0;gif_err_strings[i].err_no != 0;i++)
+  {
+    if (gif_err_strings[i].err_no == errno)
+               return gif_err_strings[i].name;
+  }
+  return "";
+}
+
+
+static int interlace_start[4] =        /* start line for interlacing */
+{
+  0, 4, 2, 1
+};
+
+static int interlace_rate[4] = /* rate at which we accelerate vertically */
+{
+  8, 8, 4, 2
+};
+
+static BYTE file_open  = 0;     /* status flags */
+static BYTE image_open = 0;
+
+static FILE *ins;              /* input stream */
+
+static int  root_size;          /* root code size */
+static int  clr_code;           /* clear code */
+static int  eoi_code;           /* end of information code */
+static int  code_size;          /* current code size */
+static int  code_mask;          /* current code mask */
+static int  prev_code;          /* previous code */
+
+static long work_data;          /* working bit buffer */
+static int  work_bits;          /* working bit count */
+
+static BYTE buf[256];           /* byte buffer */
+static int  buf_cnt;            /* byte count */
+static int  buf_idx;            /* buffer index */
+
+static int table_size;          /* string table size */
+static int prefix[STAB_SIZE];   /* string table : prefixes */
+static int extnsn[STAB_SIZE];   /* string table : extensions */
+
+static BYTE pstk[PSTK_SIZE];    /* pixel stack */
+static int  pstk_idx;           /* pixel stack pointer */
+
+
+static int  gifin_rast_width;          /* raster width */
+static int  gifin_rast_height;         /* raster height */
+static BYTE gifin_g_cmap_flag;         /* global colormap flag */
+static int  gifin_g_pixel_bits;        /* bits per pixel, global colormap */
+static int  gifin_g_ncolors;           /* number of colors, global colormap */
+static BYTE gifin_g_cmap[3][256];      /* global colormap */
+static BYTE gifin_g_cmap_sorted;       /* global colormap sorted (GIF89a only) */
+static int  gifin_bg_color;            /* background color index */
+static int  gifin_color_bits;          /* bits of color resolution */
+static double  gifin_aspect;           /* pixel aspect ratio (width/height) */
+static int  gifin_version;             /* gif file version */
+
+static int  gifin_img_left;            /* image position on raster */
+static int  gifin_img_top;             /* image position on raster */
+static int  gifin_img_width;           /* image width */
+static int  gifin_img_height;          /* image height */
+static BYTE gifin_l_cmap_flag;         /* local colormap flag */
+static int  gifin_l_pixel_bits;        /* bits per pixel, local colormap */
+static int  gifin_l_ncolors;           /* number of colors, local colormap */
+static BYTE gifin_l_cmap[3][256];      /* local colormap */
+static BYTE gifin_interlace_flag;      /* interlace image format flag */
+
+/*
+ * open a GIF file, using s as the input stream
+ */
+
+static int gifin_open_file(FILE *s)
+{
+  int errno;
+  /* make sure there isn't already a file open */
+  if (file_open)
+    return GIFIN_ERR_FAO;
+
+  /* remember that we've got this file open */
+  file_open = 1;
+  ins       = s;
+
+  /* check GIF signature */
+  if (fread(buf, 1, GIF_SIG_LEN, ins) != GIF_SIG_LEN)
+    return GIFIN_ERR_EOF;
+
+  buf[GIF_SIG_LEN] = '\0';
+  if (strcmp((char *) buf, GIF_SIG) == 0)
+    gifin_version = GIF87a;
+  else if(strcmp((char *) buf, GIF_SIG_89) == 0)
+    gifin_version = GIF89a;
+  else
+    return GIFIN_ERR_BAD_SIG;
+
+  /* read screen descriptor */
+  if (fread(buf, 1, GIF_SD_SIZE, ins) != GIF_SD_SIZE)
+    return GIFIN_ERR_EOF;
+
+  /* decode screen descriptor */
+  gifin_rast_width   = (buf[1] << 8) + buf[0];
+  gifin_rast_height  = (buf[3] << 8) + buf[2];
+  gifin_g_cmap_flag  = (buf[4] & 0x80) ? 1 : 0;
+  gifin_color_bits   = (((int)(buf[4] & 0x70)) >> 4) + 1;
+  gifin_g_pixel_bits = (buf[4] & 0x07) + 1;
+  gifin_bg_color     = buf[5];
+  gifin_aspect = 1.0;
+
+  if (gifin_version == GIF87a)
+  {
+    if (buf[4] & 0x08 || buf[6] != 0)
+      return GIFIN_ERR_BAD_SD;
+  }
+  else
+  {
+    gifin_g_cmap_sorted = ((buf[4] & 0x08) != 0);
+    if (buf[6] != 0)
+      gifin_aspect = ((double)buf[6] + 15.0) / 64.0;
+  }
+
+  /* load global colormap */
+  if (gifin_g_cmap_flag)
+  {
+    gifin_g_ncolors = (1 << gifin_g_pixel_bits);
+
+    if ((errno = gifin_load_cmap(gifin_g_cmap, gifin_g_ncolors)) != GIFIN_SUCCESS)
+      return errno;
+  }
+  else
+  {
+    gifin_g_ncolors = 0;
+  }
+
+  /* done! */
+  return GIFIN_SUCCESS;
+}
+
+
+/*
+ * open next GIF image in the input stream; returns GIFIN_SUCCESS if
+ * successful. if there are no more images, returns GIFIN_DONE. (might
+ * also return various GIFIN_ERR codes.)
+ */
+
+static int gifin_open_image()
+{
+  int i;
+  int separator;
+  int errno;
+
+  /* make sure there's a file open */
+  if (!file_open)
+    return GIFIN_ERR_NFO;
+
+  /* make sure there isn't already an image open */
+  if (image_open)
+    return GIFIN_ERR_IAO;
+
+  /* remember that we've got this image open */
+  image_open = 1;
+
+  /* skip over any extension blocks */
+  do
+  {
+    separator = fgetc(ins);
+    if (separator == GIF_EXTENSION)
+    {
+      if ((errno = gifin_skip_extension()) != GIFIN_SUCCESS)
+        return errno;
+    }
+  }
+  while (separator == GIF_EXTENSION);
+
+  /* check for end of file marker */
+  if (separator == GIF_TERMINATOR)
+    return GIFIN_DONE;
+
+  /* make sure we've got an image separator */
+  if (separator != GIF_SEPARATOR)
+    return GIFIN_ERR_BAD_SEP;
+
+  /* read image descriptor */
+  if (fread(buf, 1, GIF_ID_SIZE, ins) != GIF_ID_SIZE)
+    return GIFIN_ERR_EOF;
+
+  /* decode image descriptor */
+  gifin_img_left       = (buf[1] << 8) + buf[0];
+  gifin_img_top        = (buf[3] << 8) + buf[2];
+  gifin_img_width      = (buf[5] << 8) + buf[4];
+  gifin_img_height     = (buf[7] << 8) + buf[6];
+  gifin_l_cmap_flag    = (buf[8] & 0x80) ? 1 : 0;
+  gifin_interlace_flag = (buf[8] & 0x40) ? 1 : 0;
+  gifin_l_pixel_bits   = (buf[8] & 0x07) + 1;
+
+  /* load local colormap */
+  if (gifin_l_cmap_flag)
+  {
+    gifin_l_ncolors = (1 << gifin_l_pixel_bits);
+
+    if ((errno = gifin_load_cmap(gifin_l_cmap, gifin_l_ncolors)) != GIFIN_SUCCESS)
+      return errno;
+  }
+  else
+  {
+    gifin_l_ncolors = 0;
+  }
+
+  /* initialize raster data stream decoder */
+  root_size = fgetc(ins);
+  clr_code  = 1 << root_size;
+  eoi_code  = clr_code + 1;
+  code_size = root_size + 1;
+  code_mask = (1 << code_size) - 1;
+  work_bits = 0;
+  work_data = 0;
+  buf_cnt   = 0;
+  buf_idx   = 0;
+
+  /* initialize string table */
+  for (i=0; i<STAB_SIZE; i++)
+  {
+    prefix[i] = NULL_CODE;
+    extnsn[i] = i;
+  }
+
+  /* initialize pixel stack */
+  pstk_idx = 0;
+
+  /* done! */
+  return GIFIN_SUCCESS;
+}
+
+/*
+ * try to read next pixel from the raster, return result in *pel
+ */
+
+static int gifin_get_pixel(pel)
+     int *pel;
+{
+  int  code;
+  int  first;
+  int  place;
+  int  errno;
+
+  /* decode until there are some pixels on the pixel stack */
+  while (pstk_idx == 0)
+  {
+    /* load bytes until we have enough bits for another code */
+    while (work_bits < code_size)
+    {
+      if (buf_idx == buf_cnt)
+      {
+        /* read a new data block */
+        if ((errno = gifin_read_data_block()) != GIFIN_SUCCESS)
+          return errno;
+
+        if (buf_cnt == 0)
+          return GIFIN_ERR_EOD;
+      }
+
+      work_data |= ((long) buf[buf_idx++]) << work_bits;
+      work_bits += 8;
+    }
+
+    /* get the next code */
+    code        = work_data & code_mask;
+    work_data >>= code_size;
+    work_bits  -= code_size;
+
+    /* interpret the code */
+    if (code == clr_code)
+    {
+      /* reset decoder stream */
+      code_size  = root_size + 1;
+      code_mask  = (1 << code_size) - 1;
+      prev_code  = NULL_CODE;
+      table_size = eoi_code + 1;
+    }
+    else if (code == eoi_code)
+    {
+      /* Ooops! no more pixels */
+      return GIFIN_ERR_EOF;
+    }
+    else if (prev_code == NULL_CODE)
+    {
+      GIFIN_PUSH_STRING(code);
+      prev_code = code;
+    }
+    else
+    {
+      if (code < table_size)
+      {
+        GIFIN_PUSH_STRING(code);
+        first = ps_rslt;
+      }
+      else
+      {
+        place = pstk_idx;
+        PUSH_PIXEL(NULL_CODE);
+        GIFIN_PUSH_STRING(prev_code);
+        first = ps_rslt;
+        pstk[place] = first;
+      }
+
+      if((errno = gifin_add_string(prev_code, first)) != GIFIN_SUCCESS)
+        return errno;
+      prev_code = code;
+    }
+  }
+
+  /* pop a pixel off the pixel stack */
+  *pel = (int) pstk[--pstk_idx];
+
+  /* done! */
+  return GIFIN_SUCCESS;
+}
+
+/*
+ * close an open GIF file
+ */
+
+static int gifin_close_file()
+{
+  /* make sure there's a file open */
+  if (!file_open)
+    return GIFIN_ERR_NFO;
+
+  /* mark file (and image) as closed */
+  file_open  = 0;
+  image_open = 0;
+
+  /* done! */
+  return GIFIN_SUCCESS;
+}
+
+/*
+ * load a colormap from the input stream
+ */
+
+static int gifin_load_cmap(BYTE cmap[3][256], int ncolors)
+{
+  int i;
+
+  for (i=0; i<ncolors; i++)
+  {
+    if (fread(buf, 1, 3, ins) != 3)
+      return GIFIN_ERR_EOF;
+    
+    cmap[GIF_RED][i] = buf[GIF_RED];
+    cmap[GIF_GRN][i] = buf[GIF_GRN];
+    cmap[GIF_BLU][i] = buf[GIF_BLU];
+  }
+
+  /* done! */
+  return GIFIN_SUCCESS;
+}
+/*
+ * skip an extension block in the input stream
+ */
+
+static int gifin_skip_extension()
+{
+  int errno;
+
+  /* get the extension function byte */
+  fgetc(ins);
+
+  /* skip any remaining raster data */
+  do
+  {
+    if ((errno = gifin_read_data_block()) != GIFIN_SUCCESS)
+      return errno;
+  }
+  while (buf_cnt > 0);
+
+  /* done! */
+  return GIFIN_SUCCESS;
+}
+
+/*
+ * read a new data block from the input stream
+ */
+
+static int gifin_read_data_block()
+{
+  /* read the data block header */
+  buf_cnt = fgetc(ins);
+
+  /* read the data block body */
+  if (fread(buf, 1, buf_cnt, ins) != buf_cnt)
+    return GIFIN_ERR_EOF;
+
+  buf_idx = 0;
+
+  /* done! */
+  return GIFIN_SUCCESS;
+}
+
+
+/*
+ * add a new string to the string table
+ */
+
+static int gifin_add_string(int p, int e)
+{
+  prefix[table_size] = p;
+  extnsn[table_size] = e;
+
+  if ((table_size == code_mask) && (code_size < 12))
+  {
+    code_size += 1;
+    code_mask  = (1 << code_size) - 1;
+  }
+
+  table_size += 1;
+  if (table_size > STAB_SIZE)
+    return GIFIN_ERR_TAO;
+  return GIFIN_SUCCESS;
+}
+
+/* these are the routines added for interfacing to xli
+ */
+
+/* tell someone what the image we're loading is.  this could be a little more
+ * descriptive but I don't care
+ */
+
+static void tellAboutImage(char *name)
+{
+  printf("\n%s:\n  %dx%d %s%s image with %d colors\n",
+        name, gifin_img_width, gifin_img_height,
+        (gifin_interlace_flag ? "interlaced " : ""),
+        gif_version_name[gifin_version],
+        (gifin_l_cmap_flag ? gifin_l_ncolors : gifin_g_ncolors));
+}
+
+Image *gifLoad(char *fullname)
+{
+  FILE *zf;
+  Image *image;
+  int x, y, pixel, pass, scanlen;
+  byte *pixptr, *pixline;
+  int errno;
+
+  if (!(zf = fopen(fullname,"r")))
+  {
+    perror("gifLoad");
+    return(NULL);
+  }
+
+  if ((gifin_open_file(zf) != GIFIN_SUCCESS) || /* read GIF header */
+      (gifin_open_image() != GIFIN_SUCCESS))    /* read image header */
+  {
+    printf("gifin_open_file or gifin_open_image failed!\n");
+
+    gifin_close_file();
+    fclose(zf);
+    return(NULL);
+  }
+
+  tellAboutImage(fullname);
+
+  image= newRGBImage(gifin_img_width, gifin_img_height, (gifin_l_cmap_flag ?
+                                                        gifin_l_pixel_bits :
+                                                        gifin_g_pixel_bits));
+  image->title= dupString(fullname);
+
+  /* if image has a local colormap, override global colormap
+   */
+
+  if (gifin_l_cmap_flag)
+  {
+    for (x= 0; x < gifin_l_ncolors; x++)
+    {
+      image->rgb.red[x]= gifin_l_cmap[GIF_RED][x] << 8;
+      image->rgb.green[x]= gifin_l_cmap[GIF_GRN][x] << 8;
+      image->rgb.blue[x]= gifin_l_cmap[GIF_BLU][x] << 8;
+    }
+    image->rgb.used= gifin_l_ncolors;
+  }
+  else
+  {
+    for (x= 0; x < gifin_g_ncolors; x++)
+    {
+      image->rgb.red[x]= gifin_g_cmap[GIF_RED][x] << 8;
+      image->rgb.green[x]= gifin_g_cmap[GIF_GRN][x] << 8;
+      image->rgb.blue[x]= gifin_g_cmap[GIF_BLU][x] << 8;
+    }
+    image->rgb.used= gifin_g_ncolors;
+  }
+
+  /* interlaced image -- futz with the vertical trace.  i wish i knew what
+   * kind of drugs the GIF people were on when they decided that they
+   * needed to support interlacing.
+   */
+
+  if (gifin_interlace_flag)
+  {
+    scanlen= image->height * image->pixlen;
+
+    /* interlacing takes four passes to read, each starting at a different
+     * vertical point.
+     */
+
+    for (pass= 0; pass < 4; pass++)
+    {
+      y= interlace_start[pass];
+      scanlen= image->width * image->pixlen * interlace_rate[pass];
+      pixline= image->data + (y * image->width * image->pixlen);
+      while (y < gifin_img_height)
+      {
+       pixptr= pixline;
+       for (x= 0; x < gifin_img_width; x++)
+       {
+         if ((errno = gifin_get_pixel(&pixel)) != GIFIN_SUCCESS)
+         {
+           fprintf(stderr, "gifLoad: %s - Short read within image data, '%s'\n", fullname, get_err_string(errno));
+           y = gifin_img_height; x = gifin_img_width;
+         }
+         valToMem(pixel, pixptr, image->pixlen);
+         pixptr += image->pixlen;
+       }
+       y += interlace_rate[pass];
+       pixline += scanlen;
+      }
+    }
+  }
+  else
+  {
+    /* not an interlaced image, just read in sequentially
+     */
+
+    if(image->pixlen == 1)      /* the usual case */
+    {
+      pixptr= image->data;
+      for (y= 0; y < gifin_img_height; y++)
+        for (x= 0; x < gifin_img_width; x++)
+       {
+          if ((errno = gifin_get_pixel(&pixel)) != GIFIN_SUCCESS)
+         {
+           fprintf(stderr, "gifLoad: %s - Short read within image data, '%s'\n", fullname, get_err_string(errno));
+            y = gifin_img_height; x = gifin_img_width;
+          }
+          valToMem(pixel, pixptr, 1);
+          pixptr += 1;
+        }
+    }
+    else                       /* less ususal case */
+    {
+      pixptr= image->data;
+      for (y= 0; y < gifin_img_height; y++)
+        for (x= 0; x < gifin_img_width; x++)
+       {
+          if ((errno = gifin_get_pixel(&pixel)) != GIFIN_SUCCESS)
+         {
+           fprintf(stderr, "gifLoad: %s - Short read within image data, '%s'\n", fullname, get_err_string(errno));
+            y = gifin_img_height; x = gifin_img_width;
+          }
+          valToMem(pixel, pixptr, image->pixlen);
+          pixptr += image->pixlen;
+        }
+     }
+  }
+
+  gifin_close_file();
+  fclose(zf);
+
+  return(image);
+}
diff --git a/src/gif.h b/src/gif.h
new file mode 100644 (file)
index 0000000..89c252f
--- /dev/null
+++ b/src/gif.h
@@ -0,0 +1,121 @@
+
+/* gif.h:
+ *
+ * gifin.h
+ * kirk johnson
+ * november 1989
+ * external interface to gifin.c
+ *
+ * Copyright 1989 Kirk L. Johnson (see the included file
+ * "kljcpyrght.h" for complete copyright information)
+ */
+
+/*
+ * gifin return codes
+ */
+#define GIFIN_SUCCESS       0   /* success */
+#define GIFIN_DONE          1   /* no more images */
+
+#define GIFIN_ERR_BAD_SD   -1   /* bad screen descriptor */
+#define GIFIN_ERR_BAD_SEP  -2   /* bad image separator */
+#define GIFIN_ERR_BAD_SIG  -3   /* bad signature */
+#define GIFIN_ERR_EOD      -4   /* unexpected end of raster data */
+#define GIFIN_ERR_EOF      -5   /* unexpected end of input stream */
+#define GIFIN_ERR_FAO      -6   /* file already open */
+#define GIFIN_ERR_IAO      -7   /* image already open */
+#define GIFIN_ERR_NFO      -8   /* no file open */
+#define GIFIN_ERR_NIO      -9   /* no image open */
+#define GIFIN_ERR_PSO      -10  /* pixel stack overflow */
+#define GIFIN_ERR_TAO      -11  /* table overflow */
+#define GIFIN_ERR_BAD_DES  -12  /* bad image descriptor */
+
+#define GIFIN_ERR_BAD_SD_STR   "Bad screen descriptor"
+#define GIFIN_ERR_BAD_SEP_STR  "Bad image separator"
+#define GIFIN_ERR_BAD_SIG_STR  "Bad signature"
+#define GIFIN_ERR_EOD_STR      "Unexpected end of raster data"
+#define GIFIN_ERR_EOF_STR      "Unexpected end of input stream"
+#define GIFIN_ERR_FAO_STR      "File already open"
+#define GIFIN_ERR_IAO_STR      "Image already open"
+#define GIFIN_ERR_NFO_STR      "No file open"
+#define GIFIN_ERR_NIO_STR      "No image open"
+#define GIFIN_ERR_PSO_STR      "Pixel stack overflow"
+#define GIFIN_ERR_TAO_STR      "Table overflow"
+#define GIFIN_ERR_BAD_DES_STR  "Bad image descriptor"
+
+typedef struct {
+    int err_no;
+    char *name;
+    } gif_err_string;
+
+#ifdef GIF_C
+gif_err_string gif_err_strings[] = {
+       {GIFIN_ERR_BAD_SD, GIFIN_ERR_BAD_SD_STR},
+       {GIFIN_ERR_BAD_SEP, GIFIN_ERR_BAD_SEP_STR},
+       {GIFIN_ERR_BAD_SIG, GIFIN_ERR_BAD_SIG_STR},
+       {GIFIN_ERR_EOD, GIFIN_ERR_EOD_STR},
+       {GIFIN_ERR_EOF, GIFIN_ERR_EOF_STR},
+       {GIFIN_ERR_FAO, GIFIN_ERR_FAO_STR},
+       {GIFIN_ERR_IAO, GIFIN_ERR_IAO_STR},
+       {GIFIN_ERR_NFO, GIFIN_ERR_NFO_STR},
+       {GIFIN_ERR_NIO, GIFIN_ERR_NIO_STR},
+       {GIFIN_ERR_PSO, GIFIN_ERR_PSO_STR},
+       {GIFIN_ERR_TAO, GIFIN_ERR_TAO_STR},
+       {GIFIN_ERR_BAD_DES, GIFIN_ERR_BAD_DES_STR},
+       {0}
+    };
+#endif
+
+/*
+ * colormap indices 
+ */
+
+#define GIF_RED  0
+#define GIF_GRN  1
+#define GIF_BLU  2
+
+/*
+ * typedef BYTE for convenience
+ */
+
+typedef unsigned char BYTE;
+
+static int gifin_open_file();
+static int gifin_open_image();
+static int gifin_get_pixel();
+#if 0
+static int gifin_close_image();
+#endif
+static int gifin_close_file();
+static int gifin_load_cmap();
+static int gifin_skip_extension();
+static int gifin_read_data_block();
+static int gifin_add_string();
+
+/* #defines, typedefs, and such
+ */
+
+#define GIF_SIG      "GIF87a"
+#define GIF_SIG_89   "GIF89a"
+
+#define GIF87a 0                /* Gif file version type */
+#define GIF89a 1                /* Gif file version type */
+
+#define GIF_SIG_LEN  6          /* GIF signature length */
+#define GIF_SD_SIZE  7          /* GIF screen descriptor size */
+#define GIF_ID_SIZE  9          /* GIF image descriptor size */
+
+#define GIF_SEPARATOR   ','     /* GIF image separator */
+#define GIF_EXTENSION   '!'     /* GIF extension block marker */
+#define GIF_TERMINATOR  ';'     /* GIF terminator */
+
+#define STAB_SIZE  4096         /* string table size */
+#define PSTK_SIZE  4096         /* pixel stack size */
+
+#define NULL_CODE  -1           /* string table null code */
+
+#ifdef GIF_C
+char *gif_version_name[] = {
+    GIF_SIG,
+    GIF_SIG_89
+    };
+#endif
diff --git a/src/gifload.c b/src/gifload.c
new file mode 100644 (file)
index 0000000..89c06ae
--- /dev/null
@@ -0,0 +1,113 @@
+/***********************************************************
+*  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
+*----------------------------------------------------------*
+*  ©1995 Artsoft Development                               *
+*        Holger Schemel                                    *
+*        33659 Bielefeld-Senne                             *
+*        Telefon: (0521) 493245                            *
+*        eMail: aeglos@valinor.owl.de                      *
+*               aeglos@uni-paderborn.de                    *
+*               q99492@pbhrzx.uni-paderborn.de             *
+*----------------------------------------------------------*
+*  gifload.c                                               *
+***********************************************************/
+
+#ifndef MSDOS
+#include "gifload.h"
+
+#include "xli.h"
+
+
+
+extern Pixmap          test_pix[];
+extern Pixmap          test_clipmask[];
+extern int             test_picture_count;
+
+
+
+
+int Read_GIF_to_Image(Display *display, Window window, char *filename)
+{
+  Image *image, *image_mask;
+  XImageInfo *ximageinfo, *ximageinfo_mask;
+  Pixmap pixmap, pixmap_mask;
+  int screen;
+  Visual *visual;
+  unsigned int depth;
+
+  /* load GIF file */
+  if (!(image = gifLoad(filename)))
+  {
+    printf("Loading GIF image failed -- maybe no GIF...\n");
+    exit(1);
+  }
+
+  if (image->depth > 8)
+  {
+    printf("Sorry, GIFs with more than 256 colors are not supported.\n");
+    exit(1);
+  }
+
+  /* minimize colormap */
+  compress(image);
+
+  screen = DefaultScreen(display);
+  visual = DefaultVisual(display, screen);
+  depth = DefaultDepth(display, screen);
+
+  /* convert internal image structure to X11 XImage */
+  if (!(ximageinfo = imageToXImage(display, screen, visual, depth, image)))
+  {
+    fprintf(stderr, "Cannot convert Image to XImage.\n");
+    exit(1);
+  }
+
+  if (ximageinfo->cmap != DefaultColormap(display, screen))
+  {
+    printf("--> '%s' gets own colormap\n", filename);
+
+    XSetWindowColormap(display, window, ximageinfo->cmap);
+  }
+
+  /* convert XImage to Pixmap */
+  if ((pixmap = ximageToPixmap(display, window, ximageinfo)) == None)
+  {
+    fprintf(stderr, "Cannot convert XImage to Pixmap.\n");
+    exit(1);
+  }
+
+
+  printf("test_picture_count == %d\n", test_picture_count);
+
+
+  test_pix[test_picture_count] = pixmap;
+
+
+  /* create mono image for masking */
+  image_mask = monochrome(image);
+
+  /* convert internal image structure to X11 XImage */
+  if (!(ximageinfo_mask = imageToXImage(display, screen, visual, depth,
+                                       image_mask)))
+  {
+    fprintf(stderr, "Cannot convert Image to XImage.\n");
+    exit(1);
+  }
+
+  /* convert XImage to Pixmap */
+  if ((pixmap_mask = ximageToPixmap(display, window, ximageinfo_mask)) == None)
+  {
+    fprintf(stderr, "Cannot convert XImage to Pixmap.\n");
+    exit(1);
+  }
+
+
+  test_clipmask[test_picture_count] = pixmap_mask;
+
+  test_picture_count++;
+
+
+  return(GIF_Success);
+}
+
+#endif
diff --git a/src/gifload.h b/src/gifload.h
new file mode 100644 (file)
index 0000000..0607496
--- /dev/null
@@ -0,0 +1,39 @@
+/***********************************************************
+*  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
+*----------------------------------------------------------*
+*  ©1995 Artsoft Development                               *
+*        Holger Schemel                                    *
+*        33659 Bielefeld-Senne                             *
+*        Telefon: (0521) 493245                            *
+*        eMail: aeglos@valinor.owl.de                      *
+*               aeglos@uni-paderborn.de                    *
+*               q99492@pbhrzx.uni-paderborn.de             *
+*----------------------------------------------------------*
+*  gifload.h                                               *
+***********************************************************/
+
+#ifndef GIFLOAD_H
+#define GIFLOAD_H
+
+#ifndef MSDOS
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+#define GIF_Success             0
+#define GIF_OpenFailed         -1
+#define GIF_ReadFailed         -2
+#define        GIF_FileInvalid         -3
+#define GIF_NoMemory           -4
+#define GIF_ColorFailed                -5
+
+int Read_GIF_to_Image(Display *, Window, char *);
+int Read_GIF_to_Bitmap(Display *, char *, Pixmap *);
+int Read_GIF_to_Pixmap(Display *, char *, Pixmap *);
+int Read_GIF_to_XImage(Display *, char *, XImage **);
+
+#endif
+
+#endif
index 134cf74aeadfee1f092b95fb9496cb1adc9b2b09..2eced3e30f9af07d0162b6b5c00012c125e80457 100644 (file)
 #include "tools.h"
 #include "files.h"
 #include "joystick.h"
-#include "gfxloader.h"
+#include "gfxload.h"
+#include "gifload.h"
 
 #include <signal.h>
 
 #ifdef DEBUG
-/*
+
 #define DEBUG_TIMING
-*/
+
 #endif
 
 struct PictureFileInfo
@@ -93,6 +94,7 @@ void InitSound()
   if (sound_status==SOUND_OFF)
     return;
 
+#ifndef MSDOS
   if (access(sound_device_name,W_OK)<0)
   {
     fprintf(stderr,"%s: cannot access sound device - no sounds\n",progname);
@@ -114,9 +116,16 @@ void InitSound()
   sound_loops_allowed = TRUE;
   sound_loops_on = TRUE;
 #endif
+#else
+  sound_loops_allowed = TRUE;
+  sound_loops_on = TRUE;
+#endif
 
   for(i=0;i<NUM_SOUNDS;i++)
   {
+#ifdef MSDOS
+  sprintf(sound_name[i], "%d", i+1);
+#endif
     Sound[i].name = sound_name[i];
     if (!LoadSound(&Sound[i]))
     {
@@ -131,6 +140,7 @@ void InitSoundProcess()
   if (sound_status==SOUND_OFF)
     return;
 
+#ifndef MSDOS
   if (pipe(sound_pipe)<0)
   {
     fprintf(stderr,"%s: cannot create pipe - no sounds\n",progname);
@@ -149,6 +159,9 @@ void InitSoundProcess()
     SoundServer();
   else                         /* we are parent */
     close(sound_pipe[0]);      /* no reading from pipe needed */
+#else
+  SoundServer();
+#endif
 }
 
 void InitJoystick()
@@ -156,6 +169,7 @@ void InitJoystick()
   if (global_joystick_status==JOYSTICK_OFF)
     return;
 
+#ifndef MSDOS
   if (access(joystick_device_name[joystick_nr],R_OK)<0)
   {
     fprintf(stderr,"%s: cannot access joystick device '%s'\n",
@@ -174,6 +188,9 @@ void InitJoystick()
 
   joystick_status = JOYSTICK_AVAILABLE;
   LoadJoystickData();
+#else
+  joystick_status = JOYSTICK_AVAILABLE;
+#endif
 }
 
 void InitDisplay(int argc, char *argv[])
@@ -226,18 +243,37 @@ void InitWindow(int argc, char *argv[])
   char *window_name = WINDOWTITLE_STRING;
   char *icon_name = WINDOWTITLE_STRING;
   long window_event_mask;
+  Atom proto_atom = None, delete_atom = None;
+  int screen_width, screen_height;
+  int win_xpos = WIN_XPOS, win_ypos = WIN_YPOS;
+
+#ifndef MSDOS
   static struct IconFileInfo icon_pic =
   {
     "rocks_icon.xbm",
     "rocks_iconmask.xbm"
   };
+#endif
+
+  screen_width = XDisplayWidth(display, screen);
+  screen_height = XDisplayHeight(display, screen);
 
   width = WIN_XSIZE;
   height = WIN_YSIZE;
 
+  win_xpos = (screen_width - width) / 2;
+  win_ypos = (screen_height - height) / 2;
+
   window = XCreateSimpleWindow(display, RootWindow(display, screen),
-                           WIN_XPOS, WIN_YPOS, width, height, border_width,
-                           pen_fg, pen_bg);
+                              win_xpos, win_ypos, width, height, border_width,
+                              pen_fg, pen_bg);
+
+#ifndef MSDOS
+  proto_atom = XInternAtom(display, "WM_PROTOCOLS", FALSE);
+  delete_atom = XInternAtom(display, "WM_DELETE_WINDOW", FALSE);
+  if ((proto_atom != None) && (delete_atom != None))
+    XChangeProperty(display, window, proto_atom, XA_ATOM, 32,
+                   PropModePrepend, (unsigned char *) &delete_atom, 1);
 
   sprintf(icon_filename,"%s/%s",GFX_PATH,icon_pic.picture_filename);
   XReadBitmapFile(display,window,icon_filename,
@@ -261,9 +297,16 @@ void InitWindow(int argc, char *argv[])
     exit(-1);
   }
 
-  size_hints.flags = PSize | PMinSize | PMaxSize;
   size_hints.width  = size_hints.min_width  = size_hints.max_width  = width;
   size_hints.height = size_hints.min_height = size_hints.max_height = height;
+  size_hints.flags = PSize | PMinSize | PMaxSize;
+
+  if (win_xpos || win_ypos)
+  {
+    size_hints.x = win_xpos;
+    size_hints.y = win_ypos;
+    size_hints.flags |= PPosition;
+  }
 
   if (!XStringListToTextProperty(&window_name, 1, &windowName))
   {
@@ -301,6 +344,7 @@ void InitWindow(int argc, char *argv[])
                       KeyPressMask | KeyReleaseMask;
   XSelectInput(display, window, window_event_mask);
 
+#endif
   /* create GC for drawing with window depth */
   gc_values.graphics_exposures = False;
   gc_values.foreground = pen_bg;
@@ -325,6 +369,17 @@ void InitGfx()
   int i,j;
   XGCValues clip_gc_values;
   unsigned long clip_gc_valuemask;
+#ifdef MSDOS
+  static struct PictureFileInfo pic[NUM_PICTURES] =
+  {
+    { "Screen",        TRUE },
+    { "Door",  TRUE },
+    { "Heroes",        TRUE },
+    { "Toons", TRUE },
+    { "Font",  FALSE },
+    { "Font2", FALSE }
+  }; 
+#else
   static struct PictureFileInfo pic[NUM_PICTURES] =
   {
     { "RocksScreen",   TRUE },
@@ -334,6 +389,7 @@ void InitGfx()
     { "RocksFont",     FALSE },
     { "RocksFont2",    FALSE }
   }; 
+#endif
 
 #ifdef DEBUG_TIMING
   long count1, count2;
@@ -343,6 +399,10 @@ void InitGfx()
   LoadGfx(PIX_SMALLFONT,&pic[PIX_SMALLFONT]);
   DrawInitText(WINDOWTITLE_STRING,20,FC_YELLOW);
   DrawInitText(COPYRIGHT_STRING,50,FC_RED);
+#ifdef MSDOS
+  DrawInitText("MSDOS version done by Guido Schulz",210,FC_BLUE);
+  rest(200);
+#endif MSDOS
   DrawInitText("Loading graphics:",120,FC_GREEN);
 
   for(i=0;i<NUM_PICTURES;i++)
@@ -414,7 +474,11 @@ void LoadGfx(int pos, struct PictureFileInfo *pic)
   unsigned int width,height;
   int hot_x,hot_y;
   Pixmap shapemask;
+#ifdef MSDOS
+  char *picture_ext = ".gif";
+#else
   char *picture_ext = ".xpm";
+#endif
   char *picturemask_ext = "Mask.xbm";
 #else
   int gif_err, ilbm_err;
@@ -429,8 +493,37 @@ void LoadGfx(int pos, struct PictureFileInfo *pic)
   /* Grafik laden */
   if (pic->picture_filename)
   {
+
+
+
+
+
+    sprintf(basefilename,"%s%s",pic->picture_filename,".gif");
+    DrawInitText(basefilename,150,FC_YELLOW);
+    sprintf(filename,"%s/%s",GFX_PATH,basefilename);
+
+#ifdef DEBUG_TIMING
+    count1 = Counter();
+#endif
+
+    Read_GIF_to_Image(display, window, filename);
+
+#ifdef DEBUG_TIMING
+    count2 = Counter();
+    printf("GIF LOADING %s IN %.2f SECONDS\n",
+          filename,(float)(count2-count1)/100.0);
+#endif
+
+
+
+
+
+
     sprintf(basefilename,"%s%s",pic->picture_filename,picture_ext);
     DrawInitText(basefilename,150,FC_YELLOW);
+#ifdef MSDOS
+    rest(100);
+#endif MSDOS
     sprintf(filename,"%s/%s",GFX_PATH,basefilename);
 
 #ifdef DEBUG_TIMING
@@ -440,9 +533,19 @@ void LoadGfx(int pos, struct PictureFileInfo *pic)
 #ifdef XPM_INCLUDE_FILE
 
     xpm_att[pos].valuemask = XpmCloseness;
+    xpm_att[pos].closeness = 65535;
+
+    /*
     xpm_att[pos].closeness = 20000;
+    */
+
+#if 0
     xpm_err = XpmReadFileToPixmap(display,window,filename,
                                  &pix[pos],&shapemask,&xpm_att[pos]);
+#else
+    xpm_err = XpmSuccess;
+#endif
+
     switch(xpm_err)
     {
       case XpmOpenFailed:
@@ -501,10 +604,11 @@ void LoadGfx(int pos, struct PictureFileInfo *pic)
 
 #ifdef DEBUG_TIMING
     count2 = Counter();
-    printf("LOADING %s IN %.2f SECONDS\n",
+    printf("XPM LOADING %s IN %.2f SECONDS\n",
           filename,(float)(count2-count1)/100.0);
 #endif
 
+#if 0
     if (!pix[pos])
     {
       fprintf(stderr, "%s: cannot read graphics file '%s'.\n",
@@ -512,14 +616,22 @@ void LoadGfx(int pos, struct PictureFileInfo *pic)
       CloseAll();
       exit(-1);
     }
+#endif
+
   }
 
   /* zugehörige Maske laden (wenn vorhanden) */
   if (pic->picture_with_mask)
   {
+#ifdef MSDOS
+    xbm_err = BitmapSuccess;
+    clipmask[pos] = DUMMY_MASK;
+    goto msdos_jmp;
+#else
     sprintf(basefilename,"%s%s",pic->picture_filename,picturemask_ext);
     DrawInitText(basefilename,150,FC_YELLOW);
     sprintf(filename,"%s/%s",GFX_PATH,basefilename);
+#endif
 
 #ifdef DEBUG_TIMING
     count1 = Counter();
@@ -527,8 +639,16 @@ void LoadGfx(int pos, struct PictureFileInfo *pic)
 
 #ifdef XPM_INCLUDE_FILE
 
+#if 0
     xbm_err = XReadBitmapFile(display,window,filename,
                              &width,&height,&clipmask[pos],&hot_x,&hot_y);
+#else
+    xbm_err = BitmapSuccess;
+#endif
+
+#ifdef MSDOS
+msdos_jmp:
+#endif
     switch(xbm_err)
     {
       case BitmapSuccess:
@@ -588,6 +708,7 @@ void LoadGfx(int pos, struct PictureFileInfo *pic)
           filename,(float)(count2-count1)/100.0);
 #endif
 
+#if 0
     if (!clipmask[pos])
     {
       fprintf(stderr, "%s: cannot read graphics file '%s'.\n",
@@ -595,7 +716,12 @@ void LoadGfx(int pos, struct PictureFileInfo *pic)
       CloseAll();
       exit(-1);
     }
+#endif
+
   }
+
+  pix[pos] = test_pix[test_picture_count-1];
+  clipmask[pos] = test_clipmask[test_picture_count-1];
 }
 
 void InitElementProperties()
index 3855400d814eeacbac23662117a465813ec6b361..7bf648ed75cd766059ff843b7a966659ac884c4c 100644 (file)
@@ -90,6 +90,7 @@ int Joystick()
   if (joystick_status==JOYSTICK_OFF)
     return(0);
 
+#ifndef MSDOS
   if (read(joystick_device, &joy_ctrl, sizeof(joy_ctrl)) != sizeof(joy_ctrl))
   {
     fprintf(stderr,"%s: cannot read joystick settings - no joystick support\n",
@@ -131,6 +132,9 @@ int Joystick()
     result |= JOY_BUTTON_2;
 
   return(result);
+#else
+  return(0);
+#endif
 }
 
 int JoystickButton()
index eed5609420106a9984b6cbec570c84d38565a414..2395ec1b708f19e5bacf74727bedb65f6239bee7 100644 (file)
 #include "sound.h"
 #include "joystick.h"
 
+#ifdef MSDOS
+#include <fcntl.h>
+#endif
+
 Display        *display;
 int            screen;
 Window         window;
@@ -25,6 +29,12 @@ GC           gc, clip_gc[NUM_PIXMAPS];
 Pixmap         pix[NUM_PIXMAPS];
 Pixmap         clipmask[NUM_PIXMAPS];
 
+
+Pixmap         test_pix[NUM_PICTURES];
+Pixmap         test_clipmask[NUM_PICTURES];
+int            test_picture_count = 0;
+
+
 #ifdef XPM_INCLUDE_FILE
 XpmAttributes  xpm_att[NUM_PICTURES];
 #endif
@@ -188,6 +198,10 @@ int main(int argc, char *argv[])
   if (argc>1)
     level_directory = argv[1];
 
+#ifdef MSDOS
+  _fmode = O_BINARY;
+#endif
+
   OpenAll(argc,argv);
   EventLoop();
   CloseAll();
index aff6db83ee537004cd4b0bfb976841e0cc95586b..5969bfc4508e7cafa1ba5a01f0ae5cdb5f3e5be9 100644 (file)
 #ifndef MAIN_H
 #define MAIN_H
 
+#ifndef MSDOS
 #define XK_MISCELLANY
 #define XK_LATIN1
 
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
+#include <X11/Xatom.h>
 #include <X11/Xos.h>
 #include <X11/Intrinsic.h>
 #include <X11/keysymdef.h>
@@ -27,6 +29,9 @@
 #ifdef   XPM_INCLUDE_FILE
 #include XPM_INCLUDE_FILE
 #endif
+#else
+#include "msdos.h"
+#endif  // von #ifndef MSDOS
 
 #include <sys/types.h>
 #include <sys/stat.h>
 
 typedef int BOOL;
 
-#define TRUE           1
-#define FALSE          0
+#ifndef FALSE
+#define FALSE 0
+#define TRUE (!FALSE)
+#endif
 
-#define WIN_XPOS       0
-#define WIN_YPOS       0
 #define WIN_XSIZE      672
 #define WIN_YSIZE      560
+#ifndef MSDOS
+#define WIN_XPOS       0
+#define WIN_YPOS       0
+#else
+#define WIN_XPOS       (XRES-WIN_XSIZE)/2
+#define WIN_YPOS       (YRES-WIN_YSIZE)/2
+#endif
 #define SCR_FIELDX     17
 #define SCR_FIELDY     17
 #define MAX_BUF_XSIZE  (SCR_FIELDX + 2)
@@ -56,10 +68,18 @@ typedef int BOOL;
 #define MAX_LEV_FIELDX 128
 #define MAX_LEV_FIELDY 128
 
+#ifndef MIN
 #define MIN(a,b)       ((a)<(b) ? (a) : (b))
+#endif
+#ifndef MAX
 #define MAX(a,b)       ((a)>(b) ? (a) : (b))
+#endif
+#ifndef ABS
 #define ABS(a)         ((a)<0 ? -(a) : (a))
+#endif
+#ifndef SIGN
 #define SIGN(a)                ((a)<0 ? -1 : ((a)>0 ? 1 : 0))
+#endif
 #define SCROLLX(a)     ((a)-scroll_x)
 #define SCROLLY(a)     ((a)-scroll_y)
 #define UNSCROLLX(a)   ((a)+scroll_x)
@@ -250,6 +270,13 @@ extern XImage             *image[];
 extern Pixmap          clipmask[];
 extern Pixmap          pix[];
 
+
+extern Pixmap          test_pix[];
+extern Pixmap          test_clipmask[];
+extern int             test_picture_count;
+
+
+
 #ifdef XPM_INCLUDE_FILE
 extern XpmAttributes   xpm_att[];
 #endif
@@ -935,10 +962,17 @@ extern char               *progname;
 #define JOYDAT_PATH            GAME_DIR
 #endif
 
+#ifndef MSDOS
 #define SCORE_FILENAME         "ROCKS.score"
 #define NAMES_FILENAME         "ROCKS.names"
 #define LEVDIR_FILENAME                "ROCKS.levelinfo"
 #define JOYDAT_FILENAME                "ROCKS.joystick"
+#else
+#define SCORE_FILENAME         "ROCKS.sco"
+#define NAMES_FILENAME         "ROCKS.nam"
+#define LEVDIR_FILENAME                "ROCKS.lev"
+#define JOYDAT_FILENAME                "ROCKS.joy"
+#endif
 
 #define JOYDAT_FILE            JOYDAT_PATH "/" JOYDAT_FILENAME
 
@@ -982,8 +1016,13 @@ extern char               *progname;
 #define MB_MENU_MARK           TRUE
 #define MB_MENU_INITIALIZE     (-1)
 #define MB_LEFT                        1
+#ifdef MSDOS
+#define MB_MIDDLE              4
+#define MB_RIGHT               2
+#else
 #define MB_MIDDLE              2
 #define MB_RIGHT               3
+#endif
 
 /* values for key_status */
 #define KEY_NOT_PRESSED                FALSE
diff --git a/src/new.c b/src/new.c
new file mode 100644 (file)
index 0000000..0491352
--- /dev/null
+++ b/src/new.c
@@ -0,0 +1,170 @@
+
+/* new.c:
+ *
+ * functions to allocate and deallocate structures and structure data
+ *
+ * jim frost 09.29.89
+ *
+ * Copyright 1989, 1991 Jim Frost.
+ * See included file "copyright.h" for complete copyright information.
+ */
+
+#include "xli.h"
+
+/* this table is useful for quick conversions between depth and ncolors
+ */
+
+unsigned long DepthToColorsTable[] =
+{
+  /*  0 */ 1,
+  /*  1 */ 2,
+  /*  2 */ 4,
+  /*  3 */ 8,
+  /*  4 */ 16,
+  /*  5 */ 32,
+  /*  6 */ 64,
+  /*  7 */ 128,
+  /*  8 */ 256,
+  /*  9 */ 512,
+  /* 10 */ 1024,
+  /* 11 */ 2048,
+  /* 12 */ 4096,
+  /* 13 */ 8192,
+  /* 14 */ 16384,
+  /* 15 */ 32768,
+  /* 16 */ 65536,
+  /* 17 */ 131072,
+  /* 18 */ 262144,
+  /* 19 */ 524288,
+  /* 20 */ 1048576,
+  /* 21 */ 2097152,
+  /* 22 */ 4194304,
+  /* 23 */ 8388608,
+  /* 24 */ 16777216
+};
+
+char *dupString(char *s)
+{
+  char *d;
+
+  if (!s)
+    return(NULL);
+
+  d = (char *)lmalloc(strlen(s) + 1);
+  strcpy(d, s);
+  return(d);
+}
+
+void newRGBMapData(RGBMap *rgb, unsigned int size)
+{
+  rgb->used = 0;
+  rgb->size = size;
+  rgb->compressed = FALSE;
+  rgb->red = (Intensity *)lmalloc(sizeof(Intensity) * size);
+  rgb->green = (Intensity *)lmalloc(sizeof(Intensity) * size);
+  rgb->blue = (Intensity *)lmalloc(sizeof(Intensity) * size);
+}
+
+void freeRGBMapData(RGBMap *rgb)
+{
+  lfree((byte *)rgb->red);
+  lfree((byte *)rgb->green);
+  lfree((byte *)rgb->blue);
+}
+
+Image *newBitImage(unsigned int width, unsigned int height)
+{
+  Image        *image;
+  unsigned int  linelen;
+
+  image = (Image *)lmalloc(sizeof(Image));
+  image->type = IBITMAP;
+  image->title = NULL;
+  newRGBMapData(&(image->rgb), (unsigned int)2);
+  *(image->rgb.red)= *(image->rgb.green) = *(image->rgb.blue)= 65535;
+  *(image->rgb.red + 1)= *(image->rgb.green + 1) = *(image->rgb.blue + 1)= 0;
+  image->rgb.used = 2;
+  image->width = width;
+  image->height = height;
+  image->depth = 1;
+  linelen = ((width + 7) / 8);
+  image->data = (unsigned char *)lcalloc(linelen * height);
+  return(image);
+}
+
+Image *newRGBImage(unsigned int width, unsigned int height, unsigned int depth)
+{
+  Image        *image;
+  unsigned int  pixlen, numcolors;
+
+  if (depth == 0)      /* special case for `zero' depth image, which is */
+    depth = 1;         /* sometimes interpreted as `one color' */
+  pixlen = ((depth+7) / 8);
+  numcolors = depthToColors(depth);
+  image = (Image *)lmalloc(sizeof(Image));
+  image->type = IRGB;
+  image->title = NULL;
+  newRGBMapData(&(image->rgb), numcolors);
+  image->width = width;
+  image->height = height;
+  image->depth = depth;
+  image->pixlen = pixlen;
+  image->data = (unsigned char *)lmalloc(width * height * pixlen);
+  return(image);
+}
+
+void freeImageData(Image *image)
+{
+  if (image->title)
+  {
+    lfree((byte *)image->title);
+    image->title= NULL;
+  }
+  freeRGBMapData(&(image->rgb));
+  lfree(image->data);
+}
+
+void freeImage(Image *image)
+{
+  freeImageData(image);
+  lfree((byte *)image);
+}
+
+byte *lmalloc(unsigned int size)
+{
+  byte *area;
+
+  if (size == 0)
+  {
+    size = 1;
+  }
+  if (!(area = (byte *)malloc(size)))
+  {
+    fprintf(stderr, "Out of memory!\n");
+    exit(1);
+  }
+
+  return(area);
+}
+
+byte *lcalloc(unsigned int size)
+{
+  byte *area;
+
+  if (size == 0)
+  {
+    size = 1;
+  }
+  if (!(area = (byte *)calloc(1, size)))
+  {
+    fprintf(stderr, "Out of memory!\n");
+    exit(1);
+  }
+
+  return(area);
+}
+
+void lfree(byte *area)
+{
+  free(area);
+}
index e85a9f0293eedc30cb86aef174ed6b19d4e620c2..b2fa0d41e012bfe0c8581d2c0befe861e73d1bdb 100644 (file)
@@ -21,7 +21,9 @@
  * It was reworked for the GNU C Library by Roland McGrath.
  */
 
+#ifndef MSDOS
 #include <ansidecl.h>
+#endif
 #include <errno.h>
 #include <limits.h>
 #include <stdlib.h>
index 13bf5fab725dc1a86485bb91f09a1a3f269d911b..90305d7e4adfdfd28cecda7236d7fc45e803413f 100644 (file)
 #include "joystick.h"
 #include "cartoons.h"
 
+#ifdef MSDOS
+extern unsigned char get_ascii(KeySym);
+#endif
+
 void DrawHeadline()
 {
   int x1 = SX+(SXSIZE - strlen(GAMETITLE_STRING) * FONT1_XSIZE) / 2;
@@ -700,6 +704,7 @@ void HandleTypeName(int newxpos, KeySym key)
     return;
   }
 
+#ifndef MSDOS
   if ((key>=XK_A && key<=XK_Z) || (key>=XK_a && key<=XK_z && 
       xpos<MAX_NAMELEN-1))
   {
@@ -707,6 +712,10 @@ void HandleTypeName(int newxpos, KeySym key)
       ascii = 'A'+(char)(key-XK_A);
     if (key>=XK_a && key<=XK_z)
       ascii = 'a'+(char)(key-XK_a);
+#else
+  if((ascii = get_ascii(key)) && xpos<MAX_NAMELEN-1)
+  {
+#endif
     player.alias_name[xpos] = ascii;
     player.alias_name[xpos+1] = 0;
     xpos++;
@@ -1133,12 +1142,17 @@ void CalibrateJoystick()
   } joy_ctrl;
 #endif
 
+#ifdef MSDOS
+  char joy_nr[4];
+#endif
+
   int new_joystick_xleft, new_joystick_xright, new_joystick_xmiddle;
   int new_joystick_yupper, new_joystick_ylower, new_joystick_ymiddle;
 
   if (joystick_status==JOYSTICK_OFF)
     goto error_out;
 
+#ifndef MSDOS
   ClearWindow();
   DrawText(SX+16, SY+7*32, "MOVE JOYSTICK TO",FS_BIG,FC_YELLOW);
   DrawText(SX+16, SY+8*32, " THE UPPER LEFT ",FS_BIG,FC_YELLOW);
@@ -1238,11 +1252,50 @@ void CalibrateJoystick()
   while(Joystick() & JOY_BUTTON);
   return;
 
+#endif
   error_out:
 
+#ifdef MSDOS
+  joy_nr[0] = '#';
+  joy_nr[1] = SETUP_2ND_JOYSTICK_ON(player.setup)+49;
+  joy_nr[2] = '\0';
+
+  remove_joystick();
+  ClearWindow();
+  DrawText(SX+32, SY+7*32, "CENTER JOYSTICK",FS_BIG,FC_YELLOW);
+  DrawText(SX+16+7*32, SY+8*32, joy_nr, FS_BIG,FC_YELLOW);
+  DrawText(SX+32, SY+9*32, "AND PRESS A KEY",FS_BIG,FC_YELLOW);
+  BackToFront();
+
+  for(clear_keybuf();!keypressed(););
+  install_joystick(JOY_TYPE_2PADS);
+
+  ClearWindow();
+  DrawText(SX+16, SY+7*32, "MOVE JOYSTICK TO",FS_BIG,FC_YELLOW);
+  DrawText(SX+16, SY+8*32, " THE UPPER LEFT ",FS_BIG,FC_YELLOW);
+  DrawText(SX+32, SY+9*32, "AND PRESS A KEY",FS_BIG,FC_YELLOW);
+  BackToFront();
+
+  for(clear_keybuf();!keypressed(););
+  calibrate_joystick(SETUP_2ND_JOYSTICK_ON(player.setup));
+
+  ClearWindow();
+  DrawText(SX+16, SY+7*32, "MOVE JOYSTICK TO",FS_BIG,FC_YELLOW);
+  DrawText(SX+32, SY+8*32, "THE LOWER RIGHT",FS_BIG,FC_YELLOW);
+  DrawText(SX+32, SY+9*32, "AND PRESS A KEY",FS_BIG,FC_YELLOW);
+  BackToFront();
+
+  for(clear_keybuf();!keypressed(););
+  calibrate_joystick(SETUP_2ND_JOYSTICK_ON(player.setup));
+
+  DrawSetupScreen();
+  return;
+#endif
+
   ClearWindow();
   DrawText(SX+16, SY+16, "NO JOYSTICK",FS_BIG,FC_YELLOW);
   DrawText(SX+16, SY+48, " AVAILABLE ",FS_BIG,FC_YELLOW);
+  BackToFront();
   Delay(3000000);
   DrawSetupScreen();
 }
diff --git a/src/send.c b/src/send.c
new file mode 100644 (file)
index 0000000..e8f0ffd
--- /dev/null
@@ -0,0 +1,847 @@
+
+/* send.c
+ *
+ * send an Image to an X pixmap
+ */
+
+#include "xli.h"
+
+/* extra colors to try allocating in private color maps to minimise flashing */
+#define NOFLASH_COLORS 256
+
+Image *monochrome(Image *cimage)
+{
+  Image         *image;
+  unsigned char *sp, *dp, *dp2; /* data pointers */
+  unsigned int   spl;           /* source pixel length in bytes */
+  unsigned int   dll;           /* destination line length in bytes */
+  Pixel          color;         /* pixel color */
+  unsigned int   x, y;          /* random counters */
+  int bitmap_pixel;
+
+  if (BITMAPP(cimage))
+    return(NULL);
+
+  printf("  Converting to monochrome...");
+  fflush(stdout);
+
+  image= newBitImage(cimage->width, cimage->height);
+  if (cimage->title)
+  {
+    image->title= (char *)lmalloc(strlen(cimage->title) + 13);
+    sprintf(image->title, "%s (monochrome)", cimage->title);
+  }
+
+  spl = cimage->pixlen;
+  dll = (image->width / 8) + (image->width % 8 ? 1 : 0);
+
+  sp = cimage->data;
+  dp = image->data;
+
+  for (y= 0; y < cimage->height; y++)
+  {
+    for (x= 0; x < cimage->width; x++)
+    {
+      dp2 = dp + (x / 8);      /* dp + x/8 */
+      color= memToVal(sp, spl);
+
+      if (cimage->rgb.red[color] > 0x0000 ||
+         cimage->rgb.green[color] > 0x0000 ||
+         cimage->rgb.blue[color] > 0x0000)
+       bitmap_pixel = 0x00;
+      else
+       bitmap_pixel = 0x80;
+
+      *dp2 |= bitmap_pixel >> ( x % 8);
+      sp += spl;
+    }
+
+    dp += dll; /* next row */
+  }
+
+  printf("done\n");
+
+  return(image);
+}
+
+static unsigned int *buildIndex(unsigned int width,
+                               unsigned int zoom,
+                               unsigned int *rwidth)
+{
+  float         fzoom;
+  unsigned int *index;
+  unsigned int  a;
+
+  if (!zoom)
+  {
+    fzoom= 100.0;
+    *rwidth= width;
+  }
+  else
+  {
+    fzoom= (float)zoom / 100.0;
+    *rwidth= (unsigned int)(fzoom * width + 0.5);
+  }
+  index= (unsigned int *)lmalloc(sizeof(unsigned int) * *rwidth);
+  for (a= 0; a < *rwidth; a++)
+  {
+    if (zoom)
+      *(index + a)= (unsigned int)((float)a / fzoom + 0.5);
+    else
+      *(index + a)= a;
+  }
+  return(index);
+}
+
+Image *zoom(Image *oimage, unsigned int xzoom, unsigned int yzoom)
+{
+  Image        *image;
+  unsigned int *xindex, *yindex;
+  unsigned int  xwidth, ywidth;
+  unsigned int  x, y, xsrc, ysrc;
+  unsigned int  pixlen;
+  unsigned int  srclinelen;
+  unsigned int  destlinelen;
+  byte         *srcline, *srcptr;
+  byte         *destline, *destptr;
+  byte          srcmask, destmask, bit;
+  Pixel         value;
+
+  if ((!xzoom || xzoom==100) && (!yzoom || yzoom==100)) 
+    return(oimage);
+
+  if (!xzoom)
+    printf("  Zooming image Y axis by %d%%...", yzoom);
+  else if (!yzoom)
+    printf("  Zooming image X axis by %d%%...", xzoom);
+  else if (xzoom == yzoom)
+    printf("  Zooming image by %d%%...", xzoom);
+  else
+    printf("  Zooming image X axis by %d%% and Y axis by %d%%...",
+            xzoom, yzoom);
+  fflush(stdout);
+
+  xindex= buildIndex(oimage->width, xzoom, &xwidth);
+  yindex= buildIndex(oimage->height, yzoom, &ywidth);
+
+  switch (oimage->type)
+  {
+    case IBITMAP:
+      image= newBitImage(xwidth, ywidth);
+      for (x= 0; x < oimage->rgb.used; x++)
+      {
+       *(image->rgb.red + x)= *(oimage->rgb.red + x);
+       *(image->rgb.green + x)= *(oimage->rgb.green + x);
+       *(image->rgb.blue + x)= *(oimage->rgb.blue + x);
+      }
+      image->rgb.used= oimage->rgb.used;
+      destline= image->data;
+      destlinelen= (xwidth / 8) + (xwidth % 8 ? 1 : 0);
+      srcline= oimage->data;
+      srclinelen= (oimage->width / 8) + (oimage->width % 8 ? 1 : 0);
+      for (y= 0, ysrc= *(yindex + y); y < ywidth; y++)
+      {
+       while (ysrc != *(yindex + y))
+       {
+         ysrc++;
+         srcline += srclinelen;
+       }
+       srcptr= srcline;
+       destptr= destline;
+       srcmask= 0x80;
+       destmask= 0x80;
+       bit= srcmask & *srcptr;
+       for (x= 0, xsrc= *(xindex + x); x < xwidth; x++)
+       {
+         if (xsrc != *(xindex + x))
+         {
+           do
+           {
+             xsrc++;
+             if (!(srcmask >>= 1))
+             {
+               srcmask= 0x80;
+               srcptr++;
+             }
+           }
+           while (xsrc != *(xindex + x));
+
+           bit= srcmask & *srcptr;
+         }
+         if (bit)
+           *destptr |= destmask;
+         if (!(destmask >>= 1))
+         {
+           destmask= 0x80;
+           destptr++;
+         }
+       }
+       destline += destlinelen;
+      }
+      break;
+
+    case IRGB:
+      image= newRGBImage(xwidth, ywidth, oimage->depth);
+      for (x= 0; x < oimage->rgb.used; x++)
+      {
+       *(image->rgb.red + x)= *(oimage->rgb.red + x);
+       *(image->rgb.green + x)= *(oimage->rgb.green + x);
+       *(image->rgb.blue + x)= *(oimage->rgb.blue + x);
+      }
+      image->rgb.used= oimage->rgb.used;
+
+      pixlen= oimage->pixlen;
+      destptr= image->data;
+      srcline= oimage->data;
+      srclinelen= oimage->width * pixlen;
+      for (y= 0, ysrc= *(yindex + y); y < ywidth; y++)
+      {
+       while (ysrc != *(yindex + y))
+       {
+         ysrc++;
+         srcline += srclinelen;
+       }
+
+       srcptr = srcline;
+       value = memToVal(srcptr, image->pixlen);
+
+       for (x=0, xsrc= *(xindex + x); x<xwidth; x++)
+       {
+         if (xsrc != *(xindex + x))
+         {
+           do
+           {
+             xsrc++;
+             srcptr++;
+           }
+           while (xsrc != *(xindex + x));
+           value = memToVal(srcptr, 1);
+         }
+         valToMem(value, destptr, 1);
+         destptr++;
+       }
+      }
+      break;
+
+    default:
+      /* no zooming */
+      return(oimage);
+      break;
+  }
+
+  image->title = dupString(oimage->title);
+  lfree((byte *)xindex);
+  lfree((byte *)yindex);
+
+  printf("done\n");
+
+  return(image);
+}
+
+void compress(Image *image)
+{
+  unsigned char          *used, fast[32][32][32];
+  unsigned int     dmask;       /* Depth mask protection */
+  Pixel           *map;
+  unsigned int     next_index;
+  Intensity *red = image->rgb.red,
+            *green = image->rgb.green,
+            *blue = image->rgb.blue;
+  Intensity r,g,b;
+  unsigned int x, y, badcount = 0, dupcount = 0, unusedcount = 0;
+  unsigned char *pixptr, *pixend;
+
+  if (!RGBP(image) || image->rgb.compressed)
+    return;
+
+  printf("  Compressing colormap...");
+  fflush(stdout);
+
+  used = (unsigned char *)lcalloc(sizeof(unsigned char) * depthToColors(image->depth));
+  dmask = (1 << image->depth) -1;      /* Mask any illegal bits for that depth */
+  map = (Pixel *)lcalloc(sizeof(Pixel) * depthToColors(image->depth));
+
+  /* init fast duplicate check table */
+  for(r=0;r<32;r++)
+    for(g=0;g<32;g++)
+      for(b=0;b<32;b++)
+        fast[r][g][b] = 0;
+
+  /* do pass 1 through the image to check index usage */
+
+  pixptr = image->data;
+  pixend = pixptr + (image->height * image->width);
+  for(;pixptr < pixend; pixptr++)
+    used[(*pixptr) & dmask] = 1;
+
+  /* count the bad pixels */
+  for (x = image->rgb.used; x < depthToColors(image->depth); x++)
+    if (used[x])
+      badcount++;
+
+  /* figure out duplicates and unuseds, and create the new mapping */
+  next_index = 0;
+  for (x = 0; x < image->rgb.used; x++)
+  {
+    if (!used[x])
+    {
+      unusedcount++;
+      continue;                /* delete this index */
+    }
+
+    /* check for duplicate */
+    r = red[x];
+    g = green[x];
+    b = blue[x];
+    if (fast[r>>11][g>>11][b>>11])     /* if matches fast check */
+    {
+      /* then do a linear search */
+      for (y = x+1; y < image->rgb.used; y++)
+      {
+        if (r == red[y] && g == green[y] && b == blue[y])
+          break;
+      }
+      if (y < image->rgb.used) /* found match */
+      {
+       map[x] = y;
+        dupcount++;
+       continue;               /* delete this index */
+      }
+      fast[r>>11][g>>11][b>>11] = 1;
+    }
+    /* will map to this index */
+    map[x] = next_index;
+    next_index++;
+  }
+
+  /* change the image pixels */
+  pixptr = image->data;
+  pixend = pixptr + (image->height * image->width);
+  for(;pixptr < pixend; pixptr++)
+    *pixptr = map[(*pixptr) & dmask];
+
+  /* change the colormap */
+  for (x = 0; x < image->rgb.used; x++)
+  {
+    if (!used[x])
+      continue;
+    red[map[x]] = red[x];
+    green[map[x]] = green[x];
+    blue[map[x]] = blue[x];
+  }
+  image->rgb.used = next_index;
+
+  /* clean up */
+  lfree(map);
+  lfree(used);
+
+  if (badcount)
+    printf("%d out-of-range pixels, ", badcount);
+
+  if (!unusedcount && !dupcount)
+    printf("no improvment\n");
+  else
+  {
+    if (dupcount)
+      printf("%d duplicate%s and %d unused color%s removed...",
+            dupcount, (dupcount == 1 ? "" : "s"),
+            unusedcount, (unusedcount == 1 ? "" : "s"));
+    printf("%d unique color%s\n",
+          next_index, (next_index == 1 ? "" : "s"));
+  }
+
+  image->rgb.compressed= TRUE; /* don't do it again */
+}
+
+
+
+
+Pixmap ximageToPixmap(Display *disp, Window parent, XImageInfo *ximageinfo)
+{
+  Pixmap pixmap;
+
+  pixmap = XCreatePixmap(disp, parent,
+                        ximageinfo->ximage->width, ximageinfo->ximage->height,
+                        ximageinfo->depth);
+
+  ximageinfo->drawable = pixmap;
+
+  sendXImage(ximageinfo, 0, 0, 0, 0,
+            ximageinfo->ximage->width, ximageinfo->ximage->height);
+  return(pixmap);
+}
+
+/* find the best pixmap depth supported by the server for a particular
+ * visual and return that depth.
+ *
+ * this is complicated by R3's lack of XListPixmapFormats so we fake it
+ * by looking at the structure ourselves.
+ */
+
+static unsigned int bitsPerPixelAtDepth(Display *disp, int scrn,
+                                       unsigned int depth)
+{
+#if defined(XlibSpecificationRelease) && (XlibSpecificationRelease >= 4)
+  /* the way things are */
+  XPixmapFormatValues *xf;
+  int nxf, a;
+
+  xf = XListPixmapFormats(disp, &nxf);
+  for (a = 0; a < nxf; a++)
+  {
+    if (xf[a].depth == depth)
+    {
+      int bpp;
+      bpp = xf[a].bits_per_pixel;
+      XFree(xf);
+      return (unsigned int) bpp;
+    }
+  }
+  XFree(xf);
+#else /* the way things were (X11R3) */
+  unsigned int a;
+
+  for (a= 0; a < disp->nformats; a++)
+    if (disp->pixmap_format[a].depth == depth)
+      return(disp->pixmap_format[a].bits_per_pixel);
+#endif
+
+  /* this should never happen; if it does, we're in trouble
+   */
+
+  fprintf(stderr, "bitsPerPixelAtDepth: Can't find pixmap depth info!\n");
+  exit(1);
+}
+
+/*
+  visual: visual to use
+  ddepth: depth of the visual to use
+*/
+XImageInfo *imageToXImage(Display *disp,
+                         int scrn,
+                         Visual *visual,
+                         unsigned int ddepth,
+                         Image *image)
+{
+  Pixel        *redvalue, *greenvalue, *bluevalue;
+  unsigned int  a, c=0, x, y, linelen, dpixlen, dbits;
+  XColor        xcolor;
+  XGCValues     gcv;
+  XImageInfo   *ximageinfo;
+  Image        *orig_image;
+
+  static Colormap our_default_cmap = 0;
+  static Pixel *our_default_index;
+  static int free_cmap_entries, max_cmap_entries;
+  int use_cmap_entry;
+
+  if (!our_default_cmap)
+  {
+#if 0
+    our_default_cmap = DefaultColormap(disp, scrn);
+#endif
+
+    our_default_cmap = XCreateColormap(disp, RootWindow(disp, scrn),
+                                      visual, AllocNone);
+    our_default_index = (Pixel *)lmalloc(sizeof(Pixel) * NOFLASH_COLORS);
+
+    for (a=0; a<NOFLASH_COLORS; a++)   /* count entries we got */
+      if (!XAllocColorCells(disp, our_default_cmap, FALSE, NULL, 0,
+                           our_default_index + a, 1))
+       break;
+
+    free_cmap_entries = max_cmap_entries = a;
+
+    printf("We've got %d colormap entries.\n", free_cmap_entries);
+
+    for(a=0; a<max_cmap_entries; a++)  /* copy default colors */
+    {
+      xcolor.pixel = *(our_default_index + a);
+      XQueryColor(disp, DefaultColormap(disp, scrn), &xcolor);
+      XStoreColor(disp, our_default_cmap, &xcolor);
+    }
+  }
+
+  xcolor.flags= DoRed | DoGreen | DoBlue;
+  redvalue= greenvalue= bluevalue= NULL;
+  orig_image= image;
+  ximageinfo= (XImageInfo *)lmalloc(sizeof(XImageInfo));
+  ximageinfo->disp= disp;
+  ximageinfo->scrn= scrn;
+  ximageinfo->depth= 0;
+  ximageinfo->drawable= None;
+  ximageinfo->index= NULL;
+  ximageinfo->rootimage= FALSE;        /* assume not */
+  ximageinfo->foreground= ximageinfo->background= 0;
+  ximageinfo->gc= NULL;
+  ximageinfo->ximage= NULL;
+
+  /* do color allocation
+   */
+
+  switch (visual->class)
+  {
+    case TrueColor:
+    case DirectColor:
+    {
+      Pixel pixval;
+      unsigned int redcolors, greencolors, bluecolors;
+      unsigned int redstep, greenstep, bluestep;
+      unsigned int redbottom, greenbottom, bluebottom;
+      unsigned int redtop, greentop, bluetop;
+
+      redvalue= (Pixel *)lmalloc(sizeof(Pixel) * 256);
+      greenvalue= (Pixel *)lmalloc(sizeof(Pixel) * 256);
+      bluevalue= (Pixel *)lmalloc(sizeof(Pixel) * 256);
+
+#if 1
+      if (visual == DefaultVisual(disp, scrn))
+       ximageinfo->cmap= DefaultColormap(disp, scrn);
+      else
+       ximageinfo->cmap= XCreateColormap(disp, RootWindow(disp, scrn),
+                                         visual, AllocNone);
+#else
+      ximageinfo->cmap = our_default_cmap;
+#endif
+
+      retry_direct: /* tag we hit if a DirectColor allocation fails on
+                    * default colormap */
+
+      /* calculate number of distinct colors in each band
+       */
+
+      redcolors= greencolors= bluecolors= 1;
+      for (pixval= 1; pixval; pixval <<= 1)
+      {
+       if (pixval & visual->red_mask)
+         redcolors <<= 1;
+       if (pixval & visual->green_mask)
+         greencolors <<= 1;
+       if (pixval & visual->blue_mask)
+         bluecolors <<= 1;
+      }
+      
+      /* sanity check
+       */
+
+      if ((redcolors > visual->map_entries) ||
+         (greencolors > visual->map_entries) ||
+         (bluecolors > visual->map_entries))
+      {
+       fprintf(stderr, "Warning: inconsistency in color information (this may be ugly)\n");
+      }
+
+      redstep = 256 / redcolors;
+      greenstep = 256 / greencolors;
+      bluestep = 256 / bluecolors;
+      redbottom = greenbottom = bluebottom = 0;
+      redtop = greentop = bluetop = 0;
+      for (a= 0; a < visual->map_entries; a++)
+      {
+       if (redbottom < 256)
+         redtop= redbottom + redstep;
+       if (greenbottom < 256)
+         greentop= greenbottom + greenstep;
+       if (bluebottom < 256)
+         bluetop= bluebottom + bluestep;
+
+       xcolor.red= (redtop - 1) << 8;
+       xcolor.green= (greentop - 1) << 8;
+       xcolor.blue= (bluetop - 1) << 8;
+       if (! XAllocColor(disp, ximageinfo->cmap, &xcolor))
+       {
+         /* if an allocation fails for a DirectColor default visual then
+          * we should create a private colormap and try again.
+          */
+
+         if ((visual->class == DirectColor) &&
+             (visual == DefaultVisual(disp, scrn)))
+         {
+#if 1
+           ximageinfo->cmap = XCreateColormap(disp, RootWindow(disp, scrn),
+                                              visual, AllocNone);
+#else
+           our_default_cmap = XCopyColormapAndFree(disp, our_default_cmap);
+           ximageinfo->cmap = our_default_cmap;
+#endif
+           goto retry_direct;
+         }
+
+         /* something completely unexpected happened
+          */
+
+         fprintf(stderr, "imageToXImage: XAllocColor failed on a TrueColor/Directcolor visual\n");
+          lfree((byte *)redvalue);
+          lfree((byte *)greenvalue);
+          lfree((byte *)bluevalue);
+          lfree((byte *)ximageinfo);
+         return(NULL);
+       }
+
+       /* fill in pixel values for each band at this intensity
+        */
+
+       while ((redbottom < 256) && (redbottom < redtop))
+         redvalue[redbottom++]= xcolor.pixel & visual->red_mask;
+       while ((greenbottom < 256) && (greenbottom < greentop))
+         greenvalue[greenbottom++]= xcolor.pixel & visual->green_mask;
+       while ((bluebottom < 256) && (bluebottom < bluetop))
+         bluevalue[bluebottom++]= xcolor.pixel & visual->blue_mask;
+      }
+    }
+    break;
+
+  default:     /* Not TrueColor or DirectColor */
+
+    ximageinfo->index= (Pixel *)lmalloc(sizeof(Pixel) * (image->rgb.used+NOFLASH_COLORS));
+
+
+    /* get the colormap to use.
+     */
+
+    ximageinfo->cmap = our_default_cmap;
+
+    /* allocate colors shareable (if we can)
+     */
+
+    for (a= 0; a < image->rgb.used; a++)
+    {
+      int i;
+      XColor xcolor2;
+
+      xcolor.red= *(image->rgb.red + a);
+      xcolor.green= *(image->rgb.green + a);
+      xcolor.blue= *(image->rgb.blue + a);
+
+      for (i=max_cmap_entries-1; i>=free_cmap_entries; i--)
+      {
+       xcolor2.pixel = *(our_default_index + i);
+       XQueryColor(disp, ximageinfo->cmap, &xcolor2);
+
+       if ((xcolor.red >> 8) == (xcolor2.red >> 8) &&
+           (xcolor.green >> 8) == (xcolor2.green >> 8) &&
+           (xcolor.blue >> 8) == (xcolor2.blue >> 8))
+         break;
+      }
+
+      use_cmap_entry = i;
+
+      if (use_cmap_entry < free_cmap_entries)
+       free_cmap_entries--;
+
+      if (free_cmap_entries < 0)
+      {
+       printf("imageToXImage: too many global colors!\n");
+       exit(0);
+      }
+
+      xcolor.pixel = use_cmap_entry;
+      *(ximageinfo->index + a) = xcolor.pixel;
+      XStoreColor(disp, ximageinfo->cmap, &xcolor);
+    }
+
+    ximageinfo->no = a;    /* number of pixels allocated in default visual */
+
+    printf("still %d free colormap entries\n", free_cmap_entries);
+  }
+
+
+
+  /* create an XImage and related colormap based on the image type
+   * we have.
+   */
+
+  printf("  Building XImage...");
+  fflush(stdout);
+
+  switch (image->type)
+  {
+    case IBITMAP:
+    {
+      byte *data;
+
+      /* we copy the data to be more consistent
+       */
+
+      linelen = ((image->width + 7) / 8);
+      data= lmalloc(linelen * image->height);
+
+      memcpy((char *)data, (char *)image->data, linelen * image->height);
+
+      gcv.function= GXcopy;
+      ximageinfo->ximage= XCreateImage(disp, visual, 1, XYBitmap,
+                                      0, (char *)data, image->width, image->height,
+                                      8, linelen);
+
+      /* use this if you want to use the bitmap as a mask */
+      ximageinfo->depth = image->depth;
+
+      if(visual->class == DirectColor || visual->class == TrueColor)
+      {
+        Pixel pixval;
+        dbits= bitsPerPixelAtDepth(disp, scrn, ddepth);
+        dpixlen= (dbits + 7) / 8;
+        pixval= redvalue[image->rgb.red[0] >> 8] |
+                greenvalue[image->rgb.green[0] >> 8] |
+                bluevalue[image->rgb.blue[0] >> 8];
+        ximageinfo->background = pixval;
+        pixval= redvalue[image->rgb.red[1] >> 8] |
+                greenvalue[image->rgb.green[1] >> 8] |
+                bluevalue[image->rgb.blue[1] >> 8];
+        ximageinfo->foreground = pixval;
+      }
+      else     /* Not Direct or True Color */
+      {
+        ximageinfo->foreground = BlackPixel(disp,scrn);
+        ximageinfo->background = WhitePixel(disp,scrn);
+      }
+      ximageinfo->ximage->bitmap_bit_order= MSBFirst;
+      ximageinfo->ximage->byte_order= MSBFirst;
+
+      break;
+    }
+
+    case IRGB:
+    {
+      /* modify image data to match visual and colormap
+       */
+
+      byte *data, *destptr, *srcptr;
+
+      dbits = bitsPerPixelAtDepth(disp, scrn, ddepth); /* bits per pixel */
+      dpixlen = (dbits + 7) / 8;                       /* bytes per pixel */
+
+      ximageinfo->ximage = XCreateImage(disp, visual, ddepth, ZPixmap, 0,
+                                       NULL, image->width, image->height,
+                                       8, image->width * dpixlen);
+
+      data = (byte *)lmalloc(image->width * image->height * dpixlen);
+      ximageinfo->depth = ddepth;
+      ximageinfo->ximage->data = (char *)data;
+      ximageinfo->ximage->byte_order = MSBFirst;
+      srcptr = image->data;
+      destptr = data;
+
+      switch (visual->class)
+      {
+       case DirectColor:
+       case TrueColor:
+       {
+         Pixel pixval;
+
+         for (y=0; y<image->height; y++)
+         {
+           for (x=0; x<image->width; x++)
+           {
+             pixval = memToVal(srcptr, 1);
+             pixval = redvalue[image->rgb.red[pixval] >> 8] |
+               greenvalue[image->rgb.green[pixval] >> 8] |
+               bluevalue[image->rgb.blue[pixval] >> 8];
+             valToMem(pixval, destptr, dpixlen);
+             srcptr += 1;
+             destptr += dpixlen;
+           }
+         }
+         break;
+       }
+  
+        default:
+       {  
+         if (dpixlen == 1)                     /* most common */
+         {
+           for (y=0; y<image->height; y++)
+           {
+             for (x=0; x<image->width; x++)
+             {
+               *destptr = ximageinfo->index[c + *srcptr];
+               srcptr++;
+               destptr++;
+             }
+           }
+         }
+         else                                  /* less common */
+         {
+           for (y=0; y<image->height; y++)
+           {
+             for (x=0; x<image->width; x++)
+             {
+               register unsigned long temp;
+               temp = memToVal(srcptr, 1);
+               valToMem(ximageinfo->index[c + temp], destptr, dpixlen);
+               srcptr += 1;
+               destptr += dpixlen;
+             }
+           }
+         }
+       }
+       break;
+      }
+    }
+  }
+
+  printf("done\n");
+
+  if (redvalue)
+  {
+    lfree((byte *)redvalue);
+    lfree((byte *)greenvalue);
+    lfree((byte *)bluevalue);
+  }
+
+  if (image != orig_image)
+    freeImage(image);
+  return(ximageinfo);
+}
+
+/* Given an XImage and a drawable, move a rectangle from the Ximage
+ * to the drawable.
+ */
+
+void sendXImage(XImageInfo *ximageinfo,
+               int src_x, int src_y, int dst_x, int dst_y,
+               unsigned int w, unsigned int h)
+{
+  XGCValues gcv;
+
+  /* build and cache the GC
+   */
+
+  if (!ximageinfo->gc)
+  {
+    gcv.function = GXcopy;
+    if (ximageinfo->ximage->depth == 1)
+    {
+      gcv.foreground = ximageinfo->foreground;
+      gcv.background = ximageinfo->background;
+      ximageinfo->gc = XCreateGC(ximageinfo->disp, ximageinfo->drawable,
+                                GCFunction | GCForeground | GCBackground,
+                                &gcv);
+    }
+    else
+      ximageinfo->gc = XCreateGC(ximageinfo->disp, ximageinfo->drawable,
+                                GCFunction, &gcv);
+  }
+
+  XPutImage(ximageinfo->disp, ximageinfo->drawable, ximageinfo->gc,
+           ximageinfo->ximage, src_x, src_y, dst_x, dst_y, w, h);
+}
+
+/* free up anything cached in the local Ximage structure.
+ */
+
+void freeXImage(Image *image, XImageInfo *ximageinfo)
+{
+  if (ximageinfo->index != NULL)       /* if we allocated colors */
+  {
+    if (ximageinfo->no > 0 && !ximageinfo->rootimage)  /* don't free root colors */
+      XFreeColors(ximageinfo->disp, ximageinfo->cmap, ximageinfo->index, ximageinfo->no, 0);
+    lfree(ximageinfo->index);
+  }
+  if (ximageinfo->gc)
+    XFreeGC(ximageinfo->disp, ximageinfo->gc);
+  lfree((byte *)ximageinfo->ximage->data);
+  ximageinfo->ximage->data= NULL;
+  XDestroyImage(ximageinfo->ximage);
+  lfree((byte *)ximageinfo);
+  /* should we free private color map to ??? */
+}
index 3ee23f3024e16f80a11e5d697f061346e9e2bd06..516892b5d1e8ff841bf8bf73372f98e7a8d50044 100644 (file)
 ***********************************************************/
 
 #include "sound.h"
+#ifdef MSDOS
+extern void sound_handler(struct SoundControl);
+#endif
 
 /*** THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS ***/
 
+#ifndef MSDOS
 static struct SoundControl playlist[MAX_SOUNDS_PLAYING];
 static struct SoundControl emptySoundControl =
 {
@@ -28,18 +32,27 @@ static char premix_right_buffer[SND_BLOCKSIZE];
 static int premix_last_buffer[SND_BLOCKSIZE];
 static unsigned char playing_buffer[SND_BLOCKSIZE];
 static int playing_sounds = 0;
+#else
+struct SoundControl playlist[MAX_SOUNDS_PLAYING];
+struct SoundControl emptySoundControl;
+int playing_sounds;
+#endif
 
 void SoundServer()
 {
+  int i;
+#ifndef MSDOS
   struct SoundControl snd_ctrl;
   fd_set sound_fdset;
-  int i;
 
   close(sound_pipe[1]);                /* no writing into pipe needed */
+#endif
 
   for(i=0;i<MAX_SOUNDS_PLAYING;i++)
     playlist[i] = emptySoundControl;
+  playing_sounds = 0;
 
+#ifndef MSDOS
   stereo_volume[PSND_MAX_LEFT2RIGHT] = 0;
   for(i=0;i<PSND_MAX_LEFT2RIGHT;i++)
     stereo_volume[i] =
@@ -295,6 +308,7 @@ void SoundServer()
 #endif /* von '#ifdef VOXWARE' */
 
   }
+#endif
 }
 
 void SoundServer_InsertNewSound(struct SoundControl snd_ctrl)
@@ -308,8 +322,11 @@ void SoundServer_InsertNewSound(struct SoundControl snd_ctrl)
 
     for(i=0;i<MAX_SOUNDS_PLAYING;i++)
     {
-      int actual =
-       100 * playlist[i].playingpos / playlist[i].data_len;
+#ifndef MSDOS
+      int actual = 100 * playlist[i].playingpos / playlist[i].data_len;
+#else
+      int actual = playlist[i].playingpos;
+#endif
 
       if (!playlist[i].loop && actual>longest)
       {
@@ -317,6 +334,10 @@ void SoundServer_InsertNewSound(struct SoundControl snd_ctrl)
        longest_nr=i;
       }
     }
+#ifdef MSDOS
+    voice_set_volume(playlist[longest_nr].voice, 0);
+    deallocate_voice(playlist[longest_nr].voice);
+#endif
     playlist[longest_nr] = emptySoundControl;
     playing_sounds--;
   }
@@ -337,6 +358,11 @@ void SoundServer_InsertNewSound(struct SoundControl snd_ctrl)
       {
        playlist[i].fade_sound = FALSE;
        playlist[i].volume = PSND_MAX_VOLUME;
+#ifdef MSDOS
+        playlist[i].loop = PSND_LOOP;
+        voice_stop_volumeramp(playlist[i].voice);
+        voice_ramp_volume(playlist[i].voice, playlist[i].volume, 1000);
+#endif
       }
     }
     return;
@@ -355,13 +381,21 @@ void SoundServer_InsertNewSound(struct SoundControl snd_ctrl)
       if (!playlist[i].active || playlist[i].nr != snd_ctrl.nr)
        continue;
 
+#ifndef MSDOS
       actual = 100 * playlist[i].playingpos / playlist[i].data_len;
+#else
+      actual = playlist[i].playingpos;
+#endif
       if (actual>=longest)
       {
        longest=actual;
        longest_nr=i;
       }
     }
+#ifdef MSDOS
+    voice_set_volume(playlist[longest_nr].voice, 0);
+    deallocate_voice(playlist[longest_nr].voice);
+#endif
     playlist[longest_nr] = emptySoundControl;
     playing_sounds--;
   }
@@ -373,6 +407,14 @@ void SoundServer_InsertNewSound(struct SoundControl snd_ctrl)
     {
       playlist[i] = snd_ctrl;
       playing_sounds++;
+#ifdef MSDOS
+      playlist[i].voice = allocate_voice(Sound[snd_ctrl.nr].sample_ptr);
+      if(snd_ctrl.loop)
+        voice_set_playmode(playlist[i].voice, PLAYMODE_LOOP);
+      voice_set_volume(playlist[i].voice, snd_ctrl.volume);
+      voice_set_pan(playlist[i].voice, snd_ctrl.stereo);
+      voice_start(playlist[i].voice);       
+#endif
       break;
     }
   }
@@ -402,12 +444,18 @@ void SoundServer_StopSound(int nr)
   for(i=0;i<MAX_SOUNDS_PLAYING;i++)
     if (playlist[i].nr == nr)
     {
+#ifdef MSDOS
+      voice_set_volume(playlist[i].voice, 0);
+      deallocate_voice(playlist[i].voice);
+#endif
       playlist[i] = emptySoundControl;
       playing_sounds--;
     }
 
+#ifndef MSDOS
   if (!playing_sounds)
     close(sound_device);
+#endif
 }
 
 void SoundServer_StopAllSounds()
@@ -415,10 +463,18 @@ void SoundServer_StopAllSounds()
   int i;
 
   for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+  {
+#ifdef MSDOS
+    voice_set_volume(playlist[i].voice, 0);
+    deallocate_voice(playlist[i].voice);
+#endif
     playlist[i]=emptySoundControl;
-  playing_sounds=0;
+  }
+  playing_sounds = 0;
 
+#ifndef MSDOS
   close(sound_device);
+#endif
 }
 
 #ifdef HPUX_AUDIO
@@ -574,12 +630,17 @@ BOOL LoadSound(struct SoundInfo *snd_info)
 {
   FILE *file;
   char filename[256];
+#ifndef MSDOS
   char *sound_ext = "8svx";
+#else
+  char *sound_ext = "wav";
+#endif
   struct SoundHeader_8SVX *sound_header;
   unsigned char *ptr;
 
   sprintf(filename,"%s/%s.%s",SND_PATH,snd_info->name,sound_ext);
 
+#ifndef MSDOS
   if (!(file=fopen(filename,"r")))
   {
     fprintf(stderr,"%s: cannot open sound file '%s' - no sounds\n",
@@ -661,6 +722,17 @@ BOOL LoadSound(struct SoundInfo *snd_info)
   }
 
   return(FALSE);
+#else
+  snd_info->sample_ptr = load_sample(filename);
+  if(!snd_info->sample_ptr)
+  {
+    fprintf(stderr,"%s: cannot read sound file '%s' - no sounds\n",
+           progname,filename);
+    fclose(file);
+    return(FALSE);
+  }
+  return(TRUE);
+#endif  // von  #ifndef MSDOS
 }
 
 void PlaySound(int nr)
@@ -703,12 +775,16 @@ void PlaySoundExt(int nr, int volume, int stereo, BOOL loop)
   snd_ctrl.data_ptr    = Sound[nr].data_ptr;
   snd_ctrl.data_len    = Sound[nr].data_len;
 
+#ifndef MSDOS
   if (write(sound_pipe[1], &snd_ctrl, sizeof(snd_ctrl))<0)
   {
     fprintf(stderr,"%s: cannot pipe to child process - no sounds\n",progname);
     sound_status=SOUND_OFF;
     return;
   }
+#else
+  sound_handler(snd_ctrl);
+#endif
 }
 
 void FadeSound(int nr)
@@ -749,12 +825,16 @@ void StopSoundExt(int nr, int method)
     snd_ctrl.stop_sound = TRUE;
   }
 
+#ifndef MSDOS
   if (write(sound_pipe[1], &snd_ctrl, sizeof(snd_ctrl))<0)
   {
     fprintf(stderr,"%s: cannot pipe to child process - no sounds\n",progname);
     sound_status=SOUND_OFF;
     return;
   }
+#else
+  sound_handler(snd_ctrl);
+#endif
 }
 
 void FreeSounds(int max)
@@ -765,7 +845,11 @@ void FreeSounds(int max)
     return;
 
   for(i=0;i<max;i++)
+#ifndef MSDOS
     free(Sound[i].file_ptr);
+#else
+    destroy_sample(Sound[i].sample_ptr);
+#endif
 }
 
 /*** THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS ***/
index 089c44fbcb9c2ef620c59fd4b9c4cc30c5861c3f..213cd746739b02abc5c368a338fac99f1aa5f43d 100644 (file)
@@ -40,9 +40,14 @@ extern void ioctl(long, long, void *);
 #define HPUX_AUDIO
 #endif /* _HPUX_SOURCE */
 
+#ifndef MSDOS
 #define MAX_SOUNDS_PLAYING     16
+#else
+#define MAX_SOUNDS_PLAYING     8
+#endif
 
 /* some values for PlaySound(), StopSound() and friends */
+#ifndef MSDOS
 #define PSND_SILENCE           0
 #define PSND_MAX_VOLUME_BITS   7
 #define PSND_MIN_VOLUME                0
@@ -56,6 +61,16 @@ extern void ioctl(long, long, void *);
 #define PSND_MAX_RIGHT         (+PSND_MAX_STEREO)
 #define PSND_MAX_LEFT2RIGHT_BITS (PSND_MAX_STEREO_BITS+1)
 #define PSND_MAX_LEFT2RIGHT    (1 << PSND_MAX_LEFT2RIGHT_BITS)
+#else
+#define PSND_SILENCE           0
+#define PSND_MIN_VOLUME                0
+#define PSND_MAX_VOLUME                255
+#define PSND_NO_LOOP           0
+#define PSND_LOOP              1
+#define PSND_MAX_LEFT          0
+#define PSND_MAX_RIGHT         255
+#define PSND_MIDDLE            128
+#endif
 
 #define SSND_FADE_SOUND                (1<<0)
 #define SSND_FADE_ALL_SOUNDS   (1<<1)
@@ -114,6 +129,9 @@ struct SoundInfo
   unsigned char *file_ptr;
   char *data_ptr;
   long file_len, data_len;
+#ifdef MSDOS
+  SAMPLE *sample_ptr;
+#endif
 };
 
 struct SoundControl
@@ -130,6 +148,9 @@ struct SoundControl
   long playingpos;
   long data_len;
   char *data_ptr;
+#ifdef MSDOS
+  int voice;
+#endif
 };
 
 /* sound server functions */
index befacb27d300fe6b6cb142b4ef7af1621dad0a8a..53290c195d93d05deb93c5ba8f24387e6cedbddc 100644 (file)
 
 #include <math.h>
 
+#ifdef MSDOS
+extern BOOL wait_for_vsync;
+#endif
+
 void SetDrawtoField(int mode)
 {
   if (mode == DRAW_BUFFERED && soft_scrolling_on)
@@ -84,6 +88,9 @@ void BackToFront()
 
   if (redraw_mask & REDRAW_FIELD)
   {
+#ifdef MSDOS
+    wait_for_vsync = TRUE;
+#endif
     if (game_status != PLAYING || redraw_mask & REDRAW_FROM_BACKBUFFER)
       XCopyArea(display,backbuffer,window,gc,
                REAL_SX,REAL_SY, FULL_SXSIZE,FULL_SYSIZE,
@@ -116,6 +123,9 @@ void BackToFront()
 
   if (redraw_mask & REDRAW_DOORS)
   {
+#ifdef MSDOS
+    wait_for_vsync = TRUE;
+#endif
     if (redraw_mask & REDRAW_DOOR_1)
       XCopyArea(display,backbuffer,window,gc,
                DX,DY, DXSIZE,DYSIZE,
@@ -1469,6 +1479,9 @@ BOOL AreYouSure(char *text, unsigned int ays_state)
        case FocusOut:
          HandleFocusEvent((XFocusChangeEvent *) &event);
          break;
+        case ClientMessage:
+         HandleClientMessageEvent((XClientMessageEvent *) &event);
+         break;
        default:
          break;
       }
@@ -1553,6 +1566,10 @@ unsigned int MoveDoor(unsigned int door_state)
   static unsigned int door2 = DOOR_CLOSE_2;
   int x, start, stepsize = 4, door_anim_delay = stepsize*5000;
 
+#ifdef MSDOS
+  stepsize = 2;
+#endif
+
   if (door_state == DOOR_GET_STATE)
     return(door1 | door2);
 
@@ -1656,7 +1673,9 @@ unsigned int MoveDoor(unsigned int door_state)
       }
 
       BackToFront();
+#ifndef MSDOS
       Delay(door_anim_delay);
+#endif
 
       if (game_status==MAINMENU)
        DoAnimation();
diff --git a/src/xli.h b/src/xli.h
new file mode 100644 (file)
index 0000000..1bdf669
--- /dev/null
+++ b/src/xli.h
@@ -0,0 +1,154 @@
+
+/* xli.h:
+ *
+ * jim frost 06.21.89
+ *
+ * Copyright 1989 Jim Frost.  See included file "copyright.h" for complete
+ * copyright information.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <malloc.h>
+
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/cursorfont.h>
+
+typedef unsigned long  Pixel;     /* what X thinks a pixel is */
+typedef unsigned short Intensity; /* what X thinks an RGB intensity is */
+typedef unsigned char  byte;      /* unsigned byte type */
+
+#define FALSE 0
+#define TRUE (!FALSE)
+
+/* Display device dependent Information structure */
+typedef struct
+{
+  int  width;          /* Display width and height */
+  int  height;
+
+  Display      *disp;
+  int           scrn;
+  Colormap      colormap;
+} DisplayInfo;
+
+/* This struct holds the X-client side bits for a rendered image. */
+typedef struct
+{
+  Display  *disp;       /* destination display */
+  int       scrn;       /* destination screen */
+  int       depth;      /* depth of drawable we want/have */
+  Drawable  drawable;   /* drawable to send image to */
+  Pixel    *index;     /* array of pixel values allocated */
+  int       no;                /* number of pixels in the array */
+  int       rootimage; /* True if is a root image - eg, retain colors */
+  Pixel     foreground; /* foreground and background pixels for mono images */
+  Pixel     background;
+  Colormap  cmap;       /* colormap used for image */
+  GC        gc;         /* cached gc for sending image */
+  XImage   *ximage;     /* ximage structure */
+} XImageInfo;
+
+/* Function declarations */
+void        sendXImage(); /* send.c */
+XImageInfo *imageToXImage();
+Pixmap      ximageToPixmap();
+void        freeXImage();
+
+
+typedef struct rgbmap {
+  unsigned int  size;       /* size of RGB map */
+  unsigned int  used;       /* number of colors used in RGB map */
+  int           compressed; /* image uses colormap fully */
+  Intensity    *red;        /* color values in X style */
+  Intensity    *green;
+  Intensity    *blue;
+} RGBMap;
+
+/* image structure
+ */
+
+typedef struct {
+  char         *title;  /* name of image */
+  unsigned int  type;   /* type of image */
+  RGBMap        rgb;    /* RGB map of image if IRGB type */
+  unsigned int  width;  /* width of image in pixels */
+  unsigned int  height; /* height of image in pixels */
+  unsigned int  depth;  /* depth of image in bits if IRGB type */
+  unsigned int  pixlen; /* length of pixel if IRGB type */
+  byte         *data;   /* data rounded to full byte for each row */
+  float                gamma;  /* gamma of display the image is adjusted for */
+} Image;
+
+#define IBITMAP 0 /* image is a bitmap */
+#define IRGB    1 /* image is RGB */
+
+#define BITMAPP(IMAGE) ((IMAGE)->type == IBITMAP)
+#define RGBP(IMAGE)    ((IMAGE)->type == IRGB)
+
+#define depthToColors(n) DepthToColorsTable[((n) < 24 ? (n) : 24)]
+
+/*
+ * Architecture independent memory to value conversions.
+ * Note the "Normal" internal format is big endian.
+ */
+
+#define memToVal(PTR,LEN) (                                   \
+(LEN) == 1 ? (unsigned long)(                 *( (byte *)(PTR))         ) :    \
+(LEN) == 2 ? (unsigned long)(((unsigned long)(*( (byte *)(PTR))   ))<< 8)      \
+                          + (                 *(((byte *)(PTR))+1)      ) :    \
+(LEN) == 3 ? (unsigned long)(((unsigned long)(*( (byte *)(PTR))   ))<<16)      \
+                          + (((unsigned long)(*(((byte *)(PTR))+1)))<< 8)      \
+                                                 + (                 *(((byte *)(PTR))+2)      ) :    \
+             (unsigned long)(((unsigned long)(*( (byte *)(PTR))   ))<<24)      \
+                                                 + (((unsigned long)(*(((byte *)(PTR))+1)))<<16)      \
+                                                 + (((unsigned long)(*(((byte *)(PTR))+2)))<< 8)      \
+                                                 + (                 *(((byte *)(PTR))+3)      ) )
+
+#define valToMem(VAL,PTR,LEN)  (                                          \
+(LEN) == 1 ? (*( (byte *)(PTR)   ) = ( VAL     ) ) : \
+(LEN) == 2 ? (*( (byte *)(PTR)   ) = (((unsigned long)(VAL))>> 8),        \
+              *(((byte *)(PTR))+1) = ( VAL     ) ) : \
+(LEN) == 3 ? (*( (byte *)(PTR)   ) = (((unsigned long)(VAL))>>16),        \
+              *(((byte *)(PTR))+1) = (((unsigned long)(VAL))>> 8),        \
+              *(((byte *)(PTR))+2) = ( VAL     ) ) : \
+             (*( (byte *)(PTR)   ) = (((unsigned long)(VAL))>>24),        \
+              *(((byte *)(PTR))+1) = (((unsigned long)(VAL))>>16),        \
+              *(((byte *)(PTR))+2) = (((unsigned long)(VAL))>> 8),        \
+              *(((byte *)(PTR))+3) = ( VAL     ) ))
+
+
+/* functions */
+
+void cleanUpWindow();  /* window.c */
+char imageInWindow();
+
+int   visualClassFromName();
+char *nameOfVisualClass();
+
+extern unsigned long DepthToColorsTable[]; /* new.c */
+char  *dupString();
+Image *newBitImage();
+Image *newRGBImage();
+void   freeImage();
+void   freeImageData();
+void   newRGBMapData();
+void   freeRGBMapData();
+byte  *lcalloc();
+byte  *lmalloc();
+void   lfree();
+
+Image *gifLoad();
+Image *monochrome();
+Image *zoom();
+
+void compress(); /* compress.c */
+
+int xliOpenDisplay();
+void tellAboutDisplay(DisplayInfo *);
+void xliCloseDisplay(DisplayInfo *);