mirror of https://github.com/mgba-emu/mgba.git
Util: Add some basic geometry math
This commit is contained in:
parent
bd6edce5cf
commit
efbc4a49ce
|
@ -13,10 +13,13 @@ CXX_GUARD_START
|
||||||
struct Rectangle {
|
struct Rectangle {
|
||||||
int x;
|
int x;
|
||||||
int y;
|
int y;
|
||||||
unsigned width;
|
int width;
|
||||||
unsigned height;
|
int height;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void RectangleUnion(struct Rectangle* dst, const struct Rectangle* add);
|
||||||
|
void RectangleCenter(const struct Rectangle* ref, struct Rectangle* rect);
|
||||||
|
|
||||||
CXX_GUARD_END
|
CXX_GUARD_END
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -16,6 +16,7 @@ set(SOURCE_FILES
|
||||||
convolve.c
|
convolve.c
|
||||||
elf-read.c
|
elf-read.c
|
||||||
export.c
|
export.c
|
||||||
|
geometry.c
|
||||||
patch.c
|
patch.c
|
||||||
patch-fast.c
|
patch-fast.c
|
||||||
patch-ips.c
|
patch-ips.c
|
||||||
|
@ -33,6 +34,7 @@ set(GUI_FILES
|
||||||
gui/menu.c)
|
gui/menu.c)
|
||||||
|
|
||||||
set(TEST_FILES
|
set(TEST_FILES
|
||||||
|
test/geometry.c
|
||||||
test/sfo.c
|
test/sfo.c
|
||||||
test/string-parser.c
|
test/string-parser.c
|
||||||
test/string-utf8.c
|
test/string-utf8.c
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/* Copyright (c) 2013-2023 Jeffrey Pfau
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
#include <mgba-util/geometry.h>
|
||||||
|
|
||||||
|
void RectangleUnion(struct Rectangle* dst, const struct Rectangle* add) {
|
||||||
|
int x0 = dst->x;
|
||||||
|
int y0 = dst->y;
|
||||||
|
int x1 = dst->x + dst->width;
|
||||||
|
int y1 = dst->y + dst->height;
|
||||||
|
|
||||||
|
if (add->x < x0) {
|
||||||
|
x0 = add->x;
|
||||||
|
}
|
||||||
|
if (add->y < y0) {
|
||||||
|
y0 = add->y;
|
||||||
|
}
|
||||||
|
if (add->x + add->width > x1) {
|
||||||
|
x1 = add->x + add->width;
|
||||||
|
}
|
||||||
|
if (add->y + add->height > y1) {
|
||||||
|
y1 = add->y + add->height;
|
||||||
|
}
|
||||||
|
|
||||||
|
dst->x = x0;
|
||||||
|
dst->y = y0;
|
||||||
|
dst->width = x1 - x0;
|
||||||
|
dst->height = y1 - y0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RectangleCenter(const struct Rectangle* ref, struct Rectangle* rect) {
|
||||||
|
rect->x = ref->x + (ref->width - rect->width) / 2;
|
||||||
|
rect->y = ref->y + (ref->height - rect->height) / 2;
|
||||||
|
}
|
|
@ -0,0 +1,213 @@
|
||||||
|
/* Copyright (c) 2013-2023 Jeffrey Pfau
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
#include "util/test/suite.h"
|
||||||
|
|
||||||
|
#include <mgba-util/geometry.h>
|
||||||
|
|
||||||
|
M_TEST_DEFINE(unionRectOrigin) {
|
||||||
|
struct Rectangle a = {
|
||||||
|
.x = 0,
|
||||||
|
.y = 0,
|
||||||
|
.width = 1,
|
||||||
|
.height = 1
|
||||||
|
};
|
||||||
|
struct Rectangle b = {
|
||||||
|
.x = 1,
|
||||||
|
.y = 1,
|
||||||
|
.width = 1,
|
||||||
|
.height = 1
|
||||||
|
};
|
||||||
|
RectangleUnion(&a, &b);
|
||||||
|
assert_int_equal(a.x, 0);
|
||||||
|
assert_int_equal(a.y, 0);
|
||||||
|
assert_int_equal(a.width, 2);
|
||||||
|
assert_int_equal(a.height, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(unionRectOriginSwapped) {
|
||||||
|
struct Rectangle a = {
|
||||||
|
.x = 1,
|
||||||
|
.y = 1,
|
||||||
|
.width = 1,
|
||||||
|
.height = 1
|
||||||
|
};
|
||||||
|
struct Rectangle b = {
|
||||||
|
.x = 0,
|
||||||
|
.y = 0,
|
||||||
|
.width = 1,
|
||||||
|
.height = 1
|
||||||
|
};
|
||||||
|
RectangleUnion(&a, &b);
|
||||||
|
assert_int_equal(a.x, 0);
|
||||||
|
assert_int_equal(a.y, 0);
|
||||||
|
assert_int_equal(a.width, 2);
|
||||||
|
assert_int_equal(a.height, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(unionRectNonOrigin) {
|
||||||
|
struct Rectangle a = {
|
||||||
|
.x = 1,
|
||||||
|
.y = 1,
|
||||||
|
.width = 1,
|
||||||
|
.height = 1
|
||||||
|
};
|
||||||
|
struct Rectangle b = {
|
||||||
|
.x = 2,
|
||||||
|
.y = 2,
|
||||||
|
.width = 1,
|
||||||
|
.height = 1
|
||||||
|
};
|
||||||
|
RectangleUnion(&a, &b);
|
||||||
|
assert_int_equal(a.x, 1);
|
||||||
|
assert_int_equal(a.y, 1);
|
||||||
|
assert_int_equal(a.width, 2);
|
||||||
|
assert_int_equal(a.height, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(unionRectOverlapping) {
|
||||||
|
struct Rectangle a = {
|
||||||
|
.x = 0,
|
||||||
|
.y = 0,
|
||||||
|
.width = 2,
|
||||||
|
.height = 2
|
||||||
|
};
|
||||||
|
struct Rectangle b = {
|
||||||
|
.x = 1,
|
||||||
|
.y = 1,
|
||||||
|
.width = 2,
|
||||||
|
.height = 2
|
||||||
|
};
|
||||||
|
RectangleUnion(&a, &b);
|
||||||
|
assert_int_equal(a.x, 0);
|
||||||
|
assert_int_equal(a.y, 0);
|
||||||
|
assert_int_equal(a.width, 3);
|
||||||
|
assert_int_equal(a.height, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(unionRectSubRect) {
|
||||||
|
struct Rectangle a = {
|
||||||
|
.x = 0,
|
||||||
|
.y = 0,
|
||||||
|
.width = 3,
|
||||||
|
.height = 3
|
||||||
|
};
|
||||||
|
struct Rectangle b = {
|
||||||
|
.x = 1,
|
||||||
|
.y = 1,
|
||||||
|
.width = 1,
|
||||||
|
.height = 1
|
||||||
|
};
|
||||||
|
RectangleUnion(&a, &b);
|
||||||
|
assert_int_equal(a.x, 0);
|
||||||
|
assert_int_equal(a.y, 0);
|
||||||
|
assert_int_equal(a.width, 3);
|
||||||
|
assert_int_equal(a.height, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(unionRectNegativeOrigin) {
|
||||||
|
struct Rectangle a = {
|
||||||
|
.x = -1,
|
||||||
|
.y = -1,
|
||||||
|
.width = 1,
|
||||||
|
.height = 1
|
||||||
|
};
|
||||||
|
struct Rectangle b = {
|
||||||
|
.x = 0,
|
||||||
|
.y = 0,
|
||||||
|
.width = 1,
|
||||||
|
.height = 1
|
||||||
|
};
|
||||||
|
RectangleUnion(&a, &b);
|
||||||
|
assert_int_equal(a.x, -1);
|
||||||
|
assert_int_equal(a.y, -1);
|
||||||
|
assert_int_equal(a.width, 2);
|
||||||
|
assert_int_equal(a.height, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(centerRectBasic) {
|
||||||
|
struct Rectangle ref = {
|
||||||
|
.x = 0,
|
||||||
|
.y = 0,
|
||||||
|
.width = 4,
|
||||||
|
.height = 4
|
||||||
|
};
|
||||||
|
struct Rectangle a = {
|
||||||
|
.x = 0,
|
||||||
|
.y = 0,
|
||||||
|
.width = 2,
|
||||||
|
.height = 2
|
||||||
|
};
|
||||||
|
RectangleCenter(&ref, &a);
|
||||||
|
assert_int_equal(a.x, 1);
|
||||||
|
assert_int_equal(a.y, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(centerRectRoundDown) {
|
||||||
|
struct Rectangle ref = {
|
||||||
|
.x = 0,
|
||||||
|
.y = 0,
|
||||||
|
.width = 4,
|
||||||
|
.height = 4
|
||||||
|
};
|
||||||
|
struct Rectangle a = {
|
||||||
|
.x = 0,
|
||||||
|
.y = 0,
|
||||||
|
.width = 1,
|
||||||
|
.height = 1
|
||||||
|
};
|
||||||
|
RectangleCenter(&ref, &a);
|
||||||
|
assert_int_equal(a.x, 1);
|
||||||
|
assert_int_equal(a.y, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(centerRectRoundDown2) {
|
||||||
|
struct Rectangle ref = {
|
||||||
|
.x = 0,
|
||||||
|
.y = 0,
|
||||||
|
.width = 4,
|
||||||
|
.height = 4
|
||||||
|
};
|
||||||
|
struct Rectangle a = {
|
||||||
|
.x = 0,
|
||||||
|
.y = 0,
|
||||||
|
.width = 3,
|
||||||
|
.height = 2
|
||||||
|
};
|
||||||
|
RectangleCenter(&ref, &a);
|
||||||
|
assert_int_equal(a.x, 0);
|
||||||
|
assert_int_equal(a.y, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_DEFINE(centerRectOffset) {
|
||||||
|
struct Rectangle ref = {
|
||||||
|
.x = 1,
|
||||||
|
.y = 1,
|
||||||
|
.width = 4,
|
||||||
|
.height = 4
|
||||||
|
};
|
||||||
|
struct Rectangle a = {
|
||||||
|
.x = 0,
|
||||||
|
.y = 0,
|
||||||
|
.width = 2,
|
||||||
|
.height = 2
|
||||||
|
};
|
||||||
|
RectangleCenter(&ref, &a);
|
||||||
|
assert_int_equal(a.x, 2);
|
||||||
|
assert_int_equal(a.y, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
M_TEST_SUITE_DEFINE(Geometry,
|
||||||
|
cmocka_unit_test(unionRectOrigin),
|
||||||
|
cmocka_unit_test(unionRectOriginSwapped),
|
||||||
|
cmocka_unit_test(unionRectNonOrigin),
|
||||||
|
cmocka_unit_test(unionRectOverlapping),
|
||||||
|
cmocka_unit_test(unionRectSubRect),
|
||||||
|
cmocka_unit_test(unionRectNegativeOrigin),
|
||||||
|
cmocka_unit_test(centerRectBasic),
|
||||||
|
cmocka_unit_test(centerRectRoundDown),
|
||||||
|
cmocka_unit_test(centerRectRoundDown2),
|
||||||
|
cmocka_unit_test(centerRectOffset),
|
||||||
|
)
|
Loading…
Reference in New Issue