Subversion Repositories spacemission

Rev

Rev 1 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1 Rev 4
1
unit DXClass;
1
unit DXClass;
2
 
2
 
3
interface
3
interface
4
 
4
 
5
{$INCLUDE DelphiXcfg.inc}
5
{$INCLUDE DelphiXcfg.inc}
6
 
6
 
7
uses
7
uses
8
  Windows, Messages, SysUtils, Classes, Controls, Forms, MMSystem, DirectX;
8
  Windows, Messages, SysUtils, Classes, Controls, Forms, MMSystem, Graphics, {$IFDEF _DMO_}MultiMon,{$ENDIF}
-
 
9
{$IfDef StandardDX}
-
 
10
  {$IfDef DX9}
-
 
11
  Direct3D, DirectInput,
-
 
12
  {$EndIf}
-
 
13
  DirectDraw, DirectSound;
-
 
14
{$Else}
-
 
15
  DirectX;
-
 
16
{$EndIf}
9
 
17
 
10
type
18
type
11
 
19
 
12
  {  EDirectDrawError  }
20
  {  EDirectDrawError  }
13
 
21
 
14
  EDirectXError = class(Exception);
22
  EDirectXError = class(Exception);
15
 
23
 
16
  {  TDirectX  }
24
  {  TDirectX  }
17
 
25
 
18
  TDirectX = class(TPersistent)
26
  TDirectX = class(TPersistent)
19
  private
27
  private
20
    procedure SetDXResult(Value: HRESULT);
28
    procedure SetDXResult(Value: HRESULT);
21
  protected
29
  protected
22
    FDXResult: HRESULT;
30
    FDXResult: HRESULT;
23
    procedure Check; virtual;
31
    procedure Check; virtual;
24
  public
32
  public
25
    property DXResult: HRESULT read FDXResult write SetDXResult;
33
    property DXResult: HRESULT read FDXResult write SetDXResult;
26
  end;
34
  end;
27
 
35
 
28
  {  TDirectXDriver  }
36
  {  TDirectXDriver  }
29
 
37
 
30
  TDirectXDriver = class(TCollectionItem)
38
  TDirectXDriver = class(TCollectionItem)
31
  private
39
  private
32
    FGUID: PGUID;
40
    FGUID: PGUID;
33
    FGUID2: TGUID;
41
    FGUID2: TGUID;
34
    FDescription: string;
42
    FDescription: string;
35
    FDriverName: string;
43
    FDriverName: string;
36
    procedure SetGUID(Value: PGUID);
44
    procedure SetGUID(Value: PGUID);
37
  public
45
  public
38
    property GUID: PGUID read FGUID write SetGUID;
46
    property GUID: PGUID read FGUID write SetGUID;
39
    property Description: string read FDescription write FDescription;
47
    property Description: string read FDescription write FDescription;
40
    property DriverName: string read FDriverName write FDriverName;
48
    property DriverName: string read FDriverName write FDriverName;
41
  end;
49
  end;
42
 
50
 
43
  {  TDirectXDrivers  }
51
  {  TDirectXDrivers  }
44
 
52
 
45
  TDirectXDrivers = class(TCollection)
53
  TDirectXDrivers = class(TCollection)
46
  private
54
  private
47
    function GetDriver(Index: Integer): TDirectXDriver;
55
    function GetDriver(Index: Integer): TDirectXDriver;
48
  public
56
  public
49
    constructor Create;
57
    constructor Create;
50
    property Drivers[Index: Integer]: TDirectXDriver read GetDriver; default;
58
    property Drivers[Index: Integer]: TDirectXDriver read GetDriver; default;
51
  end;
59
  end;
52
 
60
 
-
 
61
  {$IFDEF _DMO_}
-
 
62
  {  TDirectXDriverEx  }
-
 
63
 
-
 
64
  TDirectXDriverEx = class(TCollectionItem)
-
 
65
  private
-
 
66
    FGUID: PGUID;
-
 
67
    FGUID2: TGUID;
-
 
68
    FDescription: string;
-
 
69
    FDriverName: string;
-
 
70
    FMonitor: HMonitor;
-
 
71
    FMonitorInfo: TMonitorInfo;
-
 
72
    procedure SetGUID(Value: PGUID);
-
 
73
    function ConvertHMonitor(iMonitor: HMonitor): TMonitorInfo;
-
 
74
    function GetMonitorInfo: TMonitorInfo;
-
 
75
    function GetFlags: DWORD;
-
 
76
    function GetTempSpace: TRect;
-
 
77
    function GetWorkSpace: TRect;
-
 
78
  public
-
 
79
    property GUID: PGUID read FGUID write SetGUID;
-
 
80
    property Monitor: HMonitor read FMonitor write FMonitor;
-
 
81
    property MonitorInfo: TMonitorInfo read GetMonitorInfo;
-
 
82
  published
-
 
83
    property Description: string read FDescription write FDescription;
-
 
84
    property DriverName: string read FDriverName write FDriverName;
-
 
85
    property WorkSpace: TRect read GetWorkSpace;
-
 
86
    property TempSpace: TRect read GetTempSpace;
-
 
87
    property Flags: DWORD read GetFlags;
-
 
88
  end;
-
 
89
 
-
 
90
  {  TDirectXDriversEx  }
-
 
91
 
-
 
92
  TDirectXDriversEx = class(TCollection)
-
 
93
  private
-
 
94
    function GetDriver(Index: Integer): TDirectXDriverEx;
-
 
95
  public
-
 
96
    constructor Create;
-
 
97
    property Drivers[Index: Integer]: TDirectXDriverEx read GetDriver; default;
-
 
98
  end;
-
 
99
  {$ENDIF}
-
 
100
 
53
  {  TDXForm  }
101
  {  TDXForm  }
54
 
102
 
55
  TDXForm = class(TForm)
103
  TDXForm = class(TForm)
56
  private
104
  private
57
    FStoreWindow: Boolean;
105
    FStoreWindow: Boolean;
58
    FWindowPlacement: TWindowPlacement;
106
    FWindowPlacement: TWindowPlacement;
59
    procedure WMSYSCommand(var Msg: TWMSYSCommand); message WM_SYSCOMMAND;
107
    procedure WMSYSCommand(var Msg: TWMSYSCommand); message WM_SYSCOMMAND;
60
  protected
108
  protected
61
    procedure CreateParams(var Params: TCreateParams); override;
109
    procedure CreateParams(var Params: TCreateParams); override;
62
  public
110
  public
63
    constructor Create(AOnwer: TComponent); override;
111
    constructor Create(AOnwer: TComponent); override;
64
    destructor Destroy; override;
112
    destructor Destroy; override;
65
    procedure RestoreWindow;
113
    procedure RestoreWindow;
66
    procedure StoreWindow;
114
    procedure StoreWindow;
67
  end;
115
  end;
68
 
116
 
69
  {  TCustomDXTimer  }
117
  {  TCustomDXTimer  }
70
 
118
 
71
  TDXTimerEvent = procedure(Sender: TObject; LagCount: Integer) of object;
119
  TDXTimerEvent = procedure(Sender: TObject; LagCount: Integer) of object;
72
 
120
 
73
  TCustomDXTimer = class(TComponent)
121
  TCustomDXTimer = class(TComponent)
74
  private
122
  private
75
    FActiveOnly: Boolean;
123
    FActiveOnly: Boolean;
76
    FEnabled: Boolean;
124
    FEnabled: Boolean;
77
    FFrameRate: Integer;
125
    FFrameRate: Integer;
78
    FInitialized: Boolean;
126
    FInitialized: Boolean;
79
    FInterval: Cardinal;
127
    FInterval: Cardinal;
80
    FInterval2: Cardinal;
128
    FInterval2: Cardinal;
81
    FNowFrameRate: Integer;
129
    FNowFrameRate: Integer;
82
    FOldTime: DWORD;
130
    FOldTime: DWORD;
83
    FOldTime2: DWORD;
131
    FOldTime2: DWORD;
84
    FOnActivate: TNotifyEvent;
132
    FOnActivate: TNotifyEvent;
85
    FOnDeactivate: TNotifyEvent;
133
    FOnDeactivate: TNotifyEvent;
86
    FOnTimer: TDXTimerEvent;
134
    FOnTimer: TDXTimerEvent;
87
    procedure AppIdle(Sender: TObject; var Done: Boolean);
135
    procedure AppIdle(Sender: TObject; var Done: Boolean);
88
    function AppProc(var Message: TMessage): Boolean;
136
    function AppProc(var Message: TMessage): Boolean;
89
    procedure Finalize;
137
    procedure Finalize;
90
    procedure Initialize;
138
    procedure Initialize;
91
    procedure Resume;
139
    procedure Resume;
92
    procedure SetActiveOnly(Value: Boolean);
140
    procedure SetActiveOnly(Value: Boolean);
93
    procedure SetEnabled(Value: Boolean);
141
    procedure SetEnabled(Value: Boolean);
94
    procedure SetInterval(Value: Cardinal);
142
    procedure SetInterval(Value: Cardinal);
95
    procedure Suspend;
143
    procedure Suspend;
96
  protected
144
  protected
97
    procedure DoActivate; virtual;
145
    procedure DoActivate; virtual;
98
    procedure DoDeactivate; virtual;
146
    procedure DoDeactivate; virtual;
99
    procedure DoTimer(LagCount: Integer); virtual;
147
    procedure DoTimer(LagCount: Integer); virtual;
100
    procedure Loaded; override;
148
    procedure Loaded; override;
101
  public
149
  public
102
    constructor Create(AOwner: TComponent); override;
150
    constructor Create(AOwner: TComponent); override;
103
    destructor Destroy; override;
151
    destructor Destroy; override;
104
    property ActiveOnly: Boolean read FActiveOnly write SetActiveOnly;
152
    property ActiveOnly: Boolean read FActiveOnly write SetActiveOnly;
105
    property Enabled: Boolean read FEnabled write SetEnabled;
153
    property Enabled: Boolean read FEnabled write SetEnabled;
106
    property FrameRate: Integer read FFrameRate;
154
    property FrameRate: Integer read FFrameRate;
107
    property Interval: Cardinal read FInterval write SetInterval;
155
    property Interval: Cardinal read FInterval write SetInterval;
108
    property OnActivate: TNotifyEvent read FOnActivate write FOnActivate;
156
    property OnActivate: TNotifyEvent read FOnActivate write FOnActivate;
109
    property OnDeactivate: TNotifyEvent read FOnDeactivate write FOnDeactivate;
157
    property OnDeactivate: TNotifyEvent read FOnDeactivate write FOnDeactivate;
110
    property OnTimer: TDXTimerEvent read FOnTimer write FOnTimer;
158
    property OnTimer: TDXTimerEvent read FOnTimer write FOnTimer;
111
  end;
159
  end;
112
 
160
 
113
  {  TDXTimer  }
161
  {  TDXTimer  }
114
 
162
 
115
  TDXTimer = class(TCustomDXTimer)
163
  TDXTimer = class(TCustomDXTimer)
116
  published
164
  published
117
    property ActiveOnly;
165
    property ActiveOnly;
118
    property Enabled;
166
    property Enabled;
119
    property Interval;
167
    property Interval;
120
    property OnActivate;
168
    property OnActivate;
121
    property OnDeactivate;
169
    property OnDeactivate;
122
    property OnTimer;
170
    property OnTimer;
123
  end;
171
  end;
124
 
172
 
125
  {  TControlSubClass  }
173
  {  TControlSubClass  }
126
 
174
 
127
  TControlSubClassProc = procedure(var Message: TMessage; DefWindowProc: TWndMethod) of object;
175
  TControlSubClassProc = procedure(var Message: TMessage; DefWindowProc: TWndMethod) of object;
128
 
176
 
129
  TControlSubClass = class
177
  TControlSubClass = class
130
  private
178
  private
131
    FControl: TControl;
179
    FControl: TControl;
132
    FDefWindowProc: TWndMethod;
180
    FDefWindowProc: TWndMethod;
