Tuesday, April 8, 2008

Ultramon-itoring the Crysis


Several years ago I upgraded one of my CRTs to an LCD. The primary benefit of an LCD over a CRT is simply its increased clarity when working with text. Spend a short time on an LCD looking over text and going back to a CRT is painful (on the eyes).

But my CRT has continued seeing use for one specific reason.

If you've ever played a game that has panoramic views, e.g., first person shooters, a CRT has one big benefit over an LCD - fuzziness. "What's that?" you ask. It turns out that the great ability of LCDs to show razor sharp content isn't so great with real time generated panoramic views - the geometry of a scene is filled with noticeable stair step edges of polygons that make up the models that appear in the view.

To combat this problem, over the years Graphics Processing Units (GPUs) from mainstream companies like nVidia and ATI have become much more powerful. With that power, GPUs have increasingly been tasked with performing anti-aliasing to smoothen the edges of an image. The catch in this equation is that your GPU expends far more cycles computationally eliminating the jaggies and this impacts the maximum frame rate you can achieve. It can turn a playable game on a CRT (with no anti-aliasing) into a sloth (unplayble) on an LCD (with anti-aliasing).

A CRT's inability to show razor sharp text lends itself quite nicely to panoramic views that fill the entire screen vs. a small area where your focus is fixated on a word (like the one I just italicized). By turning off full scene anti-aliasing while using a CRT, you spare a GPU a tremendous amount of work. It so happens a CRT’s lack of sharpness for text is great for wide vistas - the natural perspective of first person shooters.

Only thing is, when I've wanted to use my old CRT for gaming, I've had the hassle of making like a monkey and going through GUI motions - right clicking on the Windows desktop, selecting Properties then making the CRT the main display. Then when I'm done, go through this all over again except this time making the LCD the main display.

Yes GUIs are great but not when you need to perform a task repeatedly. Go through this enough times, which I have, and it gets old. Very old. There have been times I don’t even bother firing up a game on account of the hassle factor (but there’s another hassle factor that I’ll get to in a moment, it has to do with the position of application windows on the Windows desktop).

But because of Crysis I’ve been going through the motions as annoying as they are. The game is simply that good. The visuals and realism are stunning. It really ups the ante for first person shooters in a big way.

Before I go further I should point out that I use a very nice little utility program called Ultramon:

http://realtimesoft.com/ultramon/overview/

One of the benefits of Ultramon is a task bar for every extra display you have. Applications sitting in other displays will fill the task bar found on that display versus the task bar of your primary display. This nice touch keeps the task bar on the primary display from getting cluttered. If you work with multiple displays, once you get used to Ultramon in this regard, it's hard living without it.

Another nice Ultramon feature is the ability to set independent wallpapers for each display. Windows XP by default uses the same image on every display when you set your desktop background.

Ultramon also happens to provide an icon in the task bar area that when navigated allows you to quickly set which display is the primary as well as disabling the secondary display. So firing up a game on my CRT, I would use Ultramon’s icon in the task bar to make my CRT the primary display then quickly disable the LCD. Why disable the LCD? Some games like Quake 4 consume a lot of video memory for textures. I found that unless I disabled my secondary display, I could not run it at its maximum display settings (Ultra).

While using Ultramon is faster than right clicking on the Windows desktop and going through the usual motions, even so, the GUI (monkey) way still got old. Very old. Reverting was even even more work - I’ll get to that in a moment.

Then I had some inspiration, I had a recollection that Ultramon provided COM objects with OLE Automation support. This meant I could probably write some VBScript code to automate switching displays and setting things back to the way they were. After reading Ultramon's documentation I came up with these two scripts.

gameCRT.vbs
------

Const POS_ALL = &H7

Set sys = CreateObject("UltraMon.System")
Set Sony = sys.Monitors("2")
Set ViewSonic = sys.Monitors("1")

sys.SavePositions POS_ALL
Sony.Primary = True
sys.ApplyMonitorChanges
sys.SecondaryDisable



enableLCD.vbs
-------

Const POS_ALL = &H7
Set sys = CreateObject("UltraMon.System")

sys.SecondaryEnable
sys.ApplyMonitorChanges
Set ViewSonic = sys.Monitors("1")

ViewSonic.Primary = True

