4 Copyright (C) 2001 Alexandre Courbot
5 Copyright (C) 2001 Kai Sterker
6 Part of the Adonthell Project http://adonthell.linuxgames.com
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY.
13 See the COPYING file for more details.
17 \page page1 Introduction for new programmers
20 Adonthell makes intense use of the features of C++ whenever they make the code
21 clearer and easier and do not slow things down too much. Adonthell tries to
22 respect the concepts of Object Oriented Programming as much as possible. In
23 Adonthell, everything is an %object and inheritance and templates are used
24 where appropriate. Attributes are usually hidden and may only be accessed
25 through an %object's methods.
27 Further, Adonthell makes heavy use of the Standard Template Library (STL)
28 (http://www.sgi.com/tech/stl/), especially of strings and containers
29 like lists and hash maps. So you'll certainly want to give it a look.
31 \section python Python
32 In many kinds of computer games, including RPGs, a script language is necessary to command
33 characters, build complex actions, cutscenes, etc... As we want modularity and
34 reusability, in-%game actions must be real-time interpreted. Scripts need to
35 interact with the C++ interface and of course they have to share variables with it.
36 Python (http://www.python.org) has proven to be very efficient at both -
37 moreover it is an object-oriented language and therefore fits well with C++.
38 And with SWIG (http://www.swig.org), a great tool is available to automate the
39 process of building the Python interface to our C++ classes.
40 Basically, each class and method described in this document is also available
41 from Python scripts, with only a few exceptions:
42 Python allows no method and operator overloading, so only the first of
43 overloaded methods or constructors and no operators are accessible from
46 \section scorg Source code organisation
47 Adonthell makes use of autoconf and automake to be built. In each subdirectory
48 resides a Makefile.am file that containes the building rules for the files inside
49 that directory as well as its subdirectories. Running "automake" in the root
50 directory creates a Makefile.in from each Makefile.am. "autoconf" builds the
51 configure script from configure.in. Finally, running "./configure" generates
52 all the Makefiles from the Makefile.ins, making the package ready for
53 compilation via "make".
55 Here is what the source tree does look like:
57 - doc The user and developer documentation
58 - src Source code for Adonthell engine - this is where the adonthell executable is built
59 - tools Various development tools
60 - dlgedit The dialogue editor (requires GTK+)
61 - charedit The character editor (requires GTK+)
62 - questedit The quest editor (requires GTK+)
63 - maptools The map building tools
64 - pydonthell A custom Python interpreter with Adonthell Python modules inside
65 - oggloop Ogg music looping utility
67 Each class that is documented here is usually defined by classname.h and
68 implemented by classname.cc.
70 \section datatypes Data types
71 Adonthell can run on several platforms, which all have different characteristics.
72 One of these differences can reside in the way the basic C types (char, ints, ...)
73 are encoded. A 32 bit operating system will code it's ints with 32 bits, while a
74 64 bits operating system will use 64 bits for ints. For several operations (like
75 reading an int from a file) this can result in different behavior, and catastrophic
76 consequences (most likely a protection fault). That's why some of the most basic
77 types have been redifined according to the architecture in types.h:
78 - u_int8: unsigned 8 bit integer
79 - s_int8: signed 8 bit integer
80 - u_int16: unsigned 16 bit integer
81 - s_int16: signed 16 bit integer
82 - u_int32: unsigned 32 bit integer
83 - s_int32: signed 32 bit integer
85 \section gamedyn Game dynamic
86 As we display animated things, we need to know when they have to change. A %game that
87 runs at a different speed on various machines has nearly no interest, as only
88 a few configurations can make it run at the right speed. So it's very important
89 to have a timing system built into the %game engine.
91 Adonthell uses it's own timing system. The time unit is the %game cycle, which
92 corresponds to approximatively 1/70 of second. When the %game runs, it performs
93 a loop which looks like this:
96 while(<condition to quit the engine>)
100 for(i=0;i<gametime::get_frames_to_do();i++)
102 <update the %game status (%character positions, etc...)>
105 <perform drawing operations>
111 This loop performs what is necessary to update the %screen. Depending on the speed
112 of the CPU, this can take more or less time. You've seen that a %game cycle durate
113 1/70 of a second. For some machines, this is not enough to perform the entire loop.
115 As you've seen, there are two kinds of operations that are in the loop:
117 \li Update operations, which actually update the state of the %game, according to
118 user %input, previous %game state, etc... These operations are very fast to
121 \li Drawing operations, that is, update the %screen. This is what may slow
122 things down. Some graphic boards simply can't redraw the entire %screen 70
123 times per second. Moreover, even with high-end boards, hardware acceleration may
124 not be used depending on the SDL target used. x11 is know to be unable to use
125 hardware acceleration, while fbcon does, when possible.
127 So the solution to keep the %game running at the same speed on every machine is to
128 draw less frames per second on slow machines (instead of drawing 1 frame every %game
129 cycle, we'll draw one frame for 2 %games cycles, for example). This is where
130 gametime is usefull: The gametime::update() method calculates the delay between
131 the last call and the current call. It can then calculate if we've been late, and
132 catch the time back by telling to the other %objects that we must perform 2 %games
133 cycles instead of 1 to be sync (this is the result of the gametime::get_frames_to_do()
134 method). For example, if the last loop took 1/35 of a second to be completed,
135 gametime::get_frames_to_do() will return 2, so the loop will perform 2 %game updates
136 before drawing the %screen. On the contrary, if the machine is too fast (if it can
137 draw 2 frames for each %game cycle, for example), it will usleep() to stay in sync.
139 In a more general manner, every class that get's updated and draw something on
140 the %screen MUST have an update() method, that updates it's state once, and a
141 draw() method to draw it on the %screen.