Linux Game Programming w/CD (Prima Tech's Game Development) [1 ed.] 0761532552, 9780761532552

With the growing interest in Linux on the desktop, it is only a matter of time until everyone will want high-quality Lin

742 88 44MB

English Pages 368 [370] Year 2002

Report DMCA / Copyright

DOWNLOAD FILE

Polecaj historie

Linux Game Programming w/CD (Prima Tech's Game Development) [1 ed.]
 0761532552, 9780761532552

Citation preview

EIMT

SERIES CD-INCLUDED

,

FRDGRfllYllYllNG 5v-iT!ir-iLJM i_ inT

Andre LalVlothe CEO Xtreme Games LLC

Tr~"

J|

Linux"

f

G-hiyi-e

PRDGRfllYllYllNG

PRIMA TECH'S

C-HEC-K To check the

THE UlEE fDR UfDflT€5

for updates or corrections relevant to this

visit

our updates page on

Web at http://www.prima-tech.com/updates.

5end Us Your To comment on at

book and/or CD-ROM,

this

Coiyiiyients

book or any other PRIMA TECH

title, visit

our reader response page on the

Web

http://www.prima-tech.com/comments.

Hauu to

Order

For information on quantity discounts, contact the publisher: Prima Publishing, P.O. Box 1260BK, Rocklin,

CA 95677-1260;

(916) 787-7000.

On your letterhead,

include information concerning the

intended use of the books and the number of books you want to purchase. For individual orders, turn to the

back of this book for more information.

Tr-"

Linux

G-rfyi

Prdgra m nm n g lYlflRK

"Nurgle" Collins

PRIMA TECH'S

A

DIVISION OF PRIMA PUBLISHING

Linux

©

Cs-hm-e Progrfhyiiyiing

2001 by Prima Publishing. All rights reserved.

No

part of this

book may be reproduced or

transmitted in any form or by any means, electronic or mechanical, including photocopying, recording, or by any information storage or retrieval system without written permission from Prima Publishing, except for the inclusion of brief quotations in a review.

A Division

of Prima Publishing

Prima Publishing and colophon are registered trademarks of Prima Communications, PRIMA TECH and the Game Development series are trademarks of Prima Communications, Inc., Roseville, California 95661.

TECH

Inc.

Publisher: Stacy L. Hiquet

Associate Marketing Manager: Jennifer Breece

Managing

Editor:

Sandy Doell

Acquisitions Editor: Jody

Kennen

Project Editor: Heather Talbot

Technical Reviewer: Zach Slater

Copy

Editor: Alice Martina Smith

Interior Layout: Bill

Hartman

Cover Design: Prima Design Team Indexer: Johnna

VanHoose Dinse

Proofreader: Fran Blauw

Linux

is

a registered trademark of Linus Torvalds.

OpenGL

is

Loki and

OpenAL

Important:

a registered trademark of Silicon Graphics, Inc. are registered trademarks of Loki Software, Inc.

Prima Publishing cannot provide software support. Please contact the appropriate

software manufacturer's technical support line or

Web

site for assistance.

Prima Publishing and the author have attempted throughout this book to distinguish proprietary trademarks from descriptive terms by following the capitalization style used by the manufacturer. Information contained in

be

reliable.

this

book has been obtained by Prima Publishing from sources believed

However, because of the

possibility of

human

to

or mechanical error by our sources, Prima

Publishing, or others, the Publisher does not guarantee the accuracy, adequacy, or completeness of

any information and

is

not responsible for any errors or omissions or the results obtained from use

of such information. Readers should be particularly aware of the fact that the Internet

changing

entity.

Some

facts

may have changed

since this

ISBN: 0-7615-3255-2 Library of Congress Catalog Card

Number:

Printed in the United States of America

00 01

020304

II

109

8

765 43

2

1

00-1 10735

book went

to press.

is

an ever-

Linux

G^me

FROGR-HnnnmNG

r

dntentb at a

Glance 1

N TR DDUCT1DN

CHflFTER

XXXI

1

Introduction to Griyie DevELOFmENTiii.nl

CHAPTER

S Linux Development Toole

11

CHAPTER

3 The Structure of a G-hme

CHAPTER

H-

ED Graphics Under

CHAPTER

5

Input

5DL

ujith

EH

Linux

E3 i53

cL

Linux

Game

FRaGRfimiYnNG

CHAPTER

E 3D Grafhicb for Linux Gflmes

CHAPTER r^

7

Using OfenGL

CHAPTER

B7

in

Games

117

B

Bound Under Linux

1H-7

CHAPTER

3 Networking

1B3

CH^^T^K

ID Artificial Intelligence

CH^JPTE.^

137

11

DFENSDURCEB PR1END OR FOE?

APPENDIX A Dfen5durce License Agreements

S

l

+3

APPENDIX E Porting

E73

Linux Gaiyie

APPENDIX

-FRaG-R-HiYiiYnNG

C

REf£RENC€5

E3 3

APPENDIX D Globb-rry

SD7

APPENDIX E UUhatIs on the CD-RDIY1

Index

.313

315

vn

Linux Gaiyie -PROGRAmmiNG

1

Jl

Jn

Linux

G-hiyi-e

PRciG-R-HpnnmNG

r

Contents xxxi

Introduction

CflflFTER

1

Introduction to Gaiyie Develdpiyient What Makes Different

1

Game?

2

Game Genres

2

a

Shoot-em-ups Strategy

2

Games

3

Simulations

3

Games Puzzle Games Adventure Games Role-Play Games Card Games Sports Games

3

Platform

What Makes

a Successful

4 4 4 4

4

Game?

The Game-Development Process

5

6

The Design Document Development

6

Testing

7

7

Q^

Linux Gaiyie FRDGRflmiYiiNG

Releasing Your

1 n

Game

8

OpenSource Games

8

Commercial Games

9

Shareware Games

10

CHAPTER

S Linux Develop ment Tools Development Tools

ill 12

Compiler

12

Debugging Tools

15

Development Environments

18

Libraries

20

Simple DirectMedia Layer

20

OpenGL

21

libXIl

21

Other

21

Libraries

CHAPTER

3 The Structure of a The

E3

Game

24

Framework

24

Parts of a

A Game

Gaiyie

Linux Gaiyie FROGRfliYimiNG

CHAPTER

H-

ED Graphics Under

Linux

23 n

The SDL API Starting

30

Up SDL

30

Creating a Window

32

Creating a Surface

33

Drawing a Bitmap Image

35

Drawing Directly to the Screen

36

Formats

36

Plotting Pixels

38

Pixel

Using Palettes

Up

40

Xlib API

40

Cleaning

The

39

Creating a

Window

41

Drawing to the Screen

43

Plotting a Pixel

43

Drawing Images

45

47

Double Buffering Installing

Color Maps

48

Cleaning

Up

49

The SVGAlib API Switching to a Graphics

Drawing to the Screen

49

Mode

50 51

Linux Gaiyie FRDGRflmmiNG

52

Displaying Images

Understanding the

Tl

PCX

Format

55

Displaying the Image n

Using Color Palettes

56

Up

57

Cleaning

A

52

57

Mini-Project

CHAPTER

B

Input

5DL

uht+h

..«53

Understanding Input Devices

60

Keyboard

60

Mouse

61

Joystick

61

Handling Methods

62

Event Queues

62

Polling

62

Using the

SDL

Event Queue

63

The SDL_Event Union

63

Layout

63

Interpreting Event Types

64

Reading from the Event

Queue

64

Keyboard Events

68

Mouse Events

76

Joystick Events

78

Polling with

SDL

83

Polling the

Keyboard

83

Polling the

Mouse

84

Configuring the Control System

84

Linux

G-nnn-E FRDGRfiiYiiYiiNG

CHAPTER 3D

E Graphics for Linux Gflmes

B7

r

n

Some

History:

Mesa and OpenGL

88

What Is OpenGL? Where Can Get OpenGL?

88 89

I

Buffers,

Hidden Surface Elimination, and Animation

90

Getting Started

91

Compiling and Linking with Let's

OpenGL

93

Draw Something!

Drawing Polygons, Drawing

Lines,

93 and Points

94

3D: Perspective and Movement

in

96

Perspective and the Projection Matrix

Drawing

in

Orthographic or Perspective

Code That Moves

98

Mode

the Object

Texturing and Other "State" Elements

The The The The The The The

101 1

02

GL_CULL_FACE Option

104

GL_LIGHTING Option

104

GL_TEXTURE_2D Option

105

GL_COLOR_MATERIAL Option

105

GL_BLEND Option

105

GL_ALPHA_TEST Option

105

GL_DEPTH_TEST Option

1

05

106

Lighting Specifying the Lighting Qualities of the Object Establishing the Light Source

Setting

100

Up

Surface Normals

106 1

1

07 08

XIV

Linux Gaiyie PROGRflmmiNG

Texturing the Model 1

Jl

110

Loading the Texture Image

Ill

MIP Mapping the Image

112

Applying the Texture

113

Transparency and the Alpha Component

114

Solving Transparency Problems

115

Fogging

115

CHAPTER

7

Using DfenGL

in Gaiyieb

Understanding Display

117 118

Lists

Understanding Vertex Arrays

119

Drawing with Triangle Strips and Fans

1

Adding Text

121

Understanding Matrices

1

22

1

24

1

26

1

29

1

29

20

Working with Plane Equations, Line Equations, and Distances

in

3D

Using Billboards to Simulate

Working with

3D

Particles

Detecting Collisions Simplify the Shapes If

You Test

the Objects Are Close, Test Again

Follow Surface Contours

130 131 1

32

m

Linux

The Next

Layer: Scene

Graph APIs

G-riyi-e

FROGRflmmiNG

XV

132

Field-of-View Culling State

133

Management

1

Scene Graphs

34

135

Moving the Camera

138

Advanced Lighting

139

Putting

It

All

Together

CHAPTER

B

Bound Under Linux Open AL A Simple OpenAL Application Initializing

and Loading Samples

40

1

14-7 148 148 148

50

Creating Listeners

1

Loading a Sound

151

File

Creating Sound Sources Playing

Sounds

Getting the State of the Sound

Stopping Sounds Deleting a Source

Moving the Source Compiling the Sample

Advanced OpenAL

Volume Control

1

52

153 153 1

1

1

54 54 54

155 155 1

r

55

Velocity and Doppler Shift

156

Reverb and Echo

157

Streaming Buffers

1

58

n

$

Linux Gaiyie FKDGRflmmiNG

SDLAudio

159

Starting an

Audio Session

1

Loading Samples

1

Using the Audio Callback Function Playing a

1

Sample

1

Pausing the Audio Stream

1

Up

Cleaning

1

Mixing Different Samples

CD Audio

1

62 63 63

64 64 64

165

Using the

i

octl

(

)

Function

1

Opening the Device

1

Getting a Track Listing Playing a

59

1

CD

Tracks and Indices

Some Code Stopping a

66

67

1

67

1

3 Networking

66

1

1

CD

65

68 68

C-H-R-PT-E-R

Introduction to

Modern Networking

Peer-to-Peer Networking Client/Server Networking

The TCP/IP Stack

IB 3 70

1

1

70

171

171

TCP

171

UDP

172

Linux Gaiyie

-P-RaG-R-RiYiiYiiNG

Socket Programming Opening

a Socket

1

Connecting the Socket

1

Sending Data

Opening

1

a Socket as a File

Using the send

The sendto(

A

)

(

Stream

1

Function

)

1

Function

1

Mini-Exercise

1

Receiving Data

1

The recvf rom( Function Function The select Another Mini-Exercise The Complete Mini-Web Browser )

(

1

1

1

1

Binding the Socket 1

i

sten

(

)

1

Function

73

75 75 75

76 76 76

77

78 79

80 80

181

Accepting Connections

Threads and Networking

72

178

)

Creating a Server

Using the

72

1

181

82

1

183

Clients

Using Flags to Communicate between Threads

183

Using Message Queues to Communicate between Threads

185

Servers

186

Pings

186

Networking

in

Games

87

1

Dead Reckoning

187

Sending Controller Inputs

1

88

Ir

XVI 11

Linux Gaiyie PRDGRfimmiNG

Lobbies 1

What

Is

OpenLobby?

1

Using the Lobby Server w

88

1

1

Connecting to the Lobby Server Logging

In

1

to the Lobby Server

1

Games Creating Games Ending Games

Finding

Chatting

in

Listing

1

1

1

Chat Rooms

1

Rooms

1

Sending Chat Messages Cleaning

89

89 90

191

the Lobby

Joining and Leaving

88

1

Up

1

Security Issues

1

Denial-of-Service Attacks

1

CHAPTER

ID flRTificifiL Intelligence

93

94 95 95

96 96

198

Route Finding

1

State-Trees

1

Generate the State-Tree

Accommodate

93

137

Basic Artificial Intelligence

Modify the Tree to

93

96

1

Buffer Overflows

92

1

Multiple Routes

98

98 99

200

Search the Tree

200

The Nurgie Method

203

Linux

G-hiyie

FRDGRfliYimiNG

xix

Grouping

205

Problem Solving

206

and Error

206

Min-Max Trees

207

Trial

The Theory Behind the Tree Putting

into Practice

It

Advanced Artificial

Intelligence

Genetic Algorithms

Memes

209

212 212 213

The Genebot Neural Networks Artificial

207

Neural Networks

213

219 220

Changing the Behavior of the Network

223

Personality

223

CHAPTER

11

OfenEourceS Friend or Foe? What

Is

OpenSource?

Unlimited Redistribution Ability to

Charge for Expenses

The Development Models The Cathedral The Bazaar

iSE5 226 227 227

227 227 228

Linux Gaiyie PRDGRfiiYiimNG

Reasons For and Against OpenSource ll

I

Ten Reasons to Use OpenSource

229

Peer Reviews

229

Security

229

Code

Available

I

229

230

Free Software, Free Information

230

Many Developers Fame The Community Aspect

230

Software

Availability of the

The Cause

230 23 23 23

Because You Like

23

It

Ten Reasons to Write Closed-Source Software

232

Money

232

Paranoia

232

Plagiarists

232

New Technologies

233

Contracts

233

Selfishness

233

The "He

Didn't,

So

I

Won't" Attitude

233

Politics

233

Ego

234

Security through Obscurity

234

The Middle Ground

234

Free Code, Private Data

234

OpenSource Later

235

Limited License

235

Key Technologies

236

1

Linux Gaiyie fROGRfliYiiniNG

The Indrema Debate Big Red Warning

236

237

Emulators

238

Time-Share

238

Registered Testers

238

The

238

Which

Solution

License to Use?

239

Viral Licenses

239

Open Licenses Custom Licenses

240

240

Liability

24

R-F-P-END1X

fl

Dpen5durce License Agreeiyiente h.E43 GNU GNU BSD

General Public License

244

Lesser General Public License

250

License

259

Artistic License

260

Mozilla Public License

262

The Apache Software License

270

MIT

271

License

lr

H

XXII

Linux Gfime FRDGRflimmiNG

273

flFFENDIX B i

-Porting w

275

Porting Strategy Try Not to Fork the Codebase

275

276

Getting Started

#ifdef

Is

277

Your Friend

The Harder

277

Stuff

278

First Light

Compiler Visual

GCC

278

Issues

C/C++ Improper Code Size

Scoping

in

for Loops

279 279

Mixing Signed and Unsigned Types

280

Assignment from void*

280

GCC GCC GCC

Doesn't Complain About Missing Return Values

280

Doesn't Complain About Use of Uninitialized Variables

281

Is

More

Strict

About

Implicit Casting

281

Include Filenames

282

Struct Packing

282

File

System

Case

283

Issues

283

Sensitivity

Drive Letters and Path Separators

284

Line Termination

285

File

Attributes and

Home

Directories

Assembly Language

286

286

Operand Order

287

Naming Opcode Naming and Operand

287

Register

Size

287

1

Linux G-nm-E PRQGRfiiYiiYiiNQ

XXlll

Immediate Values

288

Addressing Modes

288

Endianess

288

Windows Wi nMa

i

n

Issues (

)

and Message Loops

289 289

Timers

290

The

29

Registry

Hungarian Notation

29

Graphics Issues

292

DirectDraw

292

DOS

Frame

Buffer

292 293

Direct3D Coordinate Systems

294

Polygon Winding

294

Texture Management

294

OpenGL

295

Sound

Extensions

295

Issues

Networking Issues

295

Winsock File

295

and Socket Handles

296

Include Files

296

Return Codes

296

Different Calls

297

DirectPlay

Is

Useful Links Footnotes

Evil

297

297 298

Linux Gaiyie FROGRflmmiNG

1

fIFFENDIX C References

239

II

Web

II

300

Sites

GameDev.Net

300

GamaSutra

300

Flipcode

300

Happy Penguin

30

Indrema Developer Network

301

Linux

Games

Linux

Game

Books OpenGL OpenGL

301

Developer Resource Centre

301

302 Super Bible (The Red Book)

302

Reference (The Blue Book)

302

Graphics Programming Black Book

302

Game Architecture

302

TCP/IP

and Design

(Volume

Illustrated

2)

303

Linux Device Drivers

303

Game Development

303

Magazines Game Developer

Series

304 Magazine

304

Develop

304

Edge

304

Newspapers

305

Computer Trade Weekly

305

MCV

305

Computer Weekly

305

Computing

305

Linux

G-rhi-e -P«OG«-HrYirYnNG

Newsgroups

306

Mailing Lists

306

flFFENDIX D Glossary flFFENDIX UU+HflT^S

-E

ON THE CD-RDIY1

Running the

CD-ROM

Running the

CD

Index

.3D7

with

with Linux

Windows 95/98/2000/NT

313 314 314

315

r

Linux Gaiyie -PROGRAmmiNG

Linux Gaiyie FRQGRfimmiNG

Jl

RCKNDU1LEDGIY1ENT5 my co-authors,

Ben Campbell, and Martin Donlon, for taking time out of their busy lives to help complete this book on time. If it weren't for their support, this book may not have happened at all. I'd also like to thank all the guys and gals at Prima Publishing, namely Jody Kennen and Heather Talbot, as well as Andre LaMothe (who may one day forgive me for not First

of all, I'd

like to

speaking at the

thank

XGDC).

A big shout goes to all and

for

In the

up with my ever-inflating ego not banning me from the message boards. (Although if they did, who'd run the Linux forum?)

same breath,

namely

Steve Baker,

Paris,

the staff and regulars at

GameDev.Net

I'd like to say "hi" to all the

Llama, Comrade, and Cronus

the 133t people at #hackerzlair

(I

lame software

shall

pirates in the Syndicate of

London,

enjoy watching you die, Mr. Anderson), and to

all

on DALnet.

A big thanks to my ex-ex-ex-ex-ex-ex-ex-ex-ex-ex-girlfriend, tle

for putting

adventure (when we weren't arguing), and to

all

Sima, for supporting

my friends from

me

many

Bath,

throughout

of whom owe

this

lit-

me

large quantities of alcohol.

In true hacker fashion, these particular order, shouts

to:

acknowledgments wouldn't be complete without a

nes8bit, pouya, Myopic Rhino, jhky,

TANSTAAFL, JadeFalcon,

Dulie, Paris,

A Maryjayne, Infinity Matrix, Fwaggle, DysfunksiOn, Trax, Lockpick, Laura ,

Silicon

Dreams

Jonsey—and

(especially Lara, she's hot),

last,

but not

list

of shouts. So in no

ShinyEyedMermaid, JerryLee, TheHermit, Nurse, Mistress Demonica,

least, Invisible

Gumby,

Bob

Comrade, Llama, A cronus A

all

Trev, Ruth, Puppy, Mike, Lil' Chris, Roper,

(the unofficial

,

the guys and gals at

Amy,

Indrema mascot).

The Infamous Mark "Nurgle"

Collins, [email protected]

Lead Author, Linux Game Programming

Linux

G-riyi-e

Author

P-ROG-R-HmmiNG

-Bio

The Infamous Mark "Nurgle"

Collins, the teenager with

about every area of the IT industry, from edly attracted his expertise In addition to

all

Web

design to network consultancy, but one field has repeat-

and outside-the-box

his hobbyist involvement,

an ego that dwarfs Texas, has worked in just

thinking.

That area

Mark has worked

for

is

game development.

one of the

largest developers in

Europe, and he acts as a freelance consultant to various commercial developers

Having

skills in

all

over the globe.

networking, AI, and graphics, he believes that games should be fun, rather than yet

another Quake clone.

Linux G-nm-E FRDGRfimiYnNG

am

t-h

Editor

1

Dear Reader,

A long time to

be a

But,

ago, in a cubicle

far,

far away,

and robust platform

reliable

UNIX had

never really gained

one other than the power user or

when

the

PC

UNIX was created. UNIX has shown

for workstations, mainframes,

much momentum on

technically

the

PC

itself

and even PCs.

platform for anv-

minded. However, the time has come

named Linux, has begun to make major in-roads home, and game programmers are taking notice! Now is the

version of UNIX,

into the average user's

time that gamers and developers alike want to play and develop games for Linux.

However, Linux,



for

like

UNIX,

games

wasn't a simple platform to learn to program

until now...

Linux Game Programming is without a doubt one of the most ambitious game pro-

gramming books ming,

it

boggles the

Linux. But,

I

and

how

starts

libraries

This book

is

mind

to

it all.

The

but an entire

book covers

it all!

treatise

.And

(Simple DirectMedia Laver) to open In conclusion, this

book

be a jewel

in

sets the

game programming

Mark

I

theory.

who want

to learn

on game programming on the Linux

mean

evervthing-from

GL and full 3D game

standard for Linux

2D and

the

SDL

programming.

game programming and

vour game programming library

.^Q%&^ Andre LaxMothe

author.

from square one setting up the compiler, explaining the

not just a bridge for Windows game programmers

platform. This

March 2001

aspects to basic Linux program-

even begin to think about writing 2D 3D games for

of Linux, and covering general

to port to Linux,

definitely

manv

can sav that Linux Game Programming does

"Nurgle" Collins, tools

ever written. There are so

will

Linux Gflme FROGRflmnmNG

Linux Gflm-E FROGRfliYiiniNG

i

lNTRDDUCTlDN j I

ell, it's

been a long time coming, but now there

is

finally a

book on Linux game program-

^^^J ming. With the growing interest in both the commercial and desktop uses of the free Linux operating system, Sure,

it

was only a matter of time

many people have

written

starting with the letter x),

little

games

until

people started thinking about writing games for

it.

x^7/and xboing (and a plethora of titles

in the past, such as

but only in recent years have games that are almost commercial quality been

available for Linux.

With companies such ter

Loki porting successful

as

of time until software houses

start

titles

such as Descent 3 and SimCity 3000,

developing original

titles

is

Linux? In 1991, a student in some country in Scandinavia

message board with big as the

that was never

uses ranging

Linux

is

immortal

this

GNU project, though."

set to

become

a

reality.

made an announcement on it

a

won't be as

(I'm paraphrasing here.) Since then, the "small" operating system

GNU project has grown

going to be as big as the

from enterprise

is

"I'm working on a minix-based operating system;

line:

only a mat-

Linux platform. With the immi-

for the

nent launch of the Indrema console, a Linux-based system, that future

But what

it's

Web

servers to

games

to several million users worldwide, with

consoles.

a semi-POSIX-compatible, UNIX-like operating system that runs on almost every platform

available today, ranging

from i386s

to PalmPilots. Until the past

few years, however, few people consid-

ered using Linux as a desktop environment, but with projects such as

more and more people

are wiping out

Windows and

KDE and Gnome

switching to one of the

paving the way,

many Linux

distributions

available.

lYlv I

first

Jdyb

wit-h

Linux

played with Linux in 1994, running an old version of Slackware on a

the version of Doom included with that

program refused

to get past the

CD-ROM.

title

screen,

I

.After

finding that

started looking for

XWindows working back then). That's when I discovered Abuse, the classic side-scrolling platform game with a rather innovative feature: You aim with the mouse while moving with the keyboard. I was impressed with this feature but knew it wasn't going to last. other games on the

CDs

(I

couldn't get

Linux Gaiyie FRDGRfliYiiYiiNG

After a few weeks,

tried to install a few things

I

UMSDOS partition,

co-existing with

Chicago

from the CD, but horror

struck!

I

was running on a

(later renamed Windows 95). A broken

installation pro-

ll

gram wiped out

the partitions

all

on my hard

disk completely, without even having the courtesy to ask

first.

n

A few years later

DOS, which everyone in my school became addicted to), I decided to try Linux again. So I popped down to the shop and bought a RedHat boxed set, and I was away. After a few problems getting XWindows running reconfiguring

files

here and there, setting up

Why? Because there was nothing Windows and load it from there. After

some

really

impressed me. So

time,

I

did

start

ed playing around with side Java for

and I

still

Web

sites,

had no time

I

playing

an agency,

December

I

Then

for games.

While

I

they'll

complain to your boss

Dreams,

I

if

this

to play

that

I

But

were

I

Dreams.

many

One

this

And

book

I

I

I

to

after I

was

of the most important things



but none of them

network consultancy

I

sending

my curriculum

fired.)

annoy Microsoft;

learned

at least officially, that

is this:

I

had the sudden urge

may seem,

As unlikely

as

a hardcore

gaming platform.

it

to

kill

for one,

I

of

was writing

many of them.

the small project that was never destined for big things I,

No one

Many

is.

co-workers at Dreams were closet die-hard Linux fans; as soon as they found out that

book,

start-

stayed in that job until

things (one of which was to not

about Linux development

into

changed.

week

(I

would reboot

downloaded SDL and

moved up

time.

I

it.

got a job. Working on server-

got the job.

full

Keeper,

in existence,

games.

find one. Within a

decided to write

you do).

I

never actually used

I

Dungeon

after that, however, things

at Silicon

learned

Soon

for

was happily playing around with

so on.

my own

for personal projects.

About a year

in the "professional" industry cares

my

bad Pong clone

the worst thing in the world happened:

had an interview

at Silicon

wanted

some of the Linux games

had no time

2000, at which point

was

I

I

and

security,

started looking for ways to write

it.

I

to do. Every time

was looking for a career change, and boy did

vitae to

really

higher than standard VGA, everything ran perfectly.

in anything stuff,

(and after the phenomenal success of Spong, a

would

like to see that

happen.

may

actually

become

1j-"

CHAPTER

\i

I

Introduction TO GflFYl D-EV-ELO-FIY1-ENT

Linux G-nm-E FRDGRflinmiNG

1

f

Listen my children, for

I

will tell

ago, in a place far away, a to the world.

upon down

He

to the

pub

young man

sat in front

many moons working on

spent

and

his creation

a tale of a quest for glory, an adventure most heroic.

saw that

it

of a magic box and decided to give something

his creation.

And when

it

was complete, he looked

was good. This creation was a computer game. (After

for a few drinks because

he

really

A long time

needed a good night

this

he went

out.)

i

LU-Hf=IT IY1-RK-E5 -R Why is a game

different

GfllYlE?

from any other type of application? There are

several

major differences:

more input and output devices than other applications. Games generally run faster than normal applications and make use of a lot of CPU time. The differences between games and other software are recognized by large software developers such as Microsoft and have forced

Games

generally use

these companies to create additional tools to allow developers to access the hardware directly.

What do you do in a word processor? You type stuff in, add a bit of formatting, stick in some random comments for your editor to have a chuckle over, and save the file. But in a game, a lot more is involved. You have to update the screen as many times as possible Let's

compare

a

game

to a

word

processor.

during a single second. You need enemies reacting to the player's actions, you need a goal to achieve,

and most important, the game has

Different There are many

to

be fun.

G-Hm-E

Genres

on the market, ranging from shoot-em-ups to strategy, from Although some genres are generally more popular than others (such as

different types of games

card games to simulations.

first-person shooters), others have

much more

playability (such as

card games).

bHDDT"€fn-U The shoot-em-up

type of

game

is

probably one of the most popular

game genres

at the

moment. This

category includes games such as Quake and Unreal Tournament. There are several types of shoot-em-up,

ranging from first-person perspective to scrolling games such as Defender. Most games in

but one goal: to

kill

Many newer shoot-em-ups have multiplayer

media

games

this

genre have

anything that moves, from a shotgun to space ship.

(for

in recent years

multiplayer capabilities, while others are written only for use as

example, Quake HI: Arena). These games have come under a

and have been blamed

for the

Columbine shootings.

lot

of fire from the

Introduction to Gflme Dcvelopiyient

Games

of this genre generally have very

alien invaders?

come up

little

in the

Although some games make an

way of a

storyline

—who needs an excuse

effort to craft a story, original stories are

to

kill

the

harder to

with these days.

Many games based on

films

fall

into this category, such as Die

Hard Tribgy and

Alien versus Predator.

[

5T-R-RT-EGY GflfYlES

d_

There are two types of strategy games: real-time and turn-based. Games such StarCraft,

and Dune are

Real-time strategy

real-time,

whereas the hugely successful

games generally

consist of two or

games usually require the mining of raw materials

to play these

Games

new

it's

Command and

Civilization series

sides battling

more time

nearly as popular as shoot-em-ups but require a lot

Conquer can take several hours of playing before

more

to build

as

is

Conquer,

turn-based.

out for an area of land. These

it

structures

and

units.

These games are

to play (a single level of

completed) Consequendy, .

it

Command and

takes a lot of patience

games, and they can become very frustrating.

that require the building of a civilization, such as Sid Miers Civilization, tend to

be turn based.

Turn-based games can be played for days on end with only regular cups of coffee to keep you going. Turn-based games allow a player to move

all

of their units before allowing the other players to have

their turns.

5llYlULflTlDN5 Any game

that attempts to simulate a real event

These games are designed

to

emulate

is

real life as

a simulator, be

much

it

a flight simulator or a fishing game.

as possible, allowing the users to gain

experience in areas they wouldn't normally get a chance to experience.

Some

simulators are used for training, such as the

the United aircraft

Concorde simulator

at British

Kingdom. This multimillion-dollar computer game emulates the

exacdy (except that they won't

let

you barrel

roll it).

A few years ago,

browse through the source code for the simulator (written in Assembler)



Aerospace Filton

in

real behavior of the I

all

had the opportunity

to

several million lines

worth of code! Accurate simulators are big projects and are not suited for the weekend programmer.

PLflTfORm Some

GfllYlEB

of the most successful games ever have been platform games, such as the Mario

consists of a character

recent years has

moving around on a

become

a hyperactive frog

on

Many people new

to

a

full

level that usually scrolls

from

series.

This genre

side to side, but that in

more

three-dimensional environment, with the character jumping around like

anti-depressants.

games development choose

(usually after a few puzzle games). This

the developer's point of view

and can

is

a platform

game

as

one of their

earlier projects

because platform games are generally uncomplicated from

result in

hours of entertainment for the

player.

Linux GfimE P-ROG«flrYimiNG

FUZZLE

GfllYl€5

There are probably more puzzle games

in the

world than any other type of game. Puzzle games are

very easy to code and can be very addictive for the player. This type of game requires very

way of artificial intelligence and tends require large

to

numbers of external data

Examples of puzzle games include to win. Like strategy

be

files

Tetris

relatively small

compared

little

in the

games from other genres

to

that

to run.

and

Minesweeper.

These games require patience and planning

games, puzzle games can get very frustrating over time.

i

RDV-ENTU-R-E

G-HIY1-E5

Adventure games run the gamut of complexity, from the text-based Zork

to the full

This genre usually consists of the main character interacting with various Characters) to achieve a goal, whether that goal (as in Leisure Suit Larry,

many

days of life from a dedicated adventurer.

and

personality,

Some

lot

(Non-Player

up with a sexy be highly immersive and can suck away

GfllYl€5

Similar to adventure games, role-play

tend to be a

NPCs

rescuing a lost artifact or hooking

by Sierra). These games tend to

babe

Rdle-Flay

is

3D Tomb Raider.

more open ended.

games often

Players can

involve going

on a quest of some

description, but

spend years building up a character, giving

it

a

collecting a large stash of cash.

RPGs (Role-Play Games), such as Ultima, used very simple graphics but proved highly successful, and some are still played today. Multiplayer RPGs have traditionally been text-based MUDs (Multi-User Dungeons), but some of the more recent games have been graphical, such as of the earlier

Ultima: Online

Card

and

EverQuest.

Gflm-ES

Everyone has played for

something

addictive;

I

to

be done or

These card games tend

Another highly

FreeCell.

is

on the phone with an annoying customer. Card games can become very get out of bed

if it

to

is

waiting

weren't for FreeCell

GfllYlE5 successful

out there has played of the

be played when the user

or

know some people who wouldn't

5FDRT5 Some

Solitaire

first

game genre

at least

the sports genre.

Here

in the

United Kingdom, every gamer

one soccer game, one racing simulation, and

games ever created

without any nets).

is

fall

at least

one beat-em-up.

into this genre (Pong being very similar to a

game of tennis

.

Game

Introduction to

Games such

as the

FIFA series are always

bestsellers,

Developitient

and with good reason. They bring out the

Many won (and many a

competitive instinct in the player and allow the user to kick ass without actually hurting anyone.

my brother challenged me he beat me up for winning)

a time

time

games are generally highly

Sports

friends.

People

like sports,

to a quick

addictive

and they

like

game of Actua

and can lead

them even more

Soccer,

to large if

and many a time

I

H

tournaments among groups of

they don't have to get injured in the

process.

WJ-H-HT IYlflK€B This

is

-H

5 UCC-E55-FUL

makes a game good, but

a tough question because everyone has different opinions about what

there are always

Nobody

some common

likes to play

pixel to the

a

factors. Successful

game where you have

J

GfllYIE?

games are always (and most important)

to type for ten

minutes just to get a square

to

playable.

move one

left.

The game also needs to have a user-friendly interface, with easy-to-navigate menus that get the player into the game as soon as it loads. Continuing from this, a good game should be very easy to learn but should take a lifetime to master. A good example of this criterion is Street Fighter. Anybody can play the game well, but very few are really good at it. This is because the game controls are intuitive; randomly hitting them allows even a new player to win a fight against a master. However, a master can learn the special moves and use them to their full effect.

Some games have overly complex control systems, such as Alien versus Predator. This game had too many controls to master before you could get into the game. This meant only a dedicated gamer could play it for more than five minutes without deleting it from the hard disk out of frustration. Having to constantly jump around the keyboard just to select a gun and fire it puts most players off for life. Another key requirement well to

run around

story

relevance to the

Good Till

some games (although not

killing ever)' goblin in sight,

second-cousin's pet cat?

background

to the success of

Or

story lines don't have to

but why are you killing them? Did they murder your

them because they are there to kill? Even a simple huge amount to the game's success, even if the actual story has no

is

be predictable

to

be interesting. Take, for example, the film From Dusk

about two criminals trying to get to Mexico, when suddenly, out of nowhere,

they are attacked by a hoard of vampires. This surprising twist

which the complete

plot twists have

Kil'rathi pilot

loyalty to the

who

done very well.

there

is

made

A good example

the film

of this

defected changes sides halfway through the

is

much more

interesting.

Wing Commander III,

story,

in

even though he showed

Terran struggle.

Sometimes, being a well-known game developer means that if

plot. It's all very

itself.

Dawn. Half the film

Games with sudden

good

a

are you just killing

can contribute a

game

all) is

nothing special about your project.

all

A good example

your games

will

of this condition

be a huge success, even is

Doom

2,

the sequel to

Linux

G-riyi-e

F-ROG-R-RiYinmNG

the highly successful Doom. There weren't any brand-spanking

new features or

their games. Doom game, but people like id software, price. People are more than willing to jump on any bugs in a game from a while a lesser-known developer might manage to sneak a few "inconsistencies"

in this sequel to the successful

However, fame has a successful developer,

a supersmart AI system

and they will buy

past the critics.

PRDCE55

T4H-E GflfYl-E-D-EV-ELO-FIYl-ENT Game

development,

process.

There are

like

any form of software engineering,

several stages to

go through

to get

isn't

a simple code-it-and-you' re-done

your game from the drawing board

to

being

played.

Design Ddcuiyient

T+h-e

A good design document is probably the

most helpful

tool for

any game developer.

It

helps you

develop a solid idea on which you can base your game. The design document can also help you get a publisher

if

What goes

you choose

into a design

going to use.

Some

the game; simpler

to write a

commercial game

(as

explained later in

document? Just about everything from the

this chapter).

story line to the

3D engine

you're

design documents are several hundred pages long and cover every single detail in

games can use shorter design documents. Even the

smallest

documents should

contain the following: •

General Overview. This section of the document covers the game story overview of the development timeline, and the development



the

main

characters, a basic

staff required.

Screen and User Interface. This section of the document covers the in-game menus, the in-game

(Heads-up Display) you might use, as well •

line,

as

any icons used

Art Specification. This section of the document

lists

in the

HUD

game.

any in-game artwork, cut-scenes, and

sprites.

Include

any appropriate storyboards and sketches. •

Sound and Music. talents the



game

All

will

sound

and music must be documented

in this section, as well as

any voice

need.

Technical Specification. This section covers

benchmarking you plan •

effects

how

the

game

is

going to run, including flowcharts and any

to perform.

Legal Information. This section includes the copyright and a disclaimer.

After you have written your design document, you should share

team so that they can give you feedback on your

ideas.

You

will

it

with everyone

on the development

probably get through several versions of

document before you all agree on what it contains, but that isn't a bad thing. The revision process will help form new ideas from old ones and might point out some serious problems that might the design

otherwise occur only later in the development process.

Introduction to

Develdfiyient

G«iyi-e

DeveLa-pmeNT After your team has agreed

Do you write

you begin?

Where

to start

fortunately,

One

is

on a design, you can

the

game engine

or the

one of the toughest choices

actually get to

menus

you'll

work on writing the code. But where do

And which

first?

have to make

when

or

of the best places to

where the program

fire

when

start

starts:

writing your

game

WTiere you go from there

up

is

allows

me

in the

development process.

fine

Without

use.

to you, but

at the

this vital part

like to

I

n

beginning.

on

a

team

that

exchange medium

if

everyone

is

you might want

to look into a

allows multiple developers to

go into further

detail

difficult to

it

add or modify features

E-mail

files.

later

is

a

working on completely separate parts of the program and you

How ever, T

if

you have problems with version concurrency System) repository.

work on the same problem by checking

CVS

I

need a way of sharing

will

CVS (Concurrency Versioning

about

don't

continue by developing the graphics engine. This

developing a large project, you

is

I

credits,

of the program, you can't do anything.

code the core of the game next, but does make

to

have a clearly defined interface to work with.

I'll

starting a

mean that you mean that you should where you prepare any variables you may need

is

the initialization routine

up any graphics APIs you

If you are

part of the

you have a design document.

should write the whole thing in order, from intro sequence to closing start

game engine? new project, but

options in Chapter

2,

files in

A CVS repository

and out of a

"repository."

"Linux Development Tools."

Testing One

of the most important steps in the development process

is

testing

your funky new game.

serious bugs

show up

Encounters

a good example of incomplete testing resulting in a buggy release (although

is

after

place the whole blame

and

several

you release the game, your reputation

on the developers). Because of a

major bugs caused serious problems

reputation of the developer, even though

There are

several stages to testing

testing phases.

and

The Alpha

the general

about

it.

who

try to

If

anv

II: First I

program wasn't

can't reallv fullv tested

game. These bugs seriously damaged the

had created

Elite,

one of the most popular games

ever.

Gamma

is

find any of the hidden bugs;

game playing community.

WTien you do, you

tight deadline, the

Frontier

done by the developers, in which they fix any obvious bugs the code. Beta testing is performed by a third partv (usuallv a

testing stage

will try to

in the

be ruined.

your game, commonly referred to as Alpha, Beta, and

glitches they find wiiile writing

dedicated gamer)

it

will

When

a

bug

is

found

finally,

in the

Gamma testing is performed by

game, chances are you

reproduce the problem and then generate a patch

will

hear

to fix the

program.

When you

it

comes

to jump to

points)

,

to testing,

one of the most

useful tools

you can create

is

a

debug

cheat.

A cheat allows

any part of the game, gives you any extras you need (such as cash, weapons, or bonus

and can

save you hours of time. Because

all

cheats are

IT

removed before the game

is

released

Linux

G-riyi-e

(honest), there are

FROGRfHYinniNG

some funky

tricks

you can use

enable or disable them at compile time using

to

preprocessor directives. If

your compiler allows a flag to add a symbol

type,

at

compile time, you can use that flag

depending on whether the code you are compiling

is

a

debug or

to specify a release

release version of the

game. For

example, you can include the following code in your game program. //

test.c

//include

main

(

)

{

#ifdef DEBUG puts("This

is

a

debugging version!");

is

a

release version");

#el se (

puts

#endi

"

Th

i

s

f

}

If

you then compile the program with the following

This

is

command and

run the program, you should get

the release version.

gcc -o testl test.c However,

if

command,

you include the -DDE BUG option on the the

program

will

output the line This

command is

line, as

shown

in the following

debugging version!

a

gcc -DDEBUG -o test2 test.c This trick allows you to add cheats using

you are ready

to

release the game,

if

#i fdef

blocks of code. You can then turn off the cheats

you wish. You can

also

add simple debugging statements

when

in #i

fdef

blocks to track the program flow without the use of an external debugger (as discussed in Chapter 2).

R-EL-E-R51NG YOU-R GfllYl€ After you have tested your

choices about what to

do

game

as

much

at this stage,

as

and

I

is

humanly

will discuss

possible,

you can release

it.

You have

several

three of your options here: OpenSource,

commercial, and shareware.

DP€N5DURC€ OpenSource want people

is

GfllTlEB

probably the simplest and quickest route to getting your games on the market.

to play

your game as soon as possible, you can release the game while you're

Not only does this approach

let

people know your game

other people work with you to help

improvement.

fix

exists

long before

it's

finished,

it

still

If

you

writing

also lets

any problems they may find or to make suggestions for

it.

lNT-RODUCITION TO G-RIYie D€V€LDPIYI£NT

The OpenSource route approach can speed up be ported

will

means

also

the development process

to other operating systems

Although many people claim that has been proved false too

many

number of testers working for free. This dramatically and might even mean that your game

that you'll have a larger

by third

parties.

make any money out of OpenSource software, this Companies such as RedHat and SuSE have made a

impossible to

it is

times to count.

huge success out of distributing OpenSource

and printed

software for years by offering support

NOTE

manuals.

The is

to

first

step to releasing an

make

it

Make sure

OpenSource

project

license just because everyone else

publicly available, including the

source code. After you have

made

everyone to get your program, make an

announcement on a few mailing

lists

and on

such as Freshmeat (http://freshmeat.net)

is

Read through several licenses (printed versions of which can be found in the back of this book) and choose the one you agree with the using

possible for

it

that you don't choose a

sites

it.

most.

.

FRE5HrYl£flT: HTTf='!//FRe5HrYieflT.NeT

made your announcement, expect input from users within a very short period of time. Some may have patches, others may have criticisms, and others may need help using your game. It is

After you have

good

practice in the

OpenSource community

product; doing so will help you gain a

CammERciflL Many

name

companies such Getting a

as Loki have

made

a

is

is

name

OpenSource community.

a viable option for commercial software, including games. for themselves by porting successful games; other

as Epic (Unreal) are also starting to

game published commercially

The process

for yourself in the

messages you receive regarding the

G-riyi-es

developers have realized that Linux

Companies such

to reply to all e-mail

is

develop games specifically for Linux machines.

not the easiest thing to do, especially for die Linux platform.

long and complicated, involving several contracts,

and tough milestones. However, the rewards

far

fame encourage many independent developers

To

get published,

see

what publishers are out

you must

first

costs.

(Non-Disclosure Agreements),

Cash advances, high

to strive for bigger, better,

approach a publisher. Look around

there.

packaging of the products you'll

outweigh the

XDAs

at

and

faster

your local

rovalties,

and

games.

Electronics Boutique to

Names and sometimes addresses of games publishers appear on the Be aware that many publishers such as Electronic Arts have in-

see.

house development teams and refuse unsolicited submissions. Look for companies that publish games

from a wide range of developers, such

as

GT Interactive

and

ActiVision.

When you

have determined

who you want to publish your game, request a submission pack from the publisher. This packet will contain an NDA, which protects all parties involved from any legal problems that may arise (for example, plagiarism).

Linux

CE-fhyi-e

P-RDG-R-RmmiNG

When you have returned the NDA with demo of your game the publisher will



you down, don't If the

give up.

Keep

your completed design document tell

trying until

you whether

it is

—and hopefully a working

interested in your submission. If

turns

it

you get a new publisher.

publisher approves your game, negotiations

will

begin.

It

might be a good idea

to contact a

lawyer because legal documents will be involved; unless you are fluent in legalese, the contracts will

probably be a

bit confusing.

A good guide

to getting

You can find the guide

your games published has been written by Geoff Howland of Lupine Games.

at http://www.lupinegames.com/articles/getstart.html.

Guide to Getting Your Games Published: HTTA "//w WW. LUfllNeGflme5.COM/flflTICLe5/GeT5TflRT.flTmL

G-nmes

5+Hfl-R-Eui-H-R-E Another option when successful

games

shareware

is

ever,

comes

it

to releasing

your game

is

the shareware route.

such as Doom and Quake, were released

very similar to releasing a

game

in the

initially as

OpenSource

distribute the source code. (Note, however, that id software has

although

You have

several options to

in

some way (such

shareware. Releasing a

route, except that

now made

game

as

you generally don't

the source code to Quake

choose from when making your game shareware. You can use an honor

system and ask the user to pay you after a certain

game

of the most

requires a license for the in-game data.)

available,

it still

Some

amount of time has

elapsed, or

you can

as only including the first few levels) until the user has paid

you

restrict the

for the

complete version.

how you're going

money from the users, you have to set a price ($20 is usually a good start) and add a message to the game letting the users know where they have to send the money. In games such as Doom and Quake, a message was displayed when you quit the game, giving the user registration details. Some games use pop-up messages during the game to get the shareware

After you have decided

message

across.

When

comes

it

the cover sites

to distributing

CD of your favorite

to claim

your game, you have several options. You can magazine, or you can upload

it

to the Internet

try

and have

it

TUCOWSl HTTA '//wWW.TUCOWS.COm

on

and have some download

such as Tucows (http://www.tucows.com), sending random surfers to get your game.

possibilities are endless.

stuck

The

CHAPTER

2

Linux Develdfiyient

Tools

-ol !:.^S/fts3tlw -Jlj—l

'5»»*Z!5

3

Linux Gaiyie FRDGRflmiYnNG

nl

Just as every plumber needs a plunger and every surgeon needs a scalpel, game developers have need

certain tools they

to create the

environments to debuggers and successful

game

next

hit

games. These tools range from development

profilers. In this chapter, you'll learn

what types of tools make up the

developer's toolkit.

Develofiyient Tools You

use several key tools

will

and version management utilities

into

when you write any software, including compilers, interpreters, debuggers, Some tools, such as KDevelop, integrate all of these

tools such as make.

one environment.

Cdiyifiler The most important

tool

you

bikini in the Arctic Circle.

need

will

is

a compiler. Without one, your code

Although some languages such

need an interpreter of some kind. Because the code

GNU C compiler,

GNU

C

GCC,

COnflPlLGR:

Compiling with the code

available

book

is

strictly

written in C,

as useful as a

compiled, you I

will

focus

will

still

on the

HTTf '//uJUJUJiGNUiORG/5a>screen->format->Gshi ft

)

&

OxFF;

b

=

)

&

OxFF;

(pixel >>screen->format->Rshi ft) & OxFF;

(

pixel >>screen->format->Bshi ft

Lock the surface and work out where to plot the pixels

//

SDL_Lock(surface)

;

bits = ((Uint8 *)surface->pixel

s

)+y * surface->pi tch + x * surface->format

>BytesPerPi xel // *

(

* *

(

PI

ot the pixel

b

ts

i

)

+ screen->format->Rshift/8) =

r;

(bits) + screen->format->Gshift/8) = g; (bits) + screen->format->Bshift/8) = b;

// Unlock the surface SDL_Unlock(surface) ;

Although SDL_MapRGB( SDL_MapRGB(

memory If

),

so this

)

is

does not work with 24-bit

per pixel for alpha. This

is

useful

you are using alpha, the SDL_MapRGB(

yourself, using a

method

)

if

you want

void

ot32(SDL_Surface ^surface, int b,

depths support the use of

32-bit color

depth has an extra byte of

have a transparent surface. it.

You

will

need

to calculate the pixel

very similar to that for calculating the pixels for 24-bit colors.

shown here demonstrates how

PI

to

The

function won't cut

function

Uint8 *bits; Uint8 r, g,

color, 32-bit color

a very simple color depth to use.

a;

to calculate the pixel.

x,

int y.

U

i

n132

pixel)

{

The

PI

ot32(

Linux

F-ROG-R-HmmiNG

Gfliri€

r

Prepare the components = (pixel >>screen->format->Rshi ft

&

OxFFr

g

=

//

>>screen->format->Gshi ft

&

OxFF

b = (pi xel >>screen->format->Bshi ft

&

OxFF

= (pixel >>screen->format->Ashi ft

&

OxFF

a

(

pi xel

Lock the surface and work out where to plot the pixels

//

SDL_Lock( surface) bits = U n 1 8 *)surface->pixel ;

(

(

i

s

)+y * surface->pi tch + x *

surf ace- >format->Bytes Per Pi xel Plot the pixels

// *

(

(bits) + screen->format->Rshi ft/8)

*

(bits) + screen->format->Gshi ft/8)

*

(bits) + screen->format->Bshi ft/8)

*

(bits) + screen->format->Ashi ft/8)

//

Unlock the surface

SDL_Unl ock( surface);

Plotting

-Pixhels

After you have worked out the format for your pixel, you can plot

it

to the screen. Before

you do

however, you'll have to lock the surface to prevent other parts of the program from accessing

an issue only

if

your program

is

multithreaded, but

SDL

it.

this,

This

is

requires you to lock the surface whether or

not your program uses threads. SDL_Lock(

)

takes only

one parameter: the address of the surface

otherwise, you should use SDL_GetError(

When

)

to see

to lock.

On

member called

pi xel s

To work out the exact

do

if

your math

that contains the actual

it

returns

0;

what went wrong.

you have locked your surface, you must then calculate the address

necessarily the easiest of things to

success,

isn't

up

to scratch.

to

draw

to.

This

The SDL_Surface

isn't

structure has a

image of the surface.

location of the pixels you want to plot,

you need

to

know how many

bytes of

memory are between each horizontal line. You can calculate this value by using the color depth and the pitch member of the surface definition. The exact formula for working out the location of the pixel follows (it may be worth making a little macro for this): offset =

Y

*

pitch +

X

*

bitdepth

;

ZD

Here

the

is

same formula

more

in a

Under Linux

useful form:

address = ((Uint8 *)surface->pixel

s

+

)

surface->format->BytesPerPixel

*

GRfiFfncB

Y

surface->pi tch +

r

X

;

n

When you memory

have calculated the address of the pixel you want to plot, you can then

to the color

(^address

value in

you desire with the following command.

CL

After you have plotted the pixel, you

plotting

its

= col or;

)

SDLJJnl ock(

set

)

must unlock the surface with SDLJJnl ock(

).

As does SDL_Lock(

),

takes a single parameter: the address of the (locked) surface to unlock. If you are

more than one

you may want

pixel,

to wait until

you have finished drawing your scene before

you unlock the surface.

Using Falettes If you

are unfortunate

your game. Luckily,

The

enough

this

is

to

be working

a simple task.

function SDL_SetCol ors(

is

)

The

used to

in 8-bit color, 8-bit

video

you might need

modes support up

to create a color palette for

to

set the color palette. It takes several

pointer to the color palette, the starting color index, and the

number

256

colors.

parameters: a surface, a

of colors. Here

is

the prototype

for the function:

extern int SDL_SetCol ors(SDL_Surf ace ^surface, SDL_Color ^colors, i

nt

The

firstcolor,

col or s

int ncolors);

argument simply points

to

an array of type SDL_Col or that contains the palette

information. SDL_Col or has four members:

unused

member

is

r, g, b

(red, green,

and

blue, respectively),

and unused. The

reserved for future expansion, so we'll ignore that.

The recommended way of using SDL_Col or is to allocate (sizeof (SDL_Color) * ncolors) bytes of memory for the array. After you have allocated enough memory, you set the values for the palette. Each component can have a value up to 255 (OxFF). The following sample code demonstrates how allocate a grayscale palette.

SDL_Color *colors; SDL_Surface ^screen; int

i

;

// Allocate the memory colors = (SDL_Col or*)mal si

zeof (SDL_Col or

)

)

1

oc( screen->format->pal ette->ncol ors *

to

Linux Gaiyie PRDGRflminiNG

Set up the palette for (i = 0; < screen->format->pal ette->ncol ors //

i

colors[I]->g = col ors[

] I

->

.

i;

->b =

] I

col ors[

i++)

;

i

Jl

Set the palette

//

SDL_SetCol ors( screen

If

you look

at the

,

colors,

screen->format->pal ette->ncol ors

0,

preceding example, you

will

)

notice the use of screen ->format->pal ette. This

is

a

pointer to the current palette for the surface (in this case, the screen). Every surface has such a palette,

and these

The most

palettes prove useful for several things.

second

available for a surface; the

is

useful

is

to find out

how many

colors are

to get the current palette.

The The

SDL_Pal ette (which the SDL_Surface>format>palette pointer refers to) contains two members. first is

number of entries

the

in the palette, the

second

is

a pointer to an array of type SDL_Col or.

SDL_Col or array contains the specifics of the current palette.

Cleaning When

comes time

it

allocated

is

to quit

freed. This can

never introduce a

memory

Earlier in this chapter,

when your program exits. It is also called

However,

U-p

it is

good

I

your program, you must make sure that every single byte of memory

be a pain

if

you are taking over someone

leak into your

own

code). Fortunately,

mentioned the SDL_Qui t(

exits.

)

all

(I'm sure you'd the cleanup for us.

memory allocated by SDL when

call

it

the program

signal (such as a segmentation fault or a user interrupt).

practice to free any

memory you've

allocated yourself, instead of leaving the

cleanup process to the API. There are several functions for allocated yourself)

handles

function and noted that you should always

This function cleans up any

on the event of a

else's project

SDL

and SDL_FreeSurface(

)

this,

such as

f

ree(

)

(for

memory you've

(for surfaces)

T+he Xi_ie -H-Fl If

you want

to

do raw

X programming, you

application that doesn'l require

all

need

to see a psychiatrist or

you want

to write a simple

of the functionality and overhead of a larger API such as SDL.

you're going to program in X, you'll want to understand the basics of X graphics (a

graphics I

is

as

.

basics of

If

discussion of

coding for X.

SDL before covered Xlib because Xlib is more complicated than SDL. In my opinion, you SDL to do just about everything you could ever want to do in X except for a few things such

covered

can use

way out of the scope of this book) The next few sections cover the

full

X

I

changing the resolution.



X

)

,

ED

Creating

Under Linux

G-R-Hf^+Hics

H-l

LUtndouu

-h

The first thing you must do when opening a window under X is to tell it where the screen is. The X Windowing System uses a client/ server architecture, and one machine (the client) sends the window to a different machine (the server) Although there are several ways of telling the client where the

r

1

.

server

is,

the most foolproof way

The DISPLAY

variable takes the

address of the

X multiple

X server,

is

to use the DISPLAY

environment variable.

form :, where

and

is

is

the

name

or IP

the server to use. (Note that a single machine can run

times.)

J

X server.

It

takes

using the display format described above, or NULL to use the default.

It

returns a pointer to the display

The function XOpenDi (of type Display)

When you

on

spl ay

)

makes the connection

success, or NULL

have a pointer to your

Defaul tScreenOfDi spl ay(

found using the XOpenDi

on

(

success, or NULL

on

)

error. is

)

)

You

display,

string

you need a screen. You can find your screen using the

one parameter: the pointer

function. Defaul tScreenOf Di spl ay( also

one argument: a

error.

function. This function takes

spl ay(

function. Defaul tScreen(

on

to the

must find the screen you

will

)

to the display

we

returns a pointer of type Screen

be using with the Defaul tScreen(

almost identical to Defaul tScreenOfDi spl ay

(

)

except that

returns

it

an integer.

Now

that

we have a

actually create the

display,

a screen, and a screen (Xlib coding

is

quite pointless at times),

window. You create the window using the XCreateSimpl eWi ndow(

(Although you can use XCreateWi ndow( XCreateSimpl eWindow(

is

)

is

infinitely

function.

)

more complicated.) The prototype

for

shown here:

Window XCreateSimpl eWi ndow( unsigned int width,

doing so

),

we can

Di spl ay

^display, Window *parent,

int x,

unsigned int height, unsigned int border_width

int y,

,

unsigned long border, unsigned long background);

The first argument, di spl ay, is the pointer to the display we got using the XOpenDi spl ay function. The next argument, parent, is a pointer to the window that is opening the new one. If this is the first window the program is opening, you must use the RootWi ndowOf Screen function. This function takes (

(

one argument: the pointer

The next four arguments specifies the

border.

The

The next

to the screen

we got using

are the location

and

size

width of the window border in pixels. last

step

is

parameter, background,

using the XMapRai sed(

).

The border_width argument

The next argument,

border,

is

the color of the

simply the background color of the window. )

.

)

(

window using the XC1 earWi ndow( function. This function takes two and the window to clear (in that order) Finally, you must raise the window function, which uses the same two arguments as XClearWindow( ).

to clear the

arguments: the display

is

)

Defaul tScreenOfDi spl ay

of the window.

)

Linux Gaiyie PRDGRflmnmNG

The

following sample code demonstrates

how

to

open

a

window

in X:

Xsamplel.c ^include //

int main(

I

)

{

Display *di splay; Window window; Screen *screen; int myscreen;

char *display_str = (char *)getenv( "DISPLAY"

)

display using the environment variable = display XOpenDi splay(di spl ay_str) screen = Defaul tScreenOfDispl ay(displ ay // Open the

)

myscreen = Defaul tScreen(displ ay

)

Open the window window = XCreateSimpl eWindow( //

di spl ay 0,

,

RootWindowOfScreenC screen)

0.

320,

200,

BTackPixel (display

1,

WhitePixel (display XC1 earWindow(displ ay

,

,

Defaul tScreen(displ ay)

Defaul tScreen(di splay

window)

,

do something

//

Cleanup

XC1 oseDi spl ay(displ ay

return

gcc -1X11

Black border

// White

The getenv( ) function in this example returns NULL in the event that the environment variable is not found. The XOpenDi spl ay ( ) function uses the )

default display (usually 0:0, 1;

this

program, use the following

-L/usr/XllR6/lib

background

NOTE

first

To compile

//

;

XMapRai sed(di spl ay .window) //

) ) )

-

command

meaning the

X server of the local machine).

line:

I/usr/XllR6/incl ude -o Xsamplel Xsamplel.c

1

,

ED Grafhicb Under

TO

D-R-HUU1NG The Xlib to do,

BCR

T+H-E

N

routines for drawing graphics are relatively

you have a range of functions from which

Linux

Depending on what you want

straightforward.

(!)

to choose.

start

I'll

with the simpler ones, such as

n

drawing text to the screen.

Plotting

-n

-Fix-el

The easiest thing to do when doing any graphics is usually plotting a pixel. This rule also applies to programming in X, but because it is X, plotting a pixel still isn't the easiest thing in the world to do. Before you can draw anything, you must

including "drawables" and graphics

initialize several items,

contexts. I'll

start

used in

by describing the Graphics Contexts (GCs for short). These are

SDL and

more

are even

function to create a

GC is

similar to Device Contexts used in

XCreateGC(

); its

prototype

unsigned long valuemask,

is

true for

server.

is

other drawable object). description itself

is

draw on

(in this

example,

The next parameter

in the Xsampl el

After you have set

d

to

know about the machine running the X The next argument, the drawable,

is

a

it's

the window, but

mask of which

it

is

could be a pixmap or any

values are used in the description; the

the final argument. )

as well as the XGCVa

The only mask value we need to plot a pixel chapter. To set a color, use the [Col or] Pixel demonstrated

here:

passed using the di spl ay argument.

masks for XCreateGC(

available

shown

like the surface definitions

Windows programming. The

XGCVa ues* gcv);

most Xlib functions, XCreateGCO needs

This information

the "surface" you want to

The

is

Drawable

extern GC XCreateGC(Di spl ay ^display,

As

up your

.

ue

member they refer to are shown

GCForeground

is (

1

)

;

in Table 4.3.

the other masks are covered later in this

functions, such as

Bl

ackPixel

(

)

or WhitePixel

(

),

as

c code, earlier in this chapter.

GC descriptor,

call

XCreateGC(

)

to create a

new Graphics

Context.

Now you

can draw pixels to the screen (or use any other graphics operation that requires a GC) You can use .

the function

drawable, a

XDrawPointO

to plot single pixels.

GC, and the window coordinates,

as

XDrawPointO takes

shown

extern int XDrawPointCDi spl ay* display,

Now

it's

five

parameters: a display, a

in the following function prototype:

Drawable

d,

GC gc,

int x,

time to put the theory into practice. Take the sample program Xsampl el

following lines just before

GC gc;

XGCValues gcv; int x

,

y

;

lr

we

initialize

X to enable

us to draw something

on the

.

c

int y,

);

and add the

screen:

MMMMHMI^H

Table 4.3 Graphics Context Value Masks XGCValue Member

Description

GCFuncti on

function

Logical operation

6CP1 aneMask

plane_mask

Plane

GCForeground

foreground

Foreground color

GCBackground

background

Background color

line_width

Width of

GC

Li

newidth

GCLineStyl

ine_style

mask

line

Style of line (Li neSol

i

d,

LineOnOffDash, LineDoubleDash)

GCCapSize

cap_size

End

style

(CapNotLast, CapButt,

Cap Round, CapProjecting) GCJoi nStyl

join_style

JoinMiter, JoinBevel.orJoinRound

GCFillStyle

flll_style

Fill Sol id, Fill Tiled, Fill Stippled,

or

Fi

lOpaqueSti ppl ed

GCFillRule

fill_rule

EvenOddRul

GCTile

tile

A pixmap

GCSti ppl e

stipple

I

e,

Windi ngRul

for tiled

bpppixmap for

fills

stippled

fills

eStipXOrigin

ts_x_origin

Offset for

tile

stipple operations

GCTileStipYOrigin

ts_y_origin

Offset for

tile

stipple operations

GCFont

font

Default font for text operations

GCSubwindowMode

subwindow mode

CI

GCTi

i

pByChi

1

dren or

Incl udelnferiors

GCGraphicsExposures

graphics_exposures

Boolean, should exposures be generated

GCC1 ipXOrigin

clip_x_origin

Offset for clipping region

GCC1

i

pYOrigin

clip_y_origin

Offset for clipping region

GCC1

i

pMask

clip_mask

Bitmap clipping (pixmap)

GCDashOffset

dash_offset

Patterned/dashed

GCDashLi st

dashes

Data for dash

list

line

information

;

,

,

2D

In addition,

where the

original

has the

file

comment

Ca-R-H-p+mcs

Under Linux

saving "do something", insert the following code:

Describe the context we want

//

gcv foreground = BlackPixel (display, myscreen); .

Create the context

//

gc = XCreateGC(di spl ay

window,

,

GCForeground &gcv)

;

while (1) = rand(

x

y =

)

%

320;

randO

I

200;

Draw the pixel

//

XDrawPoi nt(di spl ay

window, gc,

,

x,

y)

Free memory

//

XFreeGCCdi spl ay

The above code simply

gc);

,

fills

the screen using

random

black pixels.

D-RAU11NG IfYlflGES Now that we isn't really

can plot single pixels in X,

suited for

games work quite

well in X. Several popular

display.

games have been

and resemble standard C header

The

little its

1

e(

)

loads an

function prototype

extern int XReadBi tmapFi

1

.XPM is

file

files

and

more

exciting.

Although Xlib

own, simple sprite-based

written along these lines, such as Xbill

X Windowing System uses a format called .XPM

function XReadBi tmapFi

your

time to do something a

programming ultra-high-performance games on

For simple images, the are quite simple

it's

(X PixMap). The .XPM

The standard pixmap that you can use on

(they can, in fact, be used as header

creates a

files

files).

as follows:

e( Di spl ay*

display,

Drawable

_Xconst char* filename, unsigned int* width_return bi tmap_return unsigned int* height_return Pixmap*

d,

,

,

int* y_hot_return

The

first

int* x_hot_return

)

two arguments are the display and the object you plan to draw the image on.

argument to

,

is

the path

and filename of the pixmap you want

where information about the image

is

going to be stored.

to draw.

The next

The other arguments

are pointers

Linux Gaiyie -P-RDG-R-HmmiNG

After you have loaded the pixmap, you can draw is

i

shown

it

using the XCopyPl ane(

)

function,

whose prototype

here:

extern int XCopyPl ane(Di spl ay* display, Drawable src,

n

int src_x, i

nt dest_y

int src_y, ,

i

nt depth)

Using XCopyPlane()

is

Drawable dest, GC gc, unsigned int width, unsigned int height, int dest_x, ;

pretty straightforward.

As with other

X functions, you must pass the pointer to

the display. You also must specify two drawable objects (the source and the destination).

L

parameter

is

a standard GC, which you can create by calling XCreateGC(di splay,

The next

window,

0,

The next four arguments describe the dimensions of the source image, and are followed by destination coordinates. The final argument is the color depth of the source image. The

following sample code demonstrates the use ofXCopyPlaneO.

definitions section at the beginning of the original Xsampl el

.

Add

NIL).

the

the following code to the

sample, shown earlier in this chapter.

c

Pixmap pic; GC gc;

r

XGCValues gcv; int x

,

y

height,

int width,

hoty;

hotx,

int err;

char *FILE = "/usr/share/pixmap/cl ock.xpm"

Now,

in the original Xsampl el

Compile the //

file as

.

c

;

code, replace the "do something"

you have done before and run

comments with

it.

Prepare the context

gcv foreground = BlackPixel (display, myscreen); .

gcv graphics_exposures = 0; .

gc = XCreateGC(di spl ay

//

if

,

Load the bitmap ((err = XReadBitmapFi

window, GCForeground

1

e(di spl ay

,

,

&gcv);

window,

FILE,

&width, &height, &pic, &hotx,

&hoty)))

{

XC1 oseDi spl ay(di spl ay)

fpri ntf stderr

,

"Can't load image: %d", err);

this last bit

of code.

;

ED

while (1)

Gr-h-p-hics Und-e-r

Linux

47

{

randO randO

x

y

%

320

%

200

If

1

XCopyPl ane(

display, pic,

//

Source image

window, gc,

//

0.

//

Destination details Source origin

//

Dimension of image

//

Destination coordinates

0,

width, x,

y,

height 1);

I ]

}

Free the memory

//

XFreeGC(di spl ay gc); XFreePixmap(di spl ay pixmap) ,

,

r

Double Euffering Drawing

when

it

flicker

directly to the

needs

is

window has

several drawbacks, including having to

be done and putting up with flickering

to

Copying objects XCreatePi xmap(

in ),

X is stupidly simple.

when First

everything

is

tactic in

to

avoiding screen

an off-screen object and

drawn.

you create an exact copy of the window using

and then you copy the newly created image

achieve the second part of this process, use XCopyArea(

shown

A common

double buffering. This process involves drawing everything

to use

then copying that object to the window

are

sprites.

redraw the screen manually

).

The

to the

window whenever you need

to.

To

function prototypes for these functions

here:

extern Pixmap XCreatePixmap(Di spl ay* display, Drawable d, unsigned int width,

unsigned int height, unsigned int depth); extern int XCopyArea(Di spl ay* display, Drawable src, Drawable dest, GC gc, int src_x,

src_y,

int

int dest_y

)

XCopyArea(

)

is

except that

it

unsigned int width, unsigned int height,

almost identical in functionality to XCopyPl a ne(

has no depth argument. Because you do not

)

int dest_x,

(described in the preceding section),

specify'

the color depth of the area, you must

be sure that both drawable objects have the same color depth, or a BadMatch error

program

will

will

occur and your

terminate.

XCreatePi xmap(

)

is

a relatively simple function to use.

creating an off-screen window.

The

following example demonstrates

its

use for

Linux GflmE PRDGRfliYiiniNG

H-B

Create the double buffer Pixmap dbl_buf = XCreatePixmap(di spl ay //

ndow_width wi ndow_hei ght Defaul tDepth(di spl ay myscreen));

wi

,

window,

,

,

,

//

Dimensions of window

//

Color depth

h After you have created the double buffer, you use that object as the drawable surface instead of the

window.

When

code for doing

it

comes time

this

is

to display

to the

window. The

presented here.

GC gc = XCreateGC(di spl ay

XCopyArea(di spl ay wi

what you have drawn, you copy the buffer

ndow_width

0,

NIL);

dbl_buf, window, gc,

,

wi

,

window,

,

ndow_hei ght

0,

,

0,

0,

0);

Installing Color M-r-fs If

you are working

color

map

only

if

in

an

8-bit color

you are using

depth, you might want to set

If

number

color

map

)

RGB

To detect

indexing.

function, which takes the display

and the

(myscreen in the samples) as arguments.

the color depth being used

own

color map. You need a

because any other color depth uses

8-bit color

the color depth being used, you can use the Di spl ayDepth(

screen

up your own

is

8-bit color,

using XCreateCol ormap(

).

you may have

An example

map. You can create your

to install a color

of this function

is

shown here:

Colormap c_map = XCreateCol ormap(di spl ay window, Defaul tVi sual (di spl ay myscreen), AllocNone); ,

,

After you have created your color map, you definition of type

X

Col or. This data type

contains

members

member

called pixel that

When you argument

of the color

map

The

step

first

is

to create a color

similar to the SDL_Col or data type discussed earlier;

color (red, green,

and

it

blue), as well as a

the color index.

have defined the color, you for this function

to assign the colors.

component of the

that describe each is

is

need

is

the

now

call XA1

1

ocCol or(

)

to include

it

in

more-than-familiar display pointer.

you created using XCreateCol ormap(

).

The

final

your color map. The

The next argument

argument

is

is

first

the ID

a pointer to the color

definition.

extern Status XA1

1

ocCol or(

XColor* screen_i n_out

Now

that

Di spl

).

The second argument parameter

is

Colormap colormap,

)

you have created a color

XSetWi ndowCol ormap(

ay* display,

map

(in theory),

you need

to install

This function takes three arguments, the

is

the ID of the

the ID of the color

map

window

itself.

in

which you want

first

it

with the function

being the usual display pointer.

to install

me

color map, and the final

1

ED

The

G-R-R-p-Hics

Und-e« Linux

following sample code demonstrates the installation of a color map: // Create the color map Colormap c_map = XCreateCol ormap(di spl ay DefaultVisual (display, my screen)

\

window,

,

,

Al

ocNone)

Install

//

an

1

;

I

entry

XColor red; =

red. pixel

1;

red. red = OxFF; red. green = 0;

red.bl ue =

;

ocCol or(di spl ay

XA1

1

//

Set the color map

c_map, &red);

,

XsetWindowCol ormap(di spl ay

Now that we map,

call

window, c_map);

,

have our brand-spanking-new color

the XSetForeground(

),

which

map

we might as well use it. To use the color of pixels, and XSetBackground( functions.

installed,

specifies the color

Each of these functions takes three parameters: a pointer

)

to the display, the

GC to change,

and the

color index.

Cleaning When

it

comes time

Ever)' object

U-p

to exit

you create

your superb new

X Windows game, you'll

must be destroyed using the Xlib

created with XFreeWindow(

),

destroy any

GCs with

XFreeGCC

function for the object you created, you can destroy

When you

have freed the

memory used by To do

familiar display pointer as

single argument.

its

it

),

and so on.

A long time way its

there

isn't

a specific )

function.

use the XC1 oseDi spl ay

(

)

function, which takes the more-than-

__

,__,

1

CAUTION -H-Fl

SVGAlib programs must be run

as

root, or suid to root, because they

ago,

SVGAlib was just about the only

to write fast-paced

reign of suid-terror,

games under Linux. Since other APIs have been

introduced, such as SDL. These newer APIs

X a viable

If

using the general-purpose XFree(

]

The 5VG-Hi_ie

have to clean up a few things.

You should destroy any windows you

the various objects in your program, you must then close

the connection to the server.

this,

.API.

platform for games, but

some

make

users

require direct access to the hardware.

This can

mean people may be

able to

exploit bugs in your software to

promise system

security.

com-

Linux Gaiyie FROGRfliYimiNG

5D

choose not to run X. Some of those users

like to play

games, but their systems may not be capable

X Windows.

of running

5UU1TC-H1NG TD Jn

still

-H

G-R-H-F+H1C5 [YlOD-E

The first thing any SVGAlib program should do is set an appropriate graphics mode. The first step down this path is to initialize the SVGAlib by calling vga_i ni t( ), defined in the header file vga h. This function starts up the SVGAlib subsystem and then surrenders root privileges. .

If

the function

call is successful,

vga_i ni t(

)

returns

0.

Assuming

problems, you can then switch to a graphics mode. Personally, available before

I

try to switch to

the symbol for the video

the

mode

is

As soon

,_!

resolutions.

On

as

mode you want

non-zero value

is

to take. Table 4.4

success,

).

that vga_i ni t( like to

)

was called with no

check whether a

shows the different video modes

returned; otherwise, the function returns is

available,

)

VGA

mode

you can

call

available. If

0.

vga_setmode() to change

the resolution (specified in Table 4.4).

Modes

Name

Resolution

TEXT

Standard text

G320x200xl6

320x200 16-color

G640x200xl6

640x200 16-color

G640x350xl6

640x350 16-color

G640x480xl6

640x480 16-color

G320x200x256

320x200 256-color

G320x240x256

320x240 256-color (mode X)

G320x400x256

320x400 256-color (mode X)

G320x480x256

320x480 256-color

G640x480x2

640x480 monochrome

mode

is

This function takes a single parameter:

The vga_setmode( function takes one parameter: it returns 0; on failure, it returns -1.

Table 4.4

A

by calling vga_hasmode(

you know that your chosen video mode



I

available, a

it

I

(original

console mode)

.

ED

When your program assign

quits,

own console

its

a

TO

up your video mode, you

recommended double There are two ways thing.

The

first is

to

vga_setmode(TEXT) in case vga_init(

will

7

directly to the screen using

draw

SVGAlib

directiy to the screen with SVGAlib,

vga_getgraphmem(

)

to find the start location of the video

memory is verv similar

*(graph_mem + (y

c)

y,

to direct access

following sample code demonstrates

how

*

start

WIDTH + x)) =

•//define

WIDTH

•//define

PLOTU, y,c)

)

320

*(graph_mem +

Initialize SVGAlib

if

(vga_init())

*

{

puts( "vga_ini t(

//

(y

{

//

return

)

error");

1;

Check if mode is available

!vga_hasmode(G320x200x256)) puts("Mode not available"); return 1;

if

(

//

Change the mode

if

(vga_setmode(G320x200x256) putsC'Can't change mode."); return

don't

1;



to the

same

that

we can ignore

the

memorv:

c

change the resolution and draw a pretty pattern

to

VGAsamplel.c

main(

I

memory, and the

how' to draw a pixel to

the screen:

•//include

And

of the \ideo memory.

under SDL, except

to

//

it.

as easy as pie (even with the

is

and they both equate

graph_mem pointer, which already points to the

The simple macro shown here demonstrates

The

I

fl

probably want to draw something on

pitch variable.

PLOTU,

wasn't able to

using one of the standard console devices.

is

Drawing pixels

•//define

)

buffering)

to call

to use the

is

to call

Under Linux

5CREEN

T-H-E

blame you. Fortunately, drawing

second

good idea

device for output and

D-R-HUU1NG After you have set

it is

G-R-Hf'-Hics

{

-1)

WIDTH + x)) =

c

to

Linux Gaitie f*ROG«flmnn

graph_mem = vga_getgraphmem( // Draw some pattern

1

)

for (x = 0;

x < 320; x++) for (y = 0; y < 200; y++)

Jl

PL0T(x,y,x return

this

gcc -lvga

-o

the

sample program, use the following command:

VGAsamplel VGAsampl el

program has compiled,

VGAsampl el

"

y);

0;

To compile

When

A

.c

either run "chown

root VGAsampl el" followed by "chmod 4755

while logged in as root, which enables any user to run the program by setting the suid bit

of the application, or run the program from a root

shell.

DlS-PL-HYlNG 1m-RG-E5 SVGAlib doesn't have

built-in

support for image

so you'll

files,

function library to load and display images. In these examples, display) a

PCX file,

but

if

you want

functions to load a different

file

UND-E-R STANDING PCX files use

to use another image

file

need

to

implement your own

demonstrate

I'll

how

T-H-E

a simple compression

format, you can easily modify the

f*CX. fDRIYIflT

method knowTi

as

RLE (Run-Length Encoding)

to normally represent that string of individual pixels)

for images with large blocks of the

complex images such

to load (and

format.

represents long runs of pixels of the same color in 3-byte blocks (instead of however

would take

same color (such

as logos

.

This makes the

and simple

sprites)

.

This system

many bytes

it

PCX format suitable

but unsuitable for

as photos.

As with most graphics formats (apart from raw data),

PCX files start off with

a simple header. This

header can be represented using a simple structure that contains the different header

shown here: typedef struct PCXHeaderl //

Always 10 (ZSoft .pcx)

char

manufacturer; version;

//

Version number

char

encoding;

//

Encoding method (1=RLE)

char

bi

//

Number of bits per pixel

char

little

tsperpixel

;

short

xmin;

//

X

Origin of image

short

ymin;

//

Y

origin of image

short

xmax;

//

Width of image

fields, as

;

.

;

2D

short

GRflPWiCB

ymax;

//

Height of image

;

//

Horizontal

;

//

Vertical

resolution

short

hdpi

short

vdpi

char

colormap[48]

//

Palette information

char

reservedl;

//

Reserved

char

nplanes;

//

Number of planes

short

//

Number of bytes in

short

bytesperline paletteinfo; hscreensize; vscreensize;

char

filler[54];

// Unused data

short short

After the header, the actual

decompressed are equal

to

Under Linux

resolution

n a

line

//

Palette interpretation info

//

Horizontal

//

Vertical

screen size (v 4+)

screen size (v4+)

image data is stored. The dimensions of the image when it is (xmax - xmin + 1) and (ymax - ymin + 1). The total amount of storage

number

the area of the image (xsize * ysize) multiplied by the

of bytes per pixel

is

(1 for 256 color

images)

Decoding the data the pixel are pixel.

value

1

is

(that

quite simple. is,

Each byte of the image data represents a

the value of the byte

pixel. If the top

greater than or equal to 192), then

is

it is

two

bits

an encoded

The remaining six bits of the pixel indicate the length of the run, and the following of the pixel. The following sample code demonstrates how to decode the pixel.

byte

is

7

int

i

=0;

int tot_bytes = ((xmax

while (curr_byte


which, hat->hat) /* Print a nice bit of text for each position */ swi tch( hat->val ue) /* Hat

{

case SDL_HAT_CENTERED:

printf "Center\n" (

)

break;

case SDL_HAT_UP:

printf("Up\n"); break;

case SDL_HAT_RIGHTUP: pr

i

ntf

(

"

Up

-

r

i

ght\n

"

)

;

break;

case SDL_HAT_RIGHT:

printf("Right\n"); break;

case SDL_HAT_RIGHTDOWN: pri ntf

"Down-

ri

ght\n"

)

break;

case SDL_HAT_DOWN: pri ntf

"Down\n"

)

break;

case SDL_HAT_LEFTDOWN:

printf ("Down-left\n") break;

case SDL_HAT_LEFT:

printf("Left\n

M

);

break;

case SDL_HAT_LEFTUP:

printf("Up-left\n"); break; defaul

t

break; break; /* This

defaul

should never happen */

t

break;

;

;

)

;

lN^UT

Polling

UJ1T-H

5DL

5DL

ujit-h

I

SDL

provides a set of functions that you can use to bypass the normal event queue methods and get

immediate information about current device

states. It

should be noted that these functions don't query

the hardware direcdy; instead, they use the internal information that

may not

This internal information

queue. To update these internal

always be up-to-date, especially

states,

you can

call

if

SDL

maintains about devices.

you are not

SDL_PumpEvents(

),

actively using the event

SDL

which forces

to gather

information from the input devices.

Polling The

simplest

way

t-h-e -K-ey-bo-h-rd

to get the state of the

keyboard

is

to poll

it.

This can be achieved using the following

two functions.

Uint8 *SDL_GetKeyState();

SDLMod SDL_GetModState(void) Internally,

SDL

keeps track of the

pressed and which ones are not. array.

The

otherwise,

;

state

of all the keys on the keyboard, which ones are currently

The SDL_GetKeyState(

array contains an entry for each it is

not. So, if you

want

to

SDL

)

function returns a pointer to this internal

key symbol;

if

the entry

is 1,

check whether or not the Enter key

is

the key

is

pressed;

pressed, you could use the

following code:

Uint8 *key_table;

SDL_PumpEvents(

)

;

key_tabl e=SDL_GetKeyState(

)

if(key_table[SDLK_ENTER]) printf( "Enter key is pressed\n");

SDL_GetModState(

)

returns a value that

is

a bitwise ORed combination of modifier symbols.

value indicates which modifier keys (such as Shift, Caps Lock, Ctrl,

You can check for a

specific modifier

with the required modifier symbol. is

and

The

return

so on) are currently pressed.

by bitwise ANDing the value returned from SDL_GetModState(

The

following example checks to determine whether the Shift key

pressed:

SDL_PumpEvents( if(SDL_GetModState( & KMOD_SHIFT) printf( "Shift key is pressed\n"); )

)

Both the SDL_GetModState( allow

)

and SDL_GetKeyState(

)

functions can be very useful

if

used

correctly.

you to get the current state of the keyboard at any time without your having to maintain

it

They

yourself.

Linux Gaiyie P-RDG«fliYinmNG

Polling 1

fYlousE

t-h-e

Like keyboard polling, you can also poll the

mouse

method using

in a very similar

the following

functions.

n

Uint8 SDL_GetMouseState(int *x, U

i

n18

int *y);

SDL_GetRelativeMouseState(int *x, int *y);

Retrieving information about the current

SDL_GetMouseState(

)

mouse

position

function copies the current

and returns the button

states in the

same format

mouse

as the

and button

is

relative to the previous

Configuring A control

t-h-e

is

a simple

and

task.

y pointers

The

passed to

it

button data stored in the

SDL_MouseMotionEvent structure. The SDL_GetRelati veMouseState( data; however, the position data

states

position in the x

mouse

)

function returns the same button

position, not to the screen origin.

Control

IYI

system that can be completely configured by the user offers complete and total freedom.

However, such a system can also overwhelm users by offering them too many choices and options before they have even started playing the game. Note that you should always allow several features to

be configurable by the

user.

For instance, users should be able to remap keyboard keys and buttons

to

Mouse and joystick sensitivity should also be adjustable. It is worth noting that the buttons of some joysticks may actually be axes, as the joystick hardware sees it, so you should be careful not to their liking.

restrict joystick actions to

buttons only, such as an obscure throtde control or view-hat.

Do

not make assumptions based on your

will

not be the only person playing your game.

own

personal preferences. Remember, you If

possible, get friends

and colleagues to

experiment with your control methods and your configuration options.

A simple

and

effective

way

to

do

this

is

to use a structure containing the key presses as well as a

function pointer specifying the function to

sample code demonstrates ^define KEYJJP ^define

KEY_D0WN

1

//define

KEY_LEFT

3

//define

KEY_RIGHT KEY_FIRE

4

//define

5

this.

call

when

the appropriate input

is

activated.

The

following

(

,

lN-RUT

typedef struct

UI1T-H

BDL

{

unsigned int key; void (*func_ptr) void) }

lr ;

KeyMap;

// Define the default keyboard map KeyMap DefaultMap[] = {

(SDL_KEYUP, UpButton},

{SDL_KEYDOWN, DownButton},

ISDL_KEYRIGHT, {

SDL_KEYLEFT,

{

SDL_SPACE

{0,

When

,

RightButton LeftButton},

}

FireButton}

NULL}

the time

comes

to

change the mapping for the

inputs,

it's

simply a case of changing the

member of the KeyMap function for the to the map structure and call the function

associated key press for the event, contained in the kev

appropriate event. appropriate.

When you

check the inputs, refer

that

is

Linux Gaiyie fRDGRfliriiniNG

v-"

Mi"

CHAPTER

3D

6

C5-R-H-F-H1C5

for Linux Cj-riyi-es

Linux

For

3D

several \ ears now,

Quake III and

several

P«DQ-Rf=imiYiiNG

G-hiyi-e

Half-Life

has been taking

OpenGL. Direct3D

is

fYl-ESfl

graphics interfaces are in

available only

common

3D

graphics hardware

would be needed

came

to the

life

easy for us,

DfenGL

-rnd

OpenGL

is implemented on just Windows machines. So, when including to run 3D graphics PC, it was ine\itable that some sort of OpenGL implementation

under Microsoft Windows, but

-

such as

titles

use for computer games: Direct3D and



about even kind of computer with power fast

gaming, with

handle the more complex aspects of 3D programming.

to

5oiyi£ -History! 3D

in

showing developers what they should be doing. To make

companies have developed 3D APIs

Currendy, only two

more of an emphasis

for Linux.

Commodore Amiga adapted Mesa to drive 3DFX

Brian Paul had been experimenting with a graphics library he'd written for the

and ported

Voodoo

that

code

to Linux. Darvll Strauss

graphics cards.

been adapted

and David

Mesa has subsequendy

manv other graphics cards. supporting more card tvpes, Mesa

to drive

In addition to

NOTE

has grown into an almost perfect implementation of the it's

OpenGL .API

(although, for legal reasons,

using

you have a program

if

OpenGL,

prettv

it's

much

work when compiled and linked Additionally, there are

now

that's written

a sure bet that

3DFX was

bought by its comsupport for the older chipsets is going to continue, no more Voodoo-based cards are going to be manufactured. In 2001,

petition, nVidia. While

not allowed to be called OpenGL).

Nonetheless,

Bucciarelli

it'll

against Mesa.

several true

OpenGL

implementations for Linux, including those from

XiG, Metro-Link, and nVidia. Therefore, for the remainder of this chapter and the next, the

"OpenGL"

graphics interface, even though the chances are that you'll be pronouncing

In this chapter,

I'll

introduce you to enough

ject worthy of several volumes, this extensive topic,

LU-H-RT Is OpenGL

is

I'll

pick

up

much

of it

a copy of

is

OpenGL

all

you writing games. Because

out of the scope of

this

it's

it

about

"Mesa."

a deep sub-

book, but for more information on

OpenGL Game Programming (Prima

Publishing).

O-f-enGLT

an extremelv powerful graphics API.

have to provide

to get

talk

One

of its nicest features

is

that

all

implementations

of the core functionality required by the specification of the API. That

means

that

programs should run correcdy whether you have an aging \bodoo-l card or an up-to-date GeForce-2

3D

ULTRA.

If

your hardware does not implement a feature, then the

ture in software

to take

—and your program

will

should work

is

on any implementation,

more

discuss these particulars in

So what can it

OpenGL

do?

may sound

implementations are allowed

draw the graphics

into,

GUI elements such (GLUT)

extend the API

to

outside the core functions.

its

calls are likely to

be

to

fast

run

OpenGL

quickly, you'll

have to

on most 3D hardware.

and "textured" by wall-papering

but keep

do are

mind

in

it

and

it

It

doesn't deal with opening a

window

Many

OpenSource

In addition, you'll probably

sliders.

simple

Consequently, you always have to include some other

OpenGL games

clone, freeglut.

use

GLUT is also

this library.

want

to pull in

some add-on

Mark

Kilgard's

GL

7

Utility

Toolkit

used for examples in most

Nearly

all

libraries to

perhaps to handle some of the low-level drawing for you.

Official

OpenGL

Early versions of

site,

to

doesn't include routines for keyboard, mouse, joysticks, text output, or

Linux GUI

OpenGL

toolkits provide a

window into which OpenGL can render; you can use SDL, GTK+, FLTK, TCL/Tk, even raw X Windows calls.

OpenGL Web

some

games such

to create a

official

light

with a picture of

that even graphically sophisticated

also significant:

manuals, but there are plenty of alternatives to

or

We'll

using just those basic primitives. Even multimillion-dollar flight simula-

doesn't

handle those things. library or

you want the program

—each of which can be colored, illuminated by some

menus, buttons, or

as

rather

most often written using OpenGL.

OpenGL

things that

library to

lie

may run

and points

OpenGL

tor graphics systems are

Some

it

most 3D applications describe the game's "world" and everything

rather limiting,

Quake are written in

if

OpenGL

sources, fogged by the simulated atmosphere,

as

driver emulates that fea-

detail later.

Essentially,

in terms of triangles, lines,

kind. This

OpenGL

GfllYl€5

something of a double-edged sword. Although any program written using

correctly

pay careful attention to which particular

in

OpenGL

advantage of the special features of some cards that

This flexibility

FDR LlNUX

not be aware of any problem except that

addition to the core functionality,

slowly. In

G-Rfl-F-HlCS

render

A good place

text, to

way

Lesstif,

load images, and

to look for these things

is

the

located at http://www.opengl.org.

UU-eh site! httf://ujujuj. OFeNGL.ORG

Mesa had support

for software-only rendering

under SVGAlib, but

as

I

write this, that

modern implementations of OpenGL for Linux work within the XFree86 windowing system. If you are a console programming enthusiast, you'll either have to get into X or forget about doing hardware-accelerated 3D graphics.

version

is

not actively maintained. All

LU-He-RH

Can

Unless your Linux distribution installed.

However,

it's

tage of your hardware.

G

1 is

hopelessly outdated, you'll probably find that

possible that you'll

The

NGL7

site at

need

to

Mesa

is

hunt down a vendor-specific version

http://www.mesa3d.org

is

a

good place

already to take advan-

to start that search.

However,

Linux

3D

if

i

lB-hm-e F-RaG-R-nmiYnNG

you have nVidia 3D hardware, for example,

makes your graphics hardware and look

you'll

do

better to

visit

the

Web

of the

site

company

that

for a section containing appropriate Linux drivers.

(Yl£5fl/OPENGI_: HTTf i//uiUIUIime5f l3D.DRG :

Jl

For the purposes of this chapter, however, you can get by with whatever came with your Linux

Although

tion.

it'll

be slower than hardware-accelerated

BuffERB, Hidden Eli mi nation, To make images around 20

to

smoothly,

it

should work

-RNim-FmaN it's

necessary to redraw the complete image at a rate of

60 times per second. Unlike some 2D animation techniques,

redraw the entire 3D picture

at that

perfectly.

Su-r-f-h

-find

move

that appear to

OpenGL,

distribu-

it's

absolutely necessary to

speed because even the smallest movement of the eye point causes

the entire scene to change. Consequently, the graphics have to be drawn behind the scenes in a "back buffer" so that you can't see the image in the process of being drawn. After the

you can swap the front and back buffers so that the new image

one can be

recycled. This double-buffer technique

and

I'll

is

what

is

pretty

is

displayed

much

new scene

is

computed,

on the screen and the

universally used in

old

OpenGL games,

describe in the remainder of this chapter.

OpenGL makes use of a depth buffer (also known as a Z-buffer). buffer is a part of a common technique to deal with the problem of "hidden surface

In addition to the two image buffers,

r

The depth

removal," that correctly to the is

is,

of making sure that the things that are far off in the distance of your

depth buffer pixel that can store distances

from the camera (or more

often, the reciprocal of

NOTE The Z as

that distance).

I

/Z

depth of the is

it

pixel. If the value

also calculates the

of that pixel's

tially

values are stored

in

the Z-buffer

—partially to make the math eas-

ier for

When OpenGL draws a pixel, depth

scene are

hidden behind the things that are closer

camera. For every pixel on the screen, there

also a

3D

the graphics hardware and par-

to give you better

Z

resolution

close to the camera.

larger than the value currently stored in

the depth buffer, that pixel won't be drawn. If the value

is

closer, the pixel will

be drawn

—and the new

depth buffer before. By setting the depth buffer redraw,

OpenGL

application.

resolves the

"closest" value will overwrite

to the largest possible

depth

problem of hidden surface elimination with

whatever was

at the start

virtually

in the

of each screen

no impact on

the

;

3D

GRflf+Hics

-FO-R

Linux G-Rm-Es

Getting Started lr

For the sake of getting us started,

handle

all

let's

the windowing issues. We'll

look

we need

to include

some

fill

in

OpenGL program that uses the GLUT library to enough of the OpenGL API to get something

simple

romp through

going onscreen, and then backtrack and First,

at a

some

details.

definitions:

//include

/* The Standard

//include

/*

Include definitions of the OpenGL API */

//include

/*

//include

/*

Include definitions of the OpenGLUti ties API */ Include definitions of the GLUT API */

All these

GL

header

them

tions place

files are,

ma

i

n

(

)

will

void

utlni t(

&argc

,

void

argv

)

files

are

Adding the direction -I/usr/Xll/include

found no matter where they are

OpenGL program

); )

;

glutlnitDisplayModeC GLUT_RGB GLUT_DOUBLE glutInitWindowSize( 640, 480 ); gl utCreateWi ndow( "My First OpenGL Program" |

gl

utDi spl ayFunc(

ini tCamera(

gl

)

redisplay

);

;

utMai nLoop(

returnO

;

void initCamera(

void

)

glMatrixMode( GL_P R0 J ECT ON gl Loadldenti ty( I

)

)

gl

OrthoC -1,1.-1,1,-1,1);

glMatrixMode( GL_M0DELVIEW

);

installed.

generally looks something like

);

char **argv

int argc,

i

by default, supposed to be in /usr/i ncl ude/GL, but some Linux distribu-

function for a GLUT-based

extern void initCamera(

gl

1

ensure that these

extern void redisplay( int main(

math library */

(incorrectly) in /usr/Xll/incl ude/GL.

your compilation line

The

C

GLUT_DEPTH );

)

this:

to

[1

The

g

1

Linux Gaiyie

f^-ROG-R-HiYimiNG

ut

GLUT and should always be

n

I

t

i

call initializes

)

(

The

gl

utlnitDi spl ayModeC

first

GLUT or OpenGL function

in the

global constructor functions!

GLUT that you want an RGB window that is double-buffered and

call tells

)

be a depth

that there should

the

OpenGL calls in

program. C++ programmers beware: Don't put

3D games need

buffer. Virtually all

these three things, so

we won't waste

space discussing the alternatives. Next, the glutInitWindowSize(

utCreateWindow(

call to gl

)

call tells

creates that

)

GLUT about the

window with a

initial size

title.

Then

gl

of the window we want; the next

utDi spl ayFunc

(

)

tells

GLUT which

when the window needs to be redrawn. You can also select callback functions board or mouse input, window resize, expose and iconify events, timers, and so on. function to

The

i

call

tCamera

ni

(

)

function

something

is

the "virtual" camera through which

the rendering context (a window)

glutCreateWindow( Finally, ma

ple find

it

i

n

(

)

to later; for now,

the virtual world.

set up, so

i

ni t Camera

(

)

It's

I'll

just say that

not legal to make

it

initializes

OpenGL calls

has to be called sometime

after

until

the

call.

hands control over

)

we view

is

come back

we'll

for key-

to

GLUT by calling

glutMainLoopO, which never returns. Some peo-

uncomfortable to hand control over to GLUT, but you can't get around that with GLUT.

However, the freeglut library from OpenSource has a way to get around that by letting the application call

glutMainLoopUpdate(

Now all

that's left to

void redisplay(

do

inside a loop of

)

in this simple

void

its

own.

example

is

to

draw something:

)

1

glEnable( GL_DEPTH_TEST

);

/* Dark Green */ glClearColor( O.Of, 0.5f. O.Of, l.Of ); gl CI ear( GL_COLOR_BUFFER_BIT G L_DE PTH_BU F FE R_B T ); I

|

/*

The

DRAW SOMETHING!

gl

utSwapBuffers(

gl

utPostRedi spl ay(

gl

Enabl e(

tion turns

)

them

3D rendering

function

*/

)

is

)

used to turn on various optional

off again). In this example, the function

requires depth testing, so

it's

prudent

is

to start

OpenGL features

(the gl Di sabl e(

being used to turn on depth

your drawing routines with

testing.

)

func-

Most

this feature

enabled.

The

gl CI

earCol or(

)

call tells

OpenGL what color to

clear the screen to.

the values for the red, green, and blue components of the color; the isn't

important

in this context.

Because colors run from

to

1,

last

The

first

three parameters are

parameter

is

Alpha, which

the color I've specified in this example

c

3D

is

(my

a tasteful shade of dark green

screen; in this case, we've told

In a real application, we'd draw

OpenGL

programs, we'll just

window) and then

favorite color)

to clear the color

it

some polygons,

tell

GLUT

to

.

The

and

gl CI ea r

to set the

call tells

)

(

OpenGL to clear the to its maximum value.

depth buffer

and points

lines,

next. Because this

is

the simplest of

swap the double-buffer (so that you can see the dark-green

to post a request to redisplay the

window. That

ensures that the redisplay function will be called repeatedly as

most games need.

Linux Gfim€5

G-R-H-P+-HC5 ^d-r

toglutPostRedisplayO

last call

fast as possible

—which

GLUT also provides a way to redisplay the window at fixed

probably what

is

time intervals, but

won't

I

go into that here.

You can find

this

program under the name exl

ComFlLlNG

c

on the

that

with

OpenGL generally requires you

that

to

for a

cc

-c

cc

-o

I/usr/Xll/incl ude my_program. my_program my_program. o L/usr/Xll/1

called my_program c .

is

shown

book.

this

DfENGL

compile that program. Compiling

to pull in several other libraries.

mands

accompanies

UJ1T-H

OpenGL program, you'll want

Now

program

CD-ROM

LINKING

-FIND

you have coded a simple

.

A suitable

set

of compile com-

here:

-

-

But to compile the examples for

corresponding to

this

this chapter,

chapter on the

i

b

-lglut -1GLU

- 1

you can use the makefile that

CD-ROM

that

accompanies

this

GL

-1X11-1 Xext

-lm

you'll find in the directory

book. Just copy

all

the

onto

files

your hard disk and type make. In the default

Linux

installation, the

/usr/1 ib/1 ibGLU.so (with that

some

GLUT in

OpenGL libraries are

supposed

/usr/1 ib/1 ibglut.so or

more

to

be

in /usr/1

i

b/1

i

and

bGL. so

often /usr/1 ib/1 ibglut.a). Note

Linux distributions (incorrecdy) place these libraries in /usr/Xll/1

ib.

Picking

up

the

wrong

OpenGL libraries for the hardware you have is probably the most common problem for users of OpenGL under Linux; sometimes your Linux distribution will install the libraries in one place and version

you download for your

specific graphics card

being a bit of a lottery as to which library

program

to track

When you run

down

this

screen (depending

may install somewhere

errant copies of your

else.

Then

it

I

advise

you

OpenGL libraries before you

install

any new

will be linked to your program.

the

ends up

to use the find drivers.

example, you should have a green window that takes up perhaps a quarter of the

on your

display resolution).

Nothing very

exciting, but a significant step forward

nonetheless.

Let's

D-r-huj

Bdmething!

we have the basic structure of an OpenGL/ GLUT program in place. Let's add some interesting drawing commands. There are really three aspects to drawing anything in OpenGL that we have to consider, and I'll introduce them one by one: Okay, so

Linux

34

Gnme

PROG-R-HmnniNG



Drawing polygons,



Drawing



Texturing and other "state" elements

and points

lines,

3D: perspective and

in

movement

D-K-RuuiNG -Polygons, Lin-es, OpenGL can draw a wide

When you



corners

tell

the

OpenGL

vertices,

to

is

code

typically

to

draw one of those

to use the correct

You don't generally have write

range of basic shapes: points,

to

basic primitives,

fast

how

Those

to

keep

it

3D

pixel.

Because

all

gram run

to

draw

where the the

On

a

modern

memory so

you have

rest.

to

in less

graphics adapter, your biggest worry

that

you can send

it

is

to the graphics card

to wait for the hardware!

and

quadrilateral) are

and

pretty obvious.

all

triangle-fans.

These

OpenGL

strips, loops,

and

collections of connected shapes without having to send the vertices

more than once. Using

faster

it

the apparatus needed to draw a complete triangle

also offers line-strips, line-loops, quad-strips, triangle-strips,

that they share

space.

to tell

OpenGL does all

—perhaps

busy; only rarely will

you

3D

graphics card, this operation can happen very quickly

basic shapes (point, line, polygon, triangle,

fans are there to allow

you only have



to arrange the triangle vertex data in

enough

polygons, triangles, and quadrilaterals.

of triangles are in

than a millionth of a second for a small triangle! often

-Points

worry about the order in which you draw things, and you don't have

draw every individual

provided in your

term

lines,

and

these shapes can save you typing

and

will also

make your

because those shared vertices don't have to be processed more than once.

Triangle-Strip

Single Triangle

Quad-Strip

Quad

Figure

6.1

OpenGL

surfaces.

pro-

(

3D

Suppose that you wanted

How would you

tetrahedron. this

draw the simplest possible

tell

OpenGL

to

do

you

then give

OpenGL what

tell it

a

OpenGL

something

list

that? If you start with the

GLUT program from

comment with some

earlier in

actual code.

kind of primitive to draw (for the tetrahedron, you want triangles) and

3D

of vertex coordinates in

that

Linux Gaiyies

solid object: a three-sided pyramid, also called a

chapter, you can simply replace the DRAW SOMETHING!

First,

tell

to

G««-p+-iiC5 -fd-r

space.

you are done, and the drawing

When you

will

have finished describing the shape, you

commence

while your program gets

on with

else.

just for fun, let's also

color each triangle with a different color so that

we can

see which triangle

is

which. Here's the code to accomplish these lofty goals:

glBegin( GL_TRIANGLES

glColor3f(

glVertex3f( glVertex3f( glVertex3f( glColor3f(

O.Of, -l.Of.

l.Of.

-l.Of,

O.Of,

glVertex3f(

l.Of,

glVertex3f(

O.Of,

Col or3f

O.Of,

O.Of,

glVertex3f(

O.Of,

l.Of,

glVertex3f( glColor3f(

-l.Of,

-l.Of. l.Of,

g!Vertex3f(

-l.Of,

glVertex3f(

O.Of,

glVertex3f(

l.Of,

glEndO;

/* All

-l.Of

-l.Of

l.Of.

done

-

/* Thi rd triangle */

)

):

);

O.Of);

-l.Of

-l.Of.

/* Blue */

);

O.Of

l.Of,

-l.Of.

);

l.Of

glVertex3f(

/* Second triangle */

)

);

-l.Of

O.Of,

O.Of,

/* Green */

);

O.Of

-l.Of

l.Of.

First triangle */

);

O.Of

O.Of, -l.Of.

/*

)

);

-l.Of

l.Of,

O.Of,

i

-l.Of

/* Red */

);

O.Of

O.Of,

-l.Of.

glVertex3f(

g

O.Of

O.Of,

l.Of.

describing triangles */

/* Start

);

/*

);

-l.Of

-l.Of

/*

Yellow*/

Fourth triangle */

);

):

let the drawing commence.

*/

may be wondering why these commands end in 3f There are many versions of the gl Col or and gl Vertex2f )lVertex( commands, some taking more or fewer arguments is for 2D drawing, for -xample. The number sets the number of arguments and the letter f tells the system that we are pass-

rbu



)

ng

(

.

C

float

ind doubl

arguments (usually preferred for best performance). (You can

es.)

You can

also pass

(

)

)

also pass bytes, shorts,

an array containing the coordinates by adding a

v

to the

i

nts,

end of the

unction name, as in this example: !

Linux G-hm-e FRDGRfliYHYiiNG

vertex

float

gl

The

[

3

=

]

Vertex3f v( vertex

gl Col

or3f

nate data off to

OpenGL will

(

call sets

)

OpenGL.

);

OpenGL's current drawing If you

good

use between the

obscure

gl

Vertex(

)

call, you'll

see that

X and Y are in

the plane of the screen with the

coordinate system); Z decreases (becomes increasingly negative)

why some

vertices have negative

dimensions), you'll see that

this

is

Z

values).

So

(if

as

you are

a tetrahedron that's in the middle

Begi

n

know

to (

and

)

is

that

gl End

(

)

OpenGL is very picky about what commands it allows you calls.

to

Only the following commands (and a handful of other

are allowed:

Vertex(

gl Col gl

calls)

gl

front of each

point facing us.

Another important thing

gl

2D

at visualizing things in three its

call in

triangle.

farther "into" the screen (that's

of the screen with

)

(

color; the glVertex3f() call sends vertex coordi-

coordinate system in which

origin in the middle (just like a

move

put a glCol or3f

blend the colors across each

OpenGL uses a default 3D things

3.0

2.0,

1.0,

{

or

(

Normal

(

glTexCoord( gl

Mater i

If you

al

(

compile and run

see red, green,

this

and blue

code

(it's

called ex2

.

c

—the yellow one

triangles

on the is

CD-ROM

that

accompanies

this

book),

you'll

hidden behind the others (depth buffering,

remember!).

Now let's get this object to

move.

D-R-RUJ1NG IN

AND

3D3 FER5FECT1VE

MOV-EIYHENT

move in OpenGL is just a matter of drawing them in a slightly different position in each frame—just as you do in 2D graphics but recomputing all those gl Vertex values each time would be tedious. Fortunately, OpenGL can do this computing for you; on modern graphics cards, it might be done for you on lightning fast hardware. Making

things



Moving

objects in

3D

is

tricky, especially if

lations, scaling, shearing, mirroring,

(

your vector and matrix math

and other

"linear" transformations

bers arranged in a 4x4 matrix. This compact representation

you are going

to

become an

effective

3D programmer,

you'll

is

isn't strong. All rotations, trans-

can be described by 16 num-

at the heart

have to

)

come

of most to

3D

algorithms.

grips with 4x4

If

matrices.

;

;

3D

A 4x4 matrix can

combine any number of transformations applied

matrices as a single-dimension 16-element array ten

down

as a

matrix array

FDR LlNUX

G-R-nf4HlC5

—which

is

a

little

in

any order.

Gfl(YI£5

OpenGL represents

curious since they are universally writ-

4x4 two-dimensional array of numbers. The order of the matrix elements

OpenGL

an

in

I

shown here:

is

1 4

8

12

1

5

9

13

2

6

10

14

3

7

11

15

OpenGL uses

the idea of a "current" matrix (well, actually

applied to every

Vertex (

gl

)

call

before

Better

still,

from

each of the current matrices

can push or pop.

is

PushMatrix(

gl

PopMatrix(

gl

LoadMatrixf float matrix Loadldenti ty(

glMul tMatrixf

gl Seal

ef

float

(

float

Most of these routines are

matrix

utility

LoadMatrixf

specify or a fore, gl

(

)

)

and

and

gl

at the

gl

16

]

);

[

16

]

);

float

z

x,

float

to

float

y,

make

around a

line

Scalef

(

)

)

If

is

a

z

)

of com-

utility

routines

is

);

);

from the origin it

The

gl

to the point (specified

into the current matrix (the

Rotate

by

x, y,

(

)

command

and

one on top of the

z),

stack).

are similar.

replace the matrix

on the top of the

"do nothing" matrix, respectively. The identity matrix

Loadldenti ty(

effect

);

their functionality fairly obvious:

commands

LoadIdentity(

z

is

stack with the matrix

you

a "do nothing" operation; there-

a handy way to reset the current matrix.

Be careful with the matrix push and pop commands; the (16

top of the stack. Here are the

angle, float x, float y, float

through the specified angle and multiplies (

element of a stack of matrices that you

routines to create matrices that rotate, translate, or

[

float y,

x,

named

creates a matrix that rotates

The glTransl atef

extra cost.

;

float

(

float

(

no

)

)

glRotatef(

for

up

)

(

glTransl atef

on can be transformed

set

]

friends:

gl

gl

automatically

is

to multiply matrices together

each of these routines operates on the matrix

make

,

—which has the

OpenGL has commands

with which you'll want to

gl

that point

actually just the top

bining their effects. You can also use handy scale;

current matrices) which

used to draw something. This means that once you've

it's

those 16 numbers, everything you draw

three

OpenGL matrix

stacks are often quite small

common maximum number).

you add the following lines to our rapidly growing sample program, the tetrahedron

one degree every time panies this book.)

it's

redrawn. (This version of the program

is

ex3

.

c

on the

will rotate

CD-ROM

that

by

accom-



In essence, the

columns of the matrix define a new coordinate system into which objects are drawn.

Understanding

how

that matrix

is

put together

is

key to understanding transformations in

'm sure that you noticed that we have talked about only the matrix.

The bottom element of each row

isn't

matrices are always set so that elements 3, 7,

first

three elements of each

OpenGL.

column of the

relevant to simple rotate/translate matrices, so these

and

11 are

and element 15

is 1.

.

Linux Gaiyie -P-RaG-RAmmiNG

An 1

interesting

consequence of understanding what the various rows of the matrix contain

OpenGL cannot directly generate with

can make up matrices that

a "shear" matrix by having the

first

n

squares

will

come out

in a

diamond

gl

LoadMatrix(

)

you

that

the API. For example, you can

and second columns of the matrix represent vectors

perpendicular. Apply one of these matrices using

is

or

gl Mul

tMatri x(

),

make

that are not

and

all

your

shape.

Working uiit-h NE EipufinaNB, Lin-e icpu-FmaNS, AND DlBTflNCEB IN 2D -

If

you intend

mathematics.

I'll

there are always

One to

3D

to get seriously into

explain

it's

unavoidable that you'll need a certain amount of

some of the most important equations and algorithms

more equations

to learn.

—along with a function you can

compute the surface normal from the three

are parallel to

vertices of a triangle.

is

The normal

a set of four

surface normal (three numbers)

numbers

A useful extension an

that describe

infinite

and the distance from the plane

These four numbers are called A,

Hence,

+ if

a

3D

vector that

B, C,

and

D

(where A, B, and

C

of this concept

plane in 3D.

is

It's

is

the

composed of the

to the origin at the closest point.

are the surface

the distance to the origin). These values obey this relationship for every x

is

use

in a direction at right angles to the plane of the polygon. All polygons that

one another have the same surface normal.

plane equation, which

find

here, but realize that

useful concept, the surface normal, was explained in Chapter 6

one unit long and points

is

graphics,

(x,y,z)

normal vector and D that lies

on the

plane:

y+C*z+D==0 you know the surface normal of a

D by substituting one of the

D=-(A*x

+

When you compute plane and negative

B*y it

+

triangle's vertices into the

Chapter

6),

you can

plane equation:

C*z)

like this,

if it lies

triangle (by using the algorithm in

D

is

on the

a signed quantity that

is

other. That's a useful fact

positive if the origin

and leads

is

on one

side of the

to this equation:

d=A*x'+B*y'+C*z'+D Where (x',y',z') is any point in space and D is the signed distance to that point from the plane. Now, armed with the plane equation, you can easily compute whether some other point lies on the plane, behind the plane, or in front of the plane and by how much (using OpenGL's counterclockwise con-



vention discussed in Chapter 6)

.

Using

OfenGL

in Gaiyies

Just as there are plane equations, so there are also equations that describe lines in 3D.

These equations

are generally in parametric form: IT

x

=

e

*

+ xl y =

t

f

*

+ yl

t

=

z

g

*

t

+ zl

Where E,F,G is a vector (one unit in length) describing the direction along the line, (xl,yl,zl) is one point on the line, (x,y,z) is another point on the line, and t is the distance between the two points. The sign of the equation depends on which side of (xl,yl,zl) the point (x,y,z) is.

E_ If

you know two points that

equations above to

compute

Another important thing

3D

calculated in

dx = xl

-

x2

dy = yl

-

y2

dz = zl

-

z2

dist = sqrt

is

on a

lie

line,

you can work out the distance between them and reverse the

(e,f,g)

be able

to

to

measure distances

using the Pythagorean theorem

dx

(

(just as

dx + dy * dy + dz * dz

*

)

in 3D.

it is

(which are typically uninformative names)

distance between two points

is

in 2D):

;

Two other operations are commonly found. Mathematicians cross-product

The

.

The

call

them by

the

names

dot-product operation

is

dot-product

and

between two length-

one vectors that produces the cosine of the angle between them:

dot_product = xl

x2 + yl * y2

*

In this syntax, (xl,yl,zl)

The

cross-product

and

*

zl

(x2,y2,z2) are

of two unit vectors

is

*

z2

both vectors of length

another vector

1.0.

that's at right angles to the first two.

We

already

used a cross-product operation to calculate the surface normal of a triangle:

cross_x = yl

*

z2

-

zl

*

y2

;

cross_y = zl

*

x2

-

xl

*

z2

;

cross_z = xl * y2

-

yl

*

x2

;

Many of these algorithms need ing \11

an arbitrary vector and changing

you have to do

}f the vector:

to

—that

so-called unit vectors its

normalize a vector

is,

vectors

whose length

length to 1.0 without altering is

to divide the three

its

direction

is 1. is

The

act of tak-

called normalizing.

components of the vector by the length

Linux Gaiyie F^OGK-RrnnniNG

length = sqrt

float

x*x

(

y*y

+

one_over_l ength = l.Of *= x one_over_l ength y *= one_over_l ength float

1

+

length

/

z*z

)

;

;

;

Jl

Jn

z

*= one_over_l ength

;

Now you know the most common 3D

mathematical operations; almost

all

3D

algorithms use these

operations in various combinations.

Using In

-Bill-bd-h-rds

many games, you need

to

to 5imuLflT£

draw very complex objects such

2D

as trees that, to represent accurately in

know that a typical European Oak tree has more than a half-million leaves?) Even with the wonders of modern 3D graphics hardware, it would be a while before you could draw even a single mature tree as a true 3D object. 3D, would require thousands or even millions of polygons. (Did you

1

The

usual graphical trick to get around this

texture

map and set map can

gle texture

the parts of the

map

is

2D

to paint a

picture (or photograph) of a tree into a

that are not part of the tree to

then be applied to a single polygon

—and

as long as

be

fully transparent.

you don't look too

This

sin-

closely,

you'll see a tree!

The snag tree will

is

that

it's

really only a

cardboard cutout of a

You can do Rotate(

really

it,

the

2D

nature of the

)

this

tree.

by calculating the position of the tree and the position of the camera and applying a

command, but

there

is

an easier way. Because

have to do to keep something facing the camera

ing the

you walk around

be obvious. Therefore, we have to rotate the tree to face the camera, so that no matter where

you stand, you see the same picture of a

gl

tree: If

model

at

is

OpenGL keeps

to

model

it

the camera at (0,0,0),

in the

X,Y plane and avoid

all

you

rotat-

all.

That's easier said than

done because by the time we get

to

render the

tree, we'll

have the

OpenGL

matrix stack piled high with transformations that deal with the position of the camera relative to the

world and so on.

One way

to deal with that

then erase the rotation part of that matrix

is

to ask

OpenGL what

when we render

the current rotation matrix

the tree:

is

and

Using DfenGL

matrix

float

gl

16

[

PushMatrix

glGetFloatv

(

)

]

;

;

GL_MODELVIEW_MATRIX

(

Gflm£5

in

,

matrix

)

;

ri

matrix[

=matrix [ = matrix[

]

matrixL

1

]

5

]

=matrix[

10

2

]

= matrix[

3

=matrix[

]

]

= matrix[

11 4

] ]

= l.Of

;

= O.Of;

matrix[6] = matrix[7] = matrix[8] = matrix[9] = matrix[ll] = O.Of /*

Elements 12,

13,

translate component of the matrix

14 are the

;

-

leave those

alone! */ gl

LoadMatrixf

/* gl

matrix

(

)

;

Draw billboard polygons */

PopMatrix

However,

)

;

this isn't quite the right thing.

board exactly to lean

(

parallels the screen

backward

if

be high above the

your

virtual

You

tree.

—which

is



it

Z

ball,

but you don't want a tree

to

NOTE

vertical axis.

You may want to have another surface perpendicular to the main billboard if you ever have the situation where you view the object from above.

this,

as well as at right angles to the

beach

bill-

want the

we need to look at where the Yaxis of the model ends up because that's not changed by the billboarding process. If we know that, then we know that the X axis should be at right angles to

To do

rotates the tree's billboard so that the

fine for a cloud or a

camera happens

really only

around the

tree's billboard to rotate

The preceding code

axis.

That

is

what a cross-product can do for you.

The

last

step

is

to figure

out where the new Z axis should go, which should always be

the other two axes. This location float

x_axis

[

3

]

;

float

y_axis

[

3

]

;

float

z_axis

[

3

]

float

matrix

[

16

glPushMatrix glGetFloatv

()

(

is

something that a second cross-product can achieve:

;

]

at right angles to

;

;

GL_MODELVIEW_MATRIX

,

matrix

)

Linux Gaiyie FROGRfliYimiNG

IBB

z_axis

n

I

]

O.Of

;

[

1

]

O.Of

;

[

2

]

-l.Of

[

z_axis z_axis

y_axis

[

y_a x i

y_axis

;

]

matrix[4]

[

1

]

matrix[5]

[

2

]

matrix[6]

VectorProduct x_axis, z_axis, y_axis VectorProduct z_axis, y_axis, x_axis Normalize x_axis Normalize z_axis (

)

;

(

)

;

(

)

(

;

)

;

/*

Now we know where we want the three axes to end up,

it

so.

change the matrix to make

*/

matrix[ 0] = x_axis [0] matrix[ 1] = x_axis [1]

j

matrix[ 2] = x_axis [2] matrix[ 8] = z_axis [0] matrix[ 9] = z_axis [1] matrix[10] = z_axis [2] gl

/* gl

LoadMatrixf

matrix

(

)

;

Draw billboard polygons */

PopMatrix

(

)

;

This example uses two functions we talked about

void VectorProduct

*dst. float *a, float *b

(

float

dst[0] = a[l]

*

b[2]

a[2]

*

b[l]

dst[l] = a[2]

*

b[0]

a[0]

*

b[2]

dst[2] = a[0]

*

b[l]

a[l]

*

b[0]

void Normalize float

(

float

*v

length = sqrt

)

(

earlier:

)

(

v[0]

*

one_over_l ength = l.Of v[0] *= one_over_l ength v[l] *= one_over_l ength

float

v[2] *- one_over_l ength

v[0] + v[l] /

length

;

*

v[l] + v[2]

*

v[2]

)

LJ51NG

UJO-R-KING Many graphical drifting

little

games need

fluid

mapped shape

acting that

on water droplets swirl as a

these effects.

all

through that You'll also

being simulated. By using the

we can render each

first

or at most a quadrilateral).

on the OpenGL ModelView

stack,

version of the billboard

particle as a tiny texture.After

you have established

you can rapidly render a large number

3D volume.

moving the

makes fog

is

(typically either a single triangle

of particles in a rules for

reproduce the look of spraying water, swirling or

to

to turn to face the camera,

the special billboard matrix

The

motion

magical sparkles, and so on. These effects are generally handled by render-

ing small "particles" of whatever material

code that causes objects

IN Gfl(Yl€5

UU1T-H -F-H-RT1CL-E5

effects in

smoke, dust,

DPENGL

Keep

to

from one frame

in a fountain) to

to the

next can range from the very simple (gravity

something much more complex

character walks through

it)

.

The

(a full fluid-dvnamics

particle-moving basics are

track of the coordinates of your particles in a large array

each frame, you update the position of each

array: In

want

particles

add

rules for creating

new

particles

example, you might want to delete water droplets that

much

and then

the same for

zip quickly

particle.

and destroying old ones. For a fountain, hit the

model

for

ground and create new ones with an

appropriate upward velocity at the fountain's outlet even as old droplets die.

Even systems with just a handful of golden "glow"

particles that swirl in a spiral

can create wonderful

magical effects that can help cue the player that something special has just happened.

When little

a character jumps into water, you can create a handful of splash particles.

shower of blood droplets can add

quickly

and comes

to a

sudden

stop,

If

someone

greatiy to the goriness of the game! If your character

you can launch some

tiny dust clouds

from

his feet

and

gets shot, a is

running

let

them

settle to earth.

cting Collisions It's

generally necessary to provide several types of

when

the player walks into a wall or

uneven ground,

you'll also

is

hit

3D

collision-detection sequences so that

you can

tell

by a weapon. In games where the player can walk or drive on

have to detect the height and slope of the terrain beneath his feet or

wheels.

These related problems are enough ly

complex

to resolve

to completely

and may require you

kill

your frame rates because they are mathematical-

to test often for

each frame of graphics.

Linux Gaiyie Prqgrhiyi,

Imagine a case of a thin brick wall and a car driving along entirely start

on one

side of the wall at the start of one

of the next frame. In a

the user

is driving fast

game

situation,

to that

problem.

sufficiently small intervals so that the car is

to

One

is

To

calculate

whether two polygonal shapes have collided

side of

making

it

is

at the

through a brick wall

billions of calculations

is

is

its

own

equal to

quite tricky

its

length during each interval.

real length plus the distance

and very time-consuming.

collision detection

in real time

only

if

You can

invisible

by imagining an

sphere surrounding the player.

It's

you'd be

YOU TE5T

work

tests

level,

is

to simplify the shapes

you

test against.

You

coarser, simpler tests suggest the possibility of a collision.

sphere surrounding each object in the scene and another

easy to use the Pythagorean

tance between the centers of two spheres. If that distance

is

less

theorem

3D to figure out the dissum of the two radii, then the

in

than the

spheres overlap and the objects have collided. However, square roots are a costly math operation;

series

to

compare the square of the distance

//define

int

i

to the square of the

sum of the

radii.

sq(x)

{

float

x,

float

r

;

z

;

/* Center */

/* Radius

*/

}

;

((x)*(x))

sOverl appi ng

(

struct Sphere *sl,

d_sqd d_sqd = sq(sl->x

float

y,

struct Sphere *s2

)

;

return d_sqd


x) + sq(sl->y

sq(sl->r + s2->r)

;

-

s2->y) + sq(sl->z

it's

Here's a suggested

of equations your program can process to detect whether two objects are in contact:

struct Sphere

If you

per frame.

T-H-E 5-H-H-F-E5

should then use refined, detailed

cheaper

if

the time span of one graphics frame into

polygon of your player's character against every polygon in the game

5 im -FIJI -FY start off

up

to divide

travel in that frame.

to

could be that the car

to drive right

does not move more than

about to

The key

It

on the other

entirely

would be possible

pretend that the length of the car

doing millions or perhaps

J

—and

it's

tried to test every

high speed.

enough!

There are two solutions

The other approach

it

frame

at

s2->z)



When you know that two inside each object

want

The •

to test

each

and

objects are close

Cldbe, Test Again

enough

that their

bounding spheres

see whether their polygons overlap. This

triangle; you'll

have to

split

overlap,

a much nastier

is

you can look

test. First,

r

you'll really

the polygons into individual triangles before you

start.

n

steps to test a triangle against a sphere are complex:

Compute

the plane equation of the triangle. If the distance from the center of the sphere to the

plane containing the triangle

can stop the •

Are

Dejects

1-f t-h-e

is

greater than the radius of the sphere, they can't be touching, so

we

test.

get this far, we know that the sphere is crossing the plane of the triangle, but we still don't know whether the sphere is a million miles away from the triangle itself. However, if we were to coneach at right angles to the plane of the triangle, and each of which runs struct three more planes If we



through one side of the

triangle, facing

center of the sphere to these three sphere, •

we

we

"fence" planes

and the plane of the

If

sphere

still

is

planes. If that distance

is

greater than the radius of the

£

don't need to look any further.

Unfortunately,

ter of the •

a miss, and

it's

new

—we could measure the signed distance from the

outward

aren't there yet.

There are

triangle

and

inside the fence planes, then

still

which the sphere can overlap both the

not intersect the triangle. However,

still

it's

cases in

a definite hit

and we need look no

the sphere penetrates the plane of the triangle and the plane of one or

we can use

if

the cen-

further.

more of the fence

planes,

the Pythagorean theorem to determine whether the sphere actually intersects that edge

between the plane and the

triangle. If the distance

from the center of the sphere

triangle (squared) plus the distance to the plane of the fence (squared)

sphere (squared), then

it's

a

hit. If this

value

is

is

less

to the plane of the

than the radius of the

greater than the radius of the sphere (squared),

it's

a

miss.

Whew!

Well,

if

you think the

effort to

code

all

of

this is

complex, wait until you get to the next

test

intersecting the actual triangles of one object against the triangles of another!

Rather than attempting to convey that in enough detail to allow you to reproduce several

graph tion.

more chapters with library.

ugly mathematics),

I'll

This library contains the code for

refer

all

of

you

to the

code

this nastiness

and

in is

it

(which would

my own OpenSource

fill

scene-

the subject of the next sec-

hHHMMMMPR^^^^H

CDNTDUR5

"FOLLOW 5URfflC€ The other over to

thing you

hilly terrain, for

know

how

is

to

make an

example). You need to find out the height of the surface along with

you can rotate the vehicle

tion so that

object follow the contours of a surface (a vehicle driving

to

sit

in the

preceding section, you can identify the

polygon in question. Then you can use the plane equation to find the

gon, which you can use with

normal of the polygon



plus a

Trans ate 1

little

(

)

to position

trigonometry

object.

In the preceding chapter,

how you

we took a

swift gallop

apply this technology to games.

That

your vehicle

Y coordinate gives

of a point on the

you the height of the

at the desired height.

The

poly-

surface

—gives you the rotation angles.

Next Layer!

Tfi€ for

X and Z coordinates of the

gl

orienta-

on top of it.

Using the kinds of intersection techniques described

plane that corresponds to the

its

N through the

Now we'll

G-r-r-f-h -H-Pls

OpenGL API without too much

take a step back

and

see

how

to apply

concern

what

we've learned.

One

thing that I'm sure you are thinking about

is

the

amount of information

it

took to draw some-

how much would it take to draw the Enterprise and four Romulan WarBirds? The simple tetrahedron contained four triangles, with three vertices each; each vertex had a glColor( ), gl Normal ), glTexCoord( ), and gl Vertex( command. That's about 36 numbers for each triangle! When you consider a game like Quake and see an individual monster that's drawn with a thousand or more triangles, it's readily apparent that you are not going to be typing all those vertices and commands by hand! thing as simple as a tetrahedron. Just

(

)

In practice, you'll hardly ever enter vertex data by hand.

specialized

CAD

program

including Blender,

models typing.

AC3D,

called a modeler. PrettyPoly,

in a fairly natural way, It's

interesting that

all

There are

It's

several

much more

likely that you'll

cheap (or even

free)

modelers for Linux,

and Moonlight Creator. These programs allow you

without too

use a kind of

to enter

much

four of these pro-

grams are written using OpenGL.

NOTE

Although modelers help you do the detailed work

You can find Blender and PrettyPoly on the CD accompanying this book.

of creating the

3D

models, you

will

still

need

to

load those models into your program from data files

on

disk.

3D

OpenGL was

designed without a native

dering mechanism. This means that library that's layered

There

really

is

no

format because

file

if you

want

on top of OpenGL or write the code

VRML try to take

on

that mantle)

Worse

.

still,

structure for storing

disk, you'll either

have to use a

disk (although several formats such as

there are really

and libgof for 2D images. The reason

to libpng, libjpeg,

focused on an efficient and flexible ren-

to parse the data files yourself.

3D models on

single standard for storing

it's

models from

to load

no 3D model

for that

is

loaders that are analogous

no standard data simple 2D image, on the

that there

3D models in memory after they are loaded. To little more than a 2D array of pixel values.

store a

is

also

other hand, you need I

will

not attempt to describe

detail;

the

3D

file

Web.

on top of OpenGL

—and hence

storage of models

work around which you can Such

loaders. engines,

NOTE

them on

Instead, I'm going to talk about using a

library layered

libraries are

A good place to find out about

to structure the

formats of any type is http://www.wotsit.org.

file

to provide a frame-

write standardized

file

sometimes called game

but that term covers a multitude of other functions.

because most of these

libraries store the

When you

each frame using

gl

ness of drawing the models.

Doing

enough and your computer

is

fast

term

is

scene graph

API

scene in some type of directed graph or tree structure.

have the models you need stored in memory,

rect positions in

help out

3D

A more concise

Culling

Fi-eld-o-f-Vi-euj

One

formats in

there are plenty of descriptions of

Rotate

that

(

it's

tempting to just place them

orglTranslateO and

)

would

certainly

enough. But

to

make

work

let

OpenGL get on

—providing that your game

all

in their cor-

with the busiis

simple

the best use of your machine, you'll

need

to

OpenGL.

thing you can do to help

is

to try not to give

edge of the screen. Precisely how you do to say that all the

this

OpenGL

things to draw that are obviously off the

depends on the nature of your game. You might be able

monsters that are not in the same room as the player don't have to be drawn

unless the doors are

left

(well,

open). You might also be able to discard objects that are behind you because

they can't be seen. In general, anything that doesn't have to be drawn.

lies

outside your field of view (YOX)

is

not needed and

Linux

Clearly, test

G-hiyi-e -P-ro

OpenGL is itself already doing

these kinds of

but

tests,

forced by the nature of its API to

it is

every single vertex of every triangle to see whether the triangle

you can

application, however,

test

whole objects with a simple

One way

without even looking closely at them.

do

to

that

3D

sphere that tightly encloses each of the objects in your against the field of view.

You can

test

on the screen or

and

to store a

toss

not. Inside your

out thousands of polygons

bounding box or bounding

scene and just

those simple shapes

test

a sphere against the field of view with just a handful of operations

even faster than testing a single triangle). This

(it's

is

test

is

is

why

it

makes sense

to "cull" the scene to the field

OpenGL.

of view before you pass anything on to

Scene graph APIs often store the 3D scene in a tree structure; a bounding sphere (or cube)

at every

game might have a bounding sphere around each spacecraft model; that sphere would contain a number of subobjects (the engine, the weapons, the cockpit, and so on), each of which would have its own bounding node surrounds

sphere. With to

all

one

test,

being on-screen;

sphere

is

the polygons that are beneath that

API can

the scene graph

alternatively,

clearly on-screen. If the

it

node

in the tree.

Thus, a space

out the entire spaceship

toss

can draw the spacecraft unconditionally

bounding sphere

if

not anywhere close

the entire bounding

and part outside the

part inside

lies

if it's

field

of view,

the API can look at each part of the spaceship in turn, accepting or rejecting each small group of poly-

gons as

it

comes

to

it.

5T-HT-E IYlflNflG€IYI€NT Another aspect of OpenGL agement. As you saw glDisable(

)

that needs careful attention

—along with

gl

Material

before you can draw a triangle. needs, and

to set

It's

(

),

you want the best performance

number of calls

significant

glBindTexture(

),

and other functions

tempting to simply run through

them up before you do

called state changes take time to execute rible

you can have a

in the last chapter,

if

the

gl

Begi

n

(

)

and

—and sometimes a

gl

End

all )

(

relatively

is

state

to gl Enabl e(

that have to

be

)

manor

set

up

of the things that a triangle

sequence. However, these

so-

innocuous change can have a hor-

impact on performance.

There are two things you can do about

this: First,

changes only when you absolutely have

to. If

you can perform

changes, making

two consecutive groups of polygons have the same

glMateriaK) and glBindTextureO needs, you can essarily.

"lazy" state

test for this

and avoid repeating those

calls

unnec-

Second, you can even go so

far as to sort

your polygons into groups that share the same

and such so

that they are

all

tures, material settings,

drawn together, requiring fewer

state

tex-

changes.

Using

Scene Getting

all

graph API lar

of

together

libraries

is

a

little

complicated, but fortunately there are several OpenSource scene

you can pick up and use or

if

on most complete Linux

you prefer

The general

style

are CrystalSpace

so you'll always have

and

greatest version.

someone you can

of programming a scene graph API

and my own PLIB/SSG. Both

and can be downloaded from the Web with

distributions

to get the absolute latest

and developer community,

now

is

It

and learn from. Probably the two most popu-

rip apart

scene graph APIs for games under Linux right

source code

in Gaiyies

G-r-h-f-hs

this

are pre-installed

DfenGL

n

full

Each has a thriving newsgroup

d^

ask for help.

very different from the

although most of these libraries use similar terminology and even allow you to

OpenGL approach, mix raw OpenGL and

j

higher-level constructs.

In

PLIB/SSG

for example,

into a tree structure.

The

structures containing the (called branch nodes), tree, is

From

node

a

you construct your 3D scene

as a collection of

leaves of the tree contain polygons, lines,

OpenGL state

which are grouped

and points

organized

class objects

as well as pointers to

elements. Leaf nodes are grouped into higher-level objects in turn into yet higher-level objects until, at the root of the

that contains the entire virtual world

and

that point on, the entire scene can be efficiently

For the game software to interact with

C++

all

the information that's

drawn with a

this virtual world,

needed

to

single call to the scene

you use various

special

nodes

draw

it.

graph API.

in the tree that

allow objects or subobjects to be rotated or positioned within the scene. Other nodes allow you to automatically

draw simpler versions of objects when they are farther away so that you can save your precious

more

polygon-generating capacity for drawing things in different versions of objects

they've

been destroyed or

under program control so

after a

All of this flexibility allows the play, leaving

it

to the scene

Let's look at a simple libraries

with

game programmer

graph API

to

to concentrate

handle the ugly

on the

details of

after

SSG

is

is

a

is

a suite of portable

a Simple Scene Graph. Because

the scenes,

written in C++ because PLIB/SSG

higher-level aspects of game

drawing the pictures.

example using the PLIB/SSG scene graph. PLIB

designed to work well with OpenGL;

is

camera. You can also select

you can have things look different

key has been turned in a lock.

GLUT and relies on OpenGL behind

example

detail closer to the

that

C++

much

game

SSG works well

of what follows should be familiar. This

library:

1

ISIWBK

Linux Gaiyie -F^ROGR-RiYimiNG

//include

//include

i

n

//include

void redi spl ay

(

)

;

void ini t_graphi cs int main

glutlnit

I

)

;

char **

int.

(

(

gl utlni tDi spl

(

argv

&argc,

(

)

ayMode

(

)

;

GLUT_RGB

GLUT_DOUBLE

|

glutlnitWindowSize 640, 480 "My First OpenGL Program" gl utCreateWindow gl utDi spl ayFunc redisplay (

)

;

(

(

s sg

i

n

gl

i

I

n

i

t

(

)

)

;

;

;

t_g r a p h i

cs

utMai nLoop

return

)

GLUT_DEPTH

|

(

(

)

)

;

;

;

}

The main program

is

routine, called ssglni

quite similar to the t

(

),

that sets

up the SSG

Initializing the graphics system entails

ssgRoot *scene = NULL

(

)

;

addKid ->

(

;

transform

addKid

"my_object ac"

(

transform = new ssgTransform ->

setup:

(

scene = new ssgRoot

transform

Chapter

library.

some OpenGL

ssgEntity *object = ssgLoad

scene

in

;

ssgTransform ^transform = NULL void ini t_graphi cs

OpenGL examples

(

object

;

)

;

)

)

;

6.

There

is

a

new

initialization

glClearColor gl

Enable

O.Of,

(

0.5f.

GL_DEPTH_TEST

(

)

)

n

;

(

sgVec3 pos

sgSetVec3

)

)

;

;

0.2f,

pos,

(

ssgGetLight

The ssgLoad(

->

)

(

-0.5f,

0.5f

setPosition

)

;

pos

(

i

)

3D model from a file on disk into an ssgEnti ty class object. The code which we can insert the object. You can have any number of independent

function loads a

then creates a scene into

—for example, one for each of the different

scenes

The next

)

;

ssgSetFOV 60. Of, 40. Of ssgSetNearFar l.Of, 700. Of (

l.Of

O.Of,

levels in a

game.

another type of SSG object, a transform. These three objects are then connected

line creates

into a tree containing parent

and

scene; then connect the object

child nodes.

First,

we add

we loaded underneath

the transform as a child of the whole

the transform.

more than just these three levels in the scene graph because ssgLoad( have created several dozen more objects that are connected as kids of object.

In fact, there will be bly

The remainder of the

function sets

up

of view and the near and far clip planes),

The

third function

void redi spl ay

is

(

the redi spl ay(

)

)

OpenGL states: the perspective OpenGL light sources.

the usual

function,

and

it

works just

like the

=

examples

in

;

sgCoord campos

;

sgCoord objpos

;

/* Spin Tux,

sgSetCoord sgSetCoord

(

make the camera pan sinusoidally left and right */ & campos. O.Of, -5. Of. l.Of. O.Of. O.Of. O.Of )

objpos.

(

&

transform

setTransform

(

->

campos

O.Of.

O.Of.

&

ssgSetCamera

)

O.Of.

;

(

&

objpos

)

;

a.

O.Of.

O.Of

)

;

proba-

parameters (the

{

a

will

and one of the

^define R0TATI0N_SPEED l.Of

static float

)

;

Chapter

6:

field

fRDGRfllYllYllN

fllYl€

glClear ssgCul

P n

1

L_C

G

(

AndDraw

L

R_B U F F E R_B I T

(

scene

gl

utPostRedi spl ay

gl

utSwapBuf fers

This example creates two

(

(

)

sets

)

G

L_DEPTH_BU FFER_B IT

)

;

)

;

;

of positional coordinates: one for the camera and another for the object.

up the X, Y, Z, coordinates and the heading, pitch, and roll values for both the camera and the model. Unlike OpenGL, SSG lets you specify the camera position simply and directly. sgSetCoord(

calls set

)

The ssgSetCamera( location of

all

call

positions the camera.

node and everything

tions the object

J

)

The transform- >setTransform(

)

statement

inside

it.

After the screen has been cleared, the entire process of drawing the scene requires just

ssgCul

1

sets the

the child nodes beneath transform in the scene graph. In this example, this call posi-

AndDraw

(

)

one SSG

call:

walks through the scene graph, drawing just those parts of the scene that appear on-

screen.

SSG

is

and

to create simple graphical user interfaces, all using

A full

a part of a larger suite of graphics

discussion of

this brief

SSG

and sound

(or any other scene

enough

introduction should be

to

libraries that includes

code

to load

and draw

fonts

OpenGL.

graph for that matter) would

encourage you

fill

a

book

in

itself.

However,

to visit http://plib.sourceforge.net to find

out more about PLIB/SSG.

PL1E/5 5G! HTTFi//PLiei5QURCeFQRGEiN€T

FYlaVlNG For some

3D games,

games, there is

T-H-E CfllYIEKfl

is

the "camera"

no problem

really

is

attached to the player's character. For these kinds of first-person

in deciding

where

to place the

camera. In games such as Quake,

the preferred mechanism. However, other styles of game such as racing

adventure/RPG games, the camera must be moved er's

character in view

is

a deep subject, and one that

The problem

is

that

director

camera

all

to

you wind up having

rolled into one.

be

in

games and third-person

by the game software to keep the play-

—without being moved behind obstacles or ending up embedded

Moving the camera right.

intelligently

One

strategy that

many

seems

to

each room or other area of your game

in the scenery.

games come far from getting of Hollywood cinematographer and

third-person

to play the roles

work level

make a list of good places for the and to move the camera smoothly

is

this

to

.

U51NG

between those positions depending on where the

game, you find that there

is

DPENGL

player's character

is

IN GfllYlEB

at the time.

If,

in testing the

a place to which the player can go where he's hidden from the camera,

you can simply add another camera position closer

to the plaver that

does have a good view.

some control over the camera. You have to be careful not to allow him to move the camera somewhere where he may see something that he shouldn't (for example, he should not be able to move the camera inside a locked room to which he doesn't yet have the

Another approach

is

to allow the player

move

key). If you restrict the player's ability to line of sight to the player, this flexibility

For racing games,

However, screen,

this

it's

the camera only to places where the camera has a clear

should be a

tempting to place the camera

tends to look very

and you only see

it

artificial

at

gambit.

a fixed position behind the player's vehicle.

because the vehicle ends up nailed to the center of the

exactly square-on

position of the player in every frame

fairly safe

and

from the

rear.

to position the

A better approach

camera back where

is

a half-second ago. This simple trick works surprisingly well; as the player turns, that turn on-screen immediately, if

and a half-second

you brake suddenly, the camera

fall

will

come

later,

the camera catches

in closer to the vehicle; as

to

remember

the

that position was (say)

you see the

up and

effect of

follows. Similarly,

you accelerate, the camera

will

behind.

Even

in this case,

it's

nice to provide the player with a

the player to control the

amount of delay

in

little

camera control

camera positioning, which,

(for

example, you can allow

in effect,

moves

it

in closer or

farther away)

One problem with second

later.

er stops will

stop

this

approach

that

This condition requires a

if

him a halfcan detect when the play-

the player stops dead, the camera will crash into

little

adjustment to the code so that

moving and can then stop remembering old

positions

when

it

that happens.

Now the camera

moving whenever the player does.

Advanced The

is

Lig-hting

current spate of First Person Shooter (FPS) games

with flickering torchlight

and

brightly glowing energy

is

mostly set in dark, dungeon-like locations

weapons shooting along

corridors.

The standard OpenGL lighting model really doesn't cater to lighting of this sophistication. If you need shadows in OpenGL, you need to model them yourself—probably as dark, translucent polygons that overlay the walls and floors. The current generation of FPS games uses a technique called light-mapping to apply custom-made texture maps that mimic shadows to otherwise normally lit walls.

One

serious

problem with OpenGL's standard

lighting

model

is

that

it's

computed

before

applied to the model. Because textures have to modulate the results of lighting, there

amount of light to brighten up some kinds of objects.

is

texturing

no way

is

for any

the dark parts of your texture map. This can cause serious problems for

Linux

1HD

In

my games

The

I

use textures to

most of a penguin's body need

to

be

map Tux's

features.

However, no matter

shiny.

However, the black

how

shiny you

make

polygon colors are multiplied by the black texels in the map, and the

his body, the resulting white is

Linux penguin,

that star Tux, the

feathers that cover

result

PRDGRfliYiiYiiNG

G-hiyi-e

always black.

solution

is

to

render the textured polygons and then to draw them again

gons with white specular

OpenGL glBlendFuncO

colors. Setting the

as untextured black poly-

function to add the incoming

color to the color already drawn results in only the shiny spots in the second pass showing. It's

produce

possible to

niques. However,

all

kinds of interesting effects with these kinds of multilayered rendering tech-

on older graphics

wind up drawing each polygon

cards, these effects can

be considerably expensive because you

several times, often with the least-efficient pixel-blending

modes.

some modern 3D cards implement OpenGL extensions to render and combine multiple texture maps at the same time. This certainly avoids the cost of transforming the geometry several times, but the fill rates for many cards slow down proportionately to the number of texture maps that

Fortunately,

are being applied, so the net gain in

Putting The

rate

fill

may be

close to zero.

All Tdget+her

It

following sample code demonstrates most of the techniques discussed in this chapter.

found on the CD-ROM, along with a Makefile

to

compile

it.

//include //include /* Include definitions of the OpenGL API

*/

//include /*

Include definitions of the GLUT API */

extern void redisplay

void

(

extern void initCamera

extern void loadTextures int main

(

gl

(

(

;

)

;

void

)

char **argv

int argc,

glutlnit

)

void

(

&argc,

argv

utlni tDi splayMode

(

)

;

)

;

GLUT_RGB

GLUT_DOUBLE

|

glutlnitWindowSize 640, 480 gl utCreateWi ndow "My First OpenGL Program" gl utDi spl ayFunc redisplay (

)

(

(

)

;

|

GLUT_DEPTH

;

)

;

)

It

can be

Using

loadTextures i

nit Camera

(

(

)

)

DpenGL

in G-riyi-es

;

;

h Enabled ientState

(

glEnableCl ientState

(

gl

gl

Enabled ientState Enabled ientState

gl

utMainLoop

gl

return

(

)

GL_NORMAL_ARRAY GL_C0L0R_ARRAY GL_TEXTURE_COORD_ARRAY GL_VERTEX_ARRAY )

)

(

(

;

;

)

)

;

;

;

unsigned char texture

16

[

=

]

{

OxFF,

0x00,

0x00,

OxFF,

OxFF,

OxFF,

OxFF,

OxFF

OxFF,

OxFF,

OxFF,

0x00,

OxFF,

0x00,

0x00,

OxFF

unsigned int texture_handl void loadTextures

e

;

(

void

(

1,

(

GL_TEXTURE_2D, texture_handl

)

f

GenTextures glBindTexture gl

texture_handl

&

e

)

;

gluBuild2DMipmaps(GL_TEXTURE_2D,GL_RGBA, GL_RGBA, GL_UNS GNED_BYTE, texture);

2,

e

)

;

2,

I

glTexParameteri

GL_TEXTURE_2D, GL_TEXTURE_MAG_FI LTER, GL_NEAREST glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_MIN_FI LTER, GL_LINEAR_MIPMAP_LINEAR glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_WRAP_S GL_REPEAT glTexParameteri GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT (

(

)

;

(

,

(

glBindTexture

(

GL_TEXTURE_2D,

)

;

)

;

)

;

)

Linux G-nm-E FROGRflmiYiiNG IlVJK*

void initCamera

void

(

)

{

/* Select the Projection matrix */

GL_PR0J ECT ON glMatrixMode gl Loadldenti ty( I

(

)

;

)

#1f

glOrtho(-l. 1,-1. 1.-1,1); #else gluPerspective 40.0, 1.333, 0.1, 100000.0 (

#endi /* Go

back to the ModelView matrix */

glMatrixMode

tfdefine

GL_M0DELVIEW

*

3

[

NUM_VERTS

;

]

0.408248f

0.707107f 0.707107f 0.707107f 0.408248f

0.816497f, 0.408248f

0.408248f

O.OOOOOOf, 0.707107f

I

)

NUM_VERTS (3*4)

normals

float

(

O.OOOOOOf, 0.707107f O.OOOOOOf, 0.707107f

0.816497f 0.816497f

0.408248f

0.408248f 0.408248f 0.408248f

-0.816497f -0.816497f

0.408248f

-0.816497f

0.408248f 0.408248f

0.408248f

O.OOOOOOf, O.OOOOOOf,

l.OOOOOOf

,

O.OOOOOOf. O.OOOOOOf,

l.OOOOOOf

,

O.OOOOOOf, O.OOOOOOf.

l.OOOOOOf

colors

float

[

3

*

NUM_VERTS

1

Of.

O.Of

.

O.Of

1

Of.

O.Of

.

O.Of

1

Of.

O.Of.

O.Of

Of.

l.Of,

O.Of

Of.

l.Of.

O.Of

Of.

l.Of,

O.Of

/*

]

=

Red */

/* Green

*/

)

Using

float

O.Of.

O.Of.

l.Of.

O.Of.

O.Of,

l.Of.

O.Of.

O.Of,

l.Of,

l.Of,

l.Of,

O.Of,

l.Of,

l.Of,

O.Of,

l.Of.

l.Of.

O.Of

texcoords

/* Yellow */

n

]

1

O.Of.

O.Of,

-5. Of,

float

-5. Of.

5. Of.

-5. Of.

O.Of.

O.Of,

5. Of,

-5. Of,

O.Of,

5. Of,

O.Of,

O.Of.

O.Of.

5. Of,

-5. Of.

-5. Of.

-5. Of.

-5. Of.

O.Of.

5. Of.

5. Of,

-5. Of

vertices O.Of,

-l.Of

[

O.Of. ,

3

*

NUM_VERTS

O.Of,

-l.Of.

-l.Of,

l.Of.

-l.Of,

O.Of,

O.Of.

l.Of,

-l.Of,

O.Of.

l.Of.

-l.Of.

O.Of.

O.Of,

O.Of.

O.Of,

l.Of.

-l.Of,

-l.Of

.

-l.Of

.

-l.Of,

O.Of, -l.Of.

-l.Of,

-l.Of.

-l.Of.

-l.Of.

O.Of.

l.Of.

l.Of.

-l.Of.

in Gaiyieb

/* Blue */

NUM_VERTS

*

2

[

DpenGL

-l.Of.

-l.Of

]

=

Linux Gaiyie -P«

unsigned short indices i 0,

1,

2,

4,

3.

NUM_VERTS

[

6,

5,

8,

7,

=

]

10,

9,

11

[

void redisplay

void

(

)

{

ROTAT 1 0N_SPE ED l.Of static float a =

^define

;

I

4

]

=

1

l.Of,

l.Of,

l.Of.

l.Of

}

;

[

4

]

=

{

O.Of,

O.Of,

O.Of,

l.Of

}

;

3

]

=

{

[

3

white black

float

pos

float

dim_white

[

glEnable

J

[

float

float

(

1000. Of, =

{

GL_LIGHTING

)

]

5000. Of,

O.Of

}

;

0.3f,

0.3f

}

;

0.3f,

;

glMaterialfv GL_FRONT_AND_BACK, GL_EMISSI0N, black glMaterialfv GL_FRONT_AND_BACK, GL_SPECULAR, white glMaterialf GL_FRONT_AND_BACK, GL_SHININESS 5. Of glEnable GL_COLOR_MATERIAL (

)

;

(

)

;

(

,

(

)

(

glLightfv glLightfv

(

(

glEnable

(

glEnable

(

glEnable

(

;

GL_FRONT_AND_BACK, GL_AMBI ENT_AND_DI FFUSE GL_LIGHT0, GL_AMBIENT dim_white GL_LIGHT0, GL_DI FFUSE white GL_LIGHT0, GL_SPECULAR, white GL_LIGHT0

glColorMaterial

glLightfv

)

;

(

)

,

.

)

;

)

;

;

GL_BLEND GL_ALPHA_TEST )

)

;

;

)

;

glAlphaFunc GL_GREATER, O.Olf glBlendFunc GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA glEnable GL_DEPTH_TEST (

)

;

(

(

)

)

;

;

glClearColor O.Of, 0.5f, O.Of, l.Of /* Dark Green */ glClear GL_COLOR_BUFFER_BIT GL_DEPTH_BUFFER_BIT )

(

(

a

+= ROTATION_SPEED

|

;

;

)

;

)

Ueing DfenGL

gl

Load I den ti ty

glTranslatef

(

)

glLightfv

(

glRotatef

(

/*

texture */

Pick

a

O.Of,

-10. Of

)

;

GL_LIGHT0, GL_P0SITI0N, pos a, O.Of, O.Of, l.Of )

II

)

;

Enable GL_TEXTURE_2D glBindTexture GL_TEXTURE_2D, texture_handl e glColorPointer 3, GL_FL0AT, 0, colors glTexCoordPointer 2, GL_FL0AT, 0, texcoords gl

)

(

;

(

(

)

Normal Poi nter

(

gl

VertexPointer

(

glDrawElements gl gl

3,

G

(

utSwapBuffers utPostRedi spl ay (

Hopefully by

GL_FL0AT,

L_T R I A N G L E S

)

(

)

On

the

sorts

;

;

vertices

)

;

NUM_VERTS, GL_UNSIGNED_SH0RT,

,

indices

)

able to handle most of the graphics requirements for your future hit try

adding some funky graphical

effects. If so,

you may want

to visit

such as http://www.opengl.org and http://www.flipcode.com.

OpenGL Web site,

depending on

)

;

now you should be

sites,

0,

)

;

;

games; however, you might want to

some Web

normals

0,

GL_FL0AT,

)

;

(

gl

GflmEB

;

O.Of,

(

in

there are links to

his current employer) This .

Mark

Web

Kilgard's

site is filled

Web

site

(which moves once in a while,

with various

OpenGL

tutorials for use in all

of applications.

I

Linux

W|

HHIHIH w&BB^^^M

n

l

CHAPTER

8

ound Under Linux

''•jtir""

Gome -Programming

Linux

This

is

where things

start to

get

the right libraries. Fortunately, Loki

audio

a lot easier.

life

Sound under Linux

tricky.

Of course, SDL

is

a tough thing to

makes an OpenGL-like API

called

do

if

OpenAL

you don't have

that

makes your

sound support.

also provides simple

DPENflL OpenAL (Open Audio (Open Graphic

Library)

Library).

immersion into the environment. the documentation for

library with

an API similar to

OpenGL

much essential in today's games, allowing total You can download OpenAL from http://www.openal.org or use the

3D surround sound on the

version in the libs directory this,

an OpenSource 3D sound

is

is

CD-ROM

OpenAL

is

less

pretty

that

accompanies

this

book. At the time

than complete, but hopefully someone

I

will

am writing

complete

it

before too long.

OPEN-RL: HTTF://wUJUJiOf7eNflL.ORG If you

plan to port your

because

H

it

look at

to other platforms,

coding

Elvis.) If

is

DfenAL

as easy as eating pie. (For

you've read the

tions (just replace the gl at the

Okay,

it's

basics of

not quite that

first

function

last

is

the perfect choice for the audio API

thing your al

it's

*

it's

very easy. Just

name

with

al

,

and you're

away).

not far from the truth. The following sections are dedicated to the a

WAV file

to achieving full

3D surround sound.

and Loading Sam-rues

OpenAL

cCreateContexU

ALAPI void

you non-American readers, that means

beginning of the function

but

easy,

-H-f-fli cation

two chapters, you should already be familiar with the basic func-

OpenAL, ranging from loading

Initializing The

OpenAL

compiles for various operating systems, including Windows and the Mac.

5irn-PL-E

OpenAL

game

application must

).

ALAPIENTRY

The al

do

is

create a rendering

function prototype for this

is

context.

as follows:

cCreateContext ALi nt *attrl1st): (

This

is

achieved with the

)

;

Sound Under Linux

This function returns a context identifier that

ment

is

an array of attributes

be used

will

later in the

to use in creating the attribute

list.

program. The attrl i st argu-

You can use a combination of several

options for this argument, as listed in the following chart:

Attribute

Name

Description

[

The frequency of the sound to use, followed by the frequency to use. The resolution of the soundform, followed by the bit rate to use. The size of the sound buffer, followed by the size in bytes of the buffer. The larger the buffer, the longer the delay in playing the sound, but the

ALC_FREQUENCY

ALC_RES0LUTI0N ALC BUFFERSIZE

smoother the

results.

The number of sound channels End of the attribute list.

ALC_CHANNELS ALC INVALID

The use of these attributes varies slightly from most APIs. The how to implement these attributes: ^include !

#include #include int main(int argc,

void **argv)

{

Use 22khz samples ATuint ^attributes = {ALC_FREQUENCY //

ALC_INVALID}

,

22050,

;

void ^context = NULL; //

XXXI

Attempt to create the OpenAL context context = al cCreateContext(attri butes if (context == NULL) //

)

{

fprintf (stderr, return

//

"Can't create context")

1;

XXX2

Clean up cDestroyContext( context return 0; //

al

to use.

following code sample demonstrates

?.MMJ&*miw&m-mfflW'Jifflit&'

Linux

15D

PM^H

FRDGRflmmiNG

Gfiiyie

m

This simple sample creates an audio context and then destroys actually

need

to play

it.

.

Useful, no? Well, not really.

Now we

some sounds!

Creating Listeners Before we can set up a sound source, we

first

need

OpenAL where exactly the listener is in the scene. We do this in the same way that we'd set up a camera position in OpenGL before drawing any tetrahedrons. We establish the position of the listo

NOTE

tell

You are limited to omy one listener per scene, but you can move the current listener around to create the illusion of multiple sound sources.

tener using a series of calls to a function called

alListenerfvO. This function ways to the

The

OpenGL vertex and

function prototype for

ALAPI void

The

first

is

al Li

ALAPIENTRY

*

argument, pname,

is

many

similar in

lighting functions.

stenerfv(

al Li

the

)

is

as follows:

stenerf v( ALenum pname, ALfloat *param);

name

of the property

we want

change. There are three possible

to

options here: AL_P0SITI0N (the position of the listener), AL_0RI ENTATION (the direction), and

AL_VELOCITY (the speed). tion

and direction of the

Where our

little

The

properties we're interested in at the

moment are

the

first

two, the posi-

listener.

sample code has the

comment

XXXI,

add the following two

listener_pos[3] = {O.Of, O.Of. O.Of}; ALfloat listener_dir[3] = {0.0, 0.0, l.Of, O.Of,

lines of code:

ALfloat

These statements

specify the coordinates (the middle)

l.Of,

O.Of):

and the direction of the

listener (facing for-

ward) Before these values are used by OpenAL, you need to inform the API of these .

tant, facts.

//

Add

the following code to where the

Set up the

stener Listenerfv(AL_P0SITI0N,

comment

reads XXX2:

1

istener_pos) al Li sten*rfv(AL_0R ENTATION, istener_dir) // Stationary listener, so no Doppler shift needed a!Listener3v(AL_VEL0CITY, O.Of, O.Of, O.Of); al

I

1

;

1

;

little,

but impor-

;

(

;

;

Bound Under Linux

Loading

Sound

-r

We're almost ready

to play a

number of ways

are a

being

to

do

-File

sound (not but

this,

sadistic; later in this chapter,

will

I

we have to load a sound into memory. There focus on the more complicated method here. I'm not just

really),

will talk

I

but

about streaming buffers, and you

to load the samples without assigning a buffer to

The

function alutBufferAndConvert_LOKI(

added by Loki) converts a

al

them

to

do

will

need

to

know how

that.

which

(in the file alext.h,

is

an extension

to the

API

WAV file loaded into memory into an audio buffer that can be used by

OpenAL. The function prototype ALAPI ALboolean

)

first

shown

is

here:

utBuf ferAndConvert_LOKI ALui nt ALbid, void *data,

ALboolean dummy, ALuint size);

The first argument when assigning the final

argument

ment

The

is

is

the buffer identifier of the sample to convert. These are user-definable,

and used

The next argument is the WAV sample data to convert, and the (in bytes). The dummy argument is exacdy that: a dummy argu-

buffer to a source.

the size of the data

that should be set to AL_TRUE just to be safe.

following code demonstrates

program

after the block of

fp = if

f open(

(!fp) //

how

code that

"boom. wav"

,

to load a

set

up

into a buffer.

the listener.

"rb");

{

Clean up and quit

fprintf (stderr, "Can't load al c Destroy Con text (con text) return

//

WAV file

file

boom.wav\N"

)

1;

Read the WAV data

datajen = fread(data, f cl

ose(fp)

if

(

1,

DATABUFFERSIZE

,

fp);

!alutBufferAndConvert_LOKI(sound_buffer, data AL_TRUE, datajen)) fprintf (stderr, "Invalid {

return

1;

file

format\n");

Add

it

to

our evolving sample

r

Linux

152

P-ROG-R-RmmiNG

G-riyi-e

,

Add

the following lines at the XXXI //

A

comment:

(2048*1024)

void *data = (char *)mal

f

l

2MB sound buffer

#define DATABUFFERSIZE

p

^amw^f%' fve

1

oc( DATABUFFERSIZE)

;

int data_len = 0; int sound_buffer = 0;

[

Sound Sources

C-r-e-rting Now that we've

loaded a sound sample into a buffer, we have to create the sound source that

playing the sound. are

The sound

more than one

will

be

sources are created in a similar way to listeners, but the functions (there

this time) are called al Sou

position of the source, however,

you must

first

reef v(

)

and

al

Sourcei

generate the source.

(

).

The

Before you can define the function

a

1

GenSources

(

)

does

this for you.

:

ALAPI void ALAPIENTRY

The

first

argument,

n, is

the

al

GenSources( ALui nt

n,

number of sources you want

an array containing the source

identifiers

you want

ALuint *sources); to create.

to use. In

The second and

final

argument

is

our example program, we need only one

source.

After you have generated the source, you

method you used

to set

up the

listener.

must define the position of the source using the same

In addition to setting

the sound source, you also must specify which

up the

position, direction,

sound buffer the source

will

and

be playing. This

velocity of

is

defined

by the AL_BUFFER property.

Add

the following code to the sample

program

after

we load

the sound

sound source: // al

Generate

single source

a

GenSources(

1

,

&source);

// Set up the source details alSourcei (source. AL_BUFFER, sound_buf fer alSourcei (source. AL_S0UND_L00PING, AL_FALSE); )

Sourcefv(source. AL_P0S T ON source_posi tion alSource3v(source. AL_VEL0CITY. O.Of, O.Of. O.Of); al

I

I

.

)

file

to generate the single

Bound Under Linux

If

you're wondering what that extra property, AL_S0UND_L00PING

to loop the sound. If you

example), Before

code

set the third

this section

want the sound source

argument of a Source 1

of code

is

finished,

i

we have

loop

to )

(

a flag to specify whether or not

is, it's

you would with background music, for

(as

to ALJTRUE.

to define the source

number. Add the following

lines

of

to the variable declarations:

int source = 0; ALfloat

source_posi tion[3] =

l.Of.

O.Of,

1

.Of

Playing Sounds Now that we've

finally set

up everything

a source, you use the function

our example,

Add

this

value

is 0,

al PI

for playing the source,

aySource(

we can

actually play something.

),

which takes a single argument: the source

To

plav

identifier (in

or the identifier source).

the following code to our sample program, after the source

we

set

up

in the previous section:

Start playing the source

//

alPlaySource(source);

G-ETT1NG Under

STATE

certain circumstances,

not. This

when

T+H-E

is

an important task

the source

To read the

state

is

you may want if

to

you ever want

inactive (that

is,

EDUND

O-F T+HE

check whether a source to delete a source

currendy playing a sound or

is

because you can delete a source only

not playing).

of a given source, you can use the function

a

1

Source

i

(

)

with the property

AL_SOURCE_STATE and a pointer to an integer as the property value. The variable pointed to by the third

argument will

Add

specify

whether the current source

is

being used.

the following code to our sample program, after

we

start

playing the source:

int state = AL_ACTIVE;

Loop while the sound is playing while (state == AL_ACTIVE) //

{

//

XXX3

alSourcei (source, AL_SOURCE_STATE

,

&state)

'*tw3j

iJ**n'-jl

15H

OUND5

iTOFFING 1

If

HnHH^^H

-S*«j

u'OVtnls:

Linux Game- PROG«-HiYimiNQ

you ever have

to stop a

sound prematurely, you can use the function alStopSourceO. This function

takes a single argument: the source

number

to stop playing.

f

Deleting a Bdurce

1

When you

have finished with a source, you can safely destroy

function takes the same form as

created to // al

GenSources

(

Add

).

by calling alDestroy Sources 0. This

the following code after the while loop

Delete the sources

DestroySources(

t-he-

1

&source);

,

Source

Although the sample program

will

play a

sound

as

it is

currendy written, the code doesn't exploit any

of the decent capabilities of OpenAL. Without improving the code, data to /dev/audio (which

One

OpenAL makes

more complex look

is its

3D sound

sample program as

slightly off center.

it is

This was done for a reason.

ple will

bounce the source around the screen

i

we have n

OpenGL a breeze;

who I'll

don't like

cover the

currendy written, you should notice that the position of the

is

top of the ma

raw audio

stuff later.

at the

this trick,

as well stream

capabilities (stereo sound for those

integration of audio features with

listener

For

we might

a bad thing).

is

of the attractions of OpenAL

sales pitches).

If you

we just

the state of the source:

test

IYIdving

J

al

it

(

)

to declare

to

The next block of code

we'll

add

to the sam-

demonstrate the stereo capabilities of OpenAL.

another variable.

Add

the following code to the declarations at the

function:

AUfloat move = 0.05;

To

actually

move

the source,

all

we have

to

do

is

alter the

AL_P0SIT ON property. This I

following block of code, which should be inserted where the XXX3

comment

//

Bounce the source around

if

(source_posi tion[0]

>

l.Of

source_posi tion[0]


sin_add r) //

)

server->sin_port = htons(PORT); server->sin_fami ly = AF_I NET ;

Attempt to establish connection if (connecU sock server, sizeof (sockaddr_in) perror( "Socket error:"); //

,

return

1;

)

== -1)

//

Send an HTTP request

send(sock, http_request

m

,

strl en( http_request

)

0)

,

descriptors for select() FD_ZER0(readfd); FD_SET(sock, readfd); //

Set up

file

Allocate some memory for receiving data buffer = (char *)mall oc(BUFFERSIZE) //

;

//

Message receive loop

while (1) if (select(2. {

//

readfd,

NULL,

Message to be read

.

NULL,

0))

{

.

recvfrom(sock, buffer, BUFFERSIZE, fprintf (stdout buffer);

NULL)

IULL,

,

// cl

We

'

re done.

ose( socket)

return

0;

Creating

-h

Server

A server isn't that different from process for a server. Depending

a client, except that a bit

more

effort

goes into the

initialization

on the type of server you're working with (TCP or UDP), there are a

number of extra

functions you have to

Binding

t-h-e

call

before your program

is

ready to

start

serving data.

Socket

Instead of connecting to a server after you create the socket, you have to bind the socket to a specific port. This

needed

is

achieved using the bind() function

if

you are using TCP.

If you

at this point.

int bind(int sockfd,

struct sockaddr *my_addr,

int len);

are using

UDP, no

action

is

The

first

argument

the more-than-familiar socket descriptor.

is

The next argument, my_addr, is a up this structure in

pointer to a structure containing information about the local address. You set

same way

as

when you

member of the

are establishing a socket using connect

sockaddr_i

n

structure to INADDR_ANY.

The

(

final

),

except that you set the

argument

for bi nd(

)

is

si

the

n_addr

the size of

the local address descriptor.

Using

"MstenO

t+h-e

After you have

bound

the socket to a port, you

accept connections. This

int listenO'nt s, This

first

argument

many connection The

1

i

sten

(

)

is

-Function

is

must

the

tell

achieved with the function

1

c^

i

TCP/IP subsystem

sten

(

that

you are

willing to

):

int backlog);

—yep, you guessed —the socket descriptor. The next argument it

requests can be

function returns a

queued

at

specifies

how

any one time.

on success or a -1 on

error.

Accepting Connections After you have called

1

i

sten(

),

you can

received by calling the function accept

int accept(int s,

(

start

your main server loop. Incoming connections can be

).

struct sockaddr *addr,

int *addrlen);

move on to the second. The sockaddr structure is where to store the address of the remote client. Depending on how you implement your server, you may want to store this information in a linked list of other addresses, or pass this value on to a new thread to handle that client's information. I

really don't think

The accept earlier to

(

)

need

function

is

to say

what the

first

argument

a blocking function, so you

is,

so

I'll

may want

to use the sel ect(

)

function described

check whether there are any incoming connections before calling accept(

the socket

is

).

In this scenario,

regarded as data to be read.

From here on as

I

in,

the rest of the server operations are pretty

sending and receiving data.

much

identical to client operations, such

ll

U DP

Because data to a

n

is

a connectionless protocol, anyone can send have to do is

UDP server. This means that all you

in the same way you would for a client and then wait for incoming data using recvfrom( ).The server is not notified of an incoming connection because there are no connections to be established. The only time a UDP server knows about the clients is when the clients

to create the socket

actually transmit

some data to the

server.

Because of this, you may want to keep a list of all UDP have sent data to the server. When you have to notify all clients about a change in the game environment, you can refer to the list of connected machines to get the details about the remote clients. clients that

Because

UDP is faster than TCP— and

essential in real-time applications

game

because speed

is

—writing the code for

servers can be a lot of hard work.

It

can also be quite

rewarding at the same time. Ask not what your client can

do

for you, but

what you can do

for your client.

f

Threads

-find

Because a network subsystem

is

N

relatively

another thread for processing network

WORKING

independent from the

traffic.

rest

of your game, you

may want

Depending on the type of application you

to use

are working

with (client or server), there are different approaches to use.

At

this

point in the book,

this library to create extra

The most

I

want

to introduce a library called pthreads

threads within an application.

useful function in the pthread library

in a process.

The

is

It is

int pthread_create(pthread_t *thread,

pthread_attr_t *attr, void *(*start_routine) void *), (

void *arg);

)

is

threads).

You can use

included with most Linux distributions.

pthread_create(

function prototype for pthread_create(

(POSIX

),

shown

which creates a new thread with-

here:

;

The

first

thread.

argument, thread,

is

The next argument,

where you want

a pointer to

to store

an identifier for the newly created

attr, contains the attributes for the thread. For now,

it's

safe to specify a Ir

value of NULL for this argument (this

is

a chapter on networking, not threads).

start_routine,isa pointer to a function that

will

be started

The

third argument,

The

in the separate thread.

final argul

ment, arg, specifies any arguments you want to pass to the thread function.

When you want calling return.

to

end the

For more

thread, you

details

end the thread function just

on the pthreads

library, see

the

as

man

you would a normal function: by

pages.

i

LL1€NT5 When

it

comes

to client-side networking,

ing from the network code unlikely). as sendto(

a

—unless your game

By running the network code )

it's

damned good is

logic

and render-

100 percent dependant on the network data (which

in a separate thread,

causing an interruption to the game.

game

idea to isolate the

Remember

you don't have that sendto(

)

to

worn- about

blocks,

calls

is

such

and there are few

ways to prevent that from happening. If you

(the

c

decide to run the network code in a separate thread, you must provide a way for the two threads

game thread and

the network thread) to communicate.

The

first

method

I

will

demonstrate

is

the

use of flags to signify important events, such as quitting the game.

Using

Rags

to CommuNic-HTE between T+h-re-rds

In the thread that processes user input, al

variable that

is

you might have an event such

checked within the network thread loop,

extern bool quit_game; extern int thread_count void *network_thread( void *data) //

Increase the thread count

thread_count++; //

Connect to server here

//

Main thread loop

whi

1

e( !qui

t_game)

{

// Do network stuff here

{

like this:

as quitting.

This even

sets a glob-

•VS.i'Ji^SMHB'/itt-?*.^/1 *-''

F

Ji-i."-''

I

M

//

End network stuff here

//

Reduce the thread count

thread_count-

-

f

return NULL;

1 In the

game

thread, the code to cause the thread to quit

quit_game = 0; int thread_count =

would look

like this:

bool

void mai n_l oop(

)

0;

{

pthread_t *net_thread; //

Create network thread

pthread(net_thread, NULL, network_thread //

NULL)

Do game stuff here

while(l)

{

Loop until

//

quit

NOTE Novell suggested this //

Tell

all

qui t_game =

whi

1

e(

threads to finish

all

>

0)

1

it's

If

Novell

the best way to do

must be some merit Do quit stuff here

for clos-

999 NetWare

Developers Conference. thinks

//

method

threads that are running on the

server at the

1

thread_count

ing

in

it.

On

it,

there

a side

you ever go to a NetWare Developers Conference, don't eat the food. It put me in bed for a week. note,

if

)

;

Using

Qu

FYI-ess-rg-e

SETWEEN

:ueb to CommuNicflTE

TfH-RHflDS

The other method of interthread communication I will discuss here done any Windows programming, you'll have a basic understanding

is

a message queue. If you've ever

of

how

the message retrieval

sys-

tem works. messages are stored in a queue.

Basically, all

GetMessage(

)

or PeekMessage(

)

to get the

When you want to

receive a message,

you

call

next message to be processed. These functions pull the next

message from the message queue and allow you

to act

on

it.

We'll use this identical idea for our multi-

threaded program. I

won't go into too

this

much

code somewhere

detail

in the

about queues, but

network receive loop

extern void *message_queue[QUEUE_SIZE]

extern int queue_posi tion //

I'll

demonstrate the basic usage here. You'd place

in the function network_thread(

;

;

Get message from receive queue

recvfrom(sock, buffer, BUFFERSIZE, from, &from_len);

0,

//

Add message to queue to be processed

if

(++queue_position > QUEUE_SIZE) queue_posi tion == 0;

message_queue[queue_posi tion] = buffer; In our

game

loop, the

queue would be read

as follows:

void *message_queue[QUEUE_SIZE] int queue_posi tion = 0; int queue_start = 0;

Read next message from queue if (queue_start != queue_posi tion // New message in queue, so process it //

)

{

process_message(message_queue[queue_start++] if

(queue_start

>

QUEUE_SIZE) queue_start

).

HIY1-E

rRDGRfllYimiNG

That simple (and probably very buggy) implementation of a message queue system should demon-

how

strate

1 With

this

to allow

messages received from the network thread to be read from the game thread

approach, the network thread can do what

it

does

best:

itself.

be a network thread.

n

5-E-RV-E-R5 methods discussed

In addition to the

nicks to lighten the load

when

it

in the

comes

preceding section regarding

to server

clients,

programming. The most

there are a few

common

separate thread for each client; then you can use the interthread communication in the

preceding section to pass messages between the threads.

When

a connection

fresh client as the

is

requested with accept

argument

to the client's

()

,

own

trick

is

more

the use of a

methods described

you pass the new socket descriptor associated with the thread. This approach removes the

need

to

keep a

database of sockets (which can be a pain in the backside to maintain).

The

following code demonstrates this theory: //

Accept the new connection

new_sock = accept(sock, NULL, //

Create

a

IULL);

new thread for said client

pthread_create(cl ient_thread

,

NULL,

client_func, &new_sock)

Pings Every so often during a game, a client

because there

is

no way

player activity using a

been since the that client

is

last

may be disconnected from

to automatically detect this situation.

number of methods. The

easiest

To combat

method

message was received from a particular

a server. This can cause problems

is

to

client. If

it,

you must keep track of

keep a timer of how long

it

has

the timer exceeds a specified time,

removed from the game.

kicked out of the

isn't necessarily the best course of action to take. If a client is not doing much game (dare I say that he might be camping?), he probably won't appreciate being game for it. Another approach is to send regular pings to all the clients.

A ping is a simple

message that contains the time the message was

Note that

this

at that point

message,

it

approach

of the

sends the message back unchanged.

The

sent.

When

the client receives the

server can then keep track of these ping times

and

.

base the timeout value on the time between pings being returned to the server. Again,

this

might cause problems with players who are suffering high latency (but

that bad, the

game would probably be You might

also

the latencv

is

make

sure that

it is still

sending and receiv-

server.

UJO-R-K1NG IN

All the stuff in this

if

it is)

client to use a keep-alive system to

and from the

ing data to

N

want the

pretty unplavable as

approach

chapter up to

this

Gflm

point

is

pretty generic

and can be used

anv application. The

in

next sections cover some systems that are applicable only in games, such as sending onlv user input

between the

D-e-hd

clients.

Reckoning

In fast-paced action

games such

as Quake, latenq'

on the network can cause major problems with the

game. Latency can be combated somewhat by the use of dead reckoning on the

When on the

the client isn't receiving messages from the server, last

known data

low-latency range, but acters suddenly jump

This jumpy behavior

until

if

it

receives an update

from the

server.

This

is

fine for

game

logic

games played

may have

based in a

noticed char-

around the screen. is

caused by the client assuming that the character

than the server thinks the character

will take.

gospel.

is

Because the server has

the server updates the client machine with the

changed since the

continues processing the

you've ever played Quake at a medium-ping range, you

environment, what the server says

When

it

clients.

last

update. At other times,

plaver changing direction or firing a weapon.

it

game

state,

it

will take

full

a different action

control of the

sends only the information that has

only sends minor changes that affect

The

client bases

its

gaming

logic

on

play,

such as a

a continuation of the

last

action sent.

There are further complications

to this system, such as the

infamous "death by lag" scenario.

If player

Bob is running towards a corner, and player Jim suddenly encounters some lag, Jim may see Bob running straight into a wall; he may then fire a few missiles and relax. Meanwhile Bob, who isn't affected by the lag, runs around the corner, sees Jim just standing there, and opens fire. Because the server processes only the data updates

all

it

has received,

the clients with that version of events.

it

considers Bob's

kill

to

have happened and

Linux

G-hiyi-e

FRDGRflmmiNG

Bending Controller Inputs 1 If

you have a server controlling the

the client generates to the server?

n

board and

to let the server

state

of game, why bother sending every single piece of data that

A better method is to send only what the user presses on

run the main

logic.

This approach not only reduces the amount of

experiencing a

bit

traffic

being sent over the network, but allows the

game. Note that there are some problems with

er full control of the

of lag. Such players

the key-

may

this system, especially for players

find that the server processes their input a long time after

they responded. This problem was prevalent in the original Quake Deathmatch (not QuakeWorld).

had about 200ms of lag, you

felt like

serv-

you were on

ice.

Your player would

slide all

If

you

over the place because

the packet spent too long updating your current direction (in Quake Deathmatch, the client handled

all

the looking around)

Although

a major problem,

this wasn't

it

did get annoying at times, and

it's

something you should

remember when designing your games.

It's

not

much

use giving the user the ability to play multiplayer games

a server running the game. This

is

where lobbies come into

if

he doesn't know where

play. Lobbies act as directories

to find

of active

game servers, allowing players to search a database of games and choose the one he wants to play. Some lobby servers also offer a pregame chat system and staging areas where people can plan tactics before being thrown head-first into a combat scenario. II

Most current lobby APIs are limited

to a single platform, restricting players to

competing against other

people using the same platform. APIs such as DirectPlay and Kage (DreamCast) also offer proprietary

game

protocols, adding a further barrier to interoperability.

DPENLOBEYT

UJ-H-RT 15 OpenLobby

(available at http://www.thisisnurgle.org.uk/openlobby)

is

OpenSource

client

API

(to allow

porting to various platforms),

the

first

OpenLobby

is

—even

provide the interoperability that cross-platform development requires

on other

platforms.

part of a project to

open protocol and an

eliminate the proprietary-ness of networking APIs for games. With an

:

DPENLOfieY! +HTTf»!//uJUJUJ.T+H1515NURGL€.DRG.U«/afENLaeeY

almost guaranteed to

if

you don't need

to use

it

!

Although

it's still

in early phases of

rooms

persistent users to multiple chat

shower of blood and

to the lobby server

(the server software

to offer

is

function ol_Connect(

er,

as well as

On

success,

game

use of ol_Connect(

is

a two-stage process.

First,

you must connect

t-h-e

)

it

does

this for you. It takes

returns a connection object containing

data (which

is

)

established later on).

The

all

):

f

Connect to lobby server server = ol_Connect( "127 .0.0. //

i

f

,

9090);

Check that the connection was established server->socket) fprintf (stderr, "Connection to server failed"); (

{

return

//

1"

XXX

1;

TCP connection

to the server.

the details about the lobby serv-

following sample code demonstrates the

olServer *server = NULL;

//

server.

two arguments: the IP address of the server and a

//include

nt mai n(

to a central lobby server

Lq-e-by 5e-rv-e«

//include

i

from

\

5-e-rv-e-r

Before you can even think about looking for games, you must establish a

port number.

features,

that permit users to socialize before killing each other in a

included with the client API), and then you must log in to the

Connecting to The

many

bullets.

Using Loeey Connection

development, OpenLobby promises

cL

Ga

Linux

The [|

ol

Server structure contains various details about the server, and

typedef struct

}

1NG

its

definition

shown here:

is

f

int socket;

//

Server socket

char IPv4[4];

//

Server IP address

unsigned int port;

//

Port on server

unsigned int user_id;

/ /

User id

unsigned int game_id;

//

Game id

olServer;

The member of interest at this point is the socket member. This is a run-of-the-mill TCP/IP descriptor (OpenLobby uses TCP, not UDP) On BSD systems, this value is on failure.

socket

.

Logging

In to

t-hhe

Ldesy

Scrv-e-r

After you have successfully connected to the server, you must log in

planning to

This process

play.

and

handled by another function, ol_Logi

is

n(

identify the ).

game you

This function

is

are

slighdy

more complicated than ol_Connect() because it passes several things (well, the server does several things; the client always sees the same thing). The function prototype for ol_Login( is as follows: )

unsigned int o1_Login(ol Server ^session, unsigned int user_id, unsigned char user_name[16] unsigned char password[16] unsi gned nt game_id) i

The

;

The next is the user identification number. If this value is 0, a user name must be specified. If a user name is specified, a new user is created on the server database (depending on the implementation). The next argument is the password, which is always required. If a new user is being created, this password is assigned to the user, otherwise it must first

argument

is

the session returned byol_Connect().

be the previously assigned password.

The

final

(Globally

argument

Unique

is

the unique

Identifier)

game

identifier.

This identifier takes a similar format to the

used by DirectPlay and

(assuming that they are 32-bit identifiers). This value ol_Logi n(

)

returns the user ID

on

success;

it

returns

is is

GUID

compatible with UIDs from other platforms

used to identify games of the same

on

failure.

type.

;

;

;

In the previous sample of code, replace the

Login to the server uid = ol_Login( server, 0,

comment

XXX with the following code:

//

lr

"New Player",

1); 1

Make sure that an error didn't occur if (uid == 0) //

{

ol_Bye(server fpri ntf stderr )

(

return

,

"Error login in");

1;

j

Finding G-hm-es Assuming

that you've successfully logged

OpenLobby

on

uses an enumeration callback

the ol_Fi nd Games

(

)

function

call.

to the server,

to get the

you can

start

game names; you

looking for games. specify this function with

This function takes two arguments: the session pointer and the

address of the callback function.

The callback function takes only one argument: The prototype for this function is as follows:

a pointer to a

game

definition (of type ol GameDef ).

void (*FindGameEnum)(olGameDef *gamedef);

The

ol

GameDef structure contains details about the games, including name, IP address, and

players.

The

structure definition looks like

this:

typedef struct unsigned int game_id; unsigned char game_name[32] unsigned char IPv4[4]; {

unsigned char IPv6[6]; unsigned int port; unsigned int max_pl ayers unsigned int num_players; I

olGameDef;

//

For future use

number of

Linux G-nm-E

15E

Add i

f

the following block of code to the start of our

little

sample program

(after the #i ncl ude statements):

olGatneDef *my_game;

void FindCal

1

BackCol GameDef *gamedef)

{

gamedef ->max_pl ayers "Game name: %s\n" gamedef ->game_name)

(gamedef ->num_pl ayers

if


num_parents == 4) return;

((struct MapState *)node) ->prev_node[++numparents] = parent;

5EARC-H THE TREE Now

that

we can construct a

demonstrate

now

isn't

tree,

how do we

the best, but

it's

search

it?

This

is

where things get

the easiest to understand.

icky.

The

system

The more complex your node

I

will

tree,

the longer the system will take.

To search the list, we need a recursive function that searches all possible routes that the AI can take. We also need a history of nodes already searched (to avoid backtracking) as well as a current route. To do this, we will need two separate linked lists.

)

;

;

R-RTifnciflL

First

of all,

//

create our linked-list system.

let's

one-way linked

Linked

1

i

The

Intelligence

following code snippet allows you to create a simple

list:

st data

type

typedef struct link_list void *data; void *next;

{

J //

AddNodeO

Adds

-

void AddNode(

node to the linked list

a

nk_l st *root, void *data) link_list *me = root, *new; 1

i

i

{

while (me->next != NULL) I

me = me->next;

new =

(

1

i

n

k_ list *)mal

1

oc(sizeof

(

1

i

nk_l

i

st)

new->data = data me->next = new;

//

FindNodeO

-

Finds

link_list *Fi ndNode( 1

ink_l

i

1

node on

a i

nk_l

i

a

linked list

st *root,

void *data)

st *me = root

while (me->next != NULL) if (memcmp(data me->data, sizeof(len)) == 0) {

,

return me; me = me->next;

return NULL;

{

Linux Gaiyie FRDGRfimmiNG

EDE

Now

that

we have

we want

route

a minilibrary for the linked

to take. Following

is

lists,

we can

actually construct a function to find the

a very basic function that

demonstrate what you need to do, but

I

wouldn't

try this in

is

no way near

a real game.

k_ list *hi story

1

i

n

1

i

nk_l

i

st *route

;

char found_route =

0;

void find_route(MapState *start, MapState *dest) 1

i

nk_l

i

st *me;

route has been found,

//

A

if

(found_route) return;

AddNode( //

hi

story

,

for

stop searching

Check if we've been here before Fi ndNode( hi story (me->next != NULL

return

//

so

start);

me = if

{

si zeof (MapState) start->num_parents == 0)

start,

)

{

;

Search for route in all (i

= 0;

i


num_parents i++) ;

AddNode( route,

{

start->next find_route( start->next dest); )

,

//

Route found,

if

(

//

Not valid route,

stop searching

found_route) break;

me = FindNode( route,

me->next = NULL;

jump back to start

start->next, sizeof (MapState)

)

perfect. It does, however,

;

R«Tl-F1Clf=1l_

//

Did we

if

(! Fi

find

1NT€LL1G€NC€

what we are looking for?

ndNode( route, dest))

{

Ir

return

;

l

//

Yes we did.

found_start =

1

d_.

] CAUTION This code

is

purely for demonstration

purposes.

It

contains a nasty

leak that could

do nasty

memory

things. You

have been warned!

When

using this system, you

f ree(

)

must

nodes as they are removed from the current route

The

link

search works by generating a

final destination. It stops

T-H-E

map

of even' possible route the AI system can take until

searching as soon as

the system always uses the

a perfect algorithm, but

list.

first

it is

one (even

if

it

finds a plausible route;

there

is

if

there

is

it

finds

more than one

another, shorter route possible). Like

I

said,

its

route,

it's

not

simple and easy to enhance.

NU-RGL-E IY1-ET-HOD

Now that we've

commonly used method of route finding, I'll teach you about a system I developed myself. The Nurgle method uses a grid system, making it ideal for strategy games such Conquer. Each location on the grid has a score assigned to it, and that score is defined as Command discussed the most

&

by type of terrain,

risk factor, distance

from

target,

and various other

factors.

Game FRDGRflmmiNG

Linux

Here's

how

rain

on each grid

is

the system works: section.

When you are

Each

initializing the

of the types of terrain

is

game, you run a

test to see

what

sort of ter-

assigned a value, terrain that's easier to pass

ll

has a low value, while the tougher stuff gets a higher value. In addition to the terrain value, each grid

number

has a

grid section

from the target point. The farther away from the target the

associated with the distance

Jl is,

the higher the value.

The

distance value

is

stored in another array, separate from the

terrain value.

Movement

The

simple.

is

first

check you perform

distance value. (You do want your AI to potential squares to

However, there

is

group of artillery

Do you want means

into,

move toward

you check

to see

to find

which adjacent grid section has the lowest

the target, don't you?)

When you have

a

list

of

which has the lowest terrain value. Simple, no?

another factor worth considering. Imagine the situation in which you've sent a to attack the

enemy

base but your attack team

the artillery to go back to the

the terrain

should

move

is

is

more

difficult to cross,

(in theory) take a safer

.Another trick you can

do with

same spot? Of course

and

is

wiped out

in a vicious retaliation.

not. If you consider that the attack

adjust your terrain table accordingly, the artillery

route instead. this

method

is

to

normalize the terrain array whenever

it

changes, to

allow units to take clear paths around the targets. Normalization can be performed using the following

method: for (x = 0;

r

for

x




1)

(low + high)

mean

sorts

{

high = 100,

is

number

stored in the

is

minimum variable,

average of the

minimum and

of search algorithms (when the

{

/

2)

and 100.");

described:

time

higher or lower

approach can zero-in on a number very quickly sometimes.

following code demonstrates the simple guessing

void mai

guessed

secret

maximum number. Each

maximum variable.

calculates the

((min+max)/2). This concept

sorted, that

last

stored in the

a

:

1NTELL1GENC€

HRTl-FlClflL

printfCIs the number higher switch (guess) case

'

case

'

1

h

'

H

'

lower than %d?\n'

or

guess)

{

:

:

ow = guess

n ;

break;

case

'

'

1

:

L'

case

'

high = guess;

break case

'

'

;

:

Aren't

puts( "Woohoo!

return

clever?");

I

;

This stupidly simple example demonstrates the concept of

trial

and error perfecdy. Although

perfect representation of a trial-and-error system that can be used in most types of games, for simple kids'

games (edutainment), and the concept can be

easily

expanded

to cover

it's

it's

not a

perfect

more complex

problems, such as a Towers of Hanoi game.

JYliN-fYl-HX The

final aspect

This

is

is

to

Trees

of basic

how most

artificial

intelligence I'm going to cover

single-player puzzle/board

keep your opponent from winning

when

it

comes

to

min-max

at

games work, such

any possible

cost.

is

the infamous

as chess

and

min-max

tic-tac-toe

Winning the game

is

tree idea.

games. The idea

only an afterthought

trees.

The Theory -Behind the Tree The aim

of a min-max tree

is

to

keep your score

as

score as low as possible. For each possible action, actions. This

approach makes

this

high as possible, while keeping your opponent's

we

calculate the possible results of the follow-up

system perfect for turn-based games such as chess or

tic-tac-toe.

Linux

G

how the idea works: In a turn-based game, there are two objectives. The first is to maximize your own score, and the second is to keep your opponent's score as low as possible. Although the first Here's

objective requires very

little

moves the other player can .

Figure 10.2 shows the

first

few moves you might take in a

completed, there are three big). In the first option, the ly (in

and 3

option (3

2,

the

Os

thought, the second requires

some planning

to predict

what possible

take.

states left (in a real

Os

tic-tac-toe

game. By the time the moves are

game, there would be more, but

are playing defensively; in option

3,

the

Os

my paper isn't that

are playing

more

aggressive-

are being completely stupid). If we were to give each option a score between

being the highest), option

1

would score a 3

(the

Os blocked

1

the opponent as well as posi-

tioned themselves for possible victory in a single move). Option 2 would score a

1

(the

opponent can

win in the next turn), and option 3 would score a 2 (the Os have a chance of winning in the next turn if

the

opponent

is

a complete idiot)

Figure 10.2 Possible tic-tac-toe

moves.

J*^"^

'

^^~k

r

X )


cells[ (ccel s[ (c>l)?c-l c+1] NewBoard->cel s[ (ccel s[ (c>l)?c-4 c+4] NewBoard->cel s[ (ccel s[ (c>3)?c-3 c+3] NewBoard->my_ score++; else if (NewBoard->cel ls[c] == 0") if ((NewBoard->cells[ (ccel s[ (c>l)?c-l c+1] NewBoard->cel s[ (ccel s[ (c>l)?c-4 c+4] (NewBoard->cel s[ (ccel s[ (c>3)?c-3 c+3] NewBoard->thei r_score++; if

1

(

x

==

'X

==

'X

(

1

(

1

==

'X

1

==

'X

==

'X

==

'X

(

1

)

==

(

(

1

(

1

(

1

1

(

1

I

== == ==

•o •o •o

==

'0

==

•o

))

uL

Some

of you

there

is

thinking that this system doesn't take the edges of the board into account, but

may be

a reason for

As well

this.

as

aiming for a win, the system also considers a draw

to

be a reason-

II

able result. This code takes that into account by allowing certain checks to wrap. [

If,

for example,

and

do

that's

you have control of cells

by going straight

for his next turn, the

down

and

3, 4,

9,

there

the middle. However,

most profitable square

to take

if

is

only one way for the opponent to win,

you calculate what the AI player would

would be square number 5

try to

(with three neigh-

bors) forcing a draw. ,

Now

[

we have our next two turns planned out, we need to decide which one we want to do. There are two ways to make this decision. The first is to just go for whichever move gives us the highest score, and the other is to work out which gives us the highest score and prevents the opponent from winning that

in his

The

next turn.

easiest

way

to

do

this

also has the lowest score

J

is

Advanced Now we

to sort the scores

from the second

from the

first test

and then

select the highest score that

test.

-H-rtuhci-fil

Intelligence

my friends, we are deep understanding of human anatomy isn't

are going to take the concept of artificial intelligence

going to create our own pet Frankenstein. Although a

one

step further. Yes,

required for this exercise, some knowledge of biology, such as genetics and neural chemistry,

will help.

Genetic flLGDRiTHms The

first

high-level AI we're

non-symbolic, logic.

meaning

that the behavior

is

at

is

a genetic algorithm. Genetic algorithms are considered

not hard coded but

is

learned using a vague form of fuzzy

Based on Darwin's Theory of Evolution, genetic algorithms "evolve" over time, adapting to

the task at hand.

r

going to look

Intelligence

H-rti-fici-hl.

Memes Memes are a small subset of the subject known to biological evolution,

but what

meme come

So how did the

In the middle of the

if

ideas

is

relatively

n

way Chinese whispers

Dawkins wrote a book called The

ideas, like genes, evolve

Selfish Gene.

In this book,

each time they move between carriers

"evolve" as the original phrase

is

passed from ear to ear in a group

Many people picked up on the idea after this book was published. (Dawkins was, in fact, debunking the idea, but many people misunderstood his point, and in true meme style, the informaof people).

tion was passed on.)

When you

explain an idea to someone, he will

make

certain modifications to the original idea

and

The more realistic version of the idea has a greater chance of "replicating" between carrier can be a human, a book, a Web site in fact, anything that passes information

spread his version. carriers (a



between people). Consider a joke. People say that jokes, the deliver)'

method

it's

not the joke

slightly different

"How can memes be put

I

into games?",

I

hear you asking.

it

it's

told.

It's

When

people repeat

the delivery, the joke

is

the joke. In other words, the

not as hard as

it

may

at first appear,

and

much.

was toying with the idea of world domination through the use of a computer

(Have fun with the CD! it

but the way

someone screws up

Geneeot

A few years ago, cated,

If

if

I'm surprised that people haven't tried

T+H€

that's funny,

each time.

someone tells it well, the listeners will repeat while the weak one fades out of existence.

consigned to oblivion, but stronger joke survives,

is

*evil grin*)

The way

the virus worked was like

randomly modified parts of itself. Some children of the

would be

slightly better

than the parent

virus.

However, before

I

virus

this:

Every time the virus

would just

could put

virus.

my

crash,

repli-

and others

plans for global con-

quest into action, something terrible happened: Quake.

For months, lary

I

played Quake, not doing anv programming or school work.

was Quake. But,

like

any game with no longevity,

I

got bored.

time, so Deathmatch-was out of the question.) Fortunately,

had fun creating python-esque patches. But

amusement lost

it

to

Quake and add no

in a hard-disk crash.

But

fish

real challenge.

it's

It

new.

about?

Dawkins presented a new theory that (similar to the

The theory of evolving

ideas could evolve too?

century, Richard

last

Darwinism. Darwin applied his theories only

as universal

I

(I

The

had only a

onlv word in 14.4

Kbps

my vocabu-

modem

discovered QuakeC. Using this language,

grenades and dog launchers can add only a

Then

I

bit

created the Genebot. About two weeks

the thought that counts.

at the I

of later, I

Although the original Genebot was created the system to C++.

Why C++?

but other aspects of the bots things simple

The

and

meme one

Because of the nature of computer AI, will

a bot

is

quite simple.

is

When

the bot

respawned, however,

to

it

inherits

some code. The following

function pointer assigned to //

Bot.h

//

Number of genes

MAX_GENES

it

created,

it

memes from

style

class

to aid in

meme

for sniping,

selects its

one

called

void

*

(

meme

framework defines the

code

bot's behavior.

reusability.

8

I

unction_ptr) void *); (

Genepool

int gene_count[MAX_GENES];

Genedata genes[MAX_GENES]

//

;

Class definition

class Bot

(

private: Genepool publ

i

to

keep

*my_pool

c:

BoUGenepool *my_pool_); ~Bot(); void Respawn( void

void RunAI (void

)

;

)

;

;

them

genes

the pool.

and

When

over time.

Genedata;

Genepool

me

parent bots. This evolutionary approach

{

)

characteristics,

for grouping,

random memes from

containing reference counters and function pointers typedef struct //

some

the bot's behavior. Each

Gene data

typedef struct

)

at that time) that control

(I

Class definitions for genetic AI

-

#define

//

memes

is first

causes the bot to adapt to the player's

Now on

bots share

You have a pool of memes

has a different purpose (for example, one

for aggression).

have since converted

be different. The inheritance features of C++ allowed

hadn't yet heard of

I

all

I

maintain readability in what could turn into some very complex code.

idea behind the Genebot

originally because n

to

in the C-bastardization of QuakeC,

//

Gene usage count

Each

meme

has a

)

)

:

)

f

;

;

H-RTiFiciflL

*new_pool); *new_pool

void Bot_Ini tPool (Genepool

void Bot_EndIni tPool (Genepool

The next source

file

Intelligence

)

\

defines the functions used in the bot.

fl

Bot.cpp #include "Bot.h" //

cU //

Bot_Ini tPool (new_pool

//

Initializes

//

for the first time

a

new gene pool

void Bot_InitPool (Genepool for

(int i

f

i

=0;

i


genes[i

]

Bot_EndIni tPool (new_pool

//

Finishes initialization of

if

i

=0;

1


genes[i

]

Bot: :Bot(my_pool_)

//

Called when creating

Bot

:Bot(Genepool

a

]

=

-

{

)

1;

*new_pool

MAX_GENES;

(new_pool ->genes[i

//

i++)

new gene pool

a

void Bot_EndIni tPool (Genepool for (int

{

unction_ptr

.

new_pool ->gene_count[i

//

)

before creating the bot

i++)

)

{

{

-

new bot for the first time

*my_pool_)

{

my_pool = my_pool_; for

(int if

i

=0;

i


usage_count[i] && ((randO my_genes[i] = 1;

%

10)

>

5))

J

Gome

Linux

//

Bot:

Respawn(

-P« 5TTT???HW

)

Called when respawning a bot void Bot :: Respawn( void) =0; < MAX_GENES; for (int //

1

(

f

if

i++)

i

i

(my_genes[i

]

)

{

{

my_pool ->usage_count[i ]--

1 }

for

(int if

i

=0;

i

MAX_GENES;


usage_count[i] && ((randO my_genes[i] =

1;

}

1

//

Bot: :~Bot(

//

Called when deleting

Bot::~Bot()

{

for (int if

bot

a

i

=0;

i

(my_genes[i

MAX_GENES;

< ]

)

1++)

(

my_pool ->usage_count[i

]

-

-

//

Bot::RunAI()

//

Called every frame to process the bot's AI RunAI (void)

void Bot: for

I

(int if

i

= 0;

i

(my_genes[i

MAX_GENES;

< ]

)

1++)

{

{

(my_pool -> genes

.

unction_ptr (this) )

%

10)

>

5))

:

;

;

R-RTifnciflL

This simple framework cannot work as a less-generic class

ing that

it

will

on

this class

is

is

the reason for developing

tailor

based on a Half-Life mod called

and heavy weapons

es (scout, assault troops,

new

stands. This

it

in C++.

By building

each bot to a specific purpose while

still

ensur-

I

learn with the rest of the bots.

This next example

three

it

framework, we can

Intelligence

:

which uses three different types of class-

troops). In this code,

we extend

(I

the Bot class to create

with the scout.

classes, starting

class BotScout

Frontline,

Bot

{

private: //

Bot positions

int ammo_prim;

//

Primary weapon ammo

int ammo_sec;

//

Secondary weapon ammo

int health;

//

Bot's health

int x,

z;

y,

public: void Respawn( void) voi d

RunAI voi

void BotScout :

(

::

Respawn(

)

d

)

;

;

RespawnC void)

f

;

Set the bot's starting position = x rand( % map_width //

)

y = rand()

%

map_height;

Set the amount of ammo we have ammo_prim = MAX_PRIMARY; //

ammo_sec = MAX_SECONDARY Restore scout's health health = 50 //

I

void BotScout

:

:

RunAI void)

I

check if this bot takes the fastest route to If not, then take the safest route

//

First of all

//

the target.

if

(!my_genes[FASTEST])

n

{

FindSafestRoute(this);

:

:RunAI(

);

}

i This

fictitious

example demonstrates how the new BotScout

in the original Bot class to allow the scout to carry

assassinating the

tasks,

simple generic routines

such as capturing a flag or

enemy VIP.

Actually, calling this class

include something like

Genepool

class overrides the

out more specific

framework from the game

is

quite simple. In your

game

initialization,

you

this:

ScoutGenes;

ScoutGenes->genes[FASTEST] functi on_ptr = Fi ndFastestRoute ScoutGenes->genes[GROUP] unction_ptr = ScoutGroupFunc ScoutGenes->genes[CAMP] unction_ptr = ScoutCamp; .

.

;

.

Bot_InitPool( ScoutGenes); for

(int

1=0;

i


x int bot_y = ((BotScout *)caller)->y \i

some funky route finding

//

Do

II

Let the bot know where it is

((BotScout *)caller)->x = bot_x ((BotScout *)caller)->y = bot_y

Our

hypothetical scout bot

is

almost complete.

The

only thing

each frame and to respawn the bot occasionally. Both of these BotScout: :RunAI( RunAI

(

)

)

and BotScout: Respawn :

(

)

handle these

we have

left is to

tasks couldn't

tasks for you. All

be

process the AI in easier.

you have

The to

functions

do

is

call

the

function every frame; that function takes care of everything for you.

Neural Netwjdrhb Neural networks are what cal reactions that

send

electrical

essence of emotion. But

Imagine a

transistor.

of an emitter. light sensors

By

make up

how do

the very essence of the soul. You are controlled bv a series of chemi-

impulses around the brain. These reactions are what

and contact

two inputs are activated,

a whole network of transistors, with

switches),

and some connected

carefully arranging the transistors,

responses to certain stimuli.

the

very-

they work?

A transistor acts as a switch; when

Now imagine

make up

If you

you can create an

add some

it

some connected

to outputs (such as

"artificial

sends a current out

to inputs (such as

motors and speakers).

brain" that has

preprogrammed

variable resistors, you'll be able to fine-tune the network.

much how the brain works, except that there are more than two inputs to each node on the network. But how does the network learn? This is where things get complicated. As each path on the network is activated, the path becomes easier to traverse much

This oversimplified example

is

pretty



like

a footpath through a forest becomes easier to navigate as

path

is

completely unmaintained.

more people walk along

it,

even

if

the

Linux Gaiyie P-RDQRflnnnrnNG

Neural Netuidrks

R-rti-fici-hl Artificial

neural networks are really quite simple (in the same way that genetic algorithms are simple).

However, a complicated system can be quite processor intensive. Even

n

isn't that

For

this

on performance

if it is

example, we're going to use a

Before

I

go into the

details

not thought out

fictitious table

Table 10.1 shows a series of dog-fighting

i

artificial

neural network

complicated (unless you're a big fan of multithreaded applications), the system can

a significant impact

jd

your

if

about Table

tactics

10.1,

make

carefully.

of data that we want the network to learn from.

and how

I'll

still

successful they are.

explain what each of the tactics mean. Table 10.2 does

this succinctly.

In a perfect world, you want to use tactics that result in the

age to yourself. However, some tactics

(

(

damage

can be considered okay but not as desirable.

with something like if

tactics result in

ENEMY_HIT

//

enemy being

to yourself while

If we

were

killed while still

minimizing dam-

killing the

to hard-code the logic,

enemy, so these

we would end up

this:

||

ENEMY_KI LLED) && !(ME_DEAD))

{

do something here

Table

1

0.1

Dog-Fighting Tactics and Success Rates

Successful

Successful

Took

Was

Mission

Hit

Kill

Damage

Killed

Success

Name Immelman Scissors

1

Inverted scissors

Low

yo-yo

Hi yo-yo

1

1

1

1

1

1

1

R-rti-fici-rl

Intelligence

Table 10.2 Definitions of Dog-Fighting Tactics Name

Description

Immelman

Pull

back on the stick to

fly

inverted, then rotate the aircraft

1

80

degrees.

downward

while

Scissors

Fly

Inverted scissors

Similar to Scissors tactic, but

Low

in

a barrel

roll.

performed while

flying

upward.

Point nose of aircraft down, then pull up to attack the target from

yo-yo

below. Hi yo-yo

Pull

and good, but

nose of

This

is all

trick

over and over again to always win. Now, what

along,

CPU

on

well

then attack the target from above.

aircraft up,

after a while, a player

a mission-by-mission basis,

may

if

realize

how

the AI works

and may use the same

the AI-controlled opponent could learn as

and could analyze the

it

went

between missions (hence using

results

less

time during the fight)?

This dynamic learning behavior can be achieved using a weighting system that performs some simple

math

each AI frame. By using weights, you can cut down on your use of some large

in

as well,

which

is

another advantage. To create

this

i

f -el se

weighting system, CPU-heavy algorithms

blocks

come

into

play.

Software-based neural networks work by analyzing each situation and adjusting the weights so that a suitable

outcome

prefixed with an o.

The weights

is i

achieved.

(i 1 is

repeat for all

if

((il if

(

!

2 is

that demonstrates this logic follows.

a successful

)

//

w.

no changes are made

threshold)

w3) + (i4 * w4)

event shouldn

t

happen under these input

-

(il

*

0.2)

-

(i2

*

0.2)

-

(i3 * 0.2)

-

(i4 * 0.2)

>

The

inputs are

so on); outputs are prefixed with an

w2) + (i3

w2 = w2 w3 = w3 W 4 = w4

and

kill,

*

*

wl = wl

end if

i

scenarios until

wl) + (i2 o

hit,

associated with each input are prefixed with a

//

*

Some pseudo-code

a successful

Linux

(j^iyi€

II

fRDGRfuniYiiNG

el se

if

f

event should have happened, but it didn't

//

(o)

wl

wl + (11 * 0.2)

w2

w2 + (12 * 0.2)

w3

w3 + (13

*

0.2)

w4

w4 + (i4

*

0.2)

end if end

i

If you

f

apply this algorithm to the criteria defined in Table 10.1, your weights

[wl=0.3, w2=0.7, w3=0.1, w4=0.1].

Now

and which

to

tactics don't,

you have

that your

tell it

when

computer

to use

pilot has

end up with the

been "taught" which

J

use 0.5 for this value, but

it

results in a value to

use; otherwise,

The

following

ables

C code

demonstrates

#define

TACT_ .IMMELMAN TACT. .SCISSORS

1

#define

TACT. .L0Y0Y0

2

#define

TACT. .HIY0Y0

3

#define

TACT. .INVSCISS0RS 4

#define

TACT NUMTACTICS

bool

how

to use this theory in practice.

5

weights[4];

tactics[NUM_TACTICS][5];

#define

(I

usually

you how successful that

tactic

greater than the threshold, the tactic can be beneficial to

that will simplify use of the neural code.

#define

float

tells

to

it isn't.

and a macro

signed

is

work

whether

be compared against a threshold value

can be any number). The comparison

has been in the past. If the calculated value

tactics

them.

In your AI loop, multiplying the weights against the input criteria for each tactic (such as

perform an Immelman or not)

values

DoNeural(x)

\

U(weights[0]

*

(weights[l]

*

tacti cs[x] [1]

(weights[2]

*

tacti cs[x] [2]

(weights[3]

*

tacti cs[x][3]

)

tacti cs[x][0]

)

+

)

+

\

)

+

\

)

>

\

0.5)

I'll

start

by defining some

vari-

.

R-RTi-FiciflL

The next code segment demonstrates //

check whether it's

if

(DoNeural (TACT_IMMELMAN) //

a

the use of this

macro

in the

code

Intelligence

itself.

good idea to do an Immelman )

I

{

do some funky stuff II

}

else if (DoNeural(TACT_SCISSORS)) //

{

do some funky stuff

[else

//

After you have set

and so on

up your

basic

.

cL

.

node on the network, creating

a

more complex network

is

simply a

case of adding more input variables based on the output of other nodes.

Changing

t-h-e

EEfiflviDR

Network

o-f t-he

As time goes on,

different tactics will have different results. If vou update die tactics tables

result that wasn't

expected occurs (such

as a successful kill

whenever a

from an Immelman), you can continue

to

use the table. This gives the table a slighdy dynamic property as time goes on.

However, when you regenerate the weights as getting killed)

.

at the

end of a

mission,

You must check the desired outputs when you

some

results are undesirable (such

recalculate the weights,

and then

update the weights accordingly. In a perfect world, the weights for undesirable actions would be negative to

make

sure that they always put off potentially

bad

events.

FERBDNflLlTY A slightly cool thing about neural

networks

like these is that

you can create

"personalities" for each

AI

opponent simply by modifying the threshold that checks to see whether a node should be activated. If,

for example,

you have a paranoid

pilot

results in less-fancy dog-fighting tactics

that higher threshold

Likewise,

if

would

start

doesn't take any

risks,

increasing the threshold value

faster kill for the pilot).

As time goes on,

pilots using

using riskier tactics as the data table evolved.

you lower the threshold,

risk their pseudo-lives

who

(and in a

pilots

more frequendy just

would take more to get that

risks

one extra

when choosing

kill.

tactics,

choosing to

IW^Bi^B

Linux

H!WW253eCS

i

i i

\

s .

^- -^5 ** ^^.«B

I

lr"

-s

n

"^

CHAPTER

a

I

I

NbOURCE! fRIEND O-R

.

tesssss^

^^^H

^^^^^^^^1

1NUX

EEE

ippi

bfllYlE

'•'*3H

i the recent OpenSource has been Insoftware people claim development, really all

is it

nism

I

it

Although

can be, or

it's

new age of another form of commu-

been heralded

is it just

as a

in disguise?

UJ-H-HT 15 The

spotlight.

in

years,

idea behind

O

NbDURCE?

OpenSource

Sometimes hailed

software

as "technical

is

simple, yet

it

involves

communism," other times

many complex

as "the future of software

everyone has a different opinion about what OpenSource means. But what

The concept

is

like this:

You

write a

program and

release

political issues.

it

development,"

is it?

along with the source code. Now, people

movement started, so what makes had some restrictions on its use by other peo-

have been doing that since long before the OpenSource

OpenSource

different? Traditional source

ple. Early versions

OpenSource

The

code usually

of UNIX, for example, included the source code, but those versions weren't

applications by today's standards.

license restrictions regulating the use of

UNIX meant

that only corporations

and

universities

could actually see the source code. Mr. Joe Public didn't have a hope in hell of seeing a single line of

code that went into making the monster that was the original ware

is

An OpenSource it.

AT&T UNIX. Modern OpenSource

license places

no

restrictions

on who can

see the source

This approach allows a single program, released on a simple

user's

soft-

different.

hard drive without any special

effort

Web

code or who can redistribute

page, to

end up on every Linux

by the original programmer.

However, just releasing the source code to a program doesn't make

it

an OpenSource application. To

be a "proper" OpenSource program, your license agreement must meet certain requirements. Several sample license agreements are presented in Appendix A, but aspects of

all

the licenses in the next few sections.

I'll

cover

some of the more common

.

Df€n5ourc£! Friend o« Fde?

UNLIMITED RED15TR1EUT1DN Every OpenSource software license must have the provision that anyone can give your software to any-

one

else,

including any modifications they

may have made

to

your original code. Safeguards are in

place within the license agreement to protect the author's copyright, preventing

claiming credit for the original coder's hard work. This

is

one of the key

someone

else

from

n

OpenSource

selling points of

software: the low cost of acquisition.

Charge for Exfen5€5

HeiLiTY to Many OpenSource a

CD

licenses offer

these companies very

an option

charge for the cost of redistribution, such as the price of

is

cation available in a nice box,

on

several CDs,

nies weren't allowed by the rules of redistribution, the

to

how companies such as RedHat and SuSE make their money. Although rarely develop their own software for the operating system, they make the appli-

and manuals. This

and with printed

OpenSource

compa-

instruction manuals. If these

redistribution to charge for this kind of

packaged

Linux CDs that get many of us started with the operating system wouldn't

exist.

In addition to charging for nicely packaged distribution copies of software, these companies can also

charge for support packages, allowing paving customers to get help

when

they

need

it,

be

it

through

email or telephone support (some companies offer on-site support, but that kind of package tends to cost a small fortune,

something that the budget of the average Linux developer can't stretch

to

include)

Develqpiyient IYIodels

T+H-E So,

now we have

Raymond's

a vague idea of what

essay called

OpenSource

is,

but what

is

the reasoning behind

it?

In Eric

'The Cathedral and the Bazaar," he describes the two main software develop-

ment models, based on community

centers around the world.

T+H-E C-HT4H-ED-R-RL A

cathedral

is

a place

where many people can go, but where only a

select

few can address the masses.

This development model represents commercial, closed-source software such as Windows and Quicken.

These programs are written and controlled by a ple use

them without any

relatively small

say in the future of the product.

group of people,

yet

hundreds of peo-

L

Linux Gaiyi€ FRDGRfliYiiYiiNQ

This development model

god

says,

told.

and the

Although

"little

this

is

many ways: Priests or ministers tell people what a particular the people who pay the leaders' wages) must do what they're

like religion in

is

people" (that

is,

a mildly cynical view of both religion

of the commercial software industry pretty well.

and

How often

software,

sums up a

it

large percentage

has a vendor actually listened to your rec-

ommendations and acted on them?

T+H-E -BflZ-R-R-R A

open marketplace,

bazaar is an

and lined with

bustling with people haggling over prices

and run by anyone who has something

to

sell.

Trading takes place between the

stalls,

stalls set

and there

up

a

is

sense of an informal community about the place. People get to know other people's names, and friendships are formed. If you

and the goods and

replace the marketplace image with the Internet,

services

ious globs of source code, you should be able to see the relevance of the bazaar to

OpenSource. (Don't worry,

someone your code about

it,

A large the

more

it

users

either.)

make some

modifications, test

is

model when

OpenSource works

100 percent

and developers

OpenSource community

part of the

it,

like this:

it

var-

comes

You

give

or just spread the word

to help with the project.

word of mouth aspect of it. With

the

sites like

Freshmeat

forbid) Slashdot offering daily coverage of changes to the ever-growing world of Linux,

word of mouth aspect

such as

don't get

for free; in return, they

bringing in

and (heaven

I

being sold with

The GIMP and

is

very, very easy to find.

Without

it,

people wouldn't have heard of projects

the XFree86 project. By linking from various

about these projects and joining the development teams

to

fill

Web sites,

the holes that

people are finding out

may appear

in the soft-

ware. In addition to the

development advantages offered by the OpenSource community, free access

software also helps raise an in

army of testers.

If

you display your contact address

your software, you can be guaranteed to get bug reports in no time

All the

community

aspects of

OpenSource can help

munity development" takes some time

in

many

a look at the FreeCiv project, for example.

French, merde.

When

I

tried

it

again about a year

more

I first

later,

had joined the team, because something was

you

(take that as

often than not, the effort

tried that

it

was

still

game,

better,

it

was,

if

bad. But a few

things started improving. Developers started communicating, or a skills

some obvious

location

will).

create high-quality software. Although this "com-

cases,

When

flat

in

to the

is

you'll

worth

pardon

months

it.

Take

my

after that,

new hot-shot rookie with brilliant art and that made the game actually enjoyable.

O-p-en Sou-roe! -Friend

fdr and Dfen5durce

It

There are many reasons why OpenSource can be considered a good

thing, ranging

a development team consisting of thousands of coders. But are these

some ways they

are,

and

in other ways they're not,

-Foe!

"hg-r1nst

r-e-h5cdn5

rity to

or

depending on which

from greater

secu-

reallv legitimate claims? In

side of the fence

you are stand-

ing on.

J

Ten Reabons to Use Dfen5durce There are many reasons

to consider

an OpenSource development route for your

latest

Linux game;

the following sections present a small selection of them.

P-E-E-R -R-EV1-EUJ5 The

first

L

and most pushed reason

to

go the OpenSource route

is

that thousands of developers can

look at your code and point out errors. This free testing team can help you debug your

more thoroughly than you

ever could

People become attached to their code and find their

code

true,

it isn't.

flawless or that a certain situation

is

Your attachment

process. This

is

to

game much

on your own. it

hard

to test all possibilities

could never happen. As

much

because thev think that as

we

all

your code clouds your judgment and can result in a

where one of the OpenSource mottoes, "Release

wish

this

were

faultv testing

early, release often," really

comes

into

play.

Security The next reason you should consider

the

sneak a back door into a program where

Indrema mailing

lists

in the past,

OpenSource development route can be

it

when

although

easily

it

comes

to

ware,

it

would be very easy

to

that user

remove

is

allowed).

the piracy checks.

that

it's

a lot harder to

games, there are few reasons to hide a

back door (except for copyright reasons, in which the game reports

and the server can check whether

is

found. This issue has been raised on the

Of course,

if

to the server that

your game

is

it's

being used,

OpenSource

soft-

Code

Rvfiil-r-bl-e ll

Another good argument for the OpenSource cause is

Jl

is

that other people can learn

probably one of the best reasons for OpenSource software: to aid the world in

ignorance in

all its

from your code. This

its

quest to destroy

forms.

F-R-E-E 50-FTUI-H-RE,

fRE€

Who said

as a free lunch?

1

N-FO-Rm-HTlON Many OpenSource products

more than one sense of the word. In addition to making code available for free (as in free beer), OpenSource also allows another form of freedom. Many people claim that information wants to be free (although how a there ain't

no such thing

metaphysical entity can "want" anything

is

By sharing your code with other people,

it

so,

am

beyond me). can be claimed that you are helping mankind, and in doing

you are making yourself a better person. Personally, I

to say

are free in

I

don't

fall

for that, but

many

Who

others have.

who's right and who's wrong?

J

D€V€LDF€R5

lYlflNY

In addition to the peer reviews

opment approach

OpenSource almost guarantees,

offers the possibility that other

participating in an

programmers may want

to join

OpenSource

your project

goes on. This results in several things (including more free time to enjoy that free beer earlier)

.

Your project

will

gain the

skills

of someone

who may or may not have more

I

devel-

as time

mentioned

experience in

developing software than you do.

F*=im-E Publicity

probably one of the primary factors involved in the OpenSource movement, although

is

people

will

may be

all

disagree with

me on

that.

the inspiration they need to work with your software, find a few bugs,

(Obviously, then, your final version of the software will have to include a

have helped you in your development ical

person,

and

that's

what counts.

many

People love to see their names in the credits of a game, and that

efforts.)

Although

this

may be a

list

and

fix

them.

of names of people

who

cynical view of society, I'm a cyn-

Dfen5oukc€i Friend o«

T+H-E

CDIYKYIUN1TY -H5-P-ECT

If there's

one thing the OpenSource movement has

have,

a sense of community. Apart from a few global mailing

(in

-Foe?

it's

whose company an amateur developer may

don't help each other out unless they

that closed-sourced developers generally don't lists

feel intimidated),

know each other

filled

with professional developers

commercial developers generally

personally from previous experiences.

much more welcoming of "newbies" than anyone else (although claiming to be female when you're not may get you a few enemies) Finding the help you need in an OpenSource community can prove quite easy, as long as you help out others. An elitist programmer OpenSource developers

are generally

.

makes few friends

u

in the real world.

L

RV-RIL-R-BILITY O-F T-H-E So-FTUI-R-R-E Commercial games are hard get through that you'll exist with

OpenSource.

to get

on the

shelves, trust

need an army of lawyers If you write a

handle

to

good game and

appear on every major Linux distribution out there,

T+H-E I

stick

all it

layers of

the paperwork. That

on a Web

as well as

site,

bureaucracy to

problem doesn't

before you

know

it, it

on FTP archives mirroring those

will

sites.

CflU5€

know some people who

this

me. There are so many

refuse to use

non-GPLed

software,

whether

it's

because they believe in "the cause" and because they have the same

other OpenSource gurus

like

Richard Stallman do. In

my opinion,

OpenSource or

this is

They do some

not.

political beliefs that

probably a bad thing to

think.

Just because something

mean

that

it's

happens

to fall

under the

GPL

or some other OpenSource license doesn't

the best thing since sliced bread.

EECflU5€ YOU Many OpenSource

L.1-KE IT

developers out there don't really care about the whole OpenSource movement, but

games because they enjoy writing them. This is probably one of the best reasons for OpenSource development not because you follow the same political agenda, or that you worship the ground Richard Stallman walks on, but because you want to, because it makes you feel all warm and they write free



fuzzy inside.

lf*~

B^H

kr*y

w.*?»4vJk*»f

:.•,.,.-•'

iSvi^i-.S^f^r?

-;:

Linux Gflpne -Program ming "

Ten REA5DNB TO ll

'vj:.s.v>$BUi

WJ-R1

CLOBED-5DURCE 5afTWflRE my neutral stance in pretty much everything, and the OpenSource movement is no To balance my list of ten reasons for using OpenSource development, here is another list of

I'm known for exception.

reasons for using a closed-source development route. (Note that this against

OpenSource development, which

is

list

does not present ten reasons

a completely different ball game.)

nrioN-EY make money from an OpenSource product. If you ever plan to get a publisher for your game, you'll have a tough time convincing them that OpenSource is the way to go. There are too many issues to count, ranging from easy piracy to intellectual property rights. Closed-source software, on the other hand, can make money very quickly if the product is of high-enough quality. Note that many developers have found that people still buy shareware, so contacting a publisher isn't always a requirement for making money from your game. It's

very hard to

FflRflNDlfl Many

developers are worried that people

quality

and don't want other people

will rip off their

to see

it.

code, or that their code

is

of substandard

This fear of having code dissected can be found every-

where, even within commercial companies, and

is

probably one of the main reasons why hobby devel-

opers do not release their code.

Plagiarists A few years ago, when had no problem with

I

was

this,

people were just copying different

decided that

came

to

I

wouldn't give

development.

the world,

I

people kept asking

in school,

but after a while,

still

and hacked code

bits

my code stick is

by

I

for the

code

to

my

programs. At

realized that instead of writing their

of my code to

out. Instead,

this

me

I

make

a

own programs,

new program. As soon

would guide people

much

as

I

is still

lower quality than new, original code.

these

realized that,

to the right track

philosophy today; programming ignorance

frequently of

first, I

when

it

rampant

in

I

Dp€n5durc€! Friend

o-r

Fde?

TECHNOLOG1E5

N-EUU

Your game might be the foundation of a brand new technology, such

as a

Anyone would have doubts about OpenSource arena, and I wouldn't blame them.

hard-earned technique into the

tracing engine.

New

technology

is

one of the key reasons

new technology freely

freely releasing that

for closed-source software. In

new 60 frame-per-second

some

ways, the fear of

available reflects the paranoia aspect of closed-source development.

aware that OpenSource software

some new technologies

responsible for developing

is

ray-

making a

However, be

itself.

Contracts Some This

own the code they write. many universities and colleges, where the work you produce as part of your owned by the institution. In many cases, universities will allow you to release your

developers work under contract to other companies and don't actually

is

also the case in

course

actually

is

code; sometimes they won't these, obviously, the

(if

program

the

is

part of an examination, for example). In situations like

OpenSource development route

is

not an option.

5-EL.-F1 5-HN-E5 5 Everyone not

let

is

some

selfish in

ways, as

anyone see our code, even

a major obstacle to the

T+h-e

Sometimes people work

solely

mean much the

that

we hate

to

admit

5a

it.

Sometimes

code could help people

1

its

code,

hard

why should anyone is

else?

situations,

Although

born with free

people may think that

this

will,

is

a

good

question,

it

and people don't have

else.

Politics Everyone has a

political

agenda, and sometimes that plays a factor in deciding whether you

others access to your source.

ground

new

in the

Some people

development environment.

would be

lost

engine was created.

will

allow

believe that by keeping their source closed, they can gain

How can

this be,

I

hear you

(and that they would therefore have

less

ask.

By developing some funky

some people believe that this power) if people knew exactly how the

graphics engine, people gain the respect of their peers. However,

respect

is

to hurdle.

UUdn't" Attitude

in the real world, as everyone

shadow of someone

this selfishness drives us to

in the future. This short-sightedness

that will be very

from the example of others. In some

because Microsoft didn't release

live their lives in

if

as

OpenSource movement, and one

"-He Didn't,

doesn't really

much

to

As described if \\

they

knew

his fragile

pen.

example

in the

exactiy

how he

ego by releasing

The human ego

from playing a

is

role in

in the

preceding section, someone may

did something with his

his source code.

Although

a dangerous thing, but

it's

feel that others

won't respect him

code. That person may therefore not want this

scenario

a part of us,

and

may sound there's

ridiculous,

it

to hurt

does hap-

nothing we can do

to stop

it

our decision making.

Security through Descurity Although many people claim that

games are

"security

through obscurity" doesn't

involved. If people can see exactly

their advantage. This

is

how something

it

does, especially

where

done, they can change the code to

a serious problem in online games, where people can give their online avatars

super-human strength, making them impossible Also, keeping your

is

exist,

game

protocols closed

to beat

by the average (non-cheating) player.

means that people can't "sniff" packets to would give them an unfair advantage.

find out certain

things about the in-game environment that

The Middle Ground If

both the OpenSource and closed-source development routes have reasons for their respective devel-

opment models,

is

there any way to exploit the advantages from both systems?

Of course

there

FR€€

Cod-e,

One way to

gain the advantages of both sides of the OpenSource/closed-source argument

the source code to your

-F-RIV-FIT-E

game

D-RT-R

Doom source code

The

idea behind the

registered

game

shareware data

id software

proved the system

game

lowed

itself

to

make

game private. This to work when it made

publicly available.

Doom license was that although the source code was free, the data files from the meant that you still had to buy the game if you wanted to play it (the

weren't. This

files

worked just

as well, though).

This approach allowed third-party developers to learn from the the

is

public but to keep the actual data required to run the

approach has been proven successful many times; the

is!

Doom graphics engine while keeping done this, many other developers have folmore recent games to follow this pattern.

a commercial (private) product. Since id has

suite; Alien Versus Predatoris

one of the

DpenBource! Friend

While many of the examples

you from doing its first

this right

game, Black

Another advantage

game

&

from the

into the next category, there

rumor has

In fact,

to the free code, private data

it

that

actually releases

method

is

that

is

nothing

Lionhead Studios

really

will

stopping

OpenSource

it.

it

allows other developers to port vour

you a larger user base while maintaining a potential revenue stream.

to other platforms, giving

d_

LflT€R

Examples from the free code, Descent, weren't

start.

fall

company ever

White, if the

DP£N5DURC£ and

cited usually

I

o-r -Foe":

private data

made OpenSource

as

method described soon

as they

in the

preceding section, such

as

Doom

were released. Instead, the development com-

panies waited until their next big products were being played

(

Quake and Descent

II,

respectively) before

they released the source to the older applications. This approach probably kept the publishers happy

because anyone

who was going

to

buy the older games already had them, so no

real

monev was

lost

from the move. But there

is

a potential legal issue involved with trying to use this method. If you sign a publishing

agreement, there this clause into

been

may be

a clause regarding ownership of the code.

the contract

and pray

that

no one

asks questions. Several

bitten by similar clauses in publishing agreements. Consider

Lemmings but agreed

Many

publishers will try to sneak

development companies have

DMA, who

created the original

to give Psygnosis all the intellectual property rights to the application

signed the publishing agreement

doubt

(I

they'll

make

when

they

that mistake again).

your game

no longer commercially viable until you release the code is that sometimes comebacks happen. For example, after several months of zero sales, something could happen, such as an appearance in a film or some fan fiction, that may

Another

factor to be careful about

if

you plan

to wait until

spark interest in the game, causing people to start buying

Guessing what the future may bring tion.

Remember, the

best

way

to

is

know

a dangerous thing

the future

is

to

it

is

once again.

and should be done only with extreme cau-

make

the future.

LimiT-ED I_1C€EN5-E Some programs, such

license allows the Povray available.

Another

have licenses that actually define

as Povray,

code

variation

to

on

be used on closed software

this

theme

is

the code can be reused. This

long as the original Povray code

is

made

to restrict the use of the software in certain environments,

such as with a "free for noncommercial use" license.

such as Genesis 3D, have licensing schemes

as

how

like this.

Many of the

free

game engines on

the market,

J

Linux GflmE PRDGRfliYimiNG

The

limited license

is

quite

common

in

many

areas. It allows

amateur developers with

little skill

to use

game development without spending months writing their own 3D engines or spending a few million on a commercial engine. The limited license allows them to focus on other aspects of game development, such as improving the game's artificial intelligence or just creating a good game in general. If the amateur game is of commercial quality, and the programmer decides to sell it, then the license will force royalty payments or lump sums to be paid to the developers of the the engine to practice

t\

original engine.

This philosophy

is

Commercial

perfect in today's world.

entities that

want

to use the software for profit

have the means to pay for that use and don't want the legal hassle of doing anything to breach the contract (license) supplied with the engine.

commercial-quality software are as

-i

long as

Amateur developers who don't have the means

free to use the engine,

still

and even

to develop

to redistribute their

end products,

isn't for profit.

it

K-EY TECWNDLDG1E5 Another option when

it

comes

to

games

is

to

the surrounding technologies, such as sound

your systems and to use them Alternatively,

method

make

to

their

keep the actual game

own games,

you can OpenSource the game

logic itself closed, but

and 3D engines. This option

logic

itself,

OpenSource

allows people to learn

while keeping your

game

from

unique.

while keeping the engine closed. (This

requires a bit of work because any changes to the logic must be recompiled against the

engine.)

One method

of doing

this

is

to dynamically link the

game

logic at

run time,

as

Quake II, using a shared library and a predefined interface for the functions. Although isn't strictly

OpenSource,

Continuing on

this

it

is

done with

this

method

does allow people to create patches for the game.

theme, you may want to create a separate scripting language for your game, or use

C library that gives you access to another language, such as Python. This method allows you to OpenSource the logic (so that others can create patches and the like) while keeping your development time to a minimum. This does have a slight impact on performance, depending on the language used,

a

but just about everything else in programming does anyway.

THE

lNDREIYlfl

Recently (in

December

the certification

Deeate

2000), a question was raised

on one of the Indrema mailing

program (which Indrema Entertainment Systems requires

test

happening

regarding

how

programs that run on

OpenSource software. Traditionally, anyone an OpenSource product, but the certification program prevents this free testing from

the console to participate in) would affect the testing of

can help

all

lists

in the usual way.

OF€NEOURC€i F«1€ND

The

certification

program works

You pay a

like this:

allowed to run on the Indrema system. Without sole.

This system allows Indrema to recoup the

Like

all

run uncertified games so that people can

about how to get mass testing done conflict

before

the

game

kit (at

test is

the

program

is

program won't run on the con-

selling the console at a loss.

a higher price

games

compared

as they write

to the console)

between OpenSource developers and Indrema.

from big red warnings saving that the game the development kits and everything in between.

is

uncertified to a time-share

sys-



tem

for

The

real

problem

is

that the

need

stands today. People

OpenSource bazaar model

isn't

J

compatible with console development as

whole process before a solution that everyone

to rethink the

is

happy with

can be found. The following sections present some of the ideas raised during the debate.

Big One

-R-ed

of the

tem was

first

Warning

ideas in resolving the conflict between

to allow

games

would allow people

to

to

OpenSource and the Indrema

be "semicertified" for free while they were

download the game and report bugs back

big red warning screen

would appear, saying

that the

to the author.

game was not yet

certification sys-

development. This approach

in

certified

When and

the

that

game

ran, a

Indrema

wouldn't be held responsible for any incompatibilities with the console. This suggestion presented several problems for Indrema, the biggest being that no one would actually

pay for

full certification if you

could get

it

for free, albeit at the

expense of a warning screen (but that

wouldn't put most people off playing the game). There was also the problem of malicious coders.

Because the game would be in development, the minicertificate wouldn't be able to be tied binary and the binary

file

would be subject

to change.

A checksum

to a single

of the binarv would have to be

regenerated even- time the program was compiled. This inconstant checksum could allow anvone to write a trojan that could cause irreparable

At the time debate.

I

n

them. The question

submitted to the certification process caused

Several ideas were raised,

it

that says the

file

this digital signature, a

money it lost

other consoles, Indrema has a development

that can

much

fee to get a binary

« FOE?

am

writing,

many people

still

damage

to the end-user's console.

think this

is

one of the better ideas proposed during the

Linux Gaiyi€ P-ROGR-RmnniNG

EmULflTO-RS 1

My contribution

II

use

to the debate

uncertified games. it

same

The emulator wouldn't run on

several potential

as those of a

can also

slightly

the console

is,

itself

problems with

this solution.

warp the

the

picture,

game

son an actual console

is

because that would allow people to

NTSC and PAL output systems are

normal monitor, and these systems would have

would therefore

The problem

the console

games.

to play uncertified

There are

was for Indrema to develop an emulator for the console that could run

making color bleed very hard

be emulated

to

to simulate accurately.

give an inaccurate representation of the

logic itself

needed

is

can be tested using a normal

not the

as well. Televisions

Emulation of

game.

PC running DV Linux. The

to test for interface glitches, such as

warping caused by

only rea-

televisions or

color bleeding that causes severe visual problems. These are the sorts of things that can't be emulated.

TlIYl-E-5-Hfl-R-E

One

PR representative was

of the suggestions from Indrema's

share the development

kits.

same geographic area,

this is

seldom the

need

access to the

testers,

who would

still

Although

this solution

case.

to

would work

This method

development

form developer groups

if

the developers were

all

that could

located in the

also failed to address the problem of

kits to test

the uncertified

titles.

R€G15TERED TESTERS Another suggestion was

home

number of testers

to allow a select

consoles by having a central database that the

refer to

when

Although

this

trying to load an uncertified

DRM

T+he-

Management) engine would

(Digital Rights

on the number of testers

suggestion puts a limit

and therefore have experience

in dealing with

available,

would have

bug

reports

it

does help ensure a higher

tested other

and the

Indrema games

like.

Solution

Currently,

and

run uncertified games on their standard

game.

quality of testers because the people registered as testers

before,

to

Indrema

is

looking at the

first

method, a

self-certification

testers to create a time-limited certificate to allow

through the

full certification

looks like this

is

code and the binaries

the

people to run the software without going

process.

The terms of usage would prevent people from ers to release the

system that would allow developers

method Indrema

is

(as

sharing the mini-certificates but would allow develop-

long as they are uncertified). At the time

planning to use to keep everyone happy.

I

am writing,

it

O-P-ENSaU-RC-EB

fRIEND

fD€l

O-R

License to Use?

LU-Hic-H

Ir

There are many kinds of OpenSource the issue of licensing.

the

there

You have

open

is

licenses,

and some people can get quite emotional regarding

the "free software fanatics"

more open-minded OpenSource

society,

in

From

zealot

who

who assumes

consider only a

that

all

GPL program

closed-source software

is

to

be

free, to

dangerous to

a whole range of attitudes towards licensing.

several kinds of licenses to

licenses such as the

BSD

choose from, including

license.

A number of the

viral licenses

more popular

such as the

license

GPL and more

agreements are printed

Appendix A.

Vl-R-RL

LlCENBEB

Licenses such as the

GNU Public License have a clause in them stating that any derivative software

must be released under the same has caused a lot of problems

used another

license, as

among KDE

must any

libraries that the software

developers because their

is

linked

to.

commonly used widget

This clause

library-,

Qt,

license.

This conflict has been the topic of a very heated argument, one side arguing that Qt must be

GPL

re-

LGPL, a less restrictive version of the license), and the other side claiming that the GPL was the thing that needed changing. This issue has almost been resolved since the Qt libraries were released under a new license, the QPL (Qt Public License), as well as the original released under the

(or

license.

But there are further complications involved. Some being one example);

as a result,

license as the library. It

anything

it

comes

close

is

this

libraries are released

under the

GPL (libMPEG

any program that uses that library must be released under the same

problem that causes people

to consider the

GPL

to

be a

virus, infecting

to.

They do help prevent people from taking under a completely new license. (Note that this does happen anyway; there are numerous examples of it, such as an incident where Be Inc. accidentally released a development tool based on a GPLed library.)

Viral licenses are

parts of one

good

for keeping things open, however.

program and cloning them

in a proprietary system

B

Linux Gaiyie PRQGRflmiYiiNG

O-F-EN LlC-EN i

Another type of OpenSource

license

worth considering

do more things with the source than a n

ple, allows

someone

to close the source

"free software fanatics" cial entities

would refuse

OpenSource

taking

viral license like

to

if

a

the

more open

this license,

license that allows

GPL permits. The BSD

they so desire. Although

go near

software,

is

it

many

end

license, for

users to

exam-

of the previously mentioned

does open up the prospect of commer-

adding their own proprietary extensions, and then releasing a

closed version of the modified software.

Although many people would argue that

this

scenario does nothing for the

OpenSource movement,

they would be wrong. Situations such as this would bring awareness to the movement, and the original software would

add

hooks up to

still

to the software to a

be available

may be

as

OpenSource

specific to that

software.

company's

custom database. Releasing the extensions

would have very

little

licenses allow practices like the

people to do

vital to

When

it

comes

as the graphics

GPL dictate

to

is

games,

the health of

if

you decided

engine and nothing

that the entire

linked to the

proprietary extensions a

company may

such as an employee-tracking system that

to allow access to a system

nobody has

access

point.

Many OpenSource this

The

uses,

OpenSource

if

in the enterprise

to release a small part of your

else),

you use the

my humble

available to

opinion, allowing

environment.

product as OpenSource (such

an open license would allow you

program must be made

LGPL library,

one just described. In

OpenSource

to

do

(or

so.

The terms of the

must be dynamically

lesser version of the license).

CUETOm LlC€N5E5 Some

situations

might require you

to write

your own software license from scratch. This approach can

be a problem because you would have to remember hand, If

it

to "cross all the

is

and dot

all

the

fe."

On

the other

allows you to have a license tailor-made to the software you're writing.

you plan on having a

restricted-use license,

you

doesn't have to be stupidly long and complex; redistribution rights, copyright,

and

will

it just

disclaimers.

probably have to write your

has to cover

all

own

license.

It

the essential features such as

DfenEoukceS Friend

d-r

FdeI

Llfl-BILITY One

area that most

With

off-the-shelf software,

OpenSource

licenses don't cover

is

issue is

a

is

company

is

little

responsible

(and sue)

if

you

when lose

IT

everything breaks.

all

your data, but with

n to

indemnify the original developers from blame,

protection under circumstances of gross negligence.

looking into purchasing software,

it

has to consider the

liability issue.

The

liability

why many people still buy faulty closed-source software: Because there and blame. With OpenSource software, nobody knows who is responsible for

the number-one reason

a single source for fixes

a certain line of code, or

Although

who

liability isn't really

planes coverdy, which

Some

to

is

rarely there.

Although many license agreements include clauses

When

who

you know who you can turn

OpenSource, that safeguard

these clauses offer very

is

is

wrote the

an

bit

of code that caused a conflict with another patch.

issue involving

unlikely),

publishers might want the

it

games

(unless your tide

happens

to

be used

to pilot

does affect the business perspective of OpenSource software.

liability

factor to

be resolved before any contracts are signed.

Linux

i w

GfiiYiE

FROGRflinrmNG

L-1-1

,

L=

^— —

Ir-

-

!i



r^—

^rf

APPENDIX A |

DpeniBdurce License

!

flGWEEIY1ENT5

^

Linux Gaiyie -Pf^oGRflmnmNG

i There are more OpenSource license agreements than you can shake a only the most popular ones in this appendix. License. This

is

distributed with the

start

with the most

Linux kernel,

GNU

G-EN-E-R-RL "PU-BLIC Ll

Version

1991

2, June

Copyright

Everyone

1

the license that

is

I'll

is

©

is

stick at, so

common,

I

the

will

include

GNU Public

as well as the core of

most Linux.

N

1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge,

MA 02139, USA.

permitted to copy and distribute verbatim copies of this license document, but changing

it

not allowed.

m-E The

licenses for

trast,

the

most software are designed

GNU General Public License

free software



to

make

is

sure the software

to take

intended is

free for

away your freedom to share and change to

using

it.

to

You can apply

it

to

is

your programs,

Our General

referring to freedom, not price.

users.

This General Public License applies to

any other program whose authors commit

(Some other Free Software Foundation software

Public License instead.)

covered by the too.

When we

new

free programs;

To protect your

and

rights,

that

it if

you want

speak of free

Public Licenses are designed to

it,

that

we need

to

make

make

if

software,

For example, recipients

code.

all

if

if

sure that you have

anyone

to

deny you these

rights or to

gratis

or for a

make sure that they, too, they know their rights.

the rights that you have. You must these terms so

if

you

dis-

it.

you distribute copies of such a program, whether

And you must show them

in

things.

restrictions that forbid

you modify

are

you wish), that you

ask you to surrender the rights. These restrictions translate to certain responsibilities for you tribute copies of the software, or

we

you can change the software or use pieces of it

you know you can do these

to

GNU Library General

the freedom to distribute copies of free software (and charge for this service receive source code or can get

By con-

guarantee your freedom to share and change

all its

most of the Free Software Foundation's software and

it.

fee,

you must give the

receive or can get the source

Df€nBdurc€ License ^greeiyients

We

and

protect your rights with two steps: (1) copyright the software,

you

gives

legal permission to copy, distribute

and

Also, for each author's protection

there

no warranty

is

we want

its

by others Finally,

we want

to

make

that

what they have

is

is

(2) offer

you

this license

which

software.

r

certain that everyone understands that

modified by someone

else

and passed on,

precise terms

is

threatened constantly by software patents.

program

To prevent

use or not licensed at

this,

We wish

to avoid the

danger that

will individually

obtain patent licenses, in effect making the program

made

must be licensed

we have

it

clear that any patent

for everyone's free

for copying, distribution

and modification

follow.

I

AND CONDITIONS

COPYING, DISTRIBUTION, AND MODIFICATION This License applies to any program or other work which contains a notice placed by the copyright

holder saying

it

may be

distributed

below, refers to any such

Program or any

under the terms of this General Public License. The "Program",

program or work, and a "work based on the Program" means

derivative

work under copyright

law: that

is

to say, a

either the

work containing the Program

or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is

is

included without limitation in the term "modification".) Each licensee

addressed as "you".

Activities

other than copying, distribution and modification are not covered by

The

are outside

its

Program

covered only

is

scope.

act of

if its

running the Program

is

this License; they

not restricted, and the output from the

contents constitute a work based

having been made by running the Program). Whether

that

is

on

true

the

Program (independent of

depends on what the Program

does. 1.

You mav copy and

distribute verbatim copies of the Program's source

medium, provided

that

to the

code

as

you receive

it,

in

any

you conspicuously and appropriately publish on each copy an appropriate

copyright notice and disclaimer of warranty; keep intact

and

d.

all.

and conditions

IY15

0.

fi

not the original, so that any problems introduced

not reflect on the original authors' reputations.

redistributors of a free

The

know

any free program

proprietary.

7

for this free software. If the software

recipients to

will

ours,

and/or modify the

all

the notices that refer to this License

absence of any warranty; and give any other recipients of the Program a copy of this

License along with the Program.

You may charge a

fee for the physical act of transferring a copy,

warranty protection in exchange for a

fee.

and you may

at

your option offer

Linux Gaiyie FRDGRflmmiNG

2.

You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section

p

1

above, provided that you also

You must cause the modified

a)

n

files

files to

of these conditions:

all

prominent notices

carry

stating that

you changed the

and the date of any change.

You must cause any work

b)

meet

that

you

distribute or publish, that in

whole or

in part contains or

no charge

derived from the Program or any part thereof, to be licensed as a whole at third parties

to all

under the terms of this License.

If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License.

c)

(Exception:

if

the

Program

itself is interactive

ment, your work based on the Program

j

is

These requirements apply

is

but does not normally print such an announce-

not required to print an announcement.)

modified work as a whole.

to the

If identifiable sections

of that work are

not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License,

them

as separate works.

and

its

terms,

do not apply

when you

to those sections

But when you distribute the same sections

as part

distribute

of a whole which

is

a

work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend regardless of who wrote

Thus, ly

it is

to

each and every part

not the intent of this section to claim rights or contest your rights to work written entireis

to exercise the right to control the distribution

of derivative or collec-

works based on the Program.

In addition,

mere aggregation of another work not based on the Program with

with a work based

on the Program) on a volume of a

bring the other work under the scope of 3.

and thus

it.

by you; rather, the intent

tive

to the entire whole,

You may copy and

distribute the

storage or distribution

the

Program

medium does

(or

not

this License.

Program

(or a

work based on

or executable form under the terms of Sections

1

it,

under Section

and 2 above provided

that

2) in object

you

also

code

do one of the

following: a)

Accompany

it

with the complete corresponding machine-readable source code, which must

be distributed under the terms of Sections software interchange;

or,

1

and 2 above on a medium customarily used

for

DfenEource License

b)

Accompany

it

with a written

offer, valid for at least

flG«€EiriENT5

three years, to give any third party, for a

charge no more than your cost of physically performing source distribution, a complete Ir

machine-readable copy of the corresponding source code, to be distributed under the terms of Sections c)

1

Accompany

and 2 above on a medium customarilv used

it

for software interchange; or,

with the information you received as to the offer to distribute corresponding

source code. (This alternative

is

allowed only for noncommercial distribution and onlv

you

if

received the program in object code or executable form with such an offer, in accord with

Subsection b above.)

The source code

for a

work means the preferred form of the work

For an executable work, complete source code means tains,

plus any associated interface definition

of the executable. However,

installation

not include anything that

components (compiler, unless that

component

If distribution

is

itself

and

the source code for

all

modules

to

as a special exception, the source (in either

it.

con-

it

plus the scripts used to control compilation

files,

normally distributed

kernel,

all

making modifications

for

and

code distributed need

source or binarv form) with the major

so on) of the operating system

on which the executable

runs,

accompanies the executable.

of executable or object code

place, then offering equivalent access to

is

made by

offering access to copy from a designated

copy the source code from the same place counts

as distri-

bution of the source code, even though third parties are not compelled to copy the source along with the object code. 4.

You may not under void,

copy, modify', sublicense, or distribute the

this License.

and

will

Any attempt otherwise

to copy,

Program except

as expressly

provided

modify sublicense or distribute the

automatically terminate your rights under this License. However, parties

Program

who

is

have

received copies, or rights, from you under this License will not have their licenses terminated so

long as such parties remain in 5.

You are not required

to accept

full

compliance.

this License, since

grants you permission to modify or distribute the

prohibited by law

Program so,

and

all its

based on 6.

(or any

if

you do not accept

you have not signed

Program or

this License.

its

it.

However, nothing

derivative works.

else

These actions are

Therefore, by modifying or distributing the

work based on the Program) you indicate your acceptance of this License ,

to

do

terms and conditions for copying, distributing or modifying the Program or works

it.

Each time you redistribute the Program (or any work based on the Program) the recipient auto,

matically receives a license

subject to

from the original licensor

to copy, distribute or

these terms and conditions. You may not impose any further

ents' exercise

modifv the Program

restrictions

on the

recipi-

of the rights granted herein. You are not responsible for enforcing compliance b\

third parties to this License.

Linux G-nm-E PRDGRfiinirnNG

If,

consequence of a court judgment or allegation of patent infringement or for any other

as a

son (not limited to patent

ment or under

this

ute the

imposed on you (whether by court

otherwise) that contradict the conditions of this License, they

conditions of this License.

n

issues), conditions are

cannot distribute so as to

satisfy

at

of the Program by satisfy

all.

For example,

those

all

both

it

who

and

this

if

order, agree-

do not excuse you from the

simultaneously your obligations

License and any other pertinent obligations, then as a consequence you

Program

you could

If you

rea-

may not

distrib-

a patent license would not permit royalty-free redistribution

receive copies directly or indirectly through you, then the only

way

License would be to refrain entirely from distribution of the

Program. If

any portion of this section

the balance of the section

is

is

held invalid or unenforceable under any particular circumstance,

intended to apply and the section as a whole

is

intended to apply in

other circumstances. It is

not the purpose of this section to induce you to infringe any patents or other property right

claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system,

which

is

implemented by public

license practices.

Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide

if

he or she

is

willing to distribute software

through any other system and a licensee cannot

impose that choice. This section

is

intended to make thoroughly clear what

is

believed to be a consequence of the rest

of this License. If

the distribution and/or use of the

Program

is

restricted in certain countries either by patents or

by copyrighted interfaces, the original copyright holder

may add an tion

is

permitted only in or

among

places the

Program under

this

License

countries not thus excluded. In such case, this License incorpo-

rates the limitation as if written in the

The Free

who

explicit geographical distribution limitation excluding those countries, so that distribu-

body of this License.

may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number this

Software Foundation

License which applies to

and conditions Foundation.

If

it

and "any

later version",

of

you have the option of following the terms

either of that version or of any later version published by the Free Software

the

Program does not

specify a version

number of this

version ever published by the Free Software Foundation.

License, you

may choose any

DP€N5ouRce License Agkeeiyients

10.

If you

wish to incorporate parts of the Program into other free programs whose distribution condi-

tions are different, write to the author to ask for permission. For software

the Free Software Foundation, write to the Free Software Foundation; tions for this.

Our

12.

is

copyrighted by

we sometimes make excep-

decision will be guided by the two goals of preserving the free status of

tives of our free software

11.

which

and of promoting the sharing and reuse of software

all

r

deriva-

generally.

BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK .AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/ OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

n

cU

Linux

i

n

GNU

Game

FRDGRfliYiiYiiNG

L€5 5€R General -Public

License

Version

2.1,

February 1999

GNU Web site.) Copyright © 1991, Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA (The master copy of this license

Everyone is

is

lives

on the

1999 Free Software

permitted to copy and distribute verbatim copies of this license document, but changing

it

not allowed.

[This

is

the

first

released version of the Lesser GPL.

Public License, version

It

hence the version number

2,

also counts as the successor of the

GNU Library

2.1.]

IY1-E

1

The

licenses for

the

trast,

most software are designed

to take

away your freedom

and change

to share

GNU General Public Licenses are intended to guarantee your freedom

free software



to

make

sure the software

is

free for

all its

to share

it.

By con-

and change

users.

This license, the Lesser General Public License, applies to some specially designated software pack-



ages

typically libraries

can use

it

too,

—of the Free Software Foundation and other authors who decide

but we suggest you

General Public License

is

first

to use

it.

You

think carefully about whether this license or the ordinary

on the explanations

the better strategy to use in any particular case, based

below.

When we

speak of free

Licenses are designed to

(and charge for

we

software,

make

this service if

are referring to

To protect your to ask

you

to

ents

all

in

rights,

we need

to

you

make

rights. if

These

and

that

you want

it;

that

you are informed that

we gave

you. You must

make

whether

gratis

or for a

fee,

you must

so that they can relink

them with the

library after

these terms so they

rights or

you

if

you

making changes

know

give the recipi-

sure that they, too, receive or can get the source

you must provide complete object

library,

And you must show them

deny you these

it.

distribute copies of the library,

the rights that

you

free programs;

it if

restrictions translate to certain responsibilities for

you modify

code with the

If

new

restrictions that forbid distributors to

link other

code.

Public

things.

surrender these

if

Our General

you wish); that you receive source code or can get

distribute copies of the library or

For example,

price.

sure that you have the freedom to distribute copies of free software

you can change the software and use pieces of it you can do these

freedom of use, not

their rights.

files to

to the library

the recipients,

and recompiling

it.

DFEN5QURC€ LlCEN5£

We

protect your rights with a two-step method: (1)

which

license,

you

gives

we copyright

legal permission to copy, distribute

flGREEITlENTS

the library,

and

and/or modify the

we

(2)

you

offer

this

library.

r

To protect each Also,

if

the library

they have

is

we want to make it very clear that there is no warranty for the free library. modified by someone else and passed on, the recipients should know that what

distributor, is

7

not the original version, so that the original author's reputation

will

fi

not be affected by

problems that might be introduced by others. Finally, software

sure that a

patents pose a constant threat to the existence of any free program.

company cannot

effectively restrict the users of a free

license

from a patent holder. Therefore, we

library

must be consistent with the

Most

full

insist that

We wish

program by obtaining

to

make

a restrictive

any patent license obtained for a version of the

freedom of use specified

in this license.

GNU software, including some libraries, covered by the ordinary GNU General Public License. GNU Lesser General Public License, applies to certain designated libraries, and is is

from the ordinary General Public License.

We

use this license for certain libraries in

order to permit linking those libraries into non-free programs.

When

a

program

of the two

is

is

legally

linked with a library, whether statically or using a shared library, the combination

speaking a combined work, a derivative of the original

Public License therefore permits such linking only

The

Lesser General Public License permits

more

if

library.

the entire combination

The ordinary General

fits its

lax criteria for linking other

criteria

of freedom.

code with the

librarv.

We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for

many libraries. However,

the Lesser license provides advantages in cer-

tain special circumstances.

For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that

allowed to use the

it

becomes a

library.

de-facto

non-free libraries. In this case, there

we use

standard.

To achieve

A more frequent case is that a free is little

to gain

this,

library

non-free programs must be

does the same job

the

used

only, so

the Lesser General Public License.

programs enables a greater number of

GNU C Library in nonGNU operating system, as well as its variant,

people to use a large body of free software. For example, permission to use the free

as widely

by limiting the free library to free software

In other cases, permission to use a particular library in non-free

programs enables many more

GNU/Linux

operating system.

people to use the whole

U

[

This license, the quite different

cL

Linux G-nme FROGRfliYimiNG

Although the Lesser General Public License the user of a

program

that

,

precise terms

to the difference

Less protective of the users' freedom,

does ensure that

and conditions

Library.

for copying, distribution

between a "work based on the

library"

and modification

and a "work

contains code derived from the library, whereas the latter must be

Jd

it

linked with the Library has the freedom and the wherewithal to run that

is

program using a modified version of the

The

is

Pay close attention

follow.

that uses the library".

combined with the

The former

library in order

to run.

AND CONDITIONS

IY15

COPYING, D15TR1EUT1DN, AND mDDlflCflTlDN 0.

This License Agreement applies to any software library or other program which contains a notice

placed by the copyright holder or other authorized party saying

terms of this Lesser General Public License (also called

it

may be

"this License").

distributed

Each licensee

under the is

addressed

as "you".

A "library" means a collection

of software functions and/or data prepared so as to be conveniently

linked with application programs (which use

some of those

functions

and

data) to

form executa-

bles.

The

"Library", below, refers to

these terms.

A

copyright law

any such software library or work which has been distributed under

"work based on the Library" means either the Library or any derivative work under

— that

is

to say, a

work containing the Library or a portion of it,

either verbatim or

with modifications and/or translated straightforwardly into another language. (Hereinafter, translation

is

included without limitation in the term "modification".)

"Source code" for a work means the preferred form of the work for making modifications to a library, complete source code

means

ciated interface definition

plus the scripts used to control compilation

files,

all

the source code for

all

modules

it

it.

For

contains, plus any asso-

and

installation

of the

library.

Activities

other than copying, distribution and modification are not covered by

are outside

its

scope.

from such a program

The is

act of

running a program using the Library

covered only

if its

program

they

not restricted, and output

contents constitute a work based on the Library (inde-

pendent of the use of the Library in a tool for writing the Library does and what the

is

this License;

it).

Whether

that uses the Library does.

that

is

true

depends on what

CD-PEN 5 OU-RC-E

1.

You may copy and it,

in

LlCEN5€ flGRE£m€NT5

complete source code

distribute verbatim copies of the Library's

as

you receive

any medium, provided that you conspicuously and appropriatelv publish on each copy an il

appropriate copyright notice and disclaimer of warranty; keep intact

all

the notices that refer to

License and to the absence of any warranty; and distribute a copy of

this

this

License along with

the Library.

You may charge a

fee for the physical act of transferring a copy,

warranty protection in exchange for a 2.

and you may

at

your option offer

fee.

You may modify your copy or copies of the Library or any portion of it, thus forming a work based

on the

Library',

and copy and

above, provided that you also

distribute such modifications or

meet

all

The modified work must

b)

You must cause the

c)

You must cause the whole of the work

files

files

1

of these conditions:

a)

itself

work under the terms of Section

be a software

library.

modified to carry prominent notices stating that you changed the

and the date of any change. be licensed

to

at

no charge

to all third parties

under

the terms of this License. the modified Library refers to a function or a table of data to be supplied by an

If a facility in

d)

application is

program

that uses the

invoked, then you must

make

does not supply such function or of

its

other than as an argument passed

facility,

when

the

facility

a good faith effort to ensure that, in the event an application table, the facility

still

operates,

and performs whatever part

purpose remains meaningful.

(For example, a function in a library to compute square roots has a purpose that

is

entirely well-

defined independent of the application. Therefore, Subsection 2d requires that any applicationsupplied function or table used by this function must be optional: ply

the square root function must

it,

These requirements apply not derived from the in themselves,

them

then

whose

ly

as a

roots.)

whole.

If identifiable sections

and

its

terms,

do not apply

to those sections

But when you distribute the same sections

it is

of that work are

as part

when you

distribute

of a whole which

is

a

whole must be on the terms of this License,

permissions for other licensees extend to the entire whole,

and thus

to

each and every part

it.

not the intent of this section to claim rights or contest your rights to work written entire-

by you; rather, the intent

tive

modified work

Library, the distribution of the

regardless of who wrote

Thus,

compute square

the application does not sup-

and can be reasonably considered independent and separate works

this License,

as separate works.

work based on the

to the

Library',

still

if

is

to exercise the right to control the distribution of derivative or collec-

works based on the Library.

mere aggregation of another work not based on the Library with the Library (or with work based on the Library) on a volume of a storage or distribution medium does not bring the In addition,

other work under the scope of

this License.

a

Linux Gaitie

3.

You may opt to a given

-P-RaG-R-HiYirYnNG

to apply the terms of the ordinary

copy of the Library. To do

ll

this,

GNU General Public License instead of this License

you must

alter all the notices that refer to this License, so

GNU General Public License, version 2, instead of to this License. than version 2 of the ordinary GNU General Public License has appeared, then

that they refer to the ordinary (If

f

a newer version

you can

Once

specify that version instead

this

change

is

made

[

not a 4.

when you

useful

is

you

wish.)

in a given copy,

General Public License applies This option

if

to all

it is

Do

not make any other change in these notices.

that copy.

wish to copy part of the code of the Library into a program that

distribute the Library (or a portion or derivative of

code or executable form under the terms of Sections

is

1

it,

under Section

and 2 above provided

that

2) in object

you accompany

with the complete corresponding machine-readable source code, which must be distributed

under the terms of Sections If distribution

and 2 above on a medium customarily used

1

of object code

is

made by

offering access to copy

offering equivalent access to copy the source code

:

made from

library.

You may copy and

it

GNU

irreversible for that copy, so the ordinary

subsequent copies and derivative works

distribute the source code, even

though third

from a designated

from the same place

parties are not

for software interchange.

satisfies

compelled

place, then

the requirement to

copy the source along

to

with the object code. 5.

A program

that contains

no

derivative of

any portion of the Library, but

the Library by being compiled or linked with

work, in isolation,

is

it, is

is

designed to work with

called a "work that uses the Library".

not a derivative work of the Library, and therefore

falls

Such a

outside the scope of

this License.

However, linking a "work that uses the Library" with the Library creates an executable that derivative of the Library (because

the library".

The executable

is

it

is

a

contains portions of the Library), rather than a "work that uses

therefore covered by this License. Section 6 states terms for distribu-

tion of such executables.

When

a "work that uses the Library" uses material from a header

object code for the not.

Whether

the work If

is itself

such an object

small macros is

this

work may be a

is

true

is

a library. file

derivative

especially significant

The

that

is

the

and small

the work

part of the Library, the

work can be linked without the is

not precisely defined by

uses only numerical parameters, data structure layouts

and

is

Library, or

it is

legally a derivative

is

still fall

accessors,

and

a derivative of the Library, you

under the terms of Section

6.

directfy with the Library

that

itself.

file

this

6.)

may distribute

Any executables containing

whether or not they are linked

work. (Executables containing

under Section

if

law.

inline functions (ten lines or less in length), then the use of the object

object code plus portions of the Library will if

if

threshold for this to be true

unrestricted, regardless of whether

Otherwise,

file

work of the Library even though the source code

work

the object code for the work

also

fall

under Section

6,

DfenBource License Agfeeiyients

6.

As an exception

to the Sections above,

you may

also

combine or

link a "work that uses the Library"

with the Library to produce a work containing portions of the Library, and distribute that work 1

under terms of your choice, provided tomer's

own

You must

prominent notice with each copy of the work

and

among them,

must do one of these a)

for the cus-

Accompany

that the Library

is

used in

it

and

use are covered by this License. You must supply a copy of this License.

its

work during execution Library

work

use and reverse engineering for debugging such modifications.

give

the Library

that the terms permit modification of the

the

displays copyright notices,

you must include the copyright notice

as well as a reference directing the user to the

that

the

for the

copy of this License. Also, you

things:

work with the complete corresponding machine-readable source code work (which must be

the Library including whatever changes were used in the

under Sections

If

1

and 2 above); and,

if

the

work

is

for

distributed

an executable linked with the Library, with

and/or source

the complete machine-readable "work that uses the Library", as object code

code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library.

contents of definitions

files in

(It is

understood that the user who changes the

the Library will not necessarily be able to recompile the appli-

cation to use the modified definitions.) b)

Use a

one

suitable shared library

that (1) uses at

mechanism

for linking with the Library.

A suitable

tem, rather than copying library functions into the executable, and (2) with a modified version of the is

c)

library; if

the work with

made

a written offer, valid for at least

d)

with.

no more than the

cost of per-

this distribution.

If distribution

of the work

is

made by

offering access to copy

equivalent access to copy the above specified materials e)

operate properly

three years, to give the same user

the materials specified in Subsection 6a, above, for a charge

forming

will

is

sys-

the user installs one, as long as the modified version

interface-compatible with the version that the work was

Accompany

mechanism

run time a copy of the library already present on the user's computer

Verify' that

from a designated

from the same

place, offer

place.

the user has already received a copy of these materials or that you have already

sent this user a copy.

For an executable, the required form of the "work that uses the Library" must include any data and utility

programs needed for reproducing the executable from

it.

the materials to be distributed need not include anything that

is

However,

as a special exception,

normally distributed

(in either

source or binary form) with the major components (compiler, kernel, and so on) of the operating system It

on which the executable

may happen

runs, unless that

component

itself

accompanies the executable.

that this requirement contradicts the license restrictions of other proprietary

do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that vou distribute. libraries that

r L

Linux Gaiyie PHROG-R-nrYimiNG

E5E

7.

You may place

library facilities that are a

together with other library

library facilities

I

this License,

and

distribute such a

combined

otherwise permitted, and provided that you do these two things:

is

Accompany

a)

not covered by

side-by-side in a single library

provided that the separate distribution of the work based on the Library and of the other

library,

f

facilities

work based on the Library

combined

the

library with a

bined with any other library

copy of the same work based on the Library, uncom-

This must be distributed under the terms of the

facilities.

Sections above.

Give prominent notice with the combined library of the fact that part of

b)

l

to find the

it is

a

work based on

accompanying uncombined form of the same

work. 8.

You may not ed under

copy, modify, sublicense, link with, or distribute the Library except as expressly provid-

this License.

the Library

is

who have

ties

J

and explaining where

the Library,

void,

and

will

otherwise to copy, modify, sublicense, link with, or distribute

automatically terminate your rights under this License. However, par-

received copies, or rights, from you under this License will not have their licenses

minated so long 9.

Any attempt

as

such parties remain in

You are not required

full

compliance.

to accept this License, since

you have not signed

grants you permission to modify or distribute the Library or

prohibited by law

if

you do not accept

Library (or any work based

and

on 10.

all its

on the

ter-

this License.

its

it.

However, nothing

derivative works.

else

These actions are

Therefore, by modifying or distributing the

Library) you indicate your acceptance of this License to ,

do

so,

terms and conditions for copying, distributing or modifying the Library or works based

it.

Each time you

redistribute the Library (or any

cally receives a license

from the

subject to these terms

and

ents' exercise of the rights

work based on the

Library), the recipient automati-

original licensor to copy, distribute, link with or modify the Library

conditions.

You may not impose any further

restrictions

on the

recipi-

granted herein. You are not responsible for enforcing compliance by

third parties with this License. 11.

If,

as a

consequence of a court judgment or allegation of patent infringement or for any other

son (not limited to patent

ment or

conditions of this License.

under

issues),

conditions are imposed

on you (whether by court

otherwise) that contradict the conditions of this License, they

this

cannot distribute so as to

satisfy

of the Library by satisfy

all.

all

For example,

those

both

it

who

and

if

order, agree-

do not excuse you from the

simultaneously your obligations

License and any other pertinent obligations, then as a consequence you

ute the Library at

you could

If you

may not

distrib-

a patent license would not permit royalty-free redistribution

receive copies direcdy or indirectly through you, then the only

this

rea-

way

License would be to refrain entirely from distribution of the

Library.

i

DF€N5DURCE L1CEN5E

If

any portion of this section

the balance of the section

is

is

flGR€€IYI£NT5

held invalid or unenforceable under any particular circumstance,

intended to apply, and the section as a whole

is

intended to apply

in

r

other circumstances. It is

not the purpose of this section to induce you to infringe any patents or other property right

claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system

Many people have made generous on

that system in reliance

decide

if

he or she

is

which

is

implemented by public

license practices.

contributions to the wide range of software distributed through

consistent application of that system;

willing to distribute software

it is

up

to the

author/ donor to

through any other system and a licensee cannot

impose that choice. This section

is

intended to make thoroughly clear what

is

believed to be a consequence of the rest

of this License. 12.

If

the distribution

and/or use of the Library

is

restricted in certain countries either by patents or bv

copyrighted interfaces, the original copyright holder

may add an tion

is

The Free

if

among

written in the

Software Foundation

may

differ in detail to address

Each version this

is

this

License

body of this License.

publish revised and/or

and conditions If

new versions

will

new versions of the

be similar in

spirit to

Lesser General

the present version,

new problems or concerns.

given a distinguishing version number. If the Library specifies a version

License which applies to

Foundation.

under

countries not thus excluded. In such case, this License incorpo-

Public License from time to time. Such

but may

places the Library

explicit geographical distribution limitation excluding those countries, so that distribu-

permitted only in or

rates the limitation as 13.

who

it

and "any

later version",

number of

you have the option of following the terms

either of that version or of any later version published by the Free Software

the Library- does not specify a license version number, you

may choose any version

ever published by the Free Software Foundation. 14.

If you

wish to incorporate parts of the Library into other free programs whose distribution condi-

tions are incompatible with these, write to the author to ask for permission. For software

which

is

copyrighted by the Free Software Foundation, write to the Free Software Foundation; we some-

Our

times

make exceptions

status

of all derivatives of our free software and of promoting the sharing and reuse of software

for this.

decision will be guided by the two goals of preserving the free

generally. 15.

BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR

n

Linux

Game

-P-ROG-R-FimmiNG

BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BYYOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARYTO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. IMPLIED, INCLUDING,

1

n 16.

Jn

1

Dfen5ourc€ License Agreeiyients

E5D The

following

N

Li is

a

BSD

ORGANIZATION and YEAR from Note:

The

To generate your own

license template.

license,

their original values as given here,

advertising clause in the license appearing

on BSD Unix

change the values of OWNER,

and

files

substitute

was

officially

Director of the Office of Technology Licensing of the University of California

"hereby deleted in

states that clause 3

is

Note the new BSD

license

is

its

your own.

B

rescinded by the

on July 22

1999.

He

entirety."

thus equivalent to the

MIT

License, except for the no-endorsement final

clause. = Regents of the University of California

= University of California, Berkeley

= 1998 In the original

BSD

TRIBUTORS"

in the disclaimer read

Here

is

license, the first

"COPYRIGHT HOLDERS AND CON"REGENTS AND CONTRIBUTORS".

occurrence of the phrase

the license template:

Copyright

© ,

All rights reserved.

Redistribution

and use

in source

and binary forms, with or without modification, are permitted

provid-

ed that the following conditions are met: •

Redistributions of source code must retain the above copyright notice, this

list

of conditions and the

following disclaimer. •

Redistributions in binary form must reproduce die above copyright notice, this

the following disclaimer in the documentation

list

of conditions and

and/or other materials provided with the

distribu-

tion. •

Neither the

name of the nor

endorse or promote products derived from

the

names of its contributors may be used

this software

to

without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LLABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWE\TR CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Linux

G-hiyi-e "F-ROG-R-RiYirYnNG

R-RT15T1C LlC-EN 1

fl

FREfimeLE The

JD

intent of this

document

is

to state the conditions

under which a Package may be copied, such

that

some semblance of artistic control over the development of the package, while giving the users of the package the right to use and distribute the Package in a more-or-less customary fashion, plus the right to make reasonable modifications. the Copyright Holder maintains

Definitions "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of

files

created through textual modification.

"Standard Version" refers to such a Package

has not been modified, or has been modified in accor-

if it

dance with the wishes of the Copyright Holder. "Copyright Holder" 'You"

is

you,

if

is

whoever

is

named

you're thinking about copying or distributing this Package.

"Reasonable copying fee"

is

whatever you can justify on the basis of media

time of people involved, and so on. (You only to the computing "Freely Available"

community

means

handling the item.

It

tions they received

it.

1

in the copyright or copyrights for the package.

that

also

means

You may make and Package without

no

will

not be required to justify

is

charged for the item

that recipients of the item

itself,

may

provided that you duplicate

fee.)

though there may be

redistribute

give away verbatim copies of the source

restriction,

to the Copyright Holder, but

market that must bear the

at large as a

fee

it

all

duplication charges,

cost,

it

fees involved in

under the same condi-

form of the Standard Version of this of the original copyright notices and

associated disclaimers. 2.

You may apply bug

fixes, portability fixes

or from the Copyright Holder.

and other modifications derived from the Public Domain

A Package

modified

in

such a way shall

still

be considered the

Standard Version. 3.

You may otherwise modify your copy of this Package nent notice

you do

in

at least

each changed

ONE

file

stating

of the following:

in

any way, provided that you insert a promi-

how and when you changed

that

file,

and provided

that

a)

place your modifications in the Public

Domain

or otherwise

make them

Freely Available,

such as by posting said modifications to Usenet or an equivalent medium, or placing the modifications on a major archive

your modifications

to include

site

in the

such as ftp.uu.net, or by allowing the Copyright Holder

Standard Version of the Package.

b)

use the modified Package only within your corporation or organization.

c)

rename any non-standard executables bles,

which must

dard executable that

names do not

so the

conflict with standard executa-

be provided, and provide a separate manual page for each non-stan-

also

clearly

documents how

it

differs

from the Standard Version.

make other distribution arrangements with the Copyright Holder. You may distribute the programs of this Package in object code or executable form, provided d)

4.

you do a)

at least

distribute a Standard Version of the executables (in the

b)

that

ONE of the following:

manual page or equivalent) on where

accompany the

and

library

to get the

files,

together with instructions

Standard Version.

distribution with the machine-readable source of the Package with your

mod-

ifications. c)

accompany any non-standard executables with

their

corresponding Standard Version exe-

cutables, giving the non-standard executables non-standard

the differences in

manual pages

names, and clearly documenting

(or equivalent), together with instructions

on where

to get

the Standard Version.

dmake other distribution arrangements with the Copyright Holder. You may charge a reasonable copying fee for any distribution of this Package. You may charge any fee you choose for support of this Package. You may not charge a fee for this Package itself. d)

5.

However, you may distribute

this

Package

in

aggregate with other (possibly commercial) programs

as part of a larger (possibly commercial) software distribution provided that

6.

this

Package

The

scripts

as a

and

product of your own.

library files supplied as input to or

Package do not automatically generated them, and may 7.

C

8.

fall

produced

as

output from the programs of

under the copyright of this Package, but belong

be sold commercially,

and may be aggregated with

or Perl subroutines supplied by you and linked into

this

you do not advertise

this

Package

shall

this

to

whomever

Package.

not be considered part of

Package.

The name of the Copyright Holder may not be used

to

endorse or promote products derived from

this software without specific prior written permission. 9.

this

THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.

I

Linux Gaiyie FRDGRflmiYiiNG

-Public Lic-en

lYloziLL-n 1 Version 1.0

n

l.D. D-E-F1N1T10N5 means each

entity that creates or contributes to the creation of Modifications.

1.1.

"Contributor"

1.2.

"Contributor Version" means the combination of the Original Code, prior Modifications used by a

and the Modifications made by

Contributor, 1.3.

Code and 1.4.

Modifications, in each case including portions thereof.

"Electronic Distribution

opment community 1.5.

"Executable"

1 .6.

"Initial

Code 1.7.

that particular Contributor.

"Covered Code" means the Original Code or Modifications or the combination of the Original

Mechanism" means a mechanism generally accepted

in the software devel-

for the electronic transfer of data.

means Covered Code

in

any form other than Source Code.

Developer" means the individual or entity identified as the

Initial

Developer

in the

Source

notice required by Exhibit A.

"Larger Work" means a work which combines Covered

Code or

portions thereof with code not gov-

erned by the terms of this License.

means

1.8.

"License"

1.9.

"Modifications"

Original

this

document.

means any addition

Code or any

Modification

to or deletion

previous Modifications.

from the substance or structure of either the

When

Covered Code

is

released as a series of files, a

is:

A.

Any

B.

Any new

addition to or deletion from the contents of a

file

Code or

containing Original

previous

Modifications.

1.10.

"Original

Code this

1.11.

file

that contains any part of the Original

Code or

previous Modifications.

Code" means Source Code of computer software code which

notice required by Exhibit

License

is

A as Original

Code, and which,

not already Covered Code governed by

at the

is

described in the Source

time of

its

release

under

this License.

"Source Code" means the preferred form of the Covered Code for making modifications to including trol

all

modules

it

contains, plus any associated interface definition

compilation and installation of an Executable, or a

against either the Original

Contributor's choice.

list

Code or another well known,

The Source Code can be

in a

files,

scripts

it,

used to con-

of source code differential comparisons

available

Covered Code of the

compressed or archival form, provided the

appropriate decompression or de-archiving software

is

widely available for

no charge.

Dp€nBdurce License Agreeitients

1.12.

'You"

means an

terms

of, this

License or a future version of this License issued under Section

'You" includes any entity which controls,

is

controlled by, or

For purposes of this definition, "control" means direction or

and complying with

individual or a legal entity exercising rights under,

management of such

entity,

(a)

the

under

is

pow er, T

6.1.

common

For

all

of the

legal entities,

control with You.

direct or indirect, to cause the

whether by contract or otherwise, or

(b)

ownership of fifty

percent (50%) or more of the outstanding shares or beneficial ownership of such

entity.

B.Da 5durce Code License 2.1.

The

Initial

Developer Grant.

The

Initial

Developer hereby grants You a world-wide,

royalty-free, non-exclusive license, subject to

third party intellectual property claims: (a)

to use,

reproduce, modify, display, perform, sublicense and distribute the Original Code (or

portions thereof) with or without Modifications, or as part of a Larger Work; and (b)

under patents now or hereafter owned or controlled by made, use and

sell ("Utilize")

extent that any such patent (or portions thereof)

is

and not

the Original

Code

Initial

Developer, to make, have

(or portions thereof), but solely to the

reasonably necessary to enable You to Utilize the Original to

any greater extent that may

Code

be necessary to Utilize further

Modifications or combinations. 2.2.

Contributor Grant.

Each Contributor hereby grants You a world-wide,

royalty-free, non-exclusive license, subject to

third party intellectual property claims: (a)

to use,

reproduce, modify, display, perform, sublicense and distribute the Modifications creat-

ed by such Contributor (or portions thereof) either on an unmodified Modifications, as Covered (b)

Code or

basis,

with other

of a Larger Work; and

as part

under patents now or hereafter owned or controlled by Contributor, Contributor Version (or portions thereof) but ,

to Utilize the

solely to the extent that

any such patent

is

rea-

sonably necessary to enable You to Utilize the Contributor Version (or portions thereof), and

not to any greater extent that

may be

necessary to Utilize further Modifications or combina-

tions.

2.D. DlBTRlEUTlDN DfiLlGflTlDNB 3. 1

.

Application of License.

The

Modifications which You create or to which You contribute are governed by the terms of this

License, including without limitation Section 2.2.

The Source Code

version of Covered

Code may

Linux

P-RaG-R-nmmiNcs

G-rfyi-e

be distributed only under the terms of this License or a future version of this License released

i

6.1,

You

You may not

distribute.

restricts

n

may 3.2.

and You must include a copy of this License with every copy of the Source Code

under Section

include an additional

Code form under

document

You contribute must be made

create or to which

the terms of this License either

and

if

made

able for at least twelve (12)

on the same media to

anyone

to

after the date

an Executable

Mechanism, must remain

became

initially

it

an Executable version or

whom you made

available via Electronic Distribution

months

as

available in Source

available,

or at least

You are responsible

the Electronic Distribution

for ensuring that the Source

Mechanism

is

Code

maintained by a third

avail-

six (6)

subsequent version of that particular Modification has been made available

after a

recipients.

to

such

version remains available even

if

party.

Description of Modifications.

You must cause

all

changes You made

Covered Code to create that

prominent statement provided by the

Source Code, and

to

which you contribute

is

documenting the

derived, direcdy or indirecdy,

Developer and including the

(b) in

to contain a file

Covered Code and the date of any change. You must include a

that the Modification

Initial

You describe the 3.4.

offering the additional rights described in Section 3.5.

an accepted Electronic Distribution Mechanism

version available;

3.3.

or

Source Code.

Any Modification which You

months

alters

the applicable version of this License or the recipients' rights hereunder. However, You

Availability of

via

impose any terms on any Source Code version that

offer or

any notice

in

name of the

Initial

from Original Code

Developer

in (a) the

an Executable version or related documentation

in

which

origin or ownership of the Covered Code.

Intellectual Property Matters. (a)

Third Party Claims. If

You have knowledge

tionality

or code (or

its

that a party claims utilization

source code distribution tided

under

after

intellectual property right in particular func-

this License),

LEGAL which

claim in sufficient detail that a recipient

knowledge

an

will

the

LEGAL file

in

all

describes the claim

know whom

You make Your Modification

prompdy modify

(b)

inform those

who

copies You

received the Covered

text file with the

and the party making the

to contact. If you obtain such

available as described in Section 3.2,

other steps (such as notifying appropriate mailing to

you must include a

Code

make lists

that

available thereafter

and

You

shall

shall take

or newsgroups) reasonably calculated

new knowledge has been

obtained.

Contributor APIs. If

Your Modification

is

an application programming

interface,

and You own or control

patents which are reasonably necessary to implement that API, you must also include this

information in the

LEGAL

file.

Dfen5ourc€ License Agreeitients

3.5.

Required Notices.

You must duplicate the notice

in Exhibit

A in each

file

of the Source Code, and

documentation for the Source Code, where You describe If You

Code.

created one or

file

ry

due

file)

to

its

structure, then

for,

Covered

as a Contributor to the

likely to

in a location (such as a relevant directo-

look for such a notice. You

may choose

warranty, support, indemnity or liability obligations to

to offer,

one or more

and

Developer or any Contributor. You must make

Initial

liability

obligation

offered by

is

it

liability

incurred by the

Contributor as a result of warranty, support, indemnity or 3.6.

Initial

absolutely clear than any such warranty, support,

You alone, and You hereby agree

Developer and every Contributor for any

to

recipients of

Covered Code. However, You may do so only on Your own behalf, and not on behalf of the

indemnity or

\i

not possible to put such notice in a particular Source Code

you must include such notice

where a user would be

charge a fee

is

License in any

recipients' rights relating to

more Modification (s), You may add your name

notice described in Exhibit A. If it

this

liability

to

Developer or such

Initial

terms You

indemnify the

offer.

Distribution of Executable Versions.

You may

distribute

Covered Code

in

Executable form only

have been met for that Covered Code, and

if

You include

the requirements of Section 3.1-3.5

if

a notice stating that the Source

Code

ver-

Covered Code is available under the terms of this License, including a description of how and where You have fulfilled the obligations of Section 3.2. The notice must be conspicuously sion of the

included in any notice in an Executable version, related documentation or collateral in which You describe recipients' rights relating to the Covered Code. You

of Covered Code under a license of Your choice, which License, provided that

You

are in

may

may

distribute the Executable version

contain terms different from

this

compliance with the terms of this License and that the license for

the Executable version does not attempt to limit or alter the recipient's rights in the Source

Code

version from the rights set forth in this License. If You distribute the Executable version under a different license

offered by

You must make

You alone, not by the

nify the Initial

it

absolutely clear that any terms which differ

Initial

Developer and every Contributor for any

or such Contributor as a result of any such terms You 3.7.

from

this

License are

Developer or any Contributor. You hereby agree to indemliability

incurred by the

Initial

Developer

offer.

Larger Works.

Work by combining Covered Code with other code not governed by the License and distribute the Larger Work as a single product. In such a case, You must

You may

create a Larger

terms of

this

make

sure the requirements of this License are fulfilled for the Covered Code.

Linux

PRDGRflmiYiiNG

CH-hiyi-e

td

h-.d. 1n-h-b1l1ty

Statute If

it is

o-r

Regulatidn

impossible for You to comply with any of the terms of this License with respect to

the Covered

Code due

License to the

to statute or regulation

maximum

all

then You must:

(a)

some or

in the

LEGAL file

all

of

comply with the terms of this

extent possible; and (b) describe the limitations and the code they

Such description must be included with

due to

coiyl-fly

affect.

described in Section 3.4 and must be included

distributions of the Source Code. Except to the extent prohibited by statute or regulation, such

description must be sufficiently detailed for a recipient of ordinary

&

fl-F-FLlC-RTlON O-F T-H15

This License applies to code to which the

Initial

skill

to

be able

to

understand

it.

LICENSE

Developer has attached the notice in Exhibit A, and to

related Covered Code.

G.D- Versions of the License 6.1.

New Versions. Netscape Communications Corporation ("Netscape") may publish revised and/or new versions of the License from time to time. Each version will be given a distinguishing version number.

6.2.

Effect of

New Versions.

Once Covered Code continue to use

it

has been published under a particular version of the License, You

under the terms of that version. You may

also

choose

to use

may

always

such Covered Code

under the terms of any subsequent version of the License published by Netscape.

No one

other

than Netscape has the right to modify the terms applicable to Covered Code created under

this

License. 6.3.

Derivative Works. If you create

to

or use a modified version of

code which

is

this

License (which you

not already Covered Code governed by

license so that the phrases "Mozilla," ingly similar phrase

"MOZILLAPL," "MOZPL,"

do not appear anywhere

in

may

this License),

your license and

only do in order to apply

you must

(a)

it

rename Your

"Netscape," "NPL," or any confus(b) otherwise

make

it

clear that

your version of the license contains terms that differ from the Mozilla Public License and Netscape Public License. (Filling in the notice described in Exhibit License.)

name

A shall

of the

Initial

Developer, Original

not of themselves be

deemed

to

Code or Contributor

be modifications of this

in the

O-fenSource License Rgreeiyients

7.D. DlBCLflllYlER

OF

UU-RR-R-RNTV

COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT THE INITIAL DEVELOPER OR ANT OTHER CONTRIBUTOR) ASSUME THE COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER

I

J

THIS DISCLAIMER.

B.D. TE-RFYllNflTiaN This License and the rights granted hereunder

terms herein and

fail

Code which

Provisions which, by their nature,

terminate automatically

if

You

fail

to

comply with

breach within 30 days of becoming aware of the breach. All

to cure such

censes to the Covered

will

subli-

are properly granted shall survive any termination of this License.

must remain

in effect

beyond the termination of this License

shall

survive.

B.D. LimiT-FmON O-F LURCILITY UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL THE INITIAL DE\TLOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO YOU OR ANT OTHER PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL, W ORK STOPPAGE, COMPLTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER COMMERCL\L DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING FROM SUCH PARTYS NEGLIGENCE TO THE EXTENT APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THAT EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU. r

7

L

Linux Gaiyie FRDGRfrnfimiNG

EBB

1

GDVERNIY1ENT END U5ER5

1D.D. U.5. The Covered Code sisting

a "commercial item," as that term

is

defined in 48 C.F.R. 2.101 (Oct. 1995), con-

is

of "commercial computer software" and "commercial computer software documentation," as

such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),

all

U.S.

Government End Users acquire Covered Code

with only those rights set forth herein.

mis

ii. d.

LLflNEDU

This License represents the complete agreement concerning subject matter hereof. this

License

make

to

it

is

any provision of

enforceable. This License shall be governed by California law provisions (except to the

extent applicable law, to disputes in in,

If

held to be unenforceable, such provision shall be reformed only to the extent necessary

which

if

any, provides otherwise), excluding

one party

at least

is

its

conflict-of-law provisions.

With respect

a citizen of, or an entity chartered or registered to

the United States of America: (a) unless otherwise agreed in writing,

all

do business

disputes relating to this

License (excepting any dispute relating to intellectual property rights) shall be subject to final and

binding arbitration, with the losing party paying this

Agreement

shall

all

costs of arbitration; (b)

any arbitration relating to

be held in Santa Clara County, California, under the auspices of

JAMS/EndDispute; and

(c)

any

litigation relating to this

Agreement

shall

be subject to the jurisdiction

of the Federal Courts of the Northern District of California, with venue lying in Santa Clara County, California, with the losing party responsible for costs, including without limitation, court costs

sonable attorneys fees and expenses.

The

application of the United Nations Convention

for the International Sale of

Goods

language of a contract

be construed against the drafter

shall

is

expressly excluded.

Except in cases where another Contributor has failed

damages

the

number of copies of Covered Code you made

ty

not apply to

arising, directly or indirectly,

and other

on an equitable

relevant factors.

basis.

to

comply with Section

You agree

available, the

to

on Contracts

this License.

CL-RirYlS 3.4,

out of Your utilization of rights under

for

rights,

shall

rea-

regulation which provides that the

R-E5HPaN51B1L1TY -FOR

12.

such

Any law or

and

You are responsible

this License,

based on

revenues you received from utilizing

work with affected

parties to distribute responsibili-

EXHIBIT

-H.

The contents of this

are subject to the Mozilla Public License Version 1.0 (the "License"); you

not use

this file

file

except in compliance with the License. You

may

may

obtain a copy of the License at

1

http://www.mozilla.org/MPL/ Software distributed under the License

ANY KIND, limitations

\

is

distributed

on an "AS

IS" basis,

WITHOUT WARRANTY OF

either express or implied. See the License for the specific language governing rights

and

d_

under the License.

The

Original

The

Initial

Code

is

Developer of the Original Code

Portions created by All Rights Reserved.

Contributor(s):

]

.

is

are Copyright

©

Linux Gaiyie FRaGRfiiniYiiNG

Version

m

1.1

Copyright

© 2000 The Apache

Redistribution

Jn

ed

QFTUiflRE Lichens

flFflCH

T+H-E

and use

Software Foundation. All rights reserved.

in source

and binary forms, with or without modification,

are permitted provid-

that the following conditions are met: 1.

Redistributions of source code must retain the above copyright notice, this

list

of conditions and

the following disclaimer. 2.

Redistributions in binary

form must reproduce the above copyright

and the following disclaimer

in the

notice, this

list

of conditions

documentation and/or other materials provided with the

distri-

bution. 3.

The end-user documentation included

with the redistribution,

if

any,

must include the following

acknowledgment: 'This product includes software developed by the (http: / /www.apache.org/ )

Alternately, this

Apache Software Foundation

.

acknowledgment may appear

in the software

itself, if

and wherever such

third-party

acknowledgments normally appear. 4.

The names "Apache" and "Apache products derived from

this software

Software Foundation" must not be used to endorse or promote

without prior written permission. For written permission,

please contact [email protected]. 5.

Products derived from

this software

may not be

called "Apache,"

nor may "Apache" appear

in their

name, without prior written permission of the Apache Software Foundation.

THIS SOFTWARE IS PROVIDED "AS IS," AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY WHETHER IN CONTRACT, STRICT LIABILITY OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANYWAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. This software consists of voluntary contributions Software Foundation. For

more information on

made by many the

individuals

on behalf of the Apache

Apache Software Foundation,

please see

http://www.apache.org/. Portions of this software are based

upon

public

domain

Center for Supercomputing Applications, University of

software originally written at the National Illinois,

Urbana-Champaign.

OfenSoukce License Agreeiyientb

License

IY11T Copyright

©

Permission

is

hereby granted, free of charge,

ated documentation

files

to

any person obtaining a copy of this software and

associ-

(the "Software"), to deal in the Software without restriction, including with-

out limitation the rights to use, copy, modify merge, publish, distribute, sublicense, and/or of the Software, and to permit persons to

whom

the Software

is

furnished to do

sell

so, subject to

copies

the

fol-

lowing conditions:

The above

copyright notice and this permission notice shall be included in

all

copies or substantial

portions of the Software.

PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

THE SOFTWARE

IS

Linux

Game

F-ROG-R-HmmiNG

m

\

t^

APPENDIX

B

Porting

55«Sfe

Linux Gaiyie -P-RDG-RflmmiNG

nl

ack in ,

ware

The Good Old Days™, games were platform

assembly language (or raw machine code

directly.

Porting a

game

to

if

specific.

rewrite. If you

original version

the graphics hardware was similar enough. You

wanted any

sort of

were

lucky,

you might be able

to steal

had

to

be platform

The



Abstracted hardware interfaces

make

much

porting games a

use of high-level languages

Although

calling

comparison

to

C and C++

"high-level languages"

might be a subject of debate, they

are currently the

predominant languages used

Regarding the second point,

it is

Even on the same platform, the ported

is

and the These

high

level in

least a

benefits, but

running

C and

for games.

simply not feasible to program directly to the hardware anymore.

variety of video, sound,

and I/O hardware

that

may have

to

be sup-

astronomical. So that responsibility must be delegated to the operating system, device drivers,

interfaces they provide.

facts

mean

However, there

that things are

is still

a lot

more

much

better than they used to be,

to porting

from a

platform capabilities ideal

game

still

portability point of view.

an application than simply recompiling

dards, closed formats, creative use of programming language features,

It is

are

assembly language. Most important, code written on one platform has at

chance of being compiled for another. Other languages could provide the same



specific if you

viable prospect:



The

the

performance. ,

C++

hit the hard-

some graphics data from

Since those days of nostalgia 1 two main advances have taken place that

more

write everything in

another platform usually meant throwing away the original code and

doing a complete if

You would

you were a Real Programmer) and

it.

Proprietary stan-

and fundamental differences

stand in your way.

for porting has the following characteristics:

well designed

and

cleanly structured. Clean code

is

much more portable than badly organized

code.

open standards and cross-platform

wherever possible.



It

uses



It

avoids platform or compiler-specific features.



It

has segregated any unavoidably platform-specific parts into separate

libraries

files.

in

PO-RTING

In contrast, the porting project •

It

from

hell has the following characteristics:

has code that looks like spaghetti. There

is

no

clear structure or separation of responsibility

IT

between modules. •

It

uses closed, proprietary standards

tains technologies •

It

uses a

and APIs wherever

possible.

covered by software patents and hefty license

programming language

that's available

For extra

credit, the

program con-

n

fees.

only on the original platform

or, failing this,

makes

CL

extensive use of platform-specific language extensions. •

It

contains masses of badly

This appendix is

is

be pretty

much

to

Linux because

this

The good news is that the capabilities of the basic hardware The bad news is that Windows games are rarely written with portability original code is of immense help here; good programming practices such as likely case.

identical.

mind. Well-structured abstraction

code.

somewhat biased toward porting an application from Windows

considered to be the most

will

commented assembly

and encapsulation inherently

aid portability, even

if

that

is

in

not the original motivation for

using these practices.

Porting Strategy Starting a port can

be a pretty daunting prospect. You have a bunch of source

files

written for an

incompatible platform, possibly written by you, possibly written by others, probably badly documented.

Where do you

start?

Try Not to Fork the Cddeease If you

misread the word fork in the tide of this section, don't worry. The meaning doesn't change

much. There

is

a lot to be gained by trying to maintain a single codebase. That

changes while keeping the original version working. by replacing old platform-specific bits with switching between the old

and new

new

It's

is,

to

make

the porting

often tempting to diverge from the original

platform-specific

bits.

Try to avoid this snafu by

versions using compile-time switches (#1 fdef s). Better

putting platform-neutral code in place instead.

still,

try

I

Linux Gaiyie FRDGKfiiYirmNG

Here are some of the •

Changes and



The

made on one

original version will benefit

refactoring, •

fixes

benefits of a shared codebase:

and general

You can debug using a



good

automatically be incorporated

from the scrutiny given

tidying will

tools

will

on the

to

on the other (s).

during the porting process. Bug

it

improve the entire codebase, not just the new

original platform.

Having extra debugging

fixing,

port.

tools available

is

always

thing.

The codebase work

If active

platform

as a

whole

will

become

easier to port to additional platforms.

continuing on the original version, take care not to cause unnecessary breakage during

is

the porting process. If possible, test your changes

on the

original platform as

source control systems provide some sort of branching mechanism to help

you go along. Most

manage multiple streams of

development. Potentially disruptive changes can be performed on a separate branch and merged into the

main branch when they are judged

to

be well tested and

Linux world, provides the required

features.

Of course, sometimes you won't be

able to share a codebase.

stable.

Of course, CVS,

widely used in the

Maybe the people in charge of the original version don't want you messing with their copy of the code, or maybe the platforms differ in such a radical way that a complete architectural rethink is required. Maybe the original codebase resides in a source control system without Linux support (Microsoft Sourcesafe, for example). In these cases, you

have to maintain a separate Linux source repository, treating the original repository as a third-party

package you have to

track.

Getting Started As with so many

random and going

to

be

things, the best

try to

compile

trivial little

it

approach

is

to just dive right in

from the command

things. Fix

line.

and

hacking away. Pick a

A large number of the

them. For bigger problems, use

chunks of code, making sure that you leave some

start

sort of TODO

#i f def to

comment

:

file at

resulting errors are

block out offending

or NEEDS_WORK marker that

you can use grep to locate for later on. Replace problem functions with stubs that do nothing. Leave the big issues for

Go

through

feel a sense

be able

all

later.

the

files in this

goal at the

moment is just

to get the project to compile. You'll If you're lucky, you'll also

to get successful linking.

want

to script

original version of the

one or more

up a makefile

game was

prietary project description

Linux.

The

of achievement wash over you as the compiler errors disappear.

You'll probably

taining

way.

files.

built using

(or

its

equivalent)

.

There

is

a strong likelihood that the

an IDE (Integrated Development Environment) using pro-

For example, the Visual

projects (described in .DSP

files).

C/C++ IDE

Of course,

uses workspaces

these are of

little

(

.

DSW

files)

con-

or no use under

2

.

#ifdef Is Vdu-r Friend The

#i fdef

statement

is

cool. There's a real temptation to just define a LINUX

macro and have

It

all

your

porting changes switched in with that. Instead, try to switch by feature availability and not by platform.

Because most of the features you'll use are available on multiple platforms, you'll have grained control over your build configuration than

if

much

finer-

you use a blanket switch-by-platform approach.

Here are some examples: •

If you

are using a cross-platform library to aid your porting effort, the original codebase can benefit

by having the extra configuration

available.

As an example, Windows

good Direct3D support. Porting Direct3D game code •

to

Linux using

NT doesn't

macro

have very

OpenGL gives you a Windows

NT version essentially for free. A lot of the system calls provided by Linux are part of the POSIX standard. in using a

(didn't?)

By switching these

calls

called POSIX (for example) rather than LINUX, you'll be better placed to port to

other POSIX-supporting platforms (the BSDs, for example). •

Even seemingly proprietary features can pop up

Win32 API implementations •

available for

in

odd

places.

Linux/UNIX, such

For example, there are a number of

as the

WINE

project.

Don't use a platform macro to switch in a compiler-specific feature. All compilers have predefined

macros

to let

you

identify

compiler available.

GCC

them, so use these macros instead. Visual

is

C/C++

is

not the only Windows

not the only Linux compiler available.

Here are some useful compiler-defined macros:

Macro

Meaning

_W I N 3

The Win32 API

_MSC_V E R

Compiling on Microsoft Visual C/C++.

T+H-E now

It's

tive

At

is

available (defined by Visual

GNUC

Compiling on GCC.

GNUG

Compiling on

GCC C++ compiler

C/C++)

(G++) Implies .

GNUC

.

Harder 5tu

time to

and stub

this point,

start

dealing with

all

the code you previously disabled using #i fdef preprocessor direc-

functions.

you may have identified places

which some refactoring of the original code would

where separation of platform-dependent code from platform-independent Additionally, for particularly convoluted modules, refactoring just to make the code

help. Try to identify areas

code makes sense.

in

Linux Gflm-E f'ROGKflmmiNG

understandable can be worthwhile.

the refactoring would be

Ideally,

you can keep the game mnning. This approach

that

lets

you

test

done on

the original platform so

your changes to make sure that your

changes haven't broken anything. Performing the changes on the target platform, where the game not yet in a running

Often sion, l

huge leap of faith. Untested code

requires a

is

almost always buggy code.

have to make a decision between porting or rewriting a module. This can be a hard deci-

you'll

and there

rule of

state,

is

thumb

is

is

no magic method

that

if

—except experience and

to help)

getting the existing code ported involves obfuscating

you are better off making sure that the interface

well defined, forking

is

A good

familiarity with the code. it

it off,

to

any major degree,

and

writing a

new

imple-

mentation.

F1-R5T L.1G-HT a magical

"First light" is

moment.

It is

the

first

time you run the newly ported

something recognizable up on the screen. Of course,

1

screenful of random garbage It's still

this

and a horrible catastrophic

is

game and

actually see

almost always immediately followed up by a

crash.

a memorable milestone.

Anyway, you're running Linux. Horrible catastrophic crashes are well behaved and easy to deal with, a nice example for the

UK national railway operator,

Railtrack,

may

like to follow.

CamFiLER Issues Although

it

took a long time to pin down, there

ing this standard accurately in a compiler

is

not

is

now an

trivial.

official

Pity the

C++

standard. However, implement-

poor compiler engineers; C++

is

a com-

plex language to implement. You'll be hard pressed to find a compiler that doesn't break or deviate

from the standard If

you are using

for a while

C

in

some

way.

The

rather than C++, the situation

and has had time

to settle.

and of course the compiler support At the time It

I

footpath of

am writing,

compiler-level

is

is

strewn with the dog-poo of standards violations.

a lot better.

still

a few

for these additions

Microsoft Visual

can be a pretty good compiler, but

behaviors that can trip

There are

C++

it is

up the porting

C/C++ seems somewhat

process.

It

is

new

The ANSI C standard features being

likely to

to

has been in place

added here and

there,

be patchy.

be the predominant compiler for Windows.

idiosyncratic.

also supports

It

contains a lot of not-quite-standard

some non-standard

features such as

COM support.

Ml

GCC

For Linux,

is,

of course,

the

compiler.

GCC has

bad C++ compiler. Recently, however, a

really

eration

and adherence

be made

GCC,

to

it's

lot

traditionally

been a

of effort has gone into

good C compiler but a improving GCC C++ code genpretty

I to standards.

now more

or

Although there are

less

certainly additional

improvements that could

on par with other C++ compilers. fl

The simple

C++ compilers have quirks you'll have to work around. Make sure that you keep your compilers up to date and try to keep track of release notes and bug lists. For GCC, fact

that

is

http://gcc.gnu.org

GCC The

is

current

all

the

site to

watch.

UPDATE INFORMATION! HTTF I//gCCiGNUiDRG

following sections describe

some of the compiler

differences you're likely to encounter.

Visual C/C++ Iiyifrdfer in

for Laa-ps

Visual

C++

co-fing

applies an incorrect scoping rule for variables declared in for statements such as the

following:

for(

int i=0;

i UL

PORTING

Many DOS extenders provide mechanisms to map the frame buffer into a single ry. The VESA interface also provides linear frame buffers on some hardware.

linear area of

memoIr

Games

using linear frame buffers correspond nicely to the display surfaces presented by most

graphics APIs and shouldn't cause too require a

using bank switching might

H

more reworking.

little

The hardware

many porting headaches. Code

modern

DOS also means

more esoteric hardware features could be used. Probably the most (in) famous example is ModeX, in which each byte accesses four pixels. A latch register sets which of those four pixels is affected. The benefit of ModeX was that it allowed you to squeeze multiple frames into a single 64K memory window, which in turn opened up the option of hardware page flipping and smooth scrolling techniques. ModeX code will definitely require some porting work. access

under

that

DirectSD Access to accelerated

3D hardware

ing this code to Linux If

is

in

DirectX

to rewrite the

is

3D code

provided by Direct3D. The only real option when portusing

OpenGL.

the original code was well designed, the incidence of Direct3D

help a

lot.

Many games

may be

quite localized, which will

use an API-neutral high-level layer to deal with aspects such as object geometry,

spatial partitioning, culling,

and

so on. This layer

is

built

on top of an

API-specific low-level back

end

that actually pushes polygons out to the video card. If you provide a replacement low-level layer, the rest

of the code

Then

will

be happy.

again, there's a reasonable

Direct3D API

is

exposed

in

chance that the original code was badly written and that the raw

code and data structures

all

over the place. In this case, you'll probably just

have to rewrite the whole shebang. Joy.

Because Direct3D and

OpenGL are

both trying to expose the same

set

of hardware features, there



is

some degree of agreement between the two APIs they both encapsulate the same recent versions of the Direct3D API have been moving noticeably toward the style of interface provided by OpenGL. This is a really Good Thing, and will make your porting task easier.

The

following sections address

Direct3D API.

some of the

differences

concepts. Indeed,

and

similarities

between

OpenGL and

the

Linux GfimE -PRDC5«flrYimiNG

CDDRDlNflTE BY5TEIYI5 1

OpenGL uses a right-handed coordinate system while Direct3D uses a left-handed system. However, the OpenGL ModelView matrix can be fudged to produce a left-handed system by scaling Z by -1. The fol-

n

lowing example takes the existing Direct3D coordinate system and, by simply applying the function, transforms

it

into an

OpenGL

glMatrixMode( GL_MODELVIEW gl

Loadldenti ty(

Seal e(

system:

);

)

want left-handed coordinate system

// gl

gl

Seal ef

1.0,

(

1.0.

-1.0

);

now transform as usual...

//

Polygon Winding Direct3D identifies front-facing polygons as polygons that have their vertices In

OpenGL,

the default assumption

order. This behavior can

void glFrontFace( In this syntax, mode

Texture Textures in rest

is

is

that front-facing polygons are defined in counter-clockwise

is

be changed using glFrontFaceO:

GLenum mode

)

GL_CW for clockwise and GL_CCW for counter-clockwise.

[Yl-nN-RGemeNT

OpenGL are very opaque

objects.

handled for you. You don't have

to

Once

you've created a texture and passed

potentially hardware-specific operations. earlier versions of

it

in,

the

memory requirements or out from system memory or any other

worry about juggling video

using the transfer mechanisms to shuffle texture data

The

listed in clockwise order.

These things are

left

up

to the driver.

Direct3D assumed that the programmer would require complete control of tex-



management details essentially, each application could provide its own custom texture management. Although more recent versions of Direct3D provide automatic texture management in a style similar to OpenGL, porting code written using the older systems could pose some challenges. ture

DfenGL At

first

glance,

-Extensions

you may think Direct3D has some features that are missing from OpenGL. In

of these features are actually provided as tions or

new enumerants

whether the

one

go.

to existing functions.

OpenGL driver

A good example

is

OpenGL extensions.

fact,

most

Extensions take the form of new func-

A runtime query must be performed to

determine

supports the required extensions.

multitexturing, in which the hardware can perform multiple rendering passes in

Most consumer 3D cards these days have

this capability. In

OpenGL,

multitexturing

is

exposed

with the ARB_multi texture extension. In general,

if

Direct3D provides a hardware feature that

tion, there will

be an

The OpenGL Web

Of course,

OpenGL

site at

extension to support

is

missing from the base

QUND

specifica-

http://www.opengl.org maintains up-to-date information about extensions.

latest

and

greatest chipset.

U

1

Unless the original sound code was written using a cross-platform rewrite for these sections of the original

game. The good news

encapsulated. Most games have a very well-defined set a music track, change the volume, face seen by the rest of the

game

and

so on. Porting the

to

that

be looking

sound code

is

at a

sound code

is

complete

usually quite well effect, start

a matter of retaining the inter-

while replacing the implementation.

around managing sound buffers containing waveform Linux approach

is

.API, you'll

of sound requirements: play a sound

DirectX provides audio support through the DirectSound API.

centric

OpenGL

it.

the hardware manufacturers themselves usually have extension information available to

encourage you to support the new features on their

It's

quite a low-level interface, centered

data. This contrasts

somewhat with the

audio generation, which involves streaming waveform data out to

file-

an

audio device.

Networking Issues LUlNSOCH The Winsock API provides a Windows implementation some quirks that can make porting tricky.

r

of the familiar

BSD

sockets library. But

it

has

n

Linux G-nm-E FRDGRfHYimiNG

and Socket -Handles

File ra

The

"everything-is-a-file"

approach of UNIX means that

Windows tends not

interchangeable.

to allow

you

file

handles and socket handles are usually

Where UNIX

to treat sockets as files.

file

and socket

handles are usually just integers, Winsock defines the data type SOCKET to represent socket handles.

Where

a

UNIX program

might use read

use the socket-specific recv(

Winsock

is

)

)

also

work

in

socket, the

Fortunately, this difference

)).

Windows falls

in

equivalent has to

your favor because

UNIX.

-Files

included in your code using winsock.

now seems

2 of the Winsock API, which ious include

from a

to pull data in

(or WSARecvEx(

)

socket-specific calls such as recv(

Include

(

files,

to

h

orwinsock2.h. The winsock2.h header

be more or

less

standard.

BSD

sockets

on

for version

is

UNIX require var-

depending on the features being used.

Return Codes Although Winsock and tions are

BSD

communicated

sockets share a similar basic set of error conditions, the

differs.

Most socket

returns S0CKET_ERR0R instead of the

more

denote a bogus socket handle value where

The Winsock header point of view,

naming If

is

is

also

1 )

.

BSD

to indicate success.

socket calls again use

define S0CKET_ERR0R as

So Winsock

return a

does, in fact,

-1

On failure, Winsock

Winsock uses INVALID_SOCKET -

to

1.

and NVALI D_S0CKET I

as ~0 (which,

use the same return codes as

BSD

from a

sockets,

bitwise

but the

different.

an error occurs,

recover? Should calls.

-

files

calls

traditional -1. Additionally,

way those condi-

I

you'll often

panic yet?"

need

BSD

to

know more: "What

)

What happened? Can

I

sockets use the standard errno variable used by other file-handling

As a consequence of Winsock sockets not being

WSAGetLastError(

type of error?

provides the same functionality.

real file handles, errno doesn't work. Instead,

The codes returned

are pretty

much

the

same

set as those used by errno, except that they have been given a WSA prefix. For example, WSAECONNRESET

corresponds directly to ECONNRESET.



Different Calls Winsock provides most of the standard

present in

calls

BSD

sockets.

Most of these

calls also

have one

Ir

or more Winsock-specific versions. Sometimes, the Winsock versions provide significant extra functionality;

other

WSARecvEx(

calls )

appear

be present merely for the sake of consistency. For example, recv(

to

are almost identical, but select

(

WSAAsyncSelect(

),

),

and WSAEventSelect(

)

)

all

n

and work

dif-

ferently.

Some

differences between

Winsock and BSD sockets are a consequence of the

of Winsock sockets. We've already seen the way that the

WSAGetLastError(

BSD

non-file handle aspect

errno functionality

is

provided by

Following are some other examples of the differences between Winsock and

).

BSD

sockets: •

The

BSD-style c 1 o s e (

)

the Microsoft

call in

C

runtime library won't work with Winsock sockets.

Sockets should instead be closed using the cl osesocket( •

Winsock provides ioctlsocketO

DirectFlay Some Windows games nents, DirectPlay

is

to replace the

BSD

)

call.

ioctl

(

)

call.

Is -Evil

use DirectPlay for their network requirements. Like

a proprietary API. This wouldn't be too bad

all

the DirectX

—you can always port

to

compo-

another API

except that DirectPlay also imposes a proprietary network protocol. This means that the people playing

your Linux port

not be able to play with people running the Windows version of the game.

will

bad situation, and unless the protocol engineering

skills!),

is

you're out of luck.

The

players not to support DirectPlay unless

DirectPlay

u The

is

a prime

opened up by Microsoft

it is

best

you can do

is

to

It's

freed by Microsoft.

example of why proprietary protocols are a Bad Thing™.

ul Link Mozilla project has a

you'll

want

to pick

good

section

on portable coding

and choose from the advice

in C++. It

given:

http://www.mozi! la.org/hacking/portable-cpp.html

a

someone with good reversepersuade programmers and game (or by

is

pretty comprehensive,

and

Linux Gaiyie FRDGRflmmiNG

Wilfredo Sanchez of Apple has written a paper documenting some of the issues facing the develop-

1

ment of OSX. His paper is an interesting read, and many of the same facing OSX crop up when you're porting games to Linux: 'The Challenges of Integrating the

n

of issues (and solutions)

Environments"

http://www.mit.edu/people/wsanchez/papers/USENIX_2000/

DJGPP, a

jd

UNIX and Mac OS

sorts

guage

DOS port of GCC,

has an

FAQ that contains some

information on dealing with assembly lan-

syntax:

DJGPP FAQ,

section 17.2: "Converting

Between

Intel

ASM

Syntax and

AT&T Syntax"

http: //www. del orie.com/djgpp/v2faq/ index. html

For porting sockets code:

Winsock Programmers

FAQ

http://www.cyberport.com/~tangent/programming/winsock/

UNIX Socket FAQ http://www.lcg.org/sock-faq/

A D3D/OpenGL feature

comparison:

http://www.xmission.com/~legal ize/d3d-vs-opengl .html

The

NASM home

page:

http://www.web-sites.co.uk/nasm

DTNDTEB ain't

what

1

It

2.

Any

3.

"Once you

flavor

it

you

used

\

to be.

like.

start

down

the dark path, forever will

it

dominate your

destiny.

Consume

you,

it

will!"

_,

i

f

lTI^T

APPENDIX C N

2^

Linux Gaiyie FRDGKfiiYimiNG

1

Jl

my friends,

all good things must come to an end, and here it is. Before development, I'll give you some tips: Read the Web sites game ^^^J and buy the books listed in this section. They have helped me, and I'm sure they'll help you in your quest to be the next big thing in the game development community.

I

ell, 1

leave

you

it's

to the

been fun. But

chaos that

is

uu In the big white world of the Internet, there are literally millions of Web sites dedicated to helping

game

developers.

Some

are good, most aren't, but here are

some of the more

useful resources online.

GflIYl€D£ViN€T +HTTf»://uuujuj.GflmeDev.NeT Probably the best resource for amateur developers (even the guys

CMP group]

agree with

me on

this

one)

,

this site features

who own

someone new

to

game programming

Web

needs. Also

on

mail system so that people

offer will

GamaSutra

site

[the

everything from daily news to references and

message boards. Created by amateur developers for amateur developers,

gdnmail.com), a free

the

is

the

GDNet

know you're

a

this site

contains everything

mail service (http://www.

game programmer.

G-hfyi-rSut-r-r +HTTfS//uJUJUJ.GflmflSUTRfliCOm This

site is

well

funded with support and regular

development. The

site

articles

from some of the biggest names

features regular post-mortems of hit games, industry opinions,

board that draws some of the best developers out there.

It's

definitely

worth a look

(if

in

game

and a message you have a

fast

Internet connection).

FLIf^COD-E HTTf!//uJUJUJiiFLlf,CaDE.CarY1

Although Flipcode esque

many

services to the

game development community,

it

does draw a slashdot-

community as well. But don't let that put you off because this site features some advanced and various other things worth searching for. Flipcode is part of the FutureGaming network.

troll

articles

offers

.

Penguin

H-n-p-FY

HTTP'//HflFPYPeNGUlNiaRG This

site offers

Linux game development news and resources. The

game known

every Linux

to exist (and

also has links to how-to articles

on

it

site

includes links to just about

generates plenty of references to SourceForge).

getting various

games (such

as Starcraft)

The

working under

site

WTNE c_

(http://winehq.org)

J

NETWORK

lNDREIYlfl DEVELO-FE-R HTTP //lON.lNDKeiYlfi.COnn This

site is

Although

upcoming Linux-based console, the L600. consists of more mailing lists than you can shake

the gateway to the developer's side of the

this site

is

a touch

on the slow

pointy' stick at. It's the perfect

gramming and has

side,

it

resource for anyone

who wants

to

a big

break into the world of console pro-

regular input from the Indrema executives.

Linux GflmEB http '//LiNuxGflmes. com I'm not sure what part thinks

Linux and

is.

Part of me

is

convinced

it's

a

site

aimed

at developers,

while the other

good mix of the two sides of game development definitely worth a look (even if the administrators do post e-mails there without the

it's is

this site

more of a gamer's

site. It

offers a

for

author's permission :/).

Linux G-nmE Developer

Resdur

nt-re HTTP !//5UN51Te.flUCiDK/l_GDC Hosted on one of the most powerful offers a brilliant collection of links

Web

and

server networks out there (the Sunsite network), the

articles, as well as

Linux community. Just about everyone who mailing

list

is

anyone

occasional interviews with big

in the

(which has been victim to the occasional mail

worth a look.

in the

Linux games community subscribes

bomb

resulting

mail account being deleted *nervous grin*), although the message site is definitely

names

LGDC

from what may

traffic is

kinda

to the

have been

slow. Overall, this

my

Linux G-rm-e P-ROG-R-HmnmNG

Edoke 11

No n

library

shelves.

is

complete without any books;

To help you

gramming,

some other

OfenGL A must for any 3D

it's

this

the

OpenGL newbie

pages.

The

this

it

some empty

with

-Red -Book)

book or has had

(T+he

doesn't contain

it

to

much

mapping.

to him.

Blue Book)

fast printer.

in the

bump

recommended

only reason for buying this book

to the system help and don't have a

G-R-R-F-H1C5 By Michael Abrash

OpenGL man

because

room

book covers everything from transformations

DfenGL Reference of the

a

useful guides to the various aspects of game pro-

Su-f-e-r -Bible (T-he

programmer,

hardcopy references

library. It's just

references.

Anyone who has done 3D programming has read

A printed version

not even a

some

those shelves, here are

fill

as well as

hell,

don't

I

is if

you prefer

recommend

this tide for

way of tutorials.

FRDGRflnHYIlNG fiL-HCK

EOOK

(Coriolis)

ISBN 1-56710-174-6 This

is

the graphics programmer's bible. In addition to amusing anecdotes of Abrash 's

covers everything from anti-aliasing to to-the-metal optimization techniques. Although effort to apply the assembly

code

in this

a very handy reference to have, but

probably the ultimate

it's

book

to

for,

book

requires ,

some

it's still

however, because

it is

reference.

GflfYlE -H-RC-HITECTU-R By Andrew Rollings and Dave Morris

it

this

Linux systems (which uses a different syntax)

not cheap. You do get what you pay

game programmer's

life,

and Design

(Coriolis)

ISBN 1-56710425-7 This book covers every aspect of game design, from team assignments to interface planning.

must

for any



team leader/lead programmer

—because

into the industry

Although less a

I

good

it

gives helpful tips

personally disagree with read,

and

it

was written

as well as a useful guide for

and case

studies of the

It is

anyone who wants

way things work on the

to

a

break

inside.

some of the business models contained in this title, it is nonetheby two people with a long career in the game industry.

R€FER€NC€5

TCF/lF Illustrated

(Vdluiyie 2) Ir

By Richard W. Stevens Written by the late

—with

calls

full

TCP/IP networking

source code

guru, this book (the second of three) covers

—that you could ever need

if

you decide

to

all

the network

do any heavy network coding.

Linux Device Drivers By Alessandro Rubini

ISBN

1-56592-292-1

If you

want

to

do

(O'Reilly)

low-level stuff

tizes tasks is essential.

just diving into the kernel

is

for the things that can help

book

offers

some

under Linux, understanding how the kernel works and how

This book

useful tips

will

help you find out

one useful approach,

this

how

things are

book

gives

it

priori-

done under the hood. Although

you some guidance on where

to look

you squeeze every ounce of performance out of your code. In addition, the

on

writing your

own modules

GfimE Develqpiyient

(if

you ever

feel masochistic).

E

Various Authors (Prima Publishing)

ISBN

(various)

The book you Although

this

are holding is

is just

one of a growing

the only Linux-specific

book

series

of game development books from Prima.

in the series to date, the series covers other topics includ-

ing isometric programming (written by Ernest Pazera, a good friend of mine from GameDev.Net) and

dedicated

OpenGL books. The

(but then, I'm biased;

I

series

is

a

must for any game programmer, amateur, or professional

get paid royalties).

Linux G-nrne -P-RaG-RAmmiNG

Pfl-RGflZlN-ES 1 There are a few good game development magazines Jl

crowd

like a sore

thumb on

in the world,

but those that are stand out from the

Viagra.

Developer M-hg-hzine

GflinE

«TTf://uiUJWiGDrYlflGiCOm

From

the

same people who brought you GamaSutra comes Game Developer Magazine. (They gave

free T-shirt at

version of the

me

a



ECTS that's how you buy my support: Clothes.) This magazine is pretty much a paper Web site, filled to the brim with useful techniques and trade news. Free to professional

developers in the United States.

Develop The

UK version of Game Developer Magazine, Develop was rereleased in November after being bought by

the people

who

print

MCV. Free

to professional developers in the

United Kingdom.

-Edge HTTf '//uJUJUJ.FLJTLJR-ENeTiCOIYl Printed by Future Publishing (based in is

more

suited to

gamers with an

my hometown

interest in the

extensive job section as well as articles

from

month because

be

up

to every

White).

he's sure to

of Bath in the United Kingdom),

development

professionals.

in every

side of things, although

You can

also find out

it

this

magazine

does feature an

what Peter Molyneux

magazine somewhere (instead of finishing Black

is

&

Neuus-f-rre-rs \>

Where would we be without updates on

the industry? As well as the Web,

issue press releases to the traditional press before

making the information

newspapers sometimes have the news before the Net, and are state

vital

available to

prefer to

Web

sites.

resources for keeping an eye

These

on the

of the industry.

Coiyifuter C7Wis

filled to

Trade UIeehly

the brim with industry news, ranging from

should be placing on the shelves. is

many companies

If

who

hired

who

to

what games

retailers

you're into the business side of game development, this newspaper

definitely for you. Free for developers in the

United Kingdom.

IYICV MCVis

filled to

the brim with industry news, ranging from

should be placing on the shelves. is

If you're into

definitely for you. Free for developers in

who

hired

whom

to

what games

c retailers

the business side of game development, this newspaper

the United Kingdom, (deja-vu?)

CamF'UT-E-R LUee-kly Computer Weekly sionals,

it

is

a weekly publication for the entire IT industry, not just games. Free to U.K, IT profes-

has a decent job section covering both U.K. and international positions, with the occasional

games-related job sneaking

in.

Cdiyifuting Like Computer Weekly, Computing magazine

you up-to-date on

is

not

strictly

aimed

at the

the current state of the IT industry as a whole.

only newspaper in the United

Kingdom

to feature a Dilbert.

comic

It

games

industry, but

it

does keep

has the added bonus of being the

strip every

week.

Linux G-nm-E P-ROG-R-RmnniNG

NEUI5GROU li

The

best newsgroups are usually contained within the rec.games.*

that

many people

prefer mailing

interested in finding out

many

lists

to

and comp.games.* groups. Note

newsgroups because of the lack of spambots there.

what the enemy

is

working on, a useful group

games

things about just about every aspect of the

is

If

you're

ms.directx.*, which discusses

industry.

m-RiLiNG Lists The obvious mailing list

list

you should belong

to

the

is

LGDC mailing list

tends to be very quiet at times and very busy at others (especially

er starts flooding

when my ex-employer's

mail serv-

it)

Indrema and CollabNET

also

run a few Indrema-related

Indrema-specific certification discussions to a

on common

(http://sunsite.auc.dk). This

ideas.

You can subscribe

to all

list

lists

for various subjects, ranging

from the

for getting groups of developers together for

of these

lists

at the

IDN Web

site

working

(http://idn.indrema.com).

v

1-"

Ji__r^

JTf:

T-J

APPENDIX D

GLQ55flRY

-J"!

1

L

p

Linux

ALSA

Game

-PRDcsKflmnmNcs

(Advanced Linux Sound Architecture).

A set of sound drivers for Linux that supports OSS emu-

lation.

A multimedia operating system.

BeOs.

Blender.

A version

BSD.

BSD

A freeware 3D

Sockets.

Client. client

visualization package; the latest version includes a

of UNIX distributed under the

BSD

game

engine.

license.

A TCP/IP programming API.

A program that connects to

a server.

A game running under X Windows is an

example of a

program.

The

Console,

a)

Copyleft.

An

tion.

modeling and

text

mode

interface

on Linux,

b)

alternative to traditional copyright.

A home entertainment system.

It is

associated with lower restrictions

on

redistribu-

Also a vendor of Linux T-shirts and other related merchandise.

CVS (Concurrency Versioning System). A system

Debian

HURD. A UNIX-like

that enables users to share

and

edit source.

system, similar to Linux, which uses a modularized microkernel instead of

a monolithic kernel.

DRM

(Digital Rights

Management).

A system

designed to prevent software piracy on the Indrema L600

console.

DV Linux. A special

distribution of

dard Linux box running

DV Linux.

Linux designed

to

make

sure that

Indrema games run on a

stan-

r Eric S.

Raymond. Founder of OpenSource.org and acknowledged guru of the OpenSource movement. n

Free Software Foundation.

An

organization to promote the use of free software (specifically the

GNU

licenses).

FreeBSD.

See

Freshmeat.

BSD.

A directory of software for Linux,

GameDev.Net. An online reference

for

located at http://www.freshmeat.net.

game developers of all

levels,

located at

http://www.gamedev.net.

GDNet.

See

GameDev.Net.

GNU Public License. The most widely used OpenSource license.

Commonly

referred to as the GPL.

H HSR

(Hidden Surface Removal).

A technique used in 3D graphics to work out what needs to be

drawn.

HUD.

Heads-up

display.

1

EDN (Indrema Developer Network). A resource ed

at

for people interested in

Indrema development,

http://idn.indrema.com.

IES (Indrema Entertainment Systems). Creators of the Linux-powered L600 console. Indrema.

See IES.

locat-

Linux

Game

PROGRfliYiiYiiNG

i Joystick.

A type of input, frequently used for games.

f

K Kernel.

The core of an operating

system.

The

kernel controls access to the hardware.

i

Lesser

GNU Public License. An OpenSource license designed for use with libraries.

Linux.

A free

PCs and

:

LOD

servers worldwide.

(Level of Detail).

object Loki.

OpenSource operating system

is,

It is

originally created in 1991.

Linux

is

used on millions of

the "official" operating system of China.

A technique

in

3D

graphics similar to MlP-mapping.

The

further away an

the lower the quality.

A company that makes a living porting commercial games to Linux.

m Minix.

A free UNIX operating system

MlP-mapping.

A technique

to

on which Linux was

initially

based.

keep the quality of a scaled image high. Instead of scaling the image,

you "render" different versions of it

at different sizes.

MMORPG (Massively Multiplayer Online Role Play Game). A large multiplayer environment played over the Internet.

N Neverwinter Nights.

An upcoming

MMORPG from the creators of Baldours Gate. This game will be avail-

able for various platforms, including Linux

and BeOS.

OpenAL (OpenSource Audio

Library).

An OpenGL-based sound API

by Loki.

OpenBSD. 5^ BSD.

OpenGL. A 3D

Pi

graphics API originally created by SGI.

It is

available for just

about every operating

sys-

tem going.

c_

OpenLobby. An OpenSource lobbying API OpenSource.

and

A software

distribution

that encourages the sharing of source code, knowledge,

skills.

OSS (Open Sound System). A sound

Pretty Poly.

Quake.

The

under the

driver for Linux.

An OpenSource modeling

first

package.

next-generation, 3D, first-person, shoot-em-up game. Quake

is

now OpenSourced

GNU Public License.

Richard M. Stallman. Founder of the

SDL

model

for games.

(Simple DirectMedia Layer).

GNU Project and head of the Free Software Foundation.

A DirectX-like API

that runs

on

various platforms, including Linux,

BeOS, and Win32. Server.

A program

SourceForge.

An

to

which a

client connects.

server

is

an example of a

online source repository for OpenSource projects, located at

http://www.sourceforge.net.

SVGAlib.

An X Windows

A console graphics library.

server.

TCP Ji

(Transport Control Protocol).

A subset of TCP/IP.

TCP/IP. The protocol used on the Internet

as well as

on most networks on the

planet.

Tux. The accepted Linux penguin mascot created by Larry Ewing.

u UDP

(User Datagram Protocol).

A subset of TCP/IP.

LAJ Win32. The Windows

9x/NT/2k/ME programming

WINE (WINE Is Not an Emulator). A program

library.

that emulates the

Win32 API

for Linux. Several

games

can run under WINE. For more information, see http://www.winehq.org.

X Consortium. The group that defines the X Windowing protocol. X Windowing System. A distributed user interface system, commonly referred to as X. Xbox. The new console being produced by Microsoft;

An OpenSource

XFree86.

x86

series

implementation of the

it is

due

for release in the third quarter of 2001.

X Windowing protocol.

of processors, XFree86 has been ported to other platforms.

Originally intended for the i

i

I

-

I

„£

P

]T

r J

APPENDIX

*—

E

ON T+H CD-RDIY1

UJ-H-RT'5

Linux Gaiyie FRDGRfimrmNG

n

The CD-ROM SDL, OpenAL, IESDK, that

accompanies

this

able) for

Kernel versions 2.2.18,

2.4.0,

and

2.4.1.

book contains both

PrettyPoly,

binaries

and source code (when

Mesa3D, SVGAlib, and source code only

The CD-ROM

also has all the

sample

files

for

avail-

Linux

that the author used

throughout the book.

Running

t-h-e

CD—RDfYl

UU1T-H

as/aa/Ennn/NT

To make

the

CD

CD. This means install.

user-friendly

and take

less

of your disk space, no installation

that the only files transferred to your

You can run the

can be installed on

all

CD on

Insert the

Go

3.

Most of the

to

is

required to view the

hard disk are the ones you choose

any operating system that can view

files;

however, not

all

to

copy or

the programs

operating systems.

CD into the CD-ROM drive and close the tray. My Computer or Windows Explorer and double-click

1

2.

LUlNDOWl

files

contained on the

CD

Running the CD

the

CD-ROM

drive.

can be viewed with WINZIP.

uiit-h

Linux

To make the CD user-friendly and take less of your disk space, no installation is required to view the CD. This means that the only files transferred to your hard disk are the ones you choose to copy or install. You can run the CD on any operating system that can view files; however, not all the programs can be installed on all operating systems.

CD

1

Insert the

2.

Either

make

from a

shell

3.

Change

4.

Most of the ing

into the

sure that

automount

is

close the tray.

running, or

mount

the

CD

by issuing the

mount command

prompt.

to the root directory files

of the CD, usually /mnt/cdrom.

contained on the

commands:

gunzip filename tar

CD-ROM drive and

-xvf filename

CD will

need

to

be uncompressed and un-tarred with the follow-

-

1

f

lT-U-lT

In

^A

Linux Gflm-E FRDGRflimnmNG

i 8-bit color,

36

lobbies, 188

color maps, installing, 48-49

n

OpenGL, 88-89

16-bit color,

36

scene graph, 134-138

24-bit color,

36-37

SDL, 20-21, 30-40

32-bit color,

37-38

SVGAlib, 49-57

command line switch, 14 -I command line switch, 15 -L command line switch, 14-15 -O command line switch, 14 -W command line switch, 14 -D

Xlib,

40-49

applications,

compared

arguments. See attrlist,

to

also flags;

games, 2

parameters

149

background, 41-42

41^2

border,

border_width, 41-42 accept(

)

colors,

function, 181

addresses, determining pixel location, 38-39

display,

addressing modes, 288

dst,

pname, 150

genetic algorithms, 212

SDL, 30-31

grouping, 205

src,

memes, 213 trees,

223

example, 209-212

alListenerfV(

Alpha

)

)

function, 148-149

SeeAl

set,

61

argument, 149

audio. See sound

axes (joysticks) 62 ,

information about, retrieving, 79-80

function, 150

alutBufferAndConvert_LOKI( light,

scancode

function, 152

B

testing, 7

ambient

AT

attrlist

route finding, 198-203

alGenSourcefv(

Artificial Intelligence.

documents, 6

assembly language issues (porting), 286-287

problem solving techniques, 206-207

)

35

art specification, design

Nurgle method (route finding), 203-204

alcCreateContextf

35

srcrect,

207-208

neural networks, 219-223

tic-tac-toe

151

parent, 41-42

Genebot, 213-219

personality,

35

dummy,

(Artificial Intelligence)

min-max

41-42

35

dstrect,

adventure games, 4

AI

39

)

function, 151

106

background argument, 41-42 benchmarking, technical specification, 6

animation (OpenGL), 96-102

Beta

APIs (Application Programming Interfaces)

billboards, rotating,

testing, 7

126-128

bind(

)

function, 180-181

color

bitmaps, drawing to screen, 35-36

8-bit,

books, 302-303

16-bit,

36

border argument, 41-42

24-bit,

36-37

border_width argument, 41-42

32-bit,

37-38

bounding boxes, 134

blending, 105

breakpoints, setting, 16

GL_COLOR_MATERIAL

buffer overflows, 196

memory', allocating, 39-40

buffering,

3D

graphics, 90

buffers

36

files,

loading into, 151-152

streaming (sound), 158-159 bugs. See also debugging; security; testing

1

OpenGL drawing, palettes,

sound

f

option, 105

96

39-40

screen, setting with

OpenGL, 92

transparent, drawing (SVGAlib), 55

color maps, 8-bit color, 48-49 color palettes, SVGAlib, 56-57

testing and, 7

[color] Pixel (

)

function, 43

colors argument, 39

camera, moving, 101-102, 138-139

-I

audio accessing hardware, 165 playing,

line switches

-D (multiple platform architecture), 14

card games, 4

CD

command

-L (libraries), 14-15

-O (optimization), 14

167-168

track listings, 166-167 certification (Indrema),

(includes), 15

236-238

-W

(warning

commands,

levels),

display

14

lists

118-119 chatting, lobbies,

193-195

cheat codes, debugging and, 7-8

commercial games, releasing, 9-10 compilers, 12-15

client-server networking, 171 clients,

threads and, 183-186

porting, 278-282

compiling code. See also cheat codes

debugging code, adding, 8 debugging, adding, 8 forking

game

when

porting, 275-276

loop, 26-27

filenames and, 13

GCC, 12-15 multiple

makefiles, 27-28 startup

and shutdown framework, 24-26

files,

13

OpenGL, 93 optimization, 14

void * type (messages), 26 collisions,

129

shapes, simplifying, 130

surface contours, following, 132 testing for, 130-131

warning

levels, setting,

14

Computer Trade Weekly newspaper, 305 Computer Weekly newspaper, 305

Computing magazine, 305 configuring control system, 84-85

connect(

)

function, 173-174

Linux Gaiyie FRDGRflinmiNG

coordinates,

OpenGL default system,

96

documents, 6

disclaimers, design

display argument, 41-42

copyrights, design documents, 6 crashes, terminating games, importance of, 24

DISPLAY environment variable, 41-42

cross product, 125

display

cubes, drawing, 122-124

DJGPPFAQWeb site,

custom

Doppler

240

licenses,

lists,

118-119

shift,

DOS frame buffer,

cut-scenes, art specification, 6

298

156-157 293

dot product, 125

double buffering

command line switch, 14 D3D/OpenGL comparison Web

SDL, 33

-D

DDD

site,

Xlib,

298

drawing

(debugger), 15-18

collision detection, simplifying shapes,

toolbox, 16-18

Web

2D

15

site,

47-48

objects, presenting as

mathematics and, 124-126

dead reckoning, 187

matrices, 122-124

debugging. See

also bugs; testing

modeling, 132-133

breakpoints, setting, 16

OpenGL, 93-102

cheat codes and, 7-8

orthographic, 100-101

DDD, 15-18

particles,

optimization and, 14

PLIB/SSG

variable values, retrieving, 16

PCX files,

DefaultScreen (

)

98-100

(scene graph API), 135-138

smoke, 129

53

text,

function, 41-42

DefaultScreenOfDisplayf

129

perspective,

symbols, adding, 16

decoding

130

3D, 126-128

)

function, 41-42

triangle strips

denial-of-service attacks, 196 dst

design documents, 6

121-122

texture, 105

and

fans,

120-121

argument, 35

dstrect argument, 35

Develop magazine, 304

dummy argument,

development, 7

151

compilers, 12-15

design documents, 6

Edge magazine, 304

KDevelop, 18-20 libraries,

emissive light, 106

20-21

multiple platforms, 14 releasing, testing,

8-10

environment errors,

variables,

SDL_Get£rror(

DISPLAY, 41-42 )

function, 30

event handling, 69-74. See

7-8

also

78-82

diffuse light, 106

joystick (SDL),

Direct3D, porting issues, 293-295

keyboard (SDL), 68-76

DirectDraw, porting issues, 292

mouse (SDL), 76-78

DirectPlay, porting issues,

297

Unicode

field,

75-76

SDLJEvent union

event queues, 62-63

bind(), 180-181

event types (SDL), 65

[Color]Pixel(),43

HandleEvents(

connect(

function, 67

)

78-82

joystick,

173-174

),

DefaultScreen(

41-42

),

keyboard, 68-76

DefaultScreenOfDisplay(

mouse, 76-78

free(),40

reading from, 64—67

gameloop(

SDL_Event union, 63

),

41-42

26-27

),

GetMessage(), 24-26

glBegin(),96 glCallList(

FIFO file

(First In, First

Out)

arrays. See event

queues

glColor3f(),96

PCX, 52-55

XPM files,

glDeleteLists(),118

45

Web

file

formats

file

systems, 283

site,

glDisable(),92, 102

35

glEnable( ),92, 102

glEnd( ),96

filenames

glEndList(

GCC, compiling with, 13

glMaterial(

debugging and, 8

SDL_CreateRGBSurface( )

)

function, 32

Web

function, 32

),

106-107

glRotate(), 97, 126-128

47

),

132

gluBuild2DMIPMaps(

145, 300

site,

gluPerspective( flipping graphics to surfaces, 36 flowcharts, technical specification, 6

fogging, 115-116

pixels,

)

Web

glutCreate Window (

92

),

),

92

gludnitDisplayMode(

92

),

glutMainLoopUpdate( site,

121-122

),

glutMainLoop( ),92

function, 40

Freshmeat

99-100

),

gludnit(),92

34-35

framework code, startup and shutdown, 24-26 free(

112-113

),

glutBitmapCharacter(

glutDisplayFunc(

forking codebase (porting), 275-276

format descriptions,

111

),

glNewList(),118

glTranslate( flickering screen, avoiding,

118

glLightfVO, 107-108

arguments; parameters

SDL_SetVideoMode(

),

glGenTextures(

shoot-em-up games, 3

flags. See also

118

),

glGenLists(

porting, issues with, 283-284

flipcode

J

glClearColor( ),92

formats

films,

118

),

glClear(),93

),

92

9 gl\ertex3f( ),96

functions gultPostRedisplay(

accept(

),

),

93

181

HandleEvents(

alcCreateContext(

alGenSourcefv( alListenerfV(

),

),

),

),

67

148-149

HandleMouseEvent(

152

),

77-78

initCamera(), 92, 100-101

150 ioctl(

alutBufferAndConvert_LOKI(

),

),

165

151 jovsticks, retrieving

information about, 79

Linux Gaiyie FfiDGKfliniYiiNG

SDL_SetColors( ),39

functions continued listen (

),

181

SDL_SetVideoMode(

main(

),

13

SDL_Unlock(),39

makeNormalO, 109-110

SDL_WaitEvent(

ol_Bye(

SDL_WM_SetCaption(

),

195

ol_Connect(

),

189

ol_FindGames(

select(

send(

191

),

ol_Login(),190

ol_UpdateGame(

function, 192-193

)

OpenAL, 148 pcx_show_fast(

55-56

),

pcx_show_trans( pthread_create(

recvfrom(

),

177

redisplay (

),

137

SDL prototypes,

), ),

),

),

172-173

ssglnit(

),

136 ),

137

55-56

vga_getgraphmem

182-183

vga_hasmode( ),

),

(

51

50

),

50-51

vga_setmode(

50

),

vga_setpalette (

)

56-57

,

WinMain(), 289-290

SDL_BlitSurface(),35 ),

function, 33

176

),

socket(

vga_init(

SDL_CloseAudio(

)

175-176

ssgLoad(

including, 31

64-67

),

178

),

sendto(

32-33

),

XClearWindow(), 41-42

164

SDL_CreateRGBSurface(

),

33-35

SDL_CreateRGBSurfaceFrom(

),

XCloseDisplay(),49

XCopyArea(),47

33-35

XCopyPlane(),46

SDL_Flip(),36 SDL_FreeSurface(

),

XCreateGCO, 43-45

35,40

XCreatePixmap(

SDL_GetError( ),30 SDL_GetKeyState(

),

),

47-48

XCreateSimpleWindow(

83-82

),

SDL_GetModState(),83

XCreateWindow(), 41-42

SDL_GetMouseState(

XDrawPoint(),43

),

84

SDL_GetRelativeMouseState(

),

41-42

XFree(),49

84

XFreeGC(),49

SDL_Init(), 30-31

SDLJoystickEventState(

),

XFreeWindow(),49

79

SDLJoystickOpen(),79

XMapRaised(), 41-42

SDL_LoadBMP(),35 SDL_LoadWav( ), 162

XOpenDisplayO, 41-42 XSetForeground(),49

SDL_Lock(), 38-39

SDL_MapRGB(),36 SDL_MixAudio(

)

function, 163

SDL_NumJoysticks(),78

SDL_PauseAudio(),164 SDL_PollEvent(), 64-67

SDL_PumpEvents(),84 SDL_Quit(),30,40

G GamaSutra Web

site,

300

Game Architecture and Design, 302 Game Developer Magazine, 304

Game Development Series, Prima game

engines, 133

Publishing, 303

game

loop, 24

code

Web

GameDev.net gameloop(

glEndList(

26-27

for,

300

site,

function, 118

)

glGenTextures(

function, 26-27

)

function, 118

)

glGenLists(

glLightfv(

)

function, 111

function, 107-108

)

gamepads, 61

GL_LIGHTING option,

games

glLoadIdentity( ),97

applications,

compared

to,

characteristics of successful

component

parts,

glLoadIdentity(

games, 5-6

glLoadMatrixf(),97

24

lobbies, creating in,

glLoadMatrixf(

192-193

porting, desirable/undesirable characteristics,

274-275

glMaterial(

function, 97

)

function, 118

glNewList(

)

glRotate(

function, 97, 126-128

)

glScalef(),97

types of, 2-5

glScalef(

)

function, 97

GL_TEXTURE_2D

7

43-45

creating,

)

function, 106-107

terminating, 24

Gamma testing, GC,

function, 97

2

)

glTranslate(

GCC 14

option, 105

function, 132

)

glTranslatef(

libraries, specifying in,

)

function, 97

gluBuild2DMIPMaps( gluPerspective(

porting, 279-282

GLUT library,

Web

glutBitmapCharacter(

GDB

(debugger)

279

Web

site,

15

)

main(

glutCreateWindow (

Genebot, 213-219

glutDisplayFunc(

genetic algorithms, 212

glutlnit(

function, 24-26

)

GL_ALPHA_TEST option, glBegin(

)

glCallList(

glClear(

)

105

glColor3f(

)

)

function, 92

GL_COLOR_MATERIAL GL_CULL_FACE option, 104

option, 105

)

function, 118

GL_DEPTH_TEST option, glDisable(

glEnable(

glEnd(

)

)

)

)

)

function, 92

glutMainLoopUpdate )

function, 92

(

)

function, 92

function, 96 See

GCC windows

art specification, 6

buffering, 90

function, 96

glDelete Lists (

function, 92

)

function, 92

graphics. See also surfaces;

function, 92

glClearColor(

glutMainLoop(

GNU C compiler.

function, 118

function, 121-122

)

function, 92

glVertex3f(

function, 96 )

)

function, 91

)

glutInitDisplayMode(

memes, 213 GetMessage(

)

function, 112-113

)

function, 99-100

multiple platforms, 14

site, 12,

104-105

105

3D file

OpenGL and, formats Web site, 35

rendering,

90

fogging, 115-116

handle numbers (textures), 110-111

function, 92, 102

hiding surfaces, 90

function, 92, 102

images, displaying (SVGAlib), 52-56

function, 96

images, drawing, 45-47 loading, 35

.

Linux

C5f=ime

FRDGRflmiYiiNG

graphics continued I

Mesa, 88-90

1

-I

MIP mapping, 112-113 OpenGL, 88-90

PCX format,

H

command

line switch, 15

#ifdef statement, 277

images. See graphics

52-55

immediate

values,

288

pixel location, determining (SDL), 38-39

included pixels,

format descriptions (SDL), 34-35

screen, drawing to (SDL)

,

files

command

line switch for, 15

33-39 filename

screen, drawing to (Xlib), 43-48

SDL

support for textures, limitations, 114 including

issues,

282

prototypes, 31

SDL

prototypes, 31

113-114

textures, applying,

Indrema, conflicts with OpenSource, 236-238

111-112

textures, loading into,

Indrema Developer Network Web

site,

transparency, 114-115 initalization,

transparency, problems with, 115

vertex arrays, 119-120

XPM files,

SDL, 30-32

sound (SDL), 159-161

lists,

OpenGL

91-92

OpenAL, 148-150

45

graphics cards display

24

GLUT library,

executing commands, 118

initCamera(

)

function, 92, 100-101

and, 88-89

input devices, 60

graphics context. See GC

control system, configuring, 84-85

graphics modes, 50

event queues (SDL) 62, 63 ,

setting (SVGAlib), 50-51

c

keyboard, 60-61

Graphics Programming Black Book, 302 polling,

grayscale pallet, allocating

62-63

memory, 39-40 installation, 8-bit color

grouping

(AI),

maps, 48-49

205 interfaces, 5

gultPostRedisplay(

)

function, 93

design documents, 6

gamepads, 61

H

hats, 61

handle numbers (textures), 110-111

HandleEvents(

)

input devices, 60-62

function, 67

HandleMouse Event (

)

Happy Penguin Web

site,

joystick,

function, 77-78

301

trackballs, 61

hardware

ioctl(

accessing for

OpenGL and

CD

)

function, 165

audio, 165

graphics cards, 88-89

J

hats, 61

joystick,

header

61-62

mouse, 61

tiles,

location of

(OpenGL),

Hungarian Notation, 291

91

61-62

enabling subsystem, 78 event handling (SDL), 78-82

information about, retrieving, 79

301

K

line equation, 125

linking multiple

makefiles, 28

Web

Linux

keyboard, 60-61

Game

Ul

13

Developer Resource Centre

Web

Linux Games

84

listen

scancodes, 68

Web

301

event handling (SDL), 68-76 polling,

files,

Linux Device Drivers, 303

18

site,

drawing (OpenGL), 94-96

lines,

KDevelop, 18-20

(

site,

301

function, 181

)

listeners,

150

lobbies, 188

chatting -L

command

latency,

LGDC

line switch,

games, finding, 191-192

306

list,

193-195

in,

games, creating, 192-193

dead reckoning and, 187

mailing

liability,

14-15

servers,

241

connecting

servers, logging in,

libGLU, 99

locking surfaces, 38-39

libraries

loops

game GCC,

engines, 133

game loop, 24 game loop code, 26-27

specifying in, 14

libXll, 21

OpenGL,

189-190

to,

190-191

message loop, 24 21

sound sources, 153

pthreads, 182-183

Lupine Games

Web

site.

10

SDL, 20-21 storing models, 133-134

libXll, 21

M magazines, 304-305

licenses

306

mailing

lists,

main(

function, 13

custom, 240 liability,

241

)

GLUT library,

open, 240

91

makefiles

OpenSource, 226 code

OpenSource,

selecting,

for,

27-28

9 sdl-config, 31

selecting, viral,

239

makeXormal(

239

mask

light-mapping, 139

values,

function, 109-110

)

XCreateGC(

)

function, 44

mathematics, drawing and, 124-126

lighting

matrices, 122-124

OpenGL, 104-105 OpenGL, limitations, 139-140

effects,

reflective objects,

106

2D 3D

objects, presenting as 3D,

graphics, 96-97

ModelView, 96-98

source, setting, 107-108 Projection,

surface normals, 108-110 types,

106

98-100

MCV newspaper,

305

126-128

site,

',

-.

Linux GfiME P-ROG-R-HrnmiNG

memes, 213

data,

Genebot, 213-219

i

dead reckoning, 187

latency,

memory

188-195

lobbies,

buffer overflows, 196 color, allocating for,

Jl

sending to sockets, 175-176

freeing,

40

freeing,

sound

peer-to-peer, 170

39-40

players, tracking activity,

186-187

security issues, 196 files,

164

servers, creating,

180-182

remote machines, 173-174

freeing (SVGAlib), 57

sockets, connecting to

pixel location, determining, 38-39

sockets, opening, 172-173

releasing, surfaces, 35

TCP/IP

sound

files,

threads, 182-183

loading into, 151-152

terminating games, importance

of,

protocol stack, 171-172

Winsock, porting

24

Mesa

issues,

295-297

neural networks, 219-223

background, 88

newsgroups, 306

Web

newspapers, 305

site,

90

message loops,

24,

289-290

normalizing, 125

Nurgle method (AI route finding) 203-204

message queues, 185-186

,

messages, void * type, 26

min-max

trees,

O

207-208

MIP mapping, 112-113

-O

mixing sound, 164-165

command

line switch,

modeling, 132-133

129-132

collisions,

storing models, 133-134

copying in X, 47

ModelView matrix, 96-98

2D, presenting as 3D, 126-128

modifier symbols, 74

display

mouse, 61

Mozilla

MUDs

pre-defined, 103

refilctivity, setting,

84

Web site,

rotating

297

ol_Bye(

(Multi-User Dungeons), 4

)

(OpenGL), 98-99

)

function, 189

ol_FindGames(

GCC compiler,

14

ol_Login(

106-107

function, 195

ol_Connect(

multiplayer games, 2

multiple platform development,

118-119

lists,

OpenGL,

event handling (SDL), 76-78 polling,

14

objects

)

)

function, 191

function, 190

olServer structure, 190

N

ol_UpdateGame(

NASM Web site,

opcode names, 287

298

open

networking client-server, 171 clients,

threads and, 183-186

controller inputs, sending, 188 data, receiving,

176-178

licenses,

)

function, 192-193

240

OpenAL deleting sound, 154

Doppler

shift,

functions, 148

156-157

Index

initializing,

listeners,

obtaining, 89-90

148-150

options, 102

150

playing sound, 153

Projection matrix, 98-100

reverb, 157-158

reflective objects,

sound

files,

loading, 151-152

sound sources,

creating,

state

152-153

management

106-107

management, 134

surface normals, 108-110

(sound), 153

surfaces, drawing,

stopping sound, 154

text,

textures, 110-111

volume

textures, applying,

control, 154

site,

94-96

drawing, 121-122

streaming buffers (sound), 158-159

Web

transparency, problems with, 115

and

animation, 96-102

triangle strips

camera position, moving, 101-102

vertex arrays, 119-120

compiling, 93

Website, 21,89

2D

4x4 matrices, 96-97

objects, presenting as 3D, 126-128

GL_ALPHA_TEST option, 105 GL_BLEND option, 105 GL_COLOR_MATERIAL option, GL_CULL_FACE option, 104 GL_DEPTH_TEST option, 105

GLJJGHTING option,

OpenLobby, 188-189 connection, closing, 195

105

104-105

option, 105

GLUT library, windowing and, files,

91-93

location of, 91

images, loading into textures, 111-112 light source, setting,

lighting,

?

,

fogging, 115-116

header

120-121

OpenGL Reference (The Blue Book) 302 OpenGL Super Bible (The Red Book), 302

118-119

GL_TEXTURE_2D

fans,

OpenGL Game Programming, 88

default coordinate system, 96 lists,

J

113-114

transparency, 114-115

148

OpenGL, 88-89

display

fl

support for textures, limitations, 114

sound sources, moving, 154 state

lr

107-108

OpenSource advantages

of,

alternatives to,

229-231

234-236

charges and, 227

development models, 227-228 distribution model, 227

Indrema, conflicts with, 236-238 licenses, selecting, 9

overview, 226

releasing games, 8-9

106

lighting, limitations,

139-140

operand order (porting), 287

matrices, 122-124

optimization, 14

Mesa and, 88

options,

MIP mapping, 112-113

orthographic drawing, 100-101

modeling, 133-134

OSX development Web site,

ModelView matrix, 96-98 objects, pre-defined, 103 objects, rotating,

98-99

OpenGL, 102 298

Linux

FRQGRfiiYiiniNG

G-riyi-e

Direct3D, 293-295

p

DirectDraw, 292

39-40

palettes,

DirectPlay,

parameters. See also arguments; flags

parent argument, 41-42

file

particles,

297

DOS frame buffer,

293

systems, 283

drawing, 129

pathnames, porting

issues,

284-285

52-55

pcx_show_fast(

function, 55-56

pcx_show_trans(

)

283-284

issues,

GCC, 279-282

PCX file format, )

filename

Hungarian Notation, 291 #ifdef statement, 277

function, 55-56

immediate

peer-to-peer networking, 170

values,

288

included filename

issues,

282

personality (AI), 223 perspective,

message loops, 289-290

98-100

mixing signed and unsigned

pinging, 186-187

types,

280

multiple-byte storage, 288-289 Pixel (

)

function, 43

opcode names, 287

pixels

format descriptions (SDL) 34-35

operand order, 287

,

overview, 274

formats (SDL), 36-38 location, determining (SDL),

38-39

read/write access, 286

plotting (SDL), 38-39

refactoring,

plotting (Xlib), 43-45

SDL_MapRGB(

pathnames, 284-285

register )

277-278

names, 287

function, 36 resources, 297-298

plane equation, 124-126

sound

issues,

295

platform games, 3 struct packing, playability,

players, tracking activity,

PLIB/SSG

Web plot,

282-283

5 text

186-187

(scene graph API), 135-138

site,

of,

Visual

285

C/C++

issues,

279

Windows Registry, 291 WinMain( ) function, 289-290

138

importance

files,

5

pname argument, 150 points, drawing (OpenGL) 94-96

programming.

See

code

Projection matrix, 98-100

,

prototypes polling, 62-63, 83

alListenerfv(

)

function, 150

keyboard, 83

SDL_CreateRGBSurface(

),

33-35

mouse, 84 polygons, drawing (OpenGL), 94-96

SDL_CreateRGBSurfaceFrom(

),

33-35

SDL_Event union, 63-64

porting

SDLJoyAxisEvent

structure, 79

addressing modes, 288

assembly language

issues,

286-287

SDLJfoyBallEvent structure,

SDLJoyButtonEvent

codebase, forking, 275-276

80

structure, 79

SDLJoyHatEvent

structure, 80

SDL_PollEvent(

function, 64

compiler defined macros, 277 compilers, issues with, 278-282

desirable/undesirable

274-275

game

SDL_WaitEvent( characteristics,

)

)

function, 64

pthread_create(

function, 182-183

)

publishers, selecting, 9-10

puzzle games, 4

S scancodes, 61, 68

scene graph API, 133-138 screen. See also surfaces; color, setting with

queues. See event queues

R

windows

OpenGL, 92

drawing

to,

double buffering (SDL), 33-36

drawing

to,

double buffering

(Xlib),

47-48

drawing to directly (SDL), 36-39 drawing to directly (Xlib) 43-47 ,

real-time games, 3

recvfrom( redisplay (

)

function, 177

)

function, 137

refactoring,

drawing

to (SVGAlib),

flickering, avoiding,

51-52

47

pixel formats (SDL), 36-38

277-278

sdl-config, 31

references

books, 302-303

magazines, 304-305 mailing

lists,

306

newsgroups, 306

Web

sites,

300-301

106-107

reflective objects,

register

names, 287

SDL SDL SDL

key symbols, 69-74 modifier svmbols, 74

(Simple DirectMedia Layer), 20-21, 30. specific

See also

SDL fu n cticms

arguments, 30-31

audio callback, 163 event queues, 62-67 event types, 65

releasing

commercial option, 9-10

OpenSource option, 8-9

30-32

initializing,

initializing

sound, 159-161

mixing sound, 164—165 shareware option, 10 polling,

62-63

resources

books, 302-303

magazines, 304-305

prototypes, including, 31

sound, 159 sound, pausing, 164

mailing

lists,

306

sound, playing, 163-164

newsgroups, 306

Web

sites,

300-301

sound

files,

loading, 162

unions compared to structures, 63

reverb, 157-158

SDL_AudioSpec

structure, 160

role-play games, 4

SDL_BlitSurface(

function, 35

)

route finding

nurgle method, 203-204 state trees,

RPGs

198-203

SDL_CloseAudio(

)

function, 164

SDL_CreateRGBSurface(

)

function, 33-35

SDL_CreateRGBSurfaceFrom(

)

function, 33-35

(role-play games), 4

SDL_Event union, 63 event queue, reading from, 64-67 events,

determining

prototype, 63-64

types,

64

Linux Gaiyic -F-ROG-R-nmmiNG

3EB

SDL_Flip(

function, 36

)

SDL_FreeSurface(

1

SDL_GetError(

function, 30

)

SDL_GetKeyState( Jl

servers

function, 35, 40

)

SDL_GetModState(

)

)

sockets, binding,

function, 84

function, 30-31

)

structure, 79

SDLJoyBallEvent

structure,

SDLJoyButtonEvent

SDLJoyHatEvent

SDLJoystickEventState(

SDLJoystickOpen (

)

SDL_KeyboardEvent

SDL_keysym

shoot-em-up games, 2-3

Simple DirectMedia Layer.

80

socket(

structure, 68

sockets

opening, 172-173

function, 162

)

SDL_MapRGB(

software

commercial, advantages

function, 36

)

SDL_MixAudio(

SDL_MouseButtonEvent

structure,

76-77

licensing,

SDL_MouseMotionEvent

structure,

76-78

modeling, 132-133

SDL_NumJoysticks(

)

SDL_PauseAudio(

function, 164

SDL_PollEvent(

)

SDL_Quit(

)

function, 78

function, 64-67

)

SDL_PumpEvents(

)

function, 84

function, 30-31, 40

SDL_SetColors(

function, 39

)

SDL_SetVideoMode( SDL_Unlock(

)

)

)

function, 64-67

SDL_WM_SetCaption( security. See also issues,

function, 32-33

function, 39

SDL_WaitEvent(

)

function, 33

bugs

196

SVGAlib, 49 select(

send(

)

)

sendto(

function, 178 function, 175-176 )

function, 176

of,

232-234

development models, 227-228

function, 163

)

function, 172-173

connecting to remote machines, 173-174

function, 38-39

)

)

binding, 180-181

function, 35

)

SDL

smoke, 129

function, 79

structure, 68

SDL_LoadBMP( SDL_LoadWav(

See

simulation games, 3

function, 79

)

threads and, 186

shareware, releasing games, 10

80

structure, 79

structure,

180-181

UDP, 182

SDLJoyAxisEvent

SDL_Lock(

lobbies, logging in, 190-191

function, 84

SDL_GetRelativeMouseState(

189-190

lobbies, connecting to,

function, 83

)

SDL_GetMouseState(

SDL_Init(

controller inputs, sending, 188

function, 83

)

connections, accepting, 181-182

226

OpenGL and

emulation, 88-89

OpenSource, advantages OpenSource,

of,

alternatives to,

229-231

234-236

OpenSource, charges and, 227

sound audio callback, 163

CD audio, Doppler

165-168

shift,

156-157

files,

loading, 151-152

files,

loading (SDL), 162

initializing listeners,

(SDL), 159-161

150

looping, 153

memory,

freeing, 164

mixing (SDL), 164-165

OpenAL, 148 pausing (SDL), 164

H

playback, stopping, 154

memory,

playing, 153

palettes,

playing (SDL), 163-164

pixel location, determining, 38-39

porting issues, 295

pixels,

reverb, 157-158

releasing, 35

39-40

format descriptions, 34-35

unlocking, 39

SDL, 159

SVGAlib, 49-50.

See also specific

SVGAlib functions

sources, creating, 152-153

color palettes, 56-57

sources, deleting, 154

graphics modes, setting, 50-51

sources, moving, 154

memory,

management, 153

state

volume

freeing,

57

screen, drawing to, 51-52

control, 154

security issues,

49

specular light, 106 splash particles, 129

T.

sports games, 4

TCP/IP protocol

sprites, art specification,

srcrect ssglnit(

)

UDP, 172

function, 136 )

TCP

function, 137

terminating

importance

sound, 153 state trees (AI

memory,

route finding), 198

text,

5

text

storyboards, art specification, 6

282-283

compared

to unions,

63

surfaces. See also graphics; screen;

33-35

double-buffering, 33

drawing (OpenGL), 94-96 flipping graphics to, 36

handle numbers, 110-111

lighting techniques, 139-140

support

surface normals, 108-110

locking, 38-39

porting, 285

images, loading into, 111-112

surface contours, following, 132

creating,

drawing, 121-122 files,

applying, 113-114

streaming buffers (sound), 158-159

structures

129-131

texture, 105

strategy games, 3

struct packing,

debugging

development process, 7-8

searching, 200-203 of,

24

collision detection,

modifying, 200

importance

of,

freeing, 40

testing. See also bugs;

generating, 199-200

story,

(Transport Control Protocol), 171-172

technical specification, design documents, 6

and shutdown code, 24-26

management, 134

state

stack

TCP, 171-172

argument, 35

ssgLoad( startup

6

for, limitations,

114

text characters, 122

windows

texture maps, 110

threads (networking), 182-183 clients and,

183-186

message queues and, 185-186 servers and, 186 tic-tac-toe,

AI example, 209-212

Linux Gaiyie -P-ROG-RflmmiNG

timing mechanisms (porting), 290

toolbox

1

(DDD

vga_setpalette(

debugger), 16-18

viral licenses,

Visual

tools

Jl

C/C++

)

function, 56-57

239 issues,

279

compilers, 12-15

void * type (messages),

debuggers, 15-18

volume

development environments, 18-20 libraries,

20-21

track listings (CDs), 166-167

warning

transparency, 114-115

Web Web

problems with, 115 transparent color, drawing (SVGAlib) 55 ,

Transport Control Protocol (TCP), 171-172 triangle strips

Tucows Web

W -W command

trackballs, 61

and

site,

fans,

120-121

line switch, 14

levels, setting,

browser, code

for,

14

179-180

sites

D3D/OpenGL comparison,

298

DDD, 15 DJGPP FAQ, 298

10 file

turn-based games, 3

26

control, 154

formats, 35

flipcode, 145, 300

Freshmeat, 9

U

GamaSutra, 300

UDP

(User Datagram Protocol), 172

servers,

Unicode

field,

Unicode

Web

75-76 site,

GameDev.net, 300

GCC, 12, 279 GDB, 15 Happy Penguin, 301

182

75

unions compared to structures, 63

Indrema Developer Network, 301

unit vectors, 125

Linux

UNIX Scoket FAQ Web site,

298

Game

Developer Resource Centre, 301

Linux Games, 301

unlocking surfaces, 39

Lupine Games, 10

User Datagram Protocol (UDP), 172

Mesa, 90

user interfaces. See interfaces

Mozilla, 297

NASM, 298 OpenAL, 148 OpenGL, 21,89

variables

DISPLAY environment variable, 41-42 values, retrieving, 16

vertex arrays, 119-120

vga_getgraphmem(

vga_init(

)

)

)

function, 51

function, 50

function, 50-51

vga_setmode(

)

OSX development, PLIB/SSG

function, 50

298

(scene graph API), 138

SDL library,

VGA modes, 50 vga_hasmode(

OpenLobby, 188-189

21

Tucows, 10

UNIX

Scoket

FAQ

298

Winsock Programmers

FAQ

298

windows. See

XCopyPlane(

also screen; surfaces

GLUT library,

creating with, 91-93

XCreateGC(

function, 46

)

function, 43-45

)

SDL, creating surfaces with, 33-35

XCreatePixmap(

SDL, creating with, 32-31

XCreateSimpleWindow(

SDL,

window

setting

Xlib, creating with,

Windows

XCreate Window (

captions, 33

XDrawPoint(

40

XFree(

Registry, porting issues, 291

WinMain(

)

issues,

Winsock Programmers

298

function, 41-42

function, 41-42

function, 43

)

function, 49

XFreeWindow(

295-297

FAQ Web site,

)

)

)

function, 49

XFreeGC(

function, 289-290

Winsock, porting

)

function, 47-48

)

)

function, 49

Xlib, 40. See also specific

X functions

DISPLAY environment variable, 41-42

X

double buffering, 47-48

memory,

X color maps, installing, 48-49

windows, creating, 40

images, drawing, 45-47 freeing, 49

objects, copying, pixels, plotting,

programming

47

43-45

in,

40

43-45

screen, drawing to, 43

double buffering, 47-48

memory,

freeing, 49

pixels, plotting,

XMapRaised(

)

XOpenDisplay(

function, 41-42 )

function, 41-42

XPM files, 45 XSetForeground(

)

function, 49

screen, drawing to, 43-47

windows, creating, 41-42

X axis

(joysticks)

,

range, 62

Yaxis

(joysticks), range,

4x4 matrices, 96-97

X PixMap, 45 XClearWindow( XCloseDisplay(

XCopyArea(

)

)

)

function, 41-42 function, 49

function, 47

Z zFar values, 99

zNear

values,

99

62

PRIH/IAG/VII/IFS con/i

Home • News l

Strategy Guides

Forums

Game Worlds

More Than Jusb Strate gy Strategy: Over 250 Fast Track Guides with many

more

to

come

— new online strategy

every week.

;

3

3SE."

News: A

daily digest of

news

game

— our news area

is

the

you want know what's new in games.

best place to start to

industry

if

Game Worlds Our Game Worlds are dedicated most popular games and supported by our wealth

to the

of Fan Site Affiliates.

PRIMA

GflfYlE IT'S

DEVELOPIY1ENT. SERIOUS SU51NC-S5.

"Game programming is without a doubt the most intellectually challenging However, we would be fooling ourselves if we said that we are 'serious' programming book should be an exciting adventure

for

field

of Computer Science

in the world.

people! Writing (and reading) a

game

both the author and the reader."

-Andre LaMothe, Series Editor

PRIMA TECH'S

I

fnmaI

www.prima-tech.com www. PrimaGameDev. com

GAME DEVELOPMENT

The most comprehensive game development resource

.

ie

latest

news

in

v

game development

most active forums and chatrooms

an'

\

with

iA^i*TBlKVSiflT#HirSKViislif W^AJTmuTtSMTmwi&mWtSitmr&mMi

thousands of additional game ; Thorough book and product reviews >Over 000 game devefoj nent articles! >

resources

Links to

1

Game design Graphics DirectX

OpenGL Al Art

J

Music Physics

Source Code

Sound |

Assembly

And

More!

>:«

X

«•

*dl$i

rA

II OpenGL

is a rcgistcrcdtradcraark of Sili' Microsoft. DirectX are registered traderr

-_

H^\

1

II

ai

-!UUI\

II II-

il

ii

u

i

i

nc DK1

f d.

JL

.j~,

2 Z.

*

at

'J

*^

m

1! f*ah» —^^W -

W&zJSSZ-

1

t

pis} '''* 1

i

==S

K g fc

If r».Tf:.'l£B

BE

--m~.(i»

"

m

_.— —»JV



•Br—"

Xtreme Games LLC was founded

to help small

game developers

around the world create and publish their games on the commercial market. Xtreme

Games

helps younger developers break into the

field

game programming by insulating them from complex legal and business issues. Xtreme Games has hundreds of developers around of

the world, at

if

you're interested

in

becoming one

of

them, then

visit

us

www.xgames3d.com.

ww.xgames3d.com

Mfl

License Agreement/Notice of Limited Warranty By opening the sealed disc container in this book, you agree to the following terms and conditions. upon reading the following license agreement and notice of limited warranty, you cannot agree to the terms and conditions set forth, return the unused book with unopened disc to the place where you

If,

purchased

it

for

a refund.

License:

The enclosed software

is

copyrighted by the copyright holder(s) indicated on the software disc. You

are licensed to copy the software onto a single computer for use by a single concurrent user and to a

backup in

disc.

whole or

You may not reproduce, make copies, or

in part,

distribute copies or rent or lease the software

except with written permission of the copyright holder(s). You

enclosed disc only together with

this license,

and the transferee agrees

terms

to the

and only

of the license.

if

you destroy

all

may

transfer the

other copies of the software

You may not decompile, reverse assemble, or

reverse engineer the software.

Notice of Limited Warranty:

The enclosed disc is warranted by Prima Publishing to be free of physical defects in materials and workmanship for a period of sixty (60) days from end user's purchase of the book/disc combination. During the sixty-day term of the limited warranty, Prima

will

provide a replacement disc upon the

return of a defective disc.

Limited Liability:

THE SOLE REMEDY FOR BREACH OF THIS LIMITED WARRANTY SHALL CONSIST ENTIRELY OF REPLACEMENT OF THE DEFECTIVE DISC. IN NO EVENT SHALL PRIMA OR THE AUTHORS BE LIABLE FOR ANY OTHER DAMAGES, INCLUDING LOSS OR CORRUPTION OF DATA, CHANGES IN THE FUNCTIONAL CHARACTERISTICS OF THE HARDWARE OR OPERATING SYSTEM, DELETERIOUS INTERACTION WITH OTHER SOFTWARE, OR ANY OTHER SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES THAT MAY ARISE, EVEN IF PRIMA AND/OR THE AUTHOR HAVE PREVIOUSLY BEEN NOTIFIED THAT THE POSSIBILITY OF SUCH DAMAGES EXISTS. Disclaimer of Warranties:

PRIMA AND THE AUTHORS SPECIFICALLY DISCLAIM ANY AND ALL OTHER WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING WARRANTIES OF MERCHANTABILITY, SUITABILITY TO A PARTICULAR TASK OR PURPOSE, OR FREEDOM FROM ERRORS. SOME STATES DO NOT ALLOW FOR EXCLUSION OF IMPLIED WARRANTIES OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THESE LIMITATIONS MAY NOT APPLY TO YOU. Other: This Agreement

is

governed by the laws

of the State of California without regard to choice of law

The United Convention of Contracts for the International Sale of Goods is specifically disclaimed. This Agreement constitutes the entire agreement between you and Prima Publishing regardprinciples.

ing

use

of the software.

BPr*'V

LAr^--V=3

c=r

Your guide to creating games with Linux®! With the growing ter

1

interest in

of time until everyone

commercial developers

will

now

their titles to Linux, people are finally

platform

is

will

You

will also find

SVGAlib;

3D

want high-quality Linux games.

setting

up in-house teams

for Linux, covering

T-H-E

for porting

all

LATEST LINUX*

T-H-E

your guide

is

KERNEL 5DURCE



'

the APIs and methodologies you

lNDREm-n

rarely discussed in other

ENTERTAINMENT 50ETLUARE

guides, such as neural networks and genetic algorithms.

valuable information on

2D graphics using SDL,

Xlib,

OpenGL; networking, lobbying, and threading;

graphics using

DEVELORFYIENT TOOLKIT

and

artifi-

3D VERSION

IY1E5A cial

intelligence

ON CD

UJ+H-RT'S

Witfi

acknowledging that the OpenSource

some more advanced techniques

need, as well as

game development

only a mat-

it is

gaming platform. Linux® Game Programming

a viable

game development

to

Linux on the desktop,

3.H

and learning systems; genetic algorithms; and much, much more!

ORENAL IVl3rK \_Ol llTl S

At the age of just

18,

Mark "Nurgle"

Collins secured a

job

in

the

games

RRETTY POLY EDITOR

industry developing network support for a successful product line, as well as being considered a

guru for Linux game development by the GameDev.Net community. After having many adventures, he's starting

up

his

own development

studio with the goal of

making games good

again.

LINUX® 5VGAL1E

AUTHOR CODE

Series Editor

Alldre LaMothe, Andre LaMothe has been

game

for the

TRS-80®

NASA, compiler design, a consultant to various

the world's

first

in

in

CEO Xtreme Games LLC

the computing industry for more than 23 years and wrote

1976.

He has worked

in

2D/3D

Division of

first

at

robotics engineering, virtual reality, telecommunications, and has been

companies located

in Silicon Valley.

commercially available virtual

reality

Andre

is

also the inventor of one of

games, CyberGate, created

PRIMA TECH A

his

graphics, artificial intelligence

in

the early

'90s.

"- r

*rr-UHJ

Prima Publishing

ISBN D-7t,15-3S5S-5

www. pri ma -tech com .

wuuw.PrimaGameDeu.com Cover Design: Prima Design Team

User

Level;

BEGINNING/INTERMEDIATE

Category: Languages/Programming o

U.S.

$39.99

Can. $59.95

U.K.

£29.99

IH86874II53255 111

7

9I780761H532552

1

53999