Commit d6827d2

Nick committed on
WIP Order grid (mostly working)
commit d6827d287b3bbf2c0025d967171c7d5b9acff31f parent 6ceea9b
5 changed files +236−31
Modifiedhugedatatypes.pas +7−2
@@ -1,11 +1,11 @@
1 unit HugeDatatypes; 1 unit HugeDatatypes;
2 2
3 {$mode delphi} 3 {$mode objfpc}
4 4
5 interface 5 interface
6 6
7 uses 7 uses
8 Classes, SysUtils; 8 Classes, SysUtils, fgl;
9 9
10 type 10 type
11 TEffectParams = packed record 11 TEffectParams = packed record
@@ -21,6 +21,11 @@ type
21 EffectParams: TEffectParams; 21 EffectParams: TEffectParams;
22 end; 22 end;
23 23
24 TPattern = array[0..63] of TCell;
25 PPattern = ^TPattern;
26
27 TOrderMap = specialize TFPGMap<Integer, PPattern>;
28
24 TSelection = array of array of TCell; 29 TSelection = array of array of TCell;
25 30
26 implementation 31 implementation
Modifiedtracker.lfm +53−5
@@ -1,7 +1,7 @@
1 object frmTracker: TfrmTracker 1 object frmTracker: TfrmTracker
2 Left = 1184 2 Left = 1974
3 Height = 1298 3 Height = 1298
4 Top = 306 4 Top = 176
5 Width = 1893 5 Width = 1893
6 Caption = 'hUGETracker' 6 Caption = 'hUGETracker'
7 ClientHeight = 1268 7 ClientHeight = 1268
@@ -11,6 +11,7 @@ object frmTracker: TfrmTracker
11 OnCreate = FormCreate 11 OnCreate = FormCreate
12 OnKeyDown = FormKeyDown 12 OnKeyDown = FormKeyDown
13 OnKeyUp = FormKeyUp 13 OnKeyUp = FormKeyUp
14 ShowHint = True
14 LCLVersion = '2.0.6.0' 15 LCLVersion = '2.0.6.0'
15 object TreeView1: TTreeView 16 object TreeView1: TTreeView
16 Left = 0 17 Left = 0
@@ -96,6 +97,7 @@ object frmTracker: TfrmTracker
96 object SongEdit: TEdit 97 object SongEdit: TEdit
97 Left = 84 98 Left = 84
98 Height = 33 99 Height = 33
100 Hint = 'The name of your composition'
99 Top = 12 101 Top = 12
100 Width = 324 102 Width = 324
101 OnChange = SongEditChange 103 OnChange = SongEditChange
@@ -105,6 +107,7 @@ object frmTracker: TfrmTracker
105 object ArtistEdit: TEdit 107 object ArtistEdit: TEdit
106 Left = 84 108 Left = 84
107 Height = 33 109 Height = 33
110 Hint = 'Your name or handle'
108 Top = 60 111 Top = 60
109 Width = 324 112 Width = 324
110 OnChange = ArtistEditChange 113 OnChange = ArtistEditChange
@@ -123,6 +126,7 @@ object frmTracker: TfrmTracker
123 object TicksPerRowSpinEdit: TSpinEdit 126 object TicksPerRowSpinEdit: TSpinEdit
124 Left = 199 127 Left = 199
125 Height = 33 128 Height = 33
129 Hint = 'How many ticks should happen before the row changes. Higher means slower'
126 Top = 110 130 Top = 110
127 Width = 75 131 Width = 75
128 MaxValue = 20 132 MaxValue = 20
@@ -199,7 +203,7 @@ object frmTracker: TfrmTracker
199 TabOrder = 1 203 TabOrder = 1
200 end 204 end
201 end 205 end
202 object DrawGrid1: TStringGrid 206 object OrderEditStringGrid: TStringGrid
203 Left = 0 207 Left = 0
204 Height = 892 208 Height = 892
205 Top = 0 209 Top = 0
@@ -238,12 +242,19 @@ object frmTracker: TfrmTracker
238 DefaultColWidth = 25 242 DefaultColWidth = 25
239 DefaultRowHeight = 32 243 DefaultRowHeight = 32
240 ExtendedSelect = False 244 ExtendedSelect = False
241 Options = [goFixedVertLine, goFixedHorzLine, goRangeSelect, goEditing, goTabs, goSmoothScroll, goFixedRowNumbering, goRowHighlight] 245 Options = [goFixedVertLine, goFixedHorzLine, goRangeSelect, goRowMoving, goEditing, goAutoAddRows, goTabs, goSmoothScroll, goFixedRowNumbering, goRowHighlight]
246 PopupMenu = OrderEditPopup
242 RangeSelectMode = rsmMulti 247 RangeSelectMode = rsmMulti
243 RowCount = 10 248 RowCount = 10
244 ScrollBars = ssVertical 249 ScrollBars = ssVertical
245 TabOrder = 1 250 TabOrder = 1
246 UseXORFeatures = True 251 UseXORFeatures = True
252 OnAfterSelection = OrderEditStringGridAfterSelection
253 OnColRowDeleted = OrderEditStringGridColRowDeleted
254 OnColRowExchanged = OrderEditStringGridColRowExchanged
255 OnColRowInserted = OrderEditStringGridColRowInserted
256 OnColRowMoved = OrderEditStringGridColRowMoved
257 OnEditingDone = OrderEditStringGridEditingDone
247 ColWidths = ( 258 ColWidths = (
248 96 259 96
249 52 260 52
@@ -264,6 +275,7 @@ object frmTracker: TfrmTracker
264 AnchorSideBottom.Side = asrBottom 275 AnchorSideBottom.Side = asrBottom
265 Left = 0 276 Left = 0
266 Height = 394 277 Height = 394
278 Hint = 'Preview of how the resulting waveform will look with envelope applied'
267 Top = 498 279 Top = 498
268 Width = 1587 280 Width = 1587
269 Align = alClient 281 Align = alClient
@@ -327,6 +339,7 @@ object frmTracker: TfrmTracker
327 object InstrumentNumberSpinner: TSpinEdit 339 object InstrumentNumberSpinner: TSpinEdit
328 Left = 120 340 Left = 120
329 Height = 33 341 Height = 33
342 Hint = 'What instrument to edit'
330 Top = 2 343 Top = 2
331 Width = 264 344 Width = 264
332 MaxValue = 15 345 MaxValue = 15
@@ -357,6 +370,7 @@ object frmTracker: TfrmTracker
357 object InstrumentNameEdit: TEdit 370 object InstrumentNameEdit: TEdit
358 Left = 120 371 Left = 120
359 Height = 33 372 Height = 33
373 Hint = 'The name of the instrument'
360 Top = 39 374 Top = 39
361 Width = 264 375 Width = 264
362 OnChange = InstrumentNameEditChange 376 OnChange = InstrumentNameEditChange
@@ -375,6 +389,7 @@ object frmTracker: TfrmTracker
375 object InstrumentTypeCombobox: TComboBox 389 object InstrumentTypeCombobox: TComboBox
376 Left = 120 390 Left = 120
377 Height = 33 391 Height = 33
392 Hint = 'What type of channel this instrument will be played on'
378 Top = 80 393 Top = 80
379 Width = 264 394 Width = 264
380 ItemHeight = 25 395 ItemHeight = 25
@@ -393,6 +408,7 @@ object frmTracker: TfrmTracker
393 object LengthEnabledCheckbox: TCheckBox 408 object LengthEnabledCheckbox: TCheckBox
394 Left = 12 409 Left = 12
395 Height = 29 410 Height = 29
411 Hint = 'Cut the sound after a certain length of time'
396 Top = 126 412 Top = 126
397 Width = 84 413 Width = 84
398 Caption = 'Length' 414 Caption = 'Length'
@@ -403,6 +419,7 @@ object frmTracker: TfrmTracker
403 object LengthSpinner: TECSpinPosition 419 object LengthSpinner: TECSpinPosition
404 Left = 120 420 Left = 120
405 Height = 24 421 Height = 24
422 Hint = 'Units of length to cut the sound after'
406 Top = 120 423 Top = 120
407 Width = 174 424 Width = 174
408 Buttons.BtnBigDec.BtnOrder = 1 425 Buttons.BtnBigDec.BtnOrder = 1
@@ -485,6 +502,7 @@ object frmTracker: TfrmTracker
485 object DirectionComboBox: TComboBox 502 object DirectionComboBox: TComboBox
486 Left = 123 503 Left = 123
487 Height = 33 504 Height = 33
505 Hint = 'Whether to fade the sound in or out'
488 Top = 60 506 Top = 60
489 Width = 297 507 Width = 297
490 ItemHeight = 25 508 ItemHeight = 25
@@ -511,6 +529,7 @@ object frmTracker: TfrmTracker
511 object StartVolSpinner: TECSpinPosition 529 object StartVolSpinner: TECSpinPosition
512 Left = 123 530 Left = 123
513 Height = 24 531 Height = 24
532 Hint = 'The initial volume when the note is retriggered'
514 Top = -2 533 Top = -2
515 Width = 198 534 Width = 198
516 Buttons.BtnBigDec.BtnOrder = 1 535 Buttons.BtnBigDec.BtnOrder = 1
@@ -558,6 +577,7 @@ object frmTracker: TfrmTracker
558 object EnvChangeSpinner: TECSpinPosition 577 object EnvChangeSpinner: TECSpinPosition
559 Left = 123 578 Left = 123
560 Height = 24 579 Height = 24
580 Hint = 'How much to change the volume each time'
561 Top = 120 581 Top = 120
562 Width = 198 582 Width = 198
563 Buttons.BtnBigDec.BtnOrder = 1 583 Buttons.BtnBigDec.BtnOrder = 1
@@ -615,6 +635,7 @@ object frmTracker: TfrmTracker
615 object EnvelopePaintbox: TPaintBox 635 object EnvelopePaintbox: TPaintBox
616 Left = 1 636 Left = 1
617 Height = 156 637 Height = 156
638 Hint = 'Preview of the volume envelope'
618 Top = 1 639 Top = 1
619 Width = 517 640 Width = 517
620 Align = alClient 641 Align = alClient
@@ -745,6 +766,7 @@ object frmTracker: TfrmTracker
745 object SweepSizeSpinner: TECSpinPosition 766 object SweepSizeSpinner: TECSpinPosition
746 Left = 156 767 Left = 156
747 Height = 24 768 Height = 24
769 Hint = 'Change by this amount each sweep tick'
748 Top = 112 770 Top = 112
749 Width = 198 771 Width = 198
750 Buttons.BtnBigDec.BtnOrder = 1 772 Buttons.BtnBigDec.BtnOrder = 1
@@ -827,6 +849,7 @@ object frmTracker: TfrmTracker
827 object WaveformCombobox: TComboBox 849 object WaveformCombobox: TComboBox
828 Left = 156 850 Left = 156
829 Height = 33 851 Height = 33
852 Hint = 'Which waveform is associated with this instrument'
830 Top = 60 853 Top = 60
831 Width = 264 854 Width = 264
832 ItemHeight = 25 855 ItemHeight = 25
@@ -848,6 +871,7 @@ object frmTracker: TfrmTracker
848 object WavePaintbox: TPaintBox 871 object WavePaintbox: TPaintBox
849 Left = 1 872 Left = 1
850 Height = 86 873 Height = 86
874 Hint = 'Preview of the waveform associated with this instrument'
851 Top = 1 875 Top = 1
852 Width = 406 876 Width = 406
853 Align = alClient 877 Align = alClient
@@ -860,6 +884,7 @@ object frmTracker: TfrmTracker
860 object WaveVolumeCombobox: TComboBox 884 object WaveVolumeCombobox: TComboBox
861 Left = 156 885 Left = 156
862 Height = 33 886 Height = 33
887 Hint = 'The initial volume of the wave'
863 Top = 12 888 Top = 12
864 Width = 264 889 Width = 264
865 ItemHeight = 25 890 ItemHeight = 25
@@ -925,6 +950,7 @@ object frmTracker: TfrmTracker
925 object RandomizeNoiseButton: TButton 950 object RandomizeNoiseButton: TButton
926 Left = 12 951 Left = 12
927 Height = 38 952 Height = 38
953 Hint = 'Randomize the noise instrument parameters to get a random drum-like sound'
928 Top = 165 954 Top = 165
929 Width = 360 955 Width = 360
930 Caption = 'Randomize' 956 Caption = 'Randomize'
@@ -1687,9 +1713,10 @@ object frmTracker: TfrmTracker
1687 Height = 36 1713 Height = 36
1688 Top = 1232 1714 Top = 1232
1689 Width = 1893 1715 Width = 1893
1716 AutoHint = True
1690 Panels = < 1717 Panels = <
1691 item 1718 item
1692 Width = 300 1719 Width = 700
1693 end 1720 end
1694 item 1721 item
1695 Width = 300 1722 Width = 300
@@ -1698,7 +1725,9 @@ object frmTracker: TfrmTracker
1698 Width = 300 1725 Width = 300
1699 end> 1726 end>
1700 ParentFont = False 1727 ParentFont = False
1728 ParentShowHint = False
1701 SimplePanel = False 1729 SimplePanel = False
1730 ShowHint = True
1702 end 1731 end
1703 object ToolBar1: TToolBar 1732 object ToolBar1: TToolBar
1704 Left = 0 1733 Left = 0
@@ -4246,4 +4275,23 @@ object frmTracker: TfrmTracker
4246 left = 744 4275 left = 744
4247 top = 64 4276 top = 64
4248 end 4277 end
4278 object OrderEditPopup: TPopupMenu
4279 left = 1136
4280 top = 64
4281 object MenuItem17: TMenuItem
4282 Caption = 'Insert new row'
4283 Hint = 'Insert a new row filled with brand new patterns'
4284 end
4285 object MenuItem18: TMenuItem
4286 Caption = 'Insert empty row'
4287 Hint = 'Insert a new with nothing in it yet'
4288 end
4289 object MenuItem20: TMenuItem
4290 Caption = '-'
4291 end
4292 object MenuItem19: TMenuItem
4293 Caption = 'Remove row'
4294 Hint = 'Remove a row-- Does not delete the patterns from existence'
4295 end
4296 end
4249 end 4297 end
Modifiedtracker.pas +101−4
@@ -9,16 +9,20 @@ uses
9 Menus, Spin, StdCtrls, ActnList, StdActns, SynEdit, math, Instruments, Waves, 9 Menus, Spin, StdCtrls, ActnList, StdActns, SynEdit, math, Instruments, Waves,
10 Song, EmulationThread, Utils, Constants, sound, vars, machine, 10 Song, EmulationThread, Utils, Constants, sound, vars, machine,
11 about_hugetracker, TrackerGrid, lclintf, lmessages, Buttons, Grids, DBCtrls, 11 about_hugetracker, TrackerGrid, lclintf, lmessages, Buttons, Grids, DBCtrls,
12 ECProgressBar, ECSpinCtrls, ECCheckListBox, ECGrid; 12 ECProgressBar, HugeDatatypes;
13 13
14 type 14 type
15 { TfrmTracker } 15 { TfrmTracker }
16 16
17 TfrmTracker = class(TForm) 17 TfrmTracker = class(TForm)
18 CutAction: TAction; 18 CutAction: TAction;
19 DrawGrid1: TStringGrid; 19 OrderEditStringGrid: TStringGrid;
20 EditCut1: TEditCut; 20 EditCut1: TEditCut;
21 HeaderControl1: THeaderControl; 21 HeaderControl1: THeaderControl;
22 MenuItem17: TMenuItem;
23 MenuItem18: TMenuItem;
24 MenuItem19: TMenuItem;
25 MenuItem20: TMenuItem;
22 Panel3: TPanel; 26 Panel3: TPanel;
23 PasteAction: TAction; 27 PasteAction: TAction;
24 CopyAction: TAction; 28 CopyAction: TAction;
@@ -54,6 +58,7 @@ type
54 MenuItem8: TMenuItem; 58 MenuItem8: TMenuItem;
55 MenuItem9: TMenuItem; 59 MenuItem9: TMenuItem;
56 OpenDialog1: TOpenDialog; 60 OpenDialog1: TOpenDialog;
61 OrderEditPopup: TPopupMenu;
57 SaveDialog1: TSaveDialog; 62 SaveDialog1: TSaveDialog;
58 ScrollBox1: TScrollBox; 63 ScrollBox1: TScrollBox;
59 TicksPerRowSpinEdit: TSpinEdit; 64 TicksPerRowSpinEdit: TSpinEdit;
@@ -165,6 +170,17 @@ type
165 procedure MenuItem16Click(Sender: TObject); 170 procedure MenuItem16Click(Sender: TObject);
166 procedure MenuItem5Click(Sender: TObject); 171 procedure MenuItem5Click(Sender: TObject);
167 procedure NoiseFreqSpinnerChange(Sender: TObject); 172 procedure NoiseFreqSpinnerChange(Sender: TObject);
173 procedure OrderEditStringGridAfterSelection(Sender: TObject; aCol,
174 aRow: Integer);
175 procedure OrderEditStringGridColRowDeleted(Sender: TObject;
176 IsColumn: Boolean; sIndex, tIndex: Integer);
177 procedure OrderEditStringGridColRowExchanged(Sender: TObject;
178 IsColumn: Boolean; sIndex, tIndex: Integer);
179 procedure OrderEditStringGridColRowInserted(Sender: TObject;
180 IsColumn: Boolean; sIndex, tIndex: Integer);
181 procedure OrderEditStringGridColRowMoved(Sender: TObject;
182 IsColumn: Boolean; sIndex, tIndex: Integer);
183 procedure OrderEditStringGridEditingDone(Sender: TObject);
168 procedure PanicToolButtonClick(Sender: TObject); 184 procedure PanicToolButtonClick(Sender: TObject);
169 procedure PasteActionExecute(Sender: TObject); 185 procedure PasteActionExecute(Sender: TObject);
170 procedure TicksPerRowSpinEditChange(Sender: TObject); 186 procedure TicksPerRowSpinEditChange(Sender: TObject);
@@ -201,11 +217,14 @@ type
201 217
202 Ticks: Integer; 218 Ticks: Integer;
203 219
220 Orders: TOrderMap;
221
204 procedure ChangeToSquare; 222 procedure ChangeToSquare;
205 procedure ChangeToWave; 223 procedure ChangeToWave;
206 procedure ChangeToNoise; 224 procedure ChangeToNoise;
207 procedure LoadInstrument(Instr: Integer); 225 procedure LoadInstrument(Instr: Integer);
208 procedure LoadWave(Wave: Integer); 226 procedure LoadWave(Wave: Integer);
227 procedure ReloadPatterns;
209 228
210 procedure UpdateUIAfterLoad; 229 procedure UpdateUIAfterLoad;
211 230
@@ -324,6 +343,23 @@ begin
324 WaveEditPaintBox.Invalidate; 343 WaveEditPaintBox.Invalidate;
325 end; 344 end;
326 345
346 procedure TfrmTracker.ReloadPatterns;
347 var
348 I: Integer;
349 OrderNum: Integer;
350 Pat: PPattern;
351 begin
352 for I := 0 to 3 do begin
353 OrderNum := 0;
354 TryStrToInt(
355 OrderEditStringGrid.Cells[I+1, OrderEditStringGrid.Row],
356 OrderNum
357 );
358 Pat := Orders.GetOrCreateNew(OrderNum);
359 TrackerGrid.LoadPattern(I, Pat);
360 end;
361 end;
362
327 procedure TfrmTracker.LoadInstrument(Instr: Integer); 363 procedure TfrmTracker.LoadInstrument(Instr: Integer);
328 var 364 var
329 CI: ^TInstrument; 365 CI: ^TInstrument;
@@ -512,7 +548,10 @@ procedure TfrmTracker.FormCreate(Sender: TObject);
512 var 548 var
513 I, J: Integer; 549 I, J: Integer;
514 Section: TCollectionItem; 550 Section: TCollectionItem;
551 Pattern0: PPattern;
515 begin 552 begin
553 ReturnNilIfGrowHeapFails := False;
554
516 for I := Low(Song.Instruments) to High(Song.Instruments) do 555 for I := Low(Song.Instruments) to High(Song.Instruments) do
517 with Song.Instruments[I] do begin 556 with Song.Instruments[I] do begin
518 Type_ := Square; 557 Type_ := Square;
@@ -538,13 +577,23 @@ begin
538 LoadInstrument(1); 577 LoadInstrument(1);
539 LoadWave(0); 578 LoadWave(0);
540 579
580 // Initialize order table
581 for I := 0 to 4 do
582 OrderEditStringGrid.Cells[I, 1] := '0';
583
584 // Create the order map and pattern 0
585 New(Pattern0);
586 Pattern0^ := Default(TPattern);
587 Orders := TOrderMap.Create;
588 Orders.Add(0, Pattern0);
589
541 // Create pattern editor control 590 // Create pattern editor control
542 TrackerGrid := TTrackerGrid.Create(Self, ScrollBox1); 591 TrackerGrid := TTrackerGrid.Create(Self, ScrollBox1, Pattern0, Pattern0, Pattern0, Pattern0);
543 for Section in HeaderControl1.Sections do 592 for Section in HeaderControl1.Sections do
544 (Section as THeaderSection).Width := TrackerGrid.ColumnWidth; 593 (Section as THeaderSection).Width := TrackerGrid.ColumnWidth;
545 594
546 // Manually resize the fixed column in the order editor 595 // Manually resize the fixed column in the order editor
547 DrawGrid1.ColWidths[0]:=50; 596 OrderEditStringGrid.ColWidths[0]:=50;
548 597
549 // Get the emulator ready to make sound... 598 // Get the emulator ready to make sound...
550 EmulationThread := TEmulationThread.Create; 599 EmulationThread := TEmulationThread.Create;
@@ -722,6 +771,54 @@ begin
722 CurrentInstrument^.ShiftClockFreq := Round(NoiseFreqSpinner.Position); 771 CurrentInstrument^.ShiftClockFreq := Round(NoiseFreqSpinner.Position);
723 end; 772 end;
724 773
774 procedure TfrmTracker.OrderEditStringGridAfterSelection(Sender: TObject; aCol,
775 aRow: Integer);
776 begin
777 ReloadPatterns;
778 end;
779
780 procedure TfrmTracker.OrderEditStringGridColRowDeleted(Sender: TObject;
781 IsColumn: Boolean; sIndex, tIndex: Integer);
782 begin
783 ReloadPatterns;
784 end;
785
786 procedure TfrmTracker.OrderEditStringGridColRowExchanged(Sender: TObject;
787 IsColumn: Boolean; sIndex, tIndex: Integer);
788 begin
789 ReloadPatterns;
790 end;
791
792 procedure TfrmTracker.OrderEditStringGridColRowInserted(Sender: TObject;
793 IsColumn: Boolean; sIndex, tIndex: Integer);
794 begin
795 ReloadPatterns;
796 end;
797
798 procedure TfrmTracker.OrderEditStringGridColRowMoved(Sender: TObject;
799 IsColumn: Boolean; sIndex, tIndex: Integer);
800 begin
801 ReloadPatterns;
802 end;
803
804 procedure TfrmTracker.OrderEditStringGridEditingDone(Sender: TObject);
805 var
806 Temp: Integer;
807 begin
808 // TODO: Fix this hack! For some reason OnValidateEntry is giving bad pointers
809 // for its NewValue and OldValue params. This is the workaround for now.
810 if not TryStrToInt(
811 OrderEditStringGrid.Cells[OrderEditStringGrid.Col, OrderEditStringGrid.Row],
812 Temp
813 ) then
814 OrderEditStringGrid.Cells[
815 OrderEditStringGrid.Col,
816 OrderEditStringGrid.Row
817 ] := '';
818
819 ReloadPatterns;
820 end;
821
725 procedure TfrmTracker.PanicToolButtonClick(Sender: TObject); 822 procedure TfrmTracker.PanicToolButtonClick(Sender: TObject);
726 begin 823 begin
727 // Silence CH1 824 // Silence CH1
Modifiedtrackergrid.pas +40−19
@@ -20,8 +20,8 @@ const
20 clFxPan = clInstrument; 20 clFxPan = clInstrument;
21 clFxSong = TColor($00007F); 21 clFxSong = TColor($00007F);
22 22
23 NumColumns = 4; 23 NUM_COLUMNS = 4;
24 NumRows = 64; 24 NUM_ROWS = 64;
25 25
26 type 26 type
27 TCellPart = ( 27 TCellPart = (
@@ -40,7 +40,11 @@ type
40 { TTrackerGrid } 40 { TTrackerGrid }
41 41
42 TTrackerGrid = class(TCustomControl) 42 TTrackerGrid = class(TCustomControl)
43 constructor Create(AOwner: TComponent; Parent: TWinControl); 43 constructor Create(
44 AOwner: TComponent;
45 Parent: TWinControl;
46 C1, C2, C3, C4: PPattern
47 );
44 procedure Paint; override; 48 procedure Paint; override;
45 procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer); 49 procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
46 override; 50 override;
@@ -63,7 +67,7 @@ type
63 procedure InputEffectParams(Key: Word); 67 procedure InputEffectParams(Key: Word);
64 68
65 private 69 private
66 Cells: array[0..3, 0..63] of TCell; 70 Patterns: array[0..3] of PPattern;
67 71
68 CharHeight: Integer; 72 CharHeight: Integer;
69 CharWidth: Integer; 73 CharWidth: Integer;
@@ -74,7 +78,7 @@ type
74 DigitInputting: Boolean; 78 DigitInputting: Boolean;
75 79
76 procedure RenderRow(Row: Integer); 80 procedure RenderRow(Row: Integer);
77 procedure RenderCell(Cell: TCell); 81 procedure RenderCell(const Cell: TCell);
78 82
79 function GetEffectColor(EffectCode: Integer): TColor; 83 function GetEffectColor(EffectCode: Integer): TColor;
80 function SelectionsToRect(S1, S2: TSelectionPos): TRect; 84 function SelectionsToRect(S1, S2: TSelectionPos): TRect;
@@ -85,13 +89,19 @@ type
85 public 89 public
86 Cursor, Other: TSelectionPos; 90 Cursor, Other: TSelectionPos;
87 ColumnWidth, RowHeight: Integer; 91 ColumnWidth, RowHeight: Integer;
92
93 procedure LoadPattern(Idx: Integer; Pat: PPattern);
88 end; 94 end;
89 95
90 implementation 96 implementation
91 97
92 { TTrackerGrid } 98 { TTrackerGrid }
93 99
94 constructor TTrackerGrid.Create(AOwner: TComponent; Parent: TWinControl); 100 constructor TTrackerGrid.Create(
101 AOwner: TComponent;
102 Parent: TWinControl;
103 C1, C2, C3, C4: PPattern
104 );
95 var 105 var
96 X, Y: Integer; 106 X, Y: Integer;
97 begin 107 begin
@@ -114,9 +124,14 @@ begin
114 Width := ColumnWidth*4; 124 Width := ColumnWidth*4;
115 Height := RowHeight*64; 125 Height := RowHeight*64;
116 126
117 for X := 0 to High(Cells) do 127 Patterns[0] := C1;
118 for Y := 0 to High(Cells[X]) do 128 Patterns[1] := C2;
119 Cells[X, Y].Note := NO_NOTE; 129 Patterns[2] := C3;
130 Patterns[3] := C4;
131
132 for X := 0 to High(Patterns) do
133 for Y := 0 to High(Patterns[X]^) do
134 Patterns[X]^[Y].Note := NO_NOTE;
120 end; 135 end;
121 136
122 procedure TTrackerGrid.Paint; 137 procedure TTrackerGrid.Paint;
@@ -130,7 +145,7 @@ begin
130 Brush.Color := RGBToColor(225, 219, 208); 145 Brush.Color := RGBToColor(225, 219, 208);
131 Clear; 146 Clear;
132 147
133 for I := 0 to 64 do begin 148 for I := 0 to High(TPattern) do begin
134 if (I mod 4) = 0 then begin 149 if (I mod 4) = 0 then begin
135 Brush.Color := RGBToColor(216, 209, 195); 150 Brush.Color := RGBToColor(216, 209, 195);
136 FillRect(0, I*RowHeight, Width, (I+1)*RowHeight); 151 FillRect(0, I*RowHeight, Width, (I+1)*RowHeight);
@@ -301,7 +316,7 @@ procedure TTrackerGrid.InputNote(Key: Word);
301 var 316 var
302 Temp: Integer; 317 Temp: Integer;
303 begin 318 begin
304 with Cells[Cursor.X, Cursor.Y] do 319 with Patterns[Cursor.X]^[Cursor.Y] do
305 if Key = VK_DELETE then 320 if Key = VK_DELETE then
306 Note := NO_NOTE 321 Note := NO_NOTE
307 else begin 322 else begin
@@ -314,7 +329,7 @@ procedure TTrackerGrid.InputInstrument(Key: Word);
314 var 329 var
315 Temp: Byte; 330 Temp: Byte;
316 begin 331 begin
317 with Cells[Cursor.X, Cursor.Y] do 332 with Patterns[Cursor.X]^[Cursor.Y] do
318 if Key = VK_DELETE then Instrument := 0 333 if Key = VK_DELETE then Instrument := 0
319 else if KeycodeToHexNumber(Key, Temp) and (Temp < 9) then 334 else if KeycodeToHexNumber(Key, Temp) and (Temp < 9) then
320 Instrument := ((Instrument mod 10) * 10) + Temp; 335 Instrument := ((Instrument mod 10) * 10) + Temp;
@@ -327,7 +342,7 @@ end;
327 342
328 procedure TTrackerGrid.InputEffectCode(Key: Word); 343 procedure TTrackerGrid.InputEffectCode(Key: Word);
329 begin 344 begin
330 with Cells[Cursor.X, Cursor.Y] do 345 with Patterns[Cursor.X]^[Cursor.Y] do
331 if Key = VK_DELETE then begin 346 if Key = VK_DELETE then begin
332 EffectCode := 0; 347 EffectCode := 0;
333 EffectParams.Value := 0; 348 EffectParams.Value := 0;
@@ -339,7 +354,7 @@ procedure TTrackerGrid.InputEffectParams(Key: Word);
339 var 354 var
340 Temp: Byte; 355 Temp: Byte;
341 begin 356 begin
342 with Cells[Cursor.X, Cursor.Y] do 357 with Patterns[Cursor.X]^[Cursor.Y] do
343 if Key = VK_DELETE then begin 358 if Key = VK_DELETE then begin
344 EffectCode := 0; 359 EffectCode := 0;
345 EffectParams.Value := 0; 360 EffectParams.Value := 0;
@@ -364,12 +379,12 @@ begin
364 Brush.Style := bsClear; 379 Brush.Style := bsClear;
365 Pen.Color := RGBToColor(58, 52, 39); 380 Pen.Color := RGBToColor(58, 52, 39);
366 381
367 for I := 0 to 4 do 382 for I := 0 to High(Patterns) do
368 RenderCell(Cells[I, Row]); 383 RenderCell(Patterns[I]^[Row]);
369 end; 384 end;
370 end; 385 end;
371 386
372 procedure TTrackerGrid.RenderCell(Cell: TCell); 387 procedure TTrackerGrid.RenderCell(const Cell: TCell);
373 var 388 var
374 NoteString: ShortString; 389 NoteString: ShortString;
375 begin 390 begin
@@ -481,8 +496,8 @@ end;
481 496
482 function TTrackerGrid.MousePosToSelection(X, Y: Integer): TSelectionPos; 497 function TTrackerGrid.MousePosToSelection(X, Y: Integer): TSelectionPos;
483 begin 498 begin
484 Result.X := Trunc((X/Width)*NumColumns); 499 Result.X := Trunc((X/Width)*NUM_COLUMNS);
485 Result.Y := Trunc((Y/Height)*NumRows); 500 Result.Y := Trunc((Y/Height)*NUM_ROWS);
486 501
487 X := (min(X, width-1) mod ColumnWidth); 502 X := (min(X, width-1) mod ColumnWidth);
488 X := Trunc((X/ColumnWidth)*13); 503 X := Trunc((X/ColumnWidth)*13);
@@ -528,5 +543,11 @@ begin
528 Num := X; 543 Num := X;
529 end; 544 end;
530 545
546 procedure TTrackerGrid.LoadPattern(Idx: Integer; Pat: PPattern);
547 begin
548 Patterns[Idx] := Pat;
549 Invalidate;
550 end;
551
531 end. 552 end.
532 553
Modifiedutils.pas +35−1
@@ -5,9 +5,15 @@ unit Utils;
5 interface 5 interface
6 6
7 uses 7 uses
8 Classes, SysUtils, instruments, waves; 8 Classes, SysUtils, Instruments, Waves, HugeDatatypes, Constants;
9 9
10 type 10 type
11 { TOrderMapHelper }
12
13 TOrderMapHelper = class helper for TOrderMap
14 function GetOrCreateNew(Key: Integer): PPattern;
15 end;
16
11 TRegisters = record 17 TRegisters = record
12 case Type_: TInstrumentType of 18 case Type_: TInstrumentType of
13 Square: (NR10, NR11, NR12, NR13, NR14: Byte); 19 Square: (NR10, NR11, NR12, NR13, NR14: Byte);
@@ -126,8 +132,26 @@ function WaveInstrumentToRegisters(
126 132
127 function ConvertWaveform(Waveform: TWave): T4bitWave; 133 function ConvertWaveform(Waveform: TWave): T4bitWave;
128 134
135 procedure BlankPattern(Pat: PPattern);
136
129 implementation 137 implementation
130 138
139 { TOrderMapHelper }
140
141 function TOrderMapHelper.GetOrCreateNew(Key: Integer): PPattern;
142 var
143 NewPat: PPattern;
144 begin
145 if Self.IndexOf(Key) <> -1 then
146 Result := Self.KeyData[Key]
147 else begin
148 New(NewPat);
149 BlankPattern(NewPat);
150 Self.Add(Key, NewPat);
151 Result := NewPat;
152 end;
153 end;
154
131 function ConvertWaveform(Waveform: TWave): T4bitWave; 155 function ConvertWaveform(Waveform: TWave): T4bitWave;
132 var 156 var
133 I: Integer; 157 I: Integer;
@@ -139,6 +163,16 @@ begin
139 end; 163 end;
140 end; 164 end;
141 165
166 procedure BlankPattern(Pat: PPattern);
167 var
168 I: Integer;
169 begin
170 for I := 0 to High(Pat^) do begin
171 Pat^[I] := Default(TCell);
172 Pat^[I].Note := NO_NOTE;
173 end;
174 end;
175
142 function WaveInstrumentToRegisters( 176 function WaveInstrumentToRegisters(
143 Frequency: Word; 177 Frequency: Word;
144 Initial: Boolean; 178 Initial: Boolean;