rnd-20070913-1-src
[rocksndiamonds.git] / src / game.c
index f600e0462613cf1b878924af1dfccfc25802e06e..2cd5f41f7c9b42d5e41e3d761fb8affab20bda05 100644 (file)
 #define GAME_PANEL_MAGIC_WALL                  66
 #define GAME_PANEL_MAGIC_WALL_TIME             67
 #define GAME_PANEL_GRAVITY_STATE               68
-#define GAME_PANEL_ELEMENT_1                   69
-#define GAME_PANEL_ELEMENT_2                   70
-#define GAME_PANEL_ELEMENT_3                   71
-#define GAME_PANEL_ELEMENT_4                   72
-#define GAME_PANEL_ELEMENT_5                   73
-#define GAME_PANEL_ELEMENT_6                   74
-#define GAME_PANEL_ELEMENT_7                   75
-#define GAME_PANEL_ELEMENT_8                   76
-#define GAME_PANEL_ELEMENT_COUNT_1             77
-#define GAME_PANEL_ELEMENT_COUNT_2             78
-#define GAME_PANEL_ELEMENT_COUNT_3             79
-#define GAME_PANEL_ELEMENT_COUNT_4             80
-#define GAME_PANEL_ELEMENT_COUNT_5             81
-#define GAME_PANEL_ELEMENT_COUNT_6             82
-#define GAME_PANEL_ELEMENT_COUNT_7             83
-#define GAME_PANEL_ELEMENT_COUNT_8             84
-#define GAME_PANEL_CE_SCORE_1                  85
-#define GAME_PANEL_CE_SCORE_2                  86
-#define GAME_PANEL_CE_SCORE_3                  87
-#define GAME_PANEL_CE_SCORE_4                  88
-#define GAME_PANEL_CE_SCORE_5                  89
-#define GAME_PANEL_CE_SCORE_6                  90
-#define GAME_PANEL_CE_SCORE_7                  91
-#define GAME_PANEL_CE_SCORE_8                  92
-#define GAME_PANEL_CE_SCORE_1_ELEMENT          93
-#define GAME_PANEL_CE_SCORE_2_ELEMENT          94
-#define GAME_PANEL_CE_SCORE_3_ELEMENT          95
-#define GAME_PANEL_CE_SCORE_4_ELEMENT          96
-#define GAME_PANEL_CE_SCORE_5_ELEMENT          97
-#define GAME_PANEL_CE_SCORE_6_ELEMENT          98
-#define GAME_PANEL_CE_SCORE_7_ELEMENT          99
-#define GAME_PANEL_CE_SCORE_8_ELEMENT          100
-#define GAME_PANEL_PLAYER_NAME                 101
-#define GAME_PANEL_LEVEL_NAME                  102
-#define GAME_PANEL_LEVEL_AUTHOR                        103
-
-#define NUM_GAME_PANEL_CONTROLS                        104
+#define GAME_PANEL_GRAPHIC_1                   69
+#define GAME_PANEL_GRAPHIC_2                   70
+#define GAME_PANEL_GRAPHIC_3                   71
+#define GAME_PANEL_GRAPHIC_4                   72
+#define GAME_PANEL_GRAPHIC_5                   73
+#define GAME_PANEL_GRAPHIC_6                   74
+#define GAME_PANEL_GRAPHIC_7                   75
+#define GAME_PANEL_GRAPHIC_8                   76
+#define GAME_PANEL_ELEMENT_1                   77
+#define GAME_PANEL_ELEMENT_2                   78
+#define GAME_PANEL_ELEMENT_3                   79
+#define GAME_PANEL_ELEMENT_4                   80
+#define GAME_PANEL_ELEMENT_5                   81
+#define GAME_PANEL_ELEMENT_6                   82
+#define GAME_PANEL_ELEMENT_7                   83
+#define GAME_PANEL_ELEMENT_8                   84
+#define GAME_PANEL_ELEMENT_COUNT_1             85
+#define GAME_PANEL_ELEMENT_COUNT_2             86
+#define GAME_PANEL_ELEMENT_COUNT_3             87
+#define GAME_PANEL_ELEMENT_COUNT_4             88
+#define GAME_PANEL_ELEMENT_COUNT_5             89
+#define GAME_PANEL_ELEMENT_COUNT_6             90
+#define GAME_PANEL_ELEMENT_COUNT_7             91
+#define GAME_PANEL_ELEMENT_COUNT_8             92
+#define GAME_PANEL_CE_SCORE_1                  93
+#define GAME_PANEL_CE_SCORE_2                  94
+#define GAME_PANEL_CE_SCORE_3                  95
+#define GAME_PANEL_CE_SCORE_4                  96
+#define GAME_PANEL_CE_SCORE_5                  97
+#define GAME_PANEL_CE_SCORE_6                  98
+#define GAME_PANEL_CE_SCORE_7                  99
+#define GAME_PANEL_CE_SCORE_8                  100
+#define GAME_PANEL_CE_SCORE_1_ELEMENT          101
+#define GAME_PANEL_CE_SCORE_2_ELEMENT          102
+#define GAME_PANEL_CE_SCORE_3_ELEMENT          103
+#define GAME_PANEL_CE_SCORE_4_ELEMENT          104
+#define GAME_PANEL_CE_SCORE_5_ELEMENT          105
+#define GAME_PANEL_CE_SCORE_6_ELEMENT          106
+#define GAME_PANEL_CE_SCORE_7_ELEMENT          107
+#define GAME_PANEL_CE_SCORE_8_ELEMENT          108
+#define GAME_PANEL_PLAYER_NAME                 109
+#define GAME_PANEL_LEVEL_NAME                  110
+#define GAME_PANEL_LEVEL_AUTHOR                        111
+
+#define NUM_GAME_PANEL_CONTROLS                        112
 
 struct GamePanelOrderInfo
 {
@@ -606,6 +614,46 @@ static struct GamePanelControlInfo game_panel_controls[] =
     &game.panel.gravity_state,
     TYPE_STRING,
   },
