Windows Events
-
Steve Elliott
- Enthusiast

- Posts: 109
- Joined: Sun Jan 01, 2006 9:34 pm
- Location: Wales, UK
Windows Events
What event-like commands do PureBASIC users recommend for fullscreen games programming in a multi-tasking operating system like Windows?
What seems ideal is something like this DirectX code which doesn't halt the program completely to let Windows back-in (which is inefficient). It takes care of Windows calls and gives the program the time that is left (to render in the example).
WPARAM StartMessageLoop()
{
MSG msg;
while(1)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
// use idle time here
Render();
}
}
return msg.wParam;
}
What seems ideal is something like this DirectX code which doesn't halt the program completely to let Windows back-in (which is inefficient). It takes care of Windows calls and gives the program the time that is left (to render in the example).
WPARAM StartMessageLoop()
{
MSG msg;
while(1)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
break;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else
{
// use idle time here
Render();
}
}
return msg.wParam;
}
in fullscreen the messageloop is automatically processed by flipbuffer(). in windowed mode, you have to do it, preferably with WindowEvent():
Code: Select all
Repeat
Event = WindowEvent()
; handle your events here
Until Event = 0 ; until all events have been processed.
-
Steve Elliott
- Enthusiast

- Posts: 109
- Joined: Sun Jan 01, 2006 9:34 pm
- Location: Wales, UK
So Fred are you saying that fullscreen programs will only take the necessary time from Windows and no more?
In other words (using fullscreen) Windows will not try to take cycles back from the PureBASIC program because the PureBASIC game is using all resources and not allowing Windows events to function correctly (causing judder in a game). Is that correct?
In other words (using fullscreen) Windows will not try to take cycles back from the PureBASIC program because the PureBASIC game is using all resources and not allowing Windows events to function correctly (causing judder in a game). Is that correct?
- Joakim Christiansen
- Addict

- Posts: 2452
- Joined: Wed Dec 22, 2004 4:12 pm
- Location: Norway
- Contact:
-
Steve Elliott
- Enthusiast

- Posts: 109
- Joined: Sun Jan 01, 2006 9:34 pm
- Location: Wales, UK
Like I said Joakim that's inefficient - Windows might not require any processing so you've just halted your program for no reason. PureBASIC seems so Windows friendly so surely there's a better way?
Anyway Fred seems to be saying that it's taken care of - but I'd like clarification on this. Fred, do we need to put a delay statement in all of our full screen games?
Anyway Fred seems to be saying that it's taken care of - but I'd like clarification on this. Fred, do we need to put a delay statement in all of our full screen games?
- Joakim Christiansen
- Addict

