00001 /* $Id: slope_func.h 13827 2008-07-25 19:54:14Z rubidium $ */ 00002 00005 #ifndef SLOPE_FUNC_H 00006 #define SLOPE_FUNC_H 00007 00008 #include "core/math_func.hpp" 00009 #include "slope_type.h" 00010 #include "direction_type.h" 00011 #include "tile_type.h" 00012 00019 static inline bool IsValidCorner(Corner corner) 00020 { 00021 return IsInsideMM(corner, 0, CORNER_END); 00022 } 00023 00024 00031 static inline bool IsSteepSlope(Slope s) 00032 { 00033 return (s & SLOPE_STEEP) != 0; 00034 } 00035 00042 static inline bool IsHalftileSlope(Slope s) 00043 { 00044 return (s & SLOPE_HALFTILE) != 0; 00045 } 00046 00055 static inline Slope RemoveHalftileSlope(Slope s) 00056 { 00057 return (Slope)(s & ~SLOPE_HALFTILE_MASK); 00058 } 00059 00071 static inline Slope ComplementSlope(Slope s) 00072 { 00073 assert(!IsSteepSlope(s) && !IsHalftileSlope(s)); 00074 return (Slope)(0xF ^ s); 00075 } 00076 00083 static inline bool IsSlopeWithOneCornerRaised(Slope s) 00084 { 00085 return (s == SLOPE_W) || (s == SLOPE_S) || (s == SLOPE_E) || (s == SLOPE_N); 00086 } 00087 00094 static inline Slope SlopeWithOneCornerRaised(Corner corner) 00095 { 00096 assert(IsValidCorner(corner)); 00097 return (Slope)(1 << corner); 00098 } 00099 00108 static inline bool HasSlopeHighestCorner(Slope s) 00109 { 00110 s = RemoveHalftileSlope(s); 00111 return IsSteepSlope(s) || IsSlopeWithOneCornerRaised(s); 00112 } 00113 00121 static inline Corner GetHighestSlopeCorner(Slope s) 00122 { 00123 switch (RemoveHalftileSlope(s)) { 00124 case SLOPE_W: 00125 case SLOPE_STEEP_W: return CORNER_W; 00126 case SLOPE_S: 00127 case SLOPE_STEEP_S: return CORNER_S; 00128 case SLOPE_E: 00129 case SLOPE_STEEP_E: return CORNER_E; 00130 case SLOPE_N: 00131 case SLOPE_STEEP_N: return CORNER_N; 00132 default: NOT_REACHED(); 00133 } 00134 } 00135 00143 static inline Corner GetHalftileSlopeCorner(Slope s) 00144 { 00145 assert(IsHalftileSlope(s)); 00146 return (Corner)((s >> 6) & 3); 00147 } 00148 00155 static inline uint GetSlopeMaxZ(Slope s) 00156 { 00157 if (s == SLOPE_FLAT) return 0; 00158 if (IsSteepSlope(s)) return 2 * TILE_HEIGHT; 00159 return TILE_HEIGHT; 00160 } 00161 00168 static inline Corner OppositeCorner(Corner corner) 00169 { 00170 return (Corner)(corner ^ 2); 00171 } 00172 00179 static inline bool IsSlopeWithThreeCornersRaised(Slope s) 00180 { 00181 return !IsHalftileSlope(s) && !IsSteepSlope(s) && IsSlopeWithOneCornerRaised(ComplementSlope(s)); 00182 } 00183 00190 static inline Slope SlopeWithThreeCornersRaised(Corner corner) 00191 { 00192 return ComplementSlope(SlopeWithOneCornerRaised(corner)); 00193 } 00194 00201 static inline Slope SteepSlope(Corner corner) 00202 { 00203 return (Slope)(SLOPE_STEEP | SlopeWithThreeCornersRaised(OppositeCorner(corner))); 00204 } 00205 00212 static inline bool IsInclinedSlope(Slope s) 00213 { 00214 return (s == SLOPE_NW) || (s == SLOPE_SW) || (s == SLOPE_SE) || (s == SLOPE_NE); 00215 } 00216 00223 static inline DiagDirection GetInclinedSlopeDirection(Slope s) 00224 { 00225 switch (s) { 00226 case SLOPE_NE: return DIAGDIR_NE; 00227 case SLOPE_SE: return DIAGDIR_SE; 00228 case SLOPE_SW: return DIAGDIR_SW; 00229 case SLOPE_NW: return DIAGDIR_NW; 00230 default: return INVALID_DIAGDIR; 00231 } 00232 } 00233 00240 static inline Slope InclinedSlope(DiagDirection dir) 00241 { 00242 switch (dir) { 00243 case DIAGDIR_NE: return SLOPE_NE; 00244 case DIAGDIR_SE: return SLOPE_SE; 00245 case DIAGDIR_SW: return SLOPE_SW; 00246 case DIAGDIR_NW: return SLOPE_NW; 00247 default: NOT_REACHED(); 00248 } 00249 } 00250 00258 static inline Slope HalftileSlope(Slope s, Corner corner) 00259 { 00260 assert(IsValidCorner(corner)); 00261 return (Slope)(s | SLOPE_HALFTILE | (corner << 6)); 00262 } 00263 00264 00271 static inline bool IsFoundation(Foundation f) 00272 { 00273 return f != FOUNDATION_NONE; 00274 } 00275 00282 static inline bool IsLeveledFoundation(Foundation f) 00283 { 00284 return f == FOUNDATION_LEVELED; 00285 } 00286 00293 static inline bool IsInclinedFoundation(Foundation f) 00294 { 00295 return (f == FOUNDATION_INCLINED_X) || (f == FOUNDATION_INCLINED_Y); 00296 } 00297 00304 static inline bool IsNonContinuousFoundation(Foundation f) 00305 { 00306 return IsInsideMM(f, FOUNDATION_STEEP_BOTH, FOUNDATION_HALFTILE_N + 1); 00307 } 00308 00317 static inline Corner GetHalftileFoundationCorner(Foundation f) 00318 { 00319 assert(IsInsideMM(f, FOUNDATION_HALFTILE_W, FOUNDATION_HALFTILE_N + 1)); 00320 return (Corner)(f - FOUNDATION_HALFTILE_W); 00321 } 00322 00329 static inline bool IsSpecialRailFoundation(Foundation f) 00330 { 00331 return IsInsideMM(f, FOUNDATION_RAIL_W, FOUNDATION_RAIL_N + 1); 00332 } 00333 00340 static inline Corner GetRailFoundationCorner(Foundation f) 00341 { 00342 assert(IsSpecialRailFoundation(f)); 00343 return (Corner)(f - FOUNDATION_RAIL_W); 00344 } 00345 00353 static inline Foundation FlatteningFoundation(Slope s) 00354 { 00355 return (s == SLOPE_FLAT ? FOUNDATION_NONE : FOUNDATION_LEVELED); 00356 } 00357 00364 static inline Foundation InclinedFoundation(Axis axis) 00365 { 00366 return (axis == AXIS_X ? FOUNDATION_INCLINED_X : FOUNDATION_INCLINED_Y); 00367 } 00368 00375 static inline Foundation HalftileFoundation(Corner corner) 00376 { 00377 assert(IsValidCorner(corner)); 00378 return (Foundation)(FOUNDATION_HALFTILE_W + corner); 00379 } 00380 00387 static inline Foundation SpecialRailFoundation(Corner corner) 00388 { 00389 assert(IsValidCorner(corner)); 00390 return (Foundation)(FOUNDATION_RAIL_W + corner); 00391 } 00392 00393 #endif /* SLOPE_FUNC_H */