fixed compiler warnings (after adding "-Wstrict-prototypes")
[rocksndiamonds.git] / src / tools.c
index 76b40a291272a7c899ca1fba7c003f69ccfcf72b..82a58803ca3e15e0fb5da15a04984339c6c257c6 100644 (file)
@@ -166,7 +166,7 @@ static struct DoorPartControlInfo door_part_controls[] =
 
 
 /* forward declaration for internal use */
-static void UnmapToolButtons();
+static void UnmapToolButtons(void);
 static void HandleToolButtons(struct GadgetInfo *);
 static int el_act_dir2crm(int, int, int);
 static int el_act2crm(int, int);
@@ -208,7 +208,7 @@ int correctLevelPosY_EM(int ly)
   return ly;
 }
 
-static int getFieldbufferOffsetX_RND()
+static int getFieldbufferOffsetX_RND(void)
 {
   int full_lev_fieldx = lev_fieldx + (BorderElement != EL_EMPTY ? 2 : 0);
   int dx = (ScreenMovDir & (MV_LEFT | MV_RIGHT) ? ScreenGfxPos : 0);
@@ -240,7 +240,7 @@ static int getFieldbufferOffsetX_RND()
   return fx;
 }
 
-static int getFieldbufferOffsetY_RND()
+static int getFieldbufferOffsetY_RND(void)
 {
   int full_lev_fieldy = lev_fieldy + (BorderElement != EL_EMPTY ? 2 : 0);
   int dy = (ScreenMovDir & (MV_UP | MV_DOWN)    ? ScreenGfxPos : 0);
@@ -479,7 +479,7 @@ void SetDrawtoField(int mode)
   }
 }
 
-static void RedrawPlayfield_RND()
+static void RedrawPlayfield_RND(void)
 {
   if (game.envelope_active)
     return;
@@ -488,7 +488,7 @@ static void RedrawPlayfield_RND()
   DrawAllPlayers();
 }
 
-void RedrawPlayfield()
+void RedrawPlayfield(void)
 {
   if (game_status != GAME_MODE_PLAYING)
     return;
@@ -592,7 +592,7 @@ static void DrawMaskedBorderExt(int redraw_mask, int draw_target)
   }
 }
 
-void DrawMaskedBorder_FIELD()
+void DrawMaskedBorder_FIELD(void)
 {
   DrawMaskedBorderExt_FIELD(DRAW_TO_BACKBUFFER);
 }
@@ -711,7 +711,7 @@ void BlitScreenToBitmap(Bitmap *target_bitmap)
   redraw_mask |= REDRAW_FIELD;
 }
 
-void DrawFramesPerSecond()
+void DrawFramesPerSecond(void)
 {
   char text[100];
   int font_nr = FONT_TEXT_2;
@@ -737,7 +737,7 @@ void DrawFramesPerSecond()
 }
 
 #if DEBUG_FRAME_TIME
-static void PrintFrameTimeDebugging()
+static void PrintFrameTimeDebugging(void)
 {
   static unsigned int last_counter = 0;
   unsigned int counter = Counter();
@@ -790,7 +790,7 @@ static boolean equalRedrawMasks(int mask_1, int mask_2)
   return unifiedRedrawMask(mask_1) == unifiedRedrawMask(mask_2);
 }
 
-void BackToFront()
+void BackToFront(void)
 {
   static int last_redraw_mask = REDRAW_NONE;
 
@@ -981,9 +981,11 @@ static void FadeExt(int fade_mask, int fade_mode, int fade_type)
                draw_border_function);
 
   redraw_mask &= ~fade_mask;
+
+  ClearAutoRepeatKeyEvents();
 }
 
-static void SetScreenStates_BeforeFadingIn()
+static void SetScreenStates_BeforeFadingIn(void)
 {
   // temporarily set screen mode for animations to screen after fading in
   global.anim_status = global.anim_status_next;
@@ -996,7 +998,7 @@ static void SetScreenStates_BeforeFadingIn()
   global.anim_status = GAME_MODE_PSEUDO_FADING;
 }
 
-static void SetScreenStates_AfterFadingIn()
+static void SetScreenStates_AfterFadingIn(void)
 {
   // store new source screen (to use correct masked border for fading)
   gfx.fade_border_source_status = global.border_status;
@@ -1004,7 +1006,7 @@ static void SetScreenStates_AfterFadingIn()
   global.anim_status = global.anim_status_next;
 }
 
