Commit 3b4a8af

Nick committed on
Implement proper loading of v3 modules- ugly!
commit 3b4a8afbe5fc36ddd4d37c6514cd3b959a20aa90 parent 59a8042
6 changed files +210−30
ModifiedhUGEDriver +1−1
@@ -1 +1 @@
1 Subproject commit 0f3e04839b0970add9a5008e5a48ec034773b348 1 Subproject commit c29e7ab779f986d6bb944cd8ff4208eac9dc5594
Modifiedhugedatatypes.pas +14−4
@@ -12,13 +12,23 @@ type
12 12
13 TRoutine = string; 13 TRoutine = string;
14 14
15 TInstrumentBank = packed array[1..15] of TInstrument; 15 TInstrumentBankV1 = packed array[1..15] of TInstrumentV1;
16 TInstrumentCollection = packed record 16 TInstrumentCollectionV1 = packed record
17 case Boolean of 17 case Boolean of
18 False: (Duty, Wave, Noise: TInstrumentBank); 18 False: (Duty, Wave, Noise: TInstrumentBankV1);
19 True: (All: packed array[1..45] of TInstrument); 19 True: (All: packed array[1..45] of TInstrumentV1);
20 end; 20 end;
21 21
22 TInstrumentBankV2 = packed array[1..15] of TInstrumentV2;
23 TInstrumentCollectionV2 = packed record
24 case Boolean of
25 False: (Duty, Wave, Noise: TInstrumentBankV2);
26 True: (All: packed array[1..45] of TInstrumentV2);
27 end;
28
29 TInstrumentBank = TInstrumentBankV2;
30 TInstrumentCollection = TInstrumentCollectionV2;
31
22 TWaveBankV1 = packed array[0..15] of TWaveV1; 32 TWaveBankV1 = packed array[0..15] of TWaveV1;
23 TWaveBankV2 = packed array[0..15] of TWaveV2; 33 TWaveBankV2 = packed array[0..15] of TWaveV2;
24 TWaveBank = TWaveBankV2; 34 TWaveBank = TWaveBankV2;
Modifiedinstruments.pas +43−4
@@ -16,7 +16,42 @@ type
16 TEnvelopeSweepAmount = 0..7; 16 TEnvelopeSweepAmount = 0..7;
17 TNoiseMacro = array[0..5] of -31..32; 17 TNoiseMacro = array[0..5] of -31..32;
18 18
19 TInstrument = packed record 19 TInstrumentV1 = packed record
20 Type_: TInstrumentType;
21
22 Name: ShortString;
23 Length: Integer;
24 // Highmask
25 LengthEnabled: Boolean;
26
27 InitialVolume: TEnvelopeVolume;
28 VolSweepDirection: TSweepType;
29 VolSweepAmount: TEnvelopeSweepAmount;
30
31 // itSquare
32 // NR10
33 SweepTime: Integer;
34 SweepIncDec: TSweepType;
35 SweepShift: Integer;
36
37 // NR11
38 Duty: TDutyType;
39
40 // itWave
41
42 // NR32
43 OutputLevel: Integer;
44 // itWave
45 Waveform: Integer;
46
47 // itNoise
48 // NR42
49 ShiftClockFreq: Integer; // Unused
50 CounterStep: TStepWidth;
51 DividingRatio: Integer;
52 end;
53
54 TInstrumentV2 = packed record
20 Type_: TInstrumentType; 55 Type_: TInstrumentType;
21 56
22 Name: ShortString; 57 Name: ShortString;
@@ -52,6 +87,8 @@ type
52 NoiseMacro: TNoiseMacro; 87 NoiseMacro: TNoiseMacro;
53 end; 88 end;
54 89
90 TInstrument = TInstrumentV2;
91
55 TAsmInstrument = array[0..3] of Byte; 92 TAsmInstrument = array[0..3] of Byte;
56 93
57 TRegisters = record 94 TRegisters = record
@@ -210,7 +247,8 @@ begin
210 // Because *InstrumentToRegisters is meant for previewing, it puts in 247 // Because *InstrumentToRegisters is meant for previewing, it puts in
211 // a value for shift clock freq, so we have to remove it and put in the mask 248 // a value for shift clock freq, so we have to remove it and put in the mask
212 // instead. 249 // instead.
213 Poly.ShiftClockFrequency := Instrument.ShiftClockFreq; 250 // TODO: Come back here
251 //Poly.ShiftClockFrequency := Instrument.ShiftClockFreq;
214 Result[3] := Regs.NR44; 252 Result[3] := Regs.NR44;
215 end; 253 end;
216 254
@@ -283,8 +321,9 @@ begin
283 321
284 NR43.ShiftClockFrequency := $F - (Frequency shr 7); // Quantize CH4 note 322 NR43.ShiftClockFrequency := $F - (Frequency shr 7); // Quantize CH4 note
285 323
286 NR43.DividingRatio:= Instr.DividingRatio; 324 // TODO: Come back here
287 NR43.SevenBitCounter:=Instr.CounterStep = swSeven; 325 //NR43.DividingRatio:= Instr.DividingRatio;
326 //NR43.SevenBitCounter:=Instr.CounterStep = swSeven;
288 327
289 NR44.Initial:= Initial; 328 NR44.Initial:= Initial;
290 NR44.UseLength:=Instr.LengthEnabled; 329 NR44.UseLength:=Instr.LengthEnabled;
Modifiedsong.pas +150−20
@@ -17,7 +17,7 @@ type
17 Artist: ShortString; 17 Artist: ShortString;
18 Comment: ShortString; 18 Comment: ShortString;
19 19
20 Instruments: TInstrumentBank; 20 Instruments: TInstrumentBankV1;
21 Waves: TWaveBankV1; 21 Waves: TWaveBankV1;
22 22
23 TicksPerRow: Integer; 23 TicksPerRow: Integer;
@@ -33,7 +33,7 @@ type
33 Artist: ShortString; 33 Artist: ShortString;
34 Comment: ShortString; 34 Comment: ShortString;
35 35
36 Instruments: TInstrumentBank; 36 Instruments: TInstrumentBankV1;
37 Waves: TWaveBankV1; 37 Waves: TWaveBankV1;
38 38
39 TicksPerRow: Integer; 39 TicksPerRow: Integer;
@@ -51,9 +51,26 @@ type
51 Artist: ShortString; 51 Artist: ShortString;
52 Comment: ShortString; 52 Comment: ShortString;
53 53
54 Instruments: TInstrumentCollection; 54 Instruments: TInstrumentCollectionV1;
55 Waves: TWaveBankV2;
55 56
56 Waves: TWaveBank; 57 TicksPerRow: Integer;
58
59 Patterns: TPatternMap;
60 OrderMatrix: TOrderMatrix;
61
62 Routines: TRoutineBank;
63 end;
64
65 TSongV4 = packed record
66 Version: Integer;
67
68 Name: ShortString;
69 Artist: ShortString;
70 Comment: ShortString;
71
72 Instruments: TInstrumentCollectionV2;
73 Waves: TWaveBankV2;
57 74
58 TicksPerRow: Integer; 75 TicksPerRow: Integer;
59 76
@@ -65,7 +82,7 @@ type
65 82
66 { TSong } 83 { TSong }
67 84
68 TSong = TSongV3; 85 TSong = TSongV4;
69 86
70 procedure WriteSongToStream(S: TStream; const ASong: TSong); 87 procedure WriteSongToStream(S: TStream; const ASong: TSong);
71 procedure ReadSongFromStream(S: TStream; out ASong: TSong); 88 procedure ReadSongFromStream(S: TStream; out ASong: TSong);
@@ -76,6 +93,7 @@ procedure DestroySong(var S: TSong);
76 function UpgradeSong(S: TSongV1): TSong; overload; 93 function UpgradeSong(S: TSongV1): TSong; overload;
77 function UpgradeSong(S: TSongV2): TSong; overload; 94 function UpgradeSong(S: TSongV2): TSong; overload;
78 function UpgradeSong(S: TSongV3): TSong; overload; 95 function UpgradeSong(S: TSongV3): TSong; overload;
96 function UpgradeSong(S: TSongV4): TSong; overload;
79 97
80 implementation 98 implementation
81 99
@@ -198,13 +216,54 @@ begin
198 ASong.Routines[I] := S.ReadAnsiString; 216 ASong.Routines[I] := S.ReadAnsiString;
199 end; 217 end;
200 218
219 procedure ReadSongFromStreamV4(S: TStream; out ASong: TSongV4);
220 var
221 i, n: Integer;
222 pat: PPattern;
223 begin
224 // Read the fixed elements first
225 n := SizeOf(TSongV4)
226 - SizeOf(TPatternMap)
227 - SizeOf(TOrderMatrix)
228 - SizeOf(TRoutineBank);
229
230 S.Read(ASong, n);
231
232 // Create the patterns
233 ASong.Patterns := TPatternMap.Create;
234 // Read the pattern count
235 S.Read(n, SizeOf(Integer));
236 for i:=0 to n - 1 do begin
237 // Allocate memory for each pattern ...
238 New(pat);
239 // and read the pattern content
240 S.Read(pat^, SizeOf(TPattern));
241 // Add the pattern to the list
242 ASong.Patterns.Add(i, pat);
243 end;
244
245 // Read the OrderMatrix
246 for i := 0 to 3 do
247 begin
248 // Read length of each OrderMatrix array
249 S.Read(n, SizeOf(Integer));
250 // Allocate memory for it
251 SetLength(ASong.OrderMatrix[i], n);
252 // Read content of OrderMatrix array
253 S.Read(ASong.OrderMatrix[i, 0], n*SizeOf(Integer));
254 end;
255
256 for I := Low(TRoutineBank) to High(TRoutineBank) do
257 ASong.Routines[I] := S.ReadAnsiString;
258 end;
259
201 procedure WriteSongToStream(S: TStream; const ASong: TSong); 260 procedure WriteSongToStream(S: TStream; const ASong: TSong);
202 var 261 var
203 i, n: Integer; 262 i, n: Integer;
204 pPat: PPattern; 263 pPat: PPattern;
205 begin 264 begin
206 // Write the fixed record elements first 265 // Write the fixed record elements first
207 n := SizeOf(TSongV3) 266 n := SizeOf(TSongV4)
208 - SizeOf(TPatternMap) 267 - SizeOf(TPatternMap)
209 - SizeOf(TOrderMatrix) 268 - SizeOf(TOrderMatrix)
210 - SizeOf(TRoutineBank); 269 - SizeOf(TRoutineBank);
@@ -237,6 +296,7 @@ var
237 Version: Integer; 296 Version: Integer;
238 SV1: TSongV1; 297 SV1: TSongV1;
239 SV2: TSongV2; 298 SV2: TSongV2;
299 SV3: TSongV3;
240 begin 300 begin
241 S.Read(Version, SizeOf(Integer)); 301 S.Read(Version, SizeOf(Integer));
242 S.Seek(0, soBeginning); 302 S.Seek(0, soBeginning);
@@ -249,7 +309,11 @@ begin
249 ReadSongFromStreamV2(S, SV2); 309 ReadSongFromStreamV2(S, SV2);
250 ASong := UpgradeSong(SV2); 310 ASong := UpgradeSong(SV2);
251 end; 311 end;
252 3: ReadSongFromStreamV3(S, ASong); 312 3: begin
313 ReadSongFromStreamV3(S, SV3);
314 ASong := UpgradeSong(SV3);
315 end;
316 4: ReadSongFromStreamV4(S, ASong);
253 end; 317 end;
254 end; 318 end;
255 319
@@ -303,10 +367,11 @@ begin
303 InitialVolume := High(TEnvelopeVolume); 367 InitialVolume := High(TEnvelopeVolume);
304 VolSweepDirection := Down; 368 VolSweepDirection := Down;
305 VolSweepAmount := 0; 369 VolSweepAmount := 0;
306 370 NoiseMacro := Default(TNoiseMacro);
307 ShiftClockFreq := 0; 371 // TODO: Come back here
308 DividingRatio := 0; 372 //ShiftClockFreq := 0;
309 CounterStep := swFifteen; 373 //DividingRatio := 0;
374 //CounterStep := swFifteen;
310 end; 375 end;
311 376
312 for I := Low(S.Waves) to High(S.Waves) do begin 377 for I := Low(S.Waves) to High(S.Waves) do begin
@@ -402,13 +467,59 @@ var
402 SV3: TSongV3; 467 SV3: TSongV3;
403 I: Integer; 468 I: Integer;
404 begin 469 begin
405 InitializeSong(SV3);
406 SV3.Patterns.Free; // We already have one in S, so free the one InitializeSong creates.
407
408 SV3.Version:=3; 470 SV3.Version:=3;
409 SV3.Name:=S.Name; 471 SV3.Name:=S.Name;
410 SV3.Artist:=S.Artist; 472 SV3.Artist:=S.Artist;
411 SV3.Comment:=S.Comment; 473 SV3.Comment:=S.Comment;
474 SV3.TicksPerRow:=S.TicksPerRow;
475 SV3.Patterns:=S.Patterns;
476 SV3.OrderMatrix:=S.OrderMatrix;
477 SV3.Routines:=S.Routines;
478
479 // AWFUL!!!!
480 for I := Low(SV3.Instruments.All) to High(SV3.Instruments.All) do
481 SV3.Instruments.All[I] := Default(TInstrumentV1);
482
483 for I := Low(SV3.Instruments.Duty) to High(SV3.Instruments.Duty) do begin
484 with SV3.Instruments.Duty[I] do begin
485 Type_ := itSquare;
486 Length := 0;
487 LengthEnabled := False;
488 InitialVolume := High(TEnvelopeVolume);
489 VolSweepDirection := Down;
490 VolSweepAmount := 0;
491
492 SweepTime := 0;
493 SweepIncDec := Down;
494 SweepShift := 0;
495
496 Duty := 2;
497
498 OutputLevel := 1;
499 end;
500 end;
501
502 for I := Low(SV3.Instruments.Wave) to High(SV3.Instruments.Wave) do
503 with SV3.Instruments.Wave[I] do begin
504 Type_ := itWave;
505 Length := 0;
506 LengthEnabled := False;
507 OutputLevel := 1;
508 Waveform := I-1;
509 end;
510
511 for I := Low(SV3.Instruments.Noise) to High(SV3.Instruments.Noise) do
512 with SV3.Instruments.Noise[I] do begin
513 Type_ := itNoise;
514 Length := 0;
515 LengthEnabled := False;
516 InitialVolume := High(TEnvelopeVolume);
517 VolSweepDirection := Down;
518 VolSweepAmount := 0;
519 ShiftClockFreq := 0;
520 DividingRatio := 0;
521 CounterStep := swFifteen;
522 end;
412 523
413 for I := Low(S.Instruments) to High(S.Instruments) do begin 524 for I := Low(S.Instruments) to High(S.Instruments) do begin
414 case S.Instruments[I].Type_ of 525 case S.Instruments[I].Type_ of
@@ -419,17 +530,36 @@ begin
419 end; 530 end;
420 531
421 for I := Low(TWaveBank) to High(TWaveBank) do 532 for I := Low(TWaveBank) to High(TWaveBank) do
422 Move(S.Waves[I], SV3.Waves[I], SizeOf(TWave)); 533 Move(S.Waves[I], SV3.Waves[I], SizeOf(TWaveV2));
423
424 SV3.TicksPerRow:=S.TicksPerRow;
425 SV3.Patterns:=S.Patterns;
426 SV3.OrderMatrix:=S.OrderMatrix;
427 SV3.Routines:=S.Routines;
428 534
429 Result := UpgradeSong(SV3); 535 Result := UpgradeSong(SV3);
430 end; 536 end;
431 537
432 function UpgradeSong(S: TSongV3): TSong; 538 function UpgradeSong(S: TSongV3): TSong;
539 var
540 SV4: TSongV4;
541 I: Integer;
542 begin
543 SV4.Version:=4;
544 SV4.Name:=S.Name;
545 SV4.Artist:=S.Artist;
546 SV4.Comment:=S.Comment;
547 SV4.TicksPerRow:=S.TicksPerRow;
548 SV4.Patterns:=S.Patterns;
549 SV4.OrderMatrix:=S.OrderMatrix;
550 SV4.Routines:=S.Routines;
551 SV4.Waves := S.Waves;
552
553 // for now just generate a blank noise macro
554 for I := Low(S.Instruments.All) to High(S.Instruments.All) do begin
555 Move(S.Instruments.All[I], SV4.Instruments.All[I], SizeOf(TInstrumentV1));
556 SV4.Instruments.All[I].NoiseMacro := Default(TNoiseMacro);
557 end;
558
559 Result := UpgradeSong(SV4);
560 end;
561
562 function UpgradeSong(S: TSongV4): TSong;
433 begin 563 begin
434 Result := S; 564 Result := S;
435 end; 565 end;
Modifiedtracker.pas +2−1
@@ -1522,7 +1522,8 @@ procedure TfrmTracker.HeaderControl1SectionResize(
1522 begin 1522 begin
1523 // Prevent resizing these 1523 // Prevent resizing these
1524 // TODO: Create a subclass of them that doesn't allow resizing maybe? 1524 // TODO: Create a subclass of them that doesn't allow resizing maybe?
1525 Section.Width := TrackerGrid.ColumnWidth; 1525 if Section.OriginalIndex > 0 then Section.Width := TrackerGrid.ColumnWidth
1526 else Section.Width := RowNumberStringGrid.Width;
1526 end; 1527 end;
1527 1528
1528 procedure TfrmTracker.CutActionExecute(Sender: TObject); 1529 procedure TfrmTracker.CutActionExecute(Sender: TObject);