Commit 8037b8f

Nick committed on
Refactoring, and complete rendering to wav dialog
commit 8037b8f0aa0f1df9f944581c6ba10c538f9d3182 parent 19aeca8
11 changed files +522−81
ModifiedGBEmu.lpi +10−3
@@ -168,7 +168,7 @@
168 <PackageName Value="LCL"/> 168 <PackageName Value="LCL"/>
169 </Item6> 169 </Item6>
170 </RequiredPackages> 170 </RequiredPackages>
171 <Units Count="23"> 171 <Units Count="24">
172 <Unit0> 172 <Unit0>
173 <Filename Value="GBEmu.lpr"/> 173 <Filename Value="GBEmu.lpr"/>
174 <IsPartOfProject Value="True"/> 174 <IsPartOfProject Value="True"/>
@@ -283,10 +283,17 @@
283 <ResourceBaseClass Value="Form"/> 283 <ResourceBaseClass Value="Form"/>
284 </Unit21> 284 </Unit21>
285 <Unit22> 285 <Unit22>
286 <Filename Value="waveexport.pas"/> 286 <Filename Value="rendertowave.pas"/>
287 <IsPartOfProject Value="True"/> 287 <IsPartOfProject Value="True"/>
288 <UnitName Value="WaveExport"/> 288 <ComponentName Value="frmRenderToWave"/>
289 <ResourceBaseClass Value="Form"/>
290 <UnitName Value="RenderToWave"/>
289 </Unit22> 291 </Unit22>
292 <Unit23>
293 <Filename Value="htwavewriter.pas"/>
294 <IsPartOfProject Value="True"/>
295 <UnitName Value="htWavWriter"/>
296 </Unit23>
290 </Units> 297 </Units>
291 </ProjectOptions> 298 </ProjectOptions>
292 <CompilerOptions> 299 <CompilerOptions>
ModifiedGBEmu.lpr +3−1
@@ -32,7 +32,8 @@ uses
32 sound in 'Sound\sound.pas', 32 sound in 'Sound\sound.pas',
33 vars in 'Global\vars.pas', 33 vars in 'Global\vars.pas',
34 options in 'options.pas', 34 options in 'options.pas',
35 about_hugetracker in 'about_hugetracker.pas'; 35 about_hugetracker in 'about_hugetracker.pas',
36 rendertowave in 'rendertowave.pas';
36 37
37 {.$R *.RES} 38 {.$R *.RES}
38 39
@@ -71,5 +72,6 @@ begin
71 Application.CreateForm(TfrmOptions, frmOptions); 72 Application.CreateForm(TfrmOptions, frmOptions);
72 Application.CreateForm(TfrmAboutHugeTracker, frmAboutHugetracker); 73 Application.CreateForm(TfrmAboutHugeTracker, frmAboutHugetracker);
73 Application.CreateForm(TfrmEffectEditor, frmEffectEditor); 74 Application.CreateForm(TfrmEffectEditor, frmEffectEditor);
75 Application.CreateForm(TfrmRenderToWave, frmRenderToWave);
74 Application.Run; 76 Application.Run;
75 end. 77 end.
ModifiedSound/sound.pas +1−1
@@ -169,7 +169,7 @@ var
169 169
170 implementation 170 implementation
171 171
172 uses vars, sdl2, fpWavWriter; 172 uses vars, sdl2, htWaveWriter;
173 173
174 const 174 const
175 SampleSize = SizeOf(Single)*2; 175 SampleSize = SizeOf(Single)*2;
Addedhtwavewriter.pas +155−0
@@ -0,0 +1,155 @@
1 {*****************************************************************************}
2 {
3 This file is part of the Free Pascal's "Free Components Library".
4 Copyright (c) 2014 by Mazen NEIFER of the Free Pascal development team
5 and was adapted from wavopenal.pas copyright (c) 2010 Dmitry Boyarintsev.
6
7 RIFF/WAVE sound file writer implementation.
8
9 See the file COPYING.FPC, included in this distribution,
10 for details about the copyright.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
15 }
16
17 {
18 This is a vendored version of the FPC fpWavWriter unit, which removes an
19 accidental debugging leftover which causes output to take forever.
20 }
21
22 unit htWaveWriter;
23
24 {$mode objfpc}{$H+}
25
26 interface
27
28 uses
29 fpWavFormat,
30 Classes;
31
32 type
33 { TWaveReader }
34
35 { TWavWriter }
36
37 TWavWriter = class(TObject)
38 private
39 fStream: TStream;
40 FFreeStreamOnClose: Boolean;
41 public
42 fmt: TWaveFormat;
43 destructor Destroy; override;
44 function CloseAudioFile: Boolean;
45 function FlushHeader: Boolean;
46 function StoreToFile(const FileName: string): Boolean;
47 function StoreToStream(AStream: TStream): Boolean;
48 function WriteBuf(var Buffer; BufferSize: Integer): Integer;
49 end;
50
51 implementation
52
53 uses
54 SysUtils;
55
56 procedure NtoLE(var fmt: TWaveFormat); overload;
57 begin
58 with fmt, ChunkHeader do begin
59 Size := NtoLE(Size);
60 Format := NtoLE(Format);
61 Channels := NtoLE(Channels);
62 SampleRate := NtoLE(SampleRate);
63 ByteRate := NtoLE(ByteRate);
64 BlockAlign := NtoLE(BlockAlign);
65 BitsPerSample := NtoLE(BitsPerSample);
66 end;
67 end;
68
69 { TWaveWriter }
70
71 destructor TWavWriter.Destroy;
72 begin
73 CloseAudioFile;
74 inherited Destroy;
75 end;
76
77 function TWavWriter.CloseAudioFile: Boolean;
78 begin
79 Result := True;
80 if not Assigned(fStream) then begin
81 Exit(True);
82 end;
83 FlushHeader;
84 if FFreeStreamOnClose then begin
85 fStream.Free;
86 end;
87 end;
88
89 function TWavWriter.FlushHeader: Boolean;
90 var
91 riff: TRiffHeader;
92 fmtLE: TWaveFormat;
93 DataChunk: TChunkHeader;
94 Pos: Int64;
95 begin
96 Pos := fStream.Position;
97 with riff, ChunkHeader do begin
98 ID := AUDIO_CHUNK_ID_RIFF;
99 Size := NtoLE(Pos - SizeOf(ChunkHeader));
100 Format := AUDIO_CHUNK_ID_WAVE;
101 end;
102 fmtLE := fmt;
103 NtoLE(fmtLE);
104 with fStream do begin
105 Position := 0;
106 Result := Write(riff, SizeOf(riff)) = SizeOf(riff);
107 Result := Write(fmtLE, sizeof(fmtLE)) = SizeOf(fmtLE);
108 end;
109 with DataChunk do begin
110 Id := AUDIO_CHUNK_ID_data;
111 Size := Pos - SizeOf(DataChunk) - fStream.Position;
112 end;
113 with fStream do begin
114 Result := Write(DataChunk, SizeOf(DataChunk)) = SizeOf(DataChunk);
115 end;
116 end;
117
118 function TWavWriter.StoreToFile(const FileName: string):Boolean;
119 begin
120 CloseAudioFile;
121 fStream := TFileStream.Create(FileName, fmCreate + fmOpenWrite);
122 if Assigned(fStream) then begin
123 Result := StoreToStream(fStream);
124 FFreeStreamOnClose := True;
125 end else begin
126 Result := False;
127 end;
128 end;
129
130 function TWavWriter.StoreToStream(AStream:TStream):Boolean;
131 begin
132 fStream := AStream;
133 FFreeStreamOnClose := False;
134 with fmt, ChunkHeader do begin
135 ID := AUDIO_CHUNK_ID_fmt;
136 Size := SizeOf(fmt) - SizeOf(ChunkHeader);
137 Format := AUDIO_FORMAT_PCM;
138 end;
139 Result := FlushHeader;
140 end;
141
142 function TWavWriter.WriteBuf(var Buffer; BufferSize: Integer): Integer;
143 var
144 sz: Integer;
145 begin
146 Result := 0;
147 with fStream do begin
148 sz := Write(Buffer, BufferSize);
149 if sz < 0 then Exit;
150 Inc(Result, sz);
151 end;
152 end;
153
154 end.
155
Addedrendertowave.lfm +143−0
@@ -0,0 +1,143 @@
1 object frmRenderToWave: TfrmRenderToWave
2 Left = 2072
3 Height = 361
4 Top = 149
5 Width = 294
6 Caption = 'Render to .WAV'
7 ClientHeight = 361
8 ClientWidth = 294
9 OnShow = FormShow
10 Position = poDefault
11 LCLVersion = '2.0.6.0'
12 object Button1: TButton
13 Left = 16
14 Height = 25
15 Top = 320
16 Width = 264
17 Caption = 'Render'
18 Enabled = False
19 OnClick = Button1Click
20 TabOrder = 0
21 end
22 object FileNameEdit1: TFileNameEdit
23 Left = 72
24 Height = 23
25 Top = 8
26 Width = 208
27 FileName = 'FileNameEdit1'
28 OnAcceptFileName = FileNameEdit1AcceptFileName
29 Filter = 'Wave files|*.wav'
30 FilterIndex = 0
31 HideDirectories = False
32 ButtonWidth = 23
33 NumGlyphs = 1
34 MaxLength = 0
35 TabOrder = 1
36 OnChange = FileNameEdit1Change
37 Text = 'FileNameEdit1'
38 end
39 object Label1: TLabel
40 Left = 8
41 Height = 15
42 Top = 16
43 Width = 48
44 Caption = 'Filename'
45 ParentColor = False
46 end
47 object RadioGroup1: TRadioGroup
48 Left = 8
49 Height = 90
50 Top = 40
51 Width = 273
52 AutoFill = True
53 Caption = 'Duration'
54 ChildSizing.LeftRightSpacing = 6
55 ChildSizing.EnlargeHorizontal = crsHomogenousChildResize
56 ChildSizing.EnlargeVertical = crsHomogenousChildResize
57 ChildSizing.ShrinkHorizontal = crsScaleChilds
58 ChildSizing.ShrinkVertical = crsScaleChilds
59 ChildSizing.Layout = cclLeftToRightThenTopToBottom
60 ChildSizing.ControlsPerLine = 1
61 ClientHeight = 70
62 ClientWidth = 269
63 ItemIndex = 0
64 Items.Strings = (
65 'Time in seconds'
66 'Loops'
67 )
68 OnClick = RadioGroup1Click
69 TabOrder = 2
70 end
71 object Notebook1: TNotebook
72 Left = 8
73 Height = 152
74 Top = 136
75 Width = 272
76 PageIndex = 1
77 TabOrder = 3
78 object Page1: TPage
79 object Label2: TLabel
80 Left = 8
81 Height = 15
82 Top = 40
83 Width = 44
84 Caption = 'Seconds'
85 ParentColor = False
86 end
87 object SecondsSpinEdit: TSpinEdit
88 Left = 72
89 Height = 23
90 Top = 32
91 Width = 192
92 TabOrder = 0
93 end
94 end
95 object Page2: TPage
96 object Label3: TLabel
97 Left = 72
98 Height = 15
99 Top = 8
100 Width = 129
101 Caption = 'Stop playing when order'
102 ParentColor = False
103 end
104 object OrderSpinEdit: TSpinEdit
105 Left = 16
106 Height = 23
107 Top = 32
108 Width = 248
109 TabOrder = 0
110 end
111 object Label4: TLabel
112 Left = 88
113 Height = 15
114 Top = 64
115 Width = 92
116 Caption = 'has been reached'
117 ParentColor = False
118 end
119 object LoopTimesSpinEdit: TSpinEdit
120 Left = 16
121 Height = 23
122 Top = 88
123 Width = 248
124 TabOrder = 1
125 end
126 object Label5: TLabel
127 Left = 120
128 Height = 15
129 Top = 120
130 Width = 29
131 Caption = 'times'
132 ParentColor = False
133 end
134 end
135 end
136 object ProgressBar1: TProgressBar
137 Left = 16
138 Height = 28
139 Top = 280
140 Width = 264
141 TabOrder = 4
142 end
143 end
Addedrendertowave.pas +161−0
@@ -0,0 +1,161 @@
1 unit RenderToWave;
2
3 {$mode objfpc}{$H+}
4
5 interface
6
7 uses
8 Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, EditBtn,
9 ExtCtrls, Spin, ComCtrls, constants;
10
11 type
12
13 { TfrmRenderToWave }
14
15 TfrmRenderToWave = class(TForm)
16 Button1: TButton;
17 FileNameEdit1: TFileNameEdit;
18 Label1: TLabel;
19 Label2: TLabel;
20 Label3: TLabel;
21 Label4: TLabel;
22 Label5: TLabel;
23 Notebook1: TNotebook;
24 Page1: TPage;
25 Page2: TPage;
26 ProgressBar1: TProgressBar;
27 RadioGroup1: TRadioGroup;
28 SecondsSpinEdit: TSpinEdit;
29 OrderSpinEdit: TSpinEdit;
30 LoopTimesSpinEdit: TSpinEdit;
31 procedure Button1Click(Sender: TObject);
32 procedure FileNameEdit1AcceptFileName(Sender: TObject; var Value: String);
33 procedure FileNameEdit1Change(Sender: TObject);
34 procedure FormShow(Sender: TObject);
35 procedure RadioGroup1Click(Sender: TObject);
36 private
37 CurrentSeenPattern: Integer;
38 TimesSeenTargetPattern: Integer;
39
40 procedure ExportWaveToFile(Filename: String; Seconds: Integer); overload;
41 procedure ExportWaveToFile(Filename: String; OrderNum: Integer; Loops: Integer); overload;
42
43 procedure OrderCheckFD;
44 public
45
46 end;
47
48 var
49 frmRenderToWave: TfrmRenderToWave;
50
51 implementation
52
53 uses sound, machine, mainloop, vars, symparser;
54
55 {$R *.lfm}
56
57 procedure TfrmRenderToWave.FileNameEdit1AcceptFileName(Sender: TObject;
58 var Value: String);
59 begin
60 Button1.Enabled := (FileNameEdit1.FileName <> '');
61 end;
62
63 procedure TfrmRenderToWave.Button1Click(Sender: TObject);
64 begin
65 if RadioGroup1.ItemIndex = 0 then
66 ExportWaveToFile(FileNameEdit1.FileName, SecondsSpinEdit.Value)
67 else
68 ExportWaveToFile(FileNameEdit1.FileName, OrderSpinEdit.Value, LoopTimesSpinEdit.Value);
69 end;
70
71 procedure TfrmRenderToWave.FileNameEdit1Change(Sender: TObject);
72 begin
73 Button1.Enabled := (FileNameEdit1.FileName <> '');
74 end;
75
76 procedure TfrmRenderToWave.FormShow(Sender: TObject);
77 begin
78 ProgressBar1.Position:=0;
79 FileNameEdit1.FileName:='';
80 RadioGroup1.ItemIndex:=0;
81 SecondsSpinEdit.Value:=0;
82 OrderSpinEdit.Value:=0;
83 LoopTimesSpinEdit.Value:=0;
84 end;
85
86 procedure TfrmRenderToWave.RadioGroup1Click(Sender: TObject);
87 begin
88 Notebook1.PageIndex := RadioGroup1.ItemIndex;
89 end;
90
91 procedure TfrmRenderToWave.ExportWaveToFile(Filename: String; Seconds: Integer);
92 var
93 CompletedCycles: QWord = 0;
94 CyclesToDo: QWord;
95 begin
96 CyclesToDo := (70224*60)*Seconds;
97 ProgressBar1.Position := 0;
98
99 z80_reset;
100 ResetSound;
101 enablesound;
102
103 BeginWritingSoundToFile(Filename);
104
105 FDCallback := nil;
106
107 load('hUGEDriver/preview.gb');
108
109 while CompletedCycles < CyclesToDo do begin
110 Inc(CompletedCycles, z80_decode);
111 ProgressBar1.Position := Trunc((CompletedCycles / CyclesToDo)*100);
112 if Random(500) = 1 then Application.ProcessMessages;
113 end;
114
115 EndWritingSoundToFile;
116 end;
117
118 procedure TfrmRenderToWave.ExportWaveToFile(Filename: String;
119 OrderNum: Integer; Loops: Integer);
120 var
121 TimesToSeePattern: Integer;
122 begin
123 TimesToSeePattern := (LoopTimesSpinEdit.Value+1);
124 TimesSeenTargetPattern := 0;
125 CurrentSeenPattern := -1;
126
127 z80_reset;
128 ResetSound;
129 enablesound;
130
131 BeginWritingSoundToFile(Filename);
132
133 FDCallback := @OrderCheckFD;
134
135 load('hUGEDriver/preview.gb');
136 SymbolTable := ParseSymFile('hUGEDriver/preview.sym');
137
138 while TimesSeenTargetPattern < TimesToSeePattern do begin
139 z80_decode;
140 ProgressBar1.Position := Trunc((TimesSeenTargetPattern / TimesToSeePattern)*100);
141 if Random(500) = 1 then Application.ProcessMessages;
142 end;
143
144 EndWritingSoundToFile;
145 end;
146
147 procedure TfrmRenderToWave.OrderCheckFD;
148 var
149 Pat: Integer;
150 begin
151 Pat := (PeekSymbol(SYM_CURRENT_ORDER) div 2);
152 if CurrentSeenPattern <> Pat then begin
153 CurrentSeenPattern := Pat;
154
155 if Pat = OrderSpinEdit.Value then
156 Inc(TimesSeenTargetPattern);
157 end;
158 end;
159
160 end.
161
Modifiedsymparser.pas +34−0
@@ -10,10 +10,20 @@ uses
10 type 10 type
11 TSymbolMap = specialize TFPGMap<String, Integer>; 11 TSymbolMap = specialize TFPGMap<String, Integer>;
12 12
13 var
14 SymbolTable: TSymbolMap;
15
16 function WordPeekSymbol(Symbol: String): Integer;
17 procedure WordPokeSymbol(Symbol: String; Value: Word);
18 function PeekSymbol(Symbol: String): Integer;
19 procedure PokeSymbol(Symbol: String; Value: Byte);
20
13 function ParseSymFile(F: String): TSymbolMap; 21 function ParseSymFile(F: String): TSymbolMap;
14 22
15 implementation 23 implementation
16 24
25 uses machine;
26
17 function ParseSymFile(F: String): TSymbolMap; 27 function ParseSymFile(F: String): TSymbolMap;
18 var 28 var
19 SL: TStringList; 29 SL: TStringList;
@@ -38,5 +48,29 @@ begin
38 end; 48 end;
39 end; 49 end;
40 50
51 function PeekSymbol(Symbol: String): Integer;
52 begin
53 if SymbolTable = nil then exit(0);
54 Result := speekb(SymbolTable.KeyData[Symbol]);
55 end;
56
57 procedure PokeSymbol(Symbol: String; Value: Byte);
58 begin
59 if SymbolTable = nil then exit;
60 spokeb(SymbolTable.KeyData[Symbol], Value);
61 end;
62
63 function WordPeekSymbol(Symbol: String): Integer;
64 begin
65 if SymbolTable = nil then exit(0);
66 Result := wordpeek(SymbolTable.KeyData[Symbol]);
67 end;
68
69 procedure WordPokeSymbol(Symbol: String; Value: Word);
70 begin
71 if SymbolTable = nil then exit;
72 wordpoke(SymbolTable.KeyData[Symbol], Value);
73 end;
74
41 end. 75 end.
42 76
Modifiedtracker.lfm +2−2
@@ -1,7 +1,7 @@
1 object frmTracker: TfrmTracker 1 object frmTracker: TfrmTracker
2 Left = 1822 2 Left = 2122
3 Height = 714 3 Height = 714
4 Top = 143 4 Top = 119
5 Width = 1181 5 Width = 1181
6 Caption = 'hUGETracker' 6 Caption = 'hUGETracker'
7 ClientHeight = 694 7 ClientHeight = 694
Modifiedtracker.pas +9−33
@@ -10,7 +10,7 @@ uses
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 HugeDatatypes, LCLType, RackCtls, Codegen, SymParser, options, IniFiles, 12 HugeDatatypes, LCLType, RackCtls, Codegen, SymParser, options, IniFiles,
13 bgrabitmap, effecteditor, WaveExport; 13 bgrabitmap, effecteditor, RenderToWave;
14 14
15 type 15 type
16 { TfrmTracker } 16 { TfrmTracker }
@@ -335,7 +335,6 @@ type
335 335
336 {PatternsNode, }InstrumentsNode, WavesNode, RoutinesNode: TTreeNode; 336 {PatternsNode, }InstrumentsNode, WavesNode, RoutinesNode: TTreeNode;
337 337
338 SymbolTable: TSymbolMap;
339 OptionsFile: TIniFile; 338 OptionsFile: TIniFile;
340 339
341 VisualizerBuffer: TBGRABitmap; 340 VisualizerBuffer: TBGRABitmap;
@@ -351,10 +350,6 @@ type
351 function PreparePreview: Boolean; 350 function PreparePreview: Boolean;
352 procedure ResetEmulationThread; 351 procedure ResetEmulationThread;
353 352
354 function WordPeekSymbol(Symbol: String): Integer;
355 procedure WordPokeSymbol(Symbol: String; Value: Word);
356 function PeekSymbol(Symbol: String): Integer;
357 procedure PokeSymbol(Symbol: String; Value: Byte);
358 procedure OnFD(var Msg: TLMessage); message LM_FD; 353 procedure OnFD(var Msg: TLMessage); message LM_FD;
359 procedure OnUndoOccured(var Msg: TLMessage); message LM_UNDO_OCCURED; 354 procedure OnUndoOccured(var Msg: TLMessage); message LM_UNDO_OCCURED;
360 procedure OnNotePlaced(var Msg: TLMessage); message LM_PREVIEW_NOTE; 355 procedure OnNotePlaced(var Msg: TLMessage); message LM_PREVIEW_NOTE;
@@ -663,30 +658,6 @@ begin
663 OrderEditStringGrid.Cells[C, R] := '0'; 658 OrderEditStringGrid.Cells[C, R] := '0';
664 end; 659 end;
665 660
666 function TfrmTracker.PeekSymbol(Symbol: String): Integer;
667 begin
668 if SymbolTable = nil then exit(0);
669 Result := speekb(SymbolTable.KeyData[Symbol]);
670 end;
671
672 procedure TfrmTracker.PokeSymbol(Symbol: String; Value: Byte);
673 begin
674 if SymbolTable = nil then exit;
675 spokeb(SymbolTable.KeyData[Symbol], Value);
676 end;
677
678 function TfrmTracker.WordPeekSymbol(Symbol: String): Integer;
679 begin
680 if SymbolTable = nil then exit(0);
681 Result := wordpeek(SymbolTable.KeyData[Symbol]);
682 end;
683
684 procedure TfrmTracker.WordPokeSymbol(Symbol: String; Value: Word);
685 begin
686 if SymbolTable = nil then exit;
687 wordpoke(SymbolTable.KeyData[Symbol], Value);
688 end;
689
690 function TfrmTracker.PreparePreview: Boolean; 661 function TfrmTracker.PreparePreview: Boolean;
691 var 662 var
692 I: Integer; 663 I: Integer;
@@ -1571,7 +1542,11 @@ var
1571 Samp: Integer; 1542 Samp: Integer;
1572 begin 1543 begin
1573 // HACK: Avoid LCL bug where modal windows can't close. 1544 // HACK: Avoid LCL bug where modal windows can't close.
1574 if frmOptions.Visible or frmEffectEditor.Visible then Exit; 1545 if frmOptions.Visible
1546 or frmEffectEditor.Visible
1547 or frmRenderToWave.Visible then
1548 Exit;
1549
1575 if Playing then 1550 if Playing then
1576 OscilloscopeUpdateTimer.Interval := 25 1551 OscilloscopeUpdateTimer.Interval := 25
1577 else 1552 else
@@ -1609,8 +1584,9 @@ end;
1609 procedure TfrmTracker.ToolButton10Click(Sender: TObject); 1584 procedure TfrmTracker.ToolButton10Click(Sender: TObject);
1610 begin 1585 begin
1611 EmulationThread.Terminate; 1586 EmulationThread.Terminate;
1612 if RenderPreviewROM(Song) and WavSaveDialog.Execute then begin 1587 if RenderPreviewROM(Song) then begin
1613 ExportWaveToFile(WavSaveDialog.Filename); 1588 SymbolTable := ParseSymFile('hUGEDriver/preview.sym');
1589 frmRenderToWave.ShowModal;
1614 ResetEmulationThread; 1590 ResetEmulationThread;
1615 end; 1591 end;
1616 end; 1592 end;
Modifiedtrackergrid.pas +4−4
@@ -745,12 +745,12 @@ begin
745 end; 745 end;
746 746
747 procedure TTrackerGrid.SetHighlightedRow(Row: Integer); 747 procedure TTrackerGrid.SetHighlightedRow(Row: Integer);
748 {var 748 //var
749 R: TRect; 749 //R: TRect;
750 OldRow: Integer;} 750 //OldRow: Integer;
751 begin 751 begin
752 //OldRow := FHighlightedRow; 752 //OldRow := FHighlightedRow;
753 //FHighlightedRow := Row; 753 FHighlightedRow := Row;
754 754
755 Invalidate 755 Invalidate
756 756
Deletedwaveexport.pas +0−37
@@ -1,37 +0,0 @@
1 unit WaveExport;
2
3 {$mode objfpc}{$H+}
4
5 interface
6
7 uses
8 Classes, SysUtils;
9
10 procedure ExportWaveToFile(Filename: String);
11
12 implementation
13
14 uses sound, mainloop, vars, machine, constants;
15
16 procedure ExportWaveToFile(Filename: String);
17 var
18 CompletedCycles: QWord = 0;
19 begin
20 z80_reset;
21 ResetSound;
22 enablesound;
23
24 BeginWritingSoundToFile(Filename);
25
26 FDCallback := nil;
27
28 load('hUGEDriver/preview.gb');
29
30 while CompletedCycles < (70224*60)*10 do
31 Inc(CompletedCycles, z80_decode);
32
33 EndWritingSoundToFile;
34 end;
35
36 end.
37