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 {
|
||||
int x;
|
||||
int y;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
int width;
|
||||
int height;
|
||||
};
|
||||
|
||||
void RectangleUnion(struct Rectangle* dst, const struct Rectangle* add);
|
||||
void RectangleCenter(const struct Rectangle* ref, struct Rectangle* rect);
|
||||
|
||||
CXX_GUARD_END
|
||||
|
||||
#endif
|
||||
|
|
|
@ -16,6 +16,7 @@ set(SOURCE_FILES
|
|||
convolve.c
|
||||
elf-read.c
|
||||
export.c
|
||||
geometry.c
|
||||
patch.c
|
||||
patch-fast.c
|
||||
patch-ips.c
|
||||
|
@ -33,6 +34,7 @@ set(GUI_FILES
|
|||
gui/menu.c)
|
||||
|
||||
set(TEST_FILES
|
||||
test/geometry.c
|
||||
test/sfo.c
|
||||
test/string-parser.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