+ if (!redraw_panel)
+ return;
+
+ /* copy default game door content to main double buffer */
+ BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto,
+ DOOR_GFX_PAGEX5, DOOR_GFX_PAGEY1, DXSIZE, DYSIZE, DX, DY);
+
+ /* redraw game control buttons */
+#if 1
+ RedrawGameButtons();
+#else
+ UnmapGameButtons();
+ MapGameButtons();
+#endif
+
+ game_status = GAME_MODE_PSEUDO_PANEL;
+
+#if 1
+ for (i = 0; i < NUM_GAME_PANEL_CONTROLS; i++)
+#else
+ for (i = 0; game_panel_controls[i].nr != -1; i++)
+#endif
+ {
+#if 1
+ int nr = game_panel_order[i].nr;
+ struct GamePanelControlInfo *gpc = &game_panel_controls[nr];
+#else
+ struct GamePanelControlInfo *gpc = &game_panel_controls[i];
+ int nr = gpc->nr;
+#endif
+ struct TextPosInfo *pos = gpc->pos;
+ int type = gpc->type;
+ int value = gpc->value;
+ int frame = gpc->frame;
+#if 0
+ int last_value = gpc->last_value;
+ int last_frame = gpc->last_frame;
+#endif
+ int size = pos->size;
+ int font = pos->font;
+ boolean draw_masked = pos->draw_masked;
+ int mask_mode = (draw_masked ? BLIT_MASKED : BLIT_OPAQUE);
+
+ if (PANEL_DEACTIVATED(pos))
+ continue;
+
+#if 0
+ if (value == last_value && frame == last_frame)
+ continue;
+#endif
+
+ gpc->last_value = value;
+ gpc->last_frame = frame;
+
+#if 0
+ printf("::: value %d changed from %d to %d\n", nr, last_value, value);
+#endif
+
+ if (type == TYPE_INTEGER)
+ {
+ if (nr == GAME_PANEL_LEVEL_NUMBER ||
+ nr == GAME_PANEL_TIME)
+ {
+ boolean use_dynamic_size = (size == -1 ? TRUE : FALSE);
+
+ if (use_dynamic_size) /* use dynamic number of digits */
+ {
+ int value_change = (nr == GAME_PANEL_LEVEL_NUMBER ? 100 : 1000);
+ int size1 = (nr == GAME_PANEL_LEVEL_NUMBER ? 2 : 3);
+ int size2 = size1 + 1;
+ int font1 = pos->font;
+ int font2 = pos->font_alt;
+
+ size = (value < value_change ? size1 : size2);
+ font = (value < value_change ? font1 : font2);
+
+#if 0
+ /* clear background if value just changed its size (dynamic digits) */
+ if ((last_value < value_change) != (value < value_change))
+ {
+ int width1 = size1 * getFontWidth(font1);
+ int width2 = size2 * getFontWidth(font2);
+ int max_width = MAX(width1, width2);
+ int max_height = MAX(getFontHeight(font1), getFontHeight(font2));
+
+ pos->width = max_width;
+
+ ClearRectangleOnBackground(drawto, PANEL_XPOS(pos), PANEL_YPOS(pos),
+ max_width, max_height);
+ }
+#endif
+ }
+ }
+
+#if 1
+ /* correct text size if "digits" is zero or less */
+ if (size <= 0)
+ size = strlen(int2str(value, size));
+
+ /* dynamically correct text alignment */
+ pos->width = size * getFontWidth(font);
+#endif
+
+ DrawTextExt(drawto, PANEL_XPOS(pos), PANEL_YPOS(pos),
+ int2str(value, size), font, mask_mode);
+ }
+ else if (type == TYPE_ELEMENT)
+ {
+ int element, graphic;
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+ int width, height;
+ int dst_x = PANEL_XPOS(pos);
+ int dst_y = PANEL_YPOS(pos);
+
+#if 1
+ if (value != EL_UNDEFINED && value != EL_EMPTY)
+ {
+ element = value;
+ graphic = el2panelimg(value);
+
+ // printf("::: %d, '%s' [%d]\n", element, EL_NAME(element), size);
+
+#if 1
+ if (element >= EL_GRAPHIC_1 && element <= EL_GRAPHIC_8 && size == 0)
+ size = TILESIZE;
+#endif
+
+ getSizedGraphicSource(graphic, frame, size, &src_bitmap,
+ &src_x, &src_y);
+
+ width = graphic_info[graphic].width * size / TILESIZE;
+ height = graphic_info[graphic].height * size / TILESIZE;
+
+ if (draw_masked)
+ {
+ SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc,
+ dst_x - src_x, dst_y - src_y);
+ BlitBitmapMasked(src_bitmap, drawto, src_x, src_y, width, height,
+ dst_x, dst_y);
+ }
+ else
+ {
+ BlitBitmap(src_bitmap, drawto, src_x, src_y, width, height,
+ dst_x, dst_y);
+ }
+ }
+#else
+ if (value == EL_UNDEFINED || value == EL_EMPTY)
+ {
+ element = (last_value == EL_UNDEFINED ? EL_EMPTY : last_value);
+ graphic = el2panelimg(element);
+
+ src_bitmap = graphic_info[IMG_GLOBAL_DOOR].bitmap;
+ src_x = DOOR_GFX_PAGEX5 + ALIGNED_TEXT_XPOS(pos);
+ src_y = DOOR_GFX_PAGEY1 + ALIGNED_TEXT_YPOS(pos);
+ }
+ else
+ {
+ element = value;
+ graphic = el2panelimg(value);
+
+ getSizedGraphicSource(graphic, frame, size, &src_bitmap, &src_x,&src_y);
+ }
+
+ width = graphic_info[graphic].width * size / TILESIZE;
+ height = graphic_info[graphic].height * size / TILESIZE;
+
+ BlitBitmap(src_bitmap, drawto, src_x, src_y, width, height, dst_x, dst_y);
+#endif
+ }
+ else if (type == TYPE_STRING)
+ {
+ boolean active = (value != 0);
+ char *state_normal = "off";
+ char *state_active = "on";
+ char *state = (active ? state_active : state_normal);
+ char *s = (nr == GAME_PANEL_GRAVITY_STATE ? state :
+ nr == GAME_PANEL_PLAYER_NAME ? setup.player_name :
+ nr == GAME_PANEL_LEVEL_NAME ? level.name :
+ nr == GAME_PANEL_LEVEL_AUTHOR ? level.author : NULL);
+
+ if (nr == GAME_PANEL_GRAVITY_STATE)
+ {
+ int font1 = pos->font; /* (used for normal state) */
+ int font2 = pos->font_alt; /* (used for active state) */
+#if 0
+ int size1 = strlen(state_normal);
+ int size2 = strlen(state_active);
+ int width1 = size1 * getFontWidth(font1);
+ int width2 = size2 * getFontWidth(font2);
+ int max_width = MAX(width1, width2);
+ int max_height = MAX(getFontHeight(font1), getFontHeight(font2));
+
+ pos->width = max_width;
+
+ /* clear background for values that may have changed its size */
+ ClearRectangleOnBackground(drawto, PANEL_XPOS(pos), PANEL_YPOS(pos),
+ max_width, max_height);
+#endif
+
+ font = (active ? font2 : font1);
+ }
+
+ if (s != NULL)
+ {
+ char *s_cut;
+
+#if 1
+ if (size <= 0)
+ {
+ /* don't truncate output if "chars" is zero or less */
+ size = strlen(s);
+
+ /* dynamically correct text alignment */
+ pos->width = size * getFontWidth(font);
+ }
+#endif
+
+ s_cut = getStringCopyN(s, size);
+
+ DrawTextExt(drawto, PANEL_XPOS(pos), PANEL_YPOS(pos),
+ s_cut, font, mask_mode);
+
+ free(s_cut);
+ }
+ }
+
+ redraw_mask |= REDRAW_DOOR_1;
+ }
+
+ game_status = GAME_MODE_PLAYING;
+}
+
+void UpdateAndDisplayGameControlValues()
+{
+ if (tape.warp_forward)
+ return;
+
+ UpdateGameControlValues();
+ DisplayGameControlValues();
+}
+
+void DrawGameValue_Emeralds(int value)
+{
+ struct TextPosInfo *pos = &game.panel.gems;
+#if 1
+ int font_nr = pos->font;
+#else
+ int font_nr = FONT_TEXT_2;
+#endif
+ int font_width = getFontWidth(font_nr);
+ int chars = pos->size;
+
+#if 1
+ return; /* !!! USE NEW STUFF !!! */
+#endif
+
+ if (PANEL_DEACTIVATED(pos))
+ return;
+
+ pos->width = chars * font_width;
+
+ DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, chars), font_nr);
+}
+
+void DrawGameValue_Dynamite(int value)
+{
+ struct TextPosInfo *pos = &game.panel.inventory_count;
+#if 1
+ int font_nr = pos->font;
+#else
+ int font_nr = FONT_TEXT_2;
+#endif
+ int font_width = getFontWidth(font_nr);
+ int chars = pos->size;
+
+#if 1
+ return; /* !!! USE NEW STUFF !!! */
+#endif
+
+ if (PANEL_DEACTIVATED(pos))
+ return;
+
+ pos->width = chars * font_width;
+
+ DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, chars), font_nr);
+}
+
+void DrawGameValue_Score(int value)
+{
+ struct TextPosInfo *pos = &game.panel.score;
+#if 1
+ int font_nr = pos->font;
+#else
+ int font_nr = FONT_TEXT_2;
+#endif
+ int font_width = getFontWidth(font_nr);
+ int chars = pos->size;
+
+#if 1
+ return; /* !!! USE NEW STUFF !!! */
+#endif
+
+ if (PANEL_DEACTIVATED(pos))
+ return;
+
+ pos->width = chars * font_width;
+
+ DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, chars), font_nr);
+}
+
+void DrawGameValue_Time(int value)
+{
+ struct TextPosInfo *pos = &game.panel.time;
+ static int last_value = -1;
+ int chars1 = 3;
+ int chars2 = 4;
+ int chars = pos->size;
+#if 1
+ int font1_nr = pos->font;
+ int font2_nr = pos->font_alt;
+#else
+ int font1_nr = FONT_TEXT_2;
+ int font2_nr = FONT_TEXT_1;
+#endif
+ int font_nr = font1_nr;
+ boolean use_dynamic_chars = (chars == -1 ? TRUE : FALSE);
+
+#if 1
+ return; /* !!! USE NEW STUFF !!! */
+#endif
+
+ if (PANEL_DEACTIVATED(pos))
+ return;
+
+ if (use_dynamic_chars) /* use dynamic number of chars */
+ {
+ chars = (value < 1000 ? chars1 : chars2);
+ font_nr = (value < 1000 ? font1_nr : font2_nr);
+ }
+
+ /* clear background if value just changed its size (dynamic chars only) */
+ if (use_dynamic_chars && (last_value < 1000) != (value < 1000))
+ {
+ int width1 = chars1 * getFontWidth(font1_nr);
+ int width2 = chars2 * 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 = chars * getFontWidth(font_nr);
+
+ DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, chars), font_nr);
+
+ last_value = value;
+}
+
+void DrawGameValue_Level(int value)
+{
+ struct TextPosInfo *pos = &game.panel.level_number;
+ int chars1 = 2;
+ int chars2 = 3;
+ int chars = pos->size;
+#if 1
+ int font1_nr = pos->font;
+ int font2_nr = pos->font_alt;
+#else
+ int font1_nr = FONT_TEXT_2;
+ int font2_nr = FONT_TEXT_1;
+#endif
+ int font_nr = font1_nr;
+ boolean use_dynamic_chars = (chars == -1 ? TRUE : FALSE);
+
+#if 1
+ return; /* !!! USE NEW STUFF !!! */
+#endif
+
+ if (PANEL_DEACTIVATED(pos))
+ return;
+
+ if (use_dynamic_chars) /* use dynamic number of chars */
+ {
+ chars = (level_nr < 100 ? chars1 : chars2);
+ font_nr = (level_nr < 100 ? font1_nr : font2_nr);
+ }
+
+ pos->width = chars * getFontWidth(font_nr);
+
+ DrawText(PANEL_XPOS(pos), PANEL_YPOS(pos), int2str(value, chars), font_nr);
+}
+
+void DrawGameValue_Keys(int key[MAX_NUM_KEYS])
+{
+#if 0
+ struct TextPosInfo *pos = &game.panel.keys;
+#endif
+#if 0
+ int base_key_graphic = EL_KEY_1;
+#endif
+ int i;
+
+#if 1
+ return; /* !!! USE NEW STUFF !!! */
+#endif
+
+#if 0
+ if (PANEL_DEACTIVATED(pos))
+ return;
+#endif
+
+#if 0
+ if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
+ base_key_graphic = EL_EM_KEY_1;
+#endif
+
+#if 0
+ pos->width = 4 * MINI_TILEX;
+#endif
+
+#if 1
+ for (i = 0; i < MAX_NUM_KEYS; i++)
+#else
+ /* currently only 4 of 8 possible keys are displayed */
+ for (i = 0; i < STD_NUM_KEYS; i++)
+#endif
+ {
+#if 1
+ struct TextPosInfo *pos = &game.panel.key[i];
+#endif
+ int src_x = DOOR_GFX_PAGEX5 + 18 + (i % 4) * MINI_TILEX;
+ int src_y = DOOR_GFX_PAGEY1 + 123;
+#if 1
+ int dst_x = PANEL_XPOS(pos);
+ int dst_y = PANEL_YPOS(pos);
+#else
+ int dst_x = PANEL_XPOS(pos) + i * MINI_TILEX;
+ int dst_y = PANEL_YPOS(pos);
+#endif
+
+#if 1
+ int element = (i >= STD_NUM_KEYS ? EL_EMC_KEY_5 - 4 :
+ level.game_engine_type == GAME_ENGINE_TYPE_EM ? EL_EM_KEY_1 :
+ EL_KEY_1) + i;
+ int graphic = el2edimg(element);
+#endif
+
+#if 1
+ if (PANEL_DEACTIVATED(pos))
+ continue;
+#endif
+
+#if 0
+ /* masked blit with tiles from half-size scaled bitmap does not work yet
+ (no mask bitmap created for these sizes after loading and scaling) --
+ solution: load without creating mask, scale, then create final mask */
+
+ BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, src_x, src_y,
+ MINI_TILEX, MINI_TILEY, dst_x, dst_y);
+
+ if (key[i])
+ {
+#if 0
+ int graphic = el2edimg(base_key_graphic + i);
+#endif
+ Bitmap *src_bitmap;
+ int src_x, src_y;
+
+ getMiniGraphicSource(graphic, &src_bitmap, &src_x, &src_y);
+
+ SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc,
+ dst_x - src_x, dst_y - src_y);
+ BlitBitmapMasked(src_bitmap, drawto, src_x, src_y, MINI_TILEX, MINI_TILEY,
+ dst_x, dst_y);
+ }
+#else
+#if 1
+ if (key[i])
+ DrawMiniGraphicExt(drawto, dst_x, dst_y, graphic);
+ else
+ BlitBitmap(graphic_info[IMG_GLOBAL_DOOR].bitmap, drawto, src_x, src_y,
+ MINI_TILEX, MINI_TILEY, dst_x, dst_y);
+#else
+ 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);
+#endif
+#endif
+ }
+}
+
+#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_count))
+ 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 UpdateGameDoorValues()
+{
+ UpdateGameControlValues();