Monthly Archives: April 2008

A Drive Through the Country

As I alluded to in February, I’m going to try and shy away from the gaming scene while I experiment with other fields. That doesn’t mean “leave completely,” but my activity will be hampered. That is partially the reason SourceMod moved to a “rolling release” concept so we can push out incremental feature updates easier.

As part of this endeavor, I’ve accepted an internship at Mozilla. I don’t know what I’ll be working on yet, but my primary interest is in language development, so hopefully it will be EMCA4/JavaScript 2/Tamarin. It requires relocation to Mountain View, California.

I’m really looking forward to this, but the next two weeks I am not. I managed to schedule myself into a rather nasty hole. In specific, finals last until April 29th. My apartment lease ends on April 30th. I said I’d be in California by May 5th. That means I need to finish school, move all of my belongings to storage, and move — in a time span of a week.

What makes this feat particularly amusing is that, against better judgment, I have decided to drive to my destination. This is not a short road trip. Clocking in at 3,100 miles, I can expect to spend at least a few days on the road. I’ve gotten a friend to tag along to make sure I don’t accidentally drive in a direction other than “West.”

While I’m resigned to the fact that I will probably miss my deadline by a few days, it’s both a long journey and a stressful two weeks ahead. As of May 1st, I will probably not be on IRC for a week or so. You probably won’t see any commits from me for at least two weeks though I will try to read the forums and bug reports as I have time. Blog articles will resume on May 5th (I have a rather scathing, two-part overview of the JVM spooled up).

And so…
Mozilla or Bust

Sayonara, bickering with Valve!

Migration to Vista x64

About a month ago I made the migration to Windows Vista x64. A little back story first — I tried Vista Business soon after it was released. I hated it, most apps had terrible compatibility (even Microsoft’s own apps), and it didn’t feel very fast.

But recently my Windows XP install was yet again beginning to decay. This happened every time I reformatted. Usually after a few days (or even hours) of setting up my typical XP environment, it started exhibiting strange bugs, slow downs, and random problems. For example, the entire user interface would randomly stop working and I’d have to reboot. Clicking the ‘Start’ button would freeze the taskbar for about two seconds. Some USB devices wouldn’t work until they got power cycled. Killing things in Task Manager would always have some ridiculous delay (which I think is a general problem in XP).

These problems got so predictable that when my hard drive died in March, I decided up to upgrade to Vista again, and take another plunge at the same time – Vista x64. So far, I don’t have many complaints. The user interface is slick and responsive. I’m using Aero which says a lot — I never used Luna on XP. The organizational changes, for the most part, aren’t really much of a problem for me. I switch between the “Classic” and new control panels frequently to adapt.

UAC is not a problem, and in fact I like it after some tweaks. I disabled “Secure Desktop” (which is an extreme annoyance) and disabled confirmation for Administrators. I run my primary account as LUA (limited user account). Typing in the Administrator password to install apps is no big deal, I’m used to this from administering Linux boxes. On a few occasions I’ve seen the box pop up from suspicious programs that shouldn’t need Administrator privileges — on XP, these would have gracefully executed with no chance to inspect them.

Application compatibility has improved since a year ago. While most apps aren’t x64-native, a few were — 7-Zip, Ventrilo, MySQL, Perl, and a fair number of Microsoft apps. Some aren’t for decent reasons. Firefox, Internet Explorer, Media players and the like are often dependent on third-party libraries which don’t have x64 ports. You can’t mix 64-bit and 32-bit code in the same process.

I did have a few 16-bit Windows games which no longer run (x64 dropped the 16-bit subsystem). I even had one very esoteric program with a 16-bit installer. I wasn’t too broken up about losing those though, and VMWare will suffice if I ever need to run them.

As for driver compatibility, I did have one issue. My XP system had two GeForce cards, a 5200 and an 8800. On Vista (or at least, Vista x64) the 5xxx series and lower is no longer supported by any of the new nVidia drivers. The 5xxx series is only supported up to ForceWare 96.85 and the 8800 requires much later versions (the latest is 169.35). I tried to install both drivers at once and ended up with a nice blue screen, which is pretty understandable. Out of pure luck I had a GeForce 6 in another machine so the problem was easily resolved.

The one thing I do not like about Vista is its Explorer changes. The new Explorer is pretty bad. I removed the new organizational changes almost instantly (and I’m glad Microsoft allows for those to be reconfigured). However, it changed my favorite hot-keys and left no revert mechanism in. Every time I use backspace I expect it to go up one level, and instead it treats file browsing like web browsing. There’s a new shortcut for this (ALT+Up) but now it’s confusing when I go back and forth between operating systems.

Vista’s Explorer makes it difficult to right-click files that aren’t selected, because it requires hitting the exact name text, rather than the row the file is in. If you miss this, you get the folder’s context menu and you might not realize it right away. The new dialog for “Copy/Replace” is great, except for one major detail – you can’t use the keyboard. I haven’t been able to find a key combination that will automatically select “Replace.” Enter, strangely enough, just cancels the dialog. This is really annoying because I’m a heavy keyboard user and I’m overwriting files a lot while debugging.

