diff --git a/CMakeLists.txt b/CMakeLists.txt index a3d0918..295cb6f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,6 +36,8 @@ if(WHOA_STORM_FLAVOR STREQUAL "SC1") if (WHOA_SYSTEM_MAC OR WHOA_SYSTEM_LINUX) add_definitions(-DWHOA_STORM_C_CRIT_SECT_RECURSIVE) endif() + + add_definitions(-DWHOA_RECT_USES_SCREEN_COORDINATES) elseif(WHOA_STORM_FLAVOR STREQUAL "WOW") message(STATUS "Building Storm with World of Warcraft flavoring") else() diff --git a/storm/Region.cpp b/storm/Region.cpp index 537e0d5..9f1ad53 100644 --- a/storm/Region.cpp +++ b/storm/Region.cpp @@ -27,10 +27,17 @@ void AddSourceRect(TSGrowableArray* sourceArray, const RECTF* rect, void } int32_t CheckForIntersection(const RECTF* sourceRect, const RECTF* targetRect) { +#if defined(WHOA_RECT_USES_SCREEN_COORDINATES) + return sourceRect->left < targetRect->right + && sourceRect->top < targetRect->bottom + && sourceRect->right > targetRect->left + && sourceRect->bottom > targetRect->top; +#else return sourceRect->left < targetRect->right && sourceRect->bottom < targetRect->top && sourceRect->right > targetRect->left && sourceRect->top > targetRect->bottom; +#endif } void CombineRectangles(TSGrowableArray* combinedArray) { @@ -41,12 +48,18 @@ void CombineRectangles(TSGrowableArray* combinedArray) { if (rctA->left == rctB->left && rctA->right == rctB->right) { if (rctA->bottom == rctB->top || rctB->bottom == rctA->top) { +#if defined(WHOA_RECT_USES_SCREEN_COORDINATES) + rctA->top = std::min(rctB->top, rctA->top); + rctA->bottom = std::max(rctB->bottom, rctA->bottom); +#else rctA->bottom = std::min(rctB->bottom, rctA->bottom); rctA->top = std::max(rctB->top, rctA->top); +#endif DeleteRect(rctB); break; } } + if (rctA->left == rctB->right || rctB->left == rctA->right) { if (rctA->bottom == rctB->bottom && rctA->top == rctB->top) { rctA->left = std::min(rctB->left, rctA->left); @@ -57,9 +70,23 @@ void CombineRectangles(TSGrowableArray* combinedArray) { } if (rctA->left == rctB->right || rctB->left == rctA->right) { - if (rctA->bottom < rctB->top && rctB->bottom < rctA->top) { - RECTF newrect[5]; + RECTF newrect[5]; +#if defined(WHOA_RECT_USES_SCREEN_COORDINATES) + if (rctA->top < rctB->bottom && rctB->top < rctA->bottom) { + newrect[0] = { rctA->left, rctA->top, rctA->right, rctB->top }; + newrect[1] = { rctB->left, rctB->top, rctB->right, rctA->top }; + newrect[2] = { rctA->left, rctB->bottom, rctA->right, rctA->bottom }; + newrect[3] = { rctB->left, rctA->bottom, rctB->right, rctB->bottom }; + + newrect[4] = { + std::min(rctB->left, rctA->left), + std::max(rctB->top, rctA->top), + std::max(rctB->right, rctA->right), + std::min(rctB->bottom, rctA->bottom) + }; +#else + if (rctA->bottom < rctB->top && rctB->bottom < rctA->top) { newrect[0] = { rctA->left, rctA->bottom, rctA->right, rctB->bottom }; newrect[1] = { rctB->left, rctB->bottom, rctB->right, rctA->bottom }; newrect[2] = { rctA->left, rctB->top, rctA->right, rctA->top }; @@ -71,6 +98,7 @@ void CombineRectangles(TSGrowableArray* combinedArray) { std::max(rctB->right, rctA->right), std::min(rctB->top, rctA->top) }; +#endif for (uint32_t k = 0; k < 5; k++) { if (!IsNullRect(&newrect[k])) { @@ -163,6 +191,23 @@ void FragmentCombinedRectangles(TSGrowableArray* combinedArray, uint32_t } RECTF newrect[4]; + +#if defined(WHOA_RECT_USES_SCREEN_COORDINATES) + newrect[0] = { rect->left, rect->top, rect->right, checkRect->top }; + newrect[1] = { rect->left, checkRect->bottom, rect->right, rect->bottom }; + newrect[2] = { + rect->left, + std::max(checkRect->top, rect->top), + checkRect->left, + std::min(checkRect->bottom, rect->bottom) + }; + newrect[3] = { + checkRect->right, + std::max(checkRect->top, rect->top), + rect->right, + std::min(checkRect->bottom, rect->bottom) + }; +#else newrect[0] = { rect->left, rect->bottom, rect->right, checkRect->bottom }; newrect[1] = { rect->left, checkRect->top, rect->right, rect->top }; newrect[2] = { @@ -177,6 +222,7 @@ void FragmentCombinedRectangles(TSGrowableArray* combinedArray, uint32_t rect->right, std::min(checkRect->top, rect->top) }; +#endif for (uint32_t i = 0; i < 4; i++) { if (!IsNullRect(&newrect[i])) { @@ -211,6 +257,42 @@ void FragmentSourceRectangles(TSGrowableArray* sourceArray, uint32_t fir RECTF newRect[5]; +#if defined(WHOA_RECT_USES_SCREEN_COORDINATES) + newRect[0] = { + overlapRect[minTop]->left, + overlapRect[minTop]->top, + overlapRect[minTop]->right, + overlapRect[maxTop]->top, + }; + + newRect[1] = { + overlapRect[maxBottom]->left, + overlapRect[minBottom]->bottom, + overlapRect[maxBottom]->right, + overlapRect[maxBottom]->bottom, + }; + + newRect[2] = { + overlapRect[minLeft]->left, + overlapRect[maxTop]->top, + overlapRect[maxLeft]->left, + overlapRect[minBottom]->bottom, + }; + + newRect[3] = { + overlapRect[minRight]->right, + overlapRect[maxTop]->top, + overlapRect[maxRight]->right, + overlapRect[minBottom]->bottom, + }; + + newRect[4] = { + overlapRect[maxLeft]->left, + overlapRect[maxTop]->top, + overlapRect[minRight]->right, + overlapRect[minBottom]->bottom, + }; +#else newRect[0] = { overlapRect[minBottom]->left, overlapRect[minBottom]->bottom, @@ -245,6 +327,7 @@ void FragmentSourceRectangles(TSGrowableArray* sourceArray, uint32_t fir overlapRect[minRight]->right, overlapRect[minTop]->top, }; +#endif int32_t overlaps[5][2]; for (uint32_t j = 0; j < 5; j++) { @@ -287,7 +370,11 @@ void FragmentSourceRectangles(TSGrowableArray* sourceArray, uint32_t fir } int32_t IsNullRect(const RECTF* rect) { +#if defined(WHOA_RECT_USES_SCREEN_COORDINATES) + return rect->left >= rect->right || rect->top >= rect->bottom; +#else return rect->left >= rect->right || rect->bottom >= rect->top; +#endif } void ClearRegion(RGN* rgn) { @@ -522,10 +609,12 @@ void SRgnGetBoundingRectf(HSRGN handle, RECTF* rect) { STORM_VALIDATE(rect); STORM_VALIDATE_END_VOID; - rect->left = std::numeric_limits::max(); - rect->bottom = std::numeric_limits::max(); - rect->right = std::numeric_limits::min(); - rect->top = std::numeric_limits::min(); + *rect = { + std::numeric_limits::max(), + std::numeric_limits::max(), + std::numeric_limits::min(), + std::numeric_limits::min(), + }; HLOCKEDRGN lockedHandle; auto rgn = s_rgntable.Lock(handle, &lockedHandle, 0); @@ -538,9 +627,15 @@ void SRgnGetBoundingRectf(HSRGN handle, RECTF* rect) { if (!(source->flags & SF_PARAMONLY)) { rect->left = std::min(source->rect.left, rect->left); - rect->bottom = std::min(source->rect.bottom, rect->bottom); rect->right = std::max(source->rect.right, rect->right); + +#if defined(WHOA_RECT_USES_SCREEN_COORDINATES) + rect->top = std::min(source->rect.top, rect->top); + rect->bottom = std::max(source->rect.bottom, rect->bottom); +#else + rect->bottom = std::min(source->rect.bottom, rect->bottom); rect->top = std::max(source->rect.top, rect->top); +#endif } } @@ -562,11 +657,16 @@ void SRgnGetBoundingRecti(HSRGN handle, RECT* rect) { RECTF rectf; SRgnGetBoundingRectf(handle, &rectf); - // NOTE: top and bottom get flipped, this is a bug in Storm rect->left = static_cast(rectf.left); - rect->top = static_cast(rectf.bottom); rect->right = static_cast(rectf.right); +#if defined(WHOA_RECT_USES_SCREEN_COORDINATES) + rect->top = static_cast(rectf.top); + rect->bottom = static_cast(rectf.bottom); +#else + // NOTE: top and bottom get flipped, this is a bug in Storm + rect->top = static_cast(rectf.bottom); rect->bottom = static_cast(rectf.top); +#endif } void SRgnGetRectParamsf(HSRGN handle, const RECTF* rect, uint32_t* numParams, void** buffer) { @@ -659,13 +759,18 @@ void SRgnGetRectsi(HSRGN handle, uint32_t* numRects, RECT* buffer) { SRgnGetRectsf(handle, numRects, bufferf); if (buffer) { for (uint32_t i = 0; i < *numRects; i++) { +#if defined(WHOA_RECT_USES_SCREEN_COORDINATES) + buffer[i].top = static_cast(bufferf[i].top); + buffer[i].bottom = static_cast(bufferf[i].bottom); +#else float bottom = bufferf[i].bottom; float top = bufferf[i].top; - buffer[i].left = static_cast(bufferf[i].left); buffer[i].bottom = static_cast(bottom); - buffer[i].right = static_cast(bufferf[i].right); buffer[i].top = static_cast(top); +#endif + buffer[i].left = static_cast(bufferf[i].left); + buffer[i].right = static_cast(bufferf[i].right); } } } @@ -687,8 +792,13 @@ int32_t SRgnIsPointInRegionf(HSRGN handle, float x, float y) { uint32_t sourceRects = rgn->source.Count(); for (uint32_t i = 0; i < sourceRects; i++) { if (!(sourceArray[i].flags & SF_PARAMONLY)) { +#if defined(WHOA_RECT_USES_SCREEN_COORDINATES) + if (x >= sourceArray[i].rect.left && y >= sourceArray[i].rect.top && + x < sourceArray[i].rect.right && y < sourceArray[i].rect.bottom) { +#else if (x >= sourceArray[i].rect.left && y >= sourceArray[i].rect.bottom && x < sourceArray[i].rect.right && y < sourceArray[i].rect.top) { +#endif result = 1; break; } diff --git a/storm/region/Types.hpp b/storm/region/Types.hpp index c7d3766..b0a0454 100644 --- a/storm/region/Types.hpp +++ b/storm/region/Types.hpp @@ -8,12 +8,15 @@ DECLARE_STORM_HANDLE(HSRGN); DECLARE_STORM_HANDLE(HLOCKEDRGN); +#if defined(WHOA_RECT_USES_SCREEN_COORDINATES) struct RECTF { - float left; - float bottom; - float right; - float top; + float left, top, right, bottom; }; +#else +struct RECTF { + float left, bottom, right, top; +}; +#endif #if defined(WHOA_SYSTEM_WIN) // NOTE: WINAPI's RECT uses `long`. diff --git a/test/Region.cpp b/test/Region.cpp index 83a7ebc..2f03cbc 100644 --- a/test/Region.cpp +++ b/test/Region.cpp @@ -498,8 +498,8 @@ TEST_CASE("SRgnCombineRecti", "[region]") { SRgnCombineRecti(region, &testRect, nullptr, SRGN_OR); uint32_t numRects = 4; - RECT buffer[4]; - SRgnGetRectsi(region, &numRects, buffer); + RECTF buffer[4]; + SRgnGetRectsf(region, &numRects, buffer); // ┌────────────┐ // | 2 | @@ -509,9 +509,9 @@ TEST_CASE("SRgnCombineRecti", "[region]") { // │ 0 │ // └─────────┘ CHECK(numRects == 3); - CHECK_THAT(buffer[0], MatchesRecti({ 0, 6, 10, 0 })); - CHECK_THAT(buffer[1], MatchesRecti({ 0, 10, 18, 6 })); - CHECK_THAT(buffer[2], MatchesRecti({ 5, 14, 18, 10 })); + CHECK_THAT(buffer[0], MatchesRectf({ 0.0f, 0.0f, 10.0f, 6.0f })); + CHECK_THAT(buffer[1], MatchesRectf({ 0.0f, 6.0f, 18.0f, 10.0f })); + CHECK_THAT(buffer[2], MatchesRectf({ 5.0f, 10.0f, 18.0f, 14.0f })); } SECTION("OR operation on self does nothing") { @@ -519,11 +519,11 @@ TEST_CASE("SRgnCombineRecti", "[region]") { SRgnCombineRecti(region, &baseRect, nullptr, SRGN_OR); uint32_t numRects = 1; - RECT buffer[1]; - SRgnGetRectsi(region, &numRects, buffer); + RECTF buffer[1]; + SRgnGetRectsf(region, &numRects, buffer); CHECK(numRects == 1); - CHECK_THAT(buffer[0], MatchesRecti({ 0, 10, 10, 0 })); + CHECK_THAT(buffer[0], MatchesRectf({ 0.0f, 0.0f, 10.0f, 10.0f })); } SECTION("OR operation merges vertical rects") { @@ -534,11 +534,11 @@ TEST_CASE("SRgnCombineRecti", "[region]") { SRgnCombineRecti(region, &rect2, nullptr, SRGN_OR); uint32_t numRects = 1; - RECT buffer[1]; - SRgnGetRectsi(region, &numRects, buffer); + RECTF buffer[1]; + SRgnGetRectsf(region, &numRects, buffer); CHECK(numRects == 1); - CHECK_THAT(buffer[0], MatchesRecti({ 0, 30, 10, 0 })); + CHECK_THAT(buffer[0], MatchesRectf({ 0.0f, 0.0f, 10.0f, 30.0f })); } SECTION("OR operation merges vertical rects 2") { @@ -549,11 +549,11 @@ TEST_CASE("SRgnCombineRecti", "[region]") { SRgnCombineRecti(region, &baseRect, nullptr, SRGN_OR); uint32_t numRects = 1; - RECT buffer[1]; - SRgnGetRectsi(region, &numRects, buffer); + RECTF buffer[1]; + SRgnGetRectsf(region, &numRects, buffer); CHECK(numRects == 1); - CHECK_THAT(buffer[0], MatchesRecti({ 0, 30, 10, 0 })); + CHECK_THAT(buffer[0], MatchesRectf({ 0.0f, 0.0f, 10.0f, 30.0f })); } SECTION("OR operation merges horizontal rects") { @@ -564,11 +564,11 @@ TEST_CASE("SRgnCombineRecti", "[region]") { SRgnCombineRecti(region, &rect2, nullptr, SRGN_OR); uint32_t numRects = 1; - RECT buffer[1]; - SRgnGetRectsi(region, &numRects, buffer); + RECTF buffer[1]; + SRgnGetRectsf(region, &numRects, buffer); CHECK(numRects == 1); - CHECK_THAT(buffer[0], MatchesRecti({ 0, 10, 30, 0 })); + CHECK_THAT(buffer[0], MatchesRectf({ 0.0f, 0.0f, 30.0f, 10.0f })); } SECTION("OR operation merges horizontal rects 2") { @@ -579,11 +579,11 @@ TEST_CASE("SRgnCombineRecti", "[region]") { SRgnCombineRecti(region, &baseRect, nullptr, SRGN_OR); uint32_t numRects = 1; - RECT buffer[1]; - SRgnGetRectsi(region, &numRects, buffer); + RECTF buffer[1]; + SRgnGetRectsf(region, &numRects, buffer); CHECK(numRects == 1); - CHECK_THAT(buffer[0], MatchesRecti({ 0, 10, 30, 0 })); + CHECK_THAT(buffer[0], MatchesRectf({ 0.0f, 0.0f, 30.0f, 10.0f })); } SECTION("AND operation intersects rects") { @@ -591,8 +591,8 @@ TEST_CASE("SRgnCombineRecti", "[region]") { SRgnCombineRecti(region, &testRect, nullptr, SRGN_AND); uint32_t numRects = 2; - RECT buffer[2]; - SRgnGetRectsi(region, &numRects, buffer); + RECTF buffer[2]; + SRgnGetRectsf(region, &numRects, buffer); // ┌────────────┐ // |╳╳╳╳╳╳╳╳╳╳╳╳| @@ -602,7 +602,7 @@ TEST_CASE("SRgnCombineRecti", "[region]") { // │╳╳╳╳╳╳╳╳╳│ // └─────────┘ CHECK(numRects == 1); - CHECK_THAT(buffer[0], MatchesRecti({ 5, 10, 10, 6 })); + CHECK_THAT(buffer[0], MatchesRectf({ 5.0f, 6.0f, 10.0f, 10.0f })); } SECTION("AND operation on self does nothing") { @@ -610,11 +610,11 @@ TEST_CASE("SRgnCombineRecti", "[region]") { SRgnCombineRecti(region, &baseRect, nullptr, SRGN_AND); uint32_t numRects = 1; - RECT buffer[1]; - SRgnGetRectsi(region, &numRects, buffer); + RECTF buffer[1]; + SRgnGetRectsf(region, &numRects, buffer); CHECK(numRects == 1); - CHECK_THAT(buffer[0], MatchesRecti({ 0, 10, 10, 0 })); + CHECK_THAT(buffer[0], MatchesRectf({ 0.0f, 0.0f, 10.0f, 10.0f })); } SECTION("XOR operation takes exclusive differences of rects") { @@ -622,8 +622,8 @@ TEST_CASE("SRgnCombineRecti", "[region]") { SRgnCombineRecti(region, &testRect, nullptr, SRGN_XOR); uint32_t numRects = 5; - RECT buffer[5]; - SRgnGetRectsi(region, &numRects, buffer); + RECTF buffer[5]; + SRgnGetRectsf(region, &numRects, buffer); // ┌────────────┐ // | 3 | @@ -633,10 +633,10 @@ TEST_CASE("SRgnCombineRecti", "[region]") { // │ 0 │ // └─────────┘ CHECK(numRects == 4); - CHECK_THAT(buffer[0], MatchesRecti({ 0, 6, 10, 0 })); - CHECK_THAT(buffer[1], MatchesRecti({ 0, 10, 5, 6 })); - CHECK_THAT(buffer[2], MatchesRecti({ 10, 10, 18, 6 })); - CHECK_THAT(buffer[3], MatchesRecti({ 5, 14, 18, 10 })); + CHECK_THAT(buffer[0], MatchesRectf({ 0.0f, 0.0f, 10.0f, 6.0f })); + CHECK_THAT(buffer[1], MatchesRectf({ 0.0f, 6.0f, 5.0f, 10.0f })); + CHECK_THAT(buffer[2], MatchesRectf({ 10.0f, 6.0f, 18.0f, 10.0f })); + CHECK_THAT(buffer[3], MatchesRectf({ 5.0f, 10.0f, 18.0f, 14.0f })); } SECTION("XOR operation on self erases rect") { @@ -654,8 +654,8 @@ TEST_CASE("SRgnCombineRecti", "[region]") { SRgnCombineRecti(region, &testRect, nullptr, SRGN_DIFF); uint32_t numRects = 5; - RECT buffer[5]; - SRgnGetRectsi(region, &numRects, buffer); + RECTF buffer[5]; + SRgnGetRectsf(region, &numRects, buffer); // ┌────────────┐ // |╳╳╳╳╳╳╳╳╳╳╳╳| @@ -665,8 +665,8 @@ TEST_CASE("SRgnCombineRecti", "[region]") { // │ 0 │ // └─────────┘ CHECK(numRects == 2); - CHECK_THAT(buffer[0], MatchesRecti({ 0, 6, 10, 0 })); - CHECK_THAT(buffer[1], MatchesRecti({ 0, 10, 5, 6 })); + CHECK_THAT(buffer[0], MatchesRectf({ 0.0f, 0.0f, 10.0f, 6.0f })); + CHECK_THAT(buffer[1], MatchesRectf({ 0.0f, 6.0f, 5.0f, 10.0f })); } SECTION("DIFF operation on self erases rect") { @@ -684,8 +684,8 @@ TEST_CASE("SRgnCombineRecti", "[region]") { SRgnCombineRecti(region, &testRect, nullptr, SRGN_COPY); uint32_t numRects = 5; - RECT buffer[5]; - SRgnGetRectsi(region, &numRects, buffer); + RECTF buffer[5]; + SRgnGetRectsf(region, &numRects, buffer); // ┌────────────┐ // |╳╳╳╳╳╳╳╳╳╳╳╳| @@ -695,8 +695,8 @@ TEST_CASE("SRgnCombineRecti", "[region]") { // │ 0 │ // └─────────┘ CHECK(numRects == 2); - CHECK_THAT(buffer[0], MatchesRecti({ 0, 6, 10, 0 })); - CHECK_THAT(buffer[1], MatchesRecti({ 0, 10, 10, 6 })); + CHECK_THAT(buffer[0], MatchesRectf({ 0.0f, 0.0f, 10.0f, 6.0f })); + CHECK_THAT(buffer[1], MatchesRectf({ 0.0f, 6.0f, 10.0f, 10.0f })); } SECTION("COPY operation splits intersecting rects 2") { @@ -705,8 +705,8 @@ TEST_CASE("SRgnCombineRecti", "[region]") { SRgnCombineRecti(region, &testRect2, nullptr, SRGN_COPY); uint32_t numRects = 5; - RECT buffer[5]; - SRgnGetRectsi(region, &numRects, buffer); + RECTF buffer[5]; + SRgnGetRectsf(region, &numRects, buffer); // ┌───────────┐ // │ 2 │ @@ -715,9 +715,9 @@ TEST_CASE("SRgnCombineRecti", "[region]") { // │ 0 │ // └───────────┘ CHECK(numRects == 3); - CHECK_THAT(buffer[0], MatchesRecti({ 0, 4, 10, 0 })); - CHECK_THAT(buffer[1], MatchesRecti({ 0, 6, 10, 4 })); - CHECK_THAT(buffer[2], MatchesRecti({ 0, 10, 10, 6 })); + CHECK_THAT(buffer[0], MatchesRectf({ 0.0f, 0.0f, 10.0f, 4.0f })); + CHECK_THAT(buffer[1], MatchesRectf({ 0.0f, 4.0f, 10.0f, 6.0f })); + CHECK_THAT(buffer[2], MatchesRectf({ 0.0f, 6.0f, 10.0f, 10.0f })); } SECTION("COPY operation on self does nothing") { @@ -725,11 +725,11 @@ TEST_CASE("SRgnCombineRecti", "[region]") { SRgnCombineRecti(region, &baseRect, nullptr, SRGN_COPY); uint32_t numRects = 1; - RECT buffer[1]; - SRgnGetRectsi(region, &numRects, buffer); + RECTF buffer[1]; + SRgnGetRectsf(region, &numRects, buffer); CHECK(numRects == 1); - CHECK_THAT(buffer[0], MatchesRecti({ 0, 10, 10, 0 })); + CHECK_THAT(buffer[0], MatchesRectf({ 0.0f, 0.0f, 10.0f, 10.0f })); } SECTION("operation doesn't work when operating rect width or height is <= 0") { @@ -742,15 +742,14 @@ TEST_CASE("SRgnCombineRecti", "[region]") { ); SRgnCombineRecti(region, &baseRect, nullptr, SRGN_OR); - - uint32_t numRects = 5; - RECT buffer[5]; - SRgnCombineRecti(region, &testRects, &testRects, combineMode); - SRgnGetRectsi(region, &numRects, buffer); + uint32_t numRects = 5; + RECTF buffer[5]; + + SRgnGetRectsf(region, &numRects, buffer); CHECK(numRects == 1); - CHECK_THAT(buffer[0], MatchesRecti({ 0, 10, 10, 0 })); + CHECK_THAT(buffer[0], MatchesRectf({ 0.0f, 0.0f, 10.0f, 10.0f })); uint32_t numParams = 1; SRgnGetRectParamsi(region, &testRects, &numParams, nullptr); @@ -792,11 +791,11 @@ TEST_CASE("SRgnCombineRecti", "[region]") { SRgnCombineRecti(region, &testRect, nullptr, SRGN_PARAMONLY); uint32_t numRects = 5; - RECT buffer[5]; - SRgnGetRectsi(region, &numRects, buffer); + RECTF buffer[5]; + SRgnGetRectsf(region, &numRects, buffer); CHECK(numRects == 1); - CHECK_THAT(buffer[0], MatchesRecti({ 0, 10, 10, 0 })); + CHECK_THAT(buffer[0], MatchesRectf({ 0.0f, 0.0f, 10.0f, 10.0f })); } } @@ -1277,7 +1276,7 @@ TEST_CASE("SRgnGetRectsf", "[region]") { { 0, 0, 1, 1 }, { 4, -2, 5, 5 }, { -2, 2, -1, 3 }, - { 2, -2, 3, -1 }, + { 2, -3, 3, -1 }, }; for (int i = 0; i < 4; i++) { @@ -1289,18 +1288,25 @@ TEST_CASE("SRgnGetRectsf", "[region]") { SRgnGetRectsf(region, &numrects, buffer); CHECK(numrects == 4); +#if defined(WHOA_RECT_USES_SCREEN_COORDINATES) + CHECK_THAT(buffer[0], MatchesRectf(rects[3])); + CHECK_THAT(buffer[1], MatchesRectf(rects[1])); + CHECK_THAT(buffer[2], MatchesRectf(rects[0])); + CHECK_THAT(buffer[3], MatchesRectf(rects[2])); +#else CHECK_THAT(buffer[0], MatchesRectf(rects[3])); CHECK_THAT(buffer[1], MatchesRectf(rects[0])); CHECK_THAT(buffer[2], MatchesRectf(rects[2])); CHECK_THAT(buffer[3], MatchesRectf(rects[1])); +#endif } SECTION("retrieves rects in order of left value when tops are equal") { RECTF rects[4] = { { 0, 0, 1, 1 }, - { 4, 0.5, 5, 1 }, - { -2, -2, -1, 1 }, - { 2, -1, 3, 1 }, + { 4, 0, 5, 1 }, + { -2, 0, -1, 1 }, + { 2, 0, 3, 1 }, }; for (int i = 0; i < 4; i++) { @@ -1353,8 +1359,13 @@ TEST_CASE("SRgnGetRectsi", "[region]") { REQUIRE(numrects == 2); SRgnGetRectsi(region, &numrects, buffer); +#if defined(WHOA_RECT_USES_SCREEN_COORDINATES) + CHECK_THAT(buffer[0], MatchesRecti({ 0, 0, 1, 1 })); + CHECK_THAT(buffer[1], MatchesRecti({ 5, 5, 10, 10 })); +#else CHECK_THAT(buffer[0], MatchesRecti({ 0, 1, 1, 0 })); CHECK_THAT(buffer[1], MatchesRecti({ 5, 10, 10, 5 })); +#endif } SECTION("automatically merges overlapping rects") { @@ -1370,7 +1381,11 @@ TEST_CASE("SRgnGetRectsi", "[region]") { REQUIRE(numrects == 1); SRgnGetRectsi(region, &numrects, buffer); +#if defined(WHOA_RECT_USES_SCREEN_COORDINATES) + CHECK_THAT(buffer[0], MatchesRecti({ -10, -10, 10, 10 })); +#else CHECK_THAT(buffer[0], MatchesRecti({ -10, 10, 10, -10 })); +#endif } SECTION("retrieves rects in order of top value") { @@ -1378,7 +1393,7 @@ TEST_CASE("SRgnGetRectsi", "[region]") { { 0.0f, 0.0f, 1.0f, 1.0f }, { 4.0f, -2.0f, 5.0f, 5.0f }, { -2.0f, 2.0f, -1.0f, 3.0f }, - { 2.0f, -2.0f, 3.0f, -1.0f }, + { 2.0f, -3.0f, 3.0f, -1.0f }, }; for (int i = 0; i < 4; i++) { @@ -1390,18 +1405,25 @@ TEST_CASE("SRgnGetRectsi", "[region]") { SRgnGetRectsi(region, &numrects, buffer); CHECK(numrects == 4); - CHECK_THAT(buffer[0], MatchesRecti({ 2, -1, 3, -2 })); +#if defined(WHOA_RECT_USES_SCREEN_COORDINATES) + CHECK_THAT(buffer[0], MatchesRecti({ 2, -3, 3, -1 })); + CHECK_THAT(buffer[1], MatchesRecti({ 4, -2, 5, 5 })); + CHECK_THAT(buffer[2], MatchesRecti({ 0, 0, 1, 1 })); + CHECK_THAT(buffer[3], MatchesRecti({ -2, 2, -1, 3 })); +#else + CHECK_THAT(buffer[0], MatchesRecti({ 2, -1, 3, -3 })); CHECK_THAT(buffer[1], MatchesRecti({ 0, 1, 1, 0 })); CHECK_THAT(buffer[2], MatchesRecti({ -2, 3, -1, 2 })); CHECK_THAT(buffer[3], MatchesRecti({ 4, 5, 5, -2 })); +#endif } SECTION("retrieves rects in order of left value when tops are equal") { RECTF rects[4] = { { 0, 0, 10, 10 }, - { 40, 5, 50, 10 }, - { -20, -20, -10, 10 }, - { 20, -10, 30, 10 }, + { 40, 0, 50, 10 }, + { -20, 0, -10, 10 }, + { 20, 0, 30, 10 }, }; for (int i = 0; i < 4; i++) { @@ -1413,10 +1435,17 @@ TEST_CASE("SRgnGetRectsi", "[region]") { SRgnGetRectsi(region, &numrects, buffer); CHECK(numrects == 4); - CHECK_THAT(buffer[0], MatchesRecti({ -20, 10, -10, -20 })); +#if defined(WHOA_RECT_USES_SCREEN_COORDINATES) + CHECK_THAT(buffer[0], MatchesRecti({ -20, 0, -10, 10 })); + CHECK_THAT(buffer[1], MatchesRecti({ 0, 0, 10, 10 })); + CHECK_THAT(buffer[2], MatchesRecti({ 20, 0, 30, 10 })); + CHECK_THAT(buffer[3], MatchesRecti({ 40, 0, 50, 10 })); +#else + CHECK_THAT(buffer[0], MatchesRecti({ -20, 10, -10, 0 })); CHECK_THAT(buffer[1], MatchesRecti({ 0, 10, 10, 0 })); - CHECK_THAT(buffer[2], MatchesRecti({ 20, 10, 30, -10 })); - CHECK_THAT(buffer[3], MatchesRecti({ 40, 10, 50, 5 })); + CHECK_THAT(buffer[2], MatchesRecti({ 20, 10, 30, 0 })); + CHECK_THAT(buffer[3], MatchesRecti({ 40, 10, 50, 0 })); +#endif } } @@ -1775,11 +1804,11 @@ TEST_CASE("SRgnOffseti", "[region]") { SRgnOffseti(region, 1000, 500); uint32_t numRects = 2; - RECT buffer[2]; - SRgnGetRectsi(region, &numRects, buffer); + RECTF buffer[2]; + SRgnGetRectsf(region, &numRects, buffer); - CHECK_THAT(buffer[0], MatchesRecti({ -1000, -500, 0, -1500 })); - CHECK_THAT(buffer[1], MatchesRecti({ 1000, 1500, 2000, 500 })); + CHECK_THAT(buffer[0], MatchesRectf({ -1000.0f, -1500.0f, 0.0f, -500.0f })); + CHECK_THAT(buffer[1], MatchesRectf({ 1000.0f, 500.0f, 2000.0f, 1500.0f })); } SECTION("shifts rects back to their original positions with opposite amounts") { @@ -1796,11 +1825,11 @@ TEST_CASE("SRgnOffseti", "[region]") { SRgnOffseti(region, -1050, -600); uint32_t numRects = 2; - RECT buffer[2]; - SRgnGetRectsi(region, &numRects, buffer); + RECTF buffer[2]; + SRgnGetRectsf(region, &numRects, buffer); - CHECK_THAT(buffer[0], MatchesRecti({ -2000, -1000, -1000, -2000 })); - CHECK_THAT(buffer[1], MatchesRecti({ 0, 1000, 1000, 0 })); + CHECK_THAT(buffer[0], MatchesRectf(rects[0])); + CHECK_THAT(buffer[1], MatchesRectf(rects[1])); } SECTION("doesn't shift anything with 0") { @@ -1815,10 +1844,10 @@ TEST_CASE("SRgnOffseti", "[region]") { SRgnOffseti(region, 0, 0); uint32_t numRects = 2; - RECT buffer[2]; - SRgnGetRectsi(region, &numRects, buffer); + RECTF buffer[2]; + SRgnGetRectsf(region, &numRects, buffer); - CHECK_THAT(buffer[0], MatchesRecti({ -2000, -1000, -1000, -2000 })); - CHECK_THAT(buffer[1], MatchesRecti({ 0, 1000, 1000, 0 })); + CHECK_THAT(buffer[0], MatchesRectf(rects[0])); + CHECK_THAT(buffer[1], MatchesRectf(rects[1])); } } diff --git a/test/RegionTest.hpp b/test/RegionTest.hpp index f7f2b8a..c424177 100644 --- a/test/RegionTest.hpp +++ b/test/RegionTest.hpp @@ -22,7 +22,11 @@ struct RgnDataTest { // Helpers for comparing RECTF structs std::ostream& operator <<(std::ostream& os, RECTF const& value) { +#if defined(WHOA_RECT_USES_SCREEN_COORDINATES) + os << "{ " << value.left << ", " << value.top << ", " << value.right << ", " << value.bottom << " }"; +#else os << "{ " << value.left << ", " << value.bottom << ", " << value.right << ", " << value.top << " }"; +#endif return os; }