rnd-19990107-1
[rocksndiamonds.git] / src / tools.c
index b8026898b0212a18490d2cfdac4e32b16eb76bde..424a3272071868cb0877171f5dfffab88fa7a544 100644 (file)
@@ -122,10 +122,26 @@ void BackToFront()
       }
 
       if (setup.soft_scrolling ||
-         ABS(ScreenGfxPos) + ScrollStepSize == TILEX ||
-         ABS(ScreenGfxPos) == ScrollStepSize ||
+         ABS(ScreenMovPos) + ScrollStepSize == TILEX ||
+         ABS(ScreenMovPos) == ScrollStepSize ||
          redraw_tiles > REDRAWTILES_THRESHOLD)
+      {
        XCopyArea(display, buffer, window, gc, fx, fy, SXSIZE, SYSIZE, SX, SY);
+
+#ifdef DEBUG
+#if 0
+       printf("redrawing all (ScreenGfxPos == %d) because %s\n",
+              ScreenGfxPos,
+              (setup.soft_scrolling ?
+               "setup.soft_scrolling" :
+               ABS(ScreenGfxPos) + ScrollStepSize == TILEX ?
+               "ABS(ScreenGfxPos) + ScrollStepSize == TILEX" :
+               ABS(ScreenGfxPos) == ScrollStepSize ?
+               "ABS(ScreenGfxPos) == ScrollStepSize" :
+               "redraw_tiles > REDRAWTILES_THRESHOLD"));
+#endif
+#endif
+      }
     }
     redraw_mask &= ~REDRAW_MAIN;
   }
@@ -161,6 +177,10 @@ void BackToFront()
                    VX+VIDEO_CONTROL_XPOS,VY+VIDEO_CONTROL_YPOS);
       }
     }
+    if (redraw_mask & REDRAW_DOOR_3)
+      XCopyArea(display, backbuffer, window, gc,
+               EX, EY, EXSIZE, EYSIZE,
+               EX, EY);
     redraw_mask &= ~REDRAW_DOORS;
   }
 
@@ -523,7 +543,10 @@ void DrawPlayer(struct PlayerInfo *player)
        phase = 7 - phase;
     }
 
-    DrawGraphicThruMask(sx, sy, graphic + phase);
+    if (game_emulation == EMU_SUPAPLEX)
+      DrawGraphic(sx, sy, GFX_SP_DISK_RED);
+    else
+      DrawGraphicThruMask(sx, sy, graphic + phase);
   }
 
   if ((last_jx != jx || last_jy != jy) &&
@@ -622,6 +645,14 @@ void DrawGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
              SY + (graphic / GFX_PER_LINE) * TILEY,
              TILEX, TILEY, x, y);
   }
+  else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
+  {
+    graphic -= GFX_START_ROCKSMORE;
+    XCopyArea(display, pix[PIX_MORE], d, gc,
+             (graphic % MORE_PER_LINE) * TILEX,
+             (graphic / MORE_PER_LINE) * TILEY,
+             TILEX, TILEY, x, y);
+  }
   else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
   {
     graphic -= GFX_START_ROCKSHEROES;
@@ -673,6 +704,14 @@ void DrawGraphicThruMaskExt(Drawable d, int dest_x, int dest_y, int graphic)
     src_x  = SX + (graphic % GFX_PER_LINE) * TILEX;
     src_y  = SY + (graphic / GFX_PER_LINE) * TILEY;
   }
+  else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
+  {
+    src_pixmap = pix[PIX_MORE];
+    drawing_gc = clip_gc[PIX_MORE];
+    graphic -= GFX_START_ROCKSMORE;
+    src_x  = (graphic % MORE_PER_LINE) * TILEX;
+    src_y  = (graphic / MORE_PER_LINE) * TILEY;
+  }
   else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
   {
     src_pixmap = pix[PIX_HEROES];
@@ -722,6 +761,14 @@ void DrawMiniGraphicExt(Drawable d, GC gc, int x, int y, int graphic)
              MINI_GFX_STARTY + (graphic / MINI_GFX_PER_LINE) * MINI_TILEY,
              MINI_TILEX, MINI_TILEY, x, y);
   }
+  else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
+  {
+    graphic -= GFX_START_ROCKSMORE;
+    XCopyArea(display, pix[PIX_MORE], d, gc,
+             MINI_MORE_STARTX + (graphic % MINI_MORE_PER_LINE) * MINI_TILEX,
+             MINI_MORE_STARTY + (graphic / MINI_MORE_PER_LINE) * MINI_TILEY,
+             MINI_TILEX, MINI_TILEY, x, y);
+  }
   else if (graphic >= GFX_START_ROCKSFONT && graphic <= GFX_END_ROCKSFONT)
   {
     graphic -= GFX_START_ROCKSFONT;
@@ -823,6 +870,14 @@ void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
     src_x  = SX + (graphic % GFX_PER_LINE) * TILEX + cx;
     src_y  = SY + (graphic / GFX_PER_LINE) * TILEY + cy;
   }