-static void SetScreenStates_BeforeFadingOut()
+static void SetScreenStates_BeforeFadingOut(void)
 {
   // store new target screen (to use correct masked border for fading)
   gfx.fade_border_target_status = game_status;
@@ -1017,7 +1019,7 @@ static void SetScreenStates_BeforeFadingOut()
     PrepareFadeBitmap(DRAW_TO_FADE_SOURCE);
 }
 
-static void SetScreenStates_AfterFadingOut()
+static void SetScreenStates_AfterFadingOut(void)
 {
   global.border_status = game_status;
 }
@@ -1084,28 +1086,28 @@ static void FadeSetLeaveNext(struct TitleFadingInfo fading_leave, boolean set)
     fading = fading_leave_stored;
 }
 
-void FadeSetEnterMenu()
+void FadeSetEnterMenu(void)
 {
   fading = menu.enter_menu;
 
   FadeSetLeaveNext(fading, TRUE);      /* (keep same fade mode) */
 }
 
-void FadeSetLeaveMenu()
+void FadeSetLeaveMenu(void)
 {
   fading = menu.leave_menu;
 
   FadeSetLeaveNext(fading, TRUE);      /* (keep same fade mode) */
 }
 
-void FadeSetEnterScreen()
+void FadeSetEnterScreen(void)
 {
   fading = menu.enter_screen[game_status];
 
   FadeSetLeaveNext(menu.leave_screen[game_status], TRUE);      /* store */
 }
 
-void FadeSetNextScreen()
+void FadeSetNextScreen(void)
 {
   fading = menu.next_screen[game_status];
 
@@ -1113,7 +1115,7 @@ void FadeSetNextScreen()
   // FadeSetLeaveNext(fading, TRUE);   /* (keep same fade mode) */
 }
 
-void FadeSetLeaveScreen()
+void FadeSetLeaveScreen(void)
 {
   FadeSetLeaveNext(menu.leave_screen[game_status], FALSE);     /* recall */
 }
@@ -1128,19 +1130,19 @@ void FadeSetFromType(int type)
     FadeSetLeaveMenu();
 }
 
-void FadeSetDisabled()
+void FadeSetDisabled(void)
 {
   static struct TitleFadingInfo fading_none = { FADE_MODE_NONE, -1, -1, -1 };
 
   fading = fading_none;
 }
 
-void FadeSkipNextFadeIn()
+void FadeSkipNextFadeIn(void)
 {
   FadeExt(0, FADE_MODE_SKIP_FADE_IN, FADE_TYPE_SKIP);
 }
 
-void FadeSkipNextFadeOut()
+void FadeSkipNextFadeOut(void)
 {
   FadeExt(0, FADE_MODE_SKIP_FADE_OUT, FADE_TYPE_SKIP);
 }
@@ -1211,7 +1213,7 @@ void SetDoorBackgroundImage(int graphic)
   SetDoorBackgroundBitmap(getBackgroundBitmap(graphic));
 }
 
