1 /*
2     sdlshadowdisplay.c
3 
4     Copyright (C) 2010-2021 Amf
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20 
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <SDL/SDL.h>
25 #include <SDL/SDL_image.h>
26 
27 #include "chroma.h"
28 #include "menu.h"
29 #include "level.h"
30 #include "display.h"
31 #include "graphics.h"
32 #include "colours.h"
33 #include "sdlfont.h"
34 #include "sdlscreen.h"
35 #include "util.h"
36 
37 extern SDL_Surface *screen_surface;
38 
39 extern int screen_width;
40 extern int screen_height;
41 extern int screen_fullscreen;
42 
43 extern int options_sdl_width;
44 extern int options_sdl_height;
45 extern int options_sdl_fullscreen;
46 extern int options_sdl_size_x;
47 extern int options_sdl_size_y;
48 extern int options_sdl_delay;
49 extern int options_sdl_player_delay;
50 extern int options_sdl_replay_delay;
51 extern int options_sdl_undo_delay;
52 extern int options_sdl_mouse;
53 extern int options_graphic_level;
54 extern int options_debug;
55 extern char options_graphics[];
56 extern char options_colours[];
57 
58 extern char *piece_name[];
59 
60 extern int move_x[];
61 extern int move_y[];
62 
63 extern int display_offset_x;
64 extern int display_offset_y;
65 extern int display_offset_pixels_x;
66 extern int display_offset_pixels_y;
67 extern int display_start_x;
68 extern int display_start_y;
69 extern int display_end_x;
70 extern int display_end_y;
71 extern int display_pieces_x;
72 extern int display_pieces_y;
73 extern int display_focus_x;
74 extern int display_focus_y;
75 extern int display_bar_pixels;
76 extern int display_border_x;
77 extern int display_border_y;
78 
79 extern float display_animation;
80 extern int display_animation_x;
81 extern int display_animation_y;
82 
83 extern struct graphics* pdisplaygraphics;
84 
85 void display_clip(struct level* plevel, int clip);
86 int display_bevelsquare(struct level* plevel, int x, int y);
87 
88 void displayshadowed_level(struct level* plevel);
89 void displayshadowed_movers(struct level* plevel, int redraw);
90 
displayshadowed_piece(struct level * plevel,int p,int x,int y,int d)91 static inline void displayshadowed_piece(struct level* plevel, int p, int x, int y, int d)
92 {
93     SDL_Surface *pimage;
94 
95     SDL_Rect srect;
96     SDL_Rect drect;
97     int px, py;
98     int alpha = 0;
99     int bimage[4];
100     int b;
101     int bsizex, bsizey;
102     int boffset = 0;
103     int i;
104     int xend;
105 
106 #ifdef XOR_COMPATIBILITY
107     if(p == PIECE_WALL && plevel->switched)
108         return;
109 #endif
110 
111     px = x * pdisplaygraphics->size_x + display_offset_pixels_x;
112     py = y * pdisplaygraphics->size_y + display_offset_pixels_y;
113 
114     if(d != MOVE_NONE)
115     {
116         px += move_x[d] * display_animation_x;
117         py += move_y[d] * display_animation_y;
118     }
119 
120     if(isexplosion(p))
121         alpha = 255 * (1 - display_animation);
122     if(isnewexplosion(p))
123     {
124         alpha = 255 * display_animation;
125         p += PIECE_EXPLOSION_FIRST - PIECE_EXPLOSION_NEW_FIRST;
126     }
127 
128     pimage = pdisplaygraphics->image[p][IMAGE_PIECE];
129 
130     if(isexplosion(p))
131         SDL_SetAlpha(pimage, SDL_SRCALPHA, alpha);
132 
133     srect.x = 0;
134     srect.y = 0;
135     srect.w = pdisplaygraphics->size_x;
136     srect.h = pdisplaygraphics->size_y;
137 
138     drect.x = px;
139     drect.y = py;
140     drect.w = pdisplaygraphics->size_x;
141     drect.h = pdisplaygraphics->size_y;
142 
143     if(pimage->w > pdisplaygraphics->size_x)
144     {
145         if(p == PIECE_PLAYER_ONE || p == PIECE_PLAYER_TWO)
146         {
147             if(plevel->player != (p & 1) && plevel->player != 2)
148                 srect.x = pdisplaygraphics->size_x;
149         }
150         /* Is the piece tiled? */
151         if(pdisplaygraphics->image_flags[p] & GRAPHICS_TILE)
152         {
153             xend = pimage->w / pdisplaygraphics->size_x;
154             if(pdisplaygraphics->image_flags[p] & GRAPHICS_BEVEL)
155                 xend -= 4;
156 
157             b = x % xend;
158             if(b < 0)
159                 b += xend;
160             srect.x += pdisplaygraphics->size_x * b;
161 
162             b = y % (pimage->h / pdisplaygraphics->size_y);
163             if(b < 0)
164                 b += pimage->h / pdisplaygraphics->size_y;
165             srect.y += pdisplaygraphics->size_y * b;
166         }
167     }
168 
169     /* Plot piece */
170     SDL_BlitSurface(pimage, &srect, screen_surface, &drect);
171 
172     /* Plot bevelling */
173     if(pdisplaygraphics->image_flags[p] & GRAPHICS_BEVEL)
174     {
175         xend = pimage->w / pdisplaygraphics->size_x;
176         xend -=4;
177 
178         b = level_data(plevel, x, y) & BEVEL_ALL;
179         if(b != 0)
180         {
181             bsizex = pdisplaygraphics->size_x / 2;
182             bsizey = pdisplaygraphics->size_y / 2;
183             boffset = (xend - 1) * pdisplaygraphics->size_x;
184 
185             for(i = 0; i < 4; i ++)
186                 bimage[i] = 0;
187 
188             if(b & BEVEL_L)
189             {
190                 if(b & BEVEL_U)
191                     bimage[0] = 3 * pdisplaygraphics->size_x;
192                 else
193                     bimage[0] = 1 * pdisplaygraphics->size_x;
194 
195                 if(b & BEVEL_D)
196                     bimage[2] = 3 * pdisplaygraphics->size_x;
197                 else
198                     bimage[2] = 1 * pdisplaygraphics->size_x;
199             }
200             else
201             {
202                 if(b & BEVEL_U)
203                     bimage[0] = 2 * pdisplaygraphics->size_x;
204                 if(b & BEVEL_D)
205                     bimage[2] = 2 * pdisplaygraphics->size_x;
206             }
207 
208             if(b & BEVEL_R)
209             {
210                 if(b & BEVEL_U)
211                     bimage[1] = 3 * pdisplaygraphics->size_x;
212                 else
213                     bimage[1] = 1 * pdisplaygraphics->size_x;
214 
215                 if(b & BEVEL_D)
216                     bimage[3] = 3 * pdisplaygraphics->size_x;
217                 else
218                     bimage[3] = 1 * pdisplaygraphics->size_x;
219             }
220             else
221             {
222                 if(b & BEVEL_U)
223                     bimage[1] = 2 * pdisplaygraphics->size_x;
224                 if(b & BEVEL_D)
225                     bimage[3] = 2 * pdisplaygraphics->size_x;
226             }
227 
228             if(b & BEVEL_TL)
229                 bimage[0] = 4 * pdisplaygraphics->size_x;
230             if(b & BEVEL_TR)
231                 bimage[1] = 4 * pdisplaygraphics->size_x;
232             if(b & BEVEL_BL)
233                 bimage[2] = 4 * pdisplaygraphics->size_x;
234             if(b & BEVEL_BR)
235                 bimage[3] = 4 * pdisplaygraphics->size_x;
236 
237             for(i = 0; i < 4; i ++)
238             {
239                 if(bimage[i] != 0)
240                 {
241                     srect.x = boffset + bimage[i] + ((i & 1) ? bsizex : 0);
242                     srect.y = (i & 2) ? bsizey : 0;
243                     srect.w = bsizex;
244                     srect.h = bsizey;
245 
246                     drect.x = px + ((i & 1) ? bsizex : 0);
247                     drect.y = py + ((i & 2) ? bsizey : 0);
248                     drect.w = bsizex;
249                     drect.h = bsizey;
250 
251                     SDL_BlitSurface(pimage, &srect, screen_surface, &drect);
252                 }
253             }
254         }
255     }
256 }
257 
displayshadowed_pieceshadow(struct level * plevel,int p,int x,int y,int d)258 static inline void displayshadowed_pieceshadow(struct level* plevel, int p, int x, int y, int d)
259 {
260     SDL_Surface *pimage;
261 
262     SDL_Rect srect;
263     SDL_Rect drect;
264     int px, py;
265     int alpha = 0;
266 
267     if(isexplosion(p))
268         alpha = 255 * (1 - display_animation);
269     if(isnewexplosion(p))
270     {
271         alpha = 255 * display_animation;
272         p += PIECE_EXPLOSION_FIRST - PIECE_EXPLOSION_NEW_FIRST;
273     }
274 
275     pimage = pdisplaygraphics->image[p][IMAGE_SHADOW];
276     if(pimage == NULL)
277         return;
278 
279     if(isexplosion(p))
280         SDL_SetAlpha(pimage, SDL_SRCALPHA, alpha);
281 
282     px = x * pdisplaygraphics->size_x + display_offset_pixels_x;
283     py = y * pdisplaygraphics->size_y + display_offset_pixels_y;
284     if(d != MOVE_NONE)
285     {
286         px += move_x[d] * display_animation_x;
287         py += move_y[d] * display_animation_y;
288     }
289 
290     srect.x = 0;
291     srect.y = 0;
292     srect.w = pdisplaygraphics->shadow_width[p][9];
293     srect.h = pdisplaygraphics->shadow_height[p][9];
294 
295     drect.x = px + pdisplaygraphics->shadow_offset_x[p][9];
296     drect.y = py + pdisplaygraphics->shadow_offset_y[p][9];
297     drect.w = srect.w ;
298     drect.h = srect.h;
299 
300     if(pimage->w > pdisplaygraphics->shadow_width[p][9])
301     {
302         if(p == PIECE_PLAYER_ONE || p == PIECE_PLAYER_TWO)
303         {
304             if(plevel->player != (p & 1) && plevel->player != 2)
305                 srect.x = pdisplaygraphics->shadow_width[p][9];
306         }
307     }
308 
309     /* Plot piece */
310     SDL_BlitSurface(pimage, &srect, screen_surface, &drect);
311 }
312 
displayshadowed_piecebase(struct level * plevel,int x,int y)313 static inline void displayshadowed_piecebase(struct level* plevel, int x, int y)
314 {
315     int p;
316     SDL_Surface *pimage;
317     struct shadow *pshadow;
318     struct shadow *pshadowstart;
319     struct shadow *pshadowtmp;
320     struct shadow *pshadowlast;
321     int px, py;
322     int z;
323     int ok;
324     int b, bp;
325     int xend;
326 
327     SDL_Rect srect;
328     SDL_Rect drect;
329     SDL_Rect bsrect, bdrect;
330     int alpha;
331 
332     p = level_piece(plevel, x, y);
333 
334     if(level_moving(plevel, x, y) != MOVE_NONE)
335     {
336         if(display_animation >= 1)
337             p = PIECE_SPACE;
338         else
339             p = level_previous(plevel, x, y);
340     }
341 
342 #ifdef XOR_COMPATIBILITY
343     if(plevel->switched && (p == PIECE_WALL || p == PIECE_SPACE))
344         p = PIECE_DARKNESS;
345 #endif
346 
347     /* If the piece isn't transparent, nothing needs to be plotted */
348     if(p != PIECE_SPACE
349 #ifdef XOR_COMPATIBILITY
350             &&  p != PIECE_DARKNESS
351 #endif
352             && !(pdisplaygraphics->image[p][IMAGE_PIECE]->flags & SDL_SRCALPHA))
353         return;
354 
355 #ifdef XOR_COMPATIBILITY
356     if(plevel->switched)
357         bp = PIECE_DARKNESS;
358     else
359 #endif
360         bp = PIECE_SPACE;
361 
362     pimage = pdisplaygraphics->image[bp][IMAGE_PIECE];
363 
364     px = x * pdisplaygraphics->size_x + display_offset_pixels_x;
365     py = y * pdisplaygraphics->size_y + display_offset_pixels_y;
366 
367     srect.x = 0;
368     srect.y = 0;
369     srect.w = pdisplaygraphics->size_x;
370     srect.h = pdisplaygraphics->size_y;
371 
372     drect.x = px;
373     drect.y = py;
374     drect.w = pdisplaygraphics->size_x;
375     drect.h = pdisplaygraphics->size_y;
376 
377     /* Is the base tiled? */
378     if(pdisplaygraphics->image_flags[bp] & GRAPHICS_TILE)
379     {
380         xend = pimage->w / pdisplaygraphics->size_x;
381         if(pdisplaygraphics->image_flags[bp] & GRAPHICS_BEVEL)
382             xend -= 4;
383         srect.x += pdisplaygraphics->size_x * (x % xend);
384         srect.y += pdisplaygraphics->size_y * (y % (pimage->h / pdisplaygraphics->size_y));
385     }
386 
387     /* Plot the base */
388     SDL_BlitSurface(pimage, &srect, screen_surface, &drect);
389 
390     /* Do we need to order the shadows prior to plotting? */
391     if(pdisplaygraphics->flags & GRAPHICS_ZORDER)
392     {
393         pshadowstart = NULL;
394         pshadowlast = NULL;
395 
396         pshadow = pdisplaygraphics->shadows;
397         while(pshadow != NULL)
398         {
399             /* Determine which piece to consider the shadow of */
400             p = level_piece(plevel, x - pshadow->x, y - pshadow->y);
401             if(level_moving(plevel, x - pshadow->x, y - pshadow->y) != MOVE_NONE)
402             {
403                 if(display_animation >= 1)
404                     p = PIECE_SPACE;
405                 else
406                 {
407                     if(level_previousmoving(plevel, x - pshadow->x, y - pshadow->y) == MOVE_NONE)
408                         p = level_previous(plevel, x - pshadow->x, y - pshadow->y);
409                     else
410                         p = PIECE_SPACE;
411                 }
412             }
413 #ifdef XOR_COMPATIBILITY
414             if(p == PIECE_WALL && plevel->switched)
415                 p = PIECE_DARKNESS;
416 #endif
417             /* Does it have a shadow? */
418             if(pdisplaygraphics->image[p][IMAGE_SHADOW] != NULL && (pdisplaygraphics->shadow_flags[p] & pshadow->flag))
419             {
420                 z = pdisplaygraphics->shadow_z[p];
421                 pshadow->z = pdisplaygraphics->shadow_z[p];
422                 pshadow->p = p;
423 
424                 /* Put it in the ordered list */
425                 pshadowtmp = pshadowstart;
426                 while(pshadowtmp != NULL)
427                 {
428                     if(pshadowtmp->z > z)
429                         break;
430 
431                     pshadowtmp = pshadowtmp->nextordered;
432                 }
433                 if(pshadowstart == NULL)
434                     pshadowstart = pshadow;
435 
436                 /* It goes on the end of the list */
437                 if(pshadowtmp == NULL)
438                 {
439                     pshadow->nextordered = NULL;
440                     pshadow->previousordered = pshadowlast;
441                     if(pshadowlast != NULL)
442                         pshadowlast->nextordered = pshadow;
443                     pshadowlast = pshadow;
444                 }
445                 /* It goes before pshadowtmp */
446                 else
447                 {
448                     pshadow->nextordered = pshadowtmp;
449                     pshadow->previousordered = pshadowtmp->previousordered;
450                     if(pshadowtmp->previousordered != NULL)
451                         pshadowtmp->previousordered->nextordered = pshadow;
452                     else
453                         pshadowstart = pshadow;
454                     pshadowtmp->previousordered = pshadow;
455                 }
456             }
457             pshadow = pshadow->next;
458         }
459     }
460 
461     /* Plot shadows in order */
462     if(pdisplaygraphics->flags & GRAPHICS_ZORDER)
463         pshadow = pshadowstart;
464     else
465         pshadow = pdisplaygraphics->shadows;
466 
467     while(pshadow != NULL)
468     {
469         /* Determine which piece to consider the shadow of */
470         p = level_piece(plevel, x - pshadow->x, y - pshadow->y);
471         if(level_moving(plevel, x - pshadow->x, y - pshadow->y) != MOVE_NONE)
472         {
473             if(display_animation >= 1)
474                 p = PIECE_SPACE;
475             else
476             {
477                 if(level_previousmoving(plevel, x - pshadow->x, y - pshadow->y) == MOVE_NONE)
478                     p = level_previous(plevel, x - pshadow->x, y - pshadow->y);
479                 else
480                     p = PIECE_SPACE;
481             }
482         }
483         /* Does it have a shadow? */
484         if(pdisplaygraphics->image[p][IMAGE_SHADOW] != NULL && (pdisplaygraphics->shadow_flags[p] & pshadow->flag))
485         {
486             pimage = pdisplaygraphics->image[p][IMAGE_SHADOW];
487 
488             if(isexplosion(p))
489             {
490                 alpha = 255 * (1 - display_animation);
491                 SDL_SetAlpha(pdisplaygraphics->image[p][IMAGE_SHADOW], SDL_SRCALPHA, alpha);
492             }
493             if(isnewexplosion(p))
494             {
495                 p += PIECE_EXPLOSION_FIRST - PIECE_EXPLOSION_NEW_FIRST;
496                 alpha = 255 * display_animation;
497                 SDL_SetAlpha(pdisplaygraphics->image[p][IMAGE_SHADOW], SDL_SRCALPHA, alpha);
498             }
499 
500             srect.x = pdisplaygraphics->shadow_start_x[p][pshadow->shadow];
501             srect.y = pdisplaygraphics->shadow_start_y[p][pshadow->shadow];
502             srect.w = pdisplaygraphics->shadow_width[p][pshadow->shadow];
503             srect.h = pdisplaygraphics->shadow_height[p][pshadow->shadow];
504 
505             drect.x = px + pdisplaygraphics->shadow_offset_x[p][pshadow->shadow];
506             drect.y = py + pdisplaygraphics->shadow_offset_y[p][pshadow->shadow];
507             drect.w = pdisplaygraphics->shadow_width[p][pshadow->shadow];
508             drect.h = pdisplaygraphics->shadow_height[p][pshadow->shadow];
509 
510             /* Are there multiple images? */
511             if(pimage->w > pdisplaygraphics->shadow_width[p][9])
512             {
513                 /* Choose swapped player if necessary */
514                 if(p == PIECE_PLAYER_ONE || p == PIECE_PLAYER_TWO)
515                 {
516                     if(plevel->player != (p & 1) && plevel->player != 2)
517                         srect.x += pdisplaygraphics->shadow_width[p][9];
518                 }
519             }
520 
521             /* Plot shadow */
522             SDL_BlitSurface(pimage, &srect, screen_surface, &drect);
523 
524             /* Bevel shadow */
525             if(pdisplaygraphics->image_flags[p] & GRAPHICS_BEVEL_SHADOW)
526             {
527                     b = level_data(plevel, x - pshadow->x, y - pshadow->y) & BEVEL_ALL;
528                     /* Top left quadrant */
529                     if(b & (BEVEL_L | BEVEL_U | BEVEL_TL))
530                     {
531                         bsrect.x = 0;
532                         bsrect.y = 0;
533                         bsrect.w = pdisplaygraphics->shadow_width[p][9] / 2;
534                         bsrect.h = pdisplaygraphics->shadow_height[p][9] / 2;
535                         bdrect.x = drect.x;
536                         bdrect.y = drect.y;
537 
538                         ok = 1;
539                         if(bsrect.x < srect.x)
540                         {
541                             if(bsrect.w > (srect.x - bsrect.x))
542                             {
543                                 bsrect.w -= (srect.x - bsrect.x);
544                                 bdrect.x -= bsrect.x;
545                                 bsrect.x = srect.x;
546                             }
547                             else
548                                 ok = 0;
549                         }
550                         if(bsrect.y < srect.y)
551                         {
552                             if(bsrect.h > (srect.y - bsrect.y))
553                             {
554                                 bsrect.h -= (srect.y - bsrect.y);
555                                 bdrect.y -= bsrect.y;
556                                 bsrect.y = srect.y;
557                             }
558                             else
559                                 ok = 0;
560                         }
561                         if(bdrect.x + bsrect.w > drect.x + drect.w)
562                         {
563                             if(bsrect.w > ((bdrect.x + bsrect.w) - (drect.x + drect.w)))
564                                 bsrect.w -= ((bdrect.x + bsrect.w) - (drect.x + drect.w));
565                             else
566                                 ok = 0;
567                         }
568                         if(bdrect.y + bsrect.h > drect.y + drect.h)
569                         {
570                             if(bsrect.h > ((bdrect.y + bsrect.h) - (drect.y + drect.h)))
571                                 bsrect.h -= ((bdrect.y + bsrect.h) - (drect.y + drect.h));
572                             else
573                                 ok = 0;
574                         }
575                         if(b & BEVEL_TL)
576                             bsrect.x += pdisplaygraphics->shadow_width[p][9] * 4;
577                         else
578                         {
579                             if(b & BEVEL_U)
580                                 bsrect.x += pdisplaygraphics->shadow_width[p][9] * 2;
581                             if(b & BEVEL_L)
582                                 bsrect.x += pdisplaygraphics->shadow_width[p][9];
583                         }
584 
585                         if(ok)
586                             SDL_BlitSurface(pimage, &bsrect, screen_surface, &bdrect);
587                     }
588 
589                     /* Top right quadrant */
590                     if(b & (BEVEL_R | BEVEL_U | BEVEL_TR))
591                     {
592                         bsrect.x = pdisplaygraphics->shadow_width[p][9] / 2;
593                         bsrect.y = 0;
594                         bsrect.w = pdisplaygraphics->shadow_width[p][9] / 2;
595                         bsrect.h = pdisplaygraphics->shadow_height[p][9] / 2;
596                         bdrect.x = drect.x + pdisplaygraphics->size_x / 2;
597                         bdrect.y = drect.y;
598 
599                         ok = 1;
600                         if(bsrect.x < srect.x)
601                         {
602                             if(bsrect.w > (srect.x - bsrect.x))
603                             {
604                                 bsrect.w -= (srect.x - bsrect.x);
605                                 bdrect.x -= bsrect.x;
606                                 bsrect.x = srect.x;
607                             }
608                             else
609                                 ok = 0;
610                         }
611                         if(bsrect.y < srect.y)
612                         {
613                             if(bsrect.h > (srect.y - bsrect.y))
614                             {
615                                 bsrect.h -= (srect.y - bsrect.y);
616                                 bdrect.y -= bsrect.y;
617                                 bsrect.y = srect.y;
618                             }
619                             else
620                                 ok = 0;
621                         }
622                         if(bdrect.x + bsrect.w > drect.x + drect.w)
623                         {
624                             if(bsrect.w > ((bdrect.x + bsrect.w) - (drect.x + drect.w)))
625                                 bsrect.w -= ((bdrect.x + bsrect.w) - (drect.x + drect.w));
626                             else
627                                 ok = 0;
628                         }
629                         if(bdrect.y + bsrect.h > drect.y + drect.h)
630                         {
631                             if(bsrect.h > ((bdrect.y + bsrect.h) - (drect.y + drect.h)))
632                                 bsrect.h -= ((bdrect.y + bsrect.h) - (drect.y + drect.h));
633                             else
634                                 ok = 0;
635                         }
636                         if(b & BEVEL_TR)
637                             bsrect.x += pdisplaygraphics->shadow_width[p][9] * 4;
638                         else
639                         {
640                             if(b & BEVEL_U)
641                                 bsrect.x += pdisplaygraphics->shadow_width[p][9] * 2;
642                             if(b & BEVEL_R)
643                                 bsrect.x += pdisplaygraphics->shadow_width[p][9];
644                         }
645                         if(ok)
646                             SDL_BlitSurface(pimage, &bsrect, screen_surface, &bdrect);
647                     }
648 
649                     /* Bottom left quadrant */
650                     if(b & (BEVEL_L | BEVEL_D | BEVEL_BL))
651                     {
652                         bsrect.x = 0;
653                         bsrect.y = pdisplaygraphics->shadow_height[p][9] / 2;;
654                         bsrect.w = pdisplaygraphics->shadow_width[p][9] / 2;
655                         bsrect.h = pdisplaygraphics->shadow_height[p][9] / 2;
656                         bdrect.x = drect.x;
657                         bdrect.y = drect.y + pdisplaygraphics->size_y / 2;
658 
659                         ok = 1;
660                         if(bsrect.x < srect.x)
661                         {
662                             if(bsrect.w > (srect.x - bsrect.x))
663                             {
664                                 bsrect.w -= (srect.x - bsrect.x);
665                                 bdrect.x -= bsrect.x;
666                                 bsrect.x = srect.x;
667                             }
668                             else
669                                 ok = 0;
670                         }
671                         if(bsrect.y < srect.y)
672                         {
673                             if(bsrect.h > (srect.y - bsrect.y))
674                             {
675                                 bsrect.h -= (srect.y - bsrect.y);
676                                 bdrect.y -= bsrect.y;
677                                 bsrect.y = srect.y;
678                             }
679                             else
680                                 ok = 0;
681                         }
682                         if(bdrect.x + bsrect.w > drect.x + drect.w)
683                         {
684                             if(bsrect.w > ((bdrect.x + bsrect.w) - (drect.x + drect.w)))
685                                 bsrect.w -= ((bdrect.x + bsrect.w) - (drect.x + drect.w));
686                             else
687                                 ok = 0;
688                         }
689                         if(bdrect.y + bsrect.h > drect.y + drect.h)
690                         {
691                             if(bsrect.h > ((bdrect.y + bsrect.h) - (drect.y + drect.h)))
692                                 bsrect.h -= ((bdrect.y + bsrect.h) - (drect.y + drect.h));
693                             else
694                                 ok = 0;
695                         }
696                         if(b & BEVEL_BL)
697                             bsrect.x += pdisplaygraphics->shadow_width[p][9] * 4;
698                         else
699                         {
700                             if(b & BEVEL_D)
701                                 bsrect.x += pdisplaygraphics->shadow_width[p][9] * 2;
702                             if(b & BEVEL_L)
703                                 bsrect.x += pdisplaygraphics->shadow_width[p][9];
704                         }
705                         if(ok)
706                             SDL_BlitSurface(pimage, &bsrect, screen_surface, &bdrect);
707                     }
708 
709                     /* Bottom right quadrant */
710                     if(b & (BEVEL_R | BEVEL_D | BEVEL_BR))
711                     {
712                         bsrect.x = pdisplaygraphics->shadow_width[p][9] / 2;
713                         bsrect.y = pdisplaygraphics->shadow_height[p][9] / 2;
714                         bsrect.w = pdisplaygraphics->shadow_width[p][9] / 2;
715                         bsrect.h = pdisplaygraphics->shadow_height[p][9] / 2;
716                         bdrect.x = drect.x + pdisplaygraphics->size_x / 2;
717                         bdrect.y = drect.y + pdisplaygraphics->size_y / 2;
718 
719                         ok = 1;
720                         if(bsrect.x < srect.x)
721                         {
722                             if(bsrect.w > (srect.x - bsrect.x))
723                             {
724                                 bsrect.w -= (srect.x - bsrect.x);
725                                 bdrect.x -= bsrect.x;
726                                 bsrect.x = srect.x;
727                             }
728                             else
729                                 ok = 0;
730                         }
731                         if(bsrect.y < srect.y)
732                         {
733                             if(bsrect.h > (srect.y - bsrect.y))
734                             {
735                                 bsrect.h -= (srect.y - bsrect.y);
736                                 bdrect.y -= bsrect.y;
737                                 bsrect.y = srect.y;
738                             }
739                             else
740                                 ok = 0;
741                         }
742                         if(bdrect.x + bsrect.w > drect.x + drect.w)
743                         {
744                             if(bsrect.w > ((bdrect.x + bsrect.w) - (drect.x + drect.w)))
745                                 bsrect.w -= ((bdrect.x + bsrect.w) - (drect.x + drect.w));
746                             else
747                                 ok = 0;
748                         }
749                         if(bdrect.y + bsrect.h > drect.y + drect.h)
750                         {
751                             if(bsrect.h > ((bdrect.y + bsrect.h) - (drect.y + drect.h)))
752                                 bsrect.h -= ((bdrect.y + bsrect.h) - (drect.y + drect.h));
753                             else
754                                 ok = 0;
755                         }
756                         if(b & BEVEL_BR)
757                             bsrect.x += pdisplaygraphics->shadow_width[p][9] * 4;
758                         else
759                         {
760                             if(b & BEVEL_D)
761                                 bsrect.x += pdisplaygraphics->shadow_width[p][9] * 2;
762                             if(b & BEVEL_R)
763                                 bsrect.x += pdisplaygraphics->shadow_width[p][9];
764                         }
765                         if(ok)
766                             SDL_BlitSurface(pimage, &bsrect, screen_surface, &bdrect);
767                 }
768             }
769 
770         }
771 
772         if(pdisplaygraphics->flags & GRAPHICS_ZORDER)
773             pshadow = pshadow->nextordered;
774         else
775             pshadow = pshadow->next;
776     }
777 }
778 
displayshadowed_redrawpiece(int p,int x,int y,int d)779 static inline void displayshadowed_redrawpiece(int p, int x, int y, int d)
780 {
781     int dx, dy;
782 
783     dx = x * pdisplaygraphics->size_x + display_offset_pixels_x;
784     dy = y * pdisplaygraphics->size_y + display_offset_pixels_y;
785 
786     if(d != MOVE_NONE && p != PIECE_SPACE && !isexplosion(p))
787     {
788         if(d == MOVE_LEFT) { dx = dx - display_animation_x; }
789         if(d == MOVE_RIGHT) { dx = dx + display_animation_x; }
790         if(d == MOVE_UP) { dy = dy - display_animation_y; }
791         if(d == MOVE_DOWN) { dy = dy + display_animation_y; }
792     }
793 
794     screen_redraw(dx, dy, pdisplaygraphics->size_x, pdisplaygraphics->size_y);
795 }
796 
displayshadowed_level(struct level * plevel)797 void displayshadowed_level(struct level* plevel)
798 {
799     int x, y;
800     int p;
801 
802     display_clip(plevel, 1);
803 
804     /* Plot base */
805     for(y = display_start_y; y < display_end_y; y ++)
806     {
807         for(x = display_start_x; x < display_end_x; x ++)
808         {
809             displayshadowed_piecebase(plevel, x, y);
810 
811             p = level_piece(plevel, x, y);
812 
813             /* Plot the piece itself */
814             if(p != PIECE_SPACE)
815                  displayshadowed_piece(plevel, p, x, y, MOVE_NONE);
816         }
817     }
818 
819     if(plevel->mover_first != NULL)
820         displayshadowed_movers(plevel, 0);
821 
822     display_clip(plevel, 0);
823 
824     screen_redraw(0, 0, screen_width, screen_height);
825 }
826 
displayshadowed_count(struct level * plevel,int x,int y,int delta)827 static inline int displayshadowed_count(struct level* plevel, int x, int y, int delta)
828 {
829     unsigned int d;
830 
831     d = level_data(plevel, x, y);
832     level_setdata(plevel, x, y, d + (delta * SHADOW_BASE));
833 
834     return d & (0x7f * SHADOW_BASE);
835 }
836 
837 
displayshadowed_movers(struct level * plevel,int redraw)838 void displayshadowed_movers(struct level* plevel, int redraw)
839 {
840     struct shadow* pshadow;
841     struct mover* pmover;
842     int x, y, p, pm;
843     int i, j;
844     char buffer[16];
845     int d;
846     int bevel;
847     int bevelold;
848     SDL_Surface *psurface;
849     SDL_Rect srect, drect;
850 
851     p = PIECE_SPACE;
852 
853     display_animation_x = - pdisplaygraphics->size_x + (int)((float) pdisplaygraphics->size_x * display_animation);
854     display_animation_y = - pdisplaygraphics->size_y + (int)((float) pdisplaygraphics->size_y * display_animation);
855 
856     display_clip(plevel, 1);
857 
858     /* Stage one: plot base for pieces that need rebevelling */
859     if(display_animation == 0 || display_animation == 1)
860     {
861         /* When undoing, we have to create the wall prior to rebevelling, as it
862            wouldn't otherwise exist until after the end of the animation. */
863         pmover = plevel->mover_first;
864         while(pmover != NULL)
865         {
866             if(pmover->piece == PIECE_WALL)
867                 level_setpiece(plevel, pmover->x, pmover->y, pmover->piece);
868             pmover = pmover->next;
869         }
870 
871         pmover = plevel->mover_first;
872         while(pmover != NULL)
873         {
874             x = pmover->x;
875             y = pmover->y;
876             if(pmover->piece == PIECE_WALL ||
877                 (isexplosion(pmover->piece) && display_animation == 1))
878             {
879                 pshadow = pdisplaygraphics->shadows;
880                 while(pshadow != NULL)
881                 {
882                     bevel = display_bevelsquare(plevel, x + pshadow->x, y + pshadow->y);
883                     bevelold = (level_data(plevel, x + pshadow->x, y + pshadow->y) & BEVEL_ALL);
884                     /* Because this happens only once per move cycle, we
885                        are lazy and don't bother to count whether this base
886                        has already been plotted */
887                     if(bevel != bevelold);
888                         displayshadowed_piecebase(plevel, pmover->x + pshadow->x, pmover->y + pshadow->y);
889                     pshadow = pshadow->next;
890                 }
891             }
892             pmover = pmover->next;
893         }
894     }
895 
896     /* Stage two: plot shadows for stationary squares affected by movers */
897     pmover = plevel->mover_first;
898     while(pmover != NULL)
899     {
900         if(pmover->piece != PIECE_GONE)
901         {
902             /* This is overkill, but it's easier just to plot everything that
903                could be affected than to calculate what is actually affected.
904                */
905             pshadow = pdisplaygraphics->shadows;
906             while(pshadow != NULL)
907             {
908                 if(displayshadowed_count(plevel, pmover->x + pshadow->x, pmover->y + pshadow->y, 1) == 0)
909                     displayshadowed_piecebase(plevel, pmover->x + pshadow->x, pmover->y + pshadow->y);
910                 pshadow = pshadow->next;
911             }
912             if(displayshadowed_count(plevel, pmover->x, pmover->y, 1) == 0)
913                 displayshadowed_piecebase(plevel, pmover->x, pmover->y);
914         }
915 
916         pmover = pmover->next;
917     }
918     /* then reset the counts */
919     pmover = plevel->mover_first;
920     while(pmover != NULL)
921     {
922         if(pmover->piece != PIECE_GONE)
923         {
924             pshadow = pdisplaygraphics->shadows;
925             while(pshadow != NULL)
926             {
927                 displayshadowed_count(plevel, pmover->x + pshadow->x, pmover->y + pshadow->y, -1);
928                 pshadow = pshadow->next;
929             }
930             displayshadowed_count(plevel, pmover->x, pmover->y, -1);
931         }
932 
933         pmover = pmover->next;
934     }
935 
936     /* Stage three: plot shadows for movers */
937     pmover = plevel->mover_first;
938     while(pmover != NULL)
939     {
940         d = pmover->direction;
941         x = pmover->x;
942         y = pmover->y;
943 
944         if(isexplosion(pmover->piece))
945         {
946             /* If the previous piece, that is, the piece destroyed in the
947                explosion, is stationary, we don't need to plot a shadow for it,
948                as that is handled in stage one. If it is moving, however, it
949                needs a moving shadow, which we do have to plot here. */
950             p = level_previous(plevel, x, y);
951             pm = level_previousmoving(plevel, x, y);
952             if(p != PIECE_SPACE && pm != MOVE_NONE)
953                 displayshadowed_pieceshadow(plevel, p, x, y, pm);
954 
955             /* Plot shadow for the detonator */
956             p = level_detonator(plevel, x, y);
957             pm = level_detonatormoving(plevel, x, y);
958             if(p != PIECE_SPACE)
959                 displayshadowed_pieceshadow(plevel, p, x, y, pm);
960 
961         }
962         /* Spaces and walls were handled in stage one */
963         else if(pmover->piece != PIECE_SPACE && pmover->piece != PIECE_WALL && pmover->piece != PIECE_GONE)
964         {
965             /* We don't need to plot the shadow for the previous piece
966                as that is handled in stage one */
967 
968             /* Plot shadow for mover */
969 #ifdef XOR_COMPATIBILITY
970             if(pmover->piece == PIECE_TELEPORT)
971                 d = MOVE_NONE;
972 #endif
973             displayshadowed_pieceshadow(plevel, pmover->piece, pmover->x, pmover->y, d);
974         }
975         pmover = pmover->next;
976     }
977 
978     /* Stage four: plot shadows for explosions */
979     pmover = plevel->mover_first;
980     while(pmover != NULL)
981     {
982         x = pmover->x;
983         y = pmover->y;
984         /* Plot growing explosion */
985         if(isexplosion(pmover->piece))
986             displayshadowed_pieceshadow(plevel, pmover->piece + PIECE_EXPLOSION_NEW_FIRST - PIECE_EXPLOSION_FIRST, x, y, MOVE_NONE);
987 
988         /* Plot dying explosion */
989         p = level_previous(plevel, x, y);
990         if(isexplosion(p) && display_animation < 1)
991             displayshadowed_pieceshadow(plevel, p, x, y, MOVE_NONE);
992 
993         pmover = pmover->next;
994     }
995 
996     /* Stage five: plot pieces for stationary squares affected by movers.
997        We need to be careful not to plot the same piece twice, so we keep
998        count and only plot on the first occurrence. */
999     pmover = plevel->mover_first;
1000     while(pmover != NULL)
1001     {
1002         pshadow = pdisplaygraphics->shadows;
1003         while(pshadow != NULL)
1004         {
1005             if(displayshadowed_count(plevel, pmover->x + pshadow->x, pmover->y + pshadow->y, 1) == 0)
1006             {
1007                 p = level_piece(plevel, pmover->x + pshadow->x, pmover->y + pshadow->y);
1008                 pm = level_moving(plevel, pmover->x + pshadow->x, pmover->y + pshadow->y);
1009                 if(p != PIECE_SPACE && p != PIECE_GONE && pm == MOVE_NONE)
1010                     displayshadowed_piece(plevel, p, pmover->x + pshadow->x, pmover->y + pshadow->y, MOVE_NONE);
1011             }
1012             pshadow = pshadow->next;
1013         }
1014         pmover = pmover->next;
1015     }
1016     /* then reset the counts */
1017     pmover = plevel->mover_first;
1018     while(pmover != NULL)
1019     {
1020        pshadow = pdisplaygraphics->shadows;
1021         while(pshadow != NULL)
1022         {
1023             displayshadowed_count(plevel, pmover->x + pshadow->x, pmover->y + pshadow->y, -1);
1024             pshadow = pshadow->next;
1025         }
1026         pmover = pmover->next;
1027     }
1028 
1029     /* Stage six: plot pieces for movers */
1030     pmover = plevel->mover_first;
1031     while(pmover != NULL)
1032     {
1033         d = pmover->direction;
1034         x = pmover->x;
1035         y = pmover->y;
1036 
1037         if(isexplosion(pmover->piece))
1038         {
1039             /* Plot any piece destroyed by the explosion, or the bomb itself */
1040             p = level_previous(plevel, x, y);
1041             pm = level_previousmoving(plevel, x, y);
1042             if(p != PIECE_SPACE)
1043                 displayshadowed_piece(plevel, p, x, y, pm);
1044 
1045             /* Plot the detonator */
1046             p = level_detonator(plevel, x, y);
1047             pm = level_detonatormoving(plevel, x, y);
1048             if(p != PIECE_SPACE)
1049                 displayshadowed_piece(plevel, p, x, y, pm);
1050 
1051         }
1052         /* Spaces were handled in stage one */
1053         else if(pmover->piece != PIECE_SPACE && pmover->piece != PIECE_GONE)
1054         {
1055             if(display_animation < 1)
1056             {
1057                 /* Pieces being collected, earth being eaten */
1058                 p = level_previous(plevel, x, y);
1059                 pm = level_previousmoving(plevel, x, y);
1060                 if((p != PIECE_SPACE && !isexplosion(p) && pm == MOVE_NONE)
1061 #ifdef XOR_COMPATIBILITY
1062                         || pmover->piece == PIECE_TELEPORT
1063 #endif
1064                   )
1065                     displayshadowed_piece(plevel, p, x, y, pm);
1066             }
1067 
1068             /* Plot the piece itself */
1069 #ifdef XOR_COMPATIBILITY
1070             if(pmover->piece == PIECE_TELEPORT)
1071                 d = MOVE_NONE;
1072 #endif
1073             displayshadowed_piece(plevel, pmover->piece, pmover->x, pmover->y, d);
1074         }
1075         pmover = pmover->next;
1076     }
1077 
1078     /* Stage seven: plot pieces that need rebevelling */
1079     if(display_animation == 0 || display_animation == 1)
1080     {
1081         pmover = plevel->mover_first;
1082         while(pmover != NULL)
1083         {
1084             x = pmover->x;
1085             y = pmover->y;
1086             if(pmover->piece == PIECE_WALL ||
1087                 (isexplosion(pmover->piece) && display_animation == 1))
1088             {
1089                 for(i = -1; i < 2; i ++)
1090                 {
1091                     for(j = - 1; j < 2; j ++)
1092                     {
1093                         bevel = display_bevelsquare(plevel, x + i, y + j);
1094                         bevelold = (level_data(plevel, x + i, y + j) & BEVEL_ALL);
1095                         if(bevel != bevelold);
1096                         {
1097                             /* Here we are not lazy, to avoid issues with
1098                                transparent graphics being plotted twice */
1099                             if(displayshadowed_count(plevel, pmover->x + i, pmover->y + j, 1) == 0)
1100                             {
1101                                 level_setdata(plevel, x + i, y + j, bevel | (level_data(plevel, x + i, y + j) & ~BEVEL_ALL));
1102                                 p = level_piece(plevel, x + i, y + j);
1103                                 if(p == PIECE_WALL)
1104                                     displayshadowed_piece(plevel, p, pmover->x + i, pmover->y + j, MOVE_NONE);
1105                                 level_setdata(plevel, x + i, y + j, bevelold | (level_data(plevel, x + i, y + j) & ~BEVEL_ALL));
1106                             }
1107                         }
1108                     }
1109                 }
1110             }
1111             pmover = pmover->next;
1112         }
1113         /* and reset counts */
1114         pmover = plevel->mover_first;
1115         while(pmover != NULL)
1116         {
1117             x = pmover->x;
1118             y = pmover->y;
1119             if(pmover->piece == PIECE_WALL ||
1120                 (isexplosion(pmover->piece) && display_animation == 1))
1121             {
1122                 for(i = -1; i < 2; i ++)
1123                 {
1124                     for(j = - 1; j < 2; j ++)
1125                     {
1126                         bevel = display_bevelsquare(plevel, x + i, y + j);
1127                         bevelold = (level_data(plevel, x + i, y + j) & BEVEL_ALL);
1128                         if(bevel != bevelold);
1129                             displayshadowed_count(plevel, pmover->x + i, pmover->y + j, -1);
1130                     }
1131                 }
1132             }
1133             pmover = pmover->next;
1134         }
1135     }
1136 
1137     /* Stage eight: plot pieces for explosions */
1138     pmover = plevel->mover_first;
1139     while(pmover != NULL)
1140     {
1141         x = pmover->x;
1142         y = pmover->y;
1143         /* Plot growing explosion */
1144         if(isexplosion(pmover->piece))
1145             displayshadowed_piece(plevel, pmover->piece + PIECE_EXPLOSION_NEW_FIRST - PIECE_EXPLOSION_FIRST, x, y, MOVE_NONE);
1146 
1147         /* Plot dying explosion */
1148         p = level_previous(plevel, x, y);
1149         if(isexplosion(p) && display_animation < 1)
1150             displayshadowed_piece(plevel, p, x, y, MOVE_NONE);
1151 
1152         pmover = pmover->next;
1153     }
1154 
1155     /* Stage nine: plot order of movers if debugging (but not in editor) */
1156     if(options_debug & DEBUG_ORDER && display_animation < 1 && plevel->player != 2)
1157     {
1158         pmover = plevel->mover_first;
1159         i = 0;
1160         while(pmover != NULL)
1161         {
1162             if(pmover->piece != PIECE_SPACE && pmover->piece != PIECE_GONE)
1163             {
1164                 pm = pmover->direction;
1165                 if(isexplosion(pmover->piece) || isnewexplosion(pmover->piece))
1166                     pm = MOVE_NONE;
1167 
1168                 x = pmover->x * pdisplaygraphics->size_x + display_offset_pixels_x + ((-1 + display_animation) * move_x[pm] * pdisplaygraphics->size_x);
1169                 y = pmover->y * pdisplaygraphics->size_y + display_offset_pixels_y + ((-1 + display_animation) * move_y[pm] * pdisplaygraphics->size_y);
1170 
1171                 sprintf(buffer, "%X", i++);
1172                 switch(pmover->direction)
1173                 {
1174                     case MOVE_UP:
1175                         strcat(buffer, ARROW_UP);
1176                         break;
1177                     case MOVE_DOWN:
1178                         strcat(buffer, ARROW_DOWN);
1179                         break;
1180                     case MOVE_LEFT:
1181                         strcat(buffer, ARROW_LEFT);
1182                         break;
1183                     case MOVE_RIGHT:
1184                         strcat(buffer, ARROW_RIGHT);
1185                         break;
1186                     default:
1187                         break;
1188                 }
1189                 psurface = font_render(buffer, COLOUR_WHITE | COLOUR_BOLD);
1190                 srect.w = psurface->w > pdisplaygraphics->size_x ? pdisplaygraphics->size_x : psurface->w;
1191                 srect.h = psurface->h > pdisplaygraphics->size_y ? pdisplaygraphics->size_y : psurface->h;
1192                 srect.x = psurface->w - srect.w;
1193                 srect.y = 0;
1194                 drect.x = x + pdisplaygraphics->size_x - srect.w;
1195                 drect.y = y;
1196                 SDL_BlitSurface(psurface, &srect, screen_surface, &drect);
1197                 SDL_FreeSurface(psurface);
1198             }
1199             pmover = pmover->next;
1200         }
1201     }
1202 
1203     display_clip(plevel, 0);
1204 
1205     if(redraw == 0)
1206         return;
1207 
1208     display_clip(plevel, 1);
1209 
1210     /* Stage ten: redraw modified squares */
1211     pmover = plevel->mover_first;
1212     while(pmover != NULL)
1213     {
1214         if(pmover->piece != PIECE_GONE)
1215         {
1216             pshadow = pdisplaygraphics->shadows;
1217             while(pshadow != NULL)
1218             {
1219                 if(displayshadowed_count(plevel, pmover->x + pshadow->x, pmover->y + pshadow->y, 1) == 0)
1220                     displayshadowed_redrawpiece(level_piece(plevel, pmover->x + pshadow->x, pmover->y + pshadow->y), pmover->x + pshadow->x, pmover->y + pshadow->y, MOVE_NONE);
1221                 pshadow = pshadow->next;
1222             }
1223             if(displayshadowed_count(plevel, pmover->x, pmover->y, 1) == 0)
1224                 displayshadowed_redrawpiece(level_piece(plevel, pmover->x, pmover->y), pmover->x, pmover->y, MOVE_NONE);
1225         }
1226         pmover = pmover->next;
1227     }
1228     /* then reset the counts */
1229     pmover = plevel->mover_first;
1230     while(pmover != NULL)
1231     {
1232         if(pmover->piece != PIECE_GONE)
1233         {
1234             pshadow = pdisplaygraphics->shadows;
1235             while(pshadow != NULL)
1236             {
1237                 displayshadowed_count(plevel, pmover->x + pshadow->x, pmover->y + pshadow->y, -1);
1238                 pshadow = pshadow->next;
1239             }
1240             displayshadowed_count(plevel, pmover->x, pmover->y, -1);
1241         }
1242         pmover = pmover->next;
1243     }
1244 
1245     /* Stage eleven: redraw pieces that need rebevelling */
1246     if(display_animation == 0 || display_animation == 1)
1247     {
1248         pmover = plevel->mover_first;
1249         while(pmover != NULL)
1250         {
1251             x = pmover->x;
1252             y = pmover->y;
1253             if(pmover->piece == PIECE_WALL ||
1254                 (isexplosion(pmover->piece) && display_animation == 1))
1255             {
1256                 for(i = -1; i < 2; i ++)
1257                 {
1258                     for(j = - 1; j < 2; j ++)
1259                     {
1260                         bevel = display_bevelsquare(plevel, x + i, y + j);
1261                         bevelold = (level_data(plevel, x + i, y + j) & BEVEL_ALL);
1262                         if(bevel != bevelold);
1263                         {
1264                             /* Again, we are lazy and do not keep count of
1265                                whether this square has already been redrawn. */
1266                             level_setdata(plevel, x + i, y + j, bevel | (level_data(plevel, x + i, y + j) & ~BEVEL_ALL));
1267                             displayshadowed_redrawpiece(level_piece(plevel, pmover->x + i, pmover->y + j), pmover->x + i, pmover->y + j, MOVE_NONE);
1268                         }
1269                     }
1270                 }
1271             }
1272             pmover = pmover->next;
1273         }
1274     }
1275 
1276     display_clip(plevel, 0);
1277 }
1278