From e1057864d8254e35854918b2b60db6dc43025ecf Mon Sep 17 00:00:00 2001 From: rubidium Date: Fri, 27 Apr 2007 21:29:36 +0000 Subject: [PATCH] (svn r9729) -Documentation: add some documentation in various places --- src/heightmap.cpp | 7 +++ src/map.cpp | 87 ++++++++++++++++++++++---- src/map.h | 120 ++++++++++++++++++++++++++++-------- src/rail_map.h | 152 +++++++++++++++++++++++++++++++++++----------- src/tunnel_map.h | 53 +++++++++++++++- 5 files changed, 342 insertions(+), 77 deletions(-) diff --git a/src/heightmap.cpp b/src/heightmap.cpp index 3d5ddb4998..360127dc5b 100644 --- a/src/heightmap.cpp +++ b/src/heightmap.cpp @@ -275,6 +275,13 @@ static bool ReadHeightmapBMP(char *filename, uint *x, uint *y, byte **map) return true; } +/** + * Converts a given grayscale map to something that fits in OTTD map system + * and create a map of that data. + * @param img_width the with of the image in pixels/tiles + * @param img_height the height of the image in pixels/tiles + * @param map the input map + */ static void GrayscaleToMapHeights(uint img_width, uint img_height, byte *map) { /* Defines the detail of the aspect ratio (to avoid doubles) */ diff --git a/src/map.cpp b/src/map.cpp index 092603b4d5..5e511772f9 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -16,24 +16,29 @@ extern "C" _CRTIMP void __cdecl _assert(void *, void *, unsigned); #endif -uint _map_log_x; -uint _map_size_x; -uint _map_size_y; -uint _map_tile_mask; -uint _map_size; +uint _map_log_x; ///< 2^_map_log_x == _map_size_x +uint _map_size_x; ///< Size of the map along the X +uint _map_size_y; ///< Size of the map along the Y +uint _map_size; ///< The number of tiles on the map +uint _map_tile_mask; ///< _map_size - 1 (to mask the mapsize) -Tile *_m = NULL; -TileExtended *_me = NULL; +Tile *_m = NULL; ///< Tiles of the map +TileExtended *_me = NULL; ///< Extended Tiles of the map +/** + * (Re)allocates a map with the given dimension + * @param size_x the width of the map along the NE/SW edge + * @param size_y the 'height' of the map along the SE/NW edge + */ void AllocateMap(uint size_x, uint size_y) { /* Make sure that the map size is within the limits and that * the x axis size is a power of 2. */ if (size_x < 64 || size_x > 2048 || size_y < 64 || size_y > 2048 || - (size_x&(size_x-1)) != 0 || - (size_y&(size_y-1)) != 0) + (size_x & (size_x - 1)) != 0 || + (size_y & (size_y - 1)) != 0) error("Invalid map size"); DEBUG(map, 1, "Allocating map of size %dx%d", size_x, size_y); @@ -92,7 +97,12 @@ TileIndex TileAdd(TileIndex tile, TileIndexDiff add, } #endif - +/** + * Scales the given value by the map size, where the given value is + * for a 256 by 256 map + * @param n the value to scale + * @return the scaled size + */ uint ScaleByMapSize(uint n) { /* First shift by 12 to prevent integer overflow for large values of n. @@ -102,7 +112,12 @@ uint ScaleByMapSize(uint n) } -/* Scale relative to the circumference of the map */ +/** + * Scales the given value by the maps circumference, where the given + * value is for a 256 by 256 map + * @param n the value to scale + * @return the scaled size + */ uint ScaleByMapSize1D(uint n) { /* Normal circumference for the X+Y is 256+256 = 1<<9 @@ -113,12 +128,18 @@ uint ScaleByMapSize1D(uint n) } -/* This function checks if we add addx/addy to tile, if we +/** + * This function checks if we add addx/addy to tile, if we * do wrap around the edges. For example, tile = (10,2) and * addx = +3 and addy = -4. This function will now return * INVALID_TILE, because the y is wrapped. This is needed in * for example, farmland. When the tile is not wrapped, - * the result will be tile + TileDiffXY(addx, addy) */ + * the result will be tile + TileDiffXY(addx, addy) + * @param tile the 'starting' point of the adding + * @param addx the amount of tiles in the X direction to add + * @param addy the amount of tiles in the Y direction to add + * @return translated tile, or INVALID_TILE when it would've wrapped. + */ uint TileAddWrap(TileIndex tile, int addx, int addy) { uint x = TileX(tile) + addx; @@ -131,6 +152,7 @@ uint TileAddWrap(TileIndex tile, int addx, int addy) return INVALID_TILE; } +/** 'Lookup table' for tile offsets given a DiagDirection */ extern const TileIndexDiffC _tileoffs_by_diagdir[] = { {-1, 0}, ///< DIAGDIR_NE { 0, 1}, ///< DIAGDIR_SE @@ -138,6 +160,7 @@ extern const TileIndexDiffC _tileoffs_by_diagdir[] = { { 0, -1} ///< DIAGDIR_NW }; +/** 'Lookup table' for tile offsets given a Direction */ extern const TileIndexDiffC _tileoffs_by_dir[] = { {-1, -1}, ///< DIR_N {-1, 0}, ///< DIR_NE @@ -149,6 +172,15 @@ extern const TileIndexDiffC _tileoffs_by_dir[] = { { 0, -1} ///< DIR_NW }; +/** + * Gets the Manhattan distance between the two given tiles. + * The Manhattan distance is the sum of the delta of both the + * X and Y component. + * Also known as L1-Norm + * @param t0 the start tile + * @param t1 the end tile + * @return the distance + */ uint DistanceManhattan(TileIndex t0, TileIndex t1) { const uint dx = delta(TileX(t0), TileX(t1)); @@ -157,6 +189,15 @@ uint DistanceManhattan(TileIndex t0, TileIndex t1) } +/** + * Gets the 'Square' distance between the two given tiles. + * The 'Square' distance is the square of the shortest (straight line) + * distance between the two tiles. + * Also known as euclidian- or L2-Norm squared. + * @param t0 the start tile + * @param t1 the end tile + * @return the distance + */ uint DistanceSquare(TileIndex t0, TileIndex t1) { const int dx = TileX(t0) - TileX(t1); @@ -165,6 +206,13 @@ uint DistanceSquare(TileIndex t0, TileIndex t1) } +/** + * Gets the biggest distance component (x or y) between the two given tiles. + * Also known as L-Infinity-Norm. + * @param t0 the start tile + * @param t1 the end tile + * @return the distance + */ uint DistanceMax(TileIndex t0, TileIndex t1) { const uint dx = delta(TileX(t0), TileX(t1)); @@ -173,6 +221,14 @@ uint DistanceMax(TileIndex t0, TileIndex t1) } +/** + * Gets the biggest distance component (x or y) between the two given tiles + * plus the Manhattan distance, i.e. two times the biggest distance component + * and once the smallest component. + * @param t0 the start tile + * @param t1 the end tile + * @return the distance + */ uint DistanceMaxPlusManhattan(TileIndex t0, TileIndex t1) { const uint dx = delta(TileX(t0), TileX(t1)); @@ -180,6 +236,11 @@ uint DistanceMaxPlusManhattan(TileIndex t0, TileIndex t1) return dx > dy ? 2 * dx + dy : 2 * dy + dx; } +/** + * Param the minimum distance to an edge + * @param tile the tile to get the distance from + * @return the distance from the edge in tiles + */ uint DistanceFromEdge(TileIndex tile) { const uint xl = TileX(tile); diff --git a/src/map.h b/src/map.h index b3e5eef5d4..5b11e26273 100644 --- a/src/map.h +++ b/src/map.h @@ -7,29 +7,41 @@ #include "stdafx.h" -/* Putting externs inside inline functions seems to confuse the aliasing - * checking on MSVC6. Never use those variables directly. */ -extern uint _map_log_x; -extern uint _map_size_x; -extern uint _map_size_y; extern uint _map_tile_mask; -extern uint _map_size; + +/** + * 'Wraps' the given tile to it is within the map. It does + * this by masking the 'high' bits of. + * @param x the tile to 'wrap' + */ #define TILE_MASK(x) ((x) & _map_tile_mask) +/** + * Asserts when the tile is outside of the map. + * @param x the tile to check + */ #define TILE_ASSERT(x) assert(TILE_MASK(x) == (x)); +/** + * Data that is stored per tile. Also used TileExtended for this. + * Look at docs/landscape.html for the exact meaning of the members. + */ struct Tile { - byte type_height; - byte m1; - uint16 m2; - byte m3; - byte m4; - byte m5; - byte m6; + byte type_height; ///< The type (bits 4..7) and height of the northern corner + byte m1; ///< Primarily used for ownership information + uint16 m2; ///< Primarily used for indices to towns, industries and stations + byte m3; ///< General purpose + byte m4; ///< General purpose + byte m5; ///< General purpose + byte m6; ///< Primarily used for bridges and rainforest/desert }; +/** + * Data that is stored per tile. Also used Tile for this. + * Look at docs/landscape.html for the exact meaning of the members. + */ struct TileExtended { - byte m7; + byte m7; ///< Primarily used for newgrf support }; extern Tile *_m; @@ -37,16 +49,64 @@ extern TileExtended *_me; void AllocateMap(uint size_x, uint size_y); -/* binary logarithm of the map size, try to avoid using this one */ -static inline uint MapLogX() { return _map_log_x; } -/* The size of the map */ -static inline uint MapSizeX() { return _map_size_x; } -static inline uint MapSizeY() { return _map_size_y; } -/* The maximum coordinates */ -static inline uint MapMaxX() { return _map_size_x - 1; } -static inline uint MapMaxY() { return _map_size_y - 1; } -/* The number of tiles in the map */ -static inline uint MapSize() { return _map_size; } +/** + * Logarithm of the map size along the X side. + * @note try to avoid using this one + * @return 2^"return value" == MapSizeX() + */ +static inline uint MapLogX() +{ + extern uint _map_log_x; + return _map_log_x; +} + +/** + * Get the size of the map along the X + * @return the number of tiles along the X of the map + */ +static inline uint MapSizeX() +{ + extern uint _map_size_x; + return _map_size_x; +} + +/** + * Get the size of the map along the Y + * @return the number of tiles along the Y of the map + */ +static inline uint MapSizeY() +{ + extern uint _map_size_y; + return _map_size_y; +} + +/** + * Get the size of the map + * @return the number of tiles of the map + */ +static inline uint MapSize() +{ + extern uint _map_size; + return _map_size; +} + +/** + * Gets the maximum X coordinate within the map, including MP_VOID + * @return the maximum X coordinate + */ +static inline uint MapMaxX() +{ + return MapSizeX() - 1; +} + +/** + * Gets the maximum X coordinate within the map, including MP_VOID + * @return the maximum X coordinate + */ +static inline uint MapMaxY() +{ + return MapSizeY() - 1; +} /* Scale a number relative to the map size */ uint ScaleByMapSize(uint); // Scale relative to the number of tiles @@ -76,7 +136,7 @@ static inline TileIndex TileVirtXY(uint x, uint y) enum { - INVALID_TILE = (TileIndex)-1 + INVALID_TILE = (TileIndex)-1 ///< The very nice invalid tile marker }; enum { @@ -86,11 +146,21 @@ enum { }; +/** + * Get the X component of a tile + * @param tile the tile to get the X component of + * @return the X component + */ static inline uint TileX(TileIndex tile) { return tile & MapMaxX(); } +/** + * Get the Y component of a tile + * @param tile the tile to get the Y component of + * @return the Y component + */ static inline uint TileY(TileIndex tile) { return tile >> MapLogX(); diff --git a/src/rail_map.h b/src/rail_map.h index b09bccf888..e4fd20b89e 100644 --- a/src/rail_map.h +++ b/src/rail_map.h @@ -10,13 +10,21 @@ #include "tile.h" +/** Different types of Rail-related tiles */ enum RailTileType { - RAIL_TILE_NORMAL = 0, - RAIL_TILE_SIGNALS = 1, - RAIL_TILE_WAYPOINT = 2, - RAIL_TILE_DEPOT = 3, + RAIL_TILE_NORMAL = 0, ///< Normal rail tile without signals + RAIL_TILE_SIGNALS = 1, ///< Normal rail tile with signals + RAIL_TILE_WAYPOINT = 2, ///< Waypoint (X or Y direction) + RAIL_TILE_DEPOT = 3, ///< Depot (one entrance) }; +/** + * Returns the RailTileType (normal with or without signals, + * waypoint or depot). + * @param t the tile to get the information from + * @pre IsTileType(t, MP_RAILWAY) + * @return the RailTileType + */ static inline RailTileType GetRailTileType(TileIndex t) { assert(IsTileType(t, MP_RAILWAY)); @@ -26,23 +34,32 @@ static inline RailTileType GetRailTileType(TileIndex t) /** * Returns whether this is plain rails, with or without signals. Iow, if this * tiles RailTileType is RAIL_TILE_NORMAL or RAIL_TILE_SIGNALS. + * @param t the tile to get the information from + * @pre IsTileType(t, MP_RAILWAY) + * @return true if and only if the tile is normal rail (with or without signals) */ -static inline bool IsPlainRailTile(TileIndex tile) +static inline bool IsPlainRailTile(TileIndex t) { - RailTileType rtt = GetRailTileType(tile); + RailTileType rtt = GetRailTileType(t); return rtt == RAIL_TILE_NORMAL || rtt == RAIL_TILE_SIGNALS; } /** * Checks if a rail tile has signals. + * @param t the tile to get the information from + * @pre IsTileType(t, MP_RAILWAY) + * @return true if and only if the tile has signals */ -static inline bool HasSignals(TileIndex tile) +static inline bool HasSignals(TileIndex t) { - return GetRailTileType(tile) == RAIL_TILE_SIGNALS; + return GetRailTileType(t) == RAIL_TILE_SIGNALS; } /** * Add/remove the 'has signal' bit from the RailTileType + * @param tile the tile to add/remove the signals to/from + * @param signals whether the rail tile should have signals or not + * @pre IsPlainRailTile(tile) */ static inline void SetHasSignals(TileIndex tile, bool signals) { @@ -50,81 +67,144 @@ static inline void SetHasSignals(TileIndex tile, bool signals) SB(_m[tile].m5, 6, 1, signals); } - +/** + * Is this tile a rail depot? + * @param t the tile to get the information from + * @pre IsTileType(t, MP_RAILWAY) + * @return true if and only if the tile is a rail depot + */ static inline bool IsRailDepot(TileIndex t) { return GetRailTileType(t) == RAIL_TILE_DEPOT; } - +/** + * Is this tile a rail waypoint? + * @param t the tile to get the information from + * @pre IsTileType(t, MP_RAILWAY) + * @return true if and only if the tile is a rail waypoint + */ static inline bool IsRailWaypoint(TileIndex t) { return GetRailTileType(t) == RAIL_TILE_WAYPOINT; } +/** + * Gets the rail type of the given tile + * @param t the tile to get the rail type from + * @return the rail type of the tile + */ static inline RailType GetRailType(TileIndex t) { return (RailType)GB(_m[t].m3, 0, 4); } +/** + * Sets the track bits of the given tile + * @param t the tile to set the track bits of + * @param r the new track bits for the tile + */ static inline void SetRailType(TileIndex t, RailType r) { SB(_m[t].m3, 0, 4, r); } +/** + * Gets the rail type of the given tile + * @param t the tile to get the rail type from + * @return the rail type of the tile + */ static inline TrackBits GetTrackBits(TileIndex tile) { return (TrackBits)GB(_m[tile].m5, 0, 6); } +/** + * Sets the track bits of the given tile + * @param t the tile to set the track bits of + * @param b the new track bits for the tile + */ static inline void SetTrackBits(TileIndex t, TrackBits b) { SB(_m[t].m5, 0, 6, b); } /** - * Returns whether the given track is present on the given tile. Tile must be - * a plain rail tile (IsPlainRailTile()). + * Returns whether the given track is present on the given tile. + * @param tile the tile to check the track presence of + * @param track the track to search for on the tile + * @pre IsPlainRailTile(tile) + * @return true if and only if the given track exists on the tile */ static inline bool HasTrack(TileIndex tile, Track track) { return HASBIT(GetTrackBits(tile), track); } - +/** + * Returns the direction the depot is facing to + * @param t the tile to get the depot facing from + * @pre IsRailDepotTile(t) + * @return the direction the depot is facing + */ static inline DiagDirection GetRailDepotDirection(TileIndex t) { return (DiagDirection)GB(_m[t].m5, 0, 2); } +/** + * Returns the axis of the waypoint + * @param t the tile to get the waypoint axis from + * @pre IsRailWaypointTile(t) + * @return the axis of the waypoint + */ static inline Axis GetWaypointAxis(TileIndex t) { return (Axis)GB(_m[t].m5, 0, 1); } +/** + * Returns the track of the waypoint + * @param t the tile to get the waypoint track from + * @pre IsRailWaypointTile(t) + * @return the track of the waypoint + */ static inline Track GetRailWaypointTrack(TileIndex t) { return AxisToTrack(GetWaypointAxis(t)); } +/** + * Returns the track bits of the waypoint + * @param t the tile to get the waypoint track bits from + * @pre IsRailWaypointTile(t) + * @return the track bits of the waypoint + */ static inline TrackBits GetRailWaypointBits(TileIndex t) { return TrackToTrackBits(GetRailWaypointTrack(t)); } +/** + * Returns waypoint index (for the waypoint pool) + * @param t the tile to get the waypoint index from + * @pre IsRailWaypointTile(t) + * @return the waypoint index + */ static inline WaypointID GetWaypointIndex(TileIndex t) { return (WaypointID)_m[t].m2; } +/** Type of signal, i.e. how does the signal behave? */ enum SignalType { - SIGTYPE_NORMAL = 0, // normal signal - SIGTYPE_ENTRY = 1, // presignal block entry - SIGTYPE_EXIT = 2, // presignal block exit - SIGTYPE_COMBO = 3 // presignal inter-block + SIGTYPE_NORMAL = 0, ///< normal signal + SIGTYPE_ENTRY = 1, ///< presignal block entry + SIGTYPE_EXIT = 2, ///< presignal block exit + SIGTYPE_COMBO = 3 ///< presignal inter-block }; static inline SignalType GetSignalType(TileIndex t) @@ -160,10 +240,10 @@ static inline void CycleSignalSide(TileIndex t, Track track) SB(_m[t].m3, pos, 2, sig); } - +/** Variant of the signal, i.e. how does the signal look? */ enum SignalVariant { - SIG_ELECTRIC = 0, - SIG_SEMAPHORE = 1 + SIG_ELECTRIC = 0, ///< Light signal + SIG_SEMAPHORE = 1 ///< Old-fashioned semaphore signal }; static inline SignalVariant GetSignalVariant(TileIndex t) @@ -186,8 +266,8 @@ static inline bool IsSignalPresent(TileIndex t, byte signalbit) * normal boolean evaluation, since that will make future additions easier. */ enum SignalState { - SIGNAL_STATE_RED = 0, - SIGNAL_STATE_GREEN = 1, + SIGNAL_STATE_RED = 0, ///< The signal is red + SIGNAL_STATE_GREEN = 1, ///< The signal is green }; static inline SignalState GetSingleSignalState(TileIndex t, byte signalbit) @@ -243,21 +323,21 @@ static inline SignalState GetSignalStateByTrackdir(TileIndex tile, Trackdir trac */ RailType GetTileRailType(TileIndex tile); - +/** The ground 'under' the rail */ enum RailGroundType { - RAIL_GROUND_BARREN = 0, - RAIL_GROUND_GRASS = 1, - RAIL_GROUND_FENCE_NW = 2, - RAIL_GROUND_FENCE_SE = 3, - RAIL_GROUND_FENCE_SENW = 4, - RAIL_GROUND_FENCE_NE = 5, - RAIL_GROUND_FENCE_SW = 6, - RAIL_GROUND_FENCE_NESW = 7, - RAIL_GROUND_FENCE_VERT1 = 8, - RAIL_GROUND_FENCE_VERT2 = 9, - RAIL_GROUND_FENCE_HORIZ1 = 10, - RAIL_GROUND_FENCE_HORIZ2 = 11, - RAIL_GROUND_ICE_DESERT = 12, + RAIL_GROUND_BARREN = 0, ///< Nothing (dirt) + RAIL_GROUND_GRASS = 1, ///< Grassy + RAIL_GROUND_FENCE_NW = 2, ///< Grass with a fence at the NW edge + RAIL_GROUND_FENCE_SE = 3, ///< Grass with a fence at the SE edge + RAIL_GROUND_FENCE_SENW = 4, ///< Grass with a fence at the NW and SE edges + RAIL_GROUND_FENCE_NE = 5, ///< Grass with a fence at the NE edge + RAIL_GROUND_FENCE_SW = 6, ///< Grass with a fence at the SW edge + RAIL_GROUND_FENCE_NESW = 7, ///< Grass with a fence at the NE and SW edges + RAIL_GROUND_FENCE_VERT1 = 8, ///< Grass with a fence at the western side + RAIL_GROUND_FENCE_VERT2 = 9, ///< Grass with a fence at the eastern side + RAIL_GROUND_FENCE_HORIZ1 = 10, ///< Grass with a fence at the southern side + RAIL_GROUND_FENCE_HORIZ2 = 11, ///< Grass with a fence at the northern side + RAIL_GROUND_ICE_DESERT = 12, ///< Icy or sandy }; static inline void SetRailGroundType(TileIndex t, RailGroundType rgt) diff --git a/src/tunnel_map.h b/src/tunnel_map.h index 9cce870552..dde7bac63f 100644 --- a/src/tunnel_map.h +++ b/src/tunnel_map.h @@ -10,7 +10,12 @@ #include "map.h" #include "rail.h" - +/** + * Is this a tunnel (entrance)? + * @param t the tile that might be a tunnel + * @pre IsTileType(t, MP_TUNNELBRIDGE) + * @return true if and only if this tile is a tunnel (entrance) + */ static inline bool IsTunnel(TileIndex t) { assert(IsTileType(t, MP_TUNNELBRIDGE)); @@ -18,31 +23,60 @@ static inline bool IsTunnel(TileIndex t) } +/** + * Is this a tunnel (entrance)? + * @param t the tile that might be a tunnel + * @return true if and only if this tile is a tunnel (entrance) + */ static inline bool IsTunnelTile(TileIndex t) { return IsTileType(t, MP_TUNNELBRIDGE) && IsTunnel(t); } - +/** + * Gets the direction facing out of the tunnel + * @param t the tile to get the tunnel facing direction of + * @pre IsTunnelTile(t) + * @return the direction the tunnel is facing + */ static inline DiagDirection GetTunnelDirection(TileIndex t) { assert(IsTunnelTile(t)); return (DiagDirection)GB(_m[t].m5, 0, 2); } - +/** + * Gets the transport type of the tunnel (road or rail) + * @param t the tunnel entrance tile to get the type of + * @pre IsTunnelTile(t) + * @return the transport type in the tunnel + */ static inline TransportType GetTunnelTransportType(TileIndex t) { assert(IsTunnelTile(t)); return (TransportType)GB(_m[t].m5, 2, 2); } +/** + * Is this tunnel entrance in a snowy or desert area? + * @param t the tunnel entrance tile + * @pre IsTunnelTile(t) + * @return true if and only if the tunnel entrance is in a snowy/desert area + */ static inline bool HasTunnelSnowOrDesert(TileIndex t) { assert(IsTunnelTile(t)); return HASBIT(_m[t].m4, 7); } +/** + * Places this tunnel entrance in a snowy or desert area, + * or takes it out of there. + * @param t the tunnel entrance tile + * @param snow_or_desert is the entrance in snow or desert (true), when + * not in snow and not in desert false + * @pre IsTunnelTile(t) + */ static inline void SetTunnelSnowOrDesert(TileIndex t, bool snow_or_desert) { assert(IsTunnelTile(t)); @@ -54,6 +88,12 @@ TileIndex GetOtherTunnelEnd(TileIndex); bool IsTunnelInWay(TileIndex, uint z); +/** + * Makes a road tunnel entrance + * @param t the entrance of the tunnel + * @param o the owner of the entrance + * @param d the direction facing out of the tunnel + */ static inline void MakeRoadTunnel(TileIndex t, Owner o, DiagDirection d) { SetTileType(t, MP_TUNNELBRIDGE); @@ -64,6 +104,13 @@ static inline void MakeRoadTunnel(TileIndex t, Owner o, DiagDirection d) _m[t].m5 = TRANSPORT_ROAD << 2 | d; } +/** + * Makes a rail tunnel entrance + * @param t the entrance of the tunnel + * @param o the owner of the entrance + * @param d the direction facing out of the tunnel + * @param r the rail type used in the tunnel + */ static inline void MakeRailTunnel(TileIndex t, Owner o, DiagDirection d, RailType r) { SetTileType(t, MP_TUNNELBRIDGE);