Does anyone have an example of a "complete" message loop for a GUI application (game)? and one that doesn't rely on WM_TIMER

I want to make sure I'm doing it right and I'm not sure is a message loop should be special if it is for a GUI game (for example PeekMessage -- we use that for directx and opengl... should it be used to a gui application?

Sliver
Posted on 2002-06-25 14:45:18 by Sliver
Below is the main loop I used for a Tetris game. It uses GetTickCount to simulate a timer. The method is to use PeekMessage and to call GetTickCount to obtain the number of ms elapsed since the last update of the game. If the number is greater than 30 ms for example, the game is updated.
Posted on 2002-06-25 17:04:37 by Dr. Manhattan
here is the Hostileencounter Message loop (the single thread version faster version)

this will update the screen as fast as it can, you an allways place a Sleep(20) at the end of your game loop to let OS breathe and limit your fps to 50.

I guess QuerryPerformanceCounter could be used to fine tune this Sleep for better fixed FPS.



;************************************
; WinMain MESSAGE LOOP STARTS HERE
;************************************

msg_loop:

;==========================================
; we use PeekMessage in order to detect idle (no messages)
; time we can use
;==========================================
push PM_NOREMOVE
;push PM_REMOVE
push 0
push 0
push 0
push offset msg
call PeekMessageA

;===============================
; test: do we have messages?
;==============================
cmp eax, 0
je nu_sunt_msg ; happy jump if we dont

; ===============================
; but no so happy..
; if we have to handle them
; ===============================
call GetMessageA,offset msg,0,0,0

;===================================
; test: is this message WM_QUIT ?
; =================================
cmp eax,0 ; GetMessageA will return zero if it is...?
je end_loop ; EXIT PROGRAM IF TRUE!!!!

;=========================================
; default action (let windows do it's dirty job)
; for all other messages
;=========================================
call TranslateMessage,offset msg
call DispatchMessageA,offset msg

;=========================================
; and jump back to do it all over again
;======================================
jmp msg_loop

;=================================
; Here ENDS Our Program (normaly)
;==================================
end_loop:
push [msg.msWPARAM]
call ExitProcess ;exit to windows

;===================================
; we should never reach this point
;===================================
ret


;=========================================
; so...there are no win messages....
; HERE we do our GAME MAIN LOOP
;=========================================

nu_sunt_msg:
pushad

;=======================================
; test: is game loop on?
; so that in future we dont make useless/dummy/dangerouse
; paint to screen/direct draw even on pause....
;=======================================
Call Game_Main

;==================================
; just return to WIN message loop
;=================================
popad


;====================================
; return to main Message Loop
;====================================
cmp [flag_no_messages],1
jz nu_sunt_msg
;------------------------------------------------------------------
; ignore above 2 instructions if you want to play nice
;------------------------------------------------------------------
jmp msg_loop

;******************************
; END OF PROGRAM TEXT
;******************************

Posted on 2002-06-26 06:57:56 by BogdanOntanu

I guess QuerryPerformanceCounter could be used to fine tune this Sleep for better fixed FPS.
Compute the exact Hz of your CPU, and use RDTSC. When I have some time (in this period I'm extremely busy) I will convert to standard asm and post here a routine of mine that computes the CPU speed with maniacal-precision. (Tm) :)

All timings in general should be derived from RDTSC (given the precise Hz information), rather than QueryPerformance or GetTickCount.. which are much worse and suffer from considerable overhead.
Posted on 2002-06-26 07:30:37 by Maverick
Maverick, I have read that there is some problems with RDTSC on some motherboards - count 'jumping'? Maybe, motherboard manufactures trying to rig performance tests? Curious is anyone else has heard anything of this?
Posted on 2002-06-26 08:27:10 by bitRAKE
It's simply impossible. The counter is inside the CPU. Perhaps the CPU is being frozen by a ill NMI, or by the bus.. giving this illusion.
Posted on 2002-06-26 09:22:40 by Maverick

It's simply impossible.
That is what I thought. :stupid:
Posted on 2002-06-26 09:49:28 by bitRAKE
But I have to testimony about a badly-flashed motherboard that had short but fastidious interruptions. I noticed it because I wrote a realtime Dsp program (just for own and betatesters use, so far not publicly released) which doing direct I/O (0 latency) relied on critical timings with IRQ's disabled. Well, on that motherboard every exactly 1 second there was an audio glitch. I thought about an NMI problem, but then I re-flashed the BIOS and the problem disappeared.. so I never tracked down the exact problem. However, on a IRQs-disabled continuous loop, that would have looked just like what you mentioned: i.e. every 1 second the TSC jumping ahead of a certain quantity. But it would have been illusory though.. and perhaps (if not probably) would not have happened anyway, since in my Dsp program case what was locked was probably the PCI bus after all. The TSC is inside the CPU, so if it executes its code from the caches, nothing happening on the motherboard can affect it. Not even if the motherboard stops to give the clock to the CPU, since if this happens, also the TSC will stop anyway, and there will be no illusory "TSC skip aheads".

The TSC is truly an invaluable resource.. no overhead, extremely precise, etc.. a must to use, really. All one needs is a very precise and reliable CPU Hz-detection routine.. I wish I had some free time to convert mine (it's in my programming language) to assembly. I will do it when I have some time, and post it here.
Posted on 2002-06-26 16:30:58 by Maverick
What will happen with RDTSC if processor change the frequency (mobile processors) ?? I think that RDTSC in that case won't be usefull...
Posted on 2002-06-26 17:03:31 by minimoog
minimoog, on my Transmeta Crusoe, it counts the same frequency in power saver mode or not. I don't know about Intel and AMD chips, though.
Posted on 2002-06-26 17:15:15 by bitRAKE

What will happen with RDTSC if processor change the frequency (mobile processors) ?? I think that RDTSC in that case won't be usefull...
My routine detects CPU speed changes and fixes its data structures accordingly. Of course the programmer has to take care of its own actions as well.
Posted on 2002-06-26 17:21:42 by Maverick
Thank you Maverick for good will ...

HE uses RDTSC form a long time now, but for a beginer i thought that QuerryperformanceCounter API will be much easy to use at first sight ;)

I was expecting QPC API to be more hardware independent as compared to RDTSC instruction but hellas on a HP kayak OS reports no QPF available but RDTSC works ok ;) LOL


Bogdan
Posted on 2002-06-26 18:08:06 by BogdanOntanu
Hi Bog :)

QPC not supported on a HP? Very interesting.. and deserves deep investigation.

I hope you don't mind if I ask you some questions. :)

1) Did you run your tests on Win9x or WinNT?

