rnd-19980903
authorHolger Schemel <info@artsoft.org>
Thu, 3 Sep 1998 12:18:45 +0000 (14:18 +0200)
committerHolger Schemel <info@artsoft.org>
Sat, 30 Aug 2014 08:30:30 +0000 (10:30 +0200)
src/msdos.c [new file with mode: 0644]
src/msdos.h [new file with mode: 0644]

diff --git a/src/msdos.c b/src/msdos.c
new file mode 100644 (file)
index 0000000..bd4ad73
--- /dev/null
@@ -0,0 +1,980 @@
+/***********************************************************
+*  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                                                 *
+***********************************************************/
+
+#ifdef MSDOS
+#include "main.h"
+#include "tools.h"
+#include "sound.h"
+#include "files.h"
+#include "joystick.h"
+
+DECLARE_GFX_DRIVER_LIST(
+       GFX_DRIVER_VBEAF
+       GFX_DRIVER_VESA2L
+       GFX_DRIVER_VESA1)
+DECLARE_COLOR_DEPTH_LIST(COLOR_DEPTH_8)
+DECLARE_DIGI_DRIVER_LIST(DIGI_DRIVER_SB)
+DECLARE_MIDI_DRIVER_LIST()
+DECLARE_JOYSTICK_DRIVER_LIST(JOYSTICK_DRIVER_STANDARD)
+
+static int key_buffer[OSD_MAX_KEY];
+static XEvent event_buffer[MAX_EVENT_BUFFER];
+static int pending_events;
+static BOOL joystick_event;
+static BOOL mouse_installed = FALSE;
+static int last_mouse_pos;
+static int last_mouse_b;
+static int last_joystick_state;
+static BITMAP* video_bitmap;
+
+BOOL wait_for_vsync;
+
+extern int playing_sounds;
+extern struct SoundControl playlist[MAX_SOUNDS_PLAYING];
+extern struct SoundControl emptySoundControl;
+
+void allegro_drivers()
+{
+  int i;
+
+  for(i = 0; i < MAX_EVENT_BUFFER; i++);
+       event_buffer[i].type = 0;
+  for(i=0; i < OSD_MAX_KEY; i++) key_buffer[i] = KeyReleaseMask;
+  last_mouse_pos = mouse_pos;
+  last_mouse_b = 0;
+
+  pending_events = 0;
+  clear_keybuf();
+
+  i_love_bill = TRUE;
+  install_keyboard();
+  install_timer();
+  if (install_mouse() > 0) mouse_installed = TRUE;
+  install_joystick(JOY_TYPE_2PADS);
+
+  load_joystick_data(JOYDAT_FILE);
+  last_joystick_state = 0;
+  joystick_event = FALSE;
+
+  reserve_voices(MAX_SOUNDS_PLAYING, 0);
+  if(install_sound(DIGI_AUTODETECT, MIDI_NONE, "ROCKS.SND") == -1)
+    if(install_sound(DIGI_SB, MIDI_NONE, NULL) == -1) sound_status = SOUND_OFF;
+
+}
+
+BOOL hide_mouse(Display *display, int x, int y, unsigned int width, unsigned int height)
+{
+  if(mouse_x + display->mouse_ptr->w < x || mouse_x > x+width) return FALSE;
+  if(mouse_y + display->mouse_ptr->h < y || mouse_y > y+height) return FALSE;
+  show_mouse(NULL);
+  return(TRUE);
+}
+
+void unhide_mouse(Display *display)
+{
+  if(mouse_installed) show_mouse(video_bitmap);
+}
+
+int get_joystick_state()
+{
+  int state = 0;
+  poll_joystick();
+
+  if (joy[joystick_nr].stick[0].axis[0].d1) state |= JOY_LEFT;
+  if (joy[joystick_nr].stick[0].axis[0].d2) state |= JOY_RIGHT;
+  if (joy[joystick_nr].stick[0].axis[1].d1) state |= JOY_UP;
+  if (joy[joystick_nr].stick[0].axis[1].d2) state |= JOY_DOWN;
+  if (joy[joystick_nr].button[0].b) state |= JOY_BUTTON_1;
+
+  switch (state)
+  {
+    case (JOY_DOWN | JOY_LEFT):
+       state = XK_KP_1;
+       break;
+    case (JOY_DOWN):
+       state = XK_KP_2;
+       break;
+    case (JOY_DOWN | JOY_RIGHT):
+       state = XK_KP_3;
+       break;
+    case (JOY_LEFT):
+       state = XK_KP_4;
+       break;
+    case (JOY_RIGHT):
+       state = XK_KP_6;
+       break;
+    case (JOY_UP | JOY_LEFT):
+       state = XK_KP_7;
+       break;
+    case (JOY_UP):
+       state = XK_KP_8;
+       break;
+    case (JOY_UP | JOY_RIGHT):
+       state = XK_KP_9;
+       break;
+
+    case (JOY_DOWN | JOY_BUTTON_1):
+       state = XK_X;
+       break;
+    case (JOY_LEFT | JOY_BUTTON_1):
+       state = XK_S;
+       break;
+    case (JOY_RIGHT | JOY_BUTTON_1):
+       state = XK_D;
+       break;
+    case (JOY_UP | JOY_BUTTON_1):
+       state = XK_E;
+       break;
+   default:
+       state = 0;
+  }
+
+  return(state);
+}
+
+unsigned char get_ascii(KeySym key)
+{
+  switch(key) {
+
+       case OSD_KEY_Q: return 'Q';
+       case OSD_KEY_W: return 'W';
+       case OSD_KEY_E: return 'E';
+       case OSD_KEY_R: return 'R';
+       case OSD_KEY_T: return 'T';
+       case OSD_KEY_Y: return 'Y';
+       case OSD_KEY_U: return 'U';
+       case OSD_KEY_I: return 'I';
+       case OSD_KEY_O: return 'O';
+       case OSD_KEY_P: return 'P';
+       case OSD_KEY_A: return 'A';
+       case OSD_KEY_S: return 'S';
+       case OSD_KEY_D: return 'D';
+       case OSD_KEY_F: return 'F';
+       case OSD_KEY_G: return 'G';
+       case OSD_KEY_H: return 'H';
+       case OSD_KEY_J: return 'J';
+       case OSD_KEY_K: return 'K';
+       case OSD_KEY_L: return 'L';
+       case OSD_KEY_Z: return 'Z';
+       case OSD_KEY_X: return 'X';
+       case OSD_KEY_C: return 'C';
+       case OSD_KEY_V: return 'V';
+       case OSD_KEY_B: return 'B';
+       case OSD_KEY_N: return 'N';
+       case OSD_KEY_M: return 'M';
+       case OSD_KEY_1: return '1';
+       case OSD_KEY_2: return '2';
+       case OSD_KEY_3: return '3';
+       case OSD_KEY_4: return '4';
+       case OSD_KEY_5: return '5';
+       case OSD_KEY_6: return '6';
+       case OSD_KEY_7: return '7';
+       case OSD_KEY_8: return '8';
+       case OSD_KEY_9: return '9';
+       case OSD_KEY_0: return '0';
+       case OSD_KEY_SPACE: return ' ';
+ }
+  return (0);
+}
+
+long osd_key_pressed(int keycode)
+{
+  if (keycode == OSD_KEY_RCONTROL) keycode = KEY_RCONTROL;
+  if (keycode == OSD_KEY_ALTGR) keycode = KEY_ALTGR;
+
+  if (key[keycode])
+       return(KeyPressMask);
+  else
+       return(KeyReleaseMask);
+}
+
+void XMapWindow(Display* display, Window w)
+{
+  int x, y;
+  unsigned int width, height;
+  BOOL mouse_off;
+
+  x = display->screens[display->default_screen].x;
+  y = display->screens[display->default_screen].y;
+  width = display->screens[display->default_screen].width;
+  height = display->screens[display->default_screen].height;
+
+  mouse_off = hide_mouse(display, x, y, width, height);
+  blit((BITMAP *)w, video_bitmap, 0, 0, x, y, width, height);
+  if(mouse_off) unhide_mouse(display);
+}
+
+Display *XOpenDisplay(char* dummy)
+{
+  Screen *MyScreens;
+  Display *MyDisplay;
+  BITMAP *MyMouse = NULL;
+  RGB pal[256];
+
+  MyScreens = malloc(sizeof(Screen));
+  MyDisplay = malloc(sizeof(Display));
+
+  if(MOUSE_FILENAME)
+         MyMouse = load_gif(MOUSE_FILENAME, pal);
+
+  MyScreens[0].cmap = 0;
+  MyScreens[0].root = 0;
+  MyScreens[0].white_pixel = 0xFF;
+  MyScreens[0].black_pixel = 0x00;
+  MyScreens[0].video_bitmap = NULL;
+
+  MyDisplay->default_screen = 0;
+  MyDisplay->screens = MyScreens;
+  MyDisplay->mouse_ptr = MyMouse;
+
+  allegro_init();
+  allegro_drivers();
+  set_color_depth(8);
+  set_gfx_mode(GFX_AUTODETECT, 320, 200, 0, 0); // force Windows 95 to switch to fullscreen mode
+  rest(200);
+  set_gfx_mode(GFX_AUTODETECT, XRES, YRES, 0, 0);
+
+  return(MyDisplay);
+}
+
+Window XCreateSimpleWindow(
+       Display* display,
+       Window parent,
+       int x,
+       int y,
+       unsigned int width,
+       unsigned int height,
+       unsigned int border_width,
+       unsigned long border,
+       unsigned long background)
+{
+  video_bitmap = create_video_bitmap(XRES, YRES);
+  clear_to_color(video_bitmap, background);
+
+  display->screens[display->default_screen].video_bitmap = video_bitmap;
+  display->screens[display->default_screen].x = x;
+  display->screens[display->default_screen].y = y;
+  display->screens[display->default_screen].width = XRES;
+  display->screens[display->default_screen].height = YRES;
+
+  set_mouse_sprite(display->mouse_ptr);
+  set_mouse_range(display->screens[display->default_screen].x+1,
+                 display->screens[display->default_screen].y+1,
+                 display->screens[display->default_screen].x+WIN_XSIZE+1,
+                 display->screens[display->default_screen].y+WIN_YSIZE+1);
+
+  show_video_bitmap(video_bitmap);
+
+  return((Window) video_bitmap);
+}
+
+int XReadBitmapFile(
+       Display* display,
+       Drawable d,
+       char* filename,
+       unsigned int* width_return,
+       unsigned int* height_return,
+       Pixmap* bitmap_return,
+       int* x_hot_return,
+       int* y_hot_return)
+{
+  BITMAP *bmp;
+  RGB pal[256];
+
+  if((bmp = load_gif(filename, pal)) == NULL)
+       return(BitmapOpenFailed);
+
+  *width_return = bmp->w;
+  *height_return = bmp->h;
+  *x_hot_return = -1;
+  *y_hot_return = -1;
+  *bitmap_return = (Pixmap) bmp;
+
+  return(BitmapSuccess);
+}
+
+Status XStringListToTextProperty(char** list, int count, XTextProperty* text_prop_return)
+{
+  char *string;
+
+  if(count >= 1)
+  {
+       string = malloc(strlen(list[0]+1));
+       strcpy(string, list[0]);
+        text_prop_return->value = (unsigned char *) string;
+       return(1);
+  }
+  else
+  {
+        text_prop_return = NULL;
+  }
+    return(0);
+}
+
+void XFree(void* data)
+{
+  if(data) free(data);
+}
+
+GC XCreateGC(Display* display, Drawable d, unsigned long value_mask, XGCValues* values)
+{
+  XGCValues *gcv;
+  gcv = malloc(sizeof(XGCValues));
+  gcv->foreground = values->foreground;
+  gcv->background = values->background;
+  gcv->graphics_exposures = values->graphics_exposures;
+  gcv->clip_mask = values->clip_mask;
+  gcv->clip_x_origin = values->clip_x_origin;
+  gcv->clip_y_origin = values->clip_y_origin;
+  gcv->value_mask = value_mask;
+  return((GC) gcv);
+}
+
+void XFillRectangle(
+       Display* display,
+       Drawable d,
+       GC gc,
+       int x,
+       int y,
+       unsigned int width,
+       unsigned int height)
+{
+  BOOL mouse_off;
+
+  if((BITMAP *) d == video_bitmap)
+  {
+       x += display->screens[display->default_screen].x;
+       y += display->screens[display->default_screen].y;
+       freeze_mouse_flag = TRUE;
+       mouse_off = hide_mouse(display, x, y, width, height);
+  }
+
+  rectfill((BITMAP *) d, x, y, x+width, y+height, ((XGCValues *)gc)->foreground);
+  if(mouse_off) unhide_mouse(display);
+  freeze_mouse_flag = FALSE;
+}
+
+Pixmap XCreatePixmap(
+       Display* display,
+       Drawable d,
+       unsigned int width,
+       unsigned int height,
+       unsigned int depth)
+{
+  BITMAP *MyBitmap = NULL;
+
+  if(GFX_HW_VRAM_BLIT&gfx_capabilities && width == FXSIZE && height == FYSIZE)
+    MyBitmap = create_video_bitmap(width, height);
+
+  if(MyBitmap == NULL)
+    MyBitmap = create_bitmap(width, height);
+
+  return((Pixmap) MyBitmap);
+}
+
+inline void XCopyArea(
+       Display* display,
+       Drawable src,
+       Drawable dest,
+       GC gc,
+       int src_x,
+       int src_y,
+       unsigned int width,
+       unsigned int height,
+       int dest_x,
+       int dest_y)
+{
+  BOOL mouse_off;
+
+  if((BITMAP *) src == video_bitmap )
+  {
+       src_x += display->screens[display->default_screen].x;
+       src_y += display->screens[display->default_screen].y;
+  }
+  if((BITMAP *) dest == video_bitmap )
+  {
+       dest_x += display->screens[display->default_screen].x;
+       dest_y += display->screens[display->default_screen].y;
+       freeze_mouse_flag = TRUE;
+       mouse_off = hide_mouse(display, dest_x, dest_y, width, height);
+  }
+
+  if(wait_for_vsync)
+  {
+    wait_for_vsync = FALSE;
+    vsync();
+  }
+
+  if(((XGCValues *)gc)->value_mask&GCClipMask)
+    masked_blit((BITMAP *) src, (BITMAP *) dest, src_x, src_y, dest_x, dest_y, width, height);
+  else
+    blit((BITMAP *) src, (BITMAP *) dest, src_x, src_y, dest_x, dest_y, width, height);
+
+  if(mouse_off) unhide_mouse(display);
+  freeze_mouse_flag = FALSE;
+}
+
+int XpmReadFileToPixmap(
+       Display* display,
+       Drawable d,
+       char* filename,
+       Pixmap* pixmap_return,
+       Pixmap* shapemask_return,
+       XpmAttributes* attributes)
+{
+  BITMAP *bmp;
+  RGB pal[256];
+
+  if((bmp = load_gif(filename, pal)) == NULL)
+       return(XpmOpenFailed);
+
+  *pixmap_return = (Pixmap) bmp;
+  set_pallete(pal);
+
+  return(XpmSuccess);
+}
+
+void XFreePixmap(Display* display, Pixmap pixmap)
+{
+  if( pixmap != DUMMY_MASK &&
+     (is_memory_bitmap((BITMAP *) pixmap) || is_screen_bitmap((BITMAP *) pixmap)) )
+         destroy_bitmap((BITMAP *) pixmap);
+}
+
+void XFreeGC(Display* display, GC gc)
+{
+  XGCValues *gcv;
+
+  gcv = (XGCValues *) gc;
+  if(gcv) free(gcv);
+}
+
+void XCloseDisplay(Display* display)
+{
+  BITMAP * bmp;
+  bmp = video_bitmap;
+
+  if(is_screen_bitmap(bmp))
+        destroy_bitmap(bmp);
+  if(display->screens)
+        free(display->screens);
+  if(display)
+        free(display);
+}
+
+void XNextEvent(Display* display, XEvent* event_return)
+{
+  while(!pending_events) XPending(display);
+
+  memcpy(event_return, &event_buffer[pending_events], sizeof(XEvent));
+  pending_events--;
+}
+
+int XPending(Display* display)
+{
+  int i, state;
+  static BOOL joy_button_2 = FALSE;
+
+  XKeyEvent *xkey;
+  XButtonEvent *xbutton;
+  XMotionEvent *xmotion;
+
+  // joystick event (simulating keyboard event)
+
+  state = get_joystick_state();
+
+  if (joy[joystick_nr].button[1].b && !joy_button_2)
+  {
+      pending_events++;
+      xkey = (XKeyEvent *) &event_buffer[pending_events];
+      xkey->type = KeyPress;
+      xkey->state = XK_B;
+      joy_button_2 = TRUE;
+  }
+  else if (!joy[joystick_nr].button[1].b && joy_button_2)
+  {
+      pending_events++;
+      xkey = (XKeyEvent *) &event_buffer[pending_events];
+      xkey->type = KeyRelease;
+      xkey->state = XK_B;
+      joy_button_2 = FALSE;
+  }
+
+  if(state && !joystick_event)
+  {
+      pending_events++;
+      xkey = (XKeyEvent *) &event_buffer[pending_events];
+      xkey->type = KeyPress;
+      xkey->state = state;
+      joystick_event = TRUE;
+      last_joystick_state = state;
+  }
+  else if((state != last_joystick_state) && joystick_event)
+  {
+      pending_events++;
+      xkey = (XKeyEvent *) &event_buffer[pending_events];
+      xkey->type = KeyRelease;
+      xkey->state = last_joystick_state;
+      joystick_event = FALSE;
+  }
+
+  // keyboard event
+
+  for(i=0; i < OSD_MAX_KEY+1 && pending_events < MAX_EVENT_BUFFER; i++)
+  {
+    state = osd_key_pressed(i);
+
+    if(state != key_buffer[i])
+    {
+       key_buffer[i] = state;
+       pending_events++;
+       xkey = (XKeyEvent *) &event_buffer[pending_events];
+       xkey->type = state&KeyPressMask ? KeyPress : KeyRelease;
+       xkey->state = i;
+    }
+  }
+
+  // mouse motion event
+
+  if((mouse_pos != last_mouse_pos && mouse_b != last_mouse_b))
+  {
+       last_mouse_pos = mouse_pos;
+       pending_events++;
+        xmotion = (XMotionEvent *) &event_buffer[pending_events];
+        xmotion->type = MotionNotify;
+       xmotion->x = mouse_x - display->screens[display->default_screen].x;
+       xmotion->y = mouse_y - display->screens[display->default_screen].y;
+       return;
+  }
+
+  // mouse button event
+
+  if(mouse_b != last_mouse_b)
+  {
+    for(i = 1; i<4; i<<=1)
+    {
+      if((last_mouse_b&i) != (mouse_b&i))
+      {
+       pending_events++;
+        xbutton = (XButtonEvent *) &event_buffer[pending_events];
+        xbutton->type = mouse_b&i ? ButtonPress : ButtonRelease;
+        xbutton->button = i;
+       xbutton->x = mouse_x - display->screens[display->default_screen].x;
+       xbutton->y = mouse_y - display->screens[display->default_screen].y;
+      }
+    }
+    last_mouse_b = mouse_b;
+  }
+
+  return pending_events;
+}
+
+KeySym XLookupKeysym(XKeyEvent* key_event, int index)
+{
+  return(key_event->state);
+}
+
+void sound_handler(struct SoundControl snd_ctrl)
+{
+    int i;
+
+    if (snd_ctrl.fade_sound)
+    {
+      if (!playing_sounds)
+       return;
+
+      for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+       if ((snd_ctrl.stop_all_sounds || playlist[i].nr == snd_ctrl.nr) && !playlist[i].fade_sound) {
+         playlist[i].fade_sound = TRUE;
+         if(voice_check(playlist[i].voice))
+            voice_ramp_volume(playlist[i].voice, 1000, 0);
+          playlist[i].loop = PSND_NO_LOOP;
+        }
+    }
+    else if (snd_ctrl.stop_all_sounds)
+    {
+      if (!playing_sounds)
+       return;
+      SoundServer_StopAllSounds();
+    }
+    else if (snd_ctrl.stop_sound)
+    {
+      if (!playing_sounds)
+       return;
+      SoundServer_StopSound(snd_ctrl.nr);
+    }
+
+    for(i=0;i<MAX_SOUNDS_PLAYING;i++)
+    {
+      if (!playlist[i].active || playlist[i].loop)
+       continue;
+
+      playlist[i].playingpos = voice_get_position(playlist[i].voice);
+      playlist[i].volume = voice_get_volume(playlist[i].voice);
+      if (playlist[i].playingpos == -1 || !playlist[i].volume)
+      {
+        deallocate_voice(playlist[i].voice);
+        playlist[i] = emptySoundControl;
+       playing_sounds--;
+      }
+    }
+
+    if (snd_ctrl.active)
+      SoundServer_InsertNewSound(snd_ctrl);
+
+}
+
+
+// GIF Loader
+// by Paul Bartrum
+
+int _color_load_depth(int depth);
+
+struct LZW_STRING
+{
+       short base;
+       char new;
+       short length;
+};
+
+PACKFILE *f;
+int empty_string, curr_bit_size, bit_overflow;
+int bit_pos, data_pos, data_len, entire, code;
+int cc, string_length, i, bit_size;
+unsigned char string[4096];
+struct LZW_STRING str[4096];
+BITMAP *bmp;
+int image_x, image_y, image_w, image_h, x, y;
+int interlace;
+
+
+void clear_table(void)
+{
+       empty_string = cc + 2;
+       curr_bit_size = bit_size + 1;
+       bit_overflow = 0;
+}
+
+
+void get_code(void)
+{
+       if(bit_pos + curr_bit_size > 8) {
+               if(data_pos >= data_len) { data_len = pack_getc(f); data_pos = 0; }
+               entire = (pack_getc(f) << 8) + entire;
+               data_pos ++;
+       }
+       if(bit_pos + curr_bit_size > 16) {
+               if(data_pos >= data_len) { data_len = pack_getc(f); data_pos = 0; }
+               entire = (pack_getc(f) << 16) + entire;
+               data_pos ++;
+       }
+       code = (entire >> bit_pos) & ((1 << curr_bit_size) - 1);
+       if(bit_pos + curr_bit_size > 8)
+               entire >>= 8;
+       if(bit_pos + curr_bit_size > 16)
+               entire >>= 8;
+       bit_pos = (bit_pos + curr_bit_size) % 8;
+       if(bit_pos == 0) {
+               if(data_pos >= data_len) { data_len = pack_getc(f); data_pos = 0; }
+               entire = pack_getc(f);
+               data_pos ++;
+       }
+}
+
+
+void get_string(int num)
+{
+       if(num < cc)
+       {
+               string_length = 1;
+               string[0] = str[num].new;
+       }
+       else
+       {
+               i = str[num].length;
+               string_length = i;
+               while(i > 0)
+               {
+                       i --;
+                       string[i] = str[num].new;
+                       num = str[num].base;
+               }
+               /* if(num != -1) **-{[ERROR]}-** */
+       }
+}
+
+
+void output_string(void)
+{
+       for(i = 0; i < string_length; i ++)
+       {
+               putpixel(bmp, x, y, string[i]);
+               x ++;
+               if(x >= image_x + image_w)
+               {
+                       x = image_x;
+                       y += interlace;
+                       if(interlace)
+                       {
+                               if(y >= image_y + image_h)
+                               {
+                                       if(interlace == 8 && (y - image_y) % 8 == 0) {
+                                               interlace = 8;
+                                               y = image_y + 4;
+                                       }
+                                       else if(interlace == 8  && (y - image_y) % 8 == 4) {
+                                               interlace = 4;
+                                               y = image_y + 2;
+                                       }
+                                       else if(interlace == 4) {
+                                               interlace = 2;
+                                               y = image_y + 1;
+                                       }
+                               }
+                       }
+               }
+       }
+}
+
+/* load_gif:
+ *  Loads a 2-256 colour GIF file onto a bitmap, returning the bitmap
+ *  structure and storing the pallete data in the specified pallete (this
+ *  should be an array of at least 256 RGB structures).
+ */
+BITMAP *load_gif(char *filename, RGB *pal)
+{
+       int width, height, depth;
+       int old;
+       BITMAP *bmp2;
+       int dest_depth;
+
+       f = pack_fopen(filename, F_READ);
+       if (!f) /* can't open file */
+               return NULL;
+
+       i  = pack_mgetw(f) << 8;
+       i += pack_getc(f);
+       if(i != 0x474946) /* is it really a GIF? */
+       {
+               pack_fclose(f);
+               return NULL;
+       }
+       pack_fseek(f, 3); /* skip version */
+
+       width = pack_igetw(f);
+       height = pack_igetw(f);
+
+       bmp = create_bitmap_ex(8, width, height);
+       if(bmp == NULL) {
+               pack_fclose(f);
+               return NULL;
+       }
+       clear(bmp);
+
+       i = pack_getc(f);
+       if(i & 128) /* no global colour table? */
+               depth = (i & 7) + 1;
+       else
+               depth = 0;
+
+       pack_fseek(f, 2);       /* skip background colour and aspect ratio */
+
+       if(pal && depth) /* only read palette if pal and depth are not 0 */
+       {
+               for(i = 0; i < (1 << depth); i ++)
+               {
+                       pal[i].r = pack_getc(f) / 4;
+                       pal[i].g = pack_getc(f) / 4;
+                       pal[i].b = pack_getc(f) / 4;
+               }
+       }
+       else
+               if(depth)
+                       pack_fseek(f, (1 << depth) * 3);
+
+       do
+       {
+               i = pack_getc(f);
+               switch(i)
+               {
+                       case 0x2C: /* Image Descriptor */
+                               image_x = pack_igetw(f);
+                               image_y = pack_igetw(f); /* individual image dimensions */
+                               image_w = pack_igetw(f);
+                               image_h = pack_igetw(f);
+
+                               i = pack_getc(f);
+                               if(i & 64)
+                                       interlace = 8;
+                               else
+                                       interlace = 1;
+
+                               if(i & 128)
+                               {
+                                       depth = (i & 7) + 1;
+                                       if(pal)
+                                       {
+                                               for(i = 0; i < (1 << depth); i ++)
+                                               {
+                                                       pal[i].r = pack_getc(f) / 4;
+                                                       pal[i].g = pack_getc(f) / 4;
+                                                       pal[i].b = pack_getc(f) / 4;
+                                               }
+                                       }
+                                       else
+                                               pack_fseek(f, (1 << depth) * 3);
+                               }
+
+                               /* lzw stream starts now */
+                               bit_size = pack_getc(f);
+                               cc = 1 << bit_size;
+
+                               /* initialise string table */
+                               for(i = 0; i < cc; i ++)
+                               {
+                                       str[i].base = -1;
+                                       str[i].new = i;
+                                       str[i].length = 1;
+                               }
+
+                               /* initialise the variables */
+                               bit_pos = 0;
+                               data_len = pack_getc(f); data_pos = 0;
+                               entire = pack_getc(f); data_pos ++;
+                               string_length = 0; x = image_x; y = image_y;
+
+                               /* starting code */
+                               clear_table();
+                               get_code();
+                               if(code == cc)
+                                       get_code();
+                               get_string(code);
+                               output_string();
+                               old = code;
+
+                               while(TRUE)
+                               {
+                                       get_code();
+
+                                       if(code == cc)
+                                       {
+                                               /* starting code */
+                                               clear_table();
+                                               get_code();
+                                               get_string(code);
+                                               output_string();
+                                               old = code;
+                                       }
+                                       else if(code == cc + 1)
+                                       {
+                                               break;
+                                       }
+                                       else if(code < empty_string)
+                                       {
+                                               get_string(code);
+                                               output_string();
+
+                                               if(bit_overflow == 0) {
+                                                       str[empty_string].base = old;
+                                                       str[empty_string].new = string[0];
+                                                       str[empty_string].length = str[old].length + 1;
+                                                       empty_string ++;
+                                                       if(empty_string == (1 << curr_bit_size))
+                                                               curr_bit_size ++;
+                                                       if(curr_bit_size == 13) {
+                                                               curr_bit_size = 12;
+                                                               bit_overflow = 1;
+                                                       }
+                                               }
+
+                                               old = code;
+                                       }
+                                       else
+                                       {
+                                               get_string(old);
+                                               string[str[old].length] = string[0];
+                                               string_length ++;
+
+                                               if(bit_overflow == 0) {
+                                                       str[empty_string].base = old;
+                                                       str[empty_string].new = string[0];
+                                                       str[empty_string].length = str[old].length + 1;
+                                                       empty_string ++;
+                                                       if(empty_string == (1 << curr_bit_size))
+                                                               curr_bit_size ++;
+                                                       if(curr_bit_size == 13) {
+                                                               curr_bit_size = 12;
+                                                               bit_overflow = 1;
+                                                       }
+                                               }
+
+                                               output_string();
+                                               old = code;
+                                       }
+                               }
+                               break;
+                       case 0x21: /* Extension Introducer */
+                               i = pack_getc(f);
+                               if(i == 0xF9) /* Graphic Control Extension */
+                               {
+                                       pack_fseek(f, 1); /* skip size (it's 4) */
+                                       i = pack_getc(f);
+                                       if(i & 1) /* is transparency enabled? */
+                                       {
+                                               pack_fseek(f, 2);
+                                               pack_getc(f); /* transparent colour */
+                                       }
+                                       else
+                                               pack_fseek(f, 3);
+                               }
+                               i = pack_getc(f);
+                               while(i) /* skip Data Sub-blocks */
+                               {
+                                       pack_fseek(f, i);
+                                       i = pack_getc(f);
+                               }
+                               break;
+                       case 0x3B: /* Trailer - end of data */
+                               pack_fclose(f);
+
+                               /* convert to correct colour depth */
+                               dest_depth = _color_load_depth(8);
+
+                               if (dest_depth != 8)
+                               {
+                                       bmp2 = create_bitmap_ex(dest_depth, bmp->w, bmp->h);
+                                       if (!bmp2)
+                                       {
+                                               destroy_bitmap(bmp);
+                                               return NULL;
+                                       }
+
+                                       select_palette(pal);
+                                       blit(bmp, bmp2, 0, 0, 0, 0, bmp->w, bmp->h);
+                                       unselect_palette();
+
+                                       destroy_bitmap(bmp);
+                                       bmp = bmp2;
+                               }
+
+                               return bmp;
+               }
+       } while(TRUE);
+
+       /* this is never executed but DJGPP complains if you leave it out */
+       return NULL;
+}
+
+#endif
diff --git a/src/msdos.h b/src/msdos.h
new file mode 100644 (file)
index 0000000..c3357a6
--- /dev/null
@@ -0,0 +1,472 @@
+/***********************************************************
+*  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 XPM_INCLUDE_FILE
+#define XPM_INCLUDE_FILE
+#endif
+
+#define XRES 800
+#define YRES 600
+
+#define TRUE 1
+#define FALSE 0
+
+#include <allegro.h>
+#include <time.h>
+
+// Allegro keyboard mapping
+
+#define OSD_KEY_ESC         1        /* keyboard scan codes */
+#define OSD_KEY_1           2        /* (courtesy of allegro.h) */
+#define OSD_KEY_2           3
+#define OSD_KEY_3           4
+#define OSD_KEY_4           5
+#define OSD_KEY_5           6
+#define OSD_KEY_6           7
+#define OSD_KEY_7           8
+#define OSD_KEY_8           9
+#define OSD_KEY_9           10
+#define OSD_KEY_0           11
+#define OSD_KEY_MINUS       12
+#define OSD_KEY_EQUALS      13
+#define OSD_KEY_BACKSPACE   14
+#define OSD_KEY_TAB         15
+#define OSD_KEY_Q           16
+#define OSD_KEY_W           17
+#define OSD_KEY_E           18
+#define OSD_KEY_R           19
+#define OSD_KEY_T           20
+#define OSD_KEY_Y           21
+#define OSD_KEY_U           22
+#define OSD_KEY_I           23
+#define OSD_KEY_O           24
+#define OSD_KEY_P           25
+#define OSD_KEY_OPENBRACE   26
+#define OSD_KEY_CLOSEBRACE  27
+#define OSD_KEY_ENTER       28
+#define OSD_KEY_LCONTROL    29
+#define OSD_KEY_A           30
+#define OSD_KEY_S           31
+#define OSD_KEY_D           32
+#define OSD_KEY_F           33
+#define OSD_KEY_G           34
+#define OSD_KEY_H           35
+#define OSD_KEY_J           36
+#define OSD_KEY_K           37
+#define OSD_KEY_L           38
+#define OSD_KEY_COLON       39
+#define OSD_KEY_QUOTE       40
+#define OSD_KEY_TILDE       41
+#define OSD_KEY_LSHIFT      42
+/* 43 */
+#define OSD_KEY_Z           44
+#define OSD_KEY_X           45
+#define OSD_KEY_C           46
+#define OSD_KEY_V           47
+#define OSD_KEY_B           48
+#define OSD_KEY_N           49
+#define OSD_KEY_M           50
+#define OSD_KEY_COMMA       51
+#define OSD_KEY_STOP        52
+#define OSD_KEY_SLASH       53
+#define OSD_KEY_RSHIFT      54
+#define OSD_KEY_ASTERISK    55
+#define OSD_KEY_ALT         56
+#define OSD_KEY_SPACE       57
+#define OSD_KEY_CAPSLOCK    58
+#define OSD_KEY_F1          59
+#define OSD_KEY_F2          60
+#define OSD_KEY_F3          61
+#define OSD_KEY_F4          62
+#define OSD_KEY_F5          63
+#define OSD_KEY_F6          64
+#define OSD_KEY_F7          65
+#define OSD_KEY_F8          66
+#define OSD_KEY_F9          67
+#define OSD_KEY_F10         68
+#define OSD_KEY_NUMLOCK     69
+#define OSD_KEY_SCRLOCK     70
+#define OSD_KEY_HOME        71
+#define OSD_KEY_UP          72
+#define OSD_KEY_PGUP        73
+#define OSD_KEY_MINUS_PAD   74
+#define OSD_KEY_LEFT        75
+#define OSD_KEY_5_PAD       76
+#define OSD_KEY_RIGHT       77
+#define OSD_KEY_PLUS_PAD    78
+#define OSD_KEY_END         79
+#define OSD_KEY_DOWN        80
+#define OSD_KEY_PGDN        81
+#define OSD_KEY_INSERT      82
+#define OSD_KEY_DEL         83
+#define OSD_KEY_RCONTROL    84  /* different from Allegro */
+#define OSD_KEY_ALTGR       85  /* different from Allegro */
+/* 86 */
+#define OSD_KEY_F11         87
+#define OSD_KEY_F12         88
+#define OSD_KEY_COMMAND     89
+#define OSD_KEY_OPTION      90
+/* 91 - 100 */
+/* The following are all undefined in Allegro */
+#define OSD_KEY_1_PAD          101
+#define OSD_KEY_2_PAD          102
+#define OSD_KEY_3_PAD          103
+#define OSD_KEY_4_PAD          104
+/* 105 */
+#define OSD_KEY_6_PAD          106
+#define OSD_KEY_7_PAD          107
+#define OSD_KEY_8_PAD          108
+#define OSD_KEY_9_PAD          109
+#define OSD_KEY_0_PAD          110
+#define OSD_KEY_STOP_PAD       111
+#define OSD_KEY_EQUALS_PAD     112
+#define OSD_KEY_SLASH_PAD      113
+#define OSD_KEY_ASTER_PAD      114
+#define OSD_KEY_ENTER_PAD      115
+
+#define OSD_MAX_KEY         115
+
+// X11 keyboard mapping
+
+#define XK_KP_Enter    OSD_KEY_ENTER_PAD
+#define XK_KP_0                OSD_KEY_0_PAD
+#define XK_KP_1                OSD_KEY_1_PAD
+#define XK_KP_2                OSD_KEY_2_PAD
+#define XK_KP_3                OSD_KEY_3_PAD
+#define XK_KP_4                OSD_KEY_4_PAD
+#define XK_KP_6                OSD_KEY_6_PAD
+#define XK_KP_7                OSD_KEY_7_PAD
+#define XK_KP_8                OSD_KEY_8_PAD
+#define XK_KP_9                OSD_KEY_9_PAD
+/*
+#define XK_KP_Home     OSD_KEY_7_PAD
+#define XK_KP_Page_Up  OSD_KEY_9_PAD
+#define XK_KP_Page_Down        OSD_KEY_3_PAD
+#define XK_KP_End      OSD_KEY_1_PAD
+#define XK_KP_Left     OSD_KEY_4_PAD   
+#define XK_KP_Up       OSD_KEY_8_PAD
+#define XK_KP_Right    OSD_KEY_6_PAD
+#define XK_KP_Down     OSD_KEY_2_PAD
+*/
+#define XK_0           OSD_KEY_1
+#define XK_1           OSD_KEY_2
+#define XK_2           OSD_KEY_3
+#define XK_3           OSD_KEY_4
+#define XK_4           OSD_KEY_5
+#define XK_5           OSD_KEY_6
+#define XK_6           OSD_KEY_7
+#define XK_7           OSD_KEY_8
+#define XK_8           OSD_KEY_9
+#define XK_9           OSD_KEY_0
+#define XK_A           OSD_KEY_A
+#define XK_B           OSD_KEY_B
+#define XK_C           OSD_KEY_C
+#define XK_D           OSD_KEY_D
+#define XK_E           OSD_KEY_E
+#define XK_F           OSD_KEY_F
+#define XK_G           OSD_KEY_G
+#define XK_H           OSD_KEY_H
+#define XK_I           OSD_KEY_I
+#define XK_J           OSD_KEY_J
+#define XK_K           OSD_KEY_K
+#define XK_L           OSD_KEY_L
+#define XK_M           OSD_KEY_M
+#define XK_N           OSD_KEY_N
+#define XK_O           OSD_KEY_O
+#define XK_P           OSD_KEY_P
+#define XK_Q           OSD_KEY_Q
+#define XK_R           OSD_KEY_R
+#define XK_S           OSD_KEY_S
+#define XK_T           OSD_KEY_T
+#define XK_U           OSD_KEY_U
+#define XK_V           OSD_KEY_V
+#define XK_W           OSD_KEY_W
+#define XK_X           OSD_KEY_X
+#define XK_Y           OSD_KEY_Y
+#define XK_Z           OSD_KEY_Z
+#define XK_a           OSD_KEY_A
+#define XK_b           OSD_KEY_B
+#define XK_c           OSD_KEY_C
+#define XK_d           OSD_KEY_D
+#define XK_e           OSD_KEY_E
+#define XK_f           OSD_KEY_F
+#define XK_g           OSD_KEY_G
+#define XK_h           OSD_KEY_H
+#define XK_i           OSD_KEY_I
+#define XK_j           OSD_KEY_J
+#define XK_k           OSD_KEY_K
+#define XK_l           OSD_KEY_L
+#define XK_m           OSD_KEY_M
+#define XK_n           OSD_KEY_N
+#define XK_o           OSD_KEY_O
+#define XK_p           OSD_KEY_P
+#define XK_q           OSD_KEY_Q
+#define XK_r           OSD_KEY_R
+#define XK_s           OSD_KEY_S
+#define XK_t           OSD_KEY_T
+#define XK_u           OSD_KEY_U
+#define XK_v           OSD_KEY_V
+#define XK_w           OSD_KEY_W
+#define XK_x           OSD_KEY_X
+#define XK_y           OSD_KEY_Y
+#define XK_z           OSD_KEY_Z
+#define XK_Return      OSD_KEY_ENTER
+#define XK_Escape      OSD_KEY_ESC
+#define XK_Shift_L     OSD_KEY_LSHIFT
+#define XK_Shift_R     OSD_KEY_RSHIFT
+#define XK_Left                OSD_KEY_LEFT    
+#define XK_Up          OSD_KEY_UP
+#define XK_Right       OSD_KEY_RIGHT
+#define XK_Down                OSD_KEY_DOWN
+#define XK_BackSpace   OSD_KEY_BACKSPACE
+#define XK_Delete      OSD_KEY_DEL
+#define XK_Space       OSD_KEY_SPACE
+#define XK_F12         OSD_KEY_F12
+#define XK_F11         OSD_KEY_F11
+#define XK_F10         OSD_KEY_F10
+
+#define MOUSE_FILENAME "graphics\\mouse.gif"
+#define screen myscreen
+
+#define XFlush(a)
+#define XSync(a,b)
+#define XSetClipOrigin(a,b,c,d)
+#define XGetImage(a,b,c,d,e,f,g,h)             ((XImage *) NULL)
+#define XAutoRepeatOn(a)
+#define XAutoRepeatOff(a)
+#define XDisplayName(a)                                ((char *) NULL)
+#define XFreeColors(a,b,c,d,e)
+#define XpmFreeAttributes(a)
+#define XSelectInput(a,b,c)
+#define XDefaultDepth(a,b)                     (8)
+#define XSetWMProperties(a,b,c,d,e,f,g,h,i)
+
+#define MAX_EVENT_BUFFER 256
+
+#define Status int
+#define Bool int
+#define True 1
+#define False 0
+
+#define DUMMY_FILE (void*) -1
+#define DUMMY_MASK -1
+
+#define KeyPressMask                   (1L<<0)  
+#define KeyReleaseMask                 (1L<<1)  
+#define ButtonPressMask                        (1L<<2)  
+#define ButtonReleaseMask              (1L<<3)  
+#define ButtonMotionMask               (1L<<13) 
+#define ExposureMask                   (1L<<15) 
+#define StructureNotifyMask            (1L<<17) 
+#define FocusChangeMask                        (1L<<21) 
+
+#define KeyPress               2
+#define KeyRelease             3
+#define ButtonPress            4
+#define ButtonRelease          5
+#define MotionNotify           6
+#define FocusIn                        9
+#define FocusOut               10
+#define Expose                 12
+#define UnmapNotify            18
+#define MapNotify              19
+
+#define GCForeground            (1L<<2)
+#define GCBackground            (1L<<3)
+#define GCGraphicsExposures     (1L<<16)
+#define GCClipMask             (1L<<19)
+
+#define NormalState 1  /* most applications want to start this way */
+#define InputHint              (1L << 0)
+#define StateHint              (1L << 1)
+#define IconPixmapHint         (1L << 2)
+#define IconMaskHint           (1L << 5)
+#define PSize          (1L << 3) /* program specified size */
+#define PMinSize       (1L << 4) /* program specified minimum size */
+#define PMaxSize       (1L << 5) /* program specified maximum size */
+
+#define XpmSuccess       0
+#define XpmOpenFailed   -1
+#define XpmFileInvalid  -2
+#define XpmNoMemory     -3
+#define XpmColorFailed  -4
+#define XpmCloseness      (1L<<12)
+
+#define BitmapSuccess          0
+#define BitmapOpenFailed       1
+#define BitmapFileInvalid      2
+#define BitmapNoMemory         3
+
+#define ZPixmap                        2       /* depth == drawable depth */
+
+#define DefaultScreen(dpy)     (((_XPrivDisplay)dpy)->default_screen)
+#define DefaultColormap(dpy, scr)(ScreenOfDisplay(dpy,scr)->cmap)
+#define ScreenOfDisplay(dpy, scr)(&((_XPrivDisplay)dpy)->screens[scr])
+#define BlackPixel(dpy, scr)   (ScreenOfDisplay(dpy,scr)->black_pixel)
+#define WhitePixel(dpy, scr)   (ScreenOfDisplay(dpy,scr)->white_pixel)
+#define RootWindow(dpy, scr)   (ScreenOfDisplay(dpy,scr)->root)
+#define AllPlanes              ((unsigned long)~0L)
+
+#define XGetPixel(ximage, x, y) \
+       ((*((ximage)->f.get_pixel))((ximage), (x), (y)))
+
+typedef unsigned long Pixel;   /* Index into colormap */
+typedef unsigned long XID;
+typedef XID Window;
+typedef XID Drawable;
+typedef XID Pixmap;
+typedef XID Colormap;
+typedef XID KeySym;
+typedef XID GContext;
+typedef struct _XDisplay Display;
+
+typedef struct _XGC
+{
+    GContext gid;      /* protocol ID for graphics context */
+} *GC;
+
+typedef struct {
+       Colormap cmap;          /* default color map */
+       Window root;            /* Root window id. */
+       unsigned long white_pixel;
+       unsigned long black_pixel;      /* White and Black pixel values */
+       int x;
+       int y;
+       unsigned int width;
+       unsigned int height;
+       BITMAP *video_bitmap;
+} Screen;
+
+typedef struct _XDisplay
+{
+       int default_screen;     /* default screen for operations */
+       Screen *screens;        /* pointer to list of screens */
+       BITMAP *mouse_ptr;
+} *_XPrivDisplay;
+
+typedef struct _XImage {
+    struct funcs {
+       unsigned long (*get_pixel)  (struct _XImage *, int, int);
+    } f;
+} XImage;
+
+typedef struct {
+       long flags;     /* marks which fields in this structure are defined */
+       int width, height;      /* should set so old wm's don't mess up */
+       int min_width, min_height;
+       int max_width, max_height;
+} XSizeHints;
+
+typedef struct {
+       long flags;     /* marks which fields in this structure are defined */
+       Bool input;     /* does this application rely on the window manager to
+                       get keyboard input? */
+       int initial_state;      /* see below */
+       Pixmap icon_pixmap;     /* pixmap to be used as icon */
+       Pixmap icon_mask;       /* icon mask bitmap */
+} XWMHints;
+
+typedef struct {
+       char *res_name;
+       char *res_class;
+} XClassHint;
+
+typedef struct {
+    unsigned char *value;              /* same as Property routines */
+} XTextProperty;
+
+typedef struct {
+       unsigned long foreground;/* foreground pixel */
+       unsigned long background;/* background pixel */
+       Bool graphics_exposures;/* boolean, should exposures be generated */
+       Pixmap clip_mask;       /* bitmap clipping; other calls for rects */
+       int clip_x_origin;      /* origin for clipping */
+       int clip_y_origin;
+       unsigned long value_mask;
+} XGCValues;
+
+typedef struct {
+    unsigned long valuemask;           /* Specifies which attributes are */
+    unsigned int closeness;            /* Allowable RGB deviation */
+    Pixel *pixels;                     /* List of used color pixels */
+    unsigned int npixels;              /* Number of used pixels */
+} XpmAttributes;
+
+typedef struct {
+       int type;
+       int x, y;
+       int width, height;
+} XExposeEvent;
+
+typedef struct {
+       int type;               /* of event */
+       int x, y;               /* pointer x, y coordinates in event window */
+       unsigned int button;    /* detail */
+} XButtonEvent;
+
+typedef struct {
+       int type;
+       int x, y;               /* pointer x, y coordinates in event window */
+} XMotionEvent;
+
+typedef struct {
+       int type;               /* of event */
+       unsigned int state;     /* key or button mask */
+} XKeyEvent;
+
+typedef struct {
+       int type;               /* FocusIn or FocusOut */
+} XFocusChangeEvent;
+
+
+typedef union _XEvent {
+        int type;              /* must not be changed; first element */
+       XExposeEvent xexpose;
+       XButtonEvent xbutton;
+       XMotionEvent xmotion;
+       XKeyEvent xkey;
+} XEvent;
+
+
+extern void XMapWindow(Display*, Window);
+//extern void XFlush(Display*);
+extern Display *XOpenDisplay(char*);
+//extern char *XDisplayName(char*);
+extern Window XCreateSimpleWindow(Display*, Window, int, int, unsigned int, unsigned int, unsigned int, unsigned long, unsigned long);
+extern int XReadBitmapFile(Display*, Drawable, char*, unsigned int*, unsigned int*, Pixmap*, int*, int*);
+extern Status XStringListToTextProperty(char**, int, XTextProperty*);
+//extern void XSetWMProperties(Display*, Window, XTextProperty*, XTextProperty*, char**, int, XSizeHints*, XWMHints*, XClassHint*);
+extern void XFree(void*);
+//extern void XSelectInput(Display*, Window, long);
+extern GC XCreateGC(Display*, Drawable, unsigned long, XGCValues*);
+extern void XFillRectangle(Display*, Drawable, GC, int, int, unsigned int, unsigned int);
+extern Pixmap XCreatePixmap(Display*, Drawable, unsigned int, unsigned int, unsigned int);
+//extern int XDefaultDepth(Display*, int);
+extern inline void XCopyArea(Display*, Drawable, Drawable, GC, int, int, unsigned int, unsigned int, int, int);
+extern int XpmReadFileToPixmap(Display*, Drawable, char*, Pixmap*, Pixmap*, XpmAttributes*);
+//extern void XFreeColors(Display*, Colormap, unsigned long*, int, unsigned long);
+//extern void XpmFreeAttributes(XpmAttributes*);
+extern void XFreePixmap(Display*, Pixmap);
+extern void XFreeGC(Display*, GC);
+extern void XCloseDisplay(Display*);
+extern int XPending(Display*);
+extern void XNextEvent(Display*, XEvent*);
+//extern void XSync(Display*, Bool);
+//extern void XAutoRepeatOn(Display*);
+//extern void XAutoRepeatOff(Display*);
+extern KeySym XLookupKeysym(XKeyEvent*, int);
+//extern void XSetClipOrigin(Display*, GC, int, int);
+//extern XImage *XGetImage(Display*, Drawable, int, int, unsigned int, unsigned int, unsigned long, int);
+
+BITMAP *load_gif(char *filename, RGB *pal);
\ No newline at end of file