+  {
+    GAME_PANEL_GRAPHIC_1,
+    &game.panel.graphic[0],
+    TYPE_ELEMENT,
+  },
+  {
+    GAME_PANEL_GRAPHIC_2,
+    &game.panel.graphic[1],
+    TYPE_ELEMENT,
+  },
+  {
+    GAME_PANEL_GRAPHIC_3,
+    &game.panel.graphic[2],
+    TYPE_ELEMENT,
+  },
+  {
+    GAME_PANEL_GRAPHIC_4,
+    &game.panel.graphic[3],
+    TYPE_ELEMENT,
+  },
+  {
+    GAME_PANEL_GRAPHIC_5,
+    &game.panel.graphic[4],
+    TYPE_ELEMENT,
+  },
+  {
+    GAME_PANEL_GRAPHIC_6,
+    &game.panel.graphic[5],
+    TYPE_ELEMENT,
+  },
+  {
+    GAME_PANEL_GRAPHIC_7,
+    &game.panel.graphic[6],
+    TYPE_ELEMENT,
+  },
+  {
+    GAME_PANEL_GRAPHIC_8,
+    &game.panel.graphic[7],
+    TYPE_ELEMENT,
+  },
   {
     GAME_PANEL_ELEMENT_1,
     &game.panel.element[0],
@@ -848,6 +896,9 @@ static struct GamePanelControlInfo game_panel_controls[] =
         (be) + (e) - EL_SELF > EL_CUSTOM_END   ? EL_CUSTOM_END :       \
         (be) + (e) - EL_SELF)
 