It also automatically sorts new files. This seems pretty cool at first until you drop a file in a folder and watch it get sorted into a completely different location than you visually plopped it.

Back to application compatibility — some people still don’t get things totally right. A few apps failed to create Start Menu/Desktop shortcuts. Some did so, but created them with Administrator privileges (which is annoying because then I can’t remove them). Some apps almost get the right idea. For example, mIRC uses “Application Data” instead of “Program Files” now, but it uses “AppData” to store log files. That’s kind of strange, since they’re user-readable documents. “AppData” is a hidden folder and shouldn’t be used for things like that.

My favorite changes in Vista? Task Manager’s “Kill” function seems to actually work. “Documents and Settings” has been changed to the much more palatable “Users”. Symlinks now provide a bit more functionality over XP/2000’s “Junctions.” UAC makes me feel more in control.

That’s enough ranting for today — your mileage may vary.

Edit: Twisty suggested I try TAB+Space which ended up working. Huzzah!

I Can’t Write Your Plugin For You

It feels that at least once every week or so, I get a private message saying “Can you write/modify this plugin for me?” Sometimes the person even says “I’ll pay you!”

I always reply with, “Sorry, I don’t have the time anymore. You may want to post on the forums, or see if there’s anyone on our IRC channel.” Which is the truth, I barely even have time to work on my own projects these days.

The amusing thing is that I can always predict what the reply will be (if there is one, and there usually is). The person says back, “I tried that, and no one replied.”

Well… what do you want me to do about it? I can’t force people to reply to your post, and I already said I was unable to work for you.

I almost never reply back to those messages, since there’s little I can constructively say that wouldn’t further engage me in their project’s details. I learned that quickly after someone spilled their entire project’s ideas and goals to me. I felt forced to write a lengthy reply (and in fact wrote one) because I didn’t want them to feel like their effort for typing all that had gone to waste.

Often people also ask me if there’s anyone I know who’d be willing to help them, or more surreptitiously phrased, “who are the best developers you know?” Now I’ve gone from a developer to a headhunter. In the very unlikely case I know someone who’s interested in the type of request, and they’ve given me permission to do so, I’ll give them as a reference. Otherwise, I think it’d be inappropriate of me to start contacting or giving out the contacts of every developer I know.

Programmatic Radio Control for Smartphones and Pocket PCs

Lengthy title, yes. I’m working on an application for my Windows Mobile 6.0 Phone, and I needed to toggle the radio (phone receiver) on and off. It’s not very difficult to disable and enable the radio programmatically, but it did take quite a bit of research since I’m new to this platform. I couldn’t find any good, well-written examples on this using Google, so I decided to discuss my solution.

I used Visual Studio’s “Windows Mobile 5.0 Smartphone SDK (ARMV4I)” emulator and architecture for testing. The code is written in straight C. The process is pretty simple:

  1. Initialize with the TAPI DLL.
  2. Enumerate all the line devices. Find the one called “Cellular Line”.
  3. Open the line, change its equipment state, close the line.
  4. Shutdown from the TAPI DLL.

For initializing and shutting down access to TAPI, I made a few helper functions.

Select All Code:
#include <tapi.h>
#include <extapi.h>
#include <string.h>
 
HLINEAPP hLineApp = NULL;
DWORD g_NumDevices = 0;
 
int InitializeLineUtils(LINECALLBACK callback)
{
	int ret;
 
	/* Init TAPI, get device count */
	if ((ret = lineInitialize(&hLineApp,
			g_hInstance,  /* From WinMain */
			callback,
			NULL,
			&g_NumDevices))
		!= 0)
	{
		return ret;
	}
 
	return 0;
}
 
void ShutdownLineUtils()
{
	if (hLineApp != NULL)
	{
		lineShutdown(hLineApp);
		hLineApp = NULL;
	}
}

The next step is to find a device matching a specific name. Device names can be either in Unicode or ASCII, so my helper function takes both to eliminate any conversion. First the device API version is negotiated, then the device capabilities are queried. Note that the structure to do this is pretty low-level — you have to reallocate memory until the device decides it’s big enough to squirrel all its data past the end of the struct definition.

This function finds a matching device and returns its negotiated API version:

