[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Hi everybody!



Thank to your help, here is a better version of the linux game
programming howto.
I've corrected the english mistakes, made a better html, added your
suggestions and some new stuff. Can you check it again and give me
feedback? Thanks.
Alex.
Title: The Linux Games Programming HOWTO - Part 1

The Linux Games Programming HOWTO: Part 1

Alexandre Courbot, GNUrou@linuxfan.com, with the help of the LGDC mailing list members (http://sunsite.auc.dk/linuxgames/)


This is the first part of the Linux games programming HOWTO. The goal of this part is to provide information on linux programming specifics and graphics libraries. I assume that you have basic knowledge in C. Advanced knowledge of Linux is not necessary. Now, let's study the basics!

1.The C/C++ compiler:GCC/G++.

The tool you must have :). GCC is a very good, free software C compiler. It is normally installed on every linux system. It has a DOS/Windows port that is called DJGPP, and that is very powerfull too. GCC is a command line compiler, so you need an external editor (emacs is good) and you'll have to keep in mind some parameters.

GCC command line usefull parameters:
> The "-o <name>" option is always used and sets the executable name. If you omit it, it will be a.out.
> The "-Wall" option:GCC supports many levels of warning, all of which may be activated with the command line flag "-Wall". See the GCC documentation for further details. I recommend you to always use this flag if you want to check the quality of your code.

Now we can make the classic Hello World on Linux: Edit a hello.c file:

#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("Hello World! (From Linux)\n");
return(0);
}

