Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 524 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
524
Dung lượng
7,05 MB
Nội dung
Chapter 13 by Mike McShaffry Game Audio If you have any doubt about how important sound is in games, try a little experiment First, find a home theater system that can turn off all the sound except for the center channel The center channel is almost always used for dialogue, and everything else is for music and sound effects Pop a movie in and feel for yourself how flat the experience is without music and sound The same is true for games Done well, sound and music convey critical information to the player as well as incite powerful emotional reactions One of my favorite examples of powerful music in any game is the original Halo from Bungie When the music segues into a driving combat tune, you can tell what is coming up—lots of carnage, hopefully on the Covenant side of things! I’m biased, of course, but an excellent example of sound design and technology comes from Thief: Deadly Shadows by Ion Storm This game integrated the physics, portal, and AI subsystems with the sound system AI characters would receive propagated sound effect events that happened anywhere near them, and they would react accordingly If you got clumsy and stumbled Garrett, the main character in Thief, into a rack of swords, AI characters around the corner and down the hall would hear it, and they’d come looking for you Another great example is from Mushroom Men: The Spore Wars for the Wii by Red Fly Studio In this game, the sound system was actually integrated into the graphics and particles system, creating a subtle but effective effect that had each sparkle of a particle effect perfectly timed with the music They called this the “Metronome.” 391 392 Chapter 13 n Game Audio In this chapter, I’ll take you as far as I can into the world of sound We’ll explore both sound effects and music With a little work and imagination, you should be able to take what you learn here and create your own sound magic How Sound Works Imagine someone on your street working with a hammer Every time the hammer strikes a nail, or perhaps the poor schmuck’s finger, a significant amount of energy is released, causing heat, deformation of the hammer, deformation of whatever was hit, and vibrations in all the objects concerned as they return to an equilibrium state A more complete description of the situation would also include highamplitude vibration of Mr Schmuck’s vocal cords Either way, those vibrations are propagated through the air as sound waves When these sound waves strike an object, sometimes they make the object vibrate at the same frequency This only happens if the object is resonant with the frequency of the sound waves Try this: Go find two guitars and make sure they are properly tuned Then hold them close together and pluck the biggest, fattest string of one of them You should notice that the corresponding string on the second guitar will vibrate, too, and you never touched it directly The experiment with the guitars is similar to how the mechanical parts of your ear work Your ears have tiny hairs, each having a slightly different length and resonant frequency When sound waves get to them and make different sets of them vibrate, they trigger chemical messages in your brain, and your conscious mind interprets the signals as different sounds Some of them sound like a hammer striking a nail, and others sound more like words you’d rather not say in front of little kids The tone of a sound depends on the sound frequency, or how fast the vibrations hit your ear Vibrations are measured in cycles per second, or Hertz (abbreviated Hz) The lowest tone a normal human ear can hear is 20Hz, which is so low you almost feel it more than you hear it! As the frequency rises, the tone of the sounds gets higher until you can’t hear it anymore The highest frequency most people can hear is about 20,000Hz, or 20 kiloHertz (KHz) The intensity of a sound is related to the number of air molecules pushed around by the original vibration You can look at this as the “pressure” applied to anything by a sound wave A common measurement of sound intensity is the decibel, or dB This measurement is on a logarithmic scale, which means that a small increase in the dB level can be a dramatic increase in the intensity of the sound Table 13.1 shows the dB levels for various common sounds How Sound Works Table 13.1 Decibel Levels for Different Sounds dB Level Description The softest sound a person can hear with normal hearing 10 Normal breathing 20 Whispering at five feet 30 Soft whisper 50 Rainfall 60 Normal conversation 110 Shouting in ear 120 Thunder 150 Mr Mike screaming when he beats his nephew Chris at Guitar Hero The reason the scale is a logarithmic one has to with the sensitivity of your ears Normal human hearing can detect sounds over an amazing range of intensity, with the lowest being near silence and the highest being something that falls just shy of blowing your eardrums out of your head The power difference between the two is over one million times Since the range is so great, it is convenient to use a nonlinear, logarithmic scale to measure the intensity of sound Did you ever wonder why the volume knob on expensive audio gear is marked with negative dB? This is because volume is actually attenuation, or the level of change of the base level of a sound Decibels measure relative sound intensity, not absolute intensity, which means that negative decibels measure the amount of sound reduction Turning the volume to 3dB lower than the current setting reduces the power to your speakers by half Given that, and I can put this in writing, all the stereo heads out there will be happy to know that if you set your volume level to 0dB, you’ll be hearing the sound at the level intended by the audio engineer This is, of course, usually loud enough to get complaints from your neighbors Digital Recording and Reproduction If you happen to have some speakers with the cones exposed, like my nice Boston Acoustics setup, you can watch these cones move in and out in a blur when you crank the music It turns out that the speakers are moving in correlation to the plot of the sound wave recorded in the studio 393 394 Chapter 13 n Game Audio Figure 13.1 A typical sound wave You’ve probably seen a graphic rendering of a sound wave; it looks like some random up-and-down wiggling at various frequencies and amplitudes (see Figure 13.1) This scratching is actually a series of values that map to an energy value of the sound at a particular moment in time This energy value is the power level sent into a speaker magnet to get the speaker cone to move, either in or out The frequency, or tone, of the sound is directly related to the number of up/down wiggles you see in the graphic representation of the waveform The speaker is reproducing, to the best of its ability, the identical waveform of the sound that was recorded in the studio If you zoom into the waveform, you’ll see these energy values plotted as points above and below the X-axis (see Figure 13.2) If all the points were in a straight line at value 0.0f, there would be complete silence The odd thing is, if all the points were in a straight line at 1.0, you would get a little “pop” at the very beginning and silence thereafter The reason is the speaker cone would sit at the maximum position of its movement, making no vibrations at all The amplitude, or height, of the waveform is a measure of the sound’s intensity Quiet sounds only wiggle close to the 0.0 line, whereas loud noises wiggle all the way from 1.0f to -1.0f You can also imagine a really loud noise, like an explosion, has an energy level that my Boston Acoustics can’t reproduce and can’t be accurately recorded anyway because of the energies involved Figure 13.3 shows what happens to a sound wave that fails to record the amplitude of a high-energy sound Instead of a nice waveform, the tops and bottoms are squared off This creates a nasty buzzing noise because the speaker cones can’t follow a nice smooth waveform Figure 13.2 A closer view of a sound wave How Sound Works Figure 13.3 A clipped sound wave Audio engineers say that a recording like this had the “levels too hot,” and they had to re-record it with the input levels turned down a bit If you ever saw those recording meters on a mixing board, you’d notice that the input levels jumped into the red when the sound was too hot, creating the clipped waveforms The same thing can happen when you record sounds straight to your desktop with a microphone, so keep an eye on those input levels Crusty Geezers Say the Wildest Things On the Microsoft Casino project, the actors were encouraged to come up with extemporaneous barks for their characters Not surprisingly, some of them had to be cut from the game One was cut by Microsoft legal because they thought it sounded too much like the signature line, “I’ll be back,” from Arnold Schwarzenegger Another was cut because it made disparaging remarks toward the waitresses at the Mirage Resorts My favorite one of all time, though, was a bit of speech from a crusty old geezer, “You know what I REALLY love about Vegas??? The hookers!!!” Sound Files Sound files have many different formats, the most popular being WAV, MP3, OGG, and MIDI The WAV format stores raw sound data, the aural equivalent of a BMP or TGA file, and is therefore the largest MP3 and OGG files are compressed sound file formats and can achieve about a 10:1 compression ratio over WAV, with only a barely perceptible loss in sound quality MIDI files are almost like little sound programs and are extremely tiny, but the sound quality is completely different—it sounds like those video games from the 1980s So why would you choose one over the other? MIDI was popular for downloadable games and games on handheld platforms because they were so small and efficient These days MIDI is more a choice for style than anything else, since even handheld devices are fully capable of playing most sound formats The WAV format takes a lot of memory, but it is incredibly easy on your CPU budget MP3s and OGGs will save your memory budget but will hit your CPU for each stream you decompress into a hearable sound 395 396 Chapter 13 n Game Audio If you’re short on media space, you can store everything in MP3 or OGG and decompress the data in memory at load time This is a pretty good idea for short sound effects that you hear often, like weapons fire and footsteps Music and background ambiance can be many minutes long and are almost always played in their compressed form Always Keep Your Original High-Fidelity Audio Recordings Make sure that all of your original sound is recorded in high-resolution WAV format, and plan to keep it around until the end of the project If you convert all your audio to a compressed format such as MP3, you’ll lose sound quality, and you won’t be able to reconvert the audio stream to a higher bit-rate if the quality isn’t good enough This is exactly the same thing as storing all your artwork in high-resolution TGAs or TIFFs You’ll always have the original work stored in the highest possible resolution in case you need to mess with it later A Quick Word About Threads and Synchronization Sound systems run in a multithreaded architecture I’m talking about real multithreading here and not the cooperative multitasking What’s the difference? You should already be familiar with the Process and ProcessManager classes from Chapter 7, “Controlling the Main Loop.” These classes are cooperative, which means it is up to them to decide when to return control to the calling routine For those of you who remember coding in the old DOS or Windows 3.x days, this is all we had without some serious assembly level coding In a way, it was a lot safer, for reasons you’ll see in a minute, but it was a heck of a lot harder to get the computer to accomplish many tasks at once A classic task in games is to play some neat music in the background while you are playing the game Like I said at the start of this chapter, sound creates emotion in your game But what is really going on in the background to make sound come out of your speakers? Sound data is pushed into the sound card, and the sound card’s driver software converts this data into electric signals that are sent to your speakers The task of reading new data into the sound card and converting it into a usable format takes some CPU time away from your computer While modern sound cards have CPUs of their own, getting the data from the digital media into the sound card still takes your main CPU Since sound data is played at a linear time scale, it’s critical to push data into the sound card at the right time If it is pushed too early, you’ll overwrite music that is about to be played If it is pushed too late, the sound card will play some music you’ve already heard, only to skip ahead when the right data gets in place Game Sound System Architecture This is the classic reader/writer problem, where you have a fixed memory area with a writer that needs to stay ahead of the reader If the reader ever overtakes the writer or vice versa, the reader reads data that is either too old or too new When I heard about this in college, the example presented was always some horribly boring data being read and written, such as employee records or student class enrollment records I would have paid a lot more attention to this class if they had told me the same solutions could be applied to computer game sound systems What makes this problem complicated is there must be a way to synchronize the reader and writer to make sure the writer process only writes when it knows it is safely out of the reader’s way Luckily, the really nasty parts of this problem are handled at a low level in DirectSound, but you should always be aware of it so you don’t pull the rug out from the sound system’s feet, so to speak Let me give you an example In your game, let’s assume there’s a portable stereo sitting on a desk, and it is playing music You take your gun and fire an explosive round into the radio and destroy the radio Hopefully, the music the radio is playing stops when the radio is destroyed, and the memory used by the music is returned to the system You should be able to see how order-dependent all this is If you stop the music too early, it looks like the radio was somehow self-aware and freaked out just before it was sent to radio nirvana If you release all the radio’s resources before you notify the sound system, the sound system might try to play some sound data from a bogus area of memory Worse still, because the sound system runs in a different thread, you can’t count on a synchronous response when you tell the sound system to stop playing a sound Granted, the sound system will respond to the request in a few milliseconds, far shorter than any human can perceive, but far longer than you could count on using the memory currently allocated to the sound system for something that is still active All these complications require a little architecture to keep things simple for programmers who are attaching sounds to objects or music to a game Game Sound System Architecture Just like a graphics subsystem, audio subsystems can have a few different implementations DirectSound, Miles Audio, WWise, and FMod are a few examples It’s a good idea to create an implementation-agnostic wrapper for your sound system so that you are free to choose the implementation right for your game The audio system presented in this chapter can use DirectSound or Miles, and the only change you have to make for your high-level game code is one line of code Figure 13.4 shows the class hierarchy for our sound system 397 398 Chapter 13 n Game Audio Figure 13.4 Sound system class hierarchy The sound system inherits from IAudio This object is responsible for the list of sounds currently active As you might predict, you only need one of these for your game The Audio base class implements some implementation-generic routines, and the DirectSoundAudio class completes the implementation with DirectSound-specific calls The sound system needs access to the bits that make up the raw sound The IAudioBuffer interface defines the methods for an implementation-generic sound buffer AudioBuffer is a base class that implements some of the IAudioBuffer interface, and the DirectSoundAudioBuffer completes the implementation of the interface class using DirectSound calls Each instance of a sound effect will use one of these buffer objects A Resource encapsulates sound data, presumably loaded from a file or your resource cache If you had five explosions going off simultaneously, you’d have one Resource object and five DirectSoundAudioBuffer objects Sound Resources and Handles If you want to play a sound in your game, the first thing you is load it Sound resources are loaded exactly the same as other game resources; they will likely exist in a resource file Sound effects can be tiny or quite long Your game may have thousands of these things, or tens of thousands as many modern games have Just as you saw in Chapter 8, “Loading and Caching Game Data,” you shouldn’t store each effect in its own file; rather, you should pull it from a resource cache A resource cache is convenient if you have many simultaneous sounds that use the same sound data, such as weapons fire You should load this resource once, taking up only one block of memory, and have the sound driver create many “players” that will use the same resource Game Sound System Architecture The concept of streaming sound, compressed or otherwise, is beyond the scope of this chapter The sound system described here uses the resource cache to load the sound data from a resource file, decompresses it if necessary, and manages DirectSound audio buffers if you happen to have the same sound being played multiple times As usual, I’m exchanging clarity for performance, specifically memory usage, so take this into account when looking at this system A commercial grade sound system would only load the compressed sound into memory and use a thread to decompress bits of it as it is played, saving a ton of memory With that caveat in mind, the first thing to is define three classes to help the resource cache load and decompress WAV and OGG files:: class SoundResourceExtraData : public IResourceExtraData { friend class WaveResourceLoader; friend class OggResourceLoader; public: SoundResourceExtraData(); virtual ~SoundResourceExtraData() { } virtual std::string VToString() { return “SoundResourceExtraData”; } enum SoundType GetSoundType() { return m_SoundType; } WAVEFORMATEX const *GetFormat() { return &m_WavFormatEx; } int GetLengthMilli() const { return m_LengthMilli; } protected: enum SoundType m_SoundType; bool m_bInitialized; WAVEFORMATEX m_WavFormatEx; int m_LengthMilli; }; // is this an Ogg, WAV, etc.? // has the sound been initialized // description of the PCM format // how long the sound is in milliseconds class WaveResourceLoader : public IResourceLoader { public: virtual bool VUseRawFile() { return false; } virtual unsigned int VGetLoadedResourceSize(char *rawBuffer, unsigned int rawSize); virtual bool VLoadResource(char *rawBuffer, unsigned int rawSize, shared_ptr handle); virtual std::string VGetPattern() { return “*.wav”; } protected: bool ParseWave(char *wavStream, size_t length, shared_ptr handle); }; 399 400 Chapter 13 n Game Audio class OggResourceLoader : public IResourceLoader { public: virtual bool VUseRawFile() { return false; } virtual unsigned int VGetLoadedResourceSize(char *rawBuffer, unsigned int rawSize); virtual bool VLoadResource(char *rawBuffer, unsigned int rawSize, shared_ptr handle); virtual std::string VGetPattern() { return “*.ogg”; } protected: bool ParseOgg(char *oggStream, size_t length, shared_ptr handle); }; The SoundResourceExtraData class stores data that will be used by DirectSound It is initialized when the resource cache loads the sound Take a look at the protected members first The m_SoundType members store an enumeration that defines the different sound types you support: WAV, OGG, and so on The next Boolean stores whether the sound has been initialized, which is to say that the sound is ready to play The next data member, m_wavFormatEx, stores information about the sound so that DirectSound can play it This includes how many channels are included in the sound, its sample rate, its bits per sample, and other data The last member is a convenience member used to grab the length of the sound in milliseconds, which is nice to have if you are timing something, like an animation, to coincide with the end of the sound A real game would keep compressed sounds in memory and send bits and pieces of them into the audio hardware as they were needed, saving precious memory space For longer pieces such as music, the system might even stream bits of the compressed music from digital media and then uncompress those bits as they were consumed by the audio card As you can see, that system could use its own book to describe it thoroughly The resource cache will use implementations of the IResourceLoader interface to determine what kind of resource the sound is and the size of the loaded resource and to actually load the resource into the memory the resource cache allocates Stream Your Music A better solution for music files, which tend to be huge in an uncompressed form, is to stream them into memory as the sound data is played This is a complicated subject, so for now we’ll simply play uncompressed sound data that is loaded completely into memory Notice that even though a multimegabyte OGG file is loaded into a decompressed buffer, taking up perhaps 10 times as much memory, it loads many times faster As you might expect, the Vorbis decompression algorithm is much faster than your hard drive 900 Index multithreading See also threads (continued) threads background decompressing Zip files, 713–715 creating, 696–698 deadlock, 703–704 dining philosophers’ problem, 703–704 future, 718 hardware, 717 mutexes, 699–700 racing, 702 safety, 704 semaphores, 699–700 setting, 699–700 stacks, 697 starvation, 703–704 storing data, 697 synchronizing processes, 698–702 techniques/tips, 715–716 testing, 699–700 Windows critical section, 700–702 music composers, debugging techniques/tips, 827, 844 fading, 436 recording, 438 resources, 205–206 streaming, 400 mutexes (threads), 699–700 N naked pointers, 68–69 namespaces (static functions), 830 naming Lua variables, 341, 355 NativeMethods class (C# editor), 767–768 networks architectures game logic layer, 47–48 game views, 47 multiplayer games, 48 overview, 46–47 communication (application layer), 34–35 debugging (copying/sharing files), 809 outages (SneakerNet), 110–111 next statements (debugging), 818–820 nil value (Lua variables), 341 nodes (scene graphs) actors, 539, 542 additional, 565 alpha pass, 542–544 camera nodes, 548–551 cameras, 538 light nodes, 551–554 lighting, 539 matrices, 538–539, 541–542 meshes, 560–564 root nodes, 538, 545–548 scene node class, 529–536 sky nodes, 554–560 non-disclosure agreements, non-trivial operations, 59–60 normal builds, 123–124 normalizing input (controls), 259–261 vectors (3D graphics), 449–450 normals (3D graphics), 482–484 NPCs, dialogue/speech, 634, 638 numbers algorithms, 87–88 bug numbers, 860–861 floating-point numbers, 447–448, 450 quadratic equations, 87–88 random number generators, 85–87 windows (C# editor), 766 Nu-Mega BoundsChecker, 825 O objectives (character dialogue/speech), 440 object-oriented programming (Lua) class abstractions, 353–355 metatables, 351–353 overview, 349–350 vector objects, 349–350 objects See also actors; components 3D object meshes, 197–200 audio, 432 black, 485 C++ compression, 471 debugging, 819–820 Euler angles, 469 frustums, 474–478 moving, 462–469 overview, 469–473 planes, 473–474 rotating, 459–469 serializing, 690 collisions characters, 583–586 collision systems, 586–588 doors, 585–586 game logic layer, 37–38 geometry, 582–583 hulls, 580–586 meshes, 580–586 Index physics See physics properties, 578–580 raycasting, 577, 586–588 SDKs See SDKs shapecasting, 586, 588 stairs, 585–586 testing, 583 time, 585 trees, 585–586 data structures, 36–37 debugging C++, 819–820 surfaces, 808 test objects, 824 design practices composition, 61 factories, 65–66 inheritance, 61 initializing, 67–68 events See events game logic layer, 36–37 LuaPlus, 358–360 mapping controls, 243, 245 object-oriented programming (Lua) class abstractions, 353–355 metatables, 351–353 overview, 349–350 vector objects, 349–350 physics acceleration, 569–574 angular velocity, 574–575 center of mass, 574 collisions, 575–576 distance, 569–571, 575–576 force, 571–574 game logic layer, 37–38 gravity, 571–572 inertia, 574 mass, 571–574 rotation, 574 time, 574 torque, 574–575 units of measure, 569 velocity, 569–571, 574–575 state, 36–37 vector objects (Lua), 349–350 OGG files, 403–408 one-axis controls (state), 240 one-stick design (gamepads), 261 OOP (Lua) class abstractions, 353–355 metatables, 351–353 overview, 349–350 vector objects, 349–350 Open scripts, 126 open source data compression (Zlib), 213–218 interfaces, 305 OpenGL, 50 operating systems debugging, 845 developing games, 21–22 main loops, 188–189 operators (Lua), 348–349 optimizing See also debugging; techniques/tips; testing; troubleshooting code, 847–849 memory access, 78–79 options builds (Visual Studio), 104–108 game views, 45 orientation 3D graphics, 446–447 objects (C++ math classes) compression, 471 Euler angles, 469 frustums, 474–478 overview, 469–473 planes, 473–474 OSs (operating systems) debugging, 845 developing games, 21–22 main loops, 188–189 outages (networks), 110–111 overloading controls, 246 overtime (schedules), 865–868 P packaging (resources), 211 packets (sockets), 665–666, 670–673 parentheses See braces paste bugs, 842 patch builds, 878 pathfinding (AI) A* (A-Star), 638–640 dynamic avoidance, 640–641 overview, 636–638 PDB files (debugging), 801–802 percentages (variables), 625 Perforce (source repositories), 113–114 performance finishing projects, 854–855 profiling (debugging), 846–847 resources, 212 901 902 Index personnel See teams physics objects acceleration, 569–574 angular velocity, 574–575 center of mass, 574 collisions, 567–568, 575–576 distance, 569–571, 575–576 force, 571–574 game logic layer, 37–38 gravity, 571–572 inertia, 574 mass, 571–574 rotation, 574 time, 574 torque, 574–575 units of measure, 569 velocity, 569–571, 574–575 SDKs choosing, 576–578, 609 components, 593–594 creating convex meshes, 601–602 creating objects, 599–601 creating triggers, 602–603 debugging, 604–606 events, 606–608 force, 603–604 initializing, 594–595 integration overview, 588–593 shutdown, 595–596 torque, 603–604 udating, 596–599 pipeline (3D graphics), 444–445 PIX (debugging), 812–813 pixel shaders C++ helper class, 516–520 overview, 515–516 rendering, 520–521 pixels debugging, 808, 812–813 pixel shaders C++ helper class, 516–520 overview, 515–516 rendering, 520–521 PKZIP utility, 196 planes clipping planes, 481 quaternions, 473–474 planning (developing games), 18 platforms overview, 8–13 multiplatform projects, 108–110 players controls See controls feedback (cursors), 246–247, 302 game views See interfaces; views; windows input See input interacting with, 3–4 multiplayer games See multiplayer games objectives (character dialogue/speech), 440 testing, 247 understanding, 306 pointers C++ objects, 690 instruction pointers, 818–820 naked pointers, 68–69 sharing data, 172–174 smart pointers C++ shared_ptr, 71–75 memory (threads), 73 overview, 68–69 reference counting, 69–70 troubleshooting, 73–75 polling (state), 240 ports (sockets), 658–659 postmortems, 878–879 preloading See loading prime numbers (quadratic equations), 87–88 printing error messages (debugging), 840 priorities, loading threads, 706 private variables (Lua), 355 Process class, 178–183, 187–188 process managers game logic layer, 39 game views, 44 processes 3D graphics, 444–445 audio, 426–431 builds, 118–120 data-driven processes (main loops), 187 events comparison, 326 frequency values, 744 Lua scripts, 370–379, 619 process managers game logic layer, 39 game views, 44 real-time processes classes, 705–708 loading priorities, 706 overview, 704–705 receiving events, 711–713 sending events, 708–711 synchronizing (threads), 698–702 ProcessManager class, 183–185 Index producers (teams), product demos, 878 profession See jobs professionalism, 874 profiling optimizing code, 847–849 overview, 846 performance, 846–847 Program class (C# editor), 768–769 programmable 3D graphics, 445 programmers, 4–5 programming languages defined, 334 history assembly languages, 331 C++, 331–333 overview, 330 overview, 329 scripting languages comparison, 334, 336–337 programs (Internet), 649–650 progress bars, loading files, 408 project managers, projects See also games automating, 98 building overview, 118–120 builds See builds directories files, 100–103 game engines, 103–104 tools, 103–104 documentation, 98 finishing alpha milestone, 854 beta milestone, 854 breaks, 879–880 code, 857–862 comments, 859–862 debugging, 852–857, 860–861 last-minute content changes, 862–864 overview, 851–852, 876–877 patch builds, 878 performance, 854–855 postmortems, 878–879 product demos, 878 smoke testing, 853 testing archives, 877–878 multiplatform, 108–110 multiple, sharing code, 127–128 restarting, 875–876 starting overview, 97–99 promoting builds, 853 properties object collisions, 578–580 scene graphs, 526–529 protocols Internet, 644–645 TCP, 644–645 UDP, 644–645 prototyping (scripting languages), 334–335 psycho-history, 58 public variables (Lua), 355 Python, 338–339 Q quadratic equations, 87–88 quality, 141 quaternions (C++ math classes) compression, 471 Euler angles, 469 frustums, 474–478 overview, 469–473 planes, 473–474 queues (callback functions), 212 R racing (threads), 702 RAD Game Tools website, 50 RAM See also memory global memory, 75 heap, 76 overview, 75–77 stack, 75–76 VRAM (video RAM), 78 random number generators, 85–87 random set traversal, 87–88 randomization (AI), 614–616 rapid prototyping (scripting languages), 334–335 raycasting (collisions), 577, 586–588 readers (audio), 396–397 reading batching (resource caches), 235 input, 31 readers (audio), 396–397 sockets, 663 real-time processes classes, 705–708 loading priorities, 706 overview, 704–705 receiving events, 711–713 sending events, 708–711 Real-Time Rendering website, 575 receiving events, 711–713 903 904 Index recording audio, 393–395 dialogue/speech, 441 music, 438 volume, 437 reducing complexity (debugging), 817–818 reference counting (smart pointers), 69–70 registering Lua functions, classes, 357 relative paths (storing files), 784 release builds (debugging), 843 releases, first to market, 874–875 remote debugging, 808–810 removing features (schedules), 871–872 rendering displays, 190–191 scene graphs, 526–529 root nodes, 545–548 scene class, 539–541 sky nodes, 554–560 shaders, 520–521 reporting bugs, 846 repositories (source code) Avid AlienBrain, 114–115 branching, 115–118, 127–128 Microsoft Visual SourceSafe, 111–112, 114 overview, 110–111 Perforce, 113–114 sandboxes, 116–118 SneakerNet, 110–111 Subversion, 112–113 TortoiseSVN, 112–113 reproduction audio, 393–395 bugs, 817 resources See also data; files 3D graphics, 444 audio, 398–408 caches batching reads, 235 buffer zones, 234 building, 225–233 DirectX, 233 file systems, 31–33 initializing, 141–142, 147 interfaces, 222 loading, 224–225 managing, 233–237 multiple, 220 overview, 218–222 tracking loaded resources, 222–224 world design, 233–237 debugging, 808, 842–843 files callback functions, 212 data compression, 212–218 overview, 209–211 packaging, 211 performance, 212 formats 3D object meshes, 197–200 animation, 200–202 audio, 205–206 bitmaps, 202–205 cinematics, 206–209 colors, 202–205 compression, 208–209 levels, 202 lossy compression, 204 maps, 202 music, 205–206 overview, 197 textures, 202, 204–205 video, 206–209 loading, 141–142, 147 overview, 195–197 storage, 197 restarting projects, 875–876 restoring scene graphs, 539–541 reticles See cursors risks, innovation, 246 RNG (random number generators), 85–87 root nodes (scene graphs), 538, 545–548 rotation C++ math classes, 459–469 physics, 574 running controls, 248 runtime analyzers, 825 S safety (threads), 704 sandboxes (source repositories), 116–118 saving debug builds, 68 save game directories, 146–147 scalars (vectors), 450 scene class (scene graphs), 536–544 actors, 539, 542 alpha pass, 542–544 cameras, 538 implementing, 539 lighting, 539 matrices, 538–539, 541–542 rendering, 539–541 restoring, 539–541 Index root nodes, 538, 545 updating, 539–541 scene graphs axis-aligned bounding boxes, 528 bounding spheres, 528 camera node class, 548–551 debugging, 550 interface class, 524–526 light manager class, 552–554 light node class, 551–554 meshes, 560–564 nodes, additional, 565 overview, 523–524 properties, 526–529 rendering, 526–529 root node class, 545–548 scene class, 539–541 root node class, 545–548 scene class, 536–544 actors, 539–542 alpha pass, 542–544 cameras, 538 implementing, 539 lighting, 539 matrices, 538–539, 541–542 rendering, 539–541 restoring, 539–541 root nodes, 538, 545 updating, 539–541 scene node class, 529–536 sky node class, 554–560 scene node class (scene graphs), 529–536 scenes See scene graphs schedules developing games, 19–21 finishing projects, 862–864 troubleshooting adding team members, 868–869 breaks, 866 changing, 869–870 debugging, 871–872 leadership, 867 overtime, 865–868 removing features, 871–872 scientific methodology (debugging techniques/tips), 813–817 scintillation (textures), 488–490 scope (Lua variables), 341 screens See also interfaces aspect ratio, 290 class hierarchies, 299 debugging, 807–808 elements, 283–286 full-screen games, 807–808 managing transitions, 284 rendering displays, 190–191 Script Creation Utility for Maniac Mansion (SCUMM), 334 script managers, initializing, 144–145 ScriptProcess class (main loops), 370–379, 619 scripts/scripting languages See also code benefits, 337–338 build scripts automating, 121–122 Close scripts, 126 milestone builds, 124–127 normal builds, 123–124 Open scripts, 126 updating, 124 choosing, 338 creating, 337 defined, 334 design-focused, 335 limitations, 336–337 Lua See Lua memory, 336 overview, 329 programming languages comparison, 334, 336–337 Python, 338–339 rapid prototyping, 334–335 Script Creation Utility for Maniac Mansion (SCUMM), 334 script managers, initializing, 144–145 ScriptProcess class (main loops), 370–379, 619 SCUMM, 334 speed, 336 SCUMM (Script Creation Utility for Maniac Mansion), 334 SDKs (software development kits), choosing, 576–578, 609 components, 593–594 creating convex meshes, 601–602 creating objects, 599–601 creating triggers, 602–603 debugging, 604–606 events, 606–608 force, 603–604 initializing, 594–595 integration overview, 588–593 shutdown, 595–596 torque, 603–604 udating, 596–599 seeds, 85 semaphores (threads), 699–700 905 906 Index sending events, 708–711 serializing (C++ objects), 690 servers login servers (debugging), 826–827 sockets connecting, 668–670, 684–686 sockets API, 660–662 sets, random traversal, 87–88 setting threads, 699–700 shaders compiling (speed), 500 debugging, 812–813 overview, 499–501, 521 pixel shaders C++ helper class, 516–520 overview, 515–516 vertex shaders C++ helper class, 507–515 compiling, 505–507 overview, 501–505 rendering, 520–521 shapecasting (object collisions), 586, 588 shared_ptr (C++ smart pointers), 71–75 sharing code (multiple projects), 127–128 copying files comparison, 809 data events, 173–174 overview, 171 pointers, 172–174 transforms, 171–172 shared_ptr (C++ smart pointers), 71–75 showing components, 789–792 shutdown application layer, 33–35 closing modal dialog boxes, 150–151 consoles, 152–153 managing, 148–153 overview, 129, 147–148 physics SDKs, 595–596 sockets API, 654–655 single/multiple monitor debugging comparison, 807–808 sky nodes (scene graphs), 554–560 smart pointers C++ shared_ptr, 71–75 memory (threads), 73 overview, 68–69 reference counting, 69–70 troubleshooting, 73–75 smoke testing, 853 SneakerNet, 110–111 socket managers, 675–684 sockets Berkeley, 645–646 Internet, 645–646 multiplayer games client connections, 666–669, 673–675 data packets, 665–666, 670–673 events, 686–692 listening, 673–675 overview, 663–665 server connections, 668–670, 684–686 socket managers, 675–684 socket managers, 675–684 sockets API connecting sockets, 658–659 creating sockets, 655–659 DNS, 653–654 initialization, 654–655 overview, 650 ports, 658–659 reading sockets, 663 servers, 660–662 shutdown, 654–655 utility functions, 651–653 writing sockets, 663 Winsock, 645–646 sockets API connecting sockets, 658–659 creating sockets, 655–659 DNS, 653–654 initialization, 654–655 overview, 650 ports, 658–659 reading sockets, 663 servers, 660–662 shutdown, 654–655 utility functions, 651–653 writing sockets, 663 software development kits See SDKs sound See audio sound waves, 394–395 source code repositories Avid AlienBrain, 114–115 branching, 115–118, 127–128 Microsoft Visual SourceSafe, 111–112, 114 overview, 110–111 Perforce, 113–114 sandboxes, 116–118 SneakerNet, 110–111 Subversion, 112–113 TortoiseSVN, 112–113 speech See dialogue/speech Index speed See also time acceleration gamepad controls, 261–262 physics, 569–574 CPU, initializing, 140 functions, 167 memory, alignment, 80–81 profiling optimizing code, 847–849 overview, 846 performance, 846–847 scripting languages, 336 shaders, compiling, 500 velocity (physics), 569–571, 574–575 stability (jobs), 22–23 stack corruption (debugging memory), 840–842 RAM, 75–76 threads, 697 stairs (collisions), 585–586 starting projects overview, 97–99 starvation (threads), 703–704 state AI finite state machines, 617–622 utility theory, 630–634 controls, 301–302 buttons, 240 callbacks, 240 event handlers, 241–243 interface classes, 241–243 managing, 240–243 one-axis controls, 240 polling, 240 three-axis controls, 241 two-axis controls, 241 game logic layer, 36–37 Lua LuaPlus, 358 managing, 367–368 objects, 36–37 statements Lua for statements, 346–348 if statements, 346–347 while statements, 346–347 next statements (debugging), 818–820 static code analysis (debugging), 828 static functions, 830 storage/storing actors, 168–170 components, 168–170 data (threads), 697 files (relative paths), 784 hard drives, initializing, 138–139 resources, 197 streams audio, 399 code design practices, 67 events, 311 music, 400 strings application layer, 34 initializing, 142–144 styles (code) braces, 55–56 consistency, 56–58 developing, 95 overview, 54 subsampling (textures), 488–490 Subversion, 112–113 surfaces (debugging), 808 symbol files (debugging), 805–807 SYMCHK utility, 806–807 synchronizing See also time audio, 432–434 audio readers/writers, 396–397 C# editor, 786 lip synching, 440–441 processes (threads), 698–702 system clock, 34 system clock, 34 System Debug symbols (Visual Studio), 806 system RAM See RAM system resources, initializing, 136–137 T tables (Lua), 343–346 LuaPlus, 360–361 metatables, 351–353 targets controls, accuracy, 247–248 debugging techniques/tips, 824 vectors (3D graphics), 452–455 Task Manager (debugging memory), 839 TCP protocol, 644–645 teams animators, audio engineers, composers, designers, 5–6 exhaustion, 872–873 morale, 867, 873–874 907 908 Index teams (continued) postmortems, 878–879 producers, professionalism, 874 programmers, 4–5 project managers, team members adding, 868–869 debugging techniques/tips, 827–828 testers, techniques/tips See also debugging; optimizing; testing; troubleshooting debugging assembly code, 820–822 BoundsChecker, 825 breaks, 828 C++ object scope, 819–820 caveman debugging, 826–827 check routines, 822–823 code analyzers, 824–825 coordinates, 824 coworkers, 827–828 data structures, 822–823 disappearing bugs, 825 drawing, 823–824 experiment-driven process, 813–817 frame rates, 824 instruction pointers, 818–820 Lint, 824–825 logging, 826 memory, 822–824 music, 827, 844 next statements, 818–820 overview, 813 reducing complexity, 817–818 reproducing bugs, 817 runtime analyzers, 825 scientific methodology, 813–817 static code analysis, 828 targets, 824 test objects, 824 UNIX, 826–827 values, 825–826 wireframes, 824 interfaces, 304–306 threads, 715–716 template method design pattern, 63 test objects (debugging), 824 testers bugs, 15–16 teams, testing See also debugging; optimizing; techniques/tips; troubleshooting archives, 877–878 C# editor, 795 controls, 247 game editors, 765 object collisions, 583 smoke testing, 853 threads, 699–700 text dialogue/speech supplement, 440 DirectX Text Helper, 270–271 strings, initializing, 142–144 Text Helper (DirectX), 270–271 textures creating, 487–488 loading, 491–494 mip-mapping, 490–491 resources, 202, 204–205 scintillation, 488–490 subsampling, 488–490 vertices, 487 threads See also multithreading application layer, 34–35 background decompressing ZIP files, 713–715 creating, 696–698 deadlock, 703–704 dining philosophers’ problem, 703–704 future, 718 hardware, 717 memory (smart pointers), 73 mutexes, 699–700 racing, 702 real-time processes classes, 705–708 loading priorities, 706 overview, 704–705 receiving events, 711–713 sending events, 708–711 safety, 704 semaphores, 699–700 setting, 699–700 stacks, 697 starvation, 703–704 storing data, 697 synchronizing processes, 698–702 techniques/tips, 715–716 testing, 699–700 Windows critical section, 700–702 three-axis controls, 241 ticking hard drives, 212 Index time See also speed builds (events), 310 loading files, 564 object collisions, 585 physics, 574 real-time processes classes, 705–708 loading priorities, 706 overview, 704–705 receiving events, 711–713 sending events, 708–711 synchronizing audio, 432–434 audio readers/writers, 396–397 C# editor, 786 lip synching, 440–441 processes (threads), 698–702 system clock, 34 tips See techniques/tips TLDs (top-level domains), 648–649 tolua++ library, 357 tools developing games, 17 directory structures, 103–104 tooltips, 303 top-level domains (TLDs), 648–649 torque physics, 574–575 physics SDKs, 603–604 TortoiseSVN, 112–113 touchscreens See two-axis controls tracking loaded resources, 222–224 tradeshows, 13 transforms, sharing data, 171–172 transitions (screens), 284 transformations (C++ math classes), 478–481 traversing sets randomly, 87–88 trees (collisions), 585–586 triggers (collisions), 602–603 troubleshooting See also debugging; optimizing; techniques/tips; testing audio, 434 automation, 86–87 bugs, testers, 15–16 disasters, 875–876 hard drives, ticking, 212 objects, black, 485 random number generators, 86–87 schedules adding team members, 868–869 breaks, 866 changing, 869–870 debugging, 871–872 leadership, 867 overtime, 865–868 removing features, 871–872 smart pointers, 73–75 twitch-looks, 257 two-axis controls mouse capturing, 249–252 cursors (player feedback), 246–247, 302 dragging, 252–255 event handlers, 249–255 state, 241 two-stick design (gamepads), 261 types of events, 324–326 memory, 75 U Udating (physics SDKs), 596–599 UDP protocol, 644–645 Umbra Software website, 43 understanding hardware, 210–211 players, 306 unit circles (C++ math classes), 459–461 unit vectors (3D graphics), 449–453 units of measurement 3D graphics, 448 physics, 569 UNIX (debugging), 810 unmanaged/managed code comparison, 766–767 updating build scripts, 124 main loops, 176, 191 scene graphs, 539–541 user interfaces See interfaces users See players utilities debugging DUMPBIN.EXE, 806 MSVSMON.EXE, 809–810 SYMCHK, 806–807 PKZIP, 196 utility functions (sockets API), 651–653 utility theory (AI), 630–634 909 910 Index V values absolute values, 625 debugging techniques/tips, 825–826 nil (Lua variables), 341 percentages, 625 process frequency, 744 variables absolute values, 625 global variables (LuaPlus), 361–362 Lua, 340–341 global variables, 356 naming, 341, 355 nil value, 341 private variables, 355 public variables, 355 scope, 341 percentages, 625 vector objects (Lua), 349–350 vectors (3D graphics), 449–455 C++ math classes, 456–458, 481–482 calculating angles, 450–453 cross products, 453–455 dot products, 450–453 floating-point numbers, 450 normalizing, 449–450 scalars, 450 targets, 452–455 unit vectors, 449–453 velocity (physics), 569–571, 574–575 version control Avid AlienBrain, 114–115 branching, 115–118, 127–128 Microsoft Visual SourceSafe, 111–112, 114 overview, 110–111 Perforce, 113–114 sandboxes, 116–118 SneakerNet, 110–111 Subversion, 112–113 TortoiseSVN, 112–113 vertex shaders C++ helper class, 507–515 compiling, 505–507 overview, 501–505 rendering, 520–521 vertices textures, 487 vertex shaders C++ helper class, 507–515 compiling, 505–507 overview, 501–505 rendering, 520–521 video debugging, 845 resources, 206–209 VRAM (video RAM), 78 See also memory video RAM, 78 See also memory views See also interfaces; windows AI, 45–46 audio, 43–44 C# editor, 751–753 creating, 145, 271–281 creating games, 733–736 graphics displays, 41–43 interfaces, 44 multiplayer games, 45 networks, 47 options, 45 overview, 41 process managers, 44 virtual functions, 61–64 virtual memory, 33, 81–82 Visual SourceSafe, 111–112, 114 Visual Studio builds, 104–108 debugging minidumps, 811 remote debugging, 808–810 System Debug Symbols, 806 volume, 434–437 VRAM (video RAM), 78 See also memory W walking (controls), 248 WASD controls, 281–283, 736 WAV files, loading, 401–403 wave forms (audio), 394–395 websites Bullet Physics, 589, 609 Code Project, 313 Impact Software, 302 Indie Games Festival, 246 Level of Detail for 3D Graphics, 237 Lua, 390 RAD Game Tools, 50 Real-Time Rendering, 575 Umbra Software, 43 Xiph, 408 Zlib, 213 weighted randoms (AI), 616 while statements (Lua), 346–347 Wii accelerometers, 249 WinDBG, 810 Index windowed mode (debugging), 808 windows See also interfaces; views creating, 145 debugging, 803–804 number (C# editor), 766 Windows critical section (threads), 700–702 debugging symbol files, 805–807 WinDBG, 810 functions (error handling), 800 keyboards Alt keys, 267 Function keys, 265 input, 262–267 WinMain (initializing), 133–135 Windows Forms (C# editor), 772 WinMain, 133–135 Winsock sockets, 645–646 wireframes (debugging techniques/tips), 824 world design (resource caches), 233–237 wrapping (C# editor), 764 writers (audio), 396–397 writing See creating X-Z XInput (Microsoft), 243–245 Xiph website, 408 XPathUtility class (C# editor), 787–789 Zip files, 713–715 Zlib open source data compression, 213–218 911 This page intentionally left blank ... DirectMusic! // // If you want your primary buffer format to be 22 KHz stereo, 16-bit // call with these parameters: SetPrimaryBufferFormat (2, 22 050, 16); HRESULT hr; LPDIRECTSOUNDBUFFER pDSBPrimary =... Windows game Alt-Tabs away from your game It’s extremely annoying to have game sound effects continue in the background if you are trying to check email or convince your boss you aren’t playing a game. .. sound quality is completely different—it sounds like those video games from the 1980s So why would you choose one over the other? MIDI was popular for downloadable games and games on handheld