+#define GET_PLAYER_FROM_BITS(p)                                                \
+       (EL_PLAYER_1 + ((p) != PLAYER_BITS_ANY ? log_2(p) : 0))
+
 #define GET_TARGET_ELEMENT(be, e, ch, cv, cs)                          \
        ((e) == EL_TRIGGER_PLAYER   ? (ch)->actual_trigger_player    :  \
         (e) == EL_TRIGGER_ELEMENT  ? (ch)->actual_trigger_element   :  \
@@ -2060,8 +2111,17 @@ void InitGameControlValues()
 
 void UpdatePlayfieldElementCount()
 {
+  boolean use_element_count = FALSE;
   int i, j, x, y;
 
+  /* first check if it is needed at all to calculate playfield element count */
+  for (i = GAME_PANEL_ELEMENT_COUNT_1; i <= GAME_PANEL_ELEMENT_COUNT_8; i++)
+    if (!PANEL_DEACTIVATED(game_panel_controls[i].pos))
+      use_element_count = TRUE;
+
+  if (!use_element_count)
+    return;
+
   for (i = 0; i < MAX_NUM_ELEMENTS; i++)
     element_info[i].element_count = 0;
 
@@ -2280,6 +2340,9 @@ void UpdateGameControlValues()
   game_panel_controls[GAME_PANEL_GRAVITY_STATE].value = game.gravity;
 #endif
 
+  for (i = 0; i < NUM_PANEL_GRAPHICS; i++)
+    game_panel_controls[GAME_PANEL_GRAPHIC_1 + i].value = EL_GRAPHIC_1 + i;
+
   for (i = 0; i < NUM_PANEL_ELEMENTS; i++)
     game_panel_controls[GAME_PANEL_ELEMENT_1 + i].value =
       (IS_DRAWABLE_ELEMENT(game.panel.element[i].id) ?
@@ -2288,8 +2351,7 @@ void UpdateGameControlValues()
   for (i = 0; i < NUM_PANEL_ELEMENTS; i++)
     game_panel_controls[GAME_PANEL_ELEMENT_COUNT_1 + i].value =
       (IS_VALID_ELEMENT(game.panel.element_count[i].id) ?
-       element_info[game.panel.element_count[i].id].element_count :
-       EL_UNDEFINED);
+       element_info[game.panel.element_count[i].id].element_count : 0);
 
   for (i = 0; i < NUM_PANEL_CE_SCORE; i++)
     game_panel_controls[GAME_PANEL_CE_SCORE_1 + i].value =
@@ -2487,6 +2549,13 @@ void DisplayGameControlValues()
        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);
 
@@ -2593,6 +2662,15 @@ void DisplayGameControlValues()
   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;
@@ -3276,6 +3354,7 @@ static void InitGameEngine()
     {
       ei->change_page[j].actual_trigger_element = EL_EMPTY;
       ei->change_page[j].actual_trigger_player = EL_PLAYER_1;
+      ei->change_page[j].actual_trigger_player_bits = CH_PLAYER_1;
       ei->change_page[j].actual_trigger_side = CH_SIDE_NONE;
       ei->change_page[j].actual_trigger_ce_value = 0;
       ei->change_page[j].actual_trigger_ce_score = 0;
@@ -4066,8 +4145,10 @@ void InitGame()
                local_player->jy - MIDPOSY);
   }
 
+#if 0
   /* do not use PLAYING mask for fading out from main screen */
   game_status = GAME_MODE_MAIN;
+#endif
 
   StopAnimation();
 
@@ -4093,7 +4174,9 @@ void InitGame()
     FadeOut(REDRAW_FIELD);
 #endif
 
+#if 0
   game_status = GAME_MODE_PLAYING;
+#endif
 
   /* !!! FIX THIS (START) !!! */
   if (level.game_engine_type == GAME_ENGINE_TYPE_EM)
@@ -4139,8 +4222,12 @@ void InitGame()
   SetPanelBackground();
   SetDrawBackgroundMask(REDRAW_DOOR_1);
 
+#if 1
+  UpdateAndDisplayGameControlValues();
+#else
   UpdateGameDoorValues();
   DrawGameDoorValues();