2) What did QPF return, exactly?

3) Do you have ~easy access to this PC for possible further tests?

I'm quite convinced that QPx must run on that PC too.. maybe the problem was due (NT case) to a non-DWORD-aligned pointer to your QWORD var, or who knows what else. Worth investigating, though.
Posted on 2002-06-27 04:27:47 by Maverick
Yes i have acces to that machine it's "right behind" me ;)
We tested it on Win2K/NT indeed but the API returns No Performance Counters Available standard error (ie FALSE)

From API help:


Return Value

If the installed hardware supports a high-resolution
performance counter, the return value is TRUE.
If the installed hardware does not support a high-resolution performance counter,
the return value is FALSE.



So from the API help it looks like there is quite normal for a PC not to have Performance counters :)

Now the RDTSC works because of the P2 CPU inside PC but i suspect that the CTC IC is used for QPC API and maybe HP decided to reduce "production costs" and removed the "obsolete" timer IC ...

its weird indeed and it was one of the problems that made HE crash on that machine...
Posted on 2002-06-27 09:43:59 by BogdanOntanu
Hmmm.. please, could you run this little proggy and tell me if it works? (i.e. if it shows <edit>in HEX.. argh</edit> the right (not with the precision and stability of the routine I'm gonna post, though) speed of your CPU).
Posted on 2002-06-27 17:13:49 by Maverick
Hey Maverick, I tested your CpuSpeed app and it shows 2FCB31E0 == 801845728 on my 800mhz Intel P3. This is also the speed given by other benchmarkers (801mhz). So I think, it's working fine.
Posted on 2002-06-27 17:56:46 by stryker

Hey Maverick, I tested your CpuSpeed app and it shows 2FCB31E0 == 801845728 on my 800mhz Intel P3. This is also the speed given by other benchmarkers (801mhz). So I think, it's working fine.
Thanks Stryker :) Now I'm curious to see if it works on that HP machine.. hmm.
Posted on 2002-06-27 18:11:00 by Maverick
Message HEX U64
---------------------------
00000000500FDF9D
---------------------------
K7-1.334Ghz
This matches with other measurements to four places.
Using QueryPerformanceFrequency, huh. :)
Posted on 2002-06-27 18:49:17 by bitRAKE
Hi Maverick,


cpu = p3-667

try1- 0286d89d8h
try2- 0286d7d87h
try3- 0286d868eh

have nice days,
Posted on 2002-06-27 19:51:32 by CYDONIA
Frist and second try I get *000000000BE1C2D4* on my NEC 9716, p200, with 96kb ram installed ((( but 64mb maybe all that is really running because of the old 95))) running Win95. I'm on my way to beings seriously into the numbers now so that i can see what make it Tick.

Thanks Maverick

3rd try 000000000BE1BFI4

maybe i mis read the first try but it looking the same at my eye site.
Posted on 2002-06-27 20:33:09 by cmax