133
    FWindowProc: TControlSubClassProc;
181
    FWindowProc: TControlSubClassProc;
134
    procedure WndProc(var Message: TMessage);
182
    procedure WndProc(var Message: TMessage);
135
  public
183
  public
136
    constructor Create(Control: TControl; WindowProc: TControlSubClassProc);
184
    constructor Create(Control: TControl; WindowProc: TControlSubClassProc);
137
    destructor Destroy; override;
185
    destructor Destroy; override;
138
  end;
186
  end;
139
 
187
 
140
  {  THashCollectionItem  }
188
  {  THashCollectionItem  }
141
 
189
 
142
  THashCollectionItem = class(TCollectionItem)
190
  THashCollectionItem = class(TCollectionItem)
143
  private
191
  private
144
    FHashCode: Integer;
192
    FHashCode: Integer;
145
    FIndex: Integer;
193
    FIndex: Integer;
146
    FName: string;
194
    FName: string;
147
    FLeft: THashCollectionItem;
195
    FLeft: THashCollectionItem;
148
    FRight: THashCollectionItem;
196
    FRight: THashCollectionItem;
149
    procedure SetName(const Value: string);
197
    procedure SetName(const Value: string);
150
    procedure AddHash;
198
    procedure AddHash;
151
    procedure DeleteHash;
199
    procedure DeleteHash;
152
  protected
200
  protected
153
    function GetDisplayName: string; override;
201
    function GetDisplayName: string; override;
154
    procedure SetIndex(Value: Integer); override;
202
    procedure SetIndex(Value: Integer); override;
155
  public
203
  public
156
    constructor Create(Collection: TCollection); override;
204
    constructor Create(Collection: TCollection); override;
157
    destructor Destroy; override;
205
    destructor Destroy; override;
158
    procedure Assign(Source: TPersistent); override;
206
    procedure Assign(Source: TPersistent); override;
159
    property Index: Integer read FIndex write SetIndex;
207
    property Index: Integer read FIndex write SetIndex;
160
  published
208
  published
161
    property Name: string read FName write SetName;
209
    property Name: string read FName write SetName;
162
  end;
210
  end;
163
 
211
 
164
  {  THashCollection  }
212
  {  THashCollection  }
165
 
213
 
166
  THashCollection = class(TCollection)
214
  THashCollection = class(TCollection)
167
  private
215
  private
168
    FHash: array[0..255] of THashCollectionItem;
216
    FHash: array[0..255] of THashCollectionItem;
169
  public
217
  public
170
    function IndexOf(const Name: string): Integer;
218
    function IndexOf(const Name: string): Integer;
171
  end;
219
  end;
172
 
220
 
-
 
221
{Addapted from RXLib.PicClip}
-
 
222
 
-
 
223
  { TPicClip }
-
 
224
  TCellRange = 1..MaxInt;
-
 
225
 
-
 
226
  TDXPictureClip = class(TComponent)
-
 
227
  private
-
 
228
    FPicture: TPicture;
-
 
229
    FRows: TCellRange;
-
 
230
    FCols: TCellRange;
-
 
231
    FBitmap: TBitmap;
-
 
232
    FMasked: Boolean;
-
 
233
    FMaskColor: TColor;
-
 
234
    FOnChange: TNotifyEvent;
-
 
235
    procedure CheckIndex(Index: Integer);
-
 
236
    function GetCell(Col, Row: Cardinal): TBitmap;
-
 
237
    function GetGraphicCell(Index: Integer): TBitmap;
-
 
238
    function GetDefaultMaskColor: TColor;
-
 
239
    function GetIsEmpty: Boolean;
-
 
240
    function GetCount: Integer;
-
 
241
    function GetHeight: Integer;
-
 
242
    function GetWidth: Integer;
-
 
243
    function IsMaskStored: Boolean;
-
 
244
    procedure PictureChanged(Sender: TObject);
-
 
245
    procedure SetHeight(Value: Integer);
-
 
246
    procedure SetPicture(Value: TPicture);
-
 
247
    procedure SetWidth(Value: Integer);
-
 
248
    procedure SetMaskColor(Value: TColor);
-
 
249
  protected
-
 
250
    procedure AssignTo(Dest: TPersistent); override;
-
 
251
    procedure Changed; dynamic;
-
 
252
  public
-
 
253
    constructor Create(AOwner: TComponent); override;
-
 
254
    destructor Destroy; override;
-
 
255
    procedure Assign(Source: TPersistent); override;
-
 
256
    function GetIndex(Col, Row: Cardinal): Integer;
-
 
257
    procedure Draw(Canvas: TCanvas; X, Y, Index: Integer);
-
 
258
    procedure DrawCenter(Canvas: TCanvas; Rect: TRect; Index: Integer);
-
 
259
    property Cells[Col, Row: Cardinal]: TBitmap read GetCell;
-
 
260
    property GraphicCell[Index: Integer]: TBitmap read GetGraphicCell;
-
 
261
    property IsEmpty: Boolean read GetIsEmpty;
-
 
262
    property Count: Integer read GetCount;
-
 
263
  published
-
 
264
    property Cols: TCellRange read FCols write FCols default 1;
-
 
265
    property Height: Integer read GetHeight write SetHeight stored False;
-
 
266
    property Masked: Boolean read FMasked write FMasked default True;
-
 
267
    property Rows: TCellRange read FRows write FRows default 1;
-
 
268
    property Picture: TPicture read FPicture write SetPicture;
-
 
269
    property MaskColor: TColor read FMaskColor write SetMaskColor stored IsMaskStored;
-
 
270
    property Width: Integer read GetWidth write SetWidth stored False;
-
 
271
    property OnChange: TNotifyEvent read FOnChange write FOnChange;
-
 
272
  end;
-
 
273
 
173
function Max(Val1, Val2: Integer): Integer;
274
function Max(Val1, Val2: Integer): Integer; {$IFDEF VER9UP}inline;{$ENDIF}
174
function Min(Val1, Val2: Integer): Integer;
275
function Min(Val1, Val2: Integer): Integer; {$IFDEF VER9UP}inline;{$ENDIF}
175
 
276
 
176
function Cos256(i: Integer): Double;
277
function Cos256(i: Integer): Double;
177
function Sin256(i: Integer): Double;
278
function Sin256(i: Integer): Double;
178
 
279
 
179
function PointInRect(const Point: TPoint; const Rect: TRect): Boolean;
280
function PointInRect(const Point: TPoint; const Rect: TRect): Boolean; {$IFDEF VER9UP}inline;{$ENDIF}
180
function RectInRect(const Rect1, Rect2: TRect): Boolean;
281
function RectInRect(const Rect1, Rect2: TRect): Boolean; {$IFDEF VER9UP}inline;{$ENDIF}
181
function OverlapRect(const Rect1, Rect2: TRect): Boolean;
282
function OverlapRect(const Rect1, Rect2: TRect): Boolean; {$IFDEF VER9UP}inline;{$ENDIF}
-
 
283
 
-
 
284
function WideRect(ALeft, ATop, AWidth, AHeight: Integer): TRect; {$IFDEF VER9UP}inline;{$ENDIF}
-
 
285
 
-
 
286
{ Transformations routines}
-
 
287
 
-
 
288
const
-
 
289
  L_Curve = 0;//The left curve
-
 
290
  R_Curve = 1;//The right curve
-
 
291
 
-
 
292
  C_Add = 0;//Increase (BTC)
-
 
293
  C_Dec = 1;//Decrease (ETC)
-
 
294
 
-
 
295
Type
-
 
296
  TDblPoint = packed record
-
 
297
    X, Y: Double;
-
 
298
  end;
-
 
299
  TSngPoint = packed record //SinglePoint
-
 
300
    X, Y: Single;
-
 
301
  end;
-
 
302
 
-
 
303
 
-
 
304
  //Transformation matrix
-
 
305
  T2DRowCol = Array[1..3] of Array[1..3] of Double;
-
 
306
  T2DVector = Array[1..3] of Double;
-
 
307
  //Distance between 2 points
-
 
308
  function Get2PointRange(a,b: TDblPoint):Double;
-
 
309
  //From vector angular calculation
-
 
310
  function Get256(dX,dY: Double):Double;
-
 
311
  //The angular calculation of the A from B
-
 
312
  function GetARadFromB(A,B: TDblPoint):Double;
-
 
313
 
-
 
314
  //It calculates the TDblPoint
-
 
315
  function DblPoint(a,b:Double):TDblPoint;
-
 
316
  //It converts the TDboPoint to the TPoint
-
 
317
  function TruncDblPoint(DblPos: TDblPoint): TPoint;
-
 
318
 
-
 
319
  function GetPointFromRangeAndAngle(SP: TDblPoint; Range,Angle: Double): TDblPoint;
-
 
320
 
-
 
321
  function Ini2DRowCol: T2DRowCol;
-
 
322
  function Trans2DRowCol(x,y:double):T2DRowCol;
-
 
323
  function Scale2DRowCol(x,y:double):T2DRowCol;
-
 
324
  function Rotate2DRowCol(Theta:double):T2DRowCol;
-
 
325
  function RotateIntoX2DRowCol(x,y: double):T2DRowCol;
-
 
326
  function Multiply2DRowCol(A,B:T2DRowCol):T2DRowCol;
-
 
327
  function ScaleAt2DRowCol(x,y,Sx,Sy:double):T2DRowCol;
-
 
328
  function ReflectAcross2DRowCol(x,y,dx,dy:Double): T2DRowCol;
-
 
329
  function Apply2DVector(V:T2DVector; M:T2DRowCol): T2DVector;
-
 
330
  function RotateAround2DRowCol(x,y,Theta:Double): T2DRowCol;
-
 
331
 
-
 
332
  //Collision decision
-
 
333
  function PointInCircle(PPos,CPos: TPoint; R: integer): Boolean;
-
 
334
  function CircleInCircle(C1Pos,C2Pos: TPoint; R1,R2:Integer): Boolean;
-
 
335
  function SegmentInCircle(SPos,EPos,CPos: TPoint; R: Integer): Boolean;
-
 
336
 
-
 
337
  //If A is closer than B from starting point S, the True is  returned.
-
 
338
  function CheckNearAThanB(S,A,B: TDblPoint): Boolean;
-
 
339
 
-
 
340
  //The Angle of 256 period is returned
-
 
341
  function Angle256(Angle: Single): Single;
-
 
342
 
-
 
343
{ Support functions }
182
 
344
 
183
function WideRect(ALeft, ATop, AWidth, AHeight: Integer): TRect;
-
 
184
procedure ReleaseCom(out Com);
345
procedure ReleaseCom(out Com);
185
function DXLoadLibrary(const FileName, FuncName: string): TFarProc;
346
function DXLoadLibrary(const FileName, FuncName: string): TFarProc;
186
 
347
 
-
 
348
{  Simple helper  }
-
 
349
 
-
 
350
procedure Log(const Co: string; const FName: string{$IFDEF VER4UP} = 'c:\logerr.txt'{$ENDIF});
-
 
351
 
187
implementation
352
implementation
188
 
353
 
189
uses DXConsts;
354
uses DXConsts;
190
 
355
 
191
function Max(Val1, Val2: Integer): Integer;
356
function Max(Val1, Val2: Integer): Integer;
192
begin
357
begin
193
  if Val1>=Val2 then Result := Val1 else Result := Val2;
358
  if Val1>=Val2 then Result := Val1 else Result := Val2;
194
end;
359
end;
195
 
360
 
196
function Min(Val1, Val2: Integer): Integer;
361
function Min(Val1, Val2: Integer): Integer;
197
begin
362
begin
198
  if Val1<=Val2 then Result := Val1 else Result := Val2;
363
  if Val1<=Val2 then Result := Val1 else Result := Val2;
199
end;
364
end;
200
 
365
 
201
function PointInRect(const Point: TPoint; const Rect: TRect): Boolean;
366
function PointInRect(const Point: TPoint; const Rect: TRect): Boolean;
202
begin
367
begin
203
  Result := (Point.X >= Rect.Left) and
