rnd-20131212-1-src
[rocksndiamonds.git] / src / libgame / system.c
index 4b7a3cad7a238069e30d6f60bf345ce23e59e41e..988a97fae17f47e8b2d44deafc2a1f68e7d58836 100644 (file)
@@ -46,6 +46,8 @@ LevelDirTree         *leveldir_first = NULL;
 LevelDirTree          *leveldir_current = NULL;
 int                    level_nr;
 
+struct LevelStats      level_stats[MAX_LEVELS];
+
 Display                       *display = NULL;
 Visual                *visual = NULL;
 int                    screen = 0;
@@ -57,6 +59,9 @@ DrawBuffer           *drawto = NULL;
 
 int                    button_status = MB_NOT_PRESSED;
 boolean                        motion_status = FALSE;
+#if defined(TARGET_SDL2)
+boolean                        keyrepeat_status = TRUE;
+#endif
 
 int                    redraw_mask = REDRAW_NONE;
 int                    redraw_tiles = 0;
@@ -103,6 +108,11 @@ void InitProgramInfo(char *argv0,
   program.error_file = stderr;
 }
 
+void InitExitMessageFunction(void (*exit_message_function)(char *, va_list))
+{
+  program.exit_message_function = exit_message_function;
+}
+
 void InitExitFunction(void (*exit_function)(int))
 {
   program.exit_function = exit_function;
@@ -119,6 +129,9 @@ void InitExitFunction(void (*exit_function)(int))
 
 void InitPlatformDependentStuff(void)
 {
+  // this is initialized in GetOptions(), but may already be used before
+  options.verbose = TRUE;
+
 #if defined(PLATFORM_MSDOS)
   _fmode = O_BINARY;
 #endif
@@ -127,12 +140,22 @@ void InitPlatformDependentStuff(void)
   updateUserGameDataDir();
 #endif
 
+#if 1
+  openErrorFile();
+#else
 #if !defined(PLATFORM_UNIX) || defined(PLATFORM_MACOSX)
   openErrorFile();
 #endif
+#endif
 
 #if defined(TARGET_SDL)
-  if (SDL_Init(SDL_INIT_EVENTTHREAD | SDL_INIT_NOPARACHUTE) < 0)
+#if defined(TARGET_SDL2)
+  int sdl_init_flags = SDL_INIT_EVENTS      | SDL_INIT_NOPARACHUTE;
+#else
+  int sdl_init_flags = SDL_INIT_EVENTTHREAD | SDL_INIT_NOPARACHUTE;
+#endif
+
+  if (SDL_Init(sdl_init_flags) < 0)
     Error(ERR_EXIT, "SDL_Init() failed: %s", SDL_GetError());
 
   SDLNet_Init();
@@ -244,6 +267,8 @@ void SetDrawBackgroundMask(int draw_background_mask)
   gfx.draw_background_mask = draw_background_mask;
 }
 
+#if 0
+
 static void DrawBitmapFromTile(Bitmap *bitmap, Bitmap *tile,
                               int dest_x, int dest_y, int width, int height)
 {
@@ -300,6 +325,39 @@ void SetBackgroundBitmap(Bitmap *background_bitmap_tile, int mask)
   }
 }
 
