rnd-20020803-1-src
[rocksndiamonds.git] / src / libgame / system.c
index 7962345528d0213a492de88aea4e8cb5d160b01e..cc7dc2aa33fb4111ff5f737ca76a4a731437960c 100644 (file)
@@ -1,7 +1,7 @@
 /***********************************************************
 * Artsoft Retro-Game Library                               *
 *----------------------------------------------------------*
-* (c) 1994-2001 Artsoft Entertainment                      *
+* (c) 1994-2002 Artsoft Entertainment                      *
 *               Holger Schemel                             *
 *               Detmolder Strasse 189                      *
 *               33604 Bielefeld                            *
@@ -112,18 +112,11 @@ void ClosePlatformDependantStuff(void)
 
 void InitProgramInfo(char *unix_userdata_directory, char *program_title,
                     char *window_title, char *icon_title,
-                    char *x11_icon_basename, char *x11_iconmask_basename,
-                    char *msdos_pointer_basename,
+                    char *x11_icon_filename, char *x11_iconmask_filename,
+                    char *msdos_pointer_filename,
                     char *cookie_prefix, char *filename_prefix,
                     int program_version)
 {
-  char *x11_icon_filename =
-    getPath2(options.graphics_directory, x11_icon_basename);
-  char *x11_iconmask_filename =
-    getPath2(options.graphics_directory, x11_iconmask_basename);
-  char *msdos_pointer_filename =
-    getPath2(options.graphics_directory, msdos_pointer_basename);
-
 #if defined(PLATFORM_UNIX)
   program.userdata_directory = unix_userdata_directory;
 #else
@@ -215,6 +208,7 @@ inline void CloseVideoDisplay(void)
 #if defined(TARGET_SDL)
   SDL_QuitSubSystem(SDL_INIT_VIDEO);
 #else
+
   if (display)
     XCloseDisplay(display);
 #endif
@@ -287,7 +281,7 @@ inline Bitmap *CreateBitmap(int width, int height, int depth)
   return new_bitmap;
 }
 
-inline void FreeBitmap(Bitmap *bitmap)
+inline static void FreeBitmapPointers(Bitmap *bitmap)
 {
   if (bitmap == NULL)
     return;
@@ -297,17 +291,48 @@ inline void FreeBitmap(Bitmap *bitmap)
     SDL_FreeSurface(bitmap->surface);
   if (bitmap->surface_masked)
     SDL_FreeSurface(bitmap->surface_masked);
+  bitmap->surface = NULL;
+  bitmap->surface_masked = NULL;
 #else
+  /* The X11 version seems to have a memory leak here -- although
+     "XFreePixmap()" is called, the correspondig memory seems not
+     to be freed (according to "ps"). The SDL version apparently
+     does not have this problem. */
+
   if (bitmap->drawable)
     XFreePixmap(display, bitmap->drawable);
   if (bitmap->clip_mask)
     XFreePixmap(display, bitmap->clip_mask);
   if (bitmap->stored_clip_gc)
     XFreeGC(display, bitmap->stored_clip_gc);
+  /* the other GCs are only pointers to GCs used elsewhere */
+  bitmap->drawable = None;
+  bitmap->clip_mask = None;
+  bitmap->stored_clip_gc = None;
 #endif
 
   if (bitmap->source_filename)
     free(bitmap->source_filename);
+  bitmap->source_filename = NULL;
+}
+
+inline static void TransferBitmapPointers(Bitmap *src_bitmap,
+                                         Bitmap *dst_bitmap)
+{
+  if (src_bitmap == NULL || dst_bitmap == NULL)
+    return;
+
+  FreeBitmapPointers(dst_bitmap);
+
+  *dst_bitmap = *src_bitmap;
+}
+
+inline void FreeBitmap(Bitmap *bitmap)
+{
+  if (bitmap == NULL)
+    return;
+
+  FreeBitmapPointers(bitmap);
 
   free(bitmap);
 }
@@ -332,6 +357,16 @@ inline boolean DrawingDeactivated(int x, int y, int width, int height)
     if ((gfx.draw_deactivation_mask & REDRAW_FIELD) &&
        x < gfx.sx + gfx.sxsize)
       return TRUE;