+#endif
 
   if (!game.restart_level)
   {
@@ -9439,9 +9526,6 @@ void DrawTwinkleOnField(int x, int y)
   {
     MovDelay[x][y]--;
 
-    if (setup.direct_draw && MovDelay[x][y])
-      SetDrawtoField(DRAW_BUFFERED);
-
     DrawLevelElementAnimation(x, y, Feld[x][y]);
 
     if (MovDelay[x][y] != 0)
@@ -9450,18 +9534,6 @@ void DrawTwinkleOnField(int x, int y)
                                           10 - MovDelay[x][y]);
 
       DrawGraphicThruMask(SCREENX(x), SCREENY(y), IMG_TWINKLE_WHITE, frame);
-
-      if (setup.direct_draw)
-      {
-       int dest_x, dest_y;
-
-       dest_x = FX + SCREENX(x) * TILEX;
-       dest_y = FY + SCREENY(y) * TILEY;
-
-       BlitBitmap(drawto_field, window,
-                  dest_x, dest_y, TILEX, TILEY, dest_x, dest_y);
-       SetDrawtoField(DRAW_DIRECT);
-      }
     }
   }
 }
@@ -9955,11 +10027,15 @@ static void ExecuteCustomElementAction(int x, int y, int element, int page)
                            action_mode, action_arg_number,
                            action_arg_number_min, action_arg_number_max);
 
+#if 1
+  int trigger_player_bits = change->actual_trigger_player_bits;
+#else
   int trigger_player_bits =
     (change->actual_trigger_player >= EL_PLAYER_1 &&
      change->actual_trigger_player <= EL_PLAYER_4 ?
      (1 << (change->actual_trigger_player - EL_PLAYER_1)) :
      PLAYER_BITS_ANY);
+#endif
 
   int action_arg_player_bits =
     (action_arg >= CA_ARG_PLAYER_1 &&
@@ -10465,6 +10541,7 @@ static boolean ChangeElement(int x, int y, int element, int page)
     /* reset actual trigger element, trigger player and action element */
     change->actual_trigger_element = EL_EMPTY;
     change->actual_trigger_player = EL_PLAYER_1;
+    change->actual_trigger_player_bits = CH_PLAYER_1;
     change->actual_trigger_side = CH_SIDE_NONE;
     change->actual_trigger_ce_value = 0;
     change->actual_trigger_ce_score = 0;
@@ -10845,7 +10922,8 @@ static boolean CheckTriggeredElementChangeExt(int trigger_x, int trigger_y,
          IS_EQUAL_OR_IN_GROUP(trigger_element, change->trigger_element))
       {
        change->actual_trigger_element = trigger_element;
-       change->actual_trigger_player = EL_PLAYER_1 + log_2(trigger_player);
+       change->actual_trigger_player = GET_PLAYER_FROM_BITS(trigger_player);
+       change->actual_trigger_player_bits = trigger_player;
        change->actual_trigger_side = trigger_side;
        change->actual_trigger_ce_value = CustomValue[trigger_x][trigger_y];
        change->actual_trigger_ce_score = GET_CE_SCORE(trigger_element);
@@ -10964,7 +11042,8 @@ static boolean CheckElementChangeExt(int x, int y,
         IS_EQUAL_OR_IN_GROUP(trigger_element, change->trigger_element)))
     {
       change->actual_trigger_element = trigger_element;
-      change->actual_trigger_player = EL_PLAYER_1 + log_2(trigger_player);
+      change->actual_trigger_player = GET_PLAYER_FROM_BITS(trigger_player);
+      change->actual_trigger_player_bits = trigger_player;
       change->actual_trigger_side = trigger_side;
       change->actual_trigger_ce_value = CustomValue[x][y];
       change->actual_trigger_ce_score = GET_CE_SCORE(trigger_element);
@@ -11355,8 +11434,12 @@ static void CheckLevelTime()
       DrawVideoDisplay(VIDEO_STATE_TIME_ON, TapeTime);
   }
 
+#if 1
+  UpdateAndDisplayGameControlValues();
+#else
   UpdateGameDoorValues();
   DrawGameDoorValues();
+#endif
 }
 
 void AdvanceFrameAndPlayerCounters(int player_nr)
@@ -12422,7 +12505,7 @@ void ScrollLevel(int dx, int dy)
 
 #else
 
-#if 1
+#if 0
   /* !!! DOES NOT WORK FOR DIAGONAL PLAYER RELOCATION !!! */
   int xsize = (BX2 - BX1 + 1);
   int ysize = (BY2 - BY1 + 1);