Subversion Repositories spacemission

Compare Revisions

Regard whitespace Rev 3 → Rev 4

/VCL_DELPHIX_D6/SXMedia/SXEngine.pas
0,0 → 1,221
{
SXMedia Components - Beta 1
--------------------------------
Copyright 1999 Dean Ellis
http://www.sillex.freeserve.co.uk
 
This unit is part of the SXMedia Component Set. This code is
supplied as is with no guarantees and must be used at your own
risk.
 
No modifications to this code must be made without the express
permission of the author. Please report any problems to
support@sillex.freeserve.co.uk
 
You may use these components to create any freeware/shareware
applications that you wish. If the components are to be used in
a commercail product then credit for developement of these components
should be given.
 
Credits :
 
Developer : Dean Ellis
Testers : Dominique Louis
Ivan Blecic
}
unit SXEngine;
 
interface
 
uses
Windows, Messages, SysUtils, Classes, MMSystem;
 
type
TFramesPerSecond = 1..100;
TFreeCyclesEvent = procedure (Sender: TObject; Count:Integer) of object;
 
TSXEngine = class(TComponent)
private
{ Private Data Members }
FFramesPerSecond:TFramesPerSecond;
FEnabled:Boolean;
FThreadPriority:TThreadPriority;
FFPS:Integer;
FActivate:TNotifyEvent;
FDeActivate:TNotifyEvent;
FRender:TNotifyEvent;
FFreeCycles:TFreeCyclesEvent;
protected
{ Property Accessors }
procedure SetTargetFPS(Value:TFramesPerSecond);
function GetTargetFPS:TFramesPerSecond;
procedure SetEnabled(Value:Boolean);
procedure SetThreadPriority(Value:TThreadPriority);
{ Notification methods }
procedure DoRender;
procedure DoActivate;
procedure DoDeActivate;
procedure DoFreeCycles(Count: Integer);
{ Class Helper methods }
public
{ Public methods }
constructor Create(AOwner:TComponent);override;
destructor Destroy; override;
{Public Properties}
property FramesPerSecond : Integer read FFPS write FFPS;
published
{ Published properties }
property TargetFPS : TFramesPerSecond read GetTargetFPS write SetTargetFPS default 30;
property Enabled : Boolean read FEnabled write SetEnabled default False;
property ThreadPriority : TThreadPriority read FThreadPriority write SetThreadPriority;
{ Published Events}
property OnActivate : TNotifyEvent read FActivate write FActivate;
property OnDeActivate : TNotifyEvent read FDeActivate write FDeActivate;
property OnRender : TNotifyEvent read FRender write FRender;
property OnFreeCycles : TFreeCyclesEvent read FFreeCycles write FFreeCycles;
end;
 
implementation
{$J+}
const
FPS : Single = 33.3;
SECOND : Single = 1000.0;
 
type
TGameThread = class(TThread)
private
{ Private declarations }
FThreadCallback:TThreadMethod;
protected
procedure Execute; override;
property ThreadCallback: TThreadMethod read FThreadCallback write FThreadCallback;
public
constructor Create(CreateSupsended:Boolean;Callback:TThreadMethod);
end;
 
var Thread:TGameThread;
{ Important: Methods and properties of objects in VCL can only be used in a
method called using Synchronize, for example,
 
Synchronize(UpdateCaption);
 
and UpdateCaption could look like,
 
procedure TGameThread.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }
 
{ TGameThread }
 
procedure TGameThread.Execute;
begin
{ Place thread code here }
while not Terminated do
begin
try
if Assigned(ThreadCallback) then Synchronize(ThreadCallback);
except
Terminate;
end;
end;
end;
constructor TGameThread.Create(CreateSupsended:Boolean;Callback:TThreadMethod);
begin
inherited Create(CreateSupsended);
ThreadCallback := Callback;
end;
 
{ TSXEngine }
constructor TSXEngine.Create(AOwner:TComponent);
begin
inherited Create(AOwner);
if not (csDesigning in ComponentState) then
begin
if not Assigned(Thread) then
begin
Thread := TGameThread.Create(True,DoRender);
Thread.FreeOnTerminate := False;
Thread.Priority := ThreadPriority;
Thread.Suspended := not Enabled;
end;
DoActivate;
end;
Enabled := False;
TargetFPS := 30;
end;
destructor TSXEngine.Destroy;
begin
if not (csDesigning in ComponentState) then
begin
if Assigned(Thread) then
begin
Thread.Terminate;
Thread.Free;
end;
DoDeActivate;
end;
inherited Destroy;
end;
procedure TSXEngine.SetTargetFPS(Value:TFramesPerSecond);
begin
FFramesPerSecond := Value;
FPS := SECOND / Value;
end;
function TSXEngine.GetTargetFPS:TFramesPerSecond;
begin
Result := FFramesPerSecond;
end;
procedure TSXEngine.SetEnabled(Value:Boolean);
begin
FEnabled := Value;
if Thread <> nil then
Thread.Suspended := not Value;
end;
procedure TSXEngine.SetThreadPriority(Value:TThreadPriority);
begin
FThreadPriority := Value;
if Thread <> nil then
Thread.Priority := Value;
end;
procedure TSXEngine.DoRender;
const Start:DWord = 0;
OldStart:DWord = 0;
Count:Integer =0;
var FreeCycleCount:integer;
begin
try
Start := TimeGetTime;
FreeCycleCount := 0;
if Assigned(FRender) then FRender(Self);
if (Start - OldStart) < SECOND then
Inc(Count)
else
begin
FramesPerSecond := Count;
OldStart := Start;
Count := 0;
end;
repeat
DoFreeCycles(FreeCycleCount);
inc(FreeCycleCount);
until (TimeGetTime - Start) >= FPS;
except
Enabled := False;
Thread.Terminate;
end;
end;
procedure TSXEngine.DoActivate;
begin
if Assigned(FActivate) then FActivate(Self);
end;
procedure TSXEngine.DoDeActivate;
begin
if Assigned(FDeActivate) then FDeActivate(Self);
end;
procedure TSXEngine.DoFreeCycles(Count: Integer);
begin
if Assigned(FFreeCycles) then FFreeCycles(Self,Count);
end;
 
end.