rnd-20030105-1-src
[rocksndiamonds.git] / src / libgame / system.c
index 2ffce00752cf5c9348f839c7d3b8381a5e8be7e3..c071fee890f37242231dc8c7bbcaaadfe2da8dc7 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                            *
@@ -36,6 +36,7 @@ struct OptionInfo     options;
 struct VideoSystemInfo video;
 struct AudioSystemInfo audio;
 struct GfxInfo         gfx;
+struct FontInfo                font;
 struct ArtworkInfo     artwork;
 struct JoystickInfo    joystick;
 struct SetupInfo       setup;
@@ -94,6 +95,9 @@ void InitPlatformDependantStuff(void)
 
 #if !defined(PLATFORM_UNIX)
   program.userdata_directory = "userdata";
+#endif
+
+#if defined(PLATFORM_MSDOS)
   initErrorFile();
 #endif
 
@@ -105,7 +109,7 @@ void InitPlatformDependantStuff(void)
 
 void ClosePlatformDependantStuff(void)
 {
-#if !defined(PLATFORM_UNIX)
+#if defined(PLATFORM_MSDOS)
   dumpErrorFile();
 #endif
 }
@@ -182,6 +186,11 @@ void SetDrawDeactivationMask(int draw_deactivation_mask)
   gfx.draw_deactivation_mask = draw_deactivation_mask;
 }
 
+void SetBackgroundBitmap(Bitmap *background_bitmap)
+{
+  gfx.background_bitmap = background_bitmap;
+}
+
 
 /* ========================================================================= */
 /* video functions                                                           */
@@ -291,7 +300,14 @@ inline static void FreeBitmapPointers(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)
@@ -299,13 +315,18 @@ inline static void FreeBitmapPointers(Bitmap *bitmap)
   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 void TransferBitmapPointers(Bitmap *src_bitmap, Bitmap *dst_bitmap)
+inline static void TransferBitmapPointers(Bitmap *src_bitmap,
+                                         Bitmap *dst_bitmap)
 {
   if (src_bitmap == NULL || dst_bitmap == NULL)
     return;
@@ -342,14 +363,31 @@ inline boolean DrawingDeactivated(int x, int y, int width, int height)
 {
   if (gfx.draw_deactivation_mask != REDRAW_NONE)
   {
-    if ((gfx.draw_deactivation_mask & REDRAW_FIELD) &&
-       x < gfx.sx + gfx.sxsize)
+    if (gfx.draw_deactivation_mask & REDRAW_ALL)
+      return TRUE;
+    else 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;
 }
 
+inline boolean DrawingOnBackground(int x, int y)
+{
+  return (gfx.background_bitmap != NULL && x < gfx.sx + gfx.sxsize);
+}
+
 inline void BlitBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap,
                       int src_x, int src_y,
                       int width, int height,
@@ -379,6 +417,16 @@ inline void ClearRectangle(Bitmap *bitmap, int x, int y, int width, int height)
 #endif
 }
 
+inline void ClearRectangleOnBackground(Bitmap *bitmap, int x, int y,
+                                      int width, int height)
+{
+  if (!DrawingOnBackground(x, y))
+    ClearRectangle(bitmap, x, y, width, height);
+  else
+    BlitBitmap(gfx.background_bitmap, bitmap,
+              x - gfx.real_sx, y - gfx.real_sy, width, height, x, y);
+}
+
 #if 0
 #ifndef TARGET_SDL
 static GC last_clip_gc = 0;    /* needed for XCopyArea() through clip mask */
@@ -430,6 +478,29 @@ inline void BlitBitmapMasked(Bitmap *src_bitmap, Bitmap *dst_bitmap,
 #endif
 }
 
+inline void BlitBitmapOnBackground(Bitmap *src_bitmap, Bitmap *dst_bitmap,
+                                  int src_x, int src_y,
+                                  int width, int height,
+                                  int dst_x, int dst_y)
+{
+  if (!DrawingOnBackground(src_x, src_y))
+    BlitBitmap(src_bitmap, dst_bitmap, src_x, src_y, width, height,
+              dst_x, dst_y);
+  else
+  {
+    /* draw background */
+    BlitBitmap(gfx.background_bitmap, dst_bitmap,
+              dst_x - gfx.real_sx, dst_y - gfx.real_sy, width, height,
+              dst_x, dst_y);
+
+    /* draw foreground */
+    SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc,
+                 dst_x - src_x, dst_y - src_y);
+    BlitBitmapMasked(src_bitmap, dst_bitmap, src_x, src_y, width, height,
+                    dst_x, dst_y);
+  }
+}
+
 inline void DrawSimpleWhiteLine(Bitmap *bitmap, int from_x, int from_y,
                                int to_x, int to_y)
 {
@@ -647,7 +718,8 @@ Bitmap *LoadImage(char *filename)
   new_bitmap = X11LoadImage(filename);
 #endif
 
-  new_bitmap->source_filename = getStringCopy(filename);
+  if (new_bitmap)
+    new_bitmap->source_filename = getStringCopy(filename);
 
   return new_bitmap;
 }
@@ -666,57 +738,43 @@ Bitmap *LoadCustomImage(char *basename)
   return new_bitmap;
 }
 
-Bitmap *ReloadCustomImage(Bitmap **bitmap, char *basename)
+void ReloadCustomImage(Bitmap *bitmap, char *basename)
 {
   char *filename = getCustomImageFilename(basename);
-  Bitmap *old_bitmap = *bitmap;
   Bitmap *new_bitmap;
 
   if (filename == NULL)                /* (should never happen) */
   {
     Error(ERR_WARN, "ReloadCustomImage(): cannot find file '%s'", basename);
-    return NULL;
+    return;
   }
 
-  if (strcmp(filename, old_bitmap->source_filename) == 0)
+  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 NULL;
+    return;
   }
 
   if ((new_bitmap = LoadImage(filename)) == NULL)
   {
     Error(ERR_WARN, "LoadImage() failed: %s", GetError());
-    return NULL;
+    return;
   }
 
-  if (old_bitmap->width != new_bitmap->width ||
-      old_bitmap->height != new_bitmap->height)
+  if (bitmap->width != new_bitmap->width ||
+      bitmap->height != new_bitmap->height)
   {
-    Error(ERR_WARN, "ReloadCustomImage: new image has wrong dimensions");
+    Error(ERR_WARN, "ReloadCustomImage: new image '%s' has wrong dimensions",
+         filename);
     FreeBitmap(new_bitmap);
-    return NULL;
+    return;
   }
 
-#if 0
-  /* copy filename for new image */
-  free(old_bitmap->source_filename);
-  old_bitmap->source_filename = getStringCopy(filename);
-
-  /* copy bitmap data for new image */
-  BlitBitmap(new_bitmap, old_bitmap, 0,0,
-            old_bitmap->width, old_bitmap->height, 0,0);
-
-  FreeBitmap(new_bitmap);
-#else
-  /*
-  *bitmap = new_bitmap;
-  */
-  return new_bitmap;
-#endif
+  TransferBitmapPointers(new_bitmap, bitmap);
+  free(new_bitmap);
 }
 
 
@@ -730,17 +788,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();
@@ -813,7 +872,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;