From 876329da8723082813ce229eec75cda179bef518 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=CE=B6eh=20Matt?= <5415177+ZehMatt@users.noreply.github.com> Date: Tue, 7 Sep 2021 17:43:38 +0300 Subject: [PATCH] Fix hash bucketing of paint entries --- src/openrct2/paint/Paint.cpp | 6 +++--- src/openrct2/paint/Paint.h | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/openrct2/paint/Paint.cpp b/src/openrct2/paint/Paint.cpp index a27565383e..1b06b4b002 100644 --- a/src/openrct2/paint/Paint.cpp +++ b/src/openrct2/paint/Paint.cpp @@ -56,7 +56,7 @@ static void PaintPSImageWithBoundingBoxes(rct_drawpixelinfo* dpi, paint_struct* static void PaintPSImage(rct_drawpixelinfo* dpi, paint_struct* ps, uint32_t imageId, int32_t x, int32_t y); static uint32_t PaintPSColourifyImage(uint32_t imageId, ViewportInteractionItem spriteType, uint32_t viewFlags); -static constexpr int32_t CalculatePositionHash(const paint_struct& ps, uint8_t rotation) +static constexpr uint32_t CalculatePositionHash(const paint_struct& ps, uint8_t rotation) { auto pos = CoordsXY{ ps.bounds.x, ps.bounds.y }.Rotate(rotation); switch (rotation) @@ -72,13 +72,13 @@ static constexpr int32_t CalculatePositionHash(const paint_struct& ps, uint8_t r break; } - return pos.x + pos.y; + return static_cast(pos.x + pos.y); } static void PaintSessionAddPSToQuadrant(paint_session* session, paint_struct* ps) { auto positionHash = CalculatePositionHash(*ps, session->CurrentRotation); - uint32_t paintQuadrantIndex = std::clamp(positionHash / 32, 0, MAX_PAINT_QUADRANTS - 1); + uint32_t paintQuadrantIndex = (positionHash / 32) % MAX_PAINT_QUADRANTS; ps->quadrant_index = paintQuadrantIndex; ps->next_quadrant_ps = session->Quadrants[paintQuadrantIndex]; session->Quadrants[paintQuadrantIndex] = ps; diff --git a/src/openrct2/paint/Paint.h b/src/openrct2/paint/Paint.h index 7a6787d18e..596208bfea 100644 --- a/src/openrct2/paint/Paint.h +++ b/src/openrct2/paint/Paint.h @@ -113,7 +113,10 @@ struct tunnel_entry uint8_t type; }; -#define MAX_PAINT_QUADRANTS 512 +// NOTE: This should be preferably a prime number. This is the amount of +// buckets used with the position hash, so the bucket is hash % max. +#define MAX_PAINT_QUADRANTS 521 + #define TUNNEL_MAX_COUNT 65 /**