00001 /* $Id$ */ 00002 00003 /* 00004 * This file is part of OpenTTD. 00005 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. 00006 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00007 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>. 00008 */ 00009 00012 #ifndef SLOPE_FUNC_H 00013 #define SLOPE_FUNC_H 00014 00015 #include "core/math_func.hpp" 00016 #include "slope_type.h" 00017 #include "direction_type.h" 00018 #include "tile_type.h" 00019 00026 static inline bool IsValidCorner(Corner corner) 00027 { 00028 return IsInsideMM(corner, 0, CORNER_END); 00029 } 00030 00031 00038 static inline bool IsSteepSlope(Slope s) 00039 { 00040 return (s & SLOPE_STEEP) != 0; 00041 } 00042 00049 static inline bool IsHalftileSlope(Slope s) 00050 { 00051 return (s & SLOPE_HALFTILE) != 0; 00052 } 00053 00062 static inline Slope RemoveHalftileSlope(Slope s) 00063 { 00064 return s & ~SLOPE_HALFTILE_MASK; 00065 } 00066 00078 static inline Slope ComplementSlope(Slope s) 00079 { 00080 assert(!IsSteepSlope(s) && !IsHalftileSlope(s)); 00081 return s ^ SLOPE_ELEVATED; 00082 } 00083 00090 static inline bool IsSlopeWithOneCornerRaised(Slope s) 00091 { 00092 return (s == SLOPE_W) || (s == SLOPE_S) || (s == SLOPE_E) || (s == SLOPE_N); 00093 } 00094 00101 static inline Slope SlopeWithOneCornerRaised(Corner corner) 00102 { 00103 assert(IsValidCorner(corner)); 00104 return (Slope)(1 << corner); 00105 } 00106 00115 static inline bool HasSlopeHighestCorner(Slope s) 00116 { 00117 s = RemoveHalftileSlope(s); 00118 return IsSteepSlope(s) || IsSlopeWithOneCornerRaised(s); 00119 } 00120 00128 static inline Corner GetHighestSlopeCorner(Slope s) 00129 { 00130 switch (RemoveHalftileSlope(s)) { 00131 case SLOPE_W: 00132 case SLOPE_STEEP_W: return CORNER_W; 00133 case SLOPE_S: 00134 case SLOPE_STEEP_S: return CORNER_S; 00135 case SLOPE_E: 00136 case SLOPE_STEEP_E: return CORNER_E; 00137 case SLOPE_N: 00138 case SLOPE_STEEP_N: return CORNER_N; 00139 default: NOT_REACHED(); 00140 } 00141 } 00142 00150 static inline Corner GetHalftileSlopeCorner(Slope s) 00151 { 00152 assert(IsHalftileSlope(s)); 00153 return (Corner)((s >> 6) & 3); 00154 } 00155 00162 static inline uint GetSlopeMaxZ(Slope s) 00163 { 00164 if (s == SLOPE_FLAT) return 0; 00165 if (IsSteepSlope(s)) return 2 * TILE_HEIGHT; 00166 return TILE_HEIGHT; 00167 } 00168 00175 static inline Corner OppositeCorner(Corner corner) 00176 { 00177 return (Corner)(corner ^ 2); 00178 } 00179 00186 static inline bool IsSlopeWithThreeCornersRaised(Slope s) 00187 { 00188 return !IsHalftileSlope(s) && !IsSteepSlope(s) && IsSlopeWithOneCornerRaised(ComplementSlope(s)); 00189 } 00190 00197 static inline Slope SlopeWithThreeCornersRaised(Corner corner) 00198 { 00199 return ComplementSlope(SlopeWithOneCornerRaised(corner)); 00200 } 00201 00208 static inline Slope SteepSlope(Corner corner) 00209 { 00210 return SLOPE_STEEP | SlopeWithThreeCornersRaised(OppositeCorner(corner)); 00211 } 00212 00219 static inline bool IsInclinedSlope(Slope s) 00220 { 00221 return (s == SLOPE_NW) || (s == SLOPE_SW) || (s == SLOPE_SE) || (s == SLOPE_NE); 00222 } 00223 00230 static inline DiagDirection GetInclinedSlopeDirection(Slope s) 00231 { 00232 switch (s) { 00233 case SLOPE_NE: return DIAGDIR_NE; 00234 case SLOPE_SE: return DIAGDIR_SE; 00235 case SLOPE_SW: return DIAGDIR_SW; 00236 case SLOPE_NW: return DIAGDIR_NW; 00237 default: return INVALID_DIAGDIR; 00238 } 00239 } 00240 00247 static inline Slope InclinedSlope(DiagDirection dir) 00248 { 00249 switch (dir) { 00250 case DIAGDIR_NE: return SLOPE_NE; 00251 case DIAGDIR_SE: return SLOPE_SE; 00252 case DIAGDIR_SW: return SLOPE_SW; 00253 case DIAGDIR_NW: return SLOPE_NW; 00254 default: NOT_REACHED(); 00255 } 00256 } 00257 00265 static inline Slope HalftileSlope(Slope s, Corner corner) 00266 { 00267 assert(IsValidCorner(corner)); 00268 return (Slope)(s | SLOPE_HALFTILE | (corner << 6)); 00269 } 00270 00271 00278 static inline bool IsFoundation(Foundation f) 00279 { 00280 return f != FOUNDATION_NONE; 00281 } 00282 00289 static inline bool IsLeveledFoundation(Foundation f) 00290 { 00291 return f == FOUNDATION_LEVELED; 00292 } 00293 00300 static inline bool IsInclinedFoundation(Foundation f) 00301 { 00302 return (f == FOUNDATION_INCLINED_X) || (f == FOUNDATION_INCLINED_Y); 00303 } 00304 00311 static inline bool IsNonContinuousFoundation(Foundation f) 00312 { 00313 return IsInsideMM(f, FOUNDATION_STEEP_BOTH, FOUNDATION_HALFTILE_N + 1); 00314 } 00315 00324 static inline Corner GetHalftileFoundationCorner(Foundation f) 00325 { 00326 assert(IsInsideMM(f, FOUNDATION_HALFTILE_W, FOUNDATION_HALFTILE_N + 1)); 00327 return (Corner)(f - FOUNDATION_HALFTILE_W); 00328 } 00329 00336 static inline bool IsSpecialRailFoundation(Foundation f) 00337 { 00338 return IsInsideMM(f, FOUNDATION_RAIL_W, FOUNDATION_RAIL_N + 1); 00339 } 00340 00347 static inline Corner GetRailFoundationCorner(Foundation f) 00348 { 00349 assert(IsSpecialRailFoundation(f)); 00350 return (Corner)(f - FOUNDATION_RAIL_W); 00351 } 00352 00360 static inline Foundation FlatteningFoundation(Slope s) 00361 { 00362 return (s == SLOPE_FLAT ? FOUNDATION_NONE : FOUNDATION_LEVELED); 00363 } 00364 00371 static inline Foundation InclinedFoundation(Axis axis) 00372 { 00373 return (axis == AXIS_X ? FOUNDATION_INCLINED_X : FOUNDATION_INCLINED_Y); 00374 } 00375 00382 static inline Foundation HalftileFoundation(Corner corner) 00383 { 00384 assert(IsValidCorner(corner)); 00385 return (Foundation)(FOUNDATION_HALFTILE_W + corner); 00386 } 00387 00394 static inline Foundation SpecialRailFoundation(Corner corner) 00395 { 00396 assert(IsValidCorner(corner)); 00397 return (Foundation)(FOUNDATION_RAIL_W + corner); 00398 } 00399 00400 #endif /* SLOPE_FUNC_H */