Mousecursors in 4k Intros
category: code [glöplog]
Under XP it was enough to call SetCursor(False). Under win7 you have to (as Saga said) additionally clear the message queue. I assume that 3 of the 5 Evoke intros were developed under XP?
I assume that 3 of the 5 Evoke intros didn't PeekMessage with PM_REMOVE ;)
+1 to make that a compo rule.
"developing in xp" and "works fine here" is no excuse if the compo description would explicitly require the presence of PeekMessage with PM_REMOVE (or some alternative that does the same).
We use it, and also have fade in, fade out, SwapBuffers before precalc, Sleep for waiting for display resolution changes... All of those are comfort features... We can shamelessly claim that "there's no space for that" is not an excuse!
+1 to make that a compo rule.
"developing in xp" and "works fine here" is no excuse if the compo description would explicitly require the presence of PeekMessage with PM_REMOVE (or some alternative that does the same).
We use it, and also have fade in, fade out, SwapBuffers before precalc, Sleep for waiting for display resolution changes... All of those are comfort features... We can shamelessly claim that "there's no space for that" is not an excuse!
+1 for rule also. I still remember the massive embarrassment I felt when an organiser had to move the wait cursor offscreen on my 4K at Revision last year.
Yes, I know how to do it now :)
Yes, I know how to do it now :)
Using PeekMessage, messages are removed automatically (unless PM_NOREMOVE is passed). Thus, what the heck are those cursor 4ks doing? At least not behaving like nice winapi clients, I suppose ;)
T$: in essence the "bad" 4k's do this:
Consider that C++ goto-code as a placeholder for a pending asm port ;) That's what I do. "Good" 4ks should do this:
Code:
loop:
//Update and render code go here
if (!GetAsyncKeyState(VK_ESCAPE))
goto loop;
ExitProcess(0);
Consider that C++ goto-code as a placeholder for a pending asm port ;) That's what I do. "Good" 4ks should do this:
Code:
loop:
//Update and render code go here
PeekMessageA(0, 0, 0, 0, PM_REMOVE);
if (!GetAsyncKeyState(VK_ESCAPE))
goto loop;
ExitProcess(0);
Has anyone experienced a lingering mouse cursor in a D3D9 intro? It would be good to know if this is only a problem for OpenGL intros.
xTr1m: not using a message pup is even worse at all (unless you´re doing a textmode 4k ;)
xTr1m: What do mean by "SwapBuffers before precalc"? Do you mean to not just display a black screen while precalculating?
No matter how I tried, I can't reproduce the issue with my intros (DX9).
- CreateWindowExA( WS_EX_APPWINDOW, "edit", "edit", WS_POPUP, 0, 0, W, H, 0, 0, 0, 0 )
- CreateDevice
- Sleep( 1024 )
- device::Reset
- create shaders
- render music
- PlaySound // i still don't get why use waveOut - this worked perfectly every single time
- simple demo loop (including offscreen Lock/Unlock/Clear for reasonable sync)
And again, I never seen this failing to hide the cursor, no matter on which system/driver/winn settings.
- CreateWindowExA( WS_EX_APPWINDOW, "edit", "edit", WS_POPUP, 0, 0, W, H, 0, 0, 0, 0 )
- CreateDevice
- Sleep( 1024 )
- device::Reset
- create shaders
- render music
- PlaySound // i still don't get why use waveOut - this worked perfectly every single time
- simple demo loop (including offscreen Lock/Unlock/Clear for reasonable sync)
And again, I never seen this failing to hide the cursor, no matter on which system/driver/winn settings.
And of course the I forgot to put "ShowCursor" above - it's just after CreateWindowExA and before CreateDevice.
Quote:
- PlaySound // i still don't get why use waveOut - this worked perfectly every single time
Two reasons:
1. PlaySound has no mechanism for querying how much time has elapsed of the actual playback. Reading a timer right before or after PlaySound has no guarantee of being synchronized to the start of the playback. I have witnessed cases where it has been off by more than half a second. Sometimes the error even varies from time to time.
2. The audio timers (of waveOut and DirectSound) have high resolution compared to other timers such as timeGetTime and GetTickCount. For instance, timeGetTime usually has a resolution of 10ms, which can cause severe stuttering when used for animating 60fps visuals. GetTickCount is even worse. You can use the performance counter, but it is more cumbersome to use, eating into the size.
And speaking of size, the waveOut solution actually seems to be slightly smaller, all things considered (comparing the Crinkler reports of Wishful Seedling and Chaos Theory 4k). The code seems more complex, but you avoid the copying of the WAV header (not to mention the header itself, which is somewhat bigger than the waveOut input structs) and the initialization of the timer variable (waveOutGetPosition automatically counts from the beginning of the music).
T$: but that's what most 4k's do. It works (TM), but since Vista there's that mouse cursor issue.
Parasight: The first call to SwapBuffers (before any OpenGL calls came, but after having called wglMakeCurrent) paints the screen black. I do this so that the small white "edit" window and the desktop are not visible while doing precalc. As I said, it's a comfort feature.
KK: I guess this is an opengl issue only. Not sure what dx's Present call does internally. BTW: the window title doesn't need to be "edit", it can be NULL as well :)
Parasight: The first call to SwapBuffers (before any OpenGL calls came, but after having called wglMakeCurrent) paints the screen black. I do this so that the small white "edit" window and the desktop are not visible while doing precalc. As I said, it's a comfort feature.
KK: I guess this is an opengl issue only. Not sure what dx's Present call does internally. BTW: the window title doesn't need to be "edit", it can be NULL as well :)
Code:
HWND hWnd = CreateWindowExA(0, "edit", 0, WS_POPUP|WS_VISIBLE|WS_MAXIMIZE, 0, 0, 0, 0, 0, 0, 0, 0);
Replacing "edit" with NULL does not work for me (and never did).
With window title - did you mean "lpWindowName"? Then I guess I confused "lpWindowName" with "lpWindowName" AND "lpClassName".
We are using lpWindowName=NULL for some years now.
We are using lpWindowName=NULL for some years now.
Quote:
Reading a timer right before or after PlaySound has no guarantee of being synchronized to the start of the playback.
Querying timeGetTime right after PlaySound never ever failed me so far and every time gave me perfect sync (well, at least after forcing stall by Lock and offsetting time by 1/60th of the second of guaranteed frame latency).
Quote:
For instance, timeGetTime usually has a resolution of 10ms
Not true. I'm using timeGetTime in all my project since quite some time, and for me it never happened to have resolution worse than 1ms (on every single machine/system setup I have used it).
Quote:
And speaking of size, the waveOut solution actually seems to be slightly smaller
And this is the argument that I accept. :)
xTr1m: Present == glSwapBuffers.
las: Thanks for the hint.
Yes but its possible that it also does something more that causes the mouse cursor to stay hidden...
Or doing less not to show the hidden cursor back. ;)
KK: "Works for me" is not the same as "Works for all". Mind you, every program can change the precision of the internal Windows timer. Years ago I was using Sleep() to wait between frames, but then I realized that animation suddenly was much smoother while Winamp was running - apparently Winamp fucked with the timer precision and so my "Sleep(1) will last at least ~10ms, even though it should last 1ms" thinking didn't work anymore. I'd guess that the same applies to timeGetTime.
Saga Musix: Well, then I have no idea how to find any case of poor timeGetTime precision, as I use fairly minimal setup while testing (usualy open IDE, browser + about thousand of Windows services that are always there).
Quote:
Querying timeGetTime right after PlaySound never ever failed me so far and every time gave me perfect sync
the problem is PlaySound doesn't always return right after starting the playback, e.g. if you use enough memory to cause windows to swap. it's a very bad gamble, although i guess in 2012 that's less of a risk.
I know that it's not guaranteed, but I hardly can see what PlaySound could possibly do after starting the sound and returning execution.
Your trust in the OS to not do crazy shit is admirable.
That's what making 4k's is about, right? And relying on PlaySound not being too lazy doesn't even slightly compare to what Mentor & Blueberry did with exe file header.
the exe header is deterministic, it doesn't rely on timing. it either works or it doesn't, and if it does, the it'll work the same a second or third time. assuming that playsound returns "immediately" is basically just mere hope that the scheduler doesn't decide to swap out half the OS while your intro is running - i certainly used to have that problem with bassotron, and i hated the moments during the compo where i'd cross fingers to see if the sync is off or not. that said, as i noted, i suppose it's less of a problem now with the amounts of ram machines have.
I was suspicious at first, too, but after several 4k's this feeling wears off and other feelings creep in (like "I hate having to waste all this space for creating and playing with offscreen surface to keep GPU from buffering 3 frames").
Anyway, I haven't tried so far, but if waveOut really turns out to be smaller, the whole discussion is kind of pointless now. And while we are at topic of sync, care to share ideas of what do you use to prevent this 3 frame bufering?
Anyway, I haven't tried so far, but if waveOut really turns out to be smaller, the whole discussion is kind of pointless now. And while we are at topic of sync, care to share ideas of what do you use to prevent this 3 frame bufering?