changed comments from old to new style (one-line comments only)
[rocksndiamonds.git] / src / libgame / sdl.c
index 8751f1b999dfa4de510e8eacf78aee61a9684e11..6d2cb4d1133c18352b13b7bdcdf6c4a3eb6c558b 100644 (file)
 #include "misc.h"
 #include "setup.h"
 
-#define ENABLE_UNUSED_CODE     0       /* currently unused functions */
+#define ENABLE_UNUSED_CODE     0       // currently unused functions
 
+#define DEBUG_JOYSTICKS                0
 
-/* ========================================================================= */
-/* video functions                                                           */
-/* ========================================================================= */
 
-/* SDL internal variables */
+// ============================================================================
+// video functions
+// ============================================================================
+
+// SDL internal variables
 #if defined(TARGET_SDL2)
 static SDL_Window *sdl_window = NULL;
 static SDL_Renderer *sdl_renderer = NULL;
@@ -34,11 +36,11 @@ static boolean fullscreen_enabled = FALSE;
 static boolean limit_screen_updates = FALSE;
 
 
-/* functions from SGE library */
+// functions from SGE library
 void sge_Line(SDL_Surface *, Sint16, Sint16, Sint16, Sint16, Uint32);
 
 #if defined(USE_TOUCH_INPUT_OVERLAY)
-/* functions to draw overlay graphics for touch device input */
+// functions to draw overlay graphics for touch device input
 static void DrawTouchInputOverlay();
 #endif
 
@@ -60,12 +62,16 @@ static void FinalizeScreen(int draw_target)
   // copy global animations to render target buffer, if defined (above border)
   if (gfx.draw_global_anim_function != NULL)
     gfx.draw_global_anim_function(draw_target, DRAW_GLOBAL_ANIM_STAGE_2);
+
+  // copy tile selection cursor to render target buffer, if defined (above all)
+  if (gfx.draw_tile_cursor_function != NULL)
+    gfx.draw_tile_cursor_function(draw_target);
 }
 
 static void UpdateScreenExt(SDL_Rect *rect, boolean with_frame_delay)
 {
   static unsigned int update_screen_delay = 0;
-  unsigned int update_screen_delay_value = 50;         /* (milliseconds) */
+  unsigned int update_screen_delay_value = 50;         // (milliseconds)
   SDL_Surface *screen = backbuffer->surface;
 
   if (limit_screen_updates &&
@@ -239,6 +245,20 @@ static void UpdateScreen_WithoutFrameDelay(SDL_Rect *rect)
   UpdateScreenExt(rect, FALSE);
 }
 
+void Delay_WithScreenUpdates(unsigned int delay)
+{
+  unsigned int time_current = SDL_GetTicks();
+  unsigned int time_delayed = time_current + delay;
+
+  while (time_current < time_delayed)
+  {
+    // updating the screen contains waiting for frame delay (non-busy)
+    UpdateScreen_WithFrameDelay(NULL);
+
+    time_current = SDL_GetTicks();
+  }
+}
+
 static void SDLSetWindowIcon(char *basename)
 {
   /* (setting the window icon on Mac OS X would replace the high-quality
@@ -262,7 +282,7 @@ static void SDLSetWindowIcon(char *basename)
     return;
   }
 
-  /* set transparent color */
+  // set transparent color
   SDL_SetColorKey(surface, SET_TRANSPARENT_PIXEL,
                  SDL_MapRGB(surface->format, 0x00, 0x00, 0x00));
 
@@ -493,11 +513,11 @@ void SDLInitVideoDisplay(void)
   SDL_putenv("SDL_VIDEO_CENTERED=1");
 #endif
 
-  /* initialize SDL video */
+  // initialize SDL video
   if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
     Error(ERR_EXIT, "SDL_InitSubSystem() failed: %s", SDL_GetError());
 
-  /* set default SDL depth */
+  // set default SDL depth
 #if !defined(TARGET_SDL2)
   video.default_depth = SDL_GetVideoInfo()->vfmt->BitsPerPixel;
 #else
@@ -505,7 +525,7 @@ void SDLInitVideoDisplay(void)
 #endif
 }
 
-inline static void SDLInitVideoBuffer_VideoBuffer(boolean fullscreen)
+static void SDLInitVideoBuffer_VideoBuffer(boolean fullscreen)
 {
   if (program.headless)
     return;
@@ -523,23 +543,19 @@ inline static void SDLInitVideoBuffer_VideoBuffer(boolean fullscreen)
   video.fullscreen_available = FALSE;
 #endif
 
-  /* open SDL video output device (window or fullscreen mode) */
+  // open SDL video output device (window or fullscreen mode)
   if (!SDLSetVideoMode(fullscreen))
     Error(ERR_EXIT, "setting video mode failed");
 
-  /* !!! SDL2 can only set the window icon if the window already exists !!! */
-  /* set window icon */
+  // !!! SDL2 can only set the window icon if the window already exists !!!
+  // set window icon
   SDLSetWindowIcon(program.icon_filename);
 
-  /* set window and icon title */
-#if defined(TARGET_SDL2)
-  SDL_SetWindowTitle(sdl_window, program.window_title);
-#else
-  SDL_WM_SetCaption(program.window_title, program.window_title);
-#endif
+  // set window and icon title
+  SDLSetWindowTitle();
 }
 
-inline static void SDLInitVideoBuffer_DrawBuffer()
+static void SDLInitVideoBuffer_DrawBuffer(void)
 {
   /* SDL cannot directly draw to the visible video framebuffer like X11,
      but always uses a backbuffer, which is then blitted to the visible
@@ -554,10 +570,10 @@ inline static void SDLInitVideoBuffer_DrawBuffer()
      buffer 'window' at the same size as the SDL backbuffer. Although it
      should never be drawn to directly, it would do no harm nevertheless. */
 
-  /* create additional (symbolic) buffer for double-buffering */
+  // create additional (symbolic) buffer for double-buffering
   ReCreateBitmap(&window, video.width, video.height);
 
-  /* create dummy drawing buffer for headless mode, if needed */
+  // create dummy drawing buffer for headless mode, if needed
   if (program.headless)
     ReCreateBitmap(&backbuffer, video.width, video.height);
 }
@@ -661,6 +677,8 @@ static boolean SDLCreateScreen(boolean fullscreen)
       // SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "linear");
       SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, setup.window_scaling_quality);
 
