rnd-19981118-2
authorHolger Schemel <info@artsoft.org>
Wed, 18 Nov 1998 19:48:10 +0000 (20:48 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:31:50 +0000 (10:31 +0200)
19 files changed:
Makefile [new file with mode: 0644]
src/Makefile
src/files.c [new file with mode: 0644]
src/gadget.c [deleted file]
src/gadget.h [deleted file]
src/gfxload.c [deleted file]
src/gfxload.h [deleted file]
src/gfxloader.c [deleted file]
src/gfxloader.h [deleted file]
src/gif.c [deleted file]
src/gif.h [deleted file]
src/gifload.c [deleted file]
src/gifload.h [deleted file]
src/msdos.c [deleted file]
src/msdos.h [deleted file]
src/netserv.c [new file with mode: 0644]
src/new.c [deleted file]
src/send.c [deleted file]
src/xli.h [deleted file]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..914925f
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,37 @@
+#=============================================================================#
+# Makefile for Rocks'n'Diamonds 1.2                                           #
+# (c) 1995-98 Holger Schemel, aeglos@valinor.owl.de                           #
+#=============================================================================#
+
+#-----------------------------------------------------------------------------#
+# configuration section                                                       #
+#-----------------------------------------------------------------------------#
+
+#-----------------------------------------------------------------------------#
+# you shouldn't need to change anything below                                 #
+#-----------------------------------------------------------------------------#
+
+PROGNAME = rocksndiamonds
+SRC_DIR = src
+
+MAKE = make
+RM = rm -f
+
+MAKE_CMD = $(MAKE) -C $(SRC_DIR)
+
+
+all:   $(PROGNAME)
+
+$(PROGNAME):
+       $(MAKE_CMD)
+
+clean:
+       $(MAKE_CMD) clean
+       $(RM) $(PROGNAME)
+
+backup:
+       $(MAKE) clean
+       ./scripts/make_backup.sh
+
+depend:
+       $(MAKE_CMD) depend
index a652a6d49142cbef731f737d5eb45e17245b694d..9f2e950556a375056ca1a63ce03500c1a77783d3 100644 (file)
 # configuration section                                                       #
 #-----------------------------------------------------------------------------#
 
+# change this to your favorite ANSI C compiler
+CC = gcc
+
+# on Solaris and similar systems, you'll need to uncomment this
+# EXTRA_LIBS = -lnsl -lsocket 
+
+# specify X11 library path on your system
+XLIB_PATH = /usr/X11/lib
+
+# change this to the directory where you want to install game data like levels
+GAME_DIR = .
+
+# uncomment this if your system has no joystick include file
+# JOYSTICK = -DNO_JOYSTICK
+
+# uncomment this if your system has no sound
+# SOUNDS = -DNO_SOUNDS
+
+# choose if you want to allow many global score file entries for one player
+# when installing the game in a multi user environment, choose this
+# SCORE_ENTRIES = ONE_PER_NAME
+# when installing the game in a single user environment, choose this
+SCORE_ENTRIES = MANY_PER_NAME
+
+# The XPM-Library is no longer needed to build this program,
+# but is used to load graphics if XPM_INCLUDE_FILE is defined,
+# because the GIF loading routines are still a bit beta.
+# If you want to use the Xpm library, convert the GIF files to Xpm
+# files (and you need corresponding mask files in xbm format).
+
+# XPM_INCLUDE_FILE = -DXPM_INCLUDE_FILE="<X11/xpm.h>"
+# EXTRA_X11_LIBS = -lXpm
+
 #-----------------------------------------------------------------------------#
 # you shouldn't need to change anything below                                 #
 #-----------------------------------------------------------------------------#
 
 PROGNAME = rocksndiamonds
-SRC_DIR = src
 
-MAKE = make
 RM = rm -f
+CPP = $(CC) -E
+
+CONFIG_GAME_DIR = -DGAME_DIR="\"$(GAME_DIR)\""
+CONFIG_SCORE_ENTRIES = -D$(SCORE_ENTRIES)
 
-MAKE_CMD = $(MAKE) -C $(SRC_DIR)
+CONFIG = $(CONFIG_GAME_DIR) $(SOUNDS) $(JOYSTICK)      \
+        $(CONFIG_SCORE_ENTRIES) $(XPM_INCLUDE_FILE)
 
+# DEBUG = -DDEBUG -g -ansi -pedantic -Wall
+DEBUG = -DDEBUG -g -Wall
+# DEBUG = -O6
+
+# SYSTEM = -Aa -D_HPUX_SOURCE -Dhpux   # for HP-UX (obsolete)
+# SYSTEM = -DSYSV -Ae                  # for HP-UX
+# INCL = -I/usr/include/X11R5          # for HP-UX and others
+# INCL = -I/usr/local/X11/include      # for SunOS and others
+# LIBS = -L/usr/lib/X11R5 -lXpm -lX11 -lm
+#                                      # for HP-UX and others
+# LIBS = -L/usr/local/X11/lib -lXpm -lX11 -lm -lsocket -R/usr/local/X11/lib
+#                                      # for SunOS and others
+
+# LIBS = -L/usr/X11R6/lib -lXpm -lX11 -lm
+# LIBS = -L/usr/X11R6/lib -lX11 -lm
+
+# LIBS = -L/usr/X11R6/lib $(EXTRA_X11_LIBS) -lX11 -lm $(EXTRA_LIBS)
+LIBS = -L$(XLIB_PATH) $(EXTRA_X11_LIBS) -lX11 -lm $(EXTRA_LIBS)
+
+# CFLAGS = -O2 $(CONFIG) $(SYSTEM)
+CFLAGS = $(DEBUG) $(CONFIG) $(SYSTEM) $(INCL)
+
+SRCS = main.c          \
+       init.c          \
+       events.c        \
+       tools.c         \
+       screens.c       \
+       misc.c          \
+       game.c          \
+       editor.c        \
+       buttons.c       \
+       files.c         \
+       tape.c          \
+       sound.c         \
+       joystick.c      \
+       cartoons.c      \
+       random.c        \
+       pcx.c           \
+       image.c         \
+       network.c       \
+       netserv.c
+
+OBJS = main.o          \
+       init.o          \
+       events.o        \
+       tools.o         \
+       screens.o       \
+       misc.o          \
+       game.o          \
+       editor.o        \
+       buttons.o       \
+       files.o         \
+       tape.o          \
+       sound.o         \
+       joystick.o      \
+       cartoons.o      \
+       random.o        \
+       pcx.o           \
+       image.o         \
+       network.o       \
+       netserv.o
 
 all:   $(PROGNAME)
 
-$(PROGNAME):
-       $(MAKE_CMD)
+$(PROGNAME):   $(OBJS)
+       $(CC) $(CFLAGS) $(OBJS) $(LIBS) -o $(PROGNAME)
+
+.c.o:
+       $(CC) $(CFLAGS) -c $*.c
 
 clean:
-       $(MAKE_CMD) clean
+       $(RM) $(OBJS)
        $(RM) $(PROGNAME)
 
-backup:
-       ./scripts/make_backup.sh
-
 depend:
-       $(MAKE_CMD) depend
+       for i in $(SRCS); do $(CPP) $(CFLAGS) -M $$i; done > .depend
+
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/src/files.c b/src/files.c
new file mode 100644 (file)
index 0000000..46671d4
--- /dev/null
@@ -0,0 +1,1433 @@
+/***********************************************************
+*  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
+*----------------------------------------------------------*
+*  (c) 1995-98 Artsoft Entertainment                       *
+*              Holger Schemel                              *
+*              Oststrasse 11a                              *
+*              33604 Bielefeld                             *
+*              phone: ++49 +521 290471                     *
+*              email: aeglos@valinor.owl.de                *
+*----------------------------------------------------------*
+*  files.h                                                 *
+***********************************************************/
+
+#include <ctype.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "files.h"
+#include "tools.h"
+#include "misc.h"
+#include "tape.h"
+#include "joystick.h"
+
+#define MAX_LINE_LEN                   1000
+
+static void SaveUserLevelInfo();               /* for 'InitUserLevelDir()' */
+static char *getSetupLine(char *, int);                /* for 'SaveUserLevelInfo()' */
+
+static char *getGlobalDataDir()
+{
+  return GAME_DIR;
+}
+
+static char *getUserDataDir()
+{
+  static char *userdata_dir = NULL;
+
+  if (!userdata_dir)
+  {
+    char *home_dir = getHomeDir();
+    char *data_dir = USERDATA_DIRECTORY;
+
+    userdata_dir = checked_malloc(strlen(home_dir) + strlen(data_dir) + 2);
+    sprintf(userdata_dir, "%s/%s", home_dir, data_dir);
+  }
+
+  return userdata_dir;
+}
+
+static char *getSetupDir()
+{
+  return getUserDataDir();
+}
+
+static char *getUserLevelDir(char *level_subdir)
+{
+  static char *userlevel_dir = NULL;
+  char *data_dir = getUserDataDir();
+  char *userlevel_subdir = LEVELS_DIRECTORY;
+
+  if (userlevel_dir)
+    free(userlevel_dir);
+
+  userlevel_dir = checked_malloc(strlen(data_dir) + strlen(userlevel_subdir) +
+                                strlen(level_subdir) + 3);
+  sprintf(userlevel_dir, "%s/%s%s%s", data_dir, userlevel_subdir,
+         (strlen(level_subdir) > 0 ? "/" : ""), level_subdir);
+
+  return userlevel_dir;
+}
+
+static char *getTapeDir(char *level_subdir)
+{
+  static char *tape_dir = NULL;
+  char *data_dir = getUserDataDir();
+  char *tape_subdir = TAPES_DIRECTORY;
+
+  if (tape_dir)
+    free(tape_dir);
+
+  tape_dir = checked_malloc(strlen(data_dir) + strlen(tape_subdir) +
+                           strlen(level_subdir) + 3);
+  sprintf(tape_dir, "%s/%s%s%s", data_dir, tape_subdir,
+         (strlen(level_subdir) > 0 ? "/" : ""), level_subdir);
+
+  return tape_dir;
+}
+
+static char *getScoreDir(char *level_subdir)
+{
+  static char *score_dir = NULL;
+  char *data_dir = getGlobalDataDir();
+  char *score_subdir = SCORES_DIRECTORY;
+
+  if (score_dir)
+    free(score_dir);
+
+  score_dir = checked_malloc(strlen(data_dir) + strlen(score_subdir) +
+                            strlen(level_subdir) + 3);
+  sprintf(score_dir, "%s/%s%s%s", data_dir, score_subdir,
+         (strlen(level_subdir) > 0 ? "/" : ""), level_subdir);
+
+  return score_dir;
+}
+
+static void createDirectory(char *dir, char *text)
+{
+  if (access(dir, F_OK) != 0)
+    if (mkdir(dir, USERDATA_DIR_MODE) != 0)
+      Error(ERR_WARN, "cannot create %s directory '%s'", text, dir);
+}
+
+static void InitUserDataDirectory()
+{
+  createDirectory(getUserDataDir(), "user data");
+}
+
+static void InitTapeDirectory(char *level_subdir)
+{
+  createDirectory(getTapeDir(""), "main tape");
+  createDirectory(getTapeDir(level_subdir), "level tape");
+}
+
+static void InitScoreDirectory(char *level_subdir)
+{
+  createDirectory(getScoreDir(""), "main score");
+  createDirectory(getScoreDir(level_subdir), "level score");
+}
+
+static void InitUserLevelDirectory(char *level_subdir)
+{
+  if (access(getUserLevelDir(level_subdir), F_OK) != 0)
+  {
+    createDirectory(getUserLevelDir(""), "main user level");
+    createDirectory(getUserLevelDir(level_subdir), "user level");
+
+    SaveUserLevelInfo();
+  }
+}
+
+void LoadLevel(int level_nr)
+{
+  int i, x, y;
+  char filename[MAX_FILENAME_LEN];
+  char cookie[MAX_FILENAME_LEN];
+  FILE *file;
+
+  if (leveldir[leveldir_nr].user_defined)
+    sprintf(filename, "%s/%s/%d",
+           getUserLevelDir(""), leveldir[leveldir_nr].filename, level_nr);
+  else
+    sprintf(filename, "%s/%s/%d",
+           options.level_directory, leveldir[leveldir_nr].filename, level_nr);
+
+  if (!(file = fopen(filename, "r")))
+    Error(ERR_WARN, "cannot read level '%s' - creating new level", filename);
+  else
+  {
+    fgets(cookie, LEVEL_COOKIE_LEN, file);
+    fgetc(file);
+
+    if (strcmp(cookie,LEVEL_COOKIE))
+    {
+      Error(ERR_WARN, "wrong format of level file '%s'", filename);
+      fclose(file);
+      file = NULL;
+    }
+  }
+
+  if (file)
+  {
+    lev_fieldx = level.fieldx = fgetc(file);
+    lev_fieldy = level.fieldy = fgetc(file);
+
+    level.time         = (fgetc(file)<<8) | fgetc(file);
+    level.edelsteine   = (fgetc(file)<<8) | fgetc(file);
+    for(i=0; i<MAX_LEVNAMLEN; i++)
+      level.name[i]    = fgetc(file);
+    level.name[MAX_LEVNAMLEN-1] = 0;
+    for(i=0; i<MAX_LEVSCORE_ENTRIES; i++)
+      level.score[i]   = fgetc(file);
+    for(i=0; i<4; i++)
+      for(y=0; y<3; y++)
+       for(x=0; x<3; x++)
+         level.mampfer_inhalt[i][x][y] = fgetc(file);
+    level.tempo_amoebe = fgetc(file);
+    level.dauer_sieb   = fgetc(file);
+    level.dauer_ablenk = fgetc(file);
+    level.amoebe_inhalt = fgetc(file);
+
+    for(i=0; i<NUM_FREE_LVHD_BYTES; i++) /* Rest frei / Headergröße 80 Bytes */
+      fgetc(file);
+
+    for(y=0; y<MAX_LEV_FIELDY; y++) 
+      for(x=0; x<MAX_LEV_FIELDX; x++) 
+       Feld[x][y] = Ur[x][y] = EL_ERDREICH;
+
+    for(y=0; y<lev_fieldy; y++) 
+      for(x=0; x<lev_fieldx; x++) 
+       Feld[x][y] = Ur[x][y] = fgetc(file);
+
+    fclose(file);
+
+    if (level.time <= 10)      /* Mindestspieldauer */
+      level.time = 10;
+  }
+  else
+  {
+    lev_fieldx = level.fieldx = STD_LEV_FIELDX;
+    lev_fieldy = level.fieldy = STD_LEV_FIELDY;
+
+    level.time         = 100;
+    level.edelsteine   = 0;
+    strcpy(level.name, "Nameless Level");
+    for(i=0; i<MAX_LEVSCORE_ENTRIES; i++)
+      level.score[i]   = 10;
+    for(i=0; i<4; i++)
+      for(y=0; y<3; y++)
+       for(x=0; x<3; x++)
+         level.mampfer_inhalt[i][x][y] = EL_FELSBROCKEN;
+    level.tempo_amoebe = 10;
+    level.dauer_sieb   = 10;
+    level.dauer_ablenk = 10;
+    level.amoebe_inhalt = EL_DIAMANT;
+
+    for(y=0; y<STD_LEV_FIELDY; y++) 
+      for(x=0; x<STD_LEV_FIELDX; x++) 
+       Feld[x][y] = Ur[x][y] = EL_ERDREICH;
+    Feld[0][0] = Ur[0][0] = EL_SPIELFIGUR;
+    Feld[STD_LEV_FIELDX-1][STD_LEV_FIELDY-1] =
+      Ur[STD_LEV_FIELDX-1][STD_LEV_FIELDY-1] = EL_AUSGANG_ZU;
+  }
+}
+
+void SaveLevel(int level_nr)
+{
+  int i, x, y;
+  char filename[MAX_FILENAME_LEN];
+  FILE *file;
+
+  if (leveldir[leveldir_nr].user_defined)
+    sprintf(filename, "%s/%s/%d",
+           getUserLevelDir(""), leveldir[leveldir_nr].filename, level_nr);
+  else
+    sprintf(filename, "%s/%s/%d",
+           options.level_directory, leveldir[leveldir_nr].filename, level_nr);
+
+  if (!(file = fopen(filename, "w")))
+  {
+    Error(ERR_WARN, "cannot save level file '%s'", filename);
+    return;
+  }
+
+  fputs(LEVEL_COOKIE,file);            /* Formatkennung */
+  fputc(0x0a, file);
+
+  fputc(level.fieldx, file);
+  fputc(level.fieldy, file);
+  fputc(level.time / 256, file);
+  fputc(level.time % 256, file);
+  fputc(level.edelsteine / 256, file);
+  fputc(level.edelsteine % 256, file);
+
+  for(i=0; i<MAX_LEVNAMLEN; i++)
+    fputc(level.name[i], file);
+  for(i=0; i<MAX_LEVSCORE_ENTRIES; i++)
+    fputc(level.score[i], file);
+  for(i=0; i<4; i++)
+    for(y=0; y<3; y++)
+      for(x=0; x<3; x++)
+       fputc(level.mampfer_inhalt[i][x][y], file);
+  fputc(level.tempo_amoebe, file);
+  fputc(level.dauer_sieb, file);
+  fputc(level.dauer_ablenk, file);
+  fputc(level.amoebe_inhalt, file);
+
+  for(i=0; i<NUM_FREE_LVHD_BYTES; i++) /* Rest frei / Headergröße 80 Bytes */
+    fputc(0, file);
+
+  for(y=0; y<lev_fieldy; y++) 
+    for(x=0; x<lev_fieldx; x++) 
+      fputc(Ur[x][y], file);
+
+  fclose(file);
+
+  chmod(filename, LEVEL_PERMS);
+}
+
+void LoadTape(int level_nr)
+{
+  int i;
+  char filename[MAX_FILENAME_LEN];
+  char cookie[MAX_FILENAME_LEN];
+  FILE *file;
+  boolean levelrec_10 = FALSE;
+
+  sprintf(filename, "%s/%d.%s",
+         getTapeDir(leveldir[leveldir_nr].filename),
+         level_nr, TAPEFILE_EXTENSION);
+
+  if ((file = fopen(filename, "r")))
+  {
+    fgets(cookie, LEVELREC_COOKIE_LEN, file);
+    fgetc(file);
+    if (!strcmp(cookie, LEVELREC_COOKIE_10))   /* old 1.0 tape format */
+      levelrec_10 = TRUE;
+    else if (strcmp(cookie, LEVELREC_COOKIE))  /* unknown tape format */
+    {
+      Error(ERR_WARN, "wrong format of level recording file '%s'", filename);
+      fclose(file);
+      file = NULL;
+    }
+  }
+
+  if (!file)
+    return;
+
+  tape.random_seed =
+    (fgetc(file)<<24) | (fgetc(file)<<16) | (fgetc(file)<<8) | fgetc(file);
+  tape.date =
+    (fgetc(file)<<24) | (fgetc(file)<<16) | (fgetc(file)<<8) | fgetc(file);
+  tape.length =
+    (fgetc(file)<<24) | (fgetc(file)<<16) | (fgetc(file)<<8) | fgetc(file);
+
+  tape.level_nr = level_nr;
+  tape.counter = 0;
+  tape.changed = FALSE;
+
+  tape.recording = FALSE;
+  tape.playing = FALSE;
+  tape.pausing = FALSE;
+
+  for(i=0; i<tape.length; i++)
+  {
+    int j;
+
+    if (i >= MAX_TAPELEN)
+      break;
+
+    for(j=0; j<MAX_PLAYERS; j++)
+    {
+      if (levelrec_10 && j > 0)
+      {
+       tape.pos[i].action[j] = MV_NO_MOVING;
+       continue;
+      }
+      tape.pos[i].action[j] = fgetc(file);
+    }
+
+    tape.pos[i].delay = fgetc(file);
+
+    if (levelrec_10)
+    {
+      /* eliminate possible diagonal moves in old tapes */
+      /* this is only for backward compatibility */
+
+      byte joy_dir[4] = { JOY_LEFT, JOY_RIGHT, JOY_UP, JOY_DOWN };
+      byte action = tape.pos[i].action[0];
+      int k, num_moves = 0;
+
+      for (k=0; k<4; k++)
+      {
+       if (action & joy_dir[k])
+       {
+         tape.pos[i + num_moves].action[0] = joy_dir[k];
+         if (num_moves > 0)
+           tape.pos[i + num_moves].delay = 0;
+         num_moves++;
+       }
+      }
+
+      if (num_moves > 1)
+      {
+       num_moves--;
+       i += num_moves;
+       tape.length += num_moves;
+      }
+    }
+
+    if (feof(file))
+      break;
+  }
+
+  fclose(file);
+
+  if (i != tape.length)
+    Error(ERR_WARN, "level recording file '%s' corrupted", filename);
+
+  tape.length_seconds = GetTapeLength();
+}
+
+void SaveTape(int level_nr)
+{
+  int i;
+  char filename[MAX_FILENAME_LEN];
+  FILE *file;
+  boolean new_tape = TRUE;
+
+  InitTapeDirectory(leveldir[leveldir_nr].filename);
+
+  sprintf(filename, "%s/%d.%s",
+         getTapeDir(leveldir[leveldir_nr].filename),
+         level_nr, TAPEFILE_EXTENSION);
+
+  /* if a tape still exists, ask to overwrite it */
+  if ((file = fopen(filename, "r")))
+  {
+    new_tape = FALSE;
+    fclose(file);
+
+    if (!Request("Replace old tape ?", REQ_ASK))
+      return;
+  }
+
+  if (!(file = fopen(filename, "w")))
+  {
+    Error(ERR_WARN, "cannot save level recording file '%s'", filename);
+    return;
+  }
+
+  fputs(LEVELREC_COOKIE, file);                /* Formatkennung */
+  fputc(0x0a, file);
+
+  fputc((tape.random_seed >> 24) & 0xff,file);
+  fputc((tape.random_seed >> 16) & 0xff,file);
+  fputc((tape.random_seed >>  8) & 0xff,file);
+  fputc((tape.random_seed >>  0) & 0xff,file);
+
+  fputc((tape.date >>  24) & 0xff,file);
+  fputc((tape.date >>  16) & 0xff,file);
+  fputc((tape.date >>   8) & 0xff,file);
+  fputc((tape.date >>   0) & 0xff,file);
+
+  fputc((tape.length >>  24) & 0xff,file);
+  fputc((tape.length >>  16) & 0xff,file);
+  fputc((tape.length >>   8) & 0xff,file);
+  fputc((tape.length >>   0) & 0xff,file);
+
+  for(i=0; i<tape.length; i++)
+  {
+    int j;
+
+    for(j=0; j<MAX_PLAYERS; j++)
+      fputc(tape.pos[i].action[j], file);
+
+    fputc(tape.pos[i].delay, file);
+  }
+
+  fclose(file);
+
+  chmod(filename, LEVREC_PERMS);
+
+  tape.changed = FALSE;
+
+  if (new_tape)
+    Request("tape saved !",REQ_CONFIRM);
+}
+
+void LoadScore(int level_nr)
+{
+  int i;
+  char filename[MAX_FILENAME_LEN];
+  char cookie[MAX_FILENAME_LEN];
+  char line[MAX_LINE_LEN];
+  char *line_ptr;
+  FILE *file;
+
+  /* start with empty score table */
+  for(i=0; i<MAX_SCORE_ENTRIES; i++)
+  {
+    strcpy(highscore[i].Name, EMPTY_ALIAS);
+    highscore[i].Score = 0;
+  }
+
+  sprintf(filename, "%s/%d.%s",
+         getScoreDir(leveldir[leveldir_nr].filename),
+         level_nr, SCOREFILE_EXTENSION);
+
+  if (!(file = fopen(filename, "r")))
+    return;
+
+  fgets(cookie, SCORE_COOKIE_LEN, file);
+
+  if (strcmp(cookie, SCORE_COOKIE) != 0)
+  {
+    Error(ERR_WARN, "wrong format of score file '%s'", filename);
+    fclose(file);
+    return;
+  }
+
+  for(i=0; i<MAX_SCORE_ENTRIES; i++)
+  {
+    fscanf(file, "%d", &highscore[i].Score);
+    fgets(line, MAX_LINE_LEN, file);
+
+    if (line[strlen(line)-1] == '\n')
+      line[strlen(line)-1] = '\0';
+
+    for (line_ptr = line; *line_ptr; line_ptr++)
+    {
+      if (*line_ptr != ' ' && *line_ptr != '\t' && *line_ptr != '\0')
+      {
+       strncpy(highscore[i].Name, line_ptr, MAX_NAMELEN - 1);
+       highscore[i].Name[MAX_NAMELEN - 1] = '\0';
+       break;
+      }
+    }
+  }
+
+  fclose(file);
+}
+
+void SaveScore(int level_nr)
+{
+  int i;
+  char filename[MAX_FILENAME_LEN];
+  FILE *file;
+
+  InitScoreDirectory(leveldir[leveldir_nr].filename);
+
+  sprintf(filename, "%s/%d.%s",
+         getScoreDir(leveldir[leveldir_nr].filename),
+         level_nr, SCOREFILE_EXTENSION);
+
+  if (!(file = fopen(filename, "w")))
+  {
+    Error(ERR_WARN, "cannot save score for level %d", level_nr);
+    return;
+  }
+
+  fprintf(file, "%s\n\n", SCORE_COOKIE);
+
+  for(i=0; i<MAX_SCORE_ENTRIES; i++)
+    fprintf(file, "%d %s\n", highscore[i].Score, highscore[i].Name);
+
+  fclose(file);
+
+  chmod(filename, SCORE_PERMS);
+}
+
+#define TOKEN_STR_FILE_IDENTIFIER      "file_identifier"
+#define TOKEN_STR_LAST_LEVEL_SERIES    "last_level_series"
+#define TOKEN_STR_PLAYER_PREFIX                "player_"
+
+#define TOKEN_VALUE_POSITION           30
+
+/* global setup */
+#define SETUP_TOKEN_PLAYER_NAME                0
+#define SETUP_TOKEN_SOUND              1
+#define SETUP_TOKEN_SOUND_LOOPS                2
+#define SETUP_TOKEN_SOUND_MUSIC                3
+#define SETUP_TOKEN_SOUND_SIMPLE       4
+#define SETUP_TOKEN_TOONS              5
+#define SETUP_TOKEN_DOUBLE_BUFFERING   6
+#define SETUP_TOKEN_SCROLL_DELAY       7
+#define SETUP_TOKEN_SOFT_SCROLLING     8
+#define SETUP_TOKEN_FADING             9
+#define SETUP_TOKEN_AUTORECORD         10
+#define SETUP_TOKEN_QUICK_DOORS                11
+#define SETUP_TOKEN_TEAM_MODE          12
+
+/* player setup */
+#define SETUP_TOKEN_USE_JOYSTICK       13
+#define SETUP_TOKEN_JOY_DEVICE_NAME    14
+#define SETUP_TOKEN_JOY_XLEFT          15
+#define SETUP_TOKEN_JOY_XMIDDLE                16
+#define SETUP_TOKEN_JOY_XRIGHT         17
+#define SETUP_TOKEN_JOY_YUPPER         18
+#define SETUP_TOKEN_JOY_YMIDDLE                19
+#define SETUP_TOKEN_JOY_YLOWER         20
+#define SETUP_TOKEN_JOY_SNAP           21
+#define SETUP_TOKEN_JOY_BOMB           22
+#define SETUP_TOKEN_KEY_LEFT           23
+#define SETUP_TOKEN_KEY_RIGHT          24
+#define SETUP_TOKEN_KEY_UP             25
+#define SETUP_TOKEN_KEY_DOWN           26
+#define SETUP_TOKEN_KEY_SNAP           27
+#define SETUP_TOKEN_KEY_BOMB           28
+
+/* level directory info */
+#define LEVELINFO_TOKEN_NAME           29
+#define LEVELINFO_TOKEN_LEVELS         30
+#define LEVELINFO_TOKEN_SORT_PRIORITY  31
+#define LEVELINFO_TOKEN_READONLY       32
+
+#define FIRST_GLOBAL_SETUP_TOKEN       SETUP_TOKEN_PLAYER_NAME
+#define LAST_GLOBAL_SETUP_TOKEN                SETUP_TOKEN_TEAM_MODE
+
+#define FIRST_PLAYER_SETUP_TOKEN       SETUP_TOKEN_USE_JOYSTICK
+#define LAST_PLAYER_SETUP_TOKEN                SETUP_TOKEN_KEY_BOMB
+
+#define FIRST_LEVELINFO_TOKEN          LEVELINFO_TOKEN_NAME
+#define LAST_LEVELINFO_TOKEN           LEVELINFO_TOKEN_READONLY
+
+#define TYPE_BOOLEAN                   1
+#define TYPE_SWITCH                    2
+#define TYPE_KEYSYM                    3
+#define TYPE_INTEGER                   4
+#define TYPE_STRING                    5
+
+static struct SetupInfo si;
+static struct SetupInputInfo sii;
+static struct LevelDirInfo ldi;
+static struct
+{
+  int type;
+  void *value;
+  char *text;
+} token_info[] =
+{
+  /* global setup */
+  { TYPE_STRING,  &si.player_name,     "player_name"                   },
+  { TYPE_SWITCH,  &si.sound,           "sound"                         },
+  { TYPE_SWITCH,  &si.sound_loops,     "repeating_sound_loops"         },
+  { TYPE_SWITCH,  &si.sound_music,     "background_music"              },
+  { TYPE_SWITCH,  &si.sound_simple,    "simple_sound_effects"          },
+  { TYPE_SWITCH,  &si.toons,           "toons"                         },
+  { TYPE_SWITCH,  &si.double_buffering,        "double_buffering"              },
+  { TYPE_SWITCH,  &si.scroll_delay,    "scroll_delay"                  },
+  { TYPE_SWITCH,  &si.soft_scrolling,  "soft_scrolling"                },
+  { TYPE_SWITCH,  &si.fading,          "screen_fading"                 },
+  { TYPE_SWITCH,  &si.autorecord,      "automatic_tape_recording"      },
+  { TYPE_SWITCH,  &si.quick_doors,     "quick_doors"                   },
+  { TYPE_SWITCH,  &si.team_mode,       "team_mode"                     },
+
+  /* player setup */
+  { TYPE_BOOLEAN, &sii.use_joystick,   ".use_joystick"                 },
+  { TYPE_STRING,  &sii.joy.device_name,        ".joy.device_name"              },
+  { TYPE_INTEGER, &sii.joy.xleft,      ".joy.xleft"                    },
+  { TYPE_INTEGER, &sii.joy.xmiddle,    ".joy.xmiddle"                  },
+  { TYPE_INTEGER, &sii.joy.xright,     ".joy.xright"                   },
+  { TYPE_INTEGER, &sii.joy.yupper,     ".joy.yupper"                   },
+  { TYPE_INTEGER, &sii.joy.ymiddle,    ".joy.ymiddle"                  },
+  { TYPE_INTEGER, &sii.joy.ylower,     ".joy.ylower"                   },
+  { TYPE_INTEGER, &sii.joy.snap,       ".joy.snap_field"               },
+  { TYPE_INTEGER, &sii.joy.bomb,       ".joy.place_bomb"               },
+  { TYPE_KEYSYM,  &sii.key.left,       ".key.move_left"                },
+  { TYPE_KEYSYM,  &sii.key.right,      ".key.move_right"               },
+  { TYPE_KEYSYM,  &sii.key.up,         ".key.move_up"                  },
+  { TYPE_KEYSYM,  &sii.key.down,       ".key.move_down"                },
+  { TYPE_KEYSYM,  &sii.key.snap,       ".key.snap_field"               },
+  { TYPE_KEYSYM,  &sii.key.bomb,       ".key.place_bomb"               },
+
+  /* level directory info */
+  { TYPE_STRING,  &ldi.name,           "name"                          },
+  { TYPE_INTEGER, &ldi.levels,         "levels"                        },
+  { TYPE_INTEGER, &ldi.sort_priority,  "sort_priority"                 },
+  { TYPE_BOOLEAN, &ldi.readonly,       "readonly"                      }
+};
+
+static char *string_tolower(char *s)
+{
+  static char s_lower[100];
+  int i;
+
+  if (strlen(s) >= 100)
+    return s;
+
+  strcpy(s_lower, s);
+
+  for (i=0; i<strlen(s_lower); i++)
+    s_lower[i] = tolower(s_lower[i]);
+
+  return s_lower;
+}
+
+static int get_string_integer_value(char *s)
+{
+  static char *number_text[][3] =
+  {
+    { "0", "zero", "null", },
+    { "1", "one", "first" },
+    { "2", "two", "second" },
+    { "3", "three", "third" },
+    { "4", "four", "fourth" },
+    { "5", "five", "fifth" },
+    { "6", "six", "sixth" },
+    { "7", "seven", "seventh" },
+    { "8", "eight", "eighth" },
+    { "9", "nine", "ninth" },
+    { "10", "ten", "tenth" },
+    { "11", "eleven", "eleventh" },
+    { "12", "twelve", "twelfth" },
+  };
+
+  int i, j;
+
+  for (i=0; i<13; i++)
+    for (j=0; j<3; j++)
+      if (strcmp(string_tolower(s), number_text[i][j]) == 0)
+       return i;
+
+  return atoi(s);
+}
+
+static boolean get_string_boolean_value(char *s)
+{
+  if (strcmp(string_tolower(s), "true") == 0 ||
+      strcmp(string_tolower(s), "yes") == 0 ||
+      strcmp(string_tolower(s), "on") == 0 ||
+      get_string_integer_value(s) == 1)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+static char *getFormattedSetupEntry(char *token, char *value)
+{
+  int i;
+  static char entry[MAX_LINE_LEN];
+
+  sprintf(entry, "%s:", token);
+  for (i=strlen(entry); i<TOKEN_VALUE_POSITION; i++)
+    entry[i] = ' ';
+  entry[i] = '\0';
+
+  strcat(entry, value);
+
+  return entry;
+}
+
+static void freeSetupFileList(struct SetupFileList *setup_file_list)
+{
+  if (!setup_file_list)
+    return;
+
+  if (setup_file_list->token)
+    free(setup_file_list->token);
+  if (setup_file_list->value)
+    free(setup_file_list->value);
+  if (setup_file_list->next)
+    freeSetupFileList(setup_file_list->next);
+  free(setup_file_list);
+}
+
+static struct SetupFileList *newSetupFileList(char *token, char *value)
+{
+  struct SetupFileList *new = checked_malloc(sizeof(struct SetupFileList));
+
+  new->token = checked_malloc(strlen(token) + 1);
+  strcpy(new->token, token);
+
+  new->value = checked_malloc(strlen(value) + 1);
+  strcpy(new->value, value);
+
+  new->next = NULL;
+
+  return new;
+}
+
+static char *getTokenValue(struct SetupFileList *setup_file_list,
+                          char *token)
+{
+  if (!setup_file_list)
+    return NULL;
+
+  if (strcmp(setup_file_list->token, token) == 0)
+    return setup_file_list->value;
+  else
+    return getTokenValue(setup_file_list->next, token);
+}
+
+static void setTokenValue(struct SetupFileList *setup_file_list,
+                         char *token, char *value)
+{
+  if (!setup_file_list)
+    return;
+
+  if (strcmp(setup_file_list->token, token) == 0)
+  {
+    free(setup_file_list->value);
+    setup_file_list->value = checked_malloc(strlen(value) + 1);
+    strcpy(setup_file_list->value, value);
+  }
+  else if (setup_file_list->next == NULL)
+    setup_file_list->next = newSetupFileList(token, value);
+  else
+    setTokenValue(setup_file_list->next, token, value);
+}
+
+#ifdef DEBUG
+static void printSetupFileList(struct SetupFileList *setup_file_list)
+{
+  if (!setup_file_list)
+    return;
+
+  printf("token: '%s'\n", setup_file_list->token);
+  printf("value: '%s'\n", setup_file_list->value);
+
+  printSetupFileList(setup_file_list->next);
+}
+#endif
+
+static struct SetupFileList *loadSetupFileList(char *filename)
+{
+  int line_len;
+  char line[MAX_LINE_LEN];
+  char *token, *value, *line_ptr;
+  struct SetupFileList *setup_file_list = newSetupFileList("", "");
+  struct SetupFileList *first_valid_list_entry;
+
+  FILE *file;
+
+  if (!(file = fopen(filename, "r")))
+  {
+    Error(ERR_WARN, "cannot open setup/info file '%s'", filename);
+    return NULL;
+  }
+
+  while(!feof(file))
+  {
+    /* read next line of input file */
+    if (!fgets(line, MAX_LINE_LEN, file))
+      break;
+
+    /* cut trailing comment or whitespace from input line */
+    for (line_ptr = line; *line_ptr; line_ptr++)
+    {
+      if (*line_ptr == '#' || *line_ptr == '\n')
+      {
+       *line_ptr = '\0';
+       break;
+      }
+    }
+
+    /* cut trailing whitespaces from input line */
+    for (line_ptr = &line[strlen(line)]; line_ptr > line; line_ptr--)
+      if ((*line_ptr == ' ' || *line_ptr == '\t') && line_ptr[1] == '\0')
+       *line_ptr = '\0';
+
+    /* ignore empty lines */
+    if (*line == '\0')
+      continue;
+
+    line_len = strlen(line);
+
+    /* cut leading whitespaces from token */
+    for (token = line; *token; token++)
+      if (*token != ' ' && *token != '\t')
+       break;
+
+    /* find end of token */
+    for (line_ptr = token; *line_ptr; line_ptr++)
+    {
+      if (*line_ptr == ' ' || *line_ptr == '\t' || *line_ptr == ':')
+      {
+       *line_ptr = '\0';
+       break;
+      }
+    }
+
+    if (line_ptr < line + line_len)
+      value = line_ptr + 1;
+    else
+      value = "\0";
+
+    /* cut leading whitespaces from value */
+    for (; *value; value++)
+      if (*value != ' ' && *value != '\t')
+       break;
+
+    if (*token && *value)
+      setTokenValue(setup_file_list, token, value);
+  }
+
+  fclose(file);
+
+  first_valid_list_entry = setup_file_list->next;
+
+  /* free empty list header */
+  setup_file_list->next = NULL;
+  freeSetupFileList(setup_file_list);
+
+  if (first_valid_list_entry == NULL)
+    Error(ERR_WARN, "setup/info file '%s' is empty", filename);
+
+  return first_valid_list_entry;
+}
+
+static void checkSetupFileListIdentifier(struct SetupFileList *setup_file_list,
+                                        char *identifier)
+{
+  if (!setup_file_list)
+    return;
+
+  if (strcmp(setup_file_list->token, TOKEN_STR_FILE_IDENTIFIER) == 0)
+  {
+    if (strcmp(setup_file_list->value, identifier) != 0)
+    {
+      Error(ERR_WARN, "setup/info file has wrong version");
+      return;
+    }
+    else
+      return;
+  }
+
+  if (setup_file_list->next)
+    checkSetupFileListIdentifier(setup_file_list->next, identifier);
+  else
+  {
+    Error(ERR_WARN, "setup/info file has no version information");
+    return;
+  }
+}
+
+static void setLevelDirInfoToDefaults(struct LevelDirInfo *ldi)
+{
+  ldi->name = getStringCopy("non-existing");
+  ldi->levels = 0;
+  ldi->sort_priority = 999;    /* default: least priority */
+  ldi->readonly = TRUE;
+}
+
+static void setSetupInfoToDefaults(struct SetupInfo *si)
+{
+  int i;
+
+  si->player_name = getStringCopy(getLoginName());
+
+  si->sound = TRUE;
+  si->sound_loops = FALSE;
+  si->sound_music = FALSE;
+  si->sound_simple = FALSE;
+  si->toons = TRUE;
+  si->double_buffering = TRUE;
+  si->direct_draw = !si->double_buffering;
+  si->scroll_delay = FALSE;
+  si->soft_scrolling = TRUE;
+  si->fading = FALSE;
+  si->autorecord = FALSE;
+  si->quick_doors = FALSE;
+
+  for (i=0; i<MAX_PLAYERS; i++)
+  {
+    si->input[i].use_joystick = FALSE;
+    si->input[i].joy.device_name = getStringCopy(joystick_device_name[i]);
+    si->input[i].joy.xleft   = JOYSTICK_XLEFT;
+    si->input[i].joy.xmiddle = JOYSTICK_XMIDDLE;
+    si->input[i].joy.xright  = JOYSTICK_XRIGHT;
+    si->input[i].joy.yupper  = JOYSTICK_YUPPER;
+    si->input[i].joy.ymiddle = JOYSTICK_YMIDDLE;
+    si->input[i].joy.ylower  = JOYSTICK_YLOWER;
+    si->input[i].joy.snap  = (i == 0 ? JOY_BUTTON_1 : 0);
+    si->input[i].joy.bomb  = (i == 0 ? JOY_BUTTON_2 : 0);
+    si->input[i].key.left  = (i == 0 ? DEFAULT_KEY_LEFT  : KEY_UNDEFINDED);
+    si->input[i].key.right = (i == 0 ? DEFAULT_KEY_RIGHT : KEY_UNDEFINDED);
+    si->input[i].key.up    = (i == 0 ? DEFAULT_KEY_UP    : KEY_UNDEFINDED);
+    si->input[i].key.down  = (i == 0 ? DEFAULT_KEY_DOWN  : KEY_UNDEFINDED);
+    si->input[i].key.snap  = (i == 0 ? DEFAULT_KEY_SNAP  : KEY_UNDEFINDED);
+    si->input[i].key.bomb  = (i == 0 ? DEFAULT_KEY_BOMB  : KEY_UNDEFINDED);
+  }
+}
+
+static void setSetupInfo(int token_nr, char *token_value)
+{
+  int token_type = token_info[token_nr].type;
+  void *setup_value = token_info[token_nr].value;
+
+  if (token_value == NULL)
+    return;
+
+  /* set setup field to corresponding token value */
+  switch (token_type)
+  {
+    case TYPE_BOOLEAN:
+    case TYPE_SWITCH:
+      *(boolean *)setup_value = get_string_boolean_value(token_value);
+      break;
+
+    case TYPE_KEYSYM:
+      *(KeySym *)setup_value = getKeySymFromX11KeyName(token_value);
+      break;
+
+    case TYPE_INTEGER:
+      *(int *)setup_value = get_string_integer_value(token_value);
+      break;
+
+    case TYPE_STRING:
+      if (*(char **)setup_value != NULL)
+       free(*(char **)setup_value);
+      *(char **)setup_value = getStringCopy(token_value);
+      break;
+
+    default:
+      break;
+  }
+}
+
+static void decodeSetupFileList(struct SetupFileList *setup_file_list)
+{
+  int i, pnr;
+
+  if (!setup_file_list)
+    return;
+
+  /* handle global setup values */
+  si = setup;
+  for (i=FIRST_GLOBAL_SETUP_TOKEN; i<=LAST_GLOBAL_SETUP_TOKEN; i++)
+    setSetupInfo(i, getTokenValue(setup_file_list, token_info[i].text));
+  setup = si;
+
+  /* handle player specific setup values */
+  for (pnr=0; pnr<MAX_PLAYERS; pnr++)
+  {
+    char prefix[30];
+
+    sprintf(prefix, "%s%d", TOKEN_STR_PLAYER_PREFIX, pnr + 1);
+
+    sii = setup.input[pnr];
+    for (i=FIRST_PLAYER_SETUP_TOKEN; i<=LAST_PLAYER_SETUP_TOKEN; i++)
+    {
+      char full_token[100];
+
+      sprintf(full_token, "%s%s", prefix, token_info[i].text);
+      setSetupInfo(i, getTokenValue(setup_file_list, full_token));
+    }
+    setup.input[pnr] = sii;
+  }
+}
+
+int getLevelSeriesNrFromLevelSeriesName(char *level_series_name)
+{
+  int i;
+
+  if (!level_series_name)
+    return 0;
+
+  for (i=0; i<num_leveldirs; i++)
+    if (strcmp(level_series_name, leveldir[i].filename) == 0)
+      return i;
+
+  return 0;
+}
+
+int getLastPlayedLevelOfLevelSeries(char *level_series_name)
+{
+  char *token_value;
+  int level_series_nr = getLevelSeriesNrFromLevelSeriesName(level_series_name);
+  int last_level_nr = 0;
+
+  if (!level_series_name)
+    return 0;
+
+  token_value = getTokenValue(level_setup_list, level_series_name);
+
+  if (token_value)
+  {
+    int highest_level_nr = leveldir[level_series_nr].levels - 1;
+
+    last_level_nr = atoi(token_value);
+
+    if (last_level_nr < 0)
+      last_level_nr = 0;
+    if (last_level_nr > highest_level_nr)
+      last_level_nr = highest_level_nr;
+  }
+
+  return last_level_nr;
+}
+
+static int compareLevelDirInfoEntries(const void *object1, const void *object2)
+{
+  const struct LevelDirInfo *entry1 = object1;
+  const struct LevelDirInfo *entry2 = object2;
+  int compare_result;
+
+  if (entry1->sort_priority != entry2->sort_priority)
+    compare_result = entry1->sort_priority - entry2->sort_priority;
+  else
+  {
+    char *name1 = getStringToLower(entry1->name);
+    char *name2 = getStringToLower(entry2->name);
+
+    compare_result = strcmp(name1, name2);
+
+    free(name1);
+    free(name2);
+  }
+
+  return compare_result;
+}
+
+static int LoadLevelInfoFromLevelDir(char *level_directory, int start_entry)
+{
+  DIR *dir;
+  struct stat file_status;
+  char *directory = NULL;
+  char *filename = NULL;
+  struct SetupFileList *setup_file_list = NULL;
+  struct dirent *dir_entry;
+  int i, current_entry = start_entry;
+
+  if ((dir = opendir(level_directory)) == NULL)
+    Error(ERR_EXIT, "cannot read level directory '%s'", level_directory);
+
+  while (current_entry < MAX_LEVDIR_ENTRIES)
+  {
+    if ((dir_entry = readdir(dir)) == NULL)    /* last directory entry */
+      break;
+
+    /* skip entries for current and parent directory */
+    if (strcmp(dir_entry->d_name, ".")  == 0 ||
+       strcmp(dir_entry->d_name, "..") == 0)
+      continue;
+
+    /* find out if directory entry is itself a directory */
+    directory = getPath2(level_directory, dir_entry->d_name);
+    if (stat(directory, &file_status) != 0 ||          /* cannot stat file */
+       (file_status.st_mode & S_IFMT) != S_IFDIR)      /* not a directory */
+    {
+      free(directory);
+      continue;
+    }
+
+    if (strlen(dir_entry->d_name) >= MAX_LEVDIR_FILENAME)
+    {
+      Error(ERR_WARN, "filename of level directory '%s' too long -- ignoring",
+           dir_entry->d_name);
+      continue;
+    }
+
+    filename = getPath2(directory, LEVELINFO_FILENAME);
+    setup_file_list = loadSetupFileList(filename);
+
+    if (setup_file_list)
+    {
+      checkSetupFileListIdentifier(setup_file_list, LEVELINFO_COOKIE);
+      setLevelDirInfoToDefaults(&leveldir[current_entry]);
+
+      ldi = leveldir[current_entry];
+      for (i=FIRST_LEVELINFO_TOKEN; i<=LAST_LEVELINFO_TOKEN; i++)
+       setSetupInfo(i, getTokenValue(setup_file_list, token_info[i].text));
+      leveldir[current_entry] = ldi;
+
+      leveldir[current_entry].filename = getStringCopy(dir_entry->d_name);
+      leveldir[current_entry].user_defined =
+       (level_directory == options.level_directory ? FALSE : TRUE);
+
+      freeSetupFileList(setup_file_list);
+      current_entry++;
+    }
+    else
+      Error(ERR_WARN, "ignoring level directory '%s'", directory);
+
+    free(directory);
+    free(filename);
+  }
+
+  if (current_entry == MAX_LEVDIR_ENTRIES)
+    Error(ERR_WARN, "using %d level directories -- ignoring the rest",
+         current_entry);
+
+  closedir(dir);
+
+  if (current_entry == start_entry && start_entry != -1)
+    Error(ERR_EXIT, "cannot find any valid level series in directory '%s'",
+         level_directory);
+
+  return current_entry;
+}
+
+void LoadLevelInfo()
+{
+  InitUserLevelDirectory(getLoginName());
+
+  num_leveldirs = 0;
+  leveldir_nr = 0;
+
+  num_leveldirs = LoadLevelInfoFromLevelDir(options.level_directory,
+                                           num_leveldirs);
+  num_leveldirs = LoadLevelInfoFromLevelDir(getUserLevelDir(""),
+                                           num_leveldirs);
+  if (num_leveldirs > 1)
+    qsort(leveldir, num_leveldirs, sizeof(struct LevelDirInfo),
+         compareLevelDirInfoEntries);
+}
+
+static void SaveUserLevelInfo()
+{
+  char filename[MAX_FILENAME_LEN];
+  FILE *file;
+  int i;
+
+  sprintf(filename, "%s/%s",
+         getUserLevelDir(getLoginName()), LEVELINFO_FILENAME);
+
+  if (!(file = fopen(filename, "w")))
+  {
+    Error(ERR_WARN, "cannot write level info file '%s'", filename);
+    return;
+  }
+
+  ldi.name = getLoginName();
+  ldi.levels = 100;
+  ldi.sort_priority = 300;
+  ldi.readonly = FALSE;
+
+  fprintf(file, "%s\n\n",
+         getFormattedSetupEntry(TOKEN_STR_FILE_IDENTIFIER, LEVELINFO_COOKIE));
+
+  for (i=FIRST_LEVELINFO_TOKEN; i<=LAST_LEVELINFO_TOKEN; i++)
+    fprintf(file, "%s\n", getSetupLine("", i));
+
+  fclose(file);
+
+  chmod(filename, SETUP_PERMS);
+}
+
+void LoadSetup()
+{
+  char filename[MAX_FILENAME_LEN];
+  struct SetupFileList *setup_file_list = NULL;
+
+  /* always start with reliable default setup values */
+  setSetupInfoToDefaults(&setup);
+
+  sprintf(filename, "%s/%s", getSetupDir(), SETUP_FILENAME);
+
+  setup_file_list = loadSetupFileList(filename);
+
+  if (setup_file_list)
+  {
+    checkSetupFileListIdentifier(setup_file_list, SETUP_COOKIE);
+    decodeSetupFileList(setup_file_list);
+
+    setup.direct_draw = !setup.double_buffering;
+
+    freeSetupFileList(setup_file_list);
+
+    /* needed to work around problems with fixed length strings */
+    if (strlen(setup.player_name) >= MAX_NAMELEN)
+      setup.player_name[MAX_NAMELEN - 1] = '\0';
+    else if (strlen(setup.player_name) < MAX_NAMELEN - 1)
+    {
+      char *new_name = checked_malloc(MAX_NAMELEN);
+
+      strcpy(new_name, setup.player_name);
+      free(setup.player_name);
+      setup.player_name = new_name;
+    }
+  }
+  else
+    Error(ERR_WARN, "using default setup values");
+}
+
+static char *getSetupLine(char *prefix, int token_nr)
+{
+  int i;
+  static char entry[MAX_LINE_LEN];
+  int token_type = token_info[token_nr].type;
+  void *setup_value = token_info[token_nr].value;
+  char *token_text = token_info[token_nr].text;
+
+  /* start with the prefix, token and some spaces to format output line */
+  sprintf(entry, "%s%s:", prefix, token_text);
+  for (i=strlen(entry); i<TOKEN_VALUE_POSITION; i++)
+    strcat(entry, " ");
+
+  /* continue with the token's value (which can have different types) */
+  switch (token_type)
+  {
+    case TYPE_BOOLEAN:
+      strcat(entry, (*(boolean *)setup_value ? "true" : "false"));
+      break;
+
+    case TYPE_SWITCH:
+      strcat(entry, (*(boolean *)setup_value ? "on" : "off"));
+      break;
+
+    case TYPE_KEYSYM:
+      {
+       KeySym keysym = *(KeySym *)setup_value;
+       char *keyname = getKeyNameFromKeySym(keysym);
+
+       strcat(entry, getX11KeyNameFromKeySym(keysym));
+       for (i=strlen(entry); i<50; i++)
+         strcat(entry, " ");
+
+       /* add comment, if useful */
+       if (strcmp(keyname, "(undefined)") != 0 &&
+           strcmp(keyname, "(unknown)") != 0)
+       {
+         strcat(entry, "# ");
+         strcat(entry, keyname);
+       }
+      }
+      break;
+
+    case TYPE_INTEGER:
+      {
+       char buffer[MAX_LINE_LEN];
+
+       sprintf(buffer, "%d", *(int *)setup_value);
+       strcat(entry, buffer);
+      }
+      break;
+
+    case TYPE_STRING:
+      strcat(entry, *(char **)setup_value);
+      break;
+
+    default:
+      break;
+  }
+
+  return entry;
+}
+
+void SaveSetup()
+{
+  int i, pnr;
+  char filename[MAX_FILENAME_LEN];
+  FILE *file;
+
+  InitUserDataDirectory();
+
+  sprintf(filename, "%s/%s", getSetupDir(), SETUP_FILENAME);
+
+  if (!(file = fopen(filename, "w")))
+  {
+    Error(ERR_WARN, "cannot write setup file '%s'", filename);
+    return;
+  }
+
+  fprintf(file, "%s\n",
+         getFormattedSetupEntry(TOKEN_STR_FILE_IDENTIFIER, SETUP_COOKIE));
+  fprintf(file, "\n");
+
+  /* handle global setup values */
+  si = setup;
+  for (i=FIRST_GLOBAL_SETUP_TOKEN; i<=LAST_GLOBAL_SETUP_TOKEN; i++)
+  {
+    fprintf(file, "%s\n", getSetupLine("", i));
+
+    /* just to make things nicer :) */
+    if (i == SETUP_TOKEN_PLAYER_NAME)
+      fprintf(file, "\n");
+  }
+
+  /* handle player specific setup values */
+  for (pnr=0; pnr<MAX_PLAYERS; pnr++)
+  {
+    char prefix[30];
+
+    sprintf(prefix, "%s%d", TOKEN_STR_PLAYER_PREFIX, pnr + 1);
+    fprintf(file, "\n");
+
+    sii = setup.input[pnr];
+    for (i=FIRST_PLAYER_SETUP_TOKEN; i<=LAST_PLAYER_SETUP_TOKEN; i++)
+      fprintf(file, "%s\n", getSetupLine(prefix, i));
+  }
+
+  fclose(file);
+
+  chmod(filename, SETUP_PERMS);
+}
+
+void LoadLevelSetup()
+{
+  char filename[MAX_FILENAME_LEN];
+
+  /* always start with reliable default setup values */
+
+  leveldir_nr = 0;
+  level_nr = 0;
+
+  sprintf(filename, "%s/%s", getSetupDir(), LEVELSETUP_FILENAME);
+
+  if (level_setup_list)
+    freeSetupFileList(level_setup_list);
+
+  level_setup_list = loadSetupFileList(filename);
+
+  if (level_setup_list)
+  {
+    char *last_level_series =
+      getTokenValue(level_setup_list, TOKEN_STR_LAST_LEVEL_SERIES);
+
+    leveldir_nr = getLevelSeriesNrFromLevelSeriesName(last_level_series);
+    level_nr = getLastPlayedLevelOfLevelSeries(last_level_series);
+
+    checkSetupFileListIdentifier(level_setup_list, LEVELSETUP_COOKIE);
+  }
+  else
+  {
+    level_setup_list = newSetupFileList(TOKEN_STR_FILE_IDENTIFIER,
+                                       LEVELSETUP_COOKIE);
+    Error(ERR_WARN, "using default setup values");
+  }
+}
+
+void SaveLevelSetup()
+{
+  char filename[MAX_FILENAME_LEN];
+  struct SetupFileList *list_entry = level_setup_list;
+  FILE *file;
+
+  InitUserDataDirectory();
+
+  setTokenValue(level_setup_list,
+               TOKEN_STR_LAST_LEVEL_SERIES, leveldir[leveldir_nr].filename);
+
+  setTokenValue(level_setup_list,
+               leveldir[leveldir_nr].filename, int2str(level_nr, 0));
+
+  sprintf(filename, "%s/%s", getSetupDir(), LEVELSETUP_FILENAME);
+
+  if (!(file = fopen(filename, "w")))
+  {
+    Error(ERR_WARN, "cannot write setup file '%s'", filename);
+    return;
+  }
+
+  fprintf(file, "%s\n\n", getFormattedSetupEntry(TOKEN_STR_FILE_IDENTIFIER,
+                                                LEVELSETUP_COOKIE));
+  while (list_entry)
+  {
+    if (strcmp(list_entry->token, TOKEN_STR_FILE_IDENTIFIER) != 0)
+      fprintf(file, "%s\n",
+             getFormattedSetupEntry(list_entry->token, list_entry->value));
+
+    /* just to make things nicer :) */
+    if (strcmp(list_entry->token, TOKEN_STR_LAST_LEVEL_SERIES) == 0)
+      fprintf(file, "\n");
+
+    list_entry = list_entry->next;
+  }
+
+  fclose(file);
+
+  chmod(filename, SETUP_PERMS);
+}
diff --git a/src/gadget.c b/src/gadget.c
deleted file mode 100644 (file)
index dee0566..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-/* gadget.c */
-
-#include "gadget.h"
-
-struct Gadget *gadget_list;
-
-void NextGadgetEvent()
diff --git a/src/gadget.h b/src/gadget.h
deleted file mode 100644 (file)
index 5ee9c98..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/* gadget.h */
-
-/* gadget types */
-#define GD_TYPE_NORMAL_BUTTON          (1<<0)
-#define GD_TYPE_TWO_STATE_BUTTON       (1<<1)
-#define GD_TYPE_DRAWING_AREA           (1<<2)
-#define GD_TYPE_TEXTINPUT              (1<<3)
-#define GD_TYPE_TEXTOUTPUT             (1<<4)
-#define GD_TYPE_NUMBERINPUT            (1<<5)
-#define GD_TYPE_NUMBEROUTPUT           (1<<6)
-
-/* gadget events */
-#define GD_EVENT_PRESSED               (1<<0)
-#define GD_EVENT_RELEASED              (1<<1)
-#define GD_EVENT_MOVING                        (1<<2)
-
-/* gadget structure constants */
-#define MAX_GADGET_TEXTSIZE            1024
-
-struct GadgetDesign
-{
-  Pixmap pixmap;                       /* Pixmap with gadget surface */
-  int x,y;                             /* position of rectangle in Pixmap */
-};
-
-struct Gadget
-{
-  int x,y;                             /* screen position */
-  int width,height;                    /* screen size */
-  unsigned long type;                  /* type (button, text input, ...) */
-  unsigned long state;                 /* state (pressed, released, ...) */
-  long number_value;
-  char text_value[MAX_GADGET_TEXTSIZE];
-  struct GadgetDesign *design[2];      /* 0: normal; 1: pressed */
-  struct GadgetDesign *alt_design[2];  /* alternative design */
-  unsigned long event;                 /* actual gadget event */
-  struct Gadget *next;                 /* next list entry */
-};
-
-struct NewGadget
-{
-  int x,y;                             /* screen position */
-  int width,height;                    /* screen size */
-  unsigned long type;                  /* type (button, text input, ...) */
-  struct GadgetDesign *design[2];      /* 0: normal; 1: pressed */
-  struct GadgetDesign *alt_design[2];  /* alternative design */
-  unsigned long value_mask;            /* actual gadget event */
-};
-
-struct GadgetEvent
-{
-  unsigned long state;                 /* state (pressed, released, ...) */
-  int x,y;                             /* position inside drawing area */
-};
diff --git a/src/gfxload.c b/src/gfxload.c
deleted file mode 100644 (file)
index bcc7f22..0000000
+++ /dev/null
@@ -1,1120 +0,0 @@
-/***********************************************************
-*  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
-*----------------------------------------------------------*
-*  (c) 1995-98 Artsoft Entertainment                       *
-*              Holger Schemel                              *
-*              Oststrasse 11a                              *
-*              33604 Bielefeld                             *
-*              phone: ++49 +521 290471                     *
-*              email: aeglos@valinor.owl.de                *
-*----------------------------------------------------------*
-*  gfxload.c                                               *
-***********************************************************/
-
-#ifndef MSDOS
-#include "gfxload.h"
-
-
-
-
-
-
-extern Window                  window;
-extern void Delay(long);
-
-
-
-
-
-
-#ifdef DEBUG
-/*
-#define DEBUG_GIF
-#define DEBUG_ILBM
-*/
-#endif
-
-struct IFF_ILBM_FORM_big_endian
-{
-  char magic_FORM[4];
-  unsigned char chunk_size[4];
-  char magic_ILBM[4];
-};
-
-struct IFF_ILBM_BMHD_big_endian
-{
-  char Width[2], Height[2];
-  char LeftEdge[2], TopEdge[2];
-  char Depth;
-  char Mask;
-  char Compression;
-  char pad1;
-  char transparentColor[2];
-  char xAspect, yAspect;
-  char pageWidth[2], pageHeight[2];
-};
-
-struct IFF_ILBM_BMHD
-{
-  unsigned int Width, Height;
-  int LeftEdge, TopEdge;
-  unsigned int Depth;
-  unsigned int Mask;
-  unsigned int Compression;
-  unsigned char pad1;
-  unsigned int transparentColor;
-  unsigned int xAspect, yAspect;
-  int pageWidth, pageHeight;
-};
-
-static int ConvertXImageDepth(Display *, XImage **);
-static int Read_GIF_to_Pixmap_or_Bitmap(Display *, char *, Pixmap *, int);
-
-#define READ_GIF_TO_BITMAP     0
-#define READ_GIF_TO_PIXMAP     1
-
-int Read_GIF_to_Bitmap(Display *display, char *filename, Pixmap *pixmap)
-{
-  return(Read_GIF_to_Pixmap_or_Bitmap(display, filename,
-                                     pixmap, READ_GIF_TO_BITMAP));
-}
-
-int Read_GIF_to_Pixmap(Display *display, char *filename, Pixmap *pixmap)
-{
-  return(Read_GIF_to_Pixmap_or_Bitmap(display, filename,
-                                     pixmap, READ_GIF_TO_PIXMAP));
-}
-
-int Read_GIF_to_Pixmap_or_Bitmap(Display *display, char *filename,
-                                Pixmap *pixmap, int mode)
-{
-  XImage *image = NULL;
-  Pixmap new_pixmap = 0;
-  int return_code;
-
-  *pixmap = 0;
-  return_code = Read_GIF_to_XImage(display, filename, &image);
-  if (return_code != GIF_Success)
-    return(return_code);
-
-  if (image)
-  {
-    int screen = DefaultScreen(display);
-    Drawable root = RootWindow(display,screen);
-    int depth = DefaultDepth(display, screen);
-    int width = image->width;
-    int height = image->height;
-
-    if (mode == READ_GIF_TO_BITMAP)
-    {
-      int i,x,y;
-      unsigned long black_pixel = BlackPixel(display,screen);
-      int bytes_per_line = (width+7) / 8;
-      int size = bytes_per_line * height;
-      char *data, *ptr;
-
-      data = (char *)malloc(size);
-      if (!data)
-       return(GIF_NoMemory);
-
-      ptr = data;
-      for(i=0;i<size;i++)
-       *ptr++ = 0;
-
-      for(y=0;y<height;y++)
-      {
-       for(x=0;x<width;x++)
-       {
-         if (XGetPixel(image,x,y) == black_pixel)
-           data[y * bytes_per_line + x/8] |= (1 << (x%8));
-       }
-      }
-
-      new_pixmap = XCreateBitmapFromData(display,root,data,width,height);
-      free(data);
-
-      if (!new_pixmap)
-       return(GIF_NoMemory);
-    }
-    else
-    {
-      GC gc;
-      XGCValues gcv;
-
-      if (ConvertXImageDepth(display, &image) != GIF_Success)
-       return(GIF_ColorFailed);
-
-      new_pixmap = XCreatePixmap(display,root,width,height,depth);
-
-      if (!new_pixmap)
-       return(GIF_NoMemory);
-
-      gcv.foreground = BlackPixel(display,screen);
-      gcv.background = WhitePixel(display,screen);
-      gc = XCreateGC(display, root, GCForeground | GCBackground, &gcv);
-      XPutImage(display,new_pixmap,gc,image,0,0,0,0,width,height);
-
-      XFreeGC(display, gc);
-    }
-
-    XDestroyImage(image);
-  }
-
-  *pixmap = new_pixmap;
-  return(return_code);
-}
-
-
-/*
- * Read_GIF_to_XImage()  -  based strongly on...
- *
- * xgifload.c  -  based strongly on...
- *
- * gif2ras.c - Converts from a Compuserve GIF (tm) image to a Sun Raster image.
- *
- * Copyright (c) 1988, 1989 by Patrick J. Naughton
- *
- * Author: Patrick J. Naughton
- * naughton@wind.sun.com
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice appear in
- * supporting documentation.
- *
- * This file is provided AS IS with no warranties of any kind.  The author
- * shall have no liability with respect to the infringement of copyrights,
- * trade secrets or any patents by this file or any part thereof.  In no
- * event will the author be liable for any lost revenue or profits or
- * other special, indirect and consequential damages.
- *
- */
-
-typedef int boolean;
-typedef unsigned char byte;
-
-static int ReadCode(void);
-static void AddToPixel(byte);
-static int ColorDicking(Display *);
-
-#define NEXTBYTE       (*ptr++)
-#define IMAGESEP       0x2c
-#define INTERLACEMASK  0x40
-#define COLORMAPMASK   0x80
-
-static
-int BitOffset,                 /* Bit Offset of next code */
-    XC, YC,                    /* Output X and Y coords of current pixel */
-    Pass,                      /* Used by output routine if interlaced pic */
-    OutCount,                  /* Decompressor output 'stack count' */
-    RWidth, RHeight,           /* screen dimensions */
-    Width, Height,             /* image dimensions */
-    LeftOfs, TopOfs,           /* image offset */
-    BitsPerPixel,              /* Bits per pixel, read from GIF header */
-    BytesPerScanline,          /* bytes per scanline in output raster */
-    ColorMapSize,              /* number of colors */
-    Background,                        /* background color */
-    CodeSize,                  /* Code size, read from GIF header */
-    InitCodeSize,              /* Starting code size, used during Clear */
-    Code,                      /* Value returned by ReadCode */
-    MaxCode,                   /* limiting value for current code size */
-    ClearCode,                 /* GIF clear code */
-    EOFCode,                   /* GIF end-of-information code */
-    CurCode, OldCode, InCode,  /* Decompressor variables */
-    FirstFree,                 /* First free code, generated per GIF spec */
-    FreeCode,                  /* Decompressor, next free slot in hash table*/
-    FinChar,                   /* Decompressor variable */
-    BitMask,                   /* AND mask for data size */
-    ReadMask;                  /* Code AND mask for current code size */
-
-static boolean Interlace, HasColormap;
-
-static byte *ImageData;                /* The result array */
-static byte *RawGIF;           /* The heap array to hold it, raw */
-static byte *Raster;           /* The raster data stream, unblocked */
-
-/* The color map, read from the GIF header */
-static byte Red[256], Green[256], Blue[256], used[256];
-static int  numused;
-
-extern char *progname;
-
-static int numcols;
-static unsigned long cols[256];
-static XColor defs[256];
-
-int Read_GIF_to_XImage(Display *display, char *filename, XImage **image)
-{
-  int filesize;
-  register byte ch, ch1;
-  register byte *ptr, *ptr1;
-  register int i;
-  int screen = DefaultScreen(display);
-  Visual *visual = DefaultVisual(display,screen);
-  XImage *new_image = NULL;
-  char *id = "GIF87a";
-  FILE *file;
-  int Prefix[4096];    /* The hash table used by the decompressor */
-  int Suffix[4096];
-  int OutCode[1025];   /* An output array used by the decompressor */
-
-  BitOffset = XC = YC = Pass = OutCount = 0;
-  *image = NULL;
-
-  if (strcmp(filename,"-")==0)
-  {
-    file = stdin;
-    filename = "<stdin>";
-  }
-  else
-    file = fopen(filename,"r");
-
-  if (!file)
-    return(GIF_OpenFailed);
-
-  /* find the size of the file */
-  fseek(file, 0L, 2);
-  filesize = ftell(file);
-  fseek(file, 0L, 0);
-
-  if (!(ptr = RawGIF = (byte *) malloc(filesize)))
-    return(GIF_NoMemory);
-
-  if (!(Raster = (byte *) malloc(filesize)))
-    return(GIF_NoMemory);
-
-  if (fread(ptr, filesize, 1, file) != 1)
-    return(GIF_ReadFailed);
-
-  if (strncmp(ptr, id, 6))
-    return(GIF_FileInvalid);
-
-  ptr += 6;
-
-  /* Get variables from the GIF screen descriptor */
-
-  ch = NEXTBYTE;
-  RWidth = ch + 0x100 * NEXTBYTE;    /* screen dimensions... not used. */
-  ch = NEXTBYTE;
-  RHeight = ch + 0x100 * NEXTBYTE;
-
-  ch = NEXTBYTE;
-  HasColormap = ((ch & COLORMAPMASK) ? True : False);
-
-  BitsPerPixel = (ch & 7) + 1;
-  numcols = ColorMapSize = 1 << BitsPerPixel;
-  BitMask = ColorMapSize - 1;
-
-  Background = NEXTBYTE;             /* background color... not used. */
-
-  if (NEXTBYTE)              /* supposed to be NULL */
-    return(GIF_FileInvalid);
-
-  /* Read in global colormap. */
-
-  if (HasColormap)
-  {
-    for (i = 0; i < ColorMapSize; i++)
-    {
-      Red[i] = NEXTBYTE;
-      Green[i] = NEXTBYTE;
-      Blue[i] = NEXTBYTE;
-      used[i] = 0;
-    }
-    numused = 0;
-  }
-  else
-  {
-    /* no colormap in GIF file */
-    fprintf(stderr,"%s:  warning!  no colortable in this file.  Winging it.\n",
-           progname);
-    if (!numcols)
-      numcols=256;
-    for (i=0; i<numcols; i++)
-      cols[i] = (unsigned long) i;
-  }
-
-  /* Check for image seperator */
-
-  if (NEXTBYTE != IMAGESEP)
-    return(GIF_FileInvalid);
-
-  /* Now read in values from the image descriptor */
-
-  ch = NEXTBYTE;
-  LeftOfs = ch + 0x100 * NEXTBYTE;
-  ch = NEXTBYTE;
-  TopOfs = ch + 0x100 * NEXTBYTE;
-  ch = NEXTBYTE;
-  Width = ch + 0x100 * NEXTBYTE;
-  ch = NEXTBYTE;
-  Height = ch + 0x100 * NEXTBYTE;
-  Interlace = ((NEXTBYTE & INTERLACEMASK) ? True : False);
-
-#ifdef DEBUG_GIF
-  fprintf(stderr, "%s:\n", filename);
-  fprintf(stderr, "   %dx%d, %d bpp / %d colors, %sinterlaced\n",
-         Width,Height, BitsPerPixel,ColorMapSize,(Interlace ? "" : "non-"));
-  fprintf(stderr, "   Reading file... ");
-#endif
-
-  /* Note that I ignore the possible existence of a local color map.
-   * I'm told there aren't many files around that use them, and the spec
-   * says it's defined for future use.  This could lead to an error
-   * reading some files. 
-   */
-
-  /* Start reading the raster data. First we get the intial code size
-   * and compute decompressor constant values, based on this code size.
-   */
-
-  CodeSize = NEXTBYTE;
-  ClearCode = (1 << CodeSize);
-  EOFCode = ClearCode + 1;
-    FreeCode = FirstFree = ClearCode + 2;
-
-  /* The GIF spec has it that the code size is the code size used to
-   * compute the above values is the code size given in the file, but the
-   * code size used in compression/decompression is the code size given in
-   * the file plus one. (thus the ++).
-   */
-
-  CodeSize++;
-  InitCodeSize = CodeSize;
-  MaxCode = (1 << CodeSize);
-  ReadMask = MaxCode - 1;
-
-  /* Read the raster data.  Here we just transpose it from the GIF array
-   * to the Raster array, turning it from a series of blocks into one long
-   * data stream, which makes life much easier for ReadCode().
-   */
-
-  ptr1 = Raster;
-  do
-  {
-    ch = ch1 = NEXTBYTE;
-    while (ch--) *ptr1++ = NEXTBYTE;
-    if ((Raster - ptr1) > filesize)
-      return(GIF_FileInvalid);
-  }
-  while(ch1);
-
-  free(RawGIF);              /* We're done with the raw data now... */
-
-#ifdef DEBUG_GIF
-  fprintf(stderr, "done\n");
-  fprintf(stderr, "   Decompressing... ");
-#endif
-
-  /* Allocate the X Image */
-  ImageData = (byte *) malloc(Width*Height);
-  if (!ImageData)
-    return(GIF_NoMemory);
-
-  new_image = XCreateImage(display,visual,8,ZPixmap,0,ImageData,
-                          Width,Height,8,Width);
-  if (!new_image)
-    return(GIF_NoMemory);
-
-  BytesPerScanline = Width;
-
-
-  /* Decompress the file, continuing until you see the GIF EOF code.
-   * One obvious enhancement is to add checking for corrupt files here.
-   */
-
-  Code = ReadCode();
-  while (Code != EOFCode)
-  {
-    /* Clear code sets everything back to its initial value, then reads the
-     * immediately subsequent code as uncompressed data.
-     */
-
-    if (Code == ClearCode)
-    {
-      CodeSize = InitCodeSize;
-      MaxCode = (1 << CodeSize);
-      ReadMask = MaxCode - 1;
-      FreeCode = FirstFree;
-      CurCode = OldCode = Code = ReadCode();
-      FinChar = CurCode & BitMask;
-      AddToPixel(FinChar);
-    }
-    else
-    {
-      /* If not a clear code, then must be data:
-       * save same as CurCode and InCode
-       */
-
-      CurCode = InCode = Code;
-
-      /* If greater or equal to FreeCode, not in the hash table yet;
-       * repeat the last character decoded
-       */
-
-      if (CurCode >= FreeCode)
-      {
-       CurCode = OldCode;
-       OutCode[OutCount++] = FinChar;
-      }
-
-      /* Unless this code is raw data, pursue the chain pointed to by CurCode
-       * through the hash table to its end; each code in the chain puts its
-       * associated output code on the output queue.
-       */
-
-      while (CurCode > BitMask)
-      {
-       if (OutCount > 1024)
-         return(GIF_FileInvalid);
-
-       OutCode[OutCount++] = Suffix[CurCode];
-       CurCode = Prefix[CurCode];
-      }
-
-      /* The last code in the chain is treated as raw data. */
-
-      FinChar = CurCode & BitMask;
-      OutCode[OutCount++] = FinChar;
-
-      /* Now we put the data out to the Output routine.
-       * It's been stacked LIFO, so deal with it that way...
-       */
-
-      for (i = OutCount - 1; i >= 0; i--)
-       AddToPixel(OutCode[i]);
-      OutCount = 0;
-
-      /* Build the hash table on-the-fly. No table is stored in the file. */
-
-      Prefix[FreeCode] = OldCode;
-      Suffix[FreeCode] = FinChar;
-      OldCode = InCode;
-
-      /* Point to the next slot in the table.  If we exceed the current
-       * MaxCode value, increment the code size unless it's already 12.  If it
-       * is, do nothing: the next code decompressed better be CLEAR
-       */
-
-      FreeCode++;
-      if (FreeCode >= MaxCode)
-      {
-       if (CodeSize < 12)
-       {
-         CodeSize++;
-         MaxCode *= 2;
-         ReadMask = (1 << CodeSize) - 1;
-       }
-      }
-    }
-    Code = ReadCode();
-  }
-
-  free(Raster);
-
-#ifdef DEBUG_GIF
-  fprintf(stderr, "done\n");
-  fprintf(stderr,"   %d colors used\n",numused);
-#endif
-
-  if (file != stdin)
-    fclose(file);
-
-  if (ColorDicking(display) != GIF_Success)
-    return(GIF_ColorFailed);
-
-  *image = new_image;
-  return(GIF_Success);
-}
-
-
-/* Fetch the next code from the raster data stream.  The codes can be
- * any length from 3 to 12 bits, packed into 8-bit bytes, so we have to
- * maintain our location in the Raster array as a BIT Offset.  We compute
- * the byte Offset into the raster array by dividing this by 8, pick up
- * three bytes, compute the bit Offset into our 24-bit chunk, shift to
- * bring the desired code to the bottom, then mask it off and return it. 
- */
-
-static int ReadCode()
-{
-  int RawCode, ByteOffset;
-
-  ByteOffset = BitOffset / 8;
-  RawCode = Raster[ByteOffset] + (0x100 * Raster[ByteOffset + 1]);
-  if (CodeSize >= 8)
-    RawCode += (0x10000 * Raster[ByteOffset + 2]);
-  RawCode >>= (BitOffset % 8);
-  BitOffset += CodeSize;
-  return(RawCode & ReadMask);
-}
-
-
-static void AddToPixel(byte Index)
-{
-  if (YC<Height)
-    *(ImageData + YC * BytesPerScanline + XC) = Index;
-
-  if (!used[Index])
-  {
-    used[Index]=1;
-    numused++;
-  }
-
-  /* Update the X-coordinate, and if it overflows, update the Y-coordinate */
-
-  if (++XC == Width)
-  {
-    /* If a non-interlaced picture, just increment YC to the next scan line. 
-     * If it's interlaced, deal with the interlace as described in the GIF
-     * spec.  Put the decoded scan line out to the screen if we haven't gone
-     * past the bottom of it
-     */
-
-    XC = 0;
-    if (!Interlace)
-      YC++;
-    else
-    {
-      switch (Pass)
-      {
-       case 0:
-         YC += 8;
-         if (YC >= Height)
-         {
-           Pass++;
-           YC = 4;
-         }
-         break;
-
-       case 1:
-         YC += 8;
-         if (YC >= Height)
-         {
-           Pass++;
-           YC = 2;
-         }
-         break;
-
-       case 2:
-         YC += 4;
-         if (YC >= Height)
-         {
-           Pass++;
-           YC = 1;
-         }
-         break;
-
-       case 3:
-         YC += 2;
-         break;
-
-       default:
-         break;
-       }
-    }
-  }
-}
-
-
-static int ColorDicking(Display *display)
-{
-  /* we've got the picture loaded, we know what colors are needed. get 'em */
-
-  register int i,j;
-  static byte lmasks[8] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80};
-  byte lmask, *ptr;
-  int screen = DefaultScreen(display);
-  Colormap cmap = DefaultColormap(display,screen);
-  int dispcells = DisplayCells(display,screen);
-
-  int strip = 0;
-  int nostrip = 0; 
-
-  if (!HasColormap)
-    return(GIF_Success);
-  /* no need to allocate any colors if no colormap in GIF file */
-
-  /* Allocate the X colors for this picture */
-
-  if (nostrip)
-  {
-    /* nostrip was set.  try REAL hard to do it */
-    for (i=j=0; i<numcols; i++)
-    {
-      if (used[i])
-      {
-       defs[i].red   = Red[i]<<8;
-       defs[i].green = Green[i]<<8;
-       defs[i].blue  = Blue[i]<<8;
-       defs[i].flags = DoRed | DoGreen | DoBlue;
-       if (!XAllocColor(display,cmap,&defs[i]))
-       { 
-         j++;
-         defs[i].pixel = 0xffff;
-       }
-       cols[i] = defs[i].pixel;
-      }
-    }
-
-    if (j)
-    {
-      /* failed to pull it off */
-
-      XColor ctab[256];
-      int dc;
-
-      dc = (dispcells<256) ? dispcells : 256;
-
-      fprintf(stderr,
-             "failed to allocate %d out of %d colors.  Trying extra hard.\n",
-             j,numused);
-
-      /* read in the color table */
-      for (i=0; i<dc; i++)
-       ctab[i].pixel = i;
-      XQueryColors(display,cmap,ctab,dc);
-                
-      /* run through the used colors.  any used color that has a pixel
-        value of 0xffff wasn't allocated.  for such colors, run through
-        the entire X colormap and pick the closest color */
-
-      for (i=0; i<numcols; i++)
-       if (used[i] && cols[i]==0xffff)
-       {
-         /* an unallocated pixel */
-
-         int d, mdist, close;
-         unsigned long r,g,b;
-
-         mdist = 100000;   close = -1;
-         r =  Red[i];
-         g =  Green[i];
-         b =  Blue[i];
-         for (j=0; j<dc; j++)
-         {
-           d = abs(r - (ctab[j].red>>8)) +
-             abs(g - (ctab[j].green>>8)) +
-               abs(b - (ctab[j].blue>>8));
-           if (d<mdist)
-           {
-             mdist=d;
-             close=j;
-           }
-         }
-
-         if (close<0)
-           return(GIF_ColorFailed);
-
-         bcopy(&defs[close],&defs[i],sizeof(XColor));
-         cols[i] = ctab[close].pixel;
-       }
-    }  /* end 'failed to pull it off' */
-  }
-  else
-  {
-    /* strip wasn't set, do the best auto-strip */
-
-    j = 0;
-    while (strip<8)
-    {
-      lmask = lmasks[strip];
-      for (i=0; i<numcols; i++)
-      {
-       if (used[i])
-       {
-         defs[i].red   = (Red[i]  &lmask)<<8;
-         defs[i].green = (Green[i]&lmask)<<8;
-         defs[i].blue  = (Blue[i] &lmask)<<8;
-         defs[i].flags = DoRed | DoGreen | DoBlue;
-         if (!XAllocColor(display,cmap,&defs[i]))
-           break;
-         cols[i] = defs[i].pixel;
-       }
-      }
-
-      if (i<numcols)
-      {
-       /* failed */
-       strip++;
-       j++;
-       for (i--; i>=0; i--)
-         if (used[i])
-           XFreeColors(display,cmap,cols+i,1,0L);
-      }
-      else
-       break;
-    }
-
-#ifdef DEBUG_GIF
-    if (j && strip<8)
-      fprintf(stderr,"%s: stripped %d bits\n",progname,strip);
-#endif
-
-    if (strip==8)
-    {
-      fprintf(stderr,"UTTERLY failed to allocate the desired colors.\n");
-      for (i=0; i<numcols; i++) cols[i]=i;
-    }
-  }
-
-  ptr = ImageData;
-  for (i=0; i<Height; i++)
-    for (j=0; j<Width; j++,ptr++) 
-      *ptr = (byte) cols[*ptr];
-
-  return(GIF_Success);
-}
-
-
-/******************************************************************************
- *  This makes sure the display's depth is the same as the
- * depth of the default 8 bit image.  If not, we build a new image
- * that has the correct depth.  This works on the fact that
- * the color mapper has already changed every pixel value in the
- * image into the proper number of bits (to fit into the pallet)
- * so we can just chop down the number of bits.
- *   This changes the global variable 'expImage' if necessary.
- */
-
-static int ConvertXImageDepth(Display *display, XImage **image)
-{
-  int screen = DefaultScreen(display);
-  int depth = DefaultDepth(display, screen);
-
-
-
-
-
-
-  printf("ConvertXImageDepth:\n");
-  printf("(*image)->depth == %d\n",
-        (*image)->depth);
-  printf("DefaultDepth(display, screen) == %d\n",
-        DefaultDepth(display, screen));
-
-
-
-
-  if ((*image)->depth != depth)
-  {
-    XImage *old_image, *new_image;
-
-    Visual *visual = DefaultVisual(display,screen);
-
-    int width = (*image)->width;
-    int height = (*image)->height;
-    register int dwx, dwy;
-    byte *data;
-
-
-
-
-
-    printf("ConvertXImageDepth: ---------> CONVERTING...\n");
-
-
-
-
-
-
-    data = (byte *)malloc(width * height * depth);
-    old_image = *image;
-
-#if 1
-    new_image = XCreateImage(display,visual,depth,
-                            ZPixmap,0,data,width,height,8,0);
-#else
-    new_image = XGetImage(display,RootWindow(display,screen),
-                         0,0,width,height,0xffffffff,ZPixmap);
-#endif
-
-    if (!new_image)
-      return(GIF_NoMemory);
-
-    if (old_image->depth == 8 && new_image->depth == 4)
-    {
-      /* speedup for the most common format change */
-
-      register byte *sptr = (byte *)old_image->data;
-      register byte *dptr = (byte *)new_image->data;
-
-      for (dwy=1; dwy<=height; dwy++)
-      {
-       for (dwx=1; dwx<width; dwx+=2)
-       {
-         *dptr = (*sptr) | (*(sptr+1)<<4);
-         dptr++;
-         sptr+=2;
-       }
-       if (width & 1)
-       {
-         /* if extra pixal at end of line, just move it */
-         *dptr = *sptr;
-         sptr++; dptr++;
-       }
-      }
-    }
-    else       /* other format change than 8 bit -> 4 bit */
-    {
-      unsigned long pixel_value;
-
-      for (dwx=0; dwx<width; dwx++)
-      {
-       for (dwy=0; dwy<height; dwy++)
-       {
-         pixel_value = XGetPixel(old_image, dwx, dwy);
-
-         if (pixel_value > 0xff)
-           printf("pixel = %lx", pixel_value);
-
-         XPutPixel(new_image, dwx, dwy, pixel_value);
-       }
-      }
-    }
-
-    free(old_image->data);
-    old_image->data = NULL;
-    XDestroyImage(old_image);
-
-    *image = new_image;
-  }
-
-  return(GIF_Success);
-}
-
-
-static unsigned long be2long(unsigned char *be) /* big-endian -> long int */
-{
-  return((be[0]<<24) | (be[1]<<16) | (be[2]<<8) | be[3]);
-}
-
-static unsigned short be2short(unsigned char *be) /* big-endian -> short int */
-{
-  return((be[0]<<8) | be[1]);
-}
-
-static struct IFF_ILBM_BMHD *ConvertBMHD(unsigned char *header_data)
-{
-  struct IFF_ILBM_BMHD_big_endian *bmhd_be;
-  struct IFF_ILBM_BMHD *bmhd;
-
-  bmhd_be = (struct IFF_ILBM_BMHD_big_endian *)header_data;
-  bmhd = (struct IFF_ILBM_BMHD *)malloc(sizeof(struct IFF_ILBM_BMHD));
-  if (!bmhd)
-    return(NULL);
-
-  bmhd->Width = be2short(bmhd_be->Width);
-  bmhd->Height = be2short(bmhd_be->Height);
-  bmhd->LeftEdge = be2short(bmhd_be->LeftEdge);
-  bmhd->TopEdge = be2short(bmhd_be->TopEdge);
-  bmhd->Depth = (int)bmhd_be->Depth;
-  bmhd->Mask = (int)bmhd_be->Mask;
-  bmhd->Compression = (int)bmhd_be->Compression;
-  bmhd->pad1 = bmhd_be->pad1;
-  bmhd->transparentColor = be2short(bmhd_be->transparentColor);
-  bmhd->xAspect = (int)bmhd_be->xAspect;
-  bmhd->yAspect = (int)bmhd_be->yAspect;
-  bmhd->pageWidth = be2short(bmhd_be->pageWidth);
-  bmhd->pageHeight = be2short(bmhd_be->pageHeight);
-
-  return(bmhd);
-}
-
-static unsigned char MSBitFirst2LSBitFirst(unsigned char msb_byte)
-{
-  unsigned char lsb_byte = 0;
-  int i;
-
-  for(i=7;i>=0;i--)
-  {
-    lsb_byte |= (msb_byte & 1) << i;
-    msb_byte >>= 1;
-  }
-
-  return(lsb_byte);
-}
-
-int Read_ILBM_to_Bitmap(Display *display, char *filename, Pixmap *pixmap)
-{
-  Pixmap new_pixmap = 0;
-  int screen = DefaultScreen(display);
-  Drawable root = RootWindow(display,screen);
-  struct IFF_ILBM_FORM_big_endian *form_header;
-  struct IFF_ILBM_BMHD *bitmap_header;
-  unsigned long file_len, body_len;
-  unsigned char *file_data, *bitmap_data;
-  unsigned char *file_ptr, *bitmap_ptr, *body_ptr;
-  unsigned char byte_count, byte_value;
-  int i,x,y,z;
-  int width, height, depth;
-  int bytes_per_line, bitmap_size;
-  FILE *file;
-
-  if (!(file = fopen(filename,"r")))
-    return(ILBM_OpenFailed);
-
-  if (fseek(file,0,SEEK_END) < 0)
-  {
-    fclose(file);
-    return(ILBM_ReadFailed);
-  }
-
-  file_len = ftell(file);
-  rewind(file);
-
-  if (!(file_data = (unsigned char *)malloc(file_len)))
-  {
-    fclose(file);
-    return(ILBM_NoMemory);
-  }
-
-  if (fread(file_data,1,file_len,file) != file_len)
-  {
-    free(file_data);
-    fclose(file);
-    return(ILBM_ReadFailed);
-  }
-
-  fclose(file);
-
-  form_header = (struct IFF_ILBM_FORM_big_endian *)file_data;
-
-  if (strncmp(form_header->magic_FORM,"FORM",4) ||
-      file_len != be2long(form_header->chunk_size)+8 ||
-      strncmp(form_header->magic_ILBM,"ILBM",4))
-  {
-#ifdef DEBUG_ILBM
-      printf("%s: IFF chunk 'FORM' and/or 'ILBM' not found.\n",filename);
-#endif
-    free(file_data);
-    return(ILBM_FileInvalid);
-  }
-
-  bitmap_header = NULL;
-  body_ptr = NULL;
-  file_ptr = file_data + 12;
-
-  while(file_ptr < (unsigned char *)(file_data + file_len))
-  {
-    if (!strncmp(file_ptr,"BMHD",4))
-    {
-#ifdef DEBUG_ILBM
-      printf("%s: IFF chunk 'BMHD' found.\n",filename);
-#endif
-      bitmap_header = ConvertBMHD(file_ptr + 8);
-      file_ptr += be2long(file_ptr + 4) + 8;
-      continue;
-    }
-    else if (!strncmp(file_ptr,"BODY",4))
-    {
-#ifdef DEBUG_ILBM
-      printf("%s: IFF chunk 'BODY' found.\n",filename);
-#endif
-      body_ptr = file_ptr + 8;
-      body_len = be2long(file_ptr + 4);
-      file_ptr += be2long(file_ptr + 4) + 8;
-      continue;
-    }
-    else
-    {
-#ifdef DEBUG_ILBM
-      printf("%s: IFF chunk '%c%c%c%c' found (but not used).\n",filename,
-            file_ptr[0],file_ptr[1],file_ptr[2],file_ptr[3]);
-#endif
-      /* other chunk not recognized here */
-      file_ptr += be2long(file_ptr + 4) + 8;
-      continue;
-    }
-  }
-
-  if (!bitmap_header || !body_ptr)
-  {
-#ifdef DEBUG_ILBM
-      printf("%s: IFF chunk 'BMHD' and/or 'BODY' not found.\n",filename);
-#endif
-    free(file_data);
-    return(ILBM_FileInvalid);
-  }
-
-  width = bitmap_header->Width;
-  height = bitmap_header->Height;
-  depth = bitmap_header->Depth;
-
-#ifdef DEBUG_ILBM
-  if (depth > 1)
-    printf("%s: %d bitplanes found; using only the first plane.\n",
-          filename,depth);
-#endif
-
-  bytes_per_line = ((width + 15) / 16) * 2;
-  bitmap_size = bytes_per_line * height;
-
-  bitmap_data = (char *)malloc(bitmap_size);
-  if (!bitmap_data)
-  {
-    free(file_data);
-    free(bitmap_header);
-    return(ILBM_NoMemory);
-  }
-
-  bitmap_ptr = bitmap_data;
-  for(i=0;i<bitmap_size;i++)
-    *bitmap_ptr++ = 0;
-
-  for(y=0;y<height;y++)
-  {
-    /* we only read the first bitplane here to create a black/white bitmap */
-
-    for(z=0;z<depth;z++)
-    {
-      bitmap_ptr = bitmap_data + y * bytes_per_line;
-      x = 0;
-
-      if (!bitmap_header->Compression)
-      {
-       while(x++ < bytes_per_line)
-         *bitmap_ptr++ |= MSBitFirst2LSBitFirst(*body_ptr++);
-      }
-      else
-      {
-       while(x < bytes_per_line)
-       {
-         byte_count = *body_ptr++;
-
-         if (byte_count <= 128)
-         {
-           for(i=0;i<byte_count+1;i++)
-             *bitmap_ptr++ |= MSBitFirst2LSBitFirst(*body_ptr++);
-           x += byte_count + 1;
-         }
-         else
-         {
-           byte_value = *body_ptr++;
-           for(i=0;i<257-byte_count;i++)
-             *bitmap_ptr++ |= MSBitFirst2LSBitFirst(byte_value);
-           x += 257 - byte_count;
-         }
-       }
-      }
-    }
-  }
-
-  bitmap_ptr = bitmap_data;
-  for(i=0;i<bitmap_size;i++)
-    *bitmap_ptr++ ^= 0xff;
-
-  new_pixmap = XCreateBitmapFromData(display,root,bitmap_data,width,height);
-
-  free(file_data);
-  free(bitmap_data);
-  free(bitmap_header);
-
-  if (!new_pixmap)
-    return(ILBM_NoMemory);
-
-  *pixmap = new_pixmap;
-  return(ILBM_Success);
-}
-#endif
diff --git a/src/gfxload.h b/src/gfxload.h
deleted file mode 100644 (file)
index 7489447..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/***********************************************************
-*  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
-*----------------------------------------------------------*
-*  (c) 1995-98 Artsoft Entertainment                       *
-*              Holger Schemel                              *
-*              Oststrasse 11a                              *
-*              33604 Bielefeld                             *
-*              phone: ++49 +521 290471                     *
-*              email: aeglos@valinor.owl.de                *
-*----------------------------------------------------------*
-*  gfxload.h                                               *
-***********************************************************/
-
-#ifndef GFXLOAD_H
-#define GFXLOAD_H
-
-#ifndef MSDOS
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
-#define GIF_Success             0
-#define GIF_OpenFailed         -1
-#define GIF_ReadFailed         -2
-#define        GIF_FileInvalid         -3
-#define GIF_NoMemory           -4
-#define GIF_ColorFailed                -5
-
-#define ILBM_Success            0
-#define ILBM_OpenFailed                -1
-#define ILBM_ReadFailed                -2
-#define        ILBM_FileInvalid        -3
-#define ILBM_NoMemory          -4
-#define ILBM_ColorFailed       -5
-
-int Read_ILBM_to_Bitmap(Display *, char *, Pixmap *);
-int Read_GIF_to_Bitmap(Display *, char *, Pixmap *);
-int Read_GIF_to_Pixmap(Display *, char *, Pixmap *);
-int Read_GIF_to_XImage(Display *, char *, XImage **);
-
-#endif
-#endif
diff --git a/src/gfxloader.c b/src/gfxloader.c
deleted file mode 100644 (file)
index 9a28f43..0000000
+++ /dev/null
@@ -1,1155 +0,0 @@
-/***********************************************************
-*  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
-*----------------------------------------------------------*
-*  ©1995 Artsoft Development                               *
-*        Holger Schemel                                    *
-*        33659 Bielefeld-Senne                             *
-*        Telefon: (0521) 493245                            *
-*        eMail: aeglos@valinor.owl.de                      *
-*               aeglos@uni-paderborn.de                    *
-*               q99492@pbhrzx.uni-paderborn.de             *
-*----------------------------------------------------------*
-*  gfxloader.c                                             *
-***********************************************************/
-
-#include "gfxloader.h"
-
-
-
-
-
-
-extern Window                  window;
-extern void Delay(long);
-
-
-
-
-
-
-#ifdef DEBUG
-/*
-#define DEBUG_GIF
-#define DEBUG_ILBM
-*/
-#endif
-
-struct IFF_ILBM_FORM_big_endian
-{
-  char magic_FORM[4];
-  unsigned char chunk_size[4];
-  char magic_ILBM[4];
-};
-
-struct IFF_ILBM_BMHD_big_endian
-{
-  char Width[2], Height[2];
-  char LeftEdge[2], TopEdge[2];
-  char Depth;
-  char Mask;
-  char Compression;
-  char pad1;
-  char transparentColor[2];
-  char xAspect, yAspect;
-  char pageWidth[2], pageHeight[2];
-};
-
-struct IFF_ILBM_BMHD
-{
-  unsigned int Width, Height;
-  int LeftEdge, TopEdge;
-  unsigned int Depth;
-  unsigned int Mask;
-  unsigned int Compression;
-  unsigned char pad1;
-  unsigned int transparentColor;
-  unsigned int xAspect, yAspect;
-  int pageWidth, pageHeight;
-};
-
-static int ConvertXImageDepth(Display *, XImage **);
-static int Read_GIF_to_Pixmap_or_Bitmap(Display *, char *, Pixmap *, int);
-
-#define READ_GIF_TO_BITMAP     0
-#define READ_GIF_TO_PIXMAP     1
-
-
-int Read_GIF_to_Bitmap(Display *display, char *filename, Pixmap *pixmap)
-{
-  printf("Read_GIF_to_Bitmap\n");
-
-
-
-
-  return(Read_GIF_to_Pixmap_or_Bitmap(display, filename,
-                                     pixmap, READ_GIF_TO_BITMAP));
-}
-
-int Read_GIF_to_Pixmap(Display *display, char *filename, Pixmap *pixmap)
-{
-  printf("Read_GIF_to_Pixmap\n");
-
-
-
-
-  return(Read_GIF_to_Pixmap_or_Bitmap(display, filename,
-                                     pixmap, READ_GIF_TO_PIXMAP));
-}
-
-int Read_GIF_to_Pixmap_or_Bitmap(Display *display, char *filename,
-                                Pixmap *pixmap, int mode)
-{
-  XImage *image = NULL;
-  Pixmap new_pixmap = 0;
-  int return_code;
-
-  *pixmap = 0;
-  return_code = Read_GIF_to_XImage(display, filename, &image);
-  if (return_code != GIF_Success)
-    return(return_code);
-
-  if (image)
-  {
-    int screen = DefaultScreen(display);
-    Drawable root = RootWindow(display,screen);
-    int depth = DefaultDepth(display, screen);
-    int width = image->width;
-    int height = image->height;
-
-    if (mode == READ_GIF_TO_BITMAP)
-    {
-      int i,x,y;
-      unsigned long black_pixel = BlackPixel(display,screen);
-      int bytes_per_line = (width+7) / 8;
-      int size = bytes_per_line * height;
-      char *data, *ptr;
-
-      data = (char *)malloc(size);
-      if (!data)
-       return(GIF_NoMemory);
-
-      ptr = data;
-      for(i=0;i<size;i++)
-       *ptr++ = 0;
-
-      for(y=0;y<height;y++)
-      {
-       for(x=0;x<width;x++)
-       {
-         if (XGetPixel(image,x,y) == black_pixel)
-           data[y * bytes_per_line + x/8] |= (1 << (x%8));
-       }
-      }
-
-      new_pixmap = XCreateBitmapFromData(display,root,data,width,height);
-      free(data);
-
-      if (!new_pixmap)
-       return(GIF_NoMemory);
-    }
-    else
-    {
-      GC gc;
-      XGCValues gcv;
-
-      if (ConvertXImageDepth(display, &image) != GIF_Success)
-       return(GIF_ColorFailed);
-
-      new_pixmap = XCreatePixmap(display,root,width,height,depth);
-
-      if (!new_pixmap)
-       return(GIF_NoMemory);
-
-      gcv.foreground = BlackPixel(display,screen);
-      gcv.background = WhitePixel(display,screen);
-      gc = XCreateGC(display, root, GCForeground | GCBackground, &gcv);
-      XPutImage(display,new_pixmap,gc,image,0,0,0,0,width,height);
-
-
-
-
-
-
-      Delay(1000000);
-
-      XPutImage(display,window,gc,image,0,0,0,0,width,height);
-
-      Delay(3000000);
-
-
-
-
-
-      XFreeGC(display, gc);
-    }
-
-    XDestroyImage(image);
-  }
-
-  *pixmap = new_pixmap;
-  return(return_code);
-}
-
-
-/*
- * Read_GIF_to_XImage()  -  based strongly on...
- *
- * xgifload.c  -  based strongly on...
- *
- * gif2ras.c - Converts from a Compuserve GIF (tm) image to a Sun Raster image.
- *
- * Copyright (c) 1988, 1989 by Patrick J. Naughton
- *
- * Author: Patrick J. Naughton
- * naughton@wind.sun.com
- *
- * Permission to use, copy, modify, and distribute this software and its
- * documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appear in all copies and that
- * both that copyright notice and this permission notice appear in
- * supporting documentation.
- *
- * This file is provided AS IS with no warranties of any kind.  The author
- * shall have no liability with respect to the infringement of copyrights,
- * trade secrets or any patents by this file or any part thereof.  In no
- * event will the author be liable for any lost revenue or profits or
- * other special, indirect and consequential damages.
- *
- */
-
-typedef int boolean;
-typedef unsigned char byte;
-
-static int ReadCode(void);
-static void AddToPixel(byte);
-static int ColorDicking(Display *);
-
-#define NEXTBYTE       (*ptr++)
-#define IMAGESEP       0x2c
-#define INTERLACEMASK  0x40
-#define COLORMAPMASK   0x80
-
-static
-int BitOffset,                 /* Bit Offset of next code */
-    XC, YC,                    /* Output X and Y coords of current pixel */
-    Pass,                      /* Used by output routine if interlaced pic */
-    OutCount,                  /* Decompressor output 'stack count' */
-    RWidth, RHeight,           /* screen dimensions */
-    Width, Height,             /* image dimensions */
-    LeftOfs, TopOfs,           /* image offset */
-    BitsPerPixel,              /* Bits per pixel, read from GIF header */
-    BytesPerScanline,          /* bytes per scanline in output raster */
-    ColorMapSize,              /* number of colors */
-    Background,                        /* background color */
-    CodeSize,                  /* Code size, read from GIF header */
-    InitCodeSize,              /* Starting code size, used during Clear */
-    Code,                      /* Value returned by ReadCode */
-    MaxCode,                   /* limiting value for current code size */
-    ClearCode,                 /* GIF clear code */
-    EOFCode,                   /* GIF end-of-information code */
-    CurCode, OldCode, InCode,  /* Decompressor variables */
-    FirstFree,                 /* First free code, generated per GIF spec */
-    FreeCode,                  /* Decompressor, next free slot in hash table*/
-    FinChar,                   /* Decompressor variable */
-    BitMask,                   /* AND mask for data size */
-    ReadMask;                  /* Code AND mask for current code size */
-
-static boolean Interlace, HasColormap;
-
-static byte *ImageData;                /* The result array */
-static byte *RawGIF;           /* The heap array to hold it, raw */
-static byte *Raster;           /* The raster data stream, unblocked */
-
-/* The color map, read from the GIF header */
-static byte Red[256], Green[256], Blue[256], used[256];
-static int  numused;
-
-extern char *progname;
-
-static int numcols;
-static unsigned long cols[256];
-static XColor defs[256];
-
-int Read_GIF_to_XImage(Display *display, char *filename, XImage **image)
-{
-  int filesize;
-  register byte ch, ch1;
-  register byte *ptr, *ptr1;
-  register int i;
-  int screen = DefaultScreen(display);
-  Visual *visual = DefaultVisual(display,screen);
-  XImage *new_image = NULL;
-  char *id = "GIF87a";
-  FILE *file;
-  int Prefix[4096];    /* The hash table used by the decompressor */
-  int Suffix[4096];
-  int OutCode[1025];   /* An output array used by the decompressor */
-
-  BitOffset = XC = YC = Pass = OutCount = 0;
-  *image = NULL;
-
-  if (strcmp(filename,"-")==0)
-  {
-    file = stdin;
-    filename = "<stdin>";
-  }
-  else
-    file = fopen(filename,"r");
-
-  if (!file)
-    return(GIF_OpenFailed);
-
-  /* find the size of the file */
-  fseek(file, 0L, 2);
-  filesize = ftell(file);
-  fseek(file, 0L, 0);
-
-  if (!(ptr = RawGIF = (byte *) malloc(filesize)))
-    return(GIF_NoMemory);
-
-  if (!(Raster = (byte *) malloc(filesize)))
-    return(GIF_NoMemory);
-
-  if (fread(ptr, filesize, 1, file) != 1)
-    return(GIF_ReadFailed);
-
-  if (strncmp(ptr, id, 6))
-    return(GIF_FileInvalid);
-
-  ptr += 6;
-
-  /* Get variables from the GIF screen descriptor */
-
-  ch = NEXTBYTE;
-  RWidth = ch + 0x100 * NEXTBYTE;    /* screen dimensions... not used. */
-  ch = NEXTBYTE;
-  RHeight = ch + 0x100 * NEXTBYTE;
-
-  ch = NEXTBYTE;
-  HasColormap = ((ch & COLORMAPMASK) ? True : False);
-
-  BitsPerPixel = (ch & 7) + 1;
-  numcols = ColorMapSize = 1 << BitsPerPixel;
-  BitMask = ColorMapSize - 1;
-
-  Background = NEXTBYTE;             /* background color... not used. */
-
-  if (NEXTBYTE)              /* supposed to be NULL */
-    return(GIF_FileInvalid);
-
-  /* Read in global colormap. */
-
-  if (HasColormap)
-  {
-    for (i = 0; i < ColorMapSize; i++)
-    {
-      Red[i] = NEXTBYTE;
-      Green[i] = NEXTBYTE;
-      Blue[i] = NEXTBYTE;
-      used[i] = 0;
-    }
-    numused = 0;
-  }
-  else
-  {
-    /* no colormap in GIF file */
-    fprintf(stderr,"%s:  warning!  no colortable in this file.  Winging it.\n",
-           progname);
-    if (!numcols)
-      numcols=256;
-    for (i=0; i<numcols; i++)
-      cols[i] = (unsigned long) i;
-  }
-
-  /* Check for image seperator */
-
-  if (NEXTBYTE != IMAGESEP)
-    return(GIF_FileInvalid);
-
-  /* Now read in values from the image descriptor */
-
-  ch = NEXTBYTE;
-  LeftOfs = ch + 0x100 * NEXTBYTE;
-  ch = NEXTBYTE;
-  TopOfs = ch + 0x100 * NEXTBYTE;
-  ch = NEXTBYTE;
-  Width = ch + 0x100 * NEXTBYTE;
-  ch = NEXTBYTE;
-  Height = ch + 0x100 * NEXTBYTE;
-  Interlace = ((NEXTBYTE & INTERLACEMASK) ? True : False);
-
-#ifdef DEBUG_GIF
-  fprintf(stderr, "%s:\n", filename);
-  fprintf(stderr, "   %dx%d, %d bpp / %d colors, %sinterlaced\n",
-         Width,Height, BitsPerPixel,ColorMapSize,(Interlace ? "" : "non-"));
-  fprintf(stderr, "   Reading file... ");
-#endif
-
-  /* Note that I ignore the possible existence of a local color map.
-   * I'm told there aren't many files around that use them, and the spec
-   * says it's defined for future use.  This could lead to an error
-   * reading some files. 
-   */
-
-  /* Start reading the raster data. First we get the intial code size
-   * and compute decompressor constant values, based on this code size.
-   */
-
-  CodeSize = NEXTBYTE;
-  ClearCode = (1 << CodeSize);
-  EOFCode = ClearCode + 1;
-    FreeCode = FirstFree = ClearCode + 2;
-
-  /* The GIF spec has it that the code size is the code size used to
-   * compute the above values is the code size given in the file, but the
-   * code size used in compression/decompression is the code size given in
-   * the file plus one. (thus the ++).
-   */
-
-  CodeSize++;
-  InitCodeSize = CodeSize;
-  MaxCode = (1 << CodeSize);
-  ReadMask = MaxCode - 1;
-
-  /* Read the raster data.  Here we just transpose it from the GIF array
-   * to the Raster array, turning it from a series of blocks into one long
-   * data stream, which makes life much easier for ReadCode().
-   */
-
-  ptr1 = Raster;
-  do
-  {
-    ch = ch1 = NEXTBYTE;
-    while (ch--) *ptr1++ = NEXTBYTE;
-    if ((Raster - ptr1) > filesize)
-      return(GIF_FileInvalid);
-  }
-  while(ch1);
-
-  free(RawGIF);              /* We're done with the raw data now... */
-
-#ifdef DEBUG_GIF
-  fprintf(stderr, "done\n");
-  fprintf(stderr, "   Decompressing... ");
-#endif
-
-  /* Allocate the X Image */
-  ImageData = (byte *) malloc(Width*Height);
-  if (!ImageData)
-    return(GIF_NoMemory);
-
-  new_image = XCreateImage(display,visual,8,ZPixmap,0,ImageData,
-                          Width,Height,8,Width);
-  if (!new_image)
-    return(GIF_NoMemory);
-
-  BytesPerScanline = Width;
-
-
-  /* Decompress the file, continuing until you see the GIF EOF code.
-   * One obvious enhancement is to add checking for corrupt files here.
-   */
-
-  Code = ReadCode();
-  while (Code != EOFCode)
-  {
-    /* Clear code sets everything back to its initial value, then reads the
-     * immediately subsequent code as uncompressed data.
-     */
-
-    if (Code == ClearCode)
-    {
-      CodeSize = InitCodeSize;
-      MaxCode = (1 << CodeSize);
-      ReadMask = MaxCode - 1;
-      FreeCode = FirstFree;
-      CurCode = OldCode = Code = ReadCode();
-      FinChar = CurCode & BitMask;
-      AddToPixel(FinChar);
-    }
-    else
-    {
-      /* If not a clear code, then must be data:
-       * save same as CurCode and InCode
-       */
-
-      CurCode = InCode = Code;
-
-      /* If greater or equal to FreeCode, not in the hash table yet;
-       * repeat the last character decoded
-       */
-
-      if (CurCode >= FreeCode)
-      {
-       CurCode = OldCode;
-       OutCode[OutCount++] = FinChar;
-      }
-
-      /* Unless this code is raw data, pursue the chain pointed to by CurCode
-       * through the hash table to its end; each code in the chain puts its
-       * associated output code on the output queue.
-       */
-
-      while (CurCode > BitMask)
-      {
-       if (OutCount > 1024)
-         return(GIF_FileInvalid);
-
-       OutCode[OutCount++] = Suffix[CurCode];
-       CurCode = Prefix[CurCode];
-      }
-
-      /* The last code in the chain is treated as raw data. */
-
-      FinChar = CurCode & BitMask;
-      OutCode[OutCount++] = FinChar;
-
-      /* Now we put the data out to the Output routine.
-       * It's been stacked LIFO, so deal with it that way...
-       */
-
-      for (i = OutCount - 1; i >= 0; i--)
-       AddToPixel(OutCode[i]);
-      OutCount = 0;
-
-      /* Build the hash table on-the-fly. No table is stored in the file. */
-
-      Prefix[FreeCode] = OldCode;
-      Suffix[FreeCode] = FinChar;
-      OldCode = InCode;
-
-      /* Point to the next slot in the table.  If we exceed the current
-       * MaxCode value, increment the code size unless it's already 12.  If it
-       * is, do nothing: the next code decompressed better be CLEAR
-       */
-
-      FreeCode++;
-      if (FreeCode >= MaxCode)
-      {
-       if (CodeSize < 12)
-       {
-         CodeSize++;
-         MaxCode *= 2;
-         ReadMask = (1 << CodeSize) - 1;
-       }
-      }
-    }
-    Code = ReadCode();
-  }
-
-  free(Raster);
-
-#ifdef DEBUG_GIF
-  fprintf(stderr, "done\n");
-  fprintf(stderr,"   %d colors used\n",numused);
-#endif
-
-  if (file != stdin)
-    fclose(file);
-
-  if (ColorDicking(display) != GIF_Success)
-    return(GIF_ColorFailed);
-
-  *image = new_image;
-  return(GIF_Success);
-}
-
-
-/* Fetch the next code from the raster data stream.  The codes can be
- * any length from 3 to 12 bits, packed into 8-bit bytes, so we have to
- * maintain our location in the Raster array as a BIT Offset.  We compute
- * the byte Offset into the raster array by dividing this by 8, pick up
- * three bytes, compute the bit Offset into our 24-bit chunk, shift to
- * bring the desired code to the bottom, then mask it off and return it. 
- */
-
-static int ReadCode()
-{
-  int RawCode, ByteOffset;
-
-  ByteOffset = BitOffset / 8;
-  RawCode = Raster[ByteOffset] + (0x100 * Raster[ByteOffset + 1]);
-  if (CodeSize >= 8)
-    RawCode += (0x10000 * Raster[ByteOffset + 2]);
-  RawCode >>= (BitOffset % 8);
-  BitOffset += CodeSize;
-  return(RawCode & ReadMask);
-}
-
-
-static void AddToPixel(byte Index)
-{
-  if (YC<Height)
-    *(ImageData + YC * BytesPerScanline + XC) = Index;
-
-  if (!used[Index])
-  {
-    used[Index]=1;
-    numused++;
-  }
-
-  /* Update the X-coordinate, and if it overflows, update the Y-coordinate */
-
-  if (++XC == Width)
-  {
-    /* If a non-interlaced picture, just increment YC to the next scan line. 
-     * If it's interlaced, deal with the interlace as described in the GIF
-     * spec.  Put the decoded scan line out to the screen if we haven't gone
-     * past the bottom of it
-     */
-
-    XC = 0;
-    if (!Interlace)
-      YC++;
-    else
-    {
-      switch (Pass)
-      {
-       case 0:
-         YC += 8;
-         if (YC >= Height)
-         {
-           Pass++;
-           YC = 4;
-         }
-         break;
-
-       case 1:
-         YC += 8;
-         if (YC >= Height)
-         {
-           Pass++;
-           YC = 2;
-         }
-         break;
-
-       case 2:
-         YC += 4;
-         if (YC >= Height)
-         {
-           Pass++;
-           YC = 1;
-         }
-         break;
-
-       case 3:
-         YC += 2;
-         break;
-
-       default:
-         break;
-       }
-    }
-  }
-}
-
-
-static int ColorDicking(Display *display)
-{
-  /* we've got the picture loaded, we know what colors are needed. get 'em */
-
-  register int i,j;
-  static byte lmasks[8] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80};
-  byte lmask, *ptr;
-  int screen = DefaultScreen(display);
-  Colormap cmap = DefaultColormap(display,screen);
-  int dispcells = DisplayCells(display,screen);
-
-  int strip = 0;
-  int nostrip = 0; 
-
-  if (!HasColormap)
-    return(GIF_Success);
-  /* no need to allocate any colors if no colormap in GIF file */
-
-  /* Allocate the X colors for this picture */
-
-  if (nostrip)
-  {
-    /* nostrip was set.  try REAL hard to do it */
-    for (i=j=0; i<numcols; i++)
-    {
-      if (used[i])
-      {
-       defs[i].red   = Red[i]<<8;
-       defs[i].green = Green[i]<<8;
-       defs[i].blue  = Blue[i]<<8;
-       defs[i].flags = DoRed | DoGreen | DoBlue;
-       if (!XAllocColor(display,cmap,&defs[i]))
-       { 
-         j++;
-         defs[i].pixel = 0xffff;
-       }
-       cols[i] = defs[i].pixel;
-      }
-    }
-
-    if (j)
-    {
-      /* failed to pull it off */
-
-      XColor ctab[256];
-      int dc;
-
-      dc = (dispcells<256) ? dispcells : 256;
-
-      fprintf(stderr,
-             "failed to allocate %d out of %d colors.  Trying extra hard.\n",
-             j,numused);
-
-      /* read in the color table */
-      for (i=0; i<dc; i++)
-       ctab[i].pixel = i;
-      XQueryColors(display,cmap,ctab,dc);
-                
-      /* run through the used colors.  any used color that has a pixel
-        value of 0xffff wasn't allocated.  for such colors, run through
-        the entire X colormap and pick the closest color */
-
-      for (i=0; i<numcols; i++)
-       if (used[i] && cols[i]==0xffff)
-       {
-         /* an unallocated pixel */
-
-         int d, mdist, close;
-         unsigned long r,g,b;
-
-         mdist = 100000;   close = -1;
-         r =  Red[i];
-         g =  Green[i];
-         b =  Blue[i];
-         for (j=0; j<dc; j++)
-         {
-           d = abs(r - (ctab[j].red>>8)) +
-             abs(g - (ctab[j].green>>8)) +
-               abs(b - (ctab[j].blue>>8));
-           if (d<mdist)
-           {
-             mdist=d;
-             close=j;
-           }
-         }
-
-         if (close<0)
-           return(GIF_ColorFailed);
-
-         bcopy(&defs[close],&defs[i],sizeof(XColor));
-         cols[i] = ctab[close].pixel;
-       }
-    }  /* end 'failed to pull it off' */
-  }
-  else
-  {
-    /* strip wasn't set, do the best auto-strip */
-
-    j = 0;
-    while (strip<8)
-    {
-      lmask = lmasks[strip];
-      for (i=0; i<numcols; i++)
-      {
-       if (used[i])
-       {
-         defs[i].red   = (Red[i]  &lmask)<<8;
-         defs[i].green = (Green[i]&lmask)<<8;
-         defs[i].blue  = (Blue[i] &lmask)<<8;
-         defs[i].flags = DoRed | DoGreen | DoBlue;
-         if (!XAllocColor(display,cmap,&defs[i]))
-           break;
-         cols[i] = defs[i].pixel;
-       }
-      }
-
-      if (i<numcols)
-      {
-       /* failed */
-       strip++;
-       j++;
-       for (i--; i>=0; i--)
-         if (used[i])
-           XFreeColors(display,cmap,cols+i,1,0L);
-      }
-      else
-       break;
-    }
-
-#ifdef DEBUG_GIF
-    if (j && strip<8)
-      fprintf(stderr,"%s: stripped %d bits\n",progname,strip);
-#endif
-
-    if (strip==8)
-    {
-      fprintf(stderr,"UTTERLY failed to allocate the desired colors.\n");
-      for (i=0; i<numcols; i++) cols[i]=i;
-    }
-  }
-
-  ptr = ImageData;
-  for (i=0; i<Height; i++)
-    for (j=0; j<Width; j++,ptr++) 
-      *ptr = (byte) cols[*ptr];
-
-  return(GIF_Success);
-}
-
-
-/******************************************************************************
- *  This makes sure the display's depth is the same as the
- * depth of the default 8 bit image.  If not, we build a new image
- * that has the correct depth.  This works on the fact that
- * the color mapper has already changed every pixel value in the
- * image into the proper number of bits (to fit into the pallet)
- * so we can just chop down the number of bits.
- *   This changes the global variable 'expImage' if necessary.
- */
-
-static int ConvertXImageDepth(Display *display, XImage **image)
-{
-  int screen = DefaultScreen(display);
-  int depth = DefaultDepth(display, screen);
-
-
-
-
-
-
-  printf("ConvertXImageDepth:\n");
-  printf("(*image)->depth == %d\n",
-        (*image)->depth);
-  printf("DefaultDepth(display, screen) == %d\n",
-        DefaultDepth(display, screen));
-
-
-
-
-  if ((*image)->depth != depth)
-  {
-    XImage *old_image, *new_image;
-    /*
-    Visual *visual = DefaultVisual(display,screen);
-    */
-    int width = (*image)->width;
-    int height = (*image)->height;
-    register int dwx, dwy;
-    byte *data;
-
-
-
-
-
-    printf("ConvertXImageDepth: ---------> CONVERTING...\n");
-
-
-
-
-
-
-    data = (byte *)malloc(width * height * depth);
-    old_image = *image;
-
-    /*
-    new_image = XCreateImage(display,visual,depth,
-                            ZPixmap,0,data,width,height,8,0);
-                            */
-
-    new_image = XGetImage(display,RootWindow(display,screen),
-                         0,0,width,height,0xffffffff,ZPixmap);
-
-
-    if (!new_image)
-      return(GIF_NoMemory);
-
-    if (old_image->depth == 8 && new_image->depth == 4)
-    {
-      /* speedup for the most common format change */
-
-      register byte *sptr = (byte *)old_image->data;
-      register byte *dptr = (byte *)new_image->data;
-
-      for (dwy=1; dwy<=height; dwy++)
-      {
-       for (dwx=1; dwx<width; dwx+=2)
-       {
-         *dptr = (*sptr) | (*(sptr+1)<<4);
-         dptr++;
-         sptr+=2;
-       }
-       if (width & 1)
-       {
-         /* if extra pixal at end of line, just move it */
-         *dptr = *sptr;
-         sptr++; dptr++;
-       }
-      }
-    }
-    else       /* other format change than 8 bit -> 4 bit */
-    {
-      unsigned long pixel_value;
-
-      for (dwx=0; dwx<width; dwx++)
-      {
-       for (dwy=0; dwy<height; dwy++)
-       {
-         pixel_value = XGetPixel(old_image, dwx, dwy);
-
-         if (pixel_value > 0xff)
-           printf("pixel = %lx", pixel_value);
-
-         XPutPixel(new_image, dwx, dwy, pixel_value);
-       }
-      }
-    }
-
-    free(old_image->data);
-    old_image->data = NULL;
-    XDestroyImage(old_image);
-
-    *image = new_image;
-  }
-
-  return(GIF_Success);
-}
-
-
-static unsigned long be2long(unsigned char *be) /* big-endian -> long int */
-{
-  return((be[0]<<24) | (be[1]<<16) | (be[2]<<8) | be[3]);
-}
-
-static unsigned short be2short(unsigned char *be) /* big-endian -> short int */
-{
-  return((be[0]<<8) | be[1]);
-}
-
-static struct IFF_ILBM_BMHD *ConvertBMHD(unsigned char *header_data)
-{
-  struct IFF_ILBM_BMHD_big_endian *bmhd_be;
-  struct IFF_ILBM_BMHD *bmhd;
-
-  bmhd_be = (struct IFF_ILBM_BMHD_big_endian *)header_data;
-  bmhd = (struct IFF_ILBM_BMHD *)malloc(sizeof(struct IFF_ILBM_BMHD));
-  if (!bmhd)
-    return(NULL);
-
-  bmhd->Width = be2short(bmhd_be->Width);
-  bmhd->Height = be2short(bmhd_be->Height);
-  bmhd->LeftEdge = be2short(bmhd_be->LeftEdge);
-  bmhd->TopEdge = be2short(bmhd_be->TopEdge);
-  bmhd->Depth = (int)bmhd_be->Depth;
-  bmhd->Mask = (int)bmhd_be->Mask;
-  bmhd->Compression = (int)bmhd_be->Compression;
-  bmhd->pad1 = bmhd_be->pad1;
-  bmhd->transparentColor = be2short(bmhd_be->transparentColor);
-  bmhd->xAspect = (int)bmhd_be->xAspect;
-  bmhd->yAspect = (int)bmhd_be->yAspect;
-  bmhd->pageWidth = be2short(bmhd_be->pageWidth);
-  bmhd->pageHeight = be2short(bmhd_be->pageHeight);
-
-  return(bmhd);
-}
-
-static unsigned char MSBitFirst2LSBitFirst(unsigned char msb_byte)
-{
-  unsigned char lsb_byte = 0;
-  int i;
-
-  for(i=7;i>=0;i--)
-  {
-    lsb_byte |= (msb_byte & 1) << i;
-    msb_byte >>= 1;
-  }
-
-  return(lsb_byte);
-}
-
-int Read_ILBM_to_Bitmap(Display *display, char *filename, Pixmap *pixmap)
-{
-  Pixmap new_pixmap = 0;
-  int screen = DefaultScreen(display);
-  Drawable root = RootWindow(display,screen);
-  struct IFF_ILBM_FORM_big_endian *form_header;
-  struct IFF_ILBM_BMHD *bitmap_header;
-  unsigned long file_len, body_len;
-  unsigned char *file_data, *bitmap_data;
-  unsigned char *file_ptr, *bitmap_ptr, *body_ptr;
-  unsigned char byte_count, byte_value;
-  int i,x,y,z;
-  int width, height, depth;
-  int bytes_per_line, bitmap_size;
-  FILE *file;
-
-
-
-
-
-  printf("Read_ILBM_to_Bitmap\n");
-
-
-
-
-  if (!(file = fopen(filename,"r")))
-    return(ILBM_OpenFailed);
-
-  if (fseek(file,0,SEEK_END) < 0)
-  {
-    fclose(file);
-    return(ILBM_ReadFailed);
-  }
-
-  file_len = ftell(file);
-  rewind(file);
-
-  if (!(file_data = (unsigned char *)malloc(file_len)))
-  {
-    fclose(file);
-    return(ILBM_NoMemory);
-  }
-
-  if (fread(file_data,1,file_len,file) != file_len)
-  {
-    free(file_data);
-    fclose(file);
-    return(ILBM_ReadFailed);
-  }
-
-  fclose(file);
-
-  form_header = (struct IFF_ILBM_FORM_big_endian *)file_data;
-
-  if (strncmp(form_header->magic_FORM,"FORM",4) ||
-      file_len != be2long(form_header->chunk_size)+8 ||
-      strncmp(form_header->magic_ILBM,"ILBM",4))
-  {
-#ifdef DEBUG_ILBM
-      printf("%s: IFF chunk 'FORM' and/or 'ILBM' not found.\n",filename);
-#endif
-    free(file_data);
-    return(ILBM_FileInvalid);
-  }
-
-  bitmap_header = NULL;
-  body_ptr = NULL;
-  file_ptr = file_data + 12;
-
-  while(file_ptr < (unsigned char *)(file_data + file_len))
-  {
-    if (!strncmp(file_ptr,"BMHD",4))
-    {
-#ifdef DEBUG_ILBM
-      printf("%s: IFF chunk 'BMHD' found.\n",filename);
-#endif
-      bitmap_header = ConvertBMHD(file_ptr + 8);
-      file_ptr += be2long(file_ptr + 4) + 8;
-      continue;
-    }
-    else if (!strncmp(file_ptr,"BODY",4))
-    {
-#ifdef DEBUG_ILBM
-      printf("%s: IFF chunk 'BODY' found.\n",filename);
-#endif
-      body_ptr = file_ptr + 8;
-      body_len = be2long(file_ptr + 4);
-      file_ptr += be2long(file_ptr + 4) + 8;
-      continue;
-    }
-    else
-    {
-#ifdef DEBUG_ILBM
-      printf("%s: IFF chunk '%c%c%c%c' found (but not used).\n",filename,
-            file_ptr[0],file_ptr[1],file_ptr[2],file_ptr[3]);
-#endif
-      /* other chunk not recognized here */
-      file_ptr += be2long(file_ptr + 4) + 8;
-      continue;
-    }
-  }
-
-  if (!bitmap_header || !body_ptr)
-  {
-#ifdef DEBUG_ILBM
-      printf("%s: IFF chunk 'BMHD' and/or 'BODY' not found.\n",filename);
-#endif
-    free(file_data);
-    return(ILBM_FileInvalid);
-  }
-
-  width = bitmap_header->Width;
-  height = bitmap_header->Height;
-  depth = bitmap_header->Depth;
-
-#ifdef DEBUG_ILBM
-  if (depth > 1)
-    printf("%s: %d bitplanes found; using only the first plane.\n",
-          filename,depth);
-#endif
-
-  bytes_per_line = ((width + 15) / 16) * 2;
-  bitmap_size = bytes_per_line * height;
-
-  bitmap_data = (char *)malloc(bitmap_size);
-  if (!bitmap_data)
-  {
-    free(file_data);
-    free(bitmap_header);
-    return(ILBM_NoMemory);
-  }
-
-  bitmap_ptr = bitmap_data;
-  for(i=0;i<bitmap_size;i++)
-    *bitmap_ptr++ = 0;
-
-  for(y=0;y<height;y++)
-  {
-    /* we only read the first bitplane here to create a black/white bitmap */
-
-    for(z=0;z<depth;z++)
-    {
-      bitmap_ptr = bitmap_data + y * bytes_per_line;
-      x = 0;
-
-      if (!bitmap_header->Compression)
-      {
-       while(x++ < bytes_per_line)
-         *bitmap_ptr++ |= MSBitFirst2LSBitFirst(*body_ptr++);
-      }
-      else
-      {
-       while(x < bytes_per_line)
-       {
-         byte_count = *body_ptr++;
-
-         if (byte_count <= 128)
-         {
-           for(i=0;i<byte_count+1;i++)
-             *bitmap_ptr++ |= MSBitFirst2LSBitFirst(*body_ptr++);
-           x += byte_count + 1;
-         }
-         else
-         {
-           byte_value = *body_ptr++;
-           for(i=0;i<257-byte_count;i++)
-             *bitmap_ptr++ |= MSBitFirst2LSBitFirst(byte_value);
-           x += 257 - byte_count;
-         }
-       }
-      }
-    }
-  }
-
-  bitmap_ptr = bitmap_data;
-  for(i=0;i<bitmap_size;i++)
-    *bitmap_ptr++ ^= 0xff;
-
-  new_pixmap = XCreateBitmapFromData(display,root,bitmap_data,width,height);
-
-  free(file_data);
-  free(bitmap_data);
-  free(bitmap_header);
-
-  if (!new_pixmap)
-    return(ILBM_NoMemory);
-
-  *pixmap = new_pixmap;
-  return(ILBM_Success);
-}
diff --git a/src/gfxloader.h b/src/gfxloader.h
deleted file mode 100644 (file)
index d5b2257..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/***********************************************************
-*  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
-*----------------------------------------------------------*
-*  ©1995 Artsoft Development                               *
-*        Holger Schemel                                    *
-*        33659 Bielefeld-Senne                             *
-*        Telefon: (0521) 493245                            *
-*        eMail: aeglos@valinor.owl.de                      *
-*               aeglos@uni-paderborn.de                    *
-*               q99492@pbhrzx.uni-paderborn.de             *
-*----------------------------------------------------------*
-*  gfxloader.h                                             *
-***********************************************************/
-
-#ifndef GFXLOADER_H
-#define GFXLOADER_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-
-#define GIF_Success             0
-#define GIF_OpenFailed         -1
-#define GIF_ReadFailed         -2
-#define        GIF_FileInvalid         -3
-#define GIF_NoMemory           -4
-#define GIF_ColorFailed                -5
-
-#define ILBM_Success            0
-#define ILBM_OpenFailed                -1
-#define ILBM_ReadFailed                -2
-#define        ILBM_FileInvalid        -3
-#define ILBM_NoMemory          -4
-#define ILBM_ColorFailed       -5
-
-int Read_ILBM_to_Bitmap(Display *, char *, Pixmap *);
-int Read_GIF_to_Bitmap(Display *, char *, Pixmap *);
-int Read_GIF_to_Pixmap(Display *, char *, Pixmap *);
-int Read_GIF_to_XImage(Display *, char *, XImage **);
-
-#endif
diff --git a/src/gif.c b/src/gif.c
deleted file mode 100644 (file)
index bf3f5fc..0000000
--- a/src/gif.c
+++ /dev/null
@@ -1,616 +0,0 @@
-
-/* gif.c */
-
-#define GIF_C
-
-#include "gif.h"
-#include "image.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;
-}
-
-Image *Read_GIF_to_Image(char *fullname)
-{
-  FILE *f;
-  Image *image;
-  int x, y, pixel, pass, scanlen;
-  byte *pixptr, *pixline;
-  int errno;
-
-  if (!(f = fopen(fullname,"r")))
-  {
-    perror("gifLoad");
-    return(NULL);
-  }
-
-  if ((gifin_open_file(f) != 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(f);
-    return(NULL);
-  }
-
-
-
-  /*
-  printf("%s:\n   %dx%d %s%s image with %d colors at depth %d\n",
-        fullname, 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),
-        (gifin_l_cmap_flag ? gifin_l_pixel_bits : gifin_g_pixel_bits));
-        */
-
-
-
-  image = newRGBImage(gifin_img_width, gifin_img_height, (gifin_l_cmap_flag ?
-                                                         gifin_l_pixel_bits :
-                                                         gifin_g_pixel_bits));
-
-  /* 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(f);
-
-  return(image);
-}
diff --git a/src/gif.h b/src/gif.h
deleted file mode 100644 (file)
index 89c252f..0000000
--- a/src/gif.h
+++ /dev/null
@@ -1,121 +0,0 @@
-
-/* gif.h:
- *
- * gifin.h
- * kirk johnson
- * november 1989
- * external interface to gifin.c
- *
- * Copyright 1989 Kirk L. Johnson (see the included file
- * "kljcpyrght.h" for complete copyright information)
- */
-
-/*
- * gifin return codes
- */
-#define GIFIN_SUCCESS       0   /* success */
-#define GIFIN_DONE          1   /* no more images */
-
-#define GIFIN_ERR_BAD_SD   -1   /* bad screen descriptor */
-#define GIFIN_ERR_BAD_SEP  -2   /* bad image separator */
-#define GIFIN_ERR_BAD_SIG  -3   /* bad signature */
-#define GIFIN_ERR_EOD      -4   /* unexpected end of raster data */
-#define GIFIN_ERR_EOF      -5   /* unexpected end of input stream */
-#define GIFIN_ERR_FAO      -6   /* file already open */
-#define GIFIN_ERR_IAO      -7   /* image already open */
-#define GIFIN_ERR_NFO      -8   /* no file open */
-#define GIFIN_ERR_NIO      -9   /* no image open */
-#define GIFIN_ERR_PSO      -10  /* pixel stack overflow */
-#define GIFIN_ERR_TAO      -11  /* table overflow */
-#define GIFIN_ERR_BAD_DES  -12  /* bad image descriptor */
-
-#define GIFIN_ERR_BAD_SD_STR   "Bad screen descriptor"
-#define GIFIN_ERR_BAD_SEP_STR  "Bad image separator"
-#define GIFIN_ERR_BAD_SIG_STR  "Bad signature"
-#define GIFIN_ERR_EOD_STR      "Unexpected end of raster data"
-#define GIFIN_ERR_EOF_STR      "Unexpected end of input stream"
-#define GIFIN_ERR_FAO_STR      "File already open"
-#define GIFIN_ERR_IAO_STR      "Image already open"
-#define GIFIN_ERR_NFO_STR      "No file open"
-#define GIFIN_ERR_NIO_STR      "No image open"
-#define GIFIN_ERR_PSO_STR      "Pixel stack overflow"
-#define GIFIN_ERR_TAO_STR      "Table overflow"
-#define GIFIN_ERR_BAD_DES_STR  "Bad image descriptor"
-
-typedef struct {
-    int err_no;
-    char *name;
-    } gif_err_string;
-
-#ifdef GIF_C
-gif_err_string gif_err_strings[] = {
-       {GIFIN_ERR_BAD_SD, GIFIN_ERR_BAD_SD_STR},
-       {GIFIN_ERR_BAD_SEP, GIFIN_ERR_BAD_SEP_STR},
-       {GIFIN_ERR_BAD_SIG, GIFIN_ERR_BAD_SIG_STR},
-       {GIFIN_ERR_EOD, GIFIN_ERR_EOD_STR},
-       {GIFIN_ERR_EOF, GIFIN_ERR_EOF_STR},
-       {GIFIN_ERR_FAO, GIFIN_ERR_FAO_STR},
-       {GIFIN_ERR_IAO, GIFIN_ERR_IAO_STR},
-       {GIFIN_ERR_NFO, GIFIN_ERR_NFO_STR},
-       {GIFIN_ERR_NIO, GIFIN_ERR_NIO_STR},
-       {GIFIN_ERR_PSO, GIFIN_ERR_PSO_STR},
-       {GIFIN_ERR_TAO, GIFIN_ERR_TAO_STR},
-       {GIFIN_ERR_BAD_DES, GIFIN_ERR_BAD_DES_STR},
-       {0}
-    };
-#endif
-
-/*
- * colormap indices 
- */
-
-#define GIF_RED  0
-#define GIF_GRN  1
-#define GIF_BLU  2
-
-/*
- * typedef BYTE for convenience
- */
-
-typedef unsigned char BYTE;
-
-static int gifin_open_file();
-static int gifin_open_image();
-static int gifin_get_pixel();
-#if 0
-static int gifin_close_image();
-#endif
-static int gifin_close_file();
-static int gifin_load_cmap();
-static int gifin_skip_extension();
-static int gifin_read_data_block();
-static int gifin_add_string();
-
-/* #defines, typedefs, and such
- */
-
-#define GIF_SIG      "GIF87a"
-#define GIF_SIG_89   "GIF89a"
-
-#define GIF87a 0                /* Gif file version type */
-#define GIF89a 1                /* Gif file version type */
-
-#define GIF_SIG_LEN  6          /* GIF signature length */
-#define GIF_SD_SIZE  7          /* GIF screen descriptor size */
-#define GIF_ID_SIZE  9          /* GIF image descriptor size */
-
-#define GIF_SEPARATOR   ','     /* GIF image separator */
-#define GIF_EXTENSION   '!'     /* GIF extension block marker */
-#define GIF_TERMINATOR  ';'     /* GIF terminator */
-
-#define STAB_SIZE  4096         /* string table size */
-#define PSTK_SIZE  4096         /* pixel stack size */
-
-#define NULL_CODE  -1           /* string table null code */
-
-#ifdef GIF_C
-char *gif_version_name[] = {
-    GIF_SIG,
-    GIF_SIG_89
-    };
-#endif
diff --git a/src/gifload.c b/src/gifload.c
deleted file mode 100644 (file)
index f7bb514..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-/***********************************************************
-*  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
-*----------------------------------------------------------*
-*  (c) 1995-98 Artsoft Entertainment                       *
-*              Holger Schemel                              *
-*              Oststrasse 11a                              *
-*              33604 Bielefeld                             *
-*              phone: ++49 +521 290471                     *
-*              email: aeglos@valinor.owl.de                *
-*----------------------------------------------------------*
-*  gifload.c                                               *
-***********************************************************/
-
-#ifndef MSDOS
-#include "gifload.h"
-
-#include "image.h"
-
-#endif
diff --git a/src/gifload.h b/src/gifload.h
deleted file mode 100644 (file)
index 1f8cf1c..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-/***********************************************************
-*  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
-*----------------------------------------------------------*
-*  (c) 1995-98 Artsoft Entertainment                       *
-*              Holger Schemel                              *
-*              Oststrasse 11a                              *
-*              33604 Bielefeld                             *
-*              phone: ++49 +521 290471                     *
-*              email: aeglos@valinor.owl.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>
-#endif
-
-#endif
diff --git a/src/msdos.c b/src/msdos.c
deleted file mode 100644 (file)
index 4d2c432..0000000
+++ /dev/null
@@ -1,980 +0,0 @@
-/***********************************************************
-*  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
-*----------------------------------------------------------*
-*  (c) 1995-98 Artsoft Entertainment                       *
-*              Holger Schemel                              *
-*              Oststrasse 11a                              *
-*              33604 Bielefeld                             *
-*              phone: ++49 +521 290471                     *
-*              email: aeglos@valinor.owl.de                *
-*----------------------------------------------------------*
-*  msdos.c                                                 *
-***********************************************************/
-
-#ifdef MSDOS
-#include "main.h"
-#include "tools.h"
-#include "sound.h"
-#include "files.h"
-#include "joystick.h"
-
-DECLARE_GFX_DRIVER_LIST(
-       GFX_DRIVER_VBEAF
-       GFX_DRIVER_VESA2L
-       GFX_DRIVER_VESA1)
-DECLARE_COLOR_DEPTH_LIST(COLOR_DEPTH_8)
-DECLARE_DIGI_DRIVER_LIST(DIGI_DRIVER_SB)
-DECLARE_MIDI_DRIVER_LIST()
-DECLARE_JOYSTICK_DRIVER_LIST(JOYSTICK_DRIVER_STANDARD)
-
-static int key_buffer[OSD_MAX_KEY];
-static XEvent event_buffer[MAX_EVENT_BUFFER];
-static int pending_events;
-static boolean joystick_event;
-static boolean mouse_installed = FALSE;
-static int last_mouse_pos;
-static int last_mouse_b;
-static int last_joystick_state;
-static BITMAP* video_bitmap;
-
-boolean wait_for_vsync;
-
-extern int playing_sounds;
-extern struct SoundControl playlist[MAX_SOUNDS_PLAYING];
-extern struct SoundControl emptySoundControl;
-
-void allegro_drivers()
-{
-  int i;
-
-  for(i = 0; i < MAX_EVENT_BUFFER; i++);
-       event_buffer[i].type = 0;
-  for(i=0; i < OSD_MAX_KEY; i++) key_buffer[i] = KeyReleaseMask;
-  last_mouse_pos = mouse_pos;
-  last_mouse_b = 0;
-
-  pending_events = 0;
-  clear_keybuf();
-
-  i_love_bill = TRUE;
-  install_keyboard();
-  install_timer();
-  if (install_mouse() > 0) mouse_installed = TRUE;
-  install_joystick(JOY_TYPE_2PADS);
-
-  load_joystick_data(JOYDAT_FILE);
-  last_joystick_state = 0;
-  joystick_event = FALSE;
-
-  reserve_voices(MAX_SOUNDS_PLAYING, 0);
-  if(install_sound(DIGI_AUTODETECT, MIDI_NONE, "ROCKS.SND") == -1)
-    if(install_sound(DIGI_SB, MIDI_NONE, NULL) == -1) sound_status = SOUND_OFF;
-
-}
-
-boolean hide_mouse(Display *display, int x, int y,
-                  unsigned int width, unsigned int height)
-{
-  if(mouse_x + display->mouse_ptr->w < x || mouse_x > x+width) return FALSE;
-  if(mouse_y + display->mouse_ptr->h < y || mouse_y > y+height) return FALSE;
-  show_mouse(NULL);
-  return(TRUE);
-}
-
-void unhide_mouse(Display *display)
-{
-  if(mouse_installed) show_mouse(video_bitmap);
-}
-
-int get_joystick_state()
-{
-  int state = 0;
-  poll_joystick();
-
-  if (joy[joystick_nr].stick[0].axis[0].d1) state |= JOY_LEFT;
-  if (joy[joystick_nr].stick[0].axis[0].d2) state |= JOY_RIGHT;
-  if (joy[joystick_nr].stick[0].axis[1].d1) state |= JOY_UP;
-  if (joy[joystick_nr].stick[0].axis[1].d2) state |= JOY_DOWN;
-  if (joy[joystick_nr].button[0].b) state |= JOY_BUTTON_1;
-
-  switch (state)
-  {
-    case (JOY_DOWN | JOY_LEFT):
-       state = XK_KP_1;
-       break;
-    case (JOY_DOWN):
-       state = XK_KP_2;
-       break;
-    case (JOY_DOWN | JOY_RIGHT):
-       state = XK_KP_3;
-       break;
-    case (JOY_LEFT):
-       state = XK_KP_4;
-       break;
-    case (JOY_RIGHT):
-       state = XK_KP_6;
-       break;
-    case (JOY_UP | JOY_LEFT):
-       state = XK_KP_7;
-       break;
-    case (JOY_UP):
-       state = XK_KP_8;
-       break;
-    case (JOY_UP | JOY_RIGHT):
-       state = XK_KP_9;
-       break;
-
-    case (JOY_DOWN | JOY_BUTTON_1):
-       state = XK_X;
-       break;
-    case (JOY_LEFT | JOY_BUTTON_1):
-       state = XK_S;
-       break;
-    case (JOY_RIGHT | JOY_BUTTON_1):
-       state = XK_D;
-       break;
-    case (JOY_UP | JOY_BUTTON_1):
-       state = XK_E;
-       break;
-   default:
-       state = 0;
-  }
-
-  return(state);
-}
-
-unsigned char get_ascii(KeySym key)
-{
-  switch(key) {
-
-       case OSD_KEY_Q: return 'Q';
-       case OSD_KEY_W: return 'W';
-       case OSD_KEY_E: return 'E';
-       case OSD_KEY_R: return 'R';
-       case OSD_KEY_T: return 'T';
-       case OSD_KEY_Y: return 'Y';
-       case OSD_KEY_U: return 'U';
-       case OSD_KEY_I: return 'I';
-       case OSD_KEY_O: return 'O';
-       case OSD_KEY_P: return 'P';
-       case OSD_KEY_A: return 'A';
-       case OSD_KEY_S: return 'S';
-       case OSD_KEY_D: return 'D';
-       case OSD_KEY_F: return 'F';
-       case OSD_KEY_G: return 'G';
-       case OSD_KEY_H: return 'H';
-       case OSD_KEY_J: return 'J';
-       case OSD_KEY_K: return 'K';
-       case OSD_KEY_L: return 'L';
-       case OSD_KEY_Z: return 'Z';
-       case OSD_KEY_X: return 'X';
-       case OSD_KEY_C: return 'C';
-       case OSD_KEY_V: return 'V';
-       case OSD_KEY_B: return 'B';
-       case OSD_KEY_N: return 'N';
-       case OSD_KEY_M: return 'M';
-       case OSD_KEY_1: return '1';
-       case OSD_KEY_2: return '2';
-       case OSD_KEY_3: return '3';
-       case OSD_KEY_4: return '4';
-       case OSD_KEY_5: return '5';
-       case OSD_KEY_6: return '6';
-       case OSD_KEY_7: return '7';
-       case OSD_KEY_8: return '8';
-       case OSD_KEY_9: return '9';
-       case OSD_KEY_0: return '0';
-       case OSD_KEY_SPACE: return ' ';
- }
-  return (0);
-}
-
-long osd_key_pressed(int keycode)
-{
-  if (keycode == OSD_KEY_RCONTROL) keycode = KEY_RCONTROL;
-  if (keycode == OSD_KEY_ALTGR) keycode = KEY_ALTGR;
-
-  if (key[keycode])
-       return(KeyPressMask);
-  else
-       return(KeyReleaseMask);
-}
-
-void XMapWindow(Display* display, Window w)
-{
-  int x, y;
-  unsigned int width, height;
-  boolean mouse_off;
-
-  x = display->screens[display->default_screen].x;
-  y = display->screens[display->default_screen].y;
-  width = display->screens[display->default_screen].width;
-  height = display->screens[display->default_screen].height;
-
-  mouse_off = hide_mouse(display, x, y, width, height);
-  blit((BITMAP *)w, video_bitmap, 0, 0, x, y, width, height);
-  if(mouse_off) unhide_mouse(display);
-}
-
-Display *XOpenDisplay(char* dummy)
-{
-  Screen *MyScreens;
-  Display *MyDisplay;
-  BITMAP *MyMouse = NULL;
-  RGB pal[256];
-
-  MyScreens = malloc(sizeof(Screen));
-  MyDisplay = malloc(sizeof(Display));
-
-  if(MOUSE_FILENAME)
-         MyMouse = load_gif(MOUSE_FILENAME, pal);
-
-  MyScreens[0].cmap = 0;
-  MyScreens[0].root = 0;
-  MyScreens[0].white_pixel = 0xFF;
-  MyScreens[0].black_pixel = 0x00;
-  MyScreens[0].video_bitmap = NULL;
-
-  MyDisplay->default_screen = 0;
-  MyDisplay->screens = MyScreens;
-  MyDisplay->mouse_ptr = MyMouse;
-
-  allegro_init();
-  allegro_drivers();
-  set_color_depth(8);
-  set_gfx_mode(GFX_AUTODETECT, 320, 200, 0, 0); // force Windows 95 to switch to fullscreen mode
-  rest(200);
-  set_gfx_mode(GFX_AUTODETECT, XRES, YRES, 0, 0);
-
-  return(MyDisplay);
-}
-
-Window XCreateSimpleWindow(
-       Display* display,
-       Window parent,
-       int x,
-       int y,
-       unsigned int width,
-       unsigned int height,
-       unsigned int border_width,
-       unsigned long border,
-       unsigned long background)
-{
-  video_bitmap = create_video_bitmap(XRES, YRES);
-  clear_to_color(video_bitmap, background);
-
-  display->screens[display->default_screen].video_bitmap = video_bitmap;
-  display->screens[display->default_screen].x = x;
-  display->screens[display->default_screen].y = y;
-  display->screens[display->default_screen].width = XRES;
-  display->screens[display->default_screen].height = YRES;
-
-  set_mouse_sprite(display->mouse_ptr);
-  set_mouse_range(display->screens[display->default_screen].x+1,
-                 display->screens[display->default_screen].y+1,
-                 display->screens[display->default_screen].x+WIN_XSIZE+1,
-                 display->screens[display->default_screen].y+WIN_YSIZE+1);
-
-  show_video_bitmap(video_bitmap);
-
-  return((Window) video_bitmap);
-}
-
-int XReadBitmapFile(
-       Display* display,
-       Drawable d,
-       char* filename,
-       unsigned int* width_return,
-       unsigned int* height_return,
-       Pixmap* bitmap_return,
-       int* x_hot_return,
-       int* y_hot_return)
-{
-  BITMAP *bmp;
-  RGB pal[256];
-
-  if((bmp = load_gif(filename, pal)) == NULL)
-       return(BitmapOpenFailed);
-
-  *width_return = bmp->w;
-  *height_return = bmp->h;
-  *x_hot_return = -1;
-  *y_hot_return = -1;
-  *bitmap_return = (Pixmap) bmp;
-
-  return(BitmapSuccess);
-}
-
-Status XStringListToTextProperty(char** list, int count, XTextProperty* text_prop_return)
-{
-  char *string;
-
-  if(count >= 1)
-  {
-       string = malloc(strlen(list[0]+1));
-       strcpy(string, list[0]);
-        text_prop_return->value = (unsigned char *) string;
-       return(1);
-  }
-  else
-  {
-        text_prop_return = NULL;
-  }
-    return(0);
-}
-
-void XFree(void* data)
-{
-  if(data) free(data);
-}
-
-GC XCreateGC(Display* display, Drawable d, unsigned long value_mask, XGCValues* values)
-{
-  XGCValues *gcv;
-  gcv = malloc(sizeof(XGCValues));
-  gcv->foreground = values->foreground;
-  gcv->background = values->background;
-  gcv->graphics_exposures = values->graphics_exposures;
-  gcv->clip_mask = values->clip_mask;
-  gcv->clip_x_origin = values->clip_x_origin;
-  gcv->clip_y_origin = values->clip_y_origin;
-  gcv->value_mask = value_mask;
-  return((GC) gcv);
-}
-
-void XFillRectangle(
-       Display* display,
-       Drawable d,
-       GC gc,
-       int x,
-       int y,
-       unsigned int width,
-       unsigned int height)
-{
-  boolean mouse_off;
-
-  if((BITMAP *) d == video_bitmap)
-  {
-       x += display->screens[display->default_screen].x;
-       y += display->screens[display->default_screen].y;
-       freeze_mouse_flag = TRUE;
-       mouse_off = hide_mouse(display, x, y, width, height);
-  }
-
-  rectfill((BITMAP *) d, x, y, x+width, y+height, ((XGCValues *)gc)->foreground);
-  if(mouse_off) unhide_mouse(display);
-  freeze_mouse_flag = FALSE;
-}
-
-Pixmap XCreatePixmap(
-       Display* display,
-       Drawable d,
-       unsigned int width,
-       unsigned int height,
-       unsigned int depth)
-{
-  BITMAP *MyBitmap = NULL;
-
-  if(GFX_HW_VRAM_BLIT&gfx_capabilities && width == FXSIZE && height == FYSIZE)
-    MyBitmap = create_video_bitmap(width, height);
-
-  if(MyBitmap == NULL)
-    MyBitmap = create_bitmap(width, height);
-
-  return((Pixmap) MyBitmap);
-}
-
-inline void XCopyArea(
-       Display* display,
-       Drawable src,
-       Drawable dest,
-       GC gc,
-       int src_x,
-       int src_y,
-       unsigned int width,
-       unsigned int height,
-       int dest_x,
-       int dest_y)
-{
-  boolean mouse_off;
-
-  if((BITMAP *) src == video_bitmap )
-  {
-       src_x += display->screens[display->default_screen].x;
-       src_y += display->screens[display->default_screen].y;
-  }
-  if((BITMAP *) dest == video_bitmap )
-  {
-       dest_x += display->screens[display->default_screen].x;
-       dest_y += display->screens[display->default_screen].y;
-       freeze_mouse_flag = TRUE;
-       mouse_off = hide_mouse(display, dest_x, dest_y, width, height);
-  }
-
-  if(wait_for_vsync)
-  {
-    wait_for_vsync = FALSE;
-    vsync();
-  }
-
-  if(((XGCValues *)gc)->value_mask&GCClipMask)
-    masked_blit((BITMAP *) src, (BITMAP *) dest, src_x, src_y, dest_x, dest_y, width, height);
-  else
-    blit((BITMAP *) src, (BITMAP *) dest, src_x, src_y, dest_x, dest_y, width, height);
-
-  if(mouse_off) unhide_mouse(display);
-  freeze_mouse_flag = FALSE;
-}
-
-int XpmReadFileToPixmap(
-       Display* display,
-       Drawable d,
-       char* filename,
-       Pixmap* pixmap_return,
-       Pixmap* shapemask_return,
-       XpmAttributes* attributes)
-{
-  BITMAP *bmp;
-  RGB pal[256];
-
-  if((bmp = load_gif(filename, pal)) == NULL)
-       return(XpmOpenFailed);
-
-  *pixmap_return = (Pixmap) bmp;
-  set_pallete(pal);
-
-  return(XpmSuccess);
-}
-
-void XFreePixmap(Display* display, Pixmap pixmap)
-{
-  if( pixmap != DUMMY_MASK &&
-     (is_memory_bitmap((BITMAP *) pixmap) || is_screen_bitmap((BITMAP *) pixmap)) )
-         destroy_bitmap((BITMAP *) pixmap);
-}
-
-void XFreeGC(Display* display, GC gc)
-{
-  XGCValues *gcv;
-
-  gcv = (XGCValues *) gc;
-  if(gcv) free(gcv);
-}
-
-void XCloseDisplay(Display* display)
-{
-  BITMAP * bmp;
-  bmp = video_bitmap;
-
-  if(is_screen_bitmap(bmp))
-        destroy_bitmap(bmp);
-  if(display->screens)
-        free(display->screens);
-  if(display)
-        free(display);
-}
-
-void XNextEvent(Display* display, XEvent* event_return)
-{
-  while(!pending_events) XPending(display);
-
-  memcpy(event_return, &event_buffer[pending_events], sizeof(XEvent));
-  pending_events--;
-}
-
-int XPending(Display* display)
-{
-  int i, state;
-  static boolean joy_button_2 = FALSE;
-
-  XKeyEvent *xkey;
-  XButtonEvent *xbutton;
-  XMotionEvent *xmotion;
-
-  // joystick event (simulating keyboard event)
-
-  state = get_joystick_state();
-
-  if (joy[joystick_nr].button[1].b && !joy_button_2)
-  {
-      pending_events++;
-      xkey = (XKeyEvent *) &event_buffer[pending_events];
-      xkey->type = KeyPress;
-      xkey->state = XK_B;
-      joy_button_2 = TRUE;
-  }
-  else if (!joy[joystick_nr].button[1].b && joy_button_2)
-  {
-      pending_events++;
-      xkey = (XKeyEvent *) &event_buffer[pending_events];
-      xkey->type = KeyRelease;
-      xkey->state = XK_B;
-      joy_button_2 = FALSE;
-  }
-
-  if(state && !joystick_event)
-  {
-      pending_events++;
-      xkey = (XKeyEvent *) &event_buffer[pending_events];
-      xkey->type = KeyPress;
-      xkey->state = state;
-      joystick_event = TRUE;
-      last_joystick_state = state;
-  }
-  else if((state != last_joystick_state) && joystick_event)
-  {
-      pending_events++;
-      xkey = (XKeyEvent *) &event_buffer[pending_events];
-      xkey->type = KeyRelease;
-      xkey->state = last_joystick_state;
-      joystick_event = FALSE;
-  }
-
-  // keyboard event
-
-  for(i=0; i < OSD_MAX_KEY+1 && pending_events < MAX_EVENT_BUFFER; i++)
-  {
-    state = osd_key_pressed(i);
-
-    if(state != key_buffer[i])
-    {
-       key_buffer[i] = state;
-       pending_events++;
-       xkey = (XKeyEvent *) &event_buffer[pending_events];
-       xkey->type = state&KeyPressMask ? KeyPress : KeyRelease;
-       xkey->state = i;
-    }
-  }
-
-  // mouse motion event
-
-  if((mouse_pos != last_mouse_pos && mouse_b != last_mouse_b))
-  {
-       last_mouse_pos = mouse_pos;
-       pending_events++;
-        xmotion = (XMotionEvent *) &event_buffer[pending_events];
-        xmotion->type = MotionNotify;
-       xmotion->x = mouse_x - display->screens[display->default_screen].x;
-       xmotion->y = mouse_y - display->screens[display->default_screen].y;
-       return;
-  }
-
-  // mouse button event
-
-  if(mouse_b != last_mouse_b)
-  {
-    for(i = 1; i<4; i<<=1)
-    {
-      if((last_mouse_b&i) != (mouse_b&i))
-      {
-       pending_events++;
-        xbutton = (XButtonEvent *) &event_buffer[pending_events];
-        xbutton->type = mouse_b&i ? ButtonPress : ButtonRelease;
-        xbutton->button = i;
-       xbutton->x = mouse_x - display->screens[display->default_screen].x;
-       xbutton->y = mouse_y - display->screens[display->default_screen].y;
-      }
-    }
-    last_mouse_b = mouse_b;
-  }
-
-  return pending_events;
-}
-
-KeySym XLookupKeysym(XKeyEvent* key_event, int index)
-{
-  return(key_event->state);
-}
-
-void sound_handler(struct SoundControl snd_ctrl)
-{
-    int i;
-
-    if (snd_ctrl.fade_sound)
-    {
-      if (!playing_sounds)
-       return;
-
-      for(i=0;i<MAX_SOUNDS_PLAYING;i++)
-       if ((snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr) && !playlist[i].fade_sound) {
-         playlist[i].fade_sound = TRUE;
-         if(voice_check(playlist[i].voice))
-            voice_ramp_volume(playlist[i].voice, 1000, 0);
-          playlist[i].loop = PSND_NO_LOOP;
-        }
-    }
-    else if (snd_ctrl.stop_all_sounds)
-    {
-      if (!playing_sounds)
-       return;
-      SoundServer_StopAllSounds();
-    }
-    else if (snd_ctrl.stop_sound)
-    {
-      if (!playing_sounds)
-       return;
-      SoundServer_StopSound(snd_ctrl.nr);
-    }
-
-    for(i=0;i<MAX_SOUNDS_PLAYING;i++)
-    {
-      if (!playlist[i].active || playlist[i].loop)
-       continue;
-
-      playlist[i].playingpos = voice_get_position(playlist[i].voice);
-      playlist[i].volume = voice_get_volume(playlist[i].voice);
-      if (playlist[i].playingpos == -1 || !playlist[i].volume)
-      {
-        deallocate_voice(playlist[i].voice);
-        playlist[i] = emptySoundControl;
-       playing_sounds--;
-      }
-    }
-
-    if (snd_ctrl.active)
-      SoundServer_InsertNewSound(snd_ctrl);
-
-}
-
-
-// GIF Loader
-// by Paul Bartrum
-
-int _color_load_depth(int depth);
-
-struct LZW_STRING
-{
-       short base;
-       char new;
-       short length;
-};
-
-PACKFILE *f;
-int empty_string, curr_bit_size, bit_overflow;
-int bit_pos, data_pos, data_len, entire, code;
-int cc, string_length, i, bit_size;
-unsigned char string[4096];
-struct LZW_STRING str[4096];
-BITMAP *bmp;
-int image_x, image_y, image_w, image_h, x, y;
-int interlace;
-
-
-void clear_table(void)
-{
-       empty_string = cc + 2;
-       curr_bit_size = bit_size + 1;
-       bit_overflow = 0;
-}
-
-
-void get_code(void)
-{
-       if(bit_pos + curr_bit_size > 8) {
-               if(data_pos >= data_len) { data_len = pack_getc(f); data_pos = 0; }
-               entire = (pack_getc(f) << 8) + entire;
-               data_pos ++;
-       }
-       if(bit_pos + curr_bit_size > 16) {
-               if(data_pos >= data_len) { data_len = pack_getc(f); data_pos = 0; }
-               entire = (pack_getc(f) << 16) + entire;
-               data_pos ++;
-       }
-       code = (entire >> bit_pos) & ((1 << curr_bit_size) - 1);
-       if(bit_pos + curr_bit_size > 8)
-               entire >>= 8;
-       if(bit_pos + curr_bit_size > 16)
-               entire >>= 8;
-       bit_pos = (bit_pos + curr_bit_size) % 8;
-       if(bit_pos == 0) {
-               if(data_pos >= data_len) { data_len = pack_getc(f); data_pos = 0; }
-               entire = pack_getc(f);
-               data_pos ++;
-       }
-}
-
-
-void get_string(int num)
-{
-       if(num < cc)
-       {
-               string_length = 1;
-               string[0] = str[num].new;
-       }
-       else
-       {
-               i = str[num].length;
-               string_length = i;
-               while(i > 0)
-               {
-                       i --;
-                       string[i] = str[num].new;
-                       num = str[num].base;
-               }
-               /* if(num != -1) **-{[ERROR]}-** */
-       }
-}
-
-
-void output_string(void)
-{
-       for(i = 0; i < string_length; i ++)
-       {
-               putpixel(bmp, x, y, string[i]);
-               x ++;
-               if(x >= image_x + image_w)
-               {
-                       x = image_x;
-                       y += interlace;
-                       if(interlace)
-                       {
-                               if(y >= image_y + image_h)
-                               {
-                                       if(interlace == 8 && (y - image_y) % 8 == 0) {
-                                               interlace = 8;
-                                               y = image_y + 4;
-                                       }
-                                       else if(interlace == 8  && (y - image_y) % 8 == 4) {
-                                               interlace = 4;
-                                               y = image_y + 2;
-                                       }
-                                       else if(interlace == 4) {
-                                               interlace = 2;
-                                               y = image_y + 1;
-                                       }
-                               }
-                       }
-               }
-       }
-}
-
-/* load_gif:
- *  Loads a 2-256 colour GIF file onto a bitmap, returning the bitmap
- *  structure and storing the pallete data in the specified pallete (this
- *  should be an array of at least 256 RGB structures).
- */
-BITMAP *load_gif(char *filename, RGB *pal)
-{
-       int width, height, depth;
-       int old;
-       BITMAP *bmp2;
-       int dest_depth;
-
-       f = pack_fopen(filename, F_READ);
-       if (!f) /* can't open file */
-               return NULL;
-
-       i  = pack_mgetw(f) << 8;
-       i += pack_getc(f);
-       if(i != 0x474946) /* is it really a GIF? */
-       {
-               pack_fclose(f);
-               return NULL;
-       }
-       pack_fseek(f, 3); /* skip version */
-
-       width = pack_igetw(f);
-       height = pack_igetw(f);
-
-       bmp = create_bitmap_ex(8, width, height);
-       if(bmp == NULL) {
-               pack_fclose(f);
-               return NULL;
-       }
-       clear(bmp);
-
-       i = pack_getc(f);
-       if(i & 128) /* no global colour table? */
-               depth = (i & 7) + 1;
-       else
-               depth = 0;
-
-       pack_fseek(f, 2);       /* skip background colour and aspect ratio */
-
-       if(pal && depth) /* only read palette if pal and depth are not 0 */
-       {
-               for(i = 0; i < (1 << depth); i ++)
-               {
-                       pal[i].r = pack_getc(f) / 4;
-                       pal[i].g = pack_getc(f) / 4;
-                       pal[i].b = pack_getc(f) / 4;
-               }
-       }
-       else
-               if(depth)
-                       pack_fseek(f, (1 << depth) * 3);
-
-       do
-       {
-               i = pack_getc(f);
-               switch(i)
-               {
-                       case 0x2C: /* Image Descriptor */
-                               image_x = pack_igetw(f);
-                               image_y = pack_igetw(f); /* individual image dimensions */
-                               image_w = pack_igetw(f);
-                               image_h = pack_igetw(f);
-
-                               i = pack_getc(f);
-                               if(i & 64)
-                                       interlace = 8;
-                               else
-                                       interlace = 1;
-
-                               if(i & 128)
-                               {
-                                       depth = (i & 7) + 1;
-                                       if(pal)
-                                       {
-                                               for(i = 0; i < (1 << depth); i ++)
-                                               {
-                                                       pal[i].r = pack_getc(f) / 4;
-                                                       pal[i].g = pack_getc(f) / 4;
-                                                       pal[i].b = pack_getc(f) / 4;
-                                               }
-                                       }
-                                       else
-                                               pack_fseek(f, (1 << depth) * 3);
-                               }
-
-                               /* lzw stream starts now */
-                               bit_size = pack_getc(f);
-                               cc = 1 << bit_size;
-
-                               /* initialise string table */
-                               for(i = 0; i < cc; i ++)
-                               {
-                                       str[i].base = -1;
-                                       str[i].new = i;
-                                       str[i].length = 1;
-                               }
-
-                               /* initialise the variables */
-                               bit_pos = 0;
-                               data_len = pack_getc(f); data_pos = 0;
-                               entire = pack_getc(f); data_pos ++;
-                               string_length = 0; x = image_x; y = image_y;
-
-                               /* starting code */
-                               clear_table();
-                               get_code();
-                               if(code == cc)
-                                       get_code();
-                               get_string(code);
-                               output_string();
-                               old = code;
-
-                               while(TRUE)
-                               {
-                                       get_code();
-
-                                       if(code == cc)
-                                       {
-                                               /* starting code */
-                                               clear_table();
-                                               get_code();
-                                               get_string(code);
-                                               output_string();
-                                               old = code;
-                                       }
-                                       else if(code == cc + 1)
-                                       {
-                                               break;
-                                       }
-                                       else if(code < empty_string)
-                                       {
-                                               get_string(code);
-                                               output_string();
-
-                                               if(bit_overflow == 0) {
-                                                       str[empty_string].base = old;
-                                                       str[empty_string].new = string[0];
-                                                       str[empty_string].length = str[old].length + 1;
-                                                       empty_string ++;
-                                                       if(empty_string == (1 << curr_bit_size))
-                                                               curr_bit_size ++;
-                                                       if(curr_bit_size == 13) {
-                                                               curr_bit_size = 12;
-                                                               bit_overflow = 1;
-                                                       }
-                                               }
-
-                                               old = code;
-                                       }
-                                       else
-                                       {
-                                               get_string(old);
-                                               string[str[old].length] = string[0];
-                                               string_length ++;
-
-                                               if(bit_overflow == 0) {
-                                                       str[empty_string].base = old;
-                                                       str[empty_string].new = string[0];
-                                                       str[empty_string].length = str[old].length + 1;
-                                                       empty_string ++;
-                                                       if(empty_string == (1 << curr_bit_size))
-                                                               curr_bit_size ++;
-                                                       if(curr_bit_size == 13) {
-                                                               curr_bit_size = 12;
-                                                               bit_overflow = 1;
-                                                       }
-                                               }
-
-                                               output_string();
-                                               old = code;
-                                       }
-                               }
-                               break;
-                       case 0x21: /* Extension Introducer */
-                               i = pack_getc(f);
-                               if(i == 0xF9) /* Graphic Control Extension */
-                               {
-                                       pack_fseek(f, 1); /* skip size (it's 4) */
-                                       i = pack_getc(f);
-                                       if(i & 1) /* is transparency enabled? */
-                                       {
-                                               pack_fseek(f, 2);
-                                               pack_getc(f); /* transparent colour */
-                                       }
-                                       else
-                                               pack_fseek(f, 3);
-                               }
-                               i = pack_getc(f);
-                               while(i) /* skip Data Sub-blocks */
-                               {
-                                       pack_fseek(f, i);
-                                       i = pack_getc(f);
-                               }
-                               break;
-                       case 0x3B: /* Trailer - end of data */
-                               pack_fclose(f);
-
-                               /* convert to correct colour depth */
-                               dest_depth = _color_load_depth(8);
-
-                               if (dest_depth != 8)
-                               {
-                                       bmp2 = create_bitmap_ex(dest_depth, bmp->w, bmp->h);
-                                       if (!bmp2)
-                                       {
-                                               destroy_bitmap(bmp);
-                                               return NULL;
-                                       }
-
-                                       select_palette(pal);
-                                       blit(bmp, bmp2, 0, 0, 0, 0, bmp->w, bmp->h);
-                                       unselect_palette();
-
-                                       destroy_bitmap(bmp);
-                                       bmp = bmp2;
-                               }
-
-                               return bmp;
-               }
-       } while(TRUE);
-
-       /* this is never executed but DJGPP complains if you leave it out */
-       return NULL;
-}
-
-#endif
diff --git a/src/msdos.h b/src/msdos.h
deleted file mode 100644 (file)
index f4f7a5a..0000000
+++ /dev/null
@@ -1,477 +0,0 @@
-/***********************************************************
-*  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
-*----------------------------------------------------------*
-*  (c) 1995-98 Artsoft Entertainment                       *
-*              Holger Schemel                              *
-*              Oststrasse 11a                              *
-*              33604 Bielefeld                             *
-*              phone: ++49 +521 290471                     *
-*              email: aeglos@valinor.owl.de                *
-*----------------------------------------------------------*
-*  msdos.h                                                 *
-***********************************************************/
-
-#ifndef XPM_INCLUDE_FILE
-#define XPM_INCLUDE_FILE
-#endif
-
-#define XRES 800
-#define YRES 600
-
-#define TRUE 1
-#define FALSE 0
-
-#include <allegro.h>
-#include <time.h>
-
-/* some file path definitions */
-
-#define JOYDAT_PATH            GAME_DIR
-#define JOYDAT_FILENAME                "ROCKS.joy"
-#define JOYDAT_FILE            JOYDAT_PATH "/" JOYDAT_FILENAME
-
-/* Allegro keyboard mapping */
-
-#define OSD_KEY_ESC         1        /* keyboard scan codes */
-#define OSD_KEY_1           2        /* (courtesy of allegro.h) */
-#define OSD_KEY_2           3
-#define OSD_KEY_3           4
-#define OSD_KEY_4           5
-#define OSD_KEY_5           6
-#define OSD_KEY_6           7
-#define OSD_KEY_7           8
-#define OSD_KEY_8           9
-#define OSD_KEY_9           10
-#define OSD_KEY_0           11
-#define OSD_KEY_MINUS       12
-#define OSD_KEY_EQUALS      13
-#define OSD_KEY_BACKSPACE   14
-#define OSD_KEY_TAB         15
-#define OSD_KEY_Q           16
-#define OSD_KEY_W           17
-#define OSD_KEY_E           18
-#define OSD_KEY_R           19
-#define OSD_KEY_T           20
-#define OSD_KEY_Y           21
-#define OSD_KEY_U           22
-#define OSD_KEY_I           23
-#define OSD_KEY_O           24
-#define OSD_KEY_P           25
-#define OSD_KEY_OPENBRACE   26
-#define OSD_KEY_CLOSEBRACE  27
-#define OSD_KEY_ENTER       28
-#define OSD_KEY_LCONTROL    29
-#define OSD_KEY_A           30
-#define OSD_KEY_S           31
-#define OSD_KEY_D           32
-#define OSD_KEY_F           33
-#define OSD_KEY_G           34
-#define OSD_KEY_H           35
-#define OSD_KEY_J           36
-#define OSD_KEY_K           37
-#define OSD_KEY_L           38
-#define OSD_KEY_COLON       39
-#define OSD_KEY_QUOTE       40
-#define OSD_KEY_TILDE       41
-#define OSD_KEY_LSHIFT      42
-/* 43 */
-#define OSD_KEY_Z           44
-#define OSD_KEY_X           45
-#define OSD_KEY_C           46
-#define OSD_KEY_V           47
-#define OSD_KEY_B           48
-#define OSD_KEY_N           49
-#define OSD_KEY_M           50
-#define OSD_KEY_COMMA       51
-#define OSD_KEY_STOP        52
-#define OSD_KEY_SLASH       53
-#define OSD_KEY_RSHIFT      54
-#define OSD_KEY_ASTERISK    55
-#define OSD_KEY_ALT         56
-#define OSD_KEY_SPACE       57
-#define OSD_KEY_CAPSLOCK    58
-#define OSD_KEY_F1          59
-#define OSD_KEY_F2          60
-#define OSD_KEY_F3          61
-#define OSD_KEY_F4          62
-#define OSD_KEY_F5          63
-#define OSD_KEY_F6          64
-#define OSD_KEY_F7          65
-#define OSD_KEY_F8          66
-#define OSD_KEY_F9          67
-#define OSD_KEY_F10         68
-#define OSD_KEY_NUMLOCK     69
-#define OSD_KEY_SCRLOCK     70
-#define OSD_KEY_HOME        71
-#define OSD_KEY_UP          72
-#define OSD_KEY_PGUP        73
-#define OSD_KEY_MINUS_PAD   74
-#define OSD_KEY_LEFT        75
-#define OSD_KEY_5_PAD       76
-#define OSD_KEY_RIGHT       77
-#define OSD_KEY_PLUS_PAD    78
-#define OSD_KEY_END         79
-#define OSD_KEY_DOWN        80
-#define OSD_KEY_PGDN        81
-#define OSD_KEY_INSERT      82
-#define OSD_KEY_DEL         83
-#define OSD_KEY_RCONTROL    84  /* different from Allegro */
-#define OSD_KEY_ALTGR       85  /* different from Allegro */
-/* 86 */
-#define OSD_KEY_F11         87
-#define OSD_KEY_F12         88
-#define OSD_KEY_COMMAND     89
-#define OSD_KEY_OPTION      90
-/* 91 - 100 */
-/* The following are all undefined in Allegro */
-#define OSD_KEY_1_PAD          101
-#define OSD_KEY_2_PAD          102
-#define OSD_KEY_3_PAD          103
-#define OSD_KEY_4_PAD          104
-/* 105 */
-#define OSD_KEY_6_PAD          106
-#define OSD_KEY_7_PAD          107
-#define OSD_KEY_8_PAD          108
-#define OSD_KEY_9_PAD          109
-#define OSD_KEY_0_PAD          110
-#define OSD_KEY_STOP_PAD       111
-#define OSD_KEY_EQUALS_PAD     112
-#define OSD_KEY_SLASH_PAD      113
-#define OSD_KEY_ASTER_PAD      114
-#define OSD_KEY_ENTER_PAD      115
-
-#define OSD_MAX_KEY         115
-
-/* X11 keyboard mapping */
-
-#define XK_KP_Enter    OSD_KEY_ENTER_PAD
-#define XK_KP_0                OSD_KEY_0_PAD
-#define XK_KP_1                OSD_KEY_1_PAD
-#define XK_KP_2                OSD_KEY_2_PAD
-#define XK_KP_3                OSD_KEY_3_PAD
-#define XK_KP_4                OSD_KEY_4_PAD
-#define XK_KP_6                OSD_KEY_6_PAD
-#define XK_KP_7                OSD_KEY_7_PAD
-#define XK_KP_8                OSD_KEY_8_PAD
-#define XK_KP_9                OSD_KEY_9_PAD
-/*
-#define XK_KP_Home     OSD_KEY_7_PAD
-#define XK_KP_Page_Up  OSD_KEY_9_PAD
-#define XK_KP_Page_Down        OSD_KEY_3_PAD
-#define XK_KP_End      OSD_KEY_1_PAD
-#define XK_KP_Left     OSD_KEY_4_PAD   
-#define XK_KP_Up       OSD_KEY_8_PAD
-#define XK_KP_Right    OSD_KEY_6_PAD
-#define XK_KP_Down     OSD_KEY_2_PAD
-*/
-#define XK_0           OSD_KEY_1
-#define XK_1           OSD_KEY_2
-#define XK_2           OSD_KEY_3
-#define XK_3           OSD_KEY_4
-#define XK_4           OSD_KEY_5
-#define XK_5           OSD_KEY_6
-#define XK_6           OSD_KEY_7
-#define XK_7           OSD_KEY_8
-#define XK_8           OSD_KEY_9
-#define XK_9           OSD_KEY_0
-#define XK_A           OSD_KEY_A
-#define XK_B           OSD_KEY_B
-#define XK_C           OSD_KEY_C
-#define XK_D           OSD_KEY_D
-#define XK_E           OSD_KEY_E
-#define XK_F           OSD_KEY_F
-#define XK_G           OSD_KEY_G
-#define XK_H           OSD_KEY_H
-#define XK_I           OSD_KEY_I
-#define XK_J           OSD_KEY_J
-#define XK_K           OSD_KEY_K
-#define XK_L           OSD_KEY_L
-#define XK_M           OSD_KEY_M
-#define XK_N           OSD_KEY_N
-#define XK_O           OSD_KEY_O
-#define XK_P           OSD_KEY_P
-#define XK_Q           OSD_KEY_Q
-#define XK_R           OSD_KEY_R
-#define XK_S           OSD_KEY_S
-#define XK_T           OSD_KEY_T
-#define XK_U           OSD_KEY_U
-#define XK_V           OSD_KEY_V
-#define XK_W           OSD_KEY_W
-#define XK_X           OSD_KEY_X
-#define XK_Y           OSD_KEY_Y
-#define XK_Z           OSD_KEY_Z
-#define XK_a           OSD_KEY_A
-#define XK_b           OSD_KEY_B
-#define XK_c           OSD_KEY_C
-#define XK_d           OSD_KEY_D
-#define XK_e           OSD_KEY_E
-#define XK_f           OSD_KEY_F
-#define XK_g           OSD_KEY_G
-#define XK_h           OSD_KEY_H
-#define XK_i           OSD_KEY_I
-#define XK_j           OSD_KEY_J
-#define XK_k           OSD_KEY_K
-#define XK_l           OSD_KEY_L
-#define XK_m           OSD_KEY_M
-#define XK_n           OSD_KEY_N
-#define XK_o           OSD_KEY_O
-#define XK_p           OSD_KEY_P
-#define XK_q           OSD_KEY_Q
-#define XK_r           OSD_KEY_R
-#define XK_s           OSD_KEY_S
-#define XK_t           OSD_KEY_T
-#define XK_u           OSD_KEY_U
-#define XK_v           OSD_KEY_V
-#define XK_w           OSD_KEY_W
-#define XK_x           OSD_KEY_X
-#define XK_y           OSD_KEY_Y
-#define XK_z           OSD_KEY_Z
-#define XK_Return      OSD_KEY_ENTER
-#define XK_Escape      OSD_KEY_ESC
-#define XK_Shift_L     OSD_KEY_LSHIFT
-#define XK_Shift_R     OSD_KEY_RSHIFT
-#define XK_Left                OSD_KEY_LEFT    
-#define XK_Up          OSD_KEY_UP
-#define XK_Right       OSD_KEY_RIGHT
-#define XK_Down                OSD_KEY_DOWN
-#define XK_BackSpace   OSD_KEY_BACKSPACE
-#define XK_Delete      OSD_KEY_DEL
-#define XK_Space       OSD_KEY_SPACE
-#define XK_F12         OSD_KEY_F12
-#define XK_F11         OSD_KEY_F11
-#define XK_F10         OSD_KEY_F10
-
-#define MOUSE_FILENAME "graphics\\mouse.gif"
-#define screen myscreen
-
-#define XFlush(a)
-#define XSync(a,b)
-#define XSetClipOrigin(a,b,c,d)
-#define XGetImage(a,b,c,d,e,f,g,h)             ((XImage *) NULL)
-#define XAutoRepeatOn(a)
-#define XAutoRepeatOff(a)
-#define XDisplayName(a)                                ((char *) NULL)
-#define XFreeColors(a,b,c,d,e)
-#define XpmFreeAttributes(a)
-#define XSelectInput(a,b,c)
-#define XDefaultDepth(a,b)                     (8)
-#define XSetWMProperties(a,b,c,d,e,f,g,h,i)
-
-#define MAX_EVENT_BUFFER 256
-
-#define Status int
-#define Bool int
-#define True 1
-#define False 0
-
-#define DUMMY_FILE (void*) -1
-#define DUMMY_MASK -1
-
-#define KeyPressMask                   (1L<<0)  
-#define KeyReleaseMask                 (1L<<1)  
-#define ButtonPressMask                        (1L<<2)  
-#define ButtonReleaseMask              (1L<<3)  
-#define ButtonMotionMask               (1L<<13) 
-#define ExposureMask                   (1L<<15) 
-#define StructureNotifyMask            (1L<<17) 
-#define FocusChangeMask                        (1L<<21) 
-
-#define KeyPress               2
-#define KeyRelease             3
-#define ButtonPress            4
-#define ButtonRelease          5
-#define MotionNotify           6
-#define FocusIn                        9
-#define FocusOut               10
-#define Expose                 12
-#define UnmapNotify            18
-#define MapNotify              19
-
-#define GCForeground            (1L<<2)
-#define GCBackground            (1L<<3)
-#define GCGraphicsExposures     (1L<<16)
-#define GCClipMask             (1L<<19)
-
-#define NormalState 1  /* most applications want to start this way */
-#define InputHint              (1L << 0)
-#define StateHint              (1L << 1)
-#define IconPixmapHint         (1L << 2)
-#define IconMaskHint           (1L << 5)
-#define PSize          (1L << 3) /* program specified size */
-#define PMinSize       (1L << 4) /* program specified minimum size */
-#define PMaxSize       (1L << 5) /* program specified maximum size */
-
-#define XpmSuccess       0
-#define XpmOpenFailed   -1
-#define XpmFileInvalid  -2
-#define XpmNoMemory     -3
-#define XpmColorFailed  -4
-#define XpmCloseness      (1L<<12)
-
-#define BitmapSuccess          0
-#define BitmapOpenFailed       1
-#define BitmapFileInvalid      2
-#define BitmapNoMemory         3
-
-#define ZPixmap                        2       /* depth == drawable depth */
-
-#define DefaultScreen(dpy)     (((_XPrivDisplay)dpy)->default_screen)
-#define DefaultColormap(dpy, scr)(ScreenOfDisplay(dpy,scr)->cmap)
-#define ScreenOfDisplay(dpy, scr)(&((_XPrivDisplay)dpy)->screens[scr])
-#define BlackPixel(dpy, scr)   (ScreenOfDisplay(dpy,scr)->black_pixel)
-#define WhitePixel(dpy, scr)   (ScreenOfDisplay(dpy,scr)->white_pixel)
-#define RootWindow(dpy, scr)   (ScreenOfDisplay(dpy,scr)->root)
-#define AllPlanes              ((unsigned long)~0L)
-
-#define XGetPixel(ximage, x, y) \
-       ((*((ximage)->f.get_pixel))((ximage), (x), (y)))
-
-typedef unsigned long Pixel;   /* Index into colormap */
-typedef unsigned long XID;
-typedef XID Window;
-typedef XID Drawable;
-typedef XID Pixmap;
-typedef XID Colormap;
-typedef XID KeySym;
-typedef XID GContext;
-typedef struct _XDisplay Display;
-
-typedef struct _XGC
-{
-    GContext gid;      /* protocol ID for graphics context */
-} *GC;
-
-typedef struct {
-       Colormap cmap;          /* default color map */
-       Window root;            /* Root window id. */
-       unsigned long white_pixel;
-       unsigned long black_pixel;      /* White and Black pixel values */
-       int x;
-       int y;
-       unsigned int width;
-       unsigned int height;
-       BITMAP *video_bitmap;
-} Screen;
-
-typedef struct _XDisplay
-{
-       int default_screen;     /* default screen for operations */
-       Screen *screens;        /* pointer to list of screens */
-       BITMAP *mouse_ptr;
-} *_XPrivDisplay;
-
-typedef struct _XImage {
-    struct funcs {
-       unsigned long (*get_pixel)  (struct _XImage *, int, int);
-    } f;
-} XImage;
-
-typedef struct {
-       long flags;     /* marks which fields in this structure are defined */
-       int width, height;      /* should set so old wm's don't mess up */
-       int min_width, min_height;
-       int max_width, max_height;
-} XSizeHints;
-
-typedef struct {
-       long flags;     /* marks which fields in this structure are defined */
-       Bool input;     /* does this application rely on the window manager to
-                       get keyboard input? */
-       int initial_state;      /* see below */
-       Pixmap icon_pixmap;     /* pixmap to be used as icon */
-       Pixmap icon_mask;       /* icon mask bitmap */
-} XWMHints;
-
-typedef struct {
-       char *res_name;
-       char *res_class;
-} XClassHint;
-
-typedef struct {
-    unsigned char *value;              /* same as Property routines */
-} XTextProperty;
-
-typedef struct {
-       unsigned long foreground;/* foreground pixel */
-       unsigned long background;/* background pixel */
-       Bool graphics_exposures;/* boolean, should exposures be generated */
-       Pixmap clip_mask;       /* bitmap clipping; other calls for rects */
-       int clip_x_origin;      /* origin for clipping */
-       int clip_y_origin;
-       unsigned long value_mask;
-} XGCValues;
-
-typedef struct {
-    unsigned long valuemask;           /* Specifies which attributes are */
-    unsigned int closeness;            /* Allowable RGB deviation */
-    Pixel *pixels;                     /* List of used color pixels */
-    unsigned int npixels;              /* Number of used pixels */
-} XpmAttributes;
-
-typedef struct {
-       int type;
-       int x, y;
-       int width, height;
-} XExposeEvent;
-
-typedef struct {
-       int type;               /* of event */
-       int x, y;               /* pointer x, y coordinates in event window */
-       unsigned int button;    /* detail */
-} XButtonEvent;
-
-typedef struct {
-       int type;
-       int x, y;               /* pointer x, y coordinates in event window */
-} XMotionEvent;
-
-typedef struct {
-       int type;               /* of event */
-       unsigned int state;     /* key or button mask */
-} XKeyEvent;
-
-typedef struct {
-       int type;               /* FocusIn or FocusOut */
-} XFocusChangeEvent;
-
-
-typedef union _XEvent {
-        int type;              /* must not be changed; first element */
-       XExposeEvent xexpose;
-       XButtonEvent xbutton;
-       XMotionEvent xmotion;
-       XKeyEvent xkey;
-} XEvent;
-
-
-extern void XMapWindow(Display*, Window);
-// extern void XFlush(Display*);
-extern Display *XOpenDisplay(char*);
-// extern char *XDisplayName(char*);
-extern Window XCreateSimpleWindow(Display*, Window, int, int, unsigned int, unsigned int, unsigned int, unsigned long, unsigned long);
-extern int XReadBitmapFile(Display*, Drawable, char*, unsigned int*, unsigned int*, Pixmap*, int*, int*);
-extern Status XStringListToTextProperty(char**, int, XTextProperty*);
-// extern void XSetWMProperties(Display*, Window, XTextProperty*, XTextProperty*, char**, int, XSizeHints*, XWMHints*, XClassHint*);
-extern void XFree(void*);
-// extern void XSelectInput(Display*, Window, long);
-extern GC XCreateGC(Display*, Drawable, unsigned long, XGCValues*);
-extern void XFillRectangle(Display*, Drawable, GC, int, int, unsigned int, unsigned int);
-extern Pixmap XCreatePixmap(Display*, Drawable, unsigned int, unsigned int, unsigned int);
-// extern int XDefaultDepth(Display*, int);
-extern inline void XCopyArea(Display*, Drawable, Drawable, GC, int, int, unsigned int, unsigned int, int, int);
-extern int XpmReadFileToPixmap(Display*, Drawable, char*, Pixmap*, Pixmap*, XpmAttributes*);
-// extern void XFreeColors(Display*, Colormap, unsigned long*, int, unsigned long);
-// extern void XpmFreeAttributes(XpmAttributes*);
-extern void XFreePixmap(Display*, Pixmap);
-extern void XFreeGC(Display*, GC);
-extern void XCloseDisplay(Display*);
-extern int XPending(Display*);
-extern void XNextEvent(Display*, XEvent*);
-// extern void XSync(Display*, Bool);
-// extern void XAutoRepeatOn(Display*);
-// extern void XAutoRepeatOff(Display*);
-extern KeySym XLookupKeysym(XKeyEvent*, int);
-// extern void XSetClipOrigin(Display*, GC, int, int);
-// extern XImage *XGetImage(Display*, Drawable, int, int, unsigned int, unsigned int, unsigned long, int);
-
-BITMAP *load_gif(char *filename, RGB *pal);
diff --git a/src/netserv.c b/src/netserv.c
new file mode 100644 (file)
index 0000000..6ff6e52
--- /dev/null
@@ -0,0 +1,904 @@
+/*
+ *   A server for a multi-player version of Tetris
+ *
+ *   Copyright (C) 1996 Roger Espel Llima <roger.espel.llima@pobox.com>
+ *
+ *   Started: 10 Oct 1996
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation. See the file COPYING for details.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <string.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include "netserv.h"
+#include "misc.h"
+
+static int clients = 0;
+static int bots = 0;
+static int onceonly = 0;
+static int timetoplay = 0;
+static int is_daemon = 0;
+static int levelnr = 5;
+static int mode = -1;
+static int paused = 0;
+
+struct user
+{
+  int fd;
+  unsigned char nick[16];
+  unsigned char number;
+  struct user *next, *nextvictim;
+  char active;
+  char introduced;
+  unsigned char readbuf[MAX_BUFFER_SIZE];
+  int nread;
+  unsigned char writbuf[MAX_BUFFER_SIZE];
+  int nwrite;
+  char playing;
+  char isbot;
+  int lines;
+  unsigned int games;
+  unsigned char action;
+  int action_received;
+};
+
+static struct user *user0 = NULL;
+
+#define NEXT(u) ((u)->next ? (u)->next : user0)
+
+static struct sockaddr_in saddr;
+static int lfd;
+static unsigned char realbuf[512], *buf = realbuf + 4;
+
+static int interrupt;
+static int tcp = -1;
+
+static unsigned long frame_counter = 0;
+
+static fd_set fds;
+
+static void syserr(char *s)
+{
+  if (!is_daemon)
+    fprintf(stderr, "fatal: %s failed.\n", s);
+  exit(1);
+}
+
+static void addtobuffer(struct user *u, unsigned char *b, int len)
+{
+  if (u->nwrite + len >= MAX_BUFFER_SIZE)
+    Error(ERR_EXIT, "internal error: network send buffer overflow");
+
+  memcpy(u->writbuf + u->nwrite, b, len);
+  u->nwrite += len;
+}
+
+static void flushuser(struct user *u)
+{
+  if (u->nwrite)
+  {
+    write(u->fd, u->writbuf, u->nwrite);
+    u->nwrite = 0;
+  }
+}
+
+static void broadcast(struct user *except, int len, int activeonly)
+{
+  struct user *u;
+
+  realbuf[0] = realbuf[1] = realbuf[2] = 0;
+  realbuf[3] = (unsigned char)len;
+  for (u=user0; u; u=u->next)
+    if (u != except && (u->active || !activeonly) && u->introduced)
+      addtobuffer(u, realbuf, 4 + len);
+}
+
+static void sendtoone(struct user *to, int len)
+{
+  realbuf[0] = realbuf[1] = realbuf[2] = 0;
+  realbuf[3] = (unsigned char)len;
+  addtobuffer(to, realbuf, 4 + len);
+}
+
+static void dropuser(struct user *u)
+{
+  struct user *v, *w;
+  
+  if (options.verbose)
+    printf("RND_SERVER: dropping client %d (%s)\n", u->number, u->nick);
+
+  if (u == user0)
+    user0 = u->next;
+  else
+  {
+    for (v=user0; v; v=v->next)
+    {
+      if (v->next && v->next == u)
+      {
+       v->next = u->next;
+       break;
+      }
+    }
+  }
+  close(u->fd);
+
+  if (u->introduced)
+  {
+    buf[0] = u->number;
+    buf[1] = OP_PLAYER_DISCONNECTED;
+    broadcast(u, 2, 0);
+  }
+
+  for (v=user0; v; v=v->next)
+  {
+    if (v->nextvictim == u)
+    {
+      for (w=NEXT(v); w!=v; w=NEXT(w))
+      {
+       if (w->active && w->playing)
+       {
+         v->nextvictim = w;
+         break;
+       }
+      }
+      if (v->nextvictim == u)
+       v->nextvictim = NULL;
+    }
+  }
+
+  if (u->isbot)
+    bots--;
+
+  free(u);
+  clients--;
+
+  if (onceonly && clients == bots)
+  {
+    if (options.verbose)
+    {
+      printf("RND_SERVER: no clients left\n");
+      printf("RND_SERVER: aborting\n");
+    }
+    exit(0);
+  }
+
+  if (clients == 0)
+  {
+    mode = -1;
+    levelnr = 5;
+    timetoplay = 0;
+  }
+}
+
+static void new_connect(int fd)
+{
+  struct user *u, *v;
+  unsigned char nxn;
+
+  u = checked_malloc(sizeof (struct user));
+
+  u->fd = fd;
+  u->nick[0] = 0;
+  u->next = user0;
+  u->nextvictim = NULL;
+  u->active = 0;
+  u->nread = 0;
+  u->nwrite = 0;
+  u->playing = 0;
+  u->isbot = 0;
+  u->introduced = 0;
+  u->games = 0;
+  u->action = 0;
+  u->action_received = 0;
+
+  user0 = u;
+
+  nxn = 1;
+
+ again:
+  v = u->next;
+  while(v)
+  {
+    if (v->number == nxn)
+    {
+      nxn++;
+      goto again;
+    }
+    v = v->next;
+  }
+
+  u->number = nxn;
+  if (options.verbose)
+    printf("RND_SERVER: client %d connecting from %s\n", nxn, inet_ntoa(saddr.sin_addr));
+  clients++;
+
+  buf[0] = 0;
+  buf[1] = OP_YOUR_NUMBER;
+  buf[2] = u->number;
+  sendtoone(u, 3);
+}
+
+static void Handle_OP_PROTOCOL_VERSION(struct user *u, unsigned int len)
+{
+  if (len != 5 || buf[2] != PROT_VERS_1 || buf[3] != PROT_VERS_2)
+  {
+    if (options.verbose)
+      printf("RND_SERVER: client %d (%s) has wrong protocol version %d.%d.%d\n", u->number, u->nick, buf[2], buf[3], buf[4]);
+
+    buf[0] = 0;
+    buf[1] = OP_BADVERS;
+    buf[2] = PROT_VERS_1;
+    buf[3] = PROT_VERS_2;
+    buf[4] = PROT_VERS_3;
+    sendtoone(u, 5);
+    flushuser(u);
+
+    dropuser(u);
+    interrupt = 1;
+  }
+  else
+  {
+    if (options.verbose)
+      printf("RND_SERVER: client %d (%s) uses protocol version %d.%d.%d\n", u->number, u->nick, buf[2], buf[3], buf[4]);
+  }
+}
+
+static void Handle_OP_NUMBER_WANTED(struct user *u)
+{
+  struct user *v;
+  int client_nr = u->number;
+  int nr_wanted = buf[2];
+  int nr_is_free = 1;
+
+  if (options.verbose)
+    printf("RND_SERVER: client %d (%s) wants to switch to # %d\n",
+          u->number, u->nick, nr_wanted);
+
+  for (v=user0; v; v=v->next)
+  {
+    if (v->number == nr_wanted)
+    {
+      nr_is_free = 0;
+      break;
+    }
+  }
+
+  if (options.verbose)
+  {
+    if (nr_is_free)
+      printf("RND_SERVER: client %d (%s) switches to # %d\n",
+            u->number, u->nick, nr_wanted);
+    else if (u->number == nr_wanted)
+      printf("RND_SERVER: client %d (%s) still has # %d\n",
+            u->number, u->nick, nr_wanted);
+    else
+      printf("RND_SERVER: client %d (%s) cannot switch (client %d still exists)\n",
+            u->number, u->nick, nr_wanted);
+  }
+
+  if (nr_is_free)
+    u->number = nr_wanted;
+
+  buf[0] = client_nr;
+  buf[1] = OP_NUMBER_WANTED;
+  buf[2] = nr_wanted;
+  buf[3] = u->number;
+
+  /*
+  sendtoone(u, 4);
+  */
+
+  broadcast(NULL, 4, 0);
+}
+
+static void Handle_OP_NICKNAME(struct user *u, unsigned int len)
+{
+  struct user *v;
+  int i;
+
+  if (len>16)
+    len=16;
+  memcpy(u->nick, &buf[2], len-2);
+  u->nick[len-2] = 0;
+  for (i=0; i<len-2; i++)
+  {
+    if (u->nick[i] < ' ' || 
+       (u->nick[i] > 0x7e && u->nick[i] <= 0xa0))
+    {
+      u->nick[i] = 0;
+      break;
+    }
+  }
+
+  if (!u->introduced)
+  {
+    buf[0] = u->number;
+    buf[1] = OP_PLAYER_CONNECTED;
+    broadcast(u, 2, 0);
+  }
+             
+  if (options.verbose)
+    printf("RND_SERVER: client %d calls itself \"%s\"\n", u->number, u->nick);
+  buf[1] = OP_NICKNAME;
+  broadcast(u, len, 0);
+
+  if (!u->introduced)
+  {
+    for (v=user0; v; v=v->next)
+    {
+      if (v != u && v->introduced)
+      {
+       buf[0] = v->number;
+       buf[1] = OP_PLAYER_CONNECTED;
+       buf[2] = (v->games >> 8);
+       buf[3] = (v->games & 0xff);
+       sendtoone(u, 4);
+       buf[1] = OP_NICKNAME;
+       memcpy(&buf[2], v->nick, 14);
+       sendtoone(u, 2+strlen(v->nick));
+      }
+    }
+    if (levelnr != 5)
+    {
+      buf[0] = 0;
+      buf[1] = OP_LEVEL;
+      buf[2] = levelnr;
+      sendtoone(u, 3);
+    }
+    if (mode >= 0)
+    {
+      buf[1] = OP_MODE;
+      buf[2] = mode;
+      sendtoone(u, 3);
+    }
+  }
+
+  u->introduced = 1;
+}
+
+static void Handle_OP_START_PLAYING(struct user *u)
+{
+  struct user *v, *w;
+
+  if (options.verbose)
+    printf("RND_SERVER: client %d (%s) starts game [level %d from levedir %d (%s)]\n",
+          u->number, u->nick,
+          (buf[2] << 8) + buf[3],
+          (buf[4] << 8) + buf[5],
+          &buf[6]);
+  timetoplay = 0;
+
+  for (w=user0; w; w=w->next)
+  {
+    if (w->introduced)
+    {
+      w->active = 1;
+      w->playing = 1;
+      w->lines = 0;
+      w->nextvictim = NULL;
+      for (v=NEXT(w); v!=w; v=NEXT(v))
+      {
+       if (v->introduced)
+       {
+         w->nextvictim = v;
+         break;
+       }
+      }
+    }
+  }
+
+  /*
+  if (paused)
+  {
+    paused = 0;
+    buf[1] = OP_CONT;
+    broadcast(NULL, 2, 0);
+  }
+  buf[1] = OP_START_PLAYING;
+  broadcast(NULL, 2, 0);
+  */
+
+  /* reset frame counter */
+  frame_counter = 0;
+
+  /* reset player actions */
+  for (v=user0; v; v=v->next)
+  {
+    v->action = 0;
+    v->action_received = 0;
+  }
+
+  broadcast(NULL, 10 + strlen(&buf[10])+1, 0);
+}
+
+static void Handle_OP_PAUSE_PLAYING(struct user *u)
+{
+  if (options.verbose)
+    printf("RND_SERVER: client %d (%s) pauses game\n", u->number, u->nick);
+  broadcast(NULL, 2, 0);
+  paused = 1;
+}
+
+static void Handle_OP_CONTINUE_PLAYING(struct user *u)
+{
+  if (options.verbose)
+    printf("RND_SERVER: client %d (%s) continues game\n", u->number, u->nick);
+  broadcast(NULL, 2, 0);
+  paused = 0;
+}
+
+static void Handle_OP_STOP_PLAYING(struct user *u)
+{
+  if (options.verbose)
+    printf("RND_SERVER: client %d (%s) stops game\n", u->number, u->nick);
+  broadcast(NULL, 2, 0);
+}
+
+static void Handle_OP_MOVE_FIGURE(struct user *u)
+{
+  struct user *v;
+  int last_client_nr = 0;
+  int i;
+
+  /* store player action */
+  for (v=user0; v; v=v->next)
+  {
+    if (v->number == u->number)
+    {
+      v->action = buf[2];
+      v->action_received = 1;
+    }
+  }
+
+  /* check if server received action from each player */
+  for (v=user0; v; v=v->next)
+  {
+    if (!v->action_received)
+      return;
+
+    if (v->number > last_client_nr)
+      last_client_nr = v->number;
+  }
+
+  /* initialize all player actions to zero */
+  for (i=0; i<last_client_nr; i++)
+    buf[6 + i] = 0;
+
+  /* broadcast actions of all players to all players */
+  for (v=user0; v; v=v->next)
+  {
+    buf[6 + v->number-1] = v->action;
+    v->action = 0;
+    v->action_received = 0;
+  }
+
+  buf[2] = (unsigned char)((frame_counter >> 24) & 0xff);
+  buf[3] = (unsigned char)((frame_counter >> 16) & 0xff);
+  buf[4] = (unsigned char)((frame_counter >>  8) & 0xff);
+  buf[5] = (unsigned char)((frame_counter >>  0) & 0xff);
+
+  broadcast(NULL, 6 + last_client_nr, 0);
+
+  frame_counter++;
+
+  /*
+    if (verbose)
+    printf("RND_SERVER: frame %d: client %d (%s) moves player [0x%02x]\n",
+    frame_counter,
+    u->number, u->nick, buf[2]);
+  */
+}
+
+void NetworkServer(int port, int serveronly)
+{
+  int i, sl, on;
+  struct user *u, *v, *w;
+  int mfd;
+  int r; 
+  unsigned int len;
+  struct protoent *tcpproto;
+  struct timeval tv;
+  int is_daemon = 0;
+
+#ifndef NeXT
+  struct sigaction sact;
+#endif
+
+  if (port == 0)
+    port = DEFAULTPORT;
+
+  if (!serveronly)
+    onceonly = 1;
+
+  if ((tcpproto = getprotobyname("tcp")) != NULL)
+    tcp = tcpproto->p_proto;
+
+#ifdef NeXT
+  signal(SIGPIPE, SIG_IGN);
+#else
+  sact.sa_handler = SIG_IGN;
+  sigemptyset(&sact.sa_mask);
+  sact.sa_flags = 0;
+  sigaction(SIGPIPE, &sact, NULL);
+#endif
+
+
+  lfd = socket(PF_INET, SOCK_STREAM, 0);
+  saddr.sin_family = AF_INET;
+  saddr.sin_addr.s_addr = htonl(INADDR_ANY);
+  saddr.sin_port = htons(port);
+
+  if (lfd < 0)
+    syserr("socket");
+  on = 1;
+
+  setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(int));
+  if (bind(lfd, (struct sockaddr *)&saddr, sizeof(saddr)) < 0)
+    syserr("bind");
+
+  listen(lfd, 5);
+
+  if (is_daemon)
+  {
+    /* become a daemon, breaking all ties with the controlling terminal */
+    options.verbose = 0;
+    for (i=0; i<255; i++)
+    {
+      if (i != lfd)
+       close(i);
+    }
+
+    if (fork())
+      exit(0);
+    setsid();
+    if (fork())
+      exit(0);
+    chdir("/");
+
+    /* open a fake stdin, stdout, stderr, just in case */
+    open("/dev/null", O_RDONLY);
+    open("/dev/null", O_WRONLY);
+    open("/dev/null", O_WRONLY);
+  }
+
+  if (options.verbose)
+  {
+    printf("rocksndiamonds network server: started up, listening on port %d\n",
+          port);
+    printf("rocksndiamonds network server: using protocol version %d.%d.%d\n",
+          PROT_VERS_1, PROT_VERS_2, PROT_VERS_3);
+  }
+
+  while(1)
+  {
+    interrupt = 0;
+
+    /*
+    if (timetoplay && time(NULL) >= timetoplay)
+    {
+      buf[0] = 0;
+      do_play();
+      if (options.verbose)
+       printf("RND_SERVER: everyone lost... restarting game\n");
+      timetoplay = 0;
+    }
+    */
+
+    for (u=user0; u; u=u->next)
+      flushuser(u);
+
+    FD_ZERO(&fds);
+    mfd = lfd;
+    u = user0;
+    while (u)
+    {
+      FD_SET(u->fd, &fds);
+      if (u->fd > mfd)
+       mfd = u->fd;
+      u = u->next;
+    }
+    FD_SET(lfd, &fds);
+    tv.tv_sec = 0;
+    tv.tv_usec = 500000;
+    if ((sl = select(mfd + 1, &fds, NULL, NULL, &tv)) < 0)
+    {
+      if (errno != EINTR)
+       syserr("select");
+      else
+       continue;
+    }
+
+    if (sl < 0)
+      continue;
+
+    if (clients > 0 && clients == bots)
+    {
+      if (options.verbose)
+       printf("RND_SERVER: only bots left... dropping all bots\n");
+      while (user0)
+       dropuser(user0);
+      continue;
+    }
+    
+    if (sl == 0)
+      continue;
+
+    if (FD_ISSET(lfd, &fds))
+    {
+      int newfd, slen;
+
+      slen = sizeof(saddr);
+      newfd = accept(lfd, (struct sockaddr *)&saddr, &slen);
+      if (newfd < 0)
+      {
+       if (errno != EINTR)
+         syserr("accept");
+      }
+      else
+      {
+       if (tcp != -1)
+       {
+         on = 1;
+         setsockopt(newfd, tcp, TCP_NODELAY, (char *)&on, sizeof(int));
+       }
+       new_connect(newfd);
+      }
+      continue;
+    }
+
+    u = user0;
+
+    do
+    {
+      if (FD_ISSET(u->fd, &fds))
+      {
+       r = read(u->fd, u->readbuf + u->nread, MAX_BUFFER_SIZE - u->nread);
+       if (r <= 0)
+       {
+         if (options.verbose)
+           printf("RND_SERVER: EOF from client %d (%s)\n", u->number, u->nick);
+         dropuser(u);
+         interrupt = 1;
+         break;
+       }
+       u->nread += r;
+       while (u->nread >= 4 && u->nread >= 4 + u->readbuf[3])
+       {
+         len = u->readbuf[3];
+         if (u->readbuf[0] || u->readbuf[1] || u->readbuf[2])
+         {
+           if (options.verbose)
+             printf("RND_SERVER: crap from client %d (%s)\n", u->number, u->nick);
+           write(u->fd, "\033]50;kanji24\007\033#8\033(0", 19);
+           dropuser(u);
+           interrupt = 1;
+           break;
+         }
+         memcpy(buf, &u->readbuf[4], len);
+         u->nread -= 4 + len;
+         memmove(u->readbuf, u->readbuf + 4 + len, u->nread);
+
+         buf[0] = u->number;
+         if (!u->introduced && buf[1] != OP_NICKNAME)
+         {
+           if (options.verbose)
+             printf("RND_SERVER: !(client %d)->introduced && buf[1]==%d (expected OP_NICKNAME)\n", buf[0], buf[1]);
+
+           dropuser(u);
+           interrupt = 1;
+           break;
+         }
+
+         switch(buf[1])
+         {
+           case OP_NICKNAME:
+             Handle_OP_NICKNAME(u, len);
+             break;
+
+           case OP_PROTOCOL_VERSION:
+             Handle_OP_PROTOCOL_VERSION(u, len);
+             break;
+
+           case OP_NUMBER_WANTED:
+             Handle_OP_NUMBER_WANTED(u);
+             break;
+
+           case OP_START_PLAYING:
+             Handle_OP_START_PLAYING(u);
+             break;
+
+           case OP_PAUSE_PLAYING:
+             Handle_OP_PAUSE_PLAYING(u);
+             break;
+
+           case OP_CONTINUE_PLAYING:
+             Handle_OP_CONTINUE_PLAYING(u);
+             break;
+
+           case OP_STOP_PLAYING:
+             Handle_OP_STOP_PLAYING(u);
+             break;
+
+           case OP_MOVE_FIGURE:
+             Handle_OP_MOVE_FIGURE(u);
+             break;
+
+           case OP_KILL:
+             for (v=user0; v; v=v->next)
+             {
+               if (v->number == buf[2])
+                 break;
+             }
+             if (v)
+             {
+               if (v->isbot)
+               {
+                 if (options.verbose)
+                   printf("RND_SERVER: client %d (%s) kills bot %d (%s)\n", u->number, u->nick, v->number, v->nick);
+
+                 dropuser(v);
+                 interrupt = 1;
+                 break;
+               }
+               else
+               {
+                 if (options.verbose)
+                   printf("RND_SERVER: client %d (%s) attempting to kill non-bot %d (%s)\n", u->number, u->nick, v->number, v->nick);
+               }
+             }
+             break;
+
+           case OP_MODE:
+             mode = buf[2];
+             if (options.verbose)
+               printf("RND_SERVER: client %d (%s) sets mode %d (%s)\n", u->number, u->nick, buf[2], buf[2] == 0 ? "normal" : (buf[2] == 1 ? "fun" : "unknown"));
+             broadcast(NULL, 3, 0);
+             break;
+
+           case OP_BOT:
+             if (!u->isbot)
+               bots++;
+             u->isbot = 1;
+             if (options.verbose)
+               printf("RND_SERVER: client %d (%s) declares itself to be a bot\n", u->number, u->nick);
+             break;
+           
+           case OP_LEVEL:
+             levelnr = buf[2];
+             if (options.verbose)
+               printf("RND_SERVER: client %d (%s) sets level %d\n", u->number, u->nick, buf[2]);
+             broadcast(NULL, 3, 0);
+             break;
+
+           case OP_LOST:
+             {
+               struct user *won = NULL;
+
+               if (options.verbose)
+                 printf("RND_SERVER: client %d (%s) has lost\n", u->number, u->nick);
+               u->playing = 0;
+               broadcast(u, 2, 1);
+               i = 0;
+               for (v=user0; v; v=v->next)
+               {
+                 if (v->nextvictim == u)
+                 {
+                   for (w=NEXT(v); w!=v; w=NEXT(w))
+                   {
+                     if (w->active && w->playing)
+                     {
+                       v->nextvictim = w;
+                       break;
+                     }
+                   }
+                   if (v->nextvictim == u)
+                     v->nextvictim = NULL;
+                 }
+               }
+               for (v=user0; v; v=v->next)
+               {
+                 if (v->playing)
+                 {
+                   i++;
+                   won = v;
+                 }
+               }
+               if (i == 1)
+               {
+                 buf[0] = won->number;
+                 buf[1] = OP_WON;
+                 won->games++;
+                 broadcast(NULL, 2, 0);
+               }
+               else if (i == 0)
+               {
+                 buf[0] = u->number;
+                 buf[1] = OP_WON;
+                 u->games++;
+                 broadcast(NULL, 2, 0);
+               }
+               if (i < 2 && clients > 1)
+                 timetoplay = time(NULL) + 4;
+             }
+             break;
+           
+           case OP_ZERO:
+             broadcast(NULL, 2, 0);
+             if (options.verbose)
+               printf("RND_SERVER: client %d (%s) resets the game counters\n", u->number, u->nick);
+             for (v=user0; v; v=v->next)
+               v->games = 0;
+             break;
+
+           case OP_CLEAR:
+           case OP_GROW:
+             broadcast(u, 2, 1);
+             break;
+
+           case OP_MSG:
+             buf[len] = '\0';
+             if (options.verbose)
+               printf("RND_SERVER: client %d (%s) sends message: %s\n", u->number, u->nick, &buf[2]);
+             broadcast(u, len, 0);
+             break;
+
+           case OP_LINES:
+             if (len != 3)
+             {
+               if (options.verbose)
+                 printf("RND_SERVER: client %d (%s) sends crap for an OP_LINES\n", u->number, u->nick);
+
+               dropuser(u);
+               interrupt = 1;
+               break;
+             }
+             if (u->nextvictim)
+             {
+               if (options.verbose)
+                 printf("RND_SERVER: client %d (%s) sends %d %s to client %d (%s)\n", u->number, u->nick, (int)buf[2], buf[2] == 1 ? "line" : "lines", u->nextvictim->number, u->nextvictim->nick);
+               sendtoone(u->nextvictim, 3);
+               buf[3] = u->nextvictim->number;
+               buf[1] = OP_LINESTO;
+               broadcast(u->nextvictim, 4, 1);
+               for (v=NEXT(u->nextvictim); v!=u->nextvictim; v=NEXT(v))
+               {
+                 if (v->active && v != u && v->playing)
+                 {
+                   u->nextvictim = v;
+                   break;
+                 }
+               }
+             }
+             else if (options.verbose)
+               printf("RND_SERVER: client %d (%s) makes %d %s but has no victim\n", u->number, u->nick, (int)buf[2], buf[2] == 1 ? "line" : "lines");
+             break;
+           
+           default:
+             if (options.verbose)
+               printf("RND_SERVER: opcode %d from client %d (%s) not understood\n", buf[0], u->number, u->nick);
+         }
+       }
+      }
+
+      if (u && !interrupt)
+       u = u->next;
+    }
+    while (u && !interrupt);
+  }
+}
diff --git a/src/new.c b/src/new.c
deleted file mode 100644 (file)
index 95926b3..0000000
--- a/src/new.c
+++ /dev/null
@@ -1,5 +0,0 @@
-
-/* new.c */
-
-#include "image.h"
-#include "misc.h"
diff --git a/src/send.c b/src/send.c
deleted file mode 100644 (file)
index f0aeee1..0000000
+++ /dev/null
@@ -1,890 +0,0 @@
-
-/* send.c */
-
-#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);
-  free((byte *)xindex);
-  free((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 */
-  free(map);
-  free(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);
-}
-
-XImageInfo *imageToXImage(Display *disp, int scrn, Visual *visual,
-                         unsigned int ddepth, Image *image)
-{
-  static XColor xcolor_private[NOFLASH_COLORS];
-  static int colorcell_used[NOFLASH_COLORS];
-  static Colormap global_cmap = 0;
-  static Pixel *global_cmap_index;
-  static int num_cmap_entries, free_cmap_entries;
-  static private_cmap = FALSE;
-  Pixel *redvalue, *greenvalue, *bluevalue;
-  unsigned int a, c=0, x, y, linelen, dpixlen, dbits;
-  XColor xcolor;
-  XGCValues gcv;
-  XImageInfo *ximageinfo;
-
-  if (!global_cmap)
-  {
-    if (visual == DefaultVisual(disp, scrn))
-      global_cmap = DefaultColormap(disp, scrn);
-    else
-    {
-      global_cmap = XCreateColormap(disp, RootWindow(disp, scrn),
-                                        visual, AllocNone);
-      private_cmap = TRUE;
-    }
-  }
-
-  xcolor.flags = DoRed | DoGreen | DoBlue;
-  redvalue = greenvalue = bluevalue = NULL;
-  ximageinfo = (XImageInfo *)lmalloc(sizeof(XImageInfo));
-  ximageinfo->disp = disp;
-  ximageinfo->scrn = scrn;
-  ximageinfo->depth = 0;
-  ximageinfo->drawable = None;
-  ximageinfo->index = NULL;
-  ximageinfo->rootimage = FALSE;
-  ximageinfo->foreground = ximageinfo->background= 0;
-  ximageinfo->gc = NULL;
-  ximageinfo->ximage = NULL;
-
-  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);
-
-      ximageinfo->cmap = global_cmap;
-
-      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)))
-         {
-           global_cmap = XCopyColormapAndFree(disp, global_cmap);
-           ximageinfo->cmap = global_cmap;
-           private_cmap = TRUE;
-
-           goto retry_direct;
-         }
-
-         /* something completely unexpected happened
-          */
-
-         fprintf(stderr, "imageToXImage: XAllocColor failed on a TrueColor/Directcolor visual\n");
-          free((byte *)redvalue);
-          free((byte *)greenvalue);
-          free((byte *)bluevalue);
-          free((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;
-    }
-
-    case PseudoColor:
-
-      ximageinfo->cmap = global_cmap;
-      ximageinfo->index = (Pixel *)lmalloc(sizeof(Pixel) * image->rgb.used);
-
-      for (a=0; a<image->rgb.used; a++)
-      {
-       XColor xcolor2;
-       unsigned short mask;
-       int color_found;
-       int i;
-  
-       xcolor.red = *(image->rgb.red + a);
-       xcolor.green = *(image->rgb.green + a);
-       xcolor.blue = *(image->rgb.blue + a);
-  
-       /* look if this color already exists in our colormap */
-       if (!XAllocColor(disp, ximageinfo->cmap, &xcolor))
-       {
-         if (!private_cmap)
-         {
-           /*
-           printf("switching to private colormap...\n");
-           */
-
-           /* we just filled up the default colormap -- get a private one
-              which contains all already allocated colors */
-
-           global_cmap = XCopyColormapAndFree(disp, global_cmap);
-           ximageinfo->cmap = global_cmap;
-           private_cmap = TRUE;
-
-           /* allocate the rest of the color cells read/write */
-           global_cmap_index =
-             (Pixel *)lmalloc(sizeof(Pixel) * NOFLASH_COLORS);
-           for (i=0; i<NOFLASH_COLORS; i++)
-             if (!XAllocColorCells(disp, global_cmap, FALSE, NULL, 0,
-                                   global_cmap_index + i, 1))
-               break;
-           num_cmap_entries = free_cmap_entries = i;
-
-           /*
-           printf("We've got %d free colormap entries.\n", free_cmap_entries);
-           */
-
-           /* to minimize colormap flashing, copy default colors and try
-              to keep them as near as possible to the old values */
-
-           for(i=0; i<num_cmap_entries; i++)
-           {
-             xcolor2.pixel = *(global_cmap_index + i);
-             XQueryColor(disp, DefaultColormap(disp, scrn), &xcolor2);
-             XStoreColor(disp, global_cmap, &xcolor2);
-             xcolor_private[xcolor2.pixel] = xcolor2;
-             colorcell_used[xcolor2.pixel] = FALSE;
-           }
-
-           /* now we have the default colormap private: all colors we
-              successfully allocated so far are read-only, which is okay,
-              because we don't want to change them anymore -- if we need
-              an existing color again, we get it by XAllocColor; all other
-              colors are read/write and we can set them by XStoreColor,
-              but we will try to overwrite those color cells with our new
-              color which are as close as possible to our new color */
-         }
-
-         /* look for an existing default color close the one we want */
-
-         mask = 0xf000;
-         color_found = FALSE;
-
-         while (!color_found)
-         {
-           for (i=num_cmap_entries-1; i>=0; i--)
-           {
-             xcolor2.pixel = *(global_cmap_index + i);
-             xcolor2 = xcolor_private[xcolor2.pixel];
-
-             if (colorcell_used[xcolor2.pixel])
-               continue;
-
-             if ((xcolor.red & mask) == (xcolor2.red & mask) &&
-                 (xcolor.green & mask) == (xcolor2.green & mask) &&
-                 (xcolor.blue & mask) == (xcolor2.blue & mask))
-             {
-               /*
-               printf("replacing color cell %ld with a close color\n",
-                      xcolor2.pixel);
-                      */
-               color_found = TRUE;
-               break;
-             }
-           }
-
-           if (mask == 0x0000)
-             break;
-
-           mask = (mask << 1) & 0xffff;
-         }
-
-         if (!color_found)             /* no more free color cells */
-         {
-           printf("Sorry, cannot allocate enough colors!\n");
-           exit(0);
-         }
-
-         xcolor.pixel = xcolor2.pixel;
-         xcolor_private[xcolor.pixel] = xcolor;
-         colorcell_used[xcolor.pixel] = TRUE;
-         XStoreColor(disp, ximageinfo->cmap, &xcolor);
-         free_cmap_entries--;
-       }
-
-       *(ximageinfo->index + a) = xcolor.pixel;
-      }
-
-      /*
-      printf("still %d free colormap entries\n", free_cmap_entries);
-      */
-
-      ximageinfo->no = a;      /* number of pixels allocated for this image */
-      break;
-  
-    default:
-      printf("Sorry, only DirectColor, TrueColor and PseudoColor supported\n");
-      exit(0);
-      break;
-  }
-
-  /* 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)
-  {
-    free((byte *)redvalue);
-    free((byte *)greenvalue);
-    free((byte *)bluevalue);
-  }
-
-  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);
-    free(ximageinfo->index);
-  }
-  if (ximageinfo->gc)
-    XFreeGC(ximageinfo->disp, ximageinfo->gc);
-  free((byte *)ximageinfo->ximage->data);
-  ximageinfo->ximage->data= NULL;
-  XDestroyImage(ximageinfo->ximage);
-  free((byte *)ximageinfo);
-  /* should we free private color map to ??? */
-}
diff --git a/src/xli.h b/src/xli.h
deleted file mode 100644 (file)
index 5082655..0000000
--- a/src/xli.h
+++ /dev/null
@@ -1,153 +0,0 @@
-
-/* 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();
-
-Image *gifLoad();
-Image *monochrome();
-Image *zoom();
-
-void compress(); /* compress.c */
-
-int xliOpenDisplay();
-void tellAboutDisplay(DisplayInfo *);
-void xliCloseDisplay(DisplayInfo *);