- Posts: 2452
- Joined: Wed Dec 22, 2004 4:12 pm
- Location: Norway
- Contact:
I sometimes put Delay(1) in my full screen apps to limit cpu usage, which is more than enough.Steve Elliott wrote:Like I said Joakim that's inefficient - Windows might not require any processing so you've just halted your program for no reason. PureBASIC seems so Windows friendly so surely there's a better way?
Anyway Fred seems to be saying that it's taken care of - but I'd like clarification on this. Fred, do we need to put a delay statement in all of our full screen games?
If you want the game to get all the cpu available but not lock up the system,
try Delay(0)
Some people hate it when a game or app use all available cpu though, so maybe make it user selectable.
Silly example:
Myself for misc. apps I use a delay of 1.
For a game I might use a delay of 0,
or allow the user to choose between the two.
And for really simple apps I do not use any delay,
but just use WaitWindowEvent() instead of WindowEvent()
So... The 3 recommended ways to handle loops:
1.
WaitWindowEvent()
Very system friendly, bad program performance for timecritical stuff obviously.
Possibility of using a system timer for loop triggering.
2.
WindowEvent() + Delay(1)
Very common, good performance, very system friendly.
This is the most popular choice!
Uses less power, generates less heat.
(cpu fan will go between low and max depending on your game/app)
3.
WindowEvent() + Delay(0)
Still system friendly, a few other apps might suffer some performance, maximum performance for your app, uses all free cpu power.
Uses more power, generates more heat.
(cpu fan will be going full speed all the time)
I do not recommend any other types of loops myself,
like no Delay() at all. As that tends to suck up not all free cpu but
steal (or rather deny) cpu from other apps as well. (cpu hogging)
You might even end up with graphics and sound stutters in your own program.
System drivers need cpu as well, altough they should have much higher priority than your program, they still share cpu with your program.
My advice is try with Delay(1) if that seems to give bad performance,
try using Delay(0) instead.
Delay(0) is not the same as Delay(1) or Delay(2) etc.
Delay(0) cause no delay at all, but simply let the system do a task switch,
and if nothing else is going on your program get back the cpu at once,
without delays at all.
Delay(1) on the other hand always waits at least 1ms,
regardless if something is using the cpu next or not in the cpu queue.
Lookup the Sleep function in the PSDK documentation for info on the use of 0 microsecond for the delay.
I'm not sure if Linux or Mac behave the same when Delay(0) is used though.
try Delay(0)
Some people hate it when a game or app use all available cpu though, so maybe make it user selectable.
Silly example:
Code: Select all
ms=0 ;High performance (uses all available cpu without locking up system)
ms=1 ;Multitask friendly (only uses as much cpu as needed, other apps should run very well)
Delay(ms)
For a game I might use a delay of 0,
or allow the user to choose between the two.
And for really simple apps I do not use any delay,
but just use WaitWindowEvent() instead of WindowEvent()
So... The 3 recommended ways to handle loops:
1.
WaitWindowEvent()
Very system friendly, bad program performance for timecritical stuff obviously.
Possibility of using a system timer for loop triggering.
2.
WindowEvent() + Delay(1)
Very common, good performance, very system friendly.
This is the most popular choice!
Uses less power, generates less heat.
(cpu fan will go between low and max depending on your game/app)
3.
WindowEvent() + Delay(0)
Still system friendly, a few other apps might suffer some performance, maximum performance for your app, uses all free cpu power.
Uses more power, generates more heat.
(cpu fan will be going full speed all the time)
I do not recommend any other types of loops myself,
like no Delay() at all. As that tends to suck up not all free cpu but
steal (or rather deny) cpu from other apps as well. (cpu hogging)
You might even end up with graphics and sound stutters in your own program.
System drivers need cpu as well, altough they should have much higher priority than your program, they still share cpu with your program.
My advice is try with Delay(1) if that seems to give bad performance,
try using Delay(0) instead.
Delay(0) is not the same as Delay(1) or Delay(2) etc.
Delay(0) cause no delay at all, but simply let the system do a task switch,
and if nothing else is going on your program get back the cpu at once,
without delays at all.
Delay(1) on the other hand always waits at least 1ms,
regardless if something is using the cpu next or not in the cpu queue.
Lookup the Sleep function in the PSDK documentation for info on the use of 0 microsecond for the delay.
I'm not sure if Linux or Mac behave the same when Delay(0) is used though.
Yeah! That's a easy mistake to do, both ways actually.PB wrote:> Windows might not require any processing so you've just halted your
> program for no reason
You should do "Delay(1)" ONLY if WindowEvent=0, so that you won't halt
your app while it's busy.
And especially when using nested select or if else code.
It is so easy to forget to add a delay or accidentaly add a extra delay when not needed when nesting code.
-
Steve Elliott
- Enthusiast

- Posts: 109
- Joined: Sun Jan 01, 2006 9:34 pm
- Location: Wales, UK
- Joakim Christiansen
- Addict

- Posts: 2452
- Joined: Wed Dec 22, 2004 4:12 pm
- Location: Norway
- Contact:
Yeah, just have the delay on default.Steve Elliott wrote:Thanks for all your feedback.
Using a delay(1) only when a WindowEvent() = 0 sounds like the best solution - at least until v4.
Code: Select all
Select WindowEvent()
Case #PB_Event_CloseWindow: End
Default: Delay(1)
EndSelectI like logic, hence I dislike humans but love computers.
- netmaestro
- PureBasic Bullfrog

- Posts: 8452
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Try this code:
Code: Select all
Repeat
Ev=WaitWindowEvent()
until Ev=#PB_Event_V4_Release
Last edited by netmaestro on Wed Feb 22, 2006 3:36 am, edited 2 times in total.
BERESHEIT

