rnd-20060621-1-src
[rocksndiamonds.git] / src / tools.c
index 3f611344d4f9a8169c2ed3daba4c6da9375bacb1..3a2b962a3469435f1d8f00d6acf497f5be894d87 100644 (file)
@@ -241,7 +241,8 @@ void BackToFront()
   if (redraw_mask & REDRAW_ALL)
   {
     BlitBitmap(backbuffer, window, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
-    redraw_mask = 0;
+
+    redraw_mask = REDRAW_NONE;
   }
 
   if (redraw_mask & REDRAW_FIELD)
@@ -413,6 +414,50 @@ void FadeToFront()
   BackToFront();
 }
 
+void FadeIn(int fade_delay)
+{
+  if (fade_delay == 0)
+  {
+    BackToFront();
+
+    return;
+  }
+
+  FadeScreen(NULL, FADE_MODE_FADE_IN, fade_delay, 0);
+
+  redraw_mask = REDRAW_NONE;
+}
+
+void FadeOut(int fade_delay, int post_delay)
+{
+  if (fade_delay == 0)
+  {
+    ClearRectangle(backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE);
+    BackToFront();
+
+    return;
+  }
+
+  FadeScreen(NULL, FADE_MODE_FADE_OUT, fade_delay, post_delay);
+
+  redraw_mask = REDRAW_NONE;
+}
+
+void FadeCross(int fade_delay)
+{
+  if (fade_delay == 0)
+  {
+    BlitBitmap(bitmap_db_title, backbuffer, 0, 0, WIN_XSIZE, WIN_YSIZE, 0, 0);
+    BackToFront();
+
+    return;
+  }
+
+  FadeScreen(bitmap_db_title, FADE_MODE_CROSSFADE, fade_delay, 0);
+
+  redraw_mask = REDRAW_NONE;
+}
+
 void SetMainBackgroundImageIfDefined(int graphic)
 {
   if (graphic_info[graphic].bitmap)
@@ -503,6 +548,17 @@ inline int getGraphicAnimationFrame(int graphic, int sync_frame)
   if (graphic_info[graphic].anim_global_sync || sync_frame < 0)
     sync_frame = FrameCounter;
 
+#if 0
+  if (graphic == element_info[EL_CUSTOM_START + 255].graphic[ACTION_DEFAULT] &&
+      sync_frame == 0 &&
+      FrameCounter > 10)
+  {
+    int x = 1 / 0;
+
+    printf("::: FOO!\n");
+  }
+#endif
+
   return getAnimationFrame(graphic_info[graphic].anim_frames,
                           graphic_info[graphic].anim_delay,
                           graphic_info[graphic].anim_mode,
@@ -1342,8 +1398,8 @@ void AnimateEnvelope(int envelope_nr, int anim_mode, int action)
   int font_nr = FONT_ENVELOPE_1 + envelope_nr;
   int font_width = getFontWidth(font_nr);
   int font_height = getFontHeight(font_nr);
-  int max_xsize = level.envelope_xsize[envelope_nr];
-  int max_ysize = level.envelope_ysize[envelope_nr];
+  int max_xsize = level.envelope[envelope_nr].xsize;
+  int max_ysize = level.envelope[envelope_nr].ysize;
   int xstart = (anim_mode & ANIM_VERTICAL ? max_xsize : 0);
   int ystart = (anim_mode & ANIM_HORIZONTAL ? max_ysize : 0);
   int xend = max_xsize;
@@ -1370,7 +1426,7 @@ void AnimateEnvelope(int envelope_nr, int anim_mode, int action)
       DrawEnvelopeBackground(envelope_nr, sx,sy, xx,yy, xsize, ysize, font_nr);
 
     DrawTextToTextArea(SX + sx + font_width, SY + sy + font_height,
-                      level.envelope_text[envelope_nr], font_nr, max_xsize,
+                      level.envelope[envelope_nr].text, font_nr, max_xsize,
                       xsize - 2, ysize - 2, mask_mode);
 
     redraw_mask |= REDRAW_FIELD | REDRAW_FROM_BACKBUFFER;
@@ -1396,7 +1452,7 @@ void ShowEnvelope(int envelope_nr)
 
   game.envelope_active = TRUE; /* needed for RedrawPlayfield() events */
 
-  PlaySoundStereo(sound_opening, SOUND_MIDDLE);
+  PlayMenuSoundStereo(sound_opening, SOUND_MIDDLE);
 
   if (anim_mode == ANIM_DEFAULT)
     AnimateEnvelope(envelope_nr, ANIM_DEFAULT, ACTION_OPENING);
@@ -1408,7 +1464,7 @@ void ShowEnvelope(int envelope_nr)
   else
     WaitForEventToContinue();
 
-  PlaySoundStereo(sound_closing, SOUND_MIDDLE);
+  PlayMenuSoundStereo(sound_closing, SOUND_MIDDLE);
 
   if (anim_mode != ANIM_NONE)
     AnimateEnvelope(envelope_nr, main_anim_mode, ACTION_CLOSING);
@@ -1652,9 +1708,9 @@ void DrawMicroLevel(int xpos, int ypos, boolean restart)
 
   /* !!! THIS ALL SUCKS -- SHOULD BE CLEANLY REWRITTEN !!! */
   /* redraw micro level label, if needed */
-  if (strcmp(level.name, NAMELESS_LEVEL_NAME) != 0 &&
-      strcmp(level.author, ANONYMOUS_NAME) != 0 &&
-      strcmp(level.author, leveldir_current->name) != 0 &&
+  if (!strEqual(level.name, NAMELESS_LEVEL_NAME) &&
+      !strEqual(level.author, ANONYMOUS_NAME) &&
+      !strEqual(level.author, leveldir_current->name) &&
       DelayReached(&label_delay, MICROLEVEL_LABEL_DELAY))
   {
     int max_label_counter = 23;
@@ -1904,8 +1960,17 @@ void DrawPlayer(struct PlayerInfo *player)
             last_element == EL_EM_DYNAMITE_ACTIVE ||
             last_element == EL_SP_DISK_RED_ACTIVE)
       DrawDynamite(last_jx, last_jy);
+#if 0
+    /* !!! this is not enough to prevent flickering of players which are
+       moving next to each others without a free tile between them -- this
+       can only be solved by drawing all players layer by layer (first the
+       background, then the foreground etc.) !!! => TODO */
+    else if (!IS_PLAYER(last_jx, last_jy))
+      DrawLevelField(last_jx, last_jy);
+#else
     else
       DrawLevelField(last_jx, last_jy);
+#endif
 
     if (player->is_pushing && IN_SCR_FIELD(SCREENX(next_jx), SCREENY(next_jy)))
       DrawLevelElement(next_jx, next_jy, EL_EMPTY);
@@ -2502,7 +2567,7 @@ unsigned int MoveDoor(unsigned int door_state)
     door_2.height = VYSIZE;
 
   if (door_state == DOOR_GET_STATE)
-    return(door1 | door2);
+    return (door1 | door2);
 
   if (door_state & DOOR_SET_STATE)
   {
@@ -2511,17 +2576,20 @@ unsigned int MoveDoor(unsigned int door_state)
     if (door_state & DOOR_ACTION_2)
       door2 = door_state & DOOR_ACTION_2;
 
-    return(door1 | door2);
+    return (door1 | door2);
   }
 
-  if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
-    door_state &= ~DOOR_OPEN_1;
-  else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
-    door_state &= ~DOOR_CLOSE_1;
-  if (door2 == DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
-    door_state &= ~DOOR_OPEN_2;
-  else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
-    door_state &= ~DOOR_CLOSE_2;
+  if (!(door_state & DOOR_FORCE_REDRAW))
+  {
+    if (door1 == DOOR_OPEN_1 && door_state & DOOR_OPEN_1)
+      door_state &= ~DOOR_OPEN_1;
+    else if (door1 == DOOR_CLOSE_1 && door_state & DOOR_CLOSE_1)
+      door_state &= ~DOOR_CLOSE_1;
+    if (door2 == DOOR_OPEN_2 && door_state & DOOR_OPEN_2)
+      door_state &= ~DOOR_OPEN_2;
+    else if (door2 == DOOR_CLOSE_2 && door_state & DOOR_CLOSE_2)
+      door_state &= ~DOOR_CLOSE_2;
+  }
 
   door_delay_value = (door_state & DOOR_ACTION_1 ? door_1.step_delay :
                      door_2.step_delay);
@@ -2556,8 +2624,8 @@ unsigned int MoveDoor(unsigned int door_state)
 #if 1
     int end = door_size;
 #else
-    int end = (door_state & DOOR_ACTION_1 &&
-              door_1.anim_mode & ANIM_VERTICAL ? DYSIZE : DXSIZE);
+    int end = (door_state & DOOR_ACTION_1 && door_1.anim_mode & ANIM_VERTICAL ?
+              DYSIZE : DXSIZE);
 #endif
 #if 1
     int start = ((door_state & DOOR_NO_DELAY) ? end : 0);
@@ -2570,9 +2638,9 @@ unsigned int MoveDoor(unsigned int door_state)
     {
       /* opening door sound has priority over simultaneously closing door */
       if (door_state & (DOOR_OPEN_1 | DOOR_OPEN_2))
-       PlaySoundStereo(SND_DOOR_OPENING, SOUND_MIDDLE);
+       PlayMenuSoundStereo(SND_DOOR_OPENING, SOUND_MIDDLE);
       else if (door_state & (DOOR_CLOSE_1 | DOOR_CLOSE_2))
-       PlaySoundStereo(SND_DOOR_CLOSING, SOUND_MIDDLE);
+       PlayMenuSoundStereo(SND_DOOR_CLOSING, SOUND_MIDDLE);
     }
 
     for (k = start; k <= end && !(door_1_done && door_2_done); k += stepsize)
@@ -2675,9 +2743,15 @@ unsigned int MoveDoor(unsigned int door_state)
 
       if (door_state & DOOR_ACTION_2)
       {
+#if 1
+       int a = MIN(x * door_2.step_offset, door_size);
+       int p = (door_state & DOOR_OPEN_2 ? door_size - a : a);
+       int i = p + door_skip;
+#else
        int a = MIN(x * door_2.step_offset, door_size_2);
        int p = (door_state & DOOR_OPEN_2 ? door_size_2 - a : a);
        int i = p + door_skip;
+#endif
 
        if (door_2.anim_mode & ANIM_STATIC_PANEL)
        {
@@ -2754,13 +2828,15 @@ unsigned int MoveDoor(unsigned int door_state)
        door_2_done = (a == VXSIZE);
       }
 
-      BackToFront();
+      if (!(door_state & DOOR_NO_DELAY))
+      {
+       BackToFront();
 
-      if (game_status == GAME_MODE_MAIN)
-       DoAnimation();
+       if (game_status == GAME_MODE_MAIN)
+         DoAnimation();
 
-      if (!(door_state & DOOR_NO_DELAY))
        WaitUntilDelayReached(&door_delay, door_delay_value);
+      }
     }
   }
 
@@ -5853,3 +5929,60 @@ void InitGraphicInfo_EM(void)
   exit(0);
 #endif
 }
+
+void PlayMenuSound()
+{
+  int sound = menu.sound[game_status];
+
+  if (sound == SND_UNDEFINED)
+    return;
+
+  if ((!setup.sound_simple && !IS_LOOP_SOUND(sound)) ||
+      (!setup.sound_loops && IS_LOOP_SOUND(sound)))
+    return;
+
+  if (IS_LOOP_SOUND(sound))
+    PlaySoundLoop(sound);
+  else
+    PlaySound(sound);
+}
+
+void PlayMenuSoundStereo(int sound, int stereo_position)
+{
+  if (sound == SND_UNDEFINED)
+    return;
+
+  if ((!setup.sound_simple && !IS_LOOP_SOUND(sound)) ||
+      (!setup.sound_loops && IS_LOOP_SOUND(sound)))
+    return;
+
+  if (IS_LOOP_SOUND(sound))
+    PlaySoundExt(sound, SOUND_MAX_VOLUME, stereo_position, SND_CTRL_PLAY_LOOP);
+  else
+    PlaySoundStereo(sound, stereo_position);
+}
+
+void PlayMenuSoundIfLoop()
+{
+  int sound = menu.sound[game_status];
+
+  if (sound == SND_UNDEFINED)
+    return;
+
+  if ((!setup.sound_simple && !IS_LOOP_SOUND(sound)) ||
+      (!setup.sound_loops && IS_LOOP_SOUND(sound)))
+    return;
+
+  if (IS_LOOP_SOUND(sound))
+    PlaySoundLoop(sound);
+}
+
+void PlayMenuMusic()
+{
+  int music = menu.music[game_status];
+
+  if (music == MUS_UNDEFINED)
+    return;
+
+  PlayMusic(music);
+}