Commit b6e52d6

Nick committed on
De-duplicate patterns and don't compile unused ones
commit b6e52d62184f8df11e2a3716c4727007586e747d parent f08b3b5
2 changed files +46−4
Modifiedcodegen.pas +7−2
@@ -464,6 +464,8 @@ var
464 label 464 label
465 AssemblyError, Cleanup; // Eh, screw good practice. How bad can it be? 465 AssemblyError, Cleanup; // Eh, screw good practice. How bad can it be?
466 begin 466 begin
467 Song := OptimizeSong(Song);
468
467 FilePath := Filename; 469 FilePath := Filename;
468 Filename := ExtractFileNameWithoutExt(ExtractFileNameOnly(Filename)); 470 Filename := ExtractFileNameWithoutExt(ExtractFileNameOnly(Filename));
469 471
@@ -482,8 +484,9 @@ begin
482 // TODO: Are keys and data defined to be aligned? Seems like they are but 484 // TODO: Are keys and data defined to be aligned? Seems like they are but
483 // should probably find out if that's just an implementation detail... 485 // should probably find out if that's just an implementation detail...
484 for I := 0 to Song.Patterns.Count - 1 do 486 for I := 0 to Song.Patterns.Count - 1 do
485 Write(OutFile, RenderPattern('P' + IntToStr(Song.Patterns.Keys[I]), 487 if PatternIsUsed(Song.Patterns.Keys[I], Song) then
486 Song.Patterns.Data[I]^)); 488 Write(OutFile, RenderPattern('P' + IntToStr(Song.Patterns.Keys[I]),
489 Song.Patterns.Data[I]^));
487 490
488 CloseFile(OutFile); 491 CloseFile(OutFile);
489 492
@@ -624,6 +627,8 @@ begin
624 end; 627 end;
625 628
626 Cleanup: 629 Cleanup:
630 // No need to destroy Song-- OptimizeSong's output has the same lifetime
631 // as its argument.
627 Proc.Free; 632 Proc.Free;
628 OutSL.Free; 633 OutSL.Free;
629 Chdir('..'); 634 Chdir('..');
Modifiedsong.pas +39−2
@@ -95,6 +95,9 @@ function UpgradeSong(S: TSongV2): TSong; overload;
95 function UpgradeSong(S: TSongV3): TSong; overload; 95 function UpgradeSong(S: TSongV3): TSong; overload;
96 function UpgradeSong(S: TSongV4): TSong; overload; 96 function UpgradeSong(S: TSongV4): TSong; overload;
97 97
98 function OptimizeSong(const S: TSong): TSong;
99 function PatternIsUsed(Idx: Integer; const Song: TSong): Boolean;
100
98 implementation 101 implementation
99 102
100 // Thanks to WP on the FreePascal forums for this code! 103 // Thanks to WP on the FreePascal forums for this code!
@@ -442,8 +445,6 @@ var
442 I: Integer; 445 I: Integer;
443 begin 446 begin
444 S.Patterns.Free; 447 S.Patterns.Free;
445 for I := Low(TOrderMatrix) to High(TOrderMatrix) do
446 SetLength(S.OrderMatrix[I], 0);
447 end; 448 end;
448 449
449 function UpgradeSong(S: TSongV1): TSong; 450 function UpgradeSong(S: TSongV1): TSong;
@@ -604,5 +605,41 @@ begin
604 Result := S; 605 Result := S;
605 end; 606 end;
606 607
608 function OptimizeSong(const S: TSong): TSong;
609 var
610 I, J: Integer;
611
612 function FindMatchingPattern(const P: TPattern): Integer;
613 var
614 K: Integer;
615 begin
616 for K := 0 to S.Patterns.Count-1 do
617 if CompareByte(S.Patterns.KeyData[S.Patterns.Keys[K]]^, P, SizeOf(TPattern)) = 0 then
618 Result := S.Patterns.Keys[K];
619 end;
620 begin
621 Result := S;
622
623 // Uniquify the order matrix (so modifying the original doesn't affect this one)
624 for I := Low(Result.OrderMatrix) to High(Result.OrderMatrix) do
625 SetLength(Result.OrderMatrix[I], Length(Result.OrderMatrix[I]));
626
627 // De-duplicate order matrix such that only unique numbers remain
628 for I := Low(Result.OrderMatrix) to High(Result.OrderMatrix) do
629 for J := Low(Result.OrderMatrix[I]) to High(Result.OrderMatrix[I])-1 do
630 Result.OrderMatrix[I, J] := FindMatchingPattern(Result.Patterns[Result.OrderMatrix[I, J]]^);
631 end;
632
633 function PatternIsUsed(Idx: Integer; const Song: TSong): Boolean;
634 var
635 I, J: Integer;
636 begin
637 for I := Low(Song.OrderMatrix) to High(Song.OrderMatrix) do
638 for J := Low(Song.OrderMatrix[I]) to High(Song.OrderMatrix[I])-1 do
639 if Song.OrderMatrix[I, J] = Idx then Exit(True);
640
641 Result := False;
642 end;
643
607 end. 644 end.
608 645