header image
 

Newsflash: Enum.HasFlag is slow

I finally managed to repair my Visual Studio’s profiler – turns out the profiling driver was corrupted (wrong image size in PE header, only 2 bytes). Anyway, I launched Gwen.Net’s SFML sample and quickly browsed through the profiler output. One peculiar thing caught my eye: Enum.HasFlag method calls amounted to around 5% samples inclusive. What?! Sure that can’t be right? Flag testing is extensively used in control positioning and layout code, but 5%? I’ve replaced all occurrences with manual bit testing and fired up Net Reflector:

public bool HasFlag(Enum flag)
{
    if (!base.GetType().IsEquivalentTo(flag.GetType()))
    {
        throw new ArgumentException(Environment.GetResourceString("Argument_EnumTypeDoesNotMatch", new object[] { flag.GetType(), base.GetType() }));
    }
    ulong num = ToUInt64(flag.GetValue());
    return ((ToUInt64(this.GetValue()) & num) == num);
}

Wow. Type checking, boxing and conversions. I’ve used HasFlag mainly for it’s verbosity, but I guess I’ll stop now.

OpenTK text renderer

I’ve finally implemented text rendering in OpenTK GWEN.Net renderer. It seems to work fine, although (as always) there is room for improvement (mainly better caching and font handling). OpenTK renderer seems a bit slow overall on Windows, I’ll need to look at that. The code was contributed by Olli-Pekka Valtonen, I haven’t looked at it in much detail yet. But it works! 😉

I wish a day had way more than 24 hours

I’ve started reading yet another game designer blog: this time it’s Ascii Dreams by the author of Unangband. I love roguelikes (mostly played ADoM) and you can probably guess by now that the project I’m working on is a game of some sort.

Lot’s of interesting insights there.

Slowdown

I’ve caught some silly flu or cold yesterday. It was a long time since I willingly spent a good part of the day in bed simply because I had no strength to do anything else. I also started playing Deus Ex: Human Revolution… And boy, is it good. Expect slower Gwen.Net updates for a while, but I’m still working on it. Now that the GUI framework is mostly done, I can go back to my ~secret project~ that uses it. I’ll probably elaborate on it some time soon.

GWEN.Net – finally, all controls implemented!

All GWEN controls are now implemented. I’ve also added XML comments to most public symbols (when I knew what are they for anyway). I’ll focus on fixing bugs and enhancing usability next. That also most likely involves changing event system to use control-specific event args instead of one generic callback.

http://code.google.com/p/gwen-dotnet/

Bloodlines – cRPG you need to play

Yesterday I finished playing Vampire: The Masquerade – Bloodlines. I’ve heard good things about it before, and bought it some time ago while it was on sale on Steam. Recently I remembered it and thought “Hell, let’s try this”. Over 40 hours later I can say that it is one of the best cRPGs I’ve ever played. It has an amazing atmosphere, you just feel like a son of Caine wandering around the city streets amongst oblivious humans. Despite being somewhat problematic to run on modern systems and occasional stability problems, I can wholeheartedly recommend it to any cRPG fan. Make sure to use the latest unofficial patch.

I played as a rather demented Malkavian and it was an unique experience. Below you can find some samples, without any major spoilers.

Hacker Challenge 2007 – solution

I’ve posted my solution to the Hacker Challenge 2007 reverse engineering challenge here.

GWEN.Net – almost there

Gwen.Net is almost finished. Only a few controls are missing now: Trees, Properties and RichLabel. All other functionality seems to be working fine. I also need to finish Tao renderer/input and make some methods for easy font loading. After that I’ll polish the API to a “semi final” state – not “final” because I’m sure there will be changes while I work on my project. It would be also nice to add at least XML documentation to code, since Gwen doesn’t have any.

Right now I’m adding UnitTest components for easy testing, after that I’ll implement the missing controls and fix bugs.

SetWindowsHookEx and multithreading

I’ve spent most of this week troubleshooting an infuriatingly elusive problem with Windows Hooks. The use case is that the application I develop needs to monitor for certain third-party application window to appear and then install a windows hook to “do stuff”. What it does is unimportant here. The problem was, catching the target window and installing the hook worked fine, but then after some time the hook DLL was suddenly unloaded from all processes and the hook terminated. Here is a sample log from DebugView:

9.88870430	[1744] WinWrangler: CreateSharedMemory ok : C:\tools\TextPad 5\TextPad.exe [1a78]
9.88872910	[1744] WinWrangler: DLL_PROCESS_ATTACH : C:\tools\TextPad 5\TextPad.exe [1a78]
78.08577728	[1744] WinWrangler: DLL_PROCESS_DETACH : C:\tools\TextPad 5\TextPad.exe [1a78]
78.08594513	[1744] WinWrangler: CloseSharedMemory : C:\tools\TextPad 5\TextPad.exe [1a78]