+      SDLSetScreenVsyncMode(setup.vsync_mode);
+
       sdl_texture_stream = SDL_CreateTexture(sdl_renderer,
                                             SDL_PIXELFORMAT_ARGB8888,
                                             SDL_TEXTUREACCESS_STREAMING,
@@ -754,12 +772,12 @@ boolean SDLSetVideoMode(boolean fullscreen)
 
   if (fullscreen && !video.fullscreen_enabled && video.fullscreen_available)
   {
-    /* switch display to fullscreen mode, if available */
+    // switch display to fullscreen mode, if available
     success = SDLCreateScreen(TRUE);
 
     if (!success)
     {
-      /* switching display to fullscreen mode failed -- do not try it again */
+      // switching display to fullscreen mode failed -- do not try it again
       video.fullscreen_available = FALSE;
     }
     else
@@ -770,12 +788,12 @@ boolean SDLSetVideoMode(boolean fullscreen)
 
   if ((!fullscreen && video.fullscreen_enabled) || !success)
   {
-    /* switch display to window mode */
+    // switch display to window mode
     success = SDLCreateScreen(FALSE);
 
     if (!success)
     {
-      /* switching display to window mode failed -- should not happen */
+      // switching display to window mode failed -- should not happen
     }
     else
     {
@@ -827,9 +845,12 @@ boolean SDLSetVideoMode(boolean fullscreen)
   return success;
 }
 
-void SDLSetWindowTitle()
+void SDLSetWindowTitle(void)
 {
 #if defined(TARGET_SDL2)
+  if (sdl_window == NULL)
+    return;
+
   SDL_SetWindowTitle(sdl_window, program.window_title);
 #else
   SDL_WM_SetCaption(program.window_title, program.window_title);
@@ -917,7 +938,7 @@ void SDLSetWindowFullscreen(boolean fullscreen)
   }
 }
 
-void SDLSetDisplaySize()
+void SDLSetDisplaySize(void)
 {
   SDL_Rect display_bounds;
 
@@ -971,7 +992,7 @@ void SDLSetScreenSizeForRenderer(int width, int height)
   SDL_RenderSetLogicalSize(sdl_renderer, width, height);
 }
 
-void SDLSetScreenProperties()
+void SDLSetScreenProperties(void)
 {
   SDLSetScreenSizeAndOffsets(video.width, video.height);
   SDLSetScreenSizeForRenderer(video.screen_width, video.screen_height);
@@ -994,7 +1015,22 @@ void SDLSetScreenRenderingMode(char *screen_rendering_mode)
 #endif
 }
 
-void SDLRedrawWindow()
+void SDLSetScreenVsyncMode(char *vsync_mode)
+{
+#if defined(TARGET_SDL2)
+  int interval =
+    (strEqual(vsync_mode, STR_VSYNC_MODE_NORMAL)   ? VSYNC_MODE_NORMAL :
+     strEqual(vsync_mode, STR_VSYNC_MODE_ADAPTIVE) ? VSYNC_MODE_ADAPTIVE :
+     VSYNC_MODE_OFF);
+  int result = SDL_GL_SetSwapInterval(interval);
+
+  // if adaptive vsync requested, but not supported, retry with normal vsync
+  if (result == -1 && interval == VSYNC_MODE_ADAPTIVE)
+    SDL_GL_SetSwapInterval(VSYNC_MODE_NORMAL);
+#endif
+}
+
+void SDLRedrawWindow(void)
 {
   UpdateScreen_WithoutFrameDelay(NULL);
 }
@@ -1155,8 +1191,8 @@ void SDLFadeRectangle(int x, int y, int width, int height,
 
   dst_rect.x = dst_x;
   dst_rect.y = dst_y;
-  dst_rect.w = width;          /* (ignored) */
-  dst_rect.h = height;         /* (ignored) */
+  dst_rect.w = width;          // (ignored)
+  dst_rect.h = height;         // (ignored)
 
   dst_rect2 = dst_rect;
 
@@ -1164,7 +1200,7 @@ void SDLFadeRectangle(int x, int y, int width, int height,
   if (fade_mode & (FADE_TYPE_FADE_IN | FADE_TYPE_TRANSFORM))
     SDL_BlitSurface(surface_screen, &dst_rect, surface_backup, &src_rect);
 
-  /* copy source and target surfaces to temporary surfaces for fading */
+  // copy source and target surfaces to temporary surfaces for fading
   if (fade_mode & FADE_TYPE_TRANSFORM)
   {
     // (source and target fading buffer already prepared)
@@ -1174,7 +1210,7 @@ void SDLFadeRectangle(int x, int y, int width, int height,
     // (target fading buffer already prepared)
     SDL_BlitSurface(surface_black,  &src_rect, surface_source, &src_rect);
   }
-  else         /* FADE_TYPE_FADE_OUT */
+  else         // FADE_TYPE_FADE_OUT
   {
     // (source fading buffer already prepared)
     SDL_BlitSurface(surface_black,  &src_rect, surface_target, &src_rect);
@@ -1195,13 +1231,13 @@ void SDLFadeRectangle(int x, int y, int width, int height,
 
     SDL_BlitSurface(surface_source, &src_rect, surface_screen, &dst_rect);
 
-    SDLSetAlpha(surface_target, FALSE, 0);     /* disable alpha blending */
+    SDLSetAlpha(surface_target, FALSE, 0);     // disable alpha blending
 
     ypos[0] = -GetSimpleRandom(16);
 
     for (i = 1 ; i < melt_columns; i++)
     {
-      int r = GetSimpleRandom(3) - 1;  /* randomly choose from { -1, 0, -1 } */
+      int r = GetSimpleRandom(3) - 1;  // randomly choose from { -1, 0, -1 }
 
       ypos[i] = ypos[i - 1] + r;
 
@@ -1243,7 +1279,7 @@ void SDLFadeRectangle(int x, int y, int width, int height,
          if (ypos[i] + dy >= height)
            dy = height - ypos[i];
 
-         /* copy part of (appearing) target surface to upper area */
+         // copy part of (appearing) target surface to upper area
          src_rect.x = src_x + i * melt_pixels;
          // src_rect.y = src_y + ypos[i];
          src_rect.y = src_y;
@@ -1261,7 +1297,7 @@ void SDLFadeRectangle(int x, int y, int width, int height,
 
          ypos[i] += dy;
 
-         /* copy part of (disappearing) source surface to lower area */
+         // copy part of (disappearing) source surface to lower area
          src_rect.x = src_x + i * melt_pixels;
          src_rect.y = src_y;
          src_rect.w = melt_pixels;
@@ -1309,7 +1345,7 @@ void SDLFadeRectangle(int x, int y, int width, int height,
 
     SDL_BlitSurface(surface_target, &src_rect, surface_screen, &dst_rect);
 
-    SDLSetAlpha(surface_source, FALSE, 0);     /* disable alpha blending */
+    SDLSetAlpha(surface_source, FALSE, 0);     // disable alpha blending
 
     for (xx = 0; xx < xx_size;)
     {
@@ -1326,7 +1362,7 @@ void SDLFadeRectangle(int x, int y, int width, int height,
       dst_rect.x = dst_x;
       dst_rect.y = dst_y;
 
-      /* draw new (target) image to screen buffer */
+      // draw new (target) image to screen buffer
       SDL_BlitSurface(surface_target, &src_rect, surface_screen, &dst_rect);
 
       if (xx_final < xx_size)
@@ -1334,14 +1370,14 @@ void SDLFadeRectangle(int x, int y, int width, int height,
        src_rect.w = xx_size - xx_final;
        src_rect.h = height;
 
-       /* draw old (source) image to screen buffer (left side) */
+       // draw old (source) image to screen buffer (left side)
 
        src_rect.x = src_x + xx_final;
        dst_rect.x = dst_x;
 
        SDL_BlitSurface(surface_source, &src_rect, surface_screen, &dst_rect);
 
-       /* draw old (source) image to screen buffer (right side) */
+       // draw old (source) image to screen buffer (right side)
 
        src_rect.x = src_x + xx_size;
        dst_rect.x = dst_x + xx_size + xx_final;
@@ -1352,11 +1388,11 @@ void SDLFadeRectangle(int x, int y, int width, int height,
       if (draw_border_function != NULL)
        draw_border_function();
 
-      /* only update the region of the screen that is affected from fading */
+      // only update the region of the screen that is affected from fading
       UpdateScreen_WithFrameDelay(&dst_rect2);
     }
   }
-  else         /* fading in, fading out or cross-fading */
+  else         // fading in, fading out or cross-fading
   {
     float alpha;
     int alpha_final;
@@ -1368,36 +1404,23 @@ void SDLFadeRectangle(int x, int y, int width, int height,
       alpha += 255 * ((float)(time_current - time_last) / fade_delay);
       alpha_final = MIN(MAX(0, alpha), 255);
 
-      /* draw existing (source) image to screen buffer */
+      // draw existing (source) image to screen buffer
       SDL_BlitSurface(surface_source, &src_rect, surface_screen, &dst_rect);
 
-      /* draw new (target) image to screen buffer using alpha blending */
+      // draw new (target) image to screen buffer using alpha blending
       SDLSetAlpha(surface_target, TRUE, alpha_final);
       SDL_BlitSurface(surface_target, &src_rect, surface_screen, &dst_rect);
 
       if (draw_border_function != NULL)
        draw_border_function();
 
-      /* only update the region of the screen that is affected from fading */
+      // only update the region of the screen that is affected from fading
       UpdateScreen_WithFrameDelay(&dst_rect);
     }
   }
 
   if (post_delay > 0)
-  {
-    unsigned int time_post_delay;
-
-    time_current = SDL_GetTicks();
-    time_post_delay = time_current + post_delay;
-
-    while (time_current < time_post_delay)
-    {
-      // updating the screen contains waiting for frame delay (non-busy)
-      UpdateScreen_WithFrameDelay(NULL);
-
-      time_current = SDL_GetTicks();
-    }
-  }
+    Delay_WithScreenUpdates(post_delay);
 
   // restore function for drawing global masked border
   gfx.draw_global_border_function = draw_global_border_function;
@@ -1469,21 +1492,21 @@ Pixel SDLGetPixel(Bitmap *src_bitmap, int x, int y)
 
   switch (surface->format->BytesPerPixel)
   {
-    case 1:            /* assuming 8-bpp */
+    case 1:            // assuming 8-bpp
     {
       return *((Uint8 *)surface->pixels + y * surface->pitch + x);
     }
     break;
 
-    case 2:            /* probably 15-bpp or 16-bpp */
+    case 2:            // probably 15-bpp or 16-bpp
     {
       return *((Uint16 *)surface->pixels + y * surface->pitch / 2 + x);
     }
     break;
 
-  case 3:              /* slow 24-bpp mode; usually not used */
+  case 3:              // slow 24-bpp mode; usually not used
     {
-      /* does this work? */
+      // does this work?
       Uint8 *pix = (Uint8 *)surface->pixels + y * surface->pitch + x * 3;
       Uint32 color = 0;
       int shift;
@@ -1499,7 +1522,7 @@ Pixel SDLGetPixel(Bitmap *src_bitmap, int x, int y)
     }
     break;
 
-  case 4:              /* probably 32-bpp */
+  case 4:              // probably 32-bpp
     {
       return *((Uint32 *)surface->pixels + y * surface->pitch / 4 + x);
     }
@@ -1510,13 +1533,13 @@ Pixel SDLGetPixel(Bitmap *src_bitmap, int x, int y)
 }
 
 
-/* ========================================================================= */
-/* The following functions were taken from the SGE library                   */
-/* (SDL Graphics Extension Library) by Anders Lindström                      */
-/* http://www.etek.chalmers.se/~e8cal1/sge/index.html                        */
-/* ========================================================================= */
+// ============================================================================
+// The following functions were taken from the SGE library
+// (SDL Graphics Extension Library) by Anders Lindström
+// http://www.etek.chalmers.se/~e8cal1/sge/index.html
+// ============================================================================
 
-void _PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
+static void _PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
 {
   if (x >= 0 && x <= surface->w - 1 && y >= 0 && y <= surface->h - 1)
   {
@@ -1524,25 +1547,25 @@ void _PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
     {
       case 1:
       {
-       /* Assuming 8-bpp */
+       // Assuming 8-bpp
        *((Uint8 *)surface->pixels + y*surface->pitch + x) = color;
       }
       break;
 
       case 2:
       {
-       /* Probably 15-bpp or 16-bpp */
+       // Probably 15-bpp or 16-bpp
        *((Uint16 *)surface->pixels + y*surface->pitch/2 + x) = color;
       }
       break;
 
       case 3:
       {
-       /* Slow 24-bpp mode, usually not used */
+       // Slow 24-bpp mode, usually not used
        Uint8 *pix;
        int shift;
 
-       /* Gack - slow, but endian correct */
+       // Gack - slow, but endian correct
        pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3;
        shift = surface->format->Rshift;
        *(pix+shift/8) = color>>shift;
@@ -1555,7 +1578,7 @@ void _PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
 
       case 4:
       {
-       /* Probably 32-bpp */
+       // Probably 32-bpp
        *((Uint32 *)surface->pixels + y*surface->pitch/4 + x) = color;
       }
       break;
@@ -1563,28 +1586,29 @@ void _PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
   }
 }
 
-void _PutPixelRGB(SDL_Surface *surface, Sint16 x, Sint16 y,
-                 Uint8 R, Uint8 G, Uint8 B)
+#if 0
+static void _PutPixelRGB(SDL_Surface *surface, Sint16 x, Sint16 y,
+                        Uint8 R, Uint8 G, Uint8 B)
 {
   _PutPixel(surface, x, y, SDL_MapRGB(surface->format, R, G, B));
 }
 
-void _PutPixel8(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
+static void _PutPixel8(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
 {
   *((Uint8 *)surface->pixels + y*surface->pitch + x) = color;
 }
 
-void _PutPixel16(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
+static void _PutPixel16(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
 {
   *((Uint16 *)surface->pixels + y*surface->pitch/2 + x) = color;
 }
 
-void _PutPixel24(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
+static void _PutPixel24(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
 {
   Uint8 *pix;
   int shift;
 
-  /* Gack - slow, but endian correct */
+  // Gack - slow, but endian correct
   pix = (Uint8 *)surface->pixels + y * surface->pitch + x*3;
   shift = surface->format->Rshift;
   *(pix+shift/8) = color>>shift;
@@ -1594,12 +1618,12 @@ void _PutPixel24(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
   *(pix+shift/8) = color>>shift;
 }
 
-void _PutPixel32(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
+static void _PutPixel32(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
 {
   *((Uint32 *)surface->pixels + y*surface->pitch/4 + x) = color;
 }
 
-void _PutPixelX(SDL_Surface *dest,Sint16 x,Sint16 y,Uint32 color)
+static void _PutPixelX(SDL_Surface *dest,Sint16 x,Sint16 y,Uint32 color)
 {
   switch (dest->format->BytesPerPixel)
   {
@@ -1620,8 +1644,9 @@ void _PutPixelX(SDL_Surface *dest,Sint16 x,Sint16 y,Uint32 color)
       break;
   }
 }
+#endif
 
-void sge_PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
+static void sge_PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
 {
   if (SDL_MUSTLOCK(surface))
   {
@@ -1639,13 +1664,14 @@ void sge_PutPixel(SDL_Surface *surface, Sint16 x, Sint16 y, Uint32 color)
   }
 }
 
-void sge_PutPixelRGB(SDL_Surface *surface, Sint16 x, Sint16 y,
-                 Uint8 r, Uint8 g, Uint8 b)
+#if 0
+static void sge_PutPixelRGB(SDL_Surface *surface, Sint16 x, Sint16 y,
+                           Uint8 r, Uint8 g, Uint8 b)
 {
   sge_PutPixel(surface, x, y, SDL_MapRGB(surface->format, r, g, b));
 }
 
-Sint32 sge_CalcYPitch(SDL_Surface *dest, Sint16 y)
+static Sint32 sge_CalcYPitch(SDL_Surface *dest, Sint16 y)
 {
   if (y >= 0 && y <= dest->h - 1)
   {
@@ -1672,7 +1698,8 @@ Sint32 sge_CalcYPitch(SDL_Surface *dest, Sint16 y)
   return -1;
 }
 
-void sge_pPutPixel(SDL_Surface *surface, Sint16 x, Sint32 ypitch, Uint32 color)
+static void sge_pPutPixel(SDL_Surface *surface, Sint16 x, Sint32 ypitch,
+                         Uint32 color)
 {
   if (x >= 0 && x <= surface->w - 1 && ypitch >= 0)
   {
@@ -1680,25 +1707,25 @@ void sge_pPutPixel(SDL_Surface *surface, Sint16 x, Sint32 ypitch, Uint32 color)
     {
       case 1:
       {
-       /* Assuming 8-bpp */
+       // Assuming 8-bpp
        *((Uint8 *)surface->pixels + ypitch + x) = color;
       }
       break;
 
       case 2:
       {
-       /* Probably 15-bpp or 16-bpp */
+       // Probably 15-bpp or 16-bpp
        *((Uint16 *)surface->pixels + ypitch + x) = color;
       }
       break;
 
       case 3:
       {
-       /* Slow 24-bpp mode, usually not used */
+       // Slow 24-bpp mode, usually not used
        Uint8 *pix;
        int shift;
 
-       /* Gack - slow, but endian correct */
+       // Gack - slow, but endian correct
        pix = (Uint8 *)surface->pixels + ypitch + x*3;
        shift = surface->format->Rshift;
        *(pix+shift/8) = color>>shift;
@@ -1711,7 +1738,7 @@ void sge_pPutPixel(SDL_Surface *surface, Sint16 x, Sint32 ypitch, Uint32 color)
 
       case 4:
       {
-       /* Probably 32-bpp */
+       // Probably 32-bpp
        *((Uint32 *)surface->pixels + ypitch + x) = color;
       }
       break;
@@ -1719,8 +1746,8 @@ void sge_pPutPixel(SDL_Surface *surface, Sint16 x, Sint32 ypitch, Uint32 color)
   }
 }
 
-void sge_HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y,
-              Uint32 Color)
+static void sge_HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y,
+                     Uint32 Color)
 {
   SDL_Rect l;
 
@@ -1739,7 +1766,7 @@ void sge_HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y,
     x2 = tmp;
   }
 
-  /* Do the clipping */
+  // Do the clipping
   if (y < 0 || y > Surface->h - 1 || x1 > Surface->w - 1 || x2 < 0)
     return;
   if (x1 < 0)
@@ -1760,13 +1787,14 @@ void sge_HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y,
   }
 }
 
-void sge_HLineRGB(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y,
-                 Uint8 R, Uint8 G, Uint8 B)
+static void sge_HLineRGB(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y,
+                        Uint8 R, Uint8 G, Uint8 B)
 {
   sge_HLine(Surface, x1, x2, y, SDL_MapRGB(Surface->format, R, G, B));
 }
 
-void _HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color)
+static void _HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y,
+                  Uint32 Color)
 {
   SDL_Rect l;
 
@@ -1777,7 +1805,7 @@ void _HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color)
     x2 = tmp;
   }
 
-  /* Do the clipping */
+  // Do the clipping
   if (y < 0 || y > Surface->h - 1 || x1 > Surface->w - 1 || x2 < 0)
     return;
   if (x1 < 0)
@@ -1793,8 +1821,8 @@ void _HLine(SDL_Surface *Surface, Sint16 x1, Sint16 x2, Sint16 y, Uint32 Color)
   SDL_FillRect(Surface, &l, Color);
 }
 
-void sge_VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2,
-              Uint32 Color)
+static void sge_VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2,
+                     Uint32 Color)
 {
   SDL_Rect l;
 
@@ -1813,7 +1841,7 @@ void sge_VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2,
     y2 = tmp;
   }
 
-  /* Do the clipping */
+  // Do the clipping
   if (x < 0 || x > Surface->w - 1 || y1 > Surface->h - 1 || y2 < 0)
     return;
   if (y1 < 0)
@@ -1834,13 +1862,14 @@ void sge_VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2,
   }
 }
 
-void sge_VLineRGB(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2,
-                 Uint8 R, Uint8 G, Uint8 B)
+static void sge_VLineRGB(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2,
+                        Uint8 R, Uint8 G, Uint8 B)
 {
   sge_VLine(Surface, x, y1, y2, SDL_MapRGB(Surface->format, R, G, B));
 }
 
-void _VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color)
+static void _VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2,
+                  Uint32 Color)
 {
   SDL_Rect l;
 
@@ -1851,7 +1880,7 @@ void _VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color)
     y2 = tmp;
   }
 
-  /* Do the clipping */
+  // Do the clipping
   if (x < 0 || x > Surface->w - 1 || y1 > Surface->h - 1 || y2 < 0)
     return;
   if (y1 < 0)
@@ -1866,11 +1895,12 @@ void _VLine(SDL_Surface *Surface, Sint16 x, Sint16 y1, Sint16 y2, Uint32 Color)
 
   SDL_FillRect(Surface, &l, Color);
 }
+#endif
 
-void sge_DoLine(SDL_Surface *Surface, Sint16 x1, Sint16 y1,
-               Sint16 x2, Sint16 y2, Uint32 Color,
-               void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y,
-                             Uint32 Color))
+static void sge_DoLine(SDL_Surface *Surface, Sint16 x1, Sint16 y1,
+                      Sint16 x2, Sint16 y2, Uint32 Color,
+                      void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y,
+                                    Uint32 Color))
 {
   Sint16 dx, dy, sdx, sdy, x, y, px, py;
 
@@ -1922,14 +1952,16 @@ void sge_DoLine(SDL_Surface *Surface, Sint16 x1, Sint16 y1,
   }
 }
 
-void sge_DoLineRGB(SDL_Surface *Surface, Sint16 X1, Sint16 Y1,
-                  Sint16 X2, Sint16 Y2, Uint8 R, Uint8 G, Uint8 B,
-                  void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y,
-                                Uint32 Color))
+#if 0
+static void sge_DoLineRGB(SDL_Surface *Surface, Sint16 X1, Sint16 Y1,
+                         Sint16 X2, Sint16 Y2, Uint8 R, Uint8 G, Uint8 B,
+                         void Callback(SDL_Surface *Surf, Sint16 X, Sint16 Y,
+                                       Uint32 Color))
 {
   sge_DoLine(Surface, X1, Y1, X2, Y2,
             SDL_MapRGB(Surface->format, R, G, B), Callback);
 }
+#endif
 
 void sge_Line(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,
              Uint32 Color)
@@ -1940,21 +1972,23 @@ void sge_Line(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,
       return;
    }
 
-   /* Draw the line */
+   // Draw the line
    sge_DoLine(Surface, x1, y1, x2, y2, Color, _PutPixel);
 
-   /* unlock the display */
+   // unlock the display
    if (SDL_MUSTLOCK(Surface))
    {
       SDL_UnlockSurface(Surface);
    }
 }
 
-void sge_LineRGB(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2,
-                Sint16 y2, Uint8 R, Uint8 G, Uint8 B)
+#if 0
+static void sge_LineRGB(SDL_Surface *Surface, Sint16 x1, Sint16 y1, Sint16 x2,
+                       Sint16 y2, Uint8 R, Uint8 G, Uint8 B)
 {
   sge_Line(Surface, x1, y1, x2, y2, SDL_MapRGB(Surface->format, R, G, B));
 }
+#endif
 
 void SDLPutPixel(Bitmap *dst_bitmap, int x, int y, Pixel pixel)
 {
@@ -2003,11 +2037,11 @@ void SDLCopyInverseMasked(Bitmap *src_bitmap, Bitmap *dst_bitmap,
 }
 
 
-/* ========================================================================= */
-/* The following functions were taken from the SDL_gfx library version 2.0.3 */
-/* (Rotozoomer) by Andreas Schiffler                                         */
-/* http://www.ferzkopp.net/Software/SDL_gfx-2.0/index.html                   */
-/* ========================================================================= */
+// ============================================================================
+// The following functions were taken from the SDL_gfx library version 2.0.3
+// (Rotozoomer) by Andreas Schiffler
+// http://www.ferzkopp.net/Software/SDL_gfx-2.0/index.html
+// ============================================================================
 
 /*
   -----------------------------------------------------------------------------
@@ -2025,13 +2059,13 @@ typedef struct
   Uint8 a;
 } tColorRGBA;
 
-int zoomSurfaceRGBA_scaleDownBy2(SDL_Surface *src, SDL_Surface *dst)
+static int zoomSurfaceRGBA_scaleDownBy2(SDL_Surface *src, SDL_Surface *dst)
 {
   int x, y;
   tColorRGBA *sp, *csp, *dp;
   int dgap;
 
-  /* pointer setup */
+  // pointer setup
   sp = csp = (tColorRGBA *) src->pixels;
   dp = (tColorRGBA *) dst->pixels;
   dgap = dst->pitch - dst->w * 4;
@@ -2050,60 +2084,60 @@ int zoomSurfaceRGBA_scaleDownBy2(SDL_Surface *src, SDL_Surface *dst)
       tColorRGBA *sp11 = &sp1[1];
       tColorRGBA new;
 
-      /* create new color pixel from all four source color pixels */
+      // create new color pixel from all four source color pixels
       new.r = (sp00->r + sp01->r + sp10->r + sp11->r) / 4;
       new.g = (sp00->g + sp01->g + sp10->g + sp11->g) / 4;
       new.b = (sp00->b + sp01->b + sp10->b + sp11->b) / 4;
       new.a = (sp00->a + sp01->a + sp10->a + sp11->a) / 4;
 
-      /* draw */
+      // draw
       *dp = new;
 
-      /* advance source pointers */
+      // advance source pointers
       sp += 2;
 
-      /* advance destination pointer */
+      // advance destination pointer
       dp++;
     }
 
-    /* advance source pointer */
+    // advance source pointer
     csp = (tColorRGBA *) ((Uint8 *) csp + 2 * src->pitch);
 
-    /* advance destination pointers */
+    // advance destination pointers
     dp = (tColorRGBA *) ((Uint8 *) dp + dgap);
   }
 
   return 0;
 }
 
-int zoomSurfaceRGBA(SDL_Surface *src, SDL_Surface *dst)
+static int zoomSurfaceRGBA(SDL_Surface *src, SDL_Surface *dst)
 {
   int x, y, *sax, *say, *csax, *csay;
   float sx, sy;
   tColorRGBA *sp, *csp, *csp0, *dp;
   int dgap;
 
-  /* use specialized zoom function when scaling down to exactly half size */
+  // use specialized zoom function when scaling down to exactly half size
   if (src->w == 2 * dst->w &&
       src->h == 2 * dst->h)
     return zoomSurfaceRGBA_scaleDownBy2(src, dst);
 
-  /* variable setup */
+  // variable setup
   sx = (float) src->w / (float) dst->w;
   sy = (float) src->h / (float) dst->h;
 
-  /* allocate memory for row increments */
+  // allocate memory for row increments
   csax = sax = (int *)checked_malloc((dst->w + 1) * sizeof(Uint32));
   csay = say = (int *)checked_malloc((dst->h + 1) * sizeof(Uint32));
 
-  /* precalculate row increments */
+  // precalculate row increments
   for (x = 0; x <= dst->w; x++)
     *csax++ = (int)(sx * x);
 
   for (y = 0; y <= dst->h; y++)
     *csay++ = (int)(sy * y);
 
-  /* pointer setup */
+  // pointer setup
   sp = csp = csp0 = (tColorRGBA *) src->pixels;
   dp = (tColorRGBA *) dst->pixels;
   dgap = dst->pitch - dst->w * 4;
@@ -2116,22 +2150,22 @@ int zoomSurfaceRGBA(SDL_Surface *src, SDL_Surface *dst)
 
     for (x = 0; x < dst->w; x++)
     {
-      /* draw */
+      // draw
       *dp = *sp;
 
-      /* advance source pointers */
+      // advance source pointers
       csax++;
       sp = csp + *csax;
 
-      /* advance destination pointer */
+      // advance destination pointer
       dp++;
     }
 
-    /* advance source pointer */
+    // advance source pointer
     csay++;
     csp = (tColorRGBA *) ((Uint8 *) csp0 + *csay * src->pitch);
 
-    /* advance destination pointers */
+    // advance destination pointers
     dp = (tColorRGBA *) ((Uint8 *) dp + dgap);
   }
 
@@ -2149,21 +2183,21 @@ int zoomSurfaceRGBA(SDL_Surface *src, SDL_Surface *dst)
   -----------------------------------------------------------------------------
 */
 
-int zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst)
+static int zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst)
 {
   Uint32 x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy;
   Uint8 *sp, *dp, *csp;
   int dgap;
 
-  /* variable setup */
+  // variable setup
   sx = (Uint32) (65536.0 * (float) src->w / (float) dst->w);
   sy = (Uint32) (65536.0 * (float) src->h / (float) dst->h);
 
-  /* allocate memory for row increments */
+  // allocate memory for row increments
   sax = (Uint32 *)checked_malloc(dst->w * sizeof(Uint32));
   say = (Uint32 *)checked_malloc(dst->h * sizeof(Uint32));
 
-  /* precalculate row increments */
+  // precalculate row increments
   csx = 0;
   csax = sax;
   for (x = 0; x < dst->w; x++)
@@ -2200,12 +2234,12 @@ int zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst)
     csay++;
   }
 
-  /* pointer setup */
+  // pointer setup
   sp = csp = (Uint8 *) src->pixels;
   dp = (Uint8 *) dst->pixels;
   dgap = dst->pitch - dst->w;
 
-  /* draw */
+  // draw
   csay = say;
   for (y = 0; y < dst->h; y++)
   {
@@ -2213,22 +2247,22 @@ int zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst)
     sp = csp;
     for (x = 0; x < dst->w; x++)
     {
-      /* draw */
+      // draw
       *dp = *sp;
 
-      /* advance source pointers */
+      // advance source pointers
       sp += (*csax);
       csax++;
 
-      /* advance destination pointer */
+      // advance destination pointer
       dp++;
     }
 
-    /* advance source pointer (for row) */
+    // advance source pointer (for row)
     csp += ((*csay) * src->pitch);
     csay++;
 
-    /* advance destination pointers */
+    // advance destination pointers
     dp += dgap;
   }
 
@@ -2249,7 +2283,7 @@ int zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst)
   -----------------------------------------------------------------------------
 */
 
