April/May 1995

GAME DEVELOPER MAGAZINE GAME PLAN GGAMEAEM

Delphi is Editor Larry O’Brien [email protected] the Answer Senior Editor Nicole Freeman [email protected] Managing Editor Nicole Claro [email protected] ormally I make it a rule not to to gain by examining Delphi. Why? The Editorial Assistant Deborah Sommers recommend any programming huge, relatively untapped Windows game [email protected] tool that I haven’t used to market. With Delphi, you can use WinG Contributing Editors Alex Dunne develop a program from to get your images on screen relatively [email protected] scratch. I’m going to break that quickly, and you also can get many more Chris Hecker rule to recommend Borland’s compile-link-debug cycles in a program- [email protected] Delphi. I’ve only used it to ming session. Windows game develop- David Sieks [email protected] develop a program that trans- ment inevitably involves hit-and-miss pro- Wayne Sikes Nlated from Celsius to Fahrenheit degrees, gramming challenges (no matter how [email protected] but the only reason I’m not altogether experienced you are, the Windows API Editor-at-Large Alexander Antoniades committed to Delphi is (I’m blushing as I can surprise you), so more cycles means [email protected] type this) I’ve never learned Pascal. Well, faster development. When you’re done, Cover Photography I’m going to learn it now. For Windows your programs run at compiled speeds. Charles Ingram Photography developers, and for Windows game devel- Also, Delphi abstracts the Windows opers especially, Delphi is so far ahead of API. If this abstraction isn’t good enough Publisher Veronica Costanza the competition it’s embarassing. for you, feel free to create your own. Del- Group Director Regina Starr Ridley The world of Windows development phi’s code reuse infrastructure is excellent, has always been one of compromise. Tools with full object-orientation and the ability Advertising Sales Staff such as Visual Basic offer immediate grati- to package groups of objects together as West/Southwest fication when moving from writing code functional components. Develop an engine Yvonne Labat (415) 905-2353 to seeing your program run, but the per- for isometric projection, and you can save [email protected] formance has always suffered in compari- it as its own package and use it as a start- New England/Midwest son with compiled code. On the other ing point for future games. Kristin Morgan (212) 626-2498 hand, compiled C++ offers near-optimal Delphi is based on Object Pascal [email protected] performance, but all but the most trivial which, as I said, is a new language to me. programs have compilation times mea- However, it’s very straightforward—C++ Marketing Manager Susan McDonald sured in minutes, not seconds. Program- it ain’t. Although I’ve already discovered Advertising Production Coordinator Denise Temple mer productivity vs. compiled perfor- some things that I don’t like (the keyword Director of Production Andrew A. Mickus mance. Pleasure for the programmer vs. private doesn’t act the way I think it Vice President/Circulation Jerry M. Okabe pleasure for the user. The iron compro- should, and I can never figure out where Group Circulation Director Gina Oh mise of Windows. semicolons are expected), I’ve also already Circulation Manager Kathy Henry Delphi makes no compromises. For- come up to speed on the basic structure of Circulation Assistant Phil Payton get the claims of how many hundreds of the language. You should have no trouble Newsstand Manager Pam Santoro thousands of lines of code are compiled picking it up and, just as importantly, you Reprints Stella Valdez (415) 655-4269 per minute, the point is that Delphi’s shouldn’t have any trouble finding new speed of compilation is such that the programmers fluent in it. MillerFreeman A MEMBER OF THE UNITED NEWSPAPERS GROUP move from editing to debugging is seam- You’ll be reading a lot about Delphi Chairman of the Board Graham J.S. Wilson less; when your screen flickers you think a in the corporate programming magazines, President/CEO Marshall W. Freeman background compilation process is being where it will be primarily lauded for its Executive Vice President/COO Thomas L. Kemp spawned but, in fact, you’re seeing the ability to create database applications. But Senior Vice Presidents H. Vern Packer, Donald A. results of the final link. I’ll make a bold prediction—the most suc- Pazour, Wini D. Ragus Delphi is being marketed toward the cessful Windows game of 1996 will be Vice President/CFO Warren (Andy) Ambrose current marketing darling, corporate written entirely in Delphi. Until that ships, Vice President/Administration Charles H. Benz developers, and there’s no question that it I’ll be busy learning where the stupid semi- Vice President/Production Andrew A. Mickus ■ will cut a swath through the ranks of Visu- colons go. Vice President/Circulation Jerry Okabe al Basic and PowerBuilder users out there. Larry O’Brien Vice President/Software Development Division Regina However, game developers have even more Editor Starr Ridley

4 GAME DEVELOPER • APRIL/MAY 1995 SEZ U!

More to the Mystery

by Our Readers Dear Editor: but I still think that it’s worth it. I think it would like to offer a few suggestions to sup- would be enormously helpful if after each arti- plement Andre LaMothe’s article “The Myste- cle you gave a brief reading list of good books Something on your Irious Mode 13h” (Sept. 1994). that provide more information about a partic- I am a shareware game programmer who has ular topic. For instance, in the December issue been using Mode 13h for about two years now. I you featured a great article on Mode C (umm... can see at least one obvious ways to speed up excuse me...Mode X) but I would like to know the graphics functions Mr. LaMothe described. of a book that would give a beginning-to end mind? A response to an The first would be to avoid using the palette breakdown of the technique. This would help ports (0x3C7/0x3C8) as much as possible. One those who aren’t quite as technically blatant way that I can see to do this would be to advanced as some, and keep the folks who are eliminate reading the port whenever the pro- advanced happy. Plus the market for computer gram needs the value of a specific register. books is so full of crap that it would be nice to article, a query about Instead, simply create a structure: have someone who knows something suggest good books. typedef struct { Gideon Stocek unsigned char red[256]; via e-mail code, a little poem or unsigned char grn[256]; Editor Larry O’Brien responds: unsigned char blu[256]; Good suggestion! We’re running book reviews } PaletteStr; regularly to try to cut through the crap (see Dean Oisboid’s article on page 48). One sugges- Clear the structure in the beginning of the tion: don’t buy a book that calls you stupid. If ditty, perhaps? If you program, and also clear the palette (set all the title’s condescending, the text will be as “bucket” values to (0,0,0)) using the write well. port. Then, whenever the structure is updated, simply update the array value as well. That way, a function can simply look up a value in WHERE’S THE CODE? have anything to get an array instead of having to write/read to a Dear Editor: port. This also streamlines the color cycling ’m looking for the code for Carl Muller’s function by eliminating the overhead associat- article “Hitting on Collision Detection” ed with procedure calls (about five processor I(Sept. 1994). The article states that it is cycles). Simply rotate the array, then push the available on CompuServe, but I can’t find it. off your chest, please whole thing out to the VGA card when the cycle Do you have any more detailed information on function is done. exactly where it is, the filename, forum, and so Mason McCuskey on? I’d also like to know if it’s available on any via e-mail ftp sites. do. We’ll probably Leonard Guy MORE READING MATTER via e-mail Dear Editor: Editor Larry O’Brien responds: enjoy your magazine, I find it helpful and On CompuServe, Go SDFORUM and visit our interesting. I would like to see the price go library. Or set your browser to the print it here. Idown or the amount of material in it go up, /pub/gdmag/src ftp directory of whiz.mfi.com.

GAME DEVELOPER • APRIL/MAY 1995 7 CROSSFIRE

Media Vision Picks Up The Pieces

Alex Dunne igital entertainment is often months after the company went public in the media spotlight. Usu- at $15. Although the stock was gener- ally we hear about technolog- ally regarded as overvalued, nobody ”We‘ll be quiet, but ical breakthroughs, though— realized how much so until a few rarely are high-tech compa- months later. nies involved in controversies. There have been some Greenberg Blows we‘ll be here,“ notable exceptions, though, The Whistle andD surely Fremont, Calif.-based Media Herb Greenberg, a columnist for the Vision stands out as a Silicon Valley San Francisco Chronicle, did some inves- soap opera. Media Vision scraped bot- tigating and discovered that Media tom last summer when it filed for Vision had falsified sales records and says Robert Brownell, Chapter 11, ironically due to the lack of engaged in shady business practices to vision that the company—led by former paint a better picture of the company’s CEO Paul Jain—had. However, this finances. According to Greenberg, year Media Vision emerged from bank- Media Vision secretly rented ware- CEO of Media Vision. The ruptcy and is attempting a comeback houses to hide returned merchandise, with the help of new management and pressured engineers and sales reps to capital. The company has refocused on get defective products out the door, its core technology, audio cards, and is offered huge incentives to distributors company took some in the process of rebuilding the public’s and retailers who ordered large quanti- confidence and researching new audio ties of merchandise (known as “channel technologies. stuffing”), and most egregiously, doc- The company’s problems began tored shipping papers to charge a large recent blows —many back in 1993. Media Vision was well quantity of multimedia upgrade kits to positioned in the red-hot multimedia a previous fiscal quarter. market, thanks to its Pro AudioSpec- Jain, who some believe was the trum sound cards and multimedia force behind the company’s question- of them self-inflicted. upgrade kits, yet ongoing price wars able practices, was a favorite target in with rival sound card makers like Cre- Greenberg’s columns. One of Green- ative Labs and an overextended product berg’s columns even poked into Jain’s line were taking their toll on the com- personal life, referencing allegations pany. In October of 1993, Media that he illegally used Media Vision’s Now it‘s back with a Vision rolled out a plan to produce corporate assets to “court women.” I CD-ROM games, instantly making it a bet Jain loathed opening up his morn- major player in the game industry. ing paper for fear of what he’d read in As a complementary product line, the business section. kinder, gentler the company’s announcement was well When these stories surfaced, the received by investors. News of the FBI and the SEC quickly took notice. game venture helped propel the compa- On May 9, 1994, the two agencies ny’s stock. Media Vision shares reached began a probe into securities violations business sense. $46 in January 1994—barely 14 committed by the company. Media

GAME DEVELOPER • APRIL/MAY 1995 9 CROSSFIRE

Critical Path, to Virgin Interactive. when dealing with the reseller channel Brownell‘s humili- Unfortunately for the company, that we don’t put too much product in, Brownell’s move didn’t stave off bank- [rather] that we put the right product ruptcy. Two major creditors balked at in. We don’t try to give [resellers] eight the company’s reorganization plan, so kits when we know only two of them on July 25th, 1994, Media Vision filed are going to sell. We’re not in that ty contrasts his for Chapter 11. The clincher followed: mode anymore. I guess some of the the company admitted that its $20 mil- competitors still do that,” Brownell lion profit for 1993 wasn’t quite accu- commented. rate. In fact, there was no profit for the Brownell on the practice of chan- company‘s brazen previous year: the company actually lost nel stuffing: “That happens everywhere. $99 million. Media Vision attributed [If] you continue to throw out new the revision in numbers to unaccounted products and... you don’t deal with product returns and marketing costs, [your older products] as rapidly as you past, and he‘s cir- improperly recorded sales, and doubtful should, then you have a problem. We accounts. monitor the sell-through at the retail Since it came clean with investors level very closely, to make sure that we last summer, Media Vision has taken don’t put our products in that position. cumspect about steps to rebuild itself. In August, it And we don’t do deals with the reseller secured a $10 million credit line from channel that could put us in that posi- Trust Company of the West (TCW) to tion. We just say, ‘Buy what you think help fill $24 million in backlogged you can sell. Here’s our pricing. If this the hard lessons orders and prepare for heavy demand works for you, then great. We’ll support during the Christmas shopping season. you.’” On December 30th, Media Vision What are Brownell’s goals for emerged from Chapter 11. Its stock, Media Vision in 1995? “We haven’t the company has which just a year earlier had been trad- publicly stated our dollar goal, and we ing in the 40s, was canceled and worth- probably won’t until the end of the first less. To cover previous debts, the com- quarter. But [with respect to] my goals pany issued 20 million shares of new for the company, the first... was to get common stock, of which TCW will through bankruptcy. To get our house learned with own 43%. Two TCW officers sit on in order. And now we’re in that posi- Media Vision’s board of directors. The tion. We have developed a plan to go company, once composed of close to forward, [and] we need to execute on 500 employees, is about half that size that plan... 1995 should be a quiet year consumers and now. Media Vision has also entered for us.” into an agreement with the SEC, Brownell has stated that Media according to which the agency will rec- Vision will get back to its core market. I ommend that no enforcement action be asked him to elaborate on this plan: resellers. taken against the company, as long as “Our core technology is audio, graphics, Media Vision cooperates with the SEC and actually, video. One of the areas Vision’s stock, which had been plum- and the Dept. of Justice. that we’ve been working on over the last meting in recent weeks due to questions several years is waveguides. We have surrounding the company’s financial From the CEO: Brownell’s one of the licenses out at Stanford and 7 status, closed that day at 2 /8. One Plans To Rebuild we think we’re the farthest along, and week later, Jain and three other corpo- I recently spoke with Robert Brownell, we have a working chip at this time. rate officers resigned. and he explained Media Vision’s plans. We hope that this will translate into In the wake of Jain’s departure, His humility contrasts his company’s some products in the fourth quarter, but Robert Brownell, the vice president of brazen past, and he’s circumspect about I don’t think it will have a major impact domestic sales, took over as CEO. the hard lessons the company has until next year. We feel that’s our best Brownell inherited the unenviable posi- learned with consumers and resellers. shot, and we want to build our company tion of rebuilding the company, and “Our position is more one of con- around it. It will differentiate us in the one of his first actions was selling the trolled growth. We’re not just chasing a market.” company’s game publishing arm, which growth curve to see how much in sales It was encouraging to hear that included The Daedalus Encounter and we can ring up. We’re very cautious waveguides is an integral part of the

10 GAME DEVELOPER • APRIL/MAY 1995 CROSSFIRE

