Skip to content

Commit b99bab5

Browse files
committed
Add testing framework
1 parent 9716cd0 commit b99bab5

14 files changed

+224
-12
lines changed

source/egg/math/Quat.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ f32 Quatf::dot(const Quatf &q) const {
8080
return w * q.w + v.dot(q.v);
8181
}
8282

83+
void Quatf::read(Stream &stream) {
84+
v.read(stream);
85+
w = stream.read_f32();
86+
}
87+
8388
const Quatf Quatf::ident = Quatf(1.0f, Vector3f::zero);
8489

8590
} // namespace EGG

source/egg/math/Quat.hh

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ struct Quatf {
3535
return *this = *this * q;
3636
}
3737

38+
bool operator==(const Quatf &rhs) const {
39+
return w == rhs.w && v == rhs.v;
40+
}
41+
42+
bool operator!=(const Quatf &rhs) const {
43+
return !(*this == rhs);
44+
}
45+
3846
void setRPY(const Vector3f &rpy);
3947
void normalise();
4048
Quatf conjugate() const;
@@ -43,6 +51,8 @@ struct Quatf {
4351
f32 dot() const;
4452
f32 dot(const Quatf &q) const;
4553

54+
void read(Stream &stream);
55+
4656
Vector3f v;
4757
f32 w;
4858

source/egg/math/Vector.hh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,14 @@ struct Vector3f {
9191
return *this = *this / scalar;
9292
}
9393

94+
bool operator==(const Vector3f &rhs) const {
95+
return x == rhs.x && y == rhs.y && z == rhs.z;
96+
}
97+
98+
bool operator!=(const Vector3f &rhs) const {
99+
return !(*this == rhs);
100+
}
101+
94102
Vector3f cross(const EGG::Vector3f &rhs) const;
95103
f32 dot() const;
96104
f32 dot(const EGG::Vector3f &rhs) const;

source/egg/util/Stream.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ void Stream::jump(u32 index) {
1616
assert(!eof());
1717
}
1818

19+
void Stream::setEndian(std::endian endian) {
20+
m_endian = endian;
21+
}
22+
23+
u32 Stream::index() const {
24+
return m_index;
25+
}
26+
1927
u8 Stream::read_u8() {
2028
return read<u8>();
2129
}

source/egg/util/Stream.hh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ public:
1616
void skip(u32 count);
1717
void jump(u32 index);
1818

19+
void setEndian(std::endian endian);
20+
21+
u32 index() const;
22+
1923
u8 read_u8();
2024
u16 read_u16();
2125
u32 read_u32();

source/game/kart/KartObjectManager.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ void KartObjectManager::calc() {
1818
}
1919
}
2020

