Commit d9fc450

Nick committed on
Finish adding unused pattern removal
commit d9fc45074c8bd2fa1a5d3ce2a53beb7cfd819267 parent 07beedf
5 changed files +113−47
Modifiedcodegen.pas +4−1
@@ -216,8 +216,11 @@ begin
216 AssignFile(OutFile, './hUGEDriver/pattern.htt'); 216 AssignFile(OutFile, './hUGEDriver/pattern.htt');
217 Rewrite(OutFile); 217 Rewrite(OutFile);
218 218
219 // Are keys and data defined to be aligned? Seems like they are but
220 // should probably find out if that's just an implementation detail...
219 for I := 0 to Song.Patterns.Count-1 do 221 for I := 0 to Song.Patterns.Count-1 do
220 Write(OutFile, RenderPattern('P'+IntToStr(I), Song.Patterns.Data[I]^)); 222 Write(OutFile, RenderPattern('P'+IntToStr(Song.Patterns.Keys[I]),
223 Song.Patterns.Data[I]^));
221 224
222 CloseFile(OutFile); 225 CloseFile(OutFile);
223 226
Modifiedconstants.pas +4−0
@@ -13,6 +13,10 @@ type
13 TKeybindings = specialize TFPGmap<Word, Integer>; 13 TKeybindings = specialize TFPGmap<Word, Integer>;
14 TNoteToFreqMap = specialize TFPGMap<Integer, Integer>; 14 TNoteToFreqMap = specialize TFPGMap<Integer, Integer>;
15 15
16 TInstrumentIndex = 1..15;
17 TWaveIndex = 0..15;
18 TRoutineIndex = 0..15;
19
16 const 20 const
17 UGE_FORMAT_VERSION = 2; 21 UGE_FORMAT_VERSION = 2;
18 22
Modifiedtracker.lfm +27−27
@@ -1,7 +1,7 @@
1 object frmTracker: TfrmTracker 1 object frmTracker: TfrmTracker
2 Left = 1936 2 Left = 1889
3 Height = 686 3 Height = 686
4 Top = 123 4 Top = 140
5 Width = 1166 5 Width = 1166
6 Caption = 'hUGETracker' 6 Caption = 'hUGETracker'
7 ClientHeight = 666 7 ClientHeight = 666
@@ -905,16 +905,16 @@ object frmTracker: TfrmTracker
905 end 905 end
906 object WavesTabSheet: TTabSheet 906 object WavesTabSheet: TTabSheet
907 Caption = 'Waves' 907 Caption = 'Waves'
908 ClientHeight = 727 908 ClientHeight = 412
909 ClientWidth = 1685 909 ClientWidth = 960
910 ParentFont = False 910 ParentFont = False
911 object WaveEditPaintBox: TPaintBox 911 object WaveEditPaintBox: TPaintBox
912 AnchorSideTop.Control = WaveEditGroupBox 912 AnchorSideTop.Control = WaveEditGroupBox
913 AnchorSideTop.Side = asrBottom 913 AnchorSideTop.Side = asrBottom
914 Left = 0 914 Left = 0
915 Height = 447 915 Height = 252
916 Top = 280 916 Top = 160
917 Width = 1685 917 Width = 960
918 Align = alBottom 918 Align = alBottom
919 Anchors = [akTop, akLeft, akRight, akBottom] 919 Anchors = [akTop, akLeft, akRight, akBottom]
920 BorderSpacing.Top = 13 920 BorderSpacing.Top = 13
@@ -936,16 +936,16 @@ object frmTracker: TfrmTracker
936 TabOrder = 0 936 TabOrder = 0
937 object Label20: TLabel 937 object Label20: TLabel
938 Left = 16 938 Left = 16
939 Height = 30 939 Height = 15
940 Top = 16 940 Top = 16
941 Width = 51 941 Width = 29
942 Caption = 'Wave' 942 Caption = 'Wave'
943 ParentColor = False 943 ParentColor = False
944 ParentFont = False 944 ParentFont = False
945 end 945 end
946 object WaveEditNumberSpinner: TSpinEdit 946 object WaveEditNumberSpinner: TSpinEdit
947 Left = 64 947 Left = 64
948 Height = 38 948 Height = 23
949 Top = 8 949 Top = 8
950 Width = 80 950 Width = 80
951 MaxValue = 15 951 MaxValue = 15
@@ -979,17 +979,17 @@ object frmTracker: TfrmTracker
979 end 979 end
980 object CommentsTabSheet: TTabSheet 980 object CommentsTabSheet: TTabSheet
981 Caption = 'Comments' 981 Caption = 'Comments'
982 ClientHeight = 727 982 ClientHeight = 412
983 ClientWidth = 1685 983 ClientWidth = 960
984 ParentFont = False 984 ParentFont = False
985 object CommentMemo: TMemo 985 object CommentMemo: TMemo
986 AnchorSideTop.Control = Label17 986 AnchorSideTop.Control = Label17
987 AnchorSideTop.Side = asrBottom 987 AnchorSideTop.Side = asrBottom
988 Left = 0 988 Left = 0
989 Height = 660 989 Height = 376
990 Hint = 'The comments section for your song. Greetings/links/etc' 990 Hint = 'The comments section for your song. Greetings/links/etc'
991 Top = 67 991 Top = 36
992 Width = 1685 992 Width = 960
993 Align = alBottom 993 Align = alBottom
994 Anchors = [akTop, akLeft, akRight, akBottom] 994 Anchors = [akTop, akLeft, akRight, akBottom]
995 BorderSpacing.Top = 13 995 BorderSpacing.Top = 13
@@ -1000,9 +1000,9 @@ object frmTracker: TfrmTracker
1000 end 1000 end
1001 object Label17: TLabel 1001 object Label17: TLabel
1002 Left = 8 1002 Left = 8
1003 Height = 30 1003 Height = 15
1004 Top = 8 1004 Top = 8
1005 Width = 587 1005 Width = 333
1006 Caption = 'This is an area to write comments for anyone editing your tune.' 1006 Caption = 'This is an area to write comments for anyone editing your tune.'
1007 ParentColor = False 1007 ParentColor = False
1008 ParentFont = False 1008 ParentFont = False
@@ -1010,16 +1010,16 @@ object frmTracker: TfrmTracker
1010 end 1010 end
1011 object RoutinesTabSheet: TTabSheet 1011 object RoutinesTabSheet: TTabSheet
1012 Caption = 'Routines' 1012 Caption = 'Routines'
1013 ClientHeight = 727 1013 ClientHeight = 412
1014 ClientWidth = 1685 1014 ClientWidth = 960
1015 ParentFont = False 1015 ParentFont = False
1016 inline RoutineSynedit: TSynEdit 1016 inline RoutineSynedit: TSynEdit
1017 AnchorSideTop.Control = Label19 1017 AnchorSideTop.Control = Label19
1018 AnchorSideTop.Side = asrBottom 1018 AnchorSideTop.Side = asrBottom
1019 Left = 0 1019 Left = 0
1020 Height = 484 1020 Height = 284
1021 Top = 243 1021 Top = 128
1022 Width = 1685 1022 Width = 960
1023 Align = alBottom 1023 Align = alBottom
1024 BorderSpacing.Top = 13 1024 BorderSpacing.Top = 13
1025 Anchors = [akTop, akLeft, akRight, akBottom] 1025 Anchors = [akTop, akLeft, akRight, akBottom]
@@ -1520,16 +1520,16 @@ object frmTracker: TfrmTracker
1520 end 1520 end
1521 object Label18: TLabel 1521 object Label18: TLabel
1522 Left = 8 1522 Left = 8
1523 Height = 30 1523 Height = 15
1524 Top = 16 1524 Top = 16
1525 Width = 71 1525 Width = 41
1526 Caption = 'Routine' 1526 Caption = 'Routine'
1527 ParentColor = False 1527 ParentColor = False
1528 ParentFont = False 1528 ParentFont = False
1529 end 1529 end
1530 object RoutineNumberSpinner: TSpinEdit 1530 object RoutineNumberSpinner: TSpinEdit
1531 Left = 64 1531 Left = 64
1532 Height = 38 1532 Height = 23
1533 Top = 8 1533 Top = 8
1534 Width = 176 1534 Width = 176
1535 MaxValue = 15 1535 MaxValue = 15
@@ -1541,9 +1541,9 @@ object frmTracker: TfrmTracker
1541 end 1541 end
1542 object Label19: TLabel 1542 object Label19: TLabel
1543 Left = 8 1543 Left = 8
1544 Height = 150 1544 Height = 75
1545 Top = 40 1545 Top = 40
1546 Width = 891 1546 Width = 506
1547 Caption = 'Routines are an advanced feature of hUGETracker, and you likely won''t need them at all'#13#10'if you are only interested in composing music. If you want to create a custom effect, or interface'#13#10'with game code that you''re writing a soundtrack for, then routines will come in handy.'#13#10#13#10'Refer to the user manual for more information!' 1547 Caption = 'Routines are an advanced feature of hUGETracker, and you likely won''t need them at all'#13#10'if you are only interested in composing music. If you want to create a custom effect, or interface'#13#10'with game code that you''re writing a soundtrack for, then routines will come in handy.'#13#10#13#10'Refer to the user manual for more information!'
1548 ParentColor = False 1548 ParentColor = False
1549 ParentFont = False 1549 ParentFont = False
Modifiedtracker.pas +40−14
@@ -1469,24 +1469,50 @@ end;
1469 procedure TfrmTracker.MenuItem24Click(Sender: TObject); 1469 procedure TfrmTracker.MenuItem24Click(Sender: TObject);
1470 var 1470 var
1471 Report: TSongUsageReport; 1471 Report: TSongUsageReport;
1472 SL: TStringList;
1473 Iter: Report.UnusedPatterns.TIterator;
1472 begin 1474 begin
1473 Report := GetUsageReport(Song); 1475 Report := GetUsageReport(Song);
1474 1476 SL := TStringList.Create;
1475 case MessageDlg('Usage report', 1477 SL.Delimiter := ',';
1476 Format('%d unused instruments'+LineEnding+ 1478
1477 '%d unused routines'+LineEnding+ 1479 Iter := Report.UnusedPatterns.Iterator;
1478 '%d unused patterns'+LineEnding+LineEnding+ 1480 if Iter <> nil then
1479 'Do you want to remove the unused patterns?', 1481 repeat
1480 [INSTRUMENTS_COUNT - Report.UsedInstruments.Size, 1482 SL.Add(IntToStr(Iter.GetData))
1481 ROUTINES_COUNT - Report.UsedRoutines.size, 1483 until not Iter.Next;
1482 Song.Patterns.Count - Report.UsedPatterns.Size]), 1484
1483 mtInformation, [mbYes, mbNo], 0) of 1485 Iter.Free;
1484 mrYes: begin 1486
1485 // do shit 1487 if SL.Text = '' then
1488 MessageDlg('Usage report',
1489 Format('%d unused instruments'+LineEnding+
1490 '%d unused routines'+LineEnding+
1491 '%d unused patterns'+LineEnding,
1492 [INSTRUMENTS_COUNT - Report.UsedInstruments.Size,
1493 ROUTINES_COUNT - Report.UsedRoutines.size,
1494 Song.Patterns.Count - Report.UsedPatterns.Size]),
1495 mtInformation, [mbOK], 0)
1496 else
1497 if MessageDlg('Usage report',
1498 Format('%d unused instruments'+LineEnding+
1499 '%d unused routines'+LineEnding+
1500 '%d unused patterns'+LineEnding+LineEnding+
1501 'Patterns ' + SL.DelimitedText+' are unused.'+LineEnding+
1502 'Do you want to remove the unused patterns?',
1503 [INSTRUMENTS_COUNT - Report.UsedInstruments.Size,
1504 ROUTINES_COUNT - Report.UsedRoutines.size,
1505 Song.Patterns.Count - Report.UsedPatterns.Size]),
1506 mtInformation, [mbYes, mbNo], 0) = mrYes
1507 then begin
1508 Iter := Report.UnusedPatterns.Iterator;
1509 if Iter <> nil then
1510 repeat
1511 Song.Patterns.DeletePattern(Iter.GetData);
1512 until not Iter.Next;
1486 end; 1513 end;
1487 mrNo: ;
1488 end;
1489 1514
1515 SL.Free;
1490 FreeUsageReport(Report); 1516 FreeUsageReport(Report);
1491 end; 1517 end;
1492 1518
Modifiedutils.pas +38−5
@@ -23,6 +23,8 @@ type
23 function GetOrCreateNew(Key: Integer): PPattern; 23 function GetOrCreateNew(Key: Integer): PPattern;
24 function CreateNewPattern(Key: Integer): PPattern; 24 function CreateNewPattern(Key: Integer): PPattern;
25 function MaxKey: Integer; 25 function MaxKey: Integer;
26
27 procedure DeletePattern(Key: Integer);
26 end; 28 end;
27 29
28 { TSongUsageReport } 30 { TSongUsageReport }
@@ -31,6 +33,10 @@ type
31 UsedInstruments: TUsedMap; 33 UsedInstruments: TUsedMap;
32 UsedRoutines: TUsedMap; 34 UsedRoutines: TUsedMap;
33 UsedPatterns: TUsedMap; 35 UsedPatterns: TUsedMap;
36
37 {UnusedInstruments: TUsedMap;
38 UnusedRoutines: TUsedMap;}
39 UnusedPatterns: TUsedMap;
34 end; 40 end;
35 41
36 function Lerp(v0, v1, t: Double): Double; 42 function Lerp(v0, v1, t: Double): Double;
@@ -49,7 +55,7 @@ implementation
49 55
50 class function TIntegerHash.hash(I: Integer; N: Integer): Integer; 56 class function TIntegerHash.hash(I: Integer; N: Integer): Integer;
51 begin 57 begin
52 Result := I; 58 Result := I mod N;
53 end; 59 end;
54 60
55 { TOrderMapHelper } 61 { TOrderMapHelper }
@@ -84,6 +90,12 @@ begin
84 Inc(Result); 90 Inc(Result);
85 end; 91 end;
86 92
93 procedure TOrderMapHelper.DeletePattern(Key: Integer);
94 begin
95 Dispose(KeyData[Key]);
96 Self.Remove(Key);
97 end;
98
87 function Lerp(v0, v1, t: Double): Double; 99 function Lerp(v0, v1, t: Double): Double;
88 begin 100 begin
89 Result := ((1 - t) * v0) + (t * v1); 101 Result := ((1 - t) * v0) + (t * v1);
@@ -152,12 +164,13 @@ begin
152 Result.UsedPatterns := TUsedMap.Create; 164 Result.UsedPatterns := TUsedMap.Create;
153 Result.UsedInstruments := TUsedMap.Create; 165 Result.UsedInstruments := TUsedMap.Create;
154 Result.UsedRoutines := TUsedMap.Create; 166 Result.UsedRoutines := TUsedMap.Create;
167 Result.UnusedPatterns := TUsedMap.Create;
168 {Result.UnusedInstruments := TUsedMap.Create;
169 Result.UnusedRoutines := TUsedMap.Create;}
155 170
156 for X := Low(Song.OrderMatrix) to High(Song.OrderMatrix) do 171 for X := Low(Song.OrderMatrix) to High(Song.OrderMatrix) do
157 for Y := Low(Song.OrderMatrix[X]) to High(Song.OrderMatrix[X]) do begin 172 for Y := Low(Song.OrderMatrix[X]) to High(Song.OrderMatrix[X]) do
158 Writeln(X, ' ', Y, ' ', Song.OrderMatrix[X, Y]);
159 Result.UsedPatterns.insert(Song.OrderMatrix[X, Y]); 173 Result.UsedPatterns.insert(Song.OrderMatrix[X, Y]);
160 end;
161 174
162 for I := 0 to Song.Patterns.Count-1 do begin 175 for I := 0 to Song.Patterns.Count-1 do begin
163 if not Result.UsedPatterns.contains(Song.Patterns.Keys[I]) 176 if not Result.UsedPatterns.contains(Song.Patterns.Keys[I])
@@ -167,11 +180,27 @@ begin
167 180
168 for J := Low(Pat^) to High(Pat^) do 181 for J := Low(Pat^) to High(Pat^) do
169 with Pat^[J] do begin 182 with Pat^[J] do begin
170 Result.UsedInstruments.insert(Instrument); 183 if Instrument <> 0 then Result.UsedInstruments.insert(Instrument);
171 if EffectCode = $6 then // Call routine 184 if EffectCode = $6 then // Call routine
172 Result.UsedRoutines.insert(EffectParams.Value); 185 Result.UsedRoutines.insert(EffectParams.Value);
173 end; 186 end;
174 end; 187 end;
188
189 for X := 0 to Song.Patterns.Count-1 do
190 if not Result.UsedPatterns.contains(Song.Patterns.Keys[X]) then
191 Result.UnusedPatterns.insert(Song.Patterns.Keys[X]);
192
193 {for I := Low(TInstrumentIndex) to High(TInstrumentIndex) do
194 Result.UnusedInstruments.insert(I);
195
196 for I in Result.UsedInstruments.Iterator do
197 Result.UnusedInstruments.delete(I);
198
199 for I := Low(TRoutineIndex) do High(TRoutineIndex) do
200 Result.UnusedRoutines.insert(I);
201
202 for I in Result.UsedRoutines do
203 Result.UnusedRoutines.delete(I);}
175 end; 204 end;
176 205
177 procedure FreeUsageReport(Report: TSongUsageReport); 206 procedure FreeUsageReport(Report: TSongUsageReport);
@@ -179,6 +208,10 @@ begin
179 Report.UsedPatterns.Free; 208 Report.UsedPatterns.Free;
180 Report.UsedInstruments.Free; 209 Report.UsedInstruments.Free;
181 Report.UsedRoutines.Free; 210 Report.UsedRoutines.Free;
211
212 Report.UnusedPatterns.Free;
213 //Report.UnusedInstruments.Free;
214 //Report.UnusedRoutines.Free;
182 end; 215 end;
183 216
184 end. 217 end.