-SDL_Surface *zoomSurface(SDL_Surface *src, int dst_width, int dst_height)
+static SDL_Surface *zoomSurface(SDL_Surface *src, int dst_width, int dst_height)
 {
   SDL_Surface *zoom_src = NULL;
   SDL_Surface *zoom_dst = NULL;
@@ -2260,17 +2294,17 @@ SDL_Surface *zoomSurface(SDL_Surface *src, int dst_width, int dst_height)
   if (src == NULL)
     return NULL;
 
-  /* determine if source surface is 32 bit or 8 bit */
+  // determine if source surface is 32 bit or 8 bit
   is_32bit = (src->format->BitsPerPixel == 32);
 
   if (is_32bit || src->format->BitsPerPixel == 8)
   {
-    /* use source surface 'as is' */
+    // use source surface 'as is'
     zoom_src = src;
   }
   else
   {
-    /* new source surface is 32 bit with a defined RGB ordering */
+    // new source surface is 32 bit with a defined RGB ordering
     zoom_src = SDL_CreateRGBSurface(SURFACE_FLAGS, src->w, src->h, 32,
                                    0x000000ff, 0x0000ff00, 0x00ff0000,
                                    (src->format->Amask ? 0xff000000 : 0));
@@ -2279,10 +2313,10 @@ SDL_Surface *zoomSurface(SDL_Surface *src, int dst_width, int dst_height)
     is_converted = TRUE;
   }
 
-  /* allocate surface to completely contain the zoomed surface */
+  // allocate surface to completely contain the zoomed surface
   if (is_32bit)
   {
-    /* target surface is 32 bit with source RGBA/ABGR ordering */
+    // target surface is 32 bit with source RGBA/ABGR ordering
     zoom_dst = SDL_CreateRGBSurface(SURFACE_FLAGS, dst_width, dst_height, 32,
                                    zoom_src->format->Rmask,
                                    zoom_src->format->Gmask,
@@ -2291,40 +2325,40 @@ SDL_Surface *zoomSurface(SDL_Surface *src, int dst_width, int dst_height)
   }
   else
   {
-    /* target surface is 8 bit */
+    // target surface is 8 bit
     zoom_dst = SDL_CreateRGBSurface(SURFACE_FLAGS, dst_width, dst_height, 8,
                                    0, 0, 0, 0);
   }
 
-  /* lock source surface */
+  // lock source surface
   SDL_LockSurface(zoom_src);
 
-  /* check which kind of surface we have */
+  // check which kind of surface we have
   if (is_32bit)
   {
-    /* call the 32 bit transformation routine to do the zooming */
+    // call the 32 bit transformation routine to do the zooming
     zoomSurfaceRGBA(zoom_src, zoom_dst);
   }
   else
   {
-    /* copy palette */
+    // copy palette
     for (i = 0; i < zoom_src->format->palette->ncolors; i++)
       zoom_dst->format->palette->colors[i] =
        zoom_src->format->palette->colors[i];
     zoom_dst->format->palette->ncolors = zoom_src->format->palette->ncolors;
 
-    /* call the 8 bit transformation routine to do the zooming */
+    // call the 8 bit transformation routine to do the zooming
     zoomSurfaceY(zoom_src, zoom_dst);
   }
 
-  /* unlock source surface */
+  // unlock source surface
   SDL_UnlockSurface(zoom_src);
 
-  /* free temporary surface */
+  // free temporary surface
   if (is_converted)
     SDL_FreeSurface(zoom_src);
 
-  /* return destination surface */
+  // return destination surface
   return zoom_dst;
 }
 
@@ -2338,10 +2372,10 @@ static SDL_Surface *SDLGetOpaqueSurface(SDL_Surface *surface)
   if ((new_surface = SDLGetNativeSurface(surface)) == NULL)
     Error(ERR_EXIT, "SDLGetNativeSurface() failed");
 
-  /* remove alpha channel from native non-transparent surface, if defined */
+  // remove alpha channel from native non-transparent surface, if defined
   SDLSetAlpha(new_surface, FALSE, 0);
 
-  /* remove transparent color from native non-transparent surface, if defined */
+  // remove transparent color from native non-transparent surface, if defined
   SDL_SetColorKey(new_surface, UNSET_TRANSPARENT_PIXEL, 0);
 
   return new_surface;
@@ -2353,36 +2387,36 @@ Bitmap *SDLZoomBitmap(Bitmap *src_bitmap, int dst_width, int dst_height)
   SDL_Surface *src_surface = src_bitmap->surface_masked;
   SDL_Surface *dst_surface;
 
-  dst_width  = MAX(1, dst_width);      /* prevent zero bitmap width */
-  dst_height = MAX(1, dst_height);     /* prevent zero bitmap height */
+  dst_width  = MAX(1, dst_width);      // prevent zero bitmap width
+  dst_height = MAX(1, dst_height);     // prevent zero bitmap height
 
   dst_bitmap->width  = dst_width;
   dst_bitmap->height = dst_height;
 
-  /* create zoomed temporary surface from source surface */
+  // create zoomed temporary surface from source surface
   dst_surface = zoomSurface(src_surface, dst_width, dst_height);
 
-  /* create native format destination surface from zoomed temporary surface */
+  // create native format destination surface from zoomed temporary surface
   SDLSetNativeSurface(&dst_surface);
 
-  /* set color key for zoomed surface from source surface, if defined */
+  // set color key for zoomed surface from source surface, if defined
   if (SDLHasColorKey(src_surface))
     SDL_SetColorKey(dst_surface, SET_TRANSPARENT_PIXEL,
                    SDLGetColorKey(src_surface));
 
-  /* create native non-transparent surface for opaque blitting */
+  // create native non-transparent surface for opaque blitting
   dst_bitmap->surface = SDLGetOpaqueSurface(dst_surface);
 
-  /* set native transparent surface for masked blitting */
+  // set native transparent surface for masked blitting
   dst_bitmap->surface_masked = dst_surface;
 
   return dst_bitmap;
 }
 
 
