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/Allocator.hh>
7#include <egg/core/SceneManager.hh>
8#include <egg/math/Quat.hh>
9
10#include <game/system/RaceConfig.hh>
11
12#include <queue>
13
14namespace Kinoko {
15
17class KTestSystem final : public KSystem {
18public:
19 void init() override;
20 void calc() override;
21 bool run() override;
22 void parseOptions(int argc, char **argv) override;
23
24 static KTestSystem *CreateInstance();
25 static void DestroyInstance();
26
27 static KTestSystem *Instance() {
28 return static_cast<KTestSystem *>(s_instance);
29 }
30
31private:
32 struct TestCase {
33 std::string name;
34 std::string rkgPath;
35 std::string krkgPath;
36 u16 targetFrame;
37 };
38
39 struct TestData {
40 EGG::Vector3f pos;
41 EGG::Quatf fullRot;
42 // Added in 0.2
43 EGG::Vector3f extVel;
44 // Added in 0.3
45 EGG::Vector3f intVel;
46 // Added in 0.4
47 f32 speed;
48 f32 acceleration;
49 f32 softSpeedLimit;
50 // Added in 0.5
51 EGG::Quatf mainRot;
52 EGG::Vector3f angVel2;
53 // Added in 0.6
54 f32 raceCompletion;
55 u16 checkpointId;
56 u8 jugemId;
57 };
58
59 EGG_NEW_DELETE_FRIEND
60
61 KTestSystem();
62 ~KTestSystem() override;
63
64 KTestSystem(const KTestSystem &) = delete;
65 KTestSystem(KTestSystem &&) = delete;
66
67 template <IntegralType T>
68 void checkDesync(const T &t0, const T &t1, const char *name) {
69 if (t0 == t1) {
70 return;
71 }
72
73 if (m_sync) {
74 REPORT("Test Case Failed: %s [%d / %d]", getCurrentTestCase().name.c_str(),
75 m_currentFrame, m_frameCount);
76 }
77
78 REPORT("DESYNC! Name: %s", name);
79 REPORT("Expected: %d", t0);
80 REPORT("Observed: %d", t1);
81
82 m_sync = false;
83 }
84
85 template <typename T>
86 void checkDesync(const T &t0, const T &t1, const char *name) {
87 if (t0 == t1) {
88 return;
89 }
90
91 m_sceneMgr->currentScene()->heap()->enableAllocation();
92
93 if (m_sync) {
94 REPORT("Test Case Failed: %s [%d / %d]", getCurrentTestCase().name.c_str(),
95 m_currentFrame, m_frameCount);
96 }
97
98 REPORT("DESYNC! Name: %s", name);
99 std::string s0(t0);
100 std::string s1(t1);
101 REPORT("Expected: %s", s0.c_str());
102 REPORT("Observed: %s", s1.c_str());
103
104 m_sceneMgr->currentScene()->heap()->disableAllocation();
105
106 m_sync = false;
107 }
108
109 void checkDesync(const f32 &t0, const f32 &t1, const char *name) {
110 if (t0 == t1) {
111 return;
112 }
113
114 m_sceneMgr->currentScene()->heap()->enableAllocation();
115
116 if (m_sync) {
117 REPORT("Test Case Failed: %s [%d / %d]", getCurrentTestCase().name.c_str(),
118 m_currentFrame, m_frameCount);
119 }
120
121 REPORT("DESYNC! Name: %s", name);
122 std::string s0 = std::to_string(t0);
123 std::string s1 = std::to_string(t1);
124 REPORT("Expected: 0x%08X | %s", f2u(t0), s0.c_str());
125 REPORT("Observed: 0x%08X | %s", f2u(t1), s1.c_str());
126
127 m_sceneMgr->currentScene()->heap()->disableAllocation();
128
129 m_sync = false;
130 }
131
132 void initSuite();
133
134 void startNextTestCase();
135 bool popTestCase();
136
137 bool calcTest();
139 void testFrame(const TestData &data);
140
141 bool runTest();
142 void writeTestOutput() const;
143
144 const TestCase &getCurrentTestCase() const;
145
146 static void OnInit(System::RaceConfig *config, void *arg);
147
148 EGG::SceneManager *m_sceneMgr;
149 EGG::RamStream m_stream;
150 std::queue<TestCase, std::deque<TestCase, EGG::Allocator<TestCase>>> m_testCases;
151 Host::EOption m_testMode;
152
153 u16 m_versionMajor;
154 u16 m_versionMinor;
155 u16 m_frameCount;
156 u16 m_currentFrame;
157 bool m_sync;
158};
159
160} // namespace Kinoko
Base interface for a Kinoko system.
Definition KSystem.hh:10
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