tron@3636: /* $Id$ */ tron@3636: richk@6743: /** @file slope.h Definitions of a slope. richk@6743: * This file defines the enumeration and helper functions for handling richk@6743: * the slope info of a tile. richk@6743: */ richk@6719: tron@3636: #ifndef SLOPE_H tron@3636: #define SLOPE_H tron@3636: richk@6743: /** richk@6743: * Enumeration for the slope-type. richk@6743: * richk@6743: * This enumeration use the chars N,E,S,W corresponding the richk@6743: * direction north, east, south and west. The top corner of a tile richk@6743: * is the north-part of the tile. The whole slope is encoded with richk@6743: * 5 bits, 4 bits for each corner and 1 bit for a steep-flag. richk@6743: */ rubidium@6574: enum Slope { richk@6743: SLOPE_FLAT = 0x00, ///< a flat tile richk@6743: SLOPE_W = 0x01, ///< the west corner of the tile is raised richk@6743: SLOPE_S = 0x02, ///< the south corner of the tile is raised richk@6743: SLOPE_E = 0x04, ///< the east corner of the tile is raised richk@6743: SLOPE_N = 0x08, ///< the north corner of the tile is raised richk@6743: SLOPE_STEEP = 0x10, ///< indicates the slope is steep richk@6743: SLOPE_NW = SLOPE_N | SLOPE_W, ///< north and west corner are raised richk@6743: SLOPE_SW = SLOPE_S | SLOPE_W, ///< south and west corner are raised richk@6743: SLOPE_SE = SLOPE_S | SLOPE_E, ///< south and east corner are raised richk@6743: SLOPE_NE = SLOPE_N | SLOPE_E, ///< north and east corner are raised richk@6743: SLOPE_EW = SLOPE_E | SLOPE_W, ///< east and west corner are raised richk@6743: SLOPE_NS = SLOPE_N | SLOPE_S, ///< north and south corner are raised richk@6743: SLOPE_ELEVATED = SLOPE_N | SLOPE_E | SLOPE_S | SLOPE_W, ///< all corner are raised, similar to SLOPE_FLAT richk@6743: SLOPE_NWS = SLOPE_N | SLOPE_W | SLOPE_S, ///< north, west and south corner are raised richk@6743: SLOPE_WSE = SLOPE_W | SLOPE_S | SLOPE_E, ///< west, south and east corner are raised richk@6743: SLOPE_SEN = SLOPE_S | SLOPE_E | SLOPE_N, ///< south, east and north corner are raised richk@6743: SLOPE_ENW = SLOPE_E | SLOPE_N | SLOPE_W, ///< east, north and west corner are raised richk@6743: SLOPE_STEEP_W = SLOPE_STEEP | SLOPE_NWS, ///< a steep slope falling to east (from west) richk@6743: SLOPE_STEEP_S = SLOPE_STEEP | SLOPE_WSE, ///< a steep slope falling to north (from south) richk@6743: SLOPE_STEEP_E = SLOPE_STEEP | SLOPE_SEN, ///< a steep slope falling to west (from east) richk@6743: SLOPE_STEEP_N = SLOPE_STEEP | SLOPE_ENW ///< a steep slope falling to south (from north) rubidium@6574: }; tron@3636: richk@6743: /** richk@6743: * Checks if a slope is steep. richk@6743: * richk@6743: * @param s The given #Slope. richk@6743: * @return True if the slope is steep, else false. richk@6743: */ tron@3636: static inline bool IsSteepSlope(Slope s) tron@3636: { tron@3636: return (s & SLOPE_STEEP) != 0; tron@3636: } tron@3636: richk@6743: /** richk@6743: * Return the complement of a slope. richk@6743: * richk@6743: * This method returns the complement of a slope. The complement of a richk@6743: * slope is a slope with raised corner which aren't raised in the given richk@6743: * slope. richk@6743: * richk@6743: * @pre The slope must not be steep. richk@6743: * @param s The #Slope to get the complement. richk@6743: * @return a complement Slope of the given slope. richk@6743: */ tron@3636: static inline Slope ComplementSlope(Slope s) tron@3636: { tron@3636: assert(!IsSteepSlope(s)); tron@3636: return (Slope)(0xF ^ s); tron@3636: } tron@3636: richk@6743: /** richk@6743: * Returns the highest corner of a slope (one corner raised or a steep slope). richk@6743: * richk@6743: * @pre The slope must be a slope with one corner raised or a steep slope. richk@6743: * @param s The #Slope. richk@6743: * @return Number of the highest corner. (0 west, 1 south, 2 east, 3 north) richk@6743: */ richk@6743: static inline byte GetHighestSlopeCorner(Slope s) richk@6743: { richk@6743: switch (s) { richk@6743: case SLOPE_W: richk@6743: case SLOPE_STEEP_W: return 0; richk@6743: case SLOPE_S: richk@6743: case SLOPE_STEEP_S: return 1; richk@6743: case SLOPE_E: richk@6743: case SLOPE_STEEP_E: return 2; richk@6743: case SLOPE_N: richk@6743: case SLOPE_STEEP_N: return 3; richk@6743: default: NOT_REACHED(); richk@6743: } richk@6743: } richk@6743: richk@6743: richk@6743: /** richk@6743: * Enumeration for Foundations. richk@6743: */ richk@6743: enum Foundation { richk@6743: FOUNDATION_NONE, ///< The tile has no foundation, the slope remains unchanged. richk@6743: FOUNDATION_LEVELED, ///< The tile is leveled up to a flat slope. richk@6743: FOUNDATION_INCLINED_X, ///< The tile has an along X-axis inclined foundation. richk@6743: FOUNDATION_INCLINED_Y, ///< The tile has an along Y-axis inclined foundation. richk@6743: FOUNDATION_STEEP_LOWER, ///< The tile has a steep slope. The lowerst corner is raised by a foundation to allow building railroad on the lower halftile. richk@6743: FOUNDATION_STEEP_HIGHER, ///< The tile has a steep slope. Three corners are raised by a foundation to allow building railroad on the higher halftile. richk@6743: }; richk@6743: richk@6743: /** richk@6743: * Tests for FOUNDATION_NONE. richk@6743: * richk@6743: * @param f Maybe a #Foundation. richk@6743: * @return true iff f is a foundation. richk@6743: */ richk@6743: static inline bool IsFoundation(Foundation f) richk@6743: { richk@6743: return f != FOUNDATION_NONE; richk@6743: } richk@6743: richk@6743: /** richk@6743: * Tests if the foundation is a leveled foundation. richk@6743: * richk@6743: * @param f The #Foundation. richk@6743: * @return true iff f is a leveled foundation. richk@6743: */ richk@6743: static inline bool IsLeveledFoundation(Foundation f) richk@6743: { richk@6743: return f == FOUNDATION_LEVELED; richk@6743: } richk@6743: richk@6743: /** richk@6743: * Tests if the foundation is an inclined foundation. richk@6743: * richk@6743: * @param f The #Foundation. richk@6743: * @return true iff f is an inclined foundation. richk@6743: */ richk@6743: static inline bool IsInclinedFoundation(Foundation f) richk@6743: { richk@6743: return (f == FOUNDATION_INCLINED_X) || (f == FOUNDATION_INCLINED_Y); richk@6743: } richk@6743: richk@6743: /** richk@6743: * Returns the foundation needed to flatten a slope. richk@6743: * The returned foundation is either FOUNDATION_NONE if the tile was already flat, or FOUNDATION_LEVELED. richk@6743: * richk@6743: * @pre The slope must not be steep. richk@6743: * @param s The current #Slope. richk@6743: * @return The needed #Foundation. richk@6743: */ richk@6743: static inline Foundation FlatteningFoundation(Slope s) richk@6743: { richk@6743: assert(!IsSteepSlope(s)); richk@6743: return (s == SLOPE_FLAT ? FOUNDATION_NONE : FOUNDATION_LEVELED); richk@6743: } richk@6743: richk@6743: /** richk@6743: * Returns the along a specific axis inclined foundation. richk@6743: * richk@6743: * @param axis The #Axis. richk@6743: * @return The needed #Foundation. richk@6743: */ richk@6743: static inline Foundation InclinedFoundation(Axis axis) richk@6743: { richk@6743: return (axis == AXIS_X ? FOUNDATION_INCLINED_X : FOUNDATION_INCLINED_Y); richk@6743: } richk@6743: peter1138@4666: #endif /* SLOPE_H */