company’s plans. Waveguides is a soft- “Sounding Out the VESA Audio Stan- time, you have to continue to develop ware technology that was developed at dard” by Jon Burgstrom, June 1994). because you can’t stand still. So I really Stanford University’s Center for Com- Does Media Vision have any plans do believe it’s best left to people who puter Research in Music and Acoustics. to reenter the game development market? just deal with software.” It uses algorithms to mimic the subtle “No. I shouldn’t say never, but it’s Brownell had some interesting characteristics of musical instruments something that takes a lot of focus and insights into the multimedia upgrade and human voices. attention. And because of the fact that market, in which he sees a second “[Waveguides] is professional it’s not our core strength, and that we round of upgrade kit purchasing. This audio at consumer prices,” Brownell don’t devote 100% of our time to it, it’s coming round of purchasing will be explained. “You can develop sounds and a difficult business. It’s a ‘hits’ business. fueled by people who already bought an you can create new sounds that have The cost of developing [games] is so upgrade kit or PC containing a single or never been developed before. If you high—it requires a lot of cash and double-speed CD-ROM drive and wanted to know what a 10-foot-long investment before you get a payoff. I standard 8-bit or 16-bit sound card, trombone sounded like, you could do it. feel that it’s better left to people who and who would like to move up to a A guitar with a 15-foot-long neck. You are devoting 100% of their attention to quad-speed unit and a superior sound can actually recreate the [sound of] it. It’s a million dollars to develop a card. Brownell doesn’t see this second- vocal chords and how they interact with title—that’s before promotion costs. round market growing as explosively as the mouth cavity. When you hear a “The start we got off to in that the first round of kit sales. clarinet, you hear the [player’s] breath. business wasn’t very good. We didn’t What’s his take on Media Vision’s We think this is the next standard of have enough to sustain it. [Of] our competitor, Creative Labs? sound. We’ll be showing it to game existing titles, two or three were good, “I know that they have a lot of developers soon.” and the rest were O.K. I liked a lot of product out in the channel. Again, Brownell also indicated that due to the [games] that were coming down the we’re not chasing [Creative Labs’ pro- Media Vision’s past financial troubles, pipe, but it would have been another 12 jected] growth curve. They said they the company was no longer pushing for to 24 months before they started to were going after a billion dollar [in a VESA standard for audio cards (see show any returns. And, at the same sales] year, and that’s too risky for us right now. If we build good products, and make it easy for the customer to use them, ...do the right price points, the sales will come. And whatever [the sales] are, they are. If you do a good job and you support the customers, your sales will increase. But if you try to force it, and think that no matter what you put in the kit is going to sell at whatever price point, you’re only fool- ing yourself in the long run. It will be interesting to see how the industry shakes out. We’ll be quiet, but we’ll be here. Especially through ‘95. We gotta prove to people that we can do it. Deliver what we said we were going to deliver on.” What has Brownell heard about ex-CEO Paul Jain? “Nothing. I haven’t really talked with him since he left. He might have already started another company, but I’m not sure.” There’s hope for this company. ■

Alex Dunne is contributing editor for Game Developer magazine. Contact him via e-mail at [email protected] or through Game Developer.

12 GAME DEVELOPER • APRIL/MAY 1995 BIT BLASTS

Hair in a Can it Ain’t

Nicole Claro ne of the greatest challenges the channels with your remote until facing game today’s game you see the infotisement. Actually, you animators is not how to cre- can join the Alias Hair Club for Ani- Animation, animation, ate amazing graphics, or how mators by accessing Alias’s World to render realistic morphs, or Wide Web server at www.alias.com. even how to incorporate Perhaps you’ll meet the organization’s believable live-action video president who, I understand, is also a animation! It seems into their games. There’s a client. pursuitO far thornier than any of these, and that is...hair. For More Information Contact: Yes, hair. Whether the character Alias Research Inc. needs a Mike-Brady perm, a floppy 110 Richmond St. E. like that‘s what it‘s all toupee, or a purple mohawk, designers Toronto, Ont., Canada M5C-1P1 have always had difficulty creating lus- Tel: (416) 362-9181 cious head-topping or body-covering tresses that are true-to-life. Until now, Waves of Stucco and Velvet about. But it‘s also that is. Alias CompuHair will put an ure, hair’s important—who hasn’t end to bad hair days for three-dimen- been hair-obsessed at one time or sional characters forever. The new another (especially during adoles- product from Alias uses an advanced Scence)? But there are lots of things about upgrades, computer technique called particle sys- that have nothing to do with live char- tems, which uses the power of Silicon acters that can often make or break a Graphics workstations to render real- game. Fractal Design’s Really Cool looking hair and fur. Textures recently came on the market as design, textures wacky Users can customize the hair add-on packages for use with Fractal using options for color, transparency, Design Painter and Fractal Design length, curliness, and thickness. The Sketcher. Alias Digital OptiF/X system, the The company’s newest series and wonderful and the main component of Alias PowerAni- increases the number of paper grains mator 6.0, integrates the Alias particle and patterns available to users of system generator to create interactions Painter and Sketcher. You can create a between particles and NURBS or texture and use it as a background or polygonal-based models in the scene. link it to any natural-media tool to hairdo to end all hair- It’s this integration that lets you com- allow you to paint with textured ink or bine hair and fur with other three- paint. The series comprises Miles of dimensional modeling and rendering Tiles, Walls and Reliefs, Grains and elements like wind, gravity, and light, Weaves, and Patterns and Nature. dos (Ted Danson, eat to create waving hair, shadowed hair, Really Cool Textures costs $29.99. glowing hair, and the like. Wait, there’s more! If you want to For More Information Contact: find out even more about this, simply Fractal Design Corp. your heart out). stay up until 1:00 a.m. sullenly driving 335 Spreckels Dr.

14 GAME DEVELOPER • APRIL/MAY 1995 Aptos, Calif. 95003 platform. The product includes a com- It’s rendering-solution independent and Tel: (408) 688-5300 plete range of functions based on tradi- can be extended to support future hard- tional cel-drawing processes, such as ware- and software-based rendering Quickdraw and More audio input to scanning, pencil test, set methods. CDK Release 2 costs $1,995. lectric Image Inc.’s ElectricImage palette, special effects, and compositing. Animation System now supports By adding separate modules, you can For More Information Contact: Apple’s quickdraw three-dimen- customize SoftImage Toonz for scan- Autodesk, Inc. Esional API and metafile format. ning, ink and paint, and rendering. 2320 Marinship Way With this technology, users can view Version 3.5 includes enhanced ver- Sausalito, Calif. 94965 their animation projects in real time, as sions of many of the features available on Tel: (800) 879-4233 they are creating them. Accelerated past versions as well as new modules and three-dimensional graphics can only utilities, and several major bug fixes. Soft- Further Rendering increase the speed of the user interface, Image Toonz 3.5 features an icon-based, nd in other upgrade news, Render- the company says. simpler user interface; X-sheet, an expo- Morphics has released version 2 of Once available only for high-end sure sheet based on the ones used in tra- Reality Lab, its three-dimensional workstations, the new API and three- ditional animation; a camera stand, which AAPI. With full cross-platform inte- dimensional cards will soon be open to adjusts cels and layers to size and back- gration and compatibility, Reality Lab 2 all customers. Electric Image will release ground, that exists in the same interface provides new special effects options and a two versions—one for Power as the X-sheet; and resolution indepen- feature set that includes depth cueing, and one for Macintosh. Both versions dence, which lets users select film, video, projected shadows, and more. The func- import, render and animate objects from or HDTV output. SoftImage Toonz 3.5 tionality of version 1 is further enhanced multiplatform modeling programs and costs approximately $16,995, with various through Immediate mode, a module that both include sync sound animation, modules available at extra cost. allows low-level control over polygon deformations, and various plug-ins. lighting and rendering through direct ElectricImage Power Macintosh 2.1 and For More Information Contact: access to vertices and normals. This Macintosh 2.0 sell for $7,495. Owners Microsoft Inc. improves custom lighting and transform of ElectricImage 2.0 (Macintosh ver- 1 Microsoft Wy. effects, warping, twisting, and bending of sion) can upgrade to the Power Macin- Redmond, Wash. 98052-6399 object, and procedurally defined objects. tosh 2.1 versions for $495. Tel: (206) 882-8080 Reality Lab 2 supports Windows, DOS, System 7 and UNIX and contains specif- For More Information Contact: Ooh, Cyberspace! ic Pentium optimization, which ensures Electric Image Inc. utodesk has upgraded its Cyber- that it is even faster than version 1. 117 E. Colorado Blvd., Ste. 300 space Developer Kit (CDK). Pasadena, Calif. 91105 Release 2 is a Windows NT/32s- For More Information Contact: Tel: (818) 577-1627 Abased upgrade of the toolset for RenderMorphics Ltd. three-dimensional visualization and sim- Unit 15, The Turnmill Toonz Galore ulation. CDK Release 2 features a com- 63 Clerkenwell Rd. icrosoft has just released version prehensive code set that incorporates London EC1M 5NP U.K. 3.5 of SoftImage Toonz (the soft- 170 C++ classes and more than 1,400 Tel: 44 (0) 71 251 4411 ware formerly known as Creative functions that lets professional users, MToonz—not to be confused with such as game developers, create interac- Nicole Claro is managing editor for the rock star) for the Silicon Graphics tive, three-dimensional environments. Game Developer magazine.

GAME DEVELOPER • APRIL/MAY 1995 15 UNDER THE HOOD

Perspective Texture Mapping Part I: Foundations

Figure 1. Textured Checkerboard f there is one technical feature I’m going to address this lack of today’s high-performance three- documentation in this and the second dimensional games must have, it is part of this article. First, using nothing texture mapping. The technique of more than basic algebra and geometry, texture mapping stretches across I’ll show you an easy-to-understand almost every genre of game, from mathematical foundation, for how and role-playing games like Ultima why perspective texture mapping works. Underworld and System Shock, I’ll also provide sample code to imple- Ithrough simulators like Indy Car Racing ment the naive algorithm. In the second and Wing Commander III, to action installment, we’ll speed it up to interac- games like Doom and Descent. tive performance. Given its popularity, you’d think there would be a wealth of information Assumptions, Definitions, available on how to actually write your and Concepts own perspective texture mapper. You’d If we want to cover everything in two be wrong. articles, we’re going to have to move When I was researching this article pretty fast. To do this, I need to assume (actually, when I was trying to figure out you know a bit about three-dimensional if an article on perspective texture map- graphics. If you don’t know how object ping was even needed), I looked high space, world space, view space, and and low for intuitive descriptions and screen space interact, or you don’t know working sample code, but not much what those terms mean, you should exists. Most articles on the Internet probably pick up a book like Foley and describe affine texture mapping, and the van Dam before reading this article. few perspective texture mapping articles The term “texture mapping” I did find on x2ftp.oulu.fi, an excellent describes a whole family of techniques, game programming ftp site managed by but for these articles, we’ll define texture Jouni Miettunen, use overly complicated mapping as drawing a planar polygon as descriptions and aren’t accompanied by if a bitmap was glued to the polygon’s working code. Even old standbys, like face. This bitmap goes through the same Computer Graphics: Principles and Practice transforms (or at least looks like it does) (Addison-Wesley, 1992) by James D. as the polygon, so if we view the polygon Foley, Andries van Dam, Steven K. almost edge on, the bitmap, or texture, Feiner, and John F. Hughes (commonly will look like it’s edge on as well. Figure called Foley and van Dam, much to the 1 shows a checkerboard viewed at an chagrin of Feiner and Hughes, I’m sure) angle. You can see how the squares get and the bible of texture mapping, Digital smaller as they recede, just as you’d Image Warping (1990, IEEE Computer expect. Society) by George Wolberg, are woeful- To accomplish this mapping, we ly inadequate if you actually want to associate a texture bitmap with each write a texture mapper, especially one polygon and texture coordinates with fast enough to be compelling for games. each vertex of the polygon. In addition

16 GAME DEVELOPER • APRIL/MAY 1995 Chris Hecker to the normal (x,y,z) triplet to define a x©()= x 1 vertex in three dimensions, we specify the z texture coordinates u and v. These coor- If we view the z=d line as the one- dinates are two-dimensional coordinates dimensional equivalent of the two- Little has been writ- into the texture bitmap, and the pixels in dimensional screen plane (pretend you’re this bitmap are sometimes called texels. looking down on the plane from above, To make things easy to visualize, so you can only see it as a line), Equation our diagrams and equations will be in 1 says we can generate screen coordinates ten on perspective two dimensions—think of working in a (x´ for values of x) by dividing the unpro- slice through the three-dimensional jected object coordinates by their z val- space—but our results extend easily into ues. This is the perspective projection in three dimensions. its essence. texture mappers, an Perspective Projections Mapping Direction Most three-dimensional game graphics In three-dimensional graphics, we con- are based on perspective projections. Per- sider transforming from object to screen spective projections make distant objects coordinates moving “forward,” so Equa- invaluable feature of seem smaller than closer objects and dis- tion 1 is called a forward mapping—it tort angles so scenes look realistic. projects the source polygon forward onto The basic equation for the perspec- destination pixels. To use a forward map- tive projection uses similar triangles that ping for texturing a polygon, you step any high-perfor- share a vertex at the origin (the view- along the polygon in object space and point). If we take the point (x0,z0) (ignore project each generated point forward to a the u coordinates for the time being) and destination pixel position. Forward map- project it onto the dashed vertical z=d pings don’t work very well for texture mance game. This line in Figure 2 to give us (x0´,d), the mapping, however, because it’s hard to be equation for the relationship between sure how far to step in the source so that these two points is: the projected coordinates don’t skip or overwrite any pixels in the destination. month, Chris Hecker x© x Backward mappings, on the other 00= d z0 hand, allow us to step in screen space, processing each pixel exactly once. If we In other words, the ratio of the manipulate Equation 1 to give us a back- height of the triangle formed by ((0,0), ward mapping from x´ to x we get: fills the void with the

(x0´,d), (0,d)) to the length of its base is the same as the ratio of the height of the x = x´z (2) triangle formed by ((0,0), (x0,z0), (0,z0)) to the length of its base. If we assume d=1 This tells us we can generate values first of a two-part for the current example, and generalize of x from values of x´ if we multiply x´ by this equation to all unprojected points z. We can easily generate the desired u (x,z), we get: texture coordinate once we have x, but first we must find the correct z to feed into article on the subject.

GAME DEVELOPER • APRIL/MAY 1995 17 UNDER THE HOOD

Equation 2 (we already know x´ because Equation 5 is a linear equation with because there’s no divide it has the it’s the current pixel we want to write). respect to x´. The only problem is, it’s a potential to be a lot faster). A compari- It would be great if we could gener- linear equation of 1/z with respect to x´, son is beyond the scope of this article, ate z values directly from x´ values using a not z itself! We can use Equation 5 to but you can find affine texture mappers simple linear interpolation. We often use linearly interpolate values of 1/z and take on x2ftp.oulu.fi, which I mentioned pre- linear interpolations in graphics in the the reciprocal at each pixel to get the real viously. form of digital differential analyzers value of z. In other words, we can linearly (DDAs), and fixed and floating-point interpolate 1/z and divide x´ by 1/z to Our Story So Far interpolations, but we know linear inter- generate values of x according to Let’s take a break, sum up our results to polation is only accurate when we are Equation 2. These values of x allow us to this point, and outline a simple algorithm interpolating a linear equation. Let’s compute values of u that we can use to to perspective texture map the line seg- explore the relation between x´ and z to look up the correct color from the texture ment in Figure 2. see whether they are linear with respect bitmap to store in x´. Voila, perspective We’ve shown that 1/z and u/z are to one another, which in turn will tell us texture mapping. linear in screen space, so the algorithm if we can use linear interpolation to gen- It turns out we can compute u for texture mapping Figure 2 goes like erate z from x´. directly instead of computing x, saving a this: A linear equation is any equation of step and simplifying our lives. By defini- • Project the object vertices into screen the form: tion in Equation 1, x/z is linear in screen space, giving x´ = x/z and u´ = u/z. space (it’s actually equal to screen space, • Let z´ = 1/z at each vertex. y = AX + B (3) which is about as linear as you can get!). • Linearly interpolate u´ and z´ between

Just as x and z are linear with respect to xo´ and x1´, stepping x´ by 1 pixel each for any real values of A and B (this is each other because the object is planar loop. called the slope-intercept form, where A (or linear, in Figure 2), u and x are linear • At each pixel x´, calculate u by u´/z´, is the slope of the x,y line, and B is the y- with respect to each other for the same and use u to fetch the correct texel. intercept, or value of y when the line reason. Well, if x/z is linear in screen • Write the texel to the destination at crosses the y axis). That is, as x changes space, and x is linear with u, then u/z is x´. by a constant amount, y changes by a linear in screen space as well (you can The proofs for y and v are analogous constant amount proportional to the prove this to yourself by playing around to those for x and u, so this is all there is change in x. with Equations 1, 3, and 5). Instead of to writing a three-dimensional perspec- To find the relationship between x´ dividing x/z by 1/z to generate x coordi- tive texture mapper. and z, we first take the equation for the nates that we then use to solve for u unprojected line in object space, x = Az + coordinates, we can interpolate u/z and Interpolation Breakdown B. The actual values of the constants A divide it by 1/z to generate the u values In the simplified algorithm I’ve outlined, and B are based on the endpoints of the directly. we linearly interpolated u´ and z´ over line segment, and are irrelevant to this Affine texture mapping ignores the length of the scanline. Each linear derivation. Next, we substitute this into these results and linearly interpolates u interpolation usually involves these steps: Equation 2 to get an equation in z and and v in screen space without the divide. • Figure out the start and end values of x´, and solve for z: This results in funky warping, but for the interpolants (in Figure 2, u0´,z0´

some polygons it’s not too bad (and and u1´,z1´, respectively). Az + B = x´z B = z(x´-A) Figure 2. Perspective Projection and finally: x z = d (x0,z0,u0) B z = xA© - ()4

(x0',d,u0') Equation 4 is definitely not a linear equa- tion with respect to x´, so we can’t direct- ly compute z incrementally from values (0,0) z of x´. However all is not lost, because a (x ,z ,u ) little algebraic manipulation gives us: 1 1 1 11 A zB=-x©()B 5

18 GAME DEVELOPER • APRIL/MAY 1995 UNDER THE HO0D

• Calculate the amount each changes as ply some combination of the gradient in y. We can calculate the gradients for 1/z,

it moves from start to end (u1´-u0´ and x and the gradient in y. (If you think u/z, and v/z with respect to both x and y

z1´-z0´). about it, this also means you only need to at the top of our texture mapper and • Divide the change by the distance over interpolate the parameters down one never need to calculate them again during

which you want to interpolate (x1´-x0´) edge. Ponder that one for a while.) the rasterization of this polygon. to get each step. To show how gradients are calculat- Our new texture mapping algorithm

• Increment from the start to the end by ed, let’s use the triangle P0P1P2 in Figure looks like this: this step. 3. Each vertex has a screen space x and y • Project the object vertices into screen This is a fair amount of work, and if associated with it (x´,y´), but in addition space, giving x´, y´, u´ = u/z, v´ = v/z, we plan to rasterize polygons like the tri- there is an arbitrary parameter, c´, which and z´ = 1/z. angle shown in Figure 3, we have even could be color for Gouraud shading or • Calculate the gradients in x and y for more work to do. We need to interpolate 1/z, u/z, or v/z for perspective texture u´, v´, and z´. at least 1/z, u/z, and v/z (and possibly mapping. It is any parameter we can lin- • Linearly interpolate down each edge one or three colors), and if we first calcu- early interpolate over the surface of the and across each scanline using the gra- two-dimensional (screen space) triangle. dients. Given this triangle, let’s figure out • At each pixel, calculate u by u´/z´ and Figure 3. Calculating Gradients how the parameter c´ changes if we hold v by v´/z´, and use u and v to fetch the y constant and step in x. We will use the correct texel. P0 point P4 in our construction (P3 and P4 • Write the texel to the destination at P4 are both on the P1P2 line in Figure 3). It x´,y´.

is clear that y4´= y0´, and we can derive The only thing we’re missing is a

the other coordinates for P4 using the line consistent fill convention to make sure P1 equations: we light the correct destination pixels as we rasterize the polygon. Once we have a xx12©©- xx42©©- fill convention, we can guarantee poly- P = 3 yy12©©- yy42©©- gons will abut properly and we won’t have any skipped pixels (dropouts) or P P = (x ',y ',C ') 2 n n n n and: overwrites at the edges.

cc©©- cc©©- Conventional Wisdom late the interpolants down each edge, and 12= 42 then calculate new ones when we get to yy12©©- yy42©©- A fill convention is a set of rules that each scanline we will soon get lost in a describes how to light pixels in the screen sea of interpolants going in all sorts of Substituting y0´ for y4´ and solving for the under various edge conditions. The first directions. Luckily, there is a better way. various coordinates gives us: step towards implementing a fill conven- It just so happens that the incre- tion is defining exactly which pixels we yy©©= ments in each linear interpolant for a sin- 40 want lit when a polygon is rasterized. gle step in x or in y are constant across Figure 4 shows the raster grid of the dis- Ê xx12©©- ˆ x4© = ()yy02©©- + x 2 © the whole polygon. This is a very impor- Ë yy12©©- ¯ play, with pixel centers marked with tant and very cool result because it means black dots. we can calculate these increments—called and: We will define what’s called a top- the gradients—once and never need to left fill convention. Top-left refers to the worry about calculating interpolants Ê cc12©©- ˆ tie breaking rule used when the edge of a c4© = ()yy02©©- + c 2 © again during rasterization. In other Ë yy12©©- ¯ polygon lands exactly on a pixel center; if words, when we want to rasterize a poly- the edge is a top or a left edge, the pixel gon, we calculate the gradients in x and Next, refer to Figure 5 to compute is in the polygon, if it’s a right or a bot- in y for each parameter at the very begin- the difference in c´ (called dc´) as it tom edge, the pixel is considered out. ning, and every time we step in x or y or moves from P0 to P4 with Equation 6. You can see this convention in Figure 4. both we just add in the appropriate gra- The analog for c´ with respect to y If the red edge is shared by the blue and dients. When we get to a scanline we as we move from P0 to P3 is also shown in the yellow polygon, they will not light want to draw, we don’t need to calculate Figure 5, in Equation 7. (Notice the any of the same pixels. The horizontal linear interpolations for all of our para- denominators: dx = -dy.) red edge is the top of the yellow polygon, meters as we step across the scanline in x, The values dc´/dx and dc´/dy are so the pixels are considered members of because we already have their gradients called the gradients for the parameter; that polygon. In contrast, the horizontal with respect to x sitting around! In the dc´/dx is the gradient with respect to x red edge is a bottom edge of the blue same vein, stepping down an edge is sim- and dc´/dy is the gradient with respect to polygon, so the pixels are not lit. All

20 GAME DEVELOPER • APRIL/MAY 1995 other pixels—those not intersected on Figure,, 4. Fill Conventions pixel centers—are lit if they are “strictly in” the polygon. In other words, the pixel 0 12 345 678 910 center must be completely inside the 0 edge for the pixel to be lit. In contrast with Figure 4, real edges are infinitely 1 thin, so the pixel center is either out, intersected exactly, or in. 2 The next step is to define the fill convention mathematically. A top-left fill convention is defined by the ceiling func- 3 tion for the left and top edges, and the 4 ceiling-1 of the right and bottom edges. (The ceiling function bumps a fractional 5 number up to the next integer unless it’s already an integer, in which case the number stays the same.) We’ll be step- 6 ping in y to generate scanlines, so the equation for generating x coordinates 7 from y coordinates as we step from P to 0 8 P2 in Figure 3 is:

Ê xx20©©- ˆ x = ()yy- 00©©+ x Ë yy20©©- ¯

We apply the ceiling function to this equation to give us integer raster val- the pixel each time. Also, when reading terizer that doesn’t step on pixel centers, ues for a given y: from what are essentially random places where lines in the texture that should be in each pixel it’s possible to generate tex- straight come out with little notches and ÈÊ xx20©©- ˆ ˘ ture coordinates outside the texture pimples. xint = ()yy- 00©©+ x ÎÍË yy20©©- ¯ ˚˙ bitmap (which could crash our program). Figure 6 shows a close-up of a group of pixels. To start rasterizing, we If our starting coordinates are real Find Your Center must first step our edge to the point A. numbers instead of integers, we need to Given that we want to sample the texture This involves an x and y prestep for our apply our convention to the y coordinate from the exact pixel center, we need to interpolants, marked with dotted lines. as well to generate the initial y value: make sure our interpolants are Now, we can precalculate each parame- prestepped on each scanline by the differ- ter’s step in y and in x for a single scan- ence between the real edge and x . If we line step in the screen using the gradients yy0 int©©= []0 int do this correctly, our texture mapper will we calculated beforehand, so each time never read outside the texture (assuming we move from one scan to the next, we On a number of scanlines in Figure the texture coordinates are valid in the just add each step to its interpolant to 4, the real edge—the line on which we’re first place, of course), and our textures find the new value. When it’s time to interpolating our parameters—differs will not swim as our polygon moves draw a scanline, we must step to the first from the starting pixel center by some around the screen. Also, we won’t get the pixel center. Figure 6 shows this step as a small amount. Pixels in the display are “hairy texture” artifacts you see in a ras- dotted line at each scanline. not points, they’re actually boxes with an area around the pixel center (the pixel Figure 5. Equations 6 and 7 center is the integer coordinate, and the box extends 0.5 pixels to each side), and cc©©- (cc ©----- ©)( y © y ©) ( cc © ©)( yy © ©) dc© = 40= 12 02 0212 ()6 when stepping from pixel to pixel we dx xx40©©- (xx1202 ©----- ©)( yy © ©) ( xx 0212 © ©)( yy © ©) want to make sure we step from one pixel center to the next. If we don’t step on pixel centers, our textures will appear to cc©©- (cc ©----- ©)( x © x ©) ( cc © ©)( xx © ©) dc© = 30= 12 0 2 02 1 2 ()7 swim as our polygon rotates because we dy yy30©©- (xxyy0212 ©----- ©)( © ©) ( xxyy 1202 © ©)( © ©) aren’t sampling from the same place in

GAME DEVELOPER • APRIL/MAY 1995 21 UNDER THE HOOD

All this prestepping probably sounds Figure 6. Pixel Centers expensive, but there is a way to do it that 012 requires no extra multiplies per scanline. We’ll discuss this in more detail next month. A 0 Summary and Random Notes This article is too long already, but there’s still plenty we haven’t discussed. First, we didn’t talk about all the B special cases where linearly interpolating 1 the texture coordinates actually is correct, like walls and floors. A close examination of the math above will show you why this is true (hint: look at the gradients for the 1/z term). Games like Doom use this to C speed up their texture mappers at the 2 expense of not allowing arbitrarily orient- ed polygons. There’s lots of information covering these techniques on the Internet. We also didn’t discuss antialiasing or homogeneous coordinate systems. Digital Image Warping is a great resource Listing 1. Perspective Texture Mapper for antialiasing and image resampling, while Foley and van Dam cover homoge- #include #include neous coordinates. Even considering what we missed, struct POINT3D { float X, Y, Z; we certainly covered a lot of material in a float U, V; small space, and I encourage you to }; reread this article with a piece of paper in void TextureMapTriangle( BITMAPINFO const *pDestInfo, hand and try to prove the various results BYTE *pDestBits, POINT3D const *pVertices, for yourself. BITMAPINFO const *pTextureInfo, BYTE *pTextureBits ); The sample code included with this article implements the perspective texture /******** structures, inlines, and function declarations **********/ mapping algorithm. It is a high quality struct gradients { implementation with one small problem: gradients( POINT3D const *pVertices ); it’s a bit slow, doing a divide and two mul- float aOneOverZ[3]; // 1/z for each vertex float aUOverZ[3]; // u/z for each vertex tiplies per pixel. In the next column I’ll float aVOverZ[3]; // v/z for each vertex show how to optimize this code, which float dOneOverZdX, dOneOverZdY; // d(1/z)/dX, d(1/z)/dY float dUOverZdX, dUOverZdY; // d(u/z)/dX, d(u/z)/dY will give you a production quality perspec- float dVOverZdX, dVOverZdY; // d(v/z)/dX, d(v/z)/dY tive texture mapper you can just plop right }; ■ in your game engine. struct edge { edge(gradients const &Gradients, POINT3D const *pVertices, int Top, int Bottom ); inline int Step( void );

float X, XStep; // fractional x and dX/dY int Y, Height; // current y and vert count Chris Hecker wishes he had a Ph.D. in float OneOverZ, OneOverZStep; // 1/z and step float UOverZ, UOverZStep; // u/z and step mathematics so he didn’t have to struggle float VOverZ, VOverZStep; // v/z and step with the derivation of the equation for the }; area of a triangle whenever he wanted to use inline int edge::Step( void ) { it. In the meantime, he can be reached at X += XStep; Y++; Height—; [email protected] or through Game Devel- UOverZ += UOverZStep; VOverZ += VOverZStep; oper magazine.

22 GAME DEVELOPER • APRIL/MAY 1995 Listing 1. Perspective Texture Mapper (Continued on p. 25)

pLeft,pRight,pTextureInfo,pTextureBits); OneOverZ += OneOverZStep; TopToMiddle.Step(); TopToBottom.Step(); return Height; } }