368
  Result := (Point.X >= Rect.Left) and
204
            (Point.X <= Rect.Right) and
369
            (Point.X <= Rect.Right) and
205
            (Point.Y >= Rect.Top) and
370
            (Point.Y >= Rect.Top) and
206
            (Point.Y <= Rect.Bottom);
371
            (Point.Y <= Rect.Bottom);
207
end;
372
end;
208
 
373
 
209
function RectInRect(const Rect1, Rect2: TRect): Boolean;
374
function RectInRect(const Rect1, Rect2: TRect): Boolean;
210
begin
375
begin
211
  Result := (Rect1.Left >= Rect2.Left) and
376
  Result := (Rect1.Left >= Rect2.Left) and
212
            (Rect1.Right <= Rect2.Right) and
377
            (Rect1.Right <= Rect2.Right) and
213
            (Rect1.Top >= Rect2.Top) and
378
            (Rect1.Top >= Rect2.Top) and
214
            (Rect1.Bottom <= Rect2.Bottom);
379
            (Rect1.Bottom <= Rect2.Bottom);
215
end;
380
end;
216
 
381
 
217
function OverlapRect(const Rect1, Rect2: TRect): Boolean;
382
function OverlapRect(const Rect1, Rect2: TRect): Boolean;
218
begin
383
begin
219
  Result := (Rect1.Left < Rect2.Right) and
384
  Result := (Rect1.Left < Rect2.Right) and
220
            (Rect1.Right > Rect2.Left) and
385
            (Rect1.Right > Rect2.Left) and
221
            (Rect1.Top < Rect2.Bottom) and
386
            (Rect1.Top < Rect2.Bottom) and
222
            (Rect1.Bottom > Rect2.Top);
387
            (Rect1.Bottom > Rect2.Top);
223
end;
388
end;
224
 
389
 
225
function WideRect(ALeft, ATop, AWidth, AHeight: Integer): TRect;
390
function WideRect(ALeft, ATop, AWidth, AHeight: Integer): TRect;
226
begin
391
begin
227
  with Result do
392
  with Result do
228
  begin
393
  begin
229
    Left := ALeft;
394
    Left := ALeft;
230
    Top := ATop;
395
    Top := ATop;
231
    Right := ALeft+AWidth;
396
    Right := ALeft+AWidth;
232
    Bottom := ATop+AHeight;
397
    Bottom := ATop+AHeight;
233
  end;
398
  end;
234
end;
399
end;
235
 
400
 
236
var
401
var
237
  CosinTable: array[0..255] of Double;
402
  CosinTable: array[0..255] of Double;
238
 
403
 
239
procedure InitCosinTable;
404
procedure InitCosinTable;
240
var
405
var
241
  i: Integer;
406
  i: Integer;
242
begin
407
begin
243
  for i:=0 to 255 do
408
  for i:=0 to 255 do
244
    CosinTable[i] := Cos((i/256)*2*PI);
409
    CosinTable[i] := Cos((i/256)*2*PI);
245
end;
410
end;
246
 
411
 
247
function Cos256(i: Integer): Double;
412
function Cos256(i: Integer): Double;
248
begin
413
begin
249
  Result := CosinTable[i and 255];
414
  Result := CosinTable[i and 255];
250
end;
415
end;
251
 
416
 
252
function Sin256(i: Integer): Double;
417
function Sin256(i: Integer): Double;
253
begin
418
begin
254
  Result := CosinTable[(i+192) and 255];
419
  Result := CosinTable[(i+192) and 255];
255
end;
420
end;
256
 
421
 
257
procedure ReleaseCom(out Com);
422
procedure ReleaseCom(out Com);
258
begin
423
begin
259
end;
424
end;
260
 
425
 
261
var
426
var
262
  LibList: TStringList;
427
  LibList: TStringList;
263
 
428
 
264
function DXLoadLibrary(const FileName, FuncName: string): Pointer;
429
function DXLoadLibrary(const FileName, FuncName: string): Pointer;
265
var
430
var
266
  i: Integer;
431
  i: Integer;
267
  h: THandle;
432
  h: THandle;
268
begin
433
begin
269
  if LibList=nil then
434
  if LibList=nil then
270
    LibList := TStringList.Create;
435
    LibList := TStringList.Create;
271
 
436
 
272
  i := LibList.IndexOf(AnsiLowerCase(FileName));
437
  i := LibList.IndexOf(AnsiLowerCase(FileName));
273
  if i=-1 then
438
  if i=-1 then
274
  begin
439
  begin
275
    {  DLL is loaded.  }
440
    {  DLL is loaded.  }
276
    h := LoadLibrary(PChar(FileName));
441
    h := LoadLibrary(PChar(FileName));
277
    if h=0 then
442
    if h=0 then
278
      raise Exception.CreateFmt(SDLLNotLoaded, [FileName]);
443
      raise Exception.CreateFmt(SDLLNotLoaded, [FileName]);
279
    LibList.AddObject(AnsiLowerCase(FileName), Pointer(h));
444
    LibList.AddObject(AnsiLowerCase(FileName), Pointer(h));
280
  end else
445
  end else
281
  begin
446
  begin
282
    {  DLL has already been loaded.  }
447
    {  DLL has already been loaded.  }
283
    h := THandle(LibList.Objects[i]);
448
    h := THandle(LibList.Objects[i]);
284
  end;
449
  end;
285
 
450
 
286
  Result := GetProcAddress(h, PChar(FuncName));
451
  Result := GetProcAddress(h, PChar(FuncName));
287
  if Result=nil then
452
  if Result=nil then
288
    raise Exception.CreateFmt(SDLLNotLoaded, [FileName]);
453
    raise Exception.CreateFmt(SDLLNotLoaded, [FileName]);
289
end;
454
end;
290
 
455
 
291
procedure FreeLibList;
456
procedure FreeLibList;
292
var
457
var
293
  i: Integer;
458
  i: Integer;
294
begin
459
begin
295
  if LibList<>nil then
460
  if LibList<>nil then
296
  begin
461
  begin
297
    for i:=0 to LibList.Count-1 do
462
    for i:=0 to LibList.Count-1 do
298
      FreeLibrary(THandle(LibList.Objects[i]));
463
      FreeLibrary(THandle(LibList.Objects[i]));
299
    LibList.Free;
464
    LibList.Free;
300
  end;
465
  end;
301
end;
466
end;
302
 
467
 
303
{  TDirectX  }
468
{  TDirectX  }
304
 
469
 
305
procedure TDirectX.Check;
470
procedure TDirectX.Check;
306
begin
471
begin
307
end;
472
end;
308
 
473
 
309
procedure TDirectX.SetDXResult(Value: HRESULT);
474
procedure TDirectX.SetDXResult(Value: HRESULT);
310
begin
475
begin
311
  FDXResult := Value;
476
  FDXResult := Value;
312
  if FDXResult<>0 then Check;
477
  if FDXResult<>0 then Check;
313
end;
478
end;
314
 
479
 
315
{  TDirectXDriver  }
480
{  TDirectXDriver  }
316
 
481
 
317
procedure TDirectXDriver.SetGUID(Value: PGUID);
482
procedure TDirectXDriver.SetGUID(Value: PGUID);
318
begin
483
begin
319
  if not IsBadHugeReadPtr(Value, SizeOf(TGUID)) then
484
  if not IsBadHugeReadPtr(Value, SizeOf(TGUID)) then
320
  begin
485
  begin
321
    FGUID2 := Value^;
486
    FGUID2 := Value^;
322
    FGUID := @FGUID2;
487
    FGUID := @FGUID2;
323
  end else
488
  end else
324
    FGUID := Value;
489
    FGUID := Value;
325
end;
490
end;
326
 
491
 
327
{  TDirectXDrivers  }
492
{  TDirectXDrivers  }
328
 
493
 
329
constructor TDirectXDrivers.Create;
494
constructor TDirectXDrivers.Create;
330
begin
495
begin
331
  inherited Create(TDirectXDriver);
496
  inherited Create(TDirectXDriver);
332
end;
497
end;
333
 
498
 
334
function TDirectXDrivers.GetDriver(Index: Integer): TDirectXDriver;
499
function TDirectXDrivers.GetDriver(Index: Integer): TDirectXDriver;
335
begin
500
begin
336
  Result := (inherited Items[Index]) as TDirectXDriver;
501
  Result := (inherited Items[Index]) as TDirectXDriver;
337
end;
502
end;
338
 
503
 
339
{  TDXForm  }
504
{  TDXForm  }
340
 
505
 
341
var
506
var
342
  SetAppExStyleCount: Integer;
507
  SetAppExStyleCount: Integer;
343
 
508
 
344
constructor TDXForm.Create(AOnwer: TComponent);
509
constructor TDXForm.Create(AOnwer: TComponent);
345
var
510
var
346
  ExStyle: Integer;
511
  ExStyle: Integer;
347
begin
512
begin
348
  inherited Create(AOnwer);
513
  inherited Create(AOnwer);
349
  Inc(SetAppExStyleCount);
514
  Inc(SetAppExStyleCount);
350
  ExStyle := GetWindowLong(Application.Handle, GWL_EXSTYLE);
515
  ExStyle := GetWindowLong(Application.Handle, GWL_EXSTYLE);
351
  ExStyle := ExStyle or WS_EX_TOOLWINDOW;
516
  ExStyle := ExStyle or WS_EX_TOOLWINDOW;
352
  SetWindowLong(Application.Handle, GWL_EXSTYLE, ExStyle);
517
  SetWindowLong(Application.Handle, GWL_EXSTYLE, ExStyle);
353
end;
518
end;
354
 
519
 
355
destructor TDXForm.Destroy;
520
destructor TDXForm.Destroy;
356
var
521
var
357
  ExStyle: Integer;
522
  ExStyle: Integer;
358
begin
523
begin
359
  Dec(SetAppExStyleCount);
524
  Dec(SetAppExStyleCount);
360
  if SetAppExStyleCount=0 then
525
  if SetAppExStyleCount=0 then
361
  begin
526
  begin
362
    ExStyle := GetWindowLong(Application.Handle, GWL_EXSTYLE);
527
    ExStyle := GetWindowLong(Application.Handle, GWL_EXSTYLE);
363
    ExStyle := ExStyle and (not WS_EX_TOOLWINDOW);
528
    ExStyle := ExStyle and (not WS_EX_TOOLWINDOW);
364
    SetWindowLong(Application.Handle, GWL_EXSTYLE, ExStyle);
529
    SetWindowLong(Application.Handle, GWL_EXSTYLE, ExStyle);
365
  end;
530
  end;
366
  inherited Destroy;
531
  inherited Destroy;
367
end;
532
end;
368
 
533
 
369
procedure TDXForm.CreateParams(var Params: TCreateParams);
534
procedure TDXForm.CreateParams(var Params: TCreateParams);
370
begin
535
begin
371
  inherited CreateParams(Params);
536
  inherited CreateParams(Params);
372
  Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
537
  Params.ExStyle := Params.ExStyle or WS_EX_APPWINDOW;
373
end;
538
end;
374
 
539
 
375
procedure TDXForm.RestoreWindow;
540
procedure TDXForm.RestoreWindow;
376
begin
541
begin
377
  if FStoreWindow then
542
  if FStoreWindow then
378
  begin
543
  begin
379
    SetWindowPlacement(Handle, @FWindowPlacement);
544
    SetWindowPlacement(Handle, @FWindowPlacement);
380
    FStoreWindow := False;
545
    FStoreWindow := False;
381
  end;
546
  end;
382
end;
547
end;
383
 
548
 
384
procedure TDXForm.StoreWindow;
549
procedure TDXForm.StoreWindow;
385
begin
550
begin
386
  FWindowPlacement.Length := SizeOf(FWindowPlacement);
551
  FWindowPlacement.Length := SizeOf(FWindowPlacement);
387
  FStoreWindow := GetWindowPlacement(Handle, @FWindowPlacement);
552
  FStoreWindow := GetWindowPlacement(Handle, @FWindowPlacement);
