1 {*************************************************************}
2 { TSsPlayTime Component - Estimates SakuraScript playing time }
4 { Copyright (c) 2001-2003 naruto/CANO-Lab }
5 {*************************************************************}
12 Windows, SysUtils, Classes, SsParser;
15 TSsPlayTimeException = class(Exception);
16 TSsPlayTimeInitException = class(TSsPlayTimeException);
18 TSsPlayTimeSpecialChar = class(TCollectionItem)
22 procedure SetChar(const Value: String);
23 procedure SetWait(const Value: integer);
25 function GetDisplayName: String; override;
27 procedure Assign(Source: TPersistent); override;
28 function DisplayChar: String;
30 property Char: String read FChar write SetChar;
31 property Wait: integer read FWait write SetWait;
34 TSsPlayTimeSpecialChars = class(TCollection)
37 TSsPlayTimeParams = class(TComponent)
43 FCostHiResWait: integer;
44 FCostSurface: integer;
45 FCostQuickChar: integer;
47 FSpecialChars: TSsPlayTimeSpecialChars;
48 procedure SetCostChar(const Value: integer);
49 procedure SetCostConst(const Value: integer);
50 procedure SetCostDBChar(const Value: integer);
51 procedure SetCostWait(const Value: integer);
52 procedure SetCostHiResWait(const Value: integer);
53 procedure SetCostSurface(const Value: integer);
54 procedure SetCostQuickChar(const Value: integer);
55 procedure SetProfileName(const Value: String);
56 procedure SetSpecialChars(const Value: TSsPlayTimeSpecialChars);
58 constructor Create(AOwner: TComponent); override;
59 destructor Destroy; override;
60 procedure Assign(Source: TPersistent); override;
62 property ProfileName: String read FProfileName write SetProfileName;
63 property CostConst: integer read FCostConst write SetCostConst default 0;
64 property CostWait: integer read FCostWait write SetCostWait default 50;
65 property CostHiResWait: integer read FCostHiResWait write SetCostHiResWait default 1;
66 property CostSurface: integer read FCostSurface write SetCostSurface default 5;
67 property CostChar: integer read FCostChar write SetCostChar default 50;
68 property CostDBChar: integer read FCostDBChar write SetCostDBChar default 50;
69 property CostQuickChar: integer read FCostQuickChar write SetCostQuickChar default 0;
70 property SpecialChars: TSsPlayTimeSpecialChars read FSpecialChars write SetSpecialChars;
73 TSsPlayTimeCount = record
83 TSsPlayTime = class(TComponent)
85 FPlayTimeParams: TSsPlayTimeParams;
87 FCounts: TSsPlayTimeCount;
88 procedure SetPlayTimeParams(const Value: TSsPlayTimeParams);
89 procedure SetSsParser(const Value: TSsParser);
91 procedure CountElements;
92 procedure CountCharacterType(const Str: String; out SB, DB,
93 SPNum, SPWait: integer);
95 function PlayTime(const Script: String): integer;
96 property Counts: TSsPlayTimeCount read FCounts;
98 property PlayTimeParams: TSsPlayTimeParams read FPlayTimeParams write SetPlayTimeParams;
99 property SsParser: TSsParser read FSsParser write SetSsParser;
107 CDBWhiteSpace = #129 + #64; // Shift_JIS DB White Space;
111 RegisterComponents('Samples', [TSsPlayTime, TSsPlayTimeParams]);
114 { TSsPlayTimeParams }
116 procedure TSsPlayTimeParams.Assign(Source: TPersistent);
118 Src: TSsPlayTimeParams;
120 if not (Source is TSsPlayTimeParams) then
124 Src := Source as TSsPlayTimeParams;
125 FCostConst := Src.FCostConst;
126 FCostWait := Src.FCostWait;
127 FCostHiResWait := Src.FCostHiResWait;
128 FCostSurface := Src.FCostSurface;
129 FCostChar := Src.FCostChar;
130 FCostDBChar := Src.FCostDBChar;
131 FCostQuickChar := Src.FCostQuickChar;
132 FProfileName := Src.FProfileName;
133 FSpecialChars.Assign(Src.SpecialChars);
137 constructor TSsPlayTimeParams.Create(AOwner: TComponent);
147 FSpecialChars := TSsPlayTimeSpecialChars.Create(TSsPlayTimeSpecialChar);
150 destructor TSsPlayTimeParams.Destroy;
156 procedure TSsPlayTimeParams.SetCostChar(const Value: integer);
161 procedure TSsPlayTimeParams.SetCostConst(const Value: integer);
166 procedure TSsPlayTimeParams.SetCostDBChar(const Value: integer);
168 FCostDBChar := Value;
171 procedure TSsPlayTimeParams.SetCostHiResWait(const Value: integer);
173 FCostHiResWait := Value;
176 procedure TSsPlayTimeParams.SetCostQuickChar(const Value: integer);
178 FCostQuickChar := Value;
181 procedure TSsPlayTimeParams.SetCostSurface(const Value: integer);
183 FCostSurface := Value;
186 procedure TSsPlayTimeParams.SetCostWait(const Value: integer);
191 procedure TSsPlayTimeParams.SetProfileName(const Value: String);
193 FProfileName := Value;
196 procedure TSsPlayTimeParams.SetSpecialChars(
197 const Value: TSsPlayTimeSpecialChars);
199 FSpecialChars.Assign(Value);
204 procedure TSsPlayTime.CountCharacterType(const Str: String; out SB,
205 DB, SPNum, SPWait: integer);
208 InLeadByte, Flag: boolean;
209 AChar: TSsPlayTimeSpecialChar;
216 for i := 1 to Length(Str) do
226 for j := 0 to PlayTimeParams.SpecialChars.Count-1 do
228 AChar := PlayTimeParams.SpecialChars.Items[j] as TSsPlayTimeSpecialChar;
229 if Length(AChar.Char) = 2 then
231 if Str[i] + Str[i+1] = AChar.Char then
233 Inc(SPWait, AChar.Wait);
242 if Str[i] = AChar.Char then
244 Inc(SPWait, AChar.Wait);
253 if Str[i] in LeadBytes then
262 procedure TSsPlayTime.CountElements;
264 i, SB, DB, SPNum, SPWait: integer;
268 ZeroMemory(@FCounts, sizeof(FCounts));
272 for i := 0 to SsParser.Count-1 do
275 case MarkUpType[i] of
279 InQuick := not InQuick
280 else if Match(Mark, '\w%d') = 3 then
281 FCounts.Wait := FCounts.Wait + Ord(Mark[3]) - Ord('0')
282 else if Match(Mark, '\_w[%D]') > 0 then
283 Inc(FCounts.HiResWait, StrToInt(GetParam(Mark, 0)))
284 else if Match(Mark, '\s%d') = 3 then
286 else if Match(Mark, '\s%b') > 0 then
293 CountCharacterType(Mark, SB, DB, SPNum, SPWait);
294 Inc(FCounts.QuickChar, SB + DB + SPNum);
297 CountCharacterType(Mark, SB, DB, SPNum, SPWait);
298 Inc(FCounts.Char, SB);
299 Inc(FCounts.DBChar, DB);
300 Inc(FCounts.Specials, SPWait);
303 // Ignore all tag errors
309 function TSsPlayTime.PlayTime(const Script: String): integer;
312 if FSsParser = nil then
313 raise TSsPlayTimeInitException.Create('SsParser is not set');
314 if FPlayTimeParams = nil then
315 raise TSsPlayTimeInitException.Create('PlayTimeParams is not set');
316 SsParser.InputString := Script;
318 with PlayTimeParams do
319 Result := CostConst + CostWait * FCounts.Wait + CostSurface * FCounts.Surface +
320 CostHiResWait * FCounts.HiResWait + CostChar * FCounts.Char +
321 CostDBChar * FCounts.DBChar + FCounts.Specials +
322 CostQuickChar * FCounts.QuickChar;
325 procedure TSsPlayTime.SetPlayTimeParams(const Value: TSsPlayTimeParams);
327 FPlayTimeParams := Value;
330 procedure TSsPlayTime.SetSsParser(const Value: TSsParser);
335 { TSsPlayTimeSpecialChar }
337 procedure TSsPlayTimeSpecialChar.Assign(Source: TPersistent);
339 if not(Source is TSsPlayTimeSpecialChar) then
343 Self.FChar := (Source as TSsPlayTimeSpecialChar).FChar;
344 Self.FWait := (Source as TSsPlayTimeSpecialChar).FWait;
348 function TSsPlayTimeSpecialChar.DisplayChar: String;
352 else if FChar = CDBWhiteSpace then
358 function TSsPlayTimeSpecialChar.GetDisplayName: String;
360 Result := Format('"%s" = %d', [DisplayChar, FWait]);
363 procedure TSsPlayTimeSpecialChar.SetChar(const Value: String);
369 if (Value[1] in LeadBytes) then
371 if Length(Value) = 2 then
373 end else if Length(Value) = 1 then
378 procedure TSsPlayTimeSpecialChar.SetWait(const Value: integer);