Commit c389751

Nick committed on
WIP GBT import
commit c38975119e5ef1360b48683617455e7ee119870d parent 71b7470
5 changed files +341−38
ModifiedGBEmu.lpi +6−1
@@ -166,7 +166,7 @@
166 <PackageName Value="LCL"/> 166 <PackageName Value="LCL"/>
167 </Item6> 167 </Item6>
168 </RequiredPackages> 168 </RequiredPackages>
169 <Units Count="25"> 169 <Units Count="26">
170 <Unit0> 170 <Unit0>
171 <Filename Value="GBEmu.lpr"/> 171 <Filename Value="GBEmu.lpr"/>
172 <IsPartOfProject Value="True"/> 172 <IsPartOfProject Value="True"/>
@@ -298,6 +298,11 @@
298 <IsPartOfProject Value="True"/> 298 <IsPartOfProject Value="True"/>
299 <UnitName Value="NullStream"/> 299 <UnitName Value="NullStream"/>
300 </Unit24> 300 </Unit24>
301 <Unit25>
302 <Filename Value="modimport.pas"/>
303 <IsPartOfProject Value="True"/>
304 <UnitName Value="MODImport"/>
305 </Unit25>
301 </Units> 306 </Units>
302 </ProjectOptions> 307 </ProjectOptions>
303 <CompilerOptions> 308 <CompilerOptions>
Modifiedinstruments.pas +6−6
@@ -60,12 +60,12 @@ type
60 end; 60 end;
61 61
62 Bit = Boolean; 62 Bit = Boolean;
63 TwoBits = 0..3; 63 TwoBits = 0..%11;
64 ThreeBits = 0..7; 64 ThreeBits = 0..%111;
65 FourBits = 0..17; 65 FourBits = 0..%1111;
66 FiveBits = 0..31; 66 FiveBits = 0..%11111;
67 SixBits = 0..63; 67 SixBits = 0..%111111;
68 SevenBits = 0..127; 68 SevenBits = 0..%1111111;
69 EightBits = Byte; 69 EightBits = Byte;
70 70
71 TSweepRegister = bitpacked record 71 TSweepRegister = bitpacked record
Addedmodimport.pas +253−0
@@ -0,0 +1,253 @@
1 unit MODImport;
2
3 {$mode objfpc}{$H+}
4
5 interface
6
7 uses
8 Classes, SysUtils, Song, hugedatatypes, fgl, utils, constants;
9
10 type
11 TPeriodToCodeMap = specialize TFPGMap<Integer, Integer>;
12
13 // TODO: Find some way to de-duplicate these from the instruments file
14 // without a circular reference
15 Bit = Boolean;
16 TwoBits = 0..%11;
17 ThreeBits = 0..%111;
18 FourBits = 0..%1111;
19 FiveBits = 0..%11111;
20 SixBits = 0..%111111;
21 SevenBits = 0..%1111111;
22 EightBits = Byte;
23 TwelveBits = 0..%111111111111;
24
25 { TMODSample }
26
27 TMODSample = packed record
28 Name: array[0..21] of char; //string[21];
29 SampleLength: Word;
30 Finetune: Byte;
31 Volume: Byte;
32 RepeatPoint: Word;
33 RepeatLength: Word;
34 end;
35
36 { TMODRawRow }
37
38 TMODRawRow = packed array[0..3] of Byte;
39
40 { TMODRow }
41
42 TMODRow = bitpacked record
43 Note: Integer;
44 Instrument: Integer;
45 Effect: bitpacked record
46 case Boolean of
47 True: (Code, Params: Byte);
48 False: (Value: Word);
49 end
50 end;
51
52 TMODPattern = array[0..63] of array[1..4] of TMODRow;
53
54 { TMODFile }
55
56 TMODFile = packed record
57 Name: array[0..19] of Char; //string[19];
58 Samples: array[1..31] of TMODSample;
59 SongLen: Byte;
60 NumPatternsMagic: Byte;
61 Positions: array[0..127] of Byte;
62 MKMagic: array[0..3] of char; //string[3];
63 Patterns: array of TMODPattern;
64 end;
65
66 function LoadSongFromModStream(Stream: TStream): TSong;
67
68 var
69 PeriodsToCodeMap: TPeriodToCodeMap;
70
71 implementation
72
73 function RawRowToRegularRow(RawRow: TMODRawRow): TMODRow;
74 begin
75 Result.Note := ((RawRow[0] and %1111) shl 8) or RawRow[1];
76 Result.Effect.Code := RawRow[2] and %1111;
77 Result.Effect.Params := RawRow[3];
78 Result.Instrument := (RawRow[0] and %11110000) or ((RawRow[2] and %11110000) shr 4);
79 end;
80
81 function ConvertNote(Note: Integer): Integer;
82 begin
83 if Note = 0 then
84 Result := NO_NOTE
85 else
86 Result := PeriodsToCodeMap.KeyData[Note];
87 end;
88
89 function ConvertInstrument(Instr: Integer): Integer;
90 begin
91 if Instr = 0 then
92 Result := 0
93 else
94 Result := 1;
95 end;
96
97 procedure ConvertEffect(Code, Params: Integer; out OutCode: Integer; out OutParams: TEffectParams);
98 begin
99 case Code of
100 $C: begin
101 OutCode := $C;
102 OutParams.Value := ;
103 end;
104 else begin
105 OutCode := Code;
106 OutParams := Params;
107 end;
108 end
109 end;
110
111 function ConvertCell(MC: TMODRow): TCell;
112 begin
113 Result.Note := ConvertNote(MC.Note);
114 Result.Instrument := ConvertInstrument(MC.Instrument);
115 ConvertEffect(MC.Effect.Code, MC.Effect.Params, Result.EffectCode, Result.EffectParams);
116 end;
117
118 procedure TranscribePattern(MP: TMODPattern; P1, P2, P3, P4: PPattern);
119 var
120 I: Integer;
121 begin
122 for I := Low(MP) to High(MP) do begin
123 P1^[I] := ConvertCell(MP[I, 1]);
124 P2^[I] := ConvertCell(MP[I, 2]);
125 P3^[I] := ConvertCell(MP[I, 3]);
126 P4^[I] := ConvertCell(MP[I, 4]);
127 end;
128 end;
129
130 function LoadSongFromModStream(Stream: TStream): TSong;
131 var
132 ModFile: TMODFile;
133 I, J, K: Integer;
134 MaxOrder: Integer;
135 RawRow: TMODRawRow;
136 begin
137 Stream.Read(ModFile, SizeOf(ModFile) - SizeOf(ModFile.Patterns));
138 for I := Low(ModFile.Samples) to High(ModFile.Samples) do
139 with ModFile.Samples[I] do begin
140 SampleLength := BEtoN(SampleLength);
141 RepeatPoint := BEtoN(RepeatPoint);
142 RepeatLength := BEtoN(RepeatLength);
143 end;
144
145 MaxOrder := 0;
146 for I := Low(ModFile.Positions) to High(ModFile.Positions) do
147 if ModFile.Positions[I] > MaxOrder then
148 MaxOrder := ModFile.Positions[I];
149
150 SetLength(ModFile.Patterns, MaxOrder+1);
151 for I := 0 to MaxOrder do
152 for J := Low(TMODPattern) to High(TMODPattern) do
153 for K := 1 to 4 do begin
154 Stream.Read(RawRow, SizeOf(TMODRawRow));
155 ModFile.Patterns[I, J, K] := RawRowToRegularRow(RawRow);
156 end;
157
158 InitializeSong(Result);
159
160 for I := Low(ModFile.Patterns) to High(ModFile.Patterns) do
161 TranscribePattern(ModFile.Patterns[I],
162 Result.Patterns.CreateNewPattern(I*10 + 0),
163 Result.Patterns.CreateNewPattern(I*10 + 1),
164 Result.Patterns.CreateNewPattern(I*10 + 2),
165 Result.Patterns.CreateNewPattern(I*10 + 3));
166
167 for I := Low(Result.OrderMatrix) to High(Result.OrderMatrix) do begin
168 SetLength(Result.OrderMatrix[I], ModFile.SongLen);
169
170 for J := 0 to ModFile.SongLen do
171 Result.OrderMatrix[I, J] := (ModFile.Positions[J]*10) + I;
172 end;
173
174 Result.Name := ModFile.Name;
175 end;
176
177 begin
178 PeriodsToCodeMap := TPeriodToCodeMap.Create;
179
180 PeriodsToCodeMap.add(1712,0);
181 PeriodsToCodeMap.add(1616,1);
182 PeriodsToCodeMap.add(1524,2);
183 PeriodsToCodeMap.add(1440,3);
184 PeriodsToCodeMap.add(1356,4);
185 PeriodsToCodeMap.add(1280,5);
186 PeriodsToCodeMap.add(1208,6);
187 PeriodsToCodeMap.add(1140,7);
188 PeriodsToCodeMap.add(1076,8);
189 PeriodsToCodeMap.add(1016,9);
190 PeriodsToCodeMap.add(960,10);
191 PeriodsToCodeMap.add(907,11);
192 PeriodsToCodeMap.add(856,12);
193 PeriodsToCodeMap.add(808,13);
194 PeriodsToCodeMap.add(762,14);
195 PeriodsToCodeMap.add(720,15);
196 PeriodsToCodeMap.add(678,16);
197 PeriodsToCodeMap.add(640,17);
198 PeriodsToCodeMap.add(604,18);
199 PeriodsToCodeMap.add(570,19);
200 PeriodsToCodeMap.add(538,20);
201 PeriodsToCodeMap.add(508,21);
202 PeriodsToCodeMap.add(480,22);
203 PeriodsToCodeMap.add(453,23);
204 PeriodsToCodeMap.add(428,24);
205 PeriodsToCodeMap.add(404,25);
206 PeriodsToCodeMap.add(381,26);
207 PeriodsToCodeMap.add(360,27);
208 PeriodsToCodeMap.add(339,28);
209 PeriodsToCodeMap.add(320,29);
210 PeriodsToCodeMap.add(302,30);
211 PeriodsToCodeMap.add(285,31);
212 PeriodsToCodeMap.add(269,32);
213 PeriodsToCodeMap.add(254,33);
214 PeriodsToCodeMap.add(240,34);
215 PeriodsToCodeMap.add(226,35);
216 PeriodsToCodeMap.add(214,36);
217 PeriodsToCodeMap.add(202,37);
218 PeriodsToCodeMap.add(190,38);
219 PeriodsToCodeMap.add(180,39);
220 PeriodsToCodeMap.add(170,40);
221 PeriodsToCodeMap.add(160,41);
222 PeriodsToCodeMap.add(151,42);
223 PeriodsToCodeMap.add(143,43);
224 PeriodsToCodeMap.add(135,44);
225 PeriodsToCodeMap.add(127,45);
226 PeriodsToCodeMap.add(120,46);
227 PeriodsToCodeMap.add(113,47);
228 PeriodsToCodeMap.add(107,48);
229 PeriodsToCodeMap.add(101,49);
230 PeriodsToCodeMap.add(95, 50);
231 PeriodsToCodeMap.add(90, 51);
232 PeriodsToCodeMap.add(85, 52);
233 PeriodsToCodeMap.add(80, 53);
234 PeriodsToCodeMap.add(75, 54);
235 PeriodsToCodeMap.add(71, 55);
236 PeriodsToCodeMap.add(67, 56);
237 PeriodsToCodeMap.add(63, 57);
238 PeriodsToCodeMap.add(60, 58);
239 PeriodsToCodeMap.add(56, 59);
240 PeriodsToCodeMap.add(53, 60);
241 PeriodsToCodeMap.add(50, 61);
242 PeriodsToCodeMap.add(47, 62);
243 PeriodsToCodeMap.add(45, 63);
244 PeriodsToCodeMap.add(42, 64);
245 PeriodsToCodeMap.add(40, 65);
246 PeriodsToCodeMap.add(37, 66);
247 PeriodsToCodeMap.add(35, 67);
248 PeriodsToCodeMap.add(33, 68);
249 PeriodsToCodeMap.add(31, 69);
250 PeriodsToCodeMap.add(30, 70);
251 PeriodsToCodeMap.add(28, 71);
252 end.
253
Modifiedtracker.lfm +45−30
@@ -1,10 +1,10 @@
1 object frmTracker: TfrmTracker 1 object frmTracker: TfrmTracker
2 Left = 1889 2 Left = 1832
3 Height = 686 3 Height = 688
4 Top = 140 4 Top = 19
5 Width = 1166 5 Width = 1166
6 Caption = 'hUGETracker' 6 Caption = 'hUGETracker'
7 ClientHeight = 666 7 ClientHeight = 668
8 ClientWidth = 1166 8 ClientWidth = 1166
9 KeyPreview = True 9 KeyPreview = True
10 Menu = MainMenu1 10 Menu = MainMenu1
@@ -19,7 +19,7 @@ object frmTracker: TfrmTracker
19 LCLVersion = '2.0.6.0' 19 LCLVersion = '2.0.6.0'
20 object TreeView1: TTreeView 20 object TreeView1: TTreeView
21 Left = 0 21 Left = 0
22 Height = 440 22 Height = 442
23 Top = 203 23 Top = 203
24 Width = 193 24 Width = 193
25 Align = alLeft 25 Align = alLeft
@@ -37,24 +37,24 @@ object frmTracker: TfrmTracker
37 end 37 end
38 object Splitter1: TSplitter 38 object Splitter1: TSplitter
39 Left = 193 39 Left = 193
40 Height = 440 40 Height = 442
41 Top = 203 41 Top = 203
42 Width = 5 42 Width = 5
43 end 43 end
44 object Panel1: TPanel 44 object Panel1: TPanel
45 Left = 198 45 Left = 198
46 Height = 440 46 Height = 442
47 Top = 203 47 Top = 203
48 Width = 968 48 Width = 968
49 Align = alClient 49 Align = alClient
50 BevelOuter = bvNone 50 BevelOuter = bvNone
51 ClientHeight = 440 51 ClientHeight = 442
52 ClientWidth = 968 52 ClientWidth = 968
53 ParentFont = False 53 ParentFont = False
54 TabOrder = 2 54 TabOrder = 2
55 object PageControl1: TPageControl 55 object PageControl1: TPageControl
56 Left = 0 56 Left = 0
57 Height = 440 57 Height = 442
58 Top = 0 58 Top = 0
59 Width = 968 59 Width = 968
60 ActivePage = InstrumentTabSheet 60 ActivePage = InstrumentTabSheet
@@ -283,7 +283,7 @@ object frmTracker: TfrmTracker
283 end 283 end
284 object InstrumentTabSheet: TTabSheet 284 object InstrumentTabSheet: TTabSheet
285 Caption = 'Instruments' 285 Caption = 'Instruments'
286 ClientHeight = 412 286 ClientHeight = 414
287 ClientWidth = 960 287 ClientWidth = 960
288 ParentFont = False 288 ParentFont = False
289 object PaintBox1: TPaintBox 289 object PaintBox1: TPaintBox
@@ -291,7 +291,7 @@ object frmTracker: TfrmTracker
291 AnchorSideTop.Side = asrBottom 291 AnchorSideTop.Side = asrBottom
292 AnchorSideBottom.Side = asrBottom 292 AnchorSideBottom.Side = asrBottom
293 Left = 0 293 Left = 0
294 Height = 7 294 Height = 9
295 Hint = 'Preview of how the resulting waveform will look with envelope applied' 295 Hint = 'Preview of how the resulting waveform will look with envelope applied'
296 Top = 405 296 Top = 405
297 Width = 960 297 Width = 960
@@ -1664,7 +1664,7 @@ object frmTracker: TfrmTracker
1664 object StatusBar1: TStatusBar 1664 object StatusBar1: TStatusBar
1665 Left = 0 1665 Left = 0
1666 Height = 23 1666 Height = 23
1667 Top = 643 1667 Top = 645
1668 Width = 1166 1668 Width = 1166
1669 AutoHint = True 1669 AutoHint = True
1670 Panels = < 1670 Panels = <
@@ -1703,7 +1703,7 @@ object frmTracker: TfrmTracker
1703 ParentShowHint = False 1703 ParentShowHint = False
1704 end 1704 end
1705 object PanicToolButton: TToolButton 1705 object PanicToolButton: TToolButton
1706 Left = 551 1706 Left = 557
1707 Hint = 'Stops all sound output' 1707 Hint = 'Stops all sound output'
1708 Top = 0 1708 Top = 0
1709 AutoSize = True 1709 AutoSize = True
@@ -1714,7 +1714,7 @@ object frmTracker: TfrmTracker
1714 ShowHint = True 1714 ShowHint = True
1715 end 1715 end
1716 object ToolButton2: TToolButton 1716 object ToolButton2: TToolButton
1717 Left = 145 1717 Left = 147
1718 Hint = 'Begin playback from the cursor' 1718 Hint = 'Begin playback from the cursor'
1719 Top = 0 1719 Top = 0
1720 Caption = '▶️ Cursor' 1720 Caption = '▶️ Cursor'
@@ -1722,7 +1722,7 @@ object frmTracker: TfrmTracker
1722 OnClick = ToolButton2Click 1722 OnClick = ToolButton2Click
1723 end 1723 end
1724 object ToolButton4: TToolButton 1724 object ToolButton4: TToolButton
1725 Left = 219 1725 Left = 221
1726 Hint = 'Stop playback' 1726 Hint = 'Stop playback'
1727 Top = 0 1727 Top = 0
1728 Caption = '⏹ Stop' 1728 Caption = '⏹ Stop'
@@ -1730,7 +1730,7 @@ object frmTracker: TfrmTracker
1730 OnClick = ToolButton4Click 1730 OnClick = ToolButton4Click
1731 end 1731 end
1732 object ExportGBButton: TToolButton 1732 object ExportGBButton: TToolButton
1733 Left = 287 1733 Left = 291
1734 Hint = 'Export the song as a standalone ROM' 1734 Hint = 'Export the song as a standalone ROM'
1735 Top = 0 1735 Top = 0
1736 AutoSize = True 1736 AutoSize = True
@@ -1746,21 +1746,21 @@ object frmTracker: TfrmTracker
1746 Style = tbsDivider 1746 Style = tbsDivider
1747 end 1747 end
1748 object ToolButton6: TToolButton 1748 object ToolButton6: TToolButton
1749 Left = 284 1749 Left = 286
1750 Height = 22 1750 Height = 22
1751 Top = 0 1751 Top = 0
1752 Caption = 'ToolButton6' 1752 Caption = 'ToolButton6'
1753 Style = tbsDivider 1753 Style = tbsDivider
1754 end 1754 end
1755 object ToolButton7: TToolButton 1755 object ToolButton7: TToolButton
1756 Left = 1113 1756 Left = 1122
1757 Height = 22 1757 Height = 22
1758 Top = 0 1758 Top = 0
1759 Caption = 'ToolButton7' 1759 Caption = 'ToolButton7'
1760 Style = tbsSeparator 1760 Style = tbsSeparator
1761 end 1761 end
1762 object OctaveSpinEdit: TSpinEdit 1762 object OctaveSpinEdit: TSpinEdit
1763 Left = 654 1763 Left = 663
1764 Height = 23 1764 Height = 23
1765 Hint = 'The octave offset for entering new notes' 1765 Hint = 'The octave offset for entering new notes'
1766 Top = 0 1766 Top = 0
@@ -1771,14 +1771,14 @@ object frmTracker: TfrmTracker
1771 TabOrder = 0 1771 TabOrder = 0
1772 end 1772 end
1773 object ToolButton9: TToolButton 1773 object ToolButton9: TToolButton
1774 Left = 606 1774 Left = 612
1775 Height = 22 1775 Height = 22
1776 Top = 0 1776 Top = 0
1777 Caption = 'ToolButton9' 1777 Caption = 'ToolButton9'
1778 Style = tbsSeparator 1778 Style = tbsSeparator
1779 end 1779 end
1780 object Label22: TLabel 1780 object Label22: TLabel
1781 Left = 611 1781 Left = 620
1782 Height = 15 1782 Height = 15
1783 Top = 0 1783 Top = 0
1784 Width = 43 1784 Width = 43
@@ -1787,7 +1787,7 @@ object frmTracker: TfrmTracker
1787 ParentFont = False 1787 ParentFont = False
1788 end 1788 end
1789 object Label23: TLabel 1789 object Label23: TLabel
1790 Left = 744 1790 Left = 753
1791 Height = 15 1791 Height = 15
1792 Top = 0 1792 Top = 0
1793 Width = 70 1793 Width = 70
@@ -1796,7 +1796,7 @@ object frmTracker: TfrmTracker
1796 ParentFont = False 1796 ParentFont = False
1797 end 1797 end
1798 object InstrumentComboBox: TComboBox 1798 object InstrumentComboBox: TComboBox
1799 Left = 814 1799 Left = 823
1800 Height = 23 1800 Height = 23
1801 Hint = 'The selected instrument for new notes' 1801 Hint = 'The selected instrument for new notes'
1802 Top = 0 1802 Top = 0
@@ -1828,7 +1828,7 @@ object frmTracker: TfrmTracker
1828 Text = '(no instrument)' 1828 Text = '(no instrument)'
1829 end 1829 end
1830 object Label24: TLabel 1830 object Label24: TLabel
1831 Left = 1028 1831 Left = 1037
1832 Height = 15 1832 Height = 15
1833 Top = 0 1833 Top = 0
1834 Width = 35 1834 Width = 35
@@ -1837,7 +1837,7 @@ object frmTracker: TfrmTracker
1837 ParentFont = False 1837 ParentFont = False
1838 end 1838 end
1839 object StepSpinEdit: TSpinEdit 1839 object StepSpinEdit: TSpinEdit
1840 Left = 1063 1840 Left = 1072
1841 Height = 23 1841 Height = 23
1842 Hint = 'How many rows to step down after entering a new note' 1842 Hint = 'How many rows to step down after entering a new note'
1843 Top = 0 1843 Top = 0
@@ -1848,7 +1848,7 @@ object frmTracker: TfrmTracker
1848 TabOrder = 2 1848 TabOrder = 2
1849 end 1849 end
1850 object ToolButton3: TToolButton 1850 object ToolButton3: TToolButton
1851 Left = 82 1851 Left = 84
1852 Hint = 'Begin playback from the cursor' 1852 Hint = 'Begin playback from the cursor'
1853 Top = 0 1853 Top = 0
1854 Caption = '▶️ Start' 1854 Caption = '▶️ Start'
@@ -1856,7 +1856,7 @@ object frmTracker: TfrmTracker
1856 OnClick = ToolButton3Click 1856 OnClick = ToolButton3Click
1857 end 1857 end
1858 object ExportGBSButton: TToolButton 1858 object ExportGBSButton: TToolButton
1859 Left = 368 1859 Left = 372
1860 Hint = 'Export the song as a GBS soundtrack' 1860 Hint = 'Export the song as a GBS soundtrack'
1861 Top = 0 1861 Top = 0
1862 Caption = 'Export .GBS' 1862 Caption = 'Export .GBS'
@@ -1864,14 +1864,14 @@ object frmTracker: TfrmTracker
1864 OnClick = ExportGBSButtonClick 1864 OnClick = ExportGBSButtonClick
1865 end 1865 end
1866 object ToolButton5: TToolButton 1866 object ToolButton5: TToolButton
1867 Left = 548 1867 Left = 552
1868 Height = 22 1868 Height = 22
1869 Top = 0 1869 Top = 0
1870 Caption = 'ToolButton5' 1870 Caption = 'ToolButton5'
1871 Style = tbsDivider 1871 Style = tbsDivider
1872 end 1872 end
1873 object ToolButton10: TToolButton 1873 object ToolButton10: TToolButton
1874 Left = 455 1874 Left = 459
1875 Hint = 'Export the song as WAV or MP3' 1875 Hint = 'Export the song as WAV or MP3'
1876 Top = 0 1876 Top = 0
1877 Caption = 'Render Song' 1877 Caption = 'Render Song'
@@ -1900,6 +1900,16 @@ object frmTracker: TfrmTracker
1900 Action = FileSaveAs1 1900 Action = FileSaveAs1
1901 OnClick = MenuItem13Click 1901 OnClick = MenuItem13Click
1902 end 1902 end
1903 object MenuItem4: TMenuItem
1904 Caption = '-'
1905 end
1906 object MenuItem34: TMenuItem
1907 Caption = 'Import GBT Player ...'
1908 OnClick = MenuItem34Click
1909 end
1910 object MenuItem35: TMenuItem
1911 Caption = '-'
1912 end
1903 object MenuItem14: TMenuItem 1913 object MenuItem14: TMenuItem
1904 Caption = 'E&xit' 1914 Caption = 'E&xit'
1905 Hint = 'Exit' 1915 Hint = 'Exit'
@@ -1954,7 +1964,6 @@ object frmTracker: TfrmTracker
1954 Caption = 'Help' 1964 Caption = 'Help'
1955 object MenuItem15: TMenuItem 1965 object MenuItem15: TMenuItem
1956 Action = HelpLookupManual 1966 Action = HelpLookupManual
1957 Enabled = False
1958 end 1967 end
1959 object N3: TMenuItem 1968 object N3: TMenuItem
1960 Caption = '-' 1969 Caption = '-'
@@ -5153,4 +5162,10 @@ object frmTracker: TfrmTracker
5153 left = 229 5162 left = 229
5154 top = 114 5163 top = 114
5155 end 5164 end
5165 object MODOpenDialog: TOpenDialog
5166 DefaultExt = '.mod'
5167 Filter = 'GBT Player MOD files|*.mod'
5168 left = 144
5169 top = 114
5170 end
5156 end 5171 end
Modifiedtracker.pas +31−1
@@ -9,7 +9,7 @@ uses
9 FileUtil, math, Instruments, Waves, Song, EmulationThread, Utils, Constants, 9 FileUtil, math, Instruments, Waves, Song, EmulationThread, Utils, Constants,
10 sound, vars, machine, about_hugetracker, TrackerGrid, lclintf, lmessages, 10 sound, vars, machine, about_hugetracker, TrackerGrid, lclintf, lmessages,
11 Buttons, Grids, DBCtrls, HugeDatatypes, LCLType, RackCtls, Codegen, SymParser, 11 Buttons, Grids, DBCtrls, HugeDatatypes, LCLType, RackCtls, Codegen, SymParser,
12 options, IniFiles, bgrabitmap, effecteditor, RenderToWave; 12 options, IniFiles, bgrabitmap, effecteditor, RenderToWave, modimport;
13 13
14 type 14 type
15 { TfrmTracker } 15 { TfrmTracker }
@@ -37,7 +37,11 @@ type
37 MenuItem31: TMenuItem; 37 MenuItem31: TMenuItem;
38 MenuItem32: TMenuItem; 38 MenuItem32: TMenuItem;
39 MenuItem33: TMenuItem; 39 MenuItem33: TMenuItem;
40 MenuItem34: TMenuItem;
41 MenuItem35: TMenuItem;
42 MenuItem4: TMenuItem;
40 NoiseVisualizer: TPaintBox; 43 NoiseVisualizer: TPaintBox;
44 MODOpenDialog: TOpenDialog;
41 Panel6: TPanel; 45 Panel6: TPanel;
42 SynAnySyn1: TSynAnySyn; 46 SynAnySyn1: TSynAnySyn;
43 WavSaveDialog: TSaveDialog; 47 WavSaveDialog: TSaveDialog;
@@ -259,6 +263,7 @@ type
259 procedure MenuItem26Click(Sender: TObject); 263 procedure MenuItem26Click(Sender: TObject);
260 procedure MenuItem31Click(Sender: TObject); 264 procedure MenuItem31Click(Sender: TObject);
261 procedure MenuItem33Click(Sender: TObject); 265 procedure MenuItem33Click(Sender: TObject);
266 procedure MenuItem34Click(Sender: TObject);
262 procedure MenuItem5Click(Sender: TObject); 267 procedure MenuItem5Click(Sender: TObject);
263 procedure MenuItem8Click(Sender: TObject); 268 procedure MenuItem8Click(Sender: TObject);
264 procedure NoiseVisualizerPaint(Sender: TObject); 269 procedure NoiseVisualizerPaint(Sender: TObject);
@@ -1166,8 +1171,17 @@ begin
1166 end; 1171 end;
1167 1172
1168 procedure TfrmTracker.HelpLookupManualExecute(Sender: TObject); 1173 procedure TfrmTracker.HelpLookupManualExecute(Sender: TObject);
1174 procedure OpenPage(Page: Integer);
1175 begin
1176 OpenURL('file:///'+ExpandFileName('./Manual.pdf')+'#page='+IntToStr(Page));
1177 end;
1169 begin 1178 begin
1179 // TODO: This is really brittle. We need to find some way to export PDF
1180 // such that headers are exported as named destinations.
1181 {case LastActiveControl of
1182 TreeView1: OpenPage(13);
1170 1183
1184 end;}
1171 end; 1185 end;
1172 1186
1173 procedure TfrmTracker.FileSaveAs1Accept(Sender: TObject); 1187 procedure TfrmTracker.FileSaveAs1Accept(Sender: TObject);
@@ -1564,6 +1578,22 @@ begin
1564 UpdateUIAfterLoad; 1578 UpdateUIAfterLoad;
1565 end; 1579 end;
1566 1580
1581 procedure TfrmTracker.MenuItem34Click(Sender: TObject);
1582 var
1583 Stream: TStream;
1584 begin
1585 if MODOpenDialog.Execute then begin
1586 DestroySong(Song);
1587
1588 Stream := TFileStream.Create(MODOpenDialog.FileName, fmOpenRead);
1589 Song := LoadSongFromModStream(Stream);
1590
1591 Stream.Free;
1592
1593 UpdateUIAfterLoad;
1594 end;
1595 end;
1596
1567 procedure TfrmTracker.MenuItem5Click(Sender: TObject); 1597 procedure TfrmTracker.MenuItem5Click(Sender: TObject);
1568 begin 1598 begin
1569 frmAboutHugetracker.Show; 1599 frmAboutHugetracker.Show;