388
end;
553
end;
389
 
554
 
390
procedure TDXForm.WMSYSCommand(var Msg: TWMSYSCommand);
555
procedure TDXForm.WMSYSCommand(var Msg: TWMSYSCommand);
391
begin
556
begin
392
  if Msg.CmdType = SC_MINIMIZE then
557
  if Msg.CmdType = SC_MINIMIZE then
393
  begin
558
  begin
394
    DefaultHandler(Msg);
559
    DefaultHandler(Msg);
395
    WindowState := wsMinimized;
560
    WindowState := wsMinimized;
396
  end else
561
  end else
397
    inherited;
562
    inherited;
398
end;
563
end;
399
 
564
 
400
{  TCustomDXTimer  }
565
{  TCustomDXTimer  }
401
 
566
 
402
constructor TCustomDXTimer.Create(AOwner: TComponent);
567
constructor TCustomDXTimer.Create(AOwner: TComponent);
403
begin
568
begin
404
  inherited Create(AOwner);
569
  inherited Create(AOwner);
405
  FActiveOnly := True;
570
  FActiveOnly := True;
406
  FEnabled := True;
571
  FEnabled := True;
407
  Interval := 1000;
572
  Interval := 1000;
408
  Application.HookMainWindow(AppProc);
573
  Application.HookMainWindow(AppProc);
409
end;
574
end;
410
 
575
 
411
destructor TCustomDXTimer.Destroy;
576
destructor TCustomDXTimer.Destroy;
412
begin
577
begin
413
  Finalize;
578
  Finalize;
414
  Application.UnHookMainWindow(AppProc);
579
  Application.UnHookMainWindow(AppProc);
415
  inherited Destroy;
580
  inherited Destroy;
416
end;
581
end;
417
 
582
 
418
procedure TCustomDXTimer.AppIdle(Sender: TObject; var Done: Boolean);
583
procedure TCustomDXTimer.AppIdle(Sender: TObject; var Done: Boolean);
419
var
584
var
420
  t, t2: DWORD;
585
  t, t2: DWORD;
421
  LagCount, i: Integer;
586
  LagCount, i: Integer;
422
begin
587
begin
423
  Done := False;
588
  Done := False;
424
 
589
 
425
  t := TimeGetTime;
590
  t := TimeGetTime;
426
  t2 := t-FOldTime;
591
  t2 := t-FOldTime;
427
  if t2>=FInterval then
592
  if t2>=FInterval then
428
  begin
593
  begin
429
    FOldTime := t;
594
    FOldTime := t;
430
 
595
 
431
    LagCount := t2 div FInterval2;
596
    LagCount := t2 div FInterval2;
432
    if LagCount<1 then LagCount := 1;
597
    if LagCount<1 then LagCount := 1;
433
 
598
 
434
    Inc(FNowFrameRate);
599
    Inc(FNowFrameRate);
435
 
600
 
436
    i := Max(t-FOldTime2, 1);
601
    i := Max(t-FOldTime2, 1);
437
    if i>=1000 then
602
    if i>=1000 then
438
    begin
603
    begin
439
      FFrameRate := Round(FNowFrameRate*1000/i);
604
      FFrameRate := Round(FNowFrameRate*1000/i);
440
      FNowFrameRate := 0;
605
      FNowFrameRate := 0;
441
      FOldTime2 := t;
606
      FOldTime2 := t;
442
    end;
607
    end;
443
 
608
 
444
    DoTimer(LagCount);
609
    DoTimer(LagCount);
445
  end;
610
  end;
446
end;
611
end;
447
 
612
 
448
function TCustomDXTimer.AppProc(var Message: TMessage): Boolean;
613
function TCustomDXTimer.AppProc(var Message: TMessage): Boolean;
449
begin
614
begin
450
  Result := False;
615
  Result := False;
451
  case Message.Msg of
616
  case Message.Msg of
452
    CM_ACTIVATE:
617
    CM_ACTIVATE:
453
        begin
618
        begin
454
          DoActivate;
619
          DoActivate;
455
          if FInitialized and FActiveOnly then Resume;
620
          if FInitialized and FActiveOnly then Resume;
456
        end;
621
        end;
457
    CM_DEACTIVATE:
622
    CM_DEACTIVATE:
458
        begin
623
        begin
459
          DoDeactivate;
624
          DoDeactivate;
460
          if FInitialized and FActiveOnly then Suspend;
625
          if FInitialized and FActiveOnly then Suspend;
461
        end;
626
        end;
462
  end;
627
  end;
463
end;
628
end;
464
 
629
 
465
procedure TCustomDXTimer.DoActivate;
630
procedure TCustomDXTimer.DoActivate;
466
begin
631
begin
467
  if Assigned(FOnActivate) then FOnActivate(Self);
632
  if Assigned(FOnActivate) then FOnActivate(Self);
468
end;
633
end;
469
 
634
 
470
procedure TCustomDXTimer.DoDeactivate;
635
procedure TCustomDXTimer.DoDeactivate;
471
begin
636
begin
472
  if Assigned(FOnDeactivate) then FOnDeactivate(Self);
637
  if Assigned(FOnDeactivate) then FOnDeactivate(Self);
473
end;
638
end;
474
 
639
 
475
procedure TCustomDXTimer.DoTimer(LagCount: Integer);
640
procedure TCustomDXTimer.DoTimer(LagCount: Integer);
476
begin
641
begin
477
  if Assigned(FOnTimer) then FOnTimer(Self, LagCount);
642
  if Assigned(FOnTimer) then FOnTimer(Self, LagCount);
478
end;
643
end;
479
 
644
 
480
procedure TCustomDXTimer.Finalize;
645
procedure TCustomDXTimer.Finalize;
481
begin
646
begin
482
  if FInitialized then
647
  if FInitialized then
483
  begin
648
  begin
484
    Suspend;
649
    Suspend;
485
    FInitialized := False;
650
    FInitialized := False;
486
  end;
651
  end;
487
end;
652
end;
488
 
653
 
489
procedure TCustomDXTimer.Initialize;
654
procedure TCustomDXTimer.Initialize;
490
begin
655
begin
491
  Finalize;
656
  Finalize;
492
 
657
 
493
  if ActiveOnly then
658
  if ActiveOnly then
494
  begin
659
  begin
495
    if Application.Active then
660
    if Application.Active then
496
      Resume;
661
      Resume;
497
  end else
662
  end else
498
    Resume;
663
    Resume;
499
  FInitialized := True;
664
  FInitialized := True;
500
end;
665
end;
501
 
666
 
502
procedure TCustomDXTimer.Loaded;
667
procedure TCustomDXTimer.Loaded;
503
begin
668
begin
504
  inherited Loaded;
669
  inherited Loaded;
505
  if (not (csDesigning in ComponentState)) and FEnabled then
670
  if (not (csDesigning in ComponentState)) and FEnabled then
506
    Initialize;
671
    Initialize;
507
end;
672
end;
508
 
673
 
509
procedure TCustomDXTimer.Resume;
674
procedure TCustomDXTimer.Resume;
510
begin
675
begin
511
  FOldTime := TimeGetTime;
676
  FOldTime := TimeGetTime;
512
  FOldTime2 := TimeGetTime;
677
  FOldTime2 := TimeGetTime;
513
  Application.OnIdle := AppIdle;
678
  Application.OnIdle := AppIdle;
514
end;
679
end;
515
 
680
 
516
procedure TCustomDXTimer.SetActiveOnly(Value: Boolean);
681
procedure TCustomDXTimer.SetActiveOnly(Value: Boolean);
517
begin
682
begin
518
  if FActiveOnly<>Value then
683
  if FActiveOnly<>Value then
519
  begin
684
  begin
520
    FActiveOnly := Value;
685
    FActiveOnly := Value;
521
 
686
 
522
    if Application.Active and FActiveOnly then
687
    if Application.Active and FActiveOnly then
523
      if FInitialized and FActiveOnly then Suspend;
688
      if FInitialized and FActiveOnly then Suspend;
524
  end;
689
  end;
525
end;
690
end;
526
 
691
 
527
procedure TCustomDXTimer.SetEnabled(Value: Boolean);
692
procedure TCustomDXTimer.SetEnabled(Value: Boolean);
528
begin
693
begin
529
  if FEnabled<>Value then
694
  if FEnabled<>Value then
530
  begin
695
  begin
531
    FEnabled := Value;
696
    FEnabled := Value;
532
    if ComponentState*[csReading, csLoading]=[] then
697
    if ComponentState*[csReading, csLoading]=[] then
533
      if FEnabled then Initialize else Finalize;
698
      if FEnabled then Initialize else Finalize;
534
  end;
699
  end;
535
end;
700
end;
536
 
701
 
537
procedure TCustomDXTimer.SetInterval(Value: Cardinal);
702
procedure TCustomDXTimer.SetInterval(Value: Cardinal);
538
begin
703
begin
539
  if FInterval<>Value then
704
  if FInterval<>Value then
540
  begin
705
  begin
541
    FInterval := Max(Value, 0);
706
    FInterval := Max(Value, 0);
542
    FInterval2 := Max(Value, 1);
707
    FInterval2 := Max(Value, 1);
543
  end;
708
  end;
544
end;
709
end;
545
 
710
 
546
procedure TCustomDXTimer.Suspend;
711
procedure TCustomDXTimer.Suspend;
547
begin
712
begin
548
  Application.OnIdle := nil;
713
  Application.OnIdle := nil;
549
end;
714
end;
550
 
715
 
551
{  TControlSubClass  }
716
{  TControlSubClass  }
552
 
717
 
553
constructor TControlSubClass.Create(Control: TControl;
718
constructor TControlSubClass.Create(Control: TControl;
554
  WindowProc: TControlSubClassProc);
719
  WindowProc: TControlSubClassProc);
555
begin
720
begin
556
  inherited Create;
721
  inherited Create;
557
  FControl := Control;
722
  FControl := Control;
558
  FDefWindowProc := FControl.WindowProc;
723
  FDefWindowProc := FControl.WindowProc;
559
  FControl.WindowProc := WndProc;
724
  FControl.WindowProc := WndProc;
560
  FWindowProc := WindowProc;
725
  FWindowProc := WindowProc;
561
end;
726
end;
562
 
727
 
563
destructor TControlSubClass.Destroy;
728
destructor TControlSubClass.Destroy;
564
begin
729
begin
565
  FControl.WindowProc := FDefWindowProc;
730
  FControl.WindowProc := FDefWindowProc;
566
  inherited Destroy;
731
  inherited Destroy;
567
end;
732
end;
568
 
733
 
569
procedure TControlSubClass.WndProc(var Message: TMessage);
734
procedure TControlSubClass.WndProc(var Message: TMessage);
570
begin
735
begin
571
  FWindowProc(Message, FDefWindowProc);
736
  FWindowProc(Message, FDefWindowProc);
572
end;
737
end;
573
 
738
 
574
{  THashCollectionItem  }
739
{  THashCollectionItem  }
575
 
740
 
576
function MakeHashCode(const Str: string): Integer;
741
function MakeHashCode(const Str: string): Integer;
577
var
742
var
578
  s: string;
743
  s: string;
579
begin
744
begin
580
  s := AnsiLowerCase(Str);
745
  s := AnsiLowerCase(Str);
581
  Result := Length(s)*16;
746
  Result := Length(s)*16;
582
  if Length(s)>=2 then
747
  if Length(s)>=2 then
583
    Result := Result + (Ord(s[1]) + Ord(s[Length(s)-1]));
748
    Result := Result + (Ord(s[1]) + Ord(s[Length(s)-1]));
584
  Result := Result and 255;
749
  Result := Result and 255;
585
end;
750
end;
586
               
751
               
587
constructor THashCollectionItem.Create(Collection: TCollection);
752
constructor THashCollectionItem.Create(Collection: TCollection);
588
begin
753
begin
589
  inherited Create(Collection);
754
  inherited Create(Collection);
590
  FIndex := inherited Index;
