Commit e4dc2b8

Adrian Siekierka committed on
codegen: Trim unused instruments and waves when exporting song data.
commit e4dc2b8e728251c306bc105a12099217b9055a1a parent 3a48fed
2 changed files +91−37
Modifiedsrc/codegen.pas +46−37
@@ -156,7 +156,7 @@ procedure RenderSongToGBDKC(Song: TSong; DescriptorName: String; Filename: strin
156 Result := '{'+SL.DelimitedText+'}'; 156 Result := '{'+SL.DelimitedText+'}';
157 end; 157 end;
158 158
159 function RenderGBDKInstrumentBank(Name: string; Bank: TInstrumentBank): string; 159 function RenderGBDKInstrumentBank(Name: string; Bank: TInstrumentBank; Limit: Integer): string;
160 var 160 var
161 I: integer; 161 I: integer;
162 InstrType: String; 162 InstrType: String;
@@ -167,18 +167,18 @@ procedure RenderSongToGBDKC(Song: TSong; DescriptorName: String; Filename: strin
167 itNoise: InstrType := 'hUGENoiseInstr_t'; 167 itNoise: InstrType := 'hUGENoiseInstr_t';
168 end; 168 end;
169 Result := 'static const ' + InstrType + ' ' + Name + '[] = {'+LineEnding; 169 Result := 'static const ' + InstrType + ' ' + Name + '[] = {'+LineEnding;
170 for I := Low(Bank) to High(Bank) do begin 170 for I := Low(Bank) to Limit do begin
171 Result += ' '+RenderGBDKInstrument(Bank[I], I) + ','+LineEnding; 171 Result += ' '+RenderGBDKInstrument(Bank[I], I) + ','+LineEnding;
172 end; 172 end;
173 Result += '};'; 173 Result += '};';
174 end; 174 end;
175 175
176 function RenderGBDKWaves(Waves: TWaveBank): string; 176 function RenderGBDKWaves(Waves: TWaveBank; Limit: Integer): string;
177 var 177 var
178 I, J: integer; 178 I, J: integer;
179 begin 179 begin
180 Result := 'static const unsigned char waves[] = {'+LineEnding; 180 Result := 'static const unsigned char waves[] = {'+LineEnding;
181 for I := Low(Waves) to High(Waves) do 181 for I := Low(Waves) to Limit do
182 begin 182 begin
183 Result += ' '; 183 Result += ' ';
184 J := Low(Waves[I]); 184 J := Low(Waves[I]);
@@ -197,10 +197,12 @@ var
197 OutSL: TStringList; 197 OutSL: TStringList;
198 OrderCnt: integer; 198 OrderCnt: integer;
199 I: integer; 199 I: integer;
200 MaxInstrIdx: integer;
200 F: Text; 201 F: Text;
201 TypePrefix: String; 202 TypePrefix: String;
202 begin 203 begin
203 Song := OptimizeSong(Song); 204 Song := OptimizeSong(Song);
205 MaxInstrIdx := MaxInstrumentIndex(Song);
204 206
205 OutSL := TStringList.Create; 207 OutSL := TStringList.Create;
206 208
@@ -227,12 +229,13 @@ begin
227 OutSL.Add(''); 229 OutSL.Add('');
228 230
229 for I := Low(Song.Instruments.All) to High(Song.Instruments.All) do 231 for I := Low(Song.Instruments.All) to High(Song.Instruments.All) do
230 with Song.Instruments.All[I] do begin 232 if InstrumentIsUsed(I, Song) then
231 if SubpatternEnabled then begin 233 with Song.Instruments.All[I] do begin
232 WriteStr(TypePrefix, Type_); 234 if SubpatternEnabled then begin
233 OutSL.Add(RenderGBDKSubpattern(TypePrefix+'SP' + IntToStr(ModInst(I)), Subpattern)); 235 WriteStr(TypePrefix, Type_);
236 OutSL.Add(RenderGBDKSubpattern(TypePrefix+'SP' + IntToStr(ModInst(I)), Subpattern));
237 end;
234 end; 238 end;
235 end;
236 239
237 OutSL.Add(RenderGBDKOrder(1, Song.OrderMatrix[0])); 240 OutSL.Add(RenderGBDKOrder(1, Song.OrderMatrix[0]));
238 OutSL.Add(RenderGBDKOrder(2, Song.OrderMatrix[1])); 241 OutSL.Add(RenderGBDKOrder(2, Song.OrderMatrix[1]));
@@ -240,12 +243,12 @@ begin
240 OutSL.Add(RenderGBDKOrder(4, Song.OrderMatrix[3])); 243 OutSL.Add(RenderGBDKOrder(4, Song.OrderMatrix[3]));
241 OutSL.Add(''); 244 OutSL.Add('');
242 245
243 OutSL.Add(RenderGBDKInstrumentBank('duty_instruments', Song.Instruments.Duty)); 246 OutSL.Add(RenderGBDKInstrumentBank('duty_instruments', Song.Instruments.Duty, MaxInstrIdx));
244 OutSL.Add(RenderGBDKInstrumentBank('wave_instruments', Song.Instruments.Wave)); 247 OutSL.Add(RenderGBDKInstrumentBank('wave_instruments', Song.Instruments.Wave, MaxInstrIdx));
245 OutSL.Add(RenderGBDKInstrumentBank('noise_instruments', Song.Instruments.Noise)); 248 OutSL.Add(RenderGBDKInstrumentBank('noise_instruments', Song.Instruments.Noise, MaxInstrIdx));
246 OutSL.Add(''); 249 OutSL.Add('');
247 250
248 OutSL.Add(RenderGBDKWaves(Song.Waves)); 251 OutSL.Add(RenderGBDKWaves(Song.Waves, MaxWaveIndex(Song)));
249 OutSL.Add(''); 252 OutSL.Add('');
250 253
251 if Bank <> -1 then 254 if Bank <> -1 then
@@ -297,7 +300,7 @@ begin
297 Res.Free; 300 Res.Free;
298 end; 301 end;
299 302
300 function RenderInstruments(Instruments: TInstrumentBank): string; 303 function RenderInstruments(Instruments: TInstrumentBank; Limit: Integer): string;
301 var 304 var
302 ResultSL: TStringList; 305 ResultSL: TStringList;
303 AsmInstrument: TAsmInstrument; 306 AsmInstrument: TAsmInstrument;
@@ -307,7 +310,7 @@ var
307 begin 310 begin
308 ResultSL := TStringList.Create; 311 ResultSL := TStringList.Create;
309 312
310 for I := Low(Instruments) to High(Instruments) do 313 for I := Low(Instruments) to Limit do
311 begin 314 begin
312 WriteStr(TypePrefix, Instruments[I].Type_); 315 WriteStr(TypePrefix, Instruments[I].Type_);
313 ResultSL.Add(Format('%s%s:', [TypePrefix, 'inst' + IntToStr(I)])); 316 ResultSL.Add(Format('%s%s:', [TypePrefix, 'inst' + IntToStr(I)]));
@@ -425,14 +428,14 @@ begin
425 SL.Free; 428 SL.Free;
426 end; 429 end;
427 430
428 function RenderWaveforms(Waves: TWaveBank): string; 431 function RenderWaveforms(Waves: TWaveBank; Limit: Integer): string;
429 var 432 var
430 SL, ResultSL: TStringList; 433 SL, ResultSL: TStringList;
431 I, J: integer; 434 I, J: integer;
432 begin 435 begin
433 ResultSL := TStringList.Create; 436 ResultSL := TStringList.Create;
434 437
435 for I := Low(Waves) to High(Waves) do 438 for I := Low(Waves) to Limit do
436 begin 439 begin
437 SL := TStringList.Create; 440 SL := TStringList.Create;
438 SL.StrictDelimiter := True; 441 SL.StrictDelimiter := True;
@@ -457,9 +460,11 @@ var
457 OutSL: TStringList; 460 OutSL: TStringList;
458 F: Text; 461 F: Text;
459 I: Integer; 462 I: Integer;
463 MaxInstrIdx: Integer;
460 TypePrefix: String; 464 TypePrefix: String;
461 begin 465 begin
462 Song := OptimizeSong(Song); 466 Song := OptimizeSong(Song);
467 MaxInstrIdx := MaxInstrumentIndex(Song);
463 468
464 OutSL := TStringList.Create; 469 OutSL := TStringList.Create;
465 470
@@ -487,25 +492,26 @@ begin
487 OutSL.Add(RenderPattern('P' + IntToStr(Song.Patterns.Keys[I]), Song.Patterns.Data[I]^)); 492 OutSL.Add(RenderPattern('P' + IntToStr(Song.Patterns.Keys[I]), Song.Patterns.Data[I]^));
488 493
489 // Render subpatterns 494 // Render subpatterns
490 for I := Low(Song.Instruments.All) to High(Song.Instruments.All) do 495 for I := Low(Song.Instruments.All) to High(Song.Instruments.All) do
491 with Song.Instruments.All[I] do begin 496 if InstrumentIsUsed(I, Song) then
492 if SubpatternEnabled then begin 497 with Song.Instruments.All[I] do begin
493 WriteStr(TypePrefix, Type_); 498 if SubpatternEnabled then begin
494 OutSL.Add(RenderSubpattern(TypePrefix+'SP' + IntToStr(ModInst(I)), Subpattern)); 499 WriteStr(TypePrefix, Type_);
500 OutSL.Add(RenderSubpattern(TypePrefix+'SP' + IntToStr(ModInst(I)), Subpattern));
501 end;
495 end; 502 end;
496 end;
497 503
498 // Render instruments 504 // Render instruments
499 OutSL.Add('duty_instruments:'); 505 OutSL.Add('duty_instruments:');
500 OutSL.Add(RenderInstruments(Song.Instruments.Duty)); 506 OutSL.Add(RenderInstruments(Song.Instruments.Duty, MaxInstrIdx));
501 OutSL.Add(''); 507 OutSL.Add('');
502 508
503 OutSL.Add('wave_instruments:'); 509 OutSL.Add('wave_instruments:');
504 OutSL.Add(RenderInstruments(Song.Instruments.Wave)); 510 OutSL.Add(RenderInstruments(Song.Instruments.Wave, MaxInstrIdx));
505 OutSL.Add(''); 511 OutSL.Add('');
506 512
507 OutSL.Add('noise_instruments:'); 513 OutSL.Add('noise_instruments:');
508 OutSL.Add(RenderInstruments(Song.Instruments.Noise)); 514 OutSL.Add(RenderInstruments(Song.Instruments.Noise, MaxInstrIdx));
509 OutSL.Add(''); 515 OutSL.Add('');
510 516
511 // Render routines 517 // Render routines
@@ -520,7 +526,7 @@ begin
520 526
521 // Render waves 527 // Render waves
522 OutSL.Add('waves:'); 528 OutSL.Add('waves:');
523 OutSL.Add(RenderWaveforms(Song.Waves)); 529 OutSL.Add(RenderWaveforms(Song.Waves, MaxWaveIndex(Song)));
524 530
525 AssignFile(F, Filename); 531 AssignFile(F, Filename);
526 Rewrite(F); 532 Rewrite(F);
@@ -554,6 +560,7 @@ procedure AssembleSong(Song: TSong; Filename: string; Mode: TExportMode);
554 var 560 var
555 OutFile: Text; 561 OutFile: Text;
556 I: integer; 562 I: integer;
563 MaxInstrIdx: integer;
557 TypePrefix: String; 564 TypePrefix: String;
558 Proc: TProcess; 565 Proc: TProcess;
559 FilePath: string; 566 FilePath: string;
@@ -631,6 +638,7 @@ var
631 end; 638 end;
632 begin 639 begin
633 Song := OptimizeSong(Song); 640 Song := OptimizeSong(Song);
641 MaxInstrIdx := MaxInstrumentIndex(Song);
634 642
635 if not DirectoryExists(ConcatPaths([CacheDir, 'render'])) then 643 if not DirectoryExists(ConcatPaths([CacheDir, 'render'])) then
636 CreateDir(ConcatPaths([CacheDir, 'render'])); 644 CreateDir(ConcatPaths([CacheDir, 'render']));
@@ -638,11 +646,11 @@ begin
638 FilePath := Filename; 646 FilePath := Filename;
639 Filename := ConcatPaths([CacheDir, 'render', ExtractFileNameWithoutExt(ExtractFileNameOnly(Filename))]); 647 Filename := ConcatPaths([CacheDir, 'render', ExtractFileNameWithoutExt(ExtractFileNameOnly(Filename))]);
640 648
641 WriteHTT(ConcatPaths([CacheDir, 'render', 'wave.htt']), RenderWaveforms(Song.Waves)); 649 WriteHTT(ConcatPaths([CacheDir, 'render', 'wave.htt']), RenderWaveforms(Song.Waves, MaxWaveIndex(Song)));
642 WriteHTT(ConcatPaths([CacheDir, 'render', 'order.htt']), RenderOrderTable(Song.OrderMatrix)); 650 WriteHTT(ConcatPaths([CacheDir, 'render', 'order.htt']), RenderOrderTable(Song.OrderMatrix));
643 WriteHTT(ConcatPaths([CacheDir, 'render', 'duty_instrument.htt']), RenderInstruments(Song.Instruments.Duty)); 651 WriteHTT(ConcatPaths([CacheDir, 'render', 'duty_instrument.htt']), RenderInstruments(Song.Instruments.Duty, MaxInstrIdx));
644 WriteHTT(ConcatPaths([CacheDir, 'render', 'wave_instrument.htt']), RenderInstruments(Song.Instruments.Wave)); 652 WriteHTT(ConcatPaths([CacheDir, 'render', 'wave_instrument.htt']), RenderInstruments(Song.Instruments.Wave, MaxInstrIdx));
645 WriteHTT(ConcatPaths([CacheDir, 'render', 'noise_instrument.htt']), RenderInstruments(Song.Instruments.Noise)); 653 WriteHTT(ConcatPaths([CacheDir, 'render', 'noise_instrument.htt']), RenderInstruments(Song.Instruments.Noise, MaxInstrIdx));
646 for I := Low(TRoutineBank) to High(TRoutineBank) do 654 for I := Low(TRoutineBank) to High(TRoutineBank) do
647 WriteHTT(ConcatPaths([CacheDir, 'render', 'routine'+IntToStr(I)+'.htt']), Song.Routines[I]); 655 WriteHTT(ConcatPaths([CacheDir, 'render', 'routine'+IntToStr(I)+'.htt']), Song.Routines[I]);
648 656
@@ -659,13 +667,14 @@ begin
659 AssignFile(OutFile, ConcatPaths([CacheDir, 'render', 'subpattern.htt'])); 667 AssignFile(OutFile, ConcatPaths([CacheDir, 'render', 'subpattern.htt']));
660 Rewrite(OutFile); 668 Rewrite(OutFile);
661 669
662 for I := Low(Song.Instruments.All) to High(Song.Instruments.All) do 670 for I := Low(Song.Instruments.All) to High(Song.Instruments.All) do
663 with Song.Instruments.All[I] do begin 671 if InstrumentIsUsed(I, Song) then
664 if SubpatternEnabled then begin 672 with Song.Instruments.All[I] do begin
665 WriteStr(TypePrefix, Type_); 673 if SubpatternEnabled then begin
666 Write(OutFile, RenderSubpattern(TypePrefix+'SP' + IntToStr(ModInst(I)), Subpattern)); 674 WriteStr(TypePrefix, Type_);
675 Write(OutFile, RenderSubpattern(TypePrefix+'SP' + IntToStr(ModInst(I)), Subpattern));
676 end;
667 end; 677 end;
668 end;
669 678
670 CloseFile(OutFile); 679 CloseFile(OutFile);
671 680
Modifiedsrc/song.pas +45−0
@@ -123,6 +123,10 @@ function UpgradeSong(S: TSongV4): TSong; overload;
123 123
124 function OptimizeSong(const S: TSong): TSong; 124 function OptimizeSong(const S: TSong): TSong;
125 function PatternIsUsed(Idx: Integer; const Song: TSong): Boolean; 125 function PatternIsUsed(Idx: Integer; const Song: TSong): Boolean;
126 function MaxInstrumentIndex(const Song: TSong): Integer;
127 function InstrumentIsUsed(Idx: Integer; const Song: TSong): Boolean;
128 function MaxWaveIndex(const Song: TSong): Integer;
129 function WaveIsUsed(Idx: Integer; const Song: TSong): Boolean;
126 130
127 implementation 131 implementation
128 132
@@ -852,5 +856,46 @@ begin
852 Result := False; 856 Result := False;
853 end; 857 end;
854 858
859 function MaxInstrumentIndex(const Song: TSong): Integer;
860 var
861 I, J, K: Integer;
862 begin
863 K := -1;
864
865 for I := 0 to Song.Patterns.Count - 1 do
866 if PatternIsUsed(Song.Patterns.Keys[I], Song) then
867 for J := Low(Song.Patterns.Data[I]^) to High(Song.Patterns.Data[I]^) do
868 if K < Song.Patterns.Data[I]^[J].Instrument then
869 K := Song.Patterns.Data[I]^[J].Instrument;
870
871 Result := K;
872 end;
873
874 function InstrumentIsUsed(Idx: Integer; const Song: TSong): Boolean;
875 begin
876 if Idx > 15 then
877 Idx := ((Idx - 1) mod 15) + 1;
878 Result := Idx <= MaxInstrumentIndex(Song);
879 end;
880
881 function MaxWaveIndex(const Song: TSong): Integer;
882 var
883 I, K, MaxInstrIdx: Integer;
884 begin
885 K := -1;
886 MaxInstrIdx := MaxInstrumentIndex(Song);
887
888 for I := Low(Song.Instruments.Wave) to MaxInstrIdx do
889 if K < Song.Instruments.Wave[I].Waveform then
890 K := Song.Instruments.Wave[I].Waveform;
891
892 Result := K;
893 end;
894
895 function WaveIsUsed(Idx: Integer; const Song: TSong): Boolean;
896 begin
897 Result := Idx <= MaxWaveIndex(Song);
898 end;
899
855 end. 900 end.
856 901