51 constexpr u32 TEST_HEADER_SIGNATURE = 0x54535448;
52 constexpr u32 TEST_FOOTER_SIGNATURE = 0x54535446;
53 constexpr u16 SUITE_MAJOR_VER = 1;
54 constexpr u16 SUITE_MAX_MINOR_VER = 0;
56 u16 numTestCases = m_stream.read_u16();
57 u16 testMajorVer = m_stream.read_u16();
58 u16 testMinorVer = m_stream.read_u16();
60 if (testMajorVer != SUITE_MAJOR_VER || testMinorVer > SUITE_MAX_MINOR_VER) {
61 PANIC(
"Version not supported! Provided file is %d.%d while Kinoko supports up to %d.%d",
62 testMajorVer, testMinorVer, SUITE_MAJOR_VER, SUITE_MAX_MINOR_VER);
65 for (
u16 i = 0; i < numTestCases; ++i) {
67 if (m_stream.read_u32() != TEST_HEADER_SIGNATURE) {
68 PANIC(
"Invalid binary data for test case!");
71 u16 totalSize = m_stream.read_u16();
74 u16 nameLen = m_stream.read_u16();
75 testCase.name = m_stream.read_string();
76 if (nameLen != testCase.name.size() + 1) {
77 PANIC(
"Test case name length mismatch!");
80 u16 rkgPathLen = m_stream.read_u16();
81 testCase.rkgPath = m_stream.read_string();
82 if (rkgPathLen != testCase.rkgPath.size() + 1) {
83 PANIC(
"Test case RKG Path length mismatch!");
86 u16 krkgPathLen = m_stream.read_u16();
87 testCase.krkgPath = m_stream.read_string();
88 if (krkgPathLen != testCase.krkgPath.size() + 1) {
89 PANIC(
"Test case KRKG Path length mismatch!");
92 testCase.targetFrame = m_stream.read_u16();
95 if (m_stream.read_u32() != TEST_FOOTER_SIGNATURE) {
96 PANIC(
"Invalid binary data for test case!");
99 if (totalSize !=
sizeof(
u16) * 4 + nameLen + rkgPathLen + krkgPathLen) {
100 PANIC(
"Unexpected bytes in test case");
103 m_testCases.push(testCase);
140 PANIC(
"Expected suite/ghost/krkg argument!");
143 std::optional<char *> rkgPath;
144 std::optional<char *> krkgPath;
145 std::optional<u16> target;
147 for (
int i = 0; i < argc; ++i) {
148 std::optional<Host::EOption> flag = Host::Option::CheckFlag(argv[i]);
149 if (!flag || *flag == Host::EOption::Invalid) {
150 WARN(
"Expected a flag! Got: %s", argv[i]);
155 case Host::EOption::Suite: {
157 PANIC(
"Mode was already set!");
162 ASSERT(i + 1 < argc);
165 u8 *data = Abstract::File::Load(argv[++i], size);
168 PANIC(
"Failed to load suite data!");
172 m_stream.setEndian(std::endian::big);
175 case Host::EOption::Ghost:
177 PANIC(
"Mode was already set!");
181 ASSERT(i + 1 < argc);
185 case Host::EOption::KRKG:
187 PANIC(
"Mode was already set!");
191 ASSERT(i + 1 < argc);
192 krkgPath = argv[++i];
195 case Host::EOption::TargetFrame:
196 ASSERT(i + 1 < argc);
198 if (strlen(argv[++i]) > 5) {
199 PANIC(
"Target has too many digits");
201 target = atoi(argv[i]);
202 if (target < 0 || target > std::numeric_limits<u16>::max()) {
203 PANIC(
"Target is out of bounds (expected 0-65535), got %d\n", *target);
208 case Host::EOption::Invalid:
210 PANIC(
"Invalid flag!");
215 if (target &&
m_testMode != Host::EOption::Ghost) {
216 PANIC(
"'--framecount' is only supported in a single ghost test");
221 PANIC(
"Missing ghost argument!");
225 PANIC(
"Missing KRKG argument!");
232 m_testCases.emplace(*rkgPath, *rkgPath, *krkgPath, *target);
260 constexpr u32 KRKG_SIGNATURE = 0x4b524b47;
269 u16 mark =
reinterpret_cast<TestHeader *
>(krkg)->byteOrderMark;
270 std::endian endian = parse<u16>(mark) == 0xfeff ? std::endian::big : std::endian::little;
271 m_stream.setEndian(endian);
273 ASSERT(m_stream.read_u32() == KRKG_SIGNATURE);
275 m_frameCount = m_stream.read_u16();
276 m_versionMajor = m_stream.read_u16();
277 m_versionMinor = m_stream.read_u16();
279 ASSERT(m_stream.read_u32() == m_stream.index());
284 ASSERT(m_testCases.size() == 1);
285 auto &front = m_testCases.front();
286 if (front.targetFrame == 0) {
287 front.targetFrame = m_frameCount;
290 front.targetFrame = std::min(front.targetFrame, m_frameCount);
331 f32 acceleration = 0.0f;
332 f32 softSpeedLimit = 0.0f;
335 f32 raceCompletion = 0.0f;
336 u16 checkpointId = 0;
340 fullRot.read(m_stream);
342 if (m_versionMinor >= Changelog::AddedExtVel) {
343 extVel.
read(m_stream);
346 if (m_versionMinor >= Changelog::AddedIntVel) {
347 intVel.
read(m_stream);
350 if (m_versionMinor >= Changelog::AddedSpeed) {
351 speed = m_stream.read_f32();
352 acceleration = m_stream.read_f32();
353 softSpeedLimit = m_stream.read_f32();
356 if (m_versionMinor >= Changelog::AddedRotation) {
357 mainRot.read(m_stream);
358 angVel2.
read(m_stream);
361 if (m_versionMinor >= Changelog::AddedCheckpoints) {
362 raceCompletion = m_stream.read_f32();
363 checkpointId = m_stream.read_u16();
364 jugemId = m_stream.read_u8();
370 data.fullRot = fullRot;
371 data.extVel = extVel;
372 data.intVel = intVel;
374 data.acceleration = acceleration;
375 data.softSpeedLimit = softSpeedLimit;
376 data.mainRot = mainRot;
377 data.angVel2 = angVel2;
378 data.raceCompletion = raceCompletion;
379 data.checkpointId = checkpointId;
380 data.jugemId = jugemId;
387 auto *
object = Kart::KartObjectManager::Instance()->object(0);
388 const auto &pos =
object->pos();
389 const auto &fullRot =
object->fullRot();
390 const auto &extVel =
object->extVel();
391 const auto &intVel =
object->intVel();
392 f32 speed =
object->speed();
393 f32 acceleration =
object->acceleration();
394 f32 softSpeedLimit =
object->softSpeedLimit();
395 const auto &mainRot =
object->mainRot();
396 const auto &angVel2 =
object->angVel2();
398 const auto &player = System::RaceManager::Instance()->player();
399 f32 raceCompletion = player.raceCompletion();
400 u16 checkpointId = player.checkpointId();
401 u8 jugemId = player.jugemId();
403 switch (m_versionMinor) {
404 case Changelog::AddedCheckpoints:
405 checkDesync(data.raceCompletion, raceCompletion,
"raceCompletion");
406 checkDesync(data.checkpointId, checkpointId,
"checkpointId");
407 checkDesync(data.jugemId, jugemId,
"jugemId");
409 case Changelog::AddedRotation:
410 checkDesync(data.mainRot, mainRot,
"mainRot");
411 checkDesync(data.angVel2, angVel2,
"angVel2");
413 case Changelog::AddedSpeed:
414 checkDesync(data.speed, speed,
"speed");
415 checkDesync(data.acceleration, acceleration,
"acceleration");
416 checkDesync(data.softSpeedLimit, softSpeedLimit,
"softSpeedLimit");
418 case Changelog::AddedIntVel:
419 checkDesync(data.intVel, intVel,
"intVel");
421 case Changelog::AddedExtVel:
422 checkDesync(data.extVel, extVel,
"extVel");
425 checkDesync(data.pos, pos,
"pos");
426 checkDesync(data.fullRot, fullRot,
"fullRot");