May 29, 2005

BASS Sound Library (Crashing is Bad)

That project I'm working on in the moonlit hours specifies that the BASS sound library be used.

Seems like a pretty adequate tool for playing WAV, MP3, OGG, MOD, MIDI, and probably other formats that I can't even recall at this moment.

One comment I heard about "real hackers" was that they didn't like closed source tools. When a problem turns up in one of the libraries that you've licensed, a real hacker will want to get into the code, find the problem, fix it, and get back to work. Closed source libraries prevent this from happening. (The original author of this comment was blurring the definition of "open source" a bit, talking about libraries distributed in binary form alone, but you get the idea.)

I am reminded of this just now, because I have a BASS DLL and no source code. I've been seeing crashes when running in the debugger that seem to be happening in the DLL, and not in my code.

I'm of the opinion that if you're going to sell your code, it shouldn't crash. If it does crash, consider allowing the licensees to see the code so that they can help you fix it.

My current workaround is to limit the number of channels I have going at once. There may be a hardware maximum, but it seems like I shouldn't have to care about that - any extra sounds that can't be played should trigger an error condition. An error condition that higher level code can catch and respond to. Crashing is bad.

This is almost as bad as the case that an ex-coworker once found himself in - he was working on a console game, and they had a bug where the game could not go on. It wasn't precisely a crash, because the code was still running, but maybe the player control didn't work anymore, so there was nothing for the player to do but reboot the system. The crazy thing is that from within the game they could detect, but not fix, this phenomenon. So they hacked in a faux easter egg screen saying "Congratulations! You have discovered the secret bonus! Reboot your system to go back to the game!"

Posted by tsmaster at 10:47 PM | Comments (2)

May 28, 2005

Using ID3DXSprite

I'm currently working on a 2d game that mostly wants to draw unrotated rectangular images with one-bit (cookie cutter) alpha. Occasionally, though, the design requires that some of these images rotate on the screen (within the plane of the screen, nothing too fancy... yet). One route that I've taken down this path previously is to use OpenGL with an orthographic projection, but for reasons outside my control, OpenGL isn't an option for this project.

Back in earlier versions of DirectX, you might use DirectDraw for 2D games. But these days, DirectDraw and D3D are integrated, so I'm using Direct3D.

Since I've got the fullon 3D pipe available to me, I could certainly draw textured quads to the screen, similar to what I did with "Cars With Guns", but this seems like overkill when most of what I want to do is a simple copy of the image information, unmodified, from the source texture to the screen. In particular, I want the graphics to show up pixel-accurate on the screen without antialiasing or filtering.

In my research, I found CodeSampler.com, which is a terrific source for examples. At first, I was planning to use DirectX 9.0c, and the ID3DX sample got me running, giving me a simple interface for drawing sprites to the screen, with or without rotation, with scaling and other fancy stuff should I make that decision.

One thing that happens in just about any software project is changing requirements. I discovered after getting a working version of the game up that the game had to work on stock Windows XP machines, which meant dropping back to DX8.1.

Fortunately, DX8.1 has support for ID3DXSprite. Unfortunately, the interface is just about completely different. The MSDN documentation for each version, 8.1 and 9.0, is of no help.

    /* during device creation */
    D3DXCreateSprite( g_pd3dDevice, &g_pSpriteContext );


    /* during render */
    g_pSpriteContext->Begin();

    D3DCOLOR c = D3DCOLOR_COLORVALUE(1.0f,
                                     1.0f,
                                     1.0f,
                                     1.0f);
    
    float px=(pSpr->right+pSpr->left)/2.0f;
    float py=(pSpr->top+pSpr->bottom)/2.0f;
        
    float ox=pSpr->right-px;
    float oy=pSpr->bottom-py;
        
    D3DXVECTOR2 scaling(1.0, 1.0);
    D3DXVECTOR2 rotCenter(ox,oy);
			  
    D3DXVECTOR2 translate(pSpr->posX-ox,
                          pSpr->posY-oy);
    
    g_pSpriteContext->Draw(pSpr->textureHandle,
                          &pSpr->srcRect,
                          &scaling,
                          &rotCenter,
                          pSpr->angle,
                          &translate,
                          c);
The code above is a rough sketch of how I use the code. I begin by creating a "sprite context object" - my own term, as calling it a "sprite object" is misleading. I create my sprite object just after I have acquired the device.

