Changeset - r1934:c0ae769fa723
[Not reviewed]
master
0 2 0
hackykid - 19 years ago 2005-06-15 14:04:48
hackykid@openttd.org
(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.
2 files changed with 29 insertions and 8 deletions:
0 comments (0 inline, 0 general)
train_cmd.c
Show inline comments
 
@@ -116,13 +116,13 @@ void TrainConsistChanged(Vehicle *v) {
 
		// check the vehicle length (callback)
 
		veh_len = CALLBACK_FAILED;
 
		if (HASBIT(rvi_u->callbackmask, CBM_VEH_LENGTH))
 
			veh_len = GetCallBackResult(CBID_VEH_LENGTH,  u->engine_type, u);
 
		if (veh_len == CALLBACK_FAILED)
 
			veh_len = rvi_u->shorten_factor;
 
		veh_len = clamp(veh_len, 0, 7);
 
		veh_len = clamp(veh_len, 0, u->next == NULL ? 7 : 5); // the clamp on vehicles not the last in chain is stricter, as too short wagons can break the 'follow next vehicle' code
 
		u->u.rail.cached_veh_length = 8 - veh_len;
 

	
 
	};
 

	
 
	// store consist weight/max speed in cache
 
	v->u.rail.cached_max_speed = max_speed;
viewport.c
Show inline comments
 
@@ -1076,22 +1076,43 @@ static void ViewportSortParentSprites(Pa
 
	while((ps=*psd) != NULL) {
 
		if (!(ps->unk16 & 1)) {
 
			ps->unk16 |= 1;
 
			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;
 
						*psd3 = ps2;
 
						ps2 = ps3;
 

	
0 comments (0 inline, 0 general)