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