-
Notifications
You must be signed in to change notification settings - Fork 1
/
tzxblock20.inc
137 lines (108 loc) · 2.9 KB
/
tzxblock20.inc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Copyright 2022-2024 Zoran Vučenović
// SPDX-License-Identifier: Apache-2.0
{$ifdef tzx_header_section}
TTzxBlockPause = class (TTzxBlock)
private
FPauseLength: Integer;
TicksNeeded: Int64;
public
constructor Create(ATapePlayer: TTapePlayer); override;
class function GetBlockId: DWord; override;
{returns whole block length, without id byte}
function GetBlockLength: Integer; override;
function LoadBlock(const Stream: TStream): Boolean; override;
class function GetBlockDescription: String; override;
function GetNextPulse(): Boolean; override;
procedure Start; override;
procedure SetPauseLen(const APauseLength: Integer);
end;
TTzxBlock20 = class (TTzxBlockPause)
public
procedure Details(out S: String); override;
function GetStopPlaying: Boolean; override;
end;
{$else}
constructor TTzxBlockPause.Create(ATapePlayer: TTapePlayer);
begin
inherited Create(ATapePlayer);
FPauseLength := 0;
end;
class function {TTzxPlayer.}TTzxBlockPause.GetBlockId: DWord;
begin
Result := $20;
end;
function {TTzxPlayer.}TTzxBlockPause.GetBlockLength: Integer;
begin
Result := 2;
end;
function {TTzxPlayer.}TTzxBlockPause.LoadBlock(const Stream: TStream): Boolean;
var
W: Word;
begin
Result := False;
if Stream.Size >= Stream.Position + 2 then begin
if Stream.Read(W{%H-}, 2) = 2 then begin
W := LEtoN(W);
FPauseLength := W;
Result := True;
end;
end;
end;
class function {TTzxPlayer.}TTzxBlockPause.GetBlockDescription: String;
begin
Result := 'Pause (silence) or ''Stop the Tape'' command';
end;
function {TTzxPlayer.}TTzxBlockPause.GetNextPulse: Boolean;
var
ProcTicks: Int64;
TicksToWait: Int64;
begin
if State = TPlayState.psFinished then
Exit(False);
Result := True;
ProcTicks := GetCurrentTotalSpectrumTicks;
if ProcTicks >= TicksNeeded then begin
case State of
TPlayState.psStart:
begin
TicksToWait := TicksBeforePause;
State := TPlayState.psData;
end;
TPlayState.psData:
begin
TicksToWait := FPauseLength * TicksPerMilliSecond;
FTapePlayer.ActiveBit := 0;
FTapePlayer.InPause := True;
State := TPlayState.psPause;
end;
otherwise
State := TPlayState.psFinished;
Exit;
end;
AdjustTicksIfNeeded(TicksToWait);
TicksNeeded := ProcTicks + TicksToWait;
end;
end;
procedure {TTzxPlayer.}TTzxBlockPause.Start;
begin
inherited Start;
State := TPlayState.psStart;
TicksNeeded := TicksNeeded.MinValue;
end;
procedure {TTzxPlayer.}TTzxBlockPause.SetPauseLen(const APauseLength: Integer);
begin
FPauseLength := APauseLength;
end;
{ TTzxBlock20 }
procedure TTzxBlock20.Details(out S: String);
begin
if GetStopPlaying then
S := 'stop playing'
else
S := 'Pause ' + FPauseLength.ToString + ' ms';
end;
function TTzxBlock20.GetStopPlaying: Boolean;
begin
Result := FPauseLength = 0;
end;
{$endif}