755
  FIndex := inherited Index;
591
  AddHash;
756
  AddHash;
592
end;
757
end;
593
 
758
 
594
destructor THashCollectionItem.Destroy;
759
destructor THashCollectionItem.Destroy;
595
var
760
var
596
  i: Integer;
761
  i: Integer;
597
begin
762
begin
598
  for i:=FIndex+1 to Collection.Count-1 do
763
  for i:=FIndex+1 to Collection.Count-1 do
599
    Dec(THashCollectionItem(Collection.Items[i]).FIndex);
764
    Dec(THashCollectionItem(Collection.Items[i]).FIndex);
600
  DeleteHash;
765
  DeleteHash;
601
  inherited Destroy;
766
  inherited Destroy;
602
end;
767
end;
603
 
768
 
604
procedure THashCollectionItem.Assign(Source: TPersistent);
769
procedure THashCollectionItem.Assign(Source: TPersistent);
605
begin
770
begin
606
  if Source is THashCollectionItem then
771
  if Source is THashCollectionItem then
607
  begin
772
  begin
608
    Name := THashCollectionItem(Source).Name;
773
    Name := THashCollectionItem(Source).Name;
609
  end else
774
  end else
610
    inherited Assign(Source);
775
    inherited Assign(Source);
611
end;
776
end;
612
 
777
 
613
procedure THashCollectionItem.AddHash;
778
procedure THashCollectionItem.AddHash;
614
var
779
var
615
  Item: THashCollectionItem;
780
  Item: THashCollectionItem;
616
begin
781
begin
617
  FHashCode := MakeHashCode(FName);
782
  FHashCode := MakeHashCode(FName);
618
 
783
 
619
  Item := THashCollection(Collection).FHash[FHashCode];
784
  Item := THashCollection(Collection).FHash[FHashCode];
620
  if Item<>nil then
785
  if Item<>nil then
621
  begin
786
  begin
622
    Item.FLeft := Self;
787
    Item.FLeft := Self;
623
    Self.FRight := Item;
788
    Self.FRight := Item;
624
  end;
789
  end;
625
 
790
 
626
  THashCollection(Collection).FHash[FHashCode] := Self;
791
  THashCollection(Collection).FHash[FHashCode] := Self;
627
end;
792
end;
628
 
793
 
629
procedure THashCollectionItem.DeleteHash;
794
procedure THashCollectionItem.DeleteHash;
630
begin
795
begin
631
  if FLeft<>nil then
796
  if FLeft<>nil then
632
  begin
797
  begin
633
    FLeft.FRight := FRight;
798
    FLeft.FRight := FRight;
634
    if FRight<>nil then
799
    if FRight<>nil then
635
      FRight.FLeft := FLeft;
800
      FRight.FLeft := FLeft;
636
  end else
801
  end else
637
  begin
802
  begin
638
    if FHashCode<>-1 then
803
    if FHashCode<>-1 then
639
    begin
804
    begin
640
      THashCollection(Collection).FHash[FHashCode] := FRight;
805
      THashCollection(Collection).FHash[FHashCode] := FRight;
641
      if FRight<>nil then
806
      if FRight<>nil then
642
        FRight.FLeft := nil;
807
        FRight.FLeft := nil;
643
    end;
808
    end;
644
  end;
809
  end;
645
  FLeft := nil;
810
  FLeft := nil;
646
  FRight := nil;
811
  FRight := nil;
647
end;
812
end;
648
 
813
 
649
function THashCollectionItem.GetDisplayName: string;
814
function THashCollectionItem.GetDisplayName: string;
650
begin
815
begin
651
  Result := Name;
816
  Result := Name;
652
  if Result='' then Result := inherited GetDisplayName;
817
  if Result='' then Result := inherited GetDisplayName;
653
end;
818
end;
654
 
819
 
655
procedure THashCollectionItem.SetIndex(Value: Integer);
820
procedure THashCollectionItem.SetIndex(Value: Integer);
656
begin
821
begin
657
  if FIndex<>Value then
822
  if FIndex<>Value then
658
  begin
823
  begin
659
    FIndex := Value;
824
    FIndex := Value;
660
    inherited SetIndex(Value);
825
    inherited SetIndex(Value);
661
  end;
826
  end;
662
end;
827
end;
663
 
828
 
664
procedure THashCollectionItem.SetName(const Value: string);
829
procedure THashCollectionItem.SetName(const Value: string);
665
begin
830
begin
666
  if FName<>Value then
831
  if FName<>Value then
667
  begin
832
  begin
668
    FName := Value;
833
    FName := Value;
669
    DeleteHash;
834
    DeleteHash;
670
    AddHash;
835
    AddHash;
671
  end;
836
  end;
672
end;
837
end;
673
 
838
 
674
{  THashCollection  }
839
{  THashCollection  }
675
 
840
 
676
function THashCollection.IndexOf(const Name: string): Integer;
841
function THashCollection.IndexOf(const Name: string): Integer;
677
var
842
var
678
  Item: THashCollectionItem;
843
  Item: THashCollectionItem;
679
begin
844
begin
680
  Item := FHash[MakeHashCode(Name)];
845
  Item := FHash[MakeHashCode(Name)];
681
  while Item<>nil do
846
  while Item<>nil do
682
  begin
847
  begin
683
    if AnsiCompareText(Item.Name, Name)=0 then
848
    if AnsiCompareText(Item.Name, Name)=0 then
684
    begin
849
    begin
685
      Result := Item.FIndex;
850
      Result := Item.FIndex;
686
      Exit;
851
      Exit;
687
    end;
852
    end;
688
    Item := Item.FRight;
853
    Item := Item.FRight;
689
  end;
854
  end;
690
  Result := -1;
855
  Result := -1;
691
end;
856
end;
692
 
857
 
-
 
858
{  TDXPictureClip  }
-
 
859
 
-
 
860
constructor TDXPictureClip.Create(AOwner: TComponent);
-
 
861
begin
-
 
862
  inherited Create(AOwner);
-
 
863
  FPicture := TPicture.Create;
-
 
864
  FPicture.OnChange := PictureChanged;
-
 
865
  FBitmap := TBitmap.Create;
-
 
866
  FRows := 1;
-
 
867
  FCols := 1;
-
 
868
  FMaskColor := GetDefaultMaskColor;
-
 
869
  FMasked := True;
-
 
870
end;
-
 
871
 
-
 
872
destructor TDXPictureClip.Destroy;
-
 
873
begin
-
 
874
  FOnChange := nil;
-
 
875
  FPicture.OnChange := nil;
-
 
876
  FBitmap.Free;
-
 
877
  FPicture.Free;
-
 
878
  inherited Destroy;
-
 
879
end;
-
 
880
 
-
 
881
procedure TDXPictureClip.Assign(Source: TPersistent);
-
 
882
begin
-
 
883
  if Source is TDXPictureClip then begin
-
 
884
    with TDXPictureClip(Source) do begin
-
 
885
      Self.FRows := Rows;
-
 
886
      Self.FCols := Cols;
-
 
887
      Self.FMasked := Masked;
-
 
888
      Self.FMaskColor := MaskColor;
-
 
889
      Self.FPicture.Assign(FPicture);
-
 
890
    end;
-
 
891
  end
-
 
892
  else if (Source is TPicture) or (Source is TGraphic) then
-
 
893
    FPicture.Assign(Source)
-
 
894
  else inherited Assign(Source);
-
 
895
end;
-
 
896
 
-
 
897
type
-
 
898
  THack = class(TImageList);
-
 
899
 
-
 
900
procedure TDXPictureClip.AssignTo(Dest: TPersistent);
-
 
901
var
-
 
902
  I: Integer;
-
 
903
  SaveChange: TNotifyEvent;
-
 
904
begin
-
 
905
  if (Dest is TPicture) then Dest.Assign(FPicture)
-
 
906
  else if (Dest is TImageList) and not IsEmpty then begin
-
 
907
    with TImageList(Dest) do begin
-
 
908
      SaveChange := OnChange;
-
 
909
      try
-
 
910
        OnChange := nil;
-
 
911
        Clear;
-
 
912
        Width := Self.Width;
-
 
913
        Height := Self.Height;
-
 
914
        for I := 0 to Self.Count - 1 do begin
-
 
915
          if Self.Masked and (MaskColor <> clNone) then
-
 
916
            TImageList(Dest).AddMasked(GraphicCell[I], MaskColor)
-
 
917
          else TImageList(Dest).Add(GraphicCell[I], nil);
-
 
918
        end;
-
 
919
        Masked := Self.Masked;
-
 
920
      finally
-
 
921
        OnChange := SaveChange;
-
 
922
      end;
-
 
923
      THack(Dest).Change;
-
 
924
    end;
-
 
925
  end
-
 
926
  else inherited AssignTo(Dest);
-
 
927
end;
-
 
928
 
-
 
929
procedure TDXPictureClip.Changed;
-
 
930
begin
-
 
931
  if Assigned(FOnChange) then FOnChange(Self);
-
 
932
end;
-
 
933
 
-
 
934
function TDXPictureClip.GetIsEmpty: Boolean;
-
 
935
begin
-
 
936
  Result := not Assigned(Picture) or Picture.Graphic.Empty;
-
 
937
end;
-
 
938
 
-
 
939
function TDXPictureClip.GetCount: Integer;
-
 
940
begin
-
 
941
  if IsEmpty then Result := 0
-
 
942
  else Result := Cols * Rows;
-
 
943
end;
-
 
944
const
-
 
945
{ TBitmap.GetTransparentColor from GRAPHICS.PAS uses this value }
-
 
946
  PaletteMask = $02000000;
-
 
947
 
-
 
948
procedure TDXPictureClip.Draw(Canvas: TCanvas; X, Y, Index: Integer);
-
 
949
 
-
 
950
  function PaletteColor(Color: TColor): Longint;
-
 
951
  begin
-
 
952
    Result := ColorToRGB(Color) or PaletteMask;
-
 
953
  end;
-
 
954
  procedure StretchBltTransparent(DstDC: HDC; DstX, DstY, DstW, DstH: Integer;
-
 
955
    SrcDC: HDC; SrcX, SrcY, SrcW, SrcH: Integer; Palette: HPalette;
-
 
956
    TransparentColor: TColorRef);
-
 
957
  var
-
 
958
    Color: TColorRef;
-
 
959
    bmAndBack, bmAndObject, bmAndMem, bmSave: HBitmap;
-
 
960
    bmBackOld, bmObjectOld, bmMemOld, bmSaveOld: HBitmap;
-
 
961
    MemDC, BackDC, ObjectDC, SaveDC: HDC;
-
 
962
    palDst, palMem, palSave, palObj: HPalette;
-
 
963
  begin
-
 
964
    { Create some DCs to hold temporary data }
-
 
965
    BackDC := CreateCompatibleDC(DstDC);
-
 
966
    ObjectDC := CreateCompatibleDC(DstDC);
-
 
967
    MemDC := CreateCompatibleDC(DstDC);
-
 
968
    SaveDC := CreateCompatibleDC(DstDC);
-
 
969
    { Create a bitmap for each DC }
-
 
970
    bmAndObject := CreateBitmap(SrcW, SrcH, 1, 1, nil);
-
 
971
    bmAndBack := CreateBitmap(SrcW, SrcH, 1, 1, nil);
-
 
972
    bmAndMem := CreateCompatibleBitmap(DstDC, DstW, DstH);
-
 
973
    bmSave := CreateCompatibleBitmap(DstDC, SrcW, SrcH);
-
 
974
    { Each DC must select a bitmap object to store pixel data }
-
 
975
    bmBackOld := SelectObject(BackDC, bmAndBack);
-
 
976
    bmObjectOld := SelectObject(ObjectDC, bmAndObject);
-
 
977
    bmMemOld := SelectObject(MemDC, bmAndMem);
-
 
978
    bmSaveOld := SelectObject(SaveDC, bmSave);
-
 
979
    { Select palette }
-
 
980
    palDst := 0; palMem := 0; palSave := 0; palObj := 0;
