<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://oldwiki.devbox.themanaworld.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Doener</id>
	<title>The Mana World - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://oldwiki.devbox.themanaworld.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Doener"/>
	<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/wiki/Special:Contributions/Doener"/>
	<updated>2026-05-06T06:13:12Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=User:Doener&amp;diff=8892</id>
		<title>User:Doener</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=User:Doener&amp;diff=8892"/>
		<updated>2008-03-19T21:45:46Z</updated>

		<summary type="html">&lt;p&gt;Doener: Update my jid&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About ==&lt;br /&gt;
Uhm, where to start? Well, my real name is BjÃ¶rn Steinbrink, I&#039;m from Germany and born in 1982 (well, I could just say I&#039;m 23 years old, but that would be outdated so soon ;) ). I got to know about The Mana World in May 2005, when I&#039;ve been (once again) searching for a nice SNES-style RPG that runs on Linux. I wasn&#039;t that much impressed by the game itself, but kept a bookmark as it was the most promising i had seen. Time passed by and I stumbled over a new tmw release, tried it, hit a well known bug and asked on irc about it (just to find the solution in the forums before anyone could answer ;) ). And you know how irc works, right? You start talking to folks who got ideas or find bugs and all of a sudden you find yourself submitting patches... Well, that&#039;s how i got into working on tmw...&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
Mail: B.Steinbrink@gmx.de&amp;lt;br /&amp;gt;&lt;br /&gt;
Jabber: B.Steinbrink@gmx.de&lt;br /&gt;
&lt;br /&gt;
== Questions ==&lt;br /&gt;
Well, nobody asked any questions, yet. Feel free to do add some, maybe I&#039;ll feel free to ignore them, maybe not... ;)&lt;/div&gt;</summary>
		<author><name>Doener</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Development:Animations&amp;diff=3818</id>
		<title>Development:Animations</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Development:Animations&amp;diff=3818"/>
		<updated>2006-03-18T16:52:27Z</updated>

		<summary type="html">&lt;p&gt;Doener: /* Implementation proposal by Doener */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Status_red}}&lt;br /&gt;
After a mini-meeting between me and Doener we refined the model.&lt;br /&gt;
Each animation will be defined by an xml document, here follows an example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;animation name=&amp;quot;player&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;spritemap name=&amp;quot;misc&amp;quot; src=&amp;quot;player-male-misc.png&amp;quot; width=&amp;quot;64&amp;quot; height=&amp;quot;64&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;spritemap name=&amp;quot;stab&amp;quot; src=&amp;quot;player-male-stab.png&amp;quot; width=&amp;quot;64&amp;quot; height=&amp;quot;64&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;spritemap name=&amp;quot;bow&amp;quot; src=&amp;quot;player-male-bow.png&amp;quot; width=&amp;quot;64&amp;quot; height=&amp;quot;64&amp;quot; /&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
	&amp;lt;action name=&amp;quot;stand&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;frame spritemap=&amp;quot;misc&amp;quot; index=&amp;quot;0&amp;quot; delay=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;/action&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
	&amp;lt;action name=&amp;quot;walk&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;frame spritemap=&amp;quot;misc&amp;quot; index=&amp;quot;0&amp;quot; delay=&amp;quot;20&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;frame spritemap=&amp;quot;misc&amp;quot; index=&amp;quot;1&amp;quot; delay=&amp;quot;20&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;/action&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
	&amp;lt;action name=&amp;quot;bow-attack&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;sequence spritemap=&amp;quot;bow&amp;quot; start=&amp;quot;0&amp;quot; end=&amp;quot;5&amp;quot; delay=&amp;quot;20&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;/action&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So if you want to load the playerset you just load player.xml and it takes care of loading all related images. Of course delays are defined in milliseconds.&lt;br /&gt;
&lt;br /&gt;
== Some attempt by BjÃ¸rn ==&lt;br /&gt;
&lt;br /&gt;
A sprite is an object which can carry several animations, hence I call the root element the &amp;lt;code&amp;gt;sprite&amp;lt;/code&amp;gt;. Also, I think we should seperately define animations in several directions. For now this example is based on the current playerset image, but by using multiple imagesets this could of course be split up.&lt;br /&gt;
&lt;br /&gt;
Each &amp;lt;code&amp;gt;frame&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;frames&amp;lt;/code&amp;gt; element can optionally have attributes &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt; to specify an offset from the default drawing position for that frame. This will allow the animation of for example the hairset (or any equipment) to reuse the same frames with different offsets, and be defined exactly like below.&lt;br /&gt;
&lt;br /&gt;
In the bow animation I&#039;ve chosen a shortcut to specify different delays for different frames. I am undecided yet whether this is a nice feature or whether it&#039;ll be better to require multiple &amp;lt;code&amp;gt;frame&amp;lt;/code&amp;gt; elements in such cases.&lt;br /&gt;
&lt;br /&gt;
For the dead frame I have specified no direction attribute, which makes this animation independent of direction. Also, it includes an experimental suggestion on specifying that a random frame should be chosen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;sprite name=&amp;quot;player&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;imageset name=&amp;quot;base&amp;quot; src=&amp;quot;player-male-base.png&amp;quot; width=&amp;quot;64&amp;quot; height=&amp;quot;64&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;animation name=&amp;quot;stand&amp;quot; direction=&amp;quot;down&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;frame imageset=&amp;quot;base&amp;quot; index=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
 &amp;lt;animation name=&amp;quot;stand&amp;quot; direction=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;frame imageset=&amp;quot;base&amp;quot; index=&amp;quot;18&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
 &amp;lt;animation name=&amp;quot;stand&amp;quot; direction=&amp;quot;up&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;frame imageset=&amp;quot;base&amp;quot; index=&amp;quot;36&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
 &amp;lt;animation name=&amp;quot;stand&amp;quot; direction=&amp;quot;right&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;frame imageset=&amp;quot;base&amp;quot; index=&amp;quot;54&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;animation name=&amp;quot;walk&amp;quot; direction=&amp;quot;down&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;frames imageset=&amp;quot;base&amp;quot; start=&amp;quot;1&amp;quot; end=&amp;quot;6&amp;quot; delay=&amp;quot;10&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;animation name=&amp;quot;sit&amp;quot; direction=&amp;quot;down&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;frame imageset=&amp;quot;base&amp;quot; index=&amp;quot;7&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;animation name=&amp;quot;bow-attack&amp;quot; direction=&amp;quot;down&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;frames imageset=&amp;quot;base&amp;quot; start=&amp;quot;13&amp;quot; end=&amp;quot;17&amp;quot; delays=&amp;quot;5,5,5,10,50&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;animation name=&amp;quot;dead&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;random&amp;gt;&lt;br /&gt;
   &amp;lt;frame imageset=&amp;quot;base&amp;quot; index=&amp;quot;8&amp;quot; /&amp;gt;&lt;br /&gt;
   &amp;lt;frame imageset=&amp;quot;base&amp;quot; index=&amp;quot;26&amp;quot; /&amp;gt;&lt;br /&gt;
   &amp;lt;frame imageset=&amp;quot;base&amp;quot; index=&amp;quot;44&amp;quot; /&amp;gt;&lt;br /&gt;
   &amp;lt;frame imageset=&amp;quot;base&amp;quot; index=&amp;quot;62&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;/random&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/sprite&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After reflecting on this idea (and the above suggestion) I think a first issue to solve is to reduce the amount of duplicated definitions. For example, at the moment every monster uses the exact same frame size and animation frames. Hence, it would be interesting if the defined sprite could take the actual imageset it uses as a parameter instead of specifying this on its own. This way we can define a monster like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;sprite name=&amp;quot;monster-walking-default&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;imageset name=&amp;quot;base&amp;quot; /&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/sprite&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;being name=&amp;quot;Scorpion&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;sprite ref=&amp;quot;monster-walking-default&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;with-imageset name=&amp;quot;base&amp;quot; src=&amp;quot;scorpion-base.png&amp;quot; width=&amp;quot;60&amp;quot; height=&amp;quot;60&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/sprite&amp;gt;&lt;br /&gt;
