|
1 | 1 | #include <Core/StringUtils.h>
|
| 2 | +#include <Core/Utils.h> |
2 | 3 |
|
3 | 4 | #include <System/File.h>
|
4 | 5 |
|
@@ -450,24 +451,21 @@ static const char* GetDifficultyString(Difficulty difficulty)
|
450 | 451 | return "Edit";
|
451 | 452 | }
|
452 | 453 |
|
453 |
| -static int gcd(int a, int b) |
| 454 | +static inline bool TestSectionCompression(const char* section, int width, int quant) |
454 | 455 | {
|
455 |
| - if (a == 0) |
456 |
| - { |
457 |
| - return b; |
458 |
| - } |
459 |
| - if (b == 0) |
460 |
| - { |
461 |
| - return a; |
462 |
| - } |
463 |
| - if (a > b) |
464 |
| - { |
465 |
| - return gcd(a - b, b); |
466 |
| - } |
467 |
| - else |
| 456 | + String zeroline(width, '0'); |
| 457 | + float mod = (float)ROWS_PER_NOTE_SECTION / quant; |
| 458 | + for (int j = 0; j < ROWS_PER_NOTE_SECTION; ++j) |
468 | 459 | {
|
469 |
| - return gcd(a, b - a); |
| 460 | + float rem = round(fmod(j, mod)); |
| 461 | + // Check all the compressed rows and make sure they are empty |
| 462 | + if (rem > 0 && rem < static_cast<int>(mod) |
| 463 | + && memcmp(section + j * width, zeroline.str(), width)) |
| 464 | + { |
| 465 | + return false; |
| 466 | + } |
470 | 467 | }
|
| 468 | + return quant >= MIN_SECTIONS_PER_MEASURE; |
471 | 469 | }
|
472 | 470 |
|
473 | 471 | static bool GetSectionCompression(const char* section, int width, std::list<uint> quantVec, int& count, int& pitch)
|
@@ -505,35 +503,34 @@ static bool GetSectionCompression(const char* section, int width, std::list<uint
|
505 | 503 | // Determines the best compression for the given section.
|
506 | 504 | // Maybe lcm is the best factor, so just keep that.
|
507 | 505 | count = lcm;
|
508 |
| - String zeroline(width, '0'); |
509 |
| - |
510 |
| - //The factor list is small, just check them all by hand |
511 |
| - for (int i = lcm / 2; i >= 2; i--) |
| 506 | + bool valid = false; |
| 507 | + //The factor list is small, just check them all by hand, but only up to 96 at most since there won't be factors otherwise |
| 508 | + for (int i = 4; i <= lcm / 2; i++) |
512 | 509 | {
|
513 | 510 | // Skip anything that isn't a lcm factor
|
514 | 511 | if (lcm % i > 0) continue;
|
515 | 512 |
|
516 |
| - bool valid = true; |
517 |
| - float mod = (float) ROWS_PER_NOTE_SECTION / i; |
518 |
| - for (int j = 0; valid && j < ROWS_PER_NOTE_SECTION; ++j) |
519 |
| - { |
520 |
| - float rem = round(fmod(j, mod)); |
521 |
| - // Check all the compressed rows and make sure they are empty |
522 |
| - if (rem > 0 && rem < static_cast<int>(mod) |
523 |
| - && memcmp(section + j * width, zeroline.str(), width)) |
524 |
| - { |
525 |
| - valid = false; |
526 |
| - break; |
527 |
| - } |
528 |
| - } |
529 |
| - |
530 |
| - // The first (largest) match is always the best |
531 |
| - if (valid && i >= MIN_SECTIONS_PER_MEASURE) |
| 513 | + // The first (smallest) match is always the best |
| 514 | + if (TestSectionCompression(section, width, i)) |
532 | 515 | {
|
| 516 | + valid = true; |
533 | 517 | count = i;
|
534 | 518 | break;
|
535 | 519 | }
|
536 | 520 | }
|
| 521 | + |
| 522 | + // If no factor was found, double-check we won't have any data loss from our lcm guess |
| 523 | + // Why not check all factors? Saving files would be several times slower otherwise |
| 524 | + if (!valid) |
| 525 | + { |
| 526 | + valid = TestSectionCompression(section, width, lcm); |
| 527 | + } |
| 528 | + if (!valid) |
| 529 | + { |
| 530 | + // Okay, we WOULD have had data loss, so set the rows to 192 and error |
| 531 | + error = true; |
| 532 | + count = ROWS_PER_NOTE_SECTION; |
| 533 | + } |
537 | 534 | }
|
538 | 535 | // Is our factor a standard snap? If so, use it.
|
539 | 536 | // If not, save the measure as 192nds for SM5 Editor compatibility.
|
@@ -641,7 +638,7 @@ static void WriteSections(ExportData& data)
|
641 | 638 | quantVec.unique();
|
642 | 639 | if (GetSectionCompression(m, numCols, quantVec, count, pitch))
|
643 | 640 | {
|
644 |
| - HudError("Bug: zero or negative quantization recorded in chart in measure starting at row %d, quantization %d", startRow, it->quant); |
| 641 | + HudError("Bug: invalid quantization recorded in chart in measure starting at row %d", startRow); |
645 | 642 | }
|
646 | 643 | quantVec.clear();
|
647 | 644 | if (ROWS_PER_NOTE_SECTION % count != 0)
|
|
0 commit comments