Thursday, December 07, 2006

Using "ls" in Windows

As my professional life moves into a more UNIX direction I have found myself more and more often trying to execute UNIX commands in Windows. One such command is "ls" - to list the contents of a directory. I know that cygwin binaries can be compiled for Windows to get ls functionality, but I decided to solve the problem a different way. I've written a batch file that wraps the "dir" command in windows. To work properly, both "ls.bat" and "getstrlen.bat" from an earlier post on this blog, will need to be present in your PATH.

I don't have time to explain this code right now, but I will make an effort if anyone asks.

ls.bat:

@echo off

if not "%1"=="" goto gotargs
echo Executing: dir /b&dir /b
goto done

:gotargs
set ARGS1=%1
set CHECK=%ARGS1:~0,1%
if "%CHECK%"=="-" (set CURROPT=%ARGS1% & goto parsearg1)
if not "%9"=="" (echo Executing: dir /b "%1 %2 %3 %4 %5 %6 %7 %8 %9"&dir /b "%1 %2 %3 %4 %5 %6 %7 %8 %9"&goto done)
if not "%8"=="" (echo Executing: dir /b "%1 %2 %3 %4 %5 %6 %7 %8"&dir /b "%1 %2 %3 %4 %5 %6 %7 %8"&goto done)
if not "%7"=="" (echo Executing: dir /b "%1 %2 %3 %4 %5 %6 %7"&dir /b "%1 %2 %3 %4 %5 %6 %7"&goto done)
if not "%6"=="" (echo Executing: dir /b "%1 %2 %3 %4 %5 %6"&dir /b "%1 %2 %3 %4 %5 %6"&goto done)
if not "%5"=="" (echo Executing: dir /b "%1 %2 %3 %4 %5"&dir /b "%1 %2 %3 %4 %5"&goto done)
if not "%4"=="" (echo Executing: dir /b "%1 %2 %3 %4"&dir /b "%1 %2 %3 %4"&goto done)
if not "%3"=="" (echo Executing: dir /b "%1 %2 %3"&dir /b "%1 %2 %3"&goto done)
if not "%2"=="" (echo Executing: dir /b "%1 %2"&dir "%1 %2"&goto done)
echo Executing: dir /b %1&dir /b %1
goto done

:parsearg1
call getstrlen %CURROPT%
REM echo Got strlen: %strlen%
set ARGLEN=%strlen%
set count=%ARGLEN%
set i=1
set newargstr=
set CURROPT=%CURROPT: =%
set remain=%CURROPT%
goto parsearg2

:parsearg2
echo>%temp%\helper.bat set token=%%remain:~0,1%%
echo>>%temp%\helper.bat set CURROPT=%CURROPT%
echo>>%temp%\helper.bat set remain=%%CURROPT:~-%count%%%
call %temp%\helper.bat
del %temp%\helper.bat
if %i% GTR 2 goto resolvearg
:argresolved
set /a i="i+1"
set /a count="count-1"
if "%count%"=="-1" goto parsed
goto parsearg2

:resolvearg
if "%token%"=="l" goto arg_l
if "%token%"=="s" goto arg_s
if "%token%"=="a" goto arg_a
if "%token%"=="t" goto arg_t
if "%token%"=="r" goto arg_r
if "%token%"=="R" goto arg_CR
goto argresolved

:arg_l
if not "%newargstr%"=="" (set newargstr=%newargstr: /n=%)
if not "%newargstr%"=="" (set newargstr=%newargstr: /q=%)
set newargstr=%newargstr% /n /q
goto argresolved

:arg_s
if not "%newargstr%"=="" (set newargstr=%newargstr: /n=%)
if not "%newargstr%"=="" (set newargstr=%newargstr: /q=%)
set newargstr=%newargstr% /n /q
goto argresolved

:arg_a
if not "%newargstr%"=="" (set newargstr=%newargstr: /a=%)
set newargstr=%newargstr% /a
goto argresolved

:arg_t
if not "%newargstr%"=="" (set newargstr=%newargstr: /o:d=%)
if not "%newargstr%"=="" (set newargstr=%newargstr: /t:w=%)
set newargstr=%newargstr% /o:d /t:w
goto argresolved