-/* ========================================================================= */
-/* load image to bitmap                                                      */
-/* ========================================================================= */
+// ============================================================================
+// load image to bitmap
+// ============================================================================
 
 Bitmap *SDLLoadImage(char *filename)
 {
@@ -2391,7 +2425,7 @@ Bitmap *SDLLoadImage(char *filename)
 
   if (program.headless)
   {
-    /* prevent sanity check warnings at later stage */
+    // prevent sanity check warnings at later stage
     new_bitmap->width = new_bitmap->height = 1;
 
     return new_bitmap;
@@ -2401,7 +2435,7 @@ Bitmap *SDLLoadImage(char *filename)
 
   print_timestamp_time(getBaseNamePtr(filename));
 
-  /* load image to temporary surface */
+  // load image to temporary surface
   if ((sdl_image_tmp = IMG_Load(filename)) == NULL)
     Error(ERR_EXIT, "IMG_Load() failed: %s", SDL_GetError());
 
@@ -2409,7 +2443,7 @@ Bitmap *SDLLoadImage(char *filename)
 
   UPDATE_BUSY_STATE();
 
-  /* create native non-transparent surface for current image */
+  // create native non-transparent surface for current image
   if ((new_bitmap->surface = SDLGetOpaqueSurface(sdl_image_tmp)) == NULL)
     Error(ERR_EXIT, "SDLGetOpaqueSurface() failed");
 
@@ -2417,13 +2451,13 @@ Bitmap *SDLLoadImage(char *filename)
 
   UPDATE_BUSY_STATE();
 
-  /* set black pixel to transparent if no alpha channel / transparent color */
+  // set black pixel to transparent if no alpha channel / transparent color
   if (!SDLHasAlpha(sdl_image_tmp) &&
       !SDLHasColorKey(sdl_image_tmp))
     SDL_SetColorKey(sdl_image_tmp, SET_TRANSPARENT_PIXEL,
                    SDL_MapRGB(sdl_image_tmp->format, 0x00, 0x00, 0x00));
 
-  /* create native transparent surface for current image */
+  // create native transparent surface for current image
   if ((new_bitmap->surface_masked = SDLGetNativeSurface(sdl_image_tmp)) == NULL)
     Error(ERR_EXIT, "SDLGetNativeSurface() failed");
 
@@ -2431,7 +2465,7 @@ Bitmap *SDLLoadImage(char *filename)
 
   UPDATE_BUSY_STATE();
 
-  /* free temporary surface */
+  // free temporary surface
   SDL_FreeSurface(sdl_image_tmp);
 
   new_bitmap->width = new_bitmap->surface->w;
@@ -2443,9 +2477,9 @@ Bitmap *SDLLoadImage(char *filename)
 }
 
 
-/* ------------------------------------------------------------------------- */
-/* custom cursor fuctions                                                    */
-/* ------------------------------------------------------------------------- */
+// ----------------------------------------------------------------------------
+// custom cursor fuctions
+// ----------------------------------------------------------------------------
 
 static SDL_Cursor *create_cursor(struct MouseCursorInfo *cursor_info)
 {
@@ -2461,18 +2495,18 @@ void SDLSetMouseCursor(struct MouseCursorInfo *cursor_info)
   static SDL_Cursor *cursor_default = NULL;
   static SDL_Cursor *cursor_current = NULL;
 
-  /* if invoked for the first time, store the SDL default cursor */
+  // if invoked for the first time, store the SDL default cursor
   if (cursor_default == NULL)
     cursor_default = SDL_GetCursor();
 
-  /* only create new cursor if cursor info (custom only) has changed */
+  // only create new cursor if cursor info (custom only) has changed
   if (cursor_info != NULL && cursor_info != last_cursor_info)
   {
     cursor_current = create_cursor(cursor_info);
     last_cursor_info = cursor_info;
   }
 
-  /* only set new cursor if cursor info (custom or NULL) has changed */
+  // only set new cursor if cursor info (custom or NULL) has changed
   if (cursor_info != last_cursor_info2)
     SDL_SetCursor(cursor_info ? cursor_current : cursor_default);
 
@@ -2480,9 +2514,9 @@ void SDLSetMouseCursor(struct MouseCursorInfo *cursor_info)
 }
 
 
-/* ========================================================================= */
-/* audio functions                                                           */
-/* ========================================================================= */
+// ============================================================================
+// audio functions
+// ============================================================================
 
 void SDLOpenAudio(void)
 {
@@ -2513,7 +2547,7 @@ void SDLOpenAudio(void)
   audio.loops_available = TRUE;
   audio.sound_enabled = TRUE;
 
-  /* set number of available mixer channels */
+  // set number of available mixer channels
   audio.num_channels = Mix_AllocateChannels(NUM_MIXER_CHANNELS);
   audio.music_channel = MUSIC_CHANNEL;
   audio.first_sound_channel = FIRST_SOUND_CHANNEL;
@@ -2531,11 +2565,11 @@ void SDLCloseAudio(void)
 }
 
 
-/* ========================================================================= */
-/* event functions                                                           */
-/* ========================================================================= */
+// ============================================================================
+// event functions
+// ============================================================================
 
-void SDLNextEvent(Event *event)
+void SDLWaitEvent(Event *event)
 {
   SDL_WaitEvent(event);
 }
@@ -2587,9 +2621,9 @@ void SDLHandleWindowManagerEvent(Event *event)
 }
 
 
