513 void AddSortableSpriteToDraw(SpriteID image, SpriteID pal, int x, int y, int w, int h, int dz, int z, bool transparent, int bb_offset_x, int bb_offset_y, int bb_offset_z) |
513 void AddSortableSpriteToDraw(SpriteID image, SpriteID pal, int x, int y, int w, int h, int dz, int z, bool transparent, int bb_offset_x, int bb_offset_y, int bb_offset_z) |
514 { |
514 { |
515 ViewportDrawer *vd = _cur_vd; |
515 ViewportDrawer *vd = _cur_vd; |
516 ParentSpriteToDraw *ps; |
516 ParentSpriteToDraw *ps; |
517 Point pt; |
517 Point pt; |
518 int32 right, bottom; |
518 int32 left, right, top, bottom; |
519 |
519 |
520 assert((image & SPRITE_MASK) < MAX_SPRITES); |
520 assert((image & SPRITE_MASK) < MAX_SPRITES); |
521 |
521 |
522 /* make the sprites transparent with the right palette */ |
522 /* make the sprites transparent with the right palette */ |
523 if (transparent) { |
523 if (transparent) { |
550 } |
550 } |
551 |
551 |
552 pt = RemapCoords(x, y, z); |
552 pt = RemapCoords(x, y, z); |
553 ps->x = pt.x; |
553 ps->x = pt.x; |
554 ps->y = pt.y; |
554 ps->y = pt.y; |
|
555 |
|
556 /* Compute screen extents of sprite */ |
555 if (image == SPR_EMPTY_BOUNDING_BOX) { |
557 if (image == SPR_EMPTY_BOUNDING_BOX) { |
556 ps->left = RemapCoords(x + w , y + bb_offset_y, z + bb_offset_z).x; |
558 left = ps->left = RemapCoords(x + w , y + bb_offset_y, z + bb_offset_z).x; |
557 right = RemapCoords(x + bb_offset_x, y + h , z + bb_offset_z).x; |
559 right = RemapCoords(x + bb_offset_x, y + h , z + bb_offset_z).x + 1; |
558 ps->top = RemapCoords(x + bb_offset_x, y + bb_offset_y, z + dz ).y; |
560 top = ps->top = RemapCoords(x + bb_offset_x, y + bb_offset_y, z + dz ).y; |
559 bottom = RemapCoords(x + w , y + h , z + bb_offset_z).y; |
561 bottom = RemapCoords(x + w , y + h , z + bb_offset_z).y + 1; |
560 } else { |
562 } else { |
561 const Sprite *spr = GetSprite(image & SPRITE_MASK); |
563 const Sprite *spr = GetSprite(image & SPRITE_MASK); |
562 ps->left = (pt.x += spr->x_offs); |
564 left = ps->left = (pt.x += spr->x_offs); |
563 right = (pt.x + spr->width ); |
565 right = (pt.x + spr->width ); |
564 ps->top = (pt.y += spr->y_offs); |
566 top = ps->top = (pt.y += spr->y_offs); |
565 bottom = (pt.y + spr->height); |
567 bottom = (pt.y + spr->height); |
566 } |
568 } |
567 if (ps->left >= vd->dpi.left + vd->dpi.width || |
569 if (_draw_bounding_boxes && (image != SPR_EMPTY_BOUNDING_BOX)) { |
568 right <= vd->dpi.left || |
570 /* Compute maximal extents of sprite and it's bounding box */ |
569 ps->top >= vd->dpi.top + vd->dpi.height || |
571 left = min(left , RemapCoords(x + w , y + bb_offset_y, z + bb_offset_z).x); |
570 bottom <= vd->dpi.top) { |
572 right = max(right , RemapCoords(x + bb_offset_x, y + h , z + bb_offset_z).x + 1); |
|
573 top = min(top , RemapCoords(x + bb_offset_x, y + bb_offset_y, z + dz ).y); |
|
574 bottom = max(bottom, RemapCoords(x + w , y + h , z + bb_offset_z).y + 1); |
|
575 } |
|
576 /* Do not add the sprite to the viewport, if it is outside */ |
|
577 if (left >= vd->dpi.left + vd->dpi.width || |
|
578 right <= vd->dpi.left || |
|
579 top >= vd->dpi.top + vd->dpi.height || |
|
580 bottom <= vd->dpi.top) { |
571 return; |
581 return; |
572 } |
582 } |
573 |
583 |
574 vd->spritelist_mem += sizeof(ParentSpriteToDraw); |
584 vd->spritelist_mem += sizeof(ParentSpriteToDraw); |
575 |
585 |
614 DEBUG(sprite, 0, "Out of sprite memory"); |
624 DEBUG(sprite, 0, "Out of sprite memory"); |
615 return; |
625 return; |
616 } |
626 } |
617 cs = (ChildScreenSpriteToDraw*)vd->spritelist_mem; |
627 cs = (ChildScreenSpriteToDraw*)vd->spritelist_mem; |
618 |
628 |
|
629 /* If the ParentSprite was clipped by the viewport bounds, do not draw the ChildSprites either */ |
619 if (vd->last_child == NULL) return; |
630 if (vd->last_child == NULL) return; |
620 |
631 |
621 vd->spritelist_mem += sizeof(ChildScreenSpriteToDraw); |
632 vd->spritelist_mem += sizeof(ChildScreenSpriteToDraw); |
622 |
633 |
623 *vd->last_child = cs; |
634 *vd->last_child = cs; |
1230 DrawSprite(cs->image, cs->pal, ps->left + cs->x, ps->top + cs->y); |
1241 DrawSprite(cs->image, cs->pal, ps->left + cs->x, ps->top + cs->y); |
1231 } |
1242 } |
1232 } |
1243 } |
1233 } |
1244 } |
1234 |
1245 |
|
1246 /** |
|
1247 * Draws the bounding boxes of all ParentSprites |
|
1248 * @param psd Array of ParentSprites |
|
1249 */ |
|
1250 static void ViewportDrawBoundingBoxes(ParentSpriteToDraw *psd[]) |
|
1251 { |
|
1252 for (; *psd != NULL; psd++) { |
|
1253 const ParentSpriteToDraw* ps = *psd; |
|
1254 Point pt1 = RemapCoords(ps->xmax + 1, ps->ymax + 1, ps->zmax + 1); // top front corner |
|
1255 Point pt2 = RemapCoords(ps->xmin , ps->ymax + 1, ps->zmax + 1); // top left corner |
|
1256 Point pt3 = RemapCoords(ps->xmax + 1, ps->ymin , ps->zmax + 1); // top right corner |
|
1257 Point pt4 = RemapCoords(ps->xmax + 1, ps->ymax + 1, ps->zmin ); // bottom front corner |
|
1258 |
|
1259 DrawBox( pt1.x, pt1.y, |
|
1260 pt2.x - pt1.x, pt2.y - pt1.y, |
|
1261 pt3.x - pt1.x, pt3.y - pt1.y, |
|
1262 pt4.x - pt1.x, pt4.y - pt1.y); |
|
1263 } |
|
1264 } |
|
1265 |
1235 static void ViewportDrawStrings(DrawPixelInfo *dpi, const StringSpriteToDraw *ss) |
1266 static void ViewportDrawStrings(DrawPixelInfo *dpi, const StringSpriteToDraw *ss) |
1236 { |
1267 { |
1237 DrawPixelInfo dp; |
1268 DrawPixelInfo dp; |
1238 ZoomLevel zoom; |
1269 ZoomLevel zoom; |
1239 |
1270 |
1353 /* null terminate parent sprite list */ |
1384 /* null terminate parent sprite list */ |
1354 *vd.parent_list = NULL; |
1385 *vd.parent_list = NULL; |
1355 |
1386 |
1356 ViewportSortParentSprites(parent_list); |
1387 ViewportSortParentSprites(parent_list); |
1357 ViewportDrawParentSprites(parent_list); |
1388 ViewportDrawParentSprites(parent_list); |
|
1389 if (_draw_bounding_boxes) ViewportDrawBoundingBoxes(parent_list); |
1358 |
1390 |
1359 if (vd.first_string != NULL) ViewportDrawStrings(&vd.dpi, vd.first_string); |
1391 if (vd.first_string != NULL) ViewportDrawStrings(&vd.dpi, vd.first_string); |
1360 |
1392 |
1361 _cur_dpi = old_dpi; |
1393 _cur_dpi = old_dpi; |
1362 } |
1394 } |