:arg_r
if not "%newargstr%"=="" (set newargstr=%newargstr:d=-d%)
if not "%newargstr%"=="" (set newargstr=%newargstr: /t:w=%)
set newargstr=%newargstr% /t:w
goto argresolved

:arg_CR
if not "%newargstr%"=="" (set newargstr=%newargstr: /s=%)
set newargstr=%newargstr% /s
goto argresolved


:parsed
if not "%9"=="" (echo Executing: dir %newargstr% "%2 %3 %4 %5 %6 %7 %8 %9"&dir %newargstr% "%2 %3 %4 %5 %6 %7 %8 %9"&goto done)
if not "%8"=="" (echo Executing: dir %newargstr% "%2 %3 %4 %5 %6 %7 %8"&dir %newargstr% "%2 %3 %4 %5 %6 %7 %8"&goto done)
if not "%7"=="" (echo Executing: dir %newargstr% "%2 %3 %4 %5 %6 %7"&dir %newargstr% "%2 %3 %4 %5 %6 %7"&goto done)
if not "%6"=="" (echo Executing: dir %newargstr% "%2 %3 %4 %5 %6"&dir %newargstr% "%2 %3 %4 %5 %6"&goto done)
if not "%5"=="" (echo Executing: dir %newargstr% "%2 %3 %4 %5"&dir %newargstr% "%2 %3 %4 %5"&goto done)
if not "%4"=="" (echo Executing: dir %newargstr% "%2 %3 %4"&dir %newargstr% "%2 %3 %4"&goto done)
if not "%3"=="" (echo Executing: dir %newargstr% "%2 %3"&dir %newargstr% "%2 %3"&goto done)
if not "%2"=="" (echo Executing: dir %newargstr% %2&dir %newargstr% %2&goto done)
echo Executing: dir %newargstr%&dir %newargstr%
goto done


:done

How different is 1080i from 1080p really?

I've had a lot of people ask me about the new HD buzz words floating around on the Internet and in store ads. There seems to be a lot of confusion on the subject of whether or not 1080p is better than 1080i by a large enough margin that the discerning consumer needs to be careful of them. Most recently this question came in the form of an email, and I thought I'd share my answer.

Question: What is the loss of quality between 1080p and 1080i?

Answer: That actually depends on the source material and the monitor - it's a very complicated question to answer but all things being equal the loss of quality would be half of the horizontal resolution.

Another way of putting it:
1080i:
1920x540 pixels displayed at once

1080p:
1920x1080 pixels displayed at once

But this isn't an exact comparison.

The Long Explanation:
Video recorded natively at 1080i will be broken down into two separate fields (540 lines x2). One field (commonly called Field A) will consist of all of the even lines from the original frame and the other field (Field B) will consist of all of the odd lines from the original frame. The idea is that when these two fields are displayed one right after the other quickly enough, that you appear to see the whole original frame (1080 lines) but it only requres 540 horizontal lines to do it. Essentially 1080i relies on tricking your eye into thinking it is seeing more than it actually is.

The interleaving technique was developed with CRTs in mind. Most fixed-resolution displays (LCD/Plasma/DLP) can't actually display an interlaced picture (or rather don't because it would look like crap on that type of display). Instead these displays have image processors that use a variety of techniques to take the interlaced signal and turn it into a progressive signal for whatever the native resolution of the display is. This is where the interlacing really presents a problem, because when being shown on a progressive display, the material has to be "de-interlaced" first. The image processor has three basic options, line-doubling, interpolation, or field overlap.

Line-doubling is the easiest but it is wasteful- just take one of the two fields and show every line twice, discarding the other field entirely - sure, it's using all of the available pixels, but you're really only seeing half of the picture.

Interpolation is the hardest to do and it lowers fidelity- the image processor will "make up" the missing lines by averaging color and lighting info between each pair of lines in a single field and discard the other field entiely. The picture is a little clearer, but you've lost some fidelity because you're no longer seeing the true picture.