-/* ========================================================================= */
-/* joystick functions                                                        */
-/* ========================================================================= */
+// ============================================================================
+// joystick functions
+// ============================================================================
 
 #if defined(TARGET_SDL2)
 static void *sdl_joystick[MAX_PLAYERS];                // game controller or joystick
@@ -2601,7 +2635,22 @@ static int sdl_js_axis[MAX_PLAYERS][2];
 static int sdl_js_button[MAX_PLAYERS][2];
 static boolean sdl_is_controller[MAX_PLAYERS];
 
-static boolean SDLOpenJoystick(int nr)
+void SDLClearJoystickState(void)
+{
+  int i, j;
+
+  for (i = 0; i < MAX_PLAYERS; i++)
+  {
+    for (j = 0; j < 2; j++)
+    {
+      sdl_js_axis_raw[i][j] = -1;
+      sdl_js_axis[i][j] = 0;
+      sdl_js_button[i][j] = 0;
+    }
+  }
+}
+
+boolean SDLOpenJoystick(int nr)
 {
   if (nr < 0 || nr >= MAX_PLAYERS)
     return FALSE;
@@ -2612,7 +2661,7 @@ static boolean SDLOpenJoystick(int nr)
   sdl_is_controller[nr] = FALSE;
 #endif
 
-#if 1
+#if DEBUG_JOYSTICKS
   Error(ERR_DEBUG, "opening joystick %d (%s)",
        nr, (sdl_is_controller[nr] ? "game controller" : "joystick"));
 #endif
@@ -2629,12 +2678,12 @@ static boolean SDLOpenJoystick(int nr)
   return (sdl_joystick[nr] != NULL);
 }
 