+#else
+
+void SetBackgroundBitmap(Bitmap *background_bitmap_tile, int mask)
+{
+  if (background_bitmap_tile != NULL)
+    gfx.background_bitmap_mask |= mask;
+  else
+    gfx.background_bitmap_mask &= ~mask;
+
+#if 0
+  if (gfx.background_bitmap == NULL)
+    gfx.background_bitmap = CreateBitmap(video.width, video.height,
+                                        DEFAULT_DEPTH);
+#endif
+
+  if (background_bitmap_tile == NULL)  /* empty background requested */
+    return;
+
+  if (mask == REDRAW_ALL)
+    BlitBitmapTiled(background_bitmap_tile, gfx.background_bitmap, 0, 0, 0, 0,
+                   0, 0, video.width, video.height);
+  else if (mask == REDRAW_FIELD)
+    BlitBitmapTiled(background_bitmap_tile, gfx.background_bitmap, 0, 0, 0, 0,
+                   gfx.real_sx, gfx.real_sy, gfx.full_sxsize, gfx.full_sysize);
+  else if (mask == REDRAW_DOOR_1)
+  {
+    BlitBitmapTiled(background_bitmap_tile, gfx.background_bitmap, 0, 0, 0, 0,
+                   gfx.dx, gfx.dy, gfx.dxsize, gfx.dysize);
+  }
+}
+
+#endif
+
 void SetWindowBackgroundBitmap(Bitmap *background_bitmap_tile)
 {
   /* remove every mask before setting mask for window */
@@ -648,14 +706,17 @@ void BlitBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap,
     height = dst_bitmap->height - dst_y;
 #endif
 
-#if 0
+#if 1
+  /* !!! 2013-12-11: An "old friend" is back. Same bug in SDL2 2.0.1 !!! */
+#if 1
   /* !!! 2009-03-30: Fixed by using self-compiled, patched SDL.dll !!! */
   /* (This bug still exists in the actual (as of 2009-06-15) version 1.2.13,
      but is already fixed in SVN and should therefore finally be fixed with
      the next official SDL release, which is probably version 1.2.14.) */
 #if 1
   /* !!! 2009-03-24: It seems that this problem still exists in 1.2.12 !!! */
-#if defined(TARGET_SDL) && defined(PLATFORM_WIN32)
+  //#if defined(TARGET_SDL) && defined(PLATFORM_WIN32)
+#if defined(TARGET_SDL2)
   if (src_bitmap == dst_bitmap)
   {
     /* !!! THIS IS A BUG (IN THE SDL LIBRARY?) AND SHOULD BE FIXED !!! */
@@ -699,12 +760,46 @@ void BlitBitmap(Bitmap *src_bitmap, Bitmap *dst_bitmap,
   }
 #endif
 #endif
+#endif
+#endif
+
+#if 0
+  if (dst_x < gfx.sx + gfx.sxsize)
+    printf("::: %d: BlitBitmap(%d, %d, %d, %d)\n",
+          FrameCounter, dst_x, dst_y, width, height);
 #endif
 
   sysCopyArea(src_bitmap, dst_bitmap,
              src_x, src_y, width, height, dst_x, dst_y, BLIT_OPAQUE);
 }
 
+void BlitBitmapTiled(Bitmap *src_bitmap, Bitmap *dst_bitmap,
+                    int src_x, int src_y, int src_width, int src_height,
+                    int dst_x, int dst_y, int dst_width, int dst_height)
+{
+  int src_xsize = (src_width  == 0 ? src_bitmap->width  : src_width);
+  int src_ysize = (src_height == 0 ? src_bitmap->height : src_height);
+  int dst_xsize = dst_width;
+  int dst_ysize = dst_height;
+  int src_xsteps = (dst_xsize + src_xsize - 1) / src_xsize;
+  int src_ysteps = (dst_ysize + src_ysize - 1) / src_ysize;
+  int x, y;
+
+  for (y = 0; y < src_ysteps; y++)
+  {
+    for (x = 0; x < src_xsteps; x++)
+    {
+      int draw_x = dst_x + x * src_xsize;
+      int draw_y = dst_y + y * src_ysize;
+      int draw_xsize = MIN(src_xsize, dst_xsize - x * src_xsize);
+      int draw_ysize = MIN(src_ysize, dst_ysize - y * src_ysize);
+
+      BlitBitmap(src_bitmap, dst_bitmap, src_x, src_y, draw_xsize, draw_ysize,
+                draw_x, draw_y);
+    }
+  }
+}
+
 void FadeRectangle(Bitmap *bitmap_cross, int x, int y, int width, int height,
                   int fade_mode, int fade_delay, int post_delay,
                   void (*draw_border_function)(void))
@@ -927,7 +1022,7 @@ Pixel GetPixelFromRGBcompact(Bitmap *bitmap, unsigned int color)
 /* execute all pending screen drawing operations */
 void FlushDisplay(void)
 {
-#ifndef TARGET_SDL
+#if !defined(TARGET_SDL)
   XFlush(display);
 #endif
 }
@@ -935,7 +1030,7 @@ void FlushDisplay(void)
 /* execute and wait for all pending screen drawing operations */
 void SyncDisplay(void)
 {
-#ifndef TARGET_SDL
+#if !defined(TARGET_SDL)
   XSync(display, FALSE);
 #endif
 }
@@ -943,9 +1038,13 @@ void SyncDisplay(void)
 void KeyboardAutoRepeatOn(void)
 {
 #if defined(TARGET_SDL)
+#if defined(TARGET_SDL2)
+  keyrepeat_status = TRUE;
+#else
   SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY / 2,
                      SDL_DEFAULT_REPEAT_INTERVAL / 2);
   SDL_EnableUNICODE(1);
+#endif
 #else
   if (display)
     XAutoRepeatOn(display);
@@ -955,8 +1054,12 @@ void KeyboardAutoRepeatOn(void)
 void KeyboardAutoRepeatOff(void)
 {
 #if defined(TARGET_SDL)
+#if defined(TARGET_SDL2)
+  keyrepeat_status = FALSE;
+#else
   SDL_EnableKeyRepeat(0, SDL_DEFAULT_REPEAT_INTERVAL);
   SDL_EnableUNICODE(0);
+#endif
 #else
   if (display)
     XAutoRepeatOff(display);
@@ -1110,7 +1213,9 @@ static void CreateScaledBitmaps(Bitmap *old_bitmap, int zoom_factor,
   int width_4, height_4;
   int width_8, height_8;
   int width_16, height_16;
+#if 0
   int width_32, height_32;
+#endif
   int new_width, new_height;
 
   /* calculate new image dimensions for normal sized image */
@@ -1141,8 +1246,10 @@ static void CreateScaledBitmaps(Bitmap *old_bitmap, int zoom_factor,
     height_8 = height_1 / 8;
     width_16  = width_1  / 16;
     height_16 = height_1 / 16;
+#if 0
     width_32  = width_1  / 32;
     height_32 = height_1 / 32;
+#endif
 
     UPDATE_BUSY_STATE();
 
@@ -1205,11 +1312,11 @@ static void CreateScaledBitmaps(Bitmap *old_bitmap, int zoom_factor,
     if (old_bitmap->surface_masked)
       SDL_FreeSurface(old_bitmap->surface_masked);
 
-    SDL_SetColorKey(tmp_surface_1, SDL_SRCCOLORKEY,
+    SDL_SetColorKey(tmp_surface_1, SET_TRANSPARENT_PIXEL,
                    SDL_MapRGB(tmp_surface_1->format, 0x00, 0x00, 0x00));
     if ((old_bitmap->surface_masked = SDL_DisplayFormat(tmp_surface_1)) ==NULL)
       Error(ERR_EXIT, "SDL_DisplayFormat() failed");
-    SDL_SetColorKey(tmp_surface_1, 0, 0);      /* reset transparent pixel */
+    SDL_SetColorKey(tmp_surface_1, UNSET_TRANSPARENT_PIXEL, 0);
 #endif
   }
 #endif
@@ -1296,11 +1403,11 @@ static void CreateScaledBitmaps(Bitmap *old_bitmap, int zoom_factor,
     if (old_bitmap->surface_masked)
       SDL_FreeSurface(old_bitmap->surface_masked);
 
-    SDL_SetColorKey(old_surface, SDL_SRCCOLORKEY,
+    SDL_SetColorKey(old_surface, SET_TRANSPARENT_PIXEL,
                    SDL_MapRGB(old_surface->format, 0x00, 0x00, 0x00));
     if ((old_bitmap->surface_masked = SDL_DisplayFormat(old_surface)) ==NULL)
       Error(ERR_EXIT, "SDL_DisplayFormat() failed");
-    SDL_SetColorKey(old_surface, 0, 0);                /* reset transparent pixel */
+    SDL_SetColorKey(old_surface, UNSET_TRANSPARENT_PIXEL, 0);
 #endif
   }
 #endif
@@ -1538,10 +1645,14 @@ void SetAudioMode(boolean enabled)
 
 void InitEventFilter(EventFilter filter_function)
 {
-#if defined(TARGET_SDL)
   /* set event filter to filter out certain events */
+#if defined(TARGET_SDL)
+#if defined(TARGET_SDL2)
+  SDL_SetEventFilter(filter_function, NULL);
+#else
   SDL_SetEventFilter(filter_function);
 #endif
+#endif
 }
 
 boolean PendingEvent(void)
@@ -1565,7 +1676,11 @@ void NextEvent(Event *event)
 void PeekEvent(Event *event)
 {
 #if defined(TARGET_SDL)
+#if defined(TARGET_SDL2)
+  SDL_PeepEvents(event, 1, SDL_PEEKEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT);
+#else
   SDL_PeepEvents(event, 1, SDL_PEEKEVENT, SDL_ALLEVENTS);
+#endif
 #else
   XPeekEvent(display, event);
 #endif
@@ -1574,6 +1689,10 @@ void PeekEvent(Event *event)
 Key GetEventKey(KeyEvent *event, boolean with_modifiers)
 {
 #if defined(TARGET_SDL)
+#if defined(TARGET_SDL2)
+  /* key up/down events in SDL2 do not return text characters anymore */
+  return event->keysym.sym;
+#else
 
 #if 0
   printf("unicode == '%d', sym == '%d', mod == '0x%04x'\n",
@@ -1589,6 +1708,7 @@ Key GetEventKey(KeyEvent *event, boolean with_modifiers)
   else
     return event->keysym.sym;
 
+#endif
 #else
 
 #if 0