A reimplementation of Mario Kart Wii's physics engine in C++
Loading...
Searching...
No Matches
KTestSystem.hh
1#pragma once
2
3#include "host/KSystem.hh"
4#include "host/Option.hh"
5
6#include <egg/core/SceneManager.hh>
7#include <egg/math/Quat.hh>
8
9#include <game/system/RaceConfig.hh>
10
11#include <queue>
12
13namespace Kinoko {
14
16class KTestSystem final : public KSystem {
17public:
18 void init() override;
19 void calc() override;
20 bool run() override;
21 void parseOptions(int argc, char **argv) override;
22
23 static KTestSystem *CreateInstance();
24 static void DestroyInstance();
25
26 static KTestSystem *Instance() {
27 return static_cast<KTestSystem *>(s_instance);
28 }
29
30private:
31 struct TestCase {
32 std::string name;
33 std::string rkgPath;
34 std::string krkgPath;
35 u16 targetFrame;
36 };
37
38 struct TestData {
39 EGG::Vector3f pos;
40 EGG::Quatf fullRot;
41 // Added in 0.2
42 EGG::Vector3f extVel;
43 // Added in 0.3
44 EGG::Vector3f intVel;
45 // Added in 0.4
46 f32 speed;
47 f32 acceleration;
48 f32 softSpeedLimit;
49 // Added in 0.5
50 EGG::Quatf mainRot;
51 EGG::Vector3f angVel2;
52 // Added in 0.6
53 f32 raceCompletion;
54 u16 checkpointId;
55 u8 jugemId;
56 };
57
59 KTestSystem(const KTestSystem &) = delete;
60 KTestSystem(KTestSystem &&) = delete;
61 ~KTestSystem() override;
62
63 template <IntegralType T>
64 void checkDesync(const T &t0, const T &t1, const char *name) {
65 if (t0 == t1) {
66 return;
67 }
68
69 if (m_sync) {
70 REPORT("Test Case Failed: %s [%d / %d]", getCurrentTestCase().name.c_str(),
71 m_currentFrame, m_frameCount);
72 }
73
74 REPORT("DESYNC! Name: %s", name);
75 REPORT("Expected: %d", t0);
76 REPORT("Observed: %d", t1);
77
78 m_sync = false;
79 }
80
81 template <typename T>
82 void checkDesync(const T &t0, const T &t1, const char *name) {
83 if (t0 == t1) {
84 return;
85 }
86
87 m_sceneMgr->currentScene()->heap()->enableAllocation();
88
89 if (m_sync) {
90 REPORT("Test Case Failed: %s [%d / %d]", getCurrentTestCase().name.c_str(),
91 m_currentFrame, m_frameCount);
92 }
93
94 REPORT("DESYNC! Name: %s", name);
95 std::string s0(t0);
96 std::string s1(t1);
97 REPORT("Expected: %s", s0.c_str());
98 REPORT("Observed: %s", s1.c_str());
99
100 m_sceneMgr->currentScene()->heap()->disableAllocation();
101
102 m_sync = false;
103 }
104
105 void checkDesync(const f32 &t0, const f32 &t1, const char *name) {
106 if (t0 == t1) {
107 return;
108 }
109
110 m_sceneMgr->currentScene()->heap()->enableAllocation();
111
112 if (m_sync) {
113 REPORT("Test Case Failed: %s [%d / %d]", getCurrentTestCase().name.c_str(),
114 m_currentFrame, m_frameCount);
115 }
116
117 REPORT("DESYNC! Name: %s", name);
118 std::string s0 = std::to_string(t0);
119 std::string s1 = std::to_string(t1);
120 REPORT("Expected: 0x%08X | %s", f2u(t0), s0.c_str());
121 REPORT("Observed: 0x%08X | %s", f2u(t1), s1.c_str());
122
123 m_sceneMgr->currentScene()->heap()->disableAllocation();
124
125 m_sync = false;
126 }
127
128 void initSuite();
129
130 void startNextTestCase();
131 bool popTestCase();
132
133 bool calcTest();
134 TestData findCurrentFrameEntry();
135 void testFrame(const TestData &data);
136
137 bool runTest();
138 void writeTestOutput() const;
139
140 const TestCase &getCurrentTestCase() const;
141
142 static void OnInit(System::RaceConfig *config, void *arg);
143
144 EGG::SceneManager *m_sceneMgr;
145 EGG::RamStream m_stream;
146 std::queue<TestCase> m_testCases;
147 Host::EOption m_testMode;
148
149 u16 m_versionMajor;
150 u16 m_versionMinor;
151 u16 m_frameCount;
152 u16 m_currentFrame;
153 bool m_sync;
154};
155
156} // namespace Kinoko
Base interface for a Kinoko system.
Definition KSystem.hh:10
Kinoko system designed to execute tests.
bool popTestCase()
Pops the current test case and frees the KRKG buffer.
Host::EOption m_testMode
Differentiates between test suite and ghost+krkg.
bool run() override
Executes a run.
TestData findCurrentFrameEntry()
Finds the test data of the current frame.
void parseOptions(int argc, char **argv) override
Parses non-generic command line options.
void startNextTestCase()
Starts the next test case.
void writeTestOutput() const
Writes details about the current test to file.
bool calcTest()
Checks one frame in the test.
const TestCase & getCurrentTestCase() const
Gets the current test case.
void testFrame(const TestData &data)
Tests the frame against the provided test data.
bool runTest()
Runs a single test case, and ends when the test is finished or when a desync is found.
static void OnInit(System::RaceConfig *config, void *arg)
Initializes the race configuration as needed for test cases.
void calc() override
Executes a frame.
void init() override
Initializes the system.
A quaternion, used to represent 3D rotation.
Definition Quat.hh:12
A 3D float vector.
Definition Vector.hh:107