You might not have been aware of this, but the Win9x family and the WinNT family of operating systems are no closer related than humans are to chimps. Guess who the chimps are? The wise programmer would have chosen the Win9x family for the short and furry ones. In truth, the two operating systems were designed, written, and managed in two completely separate groups within Microsoft. I'm amazed beyond description that we have one API to deal with because, as you begin to look under the hood, the two families are very, very, very different.
The Win9x family includes Windows 95, Windows 98, and Windows ME. These operating systems were targeted primarily for the home, and were designed to have a maximum compatibility with legacy applications from the DOS world.
The WinNT family includes Windows NT, Windows 2000, and Windows XP. Unlike Win9x, these operating systems were written from the ground up with a serious internal architecture. These operating systems could leave legacy apps behind—perhaps where they belong—in favor of tightening the operating system in every aspect. For those of you who've spent any time at all on Win9x and WinNT, you'll recall that Win9x crashed quickly and easily. WinNT, on the other hand, is extremely robust. It recovers from application crashes extremely well.
These operating systems, being extremely different, clearly don't support the Win32 APIs identically. Some functions are not supported at all on Win9x, such as the vast majority of wide character versions of the Win32 API. Let me say that last statement much more clearly: The Win9x family of operating systems does not support UNICODE, it is an entirely ANSI character based.
|A Tale from the Pixel Mines
Are you surprised that Win9x doesn't support UNICODE? Maybe, but not half as surprised as the Microsoft product manager I worked with when I told him. It was somewhat embarrassing at the time because I'd just spent an entire month porting our ANSI game engine to UNICODE.
Suddenly it didn't work on any Win9x box. When we dug around in MSDN a little we found the horrible truth—there was no UNICODE to be had on Win9x. Luckily my butt and the MS product manager's butt was saved by a little known extension called the Microsoft Layer for UNICODE. Basically it "fools" Win9x systems into believing they have all the wide character versions of the Win32 API. It doesn't really provide the wide character versions, it just converts the UNICODE text to ANSI, and calls the ANSI API instead.
So what? I'll tell you what: It means you can create a UNICODE app and run the executable on Win9x and WinNT without a problem. If you are going to create a UNICODE compliant game, you want to build one executable, and you want to support Win9x, your only hope is the Microsoft Layer for UNICODE. If you want to know how to set this up, search for it on MSDN, it's pretty easy.
If your game uses the Microsoft Layer for UNICODE and you don't set it up correctly, your game won't be able to create a window. This is an odd failure and very confusing to debug. You'll notice that any function that accepts a window handle like LoadIcon() will simply fail. If you see this, the Unicows.dll is most likely the culprit.
Every Win32 function has compatibility documentation in the help files or on MSDN. Get used to checking for the compatibility every time you use a new function. This is becoming a frequent occurrence for me to find a different solution to maintain compatibility with Win9x. Find it at the bottom of the documentation under the "Requirements" section.
You should create a registry key for your game, not only for storing the odd registry data but the key designation is useful for finding a unique directory to store temporary files or application data on the hard drive. The key should contain the following information:
\Your Company Name\Your Product Name\Major Version.Minor Version
Here's an example of the registry key for the first version of Microsoft Casino:
\Microsoft\Microsoft Games\Microsoft Casino\1.0
Microsoft produces so many products it was convenient to add a product group description after the company name. This key will be used by the install program and your game in many different ways, many of which we'll discuss in the next section.
It was cool when it came out; there's no mistake there. At the time of this writing, Microsoft is no longer supporting Windows 95 in its own products. There are very few Win95 boxes out there any more anyway, so don't mourn its loss. Don't bother trying to support Windows 95 in your game. It's dead.
There are plenty of Windows 98 and Windows ME boxes out there, mostly in the mass market. If you are making kids games or games for your parents, you'd be wise to support Windows 98 and ME in your game. You can count on Internet Explorer being installed, which is I imagine why Microsoft got in all that trouble. Still, it's nice to know you can format your game documentation and help files completely in HTML, put it on the CD-ROM and save a few trees. The biggest pain in the butt with supporting these remnants of the Win9x group is that you can't run Visual Studio.NET on a Win9x machine, so you'll have to do all your debugging remotely.
Since Microsoft dropped support for Windows 95 in mid-2002 and Windows ME was released in 2000 we can expect to have this monkey on our backs until at least 2006, perhaps 2007. One thing that might save us is that Windows ME didn't penetrate the market very well. Most home users were satisfied with Windows 98, and for good reason. It was actually much better than Windows ME. Other power users and office users moved from Windows 98 to Windows 2000 or Windows XP. Perhaps this will bode for an early retirement for Windows ME support. I hope so.
On Windows 98 and Windows ME machines you can lock your system up if you attempt to perform pixel-by-pixel operations on multiple video RAM surfaces. The classic example would be an alpha blit, where you have a source and destination surface and one more surface that holds the alpha values. If two or more of these surfaces are in video RAM, you can crash Windows 98 and Windows ME.
This was an extremely cool operating system mainly because it was Windows, and it didn't crash. Well, it didn't crash very often! When I was cussing up a storm rebooting my Windows 95 machine for the sixteenth time my buddy across the hall at Origin Systems would brag that he hadn't rebooted in a couple of weeks.
I thought he was kidding. He wasn't kidding.
Windows NT never really penetrated the home market or the computer game market at all, mostly because very few computer game companies wanted to support it and because it never supported DirectX after version 3.0. It was different enough from Win9x to require full test passes and hardware compatibility tests. Most of the multimedia hardware ran on Win9x anyway, so Windows NT never really caught on in the home.
The last survey we did on mass market usage of Windows NT was around 2% of our customers, and dropping every month. That survey was taken in mid-2002. I really liked Windows NT but there's no reason to keep it alive in your test lab.
Windows 2000, on the other hand, is very much alive, and has good market penetration. The best thing about Windows 2000 is you can write applications for it as if it was Windows NT, for the most part. The only thing you have to do is check for the compatibility of the Win32 API functions you are using, and everything should be fine. You should make sure your games support Windows 2000, and likely do so until at least 2007.
Windows XP was not nearly so friendly. Since it is the first NT-based software to make it to the home market, it's no surprise there is will be a little hang wringing on the part of developers who've never supported NT.
One of the most significant differences involves security settings. For the first time in Windows history, security settings will prohibit any application from writing files to the Program Files directory. This is the default setting in Windows XP Home, and is a possible setting in Windows XP Pro. There are other issues as well, and it may be easiest to go over them one by one as you look at the next section.