-void SetPanelBackground()
+void SetPanelBackground(void)
 {
   struct GraphicInfo *gfx = &graphic_info[IMG_BACKGROUND_PANEL];
 
@@ -1268,7 +1270,7 @@ static int vxsize_last = -1, vysize_last = -1;
 static int ex_last = -1, ey_last = -1;
 static int exsize_last = -1, eysize_last = -1;
 
-boolean CheckIfGlobalBorderHasChanged()
+boolean CheckIfGlobalBorderHasChanged(void)
 {
   // if game status has not changed, global border has not changed either
   if (game_status == game_status_last)
@@ -1280,7 +1282,7 @@ boolean CheckIfGlobalBorderHasChanged()
   return (global_border_bitmap_last != global_border_bitmap);
 }
 
-boolean CheckIfGlobalBorderRedrawIsNeeded()
+boolean CheckIfGlobalBorderRedrawIsNeeded(void)
 {
   // if game status has not changed, nothing has to be redrawn
   if (game_status == game_status_last)
@@ -1325,7 +1327,7 @@ void RedrawGlobalBorderFromBitmap(Bitmap *bitmap)
     ClearRectangle(backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE);
 }
 
-void RedrawGlobalBorder()
+void RedrawGlobalBorder(void)
 {
   Bitmap *bitmap = getGlobalBorderBitmapFromStatus(game_status);
 
@@ -1336,7 +1338,7 @@ void RedrawGlobalBorder()
 
 #define ONLY_REDRAW_GLOBAL_BORDER_IF_NEEDED            0
 
-static void RedrawGlobalBorderIfNeeded()
+static void RedrawGlobalBorderIfNeeded(void)
 {
 #if ONLY_REDRAW_GLOBAL_BORDER_IF_NEEDED
   if (game_status == game_status_last)
@@ -1415,7 +1417,7 @@ static void RedrawGlobalBorderIfNeeded()
   eysize_last = EYSIZE;
 }
 
-void ClearField()
+void ClearField(void)
 {
   RedrawGlobalBorderIfNeeded();
 
@@ -1440,7 +1442,7 @@ void MarkTileDirty(int x, int y)
   redraw_mask |= REDRAW_FIELD;
 }
 
-void SetBorderElement()
+void SetBorderElement(void)
 {
   int x, y;
 
@@ -1574,6 +1576,10 @@ void getSizedGraphicSourceExt(int graphic, int frame, int tilesize,
 {
   struct GraphicInfo *g = &graphic_info[graphic];
 
+  // if no graphics defined at all, use fallback graphics
+  if (g->bitmaps == NULL)
+    *g = graphic_info[IMG_CHAR_EXCLAM];
+
   // if no in-game graphics defined, always use standard graphic size
   if (g->bitmaps[IMG_BITMAP_GAME] == NULL)
     tilesize = TILESIZE;
@@ -2796,6 +2802,8 @@ void AnimateEnvelope(int envelope_nr, int anim_mode, int action)
 
     SkipUntilDelayReached(&anim_delay, anim_delay_value, &i, last_frame);
   }
+
+  ClearAutoRepeatKeyEvents();
 }
 
 void ShowEnvelope(int envelope_nr)
@@ -3079,6 +3087,8 @@ void AnimateEnvelopeRequest(int anim_mode, int action)
 
     SkipUntilDelayReached(&anim_delay, anim_delay_value, &i, last_frame);
   }
+
+  ClearAutoRepeatKeyEvents();
 }
 
 void ShowEnvelopeRequest(char *text, unsigned int req_state, int action)
@@ -3500,16 +3510,185 @@ static void DrawPreviewLevelExt(boolean restart)
   }
 }
 
-void DrawPreviewLevelInitial()
+void DrawPreviewPlayers(void)
+{
+  if (game_status != GAME_MODE_MAIN)
+    return;
+
+  if (!network.enabled && !setup.team_mode)
+    return;
+
+  boolean player_found[MAX_PLAYERS];
+  int num_players = 0;
+  int i, x, y;
+
+  for (i = 0; i < MAX_PLAYERS; i++)
+    player_found[i] = FALSE;
+
+  /* check which players can be found in the level (simple approach) */
+  for (x = 0; x < lev_fieldx; x++)
+  {
+    for (y = 0; y < lev_fieldy; y++)
+    {
+      int element = level.field[x][y];
+
+      if (ELEM_IS_PLAYER(element))
+      {
+       int player_nr = GET_PLAYER_NR(element);
+
+       player_nr = MIN(MAX(0, player_nr), MAX_PLAYERS - 1);
+
+       if (!player_found[player_nr])
+         num_players++;
+
+       player_found[player_nr] = TRUE;
+      }
+    }
+  }
+
+  struct TextPosInfo *pos = &menu.main.preview_players;
+  int tile_size = pos->tile_size;
+  int border_size = pos->border_size;
+  int player_xoffset_raw = (pos->vertical ? 0 : tile_size + border_size);
+  int player_yoffset_raw = (pos->vertical ? tile_size + border_size : 0);
+  int player_xoffset = (pos->xoffset != -1 ? pos->xoffset : player_xoffset_raw);
+  int player_yoffset = (pos->yoffset != -1 ? pos->yoffset : player_yoffset_raw);
+  int max_players_width  = (MAX_PLAYERS - 1) * player_xoffset + tile_size;
+  int max_players_height = (MAX_PLAYERS - 1) * player_yoffset + tile_size;
+  int all_players_width  = (num_players - 1) * player_xoffset + tile_size;
+  int all_players_height = (num_players - 1) * player_yoffset + tile_size;
+  int max_xpos = SX + ALIGNED_XPOS(pos->x, max_players_width,  pos->align);
+  int max_ypos = SY + ALIGNED_YPOS(pos->y, max_players_height, pos->valign);
+  int xpos = SX + ALIGNED_XPOS(pos->x, all_players_width,  pos->align);
+  int ypos = SY + ALIGNED_YPOS(pos->y, all_players_height, pos->valign);
+
+  /* clear area in which the players will be drawn */
+  ClearRectangleOnBackground(drawto, max_xpos, max_ypos,
+                            max_players_width, max_players_height);
+
+  /* only draw players if level is suited for team mode */
+  if (num_players < 2)
+    return;
+
+  /* draw all players that were found in the level */
+  for (i = 0; i < MAX_PLAYERS; i++)
+  {
+    if (player_found[i])
+    {
+      int graphic = el2img(EL_PLAYER_1 + i);
+
+      DrawSizedGraphicThruMaskExt(drawto, xpos, ypos, graphic, 0, tile_size);
+
+      xpos += player_xoffset;
+      ypos += player_yoffset;
+    }
+  }
+}
+
+void DrawPreviewLevelInitial(void)
 {
   DrawPreviewLevelExt(TRUE);
+  DrawPreviewPlayers();
 }
 
