all repos — mgba @ 0cf9bf75e28e632ca071bb59a15e4f1afa4b4b9c

mGBA Game Boy Advance Emulator

src/ds/matrix.c (view raw)

 1/* Copyright (c) 2013-2017 Jeffrey Pfau
 2 *
 3 * This Source Code Form is subject to the terms of the Mozilla Public
 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 6#include <mgba/internal/ds/matrix.h>
 7
 8static int32_t _dot(const int32_t* col, const int32_t* row) {
 9	int64_t a;
10	int64_t b;
11	int64_t sum;
12	a = col[0];
13	b = row[0];
14	sum = a * b;
15	a = col[4];
16	b = row[1];
17	sum += a * b;
18	a = col[8];
19	b = row[2];
20	sum += a * b;
21	a = col[12];
22	b = row[3];
23	sum += a * b;
24	return sum >> 12LL;
25}
26
27void DSGXMtxIdentity(struct DSGXMatrix* mtx) {
28	memset(mtx, 0, sizeof(*mtx));
29	mtx->m[0] = MTX_ONE;
30	mtx->m[5] = MTX_ONE;
31	mtx->m[10] = MTX_ONE;
32	mtx->m[15] = MTX_ONE;
33}
34
35void DSGXMtxMultiply(struct DSGXMatrix* out, const struct DSGXMatrix* a, const struct DSGXMatrix* b) {
36	struct DSGXMatrix o;
37	// XXX: This is transposed because DS matrices are transposed
38	o.m[0] = _dot(&b->m[0], &a->m[0]);
39	o.m[1] = _dot(&b->m[1], &a->m[0]);
40	o.m[2] = _dot(&b->m[2], &a->m[0]);
41	o.m[3] = _dot(&b->m[3], &a->m[0]);
42	o.m[4] = _dot(&b->m[0], &a->m[4]);
43	o.m[5] = _dot(&b->m[1], &a->m[4]);
44	o.m[6] = _dot(&b->m[2], &a->m[4]);
45	o.m[7] = _dot(&b->m[3], &a->m[4]);
46	o.m[8] = _dot(&b->m[0], &a->m[8]);
47	o.m[9] = _dot(&b->m[1], &a->m[8]);
48	o.m[10] = _dot(&b->m[2], &a->m[8]);
49	o.m[11] = _dot(&b->m[3], &a->m[8]);
50	o.m[12] = _dot(&b->m[0], &a->m[12]);
51	o.m[13] = _dot(&b->m[1], &a->m[12]);
52	o.m[14] = _dot(&b->m[2], &a->m[12]);
53	o.m[15] = _dot(&b->m[3], &a->m[12]);
54	*out = o;
55}
56
57void DSGXMtxScale(struct DSGXMatrix* mtx, const int32_t* m) {
58	struct DSGXMatrix s = {
59		.m = {
60			m[0], 0, 0, 0,
61			0, m[1], 0, 0,
62			0, 0, m[2], 0,
63			0, 0, 0, MTX_ONE
64		}
65	};
66	DSGXMtxMultiply(mtx, &s, mtx);
67}
68
69void DSGXMtxTranslate(struct DSGXMatrix* mtx, const int32_t* m) {
70	struct DSGXMatrix t = {
71		.m = {
72			MTX_ONE, 0, 0, 0,
73			0, MTX_ONE, 0, 0,
74			0, 0, MTX_ONE, 0,
75			m[0], m[1], m[2], MTX_ONE
76		}
77	};
78	DSGXMtxMultiply(mtx, &t, mtx);
79}