Select All Code:
DWORD FindLineDeviceByName(LPCWSTR wstr, LPCSTR cstr, DWORD *pAPIVersion)
{
	LONG ret;
	DWORD api_version;
	LINEDEVCAPS *dev_caps;
	LINEEXTENSIONID ext_id;
	DWORD device_id, dev_cap_size;
 
	dev_cap_size = sizeof(LINEDEVCAPS);
	dev_caps = (LINEDEVCAPS *)malloc(dev_cap_size);
	dev_caps->dwTotalSize = dev_cap_size;
 
	/* For each device... */
	for (device_id = 0; device_id < g_NumDevices; device_id++)
	{
		/* Negotiate an API version (0x00020000 is my CURRENT) */
		if ((ret = lineNegotiateAPIVersion(hLineApp,
				device_id,
				0x00020000,
				TAPI_CURRENT_VERSION,
				&api_version,
				&ext_id))
			!= 0)
		{
			continue;
		}
 
		while (TRUE)
		{
			if ((ret = lineGetDevCaps(hLineApp, 
					device_id,
					api_version,
					0,
					dev_caps)) == 0
				&& dev_caps->dwNeededSize <= dev_caps->dwTotalSize)
			{
				break;
			}
 
			if (ret == 0 || ret == LINEERR_STRUCTURETOOSMALL)
			{
				dev_cap_size = dev_caps->dwNeededSize;
				dev_caps = (LINEDEVCAPS *)realloc(dev_caps, dev_cap_size);
				dev_caps->dwTotalSize = dev_cap_size;
			}
			else
			{
				break;
			}
		}
 
		if (ret != 0)
		{
			continue;
		}
 
		if (dev_caps->dwStringFormat == STRINGFORMAT_UNICODE)
		{
			const wchar_t *ptr = (wchar_t *)((BYTE *)dev_caps 
				+ dev_caps->dwLineNameOffset);
			if (wcscmp(ptr, wstr) == 0)
			{
				*pAPIVersion = api_version;
				return device_id;
			}
		}
		else if (dev_caps->dwStringFormat == STRINGFORMAT_ASCII)
		{
			const char *ptr = (char *)dev_caps + dev_caps->dwLineNameOffset;
			if (strcmp(ptr, cstr) == 0)
			{
				*pAPIVersion = api_version;
				return device_id;
			}
		}
	}
 
	return -1;
}

Lastly, helper functions for opening and closing lines:

Select All Code:
LONG OpenLine(DWORD device_id, 
	      DWORD api_version, 
	      HLINE *pLine, 
	      DWORD inst,
	      DWORD privs,
	      DWORD media)
{
	return lineOpen(hLineApp,
		device_id,
		pLine,
		api_version,
		0,
		inst,
		privs,
		media,
		NULL);
}
 
void CloseLine(HLINE line)
{
	lineClose(line);
}

Now we can write a simple program to toggle the radio:

Select All Code:
VOID FAR PASCAL lineCallbackFunc(DWORD hDevice, 
				 DWORD dwMsg, 
				 DWORD dwCallbackInstance, 
				 DWORD dwParam1, 
				 DWORD dwParam2, 
				 DWORD dwParam3)
{
}
 
int WINAPI WinMain(HINSTANCE hInstance,
		   HINSTANCE hPrevInstance,
		   LPTSTR lpCmdLine,
		   int nCmdShow)
{
	HLINE hLine;
	DWORD state, radio_support;
	DWORD cell_api, cell_device;
 
	if (InitializeLineUtils(lineCallbackFunc) != 0)
	{
		return 1;
	}
 
	if ((cell_device = FindLineDeviceByName(
			L"Cellular Line",
			"Cellular Line",
			&cell_api))
		== -1)
	{
		ShutdownLineUtils();
		return 1;
	}
 
	if (OpenLine(cell_device, cell_api, &hLine, 0, LINECALLPRIVILEGE_NONE, 0) != 0)
	{
		ShutdownLineUtils();
		return 1;
	}
 
	if (lineGetEquipmentState(hLine, &state, &radio_support) == 0)
	{
		if (state != LINEEQUIPSTATE_FULL)
		{
			state = LINEEQUIPSTATE_FULL;
		}
		else
		{
			state = LINEEQUIPSTATE_MINIMUM;
		}
 
		lineSetEquipmentState(hLine, state);
	}
 
	CloseLine(hLine);
	ShutdownLineUtils();
 
	return 0;
}

Side note: LINEEQUIPSTATE_NOTXRX seemed to have no effect for me. My device turned the radio off on “MINIMUM” but refused the other option as unsupported.

As excellent and generally seamless as Visual Studio’s emulator was, it did not respond to lineSetEquipmentState at all. I guess since it’s not an actual device, maybe it doesn’t bother implementing the “equipment.”

Bug Report Arrogance

Lately I’ve found myself going down an increasingly slippery slope. I always disliked developers that that treat users poorly when they try to report software issues. As my projects reach stable maturity and a great deal of the code stops changing, my ego starts getting the better of me when people file bug reports.

Part of it is ego, and part of it is that I get tired of fixing things on my own. It gets to the point where if I see a bug report pop up in my e-mail, I think “Oh boy, I can’t wait to deny this.” That’s not good, so I’m trying hard to temper myself. Anyway, enjoy this (I used to draw comics as a kid, thought I’d give it another shot).

bug report anger