Field overlap is the most problematic but provides the best fidelity. Simply taking the two separate fields and laying them on top of each other will give you the complete picture, however if the material was originally recorded in an interlaced format (1080i for example) each field will have a separate time index. What this means is that objects in motion between fields will not line up correctly and this creates an effect called "combing" - where the right and left edges of the moving object will appear like the teeth of a comb.

Most current image processors will use a combination of these techniques, constantly sampling the source material and trying to determine the best method. A lot of progressive scan DVD players have a Video Mode setting that will let you choose something like "Film,Video,Auto" so you can override the image processor if it isn't choosing the right technique.

The "Film" setting is of particular relavence. This is also sometimes called "3:2 pulldown" or "Inverse Telecine". Basically it is a smart version of the field overlap technique. When film material is transferred to video it is run through a machine called a Telecine. The Telecine basically takes each full frame of the film and breaks it down into separate fields to be played back on an interlaced display. Because the frame rate of film (24 frames per second) and interlaced video (~30x2 fields per second) have a constant ratio of 2:3 the Telecine machine uses that ratio to turn every two frames into five fields - that means that our of every five fields one of them will be a duplicate. When your TV or DVD player (it doesn't really matter where the image processor is) detects or is set to Inverse Telecine mode, it uses that known ratio to reassemble the original frames from the interleaved fields.

So the conclusion of the long answer is this:
--If your source material is video (i.e. it was captured/created in 1080i) then your resolution loss between 1080i and 1080p is 540 horizontal lines, because this information will most likely be padded with either fake video information, or line-doubled making every other line redundant. This would be true of most TV shows and video games.

--If your source material was originally film (i.e. it was run through a telecine machine to be made 1080i) and your TV has a decent image processor, then the individual fields will be reassembled into the full 1080p frames resulting in essentially no loss of picture quality whatsoever.

String Length with Windows Batch

I've often found myself needing a reliable way to determine string length with windows batch files. I know there are probably add-ons or third-party solutions, but I prefer to do things with the base system whenever possible. Since I wasn't able to find any solutions, I figured I'd contribute one now that I've written it. This is my code, I don't care if you use it or what you use it for. I hope it works for you and if not, sorry. It relies on the set /a command, which I believe is exclusive to XP (it might work in 2000 but I no longer have a box to test it on.)

getstrlen.bat:
@echo off
REM Sets the variable "strlen" to the length of the first argument.
REM
REM Usage:
REM getstrlen

if "%1"=="" (echo getstrlen error: no argument &goto lengthset)
if not "%2"=="" (echo getstrlen error: too many arguments &goto lengthset)

set count=1
set strlen=

:checklen
echo>%temp%\checker.bat set STRING=%1
echo>>%temp%\checker.bat set equal=no
echo>>%temp%\checker.bat set CHECK=%%STRING:~-%count%%%
echo>>%temp%\checker.bat if "%%STRING%%"=="%%CHECK%%" (set equal=yes)
call %temp%\checker.bat
del %temp%\checker.bat
if "%equal%"=="yes" (set strlen=%count% & goto lengthset)
set /a count="count+1"
if not "%count%"=="256" goto checklen
set strlen=GE256
:lengthset

This will set a session variable called "strlen" which will be assigned the numerical length of whatever string you pass to getstrlen.bat.

Example:
c:\>getstrlen.bat Badger
c:\>echo %strlen%
6
c:
How it works:
The :checklen marker is the beginning of a loop that increments an iteration variable called count.

Every time through the loop the variable passed to the batch is checked by string substitution. The logic looks at a number of characters (represented by the count variable) and compares that to the string itself.

For example, if the string being checked was "Badger", the first time through the loop "Badger" (represented by the variable STRING) would be checked against "B" (represented by the variable CHECK) because count is set to 1. Since they don't match, the script will increment count by 1 and jump back up to :checklen. This time it will check "Badger" against "Ba" because count is set to 2. The process repeats until the sixth time around when both CHECK and STRING are equal to "Badger" at that point count is set to 6. When the helper.bat script finds that the two are equal the value of check is assigned to strlen and the script exits.

Limitations:
The script will only verify strings up to 255 characters long (hopefully you're not trying to use Windows batch for stuff bigger than that!). If you try to check a string longer than that the value of strlen will be set to "GE256" meaning "Greater or equal to 256". And the script will blow up if you try to pass invalid characters like spaces, semicolons or ampersands. Some punctuation is okay but I don't have the time to write an exhaustive list. A safe bet is to either only use this script on strings composed of letters and numbers or to build in your own string validation logic.


What's the point of the checker.bat?
Because variable refrencing in Windows Batch is so limited it is not ordinarily possible to use variables with the string substitution functions of the set command.

I can't do this -
set CHECK=%STRING:~-%count%%
Because the set command will not evaluate %count% before attempting to use it.

In order to get around this I dynamically construct a secondary batch (helper.bat) file using echo statements.
%temp%\checker.bat set CHECK=%%STRING:~-%count%%%
Because the echo command will resolve the variable "count" to the value it holds, the echoed statement is perfectly valid.

If "count" happened to equal 3 during the previous command, open up checker.bat and you'll see:
set CHECK=%STRING:~-3%
Since this is using an actual number rather than a variable, we're all set. Now all that's needed is to call checker.bat from your original script and the variable is set as desired.

It's a bit silly to have to go so far out of your way just to modify the input of a command, but at least it's possible.

Let me know if you found this helpful!

Wii

Over the weekend of November 17th to November 19th, I was able to acquire both of the most sought after consoles, the Wii and the PS3. Personally I consider it unfair to compare the two because the PS3 is such a powerful beast, and the Wii is so much more fun. You can go pretty much anywhere on the 'Net and find opinions about the two systems, and this blog is no exception! I will, however, attempt to provide information that I haven't seen elsewhere.

Due to a strange sequence of events, I actually acquired my PS3 later in the day on the same day I acquired my Wii. And since I'm an unapologetic Nintendo fanboy, I'm reviewing the Wii first.

Nintendo prefers for some reason that the system simply be called Wii and not "Nintendo Wii". I'm sure it figures into the rantings of some social engineering plot designed to cement the system into the hearts and minds of the world, but it also saves me typing so I'm going along with it.

While many people camped out 2-3 days to acquire a PS3, I camped out a day and a half to get a Wii - not because that was the only way, but because I wanted one on day-one. Bored to tears I walked into the Best Buy I had camped out in front of and bought a copy of Eragon. I nearly finished the book by the time the store opened the next day, but, dad-gummit, I was the first one in line and thus got first pick of some of the more hard-to-find accessories like controllers and nunchuck attachments. I also picked up Red Steel, The Legend of Zelda: Twilight Princess, Super Monkey Ball: Banana Blitz, and Rayman: Raving Rabbids.

Out of the box -
System setup was pretty straightforward, but a bit more complicated than any previous Nintendo system owing to the requirements of the new controller. In order determine vertical alignment and triangulate distance from the screen, the system requires a slim infrared sensor bar to be mounted at the bottom of the screen or the top of it. This isn't very complicated to get accomplished correctly, however it makes moving the system from one TV to another more of a chore. I suppose if you count the fact that the controllers are all cordless now you might be able to call it even. Other than that, you have your power cord, and video cables and that's all there is to it. If you intend to use the Wii's online features (many of which are pending a future update) you will need to have a Wi-Fi capable router or access point as the Wii does not support wired Internet connections without the use of a special USB adapter (sold separately, only from Nintendo) The Wi-Fi setup is pretty straight forward. If you have ever set up a computer for Wi-Fi, everything should be more or less familiar. It supports all of the popular Wi-Fi security features like WEP and WPA. Mine was up and running in less than 10 minutes.

The Good -
The Wii remote - the center of your Wii world - is surprisingly simple in appearance but is in reality one of the most sophisticated human-computer interfaces commercially available. It utilizes two different types of wireless connectivity, has a multi-axis gyroscopic sensor that knows the exact orientation of the controller no matter how you tilt it, has a force feedback vibration function, a built in speaker, and a high-speed extension port that allows for a wide variety of possibilities for future expansions. In addition to its myriad features, it has an unexpectedly comfortable heft to it. Usage is very intuitive for simple things like menu navigation and with a little tweaking, could easily replace the PC mouse in a few years. For gameplay, there can be a bit more of a learning curve depending on how and how well the developer implemented it. Games like Rayman: Raving Rabbids were easy to just pick up and play, but Super Monkey Ball: Banana Blitz required a somewhat steeper learning curve. With practice, precision control is possible.

The Wii has a very small "footprint" (the amount of space it takes up on the surface on which it is placed) and should fit easily into just about any TV cabinet, shelf or entertainment center. The ventilation is all accomplished through the back panel of the unit (unlike the Gamecube where the fan vents were on the sides) Wii can easily be sandwiched between or underneath other devices without concern of overheating.

The Wii Sports tech demo included with the system is a very shallow but almost addictive diversion. The Wii operating software has a feature called Mii where you create little virtual characters, somewhat akin to a super-simplified version of the Sims or Animal Crossing. These characters can be sent to visit the Wii consoles of other friends connected to the Internet, and they are also the players in Wii Sports. Each Mii acquires his/her own scores and stats based on how well you perform at the various sporting events while using that Mii as the character. From what I've seen, Nintendo has future titles in the works to build on this feature.

The limited Internet communication is extremely restricted with the intention of keeping kids safe from Internet predators. Non-parent players will probably find it too restrictive as it requires that you first communicate with a person outside of the Wii network to exchange Wii console numbers. Without a Wii console number you cannot invite someone to be your friend, and unless the other person accepts your invitation you cannot communicate with him or her. The idea being that a child is literally unable to meet new people via the Wii interface. There are several fan-run websites that seek to alleviate this restriction by providing a place to meet other players and exchange the codes required to communicate via the Wii.

Zelda and Rayman are by far my favorite games so far. Rayman is stupid fun and makes innovative use of most of the new controller's capabilities. Zelda is as sweeping an epic that any fan could want. These games may not look like Oblivion or Gears of War in terms of polygon count, but they are every bit as much fun.

The system is, as far as I can tell, 100% backwards compatible with Gamecube. Two lids on the top of the Wii open up to reveal Gamecube controller and memory card ports.


The Bad

Along with all of the wonderful new features, there are a couple of annoyances I have encountered with Wii.

--Wii 24/7
This is Nintendo's "always-on" Internet-based service. The Wii will periodically "phone home" to check for system software updates, and your friends can come and visit your Wii to leave messages or Mii's even while you're not playing. Personally I would prefer to have a little more control over this feature. As it is, you have to completely disable Internet connectivity to get your Wii console to stop acting as if it has a mind of its own. It was a little creepy the first time the blue disc slot just came on in the middle of the night and stayed on for several hours. As none of my friends reported visiting at that time, and no software updates were available at the time, there was no explanation provided as to why the Wii had done that. What's more I found that my controller's battery was completely drained in the morning. (The controller part is possibly just a coincidence, but I could have sworn that the battery had at least half a charge left before night time.

--AA batteries only
The Wii remote runs on two AA batteries. With the other current generation systems, the Wireless controllers either have or can be fitted with rechargeable battery packs which can be recharged by plugging the controllers into the system. Given the immense flexibility of the Wii remote, I suppose such a feature is a possibility for the future, but for now you just have to keep changing the batteries. If you decide to use one of the rubber sleeves (I believe they are referred to as "gloves") on your Wii remote, it will have to be removed each time your replace the batteries. The gloves I have are tight enough that this operation is a royal pain.

--Composite Video
From the outset, Nintendo has downplayed the role of High Definition graphics in video games, choosing instead to focus on improved gameplay and improved overall player experience. And I'm all for innovation like that, but I still want the best picture quality possible. The Wii ships with composite video cables - probably the lowest quality signal available on most TVs these days. Composite represents the "just enough to get by" mentality, and that's fine that that is all that you get with the system, but Nintendo grossly underestimated the demand for higher-quality Component video cables needed to get ultra-clear 480p video from the system. What's worse, none of these highly-sought-after cables were sent to stores. The only place they were available was from Nintendo directly via their online store. I ordered my cables on the 16th of November and did not receive them until the 28th due to gross underestimation of demand. In the interim, these cables (which cost me $35 if you count shipping) were being scalped on Ebay for nearly $200 - and people appeared to be paying it! For smaller TVs the improvement provided by these cables will not be so evident, but with larger screens (about 30 inches and above) the difference can be night and day. They made a dramatic improvement on my 42". The supply problem appears to be fixed now, but it was very annoying in the beginning.

--Space
Although the Wii takes up very little space itself, some of the activities suggested by the games take up quite a bit more. Wii is definitely not small-room friendly, at least not for titles like Wii Sports that suggest a wide range of motion.

--Controller Volume
So far I have not found a way to mute or turn the volume down on the Wii remote, and let me tell you the sound effects in Zelda are LOUD. This would seriously hamper one's ability to play a game in the wee hours of the morning (no pun intended) without disturbing anyone sleeping within earshot.

The Ugly

--Wii Shop
The Wii Shop is Nintendo's vaunted "iTunes of Video Games" where players can go to purchase vintage games from numerous classic systems (both Nintendo and non-Nintendo systems) for download and play on the Wii console. It is one of the main selling points that Nintendo has been pushing since before any of us even knew what the Wii would look like or be named.

This feature has gone from being one of the things I was most looking forward to, to being the one I most resent and will likely never use.

When Nintendo first announced this service they (Satoru Iwata at both E3 and SpaceWorld) were adamant that first party titles would be provided free of charge. A year later when the service is actually available, first party software costs from $5 to $10 per game - not free and not even cheaper than third-party software. Nintendo welched on its promise and that stings a lot. I won't go as far as to say that this would have changed my decision about buying a Wii but it sure didn't help. I understand that they are in business to make money, but to make money, you have to have good relationships with your customers. Making promises with no intention of keeping them is not a good relationship builder.

Another big disappointment with the Wii Shop is that although the Wii games themselves have been officially declared region-free (meaning any Wii game from any country should play on any Wii system) the Wii Shop will be region locked to prevent players from downloading classic games available in other reigions. This dashes the hopes of many of us who were hoping some beloved and nearly forgotten titles would have an unprecedented second chance at U.S. distribution.

I have strong opinions about supporting download-based software distribution. Because of the security mechanisms required to satisfy anti-piracy paranoia the usability of such downloaded software is almost exclusively crippled in some way - either it can only be downloaded into internal memory and cannot be transferred to permanent storage (like CD-R or DVD-R) or it will only work with a specific machine, or for a specific amount of time. I consider such restrictions immoral as there are far too many scenarios outside of the customers' control under which they will end up paying something for nothing. Perhaps it is my collector's mentality, or my buy-it-now play-it-later attitude toward a lot of games that makes me see it that way. Or perhaps it is the fact that if such services ever become commonplace the entire video game retail industry will suffer a painful demise. No more EBGames, no more GameStop, no more Game Crazy - just poof gone. And with it any chance of service by gamers for gamers.

So, for now, despite my fanaticism for Nintendo, it is my firm hope that the Wii Shop and any other download-based distribution (like XBOX Live Arcade) fails utterly, and although this demise is largely out of my control, I refuse to contribute to the problem by allowing one red cent of my money to be applied to them.

Conclusion
At $250 a pop, the Wii is definitely a good value. Make sure you either have a big room or avoid games that are likely to require one. Rechargeable AA batteries are a must.

Merry Christmas, scratch that, Happy Jesus' Birthday!

A couple of years ago when the traditionalists and Christians were really starting to get miffed about the politically correct neutering of Christmas greetings, I decided to try a reverse-psychology approach with a friend of mine. Knowing that he was a Christian and not at all bashful about it, I approached him in mid-December and told him "Season's Holidays!". He fixed me with a flat stare and replied "Happy Jesus' Birthday." to rhyme with "Tonight you sleep with the fishes." That is one of my most cherished Christmas memories.