-
 
981
    if Palette <> 0 then begin
-
 
982
      palDst := SelectPalette(DstDC, Palette, True);
-
 
983
      RealizePalette(DstDC);
-
 
984
      palSave := SelectPalette(SaveDC, Palette, False);
-
 
985
      RealizePalette(SaveDC);
-
 
986
      palObj := SelectPalette(ObjectDC, Palette, False);
-
 
987
      RealizePalette(ObjectDC);
-
 
988
      palMem := SelectPalette(MemDC, Palette, True);
-
 
989
      RealizePalette(MemDC);
-
 
990
    end;
-
 
991
    { Set proper mapping mode }
-
 
992
    SetMapMode(SrcDC, GetMapMode(DstDC));
-
 
993
    SetMapMode(SaveDC, GetMapMode(DstDC));
-
 
994
    { Save the bitmap sent here }
-
 
995
    BitBlt(SaveDC, 0, 0, SrcW, SrcH, SrcDC, SrcX, SrcY, SRCCOPY);
-
 
996
    { Set the background color of the source DC to the color,         }
-
 
997
    { contained in the parts of the bitmap that should be transparent }
-
 
998
    Color := SetBkColor(SaveDC, PaletteColor(TransparentColor));
-
 
999
    { Create the object mask for the bitmap by performing a BitBlt()  }
-
 
1000
    { from the source bitmap to a monochrome bitmap                   }
-
 
1001
    BitBlt(ObjectDC, 0, 0, SrcW, SrcH, SaveDC, 0, 0, SRCCOPY);
-
 
1002
    { Set the background color of the source DC back to the original  }
-
 
1003
    SetBkColor(SaveDC, Color);
-
 
1004
    { Create the inverse of the object mask }
-
 
1005
    BitBlt(BackDC, 0, 0, SrcW, SrcH, ObjectDC, 0, 0, NOTSRCCOPY);
-
 
1006
    { Copy the background of the main DC to the destination }
-
 
1007
    BitBlt(MemDC, 0, 0, DstW, DstH, DstDC, DstX, DstY, SRCCOPY);
-
 
1008
    { Mask out the places where the bitmap will be placed }
-
 
1009
    StretchBlt(MemDC, 0, 0, DstW, DstH, ObjectDC, 0, 0, SrcW, SrcH, SRCAND);
-
 
1010
    { Mask out the transparent colored pixels on the bitmap }
-
 
1011
    BitBlt(SaveDC, 0, 0, SrcW, SrcH, BackDC, 0, 0, SRCAND);
-
 
1012
    { XOR the bitmap with the background on the destination DC }
-
 
1013
    StretchBlt(MemDC, 0, 0, DstW, DstH, SaveDC, 0, 0, SrcW, SrcH, SRCPAINT);
-
 
1014
    { Copy the destination to the screen }
-
 
1015
    BitBlt(DstDC, DstX, DstY, DstW, DstH, MemDC, 0, 0,
-
 
1016
      SRCCOPY);
-
 
1017
    { Restore palette }
-
 
1018
    if Palette <> 0 then begin
-
 
1019
      SelectPalette(MemDC, palMem, False);
-
 
1020
      SelectPalette(ObjectDC, palObj, False);
-
 
1021
      SelectPalette(SaveDC, palSave, False);
-
 
1022
      SelectPalette(DstDC, palDst, True);
-
 
1023
    end;
-
 
1024
    { Delete the memory bitmaps }
-
 
1025
    DeleteObject(SelectObject(BackDC, bmBackOld));
-
 
1026
    DeleteObject(SelectObject(ObjectDC, bmObjectOld));
-
 
1027
    DeleteObject(SelectObject(MemDC, bmMemOld));
-
 
1028
    DeleteObject(SelectObject(SaveDC, bmSaveOld));
-
 
1029
    { Delete the memory DCs }
-
 
1030
    DeleteDC(MemDC);
-
 
1031
    DeleteDC(BackDC);
-
 
1032
    DeleteDC(ObjectDC);
-
 
1033
    DeleteDC(SaveDC);
-
 
1034
  end;
-
 
1035
  procedure StretchBitmapTransparent(Dest: TCanvas; Bitmap: TBitmap;
-
 
1036
    TransparentColor: TColor; DstX, DstY, DstW, DstH, SrcX, SrcY,
-
 
1037
    SrcW, SrcH: Integer);
-
 
1038
  var
-
 
1039
    CanvasChanging: TNotifyEvent;
-
 
1040
  begin
-
 
1041
    if DstW <= 0 then DstW := Bitmap.Width;
-
 
1042
    if DstH <= 0 then DstH := Bitmap.Height;
-
 
1043
    if (SrcW <= 0) or (SrcH <= 0) then begin
-
 
1044
      SrcX := 0; SrcY := 0;
-
 
1045
      SrcW := Bitmap.Width;
-
 
1046
      SrcH := Bitmap.Height;
-
 
1047
    end;
-
 
1048
    if not Bitmap.Monochrome then
-
 
1049
      SetStretchBltMode(Dest.Handle, STRETCH_DELETESCANS);
-
 
1050
    CanvasChanging := Bitmap.Canvas.OnChanging;
-
 
1051
    Bitmap.Canvas.Lock;
-
 
1052
    try
-
 
1053
      Bitmap.Canvas.OnChanging := nil;
-
 
1054
      if TransparentColor = clNone then begin
-
 
1055
        StretchBlt(Dest.Handle, DstX, DstY, DstW, DstH, Bitmap.Canvas.Handle,
-
 
1056
          SrcX, SrcY, SrcW, SrcH, Dest.CopyMode);
-
 
1057
      end
-
 
1058
      else begin
-
 
1059
        if TransparentColor = clDefault then
-
 
1060
          TransparentColor := Bitmap.Canvas.Pixels[0, Bitmap.Height - 1];
-
 
1061
        if Bitmap.Monochrome then TransparentColor := clWhite
-
 
1062
        else TransparentColor := ColorToRGB(TransparentColor);
-
 
1063
        StretchBltTransparent(Dest.Handle, DstX, DstY, DstW, DstH,
-
 
1064
          Bitmap.Canvas.Handle, SrcX, SrcY, SrcW, SrcH, Bitmap.Palette,
-
 
1065
          TransparentColor);
-
 
1066
      end;
-
 
1067
    finally
-
 
1068
      Bitmap.Canvas.OnChanging := CanvasChanging;
-
 
1069
      Bitmap.Canvas.Unlock;
-
 
1070
    end;
-
 
1071
  end;
-
 
1072
  procedure DrawBitmapTransparent(Dest: TCanvas; DstX, DstY: Integer;
-
 
1073
    Bitmap: TBitmap; TransparentColor: TColor);
-
 
1074
  begin
-
 
1075
    StretchBitmapTransparent(Dest, Bitmap, TransparentColor, DstX, DstY,
-
 
1076
      Bitmap.Width, Bitmap.Height, 0, 0, Bitmap.Width, Bitmap.Height);
-
 
1077
  end;
-
 
1078
var
-
 
1079
  Image: TGraphic;
-
 
1080
begin
-
 
1081
  if Index < 0 then Image := Picture.Graphic
-
 
1082
  else Image := GraphicCell[Index];
-
 
1083
  if (Image <> nil) and not Image.Empty then begin
-
 
1084
    if FMasked and (FMaskColor <> clNone) and
-
 
1085
      (Picture.Graphic is TBitmap) then
-
 
1086
      DrawBitmapTransparent(Canvas, X, Y, TBitmap(Image), FMaskColor)
-
 
1087
    else Canvas.Draw(X, Y, Image);
-
 
1088
  end;
-
 
1089
end;
-
 
1090
 
-
 
1091
procedure TDXPictureClip.DrawCenter(Canvas: TCanvas; Rect: TRect; Index: Integer);
-
 
1092
var
-
 
1093
  X, Y: Integer;
-
 
1094
begin
-
 
1095
  X := (Rect.Left + Rect.Right - Width) div 2;
-
 
1096
  Y := (Rect.Bottom + Rect.Top - Height) div 2;
-
 
1097
  Draw(Canvas, X, Y, Index);
-
 
1098
end;
-
 
1099
 
-
 
1100
procedure TDXPictureClip.CheckIndex(Index: Integer);
-
 
1101
begin
-
 
1102
  if (Index >= Cols * Rows) or (Index < 0) then
-
 
1103
    raise EListError.CreateFmt('%s (%d)', ['Load list error', Index]);
-
 
1104
end;
-
 
1105
 
-
 
1106
function TDXPictureClip.GetIndex(Col, Row: Cardinal): Integer;
-
 
1107
begin
-
 
1108
  Result := Col + (Row * Cols);
-
 
1109
  if (Result >= Cols * Rows) or IsEmpty then Result := -1;
-
 
1110
end;
-
 
1111
 
-
 
1112
function TDXPictureClip.GetCell(Col, Row: Cardinal): TBitmap;
-
 
1113
begin
-
 
1114
  Result := GetGraphicCell(GetIndex(Col, Row));
-
 
1115
end;
-
 
1116
 
-
 
1117
function TDXPictureClip.GetGraphicCell(Index: Integer): TBitmap;
-
 
1118
  procedure AssignBitmapCell(Source: TGraphic; Dest: TBitmap; Cols, Rows,
-
 
1119
    Index: Integer);
-
 
1120
  var
-
 
1121
    CellWidth, CellHeight: Integer;
-
 
1122
  begin
-
 
1123
    if (Source <> nil) and (Dest <> nil) then begin
-
 
1124
      if Cols <= 0 then Cols := 1;
-
 
1125
      if Rows <= 0 then Rows := 1;
-
 
1126
      if Index < 0 then Index := 0;
-
 
1127
      CellWidth := Source.Width div Cols;
-
 
1128
      CellHeight := Source.Height div Rows;
-
 
1129
      with Dest do begin
-
 
1130
        Width := CellWidth; Height := CellHeight;
-
 
1131
      end;
-
 
1132
      if Source is TBitmap then begin
-
 
1133
        Dest.Canvas.CopyRect(Bounds(0, 0, CellWidth, CellHeight),
-
 
1134
          TBitmap(Source).Canvas, Bounds((Index mod Cols) * CellWidth,
-
 
1135
          (Index div Cols) * CellHeight, CellWidth, CellHeight));
-
 
1136
        Dest.TransparentColor := TBitmap(Source).TransparentColor;
-
 
1137
      end
-
 
1138
      else begin
-
 
1139
        Dest.Canvas.Brush.Color := clSilver;
-
 
1140
        Dest.Canvas.FillRect(Bounds(0, 0, CellWidth, CellHeight));
-
 
1141
        Dest.Canvas.Draw(-(Index mod Cols) * CellWidth,
-
 
1142
          -(Index div Cols) * CellHeight, Source);
-
 
1143
      end;
-
 
1144
      Dest.Transparent := Source.Transparent;
-
 
1145
    end;
-
 
1146
  end;
-
 
1147
begin
-
 
1148
  CheckIndex(Index);
-
 
1149
  AssignBitmapCell(Picture.Graphic, FBitmap, Cols, Rows, Index);
-
 
1150
  if Picture.Graphic is TBitmap then
-
 
1151
    if FBitmap.PixelFormat <> pfDevice then
-
 
1152
      FBitmap.PixelFormat := TBitmap(Picture.Graphic).PixelFormat;
-
 
1153
  FBitmap.TransparentColor := FMaskColor or PaletteMask;
-
 
1154
  FBitmap.Transparent := (FMaskColor <> clNone) and Masked;
-
 
1155
  Result := FBitmap;
-
 
1156
end;
-
 
1157
 
-
 
1158
function TDXPictureClip.GetDefaultMaskColor: TColor;
-
 
1159
begin
-
 
1160
  Result := clOlive;
-
 
1161
  if (Picture.Graphic <> nil) and (Picture.Graphic is TBitmap) then
-
 
1162
    Result := TBitmap(Picture.Graphic).TransparentColor and
-
 
1163
      not PaletteMask;
