sound.c \
joystick.c \
cartoons.c \
- gfxloader.c \
+ gfxload.c \
+ gifload.c \
+ gif.c \
+ send.c \
+ new.c \
random.c
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)
***********************************************************/
#include "events.h"
+#include "init.h"
#include "screens.h"
#include "tools.h"
#include "game.h"
case FocusOut:
HandleFocusEvent((XFocusChangeEvent *) &event);
break;
+ case ClientMessage:
+ HandleClientMessageEvent((XClientMessageEvent *) &event);
+ break;
default:
break;
}
case FocusOut:
HandleFocusEvent((XFocusChangeEvent *) &event);
break;
+ case ClientMessage:
+ HandleClientMessageEvent((XClientMessageEvent *) &event);
+ break;
default:
break;
}
case MapNotify:
window_unmapped = FALSE;
break;
+ case ClientMessage:
+ HandleClientMessageEvent((XClientMessageEvent *) &event);
+ break;
default:
break;
}
}
}
+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;
case XK_KP_Left:
#endif
case XK_KP_4:
+#ifndef MSDOS
case XK_J:
+#endif
case XK_j:
joy |= JOY_LEFT;
break;
case XK_KP_Right:
#endif
case XK_KP_6:
+#ifndef MSDOS
case XK_K:
+#endif
case XK_k:
joy |= JOY_RIGHT;
break;
case XK_KP_Up:
#endif
case XK_KP_8:
+#ifndef MSDOS
case XK_I:
+#endif
case XK_i:
joy |= JOY_UP;
break;
case XK_KP_Down:
#endif
case XK_KP_2:
+#ifndef MSDOS
case XK_M:
+#endif
case XK_m:
joy |= JOY_DOWN;
break;
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;
printf("ScrollStepSize == %d (1/1)\n", ScrollStepSize);
break;
+#ifndef MSDOS
case XK_Q:
+#endif
case XK_q:
Dynamite = 1000;
break;
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
void HandleMotionEvent(XMotionEvent *);
void HandleKeyEvent(XKeyEvent *);
void HandleFocusEvent(XFocusChangeEvent *);
+void HandleClientMessageEvent(XClientMessageEvent *event);
+
void HandleNoXEvent(void);
void HandleButton(int, int, int);
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")))
{
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")))
if (joystick_status==JOYSTICK_OFF)
return;
+#ifndef MSDOS
if (!(file=fopen(JOYDAT_FILE,"r")))
return;
fclose(file);
CheckJoystickData();
+#else
+ load_joystick_data(JOYDAT_FILE);
+#endif
}
void SaveJoystickData()
if (joystick_status==JOYSTICK_OFF)
return;
+#ifndef MSDOS
CheckJoystickData();
if (!(file=fopen(JOYDAT_FILE,"w")))
fclose(file);
chmod(JOYDAT_FILE, JOYDAT_PERMS);
+#else
+ save_joystick_data(JOYDAT_FILE);
+#endif
+
}
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()
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))
{
--- /dev/null
+/***********************************************************
+* 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
--- /dev/null
+/***********************************************************
+* 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
+++ /dev/null
-/***********************************************************
-* 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);
-}
+++ /dev/null
-/***********************************************************
-* 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
--- /dev/null
+
+/* 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);
+}
--- /dev/null
+
+/* 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
--- /dev/null
+/***********************************************************
+* 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
--- /dev/null
+/***********************************************************
+* 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
#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
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);
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]))
{
if (sound_status==SOUND_OFF)
return;
+#ifndef MSDOS
if (pipe(sound_pipe)<0)
{
fprintf(stderr,"%s: cannot create pipe - no sounds\n",progname);
SoundServer();
else /* we are parent */
close(sound_pipe[0]); /* no reading from pipe needed */
+#else
+ SoundServer();
+#endif
}
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",
joystick_status = JOYSTICK_AVAILABLE;
LoadJoystickData();
+#else
+ joystick_status = JOYSTICK_AVAILABLE;
+#endif
}
void InitDisplay(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,
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))
{
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;
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 },
{ "RocksFont", FALSE },
{ "RocksFont2", FALSE }
};
+#endif
#ifdef DEBUG_TIMING
long count1, count2;
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++)
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;
/* 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
#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:
#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",
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();
#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:
filename,(float)(count2-count1)/100.0);
#endif
+#if 0
if (!clipmask[pos])
{
fprintf(stderr, "%s: cannot read graphics file '%s'.\n",
CloseAll();
exit(-1);
}
+#endif
+
}
+
+ pix[pos] = test_pix[test_picture_count-1];
+ clipmask[pos] = test_clipmask[test_picture_count-1];
}
void InitElementProperties()
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",
result |= JOY_BUTTON_2;
return(result);
+#else
+ return(0);
+#endif
}
int JoystickButton()
#include "sound.h"
#include "joystick.h"
+#ifdef MSDOS
+#include <fcntl.h>
+#endif
+
Display *display;
int screen;
Window window;
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
if (argc>1)
level_directory = argv[1];
+#ifdef MSDOS
+ _fmode = O_BINARY;
+#endif
+
OpenAll(argc,argv);
EventLoop();
CloseAll();
#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>
#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)
#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)
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
#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
#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
--- /dev/null
+
+/* 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);
+}
* 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>
#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;
return;
}
+#ifndef MSDOS
if ((key>=XK_A && key<=XK_Z) || (key>=XK_a && key<=XK_z &&
xpos<MAX_NAMELEN-1))
{
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++;
} 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);
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();
}
--- /dev/null
+
+/* 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 ??? */
+}
***********************************************************/
#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 =
{
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] =
#endif /* von '#ifdef VOXWARE' */
}
+#endif
}
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)
{
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--;
}
{
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;
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--;
}
{
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;
}
}
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()
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
{
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",
}
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)
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)
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)
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 ***/
#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
#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)
unsigned char *file_ptr;
char *data_ptr;
long file_len, data_len;
+#ifdef MSDOS
+ SAMPLE *sample_ptr;
+#endif
};
struct SoundControl
long playingpos;
long data_len;
char *data_ptr;
+#ifdef MSDOS
+ int voice;
+#endif
};
/* sound server functions */
#include <math.h>
+#ifdef MSDOS
+extern BOOL wait_for_vsync;
+#endif
+
void SetDrawtoField(int mode)
{
if (mode == DRAW_BUFFERED && soft_scrolling_on)
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,
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,
case FocusOut:
HandleFocusEvent((XFocusChangeEvent *) &event);
break;
+ case ClientMessage:
+ HandleClientMessageEvent((XClientMessageEvent *) &event);
+ break;
default:
break;
}
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);
}
BackToFront();
+#ifndef MSDOS
Delay(door_anim_delay);
+#endif
if (game_status==MAINMENU)
DoAnimation();
--- /dev/null
+
+/* 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 *);