Hello
I'm trying fix the movement using WinAPI and DirectX...
My friend called me patrick showed a code of glscene that seems useful,
My code of rendering need be in main loop and the movement of sprites must be at on timer event to stay working properly on all machines?
loop program source:
Code:
procedure TConsole.OnProcess;
begin
Keyboard.Refresh();
Device.Render(0,0,255);
end;
procedure TConsole.DoMove();
begin
if (Keyboard.Key[200]) then
begin
Sprite.X := Sprite.X - 3;
Sprite.DoAnim(True, 0, 11, 0.5)
end;
end;
procedure TConsole.OnRender(Sender: TObject);
begin
Sprite.Draw;
DoMove();
end;
// Enter the message loop
FillChar(msg, SizeOf(msg), 0);
while (msg.message <> WM_QUIT) do
begin
if PeekMessage(msg, 0, 0, 0, PM_REMOVE) then
begin
TranslateMessage(msg);
DispatchMessage(msg);
end
else
begin
Console.OnProcess;
end;
end;
glscene's timer code:
Code:
unit AsyncTimer;
interface
{$i GLScene.inc}
uses Classes;
const
cDEFAULT_TIMER_INTERVAL = 1000;
{$IFDEF UNIX}
type
TThreadPriority = integer;
{$ENDIF}
type
// TAsyncTimer
//
{: Asynchronous timer component (actual 1 ms resolution, if CPU fast enough).<p>
Keep in mind timer resolution is obtained <i>in-between</i> events, but
events are not triggered every x ms. For instance if you set the interval to
5 ms, and your Timer event takes 1 ms to complete, Timer events will actually
be triggered every 5+1=6 ms (that's why it's "asynchronous").<p>
This component is based on ThreadedTimer by Carlos Barbosa. }
TAsyncTimer = class(TComponent)
private
FEnabled: Boolean;
FOnTimer: TNotifyEvent;
FTimerThread: TThread;
protected
procedure SetEnabled(Value: Boolean);
function GetInterval: Word;
procedure SetInterval(Value: Word);
function GetThreadPriority: TThreadPriority;
procedure SetThreadPriority(Value: TThreadPriority);
procedure DoTimer;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
published
property Enabled: Boolean read FEnabled write SetEnabled default False;
property Interval: Word read GetInterval write SetInterval default cDEFAULT_TIMER_INTERVAL;
property OnTimer: TNotifyEvent read FOnTimer write FOnTimer;
property ThreadPriority: TThreadPriority read GetThreadPriority write SetThreadPriority {$IFDEF WINDOWS} default tpTimeCritical{$ENDIF};
end;
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// ------------------------------------------------------------------
implementation
// ------------------------------------------------------------------
// ------------------------------------------------------------------
// ------------------------------------------------------------------
uses SysUtils, GLCrossPlatform;
type
// TTimerThread
//
TTimerThread = class(TThread)
private
FOwner: TAsyncTimer;
FInterval: Word;
protected
constructor Create(CreateSuspended: Boolean); virtual;
procedure Execute; override;
end;
// Create
//
constructor TTimerThread.Create(CreateSuspended: Boolean);
begin
inherited Create(CreateSuspended);
end;
// Execute
//
procedure TTimerThread.Execute;
var
lastTick, nextTick, curTick, perfFreq : Int64;
begin
QueryPerformanceFrequency(perfFreq);
QueryPerformanceCounter(lastTick);
nextTick:=lastTick+(FInterval*perfFreq) div 1000;
while not Terminated do begin
while not Terminated do begin
QueryPerformanceCounter(lastTick);
if lastTick>=nextTick then break;
Sleep(1);
end;
if not Terminated then begin
// if time elapsed run user-event
Synchronize(FOwner.DoTimer);
QueryPerformanceCounter(curTick);
nextTick:=lastTick+(FInterval*perfFreq) div 1000;
if nextTick<=curTick then begin
// CPU too slow... delay to avoid monopolizing what's left
nextTick:=curTick+(FInterval*perfFreq) div 1000;
end;
end;
end;
end;
{ TAsyncTimer }
// Create
//
constructor TAsyncTimer.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
// create timer thread
FTimerThread:=TTimerThread.Create(True);
with TTimerThread(FTimerThread) do begin
FOwner:=Self;
FreeOnTerminate:=False;
{$IFDEF WINDOWS} Priority:=tpTimeCritical;{$ENDIF}
FInterval:=cDEFAULT_TIMER_INTERVAL;
end;
end;
// Destroy
//
destructor TAsyncTimer.Destroy;
begin
Enabled:=False;
FTimerThread.Terminate;
// if stopped, resume
if FTimerThread.Suspended then
FTimerThread.Resume;
// wait & free
FTimerThread.WaitFor;
FTimerThread.Free;
inherited Destroy;
end;
// DoTimer
//
procedure TAsyncTimer.DoTimer;
begin
if Enabled and Assigned(FOnTimer) then
FOnTimer(self);
end;
// SetEnabled
//
procedure TAsyncTimer.SetEnabled(Value: Boolean);
begin
if Value <FEnabled> 0 then begin
FTimerThread.Resume;
end;
end
else
// suspend thread
FTimerThread.Suspend;
end;
end;
function TAsyncTimer.GetInterval: Word;
begin
Result:=TTimerThread(FTimerThread).FInterval;
end;
procedure TAsyncTimer.SetInterval(Value: Word);
begin
if Value<>TTimerThread(FTimerThread).FInterval then begin
TTimerThread(FTimerThread).FInterval:=Value;
end;
end;
function TAsyncTimer.GetThreadPriority: TThreadPriority;
begin
Result:=FTimerThread.Priority;
end;
procedure TAsyncTimer.SetThreadPriority(Value: TThreadPriority);
begin
FTimerThread.Priority:=Value;
end;
end.
Greetings
Bookmarks