rnd-20001201-1-src
authorHolger Schemel <info@artsoft.org>
Fri, 1 Dec 2000 18:22:24 +0000 (19:22 +0100)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:35:17 +0000 (10:35 +0200)
69 files changed:
Makefile
src/Makefile
src/buttons.c [deleted file]
src/buttons.h [deleted file]
src/cartoons.c
src/editor.c
src/events.c
src/files.c
src/game.c
src/image.c [deleted file]
src/image.h [deleted file]
src/init.c
src/joystick.c
src/libgame/Makefile [new file with mode: 0644]
src/libgame/buttons.c [new file with mode: 0644]
src/libgame/buttons.h [new file with mode: 0644]
src/libgame/image.c [new file with mode: 0644]
src/libgame/image.h [new file with mode: 0644]
src/libgame/joystick_TMP.h [new file with mode: 0644]
src/libgame/libgame.c [new file with mode: 0644]
src/libgame/libgame.h [new file with mode: 0644]
src/libgame/main_TMP.h [new symlink]
src/libgame/misc.c [new file with mode: 0644]
src/libgame/misc.h [new file with mode: 0644]
src/libgame/msdos.c [new file with mode: 0644]
src/libgame/msdos.h [new file with mode: 0644]
src/libgame/pcx.c [new file with mode: 0644]
src/libgame/pcx.h [new file with mode: 0644]
src/libgame/platform.h [new file with mode: 0644]
src/libgame/private.c [new file with mode: 0644]
src/libgame/private.h [new file with mode: 0644]
src/libgame/random.c [new file with mode: 0644]
src/libgame/random.h [new file with mode: 0644]
src/libgame/sdl.c [new file with mode: 0644]
src/libgame/sdl.h [new file with mode: 0644]
src/libgame/sound.c [new file with mode: 0644]
src/libgame/sound.h [new file with mode: 0644]
src/libgame/system.c [new file with mode: 0644]
src/libgame/system.h [new file with mode: 0644]
src/libgame/text.c [new file with mode: 0644]
src/libgame/text.h [new file with mode: 0644]
src/libgame/types.h [new file with mode: 0644]
src/libgame/x11.c [new file with mode: 0644]
src/libgame/x11.h [new file with mode: 0644]
src/main.c
src/main.h
src/misc.c [deleted file]
src/misc.h [deleted file]
src/msdos.c [deleted file]
src/msdos.h [deleted file]
src/netserv.c
src/network.c
src/pcx.c [deleted file]
src/pcx.h [deleted file]
src/platform.h [deleted file]
src/random.c [deleted file]
src/random.h [deleted file]
src/screens.c
src/sdl.c [deleted file]
src/sdl.h [deleted file]
src/sound.c [deleted file]
src/sound.h [deleted file]
src/system.c [deleted file]
src/system.h [deleted file]
src/tape.c
src/tools.c
src/tools.h
src/x11.c [deleted file]
src/x11.h [deleted file]

index cf775274d67af633249720d5c09d13da35cfa659..e058339a40bac9af41053072f94398e98e231dc5 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -48,7 +48,7 @@ SRC_DIR = src
 MAKE_CMD = $(MAKE) -C $(SRC_DIR)
 
 all:
-       @$(MAKE_CMD) TARGET=sdl
+       @$(MAKE_CMD) TARGET=x11
 
 x11:
        @$(MAKE_CMD) TARGET=x11
index cc8e1df0439b9abf95affa76278759f823248dc1..6bf31b87a2b2e9a40506c31d13de7aabce6abfd0 100644 (file)
@@ -3,6 +3,8 @@
 # (c) 1995-2000 Holger Schemel, info@artsoft.org                              #
 #=============================================================================#
 
+.EXPORT_ALL_VARIABLES:
+
 ifndef PLATFORM                        # platform not specified -- try auto detection
 ifdef COMSPEC
 PLATFORM = msdos
@@ -18,6 +20,8 @@ X11_INCL = -I$(XINC_PATH)
 X11_LIBS = -L$(XLIB_PATH)
 endif
 
+AR = ar
+RANLIB = ranlib
 
 ifeq ($(PLATFORM),msdos)       # MS-DOS native compiling
 
@@ -98,66 +102,56 @@ OPTIONS = $(DEBUG) -Wall                   # only for debugging purposes
 CFLAGS = $(OPTIONS) $(SYS_CFLAGS) $(CONFIG)
 LDFLAGS = $(SYS_LDFLAGS) $(EXTRA_LDFLAGS) -lm
 
+
 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       \
-       msdos.c         \
-       system.c        \
-       x11.c           \
-       sdl.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       \
-       msdos.o         \
-       system.o        \
-       x11.o           \
-       sdl.o
+       netserv.o
+
+LIBDIR = libgame
+LIBGAME = $(LIBDIR)/libgame.a
+
 
-all:   $(PROGNAME)
+all: $(PROGNAME)
 
-$(PROGNAME):   $(OBJS)
-       $(CC) $(PROFILING) $(OBJS) $(LDFLAGS) -o $(PROGNAME)
+$(PROGNAME): $(LIBGAME) $(OBJS)
+       $(CC) $(PROFILING) $(OBJS) $(LIBGAME) $(LDFLAGS) -o $(PROGNAME)
+
+$(LIBGAME):
+       $(MAKE) -C $(LIBDIR)
 
 .c.o:
        $(CC) $(PROFILING) $(CFLAGS) -c $*.c
 
 clean:
-       $(RM) *.o
-       $(RM) ../*.exe
+       $(MAKE) -C $(LIBDIR) clean
+       $(RM) $(OBJS)
+       $(RM) $(LIBGAME)
        $(RM) $(PROGNAME)
+       $(RM) ../*.exe
 
 
 #-----------------------------------------------------------------------------#
@@ -165,6 +159,7 @@ clean:
 #-----------------------------------------------------------------------------#
 
 depend:
+       $(MAKE) -C $(LIBDIR) depend
        for i in $(SRCS); do $(CPP) $(CFLAGS) -M $$i; done > .depend
 
 ifeq (.depend,$(wildcard .depend))
diff --git a/src/buttons.c b/src/buttons.c
deleted file mode 100644 (file)
index 88ff994..0000000
+++ /dev/null
@@ -1,1345 +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                *
-*----------------------------------------------------------*
-*  buttons.c                                               *
-***********************************************************/
-
-#include <stdarg.h>
-
-#include "buttons.h"
-#include "tools.h"
-#include "misc.h"
-#include "editor.h"
-#include "tape.h"
-
-/* some positions in the video tape control window */
-#define VIDEO_DATE_LABEL_XPOS  (VIDEO_DISPLAY1_XPOS)
-#define VIDEO_DATE_LABEL_YPOS  (VIDEO_DISPLAY1_YPOS)
-#define VIDEO_DATE_LABEL_XSIZE (VIDEO_DISPLAY_XSIZE)
-#define VIDEO_DATE_LABEL_YSIZE (VIDEO_DISPLAY_YSIZE)
-#define VIDEO_DATE_XPOS                (VIDEO_DISPLAY1_XPOS + 1)
-#define VIDEO_DATE_YPOS                (VIDEO_DISPLAY1_YPOS + 14)
-#define VIDEO_DATE_XSIZE       (VIDEO_DISPLAY_XSIZE)
-#define VIDEO_DATE_YSIZE       16
-#define VIDEO_REC_LABEL_XPOS   (VIDEO_DISPLAY2_XPOS)
-#define VIDEO_REC_LABEL_YPOS   (VIDEO_DISPLAY2_YPOS)
-#define VIDEO_REC_LABEL_XSIZE  20
-#define VIDEO_REC_LABEL_YSIZE  12
-#define VIDEO_REC_SYMBOL_XPOS  (VIDEO_DISPLAY2_XPOS + 20)
-#define VIDEO_REC_SYMBOL_YPOS  (VIDEO_DISPLAY2_YPOS)
-#define VIDEO_REC_SYMBOL_XSIZE 16
-#define VIDEO_REC_SYMBOL_YSIZE 16
-#define VIDEO_PLAY_LABEL_XPOS  (VIDEO_DISPLAY2_XPOS + 65)
-#define VIDEO_PLAY_LABEL_YPOS  (VIDEO_DISPLAY2_YPOS)
-#define VIDEO_PLAY_LABEL_XSIZE 22
-#define VIDEO_PLAY_LABEL_YSIZE 12
-#define VIDEO_PLAY_SYMBOL_XPOS (VIDEO_DISPLAY2_XPOS + 52)
-#define VIDEO_PLAY_SYMBOL_YPOS (VIDEO_DISPLAY2_YPOS)
-#define VIDEO_PLAY_SYMBOL_XSIZE        11
-#define VIDEO_PLAY_SYMBOL_YSIZE        13
-#define VIDEO_PAUSE_LABEL_XPOS (VIDEO_DISPLAY2_XPOS)
-#define VIDEO_PAUSE_LABEL_YPOS (VIDEO_DISPLAY2_YPOS + 20)
-#define VIDEO_PAUSE_LABEL_XSIZE        35
-#define VIDEO_PAUSE_LABEL_YSIZE        8
-#define VIDEO_PAUSE_SYMBOL_XPOS        (VIDEO_DISPLAY2_XPOS + 35)
-#define VIDEO_PAUSE_SYMBOL_YPOS        (VIDEO_DISPLAY2_YPOS)
-#define VIDEO_PAUSE_SYMBOL_XSIZE 17
-#define VIDEO_PAUSE_SYMBOL_YSIZE 13
-#define VIDEO_TIME_XPOS                (VIDEO_DISPLAY2_XPOS + 38)
-#define VIDEO_TIME_YPOS                (VIDEO_DISPLAY2_YPOS + 14)
-#define VIDEO_TIME_XSIZE       50
-#define VIDEO_TIME_YSIZE       16
-
-/* special */
-#define VIDEO_PBEND_LABEL_XPOS 6
-#define VIDEO_PBEND_LABEL_YPOS 220
-#define VIDEO_PBEND_LABEL_XSIZE        35
-#define VIDEO_PBEND_LABEL_YSIZE        30
-
-#define VIDEO_STATE_OFF                (VIDEO_STATE_PLAY_OFF   |       \
-                                VIDEO_STATE_REC_OFF    |       \
-                                VIDEO_STATE_PAUSE_OFF  |       \
-                                VIDEO_STATE_FFWD_OFF   |       \
-                                VIDEO_STATE_PBEND_OFF  |       \
-                                VIDEO_STATE_DATE_OFF   |       \
-                                VIDEO_STATE_TIME_OFF)
-#define VIDEO_PRESS_OFF                (VIDEO_PRESS_PLAY_OFF   |       \
-                                VIDEO_PRESS_REC_OFF    |       \
-                                VIDEO_PRESS_PAUSE_OFF  |       \
-                                VIDEO_PRESS_STOP_OFF   |       \
-                                VIDEO_PRESS_EJECT_OFF)
-#define VIDEO_ALL_OFF          (VIDEO_STATE_OFF | VIDEO_PRESS_OFF)
-
-#define VIDEO_STATE_ON         (VIDEO_STATE_PLAY_ON    |       \
-                                VIDEO_STATE_REC_ON     |       \
-                                VIDEO_STATE_PAUSE_ON   |       \
-                                VIDEO_STATE_FFWD_ON    |       \
-                                VIDEO_STATE_PBEND_ON   |       \
-                                VIDEO_STATE_DATE_ON    |       \
-                                VIDEO_STATE_TIME_ON)
-#define VIDEO_PRESS_ON         (VIDEO_PRESS_PLAY_ON    |       \
-                                VIDEO_PRESS_REC_ON     |       \
-                                VIDEO_PRESS_PAUSE_ON   |       \
-                                VIDEO_PRESS_STOP_ON    |       \
-                                VIDEO_PRESS_EJECT_ON)
-#define VIDEO_ALL_ON           (VIDEO_STATE_ON | VIDEO_PRESS_ON)
-
-#define VIDEO_STATE            (VIDEO_STATE_ON | VIDEO_STATE_OFF)
-#define VIDEO_PRESS            (VIDEO_PRESS_ON | VIDEO_PRESS_OFF)
-#define VIDEO_ALL              (VIDEO_ALL_ON | VIDEO_ALL_OFF)
-
-
-void DrawVideoDisplay(unsigned long state, unsigned long value)
-{
-  int i;
-  int part_label = 0, part_symbol = 1;
-  int xpos = 0, ypos = 1, xsize = 2, ysize = 3;
-  static char *monatsname[12] =
-  {
-    "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
-    "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"
-  };
-  static int video_pos[5][2][4] =
-  {
-    {{ VIDEO_PLAY_LABEL_XPOS, VIDEO_PLAY_LABEL_YPOS,
-       VIDEO_PLAY_LABEL_XSIZE,VIDEO_PLAY_LABEL_YSIZE },
-     { VIDEO_PLAY_SYMBOL_XPOS, VIDEO_PLAY_SYMBOL_YPOS,
-       VIDEO_PLAY_SYMBOL_XSIZE,VIDEO_PLAY_SYMBOL_YSIZE }},
-
-    {{ VIDEO_REC_LABEL_XPOS, VIDEO_REC_LABEL_YPOS,
-       VIDEO_REC_LABEL_XSIZE,VIDEO_REC_LABEL_YSIZE },
-     { VIDEO_REC_SYMBOL_XPOS, VIDEO_REC_SYMBOL_YPOS,
-       VIDEO_REC_SYMBOL_XSIZE,VIDEO_REC_SYMBOL_YSIZE }},
-
-    {{ VIDEO_PAUSE_LABEL_XPOS, VIDEO_PAUSE_LABEL_YPOS,
-       VIDEO_PAUSE_LABEL_XSIZE,VIDEO_PAUSE_LABEL_YSIZE },
-     { VIDEO_PAUSE_SYMBOL_XPOS, VIDEO_PAUSE_SYMBOL_YPOS,
-       VIDEO_PAUSE_SYMBOL_XSIZE,VIDEO_PAUSE_SYMBOL_YSIZE }},
-
-    {{ VIDEO_DATE_LABEL_XPOS, VIDEO_DATE_LABEL_YPOS,
-       VIDEO_DATE_LABEL_XSIZE,VIDEO_DATE_LABEL_YSIZE },
-     { VIDEO_DATE_XPOS, VIDEO_DATE_YPOS,
-       VIDEO_DATE_XSIZE,VIDEO_DATE_YSIZE }},
-
-    {{ 0,0,
-       0,0 },
-     { VIDEO_TIME_XPOS, VIDEO_TIME_YPOS,
-       VIDEO_TIME_XSIZE,VIDEO_TIME_YSIZE }}
-  };
-
-  if (state & VIDEO_STATE_PBEND_OFF)
-  {
-    int cx = DOOR_GFX_PAGEX3, cy = DOOR_GFX_PAGEY2;
-
-    BlitBitmap(pix[PIX_DOOR], drawto,
-              cx + VIDEO_REC_LABEL_XPOS,
-              cy + VIDEO_REC_LABEL_YPOS,
-              VIDEO_PBEND_LABEL_XSIZE,
-              VIDEO_PBEND_LABEL_YSIZE,
-              VX + VIDEO_REC_LABEL_XPOS,
-              VY + VIDEO_REC_LABEL_YPOS);
-  }
-
-  for(i=0;i<10;i++)
-  {
-    if (state & (1<<i))
-    {
-      int pos = i/2, cx, cy = DOOR_GFX_PAGEY2;
-
-      if (i%2)                 /* i ungerade => STATE_ON / PRESS_OFF */
-       cx = DOOR_GFX_PAGEX4;
-      else
-       cx = DOOR_GFX_PAGEX3;   /* i gerade => STATE_OFF / PRESS_ON */
-
-      if (video_pos[pos][part_label][0] && value != VIDEO_DISPLAY_SYMBOL_ONLY)
-       BlitBitmap(pix[PIX_DOOR], drawto,
-                  cx + video_pos[pos][part_label][xpos],
-                  cy + video_pos[pos][part_label][ypos],
-                  video_pos[pos][part_label][xsize],
-                  video_pos[pos][part_label][ysize],
-                  VX + video_pos[pos][part_label][xpos],
-                  VY + video_pos[pos][part_label][ypos]);
-      if (video_pos[pos][part_symbol][0] && value != VIDEO_DISPLAY_LABEL_ONLY)
-       BlitBitmap(pix[PIX_DOOR], drawto,
-                  cx + video_pos[pos][part_symbol][xpos],
-                  cy + video_pos[pos][part_symbol][ypos],
-                  video_pos[pos][part_symbol][xsize],
-                  video_pos[pos][part_symbol][ysize],
-                  VX + video_pos[pos][part_symbol][xpos],
-                  VY + video_pos[pos][part_symbol][ypos]);
-    }
-  }
-
-  if (state & VIDEO_STATE_FFWD_ON)
-  {
-    int cx = DOOR_GFX_PAGEX4, cy = DOOR_GFX_PAGEY2;
-
-    BlitBitmap(pix[PIX_DOOR], drawto,
-              cx + VIDEO_PLAY_SYMBOL_XPOS,
-              cy + VIDEO_PLAY_SYMBOL_YPOS,
-              VIDEO_PLAY_SYMBOL_XSIZE - 2,
-              VIDEO_PLAY_SYMBOL_YSIZE,
-              VX + VIDEO_PLAY_SYMBOL_XPOS - 9,
-              VY + VIDEO_PLAY_SYMBOL_YPOS);
-  }
-
-  if (state & VIDEO_STATE_PBEND_ON)
-  {
-    int cx = DOOR_GFX_PAGEX6, cy = DOOR_GFX_PAGEY1;
-
-    BlitBitmap(pix[PIX_DOOR], drawto,
-              cx + VIDEO_PBEND_LABEL_XPOS,
-              cy + VIDEO_PBEND_LABEL_YPOS,
-              VIDEO_PBEND_LABEL_XSIZE,
-              VIDEO_PBEND_LABEL_YSIZE,
-              VX + VIDEO_REC_LABEL_XPOS,
-              VY + VIDEO_REC_LABEL_YPOS);
-  }
-
-  if (state & VIDEO_STATE_DATE_ON)
-  {
-    int tag = value % 100;
-    int monat = (value/100) % 100;
-    int jahr = (value/10000);
-
-    DrawText(VX+VIDEO_DATE_XPOS,VY+VIDEO_DATE_YPOS,
-            int2str(tag,2),FS_SMALL,FC_SPECIAL1);
-    DrawText(VX+VIDEO_DATE_XPOS+27,VY+VIDEO_DATE_YPOS,
-            monatsname[monat],FS_SMALL,FC_SPECIAL1);
-    DrawText(VX+VIDEO_DATE_XPOS+64,VY+VIDEO_DATE_YPOS,
-            int2str(jahr,2),FS_SMALL,FC_SPECIAL1);
-  }
-
-  if (state & VIDEO_STATE_TIME_ON)
-  {
-    int min = value / 60;
-    int sec = value % 60;
-
-    DrawText(VX+VIDEO_TIME_XPOS,VY+VIDEO_TIME_YPOS,
-            int2str(min,2),FS_SMALL,FC_SPECIAL1);
-    DrawText(VX+VIDEO_TIME_XPOS+27,VY+VIDEO_TIME_YPOS,
-            int2str(sec,2),FS_SMALL,FC_SPECIAL1);
-  }
-
-  if (state & VIDEO_STATE_DATE)
-    redraw_mask |= REDRAW_VIDEO_1;
-  if ((state & ~VIDEO_STATE_DATE) & VIDEO_STATE)
-    redraw_mask |= REDRAW_VIDEO_2;
-  if (state & VIDEO_PRESS)
-    redraw_mask |= REDRAW_VIDEO_3;
-}
-
-void DrawCompleteVideoDisplay()
-{
-  BlitBitmap(pix[PIX_DOOR], drawto,
-            DOOR_GFX_PAGEX3,DOOR_GFX_PAGEY2, VXSIZE,VYSIZE, VX,VY);
-  BlitBitmap(pix[PIX_DOOR], drawto,
-            DOOR_GFX_PAGEX4+VIDEO_CONTROL_XPOS,
-            DOOR_GFX_PAGEY2+VIDEO_CONTROL_YPOS,
-            VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE,
-            VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
-
-  DrawVideoDisplay(VIDEO_ALL_OFF,0);
-  if (tape.date && tape.length)
-  {
-    DrawVideoDisplay(VIDEO_STATE_DATE_ON,tape.date);
-    DrawVideoDisplay(VIDEO_STATE_TIME_ON,tape.length_seconds);
-  }
-
-  BlitBitmap(drawto, pix[PIX_DB_DOOR],
-            VX,VY, VXSIZE,VYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
-}
-
-
-/* NEW GADGET STUFF -------------------------------------------------------- */
-
-
-/* values for DrawGadget() */
-#define DG_UNPRESSED           0
-#define DG_PRESSED             1
-#define DG_BUFFERED            0
-#define DG_DIRECT              1
-
-static struct GadgetInfo *gadget_list_first_entry = NULL;
-static struct GadgetInfo *gadget_list_last_entry = NULL;
-static int next_free_gadget_id = 1;
-static boolean gadget_id_wrapped = FALSE;
-
-static struct GadgetInfo *getGadgetInfoFromGadgetID(int id)
-{
-  struct GadgetInfo *gi = gadget_list_first_entry;
-
-  while (gi && gi->id != id)
-    gi = gi->next;
-
-  return gi;
-}
-
-static int getNewGadgetID()
-{
-  int id = next_free_gadget_id++;
-
-  if (next_free_gadget_id <= 0)                /* counter overrun */
-  {
-    gadget_id_wrapped = TRUE;          /* now we must check each ID */
-    next_free_gadget_id = 0;
-  }
-
-  if (gadget_id_wrapped)
-  {
-    next_free_gadget_id++;
-    while (getGadgetInfoFromGadgetID(next_free_gadget_id) != NULL)
-      next_free_gadget_id++;
-  }
-
-  if (next_free_gadget_id <= 0)                /* cannot get new gadget id */
-    Error(ERR_EXIT, "too much gadgets -- this should not happen");
-
-  return id;
-}
-
-static struct GadgetInfo *getGadgetInfoFromMousePosition(int mx, int my)
-{
-  struct GadgetInfo *gi = gadget_list_first_entry;
-
-  while (gi)
-  {
-    if (gi->mapped &&
-       mx >= gi->x && mx < gi->x + gi->width &&
-       my >= gi->y && my < gi->y + gi->height)
-       break;
-
-    gi = gi->next;
-  }
-
-  return gi;
-}
-
-static void default_callback_info(void *ptr)
-{
-  if (game_status == LEVELED)
-    HandleEditorGadgetInfoText(ptr);
-}
-
-static void default_callback_action(void *ptr)
-{
-  return;
-}
-
-static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct)
-{
-  int state = (pressed ? 1 : 0);
-  struct GadgetDesign *gd = (gi->checked ?
-                            &gi->alt_design[state] :
-                            &gi->design[state]);
-
-  switch (gi->type)
-  {
-    case GD_TYPE_NORMAL_BUTTON:
-    case GD_TYPE_CHECK_BUTTON:
-    case GD_TYPE_RADIO_BUTTON:
-      BlitBitmap(gd->bitmap, drawto,
-                gd->x, gd->y, gi->width, gi->height, gi->x, gi->y);
-      if (gi->deco.design.bitmap)
-       BlitBitmap(gi->deco.design.bitmap, drawto,
-                  gi->deco.design.x, gi->deco.design.y,
-                  gi->deco.width, gi->deco.height,
-                  gi->x + gi->deco.x + (pressed ? gi->deco.xshift : 0),
-                  gi->y + gi->deco.y + (pressed ? gi->deco.yshift : 0));
-      break;
-
-    case GD_TYPE_TEXTINPUT_ALPHANUMERIC:
-    case GD_TYPE_TEXTINPUT_NUMERIC:
-      {
-       int i;
-       char cursor_letter;
-       char cursor_string[3];
-       char text[MAX_GADGET_TEXTSIZE + 1];
-       int font_type = gi->text.font_type;
-       int font_width = getFontWidth(FS_SMALL, font_type);
-       int border = gi->border.size;
-       strcpy(text, gi->text.value);
-       strcat(text, " ");
-
-       /* left part of gadget */
-       BlitBitmap(gd->bitmap, drawto,
-                  gd->x, gd->y, border, gi->height, gi->x, gi->y);
-
-       /* middle part of gadget */
-       for (i=0; i<=gi->text.size; i++)
-         BlitBitmap(gd->bitmap, drawto,
-                    gd->x + border, gd->y, font_width, gi->height,
-                    gi->x + border + i * font_width, gi->y);
-
-       /* right part of gadget */
-       BlitBitmap(gd->bitmap, drawto,
-                  gd->x + gi->border.width - border, gd->y,
-                  border, gi->height, gi->x + gi->width - border, gi->y);
-
-       /* gadget text value */
-       DrawText(gi->x + border, gi->y + border, text, FS_SMALL, font_type);
-
-       cursor_letter = gi->text.value[gi->text.cursor_position];
-       cursor_string[0] = '~';
-       cursor_string[1] = (cursor_letter != '\0' ? cursor_letter : ' ');
-       cursor_string[2] = '\0';
-
-       /* draw cursor, if active */
-       if (pressed)
-         DrawText(gi->x + border + gi->text.cursor_position * font_width,
-                  gi->y + border, cursor_string, FS_SMALL, font_type);
-      }
-      break;
-
-    case GD_TYPE_SCROLLBAR_VERTICAL:
-      {
-       int i;
-       int xpos = gi->x;
-       int ypos = gi->y + gi->scrollbar.position;
-       int design_full = gi->width;
-       int design_body = design_full - 2 * gi->border.size;
-       int size_full = gi->scrollbar.size;
-       int size_body = size_full - 2 * gi->border.size;
-       int num_steps = size_body / design_body;
-       int step_size_remain = size_body - num_steps * design_body;
-
-       /* clear scrollbar area */
-       ClearRectangle(backbuffer, gi->x, gi->y, gi->width, gi->height);
-
-       /* upper part of gadget */
-       BlitBitmap(gd->bitmap, drawto,
-                  gd->x, gd->y,
-                  gi->width, gi->border.size,
-                  xpos, ypos);
-
-       /* middle part of gadget */
-       for (i=0; i<num_steps; i++)
-         BlitBitmap(gd->bitmap, drawto,
-                    gd->x, gd->y + gi->border.size,
-                    gi->width, design_body,
-                    xpos, ypos + gi->border.size + i * design_body);
-
-       /* remaining middle part of gadget */
-       if (step_size_remain > 0)
-         BlitBitmap(gd->bitmap, drawto,
-                    gd->x,  gd->y + gi->border.size,
-                    gi->width, step_size_remain,
-                    xpos, ypos + gi->border.size + num_steps * design_body);
-
-       /* lower part of gadget */
-       BlitBitmap(gd->bitmap, drawto,
-                  gd->x, gd->y + design_full - gi->border.size,
-                  gi->width, gi->border.size,
-                  xpos, ypos + size_full - gi->border.size);
-      }
-      break;
-
-    case GD_TYPE_SCROLLBAR_HORIZONTAL:
-      {
-       int i;
-       int xpos = gi->x + gi->scrollbar.position;
-       int ypos = gi->y;
-       int design_full = gi->height;
-       int design_body = design_full - 2 * gi->border.size;
-       int size_full = gi->scrollbar.size;
-       int size_body = size_full - 2 * gi->border.size;
-       int num_steps = size_body / design_body;
-       int step_size_remain = size_body - num_steps * design_body;
-
-       /* clear scrollbar area */
-       ClearRectangle(backbuffer, gi->x, gi->y, gi->width, gi->height);
-
-       /* left part of gadget */
-       BlitBitmap(gd->bitmap, drawto,
-                  gd->x, gd->y,
-                  gi->border.size, gi->height,
-                  xpos, ypos);
-
-       /* middle part of gadget */
-       for (i=0; i<num_steps; i++)
-         BlitBitmap(gd->bitmap, drawto,
-                    gd->x + gi->border.size, gd->y,
-                    design_body, gi->height,
-                    xpos + gi->border.size + i * design_body, ypos);
-
-       /* remaining middle part of gadget */
-       if (step_size_remain > 0)
-         BlitBitmap(gd->bitmap, drawto,
-                    gd->x + gi->border.size, gd->y,
-                    step_size_remain, gi->height,
-                    xpos + gi->border.size + num_steps * design_body, ypos);
-
-       /* right part of gadget */
-       BlitBitmap(gd->bitmap, drawto,
-                  gd->x + design_full - gi->border.size, gd->y,
-                  gi->border.size, gi->height,
-                  xpos + size_full - gi->border.size, ypos);
-      }
-      break;
-
-    default:
-      return;
-  }
-
-  if (direct)
-    BlitBitmap(drawto, window,
-              gi->x, gi->y, gi->width, gi->height, gi->x, gi->y);
-  else
-    redraw_mask |= (gi->x < SX + SXSIZE ? REDRAW_FIELD :
-                   gi->y < DY + DYSIZE ? REDRAW_DOOR_1 :
-                   gi->y > VY ? REDRAW_DOOR_2 : REDRAW_DOOR_3);
-}
-
-static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap)
-{
-  int tag = first_tag;
-
-  while (tag != GDI_END)
-  {
-    switch(tag)
-    {
-      case GDI_CUSTOM_ID:
-       gi->custom_id = va_arg(ap, int);
-       break;
-
-      case GDI_CUSTOM_TYPE_ID:
-       gi->custom_type_id = va_arg(ap, int);
-       break;
-
-      case GDI_INFO_TEXT:
-       {
-         int max_textsize = MAX_INFO_TEXTSIZE - 1;
-
-         strncpy(gi->info_text, va_arg(ap, char *), max_textsize);
-         gi->info_text[max_textsize] = '\0';
-       }
-       break;
-
-      case GDI_X:
-       gi->x = va_arg(ap, int);
-       break;
-
-      case GDI_Y:
-       gi->y = va_arg(ap, int);
-       break;
-
-      case GDI_WIDTH:
-       gi->width = va_arg(ap, int);
-       break;
-
-      case GDI_HEIGHT:
-       gi->height = va_arg(ap, int);
-       break;
-
-      case GDI_TYPE:
-       gi->type = va_arg(ap, unsigned long);
-       break;
-
-      case GDI_STATE:
-       gi->state = va_arg(ap, unsigned long);
-       break;
-
-      case GDI_CHECKED:
-       gi->checked = va_arg(ap, boolean);
-       break;
-
-      case GDI_RADIO_NR:
-       gi->radio_nr = va_arg(ap, unsigned long);
-       break;
-
-      case GDI_NUMBER_VALUE:
-       gi->text.number_value = va_arg(ap, long);
-       sprintf(gi->text.value, "%d", gi->text.number_value);
-       gi->text.cursor_position = strlen(gi->text.value);
-       break;
-
-      case GDI_NUMBER_MIN:
-       gi->text.number_min = va_arg(ap, long);
-       if (gi->text.number_value < gi->text.number_min)
-       {
-         gi->text.number_value = gi->text.number_min;
-         sprintf(gi->text.value, "%d", gi->text.number_value);
-       }
-       break;
-
-      case GDI_NUMBER_MAX:
-       gi->text.number_max = va_arg(ap, long);
-       if (gi->text.number_value > gi->text.number_max)
-       {
-         gi->text.number_value = gi->text.number_max;
-         sprintf(gi->text.value, "%d", gi->text.number_value);
-       }
-       break;
-
-      case GDI_TEXT_VALUE:
-       {
-         int max_textsize = MAX_GADGET_TEXTSIZE;
-
-         if (gi->text.size)
-           max_textsize = MIN(gi->text.size, MAX_GADGET_TEXTSIZE - 1);
-
-         strncpy(gi->text.value, va_arg(ap, char *), max_textsize);
-         gi->text.value[max_textsize] = '\0';
-         gi->text.cursor_position = strlen(gi->text.value);
-       }
-       break;
-
-      case GDI_TEXT_SIZE:
-       {
-         int tag_value = va_arg(ap, int);
-         int max_textsize = MIN(tag_value, MAX_GADGET_TEXTSIZE - 1);
-
-         gi->text.size = max_textsize;
-         gi->text.value[max_textsize] = '\0';
-       }
-       break;
-
-      case GDI_TEXT_FONT:
-       gi->text.font_type = va_arg(ap, int);
-       break;
-
-      case GDI_DESIGN_UNPRESSED:
-       gi->design[GD_BUTTON_UNPRESSED].bitmap = va_arg(ap, Bitmap);
-       gi->design[GD_BUTTON_UNPRESSED].x = va_arg(ap, int);
-       gi->design[GD_BUTTON_UNPRESSED].y = va_arg(ap, int);
-       break;
-
-      case GDI_DESIGN_PRESSED:
-       gi->design[GD_BUTTON_PRESSED].bitmap = va_arg(ap, Bitmap);
-       gi->design[GD_BUTTON_PRESSED].x = va_arg(ap, int);
-       gi->design[GD_BUTTON_PRESSED].y = va_arg(ap, int);
-       break;
-
-      case GDI_ALT_DESIGN_UNPRESSED:
-       gi->alt_design[GD_BUTTON_UNPRESSED].bitmap= va_arg(ap, Bitmap);
-       gi->alt_design[GD_BUTTON_UNPRESSED].x = va_arg(ap, int);
-       gi->alt_design[GD_BUTTON_UNPRESSED].y = va_arg(ap, int);
-       break;
-
-      case GDI_ALT_DESIGN_PRESSED:
-       gi->alt_design[GD_BUTTON_PRESSED].bitmap = va_arg(ap, Bitmap);
-       gi->alt_design[GD_BUTTON_PRESSED].x = va_arg(ap, int);
-       gi->alt_design[GD_BUTTON_PRESSED].y = va_arg(ap, int);
-       break;
-
-      case GDI_BORDER_SIZE:
-       gi->border.size = va_arg(ap, int);
-       break;
-
-      case GDI_TEXTINPUT_DESIGN_WIDTH:
-       gi->border.width = va_arg(ap, int);
-       break;
-
-      case GDI_DECORATION_DESIGN:
-       gi->deco.design.bitmap = va_arg(ap, Bitmap);
-       gi->deco.design.x = va_arg(ap, int);
-       gi->deco.design.y = va_arg(ap, int);
-       break;
-
-      case GDI_DECORATION_POSITION:
-       gi->deco.x = va_arg(ap, int);
-       gi->deco.y = va_arg(ap, int);
-       break;
-
-      case GDI_DECORATION_SIZE:
-       gi->deco.width = va_arg(ap, int);
-       gi->deco.height = va_arg(ap, int);
-       break;
-
-      case GDI_DECORATION_SHIFTING:
-       gi->deco.xshift = va_arg(ap, int);
-       gi->deco.yshift = va_arg(ap, int);
-       break;
-
-      case GDI_EVENT_MASK:
-       gi->event_mask = va_arg(ap, unsigned long);
-       break;
-
-      case GDI_AREA_SIZE:
-       gi->drawing.area_xsize = va_arg(ap, int);
-       gi->drawing.area_ysize = va_arg(ap, int);
-
-       /* determine dependent values for drawing area gadget, if needed */
-       if (gi->width == 0 && gi->height == 0 &&
-           gi->drawing.item_xsize !=0 && gi->drawing.item_ysize !=0)
-       {
-         gi->width = gi->drawing.area_xsize * gi->drawing.item_xsize;
-         gi->height = gi->drawing.area_ysize * gi->drawing.item_ysize;
-       }
-       else if (gi->drawing.item_xsize == 0 && gi->drawing.item_ysize == 0 &&
-                gi->width != 0 && gi->height != 0)
-       {
-         gi->drawing.item_xsize = gi->width / gi->drawing.area_xsize;
-         gi->drawing.item_ysize = gi->height / gi->drawing.area_ysize;
-       }
-       break;
-
-      case GDI_ITEM_SIZE:
-       gi->drawing.item_xsize = va_arg(ap, int);
-       gi->drawing.item_ysize = va_arg(ap, int);
-
-       /* determine dependent values for drawing area gadget, if needed */
-       if (gi->width == 0 && gi->height == 0 &&
-           gi->drawing.area_xsize !=0 && gi->drawing.area_ysize !=0)
-       {
-         gi->width = gi->drawing.area_xsize * gi->drawing.item_xsize;
-         gi->height = gi->drawing.area_ysize * gi->drawing.item_ysize;
-       }
-       else if (gi->drawing.area_xsize == 0 && gi->drawing.area_ysize == 0 &&
-                gi->width != 0 && gi->height != 0)
-       {
-         gi->drawing.area_xsize = gi->width / gi->drawing.item_xsize;
-         gi->drawing.area_ysize = gi->height / gi->drawing.item_ysize;
-       }
-       break;
-
-      case GDI_SCROLLBAR_ITEMS_MAX:
-       gi->scrollbar.items_max = va_arg(ap, int);
-       break;
-
-      case GDI_SCROLLBAR_ITEMS_VISIBLE:
-       gi->scrollbar.items_visible = va_arg(ap, int);
-       break;
-
-      case GDI_SCROLLBAR_ITEM_POSITION:
-       gi->scrollbar.item_position = va_arg(ap, int);
-       break;
-
-      case GDI_CALLBACK_INFO:
-       gi->callback_info = va_arg(ap, gadget_function);
-       break;
-
-      case GDI_CALLBACK_ACTION:
-       gi->callback_action = va_arg(ap, gadget_function);
-       break;
-
-      default:
-       Error(ERR_EXIT, "HandleGadgetTags(): unknown tag %d", tag);
-    }
-
-    tag = va_arg(ap, int);     /* read next tag */
-  }
-
-  /* check if gadget complete */
-  if (gi->type != GD_TYPE_DRAWING_AREA &&
-      (!gi->design[GD_BUTTON_UNPRESSED].bitmap ||
-       !gi->design[GD_BUTTON_PRESSED].bitmap))
-    Error(ERR_EXIT, "gadget incomplete (missing Bitmap)");
-
-  /* adjust gadget values in relation to other gadget values */
-
-  if (gi->type & GD_TYPE_TEXTINPUT)
-  {
-    int font_width = getFontWidth(FS_SMALL, gi->text.font_type);
-    int font_height = getFontHeight(FS_SMALL, gi->text.font_type);
-
-    gi->width = 2 * gi->border.size + (gi->text.size + 1) * font_width;
-    gi->height = 2 * gi->border.size + font_height;
-  }
-
-  if (gi->type & GD_TYPE_TEXTINPUT_NUMERIC)
-  {
-    struct GadgetTextInput *text = &gi->text;
-    int value = text->number_value;
-
-    text->number_value = (value < text->number_min ? text->number_min :
-                         value > text->number_max ? text->number_max :
-                         value);
-
-    sprintf(text->value, "%d", text->number_value);
-  }
-
-  if (gi->type & GD_TYPE_SCROLLBAR)
-  {
-    struct GadgetScrollbar *gs = &gi->scrollbar;
-
-    if (gi->width == 0 || gi->height == 0 ||
-       gs->items_max == 0 || gs->items_visible == 0)
-      Error(ERR_EXIT, "scrollbar gadget incomplete (missing tags)");
-
-    /* calculate internal scrollbar values */
-    gs->size_max = (gi->type == GD_TYPE_SCROLLBAR_VERTICAL ?
-                   gi->height : gi->width);
-    gs->size = gs->size_max * gs->items_visible / gs->items_max;
-    gs->position = gs->size_max * gs->item_position / gs->items_max;
-    gs->position_max = gs->size_max - gs->size;
-    gs->correction = gs->size_max / gs->items_max / 2;
-
-    /* finetuning for maximal right/bottom position */
-    if (gs->item_position == gs->items_max - gs->items_visible)
-      gs->position = gs->position_max;
-  }
-}
-
-void ModifyGadget(struct GadgetInfo *gi, int first_tag, ...)
-{
-  va_list ap;
-
-  va_start(ap, first_tag);
-  HandleGadgetTags(gi, first_tag, ap);
-  va_end(ap);
-
-  RedrawGadget(gi);
-}
-
-void RedrawGadget(struct GadgetInfo *gi)
-{
-  if (gi->mapped)
-    DrawGadget(gi, gi->state, DG_DIRECT);
-}
-
-struct GadgetInfo *CreateGadget(int first_tag, ...)
-{
-  struct GadgetInfo *new_gadget = checked_malloc(sizeof(struct GadgetInfo));
-  va_list ap;
-
-  /* always start with reliable default values */
-  memset(new_gadget, 0, sizeof(struct GadgetInfo));    /* zero all fields */
-  new_gadget->id = getNewGadgetID();
-  new_gadget->callback_info = default_callback_info;
-  new_gadget->callback_action = default_callback_action;
-
-  va_start(ap, first_tag);
-  HandleGadgetTags(new_gadget, first_tag, ap);
-  va_end(ap);
-
-  /* insert new gadget into global gadget list */
-  if (gadget_list_last_entry)
-  {
-    gadget_list_last_entry->next = new_gadget;
-    gadget_list_last_entry = gadget_list_last_entry->next;
-  }
-  else
-    gadget_list_first_entry = gadget_list_last_entry = new_gadget;
-
-  return new_gadget;
-}
-
-void FreeGadget(struct GadgetInfo *gi)
-{
-  struct GadgetInfo *gi_previous = gadget_list_first_entry;
-
-  while (gi_previous && gi_previous->next != gi)
-    gi_previous = gi_previous->next;
-
-  if (gi == gadget_list_first_entry)
-    gadget_list_first_entry = gi->next;
-
-  if (gi == gadget_list_last_entry)
-    gadget_list_last_entry = gi_previous;
-
-  gi_previous->next = gi->next;
-  free(gi);
-}
-
-static void CheckRangeOfNumericInputGadget(struct GadgetInfo *gi)
-{
-  if (gi->type != GD_TYPE_TEXTINPUT_NUMERIC)
-    return;
-
-  gi->text.number_value = atoi(gi->text.value);
-
-  if (gi->text.number_value < gi->text.number_min)
-    gi->text.number_value = gi->text.number_min;
-  if (gi->text.number_value > gi->text.number_max)
-    gi->text.number_value = gi->text.number_max;
-
-  sprintf(gi->text.value, "%d", gi->text.number_value);
-
-  if (gi->text.cursor_position < 0)
-    gi->text.cursor_position = 0;
-  else if (gi->text.cursor_position > strlen(gi->text.value))
-    gi->text.cursor_position = strlen(gi->text.value);
-}
-
-/* global pointer to gadget actually in use (when mouse button pressed) */
-static struct GadgetInfo *last_gi = NULL;
-
-static void MapGadgetExt(struct GadgetInfo *gi, boolean redraw)
-{
-  if (gi == NULL || gi->mapped)
-    return;
-
-  gi->mapped = TRUE;
-
-  if (redraw)
-    DrawGadget(gi, DG_UNPRESSED, DG_BUFFERED);
-}
-
-void MapGadget(struct GadgetInfo *gi)
-{
-  MapGadgetExt(gi, TRUE);
-}
-
-void UnmapGadget(struct GadgetInfo *gi)
-{
-  if (gi == NULL || !gi->mapped)
-    return;
-
-  gi->mapped = FALSE;
-
-  if (gi == last_gi)
-    last_gi = NULL;
-}
-
-#define MAX_NUM_GADGETS                1024
-#define MULTIMAP_UNMAP         (1 << 0)
-#define MULTIMAP_REMAP         (1 << 1)
-#define MULTIMAP_REDRAW                (1 << 2)
-#define MULTIMAP_PLAYFIELD     (1 << 3)
-#define MULTIMAP_DOOR_1                (1 << 4)
-#define MULTIMAP_DOOR_2                (1 << 5)
-#define MULTIMAP_ALL           (MULTIMAP_PLAYFIELD | \
-                                MULTIMAP_DOOR_1 | \
-                                MULTIMAP_DOOR_2)
-
-static void MultiMapGadgets(int mode)
-{
-  struct GadgetInfo *gi = gadget_list_first_entry;
-  static boolean map_state[MAX_NUM_GADGETS];
-  int map_count = 0;
-
-  while (gi)
-  {
-    if ((mode & MULTIMAP_PLAYFIELD && gi->x < SX + SXSIZE) ||
-       (mode & MULTIMAP_DOOR_1 && gi->x >= DX && gi->y < DY + DYSIZE) ||
-       (mode & MULTIMAP_DOOR_2 && gi->x >= DX && gi->y > DY + DYSIZE) ||
-       (mode & MULTIMAP_ALL) == MULTIMAP_ALL)
-    {
-      if (mode & MULTIMAP_UNMAP)
-      {
-       map_state[map_count++ % MAX_NUM_GADGETS] = gi->mapped;
-       UnmapGadget(gi);
-      }
-      else
-      {
-       if (map_state[map_count++ % MAX_NUM_GADGETS])
-         MapGadgetExt(gi, (mode & MULTIMAP_REDRAW));
-      }
-    }
-
-    gi = gi->next;
-  }
-}
-
-void UnmapAllGadgets()
-{
-  MultiMapGadgets(MULTIMAP_ALL | MULTIMAP_UNMAP);
-}
-
-void RemapAllGadgets()
-{
-  MultiMapGadgets(MULTIMAP_ALL | MULTIMAP_REMAP);
-}
-
-boolean anyTextGadgetActive()
-{
-  return (last_gi && last_gi->type & GD_TYPE_TEXTINPUT && last_gi->mapped);
-}
-
-void ClickOnGadget(struct GadgetInfo *gi, int button)
-{
-  /* simulate releasing mouse button over last gadget, if still pressed */
-  if (button_status)
-    HandleGadgets(-1, -1, 0);
-
-  /* simulate pressing mouse button over specified gadget */
-  HandleGadgets(gi->x, gi->y, button);
-
-  /* simulate releasing mouse button over specified gadget */
-  HandleGadgets(gi->x, gi->y, 0);
-}
-
-void HandleGadgets(int mx, int my, int button)
-{
-  static struct GadgetInfo *last_info_gi = NULL;
-  static unsigned long pressed_delay = 0;
-  static int last_button = 0;
-  static int last_mx = 0, last_my = 0;
-  int scrollbar_mouse_pos = 0;
-  struct GadgetInfo *new_gi, *gi;
-  boolean press_event;
-  boolean release_event;
-  boolean mouse_moving;
-  boolean gadget_pressed;
-  boolean gadget_pressed_repeated;
-  boolean gadget_moving;
-  boolean gadget_moving_inside;
-  boolean gadget_moving_off_borders;
-  boolean gadget_released;
-  boolean gadget_released_inside;
-  boolean gadget_released_off_borders;
-  boolean changed_position = FALSE;
-
-  /* check if there are any gadgets defined */
-  if (gadget_list_first_entry == NULL)
-    return;
-
-  /* check which gadget is under the mouse pointer */
-  new_gi = getGadgetInfoFromMousePosition(mx, my);
-
-  /* check if button state has changed since last invocation */
-  press_event = (button != 0 && last_button == 0);
-  release_event = (button == 0 && last_button != 0);
-  last_button = button;
-
-  /* check if mouse has been moved since last invocation */
-  mouse_moving = ((mx != last_mx || my != last_my) && motion_status);
-  last_mx = mx;
-  last_my = my;
-
-  /* special treatment for text and number input gadgets */
-  if (anyTextGadgetActive() && button != 0 && !motion_status)
-  {
-    struct GadgetInfo *gi = last_gi;
-
-    if (new_gi == last_gi)
-    {
-      /* if mouse button pressed inside activated text gadget, set cursor */
-      gi->text.cursor_position =
-       (mx - gi->x - gi->border.size) /
-       getFontWidth(FS_SMALL, gi->text.font_type);
-
-      if (gi->text.cursor_position < 0)
-       gi->text.cursor_position = 0;
-      else if (gi->text.cursor_position > strlen(gi->text.value))
-       gi->text.cursor_position = strlen(gi->text.value);
-
-      DrawGadget(gi, DG_PRESSED, DG_DIRECT);
-    }
-    else
-    {
-      /* if mouse button pressed outside text input gadget, deactivate it */
-      CheckRangeOfNumericInputGadget(gi);
-      DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
-
-      gi->event.type = GD_EVENT_TEXT_LEAVING;
-
-      if (gi->event_mask & GD_EVENT_TEXT_LEAVING)
-       gi->callback_action(gi);
-
-      last_gi = NULL;
-    }
-  }
-
-  gadget_pressed =
-    (button != 0 && last_gi == NULL && new_gi != NULL && press_event);
-  gadget_pressed_repeated =
-    (button != 0 && last_gi != NULL && new_gi == last_gi);
-
-  gadget_released =            (release_event && last_gi != NULL);
-  gadget_released_inside =     (gadget_released && new_gi == last_gi);
-  gadget_released_off_borders =        (gadget_released && new_gi != last_gi);
-
-  gadget_moving =            (button != 0 && last_gi != NULL && mouse_moving);
-  gadget_moving_inside =      (gadget_moving && new_gi == last_gi);
-  gadget_moving_off_borders = (gadget_moving && new_gi != last_gi);
-
-  /* if new gadget pressed, store this gadget  */
-  if (gadget_pressed)
-    last_gi = new_gi;
-
-  /* 'gi' is actually handled gadget */
-  gi = last_gi;
-
-  /* if gadget is scrollbar, choose mouse position value */
-  if (gi && gi->type & GD_TYPE_SCROLLBAR)
-    scrollbar_mouse_pos =
-      (gi->type == GD_TYPE_SCROLLBAR_HORIZONTAL ? mx - gi->x : my - gi->y);
-
-  /* if mouse button released, no gadget needs to be handled anymore */
-  if (button == 0 && last_gi && !(last_gi->type & GD_TYPE_TEXTINPUT))
-    last_gi = NULL;
-
-  /* modify event position values even if no gadget is pressed */
-  if (button == 0 && !release_event)
-    gi = new_gi;
-
-  if (gi)
-  {
-    int last_x = gi->event.x;
-    int last_y = gi->event.y;
-
-    gi->event.x = mx - gi->x;
-    gi->event.y = my - gi->y;
-
-    if (gi->type == GD_TYPE_DRAWING_AREA)
-    {
-      gi->event.x /= gi->drawing.item_xsize;
-      gi->event.y /= gi->drawing.item_ysize;
-
-      if (last_x != gi->event.x || last_y != gi->event.y)
-       changed_position = TRUE;
-    }
-  }
-
-  /* handle gadget popup info text */
-  if (last_info_gi != new_gi ||
-      (new_gi && new_gi->type == GD_TYPE_DRAWING_AREA && changed_position))
-  {
-    last_info_gi = new_gi;
-
-    if (new_gi != NULL && (button == 0 || new_gi == last_gi))
-    {
-      new_gi->event.type = 0;
-      new_gi->callback_info(new_gi);
-    }
-    else
-      default_callback_info(NULL);
-  }
-
-  if (gadget_pressed)
-  {
-    if (gi->type == GD_TYPE_CHECK_BUTTON)
-    {
-      gi->checked = !gi->checked;
-    }
-    else if (gi->type == GD_TYPE_RADIO_BUTTON)
-    {
-      struct GadgetInfo *rgi = gadget_list_first_entry;
-
-      while (rgi)
-      {
-       if (rgi->mapped &&
-           rgi->type == GD_TYPE_RADIO_BUTTON &&
-           rgi->radio_nr == gi->radio_nr &&
-           rgi != gi)
-       {
-         rgi->checked = FALSE;
-         DrawGadget(rgi, DG_UNPRESSED, DG_DIRECT);
-       }
-
-       rgi = rgi->next;
-      }
-
-      gi->checked = TRUE;
-    }
-    else if (gi->type & GD_TYPE_SCROLLBAR)
-    {
-      int mpos, gpos;
-
-      if (gi->type == GD_TYPE_SCROLLBAR_HORIZONTAL)
-      {
-       mpos = mx;
-       gpos = gi->x;
-      }
-      else
-      {
-       mpos = my;
-       gpos = gi->y;
-      }
-
-      if (mpos >= gpos + gi->scrollbar.position &&
-         mpos < gpos + gi->scrollbar.position + gi->scrollbar.size)
-      {
-       /* drag scrollbar */
-       gi->scrollbar.drag_position =
-         scrollbar_mouse_pos - gi->scrollbar.position;
-      }
-      else
-      {
-       /* click scrollbar one scrollbar length up/left or down/right */
-
-       struct GadgetScrollbar *gs = &gi->scrollbar;
-       int old_item_position = gs->item_position;
-
-       changed_position = FALSE;
-
-       gs->item_position +=
-         gs->items_visible * (mpos < gpos + gi->scrollbar.position ? -1 : +1);
-
-       if (gs->item_position < 0)
-         gs->item_position = 0;
-       if (gs->item_position > gs->items_max - gs->items_visible)
-         gs->item_position = gs->items_max - gs->items_visible;
-
-       if (old_item_position != gs->item_position)
-       {
-         gi->event.item_position = gs->item_position;
-         changed_position = TRUE;
-       }
-
-       ModifyGadget(gi, GDI_SCROLLBAR_ITEM_POSITION, gs->item_position,
-                    GDI_END);
-
-       gi->state = GD_BUTTON_UNPRESSED;
-       gi->event.type = GD_EVENT_MOVING;
-       gi->event.off_borders = FALSE;
-
-       if (gi->event_mask & GD_EVENT_MOVING && changed_position)
-         gi->callback_action(gi);
-
-       /* don't handle this scrollbar anymore while mouse button pressed */
-       last_gi = NULL;
-
-       return;
-      }
-    }
-
-    DrawGadget(gi, DG_PRESSED, DG_DIRECT);
-
-    gi->state = GD_BUTTON_PRESSED;
-    gi->event.type = GD_EVENT_PRESSED;
-    gi->event.button = button;
-    gi->event.off_borders = FALSE;
-
-    /* initialize delay counter */
-    DelayReached(&pressed_delay, 0);
-
-    if (gi->event_mask & GD_EVENT_PRESSED)
-      gi->callback_action(gi);
-  }
-
-  if (gadget_pressed_repeated)
-  {
-    gi->event.type = GD_EVENT_PRESSED;
-
-    if (gi->event_mask & GD_EVENT_REPEATED &&
-       DelayReached(&pressed_delay, GADGET_FRAME_DELAY))
-      gi->callback_action(gi);
-  }
-
-  if (gadget_moving)
-  {
-    if (gi->type & GD_TYPE_BUTTON)
-    {
-      if (gadget_moving_inside && gi->state == GD_BUTTON_UNPRESSED)
-       DrawGadget(gi, DG_PRESSED, DG_DIRECT);
-      else if (gadget_moving_off_borders && gi->state == GD_BUTTON_PRESSED)
-       DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
-    }
-
-    if (gi->type & GD_TYPE_SCROLLBAR)
-    {
-      struct GadgetScrollbar *gs = &gi->scrollbar;
-      int old_item_position = gs->item_position;
-
-      gs->position = scrollbar_mouse_pos - gs->drag_position;
-
-      if (gs->position < 0)
-       gs->position = 0;
-      if (gs->position > gs->position_max)
-       gs->position = gs->position_max;
-
-      gs->item_position =
-       gs->items_max * (gs->position + gs->correction) / gs->size_max;
-
-      if (gs->item_position < 0)
-       gs->item_position = 0;
-      if (gs->item_position > gs->items_max - 1)
-       gs->item_position = gs->items_max - 1;
-
-      if (old_item_position != gs->item_position)
-      {
-       gi->event.item_position = gs->item_position;
-       changed_position = TRUE;
-      }
-
-      DrawGadget(gi, DG_PRESSED, DG_DIRECT);
-    }
-
-    gi->state = (gadget_moving_inside || gi->type & GD_TYPE_SCROLLBAR ?
-                GD_BUTTON_PRESSED : GD_BUTTON_UNPRESSED);
-    gi->event.type = GD_EVENT_MOVING;
-    gi->event.off_borders = gadget_moving_off_borders;
-
-    if (gi->event_mask & GD_EVENT_MOVING && changed_position &&
-       (gadget_moving_inside || gi->event_mask & GD_EVENT_OFF_BORDERS))
-      gi->callback_action(gi);
-  }
-
-  if (gadget_released_inside)
-  {
-    if (!(gi->type & GD_TYPE_TEXTINPUT))
-      DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
-
-    gi->state = GD_BUTTON_UNPRESSED;
-    gi->event.type = GD_EVENT_RELEASED;
-
-    if (gi->event_mask & GD_EVENT_RELEASED)
-      gi->callback_action(gi);
-  }
-
-  if (gadget_released_off_borders)
-  {
-    if (gi->type & GD_TYPE_SCROLLBAR)
-      DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
-
-    gi->event.type = GD_EVENT_RELEASED;
-
-    if (gi->event_mask & GD_EVENT_RELEASED &&
-       gi->event_mask & GD_EVENT_OFF_BORDERS)
-      gi->callback_action(gi);
-  }
-}
-
-void HandleGadgetsKeyInput(Key key)
-{
-  struct GadgetInfo *gi = last_gi;
-  char text[MAX_GADGET_TEXTSIZE];
-  int text_length;
-  int cursor_pos;
-  char letter;
-  boolean legal_letter;
-
-  if (gi == NULL || !(gi->type & GD_TYPE_TEXTINPUT) || !gi->mapped)
-    return;
-
-  text_length = strlen(gi->text.value);
-  cursor_pos = gi->text.cursor_position;
-  letter = getCharFromKey(key);
-  legal_letter = (gi->type == GD_TYPE_TEXTINPUT_NUMERIC ?
-                 letter >= '0' && letter <= '9' :
-                 letter != 0);
-
-  if (legal_letter && text_length < gi->text.size)
-  {
-    strcpy(text, gi->text.value);
-    strcpy(&gi->text.value[cursor_pos + 1], &text[cursor_pos]);
-    gi->text.value[cursor_pos] = letter;
-    gi->text.cursor_position++;
-    DrawGadget(gi, DG_PRESSED, DG_DIRECT);
-  }
-  else if (key == KSYM_Left && cursor_pos > 0)
-  {
-    gi->text.cursor_position--;
-    DrawGadget(gi, DG_PRESSED, DG_DIRECT);
-  }
-  else if (key == KSYM_Right && cursor_pos < text_length)
-  {
-    gi->text.cursor_position++;
-    DrawGadget(gi, DG_PRESSED, DG_DIRECT);
-  }
-  else if (key == KSYM_BackSpace && cursor_pos > 0)
-  {
-    strcpy(text, gi->text.value);
-    strcpy(&gi->text.value[cursor_pos - 1], &text[cursor_pos]);
-    gi->text.cursor_position--;
-    DrawGadget(gi, DG_PRESSED, DG_DIRECT);
-  }
-  else if (key == KSYM_Delete && cursor_pos < text_length)
-  {
-    strcpy(text, gi->text.value);
-    strcpy(&gi->text.value[cursor_pos], &text[cursor_pos + 1]);
-    DrawGadget(gi, DG_PRESSED, DG_DIRECT);
-  }
-  else if (key == KSYM_Return)
-  {
-    CheckRangeOfNumericInputGadget(gi);
-    DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
-
-    gi->event.type = GD_EVENT_TEXT_RETURN;
-
-    if (gi->event_mask & GD_EVENT_TEXT_RETURN)
-      gi->callback_action(gi);
-
-    last_gi = NULL;
-  }
-}
diff --git a/src/buttons.h b/src/buttons.h
deleted file mode 100644 (file)
index 368fa9e..0000000
+++ /dev/null
@@ -1,265 +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                *
-*----------------------------------------------------------*
-*  buttons.h                                               *
-***********************************************************/
-
-#ifndef BUTTONS_H
-#define BUTTONS_H
-
-#include "main.h"
-
-/* the following definitions are also used by tools.c */
-
-/* some positions in the video tape control window */
-#define VIDEO_DISPLAY1_XPOS    5
-#define VIDEO_DISPLAY1_YPOS    5
-#define VIDEO_DISPLAY2_XPOS    5
-#define VIDEO_DISPLAY2_YPOS    41
-#define VIDEO_DISPLAY_XSIZE    90
-#define VIDEO_DISPLAY_YSIZE    31
-#define VIDEO_BUTTON_XSIZE     18
-#define VIDEO_BUTTON_YSIZE     18
-#define VIDEO_CONTROL_XPOS     5
-#define VIDEO_CONTROL_YPOS     77
-#define VIDEO_CONTROL_XSIZE    VIDEO_DISPLAY_XSIZE
-#define VIDEO_CONTROL_YSIZE    VIDEO_BUTTON_YSIZE
-
-/* values for video tape control */
-#define VIDEO_STATE_PLAY_OFF   (1L << 0)
-#define VIDEO_STATE_PLAY_ON    (1L << 1)
-#define VIDEO_STATE_PLAY       (VIDEO_STATE_PLAY_OFF   | VIDEO_STATE_PLAY_ON)
-#define VIDEO_STATE_REC_OFF    (1L << 2)
-#define VIDEO_STATE_REC_ON     (1L << 3)
-#define VIDEO_STATE_REC                (VIDEO_STATE_REC_OFF    | VIDEO_STATE_REC_ON)
-#define VIDEO_STATE_PAUSE_OFF  (1L << 4)
-#define VIDEO_STATE_PAUSE_ON   (1L << 5)
-#define VIDEO_STATE_PAUSE      (VIDEO_STATE_PAUSE_OFF  | VIDEO_STATE_PAUSE_ON)
-#define VIDEO_STATE_DATE_OFF   (1L << 6)
-#define VIDEO_STATE_DATE_ON    (1L << 7)
-#define VIDEO_STATE_DATE       (VIDEO_STATE_DATE_OFF   | VIDEO_STATE_DATE_ON)
-#define VIDEO_STATE_TIME_OFF   (1L << 8)
-#define VIDEO_STATE_TIME_ON    (1L << 9)
-#define VIDEO_STATE_TIME       (VIDEO_STATE_TIME_OFF   | VIDEO_STATE_TIME_ON)
-#define VIDEO_PRESS_PLAY_ON    (1L << 10)
-#define VIDEO_PRESS_PLAY_OFF   (1L << 11)
-#define VIDEO_PRESS_PLAY       (VIDEO_PRESS_PLAY_OFF   | VIDEO_PRESS_PLAY_ON)
-#define VIDEO_PRESS_REC_ON     (1L << 12)
-#define VIDEO_PRESS_REC_OFF    (1L << 13)
-#define VIDEO_PRESS_REC                (VIDEO_PRESS_REC_OFF    | VIDEO_PRESS_REC_ON)
-#define VIDEO_PRESS_PAUSE_ON   (1L << 14)
-#define VIDEO_PRESS_PAUSE_OFF  (1L << 15)
-#define VIDEO_PRESS_PAUSE      (VIDEO_PRESS_PAUSE_OFF  | VIDEO_PRESS_PAUSE_ON)
-#define VIDEO_PRESS_STOP_ON    (1L << 16)
-#define VIDEO_PRESS_STOP_OFF   (1L << 17)
-#define VIDEO_PRESS_STOP       (VIDEO_PRESS_STOP_OFF   | VIDEO_PRESS_STOP_ON)
-#define VIDEO_PRESS_EJECT_ON   (1L << 18)
-#define VIDEO_PRESS_EJECT_OFF  (1L << 19)
-#define VIDEO_PRESS_EJECT      (VIDEO_PRESS_EJECT_OFF  | VIDEO_PRESS_EJECT_ON)
-
-/* special */
-#define VIDEO_STATE_FFWD_OFF   ((1L << 20) | VIDEO_STATE_PAUSE_OFF)
-#define VIDEO_STATE_FFWD_ON    (1L << 21)
-#define VIDEO_STATE_FFWD       (VIDEO_STATE_FFWD_OFF   | VIDEO_STATE_FFWD_ON)
-#define VIDEO_STATE_PBEND_OFF  (1L << 22)
-#define VIDEO_STATE_PBEND_ON   (1L << 23)
-#define VIDEO_STATE_PBEND      (VIDEO_STATE_PBEND_OFF  | VIDEO_STATE_PBEND_ON)
-
-/* tags to draw video display labels or symbols only */
-#define VIDEO_DISPLAY_DEFAULT          0
-#define VIDEO_DISPLAY_LABEL_ONLY       1
-#define VIDEO_DISPLAY_SYMBOL_ONLY      2
-
-void DrawVideoDisplay(unsigned long, unsigned long);
-void DrawCompleteVideoDisplay(void);
-
-
-/* NEW GADGET STUFF -------------------------------------------------------- */
-
-/* gadget types */
-#define GD_TYPE_NORMAL_BUTTON          (1 << 0)
-#define GD_TYPE_CHECK_BUTTON           (1 << 1)
-#define GD_TYPE_RADIO_BUTTON           (1 << 2)
-#define GD_TYPE_DRAWING_AREA           (1 << 3)
-#define GD_TYPE_TEXTINPUT_ALPHANUMERIC (1 << 4)
-#define GD_TYPE_TEXTINPUT_NUMERIC      (1 << 5)
-#define GD_TYPE_SCROLLBAR_VERTICAL     (1 << 6)
-#define GD_TYPE_SCROLLBAR_HORIZONTAL   (1 << 7)
-
-#define GD_TYPE_BUTTON                 (GD_TYPE_NORMAL_BUTTON | \
-                                        GD_TYPE_CHECK_BUTTON | \
-                                        GD_TYPE_RADIO_BUTTON)
-#define GD_TYPE_SCROLLBAR              (GD_TYPE_SCROLLBAR_VERTICAL | \
-                                        GD_TYPE_SCROLLBAR_HORIZONTAL)
-#define GD_TYPE_TEXTINPUT              (GD_TYPE_TEXTINPUT_ALPHANUMERIC | \
-                                        GD_TYPE_TEXTINPUT_NUMERIC)
-
-/* gadget events */
-#define GD_EVENT_PRESSED               (1 << 0)
-#define GD_EVENT_RELEASED              (1 << 1)
-#define GD_EVENT_MOVING                        (1 << 2)
-#define GD_EVENT_REPEATED              (1 << 3)
-#define GD_EVENT_OFF_BORDERS           (1 << 4)
-#define GD_EVENT_TEXT_RETURN           (1 << 5)
-#define GD_EVENT_TEXT_LEAVING          (1 << 6)
-
-/* gadget button states */
-#define GD_BUTTON_UNPRESSED            0
-#define GD_BUTTON_PRESSED              1
-
-/* gadget structure constants */
-#define MAX_GADGET_TEXTSIZE            1024
-#define MAX_INFO_TEXTSIZE              1024
-
-/* gadget creation tags */
-#define GDI_END                                0
-#define GDI_CUSTOM_ID                  1
-#define GDI_CUSTOM_TYPE_ID             2
-#define GDI_X                          3
-#define GDI_Y                          4
-#define GDI_WIDTH                      5
-#define GDI_HEIGHT                     6
-#define GDI_TYPE                       7
-#define GDI_STATE                      8
-#define GDI_CHECKED                    9
-#define GDI_RADIO_NR                   10
-#define GDI_NUMBER_VALUE               11
-#define GDI_NUMBER_MIN                 12
-#define GDI_NUMBER_MAX                 13
-#define GDI_TEXT_VALUE                 14
-#define GDI_TEXT_SIZE                  15
-#define GDI_TEXT_FONT                  16
-#define GDI_DESIGN_UNPRESSED           17
-#define GDI_DESIGN_PRESSED             18
-#define GDI_ALT_DESIGN_UNPRESSED       19
-#define GDI_ALT_DESIGN_PRESSED         20
-#define GDI_BORDER_SIZE                        21
-#define GDI_TEXTINPUT_DESIGN_WIDTH     22
-#define GDI_DECORATION_DESIGN          23
-#define GDI_DECORATION_POSITION                24
-#define GDI_DECORATION_SIZE            25
-#define GDI_DECORATION_SHIFTING                26
-#define GDI_EVENT_MASK                 27
-#define GDI_EVENT                      28
-#define GDI_CALLBACK_INFO              29
-#define GDI_CALLBACK_ACTION            30
-#define GDI_AREA_SIZE                  31
-#define GDI_ITEM_SIZE                  32
-#define GDI_SCROLLBAR_ITEMS_MAX                33
-#define GDI_SCROLLBAR_ITEMS_VISIBLE    34
-#define GDI_SCROLLBAR_ITEM_POSITION    35
-#define GDI_INFO_TEXT                  36
-
-typedef void (*gadget_function)(void *);
-
-struct GadgetBorder
-{
-  int size;                            /* size of gadget border */
-  int width;                           /* for text input gadgets */
-};
-
-struct GadgetDesign
-{
-  Bitmap bitmap;                       /* Bitmap with gadget surface */
-  int x, y;                            /* position of rectangle in Bitmap */
-};
-
-struct GadgetDecoration
-{
-  struct GadgetDesign design;          /* decoration design structure */
-  int x, y;                            /* position of deco on the gadget */
-  int width, height;                   /* width and height of decoration */
-  int xshift, yshift;                  /* deco shifting when gadget pressed */
-};
-
-struct GadgetEvent
-{
-  unsigned long type;                  /* event type */
-  int button;                          /* button number for button events */
-  int x, y;                            /* gadget position at event time */
-  boolean off_borders;                 /* mouse pointer outside gadget? */
-  int item_x, item_y, item_position;   /* new item position */
-};
-
-struct GadgetDrawingArea
-{
-  int area_xsize, area_ysize;          /* size of drawing area (in items) */
-  int item_xsize, item_ysize;          /* size of each item in drawing area */
-};
-
-struct GadgetTextInput
-{
-  char value[MAX_GADGET_TEXTSIZE];     /* text string in input field */
-  int number_value;                    /* integer value, if numeric */
-  int number_min;                      /* minimal allowed numeric value */
-  int number_max;                      /* maximal allowed numeric value */
-  int size;                            /* maximal size of input text */
-  int cursor_position;                 /* actual cursor position */
-  int font_type;                       /* font to use for text input */
-};
-
-struct GadgetScrollbar
-{
-  int items_max;                       /* number of items to access */
-  int items_visible;                   /* number of visible items */
-  int item_position;                   /* actual item position */
-  int size_max;                                /* this is either width or height */
-  int size;                            /* scrollbar size on screen */
-  int position;                                /* scrollbar position on screen */
-  int position_max;                    /* bottom/right scrollbar position */
-  int drag_position;                   /* drag position on scrollbar */
-  int correction;                      /* scrollbar position correction */
-};
-
-struct GadgetInfo
-{
-  int id;                              /* internal gadget identifier */
-  int custom_id;                       /* custom gadget identifier */
-  int custom_type_id;                  /* custom gadget type identifier */
-  char info_text[MAX_INFO_TEXTSIZE];   /* short popup info text */
-  int x, y;                            /* gadget position */
-  int width, height;                   /* gadget size */
-  unsigned long type;                  /* type (button, text input, ...) */
-  unsigned long state;                 /* state (pressed, released, ...) */
-  boolean checked;                     /* check/radio button state */
-  int radio_nr;                                /* number of radio button series */
-  boolean mapped;                      /* gadget is active */
-  struct GadgetBorder border;          /* gadget border design */
-  struct GadgetDesign design[2];       /* 0: normal; 1: pressed */
-  struct GadgetDesign alt_design[2];   /* alternative design */
-  struct GadgetDecoration deco;                /* decoration on top of gadget */
-  unsigned long event_mask;            /* possible events for this gadget */
-  struct GadgetEvent event;            /* actual gadget event */
-  gadget_function callback_info;       /* function for pop-up info text */
-  gadget_function callback_action;     /* function for gadget action */
-  struct GadgetDrawingArea drawing;    /* fields for drawing area gadget */
-  struct GadgetTextInput text;         /* fields for text input gadget */
-  struct GadgetScrollbar scrollbar;    /* fields for scrollbar gadget */
-  struct GadgetInfo *next;             /* next list entry */
-};
-
-struct GadgetInfo *CreateGadget(int, ...);
-void FreeGadget(struct GadgetInfo *);
-
-void ModifyGadget(struct GadgetInfo *, int, ...);
-void RedrawGadget(struct GadgetInfo *);
-
-void MapGadget(struct GadgetInfo *);
-void UnmapGadget(struct GadgetInfo *);
-void UnmapAllGadgets();
-void RemapAllGadgets();
-
-boolean anyTextGadgetActive();
-void ClickOnGadget(struct GadgetInfo *, int);
-
-void HandleGadgets(int, int, int);
-void HandleGadgetsKeyInput(Key);
-
-#endif
index 3290331e5a74fcc1a46705cbc2829365e8f1d42a..b3a639a37bf07b0445193791acf9db9107192284 100644 (file)
 *  cartoons.c                                              *
 ***********************************************************/
 
+#include "libgame/libgame.h"
+
 #include "cartoons.h"
 #include "main.h"
-#include "misc.h"
 #include "tools.h"
 
 static void HandleAnimation(int);
index 0977a92a6dbb97b4161369f7ccb0425dfa9cd903..2ed164c15ec99eb84680e3b201834b7c73480dc5 100644 (file)
 
 #include <math.h>
 
+#include "libgame/libgame.h"
+
 #include "editor.h"
 #include "screens.h"
 #include "tools.h"
-#include "misc.h"
-#include "buttons.h"
 #include "files.h"
 #include "game.h"
 #include "tape.h"
@@ -1394,6 +1394,7 @@ static void CreateControlButtons()
                      GDI_ALT_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y2,
                      GDI_ALT_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2,
                      GDI_EVENT_MASK, event_mask,
+                     GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
                      GDI_CALLBACK_ACTION, HandleControlButtons,
                      GDI_END);
 
@@ -1451,6 +1452,7 @@ static void CreateControlButtons()
                      GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y1,
                      GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2,
                      GDI_EVENT_MASK, event_mask,
+                     GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
                      GDI_CALLBACK_ACTION, HandleControlButtons,
                      GDI_END);
 
@@ -1501,6 +1503,7 @@ static void CreateControlButtons()
                      GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
                      GDI_DECORATION_SHIFTING, 1, 1,
                      GDI_EVENT_MASK, event_mask,
+                     GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
                      GDI_CALLBACK_ACTION, HandleControlButtons,
                      GDI_END);
 
@@ -1579,6 +1582,7 @@ static void CreateCounterButtons()
                        GDI_DESIGN_UNPRESSED, gd_bitmap, gd_x1, gd_y,
                        GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y,
                        GDI_EVENT_MASK, event_mask,
+                       GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
                        GDI_CALLBACK_ACTION, HandleCounterButtons,
                        GDI_END);
 
@@ -1629,6 +1633,7 @@ static void CreateCounterButtons()
                          GDI_BORDER_SIZE, ED_BORDER_SIZE,
                          GDI_TEXTINPUT_DESIGN_WIDTH, gd_width,
                          GDI_EVENT_MASK, event_mask,
+                         GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
                          GDI_CALLBACK_ACTION, HandleCounterButtons,
                          GDI_END);
 
@@ -1772,6 +1777,7 @@ static void CreateTextInputGadgets()
                      GDI_BORDER_SIZE, ED_BORDER_SIZE,
                      GDI_TEXTINPUT_DESIGN_WIDTH, ED_WIN_COUNT_XSIZE,
                      GDI_EVENT_MASK, event_mask,
+                     GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
                      GDI_CALLBACK_ACTION, HandleTextInputGadgets,
                      GDI_END);
 
@@ -1841,6 +1847,7 @@ static void CreateScrollbarGadgets()
                      GDI_DESIGN_PRESSED, gd_bitmap, gd_x2, gd_y2,
                      GDI_BORDER_SIZE, ED_BORDER_SIZE,
                      GDI_EVENT_MASK, event_mask,
+                     GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
                      GDI_CALLBACK_ACTION, HandleControlButtons,
                      GDI_END);
 
@@ -1890,6 +1897,7 @@ static void CreateCheckbuttonGadgets()
                      GDI_ALT_DESIGN_UNPRESSED, gd_bitmap, gd_x3, gd_y,
                      GDI_ALT_DESIGN_PRESSED, gd_bitmap, gd_x4, gd_y,
                      GDI_EVENT_MASK, event_mask,
+                     GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
                      GDI_CALLBACK_ACTION, HandleRadiobuttons,
                      GDI_END);
 
@@ -1922,6 +1930,7 @@ static void CreateCheckbuttonGadgets()
                      GDI_ALT_DESIGN_UNPRESSED, gd_bitmap, gd_x3, gd_y,
                      GDI_ALT_DESIGN_PRESSED, gd_bitmap, gd_x4, gd_y,
                      GDI_EVENT_MASK, event_mask,
+                     GDI_CALLBACK_INFO, HandleEditorGadgetInfoText,
                      GDI_CALLBACK_ACTION, HandleCheckbuttons,
                      GDI_END);
 
@@ -4048,6 +4057,9 @@ void HandleEditorGadgetInfoText(void *ptr)
   char infotext[MAX_INFOTEXT_LEN + 1];
   char shortcut[MAX_INFOTEXT_LEN + 1];
 
+  if (game_status != LEVELED)
+    return;
+
   ClearEditorGadgetInfoText();
 
   /* misuse this function to delete brush cursor, if needed */
index 95d3752203352663e0def25858d35f4a4fa6c53b..604345d90f07054d1639ee0f285d45c1123547db 100644 (file)
 *  events.c                                                *
 ***********************************************************/
 
+#include "libgame/libgame.h"
+
 #include "events.h"
 #include "init.h"
 #include "screens.h"
 #include "tools.h"
 #include "game.h"
 #include "editor.h"
-#include "misc.h"
 #include "tape.h"
 #include "joystick.h"
-#include "buttons.h"
 #include "network.h"
 
 /* values for key_status */
index 42f7a9930dad5b2ca4fe93ad44a10f5078fb7548..f8bbea80a85ffde79aaacdc092af0171e55117f8 100644 (file)
 #include <dirent.h>
 #include <sys/stat.h>
 
+#include "libgame/libgame.h"
+
 #include "files.h"
 #include "tools.h"
-#include "misc.h"
 #include "tape.h"
 #include "joystick.h"
 
index 670f8cb14a19a29e0ce6bbfe04483b2790c0d1a9..1f39cd8f6da96adf4d024d849c036cf667d6add5 100644 (file)
 *  game.c                                                  *
 ***********************************************************/
 
+#include "libgame/libgame.h"
+
 #include "game.h"
-#include "misc.h"
 #include "tools.h"
 #include "screens.h"
-#include "sound.h"
 #include "init.h"
-#include "buttons.h"
 #include "files.h"
 #include "tape.h"
 #include "joystick.h"
@@ -176,7 +175,7 @@ void GetPlayerConfig()
     setup.sound_music = FALSE;
   }
 
-  if (!fullscreen_available)
+  if (!video.fullscreen_available)
     setup.fullscreen = FALSE;
 
   setup.sound_simple = setup.sound;
diff --git a/src/image.c b/src/image.c
deleted file mode 100644 (file)
index 9dd4c24..0000000
+++ /dev/null
@@ -1,554 +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                *
-*----------------------------------------------------------*
-*  image.c                                                 *
-***********************************************************/
-
-#if defined(TARGET_X11)
-
-#include "image.h"
-#include "pcx.h"
-#include "misc.h"
-
-/* for MS-DOS/Allegro, exclude all except newImage() and freeImage() */
-
-Image *newImage(unsigned int width, unsigned int height, unsigned int depth)
-{
-  Image *image;
-  const unsigned int bytes_per_pixel = 1;
-  int i;
-
-  if (depth > 8)
-    Error(ERR_EXIT, "images with more than 256 colors are not supported");
-
-  depth = 8;
-  image = checked_malloc(sizeof(Image));
-  image->data = checked_malloc(width * height * bytes_per_pixel);
-  image->width = width;
-  image->height = height;
-  image->depth = depth;
-  image->rgb.used = 0;
-  for (i=0; i<MAX_COLORS; i++)
-    image->rgb.color_used[i] = FALSE;
-
-  return image;
-}
-
-void freeImage(Image *image)
-{
-  free(image->data);
-  free(image);
-}
-
-#if defined(PLATFORM_UNIX)
-
-/* extra colors to try allocating in private color maps to minimize flashing */
-#define NOFLASH_COLORS 256
-
-/* architecture independent value-to-memory conversion
-   note: the internal format is big endian */
-
-#define value_to_memory(value, ptr, length) (                          \
-(length) == 1 ? (*( (byte *)(ptr)   ) = ( value     ) ) :              \
-(length) == 2 ? (*( (byte *)(ptr)   ) = (((unsigned long)(value))>> 8),        \
-                *(((byte *)(ptr))+1) = ( value     ) ) :               \
-(length) == 3 ? (*( (byte *)(ptr)   ) = (((unsigned long)(value))>>16),        \
-                *(((byte *)(ptr))+1) = (((unsigned long)(value))>> 8), \
-                *(((byte *)(ptr))+2) = ( value     ) ) :               \
-                (*( (byte *)(ptr)   ) = (((unsigned long)(value))>>24),        \
-                *(((byte *)(ptr))+1) = (((unsigned long)(value))>>16), \
-                *(((byte *)(ptr))+2) = (((unsigned long)(value))>> 8), \
-                *(((byte *)(ptr))+3) = ( value     ) ))
-
-static Pixmap Image_to_Mask(Image *image, Display *display, Window window)
-{
-  byte *src_ptr, *dst_ptr, *dst_ptr2;
-  unsigned int bytes_per_row;
-  unsigned int x, y;
-  byte bitmask;
-  byte *mask_data;
-  Pixmap mask_pixmap;
-
-  bytes_per_row = (image->width + 7) / 8;
-  mask_data = checked_calloc(bytes_per_row * image->height);
-
-  src_ptr = image->data;
-  dst_ptr = mask_data;
-
-  /* create bitmap data which can be used by 'XCreateBitmapFromData()'
-   * directly to create a pixmap of depth 1 for use as a clip mask for
-   * the corresponding image pixmap
-   */
-
-  for (y=0; y<image->height; y++)
-  {
-    bitmask = 0x01;            /* start with leftmost bit in the byte     */
-    dst_ptr2 = dst_ptr;                /* start with leftmost byte in the row     */
-
-    for (x=0; x<image->width; x++)
-    {
-      if (*src_ptr++)          /* source pixel solid? (pixel index != 0)  */
-       *dst_ptr2 |= bitmask;   /* then write a bit into the image mask    */
-
-      if ((bitmask <<= 1) == 0)        /* bit at rightmost byte position reached? */
-      {
-       bitmask = 0x01;         /* start again with leftmost bit position  */
-       dst_ptr2++;             /* continue with next byte in image mask   */
-      }
-    }
-
-    dst_ptr += bytes_per_row;  /* continue with leftmost byte of next row */
-  }
-
-  mask_pixmap = XCreateBitmapFromData(display, window, (char *)mask_data,
-                                     image->width, image->height);
-  free(mask_data);
-
-  return mask_pixmap;
-}
-
-static int bitsPerPixelAtDepth(Display *display, int screen, int depth)
-{
-  XPixmapFormatValues *pixmap_format;
-  int i, num_pixmap_formats, bits_per_pixel = -1;
-
-  /* get Pixmap formats supported by the X server */
-  pixmap_format = XListPixmapFormats(display, &num_pixmap_formats);
-
-  /* find format that matches the given depth */
-  for (i=0; i<num_pixmap_formats; i++)
-    if (pixmap_format[i].depth == depth)
-      bits_per_pixel = pixmap_format[i].bits_per_pixel;
-
-  XFree(pixmap_format);
-
-  if (bits_per_pixel == -1)
-    Error(ERR_EXIT, "cannot find pixmap format for depth %d", depth);
-
-  return bits_per_pixel;
-}
-
-XImageInfo *Image_to_Pixmap(Display *display, int screen, Visual *visual,
-                           Window window, GC gc, int depth, 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 boolean private_cmap = FALSE;
-  Pixel *redvalue, *greenvalue, *bluevalue;
-  unsigned int a, c = 0, x, y, bytes_per_pixel, bits_per_pixel;
-  XColor xcolor;
-  XImage *ximage;
-  XImageInfo *ximageinfo;
-  byte *src_ptr, *dst_ptr;
-
-  if (!global_cmap)
-  {
-    if (visual == DefaultVisual(display, screen))
-      global_cmap = DefaultColormap(display, screen);
-    else
-    {
-      global_cmap = XCreateColormap(display, RootWindow(display, screen),
-                                   visual, AllocNone);
-      private_cmap = TRUE;
-    }
-  }
-
-  xcolor.flags = DoRed | DoGreen | DoBlue;
-  redvalue = greenvalue = bluevalue = NULL;
-  ximageinfo = checked_malloc(sizeof(XImageInfo));
-  ximageinfo->display = display;
-  ximageinfo->depth = depth;
-
-  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 *)checked_malloc(sizeof(Pixel) * 256);
-      greenvalue = (Pixel *)checked_malloc(sizeof(Pixel) * 256);
-      bluevalue = (Pixel *)checked_malloc(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;
-      }
-      
-      /* consistency check */
-      if (redcolors > visual->map_entries ||
-         greencolors > visual->map_entries ||
-         bluecolors > visual->map_entries)
-       Error(ERR_WARN, "inconsistency in color information");
-
-      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(display, 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(display, screen)))
-         {
-           global_cmap = XCopyColormapAndFree(display, 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(redvalue);
-          free(greenvalue);
-          free(bluevalue);
-          free(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;
-
-      for (a=0; a<MAX_COLORS; a++)
-      {
-       XColor xcolor2;
-       unsigned short mask;
-       int color_found;
-       int i;
-
-       if (!image->rgb.color_used[a])
-         continue;
-
-       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(display, ximageinfo->cmap, &xcolor))
-       {
-         if (!private_cmap)
-         {
-           if (options.verbose)
-             Error(ERR_RETURN, "switching to private colormap");
-
-           /* we just filled up the default colormap -- get a private one
-              which contains all already allocated colors */
-
-           global_cmap = XCopyColormapAndFree(display, global_cmap);
-           ximageinfo->cmap = global_cmap;
-           private_cmap = TRUE;
-
-           /* allocate the rest of the color cells read/write */
-           global_cmap_index =
-             (Pixel *)checked_malloc(sizeof(Pixel) * NOFLASH_COLORS);
-           for (i=0; i<NOFLASH_COLORS; i++)
-             if (!XAllocColorCells(display, 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(display, DefaultColormap(display, screen), &xcolor2);
-             XStoreColor(display, 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 */
-           Error(ERR_EXIT, "cannot allocate enough color cells");
-
-         xcolor.pixel = xcolor2.pixel;
-         xcolor_private[xcolor.pixel] = xcolor;
-         colorcell_used[xcolor.pixel] = TRUE;
-         XStoreColor(display, 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:
-      Error(ERR_RETURN, "display class not supported");
-      Error(ERR_EXIT, "DirectColor, TrueColor or PseudoColor display needed");
-      break;
-  }
-
-#if DEBUG_TIMING
-  debug_print_timestamp(2, "   ALLOCATING IMAGE COLORS:   ");
-#endif
-
-  /* create XImage from internal image structure and convert it to Pixmap */
-
-  bits_per_pixel = bitsPerPixelAtDepth(display, screen, depth);
-  bytes_per_pixel = (bits_per_pixel + 7) / 8;
-
-  ximage = XCreateImage(display, visual, depth, ZPixmap, 0,
-                       NULL, image->width, image->height,
-                       8, image->width * bytes_per_pixel);
-  ximage->data =
-    checked_malloc(image->width * image->height * bytes_per_pixel);
-  ximage->byte_order = MSBFirst;
-
-  src_ptr = image->data;
-  dst_ptr = (byte *)ximage->data;
-
-  switch (visual->class)
-  {
-    case DirectColor:
-    case TrueColor:
-    {
-      Pixel pixval;
-
-      for (y=0; y<image->height; y++)          /* general case */
-      {
-       for (x=0; x<image->width; x++)
-       {
-         pixval = *src_ptr++;
-         pixval =
-           redvalue[image->rgb.red[pixval] >> 8] |
-           greenvalue[image->rgb.green[pixval] >> 8] |
-           bluevalue[image->rgb.blue[pixval] >> 8];
-         value_to_memory(pixval, dst_ptr, bytes_per_pixel);
-         dst_ptr += bytes_per_pixel;
-       }
-      }
-      break;
-    }
-
-    case PseudoColor:
-    {
-      if (bytes_per_pixel == 1)                        /* (common) special case */
-      {
-       for (y=0; y<image->height; y++)
-         for (x=0; x<image->width; x++)
-           *dst_ptr++ = ximageinfo->index[c + *src_ptr++];
-      }
-      else                                     /* general case */
-      {
-       for (y=0; y<image->height; y++)
-       {
-         for (x=0; x<image->width; x++)
-         {
-           value_to_memory(ximageinfo->index[c + *src_ptr++],
-                           dst_ptr, bytes_per_pixel);
-           dst_ptr += bytes_per_pixel;
-         }
-       }
-      }
-      break;
-    }
-
-    default:
-      Error(ERR_RETURN, "display class not supported");
-      Error(ERR_EXIT, "DirectColor, TrueColor or PseudoColor display needed");
-      break;
-  }
-
-  if (redvalue)
-  {
-    free((byte *)redvalue);
-    free((byte *)greenvalue);
-    free((byte *)bluevalue);
-  }
-
-#if DEBUG_TIMING
-  debug_print_timestamp(2, "   CONVERTING IMAGE TO XIMAGE:");
-#endif
-
-  ximageinfo->pixmap = XCreatePixmap(display, window,
-                                    ximage->width, ximage->height,
-                                    ximageinfo->depth);
-
-  XPutImage(ximageinfo->display, ximageinfo->pixmap, gc,
-           ximage, 0, 0, 0, 0, ximage->width, ximage->height);
-
-  free(ximage->data);
-  ximage->data = NULL;
-  XDestroyImage(ximage);
-
-  return(ximageinfo);
-}
-
-void freeXImage(Image *image, XImageInfo *ximageinfo)
-{
-  if (ximageinfo->index != NULL && ximageinfo->no > 0)
-    XFreeColors(ximageinfo->display, ximageinfo->cmap, ximageinfo->index,
-               ximageinfo->no, 0);
-  /* this       ^^^^^^^^^^^^^^ is wrong, because the used color cells
-   * are somewhere between 0 and MAX_COLORS; there are indeed 'ximageinfo->no'
-   * used color cells, but they are not at array position 0 - 'ximageinfo->no'
-   */
-
-  free(ximageinfo);
-}
-
-int Read_PCX_to_Pixmap(Display *display, Window window, GC gc, char *filename,
-                      Pixmap *pixmap, Pixmap *pixmap_mask)
-{
-  Image *image;
-  XImageInfo *ximageinfo;
-  int screen;
-  Visual *visual;
-  int depth;
-
-#if DEBUG_TIMING
-  debug_print_timestamp(2, NULL);      /* initialize timestamp function */
-#endif
-
-  /* read the graphic file in PCX format to image structure */
-  if ((image = Read_PCX_to_Image(filename)) == NULL)
-    return errno_pcx;
-
-#if DEBUG_TIMING
-  printf("%s:\n", filename);
-  debug_print_timestamp(2, "   READING PCX FILE TO IMAGE: ");
-#endif
-
-  screen = DefaultScreen(display);
-  visual = DefaultVisual(display, screen);
-  depth = DefaultDepth(display, screen);
-
-  /* convert image structure to X11 Pixmap */
-  if (!(ximageinfo = Image_to_Pixmap(display, screen, visual,
-                                    window, gc, depth, image)))
-    Error(ERR_EXIT, "cannot convert Image to Pixmap");
-
-  /* if a private colormap has been created, install it */
-  if (ximageinfo->cmap != DefaultColormap(display, screen))
-    XSetWindowColormap(display, window, ximageinfo->cmap);
-
-#if DEBUG_TIMING
-  debug_print_timestamp(2, "   CONVERTING IMAGE TO PIXMAP:");
-#endif
-
-  /* create clip mask for the image */
-  ximageinfo->pixmap_mask = Image_to_Mask(image, display, window);
-
-#if DEBUG_TIMING
-  debug_print_timestamp(2, "   CONVERTING IMAGE TO MASK:  ");
-#endif
-
-  *pixmap = ximageinfo->pixmap;
-  *pixmap_mask = ximageinfo->pixmap_mask;
-
-  return PCX_Success;
-}
-
-#endif /* PLATFORM_UNIX */
-#endif /* TARGET_X11 */
diff --git a/src/image.h b/src/image.h
deleted file mode 100644 (file)
index 860521c..0000000
+++ /dev/null
@@ -1,60 +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                *
-*----------------------------------------------------------*
-*  image.h                                                 *
-***********************************************************/
-
-#ifndef IMAGE_H
-#define IMAGE_H
-
-#ifndef TARGET_SDL
-
-#include "main.h"
-
-#define MAX_COLORS     256     /* maximal number of colors for each image */
-
-typedef unsigned short Intensity;      /* RGB intensity for X11 */
-
-typedef struct
-{
-  Display  *display;           /* destination display             */
-  int       depth;             /* depth of destination drawable   */
-  Pixel     index[MAX_COLORS]; /* array of pixel values           */
-  int       no;                        /* number of pixels in the array   */
-  Colormap  cmap;              /* colormap used for image         */
-  Pixmap   pixmap;             /* final pixmap                    */
-  Pixmap   pixmap_mask;                /* final pixmap of mask            */
-} XImageInfo;
-
-struct RGBMap
-{
-  unsigned int used;                   /* number of colors used in RGB map */
-  Intensity    red[MAX_COLORS];                /* color values in X style          */
-  Intensity    green[MAX_COLORS];
-  Intensity    blue[MAX_COLORS];
-  boolean      color_used[MAX_COLORS]; /* flag if color cell is used       */
-};
-
-typedef struct
-{
-  struct 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 */
-  byte         *data;          /* image data                          */
-} Image;
-
-Image *newImage(unsigned int, unsigned int, unsigned int);
-void freeImage(Image *);
-void freeXImage(Image *, XImageInfo *);
-int Read_PCX_to_Pixmap(Display *, Window, GC, char *, Pixmap *, Pixmap *);
-
-#endif /* !TARGET_SDL */
-#endif /* IMAGE_H */
index 851eaa5e9370a63c610ca102f3924166bb86af22..d48e713c51b629d2e2c7a4acb617728d7313cbac 100644 (file)
 
 #include <signal.h>
 
+#include "libgame/libgame.h"
+
 #include "init.h"
 #include "events.h"
-#include "misc.h"
-#include "sound.h"
 #include "screens.h"
 #include "editor.h"
 #include "game.h"
@@ -24,8 +24,6 @@
 #include "tools.h"
 #include "files.h"
 #include "joystick.h"
-#include "image.h"
-#include "pcx.h"
 #include "network.h"
 #include "netserv.h"
 
index 8f6a0d6a1e66230284b7bf098ac6bdf3b0aa0e77..16d00d785a884f92bb311fcb283a84b7362b90ef 100644 (file)
 *  joystick.c                                              *
 ***********************************************************/
 
-#ifdef __FreeBSD__
+#if defined(PLATFORM_FREEBSD)
 #include <machine/joystick.h>
 #endif
 
+#include "libgame/libgame.h"
+
 #include "joystick.h"
-#include "misc.h"
 
 #if !defined(PLATFORM_MSDOS)
 static int JoystickPosition(int middle, int margin, int actual)
diff --git a/src/libgame/Makefile b/src/libgame/Makefile
new file mode 100644 (file)
index 0000000..f096730
--- /dev/null
@@ -0,0 +1,60 @@
+#=============================================================================#
+# Makefile for Rocks'n'Diamonds                                               #
+# (c) 1995-2000 Holger Schemel, info@artsoft.org                              #
+#=============================================================================#
+
+SRCS = libgame.c       \
+       private.c       \
+       system.c        \
+       buttons.c       \
+       text.c          \
+       sound.c         \
+       pcx.c           \
+       image.c         \
+       random.c        \
+       misc.c          \
+       msdos.c         \
+       x11.c           \
+       sdl.c
+
+OBJS = libgame.o       \
+       private.o       \
+       system.o        \
+       buttons.o       \
+       text.o          \
+       sound.o         \
+       pcx.o           \
+       image.o         \
+       random.o        \
+       misc.o          \
+       msdos.o         \
+       x11.o           \
+       sdl.o
+
+LIBGAME = libgame.a
+
+
+all: $(LIBGAME)
+
+$(LIBGAME): $(OBJS)
+       $(AR) cru $(LIBGAME) $(OBJS)
+       $(RANLIB) $(LIBGAME)
+
+.c.o:
+       $(CC) $(PROFILING) $(CFLAGS) -c $*.c
+
+clean:
+       $(RM) $(OBJS)
+       $(RM) $(LIBGAME)
+
+
+#-----------------------------------------------------------------------------#
+# development only stuff                                                      #
+#-----------------------------------------------------------------------------#
+
+depend:
+       for i in $(SRCS); do $(CPP) $(CFLAGS) -M $$i; done > .depend
+
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff --git a/src/libgame/buttons.c b/src/libgame/buttons.c
new file mode 100644 (file)
index 0000000..3fad756
--- /dev/null
@@ -0,0 +1,1349 @@
+/***********************************************************
+*  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                *
+*----------------------------------------------------------*
+*  buttons.c                                               *
+***********************************************************/
+
+#include <stdarg.h>
+
+#include "libgame.h"
+
+#include "main_TMP.h"
+
+#include "buttons.h"
+
+/* some positions in the video tape control window */
+#define VIDEO_DATE_LABEL_XPOS  (VIDEO_DISPLAY1_XPOS)
+#define VIDEO_DATE_LABEL_YPOS  (VIDEO_DISPLAY1_YPOS)
+#define VIDEO_DATE_LABEL_XSIZE (VIDEO_DISPLAY_XSIZE)
+#define VIDEO_DATE_LABEL_YSIZE (VIDEO_DISPLAY_YSIZE)
+#define VIDEO_DATE_XPOS                (VIDEO_DISPLAY1_XPOS + 1)
+#define VIDEO_DATE_YPOS                (VIDEO_DISPLAY1_YPOS + 14)
+#define VIDEO_DATE_XSIZE       (VIDEO_DISPLAY_XSIZE)
+#define VIDEO_DATE_YSIZE       16
+#define VIDEO_REC_LABEL_XPOS   (VIDEO_DISPLAY2_XPOS)
+#define VIDEO_REC_LABEL_YPOS   (VIDEO_DISPLAY2_YPOS)
+#define VIDEO_REC_LABEL_XSIZE  20
+#define VIDEO_REC_LABEL_YSIZE  12
+#define VIDEO_REC_SYMBOL_XPOS  (VIDEO_DISPLAY2_XPOS + 20)
+#define VIDEO_REC_SYMBOL_YPOS  (VIDEO_DISPLAY2_YPOS)
+#define VIDEO_REC_SYMBOL_XSIZE 16
+#define VIDEO_REC_SYMBOL_YSIZE 16
+#define VIDEO_PLAY_LABEL_XPOS  (VIDEO_DISPLAY2_XPOS + 65)
+#define VIDEO_PLAY_LABEL_YPOS  (VIDEO_DISPLAY2_YPOS)
+#define VIDEO_PLAY_LABEL_XSIZE 22
+#define VIDEO_PLAY_LABEL_YSIZE 12
+#define VIDEO_PLAY_SYMBOL_XPOS (VIDEO_DISPLAY2_XPOS + 52)
+#define VIDEO_PLAY_SYMBOL_YPOS (VIDEO_DISPLAY2_YPOS)
+#define VIDEO_PLAY_SYMBOL_XSIZE        11
+#define VIDEO_PLAY_SYMBOL_YSIZE        13
+#define VIDEO_PAUSE_LABEL_XPOS (VIDEO_DISPLAY2_XPOS)
+#define VIDEO_PAUSE_LABEL_YPOS (VIDEO_DISPLAY2_YPOS + 20)
+#define VIDEO_PAUSE_LABEL_XSIZE        35
+#define VIDEO_PAUSE_LABEL_YSIZE        8
+#define VIDEO_PAUSE_SYMBOL_XPOS        (VIDEO_DISPLAY2_XPOS + 35)
+#define VIDEO_PAUSE_SYMBOL_YPOS        (VIDEO_DISPLAY2_YPOS)
+#define VIDEO_PAUSE_SYMBOL_XSIZE 17
+#define VIDEO_PAUSE_SYMBOL_YSIZE 13
+#define VIDEO_TIME_XPOS                (VIDEO_DISPLAY2_XPOS + 38)
+#define VIDEO_TIME_YPOS                (VIDEO_DISPLAY2_YPOS + 14)
+#define VIDEO_TIME_XSIZE       50
+#define VIDEO_TIME_YSIZE       16
+
+/* special */
+#define VIDEO_PBEND_LABEL_XPOS 6
+#define VIDEO_PBEND_LABEL_YPOS 220
+#define VIDEO_PBEND_LABEL_XSIZE        35
+#define VIDEO_PBEND_LABEL_YSIZE        30
+
+#define VIDEO_STATE_OFF                (VIDEO_STATE_PLAY_OFF   |       \
+                                VIDEO_STATE_REC_OFF    |       \
+                                VIDEO_STATE_PAUSE_OFF  |       \
+                                VIDEO_STATE_FFWD_OFF   |       \
+                                VIDEO_STATE_PBEND_OFF  |       \
+                                VIDEO_STATE_DATE_OFF   |       \
+                                VIDEO_STATE_TIME_OFF)
+#define VIDEO_PRESS_OFF                (VIDEO_PRESS_PLAY_OFF   |       \
+                                VIDEO_PRESS_REC_OFF    |       \
+                                VIDEO_PRESS_PAUSE_OFF  |       \
+                                VIDEO_PRESS_STOP_OFF   |       \
+                                VIDEO_PRESS_EJECT_OFF)
+#define VIDEO_ALL_OFF          (VIDEO_STATE_OFF | VIDEO_PRESS_OFF)
+
+#define VIDEO_STATE_ON         (VIDEO_STATE_PLAY_ON    |       \
+                                VIDEO_STATE_REC_ON     |       \
+                                VIDEO_STATE_PAUSE_ON   |       \
+                                VIDEO_STATE_FFWD_ON    |       \
+                                VIDEO_STATE_PBEND_ON   |       \
+                                VIDEO_STATE_DATE_ON    |       \
+                                VIDEO_STATE_TIME_ON)
+#define VIDEO_PRESS_ON         (VIDEO_PRESS_PLAY_ON    |       \
+                                VIDEO_PRESS_REC_ON     |       \
+                                VIDEO_PRESS_PAUSE_ON   |       \
+                                VIDEO_PRESS_STOP_ON    |       \
+                                VIDEO_PRESS_EJECT_ON)
+#define VIDEO_ALL_ON           (VIDEO_STATE_ON | VIDEO_PRESS_ON)
+
+#define VIDEO_STATE            (VIDEO_STATE_ON | VIDEO_STATE_OFF)
+#define VIDEO_PRESS            (VIDEO_PRESS_ON | VIDEO_PRESS_OFF)
+#define VIDEO_ALL              (VIDEO_ALL_ON | VIDEO_ALL_OFF)
+
+
+void DrawVideoDisplay(unsigned long state, unsigned long value)
+{
+  int i;
+  int part_label = 0, part_symbol = 1;
+  int xpos = 0, ypos = 1, xsize = 2, ysize = 3;
+  static char *monatsname[12] =
+  {
+    "JAN", "FEB", "MAR", "APR", "MAY", "JUN",
+    "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"
+  };
+  static int video_pos[5][2][4] =
+  {
+    {{ VIDEO_PLAY_LABEL_XPOS, VIDEO_PLAY_LABEL_YPOS,
+       VIDEO_PLAY_LABEL_XSIZE,VIDEO_PLAY_LABEL_YSIZE },
+     { VIDEO_PLAY_SYMBOL_XPOS, VIDEO_PLAY_SYMBOL_YPOS,
+       VIDEO_PLAY_SYMBOL_XSIZE,VIDEO_PLAY_SYMBOL_YSIZE }},
+
+    {{ VIDEO_REC_LABEL_XPOS, VIDEO_REC_LABEL_YPOS,
+       VIDEO_REC_LABEL_XSIZE,VIDEO_REC_LABEL_YSIZE },
+     { VIDEO_REC_SYMBOL_XPOS, VIDEO_REC_SYMBOL_YPOS,
+       VIDEO_REC_SYMBOL_XSIZE,VIDEO_REC_SYMBOL_YSIZE }},
+
+    {{ VIDEO_PAUSE_LABEL_XPOS, VIDEO_PAUSE_LABEL_YPOS,
+       VIDEO_PAUSE_LABEL_XSIZE,VIDEO_PAUSE_LABEL_YSIZE },
+     { VIDEO_PAUSE_SYMBOL_XPOS, VIDEO_PAUSE_SYMBOL_YPOS,
+       VIDEO_PAUSE_SYMBOL_XSIZE,VIDEO_PAUSE_SYMBOL_YSIZE }},
+
+    {{ VIDEO_DATE_LABEL_XPOS, VIDEO_DATE_LABEL_YPOS,
+       VIDEO_DATE_LABEL_XSIZE,VIDEO_DATE_LABEL_YSIZE },
+     { VIDEO_DATE_XPOS, VIDEO_DATE_YPOS,
+       VIDEO_DATE_XSIZE,VIDEO_DATE_YSIZE }},
+
+    {{ 0,0,
+       0,0 },
+     { VIDEO_TIME_XPOS, VIDEO_TIME_YPOS,
+       VIDEO_TIME_XSIZE,VIDEO_TIME_YSIZE }}
+  };
+
+  if (state & VIDEO_STATE_PBEND_OFF)
+  {
+    int cx = DOOR_GFX_PAGEX3, cy = DOOR_GFX_PAGEY2;
+
+    BlitBitmap(pix[PIX_DOOR], drawto,
+              cx + VIDEO_REC_LABEL_XPOS,
+              cy + VIDEO_REC_LABEL_YPOS,
+              VIDEO_PBEND_LABEL_XSIZE,
+              VIDEO_PBEND_LABEL_YSIZE,
+              VX + VIDEO_REC_LABEL_XPOS,
+              VY + VIDEO_REC_LABEL_YPOS);
+  }
+
+  for(i=0;i<10;i++)
+  {
+    if (state & (1<<i))
+    {
+      int pos = i/2, cx, cy = DOOR_GFX_PAGEY2;
+
+      if (i%2)                 /* i ungerade => STATE_ON / PRESS_OFF */
+       cx = DOOR_GFX_PAGEX4;
+      else
+       cx = DOOR_GFX_PAGEX3;   /* i gerade => STATE_OFF / PRESS_ON */
+
+      if (video_pos[pos][part_label][0] && value != VIDEO_DISPLAY_SYMBOL_ONLY)
+       BlitBitmap(pix[PIX_DOOR], drawto,
+                  cx + video_pos[pos][part_label][xpos],
+                  cy + video_pos[pos][part_label][ypos],
+                  video_pos[pos][part_label][xsize],
+                  video_pos[pos][part_label][ysize],
+                  VX + video_pos[pos][part_label][xpos],
+                  VY + video_pos[pos][part_label][ypos]);
+      if (video_pos[pos][part_symbol][0] && value != VIDEO_DISPLAY_LABEL_ONLY)
+       BlitBitmap(pix[PIX_DOOR], drawto,
+                  cx + video_pos[pos][part_symbol][xpos],
+                  cy + video_pos[pos][part_symbol][ypos],
+                  video_pos[pos][part_symbol][xsize],
+                  video_pos[pos][part_symbol][ysize],
+                  VX + video_pos[pos][part_symbol][xpos],
+                  VY + video_pos[pos][part_symbol][ypos]);
+    }
+  }
+
+  if (state & VIDEO_STATE_FFWD_ON)
+  {
+    int cx = DOOR_GFX_PAGEX4, cy = DOOR_GFX_PAGEY2;
+
+    BlitBitmap(pix[PIX_DOOR], drawto,
+              cx + VIDEO_PLAY_SYMBOL_XPOS,
+              cy + VIDEO_PLAY_SYMBOL_YPOS,
+              VIDEO_PLAY_SYMBOL_XSIZE - 2,
+              VIDEO_PLAY_SYMBOL_YSIZE,
+              VX + VIDEO_PLAY_SYMBOL_XPOS - 9,
+              VY + VIDEO_PLAY_SYMBOL_YPOS);
+  }
+
+  if (state & VIDEO_STATE_PBEND_ON)
+  {
+    int cx = DOOR_GFX_PAGEX6, cy = DOOR_GFX_PAGEY1;
+
+    BlitBitmap(pix[PIX_DOOR], drawto,
+              cx + VIDEO_PBEND_LABEL_XPOS,
+              cy + VIDEO_PBEND_LABEL_YPOS,
+              VIDEO_PBEND_LABEL_XSIZE,
+              VIDEO_PBEND_LABEL_YSIZE,
+              VX + VIDEO_REC_LABEL_XPOS,
+              VY + VIDEO_REC_LABEL_YPOS);
+  }
+
+  if (state & VIDEO_STATE_DATE_ON)
+  {
+    int tag = value % 100;
+    int monat = (value/100) % 100;
+    int jahr = (value/10000);
+
+    DrawText(VX+VIDEO_DATE_XPOS,VY+VIDEO_DATE_YPOS,
+            int2str(tag,2),FS_SMALL,FC_SPECIAL1);
+    DrawText(VX+VIDEO_DATE_XPOS+27,VY+VIDEO_DATE_YPOS,
+            monatsname[monat],FS_SMALL,FC_SPECIAL1);
+    DrawText(VX+VIDEO_DATE_XPOS+64,VY+VIDEO_DATE_YPOS,
+            int2str(jahr,2),FS_SMALL,FC_SPECIAL1);
+  }
+
+  if (state & VIDEO_STATE_TIME_ON)
+  {
+    int min = value / 60;
+    int sec = value % 60;
+
+    DrawText(VX+VIDEO_TIME_XPOS,VY+VIDEO_TIME_YPOS,
+            int2str(min,2),FS_SMALL,FC_SPECIAL1);
+    DrawText(VX+VIDEO_TIME_XPOS+27,VY+VIDEO_TIME_YPOS,
+            int2str(sec,2),FS_SMALL,FC_SPECIAL1);
+  }
+
+  if (state & VIDEO_STATE_DATE)
+    redraw_mask |= REDRAW_VIDEO_1;
+  if ((state & ~VIDEO_STATE_DATE) & VIDEO_STATE)
+    redraw_mask |= REDRAW_VIDEO_2;
+  if (state & VIDEO_PRESS)
+    redraw_mask |= REDRAW_VIDEO_3;
+}
+
+void DrawCompleteVideoDisplay()
+{
+  BlitBitmap(pix[PIX_DOOR], drawto,
+            DOOR_GFX_PAGEX3,DOOR_GFX_PAGEY2, VXSIZE,VYSIZE, VX,VY);
+  BlitBitmap(pix[PIX_DOOR], drawto,
+            DOOR_GFX_PAGEX4+VIDEO_CONTROL_XPOS,
+            DOOR_GFX_PAGEY2+VIDEO_CONTROL_YPOS,
+            VIDEO_CONTROL_XSIZE,VIDEO_CONTROL_YSIZE,
+            VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
+
+  DrawVideoDisplay(VIDEO_ALL_OFF,0);
+  if (tape.date && tape.length)
+  {
+    DrawVideoDisplay(VIDEO_STATE_DATE_ON,tape.date);
+    DrawVideoDisplay(VIDEO_STATE_TIME_ON,tape.length_seconds);
+  }
+
+  BlitBitmap(drawto, pix[PIX_DB_DOOR],
+            VX,VY, VXSIZE,VYSIZE, DOOR_GFX_PAGEX1,DOOR_GFX_PAGEY2);
+}
+
+
+/* NEW GADGET STUFF -------------------------------------------------------- */
+
+
+/* values for DrawGadget() */
+#define DG_UNPRESSED           0
+#define DG_PRESSED             1
+#define DG_BUFFERED            0
+#define DG_DIRECT              1
+
+static struct GadgetInfo *gadget_list_first_entry = NULL;
+static struct GadgetInfo *gadget_list_last_entry = NULL;
+static int next_free_gadget_id = 1;
+static boolean gadget_id_wrapped = FALSE;
+
+static struct GadgetInfo *getGadgetInfoFromGadgetID(int id)
+{
+  struct GadgetInfo *gi = gadget_list_first_entry;
+
+  while (gi && gi->id != id)
+    gi = gi->next;
+
+  return gi;
+}
+
+static int getNewGadgetID()
+{
+  int id = next_free_gadget_id++;
+
+  if (next_free_gadget_id <= 0)                /* counter overrun */
+  {
+    gadget_id_wrapped = TRUE;          /* now we must check each ID */
+    next_free_gadget_id = 0;
+  }
+
+  if (gadget_id_wrapped)
+  {
+    next_free_gadget_id++;
+    while (getGadgetInfoFromGadgetID(next_free_gadget_id) != NULL)
+      next_free_gadget_id++;
+  }
+
+  if (next_free_gadget_id <= 0)                /* cannot get new gadget id */
+    Error(ERR_EXIT, "too much gadgets -- this should not happen");
+
+  return id;
+}
+
+static struct GadgetInfo *getGadgetInfoFromMousePosition(int mx, int my)
+{
+  struct GadgetInfo *gi = gadget_list_first_entry;
+
+  while (gi)
+  {
+    if (gi->mapped &&
+       mx >= gi->x && mx < gi->x + gi->width &&
+       my >= gi->y && my < gi->y + gi->height)
+       break;
+
+    gi = gi->next;
+  }
+
+  return gi;
+}
+
+static void default_callback_info(void *ptr)
+{
+#if 0
+  if (game_status == LEVELED)
+    HandleEditorGadgetInfoText(ptr);
+#endif
+
+  return;
+}
+
+static void default_callback_action(void *ptr)
+{
+  return;
+}
+
+static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct)
+{
+  int state = (pressed ? 1 : 0);
+  struct GadgetDesign *gd = (gi->checked ?
+                            &gi->alt_design[state] :
+                            &gi->design[state]);
+
+  switch (gi->type)
+  {
+    case GD_TYPE_NORMAL_BUTTON:
+    case GD_TYPE_CHECK_BUTTON:
+    case GD_TYPE_RADIO_BUTTON:
+      BlitBitmap(gd->bitmap, drawto,
+                gd->x, gd->y, gi->width, gi->height, gi->x, gi->y);
+      if (gi->deco.design.bitmap)
+       BlitBitmap(gi->deco.design.bitmap, drawto,
+                  gi->deco.design.x, gi->deco.design.y,
+                  gi->deco.width, gi->deco.height,
+                  gi->x + gi->deco.x + (pressed ? gi->deco.xshift : 0),
+                  gi->y + gi->deco.y + (pressed ? gi->deco.yshift : 0));
+      break;
+
+    case GD_TYPE_TEXTINPUT_ALPHANUMERIC:
+    case GD_TYPE_TEXTINPUT_NUMERIC:
+      {
+       int i;
+       char cursor_letter;
+       char cursor_string[3];
+       char text[MAX_GADGET_TEXTSIZE + 1];
+       int font_type = gi->text.font_type;
+       int font_width = getFontWidth(FS_SMALL, font_type);
+       int border = gi->border.size;
+       strcpy(text, gi->text.value);
+       strcat(text, " ");
+
+       /* left part of gadget */
+       BlitBitmap(gd->bitmap, drawto,
+                  gd->x, gd->y, border, gi->height, gi->x, gi->y);
+
+       /* middle part of gadget */
+       for (i=0; i<=gi->text.size; i++)
+         BlitBitmap(gd->bitmap, drawto,
+                    gd->x + border, gd->y, font_width, gi->height,
+                    gi->x + border + i * font_width, gi->y);
+
+       /* right part of gadget */
+       BlitBitmap(gd->bitmap, drawto,
+                  gd->x + gi->border.width - border, gd->y,
+                  border, gi->height, gi->x + gi->width - border, gi->y);
+
+       /* gadget text value */
+       DrawText(gi->x + border, gi->y + border, text, FS_SMALL, font_type);
+
+       cursor_letter = gi->text.value[gi->text.cursor_position];
+       cursor_string[0] = '~';
+       cursor_string[1] = (cursor_letter != '\0' ? cursor_letter : ' ');
+       cursor_string[2] = '\0';
+
+       /* draw cursor, if active */
+       if (pressed)
+         DrawText(gi->x + border + gi->text.cursor_position * font_width,
+                  gi->y + border, cursor_string, FS_SMALL, font_type);
+      }
+      break;
+
+    case GD_TYPE_SCROLLBAR_VERTICAL:
+      {
+       int i;
+       int xpos = gi->x;
+       int ypos = gi->y + gi->scrollbar.position;
+       int design_full = gi->width;
+       int design_body = design_full - 2 * gi->border.size;
+       int size_full = gi->scrollbar.size;
+       int size_body = size_full - 2 * gi->border.size;
+       int num_steps = size_body / design_body;
+       int step_size_remain = size_body - num_steps * design_body;
+
+       /* clear scrollbar area */
+       ClearRectangle(backbuffer, gi->x, gi->y, gi->width, gi->height);
+
+       /* upper part of gadget */
+       BlitBitmap(gd->bitmap, drawto,
+                  gd->x, gd->y,
+                  gi->width, gi->border.size,
+                  xpos, ypos);
+
+       /* middle part of gadget */
+       for (i=0; i<num_steps; i++)
+         BlitBitmap(gd->bitmap, drawto,
+                    gd->x, gd->y + gi->border.size,
+                    gi->width, design_body,
+                    xpos, ypos + gi->border.size + i * design_body);
+
+       /* remaining middle part of gadget */
+       if (step_size_remain > 0)
+         BlitBitmap(gd->bitmap, drawto,
+                    gd->x,  gd->y + gi->border.size,
+                    gi->width, step_size_remain,
+                    xpos, ypos + gi->border.size + num_steps * design_body);
+
+       /* lower part of gadget */
+       BlitBitmap(gd->bitmap, drawto,
+                  gd->x, gd->y + design_full - gi->border.size,
+                  gi->width, gi->border.size,
+                  xpos, ypos + size_full - gi->border.size);
+      }
+      break;
+
+    case GD_TYPE_SCROLLBAR_HORIZONTAL:
+      {
+       int i;
+       int xpos = gi->x + gi->scrollbar.position;
+       int ypos = gi->y;
+       int design_full = gi->height;
+       int design_body = design_full - 2 * gi->border.size;
+       int size_full = gi->scrollbar.size;
+       int size_body = size_full - 2 * gi->border.size;
+       int num_steps = size_body / design_body;
+       int step_size_remain = size_body - num_steps * design_body;
+
+       /* clear scrollbar area */
+       ClearRectangle(backbuffer, gi->x, gi->y, gi->width, gi->height);
+
+       /* left part of gadget */
+       BlitBitmap(gd->bitmap, drawto,
+                  gd->x, gd->y,
+                  gi->border.size, gi->height,
+                  xpos, ypos);
+
+       /* middle part of gadget */
+       for (i=0; i<num_steps; i++)
+         BlitBitmap(gd->bitmap, drawto,
+                    gd->x + gi->border.size, gd->y,
+                    design_body, gi->height,
+                    xpos + gi->border.size + i * design_body, ypos);
+
+       /* remaining middle part of gadget */
+       if (step_size_remain > 0)
+         BlitBitmap(gd->bitmap, drawto,
+                    gd->x + gi->border.size, gd->y,
+                    step_size_remain, gi->height,
+                    xpos + gi->border.size + num_steps * design_body, ypos);
+
+       /* right part of gadget */
+       BlitBitmap(gd->bitmap, drawto,
+                  gd->x + design_full - gi->border.size, gd->y,
+                  gi->border.size, gi->height,
+                  xpos + size_full - gi->border.size, ypos);
+      }
+      break;
+
+    default:
+      return;
+  }
+
+  if (direct)
+    BlitBitmap(drawto, window,
+              gi->x, gi->y, gi->width, gi->height, gi->x, gi->y);
+  else
+    redraw_mask |= (gi->x < SX + SXSIZE ? REDRAW_FIELD :
+                   gi->y < DY + DYSIZE ? REDRAW_DOOR_1 :
+                   gi->y > VY ? REDRAW_DOOR_2 : REDRAW_DOOR_3);
+}
+
+static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap)
+{
+  int tag = first_tag;
+
+  while (tag != GDI_END)
+  {
+    switch(tag)
+    {
+      case GDI_CUSTOM_ID:
+       gi->custom_id = va_arg(ap, int);
+       break;
+
+      case GDI_CUSTOM_TYPE_ID:
+       gi->custom_type_id = va_arg(ap, int);
+       break;
+
+      case GDI_INFO_TEXT:
+       {
+         int max_textsize = MAX_INFO_TEXTSIZE - 1;
+
+         strncpy(gi->info_text, va_arg(ap, char *), max_textsize);
+         gi->info_text[max_textsize] = '\0';
+       }
+       break;
+
+      case GDI_X:
+       gi->x = va_arg(ap, int);
+       break;
+
+      case GDI_Y:
+       gi->y = va_arg(ap, int);
+       break;
+
+      case GDI_WIDTH:
+       gi->width = va_arg(ap, int);
+       break;
+
+      case GDI_HEIGHT:
+       gi->height = va_arg(ap, int);
+       break;
+
+      case GDI_TYPE:
+       gi->type = va_arg(ap, unsigned long);
+       break;
+
+      case GDI_STATE:
+       gi->state = va_arg(ap, unsigned long);
+       break;
+
+      case GDI_CHECKED:
+       gi->checked = va_arg(ap, boolean);
+       break;
+
+      case GDI_RADIO_NR:
+       gi->radio_nr = va_arg(ap, unsigned long);
+       break;
+
+      case GDI_NUMBER_VALUE:
+       gi->text.number_value = va_arg(ap, long);
+       sprintf(gi->text.value, "%d", gi->text.number_value);
+       gi->text.cursor_position = strlen(gi->text.value);
+       break;
+
+      case GDI_NUMBER_MIN:
+       gi->text.number_min = va_arg(ap, long);
+       if (gi->text.number_value < gi->text.number_min)
+       {
+         gi->text.number_value = gi->text.number_min;
+         sprintf(gi->text.value, "%d", gi->text.number_value);
+       }
+       break;
+
+      case GDI_NUMBER_MAX:
+       gi->text.number_max = va_arg(ap, long);
+       if (gi->text.number_value > gi->text.number_max)
+       {
+         gi->text.number_value = gi->text.number_max;
+         sprintf(gi->text.value, "%d", gi->text.number_value);
+       }
+       break;
+
+      case GDI_TEXT_VALUE:
+       {
+         int max_textsize = MAX_GADGET_TEXTSIZE;
+
+         if (gi->text.size)
+           max_textsize = MIN(gi->text.size, MAX_GADGET_TEXTSIZE - 1);
+
+         strncpy(gi->text.value, va_arg(ap, char *), max_textsize);
+         gi->text.value[max_textsize] = '\0';
+         gi->text.cursor_position = strlen(gi->text.value);
+       }
+       break;
+
+      case GDI_TEXT_SIZE:
+       {
+         int tag_value = va_arg(ap, int);
+         int max_textsize = MIN(tag_value, MAX_GADGET_TEXTSIZE - 1);
+
+         gi->text.size = max_textsize;
+         gi->text.value[max_textsize] = '\0';
+       }
+       break;
+
+      case GDI_TEXT_FONT:
+       gi->text.font_type = va_arg(ap, int);
+       break;
+
+      case GDI_DESIGN_UNPRESSED:
+       gi->design[GD_BUTTON_UNPRESSED].bitmap = va_arg(ap, Bitmap);
+       gi->design[GD_BUTTON_UNPRESSED].x = va_arg(ap, int);
+       gi->design[GD_BUTTON_UNPRESSED].y = va_arg(ap, int);
+       break;
+
+      case GDI_DESIGN_PRESSED:
+       gi->design[GD_BUTTON_PRESSED].bitmap = va_arg(ap, Bitmap);
+       gi->design[GD_BUTTON_PRESSED].x = va_arg(ap, int);
+       gi->design[GD_BUTTON_PRESSED].y = va_arg(ap, int);
+       break;
+
+      case GDI_ALT_DESIGN_UNPRESSED:
+       gi->alt_design[GD_BUTTON_UNPRESSED].bitmap= va_arg(ap, Bitmap);
+       gi->alt_design[GD_BUTTON_UNPRESSED].x = va_arg(ap, int);
+       gi->alt_design[GD_BUTTON_UNPRESSED].y = va_arg(ap, int);
+       break;
+
+      case GDI_ALT_DESIGN_PRESSED:
+       gi->alt_design[GD_BUTTON_PRESSED].bitmap = va_arg(ap, Bitmap);
+       gi->alt_design[GD_BUTTON_PRESSED].x = va_arg(ap, int);
+       gi->alt_design[GD_BUTTON_PRESSED].y = va_arg(ap, int);
+       break;
+
+      case GDI_BORDER_SIZE:
+       gi->border.size = va_arg(ap, int);
+       break;
+
+      case GDI_TEXTINPUT_DESIGN_WIDTH:
+       gi->border.width = va_arg(ap, int);
+       break;
+
+      case GDI_DECORATION_DESIGN:
+       gi->deco.design.bitmap = va_arg(ap, Bitmap);
+       gi->deco.design.x = va_arg(ap, int);
+       gi->deco.design.y = va_arg(ap, int);
+       break;
+
+      case GDI_DECORATION_POSITION:
+       gi->deco.x = va_arg(ap, int);
+       gi->deco.y = va_arg(ap, int);
+       break;
+
+      case GDI_DECORATION_SIZE:
+       gi->deco.width = va_arg(ap, int);
+       gi->deco.height = va_arg(ap, int);
+       break;
+
+      case GDI_DECORATION_SHIFTING:
+       gi->deco.xshift = va_arg(ap, int);
+       gi->deco.yshift = va_arg(ap, int);
+       break;
+
+      case GDI_EVENT_MASK:
+       gi->event_mask = va_arg(ap, unsigned long);
+       break;
+
+      case GDI_AREA_SIZE:
+       gi->drawing.area_xsize = va_arg(ap, int);
+       gi->drawing.area_ysize = va_arg(ap, int);
+
+       /* determine dependent values for drawing area gadget, if needed */
+       if (gi->width == 0 && gi->height == 0 &&
+           gi->drawing.item_xsize !=0 && gi->drawing.item_ysize !=0)
+       {
+         gi->width = gi->drawing.area_xsize * gi->drawing.item_xsize;
+         gi->height = gi->drawing.area_ysize * gi->drawing.item_ysize;
+       }
+       else if (gi->drawing.item_xsize == 0 && gi->drawing.item_ysize == 0 &&
+                gi->width != 0 && gi->height != 0)
+       {
+         gi->drawing.item_xsize = gi->width / gi->drawing.area_xsize;
+         gi->drawing.item_ysize = gi->height / gi->drawing.area_ysize;
+       }
+       break;
+
+      case GDI_ITEM_SIZE:
+       gi->drawing.item_xsize = va_arg(ap, int);
+       gi->drawing.item_ysize = va_arg(ap, int);
+
+       /* determine dependent values for drawing area gadget, if needed */
+       if (gi->width == 0 && gi->height == 0 &&
+           gi->drawing.area_xsize !=0 && gi->drawing.area_ysize !=0)
+       {
+         gi->width = gi->drawing.area_xsize * gi->drawing.item_xsize;
+         gi->height = gi->drawing.area_ysize * gi->drawing.item_ysize;
+       }
+       else if (gi->drawing.area_xsize == 0 && gi->drawing.area_ysize == 0 &&
+                gi->width != 0 && gi->height != 0)
+       {
+         gi->drawing.area_xsize = gi->width / gi->drawing.item_xsize;
+         gi->drawing.area_ysize = gi->height / gi->drawing.item_ysize;
+       }
+       break;
+
+      case GDI_SCROLLBAR_ITEMS_MAX:
+       gi->scrollbar.items_max = va_arg(ap, int);
+       break;
+
+      case GDI_SCROLLBAR_ITEMS_VISIBLE:
+       gi->scrollbar.items_visible = va_arg(ap, int);
+       break;
+
+      case GDI_SCROLLBAR_ITEM_POSITION:
+       gi->scrollbar.item_position = va_arg(ap, int);
+       break;
+
+      case GDI_CALLBACK_INFO:
+       gi->callback_info = va_arg(ap, gadget_function);
+       break;
+
+      case GDI_CALLBACK_ACTION:
+       gi->callback_action = va_arg(ap, gadget_function);
+       break;
+
+      default:
+       Error(ERR_EXIT, "HandleGadgetTags(): unknown tag %d", tag);
+    }
+
+    tag = va_arg(ap, int);     /* read next tag */
+  }
+
+  /* check if gadget complete */
+  if (gi->type != GD_TYPE_DRAWING_AREA &&
+      (!gi->design[GD_BUTTON_UNPRESSED].bitmap ||
+       !gi->design[GD_BUTTON_PRESSED].bitmap))
+    Error(ERR_EXIT, "gadget incomplete (missing Bitmap)");
+
+  /* adjust gadget values in relation to other gadget values */
+
+  if (gi->type & GD_TYPE_TEXTINPUT)
+  {
+    int font_width = getFontWidth(FS_SMALL, gi->text.font_type);
+    int font_height = getFontHeight(FS_SMALL, gi->text.font_type);
+
+    gi->width = 2 * gi->border.size + (gi->text.size + 1) * font_width;
+    gi->height = 2 * gi->border.size + font_height;
+  }
+
+  if (gi->type & GD_TYPE_TEXTINPUT_NUMERIC)
+  {
+    struct GadgetTextInput *text = &gi->text;
+    int value = text->number_value;
+
+    text->number_value = (value < text->number_min ? text->number_min :
+                         value > text->number_max ? text->number_max :
+                         value);
+
+    sprintf(text->value, "%d", text->number_value);
+  }
+
+  if (gi->type & GD_TYPE_SCROLLBAR)
+  {
+    struct GadgetScrollbar *gs = &gi->scrollbar;
+
+    if (gi->width == 0 || gi->height == 0 ||
+       gs->items_max == 0 || gs->items_visible == 0)
+      Error(ERR_EXIT, "scrollbar gadget incomplete (missing tags)");
+
+    /* calculate internal scrollbar values */
+    gs->size_max = (gi->type == GD_TYPE_SCROLLBAR_VERTICAL ?
+                   gi->height : gi->width);
+    gs->size = gs->size_max * gs->items_visible / gs->items_max;
+    gs->position = gs->size_max * gs->item_position / gs->items_max;
+    gs->position_max = gs->size_max - gs->size;
+    gs->correction = gs->size_max / gs->items_max / 2;
+
+    /* finetuning for maximal right/bottom position */
+    if (gs->item_position == gs->items_max - gs->items_visible)
+      gs->position = gs->position_max;
+  }
+}
+
+void ModifyGadget(struct GadgetInfo *gi, int first_tag, ...)
+{
+  va_list ap;
+
+  va_start(ap, first_tag);
+  HandleGadgetTags(gi, first_tag, ap);
+  va_end(ap);
+
+  RedrawGadget(gi);
+}
+
+void RedrawGadget(struct GadgetInfo *gi)
+{
+  if (gi->mapped)
+    DrawGadget(gi, gi->state, DG_DIRECT);
+}
+
+struct GadgetInfo *CreateGadget(int first_tag, ...)
+{
+  struct GadgetInfo *new_gadget = checked_malloc(sizeof(struct GadgetInfo));
+  va_list ap;
+
+  /* always start with reliable default values */
+  memset(new_gadget, 0, sizeof(struct GadgetInfo));    /* zero all fields */
+  new_gadget->id = getNewGadgetID();
+  new_gadget->callback_info = default_callback_info;
+  new_gadget->callback_action = default_callback_action;
+
+  va_start(ap, first_tag);
+  HandleGadgetTags(new_gadget, first_tag, ap);
+  va_end(ap);
+
+  /* insert new gadget into global gadget list */
+  if (gadget_list_last_entry)
+  {
+    gadget_list_last_entry->next = new_gadget;
+    gadget_list_last_entry = gadget_list_last_entry->next;
+  }
+  else
+    gadget_list_first_entry = gadget_list_last_entry = new_gadget;
+
+  return new_gadget;
+}
+
+void FreeGadget(struct GadgetInfo *gi)
+{
+  struct GadgetInfo *gi_previous = gadget_list_first_entry;
+
+  while (gi_previous && gi_previous->next != gi)
+    gi_previous = gi_previous->next;
+
+  if (gi == gadget_list_first_entry)
+    gadget_list_first_entry = gi->next;
+
+  if (gi == gadget_list_last_entry)
+    gadget_list_last_entry = gi_previous;
+
+  gi_previous->next = gi->next;
+  free(gi);
+}
+
+static void CheckRangeOfNumericInputGadget(struct GadgetInfo *gi)
+{
+  if (gi->type != GD_TYPE_TEXTINPUT_NUMERIC)
+    return;
+
+  gi->text.number_value = atoi(gi->text.value);
+
+  if (gi->text.number_value < gi->text.number_min)
+    gi->text.number_value = gi->text.number_min;
+  if (gi->text.number_value > gi->text.number_max)
+    gi->text.number_value = gi->text.number_max;
+
+  sprintf(gi->text.value, "%d", gi->text.number_value);
+
+  if (gi->text.cursor_position < 0)
+    gi->text.cursor_position = 0;
+  else if (gi->text.cursor_position > strlen(gi->text.value))
+    gi->text.cursor_position = strlen(gi->text.value);
+}
+
+/* global pointer to gadget actually in use (when mouse button pressed) */
+static struct GadgetInfo *last_gi = NULL;
+
+static void MapGadgetExt(struct GadgetInfo *gi, boolean redraw)
+{
+  if (gi == NULL || gi->mapped)
+    return;
+
+  gi->mapped = TRUE;
+
+  if (redraw)
+    DrawGadget(gi, DG_UNPRESSED, DG_BUFFERED);
+}
+
+void MapGadget(struct GadgetInfo *gi)
+{
+  MapGadgetExt(gi, TRUE);
+}
+
+void UnmapGadget(struct GadgetInfo *gi)
+{
+  if (gi == NULL || !gi->mapped)
+    return;
+
+  gi->mapped = FALSE;
+
+  if (gi == last_gi)
+    last_gi = NULL;
+}
+
+#define MAX_NUM_GADGETS                1024
+#define MULTIMAP_UNMAP         (1 << 0)
+#define MULTIMAP_REMAP         (1 << 1)
+#define MULTIMAP_REDRAW                (1 << 2)
+#define MULTIMAP_PLAYFIELD     (1 << 3)
+#define MULTIMAP_DOOR_1                (1 << 4)
+#define MULTIMAP_DOOR_2                (1 << 5)
+#define MULTIMAP_ALL           (MULTIMAP_PLAYFIELD | \
+                                MULTIMAP_DOOR_1 | \
+                                MULTIMAP_DOOR_2)
+
+static void MultiMapGadgets(int mode)
+{
+  struct GadgetInfo *gi = gadget_list_first_entry;
+  static boolean map_state[MAX_NUM_GADGETS];
+  int map_count = 0;
+
+  while (gi)
+  {
+    if ((mode & MULTIMAP_PLAYFIELD && gi->x < SX + SXSIZE) ||
+       (mode & MULTIMAP_DOOR_1 && gi->x >= DX && gi->y < DY + DYSIZE) ||
+       (mode & MULTIMAP_DOOR_2 && gi->x >= DX && gi->y > DY + DYSIZE) ||
+       (mode & MULTIMAP_ALL) == MULTIMAP_ALL)
+    {
+      if (mode & MULTIMAP_UNMAP)
+      {
+       map_state[map_count++ % MAX_NUM_GADGETS] = gi->mapped;
+       UnmapGadget(gi);
+      }
+      else
+      {
+       if (map_state[map_count++ % MAX_NUM_GADGETS])
+         MapGadgetExt(gi, (mode & MULTIMAP_REDRAW));
+      }
+    }
+
+    gi = gi->next;
+  }
+}
+
+void UnmapAllGadgets()
+{
+  MultiMapGadgets(MULTIMAP_ALL | MULTIMAP_UNMAP);
+}
+
+void RemapAllGadgets()
+{
+  MultiMapGadgets(MULTIMAP_ALL | MULTIMAP_REMAP);
+}
+
+boolean anyTextGadgetActive()
+{
+  return (last_gi && last_gi->type & GD_TYPE_TEXTINPUT && last_gi->mapped);
+}
+
+void ClickOnGadget(struct GadgetInfo *gi, int button)
+{
+  /* simulate releasing mouse button over last gadget, if still pressed */
+  if (button_status)
+    HandleGadgets(-1, -1, 0);
+
+  /* simulate pressing mouse button over specified gadget */
+  HandleGadgets(gi->x, gi->y, button);
+
+  /* simulate releasing mouse button over specified gadget */
+  HandleGadgets(gi->x, gi->y, 0);
+}
+
+void HandleGadgets(int mx, int my, int button)
+{
+  static struct GadgetInfo *last_info_gi = NULL;
+  static unsigned long pressed_delay = 0;
+  static int last_button = 0;
+  static int last_mx = 0, last_my = 0;
+  int scrollbar_mouse_pos = 0;
+  struct GadgetInfo *new_gi, *gi;
+  boolean press_event;
+  boolean release_event;
+  boolean mouse_moving;
+  boolean gadget_pressed;
+  boolean gadget_pressed_repeated;
+  boolean gadget_moving;
+  boolean gadget_moving_inside;
+  boolean gadget_moving_off_borders;
+  boolean gadget_released;
+  boolean gadget_released_inside;
+  boolean gadget_released_off_borders;
+  boolean changed_position = FALSE;
+
+  /* check if there are any gadgets defined */
+  if (gadget_list_first_entry == NULL)
+    return;
+
+  /* check which gadget is under the mouse pointer */
+  new_gi = getGadgetInfoFromMousePosition(mx, my);
+
+  /* check if button state has changed since last invocation */
+  press_event = (button != 0 && last_button == 0);
+  release_event = (button == 0 && last_button != 0);
+  last_button = button;
+
+  /* check if mouse has been moved since last invocation */
+  mouse_moving = ((mx != last_mx || my != last_my) && motion_status);
+  last_mx = mx;
+  last_my = my;
+
+  /* special treatment for text and number input gadgets */
+  if (anyTextGadgetActive() && button != 0 && !motion_status)
+  {
+    struct GadgetInfo *gi = last_gi;
+
+    if (new_gi == last_gi)
+    {
+      /* if mouse button pressed inside activated text gadget, set cursor */
+      gi->text.cursor_position =
+       (mx - gi->x - gi->border.size) /
+       getFontWidth(FS_SMALL, gi->text.font_type);
+
+      if (gi->text.cursor_position < 0)
+       gi->text.cursor_position = 0;
+      else if (gi->text.cursor_position > strlen(gi->text.value))
+       gi->text.cursor_position = strlen(gi->text.value);
+
+      DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+    }
+    else
+    {
+      /* if mouse button pressed outside text input gadget, deactivate it */
+      CheckRangeOfNumericInputGadget(gi);
+      DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
+
+      gi->event.type = GD_EVENT_TEXT_LEAVING;
+
+      if (gi->event_mask & GD_EVENT_TEXT_LEAVING)
+       gi->callback_action(gi);
+
+      last_gi = NULL;
+    }
+  }
+
+  gadget_pressed =
+    (button != 0 && last_gi == NULL && new_gi != NULL && press_event);
+  gadget_pressed_repeated =
+    (button != 0 && last_gi != NULL && new_gi == last_gi);
+
+  gadget_released =            (release_event && last_gi != NULL);
+  gadget_released_inside =     (gadget_released && new_gi == last_gi);
+  gadget_released_off_borders =        (gadget_released && new_gi != last_gi);
+
+  gadget_moving =            (button != 0 && last_gi != NULL && mouse_moving);
+  gadget_moving_inside =      (gadget_moving && new_gi == last_gi);
+  gadget_moving_off_borders = (gadget_moving && new_gi != last_gi);
+
+  /* if new gadget pressed, store this gadget  */
+  if (gadget_pressed)
+    last_gi = new_gi;
+
+  /* 'gi' is actually handled gadget */
+  gi = last_gi;
+
+  /* if gadget is scrollbar, choose mouse position value */
+  if (gi && gi->type & GD_TYPE_SCROLLBAR)
+    scrollbar_mouse_pos =
+      (gi->type == GD_TYPE_SCROLLBAR_HORIZONTAL ? mx - gi->x : my - gi->y);
+
+  /* if mouse button released, no gadget needs to be handled anymore */
+  if (button == 0 && last_gi && !(last_gi->type & GD_TYPE_TEXTINPUT))
+    last_gi = NULL;
+
+  /* modify event position values even if no gadget is pressed */
+  if (button == 0 && !release_event)
+    gi = new_gi;
+
+  if (gi)
+  {
+    int last_x = gi->event.x;
+    int last_y = gi->event.y;
+
+    gi->event.x = mx - gi->x;
+    gi->event.y = my - gi->y;
+
+    if (gi->type == GD_TYPE_DRAWING_AREA)
+    {
+      gi->event.x /= gi->drawing.item_xsize;
+      gi->event.y /= gi->drawing.item_ysize;
+
+      if (last_x != gi->event.x || last_y != gi->event.y)
+       changed_position = TRUE;
+    }
+  }
+
+  /* handle gadget popup info text */
+  if (last_info_gi != new_gi ||
+      (new_gi && new_gi->type == GD_TYPE_DRAWING_AREA && changed_position))
+  {
+    last_info_gi = new_gi;
+
+    if (new_gi != NULL && (button == 0 || new_gi == last_gi))
+    {
+      new_gi->event.type = 0;
+      new_gi->callback_info(new_gi);
+    }
+    else
+      default_callback_info(NULL);
+  }
+
+  if (gadget_pressed)
+  {
+    if (gi->type == GD_TYPE_CHECK_BUTTON)
+    {
+      gi->checked = !gi->checked;
+    }
+    else if (gi->type == GD_TYPE_RADIO_BUTTON)
+    {
+      struct GadgetInfo *rgi = gadget_list_first_entry;
+
+      while (rgi)
+      {
+       if (rgi->mapped &&
+           rgi->type == GD_TYPE_RADIO_BUTTON &&
+           rgi->radio_nr == gi->radio_nr &&
+           rgi != gi)
+       {
+         rgi->checked = FALSE;
+         DrawGadget(rgi, DG_UNPRESSED, DG_DIRECT);
+       }
+
+       rgi = rgi->next;
+      }
+
+      gi->checked = TRUE;
+    }
+    else if (gi->type & GD_TYPE_SCROLLBAR)
+    {
+      int mpos, gpos;
+
+      if (gi->type == GD_TYPE_SCROLLBAR_HORIZONTAL)
+      {
+       mpos = mx;
+       gpos = gi->x;
+      }
+      else
+      {
+       mpos = my;
+       gpos = gi->y;
+      }
+
+      if (mpos >= gpos + gi->scrollbar.position &&
+         mpos < gpos + gi->scrollbar.position + gi->scrollbar.size)
+      {
+       /* drag scrollbar */
+       gi->scrollbar.drag_position =
+         scrollbar_mouse_pos - gi->scrollbar.position;
+      }
+      else
+      {
+       /* click scrollbar one scrollbar length up/left or down/right */
+
+       struct GadgetScrollbar *gs = &gi->scrollbar;
+       int old_item_position = gs->item_position;
+
+       changed_position = FALSE;
+
+       gs->item_position +=
+         gs->items_visible * (mpos < gpos + gi->scrollbar.position ? -1 : +1);
+
+       if (gs->item_position < 0)
+         gs->item_position = 0;
+       if (gs->item_position > gs->items_max - gs->items_visible)
+         gs->item_position = gs->items_max - gs->items_visible;
+
+       if (old_item_position != gs->item_position)
+       {
+         gi->event.item_position = gs->item_position;
+         changed_position = TRUE;
+       }
+
+       ModifyGadget(gi, GDI_SCROLLBAR_ITEM_POSITION, gs->item_position,
+                    GDI_END);
+
+       gi->state = GD_BUTTON_UNPRESSED;
+       gi->event.type = GD_EVENT_MOVING;
+       gi->event.off_borders = FALSE;
+
+       if (gi->event_mask & GD_EVENT_MOVING && changed_position)
+         gi->callback_action(gi);
+
+       /* don't handle this scrollbar anymore while mouse button pressed */
+       last_gi = NULL;
+
+       return;
+      }
+    }
+
+    DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+
+    gi->state = GD_BUTTON_PRESSED;
+    gi->event.type = GD_EVENT_PRESSED;
+    gi->event.button = button;
+    gi->event.off_borders = FALSE;
+
+    /* initialize delay counter */
+    DelayReached(&pressed_delay, 0);
+
+    if (gi->event_mask & GD_EVENT_PRESSED)
+      gi->callback_action(gi);
+  }
+
+  if (gadget_pressed_repeated)
+  {
+    gi->event.type = GD_EVENT_PRESSED;
+
+    if (gi->event_mask & GD_EVENT_REPEATED &&
+       DelayReached(&pressed_delay, GADGET_FRAME_DELAY))
+      gi->callback_action(gi);
+  }
+
+  if (gadget_moving)
+  {
+    if (gi->type & GD_TYPE_BUTTON)
+    {
+      if (gadget_moving_inside && gi->state == GD_BUTTON_UNPRESSED)
+       DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+      else if (gadget_moving_off_borders && gi->state == GD_BUTTON_PRESSED)
+       DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
+    }
+
+    if (gi->type & GD_TYPE_SCROLLBAR)
+    {
+      struct GadgetScrollbar *gs = &gi->scrollbar;
+      int old_item_position = gs->item_position;
+
+      gs->position = scrollbar_mouse_pos - gs->drag_position;
+
+      if (gs->position < 0)
+       gs->position = 0;
+      if (gs->position > gs->position_max)
+       gs->position = gs->position_max;
+
+      gs->item_position =
+       gs->items_max * (gs->position + gs->correction) / gs->size_max;
+
+      if (gs->item_position < 0)
+       gs->item_position = 0;
+      if (gs->item_position > gs->items_max - 1)
+       gs->item_position = gs->items_max - 1;
+
+      if (old_item_position != gs->item_position)
+      {
+       gi->event.item_position = gs->item_position;
+       changed_position = TRUE;
+      }
+
+      DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+    }
+
+    gi->state = (gadget_moving_inside || gi->type & GD_TYPE_SCROLLBAR ?
+                GD_BUTTON_PRESSED : GD_BUTTON_UNPRESSED);
+    gi->event.type = GD_EVENT_MOVING;
+    gi->event.off_borders = gadget_moving_off_borders;
+
+    if (gi->event_mask & GD_EVENT_MOVING && changed_position &&
+       (gadget_moving_inside || gi->event_mask & GD_EVENT_OFF_BORDERS))
+      gi->callback_action(gi);
+  }
+
+  if (gadget_released_inside)
+  {
+    if (!(gi->type & GD_TYPE_TEXTINPUT))
+      DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
+
+    gi->state = GD_BUTTON_UNPRESSED;
+    gi->event.type = GD_EVENT_RELEASED;
+
+    if (gi->event_mask & GD_EVENT_RELEASED)
+      gi->callback_action(gi);
+  }
+
+  if (gadget_released_off_borders)
+  {
+    if (gi->type & GD_TYPE_SCROLLBAR)
+      DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
+
+    gi->event.type = GD_EVENT_RELEASED;
+
+    if (gi->event_mask & GD_EVENT_RELEASED &&
+       gi->event_mask & GD_EVENT_OFF_BORDERS)
+      gi->callback_action(gi);
+  }
+}
+
+void HandleGadgetsKeyInput(Key key)
+{
+  struct GadgetInfo *gi = last_gi;
+  char text[MAX_GADGET_TEXTSIZE];
+  int text_length;
+  int cursor_pos;
+  char letter;
+  boolean legal_letter;
+
+  if (gi == NULL || !(gi->type & GD_TYPE_TEXTINPUT) || !gi->mapped)
+    return;
+
+  text_length = strlen(gi->text.value);
+  cursor_pos = gi->text.cursor_position;
+  letter = getCharFromKey(key);
+  legal_letter = (gi->type == GD_TYPE_TEXTINPUT_NUMERIC ?
+                 letter >= '0' && letter <= '9' :
+                 letter != 0);
+
+  if (legal_letter && text_length < gi->text.size)
+  {
+    strcpy(text, gi->text.value);
+    strcpy(&gi->text.value[cursor_pos + 1], &text[cursor_pos]);
+    gi->text.value[cursor_pos] = letter;
+    gi->text.cursor_position++;
+    DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+  }
+  else if (key == KSYM_Left && cursor_pos > 0)
+  {
+    gi->text.cursor_position--;
+    DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+  }
+  else if (key == KSYM_Right && cursor_pos < text_length)
+  {
+    gi->text.cursor_position++;
+    DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+  }
+  else if (key == KSYM_BackSpace && cursor_pos > 0)
+  {
+    strcpy(text, gi->text.value);
+    strcpy(&gi->text.value[cursor_pos - 1], &text[cursor_pos]);
+    gi->text.cursor_position--;
+    DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+  }
+  else if (key == KSYM_Delete && cursor_pos < text_length)
+  {
+    strcpy(text, gi->text.value);
+    strcpy(&gi->text.value[cursor_pos], &text[cursor_pos + 1]);
+    DrawGadget(gi, DG_PRESSED, DG_DIRECT);
+  }
+  else if (key == KSYM_Return)
+  {
+    CheckRangeOfNumericInputGadget(gi);
+    DrawGadget(gi, DG_UNPRESSED, DG_DIRECT);
+
+    gi->event.type = GD_EVENT_TEXT_RETURN;
+
+    if (gi->event_mask & GD_EVENT_TEXT_RETURN)
+      gi->callback_action(gi);
+
+    last_gi = NULL;
+  }
+}
diff --git a/src/libgame/buttons.h b/src/libgame/buttons.h
new file mode 100644 (file)
index 0000000..38fbe63
--- /dev/null
@@ -0,0 +1,265 @@
+/***********************************************************
+*  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                *
+*----------------------------------------------------------*
+*  buttons.h                                               *
+***********************************************************/
+
+#ifndef BUTTONS_H
+#define BUTTONS_H
+
+#include "libgame.h"
+
+/* the following definitions are also used by tools.c */
+
+/* some positions in the video tape control window */
+#define VIDEO_DISPLAY1_XPOS    5
+#define VIDEO_DISPLAY1_YPOS    5
+#define VIDEO_DISPLAY2_XPOS    5
+#define VIDEO_DISPLAY2_YPOS    41
+#define VIDEO_DISPLAY_XSIZE    90
+#define VIDEO_DISPLAY_YSIZE    31
+#define VIDEO_BUTTON_XSIZE     18
+#define VIDEO_BUTTON_YSIZE     18
+#define VIDEO_CONTROL_XPOS     5
+#define VIDEO_CONTROL_YPOS     77
+#define VIDEO_CONTROL_XSIZE    VIDEO_DISPLAY_XSIZE
+#define VIDEO_CONTROL_YSIZE    VIDEO_BUTTON_YSIZE
+
+/* values for video tape control */
+#define VIDEO_STATE_PLAY_OFF   (1L << 0)
+#define VIDEO_STATE_PLAY_ON    (1L << 1)
+#define VIDEO_STATE_PLAY       (VIDEO_STATE_PLAY_OFF   | VIDEO_STATE_PLAY_ON)
+#define VIDEO_STATE_REC_OFF    (1L << 2)
+#define VIDEO_STATE_REC_ON     (1L << 3)
+#define VIDEO_STATE_REC                (VIDEO_STATE_REC_OFF    | VIDEO_STATE_REC_ON)
+#define VIDEO_STATE_PAUSE_OFF  (1L << 4)
+#define VIDEO_STATE_PAUSE_ON   (1L << 5)
+#define VIDEO_STATE_PAUSE      (VIDEO_STATE_PAUSE_OFF  | VIDEO_STATE_PAUSE_ON)
+#define VIDEO_STATE_DATE_OFF   (1L << 6)
+#define VIDEO_STATE_DATE_ON    (1L << 7)
+#define VIDEO_STATE_DATE       (VIDEO_STATE_DATE_OFF   | VIDEO_STATE_DATE_ON)
+#define VIDEO_STATE_TIME_OFF   (1L << 8)
+#define VIDEO_STATE_TIME_ON    (1L << 9)
+#define VIDEO_STATE_TIME       (VIDEO_STATE_TIME_OFF   | VIDEO_STATE_TIME_ON)
+#define VIDEO_PRESS_PLAY_ON    (1L << 10)
+#define VIDEO_PRESS_PLAY_OFF   (1L << 11)
+#define VIDEO_PRESS_PLAY       (VIDEO_PRESS_PLAY_OFF   | VIDEO_PRESS_PLAY_ON)
+#define VIDEO_PRESS_REC_ON     (1L << 12)
+#define VIDEO_PRESS_REC_OFF    (1L << 13)
+#define VIDEO_PRESS_REC                (VIDEO_PRESS_REC_OFF    | VIDEO_PRESS_REC_ON)
+#define VIDEO_PRESS_PAUSE_ON   (1L << 14)
+#define VIDEO_PRESS_PAUSE_OFF  (1L << 15)
+#define VIDEO_PRESS_PAUSE      (VIDEO_PRESS_PAUSE_OFF  | VIDEO_PRESS_PAUSE_ON)
+#define VIDEO_PRESS_STOP_ON    (1L << 16)
+#define VIDEO_PRESS_STOP_OFF   (1L << 17)
+#define VIDEO_PRESS_STOP       (VIDEO_PRESS_STOP_OFF   | VIDEO_PRESS_STOP_ON)
+#define VIDEO_PRESS_EJECT_ON   (1L << 18)
+#define VIDEO_PRESS_EJECT_OFF  (1L << 19)
+#define VIDEO_PRESS_EJECT      (VIDEO_PRESS_EJECT_OFF  | VIDEO_PRESS_EJECT_ON)
+
+/* special */
+#define VIDEO_STATE_FFWD_OFF   ((1L << 20) | VIDEO_STATE_PAUSE_OFF)
+#define VIDEO_STATE_FFWD_ON    (1L << 21)
+#define VIDEO_STATE_FFWD       (VIDEO_STATE_FFWD_OFF   | VIDEO_STATE_FFWD_ON)
+#define VIDEO_STATE_PBEND_OFF  (1L << 22)
+#define VIDEO_STATE_PBEND_ON   (1L << 23)
+#define VIDEO_STATE_PBEND      (VIDEO_STATE_PBEND_OFF  | VIDEO_STATE_PBEND_ON)
+
+/* tags to draw video display labels or symbols only */
+#define VIDEO_DISPLAY_DEFAULT          0
+#define VIDEO_DISPLAY_LABEL_ONLY       1
+#define VIDEO_DISPLAY_SYMBOL_ONLY      2
+
+void DrawVideoDisplay(unsigned long, unsigned long);
+void DrawCompleteVideoDisplay(void);
+
+
+/* NEW GADGET STUFF -------------------------------------------------------- */
+
+/* gadget types */
+#define GD_TYPE_NORMAL_BUTTON          (1 << 0)
+#define GD_TYPE_CHECK_BUTTON           (1 << 1)
+#define GD_TYPE_RADIO_BUTTON           (1 << 2)
+#define GD_TYPE_DRAWING_AREA           (1 << 3)
+#define GD_TYPE_TEXTINPUT_ALPHANUMERIC (1 << 4)
+#define GD_TYPE_TEXTINPUT_NUMERIC      (1 << 5)
+#define GD_TYPE_SCROLLBAR_VERTICAL     (1 << 6)
+#define GD_TYPE_SCROLLBAR_HORIZONTAL   (1 << 7)
+
+#define GD_TYPE_BUTTON                 (GD_TYPE_NORMAL_BUTTON | \
+                                        GD_TYPE_CHECK_BUTTON | \
+                                        GD_TYPE_RADIO_BUTTON)
+#define GD_TYPE_SCROLLBAR              (GD_TYPE_SCROLLBAR_VERTICAL | \
+                                        GD_TYPE_SCROLLBAR_HORIZONTAL)
+#define GD_TYPE_TEXTINPUT              (GD_TYPE_TEXTINPUT_ALPHANUMERIC | \
+                                        GD_TYPE_TEXTINPUT_NUMERIC)
+
+/* gadget events */
+#define GD_EVENT_PRESSED               (1 << 0)
+#define GD_EVENT_RELEASED              (1 << 1)
+#define GD_EVENT_MOVING                        (1 << 2)
+#define GD_EVENT_REPEATED              (1 << 3)
+#define GD_EVENT_OFF_BORDERS           (1 << 4)
+#define GD_EVENT_TEXT_RETURN           (1 << 5)
+#define GD_EVENT_TEXT_LEAVING          (1 << 6)
+
+/* gadget button states */
+#define GD_BUTTON_UNPRESSED            0
+#define GD_BUTTON_PRESSED              1
+
+/* gadget structure constants */
+#define MAX_GADGET_TEXTSIZE            1024
+#define MAX_INFO_TEXTSIZE              1024
+
+/* gadget creation tags */
+#define GDI_END                                0
+#define GDI_CUSTOM_ID                  1
+#define GDI_CUSTOM_TYPE_ID             2
+#define GDI_X                          3
+#define GDI_Y                          4
+#define GDI_WIDTH                      5
+#define GDI_HEIGHT                     6
+#define GDI_TYPE                       7
+#define GDI_STATE                      8
+#define GDI_CHECKED                    9
+#define GDI_RADIO_NR                   10
+#define GDI_NUMBER_VALUE               11
+#define GDI_NUMBER_MIN                 12
+#define GDI_NUMBER_MAX                 13
+#define GDI_TEXT_VALUE                 14
+#define GDI_TEXT_SIZE                  15
+#define GDI_TEXT_FONT                  16
+#define GDI_DESIGN_UNPRESSED           17
+#define GDI_DESIGN_PRESSED             18
+#define GDI_ALT_DESIGN_UNPRESSED       19
+#define GDI_ALT_DESIGN_PRESSED         20
+#define GDI_BORDER_SIZE                        21
+#define GDI_TEXTINPUT_DESIGN_WIDTH     22
+#define GDI_DECORATION_DESIGN          23
+#define GDI_DECORATION_POSITION                24
+#define GDI_DECORATION_SIZE            25
+#define GDI_DECORATION_SHIFTING                26
+#define GDI_EVENT_MASK                 27
+#define GDI_EVENT                      28
+#define GDI_CALLBACK_INFO              29
+#define GDI_CALLBACK_ACTION            30
+#define GDI_AREA_SIZE                  31
+#define GDI_ITEM_SIZE                  32
+#define GDI_SCROLLBAR_ITEMS_MAX                33
+#define GDI_SCROLLBAR_ITEMS_VISIBLE    34
+#define GDI_SCROLLBAR_ITEM_POSITION    35
+#define GDI_INFO_TEXT                  36
+
+typedef void (*gadget_function)(void *);
+
+struct GadgetBorder
+{
+  int size;                            /* size of gadget border */
+  int width;                           /* for text input gadgets */
+};
+
+struct GadgetDesign
+{
+  Bitmap bitmap;                       /* Bitmap with gadget surface */
+  int x, y;                            /* position of rectangle in Bitmap */
+};
+
+struct GadgetDecoration
+{
+  struct GadgetDesign design;          /* decoration design structure */
+  int x, y;                            /* position of deco on the gadget */
+  int width, height;                   /* width and height of decoration */
+  int xshift, yshift;                  /* deco shifting when gadget pressed */
+};
+
+struct GadgetEvent
+{
+  unsigned long type;                  /* event type */
+  int button;                          /* button number for button events */
+  int x, y;                            /* gadget position at event time */
+  boolean off_borders;                 /* mouse pointer outside gadget? */
+  int item_x, item_y, item_position;   /* new item position */
+};
+
+struct GadgetDrawingArea
+{
+  int area_xsize, area_ysize;          /* size of drawing area (in items) */
+  int item_xsize, item_ysize;          /* size of each item in drawing area */
+};
+
+struct GadgetTextInput
+{
+  char value[MAX_GADGET_TEXTSIZE];     /* text string in input field */
+  int number_value;                    /* integer value, if numeric */
+  int number_min;                      /* minimal allowed numeric value */
+  int number_max;                      /* maximal allowed numeric value */
+  int size;                            /* maximal size of input text */
+  int cursor_position;                 /* actual cursor position */
+  int font_type;                       /* font to use for text input */
+};
+
+struct GadgetScrollbar
+{
+  int items_max;                       /* number of items to access */
+  int items_visible;                   /* number of visible items */
+  int item_position;                   /* actual item position */
+  int size_max;                                /* this is either width or height */
+  int size;                            /* scrollbar size on screen */
+  int position;                                /* scrollbar position on screen */
+  int position_max;                    /* bottom/right scrollbar position */
+  int drag_position;                   /* drag position on scrollbar */
+  int correction;                      /* scrollbar position correction */
+};
+
+struct GadgetInfo
+{
+  int id;                              /* internal gadget identifier */
+  int custom_id;                       /* custom gadget identifier */
+  int custom_type_id;                  /* custom gadget type identifier */
+  char info_text[MAX_INFO_TEXTSIZE];   /* short popup info text */
+  int x, y;                            /* gadget position */
+  int width, height;                   /* gadget size */
+  unsigned long type;                  /* type (button, text input, ...) */
+  unsigned long state;                 /* state (pressed, released, ...) */
+  boolean checked;                     /* check/radio button state */
+  int radio_nr;                                /* number of radio button series */
+  boolean mapped;                      /* gadget is active */
+  struct GadgetBorder border;          /* gadget border design */
+  struct GadgetDesign design[2];       /* 0: normal; 1: pressed */
+  struct GadgetDesign alt_design[2];   /* alternative design */
+  struct GadgetDecoration deco;                /* decoration on top of gadget */
+  unsigned long event_mask;            /* possible events for this gadget */
+  struct GadgetEvent event;            /* actual gadget event */
+  gadget_function callback_info;       /* function for pop-up info text */
+  gadget_function callback_action;     /* function for gadget action */
+  struct GadgetDrawingArea drawing;    /* fields for drawing area gadget */
+  struct GadgetTextInput text;         /* fields for text input gadget */
+  struct GadgetScrollbar scrollbar;    /* fields for scrollbar gadget */
+  struct GadgetInfo *next;             /* next list entry */
+};
+
+struct GadgetInfo *CreateGadget(int, ...);
+void FreeGadget(struct GadgetInfo *);
+
+void ModifyGadget(struct GadgetInfo *, int, ...);
+void RedrawGadget(struct GadgetInfo *);
+
+void MapGadget(struct GadgetInfo *);
+void UnmapGadget(struct GadgetInfo *);
+void UnmapAllGadgets();
+void RemapAllGadgets();
+
+boolean anyTextGadgetActive();
+void ClickOnGadget(struct GadgetInfo *, int);
+
+void HandleGadgets(int, int, int);
+void HandleGadgetsKeyInput(Key);
+
+#endif
diff --git a/src/libgame/image.c b/src/libgame/image.c
new file mode 100644 (file)
index 0000000..9dd4c24
--- /dev/null
@@ -0,0 +1,554 @@
+/***********************************************************
+*  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                *
+*----------------------------------------------------------*
+*  image.c                                                 *
+***********************************************************/
+
+#if defined(TARGET_X11)
+
+#include "image.h"
+#include "pcx.h"
+#include "misc.h"
+
+/* for MS-DOS/Allegro, exclude all except newImage() and freeImage() */
+
+Image *newImage(unsigned int width, unsigned int height, unsigned int depth)
+{
+  Image *image;
+  const unsigned int bytes_per_pixel = 1;
+  int i;
+
+  if (depth > 8)
+    Error(ERR_EXIT, "images with more than 256 colors are not supported");
+
+  depth = 8;
+  image = checked_malloc(sizeof(Image));
+  image->data = checked_malloc(width * height * bytes_per_pixel);
+  image->width = width;
+  image->height = height;
+  image->depth = depth;
+  image->rgb.used = 0;
+  for (i=0; i<MAX_COLORS; i++)
+    image->rgb.color_used[i] = FALSE;
+
+  return image;
+}
+
+void freeImage(Image *image)
+{
+  free(image->data);
+  free(image);
+}
+
+#if defined(PLATFORM_UNIX)
+
+/* extra colors to try allocating in private color maps to minimize flashing */
+#define NOFLASH_COLORS 256
+
+/* architecture independent value-to-memory conversion
+   note: the internal format is big endian */
+
+#define value_to_memory(value, ptr, length) (                          \
+(length) == 1 ? (*( (byte *)(ptr)   ) = ( value     ) ) :              \
+(length) == 2 ? (*( (byte *)(ptr)   ) = (((unsigned long)(value))>> 8),        \
+                *(((byte *)(ptr))+1) = ( value     ) ) :               \
+(length) == 3 ? (*( (byte *)(ptr)   ) = (((unsigned long)(value))>>16),        \
+                *(((byte *)(ptr))+1) = (((unsigned long)(value))>> 8), \
+                *(((byte *)(ptr))+2) = ( value     ) ) :               \
+                (*( (byte *)(ptr)   ) = (((unsigned long)(value))>>24),        \
+                *(((byte *)(ptr))+1) = (((unsigned long)(value))>>16), \
+                *(((byte *)(ptr))+2) = (((unsigned long)(value))>> 8), \
+                *(((byte *)(ptr))+3) = ( value     ) ))
+
+static Pixmap Image_to_Mask(Image *image, Display *display, Window window)
+{
+  byte *src_ptr, *dst_ptr, *dst_ptr2;
+  unsigned int bytes_per_row;
+  unsigned int x, y;
+  byte bitmask;
+  byte *mask_data;
+  Pixmap mask_pixmap;
+
+  bytes_per_row = (image->width + 7) / 8;
+  mask_data = checked_calloc(bytes_per_row * image->height);
+
+  src_ptr = image->data;
+  dst_ptr = mask_data;
+
+  /* create bitmap data which can be used by 'XCreateBitmapFromData()'
+   * directly to create a pixmap of depth 1 for use as a clip mask for
+   * the corresponding image pixmap
+   */
+
+  for (y=0; y<image->height; y++)
+  {
+    bitmask = 0x01;            /* start with leftmost bit in the byte     */
+    dst_ptr2 = dst_ptr;                /* start with leftmost byte in the row     */
+
+    for (x=0; x<image->width; x++)
+    {
+      if (*src_ptr++)          /* source pixel solid? (pixel index != 0)  */
+       *dst_ptr2 |= bitmask;   /* then write a bit into the image mask    */
+
+      if ((bitmask <<= 1) == 0)        /* bit at rightmost byte position reached? */
+      {
+       bitmask = 0x01;         /* start again with leftmost bit position  */
+       dst_ptr2++;             /* continue with next byte in image mask   */
+      }
+    }
+
+    dst_ptr += bytes_per_row;  /* continue with leftmost byte of next row */
+  }
+
+  mask_pixmap = XCreateBitmapFromData(display, window, (char *)mask_data,
+                                     image->width, image->height);
+  free(mask_data);
+
+  return mask_pixmap;
+}
+
+static int bitsPerPixelAtDepth(Display *display, int screen, int depth)
+{
+  XPixmapFormatValues *pixmap_format;
+  int i, num_pixmap_formats, bits_per_pixel = -1;
+
+  /* get Pixmap formats supported by the X server */
+  pixmap_format = XListPixmapFormats(display, &num_pixmap_formats);
+
+  /* find format that matches the given depth */
+  for (i=0; i<num_pixmap_formats; i++)
+    if (pixmap_format[i].depth == depth)
+      bits_per_pixel = pixmap_format[i].bits_per_pixel;
+
+  XFree(pixmap_format);
+
+  if (bits_per_pixel == -1)
+    Error(ERR_EXIT, "cannot find pixmap format for depth %d", depth);
+
+  return bits_per_pixel;
+}
+
+XImageInfo *Image_to_Pixmap(Display *display, int screen, Visual *visual,
+                           Window window, GC gc, int depth, 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 boolean private_cmap = FALSE;
+  Pixel *redvalue, *greenvalue, *bluevalue;
+  unsigned int a, c = 0, x, y, bytes_per_pixel, bits_per_pixel;
+  XColor xcolor;
+  XImage *ximage;
+  XImageInfo *ximageinfo;
+  byte *src_ptr, *dst_ptr;
+
+  if (!global_cmap)
+  {
+    if (visual == DefaultVisual(display, screen))
+      global_cmap = DefaultColormap(display, screen);
+    else
+    {
+      global_cmap = XCreateColormap(display, RootWindow(display, screen),
+                                   visual, AllocNone);
+      private_cmap = TRUE;
+    }
+  }
+
+  xcolor.flags = DoRed | DoGreen | DoBlue;
+  redvalue = greenvalue = bluevalue = NULL;
+  ximageinfo = checked_malloc(sizeof(XImageInfo));
+  ximageinfo->display = display;
+  ximageinfo->depth = depth;
+
+  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 *)checked_malloc(sizeof(Pixel) * 256);
+      greenvalue = (Pixel *)checked_malloc(sizeof(Pixel) * 256);
+      bluevalue = (Pixel *)checked_malloc(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;
+      }
+      
+      /* consistency check */
+      if (redcolors > visual->map_entries ||
+         greencolors > visual->map_entries ||
+         bluecolors > visual->map_entries)
+       Error(ERR_WARN, "inconsistency in color information");
+
+      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(display, 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(display, screen)))
+         {
+           global_cmap = XCopyColormapAndFree(display, 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(redvalue);
+          free(greenvalue);
+          free(bluevalue);
+          free(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;
+
+      for (a=0; a<MAX_COLORS; a++)
+      {
+       XColor xcolor2;
+       unsigned short mask;
+       int color_found;
+       int i;
+
+       if (!image->rgb.color_used[a])
+         continue;
+
+       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(display, ximageinfo->cmap, &xcolor))
+       {
+         if (!private_cmap)
+         {
+           if (options.verbose)
+             Error(ERR_RETURN, "switching to private colormap");
+
+           /* we just filled up the default colormap -- get a private one
+              which contains all already allocated colors */
+
+           global_cmap = XCopyColormapAndFree(display, global_cmap);
+           ximageinfo->cmap = global_cmap;
+           private_cmap = TRUE;
+
+           /* allocate the rest of the color cells read/write */
+           global_cmap_index =
+             (Pixel *)checked_malloc(sizeof(Pixel) * NOFLASH_COLORS);
+           for (i=0; i<NOFLASH_COLORS; i++)
+             if (!XAllocColorCells(display, 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(display, DefaultColormap(display, screen), &xcolor2);
+             XStoreColor(display, 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 */
+           Error(ERR_EXIT, "cannot allocate enough color cells");
+
+         xcolor.pixel = xcolor2.pixel;
+         xcolor_private[xcolor.pixel] = xcolor;
+         colorcell_used[xcolor.pixel] = TRUE;
+         XStoreColor(display, 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:
+      Error(ERR_RETURN, "display class not supported");
+      Error(ERR_EXIT, "DirectColor, TrueColor or PseudoColor display needed");
+      break;
+  }
+
+#if DEBUG_TIMING
+  debug_print_timestamp(2, "   ALLOCATING IMAGE COLORS:   ");
+#endif
+
+  /* create XImage from internal image structure and convert it to Pixmap */
+
+  bits_per_pixel = bitsPerPixelAtDepth(display, screen, depth);
+  bytes_per_pixel = (bits_per_pixel + 7) / 8;
+
+  ximage = XCreateImage(display, visual, depth, ZPixmap, 0,
+                       NULL, image->width, image->height,
+                       8, image->width * bytes_per_pixel);
+  ximage->data =
+    checked_malloc(image->width * image->height * bytes_per_pixel);
+  ximage->byte_order = MSBFirst;
+
+  src_ptr = image->data;
+  dst_ptr = (byte *)ximage->data;
+
+  switch (visual->class)
+  {
+    case DirectColor:
+    case TrueColor:
+    {
+      Pixel pixval;
+
+      for (y=0; y<image->height; y++)          /* general case */
+      {
+       for (x=0; x<image->width; x++)
+       {
+         pixval = *src_ptr++;
+         pixval =
+           redvalue[image->rgb.red[pixval] >> 8] |
+           greenvalue[image->rgb.green[pixval] >> 8] |
+           bluevalue[image->rgb.blue[pixval] >> 8];
+         value_to_memory(pixval, dst_ptr, bytes_per_pixel);
+         dst_ptr += bytes_per_pixel;
+       }
+      }
+      break;
+    }
+
+    case PseudoColor:
+    {
+      if (bytes_per_pixel == 1)                        /* (common) special case */
+      {
+       for (y=0; y<image->height; y++)
+         for (x=0; x<image->width; x++)
+           *dst_ptr++ = ximageinfo->index[c + *src_ptr++];
+      }
+      else                                     /* general case */
+      {
+       for (y=0; y<image->height; y++)
+       {
+         for (x=0; x<image->width; x++)
+         {
+           value_to_memory(ximageinfo->index[c + *src_ptr++],
+                           dst_ptr, bytes_per_pixel);
+           dst_ptr += bytes_per_pixel;
+         }
+       }
+      }
+      break;
+    }
+
+    default:
+      Error(ERR_RETURN, "display class not supported");
+      Error(ERR_EXIT, "DirectColor, TrueColor or PseudoColor display needed");
+      break;
+  }
+
+  if (redvalue)
+  {
+    free((byte *)redvalue);
+    free((byte *)greenvalue);
+    free((byte *)bluevalue);
+  }
+
+#if DEBUG_TIMING
+  debug_print_timestamp(2, "   CONVERTING IMAGE TO XIMAGE:");
+#endif
+
+  ximageinfo->pixmap = XCreatePixmap(display, window,
+                                    ximage->width, ximage->height,
+                                    ximageinfo->depth);
+
+  XPutImage(ximageinfo->display, ximageinfo->pixmap, gc,
+           ximage, 0, 0, 0, 0, ximage->width, ximage->height);
+
+  free(ximage->data);
+  ximage->data = NULL;
+  XDestroyImage(ximage);
+
+  return(ximageinfo);
+}
+
+void freeXImage(Image *image, XImageInfo *ximageinfo)
+{
+  if (ximageinfo->index != NULL && ximageinfo->no > 0)
+    XFreeColors(ximageinfo->display, ximageinfo->cmap, ximageinfo->index,
+               ximageinfo->no, 0);
+  /* this       ^^^^^^^^^^^^^^ is wrong, because the used color cells
+   * are somewhere between 0 and MAX_COLORS; there are indeed 'ximageinfo->no'
+   * used color cells, but they are not at array position 0 - 'ximageinfo->no'
+   */
+
+  free(ximageinfo);
+}
+
+int Read_PCX_to_Pixmap(Display *display, Window window, GC gc, char *filename,
+                      Pixmap *pixmap, Pixmap *pixmap_mask)
+{
+  Image *image;
+  XImageInfo *ximageinfo;
+  int screen;
+  Visual *visual;
+  int depth;
+
+#if DEBUG_TIMING
+  debug_print_timestamp(2, NULL);      /* initialize timestamp function */
+#endif
+
+  /* read the graphic file in PCX format to image structure */
+  if ((image = Read_PCX_to_Image(filename)) == NULL)
+    return errno_pcx;
+
+#if DEBUG_TIMING
+  printf("%s:\n", filename);
+  debug_print_timestamp(2, "   READING PCX FILE TO IMAGE: ");
+#endif
+
+  screen = DefaultScreen(display);
+  visual = DefaultVisual(display, screen);
+  depth = DefaultDepth(display, screen);
+
+  /* convert image structure to X11 Pixmap */
+  if (!(ximageinfo = Image_to_Pixmap(display, screen, visual,
+                                    window, gc, depth, image)))
+    Error(ERR_EXIT, "cannot convert Image to Pixmap");
+
+  /* if a private colormap has been created, install it */
+  if (ximageinfo->cmap != DefaultColormap(display, screen))
+    XSetWindowColormap(display, window, ximageinfo->cmap);
+
+#if DEBUG_TIMING
+  debug_print_timestamp(2, "   CONVERTING IMAGE TO PIXMAP:");
+#endif
+
+  /* create clip mask for the image */
+  ximageinfo->pixmap_mask = Image_to_Mask(image, display, window);
+
+#if DEBUG_TIMING
+  debug_print_timestamp(2, "   CONVERTING IMAGE TO MASK:  ");
+#endif
+
+  *pixmap = ximageinfo->pixmap;
+  *pixmap_mask = ximageinfo->pixmap_mask;
+
+  return PCX_Success;
+}
+
+#endif /* PLATFORM_UNIX */
+#endif /* TARGET_X11 */
diff --git a/src/libgame/image.h b/src/libgame/image.h
new file mode 100644 (file)
index 0000000..4f55fe3
--- /dev/null
@@ -0,0 +1,63 @@
+/***********************************************************
+*  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                *
+*----------------------------------------------------------*
+*  image.h                                                 *
+***********************************************************/
+
+#ifndef IMAGE_H
+#define IMAGE_H
+
+#include "platform.h"
+
+#ifndef TARGET_SDL
+
+#include "types.h"
+#include "x11.h"
+
+#define MAX_COLORS     256     /* maximal number of colors for each image */
+
+typedef unsigned short Intensity;      /* RGB intensity for X11 */
+
+typedef struct
+{
+  Display  *display;           /* destination display             */
+  int       depth;             /* depth of destination drawable   */
+  Pixel     index[MAX_COLORS]; /* array of pixel values           */
+  int       no;                        /* number of pixels in the array   */
+  Colormap  cmap;              /* colormap used for image         */
+  Pixmap   pixmap;             /* final pixmap                    */
+  Pixmap   pixmap_mask;                /* final pixmap of mask            */
+} XImageInfo;
+
+struct RGBMap
+{
+  unsigned int used;                   /* number of colors used in RGB map */
+  Intensity    red[MAX_COLORS];                /* color values in X style          */
+  Intensity    green[MAX_COLORS];
+  Intensity    blue[MAX_COLORS];
+  boolean      color_used[MAX_COLORS]; /* flag if color cell is used       */
+};
+
+typedef struct
+{
+  struct 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 */
+  byte         *data;          /* image data                          */
+} Image;
+
+Image *newImage(unsigned int, unsigned int, unsigned int);
+void freeImage(Image *);
+void freeXImage(Image *, XImageInfo *);
+int Read_PCX_to_Pixmap(Display *, Window, GC, char *, Pixmap *, Pixmap *);
+
+#endif /* !TARGET_SDL */
+#endif /* IMAGE_H */
diff --git a/src/libgame/joystick_TMP.h b/src/libgame/joystick_TMP.h
new file mode 100644 (file)
index 0000000..ccf728a
--- /dev/null
@@ -0,0 +1,90 @@
+/***********************************************************
+*  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                *
+*----------------------------------------------------------*
+*  joystick.h                                              *
+***********************************************************/
+
+#ifndef JOYSTICK_H
+#define JOYSTICK_H
+
+/* values for the joystick */
+#define JOYSTICK_OFF           0
+#define        JOYSTICK_AVAILABLE      1
+
+#ifdef __FreeBSD__
+#include <machine/joystick.h>
+#define DEV_JOYSTICK_0         "/dev/joy0"
+#define DEV_JOYSTICK_1         "/dev/joy1"
+#define DEV_JOYSTICK_2         "/dev/joy2"
+#define DEV_JOYSTICK_3         "/dev/joy3"
+#else
+#define DEV_JOYSTICK_0         "/dev/js0"
+#define DEV_JOYSTICK_1         "/dev/js1"
+#define DEV_JOYSTICK_2         "/dev/js2"
+#define DEV_JOYSTICK_3         "/dev/js3"
+#endif
+
+/* get these values from the program 'js' from the joystick package, */
+/* set JOYSTICK_PERCENT to a threshold appropriate for your joystick */
+
+#ifdef TARGET_SDL
+#define JOYSTICK_XLEFT         -32767
+#define JOYSTICK_XMIDDLE       0
+#define JOYSTICK_XRIGHT                32767
+#define JOYSTICK_YUPPER                -32767
+#define JOYSTICK_YMIDDLE       0
+#define JOYSTICK_YLOWER                32767
+#else
+#define JOYSTICK_XLEFT         30
+#define JOYSTICK_XMIDDLE       530
+#define JOYSTICK_XRIGHT                1250
+#define JOYSTICK_YUPPER                40
+#define JOYSTICK_YMIDDLE       680
+#define JOYSTICK_YLOWER                1440
+#endif
+
+#define JOYSTICK_PERCENT       25
+
+#define JOY_LEFT               MV_LEFT
+#define JOY_RIGHT              MV_RIGHT
+#define JOY_UP                 MV_UP
+#define JOY_DOWN               MV_DOWN
+#define JOY_BUTTON_1           (1<<4)
+#define JOY_BUTTON_2           (1<<5)
+#define JOY_BUTTON             (JOY_BUTTON_1 | JOY_BUTTON_2)
+
+#define JOY_BUTTON_NOT_PRESSED 0
+#define JOY_BUTTON_PRESSED     1
+#define JOY_BUTTON_NEW_PRESSED 2
+#define JOY_BUTTON_NEW_RELEASED        3
+
+#ifdef NO_JOYSTICK
+#define JOYSTICK_STATUS                JOYSTICK_OFF
+#else
+#define JOYSTICK_STATUS                JOYSTICK_AVAILABLE
+#endif
+
+
+#if defined(TARGET_SDL)
+SDL_Joystick *Get_SDL_Joystick(int);
+boolean Open_SDL_Joystick(int);
+void Close_SDL_Joystick(int);
+boolean Check_SDL_JoystickOpened(int);
+void HandleJoystickEvent(Event *);
+int Get_SDL_Joystick_Axis(int, int);
+#endif
+
+void CheckJoystickData(void);
+int Joystick(int);
+int JoystickButton(int);
+int AnyJoystick(void);
+int AnyJoystickButton(void);
+
+#endif /* JOYSTICK_H */
diff --git a/src/libgame/libgame.c b/src/libgame/libgame.c
new file mode 100644 (file)
index 0000000..8c000c2
--- /dev/null
@@ -0,0 +1,14 @@
+/***********************************************************
+*  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                *
+*----------------------------------------------------------*
+*  libgame.c                                               *
+***********************************************************/
+
+#include "libgame.h"
diff --git a/src/libgame/libgame.h b/src/libgame/libgame.h
new file mode 100644 (file)
index 0000000..b2af140
--- /dev/null
@@ -0,0 +1,29 @@
+/***********************************************************
+*  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                *
+*----------------------------------------------------------*
+*  libgame.h                                               *
+***********************************************************/
+
+#ifndef LIBGAME_H
+#define LIBGAME_H
+
+#include "platform.h"
+#include "types.h"
+#include "private.h"
+#include "system.h"
+#include "random.h"
+#include "buttons.h"
+#include "text.h"
+#include "sound.h"
+#include "image.h"
+#include "pcx.h"
+#include "misc.h"
+
+#endif /* LIBGAME_H */
diff --git a/src/libgame/main_TMP.h b/src/libgame/main_TMP.h
new file mode 120000 (symlink)
index 0000000..31e337c
--- /dev/null
@@ -0,0 +1 @@
+../main.h
\ No newline at end of file
diff --git a/src/libgame/misc.c b/src/libgame/misc.c
new file mode 100644 (file)
index 0000000..bfc6d45
--- /dev/null
@@ -0,0 +1,1390 @@
+/***********************************************************
+*  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                *
+*----------------------------------------------------------*
+*  misc.c                                                  *
+***********************************************************/
+
+#include <time.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <stdarg.h>
+#include <ctype.h>
+
+#if !defined(PLATFORM_WIN32)
+#include <pwd.h>
+#include <sys/param.h>
+#endif
+
+#include "libgame.h"
+
+#include "main_TMP.h"
+
+#include "misc.h"
+
+#include "joystick_TMP.h"
+
+#if defined(PLATFORM_MSDOS)
+volatile unsigned long counter = 0;
+
+void increment_counter()
+{
+  counter++;
+}
+
+END_OF_FUNCTION(increment_counter);
+#endif
+
+
+/* maximal allowed length of a command line option */
+#define MAX_OPTION_LEN         256
+
+#ifdef TARGET_SDL
+static unsigned long mainCounter(int mode)
+{
+  static unsigned long base_ms = 0;
+  unsigned long current_ms;
+  unsigned long counter_ms;
+
+  current_ms = SDL_GetTicks();
+
+  /* reset base time in case of counter initializing or wrap-around */
+  if (mode == INIT_COUNTER || current_ms < base_ms)
+    base_ms = current_ms;
+
+  counter_ms = current_ms - base_ms;
+
+  return counter_ms;           /* return milliseconds since last init */
+}
+
+#else /* !TARGET_SDL */
+
+#if defined(PLATFORM_UNIX)
+static unsigned long mainCounter(int mode)
+{
+  static struct timeval base_time = { 0, 0 };
+  struct timeval current_time;
+  unsigned long counter_ms;
+
+  gettimeofday(&current_time, NULL);
+
+  /* reset base time in case of counter initializing or wrap-around */
+  if (mode == INIT_COUNTER || current_time.tv_sec < base_time.tv_sec)
+    base_time = current_time;
+
+  counter_ms = (current_time.tv_sec  - base_time.tv_sec)  * 1000
+             + (current_time.tv_usec - base_time.tv_usec) / 1000;
+
+  return counter_ms;           /* return milliseconds since last init */
+}
+#endif /* PLATFORM_UNIX */
+#endif /* !TARGET_SDL */
+
+void InitCounter()             /* set counter back to zero */
+{
+#if !defined(PLATFORM_MSDOS)
+  mainCounter(INIT_COUNTER);
+#else
+  LOCK_VARIABLE(counter);
+  LOCK_FUNCTION(increment_counter);
+  install_int_ex(increment_counter, BPS_TO_TIMER(100));
+#endif
+}
+
+unsigned long Counter()        /* get milliseconds since last call of InitCounter() */
+{
+#if !defined(PLATFORM_MSDOS)
+  return mainCounter(READ_COUNTER);
+#else
+  return (counter * 10);
+#endif
+}
+
+static void sleep_milliseconds(unsigned long milliseconds_delay)
+{
+  boolean do_busy_waiting = (milliseconds_delay < 5 ? TRUE : FALSE);
+
+#if defined(PLATFORM_MSDOS)
+  /* don't use select() to perform waiting operations under DOS/Windows
+     environment; always use a busy loop for waiting instead */
+  do_busy_waiting = TRUE;
+#endif
+
+  if (do_busy_waiting)
+  {
+    /* we want to wait only a few ms -- if we assume that we have a
+       kernel timer resolution of 10 ms, we would wait far to long;
+       therefore it's better to do a short interval of busy waiting
+       to get our sleeping time more accurate */
+
+    unsigned long base_counter = Counter(), actual_counter = Counter();
+
+    while (actual_counter < base_counter + milliseconds_delay &&
+          actual_counter >= base_counter)
+      actual_counter = Counter();
+  }
+  else
+  {
+#if defined(TARGET_SDL)
+    SDL_Delay(milliseconds_delay);
+#else
+    struct timeval delay;
+
+    delay.tv_sec  = milliseconds_delay / 1000;
+    delay.tv_usec = 1000 * (milliseconds_delay % 1000);
+
+    if (select(0, NULL, NULL, NULL, &delay) != 0)
+      Error(ERR_WARN, "sleep_milliseconds(): select() failed");
+#endif
+  }
+}
+
+void Delay(unsigned long delay)        /* Sleep specified number of milliseconds */
+{
+  sleep_milliseconds(delay);
+}
+
+boolean FrameReached(unsigned long *frame_counter_var,
+                    unsigned long frame_delay)
+{
+  unsigned long actual_frame_counter = FrameCounter;
+
+  if (actual_frame_counter < *frame_counter_var+frame_delay &&
+      actual_frame_counter >= *frame_counter_var)
+    return(FALSE);
+
+  *frame_counter_var = actual_frame_counter;
+  return(TRUE);
+}
+
+boolean DelayReached(unsigned long *counter_var,
+                    unsigned long delay)
+{
+  unsigned long actual_counter = Counter();
+
+  if (actual_counter < *counter_var + delay &&
+      actual_counter >= *counter_var)
+    return(FALSE);
+
+  *counter_var = actual_counter;
+  return(TRUE);
+}
+
+void WaitUntilDelayReached(unsigned long *counter_var, unsigned long delay)
+{
+  unsigned long actual_counter;
+
+  while(1)
+  {
+    actual_counter = Counter();
+
+    if (actual_counter < *counter_var + delay &&
+       actual_counter >= *counter_var)
+      sleep_milliseconds((*counter_var + delay - actual_counter) / 2);
+    else
+      break;
+  }
+
+  *counter_var = actual_counter;
+}
+
+/* int2str() returns a number converted to a string;
+   the used memory is static, but will be overwritten by later calls,
+   so if you want to save the result, copy it to a private string buffer;
+   there can be 10 local calls of int2str() without buffering the result --
+   the 11th call will then destroy the result from the first call and so on.
+*/
+
+char *int2str(int number, int size)
+{
+  static char shift_array[10][40];
+  static int shift_counter = 0;
+  char *s = shift_array[shift_counter];
+
+  shift_counter = (shift_counter + 1) % 10;
+
+  if (size > 20)
+    size = 20;
+
+  if (size)
+  {
+    sprintf(s, "                    %09d", number);
+    return &s[strlen(s) - size];
+  }
+  else
+  {
+    sprintf(s, "%d", number);
+    return s;
+  }
+}
+
+unsigned int SimpleRND(unsigned int max)
+{
+#if defined(TARGET_SDL)
+  static unsigned long root = 654321;
+  unsigned long current_ms;
+
+  current_ms = SDL_GetTicks();
+  root = root * 4253261 + current_ms;
+  return (root % max);
+#else
+  static unsigned long root = 654321;
+  struct timeval current_time;
+
+  gettimeofday(&current_time, NULL);
+  root = root * 4253261 + current_time.tv_sec + current_time.tv_usec;
+  return (root % max);
+#endif
+}
+
+#ifdef DEBUG
+static unsigned int last_RND_value = 0;
+
+unsigned int last_RND()
+{
+  return last_RND_value;
+}
+#endif
+
+unsigned int RND(unsigned int max)
+{
+#ifdef DEBUG
+  return (last_RND_value = random_linux_libc() % max);
+#else
+  return (random_linux_libc() % max);
+#endif
+}
+
+unsigned int InitRND(long seed)
+{
+#if defined(TARGET_SDL)
+  unsigned long current_ms;
+
+  if (seed == NEW_RANDOMIZE)
+  {
+    current_ms = SDL_GetTicks();
+    srandom_linux_libc((unsigned int) current_ms);
+    return (unsigned int) current_ms;
+  }
+  else
+  {
+    srandom_linux_libc((unsigned int) seed);
+    return (unsigned int) seed;
+  }
+#else
+  struct timeval current_time;
+
+  if (seed == NEW_RANDOMIZE)
+  {
+    gettimeofday(&current_time, NULL);
+    srandom_linux_libc((unsigned int) current_time.tv_usec);
+    return (unsigned int) current_time.tv_usec;
+  }
+  else
+  {
+    srandom_linux_libc((unsigned int) seed);
+    return (unsigned int) seed;
+  }
+#endif
+}
+
+char *getLoginName()
+{
+#if defined(PLATFORM_WIN32)
+  return ANONYMOUS_NAME;
+#else
+  struct passwd *pwd;
+
+  if ((pwd = getpwuid(getuid())) == NULL)
+    return ANONYMOUS_NAME;
+  else
+    return pwd->pw_name;
+#endif
+}
+
+char *getRealName()
+{
+#if defined(PLATFORM_UNIX)
+  struct passwd *pwd;
+
+  if ((pwd = getpwuid(getuid())) == NULL || strlen(pwd->pw_gecos) == 0)
+    return ANONYMOUS_NAME;
+  else
+  {
+    static char real_name[1024];
+    char *from_ptr = pwd->pw_gecos, *to_ptr = real_name;
+
+    if (strchr(pwd->pw_gecos, 'ß') == NULL)
+      return pwd->pw_gecos;
+
+    /* the user's real name contains a 'ß' character (german sharp s),
+       which has no equivalent in upper case letters (which our fonts use) */
+    while (*from_ptr != '\0' && (long)(to_ptr - real_name) < 1024 - 2)
+    {
+      if (*from_ptr != 'ß')
+       *to_ptr++ = *from_ptr++;
+      else
+      {
+       from_ptr++;
+       *to_ptr++ = 's';
+       *to_ptr++ = 's';
+      }
+    }
+    *to_ptr = '\0';
+
+    return real_name;
+  }
+#else /* !PLATFORM_UNIX */
+  return ANONYMOUS_NAME;
+#endif
+}
+
+char *getHomeDir()
+{
+#if defined(PLATFORM_UNIX)
+  static char *home_dir = NULL;
+
+  if (!home_dir)
+  {
+    if (!(home_dir = getenv("HOME")))
+    {
+      struct passwd *pwd;
+
+      if ((pwd = getpwuid(getuid())))
+       home_dir = pwd->pw_dir;
+      else
+       home_dir = ".";
+    }
+  }
+
+  return home_dir;
+#else
+  return ".";
+#endif
+}
+
+char *getPath2(char *path1, char *path2)
+{
+  char *complete_path = checked_malloc(strlen(path1) + 1 +
+                                      strlen(path2) + 1);
+
+  sprintf(complete_path, "%s/%s", path1, path2);
+  return complete_path;
+}
+
+char *getPath3(char *path1, char *path2, char *path3)
+{
+  char *complete_path = checked_malloc(strlen(path1) + 1 +
+                                      strlen(path2) + 1 +
+                                      strlen(path3) + 1);
+
+  sprintf(complete_path, "%s/%s/%s", path1, path2, path3);
+  return complete_path;
+}
+
+char *getStringCopy(char *s)
+{
+  char *s_copy;
+
+  if (s == NULL)
+    return NULL;
+
+  s_copy = checked_malloc(strlen(s) + 1);
+
+  strcpy(s_copy, s);
+  return s_copy;
+}
+
+char *getStringToLower(char *s)
+{
+  char *s_copy = checked_malloc(strlen(s) + 1);
+  char *s_ptr = s_copy;
+
+  while (*s)
+    *s_ptr++ = tolower(*s++);
+  *s_ptr = '\0';
+
+  return s_copy;
+}
+
+void MarkTileDirty(int x, int y)
+{
+  int xx = redraw_x1 + x;
+  int yy = redraw_y1 + y;
+
+  if (!redraw[xx][yy])
+    redraw_tiles++;
+
+  redraw[xx][yy] = TRUE;
+  redraw_mask |= REDRAW_TILES;
+}
+
+void SetBorderElement()
+{
+  int x, y;
+
+  BorderElement = EL_LEERRAUM;
+
+  for(y=0; y<lev_fieldy && BorderElement == EL_LEERRAUM; y++)
+  {
+    for(x=0; x<lev_fieldx; x++)
+    {
+      if (!IS_MASSIVE(Feld[x][y]))
+       BorderElement = EL_BETON;
+
+      if (y != 0 && y != lev_fieldy - 1 && x != lev_fieldx - 1)
+       x = lev_fieldx - 2;
+    }
+  }
+}
+
+void GetOptions(char *argv[])
+{
+  char **options_left = &argv[1];
+
+  /* initialize global program options */
+  options.display_name = NULL;
+  options.server_host = NULL;
+  options.server_port = 0;
+  options.ro_base_directory = RO_BASE_PATH;
+  options.rw_base_directory = RW_BASE_PATH;
+  options.level_directory = RO_BASE_PATH "/" LEVELS_DIRECTORY;
+  options.serveronly = FALSE;
+  options.network = FALSE;
+  options.verbose = FALSE;
+  options.debug = FALSE;
+
+  /* initialize some more global variables */
+  global.frames_per_second = 0;
+  global.fps_slowdown = FALSE;
+  global.fps_slowdown_factor = 1;
+
+  while (*options_left)
+  {
+    char option_str[MAX_OPTION_LEN];
+    char *option = options_left[0];
+    char *next_option = options_left[1];
+    char *option_arg = NULL;
+    int option_len = strlen(option);
+
+    if (option_len >= MAX_OPTION_LEN)
+      Error(ERR_EXIT_HELP, "unrecognized option '%s'", option);
+
+    strcpy(option_str, option);                        /* copy argument into buffer */
+    option = option_str;
+
+    if (strcmp(option, "--") == 0)             /* stop scanning arguments */
+      break;
+
+    if (strncmp(option, "--", 2) == 0)         /* treat '--' like '-' */
+      option++;
+
+    option_arg = strchr(option, '=');
+    if (option_arg == NULL)                    /* no '=' in option */
+      option_arg = next_option;
+    else
+    {
+      *option_arg++ = '\0';                    /* cut argument from option */
+      if (*option_arg == '\0')                 /* no argument after '=' */
+       Error(ERR_EXIT_HELP, "option '%s' has invalid argument", option_str);
+    }
+
+    option_len = strlen(option);
+
+    if (strcmp(option, "-") == 0)
+      Error(ERR_EXIT_HELP, "unrecognized option '%s'", option);
+    else if (strncmp(option, "-help", option_len) == 0)
+    {
+      printf("Usage: %s [options] [server.name [port]]\n"
+            "Options:\n"
+            "  -d, --display machine:0       X server display\n"
+            "  -b, --basepath directory      alternative base directory\n"
+            "  -l, --level directory         alternative level directory\n"
+            "  -s, --serveronly              only start network server\n"
+            "  -n, --network                 network multiplayer game\n"
+            "  -v, --verbose                 verbose mode\n",
+            program_name);
+      exit(0);
+    }
+    else if (strncmp(option, "-display", option_len) == 0)
+    {
+      if (option_arg == NULL)
+       Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str);
+
+      options.display_name = option_arg;
+      if (option_arg == next_option)
+       options_left++;
+    }
+    else if (strncmp(option, "-basepath", option_len) == 0)
+    {
+      if (option_arg == NULL)
+       Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str);
+
+      /* this should be extended to separate options for ro and rw data */
+      options.ro_base_directory = option_arg;
+      options.rw_base_directory = option_arg;
+      if (option_arg == next_option)
+       options_left++;
+
+      /* adjust path for level directory accordingly */
+      options.level_directory =
+       getPath2(options.ro_base_directory, LEVELS_DIRECTORY);
+    }
+    else if (strncmp(option, "-levels", option_len) == 0)
+    {
+      if (option_arg == NULL)
+       Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str);
+
+      options.level_directory = option_arg;
+      if (option_arg == next_option)
+       options_left++;
+    }
+    else if (strncmp(option, "-network", option_len) == 0)
+    {
+      options.network = TRUE;
+    }
+    else if (strncmp(option, "-serveronly", option_len) == 0)
+    {
+      options.serveronly = TRUE;
+    }
+    else if (strncmp(option, "-verbose", option_len) == 0)
+    {
+      options.verbose = TRUE;
+    }
+    else if (strncmp(option, "-debug", option_len) == 0)
+    {
+      options.debug = TRUE;
+    }
+    else if (*option == '-')
+    {
+      Error(ERR_EXIT_HELP, "unrecognized option '%s'", option_str);
+    }
+    else if (options.server_host == NULL)
+    {
+      options.server_host = *options_left;
+    }
+    else if (options.server_port == 0)
+    {
+      options.server_port = atoi(*options_left);
+      if (options.server_port < 1024)
+       Error(ERR_EXIT_HELP, "bad port number '%d'", options.server_port);
+    }
+    else
+      Error(ERR_EXIT_HELP, "too many arguments");
+
+    options_left++;
+  }
+}
+
+void Error(int mode, char *format, ...)
+{
+  char *process_name = "";
+  FILE *error = stderr;
+
+  /* display warnings only when running in verbose mode */
+  if (mode & ERR_WARN && !options.verbose)
+    return;
+
+#if !defined(PLATFORM_UNIX)
+  if ((error = openErrorFile()) == NULL)
+  {
+    printf("Cannot write to error output file!\n");
+    CloseAllAndExit(1);
+  }
+#endif
+
+  if (mode & ERR_SOUND_SERVER)
+    process_name = " sound server";
+  else if (mode & ERR_NETWORK_SERVER)
+    process_name = " network server";
+  else if (mode & ERR_NETWORK_CLIENT)
+    process_name = " network client **";
+
+  if (format)
+  {
+    va_list ap;
+
+    fprintf(error, "%s%s: ", program_name, process_name);
+
+    if (mode & ERR_WARN)
+      fprintf(error, "warning: ");
+
+    va_start(ap, format);
+    vfprintf(error, format, ap);
+    va_end(ap);
+  
+    fprintf(error, "\n");
+  }
+  
+  if (mode & ERR_HELP)
+    fprintf(error, "%s: Try option '--help' for more information.\n",
+           program_name);
+
+  if (mode & ERR_EXIT)
+    fprintf(error, "%s%s: aborting\n", program_name, process_name);
+
+  if (error != stderr)
+    fclose(error);
+
+  if (mode & ERR_EXIT)
+  {
+    if (mode & ERR_FROM_SERVER)
+      exit(1);                         /* child process: normal exit */
+    else
+      CloseAllAndExit(1);              /* main process: clean up stuff */
+  }
+}
+
+void *checked_malloc(unsigned long size)
+{
+  void *ptr;
+
+  ptr = malloc(size);
+
+  if (ptr == NULL)
+    Error(ERR_EXIT, "cannot allocate %d bytes -- out of memory", size);
+
+  return ptr;
+}
+
+void *checked_calloc(unsigned long size)
+{
+  void *ptr;
+
+  ptr = calloc(1, size);
+
+  if (ptr == NULL)
+    Error(ERR_EXIT, "cannot allocate %d bytes -- out of memory", size);
+
+  return ptr;
+}
+
+short getFile16BitInteger(FILE *file, int byte_order)
+{
+  if (byte_order == BYTE_ORDER_BIG_ENDIAN)
+    return ((fgetc(file) <<  8) |
+           (fgetc(file) <<  0));
+  else          /* BYTE_ORDER_LITTLE_ENDIAN */
+    return ((fgetc(file) <<  0) |
+           (fgetc(file) <<  8));
+}
+
+void putFile16BitInteger(FILE *file, short value, int byte_order)
+{
+  if (byte_order == BYTE_ORDER_BIG_ENDIAN)
+  {
+    fputc((value >>  8) & 0xff, file);
+    fputc((value >>  0) & 0xff, file);
+  }
+  else          /* BYTE_ORDER_LITTLE_ENDIAN */
+  {
+    fputc((value >>  0) & 0xff, file);
+    fputc((value >>  8) & 0xff, file);
+  }
+}
+
+int getFile32BitInteger(FILE *file, int byte_order)
+{
+  if (byte_order == BYTE_ORDER_BIG_ENDIAN)
+    return ((fgetc(file) << 24) |
+           (fgetc(file) << 16) |
+           (fgetc(file) <<  8) |
+           (fgetc(file) <<  0));
+  else          /* BYTE_ORDER_LITTLE_ENDIAN */
+    return ((fgetc(file) <<  0) |
+           (fgetc(file) <<  8) |
+           (fgetc(file) << 16) |
+           (fgetc(file) << 24));
+}
+
+void putFile32BitInteger(FILE *file, int value, int byte_order)
+{
+  if (byte_order == BYTE_ORDER_BIG_ENDIAN)
+  {
+    fputc((value >> 24) & 0xff, file);
+    fputc((value >> 16) & 0xff, file);
+    fputc((value >>  8) & 0xff, file);
+    fputc((value >>  0) & 0xff, file);
+  }
+  else          /* BYTE_ORDER_LITTLE_ENDIAN */
+  {
+    fputc((value >>  0) & 0xff, file);
+    fputc((value >>  8) & 0xff, file);
+    fputc((value >> 16) & 0xff, file);
+    fputc((value >> 24) & 0xff, file);
+  }
+}
+
+void getFileChunk(FILE *file, char *chunk_buffer, int *chunk_length,
+                 int byte_order)
+{
+  const int chunk_identifier_length = 4;
+
+  /* read chunk identifier */
+  fgets(chunk_buffer, chunk_identifier_length + 1, file);
+
+  /* read chunk length */
+  *chunk_length = getFile32BitInteger(file, byte_order);
+}
+
+void putFileChunk(FILE *file, char *chunk_name, int chunk_length,
+                 int byte_order)
+{
+  /* write chunk identifier */
+  fputs(chunk_name, file);
+
+  /* write chunk length */
+  putFile32BitInteger(file, chunk_length, byte_order);
+}
+
+#define TRANSLATE_KEYSYM_TO_KEYNAME    0
+#define TRANSLATE_KEYSYM_TO_X11KEYNAME 1
+#define TRANSLATE_X11KEYNAME_TO_KEYSYM 2
+
+void translate_keyname(Key *keysym, char **x11name, char **name, int mode)
+{
+  static struct
+  {
+    Key key;
+    char *x11name;
+    char *name;
+  } translate_key[] =
+  {
+    /* normal cursor keys */
+    { KSYM_Left,       "XK_Left",              "cursor left" },
+    { KSYM_Right,      "XK_Right",             "cursor right" },
+    { KSYM_Up,         "XK_Up",                "cursor up" },
+    { KSYM_Down,       "XK_Down",              "cursor down" },
+
+    /* keypad cursor keys */
+#ifdef KSYM_KP_Left
+    { KSYM_KP_Left,    "XK_KP_Left",           "keypad left" },
+    { KSYM_KP_Right,   "XK_KP_Right",          "keypad right" },
+    { KSYM_KP_Up,      "XK_KP_Up",             "keypad up" },
+    { KSYM_KP_Down,    "XK_KP_Down",           "keypad down" },
+#endif
+
+    /* other keypad keys */
+#ifdef KSYM_KP_Enter
+    { KSYM_KP_Enter,   "XK_KP_Enter",          "keypad enter" },
+    { KSYM_KP_Add,     "XK_KP_Add",            "keypad +" },
+    { KSYM_KP_Subtract,        "XK_KP_Subtract",       "keypad -" },
+    { KSYM_KP_Multiply,        "XK_KP_Multiply",       "keypad mltply" },
+    { KSYM_KP_Divide,  "XK_KP_Divide",         "keypad /" },
+    { KSYM_KP_Separator,"XK_KP_Separator",     "keypad ," },
+#endif
+
+    /* modifier keys */
+    { KSYM_Shift_L,    "XK_Shift_L",           "left shift" },
+    { KSYM_Shift_R,    "XK_Shift_R",           "right shift" },
+    { KSYM_Control_L,  "XK_Control_L",         "left control" },
+    { KSYM_Control_R,  "XK_Control_R",         "right control" },
+    { KSYM_Meta_L,     "XK_Meta_L",            "left meta" },
+    { KSYM_Meta_R,     "XK_Meta_R",            "right meta" },
+    { KSYM_Alt_L,      "XK_Alt_L",             "left alt" },
+    { KSYM_Alt_R,      "XK_Alt_R",             "right alt" },
+    { KSYM_Super_L,    "XK_Super_L",           "left super" },  /* Win-L */
+    { KSYM_Super_R,    "XK_Super_R",           "right super" }, /* Win-R */
+    { KSYM_Mode_switch,        "XK_Mode_switch",       "mode switch" }, /* Alt-R */
+    { KSYM_Multi_key,  "XK_Multi_key",         "multi key" },   /* Ctrl-R */
+
+    /* some special keys */
+    { KSYM_BackSpace,  "XK_BackSpace",         "backspace" },
+    { KSYM_Delete,     "XK_Delete",            "delete" },
+    { KSYM_Insert,     "XK_Insert",            "insert" },
+    { KSYM_Tab,                "XK_Tab",               "tab" },
+    { KSYM_Home,       "XK_Home",              "home" },
+    { KSYM_End,                "XK_End",               "end" },
+    { KSYM_Page_Up,    "XK_Page_Up",           "page up" },
+    { KSYM_Page_Down,  "XK_Page_Down",         "page down" },
+    { KSYM_Menu,       "XK_Menu",              "menu" },        /* Win-Menu */
+
+    /* ASCII 0x20 to 0x40 keys (except numbers) */
+    { KSYM_space,      "XK_space",             "space" },
+    { KSYM_exclam,     "XK_exclam",            "!" },
+    { KSYM_quotedbl,   "XK_quotedbl",          "\"" },
+    { KSYM_numbersign, "XK_numbersign",        "#" },
+    { KSYM_dollar,     "XK_dollar",            "$" },
+    { KSYM_percent,    "XK_percent",           "%" },
+    { KSYM_ampersand,  "XK_ampersand",         "&" },
+    { KSYM_apostrophe, "XK_apostrophe",        "'" },
+    { KSYM_parenleft,  "XK_parenleft",         "(" },
+    { KSYM_parenright, "XK_parenright",        ")" },
+    { KSYM_asterisk,   "XK_asterisk",          "*" },
+    { KSYM_plus,       "XK_plus",              "+" },
+    { KSYM_comma,      "XK_comma",             "," },
+    { KSYM_minus,      "XK_minus",             "-" },
+    { KSYM_period,     "XK_period",            "." },
+    { KSYM_slash,      "XK_slash",             "/" },
+    { KSYM_colon,      "XK_colon",             ":" },
+    { KSYM_semicolon,  "XK_semicolon",         ";" },
+    { KSYM_less,       "XK_less",              "<" },
+    { KSYM_equal,      "XK_equal",             "=" },
+    { KSYM_greater,    "XK_greater",           ">" },
+    { KSYM_question,   "XK_question",          "?" },
+    { KSYM_at,         "XK_at",                "@" },
+
+    /* more ASCII keys */
+    { KSYM_bracketleft,        "XK_bracketleft",       "[" },
+    { KSYM_backslash,  "XK_backslash",         "backslash" },
+    { KSYM_bracketright,"XK_bracketright",     "]" },
+    { KSYM_asciicircum,        "XK_asciicircum",       "circumflex" },
+    { KSYM_underscore, "XK_underscore",        "_" },
+    { KSYM_grave,      "XK_grave",             "grave" },
+    { KSYM_quoteleft,  "XK_quoteleft",         "quote left" },
+    { KSYM_braceleft,  "XK_braceleft",         "brace left" },
+    { KSYM_bar,                "XK_bar",               "bar" },
+    { KSYM_braceright, "XK_braceright",        "brace right" },
+    { KSYM_asciitilde, "XK_asciitilde",        "ascii tilde" },
+
+    /* special (non-ASCII) keys */
+    { KSYM_Adiaeresis, "XK_Adiaeresis",        "Ä" },
+    { KSYM_Odiaeresis, "XK_Odiaeresis",        "Ö" },
+    { KSYM_Udiaeresis, "XK_Udiaeresis",        "Ü" },
+    { KSYM_adiaeresis, "XK_adiaeresis",        "ä" },
+    { KSYM_odiaeresis, "XK_odiaeresis",        "ö" },
+    { KSYM_udiaeresis, "XK_udiaeresis",        "ü" },
+    { KSYM_ssharp,     "XK_ssharp",            "sharp s" },
+
+    /* end-of-array identifier */
+    { 0,                NULL,                  NULL }
+  };
+
+  int i;
+
+  if (mode == TRANSLATE_KEYSYM_TO_KEYNAME)
+  {
+    static char name_buffer[30];
+    Key key = *keysym;
+
+    if (key >= KSYM_A && key <= KSYM_Z)
+      sprintf(name_buffer, "%c", 'A' + (char)(key - KSYM_A));
+    else if (key >= KSYM_a && key <= KSYM_z)
+      sprintf(name_buffer, "%c", 'a' + (char)(key - KSYM_a));
+    else if (key >= KSYM_0 && key <= KSYM_9)
+      sprintf(name_buffer, "%c", '0' + (char)(key - KSYM_0));
+    else if (key >= KSYM_KP_0 && key <= KSYM_KP_9)
+      sprintf(name_buffer, "keypad %c", '0' + (char)(key - KSYM_KP_0));
+    else if (key >= KSYM_F1 && key <= KSYM_F24)
+      sprintf(name_buffer, "function F%d", (int)(key - KSYM_F1 + 1));
+    else if (key == KSYM_UNDEFINED)
+      strcpy(name_buffer, "(undefined)");
+    else
+    {
+      i = 0;
+
+      do
+      {
+       if (key == translate_key[i].key)
+       {
+         strcpy(name_buffer, translate_key[i].name);
+         break;
+       }
+      }
+      while (translate_key[++i].name);
+
+      if (!translate_key[i].name)
+       strcpy(name_buffer, "(unknown)");
+    }
+
+    *name = name_buffer;
+  }
+  else if (mode == TRANSLATE_KEYSYM_TO_X11KEYNAME)
+  {
+    static char name_buffer[30];
+    Key key = *keysym;
+
+    if (key >= KSYM_A && key <= KSYM_Z)
+      sprintf(name_buffer, "XK_%c", 'A' + (char)(key - KSYM_A));
+    else if (key >= KSYM_a && key <= KSYM_z)
+      sprintf(name_buffer, "XK_%c", 'a' + (char)(key - KSYM_a));
+    else if (key >= KSYM_0 && key <= KSYM_9)
+      sprintf(name_buffer, "XK_%c", '0' + (char)(key - KSYM_0));
+    else if (key >= KSYM_KP_0 && key <= KSYM_KP_9)
+      sprintf(name_buffer, "XK_KP_%c", '0' + (char)(key - KSYM_KP_0));
+    else if (key >= KSYM_F1 && key <= KSYM_F24)
+      sprintf(name_buffer, "XK_F%d", (int)(key - KSYM_F1 + 1));
+    else if (key == KSYM_UNDEFINED)
+      strcpy(name_buffer, "[undefined]");
+    else
+    {
+      i = 0;
+
+      do
+      {
+       if (key == translate_key[i].key)
+       {
+         strcpy(name_buffer, translate_key[i].x11name);
+         break;
+       }
+      }
+      while (translate_key[++i].x11name);
+
+      if (!translate_key[i].x11name)
+       sprintf(name_buffer, "0x%04lx", (unsigned long)key);
+    }
+
+    *x11name = name_buffer;
+  }
+  else if (mode == TRANSLATE_X11KEYNAME_TO_KEYSYM)
+  {
+    Key key = KSYM_UNDEFINED;
+    char *name_ptr = *x11name;
+
+    if (strncmp(name_ptr, "XK_", 3) == 0 && strlen(name_ptr) == 4)
+    {
+      char c = name_ptr[3];
+
+      if (c >= 'A' && c <= 'Z')
+       key = KSYM_A + (Key)(c - 'A');
+      else if (c >= 'a' && c <= 'z')
+       key = KSYM_a + (Key)(c - 'a');
+      else if (c >= '0' && c <= '9')
+       key = KSYM_0 + (Key)(c - '0');
+    }
+    else if (strncmp(name_ptr, "XK_KP_", 6) == 0 && strlen(name_ptr) == 7)
+    {
+      char c = name_ptr[6];
+
+      if (c >= '0' && c <= '9')
+       key = KSYM_0 + (Key)(c - '0');
+    }
+    else if (strncmp(name_ptr, "XK_F", 4) == 0 && strlen(name_ptr) <= 6)
+    {
+      char c1 = name_ptr[4];
+      char c2 = name_ptr[5];
+      int d = 0;
+
+      if ((c1 >= '0' && c1 <= '9') &&
+         ((c2 >= '0' && c1 <= '9') || c2 == '\0'))
+       d = atoi(&name_ptr[4]);
+
+      if (d >=1 && d <= 24)
+       key = KSYM_F1 + (Key)(d - 1);
+    }
+    else if (strncmp(name_ptr, "XK_", 3) == 0)
+    {
+      i = 0;
+
+      do
+      {
+       if (strcmp(name_ptr, translate_key[i].x11name) == 0)
+       {
+         key = translate_key[i].key;
+         break;
+       }
+      }
+      while (translate_key[++i].x11name);
+    }
+    else if (strncmp(name_ptr, "0x", 2) == 0)
+    {
+      unsigned long value = 0;
+
+      name_ptr += 2;
+
+      while (name_ptr)
+      {
+       char c = *name_ptr++;
+       int d = -1;
+
+       if (c >= '0' && c <= '9')
+         d = (int)(c - '0');
+       else if (c >= 'a' && c <= 'f')
+         d = (int)(c - 'a' + 10);
+       else if (c >= 'A' && c <= 'F')
+         d = (int)(c - 'A' + 10);
+
+       if (d == -1)
+       {
+         value = -1;
+         break;
+       }
+
+       value = value * 16 + d;
+      }
+
+      if (value != -1)
+       key = (Key)value;
+    }
+
+    *keysym = key;
+  }
+}
+
+char *getKeyNameFromKey(Key key)
+{
+  char *name;
+
+  translate_keyname(&key, NULL, &name, TRANSLATE_KEYSYM_TO_KEYNAME);
+  return name;
+}
+
+char *getX11KeyNameFromKey(Key key)
+{
+  char *x11name;
+
+  translate_keyname(&key, &x11name, NULL, TRANSLATE_KEYSYM_TO_X11KEYNAME);
+  return x11name;
+}
+
+Key getKeyFromX11KeyName(char *x11name)
+{
+  Key key;
+
+  translate_keyname(&key, &x11name, NULL, TRANSLATE_X11KEYNAME_TO_KEYSYM);
+  return key;
+}
+
+char getCharFromKey(Key key)
+{
+  char *keyname = getKeyNameFromKey(key);
+  char letter = 0;
+
+  if (strlen(keyname) == 1)
+    letter = keyname[0];
+  else if (strcmp(keyname, "space") == 0)
+    letter = ' ';
+  else if (strcmp(keyname, "circumflex") == 0)
+    letter = '^';
+
+  return letter;
+}
+
+#define TRANSLATE_JOYSYMBOL_TO_JOYNAME 0
+#define TRANSLATE_JOYNAME_TO_JOYSYMBOL 1
+
+void translate_joyname(int *joysymbol, char **name, int mode)
+{
+  static struct
+  {
+    int joysymbol;
+    char *name;
+  } translate_joy[] =
+  {
+    { JOY_LEFT,                "joystick_left" },
+    { JOY_RIGHT,       "joystick_right" },
+    { JOY_UP,          "joystick_up" },
+    { JOY_DOWN,                "joystick_down" },
+    { JOY_BUTTON_1,    "joystick_button_1" },
+    { JOY_BUTTON_2,    "joystick_button_2" },
+  };
+
+  int i;
+
+  if (mode == TRANSLATE_JOYSYMBOL_TO_JOYNAME)
+  {
+    *name = "[undefined]";
+
+    for (i=0; i<6; i++)
+    {
+      if (*joysymbol == translate_joy[i].joysymbol)
+      {
+       *name = translate_joy[i].name;
+       break;
+      }
+    }
+  }
+  else if (mode == TRANSLATE_JOYNAME_TO_JOYSYMBOL)
+  {
+    *joysymbol = 0;
+
+    for (i=0; i<6; i++)
+    {
+      if (strcmp(*name, translate_joy[i].name) == 0)
+      {
+       *joysymbol = translate_joy[i].joysymbol;
+       break;
+      }
+    }
+  }
+}
+
+char *getJoyNameFromJoySymbol(int joysymbol)
+{
+  char *name;
+
+  translate_joyname(&joysymbol, &name, TRANSLATE_JOYSYMBOL_TO_JOYNAME);
+  return name;
+}
+
+int getJoySymbolFromJoyName(char *name)
+{
+  int joysymbol;
+
+  translate_joyname(&joysymbol, &name, TRANSLATE_JOYNAME_TO_JOYSYMBOL);
+  return joysymbol;
+}
+
+int getJoystickNrFromDeviceName(char *device_name)
+{
+  char c;
+  int joystick_nr = 0;
+
+  if (device_name == NULL || device_name[0] == '\0')
+    return 0;
+
+  c = device_name[strlen(device_name) - 1];
+
+  if (c >= '0' && c <= '9')
+    joystick_nr = (int)(c - '0');
+
+  if (joystick_nr < 0 || joystick_nr >= MAX_PLAYERS)
+    joystick_nr = 0;
+
+  return joystick_nr;
+}
+
+/* ------------------------------------------------------------------------- */
+/* some functions to handle lists of level directories                       */
+/* ------------------------------------------------------------------------- */
+
+struct LevelDirInfo *newLevelDirInfo()
+{
+  return checked_calloc(sizeof(struct LevelDirInfo));
+}
+
+void pushLevelDirInfo(struct LevelDirInfo **node_first,
+                     struct LevelDirInfo *node_new)
+{
+  node_new->next = *node_first;
+  *node_first = node_new;
+}
+
+int numLevelDirInfo(struct LevelDirInfo *node)
+{
+  int num = 0;
+
+  while (node)
+  {
+    num++;
+    node = node->next;
+  }
+
+  return num;
+}
+
+boolean validLevelSeries(struct LevelDirInfo *node)
+{
+  return (node != NULL && !node->node_group && !node->parent_link);
+}
+
+struct LevelDirInfo *getFirstValidLevelSeries(struct LevelDirInfo *node)
+{
+  if (node == NULL)
+  {
+    if (leveldir_first)                /* start with first level directory entry */
+      return getFirstValidLevelSeries(leveldir_first);
+    else
+      return NULL;
+  }
+  else if (node->node_group)   /* enter level group (step down into tree) */
+    return getFirstValidLevelSeries(node->node_group);
+  else if (node->parent_link)  /* skip start entry of level group */
+  {
+    if (node->next)            /* get first real level series entry */
+      return getFirstValidLevelSeries(node->next);
+    else                       /* leave empty level group and go on */
+      return getFirstValidLevelSeries(node->node_parent->next);
+  }
+  else                         /* this seems to be a regular level series */
+    return node;
+}
+
+struct LevelDirInfo *getLevelDirInfoFirstGroupEntry(struct LevelDirInfo *node)
+{
+  if (node == NULL)
+    return NULL;
+
+  if (node->node_parent == NULL)               /* top level group */
+    return leveldir_first;
+  else                                         /* sub level group */
+    return node->node_parent->node_group;
+}
+
+int numLevelDirInfoInGroup(struct LevelDirInfo *node)
+{
+  return numLevelDirInfo(getLevelDirInfoFirstGroupEntry(node));
+}
+
+int posLevelDirInfo(struct LevelDirInfo *node)
+{
+  struct LevelDirInfo *node_cmp = getLevelDirInfoFirstGroupEntry(node);
+  int pos = 0;
+
+  while (node_cmp)
+  {
+    if (node_cmp == node)
+      return pos;
+
+    pos++;
+    node_cmp = node_cmp->next;
+  }
+
+  return 0;
+}
+
+struct LevelDirInfo *getLevelDirInfoFromPos(struct LevelDirInfo *node, int pos)
+{
+  struct LevelDirInfo *node_default = node;
+  int pos_cmp = 0;
+
+  while (node)
+  {
+    if (pos_cmp == pos)
+      return node;
+
+    pos_cmp++;
+    node = node->next;
+  }
+
+  return node_default;
+}
+
+struct LevelDirInfo *getLevelDirInfoFromFilenameExt(struct LevelDirInfo *node,
+                                                   char *filename)
+{
+  if (filename == NULL)
+    return NULL;
+
+  while (node)
+  {
+    if (node->node_group)
+    {
+      struct LevelDirInfo *node_group;
+
+      node_group = getLevelDirInfoFromFilenameExt(node->node_group, filename);
+
+      if (node_group)
+       return node_group;
+    }
+    else if (!node->parent_link)
+    {
+      if (strcmp(filename, node->filename) == 0)
+       return node;
+    }
+
+    node = node->next;
+  }
+
+  return NULL;
+}
+
+struct LevelDirInfo *getLevelDirInfoFromFilename(char *filename)
+{
+  return getLevelDirInfoFromFilenameExt(leveldir_first, filename);
+}
+
+void dumpLevelDirInfo(struct LevelDirInfo *node, int depth)
+{
+  int i;
+
+  while (node)
+  {
+    for (i=0; i<depth * 3; i++)
+      printf(" ");
+
+    printf("filename == '%s'\n", node->filename);
+
+    if (node->node_group != NULL)
+      dumpLevelDirInfo(node->node_group, depth + 1);
+
+    node = node->next;
+  }
+}
+
+void sortLevelDirInfo(struct LevelDirInfo **node_first,
+                     int (*compare_function)(const void *, const void *))
+{
+  int num_nodes = numLevelDirInfo(*node_first);
+  struct LevelDirInfo **sort_array;
+  struct LevelDirInfo *node = *node_first;
+  int i = 0;
+
+  if (num_nodes == 0)
+    return;
+
+  /* allocate array for sorting structure pointers */
+  sort_array = checked_calloc(num_nodes * sizeof(struct LevelDirInfo *));
+
+  /* writing structure pointers to sorting array */
+  while (i < num_nodes && node)                /* double boundary check... */
+  {
+    sort_array[i] = node;
+
+    i++;
+    node = node->next;
+  }
+
+  /* sorting the structure pointers in the sorting array */
+  qsort(sort_array, num_nodes, sizeof(struct LevelDirInfo *),
+       compare_function);
+
+  /* update the linkage of list elements with the sorted node array */
+  for (i=0; i<num_nodes - 1; i++)
+    sort_array[i]->next = sort_array[i + 1];
+  sort_array[num_nodes - 1]->next = NULL;
+
+  /* update the linkage of the main list anchor pointer */
+  *node_first = sort_array[0];
+
+  free(sort_array);
+
+  /* now recursively sort the level group structures */
+  node = *node_first;
+  while (node)
+  {
+    if (node->node_group != NULL)
+      sortLevelDirInfo(&node->node_group, compare_function);
+
+    node = node->next;
+  }
+}
+
+inline void swap_numbers(int *i1, int *i2)
+{
+  int help = *i1;
+
+  *i1 = *i2;
+  *i2 = help;
+}
+
+inline void swap_number_pairs(int *x1, int *y1, int *x2, int *y2)
+{
+  int help_x = *x1;
+  int help_y = *y1;
+
+  *x1 = *x2;
+  *x2 = help_x;
+
+  *y1 = *y2;
+  *y2 = help_y;
+}
+
+
+/* ------------------------------------------------------------------------- */
+/* the following is only for debugging purpose and normally not used         */
+/* ------------------------------------------------------------------------- */
+
+#define DEBUG_NUM_TIMESTAMPS   3
+
+void debug_print_timestamp(int counter_nr, char *message)
+{
+  static long counter[DEBUG_NUM_TIMESTAMPS][2];
+
+  if (counter_nr >= DEBUG_NUM_TIMESTAMPS)
+    Error(ERR_EXIT, "debugging: increase DEBUG_NUM_TIMESTAMPS in misc.c");
+
+  counter[counter_nr][0] = Counter();
+
+  if (message)
+    printf("%s %.2f seconds\n", message,
+          (float)(counter[counter_nr][0] - counter[counter_nr][1]) / 1000);
+
+  counter[counter_nr][1] = Counter();
+}
diff --git a/src/libgame/misc.h b/src/libgame/misc.h
new file mode 100644 (file)
index 0000000..3002844
--- /dev/null
@@ -0,0 +1,103 @@
+/***********************************************************
+*  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                *
+*----------------------------------------------------------*
+*  misc.h                                                  *
+***********************************************************/
+
+#ifndef MISC_H
+#define MISC_H
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgame.h"
+
+/* values for InitCounter() and Counter() */
+#define INIT_COUNTER                   0
+#define READ_COUNTER                   1
+
+/* values for InitRND() */
+#define NEW_RANDOMIZE                  -1
+
+/* values for Error() */
+#define ERR_RETURN                     0
+#define ERR_WARN                       (1 << 0)
+#define ERR_EXIT                       (1 << 1)
+#define ERR_HELP                       (1 << 2)
+#define ERR_SOUND_SERVER               (1 << 3)
+#define ERR_NETWORK_SERVER             (1 << 4)
+#define ERR_NETWORK_CLIENT             (1 << 5)
+#define ERR_FROM_SERVER                        (ERR_SOUND_SERVER | ERR_NETWORK_SERVER)
+#define ERR_EXIT_HELP                  (ERR_EXIT | ERR_HELP)
+#define ERR_EXIT_SOUND_SERVER          (ERR_EXIT | ERR_SOUND_SERVER)
+#define ERR_EXIT_NETWORK_SERVER                (ERR_EXIT | ERR_NETWORK_SERVER)
+#define ERR_EXIT_NETWORK_CLIENT                (ERR_EXIT | ERR_NETWORK_CLIENT)
+
+/* values for getFile...() and putFile...() */
+#define BYTE_ORDER_BIG_ENDIAN          0
+#define BYTE_ORDER_LITTLE_ENDIAN       1
+
+void InitCounter(void);
+unsigned long Counter(void);
+void Delay(unsigned long);
+boolean FrameReached(unsigned long *, unsigned long);
+boolean DelayReached(unsigned long *, unsigned long);
+void WaitUntilDelayReached(unsigned long *, unsigned long);
+char *int2str(int, int);
+unsigned int SimpleRND(unsigned int);
+unsigned int RND(unsigned int);
+unsigned int InitRND(long);
+char *getLoginName(void);
+char *getRealName(void);
+char *getHomeDir(void);
+char *getPath2(char *, char *);
+char *getPath3(char *, char *, char*);
+char *getStringCopy(char *);
+char *getStringToLower(char *);
+void MarkTileDirty(int, int);
+void SetBorderElement();
+void GetOptions(char **);
+void Error(int, char *, ...);
+void *checked_malloc(unsigned long);
+void *checked_calloc(unsigned long);
+short getFile16BitInteger(FILE *, int);
+void putFile16BitInteger(FILE *, short, int);
+int getFile32BitInteger(FILE *, int);
+void putFile32BitInteger(FILE *, int, int);
+void getFileChunk(FILE *, char *, int *, int);
+void putFileChunk(FILE *, char *, int, int);
+char *getKeyNameFromKey(Key);
+char *getX11KeyNameFromKey(Key);
+Key getKeyFromX11KeyName(char *);
+char getCharFromKey(Key);
+char *getJoyNameFromJoySymbol(int);
+int getJoySymbolFromJoyName(char *);
+int getJoystickNrFromDeviceName(char *);
+
+struct LevelDirInfo *newLevelDirInfo();
+void pushLevelDirInfo(struct LevelDirInfo **, struct LevelDirInfo *);
+int numLevelDirInfo(struct LevelDirInfo *);
+boolean validLevelSeries(struct LevelDirInfo *);
+struct LevelDirInfo *getFirstValidLevelSeries(struct LevelDirInfo *);
+struct LevelDirInfo *getLevelDirInfoFirstGroupEntry(struct LevelDirInfo *);
+int numLevelDirInfoInGroup(struct LevelDirInfo *);
+int posLevelDirInfo(struct LevelDirInfo *);
+struct LevelDirInfo *getLevelDirInfoFromPos(struct LevelDirInfo *, int);
+struct LevelDirInfo *getLevelDirInfoFromFilename(char *);
+void dumpLevelDirInfo(struct LevelDirInfo *, int);
+void sortLevelDirInfo(struct LevelDirInfo **,
+                     int (*compare_function)(const void *, const void *));
+
+inline void swap_numbers(int *, int *);
+inline void swap_number_pairs(int *, int *, int *, int *);
+
+void debug_print_timestamp(int, char *);
+
+#endif /* MISC_H */
diff --git a/src/libgame/msdos.c b/src/libgame/msdos.c
new file mode 100644 (file)
index 0000000..cc8aedd
--- /dev/null
@@ -0,0 +1,929 @@
+/***********************************************************
+*  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             *
+*----------------------------------------------------------*
+*  msdos.c                                                 *
+***********************************************************/
+
+#include "libgame.h"
+
+#if defined(PLATFORM_MSDOS)
+
+/* allegro driver declarations */
+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)
+
+/* allegro global variables */
+extern volatile int key_shifts;
+extern int num_joysticks;
+extern JOYSTICK_INFO joy[];
+extern int i_love_bill;
+
+/* internal variables of msdos.c */
+static boolean keyboard_auto_repeat = TRUE;
+static int key_press_state[MAX_SCANCODES];
+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;
+
+static RGB global_colormap[MAX_COLORS];
+static int global_colormap_entries_used = 0;
+
+boolean wait_for_vsync;
+
+/*
+extern int playing_sounds;
+extern struct SoundControl playlist[MAX_SOUNDS_PLAYING];
+extern struct SoundControl emptySoundControl;
+*/
+
+static BITMAP *Read_PCX_to_AllegroBitmap(char *);
+
+static void allegro_init_drivers()
+{
+  int i;
+
+  for (i=0; i<MAX_EVENT_BUFFER; i++)
+    event_buffer[i].type = 0;
+
+  for (i=0; i<MAX_SCANCODES; i++)
+    key_press_state[i] = KeyReleaseMask;
+
+  last_mouse_pos = mouse_pos;
+  last_mouse_b = 0;
+
+  pending_events = 0;
+  clear_keybuf();
+
+  /* enable Windows friendly timer mode (already default under Windows) */
+  i_love_bill = TRUE;
+
+  install_keyboard();
+  install_timer();
+  if (install_mouse() > 0)
+    mouse_installed = TRUE;
+
+  last_joystick_state = 0;
+  joystick_event = FALSE;
+}
+
+static boolean allegro_init_audio()
+{
+  reserve_voices(MAX_SOUNDS_PLAYING, 0);
+
+  if (install_sound(DIGI_AUTODETECT, MIDI_NONE, NULL) == -1)
+    if (install_sound(DIGI_SB, MIDI_NONE, NULL) == -1)
+      return FALSE;
+
+  return TRUE;
+}
+
+static 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;
+}
+
+static void unhide_mouse(Display *display)
+{
+  if (mouse_installed)
+    show_mouse(video_bitmap);
+}
+
+static KeySym ScancodeToKeySym(byte scancode)
+{
+  switch(scancode)
+  {
+    case KEY_ESC:              return XK_Escape;
+    case KEY_1:                        return XK_1;
+    case KEY_2:                        return XK_2;
+    case KEY_3:                        return XK_3;
+    case KEY_4:                        return XK_4;
+    case KEY_5:                        return XK_5;
+    case KEY_6:                        return XK_6;
+    case KEY_7:                        return XK_7;
+    case KEY_8:                        return XK_8;
+    case KEY_9:                        return XK_9;
+    case KEY_0:                        return XK_0;
+    case KEY_MINUS:            return XK_minus;
+    case KEY_EQUALS:           return XK_equal;
+    case KEY_BACKSPACE:                return XK_BackSpace;
+    case KEY_TAB:              return XK_Tab;
+    case KEY_Q:                        return XK_q;
+    case KEY_W:                        return XK_w;
+    case KEY_E:                        return XK_e;
+    case KEY_R:                        return XK_r;
+    case KEY_T:                        return XK_t;
+    case KEY_Y:                        return XK_y;
+    case KEY_U:                        return XK_u;
+    case KEY_I:                        return XK_i;
+    case KEY_O:                        return XK_o;
+    case KEY_P:                        return XK_p;
+    case KEY_OPENBRACE:                return XK_braceleft;
+    case KEY_CLOSEBRACE:       return XK_braceright;
+    case KEY_ENTER:            return XK_Return;
+    case KEY_LCONTROL:         return XK_Control_L;
+    case KEY_A:                        return XK_a;
+    case KEY_S:                        return XK_s;
+    case KEY_D:                        return XK_d;
+    case KEY_F:                        return XK_f;
+    case KEY_G:                        return XK_g;
+    case KEY_H:                        return XK_h;
+    case KEY_J:                        return XK_j;
+    case KEY_K:                        return XK_k;
+    case KEY_L:                        return XK_l;
+    case KEY_COLON:            return XK_colon;
+    case KEY_QUOTE:            return XK_apostrophe;
+    case KEY_TILDE:            return XK_asciitilde;
+    case KEY_LSHIFT:           return XK_Shift_L;
+    case KEY_BACKSLASH:                return XK_backslash;
+    case KEY_Z:                        return XK_z;
+    case KEY_X:                        return XK_x;
+    case KEY_C:                        return XK_c;
+    case KEY_V:                        return XK_v;
+    case KEY_B:                        return XK_b;
+    case KEY_N:                        return XK_n;
+    case KEY_M:                        return XK_m;
+    case KEY_COMMA:            return XK_comma;
+    case KEY_STOP:             return XK_period;
+    case KEY_SLASH:            return XK_slash;
+    case KEY_RSHIFT:           return XK_Shift_R;
+    case KEY_ASTERISK:         return XK_KP_Multiply;
+    case KEY_ALT:              return XK_Alt_L;
+    case KEY_SPACE:            return XK_space;
+    case KEY_CAPSLOCK:         return XK_Caps_Lock;
+    case KEY_F1:               return XK_F1;
+    case KEY_F2:               return XK_F2;
+    case KEY_F3:               return XK_F3;
+    case KEY_F4:               return XK_F4;
+    case KEY_F5:               return XK_F5;
+    case KEY_F6:               return XK_F6;
+    case KEY_F7:               return XK_F7;
+    case KEY_F8:               return XK_F8;
+    case KEY_F9:               return XK_F9;
+    case KEY_F10:              return XK_F10;
+    case KEY_NUMLOCK:          return XK_Num_Lock;
+    case KEY_SCRLOCK:          return XK_Scroll_Lock;
+    case KEY_HOME:             return XK_Home;
+    case KEY_UP:               return XK_Up;
+    case KEY_PGUP:             return XK_Page_Up;
+    case KEY_MINUS_PAD:                return XK_KP_Subtract;
+    case KEY_LEFT:             return XK_Left;
+    case KEY_5_PAD:            return XK_KP_5;
+    case KEY_RIGHT:            return XK_Right;
+    case KEY_PLUS_PAD:         return XK_KP_Add;
+    case KEY_END:              return XK_End;
+    case KEY_DOWN:             return XK_Down;
+    case KEY_PGDN:             return XK_Page_Down;
+    case KEY_INSERT:           return XK_Insert;
+    case KEY_DEL:              return XK_Delete;
+    case KEY_PRTSCR:           return XK_Print;
+    case KEY_F11:              return XK_F11;
+    case KEY_F12:              return XK_F12;
+    case KEY_LWIN:             return XK_Meta_L;
+    case KEY_RWIN:             return XK_Meta_R;
+    case KEY_MENU:             return XK_Menu;
+    case KEY_PAD:              return XK_VoidSymbol;
+    case KEY_RCONTROL:         return XK_Control_R;
+    case KEY_ALTGR:            return XK_Alt_R;
+    case KEY_SLASH2:           return XK_KP_Divide;
+    case KEY_PAUSE:            return XK_Pause;
+
+    case NEW_KEY_BACKSLASH:    return XK_backslash;
+    case NEW_KEY_1_PAD:                return XK_KP_1;
+    case NEW_KEY_2_PAD:                return XK_KP_2;
+    case NEW_KEY_3_PAD:                return XK_KP_3;
+    case NEW_KEY_4_PAD:                return XK_KP_4;
+    case NEW_KEY_5_PAD:                return XK_KP_5;
+    case NEW_KEY_6_PAD:                return XK_KP_6;
+    case NEW_KEY_7_PAD:                return XK_KP_7;
+    case NEW_KEY_8_PAD:                return XK_KP_8;
+    case NEW_KEY_9_PAD:                return XK_KP_9;
+    case NEW_KEY_0_PAD:                return XK_KP_0;
+    case NEW_KEY_STOP_PAD:     return XK_KP_Separator;
+    case NEW_KEY_EQUALS_PAD:   return XK_KP_Equal;
+    case NEW_KEY_SLASH_PAD:    return XK_KP_Divide;
+    case NEW_KEY_ASTERISK_PAD: return XK_KP_Multiply;
+    case NEW_KEY_ENTER_PAD:    return XK_KP_Enter;
+
+    default:                   return XK_VoidSymbol;
+  }
+}
+
+void XMapWindow(Display *display, Window window)
+{
+  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 *)window, video_bitmap, 0, 0, x, y, width, height);
+
+  if (mouse_off)
+    unhide_mouse(display);
+}
+
+static unsigned long AllocColorCell(int r, int g, int b)
+{
+  byte pixel_mapping = 0;
+  int i;
+
+  r >>= 10;
+  g >>= 10;
+  b >>= 10;
+
+  /* try to use existing colors from the global colormap */
+  for (i=0; i<global_colormap_entries_used; i++)
+  {
+    if (r == global_colormap[i].r &&
+       g == global_colormap[i].g &&
+       b == global_colormap[i].b)              /* color found */
+    {
+      pixel_mapping = i;
+      break;
+    }
+  }
+
+  if (i == global_colormap_entries_used)       /* color not found */
+  {
+    if (global_colormap_entries_used < MAX_COLORS)
+      global_colormap_entries_used++;
+
+    global_colormap[i].r = r;
+    global_colormap[i].g = g;
+    global_colormap[i].b = b;
+
+    pixel_mapping = i;
+  }
+
+  return pixel_mapping;
+}
+
+Display *XOpenDisplay(char *display_name)
+{
+  Screen *screen;
+  Display *display;
+  BITMAP *mouse_bitmap = NULL;
+  char *filename;
+
+  filename = getPath3(options.ro_base_directory, GRAPHICS_DIRECTORY,
+                     MOUSE_FILENAME);
+
+  mouse_bitmap = Read_PCX_to_AllegroBitmap(filename);
+  free(filename);
+
+  if (mouse_bitmap == NULL)
+    return NULL;
+
+  screen = malloc(sizeof(Screen));
+  display = malloc(sizeof(Display));
+
+  screen[0].cmap = 0;
+  screen[0].root = 0;
+#if 0
+  screen[0].white_pixel = 0xFF;
+  screen[0].black_pixel = 0x00;
+#else
+  screen[0].white_pixel = AllocColorCell(0xFFFF, 0xFFFF, 0xFFFF);
+  screen[0].black_pixel = AllocColorCell(0x0000, 0x0000, 0x0000);
+#endif
+  screen[0].video_bitmap = NULL;
+
+  display->default_screen = 0;
+  display->screens = screen;
+  display->mouse_ptr = mouse_bitmap;
+
+  allegro_init();
+  allegro_init_drivers();
+  set_color_depth(8);
+
+  /* force Windows 95 to switch to fullscreen mode */
+  set_gfx_mode(GFX_AUTODETECT, 320, 200, 0, 0);
+  rest(200);
+  set_gfx_mode(GFX_AUTODETECT, XRES, YRES, 0, 0);
+
+  return display;
+}
+
+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);
+
+#if 0
+  set_mouse_sprite_focus(1, 1);
+#endif
+
+  set_mouse_speed(1, 1);
+  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;
+}
+
+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 XSetClipMask(Display *display, GC gc, Pixmap pixmap)
+{
+  XGCValues *gcv = (XGCValues *)gc;
+
+  gcv->clip_mask = pixmap;
+  gcv->value_mask |= GCClipMask;
+}
+
+void XSetClipOrigin(Display *display, GC gc, int x, int y)
+{
+  XGCValues *gcv = (XGCValues *)gc;
+
+  gcv->clip_x_origin = x;
+  gcv->clip_x_origin = y;
+}
+
+void XFillRectangle(Display *display, Drawable d, GC gc, int x, int y,
+                   unsigned int width, unsigned int height)
+{
+  boolean mouse_off = FALSE;
+
+  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 - 1, y + height - 1,
+          ((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 *bitmap = NULL;
+
+  if (gfx_capabilities & GFX_HW_VRAM_BLIT &&
+      width == FXSIZE && height == FYSIZE)
+    bitmap = create_video_bitmap(width, height);
+
+  if (bitmap == NULL)
+    bitmap = create_bitmap(width, height);
+
+  return (Pixmap)bitmap;
+}
+
+void XSync(Display *display, Bool discard_events)
+{
+  wait_for_vsync = TRUE;
+}
+
+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 = FALSE;
+
+  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;
+}
+
+static BITMAP *Image_to_AllegroBitmap(Image *image)
+{
+  BITMAP *bitmap;
+  byte *src_ptr = image->data;
+  byte pixel_mapping[MAX_COLORS];
+  unsigned int depth = 8;
+
+#if 0
+  int i, j, x, y;
+#else
+  int i, x, y;
+#endif
+
+  /* allocate new allegro bitmap structure */
+  if ((bitmap = create_bitmap_ex(depth, image->width, image->height)) == NULL)
+  {
+    errno_pcx = PCX_NoMemory;
+    return NULL;
+  }
+
+  clear(bitmap);
+
+  /* try to use existing colors from the global colormap */
+  for (i=0; i<MAX_COLORS; i++)
+  {
+
+#if 0
+    int r, g, b;
+#endif
+
+    if (!image->rgb.color_used[i])
+      continue;
+
+
+#if 0
+    r = image->rgb.red[i] >> 10;
+    g = image->rgb.green[i] >> 10;
+    b = image->rgb.blue[i] >> 10;
+
+    for (j=0; j<global_colormap_entries_used; j++)
+    {
+      if (r == global_colormap[j].r &&
+         g == global_colormap[j].g &&
+         b == global_colormap[j].b)            /* color found */
+      {
+       pixel_mapping[i] = j;
+       break;
+      }
+    }
+
+    if (j == global_colormap_entries_used)     /* color not found */
+    {
+      if (global_colormap_entries_used < MAX_COLORS)
+       global_colormap_entries_used++;
+
+      global_colormap[j].r = r;
+      global_colormap[j].g = g;
+      global_colormap[j].b = b;
+
+      pixel_mapping[i] = j;
+    }
+#else
+    pixel_mapping[i] = AllocColorCell(image->rgb.red[i],
+                                     image->rgb.green[i],
+                                     image->rgb.blue[i]);
+#endif
+
+  }
+
+  /* copy bitmap data */
+  for (y=0; y<image->height; y++)
+    for (x=0; x<image->width; x++)
+      putpixel(bitmap, x, y, pixel_mapping[*src_ptr++]);
+
+  return bitmap;
+}
+
+static BITMAP *Read_PCX_to_AllegroBitmap(char *filename)
+{
+  BITMAP *bitmap;
+  Image *image;
+
+  /* read the graphic file in PCX format to internal image structure */
+  if ((image = Read_PCX_to_Image(filename)) == NULL)
+    return NULL;
+
+  /* convert internal image structure to allegro bitmap structure */
+  if ((bitmap = Image_to_AllegroBitmap(image)) == NULL)
+    return NULL;
+
+  set_palette(global_colormap);
+
+  return bitmap;
+}
+
+int Read_PCX_to_Pixmap(Display *display, Window window, GC gc, char *filename,
+                      Pixmap *pixmap, Pixmap *pixmap_mask)
+{
+  BITMAP *bitmap;
+
+  if ((bitmap = Read_PCX_to_AllegroBitmap(filename)) == NULL)
+    return errno_pcx;
+
+  *pixmap = (Pixmap)bitmap;
+  *pixmap_mask = (Pixmap)bitmap;
+
+  return PCX_Success;
+}
+
+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 *bitmap;
+
+  if ((bitmap = Read_PCX_to_AllegroBitmap(filename)) == NULL)
+    return BitmapOpenFailed;
+
+  *width_return = bitmap->w;
+  *height_return = bitmap->h;
+  *x_hot_return = -1;
+  *y_hot_return = -1;
+  *bitmap_return = (Pixmap)bitmap;
+
+  return BitmapSuccess;
+}
+
+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 *bitmap = video_bitmap;
+
+  if (is_screen_bitmap(bitmap))
+    destroy_bitmap(bitmap);
+
+  if (display->screens)
+    free(display->screens);
+
+  if (display)
+    free(display);
+
+  /* return to text mode (or DOS box on Windows screen) */
+  set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
+}
+
+void XNextEvent(Display *display, XEvent *event_return)
+{
+  while (!pending_events)
+    XPending(display);
+
+  memcpy(event_return, &event_buffer[pending_events], sizeof(XEvent));
+  pending_events--;
+}
+
+static void NewKeyEvent(int key_press_state, KeySym keysym)
+{
+  XKeyEvent *xkey;
+
+  if (pending_events >= MAX_EVENT_BUFFER)
+    return;
+
+  pending_events++;
+  xkey = (XKeyEvent *)&event_buffer[pending_events];
+  xkey->type = key_press_state;
+  xkey->state = (unsigned int)keysym;
+}
+
+#define HANDLE_RAW_KB_ALL_KEYS                 0
+#define HANDLE_RAW_KB_MODIFIER_KEYS_ONLY       1
+
+static int modifier_scancode[] =
+{
+  KEY_LSHIFT,
+  KEY_RSHIFT,
+  KEY_LCONTROL,
+  KEY_RCONTROL,
+  KEY_ALT,
+  KEY_ALTGR,
+  KEY_LWIN,
+  KEY_RWIN,
+  KEY_CAPSLOCK,
+  KEY_NUMLOCK,
+  KEY_SCRLOCK,
+  -1
+};
+
+static void HandleKeyboardRaw(int mode)
+{
+  int i;
+
+  for (i=0; i<MAX_SCANCODES; i++)
+  {
+    int scancode, new_state, event_type;
+    char key_pressed;
+
+    if (mode == HANDLE_RAW_KB_MODIFIER_KEYS_ONLY)
+    {
+      if ((scancode = modifier_scancode[i]) == -1)
+       return;
+    }
+    else
+      scancode = i;
+
+    key_pressed = key[scancode];
+    new_state = (key_pressed ? KeyPressMask : KeyReleaseMask);
+    event_type = (key_pressed ? KeyPress : KeyRelease);
+
+    if (key_press_state[i] == new_state)       /* state not changed */
+      continue;
+
+    key_press_state[i] = new_state;
+
+    NewKeyEvent(event_type, ScancodeToKeySym(scancode));
+  }
+}
+
+static void HandleKeyboardEvent()
+{
+  if (keypressed())
+  {
+    int key_info = readkey();
+    int scancode = (key_info >> 8);
+    int ascii = (key_info & 0xff);
+    KeySym keysym = ScancodeToKeySym(scancode);
+
+    if (scancode == KEY_PAD)
+    {
+      /* keys on the numeric keypad return just scancode 'KEY_PAD'
+        for some reason, so we must handle them separately */
+
+      if (ascii >= '0' && ascii <= '9')
+       keysym = XK_KP_0 + (KeySym)(ascii - '0');
+      else if (ascii == '.')
+       keysym = XK_KP_Separator;
+    }
+    else if (ascii >= ' ' && ascii <= 'Z')
+      keysym = XK_space + (KeySym)(ascii - ' ');
+    else if (ascii == '^')
+      keysym = XK_asciicircum;
+    else if (ascii == '_')
+      keysym = XK_underscore;
+    else if (ascii == 'Ä')
+      keysym = XK_Adiaeresis;
+    else if (ascii == 'Ö')
+      keysym = XK_Odiaeresis;
+    else if (ascii == 'Ü')
+      keysym = XK_Udiaeresis;
+    else if (ascii == 'ä')
+      keysym = XK_adiaeresis;
+    else if (ascii == 'ö')
+      keysym = XK_odiaeresis;
+    else if (ascii == 'ü')
+      keysym = XK_udiaeresis;
+    else if (ascii == 'ß')
+      keysym = XK_ssharp;
+
+    NewKeyEvent(KeyPress, keysym);
+  }
+  else if (key_shifts & (KB_SHIFT_FLAG | KB_CTRL_FLAG | KB_ALT_FLAG))
+  {
+    /* the allegro function keypressed() does not give us single pressed
+       modifier keys, so we must detect them with the internal global
+       allegro variable 'key_shifts' and then handle them separately */
+
+    HandleKeyboardRaw(HANDLE_RAW_KB_MODIFIER_KEYS_ONLY);
+  }
+}
+
+int XPending(Display *display)
+{
+  XButtonEvent *xbutton;
+  XMotionEvent *xmotion;
+  int i;
+
+  /* When using 'HandleKeyboardRaw()', keyboard input is also stored in
+     the allegro keyboard input buffer and would be available a second
+     time by calling 'HandleKeyboardEvent()'. To avoid double keyboard
+     events, the allegro function 'clear_keybuf()' must be called each
+     time when switching from calling 'HandleKeyboardRaw()' to calling
+     'HandleKeyboardEvent()' to get keyboard input, which is actually
+     done by 'XAutoRepeatOn()' which sets keyboard_auto_repeat to TRUE. */
+
+  /* keyboard event */
+  if (keyboard_auto_repeat)
+    HandleKeyboardEvent();
+  else
+    HandleKeyboardRaw(HANDLE_RAW_KB_ALL_KEYS);
+
+  /* mouse motion event */
+  if (mouse_pos != last_mouse_pos)
+  {
+    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;
+  }
+
+  /* mouse button event */
+  if (mouse_b != last_mouse_b)
+  {
+    for (i=0; i<3; i++)                /* check all three mouse buttons */
+    {
+      int bitmask = (1 << i);
+
+      if ((last_mouse_b & bitmask) != (mouse_b & bitmask))
+      {
+       int mapping[3] = { 1, 3, 2 };
+
+       pending_events++;
+        xbutton = (XButtonEvent *)&event_buffer[pending_events];
+        xbutton->type = (mouse_b & bitmask ? ButtonPress : ButtonRelease);
+        xbutton->button = mapping[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;
+}
+
+int XLookupString(XKeyEvent *key_event, char *buffer, int buffer_size,
+                 KeySym *key, XComposeStatus *compose)
+{
+  *key = key_event->state;
+  return 0;
+}
+
+void XSetForeground(Display *display, GC gc, unsigned long pixel)
+{
+  XGCValues *gcv = (XGCValues *)gc;
+
+  gcv->foreground = pixel;
+}
+
+void XDrawLine(Display *display, Drawable d, GC gc,
+              int x1, int y1, int x2, int y2)
+{
+  XGCValues *gcv = (XGCValues *)gc;
+  boolean mouse_off = FALSE;
+
+  if ((BITMAP *)d == video_bitmap)
+  {
+    x1 += display->screens[display->default_screen].x;
+    y1 += display->screens[display->default_screen].y;
+    x2 += display->screens[display->default_screen].x;
+    y2 += display->screens[display->default_screen].y;
+    freeze_mouse_flag = TRUE;
+    mouse_off = hide_mouse(display, MIN(x1, x2), MIN(y1, y2),
+                          MAX(x1, x2) - MIN(x1, x2),
+                          MAX(y1, y2) - MIN(y1, y2));
+  }
+
+  line((BITMAP *)d, x1, y1, x2, y2, gcv->foreground);
+
+  if (mouse_off)
+    unhide_mouse(display);
+
+  freeze_mouse_flag = FALSE;
+}
+
+void XDestroyImage(XImage *ximage)
+{
+}
+
+Bool XQueryPointer(Display *display, Window window,
+                  Window *root, Window *child, int *root_x, int *root_y,
+                  int *win_x, int *win_y, unsigned int *mask)
+{
+  *win_x = mouse_x - display->screens[display->default_screen].x;
+  *win_y = mouse_y - display->screens[display->default_screen].y;
+
+  return True;
+}
+
+void XAutoRepeatOn(Display *display)
+{
+  keyboard_auto_repeat = TRUE;
+  clear_keybuf();
+}
+
+void XAutoRepeatOff(Display *display)
+{
+  keyboard_auto_repeat = FALSE;
+}
+
+boolean MSDOSOpenAudio(void)
+{
+  return allegro_init_audio();
+}
+
+boolean MSDOSCloseAudio(void)
+{
+  /* nothing to be done here */
+}
+
+void NetworkServer(int port, int serveronly)
+{
+  Error(ERR_WARN, "networking not supported in DOS version");
+}
+
+#endif /* PLATFORM_MSDOS */
diff --git a/src/libgame/msdos.h b/src/libgame/msdos.h
new file mode 100644 (file)
index 0000000..26a3f79
--- /dev/null
@@ -0,0 +1,712 @@
+/***********************************************************
+*  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             *
+*----------------------------------------------------------*
+*  msdos.h                                                 *
+***********************************************************/
+
+#ifndef MSDOS_H
+#define MSDOS_H
+
+#include <allegro.h>
+#include <time.h>
+
+/* symbol 'window' is defined in DJGPP cross-compiler in libc.a(conio.o) */
+#define window window_djgpp
+
+/* system dependent definitions */
+
+#define TARGET_STRING          "DOS"
+
+/* allegro defines TRUE as -1 */
+#ifdef TRUE
+#undef TRUE
+#undef FALSE
+#endif
+
+#define TRUE   1
+#define FALSE  0
+
+#define XRES   800
+#define YRES   600
+
+/* additional Allegro keyboard mapping */
+
+/* The following are all undefined in Allegro */
+#define NEW_KEY_BACKSLASH      86
+#define NEW_KEY_1_PAD          101
+#define NEW_KEY_2_PAD          102
+#define NEW_KEY_3_PAD          103
+#define NEW_KEY_4_PAD          104
+#define NEW_KEY_5_PAD          105
+#define NEW_KEY_6_PAD          106
+#define NEW_KEY_7_PAD          107
+#define NEW_KEY_8_PAD          108
+#define NEW_KEY_9_PAD          109
+#define NEW_KEY_0_PAD          110
+#define NEW_KEY_STOP_PAD       111
+#define NEW_KEY_EQUALS_PAD     112
+#define NEW_KEY_SLASH_PAD      113
+#define NEW_KEY_ASTERISK_PAD   114
+#define NEW_KEY_ENTER_PAD      115
+
+/* X11 keyboard mapping (from 'keysymdef.h') */
+
+#define XK_VoidSymbol          0xFFFFFF        /* void symbol */
+
+/*
+ * TTY Functions, cleverly chosen to map to ascii, for convenience of
+ * programming, but could have been arbitrary (at the cost of lookup
+ * tables in client code.
+ */
+
+#define XK_BackSpace           0xFF08  /* back space, back char */
+#define XK_Tab                 0xFF09
+#define XK_Linefeed            0xFF0A  /* Linefeed, LF */
+#define XK_Clear               0xFF0B
+#define XK_Return              0xFF0D  /* Return, enter */
+#define XK_Pause               0xFF13  /* Pause, hold */
+#define XK_Scroll_Lock         0xFF14
+#define XK_Sys_Req             0xFF15
+#define XK_Escape              0xFF1B
+#define XK_Delete              0xFFFF  /* Delete, rubout */
+
+/* International & multi-key character composition */
+
+#define XK_Multi_key           0xFF20  /* Multi-key character compose */
+#define XK_SingleCandidate     0xFF3C
+#define XK_MultipleCandidate   0xFF3D
+#define XK_PreviousCandidate   0xFF3E
+
+/* Cursor control & motion */
+
+#define XK_Home                        0xFF50
+#define XK_Left                        0xFF51  /* Move left, left arrow */
+#define XK_Up                  0xFF52  /* Move up, up arrow */
+#define XK_Right               0xFF53  /* Move right, right arrow */
+#define XK_Down                        0xFF54  /* Move down, down arrow */
+#define XK_Prior               0xFF55  /* Prior, previous */
+#define XK_Page_Up             0xFF55
+#define XK_Next                        0xFF56  /* Next */
+#define XK_Page_Down           0xFF56
+#define XK_End                 0xFF57  /* EOL */
+#define XK_Begin               0xFF58  /* BOL */
+
+/* Misc Functions */
+
+#define XK_Select              0xFF60  /* Select, mark */
+#define XK_Print               0xFF61
+#define XK_Execute             0xFF62  /* Execute, run, do */
+#define XK_Insert              0xFF63  /* Insert, insert here */
+#define XK_Undo                        0xFF65  /* Undo, oops */
+#define XK_Redo                        0xFF66  /* redo, again */
+#define XK_Menu                        0xFF67
+#define XK_Find                        0xFF68  /* Find, search */
+#define XK_Cancel              0xFF69  /* Cancel, stop, abort, exit */
+#define XK_Help                        0xFF6A  /* Help */
+#define XK_Break               0xFF6B
+#define XK_Mode_switch         0xFF7E  /* Character set switch */
+#define XK_script_switch        0xFF7E  /* Alias for mode_switch */
+#define XK_Num_Lock            0xFF7F
+
+/* Keypad Functions, keypad numbers cleverly chosen to map to ascii */
+
+#define XK_KP_Space            0xFF80  /* space */
+#define XK_KP_Tab              0xFF89
+#define XK_KP_Enter            0xFF8D  /* enter */
+#define XK_KP_F1               0xFF91  /* PF1, KP_A, ... */
+#define XK_KP_F2               0xFF92
+#define XK_KP_F3               0xFF93
+#define XK_KP_F4               0xFF94
+#define XK_KP_Home             0xFF95
+#define XK_KP_Left             0xFF96
+#define XK_KP_Up               0xFF97
+#define XK_KP_Right            0xFF98
+#define XK_KP_Down             0xFF99
+#define XK_KP_Prior            0xFF9A
+#define XK_KP_Page_Up          0xFF9A
+#define XK_KP_Next             0xFF9B
+#define XK_KP_Page_Down                0xFF9B
+#define XK_KP_End              0xFF9C
+#define XK_KP_Begin            0xFF9D
+#define XK_KP_Insert           0xFF9E
+#define XK_KP_Delete           0xFF9F
+#define XK_KP_Equal            0xFFBD  /* equals */
+#define XK_KP_Multiply         0xFFAA
+#define XK_KP_Add              0xFFAB
+#define XK_KP_Separator                0xFFAC  /* separator, often comma */
+#define XK_KP_Subtract         0xFFAD
+#define XK_KP_Decimal          0xFFAE
+#define XK_KP_Divide           0xFFAF
+
+#define XK_KP_0                        0xFFB0
+#define XK_KP_1                        0xFFB1
+#define XK_KP_2                        0xFFB2
+#define XK_KP_3                        0xFFB3
+#define XK_KP_4                        0xFFB4
+#define XK_KP_5                        0xFFB5
+#define XK_KP_6                        0xFFB6
+#define XK_KP_7                        0xFFB7
+#define XK_KP_8                        0xFFB8
+#define XK_KP_9                        0xFFB9
+
+/*
+ * Auxilliary Functions; note the duplicate definitions for left and right
+ * function keys;  Sun keyboards and a few other manufactures have such
+ * function key groups on the left and/or right sides of the keyboard.
+ * We've not found a keyboard with more than 35 function keys total.
+ */
+
+#define XK_F1                  0xFFBE
+#define XK_F2                  0xFFBF
+#define XK_F3                  0xFFC0
+#define XK_F4                  0xFFC1
+#define XK_F5                  0xFFC2
+#define XK_F6                  0xFFC3
+#define XK_F7                  0xFFC4
+#define XK_F8                  0xFFC5
+#define XK_F9                  0xFFC6
+#define XK_F10                 0xFFC7
+#define XK_F11                 0xFFC8
+#define XK_L1                  0xFFC8
+#define XK_F12                 0xFFC9
+#define XK_L2                  0xFFC9
+#define XK_F13                 0xFFCA
+#define XK_L3                  0xFFCA
+#define XK_F14                 0xFFCB
+#define XK_L4                  0xFFCB
+#define XK_F15                 0xFFCC
+#define XK_L5                  0xFFCC
+#define XK_F16                 0xFFCD
+#define XK_L6                  0xFFCD
+#define XK_F17                 0xFFCE
+#define XK_L7                  0xFFCE
+#define XK_F18                 0xFFCF
+#define XK_L8                  0xFFCF
+#define XK_F19                 0xFFD0
+#define XK_L9                  0xFFD0
+#define XK_F20                 0xFFD1
+#define XK_L10                 0xFFD1
+#define XK_F21                 0xFFD2
+#define XK_R1                  0xFFD2
+#define XK_F22                 0xFFD3
+#define XK_R2                  0xFFD3
+#define XK_F23                 0xFFD4
+#define XK_R3                  0xFFD4
+#define XK_F24                 0xFFD5
+#define XK_R4                  0xFFD5
+#define XK_F25                 0xFFD6
+#define XK_R5                  0xFFD6
+#define XK_F26                 0xFFD7
+#define XK_R6                  0xFFD7
+#define XK_F27                 0xFFD8
+#define XK_R7                  0xFFD8
+#define XK_F28                 0xFFD9
+#define XK_R8                  0xFFD9
+#define XK_F29                 0xFFDA
+#define XK_R9                  0xFFDA
+#define XK_F30                 0xFFDB
+#define XK_R10                 0xFFDB
+#define XK_F31                 0xFFDC
+#define XK_R11                 0xFFDC
+#define XK_F32                 0xFFDD
+#define XK_R12                 0xFFDD
+#define XK_F33                 0xFFDE
+#define XK_R13                 0xFFDE
+#define XK_F34                 0xFFDF
+#define XK_R14                 0xFFDF
+#define XK_F35                 0xFFE0
+#define XK_R15                 0xFFE0
+
+/* Modifiers */
+
+#define XK_Shift_L             0xFFE1  /* Left shift */
+#define XK_Shift_R             0xFFE2  /* Right shift */
+#define XK_Control_L           0xFFE3  /* Left control */
+#define XK_Control_R           0xFFE4  /* Right control */
+#define XK_Caps_Lock           0xFFE5  /* Caps lock */
+#define XK_Shift_Lock          0xFFE6  /* Shift lock */
+
+#define XK_Meta_L              0xFFE7  /* Left meta */
+#define XK_Meta_R              0xFFE8  /* Right meta */
+#define XK_Alt_L               0xFFE9  /* Left alt */
+#define XK_Alt_R               0xFFEA  /* Right alt */
+#define XK_Super_L             0xFFEB  /* Left super */
+#define XK_Super_R             0xFFEC  /* Right super */
+#define XK_Hyper_L             0xFFED  /* Left hyper */
+#define XK_Hyper_R             0xFFEE  /* Right hyper */
+
+/*
+ *  Latin 1
+ *  Byte 3 = 0
+ */
+
+#define XK_space               0x020
+#define XK_exclam              0x021
+#define XK_quotedbl            0x022
+#define XK_numbersign          0x023
+#define XK_dollar              0x024
+#define XK_percent             0x025
+#define XK_ampersand           0x026
+#define XK_apostrophe          0x027
+#define XK_quoteright          0x027   /* deprecated */
+#define XK_parenleft           0x028
+#define XK_parenright          0x029
+#define XK_asterisk            0x02a
+#define XK_plus                0x02b
+#define XK_comma               0x02c
+#define XK_minus               0x02d
+#define XK_period              0x02e
+#define XK_slash               0x02f
+#define XK_0                   0x030
+#define XK_1                   0x031
+#define XK_2                   0x032
+#define XK_3                   0x033
+#define XK_4                   0x034
+#define XK_5                   0x035
+#define XK_6                   0x036
+#define XK_7                   0x037
+#define XK_8                   0x038
+#define XK_9                   0x039
+#define XK_colon               0x03a
+#define XK_semicolon           0x03b
+#define XK_less                0x03c
+#define XK_equal               0x03d
+#define XK_greater             0x03e
+#define XK_question            0x03f
+#define XK_at                  0x040
+#define XK_A                   0x041
+#define XK_B                   0x042
+#define XK_C                   0x043
+#define XK_D                   0x044
+#define XK_E                   0x045
+#define XK_F                   0x046
+#define XK_G                   0x047
+#define XK_H                   0x048
+#define XK_I                   0x049
+#define XK_J                   0x04a
+#define XK_K                   0x04b
+#define XK_L                   0x04c
+#define XK_M                   0x04d
+#define XK_N                   0x04e
+#define XK_O                   0x04f
+#define XK_P                   0x050
+#define XK_Q                   0x051
+#define XK_R                   0x052
+#define XK_S                   0x053
+#define XK_T                   0x054
+#define XK_U                   0x055
+#define XK_V                   0x056
+#define XK_W                   0x057
+#define XK_X                   0x058
+#define XK_Y                   0x059
+#define XK_Z                   0x05a
+#define XK_bracketleft         0x05b
+#define XK_backslash           0x05c
+#define XK_bracketright        0x05d
+#define XK_asciicircum         0x05e
+#define XK_underscore          0x05f
+#define XK_grave               0x060
+#define XK_quoteleft           0x060   /* deprecated */
+#define XK_a                   0x061
+#define XK_b                   0x062
+#define XK_c                   0x063
+#define XK_d                   0x064
+#define XK_e                   0x065
+#define XK_f                   0x066
+#define XK_g                   0x067
+#define XK_h                   0x068
+#define XK_i                   0x069
+#define XK_j                   0x06a
+#define XK_k                   0x06b
+#define XK_l                   0x06c
+#define XK_m                   0x06d
+#define XK_n                   0x06e
+#define XK_o                   0x06f
+#define XK_p                   0x070
+#define XK_q                   0x071
+#define XK_r                   0x072
+#define XK_s                   0x073
+#define XK_t                   0x074
+#define XK_u                   0x075
+#define XK_v                   0x076
+#define XK_w                   0x077
+#define XK_x                   0x078
+#define XK_y                   0x079
+#define XK_z                   0x07a
+#define XK_braceleft           0x07b
+#define XK_bar                 0x07c
+#define XK_braceright          0x07d
+#define XK_asciitilde          0x07e
+
+#define XK_nobreakspace        0x0a0
+#define XK_exclamdown          0x0a1
+#define XK_cent                       0x0a2
+#define XK_sterling            0x0a3
+#define XK_currency            0x0a4
+#define XK_yen                 0x0a5
+#define XK_brokenbar           0x0a6
+#define XK_section             0x0a7
+#define XK_diaeresis           0x0a8
+#define XK_copyright           0x0a9
+#define XK_ordfeminine         0x0aa
+#define XK_guillemotleft       0x0ab   /* left angle quotation mark */
+#define XK_notsign             0x0ac
+#define XK_hyphen              0x0ad
+#define XK_registered          0x0ae
+#define XK_macron              0x0af
+#define XK_degree              0x0b0
+#define XK_plusminus           0x0b1
+#define XK_twosuperior         0x0b2
+#define XK_threesuperior       0x0b3
+#define XK_acute               0x0b4
+#define XK_mu                  0x0b5
+#define XK_paragraph           0x0b6
+#define XK_periodcentered      0x0b7
+#define XK_cedilla             0x0b8
+#define XK_onesuperior         0x0b9
+#define XK_masculine           0x0ba
+#define XK_guillemotright      0x0bb   /* right angle quotation mark */
+#define XK_onequarter          0x0bc
+#define XK_onehalf             0x0bd
+#define XK_threequarters       0x0be
+#define XK_questiondown        0x0bf
+#define XK_Agrave              0x0c0
+#define XK_Aacute              0x0c1
+#define XK_Acircumflex         0x0c2
+#define XK_Atilde              0x0c3
+#define XK_Adiaeresis          0x0c4
+#define XK_Aring               0x0c5
+#define XK_AE                  0x0c6
+#define XK_Ccedilla            0x0c7
+#define XK_Egrave              0x0c8
+#define XK_Eacute              0x0c9
+#define XK_Ecircumflex         0x0ca
+#define XK_Ediaeresis          0x0cb
+#define XK_Igrave              0x0cc
+#define XK_Iacute              0x0cd
+#define XK_Icircumflex         0x0ce
+#define XK_Idiaeresis          0x0cf
+#define XK_ETH                 0x0d0
+#define XK_Eth                 0x0d0   /* deprecated */
+#define XK_Ntilde              0x0d1
+#define XK_Ograve              0x0d2
+#define XK_Oacute              0x0d3
+#define XK_Ocircumflex         0x0d4
+#define XK_Otilde              0x0d5
+#define XK_Odiaeresis          0x0d6
+#define XK_multiply            0x0d7
+#define XK_Ooblique            0x0d8
+#define XK_Ugrave              0x0d9
+#define XK_Uacute              0x0da
+#define XK_Ucircumflex         0x0db
+#define XK_Udiaeresis          0x0dc
+#define XK_Yacute              0x0dd
+#define XK_THORN               0x0de
+#define XK_Thorn               0x0de   /* deprecated */
+#define XK_ssharp              0x0df
+#define XK_agrave              0x0e0
+#define XK_aacute              0x0e1
+#define XK_acircumflex         0x0e2
+#define XK_atilde              0x0e3
+#define XK_adiaeresis          0x0e4
+#define XK_aring               0x0e5
+#define XK_ae                  0x0e6
+#define XK_ccedilla            0x0e7
+#define XK_egrave              0x0e8
+#define XK_eacute              0x0e9
+#define XK_ecircumflex         0x0ea
+#define XK_ediaeresis          0x0eb
+#define XK_igrave              0x0ec
+#define XK_iacute              0x0ed
+#define XK_icircumflex         0x0ee
+#define XK_idiaeresis          0x0ef
+#define XK_eth                 0x0f0
+#define XK_ntilde              0x0f1
+#define XK_ograve              0x0f2
+#define XK_oacute              0x0f3
+#define XK_ocircumflex         0x0f4
+#define XK_otilde              0x0f5
+#define XK_odiaeresis          0x0f6
+#define XK_division            0x0f7
+#define XK_oslash              0x0f8
+#define XK_ugrave              0x0f9
+#define XK_uacute              0x0fa
+#define XK_ucircumflex         0x0fb
+#define XK_udiaeresis          0x0fc
+#define XK_yacute              0x0fd
+#define XK_thorn               0x0fe
+#define XK_ydiaeresis          0x0ff
+
+/* end of X11 keyboard mapping */
+
+#define MOUSE_FILENAME         "mouse.pcx"
+#define JOYSTICK_FILENAME      "joystick.cnf"
+
+#define screen myscreen
+
+#define XFlush(a)
+#define XGetImage(a,b,c,d,e,f,g,h)             ((XImage *) NULL)
+#define XDisplayName(a)                                ((char *) NULL)
+#define XFreeColors(a,b,c,d,e)
+#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 MAX_SCANCODES          128
+
+#define True                   1
+#define False                  0
+#define None                   0L
+
+#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 ClientMessage          33
+
+#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 PCX_Success             0
+#define PCX_OpenFailed         -1
+#define PCX_ReadFailed         -2
+#define        PCX_FileInvalid         -3
+#define PCX_NoMemory           -4
+#define PCX_ColorFailed                -5
+
+#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 DefaultVisual(dpy, scr)          (NULL)
+#define DefaultDepth(dpy, scr)   (NULL)
+#define XDisplayWidth(dpy, scr)          (XRES)
+#define XDisplayHeight(dpy, scr)  (YRES)
+
+#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 long Visual;
+typedef long XVisualInfo;
+typedef long Atom;
+typedef int Status;
+typedef int Bool;
+typedef int XComposeStatus;    /* we don't need the real type */
+
+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;   /* white pixel value */
+  unsigned long black_pixel;   /* black pixel value */
+  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;           /* x origin for clipping */
+  int clip_y_origin;           /* y origin for clipping */
+  unsigned long value_mask;
+} XGCValues;
+
+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 struct
+{
+  int type;                    /* ClientMessage */
+} XClientMessageEvent;
+
+typedef union _XEvent
+{
+  int type;                    /* must not be changed; first element */
+  XExposeEvent xexpose;
+  XButtonEvent xbutton;
+  XMotionEvent xmotion;
+  XKeyEvent xkey;
+} XEvent;
+
+void XMapWindow(Display *, Window);
+Display *XOpenDisplay(char *);
+Window XCreateSimpleWindow(Display *, Window, int, int,
+                          unsigned int, unsigned int, unsigned int,
+                          unsigned long, unsigned long);
+Status XStringListToTextProperty(char **, int, XTextProperty *);
+void XFree(void *);
+GC XCreateGC(Display *, Drawable, unsigned long, XGCValues *);
+void XSetClipMask(Display *, GC, Pixmap);
+void XSetClipOrigin(Display *, GC, int, int);
+void XFillRectangle(Display *, Drawable, GC, int, int,
+                   unsigned int, unsigned int);
+Pixmap XCreatePixmap(Display *, Drawable, unsigned int, unsigned int,
+                    unsigned int);
+void XSync(Display *, Bool);
+inline void XCopyArea(Display *, Drawable, Drawable, GC, int, int,
+                     unsigned int, unsigned int, int, int);
+int Read_PCX_to_Pixmap(Display *, Window, GC, char *, Pixmap *, Pixmap *);
+int XReadBitmapFile(Display *, Drawable, char *,
+                   unsigned int *, unsigned int *, Pixmap *, int *, int *);
+void XFreePixmap(Display *, Pixmap);
+void XFreeGC(Display *, GC);
+void XCloseDisplay(Display *);
+void XNextEvent(Display *, XEvent *);
+int XPending(Display *);
+KeySym XLookupKeysym(XKeyEvent *, int);
+int XLookupString(XKeyEvent *, char *, int, KeySym *, XComposeStatus *);
+void XSetForeground(Display *, GC, unsigned long);
+void XDrawLine(Display *, Drawable, GC, int, int, int, int);
+void XDestroyImage(XImage *);
+Bool XQueryPointer(Display *, Window, Window *, Window *, int *, int *,
+                  int *, int *, unsigned int *);
+void XAutoRepeatOn(Display *);
+void XAutoRepeatOff(Display *);
+
+boolean MSDOSOpenAudio(void);
+boolean MSDOSCloseAudio(void);
+
+void NetworkServer(int, int);
+
+#endif /* MSDOS_H */
diff --git a/src/libgame/pcx.c b/src/libgame/pcx.c
new file mode 100644 (file)
index 0000000..b075940
--- /dev/null
@@ -0,0 +1,265 @@
+/***********************************************************
+*  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                *
+*----------------------------------------------------------*
+*  pcx.c                                                   *
+***********************************************************/
+
+#ifndef TARGET_SDL
+
+#include "pcx.h"
+#include "image.h"
+#include "misc.h"
+
+#define PCX_DEBUG              FALSE
+
+#define PCX_MAGIC              0x0a    /* first byte in a PCX image file    */
+#define PCX_LAST_VERSION       5       /* last acceptable version number    */
+#define PCX_ENCODING           1       /* PCX encoding method               */
+#define PCX_256COLORS_MAGIC    0x0c    /* first byte of a PCX 256 color map */
+#define PCX_MAXDEPTH           8       /* supports up to 8 bits per pixel   */
+#define PCX_MAXCOLORS          256     /* maximum number of colors          */
+
+#define PCX_HEADER_SIZE                128
+#define PCX_COLORMAP_SIZE      (3 * PCX_MAXCOLORS)
+
+struct PCX_Header
+{
+  unsigned char signature;     /* PCX file identifier                 */
+  unsigned char version;       /* version compatibility level         */
+  unsigned char encoding;      /* encoding method                     */
+  unsigned char bits_per_pixel;        /* bits per pixel, or depth            */
+  unsigned short xmin;         /* X position of left edge             */
+  unsigned short ymin;         /* Y position of top edge              */
+  unsigned short xmax;         /* X position of right edge            */
+  unsigned short ymax;         /* Y position of bottom edge           */
+  unsigned short hres;         /* X screen resolution of source image */
+  unsigned short vres;         /* Y screen resolution of source image */
+  unsigned char palette[16][3];        /* PCX color map                       */
+  unsigned char reserved;      /* should be 0, 1 if std res fax       */
+  unsigned char color_planes;  /* bit planes in image                 */
+  unsigned short bytes_per_line;/* byte delta between scanlines        */
+  unsigned short palette_type; /* 0 = undef, 1 = color, 2 = grayscale */
+  unsigned char filler[58];    /* fill to struct size of 128          */
+};
+
+/* global PCX error value */
+int errno_pcx = PCX_Success;
+
+static byte *PCX_ReadBitmap(Image *image, byte *buffer_ptr, byte *buffer_last)
+{
+  /* Run Length Encoding: If the two high bits are set,
+   * then the low 6 bits contain a repeat count, and the byte to
+   * repeat is the next byte in the file.  If the two high bits are
+   * not set, then this is the byte to write.
+   */
+
+  unsigned int bytes_per_pixel = (image->depth + 7) / 8;
+  register byte *bitmap_ptr, *bitmap_last;
+  register byte value, count;
+
+  bitmap_ptr = image->data;
+  bitmap_last = bitmap_ptr + (image->width * image->height * bytes_per_pixel);
+
+  while (bitmap_ptr < bitmap_last && buffer_ptr < buffer_last)
+  {
+    value = *buffer_ptr++;
+
+    if ((value & 0xc0) == 0xc0)                /* this is a repeat count byte */
+    {
+      count = value & 0x3f;            /* extract repeat count from byte */
+      value = *buffer_ptr++;           /* next byte is value to repeat */
+
+      for (; count && bitmap_ptr < bitmap_last; count--)
+       *bitmap_ptr++ = value;
+
+      if (count)                       /* repeat count spans end of bitmap */
+       return NULL;
+    }
+    else
+      *bitmap_ptr++ = value;
+
+    image->rgb.color_used[value] = TRUE;
+  }
+
+  /* check if end of buffer was reached before end of bitmap */
+  if (bitmap_ptr < bitmap_last)
+    return NULL;
+
+  /* return current buffer position for next decoding function */
+  return buffer_ptr;
+}
+
+static byte *PCX_ReadColormap(Image *image,byte *buffer_ptr, byte *buffer_last)
+{
+  int i, magic;
+
+  /* read colormap magic byte */
+  magic = *buffer_ptr++;
+
+  /* check magic colormap header byte */
+  if (magic != PCX_256COLORS_MAGIC)
+    return NULL;
+
+  /* check if enough bytes left for a complete colormap */
+  if (buffer_ptr + PCX_COLORMAP_SIZE > buffer_last)
+    return NULL;
+
+  /* read 256 colors from PCX colormap */
+  for (i=0; i<PCX_MAXCOLORS; i++)
+  {
+    image->rgb.red[i]   = *buffer_ptr++ << 8;
+    image->rgb.green[i] = *buffer_ptr++ << 8;
+    image->rgb.blue[i]  = *buffer_ptr++ << 8;
+  }
+
+  /* return current buffer position for next decoding function */
+  return buffer_ptr;
+}
+
+Image *Read_PCX_to_Image(char *filename)
+{
+  FILE *file;
+  byte *file_buffer;
+  byte *buffer_ptr, *buffer_last;
+  unsigned int file_length;
+  struct PCX_Header pcx;
+  Image *image;
+  int width, height, depth;
+  int i;
+
+  errno_pcx = PCX_Success;
+
+  if (!(file = fopen(filename, "r")))
+  {
+    errno_pcx = PCX_OpenFailed;
+    return NULL;
+  }
+
+  if (fseek(file, 0, SEEK_END) == -1)
+  {
+    fclose(file);
+    errno_pcx = PCX_ReadFailed;
+    return NULL;
+  }
+
+  file_length = ftell(file);
+  rewind(file);
+
+  if (file_length < PCX_HEADER_SIZE)
+  {
+    /* PCX file is too short to contain a valid PCX header */
+    fclose(file);
+
+    errno_pcx = PCX_FileInvalid;
+    return NULL;
+  }
+
+  file_buffer = checked_malloc(file_length);
+
+  if (fread(file_buffer, 1, file_length, file) != file_length)
+  {
+    fclose(file);
+    errno_pcx = PCX_ReadFailed;
+    return NULL;
+  }
+
+  fclose(file);
+
+  pcx.signature      = file_buffer[0];
+  pcx.version        = file_buffer[1];
+  pcx.encoding       = file_buffer[2];
+  pcx.bits_per_pixel = file_buffer[3];
+  pcx.xmin           = file_buffer[4]  + 256 * file_buffer[5];
+  pcx.ymin           = file_buffer[6]  + 256 * file_buffer[7];
+  pcx.xmax           = file_buffer[8]  + 256 * file_buffer[9];
+  pcx.ymax           = file_buffer[10] + 256 * file_buffer[11];
+  pcx.color_planes   = file_buffer[65];
+  pcx.bytes_per_line = file_buffer[66] + 256 * file_buffer[67];
+  pcx.palette_type   = file_buffer[68] + 256 * file_buffer[69];
+
+  width  = pcx.xmax - pcx.xmin + 1;
+  height = pcx.ymax - pcx.ymin + 1;
+  depth  = pcx.bits_per_pixel;
+
+  if (pcx.signature != PCX_MAGIC || pcx.version > PCX_LAST_VERSION ||
+      pcx.encoding != PCX_ENCODING || pcx.color_planes > PCX_MAXDEPTH ||
+      width < 0 || height < 0)
+  {
+    free(file_buffer);
+
+    errno_pcx = PCX_FileInvalid;
+    return NULL;
+  }
+
+#if PCX_DEBUG
+  if (options.verbose)
+  {
+    printf("%s is a %dx%d PC Paintbrush image with %d bitplanes\n",
+          filename, width, height,
+          pcx.color_planes);
+    printf("depth: %d\n", pcx.bits_per_pixel);
+    printf("color_planes: %d\n", pcx.color_planes);
+    printf("bytes_per_line: %d\n", pcx.bytes_per_line);
+    printf("palette type: %s\n",
+          (pcx.palette_type == 1 ? "color" :
+           pcx.palette_type == 2 ? "grayscale" : "undefined"));
+  }
+#endif
+
+  /* allocate new image structure */
+  image = newImage(width, height, depth);
+
+  buffer_ptr  = file_buffer + PCX_HEADER_SIZE;
+  buffer_last = file_buffer + file_length;
+
+  /* read compressed bitmap data */
+  if ((buffer_ptr = PCX_ReadBitmap(image, buffer_ptr, buffer_last)) == NULL)
+  {
+    free(file_buffer);
+    freeImage(image);
+
+    errno_pcx = PCX_FileInvalid;
+    return NULL;
+  }
+
+  if (file_length < PCX_HEADER_SIZE + PCX_COLORMAP_SIZE)
+  {
+    /* PCX file is too short to contain a valid 256 colors colormap */
+    fclose(file);
+    errno_pcx = PCX_ColorFailed;
+    return NULL;
+  }
+
+  /* read colormap data */
+  if (!PCX_ReadColormap(image, buffer_ptr, buffer_last))
+  {
+    free(file_buffer);
+    freeImage(image);
+    errno_pcx = PCX_ColorFailed;
+    return NULL;
+  }
+
+  free(file_buffer);
+
+  /* determine number of used colormap entries */
+  image->rgb.used = 0;
+  for (i=0; i<PCX_MAXCOLORS; i++)
+    if (image->rgb.color_used[i])
+      image->rgb.used++;
+
+#if PCX_DEBUG
+  if (options.verbose)
+    printf("Read_PCX_to_Image: %d colors found\n", image->rgb.used);
+#endif
+
+  return image;
+}
+
+#endif /* !TARGET_SDL */
diff --git a/src/libgame/pcx.h b/src/libgame/pcx.h
new file mode 100644 (file)
index 0000000..f214971
--- /dev/null
@@ -0,0 +1,34 @@
+/***********************************************************
+*  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                *
+*----------------------------------------------------------*
+*  pcx.h                                                   *
+***********************************************************/
+
+#ifndef PCX_H
+#define PCX_H
+
+#include "libgame.h"
+
+#if !defined(TARGET_SDL)
+
+#define PCX_Success             0
+#define PCX_OpenFailed         -1
+#define PCX_ReadFailed         -2
+#define        PCX_FileInvalid         -3
+#define PCX_NoMemory           -4
+#define PCX_ColorFailed                -5
+
+/* global PCX error value */
+extern int errno_pcx;
+
+Image *Read_PCX_to_Image(char *);
+
+#endif /* !TARGET_SDL */
+#endif /* PCX_H */
diff --git a/src/libgame/platform.h b/src/libgame/platform.h
new file mode 100644 (file)
index 0000000..0251307
--- /dev/null
@@ -0,0 +1,47 @@
+/***********************************************************
+*  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                *
+*----------------------------------------------------------*
+*  platform.h                                              *
+***********************************************************/
+
+#ifndef PLATFORM_H
+#define PLATFORM_H
+
+/* define keywords for supported main platforms */
+
+#if defined(MSDOS)
+#define PLATFORM_MSDOS
+#elif defined(WIN32)
+#define PLATFORM_WIN32
+#else
+#define PLATFORM_UNIX
+#endif
+
+/* define additional keywords for several Unix platforms */
+
+#if defined(linux)
+#define PLATFORM_LINUX
+#endif
+
+#if defined(__FreeBSD__)
+#define PLATFORM_FREEBSD
+#endif
+
+/* detecting HP-UX by the following compiler keyword definitions:
+   - in K&R mode (the default), the HP C compiler defines "hpux"
+   - in ANSI mode (-Aa or -Ae), the HP C compiler defines "__hpux"
+   - the gcc (Gnu) C compiler defines "__hpux__"
+   Thanks to Jarkko Hietaniemi  for this note. */
+
+#if defined(__hpux__) || defined(__hpux) || defined(hpux)
+#define PLATFORM_HPUX
+#endif
+
+#endif /* PLATFORM_H */
diff --git a/src/libgame/private.c b/src/libgame/private.c
new file mode 100644 (file)
index 0000000..90de58a
--- /dev/null
@@ -0,0 +1,22 @@
+/***********************************************************
+*  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                *
+*----------------------------------------------------------*
+*  private.c                                               *
+***********************************************************/
+
+#include "libgame.h"
+
+#if 0
+Display        *display;
+Visual        *visual;
+int            screen;
+
+DrawWindow     window = None;
+#endif
diff --git a/src/libgame/private.h b/src/libgame/private.h
new file mode 100644 (file)
index 0000000..e79f00d
--- /dev/null
@@ -0,0 +1,27 @@
+/***********************************************************
+*  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                *
+*----------------------------------------------------------*
+*  private.h                                               *
+***********************************************************/
+
+#ifndef PRIVATE_H
+#define PRIVATE_H
+
+#include "libgame.h"
+
+#if 0
+extern Display        *display;
+extern Visual         *visual;
+extern int             screen;
+
+extern DrawWindow      window;
+#endif
+
+#endif /* PRIVATE_H */
diff --git a/src/libgame/random.c b/src/libgame/random.c
new file mode 100644 (file)
index 0000000..864f3dc
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+/*
+ * This is derived from the Berkeley source:
+ *     @(#)random.c    5.5 (Berkeley) 7/6/88
+ * It was reworked for the GNU C Library by Roland McGrath.
+ */
+
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+
+#include "random.h"
+
+
+/* An improved random number generation package.  In addition to the standard
+   rand()/srand() like interface, this package also has a special state info
+   interface.  The initstate() routine is called with a seed, an array of
+   bytes, and a count of how many bytes are being passed in; this array is
+   then initialized to contain information for random number generation with
+   that much state information.  Good sizes for the amount of state
+   information are 32, 64, 128, and 256 bytes.  The state can be switched by
+   calling the setstate() function with the same array as was initiallized
+   with initstate().  By default, the package runs with 128 bytes of state
+   information and generates far better random numbers than a linear
+   congruential generator.  If the amount of state information is less than
+   32 bytes, a simple linear congruential R.N.G. is used.  Internally, the
+   state information is treated as an array of longs; the zeroeth element of
+   the array is the type of R.N.G. being used (small integer); the remainder
+   of the array is the state information for the R.N.G.  Thus, 32 bytes of
+   state information will give 7 longs worth of state information, which will
+   allow a degree seven polynomial.  (Note: The zeroeth word of state
+   information also has some other information stored in it; see setstate
+   for details).  The random number generation technique is a linear feedback
+   shift register approach, employing trinomials (since there are fewer terms
+   to sum up that way).  In this approach, the least significant bit of all
+   the numbers in the state table will act as a linear feedback shift register,
+   and will have period 2^deg - 1 (where deg is the degree of the polynomial
+   being used, assuming that the polynomial is irreducible and primitive).
+   The higher order bits will have longer periods, since their values are
+   also influenced by pseudo-random carries out of the lower bits.  The
+   total period of the generator is approximately deg*(2**deg - 1); thus
+   doubling the amount of state information has a vast influence on the
+   period of the generator.  Note: The deg*(2**deg - 1) is an approximation
+   only good for large deg, when the period of the shift register is the
+   dominant factor.  With deg equal to seven, the period is actually much
+   longer than the 7*(2**7 - 1) predicted by this formula.  */
+
+
+
+/* For each of the currently supported random number generators, we have a
+   break value on the amount of state information (you need at least thi
+   bytes of state info to support this random number generator), a degree for
+   the polynomial (actually a trinomial) that the R.N.G. is based on, and
+   separation between the two lower order coefficients of the trinomial.  */
+
+/* Linear congruential.  */
+#define        TYPE_0          0
+#define        BREAK_0         8
+#define        DEG_0           0
+#define        SEP_0           0
+
+/* x**7 + x**3 + 1.  */
+#define        TYPE_1          1
+#define        BREAK_1         32
+#define        DEG_1           7
+#define        SEP_1           3
+
+/* x**15 + x + 1.  */
+#define        TYPE_2          2
+#define        BREAK_2         64
+#define        DEG_2           15
+#define        SEP_2           1
+
+/* x**31 + x**3 + 1.  */
+#define        TYPE_3          3
+#define        BREAK_3         128
+#define        DEG_3           31
+#define        SEP_3           3
+
+/* x**63 + x + 1.  */
+#define        TYPE_4          4
+#define        BREAK_4         256
+#define        DEG_4           63
+#define        SEP_4           1
+
+
+/* Array versions of the above information to make code run faster.
+   Relies on fact that TYPE_i == i.  */
+
+#define        MAX_TYPES       5       /* Max number of types above.  */
+
+
+
+/* Initially, everything is set up as if from:
+       initstate(1, randtbl, 128);
+   Note that this initialization takes advantage of the fact that srandom
+   advances the front and rear pointers 10*rand_deg times, and hence the
+   rear pointer which starts at 0 will also end up at zero; thus the zeroeth
+   element of the state information, which contains info about the current
+   position of the rear pointer is just
+       (MAX_TYPES * (rptr - state)) + TYPE_3 == TYPE_3.  */
+
+static long int randtbl[DEG_3 + 1] =
+{
+  TYPE_3,
+  -851904987, -43806228, -2029755270, 1390239686, -1912102820,
+  -485608943, 1969813258, -1590463333, -1944053249, 455935928, 508023712,
+  -1714531963, 1800685987, -2015299881, 654595283, -1149023258,
+  -1470005550, -1143256056, -1325577603, -1568001885, 1275120390,
+  -607508183, -205999574, -1696891592, 1492211999, -1528267240,
+  -952028296, -189082757, 362343714, 1424981831, 2039449641,
+};
+
+/* FPTR and RPTR are two pointers into the state info, a front and a rear
+   pointer.  These two pointers are always rand_sep places aparts, as they
+   cycle through the state information.  (Yes, this does mean we could get
+   away with just one pointer, but the code for random is more efficient
+   this way).  The pointers are left positioned as they would be from the call:
+       initstate(1, randtbl, 128);
+   (The position of the rear pointer, rptr, is really 0 (as explained above
+   in the initialization of randtbl) because the state table pointer is set
+   to point to randtbl[1] (as explained below).)  */
+
+static long int *fptr = &randtbl[SEP_3 + 1];
+static long int *rptr = &randtbl[1];
+
+
+
+/* The following things are the pointer to the state information table,
+   the type of the current generator, the degree of the current polynomial
+   being used, and the separation between the two pointers.
+   Note that for efficiency of random, we remember the first location of
+   the state information, not the zeroeth.  Hence it is valid to access
+   state[-1], which is used to store the type of the R.N.G.
+   Also, we remember the last location, since this is more efficient than
+   indexing every time to find the address of the last element to see if
+   the front and rear pointers have wrapped.  */
+
+static long int *state = &randtbl[1];
+
+static int rand_type = TYPE_3;
+static int rand_deg = DEG_3;
+static int rand_sep = SEP_3;
+
+static long int *end_ptr = &randtbl[sizeof(randtbl) / sizeof(randtbl[0])];
+
+/* Initialize the random number generator based on the given seed.  If the
+   type is the trivial no-state-information type, just remember the seed.
+   Otherwise, initializes state[] based on the given "seed" via a linear
+   congruential generator.  Then, the pointers are set to known locations
+   that are exactly rand_sep places apart.  Lastly, it cycles the state
+   information a given number of times to get rid of any initial dependencies
+   introduced by the L.C.R.N.G.  Note that the initialization of randtbl[]
+   for default usage relies on values produced by this routine.  */
+
+void srandom_linux_libc(unsigned int x)
+{
+  state[0] = x;
+  if (rand_type != TYPE_0)
+  {
+    register long int i;
+    for (i = 1; i < rand_deg; ++i)
+      state[i] = (1103515145 * state[i - 1]) + 12345;
+    fptr = &state[rand_sep];
+    rptr = &state[0];
+    for (i = 0; i < 10 * rand_deg; ++i)
+      (void) random_linux_libc();
+  }
+}
+
+/* If we are using the trivial TYPE_0 R.N.G., just do the old linear
+   congruential bit.  Otherwise, we do our fancy trinomial stuff, which is the
+   same in all ther other cases due to all the global variables that have been
+   set up.  The basic operation is to add the number at the rear pointer into
+   the one at the front pointer.  Then both pointers are advanced to the next
+   location cyclically in the table.  The value returned is the sum generated,
+   reduced to 31 bits by throwing away the "least random" low bit.
+   Note: The code takes advantage of the fact that both the front and
+   rear pointers can't wrap on the same call by not testing the rear
+   pointer if the front one has wrapped.  Returns a 31-bit random number.  */
+
+long int random_linux_libc()
+{
+  if (rand_type == TYPE_0)
+  {
+    state[0] = ((state[0] * 1103515245) + 12345) & LONG_MAX;
+    return state[0];
+  }
+  else
+  {
+    long int i;
+    *fptr += *rptr;
+    /* Chucking least random bit.  */
+    i = (*fptr >> 1) & LONG_MAX;
+    ++fptr;
+    if (fptr >= end_ptr)
+    {
+      fptr = state;
+      ++rptr;
+    }
+    else
+    {
+      ++rptr;
+      if (rptr >= end_ptr)
+       rptr = state;
+    }
+    return i;
+  }
+}
diff --git a/src/libgame/random.h b/src/libgame/random.h
new file mode 100644 (file)
index 0000000..366d1ff
--- /dev/null
@@ -0,0 +1,20 @@
+/***********************************************************
+*  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                *
+*----------------------------------------------------------*
+*  random.h                                                *
+***********************************************************/
+
+#ifndef RANDOM_H
+#define RANDOM_H
+
+void srandom_linux_libc(unsigned int);
+long int random_linux_libc(void);
+
+#endif
diff --git a/src/libgame/sdl.c b/src/libgame/sdl.c
new file mode 100644 (file)
index 0000000..8e2ec94
--- /dev/null
@@ -0,0 +1,213 @@
+/***********************************************************
+*  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             *
+*----------------------------------------------------------*
+*  sdl.c                                                   *
+***********************************************************/
+
+#include "libgame.h"
+
+#ifdef TARGET_SDL
+
+inline void SDLInitBufferedDisplay(DrawBuffer *backbuffer, DrawWindow *window)
+{
+  /* initialize SDL video */
+  if (SDL_Init(SDL_INIT_VIDEO) < 0)
+    Error(ERR_EXIT, "SDL_Init() failed: %s", SDL_GetError());
+
+  /* automatically cleanup SDL stuff after exit() */
+  atexit(SDL_Quit);
+
+  /* open SDL video output device (window or fullscreen mode) */
+  if (!SDLSetVideoMode(backbuffer))
+    Error(ERR_EXIT, "setting video mode failed");
+
+  /* set window and icon title */
+  SDL_WM_SetCaption(WINDOW_TITLE_STRING, WINDOW_TITLE_STRING);
+
+  /* create additional buffer for double-buffering */
+  pix[PIX_DB_BACK] = CreateBitmap(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH);
+
+  /* SDL cannot directly draw to the visible video framebuffer like X11,
+     but always uses a backbuffer, which is then blitted to the visible
+     video framebuffer with 'SDL_UpdateRect' (or replaced with the current
+     visible video framebuffer with 'SDL_Flip', if the hardware supports
+     this). Therefore do not use an additional backbuffer for drawing, but
+     use a symbolic buffer (distinguishable from the SDL backbuffer) called
+     'window', which indicates that the SDL backbuffer should be updated to
+     the visible video framebuffer when attempting to blit to it.
+
+     For convenience, it seems to be a good idea to create this symbolic
+     buffer 'window' at the same size as the SDL backbuffer. Although it
+     should never be drawn to directly, it would do no harm nevertheless. */
+
+  *window = pix[PIX_DB_BACK];          /* 'window' is only symbolic buffer */
+  pix[PIX_DB_BACK] = *backbuffer;      /* 'backbuffer' is SDL screen buffer */
+}
+
+inline boolean SDLSetVideoMode(DrawBuffer *backbuffer, boolean fullscreen)
+{
+  boolean success = TRUE;
+
+  if (fullscreen && !video.fullscreen_enabled && video.fullscreen_available)
+  {
+    /* switch display to fullscreen mode, if available */
+    DrawWindow window_old = *backbuffer;
+    DrawWindow window_new;
+
+    if ((window_new = SDL_SetVideoMode(WIN_XSIZE, WIN_YSIZE, WIN_SDL_DEPTH,
+                                      SDL_HWSURFACE|SDL_FULLSCREEN))
+       == NULL)
+    {
+      /* switching display to fullscreen mode failed */
+      Error(ERR_WARN, "SDL_SetVideoMode() failed: %s", SDL_GetError());
+
+      /* do not try it again */
+      video.fullscreen_available = FALSE;
+      success = FALSE;
+    }
+    else
+    {
+      if (window_old)
+       SDL_FreeSurface(window_old);
+      *backbuffer = window_new;
+
+      video.fullscreen_enabled = TRUE;
+      success = TRUE;
+    }
+  }
+
+  if ((!fullscreen && video.fullscreen_enabled) || !*backbuffer)
+  {
+    /* switch display to window mode */
+    DrawWindow window_old = *backbuffer;
+    DrawWindow window_new;
+
+    if ((window_new = SDL_SetVideoMode(WIN_XSIZE, WIN_YSIZE, WIN_SDL_DEPTH,
+                                      SDL_HWSURFACE))
+       == NULL)
+    {
+      /* switching display to window mode failed -- should not happen */
+      Error(ERR_WARN, "SDL_SetVideoMode() failed: %s", SDL_GetError());
+
+      success = FALSE;
+    }
+    else
+    {
+      if (window_old)
+       SDL_FreeSurface(window_old);
+      *backbuffer = window_new;
+
+      video.fullscreen_enabled = FALSE;
+      success = TRUE;
+    }
+  }
+
+  return success;
+}
+
+inline void SDLCopyArea(SDL_Surface *src_surface, SDL_Surface *dst_surface,
+                       int src_x, int src_y,
+                       int width, int height,
+                       int dst_x, int dst_y)
+{
+  SDL_Surface *surface = (dst_surface == window ? backbuffer : dst_surface);
+  SDL_Rect src_rect, dst_rect;
+
+  src_rect.x = src_x;
+  src_rect.y = src_y;
+  src_rect.w = width;
+  src_rect.h = height;
+
+  dst_rect.x = dst_x;
+  dst_rect.y = dst_y;
+  dst_rect.w = width;
+  dst_rect.h = height;
+
+  if (src_surface != backbuffer || dst_surface != window)
+    SDL_BlitSurface(src_surface, &src_rect, surface, &dst_rect);
+
+  if (dst_surface == window)
+    SDL_UpdateRect(backbuffer, dst_x, dst_y, width, height);
+}
+
+inline void SDLFillRectangle(SDL_Surface *dst_surface, int x, int y,
+                            int width, int height, unsigned int color)
+{
+  SDL_Surface *surface = (dst_surface == window ? backbuffer : dst_surface);
+  SDL_Rect rect;
+  unsigned int color_r = (color >> 16) && 0xff;
+  unsigned int color_g = (color >>  8) && 0xff;
+  unsigned int color_b = (color >>  0) && 0xff;
+
+  rect.x = x;
+  rect.y = y;
+  rect.w = width;
+  rect.h = height;
+
+  SDL_FillRect(surface, &rect,
+              SDL_MapRGB(surface->format, color_r, color_g, color_b));
+
+  if (dst_surface == window)
+    SDL_UpdateRect(backbuffer, x, y, width, height);
+}
+
+inline void SDLDrawSimpleLine(SDL_Surface *surface, int from_x, int from_y,
+                             int to_x, int to_y, unsigned int color)
+{
+  SDL_Rect rect;
+  unsigned int color_r = (color >> 16) & 0xff;
+  unsigned int color_g = (color >>  8) & 0xff;
+  unsigned int color_b = (color >>  0) & 0xff;
+
+  if (from_x > to_x)
+    swap_numbers(&from_x, &to_x);
+
+  if (from_y > to_y)
+    swap_numbers(&from_y, &to_y);
+
+  rect.x = from_x;
+  rect.y = from_y;
+  rect.w = (to_x - from_x + 1);
+  rect.h = (to_y - from_y + 1);
+
+  SDL_FillRect(surface, &rect,
+               SDL_MapRGB(surface->format, color_r, color_g, color_b));
+}
+
+inline boolean SDLOpenAudio(void)
+{
+  if (SDL_Init(SDL_INIT_AUDIO) < 0)
+  {
+    Error(ERR_WARN, "SDL_Init() failed: %s", SDL_GetError());
+    return FALSE;
+  }
+
+  if (Mix_OpenAudio(22050, AUDIO_S16, 2, 512) < 0)
+  {
+    Error(ERR_WARN, "Mix_OpenAudio() failed: %s", SDL_GetError());
+    return FALSE;
+  }
+
+  Mix_Volume(-1, SDL_MIX_MAXVOLUME / 4);
+  Mix_VolumeMusic(SDL_MIX_MAXVOLUME / 4);
+
+  return TRUE;
+}
+
+inline void SDLCloseAudio(void)
+{
+  Mix_HaltMusic();
+  Mix_HaltChannel(-1);
+
+  Mix_CloseAudio();
+}
+
+#endif /* TARGET_SDL */
diff --git a/src/libgame/sdl.h b/src/libgame/sdl.h
new file mode 100644 (file)
index 0000000..f150e7d
--- /dev/null
@@ -0,0 +1,309 @@
+/***********************************************************
+*  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             *
+*----------------------------------------------------------*
+*  sdl.h                                                   *
+***********************************************************/
+
+#ifndef SDL_H
+#define SDL_H
+
+#include "SDL.h"
+#include "SDL_image.h"
+#include "SDL_mixer.h"
+
+
+/* definitions needed for "system.c" */
+
+#define SURFACE_FLAGS          (SDL_SWSURFACE)
+
+
+/* system dependent definitions */
+
+#define TARGET_STRING          "SDL"
+#define FULLSCREEN_STATUS      FULLSCREEN_AVAILABLE
+
+
+/* SDL type definitions */
+
+typedef SDL_Surface           *Bitmap;
+typedef SDL_Surface           *DrawWindow;
+typedef SDL_Surface           *DrawBuffer;
+
+typedef SDLKey                 Key;
+
+typedef SDL_Event              Event;
+typedef SDL_MouseButtonEvent   ButtonEvent;
+typedef SDL_MouseMotionEvent   MotionEvent;
+typedef SDL_KeyboardEvent      KeyEvent;
+typedef SDL_Event              ExposeEvent;
+typedef SDL_Event              FocusChangeEvent;
+typedef SDL_Event              ClientMessageEvent;
+
+typedef int                    GC;
+typedef int                    Pixmap;
+typedef int                    Display;
+typedef int                    Visual;
+typedef int                    Colormap;
+
+
+/* SDL symbol definitions */
+
+#define None                   0L
+
+#define EVENT_BUTTONPRESS      SDL_MOUSEBUTTONDOWN
+#define EVENT_BUTTONRELEASE    SDL_MOUSEBUTTONUP
+#define EVENT_MOTIONNOTIFY     SDL_MOUSEMOTION
+#define EVENT_KEYPRESS         SDL_KEYDOWN
+#define EVENT_KEYRELEASE       SDL_KEYUP
+#define EVENT_EXPOSE           SDL_USEREVENT + 0
+#define EVENT_FOCUSIN          SDL_USEREVENT + 1
+#define EVENT_FOCUSOUT         SDL_USEREVENT + 2
+#define EVENT_CLIENTMESSAGE    SDL_QUIT
+#define EVENT_MAPNOTIFY                SDL_USEREVENT + 4
+#define EVENT_UNMAPNOTIFY      SDL_USEREVENT + 5
+
+#define KSYM_UNDEFINED         SDLK_UNKNOWN
+
+#define KSYM_Return            SDLK_RETURN
+#define KSYM_Escape            SDLK_ESCAPE
+
+#define KSYM_Left              SDLK_LEFT
+#define KSYM_Right             SDLK_RIGHT
+#define KSYM_Up                        SDLK_UP
+#define KSYM_Down              SDLK_DOWN
+
+#ifdef SDLK_KP_LEFT
+#define KSYM_KP_Left           SDLK_KP_LEFT
+#define KSYM_KP_Right          SDLK_KP_RIGHT
+#define KSYM_KP_Up             SDLK_KP_UP
+#define KSYM_KP_Down           SDLK_KP_DOWN
+#endif
+
+#define KSYM_KP_Enter          SDLK_KP_ENTER
+#define KSYM_KP_Add            SDLK_KP_PLUS
+#define KSYM_KP_Subtract       SDLK_KP_MINUS
+#define KSYM_KP_Multiply       SDLK_KP_MULTIPLY
+#define KSYM_KP_Divide         SDLK_KP_DIVIDE
+#define KSYM_KP_Separator      SDLK_KP_PERIOD
+
+#define KSYM_Shift_L           SDLK_LSHIFT
+#define KSYM_Shift_R           SDLK_RSHIFT
+#define KSYM_Control_L         SDLK_LCTRL
+#define KSYM_Control_R         SDLK_RCTRL
+#define KSYM_Meta_L            SDLK_LMETA
+#define KSYM_Meta_R            SDLK_RMETA
+#define KSYM_Alt_L             SDLK_LALT
+#define KSYM_Alt_R             SDLK_RALT
+#define KSYM_Super_L           SDLK_LSUPER
+#define KSYM_Super_R           SDLK_RSUPER
+#define KSYM_Mode_switch       SDLK_MODE
+#define KSYM_Multi_key         SDLK_RCTRL
+
+#define KSYM_BackSpace         SDLK_BACKSPACE
+#define KSYM_Delete            SDLK_DELETE
+#define KSYM_Insert            SDLK_INSERT
+#define KSYM_Tab               SDLK_TAB
+#define KSYM_Home              SDLK_HOME
+#define KSYM_End               SDLK_END
+#define KSYM_Page_Up           SDLK_PAGEUP
+#define KSYM_Page_Down         SDLK_PAGEDOWN
+#define KSYM_Menu              SDLK_MENU
+
+#define KSYM_space             SDLK_SPACE
+#define KSYM_exclam            SDLK_EXCLAIM
+#define KSYM_quotedbl          SDLK_QUOTEDBL
+#define KSYM_numbersign                SDLK_HASH
+#define KSYM_dollar            SDLK_DOLLAR
+#define KSYM_percent           KSYM_UNDEFINED          /* undefined */
+#define KSYM_ampersand         SDLK_AMPERSAND
+#define KSYM_apostrophe                SDLK_QUOTE
+#define KSYM_parenleft         SDLK_LEFTPAREN
+#define KSYM_parenright                SDLK_RIGHTPAREN
+#define KSYM_asterisk          SDLK_ASTERISK
+#define KSYM_plus              SDLK_PLUS
+#define KSYM_comma             SDLK_COMMA
+#define KSYM_minus             SDLK_MINUS
+#define KSYM_period            SDLK_PERIOD
+#define KSYM_slash             SDLK_SLASH
+
+#define KSYM_colon             SDLK_COLON
+#define KSYM_semicolon         SDLK_SEMICOLON
+#define KSYM_less              SDLK_LESS
+#define KSYM_equal             SDLK_EQUALS
+#define KSYM_greater           SDLK_GREATER
+#define KSYM_question          SDLK_QUESTION
+#define KSYM_at                        SDLK_AT
+
+#define KSYM_bracketleft       SDLK_LEFTBRACKET
+#define KSYM_backslash         SDLK_BACKSLASH
+#define KSYM_bracketright      SDLK_RIGHTBRACKET
+#define KSYM_asciicircum       SDLK_CARET
+#define KSYM_underscore                SDLK_UNDERSCORE
+#define KSYM_grave             SDLK_BACKQUOTE
+
+#define KSYM_quoteleft         KSYM_UNDEFINED          /* undefined */
+#define KSYM_braceleft         KSYM_UNDEFINED          /* undefined */
+#define KSYM_bar               KSYM_UNDEFINED          /* undefined */
+#define KSYM_braceright                KSYM_UNDEFINED          /* undefined */
+#define KSYM_asciitilde                KSYM_UNDEFINED          /* undefined */
+
+#define KSYM_Adiaeresis                SDLK_WORLD_36
+#define KSYM_Odiaeresis                SDLK_WORLD_54
+#define KSYM_Udiaeresis                SDLK_WORLD_60
+#define KSYM_adiaeresis                SDLK_WORLD_68
+#define KSYM_odiaeresis                SDLK_WORLD_86
+#define KSYM_udiaeresis                SDLK_WORLD_92
+#define KSYM_ssharp            SDLK_WORLD_63
+
+#ifndef SDLK_A
+#define SDLK_A                 65
+#define SDLK_B                 66
+#define SDLK_C                 67
+#define SDLK_D                 68
+#define SDLK_E                 69
+#define SDLK_F                 70
+#define SDLK_G                 71
+#define SDLK_H                 72
+#define SDLK_I                 73
+#define SDLK_J                 74
+#define SDLK_K                 75
+#define SDLK_L                 76
+#define SDLK_M                 77
+#define SDLK_N                 78
+#define SDLK_O                 79
+#define SDLK_P                 80
+#define SDLK_Q                 81
+#define SDLK_R                 82
+#define SDLK_S                 83
+#define SDLK_T                 84
+#define SDLK_U                 85
+#define SDLK_V                 86
+#define SDLK_W                 87
+#define SDLK_X                 88
+#define SDLK_Y                 89
+#define SDLK_Z                 90
+#endif
+
+#define KSYM_A                 SDLK_A
+#define KSYM_B                 SDLK_B
+#define KSYM_C                 SDLK_C
+#define KSYM_D                 SDLK_D
+#define KSYM_E                 SDLK_E
+#define KSYM_F                 SDLK_F
+#define KSYM_G                 SDLK_G
+#define KSYM_H                 SDLK_H
+#define KSYM_I                 SDLK_I
+#define KSYM_J                 SDLK_J
+#define KSYM_K                 SDLK_K
+#define KSYM_L                 SDLK_L
+#define KSYM_M                 SDLK_M
+#define KSYM_N                 SDLK_N
+#define KSYM_O                 SDLK_O
+#define KSYM_P                 SDLK_P
+#define KSYM_Q                 SDLK_Q
+#define KSYM_R                 SDLK_R
+#define KSYM_S                 SDLK_S
+#define KSYM_T                 SDLK_T
+#define KSYM_U                 SDLK_U
+#define KSYM_V                 SDLK_V
+#define KSYM_W                 SDLK_W
+#define KSYM_X                 SDLK_X
+#define KSYM_Y                 SDLK_Y
+#define KSYM_Z                 SDLK_Z
+
+#define KSYM_a                 SDLK_a
+#define KSYM_b                 SDLK_b
+#define KSYM_c                 SDLK_c
+#define KSYM_d                 SDLK_d
+#define KSYM_e                 SDLK_e
+#define KSYM_f                 SDLK_f
+#define KSYM_g                 SDLK_g
+#define KSYM_h                 SDLK_h
+#define KSYM_i                 SDLK_i
+#define KSYM_j                 SDLK_j
+#define KSYM_k                 SDLK_k
+#define KSYM_l                 SDLK_l
+#define KSYM_m                 SDLK_m
+#define KSYM_n                 SDLK_n
+#define KSYM_o                 SDLK_o
+#define KSYM_p                 SDLK_p
+#define KSYM_q                 SDLK_q
+#define KSYM_r                 SDLK_r
+#define KSYM_s                 SDLK_s
+#define KSYM_t                 SDLK_t
+#define KSYM_u                 SDLK_u
+#define KSYM_v                 SDLK_v
+#define KSYM_w                 SDLK_w
+#define KSYM_x                 SDLK_x
+#define KSYM_y                 SDLK_y
+#define KSYM_z                 SDLK_z
+
+#define KSYM_0                 SDLK_0
+#define KSYM_1                 SDLK_1
+#define KSYM_2                 SDLK_2
+#define KSYM_3                 SDLK_3
+#define KSYM_4                 SDLK_4
+#define KSYM_5                 SDLK_5
+#define KSYM_6                 SDLK_6
+#define KSYM_7                 SDLK_7
+#define KSYM_8                 SDLK_8
+#define KSYM_9                 SDLK_9
+
+#define KSYM_KP_0              SDLK_KP0
+#define KSYM_KP_1              SDLK_KP1
+#define KSYM_KP_2              SDLK_KP2
+#define KSYM_KP_3              SDLK_KP3
+#define KSYM_KP_4              SDLK_KP4
+#define KSYM_KP_5              SDLK_KP5
+#define KSYM_KP_6              SDLK_KP6
+#define KSYM_KP_7              SDLK_KP7
+#define KSYM_KP_8              SDLK_KP8
+#define KSYM_KP_9              SDLK_KP9
+
+#define KSYM_F1                        SDLK_F1
+#define KSYM_F2                        SDLK_F2
+#define KSYM_F3                        SDLK_F3
+#define KSYM_F4                        SDLK_F4
+#define KSYM_F5                        SDLK_F5
+#define KSYM_F6                        SDLK_F6
+#define KSYM_F7                        SDLK_F7
+#define KSYM_F8                        SDLK_F8
+#define KSYM_F9                        SDLK_F9
+#define KSYM_F10               SDLK_F10
+#define KSYM_F11               SDLK_F11
+#define KSYM_F12               SDLK_F12
+#define KSYM_F13               SDLK_F13
+#define KSYM_F14               SDLK_F14
+#define KSYM_F15               SDLK_F15
+#define KSYM_F16               KSYM_UNDEFINED
+#define KSYM_F17               KSYM_UNDEFINED
+#define KSYM_F18               KSYM_UNDEFINED
+#define KSYM_F19               KSYM_UNDEFINED
+#define KSYM_F20               KSYM_UNDEFINED
+#define KSYM_F21               KSYM_UNDEFINED
+#define KSYM_F22               KSYM_UNDEFINED
+#define KSYM_F23               KSYM_UNDEFINED
+#define KSYM_F24               KSYM_UNDEFINED
+
+
+/* SDL function definitions */
+
+inline void SDLInitBufferedDisplay(DrawBuffer *, DrawWindow *);
+inline boolean SDLSetVideoMode(DrawBuffer *, boolean);
+inline void SDLCopyArea(SDL_Surface *, SDL_Surface *,
+                        int, int, int, int, int, int);
+inline void SDLFillRectangle(SDL_Surface *, int, int, int, int, unsigned int);
+inline void SDLDrawSimpleLine(SDL_Surface *, int, int, int, int, unsigned int);
+
+inline boolean SDLOpenAudio(void);
+inline void SDLCloseAudio(void);
+
+#endif /* SDL_H */
diff --git a/src/libgame/sound.c b/src/libgame/sound.c
new file mode 100644 (file)
index 0000000..745e3cd
--- /dev/null
@@ -0,0 +1,1032 @@
+/***********************************************************
+*  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                *
+*----------------------------------------------------------*
+*  sound.c                                                 *
+***********************************************************/
+
+#include "libgame.h"
+
+#include "main_TMP.h"
+
+#include "sound.h"
+#include "misc.h"
+
+/*** THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS ***/
+
+static int playing_sounds = 0;
+static struct SoundControl playlist[MAX_SOUNDS_PLAYING];
+static struct SoundControl emptySoundControl =
+{
+  -1,0,0, FALSE,FALSE,FALSE,FALSE,FALSE, 0,0L,0L,NULL
+};
+
+#if defined(PLATFORM_UNIX)
+static int stereo_volume[PSND_MAX_LEFT2RIGHT+1];
+static char premix_first_buffer[SND_BLOCKSIZE];
+#if defined(AUDIO_STREAMING_DSP)
+static char premix_left_buffer[SND_BLOCKSIZE];
+static char premix_right_buffer[SND_BLOCKSIZE];
+static int premix_last_buffer[SND_BLOCKSIZE];
+#endif
+static unsigned char playing_buffer[SND_BLOCKSIZE];
+#endif
+
+/* forward declaration of internal functions */
+#if defined(AUDIO_STREAMING_DSP)
+static void SoundServer_InsertNewSound(struct SoundControl);
+#elif defined(PLATFORM_UNIX)
+static unsigned char linear_to_ulaw(int);
+static int ulaw_to_linear(unsigned char);
+#endif
+
+#if defined(PLATFORM_HPUX)
+static void HPUX_Audio_Control();
+#endif
+
+#if defined(PLATFORM_MSDOS)
+static void SoundServer_InsertNewSound(struct SoundControl);
+static void SoundServer_StopSound(int);
+static void SoundServer_StopAllSounds();
+#endif
+
+#if defined(PLATFORM_UNIX)
+int OpenAudioDevice(char *audio_device_name)
+{
+  int audio_fd;
+
+  /* check if desired audio device is accessible */
+  if (access(audio_device_name, W_OK) != 0)
+    return -1;
+
+  /* try to open audio device in non-blocking mode */
+  if ((audio_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0)
+    return audio_fd;
+
+  /* re-open audio device in blocking mode */
+  close(audio_fd);
+  audio_fd = open(audio_device_name, O_WRONLY);
+
+  return audio_fd;
+}
+
+void UnixOpenAudio(struct AudioSystemInfo *audio)
+{
+  static char *audio_device_name[] =
+  {
+    DEVICENAME_DSP,
+    DEVICENAME_AUDIO
+  };
+  int audio_fd = -1;
+  int i;
+
+  /* look for available audio devices, starting with preferred ones */
+  for (i=0; i<sizeof(audio_device_name)/sizeof(char *); i++)
+    if ((audio_fd = OpenAudioDevice(audio_device_name[i])) >= 0)
+      break;
+
+  if (audio_fd < 0)
+  {
+    Error(ERR_WARN, "cannot open audio device - no sound");
+    return;
+  }
+
+  close(audio_fd);
+
+  audio->device_name = audio_device_name[i];
+  audio->sound_available = TRUE;
+
+#if defined(AUDIO_STREAMING_DSP)
+  audio->loops_available = TRUE;
+#endif
+}
+
+void UnixCloseAudio(struct AudioSystemInfo *audio)
+{
+  if (audio->device_fd)
+    close(audio->device_fd);
+}
+
+#endif /* PLATFORM_UNIX */
+
+void SoundServer()
+{
+  int i;
+#if defined(PLATFORM_UNIX)
+  struct SoundControl snd_ctrl;
+  fd_set sound_fdset;
+
+  close(audio.soundserver_pipe[1]);    /* no writing into pipe needed */
+#endif
+
+  for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+    playlist[i] = emptySoundControl;
+  playing_sounds = 0;
+
+#if defined(PLATFORM_UNIX)
+  stereo_volume[PSND_MAX_LEFT2RIGHT] = 0;
+  for(i=0;i<PSND_MAX_LEFT2RIGHT;i++)
+    stereo_volume[i] =
+      (int)sqrt((float)(PSND_MAX_LEFT2RIGHT*PSND_MAX_LEFT2RIGHT-i*i));
+
+#if defined(PLATFORM_HPUX)
+  HPUX_Audio_Control();
+#endif
+
+  FD_ZERO(&sound_fdset); 
+  FD_SET(audio.soundserver_pipe[0], &sound_fdset);
+
+  while(1)     /* wait for sound playing commands from client */
+  {
+    FD_SET(audio.soundserver_pipe[0], &sound_fdset);
+    select(audio.soundserver_pipe[0] + 1, &sound_fdset, NULL, NULL, NULL);
+    if (!FD_ISSET(audio.soundserver_pipe[0], &sound_fdset))
+      continue;
+    if (read(audio.soundserver_pipe[0], &snd_ctrl, sizeof(snd_ctrl))
+       != sizeof(snd_ctrl))
+      Error(ERR_EXIT_SOUND_SERVER, "broken pipe - no sounds");
+
+#if defined(AUDIO_STREAMING_DSP)
+
+    if (snd_ctrl.fade_sound)
+    {
+      if (!playing_sounds)
+       continue;
+
+      for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+       if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
+         playlist[i].fade_sound = TRUE;
+    }
+    else if (snd_ctrl.stop_all_sounds)
+    {
+      if (!playing_sounds)
+       continue;
+
+      for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+       playlist[i]=emptySoundControl;
+      playing_sounds=0;
+
+      close(audio.device_fd);
+    }
+    else if (snd_ctrl.stop_sound)
+    {
+      if (!playing_sounds)
+       continue;
+
+      for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+       if (playlist[i].nr == snd_ctrl.nr)
+       {
+         playlist[i]=emptySoundControl;
+         playing_sounds--;
+       }
+
+      if (!playing_sounds)
+       close(audio.device_fd);
+    }
+
+    if (playing_sounds || snd_ctrl.active)
+    {
+      struct timeval delay = { 0, 0 };
+      byte *sample_ptr;
+      long sample_size;
+      static long max_sample_size = 0;
+      static long fragment_size = 0;
+      /* Even if the stereo flag is used as being boolean, it must be
+        defined as an integer, else 'ioctl()' will fail! */
+      int stereo = TRUE;
+#if 0
+      int sample_rate = 8000;
+#else
+      int sample_rate = 22050;
+#endif
+
+      if (playing_sounds ||
+         (audio.device_fd = OpenAudioDevice(audio.device_name)) >= 0)
+      {
+       if (!playing_sounds)    /* we just opened the audio device */
+       {
+         /* 2 buffers / 512 bytes, giving 1/16 second resolution */
+         /* (with stereo the effective buffer size will shrink to 256) */
+         fragment_size = 0x00020009;
+
+         if (ioctl(audio.device_fd,SNDCTL_DSP_SETFRAGMENT,&fragment_size) < 0)
+           Error(ERR_EXIT_SOUND_SERVER,
+                 "cannot set fragment size of /dev/dsp - no sounds");
+
+         /* try if we can use stereo sound */
+         if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
+         {
+#ifdef DEBUG
+           static boolean reported = FALSE;
+
+           if (!reported)
+           {
+             Error(ERR_RETURN, "cannot get stereo sound on /dev/dsp");
+             reported = TRUE;
+           }
+#endif
+           stereo = FALSE;
+         }
+
+         if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &sample_rate) < 0)
+           Error(ERR_EXIT_SOUND_SERVER,
+                 "cannot set sample rate of /dev/dsp - no sounds");
+
+         /* get the real fragmentation size; this should return 512 */
+         if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE,&fragment_size) < 0)
+           Error(ERR_EXIT_SOUND_SERVER,
+                 "cannot get fragment size of /dev/dsp - no sounds");
+
+         max_sample_size = fragment_size / (stereo ? 2 : 1);
+       }
+
+       if (snd_ctrl.active)    /* new sound has arrived */
+         SoundServer_InsertNewSound(snd_ctrl);
+
+       while(playing_sounds &&
+             select(audio.soundserver_pipe[0] + 1,
+                    &sound_fdset, NULL, NULL, &delay) < 1)
+       {       
+         FD_SET(audio.soundserver_pipe[0], &sound_fdset);
+
+         /* first clear the last premixing buffer */
+         memset(premix_last_buffer,0,fragment_size*sizeof(int));
+
+         for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+         {
+           int j;
+
+           if (!playlist[i].active)
+             continue;
+
+           /* get pointer and size of the actual sound sample */
+           sample_ptr = playlist[i].data_ptr+playlist[i].playingpos;
+           sample_size =
+             MIN(max_sample_size,playlist[i].data_len-playlist[i].playingpos);
+           playlist[i].playingpos += sample_size;
+
+           /* fill the first mixing buffer with original sample */
+           memcpy(premix_first_buffer,sample_ptr,sample_size);
+
+           /* are we about to restart a looping sound? */
+           if (playlist[i].loop && sample_size<max_sample_size)
+           {
+             playlist[i].playingpos = max_sample_size-sample_size;
+             memcpy(premix_first_buffer+sample_size,
+                    playlist[i].data_ptr,max_sample_size-sample_size);
+             sample_size = max_sample_size;
+           }
+
+           /* decrease volume if sound is fading out */
+           if (playlist[i].fade_sound &&
+               playlist[i].volume>=PSND_MAX_VOLUME/10)
+             playlist[i].volume-=PSND_MAX_VOLUME/20;
+
+           /* adjust volume of actual sound sample */
+           if (playlist[i].volume != PSND_MAX_VOLUME)
+             for(j=0;j<sample_size;j++)
+               premix_first_buffer[j] =
+                 (playlist[i].volume * (int)premix_first_buffer[j])
+                   >> PSND_MAX_VOLUME_BITS;
+
+           /* fill the last mixing buffer with stereo or mono sound */
+           if (stereo)
+           {
+             int middle_pos = PSND_MAX_LEFT2RIGHT/2;
+             int left_volume = stereo_volume[middle_pos+playlist[i].stereo];
+             int right_volume = stereo_volume[middle_pos-playlist[i].stereo];
+
+             for(j=0;j<sample_size;j++)
+             {
+               premix_left_buffer[j] =
+                 (left_volume * (int)premix_first_buffer[j])
+                   >> PSND_MAX_LEFT2RIGHT_BITS;
+               premix_right_buffer[j] =
+                 (right_volume * (int)premix_first_buffer[j])
+                   >> PSND_MAX_LEFT2RIGHT_BITS;
+               premix_last_buffer[2*j+0] += premix_left_buffer[j];
+               premix_last_buffer[2*j+1] += premix_right_buffer[j];
+             }
+           }
+           else
+           {
+             for(j=0;j<sample_size;j++)
+               premix_last_buffer[j] += (int)premix_first_buffer[j];
+           }
+
+           /* delete completed sound entries from the playlist */
+           if (playlist[i].playingpos >= playlist[i].data_len)
+           {
+             if (playlist[i].loop)
+               playlist[i].playingpos = 0;
+             else
+             {
+               playlist[i] = emptySoundControl;
+               playing_sounds--;
+             }
+           }
+           else if (playlist[i].volume <= PSND_MAX_VOLUME/10)
+           {
+             playlist[i] = emptySoundControl;
+             playing_sounds--;
+           }
+         }
+
+         /* put last mixing buffer to final playing buffer */
+         for(i=0;i<fragment_size;i++)
+         {
+           if (premix_last_buffer[i]<-255)
+             playing_buffer[i] = 0;
+           else if (premix_last_buffer[i]>255)
+             playing_buffer[i] = 255;
+           else
+             playing_buffer[i] = (premix_last_buffer[i]>>1)^0x80;
+         }
+
+         /* finally play the sound fragment */
+         write(audio.device_fd, playing_buffer,fragment_size);
+       }
+
+       /* if no sounds playing, free device for other sound programs */
+       if (!playing_sounds)
+         close(audio.device_fd);
+      }
+    }
+
+#else /* !AUDIO_STREAMING_DSP */
+
+    if (snd_ctrl.active && !snd_ctrl.loop)
+    {
+      struct timeval delay = { 0, 0 };
+      byte *sample_ptr;
+      long sample_size, max_sample_size = SND_BLOCKSIZE;
+      long sample_rate = 8000; /* standard "/dev/audio" sampling rate */
+      int wait_percent = 90;   /* wait 90% of the real playing time */
+      int i;
+
+      if ((audio.device_fd = OpenAudioDevice(audio.device_name)) >= 0)
+      {
+       playing_sounds = 1;
+
+       while(playing_sounds &&
+             select(audio.soundserver_pipe[0] + 1,
+                    &sound_fdset, NULL, NULL, &delay) < 1)
+       {       
+         FD_SET(audio.soundserver_pipe[0], &sound_fdset);
+
+         /* get pointer and size of the actual sound sample */
+         sample_ptr = snd_ctrl.data_ptr + snd_ctrl.playingpos;
+         sample_size =
+           MIN(max_sample_size, snd_ctrl.data_len - snd_ctrl.playingpos);
+         snd_ctrl.playingpos += sample_size;
+
+         /* fill the first mixing buffer with original sample */
+         memcpy(premix_first_buffer,sample_ptr,sample_size);
+
+
+         /* adjust volume of actual sound sample */
+         if (snd_ctrl.volume != PSND_MAX_VOLUME)
+           for(i=0;i<sample_size;i++)
+             premix_first_buffer[i] =
+               (snd_ctrl.volume * (int)premix_first_buffer[i])
+                 >> PSND_MAX_VOLUME_BITS;
+
+         for(i=0;i<sample_size;i++)
+           playing_buffer[i] =
+             linear_to_ulaw(((int)premix_first_buffer[i]) << 8);
+
+         if (snd_ctrl.playingpos >= snd_ctrl.data_len)
+           playing_sounds = 0;
+
+         /* finally play the sound fragment */
+         write(audio.device_fd,playing_buffer,sample_size);
+
+         delay.tv_sec = 0;
+         delay.tv_usec = ((sample_size*10*wait_percent)/(sample_rate))*1000;
+       }
+       close(audio.device_fd);
+      }
+    }
+
+#endif /* !AUDIO_STREAMING_DSP */
+
+  }
+
+#endif /* PLATFORM_UNIX */
+
+}
+
+#if defined(PLATFORM_MSDOS)
+static 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);
+}
+#endif /* PLATFORM_MSDOS */
+
+#if !defined(PLATFORM_WIN32)
+static void SoundServer_InsertNewSound(struct SoundControl snd_ctrl)
+{
+  int i, k;
+
+  /* if playlist is full, remove oldest sound */
+  if (playing_sounds==MAX_SOUNDS_PLAYING)
+  {
+    int longest=0, longest_nr=0;
+
+    for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+    {
+#if !defined(PLATFORM_MSDOS)
+      int actual = 100 * playlist[i].playingpos / playlist[i].data_len;
+#else
+      int actual = playlist[i].playingpos;
+#endif
+
+      if (!playlist[i].loop && actual>longest)
+      {
+       longest=actual;
+       longest_nr=i;
+      }
+    }
+#if defined(PLATFORM_MSDOS)
+    voice_set_volume(playlist[longest_nr].voice, 0);
+    deallocate_voice(playlist[longest_nr].voice);
+#endif
+    playlist[longest_nr] = emptySoundControl;
+    playing_sounds--;
+  }
+
+  /* check if sound is already being played (and how often) */
+  for(k=0,i=0;i<MAX_SOUNDS_PLAYING;i++)
+  {
+    if (playlist[i].nr == snd_ctrl.nr)
+      k++;
+  }
+
+  /* restart loop sounds only if they are just fading out */
+  if (k>=1 && snd_ctrl.loop)
+  {
+    for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+    {
+      if (playlist[i].nr == snd_ctrl.nr && playlist[i].fade_sound)
+      {
+       playlist[i].fade_sound = FALSE;
+       playlist[i].volume = PSND_MAX_VOLUME;
+#if defined(PLATFORM_MSDOS)
+        playlist[i].loop = PSND_LOOP;
+        voice_stop_volumeramp(playlist[i].voice);
+        voice_ramp_volume(playlist[i].voice, playlist[i].volume, 1000);
+#endif
+      }
+    }
+    return;
+  }
+
+  /* don't play sound more than n times simultaneously (with n == 2 for now) */
+  if (k>=2)
+  {
+    int longest=0, longest_nr=0;
+
+    /* look for oldest equal sound */
+    for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+    {
+      int actual;
+
+      if (!playlist[i].active || playlist[i].nr != snd_ctrl.nr)
+       continue;
+
+#if !defined(PLATFORM_MSDOS)
+      actual = 100 * playlist[i].playingpos / playlist[i].data_len;
+#else
+      actual = playlist[i].playingpos;
+#endif
+      if (actual>=longest)
+      {
+       longest=actual;
+       longest_nr=i;
+      }
+    }
+
+#if defined(PLATFORM_MSDOS)
+    voice_set_volume(playlist[longest_nr].voice, 0);
+    deallocate_voice(playlist[longest_nr].voice);
+#endif
+    playlist[longest_nr] = emptySoundControl;
+    playing_sounds--;
+  }
+
+  /* neuen Sound in Liste packen */
+  for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+  {
+    if (!playlist[i].active)
+    {
+      playlist[i] = snd_ctrl;
+      playing_sounds++;
+
+#if defined(PLATFORM_MSDOS)
+      playlist[i].voice = allocate_voice(Sound[snd_ctrl.nr].sample_ptr);
+      if(snd_ctrl.loop)
+        voice_set_playmode(playlist[i].voice, PLAYMODE_LOOP);
+      voice_set_volume(playlist[i].voice, snd_ctrl.volume);
+      voice_set_pan(playlist[i].voice, snd_ctrl.stereo);
+      voice_start(playlist[i].voice);       
+#endif
+      break;
+    }
+  }
+}
+#endif /* !PLATFORM_WIN32 */
+
+/*
+void SoundServer_FadeSound(int nr)
+{
+  int i;
+
+  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 = TRUE;
+}
+*/
+
+#if !defined(PLATFORM_WIN32)
+#if defined(PLATFORM_MSDOS)
+static void SoundServer_StopSound(int nr)
+{
+  int i;
+
+  if (!playing_sounds)
+    return;
+
+  for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+    if (playlist[i].nr == nr)
+    {
+#if defined(PLATFORM_MSDOS)
+      voice_set_volume(playlist[i].voice, 0);
+      deallocate_voice(playlist[i].voice);
+#endif
+      playlist[i] = emptySoundControl;
+      playing_sounds--;
+    }
+
+#if !defined(PLATFORM_MSDOS)
+  if (!playing_sounds)
+    close(audio.device_fd);
+#endif
+}
+
+static void SoundServer_StopAllSounds()
+{
+  int i;
+
+  for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+  {
+#if defined(PLATFORM_MSDOS)
+    voice_set_volume(playlist[i].voice, 0);
+    deallocate_voice(playlist[i].voice);
+#endif
+    playlist[i]=emptySoundControl;
+  }
+  playing_sounds = 0;
+
+#if !defined(PLATFORM_MSDOS)
+  close(audio.device_fd);
+#endif
+}
+#endif /* PLATFORM_MSDOS */
+#endif /* !PLATFORM_WIN32 */
+
+#if defined(PLATFORM_HPUX)
+static void HPUX_Audio_Control()
+{
+  struct audio_describe ainfo;
+  int audio_ctl;
+
+  audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
+  if (audio_ctl == -1)
+    Error(ERR_EXIT_SOUND_SERVER, "cannot open /dev/audioCtl - no sounds");
+
+  if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
+    Error(ERR_EXIT_SOUND_SERVER, "no audio info - no sounds");
+
+  if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
+    Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available - no sounds");
+
+  ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
+  ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
+
+  close(audio_ctl);
+}
+#endif /* PLATFORM_HPUX */
+
+#if defined(PLATFORM_UNIX) && !defined(AUDIO_STREAMING_DSP)
+
+/* these two are stolen from "sox"... :) */
+
+/*
+** This routine converts from linear to ulaw.
+**
+** Craig Reese: IDA/Supercomputing Research Center
+** Joe Campbell: Department of Defense
+** 29 September 1989
+**
+** References:
+** 1) CCITT Recommendation G.711  (very difficult to follow)
+** 2) "A New Digital Technique for Implementation of Any
+**     Continuous PCM Companding Law," Villeret, Michel,
+**     et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
+**     1973, pg. 11.12-11.17
+** 3) MIL-STD-188-113,"Interoperability and Performance Standards
+**     for Analog-to_Digital Conversion Techniques,"
+**     17 February 1987
+**
+** Input: Signed 16 bit linear sample
+** Output: 8 bit ulaw sample
+*/
+
+#define ZEROTRAP    /* turn on the trap as per the MIL-STD */
+#define BIAS 0x84   /* define the add-in bias for 16 bit samples */
+#define CLIP 32635
+
+static unsigned char linear_to_ulaw(int sample)
+{
+  static int exp_lut[256] =
+  {
+    0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
+    4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+    5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+    5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
+    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
+    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
+    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
+  };
+
+  int sign, exponent, mantissa;
+  unsigned char ulawbyte;
+
+  /* Get the sample into sign-magnitude. */
+  sign = (sample >> 8) & 0x80;         /* set aside the sign */
+  if (sign != 0)
+    sample = -sample;                  /* get magnitude */
+  if (sample > CLIP)
+    sample = CLIP;                     /* clip the magnitude */
+
+  /* Convert from 16 bit linear to ulaw. */
+  sample = sample + BIAS;
+  exponent = exp_lut[( sample >> 7 ) & 0xFF];
+  mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
+  ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
+#ifdef ZEROTRAP
+  if (ulawbyte == 0)
+    ulawbyte = 0x02;                   /* optional CCITT trap */
+#endif
+
+  return(ulawbyte);
+}
+
+/*
+** This routine converts from ulaw to 16 bit linear.
+**
+** Craig Reese: IDA/Supercomputing Research Center
+** 29 September 1989
+**
+** References:
+** 1) CCITT Recommendation G.711  (very difficult to follow)
+** 2) MIL-STD-188-113,"Interoperability and Performance Standards
+**     for Analog-to_Digital Conversion Techniques,"
+**     17 February 1987
+**
+** Input: 8 bit ulaw sample
+** Output: signed 16 bit linear sample
+*/
+
+static int ulaw_to_linear(unsigned char ulawbyte)
+{
+  static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
+  int sign, exponent, mantissa, sample;
+
+  ulawbyte = ~ ulawbyte;
+  sign = ( ulawbyte & 0x80 );
+  exponent = ( ulawbyte >> 4 ) & 0x07;
+  mantissa = ulawbyte & 0x0F;
+  sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
+  if (sign != 0)
+    sample = -sample;
+
+  return(sample);
+}
+#endif /* PLATFORM_UNIX && !AUDIO_STREAMING_DSP */
+
+/*** THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS ***/
+
+/*===========================================================================*/
+
+/*** THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS ***/
+
+#define CHUNK_ID_LEN            4       /* IFF style chunk id length */
+#define WAV_HEADER_SIZE                20      /* size of WAV file header */
+
+boolean LoadSound(struct SampleInfo *snd_info)
+{
+  char filename[256];
+  char *sound_ext = "wav";
+#if !defined(TARGET_SDL)
+#if !defined(PLATFORM_MSDOS)
+  byte sound_header_buffer[WAV_HEADER_SIZE];
+  char chunk[CHUNK_ID_LEN + 1];
+  int chunk_length, dummy;
+  FILE *file;
+  int i;
+#endif
+#endif
+
+  sprintf(filename, "%s/%s/%s.%s",
+         options.ro_base_directory, SOUNDS_DIRECTORY,
+         snd_info->name, sound_ext);
+
+#if defined(TARGET_SDL)
+
+  snd_info->mix_chunk = Mix_LoadWAV(filename);
+  if (snd_info->mix_chunk == NULL)
+  {
+    Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
+    return FALSE;
+  }
+
+#else /* !TARGET_SDL */
+
+#if !defined(PLATFORM_MSDOS)
+
+  if ((file = fopen(filename, "r")) == NULL)
+  {
+    Error(ERR_WARN, "cannot open sound file '%s' - no sounds", filename);
+    return FALSE;
+  }
+
+  /* read chunk "RIFF" */
+  getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_LITTLE_ENDIAN);
+  if (strcmp(chunk, "RIFF") != 0)
+  {
+    Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
+    fclose(file);
+    return FALSE;
+  }
+
+  /* read chunk "WAVE" */
+  getFileChunk(file, chunk, &dummy, BYTE_ORDER_LITTLE_ENDIAN);
+  if (strcmp(chunk, "WAVE") != 0)
+  {
+    Error(ERR_WARN, "missing 'WAVE' chunk of sound file '%s'", filename);
+    fclose(file);
+    return FALSE;
+  }
+
+  /* read header information */
+  for (i=0; i<WAV_HEADER_SIZE; i++)
+    sound_header_buffer[i] = fgetc(file);
+
+  /* read chunk "data" */
+  getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_LITTLE_ENDIAN);
+  if (strcmp(chunk, "data") != 0)
+  {
+    Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
+    fclose(file);
+    return FALSE;
+  }
+
+  snd_info->data_len = chunk_length;
+  snd_info->data_ptr = checked_malloc(snd_info->data_len);
+
+  /* read sound data */
+  if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
+      snd_info->data_len)
+  {
+    Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
+    fclose(file);
+    return FALSE;
+  }
+
+  fclose(file);
+
+  for (i=0; i<snd_info->data_len; i++)
+    snd_info->data_ptr[i] = snd_info->data_ptr[i] ^ 0x80;
+
+#else /* PLATFORM_MSDOS */
+
+  snd_info->sample_ptr = load_sample(filename);
+  if (!snd_info->sample_ptr)
+  {
+    Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
+    return FALSE;
+  }
+
+#endif /* PLATFORM_MSDOS */
+#endif /* !TARGET_SDL */
+
+  return TRUE;
+}
+
+void PlaySound(int nr)
+{
+  PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_NO_LOOP);
+}
+
+void PlaySoundStereo(int nr, int stereo)
+{
+  PlaySoundExt(nr, PSND_MAX_VOLUME, stereo, PSND_NO_LOOP);
+}
+
+void PlaySoundLoop(int nr)
+{
+  PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_LOOP);
+}
+
+void PlaySoundExt(int nr, int volume, int stereo, boolean loop)
+{
+  struct SoundControl snd_ctrl = emptySoundControl;
+
+  if (!audio.sound_available || !setup.sound)
+    return;
+
+  if (volume<PSND_MIN_VOLUME)
+    volume = PSND_MIN_VOLUME;
+  else if (volume>PSND_MAX_VOLUME)
+    volume = PSND_MAX_VOLUME;
+
+  if (stereo<PSND_MAX_LEFT)
+    stereo = PSND_MAX_LEFT;
+  else if (stereo>PSND_MAX_RIGHT)
+    stereo = PSND_MAX_RIGHT;
+
+  snd_ctrl.nr          = nr;
+  snd_ctrl.volume      = volume;
+  snd_ctrl.stereo      = stereo;
+  snd_ctrl.loop                = loop;
+  snd_ctrl.active      = TRUE;
+  snd_ctrl.data_ptr    = Sound[nr].data_ptr;
+  snd_ctrl.data_len    = Sound[nr].data_len;
+
+#if defined(TARGET_SDL)
+
+  Mix_Volume(-1, SDL_MIX_MAXVOLUME / 4);
+  Mix_VolumeMusic(SDL_MIX_MAXVOLUME / 4);
+
+  Mix_PlayChannel(-1, Sound[nr].mix_chunk, (loop ? -1 : 0));
+
+#else
+#if !defined(PLATFORM_MSDOS)
+  if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
+  {
+    Error(ERR_WARN, "cannot pipe to child process - no sounds");
+    audio.sound_available = FALSE;
+    return;
+  }
+#else
+  sound_handler(snd_ctrl);
+#endif
+#endif
+}
+
+void FadeSound(int nr)
+{
+  StopSoundExt(nr, SSND_FADE_SOUND);
+}
+
+void FadeSounds()
+{
+  StopSoundExt(-1, SSND_FADE_ALL_SOUNDS);
+}
+
+void StopSound(int nr)
+{
+  StopSoundExt(nr, SSND_STOP_SOUND);
+}
+
+void StopSounds()
+{
+  StopSoundExt(-1, SSND_STOP_ALL_SOUNDS);
+}
+
+void StopSoundExt(int nr, int method)
+{
+  struct SoundControl snd_ctrl = emptySoundControl;
+
+  if (!audio.sound_available)
+    return;
+
+  if (SSND_FADING(method))
+    snd_ctrl.fade_sound = TRUE;
+
+  if (SSND_ALL(method))
+    snd_ctrl.stop_all_sounds = TRUE;
+  else
+  {
+    snd_ctrl.nr = nr;
+    snd_ctrl.stop_sound = TRUE;
+  }
+
+#if defined(TARGET_SDL)
+
+  if (SSND_FADING(method))
+  {
+    Mix_FadeOutChannel(-1, 1000);
+    Mix_FadeOutMusic(1000);
+  }
+  else
+  {
+    Mix_HaltChannel(-1);
+    Mix_HaltMusic();
+  }
+
+#else
+#if !defined(PLATFORM_MSDOS)
+  if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
+  {
+    Error(ERR_WARN, "cannot pipe to child process - no sounds");
+    audio.sound_available = FALSE;
+    return;
+  }
+#else
+  sound_handler(snd_ctrl);
+#endif
+#endif
+}
+
+void FreeSounds(int num_sounds)
+{
+  int i;
+
+  if (!audio.sound_available)
+    return;
+
+  for(i=0; i<num_sounds; i++)
+#if !defined(PLATFORM_MSDOS)
+    free(Sound[i].data_ptr);
+#else
+    destroy_sample(Sound[i].sample_ptr);
+#endif
+}
+
+/*** THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS ***/
diff --git a/src/libgame/sound.h b/src/libgame/sound.h
new file mode 100644 (file)
index 0000000..199ef75
--- /dev/null
@@ -0,0 +1,167 @@
+/***********************************************************
+*  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                *
+*----------------------------------------------------------*
+*  sound.c                                                 *
+***********************************************************/
+
+#ifndef SOUND_H
+#define SOUND_H
+
+#include <sys/ioctl.h>
+#include <math.h>
+
+#define SND_BLOCKSIZE 4096
+
+#if defined(PLATFORM_LINUX)
+#include <linux/soundcard.h>
+#elif defined(PLATFORM_FREEBSD)
+#include <machine/soundcard.h>
+#elif defined(PLATFORM_HPUX)
+#include <sys/audio.h>
+#undef  SND_BLOCKSIZE
+#define SND_BLOCKSIZE 32768
+#endif
+
+#include "libgame.h"
+
+#if defined(PLATFORM_LINUX) || defined(PLATFORM_FREEBSD) || defined(VOXWARE)
+#define AUDIO_STREAMING_DSP
+#endif
+
+#if !defined(PLATFORM_MSDOS)
+#define MAX_SOUNDS_PLAYING     16
+#else
+#define MAX_SOUNDS_PLAYING     8
+#endif
+
+/* some values for PlaySound(), StopSound() and friends */
+#if !defined(PLATFORM_MSDOS)
+#define PSND_SILENCE           0
+#define PSND_MAX_VOLUME_BITS   7
+#define PSND_MIN_VOLUME                0
+#define PSND_MAX_VOLUME                (1 << PSND_MAX_VOLUME_BITS)
+#define PSND_NO_LOOP           0
+#define PSND_LOOP              1
+#define PSND_MIDDLE            0
+#define PSND_MAX_STEREO_BITS   7
+#define PSND_MAX_STEREO                (1 << PSND_MAX_STEREO_BITS)
+#define PSND_MAX_LEFT          (-PSND_MAX_STEREO)
+#define PSND_MAX_RIGHT         (+PSND_MAX_STEREO)
+#define PSND_MAX_LEFT2RIGHT_BITS (PSND_MAX_STEREO_BITS+1)
+#define PSND_MAX_LEFT2RIGHT    (1 << PSND_MAX_LEFT2RIGHT_BITS)
+#else
+#define PSND_SILENCE           0
+#define PSND_MIN_VOLUME                0
+#define PSND_MAX_VOLUME                255
+#define PSND_NO_LOOP           0
+#define PSND_LOOP              1
+#define PSND_MAX_LEFT          0
+#define PSND_MAX_RIGHT         255
+#define PSND_MIDDLE            128
+#endif
+
+#define SSND_FADE_SOUND                (1<<0)
+#define SSND_FADE_ALL_SOUNDS   (1<<1)
+#define SSND_FADING(x)         (x & (SSND_FADE_SOUND | SSND_FADE_ALL_SOUNDS))
+#define SSND_STOP_SOUND                (1<<2)
+#define SSND_STOP_ALL_SOUNDS   (1<<3)
+#define SSND_STOPPING(x)       (x & (SSND_STOP_SOUND | SSND_STOP_ALL_SOUNDS))
+#define SSND_ALL(x)            (x&(SSND_FADE_ALL_SOUNDS|SSND_STOP_ALL_SOUNDS))
+
+/* settings for sound path, sound device, etc. */
+#ifndef SND_PATH
+#define SND_PATH       "./sounds"
+#endif
+
+#define DEVICENAME_DSP         "/dev/dsp"
+#define DEVICENAME_AUDIO       "/dev/audio"
+#define DEVICENAME_AUDIOCTL    "/dev/audioCtl"
+
+#if 0
+#if defined(AUDIO_STREAMING_DSP)
+#define AUDIO_DEVICE           DEVICENAME_DSP
+#else
+#define AUDIO_DEVICE   DEVICENAME_AUDIO
+#endif
+#endif
+
+struct SoundHeader_SUN
+{
+  unsigned long magic;
+  unsigned long hdr_size;
+  unsigned long data_size;
+  unsigned long encoding;
+  unsigned long sample_rate;
+  unsigned long channels;
+};
+
+struct SoundHeader_8SVX
+{
+  char magic_FORM[4];
+  unsigned long chunk_size;
+  char magic_8SVX[4];
+};
+
+struct SampleInfo
+{ 
+  char *name;
+  byte *data_ptr;
+  long data_len;
+
+#if defined(PLATFORM_MSDOS)
+  SAMPLE *sample_ptr;
+#endif
+
+#if defined(TARGET_SDL)
+  Mix_Chunk *mix_chunk;
+#endif
+};
+
+struct SoundControl
+{
+  int nr;
+  int volume;
+  int stereo;
+  boolean active;
+  boolean loop;
+  boolean fade_sound;
+  boolean stop_sound;
+  boolean stop_all_sounds;
+  int playingtime;
+  long playingpos;
+  long data_len;
+  byte *data_ptr;
+
+#if defined(PLATFORM_MSDOS)
+  int voice;
+#endif
+};
+
+/* general sound functions */
+void UnixOpenAudio(struct AudioSystemInfo *);
+void UnixCloseAudio(struct AudioSystemInfo *);
+
+/* sound server functions */ 
+void SoundServer(void);
+
+/* sound client functions */
+boolean LoadSound(struct SampleInfo *);
+void PlaySound(int);
+void PlaySoundStereo(int, int);
+void PlaySoundLoop(int);
+void PlaySoundExt(int, int, int, boolean);
+void FadeSound(int);
+void FadeSounds(void);
+void StopSound(int);
+void StopSounds(void);
+void StopSoundExt(int, int);
+void FreeSounds(int);
+
+#endif
diff --git a/src/libgame/system.c b/src/libgame/system.c
new file mode 100644 (file)
index 0000000..5a55f1c
--- /dev/null
@@ -0,0 +1,387 @@
+/***********************************************************
+*  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             *
+*----------------------------------------------------------*
+*  system.c                                                *
+***********************************************************/
+
+#include "libgame.h"
+
+
+/* ========================================================================= */
+/* internal variables                                                        */
+/* ========================================================================= */
+
+Display        *display;
+Visual        *visual;
+int            screen;
+Colormap       cmap;
+
+DrawWindow     window = None;
+GC             gc;
+
+int            FrameCounter;
+
+
+/* ========================================================================= */
+/* exported variables                                                        */
+/* ========================================================================= */
+
+struct VideoSystemInfo video;
+struct AudioSystemInfo audio;
+struct OptionInfo      options;
+
+
+/* ========================================================================= */
+/* video functions                                                           */
+/* ========================================================================= */
+
+inline void InitBufferedDisplay(DrawBuffer *backbuffer, DrawWindow *window)
+{
+  video.fullscreen_available = FULLSCREEN_STATUS;
+  video.fullscreen_enabled = FALSE;
+
+#ifdef TARGET_SDL
+  SDLInitBufferedDisplay(backbuffer, window);
+#else
+  X11InitBufferedDisplay(backbuffer, window);
+#endif
+}
+
+inline int GetDisplayDepth(void)
+{
+#ifdef TARGET_SDL
+  return SDL_GetVideoSurface()->format->BitsPerPixel;
+#else
+  return XDefaultDepth(display, screen);
+#endif
+}
+
+inline Bitmap CreateBitmap(int width, int height, int depth)
+{
+  int real_depth = (depth == DEFAULT_DEPTH ? GetDisplayDepth() : depth);
+
+#ifdef TARGET_SDL
+  SDL_Surface *surface_tmp, *surface_native;
+
+  if ((surface_tmp = SDL_CreateRGBSurface(SURFACE_FLAGS, width, height,
+                                         real_depth, 0, 0, 0, 0))
+      == NULL)
+    Error(ERR_EXIT, "SDL_CreateRGBSurface() failed: %s", SDL_GetError());
+
+  if ((surface_native = SDL_DisplayFormat(surface_tmp)) == NULL)
+    Error(ERR_EXIT, "SDL_DisplayFormat() failed: %s", SDL_GetError());
+
+  SDL_FreeSurface(surface_tmp);
+
+  return surface_native;
+#else
+  Pixmap pixmap;
+
+  if (!(pixmap = XCreatePixmap(display, window, width, height, real_depth)))
+    Error(ERR_EXIT, "cannot create pixmap");
+
+  return pixmap;
+#endif
+}
+
+inline void FreeBitmap(Bitmap bitmap)
+{
+#ifdef TARGET_SDL
+  SDL_FreeSurface(bitmap);
+#else
+  XFreePixmap(display, bitmap);
+#endif
+}
+
+inline void ClearRectangle(Bitmap bitmap, int x, int y, int width, int height)
+{
+#ifdef TARGET_SDL
+  SDLFillRectangle(bitmap, x, y, width, height, 0x000000);
+#else
+  XFillRectangle(display, bitmap, gc, x, y, width, height);
+#endif
+}
+
+inline void BlitBitmap(Bitmap src_bitmap, Bitmap dst_bitmap,
+                      int src_x, int src_y,
+                      int width, int height,
+                      int dst_x, int dst_y)
+{
+#ifdef TARGET_SDL
+  SDLCopyArea(src_bitmap, dst_bitmap,
+             src_x, src_y, width, height, dst_x, dst_y);
+#else
+  XCopyArea(display, src_bitmap, dst_bitmap, gc,
+           src_x, src_y, width, height, dst_x, dst_y);
+#endif
+}
+
+#ifndef TARGET_SDL
+static GC last_clip_gc = 0;    /* needed for XCopyArea() through clip mask */
+#endif
+
+inline void SetClipMask(GC clip_gc, Pixmap clip_pixmap)
+{
+#ifndef TARGET_SDL
+  XSetClipMask(display, clip_gc, clip_pixmap);
+  last_clip_gc = clip_gc;
+#endif
+}
+
+inline void SetClipOrigin(GC clip_gc, int clip_x, int clip_y)
+{
+#ifndef TARGET_SDL
+  XSetClipOrigin(display, clip_gc, clip_x, clip_y);
+  last_clip_gc = clip_gc;
+#endif
+}
+
+inline void BlitBitmapMasked(Bitmap src_bitmap, Bitmap dst_bitmap,
+                            int src_x, int src_y,
+                            int width, int height,
+                            int dst_x, int dst_y)
+{
+#ifdef TARGET_SDL
+  SDLCopyArea(src_bitmap, dst_bitmap,
+             src_x, src_y, width, height, dst_x, dst_y);
+#else
+  XCopyArea(display, src_bitmap, dst_bitmap, last_clip_gc,
+           src_x, src_y, width, height, dst_x, dst_y);
+#endif
+}
+
+inline void DrawSimpleWhiteLine(Bitmap bitmap, int from_x, int from_y,
+                               int to_x, int to_y)
+{
+#ifdef TARGET_SDL
+  SDLDrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, 0xffffff);
+#else
+  XSetForeground(display, gc, WhitePixel(display, screen));
+  XDrawLine(display, bitmap, gc, from_x, from_y, to_x, to_y);
+  XSetForeground(display, gc, BlackPixel(display, screen));
+#endif
+}
+
+/* execute all pending screen drawing operations */
+inline void FlushDisplay(void)
+{
+#ifndef TARGET_SDL
+  XFlush(display);
+#endif
+}
+
+/* execute and wait for all pending screen drawing operations */
+inline void SyncDisplay(void)
+{
+#ifndef TARGET_SDL
+  XSync(display, FALSE);
+#endif
+}
+
+inline void KeyboardAutoRepeatOn(void)
+{
+#ifdef TARGET_SDL
+  SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY / 2,
+                     SDL_DEFAULT_REPEAT_INTERVAL / 2);
+  SDL_EnableUNICODE(1);
+#else
+  XAutoRepeatOn(display);
+#endif
+}
+
+inline void KeyboardAutoRepeatOff(void)
+{
+#ifdef TARGET_SDL
+  SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL);
+  SDL_EnableUNICODE(0);
+#else
+  XAutoRepeatOff(display);
+#endif
+}
+
+inline boolean PointerInWindow(DrawWindow window)
+{
+#ifdef TARGET_SDL
+  return TRUE;
+#else
+  DrawWindow root, child;
+  int root_x, root_y;
+  unsigned int mask;
+  int win_x, win_y;
+
+  /* if XQueryPointer() returns False, the pointer
+     is not on the same screen as the specified window */
+  return XQueryPointer(display, window, &root, &child, &root_x, &root_y,
+                      &win_x, &win_y, &mask);
+#endif
+}
+
+inline boolean SetVideoMode(boolean fullscreen)
+{
+#ifdef TARGET_SDL
+  return SDLSetVideoMode(&backbuffer, fullscreen);
+#else
+  boolean success = TRUE;
+
+  if (fullscreen && video.fullscreen_available)
+  {
+    Error(ERR_WARN, "fullscreen not available in X11 version");
+
+    /* display error message only once */
+    video.fullscreen_available = FALSE;
+
+    success = FALSE;
+  }
+
+  return success;
+#endif
+}
+
+inline boolean ChangeVideoModeIfNeeded(boolean fullscreen)
+{
+#ifdef TARGET_SDL
+  if ((fullscreen && !video.fullscreen_enabled && video.fullscreen_available)||
+      (!fullscreen && video.fullscreen_enabled))
+    fullscreen = SetVideoMode(fullscreen_wanted);
+#endif
+
+  return fullscreen;
+}
+
+
+/* ========================================================================= */
+/* audio functions                                                           */
+/* ========================================================================= */
+
+inline boolean OpenAudio(struct AudioSystemInfo *audio)
+{
+  audio->sound_available = FALSE;
+  audio->loops_available = FALSE;
+  audio->soundserver_pipe[0] = audio->soundserver_pipe[1] = 0;
+  audio->soundserver_pid = 0;
+  audio->device_name = NULL;
+  audio->device_fd = 0;
+
+#if defined(TARGET_SDL)
+  if (SDLOpenAudio())
+  {
+    audio->sound_available = TRUE;
+    audio->loops_available = TRUE;
+  }
+#elif defined(PLATFORM_MSDOS)
+  if (MSDOSOpenAudio())
+  {
+    audio->sound_available = TRUE;
+    audio->loops_available = TRUE;
+  }
+#elif defined(PLATFORM_UNIX)
+  UnixOpenAudio(audio);
+#endif
+
+  return audio->sound_available;
+}
+
+inline void CloseAudio(struct AudioSystemInfo *audio)
+{
+#if defined(TARGET_SDL)
+  SDLCloseAudio();
+#elif defined(PLATFORM_MSDOS)
+  MSDOSCloseAudio();
+#elif defined(PLATFORM_UNIX)
+  UnixCloseAudio(audio);
+#endif
+
+  audio->sound_available = FALSE;
+  audio->loops_available = FALSE;
+}
+
+
+/* ========================================================================= */
+/* event functions                                                           */
+/* ========================================================================= */
+
+inline void InitEventFilter(EventFilter filter_function)
+{
+#ifdef TARGET_SDL
+  /* set event filter to filter out certain events */
+  SDL_SetEventFilter(filter_function);
+#endif
+}
+
+inline boolean PendingEvent(void)
+{
+#ifdef TARGET_SDL
+  return (SDL_PollEvent(NULL) ? TRUE : FALSE);
+#else
+  return (XPending(display) ? TRUE : FALSE);
+#endif
+}
+
+inline void NextEvent(Event *event)
+{
+#ifdef TARGET_SDL
+  SDL_WaitEvent(event);
+#else
+  XNextEvent(display, event);
+#endif
+}
+
+inline Key GetEventKey(KeyEvent *event, boolean with_modifiers)
+{
+#ifdef TARGET_SDL
+#if 0
+  printf("unicode == '%d', sym == '%d', mod == '0x%04x'\n",
+        (int)event->keysym.unicode,
+        (int)event->keysym.sym,
+        (int)SDL_GetModState());
+#endif
+
+  if (with_modifiers && event->keysym.unicode != 0)
+    return event->keysym.unicode;
+  else
+    return event->keysym.sym;
+#else
+#if 0
+  printf("with modifiers == '0x%04x', without modifiers == '0x%04x'\n",
+        (int)XLookupKeysym(event, event->state),
+        (int)XLookupKeysym(event, 0));
+#endif
+
+  if (with_modifiers)
+    return XLookupKeysym(event, event->state);
+  else
+    return XLookupKeysym(event, 0);
+#endif
+}
+
+inline boolean CheckCloseWindowEvent(ClientMessageEvent *event)
+{
+  if (event->type != EVENT_CLIENTMESSAGE)
+    return FALSE;
+
+#if defined(TARGET_SDL)
+  return TRUE;         /* the only possible message here is SDL_QUIT */
+#elif defined(PLATFORM_UNIX)
+  if ((event->window == window) &&
+      (event->data.l[0] == XInternAtom(display, "WM_DELETE_WINDOW", FALSE)))
+    return TRUE;
+#endif
+
+  return FALSE;
+}
+
+
+inline void dummy(void)
+{
+#ifdef TARGET_SDL
+#else
+#endif
+}
diff --git a/src/libgame/system.h b/src/libgame/system.h
new file mode 100644 (file)
index 0000000..fe805c8
--- /dev/null
@@ -0,0 +1,128 @@
+/***********************************************************
+*  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             *
+*----------------------------------------------------------*
+*  system.h                                                *
+***********************************************************/
+
+#ifndef SYSTEM_H
+#define SYSTEM_H
+
+#include "libgame.h"
+
+#if defined(PLATFORM_MSDOS)
+#include "msdos.h"
+#endif
+
+#if defined(TARGET_SDL)
+#include "sdl.h"
+#elif defined(TARGET_X11)
+#include "x11.h"
+#endif
+
+
+/* contant definitions */
+
+#define DEFAULT_DEPTH                  0
+
+#define FULLSCREEN_NOT_AVAILABLE       FALSE
+#define FULLSCREEN_AVAILABLE           TRUE
+
+
+/* type definitions */
+
+typedef int (*EventFilter)(const Event *);
+
+
+/* structure definitions */
+
+struct VideoSystemInfo
+{
+  boolean fullscreen_available;
+  boolean fullscreen_enabled;
+};
+
+struct AudioSystemInfo
+{
+  boolean sound_available;
+  boolean loops_available;
+  int soundserver_pipe[2];
+  int soundserver_pid;
+  char *device_name;
+  int device_fd;
+};
+
+struct OptionInfo
+{
+  char *display_name;
+  char *server_host;
+  int server_port;
+  char *ro_base_directory;
+  char *rw_base_directory;
+  char *level_directory;
+  boolean serveronly;
+  boolean network;
+  boolean verbose;
+  boolean debug;
+};
+
+
+/* ========================================================================= */
+/* exported variables                                                        */
+/* ========================================================================= */
+
+extern struct VideoSystemInfo  video;
+extern struct AudioSystemInfo  audio;
+extern struct OptionInfo       options;
+
+
+/* declarations of internal variables */
+
+extern Display        *display;
+extern Visual         *visual;
+extern int             screen;
+extern Colormap                cmap;
+
+extern DrawWindow      window;
+extern GC              gc;
+
+extern int             FrameCounter;
+
+
+/* function definitions */
+
+inline void InitBufferedDisplay(DrawBuffer *, DrawWindow *);
+inline int GetDisplayDepth(void);
+inline Bitmap CreateBitmap(int, int, int);
+inline void FreeBitmap(Bitmap);
+inline void ClearRectangle(Bitmap, int, int, int, int);
+inline void BlitBitmap(Bitmap, Bitmap, int, int, int, int, int, int);
+inline void SetClipMask(GC, Pixmap);
+inline void SetClipOrigin(GC, int, int);
+inline void BlitBitmapMasked(Bitmap, Bitmap, int, int, int, int, int, int);
+inline void DrawSimpleWhiteLine(Bitmap, int, int, int, int);
+inline void FlushDisplay(void);
+inline void SyncDisplay(void);
+inline void KeyboardAutoRepeatOn(void);
+inline void KeyboardAutoRepeatOff(void);
+inline boolean PointerInWindow(DrawWindow);
+inline boolean SetVideoMode(boolean);
+inline boolean ChangeVideoModeIfNeeded(boolean);
+
+inline boolean OpenAudio(struct AudioSystemInfo *);
+inline void CloseAudio(struct AudioSystemInfo *);
+
+inline void InitEventFilter(EventFilter);
+inline boolean PendingEvent(void);
+inline void NextEvent(Event *event);
+inline Key GetEventKey(KeyEvent *, boolean);
+inline boolean CheckCloseWindowEvent(ClientMessageEvent *);
+
+#endif /* SYSTEM_H */
diff --git a/src/libgame/text.c b/src/libgame/text.c
new file mode 100644 (file)
index 0000000..28f88c5
--- /dev/null
@@ -0,0 +1,156 @@
+/***********************************************************
+*  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                *
+*----------------------------------------------------------*
+*  text.c                                                  *
+***********************************************************/
+
+#include <stdarg.h>
+
+#include "libgame.h"
+
+#include "main_TMP.h"
+
+int getFontWidth(int font_size, int font_type)
+{
+  return (font_size == FS_BIG ? FONT1_XSIZE :
+         font_size == FS_MEDIUM ? FONT6_XSIZE :
+         font_type == FC_SPECIAL1 ? FONT3_XSIZE :
+         font_type == FC_SPECIAL2 ? FONT4_XSIZE :
+         font_type == FC_SPECIAL3 ? FONT5_XSIZE :
+         FONT2_XSIZE);
+}
+
+int getFontHeight(int font_size, int font_type)
+{
+  return (font_size == FS_BIG ? FONT1_YSIZE :
+         font_size == FS_MEDIUM ? FONT6_YSIZE :
+         font_type == FC_SPECIAL1 ? FONT3_YSIZE :
+         font_type == FC_SPECIAL2 ? FONT4_YSIZE :
+         font_type == FC_SPECIAL3 ? FONT5_YSIZE :
+         FONT2_YSIZE);
+}
+
+void DrawInitText(char *text, int ypos, int color)
+{
+  if (window && pix[PIX_SMALLFONT])
+  {
+    ClearRectangle(window, 0, ypos, WIN_XSIZE, FONT2_YSIZE);
+    DrawTextExt(window, gc, (WIN_XSIZE - strlen(text) * FONT2_XSIZE)/2,
+               ypos, text, FS_SMALL, color);
+    FlushDisplay();
+  }
+}
+
+void DrawTextFCentered(int y, int font_type, char *format, ...)
+{
+  char buffer[FULL_SXSIZE / FONT5_XSIZE + 10];
+  int font_width = getFontWidth(FS_SMALL, font_type);
+  va_list ap;
+
+  va_start(ap, format);
+  vsprintf(buffer, format, ap);
+  va_end(ap);
+
+  DrawText(SX + (SXSIZE - strlen(buffer) * font_width) / 2, SY + y,
+          buffer, FS_SMALL, font_type);
+}
+
+void DrawTextF(int x, int y, int font_type, char *format, ...)
+{
+  char buffer[FULL_SXSIZE / FONT5_XSIZE + 10];
+  va_list ap;
+
+  va_start(ap, format);
+  vsprintf(buffer, format, ap);
+  va_end(ap);
+
+  DrawText(SX + x, SY + y, buffer, FS_SMALL, font_type);
+}
+
+void DrawText(int x, int y, char *text, int font_size, int font_type)
+{
+  DrawTextExt(drawto, gc, x, y, text, font_size, font_type);
+
+  if (x < DX)
+    redraw_mask |= REDRAW_FIELD;
+  else if (y < VY)
+    redraw_mask |= REDRAW_DOOR_1;
+}
+
+void DrawTextExt(DrawBuffer d, GC gc, int x, int y,
+                char *text, int font_size, int font_type)
+{
+  int font_width, font_height, font_start;
+  int font_bitmap;
+  boolean print_inverse = FALSE;
+
+  if (font_size != FS_SMALL && font_size != FS_BIG && font_size != FS_MEDIUM)
+    font_size = FS_SMALL;
+  if (font_type < FC_RED || font_type > FC_SPECIAL3)
+    font_type = FC_RED;
+
+  font_width = getFontWidth(font_size, font_type);
+  font_height = getFontHeight(font_size, font_type);
+
+  font_bitmap = (font_size == FS_BIG ? PIX_BIGFONT :
+                font_size == FS_MEDIUM ? PIX_MEDIUMFONT :
+                PIX_SMALLFONT);
+  font_start = (font_type * (font_size == FS_BIG ? FONT1_YSIZE :
+                            font_size == FS_MEDIUM ? FONT6_YSIZE :
+                            FONT2_YSIZE) *
+               FONT_LINES_PER_FONT);
+
+  if (font_type == FC_SPECIAL3)
+    font_start += (FONT4_YSIZE - FONT2_YSIZE) * FONT_LINES_PER_FONT;
+
+  while (*text)
+  {
+    char c = *text++;
+
+    if (c == '~' && font_size == FS_SMALL)
+    {
+      print_inverse = TRUE;
+      continue;
+    }
+
+    if (c >= 'a' && c <= 'z')
+      c = 'A' + (c - 'a');
+    else if (c == 'ä' || c == 'Ä')
+      c = 91;
+    else if (c == 'ö' || c == 'Ö')
+      c = 92;
+    else if (c == 'ü' || c == 'Ü')
+      c = 93;
+
+    if (c >= 32 && c <= 95)
+    {
+      int src_x = ((c - 32) % FONT_CHARS_PER_LINE) * font_width;
+      int src_y = ((c - 32) / FONT_CHARS_PER_LINE) * font_height + font_start;
+      int dest_x = x, dest_y = y;
+
+      if (print_inverse)
+      {
+       BlitBitmap(pix[font_bitmap], d,
+                  FONT_CHARS_PER_LINE * font_width,
+                  3 * font_height + font_start,
+                  font_width, font_height, x, y);
+
+       SetClipOrigin(clip_gc[font_bitmap], dest_x - src_x, dest_y - src_y);
+       BlitBitmapMasked(pix_masked[font_bitmap], d,
+                        0, 0, font_width, font_height, dest_x, dest_y);
+      }
+      else
+       BlitBitmap(pix[font_bitmap], d,
+                  src_x, src_y, font_width, font_height, dest_x, dest_y);
+    }
+
+    x += font_width;
+  }
+}
diff --git a/src/libgame/text.h b/src/libgame/text.h
new file mode 100644 (file)
index 0000000..57fa7e1
--- /dev/null
@@ -0,0 +1,27 @@
+/***********************************************************
+*  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                *
+*----------------------------------------------------------*
+*  text.h                                                  *
+***********************************************************/
+
+#ifndef TEXT_H
+#define TEXT_H
+
+#include "libgame.h"
+
+int getFontWidth(int, int);
+int getFontHeight(int, int);
+void DrawInitText(char *, int, int);
+void DrawTextF(int, int, int, char *, ...);
+void DrawTextFCentered(int, int, char *, ...);
+void DrawText(int, int, char *, int, int);
+void DrawTextExt(DrawBuffer, GC, int, int, char *, int, int);
+
+#endif /* TEXT_H */
diff --git a/src/libgame/types.h b/src/libgame/types.h
new file mode 100644 (file)
index 0000000..e4aad2a
--- /dev/null
@@ -0,0 +1,25 @@
+/***********************************************************
+*  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                *
+*----------------------------------------------------------*
+*  types.h                                                 *
+***********************************************************/
+
+#ifndef TYPES_H
+#define TYPES_H
+
+typedef unsigned char boolean;
+typedef unsigned char byte;
+
+#ifndef FALSE
+#define FALSE          0
+#define TRUE           (!FALSE)
+#endif
+
+#endif /* TYPES_H */
diff --git a/src/libgame/x11.c b/src/libgame/x11.c
new file mode 100644 (file)
index 0000000..9de89c9
--- /dev/null
@@ -0,0 +1,207 @@
+/***********************************************************
+*  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             *
+*----------------------------------------------------------*
+*  x11.c                                                   *
+***********************************************************/
+
+#include "libgame.h"
+
+#if defined(TARGET_X11)
+
+#include "main_TMP.h"
+
+struct IconFileInfo
+{
+  char *picture_filename;
+  char *picturemask_filename;
+};
+
+static void X11InitDisplay()
+{
+#if !defined(PLATFORM_MSDOS)
+  XVisualInfo vinfo_template, *vinfo;
+  int num_visuals;
+#endif
+  unsigned int depth;
+
+  /* connect to X server */
+  if (!(display = XOpenDisplay(options.display_name)))
+    Error(ERR_EXIT, "cannot connect to X server %s",
+         XDisplayName(options.display_name));
+
+  screen = DefaultScreen(display);
+  visual = DefaultVisual(display, screen);
+  depth  = DefaultDepth(display, screen);
+  cmap   = DefaultColormap(display, screen);
+
+#if !defined(PLATFORM_MSDOS)
+  /* look for good enough visual */
+  vinfo_template.screen = screen;
+  vinfo_template.class = (depth == 8 ? PseudoColor : TrueColor);
+  vinfo_template.depth = depth;
+  if ((vinfo = XGetVisualInfo(display, VisualScreenMask | VisualClassMask |
+                             VisualDepthMask, &vinfo_template, &num_visuals)))
+  {
+    visual = vinfo->visual;
+    XFree((void *)vinfo);
+  }
+
+  /* got appropriate visual? */
+  if (depth < 8)
+  {
+    printf("Sorry, displays with less than 8 bits per pixel not supported.\n");
+    exit(-1);
+  }
+  else if ((depth ==8 && visual->class != PseudoColor) ||
+          (depth > 8 && visual->class != TrueColor &&
+           visual->class != DirectColor))
+  {
+    printf("Sorry, cannot get appropriate visual.\n");
+    exit(-1);
+  }
+#endif /* !PLATFORM_MSDOS */
+}
+
+static DrawWindow X11InitWindow()
+{
+  Window window;
+  unsigned int border_width = 4;
+  XGCValues gc_values;
+  unsigned long gc_valuemask;
+#if !defined(PLATFORM_MSDOS)
+  XTextProperty windowName, iconName;
+  Pixmap icon_pixmap, iconmask_pixmap;
+  unsigned int icon_width, icon_height;
+  int icon_hot_x, icon_hot_y;
+  char icon_filename[256];
+  XSizeHints size_hints;
+  XWMHints wm_hints;
+  XClassHint class_hints;
+  char *window_name = WINDOW_TITLE_STRING;
+  char *icon_name = WINDOW_TITLE_STRING;
+  long window_event_mask;
+  Atom proto_atom = None, delete_atom = None;
+#endif
+  int screen_width, screen_height;
+  int win_xpos = WIN_XPOS, win_ypos = WIN_YPOS;
+  unsigned long pen_fg = WhitePixel(display,screen);
+  unsigned long pen_bg = BlackPixel(display,screen);
+  const int width = WIN_XSIZE, height = WIN_YSIZE;
+
+#if !defined(PLATFORM_MSDOS)
+  static struct IconFileInfo icon_pic =
+  {
+    "rocks_icon.xbm",
+    "rocks_iconmask.xbm"
+  };
+#endif
+
+  screen_width = XDisplayWidth(display, screen);
+  screen_height = XDisplayHeight(display, screen);
+
+  win_xpos = (screen_width - width) / 2;
+  win_ypos = (screen_height - height) / 2;
+
+  window = XCreateSimpleWindow(display, RootWindow(display, screen),
+                              win_xpos, win_ypos, width, height, border_width,
+                              pen_fg, pen_bg);
+
+#if !defined(PLATFORM_MSDOS)
+  proto_atom = XInternAtom(display, "WM_PROTOCOLS", FALSE);
+  delete_atom = XInternAtom(display, "WM_DELETE_WINDOW", FALSE);
+  if ((proto_atom != None) && (delete_atom != None))
+    XChangeProperty(display, window, proto_atom, XA_ATOM, 32,
+                   PropModePrepend, (unsigned char *) &delete_atom, 1);
+
+  sprintf(icon_filename, "%s/%s/%s",
+         options.ro_base_directory, GRAPHICS_DIRECTORY,
+         icon_pic.picture_filename);
+  XReadBitmapFile(display,window,icon_filename,
+                 &icon_width,&icon_height,
+                 &icon_pixmap,&icon_hot_x,&icon_hot_y);
+  if (!icon_pixmap)
+    Error(ERR_EXIT, "cannot read icon bitmap file '%s'", icon_filename);
+
+  sprintf(icon_filename, "%s/%s/%s",
+         options.ro_base_directory, GRAPHICS_DIRECTORY,
+         icon_pic.picturemask_filename);
+  XReadBitmapFile(display,window,icon_filename,
+                 &icon_width,&icon_height,
+                 &iconmask_pixmap,&icon_hot_x,&icon_hot_y);
+  if (!iconmask_pixmap)
+    Error(ERR_EXIT, "cannot read icon bitmap file '%s'", icon_filename);
+
+  size_hints.width  = size_hints.min_width  = size_hints.max_width  = width;
+  size_hints.height = size_hints.min_height = size_hints.max_height = height;
+  size_hints.flags = PSize | PMinSize | PMaxSize;
+
+  if (win_xpos || win_ypos)
+  {
+    size_hints.x = win_xpos;
+    size_hints.y = win_ypos;
+    size_hints.flags |= PPosition;
+  }
+
+  if (!XStringListToTextProperty(&window_name, 1, &windowName))
+    Error(ERR_EXIT, "structure allocation for windowName failed");
+
+  if (!XStringListToTextProperty(&icon_name, 1, &iconName))
+    Error(ERR_EXIT, "structure allocation for iconName failed");
+
+  wm_hints.initial_state = NormalState;
+  wm_hints.input = True;
+  wm_hints.icon_pixmap = icon_pixmap;
+  wm_hints.icon_mask = iconmask_pixmap;
+  wm_hints.flags = StateHint | IconPixmapHint | IconMaskHint | InputHint;
+
+  class_hints.res_name = program_name;
+  class_hints.res_class = "Rocks'n'Diamonds";
+
+  XSetWMProperties(display, window, &windowName, &iconName, 
+                  NULL, 0, &size_hints, &wm_hints, 
+                  &class_hints);
+
+  XFree(windowName.value);
+  XFree(iconName.value);
+
+  /* Select event types wanted */
+  window_event_mask =
+    ExposureMask | StructureNotifyMask | FocusChangeMask |
+    ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
+    PointerMotionHintMask | KeyPressMask | KeyReleaseMask;
+
+  XSelectInput(display, window, window_event_mask);
+#endif
+
+  /* create GC for drawing with window depth and background color (black) */
+  gc_values.graphics_exposures = False;
+  gc_values.foreground = pen_bg;
+  gc_values.background = pen_bg;
+  gc_valuemask = GCGraphicsExposures | GCForeground | GCBackground;
+  gc = XCreateGC(display, window, gc_valuemask, &gc_values);
+
+  return window;
+}
+
+inline void X11InitBufferedDisplay(DrawBuffer *backbuffer, DrawWindow *window)
+{
+  X11InitDisplay();
+  *window = X11InitWindow();
+
+  XMapWindow(display, *window);
+  FlushDisplay();
+
+  /* create additional buffer for double-buffering */
+  *backbuffer = CreateBitmap(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH);
+  pix[PIX_DB_BACK] = *backbuffer;      /* 'backbuffer' is off-screen buffer */
+}
+
+#endif /* TARGET_X11 */
diff --git a/src/libgame/x11.h b/src/libgame/x11.h
new file mode 100644 (file)
index 0000000..ca1247c
--- /dev/null
@@ -0,0 +1,273 @@
+/***********************************************************
+*  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             *
+*----------------------------------------------------------*
+*  x11.h                                                   *
+***********************************************************/
+
+#ifndef X11_H
+#define X11_H
+
+#if !defined(PLATFORM_MSDOS)
+#define XK_MISCELLANY
+#define XK_LATIN1
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xatom.h>
+#include <X11/Xos.h>
+#include <X11/Intrinsic.h>
+#include <X11/keysymdef.h>
+#endif
+
+
+/* system dependent definitions */
+
+/* MS-DOS header file also defines "TARGET_STRING" */
+#ifndef TARGET_STRING
+#define TARGET_STRING          "X11"
+#endif
+
+#define FULLSCREEN_STATUS      FULLSCREEN_NOT_AVAILABLE
+
+
+/* X11 type definitions */
+
+typedef Pixmap                 Bitmap;
+typedef Window                 DrawWindow;
+typedef Drawable               DrawBuffer;
+
+typedef KeySym                 Key;
+
+typedef XEvent                 Event;
+typedef XButtonEvent           ButtonEvent;
+typedef XMotionEvent           MotionEvent;
+typedef XKeyEvent              KeyEvent;
+typedef XExposeEvent           ExposeEvent;
+typedef XFocusChangeEvent      FocusChangeEvent;
+typedef XClientMessageEvent    ClientMessageEvent;
+
+
+/* X11 symbol definitions */
+
+#define EVENT_BUTTONPRESS      ButtonPress
+#define EVENT_BUTTONRELEASE    ButtonRelease
+#define EVENT_MOTIONNOTIFY     MotionNotify
+#define EVENT_KEYPRESS         KeyPress
+#define EVENT_KEYRELEASE       KeyRelease
+#define EVENT_EXPOSE           Expose
+#define EVENT_FOCUSIN          FocusIn
+#define EVENT_FOCUSOUT         FocusOut
+#define EVENT_CLIENTMESSAGE    ClientMessage
+#define EVENT_MAPNOTIFY                MapNotify
+#define EVENT_UNMAPNOTIFY      UnmapNotify
+
+#define KSYM_UNDEFINED         XK_VoidSymbol
+
+#define KSYM_Return            XK_Return
+#define KSYM_Escape            XK_Escape
+
+#define KSYM_Left              XK_Left
+#define KSYM_Right             XK_Right
+#define KSYM_Up                        XK_Up
+#define KSYM_Down              XK_Down
+
+#ifdef XK_KP_Left
+#define KSYM_KP_Left           XK_KP_Left
+#define KSYM_KP_Right          XK_KP_Right
+#define KSYM_KP_Up             XK_KP_Up
+#define KSYM_KP_Down           XK_KP_Down
+#endif
+
+#ifdef XK_KP_Enter
+#define KSYM_KP_Enter          XK_KP_Enter
+#define KSYM_KP_Add            XK_KP_Add
+#define KSYM_KP_Subtract       XK_KP_Subtract
+#define KSYM_KP_Multiply       XK_KP_Multiply
+#define KSYM_KP_Divide         XK_KP_Divide
+#define KSYM_KP_Separator      XK_KP_Separator
+#endif
+
+#define KSYM_Shift_L           XK_Shift_L
+#define KSYM_Shift_R           XK_Shift_R
+#define KSYM_Control_L         XK_Control_L
+#define KSYM_Control_R         XK_Control_R
+#define KSYM_Meta_L            XK_Meta_L
+#define KSYM_Meta_R            XK_Meta_R
+#define KSYM_Alt_L             XK_Alt_L
+#define KSYM_Alt_R             XK_Alt_R
+#define KSYM_Super_L           XK_Super_L
+#define KSYM_Super_R           XK_Super_R
+#define KSYM_Mode_switch       XK_Mode_switch
+#define KSYM_Multi_key         XK_Multi_key
+
+#define KSYM_BackSpace         XK_BackSpace
+#define KSYM_Delete            XK_Delete
+#define KSYM_Insert            XK_Insert
+#define KSYM_Tab               XK_Tab
+#define KSYM_Home              XK_Home
+#define KSYM_End               XK_End
+#define KSYM_Page_Up           XK_Page_Up
+#define KSYM_Page_Down         XK_Page_Down
+#define KSYM_Menu              XK_Menu
+
+#define KSYM_space             XK_space
+#define KSYM_exclam            XK_exclam
+#define KSYM_quotedbl          XK_quotedbl
+#define KSYM_numbersign                XK_numbersign
+#define KSYM_dollar            XK_dollar
+#define KSYM_percent           XK_percent
+#define KSYM_ampersand         XK_ampersand
+#define KSYM_apostrophe                XK_apostrophe
+#define KSYM_parenleft         XK_parenleft
+#define KSYM_parenright                XK_parenright
+#define KSYM_asterisk          XK_asterisk
+#define KSYM_plus              XK_plus
+#define KSYM_comma             XK_comma
+#define KSYM_minus             XK_minus
+#define KSYM_period            XK_period
+#define KSYM_slash             XK_slash
+
+#define KSYM_colon             XK_colon
+#define KSYM_semicolon         XK_semicolon
+#define KSYM_less              XK_less
+#define KSYM_equal             XK_equal
+#define KSYM_greater           XK_greater
+#define KSYM_question          XK_question
+#define KSYM_at                        XK_at
+
+#define KSYM_bracketleft       XK_bracketleft
+#define KSYM_backslash         XK_backslash
+#define KSYM_bracketright      XK_bracketright
+#define KSYM_asciicircum       XK_asciicircum
+#define KSYM_underscore                XK_underscore
+#define KSYM_grave             XK_grave
+
+#define KSYM_quoteleft         XK_quoteleft
+#define KSYM_braceleft         XK_braceleft
+#define KSYM_bar               XK_bar
+#define KSYM_braceright                XK_braceright
+#define KSYM_asciitilde                XK_asciitilde
+
+#define KSYM_Adiaeresis                XK_Adiaeresis
+#define KSYM_Odiaeresis                XK_Odiaeresis
+#define KSYM_Udiaeresis                XK_Udiaeresis
+#define KSYM_adiaeresis                XK_adiaeresis
+#define KSYM_odiaeresis                XK_odiaeresis
+#define KSYM_udiaeresis                XK_udiaeresis
+#define KSYM_ssharp            XK_ssharp
+
+#define KSYM_A                 XK_A
+#define KSYM_B                 XK_B
+#define KSYM_C                 XK_C
+#define KSYM_D                 XK_D
+#define KSYM_E                 XK_E
+#define KSYM_F                 XK_F
+#define KSYM_G                 XK_G
+#define KSYM_H                 XK_H
+#define KSYM_I                 XK_I
+#define KSYM_J                 XK_J
+#define KSYM_K                 XK_K
+#define KSYM_L                 XK_L
+#define KSYM_M                 XK_M
+#define KSYM_N                 XK_N
+#define KSYM_O                 XK_O
+#define KSYM_P                 XK_P
+#define KSYM_Q                 XK_Q
+#define KSYM_R                 XK_R
+#define KSYM_S                 XK_S
+#define KSYM_T                 XK_T
+#define KSYM_U                 XK_U
+#define KSYM_V                 XK_V
+#define KSYM_W                 XK_W
+#define KSYM_X                 XK_X
+#define KSYM_Y                 XK_Y
+#define KSYM_Z                 XK_Z
+
+#define KSYM_a                 XK_a
+#define KSYM_b                 XK_b
+#define KSYM_c                 XK_c
+#define KSYM_d                 XK_d
+#define KSYM_e                 XK_e
+#define KSYM_f                 XK_f
+#define KSYM_g                 XK_g
+#define KSYM_h                 XK_h
+#define KSYM_i                 XK_i
+#define KSYM_j                 XK_j
+#define KSYM_k                 XK_k
+#define KSYM_l                 XK_l
+#define KSYM_m                 XK_m
+#define KSYM_n                 XK_n
+#define KSYM_o                 XK_o
+#define KSYM_p                 XK_p
+#define KSYM_q                 XK_q
+#define KSYM_r                 XK_r
+#define KSYM_s                 XK_s
+#define KSYM_t                 XK_t
+#define KSYM_u                 XK_u
+#define KSYM_v                 XK_v
+#define KSYM_w                 XK_w
+#define KSYM_x                 XK_x
+#define KSYM_y                 XK_y
+#define KSYM_z                 XK_z
+
+#define KSYM_0                 XK_0
+#define KSYM_1                 XK_1
+#define KSYM_2                 XK_2
+#define KSYM_3                 XK_3
+#define KSYM_4                 XK_4
+#define KSYM_5                 XK_5
+#define KSYM_6                 XK_6
+#define KSYM_7                 XK_7
+#define KSYM_8                 XK_8
+#define KSYM_9                 XK_9
+
+#define KSYM_KP_0              XK_KP_0
+#define KSYM_KP_1              XK_KP_1
+#define KSYM_KP_2              XK_KP_2
+#define KSYM_KP_3              XK_KP_3
+#define KSYM_KP_4              XK_KP_4
+#define KSYM_KP_5              XK_KP_5
+#define KSYM_KP_6              XK_KP_6
+#define KSYM_KP_7              XK_KP_7
+#define KSYM_KP_8              XK_KP_8
+#define KSYM_KP_9              XK_KP_9
+
+#define KSYM_F1                        XK_F1
+#define KSYM_F2                        XK_F2
+#define KSYM_F3                        XK_F3
+#define KSYM_F4                        XK_F4
+#define KSYM_F5                        XK_F5
+#define KSYM_F6                        XK_F6
+#define KSYM_F7                        XK_F7
+#define KSYM_F8                        XK_F8
+#define KSYM_F9                        XK_F9
+#define KSYM_F10               XK_F10
+#define KSYM_F11               XK_F11
+#define KSYM_F12               XK_F12
+#define KSYM_F13               XK_F13
+#define KSYM_F14               XK_F14
+#define KSYM_F15               XK_F15
+#define KSYM_F16               XK_F16
+#define KSYM_F17               XK_F17
+#define KSYM_F18               XK_F18
+#define KSYM_F19               XK_F19
+#define KSYM_F20               XK_F20
+#define KSYM_F21               XK_F21
+#define KSYM_F22               XK_F22
+#define KSYM_F23               XK_F23
+#define KSYM_F24               XK_F24
+
+
+/* X11 function definitions */
+
+inline void X11InitBufferedDisplay(DrawBuffer *, DrawWindow *);
+
+#endif /* X11_H */
index 8d927cb1c28759eb725737a7f759adf47c1d33a6..8bf9e7757d705e3ebbebdc74edc8e9d144bb721c 100644 (file)
 *  main.c                                                  *
 ***********************************************************/
 
+#include "libgame/libgame.h"
+
 #include "main.h"
 #include "init.h"
 #include "game.h"
 #include "events.h"
-#include "sound.h"
 #include "joystick.h"
-#include "misc.h"
 
 #if defined(PLATFORM_MSDOS)
 #include <fcntl.h>
 #endif
 
-Display        *display;
-Visual        *visual;
-int            screen;
+#if 0
 DrawWindow     window = None;
-GC             gc, clip_gc[NUM_BITMAPS], tile_clip_gc;
+GC             gc;
+#endif
+
+GC             clip_gc[NUM_BITMAPS], tile_clip_gc;
 Bitmap         pix[NUM_BITMAPS];
 Bitmap         pix_masked[NUM_BITMAPS], tile_masked[NUM_TILES];
 Pixmap         clipmask[NUM_BITMAPS], tile_clipmask[NUM_TILES];
 
 DrawBuffer     drawto, drawto_field, backbuffer, fieldbuffer;
+#if 0
 Colormap       cmap;
+#endif
 
+#if 0
 char          *sound_device_name = AUDIO_DEVICE;
+#endif
 
 int            joystick_device = 0;
 char          *joystick_device_name[MAX_PLAYERS] =
@@ -56,8 +61,11 @@ boolean              motion_status = FALSE;
 int            key_joystick_mapping = 0;
 int            global_joystick_status = JOYSTICK_STATUS;
 int            joystick_status = JOYSTICK_STATUS;
+
+#if 0
 boolean                fullscreen_available = FULLSCREEN_STATUS;
 boolean                fullscreen_enabled = FALSE;
+#endif
 
 boolean                redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
 int            redraw_x1 = 0, redraw_y1 = 0;
@@ -94,7 +102,12 @@ int         SBX_Left, SBX_Right;
 int            SBY_Upper, SBY_Lower;
 int            ZX,ZY, ExitX,ExitY;
 int            AllPlayersGone;
-int            FrameCounter, TimeFrames, TimePlayed, TimeLeft;
+
+#if 0
+int            FrameCounter;
+#endif
+
+int            TimeFrames, TimePlayed, TimeLeft;
 
 boolean                network_player_action_received = FALSE;
 
@@ -104,10 +117,19 @@ struct PlayerInfo stored_player[MAX_PLAYERS], *local_player = NULL;
 struct HiScore         highscore[MAX_SCORE_ENTRIES];
 struct SampleInfo      Sound[NUM_SOUNDS];
 struct TapeInfo                tape;
+
+#if 0
 struct OptionInfo      options;
+#endif
+
 struct SetupInfo       setup;
 struct GameInfo                game;
+
+#if 0
+struct VideoSystemInfo video;
 struct AudioSystemInfo audio;
+#endif
+
 struct GlobalInfo      global;
 
 /* data needed for playing sounds */
index 3eb6993d96e3e9c793281ec37825221306681587..c53408b2bebfa103bed1c7581fa3d6f4c00f2b89 100644 (file)
 #define DEBUG_TIMING   0
 #endif
 
-typedef unsigned char boolean;
-typedef unsigned char byte;
-
-#include "system.h"
+#if 0
+#include "libgame/libgame.h"
+#endif
 
 #ifndef FALSE
 #define FALSE          0
@@ -238,20 +237,6 @@ struct HiScore
   int Score;
 };
 
-struct OptionInfo
-{
-  char *display_name;
-  char *server_host;
-  int server_port;
-  char *ro_base_directory;
-  char *rw_base_directory;
-  char *level_directory;
-  boolean serveronly;
-  boolean network;
-  boolean verbose;
-  boolean debug;
-};
-
 struct SetupJoystickInfo
 {
   char *device_name;
@@ -451,19 +436,24 @@ struct GlobalInfo
   int fps_slowdown_factor;
 };
 
-extern Display        *display;
-extern Visual         *visual;
-extern int             screen;
+#if 0
 extern DrawWindow      window;
-extern GC              gc, clip_gc[], tile_clip_gc;
+extern GC              gc;
+#endif
+
+extern GC              clip_gc[], tile_clip_gc;
 extern Bitmap          pix[];
 extern Bitmap          pix_masked[], tile_masked[];
 extern Pixmap          clipmask[], tile_clipmask[];
 
 extern DrawBuffer      drawto, drawto_field, backbuffer, fieldbuffer;
+#if 0
 extern Colormap                cmap;
+#endif
 
+#if 0
 extern char           *sound_device_name;
+#endif
 
 extern int             joystick_device;
 extern char           *joystick_device_name[];
@@ -477,8 +467,11 @@ extern int         button_status;
 extern boolean         motion_status;
 extern int             key_joystick_mapping;
 extern int             global_joystick_status, joystick_status;
+
+#if 0
 extern boolean         fullscreen_available;
 extern boolean         fullscreen_enabled;
+#endif
 
 extern boolean         redraw[MAX_BUF_XSIZE][MAX_BUF_YSIZE];
 extern int             redraw_x1, redraw_y1;
@@ -514,7 +507,12 @@ extern int         SBX_Left, SBX_Right;
 extern int             SBY_Upper, SBY_Lower;
 extern int             ZX,ZY, ExitX,ExitY;
 extern int             AllPlayersGone;
-extern int             FrameCounter, TimeFrames, TimePlayed, TimeLeft;
+
+#if 0
+extern int             FrameCounter;
+#endif
+
+extern int             TimeFrames, TimePlayed, TimeLeft;
 extern boolean         SiebAktiv;
 extern int             SiebCount;
 
@@ -527,10 +525,19 @@ extern struct HiScore             highscore[];
 extern struct TapeInfo         tape;
 extern struct SampleInfo       Sound[];
 extern struct JoystickInfo     joystick[];
+
+#if 0
 extern struct OptionInfo       options;
+#endif
+
 extern struct SetupInfo                setup;
 extern struct GameInfo         game;
+
+#if 0
+extern struct VideoSystemInfo  video;
 extern struct AudioSystemInfo  audio;
+#endif
+
 extern struct GlobalInfo       global;
 
 extern char            *sound_name[];
diff --git a/src/misc.c b/src/misc.c
deleted file mode 100644 (file)
index a87a9b3..0000000
+++ /dev/null
@@ -1,1392 +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                *
-*----------------------------------------------------------*
-*  misc.c                                                  *
-***********************************************************/
-
-#include "platform.h"
-
-#include <time.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <stdarg.h>
-#include <ctype.h>
-
-#if !defined(PLATFORM_WIN32)
-#include <pwd.h>
-#include <sys/param.h>
-#endif
-
-#include "misc.h"
-#include "init.h"
-#include "tools.h"
-#include "sound.h"
-#include "random.h"
-#include "joystick.h"
-#include "files.h"
-
-#if defined(PLATFORM_MSDOS)
-volatile unsigned long counter = 0;
-
-void increment_counter()
-{
-  counter++;
-}
-
-END_OF_FUNCTION(increment_counter);
-#endif
-
-
-/* maximal allowed length of a command line option */
-#define MAX_OPTION_LEN         256
-
-#ifdef TARGET_SDL
-static unsigned long mainCounter(int mode)
-{
-  static unsigned long base_ms = 0;
-  unsigned long current_ms;
-  unsigned long counter_ms;
-
-  current_ms = SDL_GetTicks();
-
-  /* reset base time in case of counter initializing or wrap-around */
-  if (mode == INIT_COUNTER || current_ms < base_ms)
-    base_ms = current_ms;
-
-  counter_ms = current_ms - base_ms;
-
-  return counter_ms;           /* return milliseconds since last init */
-}
-
-#else /* !TARGET_SDL */
-
-#if defined(PLATFORM_UNIX)
-static unsigned long mainCounter(int mode)
-{
-  static struct timeval base_time = { 0, 0 };
-  struct timeval current_time;
-  unsigned long counter_ms;
-
-  gettimeofday(&current_time, NULL);
-
-  /* reset base time in case of counter initializing or wrap-around */
-  if (mode == INIT_COUNTER || current_time.tv_sec < base_time.tv_sec)
-    base_time = current_time;
-
-  counter_ms = (current_time.tv_sec  - base_time.tv_sec)  * 1000
-             + (current_time.tv_usec - base_time.tv_usec) / 1000;
-
-  return counter_ms;           /* return milliseconds since last init */
-}
-#endif /* PLATFORM_UNIX */
-#endif /* !TARGET_SDL */
-
-void InitCounter()             /* set counter back to zero */
-{
-#if !defined(PLATFORM_MSDOS)
-  mainCounter(INIT_COUNTER);
-#else
-  LOCK_VARIABLE(counter);
-  LOCK_FUNCTION(increment_counter);
-  install_int_ex(increment_counter, BPS_TO_TIMER(100));
-#endif
-}
-
-unsigned long Counter()        /* get milliseconds since last call of InitCounter() */
-{
-#if !defined(PLATFORM_MSDOS)
-  return mainCounter(READ_COUNTER);
-#else
-  return (counter * 10);
-#endif
-}
-
-static void sleep_milliseconds(unsigned long milliseconds_delay)
-{
-  boolean do_busy_waiting = (milliseconds_delay < 5 ? TRUE : FALSE);
-
-#if defined(PLATFORM_MSDOS)
-  /* don't use select() to perform waiting operations under DOS/Windows
-     environment; always use a busy loop for waiting instead */
-  do_busy_waiting = TRUE;
-#endif
-
-  if (do_busy_waiting)
-  {
-    /* we want to wait only a few ms -- if we assume that we have a
-       kernel timer resolution of 10 ms, we would wait far to long;
-       therefore it's better to do a short interval of busy waiting
-       to get our sleeping time more accurate */
-
-    unsigned long base_counter = Counter(), actual_counter = Counter();
-
-    while (actual_counter < base_counter + milliseconds_delay &&
-          actual_counter >= base_counter)
-      actual_counter = Counter();
-  }
-  else
-  {
-#if defined(TARGET_SDL)
-    SDL_Delay(milliseconds_delay);
-#else
-    struct timeval delay;
-
-    delay.tv_sec  = milliseconds_delay / 1000;
-    delay.tv_usec = 1000 * (milliseconds_delay % 1000);
-
-    if (select(0, NULL, NULL, NULL, &delay) != 0)
-      Error(ERR_WARN, "sleep_milliseconds(): select() failed");
-#endif
-  }
-}
-
-void Delay(unsigned long delay)        /* Sleep specified number of milliseconds */
-{
-  sleep_milliseconds(delay);
-}
-
-boolean FrameReached(unsigned long *frame_counter_var,
-                    unsigned long frame_delay)
-{
-  unsigned long actual_frame_counter = FrameCounter;
-
-  if (actual_frame_counter < *frame_counter_var+frame_delay &&
-      actual_frame_counter >= *frame_counter_var)
-    return(FALSE);
-
-  *frame_counter_var = actual_frame_counter;
-  return(TRUE);
-}
-
-boolean DelayReached(unsigned long *counter_var,
-                    unsigned long delay)
-{
-  unsigned long actual_counter = Counter();
-
-  if (actual_counter < *counter_var + delay &&
-      actual_counter >= *counter_var)
-    return(FALSE);
-
-  *counter_var = actual_counter;
-  return(TRUE);
-}
-
-void WaitUntilDelayReached(unsigned long *counter_var, unsigned long delay)
-{
-  unsigned long actual_counter;
-
-  while(1)
-  {
-    actual_counter = Counter();
-
-    if (actual_counter < *counter_var + delay &&
-       actual_counter >= *counter_var)
-      sleep_milliseconds((*counter_var + delay - actual_counter) / 2);
-    else
-      break;
-  }
-
-  *counter_var = actual_counter;
-}
-
-/* int2str() returns a number converted to a string;
-   the used memory is static, but will be overwritten by later calls,
-   so if you want to save the result, copy it to a private string buffer;
-   there can be 10 local calls of int2str() without buffering the result --
-   the 11th call will then destroy the result from the first call and so on.
-*/
-
-char *int2str(int number, int size)
-{
-  static char shift_array[10][40];
-  static int shift_counter = 0;
-  char *s = shift_array[shift_counter];
-
-  shift_counter = (shift_counter + 1) % 10;
-
-  if (size > 20)
-    size = 20;
-
-  if (size)
-  {
-    sprintf(s, "                    %09d", number);
-    return &s[strlen(s) - size];
-  }
-  else
-  {
-    sprintf(s, "%d", number);
-    return s;
-  }
-}
-
-unsigned int SimpleRND(unsigned int max)
-{
-#if defined(TARGET_SDL)
-  static unsigned long root = 654321;
-  unsigned long current_ms;
-
-  current_ms = SDL_GetTicks();
-  root = root * 4253261 + current_ms;
-  return (root % max);
-#else
-  static unsigned long root = 654321;
-  struct timeval current_time;
-
-  gettimeofday(&current_time, NULL);
-  root = root * 4253261 + current_time.tv_sec + current_time.tv_usec;
-  return (root % max);
-#endif
-}
-
-#ifdef DEBUG
-static unsigned int last_RND_value = 0;
-
-unsigned int last_RND()
-{
-  return last_RND_value;
-}
-#endif
-
-unsigned int RND(unsigned int max)
-{
-#ifdef DEBUG
-  return (last_RND_value = random_linux_libc() % max);
-#else
-  return (random_linux_libc() % max);
-#endif
-}
-
-unsigned int InitRND(long seed)
-{
-#if defined(TARGET_SDL)
-  unsigned long current_ms;
-
-  if (seed == NEW_RANDOMIZE)
-  {
-    current_ms = SDL_GetTicks();
-    srandom_linux_libc((unsigned int) current_ms);
-    return (unsigned int) current_ms;
-  }
-  else
-  {
-    srandom_linux_libc((unsigned int) seed);
-    return (unsigned int) seed;
-  }
-#else
-  struct timeval current_time;
-
-  if (seed == NEW_RANDOMIZE)
-  {
-    gettimeofday(&current_time, NULL);
-    srandom_linux_libc((unsigned int) current_time.tv_usec);
-    return (unsigned int) current_time.tv_usec;
-  }
-  else
-  {
-    srandom_linux_libc((unsigned int) seed);
-    return (unsigned int) seed;
-  }
-#endif
-}
-
-char *getLoginName()
-{
-#if defined(PLATFORM_WIN32)
-  return ANONYMOUS_NAME;
-#else
-  struct passwd *pwd;
-
-  if ((pwd = getpwuid(getuid())) == NULL)
-    return ANONYMOUS_NAME;
-  else
-    return pwd->pw_name;
-#endif
-}
-
-char *getRealName()
-{
-#if defined(PLATFORM_UNIX)
-  struct passwd *pwd;
-
-  if ((pwd = getpwuid(getuid())) == NULL || strlen(pwd->pw_gecos) == 0)
-    return ANONYMOUS_NAME;
-  else
-  {
-    static char real_name[1024];
-    char *from_ptr = pwd->pw_gecos, *to_ptr = real_name;
-
-    if (strchr(pwd->pw_gecos, 'ß') == NULL)
-      return pwd->pw_gecos;
-
-    /* the user's real name contains a 'ß' character (german sharp s),
-       which has no equivalent in upper case letters (which our fonts use) */
-    while (*from_ptr != '\0' && (long)(to_ptr - real_name) < 1024 - 2)
-    {
-      if (*from_ptr != 'ß')
-       *to_ptr++ = *from_ptr++;
-      else
-      {
-       from_ptr++;
-       *to_ptr++ = 's';
-       *to_ptr++ = 's';
-      }
-    }
-    *to_ptr = '\0';
-
-    return real_name;
-  }
-#else /* !PLATFORM_UNIX */
-  return ANONYMOUS_NAME;
-#endif
-}
-
-char *getHomeDir()
-{
-#if defined(PLATFORM_UNIX)
-  static char *home_dir = NULL;
-
-  if (!home_dir)
-  {
-    if (!(home_dir = getenv("HOME")))
-    {
-      struct passwd *pwd;
-
-      if ((pwd = getpwuid(getuid())))
-       home_dir = pwd->pw_dir;
-      else
-       home_dir = ".";
-    }
-  }
-
-  return home_dir;
-#else
-  return ".";
-#endif
-}
-
-char *getPath2(char *path1, char *path2)
-{
-  char *complete_path = checked_malloc(strlen(path1) + 1 +
-                                      strlen(path2) + 1);
-
-  sprintf(complete_path, "%s/%s", path1, path2);
-  return complete_path;
-}
-
-char *getPath3(char *path1, char *path2, char *path3)
-{
-  char *complete_path = checked_malloc(strlen(path1) + 1 +
-                                      strlen(path2) + 1 +
-                                      strlen(path3) + 1);
-
-  sprintf(complete_path, "%s/%s/%s", path1, path2, path3);
-  return complete_path;
-}
-
-char *getStringCopy(char *s)
-{
-  char *s_copy;
-
-  if (s == NULL)
-    return NULL;
-
-  s_copy = checked_malloc(strlen(s) + 1);
-
-  strcpy(s_copy, s);
-  return s_copy;
-}
-
-char *getStringToLower(char *s)
-{
-  char *s_copy = checked_malloc(strlen(s) + 1);
-  char *s_ptr = s_copy;
-
-  while (*s)
-    *s_ptr++ = tolower(*s++);
-  *s_ptr = '\0';
-
-  return s_copy;
-}
-
-void MarkTileDirty(int x, int y)
-{
-  int xx = redraw_x1 + x;
-  int yy = redraw_y1 + y;
-
-  if (!redraw[xx][yy])
-    redraw_tiles++;
-
-  redraw[xx][yy] = TRUE;
-  redraw_mask |= REDRAW_TILES;
-}
-
-void SetBorderElement()
-{
-  int x, y;
-
-  BorderElement = EL_LEERRAUM;
-
-  for(y=0; y<lev_fieldy && BorderElement == EL_LEERRAUM; y++)
-  {
-    for(x=0; x<lev_fieldx; x++)
-    {
-      if (!IS_MASSIVE(Feld[x][y]))
-       BorderElement = EL_BETON;
-
-      if (y != 0 && y != lev_fieldy - 1 && x != lev_fieldx - 1)
-       x = lev_fieldx - 2;
-    }
-  }
-}
-
-void GetOptions(char *argv[])
-{
-  char **options_left = &argv[1];
-
-  /* initialize global program options */
-  options.display_name = NULL;
-  options.server_host = NULL;
-  options.server_port = 0;
-  options.ro_base_directory = RO_BASE_PATH;
-  options.rw_base_directory = RW_BASE_PATH;
-  options.level_directory = RO_BASE_PATH "/" LEVELS_DIRECTORY;
-  options.serveronly = FALSE;
-  options.network = FALSE;
-  options.verbose = FALSE;
-  options.debug = FALSE;
-
-  /* initialize some more global variables */
-  global.frames_per_second = 0;
-  global.fps_slowdown = FALSE;
-  global.fps_slowdown_factor = 1;
-
-  while (*options_left)
-  {
-    char option_str[MAX_OPTION_LEN];
-    char *option = options_left[0];
-    char *next_option = options_left[1];
-    char *option_arg = NULL;
-    int option_len = strlen(option);
-
-    if (option_len >= MAX_OPTION_LEN)
-      Error(ERR_EXIT_HELP, "unrecognized option '%s'", option);
-
-    strcpy(option_str, option);                        /* copy argument into buffer */
-    option = option_str;
-
-    if (strcmp(option, "--") == 0)             /* stop scanning arguments */
-      break;
-
-    if (strncmp(option, "--", 2) == 0)         /* treat '--' like '-' */
-      option++;
-
-    option_arg = strchr(option, '=');
-    if (option_arg == NULL)                    /* no '=' in option */
-      option_arg = next_option;
-    else
-    {
-      *option_arg++ = '\0';                    /* cut argument from option */
-      if (*option_arg == '\0')                 /* no argument after '=' */
-       Error(ERR_EXIT_HELP, "option '%s' has invalid argument", option_str);
-    }
-
-    option_len = strlen(option);
-
-    if (strcmp(option, "-") == 0)
-      Error(ERR_EXIT_HELP, "unrecognized option '%s'", option);
-    else if (strncmp(option, "-help", option_len) == 0)
-    {
-      printf("Usage: %s [options] [server.name [port]]\n"
-            "Options:\n"
-            "  -d, --display machine:0       X server display\n"
-            "  -b, --basepath directory      alternative base directory\n"
-            "  -l, --level directory         alternative level directory\n"
-            "  -s, --serveronly              only start network server\n"
-            "  -n, --network                 network multiplayer game\n"
-            "  -v, --verbose                 verbose mode\n",
-            program_name);
-      exit(0);
-    }
-    else if (strncmp(option, "-display", option_len) == 0)
-    {
-      if (option_arg == NULL)
-       Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str);
-
-      options.display_name = option_arg;
-      if (option_arg == next_option)
-       options_left++;
-    }
-    else if (strncmp(option, "-basepath", option_len) == 0)
-    {
-      if (option_arg == NULL)
-       Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str);
-
-      /* this should be extended to separate options for ro and rw data */
-      options.ro_base_directory = option_arg;
-      options.rw_base_directory = option_arg;
-      if (option_arg == next_option)
-       options_left++;
-
-      /* adjust path for level directory accordingly */
-      options.level_directory =
-       getPath2(options.ro_base_directory, LEVELS_DIRECTORY);
-    }
-    else if (strncmp(option, "-levels", option_len) == 0)
-    {
-      if (option_arg == NULL)
-       Error(ERR_EXIT_HELP, "option '%s' requires an argument", option_str);
-
-      options.level_directory = option_arg;
-      if (option_arg == next_option)
-       options_left++;
-    }
-    else if (strncmp(option, "-network", option_len) == 0)
-    {
-      options.network = TRUE;
-    }
-    else if (strncmp(option, "-serveronly", option_len) == 0)
-    {
-      options.serveronly = TRUE;
-    }
-    else if (strncmp(option, "-verbose", option_len) == 0)
-    {
-      options.verbose = TRUE;
-    }
-    else if (strncmp(option, "-debug", option_len) == 0)
-    {
-      options.debug = TRUE;
-    }
-    else if (*option == '-')
-    {
-      Error(ERR_EXIT_HELP, "unrecognized option '%s'", option_str);
-    }
-    else if (options.server_host == NULL)
-    {
-      options.server_host = *options_left;
-    }
-    else if (options.server_port == 0)
-    {
-      options.server_port = atoi(*options_left);
-      if (options.server_port < 1024)
-       Error(ERR_EXIT_HELP, "bad port number '%d'", options.server_port);
-    }
-    else
-      Error(ERR_EXIT_HELP, "too many arguments");
-
-    options_left++;
-  }
-}
-
-void Error(int mode, char *format, ...)
-{
-  char *process_name = "";
-  FILE *error = stderr;
-
-  /* display warnings only when running in verbose mode */
-  if (mode & ERR_WARN && !options.verbose)
-    return;
-
-#if !defined(PLATFORM_UNIX)
-  if ((error = openErrorFile()) == NULL)
-  {
-    printf("Cannot write to error output file!\n");
-    CloseAllAndExit(1);
-  }
-#endif
-
-  if (mode & ERR_SOUND_SERVER)
-    process_name = " sound server";
-  else if (mode & ERR_NETWORK_SERVER)
-    process_name = " network server";
-  else if (mode & ERR_NETWORK_CLIENT)
-    process_name = " network client **";
-
-  if (format)
-  {
-    va_list ap;
-
-    fprintf(error, "%s%s: ", program_name, process_name);
-
-    if (mode & ERR_WARN)
-      fprintf(error, "warning: ");
-
-    va_start(ap, format);
-    vfprintf(error, format, ap);
-    va_end(ap);
-  
-    fprintf(error, "\n");
-  }
-  
-  if (mode & ERR_HELP)
-    fprintf(error, "%s: Try option '--help' for more information.\n",
-           program_name);
-
-  if (mode & ERR_EXIT)
-    fprintf(error, "%s%s: aborting\n", program_name, process_name);
-
-  if (error != stderr)
-    fclose(error);
-
-  if (mode & ERR_EXIT)
-  {
-    if (mode & ERR_FROM_SERVER)
-      exit(1);                         /* child process: normal exit */
-    else
-      CloseAllAndExit(1);              /* main process: clean up stuff */
-  }
-}
-
-void *checked_malloc(unsigned long size)
-{
-  void *ptr;
-
-  ptr = malloc(size);
-
-  if (ptr == NULL)
-    Error(ERR_EXIT, "cannot allocate %d bytes -- out of memory", size);
-
-  return ptr;
-}
-
-void *checked_calloc(unsigned long size)
-{
-  void *ptr;
-
-  ptr = calloc(1, size);
-
-  if (ptr == NULL)
-    Error(ERR_EXIT, "cannot allocate %d bytes -- out of memory", size);
-
-  return ptr;
-}
-
-short getFile16BitInteger(FILE *file, int byte_order)
-{
-  if (byte_order == BYTE_ORDER_BIG_ENDIAN)
-    return ((fgetc(file) <<  8) |
-           (fgetc(file) <<  0));
-  else          /* BYTE_ORDER_LITTLE_ENDIAN */
-    return ((fgetc(file) <<  0) |
-           (fgetc(file) <<  8));
-}
-
-void putFile16BitInteger(FILE *file, short value, int byte_order)
-{
-  if (byte_order == BYTE_ORDER_BIG_ENDIAN)
-  {
-    fputc((value >>  8) & 0xff, file);
-    fputc((value >>  0) & 0xff, file);
-  }
-  else          /* BYTE_ORDER_LITTLE_ENDIAN */
-  {
-    fputc((value >>  0) & 0xff, file);
-    fputc((value >>  8) & 0xff, file);
-  }
-}
-
-int getFile32BitInteger(FILE *file, int byte_order)
-{
-  if (byte_order == BYTE_ORDER_BIG_ENDIAN)
-    return ((fgetc(file) << 24) |
-           (fgetc(file) << 16) |
-           (fgetc(file) <<  8) |
-           (fgetc(file) <<  0));
-  else          /* BYTE_ORDER_LITTLE_ENDIAN */
-    return ((fgetc(file) <<  0) |
-           (fgetc(file) <<  8) |
-           (fgetc(file) << 16) |
-           (fgetc(file) << 24));
-}
-
-void putFile32BitInteger(FILE *file, int value, int byte_order)
-{
-  if (byte_order == BYTE_ORDER_BIG_ENDIAN)
-  {
-    fputc((value >> 24) & 0xff, file);
-    fputc((value >> 16) & 0xff, file);
-    fputc((value >>  8) & 0xff, file);
-    fputc((value >>  0) & 0xff, file);
-  }
-  else          /* BYTE_ORDER_LITTLE_ENDIAN */
-  {
-    fputc((value >>  0) & 0xff, file);
-    fputc((value >>  8) & 0xff, file);
-    fputc((value >> 16) & 0xff, file);
-    fputc((value >> 24) & 0xff, file);
-  }
-}
-
-void getFileChunk(FILE *file, char *chunk_buffer, int *chunk_length,
-                 int byte_order)
-{
-  const int chunk_identifier_length = 4;
-
-  /* read chunk identifier */
-  fgets(chunk_buffer, chunk_identifier_length + 1, file);
-
-  /* read chunk length */
-  *chunk_length = getFile32BitInteger(file, byte_order);
-}
-
-void putFileChunk(FILE *file, char *chunk_name, int chunk_length,
-                 int byte_order)
-{
-  /* write chunk identifier */
-  fputs(chunk_name, file);
-
-  /* write chunk length */
-  putFile32BitInteger(file, chunk_length, byte_order);
-}
-
-#define TRANSLATE_KEYSYM_TO_KEYNAME    0
-#define TRANSLATE_KEYSYM_TO_X11KEYNAME 1
-#define TRANSLATE_X11KEYNAME_TO_KEYSYM 2
-
-void translate_keyname(Key *keysym, char **x11name, char **name, int mode)
-{
-  static struct
-  {
-    Key key;
-    char *x11name;
-    char *name;
-  } translate_key[] =
-  {
-    /* normal cursor keys */
-    { KSYM_Left,       "XK_Left",              "cursor left" },
-    { KSYM_Right,      "XK_Right",             "cursor right" },
-    { KSYM_Up,         "XK_Up",                "cursor up" },
-    { KSYM_Down,       "XK_Down",              "cursor down" },
-
-    /* keypad cursor keys */
-#ifdef KSYM_KP_Left
-    { KSYM_KP_Left,    "XK_KP_Left",           "keypad left" },
-    { KSYM_KP_Right,   "XK_KP_Right",          "keypad right" },
-    { KSYM_KP_Up,      "XK_KP_Up",             "keypad up" },
-    { KSYM_KP_Down,    "XK_KP_Down",           "keypad down" },
-#endif
-
-    /* other keypad keys */
-#ifdef KSYM_KP_Enter
-    { KSYM_KP_Enter,   "XK_KP_Enter",          "keypad enter" },
-    { KSYM_KP_Add,     "XK_KP_Add",            "keypad +" },
-    { KSYM_KP_Subtract,        "XK_KP_Subtract",       "keypad -" },
-    { KSYM_KP_Multiply,        "XK_KP_Multiply",       "keypad mltply" },
-    { KSYM_KP_Divide,  "XK_KP_Divide",         "keypad /" },
-    { KSYM_KP_Separator,"XK_KP_Separator",     "keypad ," },
-#endif
-
-    /* modifier keys */
-    { KSYM_Shift_L,    "XK_Shift_L",           "left shift" },
-    { KSYM_Shift_R,    "XK_Shift_R",           "right shift" },
-    { KSYM_Control_L,  "XK_Control_L",         "left control" },
-    { KSYM_Control_R,  "XK_Control_R",         "right control" },
-    { KSYM_Meta_L,     "XK_Meta_L",            "left meta" },
-    { KSYM_Meta_R,     "XK_Meta_R",            "right meta" },
-    { KSYM_Alt_L,      "XK_Alt_L",             "left alt" },
-    { KSYM_Alt_R,      "XK_Alt_R",             "right alt" },
-    { KSYM_Super_L,    "XK_Super_L",           "left super" },  /* Win-L */
-    { KSYM_Super_R,    "XK_Super_R",           "right super" }, /* Win-R */
-    { KSYM_Mode_switch,        "XK_Mode_switch",       "mode switch" }, /* Alt-R */
-    { KSYM_Multi_key,  "XK_Multi_key",         "multi key" },   /* Ctrl-R */
-
-    /* some special keys */
-    { KSYM_BackSpace,  "XK_BackSpace",         "backspace" },
-    { KSYM_Delete,     "XK_Delete",            "delete" },
-    { KSYM_Insert,     "XK_Insert",            "insert" },
-    { KSYM_Tab,                "XK_Tab",               "tab" },
-    { KSYM_Home,       "XK_Home",              "home" },
-    { KSYM_End,                "XK_End",               "end" },
-    { KSYM_Page_Up,    "XK_Page_Up",           "page up" },
-    { KSYM_Page_Down,  "XK_Page_Down",         "page down" },
-    { KSYM_Menu,       "XK_Menu",              "menu" },        /* Win-Menu */
-
-    /* ASCII 0x20 to 0x40 keys (except numbers) */
-    { KSYM_space,      "XK_space",             "space" },
-    { KSYM_exclam,     "XK_exclam",            "!" },
-    { KSYM_quotedbl,   "XK_quotedbl",          "\"" },
-    { KSYM_numbersign, "XK_numbersign",        "#" },
-    { KSYM_dollar,     "XK_dollar",            "$" },
-    { KSYM_percent,    "XK_percent",           "%" },
-    { KSYM_ampersand,  "XK_ampersand",         "&" },
-    { KSYM_apostrophe, "XK_apostrophe",        "'" },
-    { KSYM_parenleft,  "XK_parenleft",         "(" },
-    { KSYM_parenright, "XK_parenright",        ")" },
-    { KSYM_asterisk,   "XK_asterisk",          "*" },
-    { KSYM_plus,       "XK_plus",              "+" },
-    { KSYM_comma,      "XK_comma",             "," },
-    { KSYM_minus,      "XK_minus",             "-" },
-    { KSYM_period,     "XK_period",            "." },
-    { KSYM_slash,      "XK_slash",             "/" },
-    { KSYM_colon,      "XK_colon",             ":" },
-    { KSYM_semicolon,  "XK_semicolon",         ";" },
-    { KSYM_less,       "XK_less",              "<" },
-    { KSYM_equal,      "XK_equal",             "=" },
-    { KSYM_greater,    "XK_greater",           ">" },
-    { KSYM_question,   "XK_question",          "?" },
-    { KSYM_at,         "XK_at",                "@" },
-
-    /* more ASCII keys */
-    { KSYM_bracketleft,        "XK_bracketleft",       "[" },
-    { KSYM_backslash,  "XK_backslash",         "backslash" },
-    { KSYM_bracketright,"XK_bracketright",     "]" },
-    { KSYM_asciicircum,        "XK_asciicircum",       "circumflex" },
-    { KSYM_underscore, "XK_underscore",        "_" },
-    { KSYM_grave,      "XK_grave",             "grave" },
-    { KSYM_quoteleft,  "XK_quoteleft",         "quote left" },
-    { KSYM_braceleft,  "XK_braceleft",         "brace left" },
-    { KSYM_bar,                "XK_bar",               "bar" },
-    { KSYM_braceright, "XK_braceright",        "brace right" },
-    { KSYM_asciitilde, "XK_asciitilde",        "ascii tilde" },
-
-    /* special (non-ASCII) keys */
-    { KSYM_Adiaeresis, "XK_Adiaeresis",        "Ä" },
-    { KSYM_Odiaeresis, "XK_Odiaeresis",        "Ö" },
-    { KSYM_Udiaeresis, "XK_Udiaeresis",        "Ü" },
-    { KSYM_adiaeresis, "XK_adiaeresis",        "ä" },
-    { KSYM_odiaeresis, "XK_odiaeresis",        "ö" },
-    { KSYM_udiaeresis, "XK_udiaeresis",        "ü" },
-    { KSYM_ssharp,     "XK_ssharp",            "sharp s" },
-
-    /* end-of-array identifier */
-    { 0,                NULL,                  NULL }
-  };
-
-  int i;
-
-  if (mode == TRANSLATE_KEYSYM_TO_KEYNAME)
-  {
-    static char name_buffer[30];
-    Key key = *keysym;
-
-    if (key >= KSYM_A && key <= KSYM_Z)
-      sprintf(name_buffer, "%c", 'A' + (char)(key - KSYM_A));
-    else if (key >= KSYM_a && key <= KSYM_z)
-      sprintf(name_buffer, "%c", 'a' + (char)(key - KSYM_a));
-    else if (key >= KSYM_0 && key <= KSYM_9)
-      sprintf(name_buffer, "%c", '0' + (char)(key - KSYM_0));
-    else if (key >= KSYM_KP_0 && key <= KSYM_KP_9)
-      sprintf(name_buffer, "keypad %c", '0' + (char)(key - KSYM_KP_0));
-    else if (key >= KSYM_F1 && key <= KSYM_F24)
-      sprintf(name_buffer, "function F%d", (int)(key - KSYM_F1 + 1));
-    else if (key == KSYM_UNDEFINED)
-      strcpy(name_buffer, "(undefined)");
-    else
-    {
-      i = 0;
-
-      do
-      {
-       if (key == translate_key[i].key)
-       {
-         strcpy(name_buffer, translate_key[i].name);
-         break;
-       }
-      }
-      while (translate_key[++i].name);
-
-      if (!translate_key[i].name)
-       strcpy(name_buffer, "(unknown)");
-    }
-
-    *name = name_buffer;
-  }
-  else if (mode == TRANSLATE_KEYSYM_TO_X11KEYNAME)
-  {
-    static char name_buffer[30];
-    Key key = *keysym;
-
-    if (key >= KSYM_A && key <= KSYM_Z)
-      sprintf(name_buffer, "XK_%c", 'A' + (char)(key - KSYM_A));
-    else if (key >= KSYM_a && key <= KSYM_z)
-      sprintf(name_buffer, "XK_%c", 'a' + (char)(key - KSYM_a));
-    else if (key >= KSYM_0 && key <= KSYM_9)
-      sprintf(name_buffer, "XK_%c", '0' + (char)(key - KSYM_0));
-    else if (key >= KSYM_KP_0 && key <= KSYM_KP_9)
-      sprintf(name_buffer, "XK_KP_%c", '0' + (char)(key - KSYM_KP_0));
-    else if (key >= KSYM_F1 && key <= KSYM_F24)
-      sprintf(name_buffer, "XK_F%d", (int)(key - KSYM_F1 + 1));
-    else if (key == KSYM_UNDEFINED)
-      strcpy(name_buffer, "[undefined]");
-    else
-    {
-      i = 0;
-
-      do
-      {
-       if (key == translate_key[i].key)
-       {
-         strcpy(name_buffer, translate_key[i].x11name);
-         break;
-       }
-      }
-      while (translate_key[++i].x11name);
-
-      if (!translate_key[i].x11name)
-       sprintf(name_buffer, "0x%04lx", (unsigned long)key);
-    }
-
-    *x11name = name_buffer;
-  }
-  else if (mode == TRANSLATE_X11KEYNAME_TO_KEYSYM)
-  {
-    Key key = KSYM_UNDEFINED;
-    char *name_ptr = *x11name;
-
-    if (strncmp(name_ptr, "XK_", 3) == 0 && strlen(name_ptr) == 4)
-    {
-      char c = name_ptr[3];
-
-      if (c >= 'A' && c <= 'Z')
-       key = KSYM_A + (Key)(c - 'A');
-      else if (c >= 'a' && c <= 'z')
-       key = KSYM_a + (Key)(c - 'a');
-      else if (c >= '0' && c <= '9')
-       key = KSYM_0 + (Key)(c - '0');
-    }
-    else if (strncmp(name_ptr, "XK_KP_", 6) == 0 && strlen(name_ptr) == 7)
-    {
-      char c = name_ptr[6];
-
-      if (c >= '0' && c <= '9')
-       key = KSYM_0 + (Key)(c - '0');
-    }
-    else if (strncmp(name_ptr, "XK_F", 4) == 0 && strlen(name_ptr) <= 6)
-    {
-      char c1 = name_ptr[4];
-      char c2 = name_ptr[5];
-      int d = 0;
-
-      if ((c1 >= '0' && c1 <= '9') &&
-         ((c2 >= '0' && c1 <= '9') || c2 == '\0'))
-       d = atoi(&name_ptr[4]);
-
-      if (d >=1 && d <= 24)
-       key = KSYM_F1 + (Key)(d - 1);
-    }
-    else if (strncmp(name_ptr, "XK_", 3) == 0)
-    {
-      i = 0;
-
-      do
-      {
-       if (strcmp(name_ptr, translate_key[i].x11name) == 0)
-       {
-         key = translate_key[i].key;
-         break;
-       }
-      }
-      while (translate_key[++i].x11name);
-    }
-    else if (strncmp(name_ptr, "0x", 2) == 0)
-    {
-      unsigned long value = 0;
-
-      name_ptr += 2;
-
-      while (name_ptr)
-      {
-       char c = *name_ptr++;
-       int d = -1;
-
-       if (c >= '0' && c <= '9')
-         d = (int)(c - '0');
-       else if (c >= 'a' && c <= 'f')
-         d = (int)(c - 'a' + 10);
-       else if (c >= 'A' && c <= 'F')
-         d = (int)(c - 'A' + 10);
-
-       if (d == -1)
-       {
-         value = -1;
-         break;
-       }
-
-       value = value * 16 + d;
-      }
-
-      if (value != -1)
-       key = (Key)value;
-    }
-
-    *keysym = key;
-  }
-}
-
-char *getKeyNameFromKey(Key key)
-{
-  char *name;
-
-  translate_keyname(&key, NULL, &name, TRANSLATE_KEYSYM_TO_KEYNAME);
-  return name;
-}
-
-char *getX11KeyNameFromKey(Key key)
-{
-  char *x11name;
-
-  translate_keyname(&key, &x11name, NULL, TRANSLATE_KEYSYM_TO_X11KEYNAME);
-  return x11name;
-}
-
-Key getKeyFromX11KeyName(char *x11name)
-{
-  Key key;
-
-  translate_keyname(&key, &x11name, NULL, TRANSLATE_X11KEYNAME_TO_KEYSYM);
-  return key;
-}
-
-char getCharFromKey(Key key)
-{
-  char *keyname = getKeyNameFromKey(key);
-  char letter = 0;
-
-  if (strlen(keyname) == 1)
-    letter = keyname[0];
-  else if (strcmp(keyname, "space") == 0)
-    letter = ' ';
-  else if (strcmp(keyname, "circumflex") == 0)
-    letter = '^';
-
-  return letter;
-}
-
-#define TRANSLATE_JOYSYMBOL_TO_JOYNAME 0
-#define TRANSLATE_JOYNAME_TO_JOYSYMBOL 1
-
-void translate_joyname(int *joysymbol, char **name, int mode)
-{
-  static struct
-  {
-    int joysymbol;
-    char *name;
-  } translate_joy[] =
-  {
-    { JOY_LEFT,                "joystick_left" },
-    { JOY_RIGHT,       "joystick_right" },
-    { JOY_UP,          "joystick_up" },
-    { JOY_DOWN,                "joystick_down" },
-    { JOY_BUTTON_1,    "joystick_button_1" },
-    { JOY_BUTTON_2,    "joystick_button_2" },
-  };
-
-  int i;
-
-  if (mode == TRANSLATE_JOYSYMBOL_TO_JOYNAME)
-  {
-    *name = "[undefined]";
-
-    for (i=0; i<6; i++)
-    {
-      if (*joysymbol == translate_joy[i].joysymbol)
-      {
-       *name = translate_joy[i].name;
-       break;
-      }
-    }
-  }
-  else if (mode == TRANSLATE_JOYNAME_TO_JOYSYMBOL)
-  {
-    *joysymbol = 0;
-
-    for (i=0; i<6; i++)
-    {
-      if (strcmp(*name, translate_joy[i].name) == 0)
-      {
-       *joysymbol = translate_joy[i].joysymbol;
-       break;
-      }
-    }
-  }
-}
-
-char *getJoyNameFromJoySymbol(int joysymbol)
-{
-  char *name;
-
-  translate_joyname(&joysymbol, &name, TRANSLATE_JOYSYMBOL_TO_JOYNAME);
-  return name;
-}
-
-int getJoySymbolFromJoyName(char *name)
-{
-  int joysymbol;
-
-  translate_joyname(&joysymbol, &name, TRANSLATE_JOYNAME_TO_JOYSYMBOL);
-  return joysymbol;
-}
-
-int getJoystickNrFromDeviceName(char *device_name)
-{
-  char c;
-  int joystick_nr = 0;
-
-  if (device_name == NULL || device_name[0] == '\0')
-    return 0;
-
-  c = device_name[strlen(device_name) - 1];
-
-  if (c >= '0' && c <= '9')
-    joystick_nr = (int)(c - '0');
-
-  if (joystick_nr < 0 || joystick_nr >= MAX_PLAYERS)
-    joystick_nr = 0;
-
-  return joystick_nr;
-}
-
-/* ------------------------------------------------------------------------- */
-/* some functions to handle lists of level directories                       */
-/* ------------------------------------------------------------------------- */
-
-struct LevelDirInfo *newLevelDirInfo()
-{
-  return checked_calloc(sizeof(struct LevelDirInfo));
-}
-
-void pushLevelDirInfo(struct LevelDirInfo **node_first,
-                     struct LevelDirInfo *node_new)
-{
-  node_new->next = *node_first;
-  *node_first = node_new;
-}
-
-int numLevelDirInfo(struct LevelDirInfo *node)
-{
-  int num = 0;
-
-  while (node)
-  {
-    num++;
-    node = node->next;
-  }
-
-  return num;
-}
-
-boolean validLevelSeries(struct LevelDirInfo *node)
-{
-  return (node != NULL && !node->node_group && !node->parent_link);
-}
-
-struct LevelDirInfo *getFirstValidLevelSeries(struct LevelDirInfo *node)
-{
-  if (node == NULL)
-  {
-    if (leveldir_first)                /* start with first level directory entry */
-      return getFirstValidLevelSeries(leveldir_first);
-    else
-      return NULL;
-  }
-  else if (node->node_group)   /* enter level group (step down into tree) */
-    return getFirstValidLevelSeries(node->node_group);
-  else if (node->parent_link)  /* skip start entry of level group */
-  {
-    if (node->next)            /* get first real level series entry */
-      return getFirstValidLevelSeries(node->next);
-    else                       /* leave empty level group and go on */
-      return getFirstValidLevelSeries(node->node_parent->next);
-  }
-  else                         /* this seems to be a regular level series */
-    return node;
-}
-
-struct LevelDirInfo *getLevelDirInfoFirstGroupEntry(struct LevelDirInfo *node)
-{
-  if (node == NULL)
-    return NULL;
-
-  if (node->node_parent == NULL)               /* top level group */
-    return leveldir_first;
-  else                                         /* sub level group */
-    return node->node_parent->node_group;
-}
-
-int numLevelDirInfoInGroup(struct LevelDirInfo *node)
-{
-  return numLevelDirInfo(getLevelDirInfoFirstGroupEntry(node));
-}
-
-int posLevelDirInfo(struct LevelDirInfo *node)
-{
-  struct LevelDirInfo *node_cmp = getLevelDirInfoFirstGroupEntry(node);
-  int pos = 0;
-
-  while (node_cmp)
-  {
-    if (node_cmp == node)
-      return pos;
-
-    pos++;
-    node_cmp = node_cmp->next;
-  }
-
-  return 0;
-}
-
-struct LevelDirInfo *getLevelDirInfoFromPos(struct LevelDirInfo *node, int pos)
-{
-  struct LevelDirInfo *node_default = node;
-  int pos_cmp = 0;
-
-  while (node)
-  {
-    if (pos_cmp == pos)
-      return node;
-
-    pos_cmp++;
-    node = node->next;
-  }
-
-  return node_default;
-}
-
-struct LevelDirInfo *getLevelDirInfoFromFilenameExt(struct LevelDirInfo *node,
-                                                   char *filename)
-{
-  if (filename == NULL)
-    return NULL;
-
-  while (node)
-  {
-    if (node->node_group)
-    {
-      struct LevelDirInfo *node_group;
-
-      node_group = getLevelDirInfoFromFilenameExt(node->node_group, filename);
-
-      if (node_group)
-       return node_group;
-    }
-    else if (!node->parent_link)
-    {
-      if (strcmp(filename, node->filename) == 0)
-       return node;
-    }
-
-    node = node->next;
-  }
-
-  return NULL;
-}
-
-struct LevelDirInfo *getLevelDirInfoFromFilename(char *filename)
-{
-  return getLevelDirInfoFromFilenameExt(leveldir_first, filename);
-}
-
-void dumpLevelDirInfo(struct LevelDirInfo *node, int depth)
-{
-  int i;
-
-  while (node)
-  {
-    for (i=0; i<depth * 3; i++)
-      printf(" ");
-
-    printf("filename == '%s'\n", node->filename);
-
-    if (node->node_group != NULL)
-      dumpLevelDirInfo(node->node_group, depth + 1);
-
-    node = node->next;
-  }
-}
-
-void sortLevelDirInfo(struct LevelDirInfo **node_first,
-                     int (*compare_function)(const void *, const void *))
-{
-  int num_nodes = numLevelDirInfo(*node_first);
-  struct LevelDirInfo **sort_array;
-  struct LevelDirInfo *node = *node_first;
-  int i = 0;
-
-  if (num_nodes == 0)
-    return;
-
-  /* allocate array for sorting structure pointers */
-  sort_array = checked_calloc(num_nodes * sizeof(struct LevelDirInfo *));
-
-  /* writing structure pointers to sorting array */
-  while (i < num_nodes && node)                /* double boundary check... */
-  {
-    sort_array[i] = node;
-
-    i++;
-    node = node->next;
-  }
-
-  /* sorting the structure pointers in the sorting array */
-  qsort(sort_array, num_nodes, sizeof(struct LevelDirInfo *),
-       compare_function);
-
-  /* update the linkage of list elements with the sorted node array */
-  for (i=0; i<num_nodes - 1; i++)
-    sort_array[i]->next = sort_array[i + 1];
-  sort_array[num_nodes - 1]->next = NULL;
-
-  /* update the linkage of the main list anchor pointer */
-  *node_first = sort_array[0];
-
-  free(sort_array);
-
-  /* now recursively sort the level group structures */
-  node = *node_first;
-  while (node)
-  {
-    if (node->node_group != NULL)
-      sortLevelDirInfo(&node->node_group, compare_function);
-
-    node = node->next;
-  }
-}
-
-inline void swap_numbers(int *i1, int *i2)
-{
-  int help = *i1;
-
-  *i1 = *i2;
-  *i2 = help;
-}
-
-inline void swap_number_pairs(int *x1, int *y1, int *x2, int *y2)
-{
-  int help_x = *x1;
-  int help_y = *y1;
-
-  *x1 = *x2;
-  *x2 = help_x;
-
-  *y1 = *y2;
-  *y2 = help_y;
-}
-
-
-/* ------------------------------------------------------------------------- */
-/* the following is only for debugging purpose and normally not used         */
-/* ------------------------------------------------------------------------- */
-
-#define DEBUG_NUM_TIMESTAMPS   3
-
-void debug_print_timestamp(int counter_nr, char *message)
-{
-  static long counter[DEBUG_NUM_TIMESTAMPS][2];
-
-  if (counter_nr >= DEBUG_NUM_TIMESTAMPS)
-    Error(ERR_EXIT, "debugging: increase DEBUG_NUM_TIMESTAMPS in misc.c");
-
-  counter[counter_nr][0] = Counter();
-
-  if (message)
-    printf("%s %.2f seconds\n", message,
-          (float)(counter[counter_nr][0] - counter[counter_nr][1]) / 1000);
-
-  counter[counter_nr][1] = Counter();
-}
diff --git a/src/misc.h b/src/misc.h
deleted file mode 100644 (file)
index e376cd2..0000000
+++ /dev/null
@@ -1,100 +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                *
-*----------------------------------------------------------*
-*  misc.h                                                  *
-***********************************************************/
-
-#ifndef MISC_H
-#define MISC_H
-
-#include "main.h"
-
-/* values for InitCounter() and Counter() */
-#define INIT_COUNTER                   0
-#define READ_COUNTER                   1
-
-/* values for InitRND() */
-#define NEW_RANDOMIZE                  -1
-
-/* values for Error() */
-#define ERR_RETURN                     0
-#define ERR_WARN                       (1 << 0)
-#define ERR_EXIT                       (1 << 1)
-#define ERR_HELP                       (1 << 2)
-#define ERR_SOUND_SERVER               (1 << 3)
-#define ERR_NETWORK_SERVER             (1 << 4)
-#define ERR_NETWORK_CLIENT             (1 << 5)
-#define ERR_FROM_SERVER                        (ERR_SOUND_SERVER | ERR_NETWORK_SERVER)
-#define ERR_EXIT_HELP                  (ERR_EXIT | ERR_HELP)
-#define ERR_EXIT_SOUND_SERVER          (ERR_EXIT | ERR_SOUND_SERVER)
-#define ERR_EXIT_NETWORK_SERVER                (ERR_EXIT | ERR_NETWORK_SERVER)
-#define ERR_EXIT_NETWORK_CLIENT                (ERR_EXIT | ERR_NETWORK_CLIENT)
-
-/* values for getFile...() and putFile...() */
-#define BYTE_ORDER_BIG_ENDIAN          0
-#define BYTE_ORDER_LITTLE_ENDIAN       1
-
-void InitCounter(void);
-unsigned long Counter(void);
-void Delay(unsigned long);
-boolean FrameReached(unsigned long *, unsigned long);
-boolean DelayReached(unsigned long *, unsigned long);
-void WaitUntilDelayReached(unsigned long *, unsigned long);
-char *int2str(int, int);
-unsigned int SimpleRND(unsigned int);
-unsigned int RND(unsigned int);
-unsigned int InitRND(long);
-char *getLoginName(void);
-char *getRealName(void);
-char *getHomeDir(void);
-char *getPath2(char *, char *);
-char *getPath3(char *, char *, char*);
-char *getStringCopy(char *);
-char *getStringToLower(char *);
-void MarkTileDirty(int, int);
-void SetBorderElement();
-void GetOptions(char **);
-void Error(int, char *, ...);
-void *checked_malloc(unsigned long);
-void *checked_calloc(unsigned long);
-short getFile16BitInteger(FILE *, int);
-void putFile16BitInteger(FILE *, short, int);
-int getFile32BitInteger(FILE *, int);
-void putFile32BitInteger(FILE *, int, int);
-void getFileChunk(FILE *, char *, int *, int);
-void putFileChunk(FILE *, char *, int, int);
-char *getKeyNameFromKey(Key);
-char *getX11KeyNameFromKey(Key);
-Key getKeyFromX11KeyName(char *);
-char getCharFromKey(Key);
-char *getJoyNameFromJoySymbol(int);
-int getJoySymbolFromJoyName(char *);
-int getJoystickNrFromDeviceName(char *);
-
-struct LevelDirInfo *newLevelDirInfo();
-void pushLevelDirInfo(struct LevelDirInfo **, struct LevelDirInfo *);
-int numLevelDirInfo(struct LevelDirInfo *);
-boolean validLevelSeries(struct LevelDirInfo *);
-struct LevelDirInfo *getFirstValidLevelSeries(struct LevelDirInfo *);
-struct LevelDirInfo *getLevelDirInfoFirstGroupEntry(struct LevelDirInfo *);
-int numLevelDirInfoInGroup(struct LevelDirInfo *);
-int posLevelDirInfo(struct LevelDirInfo *);
-struct LevelDirInfo *getLevelDirInfoFromPos(struct LevelDirInfo *, int);
-struct LevelDirInfo *getLevelDirInfoFromFilename(char *);
-void dumpLevelDirInfo(struct LevelDirInfo *, int);
-void sortLevelDirInfo(struct LevelDirInfo **,
-                     int (*compare_function)(const void *, const void *));
-
-inline void swap_numbers(int *, int *);
-inline void swap_number_pairs(int *, int *, int *, int *);
-
-void debug_print_timestamp(int, char *);
-
-#endif /* MISC_H */
diff --git a/src/msdos.c b/src/msdos.c
deleted file mode 100644 (file)
index 960609d..0000000
+++ /dev/null
@@ -1,938 +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             *
-*----------------------------------------------------------*
-*  msdos.c                                                 *
-***********************************************************/
-
-#include "platform.h"
-
-#if defined(PLATFORM_MSDOS)
-
-#include "main.h"
-#include "misc.h"
-#include "tools.h"
-#include "sound.h"
-#include "files.h"
-#include "joystick.h"
-#include "image.h"
-#include "pcx.h"
-
-/* allegro driver declarations */
-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)
-
-/* allegro global variables */
-extern volatile int key_shifts;
-extern int num_joysticks;
-extern JOYSTICK_INFO joy[];
-extern int i_love_bill;
-
-/* internal variables of msdos.c */
-static boolean keyboard_auto_repeat = TRUE;
-static int key_press_state[MAX_SCANCODES];
-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;
-
-static RGB global_colormap[MAX_COLORS];
-static int global_colormap_entries_used = 0;
-
-boolean wait_for_vsync;
-
-/*
-extern int playing_sounds;
-extern struct SoundControl playlist[MAX_SOUNDS_PLAYING];
-extern struct SoundControl emptySoundControl;
-*/
-
-static BITMAP *Read_PCX_to_AllegroBitmap(char *);
-
-static void allegro_init_drivers()
-{
-  int i;
-
-  for (i=0; i<MAX_EVENT_BUFFER; i++)
-    event_buffer[i].type = 0;
-
-  for (i=0; i<MAX_SCANCODES; i++)
-    key_press_state[i] = KeyReleaseMask;
-
-  last_mouse_pos = mouse_pos;
-  last_mouse_b = 0;
-
-  pending_events = 0;
-  clear_keybuf();
-
-  /* enable Windows friendly timer mode (already default under Windows) */
-  i_love_bill = TRUE;
-
-  install_keyboard();
-  install_timer();
-  if (install_mouse() > 0)
-    mouse_installed = TRUE;
-
-  last_joystick_state = 0;
-  joystick_event = FALSE;
-}
-
-static boolean allegro_init_audio()
-{
-  reserve_voices(MAX_SOUNDS_PLAYING, 0);
-
-  if (install_sound(DIGI_AUTODETECT, MIDI_NONE, NULL) == -1)
-    if (install_sound(DIGI_SB, MIDI_NONE, NULL) == -1)
-      return FALSE;
-
-  return TRUE;
-}
-
-static 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;
-}
-
-static void unhide_mouse(Display *display)
-{
-  if (mouse_installed)
-    show_mouse(video_bitmap);
-}
-
-static KeySym ScancodeToKeySym(byte scancode)
-{
-  switch(scancode)
-  {
-    case KEY_ESC:              return XK_Escape;
-    case KEY_1:                        return XK_1;
-    case KEY_2:                        return XK_2;
-    case KEY_3:                        return XK_3;
-    case KEY_4:                        return XK_4;
-    case KEY_5:                        return XK_5;
-    case KEY_6:                        return XK_6;
-    case KEY_7:                        return XK_7;
-    case KEY_8:                        return XK_8;
-    case KEY_9:                        return XK_9;
-    case KEY_0:                        return XK_0;
-    case KEY_MINUS:            return XK_minus;
-    case KEY_EQUALS:           return XK_equal;
-    case KEY_BACKSPACE:                return XK_BackSpace;
-    case KEY_TAB:              return XK_Tab;
-    case KEY_Q:                        return XK_q;
-    case KEY_W:                        return XK_w;
-    case KEY_E:                        return XK_e;
-    case KEY_R:                        return XK_r;
-    case KEY_T:                        return XK_t;
-    case KEY_Y:                        return XK_y;
-    case KEY_U:                        return XK_u;
-    case KEY_I:                        return XK_i;
-    case KEY_O:                        return XK_o;
-    case KEY_P:                        return XK_p;
-    case KEY_OPENBRACE:                return XK_braceleft;
-    case KEY_CLOSEBRACE:       return XK_braceright;
-    case KEY_ENTER:            return XK_Return;
-    case KEY_LCONTROL:         return XK_Control_L;
-    case KEY_A:                        return XK_a;
-    case KEY_S:                        return XK_s;
-    case KEY_D:                        return XK_d;
-    case KEY_F:                        return XK_f;
-    case KEY_G:                        return XK_g;
-    case KEY_H:                        return XK_h;
-    case KEY_J:                        return XK_j;
-    case KEY_K:                        return XK_k;
-    case KEY_L:                        return XK_l;
-    case KEY_COLON:            return XK_colon;
-    case KEY_QUOTE:            return XK_apostrophe;
-    case KEY_TILDE:            return XK_asciitilde;
-    case KEY_LSHIFT:           return XK_Shift_L;
-    case KEY_BACKSLASH:                return XK_backslash;
-    case KEY_Z:                        return XK_z;
-    case KEY_X:                        return XK_x;
-    case KEY_C:                        return XK_c;
-    case KEY_V:                        return XK_v;
-    case KEY_B:                        return XK_b;
-    case KEY_N:                        return XK_n;
-    case KEY_M:                        return XK_m;
-    case KEY_COMMA:            return XK_comma;
-    case KEY_STOP:             return XK_period;
-    case KEY_SLASH:            return XK_slash;
-    case KEY_RSHIFT:           return XK_Shift_R;
-    case KEY_ASTERISK:         return XK_KP_Multiply;
-    case KEY_ALT:              return XK_Alt_L;
-    case KEY_SPACE:            return XK_space;
-    case KEY_CAPSLOCK:         return XK_Caps_Lock;
-    case KEY_F1:               return XK_F1;
-    case KEY_F2:               return XK_F2;
-    case KEY_F3:               return XK_F3;
-    case KEY_F4:               return XK_F4;
-    case KEY_F5:               return XK_F5;
-    case KEY_F6:               return XK_F6;
-    case KEY_F7:               return XK_F7;
-    case KEY_F8:               return XK_F8;
-    case KEY_F9:               return XK_F9;
-    case KEY_F10:              return XK_F10;
-    case KEY_NUMLOCK:          return XK_Num_Lock;
-    case KEY_SCRLOCK:          return XK_Scroll_Lock;
-    case KEY_HOME:             return XK_Home;
-    case KEY_UP:               return XK_Up;
-    case KEY_PGUP:             return XK_Page_Up;
-    case KEY_MINUS_PAD:                return XK_KP_Subtract;
-    case KEY_LEFT:             return XK_Left;
-    case KEY_5_PAD:            return XK_KP_5;
-    case KEY_RIGHT:            return XK_Right;
-    case KEY_PLUS_PAD:         return XK_KP_Add;
-    case KEY_END:              return XK_End;
-    case KEY_DOWN:             return XK_Down;
-    case KEY_PGDN:             return XK_Page_Down;
-    case KEY_INSERT:           return XK_Insert;
-    case KEY_DEL:              return XK_Delete;
-    case KEY_PRTSCR:           return XK_Print;
-    case KEY_F11:              return XK_F11;
-    case KEY_F12:              return XK_F12;
-    case KEY_LWIN:             return XK_Meta_L;
-    case KEY_RWIN:             return XK_Meta_R;
-    case KEY_MENU:             return XK_Menu;
-    case KEY_PAD:              return XK_VoidSymbol;
-    case KEY_RCONTROL:         return XK_Control_R;
-    case KEY_ALTGR:            return XK_Alt_R;
-    case KEY_SLASH2:           return XK_KP_Divide;
-    case KEY_PAUSE:            return XK_Pause;
-
-    case NEW_KEY_BACKSLASH:    return XK_backslash;
-    case NEW_KEY_1_PAD:                return XK_KP_1;
-    case NEW_KEY_2_PAD:                return XK_KP_2;
-    case NEW_KEY_3_PAD:                return XK_KP_3;
-    case NEW_KEY_4_PAD:                return XK_KP_4;
-    case NEW_KEY_5_PAD:                return XK_KP_5;
-    case NEW_KEY_6_PAD:                return XK_KP_6;
-    case NEW_KEY_7_PAD:                return XK_KP_7;
-    case NEW_KEY_8_PAD:                return XK_KP_8;
-    case NEW_KEY_9_PAD:                return XK_KP_9;
-    case NEW_KEY_0_PAD:                return XK_KP_0;
-    case NEW_KEY_STOP_PAD:     return XK_KP_Separator;
-    case NEW_KEY_EQUALS_PAD:   return XK_KP_Equal;
-    case NEW_KEY_SLASH_PAD:    return XK_KP_Divide;
-    case NEW_KEY_ASTERISK_PAD: return XK_KP_Multiply;
-    case NEW_KEY_ENTER_PAD:    return XK_KP_Enter;
-
-    default:                   return XK_VoidSymbol;
-  }
-}
-
-void XMapWindow(Display *display, Window window)
-{
-  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 *)window, video_bitmap, 0, 0, x, y, width, height);
-
-  if (mouse_off)
-    unhide_mouse(display);
-}
-
-static unsigned long AllocColorCell(int r, int g, int b)
-{
-  byte pixel_mapping = 0;
-  int i;
-
-  r >>= 10;
-  g >>= 10;
-  b >>= 10;
-
-  /* try to use existing colors from the global colormap */
-  for (i=0; i<global_colormap_entries_used; i++)
-  {
-    if (r == global_colormap[i].r &&
-       g == global_colormap[i].g &&
-       b == global_colormap[i].b)              /* color found */
-    {
-      pixel_mapping = i;
-      break;
-    }
-  }
-
-  if (i == global_colormap_entries_used)       /* color not found */
-  {
-    if (global_colormap_entries_used < MAX_COLORS)
-      global_colormap_entries_used++;
-
-    global_colormap[i].r = r;
-    global_colormap[i].g = g;
-    global_colormap[i].b = b;
-
-    pixel_mapping = i;
-  }
-
-  return pixel_mapping;
-}
-
-Display *XOpenDisplay(char *display_name)
-{
-  Screen *screen;
-  Display *display;
-  BITMAP *mouse_bitmap = NULL;
-  char *filename;
-
-  filename = getPath3(options.ro_base_directory, GRAPHICS_DIRECTORY,
-                     MOUSE_FILENAME);
-
-  mouse_bitmap = Read_PCX_to_AllegroBitmap(filename);
-  free(filename);
-
-  if (mouse_bitmap == NULL)
-    return NULL;
-
-  screen = malloc(sizeof(Screen));
-  display = malloc(sizeof(Display));
-
-  screen[0].cmap = 0;
-  screen[0].root = 0;
-#if 0
-  screen[0].white_pixel = 0xFF;
-  screen[0].black_pixel = 0x00;
-#else
-  screen[0].white_pixel = AllocColorCell(0xFFFF, 0xFFFF, 0xFFFF);
-  screen[0].black_pixel = AllocColorCell(0x0000, 0x0000, 0x0000);
-#endif
-  screen[0].video_bitmap = NULL;
-
-  display->default_screen = 0;
-  display->screens = screen;
-  display->mouse_ptr = mouse_bitmap;
-
-  allegro_init();
-  allegro_init_drivers();
-  set_color_depth(8);
-
-  /* force Windows 95 to switch to fullscreen mode */
-  set_gfx_mode(GFX_AUTODETECT, 320, 200, 0, 0);
-  rest(200);
-  set_gfx_mode(GFX_AUTODETECT, XRES, YRES, 0, 0);
-
-  return display;
-}
-
-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);
-
-#if 0
-  set_mouse_sprite_focus(1, 1);
-#endif
-
-  set_mouse_speed(1, 1);
-  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;
-}
-
-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 XSetClipMask(Display *display, GC gc, Pixmap pixmap)
-{
-  XGCValues *gcv = (XGCValues *)gc;
-
-  gcv->clip_mask = pixmap;
-  gcv->value_mask |= GCClipMask;
-}
-
-void XSetClipOrigin(Display *display, GC gc, int x, int y)
-{
-  XGCValues *gcv = (XGCValues *)gc;
-
-  gcv->clip_x_origin = x;
-  gcv->clip_x_origin = y;
-}
-
-void XFillRectangle(Display *display, Drawable d, GC gc, int x, int y,
-                   unsigned int width, unsigned int height)
-{
-  boolean mouse_off = FALSE;
-
-  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 - 1, y + height - 1,
-          ((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 *bitmap = NULL;
-
-  if (gfx_capabilities & GFX_HW_VRAM_BLIT &&
-      width == FXSIZE && height == FYSIZE)
-    bitmap = create_video_bitmap(width, height);
-
-  if (bitmap == NULL)
-    bitmap = create_bitmap(width, height);
-
-  return (Pixmap)bitmap;
-}
-
-void XSync(Display *display, Bool discard_events)
-{
-  wait_for_vsync = TRUE;
-}
-
-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 = FALSE;
-
-  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;
-}
-
-static BITMAP *Image_to_AllegroBitmap(Image *image)
-{
-  BITMAP *bitmap;
-  byte *src_ptr = image->data;
-  byte pixel_mapping[MAX_COLORS];
-  unsigned int depth = 8;
-
-#if 0
-  int i, j, x, y;
-#else
-  int i, x, y;
-#endif
-
-  /* allocate new allegro bitmap structure */
-  if ((bitmap = create_bitmap_ex(depth, image->width, image->height)) == NULL)
-  {
-    errno_pcx = PCX_NoMemory;
-    return NULL;
-  }
-
-  clear(bitmap);
-
-  /* try to use existing colors from the global colormap */
-  for (i=0; i<MAX_COLORS; i++)
-  {
-
-#if 0
-    int r, g, b;
-#endif
-
-    if (!image->rgb.color_used[i])
-      continue;
-
-
-#if 0
-    r = image->rgb.red[i] >> 10;
-    g = image->rgb.green[i] >> 10;
-    b = image->rgb.blue[i] >> 10;
-
-    for (j=0; j<global_colormap_entries_used; j++)
-    {
-      if (r == global_colormap[j].r &&
-         g == global_colormap[j].g &&
-         b == global_colormap[j].b)            /* color found */
-      {
-       pixel_mapping[i] = j;
-       break;
-      }
-    }
-
-    if (j == global_colormap_entries_used)     /* color not found */
-    {
-      if (global_colormap_entries_used < MAX_COLORS)
-       global_colormap_entries_used++;
-
-      global_colormap[j].r = r;
-      global_colormap[j].g = g;
-      global_colormap[j].b = b;
-
-      pixel_mapping[i] = j;
-    }
-#else
-    pixel_mapping[i] = AllocColorCell(image->rgb.red[i],
-                                     image->rgb.green[i],
-                                     image->rgb.blue[i]);
-#endif
-
-  }
-
-  /* copy bitmap data */
-  for (y=0; y<image->height; y++)
-    for (x=0; x<image->width; x++)
-      putpixel(bitmap, x, y, pixel_mapping[*src_ptr++]);
-
-  return bitmap;
-}
-
-static BITMAP *Read_PCX_to_AllegroBitmap(char *filename)
-{
-  BITMAP *bitmap;
-  Image *image;
-
-  /* read the graphic file in PCX format to internal image structure */
-  if ((image = Read_PCX_to_Image(filename)) == NULL)
-    return NULL;
-
-  /* convert internal image structure to allegro bitmap structure */
-  if ((bitmap = Image_to_AllegroBitmap(image)) == NULL)
-    return NULL;
-
-  set_palette(global_colormap);
-
-  return bitmap;
-}
-
-int Read_PCX_to_Pixmap(Display *display, Window window, GC gc, char *filename,
-                      Pixmap *pixmap, Pixmap *pixmap_mask)
-{
-  BITMAP *bitmap;
-
-  if ((bitmap = Read_PCX_to_AllegroBitmap(filename)) == NULL)
-    return errno_pcx;
-
-  *pixmap = (Pixmap)bitmap;
-  *pixmap_mask = (Pixmap)bitmap;
-
-  return PCX_Success;
-}
-
-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 *bitmap;
-
-  if ((bitmap = Read_PCX_to_AllegroBitmap(filename)) == NULL)
-    return BitmapOpenFailed;
-
-  *width_return = bitmap->w;
-  *height_return = bitmap->h;
-  *x_hot_return = -1;
-  *y_hot_return = -1;
-  *bitmap_return = (Pixmap)bitmap;
-
-  return BitmapSuccess;
-}
-
-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 *bitmap = video_bitmap;
-
-  if (is_screen_bitmap(bitmap))
-    destroy_bitmap(bitmap);
-
-  if (display->screens)
-    free(display->screens);
-
-  if (display)
-    free(display);
-
-  /* return to text mode (or DOS box on Windows screen) */
-  set_gfx_mode(GFX_TEXT, 0, 0, 0, 0);
-}
-
-void XNextEvent(Display *display, XEvent *event_return)
-{
-  while (!pending_events)
-    XPending(display);
-
-  memcpy(event_return, &event_buffer[pending_events], sizeof(XEvent));
-  pending_events--;
-}
-
-static void NewKeyEvent(int key_press_state, KeySym keysym)
-{
-  XKeyEvent *xkey;
-
-  if (pending_events >= MAX_EVENT_BUFFER)
-    return;
-
-  pending_events++;
-  xkey = (XKeyEvent *)&event_buffer[pending_events];
-  xkey->type = key_press_state;
-  xkey->state = (unsigned int)keysym;
-}
-
-#define HANDLE_RAW_KB_ALL_KEYS                 0
-#define HANDLE_RAW_KB_MODIFIER_KEYS_ONLY       1
-
-static int modifier_scancode[] =
-{
-  KEY_LSHIFT,
-  KEY_RSHIFT,
-  KEY_LCONTROL,
-  KEY_RCONTROL,
-  KEY_ALT,
-  KEY_ALTGR,
-  KEY_LWIN,
-  KEY_RWIN,
-  KEY_CAPSLOCK,
-  KEY_NUMLOCK,
-  KEY_SCRLOCK,
-  -1
-};
-
-static void HandleKeyboardRaw(int mode)
-{
-  int i;
-
-  for (i=0; i<MAX_SCANCODES; i++)
-  {
-    int scancode, new_state, event_type;
-    char key_pressed;
-
-    if (mode == HANDLE_RAW_KB_MODIFIER_KEYS_ONLY)
-    {
-      if ((scancode = modifier_scancode[i]) == -1)
-       return;
-    }
-    else
-      scancode = i;
-
-    key_pressed = key[scancode];
-    new_state = (key_pressed ? KeyPressMask : KeyReleaseMask);
-    event_type = (key_pressed ? KeyPress : KeyRelease);
-
-    if (key_press_state[i] == new_state)       /* state not changed */
-      continue;
-
-    key_press_state[i] = new_state;
-
-    NewKeyEvent(event_type, ScancodeToKeySym(scancode));
-  }
-}
-
-static void HandleKeyboardEvent()
-{
-  if (keypressed())
-  {
-    int key_info = readkey();
-    int scancode = (key_info >> 8);
-    int ascii = (key_info & 0xff);
-    KeySym keysym = ScancodeToKeySym(scancode);
-
-    if (scancode == KEY_PAD)
-    {
-      /* keys on the numeric keypad return just scancode 'KEY_PAD'
-        for some reason, so we must handle them separately */
-
-      if (ascii >= '0' && ascii <= '9')
-       keysym = XK_KP_0 + (KeySym)(ascii - '0');
-      else if (ascii == '.')
-       keysym = XK_KP_Separator;
-    }
-    else if (ascii >= ' ' && ascii <= 'Z')
-      keysym = XK_space + (KeySym)(ascii - ' ');
-    else if (ascii == '^')
-      keysym = XK_asciicircum;
-    else if (ascii == '_')
-      keysym = XK_underscore;
-    else if (ascii == 'Ä')
-      keysym = XK_Adiaeresis;
-    else if (ascii == 'Ö')
-      keysym = XK_Odiaeresis;
-    else if (ascii == 'Ü')
-      keysym = XK_Udiaeresis;
-    else if (ascii == 'ä')
-      keysym = XK_adiaeresis;
-    else if (ascii == 'ö')
-      keysym = XK_odiaeresis;
-    else if (ascii == 'ü')
-      keysym = XK_udiaeresis;
-    else if (ascii == 'ß')
-      keysym = XK_ssharp;
-
-    NewKeyEvent(KeyPress, keysym);
-  }
-  else if (key_shifts & (KB_SHIFT_FLAG | KB_CTRL_FLAG | KB_ALT_FLAG))
-  {
-    /* the allegro function keypressed() does not give us single pressed
-       modifier keys, so we must detect them with the internal global
-       allegro variable 'key_shifts' and then handle them separately */
-
-    HandleKeyboardRaw(HANDLE_RAW_KB_MODIFIER_KEYS_ONLY);
-  }
-}
-
-int XPending(Display *display)
-{
-  XButtonEvent *xbutton;
-  XMotionEvent *xmotion;
-  int i;
-
-  /* When using 'HandleKeyboardRaw()', keyboard input is also stored in
-     the allegro keyboard input buffer and would be available a second
-     time by calling 'HandleKeyboardEvent()'. To avoid double keyboard
-     events, the allegro function 'clear_keybuf()' must be called each
-     time when switching from calling 'HandleKeyboardRaw()' to calling
-     'HandleKeyboardEvent()' to get keyboard input, which is actually
-     done by 'XAutoRepeatOn()' which sets keyboard_auto_repeat to TRUE. */
-
-  /* keyboard event */
-  if (keyboard_auto_repeat)
-    HandleKeyboardEvent();
-  else
-    HandleKeyboardRaw(HANDLE_RAW_KB_ALL_KEYS);
-
-  /* mouse motion event */
-  if (mouse_pos != last_mouse_pos)
-  {
-    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;
-  }
-
-  /* mouse button event */
-  if (mouse_b != last_mouse_b)
-  {
-    for (i=0; i<3; i++)                /* check all three mouse buttons */
-    {
-      int bitmask = (1 << i);
-
-      if ((last_mouse_b & bitmask) != (mouse_b & bitmask))
-      {
-       int mapping[3] = { 1, 3, 2 };
-
-       pending_events++;
-        xbutton = (XButtonEvent *)&event_buffer[pending_events];
-        xbutton->type = (mouse_b & bitmask ? ButtonPress : ButtonRelease);
-        xbutton->button = mapping[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;
-}
-
-int XLookupString(XKeyEvent *key_event, char *buffer, int buffer_size,
-                 KeySym *key, XComposeStatus *compose)
-{
-  *key = key_event->state;
-  return 0;
-}
-
-void XSetForeground(Display *display, GC gc, unsigned long pixel)
-{
-  XGCValues *gcv = (XGCValues *)gc;
-
-  gcv->foreground = pixel;
-}
-
-void XDrawLine(Display *display, Drawable d, GC gc,
-              int x1, int y1, int x2, int y2)
-{
-  XGCValues *gcv = (XGCValues *)gc;
-  boolean mouse_off = FALSE;
-
-  if ((BITMAP *)d == video_bitmap)
-  {
-    x1 += display->screens[display->default_screen].x;
-    y1 += display->screens[display->default_screen].y;
-    x2 += display->screens[display->default_screen].x;
-    y2 += display->screens[display->default_screen].y;
-    freeze_mouse_flag = TRUE;
-    mouse_off = hide_mouse(display, MIN(x1, x2), MIN(y1, y2),
-                          MAX(x1, x2) - MIN(x1, x2),
-                          MAX(y1, y2) - MIN(y1, y2));
-  }
-
-  line((BITMAP *)d, x1, y1, x2, y2, gcv->foreground);
-
-  if (mouse_off)
-    unhide_mouse(display);
-
-  freeze_mouse_flag = FALSE;
-}
-
-void XDestroyImage(XImage *ximage)
-{
-}
-
-Bool XQueryPointer(Display *display, Window window,
-                  Window *root, Window *child, int *root_x, int *root_y,
-                  int *win_x, int *win_y, unsigned int *mask)
-{
-  *win_x = mouse_x - display->screens[display->default_screen].x;
-  *win_y = mouse_y - display->screens[display->default_screen].y;
-
-  return True;
-}
-
-void XAutoRepeatOn(Display *display)
-{
-  keyboard_auto_repeat = TRUE;
-  clear_keybuf();
-}
-
-void XAutoRepeatOff(Display *display)
-{
-  keyboard_auto_repeat = FALSE;
-}
-
-boolean MSDOSOpenAudio(void)
-{
-  return allegro_init_audio();
-}
-
-boolean MSDOSCloseAudio(void)
-{
-  /* nothing to be done here */
-}
-
-void NetworkServer(int port, int serveronly)
-{
-  Error(ERR_WARN, "networking not supported in DOS version");
-}
-
-#endif /* PLATFORM_MSDOS */
diff --git a/src/msdos.h b/src/msdos.h
deleted file mode 100644 (file)
index 26a3f79..0000000
+++ /dev/null
@@ -1,712 +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             *
-*----------------------------------------------------------*
-*  msdos.h                                                 *
-***********************************************************/
-
-#ifndef MSDOS_H
-#define MSDOS_H
-
-#include <allegro.h>
-#include <time.h>
-
-/* symbol 'window' is defined in DJGPP cross-compiler in libc.a(conio.o) */
-#define window window_djgpp
-
-/* system dependent definitions */
-
-#define TARGET_STRING          "DOS"
-
-/* allegro defines TRUE as -1 */
-#ifdef TRUE
-#undef TRUE
-#undef FALSE
-#endif
-
-#define TRUE   1
-#define FALSE  0
-
-#define XRES   800
-#define YRES   600
-
-/* additional Allegro keyboard mapping */
-
-/* The following are all undefined in Allegro */
-#define NEW_KEY_BACKSLASH      86
-#define NEW_KEY_1_PAD          101
-#define NEW_KEY_2_PAD          102
-#define NEW_KEY_3_PAD          103
-#define NEW_KEY_4_PAD          104
-#define NEW_KEY_5_PAD          105
-#define NEW_KEY_6_PAD          106
-#define NEW_KEY_7_PAD          107
-#define NEW_KEY_8_PAD          108
-#define NEW_KEY_9_PAD          109
-#define NEW_KEY_0_PAD          110
-#define NEW_KEY_STOP_PAD       111
-#define NEW_KEY_EQUALS_PAD     112
-#define NEW_KEY_SLASH_PAD      113
-#define NEW_KEY_ASTERISK_PAD   114
-#define NEW_KEY_ENTER_PAD      115
-
-/* X11 keyboard mapping (from 'keysymdef.h') */
-
-#define XK_VoidSymbol          0xFFFFFF        /* void symbol */
-
-/*
- * TTY Functions, cleverly chosen to map to ascii, for convenience of
- * programming, but could have been arbitrary (at the cost of lookup
- * tables in client code.
- */
-
-#define XK_BackSpace           0xFF08  /* back space, back char */
-#define XK_Tab                 0xFF09
-#define XK_Linefeed            0xFF0A  /* Linefeed, LF */
-#define XK_Clear               0xFF0B
-#define XK_Return              0xFF0D  /* Return, enter */
-#define XK_Pause               0xFF13  /* Pause, hold */
-#define XK_Scroll_Lock         0xFF14
-#define XK_Sys_Req             0xFF15
-#define XK_Escape              0xFF1B
-#define XK_Delete              0xFFFF  /* Delete, rubout */
-
-/* International & multi-key character composition */
-
-#define XK_Multi_key           0xFF20  /* Multi-key character compose */
-#define XK_SingleCandidate     0xFF3C
-#define XK_MultipleCandidate   0xFF3D
-#define XK_PreviousCandidate   0xFF3E
-
-/* Cursor control & motion */
-
-#define XK_Home                        0xFF50
-#define XK_Left                        0xFF51  /* Move left, left arrow */
-#define XK_Up                  0xFF52  /* Move up, up arrow */
-#define XK_Right               0xFF53  /* Move right, right arrow */
-#define XK_Down                        0xFF54  /* Move down, down arrow */
-#define XK_Prior               0xFF55  /* Prior, previous */
-#define XK_Page_Up             0xFF55
-#define XK_Next                        0xFF56  /* Next */
-#define XK_Page_Down           0xFF56
-#define XK_End                 0xFF57  /* EOL */
-#define XK_Begin               0xFF58  /* BOL */
-
-/* Misc Functions */
-
-#define XK_Select              0xFF60  /* Select, mark */
-#define XK_Print               0xFF61
-#define XK_Execute             0xFF62  /* Execute, run, do */
-#define XK_Insert              0xFF63  /* Insert, insert here */
-#define XK_Undo                        0xFF65  /* Undo, oops */
-#define XK_Redo                        0xFF66  /* redo, again */
-#define XK_Menu                        0xFF67
-#define XK_Find                        0xFF68  /* Find, search */
-#define XK_Cancel              0xFF69  /* Cancel, stop, abort, exit */
-#define XK_Help                        0xFF6A  /* Help */
-#define XK_Break               0xFF6B
-#define XK_Mode_switch         0xFF7E  /* Character set switch */
-#define XK_script_switch        0xFF7E  /* Alias for mode_switch */
-#define XK_Num_Lock            0xFF7F
-
-/* Keypad Functions, keypad numbers cleverly chosen to map to ascii */
-
-#define XK_KP_Space            0xFF80  /* space */
-#define XK_KP_Tab              0xFF89
-#define XK_KP_Enter            0xFF8D  /* enter */
-#define XK_KP_F1               0xFF91  /* PF1, KP_A, ... */
-#define XK_KP_F2               0xFF92
-#define XK_KP_F3               0xFF93
-#define XK_KP_F4               0xFF94
-#define XK_KP_Home             0xFF95
-#define XK_KP_Left             0xFF96
-#define XK_KP_Up               0xFF97
-#define XK_KP_Right            0xFF98
-#define XK_KP_Down             0xFF99
-#define XK_KP_Prior            0xFF9A
-#define XK_KP_Page_Up          0xFF9A
-#define XK_KP_Next             0xFF9B
-#define XK_KP_Page_Down                0xFF9B
-#define XK_KP_End              0xFF9C
-#define XK_KP_Begin            0xFF9D
-#define XK_KP_Insert           0xFF9E
-#define XK_KP_Delete           0xFF9F
-#define XK_KP_Equal            0xFFBD  /* equals */
-#define XK_KP_Multiply         0xFFAA
-#define XK_KP_Add              0xFFAB
-#define XK_KP_Separator                0xFFAC  /* separator, often comma */
-#define XK_KP_Subtract         0xFFAD
-#define XK_KP_Decimal          0xFFAE
-#define XK_KP_Divide           0xFFAF
-
-#define XK_KP_0                        0xFFB0
-#define XK_KP_1                        0xFFB1
-#define XK_KP_2                        0xFFB2
-#define XK_KP_3                        0xFFB3
-#define XK_KP_4                        0xFFB4
-#define XK_KP_5                        0xFFB5
-#define XK_KP_6                        0xFFB6
-#define XK_KP_7                        0xFFB7
-#define XK_KP_8                        0xFFB8
-#define XK_KP_9                        0xFFB9
-
-/*
- * Auxilliary Functions; note the duplicate definitions for left and right
- * function keys;  Sun keyboards and a few other manufactures have such
- * function key groups on the left and/or right sides of the keyboard.
- * We've not found a keyboard with more than 35 function keys total.
- */
-
-#define XK_F1                  0xFFBE
-#define XK_F2                  0xFFBF
-#define XK_F3                  0xFFC0
-#define XK_F4                  0xFFC1
-#define XK_F5                  0xFFC2
-#define XK_F6                  0xFFC3
-#define XK_F7                  0xFFC4
-#define XK_F8                  0xFFC5
-#define XK_F9                  0xFFC6
-#define XK_F10                 0xFFC7
-#define XK_F11                 0xFFC8
-#define XK_L1                  0xFFC8
-#define XK_F12                 0xFFC9
-#define XK_L2                  0xFFC9
-#define XK_F13                 0xFFCA
-#define XK_L3                  0xFFCA
-#define XK_F14                 0xFFCB
-#define XK_L4                  0xFFCB
-#define XK_F15                 0xFFCC
-#define XK_L5                  0xFFCC
-#define XK_F16                 0xFFCD
-#define XK_L6                  0xFFCD
-#define XK_F17                 0xFFCE
-#define XK_L7                  0xFFCE
-#define XK_F18                 0xFFCF
-#define XK_L8                  0xFFCF
-#define XK_F19                 0xFFD0
-#define XK_L9                  0xFFD0
-#define XK_F20                 0xFFD1
-#define XK_L10                 0xFFD1
-#define XK_F21                 0xFFD2
-#define XK_R1                  0xFFD2
-#define XK_F22                 0xFFD3
-#define XK_R2                  0xFFD3
-#define XK_F23                 0xFFD4
-#define XK_R3                  0xFFD4
-#define XK_F24                 0xFFD5
-#define XK_R4                  0xFFD5
-#define XK_F25                 0xFFD6
-#define XK_R5                  0xFFD6
-#define XK_F26                 0xFFD7
-#define XK_R6                  0xFFD7
-#define XK_F27                 0xFFD8
-#define XK_R7                  0xFFD8
-#define XK_F28                 0xFFD9
-#define XK_R8                  0xFFD9
-#define XK_F29                 0xFFDA
-#define XK_R9                  0xFFDA
-#define XK_F30                 0xFFDB
-#define XK_R10                 0xFFDB
-#define XK_F31                 0xFFDC
-#define XK_R11                 0xFFDC
-#define XK_F32                 0xFFDD
-#define XK_R12                 0xFFDD
-#define XK_F33                 0xFFDE
-#define XK_R13                 0xFFDE
-#define XK_F34                 0xFFDF
-#define XK_R14                 0xFFDF
-#define XK_F35                 0xFFE0
-#define XK_R15                 0xFFE0
-
-/* Modifiers */
-
-#define XK_Shift_L             0xFFE1  /* Left shift */
-#define XK_Shift_R             0xFFE2  /* Right shift */
-#define XK_Control_L           0xFFE3  /* Left control */
-#define XK_Control_R           0xFFE4  /* Right control */
-#define XK_Caps_Lock           0xFFE5  /* Caps lock */
-#define XK_Shift_Lock          0xFFE6  /* Shift lock */
-
-#define XK_Meta_L              0xFFE7  /* Left meta */
-#define XK_Meta_R              0xFFE8  /* Right meta */
-#define XK_Alt_L               0xFFE9  /* Left alt */
-#define XK_Alt_R               0xFFEA  /* Right alt */
-#define XK_Super_L             0xFFEB  /* Left super */
-#define XK_Super_R             0xFFEC  /* Right super */
-#define XK_Hyper_L             0xFFED  /* Left hyper */
-#define XK_Hyper_R             0xFFEE  /* Right hyper */
-
-/*
- *  Latin 1
- *  Byte 3 = 0
- */
-
-#define XK_space               0x020
-#define XK_exclam              0x021
-#define XK_quotedbl            0x022
-#define XK_numbersign          0x023
-#define XK_dollar              0x024
-#define XK_percent             0x025
-#define XK_ampersand           0x026
-#define XK_apostrophe          0x027
-#define XK_quoteright          0x027   /* deprecated */
-#define XK_parenleft           0x028
-#define XK_parenright          0x029
-#define XK_asterisk            0x02a
-#define XK_plus                0x02b
-#define XK_comma               0x02c
-#define XK_minus               0x02d
-#define XK_period              0x02e
-#define XK_slash               0x02f
-#define XK_0                   0x030
-#define XK_1                   0x031
-#define XK_2                   0x032
-#define XK_3                   0x033
-#define XK_4                   0x034
-#define XK_5                   0x035
-#define XK_6                   0x036
-#define XK_7                   0x037
-#define XK_8                   0x038
-#define XK_9                   0x039
-#define XK_colon               0x03a
-#define XK_semicolon           0x03b
-#define XK_less                0x03c
-#define XK_equal               0x03d
-#define XK_greater             0x03e
-#define XK_question            0x03f
-#define XK_at                  0x040
-#define XK_A                   0x041
-#define XK_B                   0x042
-#define XK_C                   0x043
-#define XK_D                   0x044
-#define XK_E                   0x045
-#define XK_F                   0x046
-#define XK_G                   0x047
-#define XK_H                   0x048
-#define XK_I                   0x049
-#define XK_J                   0x04a
-#define XK_K                   0x04b
-#define XK_L                   0x04c
-#define XK_M                   0x04d
-#define XK_N                   0x04e
-#define XK_O                   0x04f
-#define XK_P                   0x050
-#define XK_Q                   0x051
-#define XK_R                   0x052
-#define XK_S                   0x053
-#define XK_T                   0x054
-#define XK_U                   0x055
-#define XK_V                   0x056
-#define XK_W                   0x057
-#define XK_X                   0x058
-#define XK_Y                   0x059
-#define XK_Z                   0x05a
-#define XK_bracketleft         0x05b
-#define XK_backslash           0x05c
-#define XK_bracketright        0x05d
-#define XK_asciicircum         0x05e
-#define XK_underscore          0x05f
-#define XK_grave               0x060
-#define XK_quoteleft           0x060   /* deprecated */
-#define XK_a                   0x061
-#define XK_b                   0x062
-#define XK_c                   0x063
-#define XK_d                   0x064
-#define XK_e                   0x065
-#define XK_f                   0x066
-#define XK_g                   0x067
-#define XK_h                   0x068
-#define XK_i                   0x069
-#define XK_j                   0x06a
-#define XK_k                   0x06b
-#define XK_l                   0x06c
-#define XK_m                   0x06d
-#define XK_n                   0x06e
-#define XK_o                   0x06f
-#define XK_p                   0x070
-#define XK_q                   0x071
-#define XK_r                   0x072
-#define XK_s                   0x073
-#define XK_t                   0x074
-#define XK_u                   0x075
-#define XK_v                   0x076
-#define XK_w                   0x077
-#define XK_x                   0x078
-#define XK_y                   0x079
-#define XK_z                   0x07a
-#define XK_braceleft           0x07b
-#define XK_bar                 0x07c
-#define XK_braceright          0x07d
-#define XK_asciitilde          0x07e
-
-#define XK_nobreakspace        0x0a0
-#define XK_exclamdown          0x0a1
-#define XK_cent                       0x0a2
-#define XK_sterling            0x0a3
-#define XK_currency            0x0a4
-#define XK_yen                 0x0a5
-#define XK_brokenbar           0x0a6
-#define XK_section             0x0a7
-#define XK_diaeresis           0x0a8
-#define XK_copyright           0x0a9
-#define XK_ordfeminine         0x0aa
-#define XK_guillemotleft       0x0ab   /* left angle quotation mark */
-#define XK_notsign             0x0ac
-#define XK_hyphen              0x0ad
-#define XK_registered          0x0ae
-#define XK_macron              0x0af
-#define XK_degree              0x0b0
-#define XK_plusminus           0x0b1
-#define XK_twosuperior         0x0b2
-#define XK_threesuperior       0x0b3
-#define XK_acute               0x0b4
-#define XK_mu                  0x0b5
-#define XK_paragraph           0x0b6
-#define XK_periodcentered      0x0b7
-#define XK_cedilla             0x0b8
-#define XK_onesuperior         0x0b9
-#define XK_masculine           0x0ba
-#define XK_guillemotright      0x0bb   /* right angle quotation mark */
-#define XK_onequarter          0x0bc
-#define XK_onehalf             0x0bd
-#define XK_threequarters       0x0be
-#define XK_questiondown        0x0bf
-#define XK_Agrave              0x0c0
-#define XK_Aacute              0x0c1
-#define XK_Acircumflex         0x0c2
-#define XK_Atilde              0x0c3
-#define XK_Adiaeresis          0x0c4
-#define XK_Aring               0x0c5
-#define XK_AE                  0x0c6
-#define XK_Ccedilla            0x0c7
-#define XK_Egrave              0x0c8
-#define XK_Eacute              0x0c9
-#define XK_Ecircumflex         0x0ca
-#define XK_Ediaeresis          0x0cb
-#define XK_Igrave              0x0cc
-#define XK_Iacute              0x0cd
-#define XK_Icircumflex         0x0ce
-#define XK_Idiaeresis          0x0cf
-#define XK_ETH                 0x0d0
-#define XK_Eth                 0x0d0   /* deprecated */
-#define XK_Ntilde              0x0d1
-#define XK_Ograve              0x0d2
-#define XK_Oacute              0x0d3
-#define XK_Ocircumflex         0x0d4
-#define XK_Otilde              0x0d5
-#define XK_Odiaeresis          0x0d6
-#define XK_multiply            0x0d7
-#define XK_Ooblique            0x0d8
-#define XK_Ugrave              0x0d9
-#define XK_Uacute              0x0da
-#define XK_Ucircumflex         0x0db
-#define XK_Udiaeresis          0x0dc
-#define XK_Yacute              0x0dd
-#define XK_THORN               0x0de
-#define XK_Thorn               0x0de   /* deprecated */
-#define XK_ssharp              0x0df
-#define XK_agrave              0x0e0
-#define XK_aacute              0x0e1
-#define XK_acircumflex         0x0e2
-#define XK_atilde              0x0e3
-#define XK_adiaeresis          0x0e4
-#define XK_aring               0x0e5
-#define XK_ae                  0x0e6
-#define XK_ccedilla            0x0e7
-#define XK_egrave              0x0e8
-#define XK_eacute              0x0e9
-#define XK_ecircumflex         0x0ea
-#define XK_ediaeresis          0x0eb
-#define XK_igrave              0x0ec
-#define XK_iacute              0x0ed
-#define XK_icircumflex         0x0ee
-#define XK_idiaeresis          0x0ef
-#define XK_eth                 0x0f0
-#define XK_ntilde              0x0f1
-#define XK_ograve              0x0f2
-#define XK_oacute              0x0f3
-#define XK_ocircumflex         0x0f4
-#define XK_otilde              0x0f5
-#define XK_odiaeresis          0x0f6
-#define XK_division            0x0f7
-#define XK_oslash              0x0f8
-#define XK_ugrave              0x0f9
-#define XK_uacute              0x0fa
-#define XK_ucircumflex         0x0fb
-#define XK_udiaeresis          0x0fc
-#define XK_yacute              0x0fd
-#define XK_thorn               0x0fe
-#define XK_ydiaeresis          0x0ff
-
-/* end of X11 keyboard mapping */
-
-#define MOUSE_FILENAME         "mouse.pcx"
-#define JOYSTICK_FILENAME      "joystick.cnf"
-
-#define screen myscreen
-
-#define XFlush(a)
-#define XGetImage(a,b,c,d,e,f,g,h)             ((XImage *) NULL)
-#define XDisplayName(a)                                ((char *) NULL)
-#define XFreeColors(a,b,c,d,e)
-#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 MAX_SCANCODES          128
-
-#define True                   1
-#define False                  0
-#define None                   0L
-
-#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 ClientMessage          33
-
-#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 PCX_Success             0
-#define PCX_OpenFailed         -1
-#define PCX_ReadFailed         -2
-#define        PCX_FileInvalid         -3
-#define PCX_NoMemory           -4
-#define PCX_ColorFailed                -5
-
-#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 DefaultVisual(dpy, scr)          (NULL)
-#define DefaultDepth(dpy, scr)   (NULL)
-#define XDisplayWidth(dpy, scr)          (XRES)
-#define XDisplayHeight(dpy, scr)  (YRES)
-
-#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 long Visual;
-typedef long XVisualInfo;
-typedef long Atom;
-typedef int Status;
-typedef int Bool;
-typedef int XComposeStatus;    /* we don't need the real type */
-
-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;   /* white pixel value */
-  unsigned long black_pixel;   /* black pixel value */
-  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;           /* x origin for clipping */
-  int clip_y_origin;           /* y origin for clipping */
-  unsigned long value_mask;
-} XGCValues;
-
-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 struct
-{
-  int type;                    /* ClientMessage */
-} XClientMessageEvent;
-
-typedef union _XEvent
-{
-  int type;                    /* must not be changed; first element */
-  XExposeEvent xexpose;
-  XButtonEvent xbutton;
-  XMotionEvent xmotion;
-  XKeyEvent xkey;
-} XEvent;
-
-void XMapWindow(Display *, Window);
-Display *XOpenDisplay(char *);
-Window XCreateSimpleWindow(Display *, Window, int, int,
-                          unsigned int, unsigned int, unsigned int,
-                          unsigned long, unsigned long);
-Status XStringListToTextProperty(char **, int, XTextProperty *);
-void XFree(void *);
-GC XCreateGC(Display *, Drawable, unsigned long, XGCValues *);
-void XSetClipMask(Display *, GC, Pixmap);
-void XSetClipOrigin(Display *, GC, int, int);
-void XFillRectangle(Display *, Drawable, GC, int, int,
-                   unsigned int, unsigned int);
-Pixmap XCreatePixmap(Display *, Drawable, unsigned int, unsigned int,
-                    unsigned int);
-void XSync(Display *, Bool);
-inline void XCopyArea(Display *, Drawable, Drawable, GC, int, int,
-                     unsigned int, unsigned int, int, int);
-int Read_PCX_to_Pixmap(Display *, Window, GC, char *, Pixmap *, Pixmap *);
-int XReadBitmapFile(Display *, Drawable, char *,
-                   unsigned int *, unsigned int *, Pixmap *, int *, int *);
-void XFreePixmap(Display *, Pixmap);
-void XFreeGC(Display *, GC);
-void XCloseDisplay(Display *);
-void XNextEvent(Display *, XEvent *);
-int XPending(Display *);
-KeySym XLookupKeysym(XKeyEvent *, int);
-int XLookupString(XKeyEvent *, char *, int, KeySym *, XComposeStatus *);
-void XSetForeground(Display *, GC, unsigned long);
-void XDrawLine(Display *, Drawable, GC, int, int, int, int);
-void XDestroyImage(XImage *);
-Bool XQueryPointer(Display *, Window, Window *, Window *, int *, int *,
-                  int *, int *, unsigned int *);
-void XAutoRepeatOn(Display *);
-void XAutoRepeatOff(Display *);
-
-boolean MSDOSOpenAudio(void);
-boolean MSDOSCloseAudio(void);
-
-void NetworkServer(int, int);
-
-#endif /* MSDOS_H */
index 2e356e921897bffa756d434cf6e6425e5b3b8c38..6a2479e53df35a2f638533ab85f57065701029bf 100644 (file)
@@ -11,7 +11,7 @@
 *  network.c                                               *
 ***********************************************************/
 
-#include "platform.h"
+#include "libgame/libgame.h"
 
 #if defined(PLATFORM_UNIX)
 
 #include <arpa/inet.h>
 #include <netdb.h>
 
+#if 0
+#include "libgame/libgame.h"
+#endif
+
 #include "netserv.h"
-#include "misc.h"
 
 static int clients = 0;
 static int onceonly = 0;
index e3a07c64092a5690b885e095eb3a90d36ecf6c2c..410695be366b1441a4899a1a573d58f7a444a309 100644 (file)
@@ -11,7 +11,7 @@
 *  network.c                                               *
 ***********************************************************/
 
-#include "platform.h"
+#include "libgame/libgame.h"
 
 #if defined(PLATFORM_UNIX)
 
 #include <arpa/inet.h>
 #include <netdb.h>
 
+#if 0
+#include "libgame/libgame.h"
+#endif
+
 #include "network.h"
 #include "netserv.h"
 #include "game.h"
 #include "tape.h"
 #include "files.h"
 #include "tools.h"
-#include "buttons.h"
 #include "screens.h"
-#include "misc.h"
 
 struct NetworkClientPlayerInfo
 {
diff --git a/src/pcx.c b/src/pcx.c
deleted file mode 100644 (file)
index b075940..0000000
--- a/src/pcx.c
+++ /dev/null
@@ -1,265 +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                *
-*----------------------------------------------------------*
-*  pcx.c                                                   *
-***********************************************************/
-
-#ifndef TARGET_SDL
-
-#include "pcx.h"
-#include "image.h"
-#include "misc.h"
-
-#define PCX_DEBUG              FALSE
-
-#define PCX_MAGIC              0x0a    /* first byte in a PCX image file    */
-#define PCX_LAST_VERSION       5       /* last acceptable version number    */
-#define PCX_ENCODING           1       /* PCX encoding method               */
-#define PCX_256COLORS_MAGIC    0x0c    /* first byte of a PCX 256 color map */
-#define PCX_MAXDEPTH           8       /* supports up to 8 bits per pixel   */
-#define PCX_MAXCOLORS          256     /* maximum number of colors          */
-
-#define PCX_HEADER_SIZE                128
-#define PCX_COLORMAP_SIZE      (3 * PCX_MAXCOLORS)
-
-struct PCX_Header
-{
-  unsigned char signature;     /* PCX file identifier                 */
-  unsigned char version;       /* version compatibility level         */
-  unsigned char encoding;      /* encoding method                     */
-  unsigned char bits_per_pixel;        /* bits per pixel, or depth            */
-  unsigned short xmin;         /* X position of left edge             */
-  unsigned short ymin;         /* Y position of top edge              */
-  unsigned short xmax;         /* X position of right edge            */
-  unsigned short ymax;         /* Y position of bottom edge           */
-  unsigned short hres;         /* X screen resolution of source image */
-  unsigned short vres;         /* Y screen resolution of source image */
-  unsigned char palette[16][3];        /* PCX color map                       */
-  unsigned char reserved;      /* should be 0, 1 if std res fax       */
-  unsigned char color_planes;  /* bit planes in image                 */
-  unsigned short bytes_per_line;/* byte delta between scanlines        */
-  unsigned short palette_type; /* 0 = undef, 1 = color, 2 = grayscale */
-  unsigned char filler[58];    /* fill to struct size of 128          */
-};
-
-/* global PCX error value */
-int errno_pcx = PCX_Success;
-
-static byte *PCX_ReadBitmap(Image *image, byte *buffer_ptr, byte *buffer_last)
-{
-  /* Run Length Encoding: If the two high bits are set,
-   * then the low 6 bits contain a repeat count, and the byte to
-   * repeat is the next byte in the file.  If the two high bits are
-   * not set, then this is the byte to write.
-   */
-
-  unsigned int bytes_per_pixel = (image->depth + 7) / 8;
-  register byte *bitmap_ptr, *bitmap_last;
-  register byte value, count;
-
-  bitmap_ptr = image->data;
-  bitmap_last = bitmap_ptr + (image->width * image->height * bytes_per_pixel);
-
-  while (bitmap_ptr < bitmap_last && buffer_ptr < buffer_last)
-  {
-    value = *buffer_ptr++;
-
-    if ((value & 0xc0) == 0xc0)                /* this is a repeat count byte */
-    {
-      count = value & 0x3f;            /* extract repeat count from byte */
-      value = *buffer_ptr++;           /* next byte is value to repeat */
-
-      for (; count && bitmap_ptr < bitmap_last; count--)
-       *bitmap_ptr++ = value;
-
-      if (count)                       /* repeat count spans end of bitmap */
-       return NULL;
-    }
-    else
-      *bitmap_ptr++ = value;
-
-    image->rgb.color_used[value] = TRUE;
-  }
-
-  /* check if end of buffer was reached before end of bitmap */
-  if (bitmap_ptr < bitmap_last)
-    return NULL;
-
-  /* return current buffer position for next decoding function */
-  return buffer_ptr;
-}
-
-static byte *PCX_ReadColormap(Image *image,byte *buffer_ptr, byte *buffer_last)
-{
-  int i, magic;
-
-  /* read colormap magic byte */
-  magic = *buffer_ptr++;
-
-  /* check magic colormap header byte */
-  if (magic != PCX_256COLORS_MAGIC)
-    return NULL;
-
-  /* check if enough bytes left for a complete colormap */
-  if (buffer_ptr + PCX_COLORMAP_SIZE > buffer_last)
-    return NULL;
-
-  /* read 256 colors from PCX colormap */
-  for (i=0; i<PCX_MAXCOLORS; i++)
-  {
-    image->rgb.red[i]   = *buffer_ptr++ << 8;
-    image->rgb.green[i] = *buffer_ptr++ << 8;
-    image->rgb.blue[i]  = *buffer_ptr++ << 8;
-  }
-
-  /* return current buffer position for next decoding function */
-  return buffer_ptr;
-}
-
-Image *Read_PCX_to_Image(char *filename)
-{
-  FILE *file;
-  byte *file_buffer;
-  byte *buffer_ptr, *buffer_last;
-  unsigned int file_length;
-  struct PCX_Header pcx;
-  Image *image;
-  int width, height, depth;
-  int i;
-
-  errno_pcx = PCX_Success;
-
-  if (!(file = fopen(filename, "r")))
-  {
-    errno_pcx = PCX_OpenFailed;
-    return NULL;
-  }
-
-  if (fseek(file, 0, SEEK_END) == -1)
-  {
-    fclose(file);
-    errno_pcx = PCX_ReadFailed;
-    return NULL;
-  }
-
-  file_length = ftell(file);
-  rewind(file);
-
-  if (file_length < PCX_HEADER_SIZE)
-  {
-    /* PCX file is too short to contain a valid PCX header */
-    fclose(file);
-
-    errno_pcx = PCX_FileInvalid;
-    return NULL;
-  }
-
-  file_buffer = checked_malloc(file_length);
-
-  if (fread(file_buffer, 1, file_length, file) != file_length)
-  {
-    fclose(file);
-    errno_pcx = PCX_ReadFailed;
-    return NULL;
-  }
-
-  fclose(file);
-
-  pcx.signature      = file_buffer[0];
-  pcx.version        = file_buffer[1];
-  pcx.encoding       = file_buffer[2];
-  pcx.bits_per_pixel = file_buffer[3];
-  pcx.xmin           = file_buffer[4]  + 256 * file_buffer[5];
-  pcx.ymin           = file_buffer[6]  + 256 * file_buffer[7];
-  pcx.xmax           = file_buffer[8]  + 256 * file_buffer[9];
-  pcx.ymax           = file_buffer[10] + 256 * file_buffer[11];
-  pcx.color_planes   = file_buffer[65];
-  pcx.bytes_per_line = file_buffer[66] + 256 * file_buffer[67];
-  pcx.palette_type   = file_buffer[68] + 256 * file_buffer[69];
-
-  width  = pcx.xmax - pcx.xmin + 1;
-  height = pcx.ymax - pcx.ymin + 1;
-  depth  = pcx.bits_per_pixel;
-
-  if (pcx.signature != PCX_MAGIC || pcx.version > PCX_LAST_VERSION ||
-      pcx.encoding != PCX_ENCODING || pcx.color_planes > PCX_MAXDEPTH ||
-      width < 0 || height < 0)
-  {
-    free(file_buffer);
-
-    errno_pcx = PCX_FileInvalid;
-    return NULL;
-  }
-
-#if PCX_DEBUG
-  if (options.verbose)
-  {
-    printf("%s is a %dx%d PC Paintbrush image with %d bitplanes\n",
-          filename, width, height,
-          pcx.color_planes);
-    printf("depth: %d\n", pcx.bits_per_pixel);
-    printf("color_planes: %d\n", pcx.color_planes);
-    printf("bytes_per_line: %d\n", pcx.bytes_per_line);
-    printf("palette type: %s\n",
-          (pcx.palette_type == 1 ? "color" :
-           pcx.palette_type == 2 ? "grayscale" : "undefined"));
-  }
-#endif
-
-  /* allocate new image structure */
-  image = newImage(width, height, depth);
-
-  buffer_ptr  = file_buffer + PCX_HEADER_SIZE;
-  buffer_last = file_buffer + file_length;
-
-  /* read compressed bitmap data */
-  if ((buffer_ptr = PCX_ReadBitmap(image, buffer_ptr, buffer_last)) == NULL)
-  {
-    free(file_buffer);
-    freeImage(image);
-
-    errno_pcx = PCX_FileInvalid;
-    return NULL;
-  }
-
-  if (file_length < PCX_HEADER_SIZE + PCX_COLORMAP_SIZE)
-  {
-    /* PCX file is too short to contain a valid 256 colors colormap */
-    fclose(file);
-    errno_pcx = PCX_ColorFailed;
-    return NULL;
-  }
-
-  /* read colormap data */
-  if (!PCX_ReadColormap(image, buffer_ptr, buffer_last))
-  {
-    free(file_buffer);
-    freeImage(image);
-    errno_pcx = PCX_ColorFailed;
-    return NULL;
-  }
-
-  free(file_buffer);
-
-  /* determine number of used colormap entries */
-  image->rgb.used = 0;
-  for (i=0; i<PCX_MAXCOLORS; i++)
-    if (image->rgb.color_used[i])
-      image->rgb.used++;
-
-#if PCX_DEBUG
-  if (options.verbose)
-    printf("Read_PCX_to_Image: %d colors found\n", image->rgb.used);
-#endif
-
-  return image;
-}
-
-#endif /* !TARGET_SDL */
diff --git a/src/pcx.h b/src/pcx.h
deleted file mode 100644 (file)
index 4725099..0000000
--- a/src/pcx.h
+++ /dev/null
@@ -1,35 +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                *
-*----------------------------------------------------------*
-*  pcx.h                                                   *
-***********************************************************/
-
-#ifndef PCX_H
-#define PCX_H
-
-#ifndef TARGET_SDL
-
-#include "main.h"
-#include "image.h"
-
-#define PCX_Success             0
-#define PCX_OpenFailed         -1
-#define PCX_ReadFailed         -2
-#define        PCX_FileInvalid         -3
-#define PCX_NoMemory           -4
-#define PCX_ColorFailed                -5
-
-/* global PCX error value */
-extern int errno_pcx;
-
-Image *Read_PCX_to_Image(char *);
-
-#endif /* !TARGET_SDL */
-#endif /* PCX_H */
diff --git a/src/platform.h b/src/platform.h
deleted file mode 100644 (file)
index 0251307..0000000
+++ /dev/null
@@ -1,47 +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                *
-*----------------------------------------------------------*
-*  platform.h                                              *
-***********************************************************/
-
-#ifndef PLATFORM_H
-#define PLATFORM_H
-
-/* define keywords for supported main platforms */
-
-#if defined(MSDOS)
-#define PLATFORM_MSDOS
-#elif defined(WIN32)
-#define PLATFORM_WIN32
-#else
-#define PLATFORM_UNIX
-#endif
-
-/* define additional keywords for several Unix platforms */
-
-#if defined(linux)
-#define PLATFORM_LINUX
-#endif
-
-#if defined(__FreeBSD__)
-#define PLATFORM_FREEBSD
-#endif
-
-/* detecting HP-UX by the following compiler keyword definitions:
-   - in K&R mode (the default), the HP C compiler defines "hpux"
-   - in ANSI mode (-Aa or -Ae), the HP C compiler defines "__hpux"
-   - the gcc (Gnu) C compiler defines "__hpux__"
-   Thanks to Jarkko Hietaniemi  for this note. */
-
-#if defined(__hpux__) || defined(__hpux) || defined(hpux)
-#define PLATFORM_HPUX
-#endif
-
-#endif /* PLATFORM_H */
diff --git a/src/random.c b/src/random.c
deleted file mode 100644 (file)
index 864f3dc..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright (c) 1983 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley.  The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- */
-
-/*
- * This is derived from the Berkeley source:
- *     @(#)random.c    5.5 (Berkeley) 7/6/88
- * It was reworked for the GNU C Library by Roland McGrath.
- */
-
-#include <errno.h>
-#include <limits.h>
-#include <stdlib.h>
-
-#include "random.h"
-
-
-/* An improved random number generation package.  In addition to the standard
-   rand()/srand() like interface, this package also has a special state info
-   interface.  The initstate() routine is called with a seed, an array of
-   bytes, and a count of how many bytes are being passed in; this array is
-   then initialized to contain information for random number generation with
-   that much state information.  Good sizes for the amount of state
-   information are 32, 64, 128, and 256 bytes.  The state can be switched by
-   calling the setstate() function with the same array as was initiallized
-   with initstate().  By default, the package runs with 128 bytes of state
-   information and generates far better random numbers than a linear
-   congruential generator.  If the amount of state information is less than
-   32 bytes, a simple linear congruential R.N.G. is used.  Internally, the
-   state information is treated as an array of longs; the zeroeth element of
-   the array is the type of R.N.G. being used (small integer); the remainder
-   of the array is the state information for the R.N.G.  Thus, 32 bytes of
-   state information will give 7 longs worth of state information, which will
-   allow a degree seven polynomial.  (Note: The zeroeth word of state
-   information also has some other information stored in it; see setstate
-   for details).  The random number generation technique is a linear feedback
-   shift register approach, employing trinomials (since there are fewer terms
-   to sum up that way).  In this approach, the least significant bit of all
-   the numbers in the state table will act as a linear feedback shift register,
-   and will have period 2^deg - 1 (where deg is the degree of the polynomial
-   being used, assuming that the polynomial is irreducible and primitive).
-   The higher order bits will have longer periods, since their values are
-   also influenced by pseudo-random carries out of the lower bits.  The
-   total period of the generator is approximately deg*(2**deg - 1); thus
-   doubling the amount of state information has a vast influence on the
-   period of the generator.  Note: The deg*(2**deg - 1) is an approximation
-   only good for large deg, when the period of the shift register is the
-   dominant factor.  With deg equal to seven, the period is actually much
-   longer than the 7*(2**7 - 1) predicted by this formula.  */
-
-
-
-/* For each of the currently supported random number generators, we have a
-   break value on the amount of state information (you need at least thi
-   bytes of state info to support this random number generator), a degree for
-   the polynomial (actually a trinomial) that the R.N.G. is based on, and
-   separation between the two lower order coefficients of the trinomial.  */
-
-/* Linear congruential.  */
-#define        TYPE_0          0
-#define        BREAK_0         8
-#define        DEG_0           0
-#define        SEP_0           0
-
-/* x**7 + x**3 + 1.  */
-#define        TYPE_1          1
-#define        BREAK_1         32
-#define        DEG_1           7
-#define        SEP_1           3
-
-/* x**15 + x + 1.  */
-#define        TYPE_2          2
-#define        BREAK_2         64
-#define        DEG_2           15
-#define        SEP_2           1
-
-/* x**31 + x**3 + 1.  */
-#define        TYPE_3          3
-#define        BREAK_3         128
-#define        DEG_3           31
-#define        SEP_3           3
-
-/* x**63 + x + 1.  */
-#define        TYPE_4          4
-#define        BREAK_4         256
-#define        DEG_4           63
-#define        SEP_4           1
-
-
-/* Array versions of the above information to make code run faster.
-   Relies on fact that TYPE_i == i.  */
-
-#define        MAX_TYPES       5       /* Max number of types above.  */
-
-
-
-/* Initially, everything is set up as if from:
-       initstate(1, randtbl, 128);
-   Note that this initialization takes advantage of the fact that srandom
-   advances the front and rear pointers 10*rand_deg times, and hence the
-   rear pointer which starts at 0 will also end up at zero; thus the zeroeth
-   element of the state information, which contains info about the current
-   position of the rear pointer is just
-       (MAX_TYPES * (rptr - state)) + TYPE_3 == TYPE_3.  */
-
-static long int randtbl[DEG_3 + 1] =
-{
-  TYPE_3,
-  -851904987, -43806228, -2029755270, 1390239686, -1912102820,
-  -485608943, 1969813258, -1590463333, -1944053249, 455935928, 508023712,
-  -1714531963, 1800685987, -2015299881, 654595283, -1149023258,
-  -1470005550, -1143256056, -1325577603, -1568001885, 1275120390,
-  -607508183, -205999574, -1696891592, 1492211999, -1528267240,
-  -952028296, -189082757, 362343714, 1424981831, 2039449641,
-};
-
-/* FPTR and RPTR are two pointers into the state info, a front and a rear
-   pointer.  These two pointers are always rand_sep places aparts, as they
-   cycle through the state information.  (Yes, this does mean we could get
-   away with just one pointer, but the code for random is more efficient
-   this way).  The pointers are left positioned as they would be from the call:
-       initstate(1, randtbl, 128);
-   (The position of the rear pointer, rptr, is really 0 (as explained above
-   in the initialization of randtbl) because the state table pointer is set
-   to point to randtbl[1] (as explained below).)  */
-
-static long int *fptr = &randtbl[SEP_3 + 1];
-static long int *rptr = &randtbl[1];
-
-
-
-/* The following things are the pointer to the state information table,
-   the type of the current generator, the degree of the current polynomial
-   being used, and the separation between the two pointers.
-   Note that for efficiency of random, we remember the first location of
-   the state information, not the zeroeth.  Hence it is valid to access
-   state[-1], which is used to store the type of the R.N.G.
-   Also, we remember the last location, since this is more efficient than
-   indexing every time to find the address of the last element to see if
-   the front and rear pointers have wrapped.  */
-
-static long int *state = &randtbl[1];
-
-static int rand_type = TYPE_3;
-static int rand_deg = DEG_3;
-static int rand_sep = SEP_3;
-
-static long int *end_ptr = &randtbl[sizeof(randtbl) / sizeof(randtbl[0])];
-
-/* Initialize the random number generator based on the given seed.  If the
-   type is the trivial no-state-information type, just remember the seed.
-   Otherwise, initializes state[] based on the given "seed" via a linear
-   congruential generator.  Then, the pointers are set to known locations
-   that are exactly rand_sep places apart.  Lastly, it cycles the state
-   information a given number of times to get rid of any initial dependencies
-   introduced by the L.C.R.N.G.  Note that the initialization of randtbl[]
-   for default usage relies on values produced by this routine.  */
-
-void srandom_linux_libc(unsigned int x)
-{
-  state[0] = x;
-  if (rand_type != TYPE_0)
-  {
-    register long int i;
-    for (i = 1; i < rand_deg; ++i)
-      state[i] = (1103515145 * state[i - 1]) + 12345;
-    fptr = &state[rand_sep];
-    rptr = &state[0];
-    for (i = 0; i < 10 * rand_deg; ++i)
-      (void) random_linux_libc();
-  }
-}
-
-/* If we are using the trivial TYPE_0 R.N.G., just do the old linear
-   congruential bit.  Otherwise, we do our fancy trinomial stuff, which is the
-   same in all ther other cases due to all the global variables that have been
-   set up.  The basic operation is to add the number at the rear pointer into
-   the one at the front pointer.  Then both pointers are advanced to the next
-   location cyclically in the table.  The value returned is the sum generated,
-   reduced to 31 bits by throwing away the "least random" low bit.
-   Note: The code takes advantage of the fact that both the front and
-   rear pointers can't wrap on the same call by not testing the rear
-   pointer if the front one has wrapped.  Returns a 31-bit random number.  */
-
-long int random_linux_libc()
-{
-  if (rand_type == TYPE_0)
-  {
-    state[0] = ((state[0] * 1103515245) + 12345) & LONG_MAX;
-    return state[0];
-  }
-  else
-  {
-    long int i;
-    *fptr += *rptr;
-    /* Chucking least random bit.  */
-    i = (*fptr >> 1) & LONG_MAX;
-    ++fptr;
-    if (fptr >= end_ptr)
-    {
-      fptr = state;
-      ++rptr;
-    }
-    else
-    {
-      ++rptr;
-      if (rptr >= end_ptr)
-       rptr = state;
-    }
-    return i;
-  }
-}
diff --git a/src/random.h b/src/random.h
deleted file mode 100644 (file)
index 366d1ff..0000000
+++ /dev/null
@@ -1,20 +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                *
-*----------------------------------------------------------*
-*  random.h                                                *
-***********************************************************/
-
-#ifndef RANDOM_H
-#define RANDOM_H
-
-void srandom_linux_libc(unsigned int);
-long int random_linux_libc(void);
-
-#endif
index e4be131820d7614a5c4d3b19d385393dc6178d5c..430273238aaf9370abb9fa738235b7a672f4b388 100644 (file)
 *  screens.c                                               *
 ***********************************************************/
 
+#include "libgame/libgame.h"
+
 #include "screens.h"
 #include "events.h"
-#include "sound.h"
 #include "game.h"
 #include "tools.h"
 #include "editor.h"
-#include "misc.h"
 #include "files.h"
-#include "buttons.h"
 #include "tape.h"
 #include "joystick.h"
 #include "cartoons.h"
@@ -85,7 +84,7 @@ void DrawMainMenu()
   UndrawSpecialEditorDoor();
 
   /* needed if last screen was the setup screen and fullscreen state changed */
-  ChangeVideoModeIfNeeded();
+  setup.fullscreen = ChangeVideoModeIfNeeded(setup.fullscreen);
 #ifdef TARGET_SDL
   SetDrawtoField(DRAW_BACKBUFFER);
 #endif
@@ -1500,7 +1499,7 @@ void HandleSetupScreen(int mx, int my, int dx, int dy, int button)
        setup.fading = !setup.fading;
       }
 #endif
-      else if (y == 8 && fullscreen_available)
+      else if (y == 8 && video.fullscreen_available)
       {
        if (setup.fullscreen)
          DrawText(SX+14*32, SY+yy*32,"off",FS_BIG,FC_BLUE);
diff --git a/src/sdl.c b/src/sdl.c
deleted file mode 100644 (file)
index 6e4b781..0000000
--- a/src/sdl.c
+++ /dev/null
@@ -1,214 +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             *
-*----------------------------------------------------------*
-*  sdl.c                                                   *
-***********************************************************/
-
-#ifdef TARGET_SDL
-
-#include "main.h"
-#include "misc.h"
-
-inline void SDLInitBufferedDisplay(DrawBuffer *backbuffer, DrawWindow *window)
-{
-  /* initialize SDL video */
-  if (SDL_Init(SDL_INIT_VIDEO) < 0)
-    Error(ERR_EXIT, "SDL_Init() failed: %s", SDL_GetError());
-
-  /* automatically cleanup SDL stuff after exit() */
-  atexit(SDL_Quit);
-
-  /* open SDL video output device (window or fullscreen mode) */
-  if (!SDLSetVideoMode(backbuffer))
-    Error(ERR_EXIT, "setting video mode failed");
-
-  /* set window and icon title */
-  SDL_WM_SetCaption(WINDOW_TITLE_STRING, WINDOW_TITLE_STRING);
-
-  /* create additional buffer for double-buffering */
-  pix[PIX_DB_BACK] = CreateBitmap(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH);
-
-  /* SDL cannot directly draw to the visible video framebuffer like X11,
-     but always uses a backbuffer, which is then blitted to the visible
-     video framebuffer with 'SDL_UpdateRect' (or replaced with the current
-     visible video framebuffer with 'SDL_Flip', if the hardware supports
-     this). Therefore do not use an additional backbuffer for drawing, but
-     use a symbolic buffer (distinguishable from the SDL backbuffer) called
-     'window', which indicates that the SDL backbuffer should be updated to
-     the visible video framebuffer when attempting to blit to it.
-
-     For convenience, it seems to be a good idea to create this symbolic
-     buffer 'window' at the same size as the SDL backbuffer. Although it
-     should never be drawn to directly, it would do no harm nevertheless. */
-
-  *window = pix[PIX_DB_BACK];          /* 'window' is only symbolic buffer */
-  pix[PIX_DB_BACK] = *backbuffer;      /* 'backbuffer' is SDL screen buffer */
-}
-
-inline boolean SDLSetVideoMode(DrawBuffer *backbuffer)
-{
-  boolean success = TRUE;
-
-  if (setup.fullscreen && !fullscreen_enabled && fullscreen_available)
-  {
-    /* switch display to fullscreen mode, if available */
-    DrawWindow window_old = *backbuffer;
-    DrawWindow window_new;
-
-    if ((window_new = SDL_SetVideoMode(WIN_XSIZE, WIN_YSIZE, WIN_SDL_DEPTH,
-                                      SDL_HWSURFACE|SDL_FULLSCREEN))
-       == NULL)
-    {
-      /* switching display to fullscreen mode failed */
-      Error(ERR_WARN, "SDL_SetVideoMode() failed: %s", SDL_GetError());
-
-      /* do not try it again */
-      fullscreen_available = FALSE;
-      success = FALSE;
-    }
-    else
-    {
-      if (window_old)
-       SDL_FreeSurface(window_old);
-      *backbuffer = window_new;
-
-      fullscreen_enabled = TRUE;
-      success = TRUE;
-    }
-  }
-
-  if ((!setup.fullscreen && fullscreen_enabled) || !*backbuffer)
-  {
-    /* switch display to window mode */
-    DrawWindow window_old = *backbuffer;
-    DrawWindow window_new;
-
-    if ((window_new = SDL_SetVideoMode(WIN_XSIZE, WIN_YSIZE, WIN_SDL_DEPTH,
-                                      SDL_HWSURFACE))
-       == NULL)
-    {
-      /* switching display to window mode failed -- should not happen */
-      Error(ERR_WARN, "SDL_SetVideoMode() failed: %s", SDL_GetError());
-
-      success = FALSE;
-    }
-    else
-    {
-      if (window_old)
-       SDL_FreeSurface(window_old);
-      *backbuffer = window_new;
-
-      fullscreen_enabled = FALSE;
-      success = TRUE;
-    }
-  }
-
-  return success;
-}
-
-inline void SDLCopyArea(SDL_Surface *src_surface, SDL_Surface *dst_surface,
-                       int src_x, int src_y,
-                       int width, int height,
-                       int dst_x, int dst_y)
-{
-  SDL_Surface *surface = (dst_surface == window ? backbuffer : dst_surface);
-  SDL_Rect src_rect, dst_rect;
-
-  src_rect.x = src_x;
-  src_rect.y = src_y;
-  src_rect.w = width;
-  src_rect.h = height;
-
-  dst_rect.x = dst_x;
-  dst_rect.y = dst_y;
-  dst_rect.w = width;
-  dst_rect.h = height;
-
-  if (src_surface != backbuffer || dst_surface != window)
-    SDL_BlitSurface(src_surface, &src_rect, surface, &dst_rect);
-
-  if (dst_surface == window)
-    SDL_UpdateRect(backbuffer, dst_x, dst_y, width, height);
-}
-
-inline void SDLFillRectangle(SDL_Surface *dst_surface, int x, int y,
-                            int width, int height, unsigned int color)
-{
-  SDL_Surface *surface = (dst_surface == window ? backbuffer : dst_surface);
-  SDL_Rect rect;
-  unsigned int color_r = (color >> 16) && 0xff;
-  unsigned int color_g = (color >>  8) && 0xff;
-  unsigned int color_b = (color >>  0) && 0xff;
-
-  rect.x = x;
-  rect.y = y;
-  rect.w = width;
-  rect.h = height;
-
-  SDL_FillRect(surface, &rect,
-              SDL_MapRGB(surface->format, color_r, color_g, color_b));
-
-  if (dst_surface == window)
-    SDL_UpdateRect(backbuffer, x, y, width, height);
-}
-
-inline void SDLDrawSimpleLine(SDL_Surface *surface, int from_x, int from_y,
-                             int to_x, int to_y, unsigned int color)
-{
-  SDL_Rect rect;
-  unsigned int color_r = (color >> 16) & 0xff;
-  unsigned int color_g = (color >>  8) & 0xff;
-  unsigned int color_b = (color >>  0) & 0xff;
-
-  if (from_x > to_x)
-    swap_numbers(&from_x, &to_x);
-
-  if (from_y > to_y)
-    swap_numbers(&from_y, &to_y);
-
-  rect.x = from_x;
-  rect.y = from_y;
-  rect.w = (to_x - from_x + 1);
-  rect.h = (to_y - from_y + 1);
-
-  SDL_FillRect(surface, &rect,
-               SDL_MapRGB(surface->format, color_r, color_g, color_b));
-}
-
-inline boolean SDLOpenAudio(void)
-{
-  if (SDL_Init(SDL_INIT_AUDIO) < 0)
-  {
-    Error(ERR_WARN, "SDL_Init() failed: %s", SDL_GetError());
-    return FALSE;
-  }
-
-  if (Mix_OpenAudio(22050, AUDIO_S16, 2, 512) < 0)
-  {
-    Error(ERR_WARN, "Mix_OpenAudio() failed: %s", SDL_GetError());
-    return FALSE;
-  }
-
-  Mix_Volume(-1, SDL_MIX_MAXVOLUME / 4);
-  Mix_VolumeMusic(SDL_MIX_MAXVOLUME / 4);
-
-  return TRUE;
-}
-
-inline void SDLCloseAudio(void)
-{
-  Mix_HaltMusic();
-  Mix_HaltChannel(-1);
-
-  Mix_CloseAudio();
-}
-
-#endif /* TARGET_SDL */
diff --git a/src/sdl.h b/src/sdl.h
deleted file mode 100644 (file)
index cd503c1..0000000
--- a/src/sdl.h
+++ /dev/null
@@ -1,309 +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             *
-*----------------------------------------------------------*
-*  sdl.h                                                   *
-***********************************************************/
-
-#ifndef SDL_H
-#define SDL_H
-
-#include "SDL.h"
-#include "SDL_image.h"
-#include "SDL_mixer.h"
-
-
-/* definitions needed for "system.c" */
-
-#define SURFACE_FLAGS          (SDL_SWSURFACE)
-
-
-/* system dependent definitions */
-
-#define TARGET_STRING          "SDL"
-#define FULLSCREEN_STATUS      FULLSCREEN_AVAILABLE
-
-
-/* SDL type definitions */
-
-typedef SDL_Surface           *Bitmap;
-typedef SDL_Surface           *DrawWindow;
-typedef SDL_Surface           *DrawBuffer;
-
-typedef SDLKey                 Key;
-
-typedef SDL_Event              Event;
-typedef SDL_MouseButtonEvent   ButtonEvent;
-typedef SDL_MouseMotionEvent   MotionEvent;
-typedef SDL_KeyboardEvent      KeyEvent;
-typedef SDL_Event              ExposeEvent;
-typedef SDL_Event              FocusChangeEvent;
-typedef SDL_Event              ClientMessageEvent;
-
-typedef int                    GC;
-typedef int                    Pixmap;
-typedef int                    Display;
-typedef int                    Visual;
-typedef int                    Colormap;
-
-
-/* SDL symbol definitions */
-
-#define None                   0L
-
-#define EVENT_BUTTONPRESS      SDL_MOUSEBUTTONDOWN
-#define EVENT_BUTTONRELEASE    SDL_MOUSEBUTTONUP
-#define EVENT_MOTIONNOTIFY     SDL_MOUSEMOTION
-#define EVENT_KEYPRESS         SDL_KEYDOWN
-#define EVENT_KEYRELEASE       SDL_KEYUP
-#define EVENT_EXPOSE           SDL_USEREVENT + 0
-#define EVENT_FOCUSIN          SDL_USEREVENT + 1
-#define EVENT_FOCUSOUT         SDL_USEREVENT + 2
-#define EVENT_CLIENTMESSAGE    SDL_QUIT
-#define EVENT_MAPNOTIFY                SDL_USEREVENT + 4
-#define EVENT_UNMAPNOTIFY      SDL_USEREVENT + 5
-
-#define KSYM_UNDEFINED         SDLK_UNKNOWN
-
-#define KSYM_Return            SDLK_RETURN
-#define KSYM_Escape            SDLK_ESCAPE
-
-#define KSYM_Left              SDLK_LEFT
-#define KSYM_Right             SDLK_RIGHT
-#define KSYM_Up                        SDLK_UP
-#define KSYM_Down              SDLK_DOWN
-
-#ifdef SDLK_KP_LEFT
-#define KSYM_KP_Left           SDLK_KP_LEFT
-#define KSYM_KP_Right          SDLK_KP_RIGHT
-#define KSYM_KP_Up             SDLK_KP_UP
-#define KSYM_KP_Down           SDLK_KP_DOWN
-#endif
-
-#define KSYM_KP_Enter          SDLK_KP_ENTER
-#define KSYM_KP_Add            SDLK_KP_PLUS
-#define KSYM_KP_Subtract       SDLK_KP_MINUS
-#define KSYM_KP_Multiply       SDLK_KP_MULTIPLY
-#define KSYM_KP_Divide         SDLK_KP_DIVIDE
-#define KSYM_KP_Separator      SDLK_KP_PERIOD
-
-#define KSYM_Shift_L           SDLK_LSHIFT
-#define KSYM_Shift_R           SDLK_RSHIFT
-#define KSYM_Control_L         SDLK_LCTRL
-#define KSYM_Control_R         SDLK_RCTRL
-#define KSYM_Meta_L            SDLK_LMETA
-#define KSYM_Meta_R            SDLK_RMETA
-#define KSYM_Alt_L             SDLK_LALT
-#define KSYM_Alt_R             SDLK_RALT
-#define KSYM_Super_L           SDLK_LSUPER
-#define KSYM_Super_R           SDLK_RSUPER
-#define KSYM_Mode_switch       SDLK_MODE
-#define KSYM_Multi_key         SDLK_RCTRL
-
-#define KSYM_BackSpace         SDLK_BACKSPACE
-#define KSYM_Delete            SDLK_DELETE
-#define KSYM_Insert            SDLK_INSERT
-#define KSYM_Tab               SDLK_TAB
-#define KSYM_Home              SDLK_HOME
-#define KSYM_End               SDLK_END
-#define KSYM_Page_Up           SDLK_PAGEUP
-#define KSYM_Page_Down         SDLK_PAGEDOWN
-#define KSYM_Menu              SDLK_MENU
-
-#define KSYM_space             SDLK_SPACE
-#define KSYM_exclam            SDLK_EXCLAIM
-#define KSYM_quotedbl          SDLK_QUOTEDBL
-#define KSYM_numbersign                SDLK_HASH
-#define KSYM_dollar            SDLK_DOLLAR
-#define KSYM_percent           KSYM_UNDEFINED          /* undefined */
-#define KSYM_ampersand         SDLK_AMPERSAND
-#define KSYM_apostrophe                SDLK_QUOTE
-#define KSYM_parenleft         SDLK_LEFTPAREN
-#define KSYM_parenright                SDLK_RIGHTPAREN
-#define KSYM_asterisk          SDLK_ASTERISK
-#define KSYM_plus              SDLK_PLUS
-#define KSYM_comma             SDLK_COMMA
-#define KSYM_minus             SDLK_MINUS
-#define KSYM_period            SDLK_PERIOD
-#define KSYM_slash             SDLK_SLASH
-
-#define KSYM_colon             SDLK_COLON
-#define KSYM_semicolon         SDLK_SEMICOLON
-#define KSYM_less              SDLK_LESS
-#define KSYM_equal             SDLK_EQUALS
-#define KSYM_greater           SDLK_GREATER
-#define KSYM_question          SDLK_QUESTION
-#define KSYM_at                        SDLK_AT
-
-#define KSYM_bracketleft       SDLK_LEFTBRACKET
-#define KSYM_backslash         SDLK_BACKSLASH
-#define KSYM_bracketright      SDLK_RIGHTBRACKET
-#define KSYM_asciicircum       SDLK_CARET
-#define KSYM_underscore                SDLK_UNDERSCORE
-#define KSYM_grave             SDLK_BACKQUOTE
-
-#define KSYM_quoteleft         KSYM_UNDEFINED          /* undefined */
-#define KSYM_braceleft         KSYM_UNDEFINED          /* undefined */
-#define KSYM_bar               KSYM_UNDEFINED          /* undefined */
-#define KSYM_braceright                KSYM_UNDEFINED          /* undefined */
-#define KSYM_asciitilde                KSYM_UNDEFINED          /* undefined */
-
-#define KSYM_Adiaeresis                SDLK_WORLD_36
-#define KSYM_Odiaeresis                SDLK_WORLD_54
-#define KSYM_Udiaeresis                SDLK_WORLD_60
-#define KSYM_adiaeresis                SDLK_WORLD_68
-#define KSYM_odiaeresis                SDLK_WORLD_86
-#define KSYM_udiaeresis                SDLK_WORLD_92
-#define KSYM_ssharp            SDLK_WORLD_63
-
-#ifndef SDLK_A
-#define SDLK_A                 65
-#define SDLK_B                 66
-#define SDLK_C                 67
-#define SDLK_D                 68
-#define SDLK_E                 69
-#define SDLK_F                 70
-#define SDLK_G                 71
-#define SDLK_H                 72
-#define SDLK_I                 73
-#define SDLK_J                 74
-#define SDLK_K                 75
-#define SDLK_L                 76
-#define SDLK_M                 77
-#define SDLK_N                 78
-#define SDLK_O                 79
-#define SDLK_P                 80
-#define SDLK_Q                 81
-#define SDLK_R                 82
-#define SDLK_S                 83
-#define SDLK_T                 84
-#define SDLK_U                 85
-#define SDLK_V                 86
-#define SDLK_W                 87
-#define SDLK_X                 88
-#define SDLK_Y                 89
-#define SDLK_Z                 90
-#endif
-
-#define KSYM_A                 SDLK_A
-#define KSYM_B                 SDLK_B
-#define KSYM_C                 SDLK_C
-#define KSYM_D                 SDLK_D
-#define KSYM_E                 SDLK_E
-#define KSYM_F                 SDLK_F
-#define KSYM_G                 SDLK_G
-#define KSYM_H                 SDLK_H
-#define KSYM_I                 SDLK_I
-#define KSYM_J                 SDLK_J
-#define KSYM_K                 SDLK_K
-#define KSYM_L                 SDLK_L
-#define KSYM_M                 SDLK_M
-#define KSYM_N                 SDLK_N
-#define KSYM_O                 SDLK_O
-#define KSYM_P                 SDLK_P
-#define KSYM_Q                 SDLK_Q
-#define KSYM_R                 SDLK_R
-#define KSYM_S                 SDLK_S
-#define KSYM_T                 SDLK_T
-#define KSYM_U                 SDLK_U
-#define KSYM_V                 SDLK_V
-#define KSYM_W                 SDLK_W
-#define KSYM_X                 SDLK_X
-#define KSYM_Y                 SDLK_Y
-#define KSYM_Z                 SDLK_Z
-
-#define KSYM_a                 SDLK_a
-#define KSYM_b                 SDLK_b
-#define KSYM_c                 SDLK_c
-#define KSYM_d                 SDLK_d
-#define KSYM_e                 SDLK_e
-#define KSYM_f                 SDLK_f
-#define KSYM_g                 SDLK_g
-#define KSYM_h                 SDLK_h
-#define KSYM_i                 SDLK_i
-#define KSYM_j                 SDLK_j
-#define KSYM_k                 SDLK_k
-#define KSYM_l                 SDLK_l
-#define KSYM_m                 SDLK_m
-#define KSYM_n                 SDLK_n
-#define KSYM_o                 SDLK_o
-#define KSYM_p                 SDLK_p
-#define KSYM_q                 SDLK_q
-#define KSYM_r                 SDLK_r
-#define KSYM_s                 SDLK_s
-#define KSYM_t                 SDLK_t
-#define KSYM_u                 SDLK_u
-#define KSYM_v                 SDLK_v
-#define KSYM_w                 SDLK_w
-#define KSYM_x                 SDLK_x
-#define KSYM_y                 SDLK_y
-#define KSYM_z                 SDLK_z
-
-#define KSYM_0                 SDLK_0
-#define KSYM_1                 SDLK_1
-#define KSYM_2                 SDLK_2
-#define KSYM_3                 SDLK_3
-#define KSYM_4                 SDLK_4
-#define KSYM_5                 SDLK_5
-#define KSYM_6                 SDLK_6
-#define KSYM_7                 SDLK_7
-#define KSYM_8                 SDLK_8
-#define KSYM_9                 SDLK_9
-
-#define KSYM_KP_0              SDLK_KP0
-#define KSYM_KP_1              SDLK_KP1
-#define KSYM_KP_2              SDLK_KP2
-#define KSYM_KP_3              SDLK_KP3
-#define KSYM_KP_4              SDLK_KP4
-#define KSYM_KP_5              SDLK_KP5
-#define KSYM_KP_6              SDLK_KP6
-#define KSYM_KP_7              SDLK_KP7
-#define KSYM_KP_8              SDLK_KP8
-#define KSYM_KP_9              SDLK_KP9
-
-#define KSYM_F1                        SDLK_F1
-#define KSYM_F2                        SDLK_F2
-#define KSYM_F3                        SDLK_F3
-#define KSYM_F4                        SDLK_F4
-#define KSYM_F5                        SDLK_F5
-#define KSYM_F6                        SDLK_F6
-#define KSYM_F7                        SDLK_F7
-#define KSYM_F8                        SDLK_F8
-#define KSYM_F9                        SDLK_F9
-#define KSYM_F10               SDLK_F10
-#define KSYM_F11               SDLK_F11
-#define KSYM_F12               SDLK_F12
-#define KSYM_F13               SDLK_F13
-#define KSYM_F14               SDLK_F14
-#define KSYM_F15               SDLK_F15
-#define KSYM_F16               KSYM_UNDEFINED
-#define KSYM_F17               KSYM_UNDEFINED
-#define KSYM_F18               KSYM_UNDEFINED
-#define KSYM_F19               KSYM_UNDEFINED
-#define KSYM_F20               KSYM_UNDEFINED
-#define KSYM_F21               KSYM_UNDEFINED
-#define KSYM_F22               KSYM_UNDEFINED
-#define KSYM_F23               KSYM_UNDEFINED
-#define KSYM_F24               KSYM_UNDEFINED
-
-
-/* SDL function definitions */
-
-inline void SDLInitBufferedDisplay(DrawBuffer *, DrawWindow *);
-inline boolean SDLSetVideoMode(DrawBuffer *);
-inline void SDLCopyArea(SDL_Surface *, SDL_Surface *,
-                        int, int, int, int, int, int);
-inline void SDLFillRectangle(SDL_Surface *, int, int, int, int, unsigned int);
-inline void SDLDrawSimpleLine(SDL_Surface *, int, int, int, int, unsigned int);
-
-inline boolean SDLOpenAudio(void);
-inline void SDLCloseAudio(void);
-
-#endif /* SDL_H */
diff --git a/src/sound.c b/src/sound.c
deleted file mode 100644 (file)
index 91da5d7..0000000
+++ /dev/null
@@ -1,1027 +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                *
-*----------------------------------------------------------*
-*  sound.c                                                 *
-***********************************************************/
-
-#include "sound.h"
-#include "misc.h"
-
-/*** THE STUFF BELOW IS ONLY USED BY THE SOUND SERVER CHILD PROCESS ***/
-
-static int playing_sounds = 0;
-static struct SoundControl playlist[MAX_SOUNDS_PLAYING];
-static struct SoundControl emptySoundControl =
-{
-  -1,0,0, FALSE,FALSE,FALSE,FALSE,FALSE, 0,0L,0L,NULL
-};
-
-#if defined(PLATFORM_UNIX)
-static int stereo_volume[PSND_MAX_LEFT2RIGHT+1];
-static char premix_first_buffer[SND_BLOCKSIZE];
-#if defined(AUDIO_STREAMING_DSP)
-static char premix_left_buffer[SND_BLOCKSIZE];
-static char premix_right_buffer[SND_BLOCKSIZE];
-static int premix_last_buffer[SND_BLOCKSIZE];
-#endif
-static unsigned char playing_buffer[SND_BLOCKSIZE];
-#endif
-
-/* forward declaration of internal functions */
-#if defined(AUDIO_STREAMING_DSP)
-static void SoundServer_InsertNewSound(struct SoundControl);
-#elif defined(PLATFORM_UNIX)
-static unsigned char linear_to_ulaw(int);
-static int ulaw_to_linear(unsigned char);
-#endif
-
-#if defined(PLATFORM_HPUX)
-static void HPUX_Audio_Control();
-#endif
-
-#if defined(PLATFORM_MSDOS)
-static void SoundServer_InsertNewSound(struct SoundControl);
-static void SoundServer_StopSound(int);
-static void SoundServer_StopAllSounds();
-#endif
-
-#if defined(PLATFORM_UNIX)
-int OpenAudioDevice(char *audio_device_name)
-{
-  int audio_fd;
-
-  /* check if desired audio device is accessible */
-  if (access(sound_device_name, W_OK) != 0)
-    return -1;
-
-  /* try to open audio device in non-blocking mode */
-  if ((audio_fd = open(audio_device_name, O_WRONLY | O_NONBLOCK)) < 0)
-    return audio_fd;
-
-  /* re-open audio device in blocking mode */
-  close(audio_fd);
-  audio_fd = open(audio_device_name, O_WRONLY);
-
-  return audio_fd;
-}
-
-void UnixOpenAudio(struct AudioSystemInfo *audio)
-{
-  static char *audio_device_name[] =
-  {
-    DEVICENAME_DSP,
-    DEVICENAME_AUDIO
-  };
-  int audio_fd;
-  int i;
-
-  /* look for available audio devices, starting with preferred ones */
-  for (i=0; i<sizeof(audio_device_name)/sizeof(char *); i++)
-    if ((audio_fd = OpenAudioDevice(sound_device_name)) >= 0)
-      break;
-
-  if (audio_fd < 0)
-  {
-    Error(ERR_WARN, "cannot open audio device - no sound");
-    return;
-  }
-
-  close(audio_fd);
-
-  audio->sound_available = TRUE;
-
-#if defined(AUDIO_STREAMING_DSP)
-  audio->loops_available = TRUE;
-#endif
-}
-
-void UnixCloseAudio(struct AudioSystemInfo *audio)
-{
-  if (audio->device_fd)
-    close(audio->device_fd);
-}
-
-#endif /* PLATFORM_UNIX */
-
-void SoundServer()
-{
-  int i;
-#if defined(PLATFORM_UNIX)
-  struct SoundControl snd_ctrl;
-  fd_set sound_fdset;
-
-  close(audio.soundserver_pipe[1]);    /* no writing into pipe needed */
-#endif
-
-  for(i=0;i<MAX_SOUNDS_PLAYING;i++)
-    playlist[i] = emptySoundControl;
-  playing_sounds = 0;
-
-#if defined(PLATFORM_UNIX)
-  stereo_volume[PSND_MAX_LEFT2RIGHT] = 0;
-  for(i=0;i<PSND_MAX_LEFT2RIGHT;i++)
-    stereo_volume[i] =
-      (int)sqrt((float)(PSND_MAX_LEFT2RIGHT*PSND_MAX_LEFT2RIGHT-i*i));
-
-#if defined(PLATFORM_HPUX)
-  HPUX_Audio_Control();
-#endif
-
-  FD_ZERO(&sound_fdset); 
-  FD_SET(audio.soundserver_pipe[0], &sound_fdset);
-
-  while(1)     /* wait for sound playing commands from client */
-  {
-    FD_SET(audio.soundserver_pipe[0], &sound_fdset);
-    select(audio.soundserver_pipe[0] + 1, &sound_fdset, NULL, NULL, NULL);
-    if (!FD_ISSET(audio.soundserver_pipe[0], &sound_fdset))
-      continue;
-    if (read(audio.soundserver_pipe[0], &snd_ctrl, sizeof(snd_ctrl))
-       != sizeof(snd_ctrl))
-      Error(ERR_EXIT_SOUND_SERVER, "broken pipe - no sounds");
-
-#if defined(AUDIO_STREAMING_DSP)
-
-    if (snd_ctrl.fade_sound)
-    {
-      if (!playing_sounds)
-       continue;
-
-      for(i=0;i<MAX_SOUNDS_PLAYING;i++)
-       if (snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr)
-         playlist[i].fade_sound = TRUE;
-    }
-    else if (snd_ctrl.stop_all_sounds)
-    {
-      if (!playing_sounds)
-       continue;
-
-      for(i=0;i<MAX_SOUNDS_PLAYING;i++)
-       playlist[i]=emptySoundControl;
-      playing_sounds=0;
-
-      close(audio.device_fd);
-    }
-    else if (snd_ctrl.stop_sound)
-    {
-      if (!playing_sounds)
-       continue;
-
-      for(i=0;i<MAX_SOUNDS_PLAYING;i++)
-       if (playlist[i].nr == snd_ctrl.nr)
-       {
-         playlist[i]=emptySoundControl;
-         playing_sounds--;
-       }
-
-      if (!playing_sounds)
-       close(audio.device_fd);
-    }
-
-    if (playing_sounds || snd_ctrl.active)
-    {
-      struct timeval delay = { 0, 0 };
-      byte *sample_ptr;
-      long sample_size;
-      static long max_sample_size = 0;
-      static long fragment_size = 0;
-      /* Even if the stereo flag is used as being boolean, it must be
-        defined as an integer, else 'ioctl()' will fail! */
-      int stereo = TRUE;
-#if 0
-      int sample_rate = 8000;
-#else
-      int sample_rate = 22050;
-#endif
-
-      if (playing_sounds ||
-         (audio.device_fd = OpenAudioDevice(sound_device_name)) >= 0)
-      {
-       if (!playing_sounds)    /* we just opened the audio device */
-       {
-         /* 2 buffers / 512 bytes, giving 1/16 second resolution */
-         /* (with stereo the effective buffer size will shrink to 256) */
-         fragment_size = 0x00020009;
-
-         if (ioctl(audio.device_fd,SNDCTL_DSP_SETFRAGMENT,&fragment_size) < 0)
-           Error(ERR_EXIT_SOUND_SERVER,
-                 "cannot set fragment size of /dev/dsp - no sounds");
-
-         /* try if we can use stereo sound */
-         if (ioctl(audio.device_fd, SNDCTL_DSP_STEREO, &stereo) < 0)
-         {
-#ifdef DEBUG
-           static boolean reported = FALSE;
-
-           if (!reported)
-           {
-             Error(ERR_RETURN, "cannot get stereo sound on /dev/dsp");
-             reported = TRUE;
-           }
-#endif
-           stereo = FALSE;
-         }
-
-         if (ioctl(audio.device_fd, SNDCTL_DSP_SPEED, &sample_rate) < 0)
-           Error(ERR_EXIT_SOUND_SERVER,
-                 "cannot set sample rate of /dev/dsp - no sounds");
-
-         /* get the real fragmentation size; this should return 512 */
-         if (ioctl(audio.device_fd, SNDCTL_DSP_GETBLKSIZE,&fragment_size) < 0)
-           Error(ERR_EXIT_SOUND_SERVER,
-                 "cannot get fragment size of /dev/dsp - no sounds");
-
-         max_sample_size = fragment_size / (stereo ? 2 : 1);
-       }
-
-       if (snd_ctrl.active)    /* new sound has arrived */
-         SoundServer_InsertNewSound(snd_ctrl);
-
-       while(playing_sounds &&
-             select(audio.soundserver_pipe[0] + 1,
-                    &sound_fdset, NULL, NULL, &delay) < 1)
-       {       
-         FD_SET(audio.soundserver_pipe[0], &sound_fdset);
-
-         /* first clear the last premixing buffer */
-         memset(premix_last_buffer,0,fragment_size*sizeof(int));
-
-         for(i=0;i<MAX_SOUNDS_PLAYING;i++)
-         {
-           int j;
-
-           if (!playlist[i].active)
-             continue;
-
-           /* get pointer and size of the actual sound sample */
-           sample_ptr = playlist[i].data_ptr+playlist[i].playingpos;
-           sample_size =
-             MIN(max_sample_size,playlist[i].data_len-playlist[i].playingpos);
-           playlist[i].playingpos += sample_size;
-
-           /* fill the first mixing buffer with original sample */
-           memcpy(premix_first_buffer,sample_ptr,sample_size);
-
-           /* are we about to restart a looping sound? */
-           if (playlist[i].loop && sample_size<max_sample_size)
-           {
-             playlist[i].playingpos = max_sample_size-sample_size;
-             memcpy(premix_first_buffer+sample_size,
-                    playlist[i].data_ptr,max_sample_size-sample_size);
-             sample_size = max_sample_size;
-           }
-
-           /* decrease volume if sound is fading out */
-           if (playlist[i].fade_sound &&
-               playlist[i].volume>=PSND_MAX_VOLUME/10)
-             playlist[i].volume-=PSND_MAX_VOLUME/20;
-
-           /* adjust volume of actual sound sample */
-           if (playlist[i].volume != PSND_MAX_VOLUME)
-             for(j=0;j<sample_size;j++)
-               premix_first_buffer[j] =
-                 (playlist[i].volume * (int)premix_first_buffer[j])
-                   >> PSND_MAX_VOLUME_BITS;
-
-           /* fill the last mixing buffer with stereo or mono sound */
-           if (stereo)
-           {
-             int middle_pos = PSND_MAX_LEFT2RIGHT/2;
-             int left_volume = stereo_volume[middle_pos+playlist[i].stereo];
-             int right_volume = stereo_volume[middle_pos-playlist[i].stereo];
-
-             for(j=0;j<sample_size;j++)
-             {
-               premix_left_buffer[j] =
-                 (left_volume * (int)premix_first_buffer[j])
-                   >> PSND_MAX_LEFT2RIGHT_BITS;
-               premix_right_buffer[j] =
-                 (right_volume * (int)premix_first_buffer[j])
-                   >> PSND_MAX_LEFT2RIGHT_BITS;
-               premix_last_buffer[2*j+0] += premix_left_buffer[j];
-               premix_last_buffer[2*j+1] += premix_right_buffer[j];
-             }
-           }
-           else
-           {
-             for(j=0;j<sample_size;j++)
-               premix_last_buffer[j] += (int)premix_first_buffer[j];
-           }
-
-           /* delete completed sound entries from the playlist */
-           if (playlist[i].playingpos >= playlist[i].data_len)
-           {
-             if (playlist[i].loop)
-               playlist[i].playingpos = 0;
-             else
-             {
-               playlist[i] = emptySoundControl;
-               playing_sounds--;
-             }
-           }
-           else if (playlist[i].volume <= PSND_MAX_VOLUME/10)
-           {
-             playlist[i] = emptySoundControl;
-             playing_sounds--;
-           }
-         }
-
-         /* put last mixing buffer to final playing buffer */
-         for(i=0;i<fragment_size;i++)
-         {
-           if (premix_last_buffer[i]<-255)
-             playing_buffer[i] = 0;
-           else if (premix_last_buffer[i]>255)
-             playing_buffer[i] = 255;
-           else
-             playing_buffer[i] = (premix_last_buffer[i]>>1)^0x80;
-         }
-
-         /* finally play the sound fragment */
-         write(audio.device_fd, playing_buffer,fragment_size);
-       }
-
-       /* if no sounds playing, free device for other sound programs */
-       if (!playing_sounds)
-         close(audio.device_fd);
-      }
-    }
-
-#else /* !AUDIO_STREAMING_DSP */
-
-    if (snd_ctrl.active && !snd_ctrl.loop)
-    {
-      struct timeval delay = { 0, 0 };
-      byte *sample_ptr;
-      long sample_size, max_sample_size = SND_BLOCKSIZE;
-      long sample_rate = 8000; /* standard "/dev/audio" sampling rate */
-      int wait_percent = 90;   /* wait 90% of the real playing time */
-      int i;
-
-      if ((audio.device_fd = OpenAudioDevice(sound_device_name)) >= 0)
-      {
-       playing_sounds = 1;
-
-       while(playing_sounds &&
-             select(audio.soundserver_pipe[0] + 1,
-                    &sound_fdset, NULL, NULL, &delay) < 1)
-       {       
-         FD_SET(audio.soundserver_pipe[0], &sound_fdset);
-
-         /* get pointer and size of the actual sound sample */
-         sample_ptr = snd_ctrl.data_ptr + snd_ctrl.playingpos;
-         sample_size =
-           MIN(max_sample_size, snd_ctrl.data_len - snd_ctrl.playingpos);
-         snd_ctrl.playingpos += sample_size;
-
-         /* fill the first mixing buffer with original sample */
-         memcpy(premix_first_buffer,sample_ptr,sample_size);
-
-
-         /* adjust volume of actual sound sample */
-         if (snd_ctrl.volume != PSND_MAX_VOLUME)
-           for(i=0;i<sample_size;i++)
-             premix_first_buffer[i] =
-               (snd_ctrl.volume * (int)premix_first_buffer[i])
-                 >> PSND_MAX_VOLUME_BITS;
-
-         for(i=0;i<sample_size;i++)
-           playing_buffer[i] =
-             linear_to_ulaw(((int)premix_first_buffer[i]) << 8);
-
-         if (snd_ctrl.playingpos >= snd_ctrl.data_len)
-           playing_sounds = 0;
-
-         /* finally play the sound fragment */
-         write(audio.device_fd,playing_buffer,sample_size);
-
-         delay.tv_sec = 0;
-         delay.tv_usec = ((sample_size*10*wait_percent)/(sample_rate))*1000;
-       }
-       close(audio.device_fd);
-      }
-    }
-
-#endif /* !AUDIO_STREAMING_DSP */
-
-  }
-
-#endif /* PLATFORM_UNIX */
-
-}
-
-#if defined(PLATFORM_MSDOS)
-static 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);
-}
-#endif /* PLATFORM_MSDOS */
-
-#if !defined(PLATFORM_WIN32)
-static void SoundServer_InsertNewSound(struct SoundControl snd_ctrl)
-{
-  int i, k;
-
-  /* if playlist is full, remove oldest sound */
-  if (playing_sounds==MAX_SOUNDS_PLAYING)
-  {
-    int longest=0, longest_nr=0;
-
-    for(i=0;i<MAX_SOUNDS_PLAYING;i++)
-    {
-#if !defined(PLATFORM_MSDOS)
-      int actual = 100 * playlist[i].playingpos / playlist[i].data_len;
-#else
-      int actual = playlist[i].playingpos;
-#endif
-
-      if (!playlist[i].loop && actual>longest)
-      {
-       longest=actual;
-       longest_nr=i;
-      }
-    }
-#if defined(PLATFORM_MSDOS)
-    voice_set_volume(playlist[longest_nr].voice, 0);
-    deallocate_voice(playlist[longest_nr].voice);
-#endif
-    playlist[longest_nr] = emptySoundControl;
-    playing_sounds--;
-  }
-
-  /* check if sound is already being played (and how often) */
-  for(k=0,i=0;i<MAX_SOUNDS_PLAYING;i++)
-  {
-    if (playlist[i].nr == snd_ctrl.nr)
-      k++;
-  }
-
-  /* restart loop sounds only if they are just fading out */
-  if (k>=1 && snd_ctrl.loop)
-  {
-    for(i=0;i<MAX_SOUNDS_PLAYING;i++)
-    {
-      if (playlist[i].nr == snd_ctrl.nr && playlist[i].fade_sound)
-      {
-       playlist[i].fade_sound = FALSE;
-       playlist[i].volume = PSND_MAX_VOLUME;
-#if defined(PLATFORM_MSDOS)
-        playlist[i].loop = PSND_LOOP;
-        voice_stop_volumeramp(playlist[i].voice);
-        voice_ramp_volume(playlist[i].voice, playlist[i].volume, 1000);
-#endif
-      }
-    }
-    return;
-  }
-
-  /* don't play sound more than n times simultaneously (with n == 2 for now) */
-  if (k>=2)
-  {
-    int longest=0, longest_nr=0;
-
-    /* look for oldest equal sound */
-    for(i=0;i<MAX_SOUNDS_PLAYING;i++)
-    {
-      int actual;
-
-      if (!playlist[i].active || playlist[i].nr != snd_ctrl.nr)
-       continue;
-
-#if !defined(PLATFORM_MSDOS)
-      actual = 100 * playlist[i].playingpos / playlist[i].data_len;
-#else
-      actual = playlist[i].playingpos;
-#endif
-      if (actual>=longest)
-      {
-       longest=actual;
-       longest_nr=i;
-      }
-    }
-
-#if defined(PLATFORM_MSDOS)
-    voice_set_volume(playlist[longest_nr].voice, 0);
-    deallocate_voice(playlist[longest_nr].voice);
-#endif
-    playlist[longest_nr] = emptySoundControl;
-    playing_sounds--;
-  }
-
-  /* neuen Sound in Liste packen */
-  for(i=0;i<MAX_SOUNDS_PLAYING;i++)
-  {
-    if (!playlist[i].active)
-    {
-      playlist[i] = snd_ctrl;
-      playing_sounds++;
-
-#if defined(PLATFORM_MSDOS)
-      playlist[i].voice = allocate_voice(Sound[snd_ctrl.nr].sample_ptr);
-      if(snd_ctrl.loop)
-        voice_set_playmode(playlist[i].voice, PLAYMODE_LOOP);
-      voice_set_volume(playlist[i].voice, snd_ctrl.volume);
-      voice_set_pan(playlist[i].voice, snd_ctrl.stereo);
-      voice_start(playlist[i].voice);       
-#endif
-      break;
-    }
-  }
-}
-#endif /* !PLATFORM_WIN32 */
-
-/*
-void SoundServer_FadeSound(int nr)
-{
-  int i;
-
-  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 = TRUE;
-}
-*/
-
-#if !defined(PLATFORM_WIN32)
-#if defined(PLATFORM_MSDOS)
-static void SoundServer_StopSound(int nr)
-{
-  int i;
-
-  if (!playing_sounds)
-    return;
-
-  for(i=0;i<MAX_SOUNDS_PLAYING;i++)
-    if (playlist[i].nr == nr)
-    {
-#if defined(PLATFORM_MSDOS)
-      voice_set_volume(playlist[i].voice, 0);
-      deallocate_voice(playlist[i].voice);
-#endif
-      playlist[i] = emptySoundControl;
-      playing_sounds--;
-    }
-
-#if !defined(PLATFORM_MSDOS)
-  if (!playing_sounds)
-    close(audio.device_fd);
-#endif
-}
-
-static void SoundServer_StopAllSounds()
-{
-  int i;
-
-  for(i=0;i<MAX_SOUNDS_PLAYING;i++)
-  {
-#if defined(PLATFORM_MSDOS)
-    voice_set_volume(playlist[i].voice, 0);
-    deallocate_voice(playlist[i].voice);
-#endif
-    playlist[i]=emptySoundControl;
-  }
-  playing_sounds = 0;
-
-#if !defined(PLATFORM_MSDOS)
-  close(audio.device_fd);
-#endif
-}
-#endif /* PLATFORM_MSDOS */
-#endif /* !PLATFORM_WIN32 */
-
-#if defined(PLATFORM_HPUX)
-static void HPUX_Audio_Control()
-{
-  struct audio_describe ainfo;
-  int audio_ctl;
-
-  audio_ctl = open("/dev/audioCtl", O_WRONLY | O_NDELAY);
-  if (audio_ctl == -1)
-    Error(ERR_EXIT_SOUND_SERVER, "cannot open /dev/audioCtl - no sounds");
-
-  if (ioctl(audio_ctl, AUDIO_DESCRIBE, &ainfo) == -1)
-    Error(ERR_EXIT_SOUND_SERVER, "no audio info - no sounds");
-
-  if (ioctl(audio_ctl, AUDIO_SET_DATA_FORMAT, AUDIO_FORMAT_ULAW) == -1)
-    Error(ERR_EXIT_SOUND_SERVER, "ulaw audio not available - no sounds");
-
-  ioctl(audio_ctl, AUDIO_SET_CHANNELS, 1);
-  ioctl(audio_ctl, AUDIO_SET_SAMPLE_RATE, 8000);
-
-  close(audio_ctl);
-}
-#endif /* PLATFORM_HPUX */
-
-#if defined(PLATFORM_UNIX) && !defined(AUDIO_STREAMING_DSP)
-
-/* these two are stolen from "sox"... :) */
-
-/*
-** This routine converts from linear to ulaw.
-**
-** Craig Reese: IDA/Supercomputing Research Center
-** Joe Campbell: Department of Defense
-** 29 September 1989
-**
-** References:
-** 1) CCITT Recommendation G.711  (very difficult to follow)
-** 2) "A New Digital Technique for Implementation of Any
-**     Continuous PCM Companding Law," Villeret, Michel,
-**     et al. 1973 IEEE Int. Conf. on Communications, Vol 1,
-**     1973, pg. 11.12-11.17
-** 3) MIL-STD-188-113,"Interoperability and Performance Standards
-**     for Analog-to_Digital Conversion Techniques,"
-**     17 February 1987
-**
-** Input: Signed 16 bit linear sample
-** Output: 8 bit ulaw sample
-*/
-
-#define ZEROTRAP    /* turn on the trap as per the MIL-STD */
-#define BIAS 0x84   /* define the add-in bias for 16 bit samples */
-#define CLIP 32635
-
-static unsigned char linear_to_ulaw(int sample)
-{
-  static int exp_lut[256] =
-  {
-    0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,
-    4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
-    5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-    5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
-    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
-    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
-    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
-    6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
-    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
-    7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
-  };
-
-  int sign, exponent, mantissa;
-  unsigned char ulawbyte;
-
-  /* Get the sample into sign-magnitude. */
-  sign = (sample >> 8) & 0x80;         /* set aside the sign */
-  if (sign != 0)
-    sample = -sample;                  /* get magnitude */
-  if (sample > CLIP)
-    sample = CLIP;                     /* clip the magnitude */
-
-  /* Convert from 16 bit linear to ulaw. */
-  sample = sample + BIAS;
-  exponent = exp_lut[( sample >> 7 ) & 0xFF];
-  mantissa = ( sample >> ( exponent + 3 ) ) & 0x0F;
-  ulawbyte = ~ ( sign | ( exponent << 4 ) | mantissa );
-#ifdef ZEROTRAP
-  if (ulawbyte == 0)
-    ulawbyte = 0x02;                   /* optional CCITT trap */
-#endif
-
-  return(ulawbyte);
-}
-
-/*
-** This routine converts from ulaw to 16 bit linear.
-**
-** Craig Reese: IDA/Supercomputing Research Center
-** 29 September 1989
-**
-** References:
-** 1) CCITT Recommendation G.711  (very difficult to follow)
-** 2) MIL-STD-188-113,"Interoperability and Performance Standards
-**     for Analog-to_Digital Conversion Techniques,"
-**     17 February 1987
-**
-** Input: 8 bit ulaw sample
-** Output: signed 16 bit linear sample
-*/
-
-static int ulaw_to_linear(unsigned char ulawbyte)
-{
-  static int exp_lut[8] = { 0, 132, 396, 924, 1980, 4092, 8316, 16764 };
-  int sign, exponent, mantissa, sample;
-
-  ulawbyte = ~ ulawbyte;
-  sign = ( ulawbyte & 0x80 );
-  exponent = ( ulawbyte >> 4 ) & 0x07;
-  mantissa = ulawbyte & 0x0F;
-  sample = exp_lut[exponent] + ( mantissa << ( exponent + 3 ) );
-  if (sign != 0)
-    sample = -sample;
-
-  return(sample);
-}
-#endif /* PLATFORM_UNIX && !AUDIO_STREAMING_DSP */
-
-/*** THE STUFF ABOVE IS ONLY USED BY THE SOUND SERVER CHILD PROCESS ***/
-
-/*===========================================================================*/
-
-/*** THE STUFF BELOW IS ONLY USED BY THE MAIN PROCESS ***/
-
-#define CHUNK_ID_LEN            4       /* IFF style chunk id length */
-#define WAV_HEADER_SIZE                20      /* size of WAV file header */
-
-boolean LoadSound(struct SampleInfo *snd_info)
-{
-  char filename[256];
-  char *sound_ext = "wav";
-#if !defined(TARGET_SDL)
-#if !defined(PLATFORM_MSDOS)
-  byte sound_header_buffer[WAV_HEADER_SIZE];
-  char chunk[CHUNK_ID_LEN + 1];
-  int chunk_length, dummy;
-  FILE *file;
-  int i;
-#endif
-#endif
-
-  sprintf(filename, "%s/%s/%s.%s",
-         options.ro_base_directory, SOUNDS_DIRECTORY,
-         snd_info->name, sound_ext);
-
-#if defined(TARGET_SDL)
-
-  snd_info->mix_chunk = Mix_LoadWAV(filename);
-  if (snd_info->mix_chunk == NULL)
-  {
-    Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
-    return FALSE;
-  }
-
-#else /* !TARGET_SDL */
-
-#if !defined(PLATFORM_MSDOS)
-
-  if ((file = fopen(filename, "r")) == NULL)
-  {
-    Error(ERR_WARN, "cannot open sound file '%s' - no sounds", filename);
-    return FALSE;
-  }
-
-  /* read chunk "RIFF" */
-  getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_LITTLE_ENDIAN);
-  if (strcmp(chunk, "RIFF") != 0)
-  {
-    Error(ERR_WARN, "missing 'RIFF' chunk of sound file '%s'", filename);
-    fclose(file);
-    return FALSE;
-  }
-
-  /* read chunk "WAVE" */
-  getFileChunk(file, chunk, &dummy, BYTE_ORDER_LITTLE_ENDIAN);
-  if (strcmp(chunk, "WAVE") != 0)
-  {
-    Error(ERR_WARN, "missing 'WAVE' chunk of sound file '%s'", filename);
-    fclose(file);
-    return FALSE;
-  }
-
-  /* read header information */
-  for (i=0; i<WAV_HEADER_SIZE; i++)
-    sound_header_buffer[i] = fgetc(file);
-
-  /* read chunk "data" */
-  getFileChunk(file, chunk, &chunk_length, BYTE_ORDER_LITTLE_ENDIAN);
-  if (strcmp(chunk, "data") != 0)
-  {
-    Error(ERR_WARN, "missing 'data' chunk of sound file '%s'", filename);
-    fclose(file);
-    return FALSE;
-  }
-
-  snd_info->data_len = chunk_length;
-  snd_info->data_ptr = checked_malloc(snd_info->data_len);
-
-  /* read sound data */
-  if (fread(snd_info->data_ptr, 1, snd_info->data_len, file) !=
-      snd_info->data_len)
-  {
-    Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
-    fclose(file);
-    return FALSE;
-  }
-
-  fclose(file);
-
-  for (i=0; i<snd_info->data_len; i++)
-    snd_info->data_ptr[i] = snd_info->data_ptr[i] ^ 0x80;
-
-#else /* PLATFORM_MSDOS */
-
-  snd_info->sample_ptr = load_sample(filename);
-  if (!snd_info->sample_ptr)
-  {
-    Error(ERR_WARN, "cannot read sound file '%s' - no sounds", filename);
-    return FALSE;
-  }
-
-#endif /* PLATFORM_MSDOS */
-#endif /* !TARGET_SDL */
-
-  return TRUE;
-}
-
-void PlaySound(int nr)
-{
-  PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_NO_LOOP);
-}
-
-void PlaySoundStereo(int nr, int stereo)
-{
-  PlaySoundExt(nr, PSND_MAX_VOLUME, stereo, PSND_NO_LOOP);
-}
-
-void PlaySoundLoop(int nr)
-{
-  PlaySoundExt(nr, PSND_MAX_VOLUME, PSND_MIDDLE, PSND_LOOP);
-}
-
-void PlaySoundExt(int nr, int volume, int stereo, boolean loop)
-{
-  struct SoundControl snd_ctrl = emptySoundControl;
-
-  if (!audio.sound_available || !setup.sound)
-    return;
-
-  if (volume<PSND_MIN_VOLUME)
-    volume = PSND_MIN_VOLUME;
-  else if (volume>PSND_MAX_VOLUME)
-    volume = PSND_MAX_VOLUME;
-
-  if (stereo<PSND_MAX_LEFT)
-    stereo = PSND_MAX_LEFT;
-  else if (stereo>PSND_MAX_RIGHT)
-    stereo = PSND_MAX_RIGHT;
-
-  snd_ctrl.nr          = nr;
-  snd_ctrl.volume      = volume;
-  snd_ctrl.stereo      = stereo;
-  snd_ctrl.loop                = loop;
-  snd_ctrl.active      = TRUE;
-  snd_ctrl.data_ptr    = Sound[nr].data_ptr;
-  snd_ctrl.data_len    = Sound[nr].data_len;
-
-#if defined(TARGET_SDL)
-
-  Mix_Volume(-1, SDL_MIX_MAXVOLUME / 4);
-  Mix_VolumeMusic(SDL_MIX_MAXVOLUME / 4);
-
-  Mix_PlayChannel(-1, Sound[nr].mix_chunk, (loop ? -1 : 0));
-
-#else
-#if !defined(PLATFORM_MSDOS)
-  if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
-  {
-    Error(ERR_WARN, "cannot pipe to child process - no sounds");
-    audio.sound_available = FALSE;
-    return;
-  }
-#else
-  sound_handler(snd_ctrl);
-#endif
-#endif
-}
-
-void FadeSound(int nr)
-{
-  StopSoundExt(nr, SSND_FADE_SOUND);
-}
-
-void FadeSounds()
-{
-  StopSoundExt(-1, SSND_FADE_ALL_SOUNDS);
-}
-
-void StopSound(int nr)
-{
-  StopSoundExt(nr, SSND_STOP_SOUND);
-}
-
-void StopSounds()
-{
-  StopSoundExt(-1, SSND_STOP_ALL_SOUNDS);
-}
-
-void StopSoundExt(int nr, int method)
-{
-  struct SoundControl snd_ctrl = emptySoundControl;
-
-  if (!audio.sound_available)
-    return;
-
-  if (SSND_FADING(method))
-    snd_ctrl.fade_sound = TRUE;
-
-  if (SSND_ALL(method))
-    snd_ctrl.stop_all_sounds = TRUE;
-  else
-  {
-    snd_ctrl.nr = nr;
-    snd_ctrl.stop_sound = TRUE;
-  }
-
-#if defined(TARGET_SDL)
-
-  if (SSND_FADING(method))
-  {
-    Mix_FadeOutChannel(-1, 1000);
-    Mix_FadeOutMusic(1000);
-  }
-  else
-  {
-    Mix_HaltChannel(-1);
-    Mix_HaltMusic();
-  }
-
-#else
-#if !defined(PLATFORM_MSDOS)
-  if (write(audio.soundserver_pipe[1], &snd_ctrl, sizeof(snd_ctrl)) < 0)
-  {
-    Error(ERR_WARN, "cannot pipe to child process - no sounds");
-    audio.sound_available = FALSE;
-    return;
-  }
-#else
-  sound_handler(snd_ctrl);
-#endif
-#endif
-}
-
-void FreeSounds(int num_sounds)
-{
-  int i;
-
-  if (!audio.sound_available)
-    return;
-
-  for(i=0; i<num_sounds; i++)
-#if !defined(PLATFORM_MSDOS)
-    free(Sound[i].data_ptr);
-#else
-    destroy_sample(Sound[i].sample_ptr);
-#endif
-}
-
-/*** THE STUFF ABOVE IS ONLY USED BY THE MAIN PROCESS ***/
diff --git a/src/sound.h b/src/sound.h
deleted file mode 100644 (file)
index 16fe71d..0000000
+++ /dev/null
@@ -1,167 +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                *
-*----------------------------------------------------------*
-*  sound.c                                                 *
-***********************************************************/
-
-#ifndef SOUND_H
-#define SOUND_H
-
-#include "platform.h"
-
-#include <sys/ioctl.h>
-#include <math.h>
-
-#define SND_BLOCKSIZE 4096
-
-#if defined(PLATFORM_LINUX)
-#include <linux/soundcard.h>
-#elif defined(PLATFORM_FREEBSD)
-#include <machine/soundcard.h>
-#elif defined(PLATFORM_HPUX)
-#include <sys/audio.h>
-#undef  SND_BLOCKSIZE
-#define SND_BLOCKSIZE 32768
-#endif
-
-#include "main.h"
-
-#if defined(PLATFORM_LINUX) || defined(PLATFORM_FREEBSD) || defined(VOXWARE)
-#define AUDIO_STREAMING_DSP
-#endif
-
-#if !defined(PLATFORM_MSDOS)
-#define MAX_SOUNDS_PLAYING     16
-#else
-#define MAX_SOUNDS_PLAYING     8
-#endif
-
-/* some values for PlaySound(), StopSound() and friends */
-#if !defined(PLATFORM_MSDOS)
-#define PSND_SILENCE           0
-#define PSND_MAX_VOLUME_BITS   7
-#define PSND_MIN_VOLUME                0
-#define PSND_MAX_VOLUME                (1 << PSND_MAX_VOLUME_BITS)
-#define PSND_NO_LOOP           0
-#define PSND_LOOP              1
-#define PSND_MIDDLE            0
-#define PSND_MAX_STEREO_BITS   7
-#define PSND_MAX_STEREO                (1 << PSND_MAX_STEREO_BITS)
-#define PSND_MAX_LEFT          (-PSND_MAX_STEREO)
-#define PSND_MAX_RIGHT         (+PSND_MAX_STEREO)
-#define PSND_MAX_LEFT2RIGHT_BITS (PSND_MAX_STEREO_BITS+1)
-#define PSND_MAX_LEFT2RIGHT    (1 << PSND_MAX_LEFT2RIGHT_BITS)
-#else
-#define PSND_SILENCE           0
-#define PSND_MIN_VOLUME                0
-#define PSND_MAX_VOLUME                255
-#define PSND_NO_LOOP           0
-#define PSND_LOOP              1
-#define PSND_MAX_LEFT          0
-#define PSND_MAX_RIGHT         255
-#define PSND_MIDDLE            128
-#endif
-
-#define SSND_FADE_SOUND                (1<<0)
-#define SSND_FADE_ALL_SOUNDS   (1<<1)
-#define SSND_FADING(x)         (x & (SSND_FADE_SOUND | SSND_FADE_ALL_SOUNDS))
-#define SSND_STOP_SOUND                (1<<2)
-#define SSND_STOP_ALL_SOUNDS   (1<<3)
-#define SSND_STOPPING(x)       (x & (SSND_STOP_SOUND | SSND_STOP_ALL_SOUNDS))
-#define SSND_ALL(x)            (x&(SSND_FADE_ALL_SOUNDS|SSND_STOP_ALL_SOUNDS))
-
-/* settings for sound path, sound device, etc. */
-#ifndef SND_PATH
-#define SND_PATH       "./sounds"
-#endif
-
-#define DEVICENAME_DSP         "/dev/dsp"
-#define DEVICENAME_AUDIO       "/dev/audio"
-#define DEVICENAME_AUDIOCTL    "/dev/audioCtl"
-
-#if defined(AUDIO_STREAMING_DSP)
-#define AUDIO_DEVICE           DEVICENAME_DSP
-#else
-#define AUDIO_DEVICE   DEVICENAME_AUDIO
-#endif
-
-struct SoundHeader_SUN
-{
-  unsigned long magic;
-  unsigned long hdr_size;
-  unsigned long data_size;
-  unsigned long encoding;
-  unsigned long sample_rate;
-  unsigned long channels;
-};
-
-struct SoundHeader_8SVX
-{
-  char magic_FORM[4];
-  unsigned long chunk_size;
-  char magic_8SVX[4];
-};
-
-struct SampleInfo
-{ 
-  char *name;
-  byte *data_ptr;
-  long data_len;
-
-#if defined(PLATFORM_MSDOS)
-  SAMPLE *sample_ptr;
-#endif
-
-#if defined(TARGET_SDL)
-  Mix_Chunk *mix_chunk;
-#endif
-};
-
-struct SoundControl
-{
-  int nr;
-  int volume;
-  int stereo;
-  boolean active;
-  boolean loop;
-  boolean fade_sound;
-  boolean stop_sound;
-  boolean stop_all_sounds;
-  int playingtime;
-  long playingpos;
-  long data_len;
-  byte *data_ptr;
-
-#if defined(PLATFORM_MSDOS)
-  int voice;
-#endif
-};
-
-/* general sound functions */
-void UnixOpenAudio(struct AudioSystemInfo *);
-void UnixCloseAudio(struct AudioSystemInfo *);
-
-/* sound server functions */ 
-void SoundServer(void);
-
-/* sound client functions */
-boolean LoadSound(struct SampleInfo *);
-void PlaySound(int);
-void PlaySoundStereo(int, int);
-void PlaySoundLoop(int);
-void PlaySoundExt(int, int, int, boolean);
-void FadeSound(int);
-void FadeSounds(void);
-void StopSound(int);
-void StopSounds(void);
-void StopSoundExt(int, int);
-void FreeSounds(int);
-
-#endif
diff --git a/src/system.c b/src/system.c
deleted file mode 100644 (file)
index 37ca484..0000000
+++ /dev/null
@@ -1,359 +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             *
-*----------------------------------------------------------*
-*  system.c                                                *
-***********************************************************/
-
-#include "main.h"
-#include "misc.h"
-#include "sound.h"
-
-
-/* ========================================================================= */
-/* video functions                                                           */
-/* ========================================================================= */
-
-inline void InitBufferedDisplay(DrawBuffer *backbuffer, DrawWindow *window)
-{
-#ifdef TARGET_SDL
-  SDLInitBufferedDisplay(backbuffer, window);
-#else
-  X11InitBufferedDisplay(backbuffer, window);
-#endif
-}
-
-inline int GetDisplayDepth(void)
-{
-#ifdef TARGET_SDL
-  return SDL_GetVideoSurface()->format->BitsPerPixel;
-#else
-  return XDefaultDepth(display, screen);
-#endif
-}
-
-inline Bitmap CreateBitmap(int width, int height, int depth)
-{
-  int real_depth = (depth == DEFAULT_DEPTH ? GetDisplayDepth() : depth);
-
-#ifdef TARGET_SDL
-  SDL_Surface *surface_tmp, *surface_native;
-
-  if ((surface_tmp = SDL_CreateRGBSurface(SURFACE_FLAGS, width, height,
-                                         real_depth, 0, 0, 0, 0))
-      == NULL)
-    Error(ERR_EXIT, "SDL_CreateRGBSurface() failed: %s", SDL_GetError());
-
-  if ((surface_native = SDL_DisplayFormat(surface_tmp)) == NULL)
-    Error(ERR_EXIT, "SDL_DisplayFormat() failed: %s", SDL_GetError());
-
-  SDL_FreeSurface(surface_tmp);
-
-  return surface_native;
-#else
-  Pixmap pixmap;
-
-  if (!(pixmap = XCreatePixmap(display, window, width, height, real_depth)))
-    Error(ERR_EXIT, "cannot create pixmap");
-
-  return pixmap;
-#endif
-}
-
-inline void FreeBitmap(Bitmap bitmap)
-{
-#ifdef TARGET_SDL
-  SDL_FreeSurface(bitmap);
-#else
-  XFreePixmap(display, bitmap);
-#endif
-}
-
-inline void ClearRectangle(Bitmap bitmap, int x, int y, int width, int height)
-{
-#ifdef TARGET_SDL
-  SDLFillRectangle(bitmap, x, y, width, height, 0x000000);
-#else
-  XFillRectangle(display, bitmap, gc, x, y, width, height);
-#endif
-}
-
-inline void BlitBitmap(Bitmap src_bitmap, Bitmap dst_bitmap,
-                      int src_x, int src_y,
-                      int width, int height,
-                      int dst_x, int dst_y)
-{
-#ifdef TARGET_SDL
-  SDLCopyArea(src_bitmap, dst_bitmap,
-             src_x, src_y, width, height, dst_x, dst_y);
-#else
-  XCopyArea(display, src_bitmap, dst_bitmap, gc,
-           src_x, src_y, width, height, dst_x, dst_y);
-#endif
-}
-
-#ifndef TARGET_SDL
-static GC last_clip_gc = 0;    /* needed for XCopyArea() through clip mask */
-#endif
-
-inline void SetClipMask(GC clip_gc, Pixmap clip_pixmap)
-{
-#ifndef TARGET_SDL
-  XSetClipMask(display, clip_gc, clip_pixmap);
-  last_clip_gc = clip_gc;
-#endif
-}
-
-inline void SetClipOrigin(GC clip_gc, int clip_x, int clip_y)
-{
-#ifndef TARGET_SDL
-  XSetClipOrigin(display, clip_gc, clip_x, clip_y);
-  last_clip_gc = clip_gc;
-#endif
-}
-
-inline void BlitBitmapMasked(Bitmap src_bitmap, Bitmap dst_bitmap,
-                            int src_x, int src_y,
-                            int width, int height,
-                            int dst_x, int dst_y)
-{
-#ifdef TARGET_SDL
-  SDLCopyArea(src_bitmap, dst_bitmap,
-             src_x, src_y, width, height, dst_x, dst_y);
-#else
-  XCopyArea(display, src_bitmap, dst_bitmap, last_clip_gc,
-           src_x, src_y, width, height, dst_x, dst_y);
-#endif
-}
-
-inline void DrawSimpleWhiteLine(Bitmap bitmap, int from_x, int from_y,
-                               int to_x, int to_y)
-{
-#ifdef TARGET_SDL
-  SDLDrawSimpleLine(bitmap, from_x, from_y, to_x, to_y, 0xffffff);
-#else
-  XSetForeground(display, gc, WhitePixel(display, screen));
-  XDrawLine(display, bitmap, gc, from_x, from_y, to_x, to_y);
-  XSetForeground(display, gc, BlackPixel(display, screen));
-#endif
-}
-
-/* execute all pending screen drawing operations */
-inline void FlushDisplay(void)
-{
-#ifndef TARGET_SDL
-  XFlush(display);
-#endif
-}
-
-/* execute and wait for all pending screen drawing operations */
-inline void SyncDisplay(void)
-{
-#ifndef TARGET_SDL
-  XSync(display, FALSE);
-#endif
-}
-
-inline void KeyboardAutoRepeatOn(void)
-{
-#ifdef TARGET_SDL
-  SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY / 2,
-                     SDL_DEFAULT_REPEAT_INTERVAL / 2);
-  SDL_EnableUNICODE(1);
-#else
-  XAutoRepeatOn(display);
-#endif
-}
-
-inline void KeyboardAutoRepeatOff(void)
-{
-#ifdef TARGET_SDL
-  SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL);
-  SDL_EnableUNICODE(0);
-#else
-  XAutoRepeatOff(display);
-#endif
-}
-
-inline boolean PointerInWindow(DrawWindow window)
-{
-#ifdef TARGET_SDL
-  return TRUE;
-#else
-  DrawWindow root, child;
-  int root_x, root_y;
-  unsigned int mask;
-  int win_x, win_y;
-
-  /* if XQueryPointer() returns False, the pointer
-     is not on the same screen as the specified window */
-  return XQueryPointer(display, window, &root, &child, &root_x, &root_y,
-                      &win_x, &win_y, &mask);
-#endif
-}
-
-inline boolean SetVideoMode(void)
-{
-#ifdef TARGET_SDL
-  return SDLSetVideoMode(&backbuffer);
-#else
-  boolean success = TRUE;
-
-  if (setup.fullscreen && fullscreen_available)
-  {
-    Error(ERR_WARN, "fullscreen not available in X11 version");
-
-    /* display error message only once */
-    fullscreen_available = FALSE;
-
-    success = FALSE;
-  }
-
-  return success;
-#endif
-}
-
-inline void ChangeVideoModeIfNeeded(void)
-{
-#ifdef TARGET_SDL
-  if ((setup.fullscreen && !fullscreen_enabled && fullscreen_available) ||
-      (!setup.fullscreen && fullscreen_enabled))
-    SetVideoMode();
-#endif
-}
-
-
-/* ========================================================================= */
-/* audio functions                                                           */
-/* ========================================================================= */
-
-inline boolean OpenAudio(struct AudioSystemInfo *audio)
-{
-  audio->sound_available = FALSE;
-  audio->loops_available = FALSE;
-  audio->soundserver_pipe[0] = audio->soundserver_pipe[1] = 0;
-  audio->soundserver_pid = 0;
-  audio->device_fd = 0;
-
-#if defined(TARGET_SDL)
-  if (SDLOpenAudio())
-  {
-    audio->sound_available = TRUE;
-    audio->loops_available = TRUE;
-  }
-#elif defined(PLATFORM_MSDOS)
-  if (MSDOSOpenAudio())
-  {
-    audio->sound_available = TRUE;
-    audio->loops_available = TRUE;
-  }
-#elif defined(PLATFORM_UNIX)
-  UnixOpenAudio(audio);
-#endif
-
-  return audio->sound_available;
-}
-
-inline void CloseAudio(struct AudioSystemInfo *audio)
-{
-#if defined(TARGET_SDL)
-  SDLCloseAudio();
-#elif defined(PLATFORM_MSDOS)
-  MSDOSCloseAudio();
-#elif defined(PLATFORM_UNIX)
-  UnixCloseAudio(audio);
-#endif
-
-  audio->sound_available = FALSE;
-  audio->loops_available = FALSE;
-}
-
-
-/* ========================================================================= */
-/* event functions                                                           */
-/* ========================================================================= */
-
-inline void InitEventFilter(EventFilter filter_function)
-{
-#ifdef TARGET_SDL
-  /* set event filter to filter out certain events */
-  SDL_SetEventFilter(filter_function);
-#endif
-}
-
-inline boolean PendingEvent(void)
-{
-#ifdef TARGET_SDL
-  return (SDL_PollEvent(NULL) ? TRUE : FALSE);
-#else
-  return (XPending(display) ? TRUE : FALSE);
-#endif
-}
-
-inline void NextEvent(Event *event)
-{
-#ifdef TARGET_SDL
-  SDL_WaitEvent(event);
-#else
-  XNextEvent(display, event);
-#endif
-}
-
-inline Key GetEventKey(KeyEvent *event, boolean with_modifiers)
-{
-#ifdef TARGET_SDL
-#if 0
-  printf("unicode == '%d', sym == '%d', mod == '0x%04x'\n",
-        (int)event->keysym.unicode,
-        (int)event->keysym.sym,
-        (int)SDL_GetModState());
-#endif
-
-  if (with_modifiers && event->keysym.unicode != 0)
-    return event->keysym.unicode;
-  else
-    return event->keysym.sym;
-#else
-#if 0
-  printf("with modifiers == '0x%04x', without modifiers == '0x%04x'\n",
-        (int)XLookupKeysym(event, event->state),
-        (int)XLookupKeysym(event, 0));
-#endif
-
-  if (with_modifiers)
-    return XLookupKeysym(event, event->state);
-  else
-    return XLookupKeysym(event, 0);
-#endif
-}
-
-inline boolean CheckCloseWindowEvent(ClientMessageEvent *event)
-{
-  if (event->type != EVENT_CLIENTMESSAGE)
-    return FALSE;
-
-#if defined(TARGET_SDL)
-  return TRUE;         /* the only possible message here is SDL_QUIT */
-#elif defined(PLATFORM_UNIX)
-  if ((event->window == window) &&
-      (event->data.l[0] == XInternAtom(display, "WM_DELETE_WINDOW", FALSE)))
-    return TRUE;
-#endif
-
-  return FALSE;
-}
-
-
-inline void dummy(void)
-{
-#ifdef TARGET_SDL
-#else
-#endif
-}
diff --git a/src/system.h b/src/system.h
deleted file mode 100644 (file)
index fdfb4a6..0000000
+++ /dev/null
@@ -1,85 +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             *
-*----------------------------------------------------------*
-*  system.h                                                *
-***********************************************************/
-
-#ifndef SYSTEM_H
-#define SYSTEM_H
-
-#include "platform.h"
-
-#if defined(PLATFORM_MSDOS)
-#include "msdos.h"
-#endif
-
-#if defined(TARGET_SDL)
-#include "sdl.h"
-#elif defined(TARGET_X11)
-#include "x11.h"
-#endif
-
-
-/* contant definitions */
-
-#define DEFAULT_DEPTH                  0
-
-#define FULLSCREEN_NOT_AVAILABLE       FALSE
-#define FULLSCREEN_AVAILABLE           TRUE
-
-
-/* type definitions */
-
-typedef int (*EventFilter)(const Event *);
-
-
-/* structure definitions */
-
-struct AudioSystemInfo
-{
-  boolean sound_available;
-  boolean loops_available;
-  int soundserver_pipe[2];
-  int soundserver_pid;
-  int device_fd;
-};
-
-
-/* function definitions */
-
-inline void InitBufferedDisplay(DrawBuffer *, DrawWindow *);
-inline int GetDisplayDepth(void);
-inline Bitmap CreateBitmap(int, int, int);
-inline void FreeBitmap(Bitmap);
-inline void ClearRectangle(Bitmap, int, int, int, int);
-inline void BlitBitmap(Bitmap, Bitmap, int, int, int, int, int, int);
-inline void SetClipMask(GC, Pixmap);
-inline void SetClipOrigin(GC, int, int);
-inline void BlitBitmapMasked(Bitmap, Bitmap, int, int, int, int, int, int);
-inline void DrawSimpleWhiteLine(Bitmap, int, int, int, int);
-inline void FlushDisplay(void);
-inline void SyncDisplay(void);
-inline void KeyboardAutoRepeatOn(void);
-inline void KeyboardAutoRepeatOff(void);
-inline boolean PointerInWindow(DrawWindow);
-inline boolean SetVideoMode(void);
-inline void ChangeVideoModeIfNeeded(void);
-
-inline boolean OpenAudio(struct AudioSystemInfo *);
-inline void CloseAudio(struct AudioSystemInfo *);
-
-inline void InitEventFilter(EventFilter);
-inline boolean PendingEvent(void);
-inline void NextEvent(Event *event);
-inline Key GetEventKey(KeyEvent *, boolean);
-inline boolean CheckCloseWindowEvent(ClientMessageEvent *);
-
-#endif /* SYSTEM_H */
index 49fa39ae12dca45b1cf494e6a9cf177a3773b13b..7a5d5ff3f81030fbedb7503a8f5342be7e570fec 100644 (file)
 *  tape.c                                                  *
 ***********************************************************/
 
+#include "libgame/libgame.h"
+
 #include "tape.h"
-#include "misc.h"
 #include "game.h"
-#include "buttons.h"
 #include "tools.h"
 #include "files.h"
 #include "network.h"
index 423ce49dbfc0ddefca9bb6ab7ef03bf447c1c678..61e1bac133ce0f63ba0183b775097a5d5515a4b3 100644 (file)
 
 #include <stdarg.h>
 
-#ifdef __FreeBSD__
+#if defined(PLATFORM_FREEBSD)
 #include <machine/joystick.h>
 #endif
 
+#include "libgame/libgame.h"
+
 #include "tools.h"
 #include "game.h"
 #include "events.h"
-#include "sound.h"
-#include "misc.h"
-#include "buttons.h"
 #include "joystick.h"
 #include "cartoons.h"
 #include "network.h"
@@ -352,6 +351,8 @@ void ClearWindow()
   redraw_mask |= REDRAW_FIELD;
 }
 
+
+#if 0
 int getFontWidth(int font_size, int font_type)
 {
   return (font_size == FS_BIG ? FONT1_XSIZE :
@@ -489,6 +490,8 @@ void DrawTextExt(DrawBuffer d, GC gc, int x, int y,
     x += font_width;
   }
 }
+#endif
+
 
 void DrawAllPlayers()
 {
@@ -2365,10 +2368,12 @@ static struct
   }
 };
 
+#if 0
 static void DoNotDisplayInfoText(void *ptr)
 {
   return;
 }
+#endif
 
 void CreateToolButtons()
 {
@@ -2416,8 +2421,12 @@ void CreateToolButtons()
                      GDI_DECORATION_SIZE, MINI_TILEX, MINI_TILEY,
                      GDI_DECORATION_SHIFTING, 1, 1,
                      GDI_EVENT_MASK, event_mask,
-                     GDI_CALLBACK_ACTION, HandleToolButtons,
+
+#if 0
                      GDI_CALLBACK_INFO, DoNotDisplayInfoText,
+#endif
+
+                     GDI_CALLBACK_ACTION, HandleToolButtons,
                      GDI_END);
 
     if (gi == NULL)
index 0fc1f2dadd9cc2edec417a091a44ddbbd04b9577..721aa002a91565e7b34754b77b5724b5c7e4ace9 100644 (file)
@@ -62,6 +62,8 @@ void SetDrawtoField(int);
 void BackToFront();
 void FadeToFront();
 void ClearWindow();
+
+#if 0
 int getFontWidth(int, int);
 int getFontHeight(int, int);
 void DrawInitText(char *, int, int);
@@ -69,6 +71,8 @@ void DrawTextF(int, int, int, char *, ...);
 void DrawTextFCentered(int, int, char *, ...);
 void DrawText(int, int, char *, int, int);
 void DrawTextExt(DrawBuffer, GC, int, int, char *, int, int);
+#endif
+
 void DrawAllPlayers(void);
 void DrawPlayerField(int, int);
 void DrawPlayer(struct PlayerInfo *);
@@ -116,4 +120,4 @@ void CreateToolButtons();
 
 int el2gfx(int);
 
-#endif
+#endif /* TOOLS_H */
diff --git a/src/x11.c b/src/x11.c
deleted file mode 100644 (file)
index 3c60b15..0000000
--- a/src/x11.c
+++ /dev/null
@@ -1,206 +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             *
-*----------------------------------------------------------*
-*  x11.c                                                   *
-***********************************************************/
-
-#if defined(TARGET_X11)
-
-#include "main.h"
-#include "misc.h"
-
-struct IconFileInfo
-{
-  char *picture_filename;
-  char *picturemask_filename;
-};
-
-static void X11InitDisplay()
-{
-#if !defined(PLATFORM_MSDOS)
-  XVisualInfo vinfo_template, *vinfo;
-  int num_visuals;
-#endif
-  unsigned int depth;
-
-  /* connect to X server */
-  if (!(display = XOpenDisplay(options.display_name)))
-    Error(ERR_EXIT, "cannot connect to X server %s",
-         XDisplayName(options.display_name));
-
-  screen = DefaultScreen(display);
-  visual = DefaultVisual(display, screen);
-  depth  = DefaultDepth(display, screen);
-  cmap   = DefaultColormap(display, screen);
-
-#if !defined(PLATFORM_MSDOS)
-  /* look for good enough visual */
-  vinfo_template.screen = screen;
-  vinfo_template.class = (depth == 8 ? PseudoColor : TrueColor);
-  vinfo_template.depth = depth;
-  if ((vinfo = XGetVisualInfo(display, VisualScreenMask | VisualClassMask |
-                             VisualDepthMask, &vinfo_template, &num_visuals)))
-  {
-    visual = vinfo->visual;
-    XFree((void *)vinfo);
-  }
-
-  /* got appropriate visual? */
-  if (depth < 8)
-  {
-    printf("Sorry, displays with less than 8 bits per pixel not supported.\n");
-    exit(-1);
-  }
-  else if ((depth ==8 && visual->class != PseudoColor) ||
-          (depth > 8 && visual->class != TrueColor &&
-           visual->class != DirectColor))
-  {
-    printf("Sorry, cannot get appropriate visual.\n");
-    exit(-1);
-  }
-#endif /* !PLATFORM_MSDOS */
-}
-
-static DrawWindow X11InitWindow()
-{
-  Window window;
-  unsigned int border_width = 4;
-  XGCValues gc_values;
-  unsigned long gc_valuemask;
-#if !defined(PLATFORM_MSDOS)
-  XTextProperty windowName, iconName;
-  Pixmap icon_pixmap, iconmask_pixmap;
-  unsigned int icon_width, icon_height;
-  int icon_hot_x, icon_hot_y;
-  char icon_filename[256];
-  XSizeHints size_hints;
-  XWMHints wm_hints;
-  XClassHint class_hints;
-  char *window_name = WINDOW_TITLE_STRING;
-  char *icon_name = WINDOW_TITLE_STRING;
-  long window_event_mask;
-  Atom proto_atom = None, delete_atom = None;
-#endif
-  int screen_width, screen_height;
-  int win_xpos = WIN_XPOS, win_ypos = WIN_YPOS;
-  unsigned long pen_fg = WhitePixel(display,screen);
-  unsigned long pen_bg = BlackPixel(display,screen);
-  const int width = WIN_XSIZE, height = WIN_YSIZE;
-
-#if !defined(PLATFORM_MSDOS)
-  static struct IconFileInfo icon_pic =
-  {
-    "rocks_icon.xbm",
-    "rocks_iconmask.xbm"
-  };
-#endif
-
-  screen_width = XDisplayWidth(display, screen);
-  screen_height = XDisplayHeight(display, screen);
-
-  win_xpos = (screen_width - width) / 2;
-  win_ypos = (screen_height - height) / 2;
-
-  window = XCreateSimpleWindow(display, RootWindow(display, screen),
-                              win_xpos, win_ypos, width, height, border_width,
-                              pen_fg, pen_bg);
-
-#if !defined(PLATFORM_MSDOS)
-  proto_atom = XInternAtom(display, "WM_PROTOCOLS", FALSE);
-  delete_atom = XInternAtom(display, "WM_DELETE_WINDOW", FALSE);
-  if ((proto_atom != None) && (delete_atom != None))
-    XChangeProperty(display, window, proto_atom, XA_ATOM, 32,
-                   PropModePrepend, (unsigned char *) &delete_atom, 1);
-
-  sprintf(icon_filename, "%s/%s/%s",
-         options.ro_base_directory, GRAPHICS_DIRECTORY,
-         icon_pic.picture_filename);
-  XReadBitmapFile(display,window,icon_filename,
-                 &icon_width,&icon_height,
-                 &icon_pixmap,&icon_hot_x,&icon_hot_y);
-  if (!icon_pixmap)
-    Error(ERR_EXIT, "cannot read icon bitmap file '%s'", icon_filename);
-
-  sprintf(icon_filename, "%s/%s/%s",
-         options.ro_base_directory, GRAPHICS_DIRECTORY,
-         icon_pic.picturemask_filename);
-  XReadBitmapFile(display,window,icon_filename,
-                 &icon_width,&icon_height,
-                 &iconmask_pixmap,&icon_hot_x,&icon_hot_y);
-  if (!iconmask_pixmap)
-    Error(ERR_EXIT, "cannot read icon bitmap file '%s'", icon_filename);
-
-  size_hints.width  = size_hints.min_width  = size_hints.max_width  = width;
-  size_hints.height = size_hints.min_height = size_hints.max_height = height;
-  size_hints.flags = PSize | PMinSize | PMaxSize;
-
-  if (win_xpos || win_ypos)
-  {
-    size_hints.x = win_xpos;
-    size_hints.y = win_ypos;
-    size_hints.flags |= PPosition;
-  }
-
-  if (!XStringListToTextProperty(&window_name, 1, &windowName))
-    Error(ERR_EXIT, "structure allocation for windowName failed");
-
-  if (!XStringListToTextProperty(&icon_name, 1, &iconName))
-    Error(ERR_EXIT, "structure allocation for iconName failed");
-
-  wm_hints.initial_state = NormalState;
-  wm_hints.input = True;
-  wm_hints.icon_pixmap = icon_pixmap;
-  wm_hints.icon_mask = iconmask_pixmap;
-  wm_hints.flags = StateHint | IconPixmapHint | IconMaskHint | InputHint;
-
-  class_hints.res_name = program_name;
-  class_hints.res_class = "Rocks'n'Diamonds";
-
-  XSetWMProperties(display, window, &windowName, &iconName, 
-                  NULL, 0, &size_hints, &wm_hints, 
-                  &class_hints);
-
-  XFree(windowName.value);
-  XFree(iconName.value);
-
-  /* Select event types wanted */
-  window_event_mask =
-    ExposureMask | StructureNotifyMask | FocusChangeMask |
-    ButtonPressMask | ButtonReleaseMask | PointerMotionMask |
-    PointerMotionHintMask | KeyPressMask | KeyReleaseMask;
-
-  XSelectInput(display, window, window_event_mask);
-#endif
-
-  /* create GC for drawing with window depth and background color (black) */
-  gc_values.graphics_exposures = False;
-  gc_values.foreground = pen_bg;
-  gc_values.background = pen_bg;
-  gc_valuemask = GCGraphicsExposures | GCForeground | GCBackground;
-  gc = XCreateGC(display, window, gc_valuemask, &gc_values);
-
-  return window;
-}
-
-inline void X11InitBufferedDisplay(DrawBuffer *backbuffer, DrawWindow *window)
-{
-  X11InitDisplay();
-  *window = X11InitWindow();
-
-  XMapWindow(display, *window);
-  FlushDisplay();
-
-  /* create additional buffer for double-buffering */
-  *backbuffer = CreateBitmap(WIN_XSIZE, WIN_YSIZE, DEFAULT_DEPTH);
-  pix[PIX_DB_BACK] = *backbuffer;      /* 'backbuffer' is off-screen buffer */
-}
-
-#endif /* TARGET_X11 */
diff --git a/src/x11.h b/src/x11.h
deleted file mode 100644 (file)
index ca1247c..0000000
--- a/src/x11.h
+++ /dev/null
@@ -1,273 +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             *
-*----------------------------------------------------------*
-*  x11.h                                                   *
-***********************************************************/
-
-#ifndef X11_H
-#define X11_H
-
-#if !defined(PLATFORM_MSDOS)
-#define XK_MISCELLANY
-#define XK_LATIN1
-
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
-#include <X11/Xatom.h>
-#include <X11/Xos.h>
-#include <X11/Intrinsic.h>
-#include <X11/keysymdef.h>
-#endif
-
-
-/* system dependent definitions */
-
-/* MS-DOS header file also defines "TARGET_STRING" */
-#ifndef TARGET_STRING
-#define TARGET_STRING          "X11"
-#endif
-
-#define FULLSCREEN_STATUS      FULLSCREEN_NOT_AVAILABLE
-
-
-/* X11 type definitions */
-
-typedef Pixmap                 Bitmap;
-typedef Window                 DrawWindow;
-typedef Drawable               DrawBuffer;
-
-typedef KeySym                 Key;
-
-typedef XEvent                 Event;
-typedef XButtonEvent           ButtonEvent;
-typedef XMotionEvent           MotionEvent;
-typedef XKeyEvent              KeyEvent;
-typedef XExposeEvent           ExposeEvent;
-typedef XFocusChangeEvent      FocusChangeEvent;
-typedef XClientMessageEvent    ClientMessageEvent;
-
-
-/* X11 symbol definitions */
-
-#define EVENT_BUTTONPRESS      ButtonPress
-#define EVENT_BUTTONRELEASE    ButtonRelease
-#define EVENT_MOTIONNOTIFY     MotionNotify
-#define EVENT_KEYPRESS         KeyPress
-#define EVENT_KEYRELEASE       KeyRelease
-#define EVENT_EXPOSE           Expose
-#define EVENT_FOCUSIN          FocusIn
-#define EVENT_FOCUSOUT         FocusOut
-#define EVENT_CLIENTMESSAGE    ClientMessage
-#define EVENT_MAPNOTIFY                MapNotify
-#define EVENT_UNMAPNOTIFY      UnmapNotify
-
-#define KSYM_UNDEFINED         XK_VoidSymbol
-
-#define KSYM_Return            XK_Return
-#define KSYM_Escape            XK_Escape
-
-#define KSYM_Left              XK_Left
-#define KSYM_Right             XK_Right
-#define KSYM_Up                        XK_Up
-#define KSYM_Down              XK_Down
-
-#ifdef XK_KP_Left
-#define KSYM_KP_Left           XK_KP_Left
-#define KSYM_KP_Right          XK_KP_Right
-#define KSYM_KP_Up             XK_KP_Up
-#define KSYM_KP_Down           XK_KP_Down
-#endif
-
-#ifdef XK_KP_Enter
-#define KSYM_KP_Enter          XK_KP_Enter
-#define KSYM_KP_Add            XK_KP_Add
-#define KSYM_KP_Subtract       XK_KP_Subtract
-#define KSYM_KP_Multiply       XK_KP_Multiply
-#define KSYM_KP_Divide         XK_KP_Divide
-#define KSYM_KP_Separator      XK_KP_Separator
-#endif
-
-#define KSYM_Shift_L           XK_Shift_L
-#define KSYM_Shift_R           XK_Shift_R
-#define KSYM_Control_L         XK_Control_L
-#define KSYM_Control_R         XK_Control_R
-#define KSYM_Meta_L            XK_Meta_L
-#define KSYM_Meta_R            XK_Meta_R
-#define KSYM_Alt_L             XK_Alt_L
-#define KSYM_Alt_R             XK_Alt_R
-#define KSYM_Super_L           XK_Super_L
-#define KSYM_Super_R           XK_Super_R
-#define KSYM_Mode_switch       XK_Mode_switch
-#define KSYM_Multi_key         XK_Multi_key
-
-#define KSYM_BackSpace         XK_BackSpace
-#define KSYM_Delete            XK_Delete
-#define KSYM_Insert            XK_Insert
-#define KSYM_Tab               XK_Tab
-#define KSYM_Home              XK_Home
-#define KSYM_End               XK_End
-#define KSYM_Page_Up           XK_Page_Up
-#define KSYM_Page_Down         XK_Page_Down
-#define KSYM_Menu              XK_Menu
-
-#define KSYM_space             XK_space
-#define KSYM_exclam            XK_exclam
-#define KSYM_quotedbl          XK_quotedbl
-#define KSYM_numbersign                XK_numbersign
-#define KSYM_dollar            XK_dollar
-#define KSYM_percent           XK_percent
-#define KSYM_ampersand         XK_ampersand
-#define KSYM_apostrophe                XK_apostrophe
-#define KSYM_parenleft         XK_parenleft
-#define KSYM_parenright                XK_parenright
-#define KSYM_asterisk          XK_asterisk
-#define KSYM_plus              XK_plus
-#define KSYM_comma             XK_comma
-#define KSYM_minus             XK_minus
-#define KSYM_period            XK_period
-#define KSYM_slash             XK_slash
-
-#define KSYM_colon             XK_colon
-#define KSYM_semicolon         XK_semicolon
-#define KSYM_less              XK_less
-#define KSYM_equal             XK_equal
-#define KSYM_greater           XK_greater
-#define KSYM_question          XK_question
-#define KSYM_at                        XK_at
-
-#define KSYM_bracketleft       XK_bracketleft
-#define KSYM_backslash         XK_backslash
-#define KSYM_bracketright      XK_bracketright
-#define KSYM_asciicircum       XK_asciicircum
-#define KSYM_underscore                XK_underscore
-#define KSYM_grave             XK_grave
-
-#define KSYM_quoteleft         XK_quoteleft
-#define KSYM_braceleft         XK_braceleft
-#define KSYM_bar               XK_bar
-#define KSYM_braceright                XK_braceright
-#define KSYM_asciitilde                XK_asciitilde
-
-#define KSYM_Adiaeresis                XK_Adiaeresis
-#define KSYM_Odiaeresis                XK_Odiaeresis
-#define KSYM_Udiaeresis                XK_Udiaeresis
-#define KSYM_adiaeresis                XK_adiaeresis
-#define KSYM_odiaeresis                XK_odiaeresis
-#define KSYM_udiaeresis                XK_udiaeresis
-#define KSYM_ssharp            XK_ssharp
-
-#define KSYM_A                 XK_A
-#define KSYM_B                 XK_B
-#define KSYM_C                 XK_C
-#define KSYM_D                 XK_D
-#define KSYM_E                 XK_E
-#define KSYM_F                 XK_F
-#define KSYM_G                 XK_G
-#define KSYM_H                 XK_H
-#define KSYM_I                 XK_I
-#define KSYM_J                 XK_J
-#define KSYM_K                 XK_K
-#define KSYM_L                 XK_L
-#define KSYM_M                 XK_M
-#define KSYM_N                 XK_N
-#define KSYM_O                 XK_O
-#define KSYM_P                 XK_P
-#define KSYM_Q                 XK_Q
-#define KSYM_R                 XK_R
-#define KSYM_S                 XK_S
-#define KSYM_T                 XK_T
-#define KSYM_U                 XK_U
-#define KSYM_V                 XK_V
-#define KSYM_W                 XK_W
-#define KSYM_X                 XK_X
-#define KSYM_Y                 XK_Y
-#define KSYM_Z                 XK_Z
-
-#define KSYM_a                 XK_a
-#define KSYM_b                 XK_b
-#define KSYM_c                 XK_c
-#define KSYM_d                 XK_d
-#define KSYM_e                 XK_e
-#define KSYM_f                 XK_f
-#define KSYM_g                 XK_g
-#define KSYM_h                 XK_h
-#define KSYM_i                 XK_i
-#define KSYM_j                 XK_j
-#define KSYM_k                 XK_k
-#define KSYM_l                 XK_l
-#define KSYM_m                 XK_m
-#define KSYM_n                 XK_n
-#define KSYM_o                 XK_o
-#define KSYM_p                 XK_p
-#define KSYM_q                 XK_q
-#define KSYM_r                 XK_r
-#define KSYM_s                 XK_s
-#define KSYM_t                 XK_t
-#define KSYM_u                 XK_u
-#define KSYM_v                 XK_v
-#define KSYM_w                 XK_w
-#define KSYM_x                 XK_x
-#define KSYM_y                 XK_y
-#define KSYM_z                 XK_z
-
-#define KSYM_0                 XK_0
-#define KSYM_1                 XK_1
-#define KSYM_2                 XK_2
-#define KSYM_3                 XK_3
-#define KSYM_4                 XK_4
-#define KSYM_5                 XK_5
-#define KSYM_6                 XK_6
-#define KSYM_7                 XK_7
-#define KSYM_8                 XK_8
-#define KSYM_9                 XK_9
-
-#define KSYM_KP_0              XK_KP_0
-#define KSYM_KP_1              XK_KP_1
-#define KSYM_KP_2              XK_KP_2
-#define KSYM_KP_3              XK_KP_3
-#define KSYM_KP_4              XK_KP_4
-#define KSYM_KP_5              XK_KP_5
-#define KSYM_KP_6              XK_KP_6
-#define KSYM_KP_7              XK_KP_7
-#define KSYM_KP_8              XK_KP_8
-#define KSYM_KP_9              XK_KP_9
-
-#define KSYM_F1                        XK_F1
-#define KSYM_F2                        XK_F2
-#define KSYM_F3                        XK_F3
-#define KSYM_F4                        XK_F4
-#define KSYM_F5                        XK_F5
-#define KSYM_F6                        XK_F6
-#define KSYM_F7                        XK_F7
-#define KSYM_F8                        XK_F8
-#define KSYM_F9                        XK_F9
-#define KSYM_F10               XK_F10
-#define KSYM_F11               XK_F11
-#define KSYM_F12               XK_F12
-#define KSYM_F13               XK_F13
-#define KSYM_F14               XK_F14
-#define KSYM_F15               XK_F15
-#define KSYM_F16               XK_F16
-#define KSYM_F17               XK_F17
-#define KSYM_F18               XK_F18
-#define KSYM_F19               XK_F19
-#define KSYM_F20               XK_F20
-#define KSYM_F21               XK_F21
-#define KSYM_F22               XK_F22
-#define KSYM_F23               XK_F23
-#define KSYM_F24               XK_F24
-
-
-/* X11 function definitions */
-
-inline void X11InitBufferedDisplay(DrawBuffer *, DrawWindow *);
-
-#endif /* X11_H */