&amp;lt;/being&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;being name=&amp;quot;Red Scorpion&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;sprite ref=&amp;quot;monster-walking-default&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;with-imageset name=&amp;quot;base&amp;quot; src=&amp;quot;scorpion-red-base.png&amp;quot; width=&amp;quot;60&amp;quot; height=&amp;quot;60&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/sprite&amp;gt;&lt;br /&gt;
&amp;lt;/being&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Defining an empty imageset (without &amp;lt;code&amp;gt;src&amp;lt;/code&amp;gt; attribute) will make the engine require this imageset to be passed as a parameter whenever the spriteset is referenced.&lt;br /&gt;
&lt;br /&gt;
I&#039;m not convinced yet that the &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; attribute of the &amp;lt;code&amp;gt;sprite&amp;lt;/code&amp;gt; element is really necessary. I think I would prefer each sprite to be defined in its own file. However it could be attractive to define multiple things in the same file, but in that case I think we will have to read everything when the client is launched, and only graphics and imagesets can be created lazily (only when necessary). Because the other data consists of just numbers and strings, this should not be really a problem.&lt;br /&gt;
&lt;br /&gt;
== An implementation idea by Peoro ==&lt;br /&gt;
&lt;br /&gt;
An idea to manage the animations should be a class based on a timer which choose automatically the current frame.&lt;br /&gt;
Who needs animations (players, monsters and npcs) has only to start the animanion and to request the frame to draw it.&lt;br /&gt;
Each instance of Animation class keep its own start-time (or a personal timer), its total time, number of frames, and the time of every frame.&lt;br /&gt;
The Animation class has to provide at least a function to start the animation and another one to get the current frame; other usefull functions should pause and restart the animation and allow to jump to a random frame.&lt;br /&gt;
&lt;br /&gt;
Here a simple example of a prototype of an Animation class:&lt;br /&gt;
(I mutilated my original Animation class to simplify and summarize it cutting a lot of other functions and vars and using the most possible of standard items)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Animation&lt;br /&gt;
{&lt;br /&gt;
    int nframes;&lt;br /&gt;
    Img **frames;&lt;br /&gt;
    int *times;&lt;br /&gt;
    int totalTime;&lt;br /&gt;
    int startTime;&lt;br /&gt;
    &lt;br /&gt;
public:&lt;br /&gt;
    Animation ( int n, Img **i, int *t )&lt;br /&gt;
    {&lt;br /&gt;
        int c;&lt;br /&gt;
    	&lt;br /&gt;
        nframes = n;&lt;br /&gt;
        frames = new Img* [n];&lt;br /&gt;
        times = new int [n];&lt;br /&gt;
        totalTime = 0;&lt;br /&gt;
        &lt;br /&gt;
        for ( c = 0; c &amp;lt; n; c ++ ) {&lt;br /&gt;
            frames[c] = i[c];&lt;br /&gt;
            times[c] = t[c];&lt;br /&gt;
            totalTime += t[c];&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    inline void start ( int t = clock() )&lt;br /&gt;
    {&lt;br /&gt;
        startTime = t;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    Img *getFrame ( int t = clock() )&lt;br /&gt;
    {&lt;br /&gt;
        int i;&lt;br /&gt;
        int it&lt;br /&gt;
        &lt;br /&gt;
        if ( ! totalTime ) {&lt;br /&gt;
            t = 0;&lt;br /&gt;
        } else {&lt;br /&gt;
            t = (t-startTime) % totalTime;&lt;br /&gt;
        }&lt;br /&gt;
            &lt;br /&gt;
        // searches the current frame&lt;br /&gt;
        for ( i = 0, it = 0; (it + times[i]) &amp;lt; t; i ++, it += times[i] );&lt;br /&gt;
        &lt;br /&gt;
        return frames[i];&lt;br /&gt;
    }&lt;br /&gt;
	&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And here how to use this class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Img * imgs [] = { img1, img2, img3 };&lt;br /&gt;
int times [] = { 20, 20, 30 };&lt;br /&gt;
&lt;br /&gt;
Animation a ( 3, imgs, times );&lt;br /&gt;
&lt;br /&gt;
a.start ( );&lt;br /&gt;
&lt;br /&gt;
while ( 1 ) {&lt;br /&gt;
    draw ( a.getFrame() );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An advantage of this class is that the animation speed is indipendent to FPS and it&#039;s very easy to use.&lt;br /&gt;
&lt;br /&gt;
This is a simple way to manage a lot of animations for who needs more than one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class AnimationsList&lt;br /&gt;
{&lt;br /&gt;
    // ltstr is only a const char* comparison function&lt;br /&gt;
    map&amp;lt;const char*, Animation*, ltstr&amp;gt; animations;&lt;br /&gt;
    int startTime;       // now Animation::startTime is no more usefull&lt;br /&gt;
    Animation *currentAnimation;&lt;br /&gt;
    &lt;br /&gt;
public:&lt;br /&gt;
    AnimationsList ( ) : currentAnimation(0) { }&lt;br /&gt;
    &lt;br /&gt;
    inline void addAnimation ( const char *n, Animation *a )&lt;br /&gt;
    {&lt;br /&gt;
        animations[n] = a;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    int setAnimation ( const char *n, int t = clock() )&lt;br /&gt;
    {&lt;br /&gt;
	map&amp;lt;const char*, Animation*, ltstr&amp;gt;::iterator ai;&lt;br /&gt;
        Animation *a;&lt;br /&gt;
        &lt;br /&gt;
	ai = animations.find ( n );&lt;br /&gt;
	&lt;br /&gt;
	if ( ai == animations.end() ) {&lt;br /&gt;
                // error... animation not found&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
	a = ai-&amp;gt;second;&lt;br /&gt;
        &lt;br /&gt;
        if ( currentAnimation != a ) {&lt;br /&gt;
            a-&amp;gt;start ( );&lt;br /&gt;
            currentAnimation = a;&lt;br /&gt;
            startTime = t;&lt;br /&gt;
	}&lt;br /&gt;
        &lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    Img * getFrame ( )&lt;br /&gt;
    {&lt;br /&gt;
        if ( currentAnimation ) {&lt;br /&gt;
            return currentAnimation-&amp;gt;getFrame ( );&lt;br /&gt;
        }&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using a multimap instead the map it&#039;s possible to keep more than an animation bind to the same string. This would be a good way to make AnimationsList choose a random animation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And here how to use AnimationsList class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
AnimationsList al;&lt;br /&gt;
&lt;br /&gt;
al.addAnimation ( &amp;quot;walking&amp;quot; &amp;quot;south&amp;quot;, anim1 );&lt;br /&gt;
al.addAnimation ( &amp;quot;walking&amp;quot; &amp;quot;north&amp;quot;, anim2 );&lt;br /&gt;
al.addAnimation ( &amp;quot;anim3&amp;quot;, anim3 );&lt;br /&gt;
&lt;br /&gt;
al.setAnimation ( &amp;quot;walking&amp;quot; &amp;quot;south&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
while ( 1 ) {&lt;br /&gt;
    draw ( al.getFrame() );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I hope not to had make a mistake writing... Anyway these are only theorical bases.&lt;br /&gt;
&lt;br /&gt;
== Implementation proposal by Doener ==&lt;br /&gt;
&lt;br /&gt;
This proposal is incomplete regarding how new sequences are added to the&lt;br /&gt;
Animation (which is not the right name for this type of class *g*)... Anyway,&lt;br /&gt;
you should get the idea...&lt;br /&gt;
The Frame class encapsulates images and are used to create a single linked list that&lt;br /&gt;
creates an animation. The idea behind the linked list is that you can easily create loops,&lt;br /&gt;
by having the last element of the animation pointing to the first one. Also, you can easily&lt;br /&gt;
prepend a &amp;quot;starting animation&amp;quot; before the loop, like in an animation of a running player.&lt;br /&gt;
He starts out with one animation and then loops the real running... The Animation class is&lt;br /&gt;
responsible for mapping animation names to their starting frame and for disposing the encapsulating&lt;br /&gt;
Frame objects, thus a std::map and a std::list is used to keep track of those objects.&lt;br /&gt;
The next frame is simply calculated from the time that has passed since the last run of the&lt;br /&gt;
logic method. The case that a whole animation loop can be skipped is not taken into consideration,&lt;br /&gt;
because a) we cannot do this with frames linked together arbitrarily and b) animations will probably&lt;br /&gt;
take around 100ms or longer, ie. we&#039;d have less than 10fps for that case to happen and then &lt;br /&gt;
there&#039;s nothing left to gain by that simple optimization anymore anyway ;)&lt;br /&gt;
&lt;br /&gt;
For the linked list features, of course the xml format needs to be adjusted to support that.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Frame class, stored information about frames in an animation&lt;br /&gt;
 */&lt;br /&gt;
struct Frame&lt;br /&gt;
{&lt;br /&gt;
	Image *mImg;  // Image for this frame&lt;br /&gt;
	int mDelay;   // Time in ms for how long this frame is shown&lt;br /&gt;
	Frame *mNext; // Next frame in sequence&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class Animation&lt;br /&gt;
{&lt;br /&gt;
	public:&lt;br /&gt;
		Animation():mCurrentFrame(0);&lt;br /&gt;
		~Animation();&lt;br /&gt;
&lt;br /&gt;
		void setSequence(const std::string &amp;amp;);&lt;br /&gt;
&lt;br /&gt;
		void logic(int timePassed);&lt;br /&gt;
&lt;br /&gt;
		Image* getCurrentImage()&lt;br /&gt;
			{ return mCurrentFrame ? mCurrentFrame-&amp;gt;mImg : 0; }&lt;br /&gt;
&lt;br /&gt;
	private:&lt;br /&gt;
		Frame *mCurrentFrame;&lt;br /&gt;
		typedef std::map&amp;lt;std::string,Frame*&amp;gt; FrameMap;&lt;br /&gt;
		typedef FrameMap::iterator FrameMapIterator;&lt;br /&gt;
		FrameMap mStartFrames;&lt;br /&gt;
		std::list&amp;lt;Frame*&amp;gt; mFrames;&lt;br /&gt;
		int mRemain;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Animation::~Animation()&lt;br /&gt;
{&lt;br /&gt;
	for_each(mFrames.begin(), mFrames.end(), make_dtor(mFrames));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Animation::setSequence(const std::string &amp;amp;name)&lt;br /&gt;
{&lt;br /&gt;
	FrameMapIterator i = mStartFrames.find(name);&lt;br /&gt;
	mCurrentFrame = (i == mStartFrames.end()) ? 0 : i-&amp;gt;second;&lt;br /&gt;
	mRemain = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Animation::logic(int timePassed)&lt;br /&gt;
{&lt;br /&gt;
	mRemain += timePassed;&lt;br /&gt;
	while (mRemain &amp;gt;= mCurrentFrame-&amp;gt;mDelay) {&lt;br /&gt;
		mRemain -= mCurrentFrame-&amp;gt;mDelay;&lt;br /&gt;
		mCurrentFrame = mCurrentFrame-&amp;gt;mNext;&lt;br /&gt;
	}&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Doener</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Development:Animations&amp;diff=3817</id>
		<title>Development:Animations</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Development:Animations&amp;diff=3817"/>
		<updated>2006-03-18T16:50:53Z</updated>

		<summary type="html">&lt;p&gt;Doener: Added implementation proposal&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Status_red}}&lt;br /&gt;
After a mini-meeting between me and Doener we refined the model.&lt;br /&gt;
Each animation will be defined by an xml document, here follows an example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;animation name=&amp;quot;player&amp;quot;&amp;gt;&lt;br /&gt;
	&amp;lt;spritemap name=&amp;quot;misc&amp;quot; src=&amp;quot;player-male-misc.png&amp;quot; width=&amp;quot;64&amp;quot; height=&amp;quot;64&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;spritemap name=&amp;quot;stab&amp;quot; src=&amp;quot;player-male-stab.png&amp;quot; width=&amp;quot;64&amp;quot; height=&amp;quot;64&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;spritemap name=&amp;quot;bow&amp;quot; src=&amp;quot;player-male-bow.png&amp;quot; width=&amp;quot;64&amp;quot; height=&amp;quot;64&amp;quot; /&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
	&amp;lt;action name=&amp;quot;stand&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;frame spritemap=&amp;quot;misc&amp;quot; index=&amp;quot;0&amp;quot; delay=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;/action&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
	&amp;lt;action name=&amp;quot;walk&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;frame spritemap=&amp;quot;misc&amp;quot; index=&amp;quot;0&amp;quot; delay=&amp;quot;20&amp;quot; /&amp;gt;&lt;br /&gt;
		&amp;lt;frame spritemap=&amp;quot;misc&amp;quot; index=&amp;quot;1&amp;quot; delay=&amp;quot;20&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;/action&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
	&amp;lt;action name=&amp;quot;bow-attack&amp;quot;&amp;gt;&lt;br /&gt;
		&amp;lt;sequence spritemap=&amp;quot;bow&amp;quot; start=&amp;quot;0&amp;quot; end=&amp;quot;5&amp;quot; delay=&amp;quot;20&amp;quot; /&amp;gt;&lt;br /&gt;
	&amp;lt;/action&amp;gt;&lt;br /&gt;
&amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So if you want to load the playerset you just load player.xml and it takes care of loading all related images. Of course delays are defined in milliseconds.&lt;br /&gt;
&lt;br /&gt;
== Some attempt by BjÃ¸rn ==&lt;br /&gt;
&lt;br /&gt;
A sprite is an object which can carry several animations, hence I call the root element the &amp;lt;code&amp;gt;sprite&amp;lt;/code&amp;gt;. Also, I think we should seperately define animations in several directions. For now this example is based on the current playerset image, but by using multiple imagesets this could of course be split up.&lt;br /&gt;
&lt;br /&gt;
Each &amp;lt;code&amp;gt;frame&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;frames&amp;lt;/code&amp;gt; element can optionally have attributes &amp;lt;code&amp;gt;x&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;y&amp;lt;/code&amp;gt; to specify an offset from the default drawing position for that frame. This will allow the animation of for example the hairset (or any equipment) to reuse the same frames with different offsets, and be defined exactly like below.&lt;br /&gt;
&lt;br /&gt;
In the bow animation I&#039;ve chosen a shortcut to specify different delays for different frames. I am undecided yet whether this is a nice feature or whether it&#039;ll be better to require multiple &amp;lt;code&amp;gt;frame&amp;lt;/code&amp;gt; elements in such cases.&lt;br /&gt;
&lt;br /&gt;
For the dead frame I have specified no direction attribute, which makes this animation independent of direction. Also, it includes an experimental suggestion on specifying that a random frame should be chosen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;sprite name=&amp;quot;player&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;imageset name=&amp;quot;base&amp;quot; src=&amp;quot;player-male-base.png&amp;quot; width=&amp;quot;64&amp;quot; height=&amp;quot;64&amp;quot; /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;animation name=&amp;quot;stand&amp;quot; direction=&amp;quot;down&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;frame imageset=&amp;quot;base&amp;quot; index=&amp;quot;0&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
 &amp;lt;animation name=&amp;quot;stand&amp;quot; direction=&amp;quot;left&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;frame imageset=&amp;quot;base&amp;quot; index=&amp;quot;18&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
 &amp;lt;animation name=&amp;quot;stand&amp;quot; direction=&amp;quot;up&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;frame imageset=&amp;quot;base&amp;quot; index=&amp;quot;36&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
 &amp;lt;animation name=&amp;quot;stand&amp;quot; direction=&amp;quot;right&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;frame imageset=&amp;quot;base&amp;quot; index=&amp;quot;54&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;animation name=&amp;quot;walk&amp;quot; direction=&amp;quot;down&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;frames imageset=&amp;quot;base&amp;quot; start=&amp;quot;1&amp;quot; end=&amp;quot;6&amp;quot; delay=&amp;quot;10&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;animation name=&amp;quot;sit&amp;quot; direction=&amp;quot;down&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;frame imageset=&amp;quot;base&amp;quot; index=&amp;quot;7&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;animation name=&amp;quot;bow-attack&amp;quot; direction=&amp;quot;down&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;frames imageset=&amp;quot;base&amp;quot; start=&amp;quot;13&amp;quot; end=&amp;quot;17&amp;quot; delays=&amp;quot;5,5,5,10,50&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;animation name=&amp;quot;dead&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;random&amp;gt;&lt;br /&gt;
   &amp;lt;frame imageset=&amp;quot;base&amp;quot; index=&amp;quot;8&amp;quot; /&amp;gt;&lt;br /&gt;
   &amp;lt;frame imageset=&amp;quot;base&amp;quot; index=&amp;quot;26&amp;quot; /&amp;gt;&lt;br /&gt;
   &amp;lt;frame imageset=&amp;quot;base&amp;quot; index=&amp;quot;44&amp;quot; /&amp;gt;&lt;br /&gt;
   &amp;lt;frame imageset=&amp;quot;base&amp;quot; index=&amp;quot;62&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;/random&amp;gt;&lt;br /&gt;
 &amp;lt;/animation&amp;gt;&lt;br /&gt;
&amp;lt;/sprite&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After reflecting on this idea (and the above suggestion) I think a first issue to solve is to reduce the amount of duplicated definitions. For example, at the moment every monster uses the exact same frame size and animation frames. Hence, it would be interesting if the defined sprite could take the actual imageset it uses as a parameter instead of specifying this on its own. This way we can define a monster like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
&amp;lt;sprite name=&amp;quot;monster-walking-default&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;imageset name=&amp;quot;base&amp;quot; /&amp;gt;&lt;br /&gt;
 ...&lt;br /&gt;
&amp;lt;/sprite&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;being name=&amp;quot;Scorpion&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;sprite ref=&amp;quot;monster-walking-default&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;with-imageset name=&amp;quot;base&amp;quot; src=&amp;quot;scorpion-base.png&amp;quot; width=&amp;quot;60&amp;quot; height=&amp;quot;60&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/sprite&amp;gt;&lt;br /&gt;
&amp;lt;/being&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;being name=&amp;quot;Red Scorpion&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;sprite ref=&amp;quot;monster-walking-default&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;with-imageset name=&amp;quot;base&amp;quot; src=&amp;quot;scorpion-red-base.png&amp;quot; width=&amp;quot;60&amp;quot; height=&amp;quot;60&amp;quot; /&amp;gt;&lt;br /&gt;
 &amp;lt;/sprite&amp;gt;&lt;br /&gt;
&amp;lt;/being&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Defining an empty imageset (without &amp;lt;code&amp;gt;src&amp;lt;/code&amp;gt; attribute) will make the engine require this imageset to be passed as a parameter whenever the spriteset is referenced.&lt;br /&gt;
&lt;br /&gt;
I&#039;m not convinced yet that the &amp;lt;code&amp;gt;name&amp;lt;/code&amp;gt; attribute of the &amp;lt;code&amp;gt;sprite&amp;lt;/code&amp;gt; element is really necessary. I think I would prefer each sprite to be defined in its own file. However it could be attractive to define multiple things in the same file, but in that case I think we will have to read everything when the client is launched, and only graphics and imagesets can be created lazily (only when necessary). Because the other data consists of just numbers and strings, this should not be really a problem.&lt;br /&gt;
&lt;br /&gt;
== An implementation idea by Peoro ==&lt;br /&gt;
&lt;br /&gt;
An idea to manage the animations should be a class based on a timer which choose automatically the current frame.&lt;br /&gt;
Who needs animations (players, monsters and npcs) has only to start the animanion and to request the frame to draw it.&lt;br /&gt;
Each instance of Animation class keep its own start-time (or a personal timer), its total time, number of frames, and the time of every frame.&lt;br /&gt;
The Animation class has to provide at least a function to start the animation and another one to get the current frame; other usefull functions should pause and restart the animation and allow to jump to a random frame.&lt;br /&gt;
&lt;br /&gt;
Here a simple example of a prototype of an Animation class:&lt;br /&gt;
(I mutilated my original Animation class to simplify and summarize it cutting a lot of other functions and vars and using the most possible of standard items)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class Animation&lt;br /&gt;
{&lt;br /&gt;
    int nframes;&lt;br /&gt;
    Img **frames;&lt;br /&gt;
    int *times;&lt;br /&gt;
    int totalTime;&lt;br /&gt;
    int startTime;&lt;br /&gt;
    &lt;br /&gt;
public:&lt;br /&gt;
    Animation ( int n, Img **i, int *t )&lt;br /&gt;
    {&lt;br /&gt;
        int c;&lt;br /&gt;
    	&lt;br /&gt;
        nframes = n;&lt;br /&gt;
        frames = new Img* [n];&lt;br /&gt;
        times = new int [n];&lt;br /&gt;
        totalTime = 0;&lt;br /&gt;
        &lt;br /&gt;
        for ( c = 0; c &amp;lt; n; c ++ ) {&lt;br /&gt;
            frames[c] = i[c];&lt;br /&gt;
            times[c] = t[c];&lt;br /&gt;
            totalTime += t[c];&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    inline void start ( int t = clock() )&lt;br /&gt;
    {&lt;br /&gt;
        startTime = t;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    Img *getFrame ( int t = clock() )&lt;br /&gt;
    {&lt;br /&gt;
        int i;&lt;br /&gt;
        int it&lt;br /&gt;
        &lt;br /&gt;
        if ( ! totalTime ) {&lt;br /&gt;
            t = 0;&lt;br /&gt;
        } else {&lt;br /&gt;
            t = (t-startTime) % totalTime;&lt;br /&gt;
        }&lt;br /&gt;
            &lt;br /&gt;
        // searches the current frame&lt;br /&gt;
        for ( i = 0, it = 0; (it + times[i]) &amp;lt; t; i ++, it += times[i] );&lt;br /&gt;
        &lt;br /&gt;
        return frames[i];&lt;br /&gt;
    }&lt;br /&gt;
	&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
And here how to use this class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Img * imgs [] = { img1, img2, img3 };&lt;br /&gt;
int times [] = { 20, 20, 30 };&lt;br /&gt;
&lt;br /&gt;
Animation a ( 3, imgs, times );&lt;br /&gt;
&lt;br /&gt;
a.start ( );&lt;br /&gt;
&lt;br /&gt;
while ( 1 ) {&lt;br /&gt;
    draw ( a.getFrame() );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An advantage of this class is that the animation speed is indipendent to FPS and it&#039;s very easy to use.&lt;br /&gt;
&lt;br /&gt;
This is a simple way to manage a lot of animations for who needs more than one:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
class AnimationsList&lt;br /&gt;
{&lt;br /&gt;
    // ltstr is only a const char* comparison function&lt;br /&gt;
    map&amp;lt;const char*, Animation*, ltstr&amp;gt; animations;&lt;br /&gt;
    int startTime;       // now Animation::startTime is no more usefull&lt;br /&gt;
    Animation *currentAnimation;&lt;br /&gt;
    &lt;br /&gt;
public:&lt;br /&gt;
    AnimationsList ( ) : currentAnimation(0) { }&lt;br /&gt;
    &lt;br /&gt;
    inline void addAnimation ( const char *n, Animation *a )&lt;br /&gt;
    {&lt;br /&gt;
        animations[n] = a;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    int setAnimation ( const char *n, int t = clock() )&lt;br /&gt;
    {&lt;br /&gt;
	map&amp;lt;const char*, Animation*, ltstr&amp;gt;::iterator ai;&lt;br /&gt;
        Animation *a;&lt;br /&gt;
        &lt;br /&gt;
	ai = animations.find ( n );&lt;br /&gt;
	&lt;br /&gt;
	if ( ai == animations.end() ) {&lt;br /&gt;
                // error... animation not found&lt;br /&gt;
		return 0;&lt;br /&gt;
	}&lt;br /&gt;
	a = ai-&amp;gt;second;&lt;br /&gt;
        &lt;br /&gt;
        if ( currentAnimation != a ) {&lt;br /&gt;
            a-&amp;gt;start ( );&lt;br /&gt;
            currentAnimation = a;&lt;br /&gt;
            startTime = t;&lt;br /&gt;
	}&lt;br /&gt;
        &lt;br /&gt;
        return 1;&lt;br /&gt;
    }&lt;br /&gt;
    &lt;br /&gt;
    Img * getFrame ( )&lt;br /&gt;
    {&lt;br /&gt;
        if ( currentAnimation ) {&lt;br /&gt;
            return currentAnimation-&amp;gt;getFrame ( );&lt;br /&gt;
        }&lt;br /&gt;
        return 0;&lt;br /&gt;
    }&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using a multimap instead the map it&#039;s possible to keep more than an animation bind to the same string. This would be a good way to make AnimationsList choose a random animation.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
And here how to use AnimationsList class:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
AnimationsList al;&lt;br /&gt;
&lt;br /&gt;
al.addAnimation ( &amp;quot;walking&amp;quot; &amp;quot;south&amp;quot;, anim1 );&lt;br /&gt;
al.addAnimation ( &amp;quot;walking&amp;quot; &amp;quot;north&amp;quot;, anim2 );&lt;br /&gt;
al.addAnimation ( &amp;quot;anim3&amp;quot;, anim3 );&lt;br /&gt;
&lt;br /&gt;
al.setAnimation ( &amp;quot;walking&amp;quot; &amp;quot;south&amp;quot; );&lt;br /&gt;
&lt;br /&gt;
while ( 1 ) {&lt;br /&gt;
    draw ( al.getFrame() );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I hope not to had make a mistake writing... Anyway these are only theorical bases.&lt;br /&gt;
&lt;br /&gt;
== Implementation proposal by Doener ==&lt;br /&gt;
&lt;br /&gt;
This proposal is incomplete regarding how new sequences are added to the&lt;br /&gt;
Animation (which is not the right name for this type of class *g*)... Anyway,&lt;br /&gt;
you should get the idea...&lt;br /&gt;
The Frame class encapsulates images and are used to create a single linked list that&lt;br /&gt;
creates an animation. The idea behind the linked list is that you can easily create loops,&lt;br /&gt;
by having the last element of the animation pointing to the first one. Also, you can easily&lt;br /&gt;
prepend a &amp;quot;starting animation&amp;quot; before the loop, like in an animation of a running player.&lt;br /&gt;
He starts out with one animation and then loops the real running... The Animation class is&lt;br /&gt;
responsible for mapping animation names to their starting frame and for disposing the encapsulating&lt;br /&gt;
Frame objects, thus a std::map and a std::list is used to keep track of those objects.&lt;br /&gt;
The next frame is simply calculated from the time that has passed since the last run of the&lt;br /&gt;
logic method. The case that a whole animation loop can be skipped is not taken into consideration,&lt;br /&gt;
because a) we cannot do this with frames linked together arbitrarily and b) animations will probably&lt;br /&gt;
take around 100ms or longer, ie. we&#039;d have less than 10fps for that case to happen and then &lt;br /&gt;
there&#039;s nothing left to gain by that simple optimization anymore anyway ;)&lt;br /&gt;
&lt;br /&gt;
For the linked list features, of course the xml format needs to be adjusted to support that.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
 * Frame class, stored information about frames in an animation&lt;br /&gt;
 */&lt;br /&gt;
struct Frame&lt;br /&gt;
{&lt;br /&gt;
	Image *mImg;  // Image for this frame&lt;br /&gt;
	int mDelay;   // Time in ms for how long this frame is shown&lt;br /&gt;
	Frame *mNext; // Next frame in sequence&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
class Animation&lt;br /&gt;
{&lt;br /&gt;
	public:&lt;br /&gt;
		Animation():mCurrentFrame(0);&lt;br /&gt;
		~Animation();&lt;br /&gt;
&lt;br /&gt;
		void setSequence(const std::string &amp;amp;);&lt;br /&gt;
&lt;br /&gt;
		void logic(int timePassed);&lt;br /&gt;
&lt;br /&gt;
		Image* getCurrentImage()&lt;br /&gt;
			{ return mCurrentFrame ? mCurrentFrame-&amp;gt;mImg : 0; }&lt;br /&gt;
&lt;br /&gt;
	private:&lt;br /&gt;
		Frame *mCurrentFrame;&lt;br /&gt;
		typedef std::map&amp;lt;std::string,Frame*&amp;gt; FrameMap;&lt;br /&gt;
		typedef FrameMap::iterator FrameMapIterator;&lt;br /&gt;
		FrameMap mStartFrames;&lt;br /&gt;
		std::list&amp;lt;Frame*&amp;gt; mFrames;&lt;br /&gt;
		int mRemain;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
Animation::~Animation()&lt;br /&gt;
{&lt;br /&gt;
	for_each(mFrames.begin(), mFrames.end(), make_dtor(mFrames));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Animation::setSequence(const std::string &amp;amp;name)&lt;br /&gt;
{&lt;br /&gt;
	FrameMapIterator i = mStartFrames.find(name);&lt;br /&gt;
	mCurrentFrame = (i == mStartFrames.end()) ? 0 : i-&amp;gt;second;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void Animation::logic(int timePassed)&lt;br /&gt;
{&lt;br /&gt;
	mRemain += timePassed;&lt;br /&gt;
	while (mRemain &amp;gt;= mCurrentFrame-&amp;gt;mDelay) {&lt;br /&gt;
		mRemain -= mCurrentFrame-&amp;gt;mDelay;&lt;br /&gt;
		mCurrentFrame = mCurrentFrame-&amp;gt;mNext;&lt;br /&gt;
	}&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Doener</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:System_requirements&amp;diff=3423</id>
		<title>Archive:System requirements</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:System_requirements&amp;diff=3423"/>
		<updated>2006-01-20T17:43:49Z</updated>

		<summary type="html">&lt;p&gt;Doener: /* Performance chart */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== General guideline ==&lt;br /&gt;
&lt;br /&gt;
The system requirements of TMW, as with any game, hugely depend on the kind of framerate you want. In general, you should be fine with a more or less recent (year 2001 and later) 3D accelerator card when running the OpenGL version. The software/SDL version probably heavily depends on your processor speed.&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Processor:&#039;&#039;&#039; 1 Ghz&lt;br /&gt;
* &#039;&#039;&#039;Memory:&#039;&#039;&#039; 64 MB&lt;br /&gt;
* &#039;&#039;&#039;Hard disk:&#039;&#039;&#039; ~25 MB&lt;br /&gt;
* &#039;&#039;&#039;Operating system:&#039;&#039;&#039; Windows, GNU/Linux or MacOS X&lt;br /&gt;
&lt;br /&gt;
== Performance chart ==&lt;br /&gt;
&lt;br /&gt;
Here is a list of systems and the respective framerate with TMW. Feel free to add a line of your own, add comments if you like or necessary. We need especially more data about FPS on lower end machines, and it would also be nice to see changes in framerate on the same machine with different versions of TMW.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot; width=&amp;quot;100%&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
! style=&amp;quot;background:#efdead;&amp;quot; | Name&lt;br /&gt;
! style=&amp;quot;background:#efdead;&amp;quot; | Processor&lt;br /&gt;
! style=&amp;quot;background:#efdead;&amp;quot; | Memory&lt;br /&gt;
! style=&amp;quot;background:#efdead;&amp;quot; | Video&amp;amp;nbsp;Card&lt;br /&gt;
! style=&amp;quot;background:#efdead;&amp;quot; | OS&lt;br /&gt;
! style=&amp;quot;background:#efdead;&amp;quot; | TMW&amp;amp;nbsp;Version&lt;br /&gt;
! style=&amp;quot;background:#efdead;&amp;quot; | Frame&amp;amp;nbsp;Rate&lt;br /&gt;
! style=&amp;quot;background:#efdead;&amp;quot; | Comments&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | DeveloperX&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | AMD K6-2 550 Mhz&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 640 MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | GF 2MX 32 MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | WinXP Pro&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0.0.13&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 3 to 7&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; rowspan=&amp;quot;3&amp;quot; | [[User:BjÃ¸rn|BjÃ¸rn]]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; rowspan=&amp;quot;3&amp;quot; | AthlonXP 1.6&lt;br /&gt;
| align=&amp;quot;center&amp;quot; rowspan=&amp;quot;3&amp;quot; | 512 MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | GF 2MX 64 MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; rowspan=&amp;quot;3&amp;quot; | ArchLinux/2.6&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 04/07/2005-OpenGL&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 50&lt;br /&gt;
| align=&amp;quot;center&amp;quot; rowspan=&amp;quot;3&amp;quot; | Windowed&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Radeon&amp;amp;nbsp;8500&amp;amp;nbsp;(fglrx)&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 07/14/2005-OpenGL&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 200+&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Radeon&amp;amp;nbsp;8500&amp;amp;nbsp;(ati)&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 10/26/2005-OpenGL&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 170&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [[User:ampersand|ampersand]]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Pentium III 1GHz&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 256 MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | ATI Mobility&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | SuSE 9.2&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0.0.13&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 26-45&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Shura&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | AthlonXP 1.8&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 512 MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | GF FX5200 64 MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | ArchLinux/2.6&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 12/20/2004&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 52&lt;br /&gt;
| makefile.static (performance CXXFLAGS) / GCC 3.4.3 - Allegro 4.1.17&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Sull&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | AthlonXP 1.5&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 386 MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | GF TI4200 64 MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Gentoo-2.6&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 12/17/2004&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 40&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Neko-mon&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Athlon64 3&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 512 MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | GF 4 440 MX 64 MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | WinXP Prof.&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 12/17/2004&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 67&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; rowspan=&amp;quot;2&amp;quot;| [[User:ElvenProgrammer|ElvenProgrammer]]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Pentium4 2.53&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 512 MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | ATI 9200se 128 MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | WinXP Home SP2&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 8/21/2005&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 76&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 67 to 76 thanks to Doener&#039;s patch&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | AthlonXP&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 256 MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | ATI 9200gp 64 MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | WinXP Home SP2&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 5/30/2005&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 52&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Up to 60 fps with OpenGL&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; rowspan=&amp;quot;4&amp;quot; | [[User:Javila|Javila]]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; rowspan=&amp;quot;4&amp;quot; | Duron 800MHz&lt;br /&gt;
| align=&amp;quot;center&amp;quot; rowspan=&amp;quot;4&amp;quot; | 640 MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; rowspan=&amp;quot;4&amp;quot; | nVidia TNT2 32 MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; rowspan=&amp;quot;4&amp;quot; | Slackware 10.0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0.0.12-SDL&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 07&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0.0.12-OpenGL&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 30&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 05/05/2005-OpenGL&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 33&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Windowed (up to 35 fps in fullscreen)&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 07/15/2005-OpenGL&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 40&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Windowed (up to 45 fps in fullscreen)&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [[User:Maci|maci]]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | AMD Athlon(tm) XP 2400+&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1024 MB DDR 400&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | nVidia GeForce 6600GT&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | GNU/Linux&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 13/7/2005-OpenGL&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 560+&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Windowed&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [[User:Modanung|Modanung]]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | AthlonXP 1.6&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 512 MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | ATI Radeon 9800 Pro&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | WinXP Prof.&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 5/1/2005-OpenGL&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 300+&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Windowed&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [[User:Kaxero|Kaxero]]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Pentium4 Mobile 1.7Ghz&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 512 MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | GeForce4 440Go 32Mb&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | WinXP Prof. SP2&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0.0.13&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 45-50&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Windowed&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | hStorm&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | AMD K6-2 550Mhz&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 320 MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | GeForce2 MX400 64Mb&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Windows 98&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0.0.13-OpenGL&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 10-23&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [[User:Lunpa|Lunpa]]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | AMD Athlon MP 1Ghz&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 512 MB (+ 8GB swap)&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Nvidia FX5200 256Mb&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Gentoo GNU/linux (don&#039;t look at me!)&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0.0.14.1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 50ish&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Windowed, running with two monitors.&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [[User:Crush|Crush]]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | AMD Athlon XP 2400+&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 256 MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | nVidia GeForce2 MX400 32MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Windows XP Prof&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0.0.16&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 75&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Windowed, OpenGL enabled&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [[User:KaTSuo|KaTSuo]]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | AMD Athlon XP 2000+&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 512 MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Radeon 8500 64MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Windows XP, SP-2&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0.0.15&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 80&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Windowed&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | [[User:Maniac|Maniac]]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | AMD Athlon XP 1600+&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 768 MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | nVidia GeForce4 TI4200 64MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Windows 2000&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0.0.17&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 350+&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Windowed, OpenGL enabled&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; rowspan=&amp;quot;2&amp;quot;| [[User:Burger|Burger]]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; rowspan=&amp;quot;2&amp;quot;| AMD Athlon 64 3200+&lt;br /&gt;
| align=&amp;quot;center&amp;quot; rowspan=&amp;quot;2&amp;quot;| 1024 MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; rowspan=&amp;quot;2&amp;quot;| nVidia GeForce 6800GT 256MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; rowspan=&amp;quot;2&amp;quot;| Windows XP, SP-2&lt;br /&gt;
| align=&amp;quot;center&amp;quot; rowspan=&amp;quot;2&amp;quot;| 0.0.17&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 85&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Windowed, OpenGL enabled, 85Hz&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 700+&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Windowed, OpenGL enabled, without vsync&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; rowspan=&amp;quot;2&amp;quot;| [[User:Doener|Doener]]&lt;br /&gt;
| align=&amp;quot;center&amp;quot; rowspan=&amp;quot;2&amp;quot;| AMD Athlon 64 X2 4400+&lt;br /&gt;
| align=&amp;quot;center&amp;quot; rowspan=&amp;quot;2&amp;quot;| 2048 MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; rowspan=&amp;quot;2&amp;quot;| nVidia GeForce 6600 256MB&lt;br /&gt;
| align=&amp;quot;center&amp;quot; rowspan=&amp;quot;2&amp;quot;| Gentoo Linux - Kernel 2.6.15&lt;br /&gt;
| align=&amp;quot;center&amp;quot; rowspan=&amp;quot;2&amp;quot;| 0.0.18.1+ (cvs)&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 300-600 (depends on number of in-game windows)&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | Windowed, OpenGL enabled&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Doener</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=User:Doener&amp;diff=2248</id>
		<title>User:Doener</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=User:Doener&amp;diff=2248"/>
		<updated>2005-07-30T12:26:41Z</updated>

		<summary type="html">&lt;p&gt;Doener: /* Contact */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About ==&lt;br /&gt;
Uhm, where to start? Well, my real name is BjÃ¶rn Steinbrink, I&#039;m from Germany and born in 1982 (well, I could just say I&#039;m 23 years old, but that would be outdated so soon ;) ). I got to know about The Mana World in May 2005, when I&#039;ve been (once again) searching for a nice SNES-style RPG that runs on Linux. I wasn&#039;t that much impressed by the game itself, but kept a bookmark as it was the most promising i had seen. Time passed by and I stumbled over a new tmw release, tried it, hit a well known bug and asked on irc about it (just to find the solution in the forums before anyone could answer ;) ). And you know how irc works, right? You start talking to folks who got ideas or find bugs and all of a sudden you find yourself submitting patches... Well, that&#039;s how i got into working on tmw...&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
Mail: B.Steinbrink@gmx.de&amp;lt;br /&amp;gt;&lt;br /&gt;
Jabber: doener@jabber.ccc.de&lt;br /&gt;
&lt;br /&gt;
== Questions ==&lt;br /&gt;
Well, nobody asked any questions, yet. Feel free to do add some, maybe I&#039;ll feel free to ignore them, maybe not... ;)&lt;/div&gt;</summary>
		<author><name>Doener</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=User:Doener&amp;diff=587</id>
		<title>User:Doener</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=User:Doener&amp;diff=587"/>
		<updated>2005-07-30T12:25:39Z</updated>

		<summary type="html">&lt;p&gt;Doener: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== About ==&lt;br /&gt;
Uhm, where to start? Well, my real name is BjÃ¶rn Steinbrink, I&#039;m from Germany and born in 1982 (well, I could just say I&#039;m 23 years old, but that would be outdated so soon ;) ). I got to know about The Mana World in May 2005, when I&#039;ve been (once again) searching for a nice SNES-style RPG that runs on Linux. I wasn&#039;t that much impressed by the game itself, but kept a bookmark as it was the most promising i had seen. Time passed by and I stumbled over a new tmw release, tried it, hit a well known bug and asked on irc about it (just to find the solution in the forums before anyone could answer ;) ). And you know how irc works, right? You start talking to folks who got ideas or find bugs and all of a sudden you find yourself submitting patches... Well, that&#039;s how i got into working on tmw...&lt;br /&gt;
&lt;br /&gt;
== Contact ==&lt;br /&gt;
Mail: B.Steinbrink@gmx.de&lt;br /&gt;
Jabber: doener@jabber.ccc.de&lt;br /&gt;
&lt;br /&gt;
== Questions ==&lt;br /&gt;
Well, nobody asked any questions, yet. Feel free to do add some, maybe I&#039;ll feel free to ignore them, maybe not... ;)&lt;/div&gt;</summary>
		<author><name>Doener</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Rendering&amp;diff=2207</id>
		<title>Archive:Rendering</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Archive:Rendering&amp;diff=2207"/>
		<updated>2005-07-12T17:23:22Z</updated>

		<summary type="html">&lt;p&gt;Doener: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I&#039;m not sure if i got the current rendering approach right, so feel free to &lt;br /&gt;
correct (or flame) me ;)&lt;br /&gt;
&lt;br /&gt;
Currently, all rendering happens in Image::draw(), this is a simple approach&lt;br /&gt;
that works, but it has some drawbacks. Model and view are combined in the same&lt;br /&gt;
class, this makes it hard to implement different approaches for different&lt;br /&gt;
graphic libraries (SDL vs. OpenGL in this case). There&#039;s also a tight coupling&lt;br /&gt;
between the Image class and various other classes that could be avoided.&lt;br /&gt;
&lt;br /&gt;
Actually the SubImage class just abstracts from drawing a part of a bigger image,&lt;br /&gt;
it does not really contain a SubImage. This is used to simplify the drawing code in&lt;br /&gt;
other places, but places an important constraint on the way how rendering can be done.&lt;br /&gt;
As the drawing code is in the (Sub)Image class, rendering happens on a image-by-image&lt;br /&gt;
basis. OpenGL suffers a lot from this, as the repeated glBegin()/glEnd() calls cause&lt;br /&gt;
some overhead, one should always try to send as much data at once as possible.&lt;br /&gt;
&lt;br /&gt;
To improve the situation, especially with OpenGL, I&#039;d suggest the following, based on&lt;br /&gt;
how the Map would handle the new stuff.&lt;br /&gt;
&lt;br /&gt;
Tilesets are indexed like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
1 2 3 4 &lt;br /&gt;
5 6 7 8&lt;br /&gt;
9 x x x&lt;br /&gt;
x x x x&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead of having a lot of Images in the Map, it is associated with a tileset and has&lt;br /&gt;
a set of indices into the tileset.&lt;br /&gt;
&lt;br /&gt;
That way, a rendering class could get the right x,y values inside the tileset with a&lt;br /&gt;
simple calculation based on tileset&#039;s tile-width, tile-height, row-width and the index&lt;br /&gt;
into the tileset.&lt;br /&gt;
&lt;br /&gt;
For a SDLRenderer, this would probably just end up in copying the SubImage::draw()&lt;br /&gt;
code and having the above calculation, as the &#039;draw a part of a larger image&#039; code is&lt;br /&gt;
already there.&lt;br /&gt;
&lt;br /&gt;
For a OpenGLRenderer, it would like a little different, a vertex array could be prepared&lt;br /&gt;
beforehand, as the vertex positions will never change, only the textures. For the texture,&lt;br /&gt;
there would be a prepared array of coordinates into the tileset texture for each tileset that&lt;br /&gt;
is being used. That way the indices stored in the map could probably directly be sent to opengl&lt;br /&gt;
to render the map (I need to read up on glDrawElements to actually confirm that).&lt;br /&gt;
&lt;br /&gt;
So the rendering code for the SDL part would just be moved around a little and separated from the&lt;br /&gt;
data structures (i.e. quite a trivial change). The OpenGL code would get quite some change for the&lt;br /&gt;
better, as the separation of image and map data allows a quite better handling of this stuff.&lt;br /&gt;
&lt;br /&gt;
PS: I hope anyone understands what I&#039;m trying to say, I feel like unable to speak english today...&lt;/div&gt;</summary>
		<author><name>Doener</name></author>
	</entry>
	<entry>
		<id>https://oldwiki.devbox.themanaworld.org/index.php?title=Main_Page&amp;diff=542</id>
		<title>Main Page</title>
		<link rel="alternate" type="text/html" href="https://oldwiki.devbox.themanaworld.org/index.php?title=Main_Page&amp;diff=542"/>
		<updated>2005-07-12T16:51:59Z</updated>

		<summary type="html">&lt;p&gt;Doener: Added RFC section under development&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;text-align: center; margin: 20px; font-style: italic;&amp;quot;&amp;gt;Welcome to The Mana World wiki! This wiki is meant to provide information to our players, to provide an easy way to contribute to the development of certain parts of the game and to improve collaboration between people on the development team. We hope you will find what you are looking for. To be able to edit you have to login, but signing up is free and requires no activation.&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| cellspacing=&amp;quot;3&amp;quot; cellpadding=&amp;quot;5&amp;quot; width=&amp;quot;100%&amp;quot;&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot; &lt;br /&gt;
|width=&amp;quot;50%&amp;quot; style=&amp;quot;border: 1px solid #e0c8b8; color: #000; background-color: #faeee6&amp;quot;|&lt;br /&gt;
&amp;lt;h2&amp;gt;Project information&amp;lt;/h2&amp;gt;&lt;br /&gt;
* [[Project description]]&lt;br /&gt;
* [[Developers]]&lt;br /&gt;
* [[FAQ]]&lt;br /&gt;
* [[Dependencies]]&lt;br /&gt;
* [[System requirements]]&lt;br /&gt;
* [[Roadmap]]&lt;br /&gt;
* [[Ports]]&lt;br /&gt;
* [http://cvs.sourceforge.net/viewcvs.py/themanaworld/tmw/ChangeLog?rev=HEAD&amp;amp;view=markup Change log]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h4&amp;gt;References&amp;lt;/h4&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[Guilds]]&lt;br /&gt;
* [[Monster reference]]&lt;br /&gt;
* [[Item reference]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h4&amp;gt;Organization&amp;lt;/h4&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* [[Suggestions]]&lt;br /&gt;
* [http://themanaworld.org/archive/galerie.php Gallery]&lt;br /&gt;
* [[Developer meetings]]&lt;br /&gt;
* [[Quotes]]&lt;br /&gt;
* &#039;&#039;&#039;[[Summer 2005 real life developer meeting]]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
|width=&amp;quot;50%&amp;quot; style=&amp;quot;border: 1px solid #c9c9ff; color: #000; background-color: #f3f3ff&amp;quot;|&lt;br /&gt;
&amp;lt;h2&amp;gt;Development&amp;lt;/h2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;World&#039;&#039;&#039;&lt;br /&gt;
:[[World development]], [[World backstory]], [[Map development]], [[Landmarks]], [[Kingdoms]], [[Important NPCs]], [[Finished NPCs]], [[Quest development|Quests]], [[Calendar]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Graphics&#039;&#039;&#039;&lt;br /&gt;
:[[Guidelines]], [[Concept art]], [[Tileset development|Tilesets]], [[Playerset development|Playerset]], [[NPC development|NPCs]], [[Monsterset development|Monsters]], [[Hairset development|Hairsets]], [[Itemset development|Itemsets]], [[Equipment development|Equipment]], [[:Special:Newimages|New images gallery]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;GUI&#039;&#039;&#039;&lt;br /&gt;
:[[GUI development]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Sound&#039;&#039;&#039;&lt;br /&gt;
:[[SFX]], [[Music]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Game&#039;&#039;&#039;&lt;br /&gt;
:[[Game systems]], [[Update system]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Server&#039;&#039;&#039;&lt;br /&gt;
:[[Server development]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;RFCs&#039;&#039;&#039;&lt;br /&gt;
:[[Rendering]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Doener</name></author>
	</entry>
</feed>