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