summaryrefslogtreecommitdiff
path: root/viewport.c
diff options
context:
space:
mode:
authorhackykid <hackykid@openttd.org>2005-06-15 14:04:48 +0000
committerhackykid <hackykid@openttd.org>2005-06-15 14:04:48 +0000
commit85fae22fa8b2e35099fcd699409b4b3606d99835 (patch)
treead8dc8d67b116abad947f1fbce0ddec95b8e2dc8 /viewport.c
parentd2869fbb5f8c8f94abe4ac8ca0cefaf1ec3a2739 (diff)
downloadopenttd-85fae22fa8b2e35099fcd699409b4b3606d99835.tar.xz
(svn r2440) - Fix: [newgrf] Fix the spritesorter to handle overlapping sprites properly, this fixes display problems with really short wagons. (algorithm by patchman, ported by therax)
- Fix: [newgrf] Too short wagons could break the 'follow next vehicle' code used in the traincontroller. Clamp better to prevent this.
Diffstat (limited to 'viewport.c')
-rw-r--r--viewport.c35
1 files changed, 28 insertions, 7 deletions
diff --git a/viewport.c b/viewport.c
index b58d5da98..be0bbcf6e 100644
--- a/viewport.c
+++ b/viewport.c
@@ -1079,16 +1079,37 @@ static void ViewportSortParentSprites(ParentSpriteToDraw **psd)
psd2 = psd;
while ( (ps2=*++psd2) != NULL) {
+ bool mustswap = false;
+
if (ps2->unk16 & 1)
continue;
- if (ps->tile_right >= ps2->tile_x &&
- ps->tile_bottom >= ps2->tile_y &&
- ps->tile_z_bottom >= ps2->tile_z && (
- ps->tile_x >= ps2->tile_right ||
- ps->tile_y >= ps2->tile_bottom ||
- ps->tile_z >= ps2->tile_z_bottom
- )) {
+ // Decide which sort order algorithm to use, based on whether the sprites have some overlapping area.
+ if (((ps2->tile_x > ps->tile_x && ps2->tile_x < ps->tile_right) ||
+ (ps2->tile_right > ps->tile_x && ps2->tile_x < ps->tile_right)) && // overlap in X
+ ((ps2->tile_y > ps->tile_y && ps2->tile_y < ps->tile_bottom) ||
+ (ps2->tile_bottom > ps->tile_y && ps2->tile_y < ps->tile_bottom)) && // overlap in Y
+ ((ps2->tile_z > ps->tile_z && ps2->tile_z < ps->tile_z_bottom) ||
+ (ps2->tile_z_bottom > ps->tile_z && ps2->tile_z < ps->tile_z_bottom)) ) { // overlap in Z
+ // Sprites overlap.
+ // Use X+Y+Z as the sorting order, so sprites nearer the bottom of the screen,
+ // and with higher Z elevation, draw in front.
+ // Here X,Y,Z are the coordinates of the "center of mass" of the sprite,
+ // i.e. X=(left+right)/2, etc.
+ // However, since we only care about order, don't actually calculate the division / 2.
+ mustswap = ps->tile_x + ps->tile_right + ps->tile_y + ps->tile_bottom + ps->tile_z + ps->tile_z_bottom >
+ ps2->tile_x + ps2->tile_right + ps2->tile_y + ps2->tile_bottom + ps2->tile_z + ps2->tile_z_bottom;
+ } else {
+ // No overlap; use the original TTD sort algorithm.
+ mustswap = (ps->tile_right >= ps2->tile_x &&
+ ps->tile_bottom >= ps2->tile_y &&
+ ps->tile_z_bottom >= ps2->tile_z &&
+ (ps->tile_x >= ps2->tile_right ||
+ ps->tile_y >= ps2->tile_bottom ||
+ ps->tile_z >= ps2->tile_z_bottom));
+ }
+ if (mustswap) {
+ // Swap the two sprites ps and ps2 using bubble-sort algorithm.
psd3 = psd;
do {
ps3 = *psd3;