pouët.net

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?
added on the 2012-08-15 19:19:00 by chock chock
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!
added on the 2012-08-15 22:27:38 by xTr1m xTr1m
+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 :)
added on the 2012-08-16 01:31:03 by Subi Subi
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 ;)
added on the 2012-08-16 20:17:25 by T$ T$
T$: in essence the "bad" 4k's 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);
added on the 2012-08-16 21:21:58 by xTr1m xTr1m
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.
added on the 2012-08-16 22:45:32 by Blueberry Blueberry
xTr1m: not using a message pup is even worse at all (unless you´re doing a textmode 4k ;)
added on the 2012-08-17 21:57:44 by T$ T$
xTr1m: What do mean by "SwapBuffers before precalc"? Do you mean to not just display a black screen while precalculating?
added on the 2012-08-17 22:16:20 by Parasight Parasight
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.
added on the 2012-08-18 08:49:04 by KK KK
And of course the I forgot to put "ShowCursor" above - it's just after CreateWindowExA and before CreateDevice.
added on the 2012-08-18 08:51:18 by KK KK
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).
added on the 2012-08-19 20:25:58 by Blueberry Blueberry
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 :)
added on the 2012-08-20 13:23:54 by xTr1m xTr1m
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).
added on the 2012-08-20 16:50:39 by las las
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.
added on the 2012-08-20 17:42:36 by las las
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.
added on the 2012-08-21 00:17:55 by KK KK
Yes but its possible that it also does something more that causes the mouse cursor to stay hidden...
added on the 2012-08-21 09:42:39 by xTr1m xTr1m
Or doing less not to show the hidden cursor back. ;)
added on the 2012-08-21 11:46:15 by KK KK
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).
added on the 2012-08-21 17:18:59 by KK KK
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.
added on the 2012-08-21 17:26:37 by Gargaj Gargaj
I know that it's not guaranteed, but I hardly can see what PlaySound could possibly do after starting the sound and returning execution.
added on the 2012-08-21 23:00:07 by KK KK
Your trust in the OS to not do crazy shit is admirable.
added on the 2012-08-21 23:25:04 by revival revival
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.
added on the 2012-08-22 00:57:59 by KK KK
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.
added on the 2012-08-22 02:20:11 by Gargaj Gargaj
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?
added on the 2012-08-22 11:33:49 by KK KK

login