-
 
1164
end;
-
 
1165
 
-
 
1166
function TDXPictureClip.GetHeight: Integer;
-
 
1167
begin
-
 
1168
  Result := Picture.Height div FRows;
-
 
1169
end;
-
 
1170
 
-
 
1171
function TDXPictureClip.GetWidth: Integer;
-
 
1172
begin
-
 
1173
  Result := Picture.Width div FCols;
-
 
1174
end;
-
 
1175
 
-
 
1176
function TDXPictureClip.IsMaskStored: Boolean;
-
 
1177
begin
-
 
1178
  Result := MaskColor <> GetDefaultMaskColor;
-
 
1179
end;
-
 
1180
 
-
 
1181
procedure TDXPictureClip.SetMaskColor(Value: TColor);
-
 
1182
begin
-
 
1183
  if Value <> FMaskColor then begin
-
 
1184
    FMaskColor := Value;
-
 
1185
    Changed;
-
 
1186
  end;
-
 
1187
end;
-
 
1188
 
-
 
1189
procedure TDXPictureClip.PictureChanged(Sender: TObject);
-
 
1190
begin
-
 
1191
  FMaskColor := GetDefaultMaskColor;
-
 
1192
  if not (csReading in ComponentState) then Changed;
-
 
1193
end;
-
 
1194
 
-
 
1195
procedure TDXPictureClip.SetHeight(Value: Integer);
-
 
1196
begin
-
 
1197
  if (Value > 0) and (Picture.Height div Value > 0) then
-
 
1198
    Rows := Picture.Height div Value;
-
 
1199
end;
-
 
1200
 
-
 
1201
procedure TDXPictureClip.SetWidth(Value: Integer);
-
 
1202
begin
-
 
1203
  if (Value > 0) and (Picture.Width div Value > 0) then
-
 
1204
    Cols := Picture.Width div Value;
-
 
1205
end;
-
 
1206
 
-
 
1207
procedure TDXPictureClip.SetPicture(Value: TPicture);
-
 
1208
begin
-
 
1209
  FPicture.Assign(Value);
-
 
1210
end;
-
 
1211
 
-
 
1212
{ Transformations routines }
-
 
1213
{ Authorisation: Mr. Takanori Kawasaki}
-
 
1214
 
-
 
1215
//Distance between 2 points is calculated
-
 
1216
function Get2PointRange(a,b: TDblPoint):Double;
-
 
1217
var
-
 
1218
  x,y: Double;
-
 
1219
begin
-
 
1220
  x := a.X - b.X;
-
 
1221
  y := a.Y - b.Y;
-
 
1222
  Result := Sqrt(x*x+y*y);
-
 
1223
end;
-
 
1224
 
-
 
1225
//Direction angle in the coordinate A which was seen from  coordinate B is calculated
-
 
1226
function GetARadFromB(A,B: TDblPoint):Double;
-
 
1227
var
-
 
1228
  dX,dY: Double;
-
 
1229
begin
-
 
1230
  dX := A.X - B.X;
-
 
1231
  dY := A.Y - B.Y;
-
 
1232
  Result := Get256(dX,dY);
-
 
1233
end;
-
 
1234
 
-
 
1235
//Direction angle is returned with 0 - 255.
-
 
1236
function Get256(dX,dY:Double):Double;
-
 
1237
begin
-
 
1238
  Result := 0;
-
 
1239
  if dX > 0 then
-
 
1240
  begin//0-63
-
 
1241
    if dY > 0 then Result := ArcTan(dY / dX)          // 0 < Res < 90
-
 
1242
    else//0
-
 
1243
    if dY = 0 then Result := 0                        // 0
-
 
1244
    else//192-255
-
 
1245
    if dY < 0 then Result := 2*Pi + ArcTan(dY / dX)   // 270 < Res < 360
-
 
1246
  end else
-
 
1247
  if dX = 0 then
-
 
1248
  begin//64
-
 
1249
    if dY > 0 then Result := 1 / 2 * Pi               // 90
-
 
1250
    else//0
-
 
1251
    if dY = 0 then Result := 0                        // 0
-
 
1252
    else//192
-
 
1253
    if dY < 0 then Result := 3 / 2 * Pi               // 270
-
 
1254
  end else
-
 
1255
  if dX < 0 then
-
 
1256
  begin//64-127
-
 
1257
    if dY > 0 then Result := Pi + ArcTan(dY / dX)     // 90 < Res < 180
-
 
1258
    else//128
-
 
1259
    if dY = 0 then Result := Pi                       // 180
-
 
1260
    else//128-191
-
 
1261
    if dY < 0 then Result := Pi + ArcTan(dY / dX)     // 180 < Res < 270
-
 
1262
  end;
-
 
1263
  Result := 256 * Result / (2*Pi);
-
 
1264
end;
-
 
1265
 
-
 
1266
//From the coordinate SP the Range it calculates the point  which leaves with the angular Angle
-
 
1267
function GetPointFromRangeAndAngle(SP: TDblPoint; Range,Angle: Double): TDblPoint;
-
 
1268
begin
-
 
1269
  Result.X := SP.X + Range * Cos(Angle);
-
 
1270
  Result.Y := SP.Y + Range * Sin(Angle);
-
 
1271
end;
-
 
1272
 
-
 
1273
//* As for coordinate transformation coordinate for mathematics is used
-
 
1274
//Identity matrix for the 2d is returned.
-
 
1275
function Ini2DRowCol: T2DRowCol;
-
 
1276
var
-
 
1277
  i,ii:integer;
-
 
1278
begin
-
 
1279
  for i := 1 to 3 do
-
 
1280
    for ii := 1 to 3 do
-
 
1281
      if i = ii then Result[i,ii] := 1 else Result[i,ii] := 0;
-
 
1282
end;
-
 
1283
 
-
 
1284
//Transformation matrix of the portable quantity
-
 
1285
//where the one  for 2d is appointed is returned.
-
 
1286
function Trans2DRowCol(x,y:double):T2DRowCol;
-
 
1287
begin
-
 
1288
  Result := Ini2DRowCol;
-
 
1289
  Result[3,1] := x;
-
 
1290
  Result[3,2] := y;
-
 
1291
end;
-
 
1292
 
-
 
1293
//Conversion coordinate of the expansion and contraction
-
 
1294
//quantity where the one for 2d is appointed is returned.
-
 
1295
function Scale2DRowCol(x,y:double):T2DRowCol;
-
 
1296
begin
-
 
1297
  Result := Ini2DRowCol;
-
 
1298
  Result[1,1] := x;
-
 
1299
  Result[2,2] := y;
-
 
1300
end;
-
 
1301
 
-
 
1302
//Coordinate transformation of the rotary quantity
-
 
1303
//where the  one for 2d is appointed is returned.
-
 
1304
function Rotate2DRowCol(Theta:double):T2DRowCol;
-
 
1305
begin
-
 
1306
  Result := Ini2DRowCol;
-
 
1307
  Result[1,1] := Cos256(Trunc(Theta));
-
 
1308
  Result[1,2] := Sin256(Trunc(Theta));
-
 
1309
  Result[2,1] := -1 * Result[1,2];
-
 
1310
  Result[2,2] := Result[1,1];
-
 
1311
end;
-
 
1312
 
-
 
1313
//You apply two conversion coordinates and adjust.
-
 
1314
function Multiply2DRowCol(A,B:T2DRowCol):T2DRowCol;
-
 
1315
begin
-
 
1316
  Result[1,1] := A[1,1] * B[1,1] + A[1,2] * B[2,1];
-
 
1317
  Result[1,2] := A[1,1] * B[1,2] + A[1,2] * B[2,2];
-
 
1318
  Result[1,3] := 0;
-
 
1319
  Result[2,1] := A[2,1] * B[1,1] + A[2,2] * B[2,1];
-
 
1320
  Result[2,2] := A[2,1] * B[1,2] + A[2,2] * B[2,2];
-
 
1321
  Result[2,3] := 0;
-
 
1322
  Result[3,1] := A[3,1] * B[1,1] + A[3,2] * B[2,1] + B[3,1];
-
 
1323
  Result[3,2] := A[3,1] * B[1,2] + A[3,2] * B[2,2] + B[3,2];
-
 
1324
  Result[3,3] := 1;
-
 
1325
end;
-
 
1326
 
-
 
1327
//Until coordinate (the X and the Y) comes on the X axis,
-
 
1328
//the  conversion coordinate which turns the position
-
 
1329
//of the point is  returned.
-
 
1330
function RotateIntoX2DRowCol(x,y: double):T2DRowCol;
-
 
1331
var
-
 
1332
  d: double;
-
 
1333
begin
-
 
1334
  Result := Ini2DRowCol;
-
 
1335
  d := sqrt(x*x+y*y);
-
 
1336
  Result[1,1] := x / d;
-
 
1337
  Result[1,2] := y / d;
-
 
1338
  Result[2,1] := -1 * Result[1,2];
-
 
1339
  Result[2,2] := Result[1,1];
-
 
1340
end;
-
 
1341
 
-
 
1342
//Coordinate (the X and the Y) as a center, the conversion
-
 
1343
//coordinate which does the scaling of the magnification ratio
-
 
1344
//which is  appointed with the Sx and the Sy is returned.
-
 
1345
function ScaleAt2DRowCol(x,y,Sx,Sy:double):T2DRowCol;
-
 
1346
var
-
 
1347
  T,S,TInv,M:T2DRowCol;
-
 
1348
begin
-
 
1349
  T := Trans2DRowCol(-x,-y);
-
 
1350
  TInv := Trans2DRowCol(x,y);
-
 
1351
  S := Scale2DRowCol(Sx,Sy);
-
 
1352
  M := Multiply2DRowCol(T,S);
-
 
1353
  Result := Multiply2DRowCol(M,T);
-
 
1354
end;
-
 
1355
 
-
 
1356
//Coordinate (the X and the Y) it passes, comes hard and
-
 
1357
//(DX and the dy) with the direction which is shown it
-
 
1358
//returns the  transformation matrix which does the reflected
-
 
1359
//image conversion which  centers the line which faces.
-
 
1360
function ReflectAcross2DRowCol(x,y,dx,dy:Double): T2DRowCol;
-
 
1361
var
-
 
1362
  T,R,S,RInv,TInv,M1,M2,M3: T2DRowCol;
-
 
1363
begin
-
 
1364
  T := Trans2DRowCol(-x,-y);
-
 
1365
  TInv := Trans2DRowCol(x,y);
-
 
1366
  R := RotateIntoX2DRowCol(dx,dy);
-
 
1367
  RInv := RotateIntoX2DRowCol(dx,-dy);
-
 
1368
  S := Scale2DRowCol(1,-1);
-
 
1369
  M1 := Multiply2DRowCol(T,R);
-
 
1370
  M2 := Multiply2DRowCol(S,RInv);
-
 
1371
  M3 := Multiply2DRowCol(M1,M2);
-
 
1372
  Result := Multiply2DRowCol(M3,TInv);
-
 
1373
end;
-
 
1374
 
-
 
1375
//Coordinate focusing on (the X and the Y) the transformation
-
 
1376
//matrix which turns the position of the point with angle Theta is  returned.
-
 
1377
function RotateAround2DRowCol(x,y,Theta:Double): T2DRowCol;
-
 
1378
var
-
 
1379
  T,R,TInv,M: T2DRowCol;
-
 
1380
begin
-
 
1381
  T := Trans2DRowCol(-x,-y);
-
 
1382
  TInv := Trans2DRowCol(x,y);
-
 
1383
  R := Rotate2DRowCol(Theta);
-
 
1384
  M := Multiply2DRowCol(T,R);
-
 
1385
  Result := Multiply2DRowCol(M,TInv);
-
 
1386
end;
-
 
1387
 
-
 
1388
//Transformation matrix is applied to the point.
-
 
1389
function Apply2DVector(V:T2DVector; M:T2DRowCol): T2DVector;
-
 
1390
begin
-
 