Later on, when I'm rendering my scene, first I call Begin() on my context object, at which point, I'm ready to draw the individual sprites.

First, I create a color for the sprite. In this case, I want the original colors to be used, so I use a solid white color.

Next, I set px, py to the center of the sprite within the texture. It's important to understand that the intended use of ID3DXSprite is to draw rectangular sections of source art to the screen, so several of the arguments to Draw() are relative to the upper left corner of the texture.

Second, I set ox, oy to be the "half size" of the sprite (or 'offset', if you prefer). This is the distance from upper left corner of the sprite to the center.

I create a scaling vector, but I don't currently make use of it - so I leave it at a neutral value, (1.0, 1.0).

Next, rotCenter gets the half size offset value, specifying the point around which the rotation should be centered. For my purposes, the center of the bounding box of the sprite is a good point to center the rotation about, but for odd-sized objects (like a fryingpan) you might want to set the rotation center to be somewhere closer to one of the corners.

The last part of the setup is to create the vector describing the location where the sprite should be drawn on the screen. The peculiar bit is that the sprite is positioned by its upper left hand corner, which makes little sense when you start rotating the sprites. So I subtract off the half size offset from the point on the screen where I want the center to be drawn.

Finally, I call Draw(). The arguments are the texture handle, the sprite bounding box (in texture pixels), our scaling vector, the rotation center, the angle (in radions), the screen position coordinates, and finally the color.

Phew.


the MSDN documentation of ID3DXSprite is authoritative, but very difficult to get useful information out of.

Posted by tsmaster at 08:46 PM | Comments (0)

March 11, 2005

GDC 2005: Will Wright unveils "Spore"

Will Wright's talks alone justify the cost of going to the annual Game Developers' Conference. Though he's had only two hits (Sim City, 1988, and The Sims, 2000), he's recognized as a visionary. This has permitted him a certain amount of flexibility and license to pursue projects that others couldn't pull off.

I typically find his presentations intellectually stimulating - an exhortation to explore new spaces for gameplay, to draw inspiration from other disciplines, to make excellent games.

Today's demo was a deviation from his typical format, but it accomplished the same effect.

One observation that Wright has made in years past is that the size of teams for games has been increasing exponentially - games took a couple of people back in 1980, and every couple of years, the teamsize has doubled. "The Sims" took a couple dozen people, and "The Sims 2" took over 60. For comical effect, consider how long it will take before game teams grow to the point where all humanity will need to be employed on a single game.

But let's pay particular attention to the division within those game teams - the folks that work on content (painters, modellers, folks you'd think of as "artists", as opposed to the guys writing the code) have been taking an increasing ratio of the teamsize.