-static void SDLCloseJoystick(int nr)
+void SDLCloseJoystick(int nr)
 {
   if (nr < 0 || nr >= MAX_PLAYERS)
     return;
 
-#if 1
+#if DEBUG_JOYSTICKS
   Error(ERR_DEBUG, "closing joystick %d", nr);
 #endif
 
@@ -2648,13 +2697,6 @@ static void SDLCloseJoystick(int nr)
 #endif
 
   sdl_joystick[nr] = NULL;
-
-  sdl_js_axis_raw[nr][0] = -1;
-  sdl_js_axis_raw[nr][1] = -1;
-  sdl_js_axis[nr][0] = 0;
-  sdl_js_axis[nr][1] = 0;
-  sdl_js_button[nr][0] = 0;
-  sdl_js_button[nr][1] = 0;
 }
 
 boolean SDLCheckJoystickOpened(int nr)
@@ -2741,7 +2783,7 @@ void HandleJoystickEvent(Event *event)
   {
 #if defined(TARGET_SDL2)
     case SDL_CONTROLLERDEVICEADDED:
-#if 1
+#if DEBUG_JOYSTICKS
       Error(ERR_DEBUG, "SDL_CONTROLLERDEVICEADDED: device %d added",
            event->cdevice.which);
 #endif
@@ -2749,7 +2791,7 @@ void HandleJoystickEvent(Event *event)
       break;
 
     case SDL_CONTROLLERDEVICEREMOVED:
-#if 1
+#if DEBUG_JOYSTICKS
       Error(ERR_DEBUG, "SDL_CONTROLLERDEVICEREMOVED: device %d removed",
            event->cdevice.which);
 #endif
@@ -2757,7 +2799,7 @@ void HandleJoystickEvent(Event *event)
       break;
 
     case SDL_CONTROLLERAXISMOTION:
-#if 1
+#if DEBUG_JOYSTICKS
       Error(ERR_DEBUG, "SDL_CONTROLLERAXISMOTION: device %d, axis %d: %d",
            event->caxis.which, event->caxis.axis, event->caxis.value);
 #endif
@@ -2767,7 +2809,7 @@ void HandleJoystickEvent(Event *event)
       break;
 
     case SDL_CONTROLLERBUTTONDOWN:
-#if 1
+#if DEBUG_JOYSTICKS
       Error(ERR_DEBUG, "SDL_CONTROLLERBUTTONDOWN: device %d, button %d",
            event->cbutton.which, event->cbutton.button);
 #endif
@@ -2777,7 +2819,7 @@ void HandleJoystickEvent(Event *event)
       break;
 
     case SDL_CONTROLLERBUTTONUP:
-#if 1
+#if DEBUG_JOYSTICKS
       Error(ERR_DEBUG, "SDL_CONTROLLERBUTTONUP: device %d, button %d",
            event->cbutton.which, event->cbutton.button);
 #endif
@@ -2791,7 +2833,7 @@ void HandleJoystickEvent(Event *event)
       if (sdl_is_controller[event->jaxis.which])
        break;
 
-#if 1
+#if DEBUG_JOYSTICKS
       Error(ERR_DEBUG, "SDL_JOYAXISMOTION: device %d, axis %d: %d",
            event->jaxis.which, event->jaxis.axis, event->jaxis.value);
 #endif
@@ -2805,7 +2847,7 @@ void HandleJoystickEvent(Event *event)
       if (sdl_is_controller[event->jaxis.which])
        break;
 
-#if 1
+#if DEBUG_JOYSTICKS
       Error(ERR_DEBUG, "SDL_JOYBUTTONDOWN: device %d, button %d",
            event->jbutton.which, event->jbutton.button);
 #endif
@@ -2819,7 +2861,7 @@ void HandleJoystickEvent(Event *event)
       if (sdl_is_controller[event->jaxis.which])
        break;
 
-#if 1
+#if DEBUG_JOYSTICKS
       Error(ERR_DEBUG, "SDL_JOYBUTTONUP: device %d, button %d",
            event->jbutton.which, event->jbutton.button);
 #endif
@@ -2834,12 +2876,12 @@ void HandleJoystickEvent(Event *event)
   }
 }
 
