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}