sys.ApplyMonitorChanges
sys.SecondaryDisable
sys.SecondaryEnable
sys.RestorePositions POS_ALL


So the start of gameCRT.vbs makes my Sony CRT the primary display, I apply this new state then I disable the secondary display which implicitly means my ViewSonic LCD. This bears some qualification. I expected to be able to set properties on my two displays then finish with a call to ApplyMonitorChanges but that caused a very annoying problem, at least with a couple of permutations I came up with. Namely, when I re-enabled the LCD later… the positions of the monitors had become inverted so if I moused off the left edge of my LCD (the left display), the mouse pointer would appear on the monitor to the right (the CRT).

Getting around this problem by playing with Ultramon’s object model consumed more time than anything else.

The second script enableLCD.vbs starts off with enabling the secondary display, which is my ViewSonic display on account of the first script implicitly making it the secondary. Then I set the Primary property making the Viewsonic LCD the primary display and again apply my changes with an invocation to ApplyMonitorChanges.

At this point in the script you would expect to be done but it turns out the Windows start menu is still displayed on the CRT even though the CRT is now the secondary display. You would think the Windows Start menu would naturally move itself to the primary display but that wasn't happening. As it turns out, this is not a new problem - I was experiencing the exact same behavior when I would do things interactively.

To solve this problem I disable the secondary display (the CRT now) at which points Windows’ Start Menu gravitates to the LCD (where it was before I decided to fire up a game). Finally, I re-enable the secondary display (the CRT). So reverting things takes additional steps whether you do it interactively or via my VBScript, the steps are logically the same.

That’s why the script has:

sys.SecondaryDisable
sys.SecondaryEnable


It's not immediately obvious why I would disable the secondary display and then enable it immediately afterward but now you know.

Back to back after the ApplyMonitorChanges call.

Ultramon can also keep track of the positions of the windows of applications as you flip flop. Notice this statement in the first script:

sys.SavePositions POS_ALL

And the following statement in the second script:

sys.RestorePositions POS_ALL

WinAmp is very, Very, VERY annoying when you change which display is the primary. The lower half of WinAmp, the playlist, detaches itself from the top half of WinAmp and the two windows get tossed to random positions on the desktop. Meaning WinAmp winds up in an altogether different location than where it was running. Then you have to spend time re-juxtaposing WinAmp's windows. Like I said, extremely annoying.

I also happen to run my CRT at a lower resolution than my LCD. This means when the secondary (LCD) is disabled after making the CRT the primary, applications like Firefox snap to the new smaller dimension of my Windows XP desktop. Unfortunately when I re-enable the LCD and make it the primary, applications do not snap back to their original size and location. Which means you wind up having to resize and re-situate all your applications.

It shouldn't be surprising that there are times you don't even bother firing up a game on account of all this. But with scripting and Ultramon being able to save state, all these hassles are eliminated.

Lastly I created two batch files, gameCRT and lcd which simply map to:

cscript /nologo gameCRT.vbs

cscript /nologo enableLCD.vbs

I have to give kudos to Microsoft for having architected Windows in such a way that it facilitates the development of scriptable objects by third party vendors. Considering the hassles eliminated, I really didn't care what scripting language was at play - VBScript, PERL, Python, etc., etc. In the end I automated the swapping of displays to more easily get my game on with the CRT whenever I saw fit.

Wednesday, April 2, 2008

Are You A god? Probably. You Just Don't Know It.

What could I possibly be talking about with a subject like that? Readers will find out soon enough. I've been working on a project. Something for Windows XP/2000 and to a lesser degree Windows Vista.

I submitted the program (with an installer) to Download.com and was given a public availability date of April 11th.

Yes, with this blog entry I'm not writing a "small book". What I created goes beyond catering to a technical readership. It has application to anyone who uses a web browser, including your uncle John who may have gotten his first computer last week because it seems some of his coworkers at the factory got one. Or your aunt Mary because she's into cooking and her best friend Sally whom she bowls with every Friday has gotten tons of recipes off the Internet. Now your aunt Mary wants to dive headlong into the Internet and she's been bugging you to go to Best Buy with her to pick a computer. Or, your grandmother, if she's a vanguard for her age group. But, most importantly, you.

I've been trying to think of a catchy domain. More to come.