82 BRIDGE_FULL_LEVELED_FOUNDATION = 1 << 7 | 1 << 11 | 1 << 13 | 1 << 14, |
82 BRIDGE_FULL_LEVELED_FOUNDATION = 1 << 7 | 1 << 11 | 1 << 13 | 1 << 14, |
83 // foundation, tile is partly leveled up (tileh's 1, 2, 4, 8) --> 1 corner raised |
83 // foundation, tile is partly leveled up (tileh's 1, 2, 4, 8) --> 1 corner raised |
84 BRIDGE_PARTLY_LEVELED_FOUNDATION = 1 << 1 | 1 << 2 | 1 << 4 | 1 << 8, |
84 BRIDGE_PARTLY_LEVELED_FOUNDATION = 1 << 1 | 1 << 2 | 1 << 4 | 1 << 8, |
85 // no foundations (X,Y direction) (tileh's 0, 3, 6, 9, 12) |
85 // no foundations (X,Y direction) (tileh's 0, 3, 6, 9, 12) |
86 BRIDGE_NO_FOUNDATION = 1 << 0 | 1 << 3 | 1 << 6 | 1 << 9 | 1 << 12, |
86 BRIDGE_NO_FOUNDATION = 1 << 0 | 1 << 3 | 1 << 6 | 1 << 9 | 1 << 12, |
|
87 BRIDGE_HORZ_RAMP = (BRIDGE_PARTLY_LEVELED_FOUNDATION | BRIDGE_NO_FOUNDATION) & ~0 |
87 }; |
88 }; |
88 |
89 |
89 static inline const PalSpriteID *GetBridgeSpriteTable(int index, byte table) |
90 static inline const PalSpriteID *GetBridgeSpriteTable(int index, byte table) |
90 { |
91 { |
91 const Bridge *bridge = &_bridge[index]; |
92 const Bridge *bridge = &_bridge[index]; |
1076 } |
1077 } |
1077 } |
1078 } |
1078 |
1079 |
1079 static uint GetSlopeZ_TunnelBridge(const TileInfo* ti) |
1080 static uint GetSlopeZ_TunnelBridge(const TileInfo* ti) |
1080 { |
1081 { |
|
1082 TileIndex tile = ti->tile; |
1081 uint z = ti->z; |
1083 uint z = ti->z; |
1082 uint x = ti->x & 0xF; |
1084 uint x = ti->x & 0xF; |
1083 uint y = ti->y & 0xF; |
1085 uint y = ti->y & 0xF; |
1084 uint tileh = ti->tileh; |
1086 uint tileh = ti->tileh; |
1085 |
1087 |
1086 // swap directions if Y tunnel/bridge to let the code handle the X case only. |
1088 if (IsTunnel(tile)) { |
1087 if (ti->map5 & 1) uintswap(x,y); // XXX bogus: it could be a tunnel, bridge ramp or bridge middle tile |
1089 uint pos = (DiagDirToAxis(GetTunnelDirection(tile)) == AXIS_X ? y : x); |
1088 |
1090 |
1089 // to the side of the tunnel/bridge? |
1091 // In the tunnel entrance? |
1090 if (IS_INT_INSIDE(y, 5, 10+1)) { |
1092 if (5 <= pos && pos <= 10) return z; |
1091 if (IsTunnel(ti->tile)) return z; |
1093 } else { |
1092 |
1094 if (IsBridgeRamp(tile)) { |
1093 // bridge? |
1095 DiagDirection dir = GetBridgeRampDirection(tile); |
1094 if (IsBridge(ti->tile)) { |
1096 uint pos = (DiagDirToAxis(dir) == AXIS_X ? y : x); |
1095 if (IsBridgeRamp(ti->tile)) { |
1097 |
1096 if (BRIDGE_FULL_LEVELED_FOUNDATION & (1 << tileh)) // 7, 11, 13, 14 |
1098 // On the bridge ramp? |
1097 z += 8; |
1099 if (5 <= pos && pos <= 10) { |
1098 |
1100 uint delta; |
1099 // no ramp for bridge ending |
1101 |
1100 if ((BRIDGE_PARTLY_LEVELED_FOUNDATION & (1 << tileh) || BRIDGE_NO_FOUNDATION & (1 << tileh)) && tileh != 0) { |
1102 if (HASBIT(BRIDGE_HORZ_RAMP, tileh)) return z + 8; |
1101 return z + 8; |
1103 |
1102 } else if (!(ti->map5 & 0x20)) { // northern / southern ending |
1104 if (HASBIT(BRIDGE_FULL_LEVELED_FOUNDATION, tileh)) z += 8; |
1103 // ramp |
1105 switch (dir) { |
1104 return z + (x >> 1) + 1; |
1106 default: |
1105 } else { |
1107 case DIAGDIR_NE: delta = (15 - x) / 2; break; |
1106 // ramp in opposite dir |
1108 case DIAGDIR_SE: delta = y / 2; break; |
1107 return z + ((x ^ 0xF) >> 1); |
1109 case DIAGDIR_SW: delta = x / 2; break; |
1108 } |
1110 case DIAGDIR_NW: delta = (15 - y) / 2; break; |
|
1111 } |
|
1112 return z + 1 + delta; |
1109 } else { |
1113 } else { |
1110 // build on slopes? |
1114 uint f = GetBridgeFoundation(tileh, DiagDirToAxis(dir)); |
1111 if (tileh != 0) z += 8; |
1115 |
1112 |
1116 if (f != 0) { |
1113 // keep the same elevation because we're on the bridge? |
1117 if (f < 15) return z + 8; |
1114 if (_get_z_hint >= z + 8) return _get_z_hint; |
1118 tileh = _inclined_tileh[f - 15]; |
1115 |
1119 } |
1116 // actually on the bridge, but not yet in the shared area. |
1120 } |
1117 if (!IS_INT_INSIDE(x, 5, 10 + 1)) return GetBridgeHeight(ti->tile) + 8; |
1121 } else { |
1118 |
1122 // HACK on the bridge? |
1119 // in the shared area, assume that we're below the bridge, cause otherwise the hint would've caught it. |
1123 if (_get_z_hint >= z + 8 + (tileh == 0 ? 0 : 8)) return _get_z_hint; |
1120 // if rail or road below then it means it's possibly build on slope below the bridge. |
1124 |
1121 if (IsTransportUnderBridge(ti->tile)) { |
1125 if (IsTransportUnderBridge(tile)) { |
1122 uint f = _bridge_foundations[GetBridgeAxis(ti->tile)][tileh]; |
1126 uint f = _bridge_foundations[GetBridgeAxis(tile)][tileh]; |
1123 |
1127 |
1124 // make sure that the slope is not inclined foundation |
1128 if (f != 0) { |
1125 if (IS_BYTE_INSIDE(f, 1, 15)) return z; |
1129 if (f < 15) return z + 8; |
1126 |
1130 tileh = _inclined_tileh[f - 15]; |
1127 // change foundation type? XXX - should be const; accessor function! |
1131 } |
1128 if (f != 0) tileh = _inclined_tileh[f - 15]; |
1132 } |
1129 } |
1133 } |
1130 |
1134 } |
1131 // no transport route, fallback to default |
1135 |
1132 } |
1136 return z + GetPartialZ(x, y, tileh); |
1133 } |
|
1134 } else { |
|
1135 if (IsBridge(ti->tile) && IsBridgeMiddle(ti->tile) && IsTransportUnderBridge(ti->tile)) { |
|
1136 uint f; |
|
1137 if (tileh != 0) z += 8; |
|
1138 f = _bridge_foundations[GetBridgeAxis(ti->tile)][tileh]; |
|
1139 if (IS_BYTE_INSIDE(f, 1, 15)) return z; |
|
1140 if (f != 0) tileh = _inclined_tileh[f - 15]; |
|
1141 } |
|
1142 } |
|
1143 |
|
1144 // default case |
|
1145 return GetPartialZ(ti->x & 0xF, ti->y & 0xF, tileh) + ti->z; |
|
1146 } |
1137 } |
1147 |
1138 |
1148 static uint GetSlopeTileh_TunnelBridge(TileIndex tile, uint tileh) |
1139 static uint GetSlopeTileh_TunnelBridge(TileIndex tile, uint tileh) |
1149 { |
1140 { |
1150 // not accurate, but good enough for slope graphics drawing |
1141 // not accurate, but good enough for slope graphics drawing |