-void DrawPreviewLevelAnimation()
+void DrawPreviewLevelAnimation(void)
 {
   DrawPreviewLevelExt(FALSE);
 }
 
+static void DrawNetworkPlayer(int x, int y, int player_nr, int tile_size,
+                             int border_size, int font_nr)
+{
+  int graphic = el2img(EL_PLAYER_1 + player_nr);
+  int font_height = getFontHeight(font_nr);
+  int player_height = MAX(tile_size, font_height);
+  int xoffset_text = tile_size + border_size;
+  int yoffset_text    = (player_height - font_height) / 2;
+  int yoffset_graphic = (player_height - tile_size) / 2;
+  char *player_name = getNetworkPlayerName(player_nr + 1);
+
+  DrawSizedGraphicThruMaskExt(drawto, x, y + yoffset_graphic, graphic, 0,
+                             tile_size);
+  DrawText(x + xoffset_text, y + yoffset_text, player_name, font_nr);
+}
+
+void DrawNetworkPlayersExt(boolean force)
+{
+  if (game_status != GAME_MODE_MAIN)
+    return;
+
+  if (!network.connected && !force)
+    return;
+
+  int num_players = 0;
+  int i;
+
+  for (i = 0; i < MAX_PLAYERS; i++)
+    if (stored_player[i].connected_network)
+      num_players++;
+
+  struct TextPosInfo *pos = &menu.main.network_players;
+  int tile_size = pos->tile_size;
+  int border_size = pos->border_size;
+  int xoffset_text = tile_size + border_size;
+  int font_nr = pos->font;
+  int font_width = getFontWidth(font_nr);
+  int font_height = getFontHeight(font_nr);
+  int player_height = MAX(tile_size, font_height);
+  int player_yoffset = player_height + border_size;
+  int max_players_width = xoffset_text + MAX_PLAYER_NAME_LEN * font_width;
+  int max_players_height = MAX_PLAYERS * player_yoffset - border_size;
+  int all_players_height = num_players * player_yoffset - border_size;
+  int max_xpos = SX + ALIGNED_XPOS(pos->x, max_players_width,  pos->align);
+  int max_ypos = SY + ALIGNED_YPOS(pos->y, max_players_height, pos->valign);
+  int ypos = SY + ALIGNED_YPOS(pos->y, all_players_height, pos->valign);
+
+  ClearRectangleOnBackground(drawto, max_xpos, max_ypos,
+                            max_players_width, max_players_height);
+
+  /* first draw local network player ... */
+  for (i = 0; i < MAX_PLAYERS; i++)
+  {
+    if (stored_player[i].connected_network &&
+       stored_player[i].connected_locally)
+    {
+      char *player_name = getNetworkPlayerName(i + 1);
+      int player_width = xoffset_text + getTextWidth(player_name, font_nr);
+      int xpos = SX + ALIGNED_XPOS(pos->x, player_width,  pos->align);
+
+      DrawNetworkPlayer(xpos, ypos, i, tile_size, border_size, font_nr);
+
+      ypos += player_yoffset;
+    }
+  }
+
+  /* ... then draw all other network players */
+  for (i = 0; i < MAX_PLAYERS; i++)
+  {
+    if (stored_player[i].connected_network &&
+       !stored_player[i].connected_locally)
+    {
+      char *player_name = getNetworkPlayerName(i + 1);
+      int player_width = xoffset_text + getTextWidth(player_name, font_nr);
+      int xpos = SX + ALIGNED_XPOS(pos->x, player_width,  pos->align);
+
+      DrawNetworkPlayer(xpos, ypos, i, tile_size, border_size, font_nr);
+
+      ypos += player_yoffset;
+    }
+  }
+}
+
+void DrawNetworkPlayers(void)
+{
+  DrawNetworkPlayersExt(FALSE);
+}
+
+void ClearNetworkPlayers(void)
+{
+  DrawNetworkPlayersExt(TRUE);
+}
+
 inline static void DrawGraphicAnimationExt(DrawBuffer *dst_bitmap, int x, int y,
                                           int graphic, int sync_frame,
                                           int mask_mode)