Height = MiddleToBottom.Height; void DrawScanLine( BITMAPINFO const *pDestInfo, BYTE *pDestBits, gradients const &Gradients, if(MiddleIsLeft) { edge *pLeft, edge *pRight, pLeft = &MiddleToBottom; pRight = &TopToBottom; BITMAPINFO const *pTextureInfo, BYTE *pTextureBits ); } else { pLeft = &TopToBottom; pRight = &MiddleToBottom; /******** TextureMapTriangle **********/ } void TextureMapTriangle( BITMAPINFO const *pDestInfo, while(Height—) { BYTE *pDestBits, POINT3D const *pVertices, DrawScanLine(pDestInfo,pDestBits,Gradients, BITMAPINFO const *pTextureInfo, pLeft,pRight,pTextureInfo,pTextureBits); BYTE *pTextureBits ) MiddleToBottom.Step(); TopToBottom.Step(); { } int Top, Middle, Bottom; } int MiddleCompare, BottomCompare; float Y0 = pVertices[0].Y; /********** gradients constructor **********/ float Y1 = pVertices[1].Y; float Y2 = pVertices[2].Y; gradients::gradients( POINT3D const *pVertices ) { // sort vertices in y int Counter; if(Y0 < Y1) { if(Y2 < Y0) { float OneOverdX = 1 /(((pVertices[1].X - pVertices[2].X) * Top = 2; Middle = 0; Bottom = 1; (pVertices[0].Y - pVertices[2].Y)) - MiddleCompare = 0; BottomCompare = 1; ((pVertices[0].X - pVertices[2].X) * } else { (pVertices[1].Y - pVertices[2].Y))); Top = 0; if(Y1 < Y2) { float OneOverdY = -OneOverdX; Middle = 1; Bottom = 2; MiddleCompare = 1; BottomCompare = 2; for(Counter = 0;Counter < 3;Counter++) { } else { float const OneOverZ = 1/pVertices[Counter].Z; Middle = 2; Bottom = 1; aOneOverZ[Counter] = OneOverZ; MiddleCompare = 2; BottomCompare = 1; aUOverZ[Counter] = pVertices[Counter].U * OneOverZ; } aVOverZ[Counter] = pVertices[Counter].V * OneOverZ; } } } else { if(Y2 < Y1) { dOneOverZdX = OneOverdX * (((aOneOverZ[1] - aOneOverZ[2]) * Top = 2; Middle = 1; Bottom = 0; (pVertices[0].Y - pVertices[2].Y)) - MiddleCompare = 1; BottomCompare = 0; ((aOneOverZ[0] - aOneOverZ[2]) * } else { (pVertices[1].Y - pVertices[2].Y))); Top = 1; dOneOverZdY = OneOverdY * (((aOneOverZ[1] - aOneOverZ[2]) * if(Y0 < Y2) { (pVertices[0].X - pVertices[2].X)) - Middle = 0; Bottom = 2; ((aOneOverZ[0] - aOneOverZ[2]) * MiddleCompare = 3; BottomCompare = 2; (pVertices[1].X - pVertices[2].X))); } else { Middle = 2; Bottom = 0; dUOverZdX = OneOverdX * (((aUOverZ[1] - aUOverZ[2]) * MiddleCompare = 2; BottomCompare = 3; (pVertices[0].Y - pVertices[2].Y)) - } ((aUOverZ[0] - aUOverZ[2]) * } (pVertices[1].Y - pVertices[2].Y))); } dUOverZdY = OneOverdY * (((aUOverZ[1] - aUOverZ[2]) * (pVertices[0].X - pVertices[2].X)) - gradients Gradients(pVertices); ((aUOverZ[0] - aUOverZ[2]) * edge TopToBottom(Gradients,pVertices,Top,Bottom); (pVertices[1].X - pVertices[2].X))); edge TopToMiddle(Gradients,pVertices,Top,Middle); edge MiddleToBottom(Gradients,pVertices,Middle,Bottom); dVOverZdX = OneOverdX * (((aVOverZ[1] - aVOverZ[2]) * edge *pLeft, *pRight; (pVertices[0].Y - pVertices[2].Y)) - int MiddleIsLeft; ((aVOverZ[0] - aVOverZ[2]) * (pVertices[1].Y - pVertices[2].Y))); // the triangle is clockwise, so dVOverZdY = OneOverdY * (((aVOverZ[1] - aVOverZ[2]) * // if bottom > middle then middle is right (pVertices[0].X - pVertices[2].X)) - if(BottomCompare > MiddleCompare) { ((aVOverZ[0] - aVOverZ[2]) * MiddleIsLeft = 0; (pVertices[1].X - pVertices[2].X))); pLeft = &TopToBottom; pRight = &TopToMiddle; } } else { MiddleIsLeft = 1; /********** edge constructor ***********/ pLeft = &TopToMiddle; pRight = &TopToBottom; } edge::edge( gradients const &Gradients, POINT3D const *pVertices, int Top, int Bottom ) int Height = TopToMiddle.Height; { Y = ceil(pVertices[Top].Y); while(Height—) { int YEnd = ceil(pVertices[Bottom].Y); DrawScanLine(pDestInfo,pDestBits,Gradients,

GAME DEVELOPER • APRIL/MAY 1995 23 UNDER THE HOOD

Listing 1. Continued from p. 22

Height = YEnd - Y;

float YPrestep = Y - pVertices[Top].Y;

float RealHeight = pVertices[Bottom].Y - pVertices[Top].Y; float RealWidth = pVertices[Bottom].X - pVertices[Top].X;

X = ((RealWidth * YPrestep)/RealHeight) + pVertices[Top].X; XStep = RealWidth/RealHeight; float XPrestep = X - pVertices[Top].X;

OneOverZ = Gradients.aOneOverZ[Top] + YPrestep * Gradients.dOneOverZdY + XPrestep * Gradients.dOneOverZdX; OneOverZStep = XStep * Gradients.dOneOverZdX + Gradients.dOneOverZdY;

UOverZ = Gradients.aUOverZ[Top] + YPrestep * Gradients.dUOverZdY + XPrestep * Gradients.dUOverZdX; UOverZStep = XStep * Gradients.dUOverZdX + Gradients.dUOverZdY;

VOverZ = Gradients.aVOverZ[Top] + YPrestep * Gradients.dVOverZdY + XPrestep * Gradients.dVOverZdX; VOverZStep = XStep * Gradients.dVOverZdX + Gradients.dVOverZdY; }

/********** DrawScanLine ************/ void DrawScanLine( BITMAPINFO const *pDestInfo, BYTE *pDestBits, gradients const &Gradients, edge *pLeft, edge *pRight, BITMAPINFO const *pTextureInfo, BYTE *pTextureBits ) { // we assume dest and texture are top-down

int DestWidthBytes = (pDestInfo->bmiHeader.biWidth + 3) & ~3; int TextureWidthBytes = (pTextureInfo->bmiHeader.biWidth + 3) & ~3;

int XStart = ceil(pLeft->X); float XPrestep = XStart - pLeft->X;

pDestBits += pLeft->Y * DestWidthBytes + XStart;

int Width = ceil(pRight->X) - XStart;

float OneOverZ = pLeft->OneOverZ + XPrestep * Gradients.dOneOverZdX; float UOverZ = pLeft->UOverZ + XPrestep * Gradients.dUOverZdX; float VOverZ = pLeft->VOverZ + XPrestep * Gradients.dVOverZdX;

if(Width > 0) { while(Width—) { float Z = 1/OneOverZ; int U = UOverZ * Z; int V = VOverZ * Z;

*(pDestBits++) = *(pTextureBits + U + (V * TextureWidthBytes));

OneOverZ += Gradients.dOneOverZdX; UOverZ += Gradients.dUOverZdX; VOverZ += Gradients.dVOverZdX; } } }

GAME DEVELOPER • APRIL/MAY 1995 25 DIGITIZED SOUND

Programming Digitized Sound On the Sound Blaster

Figure 1. Comparing Analog and Digitized Waves poorly written documentation on the Sound Blaster. In this article, we’ll give you the information you need to start developing your own digitized sound AAcode.

Theory of Digitized Sound As with most areas of computer program- t t ming, it is good to know some general background theory. It’s often the case that the “easy” pitfalls are far from obvious. With sound, there are a number of possi- Continuous Discrete ble problems that will cause audible glitches. When digitized sounds are produced n the early days of PC sound, we had from an analog source, signals travel the PC speaker and its lesser-known down an interconnect cable, go through a sidekick, the Programmable Interval preamplifier, and are eventually processed Timer (PIT). You could program by an analog to digital converter. We the frequency of this hardware timer, mention this because each step will have and hook the timer up to the speak- an effect on sound quality and overall vol- er. By changing this frequency, you ume. could produce a surprising variety of Figure 1 shows the difference Isound effects and music. between continuous (analog) and discrete There was only one problem— (digitized) waves. Unlike analog waves, gamers and programmers hated it. So the digitized sounds are quantized, meaning world moved onto generation two: the that the amplitude at each point can have AdLib FM Synthesizer. You could pro- only one of a finite number of values. In gram it to produce decent music and even addition, the sounds are discretely sam- certain sound effects. pled; that is, the value is sampled periodi- There was still a problem. The cally. Both facts raise important consider- sound effects stunk. ations. We’ll discuss the amplitude prob- Along came the Sound Blaster. It lem first, then the time problem. combined a digital-to-analog converter The range of values for each sample (DAC) with an FM synthesizer. Now, is finite. In a typical game playback sys- game programmers had access to decent tem, this is 8 bits, or -128 to +127. The music and decent sound effects. Finally. softest sound that can be represented is There was much rejoicing. Until the ±1, and any sound softer than this thresh- question arose as to how to program the old will be lost at 0. The loudest sound is thing. about ±127. Any sound louder than this is In developing DiamondWare’s clipped, producing a harsh and nasty Sound ToolKit, we discovered scarce and noise.

26 GAME DEVELOPER • APRIL/MAY 1995 Keith Weiner When you’re mixing two or more is beyond the scope of this article, but we sounds together, this clipping limit mention it here for completeness. Quality Erik Lorenzen applies to the total mix. Thus, you want sound processing software has the ability to produce your sounds at low volume to compress dynamic range. It‘s the low-down levels so you can mix several of them A digitized sound is considered a without problems. If you are stuck with discretely sampled waveform because it is preproduced sounds, there are two ways not contiguous in the time domain. In to cut their dynamic range. The first is other words, you’re sampling the wave- straightforward—you divide each sample form at T=1 and T=2 but there’s no by a constant. This is often implemented information for T=1.5. When it’s played dirty details of as a shift-right operation. It’s fast and back, there’s obviously sound at every easy, but if you divide too much you will moment—even in between the sample lose the softer parts of your sounds. points, which is the crux of the problem. The other method is to dynamically To understand this dilemma, let’s compress your sounds. Basically, this will look at analog waveforms. It turns out making your game soften the louder parts and raise the softer that every possible analog waveform can parts. This is what pop radio stations do. be represented by the sum of a finite After this process, the entire sound is number of pure sine waves. equally loud. The implementation of this The plot of a sound on an oscillo- sing. And talk. And Figure 2. Wave and Spectrum/Pulse and Spectrum

A growl. And make

tf

(a) (b) Continuous funny little beeping

A sounds...it‘s... tf (c) (d) Sound Blaster!!!

GAME DEVELOPER • APRIL/MAY 1995 27 DIGITIZED SOUND

scope is a time-domain plot, as shown in Nyquist rate. In Figure 3a, we see the your sample. This lends a nasty metallic Figure 2a. That is, while the Y-axis repre- original analog wave and its spectrum in sound. The solution is to filter the output sents amplitude, the X-axis represents the frequency domain. If this signal is of the DAC in analog, eliminating all fre- time. It’s possible to transform a wave into sampled above the Nyquist rate, as shown quencies above half the sampling rate. the frequency-domain. A plot after such a in Figure 3b, it can be correctly recon- transformation, shown in Figure 2b, uses structed. If the signal is sampled below the The Sound Blaster Family the X-axis to represent frequencies; each Nyquist rate, as shown in Figure 3c, there We’ve seen 10 models of Sound Blaster point farther to the right would be a high- is not enough information to properly from Creative Labs and dozens of clones er frequency. You could read the graph to reconstruct the wave and aliasing occurs. from third parties. Fortunately, they all determine, for example, how loud the How can we capture a sine wave with share the common architecture first pre- 1KHz component is. The highest fre- only two points per cycle? We know in sented in the Sound Blaster 1.5. By far, quency sine wave in this series is no higher advance that it is a sine wave. There’s only the Sound Blaster 16, Sound Blaster than the highest frequency in the original one possible sine wave that can be formu- PRO2, and Sound Blaster 2.1 sold the wave. Figure 2c illustrates a square-wave lated, given two points during each cycle. most units, and they’re still selling today. pulse, comprising an infinite frequency of Any waveform can be broken down into This article will focus on the Sound components, as you can see in its frequen- sine waves, so we have a way of discretely Blaster 1.5, because it’s the lowest com- cy-domain plot, shown in Figure 2d. capturing (digitizing) analog sounds. mon denominator. The higher models all Now, let’s get back to digital sound. There’s one last issue we must support the Sound Blaster 1.5’s modes. It turns out that to “capture” a given fre- cover—playback. Because the waves are quency, you need to sample the wave at a discretely sampled and are represented by Detecting the Sound Blaster rate at least twice as high as that frequen- few points, they’re going to look quite You can find the Sound Blaster by parsing cy. For example, if you had a sound at square, as shown in Figure 4. Square look- the BLASTER environment variable. It’s the 1KHz, you should sample it at 2KHz or ing digital signals connote “high frequen- easiest method, and it’s recommended by higher. This is known as the Nyquist rate. cy.” If you play them back as is, they’re Creative Labs and other manufacturers, Figure 3 demonstrates the effects of going to have lots of noise—in fact, you’ll especially because it can’t crash the user’s sampling a wave above and below the hear a complete harmonic overtone of machine. This is how we’ll do it here. The BLASTER environment variable comprises several sections. A typical Figure 3. Sampling Rates and Aliasing BLASTER variable might look like this:

