+void DrawPlayerField()
+{
+ int x = JX, y = JY;
+ int sx = SCROLLX(x), sy = SCROLLY(y);
+
+ int sxx = 0, syy = 0;
+
+ int element = Feld[x][y];
+ int graphic, phase;
+
+ if (PlayerGone)
+ return;
+
+#if DEBUG
+ if (!IN_LEV_FIELD(x,y) || !IN_SCR_FIELD(sx,sy))
+ {
+ printf("DrawPlayerField(): x = %d, y = %d\n",x,y);
+ printf("DrawPlayerField(): sx = %d, sy = %d\n",sx,sy);
+ printf("DrawPlayerField(): This should never happen!\n");
+ return;
+ }
+#endif
+
+ if (element == EL_EXPLODING)
+ return;
+
+ if (direct_draw_on)
+ SetDrawtoField(DRAW_BUFFERED);
+
+ /* draw things in the field the player is leaving, if needed */
+
+ if (lastJX != JX || lastJY != JY)
+ {
+ if (Store[lastJX][lastJY])
+ {
+ DrawLevelElement(lastJX,lastJY, Store[lastJX][lastJY]);
+ DrawLevelElementThruMask(lastJX,lastJY, Feld[lastJX][lastJY]);
+ }
+ else if (Feld[lastJX][lastJY] == EL_DYNAMIT)
+ DrawDynamite(lastJX,lastJY);
+ else
+ DrawLevelField(lastJX,lastJY);
+
+ if (PlayerPushing)
+ {
+ int nextJX = JX + (JX - lastJX);
+ int nextJY = JY + (JY - lastJY);
+
+ if (PlayerGfxPos)
+ {
+ if (Feld[nextJX][nextJY] == EL_SOKOBAN_FELD_VOLL)
+ DrawLevelElement(nextJX,nextJY, EL_SOKOBAN_FELD_LEER);
+ else
+ DrawLevelElement(nextJX,nextJY, EL_LEERRAUM);
+ }
+ else
+ DrawLevelField(nextJX,nextJY);
+ }
+ }
+
+ /* draw things behind the player, if needed */
+
+ if (Store[x][y])
+ DrawLevelElement(x,y, Store[x][y]);
+ else if (element != EL_DYNAMIT && element != EL_DYNABOMB)
+ DrawLevelField(x,y);
+
+ /* draw player himself */
+
+ if (PlayerMovDir==MV_LEFT)
+ graphic = (PlayerPushing ? GFX_SPIELER_PUSH_LEFT : GFX_SPIELER_LEFT);
+ else if (PlayerMovDir==MV_RIGHT)
+ graphic = (PlayerPushing ? GFX_SPIELER_PUSH_RIGHT : GFX_SPIELER_RIGHT);
+ else if (PlayerMovDir==MV_UP)
+ graphic = GFX_SPIELER_UP;
+ else /* MV_DOWN || MV_NO_MOVING */
+ graphic = GFX_SPIELER_DOWN;
+
+ graphic += PlayerFrame;
+
+ if (PlayerGfxPos)
+ {
+ if (PlayerMovDir == MV_LEFT || PlayerMovDir == MV_RIGHT)
+ sxx = PlayerGfxPos;
+ else
+ syy = PlayerGfxPos;
+ }
+
+ if (!soft_scrolling_on && ScreenMovPos)
+ sxx = syy = 0;
+
+ DrawGraphicShiftedThruMask(sx,sy, sxx,syy, graphic, NO_CUTTING);
+
+ if (PlayerPushing && PlayerGfxPos)
+ {
+ int nextJX = JX + (JX - lastJX);
+ int nextJY = JY + (JY - lastJY);
+ int px = SCROLLX(nextJX), py = SCROLLY(nextJY);
+
+ if (Feld[JX][JY] == EL_SOKOBAN_FELD_LEER ||
+ Feld[nextJX][nextJY] == EL_SOKOBAN_FELD_VOLL)
+ DrawGraphicShiftedThruMask(px,py,sxx,syy, GFX_SOKOBAN_OBJEKT,NO_CUTTING);
+ else
+ {
+ int element = Feld[nextJX][nextJY];
+ int graphic = el2gfx(element);
+
+ if (element == EL_FELSBROCKEN && sxx)
+ {
+ int phase = (PlayerGfxPos / (TILEX/4));
+
+ if (PlayerMovDir == MV_LEFT)
+ graphic += phase;
+ else
+ graphic += (phase+4)%4;
+ }
+
+ DrawGraphicShifted(px,py, sxx,syy, graphic, NO_CUTTING, NO_MASKING);
+ }
+ }
+
+ /* draw things in front of player (EL_DYNAMIT || EL_DYNABOMB) */
+
+ if (element == EL_DYNAMIT || element == EL_DYNABOMB)
+ {
+ graphic = el2gfx(element);
+
+ if (element == EL_DYNAMIT)
+ {
+ if ((phase = (96-MovDelay[x][y])/12) > 6)
+ phase = 6;
+ }
+ else
+ {
+ if ((phase = ((96-MovDelay[x][y])/6) % 8) > 3)
+ phase = 7-phase;
+ }
+
+ DrawGraphicThruMask(sx,sy, graphic + phase);
+ }
+
+ if (direct_draw_on)
+ {
+ int dest_x = SX+SCROLLX(x)*TILEX;
+ int dest_y = SY+SCROLLY(y)*TILEY;
+ int x_size = TILEX;
+ int y_size = TILEY;
+
+ if (!ScreenMovPos)
+ {
+ dest_x = SX + SCROLLX(MIN(JX,lastJX))*TILEX;
+ dest_y = SY + SCROLLY(MIN(JY,lastJY))*TILEY;
+ x_size = TILEX * (1 + ABS(JX - lastJX));
+ y_size = TILEY * (1 + ABS(JY - lastJY));
+ }
+
+ XCopyArea(display,drawto_field,window,gc,
+ dest_x,dest_y, x_size,y_size, dest_x,dest_y);
+ SetDrawtoField(DRAW_DIRECT);
+ }
+
+ MarkTileDirty(sx,sy);
+}
+
+static int getGraphicAnimationPhase(int frames, int delay, int mode)