First column is the event’s time in seconds. After a minute and a few seconds my hook was nuked from orbit by an unknown entity.

After scratching my head for a while I decided to pinpoint the code that actually called FreeLibrary on my DLL. It seemed that the OS itself was doing that. I started Api Monitor, set API filter to catch DLL loads/unloads and launched the test.

#	TID	Module	API	Return	Error	Duration
1	6200	USER32.dll	LoadLibraryExW ( "C:\code\AppEmbedder\Release\WinWrangler.dll", NULL, LOAD_WITH_ALTERED_SEARCH_PATH )	0x6f310000		0.0010937
2	6200	USER32.dll	FreeLibrary ( 0x6f310000 )	TRUE		0.0003345

After clicking on the FreeLibrary call we can see the call stack:

#	Module	Address	Offset	Location
1	USER32.dll	0x76922ed9	0x22ed9	GetKeyboardLayoutList + 0x70
2	ntdll.dll	0x77b4011a	0x1011a	KiUserCallbackDispatcher + 0x2e
3	USER32.dll	0x769260dc	0x260dc	PeekMessageA + 0x168
4	TextPad.exe	0x004bcbd3	0xbcbd3	
5	TextPad.exe	0x006279aa	0x2279aa	

GetKeyboardLayoutList on the top? What the hell? Anyway, TextPad (my guinea pig for the test) was calling PeekMessage as seen on line 4. This is not helpful. I’ve spent some time with a kernel debugger (windbg) looking around but it was mostly a waste of time, so I won’t go into that here.

I tested my sample on a few different machines, all were experiencing this behavior. After that I started commenting my code out to see what’s the minimal piece producing the issue. Needless to say I was pretty shocked when DLL was still being unloaded with the whole hook procedure empty and “loader” code reduced mostly to a SetWindowsHookEx call. At the same time other programs using hooks worked just fine. Something was really wrong.

Finally after one more code simplification it stopped the hook from breaking. What interesting was there? Well, I was creating a timer that periodically searched for the target window, and if it found one, the hook was being set up. And this turned out to be the culprit: if you call SetWindowsHookEx from a thread and that thread is later terminated, your hook will be silently killed, even if hook procedure resides in a different DLL and the whole process still lives. And CreateTimerQueueTimer runs the timer function in a thread from a thread pool.

I knew that Windows GUI and multi-threading don’t mix well usually, but wasn’t expecting this. Nowhere in MSDN documentation on hooks is this behavior explained, or any requirement for the calling thread stated. I’ve modified my code so that the timer now sends message to the main thread that does the actual hook setup. And it works. You live and learn, I guess.

Edit: now that I looked at SetWindowsHookEx MSDN page again, this behavior is given in the last user comment. Still, it should be in the damn documentation where I expect it.

Games for Windows Live… really?

I wanted to play Bulletstorm again today. I’ve played a pirated version before (specifically to avoid GFWL), but the game was really good and I bought it afterwards. So I hook up my TV to the PC, get some drink and start the game (legit version). “Press Enter”, “This game requires GFWL blah blah press space to continue”. I press Space – nothing happens. Game just goes back to the “Press Enter” prompt. No error, nothing. OK, Internet search time. Oh right, I had “Windows Live ID” service disabled. Too hard to display a relevant error message, eh?

Turned the service on. Huzzah, now GFWL seems to actually do something. “Sign in” it says, so I enter my details. Success! I can now enter my CD-Key. I type it down and I’m informed that there is an update for the game ready for download. Great! Update downloads, and GFWL informs me that I now need to save my progress and exit the game to continue. I can do that… or can I? NO! I can’t even get to bloody main menu, because it still asks me to log in into GFWL! Why?! Even Alt-F4 is futile. Killing the process manually doesn’t do anything good, update fails saying that the game needs to be registered in GFWL first. Really? So what the fuck was I doing for the past half an hour?

I proceed to download the “Games for Windows Marketplace Client” or whatever that’s called. Sign in – “Error 8015403A”. Awesome. It seems I need to accept an updated EULA. Whoa, now I’m logged in. Bulletstorm doesn’t show on my games list, so it seems that registration wasn’t successful. And I got NO ERRORS in game. What the fuck? I try to enter my CD-Key into the “Redeem code” window, but it says it’s invalid. I guess that’s because I have a retail copy.

So, an hour later I’m downloading it off a torrent again (which will take less than an hour). Three cheers for DRM!

Edit: Reinstalled the retail version and tried one last time to give GFWL a chance. Launched the game (without a crack or anything):

And this just sits there. No feedback on what’s going on, no “Next” or “OK” buttons. I obviously have Internet connection. Closing it does nothing.

Cracked the game, works like a charm.