BLASTER=A220 I5 D1 H5 P330 M250 T6 A where: • A is the base port address (here, it’s 220h). Values may be 210h to 280h. 12t 1234 f • I is the IRQ (interrupt request) level. (a) Values may be 2, 3, 5, 7, or 10. • D is the 8-bit DMA channel. Values may be 0, 1, or 3. A • H, if present, is the 16-bit DMA chan- fsamp nel. Values may be 5, 6, or 7. • P, if present, is the port for MPU401, either 300h or 330h. 12f f 1234 • T is the type of Sound Blaster card. (b) You can program the Sound Blaster Ny in 14 easy steps: • Reset the DSP (digital signal proces- A Aliased Original sor) and put it into a known state. f • Set up your interrupt service routine samp (ISR). • Enable the IRQ the Sound Blaster 12f f 123 4 card is using. (c) • Program the DAC speaker. N y • Program the DMA controller for a single cycle transfer.

28 GAME DEVELOPER • APRIL/MAY 1995 DIGITIZED SOUND

• Program the playback rate (time con- Figure 4. Comparing a Digitized Wave to the Original Analog Wave stant). • Program the DSP output/input for AA single-cycle transfer. Transfer begins immediately after step 7. At this point, you can go draw some graphics, read a disk, and get some t t coffee. When the buffer is done, the Sound Blaster will generate an interrupt. This will transfer control to the ISR. Next: Original wave Digitized wave • Acknowledge the DSP. • Send the programmable interrupt con- Blaster card is present. // wait for the MSB to be clear troller (PIC) an end of interrupt • Read sb_READ_DATA. If the return value } (EOI). is AAh, a Sound Blaster card is present. outp(baseport + sb_WRITE_COMMAND, • Program the Sound Blaster to play • If the return value is not AAh, repeat (int)value); another buffer or set a flag to show Steps 4 to 6 until the count runs out, } that we are done playing. or a Sound Blaster card is found. After we have finished all data trans- Handling DSP Interrupts fers, we need to: Reading and Writing The DSP will generate an interrupt when • Disable the DAC speaker. To read data from the DSP, we must ever it’s done recording or playing a • Disable the IRQ. read from sb_READ_STATUS until the msb is DMA buffer. To keep the system from • Unhook the ISR. set. Then, read from sb_READ_DATA: crashing and the Sound Blaster playing, • Reset the Sound Blaster DSP, leaving we need to set up an ISR. Each interrupt it in a good state, ready to work with unsigned sb_ReadDSP(unsigned baseport) must be acknowledged by reading other applications. while(!(0x80 & inp(baseport + sb_ACKIRQ. This tells the DSP that you sb_READ_STATUS))); //waiting for the have received the interrupt, and it can Detect and Reset //MSB to be set stop pulling the line. Before we assume that the presence of the return((unsigned)inp(baseport + BLASTER variable means we have a Sound sb_READ_DATA)); Using DSP commands Blaster in the system, we can check to see } A DSP revision of 1.xx accepts 20 com- if a DSP really does exist at the specified mands, as shown in Table 2. We will only port, shown in Table 1, and attempt to To write to the DSP, read from need to use five commands to get up and send it a reset by doing the following: sb_COMMAND_STATUS until the msb is reset. running. To simplify the following dis- • Write a 1 to the sb_RESET port. Then, write the desired command (or cussion, we will use the example functions • Wait three microseconds (msec). command data) to sb_WRITE_COMMAND: sb_ReadDSP and sb_WriteDSP. • Write a 0 to sb_RESET. The DAC speaker controls what we • Read sb_READ_STATUS (up to 65,535 void sb_WriteDSP(unsigned baseport, hear (and what the Sound Blaster hears). times), waiting for the msb (most sig- unsigned value) { With the speaker on, we can hear the nificant bit) to be set. while(0x80 & inp digitized playback, but the Sound Blaster • If the msb never gets set, no Sound (baseport +sb_WRITE_STATUS)); can’t hear us (record), and vice versa. To turn on the speaker, send sb_DAC- Table 1. Sound Blaster DSP Ports SPKRON to the DSP and wait 112 msec for the DSP to complete the operation: Port Number Write Read During IRQ sb_WriteDSP(baseport, sb_DACSPKRON); 2X6h sb_RESET None Normal 2XAh None sb_READ_DATA Normal Turning the speaker off is similar; 2XCh sb_WRITE_COMMAND sb_WRITE_STATUS Normal send sb_DACSPKROFF to the DSP and wait 2XEh None sb_READ_STATUS sb_ACKIRQ (read-only) even longer (220 msec)—no one said this hardware was fast:

X denotes base address. For base address of 220h, the ports are 226h, 22Ah, 22Ch, and sb_WriteDSP(baseport, sb_DACSPKROFF); 22Eh. The sb_SETTIMECONST command sets

30 GAME DEVELOPER • APRIL/MAY 1995 Table 2. DSP.1 xx Commands current stack • The CPU jumps to the address speci- Number Description fied in the vector table for this IRQ. To respond to an IRQ (for ISR’s 10h Set polled output mode and PCM (uncompressed) samples. only): 14h Set DMA output mode and PCM samples. • Tell the hardware (the Sound Blaster 74h Set DMA output mode and 8- to 4-bit ADPCM samples. DSP) to stop pulling the interrupt line. 75h Set DMA output mode and 8- to 4-bit ADPCM samples (with reference byte). • Send an EOI to the PIC. 76h Set DMA output mode and 8- to 3-bit ADPCM samples. • Set a global variable—a flag—for main 77h Set DMA output mode and 8- to 3-bit ADPCM samples program loop (this step is optional). (with reference byte). • Prepare the next sound buffer. 16h Set DMA output mode and 8- to 2-bit ADPCM samples. • Return from interrupt (IRET instruc- 17h Set DMA output mode and 8- to 2-bit ADPCM samples tion). (with reference byte). There’s a simple INT 21 (DOS) call 38h Set polled output mode and MIDI data. to hook the interrupt vector, which is 20h Set polled input ode and PCM (uncompressed) samples. even easier in C. We also need to enable 24h Set DMA input mode and PCM (uncompressed) samples. our interrupt in the PIC itself. To do this, 30h Set polled input mode and MIDI data. read the IMR, reset the bit corresponding 31h Set interrupt input mode and MIDI data. D0h Pause DMA. to the IRQ level to which the Sound D4h Resume DMA. Blaster DSP is set, and write the IMR: 40h Set time constant 80h Pause DMA for a specified duration. #define dig_IMRPORT 0x21 E1h Get DSP version. temp = inp(dig_IMRPORT); //Read the IMR D1h Enable DAC speaker. temp &= dig_onmask[irqlevel]; D3h Disable DAC speaker. //Enableour channel outp(dig_IMRPORT, temp); //Write the IMR how many samples per second the DSP Interrupt Programming Programming the will record or playback, but it doesn’t take No discussion of Sound Blaster DSP pro- DMA Controller a sampling rate directly. We must convert gramming would be complete without The 8237A high-performance program- from Hz to the Sound Blaster time con- mention of the 8259A PIC. Integrally mable direct memory access (DMA) con- stant. The time constant is always an related is the 80x86 processor’s interrupt troller provides a way to transfer data unsigned byte: mechanism, including the vector table. between memory and the I/O bus without Let’s go over the steps involved in an IRQ using CPU. If you program it properly, it tc = 256 - (1000000 / (num_channels * and its handling. allows for easy and nearly overhead-free sampling_rate)); The Sound Blaster must go through data transfers. Make a mistake, however, sb_WriteDSP(baseport, sb_SETTIMECONST); nine steps to build an IRQ: and you’ve as good as sent a garbage truck sb_WriteDSP(baseport, rate); • The Sound Blaster DSP signals the to dump a pile of trash in memory! PIC that it wants to interrupt the An AT-class machine has two To play a sound, send the DSP one CPU. DMA controllers and eight DMA chan- of the output sound commands. We’ll use • The PIC checks the interrupt mask nels. The DMA controllers have 44 I/O sb_PLAY8BITMONO. Follow this command register (IMR) to see if this is cool. ports and four modes of operation. with 2 bytes representing the size of the • If so, the PIC checks to see if any high- We’ll only discuss channels 0, 1, and buffer. The buffer can be between 1 and er-priority IRQ’s are being serviced. 3 (2 is used by the floppy controller). 65,536 bytes. No one would want to pro- • If so, it waits until they send an end of These are the 8-bit channels. Channels 4 gram the Sound Blaster to transfer 0 interrupt (EOI) to the PIC. to 7 are 16-bit channels and aren’t used bytes, so 0 means 1 byte, and 65,535 • If not, the PIC sends a signal to the by 8-bit Sound Blasters. means 65,536 bytes: CPU over a dedicated line. We’re interested in single-cycle • If the interrupt flag is set, the CPU DMA mode, which means one byte is lowbyte = (unsigned char)(buffsize - 1); replies with an interrupt acknowledge transferred by the DMA controller for highbyte = (unsigned char)((buffsize - 1) (INTA). each data request (DREQ) it receives >> 8)); • The PIC then sends an IRQ and the from the Sound Blaster DSP. sb_WriteDSP(baseport, sb_PLAY8BITMONO); IRQ level. There are nine steps to program- sb_WriteDSP(baseport, lowbyte); • The CPU pushes the flags, CS, and ming a DMA controller. Steps 2 through sb_WriteDSP(baseport, highbyte); IP registers—in that order—on the 8 employ either shared registers—used for

GAME DEVELOPER • APRIL/MAY 1995 31 DIGITIZED SOUND

all channels—or channel specific registers: Hardware Book (Addison-Wesley, 1993), • Disable interrupts. by Hans-Peter Messmer. • Disable our DMA channel (shared register). The Code • Reset the flip-flop (shared register). The code that accompanies this article • Set our channel’s mode (channel-spe- compiles with Microsoft C/C++ 7, Bor- cific register). land C/C++ 3.1 and 4.0. It should port • Program the address register (channel- easily to other DOS C environments. specific register). We used the large memory model when • Program the page register (channel- we compiled it. We tested it with a specific register). Sound Blaster 1.5, 2.1, Pro 2, 16, and • Program the count register with one AWE32. The code is available on Com- less than the actual transfer count puServe in the SDFORUM in the (channel-specific register). GDMag Library. ■ • Enable the DMA channel (shared register). Keith Weiner and Erik Lorenzen have • Enable interrupts developed a sound toolkit for DOS games, The DMA controller works with called DiamondWare’s Sound ToolKit physical addresses, not with segment:off- (available from MVP Software). Contact set addresses, not with selectors, and so them via e-mail at [email protected] or on. In real mode, it’s easy to translate [email protected]. from segment:offset to a physical address (protected-mode selectors can be trans- lated as well). The DMA controller THE GLOSSARY works with a page number, which is liter- ally the physical address divided by orking with the Sound Blaster 65,536. A DMA buffer cannot cross such can require a graduate degree in the language of acronyms. a physical page address; you must verify Hence, we provide here a that your buffer meets this criterion! breakdown of the abbrevia- Within the physical page, the DMA W tions used throughout this article. controller increments an offset. Code to translate from segment:offset to physical EOI End of interrupt page and offset is: DAC Digital-to-analog converter off = (*((unsigned _far *)&(sound))); seg = (*((unsigned _far *)&(sound) + 1)); DMA Direct memory seg <<= 4; access padd = seg + off; // calc physical DREQ Data request address page = padd >> 16; // calc page number DSP Digital signal processor Don’t be put off by our method of IMR Interrupt obtaining the segment and offset of a mask register pointer. This may seem complex, but INTA Interrupt we’re simply taking a pointer to sound; acknowledge the first word this points to is the offset, and the second is the segment. IRQ Interrupt request Explanations of the workings of the ISR Interrupt service DMA controller tend to be very lengthy. routine Fortunately, the DMA controller is very PIC Programmable well documented. We refer you to two interrupt controller books that provide in-depth explanations for further reading: Developer Kit for PIT Programmable Sound Blaster Series, 2nd Ed. (Creative interval timer Labs, 1993); and The Indispensable PC

32 GAME DEVELOPER • APRIL/MAY 1995 SUPERCHARGE YOUR SPRITES

Supercharge Your Sprites

s we continue on our quest for transparent color are left alone, and the the fastest graphics perfor- background shows through. mance possible, we are going Because irregular shapes are so dif- to focus on drawing sprites. ficult to code for, you would usually Just what is a sprite? A sprite choose to store a sprite in memory as a is usually defined as a graphi- rectangular array of pixels. A normal cal image that moves inde- sprite drawing routine then goes pendently on the screen. through the following steps. First, it CharactersA in video games are sprites. computes the screen address that corre- So are bullets, explosions—even the cur- sponds to the upper left pixel in the sor is a type of sprite. sprite’s array, even if the pixel is trans- Unlike tiles or text, sprites often parent. Then it scans the sprite’s data come in irregular shapes and sizes. from left to right and top to bottom, These varied shapes often make it diffi- checking each pixel to see if it is trans- cult to optimize a general-purpose parent. If it is not, the program draws drawing routine. To achieve superior that pixel to the screen at an offset cor- performance when drawing sprites, we responding to that pixel’s position in the are going to examine a technique called sprite’s data array. “compiled sprites,” sometimes referred This method works very well and to as “compiled bitmaps.” you can optimize it with assembly lan- guage. But it is not as fast as routines Normal Sprites that draw solid blocks or tiles, like the To start, we need to understand how ones I presented in “Faster Image sprites are usually implemented. Today, Drawing” (Feb./Mar. 1995). And the most sprites are drawn by a programmer worst part is that it is slower than these or artist using a paint program or some routines despite the fact that fewer pix- form of sprite editor, which itself is a els are actually drawn. This wouldn’t be custom paint program. The program a big deal if we didn’t use sprites very draws the image in a rectangular work much, but for many action-oriented area, using a palette of colors. games, we use them extensively. When you begin a new sprite, the Imagine you are writing a Super work area is filled with a color, usually Galaxian-style game. The player’s ship, black, white, or grey, that you’ve desig- shields, and every bullet, missile, explo- nated as a “transparent” or background sion, and enemy ship is an irregularly color. The actual color doesn’t mat- shaped sprite. You will have to redraw ter—it’s simply a value that the pro- every object for each frame of gameplay. grammer decides will be used to indi- If your sprite drawing routines aren’t cate transparency. very good, the game is going to bog When the sprite is drawn by the down when the action gets fast and program, only the portions of the image furious. Now it becomes obvious why block that are not the transparent color you want the fastest sprites possible. are actually drawn. The areas with the Performance is lost when you draw

34 GAME DEVELOPER • APRIL/MAY 1995 Matt Pritchard irregularly shaped sprites not because But what if the computer could the code is inefficient, but because for automatically generate code that draws every pixel, a decision must be made each sprite, knowing exactly what to whether or not it should be actually draw and what to eliminate for each Sprites come in all drawn. In sprite-drawing routines, it image? All the comparisons, branching, turns out that not drawing a pixel usual- and other decision-making code that ly imposes a big performance hit on would normally be executed every time normally tight assembly language code. the sprite was drawn or moved would be shapes, sizes, and This happens because the CPU has to eliminated. The processing time saved jump, flush its prefetch queue, and for every sprite in every frame drawn reload it. The code could be reversed, would add up quickly. That is the basic but the performance would suffer every premise behind compiled sprites. time a pixel is drawn. You must take colors. This variance one of two paths because there is no way Compiled Sprites around the fact that a decision must be There are two main categories of com- made. Or is there? piled sprites. One is what I call “data compiled,” which converts the sprite often presents per- Looking Back, image into a stream of data that is fed to Looking Forward a special routine. All the calculations, It the earliest days of 8-bit computers, a comparisons, and decisions are made by game would often have dedicated code the compiling routine during the com- formance challenges to draw individual sprites. Some systems piling process and encoded into the data even had hardware support for sprite stream. graphics. (Here’s a historical trivia fact: The drawing routine itself is a sim- The Atari 2600 game system only had ple state machine that reads each chunk for developers. Here 128 bytes of RAM, so each line of each of data and processes it in exactly the sprite had to be drawn with custom code same way. The inner loops are unrolled in ROM.) and contain no comparisons or branches Programmers would hand-code to slow things down. The data stream are some tips to help routines to draw each line, box, and provides all the information needed. pixel that made up a sprite. The advan- This technique provides a significant tage was that only the pixels that needed performance increase and is often used to be drawn were coded. The biggest with larger or compressed graphic drawback was that it was a slow process, images. you achieve superior requiring the programmer to change The second category consists of code every time one single bit in a sprite what I call “code compiled” sprites. The was changed, possibly introducing bugs program generates actual machine lan- each time. As graphics got bigger and guage instructions that draw the specific performance when changed more frequently during devel- image on the screen. There are no deci- opment, this method proved less practi- sion or control instructions, only direct cal and general purpose routines took writes to video memory. This method over. provides additional performance gains drawing sprites.

GAME DEVELOPER • APRIL/MAY 1995 35 SUPERCHARGE YOUR SPRITES

Listing 1. A 256-Color Sprite (Continued. on p. 38) over data compiled sprites, and is what we will now focus on. From this point /* ======*/ on, when I refer to compiled sprites, I’ll /* COMPLBMP.C - Routine to compile a 256-color bitmap image for */ /* Mode X or Mode 13h. */ be talking about code-compiled sprites. /* Author: Matt Pritchard for Game Developer Magazine. */ For this article, I have written a /* Adapted from MODEX108 */ /* ======*/ routine in C, shown in Listing 1, which will compile a 256-color sprite for either /* This stuff could go into a .h file */ Mode X or Mode 13h. I’ve also provid- /* Macro Definitions needed by Compile_Bitmap */ ed the assembly language setup routines needed to call the compiled sprite code #define ucharf unsigned char far #define uchar unsigned char #define uint unsigned int

#define hi_word( x ) (unsigned char) (x >> 8) The program #define lo_word( x ) (unsigned char) (x & 0x00FF)