One significant point in history that influenced this phenomenon was the introduction of the CD-ROM. Until that point, the distribution medium was the floppy disk (1.44 megabytes of information on a 3 1/2" device). With the CD-ROM, developers instantly had 450 times more space to fill. I imagine that moving from a 2 bedroom apartment to a 900 bedroom house would be a bit of a shift for most people. You'd still have a hard time getting the car into the garage, though.

One of the early examples of a game that took advantage of this new media format was "Myst", by Cyan. All of a sudden, it was possible to pregenerate an unprecedented amount of detail for stunningly vivid graphics. If you looked under the graphical sizzle, all you'd find was a simple HyperCard slideshow.

Games have certainly become more complex since then, but the example of Myst has remained fairly representative - people filling up their media (with the advent of single-layer DVD-ROMs, we have 4.7GB, dual layer presumably going up to 9.4GB - big enough to fit almost 15 of your 900 room mansions.

But not everyone has headed in this direction, as compelling as it is to fill the media space available. There have been some really impressive accomplishments from the "demo scene", a loose group of creative folks centered around Northern Europe. They've been making very rich "demos", or 3-d noninteractive movies, and since they haven't been targeting retail distribution, the advent of the CD-ROM hasn't been as significant to them. A common self-imposed size limation for a demo is 64 kilobytes. Twenty-three demos could fit in that original two bedroom apartment. If you wanted to fill up a dual-layer DVD with 64 kilobyte demos, it would take about a million man years.

How do these demo coders fit anything of interest into such a small space? The trick that they make use of is "procedural content" - the technique of using a small amount of numeric data to synthesize content at runtime. Wright has long been intrigued by phenomena that act as compression procedures - having described human speech as an amazingly efficient compression/decompression process for getting ideas from one brain to another. And poetry as a compression medium for communicating emotion.

Procedural textures allow a small amount of instuctions communicate the way to construct an image of bricks for a brick wall, or marble for a vase, or even water, rock, earth, and snow for an image of the Earth. It's not unusual for art in today's games to be delivered in 128 by 128 pixel images (sometimes ranging up to 1024 by 1024, in special cases). A single 128 by 128 pixel image in its uncompressed form will take up 64 kilobytes, but the instructions for "make red bricks with white mortar, the bricks being 30 pixels by 14 pixels, and the mortar being 2 pixels wide" might take substantially less (I could imagine somewhere in the 5 to 10 byte range - maybe a little higher - but even at 16 bytes, that's a 4000 to 1 compression ratio, which makes MP3's 10 to 1 compression ratio (give or take) seem paltry.

Indeed, if you remember MIDI music files, you'll grasp what's going on here - through use of concise description (and the assumption of a certain amount of intelligence on the other end) you can say "use a clarinet to play a middle C quarter note" without having to provide every detail of what that sounds like.

If the talk of compression ratios has caused your eyes to glaze over, get a drink of water and come back to this point, because now I'm going to start talking about what Wright is planning to do with this technology.

He began by showing a fairly simple looking 2d game. He described it as a free-form version of Pac Man. In the middle of the screen, there was a little critter - to me it looked a little like an earwig or a silverfish.

The bug swam around in a petri-dish-like enviroment, sometimes eating little yellow balls, sometimes evading brown balls. Ho, hum. There are plenty of little games like that, I'm sure you can whip one out in Flash in half an hour. Nothing exciting yet.

After a while, the bug had acquired enough energy to "level up", and Wright opened up a menu, which allowed him to "purchase" new body parts for his bug. He chose a spike that he chose to mount on the nose of the bug. There were numerous other mounting options available to him, and I wondered how a spike on the tail would have affected the bug's survivability. With the spike on the bug's nose, Wright was able to chase after the brown balls as a predator - he had taken one little step up the food chain.


----------
ZOOM OUT
----------

At this point, there was a discontinuity of gameplay. I'm not sure how it will be managed in-game, but through the slight of hand that we excuse in demos, we suddenly found ourself transported from a 2d petri dish up into a 3d underwater scene. The creature that we had seen before had grown up. It was now a swimming beast, and was chasing after small fish. After a little while of this, Wright was able to go back to the Body Parts Purchasing Menu and rebuild the creature. Remove the fins, rearrange the tail, bend the spine like so, make the nose shorter, let's add some legs, two legs, three legs, yeah, three legs seems good. Let's add on a prehensile grabber body part on... let's say the tail. And back to the game.

Without fins, the creature isn't much good in the underwater scene, so let's walk out onto land. A beautiful tropical beach, with grasslands and trees and a number of other creatures greeted us. Well, not so much "greeted" - the first thing we did as we came out of the water was chase after a little creature.

One thing that was impressive was that the freeform sculpted creature that Wright just made was moving around in a natural-looking way. It's hard to know how a three-legged lizard would naturally move, but I was willing to believe that this was one possible way.

The other critters on the land, Wright told us, actually were authored by other players. This is where the procedural content is beginning to make a huge difference; the "DNA" encoding my three legged lizard amounts to a tiny packet of information. The game transparently sends this up to a server in the background, and shares the content that you've created with other players. In exchange, you get a bunch of content back. Lots of novel critters to eat. Each handmade. Each with a little bit different of a personality, a little different behavior.

After chasing after a few little beasts, Wright's lizard found a scary predator that he couldn't take on. So he fled. The predator was actually pretty frightening - and created with the same set of tools as we had used to make our lizard.

For fun, Wright chose to use a mating call. There was a shrill call, which was soon answered from somewhere behind us. We were able to find another creature like ourself and we went about engaging in sweet lizard love. I'm pretty sure the sax music in the background wasn't procedurally generated, but it did get a laugh. I can only imagine that if they could procedurally generate some Barry White, they would have.

After growing our creature some more, Wright pointed out that one of the "upgrades" for our creature was a bigger brain. And that as the brain got bigger, eventually the creature would become sentient.


----------
ZOOM OUT
----------

Another discontinuity of gameplay, and we now see a cluster, no, a VILLAGE of our little lizard guys. They're moving around in a believably social fashion. Our boy's done well for himself, I think. At this point, the game very much resembles "Populous: the Third Age". The player no longer controls the individual creature directly, but is able to drop goodies into the village for our critters to play with. At first Wright gave our guys a rack of spears. A handful of lizards crawled over to the rack and grasped the spears in the grabbers at the end of their tails. Menacing chaps.

"Before they get into trouble", Wright said, "let's give them a campfire". And the spear-bearers gathered around the fire. "And a drum", which was soon being beat by one of our lizards. The spear-bearers broke into a dance around the campfire which looked entirely like every tribal dance (every tribal dance involving spears, drums, and campfires).

As your village grows, eventually it becomes a city.

----------
ZOOM OUT
----------

We're now looking at an oddly Seussian looking collection of buildings. Here and there, we can see little lizard guys moving between them. I'm reminded of "The Sims" in a weird way. Wright grabs one of the buildings - a blobby collection of mushroomy bulbs - and goes into the building editor.

The building editor looks and feels just like the creature editors. Soon he's adding a couple new blobs to this building, and we're popped out to the 3d view again, and our building has a brand new mushroom-shaped tower. At the base of the building, a crowd of lizard guys cheer. Very much like "The Sims". I think they appreciate our architectural choice.

Wright explains that there are different buildings we can buy, and of course, our menu of buildings include some options authored by other players, selected for us according to our play style. If you make a building that goes up to the server, and a lot of people put that building in their cities, it gets positive feedback, causing it to be distributed to even more players.

As you build your city up, eventually, you'll come in contact with other cities, and you'll find yourself wanting to interact with them. We flew over to a nearby city, and Wright pointed out the very different style of this city. This was very mechanical, very austere. East German, if you will. Wright commented that he wanted to support artistic styles as diverse as Pixar's "Finding Nemo" to H. R. Geiger's "Alien". He also drew our attention to the three tanks emerging from this city, trundling back... back to our HOME!

We quickly went back and built some Seussian looking ostritch flying machines. Which proceeded to fly in precisely the wrong direction, leaving our town undefended as the tanks came and proceeded to pound on our city wall.

----------
ZOOM OUT
----------

At this point, without any cuts, Wright pulled back and we were able to see our town and the neighboring town. He put up a slide on the other projection screen, showing one of those cartoon "maps" of Atlanta - the kind where downtown is zoomed in and the suburbs are clustered around it, and just beyond the suburbs is California.

The point he was illustrating was that as you pulled away from your city, the city was out of proportion - other cities became visible as we pulled back and the entire globe fit on the screen, but we were still able to see the locations of our city and its neighbors. This is important, because at this level of the game, the player is responsible for building up a civilization (like many other games, including "Civilization"), which is going to involve managing city-states and the populations of continents.

He spun around the globe, showing the different continents available on this planet. There were little wispy clouds all about. The water shone, the land was green in places, brown in others.

And then we zoomed back in to our city. Wright mentioned that as you advance your technology, you'll be able to build a UFO. A goofy looking flying saucer appeared, and hovered around the city. At this point in the game, the UFO becomes "your swiss army knife", the device that you can equip with all sorts of neat upgrades. One of these abilities that the UFO can be equipped with is a beam of light that you can point down on critters on the ground. We chased after that scary looking critter from back when we had just barely crept out of the water. We "abducted" a few animals and flew around a bit.


----------
ZOOM OUT
----------

Out to low orbit. Out further, the planet turns into a small disk. Other planets appear. We see the shape of a solar system, with a gas giant, an asteroid belt, and several other planets. We fly over to a remote planet, further out than our own. We zoom in, and it's an icy ball, pocked with craters. We proceed to beam the monstrous creature to the surface.

Uh-oh. Creatures don't survive well on airless planetoids. It burst in a particularly crowd-satisfying manner. I guess we'll have to do something to get an atmosphere onto this planet. One of the tools on our UFO happens to be a missile that creates volcanoes. Zap, Zap, Zap. We're beginning to see the plume coming from the volcanoes turning into an atmosphere.

But that's not fast enough - Wright uses 'The Genesis Device' - another tool (weapon?) that he launches, resulting in the low-lying areas filling in with water, grass greening up parts of the land. It's not quite eden yet, but it'll come along. Before we unleashed the Genesis Device, we established a colony on the arid rock, a cute little city inside a bubble. One day, we'll have terraformed the outside to a point where they don't need the bubble anymore.

----------
ZOOM OUT
----------

So. We've colonized an alien world. We're terraforming other planets. Quite the achievement, so far. I wonder if there's anybody else out there? Zoom out from our new planet, out from our solar system, there's a nebula, there's a black hole, we're seeing a 3d stellar neighborhood. The planets are no longer visible, all we can see are phenomena familiar from Hubble photographs. Let's mouse over the various things that we see. There's some interesting noises that we can discern by listening to radio emanations from the distant bodies.

Wait, what's that? I do believe that I hear alien radio transmissions. Let's go investigate. Fly over to a distant star (we've got a UFO - three light years? Thirty?) and drop down into the alien solar system, isolate the alien planet, and find an alien city.

It's a completely different art style, of course. We want to make first contact with this race. Maybe they'll be our friends. We play the "Close Encounters" musical greeting. Or perhaps the aliens don't understand us, because they begin launching missiles at our UFO. We attempt to fight back, but our weapons are doing us no good.

We retreat to space, and Wright unleashes some larger weapons. Boom, the city is gone. Boom, what was once the planet is now a new asteroid belt. "There goes my reputation as a non-violent game developer."


At this point, Wright mentioned that the options available now were varied - we could attack alien planets (think Independance Day), we could take a paternal relationship to them (The Day the Earth Stood Still), we could seed them with technology (2001), abduct their creatures and interbreed our creatures with them (X Files) or engage in diplomacy (Star Trek).

Thinking about Star Trek, he pointed out that he wanted to make sure it was possible to represent all the favorite races as simply as possible. What would happen if the Klingon Empire encountered The Borg?

----------
ZOOM OUT
----------

Our final zoom of the day, we now see the spiral disk of our galaxy. How many stars? How many planets? How many races out there?

Wright commented that his intention was to provide the climb up the evolutionary ladder as the tutorial, and then allow the players the sandbox for the remainder of the game. This is an interesting reversal - most games treat the goal-directed part of the game as the overarching structure. In Spore, Wright intends to let the players toy with the galaxy available to them at a huge range of scales.

He then apologized that he would not be able to talk more about this game until E3. This hints that the game is more than a fancy tech demo (oh, but what a tech demo!) - but it's actually a production project. As I began writing this account, I was sitting next to a Maxis employee who commented that Spore was "a great game". I wanted to grill this individual for information that I realized would not be forthcoming - if Will Wright wasn't able to talk about it, this individual wouldn't be either. The one thing that this individual was willing to pass along was that "everyone thought it was a very ambitious game".

One of the questions I decided not to ask was going to be "how much of that demo was staged, and how much is shippable code?". I take the "ambitious game" comment to mean that much of it was demo-only, which suggests that it's not going to be on shelves for your Christmas gift giving.

If I have to wait for Christmas 2006, that'll be OK. Because it is a very ambitious game - crossing a phenomenal range of scales (think of Eames' "Powers of 10"), providing the players the opportunity to create and own their race of creatures, which could eventually visit strange new worlds, going where no three-legged-lizard had gone before.


I'm anxious to see what E3 has in store for us.

Posted by tsmaster at 09:52 PM | Comments (0)

March 06, 2005

Sony DCR-TRV39 as a means for pushing back on obsolescence

Remember the commercial that had the cute chick talking about how easy it was to use her camcorder with her iBook? Macintosh saved Christmas!

I'm not as attractive as Janie Porche, and I can't say that I saved any solstice-proximate holiday, but since I got my Mac, I've been enjoying working with digital video.

The setup I have is a little peculiar, and given that I forget things, I'll document it here. If there's some non-me reader that gets some value out of the discussion, that's good, too.


Here's a few situations that come up, some more often than others:

These essentially boil down to "I want to get data off my TiVo and onto a DVD-R". The last case will be left as an exercise for the reader, but as a hint, it's "I want to get data off my LaserDisk player and onto a DVD-R".

Over time, I've gone through a number of different technologies for acquiring still or moving image content into the digital domain, including an Intel card back in 1993 that struggled to keep up with realtime footage, even when downsampled to a low-res image size. More recently, I got a Dazzle video capture device that connected over USB2 to a desktop Windows PC. I think I was most frustrated with the software included with that device - the hardware seemed adequate.

These days, what I do is hook up my Sony Digital Video Camera Recorder (tm) between my video source (TiVo) and my digital consumer (the Mac in this example). The model of camera (in case you weren't paying attention at the top of this post) is a DCR-TRV39. It's got USB2, Firewire, and modem(!) connectivity, which mostly seems useful for sucking data off of recorded tapes. However, there's a feature documented on page 163 of my manual, titled "Capturing images from an analog video unit on a computer - Signal convert function". To set this up (in case you've lost your manual), turn on "A/V->DV OUT". You probably also want to remove the tape from the camcorder - sometimes it makes things a little easier.

I think that if I were using USB, I'd be able to do this next bit simpler, but I use Firewire for the superior video quality, and the software that I've used recognizes my Firewire-connected camcorder and proceeds to send all sorts of commands up the wire to it. When I want to start recording, the host computer says "hey, start rolling the tape so we can record". Which isn't what I'm trying to do in this situation. Some higher-end (less broken) software can actually turn this off, and perhaps I had to do this in order to get my configuration to work. I don't recall now exactly what I had to do, but it is possible.

So. We've got the camcorder hooked up via Firewire to the Mac. There's a 1/8" Stereo+Video socket on the camcorder, and I connect that up to the TiVo. TiVo also has SVideo out, and the camera has SVideo in. So when I can, I use that. Now, I know that I'm going from digital (TiVo) to analog (SVideo or RCA) back to digital (the camcorder), and perhaps the difference between the connections wouldn't be visible to me, but I've got the cable, I might as well use it.

That's all the necessary physical connections. Data flows from one device to the next to the next. Turn the camcorder on, launch iMovie, press "Import", press play on the TiVo box, and then everything's good to go. iMovie doesn't like to work with clips that are 10 minutes long, so it breaks them up. But don't worry about it - when you put them back together, it'll be fine. Or, if you're recording a commercial broadcast, you can stop the import during the commercials; that often yields clips that are more meaningful.

Once I've captured all the content I'm interested in, I grab the clips and assemble them on the timeline at the bottom of the screen. If I need to trim some stuff (remove commercials, get rid of TiVo user interface that got captured before or after the show), that's easy enough - make sure to tweak the "Zoom" slider and not the "Rabbit/Turtle" slider to be able to make good cuts.

Here's where there are a few options - if I'm going to create a collection of shows on one DVD, I export ("share") the movie as a DV movie at high quality. (Look under the Quicktime tab.)

If I'm going to make a DVD with a single movie on it, I might feel like adding chapters within iMovie. That's done from the iDVD button (lower right corner of the screen) which allows you to place chapter markers. Then, when you're done, you can export directly to iDVD (saves you a step of exporting/sharing explicitly).

I'm not sure I'm completely comfortable with iDVD yet - I suspect that it's more useful than I've plumbed; maybe I've only found the scissors and corkscrew on the metaphorical swiss army knife. Just today I figured out which slider I needed to play with if some of my menus had animating video buttons while others had still frames (it's on the settings tab, near the top, make sure the duration of the loop isn't set to 0:00).

So far, I'm using single-layer DVD technology. I'm waiting until Dual Layer DVD-Rs (plus? minus? I don't think I care) drop below $5 a pop. Even better would be if printable dual layer DVDs were easily available.

Anyway, single layer means an hour at the "optimize for speed" setting, or around 2 hours in the "optimize for space". As I suggested above, I don't get worked up about video artifacts too much, and I'm happy letting the machine chew on a movie overnight. I've turned off the feature where iDVD starts encoding before you hit "Burn"- I forget if that was something I did as part of diagnosing another problem, but I thought I had some problem with it.

One thing I'd like to be able to do - and maybe it's possible - is be able to save the iDVD and iMovie projects in some way onto the DVD as data so that I can stick the burned DVD into the drive and easily duplicate the disk I've made. Let's say I made a disk of wedding movies, and after burning 20 copies, I might think that it's OK to get rid of the project data. Until such time as I recall that Aunt Lydia didn't get a copy. (Nevermind the fact that Lydia doesn't have a DVD player. Maybe we'll get her one for Christmas.) It'd be nice to churn out another DVD, picking up pretty much where I left off after the 20th copy in the first print run.


So, that's the ramble-laden process. The one bit that could afford the most speedup is the fact that I'm capturing at realtime, which means that the 20 episodes of Good Eats that are taking up my TiVo space aren't getting ripped this afternoon.

But I'm able to show my friends one of my favorite movies, and until there's a Project Gutenberg for obscure film, the above-described mess of cables will do the trick.

Posted by tsmaster at 03:40 PM | Comments (0)