Compile it:
[alex@bluefalcon]~/tut $gcc hello.c -Wall -o hello
(Note:[alex@bluefalcon]~/tut $ is my prompt, so don't type it ;), the command start at "gcc".)

And launch it:
[alex@bluefalcon]~/tut $./hello
Hello World! (From Linux)

> The "-O<n>" option sets the level of optimisation. GCC can optimize your code, and do it well. <n> can currently go from 0 (no optimisation) to 3 (all optimisations). Others optimisation levels will be added in next versions, so <n> can be above 3.

> "-c" tells GCC to compile but not to link. This will create a .o file that you may link later.
Example:

hello.c:
#include <stdio.h>

void print_to_screen(char * s)
{
printf("%s\n",s);
}

main.c:
#include <stdio.h>
#include <stdlib.h>

void print_to_screen(char * s); /* Used to avoid a warning */

int main()
{
char str[]="Hello World!";
print_to_screen(str);
return(0);
}

Now let's compile this:
[alex@bluefalcon]~/tut $gcc hello.c -c -o hello.o -Wall -O6
[alex@bluefalcon]~/tut $gcc main.c -c -o main.o -Wall -O6
[alex@bluefalcon]~/tut $ls *.o
hello.o main.o
[alex@bluefalcon]~/tut $gcc hello.o main.o -o hello
[alex@bluefalcon]~/tut $./hello
Hello World!

"gcc hello.o main.o -o hello" just take the two object files and link them to make an executable.

> "-l<libname>" is used to link your program to a library. Linux use shared libraries to avoid code redundany in memory. Libraries are usually in 3 directories:

In /usr/X11R6/lib you will find the X window libraries, but we'll not use them for the moment.
In these directories, all libraries files are in the format lib<libname>.so.* or lib<libname>.a. The .so extension mean this library can be linked dynamically, the .a mean it can be linked statically. Let's see an example using the maths library:

main.c:
#include <stdio.h>
#include <stlib.h>
#include <math.h> /* We include maths files headers */

int main()
{
printf("%f\n",sqrt(2));
return(0);
}

If we try to compile like we used to do here is the result:
[alex@bluefalcon]~/tut $gcc main.c -o math
/tmp/ccc02939: In function `main':
/tmp/ccc02939(.text+0xb): undefined reference to `sqrt'
[alex@bluefalcon]~/tut $ls math
ls: math: No such file or directory

That's because the sqrt funtion is in the m library:
[alex@bluefalcon]~/tut $ls /usr/lib/libm.*
/usr/lib/libm.a /usr/lib/libm.so

So we have to compile like this:
[alex@bluefalcon]~/tut $gcc main.c -o mathdynamic -lm

Or if we want a static binary (Which will run even if the library is not on the system):
[alex@bluefalcon]~/tut $gcc main.c -o mathstatic -lm -static

However the static binary size is much more important than the dynamic one!
[alex@bluefalcon]~/tut $ls -l mathdynamic mathstatic
-rwxr-xr-x 1 alex alex 4194 may 13 15:45 mathdynamic
-rwxr-xr-x 1 alex alex 117691 may 13 15:45 mathstatic

To find out what shared libraries a binary program requires use the 'ldd' command:
[alex@bluefalcon]~/tut $ldd mathdynamic
libm.so.6 => /lib/libm.so.6 (0x40013000)
libc.so.6 => /lib/libc.so.6 (0x4002c000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
[alex@bluefalcon]~/tut $ldd mathstatic
statically linked (ELF)

...And if your libraries are in another directory you can add the "-L/usr/my_weird_directory/" to tell gcc to search libraries in that directory too.

The library concept is very important in Linux programming, but we'll have many occasions to work with it later, so don't worry is it doesn't seems clear.

Last thing:if you prefer c++, just change gcc by g++ in the compile command line (or better, get egcs!).

2.Getting documentation: The man pages.

The man pages are the best friend of the Linux programmer. They provide you a complete documentation on all the functions you have on your system. For example, if you need help on the sqrt function just type:
[alex@bluefalcon]~/tut $man sqrt
Everything is explained: syntax, error codes, include files, library links,... The man pages are very clear and no further explanation should be necessary. You may also find documentation in the /usr/doc directory.

3.The Makefile: The One That Will Save Your Fingers.

The problem is that a big application can have hundreds of .c files and link to a lot of libraries. In some case a compilation line can fill all the screen! Thanks to make and the Makefile you'll not have to type all of this. When you launch "make" it will search for a file named "Makefile":
[alex@bluefalcon]~/tut $make
make: *** No targets. Stop.

For the moment we have no Makefile, so we got this output.
An example:
We'll use 3 .c and 1 .h files, plus a Makefile:

hello.c:
#include <stdio.h>
#include "defines.h"

void say_hello()
{
printf("Hello World! The square root of 2 is %f!\n",sqrt_of(2));
}

math.c:
#include <stdio.h>
#include <math.h>
#include "defines.h"

double sqrt_of(double x)
{
return(sqrt(x));
}

main.c:
#include <stdio.h>
#include <stdlib.h>
#include "defines.h"

int main()
{
say_hello();
return(0);
}

defines.h:
/* Fonctions prototypes to avoid compilation warnings */
void say_hello();
double sqrt_of(double x);

Makefile:
CC=gcc
CFLAGS=-Wall -O6
LIBS=-lm
OBJECTS=math.o hello.o main.o
PROGRAM=hello

all:$(OBJECTS)
        $(CC) $(OBJECTS) $(LIBS) -o $(PROGRAM)

clean:
        rm -rf *.o $(PROGRAM)

Some explanations:

Once you have typed all the files, compile them:
[alex@bluefalcon]~/tut $ls
Makefile defines.h hello.c main.c math.c
[alex@bluefalcon]~/tut $make
gcc -Wall -O6 -c math.c -o math.o
gcc -Wall -O6 -c hello.c -o hello.o
gcc -Wall -O6 -c main.c -o main.o
gcc math.o hello.o main.o -lm -o hello
[alex@bluefalcon]~/tut $ls
Makefile hello hello.o main.o math.o
defines.h hello.c main.c math.c
[alex@bluefalcon]~/tut $./hello
Hello World! The square root of 2 is 1.414214!
[alex@bluefalcon]~/tut $make clean
rm -rf *.o hello
[alex@bluefalcon]~/tut $ls
Makefile defines.h hello.c main.c math.c
[alex@bluefalcon]~/tut $

The last thing to know on make: it can take a "-C <directory>" parameter. This will launch make in the directory you specified, and is very usefull is your program is divided into several directories.

Allright! You have the basics of linux programming! Let's now see more game-specific stuff!

4)The graphics libraries.

On Linux system, the access to video memory is locked to avoid system crash. You can't have direct access to the video memory, unless you are root. All user memory is virtual, the only way for a user to get access to physical memory is via the /dev/mem special device file. For the details about the black magic involved see the LDP publication "The Linux Kernel Hackers Guide" http://www.linuxhq.com/. Most game developers will however only be interested in high level libraries. The advantages are multiple, the main is that the libraries use all your video card acceleration.
There are several way to code graphics:

That's all for this part. Please give me feedback, so I know what should be seen in the next part (I plan to make our first graphic app using svgalib and GGI). If you have problems with this part, please ask questions to GNUrou@linuxfan.com.

Thank you for reading this tutorial.