/* Prototypes for Compiled Bitmap Routines */ ucharf * Compile_Bitmap (ucharf *, int, int, int, int); generates actual void far pascal draw_compiled_bitmap (uchar far *, int, ints); void far pascal draw_compiled_bitmap_13h (uchar far *, int, ints); /* ——————————————————————————————————————*/ machine language /* This function takes a Sprite that is stored in a two-dimensional array, such as char ImageData[32][32], and creates a buffer that contains the machine language code to quickly draw that image in Mode 13h or Mode X.

The sprite data is stored line by line, from top to bottom. Each line is stored from left to right. A transparant color value is used to instructions that indicate which pixels are not part of the image and should not be drawn.

Because Mode X supports various screen sizes, we must know the width of the screen a sprite will be displayed on in advance. For Mode 13h, that width is normally 320. draw the specific When possible, two adjacent pixels will be drawn with one 16-bit MOV instruction. This results in smaller and faster code.

This function allocates a buffer to hold the compiled code and returns a far pointer to it. The pointer need only be a char type pointer, since our assembly language routine does the actual calling of it. image on the If the sprite is too big or the program has run out of memory, a null pointer is returned, otherwise a pointer to the compiled code is returned. */ ucharf * Compile_Bitmap (ucharf * theImage, /* Far Ptr to the Sprite */ screen. int X_width, /* Width of the Sprite */ int Y_width, /* Height of the Sprite */ int Trans_Color, /* Transparent Color */ in Listing 2. With minor modifications, int Screen_Width) /* Width of the screen */ { you should be able to use these routines in any program you wish. But I’ll bet int x, y, p; /* Loop counters for X, Y, and plane */ int Words, Bytes; /* Count of each type of instruction */ you aren’t satisfied with just using the int b1, b2; /* Valid pixel flags */ routines; you want to know what makes uintVidOffset, Offset; /* Offsets for memory calculations */ them tick. Let’s take a closer look at the int BytesPerLine; /* Width of display in address bytes */ routines and discuss how they work. longCompiledBufferSize; /* The size of the compiled sprite code*/ longc; /* Counter for the code writing loop */ How it Works in a Program ucharf * theBuffer; /* Pointer to the compiled code buffe */ First, here’s a quick overview of where

int Num_Planes; /* The number of video planes (4 or 1)*/ the routines fit into a typical game. Nor- int Next_Pixel; /* The number of bytes between adjacent pixel*/ mally, sprites are loaded from disk and int Code_Overhead; /* Size of any overhead code needed */ placed into memory buffers either at /* The variable Mode_X controls if we are compiling a sprite for Mode 13h or startup or at some stopping point, such Mode X. For Mode X, we must split the image into four separate planes and as a between rounds screen. With the sprite image in memory, the program

36 GAME DEVELOPER • APRIL/MAY 1995 SUPERCHARGE YOUR SPRITES

Listing 1. A 256-Color Sprite (Continued from p. 36) calls the compile_sprite routine with basic information about the sprite. add plane switching code to the compiled sprite. If the value of Mode_X is The compile_sprite function allo- 0, we compile for Mode 13h, otherwise we compile for Mode X. */ cates a second memory buffer and fills it int Mode_X = -1; /* -1 = Mode X, 0 = Mode 13h */ with machine language instructions

if (Mode_X) { made from the sprite data. Then, it Num_Planes = 4; returns a pointer to the newly compiled Next_Pixel = 4; Code_Overhead = 20; code to the program. Depending on } else { what is needed by your program, you Num_Planes = 1; can deallocate the original sprite buffer, Next_Pixel = 1; Code_Overhead = 5; freeing up additional memory. This } compiling process isn’t necessary each

BytesPerLine = Screen_Width / Num_Planes; time the program is run; the code pro- duced is completely relocatable, so you /* First, we pass through the bitmap and count up the number of adjacent pixel pairs and the number of single pixels. With this information, we will know could load and save the compiled sprites how big a buffer to allocate. */ just like regular sprites. Words = Bytes = 0; When the program needs to draw a for (p = 0; p < Num_Planes; p++) sprite, it calls a special routine with a { pointer to the compiled sprite code and for (y = 0; y < Y_width; y++) { the X,Y screen position at which the Offset = y * X_width; program will draw the sprite. This rou- for (x = p; x < X_width; x+=Next_Pixel) { tine first sets up the CPU’s registers /* Check the current pixel to see if it should be displayed */ with the correct position on the screen and then directly executes the compiled b1 = (theImage[Offset+x] != Trans_Color) ? -1 : 0; sprite code by jumping to it. The com- /* Check the next adjacent pixel (if there is one), and see if piled sprite code then actually returns to it should also be displayed */ the routine that called the special rou- if ((x + Next_Pixel) < X_width) { tine. To the programmer, this process b2 = (theImage[Offset+x+Next_Pixel] != Trans_Color) ? -1 : 0; } else { closely resembles calling a normal sprite b2 = 0; drawing routine. }

/* Check for a pair of adjacent pixels, or a lone single pixel */ How it Compiles the Sprite When we call the routine to compile the if (b1) { if (b2) { sprite, we send it the following informa- Words++; /* Another adjacent pixel pair */ tion about the sprite: x+=Next_Pixel; /* Skip over the next pixel */ } else { • A pointer to an array containing the Bytes++; /* One more lone pixel */ sprite image } • The width of the array in bytes } } • The height of the array in lines } • The color value that will indicate } transparent pixels /* Determine how big a buffer we need for the compiled code, allocate it, and • The width of the screen at the time get a far pointer to it. */ CompiledBufferSize = Code_Overhead + (6 * Words) + (5 * Bytes); the sprite will be drawn. The routine needs that last item, /* Here is where the users can insert their own error handling code */ width of the screen, to compute the off- if (CompiledBufferSize > 65535) { /* Error; compiled sprite would be too large (greater than 64K). */ sets into display memory for each pixel. return (0); In Mode 13h, the width will always be } 320, but in Mode X (see my article if ( (theBuffer = (ucharf *) malloc( (size_t) CompiledBufferSize)) == 0) { “Mode X Revealed,” Dec. 1994), it can /* Error allocating buffer; out of memory. */ return (0); vary according to the programmer’s } wishes. Compiling the sprite is a two-pass /* Now, we go through the image again, this time creating the code to write into the compile code buffer. */ process. On the first pass, the sprite image is scanned, and each pixel is examined to see if it is a transparant

38 GAME DEVELOPER • APRIL/MAY 1995 pixel. Every normal pixel is checked to Listing 1. Continued from p. 38 see if it is adjacent to another normal pixel. This process generates a count of c = 0; for (p = 0; p < Num_Planes ; p++) how many single pixels and adjacent { pixel pairs make up the sprite. for (y = 0; y < Y_width; y++) { Once the pixels are counted, the Offset = y * X_width; routine calculates the size of the com- for (x = p; x < X_width; x+=Next_Pixel) piled sprite code, and allocates memory { to hold the code. Speaking of memory, /* Check the current pixel to see if it should be displayed */ how much memory do compiled sprites b1 = (theImage[Offset+x] != Trans_Color) ? -1 : 0; take up? The size of the compiled sprite buffer will vary from image to image, /* Check the next adjacent pixel (if there is one), and see if it should also be displayed */ but will be approximately 4 bytes per pixel drawn. Transparent areas produce if ((x + Next_Pixel) < X_width) { b2 = (theImage[Offset+x+Next_Pixel] != Trans_Color) ? -1 : 0; no code. If a sprite is stored in a 32-by- } else { 32-pixel grid, but only about half the b2 = 0; pixels are actually drawn, the grid will } take up 1K, while the compiled sprite /* Generate code for a pair of pixels, or for a single pixel. */ should take up about 2K. if (b1) { The size varies because our routine VidOffset = (BytesPerLine * y) + ((x-p) / Num_Planes); creates code to draw two adjacent pixels with one instruction whenever possible. if (b2) { /* Create Code to write Word Constant */ The actual code created is: theBuffer[c++] = 0xC7; /* MOV word ptr */ MOV [BX+offset], <16-bit constant>, theBuffer[c++] = 0x87; theBuffer[c++] = lo_word( VidOffset ); /* BX+VidOffset */ theBuffer[c++] = hi_word( VidOffset ); which is 6 bytes long and draws two theBuffer[c++] = (uchar) theImage[Offset+x]; theBuffer[c++] = (uchar) theImage[Offset+x+Next_Pixel]; pixels. For pixels that are stuck by them- selves, the code created is: x+=Next_Pixel; /* Skip over second pixel*/

} else { /* Create Code to write Byte Constant*/ MOV [BX+offset], <8-bit constant>, theBuffer[c++] = 0xC6; /* MOV byte ptr */ theBuffer[c++] = 0x87; which is 5 bytes long and draws a single theBuffer[c++] = lo_word( VidOffset ); /* BX+VidOffset */ pixel. theBuffer[c++] = hi_word( VidOffset ); theBuffer[c++] = (uchar) theImage[Offset+x]; The routine makes a second pass } through the image, this time generating } } actual code whenever a single pixel or } pixel pair is encountered. If we are com- piling for Mode X, plane switching code if ( (Mode_X) && (p < 3) ) { /* Generate plane switching code*/ is generated in between each video theBuffer[c++] = 0xD0; /* ROL AL, 1 ; Get New mask*/ plane. Finally, instructions to return to theBuffer[c++] = 0xC0; theBuffer[c++] = 0x13; /* ADC BX, CX ; Add in Addr wrap*/ the calling routine are added at the end theBuffer[c++] = 0xD9; of the buffer. theBuffer[c++] = 0xEE; /* OUT DX, AL ; Select new Plane*/ } } Mode 13h vs. Mode X For Mode 13h, compiled code creation /* Create exit code to return to the calling program */ is very straightforward. But for Mode X, theBuffer[c++] = 0x5D; /* POP BP ; Restore BP */ things get more complicated. In Mode theBuffer[c++] = 0x1F; /* POP DS ; Restore DS */ theBuffer[c++] = 0xCA; /* RETF8 ; Exit & Clean Up Stack*/ X, we have to draw all the pixels on each theBuffer[c++] = 0x08; video plane before going to the next theBuffer[c++] = 0x00; video plane. Because of the video planes /* Return a pointer to the Buffer containing the Compiled Code */ in Mode X, the two adjacent pixels we compile into one instruction are actually return (theBuffer); four pixels apart on the screen. In addi- } tion, we must include a 5-byte sequence to select the next video plane into the

GAME DEVELOPER • APRIL/MAY 1995 39 SUPERCHARGE YOUR SPRITES

Listing 2. Compiled Sprite Setup and Call Routine (Continued on p. 41)

; ======; ; Here, I assume it to be a table of word values ; COMPLBMP.ASM - Compiled Sprite Setup & Call Routines for; ; which are stored in the current code segment. ; Mode X or Mode 13h. ; ; Author; Matt Pritchard for Game Developer Magazine. ; Mov BX, [BP].DCB_Ypos ; BX = Ypos ; Adapted from MODEX108 ; Add BX, BX ; Scale BX to Word Offset ; Assembler Used; MASM 5.10a ; Mov BX, wp CS;Line_Offset[BX] ; Get Offset of Line Ypos ; ======; Mov AX, [BP].DCB_Xpos ; Get UL Corner Xpos .MODEL Medium Mov CL, AL ; Save Plane # in CL .286 Shr AX, 2 ; X/4 = Offset Into Line .CODE ; ***** USER NOTE ***** MODIFY AS NEEDED ***** ; ; ===== General Constants & Macros ===== ; CURRENT PAGE is a DWORD pointer to the currently active ; Mode X video memory page. The first word is the offset wp EQU WORD PTR ; into the video adaptor, and the second is the constant dp EQU DWORD PTR ; value of A000 - the VGA’s graphics memory segment. fp EQU FAR PTR ; Here, I assume it to be in DGROUP.

; ===== VGA Register Values & Constants ===== Lds DX, dp CURRENT_PAGE ; Get Current VGA Page Add BX, DX ; DS;BX->Start of Line VGA_Segment EQU 0A000h ;Vga Memory Segment Add BX, AX ; DS;BX->Upper Left Pixel

SC_Index EQU 03C4h ; VGA Sequencer Controller ; Select the first video plane, and set up the registers SC_Data EQU 03C5h ; VGA Sequencer Data Port ; so the next 3 planes can be quickly selected.

MAP_MASK_PLANE2 EQU 01102h ; Map Register + Plane 1 And CL, PLANE_BITS ; CL = Starting Plane # PLANE_BITS EQU 03h ; Bits 0-1 of Xpos = Plane# Mov AX, MAP_MASK_PLANE2 ; Mask & Plane Select Shl AH, CL ; Select correct Plane ;======Mov DX, SC_Index ; VGA Sequencer ports ; DRAW_COMPILED_BITMAP (CompiledImage, X_pos, Y_Pos) Out DX, AX ; Set Initial Vid Plane ;======Inc DX ; Point DX to SC_Data ; Mov AL, AH ; Mask for future OUT’s ; Sets up a call to a compiled bitmap in Mode X. Clr CX ; CX = Constant 0 ; ; ENTRY; Image = Far Pointer to Compiled Bitmap Data ; Setup DS; BX = Upper left corner of Image in VGA memory ; Xpos = X position to Place Upper Left pixel at ; BP = Local Stack Frame ; Ypos = Y position to Place Upper Left pixel at ; AL = OUT mask for Selecting video Plane ; ; CX = Constant value 0 for ADC ; EXIT; No meaningful values returned ; DX = SC_Data; VGA Sequencer Data Port ; ; AH = Destroyed ; SI,DI = Not modified during call DCB_STACK STRUC ; DW ?,? ; DS, BP ; Now we jump to the compiled code which actually draws the DD ? ; Caller ; sprite. The compiled code will return to the caller. DCB_Ypos DW ? ; Y position to Draw Bitmap at DCB_Xpos DW ? ; X position to Draw Bitmap at Jmp dp [BP].DCB_Image ; Draw Sprite DCB_Image DD ? ; Far Pointer to Graphics Bitmap DCB_STACK ENDS DRAW_COMPILED_BITMAP ENDP

PUBLIC DRAW_COMPILED_BITMAP

DRAW_COMPILED_BITMAP PROC FAR ;======; DRAW_COMPILED_BITMAP_13h (CompiledImage, X_pos, Y_Pos) Push DS ; Save DS ;======Push BP ; AX-DX are destroyed ; Mov BP, SP ; Set up Stack Frame ; Sets up a call to a compiled bitmap in Mode 13h. ; ; Get DS;BX to point to (Xpos,Ypos) on the current ; ENTRY; Image = Far Pointer to Compiled Bitmap Data ; display page in VGA memory ; Xpos = X position to Place Upper Left pixel at ; Ypos = Y position to Place Upper Left pixel at ; ***** USER NOTE ***** MODIFY AS NEEDED ***** ; ; ; EXIT; No meaningful values returned ; Line_Offset is lookup table containing the start ; ; offset for each line in VGA display memory.

40 GAME DEVELOPER • APRIL/MAY 1995 compiled sprite buffer before we com- Listing 2. Compiled Sprite Setup (Continued from p. 40) pile the pixels in the next video plane. In Listing 1, the variable Mode_X PUBLIC DRAW_COMPILED_BITMAP_13H controls the output of compiled sprite DRAW_COMPILED_BITMAP_13H PROC FAR code. If it is nonzero, the image is bro- ken into four memory planes, and the Push DS ; Save DS plane switching code is added to the Push BP ; AX-DX are destroyed Mov BP,, SP ; Set up Stack Frame compiled sprite. If Mode_X is zero, then code for Mode_13h is produced. ; Get DS;BX to point to (Xpos, Ypos) in VGA memory Listing 2 shows two separate func- tions for drawing a compiled sprite—one ; ***** USER NOTE ***** MODIFY AS NEEDED ***** ; for Mode X and one for Mode 13h. The ; Line_Offset is lookup table containing the start Mode X routine, draw_compiled_bitmap, ; offset for each line in VGA display memory. loads registers with the screen address ; Here, I assume it to be a table of word values and plane-switching values. The Mode ; which are stored in the current code segment. 13h routine, draw_compiled_bitmap_13h, Mov BX, [BP].DCB_Ypos ; BX = Ypos only needs to load registers with the Add BX, BX ; Scale BX to Word Offset screen address. Mov BX, wp CS;Line_Offset[BX] ; Get Offset of Line Ypos Because compiling sprites reduces Add BX, BP].DCB_Xpos ; Get UL Corner of Sprite the process to its bare essentials, some Mov AX, VGA_Segment ; Segment A000 limitations exist. You can’t resize, rotate, Mov DS, AX ; DS;BX -> VGA memory or clip a compiled sprite to a rectangle. With normal sprites, you could write a ; Setup DS; BX = Upper left corner of Image in VGA memory ; BP = Local Stack Frame different sprite drawing routine that ; AX = Destroyed performed these operations. ; SI, DI = Not modified during call ; CX, DX = Not modified during call Suggestions for ; Improvements ; Now we jump to the compiled code which actually draws the ; sprite. The compiled code will return to the caller. The sprite compiling code I’ve present- ed here is only a start. There is no rea- Jmp dp [BP]. DCB_Image ; Draw Sprite son we can’t include other capabilites in DRAW_COMPILED_BITMAP_13H ENDP the compiled code. Clipping on one axis could be accomlished by ordering the END compiled instrctions along that axis and using a jump table. Among the things that could be added are: • Add support for EGA and VGA 16- color sprites • Add support for SVGA and VESA modes • Add support for word-aligned writes to video memory • Add support for 32-bit instructions • Add support for vertical or horizontal clipping. I leave it to you, our reader, to decide where to take it. Until next time, happy coding! ■

Matt Pritchard is a software developer for Lacerte Software in Dallas, Texas, and the author of MODEX110, a comprehensive freeware ModeX library. You can reach him via e-mail at [email protected] or through Game Developer magazine.

GAME DEVELOPER • APRIL/MAY 1995 41 PUSH-BUTTON GAME DESIGN

Has Push- Button Game Design Arrived?

adventure games—a game genre with proven appeal. More importantly, it then developed SCI, its adventure game devel- opment system, which it used to mass produce new adventure games. Other early and somewhat legendary development systems include LucasArts’s SCUMM and Microprose’s MADS. Recently, there’s been more talk about development platforms as everyone looks for a leg up on the competition. Sierra Online recently finished upgrading its aging development engine and redubbed it SCI32, while newcomer Rocket Science drew envy with its ballyhooed Game Sci- ence system. Selecting shadow colors for a specific background in MADS. The character’s shadows are dif- ferent in each scene—to match the background art. The MADS System Microprose sold the aging MADS system f you think about it, what are the var- to Sanctuary Woods, which turned around ious language compilers used by the and overhauled the entire system. “The software industry besides virtualized new system is called M4DS,” says Matt machine tools? High-level language Grueson, executive producer and director compilers, advanced graphic render- of the advanced development group. ing systems, audio routine libraries— Grueson codesigned MADS when he was these are all tools that help game still with Microprose. When he and a developers build the parts that com- small development group moved en masse poseI a game product. to Sanctuary Woods, they convinced their Historically, the complexity and spe- new employer to purchase MADS from cialization of machine tools has grown as Microprose. an industry grows. Look at any mature The purpose behind MADS, manufacturing industry, and the diversity M4DS, and other development systems is of specialized tools supporting that indus- to dramatically increase productivity. By try is likely to boggle your mind. The reducing the number of programmers younger the industry, the less rich are the needed to complete any given project, the toolsets you can use to build new products. overall budget for a project is drastically In the computer game industry, the reduced. Grueson is clearly sold on the pinnacle of the software development concept, “I had two goals. I wanted to give “machine tool” is the proprietary develop- the end-user a better-looking, better-feel- ment platform. For example, Sierra ing game, and I wanted it to be more cost Online’s long-term success is due in no effective for us to produce these games.” small part to the fact that it ventured into “With a development engine, pro-