-void SDLInitJoysticks()
+void SDLInitJoysticks(void)
 {
   static boolean sdl_joystick_subsystem_initialized = FALSE;
   boolean print_warning = !sdl_joystick_subsystem_initialized;
 #if defined(TARGET_SDL2)
-  char *mappings_file_base = getPath2(options.ro_base_directory,
+  char *mappings_file_base = getPath2(options.conf_directory,
                                      GAMECONTROLLER_BASENAME);
   char *mappings_file_user = getPath2(getUserGameDataDir(),
                                      GAMECONTROLLER_BASENAME);
@@ -2866,23 +2908,30 @@ void SDLInitJoysticks()
 #if defined(TARGET_SDL2)
     num_mappings = SDL_GameControllerAddMappingsFromFile(mappings_file_base);
 
-    if (num_mappings != -1)
-      Error(ERR_INFO, "%d game controller base mapping(s) added", num_mappings);
-    else
+    // the included game controller base mappings should always be found
+    if (num_mappings == -1)
       Error(ERR_WARN, "no game controller base mappings found");
+#if DEBUG_JOYSTICKS
+    else
+      Error(ERR_INFO, "%d game controller base mapping(s) added", num_mappings);
+#endif
 
     num_mappings = SDL_GameControllerAddMappingsFromFile(mappings_file_user);
 
-    if (num_mappings != -1)
-      Error(ERR_INFO, "%d game controller user mapping(s) added", num_mappings);
-    else
+#if DEBUG_JOYSTICKS
+    // the personal game controller user mappings may or may not be found
+    if (num_mappings == -1)
       Error(ERR_WARN, "no game controller user mappings found");
+    else
+      Error(ERR_INFO, "%d game controller user mapping(s) added", num_mappings);
 
     Error(ERR_INFO, "%d joystick(s) found:", SDL_NumJoysticks());
+#endif
 
     checked_free(mappings_file_base);
     checked_free(mappings_file_user);
 
+#if DEBUG_JOYSTICKS
     for (i = 0; i < SDL_NumJoysticks(); i++)
     {
       const char *name, *type;
@@ -2901,13 +2950,14 @@ void SDLInitJoysticks()
       Error(ERR_INFO, "- joystick %d (%s): '%s'",
            i, type, (name ? name : "(Unknown)"));
     }
+#endif
 #endif
   }
 
-  /* assign joysticks from configured to connected joystick for all players */
+  // assign joysticks from configured to connected joystick for all players
   for (i = 0; i < MAX_PLAYERS; i++)
   {
-    /* get configured joystick for this player */
+    // get configured joystick for this player
     char *device_name = setup.input[i].joy.device_name;
     int joystick_nr = getJoystickNrFromDeviceName(device_name);
 
@@ -2919,14 +2969,14 @@ void SDLInitJoysticks()
       joystick_nr = -1;
     }
 
-    /* store configured joystick number for each player */
+    // store configured joystick number for each player
     joystick.nr[i] = joystick_nr;
   }
 
-  /* now open all connected joysticks (regardless if configured or not) */
+  // now open all connected joysticks (regardless if configured or not)
   for (i = 0; i < SDL_NumJoysticks(); i++)
   {
-    /* this allows subsequent calls to 'InitJoysticks' for re-initialization */
+    // this allows subsequent calls to 'InitJoysticks' for re-initialization
     if (SDLCheckJoystickOpened(i))
       SDLCloseJoystick(i);
 
@@ -2935,6 +2985,8 @@ void SDLInitJoysticks()
     else if (print_warning)
       Error(ERR_WARN, "cannot open joystick %d", i);
   }
+
+  SDLClearJoystickState();
 }
 
 boolean SDLReadJoystick(int nr, int *x, int *y, boolean *b1, boolean *b2)
@@ -2955,17 +3007,189 @@ boolean SDLReadJoystick(int nr, int *x, int *y, boolean *b1, boolean *b2)
   return TRUE;
 }
 
