53 constexpr u32 TEST_HEADER_SIGNATURE = 0x54535448;
54 constexpr u32 TEST_FOOTER_SIGNATURE = 0x54535446;
55 constexpr u16 SUITE_MAJOR_VER = 1;
56 constexpr u16 SUITE_MAX_MINOR_VER = 0;
58 u16 numTestCases = m_stream.read_u16();
59 u16 testMajorVer = m_stream.read_u16();
60 u16 testMinorVer = m_stream.read_u16();
62 if (testMajorVer != SUITE_MAJOR_VER || testMinorVer > SUITE_MAX_MINOR_VER) {
63 PANIC(
"Version not supported! Provided file is %d.%d while Kinoko supports up to %d.%d",
64 testMajorVer, testMinorVer, SUITE_MAJOR_VER, SUITE_MAX_MINOR_VER);
67 for (u16 i = 0; i < numTestCases; ++i) {
69 if (m_stream.read_u32() != TEST_HEADER_SIGNATURE) {
70 PANIC(
"Invalid binary data for test case!");
73 u16 totalSize = m_stream.read_u16();
76 u16 nameLen = m_stream.read_u16();
77 testCase.name = m_stream.read_string();
78 if (nameLen != testCase.name.size() + 1) {
79 PANIC(
"Test case name length mismatch!");
82 u16 rkgPathLen = m_stream.read_u16();
83 testCase.rkgPath = m_stream.read_string();
84 if (rkgPathLen != testCase.rkgPath.size() + 1) {
85 PANIC(
"Test case RKG Path length mismatch!");
88 u16 krkgPathLen = m_stream.read_u16();
89 testCase.krkgPath = m_stream.read_string();
90 if (krkgPathLen != testCase.krkgPath.size() + 1) {
91 PANIC(
"Test case KRKG Path length mismatch!");
94 testCase.targetFrame = m_stream.read_u16();
97 if (m_stream.read_u32() != TEST_FOOTER_SIGNATURE) {
98 PANIC(
"Invalid binary data for test case!");
101 if (totalSize !=
sizeof(u16) * 4 + nameLen + rkgPathLen + krkgPathLen) {
102 PANIC(
"Unexpected bytes in test case");
105 m_testCases.push(testCase);
142 PANIC(
"Expected suite/ghost/krkg argument!");
145 std::optional<char *> rkgPath;
146 std::optional<char *> krkgPath;
147 std::optional<u16> target;
149 for (
int i = 0; i < argc; ++i) {
150 std::optional<Host::EOption> flag = Host::Option::CheckFlag(argv[i]);
151 if (!flag || *flag == Host::EOption::Invalid) {
152 WARN(
"Expected a flag! Got: %s", argv[i]);
157 case Host::EOption::Suite: {
159 PANIC(
"Mode was already set!");
164 ASSERT(i + 1 < argc);
167 u8 *data = Abstract::File::Load(argv[++i], size);
170 PANIC(
"Failed to load suite data!");
174 m_stream.setEndian(std::endian::big);
177 case Host::EOption::Ghost:
179 PANIC(
"Mode was already set!");
183 ASSERT(i + 1 < argc);
187 case Host::EOption::KRKG:
189 PANIC(
"Mode was already set!");
193 ASSERT(i + 1 < argc);
194 krkgPath = argv[++i];
197 case Host::EOption::TargetFrame:
198 ASSERT(i + 1 < argc);
200 if (strlen(argv[++i]) > 5) {
201 PANIC(
"Target has too many digits");
203 target = atoi(argv[i]);
204 if (target < 0 || target > std::numeric_limits<u16>::max()) {
205 PANIC(
"Target is out of bounds (expected 0-65535), got %d\n", *target);
210 case Host::EOption::Invalid:
212 PANIC(
"Invalid flag!");
217 if (target &&
m_testMode != Host::EOption::Ghost) {
218 PANIC(
"'--framecount' is only supported in a single ghost test");
223 PANIC(
"Missing ghost argument!");
227 PANIC(
"Missing KRKG argument!");
234 m_testCases.emplace(*rkgPath, *rkgPath, *krkgPath, *target);
262 constexpr u32 KRKG_SIGNATURE = 0x4b524b47;
271 u16 mark =
reinterpret_cast<TestHeader *
>(krkg)->byteOrderMark;
272 std::endian endian = parse<u16>(mark) == 0xfeff ? std::endian::big : std::endian::little;
273 m_stream.setEndian(endian);
275 ASSERT(m_stream.read_u32() == KRKG_SIGNATURE);
277 m_frameCount = m_stream.read_u16();
278 m_versionMajor = m_stream.read_u16();
279 m_versionMinor = m_stream.read_u16();
281 ASSERT(m_stream.read_u32() == m_stream.index());
286 ASSERT(m_testCases.size() == 1);
287 auto &front = m_testCases.front();
288 if (front.targetFrame == 0) {
289 front.targetFrame = m_frameCount;
292 front.targetFrame = std::min(front.targetFrame, m_frameCount);
333 f32 acceleration = 0.0f;
334 f32 softSpeedLimit = 0.0f;
337 f32 raceCompletion = 0.0f;
338 u16 checkpointId = 0;
342 fullRot.read(m_stream);
344 if (m_versionMinor >= Changelog::AddedExtVel) {
345 extVel.
read(m_stream);
348 if (m_versionMinor >= Changelog::AddedIntVel) {
349 intVel.
read(m_stream);
352 if (m_versionMinor >= Changelog::AddedSpeed) {
353 speed = m_stream.read_f32();
354 acceleration = m_stream.read_f32();
355 softSpeedLimit = m_stream.read_f32();
358 if (m_versionMinor >= Changelog::AddedRotation) {
359 mainRot.read(m_stream);
360 angVel2.
read(m_stream);
363 if (m_versionMinor >= Changelog::AddedCheckpoints) {
364 raceCompletion = m_stream.read_f32();
365 checkpointId = m_stream.read_u16();
366 jugemId = m_stream.read_u8();
372 data.fullRot = fullRot;
373 data.extVel = extVel;
374 data.intVel = intVel;
376 data.acceleration = acceleration;
377 data.softSpeedLimit = softSpeedLimit;
378 data.mainRot = mainRot;
379 data.angVel2 = angVel2;
380 data.raceCompletion = raceCompletion;
381 data.checkpointId = checkpointId;
382 data.jugemId = jugemId;
389 auto *
object = Kart::KartObjectManager::Instance()->object(0);
390 const auto &pos =
object->pos();
391 const auto &fullRot =
object->fullRot();
392 const auto &extVel =
object->extVel();
393 const auto &intVel =
object->intVel();
394 f32 speed =
object->speed();
395 f32 acceleration =
object->acceleration();
396 f32 softSpeedLimit =
object->softSpeedLimit();
397 const auto &mainRot =
object->mainRot();
398 const auto &angVel2 =
object->angVel2();
400 const auto &player = System::RaceManager::Instance()->player();
401 f32 raceCompletion = player.raceCompletion();
402 u16 checkpointId = player.checkpointId();
403 u8 jugemId = player.jugemId();
405 switch (m_versionMinor) {
406 case Changelog::AddedCheckpoints:
407 checkDesync(data.raceCompletion, raceCompletion,
"raceCompletion");
408 checkDesync(data.checkpointId, checkpointId,
"checkpointId");
409 checkDesync(data.jugemId, jugemId,
"jugemId");
411 case Changelog::AddedRotation:
412 checkDesync(data.mainRot, mainRot,
"mainRot");
413 checkDesync(data.angVel2, angVel2,
"angVel2");
415 case Changelog::AddedSpeed:
416 checkDesync(data.speed, speed,
"speed");
417 checkDesync(data.acceleration, acceleration,
"acceleration");
418 checkDesync(data.softSpeedLimit, softSpeedLimit,
"softSpeedLimit");
420 case Changelog::AddedIntVel:
421 checkDesync(data.intVel, intVel,
"intVel");
423 case Changelog::AddedExtVel:
424 checkDesync(data.extVel, extVel,
"extVel");
427 checkDesync(data.pos, pos,
"pos");
428 checkDesync(data.fullRot, fullRot,
"fullRot");