diff --git a/src/slope.h b/src/slope.h --- a/src/slope.h +++ b/src/slope.h @@ -9,12 +9,31 @@ #define SLOPE_H /** + * Enumeration of tile corners + */ +enum Corner { + CORNER_W = 0, + CORNER_S = 1, + CORNER_E = 2, + CORNER_N = 3, + CORNER_END +}; + +/** * Enumeration for the slope-type. * * This enumeration use the chars N,E,S,W corresponding the * direction north, east, south and west. The top corner of a tile * is the north-part of the tile. The whole slope is encoded with * 5 bits, 4 bits for each corner and 1 bit for a steep-flag. + * + * For halftile slopes an extra 3 bits are used to represent this + * properly; 1 bit for a halftile-flag and 2 bits to encode which + * extra side (corner) is leveled when the slope of the first 5 + * bits is applied. This means that there can only be one leveled + * slope for steep slopes, which is logical because two leveled + * slopes would mean that it is not a steep slope as halftile + * slopes only span one height level. */ enum Slope { SLOPE_FLAT = 0x00, ///< a flat tile @@ -37,18 +56,14 @@ enum Slope { SLOPE_STEEP_W = SLOPE_STEEP | SLOPE_NWS, ///< a steep slope falling to east (from west) SLOPE_STEEP_S = SLOPE_STEEP | SLOPE_WSE, ///< a steep slope falling to north (from south) SLOPE_STEEP_E = SLOPE_STEEP | SLOPE_SEN, ///< a steep slope falling to west (from east) - SLOPE_STEEP_N = SLOPE_STEEP | SLOPE_ENW ///< a steep slope falling to south (from north) -}; + SLOPE_STEEP_N = SLOPE_STEEP | SLOPE_ENW, ///< a steep slope falling to south (from north) -/** - * Enumeration of tile corners - */ -enum Corner { - CORNER_W = 0, - CORNER_S = 1, - CORNER_E = 2, - CORNER_N = 3, - CORNER_END + SLOPE_HALFTILE = 0x20, ///< one halftile is leveled (non continuous slope) + SLOPE_HALFTILE_MASK = 0xE0, ///< three bits used for halftile slopes + SLOPE_HALFTILE_W = SLOPE_HALFTILE | (CORNER_W << 6), ///< the west halftile is leveled (non continuous slope) + SLOPE_HALFTILE_S = SLOPE_HALFTILE | (CORNER_S << 6), ///< the south halftile is leveled (non continuous slope) + SLOPE_HALFTILE_E = SLOPE_HALFTILE | (CORNER_E << 6), ///< the east halftile is leveled (non continuous slope) + SLOPE_HALFTILE_N = SLOPE_HALFTILE | (CORNER_N << 6), ///< the north halftile is leveled (non continuous slope) }; /** @@ -74,43 +89,57 @@ static inline bool IsSteepSlope(Slope s) } /** + * Checks for non-continuous slope on halftile foundations. + * + * @param s The given #Slope. + * @return True if the slope is non-continuous, else false. + */ +static inline bool IsHalftileSlope(Slope s) +{ + return (s & SLOPE_HALFTILE) != 0; +} + +/** * Return the complement of a slope. * * This method returns the complement of a slope. The complement of a * slope is a slope with raised corner which aren't raised in the given * slope. * - * @pre The slope must not be steep. + * @pre The slope must neither be steep nor a halftile slope. * @param s The #Slope to get the complement. * @return a complement Slope of the given slope. */ static inline Slope ComplementSlope(Slope s) { - assert(!IsSteepSlope(s)); + assert(!IsSteepSlope(s) && !IsHalftileSlope(s)); return (Slope)(0xF ^ s); } /** * Tests if a slope has a highest corner (i.e. one corner raised or a steep slope). * + * Note: A halftile slope is ignored. + * * @param s The #Slope. * @return true iff the slope has a highest corner. */ static inline bool HasSlopeHighestCorner(Slope s) { + s = (Slope)(s & ~SLOPE_HALFTILE_MASK); return IsSteepSlope(s) || (s == SLOPE_W) || (s == SLOPE_S) || (s == SLOPE_E) || (s == SLOPE_N); } /** * Returns the highest corner of a slope (one corner raised or a steep slope). * - * @pre The slope must be a slope with one corner raised or a steep slope. + * @pre The slope must be a slope with one corner raised or a steep slope. A halftile slope is ignored. * @param s The #Slope. * @return Highest corner. */ static inline Corner GetHighestSlopeCorner(Slope s) { - switch (s) { + switch (s & ~SLOPE_HALFTILE_MASK) { case SLOPE_W: case SLOPE_STEEP_W: return CORNER_W; case SLOPE_S: @@ -124,6 +153,19 @@ static inline Corner GetHighestSlopeCorn } /** + * Returns the leveled halftile of a halftile slope. + * + * @pre The slope must be a halftile slope. + * @param s The #Slope. + * @return The corner of the leveled halftile. + */ +static inline Corner GetHalftileSlopeCorner(Slope s) +{ + assert(IsHalftileSlope(s)); + return (Corner)((s >> 6) & 3); +} + +/** * Returns the height of the highest corner of a slope relative to TileZ (= minimal height) * * @param s The #Slope. @@ -170,6 +212,19 @@ static inline Slope SlopeWithThreeCorner return ComplementSlope(SlopeWithOneCornerRaised(corner)); } +/** + * Adds a halftile slope to a slope. + * + * @param s #Slope without a halftile slope. + * @param corner The #Corner of the halftile. + * @return The #Slope s with the halftile slope added. + */ +static inline Slope HalftileSlope(Slope s, Corner corner) +{ + assert(IsValidCorner(corner)); + return (Slope)(s | SLOPE_HALFTILE | (corner << 6)); +} + /** * Enumeration for Foundations.