+    else if ((gfx.draw_deactivation_mask & REDRAW_DOORS) &&
+            x > gfx.dx)
+    {
+      if ((gfx.draw_deactivation_mask & REDRAW_DOOR_1) &&
+         y < gfx.dy + gfx.dysize)
+       return TRUE;
+      else if ((gfx.draw_deactivation_mask & REDRAW_DOOR_2) &&
+              y > gfx.vy)
+       return TRUE;
+    }
   }
 
   return FALSE;
@@ -634,22 +669,64 @@ Bitmap *LoadImage(char *filename)
   new_bitmap = X11LoadImage(filename);
 #endif
 
+  if (new_bitmap)
+    new_bitmap->source_filename = getStringCopy(filename);
+
   return new_bitmap;
 }
 
 Bitmap *LoadCustomImage(char *basename)
 {
-  char *filename = getStringCopy(getCustomImageFilename(basename));
+  char *filename = getCustomImageFilename(basename);
   Bitmap *new_bitmap;
 
+  if (filename == NULL)
+    Error(ERR_EXIT, "LoadCustomImage(): cannot find file '%s'", basename);
+
   if ((new_bitmap = LoadImage(filename)) == NULL)
     Error(ERR_EXIT, "LoadImage() failed: %s", GetError());
 
-  new_bitmap->source_filename = filename;
-
   return new_bitmap;
 }
 
+void ReloadCustomImage(Bitmap *bitmap, char *basename)
+{
+  char *filename = getCustomImageFilename(basename);
+  Bitmap *new_bitmap;
+
+  if (filename == NULL)                /* (should never happen) */
+  {
+    Error(ERR_WARN, "ReloadCustomImage(): cannot find file '%s'", basename);
+    return;
+  }
+
+  if (strcmp(filename, bitmap->source_filename) == 0)
+  {
+    /* The old and new image are the same (have the same filename and path).
+       This usually means that this image does not exist in this graphic set
+       and a fallback to the existing image is done. */
+
+    return;
+  }
+
+  if ((new_bitmap = LoadImage(filename)) == NULL)
+  {
+    Error(ERR_WARN, "LoadImage() failed: %s", GetError());
+    return;
+  }
+
+  if (bitmap->width != new_bitmap->width ||
+      bitmap->height != new_bitmap->height)
+  {
+    Error(ERR_WARN, "ReloadCustomImage: new image has wrong dimensions");
+    FreeBitmap(new_bitmap);
+    return;
+  }
+
+  TransferBitmapPointers(new_bitmap, bitmap);
+  free(new_bitmap);
+}
+
 
 /* ========================================================================= */
 /* audio functions                                                           */
@@ -661,17 +738,18 @@ inline void OpenAudio(void)
   audio.sound_available = FALSE;
   audio.music_available = FALSE;
   audio.loops_available = FALSE;
-  audio.mods_available = FALSE;
+
   audio.sound_enabled = FALSE;
+  audio.sound_deactivated = FALSE;
 
-  audio.soundserver_pipe[0] = audio.soundserver_pipe[1] = 0;
-  audio.soundserver_pid = 0;
+  audio.mixer_pipe[0] = audio.mixer_pipe[1] = 0;
+  audio.mixer_pid = -1;
   audio.device_name = NULL;
-  audio.device_fd = 0;
+  audio.device_fd = -1;
 
-  audio.channels = 0;
+  audio.num_channels = 0;
   audio.music_channel = 0;
-  audio.music_nr = 0;
+  audio.first_sound_channel = 0;
 
 #if defined(TARGET_SDL)
   SDLOpenAudio();
@@ -744,7 +822,9 @@ inline Key GetEventKey(KeyEvent *event, boolean with_modifiers)
         (int)SDL_GetModState());
 #endif
 
-  if (with_modifiers && event->keysym.unicode != 0)
+  if (with_modifiers &&
+      event->keysym.unicode > 0x0000 &&
+      event->keysym.unicode < 0x2000)
     return event->keysym.unicode;
   else
     return event->keysym.sym;