42 GAME DEVELOPER • APRIL/MAY 1995 David Gerding gramming is where we save the most forces you to reuse software assets, which money. We don’t need armies of pro- saves money, and the routines that go into grammers to make everything happen.” the development engine as parts tend to Microprose’s lushly animated Dragon- receive extra attention and become highly Fledgling though it Sphere required only one person-year of optimized over time. programming time using MADS, in com- Ideally, programmers can then focus parison to what Grueson estimates would on improving and adding new parts to the take other companies, using less evolved development engine, while (less expen- may be, the game development tools, three to four program- sive) teams of game designers and artists ming person-years to develop. “Based on develop titles. In reality, programmers are what I know about the other development still an integral part of any development- systems, their cost would be 50% to 100% system-assisted team, even if they’re there higher than ours. If someone was trying to only to make the game do new tricks. industry is more than do everything DragonSphere does, and programming it from scratch, I can’t even The Ideal System fathom how much time and money that The ideal development system abstracts as would take.” much of the programming as possible so ready for Sanctuary that artists and designers can use high- Collecting the Parts level, low-learning curve tools to build the To design an effective development sys- game. “The important thing we kept in tem you have to start thinking about any mind as we developed these tools was the Woods‘s M4DS and game as a collection of parts. A game con- programmers working on these tools were sists of programming and content. Spend not the users. The customers were the any time talking to designers of these production team. We wanted each part of development systems and the most com- the team to be able to work with the sys- Rocket Science‘s mon phrase you will hear is “asset man- tem in the way that was natural to them. agement.” Assets are your content, your The artists could do the art with the sys- media: PCX files, bitmaps, WAV files, tem, the game designers could do the and the like. writing and game design, and you didn’t Game Science, two On the software side, a game con- have programmers doing everything,” says tains a collection of routines or functions Grueson. that perform specialized tasks on different M4DS is a great example of how a media types. The road toward creating a fully developed, well-planned develop- solid development system begins with a ment works. The M4 connotes four Ms: systems that herald good library of such routines, both for multimedia, multiplatform, multiplayer, graphics and sound. and multipoint. Building on MADS, Get enough solid routines together, Grueson’s team adds multimedia exten- encapsulate them within an interface or sions, primarily streaming data handlers the onset of push- within a highly abstracted (easy to learn that let the system handle lossless video and read) scripting language, and you have data. Says Grueson, “The data streamer the core of a development system. The allows us to integrate audio, video, and benefits are numerous. This structure collision data, like Rebel Assault did— button game design.

GAME DEVELOPER • APRIL/MAY 1995 43 PUSH-BUTTON GAME DESIGN

ROLLING YOUR OWN DEVELOPMENT SYSTEM hot-spots common to all traditional graphic adventures get plenty of attention icrosoft has released three Windows extensions that, taken together, could in M4DS, including a hot-spot properties easily form the core of a simple development engine and there for the tak- editor. ing. Sure, everyone knows about WinG, the quasi-double-buffering routine The organizing components of any that speeds up graphics blitting under Windows. But go online and get ahold graphic adventure are collections of of WinToon, a set of routines that lets you superimpose a sprite on a win- Mdow playing an AVI file. Also, there’s WaveMix, which will let you mix several WAV file “scenes,” and, subsequently, Scene Edit is sources in real time for multilayered sound effects. Of course, you must already be a Win- where most of the graphical work gets dows programmer or be willing to learn. Microsoft is providing these extensions to get done, reveals Grueson. Even though a developers to develop games for Windows, and they really are worth a look. development system is usually built upon an organizing metaphor such as scenes, it Also, be sure to check out Klik and Play by Francois Lionet and Yves Lamourex. It’s a con- should also help artists and designers sumer-targeted “game creator” that will teach you a lot about how to think of action sweat the details, such as allowing artists games in terms of components. It’s way cool. to match a characters drop-shadow to each specific background. Finally, Director 4.0 has been released. If you’re a PC or Windows fanatic, is new Windows As for the core game logic, designers version is a powerful, cross-platform development system in its own right, though you working on M4DS use a proprietary will likely need to learn Lingo, its scripting language, to do anything approaching a com- mercial-quality game. scripting language modeled closely on C. According to Grueson, “We chose that because you don’t really have to train everybody in it.... Our programmers know almost any type of data that we want to a series of sprites into any one of 24 pro- it, and the syntax is already pretty well put into the stream. It’s fully virtualized. It prietary formats that trade off various lev- defined.” even handles laying out the files in the els of compression depending on the func- correct and optimal order for the best tionality of the sprite required within the Game Science access times.” game. On the cutting edge of development sys- By keeping many of the requisite The Animation Editor lets artists tems, and offering an entirely different game structures represented in data rather take backgrounds, sprites, and sounds and perspective is the Game Science develop- than code, M4DS also promises to be define the interaction between these ment system from Rocket Science. Rocket highly portable. “We’ve got a Macintosh assets. Explains Grueson, “If we have a Science is doing graphically intensive, engine planned, and we’ve got most of the sprite series of a moving car, a bouncing high-motion action arcade games, and the work done for a 3DO engine, though ball, and a kid walking down the sidewalk, organizing metaphor is, appropriately, a we’re not sure we’re going to proceed with plus a background of a street, the anima- world away from Sanctuary Woods’s. that yet,” Grueson says. tion will pull all those components togeth- Most of the work is done in a layout pro- Sanctuary Woods has also incorpo- er and optimize each of the sprite series to gram called Composer that is reminiscent rated a communications sublayer into the get the most animation in the least of Macromedia Director. “The Composer engine that will allow for distributed amount of disk space.” lets you lay out the game in the form of a games where multiple players can interact. Every asset is given a specific name, conditionally branching time line. We call “The system is designed so that the world and those names are available to all pro- it TimeSpace,” explains Sean Callahan, within it can be completely virtual. You grammers, designers, and artists. When software engineer at Rocket Science. can have players or nonplayer characters... designing a development system, it’s a Callahan—one of the principal designers all interacting within the same game uni- good idea to follow Grueson’s lead and of QuickTime while he was at Apple— verse. These ‘points’ can be hooked up via require common file naming conventions created the Composer prototype. modem, network, whatever. Because the so that every member of the development “Our main idea was to create a sys- communication layer is completely sepa- team can quickly assess the contents of an tem so that game designers could create rate, we can write a communications dri- asset by looking at the name. and develop without being programmers,” ver for practically any kind of communica- The Scene Editing tool lets the says Callahan. “In Composer, the designer tion type we might need, including inter- designer and artists lay out all the ele- can do the layout, do the connections, and active television,” says Grueson. ments that compose a particular scene. display it a reasonable level to see how the Because M4DS is primarily a graphic branches look and that kind of thing. It The Building Blocks adventure development system, the even tries to approximate the resolution of The main components of M4DS include metaphors and organizing principals it what the graphics will look like when its a Sprite Editor, Animation Editor, Scene employs follow the structures and aesthet- run on the target.” Editor, Object Editor, and Conversation ic typical to the adventure game genre. The target is important to Callahan Editor. The Sprite Editor lets artists turns For example, the active screen elements or because Rocket Science’s ambitious goal is

44 GAME DEVELOPER • APRIL/MAY 1995 PUSH-BUTTON GAME DESIGN

to make Game Science entirely platform Loadstar, originally compiled for the can rightly claim that each new graphic independent and able to compile to a tar- CD target. But all that hard work will pay adventure offers something the previous get platform at the push of a button. As off in the future, when subsequent titles version did not, but the changes have been such, the system currently handles a limit- are readily “compiled” for the PC in a incremental, rather than revolutionary. ed number of media types, including fraction of the time most companies The trick is to let the game designers’ QuickTime movies, sprites, and digitized would spend to port a product. “The needs define the growth of the develop- audio, though the system’s abilities are trickiest part in getting the compiler to ment system. The tools that programmers changing to meet new demands. port to the different platforms is figuring periodically add to the development plat- “Right now we are just looking at out all the timing issues with the different form should answer designers’ and artists’ how we are going to let Composer handle drives and the graphic hardware,” says needs. It’s simply a matter of keeping the three-dimensional graphics. While our Callahan. developmental tail from wagging the dog. current system doesn’t support true three- Push-button game design has dimensional rendering right now, when The Argument Against arrived, and as the toolsets evolve, game we render the three-dimensional images Development Systems artists, designers, and programmers will on the SGI, part of the output we include Sure, there are cost advantages to imple- likely need to press fewer and buttons to in the file is three-dimensional reference menting a development system, and the see their dreams take form. Paradoxically, information that is stored in one of the allure of such seemingly elegant produc- as the tools proliferate, it may take greater tracks in QuickTime. So, for example, if tion is highly attractive. Is there a down- and greater genius in the future to build a you’re driving down a tunnel and you take side? Yes and no. The potential downside game no one has played before. What a a right turn... the car headlights seem to is that games designed with a common marvelous challenge! ■ reflect on the wall in the right way because development system will look and play we’ve got enough of the three-dimension- alike. While the cookie-cutter similarity al information about the tunnel in the between Kings Quest 4-7 hasn’t hurt the QuickTime track,” reveals Callahan. games’ critical acclaim, sales, or profits, David Gerding is a freelance writer Rocket Science is just putting the there will always be game purists demand- who teaches interactive media at Columbia finishing touches on the PC version of ing something new and different. Sierra College of Chicago.

46 GAME DEVELOPER • APRIL/MAY 1995 BOOK REVIEW

Programming in C and C++: The Literature

n the days before computers became The only major negative aspect a lifestyle and surfing was only done about this book is its limited range of at the beach, you found computer applicability. It may prove too daunting if books in dark corners of university you try to use the Lampton’s book to pro- libraries under “engineering.” Not gram something more high-level, such as anymore. Eventually, every book- an arcade game. store, whether on campus or in a For flight simulator fans, though, mall, had rows of computer books this is the book. Novice programmers may Icovering everything from Ada to Zmo- want to get this for its clarity of writing dem. But where were the hard-core refer- and its chapter on interfaces. Certainly the ences for programming games? information on three-dimensional model- In the past two years, a surge of ing will be of some benefit for those writ- books that proclaims to reveal all these ing first-person-perspective games. secrets has emerged. While none of them will make you an instant game program- Verdict: Seemingly limited appeal ming superstar, any one of them will but well written. Would be of most prove enlightening in some way. Which interest to flight simulator fans. ones are worth the time and money? I analyzed seven books on DOS game Creating Turbo C++ Games development according to their various Clayton Walnum’s Creating Turbo C++ strengths and weaknesses. Games (Que Corp., 1994, $29.99) is a bet- ter book for the novice programmer than Flights of Fantasy Flights of Fantasy. The 470-page book First of the group is Flights of Fantasy covers basic game programming and (The Waite Group, 1993, $34.95) by includes a variety of samples. I really liked Christopher Lampton. This 550-plus- that the book uses a low-end C++ compil- page book focuses on developing a 256- er (Borland’s Turbo C++, which sells for color VGA flight simulator using Borland under $80). The games you learn how to C++. Lampton states up front that the develop are not sophisticated—card simulator won’t compare to a high-end games, a dungeon quest, versions of Wari program like Falcon 3.0, but that it will and Life—but they serve as a good spring- give you the basic rudiments and structure board for more detailed programs, and all to understand how these programs work. use 256-color VGA to look sharp. Most of the book is devoted to the Walnum’s style is friendly and care- essentials of graphics: designing land- ful as he explains the various components scapes, the mathematics of flying, how to in constructing a game and using C++. remove hidden surfaces, and polygon clip- For those new to the language, he even ping, for example. Lampton explains includes a short primer in the back of the clearly about interfaces using joysticks, the book explaining object-oriented program- keyboard, or a mouse. He even manages ming and classes. to touch upon the process of adding The downside is that the games Sound Blaster support to your games. Walnum focuses on are very simple. Top-

48 GAME DEVELOPER • APRIL/MAY 1995 Dean Oisboid ics like sound, joystick interfaces, and which are nightmarish yet vital, are han- killer animation just aren’t in the book, so dled well and made very accessible. ambitious game developers may require The book is not perfect: nowhere is other sources of information to get to the it clearly stated what compiler is recom- It used to be difficult next level of proficiency. Of all the books mended, though Microsoft C 7.0 seemed I reviewed, this one may be the best if you to be the chosen tool (e-mail to one of want to design strategy games. The fun- the authors revealed that Watcom was damentals for programming strategy also used). Many advanced topics, such as to find any program- games are here; you just have to figure out converting graphics routines to SVGA, how to use them. are hinted at but then left as exercises for the reader. No code is included for saving Verdict: Great book for C++ and restoring games, but unlike many of beginners. the other books here, at least the authors ming books —much mention the topic. Tricks of the Game The accompanying CD-ROM is Programming Gurus loaded not only with source code but The most detailed, information-packed many shareware games, such as Doom, less game-specific book of the seven books I looked at is and Blake Stone, and useful tools such as Tricks of the Game Programming Gurus DigiPak and MidiPak to help you develop (SAMS Publishing, 1994, $45.00) by sounds for your programs. Also included Andre LaMothe, John Ratcliffe, Mark is Warlock, a rudimentary Doom-like ones—in your local Seminatore, and Denise Tyler. This is a game whose code you can tinker with. must-have for beginning and intermedi- ate programmers, even if you don’t have a Verdict: A must-have! I only wish it CD-ROM player to access the enclosed went into even more detail—like bookstore. Now,such disc. This 740-page book touches on using DOS extenders and memory everything: sound, artificial intelligence, management. The CD-ROM is networking, assembly language, graphics, loaded with source code, tools, and and more. The focus is on developing a shareware. texts are the order of 256-color VGA Doom-like game. Since this may be the most difficult type of Action Arcade game to develop, understanding the rou- Adventure Set tines here may make programming other A newer book is Action Arcade Adventure types of games easier. Set (The Coriolis Group, 1994, $39.95) the day. Here are the The writing style tends toward a by Diana Gruber of Ted Gruber Soft- sophomoric buddy-buddy style at times, ware. Her book focuses on developing a but the information, tricks, and explana- 256-color VGA side-scrolling arcade tions more than make up for it. The book game similar to Commander Keen or latest books on using presents information well, despite the fact Duke Nukem. Ted Gruber Software that it starts with the topic of assembly makes Fastgraph, a set of graphics rou- language and then dives into matrix alge- tines, and the book includes a subset of bra two chapters later. These subjects, this package, called Fastgraph Light. C to develop games.

GAME DEVELOPER • APRIL/MAY 1995 49 BOOK REVIEW

I have two points to make about this books and the resources listing is a very ming Explorer (The Coriolis Group, book. First, too much space is devoted to nice addition. The listing includes sources 1994, $34.95) takes the coding challenge explaining the source code of the included for custom music, sound effects, maga- and spells things out. This 500-page book tools, such as the sprite editor. Almost zines that may interest developers, and strives to develop one type of game: a top- one hundred pages of the book are devot- other contacts. to-bottom 256-color VGA scroller, simi- ed to the tools’ code, which is great if you lar to Apogee’s Raptor (but more rudi- want to modify those tools. However, Verdict: Great or to be avoided, mentary in play). Roberts uses Borland C most of us don’t want to know how depending on whether you want to 3.1 (4.0 will also work) as the compiler. DeluxePaint or Renderman work—we use Fastgraph as a primary graphics The book is very readable and covers just want to use them. Walnum also package. the expected topics—interfacing, imple- explains his graphics tools in Turbo C++ menting VGA graphics and special Games, but he takes only 30 pages and Programming effects, and sound, which makes it an then quickly returns to game design. Computer Games in C excellent choice for beginners. But, as Second, I feel the book reads like an Robert B. Marmelstein’s book, Program- with Lampton’s Flights of Fantasy, the advertisement for Fastgraph, as all the ming Computer Games in C (M&T Books, next technical step is up to you; to gener- important functions the book describes 1994, $34.95) is similar to Walnum’s alize beyond the type of game demon- come from that product. For example, the Turbo C++ Games in that it describes the strated would require some work. other books I reviewed explain how to development of simple games in depth. Ironically, The Coriolis Group pub- write a joystick interface, but Gruber’s The games in this book tend toward the lished both Roberts’s and Gruber’s book, doesn’t; she suggests you use the Fast- “action arcade” side, putting it somewhat and my reaction while reading PC Game graph routines for this event. No other in competition with Gruber’s book. How- Programming Explorer was that this is help is given on the topic. ever, unlike Gruber’s book, development what Gruber should have written. Every- By relying on a product like Fast- doesn’t rely on high-powered graphics thing, including a joystick routine, is graph, beginning- to intermediate-level routines—and it shows. In fact, many clearly explained—with no reliance on developers don’t learn how to write vital samples use 16-color EGA, which places prepackaged graphics routines. functions such as keyboard interrupt han- this book about four years out of date. I greatly appreciated the chapter on dlers. What may be worse is losing the While each aspect of game construc- what shareware and freeware program- ability—especially for the experienced tion gets some mention, I felt the pro- ming tools to get, and where to get them. programmer—to tweak any of the Fast- grams and logic were too simplistic and graph functions if there are speed bottle- that more efficient coding schemes could Verdict: Great book for beginners to necks. The entire book relies so much on be used. Marmelstein’s use of bitmapping low-intermediates. The narrow range Fastgraph that to extract the information seems very inefficient when compared to of topics may prove too limited for of writing a side-scrolling arcade game LaMothe or Gruber. In fact, Marmelstein more experienced programmers. without it would be darn near impossible. explains various design options and then There is a flip side to this opinion, chooses the easiest option, whereas the Teach Yourself Game however. Some programmers prefer this other authors might have chosen a more Programming in 21 Days reliance, as packages such as Fastgraph efficient yet difficult option. This book As if one huge book weren’t enough for and Fastgraph Light let you can concen- would have stood out two years ago, but in him, Andre LaMothe wrote another one. trate on game design. The products take order to compete against the LaMothe Teach Yourself Game Programming in 21 care of the difficult graphics routines, doc- tome it needs to include much more detail Days (SAMS Publishing, 1994, $39.99) is ument them, and if you encounter prob- and ascribe to a higher level of game. another required monster, coming in at lems, you can call technical support. Fast- 950 pages. Topics are broken into daily graph runs on most C/C++ compilers. Verdict: Well written but not chal- chunks and each “day” ends with a sum- Reactions aside, the most interesting lenging enough. This could have mary, questions and answers, a quiz, and readings were the headers for the game been a much more useful book if exercise. He also throws in weekly reviews: programs. The headers explain the struc- Marmelstein tackled, at least, a VGA a repetition of information that helps you ture of the game and its components— platform and more advanced detailed retain the important stuff. Yes, the and right there you get a ton of informa- games. When compared to the other answers are in the back of the book. As for tion. You can see what kind of thought books, it is painfully obvious that this the compiler, LaMothe recommends and programming goes into a side- is the weakest of the bunch. Microsoft C/C++ 7.0 and MASM 5.0. scrolling arcade game and how the plan- Unlike his previous book, LaMothe ning evolves. Also of interest are the final PC Game tackles a variety of game types instead of chapters on marketing and resources. Programming Explorer just a Doom clone. In fact, he covers some How to sell your finished product is a In contrast to Marmelstein’s and Gruber’s unique topics: topic not really touched by many of the books, Dave Roberts’ PC Game Program- • Text adventures. LaMothe includes a

