1 /**
2 * @file sprite_object.cc
3 * @brief Draw a sprite on the screen
4 * @date 2014-07-27
5 * @copyright 1991-2014 TLK Games
6 * @author Bruno Ethvignot
7 * @version $Revision: 24 $
8 */
9 /*
10  * copyright (c) 1991-2014 TLK Games all rights reserved
11  * $Id: sprite_object.cc 24 2014-09-28 15:30:04Z bruno.ethvignot@gmail.com $
12  *
13  * TecnoballZ is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 3 of the License, or
16  * (at your option) any later version.
17  *
18  * TecnoballZ is distributed in the hope that it will be useful, but
19  * WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26  * MA  02110-1301, USA.
27  */
28 #include "../include/sprite_object.h"
29 
30 /**
31  * Create a sprite object
32  */
sprite_object()33 sprite_object::sprite_object ()
34 {
35   ombredecax = handler_display::SHADOWOFFX * resolution;
36   ombredecay = handler_display::SHADOWOFFY * resolution;
37   ombrepixel = handler_display::SHADOW_PIX;
38   ombrepixe4 = handler_display::SHADOWLONG;
39   sprite_height = 0;
40   sprite_width = 0;
41   screen_height = 0;
42   screen_width = 0;
43   x_maximum = 0;
44   y_maximum = 0;
45   x_minimum = 0;
46   y_minimum = 0;
47   clear_sprite_members ();
48 }
49 
50 /**
51  * Release a sprite object
52  */
~sprite_object()53 sprite_object::~sprite_object ()
54 {
55   release_sprite ();
56 }
57 
58 /**
59  * Release memory allocated dynamically bu the sprite object
60  */
61 void
release_sprite()62 sprite_object::release_sprite ()
63 {
64   if (has_allocated_memory)
65     {
66       for (Sint32 i = 0; i < max_of_images; i++)
67         {
68           if (drawing_values[i] != NULL)
69             {
70               delete[]drawing_values[i];
71               drawing_values[i] = NULL;
72             }
73           if (drawing_data[i] != NULL)
74             {
75               delete[]drawing_data[i];
76               drawing_data[i] = NULL;
77             }
78           if (is_draw_pixel_by_pixel && drawing_pixels[i] != NULL)
79             {
80               delete[]drawing_pixels[i];
81               drawing_pixels[i] = NULL;
82             }
83         }
84       if (drawing_values != NULL)
85         {
86           delete[]drawing_values;
87           drawing_values = NULL;
88         }
89       if (drawing_data != NULL)
90         {
91           delete[]drawing_data;
92           drawing_data = NULL;
93         }
94       if (is_draw_pixel_by_pixel && drawing_pixels != NULL)
95         {
96           delete[]drawing_pixels;
97           drawing_pixels = NULL;
98         }
99       if (images_pixel_data != NULL)
100         {
101           delete[]images_pixel_data;
102           images_pixel_data = NULL;
103         }
104       if (drawing_peer_line != NULL)
105         {
106           for (Sint32 i = 0; i < max_of_images; i++)
107             {
108               if (drawing_peer_line[i] != NULL)
109                 {
110                   delete[]drawing_peer_line[i];
111                   drawing_peer_line[i] = NULL;
112                 }
113             }
114           delete[]drawing_peer_line;
115           drawing_peer_line = NULL;
116         }
117     }
118   if (is_release_pixel_data && pixel_data != NULL)
119     {
120       delete[]pixel_data;
121       is_release_pixel_data = false;
122       pixel_data = NULL;
123     }
124   object_free ();
125 }
126 
127 /**
128  * Clear some values
129  */
130 void
clear_sprite_members()131 sprite_object::clear_sprite_members ()
132 {
133   object_init ();
134   pixel_data = (char *) NULL;
135   images_pixel_data = (char **) NULL;
136   screen_ptr = (char *) NULL;
137   shadow_screen_ptr = (char *) NULL;
138   frame_delay = 1;
139   max_of_images = 0;
140   frame_index = 0;
141   is_enabled = false;
142   drawing_values = (Sint16 **) NULL;
143   drawing_data = (char **) NULL;
144   drawing_pixels = (Sint16 **) NULL;
145   collision_height = 0;
146   collision_width = 0;
147   frame_period = 1;
148   x_coord = 0;
149   y_coord = 0;
150   display_pos = 0;
151   frame_index_max = 0;
152   frame_index_min = 0;
153   offsetDest = 0;
154   offsetSrce = 0;
155   current_drawing_values = (Sint16 *) NULL;
156   current_drawing_data = (char *) NULL;
157   current_drawing_pixels = NULL;
158   sprite_has_shadow = false;
159   sprite_type_id = 0;
160   row_size = 0;
161   affligFrst = 0;
162   affligLast = 1;
163   is_mirrored_vertically = false;
164   drawing_peer_line = (bb_afligne **) NULL;
165   has_allocated_memory = false;
166   object_pos = -1;
167   num_of_repeats = 0;
168   cycling_index = 0;
169   current_cycling = &cycling_01[0];
170   draw_method = COPY_FROM_BITMAP;
171   is_release_pixel_data = false;
172 }
173 
174 /**
175  * Copy sprite members to anotger sprite
176  * @param bobPt destination sprite object
177  */
178 void
duplicate_to(sprite_object * sprite_dest)179 sprite_object::duplicate_to (sprite_object * sprite_dest)
180 {
181   sprite_dest->pixel_data = pixel_data;
182   sprite_dest->images_pixel_data = images_pixel_data;
183   sprite_dest->screen_ptr = screen_ptr;
184   sprite_dest->shadow_screen_ptr = shadow_screen_ptr;
185   sprite_dest->frame_delay = frame_delay;
186   sprite_dest->max_of_images = max_of_images;
187   sprite_dest->frame_index = frame_index;
188   sprite_dest->is_enabled = is_enabled;
189   sprite_dest->sprite_height = sprite_height;
190   sprite_dest->sprite_width = sprite_width;
191   sprite_dest->drawing_values = drawing_values;
192   sprite_dest->drawing_data = drawing_data;
193   sprite_dest->drawing_pixels = drawing_pixels;
194   sprite_dest->collision_height = collision_height;
195   sprite_dest->collision_width = collision_width;
196   sprite_dest->screen_height = screen_height;
197   sprite_dest->screen_width = screen_width;
198   sprite_dest->frame_period = frame_period;
199   sprite_dest->x_coord = x_coord;
200   sprite_dest->y_coord = y_coord;
201   sprite_dest->display_pos = display_pos;
202   sprite_dest->x_maximum = x_maximum;
203   sprite_dest->y_maximum = y_maximum;
204   sprite_dest->frame_index_max = frame_index_max;
205   sprite_dest->x_minimum = x_minimum;
206   sprite_dest->y_minimum = y_minimum;
207   sprite_dest->frame_index_min = frame_index_min;
208   sprite_dest->offsetSrce = offsetSrce;
209   sprite_dest->offsetDest = offsetDest;
210   sprite_dest->current_drawing_values = current_drawing_values;
211   sprite_dest->current_drawing_data = current_drawing_data;
212   sprite_dest->current_drawing_pixels = current_drawing_pixels;
213   sprite_dest->sprite_has_shadow = sprite_has_shadow;
214   sprite_dest->sprite_type_id = sprite_type_id;
215   sprite_dest->row_size = row_size;
216   sprite_dest->offscreen_pitch = offscreen_pitch;
217   sprite_dest->draw_method = draw_method;
218   sprite_dest->is_draw_pixel_by_pixel = is_draw_pixel_by_pixel;
219   sprite_dest->has_allocated_memory = false;
220 }
221 
222 
223 /**
224  * Enable the sprite
225  */
226 void
enable()227 sprite_object::enable ()
228 {
229   is_enabled = true;
230 }
231 
232 /**
233  * Disable the sprite
234  */
235 void
disable()236 sprite_object::disable ()
237 {
238   is_enabled = false;
239 }
240 
241 /**
242  * Check if the sprite is enable
243  * @return true if the sprite is enable
244  */
is_enable()245 bool sprite_object::is_enable ()
246 {
247   return is_enabled;
248 }
249 
250 /**
251  * Return the sprite identifier
252  * @return indentifier of sprite, identify the type of the sprite
253  */
254 Uint32
get_sprite_type_id()255 sprite_object::get_sprite_type_id ()
256 {
257   return sprite_type_id;
258 }
259 
260 /**
261  * Set a number sprite (normally the number of position in list)
262  */
263 void
set_object_pos(Sint32 num)264 sprite_object::set_object_pos (Sint32 num)
265 {
266   object_pos = num;
267 }
268 
269 void
set_display_pos(Sint32 num)270 sprite_object::set_display_pos (Sint32 num)
271 {
272   display_pos = num;
273 }
274 
275 /**
276  * Make a simple sprite
277  * @param bitmap bitmap containing the images of sprite
278  * @param shadow true if the sprite has shadow, false by default
279  */
280 void
make_sprite(surface_sdl * bitmap,bool shadow)281 sprite_object::make_sprite (surface_sdl * bitmap, bool shadow)
282 {
283   init_common (bitmap, shadow);
284   pixel_data = bitmap->get_pixel_data ();
285 }
286 
287 /**
288  * Initialize some common values
289  * @param bitmap bitmap containing the images of sprite
290  * @param shadow true if the sprite has shadow
291  */
292 void
init_common(surface_sdl * bitmap,bool shadow)293 sprite_object::init_common (surface_sdl * bitmap, bool shadow)
294 {
295   screen_width = display->get_width ();
296   screen_height = display->get_height ();
297   row_size = bitmap->get_row_size ();
298   offscreen_pitch = game_screen->get_row_size ();
299   sprite_has_shadow = shadow;
300   screen_ptr = (char *) NULL;
301   shadow_screen_ptr = (char *) NULL;
302   sprite_width = bitmap->get_width ();
303   sprite_height = bitmap->get_height ();
304   max_of_images = 1;
305   collision_height = sprite_height;
306   collision_width = sprite_width;
307   x_maximum = screen_width -  collision_width;
308   y_maximum = screen_height - collision_height;
309   offsetSrce = bitmap->get_line_modulo (sprite_width);
310   offsetDest = game_screen->get_line_modulo (sprite_width);
311 }
312 
313 /**
314  * Allocate memory for graphics data sprite for optimized drawing routines
315  * @param numof maximum mumber of images for this sprite
316  */
317 void
alloc_drawing_tables(Sint32 numof)318 sprite_object::alloc_drawing_tables (Sint32 numof)
319 {
320   has_allocated_memory = true;
321   max_of_images = numof;
322   try
323     {
324       /* draw lines by lines */
325       if (draw_method == DRAW_LINE_BY_LINE)
326         {
327           affligFrst = 0;
328           affligLast = sprite_height;
329           drawing_peer_line = new bb_afligne* [max_of_images];
330           for (Sint32 i = 0; i < max_of_images; i++)
331             {
332               bb_afligne *p = new bb_afligne[sprite_height];
333               drawing_peer_line[i] = p;
334             }
335         }
336 
337       /* table giving address of each images of the sprite
338        * into bitmap source */
339       images_pixel_data = new char* [max_of_images];
340       /* drawing tables for offsets and counters values (words and bytes) */
341       drawing_values = new Sint16* [max_of_images];
342       /* drawing tables of drawing pixels data */
343       drawing_data = new char* [max_of_images];
344 
345       for (Sint32 i = 0; i < max_of_images; i++)
346         {
347           images_pixel_data[i] = NULL;
348           drawing_values[i] = NULL;
349           drawing_data[i] = NULL;
350         }
351 
352       /* table for draw pixel by pixel, used for color cycling */
353       if (is_draw_pixel_by_pixel)
354         {
355           drawing_pixels = new Sint16 *[max_of_images];
356           for (Sint32 i = 0; i < max_of_images; i++)
357             {
358               drawing_pixels[i] = NULL;
359             }
360         }
361     }
362   catch (std::bad_alloc &)
363     {
364       std::cerr << "(!)sprite_object::alloc_drawing_tables " <<
365       "not enough memory to allocate " <<
366       "list of sprite drawing tables for "
367       << max_of_images << " images! " << std::endl;
368       throw;
369     }
370 }
371 
372 /**
373  * Create the structure for drawing the sprite
374  * @param type_id sprite type id, number from 1 to n
375  * @praam image bitmap containing the images of sprite
376  * @param shadow true if it sprite has a shadow, false otherwise
377  * @param by_pixel if true generate additional table to drawing
378  *                 pixel by pixel. Used for color cyclyng.
379  *                 False by default
380  */
381 void
create_sprite(Sint32 type_id,surface_sdl * image,bool shadow,bool by_pixel)382 sprite_object::create_sprite (Sint32 type_id, surface_sdl * image, bool shadow,
383                               bool by_pixel)
384 {
385   is_draw_pixel_by_pixel = by_pixel;
386   if (draw_method == COPY_FROM_BITMAP)
387     {
388       draw_method = DRAW_WITH_TABLES;
389     }
390 
391   sprite_type_id = type_id;
392   init_common (image, shadow);
393 
394   /* read sprite characteristics */
395   const sprite_description *descr = zelistBOB[sprite_type_id];
396   sprite_height = descr->height;
397   sprite_height *= resolution;
398   max_of_images = descr->number_of_images;
399   frame_index_max = max_of_images - 1;
400   sprite_width = descr->width;
401   sprite_width *= resolution;
402   collision_height = sprite_height;
403   collision_width = sprite_width;
404   x_maximum = screen_width - sprite_width;
405   y_maximum = screen_height - sprite_height;
406 
407   offsetSrce = image->get_line_modulo (sprite_width);
408   offsetDest = game_screen->get_line_modulo (sprite_width);
409 
410   /* Allocate list for the lists of the drawing tables */
411   alloc_drawing_tables (max_of_images);
412 
413   /*
414    * generate the drawing tables
415    */
416   sprite_coordinates *coord = descr->coordinates;
417   /* process each image frame of the sprite animation */
418   for (Sint32 i = 0; i < max_of_images; i++)
419     {
420       /* counter of the number of pixels of the image frame */
421       Uint32 pixels_count = 0;
422       /* table size counter of offsets and loops counters values */
423       Uint32 values_count = 0;
424       Uint32 pos_x = (Sint32) coord[i].xcoord;
425       pos_x *= resolution;
426       pos_x *= 16;
427       Uint32 pos_y = (Sint32) coord[i].ycoord;
428       pos_y *= resolution;
429 
430       /* verify page overflow */
431       if (pos_y > (image->get_height () - sprite_height) ||
432           pos_x > (image->get_width () - sprite_width))
433         {
434           std::cerr << "(!)sprite_object::create_sprite() " <<
435           "sprite_type_id: " << sprite_type_id <<
436           "; x2: " << pos_x + sprite_width <<
437           "; width of the bitmap: " << image->get_width () <<
438           "; y2: " << pos_y + sprite_height <<
439           "; height of the bitmap: " << image->get_height () <<
440           std::endl;
441           std::cerr << "(!)sprite_object::create_sprite() " <<
442           "pox_x: " <<  coord[i].xcoord <<
443           "; pos_y: " << coord[i].ycoord <<
444           "; image number: " << i <<
445           "; resolution: " << resolution << std::endl;
446           throw std::runtime_error ("(!)sprite_object::create_sprite() "
447                                     "failed! Coordinates out of range");
448         }
449 
450       /*
451        * mirror y if request
452        */
453       if (is_mirrored_vertically)
454         {
455           char *top = image->get_pixel_data (pos_x, pos_y);
456           char *bottom = image->get_pixel_data (pos_x, pos_y + sprite_height - 1);
457           Uint32 next = image->get_row_size ();
458           for (Uint32 j = 0; j < sprite_height / 2; j++)
459             {
460               for (Uint32 k = 0; k < sprite_width; k++)
461                 {
462                   char pixel = top[k];
463                   top[k] = bottom[k];
464                   bottom[k] = pixel;
465                 }
466               top += next;
467               bottom -= next;
468             }
469         }
470 
471       /*
472        * calculation size of the table
473        */
474       /* counter of the contiguous pixels */
475       Uint32 contiguous = 0;
476       /* graphic address of the sprite in png image */
477       char *pixel_data = image->get_pixel_data (pos_x, pos_y);
478       for (Uint32 j = 0; j < sprite_height; j++)
479         {
480           for (Uint32 k = 0; k < sprite_width; k++)
481             {
482               /* read a pixel */
483               char pixel = *(pixel_data++);
484               if (pixel != 0)
485                 {
486                   contiguous++;
487                   /* increase the size of pixel's table */
488                   pixels_count++;
489                 }
490               else
491                 {
492                   /* at least one pixel? */
493                   if (contiguous > 0)
494                     {
495                       contiguous = 0;
496                       /* increase the size of the counter's table */
497                       values_count++;
498                     }
499                 }
500             }
501           if (contiguous > 0)
502             {
503               contiguous = 0;
504               values_count++;
505             }
506           pixel_data += offsetSrce;
507         }
508 
509       /*
510        * generate the sprite's table for it displaying
511        */
512       char *pixels;
513       Sint16 *counters;
514       Sint16 *destW = NULL;
515       try
516         {
517           pixels = new char[pixels_count];
518           counters = new Sint16[values_count * 3 + 1];
519           if (is_draw_pixel_by_pixel)
520             {
521               destW = new Sint16[values_count * 2 + 1];
522             }
523         }
524       catch (std::bad_alloc &)
525         {
526           std::cerr << "(!)sprite_object::create_sprite() " <<
527           "not enough memory to allocate " <<
528           "drawing tables for "
529           << pixels_count << " pixels! " << std::endl;
530           throw;
531         }
532 
533       /* table of offsets and loops counters */
534       drawing_values[i] = counters;
535       /* table of the pixels */
536       drawing_data[i] = pixels;
537       if (is_draw_pixel_by_pixel)
538         {
539           drawing_pixels[i] = destW;
540         }
541 
542       /*
543        * generate the sprite's table for display
544        */
545       Uint32 offset = 0;
546       /* counter of the contiguous pixels */
547       contiguous = 0;
548       pixel_data = image->get_pixel_data (pos_x, pos_y); // graphic address
549       images_pixel_data[i] = pixel_data;
550       *(counters++) = (Sint16) values_count;      // Nombre d'occurences
551       if (is_draw_pixel_by_pixel)
552         {
553           *(destW++) = (Sint16) values_count;    // Nombre d'occurences
554         }
555       values_count = 0;                // compteur nombre d'offest et de compteur
556       Sint32 left_offset = 0;
557       bool flagO = false;
558       for (Uint32 j = 0; j < sprite_height; j++)
559         {
560           /* special display mode line peer line (used for gigablitz) */
561           if (draw_method == DRAW_LINE_BY_LINE)
562             {
563               bb_afligne *p = drawing_peer_line[i];
564               p[j].TABAFFICH1 = counters;
565               p[j].TABAFFICH2 = pixels;
566             }
567 
568           flagO = false;
569           for (Uint32 k = 0; k < sprite_width; k++)
570             {
571               /* read the pixel */
572               char pixel = *(pixel_data++);
573               /* transparent? */
574               if (pixel != 0)
575                 {
576                   /* no, save pixel value */
577                   *(pixels++) = (Sint16) pixel;
578                   contiguous++;
579                 }
580               else
581                 {
582                   /* at least one pixel? */
583                   if (contiguous > 0)
584                     {
585                       if (is_draw_pixel_by_pixel)
586                         {
587                           *(destW++) = (Sint16) offset;  //previous offset
588                           *(destW++) = (Sint16) contiguous;  //number of pixel(s)
589                         }
590                       /* save the previous offset in bytes */
591                       *(counters++) = (Sint16) offset;
592 #ifndef BYTES_COPY
593                       /* save the number of 32-bit long words = x4 pixels */
594                       Sint32 n = contiguous >> 2;
595                       *(counters++) = (Sint16) n;
596                       /* rest 0, 1, 2 or 3 bytes */
597                       contiguous &= 0x003;
598 #else
599                       *(counters++) = 0;
600 #endif
601                       /* save number of contiguous bytes = x1 pixel */
602                       *(counters++) = (Sint16) contiguous;
603                       contiguous = 0;
604                       offset = 0;
605                       values_count++;  //COUNTERTAB++
606                       flagO = true;
607                     }
608                   if (!flagO)
609                     {
610                       left_offset++;
611                     }
612                   offset++;
613                 }
614             }                   //width loop
615           //***
616           if (contiguous > 0)
617             {
618               if (is_draw_pixel_by_pixel)
619                 {
620                   *(destW++) = (Sint16) offset;  //previous offset
621                   *(destW++) = (Sint16) contiguous;  //number of pixel(s)
622                 }
623               *(counters++) = (Sint16) offset;
624 #ifndef BYTES_COPY
625               /* save the number of 32-bit long words = x4 pixels */
626               Sint32 n = contiguous >> 2;
627               *(counters++) = (Sint16) n;
628               /* rest 0, 1, 2 or 3 bytes */
629               contiguous &= 0x003;
630 #else
631               *(counters++) = 0;
632 #endif
633               /* save number of contiguous bytes = x1 pixel */
634               *(counters++) = (Sint16) contiguous;
635               contiguous = 0;
636               values_count++;          //COUNTERTAB++
637               offset = 0;
638             }
639           pixel_data += offsetSrce;
640           offset += offsetDest;
641 
642           if (draw_method == DRAW_LINE_BY_LINE)
643             {
644               bb_afligne *p = drawing_peer_line[i];
645               p[j].COUNTERTAB = values_count;
646               p[j].OFFSETLEFT = left_offset;
647               values_count = 0;
648               left_offset = 0;
649             }
650         } /* height loop */
651     } /* image frame loop */
652   /* current table of offsets and loops counters */
653   current_drawing_values = drawing_values[0];
654   /* current pixles table */
655   current_drawing_data = drawing_data[0];
656   if (is_draw_pixel_by_pixel)
657     {
658       current_drawing_pixels = drawing_pixels[0];
659     }
660   pixel_data = images_pixel_data[0];   //adresse GFX pour routine "draw()"
661 }
662 
663 /**
664  * Set x and y coordinates of the sprite
665  * @param xcoord the x coordinate in pixels
666  * @param ycoord the y coordinate in pixels
667  */
668 void
set_coordinates(Sint32 xcoord,Sint32 ycoord)669 sprite_object::set_coordinates (Sint32 xcoord, Sint32 ycoord)
670 {
671   x_coord = xcoord;
672   y_coord = ycoord;
673 }
674 
675 /**
676  * Initializes the maximum and minimum coordinates of the sprite
677  */
678 void
init_coords_max_min(Uint32 width_less)679 sprite_object::init_coords_max_min(Uint32 width_less)
680 {
681   if (sprite_has_shadow)
682     {
683       x_minimum = ombredecax;
684     }
685   else
686     {
687       x_minimum = 0;
688       y_minimum = 0;
689     }
690   x_maximum = screen_width - collision_width - width_less;
691   y_maximum = screen_height - collision_height;
692 }
693 
694 /**
695  * Set x coordinate of the sprite
696  * @param xcoord the x coordinate in pixels
697  */
698 void
set_x_coord(Sint32 xcoord)699 sprite_object::set_x_coord (Sint32 xcoord)
700 {
701   x_coord = xcoord;
702 }
703 
704 /**
705  * Set y coordinate of the sprite
706  * @param ycoord the y coordinate in pixels
707  */
708 void
set_y_coord(Sint32 ycoord)709 sprite_object::set_y_coord (Sint32 ycoord)
710 {
711   y_coord = ycoord;
712 }
713 
714 /**
715  * Moving the sprite horizontally
716  * @param xoffset the horizontal offset of displacement
717  */
718 void
move_x(Sint32 xoffset)719 sprite_object::move_x (Sint32 xoffset)
720 {
721   x_coord += xoffset;
722 }
723 
724 /**
725  * Moving the sprite vertically
726  * @param yoffset the vertical offset of displacement
727  */
728 void
move_y(Sint32 yoffset)729 sprite_object::move_y (Sint32 yoffset)
730 {
731   y_coord += yoffset;
732 }
733 
734 /**
735  * Check if the sprite has a shadow
736  * @return true if the sprite has a shadow
737  */
738 bool
has_shadow()739 sprite_object::has_shadow ()
740 {
741   return sprite_has_shadow;
742 }
743 
744 /**
745  * Set or clear the flag sprite shadow
746  * param shadow true if the sprite has a shadow
747  */
748 void
set_shadow(bool shadow)749 sprite_object::set_shadow (bool shadow)
750 {
751   sprite_has_shadow = shadow;
752 }
753 
754 
755 
756 /**
757  * Get x coordinate
758  * @return x coordinate of the sprite
759  */
760 Sint32
get_x_coord()761 sprite_object::get_x_coord ()
762 {
763   return x_coord;
764 }
765 
766 /**
767  * Get y coordinate
768  * @return y coordinate of the sprite
769  */
770 Sint32
get_y_coord()771 sprite_object::get_y_coord ()
772 {
773   return y_coord;
774 }
775 
776 /**
777  * Set the image to use for this sprite
778  */
779 void
set_image()780 sprite_object::set_image ()
781 {
782   Sint32 index = frame_index;
783   pixel_data = images_pixel_data[index];
784   current_drawing_values = drawing_values[index];
785   current_drawing_data = drawing_data[index];
786   if (is_draw_pixel_by_pixel && drawing_pixels)
787     {
788       current_drawing_pixels = drawing_pixels[index];
789     }
790 }
791 
792 /**
793  * Set the image to use for this sprite
794  * @param index frame index
795  */
796 void
set_image(Sint32 index)797 sprite_object::set_image (Sint32 index)
798 {
799   frame_index = index;
800   pixel_data = images_pixel_data[index];
801   current_drawing_values = drawing_values[index];
802   current_drawing_data = drawing_data[index];
803   if (is_draw_pixel_by_pixel)
804     {
805       current_drawing_pixels = drawing_pixels[index];
806     }
807 }
808 
809 /**
810  * Restore background where sprite was displayed
811  */
812 void
restore_background_under_sprite()813 sprite_object::restore_background_under_sprite ()
814 {
815   /* if memory address is null, then sprite is not displaying */
816   if (NULL == screen_ptr)
817     {
818       return;
819     }
820 
821   /* special sprite, restore line by line (gigablitz) */
822   if (draw_method == DRAW_LINE_BY_LINE)
823     {
824       restore_line_by_line ();
825       return;
826     }
827 
828 #ifndef BYTES_COPY
829   Sint32 *restore32 = (Sint32 *) restore_ptr;
830   Sint32 *screen32 = (Sint32 *) screen_ptr;
831   screen_ptr = (char *) NULL;
832   Sint16 *counters = current_drawing_values;
833   Uint32 h = (Uint32) * (counters++);
834   for (Uint32 i = 0; i < h; i++)
835     {
836       /* offset */
837       Sint16 k = *(counters++);
838       screen32 = (Sint32 *) ((char *) screen32 + k);
839       restore32 = (Sint32 *) ((char *) restore32 + k);
840       /* number of contiguous bytes */
841       k = *(counters++);
842       for (Sint32 j = 0; j < k; j++)
843         {
844           *(screen32++) = *(restore32++);
845         }
846       /* number of contiguous long words */
847       k = *(counters++);
848       char *screen8 = (char *) screen32;
849       char *restore8 = (char *) restore32;
850       for (Sint32 j = 0; j < k; j++)
851         {
852           *(screen8++) = *(restore8++);
853         }
854       screen32 = (Sint32 *) screen8;
855       restore32 = (Sint32 *) restore8;
856     }
857 #else
858   char *restore = restore_ptr;
859   char *screen = screen_ptr;
860   screen_ptr = (char *) NULL;
861   Sint16 *counters = current_drawing_values;
862   Uint32 h = (Uint32) * (counters++);
863   for (Uint32 i = 0; i < h; i++)
864     {
865       /* offset */
866       Sint16 k = *(counters++);
867       screen += k;
868       restore += k;
869       counters++;
870       /* number of contiguous bytes */
871       k = *(counters++);
872       for (Sint32 j = 0; j < k; j++)
873         {
874           *(screen++) = *(restore++);
875         }
876     }
877 #endif
878 }
879 
880 /**
881  * Restore background where line by line (used for gigablitz)
882  */
883 void
restore_line_by_line()884 sprite_object::restore_line_by_line ()
885 {
886 
887   bb_afligne *p = drawing_peer_line[frame_index];
888   Sint32 l = affligFrSv;
889   Sint16 o = p[l].OFFSETLEFT;
890   Uint32 t = (Uint32) p[l].COUNTERTAB;
891   Uint16 *gfxPT = (Uint16 *) p[l].TABAFFICH1;
892   gfxPT++;
893 #ifndef BYTES_COPY
894   Sint32 *srcPT = (Sint32 *) restore_ptr;
895   Sint32 *adres = (Sint32 *) screen_ptr;
896   screen_ptr = (char *) NULL;
897   for (Uint32 i = 0; i < t; i++)
898     {
899       adres = (Sint32 *) ((char *) adres + o);
900       srcPT = (Sint32 *) ((char *) srcPT + o);
901       o = *(gfxPT++);           //number of pixels contigus
902       for (Sint32 k = 0; k < o; k++)
903         *(adres++) = *(srcPT++);
904       o = *(gfxPT++);           //number of pixels contigus
905       char *adreb = (char *) adres;
906       char *srcPB = (char *) srcPT;
907       for (Sint32 k = 0; k < o; k++)
908         *(adreb++) = *(srcPB++);
909       adres = (Sint32 *) adreb;
910       srcPT = (Sint32 *) srcPB;
911       o = *(gfxPT++);           //offset
912     }
913   l++;
914   for (; l < affligLaSv; l++)
915     {
916       gfxPT = (Uint16 *) p[l].TABAFFICH1;
917       t = (Uint32) p[l].COUNTERTAB;
918       for (Uint32 i = 0; i < t; i++)
919         {
920           o = *(gfxPT++);       //offset
921           adres = (Sint32 *) ((char *) adres + o);
922           srcPT = (Sint32 *) ((char *) srcPT + o);
923           o = *(gfxPT++);       //number of pixels contigus
924           for (Sint32 k = 0; k < o; k++)
925             *(adres++) = *(srcPT++);
926           o = *(gfxPT++);       //number of pixels contigus
927           char *adreb = (char *) adres;
928           char *srcPB = (char *) srcPT;
929           for (Sint32 k = 0; k < o; k++)
930             *(adreb++) = *(srcPB++);
931           adres = (Sint32 *) adreb;
932           srcPT = (Sint32 *) srcPB;
933         }
934     }
935 #else
936   char *srcPT = restore_ptr;
937   char *adres = screen_ptr;
938   screen_ptr = (char *) NULL;
939   for (Uint32 i = 0; i < t; i++)
940     {
941       adres = adres + o;
942       srcPT = srcPT + o;
943       gfxPT++;
944       o = *(gfxPT++);           //number of pixels contigus
945       for (Sint32 k = 0; k < o; k++)
946         *(adres++) = *(srcPT++);
947       o = *(gfxPT++);           //offset
948     }
949   l++;
950   for (; l < affligLaSv; l++)
951     {
952       gfxPT = (Uint16 *) p[l].TABAFFICH1;
953       t = (Uint32) p[l].COUNTERTAB;
954       for (Uint32 i = 0; i < t; i++)
955         {
956           o = *(gfxPT++);       //offset
957           adres = adres + o;
958           srcPT = srcPT + o;
959           gfxPT++;
960           o = *(gfxPT++);       //number of pixels contigus
961           for (Sint32 k = 0; k < o; k++)
962             *(adres++) = *(srcPT++);
963         }
964     }
965 #endif
966 }
967 
968 /**
969  * Return current animation offset
970  * @return the current frame index
971  */
972 Sint32
get_frame_index()973 sprite_object::get_frame_index ()
974 {
975   return frame_index;
976 }
977 
978 /**
979  * Restore background where sprite's shadow was displayed
980  */
981 void
restore_background_under_shadow()982 sprite_object::restore_background_under_shadow ()
983 {
984   if (NULL == shadow_screen_ptr)
985     {
986       return;
987     }
988 #ifndef BYTES_COPY
989   Sint32 *restore32 = (Sint32 *) shadow_restore_ptr;
990   Sint32 *screen32 = (Sint32 *) shadow_screen_ptr;
991   shadow_screen_ptr = (char *) NULL;
992   Sint16 *counters = current_drawing_values;
993   Uint32 h = (Uint32) * (counters++);
994   for (Uint32 i = 0; i < h; i++)
995     {
996       /* offset */
997       Sint16 k = *(counters++);
998       screen32 = (Sint32 *) ((char *) screen32 + k);
999       restore32 = (Sint32 *) ((char *) restore32 + k);
1000       /* number of contiguous 32-bit words */
1001       k = *(counters++);
1002       for (Sint32 j = 0; j < k; j++)
1003         {
1004           *(screen32++) = *(restore32++);
1005         }
1006       /* number of contiguous bytes */
1007       k = *(counters++);
1008       char *screen8 = (char *) screen32;
1009       char *restore8 = (char *) restore32;
1010       for (Sint32 j = 0; j < k; j++)
1011         {
1012           *(screen8++) = *(restore8++);
1013         }
1014       screen32 = (Sint32 *) screen8;
1015       restore32 = (Sint32 *) restore8;
1016     }
1017 #else
1018   char *restore = shadow_restore_ptr;
1019   char *screen = shadow_screen_ptr;
1020   shadow_screen_ptr = (char *) NULL;
1021   Sint16 *counters = current_drawing_values;
1022   Uint32 h = (Uint32) * (counters++);
1023   for (Uint32 i = 0; i < h; i++)
1024     {
1025       /* offset */
1026       Sint16 k = *(counters++);
1027       screen += k;
1028       restore += k;
1029       counters++;
1030       /* number of contiguous bytes */
1031       k = *(counters++);
1032       for (Sint32 j = 0; j < k; j++)
1033         {
1034           *(screen++) = *(restore++);
1035         }
1036     }
1037 #endif
1038 }
1039 
1040 /**
1041  * Draw a sprite into the offscreen
1042  */
1043 void
draw()1044 sprite_object::draw ()
1045 {
1046   if (!is_enabled || frame_index >= max_of_images)
1047     {
1048       return;
1049     }
1050   switch (draw_method)
1051     {
1052     case DRAW_WITH_TABLES:
1053       draw_with_tables ();
1054       break;
1055     case COPY_FROM_BITMAP:
1056       draw_copy_from_bitmap ();
1057       break;
1058     case DRAW_LINE_BY_LINE:
1059       draw_line_by_line ();
1060       break;
1061     case DRAW_REPEAT_SPRITE:
1062       draw_vertically_repeated ();
1063       break;
1064     case DRAW_COLOR_CYCLING_MASK:
1065       draw_cycling_color ();
1066       break;
1067     case DRAW_CAPSULE:
1068       draw_capsule ();
1069       break;
1070     }
1071 }
1072 
1073 /**
1074  * Draw a sprite with tables to optimize the copy
1075  * It is the method most frequently used
1076  */
1077 void
draw_with_tables()1078 sprite_object::draw_with_tables ()
1079 {
1080   restore_ptr = background_screen->get_pixel_data (x_coord, y_coord);
1081 #ifndef BYTES_COPY
1082   Sint32 *screen32 = (Sint32 *) game_screen->get_pixel_data (x_coord, y_coord);
1083   screen_ptr = (char *) screen32;
1084   /* pixels data of the sprite image */
1085   Sint32 *pixels32 = (Sint32 *) current_drawing_data;
1086   /* offsets and counters of loops for copies */
1087   Uint16 *counters = (Uint16 *) current_drawing_values;
1088   /* height of the sprite in pixels */
1089   Uint32 h = (Uint32) * (counters++);
1090   for (Uint32 i = 0; i < h; i++)
1091     {
1092       /* offset */
1093       Sint16 k = *(counters++);
1094       screen32 = (Sint32 *) ((char *) screen32 + k);
1095       /* number of contiguous long words */
1096       k = *(counters++);
1097       for (Sint32 j = 0; j < k; j++)
1098         {
1099           Sint32 p = *(pixels32++);
1100           *(screen32++) = p;
1101         }
1102       /* number of contiguous bytes */
1103       k = *(counters++);
1104       char *pixels8 = (char *) pixels32;
1105       char *screen8 = (char *) screen32;
1106       for (Sint32 j = 0; j < k; j++)
1107         {
1108           char p = *(pixels8++);
1109           *(screen8++) = p;
1110         }
1111       pixels32 = (Sint32 *) pixels8;
1112       screen32 = (Sint32 *) screen8;
1113     }
1114 #else
1115   char *screen = game_screen->get_pixel_data (x_coord, y_coord);
1116   screen_ptr = screen;
1117   /* pixels data of the sprite image */
1118   char *pixels = current_drawing_data;
1119   /* offsets and counters of loops for copies */
1120   Uint16 *counters = (Uint16 *) current_drawing_values;
1121   /* height of the sprite in pixels */
1122   Uint32 t = (Uint32) * (counters++);
1123   for (Uint32 i = 0; i < t; i++)
1124     {
1125       /* offset */
1126       Sint16 k = *(counters++);
1127       screen += k;
1128       counters++;
1129       /* number of contiguous bytes */
1130       k = *(counters++);
1131       for (Sint32 j = 0; j < k; j++)
1132         {
1133           *(screen++) = *(pixels++);
1134         }
1135     }
1136 #endif
1137 }
1138 
1139 /**
1140  * Draw a color cycling sprite mask (paddle's fires and guardian's fires)
1141  */
1142 void
draw_cycling_color()1143 sprite_object::draw_cycling_color ()
1144 {
1145   cycling_index &= 7;
1146   Sint32 pixel = current_cycling[cycling_index++];
1147   restore_ptr = background_screen->get_pixel_data (x_coord, y_coord);
1148 #ifndef BYTES_COPY
1149   Sint32 *screen32 = (Sint32 *) game_screen->get_pixel_data (x_coord, y_coord);
1150   screen_ptr = (char *) screen32;
1151   /* pixels data of the sprite image */
1152   Sint32 *pixels32 = (Sint32 *) current_drawing_data;
1153   /* offsets and counters of loops for copies */
1154   Uint16 *counters = (Uint16 *) current_drawing_values;
1155   /* height of the sprite in pixels */
1156   Uint32 h = (Uint32) * (counters++);
1157   for (Uint32 i = 0; i < h; i++)
1158     {
1159       /* offset */
1160       Sint16 k = *(counters++);
1161       screen32 = (Sint32 *) ((char *) screen32 + k);
1162       /* number of contiguous long words */
1163       k = *(counters++);
1164       for (Sint32 j = 0; j < k; j++)
1165         {
1166           *(screen32++) = pixel;
1167         }
1168       /* number of contiguous bytes */
1169       k = *(counters++);
1170       char *pixels8 = (char *) pixels32;
1171       char *screen8 = (char *) screen32;
1172       for (Sint32 j = 0; j < k; j++)
1173         {
1174           *(screen8++) = pixel;
1175         }
1176       pixels32 = (Sint32 *) pixels8;
1177       screen32 = (Sint32 *) screen8;
1178     }
1179 #else
1180   char *screen = game_screen->get_pixel_data (x_coord, y_coord);
1181   screen_ptr = screen;
1182   /* offsets and counters of loops for copies */
1183   Uint16 *counters = (Uint16 *) current_drawing_values;
1184   Uint32 t = (Uint32) * (counters++);
1185   for (Uint32 i = 0; i < t; i++)
1186     {
1187       /* offset */
1188       Sint16 k = *(counters++);
1189       screen += k;
1190       counters++;
1191       /* number of contiguous bytes */
1192       k = *(counters++);
1193       for (Sint32 j = 0; j < k; j++)
1194         {
1195           *(screen++) = pixel;
1196         }
1197     }
1198 #endif
1199 }
1200 
1201 /**
1202  * Draw somes capsules with color cyling
1203  */
1204 void
draw_capsule()1205 sprite_object::draw_capsule ()
1206 {
1207   cycling_index &= 7;
1208   Sint32 color = current_cycling[cycling_index++];
1209   char *screen = game_screen->get_pixel_data (x_coord, y_coord);
1210   screen_ptr = screen;
1211   restore_ptr = background_screen->get_pixel_data (x_coord, y_coord);
1212   /* pixels data of the sprite image */
1213   char *pixels = current_drawing_data;
1214   /* offsets and counters of loops for copies */
1215   Uint16 *counters = (Uint16 *) current_drawing_pixels;
1216   Uint32 h = (Uint32) * (counters++);
1217   for (Uint32 i = 0; i < h; i++)
1218     {
1219       /* offset */
1220       Sint16 k = *(counters++);
1221       screen = screen + k;
1222       /* number of contiguous bytes */
1223       k = *(counters++);
1224       for (Sint32 j = 0; j < k; j++)
1225         {
1226           char p = *(pixels++);
1227           if (p == 29)
1228             {
1229               *(screen++) = color;
1230             }
1231           else
1232             {
1233               *(screen++) = p;
1234             }
1235         }
1236     }
1237 }
1238 
1239 /**
1240  * Draw sprite. Sprite image will be repeated vertically
1241  * Used only for the vertical gauge of the guardian's life level
1242  */
1243 void
draw_vertically_repeated()1244 sprite_object::draw_vertically_repeated ()
1245 {
1246   restore_ptr = background_screen->get_pixel_data (x_coord, y_coord);
1247   screen_ptr = game_screen->get_pixel_data (x_coord, y_coord);
1248   Sint32 yoffset = 0;
1249   for (Sint32 r = 0; r < num_of_repeats; r++, yoffset += sprite_height)
1250     {
1251       /* offsets and counters of loops for copies */
1252       Uint16 *counters = (Uint16 *) current_drawing_values;
1253       Uint32 h = (Uint32) * (counters++);
1254 #ifndef BYTES_COPY
1255       Sint32 *screen32 =
1256         (Sint32 *) game_screen->get_pixel_data (x_coord, y_coord + yoffset);
1257       /* pixels data of the sprite image */
1258       Sint32 *pixels32 = (Sint32 *) current_drawing_data;
1259       for (Uint32 i = 0; i < h; i++)
1260         {
1261           /* offset in bytes */
1262           Sint16 k = *(counters++);
1263           screen32 = (Sint32 *) ((char *) screen32 + k);
1264           /* number of contiguous long words */
1265           k = *(counters++);
1266           for (Sint32 j = 0; j < k; j++)
1267             {
1268               Sint32 pixels = *(pixels32++);
1269               *(screen32++) = pixels;
1270             }
1271           /* number of contiguous bytes */
1272           k = *(counters++);
1273           char *pixels8 = (char *) pixels32;
1274           char *screen8 = (char *) screen32;
1275           for (Sint32 j = 0; j < k; j++)
1276             {
1277               char pixel = *(pixels8++);
1278               *(screen8++) = pixel;
1279             }
1280           pixels32 = (Sint32 *) pixels8;
1281           screen32 = (Sint32 *) screen8;
1282         }
1283 #else
1284       char *screen = game_screen->get_pixel_data (x_coord, y_coord + yoffset);
1285       /* pixels data of the sprite image */
1286       char *pixels = current_drawing_data;
1287       for (Uint32 i = 0; i < h; i++)
1288         {
1289           /* offset in bytes */
1290           Sint16 k = *(counters++);
1291           screen += k;
1292           counters++;
1293           /* number of contiguous bytes */
1294           k = *(counters++);
1295           for (Sint32 j = 0; j < k; j++)
1296             {
1297               char pixel = *(pixels++);
1298               *(screen++) = pixel;
1299             }
1300         }
1301 #endif
1302     }
1303 }
1304 
1305 /**
1306  * Draw a sprite line by line, always by using tables.
1307  * Method used for the gigablitz vertical clipping only
1308  */
1309 void
draw_line_by_line()1310 sprite_object::draw_line_by_line ()
1311 {
1312   bb_afligne *p = drawing_peer_line[frame_index];
1313   restore_ptr = background_screen->get_pixel_data (x_coord, y_coord + affligFrst);
1314   affligFrSv = affligFrst;
1315   affligLaSv = affligLast;
1316   Sint32 l = affligFrst;
1317   Uint32 h = (Uint32) p[l].COUNTERTAB;
1318   /* offsets and counters of loops for copies */
1319   Uint16 *counters = (Uint16 *) p[l].TABAFFICH1;
1320   Sint16 k = p[l].OFFSETLEFT;
1321   counters++;
1322 #ifndef BYTES_COPY
1323   Sint32 *screen32 =
1324     (Sint32 *) game_screen->get_pixel_data (x_coord, y_coord + affligFrst);
1325   Sint32 *pixels32 = (Sint32 *) p[l].TABAFFICH2;
1326   screen_ptr = (char *) screen32;
1327   for (Uint32 i = 0; i < h; i++)
1328     {
1329       screen32 = (Sint32 *) ((char *) screen32 + k);
1330       /* number of contiguous long words */
1331       k = *(counters++);
1332       for (Sint32 j = 0; j < k; j++)
1333         {
1334           Sint32 pixels = *(pixels32++);
1335           *(screen32++) = pixels;
1336         }
1337       /* number of contiguous bytes */
1338       k = *(counters++);
1339       char *pixels8 = (char *) pixels32;
1340       char *screen8 = (char *) screen32;
1341       for (Sint32 j = 0; j < k; j++)
1342         {
1343           char pixel = *(pixels8++);
1344           *(screen8++) = pixel;
1345         }
1346       pixels32 = (Sint32 *) pixels8;
1347       screen32 = (Sint32 *) screen8;
1348       /* offset in bytes */
1349       k = *(counters++);
1350     }
1351   l++;
1352   for (; l < affligLast; l++)
1353     {
1354       h = (Uint32) p[l].COUNTERTAB;
1355       counters = (Uint16 *) p[l].TABAFFICH1;
1356       pixels32 = (Sint32 *) p[l].TABAFFICH2;
1357       for (Uint32 i = 0; i < h; i++)
1358         {
1359           k = *(counters++);
1360           screen32 = (Sint32 *) ((char *) screen32 + k);
1361           /* number of contiguous long words */
1362           k = *(counters++);
1363           for (Sint32 j = 0; j < k; j++)
1364             {
1365               Sint32 pixels = *(pixels32++);
1366               *(screen32++) = pixels;
1367             }
1368           /* number of contiguous bytes */
1369           k = *(counters++);
1370           char *pixels8 = (char *) pixels32;
1371           char *screen8 = (char *) screen32;
1372           for (Sint32 j = 0; j < k; j++)
1373             {
1374               char pixel = *(pixels8++);
1375               *(screen8++) = pixel;
1376             }
1377           pixels32 = (Sint32 *) pixels8;
1378           screen32 = (Sint32 *) screen8;
1379         }
1380     }
1381 #else
1382   char *screen = game_screen->get_pixel_data (x_coord, y_coord + affligFrst);
1383   char *pixels = p[l].TABAFFICH2;
1384   screen_ptr = screen;
1385   for (Uint32 i = 0; i < h; i++)
1386     {
1387       screen += k;
1388       counters++;
1389       /* number of contiguous pixels */
1390       k = *(counters++);
1391       for (Sint32 j = 0; j < k; j++)
1392         {
1393           char pixel = *(pixels++);
1394           *(screen++) = pixel;
1395         }
1396       /* offset in bytes */
1397       k = *(counters++);
1398     }
1399   l++;
1400   for (; l < affligLast; l++)
1401     {
1402       h = (Uint32) p[l].COUNTERTAB;
1403       counters = (Uint16 *) p[l].TABAFFICH1;
1404       pixels = p[l].TABAFFICH2;
1405       for (Uint32 i = 0; i < h; i++)
1406         {
1407           k = *(counters++);
1408           screen += k;
1409           counters++;
1410           /* number of contiguous pixels */
1411           k = *(counters++);
1412           for (Sint32 j = 0; j < k; j++)
1413             {
1414               char pixel = *(pixels++);
1415               *(screen++) = pixel;
1416             }
1417         }
1418     }
1419 #endif
1420 }
1421 
1422 /**
1423  * Draw a sprite shadow in the game offscreen
1424  */
1425 void
draw_shadow()1426 sprite_object::draw_shadow ()
1427 {
1428   if (!is_enabled || !sprite_has_shadow)
1429     {
1430       return;
1431     }
1432   shadow_restore_ptr =
1433     background_screen->get_pixel_data (x_coord + ombredecax,
1434                                        y_coord + ombredecay);
1435   Uint16 *counters = (Uint16 *) current_drawing_values;
1436   /* height of the sprite in pixels */
1437   Uint32 h = (Uint32) * (counters++);
1438   Uint32 mask = ombrepixe4;
1439 #ifndef BYTES_COPY
1440   Sint32 *screen32 =
1441     (Sint32 *) game_screen->get_pixel_data (x_coord + ombredecax,
1442                                             y_coord + ombredecay);
1443   shadow_screen_ptr = (char *) screen32;
1444   for (Uint32 i = 0; i < h; i++)
1445     {
1446       /* offset */
1447       Sint16 k = *(counters++);
1448       screen32 = (Sint32 *) ((char *) screen32 + k);
1449       /* number of contiguous long words */
1450       k = *(counters++);
1451       for (Sint32 j = 0; j < k; j++)
1452         {
1453            *(screen32++) |= mask;
1454         }
1455       /* number of contiguous bytes */
1456       k = *(counters++);
1457       char *screen8 = (char *) screen32;
1458       for (Sint32 j = 0; j < k; j++)
1459         {
1460           *(screen8++) |= mask;
1461         }
1462       screen32 = (Sint32 *) screen8;
1463     }
1464 #else
1465   char *screen = game_screen->get_pixel_data (x_coord + ombredecax,
1466                                               y_coord + ombredecay);
1467   shadow_screen_ptr = screen;
1468   for (Uint32 i = 0; i < h; i++)
1469     {
1470       /* offset */
1471       Sint16 k = *(counters++);
1472       screen += k;
1473       counters++;
1474       /* number of contiguous bytes */
1475       k = *(counters++);
1476       for (Sint32 j = 0; j < k; j++)
1477         {
1478           *(screen++) |= mask;
1479         }
1480     }
1481 #endif
1482 }
1483 
1484 /**
1485  * Draw a sprite in the brackground surface.
1486  * (build the background before a bricks level)
1487  */
1488 void
draw_to_brackground()1489 sprite_object::draw_to_brackground ()
1490 {
1491   restore_ptr = background_screen->get_pixel_data (x_coord, y_coord);
1492   /* offsets and counters of loops for copies */
1493   Uint16 *counters = (Uint16 *) current_drawing_values;
1494   /* height of the sprite in pixels */
1495   Uint32 h = (Uint32) * (counters++);
1496 #ifndef BYTES_COPY
1497   Sint32 *background32 = (Sint32 *) background_screen->get_pixel_data (x_coord, y_coord);
1498   screen_ptr = (char *) background32;
1499   Sint32 *pixels32 = (Sint32 *) current_drawing_data;
1500   for (Uint32 i = 0; i < h; i++)
1501     {
1502       /* offset */
1503       Sint16 k = *(counters++);
1504       background32 = (Sint32 *) ((char *) background32 + k);
1505       /* number of contiguous long words */
1506       k = *(counters++);
1507       for (Sint32 j = 0; j < k; j++)
1508         {
1509           Sint32 p = *(pixels32++);
1510           *(background32++) = p;
1511         }
1512       /*  number of contiguous bytes */
1513       k = *(counters++);
1514       char *pixels8 = (char *) pixels32;
1515       char *background8 = (char *) background32;
1516       for (Sint32 j = 0; j < k; j++)
1517         {
1518           char p = *(pixels8++);
1519           *(background8++) = p;
1520         }
1521       pixels32 = (Sint32 *) pixels8;
1522       background32 = (Sint32 *) background8;
1523     }
1524 #else
1525   char *background = background_screen->get_pixel_data (x_coord, y_coord);
1526   screen_ptr = background;
1527   char *pixels = current_drawing_data;
1528   for (Uint32 i = 0; i < h; i++)
1529     {
1530       /* offset */
1531       Sint16 k = *(counters++);
1532       background += k;
1533       counters++;
1534       /*  number of contiguous bytes */
1535       k = *(counters++);
1536       for (Sint32 j = 0; j < k; j++)
1537         {
1538           char p = *(pixels++);
1539           *(background++) = p;
1540         }
1541     }
1542 #endif
1543 }
1544 
1545 /**
1546  * Draw a shadow in the brackground offscreen
1547  */
1548 void
draw_shadow_to_brackground()1549 sprite_object::draw_shadow_to_brackground ()
1550 {
1551   shadow_restore_ptr = background_screen->get_pixel_data (x_coord + ombredecax,
1552                        y_coord + ombredecay);
1553   Uint16 *counters = (Uint16 *) current_drawing_values;
1554   /* height of the sprite in pixels */
1555   Uint32 h = (Uint32) * (counters++);
1556 #ifndef BYTES_COPY
1557   Sint32 *background32 = (Sint32 *) background_screen->get_pixel_data (x_coord + ombredecax,
1558                          y_coord + ombredecay);
1559   shadow_screen_ptr = (char *) background32;
1560   Sint32 p = ombrepixe4;
1561   for (Uint32 i = 0; i < h; i++)
1562     {
1563       /* offset */
1564       Sint16 k = *(counters++);
1565       background32 = (Sint32 *) ((char *) background32 + k);
1566       /* number of contiguous long words */
1567       k = *(counters++);
1568       for (Sint32 j = 0; j < k; j++)
1569         {
1570           *(background32++) |= p;
1571         }
1572       /* number of contiguous bytes */
1573       k = *(counters++);
1574       char *background8 = (char *) background32;
1575       for (Sint32 j = 0; j < k; j++)
1576         {
1577           *(background8++) |= p;
1578         }
1579       background32 = (Sint32 *) background8;
1580     }
1581 #else
1582   char p = ombrepixel;
1583   char *background = background_screen->get_pixel_data (x_coord + ombredecax,
1584                      y_coord + ombredecay);
1585   shadow_screen_ptr = background;
1586   for (Uint32 i = 0; i < h; i++)
1587     {
1588       /* offset */
1589       Sint16 k = *(counters++);
1590       background += k;
1591       counters++;
1592       /* number of contiguous bytes */
1593       k = *(counters++);
1594       for (Sint32 j = 0; j < k; j++)
1595         {
1596           *(background++) |= p;
1597         }
1598     }
1599 #endif
1600 }
1601 
1602 /**
1603  * Draw a sprite into the game offscreen (copy byte to byte, no table)
1604  */
1605 void
draw_copy_from_bitmap()1606 sprite_object::draw_copy_from_bitmap ()
1607 {
1608   if (!is_enabled)
1609     {
1610       return;
1611     }
1612   char *s = pixel_data;
1613   char *d = game_screen->get_pixel_data (x_coord, y_coord);
1614   restore_ptr = background_screen->get_pixel_data (x_coord, y_coord);
1615   screen_ptr = d;
1616   Sint32 m = row_size;
1617   Sint32 n = offscreen_pitch;
1618   Sint32 h = sprite_height;
1619   Sint32 l = sprite_width;
1620   for (Sint32 i = 0; i < h; i++)
1621     {
1622       for (Sint32 j = 0; j < l; j++)
1623         {
1624           /* read the pixel */
1625           char p = s[j];
1626           /* black color? */
1627           if (p != 0)
1628             {
1629               /* no, put the pixel */
1630               d[j] = p;
1631             }
1632         }
1633       s += m;
1634       d += n;
1635     }
1636 }
1637 
1638 /**
1639  * Simple byte to byte copy of the sprite in the game offscreen
1640  */
1641 void
copy_to_game_screen()1642 sprite_object::copy_to_game_screen ()
1643 {
1644   if (!is_enabled)
1645     {
1646       return;
1647     }
1648   char *s = pixel_data;
1649   char *d = game_screen->get_pixel_data (x_coord, y_coord);
1650   restore_ptr = background_screen->get_pixel_data (x_coord, y_coord);
1651   screen_ptr = d;
1652   Uint32 row = row_size;
1653   Uint32 pitch = offscreen_pitch;
1654   Uint32 h = sprite_height;
1655   Uint32 w = sprite_width;
1656   for (Uint32 i = 0; i < h; i++)
1657     {
1658       for (Uint32 j = 0; j < w; j++)
1659         {
1660           d[j] = s[j];
1661         }
1662       s += row;
1663       d += pitch;
1664     }
1665 }
1666 
1667 /**
1668  * Restore rectanble background where sprite was displayed
1669  */
1670 void
restore_rectangle_background()1671 sprite_object::restore_rectangle_background ()
1672 {
1673   if (NULL == screen_ptr)
1674     {
1675       return;
1676     }
1677   char *s = restore_ptr;
1678   char *d = screen_ptr;
1679   screen_ptr = (char *) NULL;
1680   Uint32 pitch = offscreen_pitch;
1681   Uint32 h = sprite_height;
1682   Uint32 w = sprite_width;
1683   for (Uint32 i = 0; i < h; i++)
1684     {
1685       for (Uint32 j = 0; j < w; j++)
1686         {
1687           /* restore the pixel */
1688           d[j] = s[j];
1689         }
1690       s += pitch;
1691       d += pitch;
1692     }
1693 }
1694 
1695 /**
1696  * Position sprite on the other one
1697  * @param sprite Pointer to a sprite object
1698  * @param xoffset
1699  * @param yoffset
1700  */
1701 void
pull(sprite_object * sprite,Sint32 xoffset,Sint32 yoffset)1702 sprite_object::pull (sprite_object * sprite, Sint32 xoffset, Sint32 yoffset)
1703 {
1704   x_coord = (sprite->x_coord) + xoffset - (collision_width >> 1);
1705   y_coord = (sprite->y_coord) + yoffset - (collision_height >> 1);
1706 }
1707 
1708 /**
1709  * Position sprite on the other one
1710  * @param sprite Pointer to a sprite object
1711  * @param xoffset
1712  * @param yoffset
1713  */
1714 void
attract(sprite_object * sprite,Sint32 xoffset,Sint32 yoffset)1715 sprite_object::attract (sprite_object * sprite, Sint32 xoffset, Sint32 yoffset)
1716 {
1717   x_coord = (sprite->x_coord) + xoffset
1718     - ((collision_width - sprite->collision_width) >> 1);
1719   y_coord = (sprite->y_coord) + yoffset
1720     - ((collision_height - sprite->collision_height) >> 1);
1721 }
1722 
1723 
1724 /**
1725  * Check collision beetween two sprites
1726  * @param sprite Pointer to a sprite object
1727  * @return true if collision occurs, otherwise false
1728  */
1729 bool
collision(sprite_object * sprite)1730 sprite_object::collision (sprite_object * sprite)
1731 {
1732   Sint32 x1 = x_coord;
1733   Sint32 y1 = y_coord;
1734   Sint32 x2 = sprite->x_coord;
1735   Sint32 y2 = sprite->y_coord;
1736   return (x2 + (Sint32)sprite->collision_width > x1 &&
1737           x2 - (Sint32)collision_width < x1 &&
1738           y2 + (Sint32)sprite->collision_height > y1 &&
1739           y2 - (Sint32)collision_height < y1);
1740 }
1741 
1742 /**
1743  * Check collision beetween a sprite and a segment
1744  * @param sprite Pointer to a sprite object
1745  * @return true if collision occurs, otherwise false
1746  */
1747 bool
collision(Sint32 x1,Sint32 y1,Sint32 x2,Sint32 y2)1748 sprite_object::collision (Sint32 x1, Sint32 y1, Sint32 x2, Sint32 y2)
1749 {
1750   Sint32 xmin, xmax;
1751   Sint32 ymin, ymax;
1752 
1753   /* Swap points for x1 < x2 to be true */
1754   if (x1 > x2)
1755     {
1756       Sint32 tmp = x2;
1757       x2 = x1;
1758       x1 = tmp;
1759 
1760       tmp = y2;
1761       y2 = y1;
1762       y1 = tmp;
1763     }
1764   xmin = x1;
1765   xmax = x2;
1766 
1767   if (y1 < y2)
1768     {
1769       ymin = y1;
1770       ymax = y2;
1771     }
1772   else
1773     {
1774       ymin = y2;
1775       ymax = y1;
1776     }
1777 
1778   /* Condition sine qua none */
1779   if (!(xmin < x_coord + (Sint32)collision_width &&
1780         ymin < y_coord + (Sint32)collision_height &&
1781         xmax > x_coord &&
1782         ymax > y_coord))
1783     {
1784       return false;
1785     }
1786 
1787   /* Both points are in the "vertical band" */
1788   if (xmin > x_coord && xmin < x_coord + (Sint32)collision_width &&
1789       xmax > x_coord && xmax < x_coord + (Sint32)collision_width)
1790     {
1791       return true;
1792     }
1793 
1794   /* Check for diagonals and every remaining cases */
1795   float alpha = (y2 - y1) / (x2 - x1);
1796   Sint32 x0 = -alpha * x1 + y1;
1797 
1798   if (x1 < x_coord)
1799     {
1800       Sint32 ytest = alpha * x_coord + x0;
1801       if (ytest > y_coord && ytest < y_coord + (Sint32)collision_height)
1802         {
1803           return true;
1804         }
1805     }
1806 
1807   if (x2 > x_coord + (Sint32)collision_width)
1808     {
1809       Sint32 ytest = alpha * (x_coord + (Sint32)collision_width) + x0;
1810       if (ytest > y_coord && ytest < y_coord + (Sint32)collision_height)
1811         {
1812           return true;
1813         }
1814     }
1815 
1816   return false;
1817 }
1818 
1819 /**
1820  * Set the frame delay and period, the speed of animation
1821  * @param delay time delay before next image
1822  */
1823 void
set_frame_delay(Sint32 delay)1824 sprite_object::set_frame_delay (Sint32 delay)
1825 {
1826   frame_delay = delay;
1827   frame_period = delay;
1828 }
1829 
1830 /**
1831  * Set the frame period, the speed of animation
1832  * @param period time delay before next image
1833  */
1834 void
set_frame_period(Sint32 period)1835 sprite_object::set_frame_period (Sint32 period)
1836 {
1837   frame_period = period;
1838 }
1839 
1840 /**
1841  * The animation is played once
1842  * @return true if animation is finished
1843  */
1844 bool
play_animation_once()1845 sprite_object::play_animation_once ()
1846 {
1847   if (--frame_delay > 0)
1848     {
1849       return is_enabled;
1850     }
1851   frame_delay = frame_period;
1852   if (frame_index == frame_index_max)
1853     {
1854       frame_index = frame_index_min;
1855       is_enabled = false;
1856     }
1857   else
1858     {
1859       frame_index++;
1860       set_image (frame_index);
1861     }
1862   return is_enabled;
1863 }
1864 
1865 /**
1866  * The animation is played in loop-mode
1867  */
1868 void
play_animation_loop()1869 sprite_object::play_animation_loop ()
1870 {
1871   if (--frame_delay > 0)
1872     {
1873       return;
1874     }
1875   frame_delay = frame_period;
1876   if (frame_index == frame_index_max)
1877     {
1878       frame_index = frame_index_min;
1879       set_image (frame_index);
1880     }
1881   else
1882     {
1883       frame_index++;
1884       set_image (frame_index);
1885     }
1886 }
1887 
1888 /**
1889  * Change the current image of the sprite
1890  * @param index Index of the current image
1891  */
1892 void
new_offset(Sint32 index)1893 sprite_object::new_offset (Sint32 index)
1894 {
1895   frame_index = index;
1896   set_image (index);
1897 }
1898 
1899 /**
1900  * Clip coordinates of the sprite into offscreen coordinates
1901  */
1902 void
clip_coordinates()1903 sprite_object::clip_coordinates ()
1904 {
1905   if (x_coord < 0)
1906     {
1907       x_coord = 0;
1908     }
1909   else if (x_coord > (Sint32)(screen_width - sprite_width))
1910     {
1911       x_coord = screen_width - sprite_width;
1912     }
1913   if (y_coord < 0)
1914     {
1915       y_coord = 0;
1916     }
1917   else if (y_coord > (Sint32)(screen_height - sprite_height))
1918     {
1919       y_coord = screen_height - sprite_height;
1920     }
1921 }
1922 
1923 /**
1924  * Get sprite's width
1925  * @return the width of the sprite in pixels
1926  */
1927 Uint32
get_sprite_width()1928 sprite_object::get_sprite_width ()
1929 {
1930   return sprite_width;
1931 }
1932 
1933 /**
1934  * Get sprite's height
1935  * @return the height of the sprite in pixels
1936  */
1937 Uint32
get_sprite_height()1938 sprite_object::get_sprite_height ()
1939 {
1940   return sprite_height;
1941 }
1942 
1943 /**
1944  * Get sprite's width for collision
1945  * @return the width of sprite for the collisions
1946  */
1947 Uint32
get_collision_width()1948 sprite_object::get_collision_width ()
1949 {
1950   return collision_width;
1951 }
1952 
1953 /**
1954  * Enable the repeat vetical of drawing of the sprite
1955  * used only for the vertical gauge of the guadian's energy level
1956  * @param numof_repeats 2 to n
1957  */
1958 void
enable_vertical_repeat(Uint32 numof_repeats)1959 sprite_object::enable_vertical_repeat (Uint32 numof_repeats)
1960 {
1961   if (numof_repeats < 2)
1962     {
1963       return;
1964     }
1965   num_of_repeats = numof_repeats;
1966   draw_method = DRAW_REPEAT_SPRITE;
1967 }
1968 
1969 /**
1970  * Set the method of displaying used to draw the sprite
1971  * @param method draw method
1972  */
1973 void
set_draw_method(Uint32 method)1974 sprite_object::set_draw_method (Uint32 method)
1975 {
1976   draw_method = method;
1977 }
1978 
1979 /**
1980  * Set pixel data of the sprite
1981  * @param pixel pointer to the pixel data
1982  * @param is_release true if the object must release the
1983  *        pixel data memory at its destruction
1984  */
1985 void
set_pixel_data(char * pixel,bool is_release)1986 sprite_object::set_pixel_data (char *pixel, bool is_release)
1987 {
1988   pixel_data = pixel;
1989   is_release_pixel_data = is_release;
1990 }
1991 
1992 /*
1993  * Statics members
1994  */
1995 
1996 /** Color cylcing from paddle's projectiles of fire 1 */
1997 const Sint32
1998 sprite_object::cycling_01[] =
1999 {
2000   0x7e7e7e7e, 0x7e7e7e7e, 0x4b4b4b4b, 0x4b4b4b4b,
2001   0x7a7a7a7a, 0x7a7a7a7a, 0x18181818, 0x5a5a5a5a
2002 };
2003 /** Color cylcing from paddle's projectiles of fire 2 */
2004 const Sint32
2005 sprite_object::cycling_02[] =
2006 {
2007   0x3f3f3f3f, 0x3f3f3f3f, 0x17171717, 0x17171717, 0x35353535,
2008   0x35353535, 0x18181818, 0x22222222
2009 };
2010 
2011 /** Ship ennemies */
2012 sprite_coordinates
2013 BOB_POS000[] =
2014 {
2015   /* ship 1 */
2016   {0, 70}, {1, 70}, {2, 70}, {3, 70},
2017   {4, 70}, {5, 70}, {6, 70}, {7, 70},
2018   /* ship 2 */
2019   {0, 86}, {1, 86}, {2, 86}, {3, 86},
2020   {4, 86}, {5, 86}, {6, 86}, {7, 86},
2021   /* ship 3 */
2022   {0, 102}, {1, 102}, {2, 102}, {3, 102},
2023   {4, 102}, {5, 102}, {6, 102}, {7, 102},
2024   /* ship 4 */
2025   {0, 118}, {1, 118}, {2, 118}, {3, 118},
2026   {4, 118}, {5, 118}, {6, 118}, {7, 118},
2027   /* ship 5 */
2028   {0, 134}, {1, 134}, {2, 134}, {3, 134},
2029   {4, 134}, {5, 134}, {6, 134}, {7, 134},
2030   /* ship 6 */
2031   {0, 150}, {1, 150}, {2, 150}, {3, 150},
2032   {4, 150}, {5, 150}, {6, 150}, {7, 150},
2033   /* ship 7 */
2034   {0, 166}, {1, 166}, {2, 166}, {3, 166},
2035   {4, 166}, {5, 166}, {6, 166}, {7, 166},
2036   /* ship 8 */
2037   {0, 182}, {1, 182}, {2, 182}, {3, 182},
2038   {4, 182}, {5, 182}, {6, 182}, {7, 182},
2039   /* ship 9 */
2040   {0, 198}, {1, 198}, {2, 198}, {3, 198},
2041   {4, 198}, {5, 198}, {6, 198}, {7, 198},
2042   /* ship 10 */
2043   {0, 214}, {1, 214}, {2, 214}, {3, 214},
2044   {4, 214}, {5, 214}, {6, 214}, {7, 214},
2045   /* ship 11 */
2046   {8, 70}, {9, 70}, {10, 70}, {11, 70},
2047   {12, 70}, {13, 70}, {14, 70}, {15, 70},
2048   /* ship 12 */
2049   {8, 86}, {9, 86}, {10, 86}, {11, 86},
2050   {12, 86}, {13, 86}, {14, 86}, {15, 86},
2051   /* ship 13 */
2052   {8, 102}, {9, 102}, {10, 102}, {11, 102},
2053   {12, 102}, {13, 102}, {14, 102}, {15, 102},
2054   /* ship 14 */
2055   {8, 118}, {9, 118}, {10, 118}, {11, 118},
2056   {12, 118}, {13, 118}, {14, 118}, {14, 118},
2057   /* ship 15 */
2058   {8, 134}, {9, 134}, {10, 134}, {11, 134},
2059   {12, 134}, {13, 134}, {14, 134}, {15, 134},
2060   /* ship 16 */
2061   {8, 150}, {9, 150}, {10, 150}, {11, 150},
2062   {12, 150}, {13, 150}, {14, 150}, {15, 150},
2063   /* ship 17 */
2064   {8, 166}, {9, 166}, {10, 166}, {11, 166},
2065   {12, 166}, {13, 166}, {14, 166}, {15, 166},
2066   /* ship 18 */
2067   {8, 182}, {9, 182}, {10, 182}, {11, 182},
2068   {12, 182}, {13, 182}, {14, 182}, {15, 182},
2069   /* ship 19 */
2070   {8, 198}, {9, 198}, {10, 198}, {11, 198},
2071   {12, 198}, {13, 198}, {14, 198}, {15, 198},
2072   /* ship 20 */
2073   {8, 214}, {9, 214}, {10, 214}, {11, 214},
2074   {12, 214}, {13, 214}, {14, 214}, {15, 214},
2075   /* ship's explosion 1 */
2076   {0, 54}, {1, 54}, {2, 54}, {3, 54},
2077   {4, 54}, {5, 54}, {6, 54}, {7, 54},
2078   /* ship's explosion 2 */
2079   {8, 54}, {9, 54}, {10, 54}, {11, 54},
2080   {12, 54}, {13, 54}, {14, 54}, {15, 54}
2081 };
2082 sprite_description
2083 BOB_NUM000 = { 16, 16, 22 * 8, BOB_POS000 };
2084 
2085 /** Ejectors */
2086 sprite_coordinates
2087 BOB_POS001[] = { {14, 5} };
2088 sprite_description
2089 BOB_NUM001 = { 16, 16, 1, BOB_POS001 };
2090 sprite_coordinates
2091 BOB_POS002[] = { {15, 5} };
2092 sprite_description
2093 BOB_NUM002 = { 16, 16, 1, BOB_POS002 };
2094 sprite_coordinates
2095 BOB_POS003[] = { {16, 5} };
2096 sprite_description
2097 BOB_NUM003 = { 16, 16, 1, BOB_POS003 };
2098 sprite_coordinates
2099 BOB_POS004[] = { {17, 5} };
2100 sprite_description
2101 BOB_NUM004 = { 16, 16, 1, BOB_POS004 };
2102 
2103 /* Bricks */
2104 /** Vertical side brick */
2105 sprite_coordinates
2106 BOB_POS005[] = { {18, 5} };
2107 sprite_description
2108 BOB_NUM005 = { 4, 16, 1, BOB_POS005 };
2109 /** Horizontal side brick */
2110 sprite_coordinates
2111 BOB_POS006[] = { {11, 0} };
2112 sprite_description
2113 BOB_NUM006 = { 16, 4, 1, BOB_POS006 };
2114 sprite_coordinates
2115 /** Standard brick */
2116 BOB_POS007[] = { {14, 21} };
2117 sprite_description
2118 BOB_NUM007 = { 16, 7, 1, BOB_POS007 };
2119 
2120 /** Paddles */
2121 sprite_coordinates
2122 BOB_POS008[28] =
2123 {
2124   {0, 0}, {4, 0}, {8, 0}, {12, 0}, {16, 0}, {20, 0}, {24, 0},
2125   {0, 8}, {4, 8}, {8, 8}, {12, 8}, {16, 8}, {20, 8}, {24, 8},
2126   {0, 16}, {4, 16}, {8, 16}, {12, 16}, {16, 16}, {20, 16}, {24, 16},
2127   {0, 24}, {4, 24}, {8, 24}, {12, 24}, {16, 24}, {20, 24}, {24, 24}
2128 };
2129 sprite_description
2130 BOB_NUM008 = { 64, 8, 28, BOB_POS008 };
2131 sprite_coordinates
2132 BOB_POS009[28] =
2133 { {0, 32}, {1, 32}, {2, 32}, {3, 32}, {4, 32}, {5, 32}, {6, 32},
2134   {7, 32}, {8, 32}, {9, 32}, {10, 32}, {11, 32}, {12, 32}, {13, 32},
2135   {14, 32}, {15, 32}, {16, 32}, {17, 32}, {18, 32}, {19, 32}, {20, 32},
2136   {21, 32}, {22, 32}, {23, 32}, {24, 32}, {25, 32}, {26, 32}, {27, 32}
2137 };
2138 sprite_description
2139 BOB_NUM009 = { 8, 64, 28, BOB_POS009 };
2140 
2141 /** The seven gigablitz */
2142 sprite_coordinates
2143 BOB_POS021[1] = { {0, 0} };
2144 sprite_description
2145 BOB_NUM021 = { 16, 32, 1, BOB_POS021 };
2146 
2147 sprite_coordinates
2148 BOB_POS022[1] = { {0, 32} };
2149 sprite_description
2150 BOB_NUM022 = { 24, 48, 1, BOB_POS022 };
2151 
2152 sprite_coordinates
2153 BOB_POS023[1] = { {0, 80} };
2154 sprite_description
2155 BOB_NUM023 = { 32, 64, 1, BOB_POS023 };
2156 
2157 sprite_coordinates
2158 BOB_POS024[1] = { {0, 144} };
2159 sprite_description
2160 BOB_NUM024 = { 40, 80, 1, BOB_POS024 };
2161 
2162 sprite_coordinates
2163 BOB_POS025[1] = { {0, 224} };
2164 sprite_description
2165 BOB_NUM025 = { 48, 96, 1, BOB_POS025 };
2166 
2167 sprite_coordinates
2168 BOB_POS026[1] = { {0, 320} };
2169 sprite_description
2170 BOB_NUM026 = { 56, 112, 1, BOB_POS026 };
2171 
2172 sprite_coordinates
2173 BOB_POS027[1] = { {0, 432} };
2174 sprite_description
2175 BOB_NUM027 = { 64, 128, 1, BOB_POS027 };
2176 
2177 /** Balls */
2178 sprite_coordinates
2179 BOB_POS010[] =
2180 {
2181   /* size 1 green ball */
2182   {14, 46},
2183   /* size 1 grey ball */
2184   {1, 497},
2185   /* size 1 yellow ball */
2186   {14, 28},
2187   /* size 2 green ball */
2188   {15, 37},
2189   /* size 2 grey ball */
2190   {2, 497},
2191   /* size 2 yellow ball */
2192   {15, 28},
2193   /* size 3 green ball */
2194   {3, 488},
2195   /* size 3 grey ball */
2196   {3, 497},
2197   /* size 3 yellow ball */
2198   {14, 37}
2199 };
2200 sprite_description
2201 BOB_NUM010 = { 9, 9, 9, BOB_POS010 };
2202 
2203 /** Projectiles fired by a paddle in bricks level */
2204 sprite_coordinates
2205 BOB_POS011[] =
2206 {
2207   /* projectile used for the fire power 1 */
2208   {3, 0},
2209   {4, 0},
2210   {5, 0},
2211   {6, 0},
2212   /* projectile used for the fire power 2 */
2213   {7, 0},
2214   {8, 0},
2215   {9, 0},
2216   {10, 0}
2217 };
2218 sprite_description
2219 BOB_NUM011 = { 5, 5, 8, BOB_POS011 };
2220 
2221 /** The money capsule */
2222 sprite_coordinates
2223 BOB_POS012[] =
2224   { {7, 33}, {8, 33}, {9, 33}, {10, 33}, {11, 33}, {12, 33}, {13, 33} };
2225 sprite_description
2226 BOB_NUM012 = { 16, 7, 7, BOB_POS012 };
2227 
2228 /** Capsule bonuses or a penalties */
2229 sprite_coordinates
2230 BOB_POS013[] =
2231 {
2232   /* expand paddles */
2233   {0, 5}, {1, 5}, {2, 5}, {3, 5}, {4, 5}, {5, 5}, {6, 5},
2234   /* shrink paddles */
2235   {0, 12}, {1, 12}, {2, 12}, {3, 12}, {4, 12}, {5, 12}, {6, 12},
2236   /* extra life */
2237   {0, 19}, {1, 19}, {2, 19}, {3, 19}, {4, 19}, {5, 19}, {6, 19},
2238   /* lose a life */
2239   {0, 26}, {1, 26}, {2, 26}, {3, 26}, {4, 26}, {5, 26}, {6, 26},
2240   /* power ball 1 */
2241   {0, 33}, {1, 33}, {2, 33}, {3, 33}, {4, 33}, {5, 33}, {6, 33},
2242   /* power ball 2 */
2243   {0, 40}, {1, 40}, {2, 40}, {3, 40}, {4, 40}, {5, 40}, {6, 40},
2244   /* extra balls */
2245   {0, 47}, {1, 47}, {2, 47}, {3, 47}, {4, 47}, {5, 47}, {6, 47},
2246   /* multi balls */
2247   {7, 5}, {8, 5}, {9, 5}, {10, 5}, {11, 5}, {12, 5}, {13, 5},
2248   /* fire power 1 */
2249   {7, 12}, {8, 12}, {9, 12}, {10, 12}, {11, 12}, {12, 12}, {13, 12},
2250   /* fire power 2 */
2251   {7, 19}, {8, 19}, {9, 19}, {10, 19}, {11, 19}, {12, 19}, {13, 19},
2252   /* glue */
2253   {7, 26}, {8, 26}, {9, 26}, {10, 26}, {11, 26}, {12, 26}, {13, 26},
2254   /* inverse control */
2255   {7, 40}, {8, 40}, {9, 40}, {10, 40}, {11, 40}, {12, 40}, {13, 40},
2256   /* balls size 2 */
2257   {17, 219}, {18, 219}, {18, 246}, {19, 246}, {19, 261}, {19, 239}, {16, 268},
2258   /* balls size 3 */
2259   {17, 268}, {18, 268}, {19, 268}, {10, 481}, {11, 481}, {12, 481}, {13, 481},
2260   /* chance capsule */
2261   {14, 392}, {14, 399}, {14, 406}, {14, 413}, {14, 420}, {14, 427}, {14, 434},
2262   /* enable hugely options */
2263   {15, 392}, {15, 399}, {15, 406}, {15, 413}, {15, 420}, {15, 427}, {15, 434},
2264   /* enable bottom wall */
2265   {0, 635}, {1, 635}, {2, 635}, {3, 635}, {4, 635}, {5, 635}, {6, 635},
2266   /* enable bottom robot paddle */
2267   {7, 635}, {8, 635}, {9, 635}, {10, 635}, {11, 635}, {12, 635}, {13, 635},
2268   /* enable the balls control */
2269   {14, 635}, {15, 635}, {16, 635}, {17, 635}, {18, 635}, {19, 635}, {2, 490},
2270   /* paddle invincibility (only used in guardians level */
2271   {16, 205}, {17, 205}, {18, 205}, {16, 212}, {17, 212}, {18, 212}, {16, 219}
2272 };
2273 sprite_description
2274 BOB_NUM013 = { 16, 7, 7 * 20, BOB_POS013 };
2275 
2276 /** font of 43 chars used to display "LEVEL n COMPLETED */
2277 sprite_coordinates
2278 BOB_POS014[] =
2279   { {0, 758}, {1, 758}, {2, 758}, {3, 758}, {4, 758}, {5, 758}, {6, 758}, {7,
2280       758},
2281     {8, 758}, {9, 758},
2282     {10, 758}, {11, 758}, {12, 758}, {13, 758}, {14, 758}, {15, 758}, {16, 758},
2283     {17, 758}, {18, 758}, {19, 758},
2284     {0, 774}, {1, 774}, {2, 774}, {3, 774}, {4, 774}, {5, 774}, {6, 774}, {7,
2285         774},
2286     {8, 774}, {9, 774},
2287     {10, 774}, {11, 774}, {12, 774}, {13, 774}, {14, 774}, {15, 774}, {16, 774},
2288     {17, 774}, {18, 774}, {19, 774},
2289     {0, 790}, {1, 790}, {2, 790}
2290   };
2291 sprite_description
2292 BOB_NUM014 = { 16, 16, 42, BOB_POS014 };
2293 
2294 // LED du magasin --------------------------------------------------------------
2295 sprite_coordinates
2296 BOB_POS015[] = { {13, 0} };
2297 sprite_description
2298 BOB_NUM015 = { 16, 3, 1, BOB_POS015 };
2299 sprite_coordinates
2300 BOB_POS057[] = { {15, 0} };
2301 sprite_description
2302 BOB_NUM057 = { 16, 5, 1, BOB_POS057 };
2303 
2304 /** GAME OVER letters */
2305 sprite_coordinates
2306 BOB_POS016[] =
2307 {
2308   /* G */
2309   {0, 246},
2310   /* A */
2311   {2, 246},
2312   /* M */
2313   {4, 246},
2314   /* E */
2315   {6, 246},
2316   /* O */
2317   {8, 246},
2318   /* V */
2319   {10, 246},
2320   /* E */
2321   {12, 246},
2322   /* R */
2323   {14, 246}
2324 };
2325 sprite_description
2326 BOB_NUM016 = { 32, 32, 8, BOB_POS016 };
2327 
2328 /** Font used in the main menu scrolltext */
2329 sprite_coordinates
2330 BOB_POS017[43] =
2331 {
2332   {0, 587}, {1, 587}, {2, 587}, {3, 587}, {4, 587},
2333   {5, 587}, {6, 587}, {7, 587}, {8, 587}, {9, 587},
2334   {10, 587}, {11, 587}, {12, 587}, {13, 587}, {14, 587},
2335   {15, 587}, {16, 587}, {17, 587}, {18, 587}, {19, 587},
2336   {0, 607}, {1, 607}, {2, 607}, {3, 607}, {4, 607},
2337   {5, 607}, {6, 607}, {7, 607}, {8, 607}, {9, 607},
2338   {10, 607}, {11, 607}, {12, 607}, {13, 607}, {14, 607},
2339   {15, 607}, {16, 607}, {17, 607}, {18, 607}, {19, 607},
2340   {17, 520}, {18, 520}, {16, 520}
2341 };
2342 sprite_description
2343 BOB_NUM017 = { 16, 20, 43, BOB_POS017 };
2344 
2345 /** TecnoballZ logo */
2346 sprite_coordinates
2347 BOB_POS018[1] = { {0, 520} };
2348 sprite_description
2349 BOB_NUM018 = { 256, 67, 1, BOB_POS018 };
2350 
2351 /** Mouse cursor pointer 1 */
2352 sprite_coordinates
2353 BOB_POS019[8] =
2354 {
2355   {0, 230}, {1, 230}, {2, 230}, {3, 230},
2356   {4, 230}, {5, 230}, {6, 230}, {7, 230}
2357 };
2358 sprite_description
2359 BOB_NUM019 = { 16, 16, 8, BOB_POS019 };
2360 /** Mouse cursor pointer 2 */
2361 sprite_coordinates
2362 BOB_POS020[8] =
2363 {
2364   {8, 230}, {9, 230}, {10, 230}, {11, 230},
2365   {12, 230}, {13, 230}, {14, 230}, {15, 230}
2366 };
2367 sprite_description
2368 BOB_NUM020 = { 16, 16, 8, BOB_POS020 };
2369 
2370 // lettre pour afficher la somme d'argent --------------------------------------
2371 sprite_coordinates
2372 BOB_POS028[10] = { {3, 798}, {4, 798}, {5, 798}, {6, 798}, {7, 798},
2373                    {8, 798}, {9, 798}, {10, 798}, {11, 798}, {12, 798}
2374                  };
2375 sprite_description
2376 BOB_NUM028 = { 8, 8, 10, BOB_POS028 };
2377 
2378 /** Bottom paddle robot used in bricks level */
2379 sprite_coordinates
2380 BOB_POS029[1] = { {16, 448} };
2381 sprite_description
2382 BOB_NUM029 = { 64, 8, 1, BOB_POS029 };
2383 
2384 /*
2385  * GUARDIANS
2386  */
2387 sprite_coordinates
2388 BOB_POS030[1] = { {0, 278} };
2389 sprite_description
2390 BOB_NUM030 = { 64, 104, 1, BOB_POS030 };
2391 sprite_coordinates
2392 BOB_POS031[1] = { {4, 278} };
2393 sprite_description
2394 BOB_NUM031 = { 64, 99, 1, BOB_POS031 };
2395 sprite_coordinates
2396 BOB_POS032[1] = { {8, 278} };
2397 sprite_description
2398 BOB_NUM032 = { 64, 90, 1, BOB_POS032 };
2399 sprite_coordinates
2400 BOB_POS033[1] = { {8, 368} };
2401 sprite_description
2402 BOB_NUM033 = { 64, 92, 1, BOB_POS033 };
2403 sprite_coordinates
2404 BOB_POS034[1] = { {12, 278} };
2405 sprite_description
2406 BOB_NUM034 = { 64, 114, 1, BOB_POS034 };
2407 sprite_coordinates
2408 BOB_POS035[1] = { {16, 278} };
2409 sprite_description
2410 BOB_NUM035 = { 64, 163, 1, BOB_POS035 };
2411 sprite_coordinates
2412 BOB_POS036[1] = { {0, 382} };
2413 sprite_description
2414 BOB_NUM036 = { 32, 16, 1, BOB_POS036 };
2415 sprite_coordinates
2416 BOB_POS037[1] = { {0, 398} };
2417 sprite_description
2418 BOB_NUM037 = { 32, 55, 1, BOB_POS037 };
2419 sprite_coordinates
2420 BOB_POS038[1] = { {0, 453} };
2421 sprite_description
2422 BOB_NUM038 = { 32, 36, 1, BOB_POS038 };
2423 sprite_coordinates
2424 BOB_POS039[1] = { {2, 382} };
2425 sprite_description
2426 BOB_NUM039 = { 32, 52, 1, BOB_POS039 };
2427 sprite_coordinates
2428 BOB_POS040[1] = { {2, 434} };
2429 sprite_description
2430 BOB_NUM040 = { 32, 36, 1, BOB_POS040 };
2431 sprite_coordinates
2432 BOB_POS041[1] = { {4, 377} };
2433 sprite_description
2434 BOB_NUM041 = { 32, 82, 1, BOB_POS041 };
2435 sprite_coordinates
2436 BOB_POS042[1] = { {4, 459} };
2437 sprite_description
2438 BOB_NUM042 = { 32, 47, 1, BOB_POS042 };
2439 sprite_coordinates
2440 BOB_POS043[1] = { {6, 377} };
2441 sprite_description
2442 BOB_NUM043 = { 32, 74, 1, BOB_POS043 };
2443 sprite_coordinates
2444 BOB_POS044[1] = { {6, 451} };
2445 sprite_description
2446 BOB_NUM044 = { 32, 65, 1, BOB_POS044 };
2447 sprite_coordinates
2448 BOB_POS045[1] = { {12, 392} };
2449 sprite_description
2450 BOB_NUM045 = { 32, 85, 1, BOB_POS045 };
2451 /* paddle */
2452 sprite_coordinates
2453 BOB_POS046[1] = { {16, 246} };
2454 sprite_description
2455 BOB_NUM046 = { 32, 8, 1, BOB_POS046 };
2456 /* bullet fired by a guardian */
2457 sprite_coordinates
2458 BOB_POS047[16] =
2459   { {19, 141}, {8, 460}, {19, 152}, {9, 460}, {19, 163}, {10, 460}, {19, 174},
2460     {11, 460},
2461     {19, 185}, {8, 471}, {19, 196}, {9, 471}, {19, 207}, {16, 573}, {19, 218},
2462     {17, 573}
2463   };
2464 sprite_description
2465 BOB_NUM047 = { 11, 11, 16, BOB_POS047 };
2466 
2467 
2468 // explosion 1 ****
2469 sprite_coordinates
2470 BOB_POS048[8] = { {0, 54}, {1, 54}, {2, 54}, {3, 54},   //EXPLOSION 1
2471                   {4, 54}, {5, 54}, {6, 54}, {7, 54}
2472                 };
2473 sprite_description
2474 BOB_NUM048 = { 16, 16, 8, BOB_POS048 };
2475 
2476 // explosion 2 ****
2477 sprite_coordinates
2478 BOB_POS049[8] = { {8, 54}, {9, 54}, {10, 54}, {11, 54}, //EXPLOSION 2
2479                   {12, 54}, {13, 54}, {14, 54}, {15, 54}
2480                 };
2481 sprite_description
2482 BOB_NUM049 = { 16, 16, 8, BOB_POS049 };
2483 
2484 // boule argentee (congratulation)
2485 sprite_coordinates
2486 BOB_POS050[8] = { {14, 462} };
2487 sprite_description
2488 BOB_NUM050 = { 25, 26, 1, BOB_POS050 };
2489 
2490 // niveau d'energie des gadiens --------------------------------------//
2491 sprite_coordinates
2492 BOB_POS051[] = { {14, 0} };
2493 sprite_description
2494 BOB_NUM051 = { 16, 1, 1, BOB_POS051 };
2495 
2496 // gem ---------------------------------------------------------------//
2497 sprite_coordinates
2498 BOB_POS052[] = { {10, 472},     // grey square
2499                  {11, 472},                      // green sphere
2500                  {18, 574},                      // yellow ring
2501                  {19, 574},                      // blue triangle
2502                  {3, 480},                       // rhombus
2503                  {3, 472}                        // pentagon
2504                };
2505 sprite_description
2506 BOB_NUM052 = { 8, 8, 6, BOB_POS052 };
2507 
2508 // bottom wall -------------------------------------------------------//
2509 sprite_coordinates
2510 BOB_POS053[] = { {0, 627} };
2511 sprite_description
2512 BOB_NUM053 = { 192, 8, 1, BOB_POS053 };
2513 
2514 sprite_coordinates
2515 BOB_POS054[] = { {4, 730}, {5, 730}, {6, 730}, {7, 730},
2516                  {8, 730}, {9, 730}, {10, 730}, {11, 730},
2517                  {12, 730}, {13, 730}, {14, 730}, {15, 730},
2518                  {16, 730}, {17, 730}, {18, 730}, {19, 730},
2519                };
2520 sprite_description
2521 BOB_NUM054 = { 9, 9, 16, BOB_POS054 };
2522 
2523 sprite_coordinates
2524 BOB_POS055[] = { {16, 21}, {17, 21}, {18, 21}, {19, 21}, {16, 25}, {17, 25},
2525                  {18, 25}, {19, 25}
2526                };
2527 sprite_description
2528 BOB_NUM055 = { 4, 4, 8, BOB_POS055 };
2529 
2530 sprite_coordinates
2531 BOB_POS056[] =
2532   { {0, 642}, {2, 642}, {4, 642}, {6, 642}, {8, 642}, {10, 642}, {12, 642},
2533     {14, 642}, {16, 642}, {18, 642},
2534     {0, 671}, {2, 671}, {4, 671}, {6, 671}, {8, 671}, {10, 671}, {12, 671}, {14,
2535         671},
2536     {16, 671}, {18, 671},
2537     {0, 700}, {2, 700}, {4, 700}, {6, 700}, {8, 700}, {10, 700}, {12, 700}, {14,
2538         700},
2539     {16, 700}, {18, 700},
2540     {0, 729}, {2, 729}
2541   };
2542 sprite_description
2543 BOB_NUM056 = { 32, 29, 32, BOB_POS056 };
2544 
2545 // bricks
2546 sprite_coordinates
2547 BOB_POS058[] =
2548   {
2549     {0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0}, {6, 0},
2550     {0, 7}, {1, 7}, {2, 7}, {3, 7}, {4, 7}, {5, 7}, {6, 7},
2551     {0, 14}, {1, 14}, {2, 14}, {3, 14}, {4, 14}, {5, 14}, {6, 14},
2552     {0, 21}, {1, 21}, {2, 21}, {3, 21}, {4, 21}, {5, 21}, {6, 21},
2553     {0, 28}, {1, 28}, {2, 28}, {3, 28}, {4, 28}, {5, 28}, {6, 28},
2554     {0, 35}, {1, 35}, {2, 35}, {3, 35}, {4, 35}, {5, 35}, {6, 35},
2555     {0, 42}, {1, 42}, {2, 42}, {3, 42}, {4, 42}, {5, 42}, {6, 42},
2556     {0, 49}, {1, 49}, {2, 49}, {3, 49}, {4, 49}, {5, 49}, {6, 49},
2557     {0, 56}, {1, 56}, {2, 56}, {3, 56}, {4, 56}, {5, 56}, {6, 56}
2558   };
2559 sprite_description
2560 BOB_NUM058 = { 16, 7, 63, BOB_POS058 };
2561 
2562 const sprite_description *
2563 sprite_object::zelistBOB[NUMOF_SPRITE_TYPES] =
2564   {
2565     &BOB_NUM000,   // BouisBouis
2566     &BOB_NUM001,                  // Ejector
2567     &BOB_NUM002,                  //
2568     &BOB_NUM003,                  //
2569     &BOB_NUM004,                  //
2570     &BOB_NUM005,                  // Brique verticale
2571     &BOB_NUM006,                  // Brique horizontale
2572     &BOB_NUM007,                  // Brique jeu
2573     &BOB_NUM008,                  // Raquette horizontale
2574     &BOB_NUM009,                  // Raquette verticale
2575     &BOB_NUM010,                  // Balls
2576     &BOB_NUM011,                  // Bumper's fires
2577     &BOB_NUM012,                  // Capsule of money
2578     &BOB_NUM013,                  // Gadgets (bonuses or maluses)
2579     &BOB_NUM014,                  // Lettres (annonce)
2580     &BOB_NUM015,                  // shop's led (low-res)
2581     &BOB_NUM016,                  // Lettres GameOver
2582     &BOB_NUM017,                  // Lettres defilement menu
2583     &BOB_NUM018,                  // Logo TecnoballZ
2584     &BOB_NUM019,                  // Pointeur souris 1
2585     &BOB_NUM020,                  // Pointeur souris 2
2586     &BOB_NUM021,                  // GigaBlitz 1
2587     &BOB_NUM022,                  // GigaBlitz 2
2588     &BOB_NUM023,                  // GigaBlitz 3
2589     &BOB_NUM024,                  // GigaBlitz 4
2590     &BOB_NUM025,                  // GigaBlitz 5
2591     &BOB_NUM026,                  // GigaBlitz 6
2592     &BOB_NUM027,                  // GigaBlitz 7
2593     &BOB_NUM028,                  // Chiffres de 0 a 10 pour afficher le credit
2594     &BOB_NUM029,                  // Robot bottom bumper (bricks levels)
2595     &BOB_NUM030,                  // Guard final 1
2596     &BOB_NUM031,                  // Guard final 2
2597     &BOB_NUM032,                  // Guard final 3
2598     &BOB_NUM033,                  // Guard final 4
2599     &BOB_NUM034,                  // Guard final 5
2600     &BOB_NUM035,                  // Guard final 6
2601     &BOB_NUM036,                  // Guard intermediary 1
2602     &BOB_NUM037,                  // Guard intermediary 1
2603     &BOB_NUM038,                  // Guard intermediary 2
2604     &BOB_NUM039,                  // Guard intermediary 2
2605     &BOB_NUM040,                  // Guard intermediary 3
2606     &BOB_NUM041,                  // Guard intermediary 3
2607     &BOB_NUM042,                  // Guard intermediary 4
2608     &BOB_NUM043,                  // Guard intermediary 4
2609     &BOB_NUM044,                  // Guard intermediary 5
2610     &BOB_NUM045,                  // Guard intermediary 5
2611     &BOB_NUM046,                  // bumper into guards level
2612     &BOB_NUM047,                  // Guards's weapeon
2613     &BOB_NUM048,                  // explosion's guard (type 1)
2614     &BOB_NUM049,                  // explosion's guard (type 2)
2615     &BOB_NUM050,                  // boule argentee
2616     &BOB_NUM051,                  // guards's energy bar
2617     &BOB_NUM052,                  // Gem
2618     &BOB_NUM053,
2619     &BOB_NUM054,                  //directeur
2620     &BOB_NUM055,                  //echape menu
2621     &BOB_NUM056,                  //maget eye
2622     &BOB_NUM057,                  //shop's led (high-res)
2623     &BOB_NUM058                  //brick
2624   };
2625 
2626 
2627 Sint32 sprite_object::ombredecax = handler_display::SHADOWOFFX;
2628 Sint32 sprite_object::ombredecay = handler_display::SHADOWOFFY;
2629 char sprite_object::ombrepixel = handler_display::SHADOW_PIX;
2630 Sint32 sprite_object::ombrepixe4 = handler_display::SHADOWLONG;
2631