1391
  Result[1] := V[1] * M[1,1] + V[2] * M[2,1] + M[3,1];
-
 
1392
  Result[2] := V[1] * M[1,2] + V[2] * M[2,2] + M[3,2];
-
 
1393
  Result[3] := 1;
-
 
1394
end;
-
 
1395
 
-
 
1396
//The TDblPoint is returned
-
 
1397
function DblPoint(a,b:Double):TDblPoint;
-
 
1398
begin
-
 
1399
  Result.X := a;
-
 
1400
  Result.Y := b;
-
 
1401
end;
-
 
1402
 
-
 
1403
function TruncDblPoint(DblPos: TDblPoint): TPoint;
-
 
1404
begin
-
 
1405
  Result.X := Trunc(DblPos.X);
-
 
1406
  Result.Y := Trunc(DblPos.Y);
-
 
1407
end;
-
 
1408
{
-
 
1409
+-----------------------------------------------------------------------------+
-
 
1410
|Collision decision                                                           |
-
 
1411
+-----------------------------------------------------------------------------+}
-
 
1412
 
-
 
1413
//Point and circle
-
 
1414
function PointInCircle(PPos,CPos: TPoint; R: integer): Boolean;
-
 
1415
begin
-
 
1416
  Result := (PPos.X - CPos.X)*(PPos.X - CPos.X)+(PPos.Y - CPos.Y)*(PPos.Y - CPos.Y)<= R*R;
-
 
1417
end;
-
 
1418
 
-
 
1419
//Circle and circle
-
 
1420
function CircleInCircle(C1Pos,C2Pos: TPoint; R1,R2:Integer): Boolean;
-
 
1421
begin
-
 
1422
  Result := (C1Pos.X - C2Pos.X)*(C1Pos.X - C2Pos.X)+(C1Pos.Y - C2Pos.Y)*(C1Pos.Y - C2Pos.Y) <= (R1+R2)*(R1+R2);
-
 
1423
end;
-
 
1424
 
-
 
1425
//Circle and line segment
-
 
1426
function SegmentInCircle(SPos,EPos,CPos: TPoint; R: Integer): Boolean;
-
 
1427
var
-
 
1428
  V,C: TPoint;
-
 
1429
  VC,VV,CC:integer;
-
 
1430
begin
-
 
1431
  Result := False;
-
 
1432
  V.X := EPos.X - SPos.X; V.Y := EPos.Y - SPos.Y;
-
 
1433
  C.X := CPos.X - SPos.X; C.Y := CPos.Y - SPos.Y;
-
 
1434
  VC := V.X * C.X + V.Y * C.Y;
-
 
1435
  if VC < 0 then
-
 
1436
  begin
-
 
1437
    Result := (C.X * C.X + C.Y * C.Y) <= R*R;
-
 
1438
  end
-
 
1439
  else
-
 
1440
  begin
-
 
1441
    VV := V.X * V.X + V.Y * V.Y;
-
 
1442
    if VC >= VV then
-
 
1443
    begin
-
 
1444
      Result := (EPos.X - CPos.X)*(EPos.X - CPos.X)+(EPos.Y - CPos.Y)*(EPos.Y - CPos.Y) <= R * R;
-
 
1445
    end
-
 
1446
    else
-
 
1447
      if VC < VV then
-
 
1448
      begin
-
 
1449
        CC := C.X * C.X + C.Y * C.Y;
-
 
1450
        Result := CC - (VC div VV)* VC <= R*R;
-
 
1451
      end;
-
 
1452
  end;
-
 
1453
end;
-
 
1454
 
-
 
1455
//Angle recalc
-
 
1456
function Angle256(Angle: Single): Single;
-
 
1457
begin
-
 
1458
  Result := Angle;
-
 
1459
  While Result < 0 do Result := Result + 256;
-
 
1460
  While Result >= 256 do Result := Result -256;
-
 
1461
end;
-
 
1462
 
-
 
1463
//If A is closer than B from starting point S, the True is  returned.
-
 
1464
function CheckNearAThanB(S,A,B: TDblPoint): Boolean;
-
 
1465
begin
-
 
1466
  Result := (S.X-A.X)*(S.X-A.X)+(S.Y-A.Y)*(S.Y-A.Y) <= (S.X-B.X)*(S.X-B.X)+(S.Y-B.Y)*(S.Y-B.Y);
-
 
1467
end;
-
 
1468
 
-
 
1469
function CircumCenter3Pt(const x1, y1, x2, y2, x3, y3: Single; out Px, Py: Single): Boolean;
-
 
1470
var
-
 
1471
  A,B,C,D,E,F,G: Single;
-
 
1472
begin
-
 
1473
  A := x2 - x1;
-
 
1474
  B := y2 - y1;
-
 
1475
  C := x3 - x1;
-
 
1476
  D := y3 - y1;
-
 
1477
  E := A * (x1 + x2) + B * (y1 + y2);
-
 
1478
  F := C * (x1 + x3) + D * (y1 + y3);
-
 
1479
  G := 2.0 * (A * (y3 - y2) - B * (x3 - x2));
-
 
1480
  Result := G <> 0.0;
-
 
1481
  if Result then begin
-
 
1482
    Px := (D * E - B * F) / G;
-
 
1483
    Py := (A * F - C * E) / G;
-
 
1484
  end;
-
 
1485
end;
-
 
1486
 
-
 
1487
function Distance(const x1, y1, x2, y2: Double): Double;
-
 
1488
begin
-
 
1489
  Result := Sqrt(Sqr(y2 - y1) + Sqr(x2 - x1));
-
 
1490
end;
-
 
1491
 
-
 
1492
procedure InCenter(const x1, y1, x2, y2, x3, y3: Double; out Px, Py: Double);
-
 
1493
var
-
 
1494
  Perim: Double;
-
 
1495
  Side12: Double;
-
 
1496
  Side23: Double;
-
 
1497
  Side31: Double;
-
 
1498
begin
-
 
1499
  Side12 := Distance(x1, y1, x2, y2);
-
 
1500
  Side23 := Distance(x2, y2, x3, y3);
-
 
1501
  Side31 := Distance(x3, y3, x1, y1);
-
 
1502
  { Using Heron's S=UR }
-
 
1503
  Perim := 1.0 / (Side12 + Side23 + Side31);
-
 
1504
  Px := (Side23 * x1 + Side31 * x2 + Side12 * x3) * Perim;
-
 
1505
  Py := (Side23 * y1 + Side31 * y2 + Side12 * y3) * Perim;
-
 
1506
end;
-
 
1507
 
-
 
1508
function PointInTriangle(const Px, Py, x1, y1, x2, y2, x3, y3: Double): Boolean;
-
 
1509
  function Orientation(const x1, y1, x2, y2, Px, Py: Double): Integer;
-
 
1510
  var
-
 
1511
    Orin: Double;
-
 
1512
  begin
-
 
1513
    (* Linear determinant of the 3 points *)
-
 
1514
    Orin := (x2 - x1) * (py - y1) - (px - x1) * (y2 - y1);
-
 
1515
 
-
 
1516
    if Orin > 0.0 then
-
 
1517
      Result := +1             (* Orientaion is to the right-hand side *)
-
 
1518
    else if Orin < 0.0 then
-
 
1519
      Result := -1             (* Orientaion is to the left-hand side  *)
-
 
1520
    else
-
 
1521
      Result := 0;             (* Orientaion is neutral aka collinear  *)
-
 
1522
  end;
-
 
1523
var
-
 
1524
  Or1, Or2, Or3: Integer;
-
 
1525
begin
-
 
1526
  Or1 := Orientation(x1, y1, x2, y2, Px, Py);
-
 
1527
  Or2 := Orientation(x2, y2, x3, y3, Px, Py);
-
 
1528
  Or3 := Orientation(x3, y3, x1, y1, Px, Py);
-
 
1529
 
-
 
1530
  if (Or1 = Or2) and (Or2 = Or3) then
-
 
1531
    Result := True
-
 
1532
  else if Or1 = 0 then
-
 
1533
    Result := (Or2 = 0) or (Or3 = 0)
-
 
1534
  else if Or2 = 0 then
-
 
1535
    Result := (Or1 = 0) or (Or3 = 0)
-
 
1536
  else if Or3 = 0 then
-
 
1537
    Result := (Or2 = 0) or (Or1 = 0)
-
 
1538
  else
-
 
1539
    Result := False;
-
 
1540
end;
-
 
1541
 
-
 
1542
procedure Log(const Co: string; const FName: string);
-
 
1543
var F: Text; D: TDateTime;
-
 
1544
  Hour, Minute, Second, MSec: Word;
-
 
1545
begin
-
 
1546
  AsSignFile(F, FName);
-
 
1547
  if FileExists(FName) then Append(F)
-
 
1548
  else ReWrite(F);
-
 
1549
  try
-
 
1550
    D := Now;
-
 
1551
    DecodeTime(D, Hour, Minute, Second, MSec);
-
 
1552
    WriteLn(F, DateToStr(D) + ' ' + IntToStr(Hour)+':'+IntToStr(Minute)+':'+IntToStr(Second)+ '.'+IntToStr(MSec) +' ' + Co);
-
 
1553
  finally
-
 
1554
    CloseFile(F);
-
 
1555
  end;
-
 
1556
end;
-
 
1557
 
-
 
1558
{$IFDEF _DMO_}
-
 
1559
 
-
 
1560
{ TDirectXDriverEx }
-
 
1561
 
-
 
1562
function TDirectXDriverEx.ConvertHMonitor(iMonitor: HMonitor): TMonitorInfo;
-
 
1563
begin
-
 
1564
  ZeroMemory(@Result, sizeof(Result));
-
 
1565
  Result.cbSize := SizeOf(Result);
-
 
1566
  MultiMon.GetMonitorInfo(iMonitor, @Result);
-
 
1567
end;
-
 
1568
 
-
 
1569
function TDirectXDriverEx.GetFlags: DWORD;
-
 
1570
begin
-
 
1571
  Result := ConvertHMonitor(FMonitor).dwFlags;
-
 
1572
end;
-
 
1573
 
-
 
1574
function TDirectXDriverEx.GetMonitorInfo: TMonitorInfo;
-
 
1575
begin
-
 
1576
  Result:= ConvertHMonitor(FMonitor);
-
 
1577
end;
-
 
1578
 
-
 
1579
function TDirectXDriverEx.GetTempSpace: TRect;
-
 
1580
begin
-
 
1581
  Result := ConvertHMonitor(FMonitor).rcWork
-
 
1582
end;
-
 
1583
 
-
 
1584
function TDirectXDriverEx.GetWorkSpace: TRect;
-
 
1585
begin
-
 
1586
  Result := ConvertHMonitor(FMonitor).rcMonitor
-
 
1587
end;
-
 
1588
 
-
 
1589
procedure TDirectXDriverEx.SetGUID(Value: PGUID);
-
 
1590
begin
-
 
1591
  if not IsBadHugeReadPtr(Value, SizeOf(TGUID)) then
-
 
1592
  begin
-
 
1593
    FGUID2 := Value^;
-
 
1594
    FGUID := @FGUID2;
-
 
1595
  end else
-
 
1596
    FGUID := Value;
-
 
1597
end;
-
 
1598
 
-
 
1599
{ TDirectXDriversEx }
-
 
1600
 
-
 
1601
constructor TDirectXDriversEx.Create;
-
 
1602
begin
-
 
1603
  inherited Create(TDirectXDriverEx);
-
 
1604
end;
-
 
1605
 
-
 
1606
function TDirectXDriversEx.GetDriver(Index: Integer): TDirectXDriverEx;
-
 
1607
begin
-
 
1608
  Result := (inherited Items[Index]) as TDirectXDriverEx;
-
 
1609
end;
-
 
1610
 
-
 
1611
{$ENDIF}
-
 
1612
 
693
initialization
1613
initialization
694
  InitCosinTable;
1614
  InitCosinTable;
695
finalization
1615
finalization
696
  FreeLibList;
1616
  FreeLibList;
697
end.
1617
end.
698
 
-