+
+// ============================================================================
+// touch input overlay functions
+// ============================================================================
+
 #if defined(USE_TOUCH_INPUT_OVERLAY)
-static void DrawTouchInputOverlay()
+static void DrawTouchInputOverlay_ShowGrid(int alpha)
+{
+  SDL_Rect rect;
+  int grid_xsize = overlay.grid_xsize;
+  int grid_ysize = overlay.grid_ysize;
+  int x, y;
+
+  SDL_SetRenderDrawColor(sdl_renderer, 255, 255, 255, alpha);
+  SDL_SetRenderDrawBlendMode(sdl_renderer, SDL_BLENDMODE_BLEND);
+
+  for (x = 0; x < grid_xsize; x++)
+  {
+    rect.x = (x + 0) * video.screen_width / grid_xsize;
+    rect.w = (x + 1) * video.screen_width / grid_xsize - rect.x;
+
+    for (y = 0; y < grid_ysize; y++)
+    {
+      rect.y = (y + 0) * video.screen_height / grid_ysize;
+      rect.h = (y + 1) * video.screen_height / grid_ysize - rect.y;
+
+      if (overlay.grid_button[x][y] == CHAR_GRID_BUTTON_NONE)
+       SDL_RenderDrawRect(sdl_renderer, &rect);
+    }
+  }
+
+  SDL_SetRenderDrawColor(sdl_renderer, 0, 0, 0, 255);
+}
+
+static void RenderFillRectangle(int x, int y, int width, int height)
+{
+  SDL_Rect rect = { x, y, width, height };
+
+  SDL_RenderFillRect(sdl_renderer, &rect);
+}
+
+static void DrawTouchInputOverlay_ShowGridButtons(int alpha)
+{
+  static int alpha_direction = 0;
+  static int alpha_highlight = 0;
+  int alpha_max = ALPHA_FROM_TRANSPARENCY(setup.touch.transparency);
+  int alpha_step = ALPHA_FADING_STEPSIZE(alpha_max);
+  SDL_Rect rect;
+  int grid_xsize = overlay.grid_xsize;
+  int grid_ysize = overlay.grid_ysize;
+  int x, y;
+
+  if (alpha == alpha_max)
+  {
+    if (alpha_direction < 0)
+    {
+      alpha_highlight = MAX(0, alpha_highlight - alpha_step);
+
+      if (alpha_highlight == 0)
+       alpha_direction = 1;
+    }
+    else
+    {
+      alpha_highlight = MIN(alpha_highlight + alpha_step, alpha_max);
+
+      if (alpha_highlight == alpha_max)
+       alpha_direction = -1;
+    }
+  }
+  else
+  {
+    alpha_direction = 1;
+    alpha_highlight = alpha;
+  }
+
+  SDL_SetRenderDrawBlendMode(sdl_renderer, SDL_BLENDMODE_BLEND);
+
+  for (x = 0; x < grid_xsize; x++)
+  {
+    for (y = 0; y < grid_ysize; y++)
+    {
+      int grid_button = overlay.grid_button[x][y];
+      int grid_button_action = GET_ACTION_FROM_GRID_BUTTON(grid_button);
+      int alpha_draw = alpha;
+      int outline_border = MV_NONE;
+      int border_size = 2;
+      boolean draw_outlined = setup.touch.draw_outlined;
+      boolean draw_pressed = setup.touch.draw_pressed;
+
+      if (grid_button == CHAR_GRID_BUTTON_NONE)
+       continue;
+
+      if (grid_button == overlay.grid_button_highlight)
+       alpha_draw = alpha_highlight;
+
+      if (draw_pressed && overlay.grid_button_action & grid_button_action)
+      {
+       if (draw_outlined)
+         draw_outlined = FALSE;
+       else
+         alpha_draw = MIN((float)alpha_draw * 1.5, SDL_ALPHA_OPAQUE);
+      }
+
+      SDL_SetRenderDrawColor(sdl_renderer, 255, 255, 255, alpha_draw);
+
+      rect.x = (x + 0) * video.screen_width  / grid_xsize;
+      rect.y = (y + 0) * video.screen_height / grid_ysize;
+      rect.w = (x + 1) * video.screen_width  / grid_xsize - rect.x;
+      rect.h = (y + 1) * video.screen_height / grid_ysize - rect.y;
+
+      if (x == 0 || overlay.grid_button[x - 1][y] != grid_button)
+      {
+       rect.x += border_size;
+       rect.w -= border_size;
+
+       outline_border |= MV_LEFT;
+      }
+
+      if (x == grid_xsize - 1 || overlay.grid_button[x + 1][y] != grid_button)
+      {
+       rect.w -= border_size;
+
+       outline_border |= MV_RIGHT;
+      }
+
+      if (y == 0 || overlay.grid_button[x][y - 1] != grid_button)
+      {
+       rect.y += border_size;
+       rect.h -= border_size;
+
+       outline_border |= MV_UP;
+      }
+
+      if (y == grid_ysize - 1 || overlay.grid_button[x][y + 1] != grid_button)
+      {
+       rect.h -= border_size;
+
+       outline_border |= MV_DOWN;
+      }
+
+      if (draw_outlined)
+      {
+       int rect_x = rect.x +
+         (outline_border & MV_LEFT  ? border_size : 0);
+       int rect_w = rect.w -
+         (outline_border & MV_LEFT  ? border_size : 0) -
+         (outline_border & MV_RIGHT ? border_size : 0);
+
+       if (outline_border & MV_LEFT)
+         RenderFillRectangle(rect.x, rect.y, border_size, rect.h);
+
+       if (outline_border & MV_RIGHT)
+         RenderFillRectangle(rect.x + rect.w - border_size, rect.y,
+                             border_size, rect.h);
+
+       if (outline_border & MV_UP)
+         RenderFillRectangle(rect_x, rect.y, rect_w, border_size);
+
+       if (outline_border & MV_DOWN)
+         RenderFillRectangle(rect_x, rect.y + rect.h - border_size,
+                             rect_w, border_size);
+      }
+      else
+      {
+       SDL_RenderFillRect(sdl_renderer, &rect);
+      }
+    }
+  }
+
+  SDL_SetRenderDrawColor(sdl_renderer, 0, 0, 0, 255);
+}
+
+static void DrawTouchInputOverlay(void)
 {
   static SDL_Texture *texture = NULL;
   static boolean initialized = FALSE;
   static boolean deactivated = TRUE;
+  static boolean show_grid = FALSE;
   static int width = 0, height = 0;
-  static int alpha_max = SDL_ALPHA_OPAQUE / 2;
-  static int alpha_step = 5;
-  static int alpha_last = 0;
+  static int alpha_last = -1;
   static int alpha = 0;
+  int alpha_max = ALPHA_FROM_TRANSPARENCY(setup.touch.transparency);
+  int alpha_step = ALPHA_FADING_STEPSIZE(alpha_max);
   boolean active = (overlay.enabled && overlay.active);
 
   if (!active && deactivated)
@@ -2986,6 +3210,21 @@ static void DrawTouchInputOverlay()
       deactivated = TRUE;
   }
 
+  if (overlay.show_grid)
+    show_grid = TRUE;
+  else if (deactivated)
+    show_grid = FALSE;
+
+  if (show_grid)
+    DrawTouchInputOverlay_ShowGrid(alpha);
+
+  DrawTouchInputOverlay_ShowGridButtons(alpha);
+
+  return;
+
+
+  // !!! VIRTUAL BUTTONS FROM IMAGE FILE NOT USED ANYMORE !!!
+
   if (!initialized)
   {
     char *basename = "overlay/VirtualButtons.png";
@@ -3002,7 +3241,7 @@ static void DrawTouchInputOverlay()
     width  = surface->w;
     height = surface->h;
 
-    /* set black pixel to transparent if no alpha channel / transparent color */
+    // set black pixel to transparent if no alpha channel / transparent color
     if (!SDLHasAlpha(surface) &&
        !SDLHasColorKey(surface))
       SDL_SetColorKey(surface, SET_TRANSPARENT_PIXEL,
@@ -3014,7 +3253,6 @@ static void DrawTouchInputOverlay()
     SDL_FreeSurface(surface);
 
     SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
-    SDL_SetTextureAlphaMod(texture, alpha_max);
 
     initialized = TRUE;
   }