Commit 6f76bf5

Nick committed on
WIP on pattern editor
commit 6f76bf5577f058a037255da5c7bd10ffe94d650d parent c2b25a4
10 changed files +801−95
ModifiedGBEmu.lpi +31−8
@@ -43,27 +43,30 @@
43 </Mode0> 43 </Mode0>
44 </Modes> 44 </Modes>
45 </RunParams> 45 </RunParams>
46 <RequiredPackages Count="6"> 46 <RequiredPackages Count="7">
47 <Item1> 47 <Item1>
48 <PackageName Value="virtualtreeview_package"/> 48 <PackageName Value="RunTimeTypeInfoControls"/>
49 </Item1> 49 </Item1>
50 <Item2> 50 <Item2>
51 <PackageName Value="SynEdit"/> 51 <PackageName Value="virtualtreeview_package"/>
52 </Item2> 52 </Item2>
53 <Item3> 53 <Item3>
54 <PackageName Value="eccontrols"/> 54 <PackageName Value="SynEdit"/>
55 </Item3> 55 </Item3>
56 <Item4> 56 <Item4>
57 <PackageName Value="LazControls"/> 57 <PackageName Value="eccontrols"/>
58 </Item4> 58 </Item4>
59 <Item5> 59 <Item5>
60 <PackageName Value="BGRABitmapPack"/> 60 <PackageName Value="LazControls"/>
61 </Item5> 61 </Item5>
62 <Item6> 62 <Item6>
63 <PackageName Value="LCL"/> 63 <PackageName Value="BGRABitmapPack"/>
64 </Item6> 64 </Item6>
65 <Item7>
66 <PackageName Value="LCL"/>
67 </Item7>
65 </RequiredPackages> 68 </RequiredPackages>
66 <Units Count="20"> 69 <Units Count="24">
67 <Unit0> 70 <Unit0>
68 <Filename Value="GBEmu.lpr"/> 71 <Filename Value="GBEmu.lpr"/>
69 <IsPartOfProject Value="True"/> 72 <IsPartOfProject Value="True"/>
@@ -166,6 +169,26 @@
166 <HasResources Value="True"/> 169 <HasResources Value="True"/>
167 <ResourceBaseClass Value="Form"/> 170 <ResourceBaseClass Value="Form"/>
168 </Unit19> 171 </Unit19>
172 <Unit20>
173 <Filename Value="trackergrid.pas"/>
174 <IsPartOfProject Value="True"/>
175 <UnitName Value="TrackerGrid"/>
176 </Unit20>
177 <Unit21>
178 <Filename Value="patterns.pas"/>
179 <IsPartOfProject Value="True"/>
180 <UnitName Value="Patterns"/>
181 </Unit21>
182 <Unit22>
183 <Filename Value="clipboardutils.pas"/>
184 <IsPartOfProject Value="True"/>
185 <UnitName Value="ClipboardUtils"/>
186 </Unit22>
187 <Unit23>
188 <Filename Value="hugedatatypes.pas"/>
189 <IsPartOfProject Value="True"/>
190 <UnitName Value="HugeDatatypes"/>
191 </Unit23>
169 </Units> 192 </Units>
170 </ProjectOptions> 193 </ProjectOptions>
171 <CompilerOptions> 194 <CompilerOptions>
Modifiedabout_hugetracker.lfm +1−1
@@ -34,7 +34,7 @@ object frmAboutHugetracker: TfrmAboutHugetracker
34 Width = 587 34 Width = 587
35 Alignment = taCenter 35 Alignment = taCenter
36 AutoSize = False 36 AutoSize = False
37 Caption = 'Created by Nick "SuperDisk" Faro and Eldred "ISSOtm" Habert'#13#10#13#10'Sound playback engine written by Christian Hackbart' 37 Caption = 'Created by Nick "SuperDisk" Faro and Eldred "ISSOtm" Habert'#13#10#13#10'Soundchip emulator written by Christian Hackbart and Rusty Wagner'
38 ParentColor = False 38 ParentColor = False
39 end 39 end
40 object Button1: TButton 40 object Button1: TButton
Addedclipboardutils.pas +40−0
@@ -0,0 +1,40 @@
1 unit ClipboardUtils;
2
3 {$mode delphi}
4
5 interface
6
7 uses
8 Classes, SysUtils, Constants, HugeDatatypes;
9
10 type
11 TModplugClipboardCell = packed record
12 Pipe: Char;
13 Note: array[0..2] of Char;
14 Instrument: array[0..1] of Char;
15 Volume: array[0..2] of Char;
16 EffectCode: Char;
17 EffectParam: array[0..2] of Char;
18 end;
19
20 function ModplugToHuge(MPCell: TModplugClipboardCell): TCell;
21
22 implementation
23
24 function ModplugToHuge(MPCell: TModplugClipboardCell): TCell;
25 begin
26 if not NoteToCodeMap.TryGetData(String(MPCell.Note), Result.Note) then begin
27 Result := nil;
28 exit;
29 end;
30 try
31 Result.Instrument := StrToInt(String(MPCell.Instrument));
32 Result.EffectCode := StrToInt(String(MPCell.EffectCode));
33 Result.EffectParam := StrToInt(String(MPCell.EffectParam));
34 except
35 on E: EConvertError do Result := nil;
36 end;
37 end;
38
39 end.
40
Modifiedconstants.pas +237−38
@@ -9,7 +9,9 @@ uses
9 9
10 type 10 type
11 TNoteMap = specialize TFPGMap<Integer, String>; 11 TNoteMap = specialize TFPGMap<Integer, String>;
12 TNoteToCodeMap = specialize TFPGMap<String, Integer>;
12 TKeybindings = specialize TFPGmap<Word, Integer>; 13 TKeybindings = specialize TFPGmap<Word, Integer>;
14 TNoteToFreqMap = specialize TFPGMap<Integer, Integer>;
13 15
14 const 16 const
15 // Sound controller registers 17 // Sound controller registers
@@ -32,8 +34,83 @@ const
32 NR43 = $FF22; 34 NR43 = $FF22;
33 NR44 = $FF23; 35 NR44 = $FF23;
34 36
37 C_3 = 0;
38 Cs3 = 1;
39 D_3 = 2;
40 Ds3 = 3;
41 E_3 = 4;
42 F_3 = 5;
43 Fs3 = 6;
44 G_3 = 7;
45 Gs3 = 8;
46 A_3 = 9;
47 As3 = 10;
48 B_3 = 11;
49 C_4 = 12;
50 Cs4 = 13;
51 D_4 = 14;
52 Ds4 = 15;
53 E_4 = 16;
54 F_4 = 17;
55 Fs4 = 18;
56 G_4 = 19;
57 Gs4 = 20;
58 A_4 = 21;
59 As4 = 22;
60 B_4 = 23;
61 C_5 = 24;
62 Cs5 = 25;
63 D_5 = 26;
64 Ds5 = 27;
65 E_5 = 28;
66 F_5 = 29;
67 Fs5 = 30;
68 G_5 = 31;
69 Gs5 = 32;
70 A_5 = 33;
71 As5 = 34;
72 B_5 = 35;
73 C_6 = 36;
74 Cs6 = 37;
75 D_6 = 38;
76 Ds6 = 39;
77 E_6 = 40;
78 F_6 = 41;
79 Fs6 = 42;
80 G_6 = 43;
81 Gs6 = 44;
82 A_6 = 45;
83 As6 = 46;
84 B_6 = 47;
85 C_7 = 48;
86 Cs7 = 49;
87 D_7 = 50;
88 Ds7 = 51;
89 E_7 = 52;
90 F_7 = 53;
91 Fs7 = 54;
92 G_7 = 55;
93 Gs7 = 56;
94 A_7 = 57;
95 As7 = 58;
96 B_7 = 59;
97 C_8 = 60;
98 Cs8 = 61;
99 D_8 = 62;
100 Ds8 = 63;
101 E_8 = 64;
102 F_8 = 65;
103 Fs8 = 66;
104 G_8 = 67;
105 Gs8 = 68;
106 A_8 = 69;
107 As8 = 70;
108 B_8 = 71;
109 LAST_NOTE = 72;
110 NO_NOTE = 90;
111
35 // Note constants. These will probably go in a dictionary instead later 112 // Note constants. These will probably go in a dictionary instead later
36 C_3 = 44; 113 {C_3 = 44;
37 CS3 = 156; 114 CS3 = 156;
38 D_3 = 262; 115 D_3 = 262;
39 DS3 = 363; 116 DS3 = 363;
@@ -104,19 +181,29 @@ const
104 GS8 = 2009; 181 GS8 = 2009;
105 A_8 = 2011; 182 A_8 = 2011;
106 AS8 = 2013; 183 AS8 = 2013;
107 B_8 = 2015; 184 B_8 = 2015;}
108 185
109 var 186 var
110 NoteMap: TNoteMap; 187 NoteMap: TNoteMap;
111 Keybindings: TKeybindings; 188 Keybindings: TKeybindings;
189 NotesToFreqs: TNoteToFreqMap;
190 NoteToCodeMap: TNoteToCodeMap;
191
192 function NoteCodeToString(NoteCode: Integer): String;
112 193
113 implementation 194 implementation
114 195
115 uses SysUtils; 196 function NoteCodeToString(NoteCode: Integer): String;
197 begin
198 if not NoteMap.TryGetData(NoteCode, Result) then
199 Result := '...';
200 end;
116 201
117 begin 202 begin
118 NoteMap := TNoteMap.Create; 203 NoteMap := TNoteMap.Create;
119 Keybindings := TKeybindings.Create; 204 Keybindings := TKeybindings.Create;
205 NotesToFreqs := TNoteToFreqMap.Create;
206 NoteToCodeMap := TNoteToCodeMap.Create;
120 207
121 Keybindings.Add(Ord('Q'), C_4); 208 Keybindings.Add(Ord('Q'), C_4);
122 Keybindings.Add(Ord('W'), CS4); 209 Keybindings.Add(Ord('W'), CS4);
@@ -153,39 +240,151 @@ begin
153 Keybindings.Add(Ord('.'), GS6); 240 Keybindings.Add(Ord('.'), GS6);
154 Keybindings.Add(Ord('/'), A_6); 241 Keybindings.Add(Ord('/'), A_6);
155 242
156 NoteMap.Add(C_4, 'C_4'); 243 NoteToCodeMap.add('C-3', C_3);
157 NoteMap.Add(CS4, 'C#4'); 244 NoteToCodeMap.add('C#3', Cs3);
158 NoteMap.Add(D_4, 'D_4'); 245 NoteToCodeMap.add('D-3', D_3);
159 NoteMap.Add(DS4, 'D#4'); 246 NoteToCodeMap.add('D#3', Ds3);
160 NoteMap.Add(E_4, 'E_4'); 247 NoteToCodeMap.add('E-3', E_3);
161 NoteMap.Add(F_4, 'F_4'); 248 NoteToCodeMap.add('F-3', F_3);
162 NoteMap.Add(FS4, 'F#4'); 249 NoteToCodeMap.add('F#3', Fs3);
163 NoteMap.Add(G_4, 'G_4'); 250 NoteToCodeMap.add('G-3', G_3);
164 NoteMap.Add(GS4, 'G#4'); 251 NoteToCodeMap.add('G#3', Gs3);
165 NoteMap.Add(A_4, 'A_4'); 252 NoteToCodeMap.add('A-3', A_3);
166 NoteMap.Add(AS4, 'A#4'); 253 NoteToCodeMap.add('A#3', As3);
167 NoteMap.Add(B_4, 'B_4'); 254 NoteToCodeMap.add('B-3', B_3);
168 NoteMap.Add(B_5, 'B_5'); 255 NoteToCodeMap.add('C-4', C_4);
169 NoteMap.Add(C_5, 'C_5'); 256 NoteToCodeMap.add('C#4', Cs4);
170 NoteMap.Add(CS5, 'C#5'); 257 NoteToCodeMap.add('D-4', D_4);
171 NoteMap.Add(D_5, 'D_5'); 258 NoteToCodeMap.add('D#4', Ds4);
172 NoteMap.Add(DS5, 'D#5'); 259 NoteToCodeMap.add('E-4', E_4);
173 NoteMap.Add(E_5, 'E_5'); 260 NoteToCodeMap.add('F-4', F_4);
174 NoteMap.Add(F_5, 'F_5'); 261 NoteToCodeMap.add('F#4', Fs4);
175 NoteMap.Add(FS5, 'F#5'); 262 NoteToCodeMap.add('G-4', G_4);
176 NoteMap.Add(G_5, 'G_5'); 263 NoteToCodeMap.add('G#4', Gs4);
177 NoteMap.Add(GS5, 'G#5'); 264 NoteToCodeMap.add('A-4', A_4);
178 NoteMap.Add(A_5, 'A_5'); 265 NoteToCodeMap.add('A#4', As4);
179 NoteMap.Add(AS5, 'A#5'); 266 NoteToCodeMap.add('B-4', B_4);
180 NoteMap.Add(C_6, 'C_6'); 267 NoteToCodeMap.add('C-5', C_5);
181 NoteMap.Add(CS6, 'C#6'); 268 NoteToCodeMap.add('C#5', Cs5);
182 NoteMap.Add(D_6, 'D_6'); 269 NoteToCodeMap.add('D-5', D_5);
183 NoteMap.Add(DS6, 'D#6'); 270 NoteToCodeMap.add('D#5', Ds5);
184 NoteMap.Add(E_6, 'E_6'); 271 NoteToCodeMap.add('E-5', E_5);
185 NoteMap.Add(F_6, 'F_6'); 272 NoteToCodeMap.add('F-5', F_5);
186 NoteMap.Add(FS6, 'F#6'); 273 NoteToCodeMap.add('F#5', Fs5);
187 NoteMap.Add(G_6, 'G_6'); 274 NoteToCodeMap.add('G-5', G_5);
188 NoteMap.Add(GS6, 'G#6'); 275 NoteToCodeMap.add('G#5', Gs5);
189 NoteMap.Add(A_6, 'A_6'); 276 NoteToCodeMap.add('A-5', A_5);
190 end. 277 NoteToCodeMap.add('A#5', As5);
278 NoteToCodeMap.add('B-5', B_5);
279 NoteToCodeMap.add('C-6', C_6);
280 NoteToCodeMap.add('C#6', Cs6);
281 NoteToCodeMap.add('D-6', D_6);
282 NoteToCodeMap.add('D#6', Ds6);
283 NoteToCodeMap.add('E-6', E_6);
284 NoteToCodeMap.add('F-6', F_6);
285 NoteToCodeMap.add('F#6', Fs6);
286 NoteToCodeMap.add('G-6', G_6);
287 NoteToCodeMap.add('G#6', Gs6);
288 NoteToCodeMap.add('A-6', A_6);
289 NoteToCodeMap.add('A#6', As6);
290 NoteToCodeMap.add('B-6', B_6);
291 NoteToCodeMap.add('C-7', C_7);
292 NoteToCodeMap.add('C#7', Cs7);
293 NoteToCodeMap.add('D-7', D_7);
294 NoteToCodeMap.add('D#7', Ds7);
295 NoteToCodeMap.add('E-7', E_7);
296 NoteToCodeMap.add('F-7', F_7);
297 NoteToCodeMap.add('F#7', Fs7);
298 NoteToCodeMap.add('G-7', G_7);
299 NoteToCodeMap.add('G#7', Gs7);
300 NoteToCodeMap.add('A-7', A_7);
301 NoteToCodeMap.add('A#7', As7);
302 NoteToCodeMap.add('B-7', B_7);
303 NoteToCodeMap.add('C-8', C_8);
304 NoteToCodeMap.add('C#8', Cs8);
305 NoteToCodeMap.add('D-8', D_8);
306 NoteToCodeMap.add('D#8', Ds8);
307 NoteToCodeMap.add('E-8', E_8);
308 NoteToCodeMap.add('F-8', F_8);
309 NoteToCodeMap.add('F#8', Fs8);
310 NoteToCodeMap.add('G-8', G_8);
311 NoteToCodeMap.add('G#8', Gs8);
312 NoteToCodeMap.add('A-8', A_8);
313 NoteToCodeMap.add('A#8', As8);
314 NoteToCodeMap.add('B-8', B_8);
191 315
316 NoteMap.add(C_3, 'C-3');
317 NoteMap.add(Cs3, 'C#3');
318 NoteMap.add(D_3, 'D-3');
319 NoteMap.add(Ds3, 'D#3');
320 NoteMap.add(E_3, 'E-3');
321 NoteMap.add(F_3, 'F-3');
322 NoteMap.add(Fs3, 'F#3');
323 NoteMap.add(G_3, 'G-3');
324 NoteMap.add(Gs3, 'G#3');
325 NoteMap.add(A_3, 'A-3');
326 NoteMap.add(As3, 'A#3');
327 NoteMap.add(B_3, 'B-3');
328 NoteMap.add(C_4, 'C-4');
329 NoteMap.add(Cs4, 'C#4');
330 NoteMap.add(D_4, 'D-4');
331 NoteMap.add(Ds4, 'D#4');
332 NoteMap.add(E_4, 'E-4');
333 NoteMap.add(F_4, 'F-4');
334 NoteMap.add(Fs4, 'F#4');
335 NoteMap.add(G_4, 'G-4');
336 NoteMap.add(Gs4, 'G#4');
337 NoteMap.add(A_4, 'A-4');
338 NoteMap.add(As4, 'A#4');
339 NoteMap.add(B_4, 'B-4');
340 NoteMap.add(C_5, 'C-5');
341 NoteMap.add(Cs5, 'C#5');
342 NoteMap.add(D_5, 'D-5');
343 NoteMap.add(Ds5, 'D#5');
344 NoteMap.add(E_5, 'E-5');
345 NoteMap.add(F_5, 'F-5');
346 NoteMap.add(Fs5, 'F#5');
347 NoteMap.add(G_5, 'G-5');
348 NoteMap.add(Gs5, 'G#5');
349 NoteMap.add(A_5, 'A-5');
350 NoteMap.add(As5, 'A#5');
351 NoteMap.add(B_5, 'B-5');
352 NoteMap.add(C_6, 'C-6');
353 NoteMap.add(Cs6, 'C#6');
354 NoteMap.add(D_6, 'D-6');
355 NoteMap.add(Ds6, 'D#6');
356 NoteMap.add(E_6, 'E-6');
357 NoteMap.add(F_6, 'F-6');
358 NoteMap.add(Fs6, 'F#6');
359 NoteMap.add(G_6, 'G-6');
360 NoteMap.add(Gs6, 'G#6');
361 NoteMap.add(A_6, 'A-6');
362 NoteMap.add(As6, 'A#6');
363 NoteMap.add(B_6, 'B-6');
364 NoteMap.add(C_7, 'C-7');
365 NoteMap.add(Cs7, 'C#7');
366 NoteMap.add(D_7, 'D-7');
367 NoteMap.add(Ds7, 'D#7');
368 NoteMap.add(E_7, 'E-7');
369 NoteMap.add(F_7, 'F-7');
370 NoteMap.add(Fs7, 'F#7');
371 NoteMap.add(G_7, 'G-7');
372 NoteMap.add(Gs7, 'G#7');
373 NoteMap.add(A_7, 'A-7');
374 NoteMap.add(As7, 'A#7');
375 NoteMap.add(B_7, 'B-7');
376 NoteMap.add(C_8, 'C-8');
377 NoteMap.add(Cs8, 'C#8');
378 NoteMap.add(D_8, 'D-8');
379 NoteMap.add(Ds8, 'D#8');
380 NoteMap.add(E_8, 'E-8');
381 NoteMap.add(F_8, 'F-8');
382 NoteMap.add(Fs8, 'F#8');
383 NoteMap.add(G_8, 'G-8');
384 NoteMap.add(Gs8, 'G#8');
385 NoteMap.add(A_8, 'A-8');
386 NoteMap.add(As8, 'A#8');
387 NoteMap.add(B_8, 'B-8');
388
389
390 end.
Addedhugedatatypes.pas +21−0
@@ -0,0 +1,21 @@
1 unit HugeDatatypes;
2
3 {$mode delphi}
4
5 interface
6
7 uses
8 Classes, SysUtils;
9
10 type
11 TCell = record
12 Note: Integer;
13 Instrument: Integer;
14 EffectCode: Integer;
15 EffectParams: Integer;
16 end;
17
18 implementation
19
20 end.
21
Addedpatterns.pas +18−0
@@ -0,0 +1,18 @@
1 unit Patterns;
2
3 {$mode delphi}
4
5 interface
6
7 uses
8 Classes, SysUtils;
9
10 type
11 TPattern = record
12
13 end;
14
15 implementation
16
17 end.
18
Modifiedsong.pas +10−4
@@ -4,17 +4,23 @@ unit Song;
4 4
5 interface 5 interface
6 6
7 uses instruments, waves; 7 uses instruments, waves, patterns;
8 8
9 type 9 type
10
11 { TSong }
12
10 TSong = record 13 TSong = record
11 Name: String; 14 Name: ShortString;
12 Artist: String; 15 Artist: ShortString;
13 Comment: String; 16 Comment: ShortString;
14 17
15 Instruments: array[1..15] of TInstrument; 18 Instruments: array[1..15] of TInstrument;
16 Waves: array[0..15] of TWave; 19 Waves: array[0..15] of TWave;
17 20
21 Patterns: array of TPattern;
22 OrderMatrix: array of integer;
23
18 TicksPerRow: Integer; 24 TicksPerRow: Integer;
19 end; 25 end;
20 26
Modifiedtracker.lfm +74−28
@@ -1,7 +1,7 @@
1 object frmTracker: TfrmTracker 1 object frmTracker: TfrmTracker
2 Left = 986 2 Left = 1560
3 Height = 1298 3 Height = 1298
4 Top = 460 4 Top = 529
5 Width = 1893 5 Width = 1893
6 Caption = 'hUGETracker' 6 Caption = 'hUGETracker'
7 ClientHeight = 1268 7 ClientHeight = 1268
@@ -55,14 +55,14 @@ object frmTracker: TfrmTracker
55 Height = 930 55 Height = 930
56 Top = 0 56 Top = 0
57 Width = 1595 57 Width = 1595
58 ActivePage = InstrumentTabSheet 58 ActivePage = CommentsTabSheet
59 Align = alClient 59 Align = alClient
60 ParentFont = False 60 ParentFont = False
61 TabIndex = 2 61 TabIndex = 4
62 TabOrder = 0 62 TabOrder = 0
63 object GeneralTabSheet: TTabSheet 63 object GeneralTabSheet: TTabSheet
64 Caption = 'General' 64 Caption = 'General'
65 ClientHeight = 927 65 ClientHeight = 892
66 ClientWidth = 1587 66 ClientWidth = 1587
67 ParentFont = False 67 ParentFont = False
68 object SongInformationGroupbox: TGroupBox 68 object SongInformationGroupbox: TGroupBox
@@ -120,14 +120,14 @@ object frmTracker: TfrmTracker
120 ParentColor = False 120 ParentColor = False
121 ParentFont = False 121 ParentFont = False
122 end 122 end
123 object SpinEdit1: TSpinEdit 123 object TicksPerRowSpinEdit: TSpinEdit
124 Left = 199 124 Left = 199
125 Height = 33 125 Height = 33
126 Top = 110 126 Top = 110
127 Width = 75 127 Width = 75
128 MaxValue = 20 128 MaxValue = 20
129 MinValue = 1 129 MinValue = 1
130 OnChange = SpinEdit1Change 130 OnChange = TicksPerRowSpinEditChange
131 ParentFont = False 131 ParentFont = False
132 TabOrder = 2 132 TabOrder = 2
133 Value = 1 133 Value = 1
@@ -136,7 +136,25 @@ object frmTracker: TfrmTracker
136 end 136 end
137 object PatternTabSheet: TTabSheet 137 object PatternTabSheet: TTabSheet
138 Caption = 'Patterns' 138 Caption = 'Patterns'
139 ClientHeight = 892
140 ClientWidth = 1587
139 ParentFont = False 141 ParentFont = False
142 object ScrollBox1: TScrollBox
143 Left = 0
144 Height = 892
145 Top = 0
146 Width = 1587
147 HorzScrollBar.Increment = 1
148 HorzScrollBar.Page = 1
149 HorzScrollBar.Smooth = True
150 HorzScrollBar.Tracking = True
151 VertScrollBar.Increment = 1
152 VertScrollBar.Page = 1
153 VertScrollBar.Smooth = True
154 VertScrollBar.Tracking = True
155 Align = alClient
156 TabOrder = 0
157 end
140 end 158 end
141 object InstrumentTabSheet: TTabSheet 159 object InstrumentTabSheet: TTabSheet
142 Caption = 'Instruments' 160 Caption = 'Instruments'
@@ -988,14 +1006,14 @@ object frmTracker: TfrmTracker
988 end 1006 end
989 object CommentsTabSheet: TTabSheet 1007 object CommentsTabSheet: TTabSheet
990 Caption = 'Comments' 1008 Caption = 'Comments'
991 ClientHeight = 927 1009 ClientHeight = 892
992 ClientWidth = 1587 1010 ClientWidth = 1587
993 ParentFont = False 1011 ParentFont = False
994 object CommentMemo: TMemo 1012 object CommentMemo: TMemo
995 AnchorSideTop.Control = Label17 1013 AnchorSideTop.Control = Label17
996 AnchorSideTop.Side = asrBottom 1014 AnchorSideTop.Side = asrBottom
997 Left = 0 1015 Left = 0
998 Height = 870 1016 Height = 835
999 Top = 57 1017 Top = 57
1000 Width = 1587 1018 Width = 1587
1001 Align = alBottom 1019 Align = alBottom
@@ -1017,14 +1035,14 @@ object frmTracker: TfrmTracker
1017 end 1035 end
1018 object RoutinesTabSheet: TTabSheet 1036 object RoutinesTabSheet: TTabSheet
1019 Caption = 'Routines' 1037 Caption = 'Routines'
1020 ClientHeight = 927 1038 ClientHeight = 892
1021 ClientWidth = 1587 1039 ClientWidth = 1587
1022 ParentFont = False 1040 ParentFont = False
1023 inline RoutineSynedit: TSynEdit 1041 inline RoutineSynedit: TSynEdit
1024 AnchorSideTop.Control = Label19 1042 AnchorSideTop.Control = Label19
1025 AnchorSideTop.Side = asrBottom 1043 AnchorSideTop.Side = asrBottom
1026 Left = 0 1044 Left = 0
1027 Height = 722 1045 Height = 687
1028 Top = 205 1046 Top = 205
1029 Width = 1587 1047 Width = 1587
1030 Align = alBottom 1048 Align = alBottom
@@ -1632,13 +1650,13 @@ object frmTracker: TfrmTracker
1632 object MenuItem2: TMenuItem 1650 object MenuItem2: TMenuItem
1633 Caption = 'Edit' 1651 Caption = 'Edit'
1634 object MenuItem6: TMenuItem 1652 object MenuItem6: TMenuItem
1635 Action = EditCopy1 1653 Action = CopyAction
1636 end 1654 end
1637 object MenuItem7: TMenuItem 1655 object MenuItem7: TMenuItem
1638 Action = EditCut1 1656 Action = CutAction
1639 end 1657 end
1640 object MenuItem9: TMenuItem 1658 object MenuItem9: TMenuItem
1641 Action = EditPaste1 1659 Action = PasteAction
1642 end 1660 end
1643 object N1: TMenuItem 1661 object N1: TMenuItem
1644 Caption = '-' 1662 Caption = '-'
@@ -1673,9 +1691,13 @@ object frmTracker: TfrmTracker
1673 end 1691 end
1674 end 1692 end
1675 object DebugButton: TMenuItem 1693 object DebugButton: TMenuItem
1676 Caption = 'Debug shite' 1694 Caption = 'Debug play note'
1677 OnClick = DebugButtonClick 1695 OnClick = DebugButtonClick
1678 end 1696 end
1697 object MenuItem16: TMenuItem
1698 Caption = 'Debug shite'
1699 OnClick = MenuItem16Click
1700 end
1679 end 1701 end
1680 object ActionList1: TActionList 1702 object ActionList1: TActionList
1681 Images = ImageList1 1703 Images = ImageList1
@@ -1687,18 +1709,48 @@ object frmTracker: TfrmTracker
1687 Hint = 'Open' 1709 Hint = 'Open'
1688 ImageIndex = 42 1710 ImageIndex = 42
1689 ShortCut = 16463 1711 ShortCut = 16463
1712 OnAccept = FileOpen1Accept
1690 end 1713 end
1691 object FileSaveAs1: TFileSaveAs 1714 object FileSaveAs1: TFileSaveAs
1692 Category = 'File' 1715 Category = 'File'
1693 Caption = 'Save &As ...' 1716 Caption = 'Save &As ...'
1694 Hint = 'Save As' 1717 Hint = 'Save As'
1695 ImageIndex = 59 1718 ImageIndex = 59
1719 OnAccept = FileSaveAs1Accept
1696 end 1720 end
1697 object EditCut1: TEditCut 1721 object FileExit1: TFileExit
1722 Category = 'File'
1723 Caption = 'E&xit'
1724 Hint = 'Exit'
1725 end
1726 object HelpLookupManual: TAction
1727 Category = 'Help'
1728 Caption = 'Look up in &Manual ...'
1729 ImageIndex = 19
1730 OnExecute = HelpLookupManualExecute
1731 ShortCut = 32845
1732 end
1733 object CopyAction: TAction
1734 Category = 'Edit'
1735 Caption = '&Copy'
1736 Hint = 'Copy'
1737 ImageIndex = 9
1738 OnExecute = CopyActionExecute
1739 ShortCut = 16451
1740 end
1741 object PasteAction: TAction
1742 Category = 'Edit'
1743 Caption = '&Paste'
1744 Hint = 'Paste'
1745 ImageIndex = 47
1746 OnExecute = PasteActionExecute
1747 ShortCut = 16470
1748 end
1749 object CutAction: TAction
1698 Category = 'Edit' 1750 Category = 'Edit'
1699 Caption = 'Cu&t' 1751 Caption = 'Cu&t'
1700 Hint = 'Cut'
1701 ImageIndex = 10 1752 ImageIndex = 10
1753 OnExecute = CutActionExecute
1702 ShortCut = 16472 1754 ShortCut = 16472
1703 end 1755 end
1704 object EditCopy1: TEditCopy 1756 object EditCopy1: TEditCopy
@@ -1736,17 +1788,11 @@ object frmTracker: TfrmTracker
1736 ImageIndex = 39 1788 ImageIndex = 39
1737 ShortCut = 16449 1789 ShortCut = 16449
1738 end 1790 end
1739 object FileExit1: TFileExit 1791 object EditCut1: TEditCut
1740 Category = 'File' 1792 Category = 'Edit'
1741 Caption = 'E&xit' 1793 Caption = 'Cu&t'
1742 Hint = 'Exit' 1794 Hint = 'Cut'
1743 end 1795 ShortCut = 16472
1744 object HelpLookupManual: TAction
1745 Category = 'Help'
1746 Caption = 'Look up in &Manual ...'
1747 ImageIndex = 19
1748 OnExecute = HelpLookupManualExecute
1749 ShortCut = 32845
1750 end 1796 end
1751 end 1797 end
1752 object ImageList1: TImageList 1798 object ImageList1: TImageList
Modifiedtracker.pas +88−16
@@ -6,19 +6,22 @@ interface
6 6
7 uses 7 uses
8 Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, ComCtrls, 8 Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, ComCtrls,
9 Menus, Spin, StdCtrls, Grids, ValEdit, PopupNotifier, ActnList, StdActns, 9 Menus, Spin, StdCtrls, ActnList, StdActns, SynEdit,
10 SynEdit, VirtualTrees, ECSlider, ECProgressBar, math, Instruments, Waves, 10 ECSlider, ECProgressBar, math, Instruments, Waves, Song, EmulationThread,
11 Song, EmulationThread, Utils, Constants, StrUtils, mainloop, sound, vars, 11 Utils, Constants, sound, vars, machine, about_hugetracker, Clipbrd, ValEdit,
12 machine, about_hugetracker; 12 Grids, TrackerGrid, lclintf, lmessages;
13 13
14 type 14 type
15 { TfrmTracker } 15 { TfrmTracker }
16 16
17 TfrmTracker = class(TForm) 17 TfrmTracker = class(TForm)
18 CutAction: TAction;
19 EditCut1: TEditCut;
20 PasteAction: TAction;
21 CopyAction: TAction;
18 HelpLookupManual: TAction; 22 HelpLookupManual: TAction;
19 ActionList1: TActionList; 23 ActionList1: TActionList;
20 EditCopy1: TEditCopy; 24 EditCopy1: TEditCopy;
21 EditCut1: TEditCut;
22 EditDelete1: TEditDelete; 25 EditDelete1: TEditDelete;
23 EditPaste1: TEditPaste; 26 EditPaste1: TEditPaste;
24 EditSelectAll1: TEditSelectAll; 27 EditSelectAll1: TEditSelectAll;
@@ -39,6 +42,7 @@ type
39 MenuItem13: TMenuItem; 42 MenuItem13: TMenuItem;
40 MenuItem14: TMenuItem; 43 MenuItem14: TMenuItem;
41 MenuItem15: TMenuItem; 44 MenuItem15: TMenuItem;
45 MenuItem16: TMenuItem;
42 N3: TMenuItem; 46 N3: TMenuItem;
43 N2: TMenuItem; 47 N2: TMenuItem;
44 N1: TMenuItem; 48 N1: TMenuItem;
@@ -48,7 +52,8 @@ type
48 MenuItem9: TMenuItem; 52 MenuItem9: TMenuItem;
49 OpenDialog1: TOpenDialog; 53 OpenDialog1: TOpenDialog;
50 SaveDialog1: TSaveDialog; 54 SaveDialog1: TSaveDialog;
51 SpinEdit1: TSpinEdit; 55 ScrollBox1: TScrollBox;
56 TicksPerRowSpinEdit: TSpinEdit;
52 ToolBar1: TToolBar; 57 ToolBar1: TToolBar;
53 ToolButton1: TToolButton; 58 ToolButton1: TToolButton;
54 PanicToolButton: TToolButton; 59 PanicToolButton: TToolButton;
@@ -126,6 +131,11 @@ type
126 NoiseFreqSpinner: TECSpinPosition; 131 NoiseFreqSpinner: TECSpinPosition;
127 DivRatioSpinner: TECSpinPosition; 132 DivRatioSpinner: TECSpinPosition;
128 TreeView1: TTreeView; 133 TreeView1: TTreeView;
134 TrackerGrid: TTrackerGrid;
135 procedure CopyActionExecute(Sender: TObject);
136 procedure CutActionExecute(Sender: TObject);
137 procedure FileOpen1Accept(Sender: TObject);
138 procedure FileSaveAs1Accept(Sender: TObject);
129 procedure HelpLookupManualExecute(Sender: TObject); 139 procedure HelpLookupManualExecute(Sender: TObject);
130 procedure ArtistEditChange(Sender: TObject); 140 procedure ArtistEditChange(Sender: TObject);
131 procedure CommentMemoChange(Sender: TObject); 141 procedure CommentMemoChange(Sender: TObject);
@@ -143,10 +153,12 @@ type
143 procedure InstrumentNumberSpinnerChange(Sender: TObject); 153 procedure InstrumentNumberSpinnerChange(Sender: TObject);
144 procedure LengthSpinnerChange(Sender: TObject); 154 procedure LengthSpinnerChange(Sender: TObject);
145 procedure DebugButtonClick(Sender: TObject); 155 procedure DebugButtonClick(Sender: TObject);
156 procedure MenuItem16Click(Sender: TObject);
146 procedure MenuItem5Click(Sender: TObject); 157 procedure MenuItem5Click(Sender: TObject);
147 procedure NoiseFreqSpinnerChange(Sender: TObject); 158 procedure NoiseFreqSpinnerChange(Sender: TObject);
148 procedure PanicToolButtonClick(Sender: TObject); 159 procedure PanicToolButtonClick(Sender: TObject);
149 procedure SpinEdit1Change(Sender: TObject); 160 procedure PasteActionExecute(Sender: TObject);
161 procedure TicksPerRowSpinEditChange(Sender: TObject);
150 procedure WaveEditNumberSpinnerChange(Sender: TObject); 162 procedure WaveEditNumberSpinnerChange(Sender: TObject);
151 procedure WaveEditPaintBoxMouseDown(Sender: TObject; Button: TMouseButton; 163 procedure WaveEditPaintBoxMouseDown(Sender: TObject; Button: TMouseButton;
152 Shift: TShiftState; X, Y: Integer); 164 Shift: TShiftState; X, Y: Integer);
@@ -184,6 +196,8 @@ type
184 procedure LoadInstrument(Instr: Integer); 196 procedure LoadInstrument(Instr: Integer);
185 procedure LoadWave(Wave: Integer); 197 procedure LoadWave(Wave: Integer);
186 198
199 procedure UpdateUIAfterLoad;
200
187 procedure DrawWaveform(PB: TPaintBox; Wave: TWave); 201 procedure DrawWaveform(PB: TPaintBox; Wave: TWave);
188 202
189 procedure PreviewInstrument(Freq: Integer; Instr: Integer); 203 procedure PreviewInstrument(Freq: Integer; Instr: Integer);
@@ -200,6 +214,18 @@ implementation
200 214
201 { TfrmTracker } 215 { TfrmTracker }
202 216
217 procedure TfrmTracker.UpdateUIAfterLoad;
218 begin
219 LoadInstrument(1);
220 LoadWave(0);
221
222 SongEdit.Text := Song.Name;
223 ArtistEdit.Text := Song.Artist;
224 CommentMemo.Text := Song.Comment;
225
226 TicksPerRowSpinEdit.Value := Song.TicksPerRow;
227 end;
228
203 procedure TfrmTracker.DrawWaveform(PB: TPaintBox; Wave: TWave); 229 procedure TfrmTracker.DrawWaveform(PB: TPaintBox; Wave: TWave);
204 var 230 var
205 Interval, HInterval: Integer; 231 Interval, HInterval: Integer;
@@ -258,14 +284,14 @@ begin
258 Spokeb($FF30+I, NewWaveform[I]); 284 Spokeb($FF30+I, NewWaveform[I]);
259 285
260 Regs := WaveInstrumentToRegisters(Freq, True, Song.Instruments[Instr]); 286 Regs := WaveInstrumentToRegisters(Freq, True, Song.Instruments[Instr]);
261 writeln(inttobin(Regs.NR30, 8, 20)); 287 {writeln(inttobin(Regs.NR30, 8, 20));
262 writeln(inttobin(Regs.NR31, 8, 20)); 288 writeln(inttobin(Regs.NR31, 8, 20));
263 writeln(inttobin(Regs.NR32, 8, 20)); 289 writeln(inttobin(Regs.NR32, 8, 20));
264 writeln(inttobin(Regs.NR33, 8, 20)); 290 writeln(inttobin(Regs.NR33, 8, 20));
265 writeln(inttobin(Regs.NR34, 8, 20)); 291 writeln(inttobin(Regs.NR34, 8, 20));}
266 292
267 Spokeb(NR30, Regs.NR30); 293 Spokeb(NR30, Regs.NR30);
268 Spokeb(NR31, Regs.NR31); 294 Spokeb(NR31, Regs.NR31); // TODO: Figure out why this isn't working?
269 Spokeb(NR32, Regs.NR32); 295 Spokeb(NR32, Regs.NR32);
270 Spokeb(NR33, Regs.NR33); 296 Spokeb(NR33, Regs.NR33);
271 Spokeb(NR34, Regs.NR34) 297 Spokeb(NR34, Regs.NR34)
@@ -500,6 +526,10 @@ begin
500 LoadInstrument(1); 526 LoadInstrument(1);
501 LoadWave(0); 527 LoadWave(0);
502 528
529 // Create pattern editor control
530 TrackerGrid := TTrackerGrid.Create(Self, ScrollBox1);
531 //TrackerGrid.Parent := ScrollBox1;
532
503 // Get the emulator ready to make sound... 533 // Get the emulator ready to make sound...
504 EmulationThread := TEmulationThread.Create; 534 EmulationThread := TEmulationThread.Create;
505 EmulationThread.Start; 535 EmulationThread.Start;
@@ -531,13 +561,13 @@ end;
531 561
532 procedure TfrmTracker.ImportWaveButtonClick(Sender: TObject); 562 procedure TfrmTracker.ImportWaveButtonClick(Sender: TObject);
533 var 563 var
534 F: file of byte; 564 F: file of TWave;
535 begin 565 begin
536 OpenDialog1.DefaultExt := '*.pcm'; 566 OpenDialog1.DefaultExt := '*.pcm';
537 if OpenDialog1.Execute then begin 567 if OpenDialog1.Execute then begin
538 assignfile(F, OpenDialog1.FileName); 568 assignfile(F, OpenDialog1.FileName);
539 reset(F); 569 reset(F);
540 BlockRead(F, Song.Waves[WaveEditNumberSpinner.Value], 32); 570 Read(F, Song.Waves[WaveEditNumberSpinner.Value]);
541 CloseFile(F); 571 CloseFile(F);
542 WaveEditPaintBox.Invalidate; 572 WaveEditPaintBox.Invalidate;
543 end; 573 end;
@@ -566,6 +596,43 @@ begin
566 596
567 end; 597 end;
568 598
599 procedure TfrmTracker.FileSaveAs1Accept(Sender: TObject);
600 {var
601 F: file of TSong;}
602 begin
603 {AssignFile(F, FileSaveAs1.Dialog.FileName);
604 Rewrite(F);
605 Write(F, Song);
606 CloseFile(F);}
607 end;
608
609 procedure TfrmTracker.FileOpen1Accept(Sender: TObject);
610 {var
611 F: file of TSong;}
612 begin
613 {AssignFile(F, FileOpen1.Dialog.FileName);
614 Reset(F);
615 Read(F, Song);
616 CloseFile(F);
617
618 UpdateUIAfterLoad;}
619 end;
620
621 procedure TfrmTracker.CutActionExecute(Sender: TObject);
622 begin
623 PostMessage(Screen.ActiveControl.Handle, LM_CUT, 0, 0);
624 end;
625
626 procedure TfrmTracker.CopyActionExecute(Sender: TObject);
627 begin
628 PostMessage(Screen.ActiveControl.Handle, LM_COPY, 0, 0);
629 end;
630
631 procedure TfrmTracker.PasteActionExecute(Sender: TObject);
632 begin
633 PostMessage(Screen.ActiveControl.Handle, LM_PASTE, 0, 0);
634 end;
635
569 procedure TfrmTracker.DivRatioSpinnerChange(Sender: TObject); 636 procedure TfrmTracker.DivRatioSpinnerChange(Sender: TObject);
570 begin 637 begin
571 CurrentInstrument^.DividingRatio := Round(DivRatioSpinner.Position); 638 CurrentInstrument^.DividingRatio := Round(DivRatioSpinner.Position);
@@ -590,12 +657,12 @@ begin
590 end; 657 end;
591 658
592 procedure TfrmTracker.ExportButtonClick(Sender: TObject); 659 procedure TfrmTracker.ExportButtonClick(Sender: TObject);
593 var F: file of Byte; 660 var F: file of TWave;
594 begin 661 begin
595 if SaveDialog1.Execute then begin 662 if SaveDialog1.Execute then begin
596 AssignFile(F, OpenDialog1.FileName); 663 AssignFile(F, OpenDialog1.FileName);
597 Rewrite(F); 664 Rewrite(F);
598 BlockWrite(F, CurrentWave^, 32); 665 Write(F, CurrentWave^);
599 CloseFile(F); 666 CloseFile(F);
600 end; 667 end;
601 end; 668 end;
@@ -620,6 +687,11 @@ begin
620 PreviewInstrument(C_5, InstrumentNumberSpinner.Value); 687 PreviewInstrument(C_5, InstrumentNumberSpinner.Value);
621 end; 688 end;
622 689
690 procedure TfrmTracker.MenuItem16Click(Sender: TObject);
691 begin
692 PostMessage(Screen.ActiveControl.Handle, LM_PASTE, 0, 0);
693 end;
694
623 procedure TfrmTracker.MenuItem5Click(Sender: TObject); 695 procedure TfrmTracker.MenuItem5Click(Sender: TObject);
624 var 696 var
625 AboutForm: TfrmAboutHugeTracker; 697 AboutForm: TfrmAboutHugeTracker;
@@ -652,9 +724,9 @@ begin
652 Spokeb(NR44, %10000000); 724 Spokeb(NR44, %10000000);
653 end; 725 end;
654 726
655 procedure TfrmTracker.SpinEdit1Change(Sender: TObject); 727 procedure TfrmTracker.TicksPerRowSpinEditChange(Sender: TObject);
656 begin 728 begin
657 Song.TicksPerRow := SpinEdit1.Value; 729 Song.TicksPerRow := TicksPerRowSpinEdit.Value;
658 end; 730 end;
659 731
660 procedure TfrmTracker.WaveEditNumberSpinnerChange(Sender: TObject); 732 procedure TfrmTracker.WaveEditNumberSpinnerChange(Sender: TObject);
Addedtrackergrid.pas +281−0
@@ -0,0 +1,281 @@
1 unit TrackerGrid;
2
3 {$mode delphi}
4
5 interface
6
7 uses
8 Classes, SysUtils, Controls, Graphics, Constants, LCLType, math,
9 LCLIntf, LMessages, ClipboardUtils, Clipbrd, HugeDatatypes;
10
11 const
12 clMisc = clMaroon;
13 clPitch = clYellow;
14 clVolume = clGreen;
15 clPan = clTeal;
16 clSong = clRed;
17
18 type
19 TCellPart = (cpNote, cpInstrument, cpEffect);
20
21 TSelectionPos = record
22 X, Y: Integer;
23 SelectedPart: set of TCellPart
24 end;
25
26 { TTrackerGrid }
27
28 TTrackerGrid = class(TCustomControl)
29 constructor Create(AOwner: TComponent; Parent: TWinControl);
30 procedure Paint; override;
31 procedure MouseDown(Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
32 override;
33 procedure KeyDown(var Key: Word; Shift: TShiftState); override;
34
35 procedure DoPaste(var Msg: TLMessage); message LM_PASTE;
36 procedure DoCopy(var Msg: TLMessage); message LM_COPY;
37 procedure DoCut(var Msg: TLMessage); message LM_CUT;
38
39 private
40 Cells: array[0..3, 0..63] of TCell;
41
42 ColumnWidth: Integer;
43 RowHeight: Integer;
44 CharHeight: Integer;
45 CharWidth: Integer;
46
47 CursorCell, OtherCell: TCell;
48
49 procedure RenderRow(Row: Integer);
50 procedure RenderCell(Cell: TCell);
51
52 function GetEffectColor(EffectCode: Integer): TColor;
53 function CellIndexToRect(X, Y: Integer): TRect;
54
55 public
56 Cursor, Other: TSelectionPos;
57 SelectedRow: Integer;
58 end;
59
60 implementation
61
62 function TTrackerGrid.CellIndexToRect(X, Y: Integer): TRect;
63 begin
64 Result.Left := X*ColumnWidth;
65 Result.Top := Y*RowHeight;
66 Result.Width := ColumnWidth;
67 Result.Height := RowHeight;
68 end;
69
70 { TTrackerGrid }
71
72 constructor TTrackerGrid.Create(AOwner: TComponent; Parent: TWinControl);
73 var
74 X, Y: Integer;
75 begin
76 inherited Create(AOwner);
77
78 ControlStyle := ControlStyle + [csCaptureMouse, csClickEvents,
79 csDoubleClicks];
80 Self.Parent := Parent;
81
82 // Kind of a hack
83 with Canvas.Font do begin
84 Name := 'Pixelite';
85 Size := 12;
86 ColumnWidth := GetTextWidth('C-501v64C01');
87 RowHeight := GetTextHeight('C-501v64C01');
88
89 CharHeight := RowHeight;
90 CharWidth := GetTextWidth('C');
91 end;
92
93 Width := ColumnWidth*4;
94 Height := RowHeight*64;
95
96 for X := 0 to High(Cells) do
97 for Y := 0 to High(Cells[X]) do
98 Cells[X, Y].Note := NO_NOTE;
99 end;
100
101 procedure TTrackerGrid.Paint;
102 var
103 I: Integer;
104 P: TRect;
105 begin
106 inherited Paint;
107
108 with Canvas do begin
109 Brush.Color := RGBToColor(225, 219, 208);
110 Clear;
111
112 for I := 0 to 64 do begin
113 if (I mod 4) = 0 then begin
114 Brush.Color := RGBToColor(216, 209, 195);
115 FillRect(0, I*RowHeight, Width, (I+1)*RowHeight);
116 end;
117 if (I mod 16) = 0 then begin
118 Brush.Color := RGBToColor(206, 197, 181);
119 FillRect(0, I*RowHeight, Width, (I+1)*RowHeight);
120 end;
121 if I = SelectedRow then begin
122 Brush.Color := RGBToColor(169, 153, 122);
123 FillRect(0, I*RowHeight, Width, (I+1)*RowHeight);
124 end;
125
126 MoveTo(0, I*RowHeight);
127 RenderRow(I);
128 end;
129 end;
130
131 P := CellIndexToRect(Cursor.X, Cursor.Y);
132 with Cursor do begin
133 BitBlt(
134 Canvas.Handle,
135 P.Left,
136 P.Top,
137 P.Width,
138 P.Height,
139 Canvas.Handle,
140 P.Left,
141 P.Top,
142 DSTINVERT);
143 end;
144 end;
145
146 procedure TTrackerGrid.MouseDown(Button: TMouseButton; Shift: TShiftState; X,
147 Y: Integer);
148 var
149 SelectedColumn: Integer;
150 begin
151 inherited MouseDown(Button, Shift, X, Y);
152
153 if not (csDesigning in ComponentState) and CanFocus then
154 SetFocus;
155
156 SelectedRow := Round((Y/Height)*63);
157 SelectedColumn := Round((X/Width)*4);
158 with Cursor do begin
159 X := SelectedColumn;
160 Y := SelectedRow;
161 SelectedPart := [];
162 end;
163 CursorCell := Cells[SelectedColumn, SelectedRow];
164 Invalidate;
165 end;
166
167 procedure TTrackerGrid.KeyDown(var Key: Word; Shift: TShiftState);
168 begin
169 inherited KeyDown(Key, Shift);
170
171 case Key of
172 VK_UP: SelectedRow -= 1;
173 VK_DOWN: SelectedRow += 1;
174 end;
175
176 SelectedRow := Min(63, Max(0, SelectedRow));
177
178 Invalidate
179 end;
180
181 procedure TTrackerGrid.DoPaste(var Msg: TLMessage);
182 var
183 C: TCell;
184 X: TModplugClipboardCell;
185 ClipboardBytes: array of Byte;
186 begin
187 ClipboardBytes := TEncoding.UTF8.GetBytes(Clipboard.AsText);
188 Move(ClipboardBytes, X, sizeof(X));
189 C := ModplugToHuge(X);
190 end;
191
192 procedure TTrackerGrid.DoCopy(var Msg: TLMessage);
193 begin
194 //writeln('copying');
195 end;
196
197 procedure TTrackerGrid.DoCut(var Msg: TLMessage);
198 begin
199 //writeln('cutting');
200 end;
201
202 procedure TTrackerGrid.RenderRow(Row: Integer);
203 var
204 I: Integer;
205 begin
206 with Canvas do begin
207 Brush.Style := bsClear;
208 Pen.Color := RGBToColor(58, 52, 39);
209
210 for I := 0 to 4 do
211 RenderCell(Cells[I, Row]);
212 end;
213 end;
214
215 procedure TTrackerGrid.RenderCell(Cell: TCell);
216 var
217 NoteString: ShortString;
218 begin
219 with Canvas do begin
220 if NoteMap.TryGetData(Cell.Note, NoteString) then begin
221 Font.Color := clBlue;
222 TextOut(PenPos.X, PenPos.Y, NoteString);
223 end
224 else begin
225 Font.Color := clGray;
226 TextOut(PenPos.X, PenPos.Y, '...');
227 end;
228
229 if Cell.Instrument <> 0 then begin
230 Font.Color := clTeal;
231 TextOut(PenPos.X, PenPos.Y, IntToStr(Cell.Instrument));
232 end
233 else begin
234 Font.Color := clGray;
235 TextOut(PenPos.X, PenPos.Y, '..');
236 end;
237
238 //Font.Color := clDark; //clGreen;
239 Font.Color := clGray;
240 TextOut(PenPos.X, PenPos.Y, '...');
241
242 if Cell.EffectCode <> 0 then begin
243 Font.Color := GetEffectColor(Cell.EffectCode);
244 TextOut(
245 PenPos.X,
246 PenPos.Y,
247 IntToHex(Cell.EffectCode, 1) + IntToHex(Cell.EffectParams, 2)
248 );
249 end
250 else begin
251 Font.Color := clGray;
252 TextOut(PenPos.X, PenPos.Y, '...');
253 end;
254 end;
255 end;
256
257 function TTrackerGrid.GetEffectColor(EffectCode: Integer): TColor;
258 begin
259 Result := clBlack;
260 case EffectCode of
261 $0: Result := clMisc;
262 $1: Result := clPitch;
263 $2: Result := clPitch;
264 $3: Result := clPitch;
265 $4: Result := clPitch;
266 $5: Result := clSong;
267 $6: Result := clMisc;
268 $7: Result := clMisc;
269 $8: Result := clPan;
270 $9: Result := clSong;
271 $A: Result := clVolume;
272 $B: Result := clSong;
273 $C: Result := clVolume;
274 $D: Result := clSong;
275 $E: Result := clMisc;
276 $F: Result := clSong;
277 end;
278 end;
279
280 end.
281