@@ -3647,7 +3826,7 @@ static boolean equalGraphics(int graphic1, int graphic2)
          g1->anim_mode   == g2->anim_mode);
 }
 
-void DrawAllPlayers()
+void DrawAllPlayers(void)
 {
   int i;
 
@@ -3998,7 +4177,7 @@ void DrawPlayer(struct PlayerInfo *player)
 
 /* ------------------------------------------------------------------------- */
 
-void WaitForEventToContinue()
+void WaitForEventToContinue(void)
 {
   boolean still_wait = TRUE;
 
@@ -4182,8 +4361,8 @@ static int RequestHandleEvents(unsigned int req_state)
 
              case KSYM_Return:
              case KSYM_y:
-             case KSYM_Y:
 #if defined(TARGET_SDL2)
+             case KSYM_Y:
              case KSYM_Select:
              case KSYM_Menu:
 #if defined(KSYM_Rewind)
@@ -4195,8 +4374,8 @@ static int RequestHandleEvents(unsigned int req_state)
 
              case KSYM_Escape:
              case KSYM_n:
-             case KSYM_N:
 #if defined(TARGET_SDL2)
+             case KSYM_N:
              case KSYM_Back:
 #if defined(KSYM_FastForward)
              case KSYM_FastForward:    /* for Amazon Fire TV remote */
@@ -4211,7 +4390,42 @@ static int RequestHandleEvents(unsigned int req_state)
            }
 
            if (req_state & REQ_PLAYER)
-             result = 0;
+           {
+             int old_player_nr = setup.network_player_nr;
+
+             if (result != -1)
+               result = old_player_nr + 1;
+
+             switch (key)
+             {
+               case KSYM_space:
+                 result = old_player_nr + 1;
+                 break;
+
+               case KSYM_Up:
+               case KSYM_1:
+                 result = 1;
+                 break;
+
+               case KSYM_Right:
+               case KSYM_2:
+                 result = 2;
+                 break;
+
+               case KSYM_Down:
+               case KSYM_3:
+                 result = 3;
+                 break;
+
+               case KSYM_Left:
+               case KSYM_4:
+                 result = 4;
+                 break;
+
+               default:
+                 break;
+             }
+           }
 
            break;
          }
@@ -4227,19 +4441,52 @@ static int RequestHandleEvents(unsigned int req_state)
              case SDL_CONTROLLER_BUTTON_A:
              case SDL_CONTROLLER_BUTTON_X:
              case SDL_CONTROLLER_BUTTON_LEFTSHOULDER:
+             case SDL_CONTROLLER_BUTTON_LEFTSTICK:
                result = 1;
                break;
 
              case SDL_CONTROLLER_BUTTON_B:
              case SDL_CONTROLLER_BUTTON_Y:
              case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER:
+             case SDL_CONTROLLER_BUTTON_RIGHTSTICK:
              case SDL_CONTROLLER_BUTTON_BACK:
                result = 0;
                break;
            }
 
            if (req_state & REQ_PLAYER)
-             result = 0;
+           {
+             int old_player_nr = setup.network_player_nr;
+
+             if (result != -1)
+               result = old_player_nr + 1;
+
+             switch (event.cbutton.button)
+             {
+               case SDL_CONTROLLER_BUTTON_DPAD_UP:
+               case SDL_CONTROLLER_BUTTON_Y:
+                 result = 1;
+                 break;
+
+               case SDL_CONTROLLER_BUTTON_DPAD_RIGHT:
+               case SDL_CONTROLLER_BUTTON_B:
+                 result = 2;
+                 break;
+
+               case SDL_CONTROLLER_BUTTON_DPAD_DOWN:
+               case SDL_CONTROLLER_BUTTON_A:
+                 result = 3;
+                 break;
+
+               case SDL_CONTROLLER_BUTTON_DPAD_LEFT:
+               case SDL_CONTROLLER_BUTTON_X:
+                 result = 4;
+                 break;
+
+               default:
+                 break;
+             }
+           }
 
            break;
 
