PDA

View Full Version : Clootie Type Question



erikphilips
15-11-2003, 02:08 PM
So i've created this app that has similar properties to the DirectDraw example WindowsedMode_vcl. However when my app runs, it uses 100% of my processor. The cursor moves sporadically, an other app are getting little/no cpu time (winamp).

The example below is missing a TON of important code for real apps, but as long as the window doesn't move and other misc things it shouldn't have the effect i'm seeing.

I reduced my entire code down to:


mdisplay: tDisplay;
mDebugSurface: TSurface;

procedure TfrmMain.FormCreate(Sender: TObject);
begin
mdisplay := tdisplay.create;
mdisplay.CreateWindowedDisplay(handle, 640, 480);
mdisplay.CreateSurfaceFromText(mDebugSurface, 0, pAnsiChar('test'), RGB( 0, 0, 0 ), RGB( 255, 255, 0 ) );
application.OnIdle := GameLoop;
end;

procedure TfrmMain.FormDestroy(Sender: TObject);
begin
mDebugSurface.Free;
mDebugSurface := nil;
mdisplay.Free;
mdisplay := nil;
end;

procedure TfrmMain.GameLoop(Sender: TObject; var Done: Boolean);
var
newTickCount: integer;
hr : HRESULT;
x, y: integer;
begin

newTickCount := getTickCount;
if (newTickCount = lastTickCount) then
exit;
blah;
Done := False;
end;


procedure tFrmMain.blah;
begin
if (mdisplay = nil) then
exit;

mdisplay.Clear(0);
mdisplay.Blt( 10, 10, mDebugSurface, nil );
mdisplay.Flip;
end;

{debug}
procedure TfrmMain.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if ( Key = VK_F12 ) or ( Key = VK_ESCAPE ) then
begin
Key := 0;
Close;
end;
end;
{/debug}

erikphilips
15-11-2003, 03:18 PM
Yikes solved, end of game loop:

lastTickCount := getTickCount;

Clootie
15-11-2003, 08:55 PM
???
Probably Sleep(0) will help you too.

erikphilips
16-11-2003, 10:44 AM
However, a new huge problem cropped up. Nothing is being drawn unless the mouse is moving over the form, or keys are being pressed while the app has focus.

Just to make sure I wasn't crazy, I added:


application.OnIdle := GameLoop;
became
application.OnIdle := GameLoop;
x := 10;
y := 10;

and

mdisplay.Clear(0);
mdisplay.Blt( 10, 10, mDebugSurface, nil );
mdisplay.Flip;
became
x := x + 1;
if x > 50 then x := 10;
y := y + 1;
if y > 50 then y := 10;
mdisplay.Clear(0);
mdisplay.Blt(x ,y , mDebugSurface, nil );
mdisplay.Flip;


And its not like its not drawing, nothing happens in the app unless the above properties are true. While the mouse is moving, the text moves diagonall, but as soon as the mouse stops, so does the text, and when the mouse moves again, the text start right where it left off.

Harry Hunt
16-11-2003, 11:17 AM
I'm not sure if that's really the problem: But Application.OnIdle isn't exactly a good timer for games.
If you want to keep it, make sure you only handle OnIdle if you need to (which means: if your desired framerate is 25 FPS, only handle it 25 times per second). Otherwise your game will always use 100% CPU and it may be choppy and show exactly the behavior you described in your post.

Clootie
16-11-2003, 11:17 AM
procedure TfrmMain.GameLoop(Sender: TObject; var Done: Boolean);
begin
blah;
Sleep(0);
Done := False;
end;

If you want to maintain concrete FPS when you should play with Sleep(positive number).

erikphilips
16-11-2003, 09:48 PM
OnIdle isn't a good timer? Is there a better way to maximize frame rate? And using 100% of unused processor time isn't an issue either; there was a bug that caused it to be a bigger pig then necessary. Not allowing it to draw more then once every millisecond fixes the resource problem. And moving done := false to the top of the OnIdle call fixed the problem with it not drawing until after the application received WMs from my mouse or keyboard events, because I would exit before I told it I wasn?_Tt done.

Clootie, I'm not sure why I should be including a sleep(0), non of the example code uses the sleep procedure. I guess I could limit the frame rate doing that, and it would use slighty less cpu, i'll experiment with it. Thanks for all the help guys. Once I get an good working product (not finished) I'll make a website and post it in the projects forum, so you guys can see what the heck i'm doing :)

Oh lastly is there a way to draw without waiting for Vsync? (Basically turning of Vsync manually.)