+  else if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
+  {
+    src_pixmap = pix[PIX_MORE];
+    drawing_gc = clip_gc[PIX_MORE];
+    graphic -= GFX_START_ROCKSMORE;
+    src_x  = (graphic % MORE_PER_LINE) * TILEX + cx;
+    src_y  = (graphic / MORE_PER_LINE) * TILEY + cy;
+  }
   else if (graphic >= GFX_START_ROCKSHEROES && graphic <= GFX_END_ROCKSHEROES)
   {
     src_pixmap = pix[PIX_HEROES];
@@ -831,6 +886,8 @@ void DrawGraphicShifted(int x,int y, int dx,int dy, int graphic,
     src_x  = (graphic % HEROES_PER_LINE) * TILEX + cx;
     src_y  = (graphic / HEROES_PER_LINE) * TILEY + cy;
   }
+  else /* big font graphics currently not allowed (and not needed) */
+    return;
 
   dest_x = FX + x * TILEX + dx;
   dest_y = FY + y * TILEY + dy;
@@ -882,13 +939,14 @@ void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
 {
   int ux = LEVELX(x), uy = LEVELY(y);
   int graphic = el2gfx(element);
-  int phase4 = ABS(MovPos[ux][uy]) / (TILEX / 4);
-  int phase  = phase4 / 2;
+  int phase8 = ABS(MovPos[ux][uy]) / (TILEX / 8);
+  int phase4 = phase8 / 2;
+  int phase2  = phase8 / 4;
   int dir = MovDir[ux][uy];
 
   if (element == EL_PACMAN || element == EL_KAEFER || element == EL_FLIEGER)
   {
-    graphic += 4*!phase;
+    graphic += 4 * !phase2;
 
     if (dir == MV_UP)
       graphic += 1;
@@ -897,6 +955,23 @@ void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
     else if (dir == MV_DOWN)
       graphic += 3;
   }
+  else if (element == EL_SP_SNIKSNAK)
+  {
+    if (dir == MV_LEFT)
+      graphic = GFX_SP_SNIKSNAK_LEFT;
+    else if (dir == MV_RIGHT)
+      graphic = GFX_SP_SNIKSNAK_RIGHT;
+    else if (dir == MV_UP)
+      graphic = GFX_SP_SNIKSNAK_UP;
+    else
+      graphic = GFX_SP_SNIKSNAK_DOWN;
+
+    graphic += (phase8 < 4 ? phase8 : 7 - phase8);
+  }
+  else if (element == EL_SP_ELECTRON)
+  {
+    graphic = GFX2_SP_ELECTRON + getGraphicAnimationPhase(8, 2, ANIM_NORMAL);
+  }
   else if (element == EL_MAULWURF || element == EL_PINGUIN ||
           element == EL_SCHWEIN || element == EL_DRACHE)
   {
@@ -929,16 +1004,17 @@ void DrawScreenElementExt(int x, int y, int dx, int dy, int element,
   }
   else if (element == EL_BUTTERFLY || element == EL_FIREFLY)
   {
-    graphic += !phase;
+    graphic += !phase2;
   }
   else if ((element == EL_FELSBROCKEN || IS_GEM(element)) && !cut_mode)
   {
-    graphic += phase * (element == EL_FELSBROCKEN ? 2 : 1);
+    if (element != EL_SP_INFOTRON)
+      graphic += phase2 * (element == EL_FELSBROCKEN ? 2 : 1);
   }
-  else if ((element == EL_SIEB_LEER || element == EL_SIEB2_LEER ||
-           element == EL_SIEB_VOLL || element == EL_SIEB2_VOLL) && SiebAktiv)
+  else if (element == EL_SIEB_LEER || element == EL_SIEB2_LEER ||
+          element == EL_SIEB_VOLL || element == EL_SIEB2_VOLL)
   {
-    graphic += 3 - (SiebAktiv % 8) / 2;
+    graphic += 3 + getGraphicAnimationPhase(4, 4, ANIM_REVERSE);
   }
   else if (IS_AMOEBOID(element))
   {
@@ -1129,7 +1205,12 @@ void DrawScreenField(int x, int y)
 
   if (!IN_LEV_FIELD(ux, uy))
   {
-    DrawScreenElement(x, y, EL_BETON);
+    if (ux < -1 || ux > lev_fieldx || uy < -1 || uy > lev_fieldy)
+      element = EL_LEERRAUM;
+    else
+      element = BorderElement;
+
+    DrawScreenElement(x, y, element);
     return;
   }
 
@@ -1253,10 +1334,19 @@ void DrawMicroElement(int xpos, int ypos, int element)
 
   graphic = el2gfx(element);
 
-  XCopyArea(display, pix[PIX_BACK], drawto, gc,
-           MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
-           MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
-           MICRO_TILEX, MICRO_TILEY, xpos, ypos);
+  if (graphic >= GFX_START_ROCKSMORE && graphic <= GFX_END_ROCKSMORE)
+  {
+    graphic -= GFX_START_ROCKSMORE;
+    XCopyArea(display, pix[PIX_MORE], drawto, gc,
+             MICRO_MORE_STARTX + (graphic % MICRO_MORE_PER_LINE) *MICRO_TILEX,
+             MICRO_MORE_STARTY + (graphic / MICRO_MORE_PER_LINE) *MICRO_TILEY,
+             MICRO_TILEX, MICRO_TILEY, xpos, ypos);
+  }
+  else
+    XCopyArea(display, pix[PIX_BACK], drawto, gc,
+             MICRO_GFX_STARTX + (graphic % MICRO_GFX_PER_LINE) * MICRO_TILEX,
+             MICRO_GFX_STARTY + (graphic / MICRO_GFX_PER_LINE) * MICRO_TILEY,
+             MICRO_TILEX, MICRO_TILEY, xpos, ypos);
 }
 
 void DrawLevel()
@@ -1309,7 +1399,7 @@ void DrawMicroLevel(int xpos, int ypos)
                         Ur[x][y]);
       else if (x >= -1 && x < lev_fieldx+1 && y >= -1 && y < lev_fieldy+1)
        DrawMicroElement(xpos + x * MICRO_TILEX, ypos + y * MICRO_TILEY,
-                        EL_BETON);
+                        BorderElement);
 
   XFillRectangle(display, drawto,gc, SX, MICROLABEL_YPOS, SXSIZE, FONT4_YSIZE);
 
@@ -1599,11 +1689,11 @@ unsigned int GetDoorState()
 
 unsigned int MoveDoor(unsigned int door_state)
 {
-  static unsigned int door1 = DOOR_OPEN_1;
-  static unsigned int door2 = DOOR_CLOSE_2;
-  static long door_delay = 0;
+  static int door1 = DOOR_OPEN_1;
+  static int door2 = DOOR_CLOSE_2;
+  static unsigned long door_delay = 0;
   int x, start, stepsize = 2;
-  long door_delay_value = stepsize * 5;
+  unsigned long door_delay_value = stepsize * 5;
 
   if (door_state == DOOR_GET_STATE)
     return(door1 | door2);
@@ -1730,10 +1820,15 @@ unsigned int MoveDoor(unsigned int door_state)
 
 int ReadPixel(Drawable d, int x, int y)
 {
-  static XImage *pixelimage;
+  XImage *pixel_image;
+  unsigned long pixel_value;
+
+  pixel_image = XGetImage(display, d, x, y, 1, 1, AllPlanes, ZPixmap);
+  pixel_value = XGetPixel(pixel_image, 0, 0);
+
+  XDestroyImage(pixel_image);
 
-  pixelimage = XGetImage(display, d, x, y, 1, 1, AllPlanes, ZPixmap);
-  return(XGetPixel(pixelimage, 0, 0));
+  return pixel_value;
 }
 
 int el2gfx(int element)
@@ -1783,6 +1878,7 @@ int el2gfx(int element)
     case EL_MORAST_VOLL:       return GFX_MORAST_VOLL;
     case EL_TROPFEN:           return GFX_TROPFEN;
     case EL_BOMBE:             return GFX_BOMBE;
+    case EL_SIEB_INAKTIV:      return GFX_SIEB_INAKTIV;
     case EL_SIEB_LEER:         return GFX_SIEB_LEER;
     case EL_SIEB_VOLL:         return GFX_SIEB_VOLL;
     case EL_SIEB_TOT:          return GFX_SIEB_TOT;
@@ -1843,6 +1939,7 @@ int el2gfx(int element)
     case EL_ERZ_EDEL_ROT:      return GFX_ERZ_EDEL_ROT;
     case EL_ERZ_EDEL_LILA:     return GFX_ERZ_EDEL_LILA;
     case EL_MAMPFER2:          return GFX_MAMPFER2;
+    case EL_SIEB2_INAKTIV:     return GFX_SIEB2_INAKTIV;
     case EL_SIEB2_LEER:                return GFX_SIEB2_LEER;
     case EL_SIEB2_VOLL:                return GFX_SIEB2_VOLL;
     case EL_SIEB2_TOT:         return GFX_SIEB2_TOT;
@@ -1862,10 +1959,24 @@ int el2gfx(int element)
     case EL_PFEIL_R:           return GFX_PFEIL_R;
     case EL_PFEIL_O:           return GFX_PFEIL_O;
     case EL_PFEIL_U:           return GFX_PFEIL_U;
+    case EL_SPEED_PILL:                return GFX_SPEED_PILL;
+    case EL_SP_TERMINAL_ACTIVE:        return GFX_SP_TERMINAL;
+    case EL_SP_BUG_ACTIVE:     return GFX_SP_BUG_ACTIVE;
+
     default:
     {
       if (IS_CHAR(element))
        return GFX_CHAR_START + (element - EL_CHAR_START);
+      else if (element >= EL_SP_START && element <= EL_SP_END)
+      {
+       int nr_element = element - EL_SP_START;
+       int gfx_per_line = 8;
+       int nr_graphic =
+         (nr_element / gfx_per_line) * MORE_PER_LINE +
+         (nr_element % gfx_per_line);
+
+       return GFX_START_ROCKSMORE + nr_graphic;
+      }
       else
        return -1;
     }