@@ -4264,6 +4511,22 @@ static int RequestHandleEvents(unsigned int req_state)
       else if (joy & JOY_BUTTON_2)
        result = 0;
     }
+    else if (AnyJoystick())
+    {
+      int joy = AnyJoystick();
+
+      if (req_state & REQ_PLAYER)
+      {
+       if (joy & JOY_UP)
+         result = 1;
+       else if (joy & JOY_RIGHT)
+         result = 2;
+       else if (joy & JOY_DOWN)
+         result = 3;
+       else if (joy & JOY_LEFT)
+         result = 4;
+      }
+    }
 
     if (level_solved)
     {
@@ -4304,13 +4567,12 @@ static boolean RequestDoor(char *text, unsigned int req_state)
 
   SetMouseCursor(CURSOR_DEFAULT);
 
-#if defined(NETWORK_AVALIABLE)
   /* pause network game while waiting for request to answer */
-  if (options.network &&
+  if (network.enabled &&
       game_status == GAME_MODE_PLAYING &&
+      !AllPlayersGone &&
       req_state & REQUEST_WAIT_FOR_INPUT)
     SendToServer_PausePlaying();
-#endif
 
   old_door_state = GetDoorState();
 
@@ -4446,13 +4708,12 @@ static boolean RequestDoor(char *text, unsigned int req_state)
     SetDrawBackgroundMask(REDRAW_FIELD);
   }
 
-#if defined(NETWORK_AVALIABLE)
   /* continue network game after request */
-  if (options.network &&
+  if (network.enabled &&
       game_status == GAME_MODE_PLAYING &&
+      !AllPlayersGone &&
       req_state & REQUEST_WAIT_FOR_INPUT)
     SendToServer_ContinuePlaying();
-#endif
 
   /* restore deactivated drawing when quick-loading level tape recording */
   if (tape.playing && tape.deactivate_display)
@@ -4474,13 +4735,12 @@ static boolean RequestEnvelope(char *text, unsigned int req_state)
 
   SetMouseCursor(CURSOR_DEFAULT);
 
-#if defined(NETWORK_AVALIABLE)
   /* pause network game while waiting for request to answer */
-  if (options.network &&
+  if (network.enabled &&
       game_status == GAME_MODE_PLAYING &&
+      !AllPlayersGone &&
       req_state & REQUEST_WAIT_FOR_INPUT)
     SendToServer_PausePlaying();
-#endif
 
   /* simulate releasing mouse button over last gadget, if still pressed */
   if (button_status)
@@ -4533,13 +4793,12 @@ static boolean RequestEnvelope(char *text, unsigned int req_state)
     SetDrawBackgroundMask(REDRAW_FIELD);
   }
 
-#if defined(NETWORK_AVALIABLE)
   /* continue network game after request */
-  if (options.network &&
+  if (network.enabled &&
       game_status == GAME_MODE_PLAYING &&
+      !AllPlayersGone &&
       req_state & REQUEST_WAIT_FOR_INPUT)
     SendToServer_ContinuePlaying();
-#endif
 
   /* restore deactivated drawing when quick-loading level tape recording */
   if (tape.playing && tape.deactivate_display)
@@ -4579,7 +4838,7 @@ static int compareDoorPartOrderInfo(const void *object1, const void *object2)
   return compare_result;
 }
 
-void InitGraphicCompatibilityInfo_Doors()
+void InitGraphicCompatibilityInfo_Doors(void)
 {
   struct
   {
@@ -4736,7 +4995,7 @@ void InitGraphicCompatibilityInfo_Doors()
   }
 }
 
-void InitDoors()
+void InitDoors(void)
 {
   int i;
 
@@ -4801,7 +5060,7 @@ unsigned int CloseDoor(unsigned int door_state)
   return MoveDoor(door_state);
 }
 
-unsigned int GetDoorState()
+unsigned int GetDoorState(void)
 {
   return MoveDoor(DOOR_GET_STATE);
 }
@@ -5170,10 +5429,12 @@ unsigned int MoveDoor(unsigned int door_state)
   DrawMaskedBorder(REDRAW_DOOR_1);
   DrawMaskedBorder(REDRAW_DOOR_2);
 
+  ClearAutoRepeatKeyEvents();
+
   return (door1 | door2);
 }
 
-static boolean useSpecialEditorDoor()
+static boolean useSpecialEditorDoor(void)
 {
   int graphic = IMG_GLOBAL_BORDER_EDITOR;
   boolean redefined = getImageListEntryFromImageID(graphic)->redefined;
@@ -5196,7 +5457,7 @@ static boolean useSpecialEditorDoor()
   return TRUE;
 }
 
-void DrawSpecialEditorDoor()
+void DrawSpecialEditorDoor(void)
 {
   struct GraphicInfo *gfx1 = &graphic_info[IMG_DOOR_2_TOP_BORDER_CORRECTION];
   int top_border_width = gfx1->width;
@@ -5219,7 +5480,7 @@ void DrawSpecialEditorDoor()
   redraw_mask |= REDRAW_ALL;
 }
 
-void UndrawSpecialEditorDoor()
+void UndrawSpecialEditorDoor(void)
 {
   struct GraphicInfo *gfx1 = &graphic_info[IMG_DOOR_2_TOP_BORDER_CORRECTION];
   int top_border_width = gfx1->width;
@@ -5294,13 +5555,14 @@ static struct
   }
 };
 