21+
KartObject *KartObjectManager::object(size_t i) const {
22+
assert(i < m_count);
23+
return m_objects[i];
24+
}
25+
2126
KartObjectManager *KartObjectManager::CreateInstance() {
2227
assert(!s_instance);
2328
s_instance = new KartObjectManager;

source/game/kart/KartObjectManager.hh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ public:
99
void init();
1010
void calc();
1111

12+
KartObject *object(size_t i) const;
13+
1214
static KartObjectManager *CreateInstance();
1315
static void DestroyInstance();
1416
static KartObjectManager *Instance();

source/game/kart/KartObjectProxy.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,14 @@ void KartObjectProxy::setRot(const EGG::Quatf &q) {
8686
dynamics()->setMainRot(q);
8787
}
8888

89+
const EGG::Vector3f &KartObjectProxy::pos() const {
90+
return dynamics()->pos();
91+
}
92+
93+
const EGG::Quatf &KartObjectProxy::fullRot() const {
94+
return dynamics()->fullRot();
95+
}
96+
8997
Abstract::List *KartObjectProxy::list() const {
9098
return s_list;
9199
}

source/game/kart/KartObjectProxy.hh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ public:
5151
void setPos(const EGG::Vector3f &pos);
5252
void setRot(const EGG::Quatf &q);
5353

54+
const EGG::Vector3f &pos() const;
55+
const EGG::Quatf &fullRot() const;
56+
5457
Abstract::List *list() const;
5558

5659
protected:

source/host/System.cc

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,25 @@ namespace Host {
77
int KSystem::main() {
88
init();
99
m_sceneMgr->changeScene(0);
10-
run();
11-
return 0;
10+
if (!m_testDirector->init()) {
11+
return 1;
12+
}
13+
return run() ? 0 : 1;
1214
}
1315

1416
void KSystem::init() {
1517
auto *sceneCreator = new SceneCreatorDynamic;
1618
m_sceneMgr = new EGG::SceneManager(sceneCreator);
19+
20+
m_testDirector = new Test::TestDirector;
1721
}
1822

19-
void KSystem::run() {
20-
K_LOG("Initialized successfully!");
21-
K_LOG("The program will now run in an infinite loop to test 'calc' functionality.");
22-
while (true) {
23+
bool KSystem::run() {
24+
do {
2325
m_sceneMgr->calc();
24-
}
26+
} while (m_testDirector->calc());
27+
28+
return m_testDirector->sync();
2529
}
2630

2731
KSystem &KSystem::Instance() {

source/host/System.hh

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,15 @@
11
#pragma once
22

33
#include <egg/core/SceneManager.hh>
4+
#include <test/TestDirector.hh>
45

56
namespace Host {
67

78
class KSystem {
89
public:
910
int main();
1011
void init();
11-
void run();
12-
13-
EGG::SceneManager *sceneMgr() const {
14-
return m_sceneMgr;
15-
}
12+
bool run();
1613

1714
static KSystem &Instance();
1815

@@ -23,6 +20,7 @@ private:
2320
~KSystem();
2421

2522
EGG::SceneManager *m_sceneMgr;
23+
Test::TestDirector *m_testDirector;
2624
};
2725

2826
} // namespace Host

source/test/Test.hh

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#pragma once
2+
3+
#include <egg/math/Quat.hh>
4+
5+
namespace Test {
6+
7+
struct TestHeader {
8+
u32 signature;
9+
u16 byteOrderMark;
10+
u16 frameCount;
11+
u16 versionMajor;
12+
u16 versionMinor;
13+
u32 dataOffset;
14+
};
15+
16+
struct TestData {
17+
EGG::Vector3f pos;
18+
EGG::Quatf fullRot;
19+
};
20+
21+
} // namespace Test

source/test/TestDirector.cc

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#include "TestDirector.hh"
2+
3+
#include <game/kart/KartObjectManager.hh>
4+
5+
#include <abstract/File.hh>
6+
7+
#include <cstddef>
8+
9+
namespace Test {
10+
11+
TestDirector::TestDirector() {
12+
size_t size;
13+
u8 *file = Abstract::File::Load("Tests/rmc3-rta-1-17-843.krkg", size);
14+
m_file = file;
15+
m_stream = EGG::RamStream(file, static_cast<u32>(size));
16+
m_currentFrame = -1;
17+
m_sync = true;
18+
19+
// Initialize endianness for the RAM stream
20+
u16 mark = *reinterpret_cast<u16 *>(file + offsetof(TestHeader, byteOrderMark));
21+
std::endian endian = parse<u16>(mark) == 0xfeff ? std::endian::big : std::endian::little;
22+
m_stream.setEndian(endian);
23+
24+
readHeader();
25+
}
26+
27+
TestDirector::~TestDirector() = default;
28+
29+
bool TestDirector::init() {
30+
assert(m_stream.read_u32() == m_stream.index());
31+
return calc();
32+
}
33+
34+
bool TestDirector::calc() {
35+
// Check if we're out of frames
36+
constexpr u16 TARGET_FRAME = 1;
37+
assert(TARGET_FRAME <= m_frameCount);
38+
if (++m_currentFrame > TARGET_FRAME) {
39+
return false;
40+
}
41+
42+
// Test the current frame
43+
TestData data = findNextEntry();
44+
m_sync = test(data);
45+
return m_sync;
46+
}
47+
48+
bool TestDirector::test(const TestData &data) {
49+
auto logVectorDesync = [this](const EGG::Vector3f &v0, const EGG::Vector3f v1,
50+
const char *name) {
51+
K_LOG("DESYNC! Frame: %d; Name: %s", m_currentFrame, name);
52+
K_LOG("Expected [%f, %f, %f], got [%f, %f, %f]", v0.x, v0.y, v0.z, v1.x, v1.y, v1.z);
53+
};
54+
55+
auto logQuatDesync = [this](const EGG::Quatf &q0, const EGG::Quatf q1, const char *name) {
56+
K_LOG("DESYNC! Frame: %d; Name: %s", m_currentFrame, name);
57+
K_LOG("Expected [%f, %f, %f, %f], got [%f, %f, %f, %f]", q0.v.x, q0.v.y, q0.v.z, q0.w,
58+
q1.v.x, q1.v.y, q1.v.z, q1.w);
59+
};
60+
61+
auto *object = Kart::KartObjectManager::Instance()->object(0);
62+
const auto &pos = object->pos();
63+
const auto &fullRot = object->fullRot();
64+
65+
if (data.pos != pos) {
66+
logVectorDesync(data.pos, pos, "pos");
67+
return false;
68+
}
69+
if (data.fullRot != fullRot) {
70+
logQuatDesync(data.fullRot, fullRot, "fullRot");
71+
return false;
72+
}
73+
74+
return true;
75+
}
76+
77+
TestData TestDirector::findNextEntry() {
78+
EGG::Vector3f pos;
79+
EGG::Quatf fullRot;
80+
pos.read(m_stream);
81+
fullRot.read(m_stream);
82+
83+
TestData data;
84+
data.pos = pos;
85+
data.fullRot = fullRot;
86+
return data;
87+
}
88+
89+
bool TestDirector::sync() const {
90+
return m_sync;
91+
}
92+
93+
void TestDirector::readHeader() {
94+
assert(m_stream.read_u32() == 0x4b524b47); // 'KRKG'
95+
m_stream.skip(2);
96+
m_frameCount = m_stream.read_u16();
97+
m_versionMajor = m_stream.read_u16();
98+
m_versionMinor = m_stream.read_u16();
99+
}
100+
101+
} // namespace Test

source/test/TestDirector.hh

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
#pragma once
2+
3+
#include "test/Test.hh"
4+
5+
#include <egg/util/Stream.hh>
6+
7+
namespace Test {
8+
9+
class TestDirector {
10+
public:
11+
TestDirector();
12+
~TestDirector();
13+
14+
bool init();
15+
bool calc();
16+
bool test(const TestData &data);
17+
18+
TestData findNextEntry();
19+
20+
bool sync() const;
21+
22+
private:
23+
void readHeader();
24+
25+
void *m_file;
26+
EGG::RamStream m_stream;
27+
28+
u16 m_versionMajor;
29+
u16 m_versionMinor;
30+
u16 m_frameCount;
31+
u16 m_currentFrame;
32+
bool m_sync;
33+
};
34+
35+
} // namespace Test

0 commit comments

Comments
 (0)