50 GAME DEVELOPER • APRIL/MAY 1995 chapter on designing an old-fashioned C/C++ (The Waite Group Press, 1994, techniques. (Teach Yourself Game Pro- text adventure. These games sound $34.95) follows up on his Flights of Fanta- gramming in 21 Days does have the easy to program mainly because they’ve sy by exploring the construction of maze newer versions of many shareware been around for so long. However, the games like Doom using Borland C/C++. games, though.) implementation of these games is actu- Unfortunately, Walnum covers much the For the complete beginner awed by ally difficult if you want to advance same ground as LaMothe and his coau- the prospect of wading through either of beyond the “Get fish,” “Eat fish” stage. thors in their Gurus epic—but without as LaMothe’s books, my recommendation He explains the difference between much detail. In fact, the bulk of the 580- is Roberts’ PC Game Programming lexical, syntactical, and semantic analy- page book explores ways to produce a Explorer for the depth and clarity of ses—that is, parsing input into compo- first-person, three-dimensional graphics writing. For C++ aficionados, Walnum’s nents, “understanding” the compo- background. In the final chapter, Walnum Creating Turbo C++ Games gets the nod. nents of the input, and finally acting rushes through the other aspects that go It covers a variety of game types in a from the components if it’s logical to into a game. Implementing sound isn’t well-written manner. do so—as he develops the adventure even mentioned (although Walnum pro- One caveat about these books is game Shadow Lands. As an additional vides neat code for an automap feature). that they all claim to reveal the deepest, demonstration and a wonderful bonus, The book therefore reads more like a darkest secrets of game programming, the enclosed CD-ROM contains the How-to graphics manual rather than one which each one does to an extent. They source code for Zork 1. for a game. all reach a certain point before waffling. • DOS extenders. My gripe about his first On its own, the book is readable and None of the books dared to show how to book has been partially answered. useful, covering a variety of advanced top- program SVGA or implement DOS LaMothe acknowledges DOS exten- ics such as ray tracing, ray and height extenders (and try to write a decent ders and gives recommendations and casting, and the always vital code opti- Doom clone without using some sort of tips for using them, but still doesn’t mization. Of interest is the inclusion of extender). Many of these advanced areas actually show how to use them. Persistence of Vision, an incredible were left as exercises for the reader to • Marketing. While some of the other graphics generator and programming lan- figure out. Also left as an exercise, sur- books I reviewed also mention market- guage, that has quite a following of its prisingly, is how to implement save and ing, LaMothe explains how to protect own. Walnum uses it to produce various restore routines. Some of the books your work by copyrighting and regis- parts of the maze background but even mentioned the topic but none offered tering your program with the copyright this interesting program is not enough to any real code. office. This is a nice touch. save the book. The focus stays too long Realistically, as games continue to Since LaMothe has coauthored one on producing different maze types and push the envelope of hardware, a of the other reviewed books, I’m inclined snazzy background generation and not prospective game programmer just start- to compare the two and see what is miss- enough on game development. The book ing out will quickly hit a wall. Indeed, ing from this newer book. The most obvi- should have been called Producing 3D the in crowd of game developers will ous difference is that this book doesn’t Mazes in C/C++. still remain “in” when it comes to the cover three-dimensional games. In fact, high level, SVGA, network and or you might want to consider both books as Verdict: Bad timing kills this book. modem-capable, AI-intensive, next gen- a set—his first book covers three-dimen- A year ago it would have been a eration games. The fact that there is so sional games and this one explains every- groundbreaker. Though it covers much to learn and that new techniques thing else. Taken as such, the differences similar material, it can’t compare to are continually invented can be daunting are minimal. Tricks of the Game Programming to the beginner. But, with work, Gurus, especially when you factor in patience, and perhaps a little luck, the Verdict: Another must-have. price and the quantity and quality of darkest secrets of game programming LaMothe has again written a book programs on the enclosed disk or will be revealed. ■ that includes so much information CD-ROM. Beginners will not suf- that other books can’t match up. fer, however, if this is the only book The CD-ROM not only has source available at their bookstore. code, it also has more tools and newer shareware games than the A Final Word Tricks of the Game Programming All these books provide some good Gurus disk. information. If you can afford just one Dean Oisboid, owner of Garlic Soft- book, invest in either of the LaMothe ware, develops database applications and is Gardens of Imagination books; both give you a lot of informa- a game designer. He can be reached via e- Clayton Walnum’s Gardens of Imagina- tion, code, and programs for your money mail at [email protected]. or tion: Programming 3D Maze Games in and are the most current in terms of through Game Developer magazine.

GAME DEVELOPER • APRIL/MAY 1995 51 CHOPPING BLOCK

Tie Fighter, Part II

Wayne Sikes his month, we conclude our each mission set. TIE Fighter’s mission review of TIE Fighter by set consists primarily of the new mission LucasArts Entertainment Com- files plus some graphics and sound files After an initial, general pany. We’ve already looked at for the new Missile Boat vehicle. The the TIE game engine in general, absence of a new game engine in the and I wrapped up last month by TIE add-on missions implies that the summarizing some of the data I original game engine had the data for look at LucasArts‘s Tie found in the pilot file. This add-on missions built into it—the add- Tmonth, we’ll go through some of the on mission sets will activate this data as data found in the TIE mission files. needed. LucasArts’s strategy of creating LucasArts released Defender of the only one game engine is good in that it Empire, TIE Fighter’s add-on mission forced the company to plan out the Fighter game engine, disk set, just as I began writing this entire TIE game series from the start. review, so I’ll also cover some of the mis- This makes for cleaner and more reliable sion data I found in these new missions. executables—as compared to game The data files in the Defender of engines that must be updated with each Wayne Sikes digs the Empire mission set were somewhat release of new missions. Also, by not different from what I expected. The distributing new game engines with add-on missions for X-Wing, the first each add-on mission set, LucasArts game in the Star Wars series, contained saves money on duplicating and distrib- deeper. This month, he new game engines (the primary exe- uting mission disks, because the game cutable plus two overlay executables) in engine files are quite sizable. scrutinizes the game‘s data files, as well as the structure of the Defender of the Empire Tie Fighter add-on missions don’t modify the original game engine, they just activate data already incorporated in the engine. add-on mission set.

GAME DEVELOPER • APRIL/MAY 1995 53 CHOPPING BLOCK

Listing 1. General Flight Group Parameters the total number of waves allowed to appear. STRUCTURE DATA DESCRIPTION Several parameters specify the con- OFFSET (DECIMAL) TYPE* dition of the flight group vehicles when 0-11 byte Flight Group Name. 12-byte null-terminated array. the group first appears in the game. The 24-35 byte Cargo 1 text. 12-byte null-terminated array. Starting Configuration specifies normal, 36-47 byte Cargo 2 text. 12-byte null-terminated array. extra weapon, damaged, and special 48 byte Special Craft Position. (shields off, hyperdrive off) configura- 50 byte Vehicle. 1=X-Wing, 2=Y-Wing, 3=A-Wing, etc. 51 byte Vehicles Per Wave. tions. The Weapons variable gives the 52 byte Starting Configuration. 0=Normal -> 8=Shields off default weapon load and the Beam 53 byte Weapons. 0=None -> Magnetic Pulse Weapons details any beam weapon load- 54 byte Beam Weapons. 0=None -> 3=Decoy Beam out. The Beam Weapons data is espe- 55 byte Affiliation. 0=Rebel, 1=Imperial, 2=Neutral, etc. 56 byte Artificial Intelligence. 0=Novice -> 5=Super Ace cially fun to alter because in the original 58 byte Talk Flag. 0=Talk off. 1=Talk on. game only Darth Vader had a Decoy 60 byte Formation. 0=Vic -> 9=Vertical Beam weapon. Now you can give your- 64 byte Number Of Waves. self one too! 66 byte Player Position. 73 byte Difficulty. 0=All Levels -> 5=

54 GAME DEVELOPER • APRIL/MAY 1995 dition (0), “the designated object must flight group structure, beginning at off- have arrived” (1), “the object must have set 104 (decimal) and ending at offset LucasArts‘s single been destroyed” (2), and so on. The start 157 (decimal). Listing 3 summarizes condition depends on actions happening some of the parameters found in each of to another object. This object may be the orders structures. Notice the detail another flight group, a certain type of given to each order. vehicle (X-Wing, Y-Wing, and the like), The Order variable contains at least game engine- or a vehicle that has a specified allegiance 35 commanded orders. A value of 0 (Rebel, Imperial, and so on). The condi- commands the flight group to remain tion may also depend on a range of flight stationary, 1 instructs it to fly away, 2 groups (flight groups 1 to 6, for exam- commands it to fly a loop, and so on. forced the com- ple). The Primary and Secondary Depen- Any details associated with the order, dency Type variables specify the type of such as time constraints or the number object used for the start condition and of loops to fly, are found in the Indica- the Primary and Secondary Start Data tor1, Indicator2, and Indicator3 bytes. pany to plan out variables contain the data for the object. The Commanded Speed byte details the If the object is specified as a flight group, velocity for the flight group while it is the data variables will contain the num- carrying out the order. The speed values ber of the flight group. If the object is a increment in units of 10% of vehicle the whole game type of craft, the data will specify the velocity. craft in the dependency condition. Up to four targets can be associated In addition to all the Primary and with each order. Each of these targets is Secondary conditions, there can also be specified in the Target X Data and Tar- from the start, time delays that prevent a flight group get X Type variables (where X is targets from entering the game for a specified 1 to 4). The Target X Type variable time interval. The Start Minute Delay specifies the type of target and the Tar- counts in units of minutes, and the Start get X Data variable contains the data for which makes for Second Delay counts in intervals of five the target. Among the available target seconds per data increment. types are flight groups, types of craft (X- The Primary And Secondary Logic Wing, A-Wing, and so on), or craft hav- Switch is interesting in that it specifies ing a specified allegiance (Rebel, Imperi- whether the player or game must accom- al, and the like). The Global Player is a more reliable plish both the Primary and Secondary special target type. The Global Player Start Conditions or just either one of type and its associated data are “modi- them. When you set this switch to 0, a fiers” of other target objects (I’ll discuss logical AND condition is specified and global data types in more detail later.). executables. the game or player must meet both start The data for each target (Target X Data) conditions. A value of 1 specifies a logi- cal OR condition and only one of the Listing 2. Start Condition Data start conditions must be met for the flight group to enter the game. STRUCTURE DATA DESCRIPTION OFFSET (DECIMAL) TYPE* Commanding 74 byte Primary Start Condition. 0=Always. 1=Arrived, etc. The Flight Groups 75 byte Primary Dependency Type. 0=no dependence, 1=flight Commanding the flight groups is one of group dependence, 2=vehicle type dependence, etc. the most interesting yet complex areas of 76 byte Primary Start Data. the TIE game engine. A lot of fore- 78 byte Secondary Start Condition. 0=Always. 1=Arrived, etc. 79 byte Secondary Dependency Type. 0=no dependence, 1=flight thought went into the design of the group dependence, 2=vehicle type dependence, etc. algorithms used for the orders that can 80 byte Secondary Start Data. be given to a flight group. 82 byte Primary And Secondary Logic Switch. 0=AND. 1=OR. Each flight group can have primary, 84 byte Start Minute Delay. 85 byte Start Second Delay. secondary, and tertiary orders. The flight group structure stores each order as an * “byte” references an unsigned character. 18-byte structure with the three orders structures occurring sequentially in the

GAME DEVELOPER • APRIL/MAY 1995 55 CHOPPING BLOCK

Listing 3. The Orders Structure ously mentioned, the Global Player tar- get type is a modifier of other targets. It STRUCTURE DATA DESCRIPTION is used in conjunction with these logic OFFSET (DECIMAL) TYPE* flags to modify the actions a flight group 0 byte Order. 0=remain stationary, 1=fly home, 2=fly loop, takes against a target. 3=fly loop and evade, 4=rendezvous, etc. Let’s look at an example to help 1 byte Commanded Speed. 0=stopped -> 10=100% velocity simplify this targeting information. Let’s 2 byte Indicator1. General timer, loop counter, etc. assume you are flying a TIE Fighter and 3 byte Indicator2. General timer, loop counter, etc. 4 byte Indicator3. General timer, loop counter, etc. you want to program a flight group to 6 byte Target 1 Type. 1=flight group, 2=type of craft, attack all TIE Fighter vehicles—that is, 5=allegiance, 7=global, 8=flight group range all TIE Fighter craft except yours. How 7 byte Target 2 Type. 1=flight group, 2=type of craft, would you do this? First of all, program 5=allegiance, 7=global, 8=flight group range 8 byte Target 1 Data. flight group, vehicle, etc. the flight group with the Attack Flight 9 byte Target 2 Data. flight group, vehicle, etc. Group orders (give the Order byte a 10 byte Targets 1 And 2 Logic Flag. 0=AND, 1=OR value of 7). Let’s arbitarily use targets 1 12 byte Target 3 Type. 1=flight group, 2=type of craft, and 2 for this order. We would set Tar- 5=allegiance, 7=global, 8=flight group range 13 byte Target 3 Data. flight group, vehicle, etc. get 1 Type to specify a type of craft (a 14 byte Target 4 Type. 1=flight group, 2=type of craft, value of 2 commands for a type of craft), 5=allegiance, 7=global, 8=flight group range and next we would set Target 1 Data to 15 byte Target 4 Data. flight group, vehicle, etc. a value of 4, which would specify TIE 16 byte Targets 3 And 4 Logic Flag. 0=AND, 1=OR Fighters. * “byte” references an unsigned character. If we stopped right here, then all TIE Fighter craft, including yours, would be attacked. Set Target 2 Type to 7, which invokes the Global Player type, can be a flight group number (assuming in the orders structure randomly. Targets and set Target 2 Data to 10 (decimal) Target X Type specified flight groups), a 1 and 2 can be grouped together into a which is the Global Not Player option. vehicle type (assuming Target X Type single target specification, and the same Finally, set the Targets 1 And 2 Logic called for a type of craft), an allegiance goes for targets 3 and 4. The grouping is Flag to 0 to force the AND combination of (assuming Target X Type called for alle- done by using two Boolean flags—the targets 1 and 2. Now all TIE Fighter giance types), and so on. Targets 1 And 2 Logic Flag and the craft except yours will be attacked. I real- If this discussion of targets hasn’t Targets 3 And 4 Logic Flag variables. A ize that I have left out lots of detail here, already been complex enough, let’s add value of 0 commands that the two tar- but I hope you understand some of the in the logic switches and global types. In gets function in an AND manner (both logic used in commanding flight groups. Listing 3, the data for targets 1 and 2 is groups work together), and a value of 1 (I said previously that the orders system grouped together, as is the data for tar- signals an OR condition (the two target in TIE Fighter is complex. Was I right?) gets 3 and 4. These data were not placed groups work independently). As I previ- Winning the Game There are Primary (Win 1) and Sec- Listing 4. Win and Bonus Variables ondary (Win 2) win conditions that players must meet to win a mission. STRUCTURE DATA DESCRIPTION Refer to Listing 4 for a summary of the OFFSET (DECIMAL) TYPE* win and bonus conditions specified in 158 byte Win 1 Condition. 1=created, 2=destroyed, etc. the flight group structure. You’ll see that 159 byte Win 1 Detail. 1=50%, 4=special vehicle, etc. I’ve included a possible Win 3 condition, 160 byte Win 2 Condition. 1=created, 2=destroyed, etc. but I do not have much evidence that 161 byte Win 2 Detail. 1=50%, 4=special vehicle, etc. indicates this condition exists. 162 byte Possible Win 3 Condition. 163 byte Possible Win 3 Detail. The Win 1 Condition and Win 2 164 byte Bonus Condition. 1=created, 2=destroyed, etc. Condition variables contain the condi- 165 byte Bonus Detail. 1=50%, 4=special vehicle, etc. tions that must be met. The values in 166 signed char Bonus Points. 1 increment = 50 points. these conditions are the same as those * “byte” references an unsigned character. found in the start condition variables. A value of 1 specifies that the group must have arrived, 2 means the group must be destroyed, and so on. The Win 1 Detail

56 GAME DEVELOPER • APRIL/MAY 1995 and Win 2 Detail bytes function as sion structures is fantastic, to say the Wayne Sikes has been a computer modifiers of the conditions. For exam- least. This dedication to a product will hardware and software engineer for the last ple, if the condition specifies that a flight considerably prolong TIE Fighter’s life 10 years. He has an extensive backgrond in group be destroyed, the detail might on the shelves via more add-on mission C, C++, and assembly language program- modify this situation to mean that only disks. I’d really like to see LucasArts ming. He also has several years experience the special craft in the group be release some form of the mission editor as a computer systems intelligence analyst, destroyed to win. used in creating the retail missions. where he specialized in deciphering and dis- The Bonus Condition byte func- Obviously, the company might want to assembling computer code on classified gov- tions the same as the win condition vari- wait until it’s done creating more add-on ernment projects. He has written numerous ables and the Bonus Detail functions the missions, but a retail LucasArts TIE computer gaming help utitlities. You can same as the win detail parameters. If the mission editor could possibly extend the reach him via e-mail at 70733.1562@com- bonus condition and detail are met, life of the game by years. ■ puserve.com or through Game Developer. bonus points can be awarded. The Bonus Points variable is a signed char value. Each increment in the value rep- resents 50 points. Since the bonus vari- able is a signed value, note that negative or penalty bonus points can occur. For example, if the bonus condition on your mother ship is that it be destroyed, a penalty of -10,000 points may be “awarded” if the enemy gets past you and takes out your mother ship.

Want to Edit Some Missions? When analyzing the more detailed aspects of a game, I frequently write util- ities that help with my analysis. The end result of my analysis of the TIE mission structures is a routine called TIEDIT. If you’ve read this far, then you know how complex the TIE mission data is. For this reason, I opted to write TIEDIT in MS Windows because it is relative easy to implement list boxes, edit boxes, and the like in Windows. The sheer number of mission items I could edit was enough to make me abandon any thoughts of a DOS-based TIE mission editor. Com- pletion of TIEDIT took longer than I anticipated because every time I tested it I would get “hooked” by the new mis- sions I was creating, and then I’d spend too much time playing the game! TIED- IT.ZIP is on CompuServe in the Flight Simulation Forum (GO FSFORUM), Space Combat Library.

We Have A Winner Here! As I’ve said before, LucasArts gaming products are generally well written and executed, and TIE Fighter is no excep- tion. The level of detail LucasArts devel- opers have given to TIE Fighter’s mis-

GAME DEVELOPER • APRIL/MAY 1995 57 BY DESIGN

It’s a Sim, Sim, Sim, Sim World

