* Add the vehicle sprites that should be drawn at a part of the screen. * @param dpi Rectangle being drawn. */
| 1119 | * @param dpi Rectangle being drawn. |
| 1120 | */ |
| 1121 | void ViewportAddVehicles(DrawPixelInfo *dpi) |
| 1122 | { |
| 1123 | /* The bounding rectangle */ |
| 1124 | const int l = dpi->left; |
| 1125 | const int r = dpi->left + dpi->width; |
| 1126 | const int t = dpi->top; |
| 1127 | const int b = dpi->top + dpi->height; |
| 1128 | |
| 1129 | /* Border size of MAX_VEHICLE_PIXEL_xy */ |
| 1130 | const int xb = MAX_VEHICLE_PIXEL_X * ZOOM_BASE; |
| 1131 | const int yb = MAX_VEHICLE_PIXEL_Y * ZOOM_BASE; |
| 1132 | |
| 1133 | /* The hash area to scan */ |
| 1134 | uint xl, xu, yl, yu; |
| 1135 | |
| 1136 | if (static_cast<uint>(dpi->width + xb) < GEN_HASHX_SIZE) { |
| 1137 | xl = GetViewportHashX(l - xb); |
| 1138 | xu = GetViewportHashX(r); |
| 1139 | } else { |
| 1140 | /* scan whole hash row */ |
| 1141 | xl = 0; |
| 1142 | xu = GEN_HASHX_MASK; |
| 1143 | } |
| 1144 | |
| 1145 | if (static_cast<uint>(dpi->height + yb) < GEN_HASHY_SIZE) { |
| 1146 | yl = GetViewportHashY(t - yb); |
| 1147 | yu = GetViewportHashY(b); |
| 1148 | } else { |
| 1149 | /* scan whole column */ |
| 1150 | yl = 0; |
| 1151 | yu = GEN_HASHY_MASK; |
| 1152 | } |
| 1153 | |
| 1154 | for (uint y = yl;; y = (y + GEN_HASHY_INC) & GEN_HASHY_MASK) { |
| 1155 | for (uint x = xl;; x = (x + GEN_HASHX_INC) & GEN_HASHX_MASK) { |
| 1156 | const Vehicle *v = _vehicle_viewport_hash[x + y]; // already masked & 0xFFF |
| 1157 | |
| 1158 | while (v != nullptr) { |
| 1159 | |
| 1160 | if (!v->vehstatus.Test(VehState::Hidden) && |
| 1161 | l <= v->coord.right + xb && |
| 1162 | t <= v->coord.bottom + yb && |
| 1163 | r >= v->coord.left - xb && |
| 1164 | b >= v->coord.top - yb) |
| 1165 | { |
| 1166 | /* |
| 1167 | * This vehicle can potentially be drawn as part of this viewport and |
| 1168 | * needs to be revalidated, as the sprite may not be correct. |
| 1169 | */ |
| 1170 | if (v->sprite_cache.revalidate_before_draw) { |
| 1171 | VehicleSpriteSeq seq; |
| 1172 | v->GetImage(v->direction, EIT_ON_MAP, &seq); |
| 1173 | |
| 1174 | if (seq.IsValid() && v->sprite_cache.sprite_seq != seq) { |
| 1175 | v->sprite_cache.sprite_seq = seq; |
| 1176 | /* |
| 1177 | * A sprite change may also result in a bounding box change, |
| 1178 | * so we need to update the bounding box again before we |
no test coverage detected