-void CreateToolButtons()
+void CreateToolButtons(void)
 {
   int i;
 
   for (i = 0; i < NUM_TOOL_BUTTONS; i++)
   {
-    struct GraphicInfo *gfx = &graphic_info[toolbutton_info[i].graphic];
+    int graphic = toolbutton_info[i].graphic;
+    struct GraphicInfo *gfx = &graphic_info[graphic];
     struct TextPosInfo *pos = toolbutton_info[i].pos;
     struct GadgetInfo *gi;
     Bitmap *deco_bitmap = None;
@@ -5324,33 +5586,30 @@ void CreateToolButtons()
       if (x < 0 || x + gfx->width  > request.width ||
          y < 0 || y + gfx->height > request.height)
       {
-       // use left padding of "yes" button as default border padding
-       int padding = toolbutton_info[TOOL_CTRL_ID_YES].pos->x;
-
        if (id == TOOL_CTRL_ID_YES)
        {
-         x = padding;
-         y = request.height - 2 * request.border_size - gfx->height - padding;
+         x = 0;
+         y = request.height - 2 * request.border_size - gfx->height;
        }
        else if (id == TOOL_CTRL_ID_NO)
        {
-         x = request.width  - 2 * request.border_size - gfx->width  - padding;
-         y = request.height - 2 * request.border_size - gfx->height - padding;
+         x = request.width  - 2 * request.border_size - gfx->width;
+         y = request.height - 2 * request.border_size - gfx->height;
        }
        else if (id == TOOL_CTRL_ID_CONFIRM)
        {
          x = (request.width - 2 * request.border_size - gfx->width) / 2;
-         y = request.height - 2 * request.border_size - gfx->height - padding;
+         y = request.height - 2 * request.border_size - gfx->height;
        }
        else if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4)
        {
          int player_nr = id - TOOL_CTRL_ID_PLAYER_1;
 
          x = (request.width - 2 * request.border_size - gfx->width) / 2;
-         y = request.height - 2 * request.border_size - gfx->height - padding;
+         y = request.height - 2 * request.border_size - gfx->height * 2;
 
-         x += (player_nr % 2 ? +1 : -1) * gfx->width / 2;
-         y += (player_nr / 2 ?  0 : -1) * gfx->height;
+         x += (player_nr == 3 ? -1 : player_nr == 1 ? +1 : 0) * gfx->width;
+         y += (player_nr == 0 ? -1 : player_nr == 2 ? +1 : 0) * gfx->height;
        }
       }
     }
@@ -5366,6 +5625,7 @@ void CreateToolButtons()
     }
 
     gi = CreateGadget(GDI_CUSTOM_ID, id,
+                     GDI_IMAGE_ID, graphic,
                      GDI_INFO_TEXT, toolbutton_info[i].infotext,
                      GDI_X, dx + x,
                      GDI_Y, dy + y,
@@ -5391,7 +5651,7 @@ void CreateToolButtons()
   }
 }
 
-void FreeToolButtons()
+void FreeToolButtons(void)
 {
   int i;
 
@@ -5399,7 +5659,7 @@ void FreeToolButtons()
     FreeGadget(tool_gadget[i]);
 }
 
-static void UnmapToolButtons()
+static void UnmapToolButtons(void)
 {
   int i;
 
@@ -7853,9 +8113,9 @@ int getBeltSwitchElementFromBeltNrAndBeltDir(int belt_nr, int belt_dir)
   return getBeltSwitchElementFromBeltNrAndBeltDirNr(belt_nr, belt_dir_nr);
 }
 