Alexander s computer game companies game companies in the industry. It had Antoniades expand, they often tend to lose grown to over 130 employees in five years their identity. The game and was moving toward going public. But When it was first responsible for the company’s first there were two development issues initial success gives way to had to deal with. other projects, and soon several First, Maxis was still primarily a creative teams are working on Macintosh developer in what was rapidly released, SimCity, different games, some of which becoming a PC market. Co-founder Will Aare successful and some of which aren’t. Wright was a diehard Macintosh fan The next thing you know they’re hawking who developed most of Maxis’ games some Doom clone and you say to your- first on his favorite development environ- self, “This is the company that did x?” ment, the Macintosh. Unfortunately the from Maxis, was the This is not the case with Maxis. sales breakdown favored the DOS mar- At Maxis, the apple never falls far ket by a three-to-one factor, so when from the tree. And that tree, of course, is DOS versions of Maxis’s games were SimCity, the game of civic management often six months to a year behind the sleeper of computer that has not only gone on to sell more Macintosh versions the company ended than one million copies across a number up losing revenue. of platforms, but has also inspired count- This is a problem that Brian Con- less articles in famous periodicals, imita- rad, technical director of Maxis, has had games. Now, numer- tors aplenty, and everything short of a to deal with. Maxis developed SimCity Nobel prize. SimCity was followed by 2000 for DOS and Macintosh simulta- SimEarth, SimAnt, and SimLife, which neously, but, due to the complex nature extended the Sim product line and cor- of DOS platforms and trouble with the ous sequels later, nered a certain mental niche among VESA video drivers, the DOS version gameplayers. still ended up three months behind the Indeed Maxis is one of the names Macintosh version. people are likely to invoke when they talk For the long term, Maxis hopes to Maxis is embarking on about the positive aspects of computer come up with a cross-platform develop- games. The “software toy” that educates ment environment that favors what it as it entertains became Maxis’s hallmark, thinks will be the big market over the and the company thrived on it. Using the next couple of years—Windows. In the magic formula that combined provocative meantime its developers still use the stan- a new venture that games with well-written manuals, excel- dard DOS development environment lent distribution, and some of the highest consisting of Miles Design sound drivers, registration rates in the industry, Maxis Tenberry’s DOS Extender, and Watcom was often able to guide even the most C++ 10.0. The company is very close to will spawn a whole complex game into six-figure sales. moving to NT with Visual C++, but until In 1994, after releasing the much Microsoft can guarantee that what works anticipated sequel to SimCity, SimCity under Windows will work under NT, 2000, the Orinda, Calif.-based Maxis was Maxis will hold off. Conrad expects that new SimWorld. becoming one of the largest computer the company’s last DOS products will be

GAME DEVELOPER • APRIL/MAY 1995 59 BY DESIGN

the upcoming SimTown and SimIsle, the first exchange to occur between Will libraries; next, Maxis will release a software unless running three-dimensional graphics Wright’s “Project X,” the likely successor development kit to close partners; and under WinG invites a huge performance to SimCity 2000, and a three-dimensional finally, the company will put out a software penalty. helicopter rescue game that uses the same development kit for any interested devel- While Maxis addressed the Macin- data set to create scenarios. In this case, opers. Being an old operating systems guy, tosh vs. DOS issue, it was still struggling players of Project X can use the helicopter Mackraz is worried about letting a host of with another one—namely, the inter- game to perform rescues in cities they’ve developers work on SimWorld because locking nature of Maxis’ games, and the created in Project X. someone might create a killer app that future of its cash cow, the SimCity series. For the next stage of the project, cheats on the specs—and Maxis would While SimCity 2000 was a smash hit, Mackraz envisions developers breaking have to continue to support it. Maxis couldn’t see a clear path for down games into modular programs that Everyone at Maxis agrees that dri- improving the series by adding new could pipe data to one another. For exam- ving this technology should be great games to it. But most Maxis games occu- ple SimCity 4000 might contain a Sim- games and not the other way around—the pied some of the same intellectual real City data server that would feed an editor industry should never put technology over estate, which made them natural candi- client and a three-dimensional viewer, game play. Maxis’s goal is that all of the dates to extend into each other. For and a supplemental product like SimRail SimWorld components should feel like example, one of the central strategies a would include more data objects and sep- one world, and a synergy will exist player can use in SimCity is to develop a arate train builder client. between the games developers create using mass transit system to help the city grow. Mackraz stresses SimWorld will not those components. “We’re going to title In A-Train, a game Maxis imported from be a low-level infrastructure or an applica- our way to an operating system,” says Jim the Japanese company ArtDink, the goal Mackraz, indicating that SimWorld will is to help a community expand using a be extended with each new game. commuter rail line. In the same vein, the monster towers of the future in SimCity Project X 2000 are similar in nature to those players SimCity was born while Will Wright was build in another Japanese game imported working on a Commodore 64 action by Maxis, SimTower. game called Raid on Bungling Bay for Thus the SimWorld project was Broderbund in 1985. He became interest- born. The goal of this project was ed in the utility that he used to build the twofold. It would allow Maxis to create islands that were going to be bombed in future games with the capability to extend the game. After he finished the game, he and merge into other preexisting and developed the first version of SimCity for future games. And it would leverage Sim- the Commodore 64. Unfortunately, City and the millions of hours worth of Broderbund passed on the game, so it was playtime that people have invested in never released. SimCity saved games into new markets. In 1987, Wright bumped into Jeff SimTower, a Japanese game, is just one of the many titles currently out that falls Braun, who wanted to start a game com- SimWorld under the Sim umbrella. pany and was interested in helping devel- “Most of the project is formalizing the op SimCity for the new 16-bit computer interface,” says Jim Mackraz, director of tion framework for games, but various systems. Wright started working on Sim- Maxis’ newly formed Core Technology games pieces that are connected. He is City for the Amiga and Macintosh. When Group. Using his experience as a systems currently leaning toward the lowest com- SimCity was released for the Macintosh in designer (Mackraz worked on the mon denominator of object technology, 1989, Time magazine did a cover story on Amiga’s Intuition interface), he and his Microsoft’s OLE and COM, but hasn’t it, and the rest is history. group are trying to set the ground rules ruled out other technology. Maxis sees Reflecting on critics and reporters for the SimWorld project so that devel- this as the framework that will allow its using SimCity as a socio-economic urban opers can integrate them into future developers to write common tools that divining rod, Will Wright says, “I don’t Maxis games as they are making them. can be used by any SimWorld game. think anybody can build an accurate The first version of the SimWorld Developers may also be able to build model of something as complex as a city. architecture will be based around games translation layers that can exchange Sim- It’s just too chaotic.” But somehow that similar in scale to SimCity 2000’s data World data with other gaming systems. never stops him from trying. structure with one more layer of detail. As far as developer relations are con- His latest game, code-named Project This first stage of SimWorld will rely on cerned, the SimWorld project will go X, is perhaps the closest he has come yet. static data exchange—that is, a foundation through three stages. SimWorld will first It goes deeper than any of the previous of users’ saved games. Maxis would like appear as an internal set of development SimCity projects—in this game the player

60 GAME DEVELOPER • APRIL/MAY 1995 will be able to interact in the city he or she definitely makes this game CD-ROM extend its future games. Static objects in builds. I got to see this firsthand. Using an based. The data will be loaded on the fly Project X can be embedded with behav- existing SimCity 2000 saved game, Will as the character walks all the way through ioral characteristics for the simpeople. The Wright demoed some of the working code game—the only data saved in the actual simpeople here aren’t bitmaps, but stored for Project X. game will be where specific interactions pieces of component-based geometry with The game starts out on the same occur. For example, if you stop to buy a basic rules governing how they move. So detail level as SimCity 2000 and then newspaper, and the newspaper agent tells objects can be introduced into an environ- zooms down until one SimCity 2000 tile you his name is Joe, that will now be part ment that wasn’t designed to support fills the screen. The player then creates of the saved game. them. For example, a soccer ball could people who will walk around and interact The danger seems to be the inherent contain the rules of soccer, so when the with each other. As the central character difficulty in saving large games. But soccerball object appears, a simperson walks, the screen scrolls and follows his or Wright remains confident that he can would simply start playing soccer. her path. This person will eventually meet keep the data sufficiently compressed that Project X will provide the early other “simpeople,” randomly determined size will not be an issue. The current foundation of the SimWorld model, and by the surrounding socioeconomic condi- model would make a completely data-rich its success or failure will guide Maxis into tions based on the SimCity 2000 data. Project X saved game, that is, one where what is likely the most ambitious project Project X will likely determine the everything had been tracked or modified, this young industry has seen. It looks like data structure that the first version of at 3 gigabytes worth of data. But Wright Maxis, using game play and not technol- SimWorld will use. That data structure is says playing the game every day for a ogy as it guide, will build the first inte- such that managing the level of detail will month would only result in a saved game grated game environment. But in com- be one of the biggest challenges in this that was about 1MB in size, which isn’t plex data models like the computer game project. Wright estimates that in order to bad for that amount of playtime. market, no simulation can accurately pre- expand the current SimCity 2000 model Project X will put an important com- dict what will really happen. ■ to where the player can walk on every ponent of the SimWorld concept to the floor of every building will take about test—Maxis’s object-oriented data struc- Alexander Antoniades is Game Devel- 30MB to 40MB worth of datasets, which ture, which the company hopes to use to oper’s editor-at-large.

GAME DEVELOPER • APRIL/MAY 1995 61 ARTIST‘ S VIEW

Would You Like Virtual Buttery Flavoring With That?

s the processing power of com- ing much consideration to viewpoint or puters and consoles becomes composition or quick cuts—but the cost ever greater and the expecta- is in visual quality, and these days that tions of game designers and can be a high price to pay. consumers alike rise yet higher, the artist is forced to wade Let’s Go To The Movies waters of increasing depth, If we are, then, to adapt the roles of myr- treading further from shore iad film technicians to our task as com- Awhile the comforts of two-frame sprite puter artists, it is appropriate that for animation and tiled backgrounds recede inspiration and guidance we turn to the in the distance. movies in which their work comes This is not a bad thing—far from it. together. We can benefit from their Artists can now exercise greater creativity hard-earned experience as we usher in a in game creation, flexing muscles that new era of digital entertainment. had previously been underused, given the Watching a good film is an immer- limited graphics capabilities of yesterday’s sive experience. The willing viewer is car- games. Yet at the same time, this new- ried along by the plot as by a current. found “freedom” brings with it new chal- Yet, though the storyline and action may lenges. Consumers want flash and sizzle. seem to flow naturally, the film itself is Hand-animated sequences distinguish a rou- Glossy, cinematic title sequences and an assemblage of artificial devices tine fighting game and reward players for transitional animations are now all but painstakingly combined for effect. In our clearing each level. Pictured here is Mutant obligatory. And with multimedia PCs quest to incorporate similar narrative Rampage: Bodyslam, by Animation Magic for already in an estimated 10 million U.S. sequences in the animations so common CD-i. households, the demand for “interactive now in computer games, we would do movie” titles is growing. well to note how and why effective cine- With digital entertainment acquir- matic storytelling works. ing more and more the characteristics of Few moviegoers dissect a film as cinematic entertainment, game artists are they watch it, preferring to suspend dis- being called upon to adopt the roles of belief and enjoy the show. But cinematic the traditional film crew and to reinter- technique can only be understood by pret on their computers the functions of a observing a film rather than merely being movie set. Whether these complex “vir- swept along by it. Observe the cuts with- tual sets” will be used throughout game- in a scene and note that though the view play or only in title and in-between may switch from close-up to medium sequences, their creation requires a shot to tracking shot and back to close- diverse array of skills ranging from set up, the overall effect is still fluid; try to designer and propmaster to lighting tech- determine the placement of lighting nician and cinematographer, not to men- required to achieve just that effect; pay tion the technical demands of creating attention to camera position and angle full-fledged animation. You can skirt the and the way they affect the mood or significance of these roles, certainly—you meaning of a shot. When the machinery can approach an animation without giv- behind the illusion is revealed, the magic

62 GAME DEVELOPER • APRIL/MAY 1995 of cinema’s ability to transport the audi- Added to these helpful features is the David Sieks ence becomes all the more miraculous, ability to emulate natural media such as the artistry of the film crew all the more oil pastel or watercolor, creating effects so admirable. convincingly “hands-on” you expect to Game animators can The aesthetic considerations of the find finger smudges in the corners. digital entertainment artist mirror those The resulting hand-drawn look of of the filmmaker, whether that artist is such two-dimensional approaches can be a creating animations in two dimensions or refreshing and effective departure from the often take their cue three. For the most part, the creative sometimes sterile slickness or chunky pix- decisions we must make transcend tech- elization of computer graphics. If you’re nique or the actual tools an artist may use not already a fluent practitioner of tradi- to create a scene; aesthetic considerations tional animation techniques, however, this are the same regardless of the method we can be a tough way to start trying to flesh from what‘s happen- use to bring them about. Whether to out your game graphics. While it certainly work in two-dimensional or three-dimen- speeds up the inking and painting time of sional graphics, then, is chiefly a stylistic old-fashioned cel animation, two-dimen- preference. Both require a demanding sional software provides no help with cre- ing (and been hap- skill set and both rely, ultimately, on the ating the illusion of space—perspective, artist’s masterful control of the elements foreshortening, lighting effects, cast shad- that combine to make a scene. ows, and the like are all up to the artist to figure out—and if you elect to reframe a pening) in Hollywood. If It Was Good shot to depict it from a different view for Enough For Walt ... heightened mood, you’re talking about At Animation Magic, a fairly typical redrawing from scratch. fighting game (CD-i’s Mutant Rampage: The creative Body Slam) was jazzed up by means of What’s New between-play interviews with the combat- Such limitations are nothing new; it’s ants, à la TV wrestling. The artists han- essentially the way all hand-rendered art dled the animation using traditional tech- has been made throughout history. How- processes of movie niques—pen and paper—then scanned ever, with the arrival of three-dimensional the results. Later, they used the computer modeling and animation programs, the to clean up and “paint” the hand-rendered computer artist can leave behind the frames. The final look is of a comic book drudgy concerns of the draughtsman and in motion, which suits the game to a tee. concentrate on the creative challenges of making and game Fractal Design Painter offers anoth- visual narrative. And you don’t need to er two-dimensional solution, with an sell your spare organs to scrape up the “onionskin” function that lets you view price of a Silicon Graphics workstation to several still frames simultaneously, like take advantage of the power of three- design are tracing-paper overlays, to aid in rendering dimensional animation, either. Programs animations. You can also create a new like Caligari trueSpace, Visual Software’s image by tracing an existing one, say a Visual Reality, 3DStudio from Autodesk, digitized photo or frame of film or video. and many others are available for a variety strikingly similar.

GAME DEVELOPER • APRIL/MAY 1995 63 ARTIST‘ S VIEW

of platforms at down-to-earth prices, rel- background. mation is readily manageable but it can be atively speaking. Some are significantly A two-dimensional animator can a real challenge to move the viewpoint closer to terra firma than others, but com- draw in the shading and highlights that around or through a scene. pared to a $100k SGI set-up these all seem appropriate. A three-dimensional Another subtly powerful tool pro- qualify as terrestrial in price while still animator must create them by positioning vided by three-dimensional programs is delivering out-of-this-world graphics virtual lights within the virtual set. Three- the ability to affect lens optics. Just as a real effects. dimensional modeling programs will camera can be outfitted with varying To a greater or lesser extent these allow you to set a brightness value and degrees of lenses to affect focal length, so programs all offer variations on the same color for ambient light and position spot- can your virtual camera. The effect is a glorious theme; your monitor becomes a lights to customize the illumination of distortion of perspective, which affects window onto a virtual world of your cre- objects and figures. With 3DStudio, you the perception of depth in a scene. The ation. Look at it from any angle. Light it can even indicate where on an object you ability to alter the appearance of a view in brightly or dimly or fill it with fog. wish the highlight to appear and position such a manner is crucial to the filmmak- Change the textures of its surfaces. Do the light accordingly. er’s art, and, again, it can be extremely what you will, then undo it and try it a difficult to duplicate with traditional, different way. The power is dizzying. Think About two-dimensional animation methods. The range of options is dizzying, Framing and Focus too, and a formidable knowledge base is Viewpoint is a powerful and yet nearly Think About Editing required to make full use of them. A 250- invisible tool in the cinematographer’s kit. The art of editing within a scene is per- page manual is required, for example, to Careful placement of the camera can haps the most significant aspect of narra- illuminate just the “new features” in underscore the relationships of figures or tive film technique, yet it is also the least Release 4 of 3DStudio. objects in a scene by visually grouping or noticeable. Editing is so intrinsic to the separating them. Close-ups can focus way we expect a scene to unfold that the In the Director’s Chair attention on a detail or a fleeting facial details of each cut slide by without regis- Regardless of whether you already have expression, while an extreme long shot tering on the consciousness of the viewer. experience with two-dimensional or can establish locale or serve to make the Pay attention next time you watch a three-dimensional animation, or whether clash of two armies seem puny against the film to the way editing moves the plot you are even now wondering what scale of their surroundings. A high angle along. Observe how shots are juxtaposed, method you’ll use to incorporate cinemat- shot makes the subject appear smaller and how one leads to the next. Notice how ic sequences into your next game, giving might suggest weakness, whereas a low movement is handled with editing. How some thought to film art techniques can angle shot is often used to impart power long does each cut last, and how many go probably help you add something special and stature to the subject. into a scene? to that next project. Such varying viewpoints go unques- Filmmakers have been working with tioned by the audience—we don’t even these ideas throughout the past century Think About Lighting wonder why, for example, we are appar- and have become quite accomplished in While a camera certainly needs light in ently looking down on a scene from a cor- their use. So adept are they in the manip- order to capture images, any cinematogra- ner near the ceiling—because of the nat- ulation of these techniques that, for the pher will tell you that lighting in a film ural way in which viewpoint fits narrative most part, we don’t even notice them at serves more functions than mere practical structure and works to contribute to work. Now, as digital entertainment illumination. Perhaps more than any other mood and meaning. But while the range strides toward new creative horizons, we visual element, lighting sest the mood for of camera positions and angles is essen- can make use of their experience to a scene. Tension builds in darkness and tially limitless, their successful usage is a improve our own art. shadows. Flickering firelight can instantly carefully considered decision. If you want to add stunning anima- make a scene appear cozy, or hellish, or This is worth keeping in mind, as tion sequences to your next title—and of both in turn. Shading can transform a face three-dimensional modeling and anima- course you do—here are the first two from angelic to monstrous. tion software will enable you to position steps: look into a three-dimensional mod- It’s important for lighting effects to the viewpoint anywhere in relation to the eling/animation program, and start pick- seem naturalistic, but Hollywood learned scene, and it’s easy to get carried away. As ing apart every movie you watch. Oh, and long ago that realism is secondary to with placement of lights, the virtual cam- save me the aisle seat. results. In many shots, each major figure era can be positioned visually or by means in a scene will be illumined by three or of Cartesian (X,Y,Z) coordinates to dic- David Sieks is a contributing editor to more lights: a key light for the defining tate a precise location. Involved camera Game Developer and is absolutely no fun to highlights and shadows; fill light , used to movements are also facilitated by three- go to the movies with. Contact him via e- soften the effect of the key light; and a dimensional animation software. With mail at [email protected] or backlight to separate the figure from the two-dimensional methods, character ani- through Game Developer.

64 GAME DEVELOPER • APRIL/MAY 1995