# slope_func.h

Go to the documentation of this file.

    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 int GetSlopeMaxZ(Slope s)
    00163 {
    00164   if (s == SLOPE_FLAT) return 0;
    00165   if (IsSteepSlope(s)) return 2;
    00166   return 1;
    00167 }
    00168
    00175 static inline int GetSlopeMaxPixelZ(Slope s)
    00176 {
    00177   return GetSlopeMaxZ(s) * TILE_HEIGHT;
    00178 }
    00179
    00186 static inline Corner OppositeCorner(Corner corner)
    00187 {
    00188   return (Corner)(corner ^ 2);
    00189 }
    00190
    00197 static inline bool IsSlopeWithThreeCornersRaised(Slope s)
    00198 {
    00199   return !IsHalftileSlope(s) && !IsSteepSlope(s) && IsSlopeWithOneCornerRaised(ComplementSlope(s));
    00200 }
    00201
    00208 static inline Slope SlopeWithThreeCornersRaised(Corner corner)
    00209 {
    00210   return ComplementSlope(SlopeWithOneCornerRaised(corner));
    00211 }
    00212
    00219 static inline Slope SteepSlope(Corner corner)
    00220 {
    00221   return SLOPE_STEEP | SlopeWithThreeCornersRaised(OppositeCorner(corner));
    00222 }
    00223
    00230 static inline bool IsInclinedSlope(Slope s)
    00231 {
    00232   return (s == SLOPE_NW) || (s == SLOPE_SW) || (s == SLOPE_SE) || (s == SLOPE_NE);
    00233 }
    00234
    00241 static inline DiagDirection GetInclinedSlopeDirection(Slope s)
    00242 {
    00243   switch (s) {
    00244     case SLOPE_NE: return DIAGDIR_NE;
    00245     case SLOPE_SE: return DIAGDIR_SE;
    00246     case SLOPE_SW: return DIAGDIR_SW;
    00247     case SLOPE_NW: return DIAGDIR_NW;
    00248     default: return INVALID_DIAGDIR;
    00249   }
    00250 }
    00251
    00258 static inline Slope InclinedSlope(DiagDirection dir)
    00259 {
    00260   switch (dir) {
    00261     case DIAGDIR_NE: return SLOPE_NE;
    00262     case DIAGDIR_SE: return SLOPE_SE;
    00263     case DIAGDIR_SW: return SLOPE_SW;
    00264     case DIAGDIR_NW: return SLOPE_NW;
    00265     default: NOT_REACHED();
    00266   }
    00267 }
    00268
    00276 static inline Slope HalftileSlope(Slope s, Corner corner)
    00277 {
    00278   assert(IsValidCorner(corner));
    00279   return (Slope)(s | SLOPE_HALFTILE | (corner << 6));
    00280 }
    00281
    00282
    00289 static inline bool IsFoundation(Foundation f)
    00290 {
    00291   return f != FOUNDATION_NONE;
    00292 }
    00293
    00300 static inline bool IsLeveledFoundation(Foundation f)
    00301 {
    00302   return f == FOUNDATION_LEVELED;
    00303 }
    00304
    00311 static inline bool IsInclinedFoundation(Foundation f)
    00312 {
    00313   return (f == FOUNDATION_INCLINED_X) || (f == FOUNDATION_INCLINED_Y);
    00314 }
    00315
    00322 static inline bool IsNonContinuousFoundation(Foundation f)
    00323 {
    00324   return IsInsideMM(f, FOUNDATION_STEEP_BOTH, FOUNDATION_HALFTILE_N + 1);
    00325 }
    00326
    00335 static inline Corner GetHalftileFoundationCorner(Foundation f)
    00336 {
    00337   assert(IsInsideMM(f, FOUNDATION_HALFTILE_W, FOUNDATION_HALFTILE_N + 1));
    00338   return (Corner)(f - FOUNDATION_HALFTILE_W);
    00339 }
    00340
    00347 static inline bool IsSpecialRailFoundation(Foundation f)
    00348 {
    00349   return IsInsideMM(f, FOUNDATION_RAIL_W, FOUNDATION_RAIL_N + 1);
    00350 }
    00351
    00358 static inline Corner GetRailFoundationCorner(Foundation f)
    00359 {
    00360   assert(IsSpecialRailFoundation(f));
    00361   return (Corner)(f - FOUNDATION_RAIL_W);
    00362 }
    00363
    00371 static inline Foundation FlatteningFoundation(Slope s)
    00372 {
    00373   return (s == SLOPE_FLAT ? FOUNDATION_NONE : FOUNDATION_LEVELED);
    00374 }
    00375
    00382 static inline Foundation InclinedFoundation(Axis axis)
    00383 {
    00384   return (axis == AXIS_X ? FOUNDATION_INCLINED_X : FOUNDATION_INCLINED_Y);
    00385 }
    00386
    00393 static inline Foundation HalftileFoundation(Corner corner)
    00394 {
    00395   assert(IsValidCorner(corner));
    00396   return (Foundation)(FOUNDATION_HALFTILE_W + corner);
    00397 }
    00398
    00405 static inline Foundation SpecialRailFoundation(Corner corner)
    00406 {
    00407   assert(IsValidCorner(corner));
    00408   return (Foundation)(FOUNDATION_RAIL_W + corner);
    00409 }
    00410
    00417 static inline uint SlopeToSpriteOffset(Slope s)
    00418 {
    00419   extern const byte _slope_to_sprite_offset[32];
    00420   return _slope_to_sprite_offset[s];
    00421 }
    00422
    00423 #endif /* SLOPE_FUNC_H */