-boolean getTeamMode_EM()
+boolean getTeamMode_EM(void)
 {
-  return game.team_mode;
+  return game.team_mode || network_playing;
 }
 
 int getGameFrameDelay_EM(int native_em_game_frame_delay)
@@ -8909,7 +9169,7 @@ void PlayMenuSoundExt(int sound)
     PlaySound(sound);
 }
 
-void PlayMenuSound()
+void PlayMenuSound(void)
 {
   PlayMenuSoundExt(menu.sound[game_status]);
 }
@@ -8942,7 +9202,7 @@ void PlayMenuSoundIfLoopExt(int sound)
     PlaySoundLoop(sound);
 }
 
-void PlayMenuSoundIfLoop()
+void PlayMenuSoundIfLoop(void)
 {
   PlayMenuSoundIfLoopExt(menu.sound[game_status]);
 }
@@ -8955,10 +9215,13 @@ void PlayMenuMusicExt(int music)
   if (!setup.sound_music)
     return;
 
-  PlayMusic(music);
+  if (IS_LOOP_MUSIC(music))
+    PlayMusicLoop(music);
+  else
+    PlayMusic(music);
 }
 
-void PlayMenuMusic()
+void PlayMenuMusic(void)
 {
   char *curr_music = getCurrentlyPlayingMusicFilename();
   char *next_music = getMusicInfoEntryFilename(menu.music[game_status]);
@@ -8967,18 +9230,18 @@ void PlayMenuMusic()
     PlayMenuMusicExt(menu.music[game_status]);
 }
 
-void PlayMenuSoundsAndMusic()
+void PlayMenuSoundsAndMusic(void)
 {
   PlayMenuSound();
   PlayMenuMusic();
 }
 
-static void FadeMenuSounds()
+static void FadeMenuSounds(void)
 {
   FadeSounds();
 }
 
-static void FadeMenuMusic()
+static void FadeMenuMusic(void)
 {
   char *curr_music = getCurrentlyPlayingMusicFilename();
   char *next_music = getMusicInfoEntryFilename(menu.music[game_status]);
@@ -8987,27 +9250,27 @@ static void FadeMenuMusic()
     FadeMusic();
 }
 
-void FadeMenuSoundsAndMusic()
+void FadeMenuSoundsAndMusic(void)
 {
   FadeMenuSounds();
   FadeMenuMusic();
 }
 
-void PlaySoundActivating()
+void PlaySoundActivating(void)
 {
 #if 0
   PlaySound(SND_MENU_ITEM_ACTIVATING);
 #endif
 }
 
-void PlaySoundSelecting()
+void PlaySoundSelecting(void)
 {
 #if 0
   PlaySound(SND_MENU_ITEM_SELECTING);
 #endif
 }
 
-void ToggleFullscreenOrChangeWindowScalingIfNeeded()
+void ToggleFullscreenOrChangeWindowScalingIfNeeded(void)
 {
   boolean change_fullscreen = (setup.fullscreen !=
                               video.fullscreen_enabled);
@@ -9126,12 +9389,19 @@ void SetFontStatus(int game_status_new)
   }
 }
 
-void ResetFontStatus()
+void ResetFontStatus(void)
 {
   SetFontStatus(-1);
 }
 
-boolean CheckIfPlayfieldViewportHasChanged()
+void SetLevelSetInfo(char *identifier, int level_nr)
+{
+  setString(&levelset.identifier, identifier);
+
+  levelset.level_nr = level_nr;
+}
+
+boolean CheckIfPlayfieldViewportHasChanged(void)
 {
   // if game status has not changed, playfield viewport has not changed either
   if (game_status == game_status_last)
@@ -9150,13 +9420,13 @@ boolean CheckIfPlayfieldViewportHasChanged()
          new_full_sysize != FULL_SYSIZE);
 }
 
-boolean CheckIfGlobalBorderOrPlayfieldViewportHasChanged()
+boolean CheckIfGlobalBorderOrPlayfieldViewportHasChanged(void)
 {
   return (CheckIfGlobalBorderHasChanged() ||
          CheckIfPlayfieldViewportHasChanged());
 }
 
-void ChangeViewportPropertiesIfNeeded()
+void ChangeViewportPropertiesIfNeeded(void)
 {
   boolean use_mini_tilesize = (level.game_engine_type == GAME_ENGINE_TYPE_MM ?
                               FALSE : setup.small_game_graphics);