+ InitField(x, y, init_game);
+
+ /* not needed to call InitMovDir() -- already done by InitField()! */
+ if (game.engine_version < VERSION_IDENT(3,1,0,0) &&
+ CAN_MOVE(old_element) &&
+ (old_element < EL_MOLE_LEFT || old_element > EL_MOLE_DOWN))
+ InitMovDir(x, y);
+
+ /* this case is in fact a combination of not less than three bugs:
+ first, it calls InitMovDir() for elements that can move, although this is
+ already done by InitField(); then, it checks the element that was at this
+ field _before_ the call to InitField() (which can change it); lastly, it
+ was not called for "mole with direction" elements, which were treated as
+ "cannot move" due to (fixed) wrong element initialization in "src/init.c"
+ */
+}
+
+#if 1
+
+void DrawGameValue_Emeralds(int value)
+{
+ struct TextPosInfo *pos = &game.panel.gems;
+ int font_nr = FONT_TEXT_2;
+ int font_width = getFontWidth(font_nr);
+ int digits = pos->chars;
+
+ if (PANEL_DEACTIVATED(pos))
+ return;
+
+ pos->width = digits * font_width;
+
+ DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, digits), font_nr);
+}
+
+void DrawGameValue_Dynamite(int value)
+{
+ struct TextPosInfo *pos = &game.panel.inventory;
+ int font_nr = FONT_TEXT_2;
+ int font_width = getFontWidth(font_nr);
+ int digits = pos->chars;
+
+ if (PANEL_DEACTIVATED(pos))
+ return;
+
+ pos->width = digits * font_width;
+
+ DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, digits), font_nr);
+}
+
+void DrawGameValue_Score(int value)
+{
+ struct TextPosInfo *pos = &game.panel.score;
+ int font_nr = FONT_TEXT_2;
+ int font_width = getFontWidth(font_nr);
+ int digits = pos->chars;
+
+ if (PANEL_DEACTIVATED(pos))
+ return;
+
+ pos->width = digits * font_width;
+
+ DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, digits), font_nr);
+}
+
+void DrawGameValue_Time(int value)
+{
+ struct TextPosInfo *pos = &game.panel.time;
+ static int last_value = -1;
+ int digits1 = 3;
+ int digits2 = 4;
+ int digits = pos->chars;
+ int font1_nr = FONT_TEXT_2;
+ int font2_nr = FONT_TEXT_1;
+ int font_nr = font1_nr;
+ boolean use_dynamic_digits = (digits == -1 ? TRUE : FALSE);
+
+ if (PANEL_DEACTIVATED(pos))
+ return;
+
+ if (use_dynamic_digits) /* use dynamic number of digits */
+ {
+ digits = (value < 1000 ? digits1 : digits2);
+ font_nr = (value < 1000 ? font1_nr : font2_nr);
+ }
+
+ /* clear background if value just changed its size (dynamic digits only) */
+ if (use_dynamic_digits && (last_value < 1000) != (value < 1000))
+ {
+ int width1 = digits1 * getFontWidth(font1_nr);
+ int width2 = digits2 * getFontWidth(font2_nr);
+ int max_width = MAX(width1, width2);
+ int max_height = MAX(getFontHeight(font1_nr), getFontHeight(font2_nr));
+
+ pos->width = max_width;
+
+ ClearRectangleOnBackground(drawto, PANEL_XPOS(pos), PANEL_YPOS(pos),
+ max_width, max_height);
+ }
+
+ pos->width = digits * getFontWidth(font_nr);
+
+ DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, digits), font_nr);
+
+ last_value = value;
+}
+
+void DrawGameValue_Level(int value)
+{
+ struct TextPosInfo *pos = &game.panel.level;
+ int digits1 = 2;
+ int digits2 = 3;
+ int digits = pos->chars;
+ int font1_nr = FONT_TEXT_2;
+ int font2_nr = FONT_TEXT_1;
+ int font_nr = font1_nr;
+ boolean use_dynamic_digits = (digits == -1 ? TRUE : FALSE);
+
+ if (PANEL_DEACTIVATED(pos))
+ return;
+
+ if (use_dynamic_digits) /* use dynamic number of digits */
+ {
+ digits = (level_nr < 100 ? digits1 : digits2);
+ font_nr = (level_nr < 100 ? font1_nr : font2_nr);
+ }
+
+ pos->width = digits * getFontWidth(font_nr);
+
+ DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, digits), font_nr);
+}
+
+void DrawGameValue_Keys(int key[MAX_NUM_KEYS])
+{
+ struct TextPosInfo *pos = &game.panel.keys;
+ int base_key_graphic = EL_KEY_1;
+ int i;
+
+ if (PANEL_DEACTIVATED(pos))
+ return;
+
+ if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ base_key_graphic = EL_EM_KEY_1;
+
+ pos->width = 4 * MINI_TILEX;
+
+ /* currently only 4 of 8 possible keys are displayed */
+ for (i = 0; i < STD_NUM_KEYS; i++)
+ {
+ int src_x = DOOR_GFX_PAGEX5 + 18;
+ int src_y = DOOR_GFX_PAGEY1 + 123;
+ int dst_x = PANEL_XPOS(pos) + i * MINI_TILEX;
+ int dst_y = PANEL_YPOS(pos);
+
+ if (key[i])
+ DrawMiniGraphicExt(drawto, dst_x, dst_y, el2edimg(base_key_graphic + i));
+ else
+ BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, src_x, src_y,
+ MINI_TILEX, MINI_TILEY, dst_x, dst_y);
+ }
+}
+
+#else
+
+void DrawGameValue_Emeralds(int value)
+{
+ int font_nr = FONT_TEXT_2;
+ int xpos = (3 * 14 - 3 * getFontWidth(font_nr)) / 2;
+
+ if (PANEL_DEACTIVATED(game.panel.gems))
+ return;
+
+ DrawText(DX_EMERALDS + xpos, DY_EMERALDS, int2str(value, 3), font_nr);
+}
+
+void DrawGameValue_Dynamite(int value)
+{
+ int font_nr = FONT_TEXT_2;
+ int xpos = (3 * 14 - 3 * getFontWidth(font_nr)) / 2;
+
+ if (PANEL_DEACTIVATED(game.panel.inventory))
+ return;
+
+ DrawText(DX_DYNAMITE + xpos, DY_DYNAMITE, int2str(value, 3), font_nr);
+}
+
+void DrawGameValue_Score(int value)
+{
+ int font_nr = FONT_TEXT_2;
+ int xpos = (5 * 14 - 5 * getFontWidth(font_nr)) / 2;
+
+ if (PANEL_DEACTIVATED(game.panel.score))
+ return;
+
+ DrawText(DX_SCORE + xpos, DY_SCORE, int2str(value, 5), font_nr);
+}
+
+void DrawGameValue_Time(int value)
+{
+ int font1_nr = FONT_TEXT_2;
+#if 1
+ int font2_nr = FONT_TEXT_1;
+#else
+ int font2_nr = FONT_LEVEL_NUMBER;
+#endif
+ int xpos3 = (3 * 14 - 3 * getFontWidth(font1_nr)) / 2;
+ int xpos4 = (4 * 10 - 4 * getFontWidth(font2_nr)) / 2;
+
+ if (PANEL_DEACTIVATED(game.panel.time))
+ return;
+
+ /* clear background if value just changed its size */
+ if (value == 999 || value == 1000)
+ ClearRectangleOnBackground(drawto, DX_TIME1, DY_TIME, 14 * 3, 14);
+
+ if (value < 1000)
+ DrawText(DX_TIME1 + xpos3, DY_TIME, int2str(value, 3), font1_nr);
+ else
+ DrawText(DX_TIME2 + xpos4, DY_TIME, int2str(value, 4), font2_nr);
+}
+
+void DrawGameValue_Level(int value)
+{
+ int font1_nr = FONT_TEXT_2;
+#if 1
+ int font2_nr = FONT_TEXT_1;
+#else
+ int font2_nr = FONT_LEVEL_NUMBER;
+#endif
+
+ if (PANEL_DEACTIVATED(game.panel.level))
+ return;
+
+ if (level_nr < 100)
+ DrawText(DX_LEVEL1, DY_LEVEL, int2str(value, 2), font1_nr);
+ else
+ DrawText(DX_LEVEL2, DY_LEVEL, int2str(value, 3), font2_nr);
+}
+
+void DrawGameValue_Keys(int key[MAX_NUM_KEYS])
+{
+ int base_key_graphic = EL_KEY_1;
+ int i;
+
+ if (PANEL_DEACTIVATED(game.panel.keys))
+ return;
+
+ if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ base_key_graphic = EL_EM_KEY_1;
+
+ /* currently only 4 of 8 possible keys are displayed */
+ for (i = 0; i < STD_NUM_KEYS; i++)
+ {
+ int x = XX_KEYS + i * MINI_TILEX;
+ int y = YY_KEYS;
+
+ if (key[i])
+ DrawMiniGraphicExt(drawto, DX + x,DY + y, el2edimg(base_key_graphic + i));
+ else
+ BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto,
+ DOOR_GFX_PAGEX5 + x, y, MINI_TILEX, MINI_TILEY, DX + x,DY + y);
+ }
+}
+
+#endif
+
+void DrawAllGameValues(int emeralds, int dynamite, int score, int time,
+ int key_bits)
+{
+ int key[MAX_NUM_KEYS];
+ int i;
+
+ /* prevent EM engine from updating time/score values parallel to GameWon() */
+ if (level.game_engine_type == GAME_ENGINE_TYPE_EM &&
+ local_player->LevelSolved)
+ return;
+
+ for (i = 0; i < MAX_NUM_KEYS; i++)
+ key[i] = key_bits & (1 << i);
+
+ DrawGameValue_Level(level_nr);
+
+ DrawGameValue_Emeralds(emeralds);
+ DrawGameValue_Dynamite(dynamite);
+ DrawGameValue_Score(score);
+ DrawGameValue_Time(time);
+
+ DrawGameValue_Keys(key);
+}
+
+void DrawGameDoorValues()
+{
+ int time_value = (level.time == 0 ? TimePlayed : TimeLeft);
+ int dynamite_value = 0;
+ int score_value = (local_player->LevelSolved ? local_player->score_final :
+ local_player->score);
+ int gems_value = local_player->gems_still_needed;
+ int key_bits = 0;
+ int i, j;
+
+ if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ {
+ DrawGameDoorValues_EM();
+
+ return;
+ }
+
+ if (game.centered_player_nr == -1)
+ {
+ for (i = 0; i < MAX_PLAYERS; i++)
+ {
+ for (j = 0; j < MAX_NUM_KEYS; j++)
+ if (stored_player[i].key[j])
+ key_bits |= (1 << j);
+
+ dynamite_value += stored_player[i].inventory_size;
+ }
+ }
+ else
+ {
+ int player_nr = game.centered_player_nr;
+
+ for (i = 0; i < MAX_NUM_KEYS; i++)
+ if (stored_player[player_nr].key[i])
+ key_bits |= (1 << i);
+
+ dynamite_value = stored_player[player_nr].inventory_size;
+ }
+
+ DrawAllGameValues(gems_value, dynamite_value, score_value, time_value,
+ key_bits);
+}
+
+
+/*