src/direction.h
branchNewGRF_ports
changeset 6743 cabfaa4a0295
parent 6719 4cc327ad39d5
child 6870 ca3fd1fbe311
equal deleted inserted replaced
6742:1337d6c9b97b 6743:cabfaa4a0295
     5 #ifndef DIRECTION_H
     5 #ifndef DIRECTION_H
     6 #define DIRECTION_H
     6 #define DIRECTION_H
     7 
     7 
     8 #include "helpers.hpp"
     8 #include "helpers.hpp"
     9 
     9 
    10 /* Direction as commonly used in v->direction, 8 way. */
    10 /**
       
    11  * Defines the 8 directions on the map.
       
    12  *
       
    13  * This enum defines 8 possible directions which are used for
       
    14  * the vehicles in the game. The directions are aligned straight
       
    15  * to the viewport, not to the map. So north points to the top of
       
    16  * your viewport and not rotated by 45 degrees left or right to get
       
    17  * a "north" used in you games.
       
    18  */
    11 enum Direction {
    19 enum Direction {
    12 	DIR_BEGIN = 0,
    20 	DIR_BEGIN = 0,          ///< Used to iterate
    13 	DIR_N   = 0,
    21 	DIR_N   = 0,            ///< North
    14 	DIR_NE  = 1,      ///< Northeast, upper right on your monitor
    22 	DIR_NE  = 1,            ///< Northeast
    15 	DIR_E   = 2,
    23 	DIR_E   = 2,            ///< East
    16 	DIR_SE  = 3,
    24 	DIR_SE  = 3,            ///< Southeast
    17 	DIR_S   = 4,
    25 	DIR_S   = 4,            ///< South
    18 	DIR_SW  = 5,
    26 	DIR_SW  = 5,            ///< Southwest
    19 	DIR_W   = 6,
    27 	DIR_W   = 6,            ///< West
    20 	DIR_NW  = 7,
    28 	DIR_NW  = 7,            ///< Northwest
    21 	DIR_END,
    29 	DIR_END,                ///< Used to iterate
    22 	INVALID_DIR = 0xFF,
    30 	INVALID_DIR = 0xFF,     ///< Flag for an invalid direction
    23 };
    31 };
    24 
    32 
    25 /** Define basic enum properties */
    33 /** Define basic enum properties */
    26 template <> struct EnumPropsT<Direction> : MakeEnumPropsT<Direction, byte, DIR_BEGIN, DIR_END, INVALID_DIR> {};
    34 template <> struct EnumPropsT<Direction> : MakeEnumPropsT<Direction, byte, DIR_BEGIN, DIR_END, INVALID_DIR> {};
    27 typedef TinyEnumT<Direction> DirectionByte; //typedefing-enumification of Direction
    35 typedef TinyEnumT<Direction> DirectionByte; //typedefing-enumification of Direction
    28 
    36 
       
    37 /**
       
    38  * Return the reverse of a direction
       
    39  *
       
    40  * @param d The direction to get the reverse from
       
    41  * @return The reverse Direction
       
    42  */
    29 static inline Direction ReverseDir(Direction d)
    43 static inline Direction ReverseDir(Direction d)
    30 {
    44 {
    31 	return (Direction)(4 ^ d);
    45 	return (Direction)(4 ^ d);
    32 }
    46 }
    33 
    47 
    34 
    48 
       
    49 /**
       
    50  * Enumeration for the difference between two directions.
       
    51  *
       
    52  * This enumeration is used to mark differences between
       
    53  * two directions. If you get one direction you can align
       
    54  * a second direction in 8 different ways. This enumeration
       
    55  * only contains 6 of these 8 differences, but the remaining
       
    56  * two can be calculated by adding to differences together.
       
    57  * This also means you can add two differences together and
       
    58  * get the difference you really want to get. The difference
       
    59  * of 45 degrees left + the difference of 45 degrees right results in the
       
    60  * difference of 0 degrees.
       
    61  *
       
    62  * @note To get this mentioned addition of direction you must use
       
    63  *       modulo DIR_END or use the #ChangeDirDiff(DirDiff, DirDiff) function.
       
    64  * @see ChangeDirDiff(DirDiff, DirDiff)
       
    65  */
    35 enum DirDiff {
    66 enum DirDiff {
    36 	DIRDIFF_SAME    = 0,
    67 	DIRDIFF_SAME    = 0,    ///< Both directions faces to the same direction
    37 	DIRDIFF_45RIGHT = 1,
    68 	DIRDIFF_45RIGHT = 1,    ///< Angle of 45 degrees right
    38 	DIRDIFF_90RIGHT = 2,
    69 	DIRDIFF_90RIGHT = 2,    ///< Angle of 90 degrees right
    39 	DIRDIFF_REVERSE = 4,
    70 	DIRDIFF_REVERSE = 4,    ///< One direction is the opposit of the other one
    40 	DIRDIFF_90LEFT  = 6,
    71 	DIRDIFF_90LEFT  = 6,    ///< Angle of 90 degrees left
    41 	DIRDIFF_45LEFT  = 7
    72 	DIRDIFF_45LEFT  = 7     ///< Angle of 45 degrees left
    42 };
    73 };
    43 
    74 
       
    75 /**
       
    76  * Calculate the difference between to directions
       
    77  *
       
    78  * @param d0 The first direction as the base
       
    79  * @param d1 The second direction as the offset from the base
       
    80  * @return The difference how the second directions drifts of the first one.
       
    81  */
    44 static inline DirDiff DirDifference(Direction d0, Direction d1)
    82 static inline DirDiff DirDifference(Direction d0, Direction d1)
    45 {
    83 {
    46 	return (DirDiff)((d0 + 8 - d1) % 8);
    84 	return (DirDiff)((d0 + 8 - d1) % 8);
    47 }
    85 }
    48 
    86 
       
    87 /**
       
    88  * Applies two differences together
       
    89  *
       
    90  * This function adds two differences together and return the resulting
       
    91  * difference. So adding two DIRDIFF_REVERSE together results in the
       
    92  * DIRDIFF_SAME difference.
       
    93  *
       
    94  * @param d The first difference
       
    95  * @param delta The second difference to add on
       
    96  * @return The resulting difference
       
    97  */
    49 static inline DirDiff ChangeDirDiff(DirDiff d, DirDiff delta)
    98 static inline DirDiff ChangeDirDiff(DirDiff d, DirDiff delta)
    50 {
    99 {
    51 	return (DirDiff)((d + delta) % 8);
   100 	return (DirDiff)((d + delta) % 8);
    52 }
   101 }
    53 
   102 
    54 
   103 /**
       
   104  * Change a direction by a given difference
       
   105  *
       
   106  * This functions returns a new direction of the given direction
       
   107  * which is rotated by the given difference.
       
   108  *
       
   109  * @param d The direction to get a new direction from
       
   110  * @param delta The offset/drift applied to the direction
       
   111  * @return The new direction
       
   112  */
    55 static inline Direction ChangeDir(Direction d, DirDiff delta)
   113 static inline Direction ChangeDir(Direction d, DirDiff delta)
    56 {
   114 {
    57 	return (Direction)((d + delta) % 8);
   115 	return (Direction)((d + delta) % 8);
    58 }
   116 }
    59 
   117 
    60 
   118 
    61 /* Direction commonly used as the direction of entering and leaving tiles, 4-way */
   119 /**
       
   120  * Enumeration for diagonal directions.
       
   121  *
       
   122  * This enumeration is used for the 4 direction of the tile-edges.
       
   123  */
    62 enum DiagDirection {
   124 enum DiagDirection {
    63 	DIAGDIR_BEGIN = 0,
   125 	DIAGDIR_BEGIN = 0,      ///< Used for iterations
    64 	DIAGDIR_NE  = 0,      ///< Northeast, upper right on your monitor
   126 	DIAGDIR_NE  = 0,        ///< Northeast, upper right on your monitor
    65 	DIAGDIR_SE  = 1,
   127 	DIAGDIR_SE  = 1,        ///< Southeast
    66 	DIAGDIR_SW  = 2,
   128 	DIAGDIR_SW  = 2,        ///< Southwest
    67 	DIAGDIR_NW  = 3,
   129 	DIAGDIR_NW  = 3,        ///< Northwest
    68 	DIAGDIR_END,
   130 	DIAGDIR_END,            ///< Used for iterations
    69 	INVALID_DIAGDIR = 0xFF,
   131 	INVALID_DIAGDIR = 0xFF, ///< Flag for an invalid DiagDirection
    70 };
   132 };
    71 
   133 
    72 DECLARE_POSTFIX_INCREMENT(DiagDirection);
   134 DECLARE_POSTFIX_INCREMENT(DiagDirection);
    73 
   135 
    74 /** Define basic enum properties */
   136 /** Define basic enum properties */
    75 template <> struct EnumPropsT<DiagDirection> : MakeEnumPropsT<DiagDirection, byte, DIAGDIR_BEGIN, DIAGDIR_END, INVALID_DIAGDIR> {};
   137 template <> struct EnumPropsT<DiagDirection> : MakeEnumPropsT<DiagDirection, byte, DIAGDIR_BEGIN, DIAGDIR_END, INVALID_DIAGDIR> {};
    76 typedef TinyEnumT<DiagDirection> DiagDirectionByte; //typedefing-enumification of DiagDirection
   138 typedef TinyEnumT<DiagDirection> DiagDirectionByte; //typedefing-enumification of DiagDirection
    77 
   139 
       
   140 /**
       
   141  * Returns the reverse direction of the given DiagDirection
       
   142  *
       
   143  * @param d The DiagDirection to get the reverse from
       
   144  * @return The reverse direction
       
   145  */
    78 static inline DiagDirection ReverseDiagDir(DiagDirection d)
   146 static inline DiagDirection ReverseDiagDir(DiagDirection d)
    79 {
   147 {
    80 	return (DiagDirection)(2 ^ d);
   148 	return (DiagDirection)(2 ^ d);
    81 }
   149 }
    82 
   150 
    83 
   151 /**
       
   152  * Enumeration for the difference between to DiagDirection.
       
   153  *
       
   154  * As the DiagDirection only contains 4 possible directions the
       
   155  * difference between two of these directions can only be in 4 ways.
       
   156  * As the DirDiff enumeration the values can be added together and
       
   157  * you will get the resulting difference (use modulo DIAGDIR_END).
       
   158  *
       
   159  * @see DirDiff
       
   160  */
    84 enum DiagDirDiff {
   161 enum DiagDirDiff {
    85 	DIAGDIRDIFF_SAME    = 0,
   162 	DIAGDIRDIFF_SAME    = 0,        ///< Same directions
    86 	DIAGDIRDIFF_90RIGHT = 1,
   163 	DIAGDIRDIFF_90RIGHT = 1,        ///< 90 degrees right
    87 	DIAGDIRDIFF_REVERSE = 2,
   164 	DIAGDIRDIFF_REVERSE = 2,        ///< Reverse directions
    88 	DIAGDIRDIFF_90LEFT  = 3
   165 	DIAGDIRDIFF_90LEFT  = 3         ///< 90 degrees left
    89 };
   166 };
    90 
   167 
       
   168 /**
       
   169  * Applies a difference on a DiagDirection
       
   170  *
       
   171  * This function applies a difference on a DiagDirection and returns
       
   172  * the new DiagDirection.
       
   173  *
       
   174  * @param d The DiagDirection
       
   175  * @param delta The difference to applie on
       
   176  * @return The new direction which was calculated
       
   177  */
    91 static inline DiagDirection ChangeDiagDir(DiagDirection d, DiagDirDiff delta)
   178 static inline DiagDirection ChangeDiagDir(DiagDirection d, DiagDirDiff delta)
    92 {
   179 {
    93 	return (DiagDirection)((d + delta) % 4);
   180 	return (DiagDirection)((d + delta) % 4);
    94 }
   181 }
    95 
   182 
    96 
   183 /**
       
   184  * Convert a Direction to a DiagDirection.
       
   185  *
       
   186  * This function can be used to convert the 8-way Direction to
       
   187  * the 4-way DiagDirection. If the direction cannot be mapped its
       
   188  * "rounded clockwise". So DIR_N becomes DIAGDIR_NE.
       
   189  *
       
   190  * @param dir The direction to convert
       
   191  * @return The resulting DiagDirection, maybe "rounded clockwise".
       
   192  */
    97 static inline DiagDirection DirToDiagDir(Direction dir)
   193 static inline DiagDirection DirToDiagDir(Direction dir)
    98 {
   194 {
    99 	return (DiagDirection)(dir >> 1);
   195 	return (DiagDirection)(dir >> 1);
   100 }
   196 }
   101 
   197 
   102 
   198 /**
       
   199  * Convert a DiagDirection to a Direction.
       
   200  *
       
   201  * This function can be used to convert the 4-way DiagDirection
       
   202  * to the 8-way Direction. As 4-way are less than 8-way not all
       
   203  * possible directions can be calculated.
       
   204  *
       
   205  * @param dir The direction to convert
       
   206  * @return The resulting Direction
       
   207  */
   103 static inline Direction DiagDirToDir(DiagDirection dir)
   208 static inline Direction DiagDirToDir(DiagDirection dir)
   104 {
   209 {
   105 	return (Direction)(dir * 2 + 1);
   210 	return (Direction)(dir * 2 + 1);
   106 }
   211 }
   107 
   212 
   108 
   213 
   109 /* the 2 axis */
   214 /**
       
   215  * Enumeration for the two axis X and Y
       
   216  *
       
   217  * This enumeration represente the two axis X and Y in the game.
       
   218  * The X axis is the one which goes align the north-west edge
       
   219  * (and south-east edge). The Y axis must be so the one which goes
       
   220  * align the north-east edge (and south-west) edge.
       
   221  */
   110 enum Axis {
   222 enum Axis {
   111 	AXIS_X = 0,
   223 	AXIS_X = 0,     ///< The X axis
   112 	AXIS_Y = 1,
   224 	AXIS_Y = 1,     ///< The y axis
   113 	AXIS_END
   225 	AXIS_END        ///< Used for iterations
   114 };
   226 };
   115 
   227 
   116 
   228 
       
   229 /**
       
   230  * Select the other axis as provided.
       
   231  *
       
   232  * This is basically the not-operator for the axis.
       
   233  *
       
   234  * @param a The given axis
       
   235  * @return The other axis
       
   236  */
   117 static inline Axis OtherAxis(Axis a)
   237 static inline Axis OtherAxis(Axis a)
   118 {
   238 {
   119 	return (Axis)(a ^ 1);
   239 	return (Axis)(a ^ 1);
   120 }
   240 }
   121 
   241 
   122 
   242 
       
   243 /**
       
   244  * Convert a DiagDirection to the axis.
       
   245  *
       
   246  * This function returns the axis which belongs to the given
       
   247  * DiagDirection. The axis X belongs to the DiagDirection
       
   248  * north-east and south-west.
       
   249  *
       
   250  * @param d The DiagDirection
       
   251  * @return The axis which belongs to the direction
       
   252  */
   123 static inline Axis DiagDirToAxis(DiagDirection d)
   253 static inline Axis DiagDirToAxis(DiagDirection d)
   124 {
   254 {
   125 	return (Axis)(d & 1);
   255 	return (Axis)(d & 1);
   126 }
   256 }
   127 
   257 
   128 
   258 
   129 /*
   259 /**
   130  * Converts an Axis to a DiagDirection
   260  * Converts an Axis to a DiagDirection
   131  * Points always in the positive direction, i.e. S[EW]
   261  *
       
   262  * This function returns the DiagDirection which
       
   263  * belongs to the axis. As 2 directions are mapped to an axis
       
   264  * this function returns the one which points to south,
       
   265  * either south-west (on X axis) or south-east (on Y axis)
       
   266  *
       
   267  * @param a The axis
       
   268  * @return The direction pointed to south
   132  */
   269  */
   133 static inline DiagDirection AxisToDiagDir(Axis a)
   270 static inline DiagDirection AxisToDiagDir(Axis a)
   134 {
   271 {
   135 	return (DiagDirection)(2 - a);
   272 	return (DiagDirection)(2 - a);
   136 }
   273 }
   144 static inline DiagDirection XYNSToDiagDir(Axis xy, uint ns)
   281 static inline DiagDirection XYNSToDiagDir(Axis xy, uint ns)
   145 {
   282 {
   146 	return (DiagDirection)(xy * 3 ^ ns * 2);
   283 	return (DiagDirection)(xy * 3 ^ ns * 2);
   147 }
   284 }
   148 
   285 
   149 
   286 /**
       
   287  * Checks if an interger value is a valid DiagDirection
       
   288  *
       
   289  * @param d The value to check
       
   290  * @return True if the value belongs to a DiagDirection, else false
       
   291  */
   150 static inline bool IsValidDiagDirection(DiagDirection d)
   292 static inline bool IsValidDiagDirection(DiagDirection d)
   151 {
   293 {
   152 	return d < DIAGDIR_END;
   294 	return d < DIAGDIR_END;
   153 }
   295 }
   154 
   296 
       
   297 /**
       
   298  * Checks if an integer value is a valid Direction
       
   299  *
       
   300  * @param d The value to check
       
   301  * @return True if the value belongs to a Direction, else false
       
   302  */
   155 static inline bool IsValidDirection(Direction d)
   303 static inline bool IsValidDirection(Direction d)
   156 {
   304 {
   157 	return d < DIR_END;
   305 	return d < DIR_END;
   158 }
   306 }
   159 
   307 
       
   308 /**
       
   309  * Checks if an integer value is a valid Axis
       
   310  *
       
   311  * @param d The value to check
       
   312  * @return True if the value belongs to an Axis, else false
       
   313  */
   160 static inline bool IsValidAxis(Axis d)
   314 static inline bool IsValidAxis(Axis d)
   161 {
   315 {
   162 	return d < AXIS_END;
   316 	return d < AXIS_END;
   163 }
   317 }
   164 
   318