Index: branches/network/AUTHORS
===================================================================
--- branches/network/AUTHORS	(revision 6636)
+++ branches/network/AUTHORS	(revision 6636)
@@ -0,0 +1,9 @@
+orxonox-crew: <orxonox-dev@mail.datacore.ch>
+
+Patrick Boenzli <patrick@orxonox.ethz.ch>
+Benjamin Grauer <bensch@orxonox.ethz.ch>
+Simon Hofmann
+David Gruetter
+Johannes Bader
+Adrian Buerli
+Christian Meyer
Index: branches/network/CODING-STANDARDS
===================================================================
--- branches/network/CODING-STANDARDS	(revision 6636)
+++ branches/network/CODING-STANDARDS	(revision 6636)
@@ -0,0 +1,184 @@
+CODING-STANDARTS FOR ORXONOX
+-==============--==---+++++-
+In this file it is described how a orxonox-developer should structure his code.
+Every developer has to read it and follow the rules, and orxonox will grow.
+
+Contents:
+---------
+1.Coding Conventions
+2.How to format your Code
+3.Example
+
+1.Coding Conventions
+====================
+==> If you are beginning a new code-file: copy the proto_class.{cc,h}
+==> and work with these files.
+
+1.1.What has to be there:
+-------------------------
+  a) in every code file, there must be a GNU copyright header.
+
+  b) under the (c) header write your name as main-programmer, if
+     you are just bugfixing or extending write it under co-programmer.
+
+  c) Every element of the must be documented with doxygen-tags.
+
+1.2.Doxygen Tags:
+-----------------
+Doxygen tags in general are comments inside a file, that look just a bit different.
+most of the time they extend the /* or // with a second star or a !
+
+  a) h-files: 
+   1) every h-file you want to be documented you have to tag. (tag looks like /*! \file somefile */ )
+   2) every class has to be Documented. ( //! what it does)
+   3) special variables can be documented. ( //!< wow this member is cool because )
+
+  b) cc-files:
+   1) all the methods must be documented, and all their parameters and return value must be covered.
+
+  c) look out for this: Doxygen parses preprocessor arguments,
+     so if some comments is excluded by a #ifdef, #endif 
+     doxygen will not parse it. And ther will be nothing in the docu.
+
+
+2.How to format your Code
+=========================
+We use the GNU conding convention (which is also used in xemacs etc.):
+
+-- Put a space after every comma.
+-- Put a space before the parenthesis that begins a function call,
+   macro call, function declaration or definition, or control
+   statement (if, while, switch, for). (DO NOT do this for macro
+   definitions; this is invalid preprocessor syntax.)
+-- The brace that begins a control statement (if, while, for, switch,
+   do) or a function definition should go on a line by itself.
+-- In function definitions, put the return type and all other
+   qualifiers on a line before the function name.  Thus, the function
+   name is always at the beginning of a line.
+-- Indentation level is two spaces.  (However, the first and following
+   statements of a while/for/if/etc. block are indented four spaces
+   from the while/for/if keyword.  The opening and closing braces are
+   indented two spaces.)
+-- Variable and function names should be all lowercase, with underscores
+   separating words, except for a prefixing tag, which may be in
+   uppercase.  Do not use the mixed-case convention (e.g.
+   SetVariableToValue ()) and *especially* do not use Microsoft
+   Hungarian notation (char **rgszRedundantTag).
+-- preprocessor and enum constants should be all uppercase, and should
+   be prefixed with a tag that groups related constants together.
+
+
+
+
+3.Example
+=========
+3.1.Header
+----------
+A standard header has the same name as the Class it handles.
+
+someclass.h
+-----------
+/*!
+  \file someclass.h
+  \brief Some short description of the someclass
+  \todo maybe there remains something to do in this entire file
+
+  Here comes a longer description
+  this can also be longer than one line
+*/
+
+#ifndef _SOMECLASS_H
+#define _SOMECLASS_H
+
+#include <many_headers>
+#include "stdincl.h"
+
+//! short description of the class
+/**
+  \todo what remains to be done here
+
+   longer description
+*/
+class SomeClass
+{
+  private:
+   int usefull_variable;
+   int cool_variable; //!< this variable is cool, because...
+
+  protected:
+    char* someOtherMember;
+
+  public:
+   SomeClass (void);
+   ~SomeClass (void);
+   
+   int mightyFunction (char* name, int value);
+//....
+};
+
+#endif /* _SOMECLASS_H */
+
+
+
+3.2.CC-Files
+------------
+CC-files must be named the same as the .h-files they belong to.
+
+someclass.cc
+------------
+
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: The Name of Myself
+   co-programmer: ...
+*/
+
+#include "someclass.h"
+
+
+/**
+   \brief <a brief description>
+   \todo I think you get it.
+
+   <more description>
+*/
+SomeClass::SomeClass (void)
+{
+   //constructor-stuff
+}
+
+/**
+   \brief <a brief description>
+   \todo if something is not destructed it will be here
+
+   <more description>
+*/
+~SomeClass::~SomeClass (void)
+{
+  //destroy all te allocated space of the Class
+}
+
+/**
+   \brief <a brief description>
+   \param name <what is this parameter for>
+   \param valuse <what for...>
+   \returns <what it returns>
+
+   <more description>
+*/
+int SomeClass::mightyFuncion (char* name, int value)
+{
+  this->coolVariable = value;
+  // and so on.....
+}
+
+// ...
Index: branches/network/COPYING
===================================================================
--- branches/network/COPYING	(revision 6636)
+++ branches/network/COPYING	(revision 6636)
@@ -0,0 +1,340 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the 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, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  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 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) 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.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  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, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part 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 to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also 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
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    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
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is 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.
+
+  8. 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 who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation 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 of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, 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 sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+                            NO WARRANTY
+
+  11. 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.
+
+  12. 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.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
Index: branches/network/ChangeLog
===================================================================
--- branches/network/ChangeLog	(revision 6636)
+++ branches/network/ChangeLog	(revision 6636)
@@ -0,0 +1,186 @@
+2005-12-10	Benjamin Grauer <bensch@orxonox.net>
+	Implemented LOD (level of detail)
+	Implemented it through loading of Objects
+
+
+2005-11-20      Benjamin Grauer <bensch@orxonox.net>
+        Implemented a new Class: Executor
+        This is an abstract Superclass, that is able to execute any function with parameters.
+        Used it in LoadParam and ShellCommand so far.
+
+2005-09-24      Benjamin Grauer <bensch@orxonox.net>
+        Finished implementing the Shell.
+
+2005-09-20      orxonox <info@orxonox.net>
+        Begin of Valgrind cleanup.
+
+2005-08-16      orxonox <info@orxonox.net>
+        Realesed 0.3.1_alpha, on the grounds of collision detection
+        Working on a Windows-Realease...
+
+2005-08-16      Patrick Boenzli <boenzli@orxonox.net>
+        Integrated the collision detection into the orxonox framework. It
+        bases on object-oriented-bounding boxes. The tree is spawned out of
+        any polygon soup.
+
+2005-08-15      Benjamin Grauer <bensch@orxonox.net>
+        Reimplemented the IniParser.
+        Now it is possible, to read and write with it, in an easy c++ style.
+        Performance update due to preparsing.
+
+2005-08-14      Benjamin Grauer <bensch@orxonox.net>
+        Enhanced PNode, SmoothPNode, softReparenting, better display.
+        Major Speed-update to Vector and Quaternion.
+
+2005-07-23      Benjamin Grauer <bensch@orxonox.net>
+        Reimplemeted the ObjectManager, and the GarbageCollector.
+        Features:
+        modularity: easily adding new Creatable Classes through
+        the Factory-style.
+        Faster algorithm in the GarbageCollector, that only checks collectables.
+
+2005-07-23      Patrick Boenzli <boenzli@orxonox.net>
+        Implemented a spatial separation algorithm that separates any polygon
+        soup into a quadtree. The tree leafs are hold in a hash table for
+        fast lookup.
+
+2005-07-14      Benjamin Grauer <bensch@orxonox.net>
+        Implementd Render2D and Element2D, that handles 2D-shapes overlay
+        This is a new Engine, enabling us to render to layers.
+
+2005-07-01      Benjamin Grauer <bensch@orxonox.net>
+        Implemented ClassList.h:
+        an interface to BaseObject saving all instances in Lists.
+        It also enables loadability-identifiers.
+        To decide is, if this approach is fast enough.
+
+2005-06-20      Patrick Boenzli <patrick@orxonox.net>
+        Implemented an OBB collision detection system, injected into the
+        WorldEntity framework. Object - Object Collision Detection works
+        fine. Still work on the Object - Ground CD.
+
+2005-06-10      Benjamin Grauer <bensch@orxonox.net>
+        Established a try on class-derivation and isA function.
+
+2005-06-09      orxonox <info@orxonox.net>
+        created new Tag 0.3.0-pre-alpha
+
+2005-06-04      Benjamin Grauer <bensch@orxonox.net>
+        Merged the SoundEngine (openAL-version) into the trunk
+        this is one of the major steps up to version 0.3-pre-alpha
+
+2005-06-03      Benjamin Grauer <bensch@orxonox.net>
+        Implemented cycling loading procedures used for
+        the TrackManager and Animations
+
+2005-06-01      orxonox <info@orxonox.net>
+        serious cleanup of most files
+        design and doxygen tags
+        deleted old unused fucntions
+
+2005-05-30      Patrick Boenzli <patrick@oroxnox.ethz.ch>
+        Implemented new EventSystem for orxonox
+        Highly advanced, and much faster.
+
+2005-05-27      Benjamin Grauer <bensch@orxonox.net>
+        Intorducing new Subprojects with a new modular framework.
+        Introducing ParticlesFun
+        Introducing new Importer (this was easy :))
+
+2005-05-10      Benjamin Grauer <bensch@orxonox.net>
+        Merged the gui into the executable
+        Windows compiles again.
+
+2005-04-27      orxonox <info@orxonox.net>
+        Tagged Version 0.2.3-pre-alpha
+
+2005-04-23      Patrick Boenzli <patrick@orxonox.net>
+        Finished most work on Animation-classes
+
+2005-04-21      Benjamin Grauer <bensch@orxonox.net>
+        Material Class update: possibility for transparency.
+
+2005-04-15      Patrick Boenzli <partick@orxonox.net>
+        Added AnimationPlayer and two animation classes.
+
+2005-04-07      Patrick Boenzli <patrick@orxonox.net>
+        Reimplemeted the Weapon and shoot-functions
+
+2005-03-31      Benjamin Grauer <bensch@orxonox.net>
+        Added Text Engine
+
+2005-03-26      Benjamin Grauer <bensch@orxonox.net>
+        Added ResourceManager
+
+2005-03-24      Patrick Boenzli <patrick@orxonox.net>
+        Reimplemented shooting.
+
+2005-03-16      orxonox <info@orxonox.net>
+        Finished work on version 0.2.1-pre-alpha released 0.2.2-pre-alpha
+
+2005-03-15      Patrick Boenzli <patrick@orxonox.net>
+        parenting finished
+
+2005-03-09      Patrick Boenzli <patrick@orxonox.net>
+        Big Cleanup again
+
+2005-03-01      Benjamin Grauer <bensch@orxonox.net>
+        Added Light Class
+
+2005-02-27      Benjamin Grauer <bensch@orxonox.net>
+        Big Configure.ac-cleanup
+
+2005-02-22      David Gruetter <davgr@gmx.ch>
+        Added Skysphere
+
+2005-01-07      Patrick Boenzli <patrick@orxonox.net>
+        LoadScreen implemented
+
+2004-12-20      Patrick Boenzli <patrick@orxonox.net>
+        New Version out 0.2.1-pre-alpha
+
+2004-12-20      Patrick Boenzli <patrick@orxonox.net>
+        HEAVY cleanup of the framework
+
+2004-12-18      Patrick Boenzli <patrick@orxonox.net>
+        enhanced the Command Node
+
+2004-12-15      Nico Benold <bernoldn@ee.ethz.ch>
+        OS X support
+
+2004-12-15      Benjamin Grauer <bensch@orxonox.net>
+        Defined standard coding rules
+
+2004-12-15      Benjamin Grauer <bensch@orxonox.net>
+        Added Importer for showing 3D Object.
+
+2004-11-07      David Gruetter <davgr@gmx.ch>
+        Shaded Terrain
+
+2004-10-23      Adrian Buerli <buerlia@ee.ethz.ch>
+        Dynamic Mountains, dynamic movement.
+
+2004-10-18      Patrick Boenzli <patrick@orxonox.net>
+        Release 0.1-pre-alpha
+
+2004-07-17      Christian Meyer <cmeyer@ee.ethz.ch>
+        SDL-Framework
+
+2004-06-09      Tom of ethz
+        Added endless Mountains
+
+2004-06-02      Benjamin Grauer <bensch@orxonox.net>
+        Added Console
+
+2004-05-20      Patrick Boenzli <patrick@orxonox.net>
+        Added the ability to shoot
+
+2004-05-05      Benjamin Grauer <bensch@orxonox.net>
+        Added the GUI.
+
+2004-04-21      Patrik Boenzli <patrick@orxonox.net>
+        Added Makefile to orxonox
+
+2004-04-25      Amir Guindehi <amir@guindehi.ch>
+        Created Project orxonox.
+        Thanks a lot.
Index: branches/network/IDEAS
===================================================================
--- branches/network/IDEAS	(revision 6636)
+++ branches/network/IDEAS	(revision 6636)
@@ -0,0 +1,9 @@
+
+
+all: fill in your ideas here!
+
+- Spacecraft transformations
+- weather influences: fog, rain, sun, wind
+- team play: fight with team-mates
+- RPG style: intelligence, constitution, force/power
+
Index: branches/network/INSTALL
===================================================================
--- branches/network/INSTALL	(revision 6636)
+++ branches/network/INSTALL	(revision 6636)
@@ -0,0 +1,280 @@
+
+INSTALLATION INSTRUCTIONS FOR ORXONOX
+=====================================
+
+INSTALLATION
+============
+
+To make it quite easy for those of you who just want to install orxonox:
+
+1. ./configure
+2. make
+3. make install
+
+(Further Information please see below at autoconf information)
+
+DEPENDENCIES
+============
+
+There are some dependencies for orxonox you have to install:
+
+01. SDL           (http://www.libsdl.org)
+02. OPENGL        (http://www.opengl.org)
+03. OPENAL        (http://www.openal.org)
+04. SDL_image     (http://www.libsdl.org/projects/SDL_image)
+05. SDL_ttf       (http://www.libsdl.org/projects/SDL_ttf)
+ a) needs libttf (http://www.freetype.org/)
+
+Nice to Have:
+06. Doxygen       (http://www.stack.nl/~dimitri/doxygen/)
+07. Automake      (http://www.gnu.org/software/automake/)
+08. Autoconf      (http://www.gnu.org/software/autoconf/)
+
+Windows Users also need the following:
+09. mingw         (http://mingw.org/)
+
+10. more answers to your questions can be found under section
+    wiki on our webpage http://www.orxonox.net
+
+BUGS
+====
+Send bug reports to <orxonox-dev@mail.datacore.ch>
+
+
+
+
+ORXONOX->
+##########################################################
+                                                <-AUTOCONF
+
+
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
+Foundation, Inc.
+
+   This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+   These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+   Some systems require unusual options for compilation or linking that
+the `configure' script does not know about.  Run `./configure --help'
+for details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+   You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory.  After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+   By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PATH'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PATH', the package will use
+PATH as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=PATH' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+   Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+   There may be some features `configure' cannot figure out
+automatically, but needs to determine by the type of machine the package
+will run on.  Usually, assuming the package is built to be run on the
+_same_ architectures, `configure' can figure that out, but if it prints
+a message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the `--target=TYPE' option to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+   If you want to set default values for `configure' scripts to share,
+you can create a site shell script called `config.site' that gives
+default values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+   Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+will cause the specified gcc to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+`configure' Invocation
+======================
+
+   `configure' recognizes the following options to control how it
+operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
Index: branches/network/MakeMakefile
===================================================================
--- branches/network/MakeMakefile	(revision 6636)
+++ branches/network/MakeMakefile	(revision 6636)
@@ -0,0 +1,66 @@
+#!/bin/sh
+#
+# Run this script after the first cvs checkout to build
+# makefiles and friends
+
+vcheck (){
+  perl <<PERL
+@t = split /\./, "$1";
+@v = map { int \$_ } split /\./, (split /\s+/, \`$2\`)[3];
+print "$2 = ", (join ".",@v), "  (expected $1)\n";
+\$v = \$t[0]*1000000+\$t[1]*1000+\$t[2] <= \$v[0]*1000000+\$v[1]*1000+\$v[2];
+exit \$v
+PERL
+}
+
+ERROR=0
+
+if vcheck 1.5.14 "libtool --version"
+then
+  echo "get a copy of GNU libtool >= 1.5.14"
+  ERROR=1
+fi
+
+if vcheck 1.9.5  "automake  --version"
+then
+  if vcheck 1.9.5  "automake-1.9 --version"
+  then
+    echo "get a copy of GNU automake >= 1.9.5"
+    ERROR=1
+  else
+    automake=automake-1.9
+    aclocal="aclocal-1.9  --acdir=/usr/share/aclocal-1.9 -I /usr/share/aclocal/"
+  fi
+else
+    automake="automake"
+    aclocal="aclocal"
+#    aclocal="aclocal -I /usr/pack/libtool-1.5.14-to/share/aclocal"
+fi
+
+if vcheck 2.59 "autoconf --version"
+then
+  echo "get a copy of GNU autoconf >= 2.59"
+  ERROR=1
+fi
+
+if [ $ERROR -ne 0 ]
+then
+  exit 1
+fi
+
+# cleanup
+set -x
+find . -name Makefile | xargs rm -f _UNKNONW_
+find . -name "*.la" | xargs rm -f
+find . -name Makefile.in | xargs rm -f _UNKNONW_
+find . -name .libs | xargs rm -r 
+find . -name .debs | xargs rm -r
+
+$aclocal
+libtoolize --copy --force
+autoheader --warnings=all --force  
+$aclocal
+$automake --foreign --add-missing --force-missing --copy --warnings=all
+autoconf --warnings=all --force
+# one again to make every body happy
+autoreconf
Index: branches/network/Makefile.am
===================================================================
--- branches/network/Makefile.am	(revision 6636)
+++ branches/network/Makefile.am	(revision 6636)
@@ -0,0 +1,29 @@
+AUTOMAKE_OPTIONS = foreign no-installman no-installinfo
+
+SUBDIRS = src
+
+EXTRA_DIST = CODING-STANDARDS \
+             IDEAS \
+             NEWS \
+             doc/CREDITS \
+             doc/doxyconf/build \
+             doc/doxyconf/confopts \
+             doc/doxyconf/input \
+             doc/doxyconf/preprocessor \
+             doc/doxyconf/progress \
+             doc/doxyconf/project
+
+## doxygen stuff
+if DOXYGEN
+DOXYGEN_INPUT = "src"
+
+## Exclude the application wizard templates, and some file templates
+DOXYGEN_EXCLUDE =
+
+DOXYGEN_EXAMPLE_PATH =
+
+## Use Search engine (Versions 1.3.4 and above only!)
+DOXYGEN_SEARCHENGINE = YES
+
+include doc/documentation.am
+endif
Index: branches/network/NEWS
===================================================================
--- branches/network/NEWS	(revision 6636)
+++ branches/network/NEWS	(revision 6636)
@@ -0,0 +1,88 @@
+Date: Dez 23, 2005
+Topic: Christmas
+Body: Tschingel your bells, and shoot some stuff in our new ORXONOX-CHRISTMAS-EDITION-LEVEL. All you Windows gamers find the newest Binary version <a href="http://www.orxonox.net/files/snapshots/orxonox-win32-latest.zip">here</a>. For all the others, have a good holyday, and so long. (PS: to change into the new level push 'x', and to change the vehicle push 'l' (like L))
+
+Date: Dez 17, 2005
+Topic: New Drum'n'Bass Tunes in Development
+Body: They are two men from London, and their mission is to make drum'n'bass tunes: shiv&incey! And now, they want to make some massive rolling tunes for Orxonox! Check out <a href="http://www.aurorasoftware.co.uk/s&i/shiv&incey.htm">their homepage</a>. We are looking forward to the sounds; greetings to London from Switzerland!
+
+Date: Dez 05, 2005
+Topic: Homepage Corrections
+Body: Simon did take some time to read through our webpage and corrected all the english errors he found. Thanks!
+
+Date: Okt 19, 2005
+Topic: Biggest debug session ever in orxonox
+Body: We spent a lot of time to debugging Orxonox engine. Thanks to <a href="http://www.valgrind.org">valgrind</a> :D. Orxonox now plays again on Linux, OSX and Windows!
+
+Date: Sept 05, 2005
+Topic: Integrated a expendable shell
+Body: Now orxonox has a shell, similar to the quake shell... just cooler... You can directly interface the orxonox API through the shell as described in <a href="https://www.orxonox.net/cgi-bin/trac.cgi/wiki/Shell">the ShellDocumentatioWiki</a>. And yes, we will implement our first cheats like invulnerability :D
+
+Date: Aug 14, 2005
+Topic: Implemented and finaly integrated the collision detection algorithm
+Body: This was some hard work... but it now is part of orxonox: object-object collision detection. Now is the time, to shoot other the Enemies! enjoy!
+
+Date: July 21, 2005
+Topic: new domain is registered <a href="http://www.orxonox.net">www.orxonox.net</a>
+Body: Finally we have our own domain for orxonox: <a href="http://www.orxonox.net">http://www.orxonox.net</a>
+
+Date: June 25, 2005
+Topic: orxonox development for win32-patch
+Body: Included the major libraries and tool to develop orxonox on win32 to the webdev repository. Now one might download everything from <a href="http://svn.orxonox.ethz.ch/webdev/develop/">http://svn.orxonox.ethz.ch/webdev/develop/</a>
+
+Date: June 25, 2005
+Topic: Big demo in physically-based animations
+Body: on Monday we have a big demo on orxonox's physical capabilities. We will show some major new features like the ParticleEngine, the PhysicsInterface, and last but not least the longly expected CollisionDetection. Of course all the new Features are in the new trunk, and are downloadable at the  <a href="/files/snapshots">snapshot-section</a>.
+
+Date: June 09, 2005
+Topic: tag 0.3.0-pre-alpha released
+Body: new Tag release. visit the <a href="/files/snapshots">snapshot-section</a> for more detail.
+
+Date: June 04, 2005
+Topic: SoundEngine
+Body: just merged the SoundEngine into the project. This is a major step toward a new aera, of interaction, because it really gets the player a feeling, of what is happening. check <a href="https://www.orxonox.ethz.ch/cgi-bin/trac.cgi/wiki/SoundEngine">this</a> link for a description on how to use it.
+
+Date: June 01, 2005
+Topic: New Features
+Body: Orxonox now supports the MD2Model. We have implemented a physics engine and a particle system.
+
+Date: May 28, 2005
+Topic: Webpage Update
+Body: We did remaster our webpage, take a look at the new <a href="index?site=screenShots">screenshots gallery</a> and make a <a href="index?site=voting">vote</a>.
+
+Date: March 05, 2005
+Topic: Orxonox Convention 2005
+Body: We are going to make a new Convention, that you are all invited to. Visit the convention section for more details. <A href="http://www.orxonox.ethz.ch/index.php?site=conventions">link.</A>
+
+Date: February 21, 2005
+Topic: New Webpage Release
+Body: We are proud to announce our new webpage. Thanks to nico and his php skills :)
+
+Date: December 14, 2004
+Topic: Repository Moved
+Body: Today we moved the repository. The new location of the repository is <A href="https://svn.orxonox.ethz.ch/reporx">http://svn.orxonox.ethz.ch/reporx</A>.
+
+Date:   November 16, 2004
+Topic:  Importer
+Body:   There now exists a possibility to import .obj-files (alias wavefront format) into the Game. You can find some test models here: <A href="/files/models">models</a>. You can also test them with the included importer which is locates in trunk/importer. enjoy.
+
+Date:   June 22, 2004
+Topic:  Develop on Win32 - bg
+Body:   Now the moment you have all been waiting for has arrived. Orxonox can finally be compiled on Windows machines. We know that it is no good idea to do this, but since there are some people interessted in working with Windows, we will give you a chance: read <A href = "/index.php?site=additional.sites/howto.dev.win/howto.dev.win.cc.php" >the manual </A>.
+
+Date:   June 04, 2004
+Topic:  Orxonox Convention - pb
+Body:   Here you can find all the information you need, to join us at the <A href="index.php?site=additional.sites/convention01/convention01.php"> Orxonox Convention </A>, that takes Place at Stuz June 9. 2004.
+
+Date:   June 04, 2004
+Topic:  Manual for Subversion@DataCore.ch
+Body:   A manual for <A href="/files/subversion/subversion.pdf"> Subversion at DataCore</A> is made. Now we need someone, to correct all the errors. Please someone Checkout the Source of this at http://orxonox.ethz.ch/repos/latex/subversion an do the repairs.
+
+Date:   June 02, 2004
+Topic:  New homepage released - pb
+Body:   New homepage released, thanks to the power of subversion. And thanks to the VSETH to give us webspace on their server
+
+Date:   May 26, 2004
+Topic:  New ship models - bg
+Body:   Some new space models are now ready for download. You'll find them in the download section or try it <A href="/files/orx_pictures.tar.bz2">here</A>
+
Index: branches/network/README
===================================================================
--- branches/network/README	(revision 6636)
+++ branches/network/README	(revision 6636)
@@ -0,0 +1,138 @@
+
+This is the offical README file for the game project
+
+--------------------------------------------------------
+                       orxOnox
+--------------------------------------------------------
+
+
+
+
+1.Preface:
+----------
+Orxonox is a open-source vertical scroller game programed
+in c++ and OpenGL.
+If we manage to be sober enough, this game shall definitly
+become _the_ open-source vertical scroller ever.
+
+2.Manifesto:
+------------
+1) Alien is a great film
+2) Guiness is the most delicious beer
+3) If you think there is anything missing specialy in terms of story: you can be shure it's an arcade game
+4) Wanna chill: ask Boozoo Bajou
+
+to be continoued...
+
+
+3.Overview:
+---------
+1.Preface
+2.Manifesto
+3.Overview
+3.Contributing To The Project
+4.Howto C++ Programming
+5.Howto SVN
+6.Coding conventions
+
+
+4.Contributing To The project:
+------------------------------
+People who want to help us working on orxonox are always
+welcome:) Feel free to chip in anything you like. Wine, beer,
+coffee... If you like to help us programming orxonox, you:
+- join the developer community mailing lists
+- read this README file
+then you have multiple ways to get started.
+a) Read the hole source code and choose a topic you like
+b) check the TODO file to get a knowledge of what we need
+c) ask us for more information
+To get more informations about programming and project specs
+read the programming sections below.
+
+To start programming on orxonox you first have to download the
+newest svn tree of orxonox. You can do this by enterning following
+lines in the linux console (ensure svn to be installed with ssl
+support enabled):
+
+svn co https://svn.orxonox.net/reporx/orxonox orxonox
+
+If you haven't got ssl support in you svn tool, recompile it
+./configure --with-ssl
+make
+make install
+
+
+5.Howto C++ Programming:
+------------------------
+If you are new to c/c++ programming, this project is probably
+not the best starting place to learn it. For you and the rest who
+need "refreshment" check out these guides:
+
+www.cplusplus.com/doc/tutorial
+www.4p8.com/eric.brasseur/cppcen.html
+
+
+6.Howto SVN:
+------------
+For a more complete guide about this topic read the documentation
+avaiable at subversion.tigris.org.
+
+SVN (=subversion) is a version control program similar to CVS but
+newer. This program enables us to work all at the same program at
+the same time - tricky.
+
+subversion checkout https://svn.orxonox.net/reporx/orxonox orxonox
+same as: subversion co https://svn.orxonox.net.....
+
+this makes a directory orxonox at your current place in and gets
+the hole brand new source code from the server.
+
+now you can work. Remember to use 'svn copy instead of 'cp',
+'svn mv' instead of 'mv', 'svn rm' instead of 'rm'... - you got it
+I think.
+After you have made your changes to the files enter
+svn status
+or with more details: svn status -vv
+which will show you the changes you did locally on your computer.
+svn diff
+is similar but shows you all the changes in detail.
+
+svn diff > patchfile
+the patchfile you can use later in conjunction with the patch program.
+You could, for example, email this patchfile to another developer for
+review or testing prior to commit.
+
+To add a new file type
+svn add <filename>
+and to publish all your changes type
+svn commit --message "Corrected number of chees slices."
+svn commit will send all of your changs to the repository. When you
+commit a change, you need to supply a log message, describing your
+change. The message can also be read from a file:
+svn commit --file logmsg
+
+If you accidently make a change you like to revert, you just can do this
+by typing:
+svn revert <filename>
+
+To keep track about the work that is running on the project use the
+command: svn log. This will show you a bref summary of all changes.
+
+
+Most of the programmer will do their work on a branch. A Branch is
+a line of development that exists independently of another line, yet
+still shares a common history. A branch always begins life as a copy
+of something, and moves on trom there, generating its own history. Later
+the two versions will merge.
+
+If you are working on orxonox you will have your own branch in which you
+will program, some sort of sand-box. If you finish your work on your
+topic, it will be revised by us and merged with the trunk
+
+7.Coding Conventions
+--------------------
+Read the File CODING-STANDARDS
+
+
+#EOF
Index: branches/network/ToDo
===================================================================
--- branches/network/ToDo	(revision 6636)
+++ branches/network/ToDo	(revision 6636)
@@ -0,0 +1,24 @@
+ToDo:
+-----
+There are many tasks still open in orxonox.
+
+1. TASKS
+--------
+Best idea is, to visit our Webpage at: http://www.orxonox.net and
+under the wiki link follow RoadMap, and from there on you will find many tasks
+or just use this link:
+https://www.orxonox.net/cgi-bin/trac.cgi/roadmap
+
+2. ToDo-list
+------------
+see the Doxygen documetation for a List of todo's
+or visit the Code, you have with you (or a more actual version found at
+http://svn.orxonox.net/reporx/orxonox/trunk) for all the ToDo's
+The easiest way to find ToDo's is to make the following in the trunk:
+grep @todo * -R
+
+3. FIXME
+--------
+They can be found with
+grep FIXME * -R
+in the trunk.
Index: branches/network/acinclude.m4
===================================================================
--- branches/network/acinclude.m4	(revision 6636)
+++ branches/network/acinclude.m4	(revision 6636)
@@ -0,0 +1,45 @@
+
+
+dnl AX_CHECK_HEADER_LIB([HEADER-NAME], [LIBRARY-NAME], [FUNCTION-IN-LIB], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], [LIB-WEB-PAGE])
+AC_DEFUN([AX_CHECK_HEADER_LIB], [
+    _header_check=""
+    _lib_check=""
+
+    AC_CHECK_HEADER([$1], [_header_check="yes"], [_header_check="no"])
+    AC_CHECK_LIB([$2], [$3], [_lib_check="yes"], [_lib_check="no"])
+    if [test "x$_header_check" = "xyes" && test "x$_lib_check" = "xyes"] ; then
+         LIBS="$LIBS -l$2"
+	 $4
+    else
+         echo "no Support for $2"
+	 $5
+    fi
+])
+
+
+
+dnl AX_CHECK_REQUIRED_HEADER_LIB([HEADER-NAME], [LIBRARY-NAME], [FUNCTION-IN-LIB], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND], [LIB-WEB-PAGE])
+AC_DEFUN([AX_CHECK_REQUIRED_HEADER_LIB], [
+    _header_check=""
+    _lib_check=""
+
+    for _header in $1
+    do
+      AC_CHECK_HEADER([$_header], [_header_check="yes"], [_header_check="no"])
+      if  test "x$_header_check" = "xyes" ; then
+        break
+      fi
+    done
+    AC_CHECK_LIB([$2], [$3], [_lib_check="yes"], [_lib_check="no"])
+    if [test x$_header_check = "xyes" && test "x$_lib_check" = "xyes"] ; then
+         LIBS="$LIBS -l$2"
+	 $4
+    else
+         echo "------------------"
+         echo "LIBRARY $2 not found."
+         echo "please install the $2-LIBRARY-package which can be found at $6"
+         echo "------------------"
+	 $5
+         exit -1
+    fi
+])
Index: branches/network/autogen.sh
===================================================================
--- branches/network/autogen.sh	(revision 6636)
+++ branches/network/autogen.sh	(revision 6636)
@@ -0,0 +1,62 @@
+#!/bin/sh
+
+#SETUP_GETTEXT=./setup-gettext
+
+#($SETUP_GETTEXT --gettext-tool) < /dev/null > /dev/null 2>&1 || {
+#	echo;
+#	echo "You must have gettext installed to compile orxonox";
+#	echo;
+#	exit;
+#}
+
+#(libtoolize --version) < /dev/null > /dev/null 2>&1 || {
+#	echo;
+#	echo "You must have libtool installed to compile orxonox";
+#	echo;
+#	exit;
+#}
+
+(automake --version) < /dev/null > /dev/null 2>&1 || {
+	echo;
+	echo "You must have automake installed to compile orxonox";
+	echo;
+	exit;
+}
+
+(autoconf --version) < /dev/null > /dev/null 2>&1 || {
+	echo;
+	echo "You must have autoconf installed to compile orxonox";
+	echo;
+	exit;
+}
+
+echo "Generating configuration files for orxonox, please wait...."
+echo;
+
+# Backup the po/ChangeLog. This should prevent the annoying
+# gettext ChangeLog modifications.
+
+#cp -p po/ChangeLog po/ChangeLog.save
+#echo "Running gettextize, please ignore non-fatal messages...."
+#$SETUP_GETTEXT
+#echo "Running libtoolize, please ignore non-fatal messages...."
+#echo n | libtoolize --copy --force || exit;
+
+# Add other directories to this list if people continue to experience
+# brokennesses ...  Obviously the real answer is for them to fix it
+# themselves, but for Luke's sake we have this.
+#for dir in "/usr/local/share/aclocal" \
+#           "/opt/gnome-1.4/share/aclocal"
+#do
+#	if test -d $dir ; then
+#		ACLOCAL_FLAGS="$ACLOCAL_FLAGS -I $dir"
+#	fi
+#done
+
+#aclocal $ACLOCAL_FLAGS -I ./m4 || exit;
+aclocal-1.9 || aclocal || exit;
+autoheader || exit;
+automake-1.9 --add-missing --copy || automake --add-missing --copy;
+autoconf || exit;
+automake-1.9 || automake || exit;
+#./configure $@
Index: branches/network/config.guess
===================================================================
--- branches/network/config.guess	(revision 6636)
+++ branches/network/config.guess	(revision 6636)
@@ -0,0 +1,1459 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+timestamp='2005-02-10'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Per Bothner <per@bothner.com>.
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# This script attempts to guess a canonical system name similar to
+# config.sub.  If it succeeds, it prints the system name on stdout, and
+# exits with 0.  Otherwise, it exits with 1.
+#
+# The plan is that this can be called by configure scripts if you
+# don't specify an explicit build system type.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help" >&2
+       exit 1 ;;
+    * )
+       break ;;
+  esac
+done
+
+if test $# != 0; then
+  echo "$me: too many arguments$help" >&2
+  exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,)    echo "int x;" > $dummy.c ;
+	for c in cc gcc c89 c99 ; do
+	  if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+	     CC_FOR_BUILD="$c"; break ;
+	  fi ;
+	done ;
+	if test x"$CC_FOR_BUILD" = x ; then
+	  CC_FOR_BUILD=no_compiler_found ;
+	fi
+	;;
+ ,,*)   CC_FOR_BUILD=$CC ;;
+ ,*,*)  CC_FOR_BUILD=$HOST_CC ;;
+esac ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+	PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null`  || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+    *:NetBSD:*:*)
+	# NetBSD (nbsd) targets should (where applicable) match one or
+	# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
+	# *-*-netbsdecoff* and *-*-netbsd*.  For targets that recently
+	# switched to ELF, *-*-netbsd* would select the old
+	# object file format.  This provides both forward
+	# compatibility and a consistent mechanism for selecting the
+	# object file format.
+	#
+	# Note: NetBSD doesn't particularly care about the vendor
+	# portion of the name.  We always set it to "unknown".
+	sysctl="sysctl -n hw.machine_arch"
+	UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
+	    /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
+	case "${UNAME_MACHINE_ARCH}" in
+	    armeb) machine=armeb-unknown ;;
+	    arm*) machine=arm-unknown ;;
+	    sh3el) machine=shl-unknown ;;
+	    sh3eb) machine=sh-unknown ;;
+	    *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+	esac
+	# The Operating System including object format, if it has switched
+	# to ELF recently, or will in the future.
+	case "${UNAME_MACHINE_ARCH}" in
+	    arm*|i386|m68k|ns32k|sh3*|sparc|vax)
+		eval $set_cc_for_build
+		if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+			| grep __ELF__ >/dev/null
+		then
+		    # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+		    # Return netbsd for either.  FIX?
+		    os=netbsd
+		else
+		    os=netbsdelf
+		fi
+		;;
+	    *)
+	        os=netbsd
+		;;
+	esac
+	# The OS release
+	# Debian GNU/NetBSD machines have a different userland, and
+	# thus, need a distinct triplet. However, they do not need
+	# kernel version information, so it can be replaced with a
+	# suitable tag, in the style of linux-gnu.
+	case "${UNAME_VERSION}" in
+	    Debian*)
+		release='-gnu'
+		;;
+	    *)
+		release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
+		;;
+	esac
+	# Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+	# contains redundant information, the shorter form:
+	# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+	echo "${machine}-${os}${release}"
+	exit 0 ;;
+    amd64:OpenBSD:*:*)
+	echo x86_64-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    amiga:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    cats:OpenBSD:*:*)
+	echo arm-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    hp300:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    luna88k:OpenBSD:*:*)
+    	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mac68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    macppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme68k:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvme88k:OpenBSD:*:*)
+	echo m88k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    mvmeppc:OpenBSD:*:*)
+	echo powerpc-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sgi:OpenBSD:*:*)
+	echo mips64-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    sun3:OpenBSD:*:*)
+	echo m68k-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:OpenBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:ekkoBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+	exit 0 ;;
+    macppc:MirBSD:*:*)
+	echo powerppc-unknown-mirbsd${UNAME_RELEASE}
+	exit 0 ;;
+    *:MirBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+	exit 0 ;;
+    alpha:OSF1:*:*)
+	case $UNAME_RELEASE in
+	*4.0)
+		UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+		;;
+	*5.*)
+	        UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+		;;
+	esac
+	# According to Compaq, /usr/sbin/psrinfo has been available on
+	# OSF/1 and Tru64 systems produced since 1995.  I hope that
+	# covers most systems running today.  This code pipes the CPU
+	# types through head -n 1, so we only detect the type of CPU 0.
+	ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^  The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+	case "$ALPHA_CPU_TYPE" in
+	    "EV4 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV4.5 (21064)")
+		UNAME_MACHINE="alpha" ;;
+	    "LCA4 (21066/21068)")
+		UNAME_MACHINE="alpha" ;;
+	    "EV5 (21164)")
+		UNAME_MACHINE="alphaev5" ;;
+	    "EV5.6 (21164A)")
+		UNAME_MACHINE="alphaev56" ;;
+	    "EV5.6 (21164PC)")
+		UNAME_MACHINE="alphapca56" ;;
+	    "EV5.7 (21164PC)")
+		UNAME_MACHINE="alphapca57" ;;
+	    "EV6 (21264)")
+		UNAME_MACHINE="alphaev6" ;;
+	    "EV6.7 (21264A)")
+		UNAME_MACHINE="alphaev67" ;;
+	    "EV6.8CB (21264C)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8AL (21264B)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.8CX (21264D)")
+		UNAME_MACHINE="alphaev68" ;;
+	    "EV6.9A (21264/EV69A)")
+		UNAME_MACHINE="alphaev69" ;;
+	    "EV7 (21364)")
+		UNAME_MACHINE="alphaev7" ;;
+	    "EV7.9 (21364A)")
+		UNAME_MACHINE="alphaev79" ;;
+	esac
+	# A Pn.n version is a patched version.
+	# A Vn.n version is a released version.
+	# A Tn.n version is a released field test version.
+	# A Xn.n version is an unreleased experimental baselevel.
+	# 1.2 uses "1.2" for uname -r.
+	echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+	exit 0 ;;
+    Alpha\ *:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# Should we change UNAME_MACHINE based on the output of uname instead
+	# of the specific Alpha model?
+	echo alpha-pc-interix
+	exit 0 ;;
+    21064:Windows_NT:50:3)
+	echo alpha-dec-winnt3.5
+	exit 0 ;;
+    Amiga*:UNIX_System_V:4.0:*)
+	echo m68k-unknown-sysv4
+	exit 0;;
+    *:[Aa]miga[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-amigaos
+	exit 0 ;;
+    *:[Mm]orph[Oo][Ss]:*:*)
+	echo ${UNAME_MACHINE}-unknown-morphos
+	exit 0 ;;
+    *:OS/390:*:*)
+	echo i370-ibm-openedition
+	exit 0 ;;
+    *:z/VM:*:*)
+	echo s390-ibm-zvmoe
+	exit 0 ;;
+    *:OS400:*:*)
+        echo powerpc-ibm-os400
+	exit 0 ;;
+    arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+	echo arm-acorn-riscix${UNAME_RELEASE}
+	exit 0;;
+    SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+	echo hppa1.1-hitachi-hiuxmpp
+	exit 0;;
+    Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+	# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+	if test "`(/bin/universe) 2>/dev/null`" = att ; then
+		echo pyramid-pyramid-sysv3
+	else
+		echo pyramid-pyramid-bsd
+	fi
+	exit 0 ;;
+    NILE*:*:*:dcosx)
+	echo pyramid-pyramid-svr4
+	exit 0 ;;
+    DRS?6000:unix:4.0:6*)
+	echo sparc-icl-nx6
+	exit 0 ;;
+    DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+	case `/usr/bin/uname -p` in
+	    sparc) echo sparc-icl-nx7 && exit 0 ;;
+	esac ;;
+    sun4H:SunOS:5.*:*)
+	echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+	echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    i86pc:SunOS:5.*:*)
+	echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:6*:*)
+	# According to config.sub, this is the proper way to canonicalize
+	# SunOS6.  Hard to guess exactly what SunOS6 will be like, but
+	# it's likely to be more like Solaris than SunOS4.
+	echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    sun4*:SunOS:*:*)
+	case "`/usr/bin/arch -k`" in
+	    Series*|S4*)
+		UNAME_RELEASE=`uname -v`
+		;;
+	esac
+	# Japanese Language versions have a version number like `4.1.3-JL'.
+	echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+	exit 0 ;;
+    sun3*:SunOS:*:*)
+	echo m68k-sun-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    sun*:*:4.2BSD:*)
+	UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+	test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+	case "`/bin/arch`" in
+	    sun3)
+		echo m68k-sun-sunos${UNAME_RELEASE}
+		;;
+	    sun4)
+		echo sparc-sun-sunos${UNAME_RELEASE}
+		;;
+	esac
+	exit 0 ;;
+    aushp:SunOS:*:*)
+	echo sparc-auspex-sunos${UNAME_RELEASE}
+	exit 0 ;;
+    # The situation for MiNT is a little confusing.  The machine name
+    # can be virtually everything (everything which is not
+    # "atarist" or "atariste" at least should have a processor
+    # > m68000).  The system name ranges from "MiNT" over "FreeMiNT"
+    # to the lowercase version "mint" (or "freemint").  Finally
+    # the system name "TOS" denotes a system which is actually not
+    # MiNT.  But MiNT is downward compatible to TOS, so this should
+    # be no problem.
+    atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+	echo m68k-atari-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+        echo m68k-atari-mint${UNAME_RELEASE}
+	exit 0 ;;
+    milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+        echo m68k-milan-mint${UNAME_RELEASE}
+        exit 0 ;;
+    hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+        echo m68k-hades-mint${UNAME_RELEASE}
+        exit 0 ;;
+    *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+        echo m68k-unknown-mint${UNAME_RELEASE}
+        exit 0 ;;
+    m68k:machten:*:*)
+	echo m68k-apple-machten${UNAME_RELEASE}
+	exit 0 ;;
+    powerpc:machten:*:*)
+	echo powerpc-apple-machten${UNAME_RELEASE}
+	exit 0 ;;
+    RISC*:Mach:*:*)
+	echo mips-dec-mach_bsd4.3
+	exit 0 ;;
+    RISC*:ULTRIX:*:*)
+	echo mips-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    VAX*:ULTRIX*:*:*)
+	echo vax-dec-ultrix${UNAME_RELEASE}
+	exit 0 ;;
+    2020:CLIX:*:* | 2430:CLIX:*:*)
+	echo clipper-intergraph-clix${UNAME_RELEASE}
+	exit 0 ;;
+    mips:*:*:UMIPS | mips:*:*:RISCos)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h>  /* for printf() prototype */
+	int main (int argc, char *argv[]) {
+#else
+	int main (argc, argv) int argc; char *argv[]; {
+#endif
+	#if defined (host_mips) && defined (MIPSEB)
+	#if defined (SYSTYPE_SYSV)
+	  printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_SVR4)
+	  printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+	#endif
+	#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+	  printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+	#endif
+	#endif
+	  exit (-1);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c \
+	  && $dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
+	  && exit 0
+	echo mips-mips-riscos${UNAME_RELEASE}
+	exit 0 ;;
+    Motorola:PowerMAX_OS:*:*)
+	echo powerpc-motorola-powermax
+	exit 0 ;;
+    Motorola:*:4.3:PL8-*)
+	echo powerpc-harris-powermax
+	exit 0 ;;
+    Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+	echo powerpc-harris-powermax
+	exit 0 ;;
+    Night_Hawk:Power_UNIX:*:*)
+	echo powerpc-harris-powerunix
+	exit 0 ;;
+    m88k:CX/UX:7*:*)
+	echo m88k-harris-cxux7
+	exit 0 ;;
+    m88k:*:4*:R4*)
+	echo m88k-motorola-sysv4
+	exit 0 ;;
+    m88k:*:3*:R3*)
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    AViiON:dgux:*:*)
+        # DG/UX returns AViiON for all architectures
+        UNAME_PROCESSOR=`/usr/bin/uname -p`
+	if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+	then
+	    if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+	       [ ${TARGET_BINARY_INTERFACE}x = x ]
+	    then
+		echo m88k-dg-dgux${UNAME_RELEASE}
+	    else
+		echo m88k-dg-dguxbcs${UNAME_RELEASE}
+	    fi
+	else
+	    echo i586-dg-dgux${UNAME_RELEASE}
+	fi
+ 	exit 0 ;;
+    M88*:DolphinOS:*:*)	# DolphinOS (SVR3)
+	echo m88k-dolphin-sysv3
+	exit 0 ;;
+    M88*:*:R3*:*)
+	# Delta 88k system running SVR3
+	echo m88k-motorola-sysv3
+	exit 0 ;;
+    XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+	echo m88k-tektronix-sysv3
+	exit 0 ;;
+    Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+	echo m68k-tektronix-bsd
+	exit 0 ;;
+    *:IRIX*:*:*)
+	echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+	exit 0 ;;
+    ????????:AIX?:[12].1:2)   # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+	echo romp-ibm-aix      # uname -m gives an 8 hex-code CPU id
+	exit 0 ;;              # Note that: echo "'`uname -s`'" gives 'AIX '
+    i*86:AIX:*:*)
+	echo i386-ibm-aix
+	exit 0 ;;
+    ia64:AIX:*:*)
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:2:3)
+	if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+		eval $set_cc_for_build
+		sed 's/^		//' << EOF >$dummy.c
+		#include <sys/systemcfg.h>
+
+		main()
+			{
+			if (!__power_pc())
+				exit(1);
+			puts("powerpc-ibm-aix3.2.5");
+			exit(0);
+			}
+EOF
+		$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+		echo rs6000-ibm-aix3.2.5
+	elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+		echo rs6000-ibm-aix3.2.4
+	else
+		echo rs6000-ibm-aix3.2
+	fi
+	exit 0 ;;
+    *:AIX:*:[45])
+	IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+	if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+		IBM_ARCH=rs6000
+	else
+		IBM_ARCH=powerpc
+	fi
+	if [ -x /usr/bin/oslevel ] ; then
+		IBM_REV=`/usr/bin/oslevel`
+	else
+		IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+	fi
+	echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+	exit 0 ;;
+    *:AIX:*:*)
+	echo rs6000-ibm-aix
+	exit 0 ;;
+    ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+	echo romp-ibm-bsd4.4
+	exit 0 ;;
+    ibmrt:*BSD:*|romp-ibm:BSD:*)            # covers RT/PC BSD and
+	echo romp-ibm-bsd${UNAME_RELEASE}   # 4.3 with uname added to
+	exit 0 ;;                           # report: romp-ibm BSD 4.3
+    *:BOSX:*:*)
+	echo rs6000-bull-bosx
+	exit 0 ;;
+    DPX/2?00:B.O.S.:*:*)
+	echo m68k-bull-sysv3
+	exit 0 ;;
+    9000/[34]??:4.3bsd:1.*:*)
+	echo m68k-hp-bsd
+	exit 0 ;;
+    hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+	echo m68k-hp-bsd4.4
+	exit 0 ;;
+    9000/[34678]??:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	case "${UNAME_MACHINE}" in
+	    9000/31? )            HP_ARCH=m68000 ;;
+	    9000/[34]?? )         HP_ARCH=m68k ;;
+	    9000/[678][0-9][0-9])
+		if [ -x /usr/bin/getconf ]; then
+		    sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+                    sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+                    case "${sc_cpu_version}" in
+                      523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+                      528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+                      532)                      # CPU_PA_RISC2_0
+                        case "${sc_kernel_bits}" in
+                          32) HP_ARCH="hppa2.0n" ;;
+                          64) HP_ARCH="hppa2.0w" ;;
+			  '') HP_ARCH="hppa2.0" ;;   # HP-UX 10.20
+                        esac ;;
+                    esac
+		fi
+		if [ "${HP_ARCH}" = "" ]; then
+		    eval $set_cc_for_build
+		    sed 's/^              //' << EOF >$dummy.c
+
+              #define _HPUX_SOURCE
+              #include <stdlib.h>
+              #include <unistd.h>
+
+              int main ()
+              {
+              #if defined(_SC_KERNEL_BITS)
+                  long bits = sysconf(_SC_KERNEL_BITS);
+              #endif
+                  long cpu  = sysconf (_SC_CPU_VERSION);
+
+                  switch (cpu)
+              	{
+              	case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+              	case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+              	case CPU_PA_RISC2_0:
+              #if defined(_SC_KERNEL_BITS)
+              	    switch (bits)
+              		{
+              		case 64: puts ("hppa2.0w"); break;
+              		case 32: puts ("hppa2.0n"); break;
+              		default: puts ("hppa2.0"); break;
+              		} break;
+              #else  /* !defined(_SC_KERNEL_BITS) */
+              	    puts ("hppa2.0"); break;
+              #endif
+              	default: puts ("hppa1.0"); break;
+              	}
+                  exit (0);
+              }
+EOF
+		    (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+		    test -z "$HP_ARCH" && HP_ARCH=hppa
+		fi ;;
+	esac
+	if [ ${HP_ARCH} = "hppa2.0w" ]
+	then
+	    # avoid double evaluation of $set_cc_for_build
+	    test -n "$CC_FOR_BUILD" || eval $set_cc_for_build
+	    if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E -) | grep __LP64__ >/dev/null
+	    then
+		HP_ARCH="hppa2.0w"
+	    else
+		HP_ARCH="hppa64"
+	    fi
+	fi
+	echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    ia64:HP-UX:*:*)
+	HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+	echo ia64-hp-hpux${HPUX_REV}
+	exit 0 ;;
+    3050*:HI-UX:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <unistd.h>
+	int
+	main ()
+	{
+	  long cpu = sysconf (_SC_CPU_VERSION);
+	  /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+	     true for CPU_PA_RISC1_0.  CPU_IS_PA_RISC returns correct
+	     results, however.  */
+	  if (CPU_IS_PA_RISC (cpu))
+	    {
+	      switch (cpu)
+		{
+		  case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+		  case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+		  default: puts ("hppa-hitachi-hiuxwe2"); break;
+		}
+	    }
+	  else if (CPU_IS_HP_MC68K (cpu))
+	    puts ("m68k-hitachi-hiuxwe2");
+	  else puts ("unknown-hitachi-hiuxwe2");
+	  exit (0);
+	}
+EOF
+	$CC_FOR_BUILD -o $dummy $dummy.c && $dummy && exit 0
+	echo unknown-hitachi-hiuxwe2
+	exit 0 ;;
+    9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+	echo hppa1.1-hp-bsd
+	exit 0 ;;
+    9000/8??:4.3bsd:*:*)
+	echo hppa1.0-hp-bsd
+	exit 0 ;;
+    *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+	echo hppa1.0-hp-mpeix
+	exit 0 ;;
+    hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+	echo hppa1.1-hp-osf
+	exit 0 ;;
+    hp8??:OSF1:*:*)
+	echo hppa1.0-hp-osf
+	exit 0 ;;
+    i*86:OSF1:*:*)
+	if [ -x /usr/sbin/sysversion ] ; then
+	    echo ${UNAME_MACHINE}-unknown-osf1mk
+	else
+	    echo ${UNAME_MACHINE}-unknown-osf1
+	fi
+	exit 0 ;;
+    parisc*:Lites*:*:*)
+	echo hppa1.1-hp-lites
+	exit 0 ;;
+    C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+	echo c1-convex-bsd
+        exit 0 ;;
+    C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+        exit 0 ;;
+    C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+	echo c34-convex-bsd
+        exit 0 ;;
+    C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+	echo c38-convex-bsd
+        exit 0 ;;
+    C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+	echo c4-convex-bsd
+        exit 0 ;;
+    CRAY*Y-MP:*:*:*)
+	echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*[A-Z]90:*:*:*)
+	echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+	| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+	      -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+	      -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*TS:*:*:*)
+	echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*T3E:*:*:*)
+	echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    CRAY*SV1:*:*:*)
+	echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    *:UNICOS/mp:*:*)
+	echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+	exit 0 ;;
+    F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+	FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+        echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+        exit 0 ;;
+    5000:UNIX_System_V:4.*:*)
+        FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+        FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+        echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+	exit 0 ;;
+    i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+	echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    sparc*:BSD/OS:*:*)
+	echo sparc-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:BSD/OS:*:*)
+	echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+	exit 0 ;;
+    *:FreeBSD:*:*)
+	echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit 0 ;;
+    i*:CYGWIN*:*)
+	echo ${UNAME_MACHINE}-pc-cygwin
+	exit 0 ;;
+    i*:MINGW*:*)
+	echo ${UNAME_MACHINE}-pc-mingw32
+	exit 0 ;;
+    i*:PW*:*)
+	echo ${UNAME_MACHINE}-pc-pw32
+	exit 0 ;;
+    x86:Interix*:[34]*)
+	echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//'
+	exit 0 ;;
+    [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+	echo i${UNAME_MACHINE}-pc-mks
+	exit 0 ;;
+    i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+	# How do we know it's Interix rather than the generic POSIX subsystem?
+	# It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+	# UNAME_MACHINE based on the output of uname instead of i386?
+	echo i586-pc-interix
+	exit 0 ;;
+    i*:UWIN*:*)
+	echo ${UNAME_MACHINE}-pc-uwin
+	exit 0 ;;
+    amd64:CYGWIN*:*:*)
+	echo x86_64-unknown-cygwin
+	exit 0 ;;
+    p*:CYGWIN*:*)
+	echo powerpcle-unknown-cygwin
+	exit 0 ;;
+    prep*:SunOS:5.*:*)
+	echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+	exit 0 ;;
+    *:GNU:*:*)
+	# the GNU system
+	echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+	exit 0 ;;
+    *:GNU/*:*:*)
+	# other systems with GNU libc and userland
+	echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
+	exit 0 ;;
+    i*86:Minix:*:*)
+	echo ${UNAME_MACHINE}-pc-minix
+	exit 0 ;;
+    arm*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    cris:Linux:*:*)
+	echo cris-axis-linux-gnu
+	exit 0 ;;
+    crisv32:Linux:*:*)
+	echo crisv32-axis-linux-gnu
+	exit 0 ;;
+    frv:Linux:*:*)
+    	echo frv-unknown-linux-gnu
+	exit 0 ;;
+    ia64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    m32r*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    m68*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    mips:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips
+	#undef mipsel
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mipsel
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+	;;
+    mips64:Linux:*:*)
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#undef CPU
+	#undef mips64
+	#undef mips64el
+	#if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+	CPU=mips64el
+	#else
+	#if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+	CPU=mips64
+	#else
+	CPU=
+	#endif
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=`
+	test x"${CPU}" != x && echo "${CPU}-unknown-linux-gnu" && exit 0
+	;;
+    ppc:Linux:*:*)
+	echo powerpc-unknown-linux-gnu
+	exit 0 ;;
+    ppc64:Linux:*:*)
+	echo powerpc64-unknown-linux-gnu
+	exit 0 ;;
+    alpha:Linux:*:*)
+	case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+	  EV5)   UNAME_MACHINE=alphaev5 ;;
+	  EV56)  UNAME_MACHINE=alphaev56 ;;
+	  PCA56) UNAME_MACHINE=alphapca56 ;;
+	  PCA57) UNAME_MACHINE=alphapca56 ;;
+	  EV6)   UNAME_MACHINE=alphaev6 ;;
+	  EV67)  UNAME_MACHINE=alphaev67 ;;
+	  EV68*) UNAME_MACHINE=alphaev68 ;;
+        esac
+	objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null
+	if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
+	echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
+	exit 0 ;;
+    parisc:Linux:*:* | hppa:Linux:*:*)
+	# Look for CPU level
+	case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+	  PA7*) echo hppa1.1-unknown-linux-gnu ;;
+	  PA8*) echo hppa2.0-unknown-linux-gnu ;;
+	  *)    echo hppa-unknown-linux-gnu ;;
+	esac
+	exit 0 ;;
+    parisc64:Linux:*:* | hppa64:Linux:*:*)
+	echo hppa64-unknown-linux-gnu
+	exit 0 ;;
+    s390:Linux:*:* | s390x:Linux:*:*)
+	echo ${UNAME_MACHINE}-ibm-linux
+	exit 0 ;;
+    sh64*:Linux:*:*)
+    	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sh*:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    sparc:Linux:*:* | sparc64:Linux:*:*)
+	echo ${UNAME_MACHINE}-unknown-linux-gnu
+	exit 0 ;;
+    x86_64:Linux:*:*)
+	echo x86_64-unknown-linux-gnu
+	exit 0 ;;
+    i*86:Linux:*:*)
+	# The BFD linker knows what the default object file format is, so
+	# first see if it will tell us. cd to the root directory to prevent
+	# problems with other programs or directories called `ld' in the path.
+	# Set LC_ALL=C to ensure ld outputs messages in English.
+	ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \
+			 | sed -ne '/supported targets:/!d
+				    s/[ 	][ 	]*/ /g
+				    s/.*supported targets: *//
+				    s/ .*//
+				    p'`
+        case "$ld_supported_targets" in
+	  elf32-i386)
+		TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu"
+		;;
+	  a.out-i386-linux)
+		echo "${UNAME_MACHINE}-pc-linux-gnuaout"
+		exit 0 ;;
+	  coff-i386)
+		echo "${UNAME_MACHINE}-pc-linux-gnucoff"
+		exit 0 ;;
+	  "")
+		# Either a pre-BFD a.out linker (linux-gnuoldld) or
+		# one that does not give us useful --help.
+		echo "${UNAME_MACHINE}-pc-linux-gnuoldld"
+		exit 0 ;;
+	esac
+	# Determine whether the default compiler is a.out or elf
+	eval $set_cc_for_build
+	sed 's/^	//' << EOF >$dummy.c
+	#include <features.h>
+	#ifdef __ELF__
+	# ifdef __GLIBC__
+	#  if __GLIBC__ >= 2
+	LIBC=gnu
+	#  else
+	LIBC=gnulibc1
+	#  endif
+	# else
+	LIBC=gnulibc1
+	# endif
+	#else
+	#ifdef __INTEL_COMPILER
+	LIBC=gnu
+	#else
+	LIBC=gnuaout
+	#endif
+	#endif
+	#ifdef __dietlibc__
+	LIBC=dietlibc
+	#endif
+EOF
+	eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=`
+	test x"${LIBC}" != x && echo "${UNAME_MACHINE}-pc-linux-${LIBC}" && exit 0
+	test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0
+	;;
+    i*86:DYNIX/ptx:4*:*)
+	# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+	# earlier versions are messed up and put the nodename in both
+	# sysname and nodename.
+	echo i386-sequent-sysv4
+	exit 0 ;;
+    i*86:UNIX_SV:4.2MP:2.*)
+        # Unixware is an offshoot of SVR4, but it has its own version
+        # number series starting with 2...
+        # I am not positive that other SVR4 systems won't match this,
+	# I just have to hope.  -- rms.
+        # Use sysv4.2uw... so that sysv4* matches it.
+	echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+	exit 0 ;;
+    i*86:OS/2:*:*)
+	# If we were able to find `uname', then EMX Unix compatibility
+	# is probably installed.
+	echo ${UNAME_MACHINE}-pc-os2-emx
+	exit 0 ;;
+    i*86:XTS-300:*:STOP)
+	echo ${UNAME_MACHINE}-unknown-stop
+	exit 0 ;;
+    i*86:atheos:*:*)
+	echo ${UNAME_MACHINE}-unknown-atheos
+	exit 0 ;;
+	i*86:syllable:*:*)
+	echo ${UNAME_MACHINE}-pc-syllable
+	exit 0 ;;
+    i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*)
+	echo i386-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    i*86:*DOS:*:*)
+	echo ${UNAME_MACHINE}-pc-msdosdjgpp
+	exit 0 ;;
+    i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+	UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+	if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+		echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+	else
+		echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+	fi
+	exit 0 ;;
+    i*86:*:5:[78]*)
+	case `/bin/uname -X | grep "^Machine"` in
+	    *486*)	     UNAME_MACHINE=i486 ;;
+	    *Pentium)	     UNAME_MACHINE=i586 ;;
+	    *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+	esac
+	echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+	exit 0 ;;
+    i*86:*:3.2:*)
+	if test -f /usr/options/cb.name; then
+		UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+		echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+	elif /bin/uname -X 2>/dev/null >/dev/null ; then
+		UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+		(/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+		(/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+			&& UNAME_MACHINE=i586
+		(/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		(/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+			&& UNAME_MACHINE=i686
+		echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+	else
+		echo ${UNAME_MACHINE}-pc-sysv32
+	fi
+	exit 0 ;;
+    pc:*:*:*)
+	# Left here for compatibility:
+        # uname -m prints for DJGPP always 'pc', but it prints nothing about
+        # the processor, so we play safe by assuming i386.
+	echo i386-pc-msdosdjgpp
+        exit 0 ;;
+    Intel:Mach:3*:*)
+	echo i386-pc-mach3
+	exit 0 ;;
+    paragon:*:*:*)
+	echo i860-intel-osf1
+	exit 0 ;;
+    i860:*:4.*:*) # i860-SVR4
+	if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+	  echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+	else # Add other i860-SVR4 vendors below as they are discovered.
+	  echo i860-unknown-sysv${UNAME_RELEASE}  # Unknown i860-SVR4
+	fi
+	exit 0 ;;
+    mini*:CTIX:SYS*5:*)
+	# "miniframe"
+	echo m68010-convergent-sysv
+	exit 0 ;;
+    mc68k:UNIX:SYSTEM5:3.51m)
+	echo m68k-convergent-sysv
+	exit 0 ;;
+    M680?0:D-NIX:5.3:*)
+	echo m68k-diab-dnix
+	exit 0 ;;
+    M68*:*:R3V[5678]*:*)
+	test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
+    3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+	OS_REL=''
+	test -r /etc/.relid \
+	&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+	/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+	  && echo i486-ncr-sysv4.3${OS_REL} && exit 0
+	/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+	  && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
+    3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+        /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+          && echo i486-ncr-sysv4 && exit 0 ;;
+    m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+	echo m68k-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    mc68030:UNIX_System_V:4.*:*)
+	echo m68k-atari-sysv4
+	exit 0 ;;
+    TSUNAMI:LynxOS:2.*:*)
+	echo sparc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    rs6000:LynxOS:2.*:*)
+	echo rs6000-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*)
+	echo powerpc-unknown-lynxos${UNAME_RELEASE}
+	exit 0 ;;
+    SM[BE]S:UNIX_SV:*:*)
+	echo mips-dde-sysv${UNAME_RELEASE}
+	exit 0 ;;
+    RM*:ReliantUNIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    RM*:SINIX-*:*:*)
+	echo mips-sni-sysv4
+	exit 0 ;;
+    *:SINIX-*:*:*)
+	if uname -p 2>/dev/null >/dev/null ; then
+		UNAME_MACHINE=`(uname -p) 2>/dev/null`
+		echo ${UNAME_MACHINE}-sni-sysv4
+	else
+		echo ns32k-sni-sysv
+	fi
+	exit 0 ;;
+    PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+                      # says <Richard.M.Bartel@ccMail.Census.GOV>
+        echo i586-unisys-sysv4
+        exit 0 ;;
+    *:UNIX_System_V:4*:FTX*)
+	# From Gerald Hewes <hewes@openmarket.com>.
+	# How about differentiating between stratus architectures? -djm
+	echo hppa1.1-stratus-sysv4
+	exit 0 ;;
+    *:*:*:FTX*)
+	# From seanf@swdc.stratus.com.
+	echo i860-stratus-sysv4
+	exit 0 ;;
+    *:VOS:*:*)
+	# From Paul.Green@stratus.com.
+	echo hppa1.1-stratus-vos
+	exit 0 ;;
+    mc68*:A/UX:*:*)
+	echo m68k-apple-aux${UNAME_RELEASE}
+	exit 0 ;;
+    news*:NEWS-OS:6*:*)
+	echo mips-sony-newsos6
+	exit 0 ;;
+    R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+	if [ -d /usr/nec ]; then
+	        echo mips-nec-sysv${UNAME_RELEASE}
+	else
+	        echo mips-unknown-sysv${UNAME_RELEASE}
+	fi
+        exit 0 ;;
+    BeBox:BeOS:*:*)	# BeOS running on hardware made by Be, PPC only.
+	echo powerpc-be-beos
+	exit 0 ;;
+    BeMac:BeOS:*:*)	# BeOS running on Mac or Mac clone, PPC only.
+	echo powerpc-apple-beos
+	exit 0 ;;
+    BePC:BeOS:*:*)	# BeOS running on Intel PC compatible.
+	echo i586-pc-beos
+	exit 0 ;;
+    SX-4:SUPER-UX:*:*)
+	echo sx4-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-5:SUPER-UX:*:*)
+	echo sx5-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    SX-6:SUPER-UX:*:*)
+	echo sx6-nec-superux${UNAME_RELEASE}
+	exit 0 ;;
+    Power*:Rhapsody:*:*)
+	echo powerpc-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Rhapsody:*:*)
+	echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+	exit 0 ;;
+    *:Darwin:*:*)
+	UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+	case $UNAME_PROCESSOR in
+	    *86) UNAME_PROCESSOR=i686 ;;
+	    unknown) UNAME_PROCESSOR=powerpc ;;
+	esac
+	echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+	exit 0 ;;
+    *:procnto*:*:* | *:QNX:[0123456789]*:*)
+	UNAME_PROCESSOR=`uname -p`
+	if test "$UNAME_PROCESSOR" = "x86"; then
+		UNAME_PROCESSOR=i386
+		UNAME_MACHINE=pc
+	fi
+	echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+	exit 0 ;;
+    *:QNX:*:4*)
+	echo i386-pc-qnx
+	exit 0 ;;
+    NSE-?:NONSTOP_KERNEL:*:*)
+	echo nse-tandem-nsk${UNAME_RELEASE}
+	exit 0 ;;
+    NSR-?:NONSTOP_KERNEL:*:*)
+	echo nsr-tandem-nsk${UNAME_RELEASE}
+	exit 0 ;;
+    *:NonStop-UX:*:*)
+	echo mips-compaq-nonstopux
+	exit 0 ;;
+    BS2000:POSIX*:*:*)
+	echo bs2000-siemens-sysv
+	exit 0 ;;
+    DS/*:UNIX_System_V:*:*)
+	echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+	exit 0 ;;
+    *:Plan9:*:*)
+	# "uname -m" is not consistent, so use $cputype instead. 386
+	# is converted to i386 for consistency with other x86
+	# operating systems.
+	if test "$cputype" = "386"; then
+	    UNAME_MACHINE=i386
+	else
+	    UNAME_MACHINE="$cputype"
+	fi
+	echo ${UNAME_MACHINE}-unknown-plan9
+	exit 0 ;;
+    *:TOPS-10:*:*)
+	echo pdp10-unknown-tops10
+	exit 0 ;;
+    *:TENEX:*:*)
+	echo pdp10-unknown-tenex
+	exit 0 ;;
+    KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+	echo pdp10-dec-tops20
+	exit 0 ;;
+    XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+	echo pdp10-xkl-tops20
+	exit 0 ;;
+    *:TOPS-20:*:*)
+	echo pdp10-unknown-tops20
+	exit 0 ;;
+    *:ITS:*:*)
+	echo pdp10-unknown-its
+	exit 0 ;;
+    SEI:*:*:SEIUX)
+        echo mips-sei-seiux${UNAME_RELEASE}
+	exit 0 ;;
+    *:DragonFly:*:*)
+	echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+	exit 0 ;;
+    *:*VMS:*:*)
+    	UNAME_MACHINE=`(uname -p) 2>/dev/null`
+	case "${UNAME_MACHINE}" in
+	    A*) echo alpha-dec-vms && exit 0 ;;
+	    I*) echo ia64-dec-vms && exit 0 ;;
+	    V*) echo vax-dec-vms && exit 0 ;;
+	esac ;;
+    *:XENIX:*:SysV)
+	echo i386-pc-xenix
+	exit 0 ;;
+esac
+
+#echo '(No uname command or uname output not recognized.)' 1>&2
+#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
+
+eval $set_cc_for_build
+cat >$dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+main ()
+{
+#if defined (sony)
+#if defined (MIPSEB)
+  /* BFD wants "bsd" instead of "newsos".  Perhaps BFD should be changed,
+     I don't know....  */
+  printf ("mips-sony-bsd\n"); exit (0);
+#else
+#include <sys/param.h>
+  printf ("m68k-sony-newsos%s\n",
+#ifdef NEWSOS4
+          "4"
+#else
+	  ""
+#endif
+         ); exit (0);
+#endif
+#endif
+
+#if defined (__arm) && defined (__acorn) && defined (__unix)
+  printf ("arm-acorn-riscix"); exit (0);
+#endif
+
+#if defined (hp300) && !defined (hpux)
+  printf ("m68k-hp-bsd\n"); exit (0);
+#endif
+
+#if defined (NeXT)
+#if !defined (__ARCHITECTURE__)
+#define __ARCHITECTURE__ "m68k"
+#endif
+  int version;
+  version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
+  if (version < 4)
+    printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
+  else
+    printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
+  exit (0);
+#endif
+
+#if defined (MULTIMAX) || defined (n16)
+#if defined (UMAXV)
+  printf ("ns32k-encore-sysv\n"); exit (0);
+#else
+#if defined (CMU)
+  printf ("ns32k-encore-mach\n"); exit (0);
+#else
+  printf ("ns32k-encore-bsd\n"); exit (0);
+#endif
+#endif
+#endif
+
+#if defined (__386BSD__)
+  printf ("i386-pc-bsd\n"); exit (0);
+#endif
+
+#if defined (sequent)
+#if defined (i386)
+  printf ("i386-sequent-dynix\n"); exit (0);
+#endif
+#if defined (ns32000)
+  printf ("ns32k-sequent-dynix\n"); exit (0);
+#endif
+#endif
+
+#if defined (_SEQUENT_)
+    struct utsname un;
+
+    uname(&un);
+
+    if (strncmp(un.version, "V2", 2) == 0) {
+	printf ("i386-sequent-ptx2\n"); exit (0);
+    }
+    if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+	printf ("i386-sequent-ptx1\n"); exit (0);
+    }
+    printf ("i386-sequent-ptx\n"); exit (0);
+
+#endif
+
+#if defined (vax)
+# if !defined (ultrix)
+#  include <sys/param.h>
+#  if defined (BSD)
+#   if BSD == 43
+      printf ("vax-dec-bsd4.3\n"); exit (0);
+#   else
+#    if BSD == 199006
+      printf ("vax-dec-bsd4.3reno\n"); exit (0);
+#    else
+      printf ("vax-dec-bsd\n"); exit (0);
+#    endif
+#   endif
+#  else
+    printf ("vax-dec-bsd\n"); exit (0);
+#  endif
+# else
+    printf ("vax-dec-ultrix\n"); exit (0);
+# endif
+#endif
+
+#if defined (alliant) && defined (i860)
+  printf ("i860-alliant-bsd\n"); exit (0);
+#endif
+
+  exit (1);
+}
+EOF
+
+$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && $dummy && exit 0
+
+# Apollos put the system type in the environment.
+
+test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; }
+
+# Convex versions that predate uname can use getsysinfo(1)
+
+if [ -x /usr/convex/getsysinfo ]
+then
+    case `getsysinfo -f cpu_type` in
+    c1*)
+	echo c1-convex-bsd
+	exit 0 ;;
+    c2*)
+	if getsysinfo -f scalar_acc
+	then echo c32-convex-bsd
+	else echo c2-convex-bsd
+	fi
+	exit 0 ;;
+    c34*)
+	echo c34-convex-bsd
+	exit 0 ;;
+    c38*)
+	echo c38-convex-bsd
+	exit 0 ;;
+    c4*)
+	echo c4-convex-bsd
+	exit 0 ;;
+    esac
+fi
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+    ftp://ftp.gnu.org/pub/gnu/config/
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo               = `(hostinfo) 2>/dev/null`
+/bin/universe          = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch              = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM  = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
Index: branches/network/config.h.in
===================================================================
--- branches/network/config.h.in	(revision 6636)
+++ branches/network/config.h.in	(revision 6636)
@@ -0,0 +1,125 @@
+/* config.h.in.  Generated from configure.ac by autoheader.  */
+
+/* Define to the read-only architecture-independent data directory. */
+#undef DATADIR
+
+/* in which debug mode we are */
+#undef DEBUG
+
+/* Define to 1 if you have the <AL/al.h> header file. */
+#undef HAVE_AL_AL_H
+
+/* Define to 1 if you have the <avcodec.h> header file. */
+#undef HAVE_AVCODEC_H
+
+/* Define to 1 if you have the <avformat.h> header file. */
+#undef HAVE_AVFORMAT_H
+
+/* Define to 1 if you have the `bzero' function. */
+#undef HAVE_BZERO
+
+/* if we have CURL */
+#undef HAVE_CURL
+
+/* Define to 1 if you have the <ffmpeg/avcodec.h> header file. */
+#undef HAVE_FFMPEG_AVCODEC_H
+
+/* Define to 1 if you have the <ffmpeg/avformat.h> header file. */
+#undef HAVE_FFMPEG_AVFORMAT_H
+
+/* Define to 1 if you have the <GL/glew.h> header file. */
+#undef HAVE_GL_GLEW_H
+
+/* Define to 1 if you have the <GL/glu.h> header file. */
+#undef HAVE_GL_GLU_H
+
+/* Define to 1 if you have the <GL/gl.h> header file. */
+#undef HAVE_GL_GL_H
+
+/* if we have GTK2 */
+#undef HAVE_GTK2
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the `m' library (-lm). */
+#undef HAVE_LIBM
+
+/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
+   to 0 otherwise. */
+#undef HAVE_MALLOC
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <OpenAL/al.h> header file. */
+#undef HAVE_OPENAL_AL_H
+
+/* Define to 1 if you have the <OpenGL/glu.h> header file. */
+#undef HAVE_OPENGL_GLU_H
+
+/* Define to 1 if you have the <OpenGL/gl.h> header file. */
+#undef HAVE_OPENGL_GL_H
+
+/* Define to 1 if you have the <SDL/SDL.h> header file. */
+#undef HAVE_SDL_SDL_H
+
+/* Define to 1 if you have the `sqrt' function. */
+#undef HAVE_SQRT
+
+/* Define to 1 if stdbool.h conforms to C99. */
+#undef HAVE_STDBOOL_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if the system has the type `_Bool'. */
+#undef HAVE__BOOL
+
+/* if Modular-DUBUG mode is enabled */
+#undef MODULAR_DEBUG
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to rpl_malloc if the replacement function should be used. */
+#undef malloc
Index: branches/network/config.sub
===================================================================
--- branches/network/config.sub	(revision 6636)
+++ branches/network/config.sub	(revision 6636)
@@ -0,0 +1,1566 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+#   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+#   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+timestamp='2005-02-10'
+
+# This file is (in principle) common to ALL GNU software.
+# The presence of a machine in this file suggests that SOME GNU software
+# can handle that machine.  It does not imply ALL GNU software can.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Please send patches to <config-patches@gnu.org>.  Submit a context
+# diff and a properly formatted ChangeLog entry.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support.  The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+#	CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+#	CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+       $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+  -h, --help         print this help, then exit
+  -t, --time-stamp   print date of last modification, then exit
+  -v, --version      print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
+Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+  case $1 in
+    --time-stamp | --time* | -t )
+       echo "$timestamp" ; exit 0 ;;
+    --version | -v )
+       echo "$version" ; exit 0 ;;
+    --help | --h* | -h )
+       echo "$usage"; exit 0 ;;
+    -- )     # Stop option processing
+       shift; break ;;
+    - )	# Use stdin as input.
+       break ;;
+    -* )
+       echo "$me: invalid option $1$help"
+       exit 1 ;;
+
+    *local*)
+       # First pass through any local machine types.
+       echo $1
+       exit 0;;
+
+    * )
+       break ;;
+  esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+    exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+    exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+  nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
+  kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
+    os=-$maybe_os
+    basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+    ;;
+  *)
+    basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+    if [ $basic_machine != $1 ]
+    then os=`echo $1 | sed 's/.*-/-/'`
+    else os=; fi
+    ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work.  We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+	-sun*os*)
+		# Prevent following clause from handling this invalid input.
+		;;
+	-dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+	-att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+	-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+	-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+	-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+	-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+	-apple | -axis | -knuth | -cray)
+		os=
+		basic_machine=$1
+		;;
+	-sim | -cisco | -oki | -wec | -winbond)
+		os=
+		basic_machine=$1
+		;;
+	-scout)
+		;;
+	-wrs)
+		os=-vxworks
+		basic_machine=$1
+		;;
+	-chorusos*)
+		os=-chorusos
+		basic_machine=$1
+		;;
+ 	-chorusrdb)
+ 		os=-chorusrdb
+		basic_machine=$1
+ 		;;
+	-hiux*)
+		os=-hiuxwe2
+		;;
+	-sco5)
+		os=-sco3.2v5
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco4)
+		os=-sco3.2v4
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2.[4-9]*)
+		os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco3.2v[4-9]*)
+		# Don't forget version if it is 3.2v4 or newer.
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-sco*)
+		os=-sco3.2v2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-udk*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-isc)
+		os=-isc2.2
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-clix*)
+		basic_machine=clipper-intergraph
+		;;
+	-isc*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+		;;
+	-lynx*)
+		os=-lynxos
+		;;
+	-ptx*)
+		basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+		;;
+	-windowsnt*)
+		os=`echo $os | sed -e 's/windowsnt/winnt/'`
+		;;
+	-psos*)
+		os=-psos
+		;;
+	-mint | -mint[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+	# Recognize the basic CPU types without company name.
+	# Some are omitted here because they have special meanings below.
+	1750a | 580 \
+	| a29k \
+	| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+	| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+	| am33_2.0 \
+	| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \
+	| c4x | clipper \
+	| d10v | d30v | dlx | dsp16xx \
+	| fr30 | frv \
+	| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+	| i370 | i860 | i960 | ia64 \
+	| ip2k | iq2000 \
+	| m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \
+	| mips | mipsbe | mipseb | mipsel | mipsle \
+	| mips16 \
+	| mips64 | mips64el \
+	| mips64vr | mips64vrel \
+	| mips64orion | mips64orionel \
+	| mips64vr4100 | mips64vr4100el \
+	| mips64vr4300 | mips64vr4300el \
+	| mips64vr5000 | mips64vr5000el \
+	| mipsisa32 | mipsisa32el \
+	| mipsisa32r2 | mipsisa32r2el \
+	| mipsisa64 | mipsisa64el \
+	| mipsisa64r2 | mipsisa64r2el \
+	| mipsisa64sb1 | mipsisa64sb1el \
+	| mipsisa64sr71k | mipsisa64sr71kel \
+	| mipstx39 | mipstx39el \
+	| mn10200 | mn10300 \
+	| msp430 \
+	| ns16k | ns32k \
+	| openrisc | or32 \
+	| pdp10 | pdp11 | pj | pjl \
+	| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
+	| pyramid \
+	| sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \
+	| sh64 | sh64le \
+	| sparc | sparc64 | sparc86x | sparclet | sparclite | sparcv8 | sparcv9 | sparcv9b \
+	| strongarm \
+	| tahoe | thumb | tic4x | tic80 | tron \
+	| v850 | v850e \
+	| we32k \
+	| x86 | xscale | xscalee[bl] | xstormy16 | xtensa \
+	| z8k)
+		basic_machine=$basic_machine-unknown
+		;;
+	m6811 | m68hc11 | m6812 | m68hc12)
+		# Motorola 68HC11/12.
+		basic_machine=$basic_machine-unknown
+		os=-none
+		;;
+	m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+		;;
+
+	# We use `pc' rather than `unknown'
+	# because (1) that's what they normally are, and
+	# (2) the word "unknown" tends to confuse beginning users.
+	i*86 | x86_64)
+	  basic_machine=$basic_machine-pc
+	  ;;
+	# Object if more than one company name word.
+	*-*-*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+	# Recognize the basic CPU types with company name.
+	580-* \
+	| a29k-* \
+	| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+	| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+	| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
+	| arm-*  | armbe-* | armle-* | armeb-* | armv*-* \
+	| avr-* \
+	| bs2000-* \
+	| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
+	| clipper-* | craynv-* | cydra-* \
+	| d10v-* | d30v-* | dlx-* \
+	| elxsi-* \
+	| f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \
+	| h8300-* | h8500-* \
+	| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+	| i*86-* | i860-* | i960-* | ia64-* \
+	| ip2k-* | iq2000-* \
+	| m32r-* | m32rle-* \
+	| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+	| m88110-* | m88k-* | maxq-* | mcore-* \
+	| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+	| mips16-* \
+	| mips64-* | mips64el-* \
+	| mips64vr-* | mips64vrel-* \
+	| mips64orion-* | mips64orionel-* \
+	| mips64vr4100-* | mips64vr4100el-* \
+	| mips64vr4300-* | mips64vr4300el-* \
+	| mips64vr5000-* | mips64vr5000el-* \
+	| mipsisa32-* | mipsisa32el-* \
+	| mipsisa32r2-* | mipsisa32r2el-* \
+	| mipsisa64-* | mipsisa64el-* \
+	| mipsisa64r2-* | mipsisa64r2el-* \
+	| mipsisa64sb1-* | mipsisa64sb1el-* \
+	| mipsisa64sr71k-* | mipsisa64sr71kel-* \
+	| mipstx39-* | mipstx39el-* \
+	| mmix-* \
+	| msp430-* \
+	| none-* | np1-* | ns16k-* | ns32k-* \
+	| orion-* \
+	| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+	| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
+	| pyramid-* \
+	| romp-* | rs6000-* \
+	| sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \
+	| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+	| sparc-* | sparc64-* | sparc86x-* | sparclet-* | sparclite-* \
+	| sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \
+	| tahoe-* | thumb-* \
+	| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+	| tron-* \
+	| v850-* | v850e-* | vax-* \
+	| we32k-* \
+	| x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \
+	| xstormy16-* | xtensa-* \
+	| ymp-* \
+	| z8k-*)
+		;;
+	# Recognize the various machine names and aliases which stand
+	# for a CPU type and a company and sometimes even an OS.
+	386bsd)
+		basic_machine=i386-unknown
+		os=-bsd
+		;;
+	3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+		basic_machine=m68000-att
+		;;
+	3b*)
+		basic_machine=we32k-att
+		;;
+	a29khif)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+    	abacus)
+		basic_machine=abacus-unknown
+		;;
+	adobe68k)
+		basic_machine=m68010-adobe
+		os=-scout
+		;;
+	alliant | fx80)
+		basic_machine=fx80-alliant
+		;;
+	altos | altos3068)
+		basic_machine=m68k-altos
+		;;
+	am29k)
+		basic_machine=a29k-none
+		os=-bsd
+		;;
+	amd64)
+		basic_machine=x86_64-pc
+		;;
+	amd64-*)
+		basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	amdahl)
+		basic_machine=580-amdahl
+		os=-sysv
+		;;
+	amiga | amiga-*)
+		basic_machine=m68k-unknown
+		;;
+	amigaos | amigados)
+		basic_machine=m68k-unknown
+		os=-amigaos
+		;;
+	amigaunix | amix)
+		basic_machine=m68k-unknown
+		os=-sysv4
+		;;
+	apollo68)
+		basic_machine=m68k-apollo
+		os=-sysv
+		;;
+	apollo68bsd)
+		basic_machine=m68k-apollo
+		os=-bsd
+		;;
+	aux)
+		basic_machine=m68k-apple
+		os=-aux
+		;;
+	balance)
+		basic_machine=ns32k-sequent
+		os=-dynix
+		;;
+	c90)
+		basic_machine=c90-cray
+		os=-unicos
+		;;
+	convex-c1)
+		basic_machine=c1-convex
+		os=-bsd
+		;;
+	convex-c2)
+		basic_machine=c2-convex
+		os=-bsd
+		;;
+	convex-c32)
+		basic_machine=c32-convex
+		os=-bsd
+		;;
+	convex-c34)
+		basic_machine=c34-convex
+		os=-bsd
+		;;
+	convex-c38)
+		basic_machine=c38-convex
+		os=-bsd
+		;;
+	cray | j90)
+		basic_machine=j90-cray
+		os=-unicos
+		;;
+	craynv)
+		basic_machine=craynv-cray
+		os=-unicosmp
+		;;
+	cr16c)
+		basic_machine=cr16c-unknown
+		os=-elf
+		;;
+	crds | unos)
+		basic_machine=m68k-crds
+		;;
+	crisv32 | crisv32-* | etraxfs*)
+		basic_machine=crisv32-axis
+		;;
+	cris | cris-* | etrax*)
+		basic_machine=cris-axis
+		;;
+	crx)
+		basic_machine=crx-unknown
+		os=-elf
+		;;
+	da30 | da30-*)
+		basic_machine=m68k-da30
+		;;
+	decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+		basic_machine=mips-dec
+		;;
+	decsystem10* | dec10*)
+		basic_machine=pdp10-dec
+		os=-tops10
+		;;
+	decsystem20* | dec20*)
+		basic_machine=pdp10-dec
+		os=-tops20
+		;;
+	delta | 3300 | motorola-3300 | motorola-delta \
+	      | 3300-motorola | delta-motorola)
+		basic_machine=m68k-motorola
+		;;
+	delta88)
+		basic_machine=m88k-motorola
+		os=-sysv3
+		;;
+	djgpp)
+		basic_machine=i586-pc
+		os=-msdosdjgpp
+		;;
+	dpx20 | dpx20-*)
+		basic_machine=rs6000-bull
+		os=-bosx
+		;;
+	dpx2* | dpx2*-bull)
+		basic_machine=m68k-bull
+		os=-sysv3
+		;;
+	ebmon29k)
+		basic_machine=a29k-amd
+		os=-ebmon
+		;;
+	elxsi)
+		basic_machine=elxsi-elxsi
+		os=-bsd
+		;;
+	encore | umax | mmax)
+		basic_machine=ns32k-encore
+		;;
+	es1800 | OSE68k | ose68k | ose | OSE)
+		basic_machine=m68k-ericsson
+		os=-ose
+		;;
+	fx2800)
+		basic_machine=i860-alliant
+		;;
+	genix)
+		basic_machine=ns32k-ns
+		;;
+	gmicro)
+		basic_machine=tron-gmicro
+		os=-sysv
+		;;
+	go32)
+		basic_machine=i386-pc
+		os=-go32
+		;;
+	h3050r* | hiux*)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	h8300hms)
+		basic_machine=h8300-hitachi
+		os=-hms
+		;;
+	h8300xray)
+		basic_machine=h8300-hitachi
+		os=-xray
+		;;
+	h8500hms)
+		basic_machine=h8500-hitachi
+		os=-hms
+		;;
+	harris)
+		basic_machine=m88k-harris
+		os=-sysv3
+		;;
+	hp300-*)
+		basic_machine=m68k-hp
+		;;
+	hp300bsd)
+		basic_machine=m68k-hp
+		os=-bsd
+		;;
+	hp300hpux)
+		basic_machine=m68k-hp
+		os=-hpux
+		;;
+	hp3k9[0-9][0-9] | hp9[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k2[0-9][0-9] | hp9k31[0-9])
+		basic_machine=m68000-hp
+		;;
+	hp9k3[2-9][0-9])
+		basic_machine=m68k-hp
+		;;
+	hp9k6[0-9][0-9] | hp6[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hp9k7[0-79][0-9] | hp7[0-79][0-9])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k78[0-9] | hp78[0-9])
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+		# FIXME: really hppa2.0-hp
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][13679] | hp8[0-9][13679])
+		basic_machine=hppa1.1-hp
+		;;
+	hp9k8[0-9][0-9] | hp8[0-9][0-9])
+		basic_machine=hppa1.0-hp
+		;;
+	hppa-next)
+		os=-nextstep3
+		;;
+	hppaosf)
+		basic_machine=hppa1.1-hp
+		os=-osf
+		;;
+	hppro)
+		basic_machine=hppa1.1-hp
+		os=-proelf
+		;;
+	i370-ibm* | ibm*)
+		basic_machine=i370-ibm
+		;;
+# I'm not sure what "Sysv32" means.  Should this be sysv3.2?
+	i*86v32)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv32
+		;;
+	i*86v4*)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv4
+		;;
+	i*86v)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-sysv
+		;;
+	i*86sol2)
+		basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+		os=-solaris2
+		;;
+	i386mach)
+		basic_machine=i386-mach
+		os=-mach
+		;;
+	i386-vsta | vsta)
+		basic_machine=i386-unknown
+		os=-vsta
+		;;
+	iris | iris4d)
+		basic_machine=mips-sgi
+		case $os in
+		    -irix*)
+			;;
+		    *)
+			os=-irix4
+			;;
+		esac
+		;;
+	isi68 | isi)
+		basic_machine=m68k-isi
+		os=-sysv
+		;;
+	m88k-omron*)
+		basic_machine=m88k-omron
+		;;
+	magnum | m3230)
+		basic_machine=mips-mips
+		os=-sysv
+		;;
+	merlin)
+		basic_machine=ns32k-utek
+		os=-sysv
+		;;
+	mingw32)
+		basic_machine=i386-pc
+		os=-mingw32
+		;;
+	miniframe)
+		basic_machine=m68000-convergent
+		;;
+	*mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+		basic_machine=m68k-atari
+		os=-mint
+		;;
+	mips3*-*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+		;;
+	mips3*)
+		basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+		;;
+	monitor)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	morphos)
+		basic_machine=powerpc-unknown
+		os=-morphos
+		;;
+	msdos)
+		basic_machine=i386-pc
+		os=-msdos
+		;;
+	mvs)
+		basic_machine=i370-ibm
+		os=-mvs
+		;;
+	ncr3000)
+		basic_machine=i486-ncr
+		os=-sysv4
+		;;
+	netbsd386)
+		basic_machine=i386-unknown
+		os=-netbsd
+		;;
+	netwinder)
+		basic_machine=armv4l-rebel
+		os=-linux
+		;;
+	news | news700 | news800 | news900)
+		basic_machine=m68k-sony
+		os=-newsos
+		;;
+	news1000)
+		basic_machine=m68030-sony
+		os=-newsos
+		;;
+	news-3600 | risc-news)
+		basic_machine=mips-sony
+		os=-newsos
+		;;
+	necv70)
+		basic_machine=v70-nec
+		os=-sysv
+		;;
+	next | m*-next )
+		basic_machine=m68k-next
+		case $os in
+		    -nextstep* )
+			;;
+		    -ns2*)
+		      os=-nextstep2
+			;;
+		    *)
+		      os=-nextstep3
+			;;
+		esac
+		;;
+	nh3000)
+		basic_machine=m68k-harris
+		os=-cxux
+		;;
+	nh[45]000)
+		basic_machine=m88k-harris
+		os=-cxux
+		;;
+	nindy960)
+		basic_machine=i960-intel
+		os=-nindy
+		;;
+	mon960)
+		basic_machine=i960-intel
+		os=-mon960
+		;;
+	nonstopux)
+		basic_machine=mips-compaq
+		os=-nonstopux
+		;;
+	np1)
+		basic_machine=np1-gould
+		;;
+	nsr-tandem)
+		basic_machine=nsr-tandem
+		;;
+	op50n-* | op60c-*)
+		basic_machine=hppa1.1-oki
+		os=-proelf
+		;;
+	or32 | or32-*)
+		basic_machine=or32-unknown
+		os=-coff
+		;;
+	os400)
+		basic_machine=powerpc-ibm
+		os=-os400
+		;;
+	OSE68000 | ose68000)
+		basic_machine=m68000-ericsson
+		os=-ose
+		;;
+	os68k)
+		basic_machine=m68k-none
+		os=-os68k
+		;;
+	pa-hitachi)
+		basic_machine=hppa1.1-hitachi
+		os=-hiuxwe2
+		;;
+	paragon)
+		basic_machine=i860-intel
+		os=-osf
+		;;
+	pbd)
+		basic_machine=sparc-tti
+		;;
+	pbb)
+		basic_machine=m68k-tti
+		;;
+	pc532 | pc532-*)
+		basic_machine=ns32k-pc532
+		;;
+	pentium | p5 | k5 | k6 | nexgen | viac3)
+		basic_machine=i586-pc
+		;;
+	pentiumpro | p6 | 6x86 | athlon | athlon_*)
+		basic_machine=i686-pc
+		;;
+	pentiumii | pentium2 | pentiumiii | pentium3)
+		basic_machine=i686-pc
+		;;
+	pentium4)
+		basic_machine=i786-pc
+		;;
+	pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+		basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumpro-* | p6-* | 6x86-* | athlon-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+		basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pentium4-*)
+		basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	pn)
+		basic_machine=pn-gould
+		;;
+	power)	basic_machine=power-ibm
+		;;
+	ppc)	basic_machine=powerpc-unknown
+		;;
+	ppc-*)	basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppcle | powerpclittle | ppc-le | powerpc-little)
+		basic_machine=powerpcle-unknown
+		;;
+	ppcle-* | powerpclittle-*)
+		basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64)	basic_machine=powerpc64-unknown
+		;;
+	ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+		basic_machine=powerpc64le-unknown
+		;;
+	ppc64le-* | powerpc64little-*)
+		basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+		;;
+	ps2)
+		basic_machine=i386-ibm
+		;;
+	pw32)
+		basic_machine=i586-unknown
+		os=-pw32
+		;;
+	rom68k)
+		basic_machine=m68k-rom68k
+		os=-coff
+		;;
+	rm[46]00)
+		basic_machine=mips-siemens
+		;;
+	rtpc | rtpc-*)
+		basic_machine=romp-ibm
+		;;
+	s390 | s390-*)
+		basic_machine=s390-ibm
+		;;
+	s390x | s390x-*)
+		basic_machine=s390x-ibm
+		;;
+	sa29200)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	sb1)
+		basic_machine=mipsisa64sb1-unknown
+		;;
+	sb1el)
+		basic_machine=mipsisa64sb1el-unknown
+		;;
+	sei)
+		basic_machine=mips-sei
+		os=-seiux
+		;;
+	sequent)
+		basic_machine=i386-sequent
+		;;
+	sh)
+		basic_machine=sh-hitachi
+		os=-hms
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparclite-wrs | simso-wrs)
+		basic_machine=sparclite-wrs
+		os=-vxworks
+		;;
+	sps7)
+		basic_machine=m68k-bull
+		os=-sysv2
+		;;
+	spur)
+		basic_machine=spur-unknown
+		;;
+	st2000)
+		basic_machine=m68k-tandem
+		;;
+	stratus)
+		basic_machine=i860-stratus
+		os=-sysv4
+		;;
+	sun2)
+		basic_machine=m68000-sun
+		;;
+	sun2os3)
+		basic_machine=m68000-sun
+		os=-sunos3
+		;;
+	sun2os4)
+		basic_machine=m68000-sun
+		os=-sunos4
+		;;
+	sun3os3)
+		basic_machine=m68k-sun
+		os=-sunos3
+		;;
+	sun3os4)
+		basic_machine=m68k-sun
+		os=-sunos4
+		;;
+	sun4os3)
+		basic_machine=sparc-sun
+		os=-sunos3
+		;;
+	sun4os4)
+		basic_machine=sparc-sun
+		os=-sunos4
+		;;
+	sun4sol2)
+		basic_machine=sparc-sun
+		os=-solaris2
+		;;
+	sun3 | sun3-*)
+		basic_machine=m68k-sun
+		;;
+	sun4)
+		basic_machine=sparc-sun
+		;;
+	sun386 | sun386i | roadrunner)
+		basic_machine=i386-sun
+		;;
+	sv1)
+		basic_machine=sv1-cray
+		os=-unicos
+		;;
+	symmetry)
+		basic_machine=i386-sequent
+		os=-dynix
+		;;
+	t3e)
+		basic_machine=alphaev5-cray
+		os=-unicos
+		;;
+	t90)
+		basic_machine=t90-cray
+		os=-unicos
+		;;
+	tic54x | c54x*)
+		basic_machine=tic54x-unknown
+		os=-coff
+		;;
+	tic55x | c55x*)
+		basic_machine=tic55x-unknown
+		os=-coff
+		;;
+	tic6x | c6x*)
+		basic_machine=tic6x-unknown
+		os=-coff
+		;;
+	tx39)
+		basic_machine=mipstx39-unknown
+		;;
+	tx39el)
+		basic_machine=mipstx39el-unknown
+		;;
+	toad1)
+		basic_machine=pdp10-xkl
+		os=-tops20
+		;;
+	tower | tower-32)
+		basic_machine=m68k-ncr
+		;;
+	tpf)
+		basic_machine=s390x-ibm
+		os=-tpf
+		;;
+	udi29k)
+		basic_machine=a29k-amd
+		os=-udi
+		;;
+	ultra3)
+		basic_machine=a29k-nyu
+		os=-sym1
+		;;
+	v810 | necv810)
+		basic_machine=v810-nec
+		os=-none
+		;;
+	vaxv)
+		basic_machine=vax-dec
+		os=-sysv
+		;;
+	vms)
+		basic_machine=vax-dec
+		os=-vms
+		;;
+	vpp*|vx|vx-*)
+		basic_machine=f301-fujitsu
+		;;
+	vxworks960)
+		basic_machine=i960-wrs
+		os=-vxworks
+		;;
+	vxworks68)
+		basic_machine=m68k-wrs
+		os=-vxworks
+		;;
+	vxworks29k)
+		basic_machine=a29k-wrs
+		os=-vxworks
+		;;
+	w65*)
+		basic_machine=w65-wdc
+		os=-none
+		;;
+	w89k-*)
+		basic_machine=hppa1.1-winbond
+		os=-proelf
+		;;
+	xbox)
+		basic_machine=i686-pc
+		os=-mingw32
+		;;
+	xps | xps100)
+		basic_machine=xps100-honeywell
+		;;
+	ymp)
+		basic_machine=ymp-cray
+		os=-unicos
+		;;
+	z8k-*-coff)
+		basic_machine=z8k-unknown
+		os=-sim
+		;;
+	none)
+		basic_machine=none-none
+		os=-none
+		;;
+
+# Here we handle the default manufacturer of certain CPU types.  It is in
+# some cases the only manufacturer, in others, it is the most popular.
+	w89k)
+		basic_machine=hppa1.1-winbond
+		;;
+	op50n)
+		basic_machine=hppa1.1-oki
+		;;
+	op60c)
+		basic_machine=hppa1.1-oki
+		;;
+	romp)
+		basic_machine=romp-ibm
+		;;
+	mmix)
+		basic_machine=mmix-knuth
+		;;
+	rs6000)
+		basic_machine=rs6000-ibm
+		;;
+	vax)
+		basic_machine=vax-dec
+		;;
+	pdp10)
+		# there are many clones, so DEC is not a safe bet
+		basic_machine=pdp10-unknown
+		;;
+	pdp11)
+		basic_machine=pdp11-dec
+		;;
+	we32k)
+		basic_machine=we32k-att
+		;;
+	sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele)
+		basic_machine=sh-unknown
+		;;
+	sh64)
+		basic_machine=sh64-unknown
+		;;
+	sparc | sparcv8 | sparcv9 | sparcv9b)
+		basic_machine=sparc-sun
+		;;
+	cydra)
+		basic_machine=cydra-cydrome
+		;;
+	orion)
+		basic_machine=orion-highlevel
+		;;
+	orion105)
+		basic_machine=clipper-highlevel
+		;;
+	mac | mpw | mac-mpw)
+		basic_machine=m68k-apple
+		;;
+	pmac | pmac-mpw)
+		basic_machine=powerpc-apple
+		;;
+	*-unknown)
+		# Make sure to match an already-canonicalized machine name.
+		;;
+	*)
+		echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+		exit 1
+		;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+	*-digital*)
+		basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+		;;
+	*-commodore*)
+		basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+		;;
+	*)
+		;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+        # First match some system type aliases
+        # that might get confused with valid system types.
+	# -solaris* is a basic system type, with this one exception.
+	-solaris1 | -solaris1.*)
+		os=`echo $os | sed -e 's|solaris1|sunos4|'`
+		;;
+	-solaris)
+		os=-solaris2
+		;;
+	-svr4*)
+		os=-sysv4
+		;;
+	-unixware*)
+		os=-sysv4.2uw
+		;;
+	-gnu/linux*)
+		os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+		;;
+	# First accept the basic system types.
+	# The portable systems comes first.
+	# Each alternative MUST END IN A *, to match a version number.
+	# -sysv* is not here because it comes later, after sysvr4.
+	-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+	      | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
+	      | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
+	      | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+	      | -aos* \
+	      | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+	      | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+	      | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \
+	      | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+	      | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+	      | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+	      | -chorusos* | -chorusrdb* \
+	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+	      | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+	      | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+	      | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+	      | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly*)
+	# Remember, each alternative MUST END IN *, to match a version number.
+		;;
+	-qnx*)
+		case $basic_machine in
+		    x86-* | i*86-*)
+			;;
+		    *)
+			os=-nto$os
+			;;
+		esac
+		;;
+	-nto-qnx*)
+		;;
+	-nto*)
+		os=`echo $os | sed -e 's|nto|nto-qnx|'`
+		;;
+	-sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+	      | -windows* | -osx | -abug | -netware* | -os9* | -beos* \
+	      | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+		;;
+	-mac*)
+		os=`echo $os | sed -e 's|mac|macos|'`
+		;;
+	-linux-dietlibc)
+		os=-linux-dietlibc
+		;;
+	-linux*)
+		os=`echo $os | sed -e 's|linux|linux-gnu|'`
+		;;
+	-sunos5*)
+		os=`echo $os | sed -e 's|sunos5|solaris2|'`
+		;;
+	-sunos6*)
+		os=`echo $os | sed -e 's|sunos6|solaris3|'`
+		;;
+	-opened*)
+		os=-openedition
+		;;
+        -os400*)
+		os=-os400
+		;;
+	-wince*)
+		os=-wince
+		;;
+	-osfrose*)
+		os=-osfrose
+		;;
+	-osf*)
+		os=-osf
+		;;
+	-utek*)
+		os=-bsd
+		;;
+	-dynix*)
+		os=-bsd
+		;;
+	-acis*)
+		os=-aos
+		;;
+	-atheos*)
+		os=-atheos
+		;;
+	-syllable*)
+		os=-syllable
+		;;
+	-386bsd)
+		os=-bsd
+		;;
+	-ctix* | -uts*)
+		os=-sysv
+		;;
+	-nova*)
+		os=-rtmk-nova
+		;;
+	-ns2 )
+		os=-nextstep2
+		;;
+	-nsk*)
+		os=-nsk
+		;;
+	# Preserve the version number of sinix5.
+	-sinix5.*)
+		os=`echo $os | sed -e 's|sinix|sysv|'`
+		;;
+	-sinix*)
+		os=-sysv4
+		;;
+        -tpf*)
+		os=-tpf
+		;;
+	-triton*)
+		os=-sysv3
+		;;
+	-oss*)
+		os=-sysv3
+		;;
+	-svr4)
+		os=-sysv4
+		;;
+	-svr3)
+		os=-sysv3
+		;;
+	-sysvr4)
+		os=-sysv4
+		;;
+	# This must come after -sysvr4.
+	-sysv*)
+		;;
+	-ose*)
+		os=-ose
+		;;
+	-es1800*)
+		os=-ose
+		;;
+	-xenix)
+		os=-xenix
+		;;
+	-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+		os=-mint
+		;;
+	-aros*)
+		os=-aros
+		;;
+	-kaos*)
+		os=-kaos
+		;;
+	-zvmoe)
+		os=-zvmoe
+		;;
+	-none)
+		;;
+	*)
+		# Get rid of the `-' at the beginning of $os.
+		os=`echo $os | sed 's/[^-]*-//'`
+		echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+		exit 1
+		;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system.  Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+	*-acorn)
+		os=-riscix1.2
+		;;
+	arm*-rebel)
+		os=-linux
+		;;
+	arm*-semi)
+		os=-aout
+		;;
+    c4x-* | tic4x-*)
+        os=-coff
+        ;;
+	# This must come before the *-dec entry.
+	pdp10-*)
+		os=-tops20
+		;;
+	pdp11-*)
+		os=-none
+		;;
+	*-dec | vax-*)
+		os=-ultrix4.2
+		;;
+	m68*-apollo)
+		os=-domain
+		;;
+	i386-sun)
+		os=-sunos4.0.2
+		;;
+	m68000-sun)
+		os=-sunos3
+		# This also exists in the configure program, but was not the
+		# default.
+		# os=-sunos4
+		;;
+	m68*-cisco)
+		os=-aout
+		;;
+	mips*-cisco)
+		os=-elf
+		;;
+	mips*-*)
+		os=-elf
+		;;
+	or32-*)
+		os=-coff
+		;;
+	*-tti)	# must be before sparc entry or we get the wrong os.
+		os=-sysv3
+		;;
+	sparc-* | *-sun)
+		os=-sunos4.1.1
+		;;
+	*-be)
+		os=-beos
+		;;
+	*-ibm)
+		os=-aix
+		;;
+    	*-knuth)
+		os=-mmixware
+		;;
+	*-wec)
+		os=-proelf
+		;;
+	*-winbond)
+		os=-proelf
+		;;
+	*-oki)
+		os=-proelf
+		;;
+	*-hp)
+		os=-hpux
+		;;
+	*-hitachi)
+		os=-hiux
+		;;
+	i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+		os=-sysv
+		;;
+	*-cbm)
+		os=-amigaos
+		;;
+	*-dg)
+		os=-dgux
+		;;
+	*-dolphin)
+		os=-sysv3
+		;;
+	m68k-ccur)
+		os=-rtu
+		;;
+	m88k-omron*)
+		os=-luna
+		;;
+	*-next )
+		os=-nextstep
+		;;
+	*-sequent)
+		os=-ptx
+		;;
+	*-crds)
+		os=-unos
+		;;
+	*-ns)
+		os=-genix
+		;;
+	i370-*)
+		os=-mvs
+		;;
+	*-next)
+		os=-nextstep3
+		;;
+	*-gould)
+		os=-sysv
+		;;
+	*-highlevel)
+		os=-bsd
+		;;
+	*-encore)
+		os=-bsd
+		;;
+	*-sgi)
+		os=-irix
+		;;
+	*-siemens)
+		os=-sysv4
+		;;
+	*-masscomp)
+		os=-rtu
+		;;
+	f30[01]-fujitsu | f700-fujitsu)
+		os=-uxpv
+		;;
+	*-rom68k)
+		os=-coff
+		;;
+	*-*bug)
+		os=-coff
+		;;
+	*-apple)
+		os=-macos
+		;;
+	*-atari*)
+		os=-mint
+		;;
+	*)
+		os=-none
+		;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer.  We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+	*-unknown)
+		case $os in
+			-riscix*)
+				vendor=acorn
+				;;
+			-sunos*)
+				vendor=sun
+				;;
+			-aix*)
+				vendor=ibm
+				;;
+			-beos*)
+				vendor=be
+				;;
+			-hpux*)
+				vendor=hp
+				;;
+			-mpeix*)
+				vendor=hp
+				;;
+			-hiux*)
+				vendor=hitachi
+				;;
+			-unos*)
+				vendor=crds
+				;;
+			-dgux*)
+				vendor=dg
+				;;
+			-luna*)
+				vendor=omron
+				;;
+			-genix*)
+				vendor=ns
+				;;
+			-mvs* | -opened*)
+				vendor=ibm
+				;;
+			-os400*)
+				vendor=ibm
+				;;
+			-ptx*)
+				vendor=sequent
+				;;
+			-tpf*)
+				vendor=ibm
+				;;
+			-vxsim* | -vxworks* | -windiss*)
+				vendor=wrs
+				;;
+			-aux*)
+				vendor=apple
+				;;
+			-hms*)
+				vendor=hitachi
+				;;
+			-mpw* | -macos*)
+				vendor=apple
+				;;
+			-*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+				vendor=atari
+				;;
+			-vos*)
+				vendor=stratus
+				;;
+		esac
+		basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+		;;
+esac
+
+echo $basic_machine$os
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
Index: branches/network/configure.ac
===================================================================
--- branches/network/configure.ac	(revision 6636)
+++ branches/network/configure.ac	(revision 6636)
@@ -0,0 +1,662 @@
+
+##########################################################################
+#   orxonox - the future of 3D-vertical-scrollers                        #
+#                                                                        #
+#   Copyright (C) 2004 orx                                               #
+#                                                                        #
+#   This program is free software; you can redistribute it and/or modify #
+#   it under the terms of the GNU General Public License as published by #
+#   the Free Software Foundation; either version 2, or (at your option)  #
+#   any later version.                                                   #
+#                                                                        #
+#   ### File Specific:                                                   #
+#   main-programmer: Benjamin Grauer                                     #
+#   co-programmer: ...                                                   #
+#                                                                        #
+#   This is the main configuration File of autoconf.                     #
+#   Please edit this file only, if you exactly know what you are doing.  #
+#   It is quite fragile, and compiling orxonox on different Platforms    #
+#   is only guarantied, if build with the right config.                  #
+#                                                                        #
+#   be sure to visit us at http://www.orxonox.net                        #
+##########################################################################
+
+#########################
+## AUTOCONF INIT PHASE ##
+#########################
+AC_PREREQ(2.59)
+AC_INIT([orxonox], [0.3.2_alpha], [orxonox-dev at mail.datacore.ch])
+
+## Detect the canonical host and target build environment.
+AC_CANONICAL_BUILD
+AC_CANONICAL_HOST
+AC_CANONICAL_TARGET
+
+AM_INIT_AUTOMAKE
+
+AC_CONFIG_SRCDIR([./src])
+AC_CONFIG_HEADER([config.h])
+
+#########################
+## Checks for programs ##
+#########################
+AC_PROG_CXX
+AC_PROG_RANLIB
+AC_HEADER_STDC
+
+## THIS IS OUR DEFAULT-DATA-DIRECTORY
+
+##################################
+## CHECKING  OPTIONAL ARGUMENTS ##
+##################################
+#----------------#
+# Data-Directory #
+#----------------#
+DATA_DIR=$datadir
+echo \$\{prefix\}
+if test $DATA_DIR = \$\{prefix\}/share ; then
+        echo "not given"
+        DATA_DIR=/usr/share
+else
+        echo "given: $DATA_DIR"
+fi
+AC_DEFINE_UNQUOTED([DATADIR], ["$DATA_DIR"],
+                   [Define to the read-only architecture-independent
+                    data directory.])
+
+#-----------------#
+# shared-lib-path #
+#-----------------#
+SHARED_LIB_PATH=no
+AC_MSG_CHECKING([shared lib path])
+AC_ARG_WITH([shared-lib-path],
+        AS_HELP_STRING(--with-shared-lib-path,Tells the executable, where to look for the shared libraries.),
+         SHARED_LIB_PATH=$withval)
+if test x$SHARED_LIB_PATH != xno; then
+        echo "set to $SHARED_LIB_PATH"
+else
+        echo "no"
+fi
+
+
+#-----------------#
+# DEBUG-statement #
+#-----------------#
+DEBUG=no
+AC_MSG_CHECKING([if DEBUG-mode should be enabled])
+AC_ARG_ENABLE([debug],
+        AS_HELP_STRING(--enable-debug,compiles in debug mode. Lots of debug info about the game.),
+         DEBUG=$enableval)
+
+if test x$DEBUG = xno; then
+        echo "no"
+        echo " -> Setting debuglevel to 4. (orxonox is still in Development. It really is needed."
+        DEBUG=4
+elif test x$DEBUG = xyes; then
+        echo "yes"
+        echo " -> Setting debuglevel to 4. HARD DEBUG MODE!!."
+        DEBUG=4
+else
+        echo "yes: setting debuglevel to to $DEBUG"
+fi
+AC_DEFINE_UNQUOTED(DEBUG, $DEBUG, [in which debug mode we are])
+AC_SUBST(DEBUG)
+
+#---------------#
+# Modular Debug #
+#---------------#
+MODULAR_DEBUG=yes
+AC_MSG_CHECKING([if Modular-DEBUG-mode should be ebabled])
+AC_ARG_ENABLE([modular-debug],
+        AS_HELP_STRING(--disable-modular-debug,compiles in modular-debug mode, that logs differently on the many modules of orxonox.),
+         MODULAR_DEBUG=$enableval)
+
+if test x$MODULAR_DEBUG = xno; then
+        echo "no"
+elif test x$MODULAR_DEBUG = xyes; then
+        echo "yes"
+        AC_DEFINE_UNQUOTED(MODULAR_DEBUG, 1, [if Modular-DUBUG mode is enabled])
+fi
+
+#--------------#
+# GTK-disabled #
+#--------------#
+AC_MSG_CHECKING([if gtk should be enabled])
+AC_ARG_ENABLE([gtk],
+        AS_HELP_STRING(--disable-gtk,Prevents GTK from being loaded), [def_gtk=no], [def_gtk=yes])
+if test x$def_gtk = xyes; then
+  echo "yes"
+fi
+if test x$def_gtk = xno; then
+  echo "no"
+fi
+
+#------------------#
+# libCurl-disabled #
+#------------------#
+AC_MSG_CHECKING([if libcURL should be enabled])
+AC_ARG_ENABLE([curl],
+        AS_HELP_STRING(--disable-curl,Prevents libcURL from being loaded), [def_curl=no], [def_curl=yes])
+if test x$def_curl = xyes; then
+  echo "yes"
+fi
+if test x$def_curl = xno; then
+  echo "no"
+fi
+
+#-------------------#
+# SubProject-enable #
+#-------------------#
+def_sub_projects=no
+AC_MSG_CHECKING([if the SubProjects should be built])
+AC_ARG_WITH([sub-projects],
+        AS_HELP_STRING(--with-sub-projects,also builds the subProjects while make from srcdir), [def_sub_projects=yes])
+if test x$def_sub_projects = xyes; then
+  echo "yes"
+fi
+if test x$def_sub_projects = xno; then
+  echo "no"
+fi
+AM_CONDITIONAL(SUB_PROJECTS, test x$def_sub_projects = xyes)
+
+#-------------------#
+# Profiling Enabled #
+#-------------------#
+def_profiling=no
+AC_MSG_CHECKING([if Profiling should be enabled])
+AC_ARG_ENABLE([profile],
+        AS_HELP_STRING(--enable-profile,builds orxonox with profiling support), [def_profiling=yes])
+if test x$def_profiling = xyes; then
+  echo "yes"
+  CXXFLAGS="$CXXFLAGS -pg"
+fi
+if test x$def_profiling = xno; then
+  echo "no"
+fi
+
+#----------------#
+# efence Enabled #
+#----------------#
+def_efence=no
+AC_MSG_CHECKING([if efence should be enabled])
+AC_ARG_ENABLE([efence],
+        AS_HELP_STRING(--enable-efence,builds orxonox with efence support), [def_efence=yes])
+if test x$def_efence = xyes; then
+  echo "yes"
+fi
+if test x$def_efence = xno; then
+  echo "no"
+fi
+
+#----------------------#
+# Documentation-enable #
+#----------------------#
+def_documentation=no
+AC_MSG_CHECKING([if the Documentation should be build by default])
+AC_ARG_ENABLE([documentation],
+        AS_HELP_STRING(--enable-documentation,also builds the sDocumentation while make from srcdir), [def_documentation=yes])
+if test x$def_documentation = xyes; then
+  echo "yes"
+fi
+if test x$def_documentation = xno; then
+  echo "no"
+fi
+AM_CONDITIONAL(DOCUMENTATION, test x$def_documentation = xyes)
+
+
+
+#---------------------------#
+# WITH TARDIS (convenience) #
+#---------------------------#
+def_tardis=no
+GTKPATH=""
+AC_MSG_CHECKING([convenience flag for working at the taris in the ETH zurich])
+AC_ARG_WITH([tardis],
+        AS_HELP_STRING(--with-tardis,sets all the necesary environment flags for linux-TARDIS boxes at the ETH Zurich), [def_tardis=yes])
+if test x$def_tardis = xyes; then
+  ARCH=i686-debian-linux3.1
+   ## GAMELIBS
+  PREFIX=/usr/pack/gamelibs-1.0-to
+  CPPFLAGS="${CPPFLAGS} -I${PREFIX}/include"
+  LDFLAGS="${LDFLAGS} -L$PREFIX/${ARCH}/lib -Wl,-rpath -Wl,${PREFIX}/${ARCH}/lib"
+  ## GTK
+  GTKPREFIX=/usr/pack/gtk-2.8.3-mo
+  GTKPATH=${GTKPREFIX}/${ARCH}/bin
+  CPPFLAGS="${CPPFLAGS} -I${GTKPREFIX}/include"
+  LDFLAGS="${LDFLAGS} -L${GTKPREFIX}/${ARCH}/lib -Wl,-rpath -Wl,${GTKPREFIX}/${ARCH}/lib"
+  echo "yes"
+fi
+if test x$def_tardis = xno; then
+  echo "no"
+fi
+
+#######################
+## PROGRAMM CHECKING ##
+## 3. party Programs ##
+#######################
+
+#----------------------#
+# checking for Doxygen #
+#----------------------#
+AC_PATH_PROG(DOXYGEN, doxygen)
+AM_CONDITIONAL(DOXYGEN, test $DOXYGEN)
+
+#--------------------#
+# checking for gprof #
+#--------------------#
+AC_PATH_PROG(GPROF, gprof)
+
+#-------------------------#
+# checking for pkg-config #
+#-------------------------#
+if test x$def_gtk = xyes; then
+ if test x${GTKPATH} != x; then
+   AC_PATH_PROG([PKG_CONFIG], [pkg-config],[], $GTKPATH )
+ else
+   AC_PATH_PROG(PKG_CONFIG, pkg-config )
+ fi
+fi
+
+
+#########################
+## CHECKING FOR SYSTEM ##
+#########################
+## here the system is checked, and openGL is included
+## also checking for SDL on differen Systems
+
+AC_MSG_CHECKING([for System])
+## checking for openGL-environment and other sys-specific parameters
+case "$target" in
+
+###########
+#---------#
+# WINDOWS #
+#---------#
+###########
+  *-*-mingw32*)
+echo "mingw-WINDOWS detected"
+
+CPPFLAGS="-I/usr/include -I/mingw/include $CPPFLAGS"
+
+    mingw="yes"
+    MSBITFIELDS="-mms-bitfields"
+    MWINDOWS="-mwindows"
+
+#--------#
+# MIN-GW #
+#--------#
+# checking for mingw32
+    AC_CHECK_LIB([mingw32], [main], FOUND_mingw32=yes)
+    if test x$FOUND_mingw32 = xyes; then
+        LIBS="$LIBS -lmingw32"
+    fi
+
+#---------------#
+# open-GL (win) #
+#---------------#
+# checking gl header
+   AC_CHECK_HEADERS(GL/gl.h ,,
+      [AC_MSG_ERROR([cannot find opengl headers])])
+#   checking for Windows openGl library
+    AC_CHECK_LIB([opengl32], [main], [FOUND_GL=yes; LIBS="$LIBS -lopengl32"])
+    if test x$FOUND_GL != xyes ; then
+         echo "------------------"
+         echo "opengl not found."
+         echo "please install the opengl package which can be found at http://www.opengl.org"
+         echo "------------------"
+         exit -1
+    fi
+
+# cheking for GLU-header
+    AC_CHECK_HEADERS([GL/glu.h] ,,
+      [AC_MSG_ERROR([cannot find opengl headers]) ])
+
+# checking for libGLU
+    AC_CHECK_LIB([glu32], [main], [FOUND_GLU=yes; LIBS="$LIBS -lGLU32"])
+    if test x$FOUND_GLU != xyes ; then
+         echo "------------------"
+         echo "GLU library not found."
+         echo "please install the GLU library, that should come with openGL, which can be found at http://www.opengl.org"
+         echo "------------------"
+         exit -1
+    fi
+
+# checking glew header
+   AC_CHECK_HEADERS(GL/glew.h ,,
+      [AC_MSG_ERROR([cannot find opengl extension wrangler headers]) ])
+#   checking for Windows glew library
+    AC_CHECK_LIB([glew32], [main], [FOUND_GLEW=yes; LIBS="$LIBS -lglew32"])
+    if test x$FOUND_GLEW != xyes ; then
+         echo "------------------"
+         echo "opengl extension wrangler not found."
+         echo "please install the glew package which can be found at http://glew.sourceforge.net"
+         echo "------------------"
+         exit -1
+    fi
+
+#--------#
+# openAL #
+#--------#
+# checking for openAL-headers
+  AC_CHECK_HEADERS([AL/al.h] ,,
+      [AC_MSG_ERROR([cannot find openAL header.])])
+# checking for openAL-lib
+  AC_CHECK_LIB([OpenAL32], [main], [FOUND_OPENAL=yes; LIBS="$LIBS -lOpenAL32"])
+  AC_CHECK_LIB([ALut], [main], [FOUND_ALUT=yes; LIBS="-lALut $LIBS"])
+     if test x$FOUND_OPENAL != xyes ; then
+        echo "------------------"
+        echo "openal library not found."
+        echo "please install the openal library, which can be found at http://www.openal.org"
+        echo "------------------"
+        exit -1
+     fi
+
+
+#-----------#
+# SDL(win) #
+#-----------#
+# checking for SDL-headers
+    AC_CHECK_HEADERS([SDL/SDL.h] ,,
+      [AC_MSG_ERROR([cannot find SDL headers]) ])
+
+#checking for libSDL
+    AC_CHECK_LIB([sdlmain], [main], [FOUND_sdlmain=yes; LIBS="$LIBS -lsdlmain"])
+    if test x$FOUND_sdlmain != xyes ; then
+        echo "------------------"
+        echo "SDL library not found."
+        echo "please install the SDL library, which can be found at http://www.libsdl.org"
+        echo "------------------"
+        exit 1
+    fi
+    AC_CHECK_LIB([sdl], [main], [FOUND_SDL=yes; LIBS="$LIBS -lsdl"])
+    if test x$FOUND_SDL != xyes ; then
+        echo "------------------"
+        echo "SDL library not found."
+        echo "please install the SDL library, which can be found at http://www.libsdl.org"
+        echo "------------------"
+        exit -1
+    fi
+
+  ;;
+
+#########
+#-------#
+# LINUX #
+#-------#
+#########
+ *-*-linux*)
+echo "Linux detected"
+
+ Linux="yes"
+
+##CPPFLAGS="-I/usr/include $CPPFLAGS"
+##LDFLAGS="-L/usr/lib $LDFLAGS"
+if test x$SHARED_LIB_PATH != xno; then
+        echo "setting new LDFLAGS with $SHARED_LIB_PATH"
+        LDFLAGS="-Wl,-rpath,$SHARED_LIB_PATH -L$SHARED_LIB_PATH $LDFLAGS"
+fi
+
+#--------#
+# openGL #
+#--------#
+AX_CHECK_REQUIRED_HEADER_LIB([GL/gl.h], [GL], [main],,, [http://www.opengl.org])
+AX_CHECK_REQUIRED_HEADER_LIB([GL/glu.h], [GLU], [main],,, [http://www.opengl.org])
+AX_CHECK_REQUIRED_HEADER_LIB([GL/glew.h], [GLEW], [main],,, [http://glew.sourceforge.net])
+
+#--------#
+# openAL #
+#--------#
+
+AX_CHECK_REQUIRED_HEADER_LIB([AL/al.h], [openal], [main],,, [http://www.openal.org])
+AX_CHECK_HEADER_LIB([AL/alut.h], [alut], [main],,, [http://www.openal.org])
+
+#-----#
+# SDL #
+#-----#
+# checking for SDL
+  AC_MSG_CHECKING([for SDL-version])
+  SDL_VERSION=`sdl-config --version`
+  echo $SDL_VERSION
+   CPPFLAGS="$CPPFLAGS `sdl-config --cflags`"
+
+  AX_CHECK_REQUIRED_HEADER_LIB([SDL.h SDL/SDL.h], [SDL], [main],,, [http://www.libsdl.org])
+
+    ;;
+
+#############
+#-----------#
+# MAC -OS X #
+#-----------#
+#############
+ *darwin*)
+ echo "OS X detected"
+
+ osX="yes"
+
+ CPPFLAGS="-I/sw/include -I/sw/include $CPPFLAGS"
+ LDFLAGS="$LDFLAGS -L/sw/lib"
+# checking gl header
+   AC_CHECK_HEADERS([OpenGL/gl.h] ,,
+      [AC_MSG_ERROR([cannot find opengl headers]) ])
+# cheking for GLU-header
+    AC_CHECK_HEADERS([OpenGL/glu.h] ,,
+      [AC_MSG_ERROR([cannot find opengl headers]) ])
+
+   LIBS="$LIBS -framework OpenGL"
+
+
+
+# checking for GLEW-headers
+   AC_CHECK_HEADERS([GL/glew.h] ,,
+      [AC_MSG_ERROR([cannot find glew headers]) ])
+# checking for GLEW-lib
+  AC_CHECK_LIB([GLEW], [main], [FOUND_GLEW=yes; LIBS="$LIBS -lGLEW"])
+   if test x$FOUND_GLEW != xyes ; then
+         echo "------------------"
+         echo "glew not found."
+         echo "please install the glew package which can be found at http://glew.sourceforge.net"
+         echo "------------------"
+         exit -1
+   fi
+
+
+   AC_CHECK_HEADERS([OpenAL/al.h] ,,
+      [AC_MSG_ERROR([cannot find opengl headers]) ])
+  HAVE_OPENAL=yes
+  LIBS="$LIBS -framework OpenAL"
+
+
+## SDL-check
+       SDL_CFLAGS=`sdl-config --cflags`
+       SDL_LIBS=`sdl-config --libs`
+       CXXFLAGS="$CXXFLAGS $SDL_CFLAGS"
+       LIBS="$LIBS $SDL_LIBS"
+   AC_CHECK_HEADERS([SDL/SDL.h] ,,
+      [AC_MSG_ERROR([cannot find SDL headers]) ])
+   HAVE_SDL=yes
+#   LIBS="$LIBS -framework SDL"
+
+# checking for SDL-headers
+#    AC_CHECK_HEADERS(SDL/SDL.h ,,
+#      [AC_MSG_ERROR([cannot find SDL headers]) ])
+
+## checking for SDL
+#    SDL_VERSION=1.2.7
+#    AM_PATH_SDL($SDL_VERSION,
+#      :,
+#      AC_MSG_ERROR([*** SDL version $SDL_VERSION not found!])
+#      )
+
+
+    ;;
+
+  *)
+    ;;
+esac
+
+AC_SUBST(MSBITFIELDS)
+
+###################################
+## CHECKING FOR HEADERS AND LIBS ##
+###################################
+
+#---------#
+# SDL_ttf #
+#---------#
+AX_CHECK_REQUIRED_HEADER_LIB([SDL_ttf.h SDL/SDL_ttf.h], [SDL_ttf], [TTF_OpenFont],,, [http://www.libsdl.org/projects/SDL_ttf])
+#-----------#
+# SDL_Image #
+#-----------#
+AX_CHECK_REQUIRED_HEADER_LIB([SDL_image.h SDL/SDL_image.h], [SDL_image], [main],,, [http://www.libsdl.org/projects/SDL_image])
+#---------#
+# SDL_Net #
+#---------#
+AX_CHECK_REQUIRED_HEADER_LIB([SDL_net.h SDL/SDL_net.h], [SDL_net], [main],,, [http://www.libsdl.org/projects/SDL_net])
+
+#-----#
+# ogg #
+#-----#
+AX_CHECK_REQUIRED_HEADER_LIB([ogg/ogg.h], [ogg], [main],,, [http://www.xiph.org/ogg/vorbis/index.html])
+#--------#
+# vorbis #
+#--------#
+AX_CHECK_REQUIRED_HEADER_LIB([vorbis/codec.h], [vorbis], [main],,, [http://www.xiph.org/ogg/vorbis/index.html])
+AX_CHECK_REQUIRED_HEADER_LIB([vorbis/vorbisfile.h], [vorbisfile], [main],,, [http://www.xiph.org/ogg/vorbis/index.html])
+
+#--------#
+# FFmpeg #
+#--------#
+# checking for FFmpeg-headers
+  AC_CHECK_HEADERS([avformat.h] ,,
+      [AC_CHECK_HEADERS([ffmpeg/avformat.h] ,,AC_MSG_ERROR([cannot find FFmpeg header.])]))
+# checking for ffmpeg-lib
+  AC_CHECK_LIB([avformat], [main], [FOUND_avformat=yes; LIBS="$LIBS -lavformat"])
+     if test x$FOUND_avformat != xyes ; then
+        echo "------------------"
+        echo "avformat library not found."
+        echo "please install the FFmpeg library, which can be found at http://ffmpeg.sourceforge.net"
+        echo "------------------"
+        exit -1
+     fi
+  AC_CHECK_HEADERS([avcodec.h] ,,
+      [AC_CHECK_HEADERS([ffmpeg/avcodec.h] ,,AC_MSG_ERROR([cannot find FFmpeg header.])]))
+  AC_CHECK_LIB([avcodec], [main], [FOUND_avcodec=yes; LIBS="$LIBS -lavcodec"])
+     if test x$FOUND_avcodec != xyes ; then
+        echo "------------------"
+        echo "avcodec library not found."
+        echo "please install the FFmpeg library, which can be found at http://ffmpeg.sourceforge.net"
+        echo "------------------"
+        exit -1
+     fi
+  AC_CHECK_LIB([avutil], [main], [FOUND_avutil=yes; LIBS="$LIBS -lavutil"])
+
+  AC_CHECK_LIB([gcj], [main], [FOUND_gcj=yes; LIBS="$LIBS -lgcj"])
+
+  AC_CHECK_LIB([theora], [main], [FOUND_theora=yes; LIBS="$LIBS -ltheora"])
+
+  AC_CHECK_LIB([dts], [main], [FOUND_dts=yes; LIBS="$LIBS -ldts"])
+
+  AC_CHECK_LIB([gsm], [main], [FOUND_gsm=yes; LIBS="$LIBS -lgsm"])
+
+  AC_CHECK_LIB([dc1394_control], [main], [FOUND_dc1394_control=yes; LIBS="$LIBS -ldc1394_control"])
+
+  AC_CHECK_LIB([vorbisenc], [main], [FOUND_vorbisenc=yes; LIBS="$LIBS -lvorbisenc"])
+
+#---------#
+# libcURL #
+#---------#
+AX_CHECK_HEADER_LIB([curl/curl.h], [curl], [main], [
+ have_curl=yes
+  CURL_LIBS=`curl-config --libs`
+  CURLCFLAGS=`curl-config --cflags`
+  AC_DEFINE_UNQUOTED(HAVE_CURL, 1, [if we have CURL]) ]
+  ,, [http://curl.haxx.se/])
+
+AC_SUBST(CURL_LIBS)
+AC_SUBST(CURL_CFLAGS)
+AM_CONDITIONAL(HAVE_CURL, test "x$have_curl" = "xyes")
+
+#--------#
+# efence #
+#--------#
+if test x$def_efence = xyes ; then
+  AC_CHECK_LIB([efence], [main], [FOUND_efence=yes; LIBS="$LIBS -lefence"])
+   if test x$FOUND_efence != xyes ; then
+     echo "efence was requested, but is not installed!! going on"
+   fi
+
+fi
+
+#-----#
+# GTK #
+#-----#
+if test x$def_gtk = xyes; then
+#PKG_CHECK_MODULES(GTK2, gtk+-2.0 >= 2.0.3 gthread-2.0 >= 2.0.3, have_gtk2=yes, have_gtk2=no)
+        AC_MSG_CHECKING([for gtk2.0])
+        if `$PKG_CONFIG --exists gtk+-2.0`; then
+                echo "yes"
+                have_gtk2=yes
+                GTK2_LIBS=`$PKG_CONFIG --libs gtk+-2.0`
+                GTK2_CFLAGS=`$PKG_CONFIG --cflags gtk+-2.0`
+                AC_DEFINE_UNQUOTED(HAVE_GTK2, 1, [if we have GTK2])
+                if test $DEBUG -ge 3; then
+                 echo "cflags: $GTK2_CFLAGS"
+                 echo "libs: $GTK2_LIBS"
+                fi
+        else
+                echo "no"
+        fi
+
+fi
+AC_SUBST(GTK2_LIBS)
+AC_SUBST(GTK2_CFLAGS)
+AM_CONDITIONAL(HAVE_GTK2, test x$have_gtk2 = xyes)
+
+
+# FIXME: Replace `main' with a function in `-lm':
+ AC_CHECK_LIB([m], [main])
+
+
+# Checks for header files.
+AC_HEADER_STDC
+AC_CHECK_HEADERS([stdlib.h string.h])
+
+# Checks for typedefs, structures, and compiler characteristics.
+AC_HEADER_STDBOOL
+
+# Checks for library functions.
+AC_FUNC_MALLOC
+AC_CHECK_FUNCS([bzero sqrt])
+
+######################
+## OUTPUT CONFIGURE ##
+######################
+AC_CONFIG_FILES([Makefile
+                 src/Makefile
+                 src/lib/Makefile
+                 src/lib/graphics/Makefile
+                 src/lib/graphics/importer/Makefile
+                 src/lib/graphics/spatial_separation/Makefile
+                 src/lib/sound/Makefile
+                 src/lib/event/Makefile
+                 src/lib/physics/Makefile
+                 src/lib/particles/Makefile
+                 src/lib/collision_detection/Makefile
+		 src/lib/network/Makefile
+                 src/lib/shell/Makefile
+                 src/lib/gui/Makefile
+                 src/lib/gui/gtk_gui/Makefile
+                 src/lib/gui/gl_gui/Makefile
+                 src/lib/parser/Makefile
+                 src/lib/parser/tinyxml/Makefile
+                 src/lib/parser/ini_parser/Makefile
+                 src/util/Makefile
+                 src/subprojects/Makefile
+                 src/subprojects/testmain/Makefile
+                 src/subprojects/importer/Makefile
+                 src/subprojects/particles/Makefile
+                 src/subprojects/collision_detection/Makefile
+                 src/subprojects/network/Makefile
+                 ])
+
+AC_OUTPUT
Index: branches/network/depcomp
===================================================================
--- branches/network/depcomp	(revision 6636)
+++ branches/network/depcomp	(revision 6636)
@@ -0,0 +1,529 @@
+#! /bin/sh
+# depcomp - compile a program generating dependencies as side-effects
+
+scriptversion=2005-02-09.22
+
+# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
+
+case $1 in
+  '')
+     echo "$0: No command.  Try \`$0 --help' for more information." 1>&2
+     exit 1;
+     ;;
+  -h | --h*)
+    cat <<\EOF
+Usage: depcomp [--help] [--version] PROGRAM [ARGS]
+
+Run PROGRAMS ARGS to compile a file, generating dependencies
+as side-effects.
+
+Environment variables:
+  depmode     Dependency tracking mode.
+  source      Source file read by `PROGRAMS ARGS'.
+  object      Object file output by `PROGRAMS ARGS'.
+  DEPDIR      directory where to store dependencies.
+  depfile     Dependency file to output.
+  tmpdepfile  Temporary file to use when outputing dependencies.
+  libtool     Whether libtool is used (yes/no).
+
+Report bugs to <bug-automake@gnu.org>.
+EOF
+    exit $?
+    ;;
+  -v | --v*)
+    echo "depcomp $scriptversion"
+    exit $?
+    ;;
+esac
+
+if test -z "$depmode" || test -z "$source" || test -z "$object"; then
+  echo "depcomp: Variables source, object and depmode must be set" 1>&2
+  exit 1
+fi
+
+# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
+depfile=${depfile-`echo "$object" |
+  sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
+tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
+
+rm -f "$tmpdepfile"
+
+# Some modes work just like other modes, but use different flags.  We
+# parameterize here, but still list the modes in the big case below,
+# to make depend.m4 easier to write.  Note that we *cannot* use a case
+# here, because this file can only contain one case statement.
+if test "$depmode" = hp; then
+  # HP compiler uses -M and no extra arg.
+  gccflag=-M
+  depmode=gcc
+fi
+
+if test "$depmode" = dashXmstdout; then
+   # This is just like dashmstdout with a different argument.
+   dashmflag=-xM
+   depmode=dashmstdout
+fi
+
+case "$depmode" in
+gcc3)
+## gcc 3 implements dependency tracking that does exactly what
+## we want.  Yay!  Note: for some reason libtool 1.4 doesn't like
+## it if -MD -MP comes after the -MF stuff.  Hmm.
+  "$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  mv "$tmpdepfile" "$depfile"
+  ;;
+
+gcc)
+## There are various ways to get dependency output from gcc.  Here's
+## why we pick this rather obscure method:
+## - Don't want to use -MD because we'd like the dependencies to end
+##   up in a subdir.  Having to rename by hand is ugly.
+##   (We might end up doing this anyway to support other compilers.)
+## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
+##   -MM, not -M (despite what the docs say).
+## - Using -M directly means running the compiler twice (even worse
+##   than renaming).
+  if test -z "$gccflag"; then
+    gccflag=-MD,
+  fi
+  "$@" -Wp,"$gccflag$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+## The second -e expression handles DOS-style file names with drive letters.
+  sed -e 's/^[^:]*: / /' \
+      -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
+## This next piece of magic avoids the `deleted header file' problem.
+## The problem is that when a header file which appears in a .P file
+## is deleted, the dependency causes make to die (because there is
+## typically no way to rebuild the header).  We avoid this by adding
+## dummy dependencies for each header file.  Too bad gcc doesn't do
+## this for us directly.
+  tr ' ' '
+' < "$tmpdepfile" |
+## Some versions of gcc put a space before the `:'.  On the theory
+## that the space means something, we add a space to the output as
+## well.
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+hp)
+  # This case exists only to let depend.m4 do its work.  It works by
+  # looking at the text of this script.  This case will never be run,
+  # since it is checked for above.
+  exit 1
+  ;;
+
+sgi)
+  if test "$libtool" = yes; then
+    "$@" "-Wp,-MDupdate,$tmpdepfile"
+  else
+    "$@" -MDupdate "$tmpdepfile"
+  fi
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+
+  if test -f "$tmpdepfile"; then  # yes, the sourcefile depend on other files
+    echo "$object : \\" > "$depfile"
+
+    # Clip off the initial element (the dependent).  Don't try to be
+    # clever and replace this with sed code, as IRIX sed won't handle
+    # lines with more than a fixed number of characters (4096 in
+    # IRIX 6.2 sed, 8192 in IRIX 6.5).  We also remove comment lines;
+    # the IRIX cc adds comments like `#:fec' to the end of the
+    # dependency line.
+    tr ' ' '
+' < "$tmpdepfile" \
+    | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
+    tr '
+' ' ' >> $depfile
+    echo >> $depfile
+
+    # The second pass generates a dummy entry for each header file.
+    tr ' ' '
+' < "$tmpdepfile" \
+   | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
+   >> $depfile
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+aix)
+  # The C for AIX Compiler uses -M and outputs the dependencies
+  # in a .u file.  In older versions, this file always lives in the
+  # current directory.  Also, the AIX compiler puts `$object:' at the
+  # start of each line; $object doesn't have directory information.
+  # Version 6 uses the directory in both cases.
+  stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
+  tmpdepfile="$stripped.u"
+  if test "$libtool" = yes; then
+    "$@" -Wc,-M
+  else
+    "$@" -M
+  fi
+  stat=$?
+
+  if test -f "$tmpdepfile"; then :
+  else
+    stripped=`echo "$stripped" | sed 's,^.*/,,'`
+    tmpdepfile="$stripped.u"
+  fi
+
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+
+  if test -f "$tmpdepfile"; then
+    outname="$stripped.o"
+    # Each line is of the form `foo.o: dependent.h'.
+    # Do two passes, one to just change these to
+    # `$object: dependent.h' and one to simply `dependent.h:'.
+    sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
+    sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
+  else
+    # The sourcefile does not contain any dependencies, so just
+    # store a dummy comment line, to avoid errors with the Makefile
+    # "include basename.Plo" scheme.
+    echo "#dummy" > "$depfile"
+  fi
+  rm -f "$tmpdepfile"
+  ;;
+
+icc)
+  # Intel's C compiler understands `-MD -MF file'.  However on
+  #    icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
+  # ICC 7.0 will fill foo.d with something like
+  #    foo.o: sub/foo.c
+  #    foo.o: sub/foo.h
+  # which is wrong.  We want:
+  #    sub/foo.o: sub/foo.c
+  #    sub/foo.o: sub/foo.h
+  #    sub/foo.c:
+  #    sub/foo.h:
+  # ICC 7.1 will output
+  #    foo.o: sub/foo.c sub/foo.h
+  # and will wrap long lines using \ :
+  #    foo.o: sub/foo.c ... \
+  #     sub/foo.h ... \
+  #     ...
+
+  "$@" -MD -MF "$tmpdepfile"
+  stat=$?
+  if test $stat -eq 0; then :
+  else
+    rm -f "$tmpdepfile"
+    exit $stat
+  fi
+  rm -f "$depfile"
+  # Each line is of the form `foo.o: dependent.h',
+  # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
+  # Do two passes, one to just change these to
+  # `$object: dependent.h' and one to simply `dependent.h:'.
+  sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
+  # Some versions of the HPUX 10.20 sed can't process this invocation
+  # correctly.  Breaking it into two sed invocations is a workaround.
+  sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
+    sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+tru64)
+   # The Tru64 compiler uses -MD to generate dependencies as a side
+   # effect.  `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
+   # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
+   # dependencies in `foo.d' instead, so we check for that too.
+   # Subdirectories are respected.
+   dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
+   test "x$dir" = "x$object" && dir=
+   base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
+
+   if test "$libtool" = yes; then
+      # With Tru64 cc, shared objects can also be used to make a
+      # static library.  This mecanism is used in libtool 1.4 series to
+      # handle both shared and static libraries in a single compilation.
+      # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
+      #
+      # With libtool 1.5 this exception was removed, and libtool now
+      # generates 2 separate objects for the 2 libraries.  These two
+      # compilations output dependencies in in $dir.libs/$base.o.d and
+      # in $dir$base.o.d.  We have to check for both files, because
+      # one of the two compilations can be disabled.  We should prefer
+      # $dir$base.o.d over $dir.libs/$base.o.d because the latter is
+      # automatically cleaned when .libs/ is deleted, while ignoring
+      # the former would cause a distcleancheck panic.
+      tmpdepfile1=$dir.libs/$base.lo.d   # libtool 1.4
+      tmpdepfile2=$dir$base.o.d          # libtool 1.5
+      tmpdepfile3=$dir.libs/$base.o.d    # libtool 1.5
+      tmpdepfile4=$dir.libs/$base.d      # Compaq CCC V6.2-504
+      "$@" -Wc,-MD
+   else
+      tmpdepfile1=$dir$base.o.d
+      tmpdepfile2=$dir$base.d
+      tmpdepfile3=$dir$base.d
+      tmpdepfile4=$dir$base.d
+      "$@" -MD
+   fi
+
+   stat=$?
+   if test $stat -eq 0; then :
+   else
+      rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+      exit $stat
+   fi
+
+   for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
+   do
+     test -f "$tmpdepfile" && break
+   done
+   if test -f "$tmpdepfile"; then
+      sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
+      # That's a tab and a space in the [].
+      sed -e 's,^.*\.[a-z]*:[	 ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
+   else
+      echo "#dummy" > "$depfile"
+   fi
+   rm -f "$tmpdepfile"
+   ;;
+
+#nosideeffect)
+  # This comment above is used by automake to tell side-effect
+  # dependency tracking mechanisms from slower ones.
+
+dashmstdout)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  test -z "$dashmflag" && dashmflag=-M
+  # Require at least two characters before searching for `:'
+  # in the target name.  This is to cope with DOS-style filenames:
+  # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
+  "$@" $dashmflag |
+    sed 's:^[  ]*[^: ][^:][^:]*\:[    ]*:'"$object"'\: :' > "$tmpdepfile"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  tr ' ' '
+' < "$tmpdepfile" | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+dashXmstdout)
+  # This case only exists to satisfy depend.m4.  It is never actually
+  # run, as this mode is specially recognized in the preamble.
+  exit 1
+  ;;
+
+makedepend)
+  "$@" || exit $?
+  # Remove any Libtool call
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+  # X makedepend
+  shift
+  cleared=no
+  for arg in "$@"; do
+    case $cleared in
+    no)
+      set ""; shift
+      cleared=yes ;;
+    esac
+    case "$arg" in
+    -D*|-I*)
+      set fnord "$@" "$arg"; shift ;;
+    # Strip any option that makedepend may not understand.  Remove
+    # the object too, otherwise makedepend will parse it as a source file.
+    -*|$object)
+      ;;
+    *)
+      set fnord "$@" "$arg"; shift ;;
+    esac
+  done
+  obj_suffix="`echo $object | sed 's/^.*\././'`"
+  touch "$tmpdepfile"
+  ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
+  rm -f "$depfile"
+  cat < "$tmpdepfile" > "$depfile"
+  sed '1,2d' "$tmpdepfile" | tr ' ' '
+' | \
+## Some versions of the HPUX 10.20 sed can't process this invocation
+## correctly.  Breaking it into two sed invocations is a workaround.
+    sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile" "$tmpdepfile".bak
+  ;;
+
+cpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout.
+  "$@" || exit $?
+
+  # Remove the call to Libtool.
+  if test "$libtool" = yes; then
+    while test $1 != '--mode=compile'; do
+      shift
+    done
+    shift
+  fi
+
+  # Remove `-o $object'.
+  IFS=" "
+  for arg
+  do
+    case $arg in
+    -o)
+      shift
+      ;;
+    $object)
+      shift
+      ;;
+    *)
+      set fnord "$@" "$arg"
+      shift # fnord
+      shift # $arg
+      ;;
+    esac
+  done
+
+  "$@" -E |
+    sed -n '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
+    sed '$ s: \\$::' > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  cat < "$tmpdepfile" >> "$depfile"
+  sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+msvisualcpp)
+  # Important note: in order to support this mode, a compiler *must*
+  # always write the preprocessed file to stdout, regardless of -o,
+  # because we must use -o when running libtool.
+  "$@" || exit $?
+  IFS=" "
+  for arg
+  do
+    case "$arg" in
+    "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
+	set fnord "$@"
+	shift
+	shift
+	;;
+    *)
+	set fnord "$@" "$arg"
+	shift
+	shift
+	;;
+    esac
+  done
+  "$@" -E |
+  sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
+  rm -f "$depfile"
+  echo "$object : \\" > "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::	\1 \\:p' >> "$depfile"
+  echo "	" >> "$depfile"
+  . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
+  rm -f "$tmpdepfile"
+  ;;
+
+none)
+  exec "$@"
+  ;;
+
+*)
+  echo "Unknown depmode $depmode" 1>&2
+  exit 1
+  ;;
+esac
+
+exit 0
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
Index: branches/network/doc/CREDITS
===================================================================
--- branches/network/doc/CREDITS	(revision 6636)
+++ branches/network/doc/CREDITS	(revision 6636)
@@ -0,0 +1,20 @@
+The orxonox Team Thanks the following brethren.
+-----------------------------------------------
+
+Programmers:
+------------
+Patrick Boenzli
+Benjamin Grauer
+
+Infrastructure:
+---------------
+amir@datacore.ch        for giving us access to subversion and mailing lists
+
+The Great Orx Sound:
+--------------------
+Luke Grey               for making the orxonox sound
+Thierry Zaugg           many songs
+
+
+
+And many many more....
Index: branches/network/doc/documentation.am
===================================================================
--- branches/network/doc/documentation.am	(revision 6636)
+++ branches/network/doc/documentation.am	(revision 6636)
@@ -0,0 +1,62 @@
+DX_CONFIG_FILE = "$(top_srcdir)/orxodox"
+DX_CONF_DIR = "$(top_srcdir)/doc/doxyconf"
+
+doc:
+	if test ! -e $(DX_CONFIG_FILE); then \
+	 make doc-config; \
+	fi
+	@echo "Generating doxygen Documentation"; \
+	$(DOXYGEN) $(DX_CONFIG_FILE)
+
+doc-config:
+	@echo "Generationg doxygen configuration File." ; \
+	if test -e  "$(top_srcdir)/orxodox"; then \
+	  echo "deleting existing Configuration File" ; \
+	  rm $(top_srcdir)/orxodox ; \
+	fi ; \
+	touch $(DX_CONFIG_FILE) ; \
+	$(DX_CONF_DIR)/project						>> $(DX_CONFIG_FILE); \
+	echo "PROJECT_NAME		= \"$(PACKAGE_NAME)\"" 		>> $(DX_CONFIG_FILE); \
+	echo "PROJECT_NUMBER	   	= \"$(PACKAGE_VERSION)\"" 	>> $(DX_CONFIG_FILE); \
+	echo "OUTPUT_DIRECTORY  	= \"$(top_srcdir)/doc/\"" 	>> $(DX_CONFIG_FILE); \
+	echo " " >> $(DX_CONFIG_FILE); \
+\
+	$(DX_CONF_DIR)/build						>> $(DX_CONFIG_FILE); \
+\
+	$(DX_CONF_DIR)/progress						>> $(DX_CONFIG_FILE); \
+	if test $(DEBUG) -ge 2 ; then \
+	 echo "QUIET			= \"NO\""			>> $(DX_CONFIG_FILE); \
+	else \
+	 echo "QUIET			= \"YES\""			>> $(DX_CONFIG_FILE); \
+	fi ;\
+\
+	$(DX_CONF_DIR)/input						>> $(DX_CONFIG_FILE); \
+	echo "INPUT                  	= $(DOXYGEN_INPUT)"  		>> $(DX_CONFIG_FILE); \
+\
+	$(DX_CONF_DIR)/preprocessor					>> $(DX_CONFIG_FILE); \
+	echo "INCLUDE_PATH           	= \"$(top_srcdir)\""		>> $(DX_CONFIG_FILE); \
+	echo "PREDEFINED             	= \"HAVE_CONFIG_H= \""		>> $(DX_CONFIG_FILE); \
+	\
+	$(DX_CONF_DIR)/confopts						>> $(DX_CONFIG_FILE) 
+
+doc-delete: 
+	@echo "Deleting doxygen Documentation" 
+	rm -rf $(top_srcdir)/doc/html 
+	rm -rf $(top_srcdir)/doc/latex 
+
+distclean-local: doc-delete
+	rm -f $(top_srcdir)/orxodox
+
+clean-local:  doc-delete
+
+if DOCUMENTATION
+all-local: doc
+else
+all-local: 
+endif
+
+.PHONY: doc doc-config doc-delete
+
+# Local Variables:
+# mode: makefile
+# End:
Index: branches/network/doc/doxyconf/build
===================================================================
--- branches/network/doc/doxyconf/build	(revision 6636)
+++ branches/network/doc/doxyconf/build	(revision 6636)
@@ -0,0 +1,28 @@
+echo "
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = NO
+EXTRACT_PRIVATE        = YES
+EXTRACT_STATIC         = YES
+EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_METHODS  = NO
+HIDE_UNDOC_MEMBERS     = NO
+HIDE_UNDOC_CLASSES     = NO
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = NO
+CASE_SENSE_NAMES       = YES
+HIDE_SCOPE_NAMES       = NO
+SHOW_INCLUDE_FILES     = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = YES
+SORT_BRIEF_DOCS        = NO
+SORT_BY_SCOPE_NAME     = NO
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = YES"
Index: branches/network/doc/doxyconf/confopts
===================================================================
--- branches/network/doc/doxyconf/confopts	(revision 6636)
+++ branches/network/doc/doxyconf/confopts	(revision 6636)
@@ -0,0 +1,121 @@
+echo "
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = NO
+INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION    = YES
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX     = NO
+COLS_IN_ALPHA_INDEX    = 5
+IGNORE_PREFIX          = 
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML          = YES
+HTML_OUTPUT            = html
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            = 
+HTML_FOOTER            = 
+HTML_STYLESHEET        = 
+HTML_ALIGN_MEMBERS     = YES
+GENERATE_HTMLHELP      = NO
+CHM_FILE               = 
+HHC_LOCATION           = 
+GENERATE_CHI           = NO
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 4
+GENERATE_TREEVIEW      = NO
+TREEVIEW_WIDTH         = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = YES
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         = 
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = NO
+USE_PDFLATEX           = NO
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = NO
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_SCHEMA             = 
+XML_DTD                = 
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX = 
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+TAGFILES               = 
+GENERATE_TAGFILE       = 
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = YES
+HIDE_UNDOC_RELATIONS   = YES
+HAVE_DOT               = NO
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = YES
+UML_LOOK               = NO
+TEMPLATE_RELATIONS     = NO
+INCLUDE_GRAPH          = YES
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = NO
+GRAPHICAL_HIERARCHY    = YES
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = 
+DOTFILE_DIRS           = 
+MAX_DOT_GRAPH_WIDTH    = 1024
+MAX_DOT_GRAPH_HEIGHT   = 1024
+MAX_DOT_GRAPH_DEPTH    = 0
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+SEARCHENGINE           = NO"
Index: branches/network/doc/doxyconf/input
===================================================================
--- branches/network/doc/doxyconf/input	(revision 6636)
+++ branches/network/doc/doxyconf/input	(revision 6636)
@@ -0,0 +1,15 @@
+echo "
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+FILE_PATTERNS          = 
+RECURSIVE              = YES
+EXCLUDE                = 
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = 
+EXAMPLE_PATH           = 
+EXAMPLE_PATTERNS       = 
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             = 
+INPUT_FILTER           = 
+FILTER_SOURCE_FILES    = NO"
Index: branches/network/doc/doxyconf/preprocessor
===================================================================
--- branches/network/doc/doxyconf/preprocessor	(revision 6636)
+++ branches/network/doc/doxyconf/preprocessor	(revision 6636)
@@ -0,0 +1,11 @@
+echo "
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = NO
+EXPAND_ONLY_PREDEF     = NO
+SEARCH_INCLUDES        = YES
+INCLUDE_FILE_PATTERNS  = 
+EXPAND_AS_DEFINED      = 
+SKIP_FUNCTION_MACROS   = YES"
Index: branches/network/doc/doxyconf/progress
===================================================================
--- branches/network/doc/doxyconf/progress	(revision 6636)
+++ branches/network/doc/doxyconf/progress	(revision 6636)
@@ -0,0 +1,9 @@
+echo "
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_DOC_ERROR      = YES
+WARN_FORMAT            = \"\$file:\$line: \$text\"
+WARN_LOGFILE           = "
Index: branches/network/doc/doxyconf/project
===================================================================
--- branches/network/doc/doxyconf/project	(revision 6636)
+++ branches/network/doc/doxyconf/project	(revision 6636)
@@ -0,0 +1,26 @@
+echo "
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+CREATE_SUBDIRS         = YES
+OUTPUT_LANGUAGE        = English
+USE_WINDOWS_ENCODING   = YES
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = YES
+ABBREVIATE_BRIEF       = 
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = NO
+STRIP_FROM_PATH        = 
+STRIP_FROM_INC_PATH    = 
+SHORT_NAMES            = NO
+JAVADOC_AUTOBRIEF      = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP         = NO
+INHERIT_DOCS           = YES
+DISTRIBUTE_GROUP_DOC   = NO
+TAB_SIZE               = 8
+ALIASES                = 
+OPTIMIZE_OUTPUT_FOR_C  = NO
+OPTIMIZE_OUTPUT_JAVA   = NO
+SUBGROUPING            = YES"
Index: branches/network/doc/orxodox.src
===================================================================
--- branches/network/doc/orxodox.src	(revision 6636)
+++ branches/network/doc/orxodox.src	(revision 6636)
@@ -0,0 +1,213 @@
+# Doxyfile 1.3.7
+## SAMPLE FILE (to be executed from orxonox/trunk/)
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME           = Orxonox
+PROJECT_NUMBER         = 1
+OUTPUT_DIRECTORY       = doxygen/
+CREATE_SUBDIRS         = YES
+OUTPUT_LANGUAGE        = English
+USE_WINDOWS_ENCODING   = YES
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = YES
+ABBREVIATE_BRIEF       = 
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = NO
+STRIP_FROM_PATH        = 
+STRIP_FROM_INC_PATH    = 
+SHORT_NAMES            = NO
+JAVADOC_AUTOBRIEF      = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP         = NO
+INHERIT_DOCS           = YES
+DISTRIBUTE_GROUP_DOC   = NO
+TAB_SIZE               = 8
+ALIASES                = 
+OPTIMIZE_OUTPUT_FOR_C  = NO
+OPTIMIZE_OUTPUT_JAVA   = NO
+SUBGROUPING            = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = NO
+EXTRACT_PRIVATE        = YES
+EXTRACT_STATIC         = YES
+EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_METHODS  = NO
+HIDE_UNDOC_MEMBERS     = NO
+HIDE_UNDOC_CLASSES     = NO
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = NO
+CASE_SENSE_NAMES       = YES
+HIDE_SCOPE_NAMES       = NO
+SHOW_INCLUDE_FILES     = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = YES
+SORT_BRIEF_DOCS        = NO
+SORT_BY_SCOPE_NAME     = NO
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = YES
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET                  = NO
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_DOC_ERROR      = YES
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           = 
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT                  = .
+FILE_PATTERNS          = 
+RECURSIVE              = NO
+EXCLUDE                = 
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = 
+EXAMPLE_PATH           = 
+EXAMPLE_PATTERNS       = 
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             = 
+INPUT_FILTER           = 
+FILTER_SOURCE_FILES    = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = NO
+INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION    = YES
+VERBATIM_HEADERS       = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX     = NO
+COLS_IN_ALPHA_INDEX    = 5
+IGNORE_PREFIX          = 
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML          = YES
+HTML_OUTPUT            = html
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            = 
+HTML_FOOTER            = 
+HTML_STYLESHEET        = 
+HTML_ALIGN_MEMBERS     = YES
+GENERATE_HTMLHELP      = NO
+CHM_FILE               = 
+HHC_LOCATION           = 
+GENERATE_CHI           = NO
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 4
+GENERATE_TREEVIEW      = NO
+TREEVIEW_WIDTH         = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = YES
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         = 
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = NO
+USE_PDFLATEX           = NO
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = NO
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_SCHEMA             = 
+XML_DTD                = 
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX = 
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = NO
+EXPAND_ONLY_PREDEF     = NO
+SEARCH_INCLUDES        = YES
+INCLUDE_PATH           = 
+INCLUDE_FILE_PATTERNS  = 
+PREDEFINED             = 
+EXPAND_AS_DEFINED      = 
+SKIP_FUNCTION_MACROS   = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+TAGFILES               = 
+GENERATE_TAGFILE       = 
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = YES
+HIDE_UNDOC_RELATIONS   = YES
+HAVE_DOT               = NO
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = YES
+UML_LOOK               = NO
+TEMPLATE_RELATIONS     = NO
+INCLUDE_GRAPH          = YES
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = NO
+GRAPHICAL_HIERARCHY    = YES
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = 
+DOTFILE_DIRS           = 
+MAX_DOT_GRAPH_WIDTH    = 1024
+MAX_DOT_GRAPH_HEIGHT   = 1024
+MAX_DOT_GRAPH_DEPTH    = 0
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+SEARCHENGINE           = NO
Index: branches/network/doc/orxodox.this
===================================================================
--- branches/network/doc/orxodox.this	(revision 6636)
+++ branches/network/doc/orxodox.this	(revision 6636)
@@ -0,0 +1,213 @@
+# Doxyfile 1.3.7
+## SAMPLE FILE (to be executed from orxonox/trunk/)
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+PROJECT_NAME           = Orxonox
+PROJECT_NUMBER         = 1
+OUTPUT_DIRECTORY       = doxygen
+CREATE_SUBDIRS         = YES
+OUTPUT_LANGUAGE        = English
+USE_WINDOWS_ENCODING   = YES
+BRIEF_MEMBER_DESC      = YES
+REPEAT_BRIEF           = YES
+ABBREVIATE_BRIEF       = 
+ALWAYS_DETAILED_SEC    = NO
+INLINE_INHERITED_MEMB  = NO
+FULL_PATH_NAMES        = NO
+STRIP_FROM_PATH        = 
+STRIP_FROM_INC_PATH    = 
+SHORT_NAMES            = NO
+JAVADOC_AUTOBRIEF      = NO
+MULTILINE_CPP_IS_BRIEF = NO
+DETAILS_AT_TOP         = NO
+INHERIT_DOCS           = YES
+DISTRIBUTE_GROUP_DOC   = NO
+TAB_SIZE               = 8
+ALIASES                = 
+OPTIMIZE_OUTPUT_FOR_C  = NO
+OPTIMIZE_OUTPUT_JAVA   = NO
+SUBGROUPING            = YES
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+EXTRACT_ALL            = NO
+EXTRACT_PRIVATE        = YES
+EXTRACT_STATIC         = YES
+EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_METHODS  = NO
+HIDE_UNDOC_MEMBERS     = NO
+HIDE_UNDOC_CLASSES     = NO
+HIDE_FRIEND_COMPOUNDS  = NO
+HIDE_IN_BODY_DOCS      = NO
+INTERNAL_DOCS          = NO
+CASE_SENSE_NAMES       = YES
+HIDE_SCOPE_NAMES       = NO
+SHOW_INCLUDE_FILES     = YES
+INLINE_INFO            = YES
+SORT_MEMBER_DOCS       = YES
+SORT_BRIEF_DOCS        = NO
+SORT_BY_SCOPE_NAME     = NO
+GENERATE_TODOLIST      = YES
+GENERATE_TESTLIST      = YES
+GENERATE_BUGLIST       = YES
+GENERATE_DEPRECATEDLIST= YES
+ENABLED_SECTIONS       = 
+MAX_INITIALIZER_LINES  = 30
+SHOW_USED_FILES        = YES
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+QUIET                  = NO
+WARNINGS               = YES
+WARN_IF_UNDOCUMENTED   = YES
+WARN_IF_DOC_ERROR      = YES
+WARN_FORMAT            = "$file:$line: $text"
+WARN_LOGFILE           = 
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+INPUT                  = .
+FILE_PATTERNS          = 
+RECURSIVE              = YES
+EXCLUDE                = 
+EXCLUDE_SYMLINKS       = NO
+EXCLUDE_PATTERNS       = 
+EXAMPLE_PATH           = 
+EXAMPLE_PATTERNS       = 
+EXAMPLE_RECURSIVE      = NO
+IMAGE_PATH             = 
+INPUT_FILTER           = 
+FILTER_SOURCE_FILES    = NO
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+SOURCE_BROWSER         = NO
+INLINE_SOURCES         = NO
+STRIP_CODE_COMMENTS    = YES
+REFERENCED_BY_RELATION = YES
+REFERENCES_RELATION    = YES
+VERBATIM_HEADERS       = YES
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+ALPHABETICAL_INDEX     = NO
+COLS_IN_ALPHA_INDEX    = 5
+IGNORE_PREFIX          = 
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+GENERATE_HTML          = YES
+HTML_OUTPUT            = html
+HTML_FILE_EXTENSION    = .html
+HTML_HEADER            = 
+HTML_FOOTER            = 
+HTML_STYLESHEET        = 
+HTML_ALIGN_MEMBERS     = YES
+GENERATE_HTMLHELP      = NO
+CHM_FILE               = 
+HHC_LOCATION           = 
+GENERATE_CHI           = NO
+BINARY_TOC             = NO
+TOC_EXPAND             = NO
+DISABLE_INDEX          = NO
+ENUM_VALUES_PER_LINE   = 4
+GENERATE_TREEVIEW      = NO
+TREEVIEW_WIDTH         = 250
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+GENERATE_LATEX         = YES
+LATEX_OUTPUT           = latex
+LATEX_CMD_NAME         = latex
+MAKEINDEX_CMD_NAME     = makeindex
+COMPACT_LATEX          = NO
+PAPER_TYPE             = a4wide
+EXTRA_PACKAGES         = 
+LATEX_HEADER           = 
+PDF_HYPERLINKS         = NO
+USE_PDFLATEX           = NO
+LATEX_BATCHMODE        = NO
+LATEX_HIDE_INDICES     = NO
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+GENERATE_RTF           = NO
+RTF_OUTPUT             = rtf
+COMPACT_RTF            = NO
+RTF_HYPERLINKS         = NO
+RTF_STYLESHEET_FILE    = 
+RTF_EXTENSIONS_FILE    = 
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+GENERATE_MAN           = NO
+MAN_OUTPUT             = man
+MAN_EXTENSION          = .3
+MAN_LINKS              = NO
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+GENERATE_XML           = NO
+XML_OUTPUT             = xml
+XML_SCHEMA             = 
+XML_DTD                = 
+XML_PROGRAMLISTING     = YES
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+GENERATE_AUTOGEN_DEF   = NO
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+GENERATE_PERLMOD       = NO
+PERLMOD_LATEX          = NO
+PERLMOD_PRETTY         = YES
+PERLMOD_MAKEVAR_PREFIX = 
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+ENABLE_PREPROCESSING   = YES
+MACRO_EXPANSION        = NO
+EXPAND_ONLY_PREDEF     = NO
+SEARCH_INCLUDES        = YES
+INCLUDE_PATH           = 
+INCLUDE_FILE_PATTERNS  = 
+PREDEFINED             = 
+EXPAND_AS_DEFINED      = 
+SKIP_FUNCTION_MACROS   = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+TAGFILES               = 
+GENERATE_TAGFILE       = 
+ALLEXTERNALS           = NO
+EXTERNAL_GROUPS        = YES
+PERL_PATH              = /usr/bin/perl
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+CLASS_DIAGRAMS         = YES
+HIDE_UNDOC_RELATIONS   = YES
+HAVE_DOT               = NO
+CLASS_GRAPH            = YES
+COLLABORATION_GRAPH    = YES
+UML_LOOK               = NO
+TEMPLATE_RELATIONS     = NO
+INCLUDE_GRAPH          = YES
+INCLUDED_BY_GRAPH      = YES
+CALL_GRAPH             = NO
+GRAPHICAL_HIERARCHY    = YES
+DOT_IMAGE_FORMAT       = png
+DOT_PATH               = 
+DOTFILE_DIRS           = 
+MAX_DOT_GRAPH_WIDTH    = 1024
+MAX_DOT_GRAPH_HEIGHT   = 1024
+MAX_DOT_GRAPH_DEPTH    = 0
+GENERATE_LEGEND        = YES
+DOT_CLEANUP            = YES
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+SEARCHENGINE           = NO
Index: branches/network/doc/orxonox.1
===================================================================
--- branches/network/doc/orxonox.1	(revision 6636)
+++ branches/network/doc/orxonox.1	(revision 6636)
@@ -0,0 +1,63 @@
+.\"                              hey, Emacs:   -*- nroff -*-
+.\" orxonox is free software; you can redistribute it and/or modify
+.\" it under the terms of the GNU General Public License as published by
+.\" the Free Software Foundation; either version 2 of the License, or
+.\" (at your option) any later version.
+.\"
+.\" This program is distributed in the hope that it will be useful,
+.\" but WITHOUT ANY WARRANTY; without even the implied warranty of
+.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+.\" GNU General Public License for more details.
+.\"
+.\" You should have received a copy of the GNU General Public License
+.\" along with this program; see the file COPYING.  If not, write to
+.\" the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+.\"
+.TH ORXONOX 1 "March 2, 2004"
+.\" Please update the above date whenever this man page is modified.
+.\"
+.\" Some roff macros, for reference:
+.\" .nh        disable hyphenation
+.\" .hy        enable hyphenation
+.\" .ad l      left justify
+.\" .ad b      justify to both left and right margins (default)
+.\" .nf        disable filling
+.\" .fi        enable filling
+.\" .br        insert line break
+.\" .sp <n>    insert n+1 empty lines
+.\" for manpage-specific macros, see man(7)
+.SH NAME
+orxonox \-  High-End Vertical Scroller
+.SH SYNOPSIS
+.B orxonox
+.RI [ options ]
+.SH DESCRIPTION
+\fBorxonox\fP is an open-source vertical scroller game programmed in C++,OpenGL and SDL. It's designed to run on all important platforms like Linux, MacOS X, Windows.
+.PP
+It washes your windows, mends your fences, mows your lawn...
+.SH OPTIONS
+\fBorxonox\fP accepts the following options:
+.TP
+.B \-h, \-\-help
+Show summary of options.
+.TP
+.B \-v=<i>, \-\-verbose=\<i\>
+Prints out: 0: nothing, 1: error, 2: warnings, 3: information, 4+: debug
+.TP
+.B \-g, \-\-gui 
+displays the gui prior to starting orxonox. (this is also the case, if the configuration-files do not exist in your home).
+.TP
+.B \-q, \-\-windowed
+starts orxonox in windowed mode. (not fullscreen)
+.TP
+.B \-\-no\-sound 
+Disables audio completely
+.TP
+.B \-w, \-\-wireframe 
+Renders everything in Wireframe mode.
+.TP
+.\" .SH "SEE ALSO"
+.\" .BR foo (1), 
+.\" .BR bar (1).
+.SH AUTHOR
+orx-crew <orxonox@orxonox.ethz.ch>.
Index: branches/network/install-sh
===================================================================
--- branches/network/install-sh	(revision 6636)
+++ branches/network/install-sh	(revision 6636)
@@ -0,0 +1,323 @@
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2005-02-02.21
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
+#
+# Copyright (C) 1994 X Consortium
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS 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
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
+#
+#
+# FSF changes to this file are in the public domain.
+#
+# Calling this script install-sh is preferred over install.sh, to prevent
+# `make' implicit rules from creating a file called install from it
+# when there is no Makefile.
+#
+# This script is compatible with the BSD install script, but was written
+# from scratch.  It can only install one file at a time, a restriction
+# shared with many OS's install programs.
+
+# set DOITPROG to echo to test this script
+
+# Don't use :- since 4.3BSD and earlier shells don't like it.
+doit="${DOITPROG-}"
+
+# put in absolute paths if you don't have them in your path; or use env. vars.
+
+mvprog="${MVPROG-mv}"
+cpprog="${CPPROG-cp}"
+chmodprog="${CHMODPROG-chmod}"
+chownprog="${CHOWNPROG-chown}"
+chgrpprog="${CHGRPPROG-chgrp}"
+stripprog="${STRIPPROG-strip}"
+rmprog="${RMPROG-rm}"
+mkdirprog="${MKDIRPROG-mkdir}"
+
+chmodcmd="$chmodprog 0755"
+chowncmd=
+chgrpcmd=
+stripcmd=
+rmcmd="$rmprog -f"
+mvcmd="$mvprog"
+src=
+dst=
+dir_arg=
+dstarg=
+no_target_directory=
+
+usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+-c         (ignored)
+-d         create directories instead of installing files.
+-g GROUP   $chgrpprog installed files to GROUP.
+-m MODE    $chmodprog installed files to MODE.
+-o USER    $chownprog installed files to USER.
+-s         $stripprog installed files.
+-t DIRECTORY  install into DIRECTORY.
+-T         report an error if DSTFILE is a directory.
+--help     display this help and exit.
+--version  display version info and exit.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
+"
+
+while test -n "$1"; do
+  case $1 in
+    -c) shift
+        continue;;
+
+    -d) dir_arg=true
+        shift
+        continue;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+        shift
+        shift
+        continue;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) chmodcmd="$chmodprog $2"
+        shift
+        shift
+        continue;;
+
+    -o) chowncmd="$chownprog $2"
+        shift
+        shift
+        continue;;
+
+    -s) stripcmd=$stripprog
+        shift
+        continue;;
+
+    -t) dstarg=$2
+	shift
+	shift
+	continue;;
+
+    -T) no_target_directory=true
+	shift
+	continue;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    *)  # When -d is used, all remaining arguments are directories to create.
+	# When -t is used, the destination is already specified.
+	test -n "$dir_arg$dstarg" && break
+        # Otherwise, the last argument is the destination.  Remove it from $@.
+	for arg
+	do
+          if test -n "$dstarg"; then
+	    # $@ is not empty: it contains at least $arg.
+	    set fnord "$@" "$dstarg"
+	    shift # fnord
+	  fi
+	  shift # arg
+	  dstarg=$arg
+	done
+	break;;
+  esac
+done
+
+if test -z "$1"; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call `install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+for src
+do
+  # Protect names starting with `-'.
+  case $src in
+    -*) src=./$src ;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    src=
+
+    if test -d "$dst"; then
+      mkdircmd=:
+      chmodcmd=
+    else
+      mkdircmd=$mkdirprog
+    fi
+  else
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dstarg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+
+    dst=$dstarg
+    # Protect names starting with `-'.
+    case $dst in
+      -*) dst=./$dst ;;
+    esac
+
+    # If destination is a directory, append the input filename; won't work
+    # if double slashes aren't ignored.
+    if test -d "$dst"; then
+      if test -n "$no_target_directory"; then
+	echo "$0: $dstarg: Is a directory" >&2
+	exit 1
+      fi
+      dst=$dst/`basename "$src"`
+    fi
+  fi
+
+  # This sed command emulates the dirname command.
+  dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
+
+  # Make sure that the destination directory exists.
+
+  # Skip lots of stat calls in the usual case.
+  if test ! -d "$dstdir"; then
+    defaultIFS='
+	 '
+    IFS="${IFS-$defaultIFS}"
+
+    oIFS=$IFS
+    # Some sh's can't handle IFS=/ for some reason.
+    IFS='%'
+    set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
+    shift
+    IFS=$oIFS
+
+    pathcomp=
+
+    while test $# -ne 0 ; do
+      pathcomp=$pathcomp$1
+      shift
+      if test ! -d "$pathcomp"; then
+        $mkdirprog "$pathcomp"
+	# mkdir can fail with a `File exist' error in case several
+	# install-sh are creating the directory concurrently.  This
+	# is OK.
+	test -d "$pathcomp" || exit
+      fi
+      pathcomp=$pathcomp/
+    done
+  fi
+
+  if test -n "$dir_arg"; then
+    $doit $mkdircmd "$dst" \
+      && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
+      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
+      && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
+      && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
+
+  else
+    dstfile=`basename "$dst"`
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=$dstdir/_inst.$$_
+    rmtmp=$dstdir/_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+    trap '(exit $?); exit' 1 2 13 15
+
+    # Copy the file name to the temp name.
+    $doit $cpprog "$src" "$dsttmp" &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
+      && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
+      && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
+      && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
+
+    # Now rename the file to the real destination.
+    { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
+      || {
+	   # The rename failed, perhaps because mv can't rename something else
+	   # to itself, or perhaps because mv is so ancient that it does not
+	   # support -f.
+
+	   # Now remove or move aside any old file at destination location.
+	   # We try this two ways since rm can't unlink itself on some
+	   # systems and the destination file might be busy for other
+	   # reasons.  In this case, the final cleanup might fail but the new
+	   # file should still install successfully.
+	   {
+	     if test -f "$dstdir/$dstfile"; then
+	       $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
+	       || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
+	       || {
+		 echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
+		 (exit 1); exit 1
+	       }
+	     else
+	       :
+	     fi
+	   } &&
+
+	   # Now rename the file to the real destination.
+	   $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
+	 }
+    }
+  fi || { (exit 1); exit 1; }
+done
+
+# The final little trick to "correctly" pass the exit status to the exit trap.
+{
+  (exit 0); exit 0
+}
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
Index: branches/network/missing
===================================================================
--- branches/network/missing	(revision 6636)
+++ branches/network/missing	(revision 6636)
@@ -0,0 +1,357 @@
+#! /bin/sh
+# Common stub for a few missing GNU programs while installing.
+
+scriptversion=2005-02-08.22
+
+# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005
+#   Free Software Foundation, Inc.
+# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+if test $# -eq 0; then
+  echo 1>&2 "Try \`$0 --help' for more information"
+  exit 1
+fi
+
+run=:
+
+# In the cases where this matters, `missing' is being run in the
+# srcdir already.
+if test -f configure.ac; then
+  configure_ac=configure.ac
+else
+  configure_ac=configure.in
+fi
+
+msg="missing on your system"
+
+case "$1" in
+--run)
+  # Try to run requested program, and just exit if it succeeds.
+  run=
+  shift
+  "$@" && exit 0
+  # Exit code 63 means version mismatch.  This often happens
+  # when the user try to use an ancient version of a tool on
+  # a file that requires a minimum version.  In this case we
+  # we should proceed has if the program had been absent, or
+  # if --run hadn't been passed.
+  if test $? = 63; then
+    run=:
+    msg="probably too old"
+  fi
+  ;;
+
+  -h|--h|--he|--hel|--help)
+    echo "\
+$0 [OPTION]... PROGRAM [ARGUMENT]...
+
+Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
+error status if there is no known handling for PROGRAM.
+
+Options:
+  -h, --help      display this help and exit
+  -v, --version   output version information and exit
+  --run           try to run the given command, and emulate it if it fails
+
+Supported PROGRAM values:
+  aclocal      touch file \`aclocal.m4'
+  autoconf     touch file \`configure'
+  autoheader   touch file \`config.h.in'
+  automake     touch all \`Makefile.in' files
+  bison        create \`y.tab.[ch]', if possible, from existing .[ch]
+  flex         create \`lex.yy.c', if possible, from existing .c
+  help2man     touch the output file
+  lex          create \`lex.yy.c', if possible, from existing .c
+  makeinfo     touch the output file
+  tar          try tar, gnutar, gtar, then tar without non-portable flags
+  yacc         create \`y.tab.[ch]', if possible, from existing .[ch]
+
+Send bug reports to <bug-automake@gnu.org>."
+    exit $?
+    ;;
+
+  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
+    echo "missing $scriptversion (GNU Automake)"
+    exit $?
+    ;;
+
+  -*)
+    echo 1>&2 "$0: Unknown \`$1' option"
+    echo 1>&2 "Try \`$0 --help' for more information"
+    exit 1
+    ;;
+
+esac
+
+# Now exit if we have it, but it failed.  Also exit now if we
+# don't have it and --version was passed (most likely to detect
+# the program).
+case "$1" in
+  lex|yacc)
+    # Not GNU programs, they don't have --version.
+    ;;
+
+  tar)
+    if test -n "$run"; then
+       echo 1>&2 "ERROR: \`tar' requires --run"
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       exit 1
+    fi
+    ;;
+
+  *)
+    if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
+       # We have it, but it failed.
+       exit 1
+    elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
+       # Could not run --version or --help.  This is probably someone
+       # running `$TOOL --version' or `$TOOL --help' to check whether
+       # $TOOL exists and not knowing $TOOL uses missing.
+       exit 1
+    fi
+    ;;
+esac
+
+# If it does not exist, or fails to run (possibly an outdated version),
+# try to emulate it.
+case "$1" in
+  aclocal*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acinclude.m4' or \`${configure_ac}'.  You might want
+         to install the \`Automake' and \`Perl' packages.  Grab them from
+         any GNU archive site."
+    touch aclocal.m4
+    ;;
+
+  autoconf)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`${configure_ac}'.  You might want to install the
+         \`Autoconf' and \`GNU m4' packages.  Grab them from any GNU
+         archive site."
+    touch configure
+    ;;
+
+  autoheader)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`acconfig.h' or \`${configure_ac}'.  You might want
+         to install the \`Autoconf' and \`GNU m4' packages.  Grab them
+         from any GNU archive site."
+    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
+    test -z "$files" && files="config.h"
+    touch_files=
+    for f in $files; do
+      case "$f" in
+      *:*) touch_files="$touch_files "`echo "$f" |
+				       sed -e 's/^[^:]*://' -e 's/:.*//'`;;
+      *) touch_files="$touch_files $f.in";;
+      esac
+    done
+    touch $touch_files
+    ;;
+
+  automake*)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
+         You might want to install the \`Automake' and \`Perl' packages.
+         Grab them from any GNU archive site."
+    find . -type f -name Makefile.am -print |
+	   sed 's/\.am$/.in/' |
+	   while read f; do touch "$f"; done
+    ;;
+
+  autom4te)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, but is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.
+         You can get \`$1' as part of \`Autoconf' from any GNU
+         archive site."
+
+    file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
+    test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
+    if test -f "$file"; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo "#! /bin/sh"
+	echo "# Created by GNU Automake missing as a replacement of"
+	echo "#  $ $@"
+	echo "exit 0"
+	chmod +x $file
+	exit 1
+    fi
+    ;;
+
+  bison|yacc)
+    echo 1>&2 "\
+WARNING: \`$1' $msg.  You should only need it if
+         you modified a \`.y' file.  You may need the \`Bison' package
+         in order for those modifications to take effect.  You can get
+         \`Bison' from any GNU archive site."
+    rm -f y.tab.c y.tab.h
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+	case "$LASTARG" in
+	*.y)
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
+	    if [ -f "$SRCFILE" ]; then
+	         cp "$SRCFILE" y.tab.c
+	    fi
+	    SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
+	    if [ -f "$SRCFILE" ]; then
+	         cp "$SRCFILE" y.tab.h
+	    fi
+	  ;;
+	esac
+    fi
+    if [ ! -f y.tab.h ]; then
+	echo >y.tab.h
+    fi
+    if [ ! -f y.tab.c ]; then
+	echo 'main() { return 0; }' >y.tab.c
+    fi
+    ;;
+
+  lex|flex)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.l' file.  You may need the \`Flex' package
+         in order for those modifications to take effect.  You can get
+         \`Flex' from any GNU archive site."
+    rm -f lex.yy.c
+    if [ $# -ne 1 ]; then
+        eval LASTARG="\${$#}"
+	case "$LASTARG" in
+	*.l)
+	    SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
+	    if [ -f "$SRCFILE" ]; then
+	         cp "$SRCFILE" lex.yy.c
+	    fi
+	  ;;
+	esac
+    fi
+    if [ ! -f lex.yy.c ]; then
+	echo 'main() { return 0; }' >lex.yy.c
+    fi
+    ;;
+
+  help2man)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+	 you modified a dependency of a manual page.  You may need the
+	 \`Help2man' package in order for those modifications to take
+	 effect.  You can get \`Help2man' from any GNU archive site."
+
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+	file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
+    fi
+    if [ -f "$file" ]; then
+	touch $file
+    else
+	test -z "$file" || exec >$file
+	echo ".ab help2man is required to generate this page"
+	exit 1
+    fi
+    ;;
+
+  makeinfo)
+    echo 1>&2 "\
+WARNING: \`$1' is $msg.  You should only need it if
+         you modified a \`.texi' or \`.texinfo' file, or any other file
+         indirectly affecting the aspect of the manual.  The spurious
+         call might also be the consequence of using a buggy \`make' (AIX,
+         DU, IRIX).  You might want to install the \`Texinfo' package or
+         the \`GNU make' package.  Grab either from any GNU archive site."
+    # The file to touch is that specified with -o ...
+    file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
+    if test -z "$file"; then
+      # ... or it is the one specified with @setfilename ...
+      infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
+      file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile`
+      # ... or it is derived from the source name (dir/f.texi becomes f.info)
+      test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
+    fi
+    touch $file
+    ;;
+
+  tar)
+    shift
+
+    # We have already tried tar in the generic part.
+    # Look for gnutar/gtar before invocation to avoid ugly error
+    # messages.
+    if (gnutar --version > /dev/null 2>&1); then
+       gnutar "$@" && exit 0
+    fi
+    if (gtar --version > /dev/null 2>&1); then
+       gtar "$@" && exit 0
+    fi
+    firstarg="$1"
+    if shift; then
+	case "$firstarg" in
+	*o*)
+	    firstarg=`echo "$firstarg" | sed s/o//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+	case "$firstarg" in
+	*h*)
+	    firstarg=`echo "$firstarg" | sed s/h//`
+	    tar "$firstarg" "$@" && exit 0
+	    ;;
+	esac
+    fi
+
+    echo 1>&2 "\
+WARNING: I can't seem to be able to run \`tar' with the given arguments.
+         You may want to install GNU tar or Free paxutils, or check the
+         command line arguments."
+    exit 1
+    ;;
+
+  *)
+    echo 1>&2 "\
+WARNING: \`$1' is needed, and is $msg.
+         You might have modified some files without having the
+         proper tools for further handling them.  Check the \`README' file,
+         it often tells you about the needed prerequisites for installing
+         this package.  You may also peek at any GNU archive site, in case
+         some other package would contain this missing \`$1' program."
+    exit 1
+    ;;
+esac
+
+exit 0
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
Index: branches/network/mkinstalldirs
===================================================================
--- branches/network/mkinstalldirs	(revision 6636)
+++ branches/network/mkinstalldirs	(revision 6636)
@@ -0,0 +1,150 @@
+#! /bin/sh
+# mkinstalldirs --- make directory hierarchy
+
+scriptversion=2005-02-02.21
+
+# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
+# Created: 1993-05-16
+# Public domain.
+#
+# This file is maintained in Automake, please report
+# bugs to <bug-automake@gnu.org> or send patches to
+# <automake-patches@gnu.org>.
+
+errstatus=0
+dirmode=""
+
+usage="\
+Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
+
+Create each directory DIR (with mode MODE, if specified), including all
+leading file name components.
+
+Report bugs to <bug-automake@gnu.org>."
+
+# process command line arguments
+while test $# -gt 0 ; do
+  case $1 in
+    -h | --help | --h*)         # -h for help
+      echo "$usage"
+      exit $?
+      ;;
+    -m)                         # -m PERM arg
+      shift
+      test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
+      dirmode=$1
+      shift
+      ;;
+    --version)
+      echo "$0 $scriptversion"
+      exit $?
+      ;;
+    --)                         # stop option processing
+      shift
+      break
+      ;;
+    -*)                         # unknown option
+      echo "$usage" 1>&2
+      exit 1
+      ;;
+    *)                          # first non-opt arg
+      break
+      ;;
+  esac
+done
+
+for file
+do
+  if test -d "$file"; then
+    shift
+  else
+    break
+  fi
+done
+
+case $# in
+  0) exit 0 ;;
+esac
+
+# Solaris 8's mkdir -p isn't thread-safe.  If you mkdir -p a/b and
+# mkdir -p a/c at the same time, both will detect that a is missing,
+# one will create a, then the other will try to create a and die with
+# a "File exists" error.  This is a problem when calling mkinstalldirs
+# from a parallel make.  We use --version in the probe to restrict
+# ourselves to GNU mkdir, which is thread-safe.
+case $dirmode in
+  '')
+    if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
+      echo "mkdir -p -- $*"
+      exec mkdir -p -- "$@"
+    else
+      # On NextStep and OpenStep, the `mkdir' command does not
+      # recognize any option.  It will interpret all options as
+      # directories to create, and then abort because `.' already
+      # exists.
+      test -d ./-p && rmdir ./-p
+      test -d ./--version && rmdir ./--version
+    fi
+    ;;
+  *)
+    if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
+       test ! -d ./--version; then
+      echo "mkdir -m $dirmode -p -- $*"
+      exec mkdir -m "$dirmode" -p -- "$@"
+    else
+      # Clean up after NextStep and OpenStep mkdir.
+      for d in ./-m ./-p ./--version "./$dirmode";
+      do
+        test -d $d && rmdir $d
+      done
+    fi
+    ;;
+esac
+
+for file
+do
+  set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
+  shift
+
+  pathcomp=
+  for d
+  do
+    pathcomp="$pathcomp$d"
+    case $pathcomp in
+      -*) pathcomp=./$pathcomp ;;
+    esac
+
+    if test ! -d "$pathcomp"; then
+      echo "mkdir $pathcomp"
+
+      mkdir "$pathcomp" || lasterr=$?
+
+      if test ! -d "$pathcomp"; then
+	errstatus=$lasterr
+      else
+	if test ! -z "$dirmode"; then
+	  echo "chmod $dirmode $pathcomp"
+	  lasterr=""
+	  chmod "$dirmode" "$pathcomp" || lasterr=$?
+
+	  if test ! -z "$lasterr"; then
+	    errstatus=$lasterr
+	  fi
+	fi
+      fi
+    fi
+
+    pathcomp="$pathcomp/"
+  done
+done
+
+exit $errstatus
+
+# Local Variables:
+# mode: shell-script
+# sh-indentation: 2
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-end: "$"
+# End:
Index: branches/network/scripts/data.genlist.pl
===================================================================
--- branches/network/scripts/data.genlist.pl	(revision 6636)
+++ branches/network/scripts/data.genlist.pl	(revision 6636)
@@ -0,0 +1,68 @@
+#!/usr/bin/perl
+##########################################################################
+#   orxonox - the future of 3D-vertical-scrollers                        #
+#                                                                        #
+#   Copyright (C) 2004 orx                                               #
+#                                                                        #
+#   This program is free software; you can redistribute it and/or modify #
+#   it under the terms of the GNU General Public License as published by #
+#   the Free Software Foundation; either version 2, or (at your option)  #
+#   any later version.                                                   #
+#                                                                        #
+#   ### File Specific:                                                   #
+#   main-programmer: Benjamin Grauer                                     #
+#   co-programmer: ...                                                   #
+#                                                                        #
+#   This is a simple perl script, that generates a List of all files     #
+#   contained in a Folder checked out with SVN and writes into an output #
+#   file.                                                                #
+##########################################################################
+
+if (@ARGV[0] eq "-h" || $ARGV[0] eq "--help" || @ARGV != 2)
+  {
+    die ("usage: data.genlist.pl <data-directory> <output-file>\n");
+  }
+
+
+if (! -d @ARGV[0])
+  {
+    die ("@ARGV[0] is not regular Directory.\n");
+  }
+
+open(FD, "> @ARGV[1]") or die("Couldn't open @ARGV[1]\n") ;
+
+
+&createFileList(@ARGV[0]);
+
+close(FD);
+
+
+sub createFileList
+  {
+   my ($folderName) = @_;
+   my ($fullName);
+   my ($inputFile);
+   my ($printFile);
+   my (@folderList);
+
+   open(FOLDERLIST, "ls $folderName -1 |");
+   @folderList = <FOLDERLIST>;
+
+   foreach $inputFile (@folderList)
+     {
+       if ($inputFile eq "." || $inputFile eq "..")
+         {
+
+         }
+       chomp($inputFile);
+       $fullName = "$folderName/$inputFile";
+
+       $printFile = $fullName;
+       $printFile =~ s/@ARGV[0]//;
+       print FD "$printFile\n";
+       if (-d $fullName )
+         {
+           &createFileList($fullName);
+         }
+     }
+ }
Index: branches/network/scripts/gentoo/install_notes
===================================================================
--- branches/network/scripts/gentoo/install_notes	(revision 6636)
+++ branches/network/scripts/gentoo/install_notes	(revision 6636)
@@ -0,0 +1,30 @@
+INSTALLATION NOTES
+==================
+To install this script as long as it is not in portage,
+you can follow this guide.
+
+Dependencies:
+-------------
+gentoo linux :)
+http://www.gentoo.org
+
+
+1. INSTALLATION INTO PORTAGE:
+-----------------------------
+a) get root (su - )
+b) mkdir /usr/portage/games-action/orxonox
+c) cp orxonox-[*].ebuild /usr/portage/games-action/orxonox
+d) cd /usr/portage/games-action/orxonox
+e) ebuild orxonox-[*].ebuild digest
+
+[*]: the version of the ebuild to install (ex. 0.3.0-r4969)
+
+
+2. EMERGING:
+------------
+a) emerge orxonox -pv     
+	##(this is to see, if the dependencies are alright)
+b) emerge orxonox
+
+
+#EOF
Index: branches/network/scripts/gentoo/orxonox-0.3.0_alpha-r4969.ebuild
===================================================================
--- branches/network/scripts/gentoo/orxonox-0.3.0_alpha-r4969.ebuild	(revision 6636)
+++ branches/network/scripts/gentoo/orxonox-0.3.0_alpha-r4969.ebuild	(revision 6636)
@@ -0,0 +1,64 @@
+# Copyright 1999-2005 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: $
+
+inherit eutils games
+
+DATA_VERSION=73
+
+DESCRIPTION="orxonox is an open-source vertical scroller game programmed in C++, OpenGL, OpenAL and SDL"
+HOMEPAGE="http://www.orxonox.net"
+SRC_URI="http://www.orxonox.net/files/snapshots/${P}-${PR}.tar.bz2
+         http://www.orxonox.net/files/snapshots/${PN}-data-r${DATA_VERSION}.tar.bz2"
+LICENSE="GPL-2"
+SLOT="0"
+KEYWORDS="x86"
+IUSE="gtk+-2"
+
+DEPEND="virtual/opengl
+        virtual/x11
+        media-libs/openal
+        media-libs/libsdl
+        media-libs/sdl-image
+        media-libs/sdl-ttf"
+
+# Run-time dependencies, same as DEPEND if RDEPEND isn't defined:
+#RDEPEND=""
+S=${WORKDIR}/${P}
+
+src_unpack() {
+        unpack ${P}-${PR}.tar.bz2
+        cd "${S}"
+        unpack ${PN}-data-r${DATA_VERSION}.tar.bz2
+}
+
+src_compile() {
+        egamesconf || die
+
+        emake || die "emake failed"
+}
+
+src_install() {
+        make DESTDIR=${D} install || die
+
+        dodir ${GAMES_DATADIR}/${PN}
+        cp -r data/* ${D}/${GAMES_DATADIR}/${PN}/ \
+                || die "data copy failed"
+
+        dodoc AUTHORS ChangeLog README
+
+        prepgamesdirs
+
+        #make \
+        #       prefix=${D}/usr \
+        #       mandir=${D}/usr/share/man \
+        #       infodir=${D}/usr/share/info \
+        #       libdir=${D}/usr/$(get_libdir) \
+        #       install || die
+
+        #einstall || die
+}
+
+pkg_postinst() {
+        games_pkg_postinst
+}
Index: branches/network/scripts/gentoo/orxonox-0.3.1_alpha-r5273.ebuild
===================================================================
--- branches/network/scripts/gentoo/orxonox-0.3.1_alpha-r5273.ebuild	(revision 6636)
+++ branches/network/scripts/gentoo/orxonox-0.3.1_alpha-r5273.ebuild	(revision 6636)
@@ -0,0 +1,65 @@
+# Copyright 1999-2005 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: $
+
+inherit eutils games
+
+DATA_VERSION=83
+
+DESCRIPTION="orxonox is an open-source 3D-action game programmed in C++, OpenGL, OpenAL and SDL"
+HOMEPAGE="http://www.orxonox.net"
+SRC_URI="http://www.orxonox.net/files/snapshots/${P}-${PR}.tar.bz2
+         http://www.orxonox.net/files/snapshots/${PN}-data-r${DATA_VERSION}.tar.bz2"
+LICENSE="GPL-2"
+SLOT="0"
+KEYWORDS="x86"
+IUSE="gtk+-2"
+
+DEPEND="virtual/opengl
+        virtual/x11
+        media-libs/openal
+        media-libs/libsdl
+        media-libs/sdl-image
+        media-libs/sdl-ttf
+        media-libs/glew"
+
+# Run-time dependencies, same as DEPEND if RDEPEND isn't defined:
+#RDEPEND=""
+S=${WORKDIR}/${P}
+
+src_unpack() {
+        unpack ${P}-${PR}.tar.bz2
+        cd "${S}"
+        unpack ${PN}-data-r${DATA_VERSION}.tar.bz2
+}
+
+src_compile() {
+        egamesconf || die
+
+        emake || die "emake failed"
+}
+
+src_install() {
+        make DESTDIR=${D} install || die
+
+        dodir ${GAMES_DATADIR}/${PN}
+        cp -r data/* ${D}/${GAMES_DATADIR}/${PN}/ \
+                || die "data copy failed"
+
+        dodoc AUTHORS ChangeLog README
+
+        prepgamesdirs
+
+        #make \
+        #       prefix=${D}/usr \
+        #       mandir=${D}/usr/share/man \
+        #       infodir=${D}/usr/share/info \
+        #       libdir=${D}/usr/$(get_libdir) \
+        #       install || die
+
+        #einstall || die
+}
+
+pkg_postinst() {
+        games_pkg_postinst
+}
Index: branches/network/scripts/gentoo/orxonox-0.3.2_alpha-r5702.ebuild
===================================================================
--- branches/network/scripts/gentoo/orxonox-0.3.2_alpha-r5702.ebuild	(revision 6636)
+++ branches/network/scripts/gentoo/orxonox-0.3.2_alpha-r5702.ebuild	(revision 6636)
@@ -0,0 +1,66 @@
+# Copyright 1999-2005 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: $
+
+inherit eutils games
+
+DATA_VERSION=106
+
+DESCRIPTION="orxonox is an open-source 3D-action game programmed in C++, OpenGL, OpenAL and SDL"
+HOMEPAGE="http://www.orxonox.net"
+SRC_URI="http://www.orxonox.net/files/snapshots/${P}-${PR}.tar.bz2
+         http://www.orxonox.net/files/snapshots/${PN}-data-r${DATA_VERSION}.tar.bz2"
+LICENSE="GPL-2"
+SLOT="0"
+KEYWORDS="x86"
+IUSE="gtk+-2"
+
+DEPEND="virtual/opengl
+        virtual/x11
+        media-libs/openal
+        media-libs/libsdl
+        media-libs/sdl-image
+        media-libs/sdl-ttf
+        media-libs/glew"
+
+# Run-time dependencies, same as DEPEND if RDEPEND isn't defined:
+#RDEPEND=""
+S=${WORKDIR}/${P}
+
+src_unpack() {
+        unpack ${P}-${PR}.tar.bz2
+        cd "${S}"
+        unpack ${PN}-data-r${DATA_VERSION}.tar.bz2
+}
+
+src_compile() {
+	./autogen.sh
+        egamesconf || die
+
+        emake || die "emake failed"
+}
+
+src_install() {
+        make DESTDIR=${D} install || die
+
+        dodir ${GAMES_DATADIR}/${PN}
+        cp -r data/* ${D}/${GAMES_DATADIR}/${PN}/ \
+                || die "data copy failed"
+
+        dodoc AUTHORS ChangeLog README
+
+        prepgamesdirs
+
+        #make \
+        #       prefix=${D}/usr \
+        #       mandir=${D}/usr/share/man \
+        #       infodir=${D}/usr/share/info \
+        #       libdir=${D}/usr/$(get_libdir) \
+        #       install || die
+
+        #einstall || die
+}
+
+pkg_postinst() {
+        games_pkg_postinst
+}
Index: branches/network/scripts/gentoo/orxonox-0.3.2_alpha-rXXXX.ebuild
===================================================================
--- branches/network/scripts/gentoo/orxonox-0.3.2_alpha-rXXXX.ebuild	(revision 6636)
+++ branches/network/scripts/gentoo/orxonox-0.3.2_alpha-rXXXX.ebuild	(revision 6636)
@@ -0,0 +1,66 @@
+# Copyright 1999-2005 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: $
+
+inherit eutils games
+
+DATA_VERSION=83
+
+DESCRIPTION="orxonox is an open-source 3D-action game programmed in C++, OpenGL, OpenAL and SDL"
+HOMEPAGE="http://www.orxonox.net"
+SRC_URI="http://www.orxonox.net/files/snapshots/${P}-${PR}.tar.bz2
+         http://www.orxonox.net/files/snapshots/${PN}-data-r${DATA_VERSION}.tar.bz2"
+LICENSE="GPL-2"
+SLOT="0"
+KEYWORDS="x86"
+IUSE="gtk+-2"
+
+DEPEND="virtual/opengl
+        virtual/x11
+        media-libs/openal
+        media-libs/libsdl
+        media-libs/sdl-image
+        media-libs/sdl-ttf
+        media-libs/sdl-net
+        media-libs/glew"
+
+# Run-time dependencies, same as DEPEND if RDEPEND isn't defined:
+#RDEPEND=""
+S=${WORKDIR}/${P}
+
+src_unpack() {
+        unpack ${P}-${PR}.tar.bz2
+        cd "${S}"
+        unpack ${PN}-data-r${DATA_VERSION}.tar.bz2
+}
+
+src_compile() {
+        egamesconf || die
+
+        emake || die "emake failed"
+}
+
+src_install() {
+        make DESTDIR=${D} install || die
+
+        dodir ${GAMES_DATADIR}/${PN}
+        cp -r data/* ${D}/${GAMES_DATADIR}/${PN}/ \
+                || die "data copy failed"
+
+        dodoc AUTHORS ChangeLog README
+
+        prepgamesdirs
+
+        #make \
+        #       prefix=${D}/usr \
+        #       mandir=${D}/usr/share/man \
+        #       infodir=${D}/usr/share/info \
+        #       libdir=${D}/usr/$(get_libdir) \
+        #       install || die
+
+        #einstall || die
+}
+
+pkg_postinst() {
+        games_pkg_postinst
+}
Index: branches/network/scripts/gtk-config.osXframework
===================================================================
--- branches/network/scripts/gtk-config.osXframework	(revision 6636)
+++ branches/network/scripts/gtk-config.osXframework	(revision 6636)
@@ -0,0 +1,112 @@
+#!/bin/sh
+
+glib_libs="-framework GLib"
+glib_cflags="-I/Library/Frameworks/GLib.framework/Headers"
+glib_thread_libs="-framework GLib -lpthread"
+glib_thread_cflags="-I/Library/Frameworks/GLib.framework/Headers"
+
+prefix=/Library/Frameworks
+gtk_fw_prefix=/Library/Frameworks
+exec_prefix=${prefix}
+exec_prefix_set=no
+
+usage()
+{
+        cat <<EOF
+Usage: gtk-config [OPTIONS] [LIBRARIES]
+Options:
+        [--prefix[=DIR]]
+        [--exec-prefix[=DIR]]
+        [--version]
+        [--libs]
+        [--cflags]
+Libraries:
+        gtk
+        gthread
+EOF
+        exit $1
+}
+
+if test $# -eq 0; then
+        usage 1 1>&2
+fi
+
+lib_gtk=yes
+
+while test $# -gt 0; do
+  case "$1" in
+  -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+  *) optarg= ;;
+  esac
+
+  case $1 in
+    --prefix=*)
+      prefix=$optarg
+      if test $exec_prefix_set = no ; then
+        exec_prefix=$optarg
+      fi
+      ;;
+    --prefix)
+      echo_prefix=yes
+      ;;
+    --exec-prefix=*)
+      exec_prefix=$optarg
+      exec_prefix_set=yes
+      ;;
+    --exec-prefix)
+      echo_exec_prefix=yes
+      ;;
+    --version)
+      echo 1.2.10
+      ;;
+    --cflags)
+      echo_cflags=yes
+      ;;
+    --libs)
+      echo_libs=yes
+      ;;
+    gtk)
+      lib_gtk=yes
+      ;;
+    gthread)
+      lib_gthread=yes
+      ;;
+    *)
+      usage 1 1>&2
+      ;;
+  esac
+  shift
+done
+
+if test "$echo_prefix" = "yes"; then
+        echo $prefix
+fi
+
+if test "$echo_exec_prefix" = "yes"; then
+        echo $exec_prefix
+fi
+
+if test "$lib_gthread" = "yes"; then
+      glib_cflags="$glib_thread_cflags"
+      glib_libs="$glib_thread_libs"
+fi
+
+if test "$echo_cflags" = "yes"; then
+      echo -F${gtk_fw_prefix} ${glib_cflags} -I${gtk_fw_prefix}/GDK.framework/Headers -I${gtk_fw_prefix}/GTK.framework/Headers
+fi
+
+if test "$echo_libs" = "yes"; then
+      my_glib_libs=
+      libdirs=-F${exec_prefix}
+      for i in $glib_libs ; do
+        if test $i != -F${exec_prefix} ; then
+          if test -z "$my_glib_libs" ; then
+            my_glib_libs="$i"
+          else
+            my_glib_libs="$my_glib_libs $i"
+          fi
+        fi
+      done
+
+      echo $libdirs -F${gtk_fw_prefix} -framework GLib -framework GDK -framework GTK ${glib_cflags} -lm
+fi
Index: branches/network/scripts/orxodox_checkFiles.pl
===================================================================
--- branches/network/scripts/orxodox_checkFiles.pl	(revision 6636)
+++ branches/network/scripts/orxodox_checkFiles.pl	(revision 6636)
@@ -0,0 +1,294 @@
+#!/usr/bin/perl
+##########################################################################
+#   orxonox - the future of 3D-vertical-scrollers                        #
+#                                                                        #
+#   Copyright (C) 2004 orx                                               #
+#                                                                        #
+#   This program is free software; you can redistribute it and/or modify #
+#   it under the terms of the GNU General Public License as published by #
+#   the Free Software Foundation; either version 2, or (at your option)  #
+#   any later version.                                                   #
+#                                                                        #
+#   ### File Specific:                                                   #
+#   main-programmer: Benjamin Grauer                                     #
+#   co-programmer: ...                                                   #
+#                                                                        #
+#   This Script is for parsing single or multiple files for their        #
+#   doxygeb-tags, and outputs the warnings and errors, but prehibits     #
+#   the progress from being displayed.                                   #
+#   Usage: ./orxodox.checkFiles.pl [fileName1 [fileName2 [...]]]         #
+#   This script ignores file-extensions, and assumes that either         #
+#   .h, .cc or both may exist, and searches for them.                    #
+##########################################################################
+
+$inputFiles = @ARGV[0];
+$tempDoxFile = "TMPorxodox";
+
+unless (open (DOXfile, ">$tempDoxFile"))
+ {
+   die("cannot open file\n");
+ }
+
+$processFiles = "";
+$numberOfFiles = 0;
+foreach $inputFile (@ARGV)
+  {
+    $tmpNumber = $numberOfFiles;
+
+    $inputFile =~ s/\.cc$//;
+    $inputFile =~ s/\.h$//;
+
+    print "checking file $inputFile: ";
+
+    $inputFile =~ s/$/\.h/;
+    if (-e $inputFile)
+      {
+        $processFiles = "$processFiles $inputFile";
+        $numberOfFiles++;
+        print "found .h ";
+      }
+    $inputFile =~ s/\.h$/\.cc/;
+    if (-e $inputFile)
+      {
+        $processFiles = "$processFiles $inputFile";
+        $numberOfFiles++;
+        print "...found .cc ";
+      }
+    if ($tmpNumber == $numberOfFiles) {print "no matching files found";}
+    print "\n";
+  }
+
+if ($numberOfFiles == 0 && @ARGV !=0){
+  die("no Files have been found\n");}
+
+print "==================================================================\n";
+print "Generating temporary Documentation File\n";
+print "==================================================================\n";
+
+print DOXfile "# THIS IS A DEFAULT FILE FOR DOXYGEN DOCUMENTATION";
+
+printf DOXfile "# Doxyfile 1.3.7 \
+## SAMPLE FILE (to be executed from orxonox/trunk/) \
+ \
+#--------------------------------------------------------------------------- \
+# Project related configuration options \
+#--------------------------------------------------------------------------- \
+PROJECT_NAME           = orxonox \
+PROJECT_NUMBER         = 1 \
+OUTPUT_DIRECTORY       = doxygen/ \
+CREATE_SUBDIRS         = YES \
+OUTPUT_LANGUAGE        = English \
+USE_WINDOWS_ENCODING   = YES \
+BRIEF_MEMBER_DESC      = YES \
+REPEAT_BRIEF           = YES \
+ABBREVIATE_BRIEF       =  \
+ALWAYS_DETAILED_SEC    = NO \
+INLINE_INHERITED_MEMB  = NO \
+FULL_PATH_NAMES        = NO \
+STRIP_FROM_PATH        =  \
+STRIP_FROM_INC_PATH    =  \
+SHORT_NAMES            = NO \
+JAVADOC_AUTOBRIEF      = NO \
+MULTILINE_CPP_IS_BRIEF = NO \
+DETAILS_AT_TOP         = NO \
+INHERIT_DOCS           = YES \
+DISTRIBUTE_GROUP_DOC   = NO \
+TAB_SIZE               = 8 \
+ALIASES                =  \
+OPTIMIZE_OUTPUT_FOR_C  = NO \
+OPTIMIZE_OUTPUT_JAVA   = NO \
+SUBGROUPING            = YES \
+#--------------------------------------------------------------------------- \
+# Build related configuration options \
+#--------------------------------------------------------------------------- \
+EXTRACT_ALL            = NO \
+EXTRACT_PRIVATE        = YES \
+EXTRACT_STATIC         = YES \
+EXTRACT_LOCAL_CLASSES  = YES \
+EXTRACT_LOCAL_METHODS  = NO \
+HIDE_UNDOC_MEMBERS     = NO \
+HIDE_UNDOC_CLASSES     = NO \
+HIDE_FRIEND_COMPOUNDS  = NO \
+HIDE_IN_BODY_DOCS      = NO \
+INTERNAL_DOCS          = NO \
+CASE_SENSE_NAMES       = YES \
+HIDE_SCOPE_NAMES       = NO \
+SHOW_INCLUDE_FILES     = YES \
+INLINE_INFO            = YES \
+SORT_MEMBER_DOCS       = YES \
+SORT_BRIEF_DOCS        = NO \
+SORT_BY_SCOPE_NAME     = NO \
+GENERATE_TODOLIST      = YES \
+GENERATE_TESTLIST      = YES \
+GENERATE_BUGLIST       = YES \
+GENERATE_DEPRECATEDLIST= YES \
+ENABLED_SECTIONS       =  \
+MAX_INITIALIZER_LINES  = 30 \
+SHOW_USED_FILES        = YES \
+#--------------------------------------------------------------------------- \
+# configuration options related to warning and progress messages \
+#--------------------------------------------------------------------------- \
+QUIET                  = YES \
+WARNINGS               = YES \
+WARN_IF_UNDOCUMENTED   = YES \
+WARN_IF_DOC_ERROR      = YES \
+WARN_FORMAT            = \"\$file:\$line: \$text\" \
+WARN_LOGFILE           =  \
+#--------------------------------------------------------------------------- \
+# configuration options related to the input files \
+#--------------------------------------------------------------------------- \
+INPUT                  = $processFiles \
+FILE_PATTERNS          =  \
+RECURSIVE              = NO \
+EXCLUDE                =  \
+EXCLUDE_SYMLINKS       = NO \
+EXCLUDE_PATTERNS       =  \
+EXAMPLE_PATH           =  \
+EXAMPLE_PATTERNS       =  \
+EXAMPLE_RECURSIVE      = NO \
+IMAGE_PATH             =  \
+INPUT_FILTER           =  \
+FILTER_SOURCE_FILES    = NO \
+#--------------------------------------------------------------------------- \
+# configuration options related to source browsing \
+#--------------------------------------------------------------------------- \
+SOURCE_BROWSER         = NO \
+INLINE_SOURCES         = NO \
+STRIP_CODE_COMMENTS    = YES \
+REFERENCED_BY_RELATION = YES \
+REFERENCES_RELATION    = YES \
+VERBATIM_HEADERS       = YES \
+#--------------------------------------------------------------------------- \
+# configuration options related to the alphabetical class index \
+#--------------------------------------------------------------------------- \
+ALPHABETICAL_INDEX     = NO \
+COLS_IN_ALPHA_INDEX    = 5 \
+IGNORE_PREFIX          =  \
+#--------------------------------------------------------------------------- \
+# configuration options related to the HTML output \
+#--------------------------------------------------------------------------- \
+GENERATE_HTML          = YES \
+HTML_OUTPUT            = html \
+HTML_FILE_EXTENSION    = .html \
+HTML_HEADER            =  \
+HTML_FOOTER            =  \
+HTML_STYLESHEET        =  \
+HTML_ALIGN_MEMBERS     = YES \
+GENERATE_HTMLHELP      = NO \
+CHM_FILE               =  \
+HHC_LOCATION           =  \
+GENERATE_CHI           = NO \
+BINARY_TOC             = NO \
+TOC_EXPAND             = NO \
+DISABLE_INDEX          = NO \
+ENUM_VALUES_PER_LINE   = 4 \
+GENERATE_TREEVIEW      = NO \
+TREEVIEW_WIDTH         = 250 \
+#--------------------------------------------------------------------------- \
+# configuration options related to the LaTeX output \
+#--------------------------------------------------------------------------- \
+GENERATE_LATEX         = NO \
+LATEX_OUTPUT           = latex \
+LATEX_CMD_NAME         = latex \
+MAKEINDEX_CMD_NAME     = makeindex \
+COMPACT_LATEX          = NO \
+PAPER_TYPE             = a4wide \
+EXTRA_PACKAGES         =  \
+LATEX_HEADER           =  \
+PDF_HYPERLINKS         = NO \
+USE_PDFLATEX           = NO \
+LATEX_BATCHMODE        = NO \
+LATEX_HIDE_INDICES     = NO \
+#--------------------------------------------------------------------------- \
+# configuration options related to the RTF output \
+#--------------------------------------------------------------------------- \
+GENERATE_RTF           = NO \
+RTF_OUTPUT             = rtf \
+COMPACT_RTF            = NO \
+RTF_HYPERLINKS         = NO \
+RTF_STYLESHEET_FILE    =  \
+RTF_EXTENSIONS_FILE    =  \
+#--------------------------------------------------------------------------- \
+# configuration options related to the man page output \
+#--------------------------------------------------------------------------- \
+GENERATE_MAN           = NO \
+MAN_OUTPUT             = man \
+MAN_EXTENSION          = .3 \
+MAN_LINKS              = NO \
+#--------------------------------------------------------------------------- \
+# configuration options related to the XML output \
+#--------------------------------------------------------------------------- \
+GENERATE_XML           = NO \
+XML_OUTPUT             = xml \
+XML_SCHEMA             =  \
+XML_DTD                =  \
+XML_PROGRAMLISTING     = YES \
+#--------------------------------------------------------------------------- \
+# configuration options for the AutoGen Definitions output \
+#--------------------------------------------------------------------------- \
+GENERATE_AUTOGEN_DEF   = NO \
+#--------------------------------------------------------------------------- \
+# configuration options related to the Perl module output \
+#--------------------------------------------------------------------------- \
+GENERATE_PERLMOD       = NO \
+PERLMOD_LATEX          = NO \
+PERLMOD_PRETTY         = YES \
+PERLMOD_MAKEVAR_PREFIX =  \
+#--------------------------------------------------------------------------- \
+# Configuration options related to the preprocessor    \
+#--------------------------------------------------------------------------- \
+ENABLE_PREPROCESSING   = YES \
+MACRO_EXPANSION        = NO \
+EXPAND_ONLY_PREDEF     = NO \
+SEARCH_INCLUDES        = YES \
+INCLUDE_PATH           =  \
+INCLUDE_FILE_PATTERNS  =  \
+PREDEFINED             =  \
+EXPAND_AS_DEFINED      =  \
+SKIP_FUNCTION_MACROS   = YES \
+#--------------------------------------------------------------------------- \
+# Configuration::additions related to external references    \
+#--------------------------------------------------------------------------- \
+TAGFILES               =  \
+GENERATE_TAGFILE       =  \
+ALLEXTERNALS           = NO \
+EXTERNAL_GROUPS        = YES \
+PERL_PATH              = /usr/bin/perl \
+#--------------------------------------------------------------------------- \
+# Configuration options related to the dot tool    \
+#--------------------------------------------------------------------------- \
+CLASS_DIAGRAMS         = YES \
+HIDE_UNDOC_RELATIONS   = YES \
+HAVE_DOT               = NO \
+CLASS_GRAPH            = YES \
+COLLABORATION_GRAPH    = YES \
+UML_LOOK               = NO \
+TEMPLATE_RELATIONS     = NO \
+INCLUDE_GRAPH          = YES \
+INCLUDED_BY_GRAPH      = YES \
+CALL_GRAPH             = NO \
+GRAPHICAL_HIERARCHY    = YES \
+DOT_IMAGE_FORMAT       = png \
+DOT_PATH               =  \
+DOTFILE_DIRS           =  \
+MAX_DOT_GRAPH_WIDTH    = 1024 \
+MAX_DOT_GRAPH_HEIGHT   = 1024 \
+MAX_DOT_GRAPH_DEPTH    = 0 \
+GENERATE_LEGEND        = YES \
+DOT_CLEANUP            = YES \
+#--------------------------------------------------------------------------- \
+# Configuration::additions related to the search engine    \
+#--------------------------------------------------------------------------- \
+SEARCHENGINE           = NO \
+ \
+";
+
+close DOXfile;
+
+print "==================================================================\n";
+print "Generating Documentation of $processFiles\n";
+print "==================================================================\n";
+exec("doxygen $tempDoxFile");
+
+
+unlink $tmpDoxFile;
Index: branches/network/scripts/orxonoxServer.sh
===================================================================
--- branches/network/scripts/orxonoxServer.sh	(revision 6636)
+++ branches/network/scripts/orxonoxServer.sh	(revision 6636)
@@ -0,0 +1,45 @@
+#!/bin/bash
+##########################################################################
+#   orxonox - the future of 3D-vertical-scrollers                        #
+#                                                                        #
+#   Copyright (C) 2004 orx                                               #
+#                                                                        #
+#   This program is free software; you can redistribute it and/or modify #
+#   it under the terms of the GNU General Public License as published by #
+#   the Free Software Foundation; either version 2, or (at your option)  #
+#   any later version.                                                   #
+#                                                                        #
+#   ### File Specific:                                                   #
+#   main-programmer: Christoph Renner                                    #
+#   co-programmer: ...                                                   #
+#                                                                        #
+#                                                                        #
+#   This script starts an orxonox server and restarts it when it crashes.#
+#   it also creates a logfile for each start                             #
+#                                                                        #
+##########################################################################
+
+
+PORT="9999"
+
+ORXONOXBINARY="./orxonox"
+LOGDIR="/tmp/orxonox_log"
+LOGPREFIX="orxonox"
+SLEEPTIME="5"
+
+ORXONOXOPTIONS=" --dedicated-server $PORT"
+
+while true; do
+	SD=$(date +'%Y-%m-%d-%H:%M:%S');
+	CMDLINE="$ORXONOXBINARY $ORXONOXOPTIONS"
+	LOGFILE="$LOGDIR/$LOGPREFIX-$SD.log"
+	echo $CMDLINE;
+	nice $CMDLINE &> "$LOGFILE";
+
+	echo "Now is $(date +'%Y-%m-%d-%H:%M:%S')" >> "$LOGFILE";
+
+	echo -e "\n\n\nyou have $SLEEPTIME s to kill this script\n\n\n";
+	sleep $SLEEPTIME
+done
+
+
Index: branches/network/scripts/tardis.txt
===================================================================
--- branches/network/scripts/tardis.txt	(revision 6636)
+++ branches/network/scripts/tardis.txt	(revision 6636)
@@ -0,0 +1,12 @@
+## TARDIS ENVIRONMENT VARIABLES ##
+
+ set ARCH=i686-debian-linux3.1
+
+ set PREFIX=/usr/pack/gamelibs-1.0-to
+
+ setenv CPPFLAGS -I$PREFIX/include
+
+ setenv LDFLAGS "-L$PREFIX/$ARCH/lib -Wl,-rpath -Wl,$PREFIX/$ARCH/lib"
+
+ set path= ( $PREFIX/$ARCH/bin $path )
+
Index: branches/network/scripts/valgrind/nv.sup
===================================================================
--- branches/network/scripts/valgrind/nv.sup	(revision 6636)
+++ branches/network/scripts/valgrind/nv.sup	(revision 6636)
@@ -0,0 +1,81 @@
+{
+   Nvidia01
+   Memcheck:Param
+   ioctl(generic)
+   fun:ioctl
+   obj:/usr/lib/nvidia-7676/lib/libGL.so.1.0.7676
+}
+
+{
+   NVidia02
+   Memcheck:Cond
+   obj:/usr/lib/nvidia-7676/lib/libGLcore.so.1.0.7676
+}
+{
+   NVidia03
+   Memcheck:Addr4
+   obj:/usr/lib/nvidia-7676/lib/libGL.so.1.0.7676
+}
+{
+   NV04
+   Memcheck:Cond
+   fun:_nv000027gl
+   obj:/usr/lib/nvidia-7676/lib/libGLcore.so.1.0.7676
+}
+{
+   NV05
+   Memcheck:Param
+   ioctl(generic)
+   fun:ioctl
+   obj:/usr/lib/nvidia-7676/lib/libGLcore.so.1.0.7676
+   obj:*
+}
+{
+   NV06
+   Memcheck:Cond
+   fun:_nv000028gl
+   obj:/usr/lib/nvidia-7676/lib/libGLcore.so.1.0.7676
+   obj:*
+}
+
+{
+   NV07
+   Memcheck:Param
+   ioctl(generic)
+   fun:ioctl
+   obj:/usr/lib/nvidia-7676/lib/libGLcore.so.1.0.7676
+   obj:*
+}
+{
+   NV08
+   Memcheck:Cond
+   fun:_nv000028gl
+   obj:/usr/lib/nvidia-7676/lib/libGLcore.so.1.0.7676
+   obj:*
+}
+{
+   NV09
+   Memcheck:Cond
+   fun:strcat
+   obj:/usr/lib/nvidia-7676/lib/libGLcore.so.1.0.7676
+}
+
+{
+   GFX-Engine
+   Memcheck:Param
+   writev(vector[...])
+   obj:/lib/tls/libc-2.3.2.so
+   fun:writev
+   obj:/usr/X11R6/lib/libX11.so.6.2
+   fun:_X11TransWritev
+   fun:_XSend
+   fun:XStoreColors
+   fun:X11_SetGammaRamp
+   fun:X11_CreateWindow
+   fun:X11_SetVideoMode
+   fun:SDL_SetVideoMode
+   fun:_ZN14GraphicsEngine13setResolutionEiii
+   fun:_ZN14GraphicsEngine9initVideoEjjj
+}
+
+
Index: branches/network/src/INSTALL
===================================================================
--- branches/network/src/INSTALL	(revision 6636)
+++ branches/network/src/INSTALL	(revision 6636)
@@ -0,0 +1,41 @@
+
+INSTALLATION INSTRUCTIONS FOR ORXONOX
+=====================================
+
+INSTALLATION
+============
+
+To make it quite easy for those of you who just want to install orxonox:
+
+1. ./configure
+2. make
+3. make install
+
+DEPENDENCIES
+============
+
+There are some dependencies for orxonox you have to install:
+
+1. SDL           (http://www.libsdl.org)
+2. OPENGL        (http://www.opengl.org)
+3. SDL_mixer     (http://www.libsdl.org/projects/SDL_mixer)
+4. SDL_image     (http://www.libsdl.org/projects/SDL_image)
+5. SDL_ttf       (http://www.libsdl.org/projects/SDL_ttf)
+ a) needs libttf (http://www.freetype.org/)
+
+Nice to Have:
+6. Doxygen       (http://www.stack.nl/~dimitri/doxygen/)
+7. Automake	 (http://www.gnu.org/software/automake/)
+8. Autoconf      (http://www.gnu.org/software/autoconf/)
+
+Windows Users also need the following:
+9. mingw         (http://mingw.org/)
+
+
+BUGS
+====
+Send bug reports to orxonox-dev@mail.datacore.ch
+
+
+
+#EOF
Index: branches/network/src/Makefile.am
===================================================================
--- branches/network/src/Makefile.am	(revision 6636)
+++ branches/network/src/Makefile.am	(revision 6636)
@@ -0,0 +1,120 @@
+MAINSRCDIR=.
+include $(MAINSRCDIR)/defs/include_paths.am
+
+include world_entities/Makefile.am
+include story_entities/Makefile.am
+
+#"-O3 -pedantic -fPIC -ffast-math -I/usr/X11R6/include"
+
+bin_PROGRAMS = orxonox
+
+orxonox_CPPFLAGS = -DIS_ORXONOX
+orxonox_LDFLAGS = -u global_ModelParticles_Factory
+
+orxonox_DEPENDENCIES = \
+		lib/libORXlibs.a \
+		util/libORXutils.a \
+		lib/gui/gtk_gui/libORXgui.a \
+		lib/graphics/importer/libORXimporter.a \
+		lib/graphics/importer/libtc.a \
+		lib/graphics/libORXgraphics.a \
+		lib/sound/libORXsound.a \
+		lib/event/libORXevent.a \
+		lib/physics/libORXphysics.a \
+		lib/particles/libORXparticles.a \
+		lib/collision_detection/libORXcd.a \
+		lib/graphics/spatial_separation/libORXquadtree.a \
+		lib/parser/tinyxml/libtinyxml.a \
+		lib/parser/ini_parser/libIniParser.a \
+		lib/gui/gl_gui/libORXglgui.a \
+		lib/shell/libORXshell.a \
+		lib/network/libORXnet.a
+
+orxonox_LDADD = util/libORXutils.a \
+		\
+		lib/collision_detection/libORXcd.a \
+		\
+		lib/libORXlibs.a \
+		lib/gui/gtk_gui/libORXgui.a \
+		lib/graphics/importer/libORXimporter.a \
+		lib/graphics/importer/libtc.a \
+		lib/graphics/libORXgraphics.a \
+		lib/sound/libORXsound.a \
+		lib/event/libORXevent.a \
+		lib/physics/libORXphysics.a \
+		lib/particles/libORXparticles.a \
+		lib/graphics/spatial_separation/libORXquadtree.a \
+		lib/parser/tinyxml/libtinyxml.a \
+		lib/parser/ini_parser/libIniParser.a \
+		lib/gui/gl_gui/libORXglgui.a \
+		lib/shell/libORXshell.a \
+		lib/network/libORXnet.a \
+		$(GTK2_LIBS) $(GTHREAD_LIBS) $(CURL_LIBS)
+
+orxonox_SOURCES = \
+		$(WorldEntities_SOURCES_) \
+		$(StoryEntities_SOURCES_) \
+		orxonox.cc \
+		\
+		lib/particles/model_particles.cc \
+		lib/particles/spark_particles.cc \
+		lib/particles/sprite_particles.cc \
+		\
+		subprojects/benchmark.cc
+
+noinst_HEADERS = \
+		$(WorldEntities_HEADERS_) \
+		$(StoryEntities_HEADERS_) \
+		orxonox.h \
+		ability.h \
+		defs/message_structures.h \
+		defs/stdincl.h \
+		defs/stdlibincl.h \
+		defs/sdlincl.h \
+		defs/glincl.h \
+		defs/alincl.h \
+		defs/comincl.h \
+		defs/confincl.h \
+		defs/error.h \
+		defs/debug.h \
+		defs/globals.h \
+		defs/compiler.h \
+		defs/class_id.h \
+		subprojects/benchmark.h
+
+
+## orxonox.conf will be used from home-dir instead.
+EXTRA_DIST = proto/proto_class.h \
+             proto/proto_class.cc \
+             proto/proto_singleton.h \
+             proto/proto_singleton.cc \
+             proto/proto_world_entity.h \
+             proto/proto_world_entity.cc \
+             defs/include_paths.am \
+             world_entities/Makefile.am \
+             story_entities/Makefile.am
+
+if SUB_PROJECTS
+  SUB_PROGS = subprojects
+else
+  SUB_PROGS =
+endif
+
+SUBDIRS = lib \
+          util \
+          . \
+          $(SUB_PROGS)
+
+
+#EXTRA_DIST=orxonox.lsm.in orxonox.spec.in orxonox.texinfo
+
+#  if you write a self-test script named `chk', uncomment the
+#  following and add `chk' to the EXTRA_DIST list
+#TESTS=chk
+
+#  build and install the .info pages
+#info_TEXINFOS = orxonox.texinfo
+#orxonox_TEXINFOS = gpl.texinfo
+
+#  install the man pages
+#man_MANS=orxonox.1
Index: branches/network/src/ability.cc
===================================================================
--- branches/network/src/ability.cc	(revision 6636)
+++ branches/network/src/ability.cc	(revision 6636)
@@ -0,0 +1,32 @@
+
+
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+
+#include "ability.h"
+
+
+using namespace std;
+
+
+
+Ability::Ability () {}
+
+
+
+Ability::~Ability () {}
+
+
Index: branches/network/src/ability.h
===================================================================
--- branches/network/src/ability.h	(revision 6636)
+++ branches/network/src/ability.h	(revision 6636)
@@ -0,0 +1,16 @@
+
+#ifndef _ABILITY_H
+#define _ABILITY_H
+
+#include "data_tank.h"
+
+
+class Ability {
+
+ public:
+  Ability ();
+  virtual ~Ability ();
+
+};
+
+#endif /* _ABILITY_H */
Index: branches/network/src/ai/ai.cc
===================================================================
--- branches/network/src/ai/ai.cc	(revision 6636)
+++ branches/network/src/ai/ai.cc	(revision 6636)
@@ -0,0 +1,32 @@
+
+
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+
+#include "ai.h"
+
+
+using namespace std;
+
+
+
+AI::AI () {}
+
+
+
+AI::~AI () {}
+
+
Index: branches/network/src/ai/ai.h
===================================================================
--- branches/network/src/ai/ai.h	(revision 6636)
+++ branches/network/src/ai/ai.h	(revision 6636)
@@ -0,0 +1,14 @@
+
+#ifndef _AI_H
+#define _AI_H
+
+
+class AI {
+
+ public:
+  AI ();
+  virtual ~AI ();
+
+};
+
+#endif /* _AI_H */
Index: branches/network/src/defs/alincl.h
===================================================================
--- branches/network/src/defs/alincl.h	(revision 6636)
+++ branches/network/src/defs/alincl.h	(revision 6636)
@@ -0,0 +1,19 @@
+/*!
+ * This file includes openAL-Headers.
+ * @file alincl.h
+*/
+
+#ifndef _ALINCL_H
+#define _ALINCL_H
+
+#ifdef __APPLE__
+#include <OpenAL/al.h>
+#include <OpenAL/alc.h>
+#include <OpenAL/alut.h>
+#else
+#include <AL/al.h>
+#include <AL/alc.h>
+#include <AL/alut.h>
+#endif
+
+#endif /* _ALINCL_H */
Index: branches/network/src/defs/class_id.h
===================================================================
--- branches/network/src/defs/class_id.h	(revision 6636)
+++ branches/network/src/defs/class_id.h	(revision 6636)
@@ -0,0 +1,316 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: Benjamin Grauer
+
+   2005-06-10: (bensch) added new sturcture to support multiple inheritance
+*/
+
+/*!
+ * @file class_id.h
+ * @brief list of orxonox ClassID's
+ *
+ *  this File is used to identify an Object with its class and also with its sub/super-classes.
+ *  this is also used by the ObjectManager/Factory to identify and load important classes
+ *
+ *  !! important !!
+ *  When adding a new CLASS be sure about the following:
+ *    1. if it is a (SUB)SUPERCLASS make sure there is still space left (if not think of a new approach)
+ *    2. check if the Number you add is not refered twice, and that with (SUB)SUPERCLASSES there are no intersections
+ *    3. be sure to add you stuff in the right section, and don't interest yourself for the order of things. :)
+ */
+
+#ifndef _CLASS_ID_H
+#define _CLASS_ID_H
+
+//! list of all classes to be loadable in via the ObjectManager
+/**
+ *
+ * -------------------------------------------------------------------------------------------
+ * Consider the Identifiers 0xABCDEFGH
+ * The first two: A and B are superclass Identifiers !! THEY ARE ALREADY FULL !!
+ *
+ * The second three are for sub-superclass-groups inheritance:
+ *  C: a Group identifier: can be anything from 1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,g,h
+ *  D,E: Member within the Group, to specify further deriavtions within the Group.
+ *       These may be anything from 1,2,4,8 (at D and E)
+ *  !! consider, that you __may not__ have a derivated class from group a and group b.
+ *
+ * The last three entries F,G,H are for any leaf classes in existence.
+ * they are ordered in the following way:
+ *  F: LEAF-GroupSpecifier
+ *  G,H: UNIQUE NUMBER eithin F-Group.
+ *
+ * You only have to extend the Class with your ClassID-tag.
+ * If something goes Wrong, you get an Assertion-Warning in BaseObject.
+ * !! Abstrace/Non-total-leaf classes do not have a LEAF-part.
+ * -------------------------------------------------------------------------------------------
+ *
+ * COUNT:
+ * -> # max SuperClass-count        = 7 (not intersecting)
+ *    # max SubSuperClass-count     = 15*7 = 105 (the 7 classes will be able to get derived from each other, but not over the SubSuperClass.)
+ *    # max lowerClasses-count      = 3^16 = enough (they are Leaves, and may NOT be derived by any other class.)
+ */
+typedef enum ClassID
+{
+  // the Nothing CLASS (NULL)
+  CL_NULL                       =    0x00000000,
+
+  // superclasses
+  CL_MASK_SUPER_CLASS           =    0xff000000,
+  CL_BASE_OBJECT                =    0x00000000,
+
+  CL_PARENT_NODE                =    0x01000000,
+
+  CL_STORY_ENTITY               =    0x02000000,
+
+  CL_GAME_WORLD                 =    0x50000000,
+  CL_GAME_WORLD_DATA            =    0x60000000,
+
+  CL_PHYSICS_INTERFACE          =    0x04000000,
+
+  CL_EVENT_LISTENER             =    0x08000000,
+
+  CL_ELEMENT_2D                 =    0x10000000,
+
+  CL_SYNCHRONIZEABLE            =    0x20000000,
+
+  CL_WORLD_ENTITY               =    0x40000000,
+
+  // subsuper-classes derivations taken : 1, 2, 3, 5, a, b, c.     << THIS IS A LIST OF ALL THE DCL_MASK_SUBSUPERCLASS_ID's taken
+
+  // subsuper-classes
+  CL_MASK_SUBSUPER_CLASS        =    0x00fff000,
+  CL_MASK_SUBSUPER_CLASS_IDA    =    0x00f00000,
+  CL_MASK_SUBSUPER_CLASS_IDB    =    0x000ff000,
+  // SUPER-PNodes
+  CL_FIELD                      =    0x00101000,
+  // SUPER-WorldEntities
+  CL_PLAYABLE                   =    0x00201000,
+  CL_PLAYER                     =    0x00202000,
+  CL_NPC                        =    0x00204000,
+  CL_IMAGE_ENTITY               =    0x00206000,
+  CL_PLANET                     =    0x00207000,
+  CL_PROJECTILE                 =    0x00208000,
+  CL_WEAPON                     =    0x00210000,
+  CL_POWER_UP                   =    0x00220000,
+  CL_EXTENDABLE                 =    0x00240000,
+  // SUPER-Modeling
+  CL_TEXTURE                    =    0x00c01000,
+  CL_TEXT                       =    0x00c02000,
+
+  CL_MODEL                      =    0x00d01000,
+  CL_STATIC_MODEL               =    0x00002000,
+  CL_VERTEX_ARRAY_MODEL         =    0x00004000,
+
+
+  // subsuper-classes derivations taken : 1, 2, 5, a, b, c.     << THIS IS A LIST OF ALL THE DCL_MASK_SUBSUPERCLASS_ID's taken
+
+  // lowest level classes
+  CL_MASK_LOWLEVEL_CLASS        =    0x00000fff,
+
+  // singleton classes (range from 0x00000f00 to 0x00000fff)
+  CL_MASK_SINGLETON             =    0x00000f00,
+  CL_ORXONOX                    =    0x00000f01,
+  CL_NULL_PARENT                =    0x00000f02,
+  CL_PILOT_PARENT               =    0x00000f03,
+  CL_OBJECT_MANAGER             =    0x00000f04,
+  CL_RESOURCE_MANAGER           =    0x00000f05,
+  CL_GARBAGE_COLLECTOR          =    0x00000f06,
+  CL_GAME_LOADER                =    0x00000f07,
+  CL_GRAPHICS_ENGINE            =    0x00000f08,
+  CL_TEXT_ENGINE                =    0x00000f09,
+  CL_LIGHT_MANAGER              =    0x00000f0a,
+  CL_EVENT_HANDLER              =    0x00000f0b,
+  CL_PHYSICS_ENGINE             =    0x00000f0c,
+  CL_CD_ENGINE                  =    0x00000f0d,
+  CL_PARTICLE_ENGINE            =    0x00000f0e,
+  CL_SOUND_ENGINE               =    0x00000f0f,
+  CL_ANIMATION_PLAYER           =    0x00000f10,
+  CL_TRACK_MANAGER              =    0x00000f11,
+  CL_TRACK_NODE                 =    0x00000f12,
+  CL_STATE                      =    0x00000f13,
+  CL_FRAMEWORK                  =    0x00000f14,
+  CL_RENDER_2D                  =    0x00000f21,
+  CL_NULL_ELEMENT_2D            =    0x00000f22,
+  CL_SHELL_BUFFER               =    0x00000f32,
+  CL_GLGUI_HANDLER              =    0x00000f40,
+  CL_GLGUI_MAIN_WIDGET          =    0x00000f41,
+  CL_NETWORK_MANAGER            =    0x00000f50,
+
+
+
+  // StoryEntities (range from 0x00000100 to 0x000001ff)
+  CL_CAMPAIGN                   =    0x00000101,
+  CL_CAMPAIGN_DATA              =    0x00000102,
+  CL_SIMPLE_GAME_MENU           =    0x00000103,
+  CL_SIMPLE_GAME_MENU_DATA      =    0x00000104,
+  CL_SINGLE_PLAYER_WORLD        =    0x00000105,
+  CL_SINGLE_PLAYER_WORLD_DATA   =    0x00000106,
+  CL_MULTI_PLAYER_WORLD         =    0x00000107,
+  CL_MULTI_PLAYER_WORLD_DATA    =    0x00000108,
+  CL_MOVIE_LOADER               =    0x00000109,
+
+
+  // WorldEntities (range from 0x00000200 to 0x000004ff)
+  CL_CAMERA                     =    0x00000201,
+  CL_CAMERA_TARGET              =    0x00000202,
+
+  CL_ENVIRONEMENT               =    0x00000203,
+  CL_SATELLITE                  =    0x00000204,
+  CL_SKYBOX                     =    0x00000205,
+  CL_SKYSPHERE                  =    0x00000206,
+  CL_TERRAIN                    =    0x00000207,
+  CL_WATER                      =    0x00000208,
+
+  CL_TEST_ENTITY                =    0x00000209,
+  CL_SPACE_SHIP                 =    0x0000020a,
+  CL_HELICOPTER                 =    0x0000020b,
+  CL_SPAWNING_POINT             =    0x0000020c,
+  CL_MD2_CREATURE               =    0x0000020d,
+
+  CL_TURRET_POWER_UP            =    0x00000211,
+  CL_LASER_POWER_UP             =    0x00000212,
+  CL_WEAPON_POWER_UP            =    0x00000213,
+  CL_PARAM_POWER_UP             =    0x00000214,
+
+  CL_TEST_GUN                   =    0x00000230,
+  CL_TURRET                     =    0x00000231,
+  CL_AIMING_TURRET              =    0x00000232,
+  CL_CANNON                     =    0x00000233,
+  CL_TARGETING_TURRET           =    0x00000234,
+
+  CL_TEST_BULLET                =    0x00000240,
+  CL_ROCKET                     =    0x00000241,
+  CL_LASER                      =    0x00000242,
+  CL_BOMB                       =    0x00000243,
+  CL_GROUND_TURRET              =    0x00000244,
+  CL_GUIDED_MISSILE             =    0x00000245,
+
+  CL_NPC_TEST1                  =    0x00000301,
+  CL_NPC_TEST2                  =    0x00000302,
+  CL_MOVIE_ENTITY               =    0x00000303,
+
+
+  // gamePlay (range from 0x00000500 0x000005ff)
+  CL_EVENT                      =    0x00000501,
+  CL_KEY_MAPPER                 =    0x00000502,
+  CL_CROSSHAIR                  =    0x00000512,
+
+  CL_WEAPON_MANAGER             =    0x00000503,
+  CL_HUD                        =    0x00000520,
+
+  // Physics stuff (range from 0x00000600 to 0x000007ff)
+  CL_PHYSICS_CONNECTION         =    0x00000601,
+  CL_FIELD_GRAVITY              =    0x00000610,
+  CL_FIELD_POINT_GRAVITY        =    0x00000611,
+  CL_FIELD_TWIRL                =    0x00000612,
+
+
+  // Collision
+  CL_COLLISION                  =    0x00000611,
+  CL_BV_TREE                    =    0x00a01000,
+  CL_BV_TREE_NODE               =    0x00002000,
+  CL_OBB_TREE                   =    0x00000614,
+  CL_OBB_TREE_NODE              =    0x00000615,
+  CL_BOUNDING_VOLUME            =    0x00a10000,
+  CL_OBB                        =    0x00020617,
+  CL_BOUNDING_SPHERE            =    0x00040618,
+
+  // graphical stuff (range from 0x00000800 to 0x000009ff)
+  CL_FONT                       =    0x00000802,
+
+  CL_PARTICLE_EMITTER           =    0x00201852,
+  CL_PARTICLE_SYSTEM            =    0x00202000,
+  CL_SPRITE_PARTICLES           =    0x00000853,
+  CL_SPARK_PARTICLES            =    0x00000854,
+  CL_PNODE_PARTICLES            =    0x00000855,
+  CL_DOT_PARTICLES              =    0x00000856,
+  CL_MODEL_PARTICLES            =    0x00000857,
+//  CL_TEMPLATE_PARTICLES         =    0x00000857,
+
+  CL_MATERIAL                   =    0x00000804,
+  CL_TEXTURE_SEQUENCE           =    0x00004805,
+  CL_OBJ_MODEL                  =    0x00000807,
+
+  CL_MOVIE_PLAYER               =    0x00000805,
+  CL_MEDIA_CONTAINER            =    0x00000806,
+  CL_PROMITIVE_MODEL            =    0x00000808,
+  CL_MD2Model                   =    0x00000809,
+  CL_HEIGHT_MAP                 =    0x0000080a,
+  CL_GRID                       =    0x0000080b,
+
+  CL_LIGHT                      =    0x00000811,
+  CL_ENVIRONMENT                =    0x00000821,
+  CL_SHADER                     =    0x00000822,
+  // GL-GUI
+  CL_GLGUI_WIDGET               =    0x00500000,
+  CL_GLGUI_BUTTON               =    0x00501000,
+  CL_GLGUI_PUSHBUTTON           =    0x00000903,
+  CL_GLGUI_CHECKBUTTON          =    0x00000904,
+  CL_GLGUI_RADIOBUTTON          =    0x00000905,
+  CL_GLGUI_CONTAINER            =    0x00002906,
+  CL_GLGUI_BOX                  =    0x00000907,
+  CL_GLGUI_FRAME                =    0x00000908,
+  CL_GLGUI_WINDOW               =    0x00000909,
+  CL_GLMENU_IMAGE_SCREEN        =    0x00000920,
+  CL_GLGUI_BAR                  =    0x00000930,
+
+  // sound stuff (range from 0x00000a00 to 0x00000aff)
+  CL_SOUND_BUFFER               =    0x00000a01,
+  CL_SOUND_SOURCE               =    0x00000a02,
+  CL_SOUND_OGG_PLAYER           =    0x00000a11,
+
+
+  // network stuff (range from 0x00000b00 to 0x00000bff)
+  CL_DATA_STREAM                =    0x00b01b00,
+  CL_NETWORK_STREAM             =    0x00000b01,
+  CL_NETWORK_PROTOCOL           =    0x00000b02,
+  CL_NETWORK_SOCKET             =    0x00000b03,
+  CL_SERVER_SOCKET              =    0X00000b04,
+  CL_CONNECTION_MONITOR         =    0x00000b05,
+  CL_HANDSHAKE                  =    0x00000b06,
+  CL_NETWORK_GAME_MANAGER       =    0x00000b07,
+
+
+
+  // misc: (range from 0x00000d00 to 0x00000eff)
+  CL_ANIMATION                  =    0x00000d01,
+  //  CL_ANIMATION3D                =    0x00000b02,
+  CL_QUICK_ANIMATION            =    0x00000d02,
+  CL_FACTORY                    =    0x00000d03,
+  CL_INI_PARSER                 =    0x00000d04,
+  CL_LIST                       =    0x00000d05,
+  CL_SUBSTRING                  =    0x00000d06,
+  CL_LOAD_PARAM                 =    0x00000d07,
+  CL_CURVE                      =    0x00000d08,
+  CL_VECTOR                     =    0x00000d09,
+  CL_CHARACTER_ATTRIBUTES       =    0x00000d0a,
+  CL_TRACK_ELEMENT              =    0x00000d0b,
+  CL_NUMBER                     =    0x00000d0c,
+  CL_EXECUTOR                   =    0x00000d0d,
+  CL_FAST_FACTORY               =    0x00000d01,
+  CL_SHELL                      =    0x00000d10,
+  CL_SHELL_COMMAND              =    0x00000d11,
+  CL_SHELL_COMMAND_CLASS        =    0x00000d12,
+  CL_SHELL_INPUT                =    0x00000d13,
+  CL_SHELL_COMPLETION           =    0x00000d14,
+  CL_SHELL_COMMAND_ALIAS        =    0x00000d15,
+
+  // Spatial Data Separation
+  CL_SPATIAL_SEPARATION         =    0x00000d0d,
+  CL_QUADTREE                   =    0x00000d0e,
+  CL_QUADTREE_NODE              =    0x00000d0f,
+};
+
+
+#endif /* _CLASS_ID_H */
Index: branches/network/src/defs/comincl.h
===================================================================
--- branches/network/src/defs/comincl.h	(revision 6636)
+++ branches/network/src/defs/comincl.h	(revision 6636)
@@ -0,0 +1,13 @@
+/*!
+  \file glincl.h
+  \brief This file includes gl Headers.
+  
+  no Class is defined here, but the opengl Headers
+*/
+
+#ifndef _COMINCL_H
+#define _COMINCL_H
+
+#include "message_structures.h"
+
+#endif /* _COMINCL_H */
Index: branches/network/src/defs/compiler.h
===================================================================
--- branches/network/src/defs/compiler.h	(revision 6636)
+++ branches/network/src/defs/compiler.h	(revision 6636)
@@ -0,0 +1,14 @@
+
+#ifndef _COMPILER_H
+#define _COMPILER_H
+
+/* performance tweaking stuff */
+#if __GNUC__ == 2 && __GNUC_MINOR__ < 96
+#define __builtin_expect(x, expected_value) (x)
+#endif
+
+#define likely(x)       __builtin_expect((x),1)
+#define unlikely(x)     __builtin_expect((x),0)
+
+
+#endif /* _COMPILER_H */
Index: branches/network/src/defs/confincl.h
===================================================================
--- branches/network/src/defs/confincl.h	(revision 6636)
+++ branches/network/src/defs/confincl.h	(revision 6636)
@@ -0,0 +1,13 @@
+/*!
+  \file confincl.h
+  \brief includes the configure-headers, if config should be loaded
+*/
+
+#ifndef _CONFINCL_H
+#define _CONFINCL_H
+
+#if HAVE_CONFIG_H 
+#include <config.h> 
+#endif
+
+#endif /*_CONFINCL_H */
Index: branches/network/src/defs/debug.h
===================================================================
--- branches/network/src/defs/debug.h	(revision 6636)
+++ branches/network/src/defs/debug.h	(revision 6636)
@@ -0,0 +1,235 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+/*!
+ * @file debug.h
+  *  Handles output to console for different Verbose-Modes.
+
+    There are two main modes HARD and SOFT. HARD is precessed during compileTime where SOFT is for runtime.
+    \li HARD: One can choose between different modes. see: // DEFINE_MODULES
+    \li SOFT: If you want each module can have its own variable for processing. just pass it to DEBUG_MODULE_SOFT
+*/
+
+#ifndef _DEBUG_H
+#define _DEBUG_H
+
+#include "confincl.h"
+#ifndef NO_SHELL
+ #include "shell_buffer.h"
+#endif /* NO_SHELL */
+
+#include <stdio.h>
+
+// DEFINE ERROR MODES
+#define NO              0
+#define ERR             1
+#define WARN            2
+#define INFO            3
+//#define DEBUG           4
+#define vDEBUG          5
+
+extern int verbose;
+
+//definitions
+#ifndef MODULAR_DEBUG
+ #define HARD_DEBUG_LEVEL DEBUG
+ #define SOFT_DEBUG_LEVEL verbose
+#else /* MODULAR_DEBUG */
+ #ifndef DEBUG_MODULE_SOFT
+  #define SOFT_DEBUG_LEVEL verbose
+ #else /* DEBUG_MODULE_SOFT */
+  #define SOFT_DEBUG_LEVEL DEBUG_MODULE_SOFT
+ #endif /* DEBUG_MODULE_SOFT */
+
+ #ifndef DEBUG_SPECIAL_MODULE
+  #define HARD_DEBUG_LEVEL DEBUG
+ #else /* DEBUG_SPECIAL_MODULE */
+  ////////////////////
+  // DEFINE MODULES //
+  ////////////////////
+  // FRAMEWORK
+  #define DEBUG_MODULE_BASE                  2
+  #define DEBUG_MODULE_ORXONOX               2
+  #define DEBUG_MODULE_WORLD                 2
+  #define DEBUG_MODULE_NETWORK               2
+
+  // LOADING
+  #define DEBUG_MODULE_LOAD                  2
+  #define DEBUG_MODULE_IMPORTER              2
+
+  // ENGINES
+  #define DEBUG_MODULE_GRAPHICS              2
+  #define DEBUG_MODULE_EVENT                 2
+  #define DEBUG_MODULE_PHYSICS               2
+  #define DEBUG_MODULE_GARBAGE_COLLECTOR     2
+  #define DEBUG_MODULE_OBJECT_MANAGER        2
+  #define DEBUG_MODULE_ANIM                  2
+  #define DEBUG_MODULE_COLLISON_DETECTION    2
+  #define DEBUG_MODULE_SPATIAL_SEPARATION    2
+  #define DEBUG_MODULE_GUI                   2
+  #define DEBUG_MODULE_SOUND                 2
+
+  // MISC
+  #define DEBUG_MODULE_TRACK_MANAGER         2
+  #define DEBUG_MODULE_MATH                  2
+
+  #define DEBUG_MODULE_PNODE                 2
+  #define DEBUG_MODULE_WORLD_ENTITY          2
+
+  #define DEBUG_MODULE_WEAPON                2
+
+  #define HARD_DEBUG_LEVEL DEBUG_SPECIAL_MODULE
+
+ #endif /* DEBUG_SPECIAL_MODULE */
+#endif /* MODULAR_DEBUG */
+
+///////////////////////////////////////////////////
+/// PRINTF: prints with filename and linenumber ///
+///////////////////////////////////////////////////
+#define PRINTFNO      PRINTF0
+#define PRINTFERR     PRINTF1
+#define PRINTFWARN    PRINTF2
+#define PRINTFINFO    PRINTF3
+#define PRINTFDEBUG   PRINTF4
+#define PRINTFVDEBUG  PRINTF5
+
+#if DEBUG <= 3
+#define PRINTF(x)        PRINT(x)
+#endif
+#ifndef NO_SHELL
+#define PRINT_EXEC       ShellBuffer::addBufferLineStatic
+#else /* NO_SHELL */
+#define PRINT_EXEC       printf
+#endif
+
+#ifndef PRINTF
+#ifdef DEBUG
+
+#define PRINTF(x) \
+           PRINTF ## x
+
+#if HARD_DEBUG_LEVEL >= ERR
+#define PRINTF1 \
+    if (SOFT_DEBUG_LEVEL >= ERR) \
+      printf("(EE)::%s:%d:", __FILE__, __LINE__) && PRINT_EXEC
+#else
+#define PRINTF1 if (NO)
+#endif
+
+#if HARD_DEBUG_LEVEL >= WARN
+#define PRINTF2 \
+     if (SOFT_DEBUG_LEVEL >= WARN) \
+       printf("(WW)::%s:%d:", __FILE__, __LINE__) && PRINT_EXEC
+
+#else
+#define PRINTF2 if (NO)
+#endif
+
+#if HARD_DEBUG_LEVEL >= INFO
+#define PRINTF3 \
+     if (SOFT_DEBUG_LEVEL >= INFO) \
+       printf("(II)::%s:%d:", __FILE__, __LINE__) && PRINT_EXEC
+#else
+#define PRINTF3 if (NO)
+#endif
+
+#if HARD_DEBUG_LEVEL >= DEBUG
+#define PRINTF4 \
+     if (SOFT_DEBUG_LEVEL >= DEBUG) \
+       printf("(DD)::%s:%d:", __FILE__, __LINE__) && PRINT_EXEC
+#else
+#define PRINTF4 if (NO)
+#endif
+
+#if HARD_DEBUG_LEVEL >= vDEBUG
+#define PRINTF5 \
+     if (SOFT_DEBUG_LEVEL >= vDEBUG) \
+       printf("(VD)::%s:%d:", __FILE__, __LINE__) && PRINT_EXEC
+#else
+#define PRINTF5 if (NO)
+#endif
+
+#else
+#define PRINTF(x) if (NO)
+#endif
+
+#define PRINTF0 \
+    printf("%s:%d::", __FILE__, __LINE__) && PRINT_EXEC
+#endif
+
+///////////////////////////////////////////////////
+///  PRINT: just prints output as is            ///
+///////////////////////////////////////////////////
+#define PRINTNO      PRINT0
+#define PRINTERR     PRINT1
+#define PRINTWARN    PRINT2
+#define PRINTINFO    PRINT3
+#define PRINTDEBUG   PRINT4
+#define PRINTVDEBUG  PRINT5
+
+#ifdef  DEBUG
+#define PRINT(x) \
+  PRINT ## x
+
+#if HARD_DEBUG_LEVEL >= ERR
+#define PRINT1  \
+  if (SOFT_DEBUG_LEVEL >= ERR)  \
+    PRINT_EXEC
+#else
+#define PRINT1 if (NO)
+#endif
+
+#if HARD_DEBUG_LEVEL >= WARN
+#define PRINT2 \
+  if (SOFT_DEBUG_LEVEL >= WARN) \
+    PRINT_EXEC
+
+#else
+#define PRINT2 if (NO)
+#endif
+
+#if HARD_DEBUG_LEVEL >= INFO
+#define PRINT3 \
+  if (SOFT_DEBUG_LEVEL >= INFO) \
+    PRINT_EXEC
+#else
+#define PRINT3 if (NO)
+#endif
+
+#if HARD_DEBUG_LEVEL >= DEBUG
+#define PRINT4 \
+  if (SOFT_DEBUG_LEVEL >= DEBUG) \
+    PRINT_EXEC
+#else
+#define PRINT4 if (NO)
+#endif
+
+#if HARD_DEBUG_LEVEL >= vDEBUG
+#define PRINT5 \
+     if (SOFT_DEBUG_LEVEL >= vDEBUG) \
+       PRINT_EXEC
+#else
+#define PRINT5 if (NO)
+#endif
+
+
+#else
+#define PRINT(x) if (NO)
+#endif
+
+#define PRINT0 \
+  PRINT_EXEC
+
+#endif /* _DEBUG_H */
Index: branches/network/src/defs/error.h
===================================================================
--- branches/network/src/defs/error.h	(revision 6636)
+++ branches/network/src/defs/error.h	(revision 6636)
@@ -0,0 +1,63 @@
+
+
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: Christian Meyer
+*/
+
+
+/*! 
+ * @file error.h
+  *  A compendium of Error codes used in the program
+*/ 
+
+
+#ifndef _ERROR_H
+#define _ERROR_H
+
+// these are the two undefined error nr. Don't use them ...
+#define oERROR -1
+
+#define oNOERROR 0
+
+/*!
+  *  Error Definitions:
+
+    Error Classes:
+    0xx application framework codes
+    1xx graphics codes
+    2xx file/FS codes
+    3xx network codes
+    4xx general codes
+
+    Error Specifier 1:
+    x0x action finsished as desired
+    x1x initialisation error
+    x2x execution error
+    x3x uninitialisation error
+
+    Error Specifier 2:
+    xx0 no further informations
+    xx1 only a warning - feel free to ignore, the program will proceed
+    xx2 this could lead unexpected behaviour
+    xx3 this is a fatal error - you are invited to quit the program - panic!
+*/
+
+typedef struct 
+{
+  int code;
+  char* message;
+  char* location;
+} ErrorMessage;
+
+#endif /* _ERROR_H */
Index: branches/network/src/defs/glincl.h
===================================================================
--- branches/network/src/defs/glincl.h	(revision 6636)
+++ branches/network/src/defs/glincl.h	(revision 6636)
@@ -0,0 +1,21 @@
+/*!
+  \file glincl.h
+  \brief This file includes gl Headers.
+
+  no Class is defined here, but the opengl Headers
+*/
+
+#ifndef _GLINCL_H
+#define _GLINCL_H
+
+#ifndef __APPLE__
+#include <GL/glew.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+#else
+#include <GL/glew.h>
+#include <OpenGL/gl.h>
+#include <OpenGL/glu.h>
+#endif
+
+#endif /* _GLINCL_H */
Index: branches/network/src/defs/globals.h
===================================================================
--- branches/network/src/defs/globals.h	(revision 6636)
+++ branches/network/src/defs/globals.h	(revision 6636)
@@ -0,0 +1,456 @@
+/*!
+  \file globals.h
+  \brief This file defines some global default values.
+
+  no Class is defined here.
+*/
+
+#ifndef _GLOBALS_H
+#define _GLOBALS_H
+
+#include "confincl.h"
+
+
+#define   ORXONOX_STAFF "Patrick Boenzli - Captain\n" \
+                        "Benjamin Grauer - First Officer\n" \
+                        "Christian Meyer - Engeneer\n" \
+                        "Nico Bernold - Physics\n" \
+                        "David Gruetter - The ProtoType\n" \
+                        "Aaron von Schroeder - Sensors\n" \
+                        "Lukas Grauer - Phasers\n" \
+                        "many more...\n"
+
+#define   ORXONOX_WEBPAGE                  "http://www.orxonox.net"
+
+#define   DEFAULT_CONFIG_FILE              "~/.orxonox/orxonox.conf"
+#define   DEFAULT_LOCK_FILE                "~/.orxonox/orxonox.lock"
+#define   DEFAULT_DATA_DIR                 DATADIR "/orxonox/"
+#define   DEFAULT_DATA_DIR_CHECKFILE       "data.oxd"
+
+// Defines all the Sections of the Config (in Gui and orxonox)
+//! Name of Section Misc in the config-File
+#define   CONFIG_SECTION_MISC              "misc"
+#define   CONFIG_SECTION_MISC_KEYS         "miscKeys"
+#define   CONFIG_SECTION_PLAYER            "player"
+#define   CONFIG_SECTION_VIDEO             "video"
+#define   CONFIG_SECTION_VIDEO_ADVANCED    "video_advanced"
+#define   CONFIG_SECTION_AUDIO             "audio"
+#define   CONFIG_SECTION_EXEC              "exec"
+#define   CONFIG_SECTION_DATA              "data"
+
+/*
+  TAGS for all the Configuration Options
+  Consider they may __not__ have any WhiteSpaces inside
+*/
+#define   CONFIG_NAME_DATADIR              "DataDir"
+#define   CONFIG_NAME_AUTO_UPDATE          "Auto-Update"
+
+#define   CONFIG_NAME_FULLSCREEN           "Fullscreen-mode"
+#define   CONFIG_NAME_RESOLUTION           "Resolution"
+#define   CONFIG_NAME_WIREFRAME            "WireFrame-mode"
+#define   CONFIG_NAME_SHADOWS              "Shadows"
+#define   CONFIG_NAME_FOG                  "Fog"
+#define   CONFIG_NAME_REFLECTIONS          "Reflections"
+#define   CONFIG_NAME_TEXTURES             "TEXTURES"
+#define   CONFIG_NAME_TEXTURE_DETAIL       "Texture-Detail"
+#define   CONFIG_NAME_MODEL_DETAIL         "Model-Detail"
+#define   CONFIG_NAME_PARTICLES_ENABLED    "Particles Enabled"
+#define   CONFIG_NAME_ANTI_ALIASING        "Anti-Aliasing"
+#define   CONFIG_NAME_FILTER_METHOD        "Filtering-Method"
+
+#define   CONFIG_NAME_DISABLE_AUDIO        "Disable-Audio"
+#define   CONFIG_NAME_AUDIO_CHANNELS       "Audio-Channels"
+#define   CONFIG_NAME_MUSIC_VOLUME         "Music-Volume"
+#define   CONFIG_NAME_EFFECTS_VOLUME       "Effects-Volume"
+
+#define   CONFIG_NAME_SAVE_SETTINGS        "Save-Settings"
+#define   CONFIG_NAME_VERBOSE_MODE         "Verbose-Mode"
+#define   CONFIG_NAME_ALWAYS_SHOW_GUI      "Always-Show-The-Gui"
+// evenets
+#define   CONFIG_NAME_PLAYER_UP            "Up"
+#define   CONFIG_NAME_PLAYER_DOWN          "Down"
+#define   CONFIG_NAME_PLAYER_LEFT          "Left"
+#define   CONFIG_NAME_PLAYER_RIGHT         "Right"
+#define   CONFIG_NAME_PLAYER_ROLL_RIGHT    "RollR"
+#define   CONFIG_NAME_PLAYER_ROLL_LEFT     "RollL"
+
+#define   CONFIG_NAME_PLAYER_FIRE          "Fire"
+#define   CONFIG_NAME_PLAYER_NEXT_WEAPON   "Next"
+#define   CONFIG_NAME_PLAYER_PREV_WEAPON   "Prev"
+#define   CONFIG_NAME_QUIT                 "Quit"
+#define   CONFIG_NAME_PAUSE                "Pause"
+#define   CONFIG_NAME_NEXT_WORLD           "Next-World"
+#define   CONFIG_NAME_PREV_WORLD           "Prev-World"
+#define   CONFIG_NAME_VIEW0                "view0"
+#define   CONFIG_NAME_VIEW1                "view1"
+#define   CONFIG_NAME_VIEW2                "view2"
+#define   CONFIG_NAME_VIEW3                "view3"
+#define   CONFIG_NAME_VIEW4                "view4"
+#define   CONFIG_NAME_VIEW5                "view5"
+
+
+#define  ORXONOX_LICENSE_SHORT \
+    "Orxonox - The Future of 3D-Action-Game\n" \
+    "\n" \
+    "Copyright (C) 2004 orx\n" \
+    "\n" \
+    "This program is free software; you can redistribute it and/or modify\n" \
+    "it under the terms of the GNU General Public License as published by\n" \
+    "the Free Software Foundation; either version 2, or (at your option)\n" \
+    "any later version.\n" \
+    "\n" \
+    "This program is distributed in the hope that it will be useful,\n" \
+    "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"  \
+    "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n"   \
+    "GNU General Public License for more details.\n" \
+    "\n" \
+    "You should have received a copy of the GNU General Public License\n" \
+    "along with this program; if not, write to the Free Software Foundation,\n" \
+    "Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.\n"
+
+
+
+#define GNU_LICENCE_LONG \
+"                    GNU GENERAL PUBLIC LICENSE\n" \
+"                       Version 2, June 1991\n" \
+"\n" \
+" Copyright (C) 1989, 1991 Free Software Foundation, Inc.\n" \
+"     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n" \
+" Everyone is permitted to copy and distribute verbatim copies\n" \
+" of this license document, but changing it is not allowed.\n" \
+"\n" \
+"                            Preamble\n" \
+"\n" \
+"  The licenses for most software are designed to take away your\n" \
+"freedom to share and change it.  By contrast, the GNU General Public\n" \
+"License is intended to guarantee your freedom to share and change free\n" \
+"software--to make sure the software is free for all its users.  This\n" \
+"General Public License applies to most of the Free Software\n" \
+"Foundation's software and to any other program whose authors commit to\n" \
+"using it.  (Some other Free Software Foundation software is covered by\n" \
+"the GNU Library General Public License instead.)  You can apply it to\n" \
+"your programs, too.\n" \
+"\n" \
+"  When we speak of free software, we are referring to freedom, not\n" \
+"price.  Our General Public Licenses are designed to make sure that you\n" \
+"have the freedom to distribute copies of free software (and charge for\n" \
+"this service if you wish), that you receive source code or can get it\n" \
+"if you want it, that you can change the software or use pieces of it\n" \
+"in new free programs; and that you know you can do these things.\n" \
+"\n" \
+"  To protect your rights, we need to make restrictions that forbid\n" \
+"anyone to deny you these rights or to ask you to surrender the rights.\n" \
+"These restrictions translate to certain responsibilities for you if you\n" \
+"distribute copies of the software, or if you modify it.\n" \
+"\n" \
+"  For example, if you distribute copies of such a program, whether\n" \
+"gratis or for a fee, you must give the recipients all the rights that\n" \
+"you have.  You must make sure that they, too, receive or can get the\n" \
+"source code.  And you must show them these terms so they know their\n" \
+"rights.\n" \
+"\n" \
+"  We protect your rights with two steps: (1) copyright the software, and\n" \
+"(2) offer you this license which gives you legal permission to copy,\n" \
+"distribute and/or modify the software.\n" \
+"\n" \
+"  Also, for each author's protection and ours, we want to make certain\n" \
+"that everyone understands that there is no warranty for this free\n" \
+"software.  If the software is modified by someone else and passed on, we\n" \
+"want its recipients to know that what they have is not the original, so\n" \
+"that any problems introduced by others will not reflect on the original\n" \
+"authors' reputations.\n" \
+"\n" \
+"  Finally, any free program is threatened constantly by software\n" \
+"patents.  We wish to avoid the danger that redistributors of a free\n" \
+"program will individually obtain patent licenses, in effect making the\n" \
+"program proprietary.  To prevent this, we have made it clear that any\n" \
+"patent must be licensed for everyone's free use or not licensed at all.\n" \
+"\n" \
+"  The precise terms and conditions for copying, distribution and\n" \
+"modification follow.\n" \
+"\n" \
+"                    GNU GENERAL PUBLIC LICENSE\n" \
+"   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n" \
+"\n" \
+"  0. This License applies to any program or other work which contains\n" \
+"a notice placed by the copyright holder saying it may be distributed\n" \
+"under the terms of this General Public License.  The \"Program\", below,\n" \
+"refers to any such program or work, and a \"work based on the Program\"\n" \
+"means either the Program or any derivative work under copyright law:\n" \
+"that is to say, a work containing the Program or a portion of it,\n" \
+"either verbatim or with modifications and/or translated into another\n" \
+"language.  (Hereinafter, translation is included without limitation in\n" \
+"the term \"modification\".)  Each licensee is addressed as \"you\".\n" \
+"\n" \
+"Activities other than copying, distribution and modification are not\n" \
+"covered by this License; they are outside its scope.  The act of\n" \
+"running the Program is not restricted, and the output from the Program\n" \
+"is covered only if its contents constitute a work based on the\n" \
+"Program (independent of having been made by running the Program).\n" \
+"Whether that is true depends on what the Program does.\n" \
+"\n" \
+"  1. You may copy and distribute verbatim copies of the Program's\n" \
+"source code as you receive it, in any medium, provided that you\n" \
+"conspicuously and appropriately publish on each copy an appropriate\n" \
+"copyright notice and disclaimer of warranty; keep intact all the\n" \
+"notices that refer to this License and to the absence of any warranty;\n" \
+"and give any other recipients of the Program a copy of this License\n" \
+"along with the Program.\n" \
+"\n" \
+"You may charge a fee for the physical act of transferring a copy, and\n" \
+"you may at your option offer warranty protection in exchange for a fee.\n" \
+"\n" \
+"  2. You may modify your copy or copies of the Program or any portion\n" \
+"of it, thus forming a work based on the Program, and copy and\n" \
+"distribute such modifications or work under the terms of Section 1\n" \
+"above, provided that you also meet all of these conditions:\n" \
+"\n" \
+"    a) You must cause the modified files to carry prominent notices\n" \
+"    stating that you changed the files and the date of any change.\n" \
+"\n" \
+"    b) You must cause any work that you distribute or publish, that in\n" \
+"    whole or in part contains or is derived from the Program or any\n" \
+"    part thereof, to be licensed as a whole at no charge to all third\n" \
+"    parties under the terms of this License.\n" \
+"\n" \
+"    c) If the modified program normally reads commands interactively\n" \
+"    when run, you must cause it, when started running for such\n" \
+"    interactive use in the most ordinary way, to print or display an\n" \
+"    announcement including an appropriate copyright notice and a\n" \
+"    notice that there is no warranty (or else, saying that you provide\n" \
+"    a warranty) and that users may redistribute the program under\n" \
+"    these conditions, and telling the user how to view a copy of this\n" \
+"    License.  (Exception: if the Program itself is interactive but\n" \
+"    does not normally print such an announcement, your work based on\n" \
+"    the Program is not required to print an announcement.)\n" \
+"\n" \
+"These requirements apply to the modified work as a whole.  If\n" \
+"identifiable sections of that work are not derived from the Program,\n" \
+"and can be reasonably considered independent and separate works in\n" \
+"themselves, then this License, and its terms, do not apply to those\n" \
+"sections when you distribute them as separate works.  But when you\n" \
+"distribute the same sections as part of a whole which is a work based\n" \
+"on the Program, the distribution of the whole must be on the terms of\n" \
+"this License, whose permissions for other licensees extend to the\n" \
+"entire whole, and thus to each and every part regardless of who wrote it.\n" \
+"\n" \
+"Thus, it is not the intent of this section to claim rights or contest\n" \
+"your rights to work written entirely by you; rather, the intent is to\n" \
+"exercise the right to control the distribution of derivative or\n" \
+"collective works based on the Program.\n" \
+"\n" \
+"In addition, mere aggregation of another work not based on the Program\n" \
+"with the Program (or with a work based on the Program) on a volume of\n" \
+"a storage or distribution medium does not bring the other work under\n" \
+"the scope of this License.\n" \
+"\n" \
+"  3. You may copy and distribute the Program (or a work based on it,\n" \
+"under Section 2) in object code or executable form under the terms of\n" \
+"Sections 1 and 2 above provided that you also do one of the following:\n" \
+"\n" \
+"    a) Accompany it with the complete corresponding machine-readable\n" \
+"    source code, which must be distributed under the terms of Sections\n" \
+"    1 and 2 above on a medium customarily used for software interchange; or,\n" \
+"\n" \
+"    b) Accompany it with a written offer, valid for at least three\n" \
+"    years, to give any third party, for a charge no more than your\n" \
+"    cost of physically performing source distribution, a complete\n" \
+"    machine-readable copy of the corresponding source code, to be\n" \
+"    distributed under the terms of Sections 1 and 2 above on a medium\n" \
+"    customarily used for software interchange; or,\n" \
+"\n" \
+"    c) Accompany it with the information you received as to the offer\n" \
+"    to distribute corresponding source code.  (This alternative is\n" \
+"    allowed only for noncommercial distribution and only if you\n" \
+"    received the program in object code or executable form with such\n" \
+"    an offer, in accord with Subsection b above.)\n" \
+"\n" \
+"The source code for a work means the preferred form of the work for\n" \
+"making modifications to it.  For an executable work, complete source\n" \
+"code means all the source code for all modules it contains, plus any\n" \
+"associated interface definition files, plus the scripts used to\n" \
+"control compilation and installation of the executable.  However, as a\n" \
+"special exception, the source code distributed need not include\n" \
+"anything that is normally distributed (in either source or binary\n" \
+"form) with the major components (compiler, kernel, and so on) of the\n" \
+"operating system on which the executable runs, unless that component\n" \
+"itself accompanies the executable.\n" \
+"\n" \
+"If distribution of executable or object code is made by offering\n" \
+"access to copy from a designated place, then offering equivalent\n" \
+"access to copy the source code from the same place counts as\n" \
+"distribution of the source code, even though third parties are not\n" \
+"compelled to copy the source along with the object code.\n" \
+"\n" \
+"  4. You may not copy, modify, sublicense, or distribute the Program\n" \
+"except as expressly provided under this License.  Any attempt\n" \
+"otherwise to copy, modify, sublicense or distribute the Program is\n" \
+"void, and will automatically terminate your rights under this License.\n" \
+"However, parties who have received copies, or rights, from you under\n" \
+"this License will not have their licenses terminated so long as such\n" \
+"parties remain in full compliance.\n" \
+"\n" \
+"  5. You are not required to accept this License, since you have not\n" \
+"signed it.  However, nothing else grants you permission to modify or\n" \
+"distribute the Program or its derivative works.  These actions are\n" \
+"prohibited by law if you do not accept this License.  Therefore, by\n" \
+"modifying or distributing the Program (or any work based on the\n" \
+"Program), you indicate your acceptance of this License to do so, and\n" \
+"all its terms and conditions for copying, distributing or modifying\n" \
+"the Program or works based on it.\n" \
+"\n" \
+"  6. Each time you redistribute the Program (or any work based on the\n" \
+"Program), the recipient automatically receives a license from the\n" \
+"original licensor to copy, distribute or modify the Program subject to\n" \
+"these terms and conditions.  You may not impose any further\n" \
+"restrictions on the recipients' exercise of the rights granted herein.\n" \
+"You are not responsible for enforcing compliance by third parties to\n" \
+"this License.\n" \
+"\n" \
+"  7. If, as a consequence of a court judgment or allegation of patent\n" \
+"infringement or for any other reason (not limited to patent issues),\n" \
+"conditions are imposed on you (whether by court order, agreement or\n" \
+"otherwise) that contradict the conditions of this License, they do not\n" \
+"excuse you from the conditions of this License.  If you cannot\n" \
+"distribute so as to satisfy simultaneously your obligations under this\n" \
+"License and any other pertinent obligations, then as a consequence you\n" \
+"may not distribute the Program at all.  For example, if a patent\n" \
+"license would not permit royalty-free redistribution of the Program by\n" \
+"all those who receive copies directly or indirectly through you, then\n" \
+"the only way you could satisfy both it and this License would be to\n" \
+"refrain entirely from distribution of the Program.\n" \
+"\n" \
+"If any portion of this section is held invalid or unenforceable under\n" \
+"any particular circumstance, the balance of the section is intended to\n" \
+"apply and the section as a whole is intended to apply in other\n" \
+"circumstances.\n" \
+"\n" \
+"It is not the purpose of this section to induce you to infringe any\n" \
+"patents or other property right claims or to contest validity of any\n" \
+"such claims; this section has the sole purpose of protecting the\n" \
+"integrity of the free software distribution system, which is\n" \
+"implemented by public license practices.  Many people have made\n" \
+"generous contributions to the wide range of software distributed\n" \
+"through that system in reliance on consistent application of that\n" \
+"system; it is up to the author/donor to decide if he or she is willing\n" \
+"to distribute software through any other system and a licensee cannot\n" \
+"impose that choice.\n" \
+"\n" \
+"This section is intended to make thoroughly clear what is believed to\n" \
+"be a consequence of the rest of this License.\n" \
+"\n" \
+"  8. If the distribution and/or use of the Program is restricted in\n" \
+"certain countries either by patents or by copyrighted interfaces, the\n" \
+"original copyright holder who places the Program under this License\n" \
+"may add an explicit geographical distribution limitation excluding\n" \
+"those countries, so that distribution is permitted only in or among\n" \
+"countries not thus excluded.  In such case, this License incorporates\n" \
+"the limitation as if written in the body of this License.\n" \
+"\n" \
+"  9. The Free Software Foundation may publish revised and/or new versions\n" \
+"of the General Public License from time to time.  Such new versions will\n" \
+"be similar in spirit to the present version, but may differ in detail to\n" \
+"address new problems or concerns.\n" \
+"\n" \
+"Each version is given a distinguishing version number.  If the Program\n" \
+"specifies a version number of this License which applies to it and \"any\n" \
+"later version\", you have the option of following the terms and conditions\n" \
+"either of that version or of any later version published by the Free\n" \
+"Software Foundation.  If the Program does not specify a version number of\n" \
+"this License, you may choose any version ever published by the Free Software\n" \
+"Foundation.\n" \
+"\n" \
+"  10. If you wish to incorporate parts of the Program into other free\n" \
+"programs whose distribution conditions are different, write to the author\n" \
+"to ask for permission.  For software which is copyrighted by the Free\n" \
+"Software Foundation, write to the Free Software Foundation; we sometimes\n" \
+"make exceptions for this.  Our decision will be guided by the two goals\n" \
+"of preserving the free status of all derivatives of our free software and\n" \
+"of promoting the sharing and reuse of software generally.\n" \
+"\n" \
+"                            NO WARRANTY\n" \
+"\n" \
+"  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\n" \
+"FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\n" \
+"OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n" \
+"PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\n" \
+"OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\n" \
+"MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\n" \
+"TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\n" \
+"PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\n" \
+"REPAIR OR CORRECTION.\n" \
+"\n" \
+"  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\n" \
+"WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\n" \
+"REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\n" \
+"INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\n" \
+"OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\n" \
+"TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\n" \
+"YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\n" \
+"PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\n" \
+"POSSIBILITY OF SUCH DAMAGES.\n" \
+"\n" \
+"                     END OF TERMS AND CONDITIONS\n" \
+"\n" \
+"            How to Apply These Terms to Your New Programs\n" \
+"\n" \
+"  If you develop a new program, and you want it to be of the greatest\n" \
+"possible use to the public, the best way to achieve this is to make it\n" \
+"free software which everyone can redistribute and change under these terms.\n" \
+"\n" \
+"  To do so, attach the following notices to the program.  It is safest\n" \
+"to attach them to the start of each source file to most effectively\n" \
+"convey the exclusion of warranty; and each file should have at least\n" \
+"the \"copyright\" line and a pointer to where the full notice is found.\n" \
+"\n" \
+"    <one line to give the program's name and a brief idea of what it does.>\n" \
+"    Copyright (C) <year>  <name of author>\n" \
+"\n" \
+"    This program is free software; you can redistribute it and/or modify\n" \
+"    it under the terms of the GNU General Public License as published by\n" \
+"    the Free Software Foundation; either version 2 of the License, or\n" \
+"    (at your option) any later version.\n" \
+"\n" \
+"    This program is distributed in the hope that it will be useful,\n" \
+"    but WITHOUT ANY WARRANTY; without even the implied warranty of\n" \
+"    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n" \
+"    GNU General Public License for more details.\n" \
+"\n" \
+"    You should have received a copy of the GNU General Public License\n" \
+"    along with this program; if not, write to the Free Software\n" \
+"    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n" \
+"\n" \
+"\n" \
+"Also add information on how to contact you by electronic and paper mail.\n" \
+"\n" \
+"If the program is interactive, make it output a short notice like this\n" \
+"when it starts in an interactive mode:\n" \
+"\n" \
+"    Gnomovision version 69, Copyright (C) year  name of author\n" \
+"    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n" \
+"    This is free software, and you are welcome to redistribute it\n" \
+"    under certain conditions; type `show c' for details.\n" \
+"\n" \
+"The hypothetical commands `show w' and `show c' should show the appropriate\n" \
+"parts of the General Public License.  Of course, the commands you use may\n" \
+"be called something other than `show w' and `show c'; they could even be\n" \
+"mouse-clicks or menu items--whatever suits your program.\n" \
+"\n" \
+"You should also get your employer (if you work as a programmer) or your\n" \
+"school, if any, to sign a \"copyright disclaimer\" for the program, if\n" \
+"necessary.  Here is a sample; alter the names:\n" \
+"\n" \
+"  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n" \
+"  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n" \
+"\n" \
+"  <signature of Ty Coon>, 1 April 1989\n" \
+"  Ty Coon, President of Vice\n" \
+"\n" \
+"This General Public License does not permit incorporating your program into\n" \
+"proprietary programs.  If your program is a subroutine library, you may\n" \
+"consider it more useful to permit linking proprietary applications with the\n" \
+"library.  If this is what you want to do, use the GNU Library General\n" \
+"Public License instead of this License.\n"
+
+
+#endif /* _GLOBALS_H */
Index: branches/network/src/defs/include_paths.am
===================================================================
--- branches/network/src/defs/include_paths.am	(revision 6636)
+++ branches/network/src/defs/include_paths.am	(revision 6636)
@@ -0,0 +1,37 @@
+AM_CXXFLAGS=-I$(MAINSRCDIR)
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/world_entities
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/story_entities
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/coord
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/data
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/event
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/graphics
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/graphics/text_engine
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/graphics/importer
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/graphics/spatial_separation
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/graphics/render2D
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/particles
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/gui/gtk_gui
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/gui/gl_gui
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/gui/gl_gui/glmenu
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/lang
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/shell
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/util
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/math
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/network
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/tinyxml
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/physics
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/physics/fields
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/collision_detection
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/newmat
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/lib/sound
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/defs
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/font
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/network
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/ai
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/util
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/util/animation
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/util/common
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/util/loading
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/util/track
+AM_CXXFLAGS+=-I$(MAINSRCDIR)/subprojects
Index: branches/network/src/defs/message_structures.h
===================================================================
--- branches/network/src/defs/message_structures.h	(revision 6636)
+++ branches/network/src/defs/message_structures.h	(revision 6636)
@@ -0,0 +1,30 @@
+/*!
+	\file message_structures.h
+	\brief contains defintitons of messages that can be passed between classes
+*/
+
+#ifndef _MESSAGE_STRUCTURES_H
+#define _MESSAGE_STRUCTURES_H
+
+#include "stdincl.h"
+
+#define CMD_LENGHT 16
+
+//! structure that contains a command message
+typedef struct
+{
+	char cmd[CMD_LENGHT];	//!< the command delivered
+	bool bUp;	//!< false = command was activated / true = command was deactivated
+	
+	//! if cmd is "cursor" the coordinates of the mouse cursor are stored here
+	//!@{
+	Uint16 x, y;
+	//!@}
+	
+	//! if cmd is "cursor" the relative motion of the mouse cursor is stored here
+	//!@{
+	Sint16 xrel, yrel; 
+	//!@}
+} Command;
+
+#endif /* _MESSAGE_STRUCTURES_H */
Index: branches/network/src/defs/sdlincl.h
===================================================================
--- branches/network/src/defs/sdlincl.h	(revision 6636)
+++ branches/network/src/defs/sdlincl.h	(revision 6636)
@@ -0,0 +1,20 @@
+/*!
+ * @file sdlincl.h
+ * This file includes sdl Headers.
+ *
+ * no Class is defined here, but the SDL Headers
+*/
+
+#ifndef _SDLINCL_H
+#define _SDLINCL_H
+
+#include "confincl.h"
+
+#ifdef HAVE_SDL_H
+#include <SDL.h>
+#else
+#include <SDL/SDL.h>
+#endif
+
+#endif /* _SDLINCL_H */
+
Index: branches/network/src/defs/stdincl.h
===================================================================
--- branches/network/src/defs/stdincl.h	(revision 6636)
+++ branches/network/src/defs/stdincl.h	(revision 6636)
@@ -0,0 +1,26 @@
+/*!
+  \file stdincl.h
+  \brief This file includes default headers that nearly every Class needs.
+
+  no Class is defined here, but many headers to classes, and more general Headers like the openGL-header.
+*/
+
+#ifndef _STDINCL_H
+#define _STDINCL_H
+
+typedef unsigned char byte;
+
+#include "confincl.h"
+
+#ifdef __WIN32__
+//#include <windows.h>
+#endif
+
+#include "stdlibincl.h"
+
+#include "sdlincl.h"
+#include "glincl.h"
+
+#include "compiler.h"
+
+#endif /* _STDINCL_H */
Index: branches/network/src/defs/stdlibincl.h
===================================================================
--- branches/network/src/defs/stdlibincl.h	(revision 6636)
+++ branches/network/src/defs/stdlibincl.h	(revision 6636)
@@ -0,0 +1,15 @@
+/*!
+ * @file stdlibincl.h
+ * some headers of the stdlib
+ *
+ * no Class is defined here.
+ */
+
+#ifndef _STDLIBINCL_H
+#define _STDLIBINCL_H
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+#endif /* _STDLIBINCL_H */
Index: branches/network/src/lib/Makefile.am
===================================================================
--- branches/network/src/lib/Makefile.am	(revision 6636)
+++ branches/network/src/lib/Makefile.am	(revision 6636)
@@ -0,0 +1,90 @@
+MAINSRCDIR=..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXlibs.a
+
+libORXlibs_a_DEPENDENCIES = gui/gtk_gui/libORXgui.a \
+                            gui/gl_gui/libORXglgui.a \
+                            graphics/importer/libORXimporter.a \
+                            graphics/libORXgraphics.a \
+                            sound/libORXsound.a \
+                            event/libORXevent.a \
+                            physics/libORXphysics.a \
+                            particles/libORXparticles.a \
+                            collision_detection/libORXcd.a \
+			    network/libORXnet.a \
+                            graphics/spatial_separation/libORXquadtree.a \
+                            parser/tinyxml/libtinyxml.a \
+                            parser/ini_parser/libIniParser.a \
+                            shell/libORXshell.a
+
+#libORXlibs_a_LIBDADD =     gui/gtk_gui/libORXgui.a \
+                            gui/gl_gui/libORXglgui.a \
+                            graphics/importer/libORXimporter.a \
+                            graphics/libORXgraphics.a \
+                            sound/libORXsound.a \
+                            event/libORXevent.a \
+                            physics/libORXphysics.a \
+                            particles/libORXparticles.a \
+                            collision_detection/libORXcd.a \
+			    network/libORXnet.a \
+                            graphics/spatial_separation/libORXquadtree.a \
+                            shell/libORXshell.a \
+                            $(GTK2_LIBS) $(GTHREAD_LIBS) $(CURL_LIBS)
+
+libORXlibs_a_SOURCES =  coord/p_node.cc \
+                        lang/base_object.cc \
+                        lang/class_list.cc \
+                        data/data_tank.cc \
+                        util/substring.cc \
+                        util/color.cc \
+                        util/helper_functions.cc \
+                        util/multi_type.cc \
+                        util/executor/executor.cc \
+                        math/vector.cc \
+                        math/quaternion.cc \
+                        math/vector2D.cc \
+                        math/matrix.cc \
+                        math/curve.cc \
+                        math/line.cc \
+                        math/plane.cc \
+                        math/rotation_OBSOLETE.cc
+
+noinst_HEADERS =        coord/p_node.h \
+                        lang/base_object.h \
+                        data/data_tank.h \
+                        graphics/render2D/element_2d.h \
+                        graphics/render2D/render_2d.h \
+                        lang/class_list.h \
+                        util/substring.h \
+                        util/array.h \
+                        util/list.h \
+                        util/t_stack.h \
+                        util/color.h \
+                        util/helper_functions.h \
+                        util/multi_type.h \
+                        util/executor/executor.h \
+                        util/executor/executor_specials.h \
+                        util/executor/functor_list.h \
+                        math/vector.h \
+                        math/quaternion.h \
+                        math/vector2D.h \
+                        math/matrix.h \
+                        math/curve.h \
+                        math/line.h \
+                        math/plane.h \
+                        math/rotation_OBSOLETE.h
+
+
+SUBDIRS = graphics \
+          sound \
+          event \
+          physics \
+          particles \
+          collision_detection \
+	        network \
+          parser \
+          shell \
+          gui \
+          .
+
Index: branches/network/src/lib/collision_detection/Makefile.am
===================================================================
--- branches/network/src/lib/collision_detection/Makefile.am	(revision 6636)
+++ branches/network/src/lib/collision_detection/Makefile.am	(revision 6636)
@@ -0,0 +1,27 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXcd.a
+
+libORXcd_a_SOURCES = cd_engine.cc \
+                     collision.cc \
+                     obb.cc \
+                     obb_tree.cc \
+                     obb_tree_node.cc \
+                     bv_tree.cc \
+                     bv_tree_node.cc \
+                     bounding_volume.cc \
+                     bounding_sphere.cc
+
+
+noinst_HEADERS =     cd_engine.h \
+                     collision_defs.h \
+                     collision.h \
+                     obb.h \
+                     obb_tree.h \
+                     obb_tree_node.h \
+                     bv_tree.h \
+                     bv_tree_node.h \
+                     bounding_volume.h \
+                     bounding_sphere.h
+
Index: branches/network/src/lib/collision_detection/bounding_sphere.cc
===================================================================
--- branches/network/src/lib/collision_detection/bounding_sphere.cc	(revision 6636)
+++ branches/network/src/lib/collision_detection/bounding_sphere.cc	(revision 6636)
@@ -0,0 +1,39 @@
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION
+
+#include "bounding_sphere.h"
+
+using namespace std;
+
+
+/**
+ *  standard constructor
+*/
+BoundingSphere::BoundingSphere () 
+{
+   this->setClassID(CL_BOUNDING_SPHERE, "BoundingSphere"); 
+}
+
+
+/**
+ *  standard deconstructor
+
+*/
+BoundingSphere::~BoundingSphere () 
+{
+  // delete what has to be deleted here
+}
Index: branches/network/src/lib/collision_detection/bounding_sphere.h
===================================================================
--- branches/network/src/lib/collision_detection/bounding_sphere.h	(revision 6636)
+++ branches/network/src/lib/collision_detection/bounding_sphere.h	(revision 6636)
@@ -0,0 +1,27 @@
+/*! 
+ * @file bounding_sphere.h
+  *  Definition of a bounding sphere
+
+*/
+
+#ifndef _BOUNDING_SPHERE_H
+#define _BOUNDING_SPHERE_H
+
+#include "base_object.h"
+#include "bounding_volume.h"
+
+
+//! A class representing an extended bounding volume tree: an sphere
+class BoundingSphere : public BoundingVolume {
+
+ public:
+  BoundingSphere();
+  virtual ~BoundingSphere();
+
+  inline const float getRadius () const { return this->radius; }
+
+ private:
+  float radius;
+};
+
+#endif /* _BOUNDING_SPHERE_H */
Index: branches/network/src/lib/collision_detection/bounding_volume.cc
===================================================================
--- branches/network/src/lib/collision_detection/bounding_volume.cc	(revision 6636)
+++ branches/network/src/lib/collision_detection/bounding_volume.cc	(revision 6636)
@@ -0,0 +1,47 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION
+
+#include "bounding_volume.h"
+#include "vector.h"
+
+using namespace std;
+
+
+/**
+ *  standard constructor
+*/
+BoundingVolume::BoundingVolume ()
+{
+   this->setClassID(CL_BOUNDING_VOLUME, "BoundingVolume");
+   this->center = new Vector();
+   this->bOrigVertices = true;
+   this->vertices = NULL;
+}
+
+
+/**
+ *  standard deconstructor
+
+*/
+BoundingVolume::~BoundingVolume ()
+{
+  // delete what has to be deleted here
+  delete this->center;
+
+  if( this->vertices && !this->bOrigVertices)
+    delete[] this->vertices;
+}
Index: branches/network/src/lib/collision_detection/bounding_volume.h
===================================================================
--- branches/network/src/lib/collision_detection/bounding_volume.h	(revision 6636)
+++ branches/network/src/lib/collision_detection/bounding_volume.h	(revision 6636)
@@ -0,0 +1,41 @@
+/*!
+ * @file bounding_volume.h
+  *  Definition of a bounding volume for collision detection algorithms
+
+ */
+
+#ifndef _BOUNDING_VOLUME_H
+#define _BOUNDING_VOLUME_H
+
+#include "base_object.h"
+#include "model.h"
+
+class Vector;
+template<class T> class tList;
+
+
+//! An abstract class representing a bounding volume
+class BoundingVolume : public BaseObject {
+
+  public:
+    BoundingVolume();
+    virtual ~BoundingVolume();
+
+    inline const Vector* getCenter() const { return this->center; }
+
+    const sVec3D* getVertices() const { return this->vertices; }
+    virtual void mergeWith(const BoundingVolume &bv) = 0;
+
+    virtual void drawBV(int currentDepth, int drawMode) const = 0;
+
+
+
+  public:
+    Vector*             center;                     //!< Center point of box
+
+    const sVec3D*       vertices;                   //!< if CD_STORE_VERTICES enabled, this is the place, where the vert. will be sotred
+    int                 numOfVertices;              //!< number of vertices in the vertices buffer
+    bool                bOrigVertices;              //!< is true if the vertices pointer points to the original model data - only important for deleting
+};
+
+#endif /* _BOUNDING_VOLUME_H */
Index: branches/network/src/lib/collision_detection/bv_tree.cc
===================================================================
--- branches/network/src/lib/collision_detection/bv_tree.cc	(revision 6636)
+++ branches/network/src/lib/collision_detection/bv_tree.cc	(revision 6636)
@@ -0,0 +1,43 @@
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION
+
+#include "bv_tree.h"
+
+using namespace std;
+
+
+
+/**
+ *  standard constructor
+*/
+BVTree::BVTree () 
+{
+   this->setClassID(CL_BV_TREE, "BVTree"); 
+
+}
+
+
+/**
+ *  standard deconstructor
+
+*/
+BVTree::~BVTree () 
+{
+  // delete what has to be deleted here
+}
+
+
Index: branches/network/src/lib/collision_detection/bv_tree.h
===================================================================
--- branches/network/src/lib/collision_detection/bv_tree.h	(revision 6636)
+++ branches/network/src/lib/collision_detection/bv_tree.h	(revision 6636)
@@ -0,0 +1,60 @@
+/*!
+ * @file bv_tree.h
+  *  Definition of a bounding volume tree
+
+*/
+
+#ifndef _BV_TREE_H
+#define _BV_TREE_H
+
+
+#include "base_object.h"
+#include "model.h"
+
+// FORWARD DECLARATION
+class BoundingVolume;
+class BVTreeNode;
+class PNode;
+class WorldEntity;
+
+typedef enum DrawMode
+{
+  DRAW_ALL               = 1<<0,
+  DRAW_SINGLE            = 1<<1,
+
+  DRAW_SEPARATING_PLANE  = 1<<2,
+  DRAW_BV_AXIS           = 1<<3,
+  DRAW_BV_BLENDED        = 1<<4,
+  DRAW_BV_POLYGON        = 1<<5,
+  DRAW_MODEL             = 1<<6,
+  DRAW_POINTS            = 1<<7
+};
+
+
+//! A class that represents a bounding volume tree
+class BVTree : public BaseObject {
+
+ public:
+  BVTree();
+  virtual ~BVTree();
+
+  virtual void spawnBVTree(int depth, sVec3D *verticesList, const int length) = 0;
+  virtual void spawnBVTree(int depth, const modelInfo& modInfo) = 0;
+  virtual void flushTree() = 0;
+
+  virtual void collideWith(BVTree* tree, WorldEntity* nodeA, WorldEntity* nodeB) = 0;
+  virtual void collideWith(WorldEntity* entity1, WorldEntity* entity2) = 0;
+
+  /** @param depth: depth, @param drawMode: how to draw the Model */
+  virtual void drawBV(int depth, int drawMode) const = 0;
+
+
+ protected:
+  int numberOfVertices;
+
+ private:
+
+
+};
+
+#endif /* _BV_TREE_H */
Index: branches/network/src/lib/collision_detection/bv_tree_node.cc
===================================================================
--- branches/network/src/lib/collision_detection/bv_tree_node.cc	(revision 6636)
+++ branches/network/src/lib/collision_detection/bv_tree_node.cc	(revision 6636)
@@ -0,0 +1,41 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION
+
+#include "bv_tree_node.h"
+
+using namespace std;
+
+
+/**
+ *  standard constructor
+*/
+BVTreeNode::BVTreeNode ()
+{
+   this->setClassID(CL_BV_TREE_NODE, "BVTreeNode");
+
+}
+
+
+/**
+ *  standard deconstructor
+
+*/
+BVTreeNode::~BVTreeNode ()
+{
+}
+
+
Index: branches/network/src/lib/collision_detection/bv_tree_node.h
===================================================================
--- branches/network/src/lib/collision_detection/bv_tree_node.h	(revision 6636)
+++ branches/network/src/lib/collision_detection/bv_tree_node.h	(revision 6636)
@@ -0,0 +1,44 @@
+/*!
+ * @file bv_tree.h
+  *  Definition of a bounding volume tree
+
+*/
+
+#ifndef _BV_TREE_NODE_H
+#define _BV_TREE_NODE_H
+
+#include "base_object.h"
+#include "model.h"
+#include "vector.h"
+
+// FORWARD DECLARATION
+class BoundingVolume;
+class BVTree;
+class PNode;
+class WorldEntity;
+template<class T> class tList;
+
+//! A class that represents a bounding volume tree
+class BVTreeNode : public BaseObject {
+
+ public:
+  BVTreeNode();
+  virtual ~BVTreeNode();
+
+  virtual void spawnBVTree(const int depth, const sVec3D *verticesList, unsigned int length ) = 0;
+  virtual void spawnBVTree(const int depth, const modelInfo& modInfo) = 0;
+
+  virtual BoundingVolume* getBV(int index) const = 0;
+  inline const int getIndex() { return this->treeIndex; }
+
+  virtual void collideWith(BVTreeNode* treeNode, WorldEntity* nodeA, WorldEntity* nodeB) = 0;
+
+  virtual void drawBV(int depth, int drawMode, const Vector& color = Vector(1,0,0), bool top = true) const = 0;
+
+
+ private:
+  unsigned int        treeIndex;                  //!< Index number of the BV in the tree
+
+};
+
+#endif /* _BV_TREE_NODE_H */
Index: branches/network/src/lib/collision_detection/cd_engine.cc
===================================================================
--- branches/network/src/lib/collision_detection/cd_engine.cc	(revision 6636)
+++ branches/network/src/lib/collision_detection/cd_engine.cc	(revision 6636)
@@ -0,0 +1,212 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION
+
+#include "cd_engine.h"
+#include "obb_tree.h"
+#include "debug.h"
+
+#include "model.h"
+#include "world_entity.h"
+#include "terrain.h"
+// #include "player.h"
+
+#include "spatial_separation.h"
+#include "quadtree.h"
+#include "quadtree_node.h"
+
+
+
+using namespace std;
+
+
+/**
+ *  standard constructor
+ */
+CDEngine::CDEngine ()
+{
+  this->setClassID(CL_CD_ENGINE, "CDEngine");
+}
+
+
+/**
+ *  the singleton reference to this class
+ */
+CDEngine* CDEngine::singletonRef = NULL;
+
+
+/**
+ *  standard deconstructor
+ */
+CDEngine::~CDEngine ()
+{
+  CDEngine::singletonRef = NULL;
+}
+
+
+/**
+ *  this is the collision checking function
+
+    there are some speed improvements that can be done here. a rewrite of the list a would be appropriate to
+    be able to enhance iteration speed.
+ */
+//void CDEngine::checkCollisions()
+//{
+//  this->checkCollisionObjects();
+  //this->checkCollisionGround();
+//}
+
+/**
+ *  this checks the collisions with the objects
+ */
+//void CDEngine::checkCollisionObjects()
+//{
+//   BVTree* tree;
+//   tIterator<WorldEntity>* iterator1 = entityList->getIterator();
+//   tIterator<WorldEntity>* iterator2 = entityList->getIterator();
+//   WorldEntity* entity1 = iterator1->firstElement();
+//   WorldEntity* entity2 = iterator2->iteratorElement(iterator1);
+//   PRINTF(3)("checking for collisions\n");
+//   while( entity1 != NULL)
+//   {
+//     if( likely(entity1 != this->terrain))
+//     {
+//       entity2 = iterator2->nextElement();
+//
+//       while( entity2 != NULL)
+//       {
+//         if( likely(entity2 != this->terrain))
+//         {
+//           PRINTF(4)("checking object %s against %s\n", entity1->getName(), entity2->getName());
+//           tree = entity1->getOBBTree();
+//           if( likely(tree != NULL) && entity2->getOBBTree() != NULL) tree->collideWith(entity1, entity2);
+//         }
+//         entity2 = iterator2->nextElement();
+//       }
+//     }
+//     entity1 = iterator1->nextElement();
+//     entity2 = iterator2->iteratorElement(iterator1);
+//     entity2 = iterator2->nextElement();
+//   }
+//   delete iterator1;
+//   delete iterator2;
+//}
+
+void CDEngine::checkCollisions(std::list<WorldEntity*>& list1, std::list<WorldEntity*>& list2)
+{
+  BVTree* tree;
+  std::list<WorldEntity*>::iterator entity1, entity2, pre1, pre2;
+  PRINTF(3)("checking for collisions\n");
+
+  pre1 = list1.begin();
+  while (pre1 != list1.end())
+  {
+    entity1 = pre1++;
+    if( likely((*entity1) != this->terrain))
+    {
+      pre2 = list2.begin();
+      while (pre2 != list2.end())
+      {
+        entity2 = pre2++;
+        if( likely((*entity2) != this->terrain))
+        {
+          PRINTF(4)("checking object %s against %s\n", (*entity1)->getName(), (*entity2)->getName());
+          tree = (*entity1)->getOBBTree();
+          if( likely(tree != NULL) && (*entity2)->getOBBTree() != NULL) tree->collideWith(*entity1, *entity2);
+        }
+      }
+    }
+  }
+}
+
+
+/**
+ *  this checks the collisions with the ground
+ */
+void CDEngine::checkCollisionGround()
+{
+  if( likely( this->terrain != NULL))
+  {
+    Quadtree* q = dynamic_cast<Terrain*>(this->terrain)->ssp->getQuadtree();
+
+//    QuadtreeNode* n = q->getQuadtreeFromPosition(this->player->getAbsCoor());
+  }
+  //sTriangleExt* tri = q->getTriangleFromPosition(this->player->getAbsCoor());
+}
+
+
+/**
+ *  this draws the bounding volume tree
+ * @param depth until which depth to draw the tree
+ * @param drawMode mod which states how to draw it
+ */
+void CDEngine::drawBV(int depth, int drawMode) const
+{
+  /* this would operate on  worldList bases, for testing purposes, we only use one OBBTree */
+  //this->rootTree->drawBV(depth, drawMode);
+  /// FIXME
+/*  tIterator<WorldEntity>* iterator = entityList->getIterator();
+  WorldEntity* entity = iterator->firstElement();
+  while( entity != NULL)
+  {
+    entity->drawBVTree(depth, drawMode);
+    entity = iterator->nextElement();
+  }
+  delete iterator;*/
+}
+
+
+/**
+ * some debug output on the class
+ */
+void CDEngine::debug()
+{
+  PRINT(0)("\n=============================| CDEngine::debug() |===\n");
+  PRINT(0)("=  CDEngine: Spawning Tree Start\n");
+  //this->rootTree->debug();
+  PRINT(0)("=  CDEngine: Spawning Tree: Finished\n");
+  PRINT(0)("=======================================================\n");
+
+}
+
+
+/**
+ * this spawns a tree for debug purposes only
+ */
+void CDEngine::debugSpawnTree(int depth, sVec3D* vertices, int numVertices)
+{
+  if ( this->rootTree == NULL)
+    this->rootTree = new OBBTree();
+  this->rootTree->spawnBVTree(depth, vertices, numVertices);
+}
+
+
+void CDEngine::drawBV(const std::list<WorldEntity*>& drawList ) const
+{
+  std::list<WorldEntity*>::const_iterator entity;
+  for (entity = drawList.begin(); entity != drawList.end(); entity++)
+    if ((*entity)->isVisible())
+      (*entity)->drawBVTree(3, 226);
+}
+
+/**
+ * this draws the debug spawn tree
+ */
+void CDEngine::debugDraw(int depth, int drawMode)
+{
+  if(this-> rootTree != NULL)
+    this->rootTree->drawBV(depth, drawMode);
+}
Index: branches/network/src/lib/collision_detection/cd_engine.h
===================================================================
--- branches/network/src/lib/collision_detection/cd_engine.h	(revision 6636)
+++ branches/network/src/lib/collision_detection/cd_engine.h	(revision 6636)
@@ -0,0 +1,84 @@
+/*!
+ * @file cd_engine.h
+  *  Definition of the collision detection engine
+
+*/
+
+#ifndef _CD_ENGINE_H
+#define _CD_ENGINE_H
+
+#include "base_object.h"
+#include "collision_defs.h"
+#include "model.h"
+
+#include <list>
+
+class WorldEntity;
+class OBBTree;
+class Terrain;
+//class Player;
+
+
+//! featured state options, they are all additive
+typedef enum cdState
+  {
+    CD_DEBUG_DRAW_ALL = 1,
+    CD_DEBUG_DRAW_POLYGONS = 1<<1,
+    CD_DEBUG_DRAW_BLENDED = 1<<2,
+    CD_DEBUG_DRAW_HIT_BV = 1<<3,
+    CD_DEBUG_VERBOSE = 1<<4,
+
+    CD_STORE_VERTICES = 1<<5
+  };
+
+
+//! The class representing the collision detection system of orxonox
+class CDEngine : public BaseObject {
+
+  friend class WorldEntity;
+
+ public:
+  virtual ~CDEngine();
+  /** @returns a Pointer to the only object of this Class */
+  static CDEngine* getInstance() { if (!singletonRef) singletonRef = new CDEngine(); return singletonRef; }
+  void init();
+
+  inline void setState(const int newState) { this->state = newState; }
+  inline const int getState() const { return this->state; }
+  inline void enable(const int options) { this->state |= options; }
+  inline void disable(const int options) { int temp = this->state & options; this->state ^= temp; }
+
+  inline void setTerrain(Terrain* terrain) { this->terrain = terrain; }
+  //  inline void setPlayer(Player* player) { this->player = player; } /* only for debug purposes \todo: delete*/
+
+  void drawBV(int depth, int drawMode) const;
+
+//  void checkCollisions();
+  void checkCollisions(std::list<WorldEntity*>& list1, std::list<WorldEntity*>& list2);
+
+  void drawBV(const std::list<WorldEntity*>& drawList ) const;
+  void debug();
+
+
+ private:
+  CDEngine();
+  static CDEngine* singletonRef;
+
+  void spawnBVTree(int depth = MAX_BV_TREE_DEPTH);
+
+  void checkCollisionObjects();
+  void checkCollisionGround();
+
+  void debugSpawnTree(int depth, sVec3D* vertices, int numVertices);
+  void debugDraw(int depth, int drawMode);
+
+
+ private:
+  int                     state;                            //!< the current state of the cd engine
+  OBBTree*                rootTree;                         //!< for testing purposes a root tree
+
+  Terrain*                terrain;                          //!< this it a ref to the terrain, serving as a ground for all WE
+//  Player*                 player;
+};
+
+#endif /* _CD_ENGINE_H */
Index: branches/network/src/lib/collision_detection/collision.cc
===================================================================
--- branches/network/src/lib/collision_detection/collision.cc	(revision 6636)
+++ branches/network/src/lib/collision_detection/collision.cc	(revision 6636)
@@ -0,0 +1,40 @@
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION
+
+#include "collision.h"
+
+using namespace std;
+
+
+/**
+ *  standard constructor
+*/
+Collision::Collision () 
+{
+   this->setClassID(CL_COLLISION, "Collision"); 
+
+}
+
+
+/**
+ *  standard deconstructor
+
+*/
+Collision::~Collision () 
+{
+  // delete what has to be deleted here
+}
Index: branches/network/src/lib/collision_detection/collision.h
===================================================================
--- branches/network/src/lib/collision_detection/collision.h	(revision 6636)
+++ branches/network/src/lib/collision_detection/collision.h	(revision 6636)
@@ -0,0 +1,30 @@
+/*! 
+ * @file collision.h
+  *  Definition of a collision event
+
+*/
+
+#ifndef _COLLISION_H
+#define _COLLISION_H
+
+#include "base_object.h"
+#include "vector.h"
+
+
+class WorldEntity;
+class BoundingVolume;
+
+//! A class representing a simple collision
+class Collision : public BaseObject {
+
+ public:
+  Collision();
+  virtual ~Collision();
+
+ public:
+  Vector            pointOfImpact;              //!< point of impact, approximated via bounding volumes
+  WorldEntity*      body;                       //!< the collision body
+  BoundingVolume*   boundingVolume;             //!< reference to the bounding volume that fired the collision
+};
+
+#endif /* _COLLISION_H */
Index: branches/network/src/lib/collision_detection/collision_defs.h
===================================================================
--- branches/network/src/lib/collision_detection/collision_defs.h	(revision 6636)
+++ branches/network/src/lib/collision_detection/collision_defs.h	(revision 6636)
@@ -0,0 +1,23 @@
+/*! 
+ * @file collision_defs.h
+  *  Definition of some global collision data
+
+*/
+
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define MAX_BV_TREE_DEPTH 10
+#define MIN_VERT_PER_BV 3
Index: branches/network/src/lib/collision_detection/obb.cc
===================================================================
--- branches/network/src/lib/collision_detection/obb.cc	(revision 6636)
+++ branches/network/src/lib/collision_detection/obb.cc	(revision 6636)
@@ -0,0 +1,55 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION
+
+#include "obb.h"
+#include "vector.h"
+
+using namespace std;
+
+
+/**
+ *  standard constructor
+*/
+OBB::OBB ()
+{
+   this->setClassID(CL_OBB, "OBB");
+   this->axis = new Vector[3];
+   this->halfLength = new float[3];
+   this->bCollided = false;
+}
+
+
+/**
+ *  standard deconstructor
+
+*/
+OBB::~OBB ()
+{
+  delete [] this->axis;
+  delete [] this->halfLength;
+}
+
+
+
+void OBB::mergeWith(const BoundingVolume &bv)
+{}
+
+
+void OBB::drawBV(int currentDepth, int drawMode) const
+{}
+
+
Index: branches/network/src/lib/collision_detection/obb.h
===================================================================
--- branches/network/src/lib/collision_detection/obb.h	(revision 6636)
+++ branches/network/src/lib/collision_detection/obb.h	(revision 6636)
@@ -0,0 +1,41 @@
+/*!
+ * @file obb.h
+  *  Definition of an OBB (object Oriented Bounding Box)
+
+*/
+
+#ifndef _OBB_H
+#define _OBB_H
+
+#include "base_object.h"
+#include "bounding_volume.h"
+
+template<class T> class tList;
+
+//! A class representing an extended bounding volume tree: an obb tree
+class OBB : public BoundingVolume {
+
+ public:
+  OBB();
+  virtual ~OBB();
+
+
+  inline Vector* getAxis () const { return this->axis; }
+  inline const float* getHalfLength() const { return this->halfLength; }
+
+  virtual void mergeWith(const BoundingVolume &bv);
+
+  virtual void drawBV(int currentDepth, int drawMode) const;
+
+
+
+ public:
+  Vector*          axis;                       //!< Axes of oriented box [x,y,z]
+  float*           halfLength;                 //!< Half lengths of the box along the axis
+  float            covarianceMatrix[3][3];     //!< the covariance matrix
+
+  bool             bCollided;                  //!< is true if this obb has collided
+
+};
+
+#endif /* _OBB_H */
Index: branches/network/src/lib/collision_detection/obb_tree.cc
===================================================================
--- branches/network/src/lib/collision_detection/obb_tree.cc	(revision 6636)
+++ branches/network/src/lib/collision_detection/obb_tree.cc	(revision 6636)
@@ -0,0 +1,160 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION
+
+#include "obb_tree.h"
+#include "obb_tree_node.h"
+#include "obb.h"
+#include "debug.h"
+#include "compiler.h"
+#include "material.h"
+#include "world_entity.h"
+#include "p_node.h"
+
+using namespace std;
+
+
+/**
+ *  standard constructor
+*/
+OBBTree::OBBTree ()
+{
+  this->init();
+}
+
+OBBTree::OBBTree(int depth, sVec3D *verticesList, const int length)
+{
+  this->init();
+  this->spawnBVTree(depth, verticesList, length);
+}
+
+OBBTree::OBBTree(int depth, const modelInfo& modInfo)
+{
+  this->init();
+  this->spawnBVTree(depth, modInfo);
+}
+
+
+
+void OBBTree::init()
+{
+  this->setClassID(CL_OBB_TREE, "OBBTree");
+
+  this->rootNode = NULL;
+
+  this->id = 0;
+}
+
+/**
+ *  standard deconstructor
+
+*/
+OBBTree::~OBBTree ()
+{
+  delete this->rootNode;
+}
+
+
+void OBBTree::spawnBVTree(int depth, sVec3D *verticesList, const int length)
+{
+  if( unlikely(this->rootNode != NULL))
+    {
+      PRINTF(2)("The BVTree has already been spawned, flushing and respawning again...\n");
+      this->flushTree();
+    }
+  OBBTreeNode* node = new OBBTreeNode();
+  this->rootNode = node;
+  this->rootNode->setTreeRef(this);
+  this->rootNode->spawnBVTree(--depth, verticesList, length);
+}
+
+
+void OBBTree::spawnBVTree(int depth, const modelInfo& modInfo)
+{
+  if( unlikely(this->rootNode != NULL))
+  {
+    PRINTF(2)("The BVTree has already been spawned, flushing and respawning again...\n");
+    this->flushTree();
+  }
+  OBBTreeNode* node = new OBBTreeNode();
+  this->rootNode = node;
+  this->rootNode->setTreeRef(this);
+  this->rootNode->spawnBVTree(--depth, modInfo);
+}
+
+
+void OBBTree:: flushTree()
+{}
+
+
+void OBBTree::collideWith(WorldEntity* entity1, WorldEntity* entity2)
+{
+  if( likely(entity2->getOBBTree() != NULL) )
+    this->rootNode->collideWith(((OBBTree*)entity2->getOBBTree())->getRootNode(), entity1, entity2);
+}
+
+
+/**
+ * this collides two bvtrees together. the trees are attached to pnodes Objects A and B
+ * @param tree: the other tree to collide with (Object B)
+ * @param nodeA: PNode of object A
+ * @param nodeB: Pnode of object B
+ */
+void OBBTree::collideWith(BVTree* tree, WorldEntity* nodeA, WorldEntity* nodeB)
+{
+  this->rootNode->collideWith(((OBBTree*)tree)->getRootNode(), nodeA, nodeB);
+}
+
+
+void OBBTree::drawBV(int depth, int drawMode) const
+{
+  if( likely(this->rootNode != NULL))
+  {
+    this->rootNode->drawBV(depth, drawMode);
+  }
+}
+
+
+
+void OBBTree::debug()
+{
+  PRINT(0)("\n==============================| OBBTree::debug() |===\n");
+  PRINT(0)("=  Spawning Tree: Start\n");
+
+  /* generate some test vertices */
+  int const length = 9;
+  sVec3D* vertList = new sVec3D[length];
+//   sVec3D data[length]  = {{0.0, 0.0, 0.0},{1.0, 2.0, 5.0},{0.0, 6.0, 9.0},
+//                           {1.0, 4.0, 12.0}, {1.0, 2.0, 16.0}, {0.0, 0.0, 19.0},
+//                           {0.0, 3.0, 23.0}, {1.0, 5.0, 30.0}, {0.0, 10.0, 35.0}};
+
+  sVec3D data[length]  = {{0.0, 0.0, 0.0},{1.0, 2.0, 5.0},{1.0, 5.0, 30.0},
+                          {0.0, 3.0, 23.0}, {0.0, 6.0, 9.0}, {0.0, 10.0, 35.0},
+                          {1.0, 4.0, 12.0}, {1.0, 2.0, 16.0}, {0.0, 0.0, 19.0}};
+
+  for(int i = 0; i < length; ++i)
+    {
+      vertList[i][0] = data[i][0];
+      vertList[i][1] = data[i][1];
+      vertList[i][2] = data[i][2];
+    }
+
+  this->spawnBVTree(3, vertList, length);
+
+  PRINT(0)("=  Spawning Tree: Finished\n");
+  PRINT(0)("=======================================================\n");
+
+}
Index: branches/network/src/lib/collision_detection/obb_tree.h
===================================================================
--- branches/network/src/lib/collision_detection/obb_tree.h	(revision 6636)
+++ branches/network/src/lib/collision_detection/obb_tree.h	(revision 6636)
@@ -0,0 +1,47 @@
+/*!
+ * @file obb_tree.h
+  *  Definition of an obb tree (object oriented Bounding Box)
+
+*/
+
+#ifndef _OBB_TREE_H
+#define _OBB_TREE_H
+
+#include "bv_tree.h"
+#include "model.h"
+#include "material.h"
+
+class Material;
+class OBBTreeNode;
+class PNode;
+
+//! A class for representing an obb tree
+class OBBTree : public BVTree {
+
+  public:
+    OBBTree();
+    OBBTree(int depth, sVec3D *verticesList, const int length);
+    OBBTree(int depth, const modelInfo& modInfo);
+    virtual ~OBBTree();
+    void init();
+
+    virtual void spawnBVTree(int depth, sVec3D *verticesList, const int length);
+    virtual void spawnBVTree(int depth, const modelInfo& modInfo);
+    virtual void flushTree();
+
+    virtual void collideWith(BVTree* tree, WorldEntity* nodeA, WorldEntity* nodeB);
+    virtual void collideWith(WorldEntity* entity1, WorldEntity* entity2);
+
+    virtual void drawBV(int depth, int drawMode) const;
+
+    int getID() { return ++this->id;}
+    inline OBBTreeNode* getRootNode() { return this->rootNode; }
+
+    void debug();
+
+  private:
+    OBBTreeNode*         rootNode;                        //!< reference to the root node of the tree
+    int                  id;
+};
+
+#endif /* _OBB_TREE_H */
Index: branches/network/src/lib/collision_detection/obb_tree_node.cc
===================================================================
--- branches/network/src/lib/collision_detection/obb_tree_node.cc	(revision 6636)
+++ branches/network/src/lib/collision_detection/obb_tree_node.cc	(revision 6636)
@@ -0,0 +1,1136 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_COLLISION
+
+#include "obb_tree_node.h"
+#include "list.h"
+#include "obb.h"
+#include "obb_tree.h"
+#include "matrix.h"
+#include "model.h"
+#include "world_entity.h"
+#include "plane.h"
+
+#include "color.h"
+
+#include "debug.h"
+#include "glincl.h"
+
+
+
+using namespace std;
+
+OBBTree*  OBBTreeNode::obbTree = NULL;
+
+float**  OBBTreeNode::coMat = NULL;
+float**  OBBTreeNode::eigvMat = NULL;
+float*   OBBTreeNode::eigvlMat = NULL;
+int*     OBBTreeNode::rotCount = NULL;
+GLUquadricObj* OBBTreeNode_sphereObj = NULL;
+
+/**
+ *  standard constructor
+ */
+OBBTreeNode::OBBTreeNode ()
+{
+  this->setClassID(CL_OBB_TREE_NODE, "OBBTreeNode");
+  this->nodeLeft = NULL;
+  this->nodeRight = NULL;
+  this->bvElement = NULL;
+
+  if( OBBTreeNode::coMat == NULL)
+  {
+    OBBTreeNode::coMat = new float*[4];
+    for(int i = 0; i < 4; i++)
+      OBBTreeNode::coMat[i] = new float[4];
+  }
+  if( OBBTreeNode::eigvMat == NULL)
+  {
+    OBBTreeNode::eigvMat = new float*[4];
+    for( int i = 0; i < 4; i++)
+      OBBTreeNode::eigvMat[i] = new float[4];
+  }
+  if( OBBTreeNode::eigvlMat == NULL)
+  {
+    OBBTreeNode::eigvlMat = new float[4];
+  }
+  if( OBBTreeNode::rotCount == NULL)
+    OBBTreeNode::rotCount = new int;
+
+  if( OBBTreeNode_sphereObj == NULL)
+    OBBTreeNode_sphereObj = gluNewQuadric();
+}
+
+
+/**
+ *  standard deconstructor
+ */
+OBBTreeNode::~OBBTreeNode ()
+{
+  if( this->nodeLeft)
+  {
+    delete this->nodeLeft;
+    this->nodeLeft = NULL;
+  }
+  if( this->nodeRight)
+  {
+    delete this->nodeRight;
+    this->nodeRight = NULL;
+  }
+  if( this->bvElement)
+    delete this->bvElement;
+  this->bvElement = NULL;
+}
+
+
+/**
+ *  creates a new BVTree or BVTree partition
+ * @param depth: how much more depth-steps to go: if == 1 don't go any deeper!
+ * @param modInfo: model informations from the abstrac model
+ *
+ * this function creates the Bounding Volume tree from a modelInfo struct and bases its calculations
+ * on the triangle informations (triangle soup not polygon soup)
+ */
+void OBBTreeNode::spawnBVTree(const int depth, const modelInfo& modInfo)
+{
+  int length = 0;
+  sVec3D* verticesList;
+
+  PRINT(3)("\n");
+  this->treeIndex = this->obbTree->getID();
+  PRINTF(3)("OBB Depth: %i, tree index: %i, numVertices: %i\n", depth, treeIndex, length);
+  this->depth = depth;
+
+
+  this->bvElement = new OBB();
+  this->bvElement->vertices = verticesList;
+  this->bvElement->numOfVertices = length;
+  PRINTF(3)("Created OBBox\n");
+  this->calculateBoxCovariance(this->bvElement, modInfo);
+  PRINTF(3)("Calculated attributes1\n");
+  this->calculateBoxEigenvectors(this->bvElement, modInfo);
+  PRINTF(3)("Calculated attributes2\n");
+  this->calculateBoxAxis(this->bvElement,modInfo);
+  PRINTF(3)("Calculated attributes3\n");
+
+  /* if this is the first node, the vertices data are the original ones of the model itself, so dont delete them in cleanup */
+  if( this->treeIndex == 1)
+    this->bvElement->bOrigVertices = true;
+
+  if( likely( this->depth > 0))
+  {
+    this->forkBox(this->bvElement);
+
+
+//     if(this->tmpLen1 > 2)
+//     {
+//       OBBTreeNode* node1 = new OBBTreeNode();
+//       this->nodeLeft = node1;
+//       this->nodeLeft->spawnBVTree(depth - 1, this->tmpVert1, this->tmpLen1);
+//     }
+//     else
+//     {
+//       PRINTF(3)("Aboarding tree walk: less than 3 vertices left\n");
+//     }
+//
+//     if( this->tmpLen2 > 2)
+//     {
+//       OBBTreeNode* node2 = new OBBTreeNode();
+//       this->nodeRight = node2;
+//       this->nodeRight->spawnBVTree(depth - 1, this->tmpVert2, this->tmpLen2);
+//     }
+//     else
+//     {
+//       PRINTF(3)("Abording tree walk: less than 3 vertices left\n");
+//     }
+
+  }
+}
+
+
+/**
+ *  creates a new BVTree or BVTree partition
+ * @param depth: how much more depth-steps to go: if == 1 don't go any deeper!
+ * @param verticesList: the list of vertices of the object - each vertices triple is interpreted as a triangle
+ *
+ * this function creates an Bounding Volume tree from a vertices soup (no triangle data)
+ */
+void OBBTreeNode::spawnBVTree(const int depth, const sVec3D *verticesList, unsigned int length)
+{
+  PRINT(3)("\n");
+  this->treeIndex = this->obbTree->getID();
+  PRINTF(3)("OBB Depth: %i, tree index: %i, numVertices: %i\n", depth, treeIndex, length);
+  this->depth = depth;
+
+
+  this->bvElement = new OBB();
+  this->bvElement->vertices = verticesList;
+  this->bvElement->numOfVertices = length;
+  PRINTF(3)("Created OBBox\n");
+  this->calculateBoxCovariance(this->bvElement, verticesList, length);
+  PRINTF(3)("Calculated attributes1\n");
+  this->calculateBoxEigenvectors(this->bvElement, verticesList, length);
+  PRINTF(3)("Calculated attributes2\n");
+  this->calculateBoxAxis(this->bvElement, verticesList, length);
+  PRINTF(3)("Calculated attributes3\n");
+
+  /* if this is the first node, the vertices data are the original ones of the model itself, so dont delete them in cleanup */
+  if( this->treeIndex == 1)
+    this->bvElement->bOrigVertices = true;
+
+  if( likely( this->depth > 0))
+  {
+    this->forkBox(this->bvElement);
+
+
+    if(this->tmpLen1 > 2)
+    {
+      OBBTreeNode* node1 = new OBBTreeNode();
+      this->nodeLeft = node1;
+      this->nodeLeft->spawnBVTree(depth - 1, this->tmpVert1, this->tmpLen1);
+    }
+    else
+    {
+      PRINTF(3)("Aboarding tree walk: less than 3 vertices left\n");
+    }
+
+    if( this->tmpLen2 > 2)
+    {
+      OBBTreeNode* node2 = new OBBTreeNode();
+      this->nodeRight = node2;
+      this->nodeRight->spawnBVTree(depth - 1, this->tmpVert2, this->tmpLen2);
+    }
+    else
+    {
+      PRINTF(3)("Abording tree walk: less than 3 vertices left\n");
+    }
+  }
+}
+
+
+void OBBTreeNode::calculateBoxCovariance(OBB* box, const modelInfo& modInfo)
+{}
+
+
+void OBBTreeNode::calculateBoxCovariance(OBB* box, const sVec3D* verticesList, unsigned int length)
+{
+  float     facelet[length];                         //!< surface area of the i'th triangle of the convex hull
+  float     face = 0.0f;                             //!< surface area of the entire convex hull
+  Vector    centroid[length];                        //!< centroid of the i'th convex hull
+  Vector    center;                                  //!< the center of the entire hull
+  Vector    p, q, r;                                 //!< holder of the polygon data, much more conveniant to work with Vector than sVec3d
+  Vector    t1, t2;                                  //!< temporary values
+  float     covariance[3][3] = {0,0,0, 0,0,0, 0,0,0};//!< the covariance matrix
+  int       mode = 0;                                //!< mode = 0: vertex soup, no connections, mode = 1: 3 following verteces build a triangle
+
+  this->numOfVertices = length;
+  this->vertices = verticesList;
+
+
+  if( likely(mode == 0))
+  {
+    /* fist compute all the convex hull face/facelets and centroids */
+    for( int i = 0; i+3 < length ; i+=3)          /* FIX-ME-QUICK: hops of 3, array indiscontinuity*/
+    {
+      p = verticesList[i];
+      q = verticesList[i + 1];
+      r = verticesList[i + 2];
+
+      t1 = p - q; t2 = p - r;
+
+      /* finding the facelet surface via cross-product */
+      facelet[i] = 0.5f * fabs( t1.cross(t2).len() );
+      /* update the entire convex hull surface */
+      face += facelet[i];
+
+      /* calculate the cetroid of the hull triangles */
+      centroid[i] = (p + q + r) * 1/3;
+      /* now calculate the centroid of the entire convex hull, weighted average of triangle centroids */
+      center += centroid[i] * facelet[i];
+    }
+    /* take the average of the centroid sum */
+    center /= face;
+    PRINTF(3)("-- Calculated Center\n");
+
+
+    /* now calculate the covariance matrix - if not written in three for-loops, it would compute faster: minor */
+    for( int j = 0; j < 3; ++j)
+    {
+      for( int k = 0; k < 3; ++k)
+      {
+        for( int i = 0; i + 3 < length; i+=3)
+        {
+          p = verticesList[i];
+          q = verticesList[i + 1];
+          r = verticesList[i + 2];
+
+          covariance[j][k] = facelet[i] / (12.0f * face) * (9.0f * centroid[i][j] * centroid[i][k] + p[j] * p[k] +
+              q[j] * q[k] + r[j] * r[k]) - center[j] * center[k];
+        }
+      }
+    }
+    PRINTF(3)("-- Calculated Covariance\n");
+  }
+  else if( mode == 1)
+  {
+    for( int i = 0; i + 3 < length; i+=3)          /* FIX-ME-QUICK: hops of 3, array indiscontinuity*/
+    {
+      p = verticesList[i];
+      q = verticesList[i + 1];
+      r = verticesList[i + 2];
+
+      centroid[i] = (p + q + r) / 3.0f;
+      center += centroid[i];
+    }
+    center /= length;
+
+    for( int j = 0; j < 3; ++j)
+    {
+      for( int k = 0; k < 3; ++k)
+      {
+        for( int i = 0; i + 3 < length; i+=3)
+        {
+          p = verticesList[i];
+          q = verticesList[i +1];
+          r = verticesList[i + 2];
+
+          covariance[j][k] = p[j] * p[k] + q[j] * q[k] + r[j] + r[k];
+        }
+        covariance[j][k] /= (3.0f * length);
+      }
+    }
+    PRINTF(3)("-- Calculated Covariance\n");
+  }
+  else if( mode == 2)
+  {
+    /* fist compute all the convex hull face/facelets and centroids */
+    for(int i = 0; i + 3 < length; i+=3)          /* FIX-ME-QUICK: hops of 3, array indiscontinuity*/
+    {
+      p = verticesList[i];
+      q = verticesList[i + 1];
+      r = verticesList[i + 2];
+
+      t1 = p - q; t2 = p - r;
+
+      /* finding the facelet surface via cross-product */
+      facelet[i] = 0.5f * fabs( t1.cross(t2).len() );
+      /* update the entire convex hull surface */
+      face += facelet[i];
+
+      /* calculate the cetroid of the hull triangles */
+      centroid[i] = (p + q + r) * 1/3;
+      /* now calculate the centroid of the entire convex hull, weighted average of triangle centroids */
+      center += centroid[i] * facelet[i];
+    }
+    /* take the average of the centroid sum */
+    center /= face;
+    PRINTF(3)("-- Calculated Center\n");
+
+    for( int j = 0; j < 3; ++j)
+    {
+      for( int k = 0; k < 3; ++k)
+      {
+        for( int i = 0; i + 3 < length; i+=3)
+        {
+          p = verticesList[i];
+          q = verticesList[i +1];
+          r = verticesList[i + 2];
+
+          covariance[j][k] = p[j] * p[k] + q[j] * q[k] + r[j] + r[k];
+        }
+        covariance[j][k] /= (3.0f * length);
+      }
+    }
+    PRINTF(3)("-- Calculated Covariance\n");
+  }
+  else
+  {
+    for( int i = 0; i < length; ++i)          /* FIX-ME-QUICK: hops of 3, array indiscontinuity*/
+    {
+      center += verticesList[i];
+    }
+    center /= length;
+
+    for( int j = 0; j < 3; ++j)
+    {
+      for( int k = 0; k < 3; ++k)
+      {
+        for( int i = 0; i + 3 < length; i+=3)
+        {
+          p = verticesList[i];
+          q = verticesList[i +1];
+          r = verticesList[i + 2];
+
+          covariance[j][k] = p[j] * p[k] + q[j] * q[k] + r[j] + r[k];
+        }
+        covariance[j][k] /= (3.0f * length);
+      }
+    }
+    PRINTF(3)("-- Calculated Covariance\n");
+  }
+
+  PRINTF(3)("\nVertex Data:\n");
+  for(int i = 0; i < length; i++)
+  {
+    PRINTF(3)("vertex %i: %f, %f, %f\n", i, box->vertices[i][0], box->vertices[i][1], box->vertices[i][2]);
+  }
+
+
+  PRINTF(3)("\nCovariance Matrix:\n");
+  for(int j = 0; j < 3; ++j)
+  {
+    PRINT(3)(" |");
+    for(int k = 0; k < 3; ++k)
+    {
+      PRINT(3)(" \b%f ", covariance[j][k]);
+    }
+    PRINT(3)(" |\n");
+  }
+
+  PRINTF(3)("center: %f, %f, %f\n", center.x, center.y, center.z);
+
+
+  for(int i = 0; i < 3; ++i)
+  {
+    box->covarianceMatrix[i][0] = covariance[i][0];
+    box->covarianceMatrix[i][1] = covariance[i][1];
+    box->covarianceMatrix[i][2] = covariance[i][2];
+  }
+  *box->center = center;
+  PRINTF(3)("-- Written Result to obb\n");
+}
+
+
+void OBBTreeNode::calculateBoxEigenvectors(OBB* box, const modelInfo& modInfo)
+{}
+
+void OBBTreeNode::calculateBoxEigenvectors(OBB* box, const sVec3D* verticesList, unsigned int length)
+{
+
+  /* now getting spanning vectors of the sub-space:
+  the eigenvectors of a symmertric matrix, such as the
+  covarience matrix are mutually orthogonal.
+  after normalizing them, they can be used as a the basis
+  vectors
+  */
+  Vector*              axis = new Vector[3];                //!< the references to the obb axis
+
+  Matrix covMat(  box->covarianceMatrix  );
+  covMat.getEigenVectors(axis[0], axis[1], axis[2] );
+
+
+  /* new jacobi tests */
+//  JacobI(OBBTreeNode::coMat, OBBTreeNode::eigvlMat, OBBTreeNode::eigvMat, OBBTreeNode::rotCount);
+//  PRINTF(3)("-- Done Jacobi Decomposition\n");
+
+
+//   PRINTF(0)("Jacobi\n");
+//   for(int j = 0; j < 3; ++j)
+//   {
+//     printf(" |");
+//     for(int k = 0; k < 3; ++k)
+//     {
+//       printf(" \t%f ", OBBTreeNode::OBBTreeNode::eigvMat[j][k]);
+//     }
+//     printf(" |\n");
+//   }
+
+/*  axis[0].x = OBBTreeNode::eigvMat[0][0]; axis[0].y = OBBTreeNode::eigvMat[1][0]; axis[0].z = OBBTreeNode::eigvMat[2][0];
+  axis[1].x = OBBTreeNode::eigvMat[0][1]; axis[1].y = OBBTreeNode::eigvMat[1][1]; axis[1].z = OBBTreeNode::eigvMat[2][1];
+  axis[2].x = OBBTreeNode::eigvMat[0][2]; axis[2].y = OBBTreeNode::eigvMat[1][2]; axis[2].z = OBBTreeNode::eigvMat[2][2];
+  axis[0].normalize();
+  axis[1].normalize();
+  axis[2].normalize();*/
+  box->axis = axis;
+
+//   PRINTF(0)("-- Got Axis\n");
+//
+//   PRINTF(0)("eigenvector: %f, %f, %f\n", box->axis[0].x, box->axis[0].y, box->axis[0].z);
+//   PRINTF(0)("eigenvector: %f, %f, %f\n", box->axis[1].x, box->axis[1].y, box->axis[1].z);
+//   PRINTF(0)("eigenvector: %f, %f, %f\n", box->axis[2].x, box->axis[2].y, box->axis[2].z);
+}
+
+
+void OBBTreeNode::calculateBoxAxis(OBB* box, const modelInfo& modInfo)
+{
+  this->calculateBoxAxis(box, (const sVec3D*)modInfo.pVertices, modInfo.numVertices);
+}
+
+
+
+void OBBTreeNode::calculateBoxAxis(OBB* box, const sVec3D* verticesList, unsigned int length)
+{
+
+  /* now get the axis length */
+  Line                ax[3];                                 //!< the axis
+  float*              halfLength = new float[3];             //!< half length of the axis
+  float               tmpLength;                             //!< tmp save point for the length
+  Plane               p0(box->axis[0], *box->center);       //!< the axis planes
+  Plane               p1(box->axis[1], *box->center);
+  Plane               p2(box->axis[2], *box->center);
+  float               maxLength[3];
+  float               minLength[3];
+
+
+  /* get a bad bounding box */
+  halfLength[0] = -1.0f;
+  for(int j = 0; j < length; ++j)
+    {
+      tmpLength = fabs(p0.distancePoint(vertices[j]));
+      if( tmpLength > halfLength[0])
+        halfLength[0] = tmpLength;
+    }
+
+  halfLength[1] = -1.0f;
+  for(int j = 0; j < length; ++j)
+    {
+      tmpLength = fabs(p1.distancePoint(vertices[j]));
+      if( tmpLength > halfLength[1])
+        halfLength[1] = tmpLength;
+    }
+
+  halfLength[2] = -1.0f;
+  for(int j = 0; j < length; ++j)
+    {
+      tmpLength = fabs(p2.distancePoint(vertices[j]));
+      if( tmpLength > halfLength[2])
+        halfLength[2] = tmpLength;
+    }
+
+
+
+  /* get the maximal dimensions of the body in all directions */
+    maxLength[0] = p0.distancePoint(vertices[0]);
+    minLength[0] = p0.distancePoint(vertices[0]);
+   for(int j = 0; j < length; ++j)
+   {
+     tmpLength = p0.distancePoint(vertices[j]);
+     if( tmpLength > maxLength[0])
+       maxLength[0] = tmpLength;
+     else if( tmpLength < minLength[0])
+       minLength[0] = tmpLength;
+   }
+
+   maxLength[1] = p1.distancePoint(vertices[0]);
+   minLength[1] = p1.distancePoint(vertices[0]);
+   for(int j = 0; j < length; ++j)
+   {
+     tmpLength = p1.distancePoint(vertices[j]);
+     if( tmpLength > maxLength[1])
+       maxLength[1] = tmpLength;
+     else if( tmpLength < minLength[1])
+       minLength[1] = tmpLength;
+   }
+
+   maxLength[2] = p2.distancePoint(vertices[0]);
+   minLength[2] = p2.distancePoint(vertices[0]);
+   for(int j = 0; j < length; ++j)
+   {
+     tmpLength = p2.distancePoint(vertices[j]);
+     if( tmpLength > maxLength[2])
+       maxLength[2] = tmpLength;
+     else if( tmpLength < minLength[2])
+       minLength[2] = tmpLength;
+   }
+
+
+   /* calculate the real centre of the body by using the axis length */
+   float centerOffset[3];
+   float newHalfLength[3];
+   for(int i = 0; i < 3; ++i)
+     {
+       PRINTF(3)("max: %f, min: %f \n", maxLength[i], minLength[i]);
+       centerOffset[i] = (maxLength[i] + minLength[i]) / 2.0f;       // min length is negatie
+       newHalfLength[i] = (maxLength[i] - minLength[i]) / 2.0f;      // min length is negative
+       *box->center +=  (box->axis[i] * centerOffset[i]);            // update the new center vector
+       halfLength[i] = newHalfLength[i];
+     }
+
+
+
+  box->halfLength = halfLength;
+  PRINTF(3)("-- Written Axis to obb\n");
+  PRINTF(3)("-- Finished Calculating Attributes\n");
+}
+
+
+
+/**
+  \brief this separates an ob-box in the middle
+* @param box: the box to separate
+
+  this will separate the box into to smaller boxes. the separation is done along the middle of the longest axis
+ */
+void OBBTreeNode::forkBox(OBB* box)
+{
+  /* get the longest axis of the box */
+  float               aLength = -1.0f;                     //!< the length of the longest axis
+  int                 axisIndex = 0;                       //!< this is the nr of the longest axis
+
+  for(int i = 0; i < 3; ++i)
+  {
+    if( aLength < box->halfLength[i])
+    {
+      aLength = box->halfLength[i];
+      axisIndex = i;
+    }
+  }
+
+   PRINTF(3)("longest axis is: nr %i with a half-length of: %f\n", axisIndex, aLength);
+
+
+  /* get the closest vertex near the center */
+  float               dist = 999999.0f;                    //!< the smallest distance to each vertex
+  float               tmpDist;                             //!< temporary distance
+  int                 vertexIndex;
+  Plane               middlePlane(box->axis[axisIndex], *box->center); //!< the middle plane
+
+  vertexIndex = 0;
+  for(int i = 0; i < box->numOfVertices; ++i)
+  {
+    tmpDist = fabs(middlePlane.distancePoint(box->vertices[i]));
+    if( tmpDist < dist)
+    {
+      dist = tmpDist;
+      vertexIndex = i;
+    }
+  }
+
+  PRINTF(3)("\nthe clostest vertex is nr: %i, with a dist of: %f\n", vertexIndex ,dist);
+
+
+  /* now definin the separation plane through this specified nearest point and partition
+  the points depending on which side they are located
+  */
+  tList<const sVec3D>      partition1;                           //!< the vertex partition 1
+  tList<const sVec3D>      partition2;                           //!< the vertex partition 2
+
+
+  PRINTF(3)("vertex index: %i, of %i\n", vertexIndex, box->numOfVertices);
+  this->separationPlane = new Plane(box->axis[axisIndex], box->vertices[vertexIndex]);  //!< separation plane
+  this->sepPlaneCenter = &box->vertices[vertexIndex];
+  this->longestAxisIndex = axisIndex;
+
+  for(int i = 0; i < box->numOfVertices; ++i)
+  {
+    if( i == vertexIndex) continue;
+    tmpDist = this->separationPlane->distancePoint(box->vertices[i]);
+    if( tmpDist > 0.0)
+      partition1.add(&box->vertices[i]); /* positive numbers plus zero */
+    else
+      partition2.add(&box->vertices[i]); /* negatice numbers */
+  }
+  partition1.add(&box->vertices[vertexIndex]);
+  partition2.add(&box->vertices[vertexIndex]);
+
+  PRINTF(3)("\npartition1: got %i vertices/ partition 2: got %i vertices\n", partition1.getSize(), partition2.getSize());
+
+
+  /* now comes the separation into two different sVec3D arrays */
+  tIterator<const sVec3D>* iterator;                       //!< the iterator to go through the lists
+  const sVec3D*      element;                              //!< the elements
+  int                index;                                //!< index storage place
+  sVec3D*            vertList1;                            //!< the vertex list 1
+  sVec3D*            vertList2;                            //!< the vertex list 2
+
+  vertList1 = new sVec3D[partition1.getSize()];
+  vertList2 = new sVec3D[partition2.getSize()];
+
+  iterator = partition1.getIterator();
+  element = iterator->firstElement();
+  index = 0;
+  while( element != NULL)
+  {
+    vertList1[index][0] = element[0][0];
+    vertList1[index][1] = element[0][1];
+    vertList1[index][2] = element[0][2];
+    ++index;
+    element = iterator->nextElement();
+  }
+
+//   PRINTF(0)("\npartition 1:\n");
+//   for(int i = 0; i < partition1.getSize(); ++i)
+//   {
+//     PRINTF(0)("v[%i][0] = %f,\tv[%i][1] = %f,\tv[%i][1] = %f\n", i, vertList1[i][0], i, vertList1[i][1], i, vertList1[i][2]);
+//   }
+
+  iterator = partition2.getIterator();
+  element = iterator->firstElement();
+  index = 0;
+  while( element != NULL)
+  {
+    vertList2[index][0] = element[0][0];
+    vertList2[index][1] = element[0][1];
+    vertList2[index][2] = element[0][2];
+    ++index;
+    element = iterator->nextElement();
+  }
+
+  this->tmpVert1 = vertList1;
+  this->tmpVert2 = vertList2;
+  this->tmpLen1 = partition1.getSize();
+  this->tmpLen2 = partition2.getSize();
+
+  delete iterator;
+
+//   PRINTF(0)("\npartition 2:\n");
+//   for(int i = 0; i < partition2.getSize(); ++i)
+//   {
+//     PRINTF(0)("v[%i][0] = %f,\tv[%i][1] = %f,\tv[%i][1] = %f\n", i, vertList2[i][0], i,  vertList2[i][1], i, vertList2[i][2]);
+//   }
+}
+
+
+
+
+void OBBTreeNode::collideWith(BVTreeNode* treeNode, WorldEntity* nodeA, WorldEntity* nodeB)
+{
+  PRINTF(3)("collideWith\n");
+  /* if the obb overlap, make subtests: check which node is realy overlaping  */
+  PRINT(3)("Checking OBB %i vs %i: ", this->getIndex(), treeNode->getIndex());
+  if( unlikely(treeNode == NULL)) return;
+
+  if( this->overlapTest(this->bvElement, ((OBBTreeNode*)treeNode)->bvElement, nodeA, nodeB))
+  {
+    PRINTF(3)("collision @ lvl %i, object %s vs. %s, (%p, %p)\n", this->depth, nodeA->getClassName(), nodeB->getClassName(), this->nodeLeft, this->nodeRight);
+
+    /* check if left node overlaps */
+    if( likely( this->nodeLeft != NULL))
+    {
+      PRINT(3)("Checking OBB %i vs %i: ", this->nodeLeft->getIndex(), treeNode->getIndex());
+      if( this->overlapTest(this->nodeLeft->bvElement, ((OBBTreeNode*)treeNode)->bvElement, nodeA, nodeB))
+      {
+        this->nodeLeft->collideWith(((OBBTreeNode*)treeNode)->nodeLeft, nodeA, nodeB);
+        this->nodeLeft->collideWith(((OBBTreeNode*)treeNode)->nodeRight, nodeA, nodeB);
+      }
+    }
+    /* check if right node overlaps */
+    if( likely( this->nodeRight != NULL))
+    {
+      PRINT(3)("Checking OBB %i vs %i: ", this->nodeRight->getIndex(), treeNode->getIndex());
+      if(this->overlapTest(this->nodeRight->bvElement, ((OBBTreeNode*)treeNode)->bvElement, nodeA, nodeB))
+      {
+       this->nodeRight->collideWith(((OBBTreeNode*)treeNode)->nodeLeft, nodeA, nodeB);
+       this->nodeRight->collideWith(((OBBTreeNode*)treeNode)->nodeRight, nodeA, nodeB);
+      }
+    }
+
+    /* so there is a collision and this is the last box in the tree (i.e. leaf) */
+    if( unlikely(this->nodeRight == NULL && this->nodeLeft == NULL))
+    {
+      nodeA->collidesWith(nodeB, *((OBBTreeNode*)treeNode)->bvElement->center);
+
+      nodeB->collidesWith(nodeA, *this->bvElement->center);
+    }
+
+  }
+}
+
+
+
+bool OBBTreeNode::overlapTest(OBB* boxA, OBB* boxB, WorldEntity* nodeA, WorldEntity* nodeB)
+{
+  /* first check all axis */
+  Vector t;
+  float rA = 0.0f;
+  float rB = 0.0f;
+  Vector l;
+  Vector rotAxisA[3];
+  Vector rotAxisB[3];
+
+  rotAxisA[0] =  nodeA->getAbsDir().apply(boxA->axis[0]);
+  rotAxisA[1] =  nodeA->getAbsDir().apply(boxA->axis[1]);
+  rotAxisA[2] =  nodeA->getAbsDir().apply(boxA->axis[2]);
+
+  rotAxisB[0] =  nodeB->getAbsDir().apply(boxB->axis[0]);
+  rotAxisB[1] =  nodeB->getAbsDir().apply(boxB->axis[1]);
+  rotAxisB[2] =  nodeB->getAbsDir().apply(boxB->axis[2]);
+
+  t = nodeA->getAbsCoor() + nodeA->getAbsDir().apply(*boxA->center) - ( nodeB->getAbsCoor() + nodeB->getAbsDir().apply(*boxB->center));
+
+//   printf("\n");
+//   printf("(%f, %f, %f) -> (%f, %f, %f)\n", boxA->axis[0].x, boxA->axis[0].y, boxA->axis[0].z, rotAxisA[0].x, rotAxisA[0].y, rotAxisA[0].z);
+//   printf("(%f, %f, %f) -> (%f, %f, %f)\n", boxA->axis[1].x, boxA->axis[1].y, boxA->axis[1].z, rotAxisA[1].x, rotAxisA[1].y, rotAxisA[1].z);
+//   printf("(%f, %f, %f) -> (%f, %f, %f)\n", boxA->axis[2].x, boxA->axis[2].y, boxA->axis[2].z, rotAxisA[2].x, rotAxisA[2].y, rotAxisA[2].z);
+//
+//   printf("(%f, %f, %f) -> (%f, %f, %f)\n", boxB->axis[0].x, boxB->axis[0].y, boxB->axis[0].z, rotAxisB[0].x, rotAxisB[0].y, rotAxisB[0].z);
+//   printf("(%f, %f, %f) -> (%f, %f, %f)\n", boxB->axis[1].x, boxB->axis[1].y, boxB->axis[1].z, rotAxisB[1].x, rotAxisB[1].y, rotAxisB[1].z);
+//   printf("(%f, %f, %f) -> (%f, %f, %f)\n", boxB->axis[2].x, boxB->axis[2].y, boxB->axis[2].z, rotAxisB[2].x, rotAxisB[2].y, rotAxisB[2].z);
+
+
+  /* All 3 axis of the object A */
+  for( int j = 0; j < 3; ++j)
+  {
+    rA = 0.0f;
+    rB = 0.0f;
+    l = rotAxisA[j];
+
+    rA += fabs(boxA->halfLength[0] * rotAxisA[0].dot(l));
+    rA += fabs(boxA->halfLength[1] * rotAxisA[1].dot(l));
+    rA += fabs(boxA->halfLength[2] * rotAxisA[2].dot(l));
+
+    rB += fabs(boxB->halfLength[0] * rotAxisB[0].dot(l));
+    rB += fabs(boxB->halfLength[1] * rotAxisB[1].dot(l));
+    rB += fabs(boxB->halfLength[2] * rotAxisB[2].dot(l));
+
+    PRINTF(3)("s = %f, rA+rB = %f\n", fabs(t.dot(l)), rA+rB);
+
+    if( (rA + rB) < fabs(t.dot(l)))
+    {
+      PRINT(3)("no Collision\n");
+      return false;
+    }
+  }
+
+  /* All 3 axis of the object B */
+  for( int j = 0; j < 3; ++j)
+  {
+    rA = 0.0f;
+    rB = 0.0f;
+    l = rotAxisB[j];
+
+    rA += fabs(boxA->halfLength[0] * rotAxisA[0].dot(l));
+    rA += fabs(boxA->halfLength[1] * rotAxisA[1].dot(l));
+    rA += fabs(boxA->halfLength[2] * rotAxisA[2].dot(l));
+
+    rB += fabs(boxB->halfLength[0] * rotAxisB[0].dot(l));
+    rB += fabs(boxB->halfLength[1] * rotAxisB[1].dot(l));
+    rB += fabs(boxB->halfLength[2] * rotAxisB[2].dot(l));
+
+    PRINTF(3)("s = %f, rA+rB = %f\n", fabs(t.dot(l)), rA+rB);
+
+    if( (rA + rB) < fabs(t.dot(l)))
+    {
+      PRINT(3)("no Collision\n");
+      return false;
+    }
+  }
+
+
+  /* Now check for all face cross products */
+
+  for( int j = 0; j < 3; ++j)
+  {
+    for(int k = 0; k < 3; ++k )
+    {
+      rA = 0.0f;
+      rB = 0.0f;
+      l = rotAxisA[j].cross(rotAxisB[k]);
+
+      rA += fabs(boxA->halfLength[0] * rotAxisA[0].dot(l));
+      rA += fabs(boxA->halfLength[1] * rotAxisA[1].dot(l));
+      rA += fabs(boxA->halfLength[2] * rotAxisA[2].dot(l));
+
+      rB += fabs(boxB->halfLength[0] * rotAxisB[0].dot(l));
+      rB += fabs(boxB->halfLength[1] * rotAxisB[1].dot(l));
+      rB += fabs(boxB->halfLength[2] * rotAxisB[2].dot(l));
+
+      PRINTF(3)("s = %f, rA+rB = %f\n", fabs(t.dot(l)), rA+rB);
+
+      if( (rA + rB) < fabs(t.dot(l)))
+      {
+        PRINT(3)("keine Kollision\n");
+        return false;
+      }
+    }
+  }
+
+
+  boxA->bCollided = true; /* use this ONLY(!!!!) for drawing operations */
+  boxB->bCollided = true;
+  PRINT(3)("Kollision!\n");
+  return true;
+}
+
+
+
+
+
+void OBBTreeNode::drawBV(int depth, int drawMode, const Vector& color,  bool top) const
+{
+
+  /* draw the model itself, there is some problem concerning this: the vertices are drawn multiple times */
+  if( drawMode & DRAW_MODEL || drawMode & DRAW_ALL)
+  {
+    if( !(drawMode & DRAW_SINGLE && depth != 0))
+    {
+      if( drawMode & DRAW_POINTS)
+        glBegin(GL_POINTS);
+      for(int i = 0; i < this->bvElement->numOfVertices; ++i)
+      {
+        if( drawMode & DRAW_POINTS)
+          glVertex3f(this->bvElement->vertices[i][0], this->bvElement->vertices[i][1], this->bvElement->vertices[i][2]);
+        else
+        {
+          glPushMatrix();
+          glTranslatef(this->bvElement->vertices[i][0], this->bvElement->vertices[i][1], this->bvElement->vertices[i][2]);
+          gluSphere(OBBTreeNode_sphereObj, 0.1, 10, 10);
+          glPopMatrix();
+        }
+      }
+      if( drawMode & DRAW_POINTS)
+        glEnd();
+    }
+  }
+
+  if (top)
+  {
+    glPushAttrib(GL_ENABLE_BIT);
+    glDisable(GL_LIGHTING);
+    glDisable(GL_TEXTURE_2D);
+  }
+  glColor3f(color.x, color.y, color.z);
+
+
+  /* draw world axes */
+  if( drawMode & DRAW_BV_AXIS)
+  {
+    glBegin(GL_LINES);
+    glColor3f(1.0, 0.0, 0.0);
+    glVertex3f(0.0, 0.0, 0.0);
+    glVertex3f(3.0, 0.0, 0.0);
+
+    glColor3f(0.0, 1.0, 0.0);
+    glVertex3f(0.0, 0.0, 0.0);
+    glVertex3f(0.0, 3.0, 0.0);
+
+    glColor3f(0.0, 0.0, 1.0);
+    glVertex3f(0.0, 0.0, 0.0);
+    glVertex3f(0.0, 0.0, 3.0);
+    glEnd();
+  }
+
+
+  if( drawMode & DRAW_BV_AXIS || drawMode & DRAW_ALL)
+  {
+    if( !(drawMode & DRAW_SINGLE && depth != 0))
+    {
+      /* draw the obb axes */
+      glBegin(GL_LINES);
+      glColor3f(0.0, 0.4, 0.3);
+      glVertex3f(this->bvElement->center->x, this->bvElement->center->y, this->bvElement->center->z);
+      glVertex3f(this->bvElement->center->x + this->bvElement->axis[0].x * this->bvElement->halfLength[0],
+                 this->bvElement->center->y + this->bvElement->axis[0].y * this->bvElement->halfLength[0],
+                 this->bvElement->center->z + this->bvElement->axis[0].z * this->bvElement->halfLength[0]);
+
+      glVertex3f(this->bvElement->center->x, this->bvElement->center->y, this->bvElement->center->z);
+      glVertex3f(this->bvElement->center->x + this->bvElement->axis[1].x * this->bvElement->halfLength[1],
+                 this->bvElement->center->y + this->bvElement->axis[1].y * this->bvElement->halfLength[1],
+                 this->bvElement->center->z + this->bvElement->axis[1].z * this->bvElement->halfLength[1]);
+
+      glVertex3f(this->bvElement->center->x, this->bvElement->center->y, this->bvElement->center->z);
+      glVertex3f(this->bvElement->center->x + this->bvElement->axis[2].x * this->bvElement->halfLength[2],
+                 this->bvElement->center->y + this->bvElement->axis[2].y * this->bvElement->halfLength[2],
+                 this->bvElement->center->z + this->bvElement->axis[2].z * this->bvElement->halfLength[2]);
+      glEnd();
+    }
+  }
+
+
+  /* DRAW POLYGONS */
+  if( drawMode & DRAW_BV_POLYGON || drawMode & DRAW_ALL || drawMode & DRAW_BV_BLENDED)
+  {
+    if (top)
+    {
+      glEnable(GL_BLEND);
+      glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+    }
+
+    if(this->nodeLeft == NULL || this->nodeRight == NULL)
+      depth = 0;
+    if( !(drawMode & DRAW_SINGLE && depth != 0))
+    {
+    Vector cen = *this->bvElement->center;
+    Vector* axis = this->bvElement->axis;
+    float* len = this->bvElement->halfLength;
+
+    if( this->bvElement->bCollided)
+    {
+      glColor4f(1.0, 1.0, 1.0, .5); // COLLISION COLOR
+    }
+    else if( drawMode & DRAW_BV_BLENDED)
+    {
+      glColor4f(color.x, color.y, color.z, .5);
+    }
+
+    /* draw bounding box */
+    if( drawMode & DRAW_BV_BLENDED)
+      glBegin(GL_QUADS);
+    else
+      glBegin(GL_LINE_LOOP);
+    glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
+               cen.y + axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
+               cen.z + axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
+    glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
+               cen.y + axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
+               cen.z + axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
+    glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
+               cen.y + axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
+               cen.z + axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
+    glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
+               cen.y + axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
+               cen.z + axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
+    glEnd();
+
+    if( drawMode & DRAW_BV_BLENDED)
+      glBegin(GL_QUADS);
+    else
+      glBegin(GL_LINE_LOOP);
+    glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
+               cen.y + axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
+               cen.z + axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
+    glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
+               cen.y + axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
+               cen.z + axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
+    glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
+               cen.y - axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
+               cen.z - axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
+    glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
+               cen.y - axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
+               cen.z - axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
+    glEnd();
+
+    if( drawMode & DRAW_BV_BLENDED)
+      glBegin(GL_QUADS);
+    else
+      glBegin(GL_LINE_LOOP);
+    glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
+               cen.y - axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
+               cen.z - axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
+    glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
+               cen.y - axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
+               cen.z - axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
+    glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
+               cen.y - axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
+               cen.z - axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
+    glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
+               cen.y - axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
+               cen.z - axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
+    glEnd();
+
+    if( drawMode & DRAW_BV_BLENDED)
+      glBegin(GL_QUADS);
+    else
+      glBegin(GL_LINE_LOOP);
+    glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
+               cen.y - axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
+               cen.z - axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
+    glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
+               cen.y - axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
+               cen.z - axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
+    glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
+               cen.y + axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
+               cen.z + axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
+    glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
+               cen.y + axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
+               cen.z + axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
+    glEnd();
+
+
+    if( drawMode & DRAW_BV_BLENDED)
+    {
+      glBegin(GL_QUADS);
+      glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
+                 cen.y - axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
+                 cen.z - axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
+      glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] - axis[2].x * len[2],
+                 cen.y + axis[0].y * len[0] + axis[1].y * len[1] - axis[2].y * len[2],
+                 cen.z + axis[0].z * len[0] + axis[1].z * len[1] - axis[2].z * len[2]);
+      glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
+                 cen.y + axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
+                 cen.z + axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
+      glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] - axis[2].x * len[2],
+                 cen.y - axis[0].y * len[0] - axis[1].y * len[1] - axis[2].y * len[2],
+                 cen.z - axis[0].z * len[0] - axis[1].z * len[1] - axis[2].z * len[2]);
+      glEnd();
+
+      glBegin(GL_QUADS);
+      glVertex3f(cen.x - axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
+                 cen.y - axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
+                 cen.z - axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
+      glVertex3f(cen.x + axis[0].x * len[0] + axis[1].x * len[1] + axis[2].x * len[2],
+                 cen.y + axis[0].y * len[0] + axis[1].y * len[1] + axis[2].y * len[2],
+                 cen.z + axis[0].z * len[0] + axis[1].z * len[1] + axis[2].z * len[2]);
+      glVertex3f(cen.x + axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
+                 cen.y + axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
+                 cen.z + axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
+      glVertex3f(cen.x - axis[0].x * len[0] - axis[1].x * len[1] + axis[2].x * len[2],
+                 cen.y - axis[0].y * len[0] - axis[1].y * len[1] + axis[2].y * len[2],
+                 cen.z - axis[0].z * len[0] - axis[1].z * len[1] + axis[2].z * len[2]);
+      glEnd();
+    }
+
+
+    if( drawMode & DRAW_BV_BLENDED)
+      glColor3f(color.x, color.y, color.z);
+    }
+
+  }
+
+  /* DRAW SEPARATING PLANE */
+  if( drawMode & DRAW_SEPARATING_PLANE || drawMode & DRAW_ALL)
+  {
+    if( !(drawMode & DRAW_SINGLE && depth != 0))
+    {
+      if( drawMode & DRAW_BV_BLENDED)
+        glColor4f(color.x, color.y, color.z, .6);
+
+    /* now draw the separation plane */
+    Vector a1 = this->bvElement->axis[(this->longestAxisIndex + 1)%3];
+    Vector a2 = this->bvElement->axis[(this->longestAxisIndex + 2)%3];
+    Vector c = *this->bvElement->center;
+    float l1 = this->bvElement->halfLength[(this->longestAxisIndex + 1)%3];
+    float l2 = this->bvElement->halfLength[(this->longestAxisIndex + 2)%3];
+    glBegin(GL_QUADS);
+    glVertex3f(c.x + a1.x * l1 + a2.x * l2, c.y + a1.y * l1+ a2.y * l2, c.z + a1.z * l1 + a2.z * l2);
+    glVertex3f(c.x - a1.x * l1 + a2.x * l2, c.y - a1.y * l1+ a2.y * l2, c.z - a1.z * l1 + a2.z * l2);
+    glVertex3f(c.x - a1.x * l1 - a2.x * l2, c.y - a1.y * l1- a2.y * l2, c.z - a1.z * l1 - a2.z * l2);
+    glVertex3f(c.x + a1.x * l1 - a2.x * l2, c.y + a1.y * l1- a2.y * l2, c.z + a1.z * l1 - a2.z * l2);
+    glEnd();
+
+    if( drawMode & DRAW_BV_BLENDED)
+      glColor4f(color.x, color.y, color.z, 1.0);
+
+    }
+  }
+
+
+
+  if (depth > 0)
+  {
+    if( this->nodeLeft != NULL)
+      this->nodeLeft->drawBV(depth - 1, drawMode, Color::HSVtoRGB(Color::RGBtoHSV(color)+Vector(15.0,0.0,0.0)), false);
+    if( this->nodeRight != NULL)
+      this->nodeRight->drawBV(depth - 1, drawMode, Color::HSVtoRGB(Color::RGBtoHSV(color)+Vector(30.0,0.0,0.0)), false);
+  }
+  this->bvElement->bCollided = false;
+
+  if (top)
+    glPopAttrib();
+}
+
+
+
+void OBBTreeNode::debug() const
+{
+
+  /*
+  for(int i = 0; i < length; i++)
+  {
+  PRINTF(3)("vertex %i: %f, %f, %f\n", i, verticesList[i][0], verticesList[i][1], verticesList[i][2]);
+}
+  */
+}
Index: branches/network/src/lib/collision_detection/obb_tree_node.h
===================================================================
--- branches/network/src/lib/collision_detection/obb_tree_node.h	(revision 6636)
+++ branches/network/src/lib/collision_detection/obb_tree_node.h	(revision 6636)
@@ -0,0 +1,84 @@
+/*!
+ * @file bv_tree.h
+  *  Definition of a bounding volume tree
+
+ */
+
+#ifndef _OBB_TREE_NODE_H
+#define _OBB_TREE_NODE_H
+
+#include "bv_tree_node.h"
+
+
+
+// FORWARD DECLARATION
+class BoundingVolume;
+class OBB;
+class OBBTree;
+class Plane;
+class PNode;
+//struct sVec3D;
+
+//! A class that represents a bounding volume tree
+class OBBTreeNode : public BVTreeNode {
+
+
+  public:
+    OBBTreeNode();
+    virtual ~OBBTreeNode();
+
+    virtual void spawnBVTree(const int depth, const sVec3D *verticesList, unsigned int length);
+    virtual void spawnBVTree(const int depth, const modelInfo& modInfo);
+
+    BoundingVolume* getBV(int index) const { return (BoundingVolume*)this->bvElement; }
+    inline const int getIndex() { return this->treeIndex; }
+    inline void setTreeRef(OBBTree* tree) { this->obbTree = tree;}
+
+    virtual void collideWith(BVTreeNode* treeNode, WorldEntity* nodeA, WorldEntity* nodeB);
+
+    virtual void drawBV(int depth, int drawMode, const Vector& color = Vector(1,0,0), bool top = true) const;
+
+    void debug() const;
+
+  private:
+    void calculateBoxCovariance(OBB* box, const sVec3D* verticesList, unsigned int length);
+    void calculateBoxEigenvectors(OBB* box, const sVec3D* verticesList, unsigned int length);
+    void calculateBoxAxis(OBB* box, const sVec3D* verticesList, unsigned int length);
+
+    void calculateBoxCovariance(OBB* box, const modelInfo& modInfo);
+    void calculateBoxEigenvectors(OBB* box, const modelInfo& modInfo);
+    void calculateBoxAxis(OBB* box, const modelInfo& modInfo);
+
+
+    void forkBox(OBB* box);
+
+    bool overlapTest(OBB* boxA, OBB* boxB, WorldEntity* nodeA, WorldEntity* nodeB);
+
+  protected:
+    OBB*                bvElement;                  //!< the obb element
+    OBBTreeNode*        nodeLeft;                   //!< ref to the left tree node
+    OBBTreeNode*        nodeRight;                  //!< ref to the right tree node
+
+  private:
+    unsigned int        treeIndex;                  //!< Index number of the BV in the tree
+    const sVec3D*       vertices;                   //!< pointer to the vertices data
+    int                 numOfVertices;              //!< number of vertices in vertices data
+    int                 depth;                      //!< the depth of the node in the tree
+    static OBBTree*     obbTree;                    //!< reference to the obb tree
+    Plane*              separationPlane;            //!< the separation plane of the obb
+    const sVec3D*       sepPlaneCenter;             //!< only needed to draw plane
+    int                 longestAxisIndex;           //!< only needed to draw plane
+
+    /* tmp saving place for obb variables */
+    sVec3D*             tmpVert1;                   //!< pointer to the vert data of obbox1
+    sVec3D*             tmpVert2;                   //!< pointer to the vert data of obbox1
+    int                 tmpLen1;                    //!< len vert data obbox1
+    int                 tmpLen2;                    //!< len vert data obbox2
+
+    static float**      coMat;
+    static float**      eigvMat;
+    static float*       eigvlMat;
+    static int*         rotCount;
+};
+
+#endif /* _OBB_TREE_NODE_H */
Index: branches/network/src/lib/coord/p_node.cc
===================================================================
--- branches/network/src/lib/coord/p_node.cc	(revision 6636)
+++ branches/network/src/lib/coord/p_node.cc	(revision 6636)
@@ -0,0 +1,1276 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: Benjamin Grauer
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_PNODE
+
+#include "p_node.h"
+
+#include "load_param.h"
+#include "class_list.h"
+
+#include <algorithm>
+#include "compiler.h"
+#include "debug.h"
+
+#include "glincl.h"
+#include "color.h"
+
+#include "synchronizeable.h"
+
+#include "shell_command.h"
+SHELL_COMMAND(debugNode, PNode, debugNodeSC);
+
+using namespace std;
+
+
+/**
+ * @brief standard constructor
+ * @param parent the Parent of this Node. __NULL__ if __No Parent__ requested, PNode::getNullParent(), if connected to NullParent directly (default)
+ * @param nodeFlags all flags to set. THIS_WILL_OVERWRITE Default_Values.
+ */
+PNode::PNode (PNode* parent, long nodeFlags)
+{
+  this->setClassID(CL_PARENT_NODE, "PNode");
+
+  this->bRelCoorChanged = true;
+  this->bRelDirChanged = true;
+  this->parent = NULL;
+  this->parentMode = nodeFlags;
+  this->bActive = true;
+
+  // smooth-movers
+  this->toCoordinate = NULL;
+  this->toDirection = NULL;
+  this->bias = 1.0;
+
+  if (parent != NULL)
+    parent->addChild(this);
+}
+
+// NullParent Reference
+PNode* PNode::nullParent = NULL;
+
+/**
+ * @brief standard deconstructor
+ *
+ * There are two general ways to delete a PNode
+ * 1. delete instance;
+ *   -> result
+ *    delete this Node and all its children and children's children...
+ *    (danger if you still need the children's instance somewhere else!!)
+ *
+ * 2. instance->removeNode(); delete instance;
+ *   -> result:
+ *    moves its children to the NullParent
+ *    then deletes the Element.
+ */
+PNode::~PNode ()
+{
+  // remove the Node, delete it's children (if required).
+  std::list<PNode*>::iterator tmp = this->children.begin();
+  std::list<PNode*>::iterator deleteNode;
+  while(!this->children.empty())
+    while (tmp != this->children.end())
+    {
+      deleteNode = tmp;
+      tmp++;
+//      printf("TEST::%s(%s) %s\n", (*deleteNode)->getName(), (*deleteNode)->getClassName(), this->getName());
+      if ((this->parentMode & PNODE_PROHIBIT_CHILD_DELETE) ||
+          ((*deleteNode)->parentMode & PNODE_PROHIBIT_DELETE_WITH_PARENT))
+      {
+        if (this == PNode::nullParent && (*deleteNode)->parentMode & PNODE_REPARENT_TO_NULL)
+          delete (*deleteNode);
+        else
+          (*deleteNode)->reparent();
+      }
+      else
+        delete (*deleteNode);
+    }
+
+  if (this->parent != NULL)
+   {
+     this->parent->eraseChild(this);
+     this->parent = NULL;
+   }
+
+  // remove all other allocated memory.
+  if (this->toCoordinate != NULL)
+    delete this->toCoordinate;
+  if (this->toDirection != NULL)
+    delete this->toDirection;
+
+  if (this == PNode::nullParent)
+    PNode::nullParent = NULL;
+}
+
+
+/**
+ * @brief loads parameters of the PNode
+ * @param root the XML-element to load the properties of
+ */
+void PNode::loadParams(const TiXmlElement* root)
+{
+  BaseObject::loadParams(root);
+
+  LoadParam(root, "rel-coor", this, PNode, setRelCoor)
+      .describe("Sets The relative position of the Node to its parent.");
+
+  LoadParam(root, "abs-coor", this, PNode, setAbsCoor)
+      .describe("Sets The absolute Position of the Node.");
+
+  LoadParam(root, "rel-dir", this, PNode, setRelDir)
+      .describe("Sets The relative rotation of the Node to its parent.");
+
+  LoadParam(root, "abs-dir", this, PNode, setAbsDir)
+      .describe("Sets The absolute rotation of the Node.");
+
+  LoadParam(root, "parent", this, PNode, setParent)
+      .describe("the Name of the Parent of this PNode");
+
+  LoadParam(root, "parent-mode", this, PNode, setParentMode)
+      .describe("the mode to connect this node to its parent ()");
+
+  // cycling properties
+  if (root != NULL)
+  {
+    LOAD_PARAM_START_CYCLE(root, element);
+    {
+      LoadParam_CYCLE(element, "child", this, PNode, addChild)
+          .describe("adds a new Child to the current Node.");
+
+    }
+    LOAD_PARAM_END_CYCLE(element);
+  }
+}
+
+
+/**
+ *  init the pnode to a well definied state
+ *
+ * this function actualy only updates the PNode tree
+ */
+void PNode::init()
+{
+  /* just update all aboslute positions via timestep 0.001ms */
+  this->updateNode(0.001f);
+  this->updateNode(0.001f);
+}
+
+
+/**
+ * @brief set relative coordinates
+ * @param relCoord relative coordinates to its parent
+ *
+ *
+ * it is very importand, that you use this function, if you want to update the
+ * relCoordinates. If you don't use this, the PNode won't recognize, that something
+ * has changed and won't update the children Nodes.
+ */
+void PNode::setRelCoor (const Vector& relCoord)
+{
+  if (this->toCoordinate!= NULL)
+  {
+    delete this->toCoordinate;
+    this->toCoordinate = NULL;
+  }
+
+  this->relCoordinate = relCoord;
+  this->bRelCoorChanged = true;
+}
+
+/**
+ * @brief set relative coordinates
+ * @param x x-relative coordinates to its parent
+ * @param y y-relative coordinates to its parent
+ * @param z z-relative coordinates to its parent
+ * @see  void PNode::setRelCoor (const Vector& relCoord)
+ */
+void PNode::setRelCoor (float x, float y, float z)
+{
+  this->setRelCoor(Vector(x, y, z));
+}
+
+/**
+ * @brief sets a new relative position smoothely
+ * @param relCoordSoft the new Position to iterate to
+ * @param bias how fast to iterate to this position
+ */
+void PNode::setRelCoorSoft(const Vector& relCoordSoft, float bias)
+{
+  if (likely(this->toCoordinate == NULL))
+    this->toCoordinate = new Vector();
+
+  *this->toCoordinate = relCoordSoft;
+  this->toStep = 0.0f;
+  this->bias = bias;
+}
+
+
+/**
+ * @brief set relative coordinates smoothely
+ * @param x x-relative coordinates to its parent
+ * @param y y-relative coordinates to its parent
+ * @param z z-relative coordinates to its parent
+ * @see  void PNode::setRelCoorSoft (const Vector&, float)
+ */
+void PNode::setRelCoorSoft (float x, float y, float z, float bias)
+{
+  this->setRelCoorSoft(Vector(x, y, z), bias);
+}
+
+
+/**
+ * @param absCoord set absolute coordinate
+ */
+void PNode::setAbsCoor (const Vector& absCoord)
+{
+  if (this->toCoordinate!= NULL)
+  {
+    delete this->toCoordinate;
+    this->toCoordinate = NULL;
+  }
+
+  if( likely(this->parentMode & PNODE_MOVEMENT))
+  {
+      /* if you have set the absolute coordinates this overrides all other changes */
+    if (likely(this->parent != NULL))
+      this->relCoordinate = absCoord - parent->getAbsCoor ();
+    else
+      this->relCoordinate = absCoord;
+  }
+  if( this->parentMode & PNODE_ROTATE_MOVEMENT)
+  {
+    if (likely(this->parent != NULL))
+      this->relCoordinate = absCoord - parent->getAbsCoor ();
+    else
+      this->relCoordinate = absCoord;
+  }
+
+  this->bRelCoorChanged = true;
+//  this->absCoordinate = absCoord;
+}
+
+
+/**
+ * @param x x-coordinate.
+ * @param y y-coordinate.
+ * @param z z-coordinate.
+ * @see void PNode::setAbsCoor (const Vector& absCoord)
+ */
+void PNode::setAbsCoor(float x, float y, float z)
+{
+  this->setAbsCoor(Vector(x, y, z));
+}
+
+
+/**
+ * @param absCoord set absolute coordinate
+ * @todo check off
+ */
+void PNode::setAbsCoorSoft (const Vector& absCoordSoft, float bias)
+{
+  if (this->toCoordinate == NULL)
+    this->toCoordinate = new Vector;
+
+  if( likely(this->parentMode & PNODE_MOVEMENT))
+  {
+      /* if you have set the absolute coordinates this overrides all other changes */
+    if (likely(this->parent != NULL))
+      *this->toCoordinate = absCoordSoft - parent->getAbsCoor ();
+    else
+      *this->toCoordinate = absCoordSoft;
+  }
+  if( this->parentMode & PNODE_ROTATE_MOVEMENT)
+  {
+    if (likely(this->parent != NULL))
+      *this->toCoordinate = absCoordSoft - parent->getAbsCoor ();
+    else
+      *this->toCoordinate = absCoordSoft;
+  }
+  this->toStep = 0.0f;
+}
+
+
+/**
+ * @brief shift coordinate relative
+ * @param shift shift vector
+ *
+ * this function shifts the current coordinates about the vector shift. this is
+ * usefull because from some place else you can:
+ * PNode* someNode = ...;
+ * Vector objectMovement = calculateShift();
+ * someNode->shiftCoor(objectMovement);
+ *
+ * this is the internal method of:
+ * PNode* someNode = ...;
+ * Vector objectMovement = calculateShift();
+ * Vector currentCoor = someNode->getRelCoor();
+ * Vector newCoor = currentCoor + objectMovement;
+ * someNode->setRelCoor(newCoor);
+ *
+ */
+void PNode::shiftCoor (const Vector& shift)
+{
+  this->relCoordinate += shift;
+  this->bRelCoorChanged = true;
+}
+
+
+/**
+ * @brief set relative direction
+ * @param relDir to its parent
+ */
+void PNode::setRelDir (const Quaternion& relDir)
+{
+  if (this->toDirection!= NULL)
+  {
+    delete this->toDirection;
+    this->toDirection = NULL;
+  }
+  this->relDirection = relDir;
+
+  this->bRelCoorChanged = true;
+}
+
+
+/**
+ * @see void PNode::setRelDir (const Quaternion& relDir)
+ * @param x the x direction
+ * @param y the y direction
+ * @param z the z direction
+ *
+ * main difference is, that here you give a directional vector, that will be translated into a Quaternion
+ */
+void PNode::setRelDir (float x, float y, float z)
+{
+  this->setRelDir(Quaternion(Vector(x,y,z), Vector(0,1,0)));
+}
+
+
+/**
+ * @brief sets the Relative Direction of this node to its parent in a Smoothed way
+ * @param relDirSoft the direction to iterate to smoothely.
+ * @param bias how fast to iterate to the new Direction
+ */
+void PNode::setRelDirSoft(const Quaternion& relDirSoft, float bias)
+{
+  if (likely(this->toDirection == NULL))
+    this->toDirection = new Quaternion();
+
+  *this->toDirection = relDirSoft;
+  this->bias = bias;
+  this->toStep = 0.0f;
+  this->bRelDirChanged = true;
+}
+
+
+/**
+ * @see void PNode::setRelDirSoft (const Quaternion& relDir)
+ * @param x the x direction
+ * @param y the y direction
+ * @param z the z direction
+ *
+ * main difference is, that here you give a directional vector, that will be translated into a Quaternion
+ */
+void PNode::setRelDirSoft(float x, float y, float z, float bias)
+{
+  this->setRelDirSoft(Quaternion(Vector(x,y,z), Vector(0,1,0)), bias);
+}
+
+
+/**
+ * @brief sets the absolute direction
+ * @param absDir absolute coordinates
+ */
+void PNode::setAbsDir (const Quaternion& absDir)
+{
+  if (this->toDirection!= NULL)
+  {
+    delete this->toDirection;
+    this->toDirection = NULL;
+  }
+
+  if (likely(this->parent != NULL))
+    this->relDirection = absDir / this->parent->getAbsDir();
+  else
+   this->relDirection = absDir;
+
+  this->bRelDirChanged = true;
+}
+
+
+/**
+ * @see void PNode::setAbsDir (const Quaternion& relDir)
+ * @param x the x direction
+ * @param y the y direction
+ * @param z the z direction
+ *
+ * main difference is, that here you give a directional vector, that will be translated into a Quaternion
+ */
+void PNode::setAbsDir (float x, float y, float z)
+{
+  this->setAbsDir(Quaternion(Vector(x,y,z), Vector(0,1,0)));
+}
+
+
+/**
+ * @brief sets the absolute direction
+ * @param absDir absolute coordinates
+ * @param bias how fast to iterator to the new Position
+ */
+void PNode::setAbsDirSoft (const Quaternion& absDirSoft, float bias)
+{
+  if (this->toDirection == NULL)
+    this->toDirection = new Quaternion();
+
+  if (likely(this->parent != NULL))
+    *this->toDirection = absDirSoft / this->parent->getAbsDir();
+  else
+   *this->toDirection = absDirSoft;
+
+  this->bias = bias;
+  this->toStep = 0.0f;
+  this->bRelDirChanged = true;
+}
+
+
+/**
+ * @see void PNode::setAbsDir (const Quaternion& relDir)
+ * @param x the x direction
+ * @param y the y direction
+ * @param z the z direction
+ *
+ * main difference is, that here you give a directional vector, that will be translated into a Quaternion
+ */
+void PNode::setAbsDirSoft (float x, float y, float z, float bias)
+{
+  this->setAbsDirSoft(Quaternion(Vector(x,y,z), Vector(0,1,0)), bias);
+}
+
+
+/**
+ * @brief shift Direction
+ * @param shift the direction around which to shift.
+ */
+void PNode::shiftDir (const Quaternion& shift)
+{
+  this->relDirection = this->relDirection * shift;
+  this->bRelDirChanged = true;
+}
+
+
+/**
+ * @brief adds a child and makes this node to a parent
+ * @param child child reference
+ * use this to add a child to this node.
+ */
+void PNode::addChild (PNode* child)
+{
+  if( likely(child->parent != NULL))
+      child->parent->eraseChild(child);
+  if (this->checkIntegrity(child))
+  {
+    child->parent = this;
+    if (unlikely(this != NULL))
+      this->children.push_back(child);
+    child->parentCoorChanged();
+  }
+  else
+  {
+    PRINTF(1)("Tried to reparent to own child '%s::%s' to '%s::%s'.\n",
+              this->getClassName(), this->getName(), child->getClassName(), child->getName());
+    child->parent = NULL;
+    child->parentCoorChanged();
+  }
+}
+
+
+/**
+ * @see PNode::addChild(PNode* child);
+ * @param childName the name of the child to add to this PNode
+ */
+void PNode::addChild (const char* childName)
+{
+  PNode* childNode = dynamic_cast<PNode*>(ClassList::getObject(childName, CL_PARENT_NODE));
+//  PRINTF(0)("Adding the Child: %s to: %s\n", childName, this->getName());
+//  assert( childNode != NULL );
+  if (childNode != NULL)
+  {
+    this->addChild(childNode);
+  }
+}
+
+
+/**
+ * @brief removes a child from the node
+ * @param child the child to remove from this pNode.
+ *
+ * Children from pNode will not be lost, they are Reparented by the rules of the ParentMode
+ */
+void PNode::removeChild (PNode* child)
+{
+  if (child != NULL)
+   child->removeNode();
+}
+
+
+/**
+ * !! PRIVATE FUNCTION
+ * @brief reparents a node (happens on Parents Node delete or remove and Flags are set.)
+ */
+void PNode::reparent()
+{
+  if (this->parentMode & PNODE_REPARENT_TO_NULL)
+    this->setParent((PNode*)NULL);
+  else if (this->parentMode & PNODE_REPARENT_TO_PARENTS_PARENT && this->parent != NULL)
+    this->setParent(this->parent->getParent());
+  else
+    this->setParent(PNode::getNullParent());
+}
+
+/**
+ * ereases child from the nodes children
+ * @param chuld the child to remove
+ */
+void PNode::eraseChild(PNode* child)
+{
+  std::list<PNode*>::iterator childRemover = std::find(this->children.begin(), this->children.end(), child);
+  if(childRemover != this->children.end())
+    this->children.erase(childRemover);
+}
+
+
+/**
+ * @brief remove this pnode from the tree and adds all following to NullParent
+ *
+ * this can be the case, if an entity in the world is being destroyed.
+ */
+void PNode::removeNode()
+{
+  list<PNode*>::iterator child = this->children.begin();
+  list<PNode*>::iterator reparenter;
+  while (child != this->children.end())
+  {
+    reparenter = child;
+    child++;
+    if (this->parentMode & PNODE_REPARENT_CHILDREN_ON_REMOVE ||
+        (*reparenter)->parentMode & PNODE_REPARENT_ON_PARENTS_REMOVE)
+    {
+      printf("TEST----------------%s ---- %s\n", this->getClassName(), (*reparenter)->getClassName());
+      (*reparenter)->reparent();
+      printf("REPARENTED TO: %s::%s\n",(*reparenter)->getParent()->getClassName(),(*reparenter)->getParent()->getName());
+    }
+  }
+  if (this->parent != NULL)
+  {
+    this->parent->eraseChild(this);
+    this->parent = NULL;
+  }
+}
+
+
+/**
+ * @see PNode::setParent(PNode* parent);
+ * @param parentName the name of the Parent to set to this PNode
+ */
+void PNode::setParent (const char* parentName)
+{
+  PNode* parentNode = dynamic_cast<PNode*>(ClassList::getObject(parentName, CL_PARENT_NODE));
+  if (parentNode != NULL)
+    parentNode->addChild(this);
+  else
+    PRINTF(2)("Not Found PNode's (%s::%s) new Parent by Name: %s\n",
+              this->getClassName(), this->getName(), parentName);
+}
+
+
+/**
+ * @brief does the reparenting in a very smooth way
+ * @param parentNode the new Node to connect this node to.
+ * @param bias the speed to iterate to this new Positions
+ */
+void PNode::setParentSoft(PNode* parentNode, float bias)
+{
+  // return if the new parent and the old one match
+  if (this->parent == parentNode )
+    return;
+  if (parentNode == NULL)
+    parentNode = PNode::getNullParent();
+
+  // store the Valures to iterate to.
+  if (likely(this->toCoordinate == NULL))
+  {
+    this->toCoordinate = new Vector();
+    *this->toCoordinate = this->getRelCoor();
+  }
+  if (likely(this->toDirection == NULL))
+  {
+    this->toDirection = new Quaternion();
+    *this->toDirection = this->getRelDir();
+  }
+  this->bias = bias;
+  this->toStep = 0.0f;
+
+  Vector tmpV = this->getAbsCoor();
+  Quaternion tmpQ = this->getAbsDir();
+
+  parentNode->addChild(this);
+
+ if (this->parentMode & PNODE_ROTATE_MOVEMENT && this->parent != NULL)
+   this->relCoordinate = this->parent->getAbsDir().inverse().apply(tmpV - this->parent->getAbsCoor());
+ else
+   this->relCoordinate = tmpV - parentNode->getAbsCoor();
+
+ this->relDirection = tmpQ / parentNode->getAbsDir();
+}
+
+
+/**
+ * @brief does the reparenting in a very smooth way
+ * @param parentName the name of the Parent to reconnect to
+ * @param bias the speed to iterate to this new Positions
+ */
+void PNode::setParentSoft(const char* parentName, float bias)
+{
+  PNode* parentNode = dynamic_cast<PNode*>(ClassList::getObject(parentName, CL_PARENT_NODE));
+  if (parentNode != NULL)
+    this->setParentSoft(parentNode, bias);
+}
+
+/**
+ * @param parentMode sets the parentingMode of this Node
+ */
+void PNode::setParentMode(PARENT_MODE parentMode)
+{
+  this->parentMode = ((this->parentMode & 0xfff0) | parentMode);
+}
+
+/**
+ * @brief sets the mode of this parent manually
+ * @param parentMode a String representing this parentingMode
+ */
+void PNode::setParentMode (const char* parentingMode)
+{
+  this->setParentMode(PNode::charToParentingMode(parentingMode));
+}
+
+/**
+ * @brief adds special mode Flags to this PNode
+ * @see PARENT_MODE
+ * @param nodeFlags a compsition of PARENT_MODE-flags, split by the '|' (or) operator.
+ */
+void PNode::addNodeFlags(unsigned short nodeFlags)
+{
+  this->parentMode |= nodeFlags;
+}
+
+/**
+ * @brief removes special mode Flags to this PNode
+ * @see PARENT_MODE
+ * @param nodeFlags a compsition of PARENT_MODE-flags, split by the '|' (or) operator.
+ */
+void PNode::removeNodeFlags(unsigned short nodeFlags)
+{
+  this->parentMode &= !nodeFlags;
+}
+
+/**
+ * @returns the NullParent (and if needed creates it)
+ */
+PNode* PNode::createNullParent()
+{
+  if (likely(PNode::nullParent == NULL))
+  {
+    PNode::nullParent = new PNode(NULL, PNODE_PARENT_MODE_DEFAULT | PNODE_REPARENT_TO_NULL);
+    PNode::nullParent->setName("NullParent");
+  }
+  return PNode::nullParent;
+}
+
+
+/**
+ * !! PRIVATE FUNCTION
+ * @brief checks the upward integrity (e.g if PNode is somewhere up the Node tree.)
+ * @param checkParent the Parent to check.
+ * @returns true if the integrity-check succeeds, false otherwise.
+ *
+ * If there is a second occurence of checkParent before NULL, then a loop could get
+ * into the Tree, and we do not want this.
+ */
+bool PNode::checkIntegrity(const PNode* checkParent) const
+{
+  const PNode* parent = this;
+  while ( (parent = parent->getParent()) != NULL)
+    if (unlikely(parent == checkParent))
+      return false;
+  return true;
+}
+
+
+/**
+ * @brief updates the absCoordinate/absDirection
+ * @param dt The time passed since the last update
+ *
+ * this is used to go through the parent-tree to update all the absolute coordinates
+ * and directions. this update should be done by the engine, so you don't have to
+ * worry, normaly...
+ */
+void PNode::updateNode (float dt)
+{
+  if (!(this->parentMode & PNODE_STATIC_NODE))
+  {
+    if( likely(this->parent != NULL))
+    {
+        // movement for nodes with smoothMove enabled
+        if (unlikely(this->toCoordinate != NULL))
+        {
+          Vector moveVect = (*this->toCoordinate - this->relCoordinate) *fabsf(dt)*bias;
+          if (likely(moveVect.len() >= PNODE_ITERATION_DELTA))
+          {
+            this->shiftCoor(moveVect);
+          }
+          else
+          {
+            delete this->toCoordinate;
+            this->toCoordinate = NULL;
+            PRINTF(5)("SmoothMove of %s finished\n", this->getName());
+          }
+        }
+        if (unlikely(this->toDirection != NULL))
+        {
+          this->toStep += fabs(dt) * bias;
+          //printf("%s::%s %f\n", this->getClassName(), this->getName(), this->toStep );
+          Quaternion rotQuat = Quaternion::quatSlerp(this->relDirection,*this->toDirection, toStep);
+          if (this->relDirection.distance(rotQuat) >PNODE_ITERATION_DELTA)
+          {
+            this->relDirection = rotQuat;
+            this->bRelDirChanged;
+          }
+          else
+          {
+            delete this->toDirection;
+            this->toDirection = NULL;
+            PRINTF(5)("SmoothRotate of %s finished\n", this->getName());
+          }
+        }
+
+        // MAIN UPDATE /////////////////////////////////////
+        this->lastAbsCoordinate = this->absCoordinate;
+
+        PRINTF(5)("PNode::update - '%s::%s' - (%f, %f, %f)\n", this->getClassName(), this->getName(),
+                      this->absCoordinate.x, this->absCoordinate.y, this->absCoordinate.z);
+
+
+        if(this->bRelDirChanged && this->parentMode & PNODE_LOCAL_ROTATE )
+        {
+          /* update the current absDirection - remember * means rotation around sth.*/
+          this->prevRelCoordinate = this->relCoordinate;
+          this->absDirection = parent->getAbsDir() * this->relDirection;
+        }
+
+        if(likely(this->bRelCoorChanged && this->parentMode & PNODE_MOVEMENT))
+        {
+        /* update the current absCoordinate */
+          this->prevRelCoordinate = this->relCoordinate;
+          this->absCoordinate = this->parent->getAbsCoor() + this->relCoordinate;
+        }
+        else if( this->parentMode & PNODE_ROTATE_MOVEMENT && this->bRelCoorChanged)
+        {
+          /* update the current absCoordinate */
+          this->prevRelCoordinate = this->relCoordinate;
+          this->absCoordinate = this->parent->getAbsCoor() + parent->getAbsDir().apply(this->relCoordinate);
+        }
+        /////////////////////////////////////////////////
+      }
+
+  else // Nodes without a Parent are handled faster :: MOST LIKELY THE NULLPARENT
+    {
+      PRINTF(4)("update ParentLess Node (%s::%s) - (%f, %f, %f)\n", this->getClassName(), this->getName(),
+                this->absCoordinate.x, this->absCoordinate.y, this->absCoordinate.z);
+        if (this->bRelCoorChanged)
+        {
+          this->prevRelCoordinate = this->relCoordinate;
+          this->absCoordinate = this->relCoordinate;
+        }
+        if (this->bRelDirChanged)
+        {
+          this->prevRelDirection = this->relDirection;
+          this->absDirection = this->getAbsDir () * this->relDirection;
+        }
+      }
+    }
+
+    if(!this->children.empty() && (this->bActive || this->parentMode & PNODE_UPDATE_CHILDREN_IF_INACTIVE ))
+    {
+      list<PNode*>::iterator child;
+      for (child = this->children.begin(); child != this->children.end(); child ++)
+      {
+        /* if this node has changed, make sure, that all children are updated also */
+        if( likely(this->bRelCoorChanged))
+          (*child)->parentCoorChanged ();
+        if( likely(this->bRelDirChanged))
+          (*child)->parentDirChanged ();
+
+        (*child)->updateNode(dt);
+      }
+    }
+    this->velocity = (this->absCoordinate - this->lastAbsCoordinate) / dt;
+    this->bRelCoorChanged = false;
+    this->bRelDirChanged = false;
+}
+
+
+
+
+
+/*************
+ * DEBUGGING *
+ *************/
+/**
+ * @brief counts total amount the children walking through the entire tree.
+ * @param nodes the counter
+ */
+void PNode::countChildNodes(int& nodes) const
+{
+  nodes++;
+  list<PNode*>::const_iterator child;
+  for (child = this->children.begin(); child != this->children.end(); child ++)
+    (*child)->countChildNodes(nodes);
+}
+
+
+/**
+ * @brief displays some information about this pNode
+ * @param depth The deph into which to debug the children of this PNode to.
+ * (0: all children will be debugged, 1: only this PNode, 2: this and direct children, ...)
+ * @param level !! INTERNAL !! The n-th level of the Node we draw (this is internal and only for nice output).
+ */
+void PNode::debugNode(unsigned int depth, unsigned int level) const
+{
+  for (unsigned int i = 0; i < level; i++)
+    PRINT(0)(" |");
+  if (this->children.size() > 0)
+    PRINT(0)(" +");
+  else
+    PRINT(0)(" -");
+
+  int childNodeCount = 0;
+  this->countChildNodes(childNodeCount);
+
+  PRINT(0)("PNode(%s::%s) - absCoord: (%0.2f, %0.2f, %0.2f), relCoord(%0.2f, %0.2f, %0.2f), direction(%0.2f, %0.2f, %0.2f) - %s - %d childs\n",
+           this->getClassName(),
+           this->getName(),
+           this->absCoordinate.x,
+           this->absCoordinate.y,
+           this->absCoordinate.z,
+           this->relCoordinate.x,
+           this->relCoordinate.y,
+           this->relCoordinate.z,
+           this->getAbsDirV().x,
+           this->getAbsDirV().y,
+           this->getAbsDirV().z,
+           this->parentingModeToChar(parentMode),
+           childNodeCount);
+  if (depth >= 2 || depth == 0)
+  {
+    list<PNode*>::const_iterator child;
+    for (child = this->children.begin(); child != this->children.end(); child ++)
+    {
+      if (depth == 0)
+        (*child)->debugNode(0, level + 1);
+      else
+        (*child)->debugNode(depth - 1, level +1);
+    }
+  }
+}
+
+/**
+ * @brief displays the PNode at its position with its rotation as a cube.
+ * @param  depth The deph into which to debug the children of this PNode to.
+ * (0: all children will be displayed, 1: only this PNode, 2: this and direct children, ...)
+ * @param size the Size of the Box to draw.
+ * @param color the color of the Box to display.
+ * @param level !! INTERNAL !! The n-th level of the Node we draw (this is internal and only for nice output).
+ */
+void PNode::debugDraw(unsigned int depth, float size, const Vector& color, unsigned int level) const
+{
+  // if this is the first Element we draw
+  if (level == 0)
+  {
+    glPushAttrib(GL_ENABLE_BIT); // save the Enable-attributes
+    glMatrixMode(GL_MODELVIEW);  // goto the ModelView Matrix
+
+    glDisable(GL_LIGHTING);      // disable lighting (we do not need them for just lighting)
+    glDisable(GL_BLEND);         // ''
+    glDisable(GL_TEXTURE_2D);    // ''
+    glDisable(GL_DEPTH_TEST);    // ''
+  }
+
+  glPushMatrix();                // repush the Matrix-stack
+  /* translate */
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+//  this->getAbsDir ().matrix (matrix);
+
+  /* rotate */
+  Vector tmpRot = this->getAbsDir().getSpacialAxis();
+  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+  /* set the new Color */
+  glColor3f(color.x, color.y, color.z);
+  { /* draw a cube of size size */
+    glBegin(GL_LINE_STRIP);
+    glVertex3f(-.5*size, -.5*size,  -.5*size);
+    glVertex3f(+.5*size, -.5*size,  -.5*size);
+    glVertex3f(+.5*size, -.5*size,  +.5*size);
+    glVertex3f(-.5*size, -.5*size,  +.5*size);
+    glVertex3f(-.5*size, -.5*size,  -.5*size);
+    glEnd();
+    glBegin(GL_LINE_STRIP);
+    glVertex3f(-.5*size, +.5*size,  -.5*size);
+    glVertex3f(+.5*size, +.5*size,  -.5*size);
+    glVertex3f(+.5*size, +.5*size,  +.5*size);
+    glVertex3f(-.5*size, +.5*size,  +.5*size);
+    glVertex3f(-.5*size, +.5*size,  -.5*size);
+    glEnd();
+
+    glBegin(GL_LINES);
+    glVertex3f(-.5*size, -.5*size,  -.5*size);
+    glVertex3f(-.5*size, +.5*size,  -.5*size);
+    glVertex3f(+.5*size, -.5*size,  -.5*size);
+    glVertex3f(+.5*size, +.5*size,  -.5*size);
+    glVertex3f(+.5*size, -.5*size,  +.5*size);
+    glVertex3f(+.5*size, +.5*size,  +.5*size);
+    glVertex3f(-.5*size, -.5*size,  +.5*size);
+    glVertex3f(-.5*size, +.5*size,  +.5*size);
+    glEnd();
+  }
+
+  glPopMatrix();
+  if (depth >= 2 || depth == 0)
+  {
+    /* rotate the current color in HSV space around 20 degree */
+    Vector childColor =  Color::HSVtoRGB(Color::RGBtoHSV(color)+Vector(20,0,.0));
+    list<PNode*>::const_iterator child;
+    for (child = this->children.begin(); child != this->children.end(); child ++)
+    {
+      // drawing the Dependency graph
+     if (this != PNode::getNullParent())
+      {
+       glBegin(GL_LINES);
+       glColor3f(color.x, color.y, color.z);
+       glVertex3f(this->getAbsCoor ().x,
+                  this->getAbsCoor ().y,
+                  this->getAbsCoor ().z);
+        glColor3f(childColor.x, childColor.y, childColor.z);
+        glVertex3f((*child)->getAbsCoor ().x,
+                   (*child)->getAbsCoor ().y,
+                   (*child)->getAbsCoor ().z);
+        glEnd();
+      }
+
+      /* if we want to draw the children too */
+      if (depth == 0) /* -> all of them */
+        (*child)->debugDraw(0, size, childColor, level+1);
+      else            /* -> only the Next one */
+        (*child)->debugDraw(depth - 1, size, childColor, level +1);
+    }
+  }
+  if (level == 0)
+    glPopAttrib(); /* pop the saved attributes back out */
+}
+
+
+
+/////////////////////
+// HELPER_FUCTIONS //
+/////////////////////
+
+/**
+ * @brief converts a parentingMode into a string that is the name of it
+ * @param parentingMode the ParentingMode to convert
+ * @return the converted string
+ */
+const char* PNode::parentingModeToChar(int parentingMode)
+{
+  if (parentingMode == PNODE_LOCAL_ROTATE)
+    return "local-rotate";
+  else if (parentingMode == PNODE_ROTATE_MOVEMENT)
+    return "rotate-movement";
+  else if (parentingMode == PNODE_MOVEMENT)
+    return "movement";
+  else if (parentingMode == PNODE_ALL)
+    return "all";
+  else if (parentingMode == PNODE_ROTATE_AND_MOVE)
+    return "rotate-and-move";
+}
+
+/**
+ * @brief converts a parenting-mode-string into a int
+ * @param parentingMode the string naming the parentingMode
+ * @return the int corresponding to the named parentingMode
+ */
+PARENT_MODE PNode::charToParentingMode(const char* parentingMode)
+{
+  if (!strcmp(parentingMode, "local-rotate"))
+    return (PNODE_LOCAL_ROTATE);
+  else  if (!strcmp(parentingMode, "rotate-movement"))
+    return (PNODE_ROTATE_MOVEMENT);
+  else  if (!strcmp(parentingMode, "movement"))
+    return (PNODE_MOVEMENT);
+  else  if (!strcmp(parentingMode, "all"))
+    return (PNODE_ALL);
+  else  if (!strcmp(parentingMode, "rotate-and-move"))
+    return (PNODE_ROTATE_AND_MOVE);
+}
+
+/**
+ * Writes data from network containing information about the state
+ * @param data pointer to data
+ * @param length length of data
+ * @param sender hostID of sender
+ */
+int PNode::writeState( const byte * data, int length, int sender )
+{
+  SYNCHELP_READ_BEGIN();
+
+  SYNCHELP_READ_FKT( BaseObject::writeState );
+
+  char * parentName = NULL;
+  SYNCHELP_READ_STRINGM( parentName );
+
+  if ( strcmp(parentName, "")==0 )
+  {
+    setParent( (char*)NULL );
+  }
+  else
+  {
+    setParent( parentName );
+  }
+
+  delete[] parentName;
+
+  int parentMode;
+  SYNCHELP_READ_INT( parentMode );
+  this->setParentMode((PARENT_MODE)parentMode);
+
+  float f1, f2, f3, f4;
+
+  SYNCHELP_READ_FLOAT( f1 );
+  SYNCHELP_READ_FLOAT( f2 );
+  SYNCHELP_READ_FLOAT( f3 );
+  this->setRelCoor( f1, f2, f3 );
+
+
+  SYNCHELP_READ_FLOAT( f1 );
+  SYNCHELP_READ_FLOAT( f2 );
+  SYNCHELP_READ_FLOAT( f3 );
+  SYNCHELP_READ_FLOAT( f4 );
+  this->setRelDir( Quaternion( Vector(f2, f3, f4), f1 ) );
+
+  int n;
+  char * childName;
+
+  PRINTF(0)("JKLO %d %d %d %d\n", data[__synchelp_read_i], data[__synchelp_read_i+1], data[__synchelp_read_i+2], data[__synchelp_read_i+3]);
+  SYNCHELP_READ_INT( n );
+  PRINTF(0)("read %s:n=%d\n", this->getName(), n);
+
+  for (int i = 0; i<n; i++)
+  {
+    SYNCHELP_READ_STRINGM( childName );
+    PRINTF(0)("RCVD CHILD = %s\n", childName);
+    addChild( childName );
+    delete childName;
+    childName = NULL;
+  }
+
+  return SYNCHELP_READ_N;
+}
+
+/**
+ * data copied in data will bee sent to another host
+ * @param data pointer to data
+ * @param maxLength max length of data
+ * @return the number of bytes writen
+ */
+int PNode::readState( byte * data, int maxLength )
+{
+  SYNCHELP_WRITE_BEGIN();
+
+  SYNCHELP_WRITE_FKT( BaseObject::readState );
+
+  if ( this->parent )
+  {
+    SYNCHELP_WRITE_STRING( parent->getName() );
+  }
+  else
+  {
+    SYNCHELP_WRITE_STRING( "" );
+  }
+
+  SYNCHELP_WRITE_INT( this->parentMode );
+
+  SYNCHELP_WRITE_FLOAT( this->relCoordinate.x );
+  SYNCHELP_WRITE_FLOAT( this->relCoordinate.y );
+  SYNCHELP_WRITE_FLOAT( this->relCoordinate.z );
+
+  SYNCHELP_WRITE_FLOAT( this->relDirection.w );
+  SYNCHELP_WRITE_FLOAT( this->relDirection.v.x );
+  SYNCHELP_WRITE_FLOAT( this->relDirection.v.y );
+  SYNCHELP_WRITE_FLOAT( this->relDirection.v.z );
+
+  int n = children.size();
+
+  //check if camera is in children
+  for (std::list<PNode*>::const_iterator it = children.begin(); it!=children.end(); it++)
+  {
+    if ( (*it)->isA(CL_CAMERA) )
+      n--;
+  }
+  PRINTF(0)("write %s:n=%d\n", this->getName(), n);
+  SYNCHELP_WRITE_INT( n );
+  PRINTF(0)("ASDF %d %d %d %d\n", data[__synchelp_write_i-4], data[__synchelp_write_i-3], data[__synchelp_write_i-2], data[__synchelp_write_i-1]);
+
+  for (std::list<PNode*>::const_iterator it = children.begin(); it!=children.end(); it++)
+  {
+    //dont add camera because there is only one camera attached to local player
+    if ( !(*it)->isA(CL_CAMERA) )
+    {
+      PRINTF(0)("SENDING CHILD: %s\n", (*it)->getName());
+      SYNCHELP_WRITE_STRING( (*it)->getName() );
+    }
+  }
+
+  return SYNCHELP_WRITE_N;
+}
+
+#define __FLAG_COOR 1
+#define __FLAG_ROT  2
+
+#define __OFFSET_POS 1
+#define __OFFSET_ROT 0.05
+
+/**
+ * Writes data from network containing information about the state which has changed
+ * @param data pointer to data
+ * @param length length of data
+ * @param sender hostID of sender
+ */
+int PNode::writeSync( const byte * data, int length, int sender )
+{
+  SYNCHELP_READ_BEGIN();
+
+  if ( this->getHostID()==this->getOwner() )
+  {
+    return SYNCHELP_READ_N;
+  }
+
+  byte flags = 0;
+  SYNCHELP_READ_BYTE( flags );
+  //PRINTF(0)("%s::FLAGS = %d\n", this->getName(), flags);
+
+  float f1, f2, f3, f4;
+
+  if ( flags & __FLAG_COOR )
+  {
+    SYNCHELP_READ_FLOAT( f1 );
+    SYNCHELP_READ_FLOAT( f2 );
+    SYNCHELP_READ_FLOAT( f3 );
+    PRINTF(0)("RCVD COOR: %f %f %f\n", f1, f2, f3);
+    this->setRelCoor( f1, f2, f3 );
+  }
+
+  if ( flags & __FLAG_ROT )
+  {
+    SYNCHELP_READ_FLOAT( f1 );
+    SYNCHELP_READ_FLOAT( f2 );
+    SYNCHELP_READ_FLOAT( f3 );
+    SYNCHELP_READ_FLOAT( f4 );
+    PRINTF(0)("RCVD QUAT: %f %f %f %f\n", f1, f2, f3, f4);
+    //this->setRelDir( Quaternion( Vector(f2, f3, f4), f1 ) );
+    Quaternion q;
+    q.w = f1;
+    q.v.x = f2;
+    q.v.y = f3;
+    q.v.z = f4;
+    this->setAbsDir( q );
+  }
+
+  return SYNCHELP_READ_N;
+}
+
+/**
+ * data copied in data will bee sent to another host
+ * @param data pointer to data
+ * @param maxLength max length of data
+ * @return the number of bytes writen
+ */
+int PNode::readSync( byte * data, int maxLength )
+{
+  SYNCHELP_WRITE_BEGIN();
+
+  if ( this->getHostID()!=this->getOwner() )
+  {
+    return SYNCHELP_WRITE_N;
+  }
+
+  byte flags = 0;
+  if ( fabs( coorx - relCoordinate.x ) > __OFFSET_POS ||
+       fabs( coory - relCoordinate.y ) > __OFFSET_POS ||
+       fabs( coorz - relCoordinate.z ) > __OFFSET_POS )
+    flags |= __FLAG_COOR;
+
+  if ( fabs( rotw - absDirection.w ) > __OFFSET_ROT ||
+       fabs( rotx - absDirection.v.x ) > __OFFSET_ROT ||
+       fabs( roty - absDirection.v.y ) > __OFFSET_ROT ||
+       fabs( rotz - absDirection.v.z ) > __OFFSET_ROT )
+    flags |= __FLAG_ROT;
+
+
+  SYNCHELP_WRITE_BYTE( flags );
+  //PRINTF(0)("FLAGS = %d\n", flags);
+
+  if ( flags & __FLAG_COOR )
+  {
+
+    PRINTF(0)("SEND COOR: %f %f %f\n", this->relCoordinate.x, this->relCoordinate.y, this->relCoordinate.z);
+
+    SYNCHELP_WRITE_FLOAT( this->relCoordinate.x );
+    SYNCHELP_WRITE_FLOAT( this->relCoordinate.y );
+    SYNCHELP_WRITE_FLOAT( this->relCoordinate.z );
+
+    coorx = relCoordinate.x;
+    coory = relCoordinate.y;
+    coorz = relCoordinate.z;
+  }
+
+  if ( flags & __FLAG_ROT )
+  {
+
+    PRINTF(0)("SEND QUAT: %f %f %f %f\n", this->absDirection.w, this->absDirection.v.x, this->absDirection.v.y, this->absDirection.v.z);
+
+    SYNCHELP_WRITE_FLOAT( this->absDirection.w );
+    SYNCHELP_WRITE_FLOAT( this->absDirection.v.x );
+    SYNCHELP_WRITE_FLOAT( this->absDirection.v.y );
+    SYNCHELP_WRITE_FLOAT( this->absDirection.v.z );
+
+    rotw = absDirection.w;
+    rotx = absDirection.v.x;
+    roty = absDirection.v.y;
+    rotz = absDirection.v.z;
+  }
+
+  return SYNCHELP_WRITE_N;
+}
Index: branches/network/src/lib/coord/p_node.h
===================================================================
--- branches/network/src/lib/coord/p_node.h	(revision 6636)
+++ branches/network/src/lib/coord/p_node.h	(revision 6636)
@@ -0,0 +1,245 @@
+/*!
+ * @file p_node.h
+ * @brief Definition of THE Parenting Node
+ *
+ *  parenting is how coordinates are handled in orxonox, meaning, that all coordinates
+ *  are representet relative to another parent node. this nodes build a parenting
+ *  tree of one-sided references (from up to down referenced).
+ *  Every node manages itself a list of childrens (of whos it is parent - easy...).
+ *
+ *  absCoordinate, absDirection have to be recalculated as soon as there was a change in
+ *  place or ortientation. this is only the case if
+ *  o bRelCoorChanged is true (so moved)
+ *  o bRelDirChanged is true (so changed)
+ *  this conditions make it cheaper to recalculate the tree (reduces redundant work).
+ */
+
+
+#ifndef _P_NODE_H
+#define _P_NODE_H
+
+#include "base_object.h"
+#include "stdincl.h"
+#include "synchronizeable.h"
+
+#include "vector.h"
+#include "quaternion.h"
+#include <list>
+
+// FORWARD DECLARATION
+class TiXmlElement;
+
+#define PNODE_ITERATION_DELTA    .001
+
+//! Parental linkage modes
+typedef enum
+{
+  // PARENTAL FOLLOWING
+  PNODE_LOCAL_ROTATE                   = 0x0001,    //!< Rotates all the children around their centers.
+  PNODE_ROTATE_MOVEMENT                = 0x0002,    //!< Moves all the children around the center of their parent, without the rotation around their own centers.
+
+  PNODE_MOVEMENT                       = 0x0004,    //!< Moves all children along with the parent.
+  // special linkage modes
+  PNODE_ALL                            = 0x0003,    //!< Moves all children around the center of their parent, and also rotates their centers
+  PNODE_ROTATE_AND_MOVE                = 0x0005,    //!< Rotates all children around their axis, and moves them as the Parent Moves, but does not rotate around the center of their parent.
+
+
+  // REPARENTING
+  PNODE_REPARENT_TO_NULL               = 0x0010,    //!< Reparents to the Null, if the Parent is Removed. Meaning the Node wont have a parent anymore.
+  PNODE_REPARENT_TO_PARENTS_PARENT     = 0x0020,    //!< Reparents the Node to the parents (old) parent it the parent gets removed.
+  /////////////////////////////////////////////     //  ELSE: Reparents to the NullParent.
+  PNODE_REPARENT_DELETE_CHILDREN       = 0x0040,    //!< Deletes the Children of the node when This Node is Removed. (Use with care).
+  /// FIXME
+   PNODE_REPARENT_KEEP_POSITION         = 0x0080,    //!< Tries to keep the Position if the Node is reparented.
+
+
+  // DELETION
+  PNODE_PROHIBIT_CHILD_DELETE          = 0x0100,    //!< Prohibits the Children from being deleted if this Node gets deleted.
+  PNODE_PROHIBIT_DELETE_WITH_PARENT    = 0x0200,    //!< Prohibits the Node to be deleted if the Parent is. Child will be reparented according to the Repaenting-Rules
+  PNODE_REPARENT_CHILDREN_ON_REMOVE    = 0x0400,    //!< Reparents the Children of the Node if the Node gets Removed.
+  PNODE_REPARENT_ON_PARENTS_REMOVE     = 0x0800,    //!< The Node gets Reparented if its Parent gets removed. Child will be reparented according to the Reparenting-Rules.
+
+  // VISIBILITY/ACTIVITY
+  PNODE_HIDE_CHILDREN_IF_HIDDEN        = 0x1000,    //!< Prohibits the Children from being drawn if this node isn't visible. (used for Draw))
+  PNODE_HIDE_IF_PARENT_HIDDEN          = 0x2000,    //!< Prohibits the node from being drawn if the Parent is invisible.
+  PNODE_UPDATE_CHILDREN_IF_INACTIVE    = 0x4000,    //!< Updates the Children of this Node even if the Parent is Inactive (note if this's parent is inactive children won't be updated.)
+  PNODE_STATIC_NODE                    = 0x8000,    //!< Used for nodes that do not have any moving children, and that do not move.
+
+} PARENT_MODE;
+
+//! The default mode of the translation-binding.
+#define PNODE_PARENT_MODE_DEFAULT PNODE_ALL | \
+                                  PNODE_REPARENT_KEEP_POSITION
+
+
+//! Patent Node is a Engine to calculate the position of an Object in respect to the position of its parent.
+class PNode : virtual public BaseObject, virtual public Synchronizeable {
+ public:
+  PNode (PNode* parent = PNode::getNullParent(), long nodeFlags = PNODE_PARENT_MODE_DEFAULT);
+  virtual ~PNode ();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void init();
+
+  // ACTIVATION //
+  inline void activateNode() { this->bActive = this->bRelCoorChanged = this->bRelDirChanged = true; };
+  inline void deactivateNode() { this->bActive = false; };
+  inline bool getNodeActiveState() { return this->bActive; };
+
+  // POSITION //
+  void setRelCoor (const Vector& relCoord);
+  void setRelCoor (float x, float y, float z);
+  void setRelCoorSoft(const Vector& relCoordSoft, float bias = 1.0);
+  void setRelCoorSoft(float x, float y, float z, float bias = 1.0);
+  /** @returns the relative position */
+  inline const Vector& getRelCoor () const { return this->prevRelCoordinate; };
+  /** @returns the Relative Coordinate Destination */
+  inline const Vector& getRelCoorSoft2D() const { return (this->toCoordinate)? *this->toCoordinate : this->relCoordinate; };
+  void setAbsCoor (const Vector& absCoord);
+  void setAbsCoor (float x, float y, float z);
+  void setAbsCoorSoft(const Vector& absCoordSoft, float bias = 1.0);
+  void setAbsCoorSoft(float x, float y, float z, float bias = 1.0);
+  /** @returns the absolute position */
+  inline const Vector& getAbsCoor () const { return this->absCoordinate; };
+  void shiftCoor (const Vector& shift);
+  void shiftCoor (float x, float y, float z) { this->shiftCoor(Vector(x, y, z)); };
+
+  // SPEED //
+  /** @returns the Speed of the Node */
+  inline float getSpeed() const { return this->velocity.len(); };
+  /** @returns the Velocity of the Node */
+  inline const Vector& getVelocity() const { return this->velocity; };
+
+
+  // ROTATION //
+  void setRelDir (const Quaternion& relDir);
+  void setRelDir (float x, float y, float z);
+  void setRelDirSoft(const Quaternion& relDirSoft, float bias = 1.0);
+  void setRelDirSoft(float x, float y, float z, float bias = 1.0);
+  /** @returns the relative Direction */
+  inline const Quaternion& getRelDir () const { return this->prevRelDirection; };
+  /** @returns the Relative Directional Destination */
+  inline const Quaternion& getRelDirSoft2D() const { return (this->toDirection)? *this->toDirection : this->relDirection; };
+  /** @returns a Vector pointing into the relative Direction */
+  inline Vector getRelDirV() const { return this->prevRelDirection.apply(Vector(0,1,0)); };
+  void setAbsDir (const Quaternion& absDir);
+  void setAbsDir (float x, float y, float z);
+  void setAbsDirSoft(const Quaternion& absDirSoft, float bias = 1.0);
+  void setAbsDirSoft(float x, float y, float z, float bias = 1.0);
+  void shiftDir (const Quaternion& shift);
+  /** @returns the absolute Direction */
+  inline const Quaternion& getAbsDir () const { return this->absDirection; };
+  /** @returns a Vector pointing into the absolute Direction */
+  inline Vector getAbsDirV() const { return this->absDirection.apply(Vector(0,1,0)); };
+  /** @returns A Vector pointing into the forward direction (X) of the Node */
+  inline Vector getAbsDirX() const { return this->absDirection.apply(Vector(1,0,0)); };
+  /** @returns A Vector pointing into the upward direction (Y) of the Node */
+  inline Vector getAbsDirY() const { return this->absDirection.apply(Vector(0,1,0)); };
+  /** @returns A Vector pointing into the right direction (Z) of the Node */
+  inline Vector getAbsDirZ() const { return this->absDirection.apply(Vector(0,0,1)); };
+
+
+  // PARENTING //
+  void addChild (PNode* child);
+  void addChild (const char* childName);
+  void removeChild (PNode* child);
+  void removeNode();
+
+  /** @param parent the new parent of this node */
+  inline void setParent (PNode* parent) { parent->addChild(this); };
+  void setParent (const char* parentName);
+  /** @returns the parent of this PNode */
+  inline PNode* getParent () const { return this->parent; };
+  /** @returns the List of Children of this PNode */
+  const std::list<PNode*>& getNodesChildren() const { return this->children; };
+
+  void setParentSoft(PNode* parentNode, float bias = 1.0);
+  void setParentSoft(const char* parentName, float bias = 1.0);
+
+  // PARENTING_MODE AND OTHER FLAGS //
+  void setParentMode (PARENT_MODE parentMode);
+  void setParentMode (const char* parentingMode);
+  /** @returns the Parenting mode of this node */
+  int getParentMode() const { return 0x000f & this->parentMode; };
+
+  void addNodeFlags(unsigned short nodeFlags);
+  void removeNodeFlags(unsigned short nodeFlags);
+
+  // NULL_PARENT //
+  /** @returns the NullParent, the (main) ROOT of the PNode Tree. If it does not yet exist, it will be created. */
+  static PNode* getNullParent()  { return (PNode::nullParent != NULL)? PNode::nullParent : PNode::createNullParent(); };
+
+  // UPDATING //
+  void updateNode (float dt);
+
+  // DEBUG //
+  void countChildNodes(int& nodes) const;
+  void debugNodeSC (unsigned int depth = 1, unsigned int level = 0) { this->debugNode(depth, level); };
+  void debugNode (unsigned int depth = 1, unsigned int level = 0) const;
+  void debugDraw(unsigned int depth = 1, float size = 1.0, const Vector& color = Vector(1, 0, 0), unsigned int level = 0) const;
+
+  // HELPER_FUNCTIONS //
+  static const char* parentingModeToChar(int parentingMode);
+  static PARENT_MODE charToParentingMode(const char* parentingMode);
+
+  int       writeState(const byte* data, int length, int sender);
+  int       readState(byte* data, int maxLength );
+  int       writeSync(const byte* data, int length, int sender);
+  int       readSync(byte* data, int maxLength );
+
+ private:
+  /** tells the child that the parent's Coordinate has changed */
+  inline void parentCoorChanged () { this->bRelCoorChanged = true; }
+  /** tells the child that the parent's Direction has changed */
+  inline void parentDirChanged () { this->bRelDirChanged = true; }
+  /** @returns the last calculated coordinate */
+  inline Vector getLastAbsCoor() { return this->lastAbsCoordinate; }
+
+  static PNode* createNullParent();
+  void reparent();
+  bool checkIntegrity(const PNode* checkParent) const;
+  void eraseChild(PNode* child);
+
+ private:
+  bool               bRelCoorChanged;    //!< If Relative Coordinate has changed since last time we checked
+  bool               bRelDirChanged;     //!< If Relative Direction has changed since last time we checked
+
+  Vector             relCoordinate;      //!< coordinates relative to the parent
+  Vector             absCoordinate;      //!< absolute coordinates in the world ( from (0,0,0) )
+  Quaternion         relDirection;       //!< direction relative to the parent
+  Quaternion         absDirection;       //!< absolute direvtion in the world ( from (0,0,1) )
+
+  Vector             prevRelCoordinate;  //!< The last Relative Coordinate from the last update-Cycle.
+  Vector             lastAbsCoordinate;  //!< this is used for speedcalculation, it stores the last coordinate
+  Quaternion         prevRelDirection;   //!< The last Relative Direciton from the last update-Cycle.
+//  Quaternion         lastAbsDirection;
+
+  Vector             velocity;           //!< Saves the velocity.
+
+  Vector*            toCoordinate;       //!< a position to which to iterate. (This is used in conjunction with setParentSoft.and set*CoorSoft)
+  Quaternion*        toDirection;        //!< a direction to which to iterate. (This is used in conjunction with setParentSoft and set*DirSoft)
+  float              bias;               //!< how fast to iterate to the given position (default is 1)
+  float              toStep;
+
+  PNode*             parent;             //!< a pointer to the parent node.
+  std::list<PNode*>  children;           //!< list of the children of this PNode.
+
+  bool               bActive;            //!< If the Node is Active (for cutting off the rest of the tree in update).
+  unsigned short     parentMode;         //!< the mode of the binding
+
+
+  static PNode*      nullParent;         //!< The ROOT of the main PNode Tree.
+
+  private:
+    float coorx;
+    float coory;
+    float coorz;
+
+    float rotw;
+    float rotx;
+    float roty;
+    float rotz;
+};
+
+#endif /* _P_NODE_H */
Index: branches/network/src/lib/data/data_tank.h
===================================================================
--- branches/network/src/lib/data/data_tank.h	(revision 6636)
+++ branches/network/src/lib/data/data_tank.h	(revision 6636)
@@ -0,0 +1,33 @@
+/*!
+ * @file data_tank.h
+ *  container for all data and data loadings. Its absolutily abstract and therefore generic.
+ *  if there is something to load, this class will serve as a good base class since it
+ *  gives you a basic structure for data loading
+ */
+
+#ifndef _DATA_TANK_H
+#define _DATA_TANK_H
+
+
+#include "base_object.h"
+#include "error.h"
+
+
+//! The DataTank
+class DataTank : public BaseObject
+{
+
+  public:
+    DataTank() {}
+    virtual ~DataTank() {}
+
+    /** initializes the DataTank to be able to load the data */
+    virtual ErrorMessage init() {}
+    /** loads the data into the DataTank @param root is the xml root parameter for for loadParams() connection */
+    virtual ErrorMessage loadData(TiXmlElement* root = NULL) {}
+    /** unloads the data again from the DataTank */
+    virtual ErrorMessage unloadData() {}
+};
+
+
+#endif /* _DATA_TANK_H */
Index: branches/network/src/lib/event/Makefile.am
===================================================================
--- branches/network/src/lib/event/Makefile.am	(revision 6636)
+++ branches/network/src/lib/event/Makefile.am	(revision 6636)
@@ -0,0 +1,18 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXevent.a 
+
+libORXevent_a_SOURCES = event_handler.cc \
+			event_listener.cc \
+			key_mapper.cc \
+			key_names.cc
+
+
+noinst_HEADERS = event.h \
+		 event_handler.h \
+		 event_listener.h \
+		 key_mapper.h \
+		 key_names.h \
+		 event_def.h
+
Index: branches/network/src/lib/event/event.h
===================================================================
--- branches/network/src/lib/event/event.h	(revision 6636)
+++ branches/network/src/lib/event/event.h	(revision 6636)
@@ -0,0 +1,41 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+
+   Benjamin Grauer: added SDL_ResizeEvent resize (for the GraphicsEngine)
+*/
+
+/*!
+ * @file event.h
+ * an abstract event
+ */
+
+#ifndef _EVENT_H
+#define _EVENT_H
+
+#include "sdlincl.h"
+
+//! An abstract event class
+struct Event {
+  int      type;                        //!< the type field
+  bool     bPressed;                    //!< is true, if the button/mouse was pressed, false if released
+
+  Uint16   x;                           //!< x coordinate
+  Uint16   y;                           //!< y coordinate
+  Sint16   xRel;                        //!< relative x movement to last point
+  Sint16   yRel;                        //!< relative y movement to last point
+
+  SDL_ResizeEvent resize;
+};
+
+#endif /* _EVENT_H */
Index: branches/network/src/lib/event/event_def.h
===================================================================
--- branches/network/src/lib/event/event_def.h	(revision 6636)
+++ branches/network/src/lib/event/event_def.h	(revision 6636)
@@ -0,0 +1,56 @@
+/*!
+ * @file event_def.h
+ * some central definitions
+*/
+
+#ifndef _EVENT_DEF_H
+#define _EVENT_DEF_H
+
+#ifdef HAVE_SDL_H
+#include "SDL_keysym.h"
+#else
+#include "SDL/SDL_keysym.h"
+#endif
+#include "stdincl.h"
+
+
+//! these are the extended event types, that are not included in SDL_keysym
+typedef enum extEventTyes
+{
+  EV_MOUSE_BUTTON_LEFT           = SDLK_LAST + 1,
+  EV_MOUSE_BUTTON_MIDDLE,
+  EV_MOUSE_BUTTON_RIGHT,
+  EV_MOUSE_BUTTON_WHEELUP,
+  EV_MOUSE_BUTTON_WHEELDOWN,
+  EV_MOUSE_MOTION,
+  EV_JOY_AXIS_MOTION,
+  EV_JOY_BALL_MOTION,
+  EV_JOY_HAT_MOTION,
+  EV_JOY_BUTTON,
+
+  EV_VIDEO_RESIZE,
+
+  EV_MAIN_QUIT,
+
+  EV_UNKNOWN,
+
+  EV_NUMBER
+};
+
+
+//! this is an enumeration of all states of the event_handler/game
+typedef enum elState
+  {
+    ES_NULL         = -1,
+    ES_GAME         = 0,       //!< the state during the game plays
+    ES_GAME_MENU    = 1,       //!< state when the menu is called during game
+    ES_MENU         = 2,       //!< orxonox menu state
+    ES_SHELL        = 3,       //!< if we are in shell Modus
+
+    ES_ALL          = 4,       //!< you want to register events for all states
+
+    ES_NUMBER       = 5,       //!< the number of states
+  };
+
+
+#endif /* _EVENT_DEF_H */
Index: branches/network/src/lib/event/event_handler.cc
===================================================================
--- branches/network/src/lib/event/event_handler.cc	(revision 6636)
+++ branches/network/src/lib/event/event_handler.cc	(revision 6636)
@@ -0,0 +1,386 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_EVENT
+
+#include "event_handler.h"
+
+#include "event_listener.h"
+#include "event.h"
+#include "key_mapper.h"
+
+#include "compiler.h"
+#include "debug.h"
+#include "class_list.h"
+
+#include "t_stack.h"
+
+using namespace std;
+
+
+/**
+ *  standard constructor
+*/
+EventHandler::EventHandler ()
+{
+  this->setClassID(CL_EVENT_HANDLER, "EventHandler");
+  this->setName("EventHandler");
+
+  SDL_InitSubSystem(SDL_INIT_JOYSTICK);
+  SDL_InitSubSystem(SDL_INIT_EVENTTHREAD);
+  SDL_SetEventFilter(EventHandler::eventFilter);
+
+
+  /* now initialize them all to zero */
+  this->flush(ES_ALL);
+  this->withUNICODE(false);
+  this->grabEvents(false);
+
+  this->state = ES_GAME;
+  this->keyMapper = NULL;
+  this->stateStack = NULL;
+
+}
+
+
+/**
+ *  the singleton reference to this class
+*/
+EventHandler* EventHandler::singletonRef = NULL;
+
+
+/**
+ *  standard deconstructor
+
+*/
+EventHandler::~EventHandler ()
+{
+  for(int i = 0; i < ES_NUMBER; ++i)
+  {
+    for(int j = 0; j < EV_NUMBER; ++j)
+    {
+      if( this->listeners[i][j] != NULL)
+      {
+        PRINTF(2)("forgot to unsubscribe an EventListener!\n");// %s!\n", this->listeners[i][j]->getName());
+      }
+    }
+  }
+  delete this->stateStack;
+  delete this->keyMapper;
+
+  SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
+
+  EventHandler::singletonRef = NULL;
+}
+
+
+/**
+ *  initializes the event handler
+ *
+ * this has to be called before the use of the event handler
+*/
+void EventHandler::init(IniParser* iniParser)
+{
+  if (this->keyMapper == NULL)
+  {
+    this->keyMapper = new KeyMapper();
+    this->keyMapper->loadKeyBindings(iniParser);
+  }
+  if (this->stateStack == NULL)
+    this->stateStack = new tStack<short>;
+}
+
+/**
+ * pushes the current State in the State-stack, and selects state
+ * @param state the new State to set
+ */
+void EventHandler::pushState(elState state)
+{
+  if (likely(state != ES_NULL && state != ES_ALL && this->stateStack != NULL))
+  {
+    this->stateStack->push(this->state);
+    this->setState(state);
+  }
+  else
+  {
+    PRINTF(2)("unable to push State\n");
+  }
+}
+
+/**
+ * this removes the topmost stack-entry and select the underlying one
+ * @returns the next stack-entry
+ */
+elState EventHandler::popState()
+{
+  if (unlikely(this->stateStack == NULL))
+    return ES_NULL;
+  elState state = (elState)this->stateStack->pop();
+  if (state == ES_NULL)
+  {
+    PRINTF(2)("No more states availiable. (unable to pop state)\n");
+    return ES_NULL;
+  }
+  else
+  {
+    this->setState(state);
+    return state;
+  }
+}
+
+
+/**
+ *  subscribe to an event
+ * @param el: the event listener that wants to subscribe itself, the listener that will be called when the evetn occures
+ * @param state: for which the listener wants to receive events
+ * @param eventType: the event type that wants to be listened for.
+
+   This is one of the most important function of the EventHandler. If you would like to subscribe for more
+   than one state, you have to subscribe for each state again. If you want to subscribe for all states, use
+   state = ES_ALL, which will subscribe your listener for all states together.
+ */
+void EventHandler::subscribe(EventListener* el, elState state, int eventType)
+{
+  PRINTF(4)("Subscribing event type: %i\n", eventType);
+  if( state == ES_ALL )
+    {
+      for(unsigned int i = 0; i < ES_NUMBER; i++)
+        if( likely(this->listeners[i][eventType] == NULL))
+          this->listeners[i][eventType] = el;
+        else
+          PRINTF(2)("%s of class %s tried to subscribe to event %i @ state %i but this event has already been subscribed\n", el->getName(), el->getClassName(), eventType, state);
+    }
+  else
+    if( likely(this->listeners[state][eventType] == NULL))
+      {
+        this->listeners[state][eventType] = el;
+      }
+    else
+      PRINTF(2)("% of class %s tried to subscribe to event %i @ state %i but this event has already been subscribed\n", el->getName(), el->getClassName(), eventType, state);
+}
+
+
+/**
+ *  unsubscribe from the EventHandler
+ * @param state: the stat in which it has been subscribed
+ * @param eventType: the event, that shall be unsubscribed
+
+   if you want to unsubscribe an event listener from all subscribed events, just use the
+   unsubscribe(EventListener* el, elState state) function
+*/
+void EventHandler::unsubscribe(elState state, int eventType)
+{
+  PRINTF(4)("Unsubscribing event type nr: %i\n", eventType);
+  if (state == ES_ALL)
+    for (unsigned int i = 0; i < ES_NUMBER; i++)
+      this->listeners[i][eventType] = NULL;
+  else
+    this->listeners[state][eventType] = NULL;
+}
+
+
+/**
+ * unsubscribe all events from a specific listener
+ * @param el: the listener that wants to unsubscribe itself
+ * @param state: the state in which the events shall be unsubscribed
+
+*/
+void EventHandler::unsubscribe(EventListener* el, elState state)
+{
+  if( el == NULL || state >= ES_NUMBER)
+    return;
+  if( state == ES_ALL)
+    {
+      for(unsigned int i = 0; i < ES_NUMBER; i++)
+        {
+          for(unsigned int j = 0; j < EV_NUMBER; j++)
+            {
+              if( this->listeners[i][j] == el )
+                this->listeners[i][j] = NULL;
+            }
+        }
+    }
+  else
+    {
+      for(int j = 0; j < EV_NUMBER; j++)
+        {
+          if( this->listeners[state][j] == el )
+            this->listeners[state][j] = NULL;
+        }
+    }
+}
+
+
+/**
+ * flush all registered events
+ * @param state: a specific state
+*/
+void EventHandler::flush(elState state)
+{
+  if( state == ES_ALL)
+    {
+      for(int i = 0; i < ES_NUMBER; ++i)
+        {
+          for(int j = 0; j < EV_NUMBER; ++j)
+            {
+              this->listeners[i][j] = NULL;
+            }
+        }
+    }
+  else
+    {
+      for(int j = 0; j < EV_NUMBER; ++j)
+        {
+          this->listeners[state][j] = NULL;
+        }
+    }
+}
+
+
+void EventHandler::withUNICODE(bool enableUNICODE)
+{
+  SDL_EnableUNICODE(enableUNICODE);
+  this->bUNICODE = enableUNICODE;
+}
+
+void EventHandler::grabEvents(bool grabEvents)
+{
+  this->eventsGrabbed = grabEvents;
+  if(!grabEvents)
+    SDL_WM_GrabInput(SDL_GRAB_OFF);
+  else
+    ;//SDL_WM_GrabInput(SDL_GRAB_ON);
+}
+
+/**
+ *  core function of event handler: receives all events from SDL
+
+   The event from the SDL framework are collected here and distributed to all listeners.
+*/
+void EventHandler::process()
+{
+  SDL_Event event;
+  Event ev;
+  EventListener* listener = NULL;
+  while( SDL_PollEvent (&event))
+    {
+      switch( event.type)
+        {
+        case SDL_KEYDOWN:
+          ev.bPressed = true;
+          ev.type = event.key.keysym.sym;
+          if (unlikely(this->bUNICODE))
+              ev.x = event.key.keysym.unicode;
+          break;
+        case SDL_KEYUP:
+          ev.bPressed = false;
+          ev.type = event.key.keysym.sym;
+          if (unlikely(this->bUNICODE))
+            ev.x = event.key.keysym.unicode;
+          break;
+        case SDL_MOUSEMOTION:
+          ev.bPressed = false;
+          ev.type = EV_MOUSE_MOTION;
+          ev.x = event.motion.x;
+          ev.y = event.motion.y;
+          ev.xRel = event.motion.xrel;
+          ev.yRel = event.motion.yrel;
+          break;
+        case SDL_MOUSEBUTTONUP:
+          ev.bPressed = false;
+          ev.type = event.button.button + SDLK_LAST;
+          break;
+        case SDL_MOUSEBUTTONDOWN:
+          ev.bPressed = true;
+          ev.type = event.button.button + SDLK_LAST;
+          break;
+        case SDL_JOYAXISMOTION:
+          ev.bPressed = false;
+          ev.type = EV_JOY_AXIS_MOTION;
+          break;
+        case SDL_JOYBALLMOTION:
+          ev.bPressed = false;
+          ev.type = EV_JOY_BALL_MOTION;
+          break;
+        case SDL_JOYHATMOTION:
+          ev.bPressed = false;
+          ev.type = EV_JOY_HAT_MOTION;
+          break;
+        case SDL_JOYBUTTONDOWN:
+          ev.bPressed = true;
+          ev.type = EV_JOY_BUTTON;
+          break;
+        case SDL_JOYBUTTONUP:
+          ev.bPressed = true;
+          ev.type = EV_JOY_BUTTON;
+          break;
+        case SDL_VIDEORESIZE:
+          ev.resize = event.resize;
+          ev.type = EV_VIDEO_RESIZE;
+          break;
+        case SDL_QUIT:
+          ev.type = EV_MAIN_QUIT;
+          break;
+        default:
+          ev.type = EV_UNKNOWN;
+          break;
+        }
+
+      /* small debug routine: shows all events dispatched by the event handler */
+      PRINT(4)("\n==========================| EventHandler::process () |===\n");
+      PRINT(4)("=  Got Event nr %i, for state %i", ev.type, this->state);
+
+      listener = this->listeners[this->state][ev.type];
+      if( listener != NULL)
+        {
+          PRINT(4)("=  Event dispatcher msg: This event has been consumed\n");
+          PRINT(4)("=======================================================\n");
+          listener->process(ev);
+        }
+      else
+        {
+          PRINT(4)("=  Event dispatcher msg: This event has NOT been consumed\n");
+          PRINT(4)("=======================================================\n");
+        }
+    }
+}
+
+
+int EventHandler::eventFilter(const SDL_Event *event)
+{
+  if (event->type == SDL_KEYDOWN &&  event->key.keysym.sym == SDLK_TAB && SDL_GetKeyState(NULL)[SDLK_LALT])
+  {
+    printf("Not sending event to the WindowManager\n");
+
+    EventHandler::getInstance()->grabEvents(false);
+    return 0;
+  }
+  return 1;
+}
+
+/**
+ * outputs some nice information about the EventHandler
+ */
+void EventHandler::debug() const
+{
+  PRINT(0)("===============================\n");
+  PRINT(0)(" EventHandle Debug Information \n");
+  PRINT(0)("===============================\n");
+  for(int i = 0; i < ES_NUMBER; ++i)
+    for(int j = 0; j < EV_NUMBER; ++j)
+      if( this->listeners[i][j] != NULL)
+        PRINT(0)("Event %d of State %d subscribed to %s (%p)\n", j, i, this->listeners[i][j]->getName(), this->listeners[i][j]);
+  PRINT(0)("============================EH=\n");
+}
Index: branches/network/src/lib/event/event_handler.h
===================================================================
--- branches/network/src/lib/event/event_handler.h	(revision 6636)
+++ branches/network/src/lib/event/event_handler.h	(revision 6636)
@@ -0,0 +1,69 @@
+/*!
+ * @file event_handler.h
+ * Definition of the EventHandler
+ *
+ */
+
+#ifndef _EVENT_HANDLER_H
+#define _EVENT_HANDLER_H
+
+#include "base_object.h"
+#include "key_mapper.h"
+#include "event_def.h"
+
+// FORWARD DECLARATION
+class EventListener;
+template<class T> class tStack;
+class IniParser;
+
+//! The one Event Handler from Orxonox
+class EventHandler : public BaseObject {
+
+ public:
+  virtual ~EventHandler();
+  /** @returns a Pointer to the only object of this Class */
+  inline static EventHandler* getInstance() { if (!singletonRef) singletonRef = new EventHandler();  return singletonRef; };
+  void init(IniParser* iniParser);
+
+  /** @param state: to which the event handler shall change */
+  inline void setState(elState state) { this->state = state; };
+  /** @returns the current state */
+  inline elState getState() const { return this->state; };
+
+  void pushState(elState state);
+  elState popState();
+
+  void subscribe(EventListener* el, elState state, int eventType);
+  void unsubscribe(elState state, int eventType);
+  void unsubscribe(EventListener* el, elState state = ES_ALL);
+  void flush(elState state);
+  /** @returns true, if the @param state has @param eventType subscribed?? */
+  inline bool isSubscribed(elState state, int eventType) { return(listeners[state][eventType] == NULL)?false:true; };
+
+
+  void withUNICODE(bool enableUNICODE);
+  void grabEvents(bool grabEvents);
+  bool grabbedEvents() const { return this->eventsGrabbed; };
+
+  void process();
+
+  static int eventFilter(const SDL_Event *event);
+  void debug() const;
+
+ private:
+  EventHandler();
+
+ private:
+  static EventHandler*       singletonRef;                    //!< the singleton reference
+
+  EventListener*             listeners[ES_NUMBER][EV_NUMBER]; //!< a list of registered listeners.
+  elState                    state;                           //!< the state of the event handlder.
+  tStack<short>*             stateStack;                      //!< a stack for the States we are in.
+  KeyMapper*                 keyMapper;                       //!< reference to the key mapper.
+
+  bool                       bUNICODE;                        //!< If unicode should be enabled.
+  bool                       eventsGrabbed;                   //!< If the events should be grabbed
+};
+
+
+#endif /* _EVENT_HANDLER_H */
Index: branches/network/src/lib/event/event_listener.cc
===================================================================
--- branches/network/src/lib/event/event_listener.cc	(revision 6636)
+++ branches/network/src/lib/event/event_listener.cc	(revision 6636)
@@ -0,0 +1,40 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_EVENT
+
+#include "event_listener.h"
+#include "event_handler.h"
+
+using namespace std;
+
+
+/**
+ *  standard constructor
+*/
+EventListener::EventListener ()
+{
+  this->setClassID(CL_EVENT_LISTENER, "EventListener");
+}
+
+
+/**
+ *  standard deconstructor
+*/
+EventListener::~EventListener ()
+{
+  /* unsubscribes itself from the event listener */
+  EventHandler::getInstance()->unsubscribe(this, ES_ALL);
+}
Index: branches/network/src/lib/event/event_listener.h
===================================================================
--- branches/network/src/lib/event/event_listener.h	(revision 6636)
+++ branches/network/src/lib/event/event_listener.h	(revision 6636)
@@ -0,0 +1,26 @@
+/*!
+ * @file event_listener.h
+ *  Definition of an event listener base class
+*/
+
+#ifndef _EVENT_LISTENER_H
+#define _EVENT_LISTENER_H
+
+#include "base_object.h"
+#include "event.h"
+
+//! A class for event listener
+class EventListener : virtual public BaseObject {
+
+ public:
+  EventListener();
+  virtual ~EventListener();
+
+  /**
+   * abstract function that processes events from the handler
+   * @param event: the event
+   */
+  virtual void process(const Event &event) = 0;
+};
+
+#endif /* _EVENT_LISTENER_H */
Index: branches/network/src/lib/event/key_mapper.cc
===================================================================
--- branches/network/src/lib/event/key_mapper.cc	(revision 6636)
+++ branches/network/src/lib/event/key_mapper.cc	(revision 6636)
@@ -0,0 +1,226 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: Christian Meyer
+
+   This code was inspired by the command_node.cc code from Christian Meyer in revision
+   4386 and earlier.
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_EVENT
+
+#include "key_mapper.h"
+
+#include "event_def.h"
+
+#include "globals.h"
+#include "parser/ini_parser/ini_parser.h"
+#include "key_names.h"
+#include "debug.h"
+
+
+using namespace std;
+
+
+/* initialize all variables to a reasonable value*/
+int KeyMapper::PEV_UP                = EV_UNKNOWN;
+int KeyMapper::PEV_DOWN              = EV_UNKNOWN;
+int KeyMapper::PEV_LEFT              = EV_UNKNOWN;
+int KeyMapper::PEV_RIGHT             = EV_UNKNOWN;
+int KeyMapper::PEV_ROLL_LEFT         = EV_UNKNOWN;
+int KeyMapper::PEV_ROLL_RIGHT        = EV_UNKNOWN;
+int KeyMapper::PEV_STRAFE_LEFT       = EV_UNKNOWN;
+int KeyMapper::PEV_STRAFE_RIGHT      = EV_UNKNOWN;
+
+int KeyMapper::PEV_FIRE1             = EV_UNKNOWN;
+int KeyMapper::PEV_FIRE2             = EV_UNKNOWN;
+int KeyMapper::PEV_PREVIOUS_WEAPON   = EV_UNKNOWN;
+int KeyMapper::PEV_NEXT_WEAPON       = EV_UNKNOWN;
+
+int KeyMapper::PEV_VIEW0             = EV_UNKNOWN;
+int KeyMapper::PEV_VIEW1             = EV_UNKNOWN;
+int KeyMapper::PEV_VIEW2             = EV_UNKNOWN;
+int KeyMapper::PEV_VIEW3             = EV_UNKNOWN;
+int KeyMapper::PEV_VIEW4             = EV_UNKNOWN;
+int KeyMapper::PEV_VIEW5             = EV_UNKNOWN;
+
+int KeyMapper::PEV_NEXT_WORLD        = EV_UNKNOWN;
+int KeyMapper::PEV_PREVIOUS_WORLD    = EV_UNKNOWN;
+
+int KeyMapper::PEV_PAUSE             = EV_UNKNOWN;
+int KeyMapper::PEV_QUIT              = EV_UNKNOWN;
+
+
+
+//! this is the mapping array from names to ids: enter all orxonox.conf keys here
+/** @todo use globals.h for this.... everything is done there for those Options,
+ * and you do not have to care about The namings, as they might change
+ */
+orxKeyMapping map[] = {
+  {&KeyMapper::PEV_UP,                   CONFIG_NAME_PLAYER_UP},
+  {&KeyMapper::PEV_DOWN,                 CONFIG_NAME_PLAYER_DOWN},
+  {&KeyMapper::PEV_LEFT,                 CONFIG_NAME_PLAYER_LEFT},
+  {&KeyMapper::PEV_RIGHT,                CONFIG_NAME_PLAYER_RIGHT},
+  {&KeyMapper::PEV_ROLL_LEFT,            CONFIG_NAME_PLAYER_ROLL_RIGHT},
+  {&KeyMapper::PEV_ROLL_RIGHT,           CONFIG_NAME_PLAYER_ROLL_LEFT},
+  {&KeyMapper::PEV_STRAFE_LEFT,          "StrafeLeft"},
+  {&KeyMapper::PEV_STRAFE_RIGHT,         "StrafeRight"},
+
+  {&KeyMapper::PEV_FIRE1,                CONFIG_NAME_PLAYER_FIRE},
+  {&KeyMapper::PEV_FIRE1,                "Fire1"},
+  {&KeyMapper::PEV_FIRE2,                "Fire2"},
+  {&KeyMapper::PEV_NEXT_WEAPON,          CONFIG_NAME_PLAYER_NEXT_WEAPON},
+  {&KeyMapper::PEV_PREVIOUS_WEAPON,      CONFIG_NAME_PLAYER_PREV_WEAPON},
+
+
+  {&KeyMapper::PEV_VIEW0,                CONFIG_NAME_VIEW0},
+  {&KeyMapper::PEV_VIEW1,                CONFIG_NAME_VIEW1},
+  {&KeyMapper::PEV_VIEW2,                CONFIG_NAME_VIEW2},
+  {&KeyMapper::PEV_VIEW3,                CONFIG_NAME_VIEW3},
+  {&KeyMapper::PEV_VIEW4,                CONFIG_NAME_VIEW4},
+  {&KeyMapper::PEV_VIEW5,                CONFIG_NAME_VIEW5},
+
+  {&KeyMapper::PEV_NEXT_WORLD,           CONFIG_NAME_NEXT_WORLD},
+  {&KeyMapper::PEV_PREVIOUS_WORLD,       CONFIG_NAME_PREV_WORLD},
+
+  {&KeyMapper::PEV_PAUSE,                CONFIG_NAME_PAUSE},
+  {&KeyMapper::PEV_QUIT,                 CONFIG_NAME_QUIT},
+  {NULL, NULL}
+};
+
+
+
+/**
+ *  standard constructor
+*/
+KeyMapper::KeyMapper ()
+{
+   this->setClassID(CL_KEY_MAPPER, "KeyMapper");
+}
+
+
+/**
+ *  standard deconstructor
+*/
+KeyMapper::~KeyMapper ()
+{
+}
+
+
+/**
+ *  loads new key bindings from a file
+ * @param filename: The path and name of the file to load the bindings from
+*/
+void KeyMapper::loadKeyBindings (const char* fileName)
+{
+  IniParser parser(fileName);
+  this->loadKeyBindings(&parser);
+}
+
+void KeyMapper::loadKeyBindings(IniParser* iniParser)
+{
+  if( !iniParser->getSection (CONFIG_SECTION_PLAYER "1"))
+  {
+    PRINTF(1)("Could not find key bindings " CONFIG_SECTION_PLAYER"1\n");
+    return;
+  }
+  int* index;
+
+  iniParser->firstVar();
+  while(iniParser->getCurrentName())
+  {
+    PRINTF(3)("Keys: Parsing %s, %s now.\n", iniParser->getCurrentName(), iniParser->getCurrentValue());
+    // map the name to an sdl index
+    index = nameToIndex (iniParser->getCurrentValue());
+    // map the index to a internal name
+    this->mapKeys(iniParser->getCurrentName(), index);
+    iniParser->nextVar();
+  }
+
+
+  // PARSE MISC SECTION
+  if( !iniParser->getSection (CONFIG_SECTION_MISC_KEYS))
+  {
+    PRINTF(1)("Could not find key bindings" CONFIG_SECTION_MISC_KEYS "\n");
+    return;
+  }
+
+  iniParser->firstVar();
+  while(iniParser->getCurrentName())
+  {
+    PRINTF(3)("MISC: Parsing %s, %s now.\n", iniParser->getCurrentName(), iniParser->getCurrentValue());
+    index = nameToIndex (iniParser->getCurrentValue());
+    this->mapKeys(iniParser->getCurrentName(), index);
+    iniParser->nextVar();
+  }
+}
+
+/**
+ *  this function looks up name to key index
+ * @param the name of the button
+*/
+int* KeyMapper::nameToIndex (const char* name)
+{
+  coord[0] = -1;
+  coord[1] = -1;
+  int c;
+  if( (c = keynameToSDLK (name)) != -1) {
+      coord[1] = c;
+      coord[0] = 0;
+    }
+  if( (c = buttonnameToSDLB (name)) != -1) {
+      coord[1] = c;
+      coord[0] = 1;
+    }
+  return coord;
+}
+
+
+/**
+ *  the function maps name to key ids
+ * @param name of the key
+ * @param id of the key
+*/
+void KeyMapper::mapKeys(const char* name, int* index)
+{
+  for( int i = 0; map[i].pValue != NULL; ++i )
+    {
+      if( !strcmp (name, map[i].pName))
+      {
+        if( index[0] == 0)
+        {
+          *map[i].pValue = index[1];
+          PRINTF(4)("Mapping %s to '%s' (id %i)\n", name, SDLKToKeyname(index[1]), index[1]);
+          break;
+        }
+        else {
+          *map[i].pValue = index[1];
+          PRINTF(4)("Mapping %s to '%s' (id %i)\n", name, SDLBToButtonname(index[1]), index[1]);
+          break;
+        }
+      }
+    }
+}
+
+
+/**
+ *  this function gives some debug information about the key mapper class
+*/
+void KeyMapper::debug()
+{
+  PRINT(0)("\n==========================| KeyMapper::debug() |===\n");
+  for(int i = 0; map[i].pValue != NULL; ++i)
+    {
+      PRINT(0)("%s = %i\n",map[i].pName, *map[i].pValue);
+    }
+  PRINT(0)("=======================================================\n");
+}
Index: branches/network/src/lib/event/key_mapper.h
===================================================================
--- branches/network/src/lib/event/key_mapper.h	(revision 6636)
+++ branches/network/src/lib/event/key_mapper.h	(revision 6636)
@@ -0,0 +1,77 @@
+/*!
+ * @file key_mapper.h
+  *  a construct to map player defined keys to SDL keys
+
+*/
+
+#ifndef _KEY_MAPPER_H
+#define _KEY_MAPPER_H
+
+
+#include "base_object.h"
+//#include "event_def.h"
+
+class IniParser;
+
+//! A mapping from key-name to key-id
+typedef struct orxKeyMapping
+{
+  int* pValue;
+  char* pName;
+};
+
+
+//! The map class functionalities
+class KeyMapper : public BaseObject {
+
+ public:
+  KeyMapper();
+  virtual ~KeyMapper();
+
+  void loadKeyBindings(const char* fileName = NULL);
+  void loadKeyBindings(IniParser* iniParser);
+
+  void debug();
+
+ private:
+  int* nameToIndex (const char* name);
+  void mapKeys(const char* name, int* index);
+
+ public:
+  static int PEV_UP;                //!< up button
+  static int PEV_DOWN;              //!< down buttton
+  static int PEV_LEFT;              //!< left button
+  static int PEV_RIGHT;             //!< right button
+
+  static int PEV_ROLL_LEFT;         //!< rolls left
+  static int PEV_ROLL_RIGHT;        //!< rolls right
+
+  static int PEV_STRAFE_LEFT;       //!< strafe left button
+  static int PEV_STRAFE_RIGHT;      //!< strafe right button
+
+  static int PEV_FIRE1;             //!< fire button 1
+  static int PEV_FIRE2;             //!< fire button 2
+  static int PEV_PREVIOUS_WEAPON;   //!< prev weapon button
+  static int PEV_NEXT_WEAPON;       //!< next weapon button
+
+  static int PEV_VIEW0;             //!< view 0 button
+  static int PEV_VIEW1;             //!< view 1 button
+  static int PEV_VIEW2;             //!< view 2 button
+  static int PEV_VIEW3;             //!< view 3 button
+  static int PEV_VIEW4;             //!< view 4 button
+  static int PEV_VIEW5;             //!< view 5 button
+
+  static int PEV_NEXT_WORLD;        //!< next world button
+  static int PEV_PREVIOUS_WORLD;    //!< prev world button
+
+  static int PEV_PAUSE;             //!< pause button
+  static int PEV_QUIT;              //!< quit button
+
+ private:
+  int         coord[2];              //!< temp place to save variables in nameToIndex() function
+};
+
+
+
+
+#endif /* _KEY_MAPPER_H */
Index: branches/network/src/lib/event/key_names.cc
===================================================================
--- branches/network/src/lib/event/key_names.cc	(revision 6636)
+++ branches/network/src/lib/event/key_names.cc	(revision 6636)
@@ -0,0 +1,319 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: ...
+*/
+
+#include "key_names.h"
+#include "event_def.h"
+
+#include "stdincl.h"
+
+#include <string.h>
+
+using namespace std;
+
+int buttonnameToSDLB(const char* name)
+{
+        if( !strcmp (name, "BUTTON_LEFT")) return EV_MOUSE_BUTTON_LEFT;
+        if( !strcmp (name, "BUTTON_MIDDLE")) return EV_MOUSE_BUTTON_MIDDLE;
+        if( !strcmp (name, "BUTTON_RIGHT")) return EV_MOUSE_BUTTON_RIGHT;
+        if( !strcmp (name, "BUTTON_WHEELUP")) return EV_MOUSE_BUTTON_WHEELUP;
+        if( !strcmp (name, "BUTTON_WHEELDOWN")) return EV_MOUSE_BUTTON_WHEELDOWN;
+        return -1;
+}
+
+const char* SDLBToButtonname( int button)
+{
+        if( button == EV_MOUSE_BUTTON_LEFT) return "BUTTON_LEFT";
+        if( button == EV_MOUSE_BUTTON_MIDDLE) return "BUTTON_MIDDLE";
+        if( button == EV_MOUSE_BUTTON_RIGHT) return "BUTTON_RIGHT";
+        if( button == EV_MOUSE_BUTTON_WHEELUP) return "BUTTON_WHEELUP";
+        if( button == EV_MOUSE_BUTTON_WHEELDOWN) return "BUTTON_WHEELDOWN";
+        return "UNKNOWN";
+}
+
+int keynameToSDLK(const char* name)
+{
+        if( !strcmp (name, "BACKSPACE")) return SDLK_BACKSPACE;
+        if( !strcmp (name, "TAB")) return SDLK_TAB;
+        if( !strcmp (name, "CLEAR")) return SDLK_CLEAR;
+        if( !strcmp (name, "RETURN")) return SDLK_RETURN;
+        if( !strcmp (name, "ESCAPE")) return SDLK_ESCAPE;
+        if( !strcmp (name, "SPACE")) return SDLK_SPACE;
+        if( !strcmp (name, "EXCLAIM")) return SDLK_EXCLAIM;
+        if( !strcmp (name, "QUOTEDBL")) return SDLK_QUOTEDBL;
+        if( !strcmp (name, "HASH")) return SDLK_HASH;
+        if( !strcmp (name, "PAUSE")) return SDLK_PAUSE;
+        if( !strcmp (name, "DOLLAR")) return SDLK_DOLLAR;
+        if( !strcmp (name, "AMPERSAND")) return SDLK_AMPERSAND;
+        if( !strcmp (name, "QUOTE")) return SDLK_QUOTE;
+        if( !strcmp (name, "LEFTPAREN")) return SDLK_LEFTPAREN;
+        if( !strcmp (name, "RIGHTPAREN")) return SDLK_RIGHTPAREN;
+        if( !strcmp (name, "ASTERISK")) return SDLK_ASTERISK;
+        if( !strcmp (name, "PLUS")) return SDLK_PLUS;
+        if( !strcmp (name, "COMMA")) return SDLK_COMMA;
+        if( !strcmp (name, "MINUS")) return SDLK_MINUS;
+        if( !strcmp (name, "PERIOD")) return SDLK_PERIOD;
+        if( !strcmp (name, "SLASH")) return SDLK_SLASH;
+        if( !strcmp (name, "0")) return SDLK_0;
+        if( !strcmp (name, "1")) return SDLK_1;
+        if( !strcmp (name, "2")) return SDLK_2;
+        if( !strcmp (name, "3")) return SDLK_3;
+        if( !strcmp (name, "4")) return SDLK_4;
+        if( !strcmp (name, "5")) return SDLK_5;
+        if( !strcmp (name, "6")) return SDLK_6;
+        if( !strcmp (name, "7")) return SDLK_7;
+        if( !strcmp (name, "8")) return SDLK_8;
+        if( !strcmp (name, "9")) return SDLK_9;
+        if( !strcmp (name, "COLON")) return SDLK_COLON;
+        if( !strcmp (name, "SEMICOLON")) return SDLK_SEMICOLON;
+        if( !strcmp (name, "LESS")) return SDLK_LESS;
+        if( !strcmp (name, "EQUALS")) return SDLK_EQUALS;
+        if( !strcmp (name, "GREATER")) return SDLK_GREATER;
+        if( !strcmp (name, "QUESTION")) return SDLK_QUESTION;
+        if( !strcmp (name, "AT")) return SDLK_AT;
+        if( !strcmp (name, "LEFTBRACKET")) return SDLK_LEFTBRACKET;
+        if( !strcmp (name, "BACKSLASH")) return SDLK_BACKSLASH;
+        if( !strcmp (name, "RIGHTBRACKET")) return SDLK_RIGHTBRACKET;
+        if( !strcmp (name, "CARET")) return SDLK_CARET;
+        if( !strcmp (name, "UNDERSCORE")) return SDLK_UNDERSCORE;
+        if( !strcmp (name, "BACKQUOTE")) return SDLK_BACKQUOTE;
+        if( !strcmp (name, "a")) return SDLK_a;
+        if( !strcmp (name, "b")) return SDLK_b;
+        if( !strcmp (name, "c")) return SDLK_c;
+        if( !strcmp (name, "d")) return SDLK_d;
+        if( !strcmp (name, "e")) return SDLK_e;
+        if( !strcmp (name, "f")) return SDLK_f;
+        if( !strcmp (name, "g")) return SDLK_g;
+        if( !strcmp (name, "h")) return SDLK_h;
+        if( !strcmp (name, "i")) return SDLK_i;
+        if( !strcmp (name, "j")) return SDLK_j;
+        if( !strcmp (name, "k")) return SDLK_k;
+        if( !strcmp (name, "l")) return SDLK_l;
+        if( !strcmp (name, "m")) return SDLK_m;
+        if( !strcmp (name, "n")) return SDLK_n;
+        if( !strcmp (name, "o")) return SDLK_o;
+        if( !strcmp (name, "p")) return SDLK_p;
+        if( !strcmp (name, "q")) return SDLK_q;
+        if( !strcmp (name, "r")) return SDLK_r;
+        if( !strcmp (name, "s")) return SDLK_s;
+        if( !strcmp (name, "t")) return SDLK_t;
+        if( !strcmp (name, "u")) return SDLK_u;
+        if( !strcmp (name, "v")) return SDLK_v;
+        if( !strcmp (name, "w")) return SDLK_w;
+        if( !strcmp (name, "x")) return SDLK_x;
+        if( !strcmp (name, "y")) return SDLK_y;
+        if( !strcmp (name, "z")) return SDLK_z;
+        if( !strcmp (name, "DELETE")) return SDLK_DELETE;
+        if( !strcmp (name, "KP0")) return SDLK_KP0;
+        if( !strcmp (name, "KP1")) return SDLK_KP1;
+        if( !strcmp (name, "KP2")) return SDLK_KP2;
+        if( !strcmp (name, "KP3")) return SDLK_KP3;
+        if( !strcmp (name, "KP4")) return SDLK_KP4;
+        if( !strcmp (name, "KP5")) return SDLK_KP5;
+        if( !strcmp (name, "KP6")) return SDLK_KP6;
+        if( !strcmp (name, "KP7")) return SDLK_KP7;
+        if( !strcmp (name, "KP8")) return SDLK_KP8;
+        if( !strcmp (name, "KP9")) return SDLK_KP9;
+        if( !strcmp (name, "KP_PERIOD")) return SDLK_KP_PERIOD;
+        if( !strcmp (name, "KP_DIVIDE")) return SDLK_KP_DIVIDE;
+        if( !strcmp (name, "KP_MULTIPLY")) return SDLK_KP_MULTIPLY;
+        if( !strcmp (name, "KP_MINUS")) return SDLK_KP_MINUS;
+        if( !strcmp (name, "KP_PLUS")) return SDLK_KP_PLUS;
+        if( !strcmp (name, "KP_ENTER")) return SDLK_KP_ENTER;
+        if( !strcmp (name, "KP_EQUALS")) return SDLK_KP_EQUALS;
+        if( !strcmp (name, "UP")) return SDLK_UP;
+        if( !strcmp (name, "DOWN")) return SDLK_DOWN;
+        if( !strcmp (name, "RIGHT")) return SDLK_RIGHT;
+        if( !strcmp (name, "LEFT")) return SDLK_LEFT;
+        if( !strcmp (name, "INSERT")) return SDLK_INSERT;
+        if( !strcmp (name, "HOME")) return SDLK_HOME;
+        if( !strcmp (name, "END")) return SDLK_END;
+        if( !strcmp (name, "PAGEUP")) return SDLK_PAGEUP;
+        if( !strcmp (name, "PAGEDOWN")) return SDLK_PAGEDOWN;
+        if( !strcmp (name, "F1")) return SDLK_F1;
+        if( !strcmp (name, "F2")) return SDLK_F2;
+        if( !strcmp (name, "F3")) return SDLK_F3;
+        if( !strcmp (name, "F4")) return SDLK_F4;
+        if( !strcmp (name, "F5")) return SDLK_F5;
+        if( !strcmp (name, "F6")) return SDLK_F6;
+        if( !strcmp (name, "F7")) return SDLK_F7;
+        if( !strcmp (name, "F8")) return SDLK_F8;
+        if( !strcmp (name, "F9")) return SDLK_F9;
+        if( !strcmp (name, "F10")) return SDLK_F10;
+        if( !strcmp (name, "F11")) return SDLK_F11;
+        if( !strcmp (name, "F12")) return SDLK_F12;
+        if( !strcmp (name, "F13")) return SDLK_F13;
+        if( !strcmp (name, "F14")) return SDLK_F14;
+        if( !strcmp (name, "F15")) return SDLK_F15;
+        if( !strcmp (name, "NUMLOCK")) return SDLK_NUMLOCK;
+        if( !strcmp (name, "CAPSLOCK")) return SDLK_CAPSLOCK;
+        if( !strcmp (name, "SCROLLOCK")) return SDLK_SCROLLOCK;
+        if( !strcmp (name, "RSHIFT")) return SDLK_RSHIFT;
+        if( !strcmp (name, "LSHIFT")) return SDLK_LSHIFT;
+        if( !strcmp (name, "RCTRL")) return SDLK_RCTRL;
+        if( !strcmp (name, "LCTRL")) return SDLK_LCTRL;
+        if( !strcmp (name, "RALT")) return SDLK_RALT;
+        if( !strcmp (name, "LALT")) return SDLK_LALT;
+        if( !strcmp (name, "RMETA")) return SDLK_RMETA;
+        if( !strcmp (name, "LMETA")) return SDLK_LMETA;
+        if( !strcmp (name, "LSUPER")) return SDLK_LSUPER;
+        if( !strcmp (name, "RSUPER")) return SDLK_RSUPER;
+        if( !strcmp (name, "MODE")) return SDLK_MODE;
+        if( !strcmp (name, "HELP")) return SDLK_HELP;
+        if( !strcmp (name, "PRINT")) return SDLK_PRINT;
+        if( !strcmp (name, "SYSREQ")) return SDLK_SYSREQ;
+        if( !strcmp (name, "BREAK")) return SDLK_BREAK;
+        if( !strcmp (name, "MENU")) return SDLK_MENU;
+        if( !strcmp (name, "POWER")) return SDLK_POWER;
+        if( !strcmp (name, "EURO")) return SDLK_EURO;
+        return -1;
+}
+
+const char* SDLKToKeyname( int key)
+{
+        if( key == SDLK_BACKSPACE) return "BACKSPACE";
+        if( key == SDLK_TAB) return "TAB";
+        if( key == SDLK_CLEAR) return "CLEAR";
+        if( key == SDLK_RETURN) return "RETURN";
+        if( key == SDLK_SPACE) return "SPACE";
+        if( key == SDLK_ESCAPE) return "ESCAPE";
+        if( key == SDLK_EXCLAIM) return "EXCLAIM";
+        if( key == SDLK_QUOTEDBL) return "QUOTEDBL";
+        if( key == SDLK_HASH) return "HASH";
+        if( key == SDLK_PAUSE) return "PAUSE";
+        if( key == SDLK_DOLLAR) return "DOLLAR";
+        if( key == SDLK_AMPERSAND) return "AMPERSAND";
+        if( key == SDLK_QUOTE) return "QUOTE";
+        if( key == SDLK_LEFTPAREN) return "LEFTPAREN";
+        if( key == SDLK_RIGHTPAREN) return "RIGHTPAREN";
+        if( key == SDLK_ASTERISK) return "ASTERISK";
+        if( key == SDLK_PLUS) return "PLUS";
+        if( key == SDLK_COMMA) return "COMMA";
+        if( key == SDLK_MINUS) return "MINUS";
+        if( key == SDLK_PERIOD) return "PERIOD";
+        if( key == SDLK_SLASH) return "SLASH";
+        if( key == SDLK_0) return "0";
+        if( key == SDLK_1) return "1";
+        if( key == SDLK_2) return "2";
+        if( key == SDLK_3) return "3";
+        if( key == SDLK_4) return "4";
+        if( key == SDLK_5) return "5";
+        if( key == SDLK_6) return "6";
+        if( key == SDLK_7) return "7";
+        if( key == SDLK_8) return "8";
+        if( key == SDLK_9) return "9";
+        if( key == SDLK_COLON) return "COLON";
+        if( key == SDLK_SEMICOLON) return "SEMICOLON";
+        if( key == SDLK_LESS) return "LESS";
+        if( key == SDLK_EQUALS) return "EQUALS";
+        if( key == SDLK_GREATER) return "GREATER";
+        if( key == SDLK_QUESTION) return "QUESTION";
+        if( key == SDLK_AT) return "AT";
+        if( key == SDLK_LEFTBRACKET) return "LEFTBRACKET";
+        if( key == SDLK_BACKSLASH) return "BACKSLASH";
+        if( key == SDLK_RIGHTBRACKET) return "RIGHTBRACKET";
+        if( key == SDLK_CARET) return "CARET";
+        if( key == SDLK_UNDERSCORE) return "UNDERSCORE";
+        if( key == SDLK_BACKQUOTE) return "BACKQUOTE";
+        if( key == SDLK_a) return "a";
+        if( key == SDLK_b) return "b";
+        if( key == SDLK_c) return "c";
+        if( key == SDLK_d) return "d";
+        if( key == SDLK_e) return "e";
+        if( key == SDLK_f) return "f";
+        if( key == SDLK_g) return "g";
+        if( key == SDLK_h) return "h";
+        if( key == SDLK_i) return "i";
+        if( key == SDLK_j) return "j";
+        if( key == SDLK_k) return "k";
+        if( key == SDLK_l) return "l";
+        if( key == SDLK_m) return "m";
+        if( key == SDLK_n) return "n";
+        if( key == SDLK_o) return "o";
+        if( key == SDLK_p) return "p";
+        if( key == SDLK_q) return "q";
+        if( key == SDLK_r) return "r";
+        if( key == SDLK_s) return "s";
+        if( key == SDLK_t) return "t";
+        if( key == SDLK_u) return "u";
+        if( key == SDLK_v) return "v";
+        if( key == SDLK_w) return "w";
+        if( key == SDLK_x) return "x";
+        if( key == SDLK_y) return "y";
+        if( key == SDLK_z) return "z";
+        if( key == SDLK_DELETE) return "DELETE";
+        if( key == SDLK_KP0) return "KP0";
+        if( key == SDLK_KP1) return "KP1";
+        if( key == SDLK_KP2) return "KP2";
+        if( key == SDLK_KP3) return "KP3";
+        if( key == SDLK_KP4) return "KP4";
+        if( key == SDLK_KP5) return "KP5";
+        if( key == SDLK_KP6) return "KP6";
+        if( key == SDLK_KP7) return "KP7";
+        if( key == SDLK_KP8) return "KP8";
+        if( key == SDLK_KP9) return "KP9";
+        if( key == SDLK_KP_PERIOD) return "KP_PERIOD";
+        if( key == SDLK_KP_DIVIDE) return "KP_DIVIDE";
+        if( key == SDLK_KP_MULTIPLY) return "KP_MULTIPLY";
+        if( key == SDLK_KP_MINUS) return "KP_MINUS";
+        if( key == SDLK_KP_PLUS) return "KP_PLUS";
+        if( key == SDLK_KP_ENTER) return "KP_ENTER";
+        if( key == SDLK_KP_EQUALS) return "KP_EQUALS";
+        if( key == SDLK_UP) return "UP";
+        if( key == SDLK_DOWN) return "DOWN";
+        if( key == SDLK_RIGHT) return "RIGHT";
+        if( key == SDLK_LEFT) return "LEFT";
+        if( key == SDLK_INSERT) return "INSERT";
+        if( key == SDLK_HOME) return "HOME";
+        if( key == SDLK_END) return "END";
+        if( key == SDLK_PAGEUP) return "PAGEUP";
+        if( key == SDLK_PAGEDOWN) return "PAGEDOWN";
+        if( key == SDLK_F1) return "F1";
+        if( key == SDLK_F2) return "F2";
+        if( key == SDLK_F3) return "F3";
+        if( key == SDLK_F4) return "F4";
+        if( key == SDLK_F5) return "F5";
+        if( key == SDLK_F6) return "F6";
+        if( key == SDLK_F7) return "F7";
+        if( key == SDLK_F8) return "F8";
+        if( key == SDLK_F9) return "F9";
+        if( key == SDLK_F10) return "F10";
+        if( key == SDLK_F11) return "F11";
+        if( key == SDLK_F12) return "F12";
+        if( key == SDLK_F13) return "F13";
+        if( key == SDLK_F14) return "F14";
+        if( key == SDLK_F15) return "F15";
+        if( key == SDLK_NUMLOCK) return "NUMLOCK";
+        if( key == SDLK_CAPSLOCK) return "CAPSLOCK";
+        if( key == SDLK_SCROLLOCK) return "SCROLLOCK";
+        if( key == SDLK_RSHIFT) return "RSHIFT";
+        if( key == SDLK_LSHIFT) return "LSHIFT";
+        if( key == SDLK_RCTRL) return "RCTRL";
+        if( key == SDLK_LCTRL) return "LCTRL";
+        if( key == SDLK_RALT) return "RALT";
+        if( key == SDLK_LALT) return "LALT";
+        if( key == SDLK_RMETA) return "RMETA";
+        if( key == SDLK_LMETA) return "LMETA";
+        if( key == SDLK_LSUPER) return "LSUPER";
+        if( key == SDLK_RSUPER) return "RSUPER";
+        if( key == SDLK_MODE) return "MODE";
+        if( key == SDLK_HELP) return "HELP";
+        if( key == SDLK_PRINT) return "PRINT";
+        if( key == SDLK_SYSREQ) return "SYSREQ";
+        if( key == SDLK_BREAK) return "BREAK";
+        if( key == SDLK_MENU) return "MENU";
+        if( key == SDLK_POWER) return "POWER";
+        if( key == SDLK_EURO) return "EURO";
+        return "UNKNOWN";
+}
Index: branches/network/src/lib/event/key_names.h
===================================================================
--- branches/network/src/lib/event/key_names.h	(revision 6636)
+++ branches/network/src/lib/event/key_names.h	(revision 6636)
@@ -0,0 +1,39 @@
+/*!
+ * @file keynames.h
+  *  Key/button naming functions
+
+                Converts strings to SDLK/SDL_BUTTON values and vice versa
+*/
+#ifndef _KEY_NAMES_H
+#define _KEY_NAMES_H
+
+/**
+      *  converts a button name string to a integer representing the corresponding SDL mouse button identifier
+      * @param name: the name of the mouse button
+      * @return an int containing the SDL identifier of the mouse button or -1 if the button name is not valid
+*/
+int buttonnameToSDLB(const char* name);
+
+/**
+      *  converst a SDL mouse button identifier to a name string
+      * @param button: an SDL mouse button identifier
+      * @return a pointer to a string containing the name of the mouse button
+*/
+const char* SDLBToButtonname( int button);
+
+/**
+      *  converts a key name string to a integer representing the corresponding SDLK sym
+      * @param name: the name of the key
+      * @return the SDLK sym of the named key or -1 if the key name is not valid
+*/
+int keynameToSDLK(const char* name);
+
+/**
+      *  converts an SDLK sym to a name string
+      * @param key: the SDLK sym
+      * @return a pointer to a string containig the name of the key
+*/
+const char* SDLKToKeyname( int key);
+
+
+#endif /* _KEY_NAMES_H */
Index: branches/network/src/lib/graphics/Makefile.am
===================================================================
--- branches/network/src/lib/graphics/Makefile.am	(revision 6636)
+++ branches/network/src/lib/graphics/Makefile.am	(revision 6636)
@@ -0,0 +1,28 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXgraphics.a
+
+libORXgraphics_a_SOURCES = graphics_engine.cc \
+			   light.cc \
+			   shader.cc \
+			   render2D/render_2d.cc \
+			   render2D/element_2d.cc \
+			   text_engine/text_engine.cc \
+			   text_engine/text.cc \
+			   text_engine/font.cc
+
+noinst_HEADERS = graphics_engine.h \
+		 light.h \
+		 shader.h \
+		 render2D/render_2d.h \
+		 render2D/element_2d.h \
+		 text_engine/text_engine.h \
+		 text_engine/text.h \
+		 text_engine/font.h
+
+
+SUBDIRS = importer \
+          spatial_separation
+
+EXTRA_DIST = text_engine/default_font.xpm
Index: branches/network/src/lib/graphics/graphics_engine.cc
===================================================================
--- branches/network/src/lib/graphics/graphics_engine.cc	(revision 6636)
+++ branches/network/src/lib/graphics/graphics_engine.cc	(revision 6636)
@@ -0,0 +1,656 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "graphics_engine.h"
+#include "resource_manager.h"
+#include "event_handler.h"
+#include "state.h"
+
+#include "world_entity.h"
+
+#include "render_2d.h"
+#include "text_engine.h"
+#include "light.h"
+#include "shader.h"
+#include "debug.h"
+
+#include "parser/ini_parser/ini_parser.h"
+#include "substring.h"
+#include "text.h"
+
+#include "globals.h"
+#include "texture.h"
+
+#include "shell_command.h"
+
+#ifdef __WIN32__
+ #include "class_list.h"
+ #include "static_model.h"
+#endif
+using namespace std;
+
+SHELL_COMMAND(wireframe, GraphicsEngine, wireframe);
+
+/**
+ *  standard constructor
+ */
+GraphicsEngine::GraphicsEngine ()
+{
+  this->setClassID(CL_GRAPHICS_ENGINE, "GraphicsEngine");
+  this->setName("GraphicsEngine");
+
+  this->isInit = false;
+
+  this->bDisplayFPS = false;
+  this->minFPS = 9999;
+  this->maxFPS = 0;
+
+  this->geTextCFPS = NULL;
+  this->geTextMaxFPS = NULL;
+  this->geTextMinFPS = NULL;
+
+  this->fullscreenFlag = 0;
+  this->videoFlags = 0;
+  this->screen = NULL;
+
+
+  // Hardware
+  this->hwRenderer = NULL;
+  this->hwVendor = NULL;
+  this->hwVersion = NULL;
+  this->hwExtensions = NULL;
+
+  // initialize the TextEngine
+  TextEngine::getInstance();
+}
+
+/**
+ *  The Pointer to this GraphicsEngine
+*/
+GraphicsEngine* GraphicsEngine::singletonRef = NULL;
+
+/**
+ *  destructs the graphicsEngine.
+*/
+GraphicsEngine::~GraphicsEngine ()
+{
+  // delete what has to be deleted here
+  delete this->geTextCFPS;
+  delete this->geTextMaxFPS;
+  delete this->geTextMinFPS;
+
+  delete[] this->hwRenderer;
+  delete[] this->hwVendor;
+  delete[] this->hwVersion;
+  delete this->hwExtensions;
+
+  //TextEngine
+  delete TextEngine::getInstance();
+  // render 2D
+  delete Render2D::getInstance();
+
+  SDL_QuitSubSystem(SDL_INIT_VIDEO);
+//   if (this->screen != NULL)
+//     SDL_FreeSurface(this->screen);
+
+  GraphicsEngine::singletonRef = NULL;
+}
+
+/**
+ * initializes the GraphicsEngine with default settings.
+ */
+int GraphicsEngine::init()
+{
+  if (this->isInit)
+    return -1;
+  this->initVideo(640, 480, 16);
+}
+
+/**
+ * loads the GraphicsEngine's settings from a given ini-file and section
+ * @param iniParser the iniParser to load from
+ * @param section the Section in the ini-file to load from
+ * @returns nothing usefull
+ */
+int GraphicsEngine::initFromIniFile(IniParser* iniParser)
+{
+  // looking if we are in fullscreen-mode
+  const char* fullscreen = iniParser->getVar(CONFIG_NAME_FULLSCREEN, CONFIG_SECTION_VIDEO, "0");
+  if (strchr(fullscreen, '1') || !strcasecmp(fullscreen, "true"))
+    this->fullscreenFlag = SDL_FULLSCREEN;
+
+  // looking if we are in fullscreen-mode
+  const char* textures = iniParser->getVar(CONFIG_NAME_TEXTURES, CONFIG_SECTION_VIDEO_ADVANCED, "0");
+  if (strchr(textures, '1') || !strcasecmp(textures, "true"))
+    Texture::setTextureEnableState( true);
+  else
+    Texture::setTextureEnableState(false);
+
+  // searching for a usefull resolution
+  SubString resolution(iniParser->getVar(CONFIG_NAME_RESOLUTION, CONFIG_SECTION_VIDEO, "640x480"), 'x');
+  //resolution.debug();
+
+  this->initVideo(atoi(resolution.getString(0)), atoi(resolution.getString(1)), 16);
+}
+
+
+
+/**
+ *  initializes the Video for openGL.
+ *
+ * This has to be done only once when starting orxonox.
+ */
+int GraphicsEngine::initVideo(unsigned int resX, unsigned int resY, unsigned int bbp)
+{
+  if (this->isInit)
+    return -1;
+  //   initialize SDL_VIDEO
+  if (SDL_InitSubSystem(SDL_INIT_VIDEO) == -1)
+  {
+    PRINTF(1)("could not initialize SDL Video\n");
+      //      return -1;
+  }
+  // initialize SDL_GL-settings
+  this->setGLattribs();
+
+  // setting the Video Flags.
+  this->videoFlags = SDL_OPENGL | SDL_HWPALETTE | SDL_RESIZABLE | SDL_DOUBLEBUF | SDL_GL_DOUBLEBUFFER;
+
+  /* query SDL for information about our video hardware */
+  const SDL_VideoInfo* videoInfo = SDL_GetVideoInfo ();
+  if( videoInfo == NULL)
+    {
+      PRINTF(1)("Failed getting Video Info :%s\n", SDL_GetError());
+      SDL_Quit ();
+    }
+  if( videoInfo->hw_available)
+    this->videoFlags |= SDL_HWSURFACE;
+  else
+    this->videoFlags |= SDL_SWSURFACE;
+  /*
+  if(VideoInfo -> blit_hw)
+    VideoFlags |= SDL_HWACCEL;
+  */
+    // setting up the Resolution
+  this->setResolution(resX, resY, bbp);
+
+  // GRABBING ALL GL-extensions
+  this->grabHardwareSettings();
+
+  // Enable default GL stuff
+  glEnable(GL_DEPTH_TEST);
+
+  Render2D::getInstance();
+
+  this->isInit = true;
+}
+
+/**
+ * sets the Window Captions and the Name of the icon.
+ * @param windowName The name of the Window
+ * @param icon The name of the Icon on the Disc
+ */
+void GraphicsEngine::setWindowName(const char* windowName, const char* icon)
+{
+  SDL_Surface* iconSurf = SDL_LoadBMP(icon);
+  if (iconSurf != NULL)
+  {
+    Uint32 colorkey = SDL_MapRGB(iconSurf->format, 0, 0, 0);
+    SDL_SetColorKey(iconSurf, SDL_SRCCOLORKEY, colorkey);
+    SDL_WM_SetIcon(iconSurf,NULL);
+    SDL_FreeSurface(iconSurf);
+  }
+
+  SDL_WM_SetCaption (windowName, icon);
+}
+
+
+/**
+ *  Sets the GL-attributes
+ */
+int GraphicsEngine::setGLattribs()
+{
+  // Set video mode
+  // TO DO: parse arguments for settings
+  //SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
+  //SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
+  //SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
+  //SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
+
+
+  SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
+  SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16);
+  SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 0);
+  SDL_GL_SetAttribute( SDL_GL_ACCUM_RED_SIZE, 0);
+  SDL_GL_SetAttribute( SDL_GL_ACCUM_GREEN_SIZE, 0);
+  SDL_GL_SetAttribute( SDL_GL_ACCUM_BLUE_SIZE, 0);
+  SDL_GL_SetAttribute( SDL_GL_ACCUM_ALPHA_SIZE, 0);
+}
+
+/**
+ * grabs the Hardware Specifics
+ * checks for all the different HW-types
+ */
+void GraphicsEngine::grabHardwareSettings()
+{
+  const char* renderer = (const char*) glGetString(GL_RENDERER);
+  const char* vendor   = (const char*) glGetString(GL_VENDOR);
+  const char* version  = (const char*) glGetString(GL_VERSION);
+  const char* extensions = (const char*) glGetString(GL_EXTENSIONS);
+
+//  printf("%s %s %s\n %s", renderer, vendor, version, extensions);
+
+  if (this->hwRenderer == NULL && renderer != NULL)
+  {
+    this->hwRenderer = new char[strlen(renderer)+1];
+    strcpy(this->hwRenderer, renderer);
+  }
+  if (this->hwVendor == NULL && vendor != NULL)
+  {
+    this->hwVendor = new char[strlen(vendor)+1];
+    strcpy(this->hwVendor, vendor);
+  }
+  if (this->hwVersion == NULL && version != NULL)
+  {
+    this->hwVersion = new char[strlen(version)+11];
+    strcpy(this->hwVersion, version);
+  }
+
+  if (this->hwExtensions == NULL && extensions != NULL)
+    this->hwExtensions = new SubString((char*)glGetString(GL_EXTENSIONS), " \n\t,");
+
+  PRINT(4)("Running on : vendor: %s,  renderer: %s,  version:%s\n", vendor, renderer, version);
+  PRINT(4)("Extensions:\n");
+  if (this->hwExtensions != NULL)
+    for (unsigned int i = 0; i < this->hwExtensions->getCount(); i++)
+      PRINT(4)("%d: %s\n", i, this->hwExtensions->getString(i));
+
+
+  // inizializing GLEW
+  GLenum err = glewInit();
+  if (GLEW_OK != err)
+  {
+    /* Problem: glewInit failed, something is seriously wrong. */
+    PRINTF(1)("%s\n", glewGetErrorString(err));
+  }
+  PRINTF(4)("Status: Using GLEW %s\n", glewGetString(GLEW_VERSION));
+}
+
+
+/**
+ *  sets the Resolution of the Screen to display the Graphics to.
+ * @param width The width of the window
+ * @param height The height of the window
+ * @param bpp bits per pixel
+ */
+int GraphicsEngine::setResolution(int width, int height, int bpp)
+{
+  this->resolutionX = width;
+  this->resolutionY = height;
+  this->bitsPerPixel = bpp;
+  State::setResolution( width, height);
+
+  if (this->screen != NULL)
+    SDL_FreeSurface(screen);
+  if((this->screen = SDL_SetVideoMode(this->resolutionX, this->resolutionY, this->bitsPerPixel, this->videoFlags | this->fullscreenFlag)) == NULL)
+    {
+      PRINTF(1)("Could not SDL_SetVideoMode(%d, %d, %d, %d): %s\n", this->resolutionX, this->resolutionY, this->bitsPerPixel, this->videoFlags, SDL_GetError());
+      //    SDL_Quit();
+      //    return -1;
+    }
+    glMatrixMode(GL_PROJECTION_MATRIX);
+    glLoadIdentity();
+    glViewport(0, 0, width, height);                     // Reset The Current Viewport
+
+#ifdef __WIN32__
+    // REBUILDING TEXTURES (ON WINDOWS CONTEXT SWITCH)
+    const std::list<BaseObject*>* texList = ClassList::getList(CL_TEXTURE);
+    if (texList != NULL)
+    {
+      std::list<BaseObject*>::const_iterator reTex;
+      for (reTex = texList->begin(); reTex != texList->end(); reTex++)
+        dynamic_cast<Texture*>(*reTex)->rebuild();
+    }
+    // REBUILDING MODELS
+    const std::list<BaseObject*>* modelList = ClassList::getList(CL_STATIC_MODEL);
+    if (texList != NULL)
+    {
+      std::list<BaseObject*>::const_iterator reModel;
+      for (reModel = modelList->begin(); reModel != modelList->end(); reModel++)
+        dynamic_cast<StaticModel*>(*reModel)->rebuild();
+    }
+#endif /* __WIN32__ */
+}
+
+/**
+ *  sets Fullscreen mode
+ * @param fullscreen true if fullscreen, false if windowed
+*/
+void GraphicsEngine::setFullscreen(bool fullscreen)
+{
+  if (fullscreen)
+    this->fullscreenFlag = SDL_FULLSCREEN;
+  else
+    this->fullscreenFlag = 0;
+  this->setResolution(this->resolutionX, this->resolutionY, this->bitsPerPixel);
+}
+
+/**
+ *  sets the background color
+ * @param red the red part of the background
+ * @param blue the blue part of the background
+ * @param green the green part of the background
+ * @param alpha the alpha part of the background
+ */
+void GraphicsEngine::setBackgroundColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
+{
+  glClearColor(red, green, blue, alpha);
+}
+
+/**
+ *  Signalhandler, for when the resolution has changed
+ * @param resizeInfo SDL information about the size of the new screen size
+ */
+int GraphicsEngine::resolutionChanged(const SDL_ResizeEvent& resizeInfo)
+{
+  this->setResolution(resizeInfo.w, resizeInfo.h, this->bitsPerPixel);
+}
+
+/**
+ *
+ * @param show if The mouse-cursor should be visible
+ */
+void GraphicsEngine::showMouse(bool show)
+{
+  if (show)
+    SDL_ShowCursor(SDL_ENABLE);
+  else
+    SDL_ShowCursor(SDL_DISABLE);
+}
+
+/**
+ *
+ * @returns The Visinility of the mouse-cursor (true if visible, false if it is invisible)
+ */
+bool GraphicsEngine::isMouseVisible()
+{
+  if (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE)
+    return true;
+  else
+    return false;
+}
+
+/**
+ *
+ * @param steal If the Winodow-Managers Events should be stolen to this app
+ * (steals the mouse, and all WM-clicks)
+ *
+ * This only happens, if the HARD-Debug-level is set to 0,1,2, because otherwise a Segfault could
+ * result in the loss of System-controll
+ */
+void GraphicsEngine::stealWMEvents(bool steal)
+{
+#if DEBUG < 3
+   if (steal)
+     SDL_WM_GrabInput(SDL_GRAB_ON);
+   else
+     SDL_WM_GrabInput(SDL_GRAB_OFF);
+#endif
+}
+
+/**
+ *
+ * @returns true if Events are stolen from the WM, false if not.
+ */
+bool GraphicsEngine::isStealingEvents()
+{
+   if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON)
+     return true;
+   else
+     return false;
+};
+
+/**
+ *  entering 2D Mode
+
+   this is a GL-Projection-mode, that is orthogonal, for placing the font in fron of everything else
+*/
+void GraphicsEngine::enter2DMode()
+{
+  //GraphicsEngine::storeMatrices();
+  SDL_Surface *screen = SDL_GetVideoSurface();
+
+  /* Note, there may be other things you need to change,
+     depending on how you have your OpenGL state set up.
+  */
+  glPushAttrib(GL_ENABLE_BIT);
+  glDisable(GL_DEPTH_TEST);
+  glDisable(GL_CULL_FACE);
+  glDisable(GL_LIGHTING);  // will be set back when leaving 2D-mode
+
+  glViewport(0, 0, screen->w, screen->h);
+
+  glMatrixMode(GL_PROJECTION);
+  glPushMatrix();
+  glLoadIdentity();
+
+  glOrtho(0.0, (GLdouble)screen->w, (GLdouble)screen->h, 0.0, 0.0, 1.0);
+
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  glLoadIdentity();
+
+  glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+}
+
+/**
+ *  leaves the 2DMode again also @see Font::enter2DMode()
+ */
+void GraphicsEngine::leave2DMode()
+{
+  glMatrixMode(GL_PROJECTION);
+  glPopMatrix();
+
+  glMatrixMode(GL_MODELVIEW);
+  glPopMatrix();
+
+  glPopAttrib();
+}
+
+void GraphicsEngine::wireframe()
+{
+  glPolygonMode(GL_FRONT, GL_LINE);
+}
+
+/**
+ *  stores the GL_matrices
+ */
+void GraphicsEngine::storeMatrices()
+{
+  glGetDoublev(GL_PROJECTION_MATRIX, GraphicsEngine::projMat);
+  glGetDoublev(GL_MODELVIEW_MATRIX, GraphicsEngine::modMat);
+  glGetIntegerv(GL_VIEWPORT, GraphicsEngine::viewPort);
+}
+
+//! the stored ModelView Matrix.
+GLdouble GraphicsEngine::modMat[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+//! the stored Projection Matrix
+GLdouble GraphicsEngine::projMat[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+//! The ViewPort
+GLint GraphicsEngine::viewPort[4] = {0,0,0,0};
+
+
+
+/**
+ *  outputs all the Fullscreen modes.
+ */
+void GraphicsEngine::listModes()
+{
+  /* Get available fullscreen/hardware modes */
+  this->videoModes=SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_HWSURFACE);
+
+  /* Check is there are any modes available */
+  if(this->videoModes == (SDL_Rect **)0){
+    PRINTF(1)("No modes available!\n");
+    exit(-1);
+  }
+
+  /* Check if our resolution is restricted */
+  if(this->videoModes == (SDL_Rect **)-1){
+    PRINTF(2)("All resolutions available.\n");
+  }
+  else{
+    /* Print valid modes */
+    PRINT(0)("Available Resoulution Modes are\n");
+    for(int i = 0; this->videoModes[i]; ++i)
+      PRINT(4)(" |  %d x %d\n", this->videoModes[i]->w, this->videoModes[i]->h);
+  }
+}
+
+/**
+ * checks wether a certain extension is availiable
+ * @param extension the Extension to check for (ex. GL_ARB_texture_env_dot3)
+ * @return true if it is, false otherwise
+ */
+bool GraphicsEngine::hwSupportsEXT(const char* extension)
+{
+  if (this->hwExtensions != NULL)
+    for (unsigned int i = 0; i < this->hwExtensions->getCount(); i++)
+      if (!strcmp(extension, this->hwExtensions->getString(i)))
+        return true;
+  return false;
+}
+
+/**
+ * updates everything that is to be updated in the GraphicsEngine
+ */
+void GraphicsEngine::update(float dt)
+{
+  Render2D::getInstance()->update(dt);
+}
+
+
+/**
+ *  ticks the Text
+ * @param dt the time passed
+ */
+void GraphicsEngine::tick(float dt)
+{
+  if( unlikely(this->bDisplayFPS))
+  {
+    this->currentFPS = 1.0/dt;
+    if( unlikely(this->currentFPS > this->maxFPS)) this->maxFPS = this->currentFPS;
+    if( unlikely(this->currentFPS < this->minFPS)) this->minFPS = this->currentFPS;
+
+#ifndef NO_TEXT
+      char tmpChar1[20];
+      sprintf(tmpChar1, "Current:  %4.0f", this->currentFPS);
+      this->geTextCFPS->setText(tmpChar1);
+      char tmpChar2[20];
+      sprintf(tmpChar2, "Max:    %4.0f", this->maxFPS);
+      this->geTextMaxFPS->setText(tmpChar2);
+      char tmpChar3[20];
+      sprintf(tmpChar3, "Min:    %4.0f", this->minFPS);
+      this->geTextMinFPS->setText(tmpChar3);
+#endif /* NO_TEXT */
+
+
+  }
+  Render2D::getInstance()->tick(dt);
+}
+
+
+void GraphicsEngine::draw() const
+{
+  LightManager::getInstance()->draw();
+  GraphicsEngine::storeMatrices();
+  Shader::suspendShader();
+
+  Render2D::getInstance()->draw(E2D_LAYER_ALL);
+  Shader::restoreShader();
+}
+
+void GraphicsEngine::draw(const std::list<WorldEntity*>& drawList ) const
+{
+  std::list<WorldEntity*>::const_iterator entity;
+  for (entity = drawList.begin(); entity != drawList.end(); entity++)
+    if ((*entity)->isVisible())
+      (*entity)->draw();
+}
+
+
+/**
+ * displays the Frames per second
+ * @param display if the text should be displayed
+*/
+void GraphicsEngine::displayFPS(bool display)
+{
+#ifndef NO_TEXT
+  if( display )
+{
+  if (this->geTextCFPS == NULL)
+  {
+    this->geTextCFPS = new Text("fonts/arial_black.ttf", 15);
+    this->geTextCFPS->setName("curFPS");
+    this->geTextCFPS->setAlignment(TEXT_ALIGN_LEFT);
+    this->geTextCFPS->setAbsCoor2D(5, 0);
+  }
+  if (this->geTextMaxFPS == NULL)
+  {
+    this->geTextMaxFPS = new Text("fonts/arial_black.ttf", 15);
+    this->geTextMaxFPS->setName("MaxFPS");
+    this->geTextMaxFPS->setAlignment(TEXT_ALIGN_LEFT);
+    this->geTextMaxFPS->setAbsCoor2D(5, 20);
+  }
+  if (this->geTextMinFPS == NULL)
+  {
+    this->geTextMinFPS = new Text("fonts/arial_black.ttf", 15);
+    this->geTextMinFPS->setName("MinFPS");
+    this->geTextMinFPS->setAlignment(TEXT_ALIGN_LEFT);
+    this->geTextMinFPS->setAbsCoor2D(5, 40);
+  }
+}
+else
+{
+  delete this->geTextCFPS;
+  this->geTextCFPS = NULL;
+  delete this->geTextMaxFPS;
+  this->geTextMaxFPS = NULL;
+  delete this->geTextMinFPS;
+  this->geTextMinFPS = NULL;
+}
+  this->bDisplayFPS = display;
+#else
+  this->bDisplayFPS = false;
+#endif /* NO_TEXT */
+}
+
+
+/**
+  processes the events for the GraphicsEngine class
+* @param the event to handle
+ */
+void GraphicsEngine::process(const Event &event)
+{
+  switch (event.type)
+  {
+    case EV_VIDEO_RESIZE:
+      this->resolutionChanged(event.resize);
+      break;
+  }
+
+}
Index: branches/network/src/lib/graphics/graphics_engine.h
===================================================================
--- branches/network/src/lib/graphics/graphics_engine.h	(revision 6636)
+++ branches/network/src/lib/graphics/graphics_engine.h	(revision 6636)
@@ -0,0 +1,133 @@
+/*!
+ * @file graphics_engine.h
+
+  *  defines a Interface between orxonox and graphical input
+
+    handles graphical SDL-initialisation, textures, resolutions, and so on
+ */
+
+#ifndef _GRAPHICS_ENGINE_H
+#define _GRAPHICS_ENGINE_H
+
+#include "event_listener.h"
+
+#include "sdlincl.h"
+#include "glincl.h"
+
+#include <list>
+
+// Forward Declaration
+class Text;
+class IniParser;
+class SubString;
+class WorldEntity;
+
+//! class to handle graphics
+/**
+   handles graphical SDL-initialisation, textures, resolutions, and so on
+ */
+class GraphicsEngine : public EventListener
+{
+  public:
+    virtual ~GraphicsEngine();
+    /** @returns a Pointer to the only object of this Class */
+    inline static GraphicsEngine* getInstance() { if (!GraphicsEngine::singletonRef) GraphicsEngine::singletonRef = new GraphicsEngine();  return GraphicsEngine::singletonRef; };
+
+    int init();
+    int initFromIniFile(IniParser* iniParser);
+
+    void setWindowName(const char* windowName, const char* icon);
+
+    int setResolution(int width, int height, int bpp);
+    void setFullscreen(bool fullscreen = false);
+    static void setBackgroundColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha = 1.0);
+
+
+    /** @returns the x resolution */
+    inline int getResolutionX() const { return this->resolutionX; };
+    /** @returns the y resolution */
+    inline int getResolutionY() const { return this->resolutionY; };
+    /** @returns the Bits Per Pixel */
+    inline int getbbp() const { return this->bitsPerPixel; };
+
+    int resolutionChanged(const SDL_ResizeEvent& resizeInfo);
+
+    static void showMouse(bool show);
+    static bool isMouseVisible();
+    static void stealWMEvents(bool steal);
+    static bool isStealingEvents();
+
+    static void enter2DMode();
+    static void leave2DMode();
+
+    void wireframe();
+
+    static void storeMatrices();
+    static GLdouble modMat[16];
+    static GLdouble projMat[16];
+    static GLint viewPort[4];
+
+    void update(float dt);
+    void tick(float dt);
+    void draw() const;
+    void draw(const std::list<WorldEntity*>& drawList) const;
+    void displayFPS(bool display);
+
+    void listModes();
+    bool hwSupportsEXT(const char* extension);
+
+    /** @brief swaps the GL_BUFFERS */
+    inline static void swapBuffers() { SDL_GL_SwapBuffers(); };
+
+    void process(const Event  &event);
+
+  private:
+    GraphicsEngine();
+    int initVideo(unsigned int resX, unsigned int resY, unsigned int bbp);
+    int setGLattribs();
+    void grabHardwareSettings();
+
+  public:
+
+  private:
+    static GraphicsEngine*  singletonRef;       //!< Pointer to the only instance of this Class
+    bool                    isInit;             //!< if the GraphicsEngine is initialized.
+
+    // state.
+    SDL_Surface*            screen;             //!< the screen we draw to
+    int                     resolutionX;        //!< the X-resoultion of the screen
+    int                     resolutionY;        //!< the Y-resolution of the screen
+    int                     bitsPerPixel;       //!< the bits per pixels of the screen
+    Uint32                  fullscreenFlag;     //!< if we are in fullscreen mode
+    Uint32                  videoFlags;         //!< flags for video
+    SDL_Rect**              videoModes;         //!< list of resolutions
+
+    bool                    fogEnabled;         //!< If Fog should be enabled.
+    bool                    shadowsEnabled;     //!< If Shadows should be enabled.
+    bool                    particlesEnabled;   //!< If particles should be enabled.
+    int                     particlesValue;     //!< How many particles
+    int                     textureQuality;     //!< the quality of Textures
+    int                     filteringMethod;    //!< The filtering Method of textures.
+    int                     modelQuality;       //!< The quality of the Models loaded.
+    int                     antialiasingDepth;  //!< the Depth of the AntiAlias-Filter.
+
+    // HARDWARE-Settings:
+    char*                   hwRenderer;         //!< HW-renderer-string
+    char*                   hwVendor;           //!< HW-vendor-string
+    char*                   hwVersion;          //!< HW-version-string
+    SubString*              hwExtensions;       //!< All suported Extensions.
+
+    // FPS-related
+    bool                    bDisplayFPS;        //!< is true if the fps should be displayed
+    float                   currentFPS;         //!< the current frame rate: frames per seconds
+    float                   maxFPS;             //!< maximal frame rate we ever got since start of the game
+    float                   minFPS;             //!< minimal frame rate we ever got since start.
+
+#ifndef NO_TEXT
+  Text*          geTextCFPS;                    //!< Text for the current FPS
+  Text*          geTextMaxFPS;                  //!< Text for the max FPS
+  Text*          geTextMinFPS;                  //!< Text for the min FPS
+#endif /* NO_TEXT */
+};
+
+#endif /* _GRAPHICS_ENGINE_H */
Index: branches/network/src/lib/graphics/importer/Makefile.am
===================================================================
--- branches/network/src/lib/graphics/importer/Makefile.am	(revision 6636)
+++ branches/network/src/lib/graphics/importer/Makefile.am	(revision 6636)
@@ -0,0 +1,38 @@
+MAINSRCDIR=../../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXimporter.a libtc.a
+
+libORXimporter_a_SOURCES = model.cc \
+                           vertex_array_model.cc \
+                           grid.cc \
+                           static_model.cc \
+                           objModel.cc \
+                           primitive_model.cc \
+                           md2Model.cc \
+                           material.cc \
+                           texture.cc \
+                           texture_sequence.cc \
+                           height_map.cc \
+                           media_container.cc \
+                           movie_player.cc
+
+libtc_a_SOURCES  = tc.cc
+
+
+noinst_HEADERS = model.h \
+		 tc.h \
+                 vertex_array_model.h \
+                 grid.h \
+                 static_model.h \
+                 objModel.h \
+                 primitive_model.h \
+                 md2Model.h \
+                 material.h \
+                 texture.h \
+                 texture_sequence.h \
+                 height_map.h \
+                 anorms.h \
+                 anormtab.h \
+                 media_container.h \
+                 movie_player.h
Index: branches/network/src/lib/graphics/importer/anorms.h
===================================================================
--- branches/network/src/lib/graphics/importer/anorms.h	(revision 6636)
+++ branches/network/src/lib/graphics/importer/anorms.h	(revision 6636)
@@ -0,0 +1,181 @@
+/*
+Copyright (C) 1996-1997 Id Softwaref, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the Licensef, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if notf, write to the Free Software
+Foundationf, Inc.f, 59 Temple Place - Suite 330f, Bostonf, MA  02111-1307f, USA.
+*/
+
+{-0.525731f, 0.000000f, 0.850651f}, 
+{-0.442863f, 0.238856f, 0.864188f}, 
+{-0.295242f, 0.000000f, 0.955423f}, 
+{-0.309017f, 0.500000f, 0.809017f}, 
+{-0.162460f, 0.262866f, 0.951056f}, 
+{0.000000f, 0.000000f, 1.000000f}, 
+{0.000000f, 0.850651f, 0.525731f}, 
+{-0.147621f, 0.716567f, 0.681718f}, 
+{0.147621f, 0.716567f, 0.681718f}, 
+{0.000000f, 0.525731f, 0.850651f}, 
+{0.309017f, 0.500000f, 0.809017f}, 
+{0.525731f, 0.000000f, 0.850651f}, 
+{0.295242f, 0.000000f, 0.955423f}, 
+{0.442863f, 0.238856f, 0.864188f}, 
+{0.162460f, 0.262866f, 0.951056f}, 
+{-0.681718f, 0.147621f, 0.716567f}, 
+{-0.809017f, 0.309017f, 0.500000f}, 
+{-0.587785f, 0.425325f, 0.688191f}, 
+{-0.850651f, 0.525731f, 0.000000f}, 
+{-0.864188f, 0.442863f, 0.238856f}, 
+{-0.716567f, 0.681718f, 0.147621f}, 
+{-0.688191f, 0.587785f, 0.425325f}, 
+{-0.500000f, 0.809017f, 0.309017f}, 
+{-0.238856f, 0.864188f, 0.442863f}, 
+{-0.425325f, 0.688191f, 0.587785f}, 
+{-0.716567f, 0.681718f, -0.147621f}, 
+{-0.500000f, 0.809017f, -0.309017f}, 
+{-0.525731f, 0.850651f, 0.000000f}, 
+{0.000000f, 0.850651f, -0.525731f}, 
+{-0.238856f, 0.864188f, -0.442863f}, 
+{0.000000f, 0.955423f, -0.295242f}, 
+{-0.262866f, 0.951056f, -0.162460f}, 
+{0.000000f, 1.000000f, 0.000000f}, 
+{0.000000f, 0.955423f, 0.295242f}, 
+{-0.262866f, 0.951056f, 0.162460f}, 
+{0.238856f, 0.864188f, 0.442863f}, 
+{0.262866f, 0.951056f, 0.162460f}, 
+{0.500000f, 0.809017f, 0.309017f}, 
+{0.238856f, 0.864188f, -0.442863f}, 
+{0.262866f, 0.951056f, -0.162460f}, 
+{0.500000f, 0.809017f, -0.309017f}, 
+{0.850651f, 0.525731f, 0.000000f}, 
+{0.716567f, 0.681718f, 0.147621f}, 
+{0.716567f, 0.681718f, -0.147621f}, 
+{0.525731f, 0.850651f, 0.000000f}, 
+{0.425325f, 0.688191f, 0.587785f}, 
+{0.864188f, 0.442863f, 0.238856f}, 
+{0.688191f, 0.587785f, 0.425325f}, 
+{0.809017f, 0.309017f, 0.500000f}, 
+{0.681718f, 0.147621f, 0.716567f}, 
+{0.587785f, 0.425325f, 0.688191f}, 
+{0.955423f, 0.295242f, 0.000000f}, 
+{1.000000f, 0.000000f, 0.000000f}, 
+{0.951056f, 0.162460f, 0.262866f}, 
+{0.850651f, -0.525731f, 0.000000f}, 
+{0.955423f, -0.295242f, 0.000000f}, 
+{0.864188f, -0.442863f, 0.238856f}, 
+{0.951056f, -0.162460f, 0.262866f}, 
+{0.809017f, -0.309017f, 0.500000f}, 
+{0.681718f, -0.147621f, 0.716567f}, 
+{0.850651f, 0.000000f, 0.525731f}, 
+{0.864188f, 0.442863f, -0.238856f}, 
+{0.809017f, 0.309017f, -0.500000f}, 
+{0.951056f, 0.162460f, -0.262866f}, 
+{0.525731f, 0.000000f, -0.850651f}, 
+{0.681718f, 0.147621f, -0.716567f}, 
+{0.681718f, -0.147621f, -0.716567f}, 
+{0.850651f, 0.000000f, -0.525731f}, 
+{0.809017f, -0.309017f, -0.500000f}, 
+{0.864188f, -0.442863f, -0.238856f}, 
+{0.951056f, -0.162460f, -0.262866f}, 
+{0.147621f, 0.716567f, -0.681718f}, 
+{0.309017f, 0.500000f, -0.809017f}, 
+{0.425325f, 0.688191f, -0.587785f}, 
+{0.442863f, 0.238856f, -0.864188f}, 
+{0.587785f, 0.425325f, -0.688191f}, 
+{0.688191f, 0.587785f, -0.425325f}, 
+{-0.147621f, 0.716567f, -0.681718f}, 
+{-0.309017f, 0.500000f, -0.809017f}, 
+{0.000000f, 0.525731f, -0.850651f}, 
+{-0.525731f, 0.000000f, -0.850651f}, 
+{-0.442863f, 0.238856f, -0.864188f}, 
+{-0.295242f, 0.000000f, -0.955423f}, 
+{-0.162460f, 0.262866f, -0.951056f}, 
+{0.000000f, 0.000000f, -1.000000f}, 
+{0.295242f, 0.000000f, -0.955423f}, 
+{0.162460f, 0.262866f, -0.951056f}, 
+{-0.442863f, -0.238856f, -0.864188f}, 
+{-0.309017f, -0.500000f, -0.809017f}, 
+{-0.162460f, -0.262866f, -0.951056f}, 
+{0.000000f, -0.850651f, -0.525731f}, 
+{-0.147621f, -0.716567f, -0.681718f}, 
+{0.147621f, -0.716567f, -0.681718f}, 
+{0.000000f, -0.525731f, -0.850651f}, 
+{0.309017f, -0.500000f, -0.809017f}, 
+{0.442863f, -0.238856f, -0.864188f}, 
+{0.162460f, -0.262866f, -0.951056f}, 
+{0.238856f, -0.864188f, -0.442863f}, 
+{0.500000f, -0.809017f, -0.309017f}, 
+{0.425325f, -0.688191f, -0.587785f}, 
+{0.716567f, -0.681718f, -0.147621f}, 
+{0.688191f, -0.587785f, -0.425325f}, 
+{0.587785f, -0.425325f, -0.688191f}, 
+{0.000000f, -0.955423f, -0.295242f}, 
+{0.000000f, -1.000000f, 0.000000f}, 
+{0.262866f, -0.951056f, -0.162460f}, 
+{0.000000f, -0.850651f, 0.525731f}, 
+{0.000000f, -0.955423f, 0.295242f}, 
+{0.238856f, -0.864188f, 0.442863f}, 
+{0.262866f, -0.951056f, 0.162460f}, 
+{0.500000f, -0.809017f, 0.309017f}, 
+{0.716567f, -0.681718f, 0.147621f}, 
+{0.525731f, -0.850651f, 0.000000f}, 
+{-0.238856f, -0.864188f, -0.442863f}, 
+{-0.500000f, -0.809017f, -0.309017f}, 
+{-0.262866f, -0.951056f, -0.162460f}, 
+{-0.850651f, -0.525731f, 0.000000f}, 
+{-0.716567f, -0.681718f, -0.147621f}, 
+{-0.716567f, -0.681718f, 0.147621f}, 
+{-0.525731f, -0.850651f, 0.000000f}, 
+{-0.500000f, -0.809017f, 0.309017f}, 
+{-0.238856f, -0.864188f, 0.442863f}, 
+{-0.262866f, -0.951056f, 0.162460f}, 
+{-0.864188f, -0.442863f, 0.238856f}, 
+{-0.809017f, -0.309017f, 0.500000f}, 
+{-0.688191f, -0.587785f, 0.425325f}, 
+{-0.681718f, -0.147621f, 0.716567f}, 
+{-0.442863f, -0.238856f, 0.864188f}, 
+{-0.587785f, -0.425325f, 0.688191f}, 
+{-0.309017f, -0.500000f, 0.809017f}, 
+{-0.147621f, -0.716567f, 0.681718f}, 
+{-0.425325f, -0.688191f, 0.587785f}, 
+{-0.162460f, -0.262866f, 0.951056f}, 
+{0.442863f, -0.238856f, 0.864188f}, 
+{0.162460f, -0.262866f, 0.951056f}, 
+{0.309017f, -0.500000f, 0.809017f}, 
+{0.147621f, -0.716567f, 0.681718f}, 
+{0.000000f, -0.525731f, 0.850651f}, 
+{0.425325f, -0.688191f, 0.587785f}, 
+{0.587785f, -0.425325f, 0.688191f}, 
+{0.688191f, -0.587785f, 0.425325f}, 
+{-0.955423f, 0.295242f, 0.000000f}, 
+{-0.951056f, 0.162460f, 0.262866f}, 
+{-1.000000f, 0.000000f, 0.000000f}, 
+{-0.850651f, 0.000000f, 0.525731f}, 
+{-0.955423f, -0.295242f, 0.000000f}, 
+{-0.951056f, -0.162460f, 0.262866f}, 
+{-0.864188f, 0.442863f, -0.238856f}, 
+{-0.951056f, 0.162460f, -0.262866f}, 
+{-0.809017f, 0.309017f, -0.500000f}, 
+{-0.864188f, -0.442863f, -0.238856f}, 
+{-0.951056f, -0.162460f, -0.262866f}, 
+{-0.809017f, -0.309017f, -0.500000f}, 
+{-0.681718f, 0.147621f, -0.716567f}, 
+{-0.681718f, -0.147621f, -0.716567f}, 
+{-0.850651f, 0.000000f, -0.525731f}, 
+{-0.688191f, 0.587785f, -0.425325f}, 
+{-0.587785f, 0.425325f, -0.688191f}, 
+{-0.425325f, 0.688191f, -0.587785f}, 
+{-0.425325f, -0.688191f, -0.587785f}, 
+{-0.587785f, -0.425325f, -0.688191f}, 
+{-0.688191f, -0.587785f, -0.425325f},
Index: branches/network/src/lib/graphics/importer/anormtab.h
===================================================================
--- branches/network/src/lib/graphics/importer/anormtab.h	(revision 6636)
+++ branches/network/src/lib/graphics/importer/anormtab.h	(revision 6636)
@@ -0,0 +1,37 @@
+/*
+Copyright (C) 1997-2001 Id Software, Inc.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+*/
+
+{1.23,1.30,1.47,1.35,1.56,1.71,1.37,1.38,1.59,1.60,1.79,1.97,1.88,1.92,1.79,1.02,0.93,1.07,0.82,0.87,0.88,0.94,0.96,1.14,1.11,0.82,0.83,0.89,0.89,0.86,0.94,0.91,1.00,1.21,0.98,1.48,1.30,1.57,0.96,1.07,1.14,1.60,1.61,1.40,1.37,1.72,1.78,1.79,1.93,1.99,1.90,1.68,1.71,1.86,1.60,1.68,1.78,1.86,1.93,1.99,1.97,1.44,1.22,1.49,0.93,0.99,0.99,1.23,1.22,1.44,1.49,0.89,0.89,0.97,0.91,0.98,1.19,0.82,0.76,0.82,0.71,0.72,0.73,0.76,0.79,0.86,0.83,0.72,0.76,0.76,0.89,0.82,0.89,0.82,0.89,0.91,0.83,0.96,1.14,0.97,1.40,1.19,0.98,0.94,1.00,1.07,1.37,1.21,1.48,1.30,1.57,1.61,1.37,0.86,0.83,0.91,0.82,0.82,0.88,0.89,0.96,1.14,0.98,0.87,0.93,0.94,1.02,1.30,1.07,1.35,1.38,1.11,1.56,1.92,1.79,1.79,1.59,1.60,1.72,1.90,1.79,0.80,0.85,0.79,0.93,0.80,0.85,0.77,0.74,0.72,0.77,0.74,0.72,0.70,0.70,0.71,0.76,0.73,0.79,0.79,0.73,0.76,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.26,1.26,1.48,1.23,1.50,1.71,1.14,1.19,1.38,1.46,1.64,1.94,1.87,1.84,1.71,1.02,0.92,1.00,0.79,0.85,0.84,0.91,0.90,0.98,0.99,0.77,0.77,0.83,0.82,0.79,0.86,0.84,0.92,0.99,0.91,1.24,1.03,1.33,0.88,0.94,0.97,1.41,1.39,1.18,1.11,1.51,1.61,1.59,1.80,1.91,1.76,1.54,1.65,1.76,1.70,1.70,1.85,1.85,1.97,1.99,1.93,1.28,1.09,1.39,0.92,0.97,0.99,1.18,1.26,1.52,1.48,0.83,0.85,0.90,0.88,0.93,1.00,0.77,0.73,0.78,0.72,0.71,0.74,0.75,0.79,0.86,0.81,0.75,0.81,0.79,0.96,0.88,0.94,0.86,0.93,0.92,0.85,1.08,1.33,1.05,1.55,1.31,1.01,1.05,1.27,1.31,1.60,1.47,1.70,1.54,1.76,1.76,1.57,0.93,0.90,0.99,0.88,0.88,0.95,0.97,1.11,1.39,1.20,0.92,0.97,1.01,1.10,1.39,1.22,1.51,1.58,1.32,1.64,1.97,1.85,1.91,1.77,1.74,1.88,1.99,1.91,0.79,0.86,0.80,0.94,0.84,0.88,0.74,0.74,0.71,0.82,0.77,0.76,0.70,0.73,0.72,0.73,0.70,0.74,0.85,0.77,0.82,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.34,1.27,1.53,1.17,1.46,1.71,0.98,1.05,1.20,1.34,1.48,1.86,1.82,1.71,1.62,1.09,0.94,0.99,0.79,0.85,0.82,0.90,0.87,0.93,0.96,0.76,0.74,0.79,0.76,0.74,0.79,0.78,0.85,0.92,0.85,1.00,0.93,1.06,0.81,0.86,0.89,1.16,1.12,0.97,0.95,1.28,1.38,1.35,1.60,1.77,1.57,1.33,1.50,1.58,1.69,1.63,1.82,1.74,1.91,1.92,1.80,1.04,0.97,1.21,0.90,0.93,0.97,1.05,1.21,1.48,1.37,0.77,0.80,0.84,0.85,0.88,0.92,0.73,0.71,0.74,0.74,0.71,0.75,0.73,0.79,0.84,0.78,0.79,0.86,0.81,1.05,0.94,0.99,0.90,0.95,0.92,0.86,1.24,1.44,1.14,1.59,1.34,1.02,1.27,1.50,1.49,1.80,1.69,1.86,1.72,1.87,1.80,1.69,1.00,0.98,1.23,0.95,0.96,1.09,1.16,1.37,1.63,1.46,0.99,1.10,1.25,1.24,1.51,1.41,1.67,1.77,1.55,1.72,1.95,1.89,1.98,1.91,1.86,1.97,1.99,1.94,0.81,0.89,0.85,0.98,0.90,0.94,0.75,0.78,0.73,0.89,0.83,0.82,0.72,0.77,0.76,0.72,0.70,0.71,0.91,0.83,0.89,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.46,1.34,1.60,1.16,1.46,1.71,0.94,0.99,1.05,1.26,1.33,1.74,1.76,1.57,1.54,1.23,0.98,1.05,0.83,0.89,0.84,0.92,0.87,0.91,0.96,0.78,0.74,0.79,0.72,0.72,0.75,0.76,0.80,0.88,0.83,0.94,0.87,0.95,0.76,0.80,0.82,0.97,0.96,0.89,0.88,1.08,1.11,1.10,1.37,1.59,1.37,1.07,1.27,1.34,1.57,1.45,1.69,1.55,1.77,1.79,1.60,0.93,0.90,0.99,0.86,0.87,0.93,0.96,1.07,1.35,1.18,0.73,0.76,0.77,0.81,0.82,0.85,0.70,0.71,0.72,0.78,0.73,0.77,0.73,0.79,0.82,0.76,0.83,0.90,0.84,1.18,0.98,1.03,0.92,0.95,0.90,0.86,1.32,1.45,1.15,1.53,1.27,0.99,1.42,1.65,1.58,1.93,1.83,1.94,1.81,1.88,1.74,1.70,1.19,1.17,1.44,1.11,1.15,1.36,1.41,1.61,1.81,1.67,1.22,1.34,1.50,1.42,1.65,1.61,1.82,1.91,1.75,1.80,1.89,1.89,1.98,1.99,1.94,1.98,1.92,1.87,0.86,0.95,0.92,1.14,0.98,1.03,0.79,0.84,0.77,0.97,0.90,0.89,0.76,0.82,0.82,0.74,0.72,0.71,0.98,0.89,0.97,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.60,1.44,1.68,1.22,1.49,1.71,0.93,0.99,0.99,1.23,1.22,1.60,1.68,1.44,1.49,1.40,1.14,1.19,0.89,0.96,0.89,0.97,0.89,0.91,0.98,0.82,0.76,0.82,0.71,0.72,0.73,0.76,0.79,0.86,0.83,0.91,0.83,0.89,0.72,0.76,0.76,0.89,0.89,0.82,0.82,0.98,0.96,0.97,1.14,1.40,1.19,0.94,1.00,1.07,1.37,1.21,1.48,1.30,1.57,1.61,1.37,0.86,0.83,0.91,0.82,0.82,0.88,0.89,0.96,1.14,0.98,0.70,0.72,0.73,0.77,0.76,0.79,0.70,0.72,0.71,0.82,0.77,0.80,0.74,0.79,0.80,0.74,0.87,0.93,0.85,1.23,1.02,1.02,0.93,0.93,0.87,0.85,1.30,1.35,1.07,1.38,1.11,0.94,1.47,1.71,1.56,1.97,1.88,1.92,1.79,1.79,1.59,1.60,1.30,1.35,1.56,1.37,1.38,1.59,1.60,1.79,1.92,1.79,1.48,1.57,1.72,1.61,1.78,1.79,1.93,1.99,1.90,1.86,1.78,1.86,1.93,1.99,1.97,1.90,1.79,1.72,0.94,1.07,1.00,1.37,1.21,1.30,0.86,0.91,0.83,1.14,0.98,0.96,0.82,0.88,0.89,0.79,0.76,0.73,1.07,0.94,1.11,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.74,1.57,1.76,1.33,1.54,1.71,0.94,1.05,0.99,1.26,1.16,1.46,1.60,1.34,1.46,1.59,1.37,1.37,0.97,1.11,0.96,1.10,0.95,0.94,1.08,0.89,0.82,0.88,0.72,0.76,0.75,0.80,0.80,0.88,0.87,0.91,0.83,0.87,0.72,0.76,0.74,0.83,0.84,0.78,0.79,0.96,0.89,0.92,0.98,1.23,1.05,0.86,0.92,0.95,1.11,0.98,1.22,1.03,1.34,1.42,1.14,0.79,0.77,0.84,0.78,0.76,0.82,0.82,0.89,0.97,0.90,0.70,0.71,0.71,0.73,0.72,0.74,0.73,0.76,0.72,0.86,0.81,0.82,0.76,0.79,0.77,0.73,0.90,0.95,0.86,1.18,1.03,0.98,0.92,0.90,0.83,0.84,1.19,1.17,0.98,1.15,0.97,0.89,1.42,1.65,1.44,1.93,1.83,1.81,1.67,1.61,1.36,1.41,1.32,1.45,1.58,1.57,1.53,1.74,1.70,1.88,1.94,1.81,1.69,1.77,1.87,1.79,1.89,1.92,1.98,1.99,1.98,1.89,1.65,1.80,1.82,1.91,1.94,1.75,1.61,1.50,1.07,1.34,1.27,1.60,1.45,1.55,0.93,0.99,0.90,1.35,1.18,1.07,0.87,0.93,0.96,0.85,0.82,0.77,1.15,0.99,1.27,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.86,1.71,1.82,1.48,1.62,1.71,0.98,1.20,1.05,1.34,1.17,1.34,1.53,1.27,1.46,1.77,1.60,1.57,1.16,1.38,1.12,1.35,1.06,1.00,1.28,0.97,0.89,0.95,0.76,0.81,0.79,0.86,0.85,0.92,0.93,0.93,0.85,0.87,0.74,0.78,0.74,0.79,0.82,0.76,0.79,0.96,0.85,0.90,0.94,1.09,0.99,0.81,0.85,0.89,0.95,0.90,0.99,0.94,1.10,1.24,0.98,0.75,0.73,0.78,0.74,0.72,0.77,0.76,0.82,0.89,0.83,0.73,0.71,0.71,0.71,0.70,0.72,0.77,0.80,0.74,0.90,0.85,0.84,0.78,0.79,0.75,0.73,0.92,0.95,0.86,1.05,0.99,0.94,0.90,0.86,0.79,0.81,1.00,0.98,0.91,0.96,0.89,0.83,1.27,1.50,1.23,1.80,1.69,1.63,1.46,1.37,1.09,1.16,1.24,1.44,1.49,1.69,1.59,1.80,1.69,1.87,1.86,1.72,1.82,1.91,1.94,1.92,1.95,1.99,1.98,1.91,1.97,1.89,1.51,1.72,1.67,1.77,1.86,1.55,1.41,1.25,1.33,1.58,1.50,1.80,1.63,1.74,1.04,1.21,0.97,1.48,1.37,1.21,0.93,0.97,1.05,0.92,0.88,0.84,1.14,1.02,1.34,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.94,1.84,1.87,1.64,1.71,1.71,1.14,1.38,1.19,1.46,1.23,1.26,1.48,1.26,1.50,1.91,1.80,1.76,1.41,1.61,1.39,1.59,1.33,1.24,1.51,1.18,0.97,1.11,0.82,0.88,0.86,0.94,0.92,0.99,1.03,0.98,0.91,0.90,0.79,0.84,0.77,0.79,0.84,0.77,0.83,0.99,0.85,0.91,0.92,1.02,1.00,0.79,0.80,0.86,0.88,0.84,0.92,0.88,0.97,1.10,0.94,0.74,0.71,0.74,0.72,0.70,0.73,0.72,0.76,0.82,0.77,0.77,0.73,0.74,0.71,0.70,0.73,0.83,0.85,0.78,0.92,0.88,0.86,0.81,0.79,0.74,0.75,0.92,0.93,0.85,0.96,0.94,0.88,0.86,0.81,0.75,0.79,0.93,0.90,0.85,0.88,0.82,0.77,1.05,1.27,0.99,1.60,1.47,1.39,1.20,1.11,0.95,0.97,1.08,1.33,1.31,1.70,1.55,1.76,1.57,1.76,1.70,1.54,1.85,1.97,1.91,1.99,1.97,1.99,1.91,1.77,1.88,1.85,1.39,1.64,1.51,1.58,1.74,1.32,1.22,1.01,1.54,1.76,1.65,1.93,1.70,1.85,1.28,1.39,1.09,1.52,1.48,1.26,0.97,0.99,1.18,1.00,0.93,0.90,1.05,1.01,1.31,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.97,1.92,1.88,1.79,1.79,1.71,1.37,1.59,1.38,1.60,1.35,1.23,1.47,1.30,1.56,1.99,1.93,1.90,1.60,1.78,1.61,1.79,1.57,1.48,1.72,1.40,1.14,1.37,0.89,0.96,0.94,1.07,1.00,1.21,1.30,1.14,0.98,0.96,0.86,0.91,0.83,0.82,0.88,0.82,0.89,1.11,0.87,0.94,0.93,1.02,1.07,0.80,0.79,0.85,0.82,0.80,0.87,0.85,0.93,1.02,0.93,0.77,0.72,0.74,0.71,0.70,0.70,0.71,0.72,0.77,0.74,0.82,0.76,0.79,0.72,0.73,0.76,0.89,0.89,0.82,0.93,0.91,0.86,0.83,0.79,0.73,0.76,0.91,0.89,0.83,0.89,0.89,0.82,0.82,0.76,0.72,0.76,0.86,0.83,0.79,0.82,0.76,0.73,0.94,1.00,0.91,1.37,1.21,1.14,0.98,0.96,0.88,0.89,0.96,1.14,1.07,1.60,1.40,1.61,1.37,1.57,1.48,1.30,1.78,1.93,1.79,1.99,1.92,1.90,1.79,1.59,1.72,1.79,1.30,1.56,1.35,1.38,1.60,1.11,1.07,0.94,1.68,1.86,1.71,1.97,1.68,1.86,1.44,1.49,1.22,1.44,1.49,1.22,0.99,0.99,1.23,1.19,0.98,0.97,0.97,0.98,1.19,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.94,1.97,1.87,1.91,1.85,1.71,1.60,1.77,1.58,1.74,1.51,1.26,1.48,1.39,1.64,1.99,1.97,1.99,1.70,1.85,1.76,1.91,1.76,1.70,1.88,1.55,1.33,1.57,0.96,1.08,1.05,1.31,1.27,1.47,1.54,1.39,1.20,1.11,0.93,0.99,0.90,0.88,0.95,0.88,0.97,1.32,0.92,1.01,0.97,1.10,1.22,0.84,0.80,0.88,0.79,0.79,0.85,0.86,0.92,1.02,0.94,0.82,0.76,0.77,0.72,0.73,0.70,0.72,0.71,0.74,0.74,0.88,0.81,0.85,0.75,0.77,0.82,0.94,0.93,0.86,0.92,0.92,0.86,0.85,0.79,0.74,0.79,0.88,0.85,0.81,0.82,0.83,0.77,0.78,0.73,0.71,0.75,0.79,0.77,0.74,0.77,0.73,0.70,0.86,0.92,0.84,1.14,0.99,0.98,0.91,0.90,0.84,0.83,0.88,0.97,0.94,1.41,1.18,1.39,1.11,1.33,1.24,1.03,1.61,1.80,1.59,1.91,1.84,1.76,1.64,1.38,1.51,1.71,1.26,1.50,1.23,1.19,1.46,0.99,1.00,0.91,1.70,1.85,1.65,1.93,1.54,1.76,1.52,1.48,1.26,1.28,1.39,1.09,0.99,0.97,1.18,1.31,1.01,1.05,0.90,0.93,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.86,1.95,1.82,1.98,1.89,1.71,1.80,1.91,1.77,1.86,1.67,1.34,1.53,1.51,1.72,1.92,1.91,1.99,1.69,1.82,1.80,1.94,1.87,1.86,1.97,1.59,1.44,1.69,1.05,1.24,1.27,1.49,1.50,1.69,1.72,1.63,1.46,1.37,1.00,1.23,0.98,0.95,1.09,0.96,1.16,1.55,0.99,1.25,1.10,1.24,1.41,0.90,0.85,0.94,0.79,0.81,0.85,0.89,0.94,1.09,0.98,0.89,0.82,0.83,0.74,0.77,0.72,0.76,0.73,0.75,0.78,0.94,0.86,0.91,0.79,0.83,0.89,0.99,0.95,0.90,0.90,0.92,0.84,0.86,0.79,0.75,0.81,0.85,0.80,0.78,0.76,0.77,0.73,0.74,0.71,0.71,0.73,0.74,0.74,0.71,0.76,0.72,0.70,0.79,0.85,0.78,0.98,0.92,0.93,0.85,0.87,0.82,0.79,0.81,0.89,0.86,1.16,0.97,1.12,0.95,1.06,1.00,0.93,1.38,1.60,1.35,1.77,1.71,1.57,1.48,1.20,1.28,1.62,1.27,1.46,1.17,1.05,1.34,0.96,0.99,0.90,1.63,1.74,1.50,1.80,1.33,1.58,1.48,1.37,1.21,1.04,1.21,0.97,0.97,0.93,1.05,1.34,1.02,1.14,0.84,0.88,0.92,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.74,1.89,1.76,1.98,1.89,1.71,1.93,1.99,1.91,1.94,1.82,1.46,1.60,1.65,1.80,1.79,1.77,1.92,1.57,1.69,1.74,1.87,1.88,1.94,1.98,1.53,1.45,1.70,1.18,1.32,1.42,1.58,1.65,1.83,1.81,1.81,1.67,1.61,1.19,1.44,1.17,1.11,1.36,1.15,1.41,1.75,1.22,1.50,1.34,1.42,1.61,0.98,0.92,1.03,0.83,0.86,0.89,0.95,0.98,1.23,1.14,0.97,0.89,0.90,0.78,0.82,0.76,0.82,0.77,0.79,0.84,0.98,0.90,0.98,0.83,0.89,0.97,1.03,0.95,0.92,0.86,0.90,0.82,0.86,0.79,0.77,0.84,0.81,0.76,0.76,0.72,0.73,0.70,0.72,0.71,0.73,0.73,0.72,0.74,0.71,0.78,0.74,0.72,0.75,0.80,0.76,0.94,0.88,0.91,0.83,0.87,0.84,0.79,0.76,0.82,0.80,0.97,0.89,0.96,0.88,0.95,0.94,0.87,1.11,1.37,1.10,1.59,1.57,1.37,1.33,1.05,1.08,1.54,1.34,1.46,1.16,0.99,1.26,0.96,1.05,0.92,1.45,1.55,1.27,1.60,1.07,1.34,1.35,1.18,1.07,0.93,0.99,0.90,0.93,0.87,0.96,1.27,0.99,1.15,0.77,0.82,0.85,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.60,1.78,1.68,1.93,1.86,1.71,1.97,1.99,1.99,1.97,1.93,1.60,1.68,1.78,1.86,1.61,1.57,1.79,1.37,1.48,1.59,1.72,1.79,1.92,1.90,1.38,1.35,1.60,1.23,1.30,1.47,1.56,1.71,1.88,1.79,1.92,1.79,1.79,1.30,1.56,1.35,1.37,1.59,1.38,1.60,1.90,1.48,1.72,1.57,1.61,1.79,1.21,1.00,1.30,0.89,0.94,0.96,1.07,1.14,1.40,1.37,1.14,0.96,0.98,0.82,0.88,0.82,0.89,0.83,0.86,0.91,1.02,0.93,1.07,0.87,0.94,1.11,1.02,0.93,0.93,0.82,0.87,0.80,0.85,0.79,0.80,0.85,0.77,0.72,0.74,0.71,0.70,0.70,0.71,0.72,0.77,0.74,0.72,0.76,0.73,0.82,0.79,0.76,0.73,0.79,0.76,0.93,0.86,0.91,0.83,0.89,0.89,0.82,0.72,0.76,0.76,0.89,0.82,0.89,0.82,0.89,0.91,0.83,0.96,1.14,0.97,1.40,1.44,1.19,1.22,0.99,0.98,1.49,1.44,1.49,1.22,0.99,1.23,0.98,1.19,0.97,1.21,1.30,1.00,1.37,0.94,1.07,1.14,0.98,0.96,0.86,0.91,0.83,0.88,0.82,0.89,1.11,0.94,1.07,0.73,0.76,0.79,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.46,1.65,1.60,1.82,1.80,1.71,1.93,1.91,1.99,1.94,1.98,1.74,1.76,1.89,1.89,1.42,1.34,1.61,1.11,1.22,1.36,1.50,1.61,1.81,1.75,1.15,1.17,1.41,1.18,1.19,1.42,1.44,1.65,1.83,1.67,1.94,1.81,1.88,1.32,1.58,1.45,1.57,1.74,1.53,1.70,1.98,1.69,1.87,1.77,1.79,1.92,1.45,1.27,1.55,0.97,1.07,1.11,1.34,1.37,1.59,1.60,1.35,1.07,1.18,0.86,0.93,0.87,0.96,0.90,0.93,0.99,1.03,0.95,1.15,0.90,0.99,1.27,0.98,0.90,0.92,0.78,0.83,0.77,0.84,0.79,0.82,0.86,0.73,0.71,0.73,0.72,0.70,0.73,0.72,0.76,0.81,0.76,0.76,0.82,0.77,0.89,0.85,0.82,0.75,0.80,0.80,0.94,0.88,0.94,0.87,0.95,0.96,0.88,0.72,0.74,0.76,0.83,0.78,0.84,0.79,0.87,0.91,0.83,0.89,0.98,0.92,1.23,1.34,1.05,1.16,0.99,0.96,1.46,1.57,1.54,1.33,1.05,1.26,1.08,1.37,1.10,0.98,1.03,0.92,1.14,0.86,0.95,0.97,0.90,0.89,0.79,0.84,0.77,0.82,0.76,0.82,0.97,0.89,0.98,0.71,0.72,0.74,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.34,1.51,1.53,1.67,1.72,1.71,1.80,1.77,1.91,1.86,1.98,1.86,1.82,1.95,1.89,1.24,1.10,1.41,0.95,0.99,1.09,1.25,1.37,1.63,1.55,0.96,0.98,1.16,1.05,1.00,1.27,1.23,1.50,1.69,1.46,1.86,1.72,1.87,1.24,1.49,1.44,1.69,1.80,1.59,1.69,1.97,1.82,1.94,1.91,1.92,1.99,1.63,1.50,1.74,1.16,1.33,1.38,1.58,1.60,1.77,1.80,1.48,1.21,1.37,0.90,0.97,0.93,1.05,0.97,1.04,1.21,0.99,0.95,1.14,0.92,1.02,1.34,0.94,0.86,0.90,0.74,0.79,0.75,0.81,0.79,0.84,0.86,0.71,0.71,0.73,0.76,0.73,0.77,0.74,0.80,0.85,0.78,0.81,0.89,0.84,0.97,0.92,0.88,0.79,0.85,0.86,0.98,0.92,1.00,0.93,1.06,1.12,0.95,0.74,0.74,0.78,0.79,0.76,0.82,0.79,0.87,0.93,0.85,0.85,0.94,0.90,1.09,1.27,0.99,1.17,1.05,0.96,1.46,1.71,1.62,1.48,1.20,1.34,1.28,1.57,1.35,0.90,0.94,0.85,0.98,0.81,0.89,0.89,0.83,0.82,0.75,0.78,0.73,0.77,0.72,0.76,0.89,0.83,0.91,0.71,0.70,0.72,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00},
+{1.26,1.39,1.48,1.51,1.64,1.71,1.60,1.58,1.77,1.74,1.91,1.94,1.87,1.97,1.85,1.10,0.97,1.22,0.88,0.92,0.95,1.01,1.11,1.39,1.32,0.88,0.90,0.97,0.96,0.93,1.05,0.99,1.27,1.47,1.20,1.70,1.54,1.76,1.08,1.31,1.33,1.70,1.76,1.55,1.57,1.88,1.85,1.91,1.97,1.99,1.99,1.70,1.65,1.85,1.41,1.54,1.61,1.76,1.80,1.91,1.93,1.52,1.26,1.48,0.92,0.99,0.97,1.18,1.09,1.28,1.39,0.94,0.93,1.05,0.92,1.01,1.31,0.88,0.81,0.86,0.72,0.75,0.74,0.79,0.79,0.86,0.85,0.71,0.73,0.75,0.82,0.77,0.83,0.78,0.85,0.88,0.81,0.88,0.97,0.90,1.18,1.00,0.93,0.86,0.92,0.94,1.14,0.99,1.24,1.03,1.33,1.39,1.11,0.79,0.77,0.84,0.79,0.77,0.84,0.83,0.90,0.98,0.91,0.85,0.92,0.91,1.02,1.26,1.00,1.23,1.19,0.99,1.50,1.84,1.71,1.64,1.38,1.46,1.51,1.76,1.59,0.84,0.88,0.80,0.94,0.79,0.86,0.82,0.77,0.76,0.74,0.74,0.71,0.73,0.70,0.72,0.82,0.77,0.85,0.74,0.70,0.73,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00,1.00}
+
Index: branches/network/src/lib/graphics/importer/grid.cc
===================================================================
--- branches/network/src/lib/graphics/importer/grid.cc	(revision 6636)
+++ branches/network/src/lib/graphics/importer/grid.cc	(revision 6636)
@@ -0,0 +1,83 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: ...
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "grid.h"
+
+using namespace std;
+
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+Grid::Grid(float sizeX, float sizeY, unsigned int rows, unsigned int columns)
+{
+  this->planeModel(sizeX, sizeY, rows, columns);
+
+  this->_rows = rows;
+  this->_columns = columns;
+  this->_sizeX = sizeX;
+  this->_sizeY = sizeY;
+  this->_gridSpacingX = sizeX / (float)rows;
+  this->_gridSpacingY = sizeY / (float)columns;
+}
+
+
+/**
+ * standard deconstructor
+*/
+Grid::~Grid ()
+{
+  // delete what has to be deleted here
+}
+
+
+void Grid::rebuildNormals(float maxHeight)
+{
+  for (unsigned int i = 1; i < this->_rows-1; i++)
+  {
+    for (unsigned int j = 1; j < this->_columns-1; j++)
+    {
+/*
+      Vector test( this->_gridSpacingX/(this->vertex(i*_columns+j).y - this->vertex(i*_columns+j-1).y) +
+          this->_gridSpacingX/(this->vertex(i*_columns+j+1).y - this->vertex(i*_columns+j).y)
+          ,
+      _gridSpacingX,
+      this->_gridSpacingY/(this->vertex(i*_columns+j).y - this->vertex((i-1)*_columns+j).y) +
+          this->_gridSpacingX/(this->vertex((i+1)*_columns+j).y - this->vertex(i*_columns+j).y)
+                 );*/
+
+
+
+      Vector test  (
+          (-this->vertex(i*_columns+j-1).y - this->vertex(i*_columns+j+1).y)/maxHeight,
+            1.0,
+            (-this->vertex((i-1)*_columns+j).y - this->vertex((i+1)*_columns+j).y)/maxHeight
+          );
+
+
+//      Vector test(
+//           (this->vertex(i*_columns+j).y + this->vertex((i-1)*_columns+j).y - this->vertex((i+1)*_columns+j).y ) /maxHeight,
+//           1.0,
+//           (this->vertex(i*_columns+j).y - this->vertex(i*_columns+j-1).y + this->vertex(i*_columns+j+1).y)/maxHeight
+//                 );
+      this->normal( i*_columns+j) = test.getNormalized();
+    }
+
+  }
+
+}
Index: branches/network/src/lib/graphics/importer/grid.h
===================================================================
--- branches/network/src/lib/graphics/importer/grid.h	(revision 6636)
+++ branches/network/src/lib/graphics/importer/grid.h	(revision 6636)
@@ -0,0 +1,47 @@
+/*!
+ * @file grid.h
+ * @brief Definition of ...
+*/
+
+#ifndef _GRID_H
+#define _GRID_H
+
+#include "vertex_array_model.h"
+
+// FORWARD DECLARATION
+
+
+
+//! A class for ...
+class Grid : public VertexArrayModel
+{
+
+public:
+  Grid(float sizeX, float sizeY, unsigned int resolutionX, unsigned int resolutionY);
+  virtual ~Grid();
+
+  float gridSpacing() const { return this->_gridSpacingX; };
+  float sizeX() const { return this->_sizeX; };
+  float sizeY() const { return this->_sizeY; };
+  unsigned int rows() const { return this->_rows; };
+  unsigned int columns() const { return this->_columns; };
+
+  float& height(unsigned int row, unsigned int column) { return this->vertex(row*this->_columns + column).y;};
+  Vector& vertexG(unsigned int row, unsigned int column) { return this->vertex(row*this->_columns + column); };
+  Vector& normalG(unsigned int row, unsigned int column) { return this->normal(row*this->_columns + column); };
+
+
+  void rebuildNormals(float maxHeight);
+
+private:
+  float             _sizeX;
+  float             _sizeY;
+
+  float             _gridSpacingX;
+  float             _gridSpacingY;
+
+  unsigned int      _rows;
+  unsigned int      _columns;
+};
+
+#endif /* _GRID_H */
Index: branches/network/src/lib/graphics/importer/height_map.cc
===================================================================
--- branches/network/src/lib/graphics/importer/height_map.cc	(revision 6636)
+++ branches/network/src/lib/graphics/importer/height_map.cc	(revision 6636)
@@ -0,0 +1,136 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: 
+*/
+
+#include "height_map.h"
+#include "model.h"
+#include "texture.h"
+#include "vector.h"
+
+#include "debug.h"
+
+// INCLUDING SDL_Image
+#ifdef HAVE_SDL_IMAGE_H
+#include <SDL_image.h>
+#else
+#include <SDL/SDL_image.h>
+#endif
+
+HeightMap::HeightMap() : StaticModel()
+{
+	
+}
+
+HeightMap::HeightMap(const char* height_map_name = NULL) : StaticModel()
+{
+   this->setClassID(CL_HEIGHT_MAP, "HeightMap");
+   heightMap =  IMG_Load(height_map_name);
+   if(heightMap!=NULL) {
+	
+		 PRINTF(0)("loading Image %s\n", height_map_name);
+		 PRINTF(0)("width : %i\n", heightMap->w);
+		 PRINTF(0)("hight : %i\n", heightMap->h);
+		 PRINTF(0)("%i Byte(s) per Pixel \n", heightMap->format->BytesPerPixel);
+		 PRINTF(0)("Rshift : %i\n", heightMap->format->Rshift);
+		 PRINTF(0)("Bshift: %i\n", heightMap->format->Bshift);
+		 PRINTF(0)("Gshift: %i\n", heightMap->format->Gshift);
+		 PRINTF(0)("Rmask: %i\n", heightMap->format->Rmask);
+		 PRINTF(0)("Gmask: %i\n", heightMap->format->Gmask);		
+		}
+		 
+     else       PRINTF(4)("oops! couldn't load %s for some reason.\n", height_map_name);
+}
+
+
+HeightMap::~HeightMap()
+{
+	delete heightMap;
+}
+
+void HeightMap::load()
+{
+ unsigned char height = 0; 
+ int offset = 0;
+
+ char *  bmp = (char*) heightMap->pixels;
+
+  if(heightMap != NULL && heightMap->format->BitsPerPixel == 8 )
+	{
+	SDL_LockSurface(heightMap);
+	for(int i = 0 ; i < heightMap->h  ; i +=2)
+	{
+	    for(int j = 0; j < heightMap->w   ;  j += 2)
+	    {
+	    	// get local hight from heightMap
+		// This seems to work only on 8-Bit Grayscale-Bitmaps
+		height = bmp[j + i*(heightMap->w )];
+		
+			
+		/*height = heightMap->format->palette->colors[offset].r +
+			   heightMap->format->palette->colors[offset].g +
+			   heightMap->format->palette->colors[offset].b ; */
+					
+				
+		this->addVertex( 20*(heightMap->h - i) , (( (double)height)/0.3)-1200  ,20*j);
+	     }	
+	}
+	SDL_UnlockSurface(heightMap);
+
+
+
+	int c = (heightMap->w)/2 ; // One line
+	for(int i = 0; i < (heightMap->w)/2  -2  ; i ++)
+	{
+	    for(int j = 0; j < (heightMap->h)/2 - 2; j++)
+	    {
+		 
+		/* Two Triangles or ...*/ 
+		
+		//this->addFace (3, VERTEX_ONLY,j + (i+1)*c,j+1+i*c , j + i*c );
+		//this->addFace (3, VERTEX_ONLY,j + (i+1)*c,j + (i+1)*c +1 ,j+i*c +1 );				
+				 
+		/* ... one square*/
+
+		this->addFace (4 ,VERTEX_ONLY,j+i*c,j+(i+1)*c  ,j + (i+1)*c +1, j +i*c+1 );
+	    }
+				
+			
+				
+	}
+		
+
+	}//if
+  else
+   	{ 
+
+  //make a cube
+  this->setName("HardCore");
+  this->addVertex (-0.5, -0.5, 0.5);
+  this->addVertex (0.5, -0.5, 0.5);
+  this->addVertex (-0.5, 0.5, 0.5);
+  this->addVertex (0.5, 0.5, 0.5);
+  this->addVertex (-0.5, 0.5, -0.5);
+  this->addVertex (0.5, 0.5, -0.5);
+  this->addVertex (-0.5, -0.5, -0.5);
+  this->addVertex (0.5, -0.5, -0.5);
+	
+
+
+
+  this->addFace (3, VERTEX_ONLY, 4, 3, 2);
+
+	}
+      this->finalize();
+
+
+}
Index: branches/network/src/lib/graphics/importer/height_map.h
===================================================================
--- branches/network/src/lib/graphics/importer/height_map.h	(revision 6636)
+++ branches/network/src/lib/graphics/importer/height_map.h	(revision 6636)
@@ -0,0 +1,33 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer:
+*/
+
+
+#include "static_model.h"
+
+class SDL_Surface;
+class Vector;
+
+class HeightMap : public StaticModel
+{
+public:
+void load();
+void load(const char*, int);
+HeightMap();
+HeightMap(const char*);
+~HeightMap();
+
+private:
+SDL_Surface* heightMap;
+
+};
Index: branches/network/src/lib/graphics/importer/material.cc
===================================================================
--- branches/network/src/lib/graphics/importer/material.cc	(revision 6636)
+++ branches/network/src/lib/graphics/importer/material.cc	(revision 6636)
@@ -0,0 +1,340 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "material.h"
+
+#include "texture.h"
+#include "debug.h"
+#include "resource_manager.h"
+#include <stdlib.h>
+#include <string.h>
+
+//! @todo check if we are in RESOURCE MANAGER-mode
+#include "resource_manager.h"
+
+using namespace std;
+
+/**
+ * creates a Material.
+ * @param mtlName Name of the Material to be added to the Material List
+ */
+Material::Material (const char* mtlName)
+{
+  this->setClassID(CL_MATERIAL, "Material");
+
+  this->setIllum(3);
+  this->setDiffuse(1,1,1);
+  this->setAmbient(0,0,0);
+  this->setSpecular(.5,.5,.5);
+  this->setShininess(2.0);
+  this->setTransparency(1.0);
+
+  this->diffuseTexture = NULL;
+  this->ambientTexture = NULL;
+  this->specularTexture = NULL;
+
+  this->setName(mtlName);
+}
+
+/**
+  *  deletes a Material
+*/
+Material::~Material()
+{
+  PRINTF(5)("delete Material %s.\n", this->getName());
+
+  if (this->diffuseTexture != NULL)
+  {
+    ResourceManager::getInstance()->unload(this->diffuseTexture);
+  }
+  if (this->ambientTexture != NULL)
+    ResourceManager::getInstance()->unload(this->ambientTexture);
+  if (this->specularTexture != NULL)
+    ResourceManager::getInstance()->unload(this->specularTexture);
+}
+
+Material& Material::operator=(const Material& m)
+{
+  this->setIllum(m.illumModel);
+  this->setDiffuse(m.diffuse[0],m.diffuse[1],m.diffuse[2]);
+  this->setAmbient(m.ambient[0],m.ambient[1],m.ambient[2]);
+  this->setSpecular(m.specular[0],m.specular[1],m.specular[2]);
+  this->setShininess(m.shininess);
+  this->setTransparency(m.transparency);
+
+  if (this->diffuseTexture != NULL)
+    ResourceManager::getInstance()->unload(this->diffuseTexture);
+  if (m.diffuseTexture != NULL)
+    this->diffuseTexture = m.diffuseTexture; /// HACK shoudl be:(Texture*)ResourceManager::getInstance()->load();
+  this->ambientTexture = NULL; /// FIXME
+  this->specularTexture = NULL; /// FIXME
+
+  this->setName(m.getName());
+}
+
+
+/**
+ *  sets the material with which the following Faces will be painted
+ */
+bool Material::select () const
+{
+  // setting diffuse color
+  glColor3f (diffuse[0], diffuse[1], diffuse[2]);
+  glMaterialfv(GL_FRONT, GL_DIFFUSE, this->diffuse);
+
+  // setting ambient color
+  glMaterialfv(GL_FRONT, GL_AMBIENT, this->ambient);
+
+  // setting up Sprecular
+  glMaterialfv(GL_FRONT, GL_SPECULAR, this->specular);
+
+  // setting up Shininess
+  glMaterialf(GL_FRONT, GL_SHININESS, this->shininess);
+
+  // setting the transparency
+  if (this->transparency < 1.0)
+    {
+      glEnable(GL_BLEND);
+      glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+      glColor4f(*(this->diffuse), *(this->diffuse+1), *(this->diffuse+2), this->transparency);
+    }
+  else
+    {
+      glDisable(GL_BLEND);
+      glColor4f(*(this->diffuse), *(this->diffuse+1), *(this->diffuse+2), 1);
+    }
+
+
+  // setting illumination Model
+  if (this->illumModel == 1) //! @todo make this work, if no vertex-normals are read.
+    glShadeModel(GL_FLAT);
+  else if (this->illumModel >= 2)
+    glShadeModel(GL_SMOOTH);
+
+  if (this->diffuseTexture != NULL)
+    {
+      glEnable(GL_TEXTURE_2D);
+      glBindTexture(GL_TEXTURE_2D, this->diffuseTexture->getTexture());
+
+      /* This allows alpha blending of 2D textures with the scene */
+      if (this->diffuseTexture->hasAlpha())
+        {
+          glEnable(GL_BLEND);
+          glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+        }
+    }
+  else
+    {
+      glDisable(GL_TEXTURE_2D);
+      glBindTexture(GL_TEXTURE_2D, 0);
+    }
+}
+
+/**
+ *  Sets the Material Illumination Model.
+ *  illu illumination Model in int form
+ */
+void Material::setIllum (int illum)
+{
+  PRINTF(4)("setting illumModel of Material %s to %i\n", this->getName(), illum);
+  this->illumModel = illum;
+}
+
+/**
+ *  Sets the Material Illumination Model.
+ *  illu illumination Model in char* form
+ */
+void Material::setIllum (char* illum)
+{
+  this->setIllum (atoi(illum));
+}
+
+/**
+ *  Sets the Material Diffuse Color.
+ * @param r Red Color Channel.
+ * @param g Green Color Channel.
+ * @param b Blue Color Channel.
+ */
+void Material::setDiffuse (float r, float g, float b)
+{
+  PRINTF(4)("setting Diffuse Color of Material %s to r=%f g=%f b=%f.\n", this->getName(), r, g, b);
+  this->diffuse[0] = r;
+  this->diffuse[1] = g;
+  this->diffuse[2] = b;
+  this->diffuse[3] = 1.0;
+
+}
+
+/**
+ *  Sets the Material Diffuse Color.
+ * @param rgb The red, green, blue channel in char format (with spaces between them)
+ */
+void Material::setDiffuse (char* rgb)
+{
+  float r,g,b;
+  sscanf (rgb, "%f %f %f", &r, &g, &b);
+  this->setDiffuse (r, g, b);
+}
+
+/**
+ *  Sets the Material Ambient Color.
+ * @param r Red Color Channel.
+ * @param g Green Color Channel.
+ * @param b Blue Color Channel.
+*/
+void Material::setAmbient (float r, float g, float b)
+{
+  PRINTF(4)("setting Ambient Color of Material %s to r=%f g=%f b=%f.\n", this->getName(), r, g, b);
+  this->ambient[0] = r;
+  this->ambient[1] = g;
+  this->ambient[2] = b;
+  this->ambient[3] = 1.0;
+}
+
+/**
+ *  Sets the Material Ambient Color.
+ * @param rgb The red, green, blue channel in char format (with spaces between them)
+ */
+void Material::setAmbient (char* rgb)
+{
+  float r,g,b;
+  sscanf (rgb, "%f %f %f", &r, &g, &b);
+  this->setAmbient (r, g, b);
+}
+
+/**
+ *  Sets the Material Specular Color.
+ * @param r Red Color Channel.
+ * @param g Green Color Channel.
+ * @param b Blue Color Channel.
+ */
+void Material::setSpecular (float r, float g, float b)
+{
+  PRINTF(4)("setting Specular Color of Material %s to r=%f g=%f b=%f.\n", this->getName(), r, g, b);
+  this->specular[0] = r;
+  this->specular[1] = g;
+  this->specular[2] = b;
+  this->specular[3] = 1.0;
+ }
+
+/**
+ *  Sets the Material Specular Color.
+ * @param rgb The red, green, blue channel in char format (with spaces between them)
+*/
+void Material::setSpecular (char* rgb)
+{
+  float r,g,b;
+  sscanf (rgb, "%f %f %f", &r, &g, &b);
+  this->setSpecular (r, g, b);
+}
+
+/**
+ *  Sets the Material Shininess.
+ * @param shini stes the Shininess from float.
+*/
+void Material::setShininess (float shini)
+{
+  this->shininess = shini;
+}
+/**
+ *  Sets the Material Shininess.
+ * @param shini stes the Shininess from char*.
+*/
+void Material::setShininess (char* shini)
+{
+  this->setShininess (atof(shini));
+}
+
+/**
+ *  Sets the Material Transparency.
+ * @param trans stes the Transparency from int.
+*/
+void Material::setTransparency (float trans)
+{
+  PRINTF(4)("setting Transparency of Material %s to %f.\n", this->getName(), trans);
+  this->transparency = trans;
+}
+/**
+ *  Sets the Material Transparency.
+ * @param trans stes the Transparency from char*.
+*/
+void Material::setTransparency (char* trans)
+{
+  this->setTransparency (atof(trans));
+}
+
+/**
+ *  Adds a Texture Path to the List of already existing Paths
+ * @param pathName The Path to add.
+*/
+void Material::addTexturePath(const char* pathName)
+{
+  ResourceManager::getInstance()->addImageDir(pathName);
+}
+
+// MAPPING //
+
+/**
+ *  Sets the Materials Diffuse Map
+ * @param dMap the Name of the Image to Use
+*/
+void Material::setDiffuseMap(const char* dMap, GLenum target)
+{
+  PRINTF(5)("setting Diffuse Map %s\n", dMap);
+  if (this->diffuseTexture != NULL)
+    ResourceManager::getInstance()->unload(this->diffuseTexture);
+
+  //! @todo check if RESOURCE MANAGER is availiable
+  //! @todo Textures from .mtl-file need special care.
+  if (dMap != NULL)
+    this->diffuseTexture = (Texture*)ResourceManager::getInstance()->load(dMap, IMAGE, RP_GAME, (void*)&target);
+  else
+    this->diffuseTexture = NULL;
+}
+
+/**
+ *  Sets the Materials Ambient Map
+ * @param aMap the Name of the Image to Use
+   @todo implement this
+*/
+void Material::setAmbientMap(const char* aMap, GLenum target)
+{
+  SDL_Surface* ambientMap;
+
+}
+
+/**
+ *  Sets the Materials Specular Map
+ * @param sMap the Name of the Image to Use
+   @todo implement this
+*/
+void Material::setSpecularMap(const char* sMap, GLenum target)
+{
+  SDL_Surface* specularMap;
+
+}
+
+/**
+ *  Sets the Materials Bumpiness
+ * @param bump the Name of the Image to Use
+   @todo implemet this
+*/
+void Material::setBump(const char* bump)
+{
+
+}
Index: branches/network/src/lib/graphics/importer/material.h
===================================================================
--- branches/network/src/lib/graphics/importer/material.h	(revision 6636)
+++ branches/network/src/lib/graphics/importer/material.h	(revision 6636)
@@ -0,0 +1,68 @@
+/*!
+  \file material.h
+  \brief Contains the Material Class that handles Material for 3D-Objects.
+  @todo free SDL-surface when deleting Material.
+  @todo delete imgNameWithPath after use creation.
+*/
+
+#ifndef _MATERIAL_H
+#define _MATERIAL_H
+#include "base_object.h"
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#ifndef NULL
+#define NULL 0            //!< a pointer to NULL
+#endif
+
+// FORWARD DECLARATIONS //
+class Texture;
+
+//! Class to handle Materials.
+class Material : public BaseObject
+{
+ public:
+  Material (const char* mtlName = NULL);
+  virtual ~Material ();
+
+  Material& operator=(const Material& material);
+
+  bool select () const;
+
+  void setIllum (int illum);
+  void setIllum (char* illum);
+  int getIllumModel() const { return this->illumModel; };
+  void setDiffuse (float r, float g, float b);
+  void setDiffuse (char* rgb);
+  void setAmbient (float r, float g, float b);
+  void setAmbient (char* rgb);
+  void setSpecular (float r, float g, float b);
+  void setSpecular (char* rgb);
+  void setShininess (float shini);
+  void setShininess (char* shini);
+  void setTransparency (float trans);
+  void setTransparency (char* trans);
+
+ // MAPPING //
+  void setDiffuseMap(const char* dMap, GLenum target = GL_TEXTURE_2D);
+  void setAmbientMap(const char* aMap, GLenum target = GL_TEXTURE_2D);
+  void setSpecularMap(const char* sMap, GLenum target = GL_TEXTURE_2D);
+  void setBump(const char* bump);
+
+  static void addTexturePath(const char* pathName);
+
+  private:
+    int         illumModel;       //!< The IlluminationModel is either flat or smooth.
+    float       diffuse [4];      //!< The diffuse color of the Material.
+    float       ambient [4];      //!< The ambient color of the Material.
+    float       specular [4];     //!< The specular color of the Material.
+    float       shininess;        //!< The shininess of the Material.
+    float       transparency;     //!< The transperency of the Material.
+
+    Texture*    diffuseTexture;   //!< The diffuse texture of the Material.
+    Texture*    ambientTexture;   //!< The ambient texture of the Material.
+    Texture*    specularTexture;  //!< The specular texture of the Material.
+};
+#endif
Index: branches/network/src/lib/graphics/importer/md2Model.cc
===================================================================
--- branches/network/src/lib/graphics/importer/md2Model.cc	(revision 6636)
+++ branches/network/src/lib/graphics/importer/md2Model.cc	(revision 6636)
@@ -0,0 +1,490 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "md2Model.h"
+#include "material.h"
+
+#include "debug.h"
+#include "resource_manager.h"
+
+
+using namespace std;
+
+//! the model anorms
+sVec3D MD2Model::anorms[NUM_VERTEX_NORMALS] = {
+ #include "anorms.h"
+};
+
+//! anormal dots, no idea of how this shall work, but it does
+float MD2Model::anormsDots[SHADEDOT_QUANT][256] = {
+  #include "anormtab.h"
+};
+
+
+//! the angle under which the model is viewd, used internaly
+float md2Angle = 0.0f;
+
+
+//! list of all different animations a std md2model supports
+sAnim MD2Model::animationList[21] =
+  {
+ // begin, end, fps, interruptable
+    {   0,  39,  9, 1 },   //!< STAND
+    {  40,  45, 10, 1 },   //!< RUN
+    {  46,  53, 10, 0 },   //!< ATTACK
+    {  54,  57,  7, 1 },   //!< PAIN_A
+    {  58,  61,  7, 1 },   //!< PAIN_B
+    {  62,  65,  7, 1 },   //!< PAIN_C
+    {  66,  71,  7, 0 },   //!< JUMP
+    {  72,  83,  7, 1 },   //!< FLIP
+    {  84,  94,  7, 1 },   //!< SALUTE
+    {  95, 111, 10, 1 },   //!< FALLBACK
+    { 112, 122,  7, 1 },   //!< WAVE
+    { 123, 134,  6, 1 },   //!< POINTT
+    { 135, 153, 10, 1 },   //!< CROUCH_STAND
+    { 154, 159,  7, 1 },   //!< CROUCH_WALK
+    { 160, 168, 10, 1 },   //!< CROUCH_ATTACK
+    { 196, 172,  7, 1 },   //!< CROUCH_PAIN
+    { 173, 177,  5, 0 },   //!< CROUCH_DEATH
+    { 178, 183,  7, 0 },   //!< DEATH_FALLBACK
+    { 184, 189,  7, 0 },   //!< DEATH_FALLFORWARD
+    { 190, 197,  7, 0 },   //!< DEATH_FALLBACKSLOW
+    { 198, 198,  5, 1 },   //!< BOOM
+  };
+
+
+
+/********************************************************************************
+ *   MD2Model                                                                   *
+ ********************************************************************************/
+
+/**
+  \brief simple constructor initializing all variables
+*/
+MD2Model::MD2Model(const char* modelFileName, const char* skinFileName)
+{
+  /* this creates the data container via ressource manager */
+  this->data = (MD2Data*)ResourceManager::getInstance()->load(modelFileName, MD2, RP_GAME, (void*)skinFileName);
+  if( unlikely(this->data == NULL))
+    PRINTF(0)("The model was not found, MD2Model Loader finished abnormaly. Update the data-repos\n");
+
+  this->scaleFactor = this->data->scaleFactor;
+
+  shadeDots = MD2Model::anormsDots[0];
+  /* set the animation stat mannualy */
+  this->animationState.type = STAND;
+  this->animationState.numPlays = 1;
+  this->setAnim(STAND);
+
+  this->debug();
+}
+
+/**
+  \brief simple destructor, dereferencing all variables
+
+  this is where the ressource manager is cleaning the stuff
+*/
+MD2Model::~MD2Model()
+{
+  ResourceManager::getInstance()->unload(this->data);
+}
+
+
+/**
+ *  initializes an array of vert with the current frame scaled vertices
+ * @param this->verticesList: the list of vertices to interpolate between
+
+   we won't use the pVertices array directly, since its much easier and we need
+   saving of data anyway
+*/
+void MD2Model::interpolate(/*sVec3D* this->verticesList*/)
+{
+  sVec3D* currVec;
+  sVec3D* nextVec;
+
+  currVec = &this->data->pVertices[this->data->numVertices * this->animationState.currentFrame];
+  nextVec = &this->data->pVertices[this->data->numVertices * this->animationState.nextFrame];
+
+  for( int i = 0; i < this->data->numVertices; ++i)
+    {
+      this->verticesList[i][0] = currVec[i][0] + this->animationState.interpolationState * (nextVec[i][0] - currVec[i][0]);
+      this->verticesList[i][1] = currVec[i][1] + this->animationState.interpolationState * (nextVec[i][1] - currVec[i][1]);
+      this->verticesList[i][2] = currVec[i][2] + this->animationState.interpolationState * (nextVec[i][2] - currVec[i][2]);
+    }
+}
+
+
+/**
+  \brief sets the animation type
+* @param type: animation type
+
+  the animation types can be looked up in the animationType table
+*/
+void MD2Model::setAnim(int type)
+{
+  if( (type < 0) || (type > MAX_ANIMATIONS) )
+    type = STAND;
+
+  if( MD2Model::animationList[this->animationState.type].bStoppable == 0)
+  {
+    if( this->animationState.numPlays == 0 )
+      return;
+  }
+
+  this->animationState.startFrame = animationList[type].firstFrame;
+  this->animationState.endFrame = animationList[type].lastFrame;
+  this->animationState.nextFrame = animationList[type].firstFrame + 1;
+  this->animationState.fps = animationList[type].fps;
+  this->animationState.type = type;
+  this->animationState.numPlays = 0;
+
+  this->animationState.interpolationState = 0.0f;
+  this->animationState.localTime = 0.0f;
+  this->animationState.lastTime = 0.0f;
+  this->animationState.currentFrame = animationList[type].firstFrame;
+}
+
+
+/**
+  \brief sets the time in seconds passed since the last tick
+* @param time: in sec
+*/
+void MD2Model::tick(float time)
+{
+  this->animate(time);
+  this->processLighting();
+  this->interpolate(/*this->verticesList*/);
+}
+
+
+/**
+ * @brief draws the model: interface for all other classes out in the world
+ * @todo make it const and virtual
+ * FIXME
+ */
+void MD2Model::draw() const
+{
+  glPushMatrix();
+  this->renderFrame();
+  // renderFrameTriangles();
+  glPopMatrix();
+}
+
+
+/**
+  \brief this is an internal function to render this special frame selected by animate()
+*/
+void MD2Model::renderFrame() const
+{
+  int* pCommands = this->data->pGLCommands;
+
+  /* some face culling stuff */
+  glPushAttrib(GL_POLYGON_BIT);
+  glFrontFace(GL_CW);
+  glEnable(GL_CULL_FACE);
+  glCullFace(GL_BACK);
+
+  this->data->material->select();
+
+  /* draw the triangles */
+  while( int i = *(pCommands++)) /* strange looking while loop for maximum performance */
+    {
+      if( i < 0)
+        {
+          glBegin(GL_TRIANGLE_FAN);
+          i = -i;
+        }
+      else
+        {
+          glBegin(GL_TRIANGLE_STRIP);
+        }
+
+      for(; i > 0; i--, pCommands += 3) /* down counting for loop, next 3 gl commands */
+        {
+          glTexCoord2f( ((float *)pCommands)[0], ((float *)pCommands)[1] );
+          glNormal3fv(anorms[this->data->pLightNormals[pCommands[2]]]);
+          glVertex3fv(this->verticesList[pCommands[2]]);
+        }
+      glEnd();
+
+    }
+  glDisable(GL_CULL_FACE);
+  glPopAttrib();
+}
+
+
+void MD2Model::renderFrameTriangles() const
+{
+  //static sVec3D this->verticesList[MD2_MAX_VERTICES]; /* performance: created only once in a lifetime */
+  int* pCommands = this->data->pGLCommands;
+  /* some face culling stuff */
+//   glPushAttrib(GL_POLYGON_BIT);
+//   glFrontFace(GL_CW);
+//   glEnable(GL_CULL_FACE);
+//   glCullFace(GL_BACK);
+//
+//   this->processLighting();
+//   this->interpolate(/*this->verticesList*/);
+  this->data->material->select();
+
+  /* draw the triangles */
+  glBegin(GL_TRIANGLES);
+
+  for( int i = 0, k = 0; i < this->data->numTriangles; ++i, k += 3)
+  {
+    float* v = this->data->pVertices[this->data->pTriangles[i].indexToVertices[0]];
+
+    printf("triangle: %i\n", i);
+    printf("     v0: (%f, %f, %f)\n", v[0], v[1], v[2]);
+    v = this->data->pVertices[this->data->pTriangles[i].indexToVertices[1]];
+    printf("     v1: (%f, %f, %f)\n", v[0], v[1], v[2]);
+    v = this->data->pVertices[this->data->pTriangles[i].indexToVertices[2]];
+    printf("     v2: (%f, %f, %f)\n", v[0], v[1], v[2]);
+
+
+    glNormal3f(anorms[i][0], anorms[i][1], anorms[i][2]);
+    glVertex3fv(this->data->pVertices[this->data->pTriangles[i].indexToVertices[0]]);
+
+    glNormal3f(anorms[i][0], anorms[i][1], anorms[i][2]);
+    glVertex3fv(this->data->pVertices[this->data->pTriangles[i].indexToVertices[1]]);
+
+    glNormal3f(anorms[i][0], anorms[i][1], anorms[i][2]);
+    glVertex3fv(this->data->pVertices[this->data->pTriangles[i].indexToVertices[2]]);
+  }
+
+  glEnd();
+}
+
+
+/**
+  \brief animates the current model
+
+  depending on the time passed (tick function), the player will select another model
+*/
+void MD2Model::animate(float time)
+{
+  this->animationState.localTime += time;
+
+  if( this->animationState.localTime - this->animationState.lastTime > (1.0f / this->animationState.fps))
+    {
+      this->animationState.currentFrame = this->animationState.nextFrame;
+      this->animationState.nextFrame++;
+
+      if( this->animationState.nextFrame > this->animationState.endFrame)
+      {
+        this->animationState.nextFrame = this->animationState.startFrame;
+        this->animationState.numPlays++;
+      }
+      this->animationState.lastTime = this->animationState.localTime;
+    }
+
+  if( this->animationState.currentFrame > (this->data->numFrames - 1) )
+    this->animationState.currentFrame = 0;
+  if( this->animationState.nextFrame > (this->data->numFrames - 1) )
+    this->animationState.nextFrame = 0;
+
+  this->animationState.interpolationState = this->animationState.fps *
+    (this->animationState.localTime - this->animationState.lastTime);
+}
+
+
+/**
+  \brief this is how id is precessing their lightning
+
+  the details of how the whole lighting process is beeing handled - i have no idea... :)
+*/
+void MD2Model::processLighting()
+{
+  shadeDots = anormsDots[((int)(md2Angle*(SHADEDOT_QUANT / 360.0)))&(SHADEDOT_QUANT - 1)];
+}
+
+
+/**
+  \brief prints out debug informations
+*/
+void MD2Model::debug()
+{
+  PRINT(0)("\n==========================| MD2Model::debug() |===\n");
+  PRINT(0)("=  Model FileName:\t%s\n", this->data->fileName);
+  PRINT(0)("=  Skin FileName:\t%s\n", this->data->skinFileName);
+  PRINT(0)("=  Size in Memory:\t%i Bytes\n", this->data->header->frameSize * this->data->header->numFrames + 64); // 64bytes is the header size
+  PRINT(0)("=  Number of Vertices:\t%i\n", this->data->header->numVertices);
+  PRINT(0)("=  Number of Frames: \t%i\n", this->data->header->numFrames);
+  PRINT(0)("=  Height, Width:\t%i, %i\n", this->data->header->skinHeight, this->data->header->skinWidth);
+  PRINT(0)("=  Pointer to the data object: %p\n", this->data);
+  PRINT(0)("===================================================\n\n");
+}
+
+
+/********************************************************************************
+ *   MD2Data                                                                    *
+ ********************************************************************************/
+
+/**
+  \brief simple constructor
+*/
+MD2Data::MD2Data(const char* modelFileName, const char* skinFileName)
+{
+  this->pVertices = NULL;
+  this->pGLCommands = NULL;
+  this->pLightNormals = NULL;
+  this->pTexCoor = NULL;
+
+  this->numFrames = 0;
+  this->numVertices = 0;
+  this->numGLCommands = 0;
+  this->numTexCoor = 0;
+
+//   this->scaleFactor = 1.0f;
+  this->scaleFactor = 0.1f;
+
+  this->fileName = NULL;
+  this->skinFileName = NULL;
+  this->loadModel(modelFileName);
+  this->loadSkin(skinFileName);
+}
+
+
+/**
+  \brief simple destructor
+
+  this will clean out all the necessary data for a specific md2model
+*/
+MD2Data::~MD2Data()
+{
+  delete [] this->fileName;
+  delete [] this->skinFileName;
+  delete this->header;
+
+  delete [] this->pVertices;
+  delete [] this->pGLCommands;
+  delete [] this->pLightNormals;
+  delete [] this->pTexCoor;
+
+  delete this->material;
+}
+
+
+
+/**
+  \brief this will load the whole model data (vertices, opengl command list, ...)
+* @param fileName: the name of the model file
+  \return true if success
+*/
+bool MD2Data::loadModel(const char* fileName)
+{
+  FILE *pFile;                            //file stream
+  char* buffer;                           //buffer for frame data
+  sFrame* frame;                          //temp frame
+  sVec3D *pVertex;
+  int* pNormals;
+
+  //! @todo this chek should include deleting a loaded model (eventually)
+  if (fileName == NULL)
+    return false;
+
+  pFile = fopen(fileName, "rb");
+  if( unlikely(!pFile))
+    {
+      PRINTF(1)("Couldn't open the MD2 File for loading. Exiting.\n");
+      return false;
+    }
+  this->header = new MD2Header;
+  fread(this->header, 1, sizeof(MD2Header), pFile);
+  /* check for the header version: make sure its a md2 file :) */
+  if( unlikely(this->header->version != MD2_VERSION) && unlikely(this->header->ident != MD2_IDENT))
+    {
+      PRINTF(1)("Couldn't load file %s: invalid file format: stop loading\n", fileName);
+      return false;
+    }
+
+  this->fileName = new char[strlen(fileName)+1];
+  strcpy(this->fileName, fileName);
+  /* got the data: map it to locals */
+  this->numFrames = this->header->numFrames;
+  this->numVertices = this->header->numVertices;
+  this->numTriangles = this->header->numTriangles;
+  this->numGLCommands = this->header->numGlCommands;
+  this->numTexCoor = this->header->numTexCoords;
+  /* allocate memory for the data storage */
+  this->pVertices = new sVec3D[this->numVertices * this->numFrames];
+  this->pGLCommands = new int[this->numGLCommands];
+  this->pLightNormals = new int[this->numVertices * this->numFrames];
+  this->pTriangles = new sTriangle[this->numTriangles];
+  this->pTexCoor = new sTexCoor[this->numTexCoor];
+  buffer = new char[this->numFrames * this->header->frameSize];
+
+
+  /* read frame data from the file to a temp buffer */
+  fseek(pFile, this->header->offsetFrames, SEEK_SET);
+  fread(buffer, this->header->frameSize, this->numFrames, pFile);
+  /* read opengl commands */
+  fseek(pFile, this->header->offsetGlCommands, SEEK_SET);
+  fread(this->pGLCommands, sizeof(int), this->numGLCommands, pFile);
+  /* triangle list */
+  fseek(pFile, this->header->offsetTriangles, SEEK_SET);
+  fread(this->pTriangles, sizeof(sTriangle), this->numTriangles, pFile);
+  /*  read in texture coordinates */
+  fseek(pFile, this->header->offsetTexCoords, SEEK_SET);
+  fread(this->pTexCoor, sizeof(sTexCoor), this->numTexCoor, pFile);
+
+
+  for(int i = 0; i < this->numFrames; ++i)
+    {
+      frame = (sFrame*)(buffer + this->header->frameSize * i);
+      pVertex = this->pVertices + this->numVertices  * i;
+      pNormals = this->pLightNormals + this->numVertices * i;
+
+      for(int j = 0; j < this->numVertices; ++j)
+        {
+          /* SPEEDUP: *(pVerts + i + 0) = (*(frame->pVertices + i + 0)...  */
+           pVertex[j][0] = ((frame->pVertices[j].v[0] * frame->scale[0] ) + frame->translate[0] )* this->scaleFactor;
+           pVertex[j][1] = ((frame->pVertices[j].v[2] * frame->scale[2]) + frame->translate[2]) * this->scaleFactor;
+           pVertex[j][2] = (-1.0 * (frame->pVertices[j].v[1] * frame->scale[1] + frame->translate[1])) * this->scaleFactor;
+
+          //printf("vertex %i/%i: (%f, %f, %f)\n", j, this->numVertices, pVertex[j][0], pVertex[j][1], pVertex[j][2]);
+
+          pNormals[j] = frame->pVertices[j].lightNormalIndex;
+        }
+    }
+    PRINTF(4)("Finished loading the md2 file\n");
+
+  delete [] buffer;
+  fclose(pFile);
+}
+
+
+/**
+  \brief loads the skin/material stuff
+* @param fileName: name of the skin file
+  \return true if success
+*/
+bool MD2Data::loadSkin(const char* fileName)
+{
+  if( fileName == NULL)
+    {
+      this->skinFileName = NULL;
+      return false;
+    }
+
+  this->skinFileName = new char[strlen(fileName)+1];
+  strcpy(this->skinFileName, fileName);
+
+  this->material = new Material("md2ModelTest");
+  this->material->setDiffuseMap(fileName);
+  this->material->setIllum(3);
+  this->material->setAmbient(1.0, 1.0, 1.0);
+}
Index: branches/network/src/lib/graphics/importer/md2Model.h
===================================================================
--- branches/network/src/lib/graphics/importer/md2Model.h	(revision 6636)
+++ branches/network/src/lib/graphics/importer/md2Model.h	(revision 6636)
@@ -0,0 +1,258 @@
+/*!
+ * @file md2Model.h
+  *  Definition of an MD2 Model, a model format invented by ID Software.
+
+    We are deeply thankfull for all the wunderfull things id software made for us gamers!
+
+    The md2 file format is structured in a very simple way: it contains animations which are made out of
+    frames (so called keyframes). Each frame is a complete draweable model in a specific position.
+    A frame is a collection of vertex and its compagnions (normals, texture coordinates).
+
+    A typical model has about 200 frames, the maximum frame count is fixed by MD2_MAX_FRAMES to currently
+    512 frames. The maximal vetices count is set to 2048 verteces, not enough?
+    You just have to change the MD2_MAX_* values if it doesn't fit your purposes...
+
+    Surface Culling is fully implemented in md2 models: quake2 uses front face culling.
+*/
+
+#ifndef _MD2MODEL_H
+#define _MD2MODEL_H
+
+#include "model.h"
+#include "base_object.h"
+#include "stdincl.h"
+
+
+//! These are the needed defines for the max values when loading .MD2 files
+#define MD2_IDENT                       (('2'<<24) + ('P'<<16) + ('D'<<8) + 'I') //!< the md2 identifier tag in the bin file
+#define MD2_VERSION                     8                                        //!< the md2 version in the header
+#define MD2_MAX_TRIANGLES               4096                                     //!< maximal triangles count
+#define MD2_MAX_VERTICES                2048                                     //!< maximal vertices count
+#define MD2_MAX_TEXCOORDS               2048                                     //!< maximal tex coordinates
+#define MD2_MAX_FRAMES                  512                                      //!< maximal frames
+#define MD2_MAX_SKINS                   32                                       //!< maximal skins
+#define MD2_MAX_FRAMESIZE               (MD2_MAX_VERTICES * 4 + 128)             //!< maximal framesize
+
+#define NUM_VERTEX_NORMALS              162                                      //!< number of vertex normals
+#define SHADEDOT_QUANT                  16                                       //!< shade dot quantity - no idea what it is
+
+//! This stores the speed of the animation between each key frame - currently conflicting with the animation framework
+#define kAnimationSpeed                 12.0f                                    //!< animation speed
+
+//! This holds the header information that is read in at the beginning of the file: id software definition
+struct MD2Header
+{
+   int ident;                           //!< This is used to identify the file
+   int version;                         //!< The version number of the file (Must be 8)
+
+   int skinWidth;                       //!< The skin width in pixels
+   int skinHeight;                      //!< The skin height in pixels
+   int frameSize;                       //!< The size in bytes the frames are
+
+   int numSkins;                        //!< The number of skins associated with the model
+   int numVertices;                     //!< The number of vertices (constant for each frame)
+   int numTexCoords;                    //!< The number of texture coordinates
+   int numTriangles;                    //!< The number of faces (polygons)
+   int numGlCommands;                   //!< The number of gl commands
+   int numFrames;                       //!< The number of animation frames
+
+   int offsetSkins;                     //!< The offset in the file for the skin data
+   int offsetTexCoords;                 //!< The offset in the file for the texture data
+   int offsetTriangles;                 //!< The offset in the file for the face data
+   int offsetFrames;                    //!< The offset in the file for the frames data
+   int offsetGlCommands;                //!< The offset in the file for the gl commands data
+   int offsetEnd;                       //!< The end of the file offset
+};
+
+
+//! compressed vertex data: char insetead of float, the value will be expanded by the scale value. only for loading
+typedef struct
+{
+  unsigned char    v[3];                 //!< the vector of the vertex
+  unsigned char    lightNormalIndex;     //!< the index of the light normal
+} sVertex;
+
+
+//! compressed texture offset data: coords scaled by the texture size. Only for loading
+typedef struct
+{
+  short            s;                    //!< the s,t coordinates of a texture
+  short            t;                    //!< the s,t coordinates of a texture
+} sTexCoor;
+
+
+//! holds tha informations about a md2 frame
+typedef struct
+{
+  sVec3D           scale;                //!< scales values of the model
+  sVec3D           translate;            //!< translates the model
+  char             name[16];             //!< frame name: something like "run32"
+  sVertex          pVertices[1];         //!< first vertex of thes frame
+} sFrame;
+
+
+//! holds the information about a triangle
+typedef struct
+{
+  unsigned short   indexToVertices[3];   //!< index to the verteces of the triangle
+  unsigned short   indexToTexCoor[3];    //!< index to the texture coordinates
+} sTriangle;
+
+
+
+//! the command list of the md2 model, very md2 specific
+typedef struct
+{
+  float            s;                    //!< texture coordinate 1
+  float            t;                    //!< texture coordinate 2
+  int              vertexIndex;          //!< index of the vertex in the vertex list
+} glCommandVertex;
+
+
+//! a md2 animation definition
+typedef struct
+{
+  int              firstFrame;           //!< first frame of the animation
+  int              lastFrame;            //!< last frame of the animation
+  int              fps;                  //!< speed: number of frames per second
+  int              bStoppable;           //!< 1 if the animation is stoppable 0 else
+} sAnim;
+
+
+//! animation state definition
+typedef struct
+{
+  int              startFrame;           //!< the start frame of an animation
+  int              endFrame;             //!< last frame of the animation
+  int              fps;                  //!< fps of the animaion (speed)
+
+  float            localTime;            //!< the local time
+  float            lastTime;             //!< last time stamp
+  float            interpolationState;   //!< the state of the animation [0..1]
+
+  int              type;                 //!< animation type
+
+  int              currentFrame;         //!< the current frame
+  int              nextFrame;            //!< the next frame in the list
+  int              numPlays;             //!< the number of times, this has been played in series
+} sAnimState;
+
+
+//! animation names enumeration
+typedef enum animType
+  {
+    STAND,
+    RUN,
+    ATTACK,
+    PAIN_A,
+    PAIN_B,
+    PAIN_C,
+    JUMP,
+    FLIP,
+    SALUTE,
+    FALLBACK,
+    WAVE,
+    POINTT,
+    CROUCH_STAND,
+    CROUCH_WALK,
+    CROUCH_ATTACK,
+    CROUCH_PAIN,
+    CROUCH_DEATH,
+    DEATH_FALLBACK,
+    DEATH_FALLFORWARD,
+    DEATH_FALLBACKSLOW,
+    BOOM,
+
+    MAX_ANIMATIONS
+  };
+
+
+
+/* forward definitions */
+class Material;
+
+
+
+//! class to store the md2 data in
+class MD2Data : public BaseObject
+{
+ public:
+  MD2Data(const char* modelFileName, const char* skinFileName);
+  virtual ~MD2Data();
+
+ private:
+  bool loadModel(const char* fileName);
+  bool loadSkin(const char* fileName = NULL);
+
+ public:
+  int                numFrames;             //!< number of frames
+  int                numVertices;           //!< number of vertices
+  int                numTriangles;          //!< number of triangles
+  int                numTexCoor;            //!< number of texture coordinates
+  int                numGLCommands;         //!< number of gl commands in the glList (tells how to draw)
+  char*              fileName;              //!< file name of the model File
+  char*              skinFileName;          //!< file name of the skin file
+  MD2Header*         header;                //!< the header file
+
+  sVec3D*            pVertices;             //!< pointer to the vertices data block
+  sTriangle*         pTriangles;            //!< pointer to the triangles data
+  sTexCoor*          pTexCoor;              //!< pointer to the texture coordinate data
+  int*               pGLCommands;           //!< pointer to the gllist data block
+  int*               pLightNormals;         //!< pointer to the light normals
+
+  Material*          material;              //!< pointer to the material
+  float              scaleFactor;           //!< the scale factor of the model, (global)
+};
+
+
+
+
+//! This is a MD2 Model class
+class MD2Model : public Model {
+
+public:
+  MD2Model(const char* modelFileName, const char* skinFileName = NULL);
+  virtual ~MD2Model();
+
+  virtual void draw() const;
+  void renderFrameTriangles() const;
+
+
+  void setAnim(int type);
+  /**  returns the current animation @returns animation type */
+  inline int MD2Model::getAnim() { return this->animationState.type; }
+  /**  scales the current model @param scaleFactor: the factor [0..1] to use for scaling */
+  void scaleModel(float scaleFactor) { this->scaleFactor = scaleFactor;}
+
+  virtual void tick(float dtS);
+  void debug();
+
+
+private:
+  void animate(float time);
+  void processLighting();
+  void interpolate(/*sVec3D* verticesList*/);
+  void renderFrame() const ;
+
+
+ public:
+  /* these variables are static, because they are all the same for every model */
+  static sVec3D       anorms[NUM_VERTEX_NORMALS];       //!< the anormals
+  static float        anormsDots[SHADEDOT_QUANT][256];  //!< the anormals dot products
+  static sAnim        animationList[21];                //!< the anomation list
+   //! again one of these strange id software parts
+  float*              shadeDots;
+
+  MD2Data*            data;                             //!< the md2 data pointer
+
+ private:
+  float               scaleFactor;                      //!< the scale factor (individual)
+  sAnimState          animationState;                   //!< animation state of the model
+  sVec3D              verticesList[MD2_MAX_VERTICES];   //!< place to temp sav the vert
+};
+
+
+
+
+
+#endif /* _MD2MODEL_H */
Index: branches/network/src/lib/graphics/importer/media_container.cc
===================================================================
--- branches/network/src/lib/graphics/importer/media_container.cc	(revision 6636)
+++ branches/network/src/lib/graphics/importer/media_container.cc	(revision 6636)
@@ -0,0 +1,243 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: David Hasenfratz, Stephan Lienhard
+   co-programmer:
+*/
+
+
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_MEDIA module
+   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_MEDIA
+
+
+/* include your own header */
+#include "media_container.h"
+
+#include "resource_manager.h"
+
+/* header for debug output */
+#include "debug.h"
+
+
+/**
+ * Default constructor
+ */
+MediaContainer::MediaContainer(const char* filename)
+{
+  // set the class id for the base object
+  this->setClassID(CL_MEDIA_CONTAINER, "MediaContainer");
+
+  fps = 0;
+
+  if (filename != NULL)
+  {
+    if(!this->loadMedia(filename))
+      PRINTF(1)("MediaContainer::loadMedia() failed for %s\n", filename);
+  }
+}
+
+MediaContainer::MediaContainer()
+{
+  // set the class id for the base object
+  this->setClassID(CL_MEDIA_CONTAINER, "MediaContainer");
+
+  fps = 0;
+}
+
+/**
+ * Default destructor
+ */
+MediaContainer::~MediaContainer()
+{
+  if (glIsTexture(texture))
+    glDeleteTextures(1, &texture);
+
+  // Free the RGB image
+  delete [] buffer;
+  av_free(RGB_frame);
+
+  // Free the frame
+  av_free(frame);
+
+  // Close the codec
+  avcodec_close(codec_context);
+
+  // Close the video file
+  av_close_input_file(format_context);
+}
+
+bool MediaContainer::loadMedia(const char* filename)
+{
+  // register all formats and codecs
+  av_register_all();
+
+  // Open video file
+  if (av_open_input_file(&format_context, ResourceManager::getFullName(filename), NULL, 0, NULL) !=0 )
+  {
+    PRINTF(1)("Could not open %s\n", ResourceManager::getFullName(filename));
+    return false;
+  }
+
+  // Retrieve stream information
+  if (av_find_stream_info(format_context) < 0)
+  {
+    PRINTF(1)("Could not find stream information in %s\n", ResourceManager::getFullName(filename));
+    return false;
+  }
+
+  // Find the first video stream and take it
+  video_stream = av_find_default_stream_index(format_context);
+  
+  if(video_stream == -1)
+  {
+    PRINTF(1)("Could not find a video stream in %s\n", ResourceManager::getFullName(filename));
+    return false;
+  }
+
+  // Get a pointer to the codec context for the video stream
+  codec_context = format_context->streams[video_stream]->codec;
+
+  // Find the decoder for the video stream
+  codec = avcodec_find_decoder(codec_context->codec_id);
+  if (codec == NULL)
+  {
+    PRINTF(1)("Could not find codec\n");
+    return false;
+  }
+
+  // Open codec
+  if (avcodec_open(codec_context, codec) < 0)
+  {
+    PRINTF(1)("Could not open codec\n");
+    return false;
+  }
+
+  // Allocate video frame
+  frame = avcodec_alloc_frame();
+  RGB_frame = avcodec_alloc_frame();
+
+  // Determine required buffer size and allocate buffer
+  num_bytes = avpicture_get_size(PIX_FMT_RGB24, codec_context->width, codec_context->height);
+  buffer=new uint8_t[num_bytes];
+
+  // data buffer for the texture
+  data = new uint8_t[codec_context->width*codec_context->height*3*sizeof(uint8_t)];
+
+  // Assign appropriate parts of buffer to image planes in RGB_frame
+  avpicture_fill((AVPicture *)RGB_frame, buffer, PIX_FMT_RGB24, codec_context->width, codec_context->height);
+
+  // Calculate fps
+  fps = av_q2d(format_context->streams[video_stream]->r_frame_rate);
+  // NOTE: fix this fps problem!!
+  if(fps < 0 || fps > 1000)
+    fps = 30;
+
+  // read the frames and save them in a sequence as textures
+  this->loadFrames();
+
+  return true;
+}
+
+double MediaContainer::getFPS()
+{
+  return this->fps;
+}
+
+void MediaContainer::loadFrames()
+{
+  // empty texture list
+  this->clearLists();
+
+  // go to the begin of the video
+  av_seek_frame(format_context, video_stream, 0, AVSEEK_FLAG_BACKWARD);
+
+  // get all the frames and save them in the sequence
+  while(this->addFrame(this->getNextFrame()) != NULL);
+}
+
+
+GLuint MediaContainer::getNextFrame()
+{
+
+  // get next frame
+  if(av_read_frame(format_context, &packet) >= 0)
+  {
+    // Is this a packet from the video stream?
+    if(packet.stream_index == video_stream)
+    {
+      int frame_finished;
+      // Decode video frame
+      avcodec_decode_video(codec_context, frame, &frame_finished,
+                           packet.data, packet.size);
+
+      // Free the packet that was allocated by av_read_frame
+      av_free_packet(&packet);
+      
+      // Did we get a video frame?
+      if(frame_finished)
+      {
+        // Conversion from YUV to RGB
+        // Most codecs return images in YUV 420 format
+        // (one luminance and two chrominance channels, with the chrominance
+        // channels samples at half the spatial resolution of the luminance channel)
+        img_convert((AVPicture*)RGB_frame, PIX_FMT_RGB24, (AVPicture*)frame,
+                    codec_context->pix_fmt, codec_context->width, codec_context->height);
+
+        for(int i = 0; i < codec_context->height; i++)
+          memcpy(&data[i*codec_context->width*3],
+                 ((AVPicture*)RGB_frame)->data[0]+i *
+                 ((AVPicture*)RGB_frame)->linesize[0], 
+                  codec_context->width*sizeof(uint8_t)*3);
+
+        // Create an OpenGL texture
+        glGenTextures(1, &texture);
+        glBindTexture(GL_TEXTURE_2D, texture);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+        // create the texture
+        glTexImage2D(GL_TEXTURE_2D,
+                    0,
+                    GL_RGB,
+                    codec_context->width, codec_context->height,
+                    0,
+                    GL_RGB,
+                    GL_UNSIGNED_BYTE,
+                    data);
+        // build the MipMaps
+        gluBuild2DMipmaps(GL_TEXTURE_2D,
+                        GL_RGB,
+                        codec_context->width,
+                        codec_context->height,
+                        GL_RGB,
+                        GL_UNSIGNED_BYTE,
+                        data);
+        glBindTexture(GL_TEXTURE_2D, 0);
+
+        return texture;
+      }
+      else
+      {
+        av_free_packet(&packet);
+        return this->getNextFrame();
+      }
+    }
+    else
+    {
+      av_free_packet(&packet);
+      return this->getNextFrame();
+    }
+  }
+  else
+    return NULL;
+}
Index: branches/network/src/lib/graphics/importer/media_container.h
===================================================================
--- branches/network/src/lib/graphics/importer/media_container.h	(revision 6636)
+++ branches/network/src/lib/graphics/importer/media_container.h	(revision 6636)
@@ -0,0 +1,61 @@
+/*!
+ * @file media_container.h
+  *  Manages the media files
+
+*/
+
+#ifndef _MEDIA_CONTAINER
+#define _MEDIA_CONTAINER
+
+#include "sdlincl.h"
+
+#ifdef HAVE_AVFORMAT_H
+  #include <avformat.h>
+#else
+  #include <ffmpeg/avformat.h>
+#endif
+
+/* include base_object.h since all classes are derived from this one */
+#include "base_object.h"
+#include "texture_sequence.h"
+
+#include "glincl.h"
+
+class MediaContainer : public TextureSequence
+{
+
+private:
+
+  AVFormatContext* format_context;
+  AVCodecContext* codec_context;
+  AVCodec* codec;
+  AVFrame* frame;
+  AVPacket packet;
+  AVFrame* RGB_frame;
+
+  GLuint texture;
+  uint8_t* data;
+  uint8_t* buffer;
+  int num_bytes;
+  int video_stream;
+  double fps;
+
+public:
+
+  MediaContainer(const char* filename);
+  MediaContainer();
+  ~MediaContainer();
+
+  bool loadMedia(const char* filename);
+  void loadFrames();
+
+  double getFPS();
+
+private:
+  
+  GLuint getNextFrame();
+
+};
+
+
+#endif /* _MEDIA_CONTAINER */
Index: branches/network/src/lib/graphics/importer/model.cc
===================================================================
--- branches/network/src/lib/graphics/importer/model.cc	(revision 6636)
+++ branches/network/src/lib/graphics/importer/model.cc	(revision 6636)
@@ -0,0 +1,79 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_MODEL
+
+#include "model.h"
+
+#include "glincl.h"
+
+using namespace std;
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+Model::Model()
+{
+  this->setClassID(CL_MODEL, "Model");
+  this->pModelInfo.numVertices = 0;
+  this->pModelInfo.numTriangles = 0;
+  this->pModelInfo.numNormals = 0;
+  this->pModelInfo.numTexCoor = 0;
+
+  this->pModelInfo.pVertices = NULL;
+  this->pModelInfo.pTriangles = NULL;
+  this->pModelInfo.pNormals = NULL;
+  this->pModelInfo.pTexCoor = NULL;
+}
+
+
+/**
+ * standard deconstructor
+*/
+Model::~Model()
+{
+  // delete what has to be deleted here
+}
+
+
+
+void Model::draw() const
+{
+  const GLfloat* pVertices = NULL;
+  const GLfloat* pNorm = NULL;
+
+  glBegin(GL_TRIANGLES);
+  for( int i = 0; i < this->pModelInfo.numTriangles; ++i)
+    {
+      //printf("int i = %i\n", i);
+      pNorm = &this->pModelInfo.pNormals[this->pModelInfo.pTriangles[i].indexToNormals[0]];
+      pVertices = &this->pModelInfo.pVertices[this->pModelInfo.pTriangles[i].indexToVertices[0]];
+      glNormal3f(pNorm[0], pNorm[1], pNorm[2]);
+      glVertex3f(pVertices[0], pVertices[1], pVertices[2]);
+
+      pNorm = &this->pModelInfo.pNormals[this->pModelInfo.pTriangles[i].indexToNormals[1]];
+      pVertices = &this->pModelInfo.pVertices[this->pModelInfo.pTriangles[i].indexToVertices[1]];
+      glNormal3f(pNorm[0], pNorm[1], pNorm[2]);
+      glVertex3f(pVertices[0], pVertices[1], pVertices[2]);
+
+      pNorm = &this->pModelInfo.pNormals[this->pModelInfo.pTriangles[i].indexToNormals[2]];
+      pVertices = &this->pModelInfo.pVertices[this->pModelInfo.pTriangles[i].indexToVertices[2]];
+      glNormal3f(pNorm[0], pNorm[1], pNorm[2]);
+      glVertex3f(pVertices[0], pVertices[1], pVertices[2]);
+
+    }
+  glEnd();
+}
Index: branches/network/src/lib/graphics/importer/model.h
===================================================================
--- branches/network/src/lib/graphics/importer/model.h	(revision 6636)
+++ branches/network/src/lib/graphics/importer/model.h	(revision 6636)
@@ -0,0 +1,92 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+
+/*!
+ * @file model.h
+ *  Definition of an abstract model.
+ *  containing all needed for other models
+ */
+
+#ifndef _MODEL_H
+#define _MODEL_H
+
+#include "base_object.h"
+#include "vector.h"
+
+using namespace std;
+
+
+//! holds the information about a triangle
+typedef struct
+{
+  unsigned int   indexToVertices[3];   //!< index to the vertices of the triangle
+  unsigned int   indexToNormals[3];    //!< index to the normals of the triangle
+  unsigned int   indexToTexCoor[3];    //!< index to the texture coordinates
+} sTriangleExt;
+
+
+//! Model Information definitions
+typedef struct
+{
+  unsigned int     numVertices;          //!< number of Vertices in the Model
+  unsigned int     numTriangles;         //!< number of triangles in the Model
+  unsigned int     numNormals;           //!< how many Normals in the Model
+  unsigned int     numTexCoor;           //!< how many Texture Coordinates in the Model
+
+  const float*     pVertices;            //!< array of the Vertives
+  sTriangleExt*    pTriangles;           //!< array of all triangles
+  const float*     pNormals;             //!< array of the Normals
+  const float*     pTexCoor;             //!< array of the Texture Coordinates
+
+} modelInfo;
+
+
+//! This class defines the basic components of a model
+class Model : public BaseObject {
+
+  public:
+    Model();
+    virtual ~Model();
+
+    virtual void draw() const;
+
+    inline const modelInfo* getModelInfo() const { return &this->pModelInfo; }
+
+    /** @returns a Pointer to the Vertex-Array, if it was deleted it returns NULL */
+    inline const float* getVertexArray() const { return this->pModelInfo.pVertices; };
+    /** @returns the VertexCount of this Model */
+    inline unsigned int getVertexCount() const { return this->pModelInfo.numVertices; };
+
+    /** @returns a Pointer to the Normals-Array, if it was deleted it returns NULL */
+    inline const float* getNormalsArray() const { return this->pModelInfo.pNormals; };
+    /** @returns the NormalsCount of this Model */
+    inline unsigned int getNormalsCount() const { return this->pModelInfo.numNormals; };
+
+    /** @returns a Pointer to the TexCoord-Array, if it was deleted it returns NULL */
+    inline const float* getTexCoordArray() const { return this->pModelInfo.pTexCoor; };
+    /** @returns the TexCoord-Count of this Model */
+    inline unsigned int getTexCoordCount() const { return this->pModelInfo.numTexCoor; };
+
+    /** @returns the Array of triangles */
+    inline sTriangleExt* getTriangles() const { return this->pModelInfo.pTriangles; };
+    /** @returns the Count of Faces of this Model */
+    inline unsigned int getTriangleCount() const { return this->pModelInfo.numTriangles; };
+
+
+  protected:
+    modelInfo      pModelInfo;      //!< Reference to the modelInfo
+};
+
+#endif /* _MODEL_H */
Index: branches/network/src/lib/graphics/importer/movie_player.cc
===================================================================
--- branches/network/src/lib/graphics/importer/movie_player.cc	(revision 6636)
+++ branches/network/src/lib/graphics/importer/movie_player.cc	(revision 6636)
@@ -0,0 +1,461 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: David Hasenfratz
+   co-programmer:
+*/
+
+
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_MEDIA module
+   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_MEDIA
+
+
+// include your own header
+#include "movie_player.h"
+
+#include "resource_manager.h"
+
+// header for debug output
+#include "debug.h"
+
+
+MoviePlayer::MoviePlayer(const char* filename)
+{
+  this->init();
+
+  if (filename != NULL)
+  {
+    if(!this->loadMovie(filename))
+      PRINTF(1)("MoviePlayer::loadMovie() failes for %s\n", filename);
+  }
+}
+
+MoviePlayer::MoviePlayer()
+{
+  this->init();
+}
+
+MoviePlayer::~MoviePlayer()
+{
+  //delete material;
+  //delete model;
+
+  if (glIsTexture(texture))
+    glDeleteTextures(1, &texture);
+
+  // Free the RGB image
+  delete [] buffer;
+  av_free(RGB_frame);
+
+  // Free the frame
+  av_free(frame);
+
+  avcodec_default_free_buffers(codec_context);
+
+  // Close the codec
+  avcodec_close(codec_context);
+
+  // Close the video file
+  av_close_input_file(format_context);
+}
+
+void MoviePlayer::init()
+{
+  // set the class id for the base object
+  this->setClassID(CL_MOVIE_PLAYER, "MoviePlayer");
+
+  status = STOP;
+  timer = 0;
+  frame_number = 0;
+  loading = false;
+
+  /*material = new Material;
+  material->setDiffuseMap("maps/radialTransparency.png");
+
+  model = new PrimitiveModel(PRIM_PLANE, 10.0);
+
+  LightManager* lightMan = LightManager::getInstance();
+  lightMan->setAmbientColor(.1,.1,.1);
+  (new Light())->setAbsCoor(5.0, 10.0, 40.0);
+  (new Light())->setAbsCoor(-10, -20, -100);
+  */
+}
+
+bool MoviePlayer::loadMovie(const char* filename)
+{
+  // register all formats and codecs
+  av_register_all();
+
+  // Open video file
+  if (av_open_input_file(&format_context, ResourceManager::getFullName(filename), NULL, 0, NULL) !=0 )
+  {
+    PRINTF(1)("Could not open %s\n", ResourceManager::getFullName(filename));
+    return false;
+  }
+
+  // Retrieve stream information
+  if (av_find_stream_info(format_context) < 0)
+  {
+    PRINTF(1)("Could not find stream information in %s\n", ResourceManager::getFullName(filename));
+    return false;
+  }
+
+  // Find the first video stream and take it
+  video_stream = av_find_default_stream_index(format_context);
+
+  if(video_stream == -1)
+  {
+    PRINTF(1)("Could not find a video stream in %s\n", ResourceManager::getFullName(filename));
+    return false;
+  }
+
+  // Get a pointer to the codec context for the video stream
+  codec_context = format_context->streams[video_stream]->codec;
+
+  // Find the decoder for the video stream
+  codec = avcodec_find_decoder(codec_context->codec_id);
+  if (codec == NULL)
+  {
+    PRINTF(1)("Could not find codec\n");
+    return false;
+  }
+
+  // Open codec
+  if (avcodec_open(codec_context, codec) < 0)
+  {
+    PRINTF(1)("Could not open codec\n");
+    return false;
+  }
+
+  // Allocate video frame
+  frame = avcodec_alloc_frame();
+  RGB_frame = avcodec_alloc_frame();
+
+  // Determine required buffer size and allocate buffer
+  num_bytes = avpicture_get_size(PIX_FMT_RGB24, codec_context->width, codec_context->height);
+  buffer=new uint8_t[num_bytes];
+
+  // Assign appropriate parts of buffer to image planes in RGB_frame
+  avpicture_fill((AVPicture *)RGB_frame, buffer, PIX_FMT_RGB24, codec_context->width, codec_context->height);
+
+  // data buffer for the texture
+  data = new uint8_t[codec_context->width*codec_context->height*3*sizeof(uint8_t)];
+
+  // Calculate fps
+  fps = av_q2d(format_context->streams[video_stream]->r_frame_rate);
+  // NOTE: fix this fps problem!!
+  if(fps < 0 || fps > 1000)
+    fps = 30;
+
+  // duration
+  duration = format_context->duration / 1000000LL;
+
+  // create texture
+  glGenTextures(1, &texture);
+  glBindTexture(GL_TEXTURE_2D, texture);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+  glTexImage2D(GL_TEXTURE_2D,
+              0,
+              GL_RGB,
+              0, 0,
+              0,
+              GL_RGB,
+              GL_UNSIGNED_BYTE,
+              NULL);
+  glBindTexture(GL_TEXTURE_2D, 0);
+
+  loading = true;
+  return true;
+}
+
+void MoviePlayer::getNextFrame()
+{
+  // get next frame
+  if(av_read_frame(format_context, &packet) >= 0)
+  {
+    // Is this a packet from the video stream?
+    if(packet.stream_index == video_stream)
+    {
+      int frame_finished;
+      // Decode video frame
+      avcodec_decode_video(codec_context, frame, &frame_finished,
+                           packet.data, packet.size);
+
+      // Free the packet that was allocated by av_read_frame
+      av_free_packet(&packet);
+
+      // Did we get a video frame?
+      if(frame_finished)
+      {
+        frame_number++;
+        //PRINTF(0)("frame_number: %i\n", frame_number);
+        // Conversion from YUV to RGB
+        // Most codecs return images in YUV 420 format
+        // (one luminance and two chrominance channels, with the chrominance
+        // channels samples at half the spatial resolution of the luminance channel)
+        img_convert((AVPicture*)RGB_frame, PIX_FMT_RGB24, (AVPicture*)frame,
+                    codec_context->pix_fmt, codec_context->width, codec_context->height);
+
+        for(int i = 0; i < codec_context->height; i++)
+          memcpy(&data[i*codec_context->width*3], ((AVPicture*)RGB_frame)->data[0]+i *
+                 ((AVPicture*)RGB_frame)->linesize[0],
+                 codec_context->width*sizeof(uint8_t)*3);
+
+        glBindTexture(GL_TEXTURE_2D, texture);
+        // update the texture
+        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
+                          codec_context->width, codec_context->height,
+                          GL_RGB, GL_UNSIGNED_BYTE,
+                          data);
+        // build the MipMaps
+        gluBuild2DMipmaps(GL_TEXTURE_2D,
+                        GL_RGB,
+                        codec_context->width,
+                        codec_context->height,
+                        GL_RGB,
+                        GL_UNSIGNED_BYTE,
+                        data);
+        glBindTexture(GL_TEXTURE_2D, 0);
+
+      }
+      else
+      {
+        av_free_packet(&packet);
+        this->getNextFrame();
+      }
+    }
+    else
+    {
+      av_free_packet(&packet);
+      this->getNextFrame();
+    }
+  }
+  else
+    this->stop();
+}
+
+void MoviePlayer::skipFrame(int frames)
+{
+
+  while(frames != 0)
+  {
+    if(av_read_frame(format_context, &packet) < 0)
+      break;
+    if(packet.stream_index == video_stream)
+    {
+      int frame_finished;
+      // We have to decode the frame to not get ugly fragments
+      avcodec_decode_video(codec_context, frame, &frame_finished,
+                            packet.data, packet.size);
+
+      // Did we get a video frame?
+      if(frame_finished)
+      {
+        frames--;
+        frame_number++;
+      }
+    }
+    av_free_packet(&packet);
+  }
+
+  this->getNextFrame();
+
+}
+
+bool MoviePlayer::gotoFrame(int frames)
+{
+  if(!loading)
+  {
+    PRINTF(0)("Load first the media file with loadMovie\n");
+    return false;
+  }
+
+  int err;
+  // seek doesnt work for the first two frames
+  // you will get ugly fragments
+  if(frames < 2)
+  {
+    // go to the begin of the video
+    err = av_seek_frame(format_context, video_stream, 0, AVSEEK_FLAG_BACKWARD);
+    if(err < 0)
+    {
+      PRINTF(1)("Could not seek to frame 0\n");
+      return false;
+    }
+
+    this->frame_number = 0;
+  }
+  else
+  {
+    // seeks to the nearest keyframe
+    // NOTE: there is only about every 5s a keyframe!
+    err = av_seek_frame(format_context, video_stream, frames, AVSEEK_FLAG_BACKWARD);
+    if(err < 0)
+    {
+      PRINTF(1)("Could not seek to frame %i\n", frames);
+      return false;
+    }
+
+    // go from the keyframe to the exact position
+    codec_context->hurry_up = 1;
+    do {
+      if(av_read_frame(format_context, &packet) < 0)
+      {
+        PRINTF(1)("Could not seek to frame %i\n", frames);
+        return false;
+      }
+
+      if(packet.stream_index == video_stream)
+      {
+        if(packet.pts >= frames-1)
+          break;
+        int frame_finished;
+        avcodec_decode_video(codec_context, frame, &frame_finished, packet.data, packet.size);
+        av_free_packet(&packet);
+      }
+    } while(1);
+    codec_context->hurry_up = 0;
+
+    this->frame_number = frames;
+  }
+
+  return true;
+}
+
+void MoviePlayer::start(float start_time)
+{
+  //start_frame = start_time * fps;
+  start_frame = 0;
+
+  if(this->gotoFrame(start_frame))
+  {
+    status = PLAY;
+    timer = 0;
+
+    this->gotoFrame(start_frame);
+
+    PRINTF(0)("start\n");
+  }
+}
+
+void MoviePlayer::resume()
+{
+  if(status == PAUSE)
+  {
+    status = PLAY;
+    PRINTF(0)("resume\n");
+  }
+}
+
+void MoviePlayer::pause()
+{
+  if(status == PLAY)
+  {
+    status = PAUSE;
+    PRINTF(0)("pause\n");
+  }
+}
+
+void MoviePlayer::stop()
+{
+  status = STOP;
+
+  PRINTF(0)("stop\n");
+}
+
+void MoviePlayer::tick(float dt)
+{
+  if(status == PLAY)
+  {
+    timer += dt;
+    actual_frame = (int)(timer * fps + start_frame);
+    if(actual_frame != frame_number)
+    {
+      if(actual_frame - frame_number == 1)
+        this->getNextFrame();
+      else
+        this->skipFrame(actual_frame - frame_number - 1);
+    }
+    //PRINTF(0)("frame_number: %i\n", frame_number);
+  }
+}
+
+/*const void MoviePlayer::draw()
+{
+  material->select();
+  glBindTexture(GL_TEXTURE_2D, texture);
+  model->draw();
+
+  LightManager::getInstance()->draw();
+}*/
+
+GLuint MoviePlayer::getTexture()
+{
+  return this->texture;
+}
+
+void MoviePlayer::setFPS(float fps)
+{
+  if(fps > 0)
+    this->fps = fps;
+}
+
+float MoviePlayer::getFPS()
+{
+  return this->fps;
+}
+
+const MP_STATUS MoviePlayer::getStatus()
+{
+  return this->status;
+}
+
+void MoviePlayer::printInformation()
+{
+  if(!loading)
+  {
+    PRINTF(0)("Load first the media file with loadMovie\n");
+    return;
+  }
+
+  PRINTF(0)("========================\n");
+  PRINTF(0)("========================\n");
+  PRINTF(0)("=    MEDIACONTAINER    =\n");
+  PRINTF(0)("========================\n");
+  PRINTF(0)("========================\n");
+  PRINTF(0)("=    AVFormatContext   =\n");
+  PRINTF(0)("========================\n");
+  PRINTF(0)("filename: %s\n", format_context->filename);
+  PRINTF(0)("nb_streams: %i\n", format_context->nb_streams);
+  PRINTF(0)("duration: (%02d:%02d:%02d)\n", duration/3600, (duration%3600)/60, duration%60);
+  PRINTF(0)("file_size: %ikb\n", format_context->file_size/1024);
+  PRINTF(0)("bit_rate: %ikb/s\n", format_context->bit_rate/1000);
+  PRINTF(0)("nb_frames: %i\n", format_context->streams[video_stream]->nb_frames);
+  PRINTF(0)("r_frame_rate: %i\n", format_context->streams[video_stream]->r_frame_rate.num);
+  PRINTF(0)("fps: %0.2f\n", fps);
+  PRINTF(0)("========================\n");
+  PRINTF(0)("=    AVCodecContext    =\n");
+  PRINTF(0)("========================\n");
+  PRINTF(0)("width: %i\n", codec_context->width);
+  PRINTF(0)("height: %i\n", codec_context->height);
+  PRINTF(0)("time_base.den: %i\n", codec_context->time_base.den);
+  PRINTF(0)("time_base.num: %i\n", codec_context->time_base.num);
+  PRINTF(0)("========================\n");
+  PRINTF(0)("=       AVCodec        =\n");
+  PRINTF(0)("========================\n");
+  PRINTF(0)("codec name: %s\n", codec->name);
+  PRINTF(0)("========================\n");
+  PRINTF(0)("========================\n");
+}
Index: branches/network/src/lib/graphics/importer/movie_player.h
===================================================================
--- branches/network/src/lib/graphics/importer/movie_player.h	(revision 6636)
+++ branches/network/src/lib/graphics/importer/movie_player.h	(revision 6636)
@@ -0,0 +1,98 @@
+/*!
+ * @file movie_player.h
+  *  Manages the media files
+
+*/
+
+#ifndef _MOVIE_PLAYER
+#define _MOVIE_PLAYER
+
+#include "sdlincl.h"
+
+#ifdef HAVE_AVFORMAT_H
+  #include <avformat.h>
+#else
+  #include <ffmpeg/avformat.h>
+#endif
+
+#include "glincl.h"
+
+//#include "light.h"
+#include "texture.h"
+//#include "material.h"
+//#include "primitive_model.h"
+
+// include base_object.h since all classes are derived from this one
+#include "base_object.h"
+
+// The state of the MoviePlayer
+typedef enum MP_STATUS {
+  PLAY,
+        PAUSE,
+        STOP
+};
+
+class MoviePlayer : public BaseObject
+{
+
+private:
+
+  //Model* model;
+  //Material* material;
+
+  AVFormatContext* format_context;
+  AVCodecContext* codec_context;
+  AVCodec* codec;
+  AVFrame* frame;
+  AVPacket packet;
+  AVFrame* RGB_frame;
+
+  GLuint texture;
+  uint8_t* data;
+  uint8_t* buffer;
+  int num_bytes;
+  int video_stream;
+
+  MP_STATUS status;
+  float timer;
+  int start_frame;
+  int actual_frame;
+  int frame_number;
+  float fps;
+  int duration;
+  bool loading;
+
+public:
+
+  MoviePlayer(const char* filename);
+  MoviePlayer();
+  ~MoviePlayer();
+
+  bool loadMovie(const char* filename);
+
+        void start(float start_time);
+        void resume();
+        void pause();
+        void stop();
+
+        void tick(float dt);
+        //const void draw();
+        GLuint getTexture();
+
+        void setFPS(float fps);
+        float getFPS();
+        const MP_STATUS getStatus();
+  void printInformation();
+
+private:
+
+  void init();
+  void getNextFrame();
+  void skipFrame(int frames);
+  bool gotoFrame(int frames);
+
+};
+
+
+
+#endif // _MOVIE_PLAYER
Index: branches/network/src/lib/graphics/importer/objModel.cc
===================================================================
--- branches/network/src/lib/graphics/importer/objModel.cc	(revision 6636)
+++ branches/network/src/lib/graphics/importer/objModel.cc	(revision 6636)
@@ -0,0 +1,262 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "objModel.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define PARSELINELENGTH 8192
+
+#include "debug.h"
+#include "compiler.h"
+
+/**
+ *  Crates a 3D-Model, loads in a File and scales it.
+ * @param fileName file to parse and load (must be a .obj file)
+ * @param scaling The factor that the model will be scaled with.
+*/
+OBJModel::OBJModel(const char* fileName, float scaling) : StaticModel(fileName)
+{
+  this->setClassID(CL_OBJ_MODEL, "OBJModel");
+
+  this->objPath = "./";
+
+  this->scaleFactor = scaling;
+
+  this->importFile (fileName);
+
+  this->finalize();
+}
+
+/**
+ *  deletes an OBJModel.
+
+   Looks if any from model allocated space is still in use, and if so deleted it.
+*/
+OBJModel::~OBJModel()
+{
+  PRINTF(4)("Deleting the obj-names\n");
+  if (this->objPath)
+    delete []this->objPath;
+}
+
+/**
+ *  Imports a obj file and handles the the relative location
+ * @param fileName The file to import
+
+   Splits the FileName from the DirectoryName
+*/
+bool OBJModel::importFile (const char* fileName)
+{
+  PRINTF(4)("preparing to read in file: %s\n", fileName);
+  // splitting the
+  char* split = NULL;
+
+  if (!(split = strrchr(fileName, '/')))
+    split = strrchr(fileName, '\\'); // windows Case
+  if (split)
+    {
+      int len = split - fileName+1;
+      this->objPath = new char[len +2];
+      strncpy(this->objPath, fileName, len);
+      this->objPath[len] = '\0';
+      PRINTF(4)("Resolved file %s to Path %s.\n", fileName, this->objPath);
+    }
+  else
+    this->objPath = "./";
+  Material::addTexturePath(this->objPath);
+
+  this->readFromObjFile (fileName);
+  return true;
+}
+
+/**
+ *  Reads in the .obj File and sets all the Values.
+   This function does read the file, parses it for the occurence of things like vertices, faces and so on, and executes the specific tasks
+*/
+bool OBJModel::readFromObjFile(const char* fileName)
+{
+  FILE* stream;
+  if( (stream = fopen (fileName, "r")) == NULL)
+    {
+      PRINTF(2)("Object File Could not be Opened %s\n", fileName);
+      return false;
+    }
+
+  char buffer[PARSELINELENGTH];
+  while(fgets(buffer, PARSELINELENGTH, stream))
+    {
+      // line termiated with \0 not \n
+      if (buffer[strlen(buffer)-1] == '\n')
+        buffer[strlen(buffer)-1] = '\0';
+
+      // case vertice
+      if (!strncmp(buffer, "v ", 2))
+        {
+          this->addVertex(buffer+2);
+        }
+
+      // case face
+      else if (!strncmp(buffer, "f ", 2))
+        {
+          this->addFace (buffer+2);
+        }
+
+      else if (!strncmp(buffer, "mtllib ", 7))
+        {
+          this->readMtlLib (buffer+7);
+        }
+
+      else if (!strncmp(buffer, "usemtl ", 7))
+        {
+          this->setMaterial (buffer+7);
+        }
+
+      // case VertexNormal
+      else if (!strncmp(buffer, "vn ", 3))
+        {
+          this->addVertexNormal(buffer+3);
+        }
+
+      // case VertexTextureCoordinate
+      else if (!strncmp(buffer, "vt ", 3))
+        {
+          this->addVertexTexture(buffer+3);
+        }
+      // case group
+      else if (!strncmp(buffer, "g ", 2))
+        {
+          this->addGroup (buffer+2);
+        }
+      else if (!strncmp(buffer, "s ", 2)) //! @todo smoothing groups have to be implemented
+        {
+          PRINTF(3)("smoothing groups not supportet yet. line: %s\n", buffer);
+        }
+    }
+  fclose (stream);
+  return true;
+}
+
+/**
+ * Function to read in a mtl File.
+ * @param mtlFile The .mtl file to read
+ *
+ * This Function parses all Lines of an mtl File.
+ * The reason for it not to be in the materials-class is,
+ * that a material does not have to be able to read itself in from a File.
+ */
+bool OBJModel::readMtlLib (const char* mtlFile)
+{
+  char* fileName = new char [strlen(this->objPath) + strlen(mtlFile)+1];
+  sprintf(fileName, "%s%s", this->objPath, mtlFile);
+
+  FILE* stream;
+  if( (stream = fopen (fileName, "r")) == NULL)
+    {
+      PRINTF(2)("MaterialLibrary could not be opened %s\n", fileName);
+      delete[] fileName;
+      return false;
+    }
+
+  char buffer[PARSELINELENGTH];
+  Material* tmpMat = NULL;
+
+  while(fgets(buffer, PARSELINELENGTH, stream) != NULL)
+    {
+      PRINTF(5)("found line in mtlFile: %s\n", buffer);
+
+      // line termiated with \0 not \n
+      if (buffer[strlen(buffer)-1] == '\n')
+        buffer[strlen(buffer)-1] = '\0';
+
+      // create new Material
+      if (!strncmp(buffer, "newmtl ", 7))
+        {
+          tmpMat = this->addMaterial(buffer+7);//tmpMat->addMaterial(buffer+7);
+        }
+      // setting a illumMode
+      else if (!strncmp(buffer, "illum ", 6))
+        {
+          if (likely(tmpMat != NULL))
+            tmpMat->setIllum(buffer+6);
+
+        }
+      // setting Diffuse Color
+      else if (!strncmp(buffer, "Kd ", 3))
+        {
+          if (likely(tmpMat != NULL))
+            tmpMat->setDiffuse(buffer+3);
+        }
+      // setting Ambient Color
+      else if (!strncmp(buffer, "Ka ", 3))
+        {
+          if (likely(tmpMat != NULL))
+            tmpMat->setAmbient(buffer+3);
+        }
+      // setting Specular Color
+      else if (!strncmp(buffer, "Ks ", 3))
+        {
+          if (likely(tmpMat != NULL))
+            tmpMat->setSpecular(buffer+3);
+        }
+      // setting The Specular Shininess
+      else if (!strncmp(buffer, "Ns ", 3))
+        {
+          if (likely(tmpMat != NULL))
+            tmpMat->setShininess(buffer+3);
+        }
+      // setting up transparency
+      else if (!strncmp(buffer, "d ", 2))
+        {
+          if (likely(tmpMat != NULL))
+            tmpMat->setTransparency(buffer+2);
+        }
+      else if (!strncmp(buffer, "Tf ", 3))
+        {
+          if (likely(tmpMat != NULL))
+            tmpMat->setTransparency(buffer+3);
+        }
+
+      else if (!strncmp(buffer, "map_Kd ", 7))
+        {
+          if (likely(tmpMat != NULL))
+            tmpMat->setDiffuseMap(buffer+7);
+        }
+      else if (!strncmp(buffer, "map_Ka ", 7))
+        {
+          if (likely(tmpMat != NULL))
+            tmpMat->setAmbientMap(buffer+7);
+        }
+      else if (!strncmp(buffer, "map_Ks ", 7))
+        {
+          if (likely(tmpMat != NULL))
+            tmpMat->setSpecularMap(buffer+7);
+        }
+      else if (!strncmp(buffer, "bump ", 5))
+        {
+          if (likely(tmpMat != NULL))
+            tmpMat->setBump(buffer+7);
+        }
+
+
+    }
+  fclose(stream);
+  delete []fileName;
+  return true;
+}
Index: branches/network/src/lib/graphics/importer/objModel.h
===================================================================
--- branches/network/src/lib/graphics/importer/objModel.h	(revision 6636)
+++ branches/network/src/lib/graphics/importer/objModel.h	(revision 6636)
@@ -0,0 +1,28 @@
+/*!
+  \file objModel.h
+  \brief Contains the OBJ-model Class, that reads in a Model from a .obj-file
+*/
+
+#ifndef _OBJMODEL_H
+#define _OBJMODEL_H
+
+#include "static_model.h"
+
+//! A Class, that handles the parsing of an obj-file, and inclusion as a Model.
+class OBJModel : public StaticModel
+{
+ public:
+  OBJModel(const char* fileName, float scaling = 1.0);
+  virtual ~OBJModel();
+
+ private:
+  ///// readin /////
+  bool importFile (const char* fileName);
+  bool readFromObjFile (const char* fileName);
+  bool readMtlLib (const char* matFile);
+
+ private:
+  char*       objPath;     //!< The Path where the obj and mtl-file are located.
+};
+
+#endif /* _OBJ_MODEL_H */
Index: branches/network/src/lib/graphics/importer/primitive_model.cc
===================================================================
--- branches/network/src/lib/graphics/importer/primitive_model.cc	(revision 6636)
+++ branches/network/src/lib/graphics/importer/primitive_model.cc	(revision 6636)
@@ -0,0 +1,245 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_MODEL
+
+#include "primitive_model.h"
+
+#include <math.h>
+#include "vector.h"
+#include "debug.h"
+
+using namespace std;
+
+/**
+ *  Creates a 3D-Model of Primitive-Type type
+
+   if you want to just display a Cube/Sphere/Cylinder/... without any material.
+
+   @todo implement Cube/Sphere/Cylinder/...
+*/
+PrimitiveModel::PrimitiveModel(PRIMITIVE type, float size, unsigned int detail)
+{
+  switch (type)
+    {
+    default:
+    case PRIM_CUBE:
+      this->cubeModel();
+      break;
+    case PRIM_SPHERE:
+      this->sphereModel(size, detail);
+      break;
+    case PRIM_CYLINDER:
+      this->cylinderModel();
+      break;
+    case PRIM_CONE:
+      this->coneModel(size, detail);
+      break;
+    case PRIM_PLANE:
+      this->planeModel(size, detail);
+      break;
+    }
+  this->finalize();
+}
+
+/**
+ *  standard deconstructor
+
+*/
+PrimitiveModel::~PrimitiveModel ()
+{
+  // delete what has to be deleted here
+}
+
+/**
+ *  Builds a Sphere into the Model.
+ * @param size The diameter of the Sphere.
+ * @param detail The detail of the Sphere.
+*/
+void PrimitiveModel::sphereModel(float size, unsigned int detail)
+{
+  if (detail <= 0)
+    detail = 1;
+  size /= 2;
+  //  detail = 2; // make it even
+  float df = (float)detail;
+
+  // defining the Vertices
+  for (float i = 0; i < df *2.0; i+=1.0)
+    {
+      float vi = i/df *PI;
+      for (float j = -df / 2.0 +1.0; j < df / 2.0; j+=1.0 *df/(df+1.0))
+        {
+          float vj = j/df *PI;
+          this->addVertexNormal(cos(vi) * cos(vj),
+                                sin(vj),
+                                sin(vi) * cos(vj));
+
+          this->addVertex(size * cos(vi) * cos(vj),
+                          size * sin(vj),
+                          size * sin(vi) * cos(vj));
+
+          this->addVertexTexture(i / (df *2.0), (j-1.0)/(df)+.5);
+        }
+    }
+  this->addVertex(0, -size, 0);
+  this->addVertexNormal(0, -1, 0);
+  this->addVertexTexture(0,0);
+  this->addVertex(0, size, 0);
+  this->addVertexNormal(0, 1, 0);
+  this->addVertexTexture(0 ,1);
+
+  // defining the binding Faces.
+  unsigned int v1, v2, v3, v4;
+  for (int i = 0; i <= detail * 2 -1; i++)
+    {
+      for (int j = 0; j <= detail; j++)
+        {
+
+          v1 = i*detail + j-1;
+          v4 = i*detail + j;
+
+          if (i == detail*2 -1)
+            {
+              v2 = j-1;
+              v3 = j;
+            }
+          else
+            {
+              v2 = (i+1)*detail + j-1;
+              v3 = (i+1)*detail + j;
+            }
+
+          if (j == 0)
+            {
+              v1 = this->getVertexCount() - 2;
+              this->addFace(3, VERTEX_TEXCOORD_NORMAL, v1, v1, v1, v3, v3, v3, v4, v4, v4);
+            }
+          else if (j == detail)
+            {
+              v3 = this->getVertexCount()-1;
+              this->addFace(3, VERTEX_TEXCOORD_NORMAL, v1, v1, v1, v2, v2, v2, v3, v3, v3);
+            }
+          else
+            this->addFace(4, VERTEX_TEXCOORD_NORMAL, v1, v1, v1, v2, v2, v2, v3, v3, v3, v4, v4, v4);
+        }
+    }
+}
+/**
+ *  Creates a Cylinder.
+*/
+void PrimitiveModel::cylinderModel(float size, unsigned int detail)
+{
+  // check if devision by zero
+  if (detail <= 3)
+    detail = 3;
+  int count = 0;
+  // defining Points of the Cylinder.
+  for (float phi = 0.0; phi < 2.0*PI; phi += 2.0*PI/(float)detail)
+    {
+      this->addVertex(size*cos(phi), size*sin(phi), -size);
+      this->addVertex(size*cos(phi), size*sin(phi), size);
+      count ++;
+    }
+  this->addVertex(0, 0, -size);
+  this->addVertex(0, 0, size);
+
+  if (count != detail)
+    PRINTF(1)("calculation error, count should be %d but is %d.\n", detail, count);
+
+  // adding Faces
+  for (int i = 0; i < detail-1; i++)
+    {
+      int p1, p2, p3, p4;
+      p1 = 2*i;
+      p2 = 2*i+1;
+      p3 = 2*i+3;
+      p4 = 2*i+2;
+      // something is wrong here
+      this->addFace(4, VERTEX_ONLY, p1, p2, p3, p4);
+      this->addFace(3, VERTEX_ONLY, p4, p1, 2*detail);
+      this->addFace(3, VERTEX_ONLY, p2, p3, 2*detail+1);
+    }
+  // caps
+  this->addFace(4, VERTEX_ONLY, 2*detail-2, 2*detail-1, 1, 0);
+  this->addFace(3, VERTEX_ONLY, 0, 2*detail-2, 2*detail);
+  this->addFace(3, VERTEX_ONLY, 2*detail-1, 1, 2*detail+1);
+}
+
+/**
+ *  creates a cone inside of this Model
+ * @param size The size of the cone
+ * @param detail the Detail-level of this cone
+*/
+void PrimitiveModel::coneModel(float size, unsigned int detail)
+{
+  this->addVertex(0,-size,0);
+  this->addVertex(0,size,0);
+  if (detail <= 0)
+    detail = 1;
+  float df = (float)detail;
+
+  // defining the Vertices
+  for (float i = 0; i < df; i+=1.0)
+    {
+      float vi = i/df *2.0*PI;
+      this->addVertex(size* sin(vi),
+                      -size,
+                      size* cos(vi));
+    }
+
+  //defining Faces
+  for (int i = 0; i < detail; i++)
+    {
+      unsigned int v1, v2;
+      v1 = i+2;
+      if (i == detail -1)
+        v2 = 2;
+      else
+        v2 = i+3;
+      this->addFace(3, VERTEX_ONLY, 0, v1, v2);
+      this->addFace(3, VERTEX_ONLY, 1, v1, v2);
+    }
+}
+
+/**
+ *  creates a Plane inside of this Model
+ * @param size The size of this plane
+ * @param detail the Detail-level of this plane.
+*/
+void PrimitiveModel::planeModel(float size, unsigned int detail)
+{
+  //defining vertices
+  for (int i = 0; i < detail; i++)
+    for (int j = 0; j < detail; j++)
+      {
+        this->addVertex(((float)i/(float)(detail-1) -.5)*size,
+                        0,
+                        ((float)j/(float)(detail-1) -.5)*size);
+        this->addVertexTexture((float)i/(float)(detail-1),
+                               (float)j/(float)(detail-1));
+      }
+  //defining Faces
+  unsigned int v1, v2, v3, v4;
+  for (int i = 0; i < detail-1; i++)
+    for (int j = 0; j < detail-1; j++)
+      {
+        v1 = i*detail + j;
+        v2 = (i+1)*detail + j;
+        v3 = (i+1)*detail + (j+1);
+        v4 = i*detail + (j+1);
+        this->addFace(4, VERTEX_TEXCOORD, v1, v1, v2, v2, v3, v3, v4, v4);
+      }
+}
Index: branches/network/src/lib/graphics/importer/primitive_model.h
===================================================================
--- branches/network/src/lib/graphics/importer/primitive_model.h	(revision 6636)
+++ branches/network/src/lib/graphics/importer/primitive_model.h	(revision 6636)
@@ -0,0 +1,33 @@
+/*! 
+ * @file primitive_model.h 
+  *  a Class to handle different simple models like planes cubes spheres and so on.
+    (cube is also an option of Model, but is extended here.
+*/
+
+#ifndef _PRIMITIVE_MODEL_H
+#define _PRIMITIVE_MODEL_H
+
+#include "static_model.h"
+
+//! Specification of different primitives the Model knows
+enum PRIMITIVE { PRIM_CUBE,
+		 PRIM_SPHERE,
+		 PRIM_PLANE,
+		 PRIM_CYLINDER,
+		 PRIM_CONE };
+
+//! A Class to create some default Models
+class PrimitiveModel : public StaticModel {
+
+ public:
+  PrimitiveModel(PRIMITIVE type, float size = 1.0, unsigned int detail = 10);
+  virtual ~PrimitiveModel();
+
+ protected:
+  void sphereModel(float size = 1.0, unsigned int detail = 10);
+  void cylinderModel(float size = 1.0, unsigned int detail = 10);
+  void coneModel(float size = 1.0, unsigned int detail = 10);
+  void planeModel(float size = 1.0, unsigned int detail = 1);
+};
+
+#endif /* _PRIMITIVE_MODEL_H */
Index: branches/network/src/lib/graphics/importer/static_model.cc
===================================================================
--- branches/network/src/lib/graphics/importer/static_model.cc	(revision 6636)
+++ branches/network/src/lib/graphics/importer/static_model.cc	(revision 6636)
@@ -0,0 +1,1021 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+
+   2005-07-06: (Patrick) added new function buildTriangleList()
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "static_model.h"
+
+#include "stdlibincl.h"
+#include <stdarg.h>
+
+#include "vector.h"
+
+using namespace std;
+
+
+////////////////////
+/// SUB-Elements ///
+////////////////////
+/**
+ * @brief creates a new ModelFaceElement
+ */
+ModelFaceElement::ModelFaceElement()
+{
+  this->vertexNumber = -1;
+  this->normalNumber = -1;
+  this->texCoordNumber = -1;
+
+  this->next = NULL;
+}
+
+/**
+ * @brief destroys a ModelFaceElement
+ */
+ModelFaceElement::~ModelFaceElement()
+{
+  if (this->next)
+    delete this->next;
+}
+
+/**
+ * @brief creates a new ModelFace
+ */
+ModelFace::ModelFace()
+{
+  this->vertexCount = 0;
+
+  this->firstElem = NULL;
+
+  this->material = NULL;
+
+  this->next = NULL;
+}
+
+/**
+ *  deletes a ModelFace
+*/
+ModelFace::~ModelFace()
+{
+  PRINTF(5)("Cleaning up Face\n");
+
+  if (this->firstElem != NULL)
+    delete this->firstElem;
+
+  if (this->next != NULL)
+    delete this->next;
+}
+
+/**
+ * @brief Creates a new ModelGroup
+ */
+ModelGroup::ModelGroup()
+{
+  PRINTF(4)("Adding new Group\n");
+  this->name = NULL;
+  this->faceMode = -1;
+  this->faceCount = 0;
+  this->next = NULL;
+  this->listNumber = 0;
+  this->indices = NULL;
+
+  this->firstFace = new ModelFace;
+  this->currentFace = this->firstFace;
+}
+
+/**
+ * @brief deletes a ModelGroup
+ */
+ModelGroup::~ModelGroup()
+{
+  PRINTF(5)("Cleaning up group\n");
+  if (this->firstFace != NULL)
+    delete this->firstFace;
+
+  // deleting the glList
+  if (this->listNumber != 0)
+    glDeleteLists(this->listNumber, 1);
+
+  if (this->name != NULL)
+    delete[] this->name;
+
+  if (this->next !=NULL)
+    delete this->next;
+
+}
+
+/**
+ * @brief cleans up a ModelGroup
+ *
+ * actually does the same as the delete Operator, but does not delete the predecessing group
+ */
+void ModelGroup::cleanup()
+{
+  PRINTF(5)("Cleaning up group\n");
+  if (this->firstFace)
+    delete this->firstFace;
+  this->firstFace = NULL;
+  if (this->next)
+    this->next->cleanup();
+}
+
+
+/////////////
+/// MODEL ///
+/////////////
+/**
+ * @brief Creates a 3D-Model.
+ *
+ * assigns it a Name and a Type
+ */
+StaticModel::StaticModel(const char* modelName)
+{
+  this->setClassID(CL_STATIC_MODEL, "StaticModel");
+  PRINTF(4)("new 3D-Model is being created\n");
+  this->setName(modelName);
+
+  this->finalized = false;
+
+  // setting the start group;
+  this->currentGroup = this->firstGroup = new ModelGroup;
+  this->groupCount = 0;
+  this->faceCount = 0;
+
+  this->scaleFactor = 1.0f;
+}
+
+/**
+ * @brief deletes an Model.
+ *
+ * Looks if any from model allocated space is still in use, and if so deleted it.
+ */
+StaticModel::~StaticModel()
+{
+  PRINTF(4)("Deleting Model ");
+  if (this->getName())
+  {
+    PRINT(4)("%s\n", this->getName());
+  }
+  else
+  {
+    PRINT(4)("\n");
+  }
+  this->cleanup();
+
+  PRINTF(5)("Deleting display Lists.\n");
+  delete this->firstGroup;
+
+  // deleting the MaterialList
+  PRINTF(5)("Deleting Materials.\n");
+
+  //! @todo do we really have to delete this material??
+  list<ModelMaterial*>::iterator modMat;
+  for(modMat = this->materialList.begin(); modMat != this->materialList.end(); modMat++)
+  {
+    if (!(*modMat)->external)
+      delete (*modMat)->material;
+    delete (*modMat);
+  }
+}
+
+/**
+ * @brief Finalizes an Object. This can be done outside of the Class.
+ */
+void StaticModel::finalize()
+{
+  // this creates the display List.
+  this->importToDisplayList();
+  this->buildTriangleList();
+
+  this->pModelInfo.pVertices = &this->vertices[0];
+  this->pModelInfo.pNormals = &this->normals[0];
+  this->pModelInfo.pTexCoor = &this->vTexture[0];
+
+  this->finalized = true;
+}
+
+/**
+ * @brief rebuild the Model from the Information we got.
+ */
+void StaticModel::rebuild()
+{
+  PRINTF(3)("Rebuilding Model '%s'\n", this->getName());
+  this->finalize();
+}
+
+//////////
+// DRAW //
+//////////
+/**
+ * @brief Draws the Models of all Groups.
+ *
+ * It does this by just calling the Lists that must have been created earlier.
+ */
+void StaticModel::draw () const
+{
+  PRINTF(4)("drawing the 3D-Models\n");
+  ModelGroup* tmpGroup = this->firstGroup;
+  while (tmpGroup != NULL)
+    {
+      PRINTF(5)("Drawing model %s\n", tmpGroup->name);
+      glCallList (tmpGroup->listNumber);
+      tmpGroup = tmpGroup->next;
+    }
+}
+
+
+/**
+ * @brief Draws the Model number groupNumber
+ * @param groupNumber The number of the group that will be displayed.
+ *
+ * It does this by just calling the List that must have been created earlier.
+ */
+void StaticModel::draw (int groupNumber) const
+{
+  if (unlikely(groupNumber >= this->groupCount))
+    {
+      PRINTF(2)("You requested model number %i, but this File only contains of %i Models.\n", groupNumber-1, this->groupCount);
+      return;
+    }
+  PRINTF(4)("drawing the requested 3D-Models if found.\n");
+  ModelGroup* tmpGroup = this->firstGroup;
+  int counter = 0;
+  while (tmpGroup != NULL)
+    {
+      if (counter == groupNumber)
+        {
+          PRINTF(4)("Drawing model number %i named %s\n", counter, tmpGroup->name);
+          glCallList (tmpGroup->listNumber);
+          return;
+        }
+      ++counter;
+      tmpGroup = tmpGroup->next;
+    }
+  PRINTF(2)("Model number %i in %s not Found.\n", groupNumber, this->getName());
+  return;
+}
+
+
+/**
+ * @brief Draws the Model with a specific groupName
+ * @param groupName The name of the group that will be displayed.
+ *
+ * It does this by just calling the List that must have been created earlier.
+ */
+void StaticModel::draw (char* groupName) const
+{
+  if (groupName == NULL)
+     return;
+  PRINTF(4)("drawing the requested 3D-Models if found.\n");
+  ModelGroup* tmpGroup = this->firstGroup;
+  while (tmpGroup != NULL)
+    {
+      if (tmpGroup->name != NULL && !strcmp(tmpGroup->name, groupName))
+        {
+          PRINTF(4)("Drawing model %s\n", tmpGroup->name);
+          glCallList (tmpGroup->listNumber);
+          return;
+        }
+      tmpGroup = tmpGroup->next;
+    }
+  PRINTF(2)("Model Named %s in %s not Found.\n", groupName, this->getName());
+  return;
+}
+
+//////////
+// INIT //
+//////////
+
+/**
+ * @brief finalizes an Model.
+ *
+ * This funcion is needed, to delete all the Lists, and arrays that are no more
+ * needed because they are already imported into openGL.
+ * This will be applied at the end of the importing Process.
+*/
+bool StaticModel::cleanup()
+{
+  PRINTF(4)("cleaning up the 3D-Model to save Memory.\n");
+  this->firstGroup->cleanup();
+  return true;
+}
+
+//////////
+// MESH //
+//////////
+/**
+ * @brief adds a new Material to the Material List
+ * @param material the Material to add
+ * @returns the added material
+ *
+ * this also tells this Model, that all the Materials are handled externally
+ * with this option set the Materials will not be deleted with the Model.
+ */
+Material* StaticModel::addMaterial(Material* material)
+{
+  if (material == NULL)
+    return NULL;
+  ModelMaterial* modMat = new ModelMaterial;
+  modMat->external = true;
+  modMat->material = material;
+  this->materialList.push_back(modMat);
+  return modMat->material;
+}
+
+/**
+ * @brief adds a new Material to the Material List
+ * @param materialName the name of the Material to add
+ * @returns the added material
+ */
+Material* StaticModel::addMaterial(const char* materialName)
+{
+  ModelMaterial* modMat = new ModelMaterial;
+  modMat->external = false;
+  modMat->material = new Material(materialName);
+
+  // adding material to the List of materials
+  this->materialList.push_back(modMat);
+  return modMat->material;
+}
+
+/**
+ * @brief finds a Material by its name and returns it
+ * @param materialName the Name of the material to search for.
+ * @returns the Material if found, NULL otherwise
+ */
+Material* StaticModel::findMaterialByName(const char* materialName)
+{
+  list<ModelMaterial*>::iterator modMat;
+  for  (modMat = this->materialList.begin(); modMat != this->materialList.end(); modMat++)
+    if (!strcmp((*modMat)->material->getName(), materialName))
+      return (*modMat)->material;
+  return NULL;
+}
+
+/**
+ * @brief parses a group String
+ * @param groupString the new Group to create
+ *
+ * This function initializes a new Group.
+ * With it you should be able to create Models with more than one SubModel inside
+ */
+bool StaticModel::addGroup(const char* groupString)
+{
+  PRINTF(5)("Read Group: %s.\n", groupString);
+  if (this->groupCount != 0 && this->currentGroup->faceCount > 0)
+    {
+      // finalizeGroup(currentGroup);
+      this->currentGroup = this->currentGroup->next = new ModelGroup;
+    }
+  // setting the group name if not default.
+  if (strcmp(groupString, "default"))
+    {
+      this->currentGroup->name = new char [strlen(groupString)+1];
+      strcpy(this->currentGroup->name, groupString);
+    }
+  ++this->groupCount;
+}
+
+/**
+ * @brief parses a vertex-String
+ * @param vertexString The String that will be parsed.
+ *
+ *  If a vertex line is found this function will inject it into the vertex-Array
+ */
+bool StaticModel::addVertex (const char* vertexString)
+{
+  float subbuffer1;
+  float subbuffer2;
+  float subbuffer3;
+  sscanf (vertexString, "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
+  this->vertices.push_back(subbuffer1*scaleFactor);
+  this->vertices.push_back(subbuffer2*scaleFactor);
+  this->vertices.push_back(subbuffer3*scaleFactor);
+  this->pModelInfo.numVertices++;
+  return true;
+}
+
+/**
+ * @brief parses a vertex-String
+ * @param x the X-coordinate of the Vertex to add.
+ * @param y the Y-coordinate of the Vertex to add.
+ * @param z the Z-coordinate of the Vertex to add.
+ */
+bool StaticModel::addVertex(float x, float y, float z)
+{
+  PRINTF(5)("reading in a vertex: %f %f %f\n", x, y, z);
+  this->vertices.push_back(x*scaleFactor);
+  this->vertices.push_back(y*scaleFactor);
+  this->vertices.push_back(z*scaleFactor);
+  this->pModelInfo.numVertices++;
+  return true;
+}
+
+/**
+ * @brief parses a vertexNormal-String
+ * @param normalString The String that will be parsed.
+ *
+ * If a vertexNormal line is found this function will inject it into the vertexNormal-Array
+ */
+bool StaticModel::addVertexNormal (const char* normalString)
+{
+  float subbuffer1;
+  float subbuffer2;
+  float subbuffer3;
+  sscanf (normalString, "%f %f %f", &subbuffer1, &subbuffer2, &subbuffer3);
+  this->normals.push_back(subbuffer1);
+  this->normals.push_back(subbuffer2);
+  this->normals.push_back(subbuffer3);
+  this->pModelInfo.numNormals++;
+  return true;
+}
+
+/**
+ * @brief adds a VertexNormal.
+ * @param x The x coordinate of the Normal.
+ * @param y The y coordinate of the Normal.
+ * @param z The z coordinate of the Normal.
+ *
+ * If a vertexNormal line is found this function will inject it into the vertexNormal-Array
+ */
+bool StaticModel::addVertexNormal(float x, float y, float z)
+{
+  PRINTF(5)("found vertex-Normal %f, %f, %f\n", x, y, z);
+  this->normals.push_back(x);
+  this->normals.push_back(y);
+  this->normals.push_back(z);
+  this->pModelInfo.numNormals++;
+  return true;
+}
+
+/**
+ * @brief parses a vertexTextureCoordinate-String
+ * @param vTextureString The String that will be parsed.
+ *
+ * If a vertexTextureCoordinate line is found,
+ * this function will inject it into the vertexTexture-Array
+ *
+ * !! WARNING THIS IS DIFFERNT FROM addVervexTexture(float, float); because it changes the second entry to 1-v !!
+ */
+bool StaticModel::addVertexTexture (const char* vTextureString)
+{
+  float subbuffer1;
+  float subbuffer2;
+  sscanf (vTextureString, "%f %f", &subbuffer1, &subbuffer2);
+  this->vTexture.push_back(subbuffer1);
+  this->vTexture.push_back(1 - subbuffer2);
+  this->pModelInfo.numTexCoor++;
+  return true;
+}
+
+/**
+ * @brief adds a Texture Coordinate
+ * @param u The u coordinate of the TextureCoordinate.
+ * @param v The y coordinate of the TextureCoordinate.
+ *
+ * If a TextureCoordinate line is found this function will
+ *  inject it into the TextureCoordinate-Array
+ */
+bool StaticModel::addVertexTexture(float u, float v)
+{
+  PRINTF(5)("found vertex-Texture %f, %f\n", u, v);
+  this->vTexture.push_back(u);
+  this->vTexture.push_back(v);
+  this->pModelInfo.numTexCoor++;
+  return true;
+}
+
+/**
+ * @brief parses a face-string
+ * @param faceString The String that will be parsed.
+ *
+ * If a face line is found this function will add it to the glList.
+ *
+ * String is different from the argument addFace,
+ * in this, that the first Vertex/Normal/Texcoord is 1 instead of 0
+ */
+bool StaticModel::addFace (const char* faceString)
+{
+  if (this->currentGroup->faceCount >0)
+    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
+
+  ModelFaceElement* tmpElem = this->currentGroup->currentFace->firstElem = new ModelFaceElement;
+  tmpElem->next = NULL;
+  while(strcmp (faceString, "\0"))
+    {
+      if (this->currentGroup->currentFace->vertexCount>0)
+          tmpElem = tmpElem->next = new ModelFaceElement;
+      tmpElem->next = NULL;
+
+      char tmpValue [50];
+      int tmpLen;
+      char* vertex = NULL;
+      char* texture = NULL;
+      char* normal = NULL;
+
+      sscanf (faceString, "%s", tmpValue);
+      tmpLen = strlen(tmpValue);
+      vertex = tmpValue;
+
+      if ((texture = strstr (vertex, "/")) != NULL)
+        {
+          texture[0] = '\0';
+          texture ++;
+
+          if ((normal = strstr (texture, "/")) !=NULL)
+            {
+              normal[0] = '\0';
+              normal ++;
+            }
+        }
+      if (vertex)
+        tmpElem->vertexNumber = atoi(vertex)-1;
+      if (texture)
+        tmpElem->texCoordNumber = atoi(texture)-1;
+      if (normal)
+        tmpElem->normalNumber = atoi(normal)-1;
+
+      faceString += tmpLen;
+      if (strcmp (faceString, "\0"))
+        faceString++;
+      this->currentGroup->currentFace->vertexCount++;
+    }
+
+  this->currentGroup->faceCount += this->currentGroup->currentFace->vertexCount -2;
+  this->faceCount += this->currentGroup->currentFace->vertexCount -2;
+}
+
+/**
+ * @brief adds a new Face
+ * @param faceElemCount the number of Vertices to add to the Face.
+ * @param type The information Passed with each Vertex
+*/
+bool StaticModel::addFace(int faceElemCount, VERTEX_FORMAT type, ...)
+{
+  if (this->currentGroup->faceCount > 0)
+    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
+
+  ModelFaceElement* tmpElem = this->currentGroup->currentFace->firstElem = new ModelFaceElement;
+
+  va_list itemlist;
+  va_start (itemlist, type);
+
+  for (int i = 0; i < faceElemCount; i++)
+    {
+      if (this->currentGroup->currentFace->vertexCount > 0)
+        tmpElem = tmpElem->next = new ModelFaceElement;
+
+      tmpElem->vertexNumber = va_arg (itemlist, int);
+      if (type & TEXCOORD)
+        tmpElem->texCoordNumber = va_arg (itemlist, int);
+      if (type & NORMAL)
+        tmpElem->normalNumber = va_arg(itemlist, int);
+      this->currentGroup->currentFace->vertexCount++;
+    }
+  va_end(itemlist);
+
+  this->currentGroup->faceCount += this->currentGroup->currentFace->vertexCount - 2;
+  this->faceCount += this->currentGroup->currentFace->vertexCount -2;
+}
+
+/**
+ * Function that selects a material, if changed in the obj file.
+ * @param matString the Material that will be set.
+*/
+bool StaticModel::setMaterial(const char* matString)
+{
+  if (this->currentGroup->faceCount > 0)
+    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
+
+  this->currentGroup->currentFace->material = this->findMaterialByName(matString);
+
+  if (this->currentGroup->faceCount == 0)
+    this->currentGroup->faceCount++;
+}
+
+/**
+ * Function that selects a material, if changed in the obj file.
+ * @param mtl the Material that will be set.
+*/
+bool StaticModel::setMaterial(Material* mtl)
+{
+  if (this->currentGroup->faceCount > 0)
+    this->currentGroup->currentFace = this->currentGroup->currentFace->next = new ModelFace;
+
+  this->currentGroup->currentFace->material = mtl;
+
+  if (this->currentGroup->faceCount == 0)
+    this->currentGroup->faceCount++;
+}
+
+/**
+ * @brief A routine that is able to create normals.
+ *
+ * The algorithm does the following:
+ * 1. It calculates creates Vectors for each normale, and sets them to zero.
+ * 2. It then Walks through a) all the Groups b) all the Faces c) all the FaceElements
+ * 3. It searches for a points two neighbours per Face, takes Vecotrs to them calculates FaceNormals and adds it to the Points Normal.
+ * 4. It goes through all the normale-Points and calculates the VertexNormale and includes it in the normals-Array.
+ */
+bool StaticModel::buildVertexNormals ()
+{
+  PRINTF(4)("Normals are being calculated.\n");
+
+  Vector* normArray = new Vector [vertices.size()/3];
+  for (int i=0; i<vertices.size()/3;i++)
+    normArray[i] = Vector(.0,.0,.0);
+
+  int firstTouch;
+  int secondTouch;
+  Vector prevV;
+  Vector nextV;
+  Vector curV;
+
+  ModelGroup* tmpGroup = firstGroup;
+  while (tmpGroup != NULL)
+    {
+      ModelFace* tmpFace = tmpGroup->firstFace;
+      while (tmpFace != NULL)
+        {
+          if (tmpFace->firstElem != NULL)
+            {
+              ModelFaceElement* firstElem = tmpFace->firstElem;
+              ModelFaceElement* prevElem;
+              ModelFaceElement* curElem = firstElem;
+              ModelFaceElement* nextElem;
+              ModelFaceElement* lastElem;
+              // find last Element of the Chain. !! IMPORTANT:the last Element of the Chain must point to NULL, or it will resolv into an infinity-loop.
+              while (curElem != NULL)
+                {
+                  prevElem = curElem;
+                  curElem = curElem->next;
+                }
+              lastElem = prevElem;
+
+              curElem = firstElem;
+              for (int j=0; j<tmpFace->vertexCount; j++)
+                {
+                  if (!(nextElem = curElem->next))
+                    nextElem = firstElem;
+                  curElem->normalNumber = curElem->vertexNumber;
+
+                  curV = Vector (this->vertices[curElem->vertexNumber*3],
+				 this->vertices[curElem->vertexNumber*3+1],
+				 this->vertices[curElem->vertexNumber*3+2]);
+
+                  prevV = Vector (this->vertices[prevElem->vertexNumber*3],
+				  this->vertices[prevElem->vertexNumber*3+1],
+				  this->vertices[prevElem->vertexNumber*3+2]) - curV;
+
+                  nextV = Vector (this->vertices[nextElem->vertexNumber*3],
+				  this->vertices[nextElem->vertexNumber*3+1],
+				  this->vertices[nextElem->vertexNumber*3+2]) - curV;
+                  normArray[curElem->vertexNumber] = normArray[curElem->vertexNumber] + nextV.cross(prevV);
+
+                  prevElem = curElem;
+                  curElem = curElem->next;
+                }
+            }
+          tmpFace = tmpFace->next;
+        }
+      tmpGroup = tmpGroup->next;
+    }
+
+  for (int i=0; i < this->vertices.size()/3;i++)
+    {
+      normArray[i].normalize();
+      PRINTF(5)("Found Normale number %d: (%f; %f, %f).\n", i, normArray[i].x, normArray[i].y, normArray[i].z);
+
+      this->addVertexNormal(normArray[i].x, normArray[i].y, normArray[i].z);
+
+    }
+  delete[] normArray;
+}
+
+////////////
+// openGL //
+////////////
+/**
+ *  reads and includes the Faces/Materials into the openGL state Machine
+*/
+bool StaticModel::importToDisplayList()
+{
+  // finalize the Arrays
+  if (normals.size() == 0) // vertices-Array must be built for this
+    this->buildVertexNormals();
+
+  this->currentGroup = this->firstGroup;
+
+  while (this->currentGroup != NULL)
+    {
+
+      // creating a glList for the Group
+      if ((this->currentGroup->listNumber = glGenLists(1)) == 0)
+        {
+          PRINTF(2)("glList could not be created for this Model\n");
+          return false;
+        }
+      glNewList (this->currentGroup->listNumber, GL_COMPILE);
+
+      // Putting Faces to GL
+      ModelFace* tmpFace = this->currentGroup->firstFace;
+      while (tmpFace != NULL)
+        {
+          if (tmpFace->vertexCount == 0 && tmpFace->material != NULL)
+            {
+              if (this->currentGroup->faceMode != -1)
+                glEnd();
+              this->currentGroup->faceMode = 0;
+              Material* tmpMat;
+              if (tmpFace->material != NULL)
+                {
+                  tmpFace->material->select();
+                  PRINTF(5)("using material %s for coming Faces.\n", tmpFace->material->getName());
+                }
+            }
+
+          else if (tmpFace->vertexCount == 3)
+            {
+              if (this->currentGroup->faceMode != 3)
+                {
+                  if (this->currentGroup->faceMode != -1)
+                    glEnd();
+                  glBegin(GL_TRIANGLES);
+                }
+
+              this->currentGroup->faceMode = 3;
+              PRINTF(5)("found triag.\n");
+            }
+
+          else if (tmpFace->vertexCount == 4)
+            {
+              if (this->currentGroup->faceMode != 4)
+                {
+                  if (this->currentGroup->faceMode != -1)
+                    glEnd();
+                  glBegin(GL_QUADS);
+                }
+              this->currentGroup->faceMode = 4;
+              PRINTF(5)("found quad.\n");
+            }
+
+          else if (tmpFace->vertexCount > 4)
+            {
+              if (this->currentGroup->faceMode != -1)
+                glEnd();
+              glBegin(GL_POLYGON);
+              PRINTF(5)("Polygon with %i faces found.", tmpFace->vertexCount);
+              this->currentGroup->faceMode = tmpFace->vertexCount;
+            }
+
+          ModelFaceElement* tmpElem = tmpFace->firstElem;
+          while (tmpElem != NULL)
+            {
+              //      PRINTF(2)("%s\n", tmpElem->value);
+              this->addGLElement(tmpElem);
+              tmpElem = tmpElem->next;
+            }
+          tmpFace = tmpFace->next;
+        }
+      glEnd();
+      glEndList();
+
+      this->currentGroup = this->currentGroup->next;
+    }
+}
+
+
+/**
+ *  builds an array of triangles, that can later on be used for obb separation and octree separation
+ */
+bool StaticModel::buildTriangleList()
+{
+  if( unlikely(this->pModelInfo.pTriangles != NULL))
+    return true;
+  /* make sure, that all the arrays are finalized */
+  if( normals.size() == 0) // vertices-Array must be built for this
+    this->buildVertexNormals();
+
+  int index = 0;                   //!< the counter for the triangle array
+  ModelFaceElement* tmpElem;       //!< the temporary faceelement reference
+  ModelFace* tmpFace;              //!< the temporary face referece
+
+  /* count the number of triangles */
+  /* now iterate through all groups and build up the triangle list */
+  this->currentGroup = this->firstGroup;
+  while( this->currentGroup != NULL)
+  {
+    tmpFace = this->currentGroup->firstFace;
+    while( tmpFace != NULL)
+    {
+
+      /* if its a triangle just add it to the list */
+      if( tmpFace->vertexCount == 3)
+      {
+        ++this->pModelInfo.numTriangles;
+      } /* if the polygon is a quad */
+      else if( tmpFace->vertexCount == 4)
+      {
+        this->pModelInfo.numTriangles += 2;
+      }
+      else if( tmpFace->vertexCount > 4)
+      {
+        PRINTF(1)("This model (%s) got over 4 vertices per face <=> conflicts in the CD engine!\n", this->getName());
+      //exit(0);
+      }
+      tmpFace = tmpFace->next;
+    }
+    this->currentGroup = this->currentGroup->next;
+  }
+
+  PRINTF(3)("got %i triangles, %i vertices\n", this->pModelInfo.numTriangles, this->pModelInfo.numVertices);
+
+
+  /* write MODELINFO structure */
+
+  /* allocate memory for the new triangle structures */
+  if( (this->pModelInfo.pTriangles = new sTriangleExt[this->pModelInfo.numTriangles]) == NULL)
+  {
+    PRINTF(1)("Could not allocate memory for triangle list\n");
+    return false;
+  }
+
+  /* now iterate through all groups and build up the triangle list */
+  this->currentGroup = this->firstGroup;
+  while( this->currentGroup != NULL)
+  {
+      // Putting Faces to GL
+    tmpFace = this->currentGroup->firstFace;
+    while( tmpFace != NULL)
+    {
+      tmpElem = tmpFace->firstElem;
+
+      /* if its a triangle just add it to the list */
+      if( tmpFace->vertexCount == 3)
+      {
+        for( int j = 0; j < 3; ++j)
+        {
+          this->pModelInfo.pTriangles[index].indexToVertices[j] = (unsigned int)tmpElem->vertexNumber /* * 3 */;
+          this->pModelInfo.pTriangles[index].indexToNormals[j] = (unsigned int)tmpElem->normalNumber /* * 3 */;
+          this->pModelInfo.pTriangles[index].indexToTexCoor[j] = (unsigned int)tmpElem->texCoordNumber /* * 3 */;
+          tmpElem = tmpElem->next;
+        }
+        ++index;
+      } /* if the polygon is a quad */
+      else if( tmpFace->vertexCount == 4)
+      {
+
+        this->pModelInfo.pTriangles[index].indexToVertices[0] = (unsigned int)tmpElem->vertexNumber;
+        this->pModelInfo.pTriangles[index].indexToNormals[0] = (unsigned int)tmpElem->normalNumber;
+        this->pModelInfo.pTriangles[index].indexToTexCoor[0] = (unsigned int)tmpElem->texCoordNumber;
+
+        this->pModelInfo.pTriangles[index + 1].indexToVertices[0] = (unsigned int)tmpElem->vertexNumber;
+        this->pModelInfo.pTriangles[index + 1].indexToNormals[0] = (unsigned int)tmpElem->normalNumber;
+        this->pModelInfo.pTriangles[index + 1].indexToTexCoor[0] = (unsigned int)tmpElem->texCoordNumber;
+        tmpElem = tmpElem->next;
+
+        this->pModelInfo.pTriangles[index].indexToVertices[1] = (unsigned int)tmpElem->vertexNumber;
+        this->pModelInfo.pTriangles[index].indexToNormals[1] = (unsigned int)tmpElem->normalNumber;
+        this->pModelInfo.pTriangles[index].indexToTexCoor[1] = (unsigned int)tmpElem->texCoordNumber;
+        tmpElem = tmpElem->next;
+
+        this->pModelInfo.pTriangles[index].indexToVertices[2] = (unsigned int)tmpElem->vertexNumber;
+        this->pModelInfo.pTriangles[index].indexToNormals[2] = (unsigned int)tmpElem->normalNumber;
+        this->pModelInfo.pTriangles[index].indexToTexCoor[2] = (unsigned int)tmpElem->texCoordNumber;
+
+        this->pModelInfo.pTriangles[index + 1].indexToVertices[2] = (unsigned int)tmpElem->vertexNumber;
+        this->pModelInfo.pTriangles[index + 1].indexToNormals[2] = (unsigned int)tmpElem->normalNumber;
+        this->pModelInfo.pTriangles[index + 1].indexToTexCoor[2] = (unsigned int)tmpElem->texCoordNumber;
+        tmpElem = tmpElem->next;
+
+        this->pModelInfo.pTriangles[index + 1].indexToVertices[1] = (unsigned int)tmpElem->vertexNumber;
+        this->pModelInfo.pTriangles[index + 1].indexToNormals[1] = (unsigned int)tmpElem->normalNumber;
+        this->pModelInfo.pTriangles[index + 1].indexToTexCoor[1] = (unsigned int)tmpElem->texCoordNumber;
+
+        index += 2;
+      }
+      tmpFace = tmpFace->next;
+    }
+    this->currentGroup = this->currentGroup->next;
+  }
+  return true;
+}
+
+
+/**
+ *  Adds a Face-element (one vertex of a face) with all its information.
+ * @param elem The FaceElement to add to the OpenGL-environment.
+
+   It does this by searching:
+   1. The Vertex itself
+   2. The VertexNormale
+   3. The VertexTextureCoordinate
+   merging this information, the face will be drawn.
+*/
+bool StaticModel::addGLElement (ModelFaceElement* elem)
+{
+  PRINTF(5)("importing grafical Element to openGL.\n");
+
+  if (elem->texCoordNumber != -1)
+    {
+      if (likely(elem->texCoordNumber < this->pModelInfo.numTexCoor))
+        glTexCoord2fv(&this->vTexture[0] + elem->texCoordNumber * 2);
+      else
+        PRINTF(2)("TextureCoordinate %d is not in the List (max: %d)\nThe Model might be incomplete\n",
+                  elem->texCoordNumber, this->pModelInfo.numTexCoor);
+    }
+  if (elem->normalNumber != -1)
+    {
+    if (likely(elem->normalNumber < this->pModelInfo.numNormals))
+      glNormal3fv(&this->normals[0] + elem->normalNumber * 3);
+    else
+        PRINTF(2)("Normal %d is not in the List (max: %d)\nThe Model might be incomplete",
+                  elem->normalNumber, this->pModelInfo.numNormals);
+    }
+  if (elem->vertexNumber != -1)
+    {
+      if (likely(elem->vertexNumber < this->pModelInfo.numVertices))
+          glVertex3fv(&this->vertices[0]+ elem->vertexNumber * 3);
+      else
+        PRINTF(2)("Vertex %d is not in the List (max: %d)\nThe Model might be incomplete",
+                  elem->vertexNumber, this->pModelInfo.numVertices);
+    }
+
+}
+
+/**
+ *  Includes a default model
+
+   This will inject a Cube, because this is the most basic model.
+*/
+void StaticModel::cubeModel()
+{
+  this->addVertex (-0.5, -0.5, 0.5);
+  this->addVertex (0.5, -0.5, 0.5);
+  this->addVertex (-0.5, 0.5, 0.5);
+  this->addVertex (0.5, 0.5, 0.5);
+  this->addVertex (-0.5, 0.5, -0.5);
+  this->addVertex (0.5, 0.5, -0.5);
+  this->addVertex (-0.5, -0.5, -0.5);
+  this->addVertex (0.5, -0.5, -0.5);
+
+  this->addVertexTexture (0.0, 0.0);
+  this->addVertexTexture (1.0, 0.0);
+  this->addVertexTexture (0.0, 1.0);
+  this->addVertexTexture (1.0, 1.0);
+  this->addVertexTexture (0.0, 2.0);
+  this->addVertexTexture (1.0, 2.0);
+  this->addVertexTexture (0.0, 3.0);
+  this->addVertexTexture (1.0, 3.0);
+  this->addVertexTexture (0.0, 4.0);
+  this->addVertexTexture (1.0, 4.0);
+  this->addVertexTexture (2.0, 0.0);
+  this->addVertexTexture (2.0, 1.0);
+  this->addVertexTexture (-1.0, 0.0);
+  this->addVertexTexture (-1.0, 1.0);
+
+  this->addVertexNormal (0.0, 0.0, 1.0);
+  this->addVertexNormal (0.0, 0.0, 1.0);
+  this->addVertexNormal (0.0, 0.0, 1.0);
+  this->addVertexNormal (0.0, 0.0, 1.0);
+  this->addVertexNormal (0.0, 1.0, 0.0);
+  this->addVertexNormal (0.0, 1.0, 0.0);
+  this->addVertexNormal (0.0, 1.0, 0.0);
+  this->addVertexNormal (0.0, 1.0, 0.0);
+  this->addVertexNormal (0.0, 0.0, -1.0);
+  this->addVertexNormal (0.0, 0.0, -1.0);
+  this->addVertexNormal (0.0, 0.0, -1.0);
+  this->addVertexNormal (0.0, 0.0, -1.0);
+  this->addVertexNormal (0.0, -1.0, 0.0);
+  this->addVertexNormal (0.0, -1.0, 0.0);
+  this->addVertexNormal (0.0, -1.0, 0.0);
+  this->addVertexNormal (0.0, -1.0, 0.0);
+  this->addVertexNormal (1.0, 0.0, 0.0);
+  this->addVertexNormal (1.0, 0.0, 0.0);
+  this->addVertexNormal (1.0, 0.0, 0.0);
+  this->addVertexNormal (1.0, 0.0, 0.0);
+  this->addVertexNormal (-1.0, 0.0, 0.0);
+  this->addVertexNormal (-1.0, 0.0, 0.0);
+  this->addVertexNormal (-1.0, 0.0, 0.0);
+  this->addVertexNormal (-1.0, 0.0, 0.0);
+
+  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 0,0,0, 1,1,1, 3,3,2, 2,2,3);
+  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 2,2,4, 3,3,5, 5,5,6, 4,4,7);
+  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 4,4,8, 5,5,9, 7,7,10, 6,6,11);
+  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 6,6,12, 7,7,13, 1,9,14, 0,8,15);
+  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 1,1,16, 7,10,17, 5,11,18, 3,3,19);
+  this->addFace (4, VERTEX_TEXCOORD_NORMAL, 6,12,20, 0,0,21, 2,2,22, 4,13,23);
+}
Index: branches/network/src/lib/graphics/importer/static_model.h
===================================================================
--- branches/network/src/lib/graphics/importer/static_model.h	(revision 6636)
+++ branches/network/src/lib/graphics/importer/static_model.h	(revision 6636)
@@ -0,0 +1,166 @@
+/*!
+ * @file static_model.h
+ * @brief Contains the Model Class that handles Static 3D-Models rendered with glList's
+ */
+
+#ifndef _STATIC_MODEL_H
+#define _STATIC_MODEL_H
+
+#include "model.h"
+
+#include "material.h"
+#include "glincl.h"
+#include <vector>
+#include <list>
+
+// FORWARD DECLARATION //
+template<class T> class tArray;
+
+// definition of different modes for setting up Faces
+#define VERTEX 0       //!< If Faces are created WITH Vertex-Coordinate
+#define NORMAL 1       //!< If Faces are created WITH Normals (otherwise autocalculate)
+#define TEXCOORD 2     //!< If Faces are created WITH TextureCoordinate
+
+//! an enumerator for VERTEX_FORMAT
+typedef enum VERTEX_FORMAT {
+  VERTEX_ONLY = VERTEX,
+  VERTEX_NORMAL = NORMAL,
+  VERTEX_TEXCOORD = TEXCOORD,
+  VERTEX_TEXCOORD_NORMAL = NORMAL | TEXCOORD
+};
+
+////////////////////
+/// SUB-ELEMENTS ///
+////////////////////
+//! This is the placeholder of one Vertex beloning to a Face.
+class ModelFaceElement
+{
+ public:
+  ModelFaceElement();
+  ~ModelFaceElement();
+
+  int                 vertexNumber;         //!< The number of the Vertex out of the Array* vertices, this vertex points to.
+  int                 normalNumber;         //!< The number of the Normal out of the Array* normals, this vertex points to.
+  int                 texCoordNumber;       //!< The number of the textureCoordinate out of the Array* vTexture, this vertex points to.
+
+  ModelFaceElement*   next;                 //!< Point to the next FaceElement in this List.
+};
+
+//! This is the placeholder of a Face belonging to a Group of Faces.
+class ModelFace
+{
+ public:
+  ModelFace();
+  ~ModelFace();
+
+  unsigned int        vertexCount;     //!< The Count of vertices this Face has.
+  ModelFaceElement*   firstElem;       //!< Points to the first Vertex (FaceElement) of this Face.
+  Material*           material;        //!< The Material to use.
+
+  ModelFace*          next;            //!< Pointer to the next Face.
+};
+
+//! Group to handle multiple Models per obj-file.
+class ModelGroup
+{
+ public:
+  ModelGroup();
+  ~ModelGroup();
+
+  void cleanup();
+
+  char*        name;           //!< the Name of the Group. this is an identifier, that can be accessed via the draw (char* name) function.
+  GLubyte*     indices;        //!< The indices of the Groups. Needed for vertex-arrays
+  GLuint       listNumber;     //!< The number of the GL-List this Group gets.
+  ModelFace*   firstFace;      //!< The first Face in this group.
+  ModelFace*   currentFace;    //!< The current Face in this Group (the one we are currently working with.)
+  int          faceMode;       //!< The Mode the Face is in: initially -1, 0 for FaceList opened, 1 for Material,  3 for triangle, 4 for Quad, 5+ for Poly @todo ENUM...
+  int          faceCount;      //!< The Number of Faces this Group holds.
+
+  ModelGroup*  next;           //!< Pointer to the next Group.
+};
+
+struct ModelMaterial
+{
+  Material* material;
+  bool external;
+};
+
+/////////////
+/// MODEL ///
+/////////////
+//! Class that handles static 3D-Models.
+/**
+ * it can also read them in and display them.
+ * All the objects are rendered with glLists
+ */
+class StaticModel : public Model
+{
+ public:
+  StaticModel(const char* modelName = NULL);
+  virtual ~StaticModel();
+
+  virtual void draw() const;
+  void draw(int groupNumber) const;
+  void draw(char* groupName) const;
+
+  void rebuild();
+
+  Material* addMaterial(Material* material);
+  Material* addMaterial(const char* materialName);
+
+  bool addGroup(const char* groupString);
+
+  bool addVertex(const char* vertexString);
+  bool addVertex(float x, float y, float z);
+
+  bool addFace(const char* faceString);
+  bool addFace(int faceElemCount, VERTEX_FORMAT type, ...);
+
+  bool addVertexNormal(const char* normalString);
+  bool addVertexNormal(float x, float y, float z);
+
+  bool addVertexTexture(const char* vTextureString);
+  bool addVertexTexture(float u, float v);
+
+  bool setMaterial(const char* mtlString);
+  bool setMaterial(Material* mtl);
+
+  void finalize();
+
+
+ protected:
+  void cubeModel();
+
+  Material* findMaterialByName(const char* materialName);
+
+ protected:
+  float            scaleFactor;     //!< The Factor with which the Model should be scaled. @todo maybe one wants to scale the Model after Initialisation
+
+ private:
+  bool buildVertexNormals();
+
+  bool importToDisplayList();
+  bool buildTriangleList();
+
+  bool addGLElement(ModelFaceElement* elem);
+
+  bool cleanup();
+
+ private:
+  bool                       finalized;       //!< Sets the Object to be finalized.
+
+  unsigned int               faceCount;       //!< A modelwide Counter for the faces
+
+  std::vector<GLfloat>       vertices;        //!< The Array that handles the Vertices.
+  std::vector<GLfloat>       normals;         //!< The Array that handles the Normals.
+  std::vector<GLfloat>       vTexture;        //!< The Array that handles the VertexTextureCoordinates.
+
+  ModelGroup*                firstGroup;      //!< The first of all groups.
+  ModelGroup*                currentGroup;    //!< The currentGroup. this is the one we will work with.
+  int                        groupCount;      //!< The Count of Groups.
+
+  std::list<ModelMaterial*>  materialList;    //!< A list for all the Materials in this Model
+};
+
+#endif
Index: branches/network/src/lib/graphics/importer/tc.COPYRIGHT
===================================================================
--- branches/network/src/lib/graphics/importer/tc.COPYRIGHT	(revision 6636)
+++ branches/network/src/lib/graphics/importer/tc.COPYRIGHT	(revision 6636)
@@ -0,0 +1,25 @@
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided 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
+     notice, this list of conditions and the following disclaimer in the
+     documentation and/or other materials provided with the distribution.
+  3. All advertising materials mentioning features or use of this software
+     must display the following acknowledgement:
+       This product includes software developed by Brad Grantham and
+       Applied Conjecture.
+  4. Neither the name Brad Grantham nor Applied Conjecture 
+     may be used to endorse or promote products derived from this software
+     without specific prior written permission.
+  5. Notification must be made to Brad Grantham about inclusion of this
+     software in a product including the author of the product and the name
+     and purpose of the product.  Notification can be made using email
+     to Brad Grantham's current address (grantham@plunk.org as of September
+     20th, 2000) or current U.S. mail address.
+
+$Header: /home/grantham/cvsroot/projects/modules/tc/COPYRIGHT,v 1.1 2000/09/21 19:36:56 grantham Exp $
+
+# vi:tabstop=8
+#
Index: branches/network/src/lib/graphics/importer/tc.cc
===================================================================
--- branches/network/src/lib/graphics/importer/tc.cc	(revision 6636)
+++ branches/network/src/lib/graphics/importer/tc.cc	(revision 6636)
@@ -0,0 +1,1448 @@
+/*
+ * $Header: /home/grantham/cvsroot/projects/modules/tc/tc.c,v 1.27 2000/10/10 16:09:23 grantham Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include "tc.h"
+
+/* SNIPPET "table.c" Inducted Wed Nov 22 09:36:55 2000 */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if !defined(MEM_CHART)
+#define chartedSetLabel(a)
+#endif
+
+#define LEVEL1COUNT 16384
+#define LEVEL2COUNT 1024
+#define LEVEL3COUNT 256
+
+typedef struct TableLevel3
+{
+    int EntryCount;
+    void *Table[LEVEL3COUNT];
+    char IsSet[LEVEL3COUNT];
+} TableLevel3;
+
+typedef struct TableLevel2
+{
+    int EntryCount;
+    TableLevel3 *Table[LEVEL2COUNT];
+} TableLevel2;
+
+typedef struct TableRoot
+{
+    size_t EntryCount;
+    size_t TotalEntryCount;
+    size_t TotalAllocatedBytes;
+    int EmptyEntryCount;
+    TableLevel2 *Table[LEVEL1COUNT];
+} TableRoot;
+
+typedef struct TableIterator {
+    int i1, i2, i3;
+    unsigned int i;
+    TableLevel3 *CurLevel3;
+    int CheckLevel1, CheckLevel2;
+} TableIterator;
+
+TableRoot *tableNew(void)
+{
+    TableRoot *tr;
+
+    chartedSetLabel("table root");
+    tr = (TableRoot *)calloc(sizeof(TableRoot), 1);
+    return tr;
+}
+
+TableIterator *tableNewIterator(void)
+{
+    TableIterator *ti;
+
+    chartedSetLabel("table iterator");
+    ti = (TableIterator *)malloc(sizeof(TableIterator));
+    return ti;
+}
+
+int tableRetrieve(unsigned int a, TableRoot *table, void **ref)
+{
+    int i1 = a / (LEVEL2COUNT * LEVEL3COUNT);
+    int i2 = (a / LEVEL3COUNT) % LEVEL2COUNT;
+    int i3 = a % LEVEL3COUNT;
+
+    if(table->Table[i1] == NULL)
+        return 0;
+    if(table->Table[i1]->Table[i2] == NULL)
+        return 0;
+    if(!table->Table[i1]->Table[i2]->IsSet[i3])
+        return 0;
+    if(ref != NULL)
+        *ref = table->Table[i1]->Table[i2]->Table[i3];
+    return 1;
+}
+
+int tableInsert(unsigned int a, TableRoot *table, void *ref)
+{
+    int i1 = a / (LEVEL2COUNT * LEVEL3COUNT);
+    int i2 = (a / LEVEL3COUNT) % LEVEL2COUNT;
+    int i3 = a % LEVEL3COUNT;
+
+    if(table->Table[i1] == NULL) {
+	chartedSetLabel("table level 2");
+        table->Table[i1] = (TableLevel2 *)calloc(1, sizeof(TableLevel2));
+	table->TotalAllocatedBytes += sizeof(TableLevel2);
+        if(table->Table[i1] == NULL)
+            return 0;
+    }
+    if(table->Table[i1]->Table[i2] == NULL) {
+	chartedSetLabel("table level 3");
+        table->Table[i1]->Table[i2] =
+	    (TableLevel3 *)calloc(1, sizeof(TableLevel3));
+	table->TotalAllocatedBytes += sizeof(TableLevel3);
+        if(table->Table[i1]->Table[i2] == NULL)
+            return 0;
+	table->Table[i1]->EntryCount++;
+	table->TotalEntryCount += LEVEL3COUNT;
+	table->EmptyEntryCount += LEVEL3COUNT;
+    }
+    if(!table->Table[i1]->Table[i2]->IsSet[i3]) {
+	table->Table[i1]->Table[i2]->EntryCount++;
+	table->EmptyEntryCount --;
+	table->Table[i1]->Table[i2]->IsSet[i3] = 1;
+    }
+    table->Table[i1]->Table[i2]->Table[i3] = ref;
+    return 1;
+}
+
+int tableRemove(unsigned int a, TableRoot *table, void **wasref)
+{
+    int i1 = a / (LEVEL2COUNT * LEVEL3COUNT);
+    int i2 = (a / LEVEL3COUNT) % LEVEL2COUNT;
+    int i3 = a % LEVEL3COUNT;
+
+    if(table->Table[i1] == NULL)
+	return 0;
+    if(table->Table[i1]->Table[i2] == NULL)
+	return 0;
+    if(!table->Table[i1]->Table[i2]->IsSet[i3])
+        return 0;
+    if(wasref != NULL)
+        *wasref = table->Table[i1]->Table[i2]->Table[i3];
+    table->Table[i1]->Table[i2]->IsSet[i3] = 0;
+    table->EmptyEntryCount ++;
+    if(--table->Table[i1]->Table[i2]->EntryCount == 0) {
+	table->EmptyEntryCount -= LEVEL3COUNT;
+	table->TotalEntryCount -= LEVEL3COUNT;
+	free(table->Table[i1]->Table[i2]);
+	table->TotalAllocatedBytes -= sizeof(TableLevel3);
+	table->Table[i1]->Table[i2] = NULL;
+	if(--table->Table[i1]->EntryCount == 0) {
+	    table->TotalAllocatedBytes -= sizeof(TableLevel2);
+	    free(table->Table[i1]);
+	    table->Table[i1] = NULL;
+	}
+    }
+    return 1;
+}
+
+void tableResetIterator(TableIterator *ti)
+{
+    ti->i1 = 0;
+    ti->i2 = 0;
+    ti->i3 = 0;
+    ti->i = 0;
+    ti->CheckLevel1 = 1;
+    ti->CheckLevel2 = 1;
+}
+
+int tableIterate(TableRoot *table, TableIterator *ti, unsigned int *i, void **ref)
+{
+    int done;
+
+    done = 0;
+    while(ti->i1 < LEVEL1COUNT) {
+        if(ti->CheckLevel1 && table->Table[ti->i1] == NULL) {
+	    ti->i += LEVEL2COUNT * LEVEL3COUNT;
+	    ti->i1++;
+	    continue;
+	} else
+	    ti->CheckLevel1 = 0;
+        if(ti->CheckLevel2 && table->Table[ti->i1]->Table[ti->i2] == NULL) {
+	    ti->i += LEVEL3COUNT;
+	    if(++ti->i2 >= LEVEL2COUNT) {
+		ti->i2 = 0;
+		ti->i1++;
+		ti->CheckLevel1 = 1;
+	    }
+	    continue;
+	} else
+	    ti->CheckLevel2 = 0;
+	if(ti->i3 == 0)
+	    ti->CurLevel3 = table->Table[ti->i1]->Table[ti->i2];
+	if(ti->CurLevel3->IsSet[ti->i3]) {
+	    if(ref != NULL)
+		*ref = ti->CurLevel3->Table[ti->i3];
+	    if(i != NULL)
+		*i = ti->i;
+	    done = 1;
+	}
+	ti->i++;
+	if(++ti->i3 >= LEVEL3COUNT) {
+	    ti->i3 = 0;
+	    ti->CheckLevel2 = 1;
+	    if(++ti->i2 >= LEVEL2COUNT) {
+		ti->i2 = 0;
+		ti->i1++;
+		ti->CheckLevel1 = 1;
+	    }
+	}
+	if(done)
+	    return 1;
+    }
+    return 0;
+}
+
+void tableDelete(TableRoot *table, void (*datumDelete)(void *datum))
+{
+    int i1, i2, i3;
+
+    for(i1 = 0; i1 < LEVEL1COUNT; i1++) {
+        if(table->Table[i1] != NULL) {
+	    for(i2 = 0; i2 < LEVEL2COUNT; i2++) {
+		if(table->Table[i1]->Table[i2] != NULL) {
+		    for(i3 = 0; i3 < LEVEL3COUNT; i3++) {
+			if(table->Table[i1]->Table[i2]->IsSet[i3])
+			    datumDelete(table->Table[i1]->Table[i2]->Table[i3]);
+		    }
+		    free(table->Table[i1]->Table[i2]);
+		}
+	    }
+	    free(table->Table[i1]);
+	    table->Table[i1] = NULL;
+	}
+    }
+    table->TotalEntryCount = 0;
+    table->EmptyEntryCount = 0;
+    table->TotalAllocatedBytes = 0;
+}
+
+void tableGetStats(TableRoot *table, size_t *totalBytes, size_t *emptyCount,
+    size_t *totalCount)
+{
+    if(emptyCount != NULL)
+        *emptyCount = table->EmptyEntryCount;
+    if(totalCount != NULL)
+        *totalCount = table->TotalEntryCount;
+    if(totalBytes != NULL)
+        *totalBytes = table->TotalAllocatedBytes;
+}
+
+size_t tableGetIteratorSize(void)
+{
+    return sizeof(TableIterator);
+}
+
+/* "table.c" ENDSNIPPET */
+
+#if !defined(MEM_CHART)
+#define chartedSetLabel(a)
+#endif
+
+#if defined(DEBUG)
+#define ACTC_DEBUG(a) a
+#else
+#define ACTC_DEBUG(a)
+#endif
+
+#if defined(INFO)
+#define ACTC_INFO(a) a
+#else
+#define ACTC_INFO(a)
+#endif
+
+
+#define ACTC_CHECK(a) \
+    { \
+        int theErrorNow; \
+	theErrorNow = (a); \
+	if(theErrorNow < 0) \
+	    return theErrorNow; \
+    }
+
+typedef struct {
+    struct ACTCVertex *FinalVert;
+} ACTCTriangle;
+
+typedef struct {
+    struct ACTCVertex *V2;
+    int Count;
+    int TriangleCount;
+    ACTCTriangle *Triangles;
+} ACTCEdge;
+
+typedef struct ACTCVertex {
+    unsigned int V;
+    int Count;
+    struct ACTCVertex **PointsToMe;
+    struct ACTCVertex *Next;
+    int EdgeCount;
+    ACTCEdge *Edges;
+} ACTCVertex;
+
+/* private tokens */
+#define ACTC_NO_MATCHING_VERT		-0x3000
+#define ACTC_FWD_ORDER			0
+#define ACTC_REV_ORDER			1
+
+#define MAX_STATIC_VERTS		10000000 /* buh? */
+
+struct _ACTCData {
+
+    /* vertex and edge database */
+    int VertexCount;
+    TableRoot *Vertices;
+    TableIterator *VertexIterator;
+    int CurMaxVertValence;
+    int CurMinVertValence;
+    ACTCVertex **VertexBins;
+
+    /* alternate vertex array if range small enough */
+    ACTCVertex *StaticVerts;
+    int UsingStaticVerts;
+    unsigned int VertRange;
+
+    /* During consolidation */
+    int CurWindOrder;
+    int PrimType;
+    ACTCVertex *V1;
+    ACTCVertex *V2;
+    int VerticesSoFar;
+
+    /* Error and state handling */
+    int IsInputting;
+    int IsOutputting;
+    int Error;
+
+    /* actcParam-settable parameters */
+    unsigned int MinInputVert;
+    unsigned int MaxInputVert;
+    int MaxVertShare;
+    int MaxEdgeShare;
+    int MinFanVerts;
+    int MaxPrimVerts;
+    int HonorWinding;
+};
+
+#if defined(DEBUG) || defined(INFO)
+
+static void dumpTriangles(ACTCEdge *e, FILE *fp)
+{
+    int i;
+    int c;
+    char v[12];
+
+    c = fprintf(fp, "      %d triangles: ");
+    for(i = 0; i < e->TriangleCount; i++) {
+	if(c + 1 + sprintf(v, "%u", e->Triangles[i].FinalVert) > 78) {
+	    fputs("\n", fp);
+	    c = fprintf(fp, "        ");
+	}
+	c += fprintf(fp, " %s", v);
+    }
+    fputs("\n", fp);
+}
+
+static void dumpEdges(ACTCVertex *vert, FILE *fp)
+{
+    int i;
+    int c;
+    char v[26]; /* two signed ints plus x plus NUL */
+
+    for(i = 0; i < vert->EdgeCount; i++) {
+	fprintf(fp, "    %u->%u (%d times)\n", vert->V, vert->Edges[i].V2->V,
+	    vert->Edges[i].Count);
+	dumpTriangles(&vert->Edges[i], fp);
+    }
+    fputs("\n", fp);
+}
+
+static void dumpVertices(ACTCData *tc, FILE *fp)
+{
+    int i;
+    ACTCVertex *v;
+
+    if(!tc->UsingStaticVerts)
+        tableResetIterator(tc->VertexIterator);
+
+    fprintf(fp, "%d vertices in valences list\n", tc->VertexCount);
+    if(tc->UsingStaticVerts) {
+        for(i = 0; i < tc->VertRange; i++) {
+	    v = &tc->StaticVerts[i];
+	    if(v->Count > 0) {
+		fprintf(fp, "  vertex %u, valence %d, %d edges\n", v->V,
+		    v->Count, v->EdgeCount);
+		dumpEdges(v, fp);
+	    }
+	}
+    } else {
+	for(i = 0; i < tc->VertexCount; i++) {
+	    if(tableIterate(tc->Vertices, tc->VertexIterator, NULL,
+		(void **)&v) == 0) {
+		fprintf(fp, "ACTC::dumpVertices : fewer vertices in the table "
+		    "than we expected!\n");
+		fprintf(stderr, "ACTC::dumpVertices : fewer vertices in the table "
+		    "than we expected!\n");
+	    }
+	    if(v == NULL) {
+		fprintf(fp, "ACTC::dumpVertices : did not expect to get a NULL"
+		    "Vertex from the table iterator!\n");
+		fprintf(stderr, "ACTC::dumpVertices : did not expect to get a NULL"
+		    "Vertex from the table iterator!\n");
+	    }
+	    fprintf(fp, "  vertex %u, valence %d, %d edges\n", v->V, v->Count,
+		v->EdgeCount);
+	    dumpEdges(v, fp);
+	}
+    }
+}
+
+static void dumpVertexBins(ACTCData *tc, FILE *fp)
+{
+    ACTCVertex *cur;
+    int i;
+    int c;
+    char v[26]; /* two signed ints plus x plus NUL */
+
+    fprintf(fp, "vertex bins:\n");
+    if(tc->VertexBins == NULL) {
+        fprintf(fp, "        empty.\n");
+	return;
+    }
+    for(i = 1; i <= tc->CurMaxVertValence; i++) {
+        cur = tc->VertexBins[i];
+	c = fprintf(fp, "        bin %d -> ", i);
+	while(cur != NULL) {
+	    if(c + 1 + sprintf(v, "%ux%d", cur->V, cur->Count) > 78) {
+		fputs("\n", fp);
+		c = fprintf(fp, "          ");
+	    }
+	    c += fprintf(fp, " %s", v);
+	    cur = cur->Next;
+	}
+	fputs("\n", fp);
+    }
+}
+
+void actcDumpState(ACTCData *tc, FILE *fp)
+{
+    dumpVertices(tc, fp);
+    dumpVertexBins(tc, fp);
+}
+
+#endif /* DEBUG || INFO */
+
+#if defined(DEBUG)
+
+static int abortWithOptionalDump(ACTCData *tc)
+{
+    ACTC_INFO(actcDumpState(tc, stderr));
+    abort();
+}
+
+#endif /* defined(DEBUG) */
+
+int actcGetError(ACTCData *tc)
+{
+    int error = tc->Error;
+    tc->Error = ACTC_NO_ERROR;
+    return error;
+}
+
+static void *reallocAndAppend(void **ptr, unsigned int *itemCount, size_t itemBytes,
+    void *append)
+{
+    void *t;
+
+    t = realloc(*ptr, itemBytes * (*itemCount + 1));
+    if(t == NULL)
+	return NULL;
+    *ptr = t;
+
+    memcpy((unsigned char *)*ptr + *itemCount * itemBytes, append, itemBytes);
+    (*itemCount) += 1;
+
+    return *ptr;
+}
+
+/*
+ * Call only during input; changes vertices' valences and does not
+ * fix the bins that are ordered by vertex valence.  (It's usually cheaper
+ * to traverse the vertex list once after all are added, since that's
+ * linear in the NUMBER OF UNIQUE VERTEX INDICES, which is almost always
+ * going to be less than the number of vertices.)
+ */
+static int incVertexValence(ACTCData *tc, unsigned int v, ACTCVertex **found)
+{
+    ACTCVertex *vertex;
+
+    if(tc->UsingStaticVerts) {
+        vertex = &tc->StaticVerts[v];
+	vertex->Count++;
+	if(vertex->Count == 1) {
+	    vertex->V = v;
+	    tc->VertexCount++;
+	}
+    } else {
+	if(tableRetrieve(v, tc->Vertices, (void **)&vertex) == 1) {
+	    if(vertex->V != v) {
+		ACTC_DEBUG(
+		    fprintf(stderr, "ACTC::incVertexValence : Got vertex %d when "
+			"looking for vertex %d?!?\n", vertex->V, v);
+		    abortWithOptionalDump(tc);
+		)
+		return tc->Error = ACTC_DATABASE_CORRUPT;
+	    }
+	    vertex->Count++;
+	} else {
+	    chartedSetLabel("new Vertex");
+	    vertex = (ACTCVertex *)malloc(sizeof(ACTCVertex));
+	    vertex->V = v;
+	    vertex->Count = 1;
+	    vertex->Edges = NULL;
+	    vertex->EdgeCount = 0;
+	    if(tableInsert(v, tc->Vertices, vertex) == 0) {
+		ACTC_DEBUG(fprintf(stderr, "ACTC::incVertexValence : Failed "
+		    "to insert vertex into table\n");)
+		return tc->Error = ACTC_ALLOC_FAILED;
+	    }
+	    tc->VertexCount++;
+	}
+    }
+    if(vertex->Count > tc->CurMaxVertValence)
+	tc->CurMaxVertValence = vertex->Count;
+
+    *found = vertex;
+
+    return ACTC_NO_ERROR;
+}
+
+static int decVertexValence(ACTCData *tc, ACTCVertex **vptr)
+{
+    ACTCVertex *v = *vptr;
+
+    v->Count--;
+    if(v->Count < 0) {
+	ACTC_DEBUG(
+	    fprintf(stderr, "ACTC::decVertexValence : Valence went "
+		"negative?!?\n");
+	    abortWithOptionalDump(tc);
+	)
+	return tc->Error = ACTC_DATABASE_CORRUPT;
+    }
+
+    if(v->PointsToMe != NULL) {
+	*v->PointsToMe = v->Next;
+	if(v->Next != NULL)
+	    v->Next->PointsToMe = v->PointsToMe;
+	v->Next = NULL;
+    }
+
+    if(v->Count == 0) {
+	tc->VertexCount--;
+	if(v->Edges != NULL)
+	    free(v->Edges);
+        if(!tc->UsingStaticVerts) {
+	    tableRemove(v->V, tc->Vertices, NULL);
+	    free(v);
+	}
+	*vptr = NULL;
+    } else {
+	if(tc->VertexBins != NULL) {
+	    v->Next = tc->VertexBins[v->Count];
+	    v->PointsToMe = &tc->VertexBins[v->Count];
+	    if(v->Next != NULL)
+		v->Next->PointsToMe = &v->Next;
+	    tc->VertexBins[v->Count] = v;
+	    if(v->Count < tc->CurMinVertValence)
+		tc->CurMinVertValence = v->Count;
+	}
+    }
+
+    return ACTC_NO_ERROR;
+}
+
+static int findNextFanVertex(ACTCData *tc, ACTCVertex **vert)
+{
+    if(tc->CurMaxVertValence < tc->MinFanVerts) {
+	return ACTC_NO_MATCHING_VERT;
+    }
+    while(tc->VertexBins[tc->CurMaxVertValence] == NULL) {
+	tc->CurMaxVertValence--;
+	if(tc->CurMaxVertValence < tc->CurMinVertValence) {
+	    if(tc->VertexCount > 0) {
+		ACTC_DEBUG(fprintf(stderr, "tc::findNextFanVertex : no more "
+		    "vertices in bins but VertexCount > 0\n");)
+		return tc->Error = ACTC_DATABASE_CORRUPT;
+	    }
+	    return ACTC_NO_MATCHING_VERT;
+	}
+    }
+    *vert = tc->VertexBins[tc->CurMaxVertValence];
+    return ACTC_NO_ERROR;
+}
+
+static int findNextStripVertex(ACTCData *tc, ACTCVertex **vert)
+{
+    while(tc->VertexBins[tc->CurMinVertValence] == NULL) {
+	tc->CurMinVertValence++;
+	if(tc->CurMinVertValence > tc->CurMaxVertValence) {
+	    if(tc->VertexCount > 0) {
+		ACTC_DEBUG(fprintf(stderr, "tc::findNextStripVertex : no more "
+		    "vertices in bins but VertexCount > 0\n");)
+		return tc->Error = ACTC_DATABASE_CORRUPT;
+	    }
+	    return ACTC_NO_MATCHING_VERT;
+	}
+    }
+    *vert = tc->VertexBins[tc->CurMinVertValence];
+    return ACTC_NO_ERROR;
+}
+
+int actcGetIsDuringInput(ACTCData *tc) {
+    return tc->IsInputting;
+}
+
+int actcBeginInput(ACTCData *tc)
+{
+    if(tc->IsOutputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcBeginInput : called within "
+	    "BeginOutput/EndOutput\n");)
+	return tc->Error = ACTC_DURING_INPUT;
+    }
+
+    if(tc->IsInputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcBeginInput : called within "
+	    "BeginInput/EndInput\n");)
+	return tc->Error = ACTC_DURING_INPUT;
+    }
+
+    tc->IsInputting = 1;
+    tc->CurMaxVertValence = 0;
+
+    if(tc->MaxInputVert < MAX_STATIC_VERTS - 1) {
+	size_t byteCount;
+	tc->UsingStaticVerts = 1;
+	tc->VertRange = tc->MaxInputVert + 1;
+	byteCount = sizeof(ACTCVertex) * tc->VertRange;
+	chartedSetLabel("static verts");
+	tc->StaticVerts = (ACTCVertex *)calloc(sizeof(ACTCVertex), tc->VertRange);
+	if(tc->StaticVerts == NULL) {
+	    ACTC_INFO(printf("Couldn't allocate static %d vert block of %u "
+		"bytes\n", tc->VertRange, byteCount);)
+	    tc->UsingStaticVerts = 0;
+	}
+    } else
+	tc->UsingStaticVerts = 0;
+
+    return ACTC_NO_ERROR;
+}
+
+int actcEndInput(ACTCData *tc)
+{
+    if(tc->IsOutputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcEndInput : called within "
+	    "BeginOutput/EndOutput\n");)
+	return tc->Error = ACTC_DURING_OUTPUT;
+    }
+
+    if(!tc->IsInputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcEndInput : called outside "
+	    "BeginInput/EndInput\n");)
+	return tc->Error = ACTC_IDLE;
+    }
+
+    tc->IsInputting = 0;
+
+    return ACTC_NO_ERROR;
+}
+
+int actcGetIsDuringOutput(ACTCData *tc) {
+    return tc->IsOutputting;
+}
+
+int actcBeginOutput(ACTCData *tc)
+{
+    ACTCVertex *v;
+    int i;
+
+    if(tc->IsInputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcBeginOutput : called within "
+	    "BeginInput/EndInput\n");)
+	return tc->Error = ACTC_DURING_INPUT;
+    }
+
+    if(tc->IsOutputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcBeginOutput : called within "
+	    "BeginOutput/EndOutput\n");)
+	return tc->Error = ACTC_DURING_OUTPUT;
+    }
+
+    tc->IsOutputting = 1;
+
+    tc->CurMinVertValence = INT_MAX;
+    chartedSetLabel("vertex bins");
+    tc->VertexBins = (ACTCVertex **)calloc(sizeof(ACTCVertex *), tc->CurMaxVertValence + 1);
+    if(tc->VertexBins == NULL) {
+	ACTC_DEBUG(fprintf(stderr, "actcBeginOutput : couldn't allocate %d bytes "
+	    "for Vertex Bins\n",
+	    sizeof(ACTCVertex *) * tc->CurMaxVertValence);)
+	return tc->Error = ACTC_ALLOC_FAILED;
+    }
+
+    if(tc->UsingStaticVerts) {
+        double edgeTotal;
+	for(i = 0; i < tc->VertRange; i++) {
+	    v = &tc->StaticVerts[i];
+	    if(v->Count > 0) {
+		v->Next = tc->VertexBins[v->Count];
+		v->PointsToMe = &tc->VertexBins[v->Count];
+		tc->VertexBins[v->Count] = v;
+		if(v->Next != NULL)
+		    v->Next->PointsToMe = &v->Next;
+		if(v->Count < tc->CurMinVertValence)
+		    tc->CurMinVertValence = v->Count;
+		edgeTotal += v->EdgeCount;
+	    }
+	}
+    } else {
+	tableResetIterator(tc->VertexIterator);
+	for(i = 0; i < tc->VertexCount; i++) {
+	    if(tableIterate(tc->Vertices, tc->VertexIterator, NULL, (void **)&v)
+		== 0) {
+		ACTC_DEBUG(fprintf(stderr, "actcBeginOutput : fewer vertices in "
+		    "the table than we expected!\n");)
+		return tc->Error = ACTC_DATABASE_CORRUPT;
+	    }
+	    v->Next = tc->VertexBins[v->Count];
+	    v->PointsToMe = &tc->VertexBins[v->Count];
+	    tc->VertexBins[v->Count] = v;
+	    if(v->Next != NULL)
+		v->Next->PointsToMe = &v->Next;
+	    if(v->Count < tc->CurMinVertValence)
+		tc->CurMinVertValence = v->Count;
+	}
+    }
+
+    return ACTC_NO_ERROR;
+}
+
+int actcEndOutput(ACTCData *tc)
+{
+    if(tc->IsInputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcEndOutput : called within "
+	    "BeginInput/EndInput\n");)
+	return tc->Error = ACTC_DURING_INPUT;
+    }
+
+    if(!tc->IsOutputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcEndOutput : called outside "
+	    "BeginOutput/EndOutput\n");)
+	return tc->Error = ACTC_IDLE;
+    }
+
+    tc->IsOutputting = 0;
+
+    if(tc->UsingStaticVerts) {
+	free(tc->StaticVerts);
+	tc->StaticVerts = NULL;
+	tc->UsingStaticVerts = 0;
+    }
+
+    free(tc->VertexBins);
+    tc->VertexBins = NULL;
+
+    return ACTC_NO_ERROR;
+}
+
+ACTCData *actcNew(void)
+{
+    ACTCData *tc;
+#if defined(DEBUG) || defined(INFO)
+    static int didPrintVersion = 0;
+
+    if(!didPrintVersion) {
+	int verMinor, verMajor;
+	didPrintVersion = 1;
+
+        actcGetParami(tc, ACTC_MAJOR_VERSION, &verMajor);
+        actcGetParami(tc, ACTC_MINOR_VERSION, &verMinor);
+	fprintf(stderr, "TC Version %d.%d\n", verMajor, verMinor);
+    }
+#endif /* defined(DEBUG) || defined(INFO) */
+
+    chartedSetLabel("the tc struct");
+    tc = (ACTCData *)calloc(sizeof(*tc), 1);
+
+    if(tc == NULL) {
+	ACTC_DEBUG(fprintf(stderr, "actcNew : couldn't allocate %d bytes "
+	    "for new ACTCData\n", sizeof(*tc));)
+	return NULL;
+    }
+
+    tc->Vertices = tableNew();
+    tc->VertexIterator = tableNewIterator();
+
+    tc->MinFanVerts = INT_MAX;
+    tc->MaxPrimVerts = INT_MAX;
+    tc->MaxInputVert = INT_MAX;
+    tc->MaxEdgeShare = INT_MAX;
+    tc->MaxVertShare = INT_MAX;
+    tc->HonorWinding = 1;
+    /* seed = 0 handled by calloc */
+    /* XXX grantham 20000615 - seed ignored for now */
+
+    return tc;
+}
+
+static size_t allocatedForTriangles(ACTCEdge *e)
+{
+    return sizeof(ACTCTriangle) * e->TriangleCount;
+}
+
+static size_t allocatedForEdges(ACTCVertex *vert)
+{
+    int i;
+    size_t size;
+
+    size = sizeof(ACTCEdge) * vert->EdgeCount;
+    for(i = 0; i < vert->EdgeCount; i++) {
+	size += allocatedForTriangles(&vert->Edges[i]);
+    }
+    return size;
+}
+
+static size_t allocatedForVertices(ACTCData *tc)
+{
+    int i;
+    int size;
+    ACTCVertex *v;
+
+    if(!tc->UsingStaticVerts)
+        tableResetIterator(tc->VertexIterator);
+
+    if(tc->UsingStaticVerts) {
+        size = tc->VertRange * sizeof(ACTCVertex);
+        for(i = 0; i < tc->VertRange; i++) {
+	    v = &tc->StaticVerts[i];
+	    if(v->Count > 0)
+	        size += allocatedForEdges(v);
+	}
+    } else {
+	for(i = 0; i < tc->VertexCount; i++) {
+	    tableIterate(tc->Vertices, tc->VertexIterator, NULL, (void **)&v);
+	    size += allocatedForEdges(v);
+	}
+    }
+    return size;
+}
+
+int actcGetMemoryAllocation(ACTCData *tc, size_t *bytesAllocated)
+{
+    size_t tableBytes;
+
+    tableGetStats(tc->Vertices, NULL, NULL, &tableBytes);
+    *bytesAllocated = sizeof(ACTCData);
+    *bytesAllocated += tableBytes;
+    *bytesAllocated += allocatedForVertices(tc); /* recurses */
+
+    return ACTC_NO_ERROR;
+}
+
+static void freeVertex(void *p)
+{
+    ACTCVertex *v = (ACTCVertex *)p;
+    int i;
+
+    for(i = 0; i < v->EdgeCount; i++)
+        free(v->Edges[i].Triangles);
+    free(v->Edges);
+    free(v);
+}
+
+int actcMakeEmpty(ACTCData *tc)
+{
+    tc->VertexCount = 0;
+    if(!tc->UsingStaticVerts)
+        tableDelete(tc->Vertices, freeVertex);
+    if(tc->VertexBins != NULL) {
+        free(tc->VertexBins);
+	tc->VertexBins = NULL;
+    }
+    tc->IsOutputting = 0;
+    tc->IsInputting = 0;
+    return ACTC_NO_ERROR;
+}
+
+void actcDelete(ACTCData *tc)
+{
+    actcMakeEmpty(tc);
+    free(tc->VertexIterator);
+    free(tc->Vertices);
+    free(tc);
+}
+
+int actcParami(ACTCData *tc, int param, int value)
+{
+    if(tc->IsInputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcParami : within BeginInput/"
+	    "EndInput\n");)
+	return tc->Error = ACTC_DURING_INPUT;
+    }
+    if(tc->IsOutputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcParami : within BeginOutput/"
+	    "EndOutput\n");)
+	return tc->Error = ACTC_DURING_OUTPUT;
+    }
+    switch(param) {
+	case ACTC_OUT_MIN_FAN_VERTS:
+	    tc->MinFanVerts = value;
+	    break;
+
+	case ACTC_IN_MAX_VERT:
+	    if(value < tc->MinInputVert) {
+		ACTC_DEBUG(fprintf(stderr, "actcParami : tried to set "
+		    "MAX_INPUT_VERT to %d, less than MIN_INPUT_VERT (%d)\n",
+		    value, tc->MinInputVert);)
+		return tc->Error = ACTC_INVALID_VALUE;
+	    }
+	    tc->MaxInputVert = value;
+	    break;
+
+	case ACTC_IN_MIN_VERT:
+	    if(value > tc->MaxInputVert) {
+		ACTC_DEBUG(fprintf(stderr, "actcParami : tried to set "
+		    "MIN_INPUT_VERT to %d, greater than MAX_INPUT_VERT (%d)\n",
+		    value, tc->MaxInputVert);)
+		return tc->Error = ACTC_INVALID_VALUE;
+	    }
+	    tc->MinInputVert = value;
+	    break;
+
+	case ACTC_IN_MAX_EDGE_SHARING:
+	    tc->MaxEdgeShare = value;
+	    break;
+
+	case ACTC_IN_MAX_VERT_SHARING:
+	    tc->MaxVertShare = value;
+	    break;
+
+	case ACTC_OUT_HONOR_WINDING:
+	    tc->HonorWinding = value;
+	    break;
+
+	case ACTC_OUT_MAX_PRIM_VERTS:
+	    if(value < 3) {
+		ACTC_DEBUG(fprintf(stderr, "actcParami : tried to set "
+		    "MAX_PRIM_VERTS to %d (needed to be 3 or more)\n", value);)
+		return tc->Error = ACTC_INVALID_VALUE;
+	    }
+	    tc->MaxPrimVerts = value;
+	    break;
+
+    }
+    return ACTC_NO_ERROR;
+}
+
+int actcParamu(ACTCData *tc, int param, unsigned int value)
+{
+    /*
+     * XXX - yes, this is questionable, but I consulted industry
+     * experts and we agreed that most common behavior is to copy the
+     * bits directly, which is what I want.
+     */
+    return actcParami(tc, param, (int)value);
+}
+
+int actcGetParami(ACTCData *tc, int param, int *value)
+{
+    switch(param) {
+	case ACTC_MAJOR_VERSION:
+	    *value = 1;
+	    break;
+
+	case ACTC_MINOR_VERSION:
+	    *value = 1;
+	    break;
+
+	case ACTC_IN_MAX_VERT:
+	    *value = tc->MaxInputVert;
+	    break;
+
+	case ACTC_IN_MIN_VERT:
+	    *value = tc->MinInputVert;
+	    break;
+
+	case ACTC_IN_MAX_EDGE_SHARING:
+	    *value = tc->MaxEdgeShare;
+	    break;
+
+	case ACTC_IN_MAX_VERT_SHARING:
+	    *value = tc->MaxVertShare;
+	    break;
+
+	case ACTC_OUT_MIN_FAN_VERTS:
+	    *value = tc->MinFanVerts;
+	    break;
+
+	case ACTC_OUT_HONOR_WINDING:
+	    *value = tc->HonorWinding;
+	    break;
+
+	case ACTC_OUT_MAX_PRIM_VERTS:
+	    *value = tc->MaxPrimVerts;
+	    break;
+
+	default:
+	    *value = 0;
+	    return tc->Error = ACTC_INVALID_VALUE;
+	    /* break; */
+    }
+    return ACTC_NO_ERROR;
+}
+
+int actcGetParamu(ACTCData *tc, int param, unsigned int *value)
+{
+    return actcGetParami(tc, param, (int *)value);
+}
+
+static int mapEdgeTriangle(ACTCData *tc, ACTCEdge *edge, ACTCVertex *v3)
+{
+    ACTCTriangle tmp;
+    void *r;
+
+    tmp.FinalVert = v3;
+    chartedSetLabel("triangle list");
+    r = reallocAndAppend((void **)&edge->Triangles, (unsigned int*)&edge->TriangleCount,
+        sizeof(tmp), &tmp);
+    if(r == NULL) {
+	ACTC_DEBUG(fprintf(stderr, "ACTC::mapEdgeTriangle : Couldn't allocate "
+	    "%d bytes for triangles\n", sizeof(tmp) *
+	    (edge->TriangleCount + 1));)
+	return tc->Error = ACTC_ALLOC_FAILED;
+    }
+
+    return ACTC_NO_ERROR;
+}
+
+static int unmapEdgeTriangle(ACTCData *tc, ACTCEdge *edge, ACTCVertex *v3)
+{
+    int i;
+
+    for(i = 0; i < edge->TriangleCount; i++)
+	if(edge->Triangles[i].FinalVert == v3)
+	    break;
+
+    if(i == edge->TriangleCount) {
+	ACTC_DEBUG(
+	    fprintf(stderr, "ACTC::unmapEdgeTriangle : Couldn't find third vertex"
+	        " from edge in order to delete it?!?\n");
+	    abortWithOptionalDump(tc);
+	)
+	return tc->Error = ACTC_DATABASE_CORRUPT;
+    }
+
+    edge->Triangles[i] = edge->Triangles[edge->TriangleCount - 1];
+    edge->TriangleCount --;
+
+    return ACTC_NO_ERROR;
+}
+
+static int mapVertexEdge(ACTCData *tc, ACTCVertex *v1, ACTCVertex *v2, ACTCEdge **edge)
+{
+    unsigned int i;
+    ACTCEdge tmp;
+    void *r;
+
+    for(i = 0; i < v1->EdgeCount; i++)
+        if(v1->Edges[i].V2 == v2) {
+	    v1->Edges[i].Count++;
+	    break;
+	}
+
+    if(i == v1->EdgeCount) {
+
+	tmp.V2 = v2;
+	tmp.Count = 1;
+	tmp.Triangles = NULL;
+	tmp.TriangleCount = 0;
+
+	chartedSetLabel("vert-to-edge mapping");
+        r = reallocAndAppend((void **)&v1->Edges, (unsigned int*)&v1->EdgeCount,
+	    sizeof(tmp), &tmp);
+	if(r == NULL) {
+	    ACTC_DEBUG(fprintf(stderr, "ACTC::mapVertexEdge : Couldn't reallocate "
+	        "to %d bytes for vertex's edge list\n", sizeof(tmp) *
+		v1->EdgeCount);)
+	    return tc->Error = ACTC_ALLOC_FAILED;
+	}
+    }
+    *edge = &v1->Edges[i];
+
+    return ACTC_NO_ERROR;
+}
+
+static int unmapVertexEdge(ACTCData *tc, ACTCVertex *v1, ACTCVertex *v2)
+{
+    int i;
+
+    for(i = 0; i < v1->EdgeCount; i++)
+	if(v1->Edges[i].V2 == v2)
+	    break;
+
+    if(i == v1->EdgeCount) {
+	ACTC_DEBUG(
+	    fprintf(stderr, "ACTC::unmapVertexEdge : Couldn't find edge %d,%d"
+	        " from vertex in order to unmap it?!?\n", v1->V, v2->V);
+	    abortWithOptionalDump(tc);
+	)
+	return tc->Error = ACTC_DATABASE_CORRUPT;
+    }
+
+    v1->Edges[i].Count --;
+    if(v1->Edges[i].Count == 0) {
+        if(v1->Edges[i].Triangles != NULL)
+	    free(v1->Edges[i].Triangles);
+	v1->Edges[i] = v1->Edges[v1->EdgeCount - 1];
+	v1->EdgeCount --;
+    }
+
+    return ACTC_NO_ERROR;
+}
+
+int actcAddTriangle(ACTCData *tc, unsigned int v1, unsigned int v2, unsigned int v3)
+{
+    ACTCVertex *vertexRec1;
+    ACTCVertex *vertexRec2;
+    ACTCVertex *vertexRec3;
+
+    ACTCEdge *edge12;
+    ACTCEdge *edge23;
+    ACTCEdge *edge31;
+
+    if(tc->IsOutputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcAddTriangle : inside "
+	    "BeginOutput/EndOutput\n");)
+	return tc->Error = ACTC_IDLE;
+    }
+    if(!tc->IsInputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcAddTriangle : outside "
+	    "BeginInput/EndInput\n");)
+	return tc->Error = ACTC_DURING_INPUT;
+    }
+
+    if(incVertexValence(tc, v1, &vertexRec1) != ACTC_NO_ERROR) goto returnError1;
+    if(incVertexValence(tc, v2, &vertexRec2) != ACTC_NO_ERROR) goto free1;
+    if(incVertexValence(tc, v3, &vertexRec3) != ACTC_NO_ERROR) goto free2;
+
+    if(mapVertexEdge(tc, vertexRec1, vertexRec2, &edge12) != ACTC_NO_ERROR)
+        goto free3;
+    if(mapVertexEdge(tc, vertexRec2, vertexRec3, &edge23) != ACTC_NO_ERROR)
+        goto free4;
+    if(mapVertexEdge(tc, vertexRec3, vertexRec1, &edge31) != ACTC_NO_ERROR)
+        goto free5;
+
+    if(mapEdgeTriangle(tc, edge12, vertexRec3) != ACTC_NO_ERROR) goto free6;
+    if(mapEdgeTriangle(tc, edge23, vertexRec1) != ACTC_NO_ERROR) goto free7;
+    if(mapEdgeTriangle(tc, edge31, vertexRec2) != ACTC_NO_ERROR) goto free8;
+
+    return ACTC_NO_ERROR;
+
+    /*
+     * XXX Unfortunately, while backing out during the following
+     * statements, we might encounter errors in the database which
+     * will not get returned properly to the caller; I take heart in
+     * the fact that if such an error occurs, TC is just a moment from
+     * core dumping anyway. XXX grantham 20000615
+     */
+
+free8:
+    unmapEdgeTriangle(tc, edge23, vertexRec1);
+free7:
+    unmapEdgeTriangle(tc, edge12, vertexRec3);
+free6:
+    unmapVertexEdge(tc, vertexRec3, vertexRec1);
+free5:
+    unmapVertexEdge(tc, vertexRec2, vertexRec3);
+free4:
+    unmapVertexEdge(tc, vertexRec1, vertexRec2);
+free3:
+    decVertexValence(tc, &vertexRec3);
+free2:
+    decVertexValence(tc, &vertexRec2);
+free1:
+    decVertexValence(tc, &vertexRec1);
+returnError1:
+    return tc->Error;
+}
+
+int actcStartNextPrim(ACTCData *tc, unsigned int *v1Return, unsigned int *v2Return)
+{
+    ACTCVertex *v1 = NULL;
+    ACTCVertex *v2 = NULL;
+    int findResult;
+
+    if(tc->IsInputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcStartNextPrim : within "
+	    "BeginInput/EndInput\n");)
+	return tc->Error = ACTC_DURING_INPUT;
+    }
+    if(!tc->IsOutputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcStartNextPrim : outside "
+	    "BeginOutput/EndOutput\n");)
+	return tc->Error = ACTC_IDLE;
+    }
+
+    findResult = findNextFanVertex(tc, &v1);
+    if(findResult == ACTC_NO_ERROR)
+	tc->PrimType = ACTC_PRIM_FAN;
+    else if(findResult != ACTC_NO_MATCHING_VERT) {
+	ACTC_DEBUG(fprintf(stderr, "actcStartNextPrim : internal "
+	    "error finding next appropriate vertex\n");)
+	return tc->Error = findResult;
+    } else {
+	findResult = findNextStripVertex(tc, &v1);
+	if(findResult != ACTC_NO_ERROR && findResult != ACTC_NO_MATCHING_VERT) {
+	    ACTC_DEBUG(fprintf(stderr, "actcStartNextPrim : internal "
+		"error finding next appropriate vertex\n");)
+	    return tc->Error = findResult;
+	}
+	tc->PrimType = ACTC_PRIM_STRIP;
+    }
+
+    if(findResult == ACTC_NO_MATCHING_VERT) {
+	*v1Return = -1;
+	*v2Return = -1;
+	return tc->Error = ACTC_DATABASE_EMPTY;
+    }
+
+    v2 = v1->Edges[0].V2;
+
+    tc->CurWindOrder = ACTC_FWD_ORDER;
+    tc->VerticesSoFar = 2;
+
+    tc->V1 = v1;
+    tc->V2 = v2;
+
+    *v1Return = v1->V;
+    *v2Return = v2->V;
+
+    ACTC_INFO(printf("starting with edge %u, %u\n", tc->V1->V, tc->V2->V);)
+
+    return tc->PrimType;
+}
+
+static int findEdge(ACTCVertex *v1, ACTCVertex *v2, ACTCEdge **edge)
+{
+    int i;
+
+    for(i = 0; i < v1->EdgeCount; i++)
+        if(v1->Edges[i].V2 == v2) {
+	    *edge = &v1->Edges[i];
+	    return 1;
+	}
+    return 0;
+}
+
+int unmapEdgeTriangleByVerts(ACTCData *tc, ACTCVertex *v1, ACTCVertex *v2,
+    ACTCVertex *v3)
+{
+    ACTCEdge *e;
+
+    ACTC_CHECK(findEdge(v1, v2, &e));
+    unmapEdgeTriangle(tc, e, v3);
+    return ACTC_NO_ERROR;
+}
+
+int actcGetNextVert(ACTCData *tc, unsigned int *vertReturn)
+{
+    ACTCEdge *edge;
+    int wasEdgeFound = 0;
+    ACTCVertex *thirdVertex;
+    int wasFoundReversed;
+
+    if(tc->IsInputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcGetNextVert : within BeginInput/"
+	    "EndInput\n");)
+	return tc->Error = ACTC_DURING_INPUT;
+    }
+    if(!tc->IsOutputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcGetNextVert : outside BeginOutput/"
+	    "EndOutput\n");)
+	return tc->Error = ACTC_IDLE;
+    }
+    if(tc->PrimType == -1) {
+	ACTC_DEBUG(fprintf(stderr, "actcGetNextVert : Asked for next vertex "
+	    "without a primitive (got last\n    vertex already?)\n");)
+	return tc->Error = ACTC_INVALID_VALUE;
+    }
+
+    if(tc->VerticesSoFar >= tc->MaxPrimVerts) {
+	tc->PrimType = -1;
+	return tc->Error = ACTC_PRIM_COMPLETE;
+    }
+
+    if(tc->V1 == NULL || tc->V2 == NULL) {
+	tc->PrimType = -1;
+	return tc->Error = ACTC_PRIM_COMPLETE;
+    }
+
+    ACTC_INFO(printf("looking for edge %u, %u\n", tc->V1->V, tc->V2->V);)
+
+    wasFoundReversed = 0;
+
+    if(findEdge(tc->V1, tc->V2, &edge) != 0) {
+	wasEdgeFound = 1;
+    } else if(!tc->HonorWinding) {
+	wasFoundReversed = 1;
+	if(findEdge(tc->V2, tc->V1, &edge) != 0) {
+	    wasEdgeFound = 1;
+	}
+    }
+
+    if(!wasEdgeFound) {
+	tc->PrimType = -1;
+	return tc->Error = ACTC_PRIM_COMPLETE;
+    }
+
+    thirdVertex = edge->Triangles[edge->TriangleCount - 1].FinalVert;
+
+    ACTC_INFO(printf("third vertex = %u\n", thirdVertex->V);)
+    *vertReturn = thirdVertex->V;
+
+    if(wasFoundReversed) {
+	ACTC_CHECK(unmapEdgeTriangle(tc, edge, thirdVertex));
+	ACTC_CHECK(unmapEdgeTriangleByVerts(tc, tc->V1, thirdVertex, tc->V2));
+	ACTC_CHECK(unmapEdgeTriangleByVerts(tc, thirdVertex, tc->V2, tc->V1));
+	ACTC_CHECK(unmapVertexEdge(tc, tc->V2, tc->V1));
+	ACTC_CHECK(unmapVertexEdge(tc, tc->V1, thirdVertex));
+	ACTC_CHECK(unmapVertexEdge(tc, thirdVertex, tc->V2));
+    } else {
+	ACTC_CHECK(unmapEdgeTriangle(tc, edge, thirdVertex));
+	ACTC_CHECK(unmapEdgeTriangleByVerts(tc, tc->V2, thirdVertex, tc->V1));
+	ACTC_CHECK(unmapEdgeTriangleByVerts(tc, thirdVertex, tc->V1, tc->V2));
+	ACTC_CHECK(unmapVertexEdge(tc, tc->V1, tc->V2));
+	ACTC_CHECK(unmapVertexEdge(tc, tc->V2, thirdVertex));
+	ACTC_CHECK(unmapVertexEdge(tc, thirdVertex, tc->V1));
+    }
+    ACTC_CHECK(decVertexValence(tc, &tc->V1));
+    ACTC_CHECK(decVertexValence(tc, &tc->V2));
+    ACTC_CHECK(decVertexValence(tc, &thirdVertex));
+
+    if(tc->PrimType == ACTC_PRIM_FAN) {
+        tc->V2 = thirdVertex;
+    } else /* PRIM_STRIP */ {
+	if(tc->CurWindOrder == ACTC_FWD_ORDER)
+	    tc->V1 = thirdVertex;
+	else
+	    tc->V2 = thirdVertex;
+	tc->CurWindOrder = !tc->CurWindOrder;
+    }
+
+    tc->VerticesSoFar++;
+    return ACTC_NO_ERROR;
+}
+
+int actcTrianglesToPrimitives(ACTCData *tc, int triangleCount,
+    unsigned int (*triangles)[3], int primTypes[], int primLengths[], unsigned int vertices[],
+    int maxBatchSize)
+{
+    int r;
+    int curTriangle;
+    int curPrimitive;
+    unsigned int curVertex;
+    int prim;
+    unsigned int v1, v2, v3;
+    int lastPrim;
+    int passesWithoutPrims;
+    int trisSoFar;
+
+    if(tc->IsInputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcTrianglesToPrimitives : within BeginInput/"
+	    "EndInput\n");)
+	return tc->Error = ACTC_DURING_INPUT;
+    }
+    if(tc->IsOutputting) {
+	ACTC_DEBUG(fprintf(stderr, "actcTrianglesToPrimitives : within"
+	    "BeginOutput/EndOutput\n");)
+	return tc->Error = ACTC_DURING_OUTPUT;
+    }
+    curTriangle = 0;
+    curPrimitive = 0;
+    curVertex = 0;
+    passesWithoutPrims = 0;
+
+    actcMakeEmpty(tc);
+
+    ACTC_CHECK(actcBeginInput(tc));
+    trisSoFar = 0;
+    while(curTriangle < triangleCount) {
+	r = actcAddTriangle(tc, triangles[curTriangle][0],
+	    triangles[curTriangle][1], triangles[curTriangle][2]);
+	trisSoFar++;
+	curTriangle++;
+	if((trisSoFar >= maxBatchSize) ||
+	    (r == ACTC_ALLOC_FAILED && curTriangle != triangleCount) ||
+	    (r == ACTC_NO_ERROR && curTriangle == triangleCount)) {
+
+	    /* drain what we got */
+	    trisSoFar = 0;
+	    ACTC_CHECK(actcEndInput(tc));
+	    ACTC_CHECK(actcBeginOutput(tc));
+	    lastPrim = curPrimitive;
+	    while((prim = actcStartNextPrim(tc, &v1, &v2)) != ACTC_DATABASE_EMPTY) {
+		ACTC_CHECK(prim);
+		primTypes[curPrimitive] = prim;
+		primLengths[curPrimitive] = 2;
+		vertices[curVertex++] = v1;
+		vertices[curVertex++] = v2;
+		while((r = actcGetNextVert(tc, &v3)) != ACTC_PRIM_COMPLETE) {
+		    ACTC_CHECK(r);
+		    vertices[curVertex++] = v3;
+		    primLengths[curPrimitive]++;
+		}
+		curPrimitive++;
+	    }
+	    ACTC_CHECK(actcEndOutput(tc));
+	    if(r == ACTC_ALLOC_FAILED && curPrimitive == lastPrim) {
+	        if(passesWithoutPrims == 0) {
+		    /* not enough memory to add a triangle and */
+		    /* nothing in the database, better free everything */
+		    /* and try again */
+		    actcMakeEmpty(tc);
+		} else {
+		    /* cleaned up and STILL couldn't get a triangle in; */
+		    /* give up */
+		    return tc->Error = ACTC_ALLOC_FAILED;
+		}
+		passesWithoutPrims++;
+	    }
+	    ACTC_CHECK(actcBeginInput(tc));
+	} else
+	    ACTC_CHECK(r);
+	if(r == ACTC_ALLOC_FAILED)
+	    curTriangle--;
+    }
+    ACTC_CHECK(actcEndInput(tc));
+
+    actcMakeEmpty(tc);
+
+    return curPrimitive;
+}
+
+/* vi:tabstop=8
+ */
Index: branches/network/src/lib/graphics/importer/tc.h
===================================================================
--- branches/network/src/lib/graphics/importer/tc.h	(revision 6636)
+++ branches/network/src/lib/graphics/importer/tc.h	(revision 6636)
@@ -0,0 +1,77 @@
+/*
+ * $Header: /home/grantham/cvsroot/projects/modules/tc/tc.h,v 1.14 2000/10/03 07:19:20 grantham Exp $
+ */
+
+#if !defined(_ACTC_H_)
+#define _ACTC_H_
+
+#include <sys/types.h>
+
+typedef struct _ACTCData ACTCData;
+
+/*
+    Abbreviated:
+        vertex          vert
+        primitive       prim
+        maximum         max
+        minimum         min
+        parameter       param
+ */
+
+#define ACTC_NO_ERROR                   0
+#define ACTC_ALLOC_FAILED               -0x2000
+#define ACTC_DURING_INPUT               -0x2001
+#define ACTC_DURING_OUTPUT              -0x2002
+#define ACTC_IDLE                       -0x2003
+#define ACTC_INVALID_VALUE              -0x2004
+#define ACTC_DATABASE_EMPTY             -0x2005
+#define ACTC_DATABASE_CORRUPT           -0x2006
+#define ACTC_PRIM_COMPLETE              -0x2007
+
+#define ACTC_OUT_MIN_FAN_VERTS          0x1000
+#define ACTC_OUT_HONOR_WINDING          0x1001
+#define ACTC_OUT_MAX_PRIM_VERTS         0x1004
+#define ACTC_IN_MIN_VERT                0x1005
+#define ACTC_IN_MAX_VERT                0x1006
+#define ACTC_IN_MAX_VERT_SHARING        0x1007
+#define ACTC_IN_MAX_EDGE_SHARING        0x1008
+#define ACTC_MINOR_VERSION              0x1009
+#define ACTC_MAJOR_VERSION              0x1010
+
+#define ACTC_PRIM_FAN                   0x2000
+#define ACTC_PRIM_STRIP                 0x2001
+
+#define ACTC_TRUE                       1
+#define ACTC_FALSE                      0
+
+ACTCData *actcNew(void);
+int actcParami(ACTCData *tc, int param, int value);
+int actcGetParami(ACTCData *tc, int param, int *value);
+int actcParamu(ACTCData *tc, int param, unsigned int value);
+int actcGetParamu(ACTCData *tc, int param, unsigned int *value);
+int actcGetError(ACTCData *tc);
+int actcMakeEmpty(ACTCData *tc);
+void actcDelete(ACTCData *tc);
+void actcDumpState(ACTCData *tc, FILE *fp);
+
+int actcBeginInput(ACTCData *tc);
+int actcGetIsDuringInput(ACTCData *tc);
+int actcAddTriangle(ACTCData *tc, unsigned int v1, unsigned int v2, unsigned int v3);
+int actcEndInput(ACTCData *tc);
+
+int actcBeginOutput(ACTCData *tc);
+int actcGetIsDuringOutput(ACTCData *tc);
+int actcStartNextPrim(ACTCData *tc, unsigned int *v1Return, unsigned int *v2Return);
+int actcGetNextVert(ACTCData *tc, unsigned int *vReturn);
+int actcEndOutput(ACTCData *tc);
+
+int actcGetMemoryAllocation(ACTCData *tc, size_t *bytesAllocated);
+
+int actcTrianglesToPrimitives(ACTCData *tc, int triangleCount,
+    unsigned int (*triangles)[3], int primTypes[], int primLengths[], unsigned int vertices[],
+    int maxBatchSize);
+
+#endif /* _ACTC_H_ */
+
+/* vi:tabstop=8
+ */
Index: branches/network/src/lib/graphics/importer/texture.cc
===================================================================
--- branches/network/src/lib/graphics/importer/texture.cc	(revision 6636)
+++ branches/network/src/lib/graphics/importer/texture.cc	(revision 6636)
@@ -0,0 +1,304 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "texture.h"
+
+#include "debug.h"
+#include "compiler.h"
+#include <math.h>
+
+// INCLUDING SDL_Image
+#ifdef HAVE_SDL_IMAGE_H
+#include <SDL_image.h>
+#else
+#include <SDL/SDL_image.h>
+#endif
+
+/**
+ *  Constructor for a Texture
+*/
+Texture::Texture(const char* imageName, GLenum target)
+{
+  this->setClassID(CL_TEXTURE, "Texture");
+
+  this->bAlpha = false;
+  this->texture = 0;
+  this->image = NULL;
+  this->priority = 0.5;
+
+  if (imageName != NULL)
+  {
+    this->setName(imageName);
+    this->loadImage(imageName, target);
+  }
+}
+
+
+/**
+ *  Destructor of a Texture
+
+   Frees Data, and deletes the textures from GL
+*/
+Texture::~Texture()
+{
+  if (this->texture != 0)
+    glDeleteTextures(1, &this->texture);
+  if (this->image != NULL)
+    SDL_FreeSurface(this->image);
+}
+
+
+/**
+ *  loads an Image from a file to a Texture
+ * @param imageName The image to load
+*/
+bool Texture::loadImage(const char* imageName, GLenum target)
+{
+  if (Texture::texturesEnabled)
+    {
+      if (this->image != NULL)
+        {
+          SDL_FreeSurface(this->image);
+          this->image = NULL;
+        }
+      if (this->texture != 0)
+        {
+          glDeleteTextures(1, &this->texture);
+          this->texture = 0;
+        }
+      if (imageName != NULL)
+        {
+          SDL_Surface* tmpSurf;
+          if (this->texture != 0 && glIsTexture(this->texture))
+            glDeleteTextures(1, &this->texture);
+          // load the new Image to memory
+          tmpSurf = IMG_Load(imageName);
+          if(tmpSurf != NULL)
+          {
+            PRINTF(4)("loading Image %s\n", imageName);
+            bool hasAlpha;
+            SDL_Surface* newSurf = this->prepareSurface(tmpSurf, hasAlpha);
+            if (newSurf != NULL)
+            {
+              this->setSurface(newSurf);
+              this->setAlpha(hasAlpha);
+              this->setTexture(Texture::loadTexToGL(newSurf, target));
+            }
+
+            SDL_FreeSurface(tmpSurf);
+            return true;
+          }
+          else
+            {
+              PRINTF(1)("IMG_Load: %s\n", IMG_GetError());
+              this->texture = 0;
+              return false;
+            }
+        }
+      else
+        {
+          PRINTF(2)("Image-Name not specified\n");
+          return false;
+        }
+    }
+  return false;
+}
+
+
+/**
+ * rebuilds the texture.
+ * reloads the Texture from Memory to OpenGL.
+ */
+bool Texture::rebuild()
+{
+  if (this->texture != 0)
+    {
+      if (glIsTexture(this->texture))
+        glDeleteTextures(1,&this->texture);
+      this->setTexture(0);
+    }
+
+  if (this->image != NULL)
+    {
+      PRINTF(3)("Reloading Texture of %s '%s'\n", this->getClassName(), this->getName());
+      this->setTexture(loadTexToGL(this->image));
+    }
+}
+
+
+/**
+ * set the surface this Texture handles
+ * @param newSurface the new Surface to set as the image for this Texture.
+ *
+ * This deletes the old version of the stored Texture,
+ * and sets the newly given Surface as current.
+ */
+bool Texture::setSurface(SDL_Surface* newSurface)
+{
+  if (this->image != NULL)
+    SDL_FreeSurface(this->image);
+
+  this->image = newSurface;
+
+  return (this->image != NULL);
+}
+
+
+bool Texture::texturesEnabled = true;
+
+/**
+ * enables, disables textures
+ * @param texturesEnabled true if the textures should be enabled
+ */
+void Texture::setTextureEnableState(bool texturesEnabled)
+{
+  Texture::texturesEnabled = texturesEnabled;
+}
+
+
+//////////////////////////////////////
+// UTILITY FUNCTIONALITY OF TEXTURE //
+//////////////////////////////////////
+/**
+ * converts surface to a new SDL_Surface, that is loadable by openGL
+ * @param surface the Surface to convert
+ * @param hasAlpha if the newly created Surface has an alpha channel, true is returned otherwise false.
+ * @returns a !!new!! Surface, that is loadable by openGL.
+ */
+SDL_Surface* Texture::prepareSurface(SDL_Surface* surface, bool& hasAlpha) const
+{
+  PRINTF(4)("Loading texture to OpenGL-Environment.\n");
+
+  SDL_Surface* retSurface;
+  SDL_Rect area;
+  Uint32 saved_flags;
+  Uint8  saved_alpha;
+
+  hasAlpha = false;
+  retSurface = SDL_CreateRGBSurface(SDL_SWSURFACE,
+                                    surface->w, surface->h,
+                                    32,
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
+                               0x000000FF,
+                               0x0000FF00,
+                               0x00FF0000,
+                               0xFF000000
+#else
+                               0xFF000000,
+                               0x00FF0000,
+                               0x0000FF00,
+                               0x000000FF
+#endif
+                                   );
+  if ( retSurface == NULL )
+  {
+    return NULL;
+  }
+
+  /* Save the alpha blending attributes */
+  saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
+  saved_alpha = surface->format->alpha;
+  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
+    SDL_SetAlpha(surface, 0, 0);
+  }
+
+  /* Copy the surface into the GL texture image */
+  area.x = 0;
+  area.y = 0;
+  area.w = surface->w;
+  area.h = surface->h;
+  SDL_BlitSurface(surface, &area, retSurface, &area);
+
+  /* Restore the alpha blending attributes */
+  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA )
+  {
+    SDL_SetAlpha(surface, saved_flags | SDL_OPENGL, saved_alpha);
+    hasAlpha = true;
+  }
+
+  return (retSurface);
+}
+
+
+/**
+ *  Loads a Texture to the openGL-environment.
+ * @param surface the Image to load to openGL
+ * @returns The ID of the texture.
+ */
+GLuint Texture::loadTexToGL (const SDL_Surface* surface, GLenum target) const
+{
+//   if (this->texture != 0 && glIsTexture(this->texture))
+//     glDeleteTextures(1, &this->texture);
+//   this->texture = 0;
+
+  int      errorCode = 0;           //!< the error code for the texture loading functions
+  GLuint   texture;                 //!< the OpenGL texture handle
+  int      mipmapLevel = 0;         //!< the maximum mipmap level for this texture
+  int      mipmapWidth = 0;         //!< the width of the mipmap
+  int      mipmapHight = 0;         //!< the height of the mipmap
+
+
+  if (surface == NULL)
+    return 0;
+
+  /* Create an OpenGL texture for the image */
+  glGenTextures(1, &texture);
+  glBindTexture(target, texture);
+
+  glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_REPEAT);
+  glTexParameteri(target, GL_TEXTURE_WRAP_R, GL_REPEAT);
+
+  glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR/*_MIPMAP_LINEAR*/);
+  glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+  glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_PRIORITY, this->priority);
+
+
+  /* control the mipmap levels */
+  glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_MIN_LOD, 5);
+  glTexParameterf(GL_TEXTURE_ENV, GL_TEXTURE_MAX_LOD, 0);
+
+  /* build the Texture  OpenGL V >= 1.1 */
+  glTexImage2D(target,
+               0,
+               GL_RGBA,
+               surface->w,
+               surface->h,
+               0,
+               GL_RGBA,
+               GL_UNSIGNED_BYTE,
+               surface->pixels);
+
+  // build the MipMaps automaticaly
+  errorCode = gluBuild2DMipmaps(target,
+                                GL_RGBA,
+                                surface->w,
+                                surface->h,
+                                GL_RGBA,
+                                GL_UNSIGNED_BYTE,
+                                surface->pixels
+                               );
+  if(unlikely(errorCode != 0))
+    PRINTF(1)("Error while loading texture (mipmap generation), gluBuild2DMipmaps returned %i\n", errorCode);
+
+  // Deselect newly built texture, as we do not want to display with this texture.
+  if (target == GL_TEXTURE_2D)
+    glBindTexture(target, 0);
+
+  return texture;
+}
+
Index: branches/network/src/lib/graphics/importer/texture.h
===================================================================
--- branches/network/src/lib/graphics/importer/texture.h	(revision 6636)
+++ branches/network/src/lib/graphics/importer/texture.h	(revision 6636)
@@ -0,0 +1,60 @@
+/*!
+ * @file texture.h
+ * @brief Contains the texture class, that handles the reading of Images into Texutre-files.
+ */
+
+#ifndef _TEXTURE_H
+#define _TEXTURE_H
+
+#include "base_object.h"
+
+#include "glincl.h"
+
+/* Forward Declaration */
+struct SDL_Surface;
+
+//! A Class, that reads in Textures from different fileformats.
+  class Texture : public BaseObject
+  {
+    public:
+      Texture(const char* imageName = NULL, GLenum target = GL_TEXTURE_2D);
+  //  Texture(TEXTURE_TYPE type, int resolution);
+      ~Texture();
+
+      bool loadImage(const char* imageName, GLenum target = GL_TEXTURE_2D);
+      virtual bool rebuild();
+
+      /** @returns The textureID of this texture.  */
+      inline GLuint getTexture() const { return this->texture; };
+      /** @returns true if texture has alpha, false otherwise */
+      inline bool hasAlpha() const {return bAlpha;}
+      /** @returns the stored image of this Texture */
+      const SDL_Surface* const getStoredImage() const { return this->image; };
+
+
+
+      static void setTextureEnableState(bool texturesEnabled);
+      /** @returns true if Textures are enabled */
+      inline static bool getTextureEnableState() { return Texture::texturesEnabled; };
+
+      // Utility functionality:
+      SDL_Surface* prepareSurface(SDL_Surface* input, bool& hasAlpha) const;
+      GLuint loadTexToGL (const SDL_Surface* surface, GLenum target = GL_TEXTURE_2D) const;
+
+    protected:
+
+      bool setSurface(SDL_Surface* newSurface);
+      bool setAlpha(bool hasAlpha) { this->bAlpha = hasAlpha; };
+      bool setTexture(GLuint texture) { this->texture = texture; };
+
+
+    private:
+      GLuint           texture;            //!< The Texture-ID of opengl from this Texture.
+      bool             bAlpha;             //!< if the texture has an alpha channel.
+      SDL_Surface*     image;              //!< The SDL_Surfce that stores the Texture on it.
+      GLclampf         priority;           //!< the priority of the current texture (used for garphics cards with limited mem)
+
+      static bool      texturesEnabled;    //!< If the Textures are enabled.
+  };
+
+#endif /* _TEXTURE_H */
Index: branches/network/src/lib/graphics/importer/texture_sequence.cc
===================================================================
--- branches/network/src/lib/graphics/importer/texture_sequence.cc	(revision 6636)
+++ branches/network/src/lib/graphics/importer/texture_sequence.cc	(revision 6636)
@@ -0,0 +1,180 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "texture_sequence.h"
+
+#include "debug.h"
+#include "graphics_engine.h"
+
+#ifdef HAVE_SDL_IMAGE_H
+#include <SDL_image.h>
+#else
+#include <SDL/SDL_image.h>
+#endif
+
+/**
+ *  Constructor for a Texture
+ */
+TextureSequence::TextureSequence(unsigned int count, ...)
+{
+  this->setClassID(CL_TEXTURE_SEQUENCE, "TextureSequence");
+
+  va_list textureNameList;
+  va_start(textureNameList, count);
+
+  this->loadImageSeries(count, textureNameList);
+}
+
+/**
+ * Destructor of a TextureSequence
+ *
+ * Frees Data, and deletes the textures from GL
+ */
+TextureSequence::~TextureSequence()
+{
+  this->clearLists();
+}
+
+void TextureSequence::clearLists()
+{
+  // delete all images
+  while(!this->images.empty())
+  {
+    SDL_FreeSurface(this->images.back());
+    this->images.pop_back();
+  }
+
+  // delete all textures.
+  while(!this->textures.empty())
+  {
+    if (glIsTexture(this->textures.back()))
+      glDeleteTextures(1, &this->textures.back());
+    this->textures.pop_back();
+  }
+}
+
+/**
+ * @brief rebuilds all the textures from the Images stored in this FrameSequence
+ */
+bool TextureSequence::rebuild()
+{
+  PRINTF(3)("Reloading TextureSequence of %s '%s'\n", this->getClassName(), this->getName());
+
+  for (unsigned int i = 0; i < this->textures.size(); i++)
+  {
+    if (glIsTexture(this->textures[i]))
+    {
+      glDeleteTextures(1, &this->textures[i]);
+      this->textures[i] = 0;
+    }
+
+    if (this->images[i] != NULL)
+      this->textures[i] = loadTexToGL(this->images[i]);
+  }
+}
+
+/**
+ * @brief loads an image Sequence
+ * @param count how many images to load to the TextureSequence
+ * @param ... the names of the Images to load
+ * @returns true on success, false otherwise
+ */
+bool TextureSequence::loadImageSeries(unsigned int count, ...)
+{
+  va_list textureNameList;
+  va_start(textureNameList, count);
+
+  return this->loadImageSeries(count, textureNameList);
+}
+
+/**
+ * @brief loads an image Sequence
+ * @param count how many images to load to the TextureSequence
+ * @param textures the names of the Images to load
+ * @returns true on success, false otherwise
+ */
+bool TextureSequence::loadImageSeries(unsigned int count, va_list textures)
+{
+  bool retVal = true;
+  for (unsigned int i = 0; i < count; i++)
+  {
+    if( !this->addFrame(va_arg(textures, char*)))
+      retVal = false;
+  }
+  return retVal;
+}
+
+/**
+ * @brief adds a new Frame to this Sequence (at the end)
+ * @param imageName the Name of the Image to add
+ * @returns true on success
+ */
+bool TextureSequence::addFrame(const char* imageName)
+{
+  if (imageName == NULL)
+    return false;
+
+  SDL_Surface* addSurface = IMG_Load(imageName);
+  bool success = this->addFrame(addSurface);
+  delete addSurface;
+
+  return success;
+}
+
+/**
+ * @brief adds a new Frame at the end of the Sequence.
+ * @param surface the Surface to add at the end of the Sequence.
+ */
+bool TextureSequence::addFrame(SDL_Surface* surface)
+{
+  if (surface == NULL)
+    return false;
+  bool hasAlpha;
+  SDL_Surface* newSurf = this->prepareSurface(surface, hasAlpha);
+  if (newSurf != NULL)
+  {
+    this->images.push_back(newSurf);
+    this->textures.push_back(Texture::loadTexToGL(newSurf));
+  }
+  this->setAlpha(hasAlpha);
+
+  return true;
+}
+
+/**
+ * @brief adds a new Frame at the end of the Sequence.
+ * @param texture the texture to add at the end of the Sequence.
+ */
+bool TextureSequence::addFrame(GLuint texture)
+{
+  if (texture == 0)
+    return false;
+  this->textures.push_back(texture);
+
+  return true;
+}
+
+/**
+ * @brief moves to the n'th texture which can then be retrieved via the Texture function: this->getTexture()
+ * @param frameNumber the n-th frame
+ */
+/*void TextureSequence::gotoFrame(unsigned int frameNumber)
+{
+  if (this->textures.size() > frameNumber)
+    this->setTexture(this->textures[frameNumber]);
+}
+*/
Index: branches/network/src/lib/graphics/importer/texture_sequence.h
===================================================================
--- branches/network/src/lib/graphics/importer/texture_sequence.h	(revision 6636)
+++ branches/network/src/lib/graphics/importer/texture_sequence.h	(revision 6636)
@@ -0,0 +1,51 @@
+/*!
+ * @file texture.h
+ * @brief Contains the texture class, that handles the reading of Images into Texutre-files.
+ */
+
+#ifndef _TEXTURE_SEQUENCE_H
+#define _TEXTURE_SEQUENCE_H
+
+#include "texture.h"
+
+#include "glincl.h"
+
+#include <vector>
+#include <stdarg.h>
+
+/* Forward Declaration */
+struct SDL_Surface;
+
+//! A Class, that reads in Textures from different fileformats.
+class TextureSequence : public Texture
+{
+  public:
+    TextureSequence(unsigned int count = 0, ...);
+  //  Texture(TEXTURE_TYPE type, int resolution);
+    ~TextureSequence();
+
+    bool loadImageSeries(unsigned int count, ...);
+    bool loadImageSeries(unsigned int count, va_list textureNames);
+    bool addFrame(const char* image);
+    bool addFrame(SDL_Surface* surface);
+    bool addFrame(GLuint texture);
+
+    void clearLists();
+
+    virtual bool rebuild();
+
+    /** @returns the count of frames in this sequence */
+    inline unsigned int getFrameCount() const { return this->textures.size(); };
+
+    //void gotoFrame(unsigned int frameNumber);
+    /** @returns The textureID of the Frame @param frameNumber the n-th frame this texture-series.  */
+    inline GLuint getFrameTexture(unsigned int frameNumber) const { return (this->textures.size()>frameNumber)?this->textures[frameNumber]:0; };
+    /** @returns The SDL_Surface of the image at Frame @param frameNumber the n-th frame of this image-seriers */
+    const SDL_Surface* const getFrameImage(unsigned int frameNumber) const { return (this->images.size()>frameNumber)?this->images[frameNumber]:NULL; };
+
+  private:
+    std::vector<GLuint>          textures;            //!< The Texture-ID of opengl from this Texture.
+    std::vector<SDL_Surface*>    images;              //!< The SDL_Surfce that stores the Texture on it.
+};
+
+#endif /* _TEXTURE_SEQUENCE_H */
Index: branches/network/src/lib/graphics/importer/vertex_array_model.cc
===================================================================
--- branches/network/src/lib/graphics/importer/vertex_array_model.cc	(revision 6636)
+++ branches/network/src/lib/graphics/importer/vertex_array_model.cc	(revision 6636)
@@ -0,0 +1,366 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_IMPORTER
+
+#include "vertex_array_model.h"
+
+#include "stdlibincl.h"
+#include <stdarg.h>
+
+#include "tc.h"
+
+using namespace std;
+
+/////////////
+/// MODEL ///
+/////////////
+/**
+ * @brief Creates a 3D-VertexArrayModel.
+ *
+ * assigns it a Name and a Type
+ */
+VertexArrayModel::VertexArrayModel()
+{
+  this->setClassID(CL_MODEL, "VertexArrayModel");
+
+  this->newStripe();
+}
+
+/**
+ * @brief special copy constructor for converting Models to VertexArray-Stripes
+ * @param model the Model to produce a VertexArray model from.
+ *
+ * Code that uses Brad Granthams
+ * excelent TC-code for generating stripes out of a mix of ModelCoordinates.
+ */
+VertexArrayModel::VertexArrayModel(const Model& model)
+{
+  this->setClassID(CL_MODEL, "VertexArrayModel");
+
+  // importing the data to the new Model.
+  this->newStripe();
+
+  for (unsigned int i = 0; i < model.getVertexCount()*3; i+=3)
+    this->addVertex(model.getVertexArray()[i], model.getVertexArray()[i+1], model.getVertexArray()[i+2]);
+  for (unsigned int i = 0; i < model.getVertexCount()*3; i+=3)
+    this->addColor((float)i / (float)model.getVertexCount(), 0, 0);
+
+  for (unsigned int i = 0; i < model.getNormalsCount()*3; i+=3)
+     this->addNormal(model.getNormalsArray()[i], model.getNormalsArray()[i+1], model.getNormalsArray()[i+2]);
+  for (unsigned int i = 0; i < model.getTexCoordCount(); i+=2)
+     this->addTexCoor(model.getTexCoordArray()[i], model.getTexCoordArray()[i+1]);
+
+
+  // The acTC object generating this Model. //
+  ACTCData *tc;
+  tc = actcNew();
+  if(tc == NULL) {
+    /* memory allocation failed */
+    /* print error here and exit or whatever */
+  }
+
+  // inputing the data of model to the tc
+  actcBeginInput(tc);
+  for(unsigned int i = 0; i < model.getTriangleCount(); i++)
+  {
+      actcAddTriangle(tc,
+                      model.getTriangles()[i].indexToVertices[0],
+                      model.getTriangles()[i].indexToVertices[1],
+                      model.getTriangles()[i].indexToVertices[2]);
+  }
+  actcEndInput(tc);
+
+
+
+  int prim;
+  unsigned int v1, v2, v3;
+
+  actcBeginOutput(tc);
+  while((prim = actcStartNextPrim(tc, &v1, &v2) != ACTC_DATABASE_EMPTY))
+  {
+    this->newStripe();
+
+    this->addIndice(v1);
+    this->addIndice(v2);
+    /* start a primitive of type "prim" with v1 and v2 */
+    while(actcGetNextVert(tc, &v3) != ACTC_PRIM_COMPLETE)
+    {
+      /* continue primitive using v3 */
+      this->addIndice(v3);
+    }
+  }
+  actcEndOutput(tc);
+
+  this->finalize();
+}
+
+
+/**
+ * @brief deletes a VertexArrayModel.
+ *
+ * Looks if any from model allocated space is still in use, and if so deleted it.
+ */
+VertexArrayModel::~VertexArrayModel()
+{
+  PRINTF(4)("Deleting VertexArrayModel ");
+  if (this->getName())
+  {
+    PRINT(4)("%s\n", this->getName());
+  }
+  else
+  {
+    PRINT(4)("\n");
+  }
+}
+
+
+/**
+ * @brief Draws the VertexArrayModels of all Groups.
+ *
+ * It does this by just calling the Lists that must have been created earlier.
+ */
+void VertexArrayModel::draw() const
+{
+  PRINTF(4)("drawing 3D-VertexArrayModel %s\n", this->getName());
+  glEnableClientState(GL_VERTEX_ARRAY );
+  glEnableClientState(GL_TEXTURE_COORD_ARRAY );
+  glEnableClientState(GL_NORMAL_ARRAY );
+  glEnableClientState(GL_COLOR_ARRAY );
+
+
+  glVertexPointer(3, GL_FLOAT, 0, &this->vertices[0]);
+  glNormalPointer(GL_FLOAT, 0, &this->normals[0]);
+  glTexCoordPointer(2, GL_FLOAT, 0, &this->texCoords[0]);
+  glColorPointer(3, GL_FLOAT, 0, &this->colors[0]);
+
+  for (GLuint i = 1; i < this->stripes.size(); ++i)
+    {
+      glDrawElements( GL_TRIANGLE_STRIP,
+                      this->stripes[i] - this->stripes[i-1],
+                      GL_UNSIGNED_INT,
+                      &this->indices[this->stripes[i-1]] );
+    }
+}
+
+
+//////////
+// MESH //
+//////////
+/**
+ * @brief generates a new Stripe in this Model
+ */
+void VertexArrayModel::newStripe()
+{
+  // no stripes of size 0
+  if (this->stripes.empty() || this->indices.size() != this->stripes.back())
+    this->stripes.push_back(this->indices.size());
+}
+
+
+/**
+ * @brief parses a vertex-String
+ * @param x the X-coordinate of the Vertex to add.
+ * @param y the Y-coordinate of the Vertex to add.
+ * @param z the Z-coordinate of the Vertex to add.
+ */
+void VertexArrayModel::addVertex(float x, float y, float z)
+{
+  this->vertices.push_back(Vector(x,y,z));
+  this->pModelInfo.numVertices++;
+}
+
+
+/**
+ * @brief adds a VertexNormal.
+ * @param x The x coordinate of the Normal.
+ * @param y The y coordinate of the Normal.
+ * @param z The z coordinate of the Normal.
+ *
+ * If a vertexNormal line is found this function will inject it into the vertexNormal-Array
+ */
+void VertexArrayModel::addNormal(float x, float y, float z)
+{
+  this->normals.push_back(Vector(x,y,z));
+  this->pModelInfo.numNormals++;
+}
+
+
+/**
+ * @brief adds a Texture Coordinate
+ * @param u The u coordinate of the TextureCoordinate.
+ * @param v The y coordinate of the TextureCoordinate.
+ *
+ *  If a TextureCoordinate line is found this function will inject it into the TextureCoordinate-Array
+ */
+void VertexArrayModel::addTexCoor(float u, float v)
+{
+  this->texCoords.push_back(u);
+  this->texCoords.push_back(v);
+  this->pModelInfo.numTexCoor++;
+}
+
+/**
+ * @brief adds a new Color
+ * @param r the Red Component of the VertexColor to add.
+ * @param g the Green Component of the VertexColor to add.
+ * @param b the Blue of the VertexColor to add.
+ */
+void VertexArrayModel::addColor(float r, float g, float b)
+{
+  this->colors.push_back(Vector(r,g,b));
+  // FIXME
+}
+
+
+/**
+ *  adds a new Face
+ * @param faceElemCount the number of Vertices to add to the Face.
+ * @param type The information Passed with each Vertex
+*/
+void VertexArrayModel::addIndice(GLuint indice)
+{
+  this->indices.push_back(indice);
+}
+
+
+/**
+ * @brief Finalizes an Object. This can be done outside of the Class.
+ */
+void VertexArrayModel::finalize()
+{
+  // finalize the Arrays
+  this->newStripe();
+}
+
+
+
+
+/////////////
+// TESTING //
+/////////////
+/**
+* @brief Includes a default model
+*
+* This will inject a Cube, because this is the most basic model.
+*/
+void VertexArrayModel::planeModel(float sizeX, float sizeY, unsigned int resolutionX, unsigned int resolutionY)
+{
+  GLuint i, j;
+  for (i = 0; i < resolutionY; i++)
+    {
+      for (j = 0; j < resolutionX; j++)
+        {
+          this->addVertex(((float)i - (float)resolutionY/2.0)*sizeY, 0.0, ((float)j - (float)resolutionX/2.0)*sizeX);
+          this->addNormal(0.0, 1, 0.0);
+          this->addTexCoor((float)i/(float)resolutionY, (float)j/(float)resolutionY);
+          this->addColor((float)i/20.0, 0.0, (float)j/20.0);
+        }
+    }
+
+  for (i = 0; i < resolutionY-1; i++)
+  {
+    for (j = 0; j < resolutionX; j++)
+    {
+      this->addIndice( resolutionY*i + j );
+      this->addIndice( resolutionY*(i+1) + j );
+    }
+    this->newStripe();
+  }
+}
+
+#include <cmath>
+
+/**
+ * @brief builds a Triangle Stripped sphere
+ * @param radius: radius
+ * @param loops: the count of loops
+ * @param segmentsPerLoop how many Segments per loop
+ */
+void VertexArrayModel::spiralSphere(const float radius, const unsigned int loops, const unsigned int segmentsPerLoop)
+{
+  for (unsigned int loopSegmentNumber = 0; loopSegmentNumber < segmentsPerLoop; ++loopSegmentNumber)
+  {
+    float theta = 0;
+    float phi = loopSegmentNumber * 2 * PI / segmentsPerLoop;
+    float sinTheta = std::sin(theta);
+    float sinPhi = std::sin(phi);
+    float cosTheta = std::cos(theta);
+    float cosPhi = std::cos(phi);
+    this->addVertex(radius * cosPhi * sinTheta, radius * sinPhi * sinTheta, radius * cosTheta);
+    this->addNormal(radius * cosPhi * sinTheta, radius * sinPhi * sinTheta, radius * cosTheta);
+    this->addTexCoor(0,0); /// FIXME
+    this->addColor(.125,.436,.246); ///FIXME
+  }
+  for (unsigned int loopNumber = 0; loopNumber <= loops; ++loopNumber)
+  {
+    for (unsigned int loopSegmentNumber = 0; loopSegmentNumber < segmentsPerLoop; ++loopSegmentNumber)
+    {
+      float theta = (loopNumber * PI / loops) + ((PI * loopSegmentNumber) / (segmentsPerLoop * loops));
+      if (loopNumber == loops)
+      {
+        theta = PI;
+      }
+      float phi = loopSegmentNumber * 2 * PI / segmentsPerLoop;
+      float sinTheta = std::sin(theta);
+      float sinPhi = std::sin(phi);
+      float cosTheta = std::cos(theta);
+      float cosPhi = std::cos(phi);
+      this->addVertex(radius * cosPhi * sinTheta, radius * sinPhi * sinTheta, radius * cosTheta);
+      this->addNormal(radius * cosPhi * sinTheta, radius * sinPhi * sinTheta, radius * cosTheta);
+      this->addTexCoor(0,0); //FIXME
+      this->addColor(.125,.436,.246);
+
+    }
+  }
+  for (unsigned int loopSegmentNumber = 0; loopSegmentNumber < segmentsPerLoop; ++loopSegmentNumber)
+  {
+    this->addIndice(loopSegmentNumber);
+    this->addIndice(segmentsPerLoop + loopSegmentNumber);
+  }
+  for (unsigned int loopNumber = 0; loopNumber < loops; ++loopNumber)
+  {
+    for (unsigned int loopSegmentNumber = 0; loopSegmentNumber < segmentsPerLoop; ++loopSegmentNumber)
+    {
+      this->addIndice( ((loopNumber + 1) * segmentsPerLoop) + loopSegmentNumber);
+      this->addIndice( ((loopNumber + 2) * segmentsPerLoop) + loopSegmentNumber);
+    }
+  }
+}
+
+
+/**
+ * @brief print out some nice debug information about this VertexArrayModel.
+ */
+void VertexArrayModel::debug() const
+{
+  PRINT(0)("VertexArrayModel (%s): debug\n", this->getName());
+  PRINT(0)("Stripes: %d; Indices: %d; Vertices: %d; Normals %d; TextCoords %d; Colors %d\n",
+            this->stripes.size(),
+            this->indices.size(),
+            this->vertices.size(),
+            this->normals.size(),
+            this->texCoords.size()/2,
+            this->colors.size() );
+  for (GLuint i = 1; i < this->stripes.size(); ++i)
+  {
+    PRINT(0)("Stripe-%d (s:%d:e:%d):: ", i, this->stripes[i-1], this->stripes[i]);
+    for (GLuint j = this->stripes[i-1] ; j < this->stripes[i]; j++)
+    {
+      PRINT(0)("->%d", this->indices[j]);
+    }
+    PRINT(0)("\n");
+  }
+}
Index: branches/network/src/lib/graphics/importer/vertex_array_model.h
===================================================================
--- branches/network/src/lib/graphics/importer/vertex_array_model.h	(revision 6636)
+++ branches/network/src/lib/graphics/importer/vertex_array_model.h	(revision 6636)
@@ -0,0 +1,79 @@
+/*!
+ * @file vertex_array_model.h
+ * @brief Contains the VertexArrayModel Class that handles 3D-Models rendered out of VertexArrays
+ */
+
+#ifndef _VERTEX_ARRAY_MODEL_H
+#define _VERTEX_ARRAY_MODEL_H
+
+#include "model.h"
+
+#include "glincl.h"
+
+#include <vector>
+
+/* Forward Declaration */
+class Material;
+
+
+/////////////
+/// MODEL ///
+/////////////
+//! Class that handles 3D-Models. it can also read them in and display them.
+/**
+ * this renders models with help of the OpenGL glVertexArray
+ */
+class VertexArrayModel : public Model
+{
+ public:
+  VertexArrayModel();
+  VertexArrayModel(const Model& model);
+  virtual ~VertexArrayModel();
+
+  void draw() const;
+
+
+  void newStripe();
+
+  void addVertex(float x, float y, float z);
+  void addNormal(float x, float y, float z);
+  void addTexCoor(float u, float v);
+  void addColor(float r, float g, float b);
+
+  void addIndice(GLuint indice);
+
+  void finalize();
+
+  unsigned int vertexCount() const { return this->vertices.size(); };
+  unsigned int normalCount() const { return this->normals.size(); };
+  unsigned int texCoordCount() const { return this->texCoords.size(); };
+  unsigned int colorCount() const { return this->colors.size(); };
+  unsigned int indiceCount() const { return this->indices.size(); };
+
+  Vector& vertex(unsigned int i) { return this->vertices[i]; };
+  Vector& normal(unsigned int i) { return this->normals[i]; };
+  //Vector& texCoord(unsigned int i) { return this->texCoord[i]; };
+  Vector& color(unsigned int i) { return this->colors[i]; };
+  GLuint  index(unsigned int i) { return this->indices[i]; };
+  //
+  void planeModel(float sizeX, float sizeY, unsigned int resolutionX, unsigned int resolutionY);
+  void spiralSphere(const float radius, const unsigned int loops, const unsigned int segmentsPerLoop);
+
+  void debug() const;
+
+ private:
+  void importToVertexArray();
+
+ private:
+  std::vector<Vector>        vertices;        //!< The Array that handles the Vertices.
+  std::vector<Vector>        normals;         //!< The Array that handles the Normals.
+  std::vector<float>         texCoords;       //!< The Array that handles the VertexTextureCoordinates.
+  std::vector<Vector>        colors;          //!< The Array that handles Colors.
+
+  std::vector<GLuint>        indices;         //!< The Array that tells us what Vertex is connected to which other one.
+
+  std::vector<GLuint>        stripes;         //!< A lsit of Stripes of this Model.
+
+};
+
+#endif
Index: branches/network/src/lib/graphics/light.cc
===================================================================
--- branches/network/src/lib/graphics/light.cc	(revision 6636)
+++ branches/network/src/lib/graphics/light.cc	(revision 6636)
@@ -0,0 +1,367 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "light.h"
+
+#include "glincl.h"
+#include "vector.h"
+#include "parser/tinyxml/tinyxml.h"
+#include "load_param.h"
+#include "factory.h"
+#include "debug.h"
+
+using namespace std;
+
+CREATE_FACTORY(Light, CL_LIGHT);
+
+//! Definition of the Lights and their Names
+int lightsV[] =
+{
+                  GL_LIGHT0,
+                  GL_LIGHT1,
+                  GL_LIGHT2,
+                  GL_LIGHT3,
+                  GL_LIGHT4,
+                  GL_LIGHT5,
+                  GL_LIGHT6,
+                  GL_LIGHT7
+};
+
+/**
+ * @param root The XML-element to load the Light from
+
+  @todo what to do, if no Light-Slots are open anymore ???
+ */
+ Light::Light(const TiXmlElement* root)
+{
+  PRINTF(4)("initializing Light number %d.\n", this->lightNumber);
+
+  this->lightNumber = LightManager::getInstance()->registerLight(this);
+
+  this->setClassID(CL_LIGHT, "Light");
+  char tmpName[10];
+  sprintf(tmpName, "Light[%d]", this->lightNumber);
+  this->setName(tmpName);
+
+  // enable The light
+  glEnable(lightsV[this->lightNumber]); // postSpawn
+
+  // set values (defaults)
+  this->setDiffuseColor(1.0, 1.0, 1.0);
+  this->setSpecularColor(1.0, 1.0, 1.0);
+
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  destroys a Light
+*/
+Light::~Light()
+{
+  glDisable(lightsV[this->lightNumber]);
+
+  LightManager::getInstance()->unregisterLight(this);
+}
+
+/**
+ * @param root The XML-element to load the Light from
+ */
+void Light::loadParams(const TiXmlElement* root)
+{
+  PNode::loadParams(root);
+
+  LoadParam(root, "diffuse-color", this, Light, setDiffuseColor)
+      .describe("sets the diffuse color of the Light (red [0-1], green [0-1], blue [0-1])");
+
+  LoadParam(root, "specular-color", this, Light, setSpecularColor)
+      .describe("sets the specular color of the Light (red [0-1], green [0-1], blue [0-1])");
+
+  LoadParam(root, "attenuation", this, Light, setAttenuation)
+      .describe("sets the Attenuation of the LightSource (constant Factor, linear Factor, quadratic Factor).");
+
+  LoadParam(root, "spot-direction", this, Light, setSpotDirection)
+      .describe("sets the Direction of the Spot");
+
+  LoadParam(root, "spot-cutoff", this, Light, setSpotCutoff)
+      .describe("the cuttoff of the Spotlight");
+}
+
+/**
+ *  sets an emitting Diffuse color of this Light
+ * @param r red
+ * @param g green
+ * @param b blue
+*/
+void Light::setDiffuseColor(GLfloat r, GLfloat g, GLfloat b)
+{
+  this->diffuseColor[0] = r;
+  this->diffuseColor[1] = g;
+  this->diffuseColor[2] = b;
+  this->diffuseColor[3] = 1.0;
+
+  glLightfv (lightsV[this->lightNumber], GL_DIFFUSE, this->diffuseColor);
+}
+
+/**
+ *  sets an emitting Specular color of this Light
+ * @param r red
+ * @param g green
+ * @param b blue
+*/
+void Light::setSpecularColor(GLfloat r, GLfloat g, GLfloat b)
+{
+  this->specularColor[0] = r;
+  this->specularColor[1] = g;
+  this->specularColor[2] = b;
+  this->specularColor[3] = 1.0;
+
+  glLightfv (lightsV[this->lightNumber], GL_SPECULAR, this->specularColor);
+}
+
+
+/**
+ *  Sets the AttenuationType of this Light Source
+ * @param constantAttenuation The Constant Attenuation of the Light
+ * @param linearAttenuation The Linear Attenuation of the Light
+ * @param quadraticAttenuation The Quadratic Attenuation of the Light
+*/
+void Light::setAttenuation(float constantAttenuation, float linearAttenuation, float quadraticAttenuation)
+{
+  this->constantAttenuation  = constantAttenuation;
+  this->linearAttenuation    = linearAttenuation;
+  this->quadraticAttenuation = quadraticAttenuation;
+
+  glLightf(lightsV[this->lightNumber], GL_CONSTANT_ATTENUATION,  constantAttenuation);
+  glLightf(lightsV[this->lightNumber], GL_LINEAR_ATTENUATION,    linearAttenuation);
+  glLightf(lightsV[this->lightNumber], GL_QUADRATIC_ATTENUATION, quadraticAttenuation);
+}
+
+
+/**
+ *  stets the direction of the Spot Light.
+ * @param direction The direction of the Spot Light.
+*/
+void Light::setSpotDirection(const Vector& direction)
+{
+  this->spotDirection[0] = direction.x;
+  this->spotDirection[1] = direction.y;
+  this->spotDirection[2] = direction.z;
+
+  glLightfv(lightsV[this->lightNumber], GL_SPOT_DIRECTION, this->spotDirection);
+}
+
+
+/**
+ *  sets the cutoff angle of the Light.
+ * @param cutoff The cutoff angle.
+*/
+void Light::setSpotCutoff(GLfloat cutoff)
+{
+  this->spotCutoff = cutoff;
+  glLightf(lightsV[this->lightNumber], GL_SPOT_CUTOFF, cutoff);
+}
+
+/**
+ *  draws this Light. Being a World-entity the possibility to do this lies at hand.
+*/
+void Light::draw() const
+{
+  float pos[4] = {this->getAbsCoor().x, this->getAbsCoor().y, this->getAbsCoor().z, 1.0};
+  PRINTF(4)("Drawing The Lights new Position at %f %f %f\n", pos[0], pos[1], pos[2]);
+  glLightfv(lightsV[this->lightNumber], GL_POSITION, pos);
+}
+
+
+/**
+ *  Prints out some nice formated debug information about the Light
+*/
+void Light::debug() const
+{
+  PRINT(0)(":: %d ::  -- reference %p\n", this->lightNumber, this);
+  PRINT(0)(" GL-state: ");
+  GLboolean param;
+  glGetBooleanv(lightsV[this->lightNumber], &param);
+  if (param)
+    PRINT(0)("ON\n");
+  else
+    PRINT(0)("OFF\n");
+
+  PRINT(0)(" DiffuseColor:  %f/%f/%f\n", this->diffuseColor[0], this->diffuseColor[1], this->diffuseColor[2]);
+  PRINT(0)(" SpecularColor: %f/%f/%f\n", this->specularColor[0], this->specularColor[1], this->specularColor[2]);
+  PRINT(0)(" Attenuation: constant=%f linear=%f quadratic=%f\n", this->constantAttenuation, this->linearAttenuation, this->quadraticAttenuation);
+}
+
+
+/******************
+** LIGHT-MANAGER **
+******************/
+/**
+ *  standard constructor for a Light
+*/
+LightManager::LightManager ()
+{
+  this->setClassID(CL_LIGHT_MANAGER, "LightManager");
+
+  glEnable (GL_LIGHTING);
+  this->setAmbientColor(.3, .3, .3);
+  this->lights = new Light*[NUMBEROFLIGHTS];
+  for (int i = 0; i < NUMBEROFLIGHTS; i++)
+    lights[i] = NULL;
+  this->currentLight = NULL;
+}
+
+/**
+ *  standard deconstructor
+
+   first disables Lighting
+
+   then deletes the rest of the allocated memory
+   and in the end sets the singleton Reference to zero.
+*/
+LightManager::~LightManager ()
+{
+  glDisable(GL_LIGHTING);
+  this->setAmbientColor(.0,.0,.0);
+
+  for (int i = 0; i < NUMBEROFLIGHTS; i++)
+    if (this->lights[i] != NULL)
+      delete lights[i];
+  delete[] lights;
+  LightManager::singletonRef = NULL;
+}
+
+/**
+ *  singleton-Reference to the Light-class
+*/
+LightManager* LightManager::singletonRef = NULL;
+
+/**
+* @param root the XML-element to load the LightManager's settings from
+ */
+void LightManager::loadParams(const TiXmlElement* root)
+{
+  LoadParamXML(root, "Lights", this, LightManager, loadLights)
+      .describe("an XML-Element to load lights from.");
+
+  LoadParam(root, "ambient-color", this, LightManager, setAmbientColor)
+      .describe("sets the ambient Color of the Environmental Light");
+}
+
+/**
+* @param root The XML-element to load Lights from
+ */
+void LightManager::loadLights(const TiXmlElement* root)
+{
+  const TiXmlElement* element = root->FirstChildElement();
+
+  while (element != NULL)
+  {
+    Factory::fabricate(element);
+
+    element = element->NextSiblingElement();
+  }
+}
+
+// set Attributes
+/**
+ *  sets the ambient Color of the Scene
+ * @param r red
+ * @param g green
+ * @param b blue
+*/
+void LightManager::setAmbientColor(GLfloat r, GLfloat g, GLfloat b)
+{
+  this->ambientColor[0] = r;
+  this->ambientColor[1] = g;
+  this->ambientColor[2] = b;
+  this->ambientColor[3] = 1.0;
+
+  glLightfv (GL_LIGHT0, GL_AMBIENT, this->ambientColor);
+}
+
+/**
+* @param light the Light to register to the LightManager
+
+  This is done explicitely by the constructor of a Light
+*/
+int LightManager::registerLight(Light* light)
+{
+  for (int i = 0; i < NUMBEROFLIGHTS; i++)
+    if (!this->lights[i])
+  {
+    this->lights[i]=light;
+    return i;
+  }
+  PRINTF(1)("no more light slots availiable. All %d already taken\n", NUMBEROFLIGHTS);
+  return -1;
+}
+
+/**
+* @param light The light to unregister from the LightManager
+
+  This is done every time a Light is destroyed explicitely by the Light-destructor
+ */
+void LightManager::unregisterLight(Light* light)
+{
+  for (int i = 0; i < NUMBEROFLIGHTS; i++)
+  {
+    if (this->lights[i] == light)
+    {
+      this->lights[i] = NULL;
+      return;
+    }
+  }
+  PRINTF(2)("Light %p could not be unloaded (this should not heappen\n)");
+  return;
+}
+
+/**
+ *  draws all the Lights in their appropriate position
+ */
+void LightManager::draw() const
+{
+  glMatrixMode(GL_MODELVIEW);
+  glLoadIdentity();
+  PRINTF(4)("Drawing the Lights\n");
+  for (int i = 0; i < NUMBEROFLIGHTS; i++)
+    if (this->lights[i])
+      lights[i]->draw();
+}
+
+/**
+ *  outputs debug information about the Class and its lights
+*/
+void LightManager::debug() const
+{
+  PRINT(0)("=================================\n");
+  PRINT(0)("= DEBUG INFORMATION CLASS LIGHT =\n");
+  PRINT(0)("=================================\n");
+  PRINT(0)("Reference: %p\n", LightManager::singletonRef);
+  if (this->currentLight)
+    PRINT(0)("current Light Nr: %d\n", this->currentLight->getLightNumber());
+  PRINT(0)("Ambient Color: %f:%f:%f\n", this->ambientColor[0], this->ambientColor[0], this->ambientColor[0]);
+  PRINT(0)("=== Lights ===\n");
+  for (int i = 0; i < NUMBEROFLIGHTS; i++)
+    if (this->lights[i])
+      {
+        this->lights[i]->debug();
+      }
+  PRINT(0)("-----------------------------LM-\n");
+}
Index: branches/network/src/lib/graphics/light.h
===================================================================
--- branches/network/src/lib/graphics/light.h	(revision 6636)
+++ branches/network/src/lib/graphics/light.h	(revision 6636)
@@ -0,0 +1,124 @@
+/*!
+ * @file light.h
+  *  Handles Lights.
+
+    A Light is one of the more important things in a 3D-environment,
+    without it one sees nothing :)
+    It is here for diffuse-, specular- and Bump-Mappings.
+*/
+
+#ifndef _LIGHT_H
+#define _LIGHT_H
+
+#include "p_node.h"
+#include "glincl.h"
+
+//! The maximum number of Lights this OpenGL-implementation supports.
+#define NUMBEROFLIGHTS GL_MAX_LIGHTS
+
+
+// FORWARD DECLARATIONS //
+class Vector;
+class TiXmlElement;
+
+//! A class that handles Lights. The LightManager operates on this.
+class Light : public PNode
+{
+ public:
+  Light(const TiXmlElement* root = NULL);
+  virtual ~Light();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void setDiffuseColor(GLfloat r, GLfloat g, GLfloat b);
+  void setSpecularColor(GLfloat r, GLfloat g, GLfloat b);
+  void setAttenuation(float constantAttenuation, float linearAttenuation, float quadraticAttenuation);
+  void setSpotDirection(const Vector& direction);
+  void setSpotDirection(float x, float y, float z) { setSpotDirection(Vector(x,y,z)); };
+  void setSpotCutoff(GLfloat cutoff);
+
+  /** @returns the lightNumber*/
+  int getLightNumber() const {return this->lightNumber;}
+
+  virtual void draw() const;
+
+  void debug() const;
+
+  // attributes
+ private:
+  int              lightNumber;               //!< The number of this Light.
+  GLfloat          diffuseColor[4];           //!< The Diffuse Color this Light emmits.
+  GLfloat          specularColor[4];          //!< The specular Color of this Light.
+  float            constantAttenuation;       //!< The Factor of the the Constant Attenuation.
+  float            linearAttenuation;         //!< The Factor of the the Linear Attenuation.
+  float            quadraticAttenuation;      //!< The Factor of the the Quadratic Attenuation.
+  GLfloat          spotDirection[4];          //!< The direction of the Spot Light.
+  GLfloat          spotCutoff;                //!< The cutoff Angle of the Light Source
+};
+
+
+
+//! A class that handles Lights
+/**
+   A Light is a source that emits light rays (photons)
+
+   <b>Usage:</b>\n
+   First you have to get the Light Manager up and running by using LightManager::getInstance().
+   This automatically initiates the GL_LIGHTING, and sets some default stuff about the light.\n
+   Then you will create a new light using:
+   \li new Light();
+
+   if you want to operate on this Light just apply the following functions onto it.
+       (You can also optain the Light-pointer with LightManager::getInstance()->getLight(lightNumber))
+
+   now you can operate on the light as follows:
+   \li void setDiffuseColor(GLfloat r, GLfloat g, GLfloat b);
+   \li void setSpecularColor(GLfloat r, GLfloat g, GLfloat b);
+   \li void setAttenuation(float constantAttenuation, float linearAttenuation, float quadraticAttenuation);
+   \li void setSpotDirection(Vector direction);
+   \li void setSpotCutoff(GLfloat cutoff);
+   \li all PNode stuff also works
+
+   To redraw the light use
+   \li void draw() const; (this is automatically done by the LightManager)
+
+   for some nice output just use:
+   \li void debug() const; (either on LightManager for a resume or on any Light for single information.)
+*/
+class LightManager : public BaseObject
+{
+  friend class Light;
+
+ public:
+  virtual ~LightManager();
+  /** @returns a Pointer to the only object of this Class */
+  inline static LightManager* getInstance() { if (!singletonRef) singletonRef = new LightManager();  return singletonRef; };
+
+  virtual void loadParams(const TiXmlElement* root);
+  void loadLights(const TiXmlElement* root);
+
+  void setAmbientColor(GLfloat r, GLfloat g, GLfloat b);
+
+  Light* getLight(int lightNumber) const;
+  inline Light* getLight() const { return this->currentLight; };
+
+  void draw() const;
+
+  void debug() const;
+
+ private:
+  LightManager();
+
+  int  registerLight(Light* light);
+  void unregisterLight(Light* light);
+
+ private:
+  static LightManager*    singletonRef;       //!< This is the LightHandlers Reference.
+  GLfloat                 ambientColor[4];    //!< The ambient Color of the scene.
+
+  Light**                 lights;             //!< An array of Lenght NUMBEROFLIGHTS, that holds pointers to all LightValues.
+  Light*                  currentLight;       //!< The current Light, we are working with.
+
+};
+
+#endif /* _LIGHT_H */
Index: branches/network/src/lib/graphics/render2D/element_2d.cc
===================================================================
--- branches/network/src/lib/graphics/render2D/element_2d.cc	(revision 6636)
+++ branches/network/src/lib/graphics/render2D/element_2d.cc	(revision 6636)
@@ -0,0 +1,1121 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "element_2d.h"
+#include "render_2d.h"
+
+#include <algorithm>
+
+#include "p_node.h"
+
+#include "graphics_engine.h"
+#include "load_param.h"
+#include "class_list.h"
+
+#include "color.h"
+
+using namespace std;
+
+/**
+ * @brief standard constructor
+ * @param parent the parent to set for this Element2D
+ *
+ * NullElement2D needs this constructor with parameter NULL to initialize
+ * itself. Otherwise it would result in an endless Loop.
+ */
+Element2D::Element2D (Element2D* parent, E2D_LAYER layer, short nodeFlags)
+{
+  this->setClassID(CL_ELEMENT_2D, "Element2D");
+
+  this->setVisibility(true);
+  this->activate2D();
+  this->setAlignment(E2D_ALIGN_NONE);
+  this->bindNode = NULL;
+
+  this->parentMode = nodeFlags;
+  this->parent = NULL;
+  this->absDirection = 0.0;
+  this->relDirection = 0.0;
+  this->bRelCoorChanged = true;
+  this->bRelDirChanged = true;
+  this->toCoordinate = NULL;
+  this->toDirection = NULL;
+  this->setSize2D(1, 1);
+
+
+  this->layer = layer;
+  if (parent != NULL)
+    parent->addChild2D(this);
+}
+
+
+/**
+ * @brief the mighty NullElement
+ * TopMost Node of them all.
+ */
+Element2D* Element2D::nullElement = NULL;
+
+
+/**
+ * @brief standard deconstructor
+ *
+ * There are two general ways to delete an Element2D
+ * 1. delete instance;
+ *   -> result
+ *    delete this Node and all its children and children's children...
+ *    (danger if you still want the instance!!)
+ *
+ * 2. instance->remove2D(); delete instance;
+ *   -> result:
+ *    moves its children to the NullElement2D
+ *    then deletes the Element.
+ */
+Element2D::~Element2D ()
+{
+  // remove the Element2D, delete it's children (if required).
+  std::list<Element2D*>::iterator tmp = this->children.begin();
+  std::list<Element2D*>::iterator deleteNode;
+  while(!this->children.empty())
+    while (tmp != this->children.end())
+    {
+      deleteNode = tmp;
+      tmp++;
+//      printf("TEST::%s(%s) %s\n", (*deleteNode)->getName(), (*deleteNode)->getClassName(), this->getName());
+      if ((this->parentMode & E2D_PROHIBIT_CHILD_DELETE) ||
+          ((*deleteNode)->parentMode & E2D_PROHIBIT_DELETE_WITH_PARENT))
+      {
+        if (this == Element2D::nullElement && (*deleteNode)->parentMode & E2D_REPARENT_TO_NULL)
+          delete (*deleteNode);
+        else
+          (*deleteNode)->reparent2D();
+      }
+      else
+        delete (*deleteNode);
+    }
+
+  if (this->parent != NULL)
+  {
+    this->parent->eraseChild2D(this);
+    this->parent = NULL;
+  }
+
+  // remove all other allocated memory.
+  if (this->toCoordinate != NULL)
+    delete this->toCoordinate;
+  if (this->toDirection != NULL)
+    delete this->toDirection;
+
+  if (this == Element2D::nullElement)
+    Element2D::nullElement = NULL;
+}
+
+
+/**
+ * @brief Loads the Parameters of an Element2D from...
+ * @param root The XML-element to load from
+ */
+void Element2D::loadParams(const TiXmlElement* root)
+{
+  BaseObject::loadParams(root);
+
+  // ELEMENT2D-native settings.
+  LoadParam(root, "alignment", this, Element2D, setAlignment)
+      .describe("loads the alignment: (either: center, left, right or screen-center)");
+
+  LoadParam(root, "layer", this, Element2D, setLayer)
+      .describe("loads the layer onto which to project: (either: top, medium, bottom, below-all)");
+
+  LoadParam(root, "bind-node", this, Element2D, setBindNode)
+      .describe("sets a node, this 2D-Element should be shown upon (name of the node)");
+
+  LoadParam(root, "visibility", this, Element2D, setVisibility)
+      .describe("if the Element is visible or not");
+
+
+// PNode-style:
+  LoadParam(root, "rel-coor", this, Element2D, setRelCoor2D)
+      .describe("Sets The relative position of the Node to its parent.");
+
+  LoadParam(root, "abs-coor", this, Element2D, setAbsCoor2D)
+      .describe("Sets The absolute Position of the Node.");
+
+  LoadParam(root, "rel-dir", this, Element2D, setRelDir2D)
+      .describe("Sets The relative rotation of the Node to its parent.");
+
+  LoadParam(root, "abs-dir", this, Element2D, setAbsDir2D)
+      .describe("Sets The absolute rotation of the Node.");
+
+  LoadParam(root, "parent", this, Element2D, setParent2D)
+      .describe("the Name of the Parent of this Element2D");
+
+  LoadParam(root, "parent-mode", this, Element2D, setParentMode2D)
+      .describe("the mode to connect this node to its parent ()");
+
+  // cycling properties
+  LOAD_PARAM_START_CYCLE(root, element);
+  {
+    LoadParam_CYCLE(element, "child", this, Element2D, addChild2D)
+        .describe("adds a new Child to the current Node.");
+  }
+  LOAD_PARAM_END_CYCLE(element);
+}
+
+/**
+ * sets the alignment of the 2D-element in form of a String
+ * @param alignment the alignment @see loadParams
+*/
+void Element2D::setAlignment(const char* alignment)
+{
+  if (!strcmp(alignment, "center"))
+    this->setAlignment(E2D_ALIGN_CENTER);
+  else if (!strcmp(alignment, "left"))
+    this->setAlignment(E2D_ALIGN_LEFT);
+  else if (!strcmp(alignment, "right"))
+    this->setAlignment(E2D_ALIGN_RIGHT);
+  else if (!strcmp(alignment, "screen-center"))
+    this->setAlignment(E2D_ALIGN_SCREEN_CENTER);
+}
+
+
+/**
+ * moves a Element to another layer
+ * @param layer the Layer this is drawn on
+ */
+void Element2D::setLayer(E2D_LAYER layer)
+{
+  if (this->parent != NULL && this->parent->getLayer() > layer)
+  {
+    PRINTF(2)("Unable to set %s to layer %s, because it's parent(%s) is of higher layer %s\n",
+              this->getName(),
+              Element2D::layer2DToChar(layer),
+              this->parent->getName(),
+              Element2D::layer2DToChar(this->parent->getLayer()));
+    layer = this->parent->getLayer();
+  }
+  this->layer = layer;
+}
+
+/**
+ * sets the layer onto which this 2D-element is projected to.
+ * @param layer the layer @see loadParams @see Element2D::charToLayer2D(const char* layer)
+ */
+void Element2D::setLayer(const char* layer)
+{
+  this->setLayer(Element2D::charToLayer2D(layer));
+}
+
+
+/**
+ * @brief sets a node, this 2D-Element should be shown upon
+ * @param bindNode the name of the Node (should be existing)
+ */
+void Element2D::setBindNode(const char* bindNode)
+{
+  const PNode* tmpBindNode = dynamic_cast<const PNode*>(ClassList::getObject(bindNode, CL_PARENT_NODE));
+  if (tmpBindNode != NULL)
+    this->bindNode = tmpBindNode;
+}
+
+/**
+ * sets the relative coordinate of the Element2D to its parent
+ * @param relCoord the relative coordinate to the parent
+ */
+void Element2D::setRelCoor2D (const Vector& relCoord)
+{
+  if (this->toCoordinate!= NULL)
+  {
+    delete this->toCoordinate;
+    this->toCoordinate = NULL;
+  }
+  this->relCoordinate = relCoord;
+  this->bRelCoorChanged = true;
+}
+
+
+/**
+ * sets the relative coordinate of the Element2D to its Parent
+ * @param x the x coordinate
+ * @param y the y coordinate
+ * @param z the z coordinate
+ */
+void Element2D::setRelCoor2D (float x, float y, float z)
+{
+  this->setRelCoor2D(Vector(x,y,z));
+}
+
+/**
+ * sets the Relative coordinate to the parent in Pixels
+ * @param x the relCoord X
+ * @param y the relCoord Y
+ */
+void Element2D::setRelCoor2Dpx (int x, int y)
+{
+  this->setRelCoor2D(Vector((float)x/(float)GraphicsEngine::getInstance()->getResolutionX(),
+                     (float)y/(float)GraphicsEngine::getInstance()->getResolutionY(),
+                     0
+                           ));
+}
+
+/**
+ * sets a new relative position smoothely
+ * @param relCoordSoft the new Position to iterate to
+ * @param bias how fast to iterate to this position
+ */
+void Element2D::setRelCoorSoft2D(const Vector& relCoordSoft, float bias)
+{
+  if (likely(this->toCoordinate == NULL))
+    this->toCoordinate = new Vector();
+
+  *this->toCoordinate = relCoordSoft;
+  this->bias = bias;
+}
+
+/**
+ * sets a new relative position smoothely
+ * @param x the new x-coordinate in Pixels of the Position to iterate to
+ * @param y the new y-coordinate in Pixels of the Position to iterate to
+ * @param bias how fast to iterate to this position
+ */
+void Element2D::setRelCoorSoft2Dpx (int x, int y, float bias)
+{
+  this->setRelCoorSoft2D(Vector((float)x/(float)GraphicsEngine::getInstance()->getResolutionX(),
+                         (float)y/(float)GraphicsEngine::getInstance()->getResolutionY(),
+                         0),
+                         bias);
+}
+
+/**
+ * set relative coordinates smoothely
+ * @param x x-relative coordinates to its parent
+ * @param y y-relative coordinates to its parent
+ * @param z z-relative coordinates to its parent
+ * @see  void PNode::setRelCoorSoft (const Vector&, float)
+ */
+void Element2D::setRelCoorSoft2D(float x, float y, float depth, float bias)
+{
+  this->setRelCoorSoft2D(Vector(x, y, depth), bias);
+}
+
+/**
+ * @param absCoord set absolute coordinate
+ */
+void Element2D::setAbsCoor2D (const Vector& absCoord)
+{
+  if (this->toCoordinate!= NULL)
+  {
+    delete this->toCoordinate;
+    this->toCoordinate = NULL;
+  }
+
+  if( likely(this->parentMode & E2D_PARENT_MOVEMENT))
+  {
+    /* if you have set the absolute coordinates this overrides all other changes */
+    if (likely(this->parent != NULL))
+      this->relCoordinate = absCoord - parent->getAbsCoor2D ();
+    else
+      this->relCoordinate = absCoord;
+  }
+  if( this->parentMode & E2D_PARENT_ROTATE_MOVEMENT)
+  {
+    if (likely(this->parent != NULL))
+      this->relCoordinate = absCoord - parent->getAbsCoor2D ();
+    else
+      this->relCoordinate = absCoord;
+  }
+
+  this->bRelCoorChanged = true;
+}
+
+/**
+ * @param x x-coordinate.
+ * @param y y-coordinate.
+ * @param z z-coordinate.
+ * @see void PNode::setAbsCoor (const Vector& absCoord)
+ */
+void Element2D::setAbsCoor2D (float x, float y, float depth)
+{
+  this->setAbsCoor2D(Vector(x, y, depth));
+}
+
+/**
+ * @param x x-coordinate in Pixels
+ * @param y y-coordinate in Pixels
+ * @see void PNode::setAbsCoor (const Vector& absCoord)
+ */
+void Element2D::setAbsCoor2Dpx (int x, int y)
+{
+  this->setAbsCoor2D(Vector((float)x/(float)GraphicsEngine::getInstance()->getResolutionX(),
+                     (float)y/(float)GraphicsEngine::getInstance()->getResolutionY(),
+                     0
+                           ));
+}
+
+/**
+ * @param absCoordSoft set absolute coordinate
+ * @param bias how fast to iterato to the new Coordinate
+ */
+void Element2D::setAbsCoorSoft2D (const Vector& absCoordSoft, float bias)
+{
+  if (this->toCoordinate == NULL)
+    this->toCoordinate = new Vector();
+
+  if( likely(this->parentMode & E2D_PARENT_MOVEMENT))
+  {
+    /* if you have set the absolute coordinates this overrides all other changes */
+    if (likely(this->parent != NULL))
+      *this->toCoordinate = absCoordSoft - parent->getAbsCoor2D ();
+    else
+      *this->toCoordinate = absCoordSoft;
+  }
+  if( this->parentMode & E2D_PARENT_ROTATE_MOVEMENT)
+  {
+    if (likely(this->parent != NULL))
+      *this->toCoordinate = absCoordSoft - parent->getAbsCoor2D ();
+    else
+      *this->toCoordinate = absCoordSoft;
+  }
+
+  this->bias = bias;
+}
+
+/**
+ * @param x x-coordinate.
+ * @param y y-coordinate.
+ * @param z z-coordinate.
+ * @see void PNode::setAbsCoor (const Vector& absCoord)
+ */
+void Element2D::setAbsCoorSoft2D (float x, float y, float depth, float bias)
+{
+  this->setAbsCoorSoft2D(Vector(x, y, depth), bias);
+}
+
+/**
+ *  shift coordinate ralative
+ * @param shift shift vector
+ *
+ * This simply adds the shift-Vector to the relative Coordinate
+ */
+void Element2D::shiftCoor2D (const Vector& shift)
+{
+  this->relCoordinate += shift;
+  this->bRelCoorChanged = true;
+
+}
+
+/**
+ * shifts in PixelSpace
+ * @param x the pixels to shift in X
+ * @param y the pixels to shift in Y
+ */
+void Element2D::shiftCoor2Dpx (int x, int y)
+{
+  this->shiftCoor2D(Vector((float)x/(float)GraphicsEngine::getInstance()->getResolutionX(),
+                    (float)y/(float)GraphicsEngine::getInstance()->getResolutionY(),
+                     0));
+}
+
+/**
+ *  set relative direction
+ * @param relDir to its parent
+ */
+void Element2D::setRelDir2D (float relDir)
+{
+  if (this->toDirection!= NULL)
+  {
+    delete this->toDirection;
+    this->toDirection = NULL;
+  }
+
+  this->relDirection = relDir;
+  this->bRelDirChanged = true;
+}
+
+/**
+ * sets the Relative Direction of this node to its parent in a Smoothed way
+ * @param relDirSoft the direction to iterate to smoothely.
+ * @param bias how fast to iterate to the new Direction
+ */
+void Element2D::setRelDirSoft2D(float relDirSoft, float bias)
+{
+  if (likely(this->toDirection == NULL))
+    this->toDirection = new float;
+
+  *this->toDirection = relDirSoft;
+  this->bias = bias;
+}
+
+/**
+ *  sets the absolute direction
+ * @param absDir absolute coordinates
+ */
+void Element2D::setAbsDir2D (float absDir)
+{
+  if (this->toDirection!= NULL)
+  {
+    delete this->toDirection;
+    this->toDirection = NULL;
+  }
+
+  if (likely(this->parent != NULL))
+    this->relDirection = absDir - this->parent->getAbsDir2D();
+  else
+    this->relDirection = absDir;
+
+  this->bRelDirChanged = true;
+}
+
+/**
+ *  sets the absolute direction softly
+ * @param absDir absolute coordinates
+ */
+void Element2D::setAbsDirSoft2D (float absDirSoft, float bias)
+{
+  if (this->toDirection == NULL)
+    this->toDirection = new float;
+
+  if (likely(this->parent != NULL))
+    *this->toDirection = absDirSoft - this->parent->getAbsDir2D();
+  else
+    *this->toDirection = absDirSoft;
+
+  this->bias = bias;
+}
+
+/**
+ * shift Direction
+ * @param shift the direction around which to shift.
+ */
+void Element2D::shiftDir2D (float shiftDir)
+{
+  this->relDirection = this->relDirection + shiftDir;
+  this->bRelDirChanged = true;
+}
+
+/**
+ *  adds a child and makes this node to a parent
+ * @param child child reference
+ * @param parentMode on which changes the child should also change ist state
+ *
+ * use this to add a child to this node.
+ */
+void Element2D::addChild2D (Element2D* child)
+{
+  assert(child != NULL);
+  if( likely(child->parent != NULL))
+  {
+    PRINTF(5)("Element2D::addChild() - reparenting node: removing it and adding it again\n");
+    child->parent->eraseChild2D(child);
+  }
+  if (this->checkIntegrity(child))
+  {
+    child->parent = this;
+    if (likely(this != NULL))
+    {
+     // ELEMENT SORTING TO LAYERS  //
+     unsigned int childCount = this->children.size();
+
+     list<Element2D*>::iterator elem;
+     for (elem = this->children.begin(); elem != this->children.end(); elem++)
+     {
+       if ((*elem)->layer < child->layer)
+       {
+         this->children.insert(elem, child);
+         break;
+       }
+     }
+     if (childCount == this->children.size())
+       this->children.push_back(child);
+     ////////////////////////////////
+     if (unlikely(this->layer > child->getLayer()))
+     {
+       PRINTF(2)("Layer '%s' of Child(%s) lower than parents(%s) layer '%s'. updating...\n",
+       Element2D::layer2DToChar(child->getLayer()),child->getName(), this->getName(), Element2D::layer2DToChar(this->layer));
+       child->setLayer(this->layer);
+     }
+   }
+   else
+   {
+     PRINTF(1)("Tried to reparent2D to own child '%s::%s' to '%s::%s'.\n",
+              this->getClassName(), this->getName(), child->getClassName(), child->getName());
+     child->parent = NULL;
+   }
+  }
+  child->parentCoorChanged2D();
+}
+
+/**
+ * @see Element2D::addChild(Element2D* child);
+ * @param childName the name of the child to add to this PNode
+ */
+void Element2D::addChild2D (const char* childName)
+{
+  Element2D* childNode = dynamic_cast<Element2D*>(ClassList::getObject(childName, CL_ELEMENT_2D));
+  if (childNode != NULL)
+    this->addChild2D(childNode);
+}
+
+/**
+ * removes a child from the node
+ * @param child the child to remove from this Node..
+ *
+ * Children from nodes will not be lost, they are referenced to NullPointer
+ */
+void Element2D::removeChild2D (Element2D* child)
+{
+  if (child != NULL)
+    child->remove2D();
+}
+
+/**
+ * !! PRIVATE FUNCTION
+ * @brief reparents an Element2D (happens on Parents Node delete or remove and Flags are set.)
+ */
+void Element2D::reparent2D()
+{
+  if (this->parentMode & E2D_REPARENT_TO_NULL)
+    this->setParent2D((Element2D*)NULL);
+  else if (this->parentMode & E2D_REPARENT_TO_PARENTS_PARENT && this->parent != NULL)
+    this->setParent2D(this->parent->getParent2D());
+  else
+    this->setParent2D(Element2D::getNullElement());
+}
+
+
+/**
+ * @param child the child to be erased from this Nodes List
+ */
+void Element2D::eraseChild2D(Element2D* child)
+{
+  assert (this != NULL && child != NULL);
+  std::list<Element2D*>::iterator childIT = std::find(this->children.begin(), this->children.end(), child);
+  this->children.erase(childIT);
+}
+
+
+
+/**
+ * remove this Element from the tree and adds all children to NullElement2D
+ *
+ * afterwards this Node is free, and can be reattached, or deleted freely.
+ */
+void Element2D::remove2D()
+{
+  list<Element2D*>::iterator child = this->children.begin();
+  list<Element2D*>::iterator reparenter;
+  while (child != this->children.end())
+  {
+    reparenter = child;
+    child++;
+    if (this->parentMode & E2D_REPARENT_CHILDREN_ON_REMOVE ||
+        (*reparenter)->parentMode & E2D_REPARENT_ON_PARENTS_REMOVE)
+    {
+      printf("TEST----------------%s ---- %s\n", this->getClassName(), (*reparenter)->getClassName());
+      (*reparenter)->reparent2D();
+      printf("REPARENTED TO: %s::%s\n",(*reparenter)->getParent2D()->getClassName(),(*reparenter)->getParent2D()->getName());
+    }
+  }
+  if (this->parent != NULL)
+  {
+    this->parent->eraseChild2D(this);
+    this->parent = NULL;
+  }
+}
+
+
+/**
+ * @see Element2D::setParent(Element2D* parent);
+ * @param parentName the name of the Parent to set to this Element2D
+ */
+void Element2D::setParent2D (const char* parentName)
+{
+  Element2D* parentNode = dynamic_cast<Element2D*>(ClassList::getObject(parentName, CL_ELEMENT_2D));
+  if (parentNode != NULL)
+    parentNode->addChild2D(this);
+  else
+    PRINTF(2)("Not Found Element2D's (%s::%s) new Parent by Name: %s\n",
+                this->getClassName(), this->getName(), parentName);
+}
+
+/**
+ * does the reparenting in a very smooth way
+ * @param parentNode the new Node to connect this node to.
+ * @param bias the speed to iterate to this new Positions
+ */
+void Element2D::setParentSoft2D(Element2D* parentNode, float bias)
+{
+  if (this->parent == parentNode)
+    return;
+
+  if (likely(this->toCoordinate == NULL))
+  {
+    this->toCoordinate = new Vector();
+    *this->toCoordinate = this->getRelCoor2D();
+  }
+  if (likely(this->toDirection == NULL))
+  {
+    this->toDirection = new float;
+    *this->toDirection = this->getRelDir2D();
+  }
+  this->bias = bias;
+
+
+  Vector tmpV = this->getAbsCoor2D();
+  float tmpQ = this->getAbsDir2D();
+
+  parentNode->addChild2D(this);
+
+  if (this->parentMode & E2D_PARENT_ROTATE_MOVEMENT) //! @todo implement this.
+    ;//this->setRelCoor(this->parent->getAbsDir().inverse().apply(tmpV - this->parent->getAbsCoor()));
+  else
+    this->relCoordinate = (tmpV - parentNode->getAbsCoor2D());
+  this->bRelCoorChanged = true;
+
+  this->relDirection = (tmpQ - parentNode->getAbsDir2D());
+  this->bRelDirChanged = true;
+}
+
+/**
+ * does the reparenting in a very smooth way
+ * @param parentName the name of the Parent to reconnect to
+ * @param bias the speed to iterate to this new Positions
+ */
+void Element2D::setParentSoft2D(const char* parentName, float bias)
+{
+  Element2D* parentNode = dynamic_cast<Element2D*>(ClassList::getObject(parentName, CL_ELEMENT_2D));
+  if (parentNode != NULL)
+    this->setParentSoft2D(parentNode, bias);
+}
+
+/**
+ * @param parentMode sets the parentingMode of this Node
+ */
+void Element2D::setParentMode2D(E2D_PARENT_MODE parentMode)
+{
+  this->parentMode = ((this->parentMode & 0xfff0) | parentMode);
+}
+
+
+/**
+ * @brief sets the mode of this parent manually
+ * @param parentMode a String representing this parentingMode
+ */
+void Element2D::setParentMode2D (const char* parentingMode)
+{
+  this->setParentMode2D(Element2D::charToParentingMode2D(parentingMode));
+}
+
+
+/**
+ * @returns the NullElement (and if needed (most probably) creates it)
+ */
+Element2D* Element2D::createNullElement()
+{
+  if (likely(Element2D::nullElement == NULL))
+  {
+    Element2D::nullElement = new Element2D(NULL, E2D_LAYER_BELOW_ALL, E2D_PARENT_MODE_DEFAULT | E2D_REPARENT_TO_NULL);
+    Element2D::nullElement->setName("NullElement");
+  }
+  return Element2D::nullElement;
+}
+
+
+/**
+ * !! PRIVATE FUNCTION
+ * @brief checks the upward integrity (e.g if Element2D is somewhere up the Node tree.)
+ * @param checkParent the Parent to check.
+ * @returns true if the integrity-check succeeds, false otherwise.
+ *
+ * If there is a second occurence of checkParent before NULL, then a loop could get
+ * into the Tree, and we do not want this.
+ */
+bool Element2D::checkIntegrity(const Element2D* checkParent) const
+{
+  const Element2D* parent = this;
+  while ( (parent = parent->getParent2D()) != NULL)
+    if (unlikely(parent == checkParent))
+      return false;
+  return true;
+}
+
+
+/**
+ *  updates the absCoordinate/absDirection
+ * @param dt The time passed since the last update
+
+   this is used to go through the parent-tree to update all the absolute coordinates
+   and directions. this update should be done by the engine, so you don't have to
+   worry, normaly...
+ */
+void Element2D::update2D (float dt)
+{
+  // setting the Position of this 2D-Element.
+  if( likely(this->parent != NULL))
+  {
+      // movement for nodes with smoothMove enabled
+    if (unlikely(this->toCoordinate != NULL))
+    {
+      Vector moveVect = (*this->toCoordinate - this->relCoordinate) *fabsf(dt)*bias;
+
+      if (likely(moveVect.len() >= .001))//PNODE_ITERATION_DELTA))
+      {
+        this->shiftCoor2D(moveVect);
+      }
+      else
+      {
+        Vector tmp = *this->toCoordinate;
+        this->setRelCoor2D(tmp);
+        PRINTF(5)("SmoothMove of %s finished\n", this->getName());
+      }
+    }
+    if (unlikely(this->toDirection != NULL))
+    {
+      float rotFlot = (*this->toDirection - this->relDirection) *fabsf(dt)*bias;
+      if (likely(fabsf(rotFlot) >= .001))//PNODE_ITERATION_DELTA))
+      {
+        this->shiftDir2D(rotFlot);
+      }
+      else
+      {
+        float tmp = *this->toDirection;
+        this->setRelDir2D(tmp);
+        PRINTF(5)("SmoothRotate of %s finished\n", this->getName());
+      }
+    }
+
+    // MAIN UPDATE /////////////////////////////////////
+    this->lastAbsCoordinate = this->absCoordinate;
+
+    PRINTF(5)("Element2D::update - %s - (%f, %f, %f)\n", this->getName(), this->absCoordinate.x, this->absCoordinate.y, this->absCoordinate.z);
+
+
+    if( this->parentMode & E2D_PARENT_LOCAL_ROTATE && this->bRelDirChanged)
+    {
+      /* update the current absDirection - remember * means rotation around sth.*/
+      this->prevRelDirection = this->relDirection;
+      this->absDirection = this->relDirection + parent->getAbsDir2D();;
+    }
+
+
+    if (unlikely(this->alignment & E2D_ALIGN_SCREEN_CENTER && this->bRelCoorChanged))
+    {
+      this->prevRelCoordinate = this->relCoordinate;
+      this->absCoordinate.x = .5 + this->relCoordinate.x;
+      this->absCoordinate.y = .5 + this->relCoordinate.y;
+      this->absCoordinate.z = 0.0;
+    }
+    else if (unlikely(this->bindNode != NULL))
+    {
+      GLdouble projectPos[3] = {0, 0, 0};
+      gluProject(this->bindNode->getAbsCoor().x,
+                 this->bindNode->getAbsCoor().y,
+                 this->bindNode->getAbsCoor().z,
+                 GraphicsEngine::modMat,
+                 GraphicsEngine::projMat,
+                 GraphicsEngine::viewPort,
+                 projectPos,
+                 projectPos+1,
+                 projectPos+2);
+      this->prevRelCoordinate.x = this->absCoordinate.x = projectPos[0] /* /(float)GraphicsEngine::getInstance()->getResolutionX() */ + this->relCoordinate.x;
+      this->prevRelCoordinate.y = this->absCoordinate.y = (float)GraphicsEngine::getInstance()->getResolutionY() -  projectPos[1] + this->relCoordinate.y;
+      this->prevRelCoordinate.z = this->absCoordinate.z = projectPos[2] + this->relCoordinate.z;
+      this->bRelCoorChanged = true;
+    }
+    else
+    {
+      if(likely(this->parentMode & PNODE_MOVEMENT && this->bRelCoorChanged))
+      {
+        /* update the current absCoordinate */
+        this->prevRelCoordinate = this->relCoordinate;
+        this->absCoordinate = this->parent->getAbsCoor2D() + this->relCoordinate;
+      }
+      else if( this->parentMode & PNODE_ROTATE_MOVEMENT && this->bRelCoorChanged)
+      {
+        /* update the current absCoordinate */
+        this->prevRelCoordinate = this->relCoordinate;
+        float sine = sin(this->parent->getAbsDir2D());
+        float cose = cos(this->parent->getAbsDir2D());
+//        this->absCoordinate.x = this->relCoordinate.x*cose - this->relCoordinate.y*sine + this->parent->getRelCoor2D().x*(1-cose) +this->parent->getRelCoor2D().y*sine;
+//        this->absCoordinate.y = this->relCoordinate.x*sine + this->relCoordinate.y*cose + this->parent->getRelCoor2D().y*(1-cose) +this->parent->getRelCoor2D().x*sine;
+
+        this->absCoordinate.x = this->parent->getAbsCoor2D().x + (this->relCoordinate.x*cos(this->parent->getAbsDir2D()) - this->relCoordinate.y * sin(this->parent->getAbsDir2D()));
+        this->absCoordinate.y = this->parent->getAbsCoor2D().y + (this->relCoordinate.x*sin(this->parent->getAbsDir2D()) + this->relCoordinate.y * cos(this->parent->getAbsDir2D()));
+
+      }
+    }
+    /////////////////////////////////////////////////
+  }
+  else
+  {
+    PRINTF(5)("Element2D::update - (%f, %f, %f)\n", this->absCoordinate.x, this->absCoordinate.y, this->absCoordinate.z);
+    if (this->bRelCoorChanged)
+    {
+      this->prevRelCoordinate = this->relCoordinate;
+      this->absCoordinate = this->relCoordinate;
+    }
+    if (this->bRelDirChanged)
+    {
+      this->prevRelDirection = this->relDirection;
+      this->absDirection = this->getAbsDir2D() + this->relDirection;
+    }
+  }
+
+
+  // UPDATE CHILDREN
+  if(!this->children.empty() || this->parentMode & E2D_UPDATE_CHILDREN_IF_INACTIVE)
+  {
+    list<Element2D*>::iterator child;
+    for (child = this->children.begin(); child != this->children.end(); child++)
+    {
+      /* if this node has changed, make sure, that all children are updated also */
+      if( likely(this->bRelCoorChanged))
+        (*child)->parentCoorChanged2D();
+      if( likely(this->bRelDirChanged))
+        (*child)->parentDirChanged2D();
+
+      (*child)->update2D(dt);
+    }
+  }
+
+  // FINISHING PROCESS
+  this->velocity = (this->absCoordinate - this->lastAbsCoordinate) / dt;
+  this->bRelCoorChanged = false;
+  this->bRelDirChanged = false;
+}
+
+
+/**
+ *  displays some information about this pNode
+ * @param depth The deph into which to debug the children of this Element2D to.
+ * (0: all children will be debugged, 1: only this Element2D, 2: this and direct children...)
+ * @param level The n-th level of the Node we draw (this is internal and only for nice output)
+ */
+void Element2D::debug (unsigned int depth, unsigned int level) const
+{
+  for (unsigned int i = 0; i < level; i++)
+    PRINT(0)(" |");
+  if (this->children.size() > 0)
+    PRINT(0)(" +");
+  else
+    PRINT(0)(" -");
+  PRINT(0)("Element2D(%s::%s) - absCoord: (%0.2f, %0.2f), relCoord(%0.2f, %0.2f), direction(%0.2f) - %s, layer:%s\n",
+            this->getClassName(),
+            this->getName(),
+            this->absCoordinate.x,
+            this->absCoordinate.y,
+            this->relCoordinate.x,
+            this->relCoordinate.y,
+            this->getAbsDir2D(),
+            Element2D::parentingModeToChar2D(parentMode),
+            Element2D::layer2DToChar(this->layer));
+
+  if (depth >= 2 || depth == 0)
+  {
+    list<Element2D*>::const_iterator child;
+    for (child = this->children.begin(); child != this->children.end(); child++)
+    {
+      if (depth == 0)
+        (*child)->debug(0, level + 1);
+      else
+        (*child)->debug(depth - 1, level +1);
+    }
+  }
+}
+
+/**
+ * ticks the 2d-Element
+ * @param dt the time elapsed since the last tick
+ *
+ * the element only gets tickt, if it is active.
+ * Be aware, that this walks through the entire Element2D-tree,
+ * searching for Elements to be ticked.
+ */
+void Element2D::tick2D(float dt)
+{
+  if (this->bActive)
+    this->tick(dt);
+  if (this->children.size() > 0)
+  {
+    list<Element2D*>::iterator child;
+    for (child = this->children.begin(); child != this->children.end(); child++)
+      (*child)->tick2D(dt);
+  }
+}
+
+/**
+ * draws all the Elements from this element2D downwards
+ * @param layer the maximal Layer to draw. @see E2D_LAYER
+ */
+void Element2D::draw2D(short layer) const
+{
+  if (this->bVisible)
+    this->draw();
+  if (this->children.size() > 0)
+  {
+    list<Element2D*>::const_iterator child;
+    for (child = this->children.begin(); child != this->children.end(); child++)
+      if (likely(layer >= this->layer))
+        (*child)->draw2D(layer);
+  }
+}
+
+/**
+ * displays the Element2D at its position with its rotation as a Plane.
+ */
+void Element2D::debugDraw2D(unsigned int depth, float size, Vector color, unsigned int level) const
+{
+  if (level == 0)
+  {
+    glPushAttrib(GL_ENABLE_BIT);
+    glMatrixMode(GL_MODELVIEW);
+
+    glDisable(GL_LIGHTING);
+    glDisable(GL_BLEND);
+    glDisable(GL_TEXTURE_2D);
+  }
+
+  glPushMatrix();
+  /* translate */
+  /* rotate */
+  glColor3f(color.x, color.y, color.z);
+
+  glTranslatef (this->getAbsCoor2D().x, this->getAbsCoor2D().y, 0);
+  glRotatef(this->getAbsDir2D(), 0,0,1);
+  glBegin(GL_LINE_LOOP);
+  glVertex2f(0, 0);
+  glVertex2f(0, +this->getSizeY2D());
+  glVertex2f(+this->getSizeX2D(), +this->getSizeY2D());
+  glVertex2f(+this->getSizeX2D(), 0);
+  glEnd();
+
+
+  glPopMatrix();
+  if (depth >= 2 || depth == 0)
+  {
+    Vector childColor =  Color::HSVtoRGB(Color::RGBtoHSV(color)+Vector(20,0,.0));
+    list<Element2D*>::const_iterator child;
+    for (child = this->children.begin(); child != this->children.end(); child++)
+    {
+      // drawing the Dependency graph
+      if (this != Element2D::getNullElement())
+      {
+        glBegin(GL_LINES);
+        glColor3f(color.x, color.y, color.z);
+        glVertex3f(this->getAbsCoor2D ().x,
+                   this->getAbsCoor2D ().y,
+                   0);
+        glColor3f(childColor.x, childColor.y, childColor.z);
+        glVertex3f((*child)->getAbsCoor2D ().x,
+                   (*child)->getAbsCoor2D ().y,
+                   0);
+        glEnd();
+      }
+      if (depth == 0)
+        (*child)->debugDraw2D(0, size, childColor, level+1);
+      else
+        (*child)->debugDraw2D(depth - 1, size, childColor, level +1);
+    }
+  }
+  if (level == 0)
+    glPopAttrib();
+
+}
+
+
+// helper functions //
+/**
+ * converts a parentingMode into a string that is the name of it
+ * @param parentingMode the ParentingMode to convert
+ * @return the converted string
+ */
+const char* Element2D::parentingModeToChar2D(int parentingMode)
+{
+  if (parentingMode == E2D_PARENT_LOCAL_ROTATE)
+    return "local-rotate";
+  else if (parentingMode == E2D_PARENT_ROTATE_MOVEMENT)
+    return "rotate-movement";
+  else if (parentingMode == E2D_PARENT_MOVEMENT)
+    return "movement";
+  else if (parentingMode == E2D_PARENT_ALL)
+    return "all";
+  else if (parentingMode == E2D_PARENT_ROTATE_AND_MOVE)
+    return "rotate-and-move";
+}
+
+/**
+ * converts a parenting-mode-string into a int
+ * @param parentingMode the string naming the parentingMode
+ * @return the int corresponding to the named parentingMode
+ */
+E2D_PARENT_MODE Element2D::charToParentingMode2D(const char* parentingMode)
+{
+  if (!strcmp(parentingMode, "local-rotate"))
+    return (E2D_PARENT_LOCAL_ROTATE);
+  else  if (!strcmp(parentingMode, "rotate-movement"))
+    return (E2D_PARENT_ROTATE_MOVEMENT);
+  else  if (!strcmp(parentingMode, "movement"))
+    return (E2D_PARENT_MOVEMENT);
+  else  if (!strcmp(parentingMode, "all"))
+    return (E2D_PARENT_ALL);
+  else  if (!strcmp(parentingMode, "rotate-and-move"))
+    return (E2D_PARENT_ROTATE_AND_MOVE);
+}
+
+/**
+ * converts a layer into its corresponding string
+ * @param layer the layer to get the name-String of.
+ * @returns the Name of the Layer (on error the default-layer-string is returned)
+ */
+const char* Element2D::layer2DToChar(E2D_LAYER layer)
+{
+  switch(layer)
+  {
+    case E2D_LAYER_TOP:
+      return "top";
+      break;
+    case E2D_LAYER_MEDIUM:
+      return "medium";
+      break;
+    case E2D_LAYER_BOTTOM:
+      return "bottom";
+      break;
+    case E2D_LAYER_BELOW_ALL:
+      return "below-all";
+      break;
+    default:
+      return layer2DToChar(E2D_DEFAULT_LAYER);
+      break;
+  }
+}
+
+/**
+ * converts a String holding a actual Layer
+ * @param layer the String to convert into a Layer2D
+ * @returns the E2D_LAYER on success, E2D_DEFAULT_LAYER on error.
+ */
+E2D_LAYER Element2D::charToLayer2D(const char* layer)
+{
+  if (!strcmp(layer, "top"))
+    return (E2D_LAYER_TOP);
+  else  if (!strcmp(layer, "medium"))
+    return (E2D_LAYER_MEDIUM);
+  else  if (!strcmp(layer, "bottom"))
+    return (E2D_LAYER_BOTTOM);
+  else  if (!strcmp(layer, "below-all"))
+    return (E2D_LAYER_BELOW_ALL);
+  else
+    return (E2D_DEFAULT_LAYER);
+}
Index: branches/network/src/lib/graphics/render2D/element_2d.h
===================================================================
--- branches/network/src/lib/graphics/render2D/element_2d.h	(revision 6636)
+++ branches/network/src/lib/graphics/render2D/element_2d.h	(revision 6636)
@@ -0,0 +1,269 @@
+/*!
+ * @file element_2d.h
+ * Definition of the 2D elements rendered on top of all other stuff.
+ */
+
+#ifndef _ELEMENT_2D_H
+#define _ELEMENT_2D_H
+
+#include "base_object.h"
+
+#include "vector.h"
+#include <list>
+
+// FORWARD DECLARATION
+class PNode;
+class TiXmlElement;
+
+//!< An enumerator defining the Depth of a 2D-element.
+typedef enum
+{
+  E2D_LAYER_BELOW_ALL           =     0,        //!< Will be rendered below the 3D-scene. @todo make this work.
+  E2D_LAYER_BOTTOM              =     1,        //!< Will be rendered on the bottom Layer
+  E2D_LAYER_MEDIUM              =     2,        //!< Will be rendered on the medium Layer.
+  E2D_LAYER_TOP                 =     3,        //!< Will be rendered on top of everything else
+
+  E2D_LAYER_COUNT               =     4,         //!< The count of Layers.
+} E2D_LAYER;
+#define E2D_DEFAULT_LAYER       E2D_LAYER_MEDIUM
+#define E2D_LAYER_ALL           4
+
+typedef enum
+{
+  E2D_ALIGN_NONE                =     0,
+  E2D_ALIGN_LEFT                =     1,
+  E2D_ALIGN_RIGHT               =     2,
+  E2D_ALIGN_CENTER              =     4,
+  E2D_ALIGN_SCREEN_CENTER       =     8
+} E2D_ALIGNMENT;
+
+typedef enum
+{
+  E2D_PARENT_NONE                    = 0x0000,
+  E2D_PARENT_LOCAL_ROTATE            = 0x0001,    //!< Rotates all the children around their centers.
+  E2D_PARENT_ROTATE_MOVEMENT         = 0x0002,    //!< Moves all the children around the center of their parent, without the rotation around their own centers.
+
+  E2D_PARENT_MOVEMENT                = 0x0004,    //!< Moves all children along with the parent.
+// special linkage modes
+  E2D_PARENT_ALL                     = 0x0003,    //!< Moves all children around the center of their parent, and also rotates their centers
+  E2D_PARENT_ROTATE_AND_MOVE         = 0x0005,    //!< Rotates all children around their axis, and moves them as the Parent Moves, but does not rotate around the center of their parent.
+
+
+  // REPARENTING
+  E2D_REPARENT_TO_NULL               = 0x0010,    //!< Reparents to the Null, if the Parent is Removed. Meaning the Node wont have a parent anymore.
+  E2D_REPARENT_TO_PARENTS_PARENT     = 0x0020,    //!< Reparents the Node to the parents (old) parent it the parent gets removed.
+  /////////////////////////////////////////////   //  ELSE: Reparents to the NullParent.
+  E2D_REPARENT_DELETE_CHILDREN       = 0x0040,    //!< Deletes the Children of the node when This Node is Removed. (Use with care).
+  /// FIXME
+   E2D_REPARENT_KEEP_POSITION         = 0x0080,   //!< Tries to keep the Position if the Node is reparented.
+
+
+  // DELETION
+  E2D_PROHIBIT_CHILD_DELETE          = 0x0100,    //!< Prohibits the Children from being deleted if this Node gets deleted.
+  E2D_PROHIBIT_DELETE_WITH_PARENT    = 0x0200,    //!< Prohibits the Node to be deleted if the Parent is. Child will be reparented according to the Repaenting-Rules
+  E2D_REPARENT_CHILDREN_ON_REMOVE    = 0x0400,    //!< Reparents the Children of the Node if the Node gets Removed.
+  E2D_REPARENT_ON_PARENTS_REMOVE     = 0x0800,    //!< The Node gets Reparented if its Parent gets removed. Child will be reparented according to the Reparenting-Rules.
+
+  // VISIBILITY/ACTIVITY
+  E2D_HIDE_CHILDREN_IF_HIDDEN        = 0x1000,    //!< Prohibits the Children from being drawn if this node isn't visible. (used for Draw))
+  E2D_HIDE_IF_PARENT_HIDDEN          = 0x2000,    //!< Prohibits the node from being drawn if the Parent is invisible.
+  E2D_UPDATE_CHILDREN_IF_INACTIVE    = 0x4000,    //!< Updates the Children of this Node even if the Parent is Inactive (note if this's parent is inactive children won't be updated.)
+  E2D_STATIC_NODE                    = 0x8000,    //!< Used for nodes that do not have any moving children, and that do not move.
+
+} E2D_PARENT_MODE;
+#define     E2D_PARENT_MODE_DEFAULT     E2D_PARENT_ALL | \
+					E2D_REPARENT_KEEP_POSITION
+
+//! A class for 2D-elements
+/**
+ * this class mainly tries to imitate PNode in its functionality, but on a 2D-level
+ * it extends PNode in the Sense of the tick-ability/draw-alility layering (and size)
+ *
+ * Layering: Layers are sorted into the Tree. e.g:
+ * the roor is in the lowest Layer, the leaves in the highest (of each branche)
+ * the first child of each node is in the lowest layer of all children, the last in the highest
+ * -> the tree is sorted on insertion of a new Child: @see Element2D::addChild2D()
+ */
+class Element2D : virtual public BaseObject {
+
+  public:
+    Element2D(Element2D* parent = Element2D::getNullElement(), E2D_LAYER layer = E2D_DEFAULT_LAYER, short nodeFlags = E2D_PARENT_MODE_DEFAULT);
+    virtual ~Element2D();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    // ACTIVATION //
+    inline void activate2D() { this->bActive = this->bRelCoorChanged = this->bRelDirChanged = true; };
+    inline void deactivate2D() { this->bActive = false; };
+    inline bool get2DActiveState() { return this->bActive; };
+
+    // ALIGNMENT //
+    /** @param alignment the new Alignment of the 2D-Element */
+    inline void setAlignment(E2D_ALIGNMENT alignment) { this->alignment = alignment; };
+    void setAlignment(const char* alignment);
+    inline E2D_ALIGNMENT getAlignment() const { return this->alignment; };
+
+    // LAYERING //
+    void setLayer(E2D_LAYER layer);
+    void setLayer(const char* layer);
+    /** @returns the Layer this Element is drawn to */
+    inline E2D_LAYER getLayer() const { return this->layer; };
+
+    // VISIBILITY //
+    /** @param visible true if the Element should be visible false otherwise (will not be rendered) */
+    inline void setVisibility(bool visible) { this->bVisible = visible; };
+    /** @returns the visibility state */
+    inline bool isVisible() { return this->bVisible; };
+
+
+    // POSITIONAL (E2D-specials) //
+    /** @param bindNode the Node this 2D-element should follow. if NULL the Element will not follow anything */
+    inline void setBindNode(const PNode* bindNode) { this->bindNode = bindNode; };
+    void setBindNode(const char* bindNode);
+    inline const PNode* getBindNode() const { return this->bindNode; };
+
+    inline void setSize2D(float x, float y) { this->sizeX = x, this->sizeY = y; };
+    inline void setSizeX2D(float x) { this->sizeX = x; };
+    inline void setSizeY2D(float y) { this->sizeY = y; };
+    inline float getSizeX2D() const { return this->sizeX; };
+    inline float getSizeY2D() const { return this->sizeY; };
+
+  public:
+    virtual void tick(float dt) {};
+    virtual void draw() const  {};
+    void tick2D(float dt);
+    void draw2D(short layer) const;
+
+    // LIKE PNODE
+  public:
+    void setRelCoor2D (const Vector& relCoord);
+    void setRelCoor2D (float x, float y, float dontCare = 1.0);
+    void setRelCoor2Dpx (int x, int y);
+    void setRelCoorSoft2D (const Vector& relCoordSoft, float bias = 1.0);
+    void setRelCoorSoft2D (float x, float y, float dontCare = 1.0, float bias = 1.0);
+    void setRelCoorSoft2Dpx (int x, int y, float bias = 1.0);
+    /** @returns the relative position */
+    inline const Vector& getRelCoor2D () const { return this->prevRelCoordinate; };
+    /** @returns the Relative Coordinate Destination */
+    inline const Vector& getRelCoorSoft2D() const { return (this->toCoordinate)?*this->toCoordinate:this->relCoordinate; };
+    const Vector& getRelCoor2Dpx() const;
+    void setAbsCoor2D (const Vector& absCoord);
+    void setAbsCoor2D (float x, float y, float depth = 1.0);
+    void setAbsCoor2Dpx (int x, int y);
+    void setAbsCoorSoft2D (const Vector& absCoordSoft, float bias = 1.0);
+    void setAbsCoorSoft2D (float x, float y, float depth = 1.0, float bias = 1.0);
+    /** @returns the absolute position */
+    inline const Vector& getAbsCoor2D () const { return this->absCoordinate; };
+    const Vector& getAbsCoor2Dpx () const;
+
+    void shiftCoor2D (const Vector& shift);
+    void shiftCoor2Dpx (int x, int y);
+
+    void setRelDir2D (float relDir);
+    void setRelDirSoft2D(float relDirSoft, float bias = 1.0);
+    /** @returns the relative Direction */
+    inline float getRelDir2D () const { return this->prevRelDirection; };
+    /** @returns the Relative Directional Destination */
+    inline float getRelDirSoft2D() const { return (this->toDirection)?*this->toDirection:this->relDirection; };
+    void setAbsDir2D (float absDir);
+    void setAbsDirSoft2D (float absDirSoft, float bias = 1.0);
+    /** @returns the absolute Direction */
+    inline float getAbsDir2D () const { return this->absDirection; };
+    void shiftDir2D (float shiftDir);
+
+    /** @returns the Speed of the Node */
+    inline float getSpeed() const { return 0; };
+    /** @returns the Velocity of the Node */
+    inline const Vector& getVelocity() const { return this->velocity; };
+
+
+    void addChild2D (Element2D* child);
+    void addChild2D (const char* childName);
+    void removeChild2D (Element2D* child);
+    void remove2D();
+
+    /** @param parent the new parent of this Element2D */
+    void setParent2D (Element2D* parent) { parent->addChild2D(this); };
+    void setParent2D (const char* parentName);
+    /** @returns the parent of this Element2D */
+    inline Element2D* getParent2D () const { return this->parent; };
+    /** @returns the List of Children of this Element2D */
+    inline const std::list<Element2D*>& getChildren2D() const { return this->children; };
+
+    void setParentSoft2D(Element2D* parentNode, float bias = 1.0);
+    void setParentSoft2D(const char* parentName, float bias = 1.0);
+
+    void setParentMode2D (E2D_PARENT_MODE parentMode);
+    void setParentMode2D (const char* parentingMode);
+    /** @returns the Parenting mode of this node */
+    int getParentMode2D() const { return this->parentMode; };
+
+    // NULL_PARENT //
+    /** @returns the NullParent, the (main) ROOT of the PNode Tree. If it does not yet exist, it will be created. */
+    static Element2D* getNullElement()  { return (Element2D::nullElement != NULL)? Element2D::nullElement : Element2D::createNullElement(); };
+
+
+    void update2D (float dt);
+
+    void debug (unsigned int depth = 1, unsigned int level = 0) const;
+    void debugDraw2D(unsigned int depth = 1, float size = 1.0, Vector color = Vector(1,0,0), unsigned int level = 0) const;
+
+    // helper functions //
+    static const char* parentingModeToChar2D(int parentingMode);
+    static E2D_PARENT_MODE charToParentingMode2D(const char* parentingMode);
+
+    static const char* layer2DToChar(E2D_LAYER layer);
+    static E2D_LAYER charToLayer2D(const char* layer);
+
+  private:
+    void eraseChild2D(Element2D* child);
+    /** tells the child that the parent's Coordinate has changed */
+    inline void parentCoorChanged2D () { this->bRelCoorChanged = true; }
+    /** tells the child that the parent's Direction has changed */
+    inline void parentDirChanged2D () { this->bRelDirChanged = true; }
+    /** @returns the last calculated coordinate */
+    inline Vector getLastAbsCoor2D() { return this->lastAbsCoordinate; }
+
+    void reparent2D();
+    static Element2D* createNullElement();
+    bool checkIntegrity(const Element2D* checkParent) const;
+
+
+  private:
+    const PNode*            bindNode;           //!< a node over which to display this 2D-element
+    float                   sizeX;              //!< The size of the rendered item in x-direction
+    float                   sizeY;              //!< The size of the rendered Item in y-direction
+
+    E2D_ALIGNMENT           alignment;          //!< How the Element is aligned around its Position
+
+    bool                    bVisible;            //!< If the given Element2D is visible.
+    bool                    bActive;             //!< If the given Element2D is active.
+    E2D_LAYER               layer;              //!< What layer this Element2D is on.
+
+    bool                    bRelCoorChanged;    //!< If Relative Coordinate has changed since last time we checked
+    bool                    bRelDirChanged;     //!< If Relative Direction has changed since last time we checked
+
+    Vector                  relCoordinate;      //!< coordinates relative to the parent
+    Vector                  absCoordinate;      //!< absolute coordinates in the world ( from (0,0,0) )
+    float                   relDirection;       //!< direction relative to the parent
+    float                   absDirection;       //!< absolute diretion in the world ( from (0,0,1) )
+
+    Vector                  prevRelCoordinate;  //!< The last Relative Coordinate from the last update-Cycle.
+    Vector                  lastAbsCoordinate;  //!< this is used for speedcalculation, it stores the last coordinate
+    float                   prevRelDirection;   //!< The last Relative Direciton from the last update-Cycle.
+
+    Vector                  velocity;           //!< Saves the velocity.
+
+    Vector*                 toCoordinate;       //!< a position to which to iterate. (This is used in conjunction with setParentSoft.and set*CoorSoft)
+    float*                  toDirection;        //!< a direction to which to iterate. (This is used in conjunction with setParentSoft and set*DirSoft)
+    float                   bias;               //!< how fast to iterate to the given position (default is 1)
+
+    Element2D*              parent;             //!< a pointer to the parent node
+    std::list<Element2D*>   children;           //!< list of the children of this Element2D
+
+    unsigned int            parentMode;         //!< the mode of the binding
+
+    static Element2D*       nullElement;        //!< The top-most Element
+};
+
+#endif /* _ELEMENT_2D_H */
Index: branches/network/src/lib/graphics/render2D/render_2d.cc
===================================================================
--- branches/network/src/lib/graphics/render2D/render_2d.cc	(revision 6636)
+++ branches/network/src/lib/graphics/render2D/render_2d.cc	(revision 6636)
@@ -0,0 +1,89 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "render_2d.h"
+
+#include "graphics_engine.h"
+#include "class_list.h"
+#include "element_2d.h"
+
+#include <math.h>
+
+#include "shell_command.h"
+SHELL_COMMAND(toggleNodeVisibility, Render2D, toggleNodesVisibility);
+
+using namespace std;
+
+/**
+ * standard constructor
+ */
+Render2D::Render2D ()
+{
+   this->setClassID(CL_RENDER_2D, "Render2D");
+   this->setName("Render2D");
+
+   this->showNodes = false;
+}
+
+/**
+ *  the singleton reference to this class
+ */
+Render2D* Render2D::singletonRef = NULL;
+
+/**
+ * standard deconstructor
+ */
+Render2D::~Render2D ()
+{
+  delete Element2D::getNullElement();
+
+  Render2D::singletonRef = NULL;
+}
+
+/**
+ * updates all the 2d-elements
+ * @param dt the timestep since last dt
+ */
+void Render2D::update(float dt)
+{
+  Element2D::getNullElement()->update2D(dt);
+}
+
+
+/**
+ * ticks all the 2d-elements
+ * @param dt the timestep since last dt
+ */
+void Render2D::tick(float dt)
+{
+  Element2D::getNullElement()->tick2D(dt);
+}
+
+/**
+ * renders all the Elements of the Render2D-engine's layer
+ * @param layer the Layer to draw (if E2D_LAYER_ALL then all layers will be drawn)
+ */
+void Render2D::draw(short layer) const
+{
+  GraphicsEngine::enter2DMode();
+  Element2D::getNullElement()->draw2D(E2D_LAYER_ALL);
+  if (this->showNodes)
+    Element2D::getNullElement()->debugDraw2D(0);
+  GraphicsEngine::leave2DMode();
+}
+
+
Index: branches/network/src/lib/graphics/render2D/render_2d.h
===================================================================
--- branches/network/src/lib/graphics/render2D/render_2d.h	(revision 6636)
+++ branches/network/src/lib/graphics/render2D/render_2d.h	(revision 6636)
@@ -0,0 +1,35 @@
+/*!
+ * @file render_2d.h
+ * @brief Definition of the 2D-rendering engine singleton Class
+ */
+
+#ifndef _RENDER_2D_H
+#define _RENDER_2D_H
+
+#include "base_object.h"
+#include "element_2d.h"
+// FORWARD DECLARATION
+
+//! A default singleton class.
+class Render2D : public BaseObject {
+  friend class Element2D;
+
+  public:
+    virtual ~Render2D();
+    /** @returns a Pointer to the only object of this Class */
+    inline static Render2D* getInstance() { if (!singletonRef) singletonRef = new Render2D();  return singletonRef; };
+
+    void toggleNodesVisibility() { this->showNodes = !this->showNodes; };
+
+    void update(float dt);
+    void tick(float dt);
+    void draw(short layer) const;
+
+  private:
+    Render2D();
+    static Render2D*              singletonRef;                    //!< Reference to this class.
+
+    bool                          showNodes;                       //!< If the debug-Nodes should be visible
+ };
+
+#endif /* _RENDER_2D_H */
Index: branches/network/src/lib/graphics/shader.cc
===================================================================
--- branches/network/src/lib/graphics/shader.cc	(revision 6636)
+++ branches/network/src/lib/graphics/shader.cc	(revision 6636)
@@ -0,0 +1,315 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "shader.h"
+
+#include "stdlibincl.h"
+#include "compiler.h"
+#include <stdio.h>
+#include "debug.h"
+#include "array.h"
+
+#include "resource_manager.h"
+
+
+#ifndef PARSELINELENGHT
+#define PARSELINELENGHT     512       //!< how many chars to read at once
+#endif
+
+using namespace std;
+
+
+/**
+ * standard constructor
+*/
+Shader::Shader (const char* vertexShaderFile, const char* fragmentShaderFile)
+{
+   this->setClassID(CL_SHADER, "Shader");
+
+   this->fragmentShaderFile = NULL;
+   this->vertexShaderFile = NULL;
+   this->shaderProgram = 0;
+   this->vertexShader = 0;
+   this->fragmentShader = 0;
+
+   if (GLEW_ARB_shader_objects && GLEW_ARB_shading_language_100)
+     {
+       GLint status = 0;
+
+       this->shaderProgram = glCreateProgramObjectARB();
+
+       if (vertexShaderFile != NULL)
+         this->loadShaderProgramm(SHADER_VERTEX, vertexShaderFile);
+       if (fragmentShaderFile != NULL)
+         this->loadShaderProgramm(SHADER_FRAGMENT, fragmentShaderFile);
+       glLinkProgramARB(this->shaderProgram);
+       // link error checking
+       glGetObjectParameterivARB(this->shaderProgram, GL_OBJECT_LINK_STATUS_ARB, &status);
+       if (status == GL_INVALID_VALUE || status == GL_INVALID_OPERATION)
+         this->printError(this->shaderProgram);
+    }
+   else
+     {
+       PRINTF(2)("Shaders are not supported on your hardware\n");
+     }
+}
+
+
+/**
+ * standard deconstructor
+ */
+Shader::~Shader ()
+{
+  if (this->shaderProgram == glGetHandleARB(GL_PROGRAM_OBJECT_ARB))
+    Shader::deactivateShader();
+
+  // delete what has to be deleted here
+  this->deleteProgram(SHADER_VERTEX);
+  this->deleteProgram(SHADER_FRAGMENT);
+
+  if (this->fragmentShader != 0)
+  {
+    glDetachObjectARB(this->shaderProgram, this->fragmentShader);
+    glDeleteObjectARB(this->fragmentShader);
+  }
+  if (this->vertexShader != 0)
+  {
+    glDetachObjectARB(this->shaderProgram, this->vertexShader);
+    glDeleteObjectARB(this->vertexShader);
+  }
+  if (this->shaderProgram != 0)
+  {
+    GLint status = 0;
+    //glLinkProgramARB(this->shaderProgram);
+    glDeleteObjectARB(this->shaderProgram);
+       // link error checking
+    glGetObjectParameterivARB(this->shaderProgram, GL_OBJECT_DELETE_STATUS_ARB, &status);
+    if (status == GL_INVALID_VALUE || status == GL_INVALID_OPERATION)
+      this->printError(this->shaderProgram);
+  }
+}
+
+Shader* Shader::getShader(const char* vertexShaderFile, const char* fragmentShaderFile)
+{
+  return (Shader*)ResourceManager::getInstance()->load(vertexShaderFile, SHADER,  RP_LEVEL, (void*)fragmentShaderFile);
+}
+
+bool Shader::unload(Shader* shader)
+{
+  return ResourceManager::getInstance()->unload(shader);
+}
+
+Shader* Shader::storedShader = NULL;
+
+
+bool Shader::loadShaderProgramm(SHADER_TYPE type, const char* fileName)
+{
+  GLhandleARB shader = 0;
+
+  if (type != SHADER_VERTEX && type != SHADER_FRAGMENT)
+    return false;
+  this->deleteProgram(type);
+
+
+  tArray<char*>* program = fileReadArray(fileName);
+  if (program == NULL)
+    return false;
+
+  if (type == SHADER_VERTEX && GLEW_ARB_vertex_shader)
+  {
+    this->vertexShaderFile = new char[strlen(fileName)+1];
+    strcpy(this->vertexShaderFile, fileName);
+
+    shader = this->vertexShader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
+  }
+
+  if (type == SHADER_FRAGMENT && GLEW_ARB_fragment_shader)
+  {
+    this->fragmentShaderFile = new char[strlen(fileName)+1];
+    strcpy(this->fragmentShaderFile, fileName);
+
+    shader = this->fragmentShader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
+  }
+
+  if (shader != 0)
+  {
+    GLint status = 0;
+    glShaderSourceARB(shader, program->getCount(), (const char**)program->getArray(), NULL);
+    glCompileShaderARB(shader);
+    // checking on error.
+    glGetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &status);
+    if (status == GL_INVALID_VALUE || status == GL_INVALID_OPERATION)
+      this->printError(shader);
+    else
+      glAttachObjectARB(this->shaderProgram, shader);
+  }
+  for (unsigned int i=0; i< program->getCount(); i++)
+    delete[] program->getArray()[i];
+  delete program;
+}
+
+char* Shader::fileRead(const char* fileName)
+{
+  FILE* fileHandle;
+  char* content = NULL;
+
+  int count = 0;
+
+  if (fileName == NULL)
+    return NULL;
+
+  fileHandle = fopen(fileName, "rt");
+
+  if (fileHandle == NULL)
+    return NULL;
+  fseek(fileHandle, 0, SEEK_END);
+  count = ftell(fileHandle);
+  rewind(fileHandle);
+  if (count > 0) {
+     content = new char[count+1];
+     count = fread(content, sizeof(char), count, fileHandle);
+     content[count] = '\0';
+   }
+   fclose(fileHandle);
+ return content;
+}
+
+
+tArray<char*>* Shader::fileReadArray(const char* fileName)
+{
+  FILE*    stream;           //< The stream we use to read the file.
+
+  if( (stream = fopen (fileName, "rt")) == NULL)
+  {
+    PRINTF(1)("Shader could not open %s\n", fileName);
+    return NULL;
+  }
+  tArray<char*>* file = new tArray<char*>;
+
+  char lineBuffer[PARSELINELENGHT];
+  char* addString;
+  while(fgets (lineBuffer, PARSELINELENGHT, stream) != NULL)
+  {
+    addString = new char[strlen(lineBuffer)+1];
+    strcpy(addString, lineBuffer);
+    file->addEntry(addString);
+  }
+  fclose(stream);
+  file->finalizeArray();
+  return file;
+}
+
+
+
+void Shader::activateShader()
+{
+  if (likely (this->shaderProgram != 0))
+  {
+    glUseProgramObjectARB(this->shaderProgram);
+    Shader::storedShader = this;
+  }
+}
+
+void Shader::deactivateShader()
+{
+ if (storedShader != NULL)
+   glUseProgramObjectARB(0);
+ Shader::storedShader = NULL;
+}
+
+
+void Shader::deleteProgram(SHADER_TYPE type)
+{
+  GLint status = 0;
+  if (type == SHADER_VERTEX && this->vertexShader != 0)
+  {
+    delete[] this->vertexShaderFile;
+    this->vertexShaderFile = NULL;
+    glDetachObjectARB(this->shaderProgram, this->vertexShader);
+    glDeleteObjectARB(this->vertexShader);
+    glGetObjectParameterivARB(this->vertexShader, GL_OBJECT_DELETE_STATUS_ARB, &status);
+    if (status == GL_INVALID_VALUE || status == GL_INVALID_OPERATION)
+      Shader::printError(this->vertexShader);
+    this->vertexShader = 0;
+  }
+  else if (type == SHADER_FRAGMENT && this->fragmentShader != 0)
+  {
+    delete[] this->fragmentShaderFile;
+    this->fragmentShaderFile = NULL;
+    glDetachObjectARB(this->shaderProgram, this->fragmentShader);
+    glDeleteObjectARB(this->fragmentShader);
+    glGetObjectParameterivARB(this->fragmentShader, GL_OBJECT_DELETE_STATUS_ARB, &status);
+    if (status == GL_INVALID_VALUE || status == GL_INVALID_OPERATION)
+      Shader::printError(this->fragmentShader);
+    this->fragmentShader = 0;
+  }
+  else
+    return;
+}
+
+
+void Shader::printError(GLhandleARB program)
+{
+  if (program == 0)
+    return;
+
+  int infologLength = 0;
+  int charsWritten  = 0;
+  char *infoLog;
+
+  glGetObjectParameterivARB(program, GL_OBJECT_INFO_LOG_LENGTH_ARB,
+                            &infologLength);
+
+  if (infologLength > 0)
+  {
+    infoLog = new char[infologLength+1];
+    glGetInfoLogARB(program, infologLength, &charsWritten, infoLog);
+    printf("%s\n", infoLog);
+    delete[] infoLog;
+  }
+}
+
+bool Shader::checkShaderAbility()
+{
+  if (GLEW_ARB_shader_objects &&
+      GLEW_ARB_shading_language_100 &&
+      GLEW_ARB_vertex_shader &&
+      GLEW_ARB_fragment_shader)
+    return true;
+  else
+    return false;
+}
+
+void Shader::debug() const
+{
+  PRINT(3)("Shader info: (SHADER: %d)\n", this->shaderProgram);
+  if (this->vertexShader != 0)
+  {
+/*    PRINT(3)("VertexShaderProgramm: number=%d, file='%s'\n", this->vertexShader, this->vertexShaderFile);
+    if (this->vertexShaderSource != NULL)
+      for (unsigned int i = 0; i < this->vertexShaderSource->getCount(); i++)
+        PRINT(3)("%d: %s\n", i, this->vertexShaderSource->getEntry(i));
+  }
+  if (this->fragmentShader != 0)
+  {
+    PRINT(3)("FragmentShaderProgramm: number=%d, file='%s'\n", this->fragmentShader, this->fragmentShaderFile);
+    if (this->fragmentShaderSource != NULL)
+      for (unsigned int i = 0; i < this->fragmentShaderSource->getCount(); i++)
+        PRINT(3)("%d: %s\n", i, this->fragmentShaderSource->getEntry(i));*/
+  }
+}
+
Index: branches/network/src/lib/graphics/shader.h
===================================================================
--- branches/network/src/lib/graphics/shader.h	(revision 6636)
+++ branches/network/src/lib/graphics/shader.h	(revision 6636)
@@ -0,0 +1,65 @@
+/*!
+ * @file shader.h
+ * @brief Definition of the Shader rendering class
+*/
+
+#ifndef _SHADER_H
+#define _SHADER_H
+
+#include "base_object.h"
+#include "glincl.h"
+
+template<class T> class tArray;
+
+typedef enum
+{
+  SHADER_NONE       = 0,
+  SHADER_FRAGMENT   = 1,
+  SHADER_VERTEX     = 0,
+
+} SHADER_TYPE;
+
+// FORWARD DECLARATION
+
+
+//! A class for ...
+class Shader : public BaseObject {
+
+  public:
+  Shader(const char* vertexShaderFile = NULL, const char* fragmentShaderFile = NULL);
+  virtual ~Shader();
+  static Shader* getShader(const char* vertexShaderFile, const char* fragmentShaderFile);
+  static bool unload(Shader* shader);
+
+  bool loadShaderProgramm(SHADER_TYPE type, const char* fileName);
+  void activateShader();
+  static void deactivateShader();
+  void deleteProgram(SHADER_TYPE type);
+
+  char* fileRead(const char* fileName);
+  tArray<char*>* fileReadArray(const char* fileName);
+
+  static bool checkShaderAbility();
+
+  inline static bool shaderActive() { return (Shader::storedShader != NULL)?true:false; };
+  inline static Shader* getActiveShader() { return Shader::storedShader; };
+  inline static void suspendShader() { Shader* currShader = storedShader; if (storedShader!= NULL) { Shader::deactivateShader(); Shader::storedShader = currShader;} };
+  inline static void restoreShader() { if (storedShader != NULL) storedShader->activateShader(); storedShader = NULL; };
+
+
+  void printError(GLhandleARB program);
+  void debug() const;
+
+  private:
+
+ private:
+   char*                  fragmentShaderFile;
+   char*                  vertexShaderFile;
+   GLhandleARB            shaderProgram;
+   GLhandleARB            vertexShader;
+   GLhandleARB            fragmentShader;
+
+   static Shader*         storedShader;
+};
+
+#endif /* _SHADER_H */
Index: branches/network/src/lib/graphics/spatial_separation/Makefile.am
===================================================================
--- branches/network/src/lib/graphics/spatial_separation/Makefile.am	(revision 6636)
+++ branches/network/src/lib/graphics/spatial_separation/Makefile.am	(revision 6636)
@@ -0,0 +1,12 @@
+MAINSRCDIR=../../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXquadtree.a
+
+libORXquadtree_a_SOURCES = quadtree.cc \
+                           quadtree_node.cc \
+                           spatial_separation.cc
+
+noinst_HEADERS =  quadtree.h \
+                  quadtree_node.h \
+                  spatial_separation.h
Index: branches/network/src/lib/graphics/spatial_separation/quadtree.cc
===================================================================
--- branches/network/src/lib/graphics/spatial_separation/quadtree.cc	(revision 6636)
+++ branches/network/src/lib/graphics/spatial_separation/quadtree.cc	(revision 6636)
@@ -0,0 +1,214 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SPATIAL_SEPARATION
+
+#include "quadtree.h"
+
+#include "quadtree_node.h"
+#include "vector.h"
+
+#include "material.h"
+#include "debug.h"
+
+using namespace std;
+
+#define QUADTREE_MATERIAL_COUNT       4
+
+/**
+ *  standard constructor
+ */
+Quadtree::Quadtree (const modelInfo* pModelInfo, const int treeDepth)
+{
+  this->setClassID(CL_QUADTREE, "Quadtree");
+  this->pModelInfo = pModelInfo;
+  this->treeDepth = treeDepth;
+
+  /* initialize the materials for debug draw */
+  this->materials = new Material*[QUADTREE_MATERIAL_COUNT];
+  for(int i = 0; i < QUADTREE_MATERIAL_COUNT; ++i)
+  {
+    materials[i] = new Material();
+    materials[i]->setIllum(3);
+  }
+  materials[0]->setAmbient(0.0, 0.3, 0.0);
+  materials[1]->setAmbient(0.4, 0.0, 0.2);
+  materials[2]->setAmbient(1.0, 0.0, 0.0);
+  materials[3]->setAmbient(5.0, 3.0, 1.0);
+
+  /* build the tree */
+  this->rootNode = new QuadtreeNode(this->pModelInfo, this, this->treeDepth);
+
+  /* make an array with access to the leafs of the Quad-Tree */
+  this->nodes = new QuadtreeNode*[(int)pow(4, treeDepth)];
+  int index = 0; //new int; *index = 0; // !!changed by bensch!!
+  for(int i = 0; i < (int)pow(2, treeDepth); ++i)
+  {
+    this->rootNode->buildHashTable(this->nodes, &index);
+  }
+  /* sort and revert the hash table to fit the right position */
+  this->sortHashTable(this->nodes);
+  this->revertHashTable(this->nodes);
+
+  /* define some important and often used variables */
+  this->quadLength = this->nodes[0]->getDimension()->getAxis() * 2.0f;
+  Rectangle* r = this->rootNode->getDimension();
+  float xOff = r->getCenter().x - r->getAxis();
+  float yOff = r->getCenter().z - r->getAxis();
+  this->offset = new Vector();
+  this->offset->x = xOff;
+  this->offset->z = yOff;
+  this->maxIndex = (int)pow(2, this->treeDepth);
+}
+
+
+/**
+ *  standard deconstructor
+ */
+Quadtree::~Quadtree ()
+{
+  // delete what has to be deleted here
+  if (this->materials != NULL)
+  {
+    for (unsigned int i = 0; i < QUADTREE_MATERIAL_COUNT; i++)
+      delete this->materials[i];
+    delete[] this->materials;
+  }
+
+  delete this->offset;
+
+  delete this->rootNode;
+  delete [] this->nodes;
+}
+
+
+/**
+ *  this function rotates the array and mirrors it in the middle
+ * @param nodes: the nodes to translate
+
+  since the original matrix is counted from the right upper edge to the right lower one, we have to reorganize the elements
+  to be able to easily correlate the hashtable array indexes with the coorindates.
+ */
+void Quadtree::revertHashTable(QuadtreeNode** nodes)
+{
+  int                  len         = (int)pow(2, this->treeDepth);          //!< the length of a quadtree side
+  int                  iterator    = 0;                                     //!< iterator used for mapping
+  QuadtreeNode*        tmpNode     = NULL;                                  //!< temp saving place
+  int                  offset      = 0;                                     //!< offset used in the calc
+
+  for(int i = len - 1; i >= 0; --i)
+  {
+    for(int j = len - 1; j >= 0; --j)
+    {
+      offset = j * len + i;
+      /* only swap the elements in one direction */
+      if( offset > iterator)
+      {
+        tmpNode = nodes[offset];
+        nodes[offset] = nodes[iterator];
+        nodes[iterator] = tmpNode;
+      }
+      ++iterator;
+    }
+  }
+}
+
+
+/**
+ *  sorts the hash table using their positions
+ * @param nodes the nodes to use
+ */
+void Quadtree::sortHashTable(QuadtreeNode** nodes)
+{
+  int                  len         = (int)pow(2, this->treeDepth);          //!< the length of a quadtree side
+  float                a;                                                   //!< temp place for float a
+  float                b;                                                   //!< temp place for float b
+  QuadtreeNode*        tmpNode;                                             //!< tmp place for a QuadtreeNode
+
+  for( int i = 0; i < len; ++i)
+  {
+    for( int j = 0; j < len; ++j)
+    {
+      for( int k = j + 1; k < len; ++k)
+      {
+        a = this->nodes[i * len + j]->getDimension()->getCenter().z;
+        b = this->nodes[i * len + k]->getDimension()->getCenter().z;
+
+        if( b > a)
+        {
+          tmpNode = this->nodes[i * len + j];
+          this->nodes[i * len + j] = this->nodes[i * len + k];
+          this->nodes[i * len + k] = tmpNode;
+        }
+      }
+    }
+  }
+
+}
+
+
+/**
+ *  maps a position to a quadtree
+ * @param position the position so look for
+ * @return the quadtree
+
+  this function will return the quadtree that contains the position
+ */
+QuadtreeNode* Quadtree::getQuadtreeFromPosition(const Vector& position) const
+{
+  /* shift into model space */
+  Vector v = position - *this->offset;
+  /* map */
+  int i = (int)(v.x / quadLength);
+  int j = (int)(v.z / quadLength);
+
+  /* check if object is still inside the terrain - this check is not complete @todo check all 4 bounds */
+  if( i < this->maxIndex && j < this->maxIndex && i >= 0 && j >= 0)
+    return this->nodes[i + j * this->maxIndex];
+
+
+  PRINTF(4)("Object has left terrain\n");
+  return NULL;
+}
+
+
+/**
+ *  maps a position to a triangle
+ * @param position the position so look for
+ * @return the triangle
+
+  this function will return the quadtree that contains the position
+ */
+sTriangleExt* Quadtree::getTriangleFromPosition(const Vector& position) const
+{
+  QuadtreeNode* q = this->getQuadtreeFromPosition(position);
+
+  if( likely(q != NULL))
+    return q->getTriangle(position - *this->offset);
+  return NULL;
+}
+
+
+/**
+ *  draws the debug quadtree boxes around the model
+ */
+void Quadtree::drawTree() const
+{
+  //this->rootNode->drawTree();
+  for(int i = 0; i < (int)pow(4, this->treeDepth); ++i)
+  {
+    this->nodes[i]->draw();
+  }
+}
Index: branches/network/src/lib/graphics/spatial_separation/quadtree.h
===================================================================
--- branches/network/src/lib/graphics/spatial_separation/quadtree.h	(revision 6636)
+++ branches/network/src/lib/graphics/spatial_separation/quadtree.h	(revision 6636)
@@ -0,0 +1,54 @@
+/*!
+ * @file quadtree.h
+ *  Definition of a spatial data separation using quadtree
+
+  This is the top element of the quadtree framework. A Quadtree is build of QuadtreeNodes, which are again separated
+  into QuadtreeNodes until a certain depth is reached
+ */
+
+#ifndef _QUADTREE_H
+#define _QUADTREE_H
+
+
+#include "base_object.h"
+#include "model.h"
+
+
+class QuadtreeNode;
+class Material;
+class Vector;
+
+//! A class for quadtree separation of the world
+class Quadtree : public BaseObject {
+
+
+  public:
+    Quadtree(const modelInfo* pModelInfo, const int treeDepth);
+    virtual ~Quadtree();
+
+    QuadtreeNode* getQuadtreeFromPosition(const Vector& position) const;
+    sTriangleExt* getTriangleFromPosition(const Vector& position) const;
+
+    void drawTree() const;
+    inline Material* getMaterial(int indexNode) const { return this->materials[indexNode % 4]; }
+
+
+  private:
+    void revertHashTable(QuadtreeNode** nodes);
+    void sortHashTable(QuadtreeNode** nodes);
+
+
+  private:
+    QuadtreeNode*                   rootNode;              //!< reference to the root node of the quadtree
+    QuadtreeNode**                  nodes;                 //!< reference to all quadtree nodes (only leafs of the quad tree)
+    const modelInfo*                pModelInfo;            //!< reference to the modelInfo of the object
+    int                             treeDepth;             //!< depth of the tree
+
+    float                           quadLength;            //!< length of the leaf quadtree nodes
+    Vector*                         offset;                //!< vector to the left lower corner of the root quadtree node
+    int                             maxIndex;              //!< maximal index for the nodes array
+
+    Material**                      materials;             //!< materials for debug drawing purposes
+};
+
+#endif /* _QUADTREE_H */
Index: branches/network/src/lib/graphics/spatial_separation/quadtree_node.cc
===================================================================
--- branches/network/src/lib/graphics/spatial_separation/quadtree_node.cc	(revision 6636)
+++ branches/network/src/lib/graphics/spatial_separation/quadtree_node.cc	(revision 6636)
@@ -0,0 +1,555 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SPATIAL_SEPARATION
+
+#include "quadtree_node.h"
+
+#include "glincl.h"
+#include "quadtree.h"
+#include "material.h"
+#include "model.h"
+#include "debug.h"
+
+#include "util/list.h"
+
+using namespace std;
+
+
+/**
+ *  standard constructor
+ */
+QuadtreeNode::QuadtreeNode (sTriangleExt** triangles, int numTriangles,
+                            const float* pVertices, int numVertices,
+                            Quadtree* quadtree, QuadtreeNode* parent,
+                            Rectangle* rect, int treeDepth, const int maxDepth, int index
+                           )
+{
+  /* save all important variables localy */
+  this->numTriangles = numTriangles;
+  this->pTriangles = triangles;
+  this->numVertices = numVertices;
+  this->pVertices = pVertices;
+
+  this->quadtree = quadtree;
+  this->parent = parent;
+  this->pDimension = rect;
+  this->treeDepth = treeDepth;
+  this->maxDepth = maxDepth;
+  this->indexNode = index;
+
+  /* debug output */
+  for( int i = 0; i < this->treeDepth; ++i)
+    PRINT(3)(" |");
+  PRINT(3)(" | +-| (Event) Building Node Nr. %i Depth: %i/%i, pointer: %p\n", this->indexNode, treeDepth, maxDepth, this);
+
+  for( int i = 0; i < this->treeDepth; ++i)
+    PRINT(3)(" |");
+  PRINT(3)(" | +-| (II) Rectangle Center (%5.2f, %5.2f), half axis length: %5.2f\n",
+  this->pDimension->getCenter().x, this->pDimension->getCenter().z, this->pDimension->getAxis());
+
+  this->init();
+}
+
+
+/**
+ *  standard constructor
+ */
+QuadtreeNode::QuadtreeNode(const modelInfo* pModelInfo, Quadtree* quadtree, const int maxDepth)
+{
+  /* save all important variables localy */
+  this->pModelInfo = pModelInfo;
+  this->quadtree = quadtree;
+  this->maxDepth = maxDepth;
+  this->treeDepth = 0;
+  this->indexNode = 0;
+
+  /* create an array of triangle references */
+  this->pTriangles = new sTriangleExt*[this->pModelInfo->numTriangles];
+  this->numTriangles = this->pModelInfo->numTriangles;
+  this->pVertices = this->pModelInfo->pVertices;
+  this->numVertices = this->pModelInfo->numVertices;
+  for( int i = 0; i < this->pModelInfo->numTriangles; ++i)
+    this->pTriangles[i] = &this->pModelInfo->pTriangles[i];
+
+  /* debug output */
+  for( int i = 0; i < this->treeDepth; ++i)
+    PRINT(3)(" |");
+  PRINT(3)(" | +-| (Event) Building Node Nr. %i Depth: %i/%i, pointer: %p\n", this->indexNode, treeDepth, maxDepth, this);
+
+  /* set some important variables */
+  this->pDimension = this->getDimFromModel();
+
+  this->init();
+}
+
+
+/**
+ *  takes the rest of the initialisation process
+ */
+void QuadtreeNode::init()
+{
+  this->setClassID(CL_QUADTREE_NODE, "QuadtreeNode");
+
+  /* init the rest of the variables for both init types */
+  this->offset = 0.0f;
+  this->nodeIter = -1;
+  this->bDraw = false;
+
+  this->parent = NULL;
+  this->nodeA = NULL;
+  this->nodeB = NULL;
+  this->nodeC = NULL;
+  this->nodeD = NULL;
+  this->nodes = new QuadtreeNode*[4];
+  for(int i = 0; i < 4; ++i)
+    this->nodes[i] = NULL;
+
+  /* now separate the nodes */
+  if( this->treeDepth < this->maxDepth)
+    this->separateNode();
+}
+
+
+/**
+ *  standard deconstructor
+ */
+QuadtreeNode::~QuadtreeNode ()
+{
+  if( this->nodeA)
+    delete this->nodeA;
+  if( this->nodeB)
+    delete this->nodeB;
+  if( this->nodeC)
+    delete this->nodeC;
+  if( this->nodeD)
+    delete this->nodeD;
+
+  if( this->nodes)
+    delete [] this->nodes;
+
+  if( this->pTriangles)
+    delete [] this->pTriangles;
+
+  if( this->pDimension)
+    delete this->pDimension;
+}
+
+
+
+/**
+ *  this functions builds up a hash table containing all leafs of the Quadtree in a sorted array
+ * @param nodeList the nodelist array to add them
+ * @param index the current index in the array
+
+  The algorithm used for this purpose is home-brown. its not to fast but and the nodes are not always in the right
+  order. this is why there will be needed a quicksort later on.
+ */
+void QuadtreeNode::buildHashTable(QuadtreeNode** nodeList, int* index)
+{
+  if( this->nodeIter == -1)
+    this->nodeIter = *index;
+
+  /*              offset              #of elements in a row            #of rows in a quadtree          */
+  int threshold = this->nodeIter + (int)pow(2, this->maxDepth) * (int)pow(2, maxDepth - treeDepth - 1);
+  int loopLimit = (*index < threshold)?2:4;
+
+  /* is it a leaf? */
+  if( this->treeDepth < this->maxDepth)
+    for(int i = (*index < threshold)?0:2; i < loopLimit; ++i)
+      this->nodes[i]->buildHashTable(nodeList, index);
+  else
+    nodeList[(*index)++] = this;
+}
+
+
+
+/**
+ *  gives the signal to separate the model into a quadtree
+ * @param treeDepth the max depth, the steps to go if treeDept == 0 leaf reached
+
+ * @todo ATTENION: This function is currently not used and not implemented, but would be a nice addon
+ */
+void QuadtreeNode::separateNode(float minLength)
+{
+  /* dimension calculation & limit checking */
+  if( minLength <= this->pDimension->getAxis())
+    return;
+
+  /* node separation */
+//   this->separateNode();
+//   this->nodeA->separateNode(minLength);
+//   this->nodeB->separateNode(minLength);
+//   this->nodeC->separateNode(minLength);
+//   this->nodeD->separateNode(minLength);
+}
+
+
+/**
+ *  gives the signal to separate the model into a quadtree
+ * @param treeDepth the max depth, the steps to go if treeDept == 0 leaf reached
+ */
+void QuadtreeNode::separateNode()
+{
+  /* separate the four regions into the four lists */
+  tList<sTriangleExt*>*           listA = new tList<sTriangleExt*>();    //!< triangle list of nodeA
+  tList<sTriangleExt*>*           listB = new tList<sTriangleExt*>();    //!< triangle list of nodeB
+  tList<sTriangleExt*>*           listC = new tList<sTriangleExt*>();    //!< triangle list of nodeC
+  tList<sTriangleExt*>*           listD = new tList<sTriangleExt*>();    //!< triangle list of nodeD
+  const float*                    pVert;                                 //!< pointer to the vertices
+  Vector                          rectCenter;                            //!< vector to the center of the rect
+
+  rectCenter = this->pDimension->getCenter();
+  for( int i = 0; i < this->numTriangles; ++i)
+  {
+    for( int j = 0; j < 3; ++j)
+    {
+      pVert = &this->pVertices[this->pTriangles[i]->indexToVertices[j]];
+      if( pVert[0] > rectCenter.x + this->offset && pVert[2] > rectCenter.z + this->offset)
+        listA->add(&this->pTriangles[i]);
+      if( pVert[0] < rectCenter.x + this->offset && pVert[2] > rectCenter.z + this->offset)
+        listB->add(&this->pTriangles[i]);
+      if( pVert[0] < rectCenter.x + this->offset && pVert[2] < rectCenter.z + this->offset)
+        listC->add(&this->pTriangles[i]);
+      if( pVert[0] > rectCenter.x + this->offset && pVert[2] < rectCenter.z + this->offset)
+        listD->add(&this->pTriangles[i]);
+    }
+  }
+  for( int i = 0; i < treeDepth; ++i)
+    PRINT(3)(" |");
+  PRINT(3)(" | +-| (II) Quadtree Counts - separating: A: %i, B: %i, C: %i, D: %i\n", listA->getSize(), listB->getSize(), listC->getSize(), listD->getSize());
+
+
+  /* Separating into to the triangle arrays */
+  sTriangleExt**                 pTriA;                                 //!< Triangle array A
+  sTriangleExt**                 pTriB;                                 //!< Triangle array B
+  sTriangleExt**                 pTriC;                                 //!< Triangle array C
+  sTriangleExt**                 pTriD;                                 //!< Triangle array D
+  int                            lenA;                                  //!< length array A
+  int                            lenB;                                  //!< length array B
+  int                            lenC;                                  //!< length array C
+  int                            lenD;                                  //!< length array D
+  tIterator<sTriangleExt*>*      iterator;                              //!< iterator for the list iterations
+  sTriangleExt**                 tempTri;                               //!< temp save place for triangle pointer
+  int                            counter;                               //!< counter for the while loops
+
+  lenA = listA->getSize();
+  lenB = listB->getSize();
+  lenC = listC->getSize();
+  lenD = listD->getSize();
+
+  pTriA = new sTriangleExt*[lenA];
+  pTriB = new sTriangleExt*[lenB];
+  pTriC = new sTriangleExt*[lenC];
+  pTriD = new sTriangleExt*[lenD];
+
+  counter = 0;
+  iterator = listA->getIterator();
+  tempTri = iterator->firstElement();
+  while( tempTri)
+  {
+    pTriA[counter] = *tempTri;
+    tempTri = iterator->nextElement();
+    ++counter;
+  }
+  delete iterator;
+
+  counter = 0;
+  iterator = listB->getIterator();
+  tempTri = iterator->firstElement();
+  while( tempTri)
+  {
+    pTriB[counter] = *tempTri;
+    tempTri = iterator->nextElement();
+    ++counter;
+  }
+  delete iterator;
+
+  counter = 0;
+  iterator = listC->getIterator();
+  tempTri = iterator->firstElement();
+  while( tempTri)
+  {
+    pTriC[counter] = *tempTri;
+    tempTri = iterator->nextElement();
+    ++counter;
+  }
+  delete iterator;
+
+  counter = 0;
+  iterator = listD->getIterator();
+  tempTri = iterator->firstElement();
+  while( tempTri)
+  {
+    pTriD[counter] = *tempTri;
+    tempTri = iterator->nextElement();
+    ++counter;
+  }
+  delete iterator;
+
+  /* now do cleanup */
+  delete listA;
+  delete listB;
+  delete listC;
+  delete listD;
+
+
+  /* now create the rectangle dimensions */
+  Vector                     v;                                                             //!< temp saving place
+  Rectangle*                 rA;                                                            //!< new size of the node A
+  Rectangle*                 rB;                                                            //!< new size of the node B
+  Rectangle*                 rC;                                                            //!< new size of the node C
+  Rectangle*                 rD;                                                            //!< new size of the node D
+
+
+  v.x = this->pDimension->getCenter().x + this->pDimension->getAxis() / 2.0f;
+  v.y = 0.0;
+  v.z = this->pDimension->getCenter().z + this->pDimension->getAxis() / 2.0f;
+  rA = new Rectangle(v, this->pDimension->getAxis() / 2.0f);
+
+  v.z = this->pDimension->getCenter().z - this->pDimension->getAxis() / 2.0f;
+  rB = new Rectangle(v, this->pDimension->getAxis() / 2.0f);
+
+  v.x = this->pDimension->getCenter().x - this->pDimension->getAxis() / 2.0f;
+  rC = new Rectangle(v, this->pDimension->getAxis() / 2.0f);
+
+  v.z = this->pDimension->getCenter().z + this->pDimension->getAxis() / 2.0f;
+  rD = new Rectangle(v, this->pDimension->getAxis() / 2.0f);
+
+
+  /* now create the new nodes  */
+  this->nodeA = new QuadtreeNode(pTriA, lenA, this->pVertices, this->numVertices, this->quadtree, this, rA, this->treeDepth + 1, this->maxDepth, (this->treeDepth + 1) * 10 + 0);
+  this->nodeB = new QuadtreeNode(pTriB, lenB, this->pVertices, this->numVertices, this->quadtree, this, rB, this->treeDepth + 1, this->maxDepth, (this->treeDepth + 1) * 10 + 1);
+  this->nodeC = new QuadtreeNode(pTriC, lenC, this->pVertices, this->numVertices, this->quadtree, this, rC, this->treeDepth + 1, this->maxDepth, (this->treeDepth + 1) * 10 + 2);
+  this->nodeD = new QuadtreeNode(pTriD, lenD, this->pVertices, this->numVertices, this->quadtree, this, rD, this->treeDepth + 1, this->maxDepth, (this->treeDepth + 1) * 10 + 3);
+
+  /* map the array references, this is for faster and automatical interfacing  \todo: use only array */
+  this->nodes[0] = this->nodeA;
+  this->nodes[1] = this->nodeB;
+  this->nodes[2] = this->nodeC;
+  this->nodes[3] = this->nodeD;
+}
+
+
+/**
+ *  gets the maximal dimension of a model
+ * @return the dimension of the Model as a Rectangle
+
+   The rectangle is x-z axis aligned. ATTENTION: if there are any vertices in the model, that exceed the
+   size of 999999.0, there probably will be some errors in the dimensions calculations. Write an email to
+   patrick@orxonox.ethz.ch if you will ever encounter a model bigger than 999999.0 units, I will realy be
+   happy to see orxonox used to extensivly :)
+ */
+Rectangle* QuadtreeNode::getDimFromModel()
+{
+  float            maxX, maxY;                       //!< the maximal coordinates axis
+  float            minX, minY;                       //!< minimal axis coorindates
+  const float*     pVertices;                        //!< pointer to the current vertices
+
+  maxX = -999999; maxY = -999999;
+  minX =  999999; minY =  999999;
+  /* get maximal/minimal x/y */
+  for( int i = 0; i < this->numTriangles; ++i)
+  {
+    for( int j = 0; j < 3; ++j)
+    {
+
+      pVertices = &this->pVertices[this->pTriangles[i]->indexToVertices[j]];
+      if( pVertices[0] > maxX)
+        maxX = pVertices[0];
+      if( pVertices[2] > maxY)
+        maxY = pVertices[2];
+
+      if( pVertices[0] < minX)
+        minX = pVertices[0];
+      if( pVertices[2] < minY)
+        minY = pVertices[2];
+    }
+  }
+
+  Rectangle* rect = new Rectangle();
+  rect->setCenter((maxX + minX) / 2.0f, 0.0f, (maxY + minY) / 2.0f); /* this is little strange, since y is in opengl the up vector */
+  rect->setAxis(fmax(((fabs(maxX) + fabs(minX)) / 2.0f), ((fabs(maxY) + fabs(minY)) / 2.0f)));
+
+  for( int i = 0; i < this->treeDepth; ++i)
+    PRINT(3)(" |");
+  PRINT(3)(" | +-| (II) Rectangle Dimension  (%5.2f, %5.2f) to (%5.2f, %5.2f), Center (%5.2f, %5.2f)\n", minX, minY, maxX, maxY, rect->getCenter().x, rect->getCenter().z, rect->getAxis());
+  return rect;
+}
+
+
+ /**
+ * checks if a point is included in this quadtree
+ * @param v the vector to be checked
+ * @returns true if the vector is included
+  */
+bool QuadtreeNode::includesPoint(const Vector& v) const
+{
+  Vector center = this->pDimension->getCenter();
+  float ax = this->pDimension->getAxis();
+
+  if( v.x > center.x - ax && v.x < center.x + ax &&
+      v.z > center.z - ax && v.z < center.z + ax )
+    return true;
+  return false;
+}
+
+
+
+float QuadtreeNode::getHeight(const Vector& position) const
+{
+  Vector a, b, c;
+  sTriangleExt* tri;
+
+  for( int i = 0; i < this->numTriangles; ++i)
+  {
+    a = *(sVec3D*)&this->pVertices[this->pTriangles[i]->indexToVertices[0]];
+    b = *(sVec3D*)&this->pVertices[this->pTriangles[i]->indexToVertices[1]];
+    c = *(sVec3D*)&this->pVertices[this->pTriangles[i]->indexToVertices[2]];
+
+    if( unlikely(this->pointInTriangle(position, a, b, c)))
+    {
+      tri = this->pTriangles[i];
+      break;
+    }
+  }
+
+  /* calculate height out of the data collected above */
+
+}
+
+
+/**
+ *  get triangles that includes the position
+ * @param position the position that is going to be checked
+ * @returns the triangle in which the position is included, NULL if there is no such triangle
+
+ There is some random behaviour if there are more than one triangle at the same y
+ coordinate. At the moment the function just takes the first triangle, that included the
+ vector
+ */
+sTriangleExt* QuadtreeNode::getTriangle(const Vector& position) const
+{
+  Vector a, b, c;
+  PRINTF(0)("Get Triangle, %i\n", this->numTriangles);
+
+  for( int i = 0; i < numTriangles; ++i)
+    {
+
+      a = *(sVec3D*)&this->pVertices[this->pTriangles[i]->indexToVertices[0]];
+      b = *(sVec3D*)&this->pVertices[this->pTriangles[i]->indexToVertices[1]];
+      c = *(sVec3D*)&this->pVertices[this->pTriangles[i]->indexToVertices[2]];
+
+      if( unlikely(this->pointInTriangle(position, a, b, c)))
+        return this->pTriangles[i];
+
+    }
+  return NULL;
+}
+
+
+/**
+ *  checks if the point is in the triangle
+ * @param point to be checked
+ * @param rectangle edge a
+ * @param rectangle edge b
+ * @param rectangle edge c
+ * @returns true if the point is inside
+ */
+bool QuadtreeNode::pointInTriangle(const Vector&p, const Vector& a, const Vector& b, const Vector& c) const
+{
+
+  PRINTF(0)("p: (%f, %f, %f)\n", p.x, p.y, p.z);
+  PRINTF(0)("a: (%f, %f, %f)\n", a.x, a.y, a.z);
+  PRINTF(0)("b: (%f, %f, %f)\n", b.x, b.y, b.z);
+  PRINTF(0)("c: (%f, %f, %f)\n", c.x, c.y, c.z);
+
+  if( this->sameSide(p, a, b, c) && this->sameSide(p, b, a, c) && sameSide(p, c, a, b))
+    return true;
+  return false;
+}
+
+
+/**
+ *  checks if two points are on the same side
+ * @param point one to be checked
+ * @param point two to be checked
+ * @param begining point of the line
+ * @param end of the line
+ */
+bool QuadtreeNode::sameSide(const Vector& p1, const Vector&p2, const Vector& a, const Vector& b) const
+{
+  Vector cp1 = (b - a).cross(p1 - a);
+  Vector cp2 = (b - a).cross(p2 - a);
+
+  if( unlikely(cp1.dot(cp2) >= 0)) return true;
+  return false;
+}
+
+
+/**
+ *  draws all the debug quadtree squares
+ */
+void QuadtreeNode::drawTree() const
+{
+  if( this->treeDepth == this->maxDepth)
+  {
+    Vector t1 = this->pDimension->getCenter();
+    float ax = this->pDimension->getAxis();
+    float h = 50.0f;
+
+    this->quadtree->getMaterial(this->indexNode)->select();
+    glBegin(GL_QUADS);
+    glVertex3f(t1.x + ax, h - this->treeDepth * 10.0f, t1.z + ax);
+    glVertex3f(t1.x - ax, h - this->treeDepth * 10.0f, t1.z + ax);
+    glVertex3f(t1.x - ax, h - this->treeDepth * 10.0f, t1.z - ax);
+    glVertex3f(t1.x + ax, h - this->treeDepth * 10.0f, t1.z - ax);
+    glEnd();
+  }
+
+
+  if( this->nodeA != NULL)
+    this->nodeA->drawTree();
+  if( this->nodeB != NULL)
+    this->nodeB->drawTree();
+  if( this->nodeC != NULL)
+    this->nodeC->drawTree();
+  if( this->nodeD != NULL)
+    this->nodeD->drawTree();
+}
+
+
+/**
+ *  draws only this quadtree square
+ */
+void QuadtreeNode::draw() const
+{
+  if( likely(!this->bDraw))
+    return;
+
+  Vector t1 = this->pDimension->getCenter();
+  float ax = this->pDimension->getAxis();
+  float h = 70.0f;
+
+  glBegin(GL_QUADS);
+  this->quadtree->getMaterial(this->indexNode)->select();
+
+  glVertex3f(t1.x + ax, h, t1.z + ax);
+  glVertex3f(t1.x - ax, h, t1.z + ax);
+  glVertex3f(t1.x - ax, h, t1.z - ax);
+  glVertex3f(t1.x + ax, h, t1.z - ax);
+
+  glEnd();
+}
Index: branches/network/src/lib/graphics/spatial_separation/quadtree_node.h
===================================================================
--- branches/network/src/lib/graphics/spatial_separation/quadtree_node.h	(revision 6636)
+++ branches/network/src/lib/graphics/spatial_separation/quadtree_node.h	(revision 6636)
@@ -0,0 +1,91 @@
+/*!
+ * @file proto_class.h
+ *  Definition of a QuadtreeNode which represents a quad in a Quadtree
+
+  This struct is used to partition big land scapes into smaller ones for different reasons:
+    - for collision detection: only a subset of all triangles need to be tested vs a given body
+    - for object culling purposes: the quadtrees that are not in the field of view can be ommitted in the draw process
+    - for LOD (level of Detail). The models can be drawn using different LODs depending on the distance
+
+  This struct includes all the triangles, vertices, normal informations needed to make something usefull with
+  a terrain partition.
+ */
+
+#ifndef _QUADTREE_NODE_H
+#define _QUADTREE_NODE_H
+
+#include "base_object.h"
+
+#include "plane.h"
+#include "model.h"
+
+// FORWARD DECLARATION
+class Quadtree;
+
+
+//! A class for a Quadtree Node representation
+class QuadtreeNode : public BaseObject {
+
+  public:
+    QuadtreeNode(sTriangleExt** triangles, int numTriangles,
+                 const float* pVertices, int numVertices,
+                 Quadtree* quadtree, QuadtreeNode* parent,
+                 Rectangle* rect, int treeDepth, const int maxDepth, int index
+                );
+    QuadtreeNode(const modelInfo* pModelInfo, Quadtree* quadtree, const int maxDepth);
+    virtual ~QuadtreeNode();
+
+    void buildHashTable(QuadtreeNode** nodeList, int* index);
+    inline Rectangle* getDimension() { return this->pDimension; }
+
+    bool includesPoint(const Vector& v) const;
+    sTriangleExt* getTriangle(const Vector& position) const;
+    float getHeight(const Vector& position) const;
+
+
+    void drawTree() const;
+    void draw() const;
+
+
+  private:
+    void init();
+
+    void separateNode(float minLength);
+    void separateNode();
+    Rectangle* getDimFromModel();
+
+    bool sameSide(const Vector& p1, const Vector&p2, const Vector& a, const Vector& b) const;
+    bool pointInTriangle(const Vector&p, const Vector& a, const Vector& b, const Vector& c) const;
+
+  protected:
+    QuadtreeNode*                   parent;             //!< reference to the paren QuadtreeNode (NULL if rootnode)
+    QuadtreeNode*                   nodeA;              //!< reference to the node A
+    QuadtreeNode*                   nodeB;              //!< reference to the node B
+    QuadtreeNode*                   nodeC;              //!< reference to the node C
+    QuadtreeNode*                   nodeD;              //!< reference to the node D
+    QuadtreeNode**                  nodes;              //!< reference to the quadtree nodes (nodeA, nodeB, nodeC, nodeD=[0..3])
+
+
+  private:
+    Quadtree*                       quadtree;           //!< reference to the quadtree
+    Vector                          center;             //!< center coordinate of the quadtree node - relative coordinates in model space(!)
+    float                           axisLength;         //!< axis length of the quadtree
+    float                           maxHeigth;          //!< max height of the model in the quadtree
+    float                           offset;             //!< offset of the actual quadtree rectangle
+
+    int                             treeDepth;          //!< the depth of the tree
+    int                             maxDepth;           //!< the maximal depth of the tree
+    int                             indexNode;          //!< the index number of the node
+    int                             nodeIter;           //!< temp helping variable for the hashing algorithm
+
+    sTriangleExt**                  pTriangles;         //!< reference to the triangles of the node
+    const float*                    pVertices;          //!< reference to vertices data
+    unsigned int                    numTriangles;       //!< number of triangles of the Node
+    unsigned int                    numVertices;        //!< number of vertices of the node
+    const modelInfo*                pModelInfo;         //!< reference to the modelInfo of the object
+    Rectangle*                      pDimension;         //!< pointer to the local rectangle properties
+
+    bool                            bDraw;              //!< shall it be drawn? DEBUG only
+};
+
+#endif /* _QUADTREE_NODE_H */
Index: branches/network/src/lib/graphics/spatial_separation/spatial_separation.cc
===================================================================
--- branches/network/src/lib/graphics/spatial_separation/spatial_separation.cc	(revision 6636)
+++ branches/network/src/lib/graphics/spatial_separation/spatial_separation.cc	(revision 6636)
@@ -0,0 +1,131 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SPATIAL_SEPARATION
+
+#include "spatial_separation.h"
+
+#include "model.h"
+#include "quadtree.h"
+#include "debug.h"
+#include "compiler.h"
+
+using namespace std;
+
+
+/**
+ *  standard constructor
+ * @param model the model that is to be separated
+ * @param overlapSize each box will overlap for a given size
+
+   The boxes are overlaping because this makes collision detection a lot simpler
+
+ */
+SpatialSeparation::SpatialSeparation (Model* model, float overlapSize)
+{
+  PRINT(3)("+---------Debug Information SpatialSeparation----------\n");
+  PRINT(3)("+-| (Event) Spatial Separation process kicked on\n");
+
+  this->setClassID(CL_SPATIAL_SEPARATION, "SpatialSeparation");
+  /* debug vice */
+  this->createQuadtree(model);
+}
+
+
+/**
+ *  standard constructor
+ * @param model the model that is to be separated
+ * @param overlapSize each box will overlap for a given size
+
+   The boxes are overlaping because this makes collision detection a lot simpler
+ */
+SpatialSeparation::SpatialSeparation (Model* model, Model* playerModel)
+{
+  this->setClassID(CL_SPATIAL_SEPARATION, "SpatialSeparation");
+
+}
+
+
+/**
+ *  standard deconstructor
+ */
+SpatialSeparation::~SpatialSeparation ()
+{
+  if( this->quadtree)
+    delete this->quadtree;
+}
+
+
+/**
+ *  creates a quadtree
+ * @param model the model to do a quadtree on
+ * @param minLength the minimal length of a quadtree node
+ * @return the new quadtree
+ */
+Quadtree* SpatialSeparation::createQuadtree(Model* model, float minLength)
+{
+  this->minLength = minLength;
+
+}
+
+
+/**
+ *  brief creates a quadtree
+ * @param model the model to do a quadtree on
+ * @param minLength the minimal length of a quadtree node
+ * @return the new quadtree
+ */
+Quadtree* SpatialSeparation::createQuadtree(Model* model, int treeDepth)
+{
+  this->treeDepth = treeDepth;
+}
+
+
+/**
+ *  creates a quadtree
+ * @param model the model to do a quadtree on
+ * @param minLength the minimal length of a quadtree node
+ * @return the new quadtree
+ */
+Quadtree* SpatialSeparation::createQuadtree(Model* model)
+{
+  this->quadtree = new Quadtree(model->getModelInfo(), 4);
+
+  return this->quadtree;
+}
+
+
+/**
+ *  draws all the quadtrees
+ */
+void SpatialSeparation::drawQuadtree()
+{
+  if( unlikely( this->quadtree == NULL))
+    return;
+
+  this->quadtree->drawTree();
+}
+
+
+
+
+
+
+
+
+
+
+
+
Index: branches/network/src/lib/graphics/spatial_separation/spatial_separation.h
===================================================================
--- branches/network/src/lib/graphics/spatial_separation/spatial_separation.h	(revision 6636)
+++ branches/network/src/lib/graphics/spatial_separation/spatial_separation.h	(revision 6636)
@@ -0,0 +1,53 @@
+/*!
+ * @file spatial_separation.h  Definition of the generic spatial separation process of model data
+ */
+
+#ifndef _SPATIAL_SEPARATION_H
+#define _SPATIAL_SEPARATION_H
+
+#include "base_object.h"
+
+
+class Model;
+class Quadtree;
+
+
+#define SEC_OFFSET 1.0                       //!< the offset added to the overlapSize to ensure that there are no problems in
+
+
+
+//! A class for spatial separation of vertices based arrays
+class SpatialSeparation : public BaseObject {
+
+  public:
+    SpatialSeparation(Model* model, float overlapSize);
+    SpatialSeparation(Model* model, Model* playerModel);
+    virtual ~SpatialSeparation();
+
+    void setTreeDepth(int depth) { this->treeDepth = depth; }
+    void setMinLength(int minLength) { this->minLength = minLength; }
+
+    Quadtree* createQuadtree(Model* model, float minLength);
+    Quadtree* createQuadtree(Model* model, int treeDepth);
+    Quadtree* createQuadtree(Model* model);
+
+    inline Quadtree* getQuadtree() { return this->quadtree; }
+
+    void drawQuadtree();
+
+  private:
+    void separateZone();
+
+
+  private:
+    Model*             model;        //!< the reference to the model that has to be handled
+    Quadtree*                  quadtree;     //!< the reference to the created quadtree
+
+    Model*             playerModel;  //!< referece to the player model, if needed for overlap calculations
+    float                      overlapSize;  //!< the size of overlaping
+
+    int                        treeDepth;    //!< depth of the quadtree
+    float                      minLength;    //!< min length of a quadtree node
+};
+
+#endif /* _SPATIAL_SEPARATION_H */
Index: branches/network/src/lib/graphics/text_engine/default_font.xpm
===================================================================
--- branches/network/src/lib/graphics/text_engine/default_font.xpm	(revision 6636)
+++ branches/network/src/lib/graphics/text_engine/default_font.xpm	(revision 6636)
@@ -0,0 +1,268 @@
+/* XPM */
+static char * font_xpm[] = {
+"256 256 9 1",
+" 	c None",
+".	c #FEFEFE",
+"+	c #FDFDFD",
+"@	c #FAFAFA",
+"#	c #FBFBFB",
+"$	c #F8F8F8",
+"%	c #FCFCFC",
+"&	c #F9F9F9",
+"*	c #F7F7F7",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"  .               .               .               .               .               .               .               .               .               .     .         .     .         .     .         .     .         .     .         .     .         .     .       ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"  .               .               .               .               .               .               .               .               .               .               .               .               .               .               .               .             ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"  .               .               .               .               .               .               .               .               .               .               .               .     .         .     .         .     .         .     .         .     .       ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"  .               .               .               .               .               .               .               .               .               .               .               .               .               .               .               .             ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                  ..              ...             .                    ..         .                 +......       ..                 ..            .              .               .               ..              .               ..                   ..       ",
+"                  ..              ...                                 ...                          ........       .+               +...           ...+                                            ..                              ..                  ..        ",
+"                  ..              ...                              .........                       ..              @               ..               ..+                                            #                                                  .+        ",
+"                  ..                                              ..........                        ...                           ...                ..                                                                                              ..$        ",
+"                  ++                                              ... #..                          ...++  .+                      ...                ..                                                                                             #..         ",
+"                                                                  %......%%%.                     ...  %....                      ...                ..                                                                                             ..          ",
+"                  ..                                               +........+                     ..........+                     ...                .+                                                                                            +..          ",
+"                  ..                              .                    ..  ..     .               ...........#                    ...                .+           .               .                               .                                ..           ",
+"                  ..                                              &..........                       .....+                        ...                .+                                                                                            %@           ",
+"                                                                  &.........%                                                     ...                .+                                                                                                         ",
+"                                                                      ...                                                          ..               ..+                                                                                                         ",
+"                                                                                                                                   +...           ....#                                                                                                         ",
+"                                                                                                                                    ++.           ..%                                                                                                           ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"   .+....+#        ....           ..........      ..........             ..       ...........      +%.++%%##      ..........       .......+        +.....+%       ..              ..              .               .               .                ......       ",
+"  ..........      .....           ..........      ........%              ..       ...........      .........      ..........       ........+      &........+      ..              ..                                                               ......+      ",
+"  ...     .+        ...                   %.                      ..     ..                                                        ..    ..+      &..     ..                                                                                           ...      ",
+"  ..      ..        ...            +........             ..+      ..........       ........%      .........                        ........       @.........      ..              ..                                                                .....+      ",
+"  ..      ..        ...           ..........            .....     ..........       .........%     ..........           ..%         ........+       +........      ..              ..                                                                .....       ",
+"  ..      ..        ...                                   ...                             ...     ...     ..          @.+         ...     ..#                                      #                                                                            ",
+"  %......#.+        ...           ..........       ..........            ..        ..........     #..@@%+...         ...          ..........$      ........                                                                                          .          ",
+"   ........         ...           ...........     &.........             ..       &.........+      +........        ..+           ..........      .........                                                                                         ..          ",
+"     ....+           .            ..........       ........              ..        ........+         ......         ..              .......        ......+                                                                                           .          ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"  .               .........+      .........%       ........       ........+.       %.........      +........       .+.......      ...      ...    ...                  ...        ...     ..&     ...              .%.       .#.   +#%      ..     %.......+    ",
+"                  ...........     ..........#     .........       ..........+     +..........%    +.........      ..........      ...      ...    ...                  ...        ...   ++.       ...             %...+     ....  %...+     ..     ..........@  ",
+"                           %.%            ...     +..                      ..     @.       +..    +.+             +..             ...      ...    ...                  ...        ...  ..+        ...             ..#..     ..... ... .#    ..    +..      ..%  ",
+"                   ...........    ..........      ..                       ..     &...........    ..........      ...  ....       ... *.......    ...                  ...        ...  ..         ...             ... ..   .. ... ...  .%   ..    ...       ..  ",
+"                  ............    ..........      ..              ...      ..     &.........+     ..........      ...  .....      ... *.......    ...                  ...        ...  .#         ...             ... +.   .. ... ...  $..  ..    ...       ..  ",
+"                  ...      ...    ...      .+     ..              ...      ..     &..             ...             ...     ..      ...      ...    ...                  ...        ...  ...        ...             ...  .% +.  ... ...   +.. ..    +..       ..  ",
+"                  ............    ...........     %.+......       ..........+      ..........     ...             #.........      ...      ...    ...              ......+        ...   #.+       %.........      ...  ....#  ... ...    .....    %........#..  ",
+"  .               .........%..    ...........      +.......       ..........       %..........    ...              .........      ...      ...    ...             .......         ...    ...       .........      ...   ...   ... ...     ...@     +........+   ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"  .........%.      .+......+.     .........%       .........      ....... ....... ..       ..      ..       ..+   %..    ...    +. ...     ...    ...      ...    ..........         ..            ..              ..             .               ........      ",
+"  ..........+     %..........+    ..........#     ..........      &&&&#.. ....... ..       ..      %..      ..     ..    ...@   ..  ...   ..+     ...      ...     .........       ....            ..              ...                                          ",
+"           ..     %..      ..%            ...     ..+                  .. ..      ..       ..       ..     +.      ...   ....   ..   %.. ...      %..      ...                     ..               ..              ..+                                         ",
+"  ..........+     ..       ...    ..........%     .........+           .. ..      ..       ..       ..+   ..+       ..  .. .+  %..    .....        ..........                     ...               ..               ..                                         ",
+"  .........+.     ..       ...    ........+.       .........+          .. ..      ..       ..        ..   ..        ..  +. ..  +.     ....+         ........$        ....         ...                ..              ..                                         ",
+"  ...             ..%  %%  %..    ...   #.+                ..          .. ..      %..      ..        ..+ %..        ... .. ..+ ..    ... ...                        ..%           ...                ..              ..                                         ",
+"  ..              %......#+..#    ..     +..       ..........          .. ..       .........%         ..#..          +...   ....+   ...   ...         ....         .........      ...                 ..             .+                                         ",
+"  ..               %.........     ..      ..@     &..........          .. ..       #........           +..%          %..+   ....   ...     ...        ....        ...........     ...                 ..             .+                                         ",
+"                       ..                  ..                                                                                                                                     ...                                .+                                         ",
+"                                            ..                                                                                                                                    ...                                .+                                         ",
+"                                             ..                                                                                                                                    ..                               ..+                                         ",
+"                                                                                                                                                                                   +...                           ....                                          ",
+"                                                                                                                                                                                    %+.                            .%                                           ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"   ..             .........+      .........%       ........       ........+.       +........       +........       .+.......      ...      ...    ...                  ...        ...     ..&     ...              .+.       .%.   +%+      ..     %.......++   ",
+"                  .........+.     ..........#     +........        .........+     #.........      +.........      +.........      ...      ...    ...                  ...        ...   ...       ...             %...+     ....  %...+     ..     ..........#  ",
+"                           %.%            ...     +..                      ..     +.              +.+             +..             ...      ...    ...                  ...        ...  ..+        ...             ..#..     ..... ... .%    ..    +..      ..%  ",
+"                   ...........    ..........      ..               .       ..     ..........      ..........      ...  ....       ... *.......    ...                  ...        ...  ..         ...             ... ..   .. ... ...  .+   ..    ...       ..  ",
+"                  ............    ..........      ..              ...      ..     ..........      ..........      ...  .....      ... *.......    ...                  ...        ...  .%         ...             ... +.   .. ... ...  $..  ..    ...       ..  ",
+"                  ...      ...    ...      .+     ...             ...      ..     ...             ...             ...     ..      ...      ...    ...                  ...        ...  ...        ...             ...  .% +.  ... ...   +.. ..    +..       ..  ",
+"                  ............    ...........     %.+......       ..........+     %.........      ...             #.........      ...      ...    ...              ......+        ...   #.+       %.........      ...   ...#  ... ...    .....     ........%..  ",
+"                  .........%..    ...........      +.......       .........+       %........      ...              .........      ...      ...    ...             .......         ...     ..+      .........      ...   ...   ... ...     ...@     +........+   ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"  .........+.      .+......+.     .........+.      .........      ....... ....... ..       ..      ..       ..+   %..    ...    +. ...     ...    ...      ...    ..........      .               ...             .               .               .             ",
+"  ..........+     %..........%    ..........%     ..........       &&&#.. ....... ..       ..      %..      ..     ..    ...@   ..  ...   ..+     ...      ...     .........                      ...                                                           ",
+"           ..     +..      ..%             ..     ..+                  .. ..      ..       ..       ..     +.      ...   ....   ..   %.. ...      #..      ...                                    ..                                                            ",
+"  ..........+     ..       ...    ..........%     +........+           .. ..      ..       ..       +..   ..+       ..  .. .+  %.+    .....        ..........          ..                                                                                       ",
+"  .........+      ..       ...    .........+       .........+          .. ..      ..       ..        ..   ..        ..  +. ..  +.     ....+         ........$        ....                                                                                       ",
+"  ...             ..%  ++  %..    ...      .%              ..          .. ..      %..      ..         .+ +..        +.. ..  .+ ..    ... ...                        ..#                           &&                                                            ",
+"  ..              #......#+..#    ..       ..     &..........          .. ..       .........+         +.%..          +...   ....+   ...   ...         ....         .........                      ...                                                           ",
+"  ..               %.........     ..       ...    &..........          .. ..       #........           +..           %..+   ....   ...     ...        ....        ...........                     ...                                                           ",
+"                       ..                                                                                                                                                                                                                                       ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"  .               .               .               .               .               .               .               .               .               .                                                                                                             ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                  ..                   ..           .+.....                         ..      ...   ...                             .. ..                                                                                                                         ",
+"                  ..                   ...          ......                          ..      ...   ...                             ..  .                                                                                                                         ",
+"                                   %.......         ...                             ..      ...   ..                                                                                                                                                            ",
+"                  ..              +........       #%.....                         . +......... .                                                                                                                                                                ",
+"                  ..              +..  +.         .....%#                         #  .+.....+@ #                                                                                                                                                                ",
+"                  ..              ..   #.           ..                                            &&                                                                                                                                                            ",
+"                  ..              ..   &.           ......                              ...       ...                                                                                                                                                           ",
+"                  ..              ...  @.         +.......                             ....       ...                                                                                                                                                           ",
+"                                  +...@+...                                                                                                                                                                                                                     ",
+"                                   #.......                                                                                                                                                                                                                     ",
+"                                       ...                                                                                                                                                                                                                      ",
+"                                       ..                                                                                                                                                                                                                       ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                   ..                                                              ..+                                                                                                                ..        ",
+"                                                                                                                                                                                                                                                      ..        ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                   +....        ",
+"                                                                                                                                                                                                                                                  +.....        ",
+"                                                                                                                                                                                                                                                  ...           ",
+"                                                                                                                                                                                                                                                  +.......      ",
+"                                                                                                                                                                                                                                                   .......      ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"      .@               ..             ...             ...+           .. ..                        ..........%..... ........           +.                .%            .+.+           ..  .         ..              @.              ..+..           .  .         ",
+"                       *             %% #%           ...&            .  ..                         ...........@   #........                                                           .  .          %%                                             .  .         ",
+"   ........                                                                                                ..+    +..                ......                          ......                                        .                 .                          ",
+"  ...........     .........+      .........+      .........+      .........+                       .......+..%.......              +.........      %.........      +.........      %.........       ...           ...               ...             ..          ",
+"   ........%.     ...........     ...........     ...........     ...........      ........%      ...........#.......             +..........+     ..........%    +..........+     ..........%      ...           ...               ...             ..          ",
+"           ..+             %.%             %.%             %.%             %.%    ...........     ...      ..+    ..+             &..      +..    @..      +..    &..      +..    @..       ..      ...           ...               ...             ..          ",
+"   ...........     ...........     ...........     ...........     ...........             %.%    ........+....   +........       &...........    &...........    &...........    &...........      ...           ...               ...             ..          ",
+"  ............    ............    ............    ............    ............      ...... ...     .......+%...... ++......       &.........%     &.........+     &.........%     &.........+       ...           ...               ...             ..          ",
+"  ..       ...    ...      ...    ...      ...    ...      ...    ...      ...    +...........                        +..         #..             &..             #..             &..               ...           ...               ...             ..          ",
+"  ............    ............    ............    ............    ............    ...      ...                                     ...........     ..........      ...........     ..........       ...           ...               ...             ..          ",
+"   ........%..    .........+..    .........+..    .........+..    .........+..    ...      ...                                      +.........     %..........      +.........     %..........      ...           ...               ...             ..          ",
+"                    ......  .       ......  .       ......  .       ......  .     ............                                                       ........                        ........        .                                              ..          ",
+"                                                                                   .......+ ..                                                                                                                                                                  ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"   .........+          ....           ..+               ..            ....             ...#           .  ..                          .......+..       ..               &+.            ..+.           .@ .+              +.        ...             ..........    ",
+"    .........+        +..                               *                             ...             .  .                          +.........%                                                      .@  +                        .........++     ..+.......+   ",
+"            ..                       ......                          ......                                                        %..    ..%.+   ..       ..     ..       ..     ...      ..      .       ..      ..      ...    ...........     ..%     ...   ",
+"  .......   ..     +#%      ..     +........+      %.......+       +........+      %.......+       %.......+                       ...   %+  ..   ...      ..     ...      ..     ...      ..     ...      ..     ...      ...             ..     ..........    ",
+"  .......   ..    %...%     ..    +..........+    #..........     +..........+    #..........     #..........                      ...  ..   ..   ...      ..     ...      ..     ...      ..     ...      ..     +..      ...            ...     ...........   ",
+"   ...      ..    ..  .#    ..    ..       ..+    +..      ..%    ..       ..+    +..      ..%    +..      ..%                     ... +.    ..   ...      ..     ...      ..     ...      ..     ...      ..      ..........     ..........+     ..&      ..   ",
+"   ...........    ..   .%   ..    ..       ...    ..       ...    ..       ...    ..       ...    ...      ...                      ...++   #..   ...      ..     ...      ..     ...      ..     ...      ..      +........@     .........#      ..&  +.....   ",
+"   .........+     ..   &..  ..    ..       ...    ..       ...    ..       ...    ..       ...    ...      ...                      ..........    ...      ..     ...      ..     +..      ..     ...      ..                     ...             ..&  +.....   ",
+"                  ..    ... ..    +.+      #..    +.       ...    +..      #..    +.       ...    +..      ...                      .@......%     %..      .+     %..      .+     +..     ..+     %..      .+                     ..              ..&           ",
+"                  ..     .....    @..........     %........%..     ..........     %........%..    %........%..                                     ..........      ..........      +........       ..........         ....                        ..            ",
+"                  ..      ...@     %+......%+      +........+      %+......%+      +........+      +........+                                      @+.......       &+.......         .....+        &+.......          ....                                      ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"      .+               ..            .....            ...%          ... ..           .  +         ..........%..... ........           ..+              ..+            .+.#           ..  .          ..             ..%             ..+.%           .  .         ",
+"                                                     ...             .  ..           .  %          ........%..#   #........                                                           .  .                                                         .  .         ",
+"   ........        ........        ........        ........        ........          ...#                  ...    ...                .......         .......         .......                         ..            ..                .                          ",
+"  ...........     ...........     ...........     ...........     ...........                      ..................              +........       +........       +........        ........         ..           ...               ...             ..          ",
+"           %.+             %.+             %.+             %.+             %.+    .........%      ............    ...             %.+             %.+             %.+             #.........         ..           ...               ...             ..          ",
+"           ..+             ..+             ..+             ..+             ..+    ...........     ...      ...    ...             ..              ..              ..#             +.                 ..           ...               ...             ..          ",
+"  %...........    %...........    %...........    %...........    %...........             %.%    .............   +........       ..........      ..........      ..........      ..........         ..           ...               ...             ..          ",
+"  ............    ............    ............    ............    ............     +...... ...     ........%...... ++......       ..........      ..........      ..........      ..........         ..           ...               ...             ..          ",
+"  ..       ...    ..       ...    ..       ...    ..       ...    ...      ...    +...........                        ...         ...             ...             ...             ...                ..           ...               ...             ..          ",
+"  ............    ............    ............    ............    ............    ...      ...                       &@            .........       .........       .........      %.........         ..           ...               ...             ..          ",
+"   ........%..     ........%..     ........%..     ........%..     ........%..    ...      ...                                     @+.......       @+.......       @+.......       %........         ..           ...               ...             ..          ",
+"                                                                                  .........+..                                                                                                                                                                  ",
+"                                                                                   .......+ ..                                                                                                                                                                  ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"   ..........          +..%           %..              ..+            ....             ..++          ..  ..                          .......+..       ..               ...           ..%..           .. ..             ..@        ...                ..  .      ",
+"    .........+        +..                                                             +..             .  .                          +.........%                                                      ..  .                        .........++         .  .      ",
+"            ..      *                ......          ......          ......          ......          ......                        %..    ..#.+   ..       ..     ...      ..     ...      ..     ..       ..     ...      ...    ...........      ..      ..   ",
+"  .......   ..     ..++     ..     +........+      +........+      +........+      +........+      +........+                      ...   ++  ..   ...      ..     ...      ..     ...      ..     ...      ..     ...      ...             ..      ..      ...  ",
+"  .......   ..    +....#    ..    +..      ..+    +..      ..+    +..      ..+    +..      ..+    +..      ..+                     ...  ..   ..   ...      ..     ...      ..     ...      ..     ...      ..     %..      ...    ...........      ..      ...  ",
+"   ...      ..    ..  .+*   ..    ..       ..+    ..       ..+    ..       ..+    ..       ..+    ...      ..+                     ... +.    ..   ...      ..     ...      ..     ...      ..     ...      ..      +.........     ..........+      ..      ..   ",
+"   ...........    ..   ++   ..    ..       ...    ..       ...    ..       ...    ..       ...    ...      ...                      ...++...#..   ...      ..     ...      ..     ...      ..     ...      ..       ........@     ...              +........%   ",
+"   .........+     ..    +.  ..    ..       ...    ..       ...    ..       ...    ..       ...    ...      ...                      .........+    ...      ..     +..      ..     +..      ..     ...      ..                     ...                +.....+    ",
+"                  ..     .....    +.+      #..    +..      #..    +..      #..    +..      #..    +..      #..                      .&......      %..     ..+     +..     ..+     +..     ..+     #..     ..+                      .                            ",
+"                  ..      ...+     ..........      ..........      ..........      ..........      ..........                                      ..........      %........       %........       ..........         ....                            ....      ",
+"                  ..       %+       +......%        +......%        +......%        +......%        +......%                                        +.....+.         .....+          .....+         +.......           ...                            ....      ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                "};
Index: branches/network/src/lib/graphics/text_engine/font.cc
===================================================================
--- branches/network/src/lib/graphics/text_engine/font.cc	(revision 6636)
+++ branches/network/src/lib/graphics/text_engine/font.cc	(revision 6636)
@@ -0,0 +1,603 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "font.h"
+#include "text.h"
+
+#ifdef HAVE_SDL_IMAGE_H
+#include <SDL_image.h>
+#else
+#include <SDL/SDL_image.h>
+#endif
+#include "default_font.xpm"
+
+#include "debug.h"
+#include "stdlibincl.h"
+#include "compiler.h"
+
+using namespace std;
+
+/**
+ * constructs a Font out of a TTF-FIle
+ * @param fontFile the File to load the font from
+ * @param fontSize the Size of the Font in Pixels
+ */
+Font::Font(const char* fontFile, unsigned int renderSize)
+{
+  this->init();
+
+  this->renderSize = renderSize;
+  this->setStyle("c");
+
+  if (fontFile != NULL)
+    this->loadFontFromTTF(fontFile);
+}
+
+/**
+ * constructs a Font out of an ImageFile
+ * @param imageFile the ImageFile to load the Font From.
+ */
+Font::Font(const char* imageFile)
+{
+  this->init();
+  this->setName(imageFile);
+  //  this->setSize(fontSize);
+  SDL_Surface* image = NULL;
+  if (imageFile != NULL)
+    image = IMG_Load(imageFile);
+  else
+    return;
+  if (image != NULL)
+  {
+    this->loadFontFromSDL_Surface(image);
+    SDL_FreeSurface(image);
+  }
+  else
+    PRINTF(1)("loading from surface %s failed: %s\n", imageFile, IMG_GetError());
+}
+
+/**
+ * constructs a Font
+ * @param xpmArray the xpm-ARRAY to load the font from
+ */
+Font::Font(char** xpmArray)
+{
+  this->init();
+  this->setName("XPM-array-font");
+  //  this->setSize(fontSize);
+  SDL_Surface* image = NULL;
+  if (xpmArray != NULL)
+    image = IMG_ReadXPMFromArray(xpmArray);
+  if (image != NULL)
+  {
+    this->loadFontFromSDL_Surface(image);
+    SDL_FreeSurface(image);
+  }
+  else
+    PRINTF(1)("loading from surface failed: %s\n", IMG_GetError());
+}
+
+
+/**
+ * destructs a font
+ * this releases the memory a font uses to be opened.
+ * deletes the glLists, and the TTF-handler, if present.
+ */
+Font::~Font()
+{
+  // deleting all Glyphs
+  if (this->glyphArray != NULL)
+  {
+    for (int i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++)
+    {
+      if (this->glyphArray[i] != NULL)
+      {
+        delete this->glyphArray[i];
+      }
+    }
+    delete[] this->glyphArray;
+  }
+
+  //! @todo check if we really do not need to delete the fastTextureID here.
+//   if (this->fastTextureID != 0)
+//     if(glIsTexture(this->fastTextureID))
+//       glDeleteTextures(1, &this->fastTextureID);
+
+  // erease this font out of the memory.
+  if (likely(this->fontTTF != NULL))
+    TTF_CloseFont(this->fontTTF);
+}
+
+/**
+ * initializes a Font (with default values)
+ */
+void Font::init()
+{
+  this->setClassID(CL_FONT, "Font");
+  // setting default values.
+  this->fontTTF = NULL;
+  this->glyphArray = NULL;
+}
+
+
+/**
+ * sets The Font.
+ * @param fontFile The file containing the font.
+ * @returns true if loaded, false if something went wrong, or if a font was loaded before.
+ */
+bool Font::loadFontFromTTF(const char* fontFile)
+{
+  // checking for existent Font.
+  if (this->fontTTF != NULL)
+  {
+    TTF_CloseFont(this->fontTTF);
+    this->fontTTF = NULL;
+  }
+
+
+  this->setName(fontFile);
+  this->fontTTF = TTF_OpenFont(this->getName(), this->renderSize);
+
+  if(this->fontTTF != NULL)
+  {
+    this->createFastTexture();
+    return (this->getTexture() != 0);
+  }
+  else
+  {
+    PRINTF(1)("TTF_OpenFont: %s\n", TTF_GetError());
+    return false;
+  }
+
+}
+
+/**
+ * loads a font From an XPM-array.
+ * @param xpmArray the array of the XPM to load the font from.
+ */
+bool Font::loadFontFromSDL_Surface(SDL_Surface* surface)
+{
+  // loading to a texture.
+  if(surface == NULL)
+    return false;
+
+  if (this->fontTTF != NULL)
+  {
+    TTF_CloseFont(this->fontTTF);
+    this->fontTTF = NULL;
+  }
+  bool hasAlpha;
+  SDL_Surface* newSurf = this->prepareSurface(surface, hasAlpha);
+  if (newSurf != NULL)
+  {
+    this->setSurface(newSurf);
+    this->setAlpha(hasAlpha);
+    this->setTexture(Texture::loadTexToGL(newSurf));
+  }
+
+  // initializing the Glyphs.
+  if (this->glyphArray == NULL)
+  {
+    float cx,cy;
+    Glyph* tmpGlyph;
+    this->glyphArray = new Glyph*[FONT_HIGHEST_KNOWN_CHAR];
+    for (int i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++)
+    {
+      tmpGlyph = this->glyphArray[i] = new Glyph;
+      cx=(float)(i%16)/16.0f;                  // X Position Of Current Character
+      cy=(float)(i/16)/16.0f;                  // Y Position Of Current Character
+
+      tmpGlyph->texCoord[0] = cx;
+      tmpGlyph->texCoord[1] = cx+0.0625f;
+      tmpGlyph->texCoord[2] = cy+0.001f;
+      tmpGlyph->texCoord[3] = cy+0.0625f;
+      tmpGlyph->width = 1;
+      tmpGlyph->advance = 1;
+      tmpGlyph->bearingX = 1;
+      tmpGlyph->bearingY = 1;
+      tmpGlyph->height = 1;
+    }
+  }
+  return true;
+}
+
+
+/**
+ *  sets a specific renderStyle
+ * @param renderStyle the Style to render: a string (char-array) containing:
+ *   i: italic, b: bold, u, underline
+ */
+void Font::setStyle(const char* renderStyle)
+{
+  this->renderStyle = TTF_STYLE_NORMAL;
+
+  for (int i = 0; i < strlen(renderStyle); i++)
+    if (strncmp(renderStyle+i, "b", 1) == 0)
+      this->renderStyle |= TTF_STYLE_BOLD;
+  else if (strncmp(renderStyle+i, "i", 1) == 0)
+    this->renderStyle |= TTF_STYLE_ITALIC;
+  else if (strncmp(renderStyle+i, "u", 1) == 0)
+    this->renderStyle |= TTF_STYLE_UNDERLINE;
+
+  if (likely(this->fontTTF != NULL))
+    TTF_SetFontStyle(this->fontTTF, this->renderStyle);
+//  else
+//    PRINTF(2)("Font was not initialized, please do so before setting the Font-Style.\n");
+}
+
+Font* Font::defaultFont = NULL;
+
+/**
+ * creates and exports an Image, that has all the characters
+ * stored in a Array (as an image)
+ * @param fileName the File to write the image into.
+ */
+void Font::createAsciiImage(const char* fileName, unsigned int size) const
+{
+  if (this->fontTTF == NULL)
+    return;
+  int height = this->getMaxHeight();
+
+  //
+  SDL_Color tmpColor = {0, 0, 0};
+  // Surface definition.
+  SDL_Rect tmpRect; // this represents a Rectangle for blitting.
+  SDL_Surface* tmpSurf =  SDL_CreateRGBSurface(SDL_SWSURFACE,
+                                               height*size, height*size,
+                                               32,
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
+                                               0x000000FF,
+                                               0x0000FF00,
+                                               0x00FF0000,
+                                               0xFF000000
+#else
+                                               0xFF000000,
+                                               0x00FF0000,
+                                               0x0000FF00,
+                                               0x000000FF
+#endif
+                                              );
+  tmpRect.x = 0; tmpRect.y = 0; tmpRect.w = tmpSurf->w; tmpRect.h = tmpSurf->h;
+  SDL_SetClipRect(tmpSurf, &tmpRect);
+  int maxLineHeight = 0;
+
+  int posX, posY;
+  // all the interessting Glyphs
+  for (posY = 0; posY < 16; posY++)
+  {
+    for (posX = 0; posX < 16; posX++)
+    {
+      SDL_Surface* glyphSurf = NULL;
+      if (likely(this->fontTTF != NULL))
+      {
+        SDL_Color white = {255, 255, 255};
+        glyphSurf = TTF_RenderGlyph_Blended(this->fontTTF, posX+size*posY, white);
+      }
+      if( glyphSurf != NULL )
+      {
+        tmpRect.x = height*posX;
+        tmpRect.y = height*posY;
+        SDL_SetAlpha(glyphSurf, 0, 0);
+
+        SDL_BlitSurface(glyphSurf, NULL, tmpSurf, &tmpRect);
+        SDL_FreeSurface(glyphSurf);
+      }
+    }
+  }
+  SDL_SaveBMP(tmpSurf, fileName);
+  SDL_FreeSurface(tmpSurf);
+}
+
+/**
+ * initializes the default font
+ */
+void Font::initDefaultFont()
+{
+  if (Font::defaultFont == NULL)
+    Font::defaultFont = new Font(font_xpm);
+}
+
+/**
+ * deletes the default font
+ */
+void Font::removeDefaultFont()
+{
+  if (Font::defaultFont != NULL)
+    delete Font::defaultFont;
+  Font::defaultFont = NULL;
+}
+
+
+/**
+ * @returns the maximum height of the Font, if the font was initialized, 0 otherwise
+ */
+int Font::getMaxHeight() const
+{
+  if (likely (this->fontTTF != NULL))
+    return TTF_FontHeight(this->fontTTF);
+  else
+    return 0;
+}
+
+/**
+ * @returns the maximum ascent of the Font, if the font was initialized, 0 otherwise
+
+   the ascent is the pixels of the font above the baseline
+ */
+int Font::getMaxAscent() const
+{
+  if (likely(this->fontTTF != NULL))
+    return TTF_FontAscent(this->fontTTF);
+  else
+    return 0;
+}
+
+/**
+ * @returns the maximum descent of the Font, if the font was initialized, 0 otherwise
+
+   the descent is the pixels of the font below the baseline
+ */
+int Font::getMaxDescent() const
+{
+  if (likely(this->fontTTF != NULL))
+    return TTF_FontDescent(this->fontTTF);
+  else
+    return 0;
+}
+
+/**
+ * @param character The character to get info about.
+ * @returns a Glyph struct of a character. This Glyph is a pointer,
+   and MUST be deleted by the user..
+
+   This only works for horizontal fonts. see
+   http://freetype.sourceforge.net/freetype2/docs/tutorial/step2.html
+   for more info about vertical Fonts
+ */
+Glyph* Font::getGlyphMetrics(Uint16 character)
+{
+  Glyph* rg = new Glyph;
+  rg->character = character;
+  if (likely (this->fontTTF!= NULL))
+  {
+    int miX, maX, miY, maY, adv;
+    TTF_GlyphMetrics(this->fontTTF, rg->character,
+                     &miX, &maX,
+                     &miY, &maY,
+                     &adv);
+    rg->minX = (float)miX / (float)this->renderSize;
+    rg->maxX = (float)maX / (float)this->renderSize;
+    rg->minY = (float)miY / (float)this->renderSize;
+    rg->maxY = (float)maY / (float)this->renderSize;
+    rg->advance = (float)adv / (float)this->renderSize;
+  }
+  rg->height = rg->maxY - rg->minY;
+  rg->width = rg->maxX - rg->minX;
+  rg->bearingX = (rg->advance - rg->width) / 2;
+  rg->bearingY = rg->maxY;
+  return rg;
+}
+
+/**
+ * creates a Fast-Texture of this Font
+ */
+bool Font::createFastTexture()
+{
+  /* interesting GLYPHS:
+  *  32: space
+  *  33-47: Special Characters.
+  *  48-57: 0-9
+  *  58-63: some more special chars (minor)
+  *  65-90: A-Z
+  *  97-122: a-z
+  */
+  int numberOfGlyphs = 91;
+
+  this->initGlyphs(32, numberOfGlyphs);
+//  this->glyphArray[32]->width = .5f; //!< @todo find out the real size of a Space
+
+  int rectSize = this->findOptimalFastTextureSize();
+
+  // setting default values. (maybe not needed afterwards)
+  SDL_Color tmpColor;  tmpColor.r = tmpColor.g = tmpColor.b = 0;
+  // Surface definition.
+  SDL_Rect tmpRect; // this represents a Rectangle for blitting.
+  SDL_Surface* tmpSurf =  SDL_CreateRGBSurface(SDL_SWSURFACE,
+                                               rectSize, rectSize,
+                                               32,
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
+                                               0x000000FF,
+                                               0x0000FF00,
+                                               0x00FF0000,
+                                               0xFF000000
+#else
+                                               0xFF000000,
+                                               0x00FF0000,
+                                               0x0000FF00,
+                                               0x000000FF
+#endif
+                                              );
+  tmpRect.x = 0; tmpRect.y = 0; tmpRect.w = tmpSurf->w; tmpRect.h = tmpSurf->h;
+  SDL_SetClipRect(tmpSurf, &tmpRect);
+  int maxLineHeight = this->getMaxHeight();
+
+  // all the interessting Glyphs
+  for (int i = 0; i < 128; i++)
+  {
+    SDL_Surface* glyphSurf = NULL;
+    Glyph* tmpGlyph;
+
+    if (tmpGlyph = this->glyphArray[i])
+    {
+      if (tmpGlyph->height*this->renderSize > maxLineHeight)
+        maxLineHeight = (int)(tmpGlyph->height*this->renderSize);
+
+      if (tmpRect.x+tmpGlyph->advance*this->renderSize > tmpSurf->w)
+      {
+        tmpRect.x = 0;
+        tmpRect.y = tmpRect.y + maxLineHeight;
+      }
+      if (tmpRect.y + maxLineHeight > tmpSurf->h)
+      {
+        PRINTF(1)("Protection, so font cannot write over the boundraries (!!this should not heappen!!)\n");
+        break;
+      }
+          // reading in the new Glyph
+      if (likely(this->fontTTF != NULL))
+      {
+        SDL_Color white = {255, 255, 255};
+        glyphSurf = TTF_RenderGlyph_Blended(this->fontTTF, i, white);
+      }
+      if( glyphSurf != NULL )
+      {
+        SDL_SetAlpha(glyphSurf, 0, 0);
+        int tmp = tmpRect.y;
+        tmpRect.y += this->getMaxAscent()-(int)((float)tmpGlyph->bearingY*this->renderSize);
+        SDL_BlitSurface(glyphSurf, NULL, tmpSurf, &tmpRect);
+        tmpRect.y = tmp;
+
+        tmpGlyph->texCoord[0] = (float)(tmpRect.x)/(float)tmpSurf->w;
+        tmpGlyph->texCoord[1] = (float)(tmpRect.x + tmpGlyph->width*(float)this->renderSize)/(float)tmpSurf->w;
+        tmpGlyph->texCoord[2] = (float)(tmpRect.y)/(float)tmpSurf->w;
+        tmpGlyph->texCoord[3] = (float)(tmpRect.y+this->getMaxHeight())/(float)tmpSurf->w;
+        SDL_FreeSurface(glyphSurf);
+        tmpRect.x += (int)(tmpGlyph->advance * this->renderSize)+1;
+
+        /*
+        // Outputting Glyphs to BMP-files.
+        char outname[1024];
+        if (i < 10)
+        sprintf( outname, "%s-glyph-00%d.bmp", this->getName(), i );
+        else if (i <100)
+        sprintf( outname, "%s-glyph-0%d.bmp", this->getName(), i );
+        else
+        sprintf( outname, "%s-glyph-%d.bmp", this->getName(), i );
+        SDL_SaveBMP(tmpSurf, outname);*/
+      }
+    }
+  }
+  // outputting the GLYPH-table
+  //   char outName[1024];
+  //   sprintf( outName, "%s-glyphs.bmp", this->getName());
+  //   SDL_SaveBMP(tmpSurf, outName);
+
+  if (this->setSurface(tmpSurf))
+    (this->setTexture(Texture::loadTexToGL(tmpSurf)));
+}
+
+/**
+ *  stores Glyph Metrics in an Array.
+ * @param from The Glyph to start from.
+ * @param count The number of Glyphs to start From.
+ */
+void Font::initGlyphs(Uint16 from, Uint16 count)
+{
+  /* initialize the Array, and set all its entries to NULL
+  *  only if the Glyph-array has not been initialized
+  */
+  if (!this->glyphArray)
+  {
+    this->glyphArray = new Glyph*[FONT_HIGHEST_KNOWN_CHAR];
+    for (int i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++)
+      this->glyphArray[i] = NULL;
+  }
+
+  Uint16 lastGlyph = from + count;
+
+  for (int i = from; i <= lastGlyph; i++)
+  {
+      // setting up all the Glyphs we like.
+    glyphArray[i] = getGlyphMetrics(i);
+  }
+  return;
+}
+
+/**
+ * @returns the optimal size to use as the texture size
+
+   @todo: this algorithm can be a lot faster, althought it does
+   not really matter within the init-context, and 128 glyphs.
+
+   This function searches for a 2^n sizes texture-size, this is for
+   openGL-version < 1.2 compatibility ( and because it is realy easy like this :))
+ */
+int Font::findOptimalFastTextureSize()
+{
+  if (this->glyphArray == NULL)
+    return 0;
+
+  int i;
+  int x,y; // the counters
+  int maxLineHeight = this->getMaxHeight();
+  unsigned int size = 32;  // starting Value, we have to start somewhere 32 seems reasonable. (take any small enough 2^i number)
+  bool sizeOK = false;
+  Glyph* tmpGlyph;
+
+  while (!sizeOK)
+  {
+    x = 0; y = 0;
+    for (i = 0; i < FONT_HIGHEST_KNOWN_CHAR; i++)
+    {
+      if((tmpGlyph = this->glyphArray[i]) != NULL)
+      {
+              // getting the height of the highest Glyph in the Line.
+        if (tmpGlyph->height*this->renderSize > maxLineHeight)
+          maxLineHeight = (int)(tmpGlyph->height*this->renderSize);
+
+        if (x + tmpGlyph->advance*this->renderSize > size)
+        {
+          x = 0;
+          y = y + maxLineHeight;
+                  //maxLineHeight = 0;
+        }
+        if (y + maxLineHeight + 1 > size)
+          break;
+        x += (int)(tmpGlyph->advance*this->renderSize)+1;
+
+      }
+    }
+    if (i >= FONT_HIGHEST_KNOWN_CHAR-1 || size > 8192)
+      sizeOK = true;
+    else
+      size *= 2;
+  }
+  return size;
+}
+
+
+/**
+ *  a simple function to get some interesting information about this class
+ */
+void Font::debug()
+{
+  // print the loaded font's style
+  int style;
+  if (likely(this->fontTTF != NULL))
+    style = TTF_GetFontStyle(this->fontTTF);
+  PRINTF(0)("The font style is:");
+  if(style==TTF_STYLE_NORMAL)
+    PRINTF(0)(" normal");
+  else {
+    if(style&TTF_STYLE_BOLD)
+      PRINTF(0)(" bold");
+    if(style&TTF_STYLE_ITALIC)
+      PRINTF(0)(" italic");
+    if(style&TTF_STYLE_UNDERLINE)
+      PRINTF(0)(" underline");
+  }
+  PRINTF(0)("\n");
+}
Index: branches/network/src/lib/graphics/text_engine/font.h
===================================================================
--- branches/network/src/lib/graphics/text_engine/font.h	(revision 6636)
+++ branches/network/src/lib/graphics/text_engine/font.h	(revision 6636)
@@ -0,0 +1,107 @@
+/*!
+ * @file font.h
+ * brief Definition of the FONT-loading class
+ *
+ * !! IMPORTANT !! When using ttf fonts clear the license issues prior to
+ * adding them to orxonox. This is really important, because we do not want
+ * to offend anyone.
+ */
+
+#ifndef _FONT_H
+#define _FONT_H
+
+#include "texture.h"
+
+#include "glincl.h"
+
+
+#ifdef HAVE_SDL_TTF_H
+#include <SDL_ttf.h>
+#else
+#include <SDL/SDL_ttf.h>
+#endif
+
+/* some default values */
+#define FONT_NUM_COLORS              256           //!< number of colors.
+
+#define FONT_HIGHEST_KNOWN_CHAR      128           //!< The highest character known to the textEngine.
+#define FONT_DEFAULT_RENDER_SIZE     50            //!< At what Resolution to render fonts.
+// FORWARD DECLARATION
+
+//! A struct for handling glyphs
+/**
+ * a Glyph is one letter of a certain font
+ */
+struct Glyph
+{
+  // Glyph-specific (size and so on)
+  Uint16   character;         //!< The character
+  float    minX;              //!< The minimum distance from the origin in X
+  float    maxX;              //!< The maximum distance from the origin in X
+  float    minY;              //!< The minimum distance from the origin in Y
+  float    maxY;              //!< The maximum distance from the origin in Y
+  float    width;             //!< The width of the Glyph
+  float    height;            //!< The height of the Glyph
+  float    bearingX;          //!< How much is right of the Origin
+  float    bearingY;          //!< How much is above the Origin
+  float    advance;           //!< How big a Glyph would be in monospace-mode
+
+  GLfloat texCoord[4];        //!< Texture coordinates: 0:left, 1:right, 2: top, 3: bottom.
+};
+
+
+//! A class to handle a Font of a certain ttf-File/image-file, Size.
+class Font : public Texture
+{
+  public:
+    Font(const char* fontFile,
+         unsigned int renderSize);
+    Font(const char* imageFile);
+    Font(char** xpmArray);
+    virtual ~Font();
+
+    void init();
+
+  //  font
+    bool loadFontFromTTF(const char* fontFile);
+    bool loadFontFromSDL_Surface(SDL_Surface* surface);
+
+    void setStyle(const char* renderStyle);
+
+    /** @returns a Pointer to the Array of Glyphs */
+    inline Glyph** getGlyphArray() const { return this->glyphArray; };
+    /** @returns the a pointer to the TTF */
+    inline TTF_Font* getTTF() const { return this->fontTTF; };
+
+
+    /** @returns the default Font */
+    inline static Font* getDefaultFont() { if (Font::defaultFont == NULL) initDefaultFont(); return Font::defaultFont; };
+
+    void createAsciiImage(const char* fileName, unsigned int size) const;
+    static void initDefaultFont();
+    static void removeDefaultFont();
+
+  private:
+    int getMaxHeight() const;
+    int getMaxAscent() const;
+    int getMaxDescent() const;
+    Glyph* getGlyphMetrics(Uint16 character);
+
+    bool createFastTexture();
+
+    void initGlyphs(Uint16 from, Uint16 count);
+    int findOptimalFastTextureSize();
+
+    void debug();
+
+  private:
+    static Font*  defaultFont;         //!< a default font, that is used, if other fonts were unable to be loaded.
+    // information about the Font
+    TTF_Font*     fontTTF;             //!< The font we use for this.
+    int           renderStyle;         //!< The Renderstyle
+    unsigned int  renderSize;          //!< How big the Font should be rendered.
+
+    Glyph**       glyphArray;          //!< An Array of all the Glyphs stored in the Array of Glyphs.
+};
+
+#endif /* _FONT_H */
Index: branches/network/src/lib/graphics/text_engine/text.cc
===================================================================
--- branches/network/src/lib/graphics/text_engine/text.cc	(revision 6636)
+++ branches/network/src/lib/graphics/text_engine/text.cc	(revision 6636)
@@ -0,0 +1,341 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "text.h"
+#include "font.h"
+
+#include "graphics_engine.h"
+#include "resource_manager.h"
+#include "class_list.h"
+#include "debug.h"
+#include "p_node.h"
+
+using namespace std;
+
+/**
+ *  creates a new Text Element
+ * @param fontFile the Font to render this text in
+ * @param type The renderType to display this font in
+ */
+Text::Text(const char* fontFile, unsigned int textSize)
+{
+  this->init();
+
+  if (fontFile != NULL)
+    this->setFont(fontFile, FONT_DEFAULT_RENDER_SIZE);
+  this->setSizeY2D(textSize);
+}
+
+/**
+ *  deletes a Text out of memory
+ *
+ * This also ereases the text from the textList of the TextEngine
+ */
+Text::~Text()
+{
+  if (this->font != NULL && this->font != Font::getDefaultFont())
+    ResourceManager::getInstance()->unload(this->font);
+
+  if (this->text)
+    delete[] this->text;
+}
+
+/**
+ * initializes Text
+ */
+void Text::init()
+{
+  this->setClassID(CL_TEXT, "Text");
+
+  // initialize this Text
+  this->font = NULL;
+  this->text = NULL;
+  this->externText = NULL;
+  this->setAlignment(TEXT_DEFAULT_ALIGNMENT);
+  this->blending = TEXT_DEFAULT_BLENDING;
+  this->color = TEXT_DEFAULT_COLOR;
+  this->setSize(TEXT_DEFAULT_SIZE);
+  this->setText(NULL);
+}
+
+/**
+ * sets the Font of this Text to font from fontFile
+ * @param fontFile the File to load the Font from.
+ * @param fontSize the Size of the Font
+ */
+void Text::setFont(const char* fontFile, unsigned int fontSize)
+{
+  Font* tmpFont;
+  Text* newText;
+  Vector tmpVec;
+
+  // unloading the Font if we alrady have one loaded.
+  if (this->font != NULL && this->font != Font::getDefaultFont())
+    ResourceManager::getInstance()->unload(this->font);
+  this->font = NULL;
+
+  // load a new Font
+  if (fontFile != NULL)
+  {
+    tmpFont = (Font*)ResourceManager::getInstance()->load(fontFile, TTF, RP_GAME, &fontSize);
+    if (tmpFont != NULL)
+      this->font = tmpFont;
+    else
+      PRINTF(2)("Font %s could not be loaded, probably file not found\n", fontFile);
+  }
+}
+
+/**
+ * Sets a new Text to the font
+ * @param text the new text to set
+ */
+void Text::setText(const char* text, bool isExtern)
+{
+  if (isExtern)
+  {
+    this->externText = text;
+
+    if (unlikely(this->text != NULL))
+    {
+      delete[] this->text;
+      this->text = NULL;
+    }
+  }
+  else
+  {
+    this->externText = NULL;
+    if (this->text)
+      delete[] this->text;
+    if (text != NULL)
+    {
+      this->text = new char[strlen(text)+1];
+      strcpy(this->text, text);
+    }
+    else
+      this->text = NULL;
+  }
+
+  // setting up the Text-Width if DYNAMIC
+//  if (this->type & TEXT_RENDER_DYNAMIC && this->getAlignment() != TEXT_ALIGN_LEFT && this->font != NULL)
+  const Font* calcSizeFont = this->font;
+  if (calcSizeFont != NULL || (calcSizeFont = Font::getDefaultFont()) != NULL)
+  {
+    Glyph** glyphArray = calcSizeFont->getGlyphArray();
+
+    float width = 0;
+    const char* tmpText = this->externText;
+    if (this->externText == NULL)
+      tmpText = this->text;
+    if (tmpText != NULL)
+    {
+      while (*tmpText != '\0')
+      {
+        if(glyphArray[*tmpText] != NULL)
+        {
+          width += glyphArray[*tmpText]->advance;
+        }
+        tmpText++;
+      }
+      this->setSizeX2D(width *this->getSizeY2D());
+    }
+  }
+}
+
+/**
+ *  draws the Text
+ */
+void Text::draw() const
+{
+  glPushMatrix();
+  // transform for alignment.
+  if (this->getAlignment() == TEXT_ALIGN_RIGHT)
+    glTranslatef(-this->getSizeX2D(), 0, 0);
+  else if (this->getAlignment() == TEXT_ALIGN_CENTER || this->getAlignment() == TEXT_ALIGN_SCREEN_CENTER)
+    glTranslatef(-this->getSizeX2D()/2, 0, 0);
+
+  // drawing this Text.
+  // setting the Blending effects
+  glColor4f(this->color.x, this->color.y, this->color.z, this->blending);
+  glEnable(GL_BLEND);
+  glEnable(GL_TEXTURE_2D);
+  glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+
+  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, GL_MODULATE );
+
+  Glyph** glyphArray;
+  if (likely (this->font != NULL))
+  {
+    glyphArray = this->font->getGlyphArray();
+    glBindTexture(GL_TEXTURE_2D, font->getTexture());
+  }
+  else
+  {
+    if (unlikely(Font::getDefaultFont() == NULL))
+      Font::initDefaultFont();
+    glyphArray = Font::getDefaultFont()->getGlyphArray();
+    glBindTexture(GL_TEXTURE_2D, Font::getDefaultFont()->getTexture());
+  }
+  const char* tmpText = this->externText;
+  if (this->externText == NULL)
+    tmpText = this->text;
+  if (likely(tmpText != NULL))
+  {
+    glTranslatef(getAbsCoor2D().x, getAbsCoor2D().y, 0);
+    glRotatef(this->getAbsDir2D(), 0, 0, 1);
+    Glyph* tmpGlyph;
+    float posX = 0.0f;
+
+    glBegin(GL_QUADS);
+    while (likely(*tmpText != '\0'))
+    {
+      if(likely((tmpGlyph = glyphArray[*tmpText]) != NULL))
+      {
+        glTexCoord2f(tmpGlyph->texCoord[1], tmpGlyph->texCoord[2]);
+        glVertex2d(posX+tmpGlyph->width*this->getSizeY2D(), 0);
+
+        glTexCoord2f(tmpGlyph->texCoord[1], tmpGlyph->texCoord[3]);
+        glVertex2d(posX+tmpGlyph->width*this->getSizeY2D(), this->getSizeY2D());
+
+        glTexCoord2f(tmpGlyph->texCoord[0], tmpGlyph->texCoord[3]);
+        glVertex2d(posX, this->getSizeY2D());
+
+        glTexCoord2f(tmpGlyph->texCoord[0], tmpGlyph->texCoord[2]);
+        glVertex2d(posX, 0);
+
+        posX += tmpGlyph->advance * this->getSizeY2D();
+      }
+      ++tmpText;
+    }
+    glEnd();
+  }
+
+  glPopMatrix();
+}
+
+/**
+ *  prints out some nice debug information about this text
+ */
+void Text::debug() const
+{
+  if (this->externText == NULL)
+    PRINT(0)("=== TEXT: %s ===\n", this->text);
+  else
+    PRINT(0)("=== TEXT: %s ===\n", this->externText);
+
+  if (this->getBindNode())
+    PRINT(0)("is bind to %s; ref=%p\n", this->getBindNode()->getName(), this->getBindNode());
+  PRINT(0)("Color: %0.2f %0.2f %0.2f\n", this->color.x, this->color.y, this->color.z);
+}
+
+
+////////////
+/// UTIL ///
+////////////
+/**
+ * Loads a Font from an SDL_surface into a texture.
+ * @param surface The surface to make the texture of
+ * @param texCoord The texture coordinates of the 4 corners of the texture
+ * @returns the ID of the texture
+ */
+GLuint Text::loadTexture(SDL_Surface *surface, TexCoord* texCoord)
+{
+  GLuint texture;
+  int w, h;
+  SDL_Surface *image;
+  SDL_Rect area;
+  Uint32 saved_flags;
+  Uint8  saved_alpha;
+
+  /* Use the surface width and height expanded to powers of 2 */
+  w = powerOfTwo(surface->w);
+  h = powerOfTwo(surface->h);
+  if (texCoord != NULL)
+  {
+    texCoord->minU = 0.0f;
+    texCoord->minV = 0.0f;
+    texCoord->maxU = (GLfloat)surface->w / w;
+    texCoord->maxV = (GLfloat)surface->h / h;
+  }
+  image = SDL_CreateRGBSurface(SDL_SWSURFACE,
+                               w, h,
+                               32,
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
+                               0x000000FF,
+                               0x0000FF00,
+                               0x00FF0000,
+                               0xFF000000
+#else
+                                   0xFF000000,
+                               0x00FF0000,
+                               0x0000FF00,
+                               0x000000FF
+#endif
+                              );
+  if ( image == NULL ) {
+    return 0;
+  }
+
+  /* Save the alpha blending attributes */
+  saved_flags = surface->flags&(SDL_SRCALPHA|SDL_RLEACCELOK);
+  saved_alpha = surface->format->alpha;
+  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
+    SDL_SetAlpha(surface, 0, 0);
+  }
+
+  /* Copy the surface into the GL texture image */
+  area.x = 0;
+  area.y = 0;
+  area.w = surface->w;
+  area.h = surface->h;
+  SDL_BlitSurface(surface, &area, image, &area);
+
+  /* Restore the alpha blending attributes */
+  if ( (saved_flags & SDL_SRCALPHA) == SDL_SRCALPHA ) {
+    SDL_SetAlpha(surface, saved_flags, saved_alpha);
+  }
+
+  /* Create an OpenGL texture for the image */
+  glGenTextures(1, &texture);
+  glBindTexture(GL_TEXTURE_2D, texture);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+  glTexImage2D(GL_TEXTURE_2D,
+               0,
+               GL_RGBA,
+               w, h,
+               0,
+               GL_RGBA,
+               GL_UNSIGNED_BYTE,
+               image->pixels);
+  SDL_FreeSurface(image); /* No longer needed the data */
+
+  return texture;
+}
+
+/**
+ *  Quick utility function for texture creation
+ * @param input an integer
+ * @returns the next bigger 2^n-integer than input
+ */
+int Text::powerOfTwo(int input)
+{
+  int value = 1;
+
+  while ( value < input )
+    value <<= 1;
+  return value;
+}
Index: branches/network/src/lib/graphics/text_engine/text.h
===================================================================
--- branches/network/src/lib/graphics/text_engine/text.h	(revision 6636)
+++ branches/network/src/lib/graphics/text_engine/text.h	(revision 6636)
@@ -0,0 +1,77 @@
+/*!
+ * @file text.h
+ * @brief Definition of a text Class, that is able to render text.
+*/
+
+#ifndef _TEXT_H
+#define _TEXT_H
+
+#include "element_2d.h"
+
+#include "glincl.h"
+
+#define  TEXT_ALIGN_LEFT             E2D_ALIGN_LEFT
+#define  TEXT_ALIGN_RIGHT            E2D_ALIGN_RIGHT
+#define  TEXT_ALIGN_CENTER           E2D_ALIGN_CENTER
+#define  TEXT_ALIGN_SCREEN_CENTER    E2D_ALIGN_SCREEN_CENTER
+#define  TEXT_DEFAULT_COLOR          Vector(1.0, 1.0, 1.0)      //!< the default Color (white)
+#define  TEXT_DEFAULT_BLENDING       1.0f                       //!< the default blending of the text, (no blending at all)
+
+#define  TEXT_DEFAULT_ALIGNMENT      TEXT_ALIGN_LEFT            //!< default alignment
+#define  TEXT_DEFAULT_SIZE           20                         //!< default size of the Text
+
+
+// FORWARD DECLARATION
+class Font;
+struct SDL_Surface;
+
+//! A Struct to handel Texture Coordinates for quads
+struct TexCoord
+{
+  float    minU;              //!< The minimum U-Coordinate
+  float    maxU;              //!< The maximum U-Coordinate
+  float    minV;              //!< The minimum V-Coordinate
+  float    maxV;              //!< The maximum V-Coordinate
+};
+
+//! Represents one textElement.
+class Text : public Element2D
+{
+  public:
+    Text(const char* fontFile = NULL, unsigned int fontSize = TEXT_DEFAULT_SIZE);
+    ~Text();
+    void init();
+
+    void setFont(const char* fontFile, unsigned int renderSize);
+
+    void setText(const char* text, bool isExtern = false);
+
+    /** @returns the String this Text displays */
+    inline const char* getText() const { return (externText == NULL)?this->text:this->externText; };
+    /** @param blending the blending intensity to set (between 0.0 and 1.0) */
+    inline void setBlending(float blending) { this->blending = blending; };
+    /** sets the Color of the Text to render (values in [0-1]) @param r red @param g green @param b blue */
+    void setColor(float r, float g, float b) { this->color = Vector(r, g, b); };
+    /** sets the Size of the Font */
+    void setSize(float size) { this->setSizeY2D(size); };
+    /** @returns the Size of the Text */
+//    void getSize(float &x, float& y) const { return this->size; };
+
+    virtual void draw() const;
+
+    void debug() const;
+
+  // helpers.
+    static GLuint loadTexture(SDL_Surface* surface, TexCoord* texCoord);
+    static int powerOfTwo(int input);
+
+  private:
+    Font*             font;           //!< Font of this text
+
+    char*             text;           //!< The text to display
+    const char*       externText;     //!< the text to Display from an external Source.
+    Vector            color;          //!< The color of the font.
+    float             blending;       //!< The blending intensity.
+};
+
+#endif /* _TEXT_H */
Index: branches/network/src/lib/graphics/text_engine/text_engine.cc
===================================================================
--- branches/network/src/lib/graphics/text_engine/text_engine.cc	(revision 6636)
+++ branches/network/src/lib/graphics/text_engine/text_engine.cc	(revision 6636)
@@ -0,0 +1,171 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+
+   for some fonts and licenses visit: =http://www.dafont.com/en/font.php=
+
+   !! IMPORTANT !! When using ttf fonts clear the license issues prior to
+   adding them to orxonox. This is really important, because we do not
+   want to offend anyone.
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "text_engine.h"
+#include "text.h"
+#include "font.h"
+
+using namespace std;
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "graphics_engine.h"
+#include "resource_manager.h"
+#include "class_list.h"
+
+#include "debug.h"
+
+///////////////////
+/// TEXT-ENGINE ///
+///////////////////
+/**
+ *  standard constructor
+*/
+TextEngine::TextEngine ()
+{
+   this->setClassID(CL_TEXT_ENGINE, "TextEngine");
+   this->setName("TextEngine");
+   this->enableFonts();
+}
+
+/**
+ *  the singleton reference to this class
+*/
+TextEngine* TextEngine::singletonRef = NULL;
+
+/**
+ *  standard deconstructor
+
+*/
+TextEngine::~TextEngine ()
+{
+  // first remove all the remaining Texts (if any).
+  const std::list<BaseObject*>* textList = ClassList::getList(CL_TEXT);
+  if (textList != NULL)
+  {
+    while(textList->size() > 0)
+      delete dynamic_cast<Text*>(textList->front());
+  }
+  // delete all remaining fonts (There should not be Anything to do here)
+  const std::list<BaseObject*>* fontList = ClassList::getList(CL_FONT);
+  if (fontList != NULL)
+  {
+    ///FIXME
+//    while (fontList->size() > 0)
+    {
+      Font* font = dynamic_cast<Font*>(fontList->back());
+      if (likely(font != Font::getDefaultFont()))
+        ResourceManager::getInstance()->unload(font, RP_GAME);
+    }
+  }
+  this->disableFonts();
+
+  TextEngine::singletonRef = NULL;
+}
+
+/**
+ *  function to enable TTF_Fonts
+*/
+void TextEngine::enableFonts()
+{
+  if (!TTF_WasInit())
+    {
+      if(TTF_Init()==-1)
+        PRINTF(1)("TTF_Init: %s\n", TTF_GetError());
+
+      TextEngine::checkVersion();
+    }
+  else
+    PRINTF(4)("Fonts already initialized\n");
+}
+
+/**
+ *  function to disable TTF_fonts
+*/
+void TextEngine::disableFonts()
+{
+  if (TTF_WasInit())
+    {
+      Font::removeDefaultFont();
+      TTF_Quit();
+    }
+  else
+    PRINTF(4)("Fonts were not initialized.\n");
+}
+
+/**
+ *  outputs some nice Debug information
+ *
+ * @todo there should also be something outputted about Font
+ */
+void TextEngine::debug() const
+{
+  const list<BaseObject*>* textList = ClassList::getList(CL_TEXT);
+  if (textList != NULL)
+  {
+    PRINT(0)("+-------------------------------+\n");
+    PRINT(0)("+ TEXT ENGINE DEBUG INFORMATION +\n");
+    PRINT(0)("+-------------------------------+\n");
+    PRINT(0)("Reference: %p; Text Counts: %d\n", this, textList->size());
+
+    list<BaseObject*>::const_iterator text;
+    for ( text = textList->begin(); text != textList->end(); text++)
+      dynamic_cast<Text*>(*text)->debug();
+    PRINT(0)("+---------------------------TE--+\n");
+  }
+}
+
+
+/**
+ *  checks if the compiled version and the local version of SDL_ttf match.
+ * @returns true if match, false otherwise
+*/
+bool TextEngine::checkVersion()
+{
+  SDL_version compile_version;
+  SDL_version link_version;
+  TTF_VERSION(&compile_version);
+  link_version = *TTF_Linked_Version();
+
+  if (compile_version.major == link_version.major &&
+      compile_version.minor == link_version.minor &&
+      compile_version.patch == link_version.patch)
+    {
+      return true;
+    }
+  else
+    {
+      PRINTF(2)("compiled with SDL_ttf version: %d.%d.%d\n",
+                compile_version.major,
+                compile_version.minor,
+                compile_version.patch);
+
+      PRINTF(2)("running with SDL_ttf version: %d.%d.%d\n",
+                link_version.major,
+                link_version.minor,
+                link_version.patch);
+      return false;
+    }
+}
Index: branches/network/src/lib/graphics/text_engine/text_engine.h
===================================================================
--- branches/network/src/lib/graphics/text_engine/text_engine.h	(revision 6636)
+++ branches/network/src/lib/graphics/text_engine/text_engine.h	(revision 6636)
@@ -0,0 +1,43 @@
+/*!
+ * @file text_engine.h
+ *  Definition of textEngine, the Font and the Text
+ *
+ * Text is the text outputed.
+ * Font is a class that loads a certain ttf-file with a specific height into memory
+ * TextEngine is used to manage the all the different Fonts that might be included
+ *
+ *   for more information see the specific classes.
+ *
+ *  !! IMPORTANT !! When using ttf fonts clear the license issues prior to
+ * adding them to orxonox. This is really important, because we do not want
+ * to offend anyone.
+ */
+
+#ifndef _TEXT_ENGINE_H
+#define _TEXT_ENGINE_H
+
+#include "base_object.h"
+
+// FORWARD DECLARATION
+
+//! A singleton Class that operates as a Handler initializing FONTS.
+class TextEngine : public BaseObject
+{
+ public:
+  virtual ~TextEngine();
+  /** @returns a Pointer to the only object of this Class */
+  inline static TextEngine* getInstance() { if (!singletonRef) singletonRef = new TextEngine();  return singletonRef; };
+
+  void debug() const;
+
+ private:
+  TextEngine();
+  static TextEngine* singletonRef;
+
+  // general
+  static void enableFonts();
+  static void disableFonts();
+  static bool checkVersion();
+};
+
+#endif /* _TEXT_ENGINE_H */
Index: branches/network/src/lib/gui/Makefile.am
===================================================================
--- branches/network/src/lib/gui/Makefile.am	(revision 6636)
+++ branches/network/src/lib/gui/Makefile.am	(revision 6636)
@@ -0,0 +1,2 @@
+SUBDIRS = gtk_gui \
+	  gl_gui
Index: branches/network/src/lib/gui/gl_gui/Makefile.am
===================================================================
--- branches/network/src/lib/gui/gl_gui/Makefile.am	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/Makefile.am	(revision 6636)
@@ -0,0 +1,41 @@
+MAINSRCDIR=../../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+AM_LDFLAGS =
+
+noinst_LIBRARIES = libORXglgui.a
+
+libORXglgui_a_CPPFLAGS = -DBUILD_ORXONOX
+
+
+libORXglgui_a_SOURCES = glmenu/glmenu_imagescreen.cc \
+                        glgui_handler.cc \
+                        glgui_mainwidget.cc \
+                        glgui_widget.cc \
+                        glgui_button.cc \
+                        glgui_pushbutton.cc \
+                        glgui_container.cc \
+                        glgui_bar.cc \
+                        glgui_box.cc \
+                        glgui_frame.cc \
+                        glgui_window.cc
+
+
+noinst_HEADERS= glmenu/glmenu_imagescreen.h \
+		glgui.h \
+		glgui_handler.h \
+		glgui_mainwidget.h \
+		glgui_widget.h \
+		glgui_button.h \
+		glgui_pushbutton.h \
+		glgui_container.h \
+		glgui_bar.h \
+		glgui_box.h \
+		glgui_frame.h \
+		glgui_window.h
+
+
+
+
+EXTRA_DIST =
+
Index: branches/network/src/lib/gui/gl_gui/glgui.h
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui.h	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui.h	(revision 6636)
@@ -0,0 +1,16 @@
+/*!
+ * @file glgui.h
+ * includes all the Files the GLGui knows.
+ */
+
+#ifndef _GLGUI_H
+#define _GLGUI_H
+
+#include "glgui_widget.h"
+
+
+
+
+
+
+#endif _GLGUI_H
Index: branches/network/src/lib/gui/gl_gui/glgui_bar.cc
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_bar.cc	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_bar.cc	(revision 6636)
@@ -0,0 +1,76 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_bar.h"
+
+using namespace std;
+
+/**
+ * @brief standard constructor
+*/
+GLGuiBar::GLGuiBar ()
+{
+  this->init();
+
+}
+
+
+/**
+ * @brief standard deconstructor
+ */
+GLGuiBar::~GLGuiBar()
+{
+
+}
+
+/**
+ * @brief initializes the GUI-element
+ */
+void GLGuiBar::init()
+{
+  this->setClassID(CL_GLGUI_BAR, "GLGuiBar");
+
+  this->frontMat.setDiffuse(1,0,0);
+  this->frontMat.setTransparency(.99);
+
+  this->setSize2D(50, 10);
+
+  this->value = 0.5f;
+  this->minimum = 0.0f;
+  this->maximum = 1.0f;
+}
+
+/**
+ * @brief draws the GLGuiBar
+ */
+void GLGuiBar::draw() const
+{
+  this->startDraw();
+
+  GLGuiWidget::draw();
+
+  this->frontMat.select();
+  glBegin(GL_QUADS);
+
+  glVertex2f(3.0, 3.0);
+  glVertex2f(3.0, (this->getSizeY2D()-3.0)* (value/maximum));
+  glVertex2f(this->getSizeX2D()-3.0, (this->getSizeY2D()-3.0) * (value/maximum));
+  glVertex2f(this->getSizeX2D()-3.0, 3.0);
+
+  glEnd();
+  this->endDraw();
+}
Index: branches/network/src/lib/gui/gl_gui/glgui_bar.h
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_bar.h	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_bar.h	(revision 6636)
@@ -0,0 +1,45 @@
+/*!
+ * @file glgui_bar.h
+ * The gl_ widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_BAR_H
+#define _GLGUI_BAR_H
+
+#include "glgui_widget.h"
+
+// FORWARD DECLARATION
+
+//! This is Bar part of the openglGUI class
+/**
+ * The Bar shows the part value.
+ */
+class GLGuiBar : public GLGuiWidget {
+
+ public:
+  GLGuiBar();
+  virtual ~GLGuiBar();
+
+  void setValue(float value) { this->value = value; };
+  void setMinimum(float minimum) { this->minimum = minimum; };
+  void setMaximum(float maximum) { this->maximum = maximum; };
+
+  float getValue() const { return this->value; };
+  float getMinimum() const { return this->minimum; };
+  float getMaximum() const { return this->maximum; };
+
+  virtual void update() { };
+  virtual void draw() const;
+
+ private:
+   void init();
+
+  private:
+    float value;
+
+    float minimum;
+    float maximum;
+};
+
+#endif /* _GLGUI__H */
Index: branches/network/src/lib/gui/gl_gui/glgui_box.cc
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_box.cc	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_box.cc	(revision 6636)
@@ -0,0 +1,116 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_box.h"
+
+#include "list.h"
+
+using namespace std;
+
+/**
+ * standard constructor
+*/
+GLGuiBox::GLGuiBox (GLGuiBoxType type)
+{
+  this->init();
+
+  this->setType (type);
+}
+
+
+/**
+ * standard deconstructor
+*/
+GLGuiBox::~GLGuiBox()
+{
+  delete this->children;
+}
+
+/**
+ * initializes the GUI-element
+ */
+void GLGuiBox::init()
+{
+  this->setClassID(CL_GLGUI_BOX, "GLGuiBox");
+  this->children = new tList<GLGuiWidget>;
+}
+
+void GLGuiBox::pack(GLGuiWidget* widget)
+{
+  if (widget == NULL)
+    return;
+
+  this->children->add(widget);
+}
+
+
+void GLGuiBox::unpack(GLGuiWidget* widget)
+{
+  if (widget == NULL)
+  {
+    delete this->children;
+    this->children = new tList<GLGuiWidget>;
+  }
+  else
+  {
+    this->children->remove(widget);
+  }
+}
+
+void GLGuiBox::showAll()
+{
+  tIterator<GLGuiWidget>* itC = this->children->getIterator();
+  GLGuiWidget* enumC = itC->firstElement();
+  while (enumC != NULL)
+  {
+    if (enumC->isA(CL_GLGUI_CONTAINER))
+      static_cast<GLGuiContainer*>(enumC)->showAll();
+    else
+      enumC->show();
+    enumC = itC->nextElement();
+  }
+  delete itC;
+
+  this->show();
+
+}
+
+void GLGuiBox::hideAll()
+{
+  tIterator<GLGuiWidget>* itC = this->children->getIterator();
+  GLGuiWidget* enumC = itC->firstElement();
+  while (enumC != NULL)
+  {
+    if (enumC->isA(CL_GLGUI_CONTAINER))
+      static_cast<GLGuiContainer*>(enumC)->showAll();
+    else
+      enumC->hide();
+    enumC = itC->nextElement();
+  }
+  delete itC;
+
+  this->hide();
+}
+
+
+/**
+ * draws the GLGuiBox
+ */
+void GLGuiBox::draw() const
+{
+
+}
Index: branches/network/src/lib/gui/gl_gui/glgui_box.h
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_box.h	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_box.h	(revision 6636)
@@ -0,0 +1,47 @@
+/*!
+ * @file glgui_.h
+ * The gl_box widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_BOX_H
+#define _GLGUI_BOX_H
+
+#include "glgui_container.h"
+
+// FORWARD DECLARATION
+template<class T> class tList;
+
+typedef enum
+{
+  GLGuiBox_H,
+  GLGuiBox_V,
+} GLGuiBoxType;
+
+//! This is BOX part of the openglGUI class
+/**
+ *
+ */
+class GLGuiBox : public GLGuiContainer {
+
+ public:
+  GLGuiBox(GLGuiBoxType type = GLGuiBox_H);
+  virtual ~GLGuiBox();
+
+  void init();
+  void setType(GLGuiBoxType type) { this->type = type; };
+
+  virtual void pack(GLGuiWidget* widget);
+  virtual void unpack(GLGuiWidget* widget);
+  virtual void showAll();
+  virtual void hideAll();
+
+  virtual void draw() const;
+
+ private:
+   GLGuiBoxType             type;
+   tList<GLGuiWidget>*      children;
+
+};
+
+#endif /* _GLGUI__H */
Index: branches/network/src/lib/gui/gl_gui/glgui_button.cc
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_button.cc	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_button.cc	(revision 6636)
@@ -0,0 +1,70 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_button.h"
+
+#include "text.h"
+
+using namespace std;
+
+/**
+ * standard constructor
+*/
+GLGuiButton::GLGuiButton ()
+{
+  this->init();
+
+}
+
+
+/**
+ * standard deconstructor
+*/
+GLGuiButton::~GLGuiButton()
+{
+  /* this does not have to be done, since the Label is a child,
+   * and will be deleted by Element2D's deletion Process
+   * delete this->label;
+  */
+}
+
+/**
+ * initializes the GUI-element
+ */
+void GLGuiButton::init()
+{
+  this->setClassID(CL_GLGUI_BUTTON, "GLGuiButton");
+
+  this->label = new Text();
+  this->label->setParent2D(this);
+}
+
+void GLGuiButton::setLabel(const char* label)
+{
+  this->label->setText(label);
+  this->label->setRelCoor2D(5, 5);
+  this->setSize2D(this->label->getSizeX2D()+10, this->label->getSizeY2D()+10);
+}
+
+
+/**
+ * draws the GLGuiButton
+ */
+void GLGuiButton::draw() const
+{
+  GLGuiWidget::draw();
+}
Index: branches/network/src/lib/gui/gl_gui/glgui_button.h
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_button.h	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_button.h	(revision 6636)
@@ -0,0 +1,48 @@
+/*!
+ * @file glgui_button.h
+ * The gl_BUTTON widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_BUTTON_H
+#define _GLGUI_BUTTON_H
+
+#include "glgui_widget.h"
+
+typedef enum
+{
+  GLGui_Button_Active,
+  GLGui_Button_Inactive,
+  GLGui_Button_Pressed,
+  GLGui_Button_Released,
+  GLGui_Button_Activating,
+  GLGui_Button_Deactivating,
+
+} GLGui_ButtonState;
+
+// FORWARD DECLARATION
+class Text;
+
+//! This is part of the openglGUI class
+/**
+ *
+ */
+class GLGuiButton : public GLGuiWidget {
+
+ public:
+   GLGuiButton();
+   virtual ~GLGuiButton();
+
+   void init();
+   void setLabel(const char* label);
+
+   virtual void draw() const;
+
+  protected:
+    Text*                label;
+
+  private:
+    GLGui_ButtonState    state;
+};
+
+#endif /* _GLGUI__H */
Index: branches/network/src/lib/gui/gl_gui/glgui_checkbutton.cc
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_checkbutton.cc	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_checkbutton.cc	(revision 6636)
@@ -0,0 +1,57 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_checkbutton.h"
+
+#include "text.h"
+
+using namespace std;
+
+/**
+ * standard constructor
+*/
+GLGuiCheckButton::GLGuiCheckButton ()
+{
+  this->init();
+
+}
+
+
+/**
+ * standard deconstructor
+*/
+GLGuiCheckButton::~GLGuiCheckButton()
+{
+
+}
+
+/**
+ * initializes the GUI-element
+ */
+GLGuiCheckButton::init()
+{
+  this->setClassID(CL_GLGUI_CHECKBUTTON, "GLGuiCheckButton");
+
+}
+
+/**
+ * draws the GLGuiCheckButton
+ */
+void GLGuiCheckButton::draw() const
+{
+
+}
Index: branches/network/src/lib/gui/gl_gui/glgui_checkbutton.h
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_checkbutton.h	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_checkbutton.h	(revision 6636)
@@ -0,0 +1,37 @@
+/*!
+ * @file glgui_checkbutton.h
+ * The gl_ widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_CHECKBUTTON_H
+#define _GLGUI__H
+
+#include "glgui_button.h"
+
+// FORWARD DECLARATION
+
+//! This is part of the openglGUI class
+/**
+ *
+ */
+class GLGuiCheckButton : public GLGuiButton {
+
+ public:
+  GLGuiCheckButton();
+  virtual ~GLGuiCheckButton();
+
+  void init();
+
+  bool    isActive() { return this->bActive; };
+  void    setActivity(bool bActive);
+
+  virtual void draw() const;
+  virtual void update() {};
+
+ private:
+   bool             bActive;
+
+};
+
+#endif /* _GLGUI_CHECKBUTTON_H */
Index: branches/network/src/lib/gui/gl_gui/glgui_colorselector.cc
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_colorselector.cc	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_colorselector.cc	(revision 6636)
@@ -0,0 +1,55 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_.h"
+
+using namespace std;
+
+/**
+ * standard constructor
+*/
+GLGui::GLGui ()
+{
+  this->init();
+
+}
+
+
+/**
+ * standard deconstructor
+*/
+GLGui::~GLGui()
+{
+
+}
+
+/**
+ * initializes the GUI-element
+ */
+GLGui::init()
+{
+  this->setClassID(CL_GLGUI_, "GLGui");
+
+}
+
+/**
+ * draws the GLGui
+ */
+void GLGui::draw()
+{
+
+}
Index: branches/network/src/lib/gui/gl_gui/glgui_colorselector.h
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_colorselector.h	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_colorselector.h	(revision 6636)
@@ -0,0 +1,32 @@
+/*!
+ * @file glgui_.h
+ * The gl_ widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI__H
+#define _GLGUI__H
+
+#include "base_object.h"
+
+// FORWARD DECLARATION
+
+//! This is part of the openglGUI class
+/**
+ *
+ */
+class GLGui : public GLGui {
+
+ public:
+  GLGui();
+  virtual ~GLGui();
+
+  void init();
+
+  virtual void draw();
+
+ private:
+
+};
+
+#endif /* _GLGUI__H */
Index: branches/network/src/lib/gui/gl_gui/glgui_container.cc
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_container.cc	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_container.cc	(revision 6636)
@@ -0,0 +1,54 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_container.h"
+
+using namespace std;
+
+/**
+ * standard constructor
+*/
+GLGuiContainer::GLGuiContainer ()
+{
+  this->init();
+}
+
+
+/**
+ * standard deconstructor
+*/
+GLGuiContainer::~GLGuiContainer()
+{
+}
+
+/**
+ * initializes the GUI-element
+ */
+void GLGuiContainer::init()
+{
+  this->setClassID(CL_GLGUI_CONTAINER, "GLGuiContainer");
+
+}
+
+
+/**
+ * draws the GLGuiContainer
+ */
+void GLGuiContainer::draw()
+{
+
+}
Index: branches/network/src/lib/gui/gl_gui/glgui_container.h
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_container.h	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_container.h	(revision 6636)
@@ -0,0 +1,43 @@
+/*!
+ * @file glgui_container.h
+ * The gl_container widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_CONTAINER_H
+#define _GLGUI_CONTAINER_H
+
+#include "glgui_widget.h"
+
+// FORWARD DECLARATION
+
+//! This is part of the openglGUI class
+/**
+ *
+ */
+class GLGuiContainer : public GLGuiWidget {
+
+ public:
+  GLGuiContainer();
+  virtual ~GLGuiContainer();
+
+  void init();
+
+
+  void setBorderWidth(float borderwidth);
+
+
+  virtual void pack(GLGuiWidget* widget) = 0;
+  /** unpacks a Widget from this container. @param widget the GLGuiWidget to unpack, if NULL all subwidgets will be unpackt. */
+  virtual void unpack(GLGuiWidget* widget) = 0;
+  virtual void hideAll() = 0;
+  virtual void showAll() = 0;
+
+
+  virtual void draw();
+
+ private:
+
+};
+
+#endif /* _GLGUI__H */
Index: branches/network/src/lib/gui/gl_gui/glgui_cursor.cc
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_cursor.cc	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_cursor.cc	(revision 6636)
@@ -0,0 +1,55 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_.h"
+
+using namespace std;
+
+/**
+ * standard constructor
+*/
+GLGui::GLGui ()
+{
+  this->init();
+
+}
+
+
+/**
+ * standard deconstructor
+*/
+GLGui::~GLGui()
+{
+
+}
+
+/**
+ * initializes the GUI-element
+ */
+GLGui::init()
+{
+  this->setClassID(CL_GLGUI_, "GLGui");
+
+}
+
+/**
+ * draws the GLGui
+ */
+void GLGui::draw()
+{
+
+}
Index: branches/network/src/lib/gui/gl_gui/glgui_cursor.h
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_cursor.h	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_cursor.h	(revision 6636)
@@ -0,0 +1,32 @@
+/*!
+ * @file glgui_.h
+ * The gl_ widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI__H
+#define _GLGUI__H
+
+#include "base_object.h"
+
+// FORWARD DECLARATION
+
+//! This is part of the openglGUI class
+/**
+ *
+ */
+class GLGui : public GLGui {
+
+ public:
+  GLGui();
+  virtual ~GLGui();
+
+  void init();
+
+  virtual void draw();
+
+ private:
+
+};
+
+#endif /* _GLGUI__H */
Index: branches/network/src/lib/gui/gl_gui/glgui_element.cc
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_element.cc	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_element.cc	(revision 6636)
@@ -0,0 +1,55 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_.h"
+
+using namespace std;
+
+/**
+ * standard constructor
+*/
+GLGui::GLGui ()
+{
+  this->init();
+
+}
+
+
+/**
+ * standard deconstructor
+*/
+GLGui::~GLGui()
+{
+
+}
+
+/**
+ * initializes the GUI-element
+ */
+GLGui::init()
+{
+  this->setClassID(CL_GLGUI_, "GLGui");
+
+}
+
+/**
+ * draws the GLGui
+ */
+void GLGui::draw()
+{
+
+}
Index: branches/network/src/lib/gui/gl_gui/glgui_element.h
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_element.h	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_element.h	(revision 6636)
@@ -0,0 +1,32 @@
+/*!
+ * @file glgui_.h
+ * The gl_ widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI__H
+#define _GLGUI__H
+
+#include "base_object.h"
+
+// FORWARD DECLARATION
+
+//! This is part of the openglGUI class
+/**
+ *
+ */
+class GLGui : public GLGui {
+
+ public:
+  GLGui();
+  virtual ~GLGui();
+
+  void init();
+
+  virtual void draw();
+
+ private:
+
+};
+
+#endif /* _GLGUI__H */
Index: branches/network/src/lib/gui/gl_gui/glgui_frame.cc
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_frame.cc	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_frame.cc	(revision 6636)
@@ -0,0 +1,101 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_frame.h"
+
+#include "debug.h"
+
+using namespace std;
+
+/**
+ * standard constructor
+*/
+GLGuiFrame::GLGuiFrame ()
+{
+  this->init();
+
+}
+
+
+/**
+ * standard deconstructor
+*/
+GLGuiFrame::~GLGuiFrame()
+{
+
+}
+
+/**
+ * initializes the GUI-element
+ */
+void GLGuiFrame::init()
+{
+  this->setClassID(CL_GLGUI_FRAME, "GLGuiFrame");
+  this->child = NULL;
+}
+
+void GLGuiFrame::pack(GLGuiWidget* widget)
+{
+  if (widget == NULL)
+    return;
+
+  if (this->child == NULL)
+    this->child = widget;
+  else
+  {
+    PRINTF(2)("Frame %s is already filled, not filling with %s\n", this->getName(), widget->getName());
+  }
+}
+
+void GLGuiFrame::unpack(GLGuiWidget* widget)
+{
+  if (widget == NULL || widget == this->child)
+    this->child = NULL;
+}
+
+void GLGuiFrame::showAll()
+{
+  if (this->child != NULL)
+  {
+    if (this->child->isA(CL_GLGUI_CONTAINER))
+      static_cast<GLGuiContainer*>(this->child)->showAll();
+    else
+      this->child->show();
+  }
+  this->show();
+}
+
+void GLGuiFrame::hideAll()
+{
+  if (this->child != NULL)
+  {
+    if (this->child->isA(CL_GLGUI_CONTAINER))
+      static_cast<GLGuiContainer*>(this->child)->hideAll();
+    else
+      this->child->hide();
+  }
+  this->hide();
+}
+
+
+/**
+ * draws the GLGuiFrame
+ */
+void GLGuiFrame::draw()
+{
+
+}
Index: branches/network/src/lib/gui/gl_gui/glgui_frame.h
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_frame.h	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_frame.h	(revision 6636)
@@ -0,0 +1,38 @@
+/*!
+ * @file glgui_frame.h
+ * The gl_frame widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_FRAME_H
+#define _GLGUI_FRAME_H
+
+#include "glgui_container.h"
+
+// FORWARD DECLARATION
+
+//! This is Frame part of the openglGUI class
+/**
+ *
+ */
+class GLGuiFrame : public GLGuiContainer {
+
+ public:
+  GLGuiFrame();
+  virtual ~GLGuiFrame();
+
+  void init();
+
+  virtual void pack(GLGuiWidget* widget);
+  virtual void unpack(GLGuiWidget* widget);
+  virtual void showAll();
+  virtual void hideAll();
+
+  virtual void draw();
+
+ private:
+   GLGuiWidget*           child;
+
+};
+
+#endif /* _GLGUI__H */
Index: branches/network/src/lib/gui/gl_gui/glgui_handler.cc
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_handler.cc	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_handler.cc	(revision 6636)
@@ -0,0 +1,77 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_handler.h"
+#include "event_handler.h"
+
+#include "glgui_mainwidget.h"
+
+using namespace std;
+
+/**
+ * standard constructor
+ */
+GLGuiHandler::GLGuiHandler ()
+{
+   this->setClassID(CL_GLGUI_HANDLER, "GLGuiHandler");
+   this->setName("GLGuiHandler");
+
+}
+
+/**
+ *  the singleton reference to this class
+ */
+GLGuiHandler* GLGuiHandler::singletonRef = NULL;
+
+/**
+   @brief standard deconstructor
+ */
+GLGuiHandler::~GLGuiHandler ()
+{
+  GLGuiHandler::singletonRef = NULL;
+}
+
+void GLGuiHandler::activate()
+{
+  EventHandler::getInstance()->pushState(ES_MENU);
+
+}
+
+void GLGuiHandler::deactivate()
+{
+  EventHandler::getInstance()->popState();
+
+}
+
+
+void GLGuiHandler::process(const Event &event)
+{
+
+
+
+}
+
+void GLGuiHandler::draw()
+{
+  GLGuiMainWidget::getInstance()->draw2D(E2D_LAYER_TOP);
+}
+
+
+void GLGuiHandler::tick(float dt)
+{
+
+}
Index: branches/network/src/lib/gui/gl_gui/glgui_handler.h
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_handler.h	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_handler.h	(revision 6636)
@@ -0,0 +1,37 @@
+/*!
+ * @file proto_singleton.h
+ * @brief Definition of the GLGuiHandler singleton Class
+*/
+
+#ifndef _GLGUI_HANDLER_H
+#define _GLGUI_HANDLER_H
+
+#include "event_listener.h"
+
+// FORWARD DECLARATION
+
+//! A singleton class for the GLGui-Handler
+class GLGuiHandler : public EventListener {
+
+ public:
+  virtual ~GLGuiHandler(void);
+  /** @returns a Pointer to the only object of this Class */
+  inline static GLGuiHandler* getInstance(void) { if (!GLGuiHandler::singletonRef) GLGuiHandler::singletonRef = new GLGuiHandler();  return GLGuiHandler::singletonRef; };
+
+  void activate();
+  void deactivate();
+
+
+  virtual void process(const Event &event);
+  void draw();
+  void tick(float dt);
+
+ private:
+  GLGuiHandler(void);
+  static GLGuiHandler* singletonRef;
+
+
+  bool                 isActive;
+};
+
+#endif /* _GLGUI_HANDLER_H */
Index: branches/network/src/lib/gui/gl_gui/glgui_image.cc
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_image.cc	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_image.cc	(revision 6636)
@@ -0,0 +1,55 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_image.h"
+
+using namespace std;
+
+/**
+ * standard constructor
+*/
+GLGuiImage::GLGuiImage ()
+{
+  this->init();
+
+}
+
+
+/**
+ * standard deconstructor
+*/
+GLGuiImage::~GLGuiImage()
+{
+
+}
+
+/**
+ * initializes the GUI-element
+ */
+void GLGuiImage::init()
+{
+  this->setClassID(CL_GLGUI_, "GLGuiImage");
+
+}
+
+/**
+ * draws the GLGuiImage
+ */
+void GLGuiImage::draw()
+{
+
+}
Index: branches/network/src/lib/gui/gl_gui/glgui_image.h
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_image.h	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_image.h	(revision 6636)
@@ -0,0 +1,36 @@
+/*!
+ * @file glgui_image.h
+ * The gl_Image widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_IMAGE_H
+#define _GLGUI_IMAGE_H
+
+#include "base_object.h"
+
+// FORWARD DECLARATION
+struct SDL_Surface;
+
+//! This is Image part of the openglGUI class
+/**
+ *
+ */
+class GLGuiImage : public GLGuiWidget {
+
+ public:
+  GLGuiImage();
+  virtual ~GLGuiImage();
+
+  void init();
+  void loadImageFromFile(const char* fileName);
+  void loadImageFromSDLSurface(SDL_Surface* surface);
+  void loadImageFromDisplayList(GLuint displayList);
+
+  virtual void draw();
+
+ private:
+
+};
+
+#endif /* _GLGUI_IMAGE_H */
Index: branches/network/src/lib/gui/gl_gui/glgui_mainwidget.cc
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_mainwidget.cc	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_mainwidget.cc	(revision 6636)
@@ -0,0 +1,43 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_mainwidget.h"
+
+using namespace std;
+
+
+/**
+ * standard constructor
+ */
+GLGuiMainWidget::GLGuiMainWidget()
+{
+  this->setClassID(CL_GLGUI_MAIN_WIDGET, "GLGuiMainWidget");
+  this->setName("GLGuiMainWidget");
+}
+
+/**
+ *  the singleton reference to this class
+ */
+GLGuiMainWidget* GLGuiMainWidget::singletonRef = NULL;
+
+/**
+ * standard deconstructor
+ */
+GLGuiMainWidget::~GLGuiMainWidget ()
+{
+  GLGuiMainWidget::singletonRef = NULL;
+}
Index: branches/network/src/lib/gui/gl_gui/glgui_mainwidget.h
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_mainwidget.h	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_mainwidget.h	(revision 6636)
@@ -0,0 +1,29 @@
+/*!
+ * @file glgui_mainwidget.h
+ * @brief Definition of the glGui singleton Class
+ */
+
+#ifndef _GLGUI_MAINWIDGET_H
+#define _GLGUI_MAINWIDGET_H
+
+#include "glgui_widget.h"
+
+// FORWARD DECLARATION
+
+//! A default singleton class.
+class GLGuiMainWidget : public GLGuiWidget {
+
+ public:
+  virtual ~GLGuiMainWidget(void);
+  /** @returns a Pointer to the only object of this Class */
+  inline static GLGuiMainWidget* getInstance(void) { if (!GLGuiMainWidget::singletonRef) GLGuiMainWidget::singletonRef = new GLGuiMainWidget();  return GLGuiMainWidget::singletonRef; };
+
+  virtual void update() {};
+  virtual void draw() const {};
+
+ private:
+  GLGuiMainWidget(void);
+  static GLGuiMainWidget*       singletonRef;
+};
+
+#endif /* _GLGUI_MAINWIDGET_H */
Index: branches/network/src/lib/gui/gl_gui/glgui_menu.cc
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_menu.cc	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_menu.cc	(revision 6636)
@@ -0,0 +1,55 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_.h"
+
+using namespace std;
+
+/**
+ * standard constructor
+*/
+GLGuiMenu::GLGuiMenu ()
+{
+  this->init();
+
+}
+
+
+/**
+ * standard deconstructor
+*/
+GLGuiMenu::~GLGuiMenu()
+{
+
+}
+
+/**
+ * initializes the GUI-element
+ */
+void GLGuiMenu::init()
+{
+  this->setClassID(CL_GLGUI_MENU, "GLGuiMenu");
+
+}
+
+/**
+ * draws the GLGuiMenu
+ */
+void GLGuiMenu::draw()
+{
+
+}
Index: branches/network/src/lib/gui/gl_gui/glgui_menu.h
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_menu.h	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_menu.h	(revision 6636)
@@ -0,0 +1,39 @@
+/*!
+ * @file glgui_menu.h
+ * The gl_Menu widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_MENU_H
+#define _GLGUI_MENU_H
+
+#include "base_object.h"
+
+// FORWARD DECLARATION
+template<class T>  class tList;
+//! This is Menu part of the openglGUI class
+/**
+ *
+ */
+class GLGuiMenu : public GLGuiMenu {
+
+ public:
+  GLGuiMenu();
+  virtual ~GLGuiMenu();
+
+  void init();
+
+  void addItem(const char* itemName);
+  void removeItem(const char* itemName);
+  void removeItem(unsigned int itemNumber);
+  void selectItem(const char* itemName);
+  void selectItem(unsigned int itemNumber);
+
+  virtual void draw();
+
+ private:
+   tList<char>*           itemList;
+
+};
+
+#endif /* _GLGUI_MENU_H */
Index: branches/network/src/lib/gui/gl_gui/glgui_pushbutton.cc
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_pushbutton.cc	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_pushbutton.cc	(revision 6636)
@@ -0,0 +1,83 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_pushbutton.h"
+
+#include "text.h"
+#include "material.h"
+
+using namespace std;
+
+/**
+ * standard constructor
+*/
+GLGuiPushButton::GLGuiPushButton ()
+{
+  this->init();
+}
+
+
+/**
+ * standard deconstructor
+*/
+GLGuiPushButton::~GLGuiPushButton()
+{
+
+}
+
+/**
+ * initializes the GUI-element
+ */
+void GLGuiPushButton::init()
+{
+  this->setClassID(CL_GLGUI_PUSHBUTTON, "GLGuiPushButton");
+  this->frontMat.setDiffuse(1,0,0);
+//  this->label->setRelCoor2D(10, 10);
+}
+
+/**
+ * draws the GLGuiPushButton
+ */
+void GLGuiPushButton::draw() const
+{
+  this->startDraw();
+
+//  GLGuiButton::draw();
+
+  this->frontMat.select();
+  glBegin(GL_QUADS);
+
+  glVertex2d(0,0);
+  glVertex2d(0, this->getSizeY2D());
+  glVertex2d(this->getSizeX2D(), this->getSizeY2D());
+  glVertex2d(this->getSizeX2D(),0);
+
+  glEnd();
+
+  this->endDraw();
+//   this->label->draw();
+//  printf("test");
+}
+
+/**
+ * updates the GLGuiPushButton
+ */
+void GLGuiPushButton::update()
+{
+
+
+}
Index: branches/network/src/lib/gui/gl_gui/glgui_pushbutton.h
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_pushbutton.h	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_pushbutton.h	(revision 6636)
@@ -0,0 +1,32 @@
+/*!
+ * @file glgui_pushbutton.h
+ * The gl_pushbutton widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_PUSHBUTTON_H
+#define _GLGUI_PUSHBUTTON_H
+
+#include "glgui_button.h"
+
+// FORWARD DECLARATION
+
+//! This is part of the openglGUI class
+/**
+ *
+ */
+class GLGuiPushButton : public GLGuiButton {
+
+ public:
+  GLGuiPushButton();
+  virtual ~GLGuiPushButton();
+
+  void init();
+
+  virtual void draw() const;
+  virtual void update();
+ private:
+
+};
+
+#endif /* _GLGUI_PUSHBUTTON_H */
Index: branches/network/src/lib/gui/gl_gui/glgui_slider.cc
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_slider.cc	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_slider.cc	(revision 6636)
@@ -0,0 +1,55 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_slider.h"
+
+using namespace std;
+
+/**
+ * standard constructor
+*/
+GLGuiSlider::GLGuiSlider ()
+{
+  this->init();
+
+}
+
+
+/**
+ * standard deconstructor
+*/
+GLGuiSlider::~GLGuiSlider()
+{
+
+}
+
+/**
+ * initializes the GUI-element
+ */
+void GLGuiSlider::init()
+{
+  this->setClassID(CL_GLGUI_SLIDER, "GLGuiSlider");
+
+}
+
+/**
+ * draws the GLGuiSlider
+ */
+void GLGuiSlider::draw()
+{
+
+}
Index: branches/network/src/lib/gui/gl_gui/glgui_slider.h
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_slider.h	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_slider.h	(revision 6636)
@@ -0,0 +1,32 @@
+/*!
+ * @file glgui_slider.h
+ * The gl_ widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_SLIDER_H
+#define _GLGUI_SLIDER_H
+
+#include "base_object.h"
+
+// FORWARD DECLARATION
+
+//! This is part of the openglGUI class
+/**
+ *
+ */
+class GLGuiSlider : public GLGuiSlider {
+
+ public:
+  GLGuiSlider();
+  virtual ~GLGuiSlider();
+
+  void init();
+
+  virtual void draw();
+
+ private:
+
+};
+
+#endif /* _GLGUI_SLIDER_H */
Index: branches/network/src/lib/gui/gl_gui/glgui_text.cc
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_text.cc	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_text.cc	(revision 6636)
@@ -0,0 +1,57 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_text.h"
+
+#include "text.h"
+
+using namespace std;
+
+/**
+ * standard constructor
+*/
+GLGuiText::GLGuiText ()
+{
+  this->init();
+
+}
+
+
+/**
+ * standard deconstructor
+*/
+GLGuiText::~GLGuiText()
+{
+
+}
+
+/**
+ * initializes the GUI-element
+ */
+void GLGuiText::init()
+{
+  this->setClassID(CL_GLGUI_, "GLGuiText");
+
+}
+
+/**
+ * draws the GLGuiText
+ */
+void GLGuiText::draw()
+{
+
+}
Index: branches/network/src/lib/gui/gl_gui/glgui_text.h
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_text.h	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_text.h	(revision 6636)
@@ -0,0 +1,33 @@
+/*!
+ * @file glgui_text.h
+ * The gl_TEXT widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_TEXT_H
+#define _GLGUI_TEXT_H
+
+#include "glgui_widget.h"
+
+// FORWARD DECLARATION
+class Text;
+
+//! This is part of the openglGUI class
+/**
+ *
+ */
+class GLGuiText : public GLWidget {
+
+ public:
+  GLGuiText();
+  virtual ~GLGuiText();
+
+  void init();
+
+  virtual void draw();
+
+ private:
+  Text*             text;
+};
+
+#endif /* _GLGUI_TEXT_H */
Index: branches/network/src/lib/gui/gl_gui/glgui_textfield.cc
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_textfield.cc	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_textfield.cc	(revision 6636)
@@ -0,0 +1,55 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_textfield_.h"
+
+using namespace std;
+
+/**
+ * standard constructor
+*/
+GLGuiTextfield::GLGuiTextfield ()
+{
+  this->init();
+
+}
+
+
+/**
+ * standard deconstructor
+*/
+GLGuiTextfield::~GLGuiTextfield()
+{
+
+}
+
+/**
+ * initializes the GUI-element
+ */
+void GLGuiTextfield::init()
+{
+  this->setClassID(CL_GLGUI_, "GLGuiTextfield");
+
+}
+
+/**
+ * draws the GLGuiTextfield
+ */
+void GLGuiTextfield::draw()
+{
+
+}
Index: branches/network/src/lib/gui/gl_gui/glgui_textfield.h
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_textfield.h	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_textfield.h	(revision 6636)
@@ -0,0 +1,35 @@
+/*!
+ * @file glgui_textfield.h
+ * The gl_ widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_TEXTFIELD_H
+#define _GLGUI_TEXTFIELD_H
+
+#include "glgui_widget.h"
+
+// FORWARD DECLARATION
+class Text;
+template<class T> class tList;
+
+//! This is part of the openglGUI class
+/**
+ *
+ */
+class GLGuiTextfield : public GLGuiWidget {
+
+ public:
+  GLGuiTextfield();
+  virtual ~GLGuiTextfield();
+
+  void init();
+
+  virtual void draw();
+
+ private:
+  tList<Text>*      textLines;
+
+};
+
+#endif /* _GLGUI__H */
Index: branches/network/src/lib/gui/gl_gui/glgui_widget.cc
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_widget.cc	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_widget.cc	(revision 6636)
@@ -0,0 +1,126 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_widget.h"
+
+#include "material.h"
+
+#include "debug.h"
+
+using namespace std;
+
+/**
+ * standard constructor
+*/
+GLGuiWidget::GLGuiWidget ( )
+{
+  this->init();
+}
+
+
+/**
+ * standard deconstructor
+ */
+GLGuiWidget::~GLGuiWidget()
+{
+
+}
+
+
+/**
+ * initializes the GUI-element
+ */
+void GLGuiWidget::init()
+{
+  this->setClassID(CL_GLGUI_WIDGET, "GLGuiWidget");
+
+  this->focusable = true;
+  this->clickable = true;
+  this->setVisibility(GLGUI_WIDGET_DEFAULT_VISIBLE);
+//  this->setParent2D((Element2D*)NULL);
+
+  this->backMat.setDiffuse(.1, .5, .5);
+  this->backMat.setTransparency(.9);
+
+  this->frontModel = 0;
+
+  for (unsigned int i = 0; i < GLGuiSignalCount; i++)
+    this->widgetSignals[i] = NULL;
+}
+
+
+bool GLGuiWidget::focusOverWidget(float x, float y)
+{
+  if (this->getAbsCoor2D().x < x && this->getAbsCoor2D().x+ this->getSizeX2D() > x &&
+      this->getAbsCoor2D().y < y && this->getAbsCoor2D().y+ this->getSizeX2D() > y)
+    return true;
+  else
+    return false;
+}
+
+/**
+ * @brief connects a Signal to the Gui-Elements' Event.
+ * @param sinalType the Type of Signal to set. @see GLGuiSignalType
+ * @param signal the name of the Signal
+ */
+void GLGuiWidget::connectSignal(GLGuiSignalType signalType, const Executor& signal)
+{
+  if (signalType >= GLGuiSignalCount)
+    return;
+
+  if (this->widgetSignals[signalType] != NULL)
+    PRINTF(2)("Already connected a Signal to %s (%s) type %s... overwriting\n");
+
+  this->widgetSignals[signalType] = signal.clone();
+}
+
+/**
+ * @brief removes a Signal from a Gui-ELements' Event
+ * @param signalType the type of Signal to remove.
+ */
+void GLGuiWidget::disconnectSignal(GLGuiSignalType signalType)
+{
+  if (signalType > GLGuiSignalCount)
+    return;
+
+  this->widgetSignals[signalType] = NULL;
+}
+
+
+void GLGuiWidget::show()
+{
+  this->setVisibility(true);
+}
+
+void GLGuiWidget::hide()
+{
+  this->setVisibility(false);
+}
+
+
+void GLGuiWidget::draw() const
+{
+  this->backMat.select();
+
+  glBegin(GL_QUADS);
+   glVertex2d(0, 0);
+   glVertex2d(0, this->getSizeY2D());
+   glVertex2d(this->getSizeX2D(), this->getSizeY2D());
+   glVertex2d(this->getSizeX2D(), 0);
+  glEnd();
+}
+
Index: branches/network/src/lib/gui/gl_gui/glgui_widget.h
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_widget.h	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_widget.h	(revision 6636)
@@ -0,0 +1,86 @@
+/*!
+ * @file glgui_widget.h
+ * The gl_widget of the openglGUI
+ */
+
+#ifndef _GLGUI_WIDGET_H
+#define _GLGUI_WIDGET_H
+
+#include "element_2d.h"
+#include "event.h"
+
+#include "material.h"
+
+#include "glincl.h"
+#include "executor/executor.h"
+
+// FORWARD DECLARATION
+class Material;
+
+typedef enum
+{
+  GLGuiSignal_click     = 0,
+  GLGuiSignal_release,
+  GLGuiSignal_rollOn,
+  GLGuiSignal_rollOff,
+  GLGuiSignal_open,
+  GLGuiSignal_close,
+  GLGuiSignal_destroy,
+
+  GLGuiSignalCount,
+} GLGuiSignalType;
+
+//! if the Element should be visible by default.
+#define GLGUI_WIDGET_DEFAULT_VISIBLE       false
+
+//! This is widget part of the openglGUI class
+/**
+ * A widget is the main class of all the elements of th GUI.
+ */
+class GLGuiWidget : public Element2D {
+  public:
+    GLGuiWidget();
+    virtual ~GLGuiWidget();
+
+    void init();
+    /** @returns a new char-array containing a string with the options. Delete with delete[]; */
+    virtual char* save() {};
+    /** loads options of the Widget. @param loadString a string containing the Options */
+    virtual void load(const char* loadString) {};
+
+    void show();
+    void hide();
+
+    void connectSignal(GLGuiSignalType signalType, const Executor& signal);
+    void disconnectSignal(GLGuiSignalType signalType);
+    bool focusOverWidget(float x, float y);
+
+    // if something was clickt on the GUI-widget.
+    virtual void click(const Event& event) {};
+    virtual void release(const Event& event) {};
+
+    virtual void receiveFocus() {};
+    virtual void removeFocus() {};
+
+    virtual void update() {};
+    virtual void draw() const;
+
+  protected:
+    inline void startDraw() const { glPushMatrix(); glTranslatef(this->getAbsCoor2D().x, this->getAbsCoor2D().y, 0); };
+    inline void endDraw() const { glPopMatrix(); };
+
+  protected:
+    Material              backMat;
+    GLuint                backModel;
+
+    Material              frontMat;
+    GLuint                frontModel;
+
+  private:
+    Executor*             widgetSignals[GLGuiSignalCount];
+
+    bool                  focusable;        //!< If this widget can receive focus.
+    bool                  clickable;        //!< if this widget can be clicked upon.
+};
+
+#endif /* _GLGUI_WIDGET_H */
Index: branches/network/src/lib/gui/gl_gui/glgui_window.cc
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_window.cc	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_window.cc	(revision 6636)
@@ -0,0 +1,55 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI
+
+#include "glgui_window.h"
+
+using namespace std;
+
+/**
+ * standard constructor
+*/
+GLGuiWindow::GLGuiWindow ()
+{
+  this->init();
+
+}
+
+
+/**
+ * standard deconstructor
+*/
+GLGuiWindow::~GLGuiWindow()
+{
+
+}
+
+/**
+ * initializes the GUI-element
+ */
+void GLGuiWindow::init()
+{
+  this->setClassID(CL_GLGUI_WINDOW, "GLGuiWindow");
+
+}
+
+/**
+ * draws the GLGuiWindow
+ */
+void GLGuiWindow::draw() const
+{
+
+}
Index: branches/network/src/lib/gui/gl_gui/glgui_window.h
===================================================================
--- branches/network/src/lib/gui/gl_gui/glgui_window.h	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glgui_window.h	(revision 6636)
@@ -0,0 +1,32 @@
+/*!
+ * @file glgui_window.h
+ * The gl_WINDOW widget of th openglGUI
+ *
+ */
+
+#ifndef _GLGUI_WINDOW_H
+#define _GLGUI_WINDOW_H
+
+#include "glgui_container.h"
+
+// FORWARD DECLARATION
+
+//! This is window part of the openglGUI class
+/**
+ *
+ */
+class GLGuiWindow : public GLGuiContainer {
+
+ public:
+  GLGuiWindow();
+  virtual ~GLGuiWindow();
+
+  void init();
+
+  virtual void draw() const;
+
+ private:
+
+};
+
+#endif /* _GLGUI__H */
Index: branches/network/src/lib/gui/gl_gui/glmenu/glmenu_imagescreen.cc
===================================================================
--- branches/network/src/lib/gui/gl_gui/glmenu/glmenu_imagescreen.cc	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glmenu/glmenu_imagescreen.cc	(revision 6636)
@@ -0,0 +1,287 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_LOAD
+
+#include "glmenu_imagescreen.h"
+
+#include "graphics_engine.h"
+#include "material.h"
+#include "factory.h"
+#include "load_param.h"
+
+CREATE_FACTORY(GLMenuImageScreen, CL_GLMENU_IMAGE_SCREEN);
+
+using namespace std;
+/**
+ * @param root The Element to load the GLMenu from
+ */
+GLMenuImageScreen::GLMenuImageScreen(const TiXmlElement* root)
+{
+  this->setClassID(CL_GLMENU_IMAGE_SCREEN, "GLMenuImageScreen");
+  this->setName("GLMenuLoadScreen");
+  // Select Our VU Meter Background Texture
+  this->backMat = new Material("load_screen");
+  this->barMat = new Material("bar");
+  this->barMat->setDiffuse(1,1,1);
+  this->backMat->setDiffuse(1,1,1);
+  this->maxValue = 10;
+  this->currentValue = 0;
+  this->setPosition(0,0);
+  this->setScale(1,1);
+  this->setBarPosScale( .6, .75, .3, .1);
+  // End of Background image code.
+
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  Loads a GLMenu from an inputElement
+ * @param root The Element to load the GLMenu from
+*/
+void GLMenuImageScreen::loadParams(const TiXmlElement* root)
+{
+  LoadParam(root, "BackgroundImage", this, GLMenuImageScreen, setBackgroundImage)
+    .describe("sets the image to load onto the loadscreen");
+
+  LoadParam(root, "BackgroundPS", this, GLMenuImageScreen, setPosScale)
+    .describe("The Position and Scale of the Background Image in %(0-1.0). PosX, PosY, SizeX, SizeY");
+
+  LoadParam(root, "BarImage", this, GLMenuImageScreen, setBarImage)
+    .describe("sets the image of the LoadingBar");
+
+  LoadParam(root, "BarPS", this, GLMenuImageScreen, setBarPosScale)
+    .describe("The Position and Scale of the Loading Bar in %(0-1.0). PosX, PosY, SizeX, SizeY");
+
+  LoadParam(root, "ElementCount", this, GLMenuImageScreen, setMaximum)
+    .describe("The Count of elements to load into the bar (this is only a maximum value)");
+}
+
+/**
+ *  standard deconstructor
+   @todo this deconstructor is not jet implemented - do it
+*/
+GLMenuImageScreen::~GLMenuImageScreen()
+{
+  delete this->backMat;
+  delete this->barMat;
+}
+
+/**
+  *  sets the background image name
+  * @param backImageName name of the backgroun-image
+ */
+void GLMenuImageScreen::setBackgroundImage (const char* backImageName)
+{
+  this->backMat->setDiffuseMap(backImageName);
+}
+
+/**
+ *  sets position of the ImageScreen
+ * @param offsetX offset from the top left corner in percent(0-1) of the screensize
+ * @param offsetY offset from the top left corner in percent(0-1) of the screensize
+*/
+void GLMenuImageScreen::setPosition(float offsetX, float offsetY)
+{
+  this->offsetX = offsetX;
+  this->offsetY = offsetY;
+}
+
+/**
+  \brief sets size of the ImageScreen
+ * @param scaleX the scaleing of the image into the x-direction (in percent (0-1))
+ * @param scaleY the scaleing of the image into the y-direction (in percent (0-1))
+*/
+void GLMenuImageScreen::setScale(float scaleX, float scaleY)
+{
+  this->scaleX = scaleX;
+  this->scaleY = scaleY;
+}
+
+/**
+  \brief sets position and size of the ImageScreen
+* @param offsetX offset from the top left corner in percent(0-1) of the screensize
+* @param offsetY offset from the top left corner in percent(0-1) of the screensize
+* @param scaleX the scaleing of the image into the x-direction (in percent (0-1))
+* @param scaleY the scaleing of the image into the y-direction (in percent (0-1))
+*/
+void GLMenuImageScreen::setPosScale(float offsetX, float offsetY, float scaleX, float scaleY)
+{
+  this->setPosition(offsetX, offsetY);
+  this->setScale(scaleX, scaleY);
+}
+
+/**
+ * @param barImage An image for the Bar
+*/
+void GLMenuImageScreen::setBarImage(const char* barImage)
+{
+  this->barMat->setDiffuseMap(barImage);
+}
+
+/**
+ *  sets the Position and the Size of the bar
+ * @param barX The Position in the x-direction in percent of the screen (0-1)
+ * @param barY The Position in the y-direction in percent of the screen (0-1)
+ * @param barW The Size in the x-direction in percent of the screen (0-1)
+ * @param barH The Size in the y-direction in percent of the screen (0-1)
+*/
+void GLMenuImageScreen::setBarPosScale(float barX, float barY, float barW, float barH)
+{
+  this->barX = barX;
+  this->barY = barY;
+  this->barW = barW;
+  this->barH = barH;
+}
+
+
+/**
+ *  set the maximum of countable steps
+ * @param maxValue of steps
+*/
+void GLMenuImageScreen::setMaximum(int maxValue)
+{
+  this->maxValue = maxValue;
+}
+
+/**
+ *  set current value
+ * @param currentValue value to set
+*/
+void GLMenuImageScreen::setValue(int currentValue)
+{
+  this->currentValue = currentValue;
+  this->draw();
+}
+
+
+/**
+ *  get the current value
+ */
+int GLMenuImageScreen::getValue()
+{
+  return this->currentValue;
+}
+
+
+/**
+  *  call this to trigger a progress event
+
+    this has to redraw the progress bar and the whole image
+ */
+void GLMenuImageScreen::step ()
+{
+  if (this->currentValue < this->maxValue)
+  {
+    this->currentValue++;
+    this->draw();
+  }
+  else
+    PRINTF(2)("ImageScreen-loadbar exceeds maximum value %d\n", this->maxValue);
+}
+
+
+
+/**
+ *  draws the ImageScreen to the screenbuffer
+*/
+void GLMenuImageScreen::draw ()
+{
+  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+
+  PRINTF(4)("GLMenuImagEscreen::draw() - drawing step %i/%i\n",
+            this->currentValue, this->maxValue);
+
+  /* screen size */
+  int screenWidth = GraphicsEngine::getInstance()->getResolutionX();
+  int screenHeight = GraphicsEngine::getInstance()->getResolutionY();
+
+  int imageWidth = (int)(screenWidth * this->scaleX);
+  int imageHeight = (int)(screenHeight * this->scaleY);
+
+  int offsetX = (int)(this->offsetX * screenWidth);
+  int offsetY = (int)(this->offsetY * screenHeight);
+
+  /* loadbar pos */
+  int barX = (int)(this->barX *screenWidth);
+  int barY = (int)(this->barY *screenHeight);
+  int barW = (int)(this->barW *screenWidth);
+  int barH = (int)(this->barH *screenHeight);
+
+  float val = (float)this->currentValue/(float)this->maxValue;
+
+  if( val > barW)
+    val = barW;
+
+  GraphicsEngine::enter2DMode();
+
+  /* draw the BackGround */
+  backMat->select();
+  glBegin(GL_TRIANGLE_STRIP);
+  glTexCoord2i(0, 1); glVertex2i(offsetX, offsetY + imageHeight);
+  glTexCoord2i(1, 1); glVertex2i(offsetX +imageWidth, offsetY + imageHeight);
+  glTexCoord2i(0, 0); glVertex2i(offsetX, offsetY);
+  glTexCoord2i(1, 0); glVertex2i(offsetX + imageWidth, offsetY);
+  glEnd();
+
+  glDisable(GL_TEXTURE_2D);
+  /* draw white border */
+  glBegin(GL_LINE_LOOP);
+  glColor3f(1.0, 1.0, 1.0);
+  glVertex2i(barX - 2, barY - 2);
+  glVertex2i(barX + barW + 2, barY - 2);
+  glVertex2i(barX + barW + 2, barY + barH + 2);
+  glVertex2i(barX - 2, barY + barH + 2);
+  glColor3f(1.0, 1.0, 1.0);
+  glEnd();
+
+  /* draw the progress bar */
+  barMat->select();
+  glBegin(GL_TRIANGLE_STRIP);
+  glTexCoord2f(0,   1); glVertex2i(barX, barY + barH);
+  glTexCoord2f(val, 1); glVertex2i(barX + (int)(val * this->barW * (float)screenWidth), barY + barH);
+  glTexCoord2f(0,   0); glVertex2i(barX, barY);
+  glTexCoord2f(val, 0); glVertex2i(barX + (int)(val * this->barW * (float)screenWidth), barY);
+  glEnd();
+
+  /*
+    glBegin(GL_QUADS);
+    glColor3f(0.0, 0.0, 0.0);
+    glVertex2i(barX, barY);
+    glVertex2i(barX + barWidth, barY);
+    glVertex2i(barX + barWidth, barY + barHeight);
+    glVertex2i(barX, barY + barHeight);
+    glColor3f(1.0, 1.0, 1.0);
+    glEnd();
+
+    /* draw black border
+    glBegin(GL_QUADS);
+    glColor3f(0.0, 0.0, 0.0);
+    glVertex2i(barX-1, barY-1);
+    glVertex2i(barX + barWidth +1, barY-1);
+    glVertex2i(barX + barWidth+1, barY + barHeight+1);
+    glVertex2i(barX - 1, barY + barHeight +1);
+    glColor3f(1.0, 1.0, 1.0);
+    glEnd();
+
+  */
+
+  GraphicsEngine::leave2DMode();
+
+  SDL_GL_SwapBuffers();
+}
Index: branches/network/src/lib/gui/gl_gui/glmenu/glmenu_imagescreen.h
===================================================================
--- branches/network/src/lib/gui/gl_gui/glmenu/glmenu_imagescreen.h	(revision 6636)
+++ branches/network/src/lib/gui/gl_gui/glmenu/glmenu_imagescreen.h	(revision 6636)
@@ -0,0 +1,63 @@
+/*!
+ * @file glmenu_imagescreen.h
+ * class to display a LoadScreen
+ */
+
+#ifndef _GLMENU_IMAGESCREEN_H
+#define _GLMENU_IMAGESCREEN_H
+
+#include "base_object.h"
+
+class Material;
+class TiXmlElement;
+
+//! A class to display a loadScreen
+class GLMenuImageScreen : public BaseObject {
+
+ public:
+  GLMenuImageScreen (const TiXmlElement* root = NULL);
+  virtual void loadParams(const TiXmlElement* root);
+  virtual ~GLMenuImageScreen ();
+
+  void draw();
+
+  void setBackgroundImage(const char* backImageName);
+  void setPosition(float offsetX, float offsetY);
+  void setScale (float scaleX, float scaleY);
+  void setPosScale(float offsetX, float offsetY, float scaleX, float scaleY);
+
+  void setBarImage(const char* barImage);
+  void setBarPosScale(float barX, float barY, float barW, float barH);
+
+  void setMaximum (int maxValue);
+  /** @returns the maximum of countable steps*/
+  inline int GLMenuImageScreen::getMaximum() const { return this->maxValue; };
+
+  void setValue (int currentValue);
+  int  getValue ();
+  void step ();
+
+
+ private:
+  // background image
+  char*         backImageName;       //!< the name of the file of the background image
+  float         offsetX;             //!< X-offset of the the image from the left
+  float         offsetY;             //!< Y-offset of the image from the top
+  float         scaleX;              //!< width of the image
+  float         scaleY;              //!< height of the image
+  Material*     backMat;             //!< Background Material.
+
+  // Load-Bar
+  float         barX;                //!< X-position of the Bar
+  float         barY;                //!< Y-position of the Bar
+  float         barW;                //!< Width of the Bat
+  float         barH;                //!< Height of the Bar.
+  Material*     barMat;              //!< A Material for the Loading-Bar
+
+  /* progress bar values */
+  int           currentValue;        //!< the current count of step() calls fired yet
+  int           maxValue;            //!< total count of steps
+
+};
+
+#endif /* _GLMENU_IMAGESCREEN_H */
Index: branches/network/src/lib/gui/gtk_gui/Makefile.am
===================================================================
--- branches/network/src/lib/gui/gtk_gui/Makefile.am	(revision 6636)
+++ branches/network/src/lib/gui/gtk_gui/Makefile.am	(revision 6636)
@@ -0,0 +1,33 @@
+MAINSRCDIR=../../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXgui.a
+
+libORXgui_a_CPPFLAGS = -DBUILD_ORXONOX \
+			$(GTK2_CFLAGS) $(GTHREAD_CFLAGS) $(CURL_CFLAGS) $(MSBITFIELDS)
+
+libORXgui_a_SOURCES = gui.cc \
+		      gui_gtk.cc \
+	              gui_element.cc \
+	       	      gui_video.cc \
+	              gui_audio.cc \
+	              gui_exec.cc \
+	              gui_flags.cc \
+	              gui_banner.cc \
+	              gui_keys.cc \
+	              gui_update.cc
+
+noinst_HEADERS= gui.h \
+	        gui_gtk.h \
+	        gui_element.h \
+	        gui_video.h \
+	        gui_audio.h \
+	        gui_exec.h \
+	        gui_flags.h \
+	        gui_banner.h \
+	        gui_keys.h \
+	        gui_update.h
+
+EXTRA_DIST = rc \
+	     banner.xpm \
+	     logo.xpm
Index: branches/network/src/lib/gui/gtk_gui/banner.xpm
===================================================================
--- branches/network/src/lib/gui/gtk_gui/banner.xpm	(revision 6636)
+++ branches/network/src/lib/gui/gtk_gui/banner.xpm	(revision 6636)
@@ -0,0 +1,526 @@
+/* XPM */
+static char * banner_xpm[] = {
+"127 382 141 2",
+"  	c None",
+". 	c #183016",
+"+ 	c #183316",
+"@ 	c #183416",
+"# 	c #193816",
+"$ 	c #193916",
+"% 	c #193B16",
+"& 	c #1A3E17",
+"* 	c #1B3F17",
+"= 	c #1B4318",
+"- 	c #1B4418",
+"; 	c #1B4818",
+"> 	c #1C4F18",
+", 	c #1A3D17",
+"' 	c #172D15",
+") 	c #162A15",
+"! 	c #1C4B18",
+"~ 	c #193716",
+"{ 	c #36AC2D",
+"] 	c #42B837",
+"^ 	c #4DC042",
+"/ 	c #53C447",
+"( 	c #60CC53",
+"_ 	c #69D05D",
+": 	c #6ED261",
+"< 	c #74D669",
+"[ 	c #7BD86E",
+"} 	c #80D972",
+"| 	c #54C549",
+"1 	c #58C84D",
+"2 	c #45BC3C",
+"3 	c #1F641B",
+"4 	c #2FA326",
+"5 	c #32A829",
+"6 	c #25921E",
+"7 	c #2B9D23",
+"8 	c #24871D",
+"9 	c #2A9C21",
+"0 	c #31A628",
+"a 	c #183116",
+"b 	c #162314",
+"c 	c #162915",
+"d 	c #216F1B",
+"e 	c #141F14",
+"f 	c #206A1B",
+"g 	c #23791C",
+"h 	c #1D5018",
+"i 	c #1E5719",
+"j 	c #258F1E",
+"k 	c #1E5B1A",
+"l 	c #27991F",
+"m 	c #162514",
+"n 	c #23801D",
+"o 	c #22741B",
+"p 	c #2EA225",
+"q 	c #9CE391",
+"r 	c #89DC7B",
+"s 	c #BDEDB5",
+"t 	c #F8FDF7",
+"u 	c #9DE494",
+"v 	c #183216",
+"w 	c #1D5119",
+"x 	c #182F16",
+"y 	c #172A15",
+"z 	c #1B4217",
+"A 	c #30A527",
+"B 	c #85DB79",
+"C 	c #44BA39",
+"D 	c #1D5419",
+"E 	c #20691B",
+"F 	c #248E1E",
+"G 	c #26971E",
+"H 	c #216E1B",
+"I 	c #20661B",
+"J 	c #162614",
+"K 	c #182E16",
+"L 	c #EEFBEB",
+"M 	c #72D566",
+"N 	c #1A3C17",
+"O 	c #39B030",
+"P 	c #23851D",
+"Q 	c #152114",
+"R 	c #237D1C",
+"S 	c #61CD55",
+"T 	c #B5EBAD",
+"U 	c #D7F5D2",
+"V 	c #183516",
+"W 	c #1C4C18",
+"X 	c #48BD3D",
+"Y 	c #4FC244",
+"Z 	c #8EDF82",
+"` 	c #3DB433",
+" .	c #1E601A",
+"..	c #22771C",
+"+.	c #248A1E",
+"@.	c #1E5A19",
+"#.	c #C3EFBD",
+"$.	c #1F611A",
+"%.	c #E3F8DF",
+"&.	c #94E087",
+"*.	c #2C9F23",
+"=.	c #3FB735",
+"-.	c #21721B",
+";.	c #FCFEFC",
+">.	c #2DA024",
+",.	c #152314",
+"'.	c #ADE8A5",
+").	c #F3FCF2",
+"!.	c #D9F5D4",
+"~.	c #289A20",
+"{.	c #162414",
+"].	c #1B4518",
+"^.	c #DEF6D9",
+"/.	c #FEFFFE",
+"(.	c #172C15",
+"_.	c #162814",
+":.	c #26961E",
+"<.	c #FFFFFF",
+"[.	c #162714",
+"}.	c #D0F3CB",
+"|.	c #152214",
+"1.	c #38AF2F",
+"2.	c #6AD15E",
+"3.	c #1E5519",
+"4.	c #33A92A",
+"5.	c #1E5E1A",
+"6.	c #35AB2C",
+"7.	c #152014",
+"8.	c #37AD2E",
+"9.	c #3EB534",
+"0.	c #23821D",
+"a.	c #F6FDF5",
+"b.	c #A6E69C",
+"c.	c #BAECB3",
+"d.	c #FCFEFB",
+"e.	c #91DF85",
+"f.	c #F1FCEF",
+"g.	c #3CB332",
+"h.	c #43B938",
+"i.	c #172B15",
+"j.	c #C0EFBA",
+". . . . . + + + @ @ @ # # $ $ $ % % & * * * * * = = = - ; ; > > > > > , = = + . ' ' ' ' . . . ' ' ' . ' ' ' ) . ! > > ! , @ . . ~ ! { ] ] ^ / ( _ : < [ } [ < < _ | 1 ( 2 > 3 4 5 6 7 3 8 9 . > 0 a b } [ c d e f g ! h i j f k j l l m ) 9 n o p q : r s t u ",
+". . . + v . + + @ @ @ @ $ # % % % % % & & = & & = = - = ; > ; ; ! w ! & & * . v ' ' ) ' . . ' ' v x v x ' # v ) . . ' ) y z o p A p 1 / ^ ^ ^ ( : : [ } B [ < : ( | ( ( C D E F G H 6 6 F * I o J @ K L M $ N e z O d h h d 8 j d P n Q m p G R C S r _ u T U ",
+"K . . . . . . . @ @ @ @ V # # # % % & * & * N * = = = - - ; > > > > ! & = = . . ' ' ' ' ' . x ' + ' ' x ' ' . ' J @ W o 7 { C X Y X 1 S ( | ^ ( : [ B Z B [ : _ ( ( : _ `  .o ..H G 6 +.3 @.a i j c e #.[ Q z Q R ! ! f $.j f j p { j ) @ { p G Y [ B [ u %.&.",
+". . . . @ @ @ + @ @ V V $ $ $ $ % % % & * * & * = = - = ; > ; > ! > ; , = = v v ' ' ) ' . . ' ' ' ) ' + ' J ' - *.A O ] =.=.` O 2 ] A 2 _ : ( : [ [ } B B < : ( ( S < : 2 @.H R *.-.6 P F D l k @ $ K ;.O a @ e > X i i f $.j { >.n k ,.' d I o / '.[ } ).!.t ",
+"' ' . . . + + + @ + # @ V $ $ # % % & & & * % * = = = = ; > ; > > w - $ & * . . ' ' y ' ' . ' ' ' ' ' @ . ) > A =.=.` ` ` ` =.X 1 / l { ( _ ( : < [ } } } < : _ : ( S < ^ ; @.6 G 7 6 ~. .. ,.i j J {.T M e N e n R i $.].N y ) b Q Q e ) @ e Q h S k s ^./.T ",
+". . . . . . + + + @ @ V # # $ $ % % % * * = * & = = - - - - > ; > > > , = = v . ' ' ' ' . . x ' v x (.. _.. n ^ ` ` ` { O ` X / ^ | j { ( ( ( ( } } [ } [ < : : [ S _ : X ; D :.P 7 P F H ' j g @ @ @ <.=.b c Q k f Q e e c c e e e e e J y e Q 7 8 N 1 t r %.",
+". . . . . . . @ + + # # V # $ # % % % & & & N N = = = = ; ; > ; > > > , & * v . ' ) ' ' ' . ' ' ' ' . v [.$ 7 2 ` ` =.` =.Y / | Y S P p ( S : [ } [ [ < < < < < _ : _ | ` ; D +.7 -.+.P H * y k j Q e }.C e z b j c e e e a J e e e Q |.@ a e e ! C K T %.}.M ",
+". . . + @ @ + + @ @ @ V $ $ $ $ % % & * * = & & = = = - ; ; ; > > ! > * & = @ . ' ' ' x v . . ' x ' ' ) ) + { =.=.` ` =.2 Y | / / 1 l A _ _ : < B Z [ < [ } [ B < : 1 1 1.;  .F 6 +.o P H J 0 $.$ @ z L S b e e d k Q e b K c e e b e e c y e e { R $ M ).2.%.",
+"' . . . . + . a @ @ @ @ # # $ # % % & & * * * N = = = = ; > ; > > ; ; & N * a . x ' ' ' . v v x . ' . ' ' @ { ] =.=.2 Y Y Y / / Y 1 l 0 1 1 _ _ : } Z } < : : B : _ / 1 1.- @.F ..6 6 P :.j J h l e e ^.0 b e K { J e e e K Q e Q e e e v c e e i C y !.%.T | ",
+". . . . . . @ @ @ V V V # $ $ $ % % % * & = & & = = = ; - ; > ; > ; > = & = V ' ' ' ' . . . x x x x ' x x $ { O ` 2 2 Y / / / Y 1 1 7 A _ ( _ _ : B Z Z B < _ : : S | 1 1.; D 8 6 $.n F n y R N z y h }.{ e e Q 8 ! Q e e e e e e e e e e c e Q 0 f N M t Z !.",
+"K K . . . @ + + + @ # V # # $ # # % % * & * * N = = = ; - ; > > > ; ; & N * @ . ' ' ' . . . . x ' . ' ' ' + { =.=.Y ^ / | Y / Y | / *.A _ : < : : [ [ [ Z Z < : _ / / _ ` = D P n H 7 +.*. .v 8 8 e b ;.j Q e @ 0 c e e e Q e a ].N ].e z $.i N h R ; s #.!.1 ",
+". . . + + . + + @ @ @ # V $ % $ % % & & * * & & = = = = ; ; ; ; w ; > = & * @ ' ' ' ' ' . . x x (.' . ' ) + { 2 Y Y / / Y / / 1 1 1 *.7 ] 2 ( : } B < < Z Z : / S | | _ ` ; 3.+.G +.+.A j @.>.K $.b 0 '.b e e J j $ e a z $.l 1 S _ j J y O 0 O 2.C O 2.M 1 [ ",
+". . . . . . . + @ @ @ # # # % % $ % % & & * * & = = = = ; > ; ; w ; ; & * = @ . ' ' ' . v . . x ' x . ' ) + ` ^ / / / ^ Y / | 1 / | :.I 3 H F 4.| : [ } q Z : / S 1 1 _ 1.- 5.+.6 6 *.6.P = ' 0 k Q e %.k Q e e ! 0 ! d >.R j l j 0 0 e v 8 >.0 { X 1 }.).L 1 ",
+". . . . v @ + + @ V V # V $ % $ % % & * * * & * = = ; ; ; ; > > > ; > * & * @ . ' ' ' ' . v x x x ' x ' . , =.| ^ Y Y / / / 1 | _ _ { o 3 i o F +.6.C ^ : [ } [ S | S | 9 = 3 6 >.6 ~.A 5 * Y y n b { %.b e e e 0 d f f i o $.$.g 0 j 7.; Y >.>.| R 0 u %.t ).",
+"K K . . . + . a @ @ @ # V # # # # * % & & * % & = = = ; ; ; ; ; > ; > & & = . . ' ' ' ' . v . x + . x x ~ ; Y | / ^ X Y / 1 | | ^ ^ 4.P R o o R :.*.9 F >.1.C | S S | / F % H ~.>.0 8.6.F * $ 0 f e J U $ e Q b ! 8 d i i j j R f { { Q f 2.O 0 X | 1 !.M %.T ",
+". . . . . . @ + @ @ V V # $ % % N % % * * * * * = = = = ; ; > > > ; ; & % * @ . ) ' . . . ' x ' x ' ) ~ W = 2 1 ^ Y ^ / 1 | | / 1 : p 3 3 F +.n 9 *.~.A A G 8 P :.:.j H > - H A 0 8.0 4.3 V P K f b 0 S c a ].Q { d i o o $.o o o 0 d e f Z >.O j O Z !.#.L s ",
+". . . . . @ @ + @ @ @ # # $ $ $ % & % & & & * * = = = = ; ; ; > > ; ; & % & . . x (.) ' x x x . ) + , = ; = 2 ^ ^ / / ^ Y / | 1 1 _ A o  .E o P 9 ~.:.9 A G F 8 o 3 @.> ; > -.>.8.6 8.^ :.v > n d e c ;.a N c c $.k ; h o j j l 0 { o 7.N C >.O | | M s u #.Z ",
+". . . + + . + + V @ V V # # # % # % & % % * & * = = ; ; ; ; > ; w > ; & % * @ . ' ) ) ' + ' x x (.$ = - , ; 2 ^ ^ / | 1 ^ ^ S : _ | j R 3 w D 3 3 3 o G 9 A G :.8 o  .3.> 3.P 0 8.8.>.*.H & j ' n Q *.| k {.h e 0 $.i o o R l 0 j O d 7.h Y j >.| [ [ [ !.t &.",
+"K . . . . . . . @ @ @ V # % # & # & % & & * & * = = = - ; ; > ; > ; ; & % * . . ' ' ' . + ' (.x & , , @ $ W ^ 2 | 1 1 _ 1 1 1 _ S 2 7 =.1 1.9 8 o 3 3 H 3 o P 8 o o o H w > n 6.8.>.4.4.*.% > 0 $.e z ;.c k y {.R *.$.; f j *.X Y p f J f 1 >.>.C [ Z [ T ).%.",
+". . . . + @ @ @ V @ V # $ V % V * % & * & & * * = = = = ; ; ; > > > ; , & & @ . ) ) ' v x (.v @ ; , , , = W 2 | ^ | ( _ < _ ( Y | p j ^ [ < < : ^ 1.G E = = @.E  .E R H D > o >.8.*.9.6.A P I J l e d }.O Q z J =.R f n $.k j O { C o 7.>.Z j 0 1 T 1 T Z %.&.",
+"' ' . . . + + . @ @ @ @ % # % V # & % * * * * * = = ; ; ; ; ; > > ; ; & % * . . ) ' ) ' ' . , ; , $ , , - - ` _ ( 1 | 1 1 ^ { p P n O _ } : : : q q < C G o @.@.@.3.3. . .3 P >.>.8.*.6.*._.k O z e $ <.Q h c e f o i h o o j X _ 7 > 7.W { { 0 Y Z #.T U T }.",
+". . . . . . + + V @ # # # % V % * % % & % & * * = = = = ; > > ; > > ; % & & @ . ' ' ' ) ' ~ = = v @ $ $ , @ 9 ] | 2 ` { 4.9 n  .n P _ [ : : : B [ B Z } : / =.4.F o  .@.@.@.R A 4.*.O 4 4 G I K 0 e X %.j e {.v | $.; d o o ` r O z 7.7.y K R >.1 u T %.Y U r ",
+". . . . . . @ a @ @ V V # % # # # & & & & & & * = = = - ; ; > > > ; > % % * @ x ' x ' (.@ * , v @ @ @ @ - x D i :.0.o H o ..n o ; k _ : _ < < } B B : | _ : : [ < ( ` 8 D = 5.:.*.4.*.9.:.' I 0 $ e k t y @ y J v e y R *.k $ z $ Q e Q 7.a '.[ l C Z j ; ).<.",
+"' ' . . . . . v # @ @ @ # @ & # * # # * * * * & = = * 3., ! ! > > 3.; $ & = x (.K b _., - , $ + $ x @ = @ , - $ D D D ..3 5.H o I  ./ _ < < < [ } } : _ S [ B } < [ Z 1 @.# D P 6 *.0 *.- = g @ >.e Y t f e a a 1 b e n j v e Q |.e @ T N N }.a.} X O b e }.0 ",
+". ' . . . @ . x @ @ # @ # # # # * N & # & & & & * > & , > 3.* ; = > > * & = v ' _.v , = , @ v . v & @ $ W * @ = $ = i o D D k o 3 3 | ( : < } [ Z } : : : [ } [ [ [ } S n % W P ~.*.G 0 :.) f 7 N e l ).z ; b b j z y ! o @ e e e c { ;.}.e t t 1 2.j 7.f ).h ",
+"' x . x x . @ @ V # @ # # # # # & # & * & & = = * , ; ; * & * > 3.> ; # # $ x ' J , - , $ v + + v @ $ , = = , = , 5.0. .= k 5.$.i d _ _ ( < } B Z < S [ B } [ } Z : : _ p - W ..6 -.*.0 * + % $ 0 e e a k l ! Q z {.e $.j a e e Q e e ;.Z N 2.L 2.M { 7.b !.*.",
+"' ' . . x . . . @ # # # @ # # V N # * N * & & & ; & > & = 3.3.; > ; = & * , v ' - - @ a @ a v + # @ - - $ $ $ $ 5.R 0.i ; 3 5.- D d : : ( _ < B Z B [ } Z B [ } } : _ _ ` ! = -.$.+.7 ~.*.[.j l $ J e K j *.J e e e c j n Q e Q e Q b ; >.b >.0 C } >.b i ;.).",
+". x x . . x @ @ @ @ @ @ # # N # # & & & & * * = * , * > 3.& $ > > 3.> = & + a $ - , a * , ' . v v $ = @ $ $ $ D R H ; , - - D W i  ._ < : : < B B Z q Z Z Z Z } : : : _ =.W ; 3 G -.n O 4.@.N z { j b $ $.O z b e Q e k >.N e e b $ }./.T /.s S r Z { J Q r %.",
+"' ' . . . . . @ @ @ # # # # # # * V * & % & * = * > = ; @ ; @.& > > - D 3 D ; - a y y , ' v I n 3 ~ $ # v = 5.o W @ ; 7 0 D $ ; > > ^ ( < < < < B q b.Z Z B Z } _ : : : =.- W H ..-.6 +.8 _.{ N K 8 z y C l |.e e e Q ! k J e Q e $ Y Z M Z &.r 2.| f J Q e e ",
+". x x . . . @ . @ # @ # V # # & # & % & & * * * * _ [ } [ c.[ @.:.S c.c.| 3 , = a y ' a @ 5 L d.e.- x = @ w o D = ; _ f.a.^ * ; $ # O / _ [ } } Z e.q q Z B [ [ : _ < _ =.- > o ..6 P 5 g.j T s Q e y $ j >.N Q J y K J b b J z ; f 1 u 0 } C N ; h ; @ @ b b ",
+"' ' . . . @ . @ @ # @ # # # # # # & & % & * * * * S > * 3.* E }.S ~.* , i D , ' ' a @ ' (.^ /.d.d.o J @ W -.3 = W i '.d.a.| x % ) @ 1.2 | _ B B q Z Z q q } : : [ ( : : 2 = D o +.+.~.A  .y )./.; e e a | S c e e e Q e Q e $ %.T $ >.%.!.Z !.R f c j T S N c ",
+"x . @ . . ' @ @ @ @ @ # @ # # # * V & % % & N N * G > = = * D S 3.; = D R @ $ ' ' ' ' a ' : d.t t H [.W o W $ ; W , b.a.d.M |.b J . =.X | [ [ } B e.e.Z } < : : : : _ _ ] - > P F ~.:.A 8 # { T z e e e b N J e e e e e e e i %.!.; K >.R J { >.; c v u <.<.O ",
+"' ' x ' . . @ @ @ @ @ @ # # # @ # & & % & * & * > S / / S : / _ S : S : ^ W ' y ' y ' $ @ : a.d.d.I ' w D w w ; - , T d.a.: Q b b . ` X / < } B B Z B } < < : : : _ ( S h.; D F *.A 5 6.3.7.Q Q e b Q e e Q @ O b Q e e $ v z L t v ; #.).&.Y >.R e e @ i ! l ",
+"' ' ' . . @ . @ @ @ # @ @ # # # % # & % % & * * % 3.= = > ; - > = n H = V @ a a y a @ & + _ d.d.t o ' @ $ W i W , , c.d.t 1 e ,.b . ` X / M [ e.Z } [ < : : : : ( ( ( _ 2 ; 3.:.7 :.~.*.> # @ Q J $ $ e y e $.r d y l k K $ h T '.i i B L @.j 8 c R C e P {.h ",
+"@ . ' . @ @ @ . @ @ @ # # # # V * # & & % & * N * & = = ; ; > ; H 3 * $ x $ y a y , - $ ) _ d.d.t j ) ) v * - 3., $ c.;.t 1 e b b a ] X Y _ [ Z B [ : : : : : : ( _ ( _ ^ W 5.~.4.A 6.O n 6.1.A @ $ c e Q e $ { Q e l l >.i $ s ^.- = 1.%.b.E z $ 0 _ i 7.e i ",
+"# @ @ ' ' . @ @ @ @ @ # @ # # # # & # & % & & & = $ ; = & = > 3.o w V $ V $ ' ' ~ = , a b _ d.d.d.n J . $ $ $ W ; % '.;.;.2.e b J . =.X ^ 1 _ } [ < : _ : : _ _ 1 ( : _ ^ > 3 A 0 >.4.8.8 >.A g.0 e e c | z y N c e y h o d [ s '.4 @.8.^.A _ ! 0 Z 2 D - e 0 ",
+"% @ @ . @ ' @ @ @ @ @ @ # # # # # & # & % & & & & > & > * = o n > = ~ K * a a ' ! $ (.x ) _ a.;.d.d ) = = , , & D % u d.;.2.e Q J . ] X X / S < : : < : : : _ _ 1 S : : / w 3 4 6.8.4.0 F G 9 =.% e e c M }.M =.e e *.f k l 1 s c.5 F S a.b.o @.j t >.A 1 - n ",
+". @ @ . @ . @ @ @ @ @ @ # @ # # & # * N & & & & ; ^ 3., = -.S ~.* @ , W =.$ a = , ' _.a x : d.;./.H ) , & = = $ D , '.t ;.2.e b J . =.Y / 1 S [ < [ [ < < : _ : _ : < < | D H >.>.*.0 >.*.+.8.4.> e b e i ! C Z z b z f R h | < c.q 8.} /.1.; J | ^.^ { G J C ",
+") ' . @ . . . @ @ @ @ @ # # # # # # # * # & & , & S v 3.k H : 6 $ $ V ' ^ = * - _.y y v ' [ d.;.;.n {.' % ; & & > $ '.;.t 2.e b J . ` / 1 ( _ [ < [ } < : : _ : S : < < | D H A >.>.8.*.~.+.9.A g.. Q e e J j 8 b e M l ; d 1 }.c.g.>.C '.S H N P !.=.@.N g l ",
+"(.(.x x @ @ @ . @ @ @ @ @ @ # # V * * & N N & % - q A O C 9 < S :.A F :.b.o x a ' y a , = [ ;.;.d.$._.v $ $ - W , @ '.t ;.2.e ,.,.+ C / 1 ( < [ B [ < < < < } < [ : } B / w H A 0 >.>.>.~.6 >.8.5 O 5.V |.e i P y c l C $.$.C q %.^ -.* ,.C ^ & _ S X E ! *.| ",
+"i.i.K K v v @ x # @ # @ @ @ @ # $ N N % & * = , ! ^ } } S ^ [ 2 S ^ | | S - (.a y ' $ = # S t /./.f b # + @ D $ - + q ;./._ Q |.) $ 2 | / ( < [ B B [ [ < < } } [ M } B 1 w H A A *.4.>.~.~.>.8.8.9.0 6.3 Q ) i b Q [ 0 z l 1 T }.} +.~ Q P g.E >.q { 8 A M f ",
+"i.(.x x x x v @ v V @ # # # # # % % & & N $ , , , n n ! V ~ V % + V 3.k > i.a ' K V * , a : /.;.;.f ,.~ - @ $ ; % x '.<.d.: |.|.{.+ X 1 / : [ [ Z B B } } } [ } [ : [ B | D H A A >.>.0 6 6 0 0 8.9.9.9.{ R z ! e Q { r k k | Z ^.} ^ -.Q H 3 N A } [ o h | $.",
+"i.i.(.(.x x v v @ @ V V # % $ # $ $ * & & # $ , H -.; v $ V V $ V ! w $ a @ K y $ , , ~ @ B <.;./.$.b Q ) = % $ $ b q /.d.2.e m J . =.( Y : : < B B B B B B } r [ [ } } 1 w H A A >.>.4.~.6 0 8.9.8.6.>.~. .J N a |.1 | d d [ s s c.5 -.$.5 n @ P } S b 8 | N ",
+"x ' i.(.(.x v v v V @ @ V V # $ # % % , V , ; 3.-., @ ~ $ , ! , ! > - ~ ~ K i., * v ~ * $ : ;.;.;.k 7.' ,.' = % ) Q './.;.: e J c ~ C S Y ( [ B Z Z e.q e.Z Z } } [ } Z ^ D 3 A A *.4.>.6 6 *.8.8.6.9.4.A P ) ].b e j | i R 1 }.L ^ *.! i.| A N 6._ _  .j S y ",
+"i.(.i.i.(.(.x x x v @ @ # # # % % , $ $ , ! 5.3 K = V V @ V v > ..w , v @ @ $ @ K $ > * (._ /.;.t O e ,.' 7._.y e ! %./.;.} Q m J $ 0 : S 1 : B q Z q e.q Z Z Z } < } Z | 3.H A A >.>.4.~.6 0 8.8.8.9.4 ~.G ' ].y b 2 n ! 8 2.s }.< 5.J Q :.A > 7 B } N | O J ",
+"(.(.(.(.i.' (.' v x v V v V V V $ % $ ~ ! $.$.! @ =.> v $ , * P - , V a = V = x J V ! V ,.( <.;./.L $.e |.m e |.$.} <./.;.1 b b _.. d X _ _ < } Z q q b.q e.Z B } } B Z | w H A >.*.4.>.~.6 >.0 9.>.6.6.~.o ) $.b c d C f 8 [ }.^._ { ! ,.:.n * G }.=.' >.=.e ",
+"y y (.' (.' x (.' ' . v V V # $ # $ $ , k -.> i., j.=.| S ^ Z ^ ^ | | | ^ , . x v _.x $ ) Y ;./././.L C y e b j t <.;.;.<.0 e J ' {.x G ( : B Z q q q b.b.q Z Z } [ [ Z | 3.3 A A >.>.>.~.6 0 8.0 8.9.5 4 g.$ $ N Q 0 n ].j 1 T }.u ^ n = j @.' A Z 1 7.C ; b ",
+"(.(.(.' ' ' (.' ' x V V ' V , V , K ; n k ~ @ v v ^ $ v @ * H $ * @ $ , v @ $ (.' v _.V @ $ T /./.;./.<.}.=.r ;.;./.;.;.t N e _.) ' ) + D F C : } q b.b.q q q } Z : [ q ^ 3.$.A A *.4.4.6 6 >.6.0 9.0 4.A E {.I J b n { k j O u ^.#.1.K , C G = ` Z ` > 8 h e ",
+"' K y (.' ' x ' ' (.x . v V V V x = $.3 ! v v ~ $ :.# $ * - k * a * , @ $ i ; v ) ' J ' & b @ T ;.<.;.;.<.;./.<./.t <.).8 e _.b ) ' (.' @ = 5.+.^ : } q q q q Z } : Z Z C 5.-.4.>.*.>.4.6 6 0 6.6.9.9.>.7 g.h ].].Q $.8 i O O u ).'.n 7.Q 9 > = | c.Y = 1 K e ",
+"(.(.' ' ' x (.' ' a K v v v v v , $.k , K @ @ x v & x V V @ > 3.* = @ $ w $., $ V v K V b # _.b ; &.;.;.<.<./.;.;.%.R b e y Q ) ) (.' + $ = 3.R +.>.8.C ^ ^ S : } Z q [ A 3 n A 4.~.4.A 6 6 >.0 6.0 0 6.~.3.{.k y b 8 { R j C #.L #.g.v & n o > A f.o { h b e ",
+"(.' (.(.(.' x x i.x i.' @ ' v * w > ~ i.i.$ $ x & (.$ V x V , w 3.~ ~ k H w y a V = K a a a (.) l ^.<.<./.;.<.<.<.;.O v e b _.' ' (.(.v $ - 3.n n *.>.*.~.~.6 +.4.8.^ 4.n 3.n >.4.~.4.A 6 6 A 0 6.6.h.4.+.{ I ].; e h C f M f &.).s A (.K 1 > # ^ j.1.* R e e ",
+"(.(.(.' ' x ' ' ) K ' K ' v ~ 3., v v @ @ V # v v v $ V V = V V $.> 5.3.- v v ) _.a ! ~ a |.D u <./.t /.<.<././.;.t /.%.d e . ) . _._.v $ = 3.H ~.*.4.4.>.*.+.n  . .o -.w k n 4.4.*.>.4.+.6 A 4.4.C 0 *.>.$.7.! $ Q k R j R >.s #.!.^ x ; 6.G > =.L ; ` ! e Q ",
+"(.(.(.(.(.(.(.K y a @ a K ' $ ! * K i.@ v x @ # (.8 8 F F *.:.:.~.0 h.G -._.@ ' ' Q , - @ $ '.<./.<.<.<.U M T /.<./././.!.W Q ' + J J . % = 3. .n :.~.*.>.~.~.+.-. .H o $.H n >.>.*.>.A +.6 A 4.O 4.*.0 4 6 @ h N Q N | ; 2.v T ).!.{ Q {.^ @.E S =.] 0.b Q e ",
+"' ' (.' ' ' K ' a @ @ K i.v ~ , > * @ x v @ x . ; } *.*.F 8 P G 4 g.=.{ _ $ . ' N ) 7., D { d.<./.<.L [ z e @ X ;.<.<./.<.0 7.) ' ) # D 3.3.3.5. .H n n F ~.F o -. .H R $.H n *.4.~.>.A 6 6 7 4.~.^ 9.>.*. .Q $.k Q h 8 8 l $.#.%.!.=.b V E * D S j.> D {.e v ",
+"' (.' (.' x x ' (.y ' i.i.V , @ ~ ! , x v # v @ x S V $ , $ = ; 3 -.~ ' | $ + @ + x x b b e.<./.<.'.W |.|.) Q {.i 2.;.<.<._ Q _.J @ P 1 : ( ^ ^ g.4 F -.H o n H 3 3.H -.$.H n *.>.~.4.>.6 6 A A 4.6.A >.>.R ' i N Q ; 1 8 | K Z ).!.O ' > =.; o b.[ G I Q e e ",
+"x (.) x ' i.) (.(.x K ' ~ ! , K K @ 3.- v v ' $ $ c.S | ^ 9 4.] 9.:.6 ^ j.= $ & y ) v # Q : <.<.<.d Q ' . . @ @ c J }.<.<.M e J m @ X ( ( : [ Z b.q [ S =.j 5.> 3 W  .H  .5.n 4.>.*.>.4.6 6 >.4.A 4.8.>.~.-.' ; f Q h f | >.; r ).L : _.$ :.G 9 | #./ % e e y ",
+". (.(.x ' ' (.' ' x ' (.v , $ v K ~ v 3.> _.@ v v $.o :.F g.^ 5 6 *.:.6 3.$ - J _._.$ ; ,.S /.<.<.d Q ' . ~ % % @ c s <.<.[ Q b J a C 1 1 _ < Z Z b.'.c.q } ^ ] n  .i i 5.E o ~.>.*.0 0 6 6 *.4.A 4.8.A 7 n @ - $ Q h 1 f | Q !.).%.2._.b 6.3.3 ] ^./ @ Q |.Q ",
+"(.. (.(.' ' ' ' (.v x (.i.v V V V i.v ; 3.= K v @ K @ $ - H > = $ - - $ - @ V y ) V ; , e 1 <.<./.o {.' ' * ; z @ c T ;.<.} e b J + 2 1 ( : : } q q b.b.'.q q Z < 1 *.i D 5.o 4.*.~.*.0 6 6 >.>.6.4.8.>.~.6 D n o e f i Z R i Z ).%.&.b v 3.*.-.C U 1 |.b e a ",
+") x x ' (.x x ' x x K x x K v V V v V K = 5., $ v , v , H 3.~ @ $ , , V  .@ ,.(.v $ % . e 2.<.<.<.o |.' v - ; % b b s <.<.} Q {.J @ X 1 ( : < B q q q b.b.q q Z q q : p 5.> H 8.>.*.0 0 6 6 >.A 6.4.8.*.6 P = k ; e f X *.1 e %.L d.X _., ^ 3.=.B <.p Q D - e ",
+"J ' x ) ) (.x (.x ' K K K v K v @ > v (.@ & w , @ , > -.5.w ! @ $ - - - b # v a ; v ) . e S /.<.<.o |.+ # , # ) Q Q s <.<.M e m J . C 1 1 : : } q q b.b.b.b.q q < B Z : :.> 3 *.*.6 *.0 6 6 >.>.A 4.4.4.~.F w  .k Q K R &.n $ 2.).%.}.b > H ~.6.q ^.P e ]._.z ",
+"{._.(.(.(.(.' ' x ' ' x x v K K ~ ; = V K ' , - , 6 O 9.+.7 *.9.:.8 G R W ' % + $ . ) ' e 2./.<.<.I |.$ $ . _.Q b b s <.<.M e ,.J @ 2 1 1 : < B q q q q q q Z Z Z [ Z e.g.@.H *.0 *.*.0 6 6 *.>.A 4.A >.6 F  .o ! Q h =.C Y Q t }.t | m ) A 6 5 g.f.n {.|.e e ",
+") ) ) (.x (.' (.(.K x v v x v x V K w ! ~ v _.- H '.^ A F F ..4.C 7 4 :.B $ , % (.x ) J e [ <./.<.f ,.~ ' [.,.Q J e T <.<.[ e ,.{.. =.1 ( _ : } q q b.b.b.q q Z } _ < q ^ 3 5.~.*.6 0 *.+.6 >.>.A 8.4.>.+.R ; ; $.e K $.&.R J 2.t f.%.7.J 5.-.H / ^.o Q b e $ ",
+") J ) ' v x K x (.v v K (.K v v K K ~ 3 3.v v K $ [ $ v V $ & a $ , ' # ^ z $ J ' [.|.J e [ <.<.<.o {.. b Q ,._.,.e T <.<.[ e b J @ =./ ( : < B q q q q q q q Z Z B } q ^ 3.w 4.>.~.0 0 6 6 *.A A 4.4.>.6 G o n $.Q ! 0 2.Y J ).}.).r J > 5 +.F ^ a.D b ' |.Q ",
+") ) x $ @ ) ) V v x (.' v v v v K @ i.@ $.5.$ i.$ '.[ S ^ ] F :.F :.F ^ '.; J |.b |.b ) J 2./.<.<.n Q Q ,.Q |.b Q e '.<.<.M e |.b . ^ 1 1 _ : } q q b.b.q q Z Z [ < } Z ( D $.~.*.6 *.*.6 +.*.>.*.4.4.>.G o ! v k e c n '.$.e M t ).^.Q , 3.A 6.e.s ].Q m e b ",
+"(.V % v (.x V $ v v x K (.i.i.K v K v v * 3.3.@ K 5.P 5 9 +.~.F *.~.F F n ) |.m Q 7.,.) _.M <.<.<.g Q |.J Q Q Q Q b T <.<.[ Q {.b a X 1 1 _ < B q q q b.b.q q Z } < [ B | D $.*.*.*.*.*.6 +.~.>.A A *.~.*.F i + $.b y l T *.K %.L ).'.z $ o >.6.^ a.].J $ Q e ",
+"% N v ) (.$ $ v _.x $ $ v ' x v K v v K _.; H 5.@ i.$ * ! V - * ~ $ 3.= {.) ,.,.Q b ) ' _.2.<.<./.I e e Q Q |.Q Q e T <.<.: e |.J . 2 | | _ : } q q q b.q q Z Z B [ } B | w $.~.*.6 *.*.6 +.*.A A 4.8.*.n P ..D h e c n s z _.[ ).).}.7.v x 6.3 X %.d e @ e b ",
+"- v _.) x v x ' i.(.x v v v K x (.$ x (.V , = 3.$.* V K * - > 3.- , ! a |.' J |.) ' ' ) J _ <.<.<.d Q Q |.Q ,.b b e s <.<.[ e {.b a C 1 1 S : B q q q b.b.q q } [ < } B | D 5.~.*.*.*.*.6 +.~.>.A *.A *.6 F D Q j e Q l r R K %.!./.u @ J F C A 1./.i @ z c Q ",
+"' ) _.(.(._.(.V (.i.i.x v v (._.v v (.V w , i., A 3.@ @ v > 3.3.k w 3.v , J b {.) ) ) ' ) _ <./.<.$.Q Q ,.,.Q 7.b e #.;./.} e J {.. X / | _ : } q q b.q q q Z Z } < } Z | > $.6 *.6 *.*.6 +.~.*.~.A 8.~.n 6 :.d z K e o %.@ e Z ).).T J * F 1.~.B }.0 Q ) m J ",
+"_.) (.(.' K x x x (.i.' $ , $ V x i.v * & v @ - , R n ~.6 O 0 6 *.0 5 :.*.. b [.) [.) v ~ [ <.<.<.$.Q e Q b Q e e b s /./.} Q e b . 2 | 1 _ : B q q q q b.q Z Z [ < [ B | > $.~.*.6 *.6 +.+.6 >.>.>.>.*.~.+.; Q n e Q ` } ; a !.L L M 7.# =.C 7 =.t d c $ c e ",
+"K x ) ) (.x x ) $ V K ) ) V > 3 * K @ $ i.v ! 3.K 6 ~.F 9 5 [ | 6 7 0 5 F * ) ) ) (.+ ~ + Y <.<.<.k |.,.|.,.b Q Q J Z <.<.1 J Q {.. =.| | ( : } Z q q q q q Z B } : } B | w 5.6 6 6 *.*.6 n ~.>.>.A >.6 n F F o ! a Q 0 ^.c e T ).;.2.J i.6.A 5.=.%.>.J N y b ",
+") ) ) ) ) (.K v ) V , $ i._.v = $.& v v @ ; ! v V K $ = & V | ~.$ @ *  ., - x (.) x , + Q G a./.u J e Q Q Q Q b b e 0 ;.;.j e e b a C / 1 ( : B Z q q q q q Z Z [ : [ Z / w 5.~.*.6 6 6 6 n 6 *.~.A >.*.~.R = (.n Q Q Y u @ @ #.;.;.1 c ) F C F j L o c @ e e ",
+"x ) ) (.' i.(.' K ' , = @ K K i.= ! v K ! * i.V v ^ ^ S | S j.Z | | ^ ^ | W @ v # * ' b b {._.~ |.Q e e _.e Q ,.J b e @ @ b e J b . ] / 1 ( : } q q q q q q Z B } < } B | w 5.~.6 6 *.6 6 +.~.>.A 0 >.6 6 P o  .; $ J =.U e b #.).<.1 7.3 C A 8.^ L O Q c c e ",
+"i.(.x (.(.K ' _.(._.K , * a K @ ' ' i.@ > k * i.v *.:.F :.F >.+.6 :.:.:.F * , , = (.b |.|.Q e |.|.e J e e e b e e b e b e e Q {.m a =.| 1 ( : } Z q q q q q } B } : < B 1 w 3.6 ~.6 *.*.+.n 6 *.*.>.>.G 6 n ; J g Q e u &.J @ T t L 2._.F >.8.*.| a.>.K ; Q e ",
+") v v (.) (.(.(.' x i.' = * K y (.x ' @ ! 3.- $ K V @ & ; @ x & v $ $ $ (.' % = (.b |.|.J _.,.e e c 7 [ T }.T } R a e e b b b b b K 2 / 1 S : [ Z Z q q q Z Z B [ < } B | D  .G 6 6 6 6 6 +.~.~.G *.4.~.n P H - I z Q 2.u e e }.%.;.{ ,.= 9.~.A =.L C e J y |.",
+") ) x v x _._.K i.a a K , w , _.y V $ * 3.* ~ > $ i.a a , w $ v , @ x V y V V y a ) {.Q m e e b 7 }.<.<./.;.<.<.<.L 0 e e Q b c b K =.| | S : [ Z q q q q q Z B } : [ } / D 3.6 ~.6 6 6 6 n ~.~.A *.*.G n 6 o + f y e T =.b a &.;.L M 7.-.6 ^ -.A %.>.v z e e ",
+"J J (.V V x i.) i.y a $ , , - ! x v @ - k > ~ * * , v = 3.* ' $ $ @ v @ . J _.' # x J J [.e ~ 1 ;.<.<./.<.<././.<.;.<.e.@ e @ e b K =./ 1 ( _ B Z Z Z q q Z Z B [ < [ B | >  .F 6 6 6 *.n n G ~.*.*.>.G n n i ) j @ J Z }.e {.}.L <.G ,.H ^ +.^ ~.f.=.y N J J ",
+"' i.) ) v V v i.v v * $ y a ! w @.V v , ! k k * K ^ : : O , H ( ( | | g.g.x _.K ) v x ' ) _.S <.<.<.<.t %.%.U /./.<.<.<.'.c e y b K =.Y 1 S _ [ Z q q q q Z Z B < < < B 1 > 3.F 6 6 6 6 6 -.6 ~.G *.A *.n n  .$ h b c #.C Q a 2.t ).1 Q 6.>.9.6 S L =.b v |.e ",
+"x v ' i.i.v V V $ = , a ' $ , a -.= @ @ @ > $.k ~ : 3.' v $ ] A V @ , 3.< & y b |.@ # ' {.> L <.<.<.r h Q b ) ~ }.<./.<.;.I e Q b K =.| / _ _ } B Z Z Z q e.B } } : < } / w 3.G 6 +.6 6 n +.6 ~.*.*.~.G F R w ' l $ e Z u Q b %.t ;.p 7.! 8.*.*.=.).0 e @ e e ",
+"i.v , & v _.' , , a _.' - & (._.a V , - ~ K ~ -.k ^ ~ - $ x 1 :., # a ' ( J ) a ) J (.+ ' j <.;.<.L . e ,.e Q e b #.<.<.<.o ,.m b K =.| / ( _ } B Z q q q Z Z B [ : < } / D 3.F 6 6 6 6 n n +.~.~.A *.~.+.o 3.- $ c c !.j e c 2./.^.0 |.3.+.8.+.*.^.| J v Q e ",
+"v $ (.y * V b = , x ' ' V , a ' ) $ V v * ~ @ * -.j.j.c.j.^.j.> $ { ^ ( '.& J _._.J ) ' m : <.<.<.C Q e 7.e ,.e Q > <.<.<.O e Q J y 0 1 Y _ : } Z q q Z Z q B [ _ [ [ < | 3.5.+.+.+.6 6 +.n G ~.~.*.~.6 F n  .- 0 y e M [ e N %.L <.f {.~.9.0 8.+.L O v K b e ",
+"3.$ ' (.i.v i.(.- V a y ' V v a V $ ' y $ ~ @ * * -.> * ~ _.$ a @ = v ) - Q . x ) ) ) ) b : <.<./.l e e b e Q Q e @ )./.<.C e ,.e b *._ 1 S _ [ B Z q Z Z q Z B : [ } [ / > 3.+.+.+.6 6 n -.+.~.6 ~.~.6 +.o 3.; o e y T f Q e M ;.L =.e 6.~.0 9.^ L Y b N Q Q ",
+"$ v i.b a $ ' K V ' (.y ' V V $ + v ) J i.a ~ * @ > k > $ $ $ V $ v $ x @ ' V ,._.J ) (.m 2.<.<./.g e Q m Q e Q e b #./.<.S e b c e @ n 2 : < } } B q q Z Z B } < _ : [ ^ > 3.n 6 +.6 6 +.n +.G *.~.G n n n o I P c b M X Q a ^.L <.h e 3.^ *.>.=.d.>.$ J Q e ",
+"b i.K J V = V $ y y (.) i.' V $ ' ) ) ) ) ) a @ ~ @ * 3.k - @ $ $ v $ ' (.a y ) _._.) (.{._ <.<.<.o e Q e Q Q Q Q Q u <.<.M e e m e e x D F ^ [ q q b.q Z Z Z [ B _ : B / D 3.+.+.+.6 6 n n +.G 6 6 *.G n o 5.> @ e N M o e b [ <.).Y e = *.8.-.5 ^.u e @ e e ",
+"K _.@ $ @ ! - v J i.x v . (.(.' [.) ' ' ) ) ' (.w @ a * 3.- $ ,  .v $ v x v b a ) ) ) ) J : <.<.<.d Q b e |.,.b ,.Q '.<.<.} e e |.J b b [.. 3.F ^ S } q b.q } [ : _ < B ] 3.@.+.6 +.6 6 n n +.G ~.>.~.+.n R o H k $ e Z { e z T t <.~ ) >.9.0 ~.5.a.O @ e Q e ",
+"a ' ~ $ , ! V i.) ' V $ V (.' ) ) _._.c y y ' ) _., * ~ * > 3.@ ^ @ @ V y ' J ) _.) ) ) m _ <.<.<.f e y b e e Q e Q '.<./.M e e Q |.Q b ' V = w 3 F 4.^ S } Z q < < Z } p > @.F +.n 6 +.n -.+.~.n G ~.G n H D = {.e ; C $ e e r <.L j b h.*.0 8.^ %.&.e $ e Q ",
+"J y i.a - $ b y K V v V @ x x (.) ) c c y K y ) . $ ~ ~ @ * > > | a @ @ v v ' J ) ) y ' m : /.<.<.d Q a ' b Q e e Q T <.<.: e 7.Q |.{.J ' , ; 3 o n n n n ~.6.g.S _ [ ( 8 > $.n +.n 6 6 n n n G ~.~.~.n n o 3 i J { e &.>.b a #.t <.@ b 3.^ *.>.C d.| v b Q e ",
+"a _.K @ ' i.J K $ $ v v x ) ) J _.) y y y y y K ' ) V , , ~ ~ > _ $ $ ' x (.(.J J _.) (.m : <.<.<.n Q ' . @ ' Q Q Q T <.<.2.e Q J Q {.) ' V &  .H n :.F n o H  . . .n n ; ; H n 6 n 6 6 n n +.6 6 6 ~.n n o 3 D @ @ @ f K e |.s ;.U j e * *.C +.4.%.r c y e Q ",
+"_._.(.y J i.@ @ 3., v J ,.) ) ) ) ) ) ) y K K . a + v (.' , $ , : 3.$ y a ' ' J ) ) ) _.b M <.<./.n Q J @ , . ,.e Q T <.<.M e 7.b 7.m m v & >  .H n 8 F 8 o 3 5.D * D 3.> > $.6 +.n n 6 -.-.n 6 +.~.+.+.+.n i ; @ }.y C h e z &.<.).@ ,.P *.9.n o ^.Z c b e Q ",
+"V y J _._.K * k * -.@ _.' {._._.) ) _.) ) K . . a . . . @ # $ V - - - a a @ _.) ) ) ) ) ,.2.<.<.<.H |.. @ $ ' b Q Q T <.<.M 7.7._.e J ' N = ; > 3. .o R P R o 3 i = D 3.w > 3.n +.+.n 6 n -.+.6 +.~.~.+.n -.o n @ o k K N e e %.t L f @ ~.8.*.9.7 f.2.K b e Q ",
+", v J ,.) @ * * k ! $., J (.m ) _._.) ) ' . . + # @ % @ @ (.% % . = ; - ' y ,.' ) ) (._.b : <.<.<.H |.@ + + x ,.e Q T <.<.M e e e e H { ^ g.*.n  . . .5. . . .3 D w i 3.w > k n 6 -.+.+.-.n n 6 ~.6 n 6 6 o 3.D z /.b C v e $ S <.!.J 7.A 8.8.*.: L u Q c e e ",
+"K @ @ a $ $ ' J 3.* > k v b ' [._.) ) ' . v v v # . # x @ @ # # = , @ D v $ ' J _.) ) ) ,.: <.<.<.o {.' v ~ ' Q e Q T <.<.M e 7.m c 0 / S _ < [ S ^ A P 3 3.3.D W ; D D 3.3.k +.+.n n 6 -.-.n 6 6 ~.6 +.n H 5. .8 2.j J c e e ^.t %.f 7., 8.9.*.7 f.Y y e e Q ",
+"_._.v w 5.$ _.) ~ * * k 3.v [.) ) _.) ' x . @ @ V V % % E j P n R n $ v $ $ . ) ) ) ) _.{.: <.<.<.0.b ' @ $ ) e e 7.T <.<.M e e e c ` 1 / | : < Z Z q } ( 1.j o @.D ; = > 3.3.n +.n +.n -.-.+.+.+.6 6 +.n 3 w $ ; t e R c e c 1 /.}.Q J 6 *.^ n F ^.}.b b e e ",
+"K _.J $ 3.> a J i.K > > > 3.K ) ) ' ) ' v v V V x ^ q q ( ` j p ( | '.b.:.) ; ) ) y y _.,.: <.<.<.o Q . $ ' Q e e e T /.<.M e e Q ' X Y Y ( : < B B Z Z Z B [ < ^ A n D - w k n +.n +.+.-.-.n 6 6 +.6 +.n 3 & ,.j !.{ e J e J '.;.L k N 4.8.0 9.5.f.[ y e e _.",
+"@ i.J J @ w - _._.i.i.! > > k v y ) . v v v v V & ^ = v + % @ ' . . ' W < $ b ' J ) ) ) b : <.<.<.o |.. ' b e Q e Q T <.<.[ e e Q c X / ( S S < [ } Z Z q Z B B e.< / :.3.- 3.n n n n +.-.-.n +.+.+.G +.n 3 3.D o /.e N e Q e | ;.}.7.7.4.0 6 6 g.f.T b e e e ",
+"K a v K i.$ w > ' i.J _.* 3.! $.i.(.x . v v v V a b.0.G j j *.n 9 j P R q a v x _.) ) _.b : <.<.<.o J ) e e Q Q e e T <.<.M e Q b _.C X 1 ( ( [ B Z q Z q B [ [ S < q / o - 3.n +.n n +.-.-.n +.6 n 6 6 -.3 D > l t 0 Q e Q J }.).%.> 7.5.9.8.6 6 L [ K Q e Q ",
+"_.i.@ v _._.V w $ J i.i.@ k > > 3.* i.$ 3.- (.@ % P 7 F 9 9 j p j G ..o A H v ) (.(.y x ) B <.<.<.d e Q Q 7.Q e e Q T <.<.[ e e e K =./ / 1 _ [ B B Z q Z Z B [ : ( _ < 4.* 3.+.-.-.n n -.-.n +.+.n +.6 +.$.> m { %.e e e e e S /.T 7.' 4.*.9.H +.%.T b e Q Q ",
+"i.K K _._.i.K v R = b i.i.@ k > > 3.! $ x V & $ v * ' @ & @ , ' $ . = @ @ ) , V ' {.) = # e.<./.<.d e 7.Q e Q e e e u <.<.M e e e y =.Y / ( _ [ B B Z Z Z B B } : S < B =.- 3.n n -.+.n -.-.n +.*.+.n n 6 H ; {.*.<.j e e e K s ;.U $ z *.8.0 6 > j.T c e e e ",
+"~ ~ K _._.v ~ v @ $.w i._._.K ! k - $ K y @ = = $ # + * $ v & & v ; = v a ' (.$ ' ,.v > + : <.<.<.f e Q 7.e Q e e Q T /.<.[ e e e K =./ / S S [ B Z Z q Z Z } } < _ : B 2 > 3.n n -.n n -.-.n +.n 6 6 n n H H i *.t ; b e e e [ <.M 7._.^ 0 0 0 ] L u J e e e ",
+"~ K _._.' @ a ' b i.H 3.i.K K i.! ! @ _.@ , , = @ v = $ $ = @ , , ; ; W b (.a V x _.. % m ( /.<./.$.e e 7.e e e e Q T <.<.M e Q e K =.Y Y S _ < } B Z Z Z B } [ < _ : B ^ D 3.n n -.n n H -.n n n +.+.n o $.> {.` <.$.e Q e K r %.%.z Q ! 9.8.+.5 f.!.$ Q e e ",
+"~ @ v $ $ ' y ' i._.a $.- _.v i.K * - K ' $ @ ) ' ..F R j :.:.F *.:.*.~.o y a @ V . ) [.b [ <.<./.f e e Q e Q e e e T /.<.M e e e y =.Y / ( _ [ B B B q B B } [ : : : } C > 3.-.n -.n n -.$.n +.+.n +.n n H 3.7.=.;.=.e e e e u <.[ 7.) O 6 0 *.+.}.u J e e e ",
+"w * $ * $ _.i.v _.a {.a 5.$ ,.K K K * * @ $ , _., B *.:.p j r 1 *.0.:.P c.$ (.b y . ' y J } <././.$.e e 7.e Q e e e T <.<.M e e e K C | Y 1 _ < } B B Z Z B } [ : 2._ } ^ > w o -.-.n n -.H n n 6 n 6 -.3.5.3 [.X ;.v e e e K 2.;.s c = A 9.8.n ! }.^.N e e e ",
+"$ & * @ i._._.' @ {.(._.$ 3 @ b ~ y ~ > > > 3.* y : @ ' $ x _ A 3 V ' y : ' D , {.(.V # m _ <.<./.f e e Q 7.Q Q e Q T <.<.[ e Q e y =.Y | ( _ [ B B Z e.Z B } } _ : : } C w > n n -.n n H 3 n +.+.n n n n n o ) | t M Q e e b e./.1 7.@ C 6 *.9...#.#.v e Q e ",
+"m ~ - ~ @ @ K _.' % (.(.@ & w ! _._.y a * > w > a '.7 ~.R ~ 2 H $ ( ^ h.j.! v $ (.,.) + Q / <.<./.f e Q Q e Q e e e T <.<.M e Q e K =.Y Y 1 _ [ } B Z e.Z } [ [ _ : : B Y w > n o H n n -.H n n n -.-.-.$.! ; ' U ;.; e Q e J 1 /.u J 7.n 8.*.*.| d.%.v e e e ",
+"|.{.$ > * @ K i.) J @ & V _.' H * i.y a K ~ > > k k o :.-., v , , o *.:.5.a J ' - a J v b [ <.<./.o e e e e Q Q Q e T <.<.} e e e y C Y / S _ < B } B Z e.B B } 2._ : [ ^ w 3.o -.-.H n H $.n n +.6 n -.3.H  .) u <.M Q e e e u <.X 7.' H *.9.*.G ^.}.N e e |.",
+"[.Q {.$ = = V i.(.(.v v y J _.* P ! y i.@ @ ~ > ! ! , a ' x @ + # + W W ' b ) b = & J ) |.: <.<.<.$.e e Q e e e e b './.<.M e b e y =.Y Y 1 S [ B B B Z Z B [ < _ S : [ / > D R o H -.-.H 3 n n n -.n -.3 @.. ; t t j 7.Q Q y X <.M c > O >.0 -.$.T %.v e e Q ",
+") ,.{.) $ ; * K v ' v ) J K $ , W 3., J i.v @ ~ > 3.! x i.$ * $ $ & @ x (.y y x V ; J J |._ <.<.<.k e e b Q Q b e {.T /.<.S e e e c C Y | ( _ : } B Z Z Z B } } _ _ : [ ^ w 3.o -.H H n H H -.n +.H -.-.5.> ' k }./.S Q Q e e }.<.0 7.> 8.8.0 8.H %.}.; e e {.",
+"J _.) {._.V - $ V K K ) ) V , V b V ! $ i._.K K * ! $.3.& v @ $ , W $ ) ' x x & ' % . (.,._ <.<.<.k b e Q Q b e e e T /.<.[ e e e y O Y Y 1 _ < } } B Z B B [ [ _ S : [ / W w o n H -.-.H H -.n n n $.H 3.3.> ! <.).O J e Q J 0 ;.u 7.7.*.6 *.6 9.#.).c e e e ",
+"_.) J b {.(.$ ! ~ K K v v v v ' ) (.& ! , i.i.@ @ , ! 5.> V a $ & V V (._.$ - a b b $ + b : /.<.<.$.e e e e Q e Q e %.<.;.M e Q e y C Y / S _ [ } B Z Z Z B } [ _ ( _ < ^ w w o o H -.n H H -.n n -.$.H 5.3.; h u /.| e ,.e e T <.j 7.* 9 0 8.8.5 f.#.! e Q b ",
+"$ ' b _.) ,.J V - ~ v @ ' ) K @ @ x (.$ w * K K K K ~ ! w w = V V v v V , - V ,.) 7.J y c r <.<.<.j e Q Q e Q Q e K t <.;.Y e e e c C Y Y 1 S < } } B Z B } [ < 2.S : < ^ W w o o 3 H -.$.H -.n n $.-.$.3 = J j <.L 2.J e ,.e | /.| c  .C >.9.-.R '.%.c e Q Q ",
+"N v ) J _.b b _.- ! * ~ v _.' x ' . ) ) , w , i.K K v $ - w = v i.V v V = x Q b . ,.7.,.c S <.;./.} e e Q e Q Q e 0 ;.<.<.0 e Q e y C Y | ( _ < } } B B Z B [ < _ ( : < ^ w w -.-.H -.-.H $.-.n n H -.$.5.> J >.L ;.C e ,.e e } <.j 7.D =.0 9.8.= j.).i e e e ",
+",.# # J m _.) J i.* * ~ @ K (.) v (.' (._.$ w * K v v v V , $ x @ (.& > x ,.i.& ' # Q Q 7.{ /.<.<.t z Q e e e e N ^.<.<.<.R e e e c O Y | 1 S < } } B B B B } < _ S : < Y W w H -.3 -.-.H $.-.n n n 5.k 3. .> 8 /.;.u ) e e e 1 /.1 7.,.4.~.*.9.O }.}.y e e Q ",
+"b ' # . J J c J b K = ; , v K ) ) ' v v ) _.v - K v K @ @ V = ~ V v = v J $ ' J b v @ b e $ t <.<.<.#.0 ; c @ j t <./.<.;.$ e Q 7.J =.| | S _ [ } B Z Z Z B < : _ S _ [ ^ w D n o H H -.$.H -.n n -.H 3 w 3.7.=.L /.>.e e e c } t j 7.J n 0 0 *.8 f./.i e e e ",
+"J J ' @ a ) c J _.b i.$ = , $ v (.' (.v ' (.K $ > K i.i.v $ v v $ $ & (.J 3.= ,.) ,.. ' Q Q 2.<./.<.;.;.<./.t /.<.<.<.;.u J e e e c C | Y 1 _ : } } B B } } [ : _ _ _ [ / > w o o H -.n $.$.-.-.H -.H 5.3 _.b C t ;.}.e m J e 1 <.0 J ].8.8.0 n P j.}.v e Q e ",
+"i.b J v @ a y _._.{._.' $ , , v v x (.' x v x i.i.3 w _._.V V , , ; * K J i.$ ' J J . [.@ Q _.Y /.<.<.<.<././.<.<.<.t =.y e e e 7.y O Y C 1 : ( B B B B B B < < _ ( : < ^ > w -.-.3 H -.$.H -.n -.n $.3.3.3 ) | ).;.f e e e y S t i 7.o C 4.C 6 V }.t h e e e ",
+"_._.J _.) @ @ K J ) ) _.(.V , $ v x (.(.x x v x (.< : : 6.V :.B ^ S B : S i._.V a b (.x ' . e e g &.<.<./.;.<.<.<.r $.e e Q Q e Q y O 1 Y | : < < < B Z Z B < : 2.( : < ^ W D o -.3 H -.$.$.-.-.H n -.H 5.j J 1 /.).Y b ,.b e M <.{ 7.@ C 8.0 ^ 6 j.#.$ e e e ",
+"J i.) J _.' @ N J c _._.) a $ = V v K (.(.x x v x ^ > 3.= ) ( ~.$ a @ w } K _.v , y b (.m @ # Q e ) $.O : r S 0 $ e e Q J e e J 7.7.j _ S / S } } } B Z Z Z } < _ S _ [ ^ > w -.H 3 H -.$.$.-.-.H H k 3.5.(.# s <.t d e Q e y 2.t d 7.' -.4.9.*.~.L ).N e Q Q ",
+"b _.) ) _.J ) N @ y J ) y ) ) $ $ $ V K i.' v v _.: v . 3 $ ] n a , $ , [ , a J ' ! _.J x (.(.) e e e e e e e Q Q Q e e e e b e b 7.h C _ S S : Z B B B } [ < : S S _ < ^ > w o H $.$.H $.5.-.-.-.-.H $.w (.7.&.<.}.O e ) Q e u ;.j J W =.9.*.~.:.j.}.N e e e ",
+"{._.) i.i.J J ' # @ K y ' J {.' ~ $ ~ V K ' ' ' $ ( q U j.j.c.a $ 5 | ^ S ! $ ' y y , v y b y + ' $ k 8 n d d g d $.$.k $.J e Q e 7.J $.O 1 _ } < } Z e.B [ < < _ ( _ < ^ ; D H H 3 H -.5.k -.-.-.H k $.3.R + ^.t /.$ |.b {.c X t ! 7.o ^ 0 *.+.w s L ; e e e ",
+"{.) J b _.i._.{.' $ # c _._._._.v V V V V v x i.(.x V x x # @ v y , y ~ ' y , , ' b , ' $ b a Y %.t <.<.;./.<.<.<.<.<.<.<.0 e Q e b 7.b . W d 7 | _ B Z Z } < : S ( : < ^ ; w o 3 $.$.H $.5.-.-.H -.$.5.5.[._.#.<.}.o e @ Q e u ;.>.7.* C 4.9.9.= q L k b e e ",
+"_.) _.J _._._.) J ' @ # . ) _.) J (., $ V V V (.i.V v v V ' . $ a @ @ y m ' y * , m b ) ) Q q <.<.d.<.<.<.<.<.<./.<.<.;.<.1 Q e b 7.,.) . @ # ; D R *.] S } B < : / ( [ 4.> > H 3 $.H H $.k H -.$.5.$.> - (.! a.;.t @ e K Q b X %.].Q . *.4.0 >.h.^.t $ e e e ",
+"_.J _._._.) ) ) (.J ' # V ) {.(.' _.a , $ V v K ' i.x V (.v & (.V ' y a ' J b ' * $ a _.) k L <./.<.<./.<.<.<./.<.<.<.<.;.0 e Q Q Q Q ,.) v * D 3. . . .H ~.1.=./ _ B _ R = 3.H 3 $.H H $.$.H H -.5.3 5.E x ~ T <.u b b a e e &./.k 7.o >.4.4.*.7 U /.i e e e ",
+"J _._.J _.) _.) ) _.J x @ v (.) ' J ) @ $ $ V v ' x _.' V x x a ' @ y ) v b y b v * $ ' b { <.<.<.d.Y p 0 0 0 l j 0 l l n ) e e e {.b {.' v - 3.3.3 o 3 5.@.3.> D P 9 8 ; = 5.5.$.$.H H k $.H H $.5.5.5.o , n /.%.}.y e K J c 1 !.; 7.j 8.=.9.-.R '.a.v e e b ",
+"_.J _.) J ) ) ) J ) ) _.(.# @ ) ) ) ) ) a , & V ! =.| C ^ ^ ^ 2 ^ ^ | : b.(.J ) {.@ = = {.^ <./.<.< |.e e e Q |.e Q e Q Q e |.,.e Q Q ,.. @ & = 3.3 H 3 E @.> ; @ @ N = = ; 3 3 5.$.$.H k $.H H H 3 3 3.D |.i }.<.Y Q J K e e Z /.! 7.> ^ *.8.6.* '.d.j e Q e ",
+"J _.J _._.) _.) ) (.(.J _.V # . ' ' ) J ) v $ $ (.V V v ' @ & ' a a ' _.( ) y J b _.$ D (.S <.<.;.j e m m ) ) ) ) m ,.a ' Q Q e J e Q [.% & ; ; @.@.3 E 3 3.3.= * @ & D > ; 3.H $.5.H $.k k H 3 H 5.5.3. .@ { t !.#.e e N Q v M !.h 7._.9 =.9.>.O c.f.@ e e Q ",
+"J _.J ) _.) _.) (.) ) y ) (.. @ # . ) (.(.) (.$ , , a ' a y a V $ i.v D q . Q b J b ) $ ) r <./.<.I b . ) ) ' @ % # # % @ ~ . e e e > j O A F 3 D D 3.3.5.@.3.> N @ % = ; ; >  .$.5.H 3 5.5.H H $.5.H @.; b { ^.;.=.e y N e Q M ).; 7.3.>.C *.:.~.j.a.o e b e ",
+") [._._.) ) ) ) ) _.) ) ) _.) x # + (.) ' ) _.x $ ^ : | | | ^ | ^ S | 4.~.(.|.y J b b [.J } <.<.<.H ,.[.@ x . $ x , , ~ $ $.* e Q |.7 2 ( _ _ S =.A 8  .> > W > * $ * = W 3.3.3.5.$.3 H k 5.H 3 H 5.3 ; + e | %.).Z b e K J N 1 #.N b F =.: ^ ..6 q L ].e e e ",
+"_.[.[._._.) _.) J ) ' ) ) ) ) {.. # x ) (.' ) ) V $ a $ ~ y ' a @ a ) , |.(.b _.J J y [.b : ;.<.<.$.7.(.d = . v $ @ @ # = I @ e Q ) X | X | _ [ B B < | 6.o 3.* * * ! ; ; ; 3.3 5.5.3 3 5.5.H 3 $.3.H @.> ' S #.t *.e y @ ,.a } ).- Q 3 C 4.^ 6 ! b./.n e Q e ",
+") ) _.[.[.) ) ) ) ) ) ) ) ) ) (.) ' + + . (.(.' (.' @ $ @ $ a ' ' V x (.(.b [.J J ) ) [.Q S <.<.<.H Q = o R W x @ $ + $ D ; y e e c =.Y | 1 : : < < } B B : 2 1.f W N ; > @.= 5.5.5.5.5.3.5.3 $.H 3.3. .I {.| %.!.[ e e z % E #.#.$ ,.x 1.C C G :.q ^.f e e e ",
+") [.J ) [._.) ) _._.) ) ) ) ) ) ) (.. @ @ . (._.) v (.@ @ @ (.@ v a x ' [.) ) b J ) ) ) b : <.<.<.I _.= # ;  .; v @ ;  .k & _.Q e ) X Y | 1 _ < [ [ } } Z B < _ S Y 9  .* ; 3.H 5.3.3 3 3.5.H 3 3 H 3 ; = K Z #.t 8 e J b ) n 1 ;.@ 7.; A ^ : 4.g.^./.$.e e Q ",
+"b J _.) ) ) ) _.) ) _.) ) i.) i._.) (.. # V . ) ) + J , ' $ $ ' a x a ) x [._.) _.J _.) m M <.<.<.n J ' ) @ W D ; , ;  .* _.|.e e c =.Y / | : : < < < [ } B < < _ [ _ O  .> > 3 @.5.5.5.3.5.3 $.5.3 5.; _.e u #.#.2.e b % |.' Z '.N ' G =.: C -.P '.^.n e J e ",
+"b m J ) ) ) J ) ) ) _.i.) i.) ) (._._.) . V @ + # q ] 2 / ^ ] _ ^ ^ ( ] ^ . b J J _.) ) m M <.<.<.j ,.) + v v = i $ ' x [.e e e e c C Y Y 1 _ : < < < < < < _ S | | : _ G ; =  .5.3.5.3 3.5.3 $.-.3.3.H > ].#.s ).h b b . . i S ;.) 7.:.C S : n @.c.<.i e e c ",
+"m m m J [.[.) _.) ) ) ) ) ) i.i.i.) y y (.. @ # ) ] ' ) ) . $ x $ a ) # ( b b ' [.y (.) Q _ /.<.<.f ) z x ' a x = x Q e |.Q e e e c =.X / / : : : < B B } < : _ _ 1 S [ 1.> > 3 3.3.5.5.3.3.3 5.5.5.3 * |.v u s #.X e Q D D D ^.q ' 7.V 4.S S *.3 c.t O Q e e ",
+"b b {.J _.[.J _.) ) _.) ) ) ) ) _._.i.y ) (.. + . q l n P N [.* $ @ x > } ' b {.[.) ) ) e S <.<./.d ,.$ % # x v $ v b e Q e e e e c C X Y | _ : < < [ [ [ < < : 1 | 1 [ 2 @.3. . .3.5.$.5.3.3 5.H 3 5.* _.i T T ).y b e e $ F < L J 7.= A 8.[ 8.A }.<.f Q e {.",
+"b b b b J [.[.) ) _.) i._._.i.i.i.i.y (.y (.' . z 0 { X / X C 2 C 1 / g.p {.|.) _.) ) _.b 2.<.<.<.g e ) ! = x $ % , v b e e e e e J C X / | _ _ [ } < [ < < _ S 1 _ 1 [ 2 > ; 3.3.5.5.5.3.5.3 3 $.$.3.> b $ s #.T R Q |.~ x # j.q . N *.C ^ S 8 6 j.d.0 e e e ",
+"m b b b b [.[.) _.) _.i.i.) ) _.K y y y ) y ) ' . + z . ) . ) ' v v + $ |.) [.{.) ) [.) _.[ <.<.<.I e ' # = , V @ # * @ ,.e e e e J C Y Y | _ _ : < [ } } } : _ 1 1 | [ ^ ; ; H 3.3.3.3.3.3.5.3 $.$.3.n N f %.s s Q e _.$ $ = < %.e 7.A 6.S [ 3 o q a.o e e Q ",
+"m m m ,.,.b {.[.) _.) ) ) i._._.y y y ) y (.y (.. . , $ (.x . ) ) ' ' ' [.x [.) b J y . ) } <.<.<.d Q . . . $ ; @ ; $ @ & ) e Q 7.c O | | 1 S : : < [ [ [ < _ _ S | S [ Y > > @. .3.5.$.3.3.$.$.$.$.- @.e R u }.[ ! e e ' % > }._ @ 7.; 4.4.}.:.; e./.| e Q {.",
+"_.m m m ,.m {.{.) ) ) ) ) ) ) ) y _.y (.y (.(.y ) (.' @ # ' ' @ ' ' ) ) @ Q ) . ' (.y (.b : <.<.<.o e _.' # = ; @ + v = D x e Q e J O | | 1 S : < < [ [ [ [ _ _ S 1 1 _ X > > @.3.3.3.5.3.3.5.5.$.> H N 7.>.).u T e e (.. @ n #.U 7.@ @ A S C ~.A }.d.l e e e ",
+"J [.J m J b b b [._._.) ) ) (.y ) (.) y (.(.y (.) R :.F :.F 8 o P P o E P |.[.) a x (.) Q S /.<.<.o e _.+ = = % # v $ D  .. 7.e 7.c O | Y 1 S : < < [ [ [ < _ _ S Y _ : Y W > @. .> 3.5.3.3.$.$.$.3. .H J 0 }.!.C . |.W z J R L Y Q J E A C j.*.F U /.7 _.e e ",
+"J _.J J J J b {.J J _._.) ) ) ) ) y ) ) y (.(.(.+ ` ^ ] ^ ( : 2 ^ Y Y ` 4.@ [.b (.) ) ) |.: <.<.<.d Q ' ~ * % @ # % W i D # {.e 7.c O | | 1 S _ : < [ [ } < _ _ 1 | _ : 2 > > @. .3.3. .3.3.$.$.H 3.3.@.7.1 !.[ O e e a J b Q O T 7.J ` 1.4.G x o c.t { b Q b ",
+"m m J J [.m {.,.{.b J ) ) _.) _.y ) y y y (.(.(.b v ) ) . ' # . . ' _.) ,.Q |._.J ) ) ) b _ <.<.<.d Q + ~ $ v v & ; > ; - & @ _.Q c =.| Y 1 _ < < [ < [ [ [ _ _ 1 Y _ _ Y > > 3.3.> 3.3.3.3.5.5.5.w  .(.y 2.u h e Q e 7.c y { 7.i y Q * i _.A ~ > _ ;.| e c e ",
+"m [._._.[.J J b b ,.{.J ) _.) ) y ) (.(.) y y (.. ' J x v ) + # v @ y _.Q m e 7.J ) [.J |.: <.<.<.d ,.. . . . # = & , & - ; z N J y C Y X | S : : < [ [ < < _ _ 1 Y _ _ 2 > > 3.3.> 3.3.w 3.5.$.5.5.> ' ,.! @ K f e Q K 7.1 Y k Q Q v $ 7.` ] ^ j { u z c s 0 ",
+"m m m J J _.J J {.J J J J ) (.y ) y ) ) y (.(.(.) x v + . ' x (.% * ) Q m Q e |.b [._.b Q _ <.<.<.o Q ' ' . @ = * $ @ % ; W W > @ N | 1 | 1 _ [ : < < [ [ : _ _ 1 | S _ X W > @.3.w 3. .3.3. .3 3. .o P ' j ; Q J e Q K Q ; L ; J @ J 7.N _ }.|. .0 L [ { R y ",
+"b m m [.m _.[._.[.[.J {.J ) x a ) y y (.) (.(.(.) ) ) J x v ' . (.% . ) $.J 7.e e b [.[.b < <.<.<.n ,.) ' ~ % * v % $ # - W ! > h k M [ | 1 S : : < < < [ : _ _ 1 Y _ : 2 ; > 3.D > w 3.3.3. .3 n E N e f }.| v e b e b b { [ ; Q J ' N 7.P $.. ~ C t ).).h e ",
+"m m [.J J m [.[.J ) _.|._.= = v _._.) ) y y ) ) ) | / : ( b./ = H ] u #.` _.e e e e b m Q : <.<.<.f e ) . ~ $ @ $ @ # & = = = =  .g _ _ M _ S [ : < [ [ [ < _ _ S | S : Y D > 3.5.= D > D > 3.7 g h v c ! M u Q b e e j >.j T z b J v a e N l v N { %.L ).>.e ",
+"m m m J J m [._.' {.,.' V # x (.) ) i.) ) y (.) @ 1.V ) . b z j.` R @ J b e ,.e e e e |.e : <.<.<.d e ' v # # + @ @ $ # ~ - D $.@. .1 [ [ 2.S 1 : : [ [ < : _ S S Y 1 : ^ > > i - 5.>  .D ;  .D c Y M e h =.n v e b e h O S T ; Q ' J b Q K f i c O <.%.t N r ",
+"_.J m m J _.[._.) b J @ & ' J J ) y ) y y (.y (.) j ) ) $ ' . ^ # . {.b ) e Q e Q Q e e Q _ <.<.<.d Q ' . + @ @ + % % @ $ = D 3.D > 1 r [ M [ : : < [ [ } < 2._ 1 | ( : X D W D D ; i > D * @ ,.{ y Q $ k 2.O e b e e 7.7.> Y E c z N h h @ z N c | %./.s Y ; ",
+"J m m m [._.[.[.|.' ~ $ x ) _.y ) _.) ) ) (.y (.x ] ^ ^ g.^ 2 ^ ] Y / C l K e e e Q Q Q Q : <.<.<.o ,.. . . . @ # @ # % ; > ! = * 3.: B _ 1 S 2._ : < < [ : _ S S Y 1 : X > > D w 3.i 3.I Q D @ ; R Q Q =.1 0 b e e c y b 7.].7 g I $.d ].v k N a M <.t ).$ T ",
+"b m m _.m m m b {.@ & . J J ) ) _.) _.y y ) (.) b + J . . + ) {.' ) {.J c e e e e Q b J Q _ <.<.<.o Q y ' v v @ V . . , W W ; * V  .< _ 1 | 1 S : : : < : : 2._ 1 | ( : ^ W > D D - i & = # . K T v b Q j u 7 J Q 7.7.N z J % A n h f d @ @ 8 @ $.S }.#.^.Z 8 ",
+"b m _._.m b {.[.$ # x ) J _._._.y y ) ) y ) (.) ' ) {.v ' ) x @ _.) _.Q b e b Q e m _.) Q _ <.<.<.o |.' ' . + # @ @ % ; > , N * > o : Y Y 1 1 S _ M < < < : _ S 1 Y S _ Y W > D = 5.7.$ > $.N J i j Q { S $.+ @ j z 7.K b _.k A d W $.k K $ 0 ! o r '.T u R ].",
+"m J _.m b m ) ' % (.b [.(.) ) _.) ) ) y ) (.y y ) (.v ' J x + |.J _.) ,.Q e Q e ,.J ) _.,._ <.<.<.o Q y ' v v v + * W > - $ , = o o / ^ Y Y 1 S S _ : < : : _ S 1 | 1 : 2 W W D 3.= |.> G D Q c } b &.#.I $ ' ! h h b J K v D =.0.i o f @ N >.; *.&.^.U /.L &.",
+"J m _.J {.{.' # ' J b J y _.) (.) ) ) (.y (.(.) x 3 n H :.n 3 n 8 o n $.$ Q Q e _._.J b Q _ <.<.<.I Q ' . + + v # ; W & @ $ > $.; $ 4./ | X 1 S _ _ 2.< : 2._ S 1 Y 1 : ^ W W D w v v / a.! e e j { P X $.- I ! o N 7.y b a f O j ].i i v v j @ j u '.^.).;.%.",
+"J {.,.b _.+ + ' ) _.J ) J ) ) ) ) ) ) ) ) ) _.i.v H P P G R d o o d n P s e ,.[.[.{.J [.Q _ <.<.<.o Q ) . + v # w @ , % . > P & 7._.G < _ ^ 1 1 S S _ : [ : S S | 1 1 ( 2 - w w > > J > j a e c l y K D o g ! h k i Q z $ K o =.I > i f c N j $ n s '.%.d.^.s ",
+"J b |.) x a ' ) J _.J ) _._.) ) ) _._.) ) ) ) i.b $ ' b J b J ) {.' ,.e X m ) b J J _.) Q : <.<.<.d e _.' @ $ $ @ x v = D , . Q v x  .] : < < ( _ S _ _ 2.[ 2.S 1 1 ( : ^ - W w W # m Q e c e e =.0 ].0 j ! ! @ f ; b y c a h =.n i i d N N O z =.!.}.L t }.T ",
+"b |.J ' a x J J ) [._._._.) _._._.) ) ) ) (.) ) x H P o o o d d F I n 4.'.@ |.) _.J [.[.Q _ <.<./.o ,.' ' ' # = & $ @ % i . e Q ; - W H 9 4.g.C | : } [ [ 2.S | / 2 / : ^ w - ; w - . e z ~ e $ } [ =.P f $ k i f $.e @ K Q n { o ! i $.{.k *.z 0 U &.s ).}.u ",
+"b J (.. (._.{.J _.[.[.) ) ) ) ) ) ) ) ) ) (.) ) x 3 o o n H o o 3 n j D W b ) Q [.J _.) Q : <.<.<.f e m @ + + . $ % W = , [.7.,.; H o 3  .W W H F { / _ [ [ [ [ S / _ : g.W - ; W 3 I e j ).K Q [ u 0 j @ N h h f a y y c N ! Y f ].! ; @ @ Y z 0 T &.%.t !.#.",
+"b ) ' y J {._._.[._._.) J ) ) _.J ) ) (.' ) ) ) ,.) {.|.J J m m ) b a x ) e m (.J J J ) Q _ <.<.;.0 K @ % ; W > = -  .i > ' ) , - 3 3  .H  . .o = ;  .P A { ] Y / 1 : | :.= - 3.; > |.e &.u c $ 2.f j z z ].$ ! i k e $ y e k *.I ].> k Q ! *.! j #.u #.;.%.&.",
+"y y ) b J [.) J [.[.J ) ) _.) ) _.) ) ) (.) ) _.b c b _.) _._.) J v x {.m [.|.b J J J ) Q : <.<.<.t t ;.t t t t d.d./.d.L ` . , $.H D ; 5.H o R H 3.= = > = = * H I n ..D = ! w ; I - _.m n e Q 2.{ z f $ N h ; h c y c Q @ N X $.h i i z y { $ O #.#.%.%.#.'.",
+"' (.J b J _.) J _._._._._.) ) ) _._.) y ) ) [.J b y c J J ,.) . ' , ' b J ) b [.[.m ) J |._ <.<./.<.<.<.<.<.<.<.<.<.<.<.<.| ) ! W ; W w 3.3 H -.F o 3.> ; ; % @ . {.(.# , - W - W = _.7.].k b N | >.k $ $ N ! z ].].Q @ c _.f Y n k f d $ ].j ].*.}.#.!.;.}.} ",
+") J J J ) J J ) J [.[.[.) ) _.) ) ) ) ) _.J J b y @ c J J c . . V ' _._.m b b b J J [.[.Q : <.<.<.<.<.<.<.<./.<.<.<.<.<.<.S . ; = = W D w  .o R o o 3 3.* = & $ . {.v = = = ; > ; % $ e o T b e &.{ N v $ ! z ].].v K ~ c a h 1 o i ! > z @ j N O }.#.!.L #.[ ",
+"J J J J J J J J ) _._._._._.) _.) y ) [.[.J m J J Y b c _.' 1 j i.a y b J b ) J [.b y J Q S <.;.;././.;.<.;.;./.<.;.d.<./.l ) @ = = W k 3 H -.o R +.R 3 w = , # ' ) . & = ! > ; W % ,.Q O M y z X 8 K K $ ; ; z $.z b @ J K i C l i h h N N $.z j u s !.t %.'.",
+"b J J J J _.J J J [.[.[.[._.) _.) ) ) J m m J J Q X c b _.N ^ j _.i.y _.) 7.|.J b ' m ) |.~ ; h > z ! ; a y @ $ % $ ! $ . |.. . , = W D 5.3 -...R F F o  .> , V ) ) @ & = - w ; = $ y ,.7 %.Q e r 0 N $ ].N @ z y b J a y K $.| l h h i ].z i N j &.u #.L L !.",
+"J {.J J J J _.J J _._._._.) ) ) ) ) {.b {.J [.J . &.Y ^ / / c.[ ^ ^ ^ ^ 4 @ b ,.b y |.) ) J |.J b e {.~ ! f k K b e e e Q ' @ + , - ! D i 3 H o R P F F R 3 ; @ ) ) @ = = - > > D . 7.7.U M c z | 0 h @ N $.N b e e J N e v N O *.! ].i ! N ! $ n &.#.%./.%.u ",
+"J b J J J J _._.J J ) ) ) _.) ) [.[.{.m b ,.{.{.Q 8 o G G R j R P P P R I ) b m [.b J b _.~ x J ' =.%./.<.<.<./.s l . _.@ @ {.! z ; W 3.5.3 H o R P P F F ..i = ' _.. & = - > > & 8 E 7.| %.7.N }.8 J e b $ % $ Q e $ K c c N 0 { ! z h z a N N l r T !.;.%.u ",
+"J J J J J J J [.J _.J ) ) ) ) _.m m m {.b ,.,.,._.% V V x J _.' K a y m (.|.m [.m |.y m ) ' . H ^.;.<.<.<.<.<.<.<.<.}.o b = W $ , - D D 5.3 o o ....0.+.6 F o 3.@ ' ' # = > > = D @ 7._.C @ J j r ! ,.e Q z N J e e K N e @ K 0 { ].].i ! y @ N 8 } u %.;.).T ",
+"J {.J J J J J J J _._.) ) J _.[.b b b ,.b ,.,.J v # $ v i.) (.a _.a y b m b b e [.{.J _., _.H L <.<.<.<.<././.<./.;.<.L j ,.$ W - - W D i  .o o P P ..R F F 0.H ; # x $ = w > = = @.d 7.v N e $ #.z e e e v $ a e e z K b b ' j { ].].k i a a N l } u !.t %.T ",
+"J J J J J J J _.J [.) J J J b b Q b J J ,.{.) (.$ v J J (.' y _.y ' y b ) b ) m m y J x @ y _ <.d.<.<./.).U %.;.<./.<.<.'.$ @ ; - ; W D i 3 H ......P P 0.F 0.R E ; * & * ; ! = & * 7.' > b 7.8 S a b e Q N y e e Q v z e K y *.X h ].$.i @ @ N n M u !.;.).T ",
+"J {.{.J J J J J J [.) ) ) J b b ,.b b ,.,.J ' $ @ v _._.x ) ) a ' (._.b [.Q {.J |.y @ , y 5././.<./._ z {.e b > q <.<.<.;.d . $ ; W W D i 5.H o ..P +.0.0.F 0.R n @.; = & = > = = ,.,.Q ].f y v }.v e e v K e y e e c K e J _.o M I ].i i $ $ z *.r T L ;.L T ",
+"J {.J J J J J J [.J ) _.{.b ,.,.7.J J Q J V = $ i._._.K _.i.y ' y ' ' ) J J b b ' @ $ a e X <.<.<.e.J e Q |.[.Q Q C <.<.<.{ {.~ - ; W D i H o o ....R 0.0.0.0.R o o d 3 3.; ; ; = = 7.@.T K 7.o =.@ e b K K Q y N b K d @ e y d Y d z ! i z a K C u X X #.u &.",
+"J m {.J J J J J [.J [.[.b b |.b J ,.Q [.@ $ @ i._.i._.i.K _.(.) (.' ) _.b b J _.@ V v y e Y <.<.<.O e e [.x . ' |.o d.<./.C {.@ , ].W D 5.3 H H o ..0.P 8 P n o E R n n 3 > - = *  .' @ o 8 7.! }.7.Q @ v v z h D K $ l h J c i 1 n ].! i z N N { u u Z &.M 1 ",
+"{.J J J J J J J [.J m ,.b ,.b |.[.|.J @ = $ i.J i.K i.i.' _.' (.) ) y J ,.b _.' , x ) ,.Q 1 <./.<.I e [.x # . . _.~ %.<./.S |.. $ W D D 5. . .R ....P F 8 n n R H o F j 8 H > * W E _.@ / - Q R >.K Q ; ].].N $ k y y j D b b z | *.! ! ! N @ $ 1 2.} s %.^.}.",
+"b J J J J J J [.b b b ,.,.,.|.|.|._.V * V ' _.i._.J i._.' J y x y ' (.J b _.@ , V ) Q e e S <./.<.k Q ' x a ' . @ K }.<.<.M b ' $ W W D  .5.3 R ....R 8 8 8 8 R o d R j 9 F 3 ; N ,.= b { O 7.].u b y y $ $ N ; h y y *.g . Q $ { l z ].h N $ N 0 2.} T }.%.!.",
+"J b J _.J _.J m b b b Q ,.|.|.Q J @ N V (.J ) i._._.a ' ' ' m y x a i.J _.v V x J Q Q e e 1 <././.d |.' ' ' v @ ~ ~ #.<.<.} |.a $ = W W 3 H 3 o o R P P 8 P n o n o H 8 9 *.P H V ; ' # P J J $.X ; c ; v $ ].! j N y j d K Q @ =.{ h ! h z $ z 1 u T %.!.r } ",
+"J J J _.J {.J m Q b b |.Q ,.{.J # , @ ) b _.i.J J @ b b _.a ) (.(.) i.i.~ , V ) Q e e e e 1 <.<./.n Q [.. . # + . N s <.<.[ b K ~ z i i  .H o o o R 8 F 8 P 8 o H o R n :.9 G G E * ; ,.n i e R T b K v ; z ! ; h y Q 8 l ].b ' { O ! ].h ].z i 2.#.T u r T u ",
+"b b J J J m b Q b b b Q ,.|.) v = @ ) J ) ) ) _.y *.a ' ' a y a _.i.a * = V [.Q e e e e e | <./.<.g |.[.+ . v . . ~ T <./.} Q a $ ; i i ; i ..o ....P 8 8 n R P H o n F j :.~.9 ] H [.' ) J e j O ! y $ ; i z $ i K {.P *.D {.y 0 C z $ ; N @ z Y T T u u T | ",
+"b b J J J b b Q Q b b Q |.J v , , (.{.i.) J J v ) Z H R n o o ..-.R 7 4 H . 7.e 7.e e e e 1 <./.<.k Q _.+ v ' @ ~ @ s <./.e.Q a $ - ! $ ) , H o o ..P 8 8 8 R R H o 8 j ~.9 :.j 9 @ = 7.> y e *.[ e b N v $ ! z $ c c l { $.J c l O N z ! z @ z Y #.#.u #.!.0 ",
+"J J J b ,.m b Q Q m m 7.{.$ = V J _._._.) _.) ) (.[ R ....0.H +.R G 5 9 o |.e e e e e Q e 1 <.<.<.d Q (.x . + + + . j.<.<.[ Q K N W ~ {.m ) , o P n 8 F F P R R o o n j :.G 9 9 ] D _.. . J 7.0 =.y J v $ @ z ! ; Q y =.Y n ) Q n C f ! ! z K ; | s !.T }.2.$ ",
+"b [.[.,.e Q Q Q J Q Q b a , $ K _._._.) ) i.) _._.4.' m a a b y * 3.* b ,.Q Q e e Q 7.7.7.} <./.<.d e ) . v + @ @ v s <.<.} b a N N c Q b _.x = o R R o ..F 8 o o H o P :.9 :.G E (. .c N c b { M J 7.$ v $ i ! $.a J O j 0 N c n | n ! ! z @ z O }.s } T *.c ",
+"b b ,.Q Q e b ,.Q |._.V , $ K J _.J J _.) ) ) ) ) a b @ J J , ~ ! > x ,.e b e e 7.e 7.[.) [ <.<.<.d Q ) ' + v + ~ + s <.<.} b K y c Q e J ) (.. W o F P o 0.+.o H o R j :.9 9 G ` H _.' ) J e { Y ; c J $ @ $ h f b % n C 0 $.{.i O h N N $ @ N [ #.}.!.u i h ",
+") b Q Q m Q Q {.7._.& > , i._._._.) ) _.) y ) y ) J y y i.i., 3.! a |.,.e e e e 7.|.y $ ) _ ;.<.<.d Q (.' + + + @ @ #.<.<.} b y Q e e ,.m ) ' . x W R 6 0.o R R o o R j :.9 ~.:. .Q = Q C N b >.2.J e v v v j [ Y h b *.k C $ |.i 0 z @ N K @ z 0 #.}.#.r e u ",
+") _.J |.7.|.|.Q b $ w , i.J J _._._.J ) ) ) ) ) ) x v Q (.- w w v J |.,.e b Q e e ' , x Q S <.<.<.d Q ) x v v @ v @ s <.<.[ e Q e e b b J c ' x (.@ W R F 0.o 0.H o o 8 :.~.9 9 p > ) ! b.q 7.o { J e v k O S 1 %.y J b {.> o e ! 0 ! $ z v $ ! *.'.Z #.k y r ",
+",.x . b e Q b Q , - , i.b J ) J _.) _.) _.) ) ) ) J J ' - ! > _._.,.J e b e Q ,.' . x J 7.: <./.<.f 7.) ' v v @ . @ #.<.<.M e e e e Q Q J ) ' x # ' x W 0.F ....H o n P G 9 :.G d @ v @ L 0 e k | >.C X | X 1 u S h e J Q 0 @ b z =.o N z z ; ! 0 }./.%.u u <.",
+"b y V ' b Q b i.- $ i.b J ) ) J _._.) _.) ) ) ) _.( 2 | h.w O [ 2 ] Y ` 1 Q e Q $ (.,.b b _ <.<.<.d Q ) x v + + @ + #.<.<.[ e e e e e Q J ) . + $ v a $ w ..F R o o n F :.G 9 ~.*.@ ) E ^.r e r L Z &.Z } %.t }.M v K Q b l n {.i Y *.! i h h ].0 &.;.| >.}.T ",
+"J b ' & @ |.J = , i.J _.i.J J (._._.) ) ) ) ) y _.h.* w w a g.H ,.|.J _.X e m # ) ) J b Q : <./.<.d Q ) ' + v + @ ~ #.<.<.[ e e e b b b c ) . $ . & = a $ i R R o o n P :.9 G G p ; . $ } j 7.Z %.M M Z T Z { h g a e Q K 0 @ ) ! { n z $.k z $ O L u v $.).[ ",
+"J b b b a 3.D V J J J J J _.) _.) _.J J [._.y _.J } k w ' Q / I b (.|.|.^ v = [.J J [._.Q _ <.<.<.o Q ) (.. + @ $ . j.<.<.M e e e e Q ,.[.' + # , , , , @ x - 0.d E o j :.:.:.:.F . ; @ >.k b '.).1 Z } f >.X e e b . e . n h K N C *.z ! ; $ h 2.).u Q T ^.h ",
+"_.i.J y ' V > (.b b J ) i._.J _.) _.{.) (._._.i.> [ b.j.j.c.r y y p 2 p < # ) J J [._.) Q : <.<./.H Q ) ' . + ~ . ' s <.<.: e e e e Q ,._.' V # $ & & = , . + ; I P n o 9 *.:.*.9 d y N >.! b >.Z 2.Z 0 i [ %.! Q b J e c i $ b $ O *.h $.h $ ].M ;.{ n t S e ",
+"J @ , , b Q V , ) {.b _.) ) J J (.{.[.' y J y ~ > ! * J ) J b b b |.b . ; J |.b [.m [._.Q _ <.<.<.d Q ' ' . @ ~ _.,.T /.<.M e e e Q Q ,._.x @ & & * = = = + (.) z d P 8 :.9 :.9 G n . ! 8 f y >.Z 2.O ; N 2.}.].e e J Q {.@ z z ; 0 j z ; ; $ ! } Z Q ; %.8 h ",
+"y ' W @ J _.,.V v ) ,.b _.) ) J J _.) ) J _.~ w ! a b 7._._.b ) ' |.. ; ) ) J _.J J [.[.Q : <.<.<.H e ) ' + . . Q Q './.<.M e e e e Q ,.) . # N = = * * = $ x ) [.$ o *.:.F 9 ~.:.; y $.r N v { ; h N 7.v S r @ J e y h o 8 n f N >.8 ! ! ].z i | l e l j {.{ ",
+"_.' * y y a 7._.V v (.{.b ) (._._.) _.J y $ ! w ' Q [.) ,.Q y Q 7.@ , ' Q J Q b [.{.[.) Q _ <.<.<.d e ) . . ) m e e '.<.<.[ e e e e Q m ) @ # & * = - = * % # x ,.J W j ~.:.~.:.P @.* ; !.}.j $.C j R $ N j R N z b y 8 0 l j k @ j R z z N h R X N K 1 ! c 0 ",
+"$ D a y ' J J J ) ' v x _.b _._._._.J i.* 3.- x Q [.Q b b _.J _.% # x |.) b [.) _.J [.[.Q : <.<.<.H Q ' + ' |.e e Q T <.<.M e e e e Q J ) @ $ * N * = - * $ + ' _.m (.D :.9 :.*.G D 7.R %.C $.| f b z ! ; N N g f J y R j 8 8 $.K l l h ! N ! o { N M &.K i s ",
+"$.; b J (.i.(.b J _.x V x J b ) _.J i., D - v b J q | =.=.X O / _ ] / ` 2 {.J [.J {.[.[.Q _ <.<.<.f Q ' c m e e e e T <.<.M e e e Q |.J ) @ # & = $ = ; = $ @ (.) J {.v  .F 9 9 H > N _.}.2.N k k y ! ! z i k n f e c R >.j o ; ! O 0 i h h i j i e f =.k u }.",
+"= J |.J J y ) ) _.,.b V v _.b _._._.$ k w ' |.b Q C Q J {.,.V D + ' ) ) ^ b b ) J {._.[.Q : <.<.<.d Q m Q e e Q e e '.<.<.2.e e e Q ,._.) @ # & ; & * ; = & $ . {.J ' ' ' 5.*.:.p n J N S Z b C $ b ; i N N ; ! d c ! { { 0 j o K >.>.h k h ! f y b ].y j T [ ",
+"J ,.,.J _.J J _.J b v = $ J b (.|.' w D ' Q b m J &.g k j % ; v ) ) . ; Z ,.[.{.[.J J [.Q _ <./.<.I Q e e e e e e e T <./.r e e e Q ,.J ' @ % * = = = = = % @ + ) m ) $ $ v D *.*.= z b | %.f k =.y z ! ! z ! f z 7.$ l h >.f ! ! l j h ! ! z h K > ; i T T X ",
+"|.J b J (.(.J _.b x , @ ) i.) b ' 3.D (.b b b b J g 0 =.2 ^ ^ C ^ ^ { C 8 ,.|.J [.{.J [.Q : <.<.<.g Q e e e e e e Q T <./.M e e e e ,.J ) @ # * * = = = = & @ + ) _.y # $ V * i P D J 7.; [ { 1 f b a v z z $ ; h e $ R 1 Z { k $ l 8 ! ; ! i ! v O j | s T Y ",
+"J Q ) . i.) ) ,.= $ v i.b b ' a D D a |.|.J b b b b J . ' @ ' b |.' x J Q J b {.J J [.[.Q _ <.<./.o e e e e Q e e Q './.<.M e e e Q ,.J ' . $ * = = = - = % @ . _._.x @ = & $ V 8 G = ; 0 i ; C { b v ! ].N i $.@ y h { j %.C ; N >.o ; ; ! h K e K j | T } C ",
+"J b (.@ _.Q b (.3.V J J J J V 3.W (.Q b |.{.[.,.b J ) N (.,.J $ ' ) ) J ) [.|.) J J [.[.Q : <.<./.$.e Q e e 7.e e e T <.<.M Q e e e ,.J ' . # * * = = = = N @ . _._.' @ - ; , @ ) D c >.!.k b 2.h a $ a ].! ; ; k e >.>.{ O l h N 8 k $ N h i a Q N =.[ T [ } ",
+",.$ v b {.,._.5.(._.J _.@ , - ! y _.y b 7.,._.,.J J ~ ) 7.$ (.{.' ' Q ' 7._.) Q [.J [.) Q _ <.<.<.$.e b e e e e |.e }.<.<.M e e e Q ,.J ) @ % * = = = = = , ~ v ) ) x $ = - = = @. .k 8 L R b f 8 _.N k N @ ! i v 7.z O | %.j ; v k f ; $ ; h i ! o | T &.u M ",
+"# V ' ,.,.@ ; - Q J _.y , , a y _.@ ' b |.b ,.J ,.z _.{.) _._.. ) + (.b (.7.(.{.{.{.[.[.e _ <.<./.I e Q e e e e e e ^.<.<.1 e e e e ,._.' @ # * * * = = z , @ . _._.. & = = = D P # 7.| /.Z 7.o ! z ! ; z N $ z N b j ! 2.%.2.z v k $.N @ z ; k i ; X [ r u S ",
+"= J {.) ) ; D ,._.J J ' a y m y a a _.J ) b Q J % d.a.}.#.'.}.T '.c.U '.b.x Q ) b b [.[.e S <.<./.0 e e e e e e e z )./.<.X e Q e Q ,.J ) . % & = = = = = % ~ v ) ) ' % = ; i o j > J ; L ).; i f K v ; v y ; k h Q h >.>.Y $.; K f i $ $ z ].; @ n C Y u 2.M ",
+"{.J ,.(.> = ) J {._.J b J _.y , y y _.(.b b _.J {.G 1 c.u { ].y + ' _.) _.Q {.[.{.b [.[.e S <./.<.M b ,.J e e e Q >.<.<.<.0 e e e e ,.J ' . # * = = = = = % @ . _.) ' @ - 5.8 4 G - ,.7.M %.R l f z z h ! z h f ; y ! ! Z ).M $.b R f v @ $ ! z k 0 C } u &.S ",
+"J b $ > v ,.b [.J ) J b y $ ~ y _._._.) ' [.,.J b K J _.> { e.u 1 P ) J + 7.J _.|._.) |.b  .<.<.<.;.0 J J e e e C <.<.<.<.$.e e e Q ,.[.) @ % N * * * ; = # . . _.[.[.% H *.*.G A = 7.N 1 O $ }.0 c h $.! z h $ Q K v Q { u t Z @ $.h $ @ h h k k ! 0 &.u 2.2.",
+",._.V x J b _.) J J b b ' @ ' _.|.i.' y ) b ,.) c b c K _.J ) (.k ` } r ` @ m Q (.|.J ' ,.+ }.<.;.<.;.}.[ / [ #.<./.;.<.%.v e e e e ,._.(.+ $ * * = * * * N # . y ,..  .j G 9 G P @ K 2.t 2.; &.y c j ; b y N 7.Q e N c r Y o j c f ! @ $ ! i ! ].$.} %.%.&.Z ",
+"a - V |.|.y ) b J y b _.$ y Q y J ' a ' ) {.J ) _._.. m {.. y c $ 7 [ '.` ,.7.x ,._.J b b e 7 <.<.;.<.<.<.<./.<././.<.t 0 e Q e e Q |.J ) . % * % * = * * * @ . _.{.= G 9 :.G G ` $.b =.t Z @ #.j J K Q Q y $ Q e c b h #.L T z y h ].J N o z $ $ k X %.^.Z s ",
+"@ - , m |._.(.J J |.' = a J J b ' V a ) (.' ) ) . ) J _.a $.2 #.: 0 @ e _._.+ m |.(.) {.+ J ,.{ <./.<./.;.<.<.<.<.<.a.{ e e J e e e |._.' v $ & * * = = * * @ ' J @  .G j :.9 9 d y 2.^.s j R %.! 7.K K c 7.J e e Q z Q 0 [ %.=.J f ~ K N $ i ! i 0 u }.%.S #.",
+"m ) @ $ y |.b _.|.a $ a ' b b x @ + y J y . x (.) ; A u c.=.f c _.' {.Q b e c ) x Q ) b |.. e b n [ ^.t <./.d.a.#._ k Q e Q e Q e Q ,.m ) @ $ * & = * ; = @ @ . # D n j j G 9 G A > f }.L U y [ k c K b b y @ c Q e 7.O t [ f N v i ! a N N v i o 1 } !.#.Z '.",
+"Q e ) = , _.b b @ - a Q J ) a W y ) J b ) (.(.x (.d.d./ 1 2 O X X =.C Y 7 ) Q J x b ' J Q ' ' c 7.y ) _.% - , . J {.e e Q b e Q e Q ,.[.' @ $ * = = = ; * N * = E g n F 9 *.G G P Q R [ !.0 j O b 7.@ y Q e Q Q e e $ $ T %.u h N f ' $ h K ].; ; O &.#.%.| #.",
+"J Q Q ' , $ ' y w _.' i.e $ H @ b J J J _.J _.' ' V J (.' _.. ' c K J e e e Q Q [.x (.[.) b c J J Q b J e Q Q e m ) _.m b e Q Q Q e |.J ) @ $ & & ; * ; * = > E P o o j 9 G G G # J 0 !.U #.y &.z @ $ b e Q J e e J c j | O | Q @ ! $ . N K z i e C u %.}.[ }.",
+"Q J Q Q x $ $ - y _.b b $ D @ Q [._.) ) (.J b y a a x (.' ' ) _.c K c Q Q e e e b ) ' ) {., [ s *.) _.' |.) ) ' ' |. .u '.% e e Q Q |.[.) @ $ & $ = ; * * > o j H E n F 8 :.A j 9 J ; T }.8 h 0 $ Q ,.b J Q b J Q e k [ %.n J 7.! d @ ) a {.z N i O =.| M =.}.",
+"{.Q ,.,.Q x w $ b _.b y = v b y ) J {.) ) J J J i.$ $ x (.. ' _.' y c J e e e e e |.x . J ( /.<.d.k Q a y ' . ' ' + './.;._ e e e Q |.{.. x @ = = = & $ > o P o o o o 8 G 9 G G { $ j 0 8 n # t z Q ; $.y J a a K e k &.[ $ J _.! N K ; a K k ! o [ 1 X 0 j X ",
+"b |.,.|.e [.$ _.m b y $ @ (.) b ) J ) J b _.' i.J i.V V (.' ' ' ) y J Q e e e Q e Q _.) J _ <.<.;.f Q . ) ' . . . ~ j.<.<.[ e b e Q b ) ' V % = = & ; ; E 8 n o E o n 8 G 9 9 G o ' 0 %.L X =.j @ e $ ! m J $ ! ) b h s 0 @ e c ].$ y N @ z h b o X { | u Z | ",
+"{.b ,.Q Q Q b Q y , , ' y _.b _._.J J ) ' $ = = i.J y v @ v a ) . ' c Q e e e e e e Q |.m : <.<.<.d ,.' ' . v v @ + j.<.<.} m y b 7.Q _.) @ = & $ = 3.o 8 8 n o o o g P :.~.G G ] N z T ).=.Q }.a e $ ].y y $ ].y 7.l '.| K Q Q h ].' c Q @ ; b k Y C 2.r r 2.",
+"{.{.b b b |.|.|.' 3.- _._.J b y _.) b y , @ i., $ _.J _.' @ v J ) ) _.e e e e e e e e e Q 2.<.<.<.d 7.) ' v + @ @ @ j.<.<.B m ' @ {.Q _.' v $ & = 3.o 8 F n o o o o n P G 9 G G  .$ | u u z =.Y N b K v J J y $ K e R } f Q e K N z % @ J @ N e j 2.| 2.1 Y =.",
+",.,.b b J b |.b |.(., * y _.K J _._.' V $ ) b J = $ ' _._.$ , a ' x ) |.e Q Q e e e e e e S <.<.<.d 7.) ' a + @ v @ c.<.<.} b ' ; % ) {.(.v $ = 3.o :.F n P 8 n H H n j :.9 9 G { @ E !.;.| J }.J e a z K c Q b e Q 1 }.8 e e ) k N K c Q $ $ y O [ | 1 M | >.",
+"m ,.m b b {.|.{.Q Q ' = , _.J _.J _.= = ) _.a b v V x J J K $ $ a ' ) |.e e e Q e e Q e e 1 <.<./.d 7.) x v x @ @ @ j.<./.} ,.K N > * _._.x $ > R 8 F R o 8 R d o o o P G 9 G G E _.{ X =.; =.` c b $ z y b Q c b K Y q K e e ].h a y c J N @ K C r Y X X =.*.",
+"b |.m ,.|.m |.b Q m m ' - @ b i._.K $ ' |.J (.b J ' v @ K _.i.- & % V ' ,.e e e e e Q e e 1 <.<.<.d 7._.' . . @ @ @ }.<.<.} ,.. + W D # i.v ; 3...P R R 8 8 P o E o n j :.G 9 G D y 0 s %.1 a #.b Q N z c Q e b e b [ C $ e J K $ c y J b ; $ K >.1 { >.O O 0 ",
+"m |._.{.|.c J b b |.) a V ! - J ~ * ' b i.) J x ) ; o 0.3.i.v +.>.*.:.n - J e e e e Q e e 2.<./.<.o Q ) ' x . @ + + j.<./.} ,.. , z i  .= ,  .R -.o R P F R R R H o o P :.9 G G E b ; &.#.0 l k c Q $ N c b J K Q z [ | e Q Q ~ $ c ) b J i N y =.[ C 0 0 0 0 ",
+",.,.b ,.b b b b c J J J y K * -.v ' J J _.x x [.[.e.d o 3 _.| g.5 :.F F c.~ c e e e e e e | <.<.<.i y . J @ x a v @ j.<.<.} Q . # W W D o R H o o R ..R R n R o o E n G G G 9 j ' _.7 1 &.>.h }.e K N J Q e e Q Q K T h Q e _.$ @ a v c b N $ k 1 | O =.| Y C ",
+",.,.,.b J J b b c Q [.) J @ > , J b J v a J J x . X + _.) J | 9.$ _.7.J ] x . b e e e e e 1 <.<.<.n e N % J v @ ' . #.<.;.[ m ' ~ ; ; > H o H o o R R R 8 n n o f g n n 8 A G @.@ 7.j !.L X ; f a . $ J Q e Q y Q { &.! e b b . ) ' a J b ; ; f | Y 0 O C O O ",
+"b b {.m b b J J b ) J Q y * ~ i._._.' $ @ ) J ) # '.` ] ^ ^ j.$.b 3 H :.q ; e {.Q Q e e e | <.<./.f e ) - , . . ~ . c.<.<.} |.' ~ ; ; W 5.H 3 ..o o R P R R o o H o n j 9 9 H # $.y ! C r f $.&.J K ! ' Q m a ) e D | _.e e ) $ K y y b b k $ $ C X 0 O | C 0 ",
+",.,.,.,.m b b m J @ ) J = , _.b ,.v $ x _.y i.J J  .j n 3 0.H _.y i 8 ~.8 (.(.[.|.Q e e e 1 <.<./.$.e e ' D ~ . ~ $ T <.<.} Q . ~ ; W ; i 3 E R o o o n n n n o g E o A G  .N @ ,.y =.L s ! n r k J J b Q e y $ b M j Q e Q a v c c y Q y 8 ; @ >.O 0 X 1 C { ",
+"b b ,.{.b m J b J ,.. = V y J b ) & w $ J b _.y J J = $ ) _.J ) b v $ x J V W J _.[.Q e e 1 <.<.<.o e Q e (.- , . ~ j././.} {.. $ - W D i 3 H o R R R R n R n n o d o j H # (.@ f Q N &.!.! $.[ @ J c Q Q J c e h '.> ,.Q Q $ y b c c e e k @ v 0 C Y Z S 0 O ",
+",.b ,.b b b J J b J ' $ ' Q J $ W % $ > = i.J _.b ' b $ , [.v Q (.& J 7.b i.K , a (.,.e e 1 <.<.<.D e Q e Q ) z z K T <./.[ {.) $ - D D i 3 H H o R R R 8 R o o E n E = V x . @ J K =.T X c { U e.n y e Q Q 7.b 0 0 K e Q e % y b c c Q v j N z l 0 | }.u j j ",
+",.b ,.b b J b b {.) {.b ) _.y W $ J ,.' - - K _.K J b ) $ V b ' @ J y a b Q J V , @ J 7.e 1 <.<.<.o e e Q |.e (.].].U <.<.} |.' $ - W D  .3 H o o o R P n n n R f E = ' (.v V v Q b >.}.}.N $.u &.&./ - m e c N M S Q Q Q J ' Q b b Q e ! 0 $ $ *.O | !.u h y ",
+",.b b {.b m J b J Q ,.[.[.& w @ Q b |.,.' w - i.b +.^ h.h.*.& ) (.' J ,.J _.b J - $ _.7.e 1 <.<.<.M m e Q e Q e ' 0 <./.;.r |.. , - W > i 3 H o o o o R R R o n 8 ; J _.V V ' x . _.{ 2.R e >.'.&.&.C N J e e K #.i e e e b _.b b J b e ; j K $ l X 1 s [ $ Q ",
+"|.b ,.,.b b b J [._.{.Q x - # |.J m ,.Q b a * > b ! R R ..W ; y ) J (._.Q v Q b _.- = b Q Y <./.<.<.1 ) e e e _.S <.<.;.<.2 Q . $ = D 3.i  .H H R n P 8 n R n n ; J _.' @ x (.W % b l X v e $ o 1 s S h Q Q Q 0 }.j J e Q ) c e b J e e $ o y h =.C =.u &.c e ",
+",.b ,.{.m m b b |.,.{.|.b ) m Q |.b ,.b ,._.v * = ,._.i.i._.(.' _.J y _.J 7.K J ,.v = D |.i t <.;.<.<.%.7 e D T <.;.<.<.t l e ' ~ , W D D  .H o H R o R 8 j H D _.7.) . x v & 8 * ,.b ) 7.K v Q Q K N e ,.,.y 1 O a Q Q e c m Q Q a J e h R e ; R 0 Y } u $.e ",
+"b b {.,.b b m m ,.J [.J b |.|.|.|.|.b m b |.J x - * v J J ) x (.(.. {.Q _.Q _.J _.b ' $ + _.d #.<./.;.<.<.f.t <.;.<./.t C m ) ~ , - W D 5. .H o R o R n j o ; ) [.,._._.v D :./ ' ) _.J y N ) m b c e b y e $.r l ,.Q J b K b Q b b b Q $ h e z j O 1 u u | { ",
+"b ,.,.b b ,.,.b [.J _._.J b b [.,.|.|.,.b ,.|.,.& , $ @ ' _.b (.J . ' v ,._.Q _._.,.J J > = 7.' 0 L <././.<.<./.<.;.[ N e a ' ' $ z ; W 3. .3 o +.o R 8 o = ) ,.{.Q {.) w A C C D N b y f j @ ,.J e ) ,.e ) j }.8 J e Q ,._.e e c e e J ].z J n >.8 R 0 f l [ ",
+"b b b b b m J {.,.m b b m m m b b ,.,.,.b m ,.|.|.H : b.Z Z h.^ j.c.[ p i.b _.b b J J Q m > > e b } /.<.<.<.<.<./.#.; e e c > , = ; W D 3. .H o o o n 8 3.. J ) {.7.J > G ^ ] A ] p . k Y [ Y k m c Q c 1 { } 0 @ Q e b J e e Q Q b e b o z e R d y . ! $ b e ",
+"b {.,.m b b b J ,.J _.,.,.m m ,.|.J _.b |.J J m ) _ 8 > * ' (.y _.b v g.q ) Q b {.) (.' [.m ; *.^./.<.<.<.<././.<.<.%.>.Q e z $.- ; W D 3.3 H o o 8 n @.# (.) ' J Q % :.g.=.4.A j p ' n Y C S g b ! Q % =.u | 0 Q Q e c y e e J Q Q e J d N b z J e e c O r j ",
+"{.b b b ,.m J b {.[.c _.m {._.J |.b m J b J J J m | y V 3 x y ' x $ b J ^ b ) ,._.b |.b ) ) 7 <.<.<.<.<.<.;.<.<././.<./.M 7.7.$ W W W W i 3 H o o R 5.$ x (.) J 7.) H =.g.4 *.9 0 n + n Y X P ,.k n z ! r Y S ~ Q Q Q b m e e e b e Q z k @ z v Q e b v @ y z ",
+",.b b m ,.b m m J b ,.m m J J _._.,.,.J J c J J _.] ^ ^ ^ [ C ^ C C ^ ` 2 J b _.[.b {.+ e H d./.<.<.t U { @ n T <././.<.<.o 7.Q D > D D i 3 H o o > v ) ' x (.{.(.D A 1.9 *.1.5 ; ' @ N O s j [.y K b *.S M X Q Q e J Q e e e Q e e b h f b y _.e y =.{ ].e Q ",
+"b ,.,.b m b b b m m m m m J J J J J J J _.J m b # @ y _._.@ 3.- a _.y b _.7.) |._.J [.[.Q _ <.<.<.;.n e b Q e e o }.<./.<.S Q e e .  . .>  .H H # v (.v v ) _.# o 4.9 8 9 j 9 { n ' @ ] 1 H $ > a ) P O j } f c Q Q |.b Q e e Q e Q e v N ) N e $ k { D e e e ",
+",.,.,.,.m b m m m m m _.[.J J _.c J c c _.b ) @ + ) J K i._., k ~ v _._.|.{.b ,.[.m [.[.Q : <.<./.O {.,.Q e b e e $.%.<.<.r c m e 7.z H E H H D . . x v x ) , H A P j j j O X O Y _ 8 r T D ~ $ @ ; 1 =.[ C a e Q Q |.Q Q e e e Q e e z y ~ z e Q b 1 | y e e ",
+"{.b b m b m b ,.m m m m m J [.J _.J _.c m J . , ' _.b J y _.y ~ > ! i.J b [.,.J [.J ) ) Q _ <.<.<. .e $ * {.7.e Q b #.<.<.r ) $ [.7._.D I E > @ ' . x ' ) , o A A n 8 P 7 A p O ( 1 : q p ' $ , - j l g 2.*.J |.e ,.|.|.Q Q Q Q ,.e ,.@ c y *.Q e > O } j e e ",
+"b b ,.b m m m m m m m J m J J J m c _.m _.+ ~ v {.y v x ' y J _.* 3.V Q @.Q |.[.[.{.[.) Q : <.<.<.$.e @  .; J x ~ ) #.<.<.} 7.$ ; ' 7._.; > @ (.. @ x ) @ o A *.F o n j A l P 0 S ` : l @ ~ % i n S j =./ ].b Q Q Q Q |.Q e e Q e e z h e ! j N b ! 0 2.{ . e ",
+",.,.,.b ,.b m b m m m m J [.J J [.) _.,.(.@ + [.. {.m _.) y ' (._.= w @ '.|.J |.J J [.[.Q _ <.<.<. .Q [.+ o  .= + @ j.<.<.} e . > = _.7.' % @ ' v (.' # 3.*.5 8 d 3 n 7 n P 1.0 Y Y | P . N D ' p 0 *.r X Q b e Q Q Q Q Q Q Q e Q m @ K J @ p J e e n r l Q e ",
+",.b ,.m m m m m m m m J m [._.J _.{.{.) ' ' ) ) m x ' ) ) x @ (.J x & N ^.e b ) J J [.[.Q : <.<.<.H Q b a H 3 = + @ j.<./.[ ) ' N ; ; + |._.# ' (.' = o 9 p F o H H o 7 n = P Y O C Y ` j =.e.X 0 I 0 2.i b ,.b b |.Q Q Q Q Q Q Q e Q b Q g k K h 0 0 2.X ' e ",
+"b b b ,.,.,.b m m m m m J J m J ) J [.) ) {.J ) ) { ^ 2 2 h.( ^ ( ^ / ^ %.* ) Q J J _.) Q _ <.<./.n 7.J , - V @ (.x s <.<.} ) ) @ ;  .@.V ) v (.x = o A A F o n H n H G G # @ O ` Y S 1 } } / _ 0 =.[ Y J ) e ,.b Q e e Q Q Q e e Q J Q ,.e _.e e I 7 l | j e ",
+",.b ,.m m m b m m m m J m _._.J ) _.J J J J ) ) ) F o o G H ..:.A F  .3 :.* a (.J J J [.Q 2.<.<./.o e # = x x v # & }.<.<.} [.~ @ z ; I  .$ ' v $ R 5 { G o H n o H n j G @.# @.Y 4./ S 7 o { Y 0 O S h K Q J e b |.Q e e Q Q e Q ,.a N a c e Q e Q @ N c Q b ",
+",.,.m ,.,.b b m m m m m m m m J J J c _._.) _.[._.. ) ) (.) a |.J ,.|.,.Q . - ' |.J ) J Q : <.<.<.H b @ v ' (.@ W D U <.<.} b , > ; ; = o R % ' R *.5 j R n 8 o H o F 9 { n . $ 0 { 7 j j ` 0 P 0 | 0 @ b b ,.,.Q Q Q Q |.Q Q Q e c . ].~ e Q Q e e $ i y c ].",
+",.,.b m {.m b ,.b b b m m m [.J _.J _._.J c _.) b ) ' ) ) ) _.(.[.) b Q e 7.+ ; a J J ) e _ <.<.<.o J (.(.a V $ & ; }.<.<.[ Q @ > > D >  .R H H F :.:.8 P o R R H n j G 2 Y P D j l j *.{ { j n 0 1 O N b ,.Q ,.b ,.|.Q Q Q Q e Q Q ) h ! J Q b e Q y z . _.$ ",
+"m ,.b ,.,.m b m m b b m m _.m [.J J J J c _.) [.' ) (.x _.(.y v ' . ,.Q ,.e e ) - ' _.[.e : <./.<.n |.[.) V = & x # j.<.<.B b ~ ; -  .D ; 3 o :.7 8 n P R R o n o 3 P 9 A G G C j 0 0 O O 7 f P 0 Y 7 $ ,.Q b J Q Q Q Q Q Q e Q Q e v f $.v Q e Q e e y ! ! a ",
+",.,.m m b m m b m m m m m m J J _.J _._._._._.) ,.b @ :.F D y ) + [.' o 7 ) e |.v * v |.7.: <.<.<.d 7.[.+ = = # . @ #.<.<.} Q . > ;  .E 3. .H F ~.P o R R R o o H P 9 d E 7 { 0 p 1.O 4.p j o G Y O $.y b Q Q Q b ,.|.Q Q Q Q e Q e _.J e e e Q Q e e e ,.@ @ ",
+"m ,.,.,.b m m m m m b m m J m [._._.J _._._.) _.) } ^ o P : S 0./ q '.2 $.b e e Q $ , x |._ <.<.<.I e v & % @ v + @ #.<.<.r [.~ D - W  .H H 5.R +.6 F P R n 8 o 8 :.1.` 1.` =.0 =.1.0 0 7 G 0 O X R a Q ,.m Q Q Q Q Q |.Q Q Q Q e b v _.e e e e e e ,.e e _.].",
+"{.,.b b b ,.m b b m m m m m m m [._.J _._._._.) (.7 m _.' |.; q W + _._.c e e Q e ,.@ = ) _ /.<.<.I Q $ , . x + . + s <.<.&.K z - N = 3 8 R 5.H n 6 :.+.R R P o o 9 / ^ 0 { =.O 2 { A l o  .j =.n N b Q J m b m b |.Q Q |.Q Q Q Q J y Q e e e Q e e e e Q e b ",
+",.,.b b b m b m m b b m m J m m [._.[.[._.[.[.J ) 1 n o o o P } R R P o d c e e e e b # v [ /.<./.g [.@ v . . + ~ @ s <.<.r c @ ~ =  .o 8 :.F -.o n :.:.F P R R F R ` q B 1.7 =.{ 0 G h @ J * d ! y Q c c b b Q Q Q |.|.Q Q Q e Q _.J e e e e Q e e e e e e e ",
+"m ,.b b b b b b m b ,.{.m m m m [.[._._._.) _._.|.j I P d P I l j F n I o K Q e Q Q e Q @ b.<././.n J ) ) . @ + . + #.<.<.} J . ~ = 3 3 w H :.o R H R :.:.o o P :.F 7 *.G 0 ^ _ ` O o y _.J ' % @ J b _.[.b _.m ,.Q Q Q Q Q Q Q e a ) e Q e e e b e e e e Q ,.",
+"Q b b b {.{.b ,.|.J @ @ {.|.) ) J J J _._.c c _._.. {.J J ' b |.' , ' J ) [.' ' 7.7.Q 7.|.C <.;.t z Q ' ' a x @ @ ~ [ <./.` Q . = ..F D D H H F R ..o R F 6 0.o H H o P 9 C A C | 0 z J b N  .j D & y ) ' |.|.(.|.m |.Q Q Q e Q {.' b e e e e e e e e e e e e ",
+"b ,.b J J J m ,.b & W v J {.[.m J J J c J c c _.) |.' ) J _.J b Q . @ b Q {.) (.J |.|.7.e a | u n Q Q ) . v v ~ ' x H } : - Q ' i H 8 3 w 3.H R 8 R P R 8 0.R o E o ..4 ] *.# . y J y $ 8 p S F > W = i W y m Q Q ,.,.|.Q Q e e b c Q e e e e e e e e e e e Q ",
+"m Q b J J b ,.J v D > K J ) [.{._.c c J _.) ) ) ) [.) b . . J + ) ) + ~ 7.|.{.V x b 7.|.,.e e b b Q ' x a a a ' , , ; x {.) (.D w =  .o  .5.3 o F F P P R R 0.0.6  .+.{ H v b ,.b J b >.=.C *.! x ; - i 5.5.3 y Q b b |.e e Q e b J e e Q e e e e e e e e e Q ",
+"J Q Q b b Q b (.D - x J y x ) [.[.J [._.J c c c b > $.j k E j E o f $.n z _.Q b $ v b 7.7.Q z i ! J ) ) (.@ v v v d W ' |.. D $ - $ D 8 8 8 8 P o R 8 8 0.P F j F H :.*., |.) _._.b J k 1 O W x m # @ $ W F A ..' b Q ,.e e b Q J Q e e Q e e e e e e e e e e ",
+",.,.,.,.Q b y % ; (.,.J ) (.x ) ) ) _._.[.J c c a u d o P j d o j f f P _ ) Q b _.a @ b 7.p t /.j.- . @ ' (.' $ D D . ~ , $ D = , = i ..8 o o o H o P P ....+.6 3 *.F W $ ) b {.,.Q b m p _ - _.(.(.. (.$ ; D p ; ) Q |.Q e Q b _.Q e Q Q e e e e e e e e e e ",
+"|.,.b m J . # = ) b J J ,.J . (.(.y ) [._.J c c 7.1 K y ) . ' _.,.. . e | b @ b {.J @ ' J | <.;.<.D . = $ a @ W = (.@ ; D ; + , , D D  . .i 5.o o R P P P 0.+.F G R ; J m b b ) _._.c J z 1 $ ) ) ) x ) , W v i i . Q |.b e Q b J e e e e e e e e e e e e e e ",
+",.,.,.b . # $ . |.J _._.J {.) ) x ' (.) _._._.c a u Y C X 9 $.j j f R 0 '.c b @ J 7.) (.) _ <./.<.D b @ , $ a @ ' , , D - @ W $ D  .i D i @.o o o R R P +.P F 6 :.x b J x x ) [.J 7.) Q . D N . ' . . ) i p i v D $ J Q ,.Q Q b Q e Q e e e e e e e e e e e e ",
+"m ,.,.,.+ $ x Q J ) b J (.[.{.(.V v a (.(.) ) y J z o o g o o o R R $.o c e ,.) ) ,.J J ) : <.<.<.d e J - ! , y @ $ D W $ - , =  .i ; W 5. .o 3 o o R R +.6 ~.~.) [.# x = $ [.) b ' Q . m @ ) c ' . ) (. .A I ) ; , ' Q ,.Q Q b e e Q e e e e e e e e e e e e ",
+",.,.[.v . (.J b J J J J [.J [.) _.@ V ' ) ' c ,.m @ Q . . ' ' _._.K b b Q e e e $ . _.b Q : <.<.<.I Q _., 3 w ' = W - v $ , W i W - ; i i @.3 P R R P R -.4 6 @ ) @ $ , - ; = ; % b [.b ) (.' . ) @ ' J I p ; $ + . m ,.Q Q e e Q e J K Q e e e e e e e e e e ",
+"|.m ) x (._.J J J J J J [._.J J J _.v V v ' ) [.) |.a ,.) _.@ ' y ' y 7.e e Q e |.' + ) 7.2.<.<.<.$.Q v a ~ - 3 , $ , @ $ = W W ; - ; i  .E 3 H R -.o P 6 7 ..a b |.) v @ - D D i @ [.) W = @ ' ) ' ' K H 9 ~ ~ , . |.e e e b % $.$ d ! e Q e e e e e e e e e ",
+"|.[.(.) J J J _.J J J J J [.[._._._.) @ , # (.) ) J ) _._.' b J ' J y b e Q e e e |.) . J _ <.<.<.H b a y (.! ..= @ @ $ $ - ; $ , ; D i H R o 3 R H 0.>.5 5 P 5.' Q Q [._.~ = # D ; ) . I - ' ' v @ y + d G $ v ; ' ) J {.. ! d k $ j d e e e Q e e e e Q e e ",
+"b [.J b b _.J b J J J [._._.[.J J _._.y V = , ' ' I ' ) _.' y . K ) c Q Q e Q e Q e 7.' ' [ /.<.<.n Q m ' - D - W $ ~ ~ , = - $ = D i i 3 P 8 o H R 9 5 ~.+.....w ' ,.b J ' . J ; w @ i :.$ ' @ K @ y _.> P ~ J m e J ,.b > g k J b ! n @ e b y e e e e e e e ",
+"J [._.b b _._.b J J J [.[.) _._.) y J J ' $ , $ a h.Z } '.Y { d J @ c 7.b e e e Q e e 7.b } <./.<.d Q ) = 5.= ' = = $ $ z = $ = - D  .w i H F 8 R 7 5 :.0...o R  ., ) ,.J ) v $ W W , 0.{ = @ . v N K _.D j $ b b |.J e b ].$ Q e Q c i k J e Q e e e e e e e ",
+",.[.) _.b J _._.J J J J J _.[._.) J J _._._.a - $ $ @ b ) % d O Y _ X C 0 b e e Q e Q 7.7.2.<.<.<.I Q $ ; , x @ v $ + @ , , ~ ; - W i > > 3.o 8 9 A *.P o 0.R H i ; ~ ) [.c N 3 $ - - :.4.$ . y @ z v v E l z J m _.Q ,., ~ b Q K J b K k h e e e e Q e e e e ",
+"|.b ) i.i.J b J J J [.[.[._.J [.) m _.y _.b ' , $ = a @ ' d j X / Y Y Y 0 J e e e e e ,.e 1 ;.<.<.d b $ $ (.' ; @ + @ ~ z , = ; ; W W D 3.5.H 8 4 *.F o H o ..H D ; , @ y ' ; H @ i 3 *.4.= @ v K N ' ' i 7 - ,.|.b e z $.' e J J Q e e a ! c e e b J Q e e e ",
+",.,.J (.i.i.J b J J J [.[.) [.) J [.) _._._.i.i.> q j.S 2 *.n ) ' ) ' 7.Q e Q Q e 7.e e e M <.;./.j J ) ) x @ = ; ~ ~ ~ ~ $ ! D D W D H H 3 3 ..:.F :.:.8 F *.{ ; % - ! + @ > i @ o ..9 { D @ ' $ i N ' @.{ $._.m Q ' P g {.Q Q e J e e Q y N c e b y J Q e e ",
+"Q b b ,.) x i.J J J J J [.[.[.[.[.) [.[._._.J J _.5 h.| : ^ ( ^ A n c J e e e e e e Q e e 1 <.<.<.d Q (.$ ; $ a W W $ $ - W i - $ - W D o R 3 R 3 P F +.:.A 9 H % - > ; . . d W W P I H 4.j = ' ' g g y ' P j ~ m ,.].i ~ m e Q e e e e e b J b e Q a @ Q e Q ",
+"b b b b ,._.(.K b J _.y [.b b ) [.) ) ) ) _._._.' m - w $ @ $ J  .E s T T Q Q e e e Q e e S <.<.<.o Q x $ = @ ' @ ; H @ , H , @ - i 3.3.0.4 P H ....P 4 g.4 o W W $ W ' ,.%  .i - o 4.7 { 0 N ' @ 8 G = . D P o . . k h Q e b J Q e e e e Q Q e e Q v N c e e ",
+"b b b Q Q b ) v J J J ) _.J m ) ) [.J [._.) ) ) J y $ 7 ^ S '.^ < X O f b e e e Q e e e e S <.<.<.o Q ) @ , + v @ @ D H = ; 3 , = ; 3.H :.F 3 H H ..5 ^ 4.F H i > = ) . ' ) o - . j Y ` ^ A # @ @ h E ].) . i j - z h a e Q _.b b J Q e e e e e e Q @ ! a e e ",
+"Q Q b J b Q {.(.V ' b ,.J ) J J ) ) ) _._._._.J @ q | { h.w , V $ ) ,.m e J b e ,.e e e e _ <.<.<.o e _.. ~ @ $ ' , x D H = W o = ; 5.0.:.o 5.o o 4 ^ { R o R H W ' _.' . . > D ' p ` ] ^ o @ . x @ $ N ) J # D k D $ ,.,.b 7.b J J Q e e e e e e Q a i N b e ",
+"b Q b J J ,.,.,.% v y J b ) ) b _.) J _.[.[._._.Q ' a J y w w @ - _.x Q Q e e Q e e Q Q |.: <.<.<.d e m ' @ @ = @ a $ v W i $ D D 5.i  .H o o o *.5 *.0.o P 0.i . ,.J ' @ ) % * ' H p X A % ' # # @ . . K ) _.) N i ].v v ' m ,.Q e e e e e e e e e a k z Q Q ",
+"c Q Q Q b b ,.Q _.. $ V J b J _.J ) ) ) ) _._._.y y J y ' x & W $ $ v b Q Q e e e 7.[.) _.M <./.<.o Q ) x . . $ W ' $ , . W  ., i 5.w D w 5.P ~.4 :.o o F P i # # = . * = b % ) ) . p 1 G * . N # # @ ' y ) _.{._.N W W N ].! K b e e e e e e e e e y i N e Q ",
+"b b b Q b b b b ,.[.@ $ v b b ) _._.J _._.) ) _.) ) J V ) Q = w k - $ b |.e {.) e b (.) _._ <.<.<.o Q ' . x a $ , D a $ = ~ D D 5.i D 5. .3 :.{ R o o :.j i z D o > D D > @ ) # @ ) o 1.o * @ @ . @ @ ' ) _._._.' ' y v @ z f > K c b Q e e e e e e c ; @ e e ",
+"7.,.b Q b J b Q b e {.$ , i.J _.) ) ) ) _.J ) _._.J x b _.x ,.a ! w $ $ |.{.) b ,.) . ) ,.1 /.<.<.o e _.' ' v - $ = D , @ = $ - ; W = - i 0.*.6 o 0.0.F 3 @ ; 0 > ; W p A ~ ' ' # # ' W ].' N @ @ @ @ . ' ) _.J J y b K $ K N ! $ a K y J e e e e e {.z @ e Q ",
+",.b b J b b J J ,.,.,.J V = v Q _.J J ) _.) ) _.J x J ) x _.' ) ' ! k a b _.b {._.) J ,.Q 2./.<.<. .|.x (., W v , $ = W , $ = = ; ; W  .3 D 5.F ..H 0.F > (.+ H i D D  .E ; . ) . # * N V @ @ N # $ # @ # $ ' Q b J J J Q ,.c ' N z $ K y K J e e e b b Q e e ",
+",.{.b b b b b b J J ,.,.) V , v ,.J y i.J J ) _.b ) _.y (.[.y y i.@ w ! y m b J _.J J ) ) [ <.<.<.P e b ; W . v a , = - D ; $ = , - > i & [.+ o 0.o R :.o = ' _.d  .N y * @.; ) ' ) @ = ; N @ % @ # . . @ N , % J _.J J b Q Q Q Q a z N @ K c b e e Q e e e e ",
+",.,.,.b m b b m _.J ,.,.b ' V = K i.J J _._.J ) y b ) ) ) _.J y _.J @ w = V _.b J J {.' . r <.<./.j {.) ~ W , (.$ = $ = i D = , - ; , x {.b y , o R 0.0.8 o = J @ + . + W H $.= ' . @ N - = = N % # @ ' ' + N ! % a ) J Q Q 7.e e Q b c $ ].a e e e e e e e e ",
+",.,.b b {.m b b m J J J Q ,.) V > $ J b _.) J (.i.J _.y v x ) (._.$ a y , D , b J b b _.) [ <.<.<.$._.$ (.~ D , , , , = ; D i ; ! % c Q |.. ' _.= o :.0.0.:.8 D Q Q # E o  .@.E # + + @ % * ; ; = * # @ ' _.) @ z N @ a ) c ,.Q Q e e e b c b e e e e e e e e ",
+",.,.b b b m m m J ,.b J {.Q Q J = * v J J _._.) J v _.[.) _.(.J ' 3.! b . * W b J J J b Q M <.<.<.I Q $ , v v i v @ W - $ - i i % c e ,.) [.(.v _.= H P P F 8 ..% J ' k H k  .H # + + & N + # ; z # @ @ . ) ) ) _.a N ].z a c J e |.Q e e e e e e e e e e e e ",
+"b ,.b b b b m ,._.J J J _.{.,.{.b , - v J _.y _.) H y J J |.i W , ' $ , H ' , ) J ) (.{.e : <.<.<.o e ) = - + $ @ = = , = , v $ y Q e b _.[.' + (.y $ o :.+.o R o % J ' i P d = + - W $ + ~ N # * # @ @ @ ' ' ' ,.) a @ a . K a K c Q e e e e e e e e e e e e ",
+",.,.,.,.b m ,.J b b b J J b b J 7.i.- * ' _._.) x g.x ) . ) 2 1.$ Q _.& ^ v . ) b J ) _.Q M <.<.<.o |.) ' ; - (.= = $ $ = + |.e Q e e Q b ' . ) V (.' = o P +.P P E N . = d  .N @.o E * . N * @ = * N # @ ' ) ) _.J J b b J y . @ K J Q e e e e e e e e e e e ",
+"b ,.,.,.,.m b J ,.b J J J J b ,.J ,.@ 3.; (.J y J ^ ) J x J 1 4.) v ) 7.1 = a b J b {.m e _ <.<.<.d e ) ' v @ , , @ , = x b Q e Q e e J J J ' v + $ V ' & o +...H P H ; # @ > o 4.G o H > # @ * # % N % + ' c _._.[.J J b ,.7.e J Q e e Q e e e e e e e e e e ",
+",.,.b b b b {.b b b b b J J J J ,.{.|._.; D V J _.L ^.u j.j.%.%.c.j.}.j.^.' $ = b ,.b b e 2.<./.<.d Q ) (.(.. @ , = ~ ) Q e Q e e e Q m _.) . . # $ $ # v @ D P H H F G H & &  .p 9 1.1.H % % = & $ * = * . ) ) _.J J J m b b Q Q Q e Q Q Q e e e e e e e e e ",
+",.,.,.b m b J J J J J b J J J b J J ) J (.; D V b K b @ ' J . ) ' @ ' Q ' 7.V = _._.J (.' r <.<.<.H Q . . x x @ @ $ . |.e e Q e e e Q b J ) ' ' ' . ' ' ) [.(.+ % N * = ; % + + o 9 A j o P o * & $ & = = @ ) ) c _.J b b b b Q Q Q Q e e e e e e e e e e e Q ",
+",.,.,.b b J b b b b b J b J J J y m J {.,.x - 3.J i._.{.,.) _.K (.) ' x J ,.|.J > y |.' ~ } ;.<.<.o b v + x ' . @ ~ y e e e Q e e Q Q Q b J _.) ) _.) y ) [.,.b . @ $ # % ; $ [.(.- W , i A ] G i ; # @ . (.) ' [._._.J b Q Q Q Q Q e Q Q e e e e e e e e e e ",
+",.b ,.,.b m m J J J J J J J J J c [.Q ,.{.b (.D > J y x _.) ' c [.' . ) Q ' [.Q v & @ b Q } <./.<.d Q . + + . + @ v ) e e e Q e e Q |.,.b m _._.' ) ) ' ' ) {.|.b K $ % N z * @ J J J y N D n 7 7 8 k = ~ . ) ) J J J J m b b Q Q Q e e Q Q e e e e e e Q e e ",
+"b ,.b b b b b b b b b J b J J J ,.' ' J J ,.J K  .= ) {.. J ' _.(.(.x ) ' Q |.|.Q @ W + e _ <./.<. .e ) @ @ + . . c ,.e e Q e Q Q Q Q Q m _.c ) ' ' ' ) ) (._._.7.J a N z z z z @ _.J @ N @ # ! E $.$.I @.z K _._._._.m b ,.Q Q Q Q Q Q e e e e e e e Q e e e ",
+"b b b J m J J J J J b J J J J J {._.@ % (.b b b V S < =.: ^ } _ | g.] ] { ' Q |.J 7.(.* ' S /.<.<.$.e ) a ' _.|.|.e e e Q Q e Q e e b b m _.y ) ) ' . ' ) ) [.[.J ,.J v * z z N N K _.y a $ # a ) ' a N N # K ) J J J J b ,.,.,.Q Q e Q e e e e e e e Q e e c ",
+"b b b b b b b b b ,.J J b J J J ) ,.(.= V _.b b Q , H D ) x g.P _.x ' b J Q [.m b b b [.{.Z <./.<.d e y _.b e e e e e e e e Q Q Q Q Q Q m [.) y _.) ' ) ) ) J |.b Q Q _.v N N N ].* @ J ,.@ $ c c c _.J _.c c c c _.J b b b Q Q Q Q Q e Q e e e e e e e e J N ",
+",.b b b b J J J J ,.b {.J _.[.[.[.) {.) $ , J ,.i.@ w = ) . ] n _.) ) ) |._.|.Q e _.) |.Q < <.<.<.d e J Q e e Q 7.Q Q Q Q Q Q e Q Q b ,.m m J _.) ' . . + $ ~ @ ) ' ) _.) @ N $ $ N ].@ J ' # ) c c c c c J b ,.J c _.J b b Q ,.Q Q Q e Q e e e e e e e b $ i ",
+"b ,.,.b m b b b b J J J {.{.[._.J ) _.J i.V ~ ' - j.^.'.j.c.j.j.j.'.j.c.'.. Q ~ [.,.|.|.) < <.<./.j e K Q e Q e e e Q e e e 7.b ,.e e Q m ' $ W H H n j G G G j n o o o d E $.E = N % N @ _._.K J c c c b b J b J J J m m b b Q Q e e Q Q Q Q e e e e e y ! k ",
+"b b b b m m b {.J {.b {.J _._.) {._.) ) {.) V % -  ., ) ,.Q Q y (.a _.,.x Q J -  .7.b v _.1 <.<.<.2.c b b J Q e e e e e J b e Q Q m K z k P 9 p 0 A p p *.G G j P P j G 9 9 G 9 1.9 R i = # (.,._.c J c _.b J m b b b b b ,.Q Q e Q b Q e e e e e e e K ! k k ",
+"b b b b b b b b J ,.{.{.) _._.J J {.) ) b b x V ; (._._.b & (.7.J J (.- . ' b i n $ e ) |.H <.<.<./.}.u s T u T T T T T s O c @ ! i o P j 9 j n H 3  .D - & $ $ , , & D  .H F 9 p 2 2 A F o i % ' _.J _.c _.,.b b ,.,.b b Q b ,.e b Q e e e e e e Q a h i i h ",
+"b b b b b J J {.{.,.{._.) ) _._.) b {.) _._.) J V (.(._.Q 3 i J J b @ ; |.7.,.F n 9 [.7.m ) u <.<.<.<.;./.<.<./.<.<.<./.<.q z H d n 0.o D ; @ x |.b J ) y y ) J ,.Q Q ,.J J (.a = o *.A 5 5 4 j D $ [.,.{.J J _.,.,.b ,.b Q Q ,.Q Q e e Q Q e e b N i k h h i ",
+"b b ,.b J ,.{.J ,.J ) ) _.{._.) ) _._._._.(.) {.b # ,.) ,.E P i Q [.* ) e Q , o F o w 7.b Q i U ;.<.<.<.<.<.<./.<.<./.;.<.r @ W E W + J |.b (.@ W D  .o R ......H 3 5. .D = a (.|.J $ i R 9 A 4.0 o = . J ,.b J ,.,.Q Q Q Q Q Q b e e Q Q e e Q ].i k h h i i ",
+"b b b b b b b m J ) ) _.J b J ) ,.) ) b ,.b _.) . p v [.Q D j 0.; ' ) 7.{.Q i 8 :.o R . Q e e z S }.;.;./.;.;.;././.<.<.<.} + x J Q 7.J @ > o :.~.~.*.*.*.~.:.F R 0.F 9 *.9 F 8 D $ ' (.v , 3 *.1.A G E * ) |.7.b b ,.,.,.,.Q Q b e Q Q e e Q y k i i i k i i ",
+"b b b b b J b b ) _.) _.J J J J ) ) {.Q ,.Q b ' ) < n E E 1./ C : 0  .I 3 ) 3 F H F 0.D ,.J y e e c $ @ ; $ N $ k h D k  .$ e |.Q (.- o :.~.:.:.:.:.:.6 F F +.P F n 8 :.9 9 9 9 9 F n o W @ v # E 8 :.F o D # ) {.b ,.Q Q Q Q b Q Q e Q e e K ! h i i k i h h ",
+"b b b b ,.b b ,.. ) J J ) ) _.b , @ _._.V y ,.) ) } n E d 1./ : ^ ( :.o w @ F P ..o o  .b Q Q c |.e b y $ @ ! ; @ K ) {.e 7.|.a w H F F R R F ~.:.:.~.7 ~.:.6 8 R o n :.9 9 :.:.:.:.j :.j R  .W # ;  .o P F H ; J {.,.|.Q Q Q Q ,.Q Q e b K h o h k k h h k k ",
+"b m ,.,.Q J ) x ) J {.i.' b J > V b ,.b $.8 = ,.{.p ' e _.E :.G 0...P - ,.5.~.H R :.= J Q _.J e Q { !.;.;.<.<.;.}.C J e ' W W 3 R -.H ..+.F F F ~.~.~.:.~.:.F +.R 8 F j 9 ~.9 :.j F :.F R o F 9 G H % . w o o o o % ,.Q b Q e m ,.m e |.z I $.k k $.k i i i i ",
+",.m |.Q b x . ) _._.) ' ) ,._.> * i.b ,.> G n  .Q ) 7.[.,. .:.P ~...6 -.~ H :.0.j @ [.7.J _.e ].}.;.<.<./.;.<.<.<.;.U n 3 d H H o o o P +.8 F :.:.:.~.:.:.:.F F ..R +.F ~.~.~.~.:.:.:.:.F ..P :.p A 8 ; @ v ; H 3 o W [.7.,.m Q e e Q ) z $.I i k k k i i i i ",
+"m ,.Q ,.' @ x |.b _.(._._._.@ , ; v ) {.$ j n F 3 x 7.[.(.n :.:.R 6 +.R n R ..:.> Q c Q J 7.* }.<.<.;.<.<.<.<.<.<.<.<.L 0 o H H H -...P 0.+.6 :.~.~.:.~.~.:.F 8 R R 8 :.:.~.:.:.:.F :.~.F P ....j 4.1.:.i $ v $ R 0.E = (.7.e ,.Q 7.) @ ~ ! k k k i i k i h h ",
+"{.Q J . + ) b |.b _.) ,._.$ > = v x ' J ) o o 8 F H D . J 3.R 7 - 3 6 6 ..R -...) ,.Q J Q b : <.;.<.<.t L L U <.<.<.;.<.}.i j 0.o o o ..R 8 6 :.:.:.:.:.:.:.F 8 P P +.:.~.*.~.:.:.F :.~.:.P R ..R :.p 5 4.F - _.$ 3 0.d ; ) Q e b J . ~ . @ ! I k h h k $.i k ",
+"|.b (.+ ' |.Q y ) J ,.,._.$ * , J ) ) ,.b o 8 8 o P :.5.$ $.+...$ ' ..7 o ..R N |.) Q ) Q z t <.<.<.e.d . |.b D j.<./.<.<.F H 0.F P o o P 6 :.:.~.~.:.~.~.:.6 F ..R 8 :.~.~.:.:.:.6 F ~.:.F 8 P R R F 9 5 A 8  .b . i j n ~ b ' ' @ + a . . $ i $.k k k k i i ",
+"{.' . ) ,.b ) a J b b _.v i.,.,.{._.J ,.Q W n R F :.:.R P 6 G +.= ) $ 5.~.F = |.m _.J ) 7.*.<.<.<.#.@ e e m % ~ - r /.<.;.^ % o F +.....0.F :.F :.~.:.:.~.:.F P R P P F ~.7 ~.~.:.6 F ~.~.F F :.+.R P F ~.5 A *. .' b - i K J N . @ + . ~ @ K N k k $.k k i k ",
+". . (.|.,.) x (.J _.J K , $ _.,.J Q ,.,.,.+ 0.8 R ..F R G ..+.{ - ' e ) n  .m e ) J m e e S <.<.<.X e Q , D H D % R <.<.<.Y , $.F F :.P R F 6 :.~.:.:.~.:.6 F +.P ..F :.:.9 ~.:.:.F :.~.~.:.~.~.F +.P 0.8 9 5 9 A o . e |.a @ a @ @ . @ @ @ a a ! k $.k i i i ",
+"= . b b ' v ' J _.@ ) J ! P H ; ' {.,.{.{._.F *.3.J $.:.P +.0 4 ~ |.Q |._.) m Q e c y Q Q [ ;.<./.f Q % i 0.H R I $.L <.<.[ . D 8 :.~.:.P 0.6 :.~.~.:.~.:.:.F P R R F :.~.~.~.:.:.:.:.~.~.:.:.9 6 +.+...o 8 *.*.*.{ d . ,.) @ ~ . K ~ ~ ' ' @ @ $ h $.k i $.$.",
+") |.|.y . y J b v & = J ' o P ..P 3 , ' Q _.3 ~...J |., R g.4 P v ,.b ,.e e |.e e |._.Q c } <.<./.I ) I n R n j n o ^.<.<.r . D ..:.~.:.:.:.+.F ~.~.~.:.~.~.:.F R P P :.:.9 :.:.6 6 :.:.9 ~.~.~.~.6 F F ..H 0.9 { o - @ . @ @ K . D ~ . @ $ K a K N k $.i k $.",
+"J b ) V v b b ' > - v ,.J w :.F P ..o o D = 3 o 6 ' e ) , 3 F ~.' ,.,.b e e Q e b e e ' ! '.<.;.<.o + H n +.F :.0.o U <.<.e.. > o :.7 ~.*.~.6 :.:.6 ~.~.~.6 +.+...P P :.~.7 ~.:.F :.~.~.~.9 ~.~.*.~.6 F F n P j P ; @ % % . @ z n l > + K ~ . a a $ ! k $.$.$.",
+"Q _.v a J b y , $ v {.b 7.(.o R ..+.F ~.8 ..P 6 :.w J J . . = k ) Q ,.b e e Q e |.e |.> d '.<.<.<.P ~ o 0.0.F :.P o U <.<.r . > o :.9 *.4 *.~.~.F F :.*.*.:.8 F R ..+.:.~.~.~.:.:.6 :.:.~.~.~.~.~.7 *.F F :.0.H , ' . , ~ . @ $ G { n N ' @ a @ a @ $ h $.k i ",
+"J ' ' b ,.x = - [.J J y |.|.W P ..P 0.~.~.F P P P H + ' ' Q b ) m Q ,.Q e e Q e e ,.$ P d q <.<.<.j ~ 3 R 0.P 8 P R ^./.<.r . W H +.~.~.4 A *.4 :.~.*.5 4 ~.8 +.R R P F ~.~.~.:.F 6 ~.:.~.~.~.~.6 ~.~.F :.G  .+ |.+ N @ + > > ' > 7 { $.. . a @ v @ v N k $.k ",
+"a . J Q J $ $ . J b ) [.b Q ) 3 0.R 3 D H ..P 6 +.0.v ,.J e ,.Q ,.Q Q b e Q Q e e ~ I G W [ <.<./.j $  .o 0.P F F R U <.<.r K ! o F ~.9 4 5 5 5 *.*.4 { 5 *.F P P P F :.:.~.~.:.:.F :.~.~.~.~.~.*.:.6 9 :.3 + Q ' , - ' z 9 G - . d O o $ ~ @ K a v K @ h k k ",
+"x J Q {.' ) {.Q [.|.b |.J b Q = :.0.W m ' = 5.+.{ A $ Q Q |._.m b b Q 7.e e e e Q i *.:.v _ /.<.<.j $ 3 ..+.0.F F R ^.<.<.r K ! o F ~.:.*.4 5 { 5 { { g.5 5 ~.P ..R +.:.~.~.~.:.:.6 :.~.9 ~.~.~.4 :.9 A H . |.) - ~ + , o g.{ P + - P h . @ ~ a a @ v v z i $.",
+"J |.b (.) ,.|.(.b Q 7.7.{.Q e b 0.*.o x |.m m @ o .., |.|.|.b ,.Q b b Q Q e Q Q @ d 7 I |.S /.<.<.G #  .P P P 6 0...U <.<.r . W o F :.~.*.4 4 5 5 { { 5 { 5 *.F R P 8 :.~.~.~.:.F F :.:.~.~.~.~.~.*.*...$ |.J % , + , o p { { 4.$.@ ; ~ . ~ @ @ a ~ @ K @ ! $.",
+",.y V a J b $ I D W $ $ V v $ v - F :.= (._.b ' Q ) b Q b b ,.b b J b e e Q e Q H R H $ Q [ <.<.<.j +  .P P ..F 8 R ^.<.<.r . W H F ~.~.4 4 *.4 5 { { 5 { O 4 F ..P 0.F ~.~.~.~.:.:.~.~.9 ~.~.~.~.*.o + |.' % N @ z R { g.4.5 { p v ~ @ @ @ + @ v @ $ v v ; $.",
+"i.- ~ J y J ) W :.9 6 P P F :.....0.0.F = ) @ b |.|.,.,.,.b b b Q b J e b Q e ~ o n $ e ' q <.<.<.F $ H 8 8 F :.P R U <.<.e.x D o F :.7 4 5 4 5 4.5 5 5 4 A { g.6 ..R ~.*.9 :.:.~.0.F *.F :.*.F *...@ |.@ z ~ ~ k 4.] { 4.g.{ *.].% @ ~ $ ~ + . @ @ a $ @ $ k ",
+"~ , y b $ $ _._.H :.~.G 6 P R R R ..+.5 R v b |.|.|.,.,.,.,.b ,.,.b b e b e e ; n  .m |.- u <.<.<.F ~ H R R P F P R U /.<.Z x W -.F :.~.4 5 4 5 5 4.4.4.{ 4 4 4 *.F R F :.9 *.A 8 9 :.:.p G :.{ 0.% ) ~ ; N ~ ! p *.4.{ 4 { *.W @ K $ % ) a ! - @ @ a $ @ @ h ",
+"* a b b ' @ (.Q $ o 6 ~.7 +.P 7 6 +.+.*.9 * 7.|.,.,.,.b b b b b b J b Q e e ) $.P , e + I q <.<.<.j $ 3 R ..R +.P o ^.<.<.r x w H F ~.*.4 5 *.4 5 4.5 { 5 5 4 4 { A :.8 F ~.5 { 9 :.:.9 :.*.9 n % ) x ; z . ! F ] 4.*.4.] 9 > . @ @ z ~ . D P n + @ v v v @ ].",
+"y b J m m ) x ) |.= o G ~.H - - o 8 :.F :. .m b ,.b Q b b ,.b b b J Q b e e % P d {.Q D o q <.<.<.j ~  .d o o R 8 o ^./.<.Z ' W -.F :.*.4 5 *.4 A 4 5 { { { A *.{ 5 4 ~.~.A O O =.9 j G j p n @ [.@ - $ ' , 0.g.{ { 5 g.g.i ' ~ $ z @ ' > l p j @ a @ @ v K N ",
+"|.b _.(.|.{.) (.|._.- 0.~...$ Q |.y a _.. + b 7.Q b b b b b {.b m J Q b e b i j W e . o I e.<./.<.P @ k H H H n P R U <.<.B . w H F ~.~.*.*.*.4 5 5 A 5 { { { 5 4 5 5 A { =.g.{ ] 1.*.:.7 o z ) . z % @ W 0.{ g.{ 4 g.{ k ~ ~ $ N @ @ W j { A p , a @ @ @ @ @ ",
+"' [.{.{.b J _.m (.|.b , -.~.o * v J J 7.e ,.b J b b b b b b b b m J Q Q Q @ d o (.e D n D q <.<.<.F + i E H o P P R ^.<.<.e.x W H :.9 7 A A *.A A 5 A 5 { { g.{ *.A { { =.h.=.6.=.1.g.1.n N @ N z N N i *.9.O O h.g.9 i @ v N N $ K > p { { A 0 i @ ~ $ @ @ a ",
+". (.|.Q b ,.|.{.x J |.m - +.6 F $ J Q |.|.Q Q |.b b b b {.b {.m J ,.b 7.b h P $.e x d R i q <.<.<.n @ i 3 H o P F o U <.<.r a w H F 7 9 *.*.*.*.5 4 { 5 5 5 5 { 5 5 5 { =.h.h.g.=.4 ` A ; . z ].z N  .5 h.{ 5 9.{ A i . ~ % a $ @ ! P { 4.9 A A P @ @ @ v $ . ",
+"Q ) J ,.,.7.7.[._.$ , ~ w o o :.I $ m m m b b Q b b b b b b b b J ,.m e J d G D e W o H  .u <.<.<.n . i 3 H o 8 P o U <.<.r x D H F 7 *.*.*.*.4 4 4 { 5 5 5 A 4.g.5 4 5 6.=.h.h.{ =.p @., N - z N > 9 2 O 0 O O 5 D + $ % % ~ . z 7 g.p A { 4.4.0 ~ @ $ K $ . ",
+"b ,.) @ v = 3 3 o -.+.G +.....0.:.$.x e m J e b b b b b {.J J J ,.,.b 7.$ d P - b I ..H I Z <.<./.j @ D E o R F P ..U <.<.e.~ = 3 F ~.~.4 *.*.*.5 5 4 A 4.4.{ 5 A 5 { 5 5 { g.h.C :.> ~ N ; ; N - l ] g.5 g.g.4 - ~ @ % $ @ @ , 4.0 { 4.4.A A p 4.$.. $ @ v K ",
+"{._.# E j 9 :.....n R +.*.6 P P 9 n - _.b Q e J b b b b b b b b c _.m ,.! j P v J H 0.d 3 q <.<.<.l ~ D  .E R ~.F n U <.<.} v D o F ~.:.7 *.4 4 *.4 5 5 5 4 4 4 4 5 O O { { g.C *.5.& N - N N ; F ` h.{ O ^ 1.H ~ + % - $ v W :.4.A 4.A 5 4.4 p 4.o . @ @ @ a ",
+",.Q _.& E n 8 P H +.+.6 6 R $.W ; - ~ _.b Q e {.b b {.b J J {.m Q b b m > j H [., 0.0.o d q <.<.<.j @ D E H o 9 R o }.<.<.} x W 3 8 :.7 A 5 4 5 5 5 5 4 5 5 { { A 5 4.1.=.C g.9 > % # * - z i P ` ^ ` h.] 4.R , + - - @ + D 7 ` A A A 5 A 4 A 4.A :.% a $ $ $ ",
+"J b ,.{.v , 5.~.G +.n ! _.|.J {.|.|.|.Q m b Q b {.b b b b J b m Q _.J ,.a - , b E 0.o o H q <.<./.o . k o o H 8 :.n U <.<.r . D o 6 ~.7 4 4 7 *.5 5 5 4 5 { { 4 *.5 A A ] C 9 D + % * ~ % $.p ] g.{ 1.^ A D % ~ $ - $ ' ; *.] 4 4.4.5 5 5 5 4 4.A p ! @ $ . @ ",
+"b J b b {.{.v w 6 G ~.H a Q b ) J m Q ,.m _.b {.b b {.J J m m m J ) Q Q e e ,.b 3 0.0...I q <.<.<.l @ i $.@.3.H j 8 ^./.<.e.+ W o F ~.~.4 4 4 5 4 5 5 4 5 { 5 *.A 4 5 O g.p  .@ $ - z # > 9 ] 2 { g.{ A I ~ @ % - a . D ~.{ 5 A 5 4.4 5 5 5 4 A 4.{ D @ $ y a ",
+") _.{._.(.J ) a -.7 ~.o 3.' Q _.{.[.m m b b b {.J b b b m m m J J _.7.J b 7.7.Q $ H :.0. .q <./.<.P c ' J Q Q J * ; U <.<.r v ; 3 +.7 *.5 5 4 4 5 { 5 5 5 { { 4 4 5 1.g.G D % N z ~ @ - P g.] { g.^ *.D @ N ! % . v > *.g.5 9 4.4.4.4 4 7 0 4 A *.l ; ) $ @ @ ",
+". (.b |.,.J J ) ) ; H 8 G E @ _.,.,.b ,.,.b J J b {.{.m m m [.J b ) {.- D , [.Q b , o F 3 q <./.<.P Q Q e 7.7.Q Q _.#.<.<.r . ; o :.~.+...H D 5.~.5 g.5 4 5 5 5 4 4 5 j i # $ - N ~ - P g.] g.g.2 g.H ~ @ z h % + i 9 4.{ A 5 5 { { 5 5 5 7 4 *.F R ].Q ' $ $ ",
+". . ) J b {.) y _.) > R n G F ; # a ' J |.,.c y b b b m m m m J ,.[.|.> j P W ' Q m - 0...q <.<.<.d e Q ) V V v {.,.T <.<.B + D o R 3 = ' y y ' @ H 4 { 4.5 5 5 4 5 F ; @ * ].N N ].n ` 2 4.4.^ 1.n = , z ~ N % i ~.g.5 *.4 4.A { { 5 5 5 4 4 *.R R > e {.@ a ",
+") + v {.Q Q b v n 8 8 R R P F *.0.' Q m c ' _.,.m ,.,.,.m J J J _.Q {. .....0.3 b Q ) 3 I './.<.<.d e * 3 o H :.o [.u <.<.q ) W o o @ b @ w W , @ (.; A { { 5 4 { F ; @ N z N N @.A h.g.1.h.g.4.D - N N ! N . i ` 5 4 5 5 5 { { A { { 4 A 5 :.H d o  .Q e e Q ",
+"Q Q |.J ' , 3...F G :.F 8 P H w . e Q _._.m ,.|.b b ,.m [._.J b m ,.J  .R R 0.H ' J |.5.o Z <.<./.$.) E H R o R R  .#./.<.} @ W I ; J v o 4 4 9 - x $ n 4.5 5 4 P D + @ - % ~ ].p 1.1.{ C ^ ~.D , $ - ; N + ! *.{ 5 4 5 { 5 4.4.5 4.5 4.*.F ..H o o k Q Q Q b ",
+"7.{.$ i ..P +.R o ~.A n w @ _.|.Q Q ) ' _.m Q ,.b b _._._.m b m J ,.[.3 P o ..R & |.e W H e./.<.<.$.) E H ..o n l j %.<.<._ + W d + b D 4 4.{ O o @ v i { 4.{ 5 3.~ . , ].z > 8 ` =.{ { h.5  .@ $ z ].z N i *.` { 5 5 5 { 5 4 A 4.p A { p ..3 o H R  .Q e e Q ",
+") = ..:.6 ~.6 -.P H ; (.J _.J |.|.J ) m b b Q b m m _._.m b b m J J [.3 0.H o 8 w e |.= H q /.<./.l . d R H o 8 o P t <.<.| ) D  .) b  .5 *.*.{ p , v ; { 4 { 4 @ @ $ z z - n ^ 1.4.O ^ { H , , - ! z $ z d ` ` 5 5 6.5 5 5 A 4.5 A A 5 9 0.H H H o  .Q Q e b ",
+"|.' D o o ..6 6 n 5.$ i._.m b {._.J ) ,.|.m Q ,.J _._.m m m m m _.J J 5.0.o R P > Q |.; 3 Z <./.<.M @ - n o H o o S <.<.<.=.c D I + J 3 A 4.4.O :., + W g.4.5 4 $ ~ @ $ % N $.4.1.g.g.^ ] :.D = z ! N z z ].R g.5 O 5 5 5 4.A 5 4 4.4.A A 9 F H H R k Q e Q Q ",
+"x b |._.' @ 5.6 P +.F R D # b e ) b _.J b b Q Q _.J J m ,.m m J b b b i R R 0.o ' ,.7.D H =.<.<.<.t 0 $.3  .d F r t <.<.<.7 . k o , b $ ..*.A ~.W v = H g.{ { 4.o ; . ~ - , z  .4.g.g.O h.h.*.o $ z z z % . - d 5 O 5 5 5 4 +.0.:.A 4.A 4 A :.H H R  .Q e e b ",
+"@ ' m ,.|.Q Q _.H -.P 6 ~.P 3 w @ Q Q |.Q Q ,.J _.J b ,.b b m m m ,.{.i ..8 0.5.|.,.J H ....U <.;.<.d.#.q < q %.<.<.;.<.%.> $ k F H . m @ W W , @ @  .A g.5 { { { n - % - N % z I A ` 4.g.^ 2 g.$.! z N $ , ~ $ n 4.O 5 5 F H H ..:.*.4.A ~.+.o H o k Q Q Q Q ",
+"(.@ ' ,.Q ,.Q Q |.$ k -.-.8 :.:.d ' ,.b ,.b _.) m m ,.b J m b ,.J m _. ...8 o = |.Q ; R R W ^ /.<./.<.<.<.<.d.<.<./.<./.C {.- $.0.9 D ) b ) a ' a - 6 ^ g.5 5 5 ` A 3 ~ ~ z z z @ o { g.g.O O g.] i , z % , ~ $ , n 4.{ 7 +.o ..H ..~.{ 4.0.o o d R  .Q e e b ",
+"|.) . ' b Q Q |.J ' w R :.6 P H ) Q b Q Q ) c m m b m m ,.m m m _.,.|.> ~. .$ Q Q ) H +...3 i ^ <.<.<.<./.<.<.<./.<.;.{ c @ D H P 0.0.3 , _.y , H 7 g.{ 5 { 5 5 *.{ A $.@ @ ].].- % I { g.O h.^ g.4. .~ $ z % % @ $ o p 6 ..R H 0.o n 7 F H H o o n W e Q Q e ",
+"J J _.' [.Q Q [.& 3 6 P P F W 7.,.e ,.b b [.m ,.m m b m m b b m Q J b ' $ b b Q [.W F o o R W W { c.<.<.<./.<./.<.q P . _.W I P 9 9 *.9 R 3 o ~.*.{ g.5 4 5 5 5 5 4 { 4 H z N N N ].z I { g.5 g.O ] :.W ~ ~ ~ z ].+ @ D 0...-...o 3 H R ..d o o H n z e Q e Q ",
+"{.,.J _.J ,.(.= F ..P :.3 v ,.Q m Q m ) _.J m _.m m m m m m b m Q J ,.Q Q 7.|.Q  .8 F -.P F H i + D 9 ^ _ : S /  .' ) + W I H F F :.9 *.j n :.A g.O 5 4 4 4 4 4 5 7 5 ^ 4.H z $ ].N $ z I 5 h.O { ^ g.:. ., @ $ a y Q {.= o ..H o o o o H o R ..o R @ e Q e e ",
+"' J Q Q _.= H F P P ..; [.e e _.,.{.c _.m ,.,.,.,.m m ,.m m m b m [.|.|.v $ $ b  .n o o +.o ..0...; . v + ' ) ) ~ $ W D i o 0.~.F 6 :.9 :.o ..:.g.{ 5 7 { { { 5 5 7 4 =.] 1.n W z $ z - , I 4.h.g.] ] ] A H , ~ ' {.|.e |.= 0...o ....o H H H o o d _.e b e Q ",
+"' [.|.(.D P 0.-.o F H # {._._.Q e ,.,.,.,.,.,.,.m b ,.m b m ,.m J b Q J  .P E [.~ 0.0...-.o 0.H o ..H W = ; W > ; i ..H ..:.F F ~.:.9 *.:.0.R 8 7 5 0 5 5 O 5 4 5 5 5 5 { ^ g.P N z N $ ]., I g.` g.g.g.g.*. ., $ _.m J e |.W F H H d o o o o o R  .b e b e e ",
+"7.,.+  .F 6 0.o F o E H o I i i ! - ' ,.,.,._._.b m m b b m b m {.,.|.{.i j d ) @ 0.F ....-.+...R ....H H H  .5.H o F :.:.+.P 7 6 F :.9 j R R :.7 { 6.0 7 5 5 5 5 5 5 { 5 g.C g.$.% K z ! N z I { ] h.{ { g.5 o $ . _.m |.e J - 0.0.o o R ..o d n W Q e Q e e ",
+"Q J ~ D 5.i H F 8 :.8 n F F 0...A P % m ,.,.m m m {.m m m m m m b b m Q $ H o $ [.k 0.R P ....o +.n o P 0.o ..F 0...0.~.4 G P 6 ~.:.~.9 j n F ~.4 5 5 7 4 5 5 { 5 *.{ O 8.{ =.g.A D ].].N z ! $ R 4.g.{ 6.h.9.4 W , ' J J Q e e W H 0.R R R o o ..$ 7.Q e e e ",
+"Q Q ,.Q Q |.) ) ~ N N > 3 -.+.4 F k ) Q m ,.,.,.m ,.m b {.m m ,.b m [.7.. I 0.! Q i 8 o o R P R -.+.+.R P :.F o P :.F P 6 7 :.+.6 F :.~.F 0.:.5 5 0 5 6.5 5 5 { 4.*.5 O O 8.O 5 C { I $ $ z z ; N d 4.g.O O 8.O ~.W # @ _.e b b Q = o o d H o o o . e Q e Q Q ",
+",.m _.Q Q J |.Q 7.,.7.Q D :.6 +.W |.e [.|.Q Q [.,.m m m m b ,.m Q c b e b W n  .e + o 0.o R R ....n P P P P P +.+.+.+.+.6 6 7 7 +.F ~.*.*.~.*.5 4 5 7 5 5 5 4 4 5 5 5 { { O { { 5 { { j W @ $ z , $ 3 O h.{ 6.{ O 5 E ~ K y Q b e Q ~ d R o o o D ,.e Q e b e ",
+"Q ,.' ) {.b Q Q m e Q , 0.7 6 H (.Q ,._.b [.,.,.m b m b b m ,.,.b J ,.e e % n H m b  .F H o R ..R P ..n P +.P P P +.+.+.6 6 ~.~.~.:.~.9 *.*.*.4 4 5 5 5 4 4 4 4 5 5 0 { 6.{ { 1.{ g.] ` F ! $ - , ~ ; o *.g.h.4 5 g.4 I % y Q e Q Q b - n o H n % e e Q e Q e ",
+"Q Q . @ J Q e ,.,.e ~ 0.:.F 5.' |.b {.Q Q |.,.|.b b m b m ,.J J J ,.b Q e ' I n $ e , j o 8 8 o R ..R +.P P +.+.F +.P 8 +.F 6 ~.*.~.:.7 *.*.7 A 4 4 4 4 5 5 4 4 4 5 5 5 { { O { { g.O ] ` o , $ - ]., $  .5 g.5 5 { ] A $.~ ' J e Q e {.- ..R o ) e e Q e Q e ",
+"|.e _.) |.Q Q b e v o A 0.5.@ e Q b b |.) ) b ,.b ,.m m m b m m _.,.Q Q e ,.W P  .e {.3 8 R n R P P R P n P P +.P F +.8 +.F F 6 *.7 *.4 4 *.4 4 4 4 5 4 4 5 4 4 4 5 5 { { { { { A { { { ` 4.I $ $ ].; $ , 3 *.g.O *.5 g.p i @ . J |.b e ,.! R $.Q e Q Q e Q e ",
+"b e |.,.Q b Q Q )  .:.0.o D $ @ - W 3.H R > ' {.b b ,.,.b m J J b b ,.Q e Q v d n + Q % 8 R P P R P n P P P P P F +.+.+.+.F +.6 :.:.*.4 4 7 ~.*.4 5 4 5 5 4 4 4 4 4 5 5 { { { O { O O 4.O ] 5 H z % N , $ $  .{ { { *.{ g.F = + . Q Q ,.e b , ! e e b Q e e Q ",
+",.Q |.Q Q b Q J o 9 F ..F 0.H j F 0.0.:.0.$ |.Q b b m m J {.J b Q m ,.Q ,.e {.D 0.i |.{. .o R 8 P +.P R P n P P P +.+.P +.6 F F +.6 *.4 A 7 7 4 4 4 4 A 4 4 4 4 A 4 A 5 4.{ { O ` 4.g.g.4.` ] { P W ~ z z + ~ i A ] 1.4 1.{ +.3 % K J ,.Q e |._.e e b e e e e ",
+"Q Q ,.|.b |._.W A ~.0.R 0.P 0.F R 0.0.R > ) |.{.,.b m _.J b b ,.,.Q Q e Q e e + o n , Q @ H H ..P ..P P P P P P +.P 8 F F F 6 6 :.F ~.4 5 4 4 *.4 4 4 5 5 5 5 4 *.A 4.4.{ { { { { { { { { O g.h.` j ; # , ~ . ~ $.A { *.4 g.O 1. .; K ,.Q Q e e e Q Q Q e e e ",
+"e ,.b |.b b v :.3 D  .i = z % J ; H F .., |.Q b |.b m _._.{.Q Q J Q Q Q Q Q e ) d n H Q |.H H H P P P R P ..P R 8 +.+.F F F F F ~.F F 7 { { 5 *.A 4 4 4 4 A 4 4 *.*.A 4.{ { { O 4.{ O g.] ] g.g.2 { o ~ ~ - z $ @ I { g.4 *.5 4.0 W @ . Q e b Q Q e e Q Q e e ",
+"|.e ,.m e m $ (.m |.m |.Q b Q Q 5.P :.; J b Q |.Q ) _.,.b e e J Q Q b e Q Q Q e ; o j $ Q = n o -.0.6 +...+.P R P P 8 F F :.6 :.F F :.~.7 A 5 { 7 4 5 5 5 4 4 5 A 4.A 4.{ g.{ 4.{ O { 5 A g.h.O 5 2 4. .$ $ - $ % . i { { *.A 4.F % ~ ~ ' _.e Q e |.b Q e e e ",
+"Q ,.|.|.b J m Q b b m b b |.|.@ ..F ..v Q |.|._.z o ; Q e y y e Q b b Q Q Q Q Q ' I o 3 . _. .n H o ..P P R P F P +.+.+.+.F F 6 6 6 :.:.~.4 5 4.4 4 5 5 5 4.4 4 *.A 4.{ 4.{ { { g.{ A ~.~.4.] g.O g.g.4.H + ' , . N -  .p g.4.4.$ ~ D > @ y Q Q e e e Q Q e e ",
+"|.|.b (.x y J b |.J b b m Q (. .8 ..3.y J , W H :.P a ,.J Q ,.b b Q b Q e Q |.e e $ 3 l D Q . E ..H H 0.:.8 o +.8 8 8 F P F :.F :.:.6 ~.9 7 4 5 5 A 4 4 5 5 5 5 *.A 5 4.4.4.{ g.{ *.~.F 0.9 g.h.=.O =.^ 4.3 $ $ $ % $ @ D p A k .  .{ j z @ a c c e e e Q e e ",
+"J |.x = y |.J J m ) J J b |., 0.H R E 5.o P n P F H |.e ,.e Q e J Q Q Q Q Q |.e e ,.- R o @ 7.. ..R o o F :.n R R 0.0.+.8 F :.F F F :.~.~.~.4 5 5 5 4 5 4 A 4 A 7 A 5 4.{ { { { *.F F F :.*.{ g.g.h.O { g.g.0., % ~ ~ a @ k  .. D p ` g $ @ $ a a J Q e e e Q ",
+"J J @ a |.|.J b J y m m |.) 3 j +.F 0.R F :.:.:.n D |.Q [.e b ) J Q |.b Q Q |.Q Q e ) - F H {.Q = o R 3 H F ~.6 8 P 0.8 +.F F :.:.:.6 :.~.*.7 *.4 5 { 5 5 4 4 5 5 4 4 5 { O 5 A :.0.0.:.:.p g.g.O ^ ^ 4 A 2 { P x % ~ + ~ . . - 9 { *.! K v N @ $ @ ) Q e e b ",
+"_.$ x |.|.) J b b m J |.|.= F 0.R F F 8 H i H 0.P % 7.Q |.|.$ d y Q Q Q e Q |.e e Q e . H P D b 7.= P P H o F :.8 8 8 8 0.F F :.6 F ~.~.~.*.*.4 7 5 { { 5 4 4 4 5 5 5 5 { { A 6 0.R n F l A ` g.{ g.h.g.{ { 1.{ i % ' ~ z a v ! { O o % @ $ N @ v $ $ m e e b ",
+"$ $ y |.J ) b |.b b {.Q y 3 8 H F o D W x (. .o H # |.e [.; n P y b Q b e e Q e Q |.e |.~ H n = 7.J w R o o R ..:.F F 8 8 8 F F F :.:.~.*.7 4 4 *.4 5 { { 5 A 7 5 7 5 5 { 4 :.0.F 0.0.n :.4.] ` g.O g.h.g.4.4.] 4. .# ~ ~ $ z ~ o 0.- @ @ v @ v @ ].i z Q e Q ",
+", b Q J [.{.m m J J J Q # 0.R i - @ J ) |.J 3 8 H b Q @ i n 8 P . b Q ,.e e |.e |.e b e Q  .R R - b ' 3 ..H o o :.F F +.F F F 6 F 6 :.~.9 *.*.4 4 4 7 A 5 { 5 7 7 4 5 5 5 7 0...0.0.F 0.j { ] { g.g.g.g.g.g.{ { g.A i + ~ @ . ~ ' W @ a $ $ $ @ $ h g k _.e Q ",
+"b b ,.b b {.{.{.m |.|.J ' ' b b e J . |.e + R ..D $ i n n o o +.x ,.,.e $ > e e Q e Q e e J h j n D b |.D R 3 o H 6 9 F ..P :.:.6 :.6 ~.7 7 7 7 4 5 4 7 5 5 { 5 4 7 5 7 6 P 0.F R 0.R o F A { { 1.{ 1.g.g.g.{ { O P - @ . @ % @ ~ @ ~ $ $ @ @ @ h f d d k ' e ",
+"b b b {.b m J J m |.|.b m b |.b J a # b |.W 0.H ..3 0.F o n 0.+.$ Q Q . $.o @ e Q Q e Q b e c k n o ; Q 7.; 8 0.E 0.:.F +.F F +.6 G 6 ~.7 7 4 7 7 7 5 4 0 5 5 6.5 4 7 6 0.+.P P 0.F F 8 F 4 { { g.{ g.g.1.5 g.g.0.~ x 0.G % ' z % @ a @ $ @ $ N f d f d o ! c ",
+",.{.{.{.{.{.J {.{.|.Q b b b b ) W , ) e e 3 0...H ..G d ; H 0.0.a |.) $.g n  .) e b Q Q Q e e _. .0.H & b e + n ..F :.9 ~.:.:.F 6 :.~.~.~.4 7 4 4 7 5 5 7 7 4 O 5 7 F P +.8 F 0.8 8 0.0.0.9 { h.5 O g.g.5 ] g.7 + , I 0 { I ~ ' $ @ @ $ v a N h R g f f R o - ",
+"b b b {.b b b {.b b b b b b ) v $ (.|.Q _.o o ..F R i + |.> R 0.' ) > j o d n > e e Q b Q e b e _.k P H W {.7.' :.F F :.7 ~.:.F 6 6 6 ~.~.7 7 7 7 4 5 5 5 7 5 5 *.:.P R P 8 P R P R R 8 R F *.{ ` O 4 { h.] n $ = n { 2 A D @ @ ~ @ @ ~ a v ! d d d o d f o f ",
+"{.{.{.b {.{.{.b b b {.J J J (.+ _.J {.b . n d R H ; ) e Q  .F n & $ o P I o H I # e e b Q e e Q e ) D j n i @ |., i F *.9 6 F 6 :.:.~.~.~.*.*.4 4 4 4 5 5 { 4 7 P +.8 P P P 8 8 R 8 F j F F j ~.{ g.g.{ *.i , ; p ` { 7 $.@ . % @ $ @ v ~ ].k g $.f o d k $.g ",
+"{.b {.b b b b b b {.J [.J {.[.) _.J ,.Q ; G H W ) m Q |.J I 8 R E H j k N @.H n I , Q e Q Q e Q Q e J ! o P H i b (.; 3 P 6 :.6 6 :.:.~.~.7 *.7 4 4 4 7 4 5 ~.F H R 8 F 8 8 8 8 8 j F P P j G G *.1.~.D , , 3 A ` =.n - @ ~ % @ $ @ @ $ ! $.f d f $.f o f I d ",
+"b {.J {.b b b b J J b J J b m _._.,.,.J $.I - b |.,.,.,.7.h R P 8 P d ' Q , o 0...o z b e b Q Q e _.Q e , P j j H = b b % ..:.8 :.:.:.~.9 *.*.A *.4 *.4 *.~.F ..o o R 8 8 P 8 P n 8 P P j 9 G F n  .% + D 9 ` O *.I $ ~ @ . ~ ~ ~ @ @ ].$.d d $.g $.$.d o f f ",
+"J {.{.{.b b b b J b |.J _.J J J _.,._._.> J |.Q {.{.,.J ,.k R R P P - Q 7.$ 0.5.o ..H z e e Q Q ,.e e b {.+  .n A 9  .' Q y w ..F :.:.~.9 *.*.A *.*.*.A *.F ..o ..R o R 8 P F 8 n P j :.l 9 o 3.v |.# F { { { 0 i z . $ $ ~ % a a @ - $.g d f $.o d f f f f d ",
+"_.J b b {.{.b J b b J b b J b J b b ,.b ,.J |.|.J ) Q Q Q D n n *.W ,.Q Q b ..o ..E n k Q e m e Q e Q J m Q ) D p j F P D ) |.(.- H 9 *.~.:.~.9 *.A A *.j R R P o o o R n F 8 8 j F :.l n ; (.,._.= o 7 ` =.G W ~ % , % ~ ~ $ $ @ ].$.g d f f d f f f f f f f ",
+"b {.{.J J b {.J m b J m b J b J b b ,.b ,.J J J J b ,._.,.> P :.i + Q e 7.Q i o o R H N 7.e Q e e Q b {.b m ) . ; I :.9 G H = ' |.) ,  .0.9 A 4.A A A ~.:.0.R R H o n j :.j P P P d D $ _.,.' = o P l G P I D % + ~ ~ $ % ~ @ . ].i f d f f f d f f I f I f f ",
+"7.Q J [.[.J b b b b b b J J J J J {.{.,.J _.) x ,.J ) _.7.i 0.D ) {.Q e e e $ ..H n z Q Q 7.e Q e ,.m b m c _.Q |.@ > k o A 7 H  .= . x + $ W  .0...d H H H H H H o o o E  .D > ' _.J ' z  .P l p l d ! @ y K ~ ~ ~ % % ~ $ z ! f f d d f f d o f f f f f f f ",
+"7.Q ,.J _.[.[.b b b J b J J J J b b {.{.b [.) ' _.) J |.Q D D b |.b {.Q e e ) o R  .) 7.7.7.7.|.J Q ,._._.J _.m |.b J ) + i j p G :.F 0.H W , @ ) b |.Q |.b b ,.Q ,.,.,.,.b {.[.z @.n j j l l l k z . J |.Q _.@ N $ @ . @ ! I n n R g d f f f o I $.f $.$.f f ",
+"Q 7.Q |.J ) [.b m m b m b m J J b b J J J {._.(.@ ) |.,.[.. _.Q b J J e Q e Q $.o @ Q 7.e 7.|.,.[.|.m ) J b _._.) J ,.b {.c ~ W j G p 7 G ~.9 7 D W , $ # @ ' (.(.. # * >  .o j G j j j 9 P i ~ ' ) J J J J J J $ ~ K K - I P P P n o o o d f $.$.f $.f f I I ",
+",.7.e Q ,._._.{.{.J b b b b J J b b {.J [.{.b J ' a ' b |.|.|.b J J b e e Q Q ; i b e Q e e [.J |.[.' c m b m Q _.c _.c J {.J _.' , H :.A { *.:.F F P 8 0.8 8 n o R P j j G j j j l l f - a _.c J c ) c _.{.{.,.c @ z > $.o n o g o o f f o f $.f f I f $.$.f ",
+",.Q 7.Q Q ,.[.) ) J b b b b b b J J J m [.J J b J @ @ [.e b _.J [._.Q e e e e v . e e Q e ,.) b b . . [.,.J m Q b b J b _.y y _.J ) ' @ - i d o n n F P P 0.n n n P j j :.P o H > z . _._.c y J y y c J b Q b c Q ' h d g I I n g o f f f f f f $.$.$.$.f f $.",
+"Q b Q Q Q e b ) [.[.J b b b b J _.J J m [.) J m J b x . m b _.J ) _.Q Q e e e J e Q e e Q J J J (.+ x [.[._.J _._.m m J c c J _.) m _.(.) b b b + ~ ; W ! ; ! D ! ; ; ! - N . c m ,.b J c ) y c c c c c c b b J b J $ $.n d I d n g f $.$.$.f f f f f $.$.f f ",
+"Q Q Q Q Q ,.Q Q ) (.[.b b b m J J J J b m m [.J J b b ) ) _.J J [.[._.Q e Q |.Q e e Q ,.b ,._.' a y ) [.) ) ) [.m m {._.c y ) c c ) ) _.m b b {.|.,.,.|.|.,.|.Q 7.Q b b m J J _.J J c c ) c c _.y c c J J m J J J _.e {.i o $.$.$.d g f k $.$.$.$.k k $.$.$.I ",
+"Q Q Q Q Q Q Q Q [.) ) [.b b b J J b J J {.J [.[.b [._.b ) v x b ) J ,.{.,.e e ,.e ,.[.m {.[.' . ) J J J ) ) (.' ' ' ) J m J J ) y c J b b ,.b b b Q ,.b b b b ,.Q b m J ) c c _._._.c c c c c c c _._.c c c c c c ,.b b y ! g f f $.$.$.I $.$.d $.$.$.$.$.$.f ",
+"Q Q Q Q Q |.Q |.,.[.(.(.[.b b J b m J J J J m m b ) [.b m @ V y b J J |.|.b b m |.m _.{.J ) ' ' J J J ) (.' ' ' ' . . ' _._._._.y c b ,.|.b b m ,.b b b b b ,.b b b J y c ) c J c c J J J {.c c c ) y ' K y y c c Q J Q e K $.d I k i f k $ $ $.f $.$.$.$.$.$.",
+"Q Q Q Q Q ,.Q Q Q ,.J (.) ) {.b b b b J J {.{.b ) ) J J {._.x $ _.J _.|.7._.. ,.b |.|.|.J ' (.J J _._.) ) ) ) ' ' ' . . K ' K y c m Q 7.Q b J b b b m m m b b b Q b b c c J _.b J J J J c c c y K a a a . y c J J J b Q Q Q a i f f $.k $ e e ! $.$.$.$.$.$.$.",
+"Q Q Q Q Q Q Q Q Q Q |.J (.(.[.b b b b b J J m m ) b J ) m |._.@ % (.J b |.|.m [.{.|.Q J ) _.b b b [.(.y ) ) ) ) ' ) ) ' + ~ @ @ b b Q Q ,.m m m ,.b b J J J ,.|.b b {.{.J c J c b {.c c y K @ @ $ ~ v . ' y c J J J b ,.c e e a k I k $ Q e y i $.k k k k k $.",
+"Q Q Q Q Q Q |.Q |.Q Q |.) ' (.J J J m b b J J {.m m J _._.[.J J v # _.|.J {.b ) b b {.) ) J b J b J [.) ) ) ) (.. ' ' . @ ~ K _.e e Q Q b b J J m m J J J J b b b b c y y ' y ' K K a a @ @ $ $ @ ~ a K ' ) ) c c J b Q Q Q Q e K z $ e e a i $.$.k k k k k $.",
+"Q Q Q Q Q Q Q |.,.Q 7.Q |.[.) ' ) _.b b b b J J {.{.J J [._.b b b a @ b Q ) x ) b J y ) {.|.b ) b {.) ) ) ) ' ) ' ' . @ ~ K b e e e Q b b m J J J c c y ) c _.J Q {.c a @ v a K @ @ @ @ @ @ a a @ a a K y y c c _.J m b e Q b e e b b e e % $.i i k i i k k k "};
Index: branches/network/src/lib/gui/gtk_gui/gui.cc
===================================================================
--- branches/network/src/lib/gui/gtk_gui/gui.cc	(revision 6636)
+++ branches/network/src/lib/gui/gtk_gui/gui.cc	(revision 6636)
@@ -0,0 +1,156 @@
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+
+*/
+
+#include <unistd.h>
+
+#include "gui_gtk.h"
+#include "gui.h"
+#include "gui_video.h"
+#include "gui_audio.h"
+#include "gui_exec.h"
+#include "gui_flags.h"
+#include "gui_banner.h"
+#include "gui_keys.h"
+#include "gui_update.h"
+
+// GUI-modules
+GuiFlags* flags   = NULL;
+GuiVideo* video   = NULL;
+GuiAudio* audio   = NULL;
+GuiExec* exec     = NULL;
+GuiBanner* banner = NULL;
+GuiKeys* keys     = NULL;
+GuiUpdate* update = NULL;
+
+/* ORXONOXGUI */
+
+/**
+ *  Initializes the Gui
+*/
+Gui::Gui(int argc, char *argv[])
+{
+  Window* orxonoxGUI = NULL;
+  executable = NULL;
+  
+  initGUI(argc, argv);
+
+  orxonoxGUI = new Window( "grafical " PACKAGE_NAME " loader, "PACKAGE_VERSION);
+  {
+    Box* windowBox = new Box ('h');
+    {
+      banner = new GuiBanner();
+      windowBox->fill (banner->getWidget());
+      
+      Box* optionBoxL = new Box('v');
+      {
+	Box* avBox = new Box('h');
+	
+	video = new GuiVideo();
+	avBox->fill(video->getWidget());
+	audio = new GuiAudio();
+	avBox->fill(audio->getWidget());
+      
+	optionBoxL->fill(avBox);
+
+	keys = new GuiKeys();
+	optionBoxL->fill(keys->getWidget());
+	windowBox->fill(optionBoxL);
+      }
+      Box* optionBoxR = new Box('v');
+      {
+	flags = new GuiFlags();
+	optionBoxR->fill(flags->getWidget());
+	
+	update = new GuiUpdate();
+	optionBoxR->fill(update->getWidget());
+
+	exec = new GuiExec();
+	optionBoxR->fill(exec->getWidget());
+      }
+      windowBox->fill(optionBoxR);
+    }
+    orxonoxGUI->fill(windowBox);
+  }
+
+
+  // Reading Values from File
+  exec->setConfDir(GUI_DEFAULT_CONF_DIR);
+  exec->setConfFile(GUI_DEFAULT_CONF_FILE);
+  exec->readFromFile(Window::mainWindow);
+  // Merging changes to the Options from appended flags.
+  for (int optCount = 1; optCount < argc; optCount++)
+    Window::mainWindow->walkThrough(Widget::flagCheck, argv[optCount], 0);
+
+  flags->setTextFromFlags(Window::mainWindow);
+  Window::mainWindow->showall();
+  
+  Window::mainWindow->walkThrough(Widget::redrawOptions, 1);
+
+  //// Handling special Cases. ///
+
+  // case update //
+#ifdef HAVE_CURL
+  if (static_cast<Option*>(Window::mainWindow->findWidgetByName(CONFIG_NAME_AUTO_UPDATE, 0))->value == 1)
+    {
+      update->checkForUpdates();
+    }
+#endif /* HAVE_CURL */
+}
+
+/**
+ *  starts the OrxonoxGUI
+*/
+void Gui::startGui()
+{
+  mainloopGUI();
+  
+#ifndef HAVE_GTK2
+  GuiExec::startOrxonox(NULL, exec);
+#endif /* HAVE_GTK2 */
+}
+
+void Gui::printHelp()
+{
+  Window::mainWindow->walkThrough(Widget::printHelp, 1);
+}
+
+/**
+ *  a bool that knows if orxonox should be started
+*/
+bool Gui::startOrxonox = false;
+
+/**
+ *  Destructor.
+*/
+Gui::~Gui()
+{
+  delete video;
+  delete audio;
+  delete exec;
+  delete flags;
+  delete banner;
+  delete keys;
+  delete update;
+}
Index: branches/network/src/lib/gui/gtk_gui/gui.h
===================================================================
--- branches/network/src/lib/gui/gtk_gui/gui.h	(revision 6636)
+++ branches/network/src/lib/gui/gtk_gui/gui.h	(revision 6636)
@@ -0,0 +1,34 @@
+/*!
+ \file gui.h
+ \brief Creation of the Gui
+
+ @todo way to start gui without GTK (textmode) AND IMPROOVE
+ @todo curl interface to Download cool stuff
+
+ @todo widgets save themselves
+ @todo good way to step through all the Widgets
+ @todo label -> protected : getlabel function
+*/
+
+#ifndef _GUI_H
+#define _GUI_H
+
+using namespace std;
+
+#define GUI_DEFAULT_CONF_DIR "~/.orxonox"
+#define GUI_DEFAULT_CONF_FILE "orxonox.conf"
+
+//! Class that creates the Gui
+class Gui
+{
+ public:
+  Gui(int argc, char *argv[]);
+  ~Gui();
+
+  void startGui();
+  void printHelp();
+
+  static bool startOrxonox;
+};
+
+#endif /* _GUI_H */
Index: branches/network/src/lib/gui/gtk_gui/gui_audio.cc
===================================================================
--- branches/network/src/lib/gui/gtk_gui/gui_audio.cc	(revision 6636)
+++ branches/network/src/lib/gui/gtk_gui/gui_audio.cc	(revision 6636)
@@ -0,0 +1,91 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+
+*/
+
+#include "gui_audio.h"
+
+#include "gui_gtk.h"
+
+/**
+ *  Creates an Audio-Frame
+*/
+GuiAudio::GuiAudio()
+{
+  Frame* audioFrame;        //!< The Frame that holds the audio Options.
+
+  audioFrame = new Frame("Audio-Options:");
+  audioFrame->setGroupName(CONFIG_SECTION_AUDIO);
+  {
+    Box* audioBox;            //!< The Box that holds the audio Options.
+    audioBox = new Box('v');
+    {
+      CheckButton* enableSound; //!< A Ckeckbutton for enabling Sound.
+      Slider* audioChannels;    //!< A Slider for the count of audio-channels.
+      Slider* musicVolume;      //!< A Slider for music volume.
+      Slider* effectsVolume;    //!< A Slider for effects volume.
+
+      enableSound = new CheckButton(CONFIG_NAME_DISABLE_AUDIO);
+      enableSound->setFlagName ("no-sound", 0);
+      enableSound->setDescription("Disables Sound", "Check this to disable Sound in Orxonox");
+      enableSound->setDefaultValue(0);
+      enableSound->saveability();
+      audioBox->fill(enableSound);
+
+      Label* audioChannelsLabel = new Label(CONFIG_NAME_AUDIO_CHANNELS);
+      audioBox->fill(audioChannelsLabel);
+      audioChannels = new Slider(CONFIG_NAME_AUDIO_CHANNELS, 0, 32);
+      audioChannels->setFlagName("channels", "c", 32);
+      audioChannels->setDescription("Sets the count of channels in the game");
+      audioChannels->saveability();
+      audioBox->fill (audioChannels);
+
+
+      Label* musicVolumeLabel = new Label(CONFIG_NAME_MUSIC_VOLUME);
+      audioBox->fill(musicVolumeLabel);
+      musicVolume = new Slider(CONFIG_NAME_MUSIC_VOLUME, 0, 100);
+      musicVolume->setFlagName("music-volume", "m", 80);
+      musicVolume->setDescription("Sets the volume of the ingame music");
+      musicVolume->saveability();
+      audioBox->fill (musicVolume);
+
+      Label* effectsVolumeLabel = new Label (CONFIG_NAME_EFFECTS_VOLUME);
+      audioBox->fill (effectsVolumeLabel);
+      effectsVolume = new Slider (CONFIG_NAME_EFFECTS_VOLUME, 0, 100);
+      effectsVolume->setFlagName ("effects-volume", "e", 80);
+      effectsVolume->setDescription("Sets the volune of the ingame SoundEffects");
+      effectsVolume->saveability();
+      audioBox->fill (effectsVolume);
+    }
+    audioFrame->fill(audioBox);
+  }
+  setMainWidget(audioFrame);
+}
+
+/**
+  *  Destructs the Audio-Stuff
+*/
+GuiAudio::~GuiAudio()
+{
+  // nothing to do here.
+}
Index: branches/network/src/lib/gui/gtk_gui/gui_audio.h
===================================================================
--- branches/network/src/lib/gui/gtk_gui/gui_audio.h	(revision 6636)
+++ branches/network/src/lib/gui/gtk_gui/gui_audio.h	(revision 6636)
@@ -0,0 +1,18 @@
+/*!
+  \file gui_audio.h
+  \brief File that holds the class that creates the Audio-Options.
+*/
+
+#ifndef _GUI_AUDIO_H
+#define _GUI_AUDIO_H
+
+#include "gui_element.h"
+
+//! Class that creates the Audio-Options.
+class GuiAudio : public GuiElement
+{
+ public:
+  GuiAudio();
+  ~GuiAudio();
+};
+#endif /* _GUI_AUDIO_H */
Index: branches/network/src/lib/gui/gtk_gui/gui_banner.cc
===================================================================
--- branches/network/src/lib/gui/gtk_gui/gui_banner.cc	(revision 6636)
+++ branches/network/src/lib/gui/gtk_gui/gui_banner.cc	(revision 6636)
@@ -0,0 +1,97 @@
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+
+*/
+
+#include "gui_banner.h"
+
+#include "gui_gtk.h"
+
+#include "banner.xpm"
+#include "logo.xpm"
+
+/**
+ *  Creates a new BannerEventBox and its content.
+*/
+GuiBanner::GuiBanner()
+{
+  // the banner Frame
+  Frame* bannerFrame;       //!< The frame that holds the Banner.
+  Box* bannerBox;           //!< The box that holds the Banner.
+  EventBox* bannerEventBox; //!< an Image needs an EventBox to catch klicks.
+  Label* bannerLabel;       //!< The Label of the Banner.
+
+  // the logo Window
+  Window* logoWindow;       //!< The Window that holds the Orxonox-CrewLogo.
+  Box* logoBox;             //!< The Box that holds the Orxonox-CrewLogo
+  Image* logoImage;         //!< The Orxonox-CrewLogo-Image
+  Label* logoLabel;         //!< The Label for the Orxonox-CrewLogo
+  Label* orxIsLabel;        //!< Some text about us.
+
+
+  // Banner Itself //
+  bannerEventBox = new EventBox("BannerEventBox");
+  {
+    Image* bannerImage;       //!< The Image for the Banner.
+
+    bannerImage = new Image(banner_xpm);
+    bannerEventBox->fill(bannerImage);
+  }
+  // Banner Window //
+  logoWindow = new Window(PACKAGE_NAME " is:");
+  {
+  EventBox* logoEventBox;   //!< The EventBox that holds the Orxonox-CrewLogo. it has to be an eventbox, because Images can not receive clicks.
+  
+#ifdef HAVE_GTK2
+    bannerEventBox->connectSignal("button_press_event", logoWindow, Window::windowOpen);
+    logoWindow->connectSignal("destroy", logoWindow, Window::windowClose);
+    logoWindow->connectSignal("delete_event", logoWindow, Window::windowClose);
+#endif /* HAVE_GTK2 */
+    logoEventBox = new EventBox();
+    logoBox = new Box('v');
+    logoLabel = new Label(PACKAGE_NAME " v." PACKAGE_VERSION);
+    logoBox->fill(logoLabel);
+    logoImage = new Image(logo_xpm);
+    logoBox->fill(logoImage);
+
+    //! @todo add the names of all the guys working on orxonox
+    orxIsLabel = new Label("           " PACKAGE_NAME " is:\n" ORXONOX_STAFF);
+    logoBox->fill(orxIsLabel);
+    logoEventBox->fill(logoBox);
+#ifdef HAVE_GTK2
+    logoEventBox->connectSignal("button_press_event", logoWindow, Window::windowClose);
+#endif /* HAVE_GTK2 */
+    logoWindow->fill(logoEventBox);
+  }
+  Window::addWindow(logoWindow);
+  
+  setMainWidget(bannerEventBox);
+}
+
+/**
+ *  Destructs it.
+*/
+GuiBanner::~GuiBanner()
+{
+  // nothing to do here
+}
Index: branches/network/src/lib/gui/gtk_gui/gui_banner.h
===================================================================
--- branches/network/src/lib/gui/gtk_gui/gui_banner.h	(revision 6636)
+++ branches/network/src/lib/gui/gtk_gui/gui_banner.h	(revision 6636)
@@ -0,0 +1,22 @@
+/*!
+  \file gui_banner.h
+  \brief  File that holds the class that creates the Banner-Image.\n
+  This is Commercial :-)
+*/
+
+#ifndef _GUI_BANNER_H
+#define _GUI_BANNER_H
+
+#include "gui.h"
+#include "gui_element.h"
+
+//! Class that creates the Banner-Image
+class GuiBanner : public GuiElement
+{
+ public:
+  GuiBanner();
+  ~GuiBanner();
+};
+
+
+#endif /* _GUI_BANNER_H */
Index: branches/network/src/lib/gui/gtk_gui/gui_element.cc
===================================================================
--- branches/network/src/lib/gui/gtk_gui/gui_element.cc	(revision 6636)
+++ branches/network/src/lib/gui/gtk_gui/gui_element.cc	(revision 6636)
@@ -0,0 +1,50 @@
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: ...
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "gui_element.h"
+
+#include "gui_gtk.h"
+
+using namespace std;
+
+
+/**
+ *  standard constructor
+   @todo this constructor is not jet implemented - do it
+*/
+GuiElement::GuiElement () 
+{
+  this->mainWidget = NULL;
+}
+
+
+/**
+ *  standard deconstructor
+
+*/
+GuiElement::~GuiElement () 
+{
+  // delete what has to be deleted here
+}
+
+/**
+ *  Every GuiElement should set this, or it could result in a SegFault.
+*/
+void GuiElement::setMainWidget(Widget* widget)
+{
+  this->mainWidget = widget;
+}
Index: branches/network/src/lib/gui/gtk_gui/gui_element.h
===================================================================
--- branches/network/src/lib/gui/gtk_gui/gui_element.h	(revision 6636)
+++ branches/network/src/lib/gui/gtk_gui/gui_element.h	(revision 6636)
@@ -0,0 +1,28 @@
+/*! 
+ * @file gui_element.h
+  *  Definition of ...
+
+*/
+
+#ifndef _GUI_ELEMENT_H
+#define _GUI_ELEMENT_H
+
+class Widget;
+
+//! A SuperClass for all the Different GuiElements
+class GuiElement {
+
+ public:
+  GuiElement();
+  virtual ~GuiElement();
+  
+  /** @returns the main Widget of this GuiElement. */
+  Widget* getWidget() {return this->mainWidget;}
+ protected:
+  void setMainWidget(Widget* widget);
+  
+ private:
+  Widget* mainWidget;
+};
+
+#endif /* _GUI_ELEMENT_H */
Index: branches/network/src/lib/gui/gtk_gui/gui_exec.cc
===================================================================
--- branches/network/src/lib/gui/gtk_gui/gui_exec.cc	(revision 6636)
+++ branches/network/src/lib/gui/gtk_gui/gui_exec.cc	(revision 6636)
@@ -0,0 +1,401 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+
+*/
+
+#include "gui_exec.h"
+
+#include "resource_manager.h"
+#include "parser/ini_parser/ini_parser.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+
+#ifdef __WIN32__
+#include <direct.h>
+#endif /* __WIN32__ */
+HashTable* orxonoxFlagHash;
+
+/**
+  *  Creates the Exec-Frame
+*/
+GuiExec::GuiExec()
+{
+  Frame* execFrame;            //!< The Frame that holds the ExecutionOptions.
+
+  this->confFile = NULL;
+  this->confDir = NULL;
+
+  execFrame = new Frame("Execute-Tags:");
+  {
+    Box* execBox;                //!< The Box that holds the ExecutionOptions.
+
+    execBox = new Box('v');
+    execFrame->setGroupName(CONFIG_SECTION_MISC);
+    {
+      Button* start;               //!< The start Button of orxonox.
+      Menu* verboseMode;           //!< A Menu for setting the verbose-Mode. @todo setting up a verbose-class.
+      CheckButton* alwaysShow;     //!< A CheckButton, for if orxonox should start with or without gui.
+      Button* quit;                //!< A Button to quit the Gui without starting orxonox.
+
+      start = new Button("Start");
+#ifdef HAVE_GTK2
+      start->connectSignal("clicked", this, startOrxonox);
+#endif /* HAVE_GTK2 */
+      execBox->fill(start);
+      this->saveSettings = new CheckButton(CONFIG_NAME_SAVE_SETTINGS);
+      this->saveSettings->value = 1;
+      this->saveSettings->saveability();
+      execBox->fill(this->saveSettings);
+
+#ifdef DEBUG
+      verboseMode = new Menu(CONFIG_NAME_VERBOSE_MODE, "nothing",
+#if DEBUG >=1
+                             "error",
+#endif
+#if DEBUG >=2
+                             "warning",
+#endif
+#if DEBUG >=3
+                             "info",
+#endif
+#if DEBUG >=4
+                             "debug",
+#endif
+#if DEBUG >=5
+                             "heavydebug",
+#endif
+                             "lastItem");
+      verboseMode->setFlagName("verbose", "v", 2);
+      verboseMode->setDescription("Sets the Output Mode", "This Enables Outbug messages\n"
+                                  "0: nothing will be displayed, but stuff one cannot do without (eg.GUI)\n"
+#if DEBUG >=1
+                                  "1: error: outputs all the above and errors"
+#endif
+#if DEBUG >=2
+                                  "2: warning: outputs all the above plus warnings"
+#endif
+#if DEBUG >=3
+                                  "3: info: outputs all the above plus Information"
+#endif
+#if DEBUG >=4
+                                  "4: debug: displays all the above plus debug information"
+#endif
+#if DEBUG >=5
+                                  "5: heavydebug: displays all the above plus heavy debug information: WARNING: the game will run very slow with this."
+#endif
+                                  );
+      verboseMode->saveability();
+      execBox->fill(verboseMode);
+#endif
+
+      alwaysShow = new CheckButton(CONFIG_NAME_ALWAYS_SHOW_GUI);
+      alwaysShow->setFlagName("gui", "g", 0);
+      alwaysShow->setDescription("shows the gui when starting orxonox");
+      alwaysShow->saveability();
+      execBox->fill(alwaysShow);
+
+      quit = new Button("Quit");
+#ifdef HAVE_GTK2
+      quit->connectSignal("clicked", this, GuiExec::quitGui);
+      //  Window::mainWindow->connectSignal("remove", this, GuiExec::quitGui);
+      Window::mainWindow->connectSignal("destroy", this, GuiExec::quitGui);
+#endif /* HAVE_GTK2 */
+      execBox->fill(quit);
+    }
+    execFrame->fill(execBox);
+  }
+  setMainWidget(execFrame);
+}
+
+/**
+ *  Destructs the Execution-stuff
+*/
+GuiExec::~GuiExec()
+{
+  if(this->confFile)
+    delete []this->confFile;
+  if(this->confDir)
+    delete []this->confDir;
+}
+
+/* FILE HANDLING */
+
+/**
+ *  sets the Directory of the configuration files
+ * @param confDir the Directory for the configuration files
+*/
+void GuiExec::setConfDir(const char* confDir)
+{
+  this->confDir = ResourceManager::homeDirCheck(confDir);
+
+  PRINTF(5)("Config Directory is: %s.\n", this->confDir);
+  //! @todo F** Windows-support
+#ifndef __WIN32__
+  mkdir(this->confDir, 0755);
+#else /* __WiN32__ */
+  mkdir(this->confDir);
+#endif /* __WIN32__ */
+}
+
+/**
+ *  Sets the location of the configuration File.
+ * @param fileName the location of the configFile
+
+   The name will be parsed from ~/ to /home/[username] on unix and c:/Documents and Settings/username/Settings/ on Windows
+*/
+void GuiExec::setConfFile(const char* fileName)
+{
+  if (!this->confDir)
+    this->setConfDir("~/");
+  this->confFile = new char[strlen(this->confDir)+strlen(fileName)+2];
+  sprintf(this->confFile, "%s/%s", this->confDir, fileName);
+  PRINTF(5)("ConfigurationFile is %s.\n", this->confFile);
+}
+
+/**
+ * @returns The name of the Configuration-File
+*/
+const char* GuiExec::getConfigFile() const
+{
+  return this->confFile;
+}
+
+/**
+ *  checks if a option should be saved.
+ * @return 1 if it should 0 if not/
+*/
+int GuiExec::shouldsave()
+{
+  return(static_cast<Option*>(this->saveSettings)->value);
+}
+
+/**
+  *  Saves the configuration-file to the Disk.\n
+  * @param widget from which Widget on should be saved.
+
+    this Function only opens and closes the file, in between GuiExec::writeFileText(Widget* widget) will execute the real writing process.
+*/
+void GuiExec::writeToFile(Widget* widget)
+{
+  IniParser iniParser;
+  this->writeFileText(widget, &iniParser, 0);
+  char* fileName = ResourceManager::homeDirCheck(confFile);
+  iniParser.writeFile(fileName);
+  delete[] fileName;
+}
+
+/**
+ *  Actually writes into the configuration file to the disk.
+ * @param widget from which Widget on should be saved.
+ * @param parser the IniParser to write to.
+ * @param depth initially "0", and grows higher, while new Groups are bundeled.
+*/
+void GuiExec::writeFileText(Widget* widget, IniParser* parser, int depth)
+{
+//   int counter = 0;
+//   while(counter < depth &&((widget->optionType > GUI_NOTHING
+//                               &&(static_cast<Option*>(widget)->isSaveable()))
+//                              ||(widget->optionType < GUI_NOTHING
+//                                 && static_cast<Packer*>(widget)->getGroupName())))
+//     {
+//       fprintf(this->CONFIG_FILE, "  ", depth);
+//       counter++;
+//     }
+
+  // check if it is a Packer, and if it is, check if it has a name and if there is something in it.
+  if(widget->optionType < GUI_NOTHING)
+    {
+      if(static_cast<Packer*>(widget)->getGroupName())
+        {
+          parser->addSection(static_cast<Packer*>(widget)->getGroupName());
+          this->writeFileText(static_cast<Packer*>(widget)->down, parser, depth+1);
+        }
+      else
+        {
+          this->writeFileText(static_cast<Packer*>(widget)->down, parser, depth);
+        }
+    }
+
+  if(widget->optionType > GUI_NOTHING)
+    if (static_cast<Option*>(widget)->isSaveable())
+    {
+      char* saveName = static_cast<Option*>(widget)->save();
+      parser->addVar(static_cast<Option*>(widget)->title, saveName);
+      delete[] saveName;
+    }
+
+  if(widget->next != NULL)
+    this->writeFileText(widget->next, parser, depth);
+}
+
+/**
+ * @brief Reads in Configuration Data.
+ * @param widget from which Widget on should be saved.
+*/
+void GuiExec::readFromFile(Widget* widget)
+{
+  char* fileName = ResourceManager::homeDirCheck(confFile);
+  IniParser iniParser(fileName);
+  delete[] fileName;
+  if (!iniParser.isOpen())
+    return;
+
+  iniParser.firstSection();
+  Widget* groupWidget = widget;
+  const char* groupName;
+  const char* widgetName;
+  VarInfo varInfo;
+  while (groupName = iniParser.getCurrentSection())
+  {
+    printf("GROUP:::%s\n", groupName);
+    if((groupWidget = locateGroup(widget, groupName, 1))==NULL)
+      {
+	PRINTF(2)("!!There is no group called %s in this GUI.\n First best Widget will get the Infos assigned.\n Config-File will be updated in next Save\n", groupName);
+	groupWidget = widget;
+	continue;
+      }
+    else
+      PRINT(4)("Group %s located.\n", static_cast<Packer*>(groupWidget)->groupName);
+
+    const char* entryName;
+    iniParser.firstVar();
+    while(entryName = iniParser.getCurrentName())
+    {
+      PRINTF(4)("ENTRY:::%s = %s\n", entryName, iniParser.getCurrentValue());
+      varInfo.variableName = entryName;
+      varInfo.variableValue = iniParser.getCurrentValue();
+      groupWidget->walkThrough(this->readFileText, &varInfo, 0);
+      iniParser.nextVar();
+    }
+
+    iniParser.nextSection();
+  }
+  widget->walkThrough(widget->setOptions, 0);
+}
+
+/**
+ *  Maps Confugurations to the Options.
+ * @param widget which widget downwards
+ * @param varInfo Information about the Variable to read
+*/
+void GuiExec::readFileText(Widget* widget, void* varInfo)
+{
+  VarInfo* info =(VarInfo*)varInfo;
+  if (info == NULL || info->variableName == NULL)
+    return;
+
+  if(widget->title && !strcmp(widget->title, info->variableName))
+    {
+      PRINT(5)("Located Option %s.\n", widget->title);
+      if(widget->optionType > GUI_NOTHING)
+	if (info->variableValue != NULL)
+	  static_cast<Option*>(widget)->load(info->variableValue);
+    }
+}
+
+/**
+ *  Locates a Group.
+ * @param widget The Widget from where to search from
+ * @param groupName The GroupName for which to search.
+ * @param depth The Depth of the search seen from the first widget we searched from.
+ * @returns The Widget that holds the Group, or the NULL if the Group wasn't found.
+
+   @todo do this in gui-gtk.
+*/
+Widget* GuiExec::locateGroup(Widget* widget, const char* groupName, int depth)
+{
+  Widget* tmp;
+  if (widget  == NULL || groupName == NULL)
+    return NULL;
+
+  if(widget->optionType < GUI_NOTHING)
+    {
+      if(static_cast<Packer*>(widget)->getGroupName() != NULL &&
+         !strcmp(groupName, static_cast<Packer*>(widget)->getGroupName()))
+	return widget;
+      else
+        {
+          if((tmp = locateGroup(static_cast<Packer*>(widget)->down,
+				groupName, depth+1)) != NULL)
+            return tmp;
+        }
+    }
+
+  if(widget->next != NULL && depth != 0)
+    {
+      if((tmp = locateGroup(widget->next, groupName, depth)) != NULL)
+        return tmp;
+    }
+  return NULL;
+}
+
+/**
+ *  Starts ORXONOX.(not really implemented yet, but the function is there.\n
+ * @param widget the widget that executed the start command
+ * @param data additional data
+
+   This is a Signal and can be executed through Widget::signal_connect
+*/
+#ifdef HAVE_GTK2
+int GuiExec::startOrxonox(GtkWidget* widget, void* data)
+#else /* HAVE_GTK2 */
+int GuiExec::startOrxonox(void* widget, void* data)
+#endif /* HAVE_GTK2 */
+{
+  Window::mainWindow->hide();
+
+#ifdef HAVE_GTK2
+  gtk_widget_destroy(Window::mainWindow->widget);
+#else
+  quitGui(widget, data);
+#endif /* HAVE_GTK2 */
+
+  PRINT(3)("Starting Orxonox\n");
+  Gui::startOrxonox = true;
+}
+
+/**
+ *  Starts ORXONOX.(not really implemented yet, but the function is there.\n
+ * @param widget the widget that executed the start command
+ * @param data additional data
+
+   This is a Signal and can be executed through Widget::signal_connect
+*/
+#ifdef HAVE_GTK2
+int GuiExec::quitGui(GtkWidget* widget, void* data)
+#else /* HAVE_GTK2 */
+int GuiExec::quitGui(void* widget, void* data)
+#endif /* HAVE_GTK2 */
+{
+  GuiExec* exec = (GuiExec*)data;
+  if(exec->shouldsave())
+    exec->writeToFile(Window::mainWindow);
+#ifdef HAVE_GTK2
+  gtk_main_quit();
+  while(gtk_events_pending()) gtk_main_iteration();
+#endif /* HAVE_GTK2 */
+}
Index: branches/network/src/lib/gui/gtk_gui/gui_exec.h
===================================================================
--- branches/network/src/lib/gui/gtk_gui/gui_exec.h	(revision 6636)
+++ branches/network/src/lib/gui/gtk_gui/gui_exec.h	(revision 6636)
@@ -0,0 +1,66 @@
+/*!
+ * file gui_exec.h
+ * File that holds the class that creates the execute-Options.
+ */
+
+#ifndef _GUI_EXEC_H
+#define _GUI_EXEC_H
+
+#include "gui.h"
+#include "gui_element.h"
+#include "gui_gtk.h"
+
+class Widget;
+class CheckButton;
+using namespace std;
+class IniParser;
+
+//! Class that creates the execute-Options.
+class GuiExec : public GuiElement
+{
+ private:
+  CheckButton* saveSettings;   //!< A CheckBox for if the Options should be saved.
+
+  char* confDir;               //!< The directory of the orxonox-configuration-files.
+  char* confFile;              //!< The name of the .orxonox.conf(ig)-file.
+
+  //! A struct that holds informations about variables.
+  struct VarInfo
+  {
+    const char* variableName;  //!< The Name of this variable;
+    const char* variableValue; //!< The Value this variable gets.
+  };
+
+ public:
+  GuiExec();
+  ~GuiExec();
+
+  void setConfDir(const char* confDir);
+  void setConfFile(const char* confFile);
+  const char* getConfigFile() const;
+  int shouldsave();
+  void writeToFile(Widget* widget);
+  void writeFileText(Widget* widget, IniParser* parser, int depth);
+  void readFromFile(Widget* widget);
+  static void readFileText(Widget* widget, void* varInfo);
+  Widget* locateGroup(Widget* widget, const char* groupName, int depth);
+
+#ifdef HAVE_GTK2
+  static int startOrxonox(GtkWidget *widget, void* data);
+  static int quitGui(GtkWidget *widget, void* data);
+#else /* HAVE_GTK2 */
+  static int startOrxonox(void* widget, void* data);
+  static int quitGui(void* widget, void* data);
+#endif /* HAVE_GTK2 */
+};
+
+//! A simple hashtable
+struct HashTable
+{
+  char* name;           //!< name of the entry
+  char* value;          //!< value of the entry
+  HashTable* next;      //!< pointer to the next entry
+};
+
+
+#endif /* _GUI_EXEC_H */
Index: branches/network/src/lib/gui/gtk_gui/gui_flags.cc
===================================================================
--- branches/network/src/lib/gui/gtk_gui/gui_flags.cc	(revision 6636)
+++ branches/network/src/lib/gui/gtk_gui/gui_flags.cc	(revision 6636)
@@ -0,0 +1,99 @@
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
+
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+
+*/
+
+#include "gui_flags.h"
+
+/**
+ *  Creates the Flags-Frame
+*/
+GuiFlags::GuiFlags()
+{
+  this->flagsFrame = new Frame("Orxonox-Startup-Flags:");
+  this->flagsBox = new Box('v');
+
+  this->flagsLabel = new Label();
+  this->flagsLabel->setSize(260,60);
+  this->flagsBox->fill(flagsLabel);
+  this->shortFlags = new CheckButton("shortFlags");
+  this->shortFlags->setDefaultValue(0);
+  this->flagsBox->fill(shortFlags);
+
+  this->flagsFrame->fill(flagsBox);
+  this->setMainWidget(flagsFrame);
+}
+
+/**
+ *  Destructs the Flags-stuff
+*/
+GuiFlags::~GuiFlags()
+{
+  // nothing to do here
+}
+
+/**
+ *  Sets the Flags from widget downwards.
+ * @param widget the Widget from which on to scan for deeper Options and their settings.
+*/
+void GuiFlags::setTextFromFlags(Widget* widget)
+{
+  FlagInfo flagInfo;
+  flagInfo.shortFlags = this->shortFlags;
+  flagInfo.flagsLabel = this->flagsLabel;
+
+  this->flagsLabel->ereaseText();
+  this->flagsLabel->appendText(executable);
+  widget->walkThrough(GuiFlags::flagsText, &flagInfo, 0);
+  //  flagsLabel->setTitle(flagText);
+}
+
+/** 
+  *  this actually sets the flagtext, and appends it to flagText
+  * @param widget like GuiFlags::setTextFromFlags(widget)
+  * @param flagInfo Information aboout the Flag that should be updated.
+*/
+void GuiFlags::flagsText(Widget* widget, void* flagInfo)
+{
+  FlagInfo* info =(FlagInfo*)flagInfo;
+  if(widget->optionType > GUI_NOTHING)
+    if (static_cast<Option*>(widget)->value != static_cast<Option*>(widget)->defaultValue )
+      {
+	if(info->shortFlags->isActive() && static_cast<Option*>(widget)->flagNameShort)
+	  {
+	    info->flagsLabel->appendText(" -");
+	    info->flagsLabel->appendText(static_cast<Option*>(widget)->flagNameShort);
+	  }
+	else if(!info->shortFlags->isActive() && static_cast<Option*>(widget)->flagName)
+	  {
+	    info->flagsLabel->appendText(" --");
+	    info->flagsLabel->appendText(static_cast<Option*>(widget)->flagName);
+	  }
+
+	if(static_cast<Option*>(widget)->optionType > GUI_BOOL)
+	  {
+	    info->flagsLabel->appendText("=");
+	    info->flagsLabel->appendInt(static_cast<Option*>(widget)->value);
+	  }
+      }
+}
Index: branches/network/src/lib/gui/gtk_gui/gui_flags.h
===================================================================
--- branches/network/src/lib/gui/gtk_gui/gui_flags.h	(revision 6636)
+++ branches/network/src/lib/gui/gtk_gui/gui_flags.h	(revision 6636)
@@ -0,0 +1,36 @@
+/*!
+  \file gui_flags.h
+  \brief File that holds the class that creates the flags-Text.
+*/
+
+#ifndef _GUI_FLAGS_H
+#define _GUI_FLAGS_H
+
+#include "gui.h"
+#include "gui_element.h"
+#include "gui_gtk.h"
+
+//! Class that creates the flags-Text.
+class GuiFlags : public GuiElement
+{
+ private:
+  Frame* flagsFrame;          //!< The Frame that holds the flagsDisplay.
+  Box* flagsBox;              //!< The Box that holds the flagsDisplay.
+  CheckButton* shortFlags;    //!< CheckButton to change the display of short and long flags @todo show long if long not availible...
+  Label* flagsLabel;          //!< The Label of the Flags
+
+ public:
+  GuiFlags();
+  ~GuiFlags();
+
+  void setTextFromFlags(Widget* widget);
+  static void flagsText(Widget* widget, void* flagInfo);
+  
+  //! Struct that handles flag information.
+  struct FlagInfo
+  {
+    CheckButton* shortFlags;     //!< Button for the flag.
+    Label* flagsLabel;           //!< Label for the flag.
+  };
+};
+#endif /* _GUI_FLAGS_H */
Index: branches/network/src/lib/gui/gtk_gui/gui_gtk.cc
===================================================================
--- branches/network/src/lib/gui/gtk_gui/gui_gtk.cc	(revision 6636)
+++ branches/network/src/lib/gui/gtk_gui/gui_gtk.cc	(revision 6636)
@@ -0,0 +1,1986 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+
+*/
+
+
+#include "gui_gtk.h"
+
+#include <stdarg.h>
+#include <string.h>
+#include <stdlib.h>
+#include <math.h>
+
+using namespace std;
+
+#include "gui_flags.h"
+#include "gui_exec.h"
+
+extern GuiFlags* flags;
+
+char* executable;
+
+/**
+ *  Initializes the Guis GTK-stuff.
+ * @param argc the argument count.
+ * @param argv The Argument strings.
+*/
+bool initGUI(int argc, char *argv[])
+{
+  if (argv)
+    {
+      executable = new char[strlen(argv[0])+1];
+      strcpy(executable, argv[0]);
+    }
+  else
+    executable = NULL;
+
+#ifdef HAVE_GTK2
+  gtk_init(&argc, &argv);
+#include "rc"
+  gtk_rc_parse_string( rc_string );
+#endif /* HAVE_GTK2 */
+}
+
+/**
+ *  enters the GUI's main-loop
+*/
+bool mainloopGUI()
+{
+#ifdef HAVE_GTK2
+  gtk_main();
+#else /* HAVE_GTK2 */
+  char boolAns = 'y';
+  char ans[1000];
+  PRINT(0)("================================\n");
+  PRINT(0)("= ORXONOX CONFIGURATION WIZARD =\n");
+  PRINT(0)("================================ - v." PACKAGE_VERSION "\n");
+
+  while(true)
+    {
+      PRINT(0)("\n Listing all the Orxonox Options: \n");
+      PRINT(0)("  #############################\n");
+      Window::mainWindow->walkThrough(Widget::listOptionsAndGroups, 1);
+
+      PRINT(0)("\nDo you want change any of the above values now? [Yn] ");
+      scanf("%s", ans);
+      if (ans[0] =='n' || ans[0]=='N')
+        break;
+
+      PRINT(0)("\n Listing all groups\n");
+      PRINT(0)("  #################\n");
+      int groupCount = 0;
+      Window::mainWindow->walkThrough(Widget::listGroups, &groupCount, 1);
+
+      PRINT(0)("\nIn which Group? [1-%d] ", groupCount);
+      Packer* group;
+      while(true)
+        {
+          scanf("%s", ans);
+          int ansIp = atoi(ans);
+          if (ansIp <= groupCount)
+            {
+              group = static_cast<Packer*>(Window::mainWindow->findGroupByNumber(&ansIp, 1));
+              break;
+            }
+          else
+            PRINT(0)("\nChoose a smaller Number please: [1-%d] ", groupCount);
+        }
+      PRINT(0)("\n\nGroup: [%s]\n\n", group->groupName);
+      int optionCount = 0;
+      group->walkThrough(Widget::listOptions, &optionCount, 0);
+      PRINT(0)("\nWhich Option? [1-%d] ", optionCount);
+      Option* option;
+      while(true)
+        {
+          scanf("%s", ans);
+          int ansIp = atoi(ans);
+          if (ansIp <= groupCount)
+            {
+              option = static_cast<Option*>(group->findOptionByNumber(&ansIp, 0));
+              break;
+            }
+          else
+            PRINT(0)("\nChoose a smaler Number please: [1-%d] ", optionCount);
+        }
+      PRINT(0)("\n\n:: %s ::\n", option->title);
+      option->changeOption();
+
+      // here follows the rest.... this will be nasty.
+      //! @todo finish it.
+      //! @todo memory leek at save(); and save is a BAD word, use saveString instead, or something like it.
+    }
+#endif /* HAVE_GTK2 */
+
+}
+
+
+//////////////////////////////
+/// DEFINING WIDGET-CLASES ///
+//////////////////////////////
+
+////////////
+/* WIDGET */
+////////////
+/**
+ *  constructs a Widget
+*/
+Widget::Widget()
+{
+  next = NULL;
+  this->title = NULL;
+}
+
+/**
+ *  deletes any given Widget
+   This is still pretty crappy.
+*/
+Widget::~Widget()
+{
+  if (this->title)
+    {
+      delete []this->title;
+    }
+
+  PRINTF(5)("deleting the Widget part.\n");
+
+  // deleting next item if existent
+  if (this->next)
+    delete this->next;
+  this->next = NULL;
+
+  //!  @todo not hiding widget, deleting.
+  //  this->hide();
+  // gtk_destroy_widget(this->widget);
+}
+
+/**
+ *  sets a new Title to a Widget
+ * @param title The new Title to set to the Widget
+*/
+void Widget::setTitle(const char* title)
+{
+  if (this->title)
+    delete []this->title;
+  this->title = new char[strlen(title)+1];
+  strcpy(this->title, title);
+}
+
+/**
+ *  makes the widget visible.
+*/
+void Widget::show()
+{
+#ifdef HAVE_GTK2
+  gtk_widget_show(this->widget);
+#endif /* HAVE_GTK2 */
+}
+
+/**
+ *  hides the widget.
+*/
+void Widget::hide()
+{
+#ifdef HAVE_GTK2
+  gtk_widget_hide(this->widget);
+#endif /* HAVE_GTK2 */
+}
+
+/**
+ *  Sets the resolution of a specific widget to the given size.
+ * @param width the width of the widget to set.
+ * @param height the height of the widget to set.
+*/
+void Widget::setSize(int width, int height)
+{
+#ifdef HAVE_GTK2
+  gtk_widget_set_usize(this->widget, width, height);
+#endif /* HAVE_GTK2 */
+}
+
+/**
+ *  searches through widgets for a Name.
+*/
+Widget* Widget::findWidgetByName(char* name, unsigned int depth)
+{
+
+  if (this->title && !strcmp(this->title, name))
+    return this;
+
+  if (this->optionType < GUI_NOTHING && static_cast<Packer*>(this)->down)
+    {
+      Widget* tmp = static_cast<Packer*>(this)->down->findWidgetByName(name, depth+1);
+      if (tmp)
+        return tmp;
+    }
+
+  if (depth>0 && this->next)
+    return this->next->findWidgetByName(name, depth);
+
+  return NULL;
+}
+
+/**
+ *  Moves through all the Widgets downwards from this and executes the function on them.
+ * @param function must be of type void and takes a Widget* as an Input.
+ * @param depth the current depth. if > 0 then the next Widget will also be walked through.
+*/
+void Widget::walkThrough(void(*function)(Widget*), unsigned int depth)
+{
+  function(this);
+  if (this->optionType < GUI_NOTHING)
+    {
+      static_cast<Packer*>(this)->down->walkThrough(function, depth+1);
+    }
+
+  if (this->next && depth != 0)
+    this->next->walkThrough(function, depth);
+}
+
+/**
+ *  Moves through all the Widgets downwards from this and executes the function on them.
+ * @param function must be of type void and takes a Widget* as an Input.
+ * @param data Additional Data you want to pass to the function.
+ * @param depth the current depth. if > 0 then the next Widget will also be walked through.
+*/
+void Widget::walkThrough(void(*function)(Widget*, void*), void* data, unsigned int depth)
+{
+  function(this, data);
+  if (this->optionType < GUI_NOTHING)
+    {
+      static_cast<Packer*>(this)->down->walkThrough(function, data, depth+1);
+    }
+  if (this->next && depth != 0)
+    this->next->walkThrough(function, data, depth);
+}
+
+/**
+  *  This is for listing the options of "widget"
+  * @param widget specifies the widget that should be listed
+*/
+void Widget::listOptionsAndGroups(Widget* widget)
+{
+  if (widget->optionType < GUI_NOTHING && static_cast<Packer*>(widget)->groupName)
+    PRINT(0)("[%s]\n", static_cast<Packer*>(widget)->groupName);
+  if (widget->optionType > GUI_NOTHING)
+    {
+      Widget::listOptions(widget);
+    }
+}
+
+/**
+  *  This is for listing the options of "widget"
+  * @param widget specifies the widget that should be listed
+*/
+void Widget::listOptions(Widget* widget)
+{
+  if(widget->optionType > GUI_NOTHING)
+    PRINT(0)("  %s is %s\n", static_cast<Option*>(widget)->title, static_cast<Option*>(widget)->save());
+}
+
+/**
+  *  This is for listing the options of "widget"
+  * @param widget specifies the widget that should be listed
+  * @param data A Counter, that always knows how many Options have been found yet.
+*/
+void Widget::listOptions(Widget* widget, void* data)
+{
+
+  if (widget->optionType > GUI_NOTHING)
+    {
+      int* count =(int*)data;
+      *count = *count +1;
+      PRINT(0)(" %d:%s is %s\n", *count,
+               static_cast<Option*>(widget)->title,
+               static_cast<Option*>(widget)->save());
+    }
+}
+
+/**
+  *  This is for listing the options of "widget"
+  * @param widget specifies the widget that should be listed
+  * @param data A Counter, that always knows how many Options have been found yet.
+*/
+void Widget::printHelp(Widget* widget)
+{
+  int helpLen=0;
+
+  if (widget->optionType > GUI_NOTHING)
+    {
+      Option* option = (Option*)widget;
+      if (option->flagName || option->flagNameShort)
+        {
+          PRINT(0)("  ");
+          if (option->flagNameShort)
+            {
+              PRINT(0)("-%s", option->flagNameShort);
+              helpLen += strlen(option->flagNameShort)+1;
+            }
+          if (option->flagName)
+            {
+              if (helpLen > 0)
+                {
+                  PRINT(0)("|");
+                  helpLen++;
+                }
+              PRINT(0)("--%s:", option->flagName);
+              helpLen += strlen(option->flagName)+2;
+            }
+          while ((helpLen ++) < 29)
+            PRINT(0)(" ");
+          if (option->shortDescription)
+            PRINT(0)("%s\n", option->shortDescription);
+          else
+            PRINT(0)("\n");
+        }
+    }
+}
+
+/**
+  *  Finds an Option by a given number(the n'th option found away from this Widget)
+  * @param number The Count of options to wait(by reference)
+  * @param depth The depth of the sarch. if 0 it will not search next pointer
+
+    @todo should return Option* would be much sexier.
+*/
+Widget* Widget::findOptionByNumber(int* number, unsigned int depth)
+{
+  if (optionType > GUI_NOTHING)
+    {
+      --*number;
+      if (*number <= 0)
+        {
+          return this;
+        }
+    }
+  if (this->optionType < GUI_NOTHING && static_cast<Packer*>(this)->down)
+    {
+      Widget* tmp = static_cast<Packer*>(this)->down->findOptionByNumber(number, depth+1);
+      if (tmp)
+        return tmp;
+    }
+  if (depth>0 && this->next)
+    return this->next->findOptionByNumber(number, depth);
+
+  return NULL;
+}
+
+/**
+  *  This is for listing the groups of "widget"
+  * @param widget specifies the widget that should be listed
+*/
+void Widget::listGroups(Widget* widget)
+{
+  if (widget->optionType < GUI_NOTHING && static_cast<Packer*>(widget)->groupName)
+    PRINT(0)("[%s]\n", static_cast<Packer*>(widget)->groupName);
+}
+
+/**
+  *  This is for listing the Groups of "widget". It also displays the n'th number found.
+  * @param widget specifies the widget that should be listed
+  * @param data the Counter, that will show the number(this function will raise it by one if a Group is fount.
+*/
+void Widget::listGroups(Widget* widget, void* data)
+{
+  int* count = (int*)data;
+  if (widget->optionType < GUI_NOTHING && static_cast<Packer*>(widget)->groupName)
+    PRINT(0)("%d: [%s]\n", ++*count, static_cast<Packer*>(widget)->groupName);
+}
+
+/**
+  *  Finds a Group by a given number(the n'th Group found away from this Widget)
+  * @param number The Count of options to wait(by reference)
+  * @param depth The depth of the sarch. if 0 it will not search next pointer
+*/
+Widget* Widget::findGroupByNumber(int* number, unsigned int depth)
+{
+  if (optionType < GUI_NOTHING && static_cast<Packer*>(this)->groupName)
+    {
+      --*number;
+      if (*number <= 0)
+        {
+          return this;
+        }
+    }
+  if (this->optionType < GUI_NOTHING && static_cast<Packer*>(this)->down)
+    {
+      Widget* tmp = static_cast<Packer*>(this)->down->findGroupByNumber(number, depth+1);
+      if (tmp)
+        return tmp;
+    }
+  if (depth>0 && this->next)
+    return this->next->findGroupByNumber(number, depth);
+
+  return NULL;
+}
+
+/**
+  *  This is for setting the option of "widget"
+  * @param widget specifies the widget that should be set.
+*/
+void Widget::setOptions(Widget* widget)
+{
+  if (widget->optionType > GUI_NOTHING)
+    static_cast<Option*>(widget)->redraw();
+}
+
+/**
+ *  redraws all the Widgets down from widget
+ * @param widget The topmost Widget
+ * @param data ...
+*/
+void Widget::redrawOptions(Widget* widget)
+{
+  if (widget->optionType > GUI_NOTHING)
+    static_cast<Option*>(widget)->redraw();
+}
+
+/**
+ *  Walks through all the Flags given at startuptime.
+*/
+void Widget::flagCheck(Widget* widget, void* flagName)
+{
+  if (widget->optionType > GUI_NOTHING)
+    {
+      Option* option =(Option*)widget;
+      char* name =(char*)flagName;
+      char* value = NULL;
+      bool found = false;
+      // check if long flag matches
+      if ((option->flagName && strlen(name) > 2 &&
+           !strncmp(name+2, option->flagName, strlen(option->flagName)) &&
+           (name[strlen(option->flagName)+2] == '\0' || name[strlen(option->flagName)+2] == '=') ))
+        {
+          found = true;
+          if (name[strlen(option->flagName)+2] == '=')
+            {
+              value = name+strlen(option->flagName)+3;
+            }
+        }
+      // check if short flag matches
+      else if (option->flagNameShort && strlen(name)>1 &&
+               !strncmp(name+1, option->flagNameShort, strlen(option->flagNameShort)) &&
+               (name[strlen(option->flagNameShort)+1] == '\0' || name[strlen(option->flagNameShort)+1] == '='))
+        {
+          found = true;
+          if (name[strlen(option->flagNameShort)+1] == '=')
+            {
+              value = name+strlen(option->flagNameShort)+2;
+            }
+        }
+
+      if (found)
+        {
+          PRINT(4)("found matching Flag %s\n", name);
+          if (value)
+            {
+              PRINT(4)("with Value %s\n", value);
+              option->value = atoi(value);
+            }
+          else
+            {
+              option->value = !option->defaultValue;
+            }
+          option->redraw();
+        }
+
+    }
+}
+
+#ifdef HAVE_GTK2
+/**
+  *  Connect any signal to any given Sub-widget
+*/
+gulong Widget::connectSignal(char* event, gint(*signal)(GtkWidget*, GdkEvent*, void *))
+{
+  return g_signal_connect(G_OBJECT(this->widget), event, G_CALLBACK(signal), NULL);
+}
+
+/**
+ *  Connect a signal with additionally passing the whole Object
+*/
+gulong Widget::connectSignal(char* event, gint(*signal)( GtkWidget*, Widget *))
+{
+  return g_signal_connect(G_OBJECT(this->widget), event, G_CALLBACK(signal), this);
+}
+
+/**
+ *  Connect a signal with additionally passing a whole external Object
+*/
+gulong Widget::connectSignal(char* event, void* extObj, gint(*signal)(GtkWidget*, GdkEvent*, void *))
+{
+  return g_signal_connect(G_OBJECT(this->widget), event, G_CALLBACK(signal), extObj);
+}
+
+/**
+ *  Connect a signal with additionally passing a whole external Object
+*/
+gulong Widget::connectSignal(char* event, void* extObj, gint(*signal)(GtkWidget*, void *))
+{
+  return g_signal_connect(G_OBJECT(this->widget), event, G_CALLBACK(signal), extObj);
+}
+
+/**
+ *  Connect a signal with additionally passing a whole external Object
+*/
+gulong Widget::connectSignal(char* event, void* extObj, gint(*signal)(GtkWidget*, GdkEventKey*, void *))
+{
+  return g_signal_connect(G_OBJECT(this->widget), event, G_CALLBACK(signal), extObj);
+}
+
+void Widget::disconnectSignal(gulong signalID)
+{
+  g_signal_handler_disconnect(G_OBJECT(this->widget), signalID);
+}
+
+/**
+ *  Signal that does absolutely nothing
+ * @param widget The widget that initiated the Signal
+ * @param event The event-type.
+ * @param nothing nothin.
+*/
+gint Widget::doNothingSignal(GtkWidget *widget, GdkEvent* event, void* nothing)
+{
+}
+#endif /* HAVE_GTK2 */
+
+/////////////
+/* PACKERS */
+/////////////
+/**
+ *  Constructs a Packer
+*/
+Packer::Packer()
+{
+  this->down = NULL;
+  this->groupName = NULL;
+}
+
+/**
+ *  Destroys a Packer.
+*/
+Packer::~Packer()
+{
+  PRINTF(5)("deleting the Packer part.\n");
+  if (this->groupName)
+    delete []this->groupName;
+
+  //deleting recursively.
+  if (this->down)
+    delete this->down;
+}
+
+/**
+ *  Sets the group name under which all the lower widgets of this will be saved.
+ * @param name The name of the group.
+*/
+void Packer::setGroupName(const char* name)
+{
+  if (this->groupName)
+    delete []this->groupName;
+  this->groupName = new char[strlen(name)+1];
+  strcpy(this->groupName, name);
+}
+
+////////////////
+/* CONTAINERS */
+////////////////
+/**
+ *  Initializes a Container.
+
+   sets the Container-Specific defaults.
+*/
+Container::Container()
+{
+  this->optionType = GUI_CONTAINER;
+}
+
+/**
+ *  Destroys a Container.
+*/
+Container::~Container()
+{
+  PRINTF(5)("deleting the Container part.\n");
+}
+
+/**
+ * Fills a Container with lowerWidget.
+ * @param lowerWidget the Widget that should be filled into the Container.
+
+   It does this by filling up the down pointer only if down points to NULL.
+*/
+void Container::fill(Widget* lowerWidget)
+{
+  if (this->down == NULL)
+    {
+#ifdef HAVE_GTK2
+      gtk_container_add(GTK_CONTAINER(this->widget), lowerWidget->widget);
+#endif /* HAVE_GTK2 */
+
+      this->down = lowerWidget;
+    }
+  else
+    PRINTF(2)("You tried to put more than one Widget into a Container. \nNot including this item.\nThis is only possible with Boxes.\n");
+}
+
+/**
+ * @param borderwidth sets the Width of the border
+*/
+void Container::setBorderWidth(int borderwidth)
+{
+  this->borderwidth = borderwidth;
+
+#ifdef HAVE_GTK2
+  gtk_container_set_border_width(GTK_CONTAINER(widget), borderwidth);
+#endif /* HAVE_GTK2 */
+}
+
+////////////
+/* WINDOW */
+////////////
+
+/**
+ *  The main Window of Th Gui
+*/
+Window* Window::mainWindow = NULL;
+
+/**
+ *  Creating a Window with a name
+ * @param windowName the name the window should get.
+*/
+Window::Window(const char* windowName)
+{
+  if (!mainWindow)
+    {
+      mainWindow = this;
+      this->isOpen = true;
+    }
+  isOpen = false;
+
+#ifdef HAVE_GTK2
+  widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_policy(GTK_WINDOW(widget), TRUE, TRUE, TRUE);
+#if !defined(__WIN32__)
+  //  gtk_window_set_decorated(GTK_WINDOW(widget), FALSE);
+#endif
+  gtk_container_set_border_width(GTK_CONTAINER(widget), 3);
+#endif /* HAVE_GTK2 */
+
+  if (windowName)
+    this->setTitle(windowName);
+}
+
+/**
+ *  Destructs a Window.
+*/
+Window::~Window()
+{
+  PRINTF(5)("deleting the Window: %s\n", this->title);
+}
+
+/**
+ *  Adds a new Window Windows to the List of Windows.
+ * @param windowToAdd The Windows that should be added to the List
+   @todo this instead of windowToAdd(possibly)
+*/
+void Window::addWindow(Window* windowToAdd)
+{
+  if (!mainWindow)
+    {
+      mainWindow = windowToAdd;
+      windowToAdd->isOpen = true;
+    }
+  else
+    {
+      Widget* tmpWindow = mainWindow;
+      while(tmpWindow->next)
+        tmpWindow = tmpWindow->next;
+      tmpWindow->next = windowToAdd;
+      windowToAdd->isOpen = false;
+    }
+  return;
+}
+
+/**
+ *  Shows all Widgets that are included within this->widget.
+*/
+void Window::showall()
+{
+#ifdef HAVE_GTK2
+  if (!this->isOpen)
+    gtk_widget_show_all(this->widget);
+  else
+    gtk_widget_show(this->widget);
+#endif /* HAVE_GTK2 */
+}
+
+/**
+ *  Set The Window-title to title
+ * @param title title the Window should get.
+*/
+void Window::setTitle(const char* title)
+{
+  if (this->title)
+    delete []this->title;
+  this->title = new char[strlen(title)+1];
+  strcpy(this->title, title);
+#ifdef HAVE_GTK2
+  gtk_window_set_title(GTK_WINDOW(widget), title);
+#endif /* HAVE_GTK2 */
+}
+
+/**
+ *  opens up a Window and fixes the Focus to it
+*/
+void Window::open()
+{
+  if (this != mainWindow)
+    {
+      isOpen = true;
+#ifdef HAVE_GTK2
+      gtk_widget_show_all(this->widget);
+      gtk_grab_add(this->widget);
+#endif /* HAVE_GTK2 */
+    }
+}
+
+/**
+ *  closes up a Window and removes the Focus from it
+*/
+void Window::close()
+{
+  if (this != mainWindow)
+    {
+      this->isOpen = false;
+#ifdef HAVE_GTK2
+      gtk_grab_remove(this->widget);
+      gtk_widget_hide(this->widget);
+#endif /* HAVE_GTK2 */
+    }
+}
+
+/**
+ *  opens up a window(not topmost Window).
+   this is the Signal that does it. !!SIGNALS ARE STATIC!!
+ * @param widget the widget that did it.
+ * @param event the event that did it.
+ * @param window the Window that should be opened
+*/
+#ifdef HAVE_GTK2
+gint Window::windowOpen(GtkWidget* widget, GdkEvent* event, void* window)
+{
+  static_cast<Window*>(window)->open();
+}
+#else /* HAVE_GTK2 */
+int Window::windowOpen(void* widget, void* event, void* window){}
+#endif /* HAVE_GTK2 */
+
+/**
+ *  closes a window(not topmost Window).
+   this is the Signal that does it. !!SIGNALS ARE STATIC!!
+ * @param widget the widget that did it!
+ * @param event the event that did it!
+ * @param window the Window that should be closed
+*/
+#ifdef HAVE_GTK2
+gint Window::windowClose(GtkWidget* widget, GdkEvent* event, void* window)
+{
+  static_cast<Window*>(window)->close();
+}
+#else /* HAVE_GTK2 */
+int Window::windowClose(void* widget, void* event, void* window){}
+#endif /* HAVE_GTK2 */
+
+///////////
+/* FRAME */
+///////////
+/**
+ *  Creates a new Frame with name title
+*/
+Frame::Frame(const char* frameName)
+{
+#ifdef HAVE_GTK2
+  this->widget = gtk_frame_new("");
+  gtk_container_set_border_width(GTK_CONTAINER(this->widget), 3);
+#endif /* HAVE_GTK2 */
+  if (frameName)
+    this->setTitle(frameName);
+}
+
+/**
+ *  destrcucts a Frame
+*/
+Frame::~Frame()
+{
+  PRINTF(5)("deleting the Frame: %s\n", this->title);
+}
+
+/**
+ *  Sets the Frames name to title
+ * @param title The title the Frame should get.
+*/
+void Frame::setTitle(const char* title)
+{
+  if (this->title)
+    delete []this->title;
+  this->title = new char[strlen(title)+1];
+  strcpy(this->title, title);
+#ifdef HAVE_GTK2
+  gtk_frame_set_label(GTK_FRAME(widget), this->title);
+#endif /* HAVE_GTK2 */
+}
+
+//////////////
+/* EVENTBOX */
+//////////////
+/**
+ *  Creates a new EventBox with name title
+ * @param eventBoxName title the Eventbox should get(only data-structure-internal)
+*/
+EventBox::EventBox(const char* eventBoxName)
+{
+#ifdef HAVE_GTK2
+  this->widget = gtk_event_box_new();
+  gtk_container_set_border_width(GTK_CONTAINER(this->widget), 3);
+#endif /* HAVE_GTK2 */
+
+  if (eventBoxName)
+    this->setTitle(eventBoxName);
+}
+
+/**
+ *  destructs an EventBox.
+*/
+EventBox::~EventBox()
+{
+  PRINTF(5)("deleting the EventBox: %s\n", this->title);
+}
+
+/////////
+/* BOX */
+/////////
+/**
+ *  Creates a new Box of type boxtype
+ * @param boxtype if 'v' the Box will be vertically, if 'h' the Box will be horizontally
+*/
+Box::Box(char boxtype)
+{
+  this->optionType = GUI_BOX;
+
+#ifdef HAVE_GTK2
+  if (boxtype == 'v')
+    this->widget = gtk_vbox_new(FALSE, 0);
+  else
+    this->widget = gtk_hbox_new(FALSE, 0);
+#endif /* HAVE_GTK2 */
+}
+
+/**
+ *  destructs a Box.
+*/
+Box::~Box()
+{
+  PRINTF(5)("deleting the Box: %s\n", this->title);
+}
+
+/**
+  *  Fills a box with a given Widget.
+  * @param lowerWidget the next Widget that should be appendet to this Box
+
+    It does this by apending the first one to its down-pointer and all its following ones to the preceding next-pointer. The last one will receive a NULL pointer as Next
+*/
+void Box::fill(Widget* lowerWidget)
+{
+#ifdef HAVE_GTK2
+  gtk_box_pack_start(GTK_BOX(this->widget), lowerWidget->widget, TRUE, TRUE, 0);
+#endif /* HAVE_GTK2 */
+  if (this->down == NULL)
+    this->down = lowerWidget;
+  else
+    {
+      Widget* tmp;
+      tmp = this->down;
+      while(tmp->next != NULL)
+        tmp = tmp->next;
+      tmp->next = lowerWidget;
+    }
+}
+
+////////////
+/* OPTION */
+////////////
+/**
+ *  Initializes a new Option.
+   sets all Option-Specific-Values to their defaults.
+*/
+Option::Option()
+{
+  this->value = 0;
+  this->flagName = NULL;
+  this->flagNameShort = NULL;
+
+  this->shortDescription = NULL;
+  this->longDescription = NULL;
+
+  this->saveable = false;
+  this->defaultValue = 0;
+}
+
+/**
+ *  Destroys an Option.
+*/
+Option::~Option()
+{
+  PRINTF(5)("deleting the Option Part.\n");
+  if (this->flagName)
+    delete []this->flagName;
+  if (this->flagNameShort)
+    delete []this->flagNameShort;
+  if (this->shortDescription)
+    delete []this->shortDescription;
+  if (this->longDescription)
+    delete []this->longDescription;
+}
+
+/**
+ * @param defaultValue new defaultValue for this option
+*/
+void Option::setDefaultValue(int defaultValue)
+{
+  this->value = this->defaultValue = defaultValue;
+}
+
+/**
+ *  This sets The FlagName of an Option and defines its default Values
+   !! Options will be saved if flagname is different from NULL !!
+ * @param flagname the Name that will be displayed in the output
+ * @param defaultvalue the default Value for this Option(see definition of defaultvalue
+*/
+void Option::setFlagName(const char* flagname, int defaultvalue)
+{
+  if (this->flagName)
+    delete this->flagName;
+  this->flagName = new char [strlen(flagname)+1];
+  strcpy(this->flagName, flagname);
+
+  this->setDefaultValue(defaultvalue);
+
+  if (this->flagNameShort)
+    {
+      delete this->flagNameShort;
+      this->flagNameShort = NULL;
+    }
+
+  //  cout << "Set Flagname of " << this->title << " to " << flagname << endl;
+}
+
+/**
+  *  see Option::setFlagName(char* flagname, int defaultvalue)
+  * @param flagname the Name that will be displayed in the output
+  * @param defaultvalue the default Value for this Option(see definition of defaultvalue
+  * @param flagnameshort a short flagname to be displayed in the output
+*/
+void Option::setFlagName(const char* flagname, const char* flagnameshort,  int defaultvalue)
+{
+  if (this->flagName)
+    delete []this->flagName;
+  this->flagName = new char [strlen(flagname)+1];
+  strcpy(this->flagName, flagname);
+
+  if (this->flagNameShort)
+    delete []this->flagNameShort;
+  this->flagNameShort = new char [strlen(flagnameshort)+1];
+  strcpy(this->flagNameShort, flagnameshort);
+  this->setDefaultValue(defaultvalue);
+  //  cout << "Set Flagname of " << this->title << " to " << flagname << endl;
+}
+
+void Option::setDescription(const char* shortDescription, const char* longDescription)
+{
+  // setting up the short description
+  if (this->shortDescription)
+    delete []this->shortDescription;
+  this->shortDescription = new char [strlen(shortDescription)+1];
+  strcpy(this->shortDescription, shortDescription);
+
+  //setting up the long description
+  if (this->longDescription)
+    delete []this->longDescription;
+  if (longDescription)
+    {
+      this->longDescription = new char [strlen(longDescription)+1];
+      strcpy(this->longDescription, longDescription);
+    }
+  else
+    this->longDescription = NULL;
+}
+
+/**
+ *  Sets the saveable-state of the option.
+ * @param isSaveable the saveable-state to set.
+*/
+void Option::saveability(bool isSaveable)
+{
+  this->saveable = isSaveable;
+}
+
+/**
+ *  saves an Option
+ * @returns the String that should be saved. (this string __should__ be deleted)
+
+   this is a default Option save
+*/
+char* Option::save()
+{
+  char* value = new char [30];
+  sprintf (value, "%d", this->value);
+  return value;
+}
+
+/**
+ *  loads an Option from of its loadString
+ * @param loadString the string from which to load the data from
+*/
+void Option::load(const char* loadString)
+{
+  this->value = atoi(loadString);
+  PRINT(5)("Loading %s: %s %d\n", this->title, loadString, value);
+  this->redraw();
+}
+
+/**
+ * @returns The saveable-state.
+*/
+bool Option::isSaveable()
+{
+  return this->saveable;
+}
+
+#ifdef HAVE_GTK2
+/**
+  *  Signal OptionChange writes the Value from the Option to its Object-Database.
+  * @param widget The widget(Option) that has a changed Value
+  * @param option the Option-Object that should receive the change.
+*/
+gint Option::OptionChange(GtkWidget *widget, Widget* option)
+{
+  static_cast<Option*>(option)->changeOption();
+#ifdef BUILD_ORXONOX
+  flags->setTextFromFlags(Window::mainWindow);
+#endif
+}
+#endif /* HAVE_GTK2 */
+
+////////////
+/* BUTTON */
+////////////
+/**
+ *  Creates a new Button with a buttonname
+ * @param buttonName sets the Name of the Button
+*/
+Button::Button(const char* buttonName)
+{
+  this->optionType = GUI_NOTHING;
+
+#ifdef HAVE_GTK2
+  widget = gtk_button_new_with_label("");
+#endif /* HAVE_GTK2 */
+
+  if (buttonName)
+    this->setTitle(buttonName);
+}
+
+/**
+ *  destructs a Button.
+*/
+Button::~Button()
+{
+  PRINTF(5)("deleting the Label: %s\n", this->title);
+}
+
+/**
+ *  Sets a new name to the Button
+ * @param title The name the Button should get
+*/
+void Button::setTitle(const char *title)
+{
+  if (this->title)
+    delete []this->title;
+  this->title = new char[strlen(title)+1];
+  strcpy(this->title, title);
+#ifdef HAVE_GTK2
+  gtk_button_set_label(GTK_BUTTON(widget), title);
+#endif /* HAVE_GTK2 */
+}
+
+/**
+ *  redraws the Button
+   @todo not implemented yet
+*/
+void Button::redraw()
+{
+}
+
+/**
+ *  Button can not be changed, optionChange is empty)
+
+   @todo Actions for non-GTK-mode
+*/
+void Button::changeOption()
+{
+  // This will possibly be used for ACTIONS !
+}
+
+/////////////////
+/* CHECKBUTTON */
+/////////////////
+/**
+ *  Creates a new CheckButton with an ame
+ * @param buttonName The name the CheckButton should display.
+*/
+CheckButton::CheckButton(const char* buttonName)
+{
+  this->optionType = GUI_BOOL;
+
+#ifdef HAVE_GTK2
+  this->widget = gtk_check_button_new_with_label("");
+#endif /* HAVE_GTK2 */
+
+  if (buttonName)
+    this->setTitle(buttonName);
+
+#ifdef HAVE_GTK2
+  this->connectSignal("clicked", this->OptionChange);
+#endif /* HAVE_GTK2 */
+}
+
+/**
+ *  destructs a CheckButton.
+*/
+CheckButton::~CheckButton()
+{
+  if (this->title)
+    PRINTF(5)("deleting the CheckButton: %s\n", this->title);
+  else
+    PRINTF(5)("deleting the CheckButton.\n");
+}
+
+/**
+ *  Sets a new Title to a CheckButton
+ * @param title The new Name the CheckButton should display.
+*/
+void CheckButton::setTitle(const char* title)
+{
+  if (this->title)
+    delete []this->title;
+  this->title = new char[strlen(title)+1];
+  strcpy(this->title, title);
+#ifdef HAVE_GTK2
+  gtk_button_set_label(GTK_BUTTON(widget), title);
+#endif /* HAVE_GTK2 */
+}
+
+/**
+ * @returns the Active state of the checkButton
+*/
+bool CheckButton::isActive()
+{
+#ifdef HAVE_GTK2
+  return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+#endif /* HAVE_GTK2 */
+}
+
+/**
+ *  Changed the Option, call this Function
+*/
+void CheckButton::changeOption()
+{
+#ifdef HAVE_GTK2
+  this->value =(int)gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(this->widget));
+#else /* HAVE_GTK2 */
+  char tmpChar[200];
+  PRINT(0)("\nPlease give me a new value for %s [0,1](default:%d): ",this->title, this->defaultValue);
+  scanf("%s", tmpChar);
+
+  if ((this->value = atoi(tmpChar))=!0)
+    this->value = 1;
+
+  PRINT(0)("%s set to: %d\n", this->title, this->value);
+#endif /* HAVE_GTK2 */
+}
+
+/**
+ *  Redraws the CheckButton(if option has changed).
+   Example: if new settings are loaded the Button must be redrawn for the GUI to display that Change
+*/
+void CheckButton::redraw()
+{
+#ifdef HAVE_GTK2
+  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(this->widget), value);
+#endif /* HAVE_GTK2 */
+}
+
+////////////
+/* SLIDER */
+////////////
+/**
+ *  Creates a new Slider
+ * @param slidername The data-structure-name of the slider.
+ * @param start The minimal Value of the slider.
+ * @param end The maximal Value of the slider.
+*/
+Slider::Slider(const char* slidername, float start, float end)
+{
+  this->optionType = GUI_FLOAT;
+
+  this->start = start;
+  this->end = end;
+#ifdef HAVE_GTK2
+ widget = gtk_hscale_new_with_range(this->start, this->end, 5);
+#endif /* HAVE_GTK2 */
+
+  this->setValue(start);
+  this->setTitle(slidername);
+#ifdef HAVE_GTK2
+  this->connectSignal("value_changed", this->OptionChange);
+#endif /* HAVE_GTK2 */
+}
+
+/**
+ *  destructs a Slider.
+*/
+Slider::~Slider()
+{
+  PRINTF(5)("deleting the Slider: %s\n", this->title);
+}
+
+/**
+ *  sets the exactness of the widget
+ * @param exactness count of digits after the dot
+*/
+void Slider::setExactness(int exactness)
+{
+#ifdef HAVE_GTK2
+ gtk_scale_set_digits(GTK_SCALE(this->widget), exactness);
+ gtk_range_set_increments(GTK_RANGE(this->widget), pow(.1, exactness), pow(.1, exactness-1));
+#endif /* HAVE_GTK2 */
+}
+
+/**
+ *  Setting a new value to the Slider.
+   Maybe you also require a Slider::redraw() for this to display
+*/
+void Slider::setValue(float value)
+{
+  this->fValue = value;
+}
+
+/**
+ *  Redraws the widget
+   Example: see void CheckButton::redraw()
+*/
+void Slider::redraw()
+{
+#ifdef HAVE_GTK2
+  gtk_range_set_value(GTK_RANGE(this->widget), this->fValue);
+#endif /* HAVE_GTK2 */
+}
+
+/**
+ *  Changed the Option, call this Function
+*/
+void Slider::changeOption()
+{
+#ifdef HAVE_GTK2
+  this->fValue = gtk_range_get_value(GTK_RANGE(this->widget));
+#else /* HAVE_GTK2 */
+  char tmpChar[20];
+  PRINT(0)("\nPlease give me a new value for %s [%d-%d] (default:%d): ", this->title, this->start, this->end, this->defaultValue);
+  scanf("%s", tmpChar);
+
+  if ((this->fValue = atof(tmpChar))> this->end)
+    this->fValue = this->end;
+  if (this->fValue <= this->start)
+    this->fValue = this->start;
+
+  PRINT(0)("%s set to: %d\n",this->title, this->fValue);
+#endif /* HAVE_GTK2 */
+}
+
+char* Slider::save()
+{
+  char* value = new char [30];
+  sprintf (value, "%f", this->fValue);
+  return value;
+}
+void Slider::load(const char* loadString)
+{
+  this->fValue = atof(loadString);
+  PRINT(5)("Loading %s: %s %f\n", this->title, loadString, fValue);
+  this->redraw();
+}
+
+
+//////////
+/* MENU */
+//////////
+/**
+ *  constructs a new Menu, without adding any items to it.
+ * @param menuName the Name the Menu gets.
+*/
+Menu::Menu(const char* menuName)
+{
+  this->init();
+  this->setTitle(menuName);
+}
+
+/**
+  *  Creates a Menu-Item-list out of multiple input.
+    !! Consider, that the last input argument has to be "lastItem" for this to work!!
+  * @param menuname The Database-Name of this Menu
+  * @param ... items to be added to this Menu. !! Consider, that the last input argument has to be "lastItem" for this to work!!
+*/
+Menu::Menu(char* menuname, ...)
+{
+  this->init();
+  this->setTitle(menuname);
+  va_list itemlist;                     //!< The list to readin multiple Options.
+
+  char *itemName;
+
+  va_start(itemlist, menuname);
+  while(strcmp(itemName = va_arg(itemlist, char*), "lastItem"))
+    {
+      this->addItem(itemName);
+    }
+  va_end(itemlist);
+}
+
+/**
+ *  destructs a Menu.
+*/
+Menu::~Menu()
+{
+  PRINTF(5)("deleting the Menu: %s\n", this->title);
+  this->currItem = this->firstItem;
+  while(this->currItem)
+    {
+      delete []this->currItem->name;
+      //! @todo destroy menu
+      /*
+        #ifdef HAVE_GTK2
+        gtk_widget_destroy(this->currItem->item);
+        #endif /* HAVE_GTK2 */
+      MenuItem* tmpItem = this->currItem;
+      this->currItem = this->currItem->next;
+      delete tmpItem;
+    }
+}
+
+/**
+ *  Initializes a new Menu with no items
+*/
+void Menu::init()
+{
+  this->optionType = GUI_INT;
+  this->firstItem = NULL;
+
+#ifdef HAVE_GTK2
+  this->widget = gtk_option_menu_new();
+  this->menu = gtk_menu_new();
+  gtk_option_menu_set_menu(GTK_OPTION_MENU(this->widget), menu);
+  this->connectSignal("changed", this->OptionChange);
+#endif /* HAVE_GTK2 */
+}
+
+/**
+ *  saves the Label of the Menu
+ * @returns the name of the selected Menu-Item
+*/
+char* Menu::save()
+{
+  MenuItem* tmpItem = this->firstItem;
+  for (int i = 0; i < this->value; i++)
+    if (tmpItem)
+      tmpItem = tmpItem->next;
+    else
+      break;
+  if (tmpItem)
+    {
+      char* tmpName = new char[strlen(tmpItem->name)+1];
+      strcpy(tmpName, tmpItem->name);
+      return tmpName;
+    }
+  else
+    return NULL;
+}
+
+/**
+ *  loads a Menu from of its loadString
+ * @param loadString the string from which to load the data from
+*/
+void Menu::load(const char* loadString)
+{
+  MenuItem* tmpItem = firstItem;
+  bool foundItem = false;
+  while (tmpItem)
+    {
+      if (!strcmp(loadString, tmpItem->name))
+        {foundItem = true; break;}
+      tmpItem = tmpItem->next;
+    }
+  if (foundItem)
+    this->value = tmpItem->itemNumber;
+  else
+    {
+      this->value = 0;
+      PRINTF(2)("%s has not been found in the Itemlist of %s\n", loadString, this->title);
+    }
+  PRINTF(5)( "Loading %s: setting to %d\n", this->title, this->value);
+  this->redraw();
+}
+
+/**
+ *  appends a new Item to the Menu-List.
+ * @param itemName the itemName to be appendet.
+*/
+void Menu::addItem(char* itemName)
+{
+  if (!this->firstItem)
+    {
+      this->firstItem = this->currItem = new MenuItem;
+      this->currItem->itemNumber = 0;
+    }
+  else
+    {
+      int tmpI = this->currItem->itemNumber;
+      this->currItem = this->currItem->next = new MenuItem;
+      this->currItem->itemNumber = tmpI+1;
+    }
+
+  this->currItem->name = new char[strlen(itemName)+1];
+  strcpy(this->currItem->name, itemName);
+
+#ifdef HAVE_GTK2
+  this->currItem->item = gtk_menu_item_new_with_label(itemName);
+  gtk_menu_shell_append(GTK_MENU_SHELL(this->menu), this->currItem->item);
+#endif /* HAVE_GTK2 */
+  this->currItem->next = NULL;
+}
+
+/**
+ *  Redraws the widget
+   Example: see void CheckButton::redraw()
+*/
+void Menu::redraw()
+{
+#ifdef HAVE_GTK2
+  gtk_option_menu_set_history(GTK_OPTION_MENU(this->widget), this->value);
+#endif /* HAVE_GTK2 */
+}
+
+/**
+ *  Changed the Option, call this Function
+*/
+void Menu::changeOption()
+{
+#ifdef HAVE_GTK2
+  this->value =(int)gtk_option_menu_get_history(GTK_OPTION_MENU(this->widget));
+#else /* HAVE_GTK2 */
+  char tmpChar[20];
+  PRINT(0)("\nPlease give me a new value for %s (default: %d): ", this->title, this->defaultValue);
+  scanf("%s",tmpChar);
+  this->value = atoi(tmpChar);
+
+#endif /* HAVE_GTK2 */
+  PRINT(4)("%s set to: %d\n", this->title, this->value);
+}
+
+/* OPTION LABEL */
+
+/**
+ *  Creates a new OptionLabel with a LabelName and a Value.
+ * @param label The name of the OptionLabel.
+ * @param value The Value of the OptionLabel(what will be displayed).
+*/
+OptionLabel::OptionLabel(const char* label, const char* value)
+{
+  this->optionType = GUI_CHAR_ARRAY;
+  cValue = NULL;
+
+#ifdef HAVE_GTK2
+  this->widget = gtk_label_new("");
+#endif /* HAVE_GTK2 */
+
+  this->setTitle(label);
+  this->setValue(value);
+}
+
+/**
+ *  destructs an OptionLabel.
+*/
+OptionLabel::~OptionLabel()
+{
+  PRINTF(5)("deleting the OptionLabel: %s\n", this->title);
+  if (this->cValue)
+    delete []this->cValue;
+}
+
+/**
+ *  Updates the value of an OptionLabel
+ * @param newValue The new Name that should be displayed.
+*/
+void OptionLabel::setValue(const char* newValue)
+{
+  if (this->cValue)
+    delete []this->cValue;
+  this->cValue = new char [strlen(newValue)+1];
+  strcpy(this->cValue, newValue);
+
+  this->redraw();
+}
+
+/**
+ *  Redraws an OptionLabel(not implemented yet, but it works).
+*/
+void OptionLabel::redraw()
+{
+#ifdef HAVE_GTK2
+  gtk_label_set_text(GTK_LABEL(widget), cValue);
+#endif /* HAVE_GTK2 */
+}
+
+/**
+ *  Changed the Option, call this Function
+*/
+void OptionLabel::changeOption()
+{
+#ifdef HAVE_GTK2
+  this->cValue = (char*)gtk_label_get_text(GTK_LABEL(this->widget));
+#else /* HAVE_GTK2 */
+  PRINT(0)("\nPlease give me a new input for %s: ", this->title);
+  char tmpChar[100];
+  scanf("%s",tmpChar);
+  this->setValue(tmpChar);
+#endif /* HAVE_GTK2 */
+  PRINT(4)("%s set to: %s\n", this->title,  this->cValue);
+}
+
+
+/**
+ *  creates the Optionlabel save-string
+ * @returns the String to save.
+*/
+char* OptionLabel::save()
+{
+  char* retVal = new char[strlen(cValue)+1];
+  strcpy(retVal, cValue);
+  return retVal;
+}
+
+/**
+ *  loads an Option from of its loadString
+ * @param loadString the string from which to load the data from
+*/
+void OptionLabel::load(const char* loadString)
+{
+  PRINTF(5)("Loading %s: setting to %s\n", this->title, loadString);
+  this->setValue(loadString);
+}
+
+///////////
+/* LABEL */
+///////////
+/**
+ *  Creates a new Label with a Text.
+ * @param text The text to be displayed.
+*/
+Label:: Label(const char* text)
+{
+  this->optionType = GUI_NOTHING;
+
+#ifdef HAVE_GTK2
+  this->widget = gtk_label_new("");
+  gtk_label_set_line_wrap(GTK_LABEL(this->widget), TRUE);
+#endif /* HAVE_GTK2 */
+
+  if (text)
+    this->setTitle(text);
+}
+
+/**
+ *  destructs a Label.
+*/
+Label::~Label()
+{
+  PRINTF(5)("deleting the Label: %s\n", this->title);
+}
+
+/**
+ *  Sets a new Text to a Label.
+ * @param text The text to be inserted into the Label.
+*/
+void Label::setTitle(const char* text)
+{
+  if (this->title)
+    delete []this->title;
+  this->title = new char[strlen(text)+1];
+  strcpy(this->title, text);
+#ifdef HAVE_GTK2
+  gtk_label_set_text(GTK_LABEL(this->widget), this->title);
+#endif /* HAVE_GTK2 */
+}
+
+/**
+ *  ereases the Text of a Label
+*/
+void Label::ereaseText()
+{
+  this->setTitle("");
+}
+
+/**
+  *  appends some Text to a Label
+  * @param textToAppend The text that will be appended to this Label
+*/
+void Label::appendText(char* textToAppend)
+{
+  if (this->title)
+    {
+      char* tmpTitle = new char[strlen(this->title)+strlen(textToAppend)+1];
+      strcpy(tmpTitle, title);
+      strcat(tmpTitle, textToAppend);
+      delete []this->title;
+      this->title = tmpTitle;
+    }
+  else
+    this->title = new char[strlen(textToAppend)];
+
+#ifdef HAVE_GTK2
+  gtk_label_set_text(GTK_LABEL(this->widget), title);
+#endif /* HAVE_GTK2 */
+}
+
+/**
+  *  Appends some integer to the Label
+  * @param intToAppend The Int that will be added.
+
+    it does this by just converting the int into a char* and send it to appendText
+*/
+void Label::appendInt(int intToAppend)
+{
+  char append [32];
+  sprintf(append, "%d", intToAppend);
+  this->appendText(append);
+}
+
+
+/**
+ *  get the Text of a Label
+ * @return The Text the Label holds.
+*/
+const char* Label::getText()
+{
+  return this->title;
+}
+
+//////////////////
+/* PROGRESS-BAR */
+//////////////////
+/**
+ *  Creates a new ProgressBar.
+ * @param label The name you want to get the ProgressBar.
+*/
+ProgressBar::ProgressBar(const char* label)
+{
+  this->optionType = GUI_NOTHING;
+  this->progress = 0.0;
+  this->totalSize = 0.0;
+
+#ifdef HAVE_GTK2
+  this->adjustment =(GtkAdjustment*)gtk_adjustment_new(0, 0, 100, 0, 0, 0);
+  this->widget = gtk_progress_bar_new_with_adjustment(this->adjustment);
+#endif /* HAVE_GTK2 */
+
+  if (label)
+    this->setTitle(label);
+}
+
+/**
+ *  destructs a ProgressBar
+*/
+ProgressBar::~ProgressBar()
+{
+  PRINTF(5)("deleting the ProgressBar: %s\n", this->title);
+}
+
+/**
+ *  Sets the Total size of the Bar.(ex. The maximum one can download)
+*/
+void ProgressBar::setTotalSize(double totalSize)
+{
+  this->totalSize = totalSize;
+}
+
+/**
+ *  Sets the progress maximum is this->totalSize
+*/
+void ProgressBar::setProgress(double progress)
+{
+  this->progress = progress;
+
+  if (this->progress > this->totalSize)
+    this->progress = this->totalSize;
+
+#ifdef HAVE_GTK2
+  gtk_progress_set_value(GTK_PROGRESS(widget), this->progress*100.0/this->totalSize);
+  PRINTF(5)("Progress: %f%%\n", this->progress*100.0/this->totalSize);
+#else /* HVE_GTK2 */
+  PRINT(0)("Progress: %f%%\n", this->progress*100.0/this->totalSize);
+#endif /* HAVE_GTK2 */
+}
+
+/**
+  *  returns the Progress Status
+*/
+double ProgressBar::getProgress()
+{
+  return this->progress;
+}
+
+///////////
+/* IMAGE */
+///////////
+/**
+ *  Creates a new Image
+ * @param imageName the location of the Image on the Hard Disc
+*/
+Image::Image(const char* imageName)
+{
+  this->init(imageName);
+
+#ifdef HAVE_GTK2
+  widget = gtk_image_new_from_file(imageName);
+#endif /* HAVE_GTK2 */
+}
+
+/**
+ *  Creates a new Image
+ * @param imageData data to the PixBuff
+*/
+Image::Image(char** imageData)
+{
+  this->init("pixBuffImage");
+
+#ifdef HAVE_GTK2
+  widget = gtk_image_new_from_pixbuf(gdk_pixbuf_new_from_xpm_data((const char**)imageData));
+#endif /* HAVE_GTK2 */
+}
+
+
+/**
+ *  destructs an Image.
+*/
+Image::~Image()
+{
+  PRINTF(5)("deleting the Image: %s\n", this->title);
+}
+
+/**
+  *  Initializes a new Image
+  * @param name the name to set to the Image
+*/
+void Image::init(const char* name)
+{
+  optionType = GUI_NOTHING;
+
+  if (this->title)
+    delete []this->title;
+  this->title = new char[strlen(name)+1];
+  strcpy(this->title, name);
+}
+
+
+/////////////////
+/* FILE DIALOG */
+/////////////////
+/**
+ *  Creates a new FileDialog
+ * @param fileDialogName a Name for the Dialog
+*/
+FileDialog::FileDialog(const char* fileDialogName)
+{
+  this->optionType = GUI_NOTHING;
+  this->isOpen = false;
+  this->changeOption = NULL;
+  this->openUpButton = NULL;
+  this->okObject = NULL;
+  this->okFunc = NULL;
+
+#ifdef HAVE_GTK2
+  this->widget = gtk_file_selection_new(fileDialogName);
+
+  gtk_file_selection_set_select_multiple(GTK_FILE_SELECTION (this->widget), FALSE);
+
+  g_signal_connect(GTK_FILE_SELECTION (this->widget)->cancel_button,
+                     "button_release_event",
+                     G_CALLBACK (FileDialog::dialogClose),
+                     this);
+  g_signal_connect(GTK_FILE_SELECTION (this->widget),
+                     "delete_event",
+                     G_CALLBACK (FileDialog::dialogClose),
+                     this);
+  g_signal_connect(GTK_FILE_SELECTION (this->widget)->ok_button,
+                     "button_release_event",
+                     G_CALLBACK (FileDialog::dialogOK),
+                     this);
+#endif /* HAVE_GTK2 */
+  if (fileDialogName)
+    this->setTitle(fileDialogName);
+}
+
+/**
+ *  destructs a FileDialog
+*/
+FileDialog::~FileDialog()
+{
+  PRINTF(5)("deleting FileDialog %s\n", this->title);
+}
+
+void FileDialog::setChangeOption(OptionLabel* changeOption)
+{
+  this->changeOption = changeOption;
+}
+
+void FileDialog::setOKFunc(void* okObject, bool(*function)(const char* , void*))
+{
+  this->okObject = okObject;
+  this->okFunc = function;
+}
+
+
+void FileDialog::setOpenUpButton(Button* openUpButton)
+{
+  this->openUpButton = openUpButton;
+
+  openUpButton->connectSignal("button_release_event", this, FileDialog::dialogOpen);
+}
+
+
+void FileDialog::setDefaultFileName(const char* defaultFileName)
+{
+#ifdef HAVE_GTK2
+  gtk_file_selection_set_filename (GTK_FILE_SELECTION(this->widget), defaultFileName);
+#endif /* HAVE_GTK2 */
+}
+
+void FileDialog::setMask(const char* mask)
+{
+#ifdef HAVE_GTK2
+  gtk_file_selection_complete(GTK_FILE_SELECTION(this->widget), mask);
+#endif /* HAVE_GTK2 */
+}
+
+/**
+ *  disables the File Operator Buttons
+*/
+void FileDialog::disableFileOpts()
+{
+#ifdef HAVE_GTK2
+  gtk_file_selection_hide_fileop_buttons(GTK_FILE_SELECTION(this->widget));
+#endif /* HAVE_GTK2 */
+}
+
+/**
+ *  The ok-button has been pressed
+*/
+void FileDialog::okEvent()
+{
+  if (this->okFunc)
+    {
+#ifdef HAVE_GTK2
+      if(this->okFunc((const char*)gtk_file_selection_get_filename(GTK_FILE_SELECTION(this->widget)), this->okObject))
+         this->close();
+#endif /* HAVE_GTK2 */
+    }
+  else if (this->changeOption)
+    {
+#ifdef HAVE_GTK2
+      changeOption->setValue(gtk_file_selection_get_filename(GTK_FILE_SELECTION(this->widget)));
+#endif /* HAVE_GTK2 */
+      this->close();
+    }
+  else
+    this->close();
+}
+
+/**
+   \biref opens up the FileDialog-Window
+*/
+void FileDialog::open()
+{
+  isOpen = true;
+#ifdef HAVE_GTK2
+  gtk_widget_show_all(this->widget);
+  gtk_grab_add(this->widget);
+#endif /* HAVE_GTK2 */
+}
+
+/**
+   \closes the FileDialog-Window
+*/
+void FileDialog::close()
+{
+  this->isOpen = false;
+#ifdef HAVE_GTK2
+  gtk_grab_remove(this->widget);
+  gtk_widget_hide(this->widget);
+#endif /* HAVE_GTK2 */
+}
+
+#ifdef HAVE_GTK2
+gint FileDialog::dialogOK(GtkWidget* widget, GdkEvent* event, void* dialog)
+{
+  static_cast<FileDialog*>(dialog)->okEvent();
+}
+#else /* HAVE_GTK2 */
+int FileDialog::dialogOK(void* widget, void* event, void* dialog){}
+#endif /* HAVE_GTK2 */
+
+#ifdef HAVE_GTK2
+gint FileDialog::dialogOpen(GtkWidget* widget, GdkEvent* event, void* dialog)
+{
+  static_cast<FileDialog*>(dialog)->open();
+}
+#else /* HAVE_GTK2 */
+int FileDialog::dialogOpen(void* widget, void* event, void* dialog){}
+#endif /* HAVE_GTK2 */
+
+#ifdef HAVE_GTK2
+gint FileDialog::dialogClose(GtkWidget* widget, GdkEvent* event, void* dialog)
+{
+  static_cast<FileDialog*>(dialog)->close();
+}
+#else /* HAVE_GTK2 */
+int FileDialog::dialogClose(void* widget, void* event, void* dialog){}
+#endif /* HAVE_GTK2 */
Index: branches/network/src/lib/gui/gtk_gui/gui_gtk.h
===================================================================
--- branches/network/src/lib/gui/gtk_gui/gui_gtk.h	(revision 6636)
+++ branches/network/src/lib/gui/gtk_gui/gui_gtk.h	(revision 6636)
@@ -0,0 +1,470 @@
+/*!
+ * @file gui_gtk.h
+ * Contains all th different Widgets.
+ */
+#ifndef _GUI_GTK_H
+#define _GUI_GTK_H
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "debug.h"
+#include "globals.h"
+
+#ifdef HAVE_GTK2
+#include <gtk/gtkmain.h>
+#include <gtk/gtkwindow.h>
+#include <gtk/gtkframe.h>
+#include <gtk/gtkhbox.h>
+#include <gtk/gtkvbox.h>
+#include <gtk/gtkbutton.h>
+#include <gtk/gtkcheckbutton.h>
+#include <gtk/gtkhscale.h>
+#include <gtk/gtkoptionmenu.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkmenuitem.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkimage.h>
+#include <gtk/gtkeventbox.h>
+#include <gtk/gtkprogressbar.h>
+#include <gtk/gtkfilesel.h>
+#endif /* HAVE_GTK2 */
+
+// enumerator for different GuiOption-Types
+enum GUI_OPTION
+{
+  GUI_BOX = -2,
+  GUI_CONTAINER = -1,
+  GUI_NOTHING = 0,
+  GUI_BOOL = 1,
+  GUI_INT = 2,
+  GUI_FLOAT = 3,
+  GUI_CHAR = 4,
+  GUI_CHAR_ARRAY = 5
+};
+
+extern char* executable;
+
+bool initGUI(int argc, char* argv[]);
+bool mainloopGUI();
+
+//! This is the topmost object that can be displayed all others are derived from it.
+class Widget
+{
+ private:
+
+ public:
+  Widget();
+  virtual ~Widget();
+
+  void show();
+  void hide();
+  void setSize(int width, int height);
+
+  virtual void setTitle(const char* title);  //!< An abstract Function, that sets the title of Widgets.
+  virtual const char* getTitle() const { return this->title; };
+
+  Widget* findWidgetByName(char* name, unsigned int depth);
+  void walkThrough(void(*function)(Widget*), unsigned int depth);
+  void walkThrough(void(*function)(Widget*, void*), void* data, unsigned int depth);
+   static void listOptionsAndGroups(Widget* widget);
+   static void listOptions(Widget* widget);
+   static void listOptions(Widget* widget, void* data);
+   Widget* findOptionByNumber(int* number, unsigned int depth);
+   static void listGroups(Widget* widget);
+   static void listGroups(Widget* widget, void* data);
+   static void printHelp(Widget* widget);
+   Widget* findGroupByNumber(int* number, unsigned int depth);
+   static void setOptions(Widget* widget);
+   static void redrawOptions(Widget* widget);
+   static void flagCheck(Widget* widget, void* flagName);
+
+#ifdef HAVE_GTK2
+  // Connection - Functions
+  gulong connectSignal(char* event, gint(*signal)(GtkWidget*, GdkEvent*, void* ));
+  gulong connectSignal(char* event, gint(*signal)(GtkWidget*, Widget* ));
+  gulong connectSignal(char* event, void* extObj, gint(*signal)(GtkWidget*, GdkEvent*, void* ));
+  gulong connectSignal(char* event, void* extObj, gint(*signal)(GtkWidget*, void* ));
+  gulong connectSignal(char* event, void* extObj, gint(*signal)(GtkWidget*, GdkEventKey*, void* ));
+  void disconnectSignal(gulong signalID);
+  // Signals
+  static gint doNothingSignal(GtkWidget* widget, GdkEvent* event, void* nothing);
+#else /* HAVE_GTK2 */
+  // Connection - Functions
+  unsigned long connectSignal(char* event, int(*signal)(void*, void*, void* )){};
+  unsigned long connectSignal(char* event, int(*signal)(void*, Widget* )){};
+  unsigned long connectSignal(char* event, void* extObj, int(*signal)(void*, void*, void* )){};
+  unsigned long connectSignal(char* event, void* extObj, int(*signal)(void*, void* )){};
+  void disconnectSignal(unsigned long signalID);
+  // Signals
+  static int doNothingSignal(void* widget, void* event, void* nothing);
+#endif /* HAVE_GTK2 */
+
+
+  Widget* next;                     //!< next always points to the next Widget in the list. Every Widget has a next one, or has NULL as next
+#ifdef HAVE_GTK2
+  GtkWidget* widget;                //!< widget is the gtk_widget that the specific Object Contains.
+#else /* HAVE_GTK2 */
+  void* widget;
+#endif /* HAVE_GTK2 */
+
+  GUI_OPTION optionType;            //!< The Type of the Widget.
+  char* title;                      //!< The name of the Widget. Some do display it, Options need it to save;
+};
+
+//! This is a Packer Object, which has the ability to Pack other Widgets into itself.
+class Packer : public Widget
+{
+ public:
+  Packer();
+  virtual ~Packer();
+
+  Widget* down;                      //!< this points to the Widget below this.
+  char* groupName;                   //!< For each Packer you can specify a Groupname under which the lowerWidgets will be saved.
+
+  void setGroupName(const char* name);
+  /** @returns the GroupName if existent NULL otherwise */
+  inline const char* getGroupName() const {return this->groupName;}
+
+
+  virtual void fill(Widget* lowerWidget) = 0; //!< An abstract function, that fills Packers.
+};
+
+//! This is a Container Class, it can contain one sub-Widget: down.
+/**
+ * A Container is a Widget that can hold a subWidget in addition to a next-Widget.
+ * The Container can by itself not be displayed created or used.
+ * The derived classes of Container can be displayed
+*/
+class Container : public Packer
+{
+ private:
+  int borderwidth;          //!< The width of The Container Boarder.
+  int policy;               //!< The Update Policy of a Container.
+
+ public:
+  Container();
+  virtual ~Container();
+
+  void setBorderWidth(int borderwidth);
+  void fill(Widget* lowerWidget);
+};
+
+//! Window is the class that creates new Windows, and handels them
+/**
+ * A Window is a class derived from Container that contains a window-widget.
+ * It has the ability to hold one sub-object
+ */
+class Window : public Container
+{
+ private:
+  bool isOpen;                      //!< A bool Variable that checks if a Window is already open.
+ public:
+  static Window* mainWindow;        //!< Pointer to the First Window that was opened. By default this should be the GUI's main-Window.
+  static void addWindow(Window* windowToAdd);
+
+  Window(const char* windowName = NULL);
+  virtual ~Window();
+
+  virtual void setTitle(const char* title);
+  void showall();
+  void open();
+  void close();
+
+#ifdef HAVE_GTK2
+  // Signals
+  static gint windowOpen(GtkWidget* widget, GdkEvent* event, void* window);
+  static gint windowClose(GtkWidget* widget, GdkEvent* event, void* window);
+#else /* HAVE_GTK2 */
+  int Window::windowOpen(void* widget, void* event, void* window);
+  int Window::windowClose(void* widget, void* event, void* window);
+#endif /* HAVE_GTK2 */
+};
+
+//! Frame is the class that handles frames
+/**
+ * A Frame is an object, that has a border and if you like a name on it.
+ * It can contain a Widget, which means that you can insert anything you like inside of a frame
+ */
+class Frame :public Container
+{
+ public:
+  Frame(const char* frameName = NULL);
+  virtual ~Frame();
+
+  virtual void setTitle(const char* title);
+};
+
+//! EventBox is a Container that can Handle all Events happening inside of it.
+/**
+ * Example: if you have a picture, and you want it to catch mouse-clicks, you have to pack it inside a EventBox
+ */
+class EventBox : public Container
+{
+ public:
+  EventBox(const char* eventBoxName = NULL);
+  virtual ~EventBox();
+};
+
+//! A Box can contain multiple Widgets
+/**
+   A Box can Contain multiple Widgets, that are ordered either horizontally or vertically
+   I defined the standartbox to be horizontally.
+   A Box is always filled left->right(horizontally) or up->down(vertically)
+*/
+class Box : public Packer
+{
+ public:
+  Box(char boxtype = 'h');
+  virtual ~Box();
+
+  virtual void fill(Widget* lowerWidget);
+};
+
+//! An Option is a Widget that contains something that may change its state.
+/**
+ * Options are the essence of a GUI, they: Configure, Start, Quit, Execute, and make it worth something
+ */
+class Option : public Widget
+{
+ protected:
+  bool saveable;              //!< Options can be Saved.
+
+ public:
+  Option();
+  virtual ~Option();
+
+  int value;                  //!< every option has a value either true or false(0,1) or something else like 25 for 25% of the volume
+  char* flagName;             //!< options have a flag name that will be appendet if you start the Program from the GUI.
+  char* flagNameShort;        //!< like flag_name but shorter
+  int defaultValue;           //!< A default value is good, for hiding a option if it is not needed.(hidden if value == default_value)
+
+  char* shortDescription;      //!< A Text that describes this option in short
+  char* longDescription;      //!< A Longer Text describing this option in a full way
+
+  void saveability(bool isSaveable = true);
+  virtual char* save();
+  virtual void load(const char* loadString);
+
+  bool isSaveable();
+  void setDefaultValue(int defaultValue);
+  void setFlagName(const char* flagname, int defaultvalue);
+  void setFlagName(const char* flagname, const char* flagnameshort, int defaultvalue);
+  void setDescription(const char* shortDescription, const char* longDescription = NULL);
+
+  virtual void redraw() = 0;       //!< A Option must be able to redraw itself.
+  virtual void changeOption() = 0; //!< What to do, if an Option is Changed. eacht option decides for itself.
+#ifdef HAVE_GTK2
+    // Signals
+  static gint OptionChange(GtkWidget* widget, Widget* option); //!< Signal for Options that change.
+#endif /* HAVE_GTK2 */
+};
+
+//! Buttons can be pressed, and released.
+/**
+ * Buttons are mainly there for executing some action like Starting the Programm, or Quiting it.
+ */
+class Button : public Option
+{
+ public:
+  Button(const char* buttonName = NULL);
+  virtual ~Button();
+
+  virtual void setTitle(const char* title);
+  virtual void redraw();
+  virtual void changeOption();
+};
+
+//! CheckButtons are a key in configuring bool Variables
+/** CheckButtons can configure bool Variables like wireframe on/off, enable_sound etc.
+ */
+class CheckButton : public Option
+{
+ public:
+  CheckButton(const char* buttonName = NULL);
+  virtual ~CheckButton();
+
+  bool isActive();
+
+  virtual void setTitle(const char* title);
+  virtual void redraw();
+  virtual void changeOption();
+};
+
+//! Sliders are Options that can be modified in their value
+/**
+ * good for volume, brightness, etc.
+ */
+class Slider : public Option
+{
+ private:
+  float start;                            //!< The beginning of the Slider-range.
+  float end;                              //!< The end of the Slider-range.
+  float fValue;                           //!< a value for the slider
+ public:
+  Slider(const char* slidername, float start, float end);
+  virtual ~Slider();
+
+  void setExactness(int exactness);
+  void setValue(float value);
+  virtual void redraw();
+  virtual void changeOption();
+
+  virtual char* save();
+  virtual void load(const char* loadString);
+};
+
+//! A Menu is an Option that has a dropdown menu, where you can chose between different Items
+class Menu : public Option
+{
+ private:
+#ifdef HAVE_GTK2
+  GtkWidget* menu;                      //!< The menu That will hold the Options.
+#endif /* HAVE_GTK2 */
+
+  //! A struct to handle the MenuItems
+  struct MenuItem
+  {
+    char* name;                         //!< The name of this entry.
+    int itemNumber;                     //!< The n'th entry of this menu;
+#ifdef HAVE_GTK2
+    GtkWidget* item;                    //!< One Item From a Menu.
+#endif /* HAVE_GTK2 */
+
+    MenuItem* next;                     //!< Pointer to the next MenuItem.
+  };
+  MenuItem* firstItem;                  //!< Pointer to the first Item.
+  MenuItem* currItem;                   //!< Pointer to the current Item.
+
+ public:
+  Menu(const char* menuName);
+  Menu(char* menuname, ...);
+  virtual ~Menu();
+  void init();
+
+  virtual char* save();
+  virtual void load(const char* loadString);
+
+  void addItem(char* itemName);
+  virtual void redraw();
+  virtual void changeOption();
+};
+
+//! A OptionLabel is a simple Label, that holds a char*, and will be updated, if changed.
+class OptionLabel : public Option
+{
+ public:
+  OptionLabel(const char* label, const char* value);
+  virtual ~OptionLabel();
+
+  void setValue(const char* newValue);
+
+  virtual char* save();
+  virtual void load(const char* loadString);
+
+  virtual void redraw();
+  virtual void changeOption();
+
+  char* cValue;                          //!< The Value the Label will have. @todo make private
+};
+
+//! A EntryField is a TextEntry field, for putting some text into.
+class EntryField : public Option
+{
+ public:
+  EntryField(const char* name = NULL);
+  virtual ~EntryField();
+
+  void setValue(const char* newValue);
+  virtual char* save();
+  virtual void load(const char* loadString);
+
+  virtual void redraw();
+  virtual void changeOption();
+};
+
+//! A label is a Widget, that displays a text
+class Label : public Widget
+{
+ public:
+  Label(const char* text = NULL);
+  virtual ~Label();
+
+  virtual void setTitle(const char* text);
+  void ereaseText();
+  void appendText(char* textToAppend);
+  void appendInt(int intToAppend);
+  const char* getText();
+};
+
+//! A ProgressBar is a Widget, that can display a Progress
+class ProgressBar : public Widget
+{
+ public:
+  ProgressBar(const char* label = NULL);
+  virtual ~ProgressBar();
+
+  void setProgress(double progress);
+  void setTotalSize(double totalSize);
+  double getProgress();
+
+ private:
+  double totalSize;         //!< The total Size of a download Bar
+  double progress;          //!< The progress of a Bar.
+#ifdef HAVE_GTK2
+  GtkAdjustment* adjustment;
+#endif /* HAVE_GTK2 */
+};
+
+//! Image is the keeper of one Image
+/**
+ * Images are mighty cool.
+ * Images can help you lighten up the Programming process, and will give everyone a better impression of the Software.
+ */
+class Image : public Widget
+{
+ public:
+  Image(const char* imgaeName);
+  Image(char** imageData);
+  virtual ~Image();
+  void init(const char* name);
+};
+
+//! A FileDialog is a window with wich one can select a File
+class FileDialog : public Widget
+{
+ private:
+  OptionLabel* changeOption;
+  Button* openUpButton;
+  bool isOpen;
+  bool (*okFunc)(const char* , void*);
+  void* okObject;
+
+ public:
+  FileDialog(const char* fileDialogName);
+  virtual ~FileDialog();
+
+  void setChangeOption(OptionLabel* changeOption);
+  void setOKFunc(void* okObject, bool(*function)(const char* , void*));
+  void setOpenUpButton(Button* openUpButton);
+  void setDefaultFileName(const char* defaultFileName);
+  void setMask(const char* mask);
+  void disableFileOpts();
+
+  void okEvent();
+  void open();
+  void close();
+
+#ifdef HAVE_GTK2
+  static gint dialogOK(GtkWidget* widget, GdkEvent* event, void* dialog);
+  static gint dialogOpen(GtkWidget* widget, GdkEvent* event, void* dialog);
+  static gint dialogClose(GtkWidget* widget, GdkEvent* event, void* dialog);
+#else /* HAVE_GTK2 */
+  static int dialogOK(void* widget, void* event, void* dialog);
+  static int dialogOpen(void* widget, void* event, void* dialog);
+  static int dialogClose(void* widget, void* event, void* dialog);
+#endif /* HAVE_GTK2 */
+};
+
+#endif /* _GUI_GTK_H */
Index: branches/network/src/lib/gui/gtk_gui/gui_keys.cc
===================================================================
--- branches/network/src/lib/gui/gtk_gui/gui_keys.cc	(revision 6636)
+++ branches/network/src/lib/gui/gtk_gui/gui_keys.cc	(revision 6636)
@@ -0,0 +1,441 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+
+*/
+
+#include "gui_keys.h"
+
+#include <string.h>
+
+/**
+ *  Creates an Keyboard-Frame
+*/
+GuiKeys::GuiKeys()
+{
+  Frame* keysFrame;      //!< The Frame that holds the keyOptions.
+
+  keysFrame = new Frame("Keyboard-Options:");
+  {
+    Box* keysBox0;          //!< The Frame that holds the keyOptions.
+
+    //  keysFrame->setGroupName("Keyboard");
+    keysBox0 = new Box('v');
+    {
+      Box* keysBox1;
+      MiscKeys* misc;            //!< The Misc Keys
+
+      keysBox1 = new Box('h');
+      {
+        PlayerKeys* player1;       //!< The first Player's keys.
+        PlayerKeys* player2;       //!< The seconds Player's keys.
+
+        player1 = new PlayerKeys(CONFIG_SECTION_PLAYER "1");
+        player2 = new PlayerKeys(CONFIG_SECTION_PLAYER "2");
+
+        keysBox1->fill(player1->getOpenButton());
+        keysBox1->fill(player2->getOpenButton());
+      }
+      keysBox0->fill(keysBox1);
+
+      misc = new MiscKeys();
+      keysBox0->fill(misc->getOpenButton());
+    }
+    keysFrame->fill(keysBox0);
+  }
+
+  // setting up the Input Windows that receives keystrokes.
+  this->inputWindow = new Window("inputWindow");
+  this->inputButton = new Button("test");
+#ifdef HAVE_GTK2
+  this->inputWindow->connectSignal("destroy",  Widget::doNothingSignal);
+  this->inputWindow->connectSignal("delete_event", Widget::doNothingSignal);
+#endif /* HAVE_GTK2 */
+  this->inputWindow->fill(inputButton);
+
+  this->setMainWidget(keysFrame);
+}
+
+/**
+ *  Destructs the Keys-stuff
+*/
+GuiKeys::~GuiKeys()
+{
+  // nothing to do here.
+}
+
+
+Window* GuiKeys::inputWindow = NULL;
+Button* GuiKeys::inputButton = NULL;
+long GuiKeys::keySignal = 0;
+
+////////////
+/* PLAYER */
+////////////
+/**
+ *  Creates new inputs for a player
+ * @param player the name of the Player
+*/
+PlayerKeys::PlayerKeys(char* player)
+{
+  Window* pKeyWindow;     //!< The Window for a new Key-setting.
+
+  char* windowName = new char[strlen(player)+12];
+  strcpy(windowName, "KeySets: ");
+  strcat(windowName, player);
+  pKeyWindow = new Window(windowName);
+  {
+    Frame* pKeyFrame;       //!< The Frame for a new Key-setting.
+
+    pKeyFrame = new Frame(windowName);
+    {
+      Box* pKeysBox;          //!< The Box that holds the Key-settings.
+      pKeysBox = new Box('v');
+      {
+        Button* closeButton;    //!< The CloseButton for this key-settings.
+
+        pKeysBox->setGroupName(player);
+        pKeysBox->fill(addKey(CONFIG_NAME_PLAYER_UP, "w"));
+        pKeysBox->fill(addKey(CONFIG_NAME_PLAYER_DOWN, "s"));
+        pKeysBox->fill(addKey(CONFIG_NAME_PLAYER_LEFT, "a"));
+        pKeysBox->fill(addKey(CONFIG_NAME_PLAYER_RIGHT, "d"));
+        pKeysBox->fill(addKey(CONFIG_NAME_PLAYER_ROLL_LEFT, "q"));
+        pKeysBox->fill(addKey(CONFIG_NAME_PLAYER_ROLL_RIGHT, "e"));
+        pKeysBox->fill(addKey(CONFIG_NAME_PLAYER_FIRE, "BUTTON_LEFT"));
+        pKeysBox->fill(addKey(CONFIG_NAME_PLAYER_NEXT_WEAPON, "m"));
+        pKeysBox->fill(addKey(CONFIG_NAME_PLAYER_PREV_WEAPON, "n"));
+        closeButton = new Button("close");
+#ifdef HAVE_GTK2
+        closeButton->connectSignal("button_press_event", pKeyWindow, Window::windowClose);
+#endif /* HAVE_GTK2 */
+
+        pKeysBox->fill(closeButton);
+      }
+      pKeyFrame->fill(pKeysBox);
+    }
+    pKeyWindow->fill(pKeyFrame);
+  }
+  delete[] windowName;
+  Window::addWindow(pKeyWindow);
+#ifdef HAVE_GTK2
+  pKeyWindow->connectSignal("destroy", pKeyWindow, Window::windowClose);
+  pKeyWindow->connectSignal("delete_event", pKeyWindow, Window::windowClose);
+#endif /* HAVE_GTK2 */
+
+  this->openButton = new Button(player);
+#ifdef HAVE_GTK2
+  this->openButton->connectSignal("button_press_event", pKeyWindow, Window::windowOpen);
+#endif /* HAVE_GTK2 */
+}
+
+/**
+ * @returns the OpenButton of a Player
+*/
+Button* PlayerKeys::getOpenButton()
+{
+  return this->openButton;
+}
+
+//////////////////
+/* MISC_OPTIONS */
+//////////////////
+/**
+ *  Creates new inputs for a misc
+ * @param player the name of the Misc
+*/
+MiscKeys::MiscKeys()
+{
+  Window* keyWindow;     //!< The Window for a new Key-setting.
+
+  keyWindow = new Window("misc Keys");
+  {
+    Frame* keyFrame;       //!< The Frame for a new Key-setting.
+
+    keyFrame = new Frame("misc Keys:");
+    {
+      Box* keysBox;          //!< The Box that holds the Key-settings.
+      keysBox = new Box('v');
+      {
+        Button* closeButton;    //!< The CloseButton for this key-settings.
+
+        keysBox->setGroupName(CONFIG_SECTION_MISC_KEYS);
+        keysBox->fill(addKey(CONFIG_NAME_QUIT , "ESCAPE"));
+        keysBox->fill(addKey(CONFIG_NAME_PAUSE, "PAUSE"));
+        keysBox->fill(addKey(CONFIG_NAME_NEXT_WORLD, "x"));
+        keysBox->fill(addKey(CONFIG_NAME_PREV_WORLD, "z"));
+        keysBox->fill(addKey(CONFIG_NAME_VIEW0, "1"));
+        keysBox->fill(addKey(CONFIG_NAME_VIEW1, "2"));
+        keysBox->fill(addKey(CONFIG_NAME_VIEW2, "3"));
+        keysBox->fill(addKey(CONFIG_NAME_VIEW3, "4"));
+        keysBox->fill(addKey(CONFIG_NAME_VIEW4, "5"));
+        keysBox->fill(addKey(CONFIG_NAME_VIEW5, "6"));
+
+        closeButton = new Button("close");
+#ifdef HAVE_GTK2
+        closeButton->connectSignal("button_press_event", keyWindow, Window::windowClose);
+#endif /* HAVE_GTK2 */
+
+        keysBox->fill(closeButton);
+      }
+      keyFrame->fill(keysBox);
+    }
+    keyWindow->fill(keyFrame);
+  }
+  Window::addWindow(keyWindow);
+#ifdef HAVE_GTK2
+  keyWindow->connectSignal("destroy", keyWindow, Window::windowClose);
+  keyWindow->connectSignal("delete_event", keyWindow, Window::windowClose);
+#endif /* HAVE_GTK2 */
+
+  this->openButton = new Button("misc");
+#ifdef HAVE_GTK2
+  this->openButton->connectSignal("button_press_event", keyWindow, Window::windowOpen);
+#endif /* HAVE_GTK2 */
+}
+
+/**
+ * @returns the OpenButton of a Misc
+*/
+Button* MiscKeys::getOpenButton()
+{
+  return this->openButton;
+}
+
+
+/**
+ *  adds a new Key.
+ * @param key the number of the Key
+ * @param name The name of the new Key.
+ * @returns A widget that has the Key-Box
+*/
+Widget* addKey(const char* name, const char* defaultVal)
+{
+  InputKey* inputKey = new InputKey;
+  inputKey->keyBox = new Box();
+  inputKey->keyButton = new Button(name);
+  if (defaultVal)
+    inputKey->keyOLabel = new OptionLabel(name, defaultVal);
+  else
+    inputKey->keyOLabel = new OptionLabel(name, name);
+  inputKey->keyOLabel->saveability();
+
+#ifdef HAVE_GTK2
+  //inputKey->keyButton->connectSignal("key_press_event", inputKey->keyButton, key_cb);
+  inputKey->keyButton->connectSignal("button_press_event", inputKey, inputWindowEvent);
+#endif /* HAVE_GTK2 */
+  inputKey->keyBox->fill(inputKey->keyButton);
+  inputKey->keyBox->fill(inputKey->keyOLabel);
+  return inputKey->keyBox;
+}
+
+
+#ifdef HAVE_GTK2
+gint inputWindowEvent(GtkWidget* w, GdkEventKey* event, void* inputKey)
+{
+  GuiKeys::inputButton->setTitle("press a Key");
+  GuiKeys::keySignal = GuiKeys::inputButton->connectSignal("key_press_event", inputKey, key_cb);
+  GuiKeys::inputWindow->open();
+}
+
+/**
+ *  Function which gets keystrokes
+ * @param w the widget that released the Function.
+ * @param event The event that happened.
+ * @param Widget the Widget which will be applied.
+ * @returns Nothing
+*/
+gint key_cb(GtkWidget* w, GdkEventKey* event, void* inputKey)
+{
+  InputKey* inputkey =(InputKey*) inputKey;
+  char title [50];
+
+  switch(event->keyval)
+    {
+    case GDK_Up:
+      strcpy(title, "UP");
+      break;
+    case GDK_Down:
+      strcpy(title, "DOWN");
+      break;
+    case GDK_Left:
+      strcpy(title, "LEFT");
+      break;
+    case GDK_Right:
+      strcpy(title, "RIGHT");
+      break;
+
+    case GDK_space:
+      strcpy(title, "SPACE");
+      break;
+
+    case GDK_Return:
+      strcpy(title, "RETURN");
+      break;
+
+      // Special Keys //
+    case GDK_BackSpace:
+      strcpy(title, "BACKSPACE");
+      break;
+    case GDK_Scroll_Lock:
+      strcpy(title, "SCROLLOCK");
+      break;
+    case GDK_minus:
+      strcpy(title, "MINUS");
+      break;
+    case GDK_plus:
+      strcpy(title, "PLUS");
+      break;
+    case GDK_slash:
+      strcpy(title, "SLASH");
+      break;
+    case GDK_period:
+      strcpy(title, "PERIOD");
+      break;
+    case GDK_comma:
+      strcpy(title, "COMMA");
+      break;
+    case GDK_colon:
+      strcpy(title, "COLON");
+      break;
+    case GDK_semicolon:
+      strcpy(title, "SEMICOLON");
+      break;
+    case GDK_less:
+      strcpy(title, "LESS");
+      break;
+    case GDK_equal:
+      strcpy(title, "EQUALS");
+      break;
+    case GDK_greater:
+      strcpy(title, "GREATER");
+      break;
+    case GDK_question:
+      strcpy(title, "QUESTION");
+      break;
+    case GDK_at:
+      strcpy(title, "AT");
+      break;
+    case GDK_bracketleft:
+      strcpy(title, "LEFTBRACKET");
+      break;
+    case GDK_bracketright:
+      strcpy(title, "RIGHTBRACKET");
+      break;
+    case GDK_backslash:
+      strcpy(title, "BACKSLASH");
+      break;
+    case GDK_underscore:
+      strcpy(title, "UNDERSCORE");
+      break;
+    case GDK_quoteleft:
+      strcpy(title, "BACKQUOTE");
+      break;
+
+    case GDK_Page_Up:
+      strcpy(title, "PAGEUP");
+      break;
+    case GDK_Page_Down:
+      strcpy(title, "PAGEDOWN");
+      break;
+    case GDK_Home:
+      strcpy(title, "HOME");
+      break;
+    case GDK_Insert:
+      strcpy(title, "INSERT");
+      break;
+
+    case GDK_Escape:
+      strcpy(title, "ESCAPE");
+      break;
+    case GDK_Tab:
+      strcpy(title, "TAB");
+      break;
+    case GDK_Shift_L:
+      strcpy(title, "LSHIFT");
+      break;
+    case GDK_Shift_R:
+      strcpy(title, "R_SHIFT");
+      break;
+    case GDK_Control_L:
+      strcpy(title, "LCTRL");
+      break;
+    case GDK_Control_R:
+      strcpy(title, "RCTRL");
+      break;
+    case GDK_Alt_L:
+      strcpy(title, "LALT");
+      break;
+    case GDK_Alt_R:
+      strcpy(title, "RALT");
+      break;
+      // FXX KEYS //
+    case GDK_F1:
+      strcpy(title, "F1");
+      break;
+    case GDK_F2:
+      strcpy(title, "F2");
+      break;
+    case GDK_F3:
+      strcpy(title, "F3");
+      break;
+    case GDK_F4:
+      strcpy(title, "F4");
+      break;
+    case GDK_F5:
+      strcpy(title, "F5");
+      break;
+    case GDK_F6:
+      strcpy(title, "F6");
+      break;
+    case GDK_F7:
+      strcpy(title, "F7");
+      break;
+    case GDK_F8:
+      strcpy(title, "F8");
+      break;
+    case GDK_F9:
+      strcpy(title, "F9");
+      break;
+    case GDK_F10:
+      strcpy(title, "F10");
+      break;
+    case GDK_F11:
+      strcpy(title, "F11");
+      break;
+    case GDK_F12:
+      strcpy(title, "F12");
+      break;
+
+
+    default:
+      char* tmp;
+      sprintf(tmp, "%c", event->keyval);
+      printf("other key %s \n", tmp);
+      strcpy(title, tmp);
+      break;
+    }
+
+  inputkey->keyOLabel->setValue(title);
+  GuiKeys::inputButton->disconnectSignal(GuiKeys::keySignal);
+  GuiKeys::inputWindow->close();
+}
+#endif /* HAVE_GTK2 */
Index: branches/network/src/lib/gui/gtk_gui/gui_keys.h
===================================================================
--- branches/network/src/lib/gui/gtk_gui/gui_keys.h	(revision 6636)
+++ branches/network/src/lib/gui/gtk_gui/gui_keys.h	(revision 6636)
@@ -0,0 +1,67 @@
+/*!
+  \file gui_keys.h
+  \brief File that holds the class that creates the Keyboard-Options.
+*/
+
+#ifndef _GUI_KEYS_H
+#define _GUI_KEYS_H
+
+#include "gui.h"
+#include "gui_element.h"
+#include "gui_gtk.h"
+
+#ifdef HAVE_GTK2
+#include <gdk/gdkkeysyms.h>
+#endif /* HAVE_GTK2 */
+
+//! One KeyOption has one InputKey
+struct InputKey
+{
+  Box* keyBox;           //!< One Box that holds the Keys
+  Button* keyButton;     //!< The Button for changing the Key.
+  OptionLabel* keyOLabel;//!< The Label for displaying the Key-setting.
+};
+
+//! Class that creates the Keys-Options.
+class GuiKeys : public GuiElement
+{
+ public:
+  GuiKeys();
+  ~GuiKeys();
+
+  static Window* inputWindow; //!< A Window that gets keyboard clicks. Static, because only one needed.
+  static Button* inputButton; //!< A Button that gets keyboard clicks. Static, because only one needed.
+  static long keySignal;      //!< A keySignal that handles keyboard clicks. Static, because only one needed.
+};
+
+//! Class to hold infos about a Player
+class PlayerKeys
+{
+ private:
+  Button* openButton;     //!< The OpenButton for this key-settings.
+
+ public:
+  PlayerKeys(char* player);
+
+  Button* getOpenButton();
+};
+
+class MiscKeys
+{
+ private:
+  Button* openButton;     //!< The OpenButton for this key-settings.
+
+ public:
+  MiscKeys();
+
+  Button* getOpenButton();  
+};
+
+Widget* addKey(const char* name, const char* defaultValue = NULL);
+#ifdef HAVE_GTK2
+gint inputWindowEvent(GtkWidget* w, GdkEventKey* event, void* widget);
+gint key_cb(GtkWidget* w, GdkEventKey* event, void* inputKey);
+#endif /* HAVE_GTK2 */
+
+
+#endif /* _GUI_KEYS_H */
Index: branches/network/src/lib/gui/gtk_gui/gui_update.cc
===================================================================
--- branches/network/src/lib/gui/gtk_gui/gui_update.cc	(revision 6636)
+++ branches/network/src/lib/gui/gtk_gui/gui_update.cc	(revision 6636)
@@ -0,0 +1,501 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+
+*/
+
+#include "gui_update.h"
+#include <string.h>
+
+#include "gui.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include "globals.h"
+
+using namespace std;
+
+/**
+ *  Creates an Update-Frame
+*/
+GuiUpdate::GuiUpdate()
+{
+  FileDialog* dataDirDialog;   //!< A FileDialog for the selection of the DataRepos
+  Button* dataDirButton;       //!< A Button for the selection of the DataRepos
+  OptionLabel* dataDirLabel;   //!< A Label fot the selection of the DataRepos
+
+
+  this->tmpDir = NULL;
+  this->homeDir = NULL;
+  this->installSourceDir = NULL;
+  this->userName = NULL;
+
+  this->getSystemInfo();
+
+  this->updateFrame = new Frame("Update-Options:");
+  this->updateFrame->setGroupName(CONFIG_SECTION_DATA);
+  this->updateBox = new Box('v');
+
+  dataDirButton = new Button(CONFIG_NAME_DATADIR);
+  dataDirLabel = new OptionLabel(CONFIG_NAME_DATADIR, "unknown");
+  dataDirLabel->setFlagName("data-dir", "d", 0);
+  dataDirLabel->setDescription("Sets the location of the orxonox' Data-Directory");
+  dataDirLabel->saveability();
+  dataDirDialog = new FileDialog("data-Repos-location");
+  dataDirDialog->setDefaultFileName("data");
+  dataDirDialog->setMask(DATA_IDENTIFIER);
+  this->checkDataDir(DEFAULT_DATA_DIR DATA_IDENTIFIER, dataDirLabel);
+  dataDirDialog->disableFileOpts();
+  dataDirDialog->setOpenUpButton(dataDirButton);
+  //dataDirDialog->setChangeOption(dataDirLabel);
+  dataDirDialog->setOKFunc(dataDirLabel, GuiUpdate::checkDataDir);
+  updateBox->fill(dataDirButton);
+  updateBox->fill(dataDirLabel);
+
+#ifdef HAVE_CURL
+
+  // the Button for autoUpdating
+  this->autoUpdate = new CheckButton(CONFIG_NAME_AUTO_UPDATE);
+  this->updateBox->fill(this->autoUpdate);
+  this->autoUpdate->setFlagName("update", "u", 0);
+  this->autoUpdate->setDescription("Updates orxonox", "When this option is selected orxonox automatically searches for updates, and if found installs them");
+  this->autoUpdate->saveability();
+
+
+
+
+  this->updateSourceWindowCreate();
+  this->updateBox->fill(this->updateSourceWindowGetButton());
+
+  this->updateDataWindowCreate();
+  this->updateBox->fill(this->updateDataWindowGetButton());
+
+#else /* HAVE_CURL */
+  Label* noCurlLabel = new Label("since you do not have cURL-support,\nupdate options are not availible");
+  this->updateBox->fill(noCurlLabel);
+#endif /* HAVE_CURL */
+  this->updateFrame->fill(this->updateBox);
+  this->setMainWidget(this->updateFrame);
+
+
+}
+
+/**
+ *  Destructs the Update-stuff
+*/
+GuiUpdate::~GuiUpdate()
+{
+
+}
+
+/**
+ *  checks if the Folder containing selected File is data.oxd, and if so sets it.
+ * @param
+*/
+bool GuiUpdate::checkDataDir(const char* fileName, void* object)
+{
+  if (!strcmp(fileName+(strlen(fileName)-strlen(DATA_IDENTIFIER)), DATA_IDENTIFIER))
+    {
+      char* tmpName = new char[strlen(fileName)-strlen(DATA_IDENTIFIER)+1];
+      strncpy(tmpName, fileName, strlen(fileName)-strlen(DATA_IDENTIFIER));
+      tmpName[strlen(fileName)-strlen(DATA_IDENTIFIER)] = '\0';
+      static_cast<OptionLabel*>(object)->setValue(tmpName);
+      delete[] tmpName;
+      return true;
+    }
+  else
+    return false;
+}
+
+
+/**
+  *  Look what info we can get from this system
+*/
+bool GuiUpdate::getSystemInfo()
+{
+  PRINTF(5)("Grabbing system information\n");
+  this->tmpDir = getenv("TMPDIR");
+  if(!tmpDir)
+    this->tmpDir = "/tmp";
+  PRINTF(5)("Temporary directory is: %s\n", this->tmpDir);
+
+#ifdef __WIN32__
+  this->homeDir = getenv("USERPROFILE");
+#else
+  this->homeDir = getenv("HOME");
+#endif
+  PRINTF(5)("Home directory is %s\n", homeDir);
+
+
+  this->installDataDir = DEFAULT_DATA_DIR;
+  PRINTF(5)("Installation of orxonox-data will go to this directory: %s\n", this->installDataDir);
+
+  this->installSourceDir = "/usr/games/bin";
+  PRINTF(5)("Installation of orxonox-source will go to this directory: %s\n", this->installSourceDir);
+
+  this->userName = getenv("USER");
+  PRINTF(5)("Logged in username is: %s\n", this->userName);
+}
+
+#ifdef HAVE_CURL
+bool* GuiUpdate::checkForUpdates()
+{
+  PRINTF(4)("checking for new version of orxonox\n");
+  FileInfo updateFileInfo;
+  updateFileInfo.fileName = "update_info";
+  updateFileInfo.webRoot = "http://www.orxonox.ethz.ch/files/data";
+  updateFileInfo.localRoot = this->tmpDir;
+
+  download(&updateFileInfo);
+}
+
+/**
+ *  Creates a window, and all it contains for the Data-update.
+*/
+void GuiUpdate::updateDataWindowCreate()
+{
+  this->updateDataWindow = new Window("update orxonox::Data");
+  this->updateDataBox = new Box('v');
+
+  // the close-Button of the Update Window.
+  //  updateWindowClose = new Button("close");
+#ifdef HAVE_GTK2
+  //  updateWindowClose->connectSignal("button_press_event", updateWindow, Window::windowClose);
+#endif /* HAVE_GTK2 */
+  //  updateWindowBox->fill(updateWindowClose);
+
+  this->updateDataBar = new ProgressBar();
+  this->updateDataBox->fill(this->updateDataBar);
+
+  FileInfo* dataInfo = new FileInfo;
+  dataInfo->bar = this->updateDataBar;
+
+  this->updateDataBegin = new Button("begin.");
+  dataInfo->stateButton = this->updateDataBegin;
+#ifdef HAVE_GTK2
+  dataInfo->buttonSignal = updateDataBegin->connectSignal("button_press_event", dataInfo, updateDataFunc);
+#endif /* HAVE_GTK2 */
+  this->updateDataBox->fill(this->updateDataBegin);
+
+  this->updateDataWindow->fill(this->updateDataBox);
+
+  this->updateDataWindowButton = new Button("update orxonox::Data");
+#ifdef HAVE_GTK2
+  this->updateDataWindowButton->connectSignal("button_press_event", this->updateDataWindow, Window::windowOpen);
+  this->updateDataWindow->connectSignal("destroy", this->updateDataWindow, Window::windowClose);
+  this->updateDataWindow->connectSignal("delete_event", this->updateDataWindow, Window::windowClose);
+#endif /* HAVE_GTK2 */
+
+}
+
+/**
+ * @returns A Pointer to the Button of the UpdaterDataWindow
+*/
+Button* GuiUpdate::updateDataWindowGetButton()
+{
+  return this->updateDataWindowButton;
+}
+
+/**
+ *  Creates a window, and all it contains for the Source-update.
+*/
+void GuiUpdate::updateSourceWindowCreate()
+{
+  // the button, that opens this Window.
+  this->updateSourceWindowButton = new Button("update orxonox::Source");
+
+  // the Window itself
+  this->updateSourceWindow = new Window("update orxonox::Source");
+
+  this->updateSourceBox = new Box();
+
+  this->updateSourceBar = new ProgressBar();
+  this->updateSourceBox->fill(this->updateSourceBar);
+  test = new Button("increment");
+
+#ifdef HAVE_GTK2
+  test->connectSignal("button_press_event", updateSourceBar, updateSourceFunc);
+#endif /* HAVE_GTK2 */
+
+  this->updateSourceBox->fill(test);
+  this->updateSourceWindow->fill(updateSourceBox);
+#ifdef HAVE_GTK2
+  this->updateSourceWindowButton->connectSignal("button_press_event", this->updateSourceWindow, Window::windowOpen);
+  this->updateSourceWindow->connectSignal("destroy", this->updateSourceWindow, Window::windowClose);
+  this->updateSourceWindow->connectSignal("delete_event", this->updateSourceWindow, Window::windowClose);
+#endif /* HAVE_GTK2 */
+
+}
+
+/**
+ * @returns A Pointer to the Button of the UpdaterSourceWindow
+*/
+Button* GuiUpdate::updateSourceWindowGetButton()
+{
+  return this->updateSourceWindowButton;
+}
+
+
+#ifdef HAVE_GTK2
+/**
+ *  updates the Data of orxonox.
+ * @param w The widget, that executed this Function.
+ * @param event The event that trigered this Function.
+ * @param button The Button, that triggered this event.
+*/
+gint GuiUpdate::updateDataFunc(GtkWidget* w, GdkEventKey* event, void* info)
+{
+  FileInfo* dataInfo =(FileInfo*)info;
+
+  dataInfo->fileName = "02%20orxonox%203.mp3";
+  dataInfo->webRoot  = "http://www.orxonox.net/files/";
+  dataInfo->localRoot = "./";
+  PRINTF(4)("Preparing to download file %s.\n", dataInfo->fileName);
+  downloadWithStyle(dataInfo);
+}
+
+/**
+ *  updates the source of orxonox.
+ * @param w The widget, that executed this Function.
+ * @param event The event that trigered this Function.
+ * @param button The Button, that triggered this event.
+*/
+gint GuiUpdate::updateSourceFunc(GtkWidget* w, GdkEventKey* event, void* bar)
+{
+  ProgressBar* tmpBar = static_cast<ProgressBar*>(bar);
+  tmpBar->setTotalSize(20);
+  tmpBar->setProgress(tmpBar->getProgress()+1);
+}
+#endif /* HAVE_GTK2 */
+
+/**
+ *  The Function Curl calls to write out the File.
+ * @param ptr A Pointer to the date to write.
+ * @param size The size in bytes of one nmemb to write.
+ * @param nmemb The Count of size to write.
+ * @param stream Filehandler to write to.
+*/
+size_t GuiUpdate::curlWriteFunc(void* ptr, size_t size, size_t nmemb, FILE* stream)
+{
+  return fwrite(ptr, size, nmemb, stream);
+}
+
+/**
+ *  The Function Curl calls to write out the File.
+ * @param ptr A Pointer to the date to write to.
+ * @param size The size in bytes of one nmemb to write.
+ * @param nmemb The Count of size to write.
+ * @param stream Filehandler to get data from.
+*/
+size_t GuiUpdate::curlReadFunc(void* ptr, size_t size, size_t nmemb, FILE* stream)
+{
+  return fread(ptr, size, nmemb, stream);
+}
+
+
+/**
+ *  An update Function for the GUI, to show the progress.
+ * @param Bar th ProgressBar to update
+ * @param totalSize The total size of the download in bytes.
+ * @param progress The current Progress of the download in bytes.
+ * @param upTotal not needed
+ * @param upProgress not needed
+*/
+int GuiUpdate::curlProgressFunc(ProgressBar* bar, double totalSize, double progress, double upTotal, double upProgress)
+{
+  bar->setProgress(progress);
+  bar->setTotalSize(totalSize);
+#ifdef HAVE_GTK2
+  while(gtk_events_pending()) gtk_main_iteration();
+#endif
+  return 0;
+}
+
+/**
+ *  The Curl handle for only one CURL(static).
+*/
+CURL* GuiUpdate::curlHandle = NULL;
+
+//! A bool parameter that shows if we are downloading.
+bool GuiUpdate::isDownloading = false;
+
+//! A parameter to see, if downloading has been canceled
+bool GuiUpdate::downloadCanceled = false;
+
+/**
+ *  Initializes a Download without displaying it.
+ * @param fileInfo the FileInfo.
+
+   !! BE AWARE THIS WILL NOT BE THREADED. !!
+*/
+bool GuiUpdate::download(void* fileInfo)
+{
+  if(isDownloading)
+    {
+      PRINTF(2)("unable to Download. already getting some file\n");
+      return false;
+    }
+  PRINTF(4)("Downloading.\n");
+  FileInfo* info =(FileInfo*)fileInfo;
+  CURLcode res;
+  CURL* localCurl;
+  localCurl = curl_easy_init();
+  char* fileOnNet = new char [strlen(info->webRoot)+strlen(info->fileName)+2];
+  strcpy(fileOnNet, info->webRoot);
+  if(fileOnNet[strlen(fileOnNet)] != '/') //!< @todo windows-shit
+    strcat(fileOnNet, "/");
+  strcat(fileOnNet, info->fileName);
+  char* fileOnDisk = new char [strlen(info->localRoot)+strlen(info->fileName)+2];
+  strcpy(fileOnDisk, info->localRoot);
+  if(fileOnDisk[strlen(fileOnDisk)] != '/') //!< @todo windows-shit
+    strcat(fileOnDisk, "/");
+  strcat(fileOnDisk, info->fileName);
+
+  if(localCurl)
+    {
+
+      info->fileHandle = fopen(fileOnDisk, "w");
+
+      curl_easy_setopt(localCurl, CURLOPT_URL, fileOnNet);
+      curl_easy_setopt(localCurl, CURLOPT_WRITEDATA, info->fileHandle);
+      curl_easy_setopt(localCurl, CURLOPT_WRITEFUNCTION, curlWriteFunc);
+      curl_easy_setopt(localCurl, CURLOPT_READFUNCTION, curlReadFunc);
+      curl_easy_setopt(localCurl, CURLOPT_NOPROGRESS, true);
+
+      curl_easy_perform(localCurl);
+
+      curl_easy_cleanup(localCurl);
+      fclose(info->fileHandle);
+    }
+}
+
+/**
+ *  Initializes a Download with some style.
+ * @param fileInfo the FileInfo.
+   @todo release thread-lock.
+
+   Downloading with a Button that gets a different Name while downloading, and a Bar, that gets to be updated. More to be followed
+*/
+bool GuiUpdate::downloadWithStyle(void* fileInfo)
+{
+  if(isDownloading)
+    {
+      PRINTF(2)("unable to Download. already getting some file\n");
+      return false;
+    }
+  PRINTF(4)("Downloading.\n");
+  FileInfo* info =(FileInfo*)fileInfo;
+  CURLcode res;
+  curlHandle = curl_easy_init();
+  char* fileOnNet = new char [strlen(info->webRoot)+strlen(info->fileName)+1];
+  strcpy(fileOnNet, info->webRoot);
+  strcat(fileOnNet, info->fileName);
+  char* fileOnDisk = new char [strlen(info->localRoot)+strlen(info->fileName)+1];
+  strcpy(fileOnDisk, info->localRoot);
+  strcat(fileOnDisk, info->fileName);
+
+  if(curlHandle)
+    {
+
+      info->fileHandle = fopen(fileOnDisk, "w");
+
+      curl_easy_setopt(curlHandle, CURLOPT_URL, fileOnNet);
+      curl_easy_setopt(curlHandle, CURLOPT_WRITEDATA, info->fileHandle);
+      curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION, curlWriteFunc);
+      curl_easy_setopt(curlHandle, CURLOPT_READFUNCTION, curlReadFunc);
+      curl_easy_setopt(curlHandle, CURLOPT_NOPROGRESS, false);
+      curl_easy_setopt(curlHandle, CURLOPT_PROGRESSFUNCTION, curlProgressFunc);
+      curl_easy_setopt(curlHandle, CURLOPT_PROGRESSDATA, info->bar);
+
+      if(!isDownloading)
+        {
+#ifdef HAVE_GTK2
+          info->stateButton->disconnectSignal(info->buttonSignal);
+          info->buttonSignal = info->stateButton->connectSignal("button_press_event", info, cancelDownload);
+#endif /* HAVE_GTK2 */
+          info->stateButton->setTitle("please wait");
+
+          downloadThread(info);
+          downloadThreadFinished(info);
+
+          //      res = curl_easy_perform(curlHandle);
+
+          //      fclose(outfile);
+        }
+      else
+        PRINTF(1)("thread already in use\n");
+
+    }
+  return true;
+}
+
+/**
+ *  The downloading process(either threaded or not).
+ * @param fileInfo the FileInfo.
+
+   @todo Threads get locked, if the cancel button is pressed in to small intervals.
+*/
+void* GuiUpdate::downloadThread(void* fileInfo)
+{
+  isDownloading = true;
+  curl_easy_perform(curlHandle);
+}
+
+/**
+ *  Finishes a downloading process.
+ * @param fileInfo the FileInfo.
+*/
+void* GuiUpdate::downloadThreadFinished(void* fileInfo)
+{
+  FileInfo* info =(FileInfo*)fileInfo;
+  if(curlHandle)
+    curl_easy_cleanup(curlHandle);
+
+  PRINTF(4)("Closing the downloaded file.\n");
+  fclose(info->fileHandle);
+
+  if(isDownloading)
+    info->stateButton->setTitle("go on");
+  //  else
+  //    info->stateButton->setTitle("done");
+#ifdef HAVE_GTK2
+  info->stateButton->disconnectSignal(info->buttonSignal);
+  info->buttonSignal = info->stateButton->connectSignal("button_press_event", info, updateDataFunc);
+#endif /* HAVE_GTK2 */
+  isDownloading = false;
+
+}
+
+#ifdef HAVE_GTK2
+/**
+ *  canceles a downloading session.
+ * @param w The widget, that executed this Function.
+ * @param event The event that trigered this Function.
+ * @param bar The Bar, that triggered this event.
+
+   @todo canceling a session in non-threaded mode.
+*/
+gint GuiUpdate::cancelDownload(GtkWidget* w, GdkEventKey* event, void* bar)
+{
+  PRINTF(3)("Cannot cancle the Downloading process until after this File\n");
+}
+#endif /* HAVE_GTK2 */
+
+#endif /* HAVE_CURL */
Index: branches/network/src/lib/gui/gtk_gui/gui_update.h
===================================================================
--- branches/network/src/lib/gui/gtk_gui/gui_update.h	(revision 6636)
+++ branches/network/src/lib/gui/gtk_gui/gui_update.h	(revision 6636)
@@ -0,0 +1,117 @@
+/*!
+  \file gui_update.h
+  \brief File that holds the class that creates the update-menu.
+*/
+
+#ifndef _GUI_UPDATE_H
+#define _GUI_UPDATE_H
+
+#include "gui.h"
+#include "gui_element.h"
+#include "gui_gtk.h"
+
+
+#define DATA_IDENTIFIER "data.oxd"
+
+#include <stdio.h>
+#ifdef HAVE_CURL
+#include <curl/curl.h>
+#include <curl/types.h>
+#include <curl/easy.h>
+#endif /* HAVE_CURL */
+#ifdef HAVE_PTHREAD_H
+#define _MULTI_THREADED
+#include <pthread.h>
+#endif /* HAVE_PTHREAD_H */
+using namespace std;
+
+//! Class that creates the execute-Options.
+class GuiUpdate : public GuiElement
+{
+ private:
+  // Defining Variables
+  char* tmpDir;                         //!< The Temporary directory.
+  char* homeDir;                        //!< The Home directory.
+  char* installDataDir;                 //!< Where to install the Data to.
+  char* installSourceDir;               //!< Where to install the Source to.
+  char* userName;                       //!< The user logged in.
+
+  bool getSystemInfo();
+
+  // Window creation.
+  Frame* updateFrame;                   //!< The Frame that holds the updateOptions.
+  Box* updateBox;                       //!< The Box that holds the updateOptions.
+  CheckButton* autoUpdate;              //!< A Checkbutton to enable the automatic Updating.
+
+
+  Button* updateDataWindowButton;       //!< A Button to update the Data of orxonox.
+  Window* updateDataWindow;             //!< A Window for the data-update.
+  Box* updateDataBox;                   //!< A Box for the Window for the Data-update.
+  ProgressBar* updateDataBar;           //!< A Bar to display the progress of the download.
+  Button* updateDataBegin;              //!< A Button to start the process.
+
+  Button* updateSourceWindowButton;     //!< A Button to update the Source of orxonox. @todo tricky
+  Window* updateSourceWindow;           //!< A Window for the Source-update.
+  Box* updateSourceBox;                 //!< A Box for the Window for the Source-update.
+  ProgressBar* updateSourceBar;         //!< A Bar to display the progress of the download.
+
+  Button* test;                         //!< will be deleted soon.
+
+#ifdef HAVE_GTK2
+  static gint updateDataFunc(GtkWidget* w, GdkEventKey* event, void* info);
+  static gint updateSourceFunc(GtkWidget* w, GdkEventKey* event, void* info);
+#endif /* HAVE_GTK2 */
+
+  static bool checkDataDir(const char* fileName, void* object);
+
+#ifdef HAVE_CURL
+  //! A Struct to hold information about one File to download.
+  struct FileInfo
+  {
+    char* fileName;                     //!< The Name of the file we want to get.
+    char* webRoot;                      //!< The Root of the File on The Web
+    char* localRoot;                    //!< The Root directory to put the files on the local disk.
+    FILE* fileHandle;                   //!< A fileHandler.
+
+    Button* stateButton;                //!< A button that shows either start or cancel;
+    long int buttonSignal;              //!< The Signal of the stateButton.
+    ProgressBar* bar;                   //!< The ProgressBar, that sould be updated.
+  };
+
+  static size_t curlWriteFunc(void* ptr, size_t size, size_t nmemb, FILE* stream);
+  static size_t curlReadFunc(void* ptr, size_t size, size_t nmemb, FILE* stream);
+  static int curlProgressFunc(ProgressBar* bar, double totalSize, double progress, double upTotal, double upProgress);
+
+  static CURL* curlHandle;
+#ifdef HAVE_GTK2
+  static gint cancelDownload(GtkWidget* w, GdkEventKey* event, void* bar);
+#endif /* HAVE_GTK2 */
+  static bool isDownloading;
+  static bool downloadCanceled;
+
+  static bool download(void* fileInfo);
+  static bool downloadWithStyle(void* fileInfo);
+  static void* downloadThread(void* fileInfo);
+  static void* downloadThreadFinished(void* fileInfo);
+
+
+#endif /* HAVE_CURL */
+
+ public:
+  GuiUpdate();
+  ~GuiUpdate();
+
+#ifdef HAVE_CURL
+  void updateDataWindowCreate();
+  Button* updateDataWindowGetButton();
+
+  void updateSourceWindowCreate();
+  Button* updateSourceWindowGetButton();
+
+  bool* checkForUpdates();
+
+#endif /* HAVE_CURL */
+
+};
+
+#endif /* _GUI_UPDATE_H */
Index: branches/network/src/lib/gui/gtk_gui/gui_video.cc
===================================================================
--- branches/network/src/lib/gui/gtk_gui/gui_video.cc	(revision 6636)
+++ branches/network/src/lib/gui/gtk_gui/gui_video.cc	(revision 6636)
@@ -0,0 +1,227 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+
+*/
+
+
+#include "gui_video.h"
+
+#include "gui_gtk.h"
+#include "sdlincl.h"
+#include <stdlib.h>
+
+/**
+ *  Creates the Video-Option-Frame
+*/
+GuiVideo::GuiVideo()
+{
+  Frame* videoFrame;        //!< The Frame that holds the video options.
+
+  videoFrame = new Frame("Video-Options:");
+  videoFrame->setGroupName("video");
+  {
+    Box* videoBox;            //!< The Box that holds the video options.
+
+    videoBox = new Box('v');
+    {
+      CheckButton* fullscreen;  //!< CheckButton for fullscreen-mode
+      Menu* resolution;         //!< Menu for the resolution
+      CheckButton* wireframe;   //!< CheckButton for wireframe Mode.
+
+      fullscreen = new CheckButton(CONFIG_NAME_FULLSCREEN);
+      fullscreen->setFlagName("windowed", "q", 1);
+      fullscreen->setDescription("Starts orxonox in windowed mode");
+      fullscreen->saveability();
+      videoBox->fill(fullscreen);
+      resolution = new Menu(CONFIG_NAME_RESOLUTION);
+      getResolutions(resolution);
+      resolution->saveability();
+      resolution->setFlagName("resolution", "r", 0);
+      resolution->setDescription("Sets the resolution of orxonox");
+      videoBox->fill(resolution);
+      wireframe = new CheckButton(CONFIG_NAME_WIREFRAME);
+      wireframe->setFlagName("wireframe", "w", 0);
+      wireframe->setDescription("Starts orxonox in wireframe mode");
+      wireframe->saveability();
+      videoBox->fill(wireframe);
+
+      videoBox->fill(advancedWindowCreate());
+    }
+    videoFrame->fill(videoBox);
+  }
+  setMainWidget(videoFrame);
+}
+
+/**
+ *  Destructs the Video-stuff
+*/
+GuiVideo::~GuiVideo()
+{
+  // nothing to do here.
+}
+
+/**
+ *  Creates a window, and all it contains for the Source-update.
+*/
+Widget* GuiVideo::advancedWindowCreate()
+{
+  // advanced-Performance-Options
+  Window* advancedWindow;   //!< A Window to display advanced options.
+  Button* advancedButton;   //!< A Button to open the Advanced Video Performance Window.
+  // the button, that opens this Window.
+  advancedButton = new Button("advanced");
+
+  // the Window itself
+  advancedWindow = new Window("Advanced Video Options");
+  advancedWindow->setGroupName(CONFIG_SECTION_VIDEO_ADVANCED);
+  {
+    Box* advancedBox;         //!< A Box to pack the options into.
+
+    advancedBox = new Box('v');
+    {
+      CheckButton* shadows;     //!< CheckButton for shadows
+      CheckButton* fog;         //!< CheckButton for fog.
+      CheckButton* reflections; //!< CheckButton for reflections
+      CheckButton* textures;    //!< CheckButton for textures
+      Menu* textureDetail;      //!< Menu for the Texture-Detail.
+      Label* modelDetailLabel;  //!< Label for model-detail.
+      Menu* modelDetail;        //!< model-detail.
+      CheckButton* particles;   //!< If the Particles should be enabled
+      Label* antiAliasingLabel; //!< Label for the anti-aliasing mode.
+      Menu* antiAliasing;       //!< Menu for the Antialiasing-mode.
+      Label* filterMethodLabel; //!< Label for filtering-Method.
+      Menu* filterMethod;       //!< Menu for filtering Method.
+      Button* closeButton;      //!< A Button to close the Advanced-settingsWindow.
+
+      // Advanced Performance Options
+      shadows = new CheckButton(CONFIG_NAME_SHADOWS);
+      shadows->saveability();
+      advancedBox->fill(shadows);
+
+      fog = new CheckButton(CONFIG_NAME_FOG);
+      fog->saveability();
+      advancedBox->fill(fog);
+
+      reflections = new CheckButton(CONFIG_NAME_REFLECTIONS);
+      reflections->saveability();
+      advancedBox->fill(reflections);
+
+      textures = new CheckButton(CONFIG_NAME_TEXTURES);
+      textures->setDefaultValue(1);
+      textures->saveability();
+      advancedBox->fill(textures);
+
+      textureDetail = new Menu(CONFIG_NAME_TEXTURE_DETAIL, "low", "medium", "high", "lastItem");
+      textureDetail->setDefaultValue(1);
+      textureDetail->saveability();
+      advancedBox->fill(textureDetail);
+
+      modelDetailLabel = new Label(CONFIG_NAME_MODEL_DETAIL);
+      advancedBox->fill(modelDetailLabel);
+      modelDetail = new Menu(CONFIG_NAME_MODEL_DETAIL, "low", "high", "lastItem");
+      modelDetail->setDefaultValue(1);
+      modelDetail->saveability();
+      advancedBox->fill(modelDetail);
+
+      particles = new CheckButton(CONFIG_NAME_PARTICLES_ENABLED);
+      particles->saveability();
+      particles->setDefaultValue(1);
+      advancedBox->fill(particles);
+
+      antiAliasingLabel = new Label("Anti-Aliasing-depth:");
+      advancedBox->fill(antiAliasingLabel);
+      antiAliasing = new Menu(CONFIG_NAME_ANTI_ALIASING, "0", "1", "2", "4", "8",  "lastItem");
+      antiAliasing->setDefaultValue(2);
+      antiAliasing->saveability();
+      advancedBox->fill(antiAliasing);
+
+      filterMethodLabel = new Label("Filtering Method:");
+      advancedBox->fill(filterMethodLabel);
+      filterMethod = new Menu(CONFIG_NAME_FILTER_METHOD, "none", "linear", "bilinear", "trilinear", "anisortopic", "lastItem");
+      filterMethod->setDefaultValue(1);
+      filterMethod->saveability();
+      advancedBox->fill(filterMethod);
+
+
+
+      closeButton = new Button("close");
+#ifdef HAVE_GTK2
+      closeButton->connectSignal("button_press_event", advancedWindow, Window::windowClose);
+#endif /* HAVE_GTK2 */
+
+      advancedBox->fill(closeButton);
+    }
+    advancedWindow->fill(advancedBox);
+  }
+#ifdef HAVE_GTK2
+  advancedButton->connectSignal("button_press_event", advancedWindow, Window::windowOpen);
+  advancedWindow->connectSignal("destroy", advancedWindow, Window::windowClose);
+  advancedWindow->connectSignal("delete_event", advancedWindow, Window::windowClose);
+#endif /* HAVE_GTK2 */
+  Window::addWindow(advancedWindow);
+
+  return advancedButton;
+}
+
+/**
+ *  sets all resolutions to the menu
+ * @param menu the Menu to set The resolutions to.
+*/
+void GuiVideo::getResolutions(Menu* menu)
+{
+  SDL_Init(SDL_INIT_VIDEO);
+  SDL_Rect **modes;
+  int i;
+  int x = 0,y =0; // check for difference
+  char tmpChar[100];
+
+  /* Get available fullscreen/hardware modes */
+  modes=SDL_ListModes(NULL, SDL_FULLSCREEN|SDL_HWSURFACE);
+
+  /* Check is there are any modes available */
+  if(modes == (SDL_Rect **)0){
+    PRINTF(2)("No video-modes available!\n");
+    exit(-1);
+  }
+
+  /* Check if our resolution is restricted */
+  if(modes == (SDL_Rect **)-1){
+    PRINTF(2)("All resolutions available.\n");
+  }
+  else{
+    /* Print valid modes */
+    PRINT(5)("Available Modes\n");
+    for(i = 0; modes[i] ;++i)
+      {
+        if (x != modes[i]->w || y != modes[i]->h)
+          {
+            PRINTF(5)("  %d x %d\n", modes[i]->w, modes[i]->h);
+            sprintf(tmpChar, "%dx%d", modes[i]->w, modes[i]->h);
+            menu->addItem(tmpChar);
+            x = modes[i]->w; y = modes[i]->h;
+          }
+      }
+  }
+  SDL_QuitSubSystem(SDL_INIT_VIDEO);
+  SDL_Quit();
+}
Index: branches/network/src/lib/gui/gtk_gui/gui_video.h
===================================================================
--- branches/network/src/lib/gui/gtk_gui/gui_video.h	(revision 6636)
+++ branches/network/src/lib/gui/gtk_gui/gui_video.h	(revision 6636)
@@ -0,0 +1,29 @@
+/*!
+  \file gui_video.h
+  \brief File that holds the class that creates the Video-Options.
+*/
+#ifndef _GUI_VIDEO_H
+#define _GUI_VIDEO_H
+
+#include "gui.h"
+#include "gui_element.h"
+
+// FORWARD DECLARATIONS
+class Widget;
+class Menu;
+
+//! Class that creates the Video-Options.
+class GuiVideo : public GuiElement
+{
+ private:
+  //  Button* advancedWindowGetButton();
+  
+ public:
+  GuiVideo();
+  ~GuiVideo();
+
+ private:
+  void getResolutions(Menu* menu);
+  Widget* advancedWindowCreate();
+};
+#endif /* _GUI_VIDEO_H */
Index: branches/network/src/lib/gui/gtk_gui/logo.xpm
===================================================================
--- branches/network/src/lib/gui/gtk_gui/logo.xpm	(revision 6636)
+++ branches/network/src/lib/gui/gtk_gui/logo.xpm	(revision 6636)
@@ -0,0 +1,3170 @@
+/* XPM */
+static char * logo_xpm[] = {
+"200 200 2967 2",
+"  	c #000000",
+". 	c #020202",
+"+ 	c #010101",
+"@ 	c #242424",
+"# 	c #2A2A2A",
+"$ 	c #030303",
+"% 	c #040404",
+"& 	c #8B8B8B",
+"* 	c #A0A0A0",
+"= 	c #848484",
+"- 	c #0D0D0D",
+"; 	c #E3E3E3",
+"> 	c #F4F4F4",
+", 	c #181818",
+"' 	c #1C1C1C",
+") 	c #6D6D6D",
+"! 	c #A7A7A7",
+"~ 	c #CECECE",
+"{ 	c #080808",
+"] 	c #555555",
+"^ 	c #FFFFFF",
+"/ 	c #828282",
+"( 	c #090909",
+"_ 	c #B1B1B1",
+": 	c #D3D3D3",
+"< 	c #D5D5D5",
+"[ 	c #FDFDFD",
+"} 	c #8D8D8D",
+"| 	c #D1D1D1",
+"1 	c #FEFEFE",
+"2 	c #E2E2E2",
+"3 	c #6E6E6E",
+"4 	c #FCFCFC",
+"5 	c #EAEAEA",
+"6 	c #0E0E0E",
+"7 	c #141414",
+"8 	c #F7F7F7",
+"9 	c #525252",
+"0 	c #3D3D3D",
+"a 	c #F9F9F9",
+"b 	c #565656",
+"c 	c #3B3B3B",
+"d 	c #F5F5F5",
+"e 	c #1F1F1F",
+"f 	c #FDFEFE",
+"g 	c #FFFEFE",
+"h 	c #EBEAE9",
+"i 	c #29292A",
+"j 	c #9D9D9D",
+"k 	c #FEFDFE",
+"l 	c #FEFEFD",
+"m 	c #BABABA",
+"n 	c #020101",
+"o 	c #111214",
+"p 	c #E2E2E1",
+"q 	c #4B4B4B",
+"r 	c #969696",
+"s 	c #535353",
+"t 	c #FAFFFF",
+"u 	c #FCFBFC",
+"v 	c #C8C6C6",
+"w 	c #050505",
+"x 	c #F3F2F2",
+"y 	c #FDFFFA",
+"z 	c #FAFCFF",
+"A 	c #F2F7F8",
+"B 	c #FCFDFE",
+"C 	c #FAFAFA",
+"D 	c #333333",
+"E 	c #030404",
+"F 	c #B7B5B3",
+"G 	c #FBFFFF",
+"H 	c #606060",
+"I 	c #292929",
+"J 	c #F8F8F8",
+"K 	c #C1C1C1",
+"L 	c #717171",
+"M 	c #FCFEFF",
+"N 	c #FDFCF9",
+"O 	c #FDFCFA",
+"P 	c #FCFCFB",
+"Q 	c #838383",
+"R 	c #FCFEFE",
+"S 	c #FEFDF7",
+"T 	c #BCDFF5",
+"U 	c #A4CDED",
+"V 	c #949494",
+"W 	c #6E6D6F",
+"X 	c #FEFCFB",
+"Y 	c #FBFEFF",
+"Z 	c #FFFDF8",
+"` 	c #919191",
+" .	c #C0C0C0",
+"..	c #C9C9C9",
+"+.	c #E8E8E8",
+"@.	c #323232",
+"#.	c #FBFCFD",
+"$.	c #FCFCFA",
+"%.	c #BAD9E8",
+"&.	c #F7FCFB",
+"*.	c #FAFDFE",
+"=.	c #0B0B0B",
+"-.	c #DBDBDB",
+";.	c #FBFDFE",
+">.	c #50A7EF",
+",.	c #3696F1",
+"'.	c #FAFEFE",
+").	c #EFEFEF",
+"!.	c #373737",
+"~.	c #FAFCFC",
+"{.	c #F6FBFC",
+"].	c #BADBEE",
+"^.	c #FEFFFF",
+"/.	c #2F2F2F",
+"(.	c #CACACA",
+"_.	c #FAFAF7",
+":.	c #5E5F5D",
+"<.	c #030102",
+"[.	c #FEFDFD",
+"}.	c #F9FCFA",
+"|.	c #3898EC",
+"1.	c #9FCBED",
+"2.	c #FCFDFD",
+"3.	c #EEEEEC",
+"4.	c #262827",
+"5.	c #010103",
+"6.	c #4C4C4C",
+"7.	c #D8ECFA",
+"8.	c #0A80F5",
+"9.	c #0780F6",
+"0.	c #C9E4F7",
+"a.	c #FEFCFA",
+"b.	c #68696A",
+"c.	c #1A1A1A",
+"d.	c #DDDDDD",
+"e.	c #FAFCFD",
+"f.	c #FDFBF5",
+"g.	c #B4D7F2",
+"h.	c #2A8EE9",
+"i.	c #F6FEFF",
+"j.	c #FEFCFE",
+"k.	c #CFD4D1",
+"l.	c #050305",
+"m.	c #000002",
+"n.	c #020002",
+"o.	c #030101",
+"p.	c #474646",
+"q.	c #E9E9E7",
+"r.	c #D6D6D6",
+"s.	c #B2B2B2",
+"t.	c #FCFDFC",
+"u.	c #FDFFFD",
+"v.	c #FEFEFF",
+"w.	c #F8F8FA",
+"x.	c #858784",
+"y.	c #060606",
+"z.	c #E0E0E0",
+"A.	c #F9FCFC",
+"B.	c #1E8CF3",
+"C.	c #1B86F3",
+"D.	c #CDE9F4",
+"E.	c #FCFFFE",
+"F.	c #FDFDFC",
+"G.	c #C1C3C3",
+"H.	c #090908",
+"I.	c #B5B5B5",
+"J.	c #7ABAEE",
+"K.	c #047EFC",
+"L.	c #0181FD",
+"M.	c #5DAAEE",
+"N.	c #F7FDFF",
+"O.	c #FCFDFA",
+"P.	c #D5D6D6",
+"Q.	c #070605",
+"R.	c #B3B3B3",
+"S.	c #FDFCFC",
+"T.	c #FAFCFB",
+"U.	c #E3F3FA",
+"V.	c #228BF2",
+"W.	c #0F7FEE",
+"X.	c #DBEDF5",
+"Y.	c #FDFBFC",
+"Z.	c #F8FEFA",
+"`.	c #111011",
+" +	c #020001",
+".+	c #080506",
+"++	c #676A6C",
+"@+	c #F5F9FA",
+"#+	c #BCBCBC",
+"$+	c #7E7E7E",
+"%+	c #FDFDF8",
+"&+	c #FEFDF9",
+"*+	c #A8A8A8",
+"=+	c #151515",
+"-+	c #0F0F0F",
+";+	c #FEFDFA",
+">+	c #D5EDF5",
+",+	c #0E7EEE",
+"'+	c #017FFC",
+")+	c #3798F1",
+"!+	c #EDF6F4",
+"~+	c #8C8E8D",
+"{+	c #343434",
+"]+	c #FBFBFB",
+"^+	c #EEF8FB",
+"/+	c #238FF0",
+"(+	c #0281FD",
+"_+	c #027FFC",
+":+	c #0F82F3",
+"<+	c #E2F2FB",
+"[+	c #FEFDFB",
+"}+	c #454646",
+"|+	c #707070",
+"1+	c #F7FCFC",
+"2+	c #48A1EC",
+"3+	c #047FF8",
+"4+	c #067EF9",
+"5+	c #C5E6F6",
+"6+	c #FBFEFC",
+"7+	c #2A292A",
+"8+	c #060504",
+"9+	c #9B9E9E",
+"0+	c #FAFDFD",
+"a+	c #FFFCF6",
+"b+	c #BBBBBB",
+"c+	c #FFFFFE",
+"d+	c #FBFBFC",
+"e+	c #E8F5F6",
+"f+	c #F3FEFE",
+"g+	c #CFCFCF",
+"h+	c #262626",
+"i+	c #B4DCF4",
+"j+	c #067FF3",
+"k+	c #0180FD",
+"l+	c #0380FC",
+"m+	c #73B4EC",
+"n+	c #FDFFFE",
+"o+	c #FCFBFB",
+"p+	c #9DCEF2",
+"q+	c #057FFB",
+"r+	c #0280FB",
+"s+	c #037EFE",
+"t+	c #0380FB",
+"u+	c #86BEEE",
+"v+	c #CCCDCD",
+"w+	c #7EBDEE",
+"x+	c #047FFA",
+"y+	c #0280FC",
+"z+	c #047EFE",
+"A+	c #9ECCF3",
+"B+	c #4D4D4C",
+"C+	c #171717",
+"D+	c #CCCBCA",
+"E+	c #FDFCFB",
+"F+	c #F9FCFB",
+"G+	c #E8F5F8",
+"H+	c #818181",
+"I+	c #5E5E5E",
+"J+	c #FEFFFD",
+"K+	c #A5C8E3",
+"L+	c #75B6E9",
+"M+	c #F6FBFB",
+"N+	c #FBFCFB",
+"O+	c #F0EFEC",
+"P+	c #3C3C3C",
+"Q+	c #5F5F5F",
+"R+	c #FFFEFB",
+"S+	c #9ACCF5",
+"T+	c #0182FB",
+"U+	c #037DFE",
+"V+	c #0180FC",
+"W+	c #0581F8",
+"X+	c #A6D4F3",
+"Y+	c #FBFEF6",
+"Z+	c #FCFEFD",
+"`+	c #F9FCFF",
+" @	c #3898E9",
+".@	c #017EFF",
+"+@	c #0181FA",
+"@@	c #0180FE",
+"#@	c #2990EE",
+"$@	c #F2FDFE",
+"%@	c #FDFEFA",
+"&@	c #FEFEFC",
+"*@	c #FDFDF9",
+"=@	c #C1E2F4",
+"-@	c #097EF1",
+";@	c #0080FF",
+">@	c #7EBBEF",
+",@	c #FBFDFC",
+"'@	c #8A8A8A",
+")@	c #030201",
+"!@	c #3D3A39",
+"~@	c #FDFEFD",
+"{@	c #FEFCF7",
+"]@	c #F4FCFC",
+"^@	c #88C3ED",
+"/@	c #79B5EA",
+"(@	c #7F7F7F",
+"_@	c #9B9B9B",
+":@	c #404040",
+"<@	c #424242",
+"[@	c #FDFEFC",
+"}@	c #A4D3F0",
+"|@	c #087EF6",
+"1@	c #4DA1EA",
+"2@	c #E6F4FB",
+"3@	c #FDFCF6",
+"4@	c #F6FEFE",
+"5@	c #72B1E9",
+"6@	c #0181FC",
+"7@	c #037EFF",
+"8@	c #0281F8",
+"9@	c #1B83ED",
+"0@	c #D2E9F5",
+"a@	c #FCFDF8",
+"b@	c #C0E0F3",
+"c@	c #0C7DF9",
+"d@	c #0282F9",
+"e@	c #037DFF",
+"f@	c #0380FE",
+"g@	c #057EF8",
+"h@	c #ABD2F2",
+"i@	c #FFFDFF",
+"j@	c #FBFFFA",
+"k@	c #DEF0F6",
+"l@	c #288BEE",
+"m@	c #0180FF",
+"n@	c #0081FE",
+"o@	c #60ADED",
+"p@	c #FAFDFC",
+"q@	c #FDFDFB",
+"r@	c #9F9E9F",
+"s@	c #616165",
+"t@	c #EBF1ED",
+"u@	c #FAFDFB",
+"v@	c #EFF8F9",
+"w@	c #6BB5F0",
+"x@	c #067EF7",
+"y@	c #90C4F2",
+"z@	c #6A6A6A",
+"A@	c #121212",
+"B@	c #909090",
+"C@	c #BFBFBF",
+"D@	c #444444",
+"E@	c #393939",
+"F@	c #FCFDF6",
+"G@	c #B3D4EE",
+"H@	c #0280FA",
+"I@	c #3596EE",
+"J@	c #CAE7F6",
+"K@	c #EEEEEE",
+"L@	c #FDFFFF",
+"M@	c #56A9F0",
+"N@	c #0281FB",
+"O@	c #017FFF",
+"P@	c #0081FC",
+"Q@	c #0280FE",
+"R@	c #3790EC",
+"S@	c #EDF9F7",
+"T@	c #FCFAFD",
+"U@	c #61B3F1",
+"V@	c #037FFD",
+"W@	c #489EEC",
+"X@	c #F5FCFD",
+"Y@	c #FBFDF8",
+"Z@	c #F6F8FC",
+"`@	c #4EA2EF",
+" #	c #0080FE",
+".#	c #3192ED",
+"+#	c #F7FEFE",
+"@#	c #F7F7F4",
+"##	c #FDFAF8",
+"$#	c #E3F5F8",
+"%#	c #4499E8",
+"&#	c #0381F5",
+"*#	c #A6D3ED",
+"=#	c #2C2C2C",
+"-#	c #A1A1A1",
+";#	c #414141",
+">#	c #C4C4C4",
+",#	c #4A4A49",
+"'#	c #DEF3FA",
+")#	c #057FF6",
+"!#	c #1E8AF1",
+"~#	c #BDDEF3",
+"{#	c #288DF0",
+"]#	c #007FFF",
+"^#	c #0082F8",
+"/#	c #047DFE",
+"(#	c #0281F9",
+"_#	c #057EFA",
+":#	c #6FB4ED",
+"<#	c #F9FDFB",
+"[#	c #E0F0F6",
+"}#	c #1281F3",
+"|#	c #0281FC",
+"1#	c #4CA4EA",
+"2#	c #077EF7",
+"3#	c #037FFC",
+"4#	c #0880F4",
+"5#	c #CCE7F6",
+"6#	c #FBFDFD",
+"7#	c #86C2EE",
+"8#	c #057FF8",
+"9#	c #0380FD",
+"0#	c #1987F4",
+"a#	c #EDF7FB",
+"b#	c #FEFFFE",
+"c#	c #FEFEFB",
+"d#	c #C4E5F5",
+"e#	c #278AE6",
+"f#	c #B6D8F1",
+"g#	c #4A4A4A",
+"h#	c #646464",
+"i#	c #DEDEDE",
+"j#	c #FFFDFE",
+"k#	c #FDFEF7",
+"l#	c #CAC9C8",
+"m#	c #4D4F52",
+"n#	c #010203",
+"o#	c #050304",
+"p#	c #E4F2FC",
+"q#	c #0680F8",
+"r#	c #0180FB",
+"s#	c #0F7EF0",
+"t#	c #9BCDED",
+"u#	c #F9FCFE",
+"v#	c #FCFDF9",
+"w#	c #FDFFFC",
+"x#	c #E1F4F9",
+"y#	c #1183F0",
+"z#	c #067EFD",
+"A#	c #2D96EF",
+"B#	c #067EF6",
+"C#	c #087FF5",
+"D#	c #A6D3F2",
+"E#	c #80BFF1",
+"F#	c #067FF8",
+"G#	c #1883EB",
+"H#	c #E4F9FC",
+"I#	c #3E9AF1",
+"J#	c #017FFE",
+"K#	c #0380F8",
+"L#	c #72B5F0",
+"M#	c #BBE0F4",
+"N#	c #0F83F7",
+"O#	c #2E94F0",
+"P#	c #087DF9",
+"Q#	c #037FFA",
+"R#	c #087DF2",
+"S#	c #D7EEF8",
+"T#	c #F9FEFE",
+"U#	c #FAFDFA",
+"V#	c #A0CFF1",
+"W#	c #1688F4",
+"X#	c #057FF9",
+"Y#	c #047FF9",
+"Z#	c #E4F3FB",
+"`#	c #4E4F4F",
+" $	c #C9C9C4",
+".$	c #F1F1F1",
+"+$	c #8E8E8E",
+"@$	c #FFFCFD",
+"#$	c #FCFFFA",
+"$$	c #FAFEFB",
+"%$	c #D0CFCE",
+"&$	c #555357",
+"*$	c #040405",
+"=$	c #F4FBFD",
+"-$	c #238CF1",
+";$	c #027EFE",
+">$	c #0184FC",
+",$	c #62AEEC",
+"'$	c #F6FCFE",
+")$	c #D9EDF7",
+"!$	c #097DF3",
+"~$	c #067EF8",
+"{$	c #E5F7FB",
+"]$	c #429BE9",
+"^$	c #0E81F0",
+"/$	c #178BF7",
+"($	c #0181FE",
+"_$	c #7AB7EE",
+":$	c #FAFEF9",
+"<$	c #A0CCEE",
+"[$	c #047EFB",
+"}$	c #0E83F2",
+"|$	c #1A8AF0",
+"1$	c #037FFE",
+"2$	c #1D89EF",
+"3$	c #DCF4FB",
+"4$	c #268BEC",
+"5$	c #027FFE",
+"6$	c #057EF9",
+"7$	c #B3D7F4",
+"8$	c #F6FBFE",
+"9$	c #7CBBF0",
+"0$	c #097CF7",
+"a$	c #067FF5",
+"b$	c #FBFDFF",
+"c$	c #FCFEF9",
+"d$	c #FDFEFB",
+"e$	c #FFFEFF",
+"f$	c #FEFCFC",
+"g$	c #FDFFF9",
+"h$	c #E6EFF3",
+"i$	c #F9FBF9",
+"j$	c #FEFBF8",
+"k$	c #F9FEFF",
+"l$	c #FDFEF8",
+"m$	c #DDDCDB",
+"n$	c #787878",
+"o$	c #101010",
+"p$	c #F8FEFE",
+"q$	c #328EEA",
+"r$	c #0081FD",
+"s$	c #0081FB",
+"t$	c #077EF8",
+"u$	c #479AE9",
+"v$	c #DEF2FA",
+"w$	c #A2D0F2",
+"x$	c #248AEF",
+"y$	c #F2FBFA",
+"z$	c #D8F0F9",
+"A$	c #1C89ED",
+"B$	c #027FFF",
+"C$	c #037FFB",
+"D$	c #0B80F6",
+"E$	c #D2E9F3",
+"F$	c #EDFAFB",
+"G$	c #1A87EF",
+"H$	c #0B81F4",
+"I$	c #BEDFF3",
+"J$	c #F8FCF9",
+"K$	c #3D98ED",
+"L$	c #027FFB",
+"M$	c #027FFA",
+"N$	c #9ACCF4",
+"O$	c #E3F1F7",
+"P$	c #58A9EE",
+"Q$	c #0380F7",
+"R$	c #0081FA",
+"S$	c #1E89EE",
+"T$	c #EEF9FD",
+"U$	c #0A0A0A",
+"V$	c #5A5A5A",
+"W$	c #D0D0D0",
+"X$	c #FAFCF7",
+"Y$	c #EDF6FA",
+"Z$	c #FAFBFD",
+"`$	c #4F4F4F",
+" %	c #CDCECC",
+".%	c #63A5E3",
+"+%	c #66B3EE",
+"@%	c #D6ECF7",
+"#%	c #FCFEFB",
+"$%	c #EBEBEB",
+"%%	c #E7E7E6",
+"&%	c #FEFFFC",
+"*%	c #F2FFFF",
+"=%	c #3B93EA",
+"-%	c #0380F5",
+";%	c #0181FB",
+">%	c #2E90F1",
+",%	c #5BABF1",
+"'%	c #3E92E8",
+")%	c #F4FDFE",
+"!%	c #ACD4EF",
+"~%	c #0780F5",
+"{%	c #4C9FED",
+"]%	c #78B7EE",
+"^%	c #037FFF",
+"/%	c #0282FA",
+"(%	c #8CC1F0",
+"_%	c #F8FCFC",
+":%	c #6DB3F3",
+"<%	c #027FFD",
+"[%	c #0280FD",
+"}%	c #419CEB",
+"|%	c #3095F2",
+"1%	c #047FFC",
+"2%	c #067FF7",
+"3%	c #308FEA",
+"4%	c #E8E8E7",
+"5%	c #D4D4D4",
+"6%	c #E3F8FC",
+"7%	c #8EC0ED",
+"8%	c #53A2E6",
+"9%	c #717173",
+"0%	c #A0D0EF",
+"a%	c #0B7DF5",
+"b%	c #1084F5",
+"c%	c #69AEEA",
+"d%	c #D4ECF6",
+"e%	c #F8FDFC",
+"f%	c #FDFAFA",
+"g%	c #67B0F7",
+"h%	c #0381F9",
+"i%	c #5FB0EC",
+"j%	c #5DAAED",
+"k%	c #067DF8",
+"l%	c #67B1F4",
+"m%	c #FCFEFC",
+"n%	c #F8FDFB",
+"o%	c #75B6EC",
+"p%	c #0680F7",
+"q%	c #AED5F4",
+"r%	c #D8EEF7",
+"s%	c #1181F3",
+"t%	c #4AA1ED",
+"u%	c #F5FBFD",
+"v%	c #8DC5F0",
+"w%	c #0081FF",
+"x%	c #0480F9",
+"y%	c #3B97F0",
+"z%	c #5AABE8",
+"A%	c #0182FE",
+"B%	c #358EE9",
+"C%	c #F5FEFE",
+"D%	c #FEFFFB",
+"E%	c #FAFEFA",
+"F%	c #D7EBF7",
+"G%	c #6DB3ED",
+"H%	c #1D88EE",
+"I%	c #87C3F0",
+"J%	c #FCFDFB",
+"K%	c #F8F9F8",
+"L%	c #ECF9F9",
+"M%	c #1C88F6",
+"N%	c #0E80ED",
+"O%	c #62ACF0",
+"P%	c #FBFFFB",
+"Q%	c #FCFEFA",
+"R%	c #68B0F0",
+"S%	c #057DFE",
+"T%	c #449FF2",
+"U%	c #F8FAF9",
+"V%	c #90CAF1",
+"W%	c #087DF4",
+"X%	c #017FFD",
+"Y%	c #80BCEE",
+"Z%	c #FEFEFA",
+"`%	c #FDFCFD",
+" &	c #EFFAFA",
+".&	c #489CED",
+"+&	c #3193F1",
+"@&	c #F2FAFC",
+"#&	c #FCFBFE",
+"$&	c #52A3EE",
+"%&	c #0083F9",
+"&&	c #288EF5",
+"*&	c #DDEDF6",
+"=&	c #AED6EF",
+"-&	c #60A8EA",
+";&	c #F3FBFA",
+">&	c #73B8EB",
+",&	c #61AFF5",
+"'&	c #FBFFFD",
+")&	c #D4ECF7",
+"!&	c #62ADEF",
+"~&	c #0A82F4",
+"{&	c #037EFC",
+"]&	c #D8ECF6",
+"^&	c #FDFDFE",
+"/&	c #3F3F3F",
+"(&	c #020203",
+"_&	c #C7C7C5",
+":&	c #FEFEF8",
+"<&	c #63ACE9",
+"[&	c #0380FA",
+"}&	c #0A7FF1",
+"|&	c #5AAAF1",
+"1&	c #CDE7F5",
+"2&	c #FAFBFA",
+"3&	c #FDFBF9",
+"4&	c #82C1EC",
+"5&	c #047FFB",
+"6&	c #057FFA",
+"7&	c #3298F3",
+"8&	c #A8D4F0",
+"9&	c #1787F2",
+"0&	c #067DFB",
+"a&	c #037EFD",
+"b&	c #A9D3EE",
+"c&	c #FAFFFD",
+"d&	c #DBEDF8",
+"e&	c #1484F5",
+"f&	c #8BC3EB",
+"g&	c #B7DCF1",
+"h&	c #1481F5",
+"i&	c #B7DCF4",
+"j&	c #FBFDF6",
+"k&	c #FAFEFF",
+"l&	c #DBEFF8",
+"m&	c #0781F6",
+"n&	c #92C8F0",
+"o&	c #F7FCFD",
+"p&	c #6CB6F1",
+"q&	c #0180FA",
+"r&	c #FEFBFE",
+"s&	c #CFE9F5",
+"t&	c #5CACF1",
+"u&	c #077EF6",
+"v&	c #047EFD",
+"w&	c #4DA5F0",
+"x&	c #FCFCFD",
+"y&	c #D9D9D9",
+"z&	c #6B6A68",
+"A&	c #FCFFFD",
+"B&	c #BBDCF6",
+"C&	c #077FF5",
+"D&	c #51A6EE",
+"E&	c #B2D6F2",
+"F&	c #98CCEB",
+"G&	c #0480FA",
+"H&	c #2491F2",
+"I&	c #F6FCFD",
+"J&	c #FCFFFB",
+"K&	c #C8E5F5",
+"L&	c #2F94EE",
+"M&	c #0381FB",
+"N&	c #057DFD",
+"O&	c #CBE6F4",
+"P&	c #FEFEF9",
+"Q&	c #A5D6F1",
+"R&	c #1A84EA",
+"S&	c #E3F3F7",
+"T&	c #FFFEFD",
+"U&	c #F6F9F9",
+"V&	c #328FEA",
+"W&	c #82BBEB",
+"X&	c #FBFEFE",
+"Y&	c #FFFEFC",
+"Z&	c #ECF7FA",
+"`&	c #0E7FF0",
+" *	c #1888F3",
+".*	c #B9DCF2",
+"+*	c #FBFEFD",
+"@*	c #4099F1",
+"#*	c #74BBF2",
+"$*	c #C6E6F6",
+"%*	c #57A9ED",
+"&*	c #097EF8",
+"**	c #057EFB",
+"=*	c #A3CEF0",
+"-*	c #858581",
+";*	c #505050",
+">*	c #CCCCCC",
+",*	c #8F8F8F",
+"'*	c #626262",
+")*	c #F6F6F6",
+"!*	c #EEF9FB",
+"~*	c #1F89F2",
+"{*	c #047EFA",
+"]*	c #0281FE",
+"^*	c #1588F4",
+"/*	c #0480FB",
+"(*	c #0A7FED",
+"_*	c #EAF7FB",
+":*	c #FCFFFF",
+"<*	c #FFFEFA",
+"[*	c #E0F5FA",
+"}*	c #489EE7",
+"|*	c #0F81F2",
+"1*	c #E6F4FA",
+"2*	c #C2DFEC",
+"3*	c #FDFFFB",
+"4*	c #C4E3EF",
+"5*	c #EFFBFB",
+"6*	c #F6FFFD",
+"7*	c #3795EF",
+"8*	c #3898F0",
+"9*	c #CEE6F2",
+"0*	c #389BF4",
+"a*	c #168AF7",
+"b*	c #0C7FF2",
+"c*	c #0183FD",
+"d*	c #1584F4",
+"e*	c #E7F5FA",
+"f*	c #F9FDFC",
+"g*	c #FDFAFB",
+"h*	c #2C2C2B",
+"i*	c #BEBEBE",
+"j*	c #EDEDED",
+"k*	c #727272",
+"l*	c #A2A2A2",
+"m*	c #E5E5E5",
+"n*	c #858585",
+"o*	c #474747",
+"p*	c #1D1D1D",
+"q*	c #A9A9A9",
+"r*	c #6EB2EE",
+"s*	c #0D7DED",
+"t*	c #E6F8F9",
+"u*	c #FEFCF9",
+"v*	c #F5FCFB",
+"w*	c #3192E6",
+"x*	c #FFFDFC",
+"y*	c #52A1EC",
+"z*	c #5AA5EA",
+"A*	c #E4F5FA",
+"B*	c #F5FDFE",
+"C*	c #1C88EB",
+"D*	c #0282F7",
+"E*	c #1A89F0",
+"F*	c #057EFD",
+"G*	c #55A5F0",
+"H*	c #F7FDFA",
+"I*	c #FCFAF9",
+"J*	c #D5D6D5",
+"K*	c #111111",
+"L*	c #777777",
+"M*	c #E6E6E6",
+"N*	c #C2C2C2",
+"O*	c #E7E7E7",
+"P*	c #D7D7D7",
+"Q*	c #797979",
+"R*	c #CAE4F3",
+"S*	c #087EF5",
+"T*	c #B5DDF2",
+"U*	c #93CAF2",
+"V*	c #248CF1",
+"W*	c #0080FD",
+"X*	c #077EF9",
+"Y*	c #BFDFF1",
+"Z*	c #F8FCFE",
+"`*	c #CBDFEA",
+" =	c #F5FEFD",
+".=	c #FEFFF8",
+"+=	c #FFFDFD",
+"@=	c #C4E1F3",
+"#=	c #F6FCF9",
+"$=	c #FEFFFA",
+"%=	c #EEFCFE",
+"&=	c #0A7EEC",
+"*=	c #258BF2",
+"==	c #90CAF0",
+"-=	c #D9F0F5",
+";=	c #A9D5F1",
+">=	c #A4A3A5",
+",=	c #6A6A69",
+"'=	c #2B2B2B",
+")=	c #5D5D5D",
+"!=	c #FDFAFD",
+"~=	c #F8FEFC",
+"{=	c #3497F4",
+"]=	c #057EFC",
+"^=	c #5BA8ED",
+"/=	c #F8FDFE",
+"(=	c #F6FCFB",
+"_=	c #9ECBF1",
+":=	c #3699EF",
+"<=	c #0980F2",
+"[=	c #ADD8F7",
+"}=	c #FEFDFC",
+"|=	c #FFFFFB",
+"1=	c #FFFFFD",
+"2=	c #E8FAFC",
+"3=	c #107BF2",
+"4=	c #2890F1",
+"5=	c #9ACBEE",
+"6=	c #F3FDFD",
+"7=	c #87C2F0",
+"8=	c #1989F1",
+"9=	c #E5F6FB",
+"0=	c #FAFEFD",
+"a=	c #F6FDFE",
+"b=	c #6C6C6C",
+"c=	c #A6A6A6",
+"d=	c #FFFFFA",
+"e=	c #E8F0F4",
+"f=	c #539CE1",
+"g=	c #72B8F0",
+"h=	c #A2D3EE",
+"i=	c #D9EDF8",
+"j=	c #F0F9F8",
+"k=	c #FCFEF8",
+"l=	c #FEFFF9",
+"m=	c #81C0F1",
+"n=	c #1583ED",
+"o=	c #EAF7FC",
+"p=	c #FBFDFA",
+"q=	c #F8FBFC",
+"r=	c #B9DDF6",
+"s=	c #4B9FF0",
+"t=	c #0881F7",
+"u=	c #AED4F1",
+"v=	c #FFFEF4",
+"w=	c #B7DBF2",
+"x=	c #0283FC",
+"y=	c #2E93F2",
+"z=	c #9ECEF1",
+"A=	c #F3F9FC",
+"B=	c #FAFFFE",
+"C=	c #3092EC",
+"D=	c #0181F9",
+"E=	c #75B6EE",
+"F=	c #FDFDFA",
+"G=	c #FAFCFE",
+"H=	c #F1FCFD",
+"I=	c #E1F1FA",
+"J=	c #B2D5F0",
+"K=	c #75B7F4",
+"L=	c #51A2E7",
+"M=	c #D8E7ED",
+"N=	c #E4E4E3",
+"O=	c #8CC6F1",
+"P=	c #057CFA",
+"Q=	c #0480F8",
+"R=	c #057DF9",
+"S=	c #2088F3",
+"T=	c #53A5F0",
+"U=	c #7FBDEF",
+"V=	c #B8DCF2",
+"W=	c #E1F0F8",
+"X=	c #F4FFF9",
+"Y=	c #FEFBF9",
+"Z=	c #CDEAF5",
+"`=	c #0982F4",
+" -	c #A4CEF2",
+".-	c #FEFDFF",
+"+-	c #C0DFF5",
+"@-	c #50A1ED",
+"#-	c #80B7E2",
+"$-	c #BDDCF2",
+"%-	c #3792EE",
+"&-	c #A4D0F1",
+"*-	c #F2FBFC",
+"=-	c #FDFEF9",
+"--	c #D6EAF4",
+";-	c #0680F9",
+">-	c #BDDEF4",
+",-	c #F7FEFF",
+"'-	c #E3F6FC",
+")-	c #BCDBF2",
+"!-	c #8AC4F1",
+"~-	c #53A5EB",
+"{-	c #2790EF",
+"]-	c #077FF4",
+"^-	c #0480F7",
+"/-	c #7ABAEF",
+"(-	c #FBFCFC",
+"_-	c #505152",
+":-	c #49A4EB",
+"<-	c #057EF7",
+"[-	c #0D83F1",
+"}-	c #228CF2",
+"|-	c #5EAAEE",
+"1-	c #8AC5F1",
+"2-	c #1385F6",
+"3-	c #51A8F1",
+"4-	c #F9FDF9",
+"5-	c #EBF8F8",
+"6-	c #F6F9FB",
+"7-	c #F0FBF7",
+"8-	c #7CBCEF",
+"9-	c #1384F2",
+"0-	c #86C3EF",
+"a-	c #60ACEE",
+"b-	c #3594EA",
+"c-	c #1584EF",
+"d-	c #2F8FEE",
+"e-	c #EAF6F8",
+"f-	c #020302",
+"g-	c #B7B5B7",
+"h-	c #D0E9F6",
+"i-	c #1380F1",
+"j-	c #0281F7",
+"k-	c #0E80F2",
+"l-	c #EBF4F9",
+"m-	c #FDFEFF",
+"n-	c #F7FEFB",
+"o-	c #2B91EE",
+"p-	c #0E81F5",
+"q-	c #BBE0F5",
+"r-	c #C5C5C5",
+"s-	c #191919",
+"t-	c #ECECEC",
+"u-	c #FCFDFF",
+"v-	c #8DC6F1",
+"w-	c #0082FE",
+"x-	c #0280F9",
+"y-	c #057DFB",
+"z-	c #99CDEF",
+"A-	c #C1DDF4",
+"B-	c #0082FC",
+"C-	c #047DFF",
+"D-	c #047FF7",
+"E-	c #74B5E8",
+"F-	c #EEEBEF",
+"G-	c #272728",
+"H-	c #FEFCFD",
+"I-	c #F1FAFA",
+"J-	c #409DF0",
+"K-	c #54AAEF",
+"L-	c #72B3EB",
+"M-	c #3995EB",
+"N-	c #1685F2",
+"O-	c #0480FC",
+"P-	c #3995EF",
+"Q-	c #67B3EE",
+"R-	c #0380F9",
+"S-	c #0281FA",
+"T-	c #1281EF",
+"U-	c #2B8EEA",
+"V-	c #61ACF0",
+"W-	c #6AB4EA",
+"X-	c #0481F9",
+"Y-	c #027EFB",
+"Z-	c #3992EC",
+"`-	c #EDFBFD",
+" ;	c #6E716F",
+".;	c #010000",
+"+;	c #FEFBFA",
+"@;	c #D1EBF8",
+"#;	c #1A86ED",
+"$;	c #0181FF",
+"%;	c #3090ED",
+"&;	c #F6FDFD",
+"*;	c #EAF6F7",
+"=;	c #C1DFF2",
+"-;	c #8EC7F0",
+";;	c #61AEF4",
+">;	c #3090EC",
+",;	c #0682F7",
+"';	c #0E7FEF",
+");	c #D5EBF5",
+"!;	c #FBFFFE",
+"~;	c #1F89F1",
+"{;	c #097DF4",
+"];	c #2B8FEC",
+"^;	c #55A6F2",
+"/;	c #81BEF0",
+"(;	c #E1F1F6",
+"_;	c #F3FDFC",
+":;	c #F6FCF7",
+"<;	c #52A4E8",
+"[;	c #0A7FF6",
+"};	c #BADDF3",
+"|;	c #C7CACA",
+"1;	c #EDEEED",
+"2;	c #91C7EF",
+"3;	c #0580F6",
+"4;	c #6CB3EC",
+"5;	c #FAFEFC",
+"6;	c #DFF1FA",
+"7;	c #B4D7ED",
+"8;	c #CAE3ED",
+"9;	c #FDFBFA",
+"0;	c #EAF6F9",
+"a;	c #AED1E7",
+"b;	c #DDF1F9",
+"c;	c #F6FFFE",
+"d;	c #F7FFFF",
+"e;	c #FFFCFC",
+"f;	c #9FCCEE",
+"g;	c #71B5EE",
+"h;	c #FBFCFA",
+"i;	c #303030",
+"j;	c #434343",
+"k;	c #B6B6B6",
+"l;	c #F2F2F2",
+"m;	c #F9FFFD",
+"n;	c #F1FBF8",
+"o;	c #3F98E7",
+"p;	c #0480FD",
+"q;	c #0A82F1",
+"r;	c #C6E5F7",
+"s;	c #FEFDF8",
+"t;	c #FCFBF7",
+"u;	c #FEFBF5",
+"v;	c #FDFBFB",
+"w;	c #FCFFFC",
+"x;	c #E5F3F9",
+"y;	c #1586F2",
+"z;	c #2A91F3",
+"A;	c #EAF4FC",
+"B;	c #FBFEFA",
+"C;	c #F0F0F0",
+"D;	c #575757",
+"E;	c #CCE8F7",
+"F;	c #157EEB",
+"G;	c #3595EF",
+"H;	c #F0F8FA",
+"I;	c #F8FDF7",
+"J;	c #5AA9F0",
+"K;	c #0683F9",
+"L;	c #C1DFF6",
+"M;	c #929292",
+"N;	c #545454",
+"O;	c #E4F2FA",
+"P;	c #E3F2FB",
+"Q;	c #E4F1FB",
+"R;	c #E2F2FA",
+"S;	c #CAE3F5",
+"T;	c #A3D1EF",
+"U;	c #A7D2EC",
+"V;	c #45A2F0",
+"W;	c #007FFD",
+"X;	c #79BDEE",
+"Y;	c #FFFFFC",
+"Z;	c #A0D1EF",
+"`;	c #3B9AEA",
+" >	c #A2D1F2",
+".>	c #A5D1EE",
+"+>	c #C8E2F4",
+"@>	c #E3F2FC",
+"#>	c #E4F2FB",
+"$>	c #F3FDFE",
+"%>	c #7C7C7C",
+"&>	c #515151",
+"*>	c #F2FAFA",
+"=>	c #59A0E2",
+"->	c #0680F2",
+";>	c #077FF6",
+">>	c #0C81F3",
+",>	c #BDDFF3",
+"'>	c #F8FEFD",
+")>	c #E0F1F8",
+"!>	c #1C8AF0",
+"~>	c #067DFA",
+"{>	c #097EF4",
+"]>	c #5C9FE0",
+"^>	c #F0F8F7",
+"/>	c #494949",
+"(>	c #DFDFDF",
+"_>	c #E2F2F9",
+":>	c #5BACEF",
+"<>	c #3291ED",
+"[>	c #EDF6FB",
+"}>	c #F7F9FD",
+"|>	c #50A4ED",
+"1>	c #0082F9",
+"2>	c #3897EC",
+"3>	c #DEF3F9",
+"4>	c #F5F6F5",
+"5>	c #DCDCDC",
+"6>	c #F7FBFD",
+"7>	c #64AFE9",
+"8>	c #0280FF",
+"9>	c #097EF2",
+"0>	c #107CE9",
+"a>	c #0F7DEC",
+"b>	c #86B9E3",
+"c>	c #B1D6E9",
+"d>	c #117CE7",
+"e>	c #0E7DEB",
+"f>	c #0B7CF5",
+"g>	c #047DFA",
+"h>	c #097CFA",
+"i>	c #0381FA",
+"j>	c #0382FB",
+"k>	c #087CFC",
+"l>	c #4294EE",
+"m>	c #E4F4F9",
+"n>	c #FFFEF7",
+"o>	c #F4F3F4",
+"p>	c #484847",
+"q>	c #D9D8D9",
+"r>	c #F6FEFC",
+"s>	c #6FAFEB",
+"t>	c #3B99ED",
+"u>	c #BBDDF5",
+"v>	c #C1DDF3",
+"w>	c #C1DEF5",
+"x>	c #C0DEF6",
+"y>	c #C1DEF2",
+"z>	c #C1DEF4",
+"A>	c #DCF0F9",
+"B>	c #EFFEFD",
+"C>	c #F1FEFD",
+"D>	c #F4FEFD",
+"E>	c #F5FDFF",
+"F>	c #EFFEFF",
+"G>	c #F3FFFD",
+"H>	c #E5FAFA",
+"I>	c #C4DFF4",
+"J>	c #C0DEF5",
+"K>	c #C2DFF3",
+"L>	c #C2DEF1",
+"M>	c #BFDEF5",
+"N>	c #BFDEF1",
+"O>	c #66B3F0",
+"P>	c #67B2EC",
+"Q>	c #F7FDF7",
+"R>	c #2F2C2F",
+"S>	c #020103",
+"T>	c #F7FEFD",
+"U>	c #70B3EC",
+"V>	c #0D80F3",
+"W>	c #78B8ED",
+"X>	c #A9D3F2",
+"Y>	c #1082F2",
+"Z>	c #6EB3E8",
+"`>	c #F5FDFC",
+" ,	c #A2D3F3",
+".,	c #0B84F2",
+"+,	c #0581F9",
+"@,	c #73B5ED",
+"#,	c #FCFFF9",
+"$,	c #78B9F0",
+"%,	c #087EF7",
+"&,	c #74B7EC",
+"*,	c #F6FCFA",
+"=,	c #FFFDFA",
+"-,	c #D4D3D3",
+";,	c #1B1B1B",
+">,	c #A5A5A5",
+",,	c #F9FEFC",
+"',	c #ACD4F1",
+"),	c #1081F3",
+"!,	c #53A4EA",
+"~,	c #E9F6F9",
+"{,	c #F9FBFE",
+"],	c #F8FFFC",
+"^,	c #F9FCF9",
+"/,	c #EEF7F9",
+"(,	c #CCE4F2",
+"_,	c #C7E4F3",
+":,	c #ECF9FB",
+"<,	c #F7FFFE",
+"[,	c #FDFCF8",
+"},	c #FFFBFB",
+"|,	c #F2FDFC",
+"1,	c #6FB8ED",
+"2,	c #087DF7",
+"3,	c #1081F0",
+"4,	c #95C9EE",
+"5,	c #F6FBFD",
+"6,	c #B5B5B6",
+"7,	c #1B1918",
+"8,	c #010100",
+"9,	c #010200",
+"0,	c #2A2C2A",
+"a,	c #6B6B6B",
+"b,	c #EBEDEC",
+"c,	c #FBFCFE",
+"d,	c #ABD8F6",
+"e,	c #0381FC",
+"f,	c #3F98E9",
+"g,	c #EBF7FA",
+"h,	c #81B7E6",
+"i,	c #3697EB",
+"j,	c #1583F0",
+"k,	c #1184F6",
+"l,	c #1384F5",
+"m,	c #0D84F7",
+"n,	c #1184F5",
+"o,	c #1284F5",
+"p,	c #3994EC",
+"q,	c #97C7EC",
+"r,	c #F9FEFD",
+"s,	c #F5FFF7",
+"t,	c #70B2EC",
+"u,	c #0D82F3",
+"v,	c #A7D6F5",
+"w,	c #6C6C6A",
+"x,	c #2B2B2D",
+"y,	c #030202",
+"z,	c #030000",
+"A,	c #000201",
+"B,	c #D9D9DA",
+"C,	c #FDFBFD",
+"D,	c #FEFBFD",
+"E,	c #F6FCFC",
+"F,	c #B4E0F6",
+"G,	c #0082F7",
+"H,	c #3697ED",
+"I,	c #E7F3F6",
+"J,	c #F8FBFB",
+"K,	c #E4F3FA",
+"L,	c #A1CBEE",
+"M,	c #61ADEF",
+"N,	c #3495EE",
+"O,	c #2889E1",
+"P,	c #F2FBFD",
+"Q,	c #F4FEFE",
+"R,	c #8EC2EF",
+"S,	c #90C3ED",
+"T,	c #F0F7F8",
+"U,	c #0C7EEC",
+"V,	c #3594EF",
+"W,	c #61ACF3",
+"X,	c #9CCDEF",
+"Y,	c #E1F3FA",
+"Z,	c #F6FDFB",
+"`,	c #67A9E6",
+" '	c #9DCEF0",
+".'	c #E6E9E9",
+"+'	c #9B9D9E",
+"@'	c #5F5F60",
+"#'	c #232221",
+"$'	c #464646",
+"%'	c #F6FEFD",
+"&'	c #EFFAFC",
+"*'	c #C4DFF1",
+"='	c #82C1F2",
+"-'	c #4199EA",
+";'	c #0E82F4",
+">'	c #3B97EA",
+",'	c #D5EBF6",
+"''	c #D3E8F5",
+")'	c #379AF0",
+"!'	c #D1E7F5",
+"~'	c #DDF0F8",
+"{'	c #1883F0",
+"]'	c #1C87F0",
+"^'	c #DEF0F7",
+"/'	c #B8DEF3",
+"('	c #0480F5",
+"_'	c #077FF3",
+":'	c #3899ED",
+"<'	c #87C1F0",
+"['	c #D2E9F7",
+"}'	c #F7FDFD",
+"|'	c #C9E5F6",
+"1'	c #2E8FF1",
+"2'	c #0282FD",
+"3'	c #0C81F2",
+"4'	c #3D9BEE",
+"5'	c #74BAF2",
+"6'	c #C1E0F4",
+"7'	c #EBF7F9",
+"8'	c #D2D2D2",
+"9'	c #878787",
+"0'	c #454545",
+"a'	c #070707",
+"b'	c #2E2E2E",
+"c'	c #B8B8B8",
+"d'	c #D5EBF8",
+"e'	c #8EC6F0",
+"f'	c #52A5F1",
+"g'	c #228AEE",
+"h'	c #027EFD",
+"i'	c #72B4ED",
+"j'	c #F0F8FB",
+"k'	c #FCFBFA",
+"l'	c #E7F4F8",
+"m'	c #93C5EC",
+"n'	c #3997EF",
+"o'	c #0A7FEC",
+"p'	c #2691EE",
+"q'	c #B5D5EF",
+"r'	c #FBFFFC",
+"s'	c #97C9EF",
+"t'	c #1081EE",
+"u'	c #A9D1F0",
+"v'	c #ACD1F1",
+"w'	c #2B8EF1",
+"x'	c #0B7DF3",
+"y'	c #489EF2",
+"z'	c #A1CDF1",
+"A'	c #E8F3F9",
+"B'	c #F9FDFE",
+"C'	c #EDF9F8",
+"D'	c #73B3EC",
+"E'	c #097FF2",
+"F'	c #1786F3",
+"G'	c #449FEF",
+"H'	c #8EC4EE",
+"I'	c #CEE5F6",
+"J'	c #F1FDFE",
+"K'	c #F3F3F3",
+"L'	c #7B7B7B",
+"M'	c #E5F6FC",
+"N'	c #AAD2F1",
+"O'	c #68B3F2",
+"P'	c #288CEE",
+"Q'	c #087FF7",
+"R'	c #1C8AEF",
+"S'	c #AFD7F2",
+"T'	c #D0E9F8",
+"U'	c #6AB2EE",
+"V'	c #1887F3",
+"W'	c #047FFD",
+"X'	c #258BEF",
+"Y'	c #64B1EE",
+"Z'	c #ABD4F1",
+"`'	c #E1F1F8",
+" )	c #FCFCFE",
+".)	c #F8FFFB",
+"+)	c #F5FCFA",
+"@)	c #7EBFF1",
+"#)	c #0D7FF5",
+"$)	c #0F81F0",
+"%)	c #9ECFED",
+"&)	c #DAEFF9",
+"*)	c #A0D0F3",
+"=)	c #65AEEE",
+"-)	c #258CEF",
+";)	c #027FF9",
+">)	c #1B87ED",
+",)	c #77BAF0",
+"')	c #D1E8F6",
+"))	c #FBFEFB",
+"!)	c #F8FEFB",
+"~)	c #A1CDF3",
+"{)	c #1381F4",
+"])	c #027EFF",
+"^)	c #288CEA",
+"/)	c #5BABF3",
+"()	c #A7D2F1",
+"_)	c #DBEFF7",
+":)	c #EBF1F4",
+"<)	c #6CACE0",
+"[)	c #0880F3",
+"})	c #0082FD",
+"|)	c #DAEEF7",
+"1)	c #D2E7F8",
+"2)	c #5BAAF0",
+"3)	c #0C81F6",
+"4)	c #0083FD",
+"5)	c #268FEB",
+"6)	c #6FB5EC",
+"7)	c #CEE8F6",
+"8)	c #F2FAFD",
+"9)	c #F1FCFE",
+"0)	c #F8FCFB",
+"a)	c #51A6F5",
+"b)	c #127FE9",
+"c)	c #057FF7",
+"d)	c #077FF9",
+"e)	c #127DEA",
+"f)	c #4FA5F2",
+"g)	c #CBE5F6",
+"h)	c #FBFBFD",
+"i)	c #F4FCFE",
+"j)	c #C5DEF2",
+"k)	c #F1FDFF",
+"l)	c #F1FAFC",
+"m)	c #BFE2F5",
+"n)	c #70B5EA",
+"o)	c #278CF0",
+"p)	c #5FA7EF",
+"q)	c #CEE7F5",
+"r)	c #F6FDF9",
+"s)	c #CEECF4",
+"t)	c #2C8FF0",
+"u)	c #62A5E2",
+"v)	c #DDE7EC",
+"w)	c #3E3E3E",
+"x)	c #C6E7F7",
+"y)	c #3D9AEE",
+"z)	c #53A6F0",
+"A)	c #E5F4F6",
+"B)	c #DDF1FA",
+"C)	c #65ADEA",
+"D)	c #107FF2",
+"E)	c #62ADEC",
+"F)	c #BBDDF2",
+"G)	c #FEFAFC",
+"H)	c #E5F2F9",
+"I)	c #AAD3F4",
+"J)	c #6FB5ED",
+"K)	c #3893ED",
+"L)	c #0A80EC",
+"M)	c #087DFA",
+"N)	c #6AAEEE",
+"O)	c #F3FFFE",
+"P)	c #D1E7F7",
+"Q)	c #D0E6F4",
+"R)	c #F1FEFE",
+"S)	c #FBFFF9",
+"T)	c #66B1EB",
+"U)	c #067FF9",
+"V)	c #0C7DEB",
+"W)	c #3395F3",
+"X)	c #6CB4EC",
+"Y)	c #A9D9F0",
+"Z)	c #E9F7FB",
+"`)	c #F6FFFF",
+" !	c #B1D7F2",
+".!	c #62ADEE",
+"+!	c #0E81F1",
+"@!	c #0A7EF4",
+"#!	c #6FB5F0",
+"$!	c #DEF0F8",
+"%!	c #4EA2EA",
+"&!	c #077DFC",
+"*!	c #0680F6",
+"=!	c #3B9AF2",
+"-!	c #B3D6F1",
+";!	c #F9FDFD",
+">!	c #D2D2D1",
+",!	c #DFDEDE",
+"'!	c #FBFDFB",
+")!	c #FAFBFC",
+"!!	c #B2DAF2",
+"~!	c #3093EB",
+"{!	c #59A9EE",
+"]!	c #F0FAFD",
+"^!	c #FFFDFB",
+"/!	c #F0FBFC",
+"(!	c #80BAEE",
+"_!	c #1385F0",
+":!	c #208AF0",
+"<!	c #7DBBEC",
+"[!	c #DBEBF5",
+"}!	c #FDFBF8",
+"|!	c #DBF1F7",
+"1!	c #95C8F0",
+"2!	c #48A1F0",
+"3!	c #1180F2",
+"4!	c #5FACF3",
+"5!	c #E4F2F8",
+"6!	c #56A4EE",
+"7!	c #1181EB",
+"8!	c #49A2EF",
+"9!	c #9AC7ED",
+"0!	c #E5F4F9",
+"a!	c #D6ECF9",
+"b!	c #6AB0EE",
+"c!	c #1182F2",
+"d!	c #1185F2",
+"e!	c #98CBF0",
+"f!	c #F1F9FC",
+"g!	c #59A8EB",
+"h!	c #328FE7",
+"i!	c #9BCEF1",
+"j!	c #FBFCF7",
+"k!	c #DEDDDC",
+"l!	c #6C6F71",
+"m!	c #0E0D0C",
+"n!	c #484848",
+"o!	c #ABABAB",
+"p!	c #888888",
+"q!	c #EFEEEF",
+"r!	c #F0FAFC",
+"s!	c #9CCEF1",
+"t!	c #2790EE",
+"u!	c #0681F9",
+"v!	c #68ADEB",
+"w!	c #F1FBFB",
+"x!	c #C5E3F5",
+"y!	c #3996EB",
+"z!	c #1284F2",
+"A!	c #6EB4EB",
+"B!	c #DFF2F9",
+"C!	c #FCFCF9",
+"D!	c #B7DCF2",
+"E!	c #56A4E8",
+"F!	c #1181F5",
+"G!	c #268BED",
+"H!	c #8AC6F1",
+"I!	c #DEF2F6",
+"J!	c #F8FDFD",
+"K!	c #E0F3F8",
+"L!	c #8AC4F0",
+"M!	c #208CF2",
+"N!	c #1785F4",
+"O!	c #55A5EE",
+"P!	c #B5DCF4",
+"Q!	c #F9FCFD",
+"R!	c #DAEEF9",
+"S!	c #72B3ED",
+"T!	c #0F85F4",
+"U!	c #3495ED",
+"V!	c #5CA9EC",
+"W!	c #1B85F3",
+"X!	c #8DC6ED",
+"Y!	c #EFF9FB",
+"Z!	c #878786",
+"`!	c #000001",
+" ~	c #313131",
+".~	c #C7C7C7",
+"+~	c #161616",
+"@~	c #F9F8F3",
+"#~	c #FDFAF9",
+"$~	c #EEF5FC",
+"%~	c #85C3F2",
+"&~	c #7BB9EB",
+"*~	c #F6FDFA",
+"=~	c #F1F9F9",
+"-~	c #80BEEE",
+";~	c #0F83F1",
+">~	c #59A6E9",
+",~	c #DEEEF6",
+"'~	c #FEFCF6",
+")~	c #F1F9F8",
+"!~	c #94CAF0",
+"~~	c #2D93F0",
+"{~	c #097EF6",
+"]~	c #0280F6",
+"^~	c #067FFA",
+"/~	c #1183F5",
+"(~	c #449FED",
+"_~	c #70B6EC",
+":~	c #8DC7F4",
+"<~	c #92C6F3",
+"[~	c #73B5EA",
+"}~	c #439DF0",
+"|~	c #077DFA",
+"1~	c #3C99EF",
+"2~	c #ECF9F7",
+"3~	c #DCEDF9",
+"4~	c #59A6EC",
+"5~	c #037FF9",
+"6~	c #1484F0",
+"7~	c #86C4F3",
+"8~	c #F0F9FC",
+"9~	c #F9FFFE",
+"0~	c #F5FAFC",
+"a~	c #70B0EA",
+"b~	c #6EAFEE",
+"c~	c #E7F8F5",
+"d~	c #363636",
+"e~	c #AFAFAF",
+"f~	c #E1E1E1",
+"g~	c #A4A4A4",
+"h~	c #585858",
+"i~	c #232328",
+"j~	c #A2A3A7",
+"k~	c #FBFDF9",
+"l~	c #FBFFF8",
+"m~	c #DCEDF5",
+"n~	c #3D99F1",
+"o~	c #B5D9F1",
+"p~	c #F7FDFE",
+"q~	c #FCFBF8",
+"r~	c #99CBF2",
+"s~	c #288CF0",
+"t~	c #268BF3",
+"u~	c #9CCAF0",
+"v~	c #F7FDFC",
+"w~	c #B3D8F1",
+"x~	c #268CEF",
+"y~	c #0580F8",
+"z~	c #4B9FEF",
+"A~	c #DAEFF7",
+"B~	c #FDFDF7",
+"C~	c #B7B8B7",
+"D~	c #AAAAAA",
+"E~	c #747474",
+"F~	c #D8D8D8",
+"G~	c #010201",
+"H~	c #050301",
+"I~	c #383839",
+"J~	c #B0B1B3",
+"K~	c #B1D9F1",
+"L~	c #1C89F2",
+"M~	c #037EFB",
+"N~	c #0A7FF5",
+"O~	c #6DB6F1",
+"P~	c #B5DAF2",
+"Q~	c #3497EF",
+"R~	c #3895EC",
+"S~	c #C5E2F3",
+"T~	c #70B8EC",
+"U~	c #258FF0",
+"V~	c #B6DCF4",
+"W~	c #D2D3CE",
+"X~	c #373638",
+"Y~	c #E9E9E9",
+"Z~	c #9C9C9C",
+"`~	c #010202",
+" {	c #4A4B4B",
+".{	c #8FC5F0",
+"+{	c #238BEF",
+"@{	c #B8DDF3",
+"#{	c #67AEEA",
+"${	c #65B0EE",
+"%{	c #ECF5FB",
+"&{	c #ACD6F3",
+"*{	c #1B88F1",
+"={	c #1083F5",
+"-{	c #9ECBF0",
+";{	c #F8FCFA",
+">{	c #959595",
+",{	c #383838",
+"'{	c #F4FEFF",
+"){	c #7CB9EE",
+"!{	c #459EEE",
+"~{	c #F7FDF9",
+"{{	c #ABD4EF",
+"]{	c #258DF5",
+"^{	c #0181F7",
+"/{	c #0B7DF1",
+"({	c #1986EE",
+"_{	c #1588F2",
+":{	c #0B7FF0",
+"<{	c #0280F8",
+"[{	c #2190F4",
+"}{	c #B3D9F2",
+"|{	c #FBFEF9",
+"1{	c #DCEEF8",
+"2{	c #389AF3",
+"3{	c #0282FB",
+"4{	c #7BBAF3",
+"5{	c #FAFDF9",
+"6{	c #9F9F9F",
+"7{	c #E4E4E4",
+"8{	c #ACACAC",
+"9{	c #212121",
+"0{	c #DADADA",
+"a{	c #79B6EC",
+"b{	c #69B2F0",
+"c{	c #EBF9FA",
+"d{	c #6AB0F1",
+"e{	c #097DF6",
+"f{	c #0082FA",
+"g{	c #0D83F3",
+"h{	c #5BA8EE",
+"i{	c #AED5F2",
+"j{	c #D8F1F8",
+"k{	c #EDF6F9",
+"l{	c #DCF1F8",
+"m{	c #AAD5F5",
+"n{	c #479DEC",
+"o{	c #0580F7",
+"p{	c #0D80F6",
+"q{	c #79BAEF",
+"r{	c #EDF8FC",
+"s{	c #FBFBF9",
+"t{	c #EBF3F8",
+"u{	c #6BADEC",
+"v{	c #73B8EC",
+"w{	c #FAFCF9",
+"x{	c #6F6F6F",
+"y{	c #666666",
+"z{	c #808080",
+"A{	c #CBCBCB",
+"B{	c #9A9A9A",
+"C{	c #F8FFFF",
+"D{	c #6FB4F1",
+"E{	c #0681F6",
+"F{	c #0A81F5",
+"G{	c #88C1EE",
+"H{	c #D4EBF7",
+"I{	c #469BED",
+"J{	c #248CEF",
+"K{	c #C0E1F7",
+"L{	c #C1DFF4",
+"M{	c #419DEE",
+"N{	c #F2FCFB",
+"O{	c #6FB2EF",
+"P{	c #087EF9",
+"Q{	c #4D4D4D",
+"R{	c #999999",
+"S{	c #6CB1EA",
+"T{	c #0E80F5",
+"U{	c #ABD3F1",
+"V{	c #FAFBFB",
+"W{	c #BFDFF4",
+"X{	c #218AEE",
+"Y{	c #067EFA",
+"Z{	c #2C90EE",
+"`{	c #DAF1F9",
+" ]	c #FDFDFF",
+".]	c #D2ECF7",
+"+]	c #278DF0",
+"@]	c #238BEC",
+"#]	c #C9EAF7",
+"$]	c #80BCED",
+"%]	c #0882F6",
+"&]	c #6CB0F1",
+"*]	c #868686",
+"=]	c #77B9EF",
+"-]	c #A9D7EF",
+";]	c #FCFBFD",
+">]	c #A6D0F2",
+",]	c #1686F1",
+"']	c #D8ECF7",
+")]	c #92C5EA",
+"!]	c #6CB3F0",
+"~]	c #70B3ED",
+"{]	c #9ECEED",
+"]]	c #EDF9FC",
+"^]	c #0F85F5",
+"/]	c #1A86F1",
+"(]	c #A4D2F5",
+"_]	c #84BEEC",
+":]	c #0480F4",
+"<]	c #353535",
+"[]	c #202020",
+"}]	c #5C5C5C",
+"|]	c #B0B0B0",
+"1]	c #757575",
+"2]	c #95C9F0",
+"3]	c #0881F8",
+"4]	c #0381F8",
+"5]	c #96C7F0",
+"6]	c #A1CDF0",
+"7]	c #0C82F6",
+"8]	c #057DFC",
+"9]	c #79B9F1",
+"0]	c #BFE0F4",
+"a]	c #2489EB",
+"b]	c #047EF9",
+"c]	c #328FED",
+"d]	c #BDDFF1",
+"e]	c #7BBBED",
+"f]	c #0B82F6",
+"g]	c #A0CFF2",
+"h]	c #F5FCFE",
+"i]	c #0A81F7",
+"j]	c #9CCEF2",
+"k]	c #FCFDF7",
+"l]	c #989898",
+"m]	c #939393",
+"n]	c #131313",
+"o]	c #8C8C8C",
+"p]	c #BBE1F7",
+"q]	c #1383EF",
+"r]	c #85BEF3",
+"s]	c #F9FDFA",
+"t]	c #9CCCEE",
+"u]	c #0A82F3",
+"v]	c #0C7FF3",
+"w]	c #D6EDF5",
+"x]	c #1D89EE",
+"y]	c #1F88E8",
+"z]	c #E4F6FB",
+"A]	c #D6EDF6",
+"B]	c #0982F7",
+"C]	c #0982F8",
+"D]	c #9ECDF3",
+"E]	c #F7FDFB",
+"F]	c #87BDEF",
+"G]	c #1687F4",
+"H]	c #BEE0F1",
+"I]	c #252525",
+"J]	c #B4B4B4",
+"K]	c #DAEFFA",
+"L]	c #2189ED",
+"M]	c #61AAEF",
+"N]	c #F5FEFA",
+"O]	c #B4DAF3",
+"P]	c #0C7EF4",
+"Q]	c #74B5EB",
+"R]	c #83BEEE",
+"S]	c #1C89EF",
+"T]	c #1585F3",
+"U]	c #BFE4F6",
+"V]	c #F7FBFB",
+"W]	c #51A6F0",
+"X]	c #2C8FF3",
+"Y]	c #E1F0F7",
+"Z]	c #9E9E9E",
+"`]	c #0C0C0C",
+" ^	c #A3A3A3",
+".^	c #F7F9FB",
+"+^	c #439BF1",
+"@^	c #3999EB",
+"#^	c #F5FAFD",
+"$^	c #C4E1F7",
+"%^	c #4B9DED",
+"&^	c #2D8DEA",
+"*^	c #439DF1",
+"=^	c #F9FFFF",
+"-^	c #44A0EE",
+";^	c #1785EF",
+">^	c #C4E3F3",
+",^	c #EEF8FA",
+"'^	c #3394EE",
+")^	c #4DA3EE",
+"!^	c #F2FBFB",
+"~^	c #ADADAD",
+"{^	c #84BFEE",
+"]^	c #1E84F3",
+"^^	c #D7EDF5",
+"/^	c #DAF1FA",
+"(^	c #248DEC",
+"_^	c #047EFF",
+":^	c #489FEE",
+"<^	c #F5FDFD",
+"[^	c #2C8DE8",
+"}^	c #4098E8",
+"|^	c #499FEB",
+"1^	c #2E92EE",
+"2^	c #CDE8F7",
+"3^	c #1788F3",
+"4^	c #077EFA",
+"5^	c #91C6EF",
+"6^	c #3A3A3A",
+"7^	c #D2E7F6",
+"8^	c #0C84F3",
+"9^	c #0981F8",
+"0^	c #B0D8F5",
+"a^	c #F1F9FB",
+"b^	c #4199EE",
+"c^	c #439AEF",
+"d^	c #F8FEF9",
+"e^	c #5FADF2",
+"f^	c #0182FA",
+"g^	c #78B9F1",
+"h^	c #258EF1",
+"i^	c #52A4EE",
+"j^	c #F1FAF9",
+"k^	c #A1CDEF",
+"l^	c #CDE9F6",
+"m^	c #FDFCFE",
+"n^	c #656565",
+"o^	c #7A7A7A",
+"p^	c #3E97F1",
+"q^	c #62AFF0",
+"r^	c #7FBAED",
+"s^	c #0D80F4",
+"t^	c #DBF1F6",
+"u^	c #D2E7F4",
+"v^	c #1285F4",
+"w^	c #1782F4",
+"x^	c #DAF1F7",
+"y^	c #E4F1F7",
+"z^	c #0981F4",
+"A^	c #86C1F0",
+"B^	c #F3FCFE",
+"C^	c #55A3EE",
+"D^	c #037FF8",
+"E^	c #4A9EEC",
+"F^	c #4E4E4E",
+"G^	c #C8C8C8",
+"H^	c #B7B7B7",
+"I^	c #C6C6C6",
+"J^	c #FFFDF9",
+"K^	c #92C7EB",
+"L^	c #0580FA",
+"M^	c #278CF1",
+"N^	c #E8F7F7",
+"O^	c #BADFF4",
+"P^	c #0A80F6",
+"Q^	c #0182FD",
+"R^	c #8CC3F2",
+"S^	c #A7D2EF",
+"T^	c #1080EF",
+"U^	c #1A89F4",
+"V^	c #A6D2F3",
+"W^	c #8FC2ED",
+"X^	c #0D83F8",
+"Y^	c #CCE5F4",
+"Z^	c #E0F2F7",
+"`^	c #1E8BF3",
+" /	c #067FFB",
+"./	c #9FCFEE",
+"+/	c #E5F4F7",
+"@/	c #1788F0",
+"#/	c #0581F3",
+"$/	c #B0D8F4",
+"%/	c #E3F7FB",
+"&/	c #298DEF",
+"*/	c #2087F6",
+"=/	c #E4F7FB",
+"-/	c #D7F0F8",
+";/	c #70B2EB",
+">/	c #48A4F5",
+",/	c #4AA3F3",
+"'/	c #7CBBEC",
+")/	c #DAEEF8",
+"!/	c #D7EFF8",
+"~/	c #3495EC",
+"{/	c #96C8EE",
+"]/	c #0A7FF4",
+"^/	c #248FF0",
+"//	c #E5F5FA",
+"(/	c #272727",
+"_/	c #282828",
+":/	c #7FBBED",
+"</	c #48A3F0",
+"[/	c #76B4EC",
+"}/	c #3F9AEC",
+"|/	c #ECF8F8",
+"1/	c #FFFEF8",
+"2/	c #E1F2F9",
+"3/	c #3E97E9",
+"4/	c #7BBBF0",
+"5/	c #3E99EB",
+"6/	c #7CBBEE",
+"7/	c #979797",
+"8/	c #1586F3",
+"9/	c #0D7FF3",
+"0/	c #C9E7F7",
+"a/	c #CBE8F6",
+"b/	c #1583F2",
+"c/	c #0180F9",
+"d/	c #3597F0",
+"e/	c #D9EDF6",
+"f/	c #FFFEF9",
+"g/	c #D7EDF6",
+"h/	c #3C96E7",
+"i/	c #1683F0",
+"j/	c #D9EFF9",
+"k/	c #B5DAF3",
+"l/	c #1884F4",
+"m/	c #E4F4F7",
+"n/	c #5B5B5B",
+"o/	c #5AADF0",
+"p/	c #50A6EF",
+"q/	c #067FF6",
+"r/	c #1788F2",
+"s/	c #7DBBEE",
+"t/	c #CBE7F3",
+"u/	c #C8E6F6",
+"v/	c #63B1EF",
+"w/	c #1183F2",
+"x/	c #55A5ED",
+"y/	c #439DE9",
+"z/	c #047DFC",
+"A/	c #78B9EE",
+"B/	c #B9B9B9",
+"C/	c #676767",
+"D/	c #E3F2FA",
+"E/	c #1485F1",
+"F/	c #D7E9F6",
+"G/	c #C6E2F6",
+"H/	c #097FF7",
+"I/	c #0980F4",
+"J/	c #1484F2",
+"K/	c #2C91ED",
+"L/	c #218AF2",
+"M/	c #1583F7",
+"N/	c #0A80F1",
+"O/	c #C2E3F5",
+"P/	c #C8E5F4",
+"Q/	c #1887F0",
+"R/	c #EAF8FC",
+"S/	c #7D7D7D",
+"T/	c #0182FC",
+"U/	c #56A6EA",
+"V/	c #4CA1ED",
+"W/	c #4BA2ED",
+"X/	c #F8FCFD",
+"Y/	c #499EED",
+"Z/	c #90C5ED",
+"`/	c #F5FBFB",
+" (	c #288DF4",
+".(	c #077DF6",
+"+(	c #BBE1F5",
+"@(	c #C4E0F2",
+"#(	c #0080FC",
+"$(	c #D1EAF7",
+"%(	c #B5D7F2",
+"&(	c #3894EF",
+"*(	c #F3FCFD",
+"=(	c #616161",
+"-(	c #636363",
+";(	c #ABD8F3",
+">(	c #3193F2",
+",(	c #59AAEF",
+"'(	c #66AEEB",
+")(	c #2C8FEC",
+"!(	c #BADEF2",
+"~(	c #232323",
+"{(	c #BDBDBD",
+"](	c #5AA7E7",
+"^(	c #93C5F2",
+"/(	c #0D81EE",
+"((	c #2C8DEB",
+"_(	c #66B3F2",
+":(	c #72B2EA",
+"<(	c #6FB3EB",
+"[(	c #56ABEF",
+"}(	c #1F86F0",
+"|(	c #E7F3F9",
+"1(	c #8BC2F0",
+"2(	c #73B6F1",
+"3(	c #FAFFFC",
+"4(	c #767676",
+"5(	c #898989",
+"6(	c #EBF4FA",
+"7(	c #1886F2",
+"8(	c #0B7DF4",
+"9(	c #DAEEF6",
+"0(	c #8BC2EF",
+"a(	c #1184EF",
+"b(	c #9AD0F5",
+"c(	c #8BC9EF",
+"d(	c #0F81F5",
+"e(	c #98C8EF",
+"f(	c #0A7DF3",
+"g(	c #2489EE",
+"h(	c #C3C3C3",
+"i(	c #ABD6F0",
+"j(	c #0082FF",
+"k(	c #4A9FED",
+"l(	c #F8FEFF",
+"m(	c #2F94ED",
+"n(	c #1C87F2",
+"o(	c #D7EDF7",
+"p(	c #FDFCF7",
+"q(	c #AFDAF3",
+"r(	c #1582EE",
+"s(	c #46A1F0",
+"t(	c #479FF1",
+"u(	c #B9DCF5",
+"v(	c #66B3EF",
+"w(	c #95C7EF",
+"x(	c #D3EAF5",
+"y(	c #0780F8",
+"z(	c #ACD5F4",
+"A(	c #F6FDFC",
+"B(	c #E0F1F6",
+"C(	c #FBFCF4",
+"D(	c #9CCEF4",
+"E(	c #097EF0",
+"F(	c #DFF0F9",
+"G(	c #86BFEF",
+"H(	c #F4FDFD",
+"I(	c #288DEE",
+"J(	c #D1E8F5",
+"K(	c #89C1F1",
+"L(	c #3293EF",
+"M(	c #D8F0F8",
+"N(	c #50A0E9",
+"O(	c #0B7EF2",
+"P(	c #0B7EED",
+"Q(	c #4CA1EC",
+"R(	c #D6F0F9",
+"S(	c #3192F0",
+"T(	c #93C8F1",
+"U(	c #D2E8F5",
+"V(	c #3593F0",
+"W(	c #CDCDCD",
+"X(	c #D4EBF6",
+"Y(	c #2F91EE",
+"Z(	c #F4FCFD",
+"`(	c #4AA0EE",
+" _	c #76BBF2",
+"._	c #F7FCFA",
+"+_	c #479CE7",
+"@_	c #4A9AE4",
+"#_	c #78BAF2",
+"$_	c #56A9EE",
+"%_	c #F3FBFD",
+"&_	c #248CEE",
+"*_	c #0D81F1",
+"=_	c #E0F2F9",
+"-_	c #A8D2F3",
+";_	c #5FA9EE",
+">_	c #0F81F1",
+",_	c #91C6F4",
+"'_	c #0882F7",
+")_	c #DEEFF9",
+"!_	c #8EC5F6",
+"~_	c #1889F2",
+"{_	c #5BAAEF",
+"]_	c #ACD3F3",
+"^_	c #6BB1EB",
+"/_	c #94C8F3",
+"(_	c #BBDDF0",
+"__	c #91C7F4",
+":_	c #D2E8F6",
+"<_	c #0E81F4",
+"[_	c #DDEFF7",
+"}_	c #93C5F4",
+"|_	c #CAE5F5",
+"1_	c #89C2EF",
+"2_	c #7CBAEE",
+"3_	c #3C98F1",
+"4_	c #C8E3F4",
+"5_	c #88C1F1",
+"6_	c #7ABCF1",
+"7_	c #58A5ED",
+"8_	c #F9FFFC",
+"9_	c #71B1F1",
+"0_	c #90C5F3",
+"a_	c #BDDBF0",
+"b_	c #46A2F3",
+"c_	c #595959",
+"d_	c #F2F9FB",
+"e_	c #238AF1",
+"f_	c #0C80F8",
+"g_	c #E4F1F9",
+"h_	c #64AAEE",
+"i_	c #F2F9FA",
+"j_	c #DEEFF8",
+"k_	c #1283F3",
+"l_	c #1682EF",
+"m_	c #5DAAF0",
+"n_	c #F2F9FC",
+"o_	c #3490EE",
+"p_	c #6FB3EE",
+"q_	c #E0F2FB",
+"r_	c #2891F4",
+"s_	c #F5FCFC",
+"t_	c #696969",
+"u_	c #0C7CF0",
+"v_	c #2C90EF",
+"w_	c #F3FEFD",
+"x_	c #419CED",
+"y_	c #9ACCF2",
+"z_	c #E2F5FB",
+"A_	c #E4F5F9",
+"B_	c #8FC5F1",
+"C_	c #49A1EC",
+"D_	c #F2FCFE",
+"E_	c #2490F0",
+"F_	c #0B7DEE",
+"G_	c #C3E5F4",
+"H_	c #3C96EE",
+"I_	c #1084F7",
+"J_	c #1485EE",
+"K_	c #B3D8F4",
+"L_	c #B0DCF5",
+"M_	c #1185F1",
+"N_	c #208BED",
+"O_	c #2F90E7",
+"P_	c #ACD6F4",
+"Q_	c #61B1F6",
+"R_	c #E6F7F6",
+"S_	c #0E81F3",
+"T_	c #8CC2EC",
+"U_	c #EBF8FC",
+"V_	c #E3F5FC",
+"W_	c #83BAEC",
+"X_	c #0F83F2",
+"Y_	c #1184F4",
+"Z_	c #F7FCFE",
+"`_	c #61B0F7",
+" :	c #B1D5F1",
+".:	c #62B1F4",
+"+:	c #C9E2F2",
+"@:	c #1E87F0",
+"#:	c #4CA3F1",
+"$:	c #6BB4EF",
+"%:	c #4EA3EF",
+"&:	c #1282F0",
+"*:	c #64AFF5",
+"=:	c #AFD5F4",
+"-:	c #7FB9E9",
+";:	c #88C2EE",
+">:	c #C6E3F4",
+",:	c #067DF9",
+"':	c #C7E3F3",
+"):	c #A0D1F4",
+"!:	c #73B6EA",
+"~:	c #A0CEEE",
+"{:	c #C6E3F2",
+"]:	c #087EF4",
+"^:	c #C4E3F4",
+"/:	c #65AFF4",
+"(:	c #74B6EA",
+"_:	c #75B4ED",
+"::	c #A0CEEF",
+"<:	c #C7E3F4",
+"[:	c #047EF5",
+"}:	c #0082FB",
+"|:	c #067EF5",
+"1:	c #C6E3F3",
+"2:	c #9ECDED",
+"3:	c #71B5EA",
+"4:	c #047FF5",
+"5:	c #067DFC",
+"6:	c #0A7FF7",
+"7:	c #A1CEED",
+"8:	c #2188ED",
+"9:	c #9DD4F3",
+"0:	c #DEF0F5",
+"a:	c #D3E9F4",
+"b:	c #85C1EF",
+"c:	c #0C80F5",
+"d:	c #88C3F1",
+"e:	c #74B4EC",
+"f:	c #2589E9",
+"g:	c #CEE6F4",
+"h:	c #9ED0F1",
+"i:	c #0B81F7",
+"j:	c #62AFF5",
+"k:	c #8BC3EE",
+"l:	c #6FB2F0",
+"m:	c #C9E3F3",
+"n:	c #047FF6",
+"o:	c #CDE8F8",
+"p:	c #A5D3F2",
+"q:	c #0D82F4",
+"r:	c #087CF8",
+"s:	c #65B0F4",
+"t:	c #ADD5F5",
+"u:	c #AED5F5",
+"v:	c #66B0F4",
+"w:	c #CBE3F1",
+"x:	c #0083FA",
+"y:	c #D2E9F8",
+"z:	c #FCFCF3",
+"A:	c #A9D6F2",
+"B:	c #0B82F5",
+"C:	c #1082F3",
+"D:	c #E7F6F9",
+"E:	c #62B0F4",
+"F:	c #ACD5F5",
+"G:	c #ADD5F3",
+"H:	c #5EAEF6",
+"I:	c #2A8DEB",
+"J:	c #D8EBF6",
+"K:	c #AFD8F1",
+"L:	c #1182F5",
+"M:	c #1384EF",
+"N:	c #459FEA",
+"O:	c #BFDCF2",
+"P:	c #D7EFF6",
+"Q:	c #0780F7",
+"R:	c #308EEA",
+"S:	c #1887EE",
+"T:	c #2F8EEA",
+"U:	c #D7ECF7",
+"V:	c #B1DAF1",
+"W:	c #0F84F5",
+"X:	c #2E96F3",
+"Y:	c #2E90E8",
+"Z:	c #0A7DEF",
+"`:	c #E0F4F9",
+" <	c #0C7EF1",
+".<	c #248DF1",
+"+<	c #47A2ED",
+"@<	c #0282FC",
+"#<	c #2F8FEF",
+"$<	c #FEFFF7",
+"%<	c #B6DCF3",
+"&<	c #1285F2",
+"*<	c #50A0ED",
+"=<	c #E9F4F8",
+"-<	c #1983EE",
+";<	c #E7F8FC",
+"><	c #2E90F5",
+",<	c #DBF1FB",
+"'<	c #6EB7F0",
+")<	c #3090F1",
+"!<	c #DCEFF9",
+"~<	c #D6E9F2",
+"{<	c #EEF7FB",
+"]<	c #B9DFF5",
+"^<	c #1185F3",
+"/<	c #077CFB",
+"(<	c #81BDF5",
+"_<	c #D4EBF9",
+":<	c #3294EF",
+"<<	c #58A8F0",
+"[<	c #ABD3EC",
+"}<	c #9FCEED",
+"|<	c #3491E8",
+"1<	c #E0F0F8",
+"2<	c #FBFEF8",
+"3<	c #D6E6F2",
+"4<	c #2189F0",
+"5<	c #3D99E9",
+"6<	c #E2F5FA",
+"7<	c #FEFBF6",
+"8<	c #BDE0F3",
+"9<	c #AFD4F1",
+"0<	c #A6D0F0",
+"a<	c #64B2F0",
+"b<	c #AEAEAE",
+"c<	c #7EBBEE",
+"d<	c #87C2F3",
+"e<	c #CFE7F1",
+"f<	c #3894EB",
+"g<	c #E2F1F9",
+"h<	c #FFFFF8",
+"i<	c #1C8AEE",
+"j<	c #3C97E8",
+"k<	c #FEFAFE",
+"l<	c #C0E4F5",
+"m<	c #1687F3",
+"n<	c #DDEFF8",
+"o<	c #79B9F0",
+"p<	c #8DC3F0",
+"q<	c #4CA0EC",
+"r<	c #FBFCFF",
+"s<	c #F2FDF8",
+"t<	c #1F88F3",
+"u<	c #3C95EF",
+"v<	c #E4F2F7",
+"w<	c #C6E3F5",
+"x<	c #2088EB",
+"y<	c #3798EE",
+"z<	c #E0F2F6",
+"A<	c #FEFBFC",
+"B<	c #C4E3F5",
+"C<	c #1A88F0",
+"D<	c #2B91F0",
+"E<	c #3F99EB",
+"F<	c #0481F7",
+"G<	c #E0F3F9",
+"H<	c #127FEA",
+"I<	c #1686F3",
+"J<	c #5DA8EF",
+"K<	c #3F98EE",
+"L<	c #F9FDF6",
+"M<	c #FBFDF5",
+"N<	c #1C88F3",
+"O<	c #077CFD",
+"P<	c #3595EE",
+"Q<	c #C5E6F7",
+"R<	c #1C89F0",
+"S<	c #087CFB",
+"T<	c #6BB0F0",
+"U<	c #E6F7FC",
+"V<	c #0D82F1",
+"W<	c #1486F2",
+"X<	c #EBF5F9",
+"Y<	c #737373",
+"Z<	c #429DED",
+"`<	c #B9E0F5",
+" [	c #FEFBFB",
+".[	c #A5D0EF",
+"+[	c #4499E7",
+"@[	c #E5F4FA",
+"#[	c #C0E0F5",
+"$[	c #1A87F2",
+"%[	c #C8E5F6",
+"&[	c #1F89F0",
+"*[	c #B3D7F0",
+"=[	c #FCFCF8",
+"-[	c #AFD6F0",
+";[	c #459DF0",
+">[	c #1E1E1E",
+",[	c #80BDEF",
+"'[	c #76B7EF",
+")[	c #EFFBFA",
+"![	c #1783F4",
+"~[	c #0382FA",
+"{[	c #439AEB",
+"][	c #E9F5FA",
+"^[	c #1A86EE",
+"/[	c #3092E8",
+"([	c #FEF9FD",
+"_[	c #CBEAF7",
+":[	c #1F8BF1",
+"<[	c #69AFEE",
+"[[	c #8DC5F2",
+"}[	c #CDE6F5",
+"|[	c #2B8FEB",
+"1[	c #F4FAFD",
+"2[	c #499BEF",
+"3[	c #EEF6F8",
+"4[	c #F7FFFD",
+"5[	c #BCDCF3",
+"6[	c #1584EE",
+"7[	c #0281F6",
+"8[	c #2A91F0",
+"9[	c #D8EEF5",
+"0[	c #FEFAFD",
+"a[	c #D1EAF8",
+"b[	c #228DF0",
+"c[	c #5FAAF1",
+"d[	c #1D8AEF",
+"e[	c #CDE6F4",
+"f[	c #3698EE",
+"g[	c #CBE4F4",
+"h[	c #AED6ED",
+"i[	c #4D9EEC",
+"j[	c #EDF8FB",
+"k[	c #F7FEF9",
+"l[	c #B8D9F5",
+"m[	c #1384F6",
+"n[	c #1184F8",
+"o[	c #087CFD",
+"p[	c #278FEF",
+"q[	c #FDFBF7",
+"r[	c #D2EDF8",
+"s[	c #268DEE",
+"t[	c #B8DBF2",
+"u[	c #3996EE",
+"v[	c #84BEF0",
+"w[	c #6BB0EC",
+"x[	c #ECFCFC",
+"y[	c #268DED",
+"z[	c #51A0E5",
+"A[	c #B1D9F4",
+"B[	c #7BBBF1",
+"C[	c #D2EBF6",
+"D[	c #298EEA",
+"E[	c #D0ECF6",
+"F[	c #D6ECF8",
+"G[	c #278FEE",
+"H[	c #3390E8",
+"I[	c #F4FBF9",
+"J[	c #61ADEC",
+"K[	c #87BEEE",
+"L[	c #D8EBF7",
+"M[	c #0C81F5",
+"N[	c #1C85F1",
+"O[	c #EAF6FA",
+"P[	c #F8FFFE",
+"Q[	c #85C0EF",
+"R[	c #52A2EC",
+"S[	c #AED6F0",
+"T[	c #1482ED",
+"U[	c #80BFEF",
+"V[	c #D5EDF8",
+"W[	c #278EF0",
+"X[	c #258CEA",
+"Y[	c #FDF9FC",
+"Z[	c #D7EFF9",
+"`[	c #2990EF",
+" }	c #89C3F0",
+".}	c #E5F5FB",
+"+}	c #0D82F2",
+"@}	c #479FEE",
+"#}	c #A0CDF2",
+"$}	c #E9F5F8",
+"%}	c #1084F1",
+"&}	c #56A3EF",
+"*}	c #F2F8F8",
+"=}	c #B0D4F1",
+"-}	c #0E83F1",
+";}	c #087FF1",
+">}	c #81C1F1",
+",}	c #FAFBF9",
+"'}	c #298EF1",
+")}	c #218CF1",
+"!}	c #CEE9F4",
+"~}	c #2A91EF",
+"{}	c #1D88EF",
+"]}	c #EAF7F9",
+"^}	c #83BCED",
+"/}	c #56A7EF",
+"(}	c #AED8F3",
+"_}	c #0183F8",
+":}	c #258FEE",
+"<}	c #F2FAFE",
+"[}	c #6DB5EF",
+"}}	c #0580F9",
+"|}	c #5CA7EB",
+"1}	c #F4FBFB",
+"2}	c #F6FFFB",
+"3}	c #FBFCF5",
+"4}	c #A9D0F3",
+"5}	c #0C81F8",
+"6}	c #DBF0F9",
+"7}	c #2B92F0",
+"8}	c #087BFE",
+"9}	c #1C8AF1",
+"0}	c #CAE6F6",
+"a}	c #FCFBF6",
+"b}	c #DEF2F9",
+"c}	c #3193ED",
+"d}	c #077CFC",
+"e}	c #89C4F2",
+"f}	c #FBFCF9",
+"g}	c #B5D7F1",
+"h}	c #F4FEFA",
+"i}	c #2A90EF",
+"j}	c #99C9EF",
+"k}	c #DCEEF7",
+"l}	c #62A9E6",
+"m}	c #0C82F4",
+"n}	c #8FC5EE",
+"o}	c #3293ED",
+"p}	c #208AEC",
+"q}	c #3396ED",
+"r}	c #248BF1",
+"s}	c #E9F8F9",
+"t}	c #FCFBF9",
+"u}	c #9BCAEC",
+"v}	c #3E9BEE",
+"w}	c #98CBEF",
+"x}	c #268EEF",
+"y}	c #F1F9FA",
+"z}	c #65ACED",
+"A}	c #0982F5",
+"B}	c #93C8EF",
+"C}	c #DFF2FA",
+"D}	c #3295F0",
+"E}	c #1D88EC",
+"F}	c #C2E2F6",
+"G}	c #E1F4FA",
+"H}	c #3797ED",
+"I}	c #077DF9",
+"J}	c #8DC8F3",
+"K}	c #EFF9FA",
+"L}	c #298DEA",
+"M}	c #B6DAF4",
+"N}	c #F5FBFA",
+"O}	c #288FF1",
+"P}	c #067FFD",
+"Q}	c #91C8F3",
+"R}	c #EEF7FC",
+"S}	c #2A8DEC",
+"T}	c #0382F9",
+"U}	c #68ADF0",
+"V}	c #F5FAF9",
+"W}	c #F7FEFC",
+"X}	c #9DC9F1",
+"Y}	c #0B82F3",
+"Z}	c #0C80EF",
+"`}	c #94CBF2",
+" |	c #E0F2FA",
+".|	c #3695F0",
+"+|	c #1A88F2",
+"@|	c #C0E2F3",
+"#|	c #3899EE",
+"$|	c #3696ED",
+"%|	c #F2F7FA",
+"&|	c #91C8F1",
+"*|	c #439EF1",
+"=|	c #9FCDF0",
+"-|	c #218DF4",
+";|	c #ECF6FA",
+">|	c #B1D7F4",
+",|	c #0580F4",
+"'|	c #6BB0EB",
+")|	c #F6FFFC",
+"!|	c #FAFDF8",
+"~|	c #99C7F1",
+"{|	c #097FF8",
+"]|	c #9DCDEF",
+"^|	c #087BFD",
+"/|	c #FBFBF8",
+"(|	c #FFFCF7",
+"_|	c #3C99ED",
+":|	c #077DFD",
+"<|	c #0D81F4",
+"[|	c #B8DDF4",
+"}|	c #E3F1F9",
+"||	c #1584F3",
+"1|	c #C0DCF2",
+"2|	c #44A0F2",
+"3|	c #70B4F1",
+"4|	c #60AAEF",
+"5|	c #73B2E6",
+"6|	c #A3D1F0",
+"7|	c #E8F6FB",
+"8|	c #3C98EB",
+"9|	c #1585EE",
+"0|	c #B7DFF3",
+"a|	c #3E9CED",
+"b|	c #71B3E7",
+"c|	c #62ADE9",
+"d|	c #C1E1F4",
+"e|	c #0E80F4",
+"f|	c #107EF4",
+"g|	c #E1F4FB",
+"h|	c #238DF0",
+"i|	c #057EFF",
+"j|	c #77B4EC",
+"k|	c #8BC3ED",
+"l|	c #0A7FF0",
+"m|	c #0A83F5",
+"n|	c #5BA6E8",
+"o|	c #E8F7FC",
+"p|	c #3C9BEF",
+"q|	c #067EFB",
+"r|	c #1483EE",
+"s|	c #FCFAFA",
+"t|	c #449DEC",
+"u|	c #077DF8",
+"v|	c #3291EE",
+"w|	c #ECF9FC",
+"x|	c #FCFCF7",
+"y|	c #AED9F4",
+"z|	c #0B81F1",
+"A|	c #D8EEF8",
+"B|	c #79B8F1",
+"C|	c #077EFC",
+"D|	c #EEF6F9",
+"E|	c #B9DCF3",
+"F|	c #0883F6",
+"G|	c #0481F6",
+"H|	c #7BB7F0",
+"I|	c #FDFDF6",
+"J|	c #8ABFF0",
+"K|	c #0782F5",
+"L|	c #1082EE",
+"M|	c #A7D4F3",
+"N|	c #DBECF8",
+"O|	c #2B8FF0",
+"P|	c #2F92EB",
+"Q|	c #E9F6FC",
+"R|	c #B2DBF2",
+"S|	c #45A0ED",
+"T|	c #047DFD",
+"U|	c #1386F3",
+"V|	c #C3E0F5",
+"W|	c #E1F2F8",
+"X|	c #248AF0",
+"Y|	c #222222",
+"Z|	c #EFF7FB",
+"`|	c #3494EC",
+" 1	c #87C1EA",
+".1	c #7EBBED",
+"+1	c #F7FFFC",
+"@1	c #87BCEE",
+"#1	c #0780FA",
+"$1	c #1182EF",
+"%1	c #ADD6F1",
+"&1	c #DAEBF6",
+"*1	c #298FF3",
+"=1	c #2C91F0",
+"-1	c #DBEDF7",
+";1	c #1084F4",
+">1	c #ADD8F1",
+",1	c #EEF9FA",
+"'1	c #4BA1EC",
+")1	c #91CAF1",
+"!1	c #5FAAEC",
+"~1	c #3593EA",
+"{1	c #686868",
+"]1	c #BADEF5",
+"^1	c #0E86F7",
+"/1	c #0C7EF0",
+"(1	c #A5D4F4",
+"_1	c #F4FCF9",
+":1	c #60AAF0",
+"<1	c #83BCEA",
+"[1	c #FFFFF9",
+"}1	c #7EBAE9",
+"|1	c #0480F6",
+"11	c #0E85F4",
+"21	c #B0D8F3",
+"31	c #D0EBF9",
+"41	c #268DF0",
+"51	c #4CA0EB",
+"61	c #0F84F1",
+"71	c #AAD7F1",
+"81	c #FDFBFE",
+"91	c #F0FAFA",
+"01	c #4CA4ED",
+"a1	c #66ABEC",
+"b1	c #F8FDFA",
+"c1	c #0680FA",
+"d1	c #1483F1",
+"e1	c #82BCEA",
+"f1	c #1183F4",
+"g1	c #C8E3F3",
+"h1	c #F2FCFC",
+"i1	c #3896EF",
+"j1	c #0880F9",
+"k1	c #8ABFEE",
+"l1	c #F9FEFB",
+"m1	c #F9FFFB",
+"n1	c #79B9EC",
+"o1	c #0980F3",
+"p1	c #1086F4",
+"q1	c #B7DAF1",
+"r1	c #D3E8F7",
+"s1	c #258BED",
+"t1	c #2A8CE7",
+"u1	c #D0ECF8",
+"v1	c #EDF9FD",
+"w1	c #4BA4EF",
+"x1	c #087EFA",
+"y1	c #0E82F2",
+"z1	c #A4D3F2",
+"A1	c #FBFAFA",
+"B1	c #53A6EC",
+"C1	c #459EEB",
+"D1	c #BBDCF2",
+"E1	c #1183F1",
+"F1	c #F5FAF8",
+"G1	c #53AAEE",
+"H1	c #E7F6F8",
+"I1	c #4298ED",
+"J1	c #0882F3",
+"K1	c #FEFEF6",
+"L1	c #F4FCFB",
+"M1	c #78B5F0",
+"N1	c #1685EE",
+"O1	c #B8DCF3",
+"P1	c #CEE6F6",
+"Q1	c #208BF0",
+"R1	c #248DED",
+"S1	c #D3E9F7",
+"T1	c #F1FAFD",
+"U1	c #51A6EF",
+"V1	c #A1D2F2",
+"W1	c #FFFDF7",
+"X1	c #5CA7EC",
+"Y1	c #3C98EC",
+"Z1	c #D8EDF8",
+"`1	c #278DF7",
+" 2	c #F9FBFC",
+".2	c #E5F2F6",
+"+2	c #3193EC",
+"@2	c #EEF7FA",
+"#2	c #A6CEEE",
+"$2	c #F4FDFC",
+"%2	c #75B3ED",
+"&2	c #1885ED",
+"*2	c #BCDEF3",
+"=2	c #C7E6F7",
+"-2	c #2289EF",
+";2	c #218CF0",
+">2	c #CEE7F6",
+",2	c #59A6EB",
+"'2	c #9CCEEF",
+")2	c #F8FBFA",
+"!2	c #F2FAFB",
+"~2	c #86BEEC",
+"{2	c #E6F3F8",
+"]2	c #E8F7FA",
+"^2	c #288CED",
+"/2	c #3D95EB",
+"(2	c #2087EE",
+"_2	c #499CE7",
+":2	c #6EB0E7",
+"<2	c #1687F1",
+"[2	c #BDE1F7",
+"}2	c #C4E4F6",
+"|2	c #1D8BF0",
+"12	c #CEE7F4",
+"22	c #5DA8EB",
+"32	c #9ACEEF",
+"42	c #FBFAFD",
+"52	c #EDF7F8",
+"62	c #1E89F1",
+"72	c #DAF1FC",
+"82	c #C7E6F4",
+"92	c #0A7EF3",
+"02	c #B3D6F0",
+"a2	c #67ACEC",
+"b2	c #1487F2",
+"c2	c #C3E2F4",
+"d2	c #C7E3F5",
+"e2	c #1E88EC",
+"f2	c #59ABEF",
+"g2	c #0981F6",
+"h2	c #95CBEF",
+"i2	c #8AC0E9",
+"j2	c #1D8AEE",
+"k2	c #CBE5F5",
+"l2	c #ACD3F2",
+"m2	c #1781EB",
+"n2	c #FDFFF8",
+"o2	c #65AAEE",
+"p2	c #C9E5F5",
+"q2	c #C5E0F4",
+"r2	c #1988EF",
+"s2	c #C8E4F7",
+"t2	c #F8FDFF",
+"u2	c #60AFEF",
+"v2	c #087DF6",
+"w2	c #91CAF2",
+"x2	c #1881EA",
+"y2	c #CEEAF7",
+"z2	c #6DAAE2",
+"A2	c #1F89EC",
+"B2	c #BBDFF6",
+"C2	c #1885EF",
+"D2	c #1888F0",
+"E2	c #C0E1F4",
+"F2	c #69B0EC",
+"G2	c #98C8EB",
+"H2	c #C7E3F1",
+"I2	c #FAFCF8",
+"J2	c #2890EE",
+"K2	c #218CEE",
+"L2	c #C9E8F8",
+"M2	c #1485F2",
+"N2	c #1787F0",
+"O2	c #C0DFF2",
+"P2	c #077FF8",
+"Q2	c #0481FA",
+"R2	c #3392ED",
+"S2	c #C4E1F5",
+"T2	c #B8D8F1",
+"U2	c #EAF6FB",
+"V2	c #67B3EF",
+"W2	c #067FF4",
+"X2	c #B7DBF4",
+"Y2	c #1586F0",
+"Z2	c #B8DEF4",
+"`2	c #70B6F2",
+" 3	c #0780F4",
+".3	c #69B1EC",
+"+3	c #EBF9FC",
+"@3	c #F7FAFA",
+"#3	c #BBDEF0",
+"$3	c #EDFBFC",
+"%3	c #4EA4F2",
+"&3	c #0A80F4",
+"*3	c #5DACEC",
+"=3	c #FBFBFA",
+"-3	c #B8DDF6",
+";3	c #288CEC",
+">3	c #D2E9F6",
+",3	c #B6D8F3",
+"'3	c #1385F2",
+")3	c #74B7ED",
+"!3	c #3D96E5",
+"~3	c #C3E4F6",
+"{3	c #54A6EE",
+"]3	c #087EF8",
+"^3	c #A0C6E8",
+"/3	c #228CEF",
+"(3	c #F0FBFB",
+"_3	c #E2EFF6",
+":3	c #ADD7F4",
+"<3	c #0F82EF",
+"[3	c #1184F1",
+"}3	c #B0DAF3",
+"|3	c #268AEE",
+"13	c #0481F8",
+"23	c #0B7FF1",
+"33	c #B5D7ED",
+"43	c #93C7EE",
+"53	c #63ADEB",
+"63	c #E1F0F6",
+"73	c #AAD4F2",
+"83	c #1183EF",
+"93	c #B1D8F0",
+"03	c #ECF7F9",
+"a3	c #5FA6E5",
+"b3	c #1785F2",
+"c3	c #A1D0F1",
+"d3	c #FFFCFB",
+"e3	c #D4EBF8",
+"f3	c #3998F2",
+"g3	c #DBEDF6",
+"h3	c #0D84F4",
+"i3	c #ABD5F1",
+"j3	c #7DC0F2",
+"k3	c #4C9EED",
+"l3	c #D8ECF5",
+"m3	c #2D2D2D",
+"n3	c #F3FBFB",
+"o3	c #92C2EF",
+"p3	c #3E97EB",
+"q3	c #DBF1FA",
+"r3	c #FEFEF7",
+"s3	c #FFFBFE",
+"t3	c #A5D0F1",
+"u3	c #0C82F5",
+"v3	c #AAD5F3",
+"w3	c #8FC2EC",
+"x3	c #9BCBF0",
+"y3	c #A0D0F1",
+"z3	c #0980F1",
+"A3	c #A3D2F1",
+"B3	c #9CCCF0",
+"C3	c #0D80F1",
+"D3	c #9CD1F4",
+"E3	c #97C9F1",
+"F3	c #087FF6",
+"G3	c #9FCFED",
+"H3	c #FEFAFB",
+"I3	c #EFF7FA",
+"J3	c #6FB2E6",
+"K3	c #057FFD",
+"L3	c #1B86F1",
+"M3	c #69B0EE",
+"N3	c #D6ECF5",
+"O3	c #E7F8FD",
+"P3	c #9DCBED",
+"Q3	c #439BEF",
+"R3	c #1083F3",
+"S3	c #50A3EF",
+"T3	c #99CBEF",
+"U3	c #DCEDF7",
+"V3	c #95C5F1",
+"W3	c #54A7F2",
+"X3	c #1380EC",
+"Y3	c #077EF5",
+"Z3	c #047EF7",
+"`3	c #1D8AED",
+" 4	c #56A8EF",
+".4	c #A3CDEF",
+"+4	c #C4E2F4",
+"@4	c #8AC3F3",
+"#4	c #5BABED",
+"$4	c #3092EF",
+"%4	c #1482F8",
+"&4	c #0680F5",
+"*4	c #1184F3",
+"=4	c #3093EC",
+"-4	c #99CBF0",
+";4	c #C6E1F0",
+">4	c #CEE3F1",
+",4	c #95C5EE",
+"'4	c #8CC6F4",
+")4	c #60ABE9",
+"!4	c #58A7EA",
+"~4	c #59A7EA",
+"{4	c #54A8F0",
+"]4	c #6EB2EC",
+"^4	c #90C6F4",
+"/4	c #B2DAF4",
+"(4	c #CCE3F0",
+"                                                                                                                                                                                                      . . +                                                                                                                                                                                                     ",
+"                                                                                                                                                                                                      @ #                                                                                                                                                                                                       ",
+"                                                                                                                                                                      + . $ $ +                   + % & * +                       . $                                                                                                                                                                           ",
+"                                                                                                                                                                      + . = @ +                   + - ; > ,                       ' )                                                                                                                                                                           ",
+"                                                                                                                                                                      + . ! ~ {                   . ] ^ ^ / $                 $ ( _ : $ .                                                                                                                                                                       ",
+"                                                                                                                                                                        + < [ } +                 + | 1 ^ 2 %                 . 3 4 5 6 +                                                                                                                                                                       ",
+"                                                                                                                                                                      + 7 8 ^ 1 9 .               0 a 1 ^ 1 b                 c d ^ ^ , .                                                                                                                                                                       ",
+"                                                                                                                                                + +                   + e f g 1 h i +           + j [ k l [ m + +         n o p l ^ 1 q +                 + +                                                                                                                                                   ",
+"                                                                                                                                                r -                     s [ 1 t u v w +       + 7 x y z A B C D $         E F 1 G ^ ^ H +               + $ $ & I                                                                                                                                               ",
+"                                                                                                                                                J K ' + + +           + L B M N O P & . +     + Q R S T U l [ V .     + + W X Y Z ^ ^ ` .             + . 6  .J +                                                                                                                                               ",
+"                                                                                                                                                ..[ +.@.% .             V #.$.%.&.*.4 s $ +   =.-.;.u >.,.'.^ ).7     . !.$.~.{.].^.^  ..           + $ /.(.1 C                                                                                                                                                 ",
+"                                                                                                                                                m [ k _.:.<.. +         ~ [.}.|.1.P 2.3.4.5.+ 6.4 2.7.8.9.0.a.2.b.n + c.d.e.f.g.h.i.j.k.l.      m.n.o.p.q.1 ^ r.                                                                                                                                                ",
+"                                                                                                                                                s.t.u.v.w.x.y..       y.z.4 A.B.C.D.E.F.G.H.$ I.[ a.J.K.L.M.N.O.P.Q.% R.S.T.U.V.W.X.Y.Z.`.       +.+++@+f ^ ^ #+                                                                                                                                                ",
+"                                                                                                                                                $+1 [.%+&+[.*+=++ +   -+[ ;+>+,+'+)+!+;+B ~+{+]+1 ^+/+(+_+:+<+[+f }+|+[ 1 1+2+3+4+5+[ 6+7+  + + 8+9+0+a+;+^ 1 b++                                                                                                                                               ",
+"                                                                                                                                                $+c+d+e+f+S.[ g+h+.   c [ S.i+j+k+l+m+R n+o+(.1 ^ p+q+r+s+t+u+v.u.v+> ^ ^.w+x+y+z+A+~.4 B+  + C+D+0+E+F+G+^ 1 H++                                                                                                                                               ",
+"                                                                                                                    + . + .                     I+1 J+K+L+M+N+[ O+P+. Q+^ R+S+T+U+V+W+X+Y+[.Z+[+`+ @.@+@@@V+#@$@%@&@R *@=@-@;@;@@@>@,@P '@)@!@z.~@{@]@^@/@^ 1 (@+                   + .                                                                                                                         ",
+"                                                                                                                    . . _@:@+                   <@[ [@}@|@1@2@3@4@t.|+& ^ J+5@6@7@k+8@9@0@B l a@b@c@8@d@e@f@g@h@E+i@j@k@l@m@;@;@n@o@p@q@r@s@t@u@u v@w@x@y@^ 1 z@.                   I V A@                                                                                                                      ",
+"                                                                                                                        B@[ C@D@+ .             E@2.F@G@x+H@I@J@O.a.1 K@^ L@M@N@O@P@r+Q@R@S@e.T@U@K.L.K.V@T+L.W@X@Y@Z@`@N@;@;@;@ #.#+#R+@#[+j.##$#%#t+&#*#^ ^ :@        . . . . =#-#d C@                                                                                                                        ",
+"                                                                                                                        ;#[ [ [ >#,#            $ [ t.'#)#V+l+!#~#*.^ ^ ^ G {#N@]#^#/#(#_#:#<#[#}#|#g@1#2# #3#4#5#6#7#8#9#;@;@;@ #0#a#R+b#n+c#d#e#t+V@8#f#^ ^ :@        + $ g#>#8 4 [ h#                                                                                                                        ",
+"                                                                                                                        % i#l f j#k#l#m#n#o#    % k %@p#q#|#r#6@s#t#u#v#w#x#y#H@z#A#B#k+_+C#D#E#F#@@G#H#I#H@J#K#L#M#N#3+3#O#P#O@Q#R#S#T#[ U#V#W#X#L.V@Y#Z#^ ^ w . . $ % `# $q@[@L@^ .$6                                                                                                                         ",
+"                                                                                                                        + +$n+@$w##$$$&+%$&$*$  % i#w#=$-$L.;$_+>$B#,$'$f )$!$t+~${$]$L.V@m@^$/$y+($_$:$<$r+[$V+}$|$1$t+2$3$4$5$V+6$7$[ 8$9$0$l+k+k+@@a$Z#^ ^ .   y.] g+t.b$c$d$e$^ j $                                                                                                                         ",
+"                                                                                                                        . c f$g$'$h$i$j$k$l$m$n$o$K J+p$q$r$s$e@3#V+t$u$v$w$K.y+x$y$z$A$k+4+B$($C$D$E$B F$G$f@J#P@@@_+H$I$J$K$L$M$d@N$O$P$Q$n@3#R$k+k+S$T$^ 5 U$V$W$1 ^ X X$Y$Z$2.4 `$.                                                                                                                         ",
+"                                                                                                                        + .  %Z+$..%+%@%#%n+2.q@$%%%&%*%=%M$k+-%_+;%y+C$>%,%_+V+'%)%S.!%~%($s+;%(${%e.E+p@]%l+^%V+_+/%(%0+_%:%5$<%[%}%|%1%<%r#2%]#r+V+3%4@^ 4%5%~.[ v.L@6%7%8%}.E+5 U$.                                                                                                                         ",
+"                                                                                                                            9%$.#.0%a%b%c%d%e%f%1 u.k 2.g%h%[%i%j%k%@@5$3#r+V+k+l%m%~@n%o%y+V+l+p%q%*.l g r%s%y+s+t+t%u%w#4 v%J#J#3#C$w%t+x%y%z%($z+A%B%C%L@f D%E%e.F%G%H%X#I%J%4 _@+                                                                                                                           ",
+"                                                                                                                            e K%F.L%M%|#U+N%O%d%6+k P%Q%R%m@S%T%U%V%W%[%(#r$<%X%Y%R Z%`% &.&K.|#+&@&f ^ ^.#&$&Q#%&&&*&d$1 4 =&C$;@C$<%_#l+-&;&>&[$<%@@,&6#f Z+'&)&!&~&<%{&4#]&^&2./&                                                                                                                            ",
+"                                                                                                                            (&_&l :&<&Q#C$|#[&}&|&1&2&3&4&5&6&7&[ R 8&9&0&s+a&y+b&^&G j#c&d&e&a$f&R ^ ^.^ U#g&5&h&i&j&k&i@#.l&)#5$k+<%m&n&o&k#p&V@q&5$l%r&Z$s&t&u&v&y+6@_+w&x&J+y&$                                                                                                                             ",
+"                                                                                                  + o$6 + +     +   +       n#z&Z+A&B&x%J#r#y+5$f@C&D&E&F&G&K.H&I&J&J%K&L&M&N&Y#O&P&i@&%g [+Q&R&S&l ^ ^ T&x&U&V&W&t.X&Y&'&,@Z&`&V@<% *.*+*t.2.@*<%s$6$#*$*%*&***K#L.L._+[$=*#%[.-*.     +   + + + + + + 6 o$                                                                                                    ",
+"                                                                                                + $ ;*5 >*,*'*@ $ . +       . ' )*^ !*~*@@<%{*Q@]*y+;%t$^*/*5$(*_*f :*<*[*}*2%|*1*m%^ ^ ^ M o&2*~.L@^ ^ ^ 3*#%4*5*e$^ ^ ^ &@6*7*($8*9*[@b#n+f 0*l+B$<%a*b*/#[&c*V@;@@@k+d*e*f*g*h*.     . $ $ $ h+9 B@i*j*k*                                                                                                    ",
+"                                                                                                  + . l*[ 1 1 [ m*I.n*o*p*+ . . q*1 X&r*J#<%3#S$H@q+[$<%9#x+m@s*t*f 1 n+u*v*:#w*I&x*^ ^ ^ &@[@q@[@T&^ ^ ^ e$f f$f$c+^ ^ ^ 1 +*y*z*A*q@&%Y&^.B*C*@@Q@X#4+D*[$6&E*F*_+<%n@G*H*I*J*(&$ + K*o*L*I.M*[ 1 [ 4 N*y.                                                                                                    ",
+"                                                                                                    + p*O*^ ^ ^ ^ ^ 1 4 8 P**+Q*= [ R R*S*5$[&T*U*V*_+H@ #k+W*X*Y*J%g ^.L@6+Z*`* =[.^ ^ ^ :*Y&1 &@L@^ ^ ^ .=+=d$'&c+^ ^ ^ c#~@@=#=$=Y&&%L@c+%=&=J#[%k+r$'+*===-=8#x+Q@2%;=6#;+>=,=*+P*d 4 [ ^ ^ ^ ^ 4 > '=.                                                                                                     ",
+"                                                                                                      + )=1 l n+M '.j.!=j.k 6#X&1 k k ~={=]=1$^=/=(=_=:=<=H@K.K.[=[@b#T&^.&%X&}=c#^ ^ ^ ^ ^ b#c+l ^ ^ ^ ^ v.:*|=g ^ ^ ^ ^ 1=R Z 1 L@L@R+u.~@2=3=y+a&V@4=5=6=t.7=y+C$@@8=9=0=R k &@[ J%N J%`%f a=^ ^ 4 b=+ +                                                                                                     ",
+"                                                                                                        . c=k d=e=f=g=h=i=j=k=:&l=J+f Y m=]=[%n=o=O.p=q=r=s=t=|#u=&+^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ c+v=w=x=Q#y=z=A=x&B=+*C=L.D=5&E=F=&@&%n+[+G=H=I=J=K=L=M=c+^ b+$                                                                                                         ",
+"                                                                                                        + , N=R #%O=P=Q=R=S=T=U=V=W=X=Y=Z=`=k+_+ -u@.-x*&@P%+-@-#-;.^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^.f $-%-&-*-6+f [ =---;-<%k+8#>-0=,-'-)-!-~-{-]-C$^-/-(-l > /.+                                                                                                         ",
+"                                                                                                        + $ _-N N+M+:-3#;%H@Q@l+<-[-}-|-1-2-X%X%3-,@'&t f ;+4-f*5-F@^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^.J&6-7-,@$=~@L@;.O.8-]=(+y+9-0-a-b-c-q+{*[%m@5$G&d-e-p@4 Q*$ .                                                                                                         ",
+"                                                                                                          + f-g-f :*h-i-n@k+K.@@J#H@[$C$x+r$J#j-k-l-g g R+:*m-v.1 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ g e$v.J+^.c+^.~@n-o-z+L.W*r#k+r+@@V+x%@@@@L$k+p-q-4 U#r-y.  +                                                                                                         ",
+"                                                                                                              s-t-^ u-v-5&5&w-x-3+<%k+ #;@L$(#k+y-z-T&^ ^.c+^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ i@A-&*v&l+k+w%5$z+6&V@<%B-C-P@D-E-<#*@F-G-$                                                                                                             ",
+"                                                                                                              + b [ H-I-J-k+{*<%K-L-M-N-O-1%s+r+x%P-T#&@G Y&^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ w#Q-r$R-S-(+5&T-U-V-W-X-Y-r#3#Z-`-:&f* ;.;                                                                                                              ",
+"                                                                                                                $ *+X&+;@;#;$;_#%;a#&;*;=;-;;;>;,;';);S !;e$^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ *-~;{;];^;/;$-(;_;:;<;{&;$y+[;};l J+|;H.                                                                                                                ",
+"                                                                                      . . + + + + + . . . + + + + =+1;P&S.2;3;J#R-4;<#E+~@.-b#5;6;7;8;9;L@1=^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 0;a;b;c;~@d;e;~@,@f;;-V+5$[$g;h;q@d i;. + + + + + + + + + + + + . +                                                                                     ",
+"                                                                                    + j;k;k;k;k;k;k;k;k;j*l;l;l;l;.$P m;P n;o;[%p;q;r;G=u.[ g ^ O s;t;u;G J+^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ l v;T&^.1 y :*w;x;y;1$_+3+z;A;B;P ]+.$C;l;l;l;K@k;k;k;k;k;k;k;k;j;+                                                                                     ",
+"                                                                                    + . D;a [ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ x*3*`%a@E;F;($5&G;H;f n+T&L@t E.u.G :*Y&^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^.L@L@c+b#d=&@I;J;6$5$_+K;L;v;+*^.^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 4 M;$ +                                                                                     ",
+"                                                                                      . $ N;J ^ ^ ^ L@B*O;p#P;P;P;P;Q;R;S;T;U;V;W;@@v&X;R 1 L@Y;Y&1 J+^.g v.^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1=1=^.b#1=w#t.Z;X#5&w%k+`; >.>+><+P;P;P;@>@>P;#>$>L@^ ^ ^ a %>. . .                                                                                     ",
+"                                                                                        + . &>)*[ ^ *>=>->6&3+x+x+x+;>F#C$R-x+<%5$5$1%>>,>J%e$^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ [@'>)>!>[%@@5$B$r+~>3+Y#x+x+x+x+X#t$X#{>]>^>Y&P&d ;*                                                                                            ",
+"                                                                                          . $ />(>^ l _>:>6$<%;@;@;@;@V+C$5$m@w%w%n@[&Q@<>[>^.^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ R }>|>v&X%W*r$s$;$1>@@@@ #;@;@;@_+A%Q$2>3>q@f 4>6.+                                                                                             ",
+"                                                                                              . @ 5>6#d$6>7>Q@;@;@;@C$1$8>|#y+[%[%[%9>0>a>b>^.^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ [+c>d>e>f>g>Q@V@Y#@@h>i>n@;@;@;@j>k>l>m>@$n>o>p>                                                                                                ",
+"                                                                                            + . . e q>d$[.r>s>Y#@@;@@@t>u>v>w>x>y>z>A>B>C>D>^.^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ c+c+^ ^ Y;1=^ c+^.^.1=1=e$e$e$e$:*L@^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ &@E>F>G>H>I>J>K>L>M>N>O>3#m@ #m@6&P>Q>k &@y&R>S>                                                                                                ",
+"                                                                                                + . e 5%1 ^ T>U>V>V+k+~%W>A.1 l ~@~@g ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ g g ^.^ T&1 E.w#D%T&c+L@u.w#w#&%[+1 1=Y&^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ g T&w#n+2.}.X>Y>Q#@@(+2%Z>`>D%:*r.p*                                                                                                    ",
+"                                                                                                + + + o$q*1 &@f* ,.,<%Q@+,@,&.k x*f b#^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^.^ 1 ~@c#<*g ~@X&L@l g g g c+Z+k$:*+=^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ e$#,F.;+U#$,%,t+;%<%W+&,*,=,M -,;,+                                                                                                     ",
+"                                                                                                        w >,B <*,,',),C$Q@9.!,~,'.&%^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 *.G={,+#],^,/,(,_,:,<,<,<,*,[,R+n+^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ Y;:*},|,1,2,5$ #/*3,4,5,w#L@6,7,                                                                                                        ",
+"                                                                                              +   + 8,9,0,a,b,g i@c,d,T-[%X%e,f,g,B 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ c+^ e$^ ^ L@1 [.1 t.T#'.[ =-Z*h,i,j,k,l,m,8#B#Y>n,n,o,p,q,l |=Z+,,r,y ~@=,1 L@^.g ^.c+^ ^ c+1=^ ^ ^ ^ ^ ^ ^ f j.s,t,t$6@<%a&u,v,%@R l ,@w,x,y,z,8,A,+                                                                                               ",
+"                                                                                              % =+&>j B,c,C,D,j#R E%E,F,b%G,k+t+H,I,Y;^ ^ ^ ^ ^ ^ ^ ^ ^ ^ g x*g Y;Z%b#Y&J,K,L,M,N,O,P,{@Q,R,+,s+X%r#;@;@;@n@@@[$C$]*S,g T&T,U,V,W,X,Y,Z,a@Y;&%L@Y&g ^.^ c+^ ^ ^ ^ ^ ^ ^ d$Z.`,;-y+@@w%5& 'i$m%&@n+v.x&Q%.'+'@'#'$ .                                                                                             ",
+"                                                                              . + + + + - $'Q r-1 1 ~@O ;+4 %'&'*'='-';'t$[%[$r+>','g ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^.2.&@X&i.''7=)']-C$Q@Q@S*!'5;&+~'{'L.q&]#;@;@;@;@**5$$;]'^';+f /'('t+S-8#_':'<'['}'+*;.l ^ ^.^.^ ^ ^ ^ ^ ^ ^ [@'.|'1'2'C$k+L.3'4'5'6'7'5;O.+*j$F.n+[+8'9'0'A@+ . . + + +                                                                             ",
+"                                                                              $ a'b'b=c'5 4 1 ^ ^ ^ M %'d'e'f'g'Q=H@r#K.n@h'C#i'j'k'1=^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^.<#l'm'n']-[&k+<%5$x+o'p'q',@r'2.s'^-Q# #;@;@;@@@C$w%t'u'r,&+d$v'w'x'<%m@1%5$O-C&y'z'A'B'1 g ^ ^ ^ ^ ^ ^ ^ ^ [+'&[ C'D'E'[%<%k+Q#t+X#F'G'H'I'J'6+Y;^.^ ^ 1 K'c'L'0 { $ +                                                                             ",
+"                                                                              . H+J [ [ [ ^ l p$M'N'O'P'Q'K.y+ #O@5$_+{*@@R'S';.E.f ^.^ ^ ^ E.j#J+b#Q%B q@T'U'V'C$r#W'3#B#X'Y'Z'`'r> )[,.)[ +)@)#);%V+Q@r+r#y+$)%)0+0=O J%U#G=&)*)=)-)Q=;)x%Q@C$>),)')))k &@m%1 g ^ ^ ^ :*|=e$u.!)~){)y+V+ #C-_+3#])<%+,^)/)()_)i.&@J+1 [ [ [ 9'.                                                                               ",
+"                                                                              . + b'c'4 [ ^ l :)<)[)<-3#@@r+8#@@B$;@O@})];|)l ^ ^ ^ ^ ^ ^ ^ &%n+u.u.h;1)2)3)**4)H@X#5)6)7)8)t.6+:*e%9)L>0)F.P&o+,>a)b)c)d)e)f)g)h)m%P&i)j)k)0)Y&f$p=l)m)n)o)~$k+[%i>~&p)q)#.H-w#$=^ ^ ^ ^ ^ ^ ^ r&r)s)t)s+Q@(#0&;@<%C$V+y+6$F#u)v)c#n+1 4 c'w)w $ +                                                                             ",
+"                                                                              + +     !.W$[ t.w;u@x)y)%,3#V@_+k+J#y+t$z)A)E.^.^ ^ ^ ^ ^ ^ ^ ;+'.f$B)C)%,y+**Q#D)E)F)T#G)x&J%H)I)J)K)L)M)N)v*t.Z%i@m-O)P)Q)R)p=S)Z+[ E,T)U)V)W)X)Y)Z)h)`%[+`) !.!+!1%s+x+@!#!$!0+[.^ ^ ^ ^ ^ ^ ^ f [+Y.l&%!&!6&w-@@{&$;k+*!=!-!+#;!q@;.>!N;+                                   . + . .                                           ",
+"                                                                                      . $ Q+,!x*#$'!)!!!~!8#k+;@@@x@{!]!^!l ^ ^ ^ ^ ^ ^ ^ ^ #./!(!_!G&W'r+:!<![!B'}!<#|!1!2!3!v&e,Q@5&6@U)4!O;~@Z+j#3*w;&@[ :*1 m-5!6!q+|#L.8>5&;>7!8!9!0!m-[.*.a!b!c!k+M$l+d!e!=$^ ^ ^ ^ ^ ^ ^ g :*[+P f!g!a&_+k+3#Q#h!i!e%j!k#F=k!l!m!. +                                   + y.A@.                                           ",
+"                              + . + $ n!o!p!q -+. . .                                       =.b=q!4 ~@A&r!s!t!y+u!v!w!^.e$^.^ ^ ^ ^ 1 :*X ;!x!y!y+k+5$z!A!B!~.C!D>D!E!F!+@[%m@O@@@O@n@;@V+1$G!H!I!p@E+e;m-J!)!K!L!M! #m@;@;@;@;@]#;@;@_+N!O!P!Q!`%*.R!S!T!X#;$Y#U!x!u Y@&@u.T&~@b#c+^ ^.l *-V!]=N@W!X!Y!c+^.;.K@Z!6 `!                                        =#: ).*+ ~$ . +                                   ",
+"                                . <@.~[ 4 [ 1 K@#+k*{++                                       . +~H+@~w#~@#~$~%~&~*~T&^ ^ ^ ^ ^ ^ ^ '&k =~-~;~3#<%9.>~,~J!'~)~!~~~{~<%;%]~1$;@;@;@;@;@;@;@m@5$^~/~(~_~:~<~[~}~/~|~O@;@;@;@;@;@;@;@;@;@;@@@9#B#1~4,2~B;B'3~4~2%5~B$6~7~8~[ J+D%9~L@^ ^ ^ l ~@0~a~b~c~T@[ ^ a j @ . +                                           6 t-[ [ J b+&>$                                   ",
+"                          + % d~e~C ^ ^ ^ ^ ^ ^ ^ ^ ^ f~g~h~;,. $ + $                               i~j~N k~l~t l$r&c+^ ^ ^ ^ ^ ^ ^ F.m~n~H@[%F#|%o~p~q~B*r~s~x+q&Q#<%])a&;%;@;@;@;@;@;@;@[%[%;@V@1$5$B$]);$<%8@r$;@;@;@;@;@;@;@;@;@;@;@@@<%7@7@{&t~u~v~e.n%w~x~C$[%y~z~A~B~'&^&g ^ ^ ^ &@E.G A&5;^&C,$$C~=#                          + . . $                 . D~1 ^ ^ ^ [ 8'E~- . +                           ",
+"                          I I.[ [ 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 [ [ [ F~} 0'(                               G~H~I~J~f$c#J+w;b#^ ^ ^ ^ ^ ^ ^.K~L~M~V@N~O~(=p=A.P~Q~~$y+m@k+O@L.P@s+L$;@;@;@;@;@;@;@O@3#[%V+_+k+ #Q@t+O@Q@V+;@;@;@;@;@;@;@;@;@;@;@O@1%V+r$(+N@G&R~S~p@Z+0!T~[;;%v&U~V~&+:*^ ^ ^ ^ [@<*b#J+2.1 W~X~$ .                             ( /&-++               . q ^ ^ ^ ^ 4 [ 4 Y~p!@                           ",
+"                  + $ I Z~8 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ [ ~ w .                               `~ {[ ^ ^ ^ ^ ^ ^ ^ 1 [@u@.{;~Q@l++{@{0+~._)#{x@t+_+;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@r$y+C$a&[%n@ #X%L$@@W* #;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@ #]-${%{6#p$&{*{x+6&={-{;{R+J+n+Y&^ ^ ^ ^ ^ ^ b .                           + . I+M*4 9 +               + -+5 [ ^ ^ ^ ^ ^ ^ ^ J _@!.                      ",
+"                  7 >{8 [ 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ [ [ Q+.                               ,{C;1 ^ ^ ^ ^ ^ ^ ^ 3*'{){D-[%3+!{x;`%~{{{]{<%^{S%m@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@J#_#($L._#/{({_{:{[$O@<{k+;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@5$q+[{}{|{))1{2{K.3{X*4{5{9~n>n+^ ^ ^ ^ ^ ^ C;#                           + U$f~[ 4 D~+               + $ 6{[ ^ ^ ^ ^ ^ ^ 1 ^ 7{N;                      ",
+"                + 8{^ ^ ^ ^ ^ ^ ^ 1 4 f~Q I.$%4 [ 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ Y~K*                          + 9{0{^ ^ ^ ^ ^ ^ ^ ^ ^ 6#a{S-{&2%b{M+;!c{d{e{|#<%f{m@**;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@H@g{h{i{j{e-k{l{m{n{o{;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@w%R-C$p{q{r{s{t{u{G&6&Q=v{w{9~u.^ ^ ^ ^ ^ ^ [ y&+~.                       + x{1 ^ [ C;K*                  & 4 ^ ^ ^ ^ ^ ^ [ >,+~.                       ",
+"                . t-^ ^ ^ ^ 1 1 ^ C;y{a'. + ( D z{A{^ 1 1 ^ ^ ^ ^ ^ ^ [ B{                        + U$m 1 ^ ^ ^ ^ ^ ^ ^ c+C{D{E{_+F{G{o&#&H{I{r+y+Q@r#z+P@m@;@;@;@;@;@;@;@;@;@;@;@;@W*;@5$l+J{K{O.#.6#0=J%F.B~f+L{X'm@;@@@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@]#]#5$|#K#M{);6#N{O{-%3#P{_~U#R+c+g b#L@^ ^ [ [ _ + +                     - 7{^ ^ 1 1 |++               + A{1 ^ ^ ^ ^ ^ $%h#$ + +                       ",
+"                D [ ^ ^ ^ 1 4 5 (@7 $ +           . o$Q{R{r.C ^ ^ ^ ^ [ a @..                   + $ Q*4 1 ^ ^ ^ ^ ^ e$:*e%S{F#n@T{U{4 V{W{X{m@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@]#R$V+Y{Z{`{ ]w#H-#.q@k j.Y&:&#,.]+];@y+ #;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@5$B$@]#]S i)$]%]W'K#&]#=:*f X&6+^ ^ ^ ^ 4 a,% .               + $ *][ 1 ^ ^ ^ >#$             . K*).^ ^ ^ ^ ^ g+'                               ",
+"              + / 1 ^ ^ ^ 1 C;' $ + + +           + . . + . j;l;^ ^ ^ [ 1 C@a'                +   D@8 [ 1 ^ ^ ^ ^ ^ J+t.=]G&r+T{-];];.>]3)N@ #;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@ #Q#($,]']k==-~=_*)]!]~]{]]]l k N 5#^]1%@@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@w%V+[%/](]h)}._]:]X#1%u+*@6+&%R+^ ^ ^ ^ 1 J <].               + []d [ 1 ^ ^ ^ J }]% +         + <@^ ^ ^ ^ ^ ^ x{$                               ",
+"              + W$[ ^ ^ ^ 1 |].                               1]4 ^ ^ ^ ^ 4 '*              + $ =+d.[ ^ ^ ^ ^ ^ ^ ^ m%2]3]V@4]5]e.E,6]7]y+8]@@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@]#H@_+9]R #,'>0]a]c)b]C$X-c]d]h;'.#%e]t+;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@O@B$@@r$f]g]x&h]9$x+;%i]j]k]J+w#^ ^ ^ ^ ^ ^ g+=.              + l][ ^ ^ ^ ^ ^ [ [ m]w +       + / ^ ^ ^ ^ ^ 1 /..                               ",
+"            + , a 1 ^ ^ ^ 1 |++       + + p*n]+ + + .         - g+1 1 ^ ^ 1 K@n]              . o][ ^ ^ ^ ^ ^ T&l R p]q]@@|@r]s];!t]u]z+5$@@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@r#;@v]w]j.%@A>x];$@@($O@C$6@y]z]s;m%A]B];@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@y+n@k+5$<%C]D]F@E]F]x+P#G]H]B J&^ ^ ^ ^ ^ ^ [ n*+ +       + + I]d 1 ^ ^ ^ ^ ^ 1 1 1 K A@.     . J]^ ^ ^ ^ 1 5 . +                               ",
+"            $ ] ^ ^ ^ ^ ^ ^ 9{+       + $ R.d A{(@<@%         . <]8 [ ^ ^ ^ ^ m].           + /.4 ^ ^ ^ ^ ^ c+G q@K]L]K#y~M]N]5{O]P]O@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@X%n@7*+)`%B'Q]y+O@;@;@;@<%[&Q#R]c#v.E]S];@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@X%r#T]U]6#V]W]G&K.X]Y]E+c+^ ^ ^ ^ ^ 4 ).=#.         . Z]4 1 ^ ^ ^ ^ ^ ^ ^ 1 4 F~@.+   `]Y~^ ^ ^ ^ 4 *+                                  ",
+"            $  ^^ ^ ^ ^ 1 y&. +       . A@> 1 1 1 [ i#+       + + n$1 ^ ^ ^ ^ 8 i;        + % (.1 ^ ^ ^ ^ ^ g 5;.^+^H@V@@^#^N+$^y;h%w%;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@r+%^$$0+`>&^[%;@;@;@;@m@x+[%*^=^T&0+-^;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@W*[%[%;^>^q~,^'^1%[&)^!^c+^ ^ ^ ^ ^ 1 1 #+w       + c )*1 1 ^ ^ ^ ^ ^ ^ ^ 1 1 1 ).] + ,{1 ^ ^ ^ ^ 1 z@                                  ",
+"            a'7{^ ^ ^ 1 [ & $ +       + o*1 ^ ^ ^ 1 ~^            =.C;^ ^ ^ ^ 4 `$      + . y{[ [ ^ ^ ^ ^ ^ ~@;!{^3+h%]^^^c,/^(^@@_^;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@B$y+:^P%k <^[^B$W*;@;@;@m@V+1%}^B=&@C{|^;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@W*J#r+O@1^U.F.2^3^(+4^5^^.^ ^ ^ ^ ^ ^ ^ [ 9       + B{[ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ]+Q*%>[ ^ ^ ^ ^ 4 #                                   ",
+"            6^1 ^ ^ ^ 1 4 q +         . B@1 ^ ^ ^ [ 3             @.C ^ ^ ^ ^ K',         - O*1 ^ ^ e$^ |=1=B 7^8^V@9^0^Z$a^b^ #@@ # #;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@B$;@c^d^@$5;e^y+a&R$C$O@B$f^Y#g^n+X&}'h^;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@k+B$w%5$6$i^j^4 k^X#;$u,l^m^$=Y&^ ^ ^ ^ 1 8'. +     E~1 [ 1 j*6{n^F~[ 1 ^ ^ ^ ^ ^ 1 1 d 1 ^ ^ ^ ^ m*.                                   ",
+"            o^[ ^ ^ ^ 1 $%-           % r.1 ^ ^ ^ 1 []            n$1 ^ ^ ^ ^ #+$         L*1 ^ ^ ^ n+D%L@^.<^p^6@q+q^P }'r^y+;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@m@5~s^t^~@g u^v^v&w%B$**L.1%w^x^[@Z%y^z^;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@[%6&A^(-B^C^D^_+E^1+'&A&^ ^ ^ ^ ^ ^ D;.     []7{c=F^K*+ $ `]B@1 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ >,.                                   ",
+"            G^1 ^ ^ ^ 1 H^+           # [ ^ ^ ^ ^ F~%         + . I^1 ^ ^ ^ ^ L'+     . -+Y~1 ^ ^ ^ L@J^^&#%K^L^[&M^N^+;O^P^n@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@@@Q^a$R^d$l 0+S^T^O-L$V+_+U^V^S.x*,@W^R-;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@n@5&X^Y^0+Z^`^V@ /./D,c$^ ^ ^ ^ ^ ^ F~+     + a'+   + +   + . n!(>1 1 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ n^$                                   ",
+"          =+K'[ ^ ^ ^ 1 E~+           z@4 1 ^ ^ ^ '@$ +       . C+.$4 ^ ^ ^ 1 c .   + $ ) ]+1 ^ ^ ^ ^ c#c&+/@/5&#/$/$.%/&/|#<%;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@O@V+R-*/=/~@Z*I*-/;/>/,/'/)/p=t.`%!/R'9#;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@O@+@l+~/,^$.{/]/<%^/// )^ ^ ^ ^ ^ ^ [ I+                      + =.r ]+^ ^ ^ ^ ^ ^ ^ ^ ^ ^ (/$                                   ",
+"        . }]1 ^ ^ ^ ^ [ _/+       + $ 8{^ ^ ^ 1 [ o*+         . q ^ ^ ^ ^ [ m*+       { 0{1 ^ ^ ^ ^ ^.c#T#:/8>Q#</Q!O.[/(+<% #;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@@@;@J#}/|/k'5{d$m-x*c#1/^&(-J%2/3/@@s+;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@w%;@y+4/N %'5/_#N@6/F.c+^.^ Y&^ ^ ^ 0{. +                       . N;(>[ 1 ^ ^ ^ ^ ^ ^ ^ #+;,+ +                               ",
+"        . >,^ ^ ^ ^ ^ 5%. +       + a'd ^ ^ ^ 1 $%U$          . B{^ ^ ^ ^ 4 7/        Q{[ ^ ^ ^ ^ ^ e$B=//8/|#9/0/Y@a/b/v&c/]#;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@Y#d/e/<#:&J^c#E.!;f/U#g/h/R-k+_+;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@i/j/h;k/^~h%l/m/T&^ ^ ^ ^ ^ ^ [ $'+                       . $ n]Z~^ ^ ^ ^ ^ ^ ^ ^ 4 Y~n/.                               ",
+"        { M*^ ^ ^ ^ [ M;          + />1 ^ ^ ^ 1 I.+           { (>^ ^ ^ ^ [ D;        I.[ ^ ^ ^ ^ ^ j#p==]5$y+o/C!A.p/q/;@_+;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@@@8#r/s/t/$@1+_%f*u/v/w/@@[%M$w%;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@_+x/0)J!y/z/N@A/;.1 ^ ^.^ ^ ^ 1 ! .                           + $ B/4 ^ ^ ^ ^ ^ ^ ^ ^ ]+Z~U$+                           ",
+"        @.[ ^ ^ ^ 1 [ <@          + ,*1 ^ ^ ^ 1 C/+            ~4 ^ ^ ^ ^ J '       []J [ ^ ^ ^ ^ ^ n+D/E/r$C&F/0=G/H/;%C$;@r$;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@k+;@[%l+I/J/K/L/M/[;L$C$a&_+w%V@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@V@N/O/$.P/t$q+Q/R/B 1=c+^ ^ ^ 1 d +~                          + % $%[ ^ ^ ^ ^ ^ ^ ^ ^ [ 1 P*/.                          ",
+"        z{1 ^ ^ ^ ^ l;-           + W$1 ^ ^ ^ 1 (/+           x{[ ^ ^ ^ ^ >#.     $ S/^ ^ ^ ^.c+g ^.!;F]T/v&U/p@;!V/r+;@@@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@5$1$J#k+B$B$W* #;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@<%k+W/X/0+Y/J#D=Z/ )A&J+^ ^ ^ 1 [ S/$ +                       . &>1 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 8 n$w . . `]}]! t-e +       ",
+"        K 1 ^ ^ ^ 1 B/+           @ 4 1 ^ ^ ^ F~{ +           i*[ ^ ^ ^ ^ $+.     $ >*^ ^ ^ 1=T&L@T&`/ (5&.(+(p=@(x%($;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@5$@@@@x+J# ##(B$;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@r$J#C&$(t.%(F#3#&(*(k ^ ^ ^ ^ ^ [ >*. +                       + ! ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 4 H^h#e~.$4 4 [ =(+       ",
+"      C+J [ ^ ^ ^ ^ 1]+       + . -([ 1 ^ [ [ B@. +       + A@.$^ ^ ^ ^ 1 D .     =#C ^ ^ ^ 1=n+~@E+;(4^Y#>(&;~=,(K.;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@[&Q#y+n@5&[% #B$;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@L$C$Q#'(w;N.)(@@2%!(l ^ ^ ^ ^ ^ ^ ]+~(+                       C+a ^ ^ ^ ^ [ {(o![ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 4 l;[]+       ",
+"      ( 0{[ ^ ^ ^ 1 .~+       + . s.4 1 ^ 1 4 :@+         + s ^ ^ ^ ^ ^ ).+ +     (@1 ^ ^ ^ ^ :*[+~.](9#|#^(O _>/(@@ #;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@k+<%V@((_(:(<([(}(5$r+@@5$n@@@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@X%V+w-/]|(F.1(b]R-2(3(J+^ ^ ^ ^ ^ ^ a,+                       -([ ^ ^ ^ ^ 4 I+y.Q+.$^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 [ 4(. +       ",
+"        w))*^ ^ ^ 1 ]+z@. +   + $ `]6.5(: [ j*o$          . M;^ ^ ^ ^ [ 6{        C@[ ^ ^ ^ ^ b#Z+6(7(T/8(9(G=0([%k+k+;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@1%1%a(b(1+E.!;E.P ,^c(d(l+1$T/r+m@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@k+e(Z+A~f(V@g(v@[@^ ^ ^ ^ ^ ^ _ .                   + $ i*[ ^ ^ ^ ^ > ,     c.h(4 [ ^ ^ ^ ^ ^ ^ ^ ^ z.-           ",
+"        . 6{^ 1 ^ ^ [ > I +   + + . + + + C+D@+           a'(>^ ^ ^ ^ 4 Q+      s-)*1 ^ ^ ^ b#l l i(0&j(k(l(;.m(X%@@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;%n(o(p(m^%@l=a.5{0+g*q(r(($_+k+;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@s(Z$J!t({&~$u([+^ ^ ^ ^ ^ 1 ).A@                  . ' 8 [ ^ ^ ^ ^ B/+     + % E~8 1 ^ ^ ^ ^ ^ 1 1 z@+           ",
+"        . =+5 [ ^ ^ ^ 1 C@w                               I 4 ^ ^ ^ ^ [ o$    . D@^ ^ ^ ^ ^ 1=n+Z+v(5$V@w(1 x(c)C$t+<%;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@y(z(H-v.q@A(B(l{Z*C(#%c#D(2#V+k+ #;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@E(F(A.G(H@6@J)a@^ ^ ^ ^ ^ 1 [ <]                  + a,1 ^ ^ ^ ^ ^ n^$         .  ~>*[ ^ ^ ^ ^ 4 d.=.+           ",
+"        . + Q+[ ^ ^ ^ ^ 1 a,+ + + + +               + + + z{[ ^ ^ ^ ^ (.$     . n*^ ^ ^ ^ ^ g G H(I([%2,J(+=K(k+X%;@W*;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@L(E]~=}=M(N(O(P(Q(R(+=A&w!S(x- #;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@l+T(*@U(y~m@V(T#^ ^ ^ ^ ^ ^ 1 4(+             + + . >#1 ^ ^ ^ 1 C p*+         + + -+g~^ 1 ^ ^ 4 y{.             ",
+"            a'#+^ ^ ^ ^ ^ ]+W(,*D@-+$ +           . . d~~^8 [ ^ ^ ^ ^ z{$     + k;^ ^ ^ ^ ^ ^ c+X(O(V+Y(Z(k~`(;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@ _a.p=._+_N@Q@3#y+@_'.l ~.#_<%W*;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@9#$_}=%_&_W'*_=_^ ^ ^ ^ ^ ^ ^ *+. +       + $ e x{K ]+^ ^ ^ ^ [ I^                . E@4 [ ^ 1 K {               ",
+"            + 9{]+1 ^ ^ ^ ^ 1 1 1 )*>#4(# + + + + !.R.C 1 1 1 ^ ^ 1 1 6^.     a'2 ^ ^ ^ ^ ^ ^.~@-_@@@@;_G=Q,>_;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@,_=-6#0@;-m@K.<%@@'_)_f ^!!_5$k+;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@Q@~_u@Y {_h'3#]_^ ^ ^ ^ ^ ^ ^ 0{$ +   + A@L (.a 1 1 1 ^ ^ ^ ^ 4 L*                + `]5 1 1 1 ;#.               ",
+"                n$^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 4 +.o!L*.~4 [ 1 ^ ^ ^ ^ ^ [ f~{ .     c.[ ^ ^ ^ ^ ^ c+0+^_;@6@/_*@(_U);@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@__:*2.:_]-{*<%n@(+<_[_M l }_J#5$;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@X%;>|_x&1_l+q+2_^ ^ ^ ^ ^ ^ ^ )*=+.   + ,{1 ^ ^ ^ ^ ^ ^ ^ ^ ^ [ #                      ^1 4 #+. .               ",
+"                - 5%1 1 ^ ^ ^ ^ ^ ^ ^ ^ 1 1 1 ^ 1 1 1 ^ ^ ^ ^ 1 1 [ B{+ +     6.1 ^ ^ ^ ^ ^ g 6#3_y+c)4_k=5_k+;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@6_Y@c$F+J-J#V@r#G&7_8_u.'.9_R$5$m@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@J#b]0_F.a_Y#6@b_Z+&%n+1=^ ^ ^ 1 /.+   + y.0{1 1 [ ^ ^ ^ ^ ^ ^ 4 x{                  + ] [ [ c + +               ",
+"              + . 0'4 [ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ [ I^F^w         c_1 ^ ^ ^ ^ ^ ^&d_e_;%f_g_;.h_@@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@1^i_+#<*j_V!k_l_m_n_6+:*!^o_y+L.;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@@@V+p_N+q_C&r$r_s_Q%E.Y;^ ^ ^ 1 b +   + . c.'@K@[ 1 ^ ^ ^ ^ ^ [ ..                    ' (.4(.                   ",
+"                + + t_R.Y~[ [ 1 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 1 5>y{% + +         ,*1 ^ ^ ^ ^ ^ g [*u_r#v_w_))x_6@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@1%y_h;F=l(F.z_A_5;Q%p@E+B_R-J#V+;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@@@W*C_e.D_E_J#F_m>6+g 1=^ ^ ^ 1 L +     + + + C+= 2 1 1 1 ^ ^ 1 4 # .                     + +                   ",
+"                    $ + U$;#5(W(4 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ [ 0{H { $ $             >{^ ^ ^ ^ ^ ^ T&G_x@q&H_J!J,I__+;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@@@J_K_c,Z+Z+w;y |=:*(-L_M_3#@@W';@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@ #W*N_6>B'O_z+)#.]0=Y&b#^ ^ ^ 1 m]+           . . a'H -.4 ^ ^ ^ ^ $+$                                           ",
+"                    +   +       - V$R{7{]+[ 1 1 [ [ O*Q*-++                   I.[ ^ ^ ^ ^ ^ c+P_r+Y#Q_^&R_S_$;;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@<%y+3,T_U_6+P&'.2.V_W_X_ #V@@@m@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@k+Q@Y_Z_f `_Q@5$ :2.[@^ ^ ^ ^ ^ >{+                   + n/< 4 [ 1 7{=.                                          ",
+"                                  + . $ I z@|]).l;L*-+. $ +                   W$[ ^ ^ ^ ^ ^ T&q%y+;@.:v.+:e{@@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@C$k+i>@:#:$:t,%:&:M&r+@@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@<%@@H$,~1 *:($B$=:+=u.^.^ ^ ^ 1 .~+                   + . % 9 s.K ) a'                                          ",
+"                                              -+=+                            : 1 ^ ^ ^ ^ ^ ^.-:@@6&;:v.>:,:W*;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@K#K#k+v&a&5$k+@@L._+5&5$;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@B$w%B#':1 *:($<%):O 1 J+^ ^ ^ ^ :                               +                                               ",
+"                                                                              : ^ ^ ^ ^ ^ ^ ^.!:($3+~:.-{:k%]#;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@5$O@y+[%@@k+_+v&]=@@($$;;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@J#$;]:^:l /:($J#(:O. ]c#^ ^ ^ ^ :                                                                               ",
+"                                                                              : ^ ^ ^ ^ ^ ^ L@_:W*_+::e$<:[:;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@V+n@J#<%}:J#H@H@_#L.5&k+;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@O@ #|:1:g 2:[%_+3:c#^ ^.^ ^ ^ ^ :                                                                               ",
+"                                                                              : ^ ^ ^ ^ ^ ^ L@_:W*_+::e$<:4:;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@<%**3#s+5:T{6:@@K.k+Q# #;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@O@ #|:1:f 7:_# #3:c#^ ^.^ ^ ^ ^ :                                                                               ",
+"                                                                              : ^ ^ ^ ^ ^ ^ L@_:W*_+::e$<:4:;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@_#m@L.8:9:0:a:b:c:b] #;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@O@ #|:1:p=d:6$ #3:c#^ ^.^ ^ ^ ^ :                                                                               ",
+"                                                                              : ^ ^ ^ ^ ^ ^ L@e:W*_+z=e$<:[:;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@ #;@;@;@;@_+n@f:g:6#`%6#p=h:i:V+ # #O@ #;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@O@W*B#1:v#j:@@y+&~&@^ c+^ ^ ^ ^ :                                                                               ",
+"                                                                              : ^ ^ ^ ^ ^ ^ m-k:O-(+l:!;m:n:W*;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@k+n@<%_+5$6@X'o:1 ^ ^ ^ u.E.p:q:{&w-K.6&;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@m@+@r:':R s:B$[%t:Y;L@Y&^ ^ ^ ^ | +                                                                             ",
+"                                                                              : 1 ^ ^ ^ ^ ^ T&u:Y#V+v:w#w:<-J#;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@<%K.<%x:*=y:z:J+^ ^ ^ n+Y;+*A:B:8]4]1$;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@w%r#C:D:}=E:B$@@F:c#&@n+^ ^ ^ 1 I.+                               +     +                                       ",
+"                                      + $ $ h+o$.                             >{[ ^ ^ ^ ^ ^ L@G:[%x+H:k~_;Y_V@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@{*m@|#I:J:E%p$g ^ ^ ^ X&J^Y;u.K:L:z+r$;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@@@s+M:J!F+N:])D-O:+*c#L@^ ^ ^ ^ >{                    . w Q{I.6{N;7 . $ $                                       ",
+"                            + + + +   C+t_m 1 5 Z~(/+ + +                     >{[ ^ ^ ^ ^ ^ Y;P:Q:Y{R:H(}'S:m@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@@@ #;@;@m@<%Q^T:U:,@[.&@D%c+^ Y;d$R ~@l S.V:W:3# # #B$n@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@<%S%X:p@B*Y:O@Z:`:+*b#c+^ ^ ^ ^ >{              + + w 9 (.[ 1 1 1 )*k;t_'=. + + +   +                           ",
+"                          + $ % n]9 ~^> [ 1 ^ ^ ^ )*{(D@=.+                   S/1 ^ ^ ^ ^ ^ e$m> <z+.<I-u#+<B$;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@ #n@<%5&<%@<#<)/J+^ ^ ^ Y&w#$<A&b#G v.g n+n+%<&<a&j(6&**;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@W;3#*<0==<-<r$({;<J^L@1=^ ^ ^ 1 =(.           + . 6^..1 ^ ^ ^ ^ ^ ^ ^ 4 [ >*$+;#( $ .                           ",
+"                    . + + a'/>r j*1 1 1 1 1 ^ ^ ^ 1 1 1 0{n^=++ + + +         D;1 ^ ^ ^ ^ ^ i@<^><[&x@,<E+'<O@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@<%K.@@f^)<!<C(T&^ ^ ^ n+p@~<{<;+;+G J+l &@Z+]<^</<(#8>;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@3#r+(<*._<L^[&:<6+l L@T&^ ^ ^ ^ h~+     + + + /&B/]+[ ^ ^ ^ ^ ^ ^ ^ ^ 1 1 [ 1 1 7{>{D;A@+ .                     ",
+"                    $ I +$5>4 [ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ [ ).5(h+. $         c 1 ^ ^ ^ ^ ^ g V{<<y+Q#[<S.}<_+;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@C$@@M&|<1<2<p$T&^ ^ ^ 6+3<4<5<6<7<~@n++*f/T&u.8<b/7@6@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@V@S-9<~.0<t+e,a<J+b#1=^.^ ^ ^ 1 p*.   + . j;i*a 4 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ [ ]+d 5($ .                   ",
+"                  t_: 1 1 1 1 1 ^ ^ ^ ^ ^ 1 1 [ 1 1 ^ ^ ^ 1 1 1 1 b<b'        7 K'^ ^ ^ ^ ^ f S.c<J#b]d<e.e<X#s+w%x-;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@@@k+;@;@m@<%T+f<g<6#j#T&h<+=T&6#K&i<n@5&j<A*k<#%%@f f 1 X l<m<V@W*@@7@r$;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@a&m&n<Z+o<1%x-p<^.c+Y;^.^ ^ ^ $%6 +   . I.1 [ ^ 1 ^ ^ ^ ^ 1 1 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 1 1 1 ;#.                   ",
+"                '=[ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ [ [ .$4 1 ^ ^ ^ ^ ^ ^ ^ [ *         $ F~^ ^ ^ ^ ^ ^.s;P!Q=p;q<r<s<t<:]L.5:]#;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@n@V@{*y+@<u<v<w#^ ^ ^ T&<,k=w<x<L.Q@C$C$y<z<A<f G L@T&E.u.B<C<s+A%3+F*;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@<%D<B=8_E<W'F<G/^ ^ ^ ^ ^ ^ ^ 5%$ +   h+[ 1 ^ ^ ^ ^ ^ ^ ^ 1 t-A{> ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 >*U$                  ",
+"            . . o!1 ^ ^ ^ ^ ^ 1 1 [ [ 1 Y~l*q =+c_W$[ 1 1 ^ ^ ^ ^ ^ 8 A@.     .  ^^ ^ ^ ^ ^ e$+=G<H<Q@I<_*U#J<}:X%B$r$;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@_+K.m@3{K<K,L<+=^ ^ ^ Y&M<$^N<;%Q@**Q@L.O<P<6;j$s;G J+Y&&@[@Q<R<S<|#m@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@+@T<F.U<V<5&W<X<^ ^ ^ ^ ^ ^ [ M;+ + + 4(1 ^ ^ ^ ^ 1 1 [ 5%) K*+ +~-(H^Y~[ 1 1 1 1 ^ ^ ^ ^ 4 Y<+ +               ",
+"            $ @.C 1 ^ ^ ^ ^ ^ 1 4 4 e~H `]$ . $ . a'!.|]4 ^ ^ ^ ^ ^ ^ h#$     $ n^^ ^ ^ ^ ^ ^ b#'&Z<C$0&`< [.[2%V@n@@@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@3#@@[&+[@[B~T#&%^ ^ ^ Z+#[$[3#[%C$5$r$y+t$J#b-z$j$n+n++*<*b#&@%[&[])V+;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@*!*[=[-[i>R-;[0+^ ^ ^ ^ ^ 1 [ )=  + % N*^ ^ ^ ^ ^ 1 k;q { +       . $ - D@B@0{[ [ ^ ^ ^ ^ 4 O*' +               ",
+"            + |]1 ^ ^ ^ [ [ 1 A{z@>[+ +     +   + + + + ~(M*[ ^ ^ ^ ^ g+$     +  ~1 1 ^ ^ ^ ^ R+#%,[t+C$'[2.)[![N@U+P@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@@@V+;@@@O@Q@~[{[][~@g g h<l Y&f*~#^[L.[%5$;@m@X%@@k+J#(+/[A>([v#d$1 1 g [+_[:[V@V+@@S%r$;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@_+w% #;@d*7-4 <[k+y+[[F.^ ^ ^ ^ ^ 1 4 ~(  + p*4 ^ ^ ^ 1 [ &>+   +                 + % /.z{> [ ^ ^ 1 1 r .               ",
+"            ,{C ^ ^ ^ 1 [ -#h+. $ .                   . $ $+]+^ ^ ^ ^ 4 I]      { M*[ ^ ^ ^ ^.c+~@}[E{n@|[1[p@:>y+V+#(;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@K.{*N@;%2[3[%@^ ^ ^ j#4[E%5[6[L.Q@5&O@Y{w%7[n@;@B$@@V@8[9[0[L@t L@l E.&%a[b[;$2'^-z+;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@X%[$3#c[f+A=d[k+9.e[}=^ ^ ^ ^ ^ 1 5>.   + z@[ ^ ^ ^ [ i#a'                          $ . 1][ ^ ^ ^ ^ ]+P+              ",
+"        . . 7/1 ^ ^ ^ 1 +.o$  +       + . $ . +           /.[ ^ ^ ^ ^ [ p!        ! [ ^ ^ ^ ^.n+1 Z$f[C$^-g[@$h[,:($B$;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@_+K.w%M&i[j[k[[.^ ^ ^ Y;C(l[m[T+<%**Q@k+r+4+n[l+<%O@r#[&o[p[a!q[{@t J+c#&@&%r[s[S<Q^@@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@@@C$;@Y#5[$.t[3+_+u[!;l ^ ^ ^ ^ ^ 1 } +   + e~1 ^ ^ ^ [ p!+           % y.. . . .         { ~ [ [ ^ ^ ^ {(y.+           ",
+"        . I]> [ ^ ^ ^ ^ V$+           + w g#*]w           w K ^ ^ ^ ^ [ f~        )=[ ^ ^ ^ c+1=1 ;.v[L$Q^w[#.x[y[V+]#;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@<%k+x%z[r{B~'.$=^ ^ ^ f A[w/l+5$_+@@r$y+]-B[C[&_x+;@ #[%X#J#D[E[+;L@u.6+c#n+c#F[G[s+V+;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@n@V+L.H[I[6#J[V@[%K[E.g ^ ^ ^ ^ ^ ^ Q{.   7 )*1 ^ ^ ^ 1 o*+           w)i#Z~/>-+.         . :@J 1 ^ ^ ^ 1 H +           ",
+"        $ j ^ ^ ^ ^ [ | y.+       + <]} -.[ 4 $'. +       . ) ^ ^ ^ ^ ^ 1 ;#.     C+K'^ ^ ^ ^ ^ ^ ^.L[M[r+N[O[P[Q[1%V+;@;@;@;@;@;@;@;@;@;@;@;@;@;@ #;%;@X%J#9#i>R[8~b#^ ^ d=[@[+n%S[T[n@_+;@k+_+L.~%U[~=&@V[W[[%_+m@@@O@$;X[a[Y[v#u.1 1 g c#Z[`[3#V+$;0&L.;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@ #r$5& }a@.}+}V@n,[_#%n+^ ^ ^ 1 [ j*-+$ . }]4 ^ ^ ^ ^ 5 6 +       + $ 7/[ ^ ^ t-m e +         * [ ^ ^ ^ ^ d.A@          ",
+"        I )*^ ^ ^ ^ [ b $ +       n^C [ 4 [ [ g~$ +       . A@K@^ ^ ^ ^ ^  ^.     $ B/^ ^ ^ ^ ^ ^ ^ B=@}(+6&#}R $}%}W';@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@K.[$6@N@&}*}l$^ ^ ^ g 8_~==}-}n@5${*@@C$@@;}>},}5;n+2.V['}1%w%]#B$k+5$)}!}0[n+G L@&@f w#!<~}])[&K#7@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@V@y+{}]}0+^}3+5$/}J!~@n+^ ^ ^ ^ [ _@. . . j [ [ ^ ^ ^ l].         + U$7{[ ^ ^ 4 [ (/+         c.m*^ ^ ^ 1 [ z{          ",
+"        * [ ^ ^ 4 4 W(+           >[4 1 ^ ^ ^ $%K*            ! [ ^ ^ ^ ^ d o$    . n/4 1 ^ ^ ^ ^ ^ T&(}]/_}:}<}T.[}v&;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@<%K.w%}}|}1}2}k ^ ^ ^ J+3}4}5}f^3#**@@ #y+I/k:[@=^:&n+$=f 6}7}Y#<%]#r#x%8}9}0}a}a+t u.Z%Y&J+b}c}d}($r$;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@ #x+e}f}0~s[$;p%g}h;l u.^ ^ ^ ^ [ q   + -+C;^ ^ ^ 1 4 s           .  ~^ ^ ^ ^ [ g++           - ).^ ^ ^ 1 4 M;          ",
+"        c'[ ^ a .~L', .           + >#1 ^ ^ ^ [ t_            g#4 ^ ^ ^ ^ [ )=    . =.Y~[ ^ ^ ^ ^ ^ 1 h}i}[%K.j}'!k}^<;@m@;@;@;@;@;@;@;@;@;@ #;@;@;@J#k+}}l}l)s;B .=c+^ b#R V#m}y+s+k+@@r$K#%]n}e.l J+L@T&J+y F.A>o}x+;@ #@@R-5$p}G_S.m-3*+*Y&E.x*)>q}a&k+ #m@m@;@;@;@;@;@;@;@;@;@k+;@;@t+r}s}t}u}|#U)v}F+f*l l ^ ^ ^ ^ -.U$    ;*1 ^ ^ ^ 1 ).K*          . *]^ ^ ^ ^ 4 E~            F^[ ^ ^ ^ ^ 4 D@          ",
+"        =(-.Q i;                  + }]1 ^ ^ ^ 1 i*$           y.0{^ ^ ^ ^ [ r-% .     '@1 ^ ^ ^ ^ ^ [@'!w}Q=<%x}y}f*4/N@W'n@@@;@;@;@;@;@;@;@;%;@_+<%9#}}z}%_^ ^ ^ Y;m%q@s]t]t'w%C$ #k+_+(+A}B}r,J+c+^ ^ ^ ^ ^ ^ ^ C}D}1%3#;@@@O@w%E}F}g*O.n+L@g 1 J+G}H}1%V+$;I}@@;@;@;@;@;@;@;@@@c)($[$G&J}p(K}L}A%*!M}^ ^ ^ ^ ^ ^ ^ 1 z{+   + B@1 ^ ^ ^ 1 q*+           w 5>^ ^ ^ ^ [ <]          + j [ ^ ^ ^ ^ 2 {           ",
+"        w =.. +                   + - l;^ ^ ^ 1 [ #           + p!^ ^ ^ ^ 1 8 '=.   + h+a ^ ^ ^ ^ ^ e$}=N}O}S-P}Q}5;R}S};%V@J#;@;@;@;@;@;@;@;@K.3#k+T}U}V}S ^ ^ ^ e$|{W}X}Y}n@5${*@@C$($Z}`}F+c$E.^ ^ ^ ^ ^ ^ ^ ^ F. |.|e,w%O@5$y+5$+|@|r&&@!;:*&@l ~@K,#|s+8#N@]);@;@;@;@;@;@;@r#;@{&S-$|%|G=&|M&5$*|^,^ ^ ^ ^ ^ ^ ^ C e +   { ; [ ^ ^ ^ 1 =(+           I][ ^ ^ ^ ^ d.y.          a'; 1 ^ ^ ^ ^ * .           ",
+"                                  + . *+[ 1 ^ ^ ^ L'. +       .  ~)*4 ^ ^ ^ ^ 9'$     $ B/^ ^ ^ ^ ^ :*c#k$=|Y{V@-|;|E+>|,|k+;@;@;@;@;@;@;@;@X%[$j(;>'|;{)|B ^ ^ ^ J+!|~|{|T+5&**@@n@t+}&]|Z+B=y J+c+^ ^ ^ ^ ^ ^ ^ y m-A*$|8#<%;@V+8#^|8/8</|(|t E.&+R+J+D:_|:|$;W*;@;@;@;@;@;@;@7@r$f^<|[|u@}|||x+q/1|E]^.^ ^ ^ ^ ^ 4 j $ . $ d~[ 1 ^ ^ ^ )*c.+           Y<]+^ ^ ^ ^ Q .         $ j;^ ^ ^ ^ ^ 1 &>.           ",
+"                                    . 6^[ 1 ^ ^ ^ m*{         + . r-1 ^ ^ ^ ^ P*$     + 6^[ ^ ^ ^ ^ ^ c+[.Z*2|y+F#3|;!J!4|q&k+;@m@5$k+;@;@;@5$6@G&5|o&q@k .=Y;e$~@+*n}9.|#7@@@@@n@^-%]6|#.&@1=L@T&e$:*&%1 T&R T&^.c+$=^&7|8|5&w%J#@@;%V@9|0|H-k %@!;Y&:*x*]}a|K. #W*O@m@ #;@;@;@ #**{&b|f*s]c|a&f@1@J!X ^ ^ ^ ^ ^ ^ ]+6^+ . . n*1 1 ^ ^ 1 #+. +         + : [ ^ ^ ^ 1 ;#+         . B@^ ^ ^ ^ ^ C;- +           ",
+"                                      a'z.1 ^ ^ ^ [ <@+           k*[ ^ ^ ^ ^ [ g#      + J][ ^ ^ ^ ^ ^ ^ ^ d|e|[&f|W{p=g|h|Q@t+V@i|r$@@C$_+(+}}j|T>^ ^ ^ c+m%))U#k|l|w%5&@@k+3#r+m|S^p$u.Y&c+^.g },<#[_n|`{~.~@l ^ ^ ^ ^ o|p|q|y+;@O@O@($r|i+s|F.:*L@g f J+:,t|5&k+A%u|@@;@;@;@@@_+v|w|x|y|z|v&|*A|l f ^ ^ ^ ^ ^ 1 J].   + y.r.^ ^ ^ 1 [ 3 $ +       . s-1 ^ ^ ^ [ 7{{           w : ^ ^ ^ 1 [ ~^$ +           ",
+"                                      + H+^ ^ ^ ^ 1 Z~+           n]K'^ ^ ^ ^ 1 * +       <][ ^ ^ ^ ^ ^ ^ ^ k B|H@C|m(D|O E|F|3#q& #n@[$V@@@G|H|._I|^ ^ ^ ^ B~r>J|K|$;5$[$@@C$@@L|M|J!S E.^.^.^ l p$N|O|[%P|j_k J%c+^ ^ ^ q@Q|}~|#@@J#5$r+1$k_R|C,P&Z+:*&@Y&Z+j[S|T|x@Q^B$;@;@;@]=U|V|5{W|X|1$C$Q[;][@&@^ ^ ^ ^ 1 1 {++     I 1 ^ ^ ^ 1 a Y|+ +       + C/^ ^ ^ ^ [ r             <][ ^ ^ ^ ^ [ I++ +           ",
+"                                      + # 1 ^ ^ ^ [ )*6           . q*^ ^ ^ ^ [ Y~-+.     $ |]^ ^ ^ ^ ^ ^ ^ $$Z|`|S%5&p&;!e% 1q+r#J#k+[$w%E'.1f}+12.^ ^ ^ b#!)@1#1V+C$[$@@n@r+$1%1Z+A&A&1=c+c+1 *.&1*1X%k+Q@=1-1J!b#^ ^ c+3*f _*W@2%<%;@k+c)O<;1>1i$J^G E.J^R+b#,1'18]@@W*;@;@;@/*)1}!N}!1**V+~1,^;!k Y;^ ^ ^ ^ ]+b<$ .   + L*1 ^ ^ ^ 1 A{.           .  .1 ^ ^ ^ [ Q{            = 1 ^ ^ ^ ^ 8 7               ",
+"                                      + . c'1 ^ ^ ^ 1 )=+         . b ^ ^ ^ ^ [ 1 {1+       =#l;1 ^ ^ ^ ^ ^ &@k ]1^1i>/1(1B _1:1_#[%1$;%y~<1Q![@i@[1d=i@l ;!}1+,6@^% #@@n@|111212.R+T&L@g L@x*[ 3141@@R-@@a&y+t!r%[+'.Y&^.1=D%v.]]511%n@J#@@6@a&617181[.l$!;T&m-}=91015&3#;@]){*a1b1,@e!c1k+d1|_R F.l L@^ ^ ^ 1 l;>[. +   + I^1 ^ ^ ^ 1 %>+           -+J ^ ^ ^ ^ t--+        + . h(1 ^ ^ ^ ^ #++               ",
+"                                          h#4 1 ^ ^ ^ C@. +       . y.)*^ ^ ^ ^ ^ 4(.       + '@4 ^ ^ ^ ^ ^ ^ ^.6#e1r+C$f1g1u@h1i1X#6@j1k1l1c+^ ^ ^ Z+m1^,n1o1w%[$@@[%l+C$p1q1r,E.T&^ ^.c+[++#r1s1r#;@;@;@;@_+t+t1u14 m-l ^ ^ ^ ^ v1w1x1L.;@O@O@@@y1z1A1[.G :*g n+J+*-B1y+s$Y#C1J'v;D1E1x+l+N$,@^ ^ ^ ^ ^ ^ ^ ^ 9'+       , 4 1 ^ ^ ^ 1 /&+           V$4 ^ ^ ^ ^ *+$         . I 4 [ ^ ^ ^ 1 t_.               ",
+"                                . + . . s-E~[ ^ ^ ^ ^ ]+Y|        . %>^ ^ ^ ^ 1 M*6 +       + =+i#1 1 ^ ^ ^ Y;E.R+F1G1|#1%5)']O H1I1J1(%n%k]^ ^ ^ ^ K1L1M1F<@@V@[$;@L$k+N1O1p$S A&^.^.^ 1 F.P1Q1@@@@;@;@;@V+w%C$($R1S1`%$.^ ^ ^ c+c#T1U1e,k+J#<%;%N&e|V1u W1Z+:*Y&R+Z+*-X16&Y1//B~Z1`1y+|#a- 2Q%^ ^ ^ ^ ^ ^ 1 i#{ +       U$: 1 ^ ^ ^ 1 _ . .         *+[ [ [ 1 [ V$.         . n$[ 1 ^ ^ [ [ ' .               ",
+"                              + $ n]N;{()*4 4 1 ^ ^ ^ [ *]        n]$%^ ^ ^ ^ 4 k*          + $ n!4 1 ^ ^ ^ 1=g &@A&.2+26@1%4'@2'!9=#2v#l1m%c+^ ^ ^ $2%2L^9#_+C$@@P@y+&2*22.J+E.1=g g 1 B'=2-2@@5~ #;@;@;@V@@@n@3#[%;2>2r,^ ^ ^ c+w#[@&',22%Q@;@@@o{N&q:'2)2=,:*'&;+Y&u.!2~2{2;.]2^2Y#<%/2k{l Z+^ ^ ^ ^ ^ ^ 8 0'          + F^1 ^ ^ ^ 1 ]+F^. +       I |+#+d [ .$C+.         . c'^ ^ ^ ^ [ I^$ +               ",
+"                        . . ( 6.g~.$1 1 1 1 1 ^ ^ ^ ^ [ 5>. . + . z{[ ^ ^ ^ ^ f~-+            + $ *+1 ^ ^ ^ ^.c+T&L@[@w<(29#{&_2;<Y=[.~@i@&%J+J+k (=:2[&6@5$n@<% #Q=<2[2[ c#T&^.c+n+F.`%}2L~V+m@ #W*;@;@;@;@<% #;@V@[%|212J%0+Y&b#1=&%v.*(22O-L.J#@@k+5$u]3242S.#%B=&%n+Z%N s]52C1R-r+6272v.n+T&^ ^ ^ ^ 1 [ >{.             w #+[ ^ ^ ^ 1 z.=++       + +   C+n/Y<+ +         ;,a ^ ^ ^ ^ [ %>.                 ",
+"                        6^,*t-[ 4 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 4 :@$ $ ~(j*[ ^ ^ ^ ^ ) +               + -+y&^ ^ ^ ^ ^ ^ ^ Z%h;82616@9202B~b#^ ^ c+Z%$=h}a2;>w%[$X%_+y+t+b2c2'!!;J+^ ^.c+^!+#d2]'q&;@;@;@;@;@;@;@;@;@;@;@;@_+G&e2$*f$m-&@^ ^ ^ ^.*(f2P#($;@O@@@5$g2h2]+x*1=c+c+n+R+F.i2Q$@@j2k2g ^ ^ ^ ^ ^ ^ ^ [ F~6 +           + $ i;8 1 ^ ^ ^ 1 >{+               . .             b=4 ^ ^ ^ ^ 4 _/                  ",
+"                  7 L'< ^ 1 1 ^ ^ ^ ^ ^ ^ ^ ^ 1 [ ^ ^ ^ 1 l*$ y.! ^ 1 ^ ^ 1 ..  +                   E@> 1 ^ ^ ^ ^ ^ e$T&R l2m2z=n2m%L@^ ^ ^ a@H=o2d@k+{&K.;@'+[%E}p2T#=-3*L@^.^ ^&,@q2y;V+m@;@;@;@;@;@;@;@;@;@;@;@y+w%L$@@r2s2S.N+^ ^ ^ 1=c#t2u2G&y+J#k+;%d}v2w2Q![ i@J+A&<*T&'.'|x2y2Z+c+^ ^ ^ ^ ^ ^ ^ > '=                  + >,1 ^ ^ ^ 1 J d~. . .         +           . + o!4 ^ ^ ^ ^ : .                   ",
+"                  9{4 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ a ]+^ ^ ^ ^ .$(@(>4 ^ ^ ^ ^ [ />                      + ) 4 ^ ^ ^ ^ ^ u.$=O o&B(T.%@~@g ^ ^ ^ A.z2l+1%k+_+;@;%|#A2|'F.Y;:*J+g g l B'B2C2J#Q#W*;@;@;@;@;@;@;@;@;@;@;@5$[%n@V@[%D2E25;^ ^ ^ c+w#c#Z(F2q/5$;@@@Q=1$]/G2t2c#J+f n+J+A&s_H2w;u.c+^ ^ ^ ^ ^ ^ [ I+$                   + 9{j*^ ^ ^ 1 4 )*H^z@b'.                   6 L*K'[ ^ ^ ^ ^ ,*+                   ",
+"                  . r-1 ^ ^ ^ ^ ^ 1 1 [ [ A{Q*h+K 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ >#+                       + . ! [ 1 ^ ^ ^ ^ ^.e$e$c+c+^.^ f 3*6#I2F=E2J2V@8>;$y+5&K2L2&@c#T&^.^ f 2.x&i&M2W*;@;@ #;@;@;@;@;@;@;@;@;@;@;@;@@@;@;@<%k+N2O2u@~.&@b#c+c+^.a=p_P2L.V+<%Q2R2S2P h;p=c#^.^.R+Y;1=c+c+^ ^ ^ ^ ^ ^ [ 7/                        . H+4 1 ^ ^ ^ ^ ^ ^ ^ W(z{<@( . + . $ A@Q*$%1 ^ ^ ^ ^ ^ ^ <]+                   ",
+"                    =(1 ^ ^ ^ ^ ^ 1 ; z{{+y.$ + C/^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 0'.                       + $ { W(1 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ E.m-j^T2k$O U2V2W2v&l+)}E;[,B=b#^ ^ c+^!J!X2||q&;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@w%_+X#Y2Z2[.m-&@^ ^ ^ b#J,`22%[% 3.3+3;.@3#3~.T&c+^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ _ a'                      + . A@5 1 ^ ^ ^ ^ ^ ^ ^ [ [ [ M*r c_;,-(5>[ ^ ^ ^ ^ ^ ^ ^ (>a'+                   ",
+"                    -+l;4 [ [ l;c=/&{         $ o$l;[ 1 ^ ^ ^ ^ ^ ^ ^ [ i*                              + +~g+4 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ O $3%3&3*3m>F==3-3i};3>3+*J&$=b#^ e$^&0+,3Y_H@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@r+w%_+@@'3u(v;~.^ ^ ^ b#u.B')3!3~3h;p=S&{3]3E#p$x&v.^ ^ ^ ^ ^ ^ ^ ^ ^ [ g+C++                           + I+[ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ a ^ ^ ^ ^ ^ ^ ^ 4 [ [ M;                      ",
+"                    . q*)*I.s a'. $ . +       + . Z][ ^ ^ ^ ^ ^ ^ ^ ^ 1 w)                              + $ []5 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ p@^3y(H@5&/3S'a=o+(3_3F=Y&E.J+g g l /=:3<3J#<%#(;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@5$L$w%<%9#[3}36+c+^.c+b#Z+Z+N+J!(-<#&{|3[%132333*.l g ^ ^ ^ ^ ^ ^ ^ ^ -.A@. .                           + . r.^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 4 h(/>.                       ",
+"                      o$+~.                       q ]+^ ^ ^ ^ 4 4 2 ,*j;$                                   + b'O*4 1 ^ ^ ^ ^ ^ ^ ^ A&6+43,]|1@@x@5363k#1 l T&^.^ l 0+#.73+} #;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@<%@@8393v~N+l b#^ ^ ^ 1 03a3p%t+l+b3c3=^^ ^ ^ ^ ^ ^ ^ ^ ^ 4 M*/..                                   s-9 -#$%[ 4 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 4 [ 4 {(0'.                           ",
+"                        . +                       . d.1 ^ ^ l;Z]g#6 . $ $                                   + $ =#; 1 ^ ^ ^ ^ ^ ^ ^ d3'&k#e3f3Q=N@3%g3B;&%g ^.^ ^ [+f*D#p-r+;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@n@_+x+h3i3`%R &@^ ^ ^ Y&h;j3q#Y{k3l3t.&@^ ^ ^ ^ ^ ^ ^ ^ ^ ; m3$ .                                   + . . 6 c 9'-.^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ [ c'/&. . +                           ",
+"                                                  . +$]+b+)=A@                                                  . I 2 4 1 ^ ^ ^ ^ ^ E.+=j#:*n3o3p3q3r3s3v.D%^ c+B /=t3D$x-;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@@@_+w%[%[%u3v3d+;!^ ^ ^ L@Z+'!w3x3;&0=f g ^ ^ ^ ^ ^ ^ ^ [ z.# .                                                   y.h+L i*4 [ 4 4 4 [ [ R.E@$                                   ",
+"                                                  + =+' + . +                                     + +           + $ h+| 1 ^ ^ ^ ^ ^ g |=E.j#t.6+}.S.E.e$&%e$g [.u#y3z3[%J##(;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@5$L$w%<%[%Y}A3[@:*v.c+^.c#6+'!6#E+P&u.n+^ ^ ^ ^ ^ ^ ^ b+o$$ . +       + +   + +                                 + . + + o$n/! > [ b<{+. . +                                   ",
+"                                                                                              $ . $ - !./&$ +       . `]k;[ 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ e$*.n%B3u&;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@ #;$L.C3D33}Y.&%g ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 4 J]- .     $ P+= g#(/- $ . $ +                                           + . e $                                           ",
+"                                                                              +   + + + + n]E@t_l]~ J [ 1 >,K*      + + U$H+[ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ J+~.E3F33#;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@@@s+L$<%q;G3H3E.^.^ ^ ^ ^ ^ ^ ^ ^ ^ 1 ^ 1 J $++ + .     x{4 1 1 [ J W(I.M;c_!., w + +                                   + . +                                           ",
+"                                                                              . o$b''*B{< K'4 ^ ^ ^ ^ ^ [ K $           . $ F^l;^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ g I3J3@/K3;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@;@L.y+|1L3M3N3 )w#T&^ ^ ^ ^ ^ ^ ^ ^ ^ [ 4 Y~0'            / 4 ^ ^ ^ ^ ^ ^ ^ ^ 4 [ (>C@K*+                                                                                 ",
+"                                                                              . l*1 1 1 1 [ 1 ^ ^ ^ ^ 1 > I]+           + . + ~(C@1 1 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ b#w;F.O3P3Q3;>($X%$;;@k+V+W*;@O@m@;@;@W*@@O@O@O@<%5$;@;@;@O@O@B$C$;@;@@@O@J#r+R3S3T3a#6#[+1 1=^.^ ^ ^ ^ ^ ^ ^ 1 ^ 1 i*p*+             a'8{^ 1 ^ ^ ^ ^ ^ ^ 1 1 1 1 l*. +                                                                               ",
+"                                                                              $']+^ ^ ^ ^ ^ ^ ^ ^ ^ 1 [ n^$ +                   a'S/K'[ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ n+A(U3V3W3X3Y3_+k+ #R$V@]=1%X%W*W* # # # # #V+y+W* # # #;@m@5&Z3`3 4.4U2v~}=g ^.^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 l;|+y.+               . +~: [ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 ]+{1$ .                                                                             ",
+"                                                                              a'Q*l;1 1 1 ^ ^ ^ ^ ^ 1 D~y..                       + I N*4 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ e$H-^&+*:$6*+4@4#4$4%4&4d@($y+{&@@;@;@;@5&3#k+V+[%Y#]-*4=4j%-4;4}'6+Z+m%J^Z+L@1=^ ^ ^ ^ ^ ^ ^ ^ [ [ 4 J];,. +                 + + <]).1 1 1 1 ^ ^ ^ ^ ^ ^ 1 d ,{                                                                              ",
+"                                                                              . $ # K [ [ ^ ^ ^ ^ ^ 1 h++                           . . n/0{^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ J+D%g g ~@P%d$[ u ~.|,>4k/,4'4)4!4~4~4~4{4 4]4^40_/4(4)%J!/=L@J+G g Y;u.:*n+g c+^ ^ ^ ^ ^ ^ ^ 1 4 5%V$$ $ +                       . Q{q*-.K'4 ^ ^ ^ ^ ^ ^ ^ 1 i#[]                                                                            ",
+"                                                                              +   + a'z@+.1 1 ^ ^ ^ ^ h~+                             + + o$n$+.1 1 ^ ^ ^ ^ ^ ^ ^ ^ ^.c+1=b#T&g v.n+f 1 1 L@1 v.M :*L@L@L@1 L@L@l R+Y&&@u.1 R+T&^.g ^.^ c+e$T&c+^.^ ^ ^ 1 1 1 [ +.n$a'+   +                         + + + + , w)3 8{> 1 ^ ^ ^ ^ 1 C@w +                                                                         ",
+"                                                                                    + $ ;*4 1 ^ ^ ^ 1 b<+                                   . - H+l;^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 [ m*Y<- . +                                           $ . H [ ^ ^ ^ ^ ^ 1 9'.                                                                         ",
+"                                                                                        $ d.[ ^ ^ ^ 1 C;-                                       + `]x{7{[ 1 1 [ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 [ 1 1 7{3 U$      + + + .                                       + $ B{[ 1 ^ ^ ^ ^ C F^. +                                                                     ",
+"                                                                                        + & 1 ^ ^ ^ 1 [ =(                                          $ a's k;J [ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 d ! g#. . +       + a'j;-++                                     + . { W(1 ^ ^ ^ 1 4 t-@ +                                                                     ",
+"                                                                                          b'1 ^ ^ ^ ^ 1 _ $ +                       + n]j +~. .           + 9{1]r-8 [ [ [ 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 [ [ 8 r-4(+~+           + . @ C@1 5 l]6^$ . . .                               + (/+.[ 1 ^ ^ ^ 1 ~ a'$ +                                                                 ",
+"                                                                                        + $ | ^ ^ ^ ^ ^ $%( +                       + R{4 ; q $             $ . $ p*k*e~m*1 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 7{|]-(p*. $ . .           + s 7{1 1 ^ 1 [ b+I+n].                               + $ 0'8 1 ^ ^ ^ 1 [ *+$ +                                                                 ",
+"                                                              + . k*[]$ .                 . ) [ 1 ^ ^ ^ 1 `$+                   + $ q a ^ ^ q*$                         { b'b=Z~W(]+1 [ [ 4 [ 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ [ [ [ 1 [ C ~ Z~) i;{                         z@J ^ ^ ^ ^ ^ ^ ^ ^ $%9'# . . +                           + L'1 ^ ^ ^ ^ ^ 4 />+                                                                 ",
+"                                                              + j;4 $%&>$                 $ >[4 1 ^ ^ ^ 1  ^+                   . s-2 [ ^ ^ >*.                             . . . - '=g#Q**]_@N*N*N*N*N*N*N*N*N*N*_@*]t_g#'=- . . . .                           *][ 1 ^ ^ ^ ^ ^ ^ ^ [ 4 a N*H a'                          + % J]^ ^ ^ ^ ^ 1 /.+                                                                 ",
+"                                                              . !.^ ^ [ m]{ $       + $ +   + D~[ ^ ^ ^ 1 C;a'+ + + + + + ( - - 6 * ^ ^ ^ ^ [ -                                                                                                                 I^^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ [ 2 5(=#. .                       A@i#1 ^ ^ ^ 1 /.+                                                                 ",
+"                                                              . ' 8 ^ [ [ : =(] ] ] b z{M;M;M;i*1 ^ ^ ^ 1 [ ~^_ ~ ~ ~ ~ ~ K@1 ^ 1 [ ^ ^ ^ ^ 4  ~                                                                                                              + A{^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 4 [ [ [ b<;*U$                    + *+1 ^ ^ ^ .$`]                                                                  ",
+"                                                                  m*1 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 s                                                                                                               w ^ ^ ^ ^ 1 r.;#c'K'4 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 2 Q*[]. . $             W([ ^ ^ ^ j*. +                                                                 ",
+"                                                                  b<[ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 p!                              +               >[ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~i;Y|                                y.^ ^ ^ ^ 1 ! . . ~(9'Y~^ ^ ^ ^ ^ ^ ^ ^ ^ [ 1 > J]0'%           + m*1 ^ ^ ^ : . +                                                                 ",
+"                                                                  o][ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ [ R.                          + $ I]y&l;K'K'K'K'K'C ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ [ > ;*$                             :@[ ^ ^ ^ ^ m]        ( N; .4 4 4 ^ ^ ^ ^ ^ ^ ^ ^ 4 r.o^o$$ +   + 7{1 ^ ^ ^ _                                                                     ",
+"                                                                  t_[ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 r.. +                       + I ; [ 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ [ [ J b                           + $'1 ^ ^ ^ ^ m]        + . +  ~m]C;1 1 ^ ^ ^ ^ ^ ^ 1 1 1 ]+-#;#$ p*8 1 ^ ^ ^ b<+                                                                   ",
+"                                                                  i;4 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ [ 4 1 ^ [ 4 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ { .                   + $ (/; [ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ [ )*n/$                       + z{1 ^ ^ ^ [ |++               . - a,G^4 4 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ W(= 4 1 ^ ^ ^ 1]$ +                                                                 ",
+"                                                                  7 K'^ ^ 1 1 5 -.-.-.-.W(Z]Z]Z]Z]B/1 ^ ^ ^ ^ ^ ~ '*=(=(=() j Z]Z]Z]7{1 1 1 ^ ^ P+.                 + + n]r-[ 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ [ 1 J H + +                   + 5(1 ^ ^ ^ 1 ] +               . . + . 0'g~).1 1 1 ^ ^ ^ ^ ^ ^ 1 1 1 1 ^ ^ 1 Y<+ +                                                                 ",
+"                                                                  . 2 ^ ^ 4 d /..               + - d.^ ^ ^ ^ ^ K@=++               =+ ^4 4 ^ ^ I+.               + $ =+G^[ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ [ J h#.                   + {(1 ^ ^ ^ 1 e~%                       . % =+o^y&[ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 4 />                                                                    ",
+"                                                                  . |]^ ^ 1 L*. +                 . = 1 1 ^ ^ ^ 1 *]+               + $ =(+.1 1 !.+             + + =+W(1 1 ^ 1 1 1 K@N*N*N*N*N*N*N*N*N*V *]*]*]*]*]*]*]g+1 1 ^ ^ [ 1 ]+C/+ +               + i*1 ^ ^ ^ 1 [ L*+                     + + + + y.:@|]4 1 ^ 1 ^ ^ ^ ^ ^ ^ ^ [ {+                                                                    ",
+"                                                                  + H+^ ^ i*%                       ;,d 1 ^ ^ ^ 1 i#`]                  $ ' D~H+                . a'! [ ^ ^ ^ 1 4 Y~D + + + + + + + + + $ +           % e +.4 ^ ^ ^ ^ 4 4 ) .               + o^[ ^ ^ ^ ^ ^ [ :@                                $ >[5(; [ [ ^ ^ ^ ^ ^ 1 > h+                                                                    ",
+"                                                                  . V$[ O*s-+                         6{1 ^ ^ ^ ^ 1 3 +                 + + + +                 a'D~1 ^ ^ ^ ^ ^ a <@+                                 + + '=m*1 1 ^ ^ 1 1 [ a,              + $ k;[ ^ ^ ^ ^ [ 7{p*.                             + + . % b i*a [ 1 1 [ ~ (/+                                                                     ",
+"                                                                  $ $ `$g#                            /&]+^ ^ ^ ^ ^ W(a'+                                       m]4 ^ ^ ^ ^ ^ J V$.                                       . '=f~4 ^ ^ ^ 1 4 B/              + $ n]f~1 ^ ^ ^ [ 4 b+U$+                                   $ $ <]B@+.[ V `]. +                                                                     ",
+"                                                                    + + +                           + . >#[ ^ ^ ^ ^ 1 b                                         J]1 ^ ^ ^ 1 [ n*+                                         + + 6^d ^ ^ ^ ^ 1 b+                + + 6^)*1 1 ^ 1 ^ [ 5(+ +                                 +   + + =.<]. + +                                                                       ",
+"                                                                                                    + . D;4 1 ^ ^ ^ [ B/+                                       J]^ ^ ^ ^ 1 -#$                                               . B{^ ^ ^ ^ ^ b+                  + $ b=4 1 ^ ^ ^ [ 4 I+%                                                                                                                         ",
+"                                                                                                        . 2 1 ^ ^ ^ 1 4 P+. +                                 + J]1 ^ ^ ^ ^ =(+               + .                 . + $ +     $ m]^ ^ ^ ^ ^ b+                    + + >,[ [ 1 ^ ^ 1 )*m3. . . +                                                                                                                 ",
+"                                                                                                        + x{1 ^ ^ ^ [ [ +.=(+                                   ` 1 ^ ^ ^ 1 1].       - s-s-s-Y|b ] ] ] ] ] ] ] ] x{` `$$     $ V$^ ^ ^ ^ ^ b+                      . ( (.[ ^ ^ ^ ^ [ F~'@b b';,+                                                                                                               ",
+"                                                                                                        . []4 ^ ^ ^ ^ ^ ^ ^ s.~(. $                             L*^ ^ ^ ^ ^ Z]        = ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ & +     + c_^ ^ ^ ^ ^ b+                          Y|$%1 ^ ^ ^ ^ ^ ^ ^ ^ 1 0{b+b'.                                                                                                         ",
+"                                                                                                        + b 1 ^ ^ ^ ^ ^ ^ ^ [ .$t_$                             L*^ ^ ^ ^ ^ Z]        = ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ &         c_^ ^ ^ ^ ^ b+                          + `$]+^ ^ ^ ^ ^ ^ ^ ^ ^ 4 [ -.`]                                                                                                        ",
+"                                                                                                        + g~1 ^ ^ ^ ^ ^ ^ ^ 4 [ C (/                            L*^ ^ ^ ^ ^ Z]        = ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ B{+       c_^ ^ ^ ^ ^ b+                              9'[ 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ [ *+. +                                                                                                     ",
+"                                                                                                        o$> 1 ^ ^ ^ ^ ^ ^ ^ ]+f~1]$                             L*^ ^ ^ ^ ^ Z]        = ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ .~.       c_^ ^ ^ ^ ^ i*                              . C@1 ^ ^ ^ ^ ^ ^ ^ ^ ^ [ [ L .                                                                                                     ",
+"                                                                                                    + . D;[ [ 4 1 1 ).~ ` s _/. +                               L*^ ^ ^ ^ ^ Z]        Q ^ ^ ^ ^ ^ ^ ^ 1 1 1 1 1 1 1 1 .~.       c_^ ^ ^ ^ ^ a                               + 6 Q+(@q*-.+.4 [ [ 4 [ ^ ^ J 6^                                                                                                    ",
+"                                                                                                    + . e~4 0{o!3 /&o$. . + . $ +                               L*^ ^ ^ ^ ^ Z]        @.=(=(=(=(=(=(=('*{+I]I]I]I]I]I]>[.     + c_^ ^ ^ ^ ^ a                               . . + . + + a'I]F^3 Z]m 5>^ 2 6^                                                                                                    ",
+"                                                                                                    + . `$p*.                                                   L*^ ^ ^ ^ ^ Z]                                                $ V$^ ^ ^ ^ ^ a                                                       $ s-- .                                                                                                     ",
+"                                                                                                      . . . +                                                   L*^ ^ ^ ^ ^ j   +                                         +   . m]^ ^ ^ ^ ^ a + +                                                   + + . .                                                                                                     ",
+"                                                                                                                                                                E~[ ^ ^ ^ 1 > q $ +                                       $ % n$4 ^ ^ ^ 1 [ K'$ +                                                                                                                                                               ",
+"                                                                                                                                                              + c [ 1 ^ ^ ^ [ )*;*+ +                                     + 6.1 [ ^ ^ 1 ^ 8 &>. +                                                                                                                                                               ",
+"                                                                                                                                                                U$s.4 [ ^ ^ ^ 1 )*s $ +                                   d~d ^ ^ ^ ^ 4 4 o^.                                                                                                                                                                   ",
+"                                                                                                                                                                + { b<1 1 ^ ^ ^ [ a b .       + +                 7 i; ~/&; 1 ^ ^ ^ ^ [ $+.                                                                                                                                                                     ",
+"                                                                                                                                                                  + { o!4 [ ^ ^ ^ 1 a J]k;k;k;{(.$l;K'K'K'K'K'K'K')*4 [ ]+^ ^ ^ ^ ^ ^ _ y.                                                                                                                                                                      ",
+"                                                                                                                                                                    + % >,[ [ ^ ^ 1 1 ^ ^ ^ ^ 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 1 [ ^ ^ ^ ^ ^ 1 8{a'+                                                                                                                                                                       ",
+"                                                                                                                                                                      + a'* 4 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ g+-                                                                                                                                                                           ",
+"                                                                                                                                                                        + w _@[ [ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ 1 W(C++                                                                                                                                                                           ",
+"                                                                                                                                                                          + y.7/4 1 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ +.[]                                                                                                                                                                              ",
+"                                                                                                                                                                              $ o^]+^ ^ ^ ^ ^ ^ ^ ^ ^ 1 1 ^ ^ ^ ^ ^ ^ ^ ^ 1 -.i;+                                                                                                                                                                               ",
+"                                                                                                                                                                              + . =#0 0 0 0 0 0 0 0 0 w)b'+ + + + + + + + . $ $ .                                                                                                                                                                               ",
+"                                                                                                                                                                                                        +                                                                                                                                                                                                       ",
+"                                                                                                                                                                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                                                                                                                                                                ",
+"                                                                                                                                                                                                                                                                                                                                                                                                                "};
Index: branches/network/src/lib/gui/gtk_gui/rc
===================================================================
--- branches/network/src/lib/gui/gtk_gui/rc	(revision 6636)
+++ branches/network/src/lib/gui/gtk_gui/rc	(revision 6636)
@@ -0,0 +1,139 @@
+/*
+ * style <name> [= <name>]
+ * {
+ *   <option>
+ * }
+ *
+ * widget <widget_set> style <style_name>
+ * widget_class <widget_class_set> style <style_name>
+ *
+ * Here is a list of all the possible states.  Note that some do not apply to
+ * certain widgets.
+ *
+ * NORMAL - The normal state of a widget, without the mouse over top of
+ * it, and not being pressed, etc.
+ *
+ * PRELIGHT - When the mouse is over top of the widget, colors defined
+ * using this state will be in effect.
+ *
+ * ACTIVE - When the widget is pressed or clicked it will be active, and
+ * the attributes assigned by this tag will be in effect.
+ *
+ * INSENSITIVE - When a widget is set insensitive, and cannot be
+ * activated, it will take these attributes.
+ *
+ * SELECTED - When an object is selected, it takes these attributes.
+ *
+ * Given these states, we can set the attributes of the widgets in each of
+ * these states using the following directives.
+ *
+ * fg - Sets the foreground color of a widget.
+ * bg - Sets the background color of a widget.
+ * bg_pixmap - Sets the background of a widget to a tiled pixmap.
+ * base - Sets the base of Widgets
+ * font - Sets the font to be used with the given widget.
+*/
+
+
+
+static const gchar* rc_string =
+(
+"style'orxonox'"
+"{"
+"fg[NORMAL]      = { 0.0, 1.0, 0.0 }"
+"fg[PRELIGHT]    = { 0.0, 1.0, 0.0 }"
+"fg[ACTIVE]      = { 0.0, 1.0, 0.0 }"
+"fg[INSENSITIVE] = { 0.0, 0.8, 0.0 }"
+"fg[SELECTED]    = { 0.0, 1.0, 0.0 }"
+
+"bg[NORMAL]      = { 0.0, 0.0, 0.0 }"
+"bg[PRELIGHT]    = { 0.0, 1.0, 0.0 }"
+"bg[ACTIVE]      = { 0.0, 0.3, 0.0 }"
+"bg[INSENSITIVE] = { 0.0, 0.1, 0.0 }"
+"bg[SELECTED]    = { 0.0, 0.1, 0.0 }"
+
+"base[NORMAL]      = { 0.0, 1.0, 0.0 }"
+"base[PRELIGHT]    = { 0.0, 1.0, 0.0 }"
+"base[ACTIVE]      = { 0.0, 1.0, 0.0 }"
+"base[INSENSITIVE] = { 0.0, 1.0, 0.0 }"
+"base[SELECTED]    = { 0.0, 1.0, 0.0 }"
+
+"font              = '-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*'"
+"}"
+
+"style'window'"
+"{"			
+"bg[NORMAL] = { 0, 0, 0 }"
+"fg[NORMAL] = { 0, 1.0, 0 }"
+"base[NORMAL] = { 0, 0, 0 }"
+"base[INSENSITIVE] = { 0, 0, 0 }"
+"}"
+
+"style'frame'"
+"{"
+"bg[NORMAL]  = { 0.0, 0.4, 0.0 }"
+"}"
+
+"style'scale'"
+"{"
+"fg[NORMAL] = { 0, 1.0, 0 }"
+"bg[NORMAL] = { 0, 1.0, 0 }"
+"bg[INSENSITIVE] = { 0, 1.0, 0 }"
+"bg[PRELIGHT] = { 0, 1.0, 0 }"
+"bg[ACTIVE] =   {0.2, 0.2, 0.2 }"
+"}"
+
+"style'button'"
+"{"
+"fg[PRELIGHT] = { 0, 0, 0 }"
+"bg[PRELIGHT] = { 0, 1.0, 0 }"
+"bg[ACTIVE] = { 0, 1.0, 0 }"
+"fg[ACTIVE] = { 0, 1.0, 0 }"
+"bg[NORMAL] = { 0, 0, 0 }"
+"fg[NORMAL] = { 0, 1.0, 0 }"
+"bg[INSENSITIVE] = { 0.0, 0.2, 0.0 }"
+"fg[INSENSITIVE] = { 0.0, 0.8, 0.0 }"
+"base[NORMAL] = { 0, 1.0, 0 }"
+"base[PRELIGHT] = { 0, 1.0, 0 }"
+"}"
+
+"style'main_button' = 'button'"
+"{"
+"font = '-adobe-helvetica-medium-r-normal--*-100-*-*-*-*-*-*'"
+"bg[PRELIGHT] = { 0, 0.75, 0 }"
+"}"
+
+"style'toggle_button' = 'button'"
+"{"
+"fg[NORMAL] = { 0, 1.0, 0 }"
+"fg[ACTIVE] = { 0, 1.0, 0 }"
+"text[NORMAL] = { 0, 0, 0}"
+"}"
+
+"style'text'"
+"{"
+"fg[NORMAL] = { 0, 1.0, 0 }"
+"}"
+
+"style'ruler'"
+"{"
+"font = '-adobe-helvetica-medium-r-normal--*-20-*-*-*-*-*-*'"
+"}"
+
+"widget'Gtk*'			style'orxonox'"
+"widget'*Gtk*Frame*'              style'frame'"
+"widget'GtkWindow'		style'window'"
+"widget'GtkFileSelection'	style'window'"
+"widget'*Gtk*Scale'		style'scale'"
+"widget'*GtkCheckButton*'	style'toggle_button'"
+"widget'*Gtk*Menu*'		style'toggle_button'"
+"widget'*GtkRadioButton*'	style'toggle_button'"
+"widget'*GtkButton*'		style'button'"
+"widget'*Ruler'			style'ruler'"
+"widget'*GtkText'		style'text'"
+"widget'*GtkLabel'		style'text'"
+
+"widget'main window.*GtkButton*' style 'main_button'"
+
+
+);
Index: branches/network/src/lib/lang/base_object.cc
===================================================================
--- branches/network/src/lib/lang/base_object.cc	(revision 6636)
+++ branches/network/src/lib/lang/base_object.cc	(revision 6636)
@@ -0,0 +1,230 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_BASE
+
+#include "base_object.h"
+
+#include "load_param.h"
+#include "compiler.h"
+#include "class_list.h"
+
+#include "synchronizeable.h"
+
+using namespace std;
+
+
+/**
+ * @brief sets the name from a LoadXML-Element
+ * @param root the element to load from
+ */
+BaseObject::BaseObject()
+{
+  this->className = "BaseObject";
+  this->classID = CL_BASE_OBJECT;
+
+  this->objectName = NULL;
+  this->classList = NULL;
+  this->xmlElem = NULL;
+
+//  ClassList::addToClassList(this, this->classID, "BaseObject");
+}
+
+/**
+ * @brief standard deconstructor
+*/
+BaseObject::~BaseObject ()
+{
+  ClassList::removeFromClassList(this);
+
+  //  delete []this->className;
+  if (this->objectName)
+    delete[] this->objectName;
+  if (this->xmlElem != NULL)
+    delete this->xmlElem;
+}
+
+/**
+ * @brief loads parameters
+ * @param root the element to load from
+ */
+void BaseObject::loadParams(const TiXmlElement* root)
+{
+  // all loadParams should sometime arrive here.
+  assert (root != NULL);
+
+  if (this->xmlElem != NULL)
+    delete this->xmlElem;
+  this->xmlElem = root->Clone();
+  // name setup
+  LoadParam(root, "name", this, BaseObject, setName)
+      .describe("the Name of the Object.");
+}
+
+/**
+ * @brief sets the class identifiers
+ * @param id a number for the class from class_id.h enumeration
+ * @param className the class name
+*/
+void BaseObject::setClassID(ClassID classID, const char* className)
+{
+  //printf("%s(0x%.8X)->%s(0x%.8X)\n", this->className, this->classID, className, classID);
+  assert (!(this->classID & classID & !CL_MASK_SUBSUPER_CLASS_IDA ));
+
+  this->classID |= (long)classID;
+  this->className = className;
+
+  this->classList = ClassList::addToClassList(this, classID, this->classID, className);
+}
+
+
+/**
+ * @brief set the name of the Object
+ */
+void BaseObject::setName (const char* objectName)
+{
+  if (this->objectName)
+    delete[] this->objectName;
+  if (objectName != NULL)
+  {
+    this->objectName = new char[strlen(objectName)+1];
+    strcpy(this->objectName, objectName);
+  }
+  else
+    this->objectName = NULL;
+}
+
+
+/**
+ * @brief queries for the ClassID of the Leaf Class (the last made class of this type
+ * @returns the ClassID of the Leaf Class (e.g. the ID of the Class)
+ *
+ * the returned ID can be used to generate new Objects of the same type through
+ * Factory::fabricate(Object->getLeafClassID());
+ */
+ClassID BaseObject::getLeafClassID() const
+{
+  assert (this->classList != NULL);
+  return this->classList->getLeafClassID();
+}
+
+
+
+/**
+ * @brief checks if the class is a classID
+ * @param classID the Identifier to check for
+ * @returns true if it is, false otherwise
+*/
+bool BaseObject::isA (ClassID classID) const
+{
+  // if classID is a derivable object from a SUPERCLASS
+  if (classID & CL_MASK_SUPER_CLASS)
+  {
+    if( likely(this->classID & classID))
+      return true;
+  }
+  // if classID is a SubSuperClass, and
+  else if (classID & CL_MASK_SUBSUPER_CLASS)
+  {
+    if (likely(((this->classID & CL_MASK_SUBSUPER_CLASS_IDA) == (this->classID & CL_MASK_SUBSUPER_CLASS_IDA)) &&
+        this->classID & classID & CL_MASK_SUBSUPER_CLASS_IDB))
+      return true;
+  }
+  // if classID is a LOWLEVEL-class
+  else
+  {
+    if( likely((this->classID & CL_MASK_LOWLEVEL_CLASS) == classID))
+      return true;
+  }
+  return false;
+}
+
+
+
+/**
+ * @brief checks if the class is a classID
+ * @param classID the Identifier to check for
+ * @returns true if it is, false otherwise
+ */
+bool BaseObject::isA (const char* className) const
+{
+  ClassID classID = ClassList::StringToID(className);
+  if (classID != CL_NULL)
+    return this->isA(classID);
+}
+
+
+/**
+ * @brief compares the ObjectName with an external name
+ * @param objectName: the name to check.
+ * @returns true on match, false otherwise.
+ */
+bool BaseObject::operator==(const char* objectName)
+{
+  if (likely(this->objectName != NULL && objectName != NULL))
+    return (strcmp(this->objectName, objectName)) ? false : true;
+}
+
+
+/**
+ * @brief displays everything this class is
+ * @TODO REIMPLEMENT WITH SENSE.
+ */
+void BaseObject::whatIs() const
+{
+
+}
+
+/**
+ * Writes data from network containing information about the state
+ * @param data pointer to data
+ * @param length length of data
+ * @param sender hostID of sender
+ */
+int BaseObject::writeState( const byte * data, int length, int sender )
+{
+  SYNCHELP_READ_BEGIN();
+
+  if ( objectName )
+  {
+    delete[] objectName;
+    objectName = NULL;
+  }
+  SYNCHELP_READ_STRINGM( this->objectName );
+  if ( this->objectName && !strcmp(this->objectName, "") )
+  {
+    delete[] this->objectName;
+    this->objectName = NULL;
+  }
+
+  return SYNCHELP_READ_N;
+}
+
+/**
+ * data copied in data will bee sent to another host
+ * @param data pointer to data
+ * @param maxLength max length of data
+ * @return the number of bytes writen
+ */
+int BaseObject::readState( byte * data, int maxLength )
+{
+  SYNCHELP_WRITE_BEGIN();
+
+  //PRINTF(0)("objectname = %s\n", this->objectName);
+  SYNCHELP_WRITE_STRING( this->objectName );
+
+  return SYNCHELP_WRITE_N;
+}
Index: branches/network/src/lib/lang/base_object.h
===================================================================
--- branches/network/src/lib/lang/base_object.h	(revision 6636)
+++ branches/network/src/lib/lang/base_object.h	(revision 6636)
@@ -0,0 +1,68 @@
+/*!
+ * @file base_object.h
+  *  Definition of the base object class.
+
+    This is a global handler for all classes.
+*/
+
+
+#ifndef _BASE_OBJECT_H
+#define _BASE_OBJECT_H
+
+#include "class_id.h"
+#include "debug.h"
+#ifndef NULL
+#define NULL     0    //!< NULL
+#endif
+
+#include "stdincl.h"
+
+class TiXmlNode;
+class TiXmlElement;
+class ClassList;
+
+//! A class all other classes are derived from
+class BaseObject {
+
+ public:
+  BaseObject ();
+  virtual ~BaseObject ();
+
+  virtual void loadParams(const TiXmlElement* root);
+  void setName (const char* newName);
+  /** returns the Name of this Object */
+  inline const char* getName ()const { return this->objectName; };
+  /** @returns the XML-Element with whicht this Object was loaded */
+  inline TiXmlNode* getXmlElem() const { return this->xmlElem; };
+
+  /** @returns the className of the corresponding Object */
+  inline const char* getClassName() const { return this->className; };
+  /** @returns the classID of the corresponding Object */
+  inline int getClassID() const { return this->classID; };
+  ClassID    getLeafClassID() const;
+
+  bool isA (ClassID classID) const;
+  bool isA (const char* className) const;
+  void whatIs() const;
+
+  bool operator==(const char* objectName);
+  /** @param classID comparer for a ClassID @returns true on match, false otherwise */
+  bool operator==(ClassID classID) { return this->isA(classID); };
+
+  int       writeState(const byte* data, int length, int sender);
+  int       readState(byte* data, int maxLength );
+
+ protected:
+  void setClassID(ClassID classID, const char* className);
+
+ private:
+    const char*        className;        //!< the name of the class
+    long               classID;          //!< this is the id from the class_id.h enumeration
+    char*              objectName;       //!< The name of this object
+
+    ClassList*         classList;        //!< Pointer to the ClassList this Object is inside of
+
+    TiXmlNode*         xmlElem;          //!< The XML Element with wich this Object was loaded(saved).
+};
+
+#endif /* _BASE_OBJECT_H */
Index: branches/network/src/lib/lang/class_list.cc
===================================================================
--- branches/network/src/lib/lang/class_list.cc	(revision 6636)
+++ branches/network/src/lib/lang/class_list.cc	(revision 6636)
@@ -0,0 +1,376 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "class_list.h"
+#include "base_object.h"
+
+#include "compiler.h"
+#include "debug.h"
+#include <string.h>
+#include <math.h>
+#include <algorithm>
+#include "shell_command.h"
+
+using namespace std;
+
+#ifndef NO_SHELL_COMMAND
+SHELL_COMMAND_STATIC(debug, ClassList, ClassList::debugS)
+    ->describe("Shows all registered classes, if param1: is a valid ClassName only values of this class are shown. param2: how much output")
+    ->defaultValues(2, NULL, 1);
+#endif
+
+/**
+ *  Creates a new ClassList
+*/
+ClassList::ClassList(ClassID classID, unsigned long classIDFull, const char* className)
+{
+  this->className = className;
+  this->classID = classID;
+  this->classIDFull = classIDFull;
+}
+
+/**
+ *  standard deconstructor
+*/
+ClassList::~ClassList ()
+{
+//   ClassList::classList->clear());
+}
+
+//! a List of all known Classes.
+std::list<ClassList>* ClassList::classList = NULL;
+
+//! a List of all strings of all classes, that have registered so far.
+std::list<const char*> ClassList::classNames;
+
+/**
+ * @brief Adds a new Object to the ClassList (and if necessary a new Class)
+ * @param objectPointer Pointer to the Object at hand
+ * @param classID ID of the Given ObjectType \see ClassID
+ * @param className name of the Class to add
+ *
+ * !! FIRST YOU HAVE TO CALL THIS FUNCTION ONCE
+ * !! Before unsing the ClassList, as it creates the ClassLits
+ */
+ClassList* ClassList::addToClassList(BaseObject* objectPointer, ClassID classID, unsigned long classIDFull, const char* className)
+{
+  if (unlikely(classList == NULL))
+    ClassList::classList = new list<ClassList>();
+
+  PRINTF(5)("subscribe a '%s'\n", className );
+
+  ClassList* regClass = ClassList::getClassList(classID);
+  if (regClass != NULL)
+  {
+    regClass->objectList.push_back(objectPointer);
+    return regClass;
+  }
+  else
+  {
+    ClassList::classList->push_back(ClassList(classID, classIDFull, className));
+    ClassList::classList->back().objectList.push_back(objectPointer);
+    return &ClassList::classList->back();
+  }
+}
+
+/**
+ * removes an Object from a the ClassList
+ * @param objectPointer the Object to delete from the List
+ */
+void ClassList::removeFromClassList(BaseObject* objectPointer)
+{
+  list<ClassList>::iterator cl;
+  for(cl = ClassList::classList->begin(); cl != ClassList::classList->end(); cl++)
+  {
+    if (objectPointer->isA((*cl).classID))
+    {
+      std::list<BaseObject*>::iterator bo = std::find ((*cl).objectList.begin(), (*cl).objectList.end(), objectPointer);
+      if (bo != (*cl).objectList.end())
+          (*cl).objectList.erase(bo);
+    }
+  }
+}
+
+/**
+ * grabs the names of all Classes, and injects it into a List of const chars
+ * @return the generated List
+ *
+ * This function first looks, if the List has been changed (by the ListSize)
+ * befor it changes anything.
+ */
+const std::list<const char*>* ClassList::getClassNames()
+{
+  if (ClassList::classNames.size() != ClassList::classList->size())
+  {
+      ClassList::classNames.clear();
+
+      list<ClassList>::const_iterator cl;
+      for (cl = ClassList::classList->begin(); cl != ClassList::classList->end(); cl++)
+        ClassList::classNames.push_back((*cl).className);
+  }
+
+  return &ClassList::classNames;
+}
+
+/**
+ * searches for classID and returns the list of Entities
+ * @param classID the ID of the class to get the list from
+ * @return the List accessed by classID, or NULL if not found
+ */
+const std::list<BaseObject*>* ClassList::getList(ClassID classID)
+{
+  ClassList* fl;
+  return ((fl = ClassList::getClassList(classID)) != NULL)?
+       &(fl->objectList) : NULL;
+
+/*
+  std::list<ClassList>::iterator classIT = find (classList->begin(), classList->end(), classID);
+  return (likely(classIT != classList->end()))? &(*classIT).objectList : NULL;*/
+
+/*  for (classIT = ClassList::classList->begin(); classIT != ClassList::classList->end(); classIT++)
+  {
+    if ((*classIT) == classID )
+      return &(*classIT).objectList;
+  }
+  return NULL;*/
+}
+
+/**
+ * searches for className and returns the list of Entities
+ * @param className the name of the class to get the list from
+ * @return the List accessed by classID, or NULL if not found
+ */
+const std::list<BaseObject*>* ClassList::getList(const char* className)
+{
+  ClassList* fl;
+  return ((fl = ClassList::getClassList(className)) != NULL)?
+      &(fl->objectList) : NULL;
+
+  /*
+  std::list<ClassList>::iterator classIT = find (classList->begin(), classList->end(), className);
+  return (likely(classIT != classList->end()))? &(*classIT).objectList : NULL;*/
+
+
+/*  for (classIT = ClassList::classList->begin(); classIT != ClassList::classList->end(); classIT++)
+  {
+    if ((*classIT) == className )
+      return &(*classIT).objectList;
+  }
+  return NULL;*/
+}
+
+/**
+ * !!PRIVATE!!
+ * @param classID the ClassID to search for
+ * @returns the ClassList with classID as specifyer, or NULL if not
+ */
+ClassList* ClassList::getClassList(ClassID classID)
+{
+  std::list<ClassList>::iterator classIT = find (ClassList::classList->begin(), ClassList::classList->end(), classID);
+  return (likely(classIT != classList->end()))? &(*classIT) : NULL;
+}
+
+
+/**
+ * !!PRIVATE!!
+ * @param className the ClassName to search for
+ * @returns the ClassList with className as specifyer, or NULL if not
+ */
+ClassList* ClassList::getClassList(const char* className)
+{
+  if (className == NULL)
+    return NULL;
+  std::list<ClassList>::iterator classIT = find (classList->begin(), classList->end(), className);
+  return (likely(classIT != classList->end()))? &(*classIT) : NULL;
+}
+
+
+/**
+ * checks if the BaseObject* object exists.
+ * @param objectName the name of the BaseObject to look for
+ * @param classID if not CL_NULL it will only search through a specific type of Objects. Otherwise it will be searched everywhere.
+ * @return true, if the Object Exists in the specified ClassID, false otherwise
+ * @todo: speed this up!!
+ */
+BaseObject* ClassList::getObject(const char* objectName, ClassID classID)
+{
+  if (classID != CL_NULL)
+  {
+    ClassList* cl = ClassList::getClassList(classID);
+    if (cl != NULL)
+    {
+      std::list<BaseObject*>::iterator bo;
+      for (bo = cl->objectList.begin(); bo != cl->objectList.end(); bo++)
+        if ((*bo)->getName() != NULL && !strcmp((*bo)->getName(), objectName))
+          return (*bo);
+    }
+  }
+  else
+  {
+    list<ClassList>::iterator cl;
+    for (cl = ClassList::classList->begin(); cl != ClassList::classList->end(); cl++)
+    {
+      std::list<BaseObject*>::iterator bo;
+      for (bo = (*cl).objectList.begin(); bo != (*cl).objectList.end(); bo++)
+        if ((*bo)->getName() != NULL && !strcmp((*bo)->getName(), objectName))
+          return (*bo);
+    }
+  }
+  return NULL;
+}
+
+
+/**
+ * checks if the BaseObject* object exists.
+ * @param object the Pointer to a BaseObject to check if it exists
+ * @param classID if not CL_NULL it will only search through a specific type of Objects. Otherwise it will be searched everywhere.
+ * @return true, if the Object Exists in the specified ClassID, false otherwise
+ * @todo: speed this up!!
+ */
+bool ClassList::exists(const BaseObject* object, ClassID classID)
+{
+  if (classID != CL_NULL)
+  {
+    ClassList* cl = ClassList::getClassList(classID);
+    if (cl != NULL)
+    {
+      std::list<BaseObject*>::const_iterator bo = find (cl->objectList.begin(), cl->objectList.end(), object);
+      return (bo != cl->objectList.end());
+    }
+  }
+  else
+  {
+    list<ClassList>::iterator cl;
+    for (cl = ClassList::classList->begin(); cl != ClassList::classList->end(); cl++)
+    {
+      std::list<BaseObject*>::const_iterator bo = find ((*cl).objectList.begin(), (*cl).objectList.end(), object);
+      if (bo != (*cl).objectList.end())
+        return true;
+    }
+  }
+  return false;
+}
+
+/**
+ * prints out a string of all the types this Object matches
+ * @param object a Pointer to the object to analyze
+ */
+void ClassList::whatIs(const BaseObject* object)
+{
+  list<ClassList>::iterator cl;
+  for (cl = ClassList::classList->begin(); cl != ClassList::classList->end(); cl++)
+    if (object->isA((*cl).classID))
+  {
+    PRINT(0)("=%s=-", (*cl).className);
+  }
+}
+
+/**
+ * converts a ClassID into a string
+ * @param classID the ClassID to search for
+ * @return a String containing the name of the Class, NULL if the Class was not found
+ */
+const char* ClassList::IDToString(ClassID classID)
+{
+  ClassList* cl = ClassList::getClassList(classID);
+  return (cl != NULL) ? cl->className : NULL;
+}
+
+/**
+ * converts a String into a ClassID
+ * @param className the name of the class to search for
+ * @return the ClassID. CL_NULL, if the class was not found.
+ */
+ClassID ClassList::StringToID(const char* className)
+{
+  ClassList* cl = ClassList::getClassList(className);
+  return (cl != NULL) ? cl->classID : CL_NULL;
+}
+
+/**
+ * checks if this ClassList is named className
+ * @param className the Name to check this ClassList's ClassName against
+ * @returns true on match, false otherwise
+ */
+bool ClassList::operator==(const char* className)
+{
+  if (likely( className != NULL && this->className != NULL))
+    return (!strcmp(this->className, className));
+  else
+    return false;
+}
+
+
+
+/**
+ * Print out some very nice debug information
+ * @param debugLevel the level of verbosity
+ * @param classID the class that should be displayed (if CL_NULL (default) all classes will be displayed)
+ */
+void ClassList::debug(unsigned int debugLevel, ClassID classID)
+{
+  if (debugLevel > 3)
+    debugLevel = 3;
+  PRINT(0)("==========================\n");
+  PRINT(0)("=  CLASS_LIST (level %d)  =\n", debugLevel);
+  PRINT(0)("==========================\n");
+  PRINT(0)("| knows %d Classes\n|\n", ClassList::classList->size());
+  char niceString[100];
+  unsigned int lenCount = 0;
+
+  list<ClassList>::iterator cl;
+  for (cl = ClassList::classList->begin(); cl != ClassList::classList->end(); cl++)
+  {
+    if ((debugLevel >= 1 || (*cl).objectList.size() > 0 ) &&
+         (classID == CL_NULL || unlikely (classID == (*cl).classID)))
+    {
+      lenCount = 1;
+      while (pow(10, lenCount) <= (*cl).objectList.size())
+        ++lenCount;
+      for (int i=0; i < 30-strlen((*cl).className) - lenCount; i++)
+        (niceString[i]) = ' ';
+      niceString[30-strlen((*cl).className) - lenCount] = '\0';
+
+      PRINT(0)("| CLASS %s:%s %d\n", (*cl).className, niceString, (*cl).objectList.size());
+
+      if (debugLevel >=2 && (*cl).objectList.size() > 0)
+      {
+        PRINT(0)("|  Listing Instances:\n");
+        list<BaseObject*>::const_iterator bo;
+        for (bo = (*cl).objectList.begin(); bo != (*cl).objectList.end(); bo++)
+        {
+          PRINT(0)("|   (class %s): NAME(%s)->%p ", (*bo)->getClassName(), (*bo)->getName(), (*bo));
+          if (debugLevel == 3)
+            ClassList::whatIs(*bo);
+          PRINT(0)("\n");
+        }
+      }
+    }
+  }
+  PRINT(0)("=======================CL=\n");
+}
+
+/**
+ * Print out some very nice debug information
+ * @param debugLevel the level of verbosity
+ * @param className the class that should be displayed.
+ * @see ClassList::debug
+ */
+void ClassList::debugS(const char* className, unsigned int debugLevel)
+{
+  ClassList::debug(debugLevel, ClassList::StringToID(className));
+}
Index: branches/network/src/lib/lang/class_list.h
===================================================================
--- branches/network/src/lib/lang/class_list.h	(revision 6636)
+++ branches/network/src/lib/lang/class_list.h	(revision 6636)
@@ -0,0 +1,79 @@
+/*!
+ * @file class_list.h
+  *  Definition of the Class List, that handles a Class-Specific-Control structure
+
+ */
+
+#ifndef _CLASS_LIST_H
+#define _CLASS_LIST_H
+
+#include "class_id.h"
+#include <list>
+#ifndef NULL
+#define NULL     0    //!< NULL
+#endif
+
+// FORWARD DECLARATION
+class BaseObject;
+
+//! A class that handles Pointers to Objects of all type.
+/**
+ * here all the Pointers to all the Object of orxonox are stored, that implement BaseObject
+ * for now.
+ * You can get Any Object's Reference to BaseObject with dynamic_cast<T>(ClassList::getObject(name, CL_T_NAME));
+ *  where: T: is the Class to cast to,
+ *   name: the name of the Object (not className)
+ *   CL_T_NAME: the class Identifier, (if CL_NULL or nothing it will take longer, because all BaseObject's are searched through)
+ *
+ * There is also the exists-function, that just checks, if a Reference is still in existence.
+ *
+ * @see ClassID, BaseObject, dynamic_cast
+ */
+class ClassList {
+  public:
+    ClassList(ClassID classID, unsigned long classIDFull, const char* className);
+    virtual ~ClassList();
+
+    /* MAINTENANCE FUNCTIONS THESE ARE !!ONLY FOR BASEOBJECT !! */
+    static ClassList*                     addToClassList(BaseObject* objectPointer, ClassID classID, unsigned long classIDFull, const char* className);
+    static void                           removeFromClassList(BaseObject* objectPointer);
+
+
+
+    static const std::list<BaseObject*>*  getList(ClassID classID = CL_NULL);// { return (ClassList* fl = ClassList::getClassList(classID) != NULL)? &(fl->objectList) : NULL; };
+    static const std::list<BaseObject*>*  getList(const char* className); // { return (ClassList* fl = ClassList::getClassList(className) != NULL)? &(fl->objectList) : NULL;  };
+    static const std::list<const char*>*  getClassNames();
+    static BaseObject*                    getObject(const char* name, ClassID classID = CL_NULL);
+    static bool                           exists(const BaseObject* object, ClassID classID = CL_NULL);
+
+    void                                  sendBack(std::list<BaseObject*>::const_iterator it);
+
+    static void                           whatIs(const BaseObject* object);
+
+    static const char*                    IDToString(ClassID classID = CL_NULL);
+    static ClassID                        StringToID(const char* className);
+    static void                           debug(unsigned int debugLevel = 0, ClassID classID = CL_NULL);
+    static void                           debugS(const char* className = NULL, unsigned int debugLevel = 0);
+
+    inline bool                           operator==(ClassID classID) { return (this->classID == classID); };
+    bool                                  operator==(const char* className);
+    inline ClassID                        getLeafClassID() const { return this->classID; };
+
+  private:
+    static ClassList*                     getClassList(ClassID classID);
+    static ClassList*                     getClassList(const char* className);
+
+  private:
+    ClassID                         classID;                //!< ClassID stored in this ClassList
+    unsigned long                   classIDFull;            //!< The Full ClassID of this Class.
+
+    const char*                     className;              //!< Name of the Class Stored here
+
+    std::list<BaseObject*>          objectList;             //!< A list of Objects belonging to this Class
+
+    // STATIC MEMBERS
+    static std::list<ClassList>*    classList;              //!< The first Class in the List
+    static std::list<const char*>   classNames;             //!< a List of all Names of all classes, that have registered so far.
+};
+
+#endif /* _CLASS_LIST_H */
Index: branches/network/src/lib/math/curve.cc
===================================================================
--- branches/network/src/lib/math/curve.cc	(revision 6636)
+++ branches/network/src/lib/math/curve.cc	(revision 6636)
@@ -0,0 +1,306 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: Patrick Boenzli
+
+   ADD: Patrick Boenzli           B-Spline
+
+
+   TODO:
+     local-Time implementation
+     NURBS
+     !!tList implementation!!
+
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_MATH
+
+#include "curve.h"
+
+#include "debug.h"
+
+#include <math.h>
+#include <stdio.h>
+
+
+/**
+  *  default constructor for a Curve
+*/
+Curve::Curve()
+{
+  this->nodeCount = 0;
+  this->localTime = 0;
+  this->derivation = 0;
+  this->dirCurve = NULL;
+  this->firstNode = new PathNode();
+  this->currentNode = firstNode;
+
+  this->firstNode->position = Vector (.0, .0, .0);
+  this->firstNode->number = 0;
+  this->firstNode->next = 0; // not sure if this really points to NULL!!
+}
+
+
+Curve::~Curve()
+{
+  PathNode* pn = this->firstNode;
+  PathNode* unusedPN;
+  while( pn != NULL)
+  {
+    unusedPN = pn;
+    pn = pn->next;
+    delete unusedPN;
+  }
+
+  if (dirCurve)
+    delete dirCurve;
+}
+
+
+/**
+ *  adds a new Node to the bezier Curve
+ * @param newNode a Vector to the position of the new node
+*/
+void Curve::addNode(const Vector& newNode)
+{
+  if (nodeCount != 0 )
+    {
+      currentNode = currentNode->next = new PathNode;
+    }
+  currentNode->position = newNode;
+  currentNode->next = 0;
+  currentNode->number = (++nodeCount);
+  this->rebuild();
+  return;
+}
+
+/**
+ *  adds a new Node to the bezier Curve
+ * @param newNode a Vector to the position of the new node
+ * @param insertPosition after the n-th node the new node will be inserted
+*/
+void Curve::addNode(const Vector& newNode, unsigned int insertPosition)
+{
+  if (this->nodeCount == 0 || insertPosition > this->nodeCount)
+    return addNode(newNode);
+
+  if (insertPosition == 0)
+    insertPosition = 1;
+
+  PathNode* insNode = new PathNode;
+
+  // relinking
+  PathNode* tmpNode = this->firstNode;
+  if (insertPosition > 1)
+    {
+      while (tmpNode->next->number != insertPosition)
+        tmpNode= tmpNode->next;
+      insNode->next = tmpNode->next;
+      tmpNode->next = insNode;
+    }
+  else
+    {
+      insNode->next = this->firstNode;
+      this->firstNode = insNode;
+    }
+  // renumbering
+  insNode->number = insertPosition;
+  tmpNode = insNode->next;
+  while (tmpNode)
+    {
+      tmpNode->number++;
+      tmpNode = tmpNode->next;
+    }
+
+    // finished
+  insNode->position = newNode;
+  ++nodeCount;
+  this->rebuild();
+  return;
+}
+
+/**
+ *  Finds a Node by its Number, and returns its Position
+ * @param nodeToFind the n'th node in the List of nodes
+ * @returns A Vector to the Position of the Node.
+*/
+Vector Curve::getNode(unsigned int nodeToFind)
+{
+  if (nodeToFind > this->nodeCount || nodeToFind < 0)
+    return Vector(0,0,0);
+  PathNode* tmpNode = this->firstNode;
+  for (int i = 1; i < nodeToFind; i++)
+    tmpNode = tmpNode->next;
+  return tmpNode->position;
+}
+
+/**
+ *  Outputs information about the state of this Curve
+*/
+void Curve::debug()
+{
+  printf("<<-------------------------------\n");
+  printf("Curve Information:\n");
+  printf("NodeCount: %d\n", this->nodeCount);
+  PathNode* tmpNode = this->firstNode;
+  while (tmpNode)
+    {
+      printf("node #%d: %f, %f, %f\n", tmpNode->number, tmpNode->position.x, tmpNode->position.y, tmpNode->position.z);
+      tmpNode = tmpNode->next;
+    }
+  printf("------------------------------->>\n");
+}
+
+
+///////////////////////////////////
+/// Bezier Curve //////////////////
+///////////////////////////////////
+
+/**
+ *  Creates a new BezierCurve
+*/
+BezierCurve::BezierCurve ()
+{
+  this->derivation = 0;
+  dirCurve = new BezierCurve(1);
+}
+
+/**
+ *  Creates a new BezierCurve-Derivation-Curve
+*/
+BezierCurve::BezierCurve (int derivation)
+{
+  this->derivation = derivation;
+  dirCurve=NULL;
+}
+
+/**
+ *  Deletes a BezierCurve.
+
+   It does this by freeing all the space taken over from the nodes
+*/
+BezierCurve::~BezierCurve()
+{
+
+}
+
+/**
+ *  Rebuilds a Curve
+*/
+void BezierCurve::rebuild()
+{
+  PathNode* tmpNode = firstNode;
+
+  // rebuilding the Curve itself
+  float k = 0;
+  float n = nodeCount -1;
+  float binCoef = 1;
+  while( tmpNode)
+    {
+      tmpNode->factor = binCoef;
+      if( tmpNode = tmpNode->next)
+        {
+          binCoef *= (n-k) / (k+1);
+          ++k;
+        }
+    }
+
+  // rebuilding the Derivation curve
+  if( this->derivation <= 1)
+    {
+      tmpNode = firstNode;
+      delete dirCurve;
+      dirCurve = new BezierCurve(1);
+      while( tmpNode->next)
+        {
+          Vector tmpVector = (tmpNode->next->position) - (tmpNode->position);
+          tmpVector.x*=(float)nodeCount;
+          tmpVector.y*=(float)nodeCount;
+          tmpVector.z*=(float)nodeCount;
+          tmpVector.normalize();
+          this->dirCurve->addNode(tmpVector);
+          tmpNode = tmpNode->next;
+        }
+    }
+}
+
+/**
+ *  calculates the Position on the curve
+ * @param t The position on the Curve (0<=t<=1)
+ * @return the Position on the Path
+*/
+Vector BezierCurve::calcPos(float t)
+{
+  Vector ret = Vector(0.0,0.0,0.0);
+  if (this->nodeCount >= 3)
+    {
+      PathNode* tmpNode = this->firstNode;
+      double factor = pow(1.0-t,nodeCount-1);
+      while(tmpNode)
+        {
+          ret.x += tmpNode->factor * factor * tmpNode->position.x;
+          ret.y += tmpNode->factor * factor * tmpNode->position.y;
+          ret.z += tmpNode->factor * factor * tmpNode->position.z;
+          factor *= t/(1.0-t); // same as pow but much faster.
+
+          tmpNode = tmpNode->next;
+        }
+    }
+  else if (nodeCount == 2)
+    {
+      ret = this->firstNode->position *(1.0-t);
+      ret = ret + this->firstNode->next->position * t;
+    }
+  else if (nodeCount == 1)
+    ret = this->firstNode->position;
+  return ret;
+}
+
+/**
+ *  Calulates the direction of the Curve at time t.
+ * @param t The time at which to evaluate the curve.
+ * @returns The valuated Vector.
+*/
+Vector BezierCurve::calcDir (float t)
+{
+  return this->dirCurve->calcPos(t);
+}
+
+/**
+ *  Calulates the acceleration (second derivate) of the Curve at time t.
+ * @param t The time at which to evaluate the curve.
+ * @returns The valuated Vector.
+*/
+Vector BezierCurve::calcAcc (float t)
+{
+  return this->dirCurve->getDirCurve()->calcPos(t);
+}
+
+/**
+ *  Calculates the Quaternion needed for our rotations
+ * @param t The time at which to evaluate the cuve.
+ * @returns The evaluated Quaternion.
+*/
+Quaternion BezierCurve::calcQuat (float t)
+{
+  return Quaternion (calcDir(t), Vector(0,0,1));
+}
+
+
+/**
+  \brief returns the Position of the point calculated on the Curve
+  \return a Vector to the calculated position
+*/
+Vector BezierCurve::getPos() const
+{
+  return curvePoint;
+}
Index: branches/network/src/lib/math/curve.h
===================================================================
--- branches/network/src/lib/math/curve.h	(revision 6636)
+++ branches/network/src/lib/math/curve.h	(revision 6636)
@@ -0,0 +1,116 @@
+
+/*!
+ * @file curve.h
+  *  A basic 3D curve framework
+
+    Contains classes to handle curves
+*/
+
+#ifndef _CURVE_H
+#define _CURVE_H
+
+#include "vector.h"
+#include "quaternion.h"
+
+template<class T> class tList;
+template<class T> class tIterator;
+
+//! An Enumerator that defines what sort of Curves are availible
+enum CurveType {
+  CURVE_BEZIER
+};
+
+
+//! An abstract class to handle curves. Needed for the Tracking system in orxonox.
+class Curve
+{
+ protected:
+  //! Handles the curve-points (dynamic List)
+  struct PathNode
+  {
+    int          number;       //!< The N-th node of this curve.
+    float        factor;       //!< Curve specific multiplier factor.
+    Vector       vFactor;      //!< A Vector-factor for multipliing.
+    Vector       position;     //!< Vector Pointung to this curve-point.
+    PathNode*    next;         //!< Pointer to the next Node.
+  };
+
+ public:
+  Curve();
+  virtual ~Curve();
+
+  void addNode(const Vector& newNode);
+  void addNode(const Vector& newNode, unsigned int insertPosition);
+  Vector getNode(unsigned int nodeToFind);
+  /** @returns the count of nodes in this curve */
+  inline int getNodeCount() const { return this->nodeCount; };
+  /** @returns the directional Curve */
+  Curve* getDirCurve() const { return this->dirCurve; };
+
+  /** @param t the value on the curve [0-1] @returns Vector to the position */
+  virtual Vector calcPos(float t) = 0;
+  /** @param t the value on the curve [0-1] @returns the direction */
+  virtual Vector calcDir(float t) = 0;
+  /** @param t the value on the curve [0-1] @returns the acceleration */
+  virtual Vector calcAcc(float t) = 0;
+  /** @param t the value on the curve [0-1] @returns quaternion of the rotation */
+  virtual Quaternion calcQuat(float t) = 0;
+
+  // DEBUG
+  void debug();
+
+ private:
+  /** \brief rebuilds the curve */
+  virtual void rebuild() = 0;
+
+ protected:
+  int                   nodeCount;       //!< The count of nodes the Curve has.
+  Vector                curvePoint;      //!< The point on the Cureve at a local Time.
+  float                 localTime;       //!< If the time of one point is asked more than once the programm will not calculate it again.
+  int                   derivation;      //!< Which derivation of a Curve is this.
+
+  Curve*                dirCurve;        //!< The derivation-curve of this Curve.
+
+  tList<PathNode>*      nodeList;        //!< A list of all the Nodes of a Curve.
+  tIterator<PathNode>*  nodeIterator;    //!< An iterator that should point to the current Node
+  PathNode*             firstNode;       //!< First node of the curve.
+  PathNode*             currentNode;     //!< The node we are working with (the Last node).
+
+};
+
+//!    Class to handle bezier curves in 3-dimesnsional space
+/**
+   This Curve is good, for Fast Interaction. If you want to change it during the game, go on.
+   !!be aware!! BezierCurves only flow through their first and last Node. Their Tangents at those Points a directed to the second and second-last Point.
+*/
+class BezierCurve : public Curve
+{
+ public:
+  BezierCurve();
+  BezierCurve(int derivation);
+  virtual ~BezierCurve();
+
+  virtual Vector calcPos(float t);
+  virtual Vector calcDir(float t);
+  virtual Vector calcAcc(float t);
+  virtual Quaternion calcQuat(float t);
+
+
+  Vector getPos() const;
+
+ private:
+  void rebuild();
+};
+
+
+//! B-Spline
+/**
+   class to handle b-spline in 3d space
+*/
+class BSplieCurve : public Curve
+{
+
+
+};
+
+#endif /* _CURVE_H */
Index: branches/network/src/lib/math/line.cc
===================================================================
--- branches/network/src/lib/math/line.cc	(revision 6636)
+++ branches/network/src/lib/math/line.cc	(revision 6636)
@@ -0,0 +1,104 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: Patrick Boenzli : Vector::scale()
+                                    Vector::abs()
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_MATH
+
+#include "line.h"
+#include "plane.h"
+#ifdef DEBUG
+  #include "debug.h"
+#else
+  #include <stdio.h>
+  #define PRINT(x) printf
+#endif
+
+using namespace std;
+
+/**
+ *  calculate the distance between two lines
+ * @param l: the other line
+ * @return the distance between the lines
+*/
+float Line::distance (const Line& l) const
+{
+  float q, d;
+  Vector n = a.cross(l.a);
+  q = n.dot(r-l.r);
+  d = n.len();
+  if( d == 0.0) return 0.0;
+  return q/d;
+}
+
+/**
+ *  calculate the distance between a line and a point
+ * @param v: the point
+ * @return the distance between the Line and the point
+*/
+float Line::distancePoint (const Vector& v) const
+{
+  Vector d = v-r;
+  Vector u = a * d.dot( a);
+  return (d - u).len();
+}
+
+/**
+ *  calculate the distance between a line and a point
+ * @param v: the point
+ * @return the distance between the Line and the point
+ */
+float Line::distancePoint (const sVec3D& v) const
+{
+  Vector s(v[0], v[1], v[2]);
+  Vector d = s - r;
+  Vector u = a * d.dot( a);
+  return (d - u).len();
+}
+
+/**
+ *  calculate the two points of minimal distance of two lines
+ * @param l: the other line
+ * @return a Vector[2] (!has to be deleted after use!) containing the two points of minimal distance
+*/
+Vector* Line::footpoints (const Line& l) const
+{
+  Vector* fp = new Vector[2];
+  Plane p = Plane (r + a.cross(l.a), r, r + a);
+  fp[1] = p.intersectLine (l);
+  p = Plane (fp[1], l.a);
+  fp[0] = p.intersectLine (*this);
+  return fp;
+}
+
+/**
+  \brief calculate the length of a line
+  \return the lenght of the line
+*/
+float Line::len() const
+{
+  return a.len();
+}
+
+/**
+ *  rotate the line by given rotation
+ * @param rot: a rotation
+*/
+void Line::rotate (const Rotation& rot)
+{
+  Vector t = a + r;
+  t = rotateVector( t, rot);
+  r = rotateVector( r, rot),
+  a = t - r;
+}
Index: branches/network/src/lib/math/line.h
===================================================================
--- branches/network/src/lib/math/line.h	(revision 6636)
+++ branches/network/src/lib/math/line.h	(revision 6636)
@@ -0,0 +1,59 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: ...
+*/
+
+/*!
+ * @file line.h
+ * A basic 3D math line framework
+ *
+ * Contains class to handle lines
+*/
+
+#ifndef __LINE_H_
+#define __LINE_H_
+
+#include <math.h>
+#include "compiler.h"
+#include "vector.h"
+#include "rotation_OBSOLETE.h"
+
+//! 3D line
+/**
+  Class to store Lines in 3-dimensional space
+
+  Supports line-to-line distance measurements and rotation
+*/
+class Line
+{
+  public:
+
+  Vector r;   //!< Offset
+  Vector a;   //!< Direction
+
+  Line ( Vector r, Vector a) : r(r), a(a) {}  //!< assignment constructor
+  Line () : r(Vector(0,0,0)), a(Vector (1,1,1)) {}
+  ~Line () {}
+
+  float distance (const Line& l) const;
+  float distancePoint (const Vector& v) const;
+  float distancePoint (const sVec3D& v) const;
+  Vector* footpoints (const Line& l) const;
+  float len () const;
+
+  void rotate(const Rotation& rot);
+};
+
+
+#endif /* __LINE_H_ */
+
Index: branches/network/src/lib/math/matrix.cc
===================================================================
--- branches/network/src/lib/math/matrix.cc	(revision 6636)
+++ branches/network/src/lib/math/matrix.cc	(revision 6636)
@@ -0,0 +1,268 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: Patrick Boenzli
+*/
+#include "matrix.h"
+#include <math.h>
+
+#ifdef DEBUG
+#include "debug.h"
+#else
+#include <stdio.h>
+#define PRINT(x) printf
+#endif
+
+/**
+ * constructs a Matrix from all Parameters in a Row
+ * @param m11 [0][0]
+ * @param m12 [0][1]
+ * @param m13 [0][2]
+ * @param m21 [1][0]
+ * @param m22 [1][1]
+ * @param m23 [1][2]
+ * @param m31 [2][0]
+ * @param m32 [2][1]
+ * @param m33 [2][2]
+ */
+Matrix::Matrix ( float m11, float m12, float m13,
+             float m21, float m22, float m23,
+             float m31, float m32, float m33 )
+{
+  this->m11 = m11; this->m12 = m12; this->m13 = m13;
+  this->m21 = m21; this->m22 = m22; this->m23 = m23;
+  this->m31 = m31; this->m32 = m32; this->m33 = m33;
+};
+
+/**
+ * creates a Matrix out of an Array of floats with size [3][3]
+ * @param m the Matrix stored in an Array
+ */
+Matrix::Matrix(const float m[3][3])
+{
+  this->m11 = m[0][0]; this->m12 = m[0][1]; this->m13 = m[0][2];
+  this->m21 = m[1][0]; this->m22 = m[1][1]; this->m23 = m[1][2];
+  this->m31 = m[2][0]; this->m32 = m[2][1]; this->m33 = m[2][2];
+};
+
+
+/**
+ * adds a Matrix to this one returning the result
+ * @param m the Matrix to add to this one
+ * @returns a copy of this Matrix added m
+ */
+Matrix Matrix::operator+ (const Matrix& m) const
+{
+  return Matrix (this->m11 + m.m11, this->m12 + m.m12, this->m13 + m.m13,
+                 this->m21 + m.m21, this->m22 + m.m22, this->m23 + m.m23,
+                 this->m31 + m.m31, this->m32 + m.m32, this->m33 + m.m33);
+}
+
+/**
+ * sustracts a Matrix from this one returning the result
+ * @param m the Matrix to substract from this one
+ * @returns a copy of this Matrix substracted m
+ */
+Matrix Matrix::operator- (const Matrix& m) const
+{
+  return Matrix (this->m11 - m.m11, this->m12 - m.m12, this->m13 - m.m13,
+                 this->m21 - m.m21, this->m22 - m.m22, this->m23 - m.m23,
+                 this->m31 - m.m31, this->m32 - m.m32, this->m33 - m.m33);
+}
+
+/**
+ * multiplies each value of a copu of this Matrix by k
+ * @param k the multiplication factor
+ * @returns a copy of this Matrix multiplied by k
+ */
+Matrix Matrix::operator* (float k) const
+{
+  return Matrix(this->m11 * k, this->m12 * k, this->m13 * k,
+                this->m21 * k, this->m22 * k, this->m23 * k,
+                this->m31 * k, this->m32 * k, this->m33 * k);
+}
+
+/**
+ * multiplies the Matrix by a Vector returning a Vector of the result
+ * @param v the Vector the matrix will be multiplied with
+ * @returns the result of the Multiplication
+ */
+Vector Matrix::operator* (const Vector& v) const
+{
+  return Vector (this->m11*v.x + this->m12*v.y + this->m13*v.z,
+                 this->m21*v.x + this->m22*v.y + this->m23*v.z,
+                 this->m31*v.x + this->m32*v.y + this->m33*v.z );
+}
+
+/**
+ * @returns a Transposed copy of this Matrix
+ */
+Matrix Matrix::getTransposed() const
+{
+  return Matrix( this->m11, this->m21, this->m31,
+                 this->m12, this->m22, this->m32,
+                 this->m13, this->m23, this->m33);
+}
+
+/**
+ * converts the Matrix into 3 Vector, and returns them in m1, m2 and m3
+ * @param m1 the first Column of the Matrix as a Vector
+ * @param m2 the second Column of the Matrix as a Vector
+ * @param m3 the third Column of the Matrix as a Vector
+ */
+void Matrix::toVectors(Vector& m1, Vector& m2, Vector& m3) const
+{
+  m1 = Vector(this->m11, this->m21, this->m31);
+  m2 = Vector(this->m12, this->m22, this->m32);
+  m3 = Vector(this->m13, this->m23, this->m33);
+}
+
+/**
+ * @returns the Determinant of this Matrix
+ */
+float Matrix::getDeterminant() const
+{
+  return this->m11*(this->m22*this->m33 - this->m23*this->m32) -
+      this->m12*(this->m21*this->m33 - this->m23*this->m31) +
+      this->m13*(this->m21*this->m32 - this->m22*this->m31);
+}
+
+/**
+ * calculates an returns the EingenValues of this Matrix.
+ * @param eigneValues the Values calculated in a Vector
+ * @returns the Count of found eigenValues
+ *
+ * This Function calculates the EigenValues of a 3x3-Matrix explicitly.
+ * the Returned value eigenValues has the Values stored in Vector form
+ * The Vector will be filled upside down, meaning if the count of found
+ * eingenValues is 1 the only value will be located in eigneValues.x
+ */
+int Matrix::getEigenValues(Vector& eigenValues) const
+{
+  int retVal = -1;
+  float a = 0;
+  float b = 0;
+
+  float c[3];
+
+  // c[0] is the determinante of mat
+  c[0] = this->m11 * this->m22 * this->m33 +
+      2* this->m12 * this->m13 * this->m23 -
+      this->m11 * this->m23 * this->m23 -
+      this->m22 * this->m13 * this->m13 -
+      this->m33 * this->m12 * this->m12;
+
+  // c[1] is the trace of a
+  c[1] = this->m11 * this->m22 -
+      this->m12 * this->m12 +
+      this->m11 * this->m33 -
+      this->m13 * this->m13 +
+      this->m22 * this->m33 -
+      this->m23 * this->m23;
+
+  // c[2] is the sum of the diagonal elements
+  c[2] = this->m11 +
+      this->m22 +
+      this->m33;
+
+
+  // Computing the roots:
+  a = (3.0*c[1] - c[2]*c[2]) / 3.0;
+  b = (-2.0*c[2]*c[2]*c[2] + 9.0*c[1]*c[2] - 27.0*c[0]) / 27.0;
+
+  float Q = b*b/4.0 + a*a*a/27.0;
+
+  // 3 distinct Roots
+  if (Q < 0)
+  {
+    float psi = atan2(sqrt(-Q), -b/2.0);
+    float p = sqrt((b/2.0)*(b/2.0) - Q);
+
+    eigenValues.x = c[2]/3.0 + 2 * pow(p, 1/3.0) * cos(psi/3.0);
+    eigenValues.y = c[2]/3.0 - pow(p, 1/3.0) * (cos(psi/3.0)
+        + sqrt(3.0) * sin(psi/3.0));
+    eigenValues.z = c[2]/3.0 - pow(p, 1/3.0) * (cos(psi/3.0)
+        - sqrt(3.0) * sin(psi/3.0));
+    retVal = 3;
+  }
+  // 2 Distinct Roots
+  else if (Q == 0)
+  {
+    eigenValues.x = eigenValues.y = c[2]/3.0 + pow(b/2.0, 1.0/3.0);
+    eigenValues.z = c[2]/3.0 + 2* pow(b/2.0, 1.0/3.0);
+    retVal = 2;
+  }
+  // 1 Root (not calculating anything.)
+  else if (Q > 0)
+  {
+    eigenValues.x = eigenValues.y = eigenValues.z = 1;
+    retVal = 1;
+  }
+  return retVal;
+}
+
+/**
+ * calculates and returns the EigenVectors of this function as Vectors.
+ * @param eigVc1 the first eigenVector will be stored here.
+ * @param eigVc2 the second eigenVector will be stored here.
+ * @param eigVc3 the third eigenVector will be stored here.
+ */
+void Matrix::getEigenVectors(Vector& eigVc1, Vector& eigVc2, Vector& eigVc3) const
+{
+  Vector eigenValues;
+  int eigenValuesCount = this->getEigenValues(eigenValues);
+
+  if (eigenValuesCount == 2 || eigenValuesCount == 3)
+  {
+    /* eigenvec creation */
+    eigVc1.x = -1/this->m13*(this->m33 - eigenValues.x) +
+        (this->m32*(-this->m31*this->m32 + this->m12*this->m33 - this->m12*eigenValues.x)) /
+        this->m13*(-this->m13*this->m22 - this->m12*this->m23 + this->m13*eigenValues.x);
+
+    eigVc1.y = -( -this->m13*this->m23 + this->m12*this->m33 - this->m12*eigenValues.x) /
+        (-this->m31*this->m22 + this->m12*this->m23 + this->m13*eigenValues.x);
+
+    eigVc1.z = 1.0f;
+
+    eigVc2.x = -1/this->m13*(this->m33 - eigenValues.y) +
+        (this->m32*(-this->m31*this->m32 + this->m12*this->m33 - this->m12*eigenValues.y)) /
+        this->m13*(-this->m13*this->m22 - this->m12*this->m23 + this->m13*eigenValues.y);
+
+    eigVc2.y = -( -this->m13*this->m23 + this->m12*this->m33 - this->m12*eigenValues.y) /
+        (-this->m31*this->m22 + this->m12*this->m23 + this->m13*eigenValues.y);
+
+    eigVc2.z = 1.0f;
+
+    eigVc3 = eigVc1.cross(eigVc2);
+  }
+  else if (eigenValuesCount == 1)
+  {
+    eigVc1 = Vector(1,0,0);
+    eigVc2 = Vector(0,1,0);
+    eigVc3 = Vector(0,0,1);
+  }
+  eigVc1.normalize();
+  eigVc2.normalize();
+  eigVc3.normalize();
+}
+
+/**
+ * prints out some nice debug information
+ */
+void Matrix::debug() const
+{
+  printf("| %f | %f | %f |\n", this->m11, this->m12, this->m13 );
+  printf("| %f | %f | %f |\n", this->m21, this->m22, this->m23 );
+  printf("| %f | %f | %f |\n", this->m31, this->m32, this->m33 );
+
+}
+
Index: branches/network/src/lib/math/matrix.h
===================================================================
--- branches/network/src/lib/math/matrix.h	(revision 6636)
+++ branches/network/src/lib/math/matrix.h	(revision 6636)
@@ -0,0 +1,48 @@
+/*!
+ * @file matrix.h
+ * @brief Definition of a 3x3 matrix.
+ */
+
+#include <math.h>
+#include "vector.h"
+
+//! Matrix is a 3x3 Matrix class with most important functions
+class Matrix
+{
+  public:
+    Matrix() : m11(0), m12(0), m13(0), m21(0), m22(0), m23(0), m31(0), m32(0), m33(0) { };
+
+    Matrix ( float m11, float m12, float m13,
+             float m21, float m22, float m23,
+             float m31, float m32, float m33 );
+    Matrix(const float m[3][3]);
+
+    Matrix operator+ (const Matrix& m) const;
+    Matrix operator- (const Matrix& m) const;
+    Matrix operator* (float k) const;
+    Vector operator* (const Vector& v) const;
+
+    Matrix getTransposed() const;
+    void toVectors(Vector& m1, Vector& m2, Vector& m3) const;
+
+    float getDeterminant() const;
+
+    int getEigenValues(Vector& eigenVectors) const;
+    void getEigenVectors(Vector& a, Vector& b, Vector& c) const;
+
+    /** @returns the Identity-Matrix (diagonal 3x3 with 1's everywhere) */
+    static Matrix identity() { return Matrix(1,0,0, 0,1,0, 0,0,1); }
+
+    void debug() const;
+
+  public:
+    float m11;              //!< Matrix Entry [0][0]
+          float m12;        //!< Matrix Entry [0][1]
+                float m13;  //!< Matrix Entry [0][2]
+    float m21;              //!< Matrix Entry [1][0]
+          float m22;        //!< Matrix Entry [1][1]
+                float m23;  //!< Matrix Entry [1][2]
+    float m31;              //!< Matrix Entry [2][0]
+          float m32;        //!< Matrix Entry [2][1]
+                float m33;  //!< Matrix Entry [2][2]
+};
Index: branches/network/src/lib/math/plane.cc
===================================================================
--- branches/network/src/lib/math/plane.cc	(revision 6636)
+++ branches/network/src/lib/math/plane.cc	(revision 6636)
@@ -0,0 +1,344 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_MATH
+
+#include "plane.h"
+#ifdef DEBUG
+  #include "debug.h"
+#else
+  #include <stdio.h>
+  #define PRINT(x) printf
+#endif
+
+using namespace std;
+
+/**
+ *  create a rotation from a vector
+ * @param v: a vector
+*/
+Rotation::Rotation (const Vector& v)
+{
+  Vector x = Vector( 1, 0, 0);
+  Vector axis = x.cross( v);
+  axis.normalize();
+  float angle = angleRad( x, v);
+  float ca = cos(angle);
+  float sa = sin(angle);
+  m[0] = 1.0f+(1.0f-ca)*(axis.x*axis.x-1.0f);
+  m[1] = -axis.z*sa+(1.0f-ca)*axis.x*axis.y;
+  m[2] = axis.y*sa+(1.0f-ca)*axis.x*axis.z;
+  m[3] = axis.z*sa+(1.0f-ca)*axis.x*axis.y;
+  m[4] = 1.0f+(1.0f-ca)*(axis.y*axis.y-1.0f);
+  m[5] = -axis.x*sa+(1.0f-ca)*axis.y*axis.z;
+  m[6] = -axis.y*sa+(1.0f-ca)*axis.x*axis.z;
+  m[7] = axis.x*sa+(1.0f-ca)*axis.y*axis.z;
+  m[8] = 1.0f+(1.0f-ca)*(axis.z*axis.z-1.0f);
+}
+
+/**
+ *  creates a rotation from an axis and an angle (radians!)
+ * @param axis: the rotational axis
+ * @param angle: the angle in radians
+*/
+Rotation::Rotation (const Vector& axis, float angle)
+{
+  float ca, sa;
+  ca = cos(angle);
+  sa = sin(angle);
+  m[0] = 1.0f+(1.0f-ca)*(axis.x*axis.x-1.0f);
+  m[1] = -axis.z*sa+(1.0f-ca)*axis.x*axis.y;
+  m[2] = axis.y*sa+(1.0f-ca)*axis.x*axis.z;
+  m[3] = axis.z*sa+(1.0f-ca)*axis.x*axis.y;
+  m[4] = 1.0f+(1.0f-ca)*(axis.y*axis.y-1.0f);
+  m[5] = -axis.x*sa+(1.0f-ca)*axis.y*axis.z;
+  m[6] = -axis.y*sa+(1.0f-ca)*axis.x*axis.z;
+  m[7] = axis.x*sa+(1.0f-ca)*axis.y*axis.z;
+  m[8] = 1.0f+(1.0f-ca)*(axis.z*axis.z-1.0f);
+}
+
+/**
+ *  creates a rotation from euler angles (pitch/yaw/roll)
+ * @param pitch: rotation around z (in radians)
+ * @param yaw: rotation around y (in radians)
+ * @param roll: rotation around x (in radians)
+*/
+Rotation::Rotation ( float pitch, float yaw, float roll)
+{
+  float cy, sy, cr, sr, cp, sp;
+  cy = cos(yaw);
+  sy = sin(yaw);
+  cr = cos(roll);
+  sr = sin(roll);
+  cp = cos(pitch);
+  sp = sin(pitch);
+  m[0] = cy*cr;
+  m[1] = -cy*sr;
+  m[2] = sy;
+  m[3] = cp*sr+sp*sy*cr;
+  m[4] = cp*cr-sp*sr*sy;
+  m[5] = -sp*cy;
+  m[6] = sp*sr-cp*sy*cr;
+  m[7] = sp*cr+cp*sy*sr;
+  m[8] = cp*cy;
+}
+
+/**
+ *  creates a nullrotation (an identity rotation)
+*/
+Rotation::Rotation ()
+{
+  m[0] = 1.0f;
+  m[1] = 0.0f;
+  m[2] = 0.0f;
+  m[3] = 0.0f;
+  m[4] = 1.0f;
+  m[5] = 0.0f;
+  m[6] = 0.0f;
+  m[7] = 0.0f;
+  m[8] = 1.0f;
+}
+
+/**
+ *  fills the specified buffer with a 4x4 glmatrix
+ * @param buffer: Pointer to an array of 16 floats
+
+   Use this to get the rotation in a gl-compatible format
+*/
+void Rotation::glmatrix (float* buffer)
+{
+        buffer[0] = m[0];
+        buffer[1] = m[3];
+        buffer[2] = m[6];
+        buffer[3] = m[0];
+        buffer[4] = m[1];
+        buffer[5] = m[4];
+        buffer[6] = m[7];
+        buffer[7] = m[0];
+        buffer[8] = m[2];
+        buffer[9] = m[5];
+        buffer[10] = m[8];
+        buffer[11] = m[0];
+        buffer[12] = m[0];
+        buffer[13] = m[0];
+        buffer[14] = m[0];
+        buffer[15] = m[1];
+}
+
+/**
+ *  multiplies two rotational matrices
+ * @param r: another Rotation
+ * @return the matrix product of the Rotations
+
+   Use this to rotate one rotation by another
+*/
+Rotation Rotation::operator* (const Rotation& r)
+{
+        Rotation p;
+
+        p.m[0] = m[0]*r.m[0] + m[1]*r.m[3] + m[2]*r.m[6];
+        p.m[1] = m[0]*r.m[1] + m[1]*r.m[4] + m[2]*r.m[7];
+        p.m[2] = m[0]*r.m[2] + m[1]*r.m[5] + m[2]*r.m[8];
+
+        p.m[3] = m[3]*r.m[0] + m[4]*r.m[3] + m[5]*r.m[6];
+        p.m[4] = m[3]*r.m[1] + m[4]*r.m[4] + m[5]*r.m[7];
+        p.m[5] = m[3]*r.m[2] + m[4]*r.m[5] + m[5]*r.m[8];
+
+        p.m[6] = m[6]*r.m[0] + m[7]*r.m[3] + m[8]*r.m[6];
+        p.m[7] = m[6]*r.m[1] + m[7]*r.m[4] + m[8]*r.m[7];
+        p.m[8] = m[6]*r.m[2] + m[7]*r.m[5] + m[8]*r.m[8];
+
+        return p;
+}
+
+
+/**
+ *  rotates the vector by the given rotation
+ * @param v: a vector
+ * @param r: a rotation
+ * @return the rotated vector
+*/
+Vector rotateVector( const Vector& v, const Rotation& r)
+{
+  Vector t;
+
+  t.x = v.x * r.m[0] + v.y * r.m[1] + v.z * r.m[2];
+  t.y = v.x * r.m[3] + v.y * r.m[4] + v.z * r.m[5];
+  t.z = v.x * r.m[6] + v.y * r.m[7] + v.z * r.m[8];
+
+  return t;
+}
+
+/**
+ *  calculate the distance between two lines
+ * @param l: the other line
+ * @return the distance between the lines
+*/
+float Line::distance (const Line& l) const
+{
+  float q, d;
+  Vector n = a.cross(l.a);
+  q = n.dot(r-l.r);
+  d = n.len();
+  if( d == 0.0) return 0.0;
+  return q/d;
+}
+
+/**
+ *  calculate the distance between a line and a point
+ * @param v: the point
+ * @return the distance between the Line and the point
+*/
+float Line::distancePoint (const Vector& v) const
+{
+  Vector d = v-r;
+  Vector u = a * d.dot( a);
+  return (d - u).len();
+}
+
+/**
+ *  calculate the distance between a line and a point
+ * @param v: the point
+ * @return the distance between the Line and the point
+ */
+float Line::distancePoint (const sVec3D& v) const
+{
+  Vector s(v[0], v[1], v[2]);
+  Vector d = s - r;
+  Vector u = a * d.dot( a);
+  return (d - u).len();
+}
+
+/**
+ *  calculate the two points of minimal distance of two lines
+ * @param l: the other line
+ * @return a Vector[2] (!has to be deleted after use!) containing the two points of minimal distance
+*/
+Vector* Line::footpoints (const Line& l) const
+{
+  Vector* fp = new Vector[2];
+  Plane p = Plane (r + a.cross(l.a), r, r + a);
+  fp[1] = p.intersectLine (l);
+  p = Plane (fp[1], l.a);
+  fp[0] = p.intersectLine (*this);
+  return fp;
+}
+
+/**
+  \brief calculate the length of a line
+  \return the lenght of the line
+*/
+float Line::len() const
+{
+  return a.len();
+}
+
+/**
+ *  rotate the line by given rotation
+ * @param rot: a rotation
+*/
+void Line::rotate (const Rotation& rot)
+{
+  Vector t = a + r;
+  t = rotateVector( t, rot);
+  r = rotateVector( r, rot),
+  a = t - r;
+}
+
+/**
+ *  create a plane from three points
+ * @param a: first point
+ * @param b: second point
+ * @param c: third point
+*/
+Plane::Plane (const Vector& a, const Vector& b, const Vector& c)
+{
+  n = (a-b).cross(c-b);
+  k = -(n.x*b.x+n.y*b.y+n.z*b.z);
+}
+
+/**
+ *  create a plane from anchor point and normal
+ * @param norm: normal vector
+ * @param p: anchor point
+*/
+Plane::Plane (const Vector& norm, const Vector& p)
+{
+  n = norm;
+  k = -(n.x*p.x+n.y*p.y+n.z*p.z);
+}
+
+
+/**
+  *  create a plane from anchor point and normal
+  * @param norm: normal vector
+  * @param p: anchor point
+*/
+Plane::Plane (const Vector& norm, const sVec3D& g)
+{
+  Vector p(g[0], g[1], g[2]);
+  n = norm;
+  k = -(n.x*p.x+n.y*p.y+n.z*p.z);
+}
+
+
+/**
+ *  returns the intersection point between the plane and a line
+ * @param l: a line
+*/
+Vector Plane::intersectLine (const Line& l) const
+{
+  if (n.x*l.a.x+n.y*l.a.y+n.z*l.a.z == 0.0) return Vector(0,0,0);
+  float t = (n.x*l.r.x+n.y*l.r.y+n.z*l.r.z+k) / (n.x*l.a.x+n.y*l.a.y+n.z*l.a.z);
+  return l.r + (l.a * t);
+}
+
+/**
+ *  returns the distance between the plane and a point
+ * @param p: a Point
+ * @return the distance between the plane and the point (can be negative)
+*/
+float Plane::distancePoint (const Vector& p) const
+{
+  float l = n.len();
+  if( l == 0.0) return 0.0;
+  return (n.dot(p) + k) / n.len();
+}
+
+
+/**
+ *  returns the distance between the plane and a point
+ * @param p: a Point
+ * @return the distance between the plane and the point (can be negative)
+ */
+float Plane::distancePoint (const sVec3D& p) const
+{
+  Vector s(p[0], p[1], p[2]);
+  float l = n.len();
+  if( l == 0.0) return 0.0;
+  return (n.dot(s) + k) / n.len();
+}
+
+
+/**
+ *  returns the side a point is located relative to a Plane
+ * @param p: a Point
+ * @return 0 if the point is contained within the Plane, positive(negative) if the point is in the positive(negative) semi-space of the Plane
+*/
+float Plane::locatePoint (const Vector& p) const
+{
+  return (n.dot(p) + k);
+}
+
Index: branches/network/src/lib/math/plane.h
===================================================================
--- branches/network/src/lib/math/plane.h	(revision 6636)
+++ branches/network/src/lib/math/plane.h	(revision 6636)
@@ -0,0 +1,89 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: ...
+*/
+
+/*!
+ * @file plane.h
+ * A basic 3D plane math framework
+ *
+ * Contains class to handle planes
+*/
+
+#ifndef __PLANE_H_
+#define __PLANE_H_
+
+#include <math.h>
+#include "compiler.h"
+#include "vector.h"
+#include "line.h"
+
+//! 3D plane
+/**
+  Class to handle planes in 3-dimensional space
+
+  Critical for polygon-based collision detection
+*/
+class Plane
+{
+  public:
+
+  Vector n;   //!< Normal vector
+  float k;    //!< Offset constant
+
+  Plane (const Vector& a, const Vector& b, const Vector& c);
+  Plane (const Vector& norm, const Vector& p);
+  Plane (const Vector& norm, const sVec3D& p);
+  Plane (const Vector& n, float k) : n(n), k(k) {} //!< assignment constructor
+  Plane () : n(Vector(1,1,1)), k(0) {}
+  ~Plane () {}
+
+  Vector intersectLine (const Line& l) const;
+  float distancePoint (const Vector& p) const;
+  float distancePoint (const sVec3D& p) const;
+  float locatePoint (const Vector& p) const;
+};
+
+
+
+//! A class that represents a rectangle, this is needed for SpatialSeparation
+class Rectangle
+{
+
+  public:
+    Rectangle() { this->center = Vector(); }
+    Rectangle(const Vector &center, float len) { this->center = Vector(center.x, center.y, center.z); this->axis[0] = len; this->axis[1] = len; }
+    virtual ~Rectangle() {}
+
+    /** \brief sets the center of the rectangle to a defined vector @param center the new center */
+   inline void setCenter(const Vector &center) { this->center = center;}
+    /** \brief sets the center of the rectangle to a defined vector @param x coord of the center @param y coord of the center @param z coord of the center */
+   inline void setCenter(float x, float y, float z) { this->center.x = x; this->center.y = y; this->center.z = z; }
+   /** \brief returns the center of the rectangle to a defined vector @returns center the new center */
+   inline const Vector& getCenter() const { return this->center; }
+
+   /** \brief sets both axis of the rectangle to a defined vector @param unityLength the new center */
+   inline void setAxis(float unityLength) { this->axis[0] = unityLength; this->axis[1] = unityLength; }
+   /** \brief sets both axis of the rectangle to a defined vector @param v1 the length of the x axis @param v2 the length of the z axis*/
+   inline void setAxis(float v1, float v2) { this->axis[0] = v1; this->axis[1] = v2; }
+   /** \brief gets one axis length of the rectangle  @returns the length of the axis 0 */
+   inline float getAxis() { return this-> axis[0]; }
+
+  private:
+    Vector          center;
+    float           axis[2];
+};
+
+
+#endif /* __PLANE_H_ */
+
Index: branches/network/src/lib/math/quaternion.cc
===================================================================
--- branches/network/src/lib/math/quaternion.cc	(revision 6636)
+++ branches/network/src/lib/math/quaternion.cc	(revision 6636)
@@ -0,0 +1,238 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: Patrick Boenzli : Vector::scale()
+                                    Vector::abs()
+
+   Quaternion code borrowed from an Gamasutra article by Nick Bobick and Ken Shoemake
+
+   2005-06-02: Benjamin Grauer: speed up, and new Functionality to Vector (mostly inline now)
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_MATH
+
+#include "quaternion.h"
+#ifdef DEBUG
+  #include "debug.h"
+#else
+  #include <stdio.h>
+  #define PRINT(x) printf
+#endif
+
+using namespace std;
+
+/////////////////
+/* QUATERNIONS */
+/////////////////
+/**
+ *  calculates a lookAt rotation
+ * @param dir: the direction you want to look
+ * @param up: specify what direction up should be
+
+   Mathematically this determines the rotation a (0,0,1)-Vector has to undergo to point
+   the same way as dir. If you want to use this with cameras, you'll have to reverse the
+   dir Vector (Vector(0,0,0) - your viewing direction) or you'll point the wrong way. You
+   can use this for meshes as well (then you do not have to reverse the vector), but keep
+   in mind that if you do that, the model's front has to point in +z direction, and left
+   and right should be -x or +x respectively or the mesh wont rotate correctly.
+ *
+ * @TODO !!! OPTIMIZE THIS !!!
+ */
+Quaternion::Quaternion (const Vector& dir, const Vector& up)
+{
+  Vector z = dir.getNormalized();
+  Vector x = up.cross(z).getNormalized();
+  Vector y = z.cross(x);
+
+  float m[4][4];
+  m[0][0] = x.x;
+  m[0][1] = x.y;
+  m[0][2] = x.z;
+  m[0][3] = 0;
+  m[1][0] = y.x;
+  m[1][1] = y.y;
+  m[1][2] = y.z;
+  m[1][3] = 0;
+  m[2][0] = z.x;
+  m[2][1] = z.y;
+  m[2][2] = z.z;
+  m[2][3] = 0;
+  m[3][0] = 0;
+  m[3][1] = 0;
+  m[3][2] = 0;
+  m[3][3] = 1;
+
+  *this = Quaternion (m);
+}
+
+/**
+ *  calculates a rotation from euler angles
+ * @param roll: the roll in radians
+ * @param pitch: the pitch in radians
+ * @param yaw: the yaw in radians
+ */
+Quaternion::Quaternion (float roll, float pitch, float yaw)
+{
+  float cr, cp, cy, sr, sp, sy, cpcy, spsy;
+
+  // calculate trig identities
+  cr = cos(roll/2);
+  cp = cos(pitch/2);
+  cy = cos(yaw/2);
+
+  sr = sin(roll/2);
+  sp = sin(pitch/2);
+  sy = sin(yaw/2);
+
+  cpcy = cp * cy;
+  spsy = sp * sy;
+
+  w = cr * cpcy + sr * spsy;
+  v.x = sr * cpcy - cr * spsy;
+  v.y = cr * sp * cy + sr * cp * sy;
+  v.z = cr * cp * sy - sr * sp * cy;
+}
+
+/**
+ *  convert the Quaternion to a 4x4 rotational glMatrix
+ * @param m: a buffer to store the Matrix in
+ */
+void Quaternion::matrix (float m[4][4]) const
+{
+  float wx, wy, wz, xx, yy, yz, xy, xz, zz, x2, y2, z2;
+
+  // calculate coefficients
+  x2 = v.x + v.x;
+  y2 = v.y + v.y;
+  z2 = v.z + v.z;
+  xx = v.x * x2; xy = v.x * y2; xz = v.x * z2;
+  yy = v.y * y2; yz = v.y * z2; zz = v.z * z2;
+  wx = w * x2; wy = w * y2; wz = w * z2;
+
+  m[0][0] = 1.0 - (yy + zz); m[1][0] = xy - wz;
+  m[2][0] = xz + wy; m[3][0] = 0.0;
+
+  m[0][1] = xy + wz; m[1][1] = 1.0 - (xx + zz);
+  m[2][1] = yz - wx; m[3][1] = 0.0;
+
+  m[0][2] = xz - wy; m[1][2] = yz + wx;
+  m[2][2] = 1.0 - (xx + yy); m[3][2] = 0.0;
+
+  m[0][3] = 0; m[1][3] = 0;
+  m[2][3] = 0; m[3][3] = 1;
+}
+
+/**
+ *  performs a smooth move.
+ * @param from  where
+ * @param to where
+ * @param t the time this transformation should take value [0..1]
+ * @returns the Result of the smooth move
+ */
+Quaternion Quaternion::quatSlerp(const Quaternion& from, const Quaternion& to, float t)
+{
+  float tol[4];
+  double omega, cosom, sinom, scale0, scale1;
+  //  float DELTA = 0.2;
+
+  cosom = from.v.x * to.v.x + from.v.y * to.v.y + from.v.z * to.v.z + from.w * to.w;
+
+  if( cosom < 0.0 )
+    {
+      cosom = -cosom;
+      tol[0] = -to.v.x;
+      tol[1] = -to.v.y;
+      tol[2] = -to.v.z;
+      tol[3] = -to.w;
+    }
+  else
+    {
+      tol[0] = to.v.x;
+      tol[1] = to.v.y;
+      tol[2] = to.v.z;
+      tol[3] = to.w;
+    }
+
+  omega = acos(cosom);
+  sinom = sin(omega);
+  scale0 = sin((1.0 - t) * omega) / sinom;
+  scale1 = sin(t * omega) / sinom;
+  return Quaternion(Vector(scale0 * from.v.x + scale1 * tol[0],
+                    scale0 * from.v.y + scale1 * tol[1],
+                    scale0 * from.v.z + scale1 * tol[2]),
+                    scale0 * from.w + scale1 * tol[3]);
+}
+
+
+/**
+ *  convert a rotational 4x4 glMatrix into a Quaternion
+ * @param m: a 4x4 matrix in glMatrix order
+ */
+Quaternion::Quaternion (float m[4][4])
+{
+
+  float  tr, s, q[4];
+  int    i, j, k;
+
+  int nxt[3] = {1, 2, 0};
+
+  tr = m[0][0] + m[1][1] + m[2][2];
+
+        // check the diagonal
+  if (tr > 0.0)
+  {
+    s = sqrt (tr + 1.0);
+    w = s / 2.0;
+    s = 0.5 / s;
+    v.x = (m[1][2] - m[2][1]) * s;
+    v.y = (m[2][0] - m[0][2]) * s;
+    v.z = (m[0][1] - m[1][0]) * s;
+        }
+        else
+        {
+                // diagonal is negative
+        i = 0;
+        if (m[1][1] > m[0][0]) i = 1;
+    if (m[2][2] > m[i][i]) i = 2;
+    j = nxt[i];
+    k = nxt[j];
+
+    s = sqrt ((m[i][i] - (m[j][j] + m[k][k])) + 1.0);
+
+    q[i] = s * 0.5;
+
+    if (s != 0.0) s = 0.5 / s;
+
+          q[3] = (m[j][k] - m[k][j]) * s;
+    q[j] = (m[i][j] + m[j][i]) * s;
+    q[k] = (m[i][k] + m[k][i]) * s;
+
+        v.x = q[0];
+        v.y = q[1];
+        v.z = q[2];
+        w = q[3];
+  }
+}
+
+/**
+ *  outputs some nice formated debug information about this quaternion
+*/
+void Quaternion::debug()
+{
+  PRINT(0)("real a=%f; imag: x=%f y=%f z=%f\n", w, v.x, v.y, v.z);
+}
+
+void Quaternion::debug2()
+{
+  Vector axis = this->getSpacialAxis();
+  PRINT(0)("angle = %f, axis: ax=%f, ay=%f, az=%f\n", this->getSpacialAxisAngle(), axis.x, axis.y, axis.z );
+}
Index: branches/network/src/lib/math/quaternion.h
===================================================================
--- branches/network/src/lib/math/quaternion.h	(revision 6636)
+++ branches/network/src/lib/math/quaternion.h	(revision 6636)
@@ -0,0 +1,116 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: ...
+*/
+
+/*!
+ * @file quaternion.h
+ * A basic 3D quaternion math framework
+ *
+ * Contains classes to handle vectors, lines, rotations and planes
+*/
+
+#ifndef __QUATERNION_H_
+#define __QUATERNION_H_
+
+#include <math.h>
+#include "compiler.h"
+//! PI the circle-constant
+#define PI 3.14159265359f
+#include "vector.h"
+
+//! Quaternion
+/**
+   Class to handle 3-dimensional rotation efficiently
+*/
+class Quaternion
+{
+ public:
+  /** creates a Default quaternion (multiplicational identity Quaternion)*/
+  inline Quaternion () { w = 1; v = Vector(0,0,0); }
+  /** creates a Quaternion looking into the direction v @param v: the direction @param f: the value */
+  inline Quaternion (const Vector& v, float f) { this->w = f; this->v = v; }
+  Quaternion (float m[4][4]);
+  /** turns a rotation along an axis into a Quaternion @param angle: the amount of radians to rotate @param axis: the axis to rotate around */
+  inline Quaternion (float angle, const Vector& axis) { w = cos(angle/2.0); v = axis * sin(angle/2.0); }
+  Quaternion (const Vector& dir, const Vector& up);
+  Quaternion (float roll, float pitch, float yaw);
+
+  /** @param q: the Quaternion to compare with this one. @returns true if the Quaternions are the same, false otherwise */
+  inline bool operator== (const Quaternion& q) const { return (unlikely(this->v==q.v&&this->w==q.w))?true:false; };
+  /** @param f: a real value @return a Quaternion containing the quotient */
+  inline Quaternion operator/ (const float& f) const { return (unlikely(f==0.0)) ? Quaternion() : Quaternion(this->v/f, this->w/f); };
+  /** @param f: the value to divide by @returns the quaternion devided by f (this /= f) */
+  inline const Quaternion& operator/= (const float& f) {*this = *this / f; return *this;}
+  /** @param f: a real value @return a Quaternion containing the product */
+  inline Quaternion operator* (const float& f) const { return Quaternion(this->v*f, this->w*f); };
+  /** @param f: the value to multiply by @returns the quaternion multiplied by f (this *= f) */
+  inline const Quaternion& operator*= (const float& f) {*this = *this * f; return *this;}
+  /** @param q: another Quaternion to rotate this by @return a quaternion that represents the first one rotated by the second one (WARUNING: this operation is not commutative! e.g. (A*B) != (B*A)) */
+  Quaternion operator* (const Quaternion& q) const { return Quaternion(Vector(this->w*q.v.x + this->v.x*q.w + this->v.y*q.v.z - this->v.z*q.v.y,
+                                                                         this->w*q.v.y + this->v.y*q.w + this->v.z*q.v.x - this->v.x*q.v.z,
+                                                                         this->w*q.v.z + this->v.z*q.w + this->v.x*q.v.y - this->v.y*q.v.x),
+                                                                         this->w*q.w - this->v.x*q.v.x - this->v.y*q.v.y - this->v.z*q.v.z); };
+  /** @param q: the Quaternion to multiply by @returns the quaternion multiplied by q (this *= q) */
+  inline const Quaternion& operator*= (const Quaternion& q) {*this = *this * q; return *this; };
+  /** @param q the Quaternion by which to devide @returns the division from this by q (this / q) */
+  inline Quaternion operator/ (const Quaternion& q) const { return *this * q.inverse(); };
+  /** @param q the Quaternion by which to devide @returns the division from this by q (this /= q) */
+  inline const Quaternion& operator/= (const Quaternion& q) { *this = *this * q.inverse(); return *this; };
+  /** @param q the Quaternion to add to this @returns the quaternion added with q (this + q) */
+  inline Quaternion operator+ (const Quaternion& q) const { return Quaternion(q.v + v, q.w + w); };
+  /** @param q the Quaternion to add to this @returns the quaternion added with q (this += q) */
+  inline const Quaternion& operator+= (const Quaternion& q) { this->v += q.v; this->w += q.w; return *this; };
+  /** @param q the Quaternion to substrace from this @returns the quaternion substracted by q (this - q) */
+  inline Quaternion operator- (const Quaternion& q) const { return Quaternion(q.v - v, q.w - w); }
+  /** @param q the Quaternion to substrace from this @returns the quaternion substracted by q (this -= q) */
+  inline const Quaternion& operator-= (const Quaternion& q) { this->v -= q.v; this->w -= q.w; return *this; };
+  /** copy constructor @param q: the Quaternion to set this to. @returns the Quaternion q (or this) */
+  inline Quaternion operator= (const Quaternion& q) {this->v = q.v; this->w = q.w; return *this;}
+  /** conjugates this Quaternion @returns the conjugate */
+  inline Quaternion conjugate () const { return Quaternion(Vector(-v.x, -v.y, -v.z), this->w); };
+  /** @returns the norm of The Quaternion */
+  inline float norm () const { return sqrt(w*w + v.x*v.x + v.y*v.y + v.z*v.z); };
+  /** @returns the inverted Quaterntion of this */
+  inline Quaternion inverse () const { return conjugate() / (w*w + v.x*v.x + v.y*v.y + v.z*v.z); };
+  /** @returns the dot Product of a Quaternion */
+  inline float dot (const Quaternion& q) const { return v.x*q.v.x + v.y*q.v.y + v.z*q.v.z + w*q.w; };
+  /** @retuns the Distance between two Quaternions */
+  inline float distance(const Quaternion& q) const { return 2*acos(fabsf(this->dot(q))); };
+  /** @param v: the Vector  @return a new Vector representing v rotated by the Quaternion */
+  inline Vector apply (const Vector& v) const { return (*this * Quaternion(v, 0) * conjugate()).v; };
+  void matrix (float m[4][4]) const;
+  /** @returns the normalized Quaternion (|this|) */
+  inline Quaternion getNormalized() const { float n = this->norm(); return Quaternion(this->v/n, this->w/n); };
+  /** normalizes the current Quaternion */
+  inline void normalize() { float n = this->norm(); this->v /= n; this->w/=n; };
+
+  /** @returns the rotational axis of this Quaternion */
+  inline Vector getSpacialAxis() const { return this->v / sin(acos(w));/*sqrt(v.x*v.x + v.y*v.y + v.z+v.z);*/ };
+  /** @returns the rotational angle of this Quaternion around getSpacialAxis()  !! IN DEGREE !! */
+  inline float getSpacialAxisAngle() const { return 360.0 / M_PI * acos( this->w ); };
+
+  static Quaternion quatSlerp(const Quaternion& from, const Quaternion& to, float t);
+
+  void debug();
+  void debug2();
+
+
+ public:
+  Vector    v;        //!< Imaginary Vector
+  float     w;        //!< Real part of the number
+};
+
+
+#endif /* __QUATERNION_H_ */
+
Index: branches/network/src/lib/math/rotation_OBSOLETE.cc
===================================================================
--- branches/network/src/lib/math/rotation_OBSOLETE.cc	(revision 6636)
+++ branches/network/src/lib/math/rotation_OBSOLETE.cc	(revision 6636)
@@ -0,0 +1,182 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_MATH
+
+#include "rotation_OBSOLETE.h"
+#ifdef DEBUG
+  #include "debug.h"
+#else
+  #include <stdio.h>
+  #define PRINT(x) printf
+#endif
+
+using namespace std;
+
+/**
+ *  create a rotation from a vector
+ * @param v: a vector
+*/
+Rotation::Rotation (const Vector& v)
+{
+  Vector x = Vector( 1, 0, 0);
+  Vector axis = x.cross( v);
+  axis.normalize();
+  float angle = angleRad( x, v);
+  float ca = cos(angle);
+  float sa = sin(angle);
+  m[0] = 1.0f+(1.0f-ca)*(axis.x*axis.x-1.0f);
+  m[1] = -axis.z*sa+(1.0f-ca)*axis.x*axis.y;
+  m[2] = axis.y*sa+(1.0f-ca)*axis.x*axis.z;
+  m[3] = axis.z*sa+(1.0f-ca)*axis.x*axis.y;
+  m[4] = 1.0f+(1.0f-ca)*(axis.y*axis.y-1.0f);
+  m[5] = -axis.x*sa+(1.0f-ca)*axis.y*axis.z;
+  m[6] = -axis.y*sa+(1.0f-ca)*axis.x*axis.z;
+  m[7] = axis.x*sa+(1.0f-ca)*axis.y*axis.z;
+  m[8] = 1.0f+(1.0f-ca)*(axis.z*axis.z-1.0f);
+}
+
+/**
+ *  creates a rotation from an axis and an angle (radians!)
+ * @param axis: the rotational axis
+ * @param angle: the angle in radians
+*/
+Rotation::Rotation (const Vector& axis, float angle)
+{
+  float ca, sa;
+  ca = cos(angle);
+  sa = sin(angle);
+  m[0] = 1.0f+(1.0f-ca)*(axis.x*axis.x-1.0f);
+  m[1] = -axis.z*sa+(1.0f-ca)*axis.x*axis.y;
+  m[2] = axis.y*sa+(1.0f-ca)*axis.x*axis.z;
+  m[3] = axis.z*sa+(1.0f-ca)*axis.x*axis.y;
+  m[4] = 1.0f+(1.0f-ca)*(axis.y*axis.y-1.0f);
+  m[5] = -axis.x*sa+(1.0f-ca)*axis.y*axis.z;
+  m[6] = -axis.y*sa+(1.0f-ca)*axis.x*axis.z;
+  m[7] = axis.x*sa+(1.0f-ca)*axis.y*axis.z;
+  m[8] = 1.0f+(1.0f-ca)*(axis.z*axis.z-1.0f);
+}
+
+/**
+ *  creates a rotation from euler angles (pitch/yaw/roll)
+ * @param pitch: rotation around z (in radians)
+ * @param yaw: rotation around y (in radians)
+ * @param roll: rotation around x (in radians)
+*/
+Rotation::Rotation ( float pitch, float yaw, float roll)
+{
+  float cy, sy, cr, sr, cp, sp;
+  cy = cos(yaw);
+  sy = sin(yaw);
+  cr = cos(roll);
+  sr = sin(roll);
+  cp = cos(pitch);
+  sp = sin(pitch);
+  m[0] = cy*cr;
+  m[1] = -cy*sr;
+  m[2] = sy;
+  m[3] = cp*sr+sp*sy*cr;
+  m[4] = cp*cr-sp*sr*sy;
+  m[5] = -sp*cy;
+  m[6] = sp*sr-cp*sy*cr;
+  m[7] = sp*cr+cp*sy*sr;
+  m[8] = cp*cy;
+}
+
+/**
+ *  creates a nullrotation (an identity rotation)
+*/
+Rotation::Rotation ()
+{
+  m[0] = 1.0f;
+  m[1] = 0.0f;
+  m[2] = 0.0f;
+  m[3] = 0.0f;
+  m[4] = 1.0f;
+  m[5] = 0.0f;
+  m[6] = 0.0f;
+  m[7] = 0.0f;
+  m[8] = 1.0f;
+}
+
+/**
+ *  fills the specified buffer with a 4x4 glmatrix
+ * @param buffer: Pointer to an array of 16 floats
+
+   Use this to get the rotation in a gl-compatible format
+*/
+void Rotation::glmatrix (float* buffer)
+{
+        buffer[0] = m[0];
+        buffer[1] = m[3];
+        buffer[2] = m[6];
+        buffer[3] = m[0];
+        buffer[4] = m[1];
+        buffer[5] = m[4];
+        buffer[6] = m[7];
+        buffer[7] = m[0];
+        buffer[8] = m[2];
+        buffer[9] = m[5];
+        buffer[10] = m[8];
+        buffer[11] = m[0];
+        buffer[12] = m[0];
+        buffer[13] = m[0];
+        buffer[14] = m[0];
+        buffer[15] = m[1];
+}
+
+/**
+ *  multiplies two rotational matrices
+ * @param r: another Rotation
+ * @return the matrix product of the Rotations
+
+   Use this to rotate one rotation by another
+*/
+Rotation Rotation::operator* (const Rotation& r)
+{
+        Rotation p;
+
+        p.m[0] = m[0]*r.m[0] + m[1]*r.m[3] + m[2]*r.m[6];
+        p.m[1] = m[0]*r.m[1] + m[1]*r.m[4] + m[2]*r.m[7];
+        p.m[2] = m[0]*r.m[2] + m[1]*r.m[5] + m[2]*r.m[8];
+
+        p.m[3] = m[3]*r.m[0] + m[4]*r.m[3] + m[5]*r.m[6];
+        p.m[4] = m[3]*r.m[1] + m[4]*r.m[4] + m[5]*r.m[7];
+        p.m[5] = m[3]*r.m[2] + m[4]*r.m[5] + m[5]*r.m[8];
+
+        p.m[6] = m[6]*r.m[0] + m[7]*r.m[3] + m[8]*r.m[6];
+        p.m[7] = m[6]*r.m[1] + m[7]*r.m[4] + m[8]*r.m[7];
+        p.m[8] = m[6]*r.m[2] + m[7]*r.m[5] + m[8]*r.m[8];
+
+        return p;
+}
+
+
+/**
+ *  rotates the vector by the given rotation
+ * @param v: a vector
+ * @param r: a rotation
+ * @return the rotated vector
+*/
+Vector rotateVector( const Vector& v, const Rotation& r)
+{
+  Vector t;
+
+  t.x = v.x * r.m[0] + v.y * r.m[1] + v.z * r.m[2];
+  t.y = v.x * r.m[3] + v.y * r.m[4] + v.z * r.m[5];
+  t.z = v.x * r.m[6] + v.y * r.m[7] + v.z * r.m[8];
+
+  return t;
+}
Index: branches/network/src/lib/math/rotation_OBSOLETE.h
===================================================================
--- branches/network/src/lib/math/rotation_OBSOLETE.h	(revision 6636)
+++ branches/network/src/lib/math/rotation_OBSOLETE.h	(revision 6636)
@@ -0,0 +1,57 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: ...
+*/
+
+/*!
+ * @file rotation_OBSOLETE.h
+ * A basic 3D rotation framework
+ *
+ * THIS IS AN OBSOLETE FRAMEWORK, AND WILL BE DELETED SOON
+ *
+ *
+ * Contains classes to handle vectors, lines, rotations and planes
+*/
+
+#ifndef __ROTATION_H_
+#define __ROTATION_H_
+
+#include "vector.h"
+
+//! 3D rotation (OBSOLETE)
+/**
+  Class to handle 3-dimensional rotations.
+  Can create a rotation from several inputs, currently stores rotation using a 3x3 Matrix
+*/
+class Rotation {
+  public:
+
+  float m[9]; //!< 3x3 Rotation Matrix
+
+  Rotation ( const Vector& v);
+  Rotation ( const Vector& axis, float angle);
+  Rotation ( float pitch, float yaw, float roll);
+  Rotation ();
+  ~Rotation () {}
+
+  Rotation operator* (const Rotation& r);
+
+  void glmatrix (float* buffer);
+};
+
+//!< Apply a rotation to a vector
+Vector rotateVector( const Vector& v, const Rotation& r);
+
+
+#endif /* __ROTATION_H_ */
+
Index: branches/network/src/lib/math/vector.cc
===================================================================
--- branches/network/src/lib/math/vector.cc	(revision 6636)
+++ branches/network/src/lib/math/vector.cc	(revision 6636)
@@ -0,0 +1,68 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: Patrick Boenzli : Vector::scale()
+                                    Vector::abs()
+
+   Quaternion code borrowed from an Gamasutra article by Nick Bobick and Ken Shoemake
+
+   2005-06-02: Benjamin Grauer: speed up, and new Functionality to Vector (mostly inline now)
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_MATH
+
+#include "vector.h"
+#ifdef DEBUG
+  #include "debug.h"
+#else
+  #include <stdio.h>
+  #define PRINT(x) printf
+#endif
+
+using namespace std;
+
+/////////////
+/* VECTORS */
+/////////////
+/**
+ *  returns the this-vector normalized to length 1.0
+ * @todo there is some error in this function, that i could not resolve. it just does not, what it is supposed to do.
+ */
+Vector Vector::getNormalized() const
+{
+  float l = this->len();
+  if(unlikely(l == 1.0 || l == 0.0))
+    return *this;
+  else
+    return (*this / l);
+}
+
+/**
+ *  Vector is looking in the positive direction on all axes after this
+*/
+Vector Vector::abs()
+{
+  Vector v(fabs(x), fabs(y), fabs(z));
+  return v;
+}
+
+
+
+/**
+ *  Outputs the values of the Vector
+ */
+void Vector::debug() const
+{
+  PRINT(0)("x: %f; y: %f; z: %f", x, y, z);
+  PRINT(0)(" lenght: %f", len());
+  PRINT(0)("\n");
+}
Index: branches/network/src/lib/math/vector.h
===================================================================
--- branches/network/src/lib/math/vector.h	(revision 6636)
+++ branches/network/src/lib/math/vector.h	(revision 6636)
@@ -0,0 +1,127 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: ...
+*/
+
+/*!
+ * @file vector.h
+ * A basic 3D math framework
+ *
+ * Contains classes to handle vectors, lines, rotations and planes
+*/
+
+#ifndef __VECTOR_H_
+#define __VECTOR_H_
+
+#include <math.h>
+#include "compiler.h"
+//! PI the circle-constant
+#define PI 3.14159265359f
+
+
+//! this is a small and performant 3D vector
+typedef float sVec3D[3];
+
+
+//! small and performant 2D vector
+typedef float sVec2D[2];
+
+
+
+//! 3D Vector
+/**
+        Class to handle 3D Vectors
+*/
+class Vector {
+ public:
+  Vector (float x, float y, float z) : x(x), y(y), z(z) {}  //!< assignment constructor
+  Vector () : x(0), y(0), z(0) {}
+  ~Vector () {}
+
+  /** @param v: the Vecor to compare with this one @returns true, if the Vecors are the same, false otherwise */
+  inline bool operator== (const Vector& v) const { return (this->x==v.x&&this->y==v.y&&this->z==v.z)?true:false; };
+  /** @param index The index of the "array" @returns the x/y/z coordinate */
+  inline float operator[] (float index) const {if( index == 0) return this->x; if( index == 1) return this->y; if( index == 2) return this->z; }
+  /** @param v The vector to add @returns the addition between two vectors (this + v) */
+  inline Vector operator+ (const Vector& v) const { return Vector(x + v.x, y + v.y, z + v.z); };
+  /** @param v The vector to add @returns the addition between two vectors (this + v) */
+  inline Vector operator+ (const sVec3D& v) const { return Vector(x + v[0], y + v[1], z + v[2]); };
+  /** @param v The vector to add  @returns the addition between two vectors (this += v) */
+  inline const Vector& operator+= (const Vector& v) { this->x += v.x; this->y += v.y; this->z += v.z; return *this; };
+  /** @param v The vector to substract  @returns the substraction between two vectors (this - v) */
+  inline const Vector& operator+= (const sVec3D& v) { this->x += v[0]; this->y += v[1]; this->z += v[2]; return *this; };
+  /** @param v The vector to substract  @returns the substraction between two vectors (this - v) */
+  inline Vector operator- (const Vector& v) const { return Vector(x - v.x, y - v.y, z - v.z); }
+  /** @param v The vector to substract  @returns the substraction between two vectors (this - v) */
+  inline Vector operator- (const sVec3D& v) const { return Vector(x - v[0], y - v[1], z - v[2]); }
+  /** @param v The vector to substract  @returns the substraction between two vectors (this -= v) */
+  inline const Vector& operator-= (const Vector& v) { this->x -= v.x; this->y -= v.y; this->z -= v.z; return *this; };
+  /** @param v The vector to substract  @returns the substraction between two vectors (this -= v) */
+  inline const Vector& operator-= (const sVec3D& v) { this->x -= v[0]; this->y -= v[1]; this->z -= v[2]; return *this; };
+  /** @param v the second vector  @returns The dotProduct between two vector (this (dot) v) */
+  inline float operator* (const Vector& v) const { return x * v.x + y * v.y + z * v.z; };
+  /** @todo strange */
+  inline const Vector& operator*= (const Vector& v) { this->x *= v.x; this->y *= v.y; this->z *= v.z; return *this; };
+  /** @param f a factor to multiply the vector with @returns the vector multiplied by f (this * f) */
+  inline Vector operator* (float f) const { return Vector(x * f, y * f, z * f); };
+  /** @param f a factor to multiply the vector with @returns the vector multiplied by f (this *= f) */
+  inline const Vector& operator*= (float f) { this->x *= f; this->y *= f; this->z *= f; return *this; };
+  /** @param f a factor to divide the vector with @returns the vector divided by f (this / f) */
+  inline Vector operator/ (float f) const { return (unlikely(f == 0.0))?Vector(0,0,0):Vector(this->x / f, this->y / f, this->z / f); };
+  /** @param f a factor to divide the vector with @returns the vector divided by f (this /= f) */
+  inline const Vector& operator/= (float f) {if (unlikely(f == 0.0)) {this->x=0;this->y=0;this->z=0;} else {this->x /= f; this->y /= f; this->z /= f;} return *this; };
+  /**  copy constructor @todo (i do not know it this is faster) @param v the vector to assign to this vector. @returns the vector v */
+  inline const Vector& operator= (const Vector& v) { this->x = v.x; this->y = v.y; this->z = v.z; return *this; };
+  /** copy constructor* @param v the sVec3D to assign to this vector. @returns the vector v */
+  inline const Vector& operator= (const sVec3D& v) { this->x = v[0]; this->y = v[1]; this->z = v[2]; }
+  /** @param v: the other vector \return the dot product of the vectors */
+  float dot (const Vector& v) const { return x*v.x+y*v.y+z*v.z; };
+  /** @param v: the corss-product partner @returns the cross-product between this and v (this (x) v) */
+  inline Vector cross (const Vector& v) const { return Vector(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x ); }
+  /** scales the this vector with v* @param v the vector to scale this with */
+  void scale(const Vector& v) {   x *= v.x;  y *= v.y; z *= v.z; };
+  /** @returns the length of the vector */
+  inline float len() const { return sqrt (x*x+y*y+z*z); }
+  /** normalizes the vector */
+  inline void normalize() { float l = len(); if( unlikely(l == 0.0))return; this->x=this->x/l; this->y=this->y/l; this->z=this->z/l; };
+  Vector getNormalized() const;
+  Vector abs();
+
+  void debug() const;
+
+ public:
+  float    x;     //!< The x Coordinate of the Vector.
+  float    y;     //!< The y Coordinate of the Vector.
+  float    z;     //!< The z Coordinate of the Vector.
+};
+
+/**
+ *  calculate the angle between two vectors in radiances
+ * @param v1: a vector
+ * @param v2: another vector
+ * @return the angle between the vectors in radians
+*/
+inline float angleDeg (const Vector& v1, const Vector& v2) { return acos( v1 * v2 / (v1.len() * v2.len())); };
+/**
+ *  calculate the angle between two vectors in degrees
+ * @param v1: a vector
+ * @param v2: another vector
+ * @return the angle between the vectors in degrees
+*/
+inline float angleRad (const Vector& v1, const Vector& v2) { return acos( v1 * v2 / (v1.len() * v2.len())) * 180/M_PI; };
+
+/** an easy way to create a Random Vector @param sideLength the length of the Vector (x not sqrt(x^2...)) */
+#define VECTOR_RAND(sideLength)  (Vector((float)rand()/RAND_MAX -.5, (float)rand()/RAND_MAX -.5, (float)rand()/RAND_MAX -.5) * sideLength)
+
+#endif /* __VECTOR_H_ */
+
Index: branches/network/src/lib/math/vector2D.cc
===================================================================
--- branches/network/src/lib/math/vector2D.cc	(revision 6636)
+++ branches/network/src/lib/math/vector2D.cc	(revision 6636)
@@ -0,0 +1,66 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: Patrick Boenzli : Vector2D::scale()
+                                    Vector2D::abs()
+
+   Benjamin Grauer: port to Vector2D
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_MATH
+
+#include "vector2D.h"
+#ifdef DEBUG
+  #include "debug.h"
+#else
+  #include <stdio.h>
+  #define PRINT(x) printf
+#endif
+
+using namespace std;
+
+/////////////
+/* VECTORS */
+/////////////
+/**
+ *  returns the this-vector normalized to length 1.0
+ * @todo there is some error in this function, that i could not resolve. it just does not, what it is supposed to do.
+ */
+Vector2D Vector2D::getNormalized() const
+{
+  float l = this->len();
+  if(unlikely(l == 1.0 || l == 0.0))
+    return *this;
+  else
+    return (*this / l);
+}
+
+/**
+ *  Vector2D is looking in the positive direction on all axes after this
+*/
+Vector2D Vector2D::abs()
+{
+  Vector2D v(fabs(x), fabs(y));
+  return v;
+}
+
+
+
+/**
+ *  Outputs the values of the Vector2D
+ */
+void Vector2D::debug() const
+{
+  PRINT(0)("x: %f; y: %f", x, y);
+  PRINT(0)(" lenght: %f", len());
+  PRINT(0)("\n");
+}
Index: branches/network/src/lib/math/vector2D.h
===================================================================
--- branches/network/src/lib/math/vector2D.h	(revision 6636)
+++ branches/network/src/lib/math/vector2D.h	(revision 6636)
@@ -0,0 +1,101 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+/*!
+ * @file vector2D.h
+ * A basic 2D Vector math framework
+ *
+ * Contains classes to handle vectors, lines, rotations and planes
+*/
+
+#ifndef __VECTOR2D_H_
+#define __VECTOR2D_H_
+
+#include <math.h>
+#include "compiler.h"
+
+//! small and performant 2D vector
+typedef float sVec2D[2];
+
+//! 2D Vector2D
+/**
+ *       Class to handle 2D Vector2Ds
+ */
+class Vector2D {
+ public:
+  Vector2D (float x, float y) : x(x), y(y) {}  //!< assignment constructor
+  Vector2D () : x(0), y(0) {}
+
+  /** @param v: the Vecor to compare with this one @returns true, if the Vecors are the same, false otherwise */
+  inline bool operator== (const Vector2D& v) const { return (this->x==v.x && this->y==v.y)?true:false; };
+  /** @param index The index of the "array" @returns the x/y coordinate */
+  inline float operator[] (float index) const { return ( index == 0)? this->x : this->y; }
+  /** @param v The vector to add @returns the addition between two vectors (this + v) */
+  inline Vector2D operator+ (const Vector2D& v) const { return Vector2D(x + v.x, y + v.y); };
+  /** @param v The vector to add @returns the addition between two vectors (this + v) */
+  inline Vector2D operator+ (const sVec2D& v) const { return Vector2D(x + v[0], y + v[1]); };
+  /** @param v The vector to add  @returns the addition between two vectors (this += v) */
+  inline const Vector2D& operator+= (const Vector2D& v) { this->x += v.x; this->y += v.y; return *this; };
+  /** @param v The vector to substract  @returns the substraction between two vectors (this - v) */
+  inline const Vector2D& operator+= (const sVec2D& v) { this->x += v[0]; this->y += v[1]; return *this; };
+  /** @param v The vector to substract  @returns the substraction between two vectors (this - v) */
+  inline Vector2D operator- (const Vector2D& v) const { return Vector2D(x - v.x, y - v.y); }
+  /** @param v The vector to substract  @returns the substraction between two vectors (this - v) */
+  inline Vector2D operator- (const sVec2D& v) const { return Vector2D(x - v[0], y - v[1]); }
+  /** @param v The vector to substract  @returns the substraction between two vectors (this -= v) */
+  inline const Vector2D& operator-= (const Vector2D& v) { this->x -= v.x; this->y -= v.y; return *this; };
+  /** @param v The vector to substract  @returns the substraction between two vectors (this -= v) */
+  inline const Vector2D& operator-= (const sVec2D& v) { this->x -= v[0]; this->y -= v[1]; return *this; };
+  /** @param v the second vector  @returns The dotProduct between two vector (this (dot) v) */
+  inline float operator* (const Vector2D& v) const { return x * v.x + y * v.y; };
+  /** @todo strange */
+  inline const Vector2D& operator*= (const Vector2D& v) { this->x *= v.x; this->y *= v.y; return *this; };
+  /** @param f a factor to multiply the vector with @returns the vector multiplied by f (this * f) */
+  inline Vector2D operator* (float f) const { return Vector2D(x * f, y * f); };
+  /** @param f a factor to multiply the vector with @returns the vector multiplied by f (this *= f) */
+  inline const Vector2D& operator*= (float f) { this->x *= f; this->y *= f; return *this; };
+  /** @param f a factor to divide the vector with @returns the vector divided by f (this / f) */
+  inline Vector2D operator/ (float f) const { return (unlikely(f == 0.0)) ? Vector2D(0,0):Vector2D(this->x / f, this->y / f); };
+  /** @param f a factor to divide the vector with @returns the vector divided by f (this /= f) */
+  inline const Vector2D& operator/= (float f) {if (unlikely(f == 0.0)) {this->x=0;this->y=0;} else {this->x /= f; this->y /= f;} return *this; };
+  /**  copy constructor @todo (i do not know it this is faster) @param v the vector to assign to this vector. @returns the vector v */
+  inline const Vector2D& operator= (const Vector2D& v) { this->x = v.x; this->y = v.y; return *this; };
+  /** copy constructor* @param v the sVec3D to assign to this vector. @returns the vector v */
+  inline const Vector2D& operator= (const sVec2D& v) { this->x = v[0]; this->y = v[1]; }
+  /** @param v: the other vector \return the dot product of the vectors */
+  float dot (const Vector2D& v) const { return x*v.x+y*v.y; };
+  /** scales the this vector with v* @param v the vector to scale this with */
+  void scale(const Vector2D& v) {   x *= v.x;  y *= v.y; };
+  /** @returns the length of the vector */
+  inline float len() const { return sqrt (x*x+y*y); }
+  /** normalizes the vector */
+  inline void normalize() { float l = len(); if( unlikely(l == 0.0))return; this->x=this->x/l; this->y=this->y/l; };
+  Vector2D getNormalized() const;
+  Vector2D abs();
+
+  void debug() const;
+
+ public:
+  float    x;     //!< The x Coordinate of the Vector2D.
+  float    y;     //!< The y Coordinate of the Vector2D.
+};
+
+
+/** an easy way to create a Random Vector2D @param sideLength the length of the Vector2D (x not sqrt(x^2...)) */
+#define VECTOR2D_RAND(sideLength)  (Vector2D((float)rand()/RAND_MAX -.5, (float)rand()/RAND_MAX -.5) * sideLength)
+
+
+#endif /* __VECTOR2D_H_ */
+
Index: branches/network/src/lib/network/Makefile.am
===================================================================
--- branches/network/src/lib/network/Makefile.am	(revision 6636)
+++ branches/network/src/lib/network/Makefile.am	(revision 6636)
@@ -0,0 +1,33 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXnet.a
+
+libORXnet_a_SOURCES = synchronizeable.cc \
+		      network_manager.cc \
+		      network_socket.cc \
+		      connection_monitor.cc \
+		      network_stream.cc \
+                      data_stream.cc \
+                      network_protocol.cc \
+		      server_socket.cc \
+		      handshake.cc \
+		      network_game_manager.cc \
+		      converter.cc
+
+
+
+
+noinst_HEADERS = synchronizeable.h \
+                 network_manager.h \
+                 network_socket.h \
+                 connection_monitor.h \
+		 network_stream.h \
+                 data_stream.h \
+                 network_protocol.h \
+		 server_socket.h \
+		 handshake.h \
+		 network_game_manager.h \
+		 converter.h
+
+
Index: branches/network/src/lib/network/README
===================================================================
--- branches/network/src/lib/network/README	(revision 6636)
+++ branches/network/src/lib/network/README	(revision 6636)
@@ -0,0 +1,16 @@
+
+
+Hi people
+
+Before starting your implementation, please have a look at the 
+./network_monitor.cc
+./network_monitor.h
+files. They are well commented and include everything you will have 
+to use.
+
+For network module information, check out:
+https://www.orxonox.net/cgi-bin/trac.cgi/wiki/NetworkManager
+
+
+
+
Index: branches/network/src/lib/network/connection_monitor.cc
===================================================================
--- branches/network/src/lib/network/connection_monitor.cc	(revision 6636)
+++ branches/network/src/lib/network/connection_monitor.cc	(revision 6636)
@@ -0,0 +1,147 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Silvan Nellen
+   co-programmer: ...
+*/
+
+#include "connection_monitor.h"
+#include <debug.h>
+#include <SDL/SDL.h>
+#include <string.h>
+
+/* using namespace std is default, this needs to be here */
+using namespace std;
+
+ConnectionMonitor::ConnectionMonitor()
+{
+
+  /* set the class id for the base object and add ist to class list*/
+  this->setClassID(CL_CONNECTION_MONITOR, "ConnectionMonitor");
+
+  /*initialize variables*/
+
+  /*Data of the lifetime of the ConnectionMonitor Object*/
+  packetToAverage = 100;
+  protocollType = "default(TCP)";
+
+  startTime= SDL_GetTicks();
+  totalReceivedPackets=0;
+  averageDatarate=0;
+  totalLostPackets=0;
+  totalPacketloss=0;
+
+  /*Data of the current packet*/
+  currentPacketID=0;
+  currentPacketTick=0;
+  lastPacketID=0;
+  lastPacketTick=0;
+  currentDelay=0;
+
+  /*Data of the last n packets (n is specified by paxketsToAverage)*/
+  sizeOfLastFewPackets=0;
+  currentDatarate=0;
+  lastFewDelays = new unsigned int [packetToAverage];
+  lastFewPackets = new byte* [packetToAverage];
+  packetCounter=0;
+
+
+}
+
+
+ConnectionMonitor::~ConnectionMonitor()
+{
+
+
+}
+
+
+
+void ConnectionMonitor::processPacket(byte* currentPacket, unsigned int packetLength)
+{
+  /*Process the current Packet*/
+  currentPacketTick = SDL_GetTicks();
+  currentDelay = currentPacketTick - lastPacketTick;
+
+  /*Do whats needed for Averaging*/
+
+  if(packetCounter == packetToAverage)
+    {
+      computeCurrentDatarate();
+      displayStatistic();
+      packetCounter = 0;
+      sizeOfLastFewPackets = 0;
+    }
+
+  lastFewDelays[packetCounter] = currentDelay;
+  lastFewPackets[packetCounter] = currentPacket;
+  sizeOfLastFewPackets += packetLength;
+
+  /*Update the lifetime Variables*/
+  totalReceivedPackets ++;
+  float timeDiff = this->currentPacketTick - this->startTime;
+  if( timeDiff != 0.0f )
+    averageDatarate = totalReceivedPackets/timeDiff;
+
+  /*Preparefor the next Packet*/
+  lastPacketTick = currentPacketTick;
+  packetCounter++;
+}
+
+
+/* Compute the value of current Datarate*/
+void ConnectionMonitor::computeCurrentDatarate()
+{
+  int timeForLastFewPackets=0;
+  for(int i=0;i < packetToAverage;i++)
+    timeForLastFewPackets += lastFewDelays[i];
+
+  if( timeForLastFewPackets != 0)
+    currentDatarate = sizeOfLastFewPackets/timeForLastFewPackets;
+}
+
+void doUDPRelatedStuff()
+{
+  /*  Do protocol related stuff
+
+  Only for Udp:
+  "currentPacketID = getID from package";
+
+  if(currentPacketID - lastPacketID > 1)
+  {
+  totalLostPackets += currentPacketID - lastPacketID;
+}
+
+  totalPacketloss = (totalLostPackets/totalReceivedPackets)*100 ;
+  */
+}
+
+
+
+/* Display connectoin statistic*/
+void ConnectionMonitor::displayStatistic()
+{
+//   PRINT(0)("============================================\n");
+//   PRINT(0)("Connection Monitor Network Statistics:\n");
+//   PRINT(0)("Total received packets:",totalReceivedPackets);
+//   PRINT(0)("Average datarate :\n",averageDatarate);
+//   PRINT(0)("Total lost packets:",totalLostPackets);
+//   PRINT(0)("Packetloss [%] :\n",totalPacketloss);
+//
+//   PRINT(0)("Current datarate :\n",currentDatarate);
+//   PRINT(0)("Delays of the last few packets :\n");
+//   for(int i=1 ;i <= packetToAverage-1;i++)
+//     PRINT(0)("%i ",lastFewDelays[i]);
+//
+//   PRINT(0)("============================================\n");
+
+}
+
Index: branches/network/src/lib/network/connection_monitor.h
===================================================================
--- branches/network/src/lib/network/connection_monitor.h	(revision 6636)
+++ branches/network/src/lib/network/connection_monitor.h	(revision 6636)
@@ -0,0 +1,54 @@
+/*!
+ * @file connection_monitor.h
+    \brief provides information about the quality of a connection.
+ */
+
+#ifndef _CONNECTION_MONITOR_H
+#define _CONNECTION_MONITOR_H
+
+#include "base_object.h"
+#include "netdefs.h"
+
+class ConnectionMonitor : virtual public BaseObject
+  {
+  public:
+    ConnectionMonitor();
+    ~ConnectionMonitor();
+
+    void                processPacket(byte* packet, unsigned int packetLength);
+
+
+  private:
+
+
+    void                displayStatistic();
+    void                computeCurrentDatarate();
+    void                doUDPRelatedStuff();
+
+    /*Data of the lifetime of the ConnectionMonitor Object*/
+    unsigned int        packetToAverage;
+    char*               protocollType;
+
+    unsigned int        totalReceivedPackets;
+    float               averageDatarate;
+    unsigned int        totalLostPackets;
+    float               totalPacketloss;
+    unsigned int        startTime;
+
+    /*Data of the current packet*/
+    unsigned int        currentPacketID;
+    unsigned int        currentPacketTick;
+    unsigned int        lastPacketID;
+    unsigned int        lastPacketTick;
+    unsigned int        currentDelay;
+
+    /*Data of the last n packets (n is specified by paxketsToAverage)*/
+    unsigned int        sizeOfLastFewPackets;
+    unsigned int        currentDatarate;
+    byte**              lastFewPackets;
+    unsigned int*       lastFewDelays;
+    unsigned int        packetCounter;
+
+  };
+
+#endif
Index: branches/network/src/lib/network/converter.cc
===================================================================
--- branches/network/src/lib/network/converter.cc	(revision 6636)
+++ branches/network/src/lib/network/converter.cc	(revision 6636)
@@ -0,0 +1,654 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Wuest
+   co-programmer: ...
+*/
+
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
+/* include your own header */
+#include "converter.h"
+#include "shell_command.h"
+
+#include <limits>
+
+SHELL_COMMAND_STATIC(debug, Converter, Converter::debug);
+
+
+/* using namespace std is default, this needs to be here */
+using namespace std;
+
+/*!
+ * Standard constructor
+ */
+Converter::Converter()
+{
+  /* set the class id for the base object */
+  //this->setClassID(CL_ENTITY_MANAGER, "EntityManager");
+}
+
+/*!
+ * Standard destructor
+ */
+Converter::~Converter()
+{
+}
+
+const int sgnadd = 128; // = 2^7
+
+/*!
+ * Converts an int into a byte-array
+ * @remarks: The int is stored in big-endian
+ * @param x: The int which is to convert
+ * @return: A byte-array that accords the given int value
+ */
+byte* Converter::intToByteArray(int x)
+{
+  const int mod = 256; // = 2^8
+
+
+  byte* result = new byte[INTSIZE];
+  int sgn;
+  if (x >= 0)
+    sgn = 1;
+  else
+  {
+    sgn = -1;
+    x = -x;
+  }
+
+  for (int i = 0; i < INTSIZE; i++)
+  {
+    result[i] = x % mod;
+    x /= mod;
+  }
+
+  if (sgn == -1)
+    result[INTSIZE - 1] += sgnadd;
+
+
+  return result;
+}
+
+/*!
+ * Converts an int into a byte-array and stores the result into a given byte-array
+ * @remarks: The int is stored in big-endian
+ * @param x: The int which is to convert
+ * @return: A byte-array that accords the given int value
+ */
+int Converter::intToByteArray(int x, byte* a, int length)
+{
+  if (length < INTSIZE)
+  {
+    PRINTF(1)("byte buffer to short to store an int. Needed length %i. Avaiable length %i", INTSIZE, length);
+    return -1;
+  }
+
+  const int mod = 256; // = 2^8
+
+  int sgn;
+  if (x >= 0)
+    sgn = 1;
+  else
+  {
+    sgn = -1;
+    x = -x;
+  }
+
+  for (int i = 0; i < INTSIZE; i++)
+  {
+    a[i] = x % mod;
+    x /= mod;
+  }
+
+  if (sgn == -1)
+    a[INTSIZE - 1] += sgnadd;
+
+  return INTSIZE;
+}
+
+/*!
+ * Converts a byte-array into an int
+ * @param a: The byte-array which is to convert
+ * @return: An int that accords the given byte-array
+ */
+int Converter::byteArrayToInt(const byte* a, int* x)
+{
+  int mult = 1;
+  const int step = 256; // = 2 ^ 8
+  *x = 0;
+  for (int i = 0; i < INTSIZE - 1; i++)
+  {
+    *x += a[i] * mult;
+    mult *= step;
+  }
+
+  if (a[INTSIZE - 1] >= sgnadd)
+  {
+    *x += (a[INTSIZE - 1] - sgnadd) * mult;
+    *x *= -1;
+  }
+  else
+    *x += a[INTSIZE - 1] * mult;
+
+  return INTSIZE;
+}
+
+/*!
+ * Converts a float into a string containing its binary representation
+ */
+char* Converter::floatToBinString(float x)
+{
+  char* result = new char[200];
+  int pos = 0;
+
+  if (x < 0)
+  {
+    result[pos++] = '-';
+    x = -x;
+  }
+
+  float sub = 1;
+  while (sub < x)
+    sub *= 2;
+
+  while ((x > 0 || sub >= 1) && pos < 200)
+  {
+    if (x >= sub)
+    {
+      result[pos] = '1';
+      x -= sub;
+    }
+    else
+      result[pos] = '0';
+    pos++;
+    sub /= 2;
+
+    if (sub == 0.5f)
+      result[pos++] = '.';
+  }
+
+  return result;
+}
+
+const int expmult = 8388608; //2^23
+
+float Converter::getDenormConst()
+{
+  const int exp = 126;
+  float result = 1.0f;
+  for (int i = 0; i < exp; i++)
+    result /= 2.0f;
+  return result;
+}
+
+/*!
+ * Converts a float value into a byte-array
+ * @param x: The float which is to convert
+ * @return: A byte-array which accords the given float
+ */
+byte* Converter::floatToByteArray(float x)
+{
+  byte* result = new byte[4];
+  floatToByteArray(x, result, 4);
+  return result;
+  /*
+  int mantisse = 0;
+  int exponent = 128;
+
+  int sgn;
+  if (x < 0)
+  {
+    x = -x;
+    sgn = -1;
+  }
+  else
+    sgn = 1;
+
+  if (x == 0)
+  {
+    exponent = 255;
+    mantisse = 0;
+  }
+  else
+  {
+    //if (x < getDenormConst())
+    //  printf("Denormalisiert!\n");
+    //printf("DenormConst = %e", getDenormConst());
+
+    float sub = 1;
+    while (sub < x)
+    {
+      sub *= 2;
+      exponent++;
+    }
+
+    while (x > 0)
+    {
+      if (x >= sub)
+      {
+        mantisse += 1;
+        x -= sub;
+      }
+
+      mantisse *= 2;
+      exponent--;
+      sub /= 2;
+    }
+    exponent++;
+    mantisse /= 2;
+
+    printf("Conv:        mantisse = %i exponent = %i \n", mantisse, exponent);
+
+
+    if (mantisse != 0)
+    {
+      while (mantisse < expmult)
+      {
+        mantisse *= 2;
+        exponent--;
+      }
+
+      mantisse -= expmult;
+    }
+  }
+
+  printf("Conv: mantisse = %i exponent = %i \n", mantisse, exponent);
+
+
+  int hx = mantisse + expmult * exponent;
+  byte* result = intToByteArray(hx);
+  if (sgn == -1)
+    result[3] += sgnadd;
+
+  return result;
+  */
+}
+
+
+/*!
+ * Converts a byte-array into a float value
+ * @param a: The byte-array which is to convert
+ * @return: A float value which accords the given byte-array
+ */
+float Converter::byteArrayToFloat(byte* a)
+{
+  byte* h = new byte[4];
+  float result = 0.0f;
+  byteArrayToFloat(a, &result);
+  return result;
+  /*
+  int hexp = a[2] + a[3] * 256;
+  int exponent = (hexp / 128) % 256;
+
+  int hmant = a[0] + a[1] * 256 + a[2] * 65536;
+  int mantisse = hmant % expmult;
+  if (mantisse == 0 && exponent == 255)
+    return 0;
+
+  mantisse += expmult;
+  exponent -= 128;
+
+
+  int sgn;
+  if (a[3] >= sgnadd)
+    sgn = -1;
+  else
+    sgn = 1;
+
+  printf("ReConv: mantisse = %i exponent = %i \n", mantisse, exponent);
+
+  float emult = 1;
+  if (exponent > 0)
+    for (int i = 0; i < exponent; i++)
+      emult *= 2;
+  else if (exponent < 0)
+    for (int i = 0; i > exponent; i--)
+      emult /= 2;
+
+  float result = mantisse * emult;
+  if (sgn == -1)
+    result = -result;
+
+  return result;
+  */
+}
+
+/*!
+ * Converts a float value into a byte-array and stores the result into a given byte-array
+ * @param x: The float which is to convert
+ * @return: A byte-array which accords the given float
+ */
+int Converter::_floatToByteArray(float x, byte* a, int length)
+{
+  if (length < FLOATSIZE)
+  {
+    PRINTF(1)("byte buffer to short to store a float. Needed length %i. Avaiable length %i", FLOATSIZE, length);
+    return -1;
+  }
+
+  //handle 0 else function will loop for ever
+  /*if ( x == 0 )
+  {
+    for ( int i = 0; i<FLOATSIZE; i++)
+      a[i] = 0;
+    return FLOATSIZE;
+}*/
+
+  int mantisse = 0;
+  int exponent = 128;
+
+  int sgn;
+  if (x < 0)
+  {
+    x = -x;
+    sgn = -1;
+  }
+  else
+    sgn = 1;
+
+  if (x == 0)
+  {
+    exponent = 255;
+    mantisse = 0;
+  }
+  else
+  {
+    //if (x < getDenormConst())
+    //  printf("Denormalisiert!\n");
+    //printf("DenormConst = %e", getDenormConst());
+
+    float sub = 1;
+    while (sub < x)
+    {
+      sub *= 2;
+      exponent++;
+    }
+
+    while (x > 0)
+    {
+      if (x >= sub)
+      {
+        mantisse += 1;
+        x -= sub;
+      }
+
+      mantisse *= 2;
+      exponent--;
+      sub /= 2;
+    }
+    exponent++;
+    mantisse /= 2;
+
+
+///    printf("Conv:        mantisse = %i exponent = %i \n", mantisse, exponent);
+
+
+    if (mantisse != 0)
+    {
+      while (mantisse < expmult)
+      {
+        mantisse *= 2;
+        exponent--;
+      }
+
+      mantisse -= expmult;
+    }
+  }
+
+///  printf("Conv: mantisse = %i exponent = %i \n", mantisse, exponent);
+
+
+  int hx = mantisse + expmult * exponent;
+  int result = intToByteArray(hx, a, length);
+  if (sgn == -1)
+    a[3] += sgnadd;
+
+
+//  int hx = mantisse + expmult * exponent;
+//  byte* result = intToByteArray(hx);
+//  if (sgn == -1)
+//    result[3] += sgnadd;
+
+  return result;
+}
+
+
+/*!
+ * Converts a byte-array into a float value
+ * @param a: The byte-array which is to convert
+ * @return: A float value which accords the given byte-array
+ */
+int Converter::_byteArrayToFloat(const byte* a, float* x)
+{
+    //handle 0
+  /*for (int i = 0; i<FLOATSIZE; i++)
+  {
+    if (a[i]!=0)
+      break;
+    if ( i==FLOATSIZE-1 )
+    {
+      *x = 0.0f;
+      return FLOATSIZE;
+    }
+}*/
+
+  int hexp = a[2] + a[3] * 256;
+  int exponent = (hexp / 128) % 256;
+
+  int hmant = a[0] + a[1] * 256 + a[2] * 65536;
+  int mantisse = hmant % expmult;
+
+  //handle 0
+  if (mantisse == 0 && exponent == 255)
+  {
+    *x = 0;
+    return FLOATSIZE;
+  }
+
+  mantisse += expmult;
+  exponent -= 128;
+
+
+  int sgn;
+  if (a[3] >= sgnadd)
+    sgn = -1;
+  else
+    sgn = 1;
+
+///  printf("ReConv: mantisse = %i exponent = %i \n", mantisse, exponent);
+
+  float emult = 1;
+  if (exponent > 0)
+    for (int i = 0; i < exponent; i++)
+      emult *= 2;
+  else if (exponent < 0)
+    for (int i = 0; i > exponent; i--)
+      emult /= 2;
+
+  /*
+  float result = mantisse * emult;
+  if (sgn == -1)
+    result = -result;
+
+  return result;
+  */
+
+  *x = mantisse * emult;
+  if (sgn == -1)
+    *x = -  *x;
+
+  return FLOATSIZE;
+}
+
+/*!
+ * Converts a float value into a byte-array
+ * @param x: The float which is to convert
+ * @return: A byte-array which accords the given float
+ */
+int Converter::floatToByteArray(float x, byte* a, int length)
+{
+  if ( length<4 )
+  {
+    PRINTF(1)("Byte Array to small\n");
+    return 0;
+  }
+  byte* p = (byte*)&x;
+
+  for (int i = 0; i < 4; i++)
+    a[i] = p[i];
+  return 4;
+}
+
+
+/*!
+ * Converts a byte-array into a float value
+ * @param a: The byte-array which is to convert
+ * @return: A float value which accords the given byte-array
+ */
+int Converter::byteArrayToFloat(const byte* a, float* x)
+{
+  *x = *((float*)a);
+
+  return 4;
+}
+
+/**
+ * copies a strint to a byte array
+ * @param s: string to copy
+ * @param a: byte array
+ * @param length: string length
+ * @return: the used number of bytes in byte array
+ */
+int Converter::stringToByteArray( const char * s, byte * a, int length, int maxLength )
+{
+  if ( length+INTSIZE > maxLength )
+  {
+    PRINTF(1)("Byte array is too small (%d) to store %d bytes\n", maxLength, length+INTSIZE);
+    return -1;
+  }
+
+  int n = Converter::intToByteArray( length, a, maxLength );
+
+  memcpy( a+INTSIZE, s, length );
+
+  return length + INTSIZE;
+}
+
+/**
+ * reads a string out of a byte array
+ * @param a: byte array
+ * @param s: string
+ * @param maxLength: max bytes to copy
+ * @return: the number of read bytes in byte array
+ */
+int Converter::byteArrayToString( const byte * a, char * s, int maxLength )
+{
+  int length;
+
+  int n = Converter::byteArrayToInt( a, &length );
+
+
+  if ( length+1 > maxLength )
+  {
+    PRINTF(1)("There is not enough space in string (%d) to store %d bytes\n", maxLength, length+1 );
+    strncpy(s,"",maxLength);
+    return -1;
+  }
+
+  memcpy( s, a+n, length );
+  s[length] = '\0';
+
+  return n+length;
+}
+
+/**
+ * reads a string out of a byte array and allocates memory for string
+ * @param a: byte array
+ * @param s: string
+ * @param maxLength: max bytes to copy
+ * @return: the number of read bytes in byte array
+ */
+int Converter::byteArrayToStringM( const byte * a, char*& s )
+{
+  int length;
+
+  int n = Converter::byteArrayToInt( a, &length );
+
+  s = new char[length+1];
+
+  if ( !s )
+  {
+    PRINTF(1)("Could not allocate memory!\n" );
+    return -1;
+  }
+
+  memcpy( s, a+n, length );
+  s[length] = '\0';
+
+  return n+length;
+}
+
+
+
+
+void Converter::floatTest(float x)
+{
+  //float x = 8.0f;
+  //float x = numeric_limits<float>::infinity();
+
+  printf("To Convert: %e\n", x);
+
+  byte* res = floatToByteArray(x);
+  for (int i = 0; i < 4; i++)
+    printf("%i ", res[i]);
+  printf("\n");
+
+  float y = byteArrayToFloat(res);
+  printf("ReConvert: %e\n", y);
+
+  if (x == y)
+    printf("equal\n");
+  else
+    printf("different\n");
+}
+
+void Converter::debug()
+{
+  printf("We rulez\n");
+
+  //Denormalized?
+  //floatTest(-9.87624e-38f);
+  //floatTest(-9.87624e-37f);
+  //floatTest(-9.87624e-36f);
+  //floatTest(-9.87624e-35f);
+
+  /*
+  floatTest(14.7f);
+  floatTest(12.07e15f);
+  floatTest(0.0f);
+  floatTest(5.67e-15f);
+  */
+
+  //floatTest(-18.0098f);
+  //floatTest(-24.07e23f);
+  //floatTest(-0.0f);
+  //floatTest(-5.67e-29f);
+  floatTest(-45.7e-32f);
+  floatTest(45.7e-33f);
+  floatTest(-45.7e-34f);
+  floatTest(45.7e-35f);
+}
Index: branches/network/src/lib/network/converter.h
===================================================================
--- branches/network/src/lib/network/converter.h	(revision 6636)
+++ branches/network/src/lib/network/converter.h	(revision 6636)
@@ -0,0 +1,62 @@
+/*!
+ * @file converter.h
+ *  Is able to convert int to byte-array and vice versa
+ */
+
+#ifndef _CONVERTER
+#define _CONVERTER
+
+/* include this file, it contains some default definitions */
+#include "netdefs.h"
+
+
+/* include base_object.h since all classes are derived from this one */
+#include "base_object.h"
+
+/* The size of an int in byte */
+#define INTSIZE 4
+/* The size of a float in byte */
+#define FLOATSIZE 4
+
+/*!
+ * a class that can convert int to byte-array and vice versa
+ */
+class Converter : public BaseObject
+{
+  public:
+    static byte* intToByteArray(int x);
+    static int byteArrayToInt(const byte* a);
+
+    static int intToByteArray(int x, byte* a, int length);
+    static int byteArrayToInt(const byte* a, int* x);
+
+    static int floatToByteArray(float x, byte* a, int length);
+    static int byteArrayToFloat(const byte* a, float* x);
+
+    static int stringToByteArray(const char* s, byte* a, int length, int maxLength);
+    static int byteArrayToString(const byte* a, char* s, int maxLength);
+    static int byteArrayToStringM(const byte* a, char*& s );
+
+    //Test
+    static char* floatToBinString(float x);
+
+    static byte* floatToByteArray(float x);
+    static float byteArrayToFloat(byte* a);
+
+    static int _floatToByteArray(float x, byte* a, int length);
+    static int _byteArrayToFloat(const byte* a, float* x);
+
+
+    static void debug();
+    static void floatTest(float x);
+    static float getDenormConst();
+
+
+  private:
+    Converter();
+    ~Converter();
+};
+
+#undef byte
+
+#endif /*_CONVERTER*/
Index: branches/network/src/lib/network/data_stream.cc
===================================================================
--- branches/network/src/lib/network/data_stream.cc	(revision 6636)
+++ branches/network/src/lib/network/data_stream.cc	(revision 6636)
@@ -0,0 +1,125 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Knecht
+   co-programmer: ...
+*/
+
+/* include Data_stream Header */
+#include "data_stream.h"
+
+
+
+
+/* using namespace std is default, this needs to be here */
+using namespace std;
+
+
+
+/**
+ * This is the empty constructor
+ */
+DataStream::DataStream()
+{
+  this->setClassID(CL_DATA_STREAM, "DataStream");
+  this->upBuffer = new byte[DATA_STREAM_BUFFER_SIZE];
+  this->downBuffer = new byte[DATA_STREAM_BUFFER_SIZE];
+}
+
+/**
+ * This constructor creates a new DataStream and connects it to both streams (upStream, downStream)
+ */
+DataStream::DataStream(DataStream& inStream, DataStream& outStream)
+{
+    this->setClassID(CL_DATA_STREAM, "DataStream");
+    this->downStream = &outStream;
+    this->upStream = &inStream;
+
+    if( this->upBuffer)
+      delete[] this->upBuffer;
+    if( this->downBuffer)
+      delete[] this->downBuffer;
+}
+
+/**
+ *  standart deconstructor
+ */
+DataStream::~DataStream()
+{
+
+}
+
+
+/**
+ * This function connects this stream to another stream. The connected DataStream is an up-stream, meaning
+ * that the stream is "further away" from the NetworkSocket. The local reference upStream will be set to this
+ * Stream
+ */
+void DataStream::connectUpStream(DataStream& upStream)
+{
+
+}
+
+/**
+ * This function connects this stream to another stream. The connected DataStream is an down-stream, meaning
+ * that the stream is "closer" to the NetworkSocket.
+ */
+void DataStream::connectDownStream(DataStream& upStream)
+{
+
+}
+
+/**
+ * This function disconnects the upStream and sets it to NULL
+ */
+void DataStream::disconnectUpStream()
+{
+
+}
+
+/**
+ * This function disconnects the downStream and sets it to NULL
+ */
+void DataStream::disconnectDownStream()
+{
+
+}
+
+
+/**
+ * Following functions are protected and only visible inside the object and from derived classes
+ */
+
+/**
+ * This function writes the binary data to the local data. You will have to copy each byte and not only dublicate
+ * it.
+ *
+ * @param data: the binary array
+ * @param length: the length of the array
+ */
+void passDown(byte* data, int length)
+{
+
+}
+
+
+/**
+ * This function returns a reference to the local upData data array. So it can be read by an upper Stream
+ * The reading function will have to copy the whole data and musn't just reference it!
+ * This function is only called from other connected DataStreams to read the data.
+ *
+ * @param data: the binary array
+ * @return: the length of the data
+ */
+int passUp(byte* data)
+{
+
+}
Index: branches/network/src/lib/network/data_stream.h
===================================================================
--- branches/network/src/lib/network/data_stream.h	(revision 6636)
+++ branches/network/src/lib/network/data_stream.h	(revision 6636)
@@ -0,0 +1,48 @@
+/*!
+ * @file data_stream.h
+  *  Main class for a data stream, used for our network stream
+  *  network stream will get data, and will send it with a network socket
+  *  to another network stream
+
+*/
+
+#ifndef _DATA_STREAM_H
+#define _DATA_STREAM_H
+
+#include "base_object.h"
+#include "netdefs.h"
+
+#define DATA_STREAM_BUFFER_SIZE 10240
+
+class DataStream : public BaseObject
+{
+      public:
+      DataStream();
+      DataStream(DataStream& inStream, DataStream& outStream);
+      ~DataStream();
+
+
+      void connectUpStream(DataStream& upStream);
+
+      void disconnectUpStream();
+
+      void connectDownStream(DataStream& downStream);
+
+      void disconnectDownStream();
+
+      virtual void processData() = 0;
+
+      protected:
+      void passDown(byte* data, int length);
+
+      int passUp(byte* data);
+
+      byte* upBuffer;
+      byte* downBuffer;
+      unsigned int bufferSize;
+      DataStream* upStream;
+      DataStream* downStream;
+
+};
+
+#endif /* _DATA_STREAM_ */
Index: branches/network/src/lib/network/handshake.cc
===================================================================
--- branches/network/src/lib/network/handshake.cc	(revision 6636)
+++ branches/network/src/lib/network/handshake.cc	(revision 6636)
@@ -0,0 +1,201 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: christoph
+   co-programmer:
+*/
+
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
+#include "handshake.h"
+
+Handshake::Handshake( bool server, int clientId, int networkGameManagerId )
+{
+  /* set the class id for the base object */
+  this->setClassID(CL_HANDSHAKE, "Handshake");
+
+  this->setIsServer(server);
+  this->clientId = clientId;
+  this->networkGameManagerId = networkGameManagerId;
+  this->state = 0;
+  this->isOk = false;
+  this->setOwner(0);
+
+  PRINTF(5)("Handshake created clientId = %d\n", clientId);
+}
+
+int Handshake::writeBytes( const byte * data, int length, int sender)
+{
+  PRINTF(5)("Handshake::writeBytes states = %d %d %d %d (%d)\n", hasState( HS_RECVD_INIT ), hasState( HS_RECVD_VER ), hasState( HS_RECVD_HID ), hasState( HS_COMPLETED ), state);
+
+  SYNCHELP_READ_BEGIN();
+
+  if ( hasState( HS_COMPLETED ) )
+       return 0;
+
+  if ( !hasState( HS_RECVD_INIT ) )
+  {
+    if ( length != _INITIAL_DATA_LENGTH )
+    {
+      PRINTF(0)("initial packet has wrong size %d instead of %d\n", length, _INITIAL_DATA_LENGTH);
+      setState( HS_COMPLETED );
+      return 0;
+    }
+
+    if ( strncmp((char*)data, _INITIAL_DATA, length) )
+    {
+      PRINTF(0)("initial packed does not match\n");
+      setState( HS_COMPLETED );
+      return length;
+    }
+
+    setState( HS_RECVD_INIT );
+    PRINTF(0)("got valid initial packet from client %d\n", clientId);
+    return length;
+  }
+
+  if ( hasState( HS_RECVD_INIT ) && !hasState( HS_RECVD_VER ) )
+  {
+    if ( length != _ORXONOX_VERSION_LENGTH )
+    {
+      PRINTF(0)("version number packet has wrong size %d instead of %d\n", length, _ORXONOX_VERSION_LENGTH);
+      setState( HS_COMPLETED );
+      return 0;
+    }
+
+    if ( strncmp((char*)data, _ORXONOX_VERSION, length) )
+    {
+      PRINTF(0)("versions do not match\n");
+      setState( HS_COMPLETED );
+      return length;
+    }
+
+    setState( HS_RECVD_VER );
+
+    PRINTF(0)("client %d's version does match\n", clientId);
+    return length;
+  }
+
+  if ( !isServer() && hasState( HS_RECVD_VER ) && !hasState( HS_RECVD_HID ) )
+  {
+    if ( length != INTSIZE+INTSIZE )
+    {
+      PRINTF(0)("hostID packet has wrong size %d instead of %d\n", length, 1);
+      setState( HS_COMPLETED );
+      return 0;
+    }
+
+    setState( HS_COMPLETED );
+    setState( HS_RECVD_HID );
+    this->isOk = true;
+    SYNCHELP_READ_INT( this->newHostId );
+    SYNCHELP_READ_INT( this->newNetworkGameManagerId );
+
+    if ( newHostId == 0 )
+    {
+      setState( HS_WAS_REJECT );
+      isOk = false;
+      PRINTF(0)("Server did not accept handshake!\n");
+    }
+    else
+    {
+      PRINTF(0)("got my hostID: %d and networkGameManagerId: %d\n", newHostId, newNetworkGameManagerId);
+    }
+    return SYNCHELP_READ_N;
+  }
+
+}
+
+int Handshake::readBytes( byte * data, int maxLength, int * reciever )
+{
+  PRINTF(5)("Handshake::readBytes states = %d %d %d %d (%d)\n", hasState( HS_SENT_INIT ), hasState( HS_SENT_VER ), hasState( HS_SENT_HID ), hasState( HS_COMPLETED ), state);
+
+  SYNCHELP_WRITE_BEGIN();
+
+  if ( hasState( HS_COMPLETED ) )
+    return 0;
+
+  if ( !hasState( HS_SENT_INIT ) )
+  {
+    if ( maxLength < _INITIAL_DATA_LENGTH )
+    {
+      PRINTF(0)("buffer too small for _INITIAL_DATA");
+      setState( HS_COMPLETED );
+      return 0;
+    }
+
+    setState( HS_SENT_INIT );
+    memcpy(data, _INITIAL_DATA, _INITIAL_DATA_LENGTH);
+    if ( this->isServer() )
+      *reciever = clientId;
+    return _INITIAL_DATA_LENGTH;
+  }
+
+  if ( hasState( HS_RECVD_INIT ) && hasState( HS_SENT_INIT ) && !hasState( HS_SENT_VER ) )
+  {
+    if ( maxLength < _ORXONOX_VERSION_LENGTH )
+    {
+      PRINTF(0)("buffer too small for version number");
+      setState( HS_COMPLETED );
+      return 0;
+    }
+
+    setState( HS_SENT_VER );
+    memcpy(data, _ORXONOX_VERSION, _ORXONOX_VERSION_LENGTH);
+    if ( this->isServer() )
+      *reciever = clientId;
+    return _ORXONOX_VERSION_LENGTH;
+  }
+
+  if ( isServer() && hasState( HS_RECVD_VER) && hasState( HS_SENT_VER ) && !hasState( HS_SENT_HID ) )
+  {
+    if ( maxLength < 2 )
+    {
+      PRINTF(0)("buffer too small for ID");
+      setState( HS_COMPLETED );
+      return 0;
+    }
+
+    setState( HS_SENT_HID );
+    setState( HS_COMPLETED );
+
+    if ( hasState( HS_DO_REJECT ) )
+    {
+      isOk = false;
+      //memcpy(data, (byte*)0, 4);
+      SYNCHELP_WRITE_INT( 0 );
+      SYNCHELP_WRITE_INT( 0 );
+    }
+    else
+    {
+      isOk = true;
+      //memcpy(data, &clientId, 4);
+      SYNCHELP_WRITE_INT( clientId );
+      SYNCHELP_WRITE_INT( networkGameManagerId );
+    }
+    *reciever = clientId;
+    return SYNCHELP_WRITE_N;
+  }
+
+  return 0;
+}
+
+void Handshake::writeDebug( ) const
+{
+}
+
+void Handshake::readDebug( ) const
+{
+}
Index: branches/network/src/lib/network/handshake.h
===================================================================
--- branches/network/src/lib/network/handshake.h	(revision 6636)
+++ branches/network/src/lib/network/handshake.h	(revision 6636)
@@ -0,0 +1,64 @@
+/*!
+ * @file network_stream.h
+ *  implementation of a network pipe
+ */
+
+#ifndef _HANDSHAKE
+#define _HANDSHAKE
+
+#include "base_object.h"
+#include "synchronizeable.h"
+
+#define _INITIAL_DATA "orxonox"
+#define _INITIAL_DATA_LENGTH 7
+
+#define _ORXONOX_VERSION "\x00\x00\x00\x01"
+#define _ORXONOX_VERSION_LENGTH 4
+
+typedef enum HandshakeState {
+  HS_SENT_INIT  = 0x00000001,
+  HS_RECVD_INIT = 0x00000002,
+  HS_SENT_VER   = 0x00000004,
+  HS_RECVD_VER  = 0x00000008,
+  HS_SENT_HID   = 0x00000010,
+  HS_RECVD_HID  = 0x00000020,
+  HS_COMPLETED  = 0x00000040,
+
+  HS_DO_REJECT  = 0x00010000,
+  HS_WAS_REJECT = 0x00020000,
+
+  NUM_STATES
+};
+
+class Handshake : public Synchronizeable
+{
+  public:
+    Handshake(bool server, int clientId = 0, int networkGameManagerId = 0);
+    inline bool       completed(){ return hasState( HS_COMPLETED ); }
+    inline bool       ok(){ return isOk; }
+    inline int        getHostId(){ return newHostId; }
+    inline int        getNetworkGameManagerId(){ return newNetworkGameManagerId; }
+
+    inline void       doReject(){ setState(HS_DO_REJECT); }
+
+    virtual int       writeBytes(const byte* data, int length, int sender);
+    virtual int       readBytes(byte* data, int maxLength, int * reciever);
+    virtual void      writeDebug() const;
+    virtual void      readDebug() const;
+
+  private:
+    int               state;
+    int               clientId;
+    int               networkGameManagerId;
+    int               newHostId;
+    int               newNetworkGameManagerId;
+    bool              isOk;
+
+    inline bool       hasState( int a ){ return (state & a) == a; }
+    inline void       setState( int a ){ state = state | a; }
+    inline void       unsetState( int a ){ state = state & (~a); }
+
+};
+
+
+#endif
Index: branches/network/src/lib/network/netdefs.h
===================================================================
--- branches/network/src/lib/network/netdefs.h	(revision 6636)
+++ branches/network/src/lib/network/netdefs.h	(revision 6636)
@@ -0,0 +1,27 @@
+
+
+/*!
+ * @file network_manager.h
+ *  Main interface for the network module. Manages all the modules
+
+ */
+
+#ifndef _NETDEFS
+#define _NETDEFS
+
+#ifdef HAVE_SDL_NET_H
+  #include <SDL_net.h>
+#else
+  #include <SDL/SDL_net.h>
+#endif
+
+
+typedef unsigned char byte;
+
+
+typedef enum {
+  NET_SERVER,
+  NET_CLIENT
+} NodeType;
+
+#endif /* _NETWORK_MANAGER */
Index: branches/network/src/lib/network/network_game_manager.cc
===================================================================
--- branches/network/src/lib/network/network_game_manager.cc	(revision 6636)
+++ branches/network/src/lib/network/network_game_manager.cc	(revision 6636)
@@ -0,0 +1,905 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Wuest
+   co-programmer: ...
+*/
+
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
+#include "factory.h"
+#include "network_stream.h"
+#include "converter.h"
+
+#include "p_node.h"
+#include "state.h"
+#include "game_world.h"
+#include "world_entity.h"
+#include "playable.h"
+#include "player.h"
+#include "network_manager.h"
+
+
+/* include your own header */
+#include "network_game_manager.h"
+
+
+/* using namespace std is default, this needs to be here */
+using namespace std;
+
+NetworkGameManager* NetworkGameManager::singletonRef = NULL;
+
+/*!
+ * Standard constructor
+ */
+NetworkGameManager::NetworkGameManager()
+{
+  PRINTF(0)("START\n");
+
+  /* set the class id for the base object */
+  this->setClassID(CL_NETWORK_GAME_MANAGER, "NetworkGameManager");
+
+  newUniqueID = MAX_CONNECTIONS + 2;
+
+  hasRequestedWorld = false;
+}
+
+/*!
+ * Standard destructor
+ */
+NetworkGameManager::~NetworkGameManager()
+{
+  for ( int i = 0; i<outBuffer.size(); i++)
+  {
+    if ( outBuffer[i].buffer )
+      delete outBuffer[i].buffer;
+  }
+
+}
+
+
+int NetworkGameManager::writeBytes(const byte* data, int length, int sender)
+{
+  int i = 0;
+  byte b;
+
+  while ( i<length )
+  {
+    b = data[i++];
+
+    if ( isServer() )
+    {
+      if ( b == REQUEST_CREATE )
+      {
+        if ( !handleRequestCreate( i, data, length, sender ) )
+          return i;
+        continue;
+      }
+      if ( b == REQUEST_REMOVE )
+      {
+        if ( !handleRequestRemove( i, data, length, sender ) )
+          return i;
+        continue;
+      }
+    }
+    else
+    {
+      if ( b == CREATE_ENTITY )
+      {
+        PRINTF(0)("CREATE_ENTITY\n");
+        if ( !handleCreateEntity( i, data, length, sender ) )
+          return i;
+        continue;
+      }
+      if ( b == REMOVE_ENTITY )
+      {
+        if ( !handleRemoveEntity( i, data, length, sender ) )
+          return i;
+        continue;
+      }
+      if ( b == CREATE_ENTITY_LIST )
+      {
+        if ( !handleCreateEntityList( i, data, length, sender ) )
+          return i;
+        continue;
+      }
+      if ( b == REMOVE_ENTITY_LIST )
+      {
+        if ( !handleRemoveEntityList( i, data, length, sender ) )
+          return i;
+        continue;
+      }
+      if ( b == YOU_ARE_ENTITY )
+      {
+        if ( !handleYouAreEntity( i, data, length, sender ) )
+          return i;
+        continue;
+      }
+    }
+
+    if ( b == REQUEST_ENTITY_LIST )
+    {
+      sendEntityList( sender );
+      continue;
+    }
+
+    if ( b == REQUEST_SYNC )
+    {
+      if ( !handleRequestSync( i, data, length, sender ) )
+        return i;
+      continue;
+    }
+
+    //if we get her something with data is wrong
+    PRINTF(1)("Data is not in the right format! i=%d\n", i);
+    return i;
+  }
+
+  return i;
+}
+
+int NetworkGameManager::readBytes(byte* data, int maxLength, int * reciever)
+{
+  if ( !isServer() && !hasRequestedWorld )
+  {
+    SYNCHELP_WRITE_BEGIN();
+    byte b = REQUEST_ENTITY_LIST;
+    SYNCHELP_WRITE_BYTE( b );
+    hasRequestedWorld = true;
+    return SYNCHELP_WRITE_N;
+  }
+
+  for ( int i = 0; i<outBuffer.size(); i++ )
+  {
+    *reciever = i;
+    if ( outBuffer[i].length>0 )
+    {
+      int nbytes = outBuffer[i].length;
+      outBuffer[i].length = 0;
+
+      if ( nbytes > maxLength )
+      {
+        PRINTF(1)("OutBuffer.length (%d) > (%d) networkStreamBuffer.maxLength\n", nbytes, maxLength);
+        return 0;
+      }
+
+      memcpy(data, outBuffer[i].buffer, nbytes);
+      return nbytes;
+    }
+  }
+
+  return 0;
+}
+
+void NetworkGameManager::writeDebug() const
+{
+}
+
+void NetworkGameManager::readDebug() const
+{
+}
+
+
+/*!
+ * Checks whether this is connected to a server or a client
+ * and afterwards creates the needed entity
+ * @param classID: The ID of the class of which an entity should be created
+ */
+int NetworkGameManager::createEntity( ClassID classID, int owner )
+{
+  if ( this->isServer() )
+  {
+    if ( newUniqueID < 0 )
+    {
+      PRINTF(1)("Cannot create entity! There are no more uniqueIDs left!\n");
+      return -1;
+    }
+
+    return this->executeCreateEntity( classID, newUniqueID++, owner );
+  }
+  else
+  {
+    this->requestCreateEntity( classID );
+    return -1;
+  }
+}
+
+
+/*!
+ * Checks whether this is connected to a server or a client
+ * and afterwards creates the needed entity
+ * @param classID: The ID of the class of which an entity should be created
+ */
+BaseObject* NetworkGameManager::createEntity(const TiXmlElement* element)
+{
+  if ( this->isServer() )
+  {
+    if ( newUniqueID < 0 )
+    {
+      PRINTF(1)("Cannot create entity! There are no more uniqueIDs left!\n");
+      return NULL;
+    }
+
+    BaseObject * b = Factory::fabricate( element );
+
+    if ( !b )
+    {
+      PRINTF(1)("Could not fabricate Object with className %s\n", element->Value() );
+      return NULL;
+    }
+
+
+    if ( b->isA(CL_SYNCHRONIZEABLE) )
+    {
+      Synchronizeable * s = dynamic_cast<Synchronizeable*>(b);
+      s->setUniqueID( newUniqueID++ );
+      s->setOwner( 0 );
+      this->networkStream->connectSynchronizeable( *s );
+      return b;
+    }
+    else
+    {
+      PRINTF(1)("Class %s is not a synchronizeable!\n", b->getClassName() );
+      delete b;
+    }
+
+  }
+  else
+  {
+    PRINTF(1)("This node is not a server and cannot create id %x\n", element->Value());
+  }
+  return NULL;
+}
+
+
+/*!
+ * Checks whether this is connected to a server or a client
+ * and afterwards removes the specified entity
+ * @param uniqueID: The ID of the entity object which should be removed
+ */
+void NetworkGameManager::removeEntity(int uniqueID)
+{
+  if ( this->isServer() )
+  {
+    this->executeRemoveEntity( uniqueID );
+  }
+  else
+  {
+    this->requestRemoveEntity( uniqueID );
+  }
+}
+
+
+
+/*!
+ * Creates the needed entity on the server if possible
+ * @param classID: The ID of the class of which an entity should be created
+ */
+void NetworkGameManager::requestCreateEntity(ClassID classID)
+{
+  for ( int i = 0; i<outBuffer.size(); i++)
+  {
+    if ( !this->networkStream->isUserIdActive( i ) )
+      continue;
+
+    if ( !writeToClientBuffer( outBuffer[i], (byte)REQUEST_CREATE ) )
+      return;
+    if ( !writeToClientBuffer( outBuffer[i], (int)classID ) )
+      return;
+  }
+}
+
+/*!
+ * Removes the specified entity on the server
+ * @param uniqueID: The ID of the entity object which should be removed
+ */
+void NetworkGameManager::requestRemoveEntity(int uniqueID)
+{
+  for ( int i = 0; i<outBuffer.size(); i++)
+  {
+    if ( !this->networkStream->isUserIdActive( i ) )
+      continue;
+
+    if ( !writeToClientBuffer( outBuffer[i], (byte)REQUEST_REMOVE ) )
+      return;
+    if ( !writeToClientBuffer( outBuffer[i], uniqueID ) )
+      return;
+  }
+}
+
+/*!
+ * Creates the needed entity if possible
+ * This function is called if this is a server
+ * @param classID: The ID of the class of which an entity should be created
+ */
+int NetworkGameManager::executeCreateEntity(ClassID classID, int uniqueID, int owner)
+{
+  for ( int i = 0; i<outBuffer.size(); i++)
+  {
+    if ( !this->networkStream->isUserIdActive( i ) )
+      continue;
+
+    if ( !writeToClientBuffer( outBuffer[i], (byte)CREATE_ENTITY ) )
+      return -1;
+    if ( !writeToClientBuffer( outBuffer[i], (int)classID ) )
+      return -1;
+    if ( !writeToClientBuffer( outBuffer[i], uniqueID ) )
+      return -1;
+    if ( !writeToClientBuffer( outBuffer[i], owner ) )
+      return -1;
+  }
+
+  doCreateEntity( classID, uniqueID, owner );
+
+  return uniqueID;
+}
+
+/*!
+ * Removes the specified entity
+ * This function is called if this is a server
+ * @param uniqueID: The ID of the entity object which should be removed
+ */
+void NetworkGameManager::executeRemoveEntity(int uniqueID)
+{
+  for ( int i = 0; i<outBuffer.size(); i++)
+  {
+    if ( !this->networkStream->isUserIdActive( i ) )
+      continue;
+
+    if ( !writeToClientBuffer( outBuffer[i], (byte)REMOVE_ENTITY ) )
+      return;
+    if ( !writeToClientBuffer( outBuffer[i], uniqueID ) )
+      return;
+  }
+
+  doRemoveEntity(uniqueID);
+}
+
+/*!
+ * Checks whether it is possible to create an entity of a given class
+ * @return: true if the entity can be created, false otherwise
+ */
+bool NetworkGameManager::canCreateEntity(ClassID classID)
+{
+  return true;
+}
+
+/*!
+ * Sends the Entities to the new connected client
+ * @param userID: The ID of the user
+ */
+void NetworkGameManager::sendEntityList( int userID )
+{
+  if ( !isServer() )
+    return;
+
+  if ( userID >= outBuffer.size() )
+    resizeBufferVector( userID );
+
+  SynchronizeableList::const_iterator it, e;
+
+  it = this->networkStream->getSyncBegin();
+  e = this->networkStream->getSyncEnd();
+
+  if ( !writeToClientBuffer( outBuffer[userID], (byte)CREATE_ENTITY_LIST ) )
+    return;
+
+  // -2 because you must not send network_game_manager and handshake
+  if ( !writeToClientBuffer( outBuffer[userID], networkStream->getSyncCount() ) )
+    return;
+
+  //PRINTF(0)("SendEntityList: n = %d\n", networkStream->getSyncCount()-2 );
+
+  int n = 0;
+
+  while ( it != e )
+  {
+    PRINTF(5)("SENDING ENTITY %s id %d\n", (*it)->getClassName(), (*it)->getUniqueID() );
+    if ( !writeToClientBuffer( outBuffer[userID], (int)((*it)->getLeafClassID()) ) )
+      return;
+
+    if ( !writeToClientBuffer( outBuffer[userID], (int)((*it)->getUniqueID()) ) )
+      return;
+
+    if ( !writeToClientBuffer( outBuffer[userID], (int)((*it)->getOwner()) ) )
+      return;
+
+    it++;
+  }
+
+  signalNewPlayer( userID );
+}
+
+
+
+bool NetworkGameManager::signalNewPlayer(int userId)
+{
+  if ( userId >= outBuffer.size() )
+    resizeBufferVector( userId );
+
+  /* create new playable for Player*/
+  PRINTF(0)("Request for creation: %i\n", userId);
+  int uniqueId = this->createEntity(CL_SPACE_SHIP, userId);
+  PRINTF(0)("Request for creation: userid: %i, uniqueid: %i\n", userId, uniqueId);
+  this->sendYouAre(uniqueId, userId);
+
+}
+
+
+/**
+ * Creates a buffer for user n
+ * @param n The ID of the user
+ */
+void NetworkGameManager::resizeBufferVector( int n )
+{
+  for ( int i = outBuffer.size(); i<=n; i++)
+  {
+    clientBuffer outBuf;
+
+    outBuf.length = 0;
+
+    outBuf.maxLength = 5*1024;
+
+    outBuf.buffer = new byte[5*1014];
+
+    outBuffer.push_back(outBuf);
+  }
+}
+
+/**
+ * Creates the entity on this host
+ * @param classID: ClassID of the entity to create
+ * @param uniqueID: Unique ID to assign to the synchronizeable
+ * @param owner: owner of this synchronizealbe
+ */
+BaseObject* NetworkGameManager::doCreateEntity( ClassID classID, int uniqueID, int owner )
+{
+  BaseObject * b = Factory::fabricate( classID );
+
+  if ( !b )
+  {
+    PRINTF(1)("Could not fabricate Object with classID %x\n", classID);
+    return NULL;
+  }
+
+  if ( b->isA(CL_SYNCHRONIZEABLE) )
+  {
+    Synchronizeable * s = dynamic_cast<Synchronizeable*>(b);
+    s->setUniqueID( uniqueID );
+    s->setOwner( owner );
+    this->networkStream->connectSynchronizeable( *s );
+    if ( !isServer() )
+      s->setIsOutOfSync( true );
+    PRINTF(0)("Fabricated %s with id %d\n", s->getClassName(), s->getUniqueID());
+
+    //HACK: hack to prevent collision
+    if ( b->isA(CL_WORLD_ENTITY) && !b->isA(CL_PLAYABLE) )
+    {
+      if ( NetworkManager::getInstance()->getHostID()!=0 )
+      {
+        static Vector pos = Vector(1000.0, 1000.0, 1000.0);
+        PNode *p = dynamic_cast<PNode*>(b);
+        p->setAbsCoor(pos);
+        //p->updateNode(0);
+        pos += Vector(1000.0, 1000.0, 1000.0);
+      }
+    }
+
+    return b;
+  }
+  else
+  {
+    PRINTF(1)("Class with ID %x is not a synchronizeable!", (int)classID);
+    delete b;
+  }
+  return NULL;
+}
+
+/**
+ * Removes a entity on this host
+ * @param uniqueID: unique ID assigned with the entity to remove
+ */
+void NetworkGameManager::doRemoveEntity( int uniqueID )
+{
+  SynchronizeableList::const_iterator it,e;
+  it = this->networkStream->getSyncBegin();
+  e = this->networkStream->getSyncEnd();
+
+  while ( it != e )
+  {
+    if ( (*it)->getUniqueID() == uniqueID )
+    {
+      delete *it;
+      break;
+    }
+    it++;
+  }
+}
+
+/**
+ * Tell the synchronizeable that a user's synchronizeable is out of sync
+ * @param uniqueID: unique ID assigned with the entity which is out of sync
+ * @param userID: user ID who's synchronizeable is out of sync
+ */
+void NetworkGameManager::doRequestSync( int uniqueID, int userID )
+{
+  SynchronizeableList::const_iterator it,e;
+  it = this->networkStream->getSyncBegin();
+  e = this->networkStream->getSyncEnd();
+
+  while ( it != e )
+  {
+    if ( (*it)->getUniqueID() == uniqueID )
+    {
+      (*it)->requestSync( userID );
+      break;
+    }
+    it++;
+  }
+}
+
+/**
+ * Copies length bytes to the clientBuffer with error checking
+ * @param clientBuffer: the clientBuffer to write to
+ * @param data: buffer to the data
+ * @param length: length of data
+ * @return false on error true else
+ */
+bool NetworkGameManager::writeToClientBuffer( clientBuffer &cb, byte * data, int length )
+{
+  if ( length > cb.maxLength-cb.length )
+  {
+    PRINTF(1)("No space left in clientBuffer\n");
+    return false;
+  }
+
+  memcpy( cb.buffer+cb.length, data, length );
+  return true;
+}
+
+/**
+ * Reads data from clientBuffer with error checking
+ * @param clientBuffer: the clientBuffer to read from
+ * @param data: pointer to the buffer
+ * @param length:
+ * @return
+ */
+bool NetworkGameManager::readFromClientBuffer( clientBuffer &cb, byte * data, int length )
+{
+  if ( cb.length < length )
+  {
+    PRINTF(0)("There is not enough data in clientBuffer\n");
+    return 0;
+  }
+
+  memcpy( data, cb.buffer+cb.length-length, length );
+  return true;
+}
+
+/**
+ * Tells this client that he has to control this entity
+ * @param uniqueID: the entity's uniqeID
+ */
+void NetworkGameManager::doYouAre( int uniqueID )
+{
+
+  SynchronizeableList::const_iterator it = this->networkStream->getSyncBegin();
+
+  Playable *p = NULL;
+  Synchronizeable *s = NULL;
+
+  for ( ; it !=networkStream->getSyncEnd(); it++ )
+  {
+    if ( (*it)->getUniqueID()==uniqueID )
+    {
+      if ( (*it)->isA( CL_SYNCHRONIZEABLE ) )
+      {
+        s = dynamic_cast<Synchronizeable*>(*it);
+      }
+      if ( (*it)->isA( CL_PLAYABLE ) )
+      {
+        p = dynamic_cast<Playable*>(*it);
+        break;
+      } else
+      {
+        PRINTF(1)("UniqueID is not a Playable\n");
+      }
+    }
+  }
+
+  Player* player = State::getPlayer();
+  assert(p != NULL);
+  assert(s != NULL);
+  assert(player != NULL);
+
+  s->setIsOutOfSync( true );
+
+  PRINTF(0)("uniqueID = %d\n", s->getUniqueID());
+
+  player->setControllable(p);
+
+
+}
+
+/**
+ * Tells a remote client that he has to control this entity
+ * @param uniqueID: the entity's uniqeID
+ * @param userID: the users ID
+ */
+void NetworkGameManager::sendYouAre( int uniqueID, int userID )
+{
+  if ( !isServer() )
+    return;
+
+  if ( userID != 0 )
+  {
+    if ( !writeToClientBuffer( outBuffer[userID], (byte)YOU_ARE_ENTITY ) )
+      return;
+
+    if ( !writeToClientBuffer( outBuffer[userID], uniqueID ) )
+      return;
+  }
+  else
+  {
+    doYouAre(uniqueID);
+  }
+}
+
+bool NetworkGameManager::handleRequestCreate( int & i, const byte * data, int length, int sender )
+{
+  if ( INTSIZE > length-i )
+  {
+    PRINTF(1)("Cannot read classID from buffer! Not enough data left!\n");
+    return false;
+  }
+  int classID;
+  i += Converter::byteArrayToInt( &data[i], &classID );
+
+  createEntity( (ClassID)classID );
+
+  return true;
+}
+
+bool NetworkGameManager::handleRequestRemove( int & i, const byte * data, int length, int sender )
+{
+  if ( INTSIZE > length-i )
+  {
+    PRINTF(1)("Cannot read uniqueID from buffer! Not enough data left!\n");
+    return false;
+  }
+  int uniqueID;
+  i += Converter::byteArrayToInt( &data[i], &uniqueID );
+
+  removeEntity( uniqueID );
+
+  return true;
+}
+
+bool NetworkGameManager::handleCreateEntity( int & i, const byte * data, int length, int sender )
+{
+  if ( INTSIZE > length-i )
+  {
+    PRINTF(1)("Cannot read classID from buffer! Not enough data left!\n");
+    return false;
+  }
+  int classID;
+  i += Converter::byteArrayToInt( &data[i], &classID );
+
+  if ( INTSIZE > length-i )
+  {
+    PRINTF(1)("Cannot read uniqueID from buffer! Not enough data left!\n");
+    return false;
+  }
+  int uniqueID;
+  i += Converter::byteArrayToInt( &data[i], &uniqueID );
+
+  if ( INTSIZE > length-i )
+  {
+    PRINTF(1)("Cannot read owner from buffer! Not enough data left!\n");
+    return false;
+  }
+  int owner;
+  i += Converter::byteArrayToInt( &data[i], &owner );
+
+  doCreateEntity( (ClassID)classID, uniqueID, owner );
+
+  return true;
+}
+
+bool NetworkGameManager::handleRemoveEntity( int & i, const byte * data, int length, int sender )
+{
+  if ( INTSIZE > length-i )
+  {
+    PRINTF(1)("Cannot read uniqueID from buffer! Not enough data left!\n");
+    return false;
+  }
+  int uniqueID;
+  i += Converter::byteArrayToInt( &data[i], &uniqueID );
+
+  doRemoveEntity( uniqueID );
+
+  return true;
+}
+
+bool NetworkGameManager::handleCreateEntityList( int & i, const byte * data, int length, int sender )
+{
+  if ( INTSIZE > length-i )
+  {
+    PRINTF(1)("Cannot read n from buffer! Not enough data left!\n");
+    return false;
+  }
+
+  PRINTF(0)("HandleCreateEntityList:  data[i..i+3] = %d %d %d %d\n", data[i], data[i+1], data[i+2], data[i+3]);
+
+  int n;
+  i += Converter::byteArrayToInt( &data[i], &n );
+
+
+  PRINTF(0)("HandleCreateEntityList: n = %d\n", n);
+
+  int classID, uniqueID, owner;
+
+  for ( int j = 0; j<n; j++ )
+  {
+
+    if ( INTSIZE > length-i )
+    {
+      PRINTF(1)("Cannot read classID from buffer! Not enough data left!\n");
+      return false;
+    }
+    i += Converter::byteArrayToInt( &data[i], &classID );
+
+    if ( INTSIZE > length-i )
+    {
+      PRINTF(1)("Cannot read uniqueID from buffer! Not enough data left!\n");
+      return false;
+    }
+    i += Converter::byteArrayToInt( &data[i], &uniqueID );
+
+    if ( INTSIZE > length-i )
+    {
+      PRINTF(1)("Cannot read owner from buffer! Not enough data left!\n");
+      return false;
+    }
+    i += Converter::byteArrayToInt( &data[i], &owner );
+
+    if ( classID != CL_NETWORK_GAME_MANAGER && classID != CL_HANDSHAKE )
+    {
+      BaseObject* b = doCreateEntity( (ClassID)classID, uniqueID, owner );
+
+      /*if ( b != NULL )
+      {
+        if ( b->isA(CL_WORLD_ENTITY) )
+        {
+          int n = dynamic_cast<WorldEntity*>(b)->writeState( data, length, sender );
+
+          i += n;
+        }
+    }*/
+    }
+
+  }
+
+  return true;
+}
+
+bool NetworkGameManager::handleRemoveEntityList( int & i, const byte * data, int length, int sender )
+{
+  if ( INTSIZE > length-i )
+  {
+    PRINTF(1)("Cannot read n from buffer! Not enough data left!\n");
+    return false;
+  }
+  int n;
+  i += Converter::byteArrayToInt( &data[i], &n );
+
+  int uniqueID;
+
+  for ( int j = 0; j<n; j++ )
+  {
+
+    if ( INTSIZE > length-i )
+    {
+      PRINTF(1)("Cannot read uniqueID from buffer! Not enough data left!\n");
+      return false;
+    }
+    i += Converter::byteArrayToInt( &data[i], &uniqueID );
+
+    doRemoveEntity( uniqueID );
+  }
+
+  return true;
+}
+
+bool NetworkGameManager::handleYouAreEntity( int & i, const byte * data, int length, int sender )
+{
+  if ( INTSIZE > length-i )
+  {
+    PRINTF(1)("Cannot read uniqueID from buffer! Not enough data left!\n");
+    return false;
+  }
+
+  int uniqueID;
+  i += Converter::byteArrayToInt( &data[i], &uniqueID );
+
+  doYouAre( uniqueID );
+
+  return true;
+}
+
+bool NetworkGameManager::handleRequestSync( int & i, const byte * data, int length, int sender )
+{
+  if ( INTSIZE > length-i )
+  {
+    PRINTF(1)("Cannot read uniqueID from buffer! Not enough data left!\n");
+    return false;
+  }
+  int uniqueID;
+  i += Converter::byteArrayToInt( &data[i], &uniqueID );
+
+  doRequestSync( uniqueID, sender );
+
+  return true;
+}
+
+bool NetworkGameManager::writeToClientBuffer( clientBuffer & cb, byte b )
+{
+  if ( cb.maxLength-cb.length < 1 )
+  {
+    PRINTF(1)("Cannot write to clientBuffer! Not enough space for 1 byte\n");
+    return false;
+  }
+
+  cb.buffer[cb.length++] = b;
+
+  return true;
+}
+
+bool NetworkGameManager::writeToClientBuffer( clientBuffer & cb, int i )
+{
+  int n = Converter::intToByteArray( i, cb.buffer+cb.length, cb.maxLength-cb.length );
+  cb.length += n;
+
+  if ( n <= 0 )
+  {
+    PRINTF(1)("Cannot write to clientBuffer! Not enough space for 1 int\n");
+    return false;
+  }
+
+  return true;
+}
+
+void NetworkGameManager::sync( int uniqueID, int owner )
+{
+  /*if ( owner==this->getHostID() )
+  return;*/
+
+  if ( !isServer() )
+    executeRequestSync( uniqueID, 0 );
+  else
+    executeRequestSync( uniqueID, owner );
+}
+
+void NetworkGameManager::executeRequestSync( int uniqueID, int user )
+{
+  if ( user >= outBuffer.size() )
+    resizeBufferVector( user );
+
+  if ( !writeToClientBuffer( outBuffer[user], (byte)REQUEST_SYNC ) )
+    return;
+  if ( !writeToClientBuffer( outBuffer[user], uniqueID ) )
+    return;
+}
+
Index: branches/network/src/lib/network/network_game_manager.h
===================================================================
--- branches/network/src/lib/network/network_game_manager.h	(revision 6636)
+++ branches/network/src/lib/network/network_game_manager.h	(revision 6636)
@@ -0,0 +1,131 @@
+/*!
+ * @file entity_manager.h
+ *  Manages creation and destruction of entities
+ */
+
+#ifndef _NETWORK_GAME_MANGER
+#define _NETWORK_GAME_MANAGER
+
+/* include this file, it contains some default definitions */
+#include "netdefs.h"
+
+/* include base_object.h since all classes are derived from this one */
+#include "synchronizeable.h"
+
+
+class TiXmlElement;
+
+/**
+ * protocol definition
+ *
+ *  CREATE_ENTITY:       CLASS_ID, UNIQUE_ID, OWNER
+ *  REMOVE_ENTITY:       UNIQUE_ID
+ *
+ *  CREATE_ENTITY_LIST:  NUMBER, [CLASS_ID, UNIQUE_ID, OWNER][0..NUMBER]
+ *  REMOVE_ENTITY_LIST:  NUMBER, [UNIQUE_ID][0..NUMBER]
+ *
+ *  REQUEST_CREATE:      CLASS_ID
+ *  REQUEST_REMOVE:      UNIQUE_ID
+ *
+ *  //REQUEST_CREATE_LIST: NUMBER, [CLASS_ID][0..NUMBER]
+ *  //REQUEST_CREATE_LIST: NUMBER, [UNIQUE_ID][0..NUMBER]
+ *
+ *  REQUEST_ENTITY_LIST: //request the whole world :D
+ *  REQUEST_SYNC:        UNIQUE_ID
+ *  //REQUEST_SYNC_LIST:   NUMBER, [UNIQUE_ID][0..NUMBER]
+ *
+ *  YOU_ARE_ENTITY:      UNIQUE_ID
+ *
+ */
+
+typedef enum NetworkGameManagerProtocol{
+  CREATE_ENTITY = 0,
+  REMOVE_ENTITY,
+  CREATE_ENTITY_LIST,
+  REMOVE_ENTITY_LIST,
+  REQUEST_CREATE,
+  REQUEST_REMOVE,
+  REQUEST_SYNC,
+  YOU_ARE_ENTITY,
+  REQUEST_ENTITY_LIST
+};
+
+struct clientBuffer
+{
+  int length;
+  int maxLength;
+  byte * buffer;
+};
+
+/*!
+ * a class that can create and remove entities
+ */
+class NetworkGameManager: public Synchronizeable
+{
+  public:
+    ~NetworkGameManager();
+
+    static NetworkGameManager* NetworkGameManager::getInstance()
+    { if (!NetworkGameManager::singletonRef) NetworkGameManager::singletonRef = new NetworkGameManager(); return NetworkGameManager::singletonRef; }
+
+    virtual int writeBytes(const byte* data, int length, int sender);
+    virtual int readBytes(byte* data, int maxLength, int * reciever);
+    virtual void writeDebug() const;
+    virtual void readDebug() const;
+
+    int createEntity( ClassID classID, int owner = 0 );
+    BaseObject* createEntity(const TiXmlElement* element);
+    void removeEntity( int uniqueID );
+    void sendYouAre( int uniqueID, int userID );
+
+    void sync(int uniqueID, int owner);
+
+    void sendEntityList(int userID);
+
+  private:
+    NetworkGameManager();
+
+    void requestCreateEntity(ClassID classID);
+    int executeCreateEntity(ClassID classID, int uniqueID = 0, int owner = 0);
+
+    void requestRemoveEntity(int uniqueID);
+    void executeRemoveEntity(int uniqueID);
+
+    void executeRequestSync( int uniqueID, int user );
+
+    BaseObject* doCreateEntity(ClassID classID, int uniqueID, int owner);
+    void doRemoveEntity(int uniqueID);
+    void doRequestSync(int uniqueID, int userID);
+    void doYouAre( int uniqueID );
+
+    bool canCreateEntity(ClassID classID);
+
+    bool signalNewPlayer(int userId);
+
+    void resizeBufferVector(int n);
+
+    inline bool writeToClientBuffer( clientBuffer &cb, byte*data, int length );
+    inline bool writeToClientBuffer( clientBuffer &cb, byte b );
+    inline bool writeToClientBuffer( clientBuffer &cb, int i );
+    inline bool readFromClientBuffer( clientBuffer &cb, byte*data, int length );
+
+    //helper functions for writeBytes
+    inline bool handleRequestCreate( int& i, const byte* data, int length, int sender );
+    inline bool handleRequestRemove( int& i, const byte* data, int length, int sender );
+    inline bool handleCreateEntity( int& i, const byte* data, int length, int sender );
+    inline bool handleRemoveEntity( int& i, const byte* data, int length, int sender );
+    inline bool handleCreateEntityList( int& i, const byte* data, int length, int sender );
+    inline bool handleRemoveEntityList( int& i, const byte* data, int length, int sender );
+    inline bool handleYouAreEntity( int& i, const byte* data, int length, int sender );
+    inline bool handleRequestSync( int& i, const byte* data, int length, int sender );
+
+  private:
+    std::vector<clientBuffer>     outBuffer;
+    //clientBuffer                  allOutBuffer;
+    static NetworkGameManager*    singletonRef;
+
+    int                           newUniqueID;
+    bool                          hasRequestedWorld;
+};
+
+#endif /*_ENTITY_MANGER*/
Index: branches/network/src/lib/network/network_manager.cc
===================================================================
--- branches/network/src/lib/network/network_manager.cc	(revision 6636)
+++ branches/network/src/lib/network/network_manager.cc	(revision 6636)
@@ -0,0 +1,171 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
+
+#include "network_stream.h"
+#include "class_list.h"
+
+#include "debug.h"
+
+
+/* include your own header */
+#include "network_manager.h"
+
+
+/* using namespace std is default, this needs to be here */
+using namespace std;
+
+
+NetworkManager* NetworkManager::singletonRef = NULL;
+
+/**
+ *  standard constructor
+ */
+NetworkManager::NetworkManager()
+{
+  /* set the class id for the base object */
+  this->setClassID(CL_NETWORK_MANAGER, "NetworkManager");
+  PRINTF(0)("START\n");
+
+  /* initialize the references */
+  this->netStreamList = NULL;
+  this->syncList = NULL;
+  this->tmpStream = NULL;
+
+  this->hostID = -1;
+  this->bGameServer = false;
+
+  PRINTF(0)("NetworkManager created\n");
+}
+
+
+/**
+ *  standard deconstructor
+ */
+NetworkManager::~NetworkManager()
+{}
+
+
+/**
+ *  initializes the network manager
+ */
+void NetworkManager::initialize()
+{
+  /* get the synchronizeable list from the class list */
+  this->netStreamList = ClassList::getList(CL_SYNCHRONIZEABLE);
+  PRINTF(0)("NetworkManager initzalized\n");
+}
+
+
+/**
+ *  shutsdown the network manager
+ */
+void NetworkManager::shutdown()
+{
+
+}
+
+
+/**
+ *  creates a connection from one object to a host
+ * @param hostName: the name of the destination host
+ */
+int NetworkManager::establishConnection(const char* name, unsigned int port)
+{
+  IPaddress ipAddress;
+  int error = SDLNet_ResolveHost(&ipAddress, name, port);
+  if( error == -1) {
+    printf("\n\nerror on address resolution, program inconsistency\n\n");
+    return -1;
+  }
+
+  this->tmpStream = new NetworkStream(ipAddress);
+  return 1;
+}
+
+
+/**
+ *  creates a new NetworkStream of server type
+ * @param port: number of the TCP port
+ */
+int NetworkManager::createServer(unsigned int port)
+{
+  this->hostID = 0;
+  this->bGameServer = true;
+  this->tmpStream = new NetworkStream(port);
+  this->bGameServer = true;
+  SDL_Delay(20);
+  return 1;
+}
+
+
+/**
+ *  creates a connection from one object to a host
+ * @param address: the address of the destination host
+ * @param synchronizeable: reference to the sync object
+ */
+NetworkStream& NetworkManager::establishConnection(IPaddress& address, Synchronizeable& sync)
+{
+  /* creating a new network stream, it will register itself automaticaly to the class list */
+  this->tmpStream = new NetworkStream(address);
+  this->tmpStream->connectSynchronizeable(sync);
+}
+
+
+/**
+ *  teardown a connection
+ */
+void NetworkManager::shutdownConnection()
+{
+  PRINTF(0)("Shutdown connection\n");
+}
+
+
+void NetworkManager::connectSynchronizeable(Synchronizeable& sync)
+{
+  this->tmpStream->connectSynchronizeable(sync);
+}
+
+
+/**
+ *  sync the network
+ */
+void NetworkManager::synchronize()
+{
+  if (this->netStreamList != NULL || (this->netStreamList = ClassList::getList(CL_NETWORK_STREAM)) != NULL)
+  {
+    std::list<BaseObject*>::const_iterator stream;
+    for (stream = this->netStreamList->begin(); stream != this->netStreamList->end(); ++stream)
+      if( static_cast<NetworkStream*>(*stream)->isActive())
+        static_cast<NetworkStream*>(*stream)->processData();
+
+  }
+
+}
+
+/**
+ * Sets the hostID to a specific number
+ * @param id: The new ID
+ */
+void NetworkManager::setHostID(int id)
+{
+    this->hostID = id;
+}
Index: branches/network/src/lib/network/network_manager.h
===================================================================
--- branches/network/src/lib/network/network_manager.h	(revision 6636)
+++ branches/network/src/lib/network/network_manager.h	(revision 6636)
@@ -0,0 +1,69 @@
+/*!
+ * @file network_manager.h
+  *  Main interface for the network module. Manages all the modules
+*/
+
+/* you will want to add such a a line at your header file also, since it will
+   prevent c++ from including your code twice*/
+#ifndef _NETWORK_MANGER
+#define _NETWORK_MANAGER
+
+/* include this file, it contains some default definitions */
+#include "netdefs.h"
+
+/* include base_object.h since all classes are derived from this one */
+#include "base_object.h"
+
+
+/* forward declarations for the header file (include the header via #include "bla.h" in the source file) */
+class NetworkStream;
+class Synchronizeable;
+template<typename>
+class tList;
+
+/* and here is the class itsself*/
+class NetworkManager : public BaseObject
+{
+
+  public:
+
+    inline static NetworkManager* getInstance() { if (!NetworkManager::singletonRef) NetworkManager::singletonRef = new NetworkManager();
+      return NetworkManager::singletonRef; }
+    ~NetworkManager();
+
+    void initialize();
+    void shutdown();
+
+    int establishConnection(const char* name, unsigned int port);
+    int createServer(unsigned int port);
+
+    NetworkStream& establishConnection(IPaddress& address, Synchronizeable& sync);
+    void shutdownConnection();
+
+
+    void setHostID(int id);
+    /** Returns the hostID @return The hostID of the object */
+    inline int getHostID() { return this->hostID; }
+    inline bool isGameServer() { return this->bGameServer; }
+
+
+    void connectSynchronizeable(Synchronizeable& sync);
+    void synchronize();
+
+  private:
+    NetworkManager();
+
+
+  private:
+    const std::list<BaseObject*>*    netStreamList;           // list with refs to all network streams
+    const std::list<BaseObject*>*    syncList;                // list of synchronizeables
+    static NetworkManager*           singletonRef;            //!< Pointer to the only instance of this Class
+    NetworkStream*                   tmpStream;               //!< FIXME: this is only for testing purposes
+    int                              hostID;                  //!< The Host-ID of the Manager
+    bool                             bGameServer;             //!< true if it is a server
+
+};
+
+
+
+#endif /* _NETWORK_MANAGER */
Index: branches/network/src/lib/network/network_protocol.cc
===================================================================
--- branches/network/src/lib/network/network_protocol.cc	(revision 6636)
+++ branches/network/src/lib/network/network_protocol.cc	(revision 6636)
@@ -0,0 +1,120 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Wuest
+   co-programmer: ...
+*/
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
+//#include ...
+
+/* include my own header */
+#include "network_protocol.h"
+
+/* include the synchronizeable object */
+#include "synchronizeable.h"
+
+/* include this file for debugging */
+#include "debug.h"
+
+#include "converter.h"
+
+/* using namespace std is default, this needs to be here */
+using namespace std;
+
+
+/**
+  standard constructor
+*/
+NetworkProtocol::NetworkProtocol()
+{
+  /* set the class id for the base object */
+  this->setClassID(CL_NETWORK_PROTOCOL, "NetworkProtocol");
+  this->headerLength = INTSIZE+FLOATSIZE;
+}
+
+/**
+  standard destructor
+*/
+NetworkProtocol::~NetworkProtocol()
+{}
+
+/**
+    * creates a new packet header from the function arguments
+    *
+    * @arg data: the binary data without header -> return the data in this binary array
+    * @arg length: the data length without header
+    * @arg bufferLength: the length of the internal buffer
+    * @arg source: reference to the source Synchronizeable object
+    * @return: the new data length with header (the header data is included into byte* data)
+    *          -1 if there isn't enough space in the buffer for the header
+*/
+int NetworkProtocol::createHeader(byte* data, int length, int bufferLength, const Synchronizeable& source)
+{
+  PRINTF(5)("create header length = %i, bufferLength = %i\n", length, bufferLength);
+  //If there isn't enough space for the header return -1
+  if (length + 2*INTSIZE > bufferLength)
+    return -1;
+
+
+  // FIXME: without move Create space for the header
+  for( int i = length - 1; i >= 0; i--)
+    data[i + INTSIZE+INTSIZE] = data[i];
+
+  //Now create the header
+  /* sender ID: FIXME: there will be a better ID (for example unique:D)*/
+  //data[0] = (byte)(source.getUniqueID());
+  int res = Converter::intToByteArray( source.getUniqueID(), data, bufferLength );
+
+  /* data length*/
+  //data[1] = length;
+  res += Converter::intToByteArray( length, data+res, bufferLength-res );
+
+
+  return length + res;
+}
+
+/**
+    * extracts the header from the binary data stream
+    * @arg data: the binary data with the header
+    * @arg length: the length of the binary data (including header)
+    * @return: a Header struct with the header information and the binary data
+*/
+Header NetworkProtocol::extractHeader(byte* data, int length)
+{
+  PRINTF(5)("extract Header\n");
+  //Test if received data can contain a header
+  if (length < 2*INTSIZE)
+  {
+    PRINTF(1)("Received data is to short; it can't contain a header!\n");
+    Header h;
+    h.length = 0;
+    return h;
+  }
+
+  //Extract header
+  Header h;
+  //&h = data;
+
+  /* unique ID */
+  //h.synchronizeableID = data[0];
+  int res = Converter::byteArrayToInt( data, &(h.synchronizeableID) );
+  /* data length*/
+  //h.length = data[1];
+  Converter::byteArrayToInt( data+res, &(h.length) );
+
+
+  return h;
+}
Index: branches/network/src/lib/network/network_protocol.h
===================================================================
--- branches/network/src/lib/network/network_protocol.h	(revision 6636)
+++ branches/network/src/lib/network/network_protocol.h	(revision 6636)
@@ -0,0 +1,38 @@
+/*!
+
+*/
+
+#ifndef _NETWORK_PROTOCOL_H
+#define _NETWORK_PROTOCOL_H
+
+/* include base_object.h since all classes are derived from this one */
+#include "base_object.h"
+
+/* include this file, it contains some default definitions */
+#include "netdefs.h"
+
+typedef struct Header
+{
+  int synchronizeableID;
+  int length;
+};
+
+class Synchronizeable;
+
+/*!
+
+*/
+class NetworkProtocol : virtual public BaseObject
+{
+  public:
+    NetworkProtocol();
+    ~NetworkProtocol();
+
+    int createHeader(byte* data, int length, int bufferLength, const Synchronizeable& source);
+    Header extractHeader(byte* data, int length);
+
+  private:
+    unsigned int headerLength; //The Length of the Header in bytes
+};
+
+#endif //_NETWORK_PROTOCOL_H
Index: branches/network/src/lib/network/network_socket.cc
===================================================================
--- branches/network/src/lib/network/network_socket.cc	(revision 6636)
+++ branches/network/src/lib/network/network_socket.cc	(revision 6636)
@@ -0,0 +1,446 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner, David Hasenfratz
+   co-programmer:
+*/
+
+
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
+#include "converter.h"
+
+/* include your own header */
+#include "network_socket.h"
+
+/* header for debug output */
+#include "debug.h"
+
+/**
+ * Default constructor
+ */
+NetworkSocket::NetworkSocket()
+{
+  this->init();
+}
+
+/**
+ * Constructor to connect directly
+ */
+NetworkSocket::NetworkSocket(IPaddress ip)
+{
+  this->init();
+  connectToServer(ip);
+}
+
+
+NetworkSocket::NetworkSocket( TCPsocket sock )
+{
+  this->init();
+  this->tcpSocket = sock;
+
+  readThread = SDL_CreateThread(thread_read, (void*)this);
+  writeThread = SDL_CreateThread(thread_write, (void*)this);
+}
+
+void NetworkSocket::init()
+{
+  /* set the class id for the base object */
+  this->setClassID(CL_NETWORK_SOCKET, "NetworkSocket");
+
+  tcpSocket = NULL;
+  incomingBufferLength = 0;
+  outgoingBufferLength = 0;
+
+  readThread = NULL;
+  writeThread = NULL;
+
+
+  thread_write_running = false;
+  thread_read_running = false;
+
+  incomingBufferMutex = SDL_CreateMutex();
+  outgoingBufferMutex = SDL_CreateMutex();
+
+
+  socketMutex = SDL_CreateMutex();
+  terminateThread = false;
+
+  /* Init SDL_net */
+  //NOTE: do we need to call SDLNet_Init for all instances?
+  if(SDLNet_Init()==-1)
+  {
+    PRINTF(1)("SDLNet_Init: %s\n", SDLNet_GetError());
+    return;
+  }
+  else
+    PRINTF(5)("SDL_net initialized\n");
+
+  PRINTF(0)("NetworkSocket created\n");
+
+}
+
+
+
+/**
+ * Default destructor
+ */
+NetworkSocket::~NetworkSocket( )
+{
+  this->terminateThread = true;
+  /* Quit SDL_net */
+  // NOTE: what if other instances of NetworkSocket running?
+  SDLNet_Quit();
+  PRINTF(5)("SDL_net shutdown\n");
+
+  SDL_DestroyMutex(incomingBufferMutex);
+  SDL_DestroyMutex(outgoingBufferMutex);
+  SDL_DestroyMutex(socketMutex);
+  SDL_DestroyMutex(threadTerminationMutex);
+}
+
+/**
+ * This function establishes a TCP/UDP connection to a given server (function argument).
+ * It is called by the NetworkStream. It creates a TCP/UDP socket for the connection.
+ * @param ip
+ */
+void NetworkSocket::connectToServer(IPaddress ip)
+{
+  //check if not already connected or listening
+  if (tcpSocket)
+  {
+    PRINTF(1)("NetworkSocket::listen: tcpSocket!=NULL! maybe you already called listen or connectToServer or did not call disconnectServer()!");
+  }
+
+  /* Connect to the host and port contained in ip using a TCP connection. */
+  tcpSocket = SDLNet_TCP_Open(&ip);
+  if(!tcpSocket)
+  {
+    PRINTF(1)("SDLNet_TCP_Open: %s\n", SDLNet_GetError());
+    return;
+  }
+
+  readThread = SDL_CreateThread(thread_read, (void*)this);
+  writeThread = SDL_CreateThread(thread_write, (void*)this);
+}
+
+
+/**
+ * DTears down a TCP/UDP connection.
+ */
+void NetworkSocket::disconnectServer( )
+{
+  terminateThread = true;
+  /* Close the connection */
+
+  SDL_mutexP(socketMutex);
+  SDLNet_TCP_Close(tcpSocket);
+  tcpSocket = NULL;
+  SDL_mutexV(socketMutex);
+}
+
+
+/**
+ * This function writes some bytes (data) to the network connection (if the connection is already
+ * estabilhed) otherwise it just does nothing (silently discarding the data). And writes some
+ * warnings
+ * @param data: pointer to the data to send
+ * @param length: n bytes to send
+ * @return the number successfully written bytes
+ */
+int NetworkSocket::writeBytes(byte * data, int length)
+{
+  PRINTF(5)("NetworkSocket::writeBytes()\n");
+#ifdef _USE_OUTGOING_BUFFER
+
+#define min(a,b) (a<b)?a:b
+  int nbytes = min(_OUTGOING_BUFFER_SIZE - outgoingBufferLength, length);
+#undef min
+
+  if (!tcpSocket || data==NULL || nbytes<=0)
+    return 0;
+
+  SDL_mutexP(outgoingBufferMutex);
+
+  memcpy(outgoingBuffer + outgoingBufferLength, data, nbytes);
+  outgoingBufferLength += nbytes;
+
+  SDL_mutexV(outgoingBufferMutex);
+
+
+  return nbytes;
+#else
+  SDL_mutexP(socketMutex);
+
+  if (!tcpSocket || data==NULL)
+    return 0;
+
+  int res = SDLNet_TCP_Send(tcpSocket, data, length);
+
+  SDL_mutexV(socketMutex);
+
+  if (res<length)
+    PRINTF(1)("SDLNet_TCP_Send: %s\n", SDLNet_GetError());
+
+  return res;
+#endif
+}
+
+/**
+ * Reads in the bytes from the network interface and passes it to the NetworkStream.
+ * This function must internaly be implemented/connected as a thread, since the read
+ * functions of many network libraries are blocking an would therefore block the whole
+ * program.
+ * From outside, the thread shouldn't be accessible at all.
+ * @param data: pointer to memory, big enough to store length bytes
+ * @param length: n bytes to read
+ * @return the number successfully read bytes. -1 on error. may be less than length!
+ */
+int NetworkSocket::readBytes(byte * data, int length)
+{
+  PRINTF(5)("NetworkSocket::readBytes()\n");
+  if (data==NULL)
+    return 0;
+
+  int nbytes = (length<incomingBufferLength) ? length : incomingBufferLength;
+
+
+  //printf("readBytes: nbytes = %d; length=%d; incomingBufferLength=%d\n", nbytes, length, incomingBufferLength);
+
+  // just in case ...
+  if (nbytes<0)
+    return -1;
+
+  if (nbytes==0)
+      return 0;
+
+  SDL_mutexP(incomingBufferMutex);
+
+  memcpy(data, incomingBuffer, nbytes);
+
+  //important: use memmove because the memory areas may overlap
+  memmove(incomingBuffer, incomingBuffer+nbytes, incomingBufferLength-nbytes);
+  incomingBufferLength -= nbytes;
+
+  SDL_mutexV(incomingBufferMutex);
+
+  return nbytes;
+}
+
+/**
+ * Reads in the bytes form the network interface and passes it to the NetworkStream.
+ * It only reads the bytes if there are enough bytes in our buffer.
+ * @param data: pointer to memory, big enough to store length bytes
+ * @param length: n bytes to read
+ * @return the number successfully read bytes. -1 on error. 0 if there are not enough bytes in our buffer.
+ */
+int NetworkSocket::readBlock(byte * data, int length)
+{
+  printf("NetworkSocket: got %i bytes, NetworkStream requested %i bytes\n", this->incomingBufferLength, length);
+  if (incomingBufferLength >= length)
+    return readBytes(data, length);
+  else return 0;
+}
+
+
+/**
+ * used to create a thread to read from socket
+ * @param data: pointer to NetworkSocket
+ */
+int NetworkSocket::thread_read( void * data )
+{
+  int nbytesread = 0;
+  int nbytestoread = 0;
+  char buffer[_LOCAL_BUFFER_SIZE];
+  NetworkSocket * self = (NetworkSocket*)data;
+
+  self->thread_read_running = true;
+
+  while (!self->terminateThread)
+  {
+#define min(a,b) (a<b)?a:b
+    nbytestoread = min(_INCOMING_BUFFER_SIZE - self->incomingBufferLength, _LOCAL_BUFFER_SIZE);
+#undef min
+
+    //if buffer is full
+    if (nbytestoread<=0 || !self->tcpSocket)
+    {
+      SDL_Delay(_MSECONDS_SLEEP_FULL_BUFFER);
+      continue;
+    }
+
+    nbytesread = SDLNet_TCP_Recv(self->tcpSocket, buffer, nbytestoread);
+
+    SDL_mutexP(self->incomingBufferMutex);
+
+    if (nbytesread<=0)
+    {
+      if (nbytesread<0)
+        printf("SDLNet_TCP_Recv: %s\n", SDLNet_GetError());
+
+      SDL_mutexP(self->socketMutex);
+
+      SDLNet_TCP_Close(self->tcpSocket);
+      self->tcpSocket = NULL;
+
+      SDL_mutexV(self->socketMutex);
+      SDL_mutexV(self->incomingBufferMutex);
+      continue;
+    }
+
+    //printf("thread_read: nbytesread=%d\n", nbytesread);
+
+    memcpy(self->incomingBuffer+self->incomingBufferLength, buffer, nbytesread);
+    self->incomingBufferLength += nbytesread;
+
+    SDL_mutexV(self->incomingBufferMutex);
+  }
+
+  SDL_mutexP(self->threadTerminationMutex);
+  self->thread_read_running = false;
+
+  if ( !self->thread_write_running )
+  {
+    //delete self;
+    SDL_mutexV(self->threadTerminationMutex);
+  }
+  else
+  {
+    SDL_mutexV(self->threadTerminationMutex);
+  }
+
+
+  PRINTF(0)("QUIT READ THREAD\n");
+  return 0;
+}
+
+int NetworkSocket::thread_write( void * data )
+{
+  int nbyteswrite = 0;
+  int nbytestowrite = 0;
+  char buffer[_LOCAL_BUFFER_SIZE];
+  NetworkSocket * self = (NetworkSocket*)data;
+
+  self->thread_write_running = true;
+
+  while (!self->terminateThread)
+  {
+#define min(a,b) (a<b)?a:b
+    nbytestowrite = min(self->outgoingBufferLength, _LOCAL_BUFFER_SIZE);
+#undef min
+
+//     printf("thread_write nbytes=%d listening=%d\n", nbytestowrite, (int)self->_isListening);
+
+    //if buffer is full
+    if (nbytestowrite<=0 || !self->tcpSocket)
+    {
+      SDL_Delay(_MSECONDS_SLEEP_EMPTY_BUFFER);
+      continue;
+    }
+
+    SDL_mutexP(self->outgoingBufferMutex);
+
+    //printf("a\n");
+
+    memcpy(buffer, self->outgoingBuffer, nbytestowrite);
+    self->outgoingBufferLength -= nbytestowrite;
+    memmove(self->outgoingBuffer, self->outgoingBuffer+nbytestowrite, self->outgoingBufferLength);
+
+    SDL_mutexV(self->outgoingBufferMutex);
+
+    nbyteswrite = SDLNet_TCP_Send(self->tcpSocket, buffer, nbytestowrite);
+
+    if (nbyteswrite<=0)
+    {
+      printf("SDLNet_TCP_Recv: %s\n", SDLNet_GetError());
+
+      SDL_mutexP(self->socketMutex);
+
+      SDLNet_TCP_Close(self->tcpSocket);
+      self->tcpSocket = NULL;
+
+      SDL_mutexV(self->socketMutex);
+      continue;
+    }
+
+  }
+
+  SDL_mutexP(self->threadTerminationMutex);
+  self->thread_write_running = false;
+
+  if ( !self->thread_read_running )
+  {
+    //delete self;
+    SDL_mutexV(self->threadTerminationMutex);
+  }
+  else
+  {
+    SDL_mutexV(self->threadTerminationMutex);
+  }
+
+
+  PRINTF(0)("QUIT WRITE THREAD\n");
+  return 0;
+}
+
+bool NetworkSocket::writePacket( byte * data, int length )
+{
+  PRINTF(5)("NetworkSocket::writePacket() size=%d\n", length);
+
+  if ( length > 1024 )
+  PRINTF(2)("WARNING SENDING BIG PACKET SIZE = %d\n", length);
+
+  byte blen[INTSIZE];
+
+  Converter::intToByteArray( length, blen, INTSIZE );
+
+  writeBytes(blen, INTSIZE);
+  writeBytes(data, length);
+}
+
+int NetworkSocket::readPacket( byte * data, int maxLength )
+{
+  PRINTF(5)("NetworkSocket::readPacket()\n");
+  if (incomingBufferLength<INTSIZE)
+  {
+    return 0;
+  }
+
+  int blen;
+  Converter::byteArrayToInt( incomingBuffer, &blen );
+
+  if (blen>maxLength)
+  {
+    PRINTF(1)("Buffersize is too small (%d) for packet (%d)\n", maxLength, blen);
+    return 0;
+  }
+
+  if (blen>incomingBufferLength)
+  {
+    return 0;
+  }
+
+  byte t[INTSIZE];
+  readBytes(t, INTSIZE);
+  int res = readBytes(data, blen);
+
+  if (res!=blen)
+    return -1;
+  else
+    return blen;
+
+}
+
+
Index: branches/network/src/lib/network/network_socket.h
===================================================================
--- branches/network/src/lib/network/network_socket.h	(revision 6636)
+++ branches/network/src/lib/network/network_socket.h	(revision 6636)
@@ -0,0 +1,106 @@
+/*!
+ * @file network_socket.h
+  *  Main interface for the network module. Manages all the modules
+
+*/
+
+#ifndef _NETWORK_SOCKET
+#define _NETWORK_SOCKET
+
+//if you want to use outgoing buffer define _USE_OUTGOING_BUFFER
+#define _USE_OUTGOING_BUFFER
+
+#define _INCOMING_BUFFER_SIZE 10240
+#define _OUTGOING_BUFFER_SIZE 2024000
+#define _LOCAL_BUFFER_SIZE 1024
+//sleep if incoming buffer is full
+#define _MSECONDS_SLEEP_FULL_BUFFER 10
+//sleep if outgoing buffer is empty
+#define _MSECONDS_SLEEP_EMPTY_BUFFER 10
+
+
+/* contains memmove and memcpy */
+#include <string.h>
+
+#ifdef HAVE_SDL_H
+ #include <SDL_thread.h>
+#else
+ #include <SDL/SDL_thread.h>
+#endif
+/* include this file, it contains some default definitions */
+#include "netdefs.h"
+
+
+/* include base_object.h since all classes are derived from this one */
+#include "base_object.h"
+
+/* using namespace std is default, this needs to be here */
+using namespace std;
+
+class NetworkSocket : public BaseObject
+{
+
+private:
+//  IPaddress serverAddress;
+//  unsigned int port;
+  TCPsocket tcpSocket;
+//  UDPsocket udpSocket;
+
+  byte incomingBuffer[_INCOMING_BUFFER_SIZE];
+#ifdef _USE_OUTGOING_BUFFER
+  byte outgoingBuffer[_OUTGOING_BUFFER_SIZE];
+#endif
+  int incomingBufferLength;
+#ifdef _USE_OUTGOING_BUFFER
+  int outgoingBufferLength;
+#endif
+
+  SDL_mutex * incomingBufferMutex;
+#ifdef _USE_OUTGOING_BUFFER
+  SDL_mutex * outgoingBufferMutex;
+#endif
+  SDL_mutex * socketMutex;
+  bool terminateThread;
+
+  SDL_mutex* threadTerminationMutex;
+  static int thread_read(void * data);
+  bool thread_read_running;
+  bool thread_write_running;
+
+  SDL_Thread*            readThread;
+  SDL_Thread*            writeThread;
+
+#ifdef _USE_OUTGOING_BUFFER
+  static int thread_write(void * data);
+#endif
+
+  int writeBytes(byte * data, int length);
+  int readBytes(byte * data, int length);
+  int readBlock(byte * data, int length);
+
+  void init();
+
+  //dont make this public use destroy() instead
+  ~NetworkSocket();
+
+public:
+
+  NetworkSocket();
+  NetworkSocket(IPaddress ip);
+  NetworkSocket(TCPsocket sock);
+  void destroy() { terminateThread = true; };
+
+
+  void connectToServer(IPaddress ip);
+  void disconnectServer();
+
+  bool writePacket(byte * data, int length);
+  int readPacket(byte * data, int maxLength);
+
+  inline bool isOk() { return tcpSocket!=NULL; }
+
+};
+
+
+
+#endif /* _NETWORK_SOCKET */
Index: branches/network/src/lib/network/network_stream.cc
===================================================================
--- branches/network/src/lib/network/network_stream.cc	(revision 6636)
+++ branches/network/src/lib/network/network_stream.cc	(revision 6636)
@@ -0,0 +1,417 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: claudio
+   co-programmer:
+*/
+
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
+
+#include "base_object.h"
+#include "network_protocol.h"
+#include "network_socket.h"
+#include "connection_monitor.h"
+#include "synchronizeable.h"
+#include "network_manager.h"
+#include "network_game_manager.h"
+
+#include "debug.h"
+#include "class_list.h"
+#include <algorithm>
+
+/* include your own header */
+#include "network_stream.h"
+
+/* probably unnecessary */
+using namespace std;
+
+
+#define PACKAGE_SIZE  256
+
+
+NetworkStream::NetworkStream()
+    : DataStream()
+{
+  this->init();
+  /* initialize the references */
+  this->type = NET_CLIENT;
+  this->networkProtocol = new NetworkProtocol();
+  this->connectionMonitor = new ConnectionMonitor();
+}
+
+NetworkStream::NetworkStream(IPaddress& address)
+{
+  this->type = NET_CLIENT;
+  this->init();
+  this->networkSockets.push_back(new NetworkSocket(address));
+  this->networkProtocol = new NetworkProtocol();
+  this->connectionMonitor = new ConnectionMonitor();
+
+  Handshake* hs = new Handshake(false);
+  hs->setUniqueID( 0 );
+  this->handshakes.push_back(hs);
+  this->connectSynchronizeable(*hs);
+  PRINTF(0)("NetworkStream: %s\n", hs->getName());
+  this->maxConnections = 1;
+}
+
+
+NetworkStream::NetworkStream(unsigned int port)
+{
+  this->type = NET_SERVER;
+  this->init();
+  this->serverSocket = new ServerSocket(port);
+  this->networkProtocol = new NetworkProtocol();
+  this->connectionMonitor = new ConnectionMonitor();
+  this->networkSockets.push_back( NULL );
+  this->networkSockets[0] = NULL; //TODO: remove this
+  this->handshakes.push_back( NULL );
+  this->bActive = true;
+  this->networkGameManager = NetworkGameManager::getInstance();
+  // setUniqueID( maxCon+2 ) because we need one id for every handshake
+  // and one for handshake to reject client maxCon+1
+  this->networkGameManager->setUniqueID( this->maxConnections+2 );
+  this->connectSynchronizeable( *(this->networkGameManager) );
+
+  this->setMaxConnections( 10 );
+}
+
+
+void NetworkStream::init()
+{
+  /* set the class id for the base object */
+  this->setClassID(CL_NETWORK_STREAM, "NetworkStream");
+  this->bActive = false;
+  this->serverSocket = NULL;
+  this->networkGameManager = NULL;
+  myHostId = 0;
+}
+
+
+NetworkStream::~NetworkStream()
+{
+  if ( this->serverSocket )
+  {
+    serverSocket->close();
+    delete serverSocket;
+  }
+
+  for (NetworkSocketVector::iterator i = networkSockets.begin(); i!=networkSockets.end(); i++)
+  {
+    if ( *i )
+    {
+      (*i)->disconnectServer();
+      (*i)->destroy();
+    }
+  }
+
+  for (HandshakeVector::iterator i = handshakes.begin(); i!=handshakes.end(); i++)
+  {
+    if ( *i )
+    {
+      delete (*i);
+    }
+  }
+
+  delete connectionMonitor;
+  delete networkProtocol;
+}
+
+
+void NetworkStream::connectSynchronizeable(Synchronizeable& sync)
+{
+  this->synchronizeables.push_back(&sync);
+  sync.setNetworkStream( this );
+
+  if( this->networkSockets.size()>0 )
+    this->bActive = true;
+}
+
+void NetworkStream::disconnectSynchronizeable(Synchronizeable& sync)
+{
+  // removing the Synchronizeable from the List.
+  std::list<Synchronizeable*>::iterator disconnectSynchro = std::find(this->synchronizeables.begin(), this->synchronizeables.end(), &sync);
+  if (disconnectSynchro != this->synchronizeables.end())
+    this->synchronizeables.erase(disconnectSynchro);
+
+  if( this->networkSockets.size()<=0 )
+    this->bActive = false;
+}
+
+
+void NetworkStream::processData()
+{
+  if ( this->type == NET_SERVER )
+    this->updateConnectionList();
+  else
+  {
+    if ( networkSockets[0] && !networkSockets[0]->isOk() )
+    {
+      PRINTF(1)("lost connection to server\n");
+
+      //delete networkSockets[i];
+      networkSockets[0]->disconnectServer();
+      networkSockets[0]->destroy();
+      networkSockets[0] = NULL;
+
+      if ( handshakes[0] )
+        delete handshakes[0];
+      handshakes[0] = NULL;
+    }
+  }
+
+  for (int i = 0; i<handshakes.size(); i++)
+  {
+    if ( handshakes[i] )
+    {
+      if ( handshakes[i]->completed() )
+      {
+        if ( handshakes[i]->ok() )
+        {
+          if ( type != NET_SERVER )
+          {
+            NetworkManager::getInstance()->setHostID( handshakes[i]->getHostId() );
+            myHostId = NetworkManager::getInstance()->getHostID();
+
+            this->networkGameManager = NetworkGameManager::getInstance();
+            this->networkGameManager->setUniqueID( handshakes[i]->getNetworkGameManagerId() );
+            this->connectSynchronizeable( *(this->networkGameManager) );
+          }
+          else
+          {
+
+          }
+          PRINT(0)("handshake finished id=%d\n", handshakes[i]->getNetworkGameManagerId());
+
+
+          delete handshakes[i];
+          handshakes[i] = NULL;
+        }
+        else
+        {
+          PRINT(1)("handshake failed!\n");
+          networkSockets[i]->disconnectServer();
+          delete handshakes[i];
+          handshakes[i] = NULL;
+          //TODO: handle error
+        }
+      }
+    }
+  }
+
+
+  /* DOWNSTREAM */
+
+  int dataLength;
+  int reciever;
+  Header header;
+  for (SynchronizeableList::iterator it = synchronizeables.begin(); it!=synchronizeables.end(); it++)
+  {
+    if ( (*it)!=NULL /*&& (*it)->getOwner() == myHostId*/ )
+    {
+      do {
+        reciever = 0;
+        dataLength = (*it)->readBytes(downBuffer, DATA_STREAM_BUFFER_SIZE, &reciever);
+
+
+        if ( dataLength<=0 ){
+          reciever = 0;
+          continue;
+        }
+
+        dataLength = networkProtocol->createHeader((byte*)downBuffer, dataLength, DATA_STREAM_BUFFER_SIZE, static_cast<const Synchronizeable&>(*(*it)));
+
+        Header* header = (Header*)downBuffer;
+        if ( header->synchronizeableID < this->maxConnections+2 )
+        {
+          //if ( !isServer() ) PRINTF(0)("RESET UNIQUEID FROM %d TO 0 maxCon=%d\n", header->synchronizeableID, this->maxConnections);
+          header->synchronizeableID = 0;
+        }
+        else
+        {
+          //if ( !isServer() ) PRINTF(0)("UNIQUEID=%d\n", header->synchronizeableID);
+        }
+
+        if ( dataLength<=0 )
+          continue;
+
+        if ( reciever!=0 )
+        {
+          if ( networkSockets[reciever] != NULL )
+          {
+            PRINTF(5)("write %d bytes to socket %d\n", dataLength, reciever);
+            networkSockets[reciever]->writePacket(downBuffer, dataLength);
+          }
+          else
+          {
+            PRINTF(1)("networkSockets[reciever] == NULL\n");
+          }
+        }
+        else
+        {
+          for ( int i = 0; i<networkSockets.size(); i++)
+          {
+            if ( networkSockets[i] != NULL )
+            {
+              PRINTF(5)("write %d bytes to socket %d\n", dataLength, i);
+              networkSockets[i]->writePacket(downBuffer, dataLength);
+            }
+          }
+        }
+
+      } while( reciever!=0 );
+    }
+  }
+
+  /* UPSTREAM */
+
+  for ( int i = 0; i<networkSockets.size(); i++)
+  {
+    if ( networkSockets[i] )
+    {
+      do {
+        dataLength = networkSockets[i]->readPacket(upBuffer, DATA_STREAM_BUFFER_SIZE);
+
+        if ( dataLength<=0 )
+          continue;
+
+        header = networkProtocol->extractHeader(upBuffer, dataLength);
+        dataLength -= sizeof(header);
+
+        PRINTF(5)("read %d bytes from socket uniqueID = %d\n", dataLength, header.synchronizeableID);
+
+        if ( dataLength != header.length )
+        {
+          PRINTF(1)("packetsize in header and real packetsize do not match! %d:%d\n", dataLength, header.length);
+          continue;
+        }
+
+        if ( header.synchronizeableID == 0 )
+        {
+          header.synchronizeableID = i;
+        }
+
+        for (SynchronizeableList::iterator it = synchronizeables.begin(); it!=synchronizeables.end(); it++)
+        {
+          if ( *it && (*it)->getUniqueID()==header.synchronizeableID )
+          {
+            if ( (*it)->writeBytes(upBuffer+sizeof(header), dataLength, i) != header.length )
+            {
+              PRINTF(1)("%s did not read all the data id = %d!\n", (*it)->getClassName(), (*it)->getUniqueID());
+              break;
+            }
+            continue;
+          }
+        }
+
+      } while ( dataLength>0 );
+    }
+  }
+}
+
+void NetworkStream::updateConnectionList( )
+{
+  //check for new connections
+
+  NetworkSocket* tempNetworkSocket = serverSocket->getNewSocket();
+
+  if ( tempNetworkSocket )
+  {
+    int clientId;
+    if ( freeSocketSlots.size() >0 )
+    {
+      clientId = freeSocketSlots.back();
+      freeSocketSlots.pop_back();
+      networkSockets[clientId] = tempNetworkSocket;
+      handshakes[clientId] = new Handshake(true, clientId, this->networkGameManager->getUniqueID());
+      handshakes[clientId]->setUniqueID(clientId);
+    } else
+    {
+      clientId = networkSockets.size();
+      networkSockets.push_back(tempNetworkSocket);
+      Handshake* tHs = new Handshake(true, clientId, this->networkGameManager->getUniqueID());
+      tHs->setUniqueID(clientId);
+      handshakes.push_back(tHs);
+    }
+
+    if ( clientId > this->maxConnections )
+    {
+      handshakes[clientId]->doReject();
+      PRINTF(0)("Will reject client %d because there are to many connections!\n", clientId);
+    }
+    else
+
+    PRINTF(0)("New Client: %d\n", clientId);
+
+    this->connectSynchronizeable(*handshakes[clientId]);
+  }
+
+
+  //check if connections are ok else remove them
+  for ( int i = 1; i<networkSockets.size(); i++)
+  {
+    if ( networkSockets[i] && !networkSockets[i]->isOk() )
+    {
+      //TODO: tell EntityManager that this player left the game
+      PRINTF(0)("Client is gone: %d\n", i);
+
+      //delete networkSockets[i];
+      networkSockets[i]->disconnectServer();
+      networkSockets[i]->destroy();
+      networkSockets[i] = NULL;
+
+      if ( handshakes[i] )
+        delete handshakes[i];
+      handshakes[i] = NULL;
+
+      if ( i == networkSockets.size()-1 )
+      {
+        networkSockets.pop_back();
+        handshakes.pop_back();
+      }
+      else
+      {
+        freeSocketSlots.push_back(i);
+      }
+    }
+  }
+
+
+}
+
+void NetworkStream::setMaxConnections( int n )
+{
+  if ( !this->isServer() )
+  {
+    PRINTF(1)("Cannot set maxConnections because I am no server.\n");
+  }
+  if ( this->networkSockets.size() > 1 )
+  {
+    PRINTF(1)("Cannot set maxConnections because there are already %d connections.\n", this->networkSockets.size());
+    return;
+  }
+
+  if ( n > MAX_CONNECTIONS )
+  {
+    PRINTF(1)("Cannot set maxConnectiosn to %d because of hardcoded limit %d\n", n, MAX_CONNECTIONS);
+    return;
+  }
+
+  this->maxConnections = n;
+  this->networkGameManager->setUniqueID( n+2 );
+}
+
+
Index: branches/network/src/lib/network/network_stream.h
===================================================================
--- branches/network/src/lib/network/network_stream.h	(revision 6636)
+++ branches/network/src/lib/network/network_stream.h	(revision 6636)
@@ -0,0 +1,78 @@
+/*!
+ * @file network_stream.h
+ *  implementation of a network pipe
+ */
+
+#ifndef _NETWORK_STREAM
+#define _NETWORK_STREAM
+
+#include <vector>
+#include <list>
+
+#include "data_stream.h"
+#include "network_protocol.h"
+#include "server_socket.h"
+#include "handshake.h"
+
+#define MAX_CONNECTIONS 1000
+
+class Synchronizeable;
+class NetworkSocket;
+class ServerSocket;
+class ConnectionMonitor;
+class NetworkProtocol;
+class NetworkGameManager;
+
+typedef std::list<Synchronizeable*>  SynchronizeableList;
+typedef std::vector<NetworkSocket*>  NetworkSocketVector;
+typedef std::vector<Handshake*>      HandshakeVector;
+
+
+class NetworkStream : public DataStream
+{
+
+  public:
+    NetworkStream();
+    NetworkStream(IPaddress& address);
+    NetworkStream(unsigned int port);
+
+    ~NetworkStream();
+    void init();
+
+    void connectSynchronizeable(Synchronizeable& sync);
+    void disconnectSynchronizeable(Synchronizeable& sync);
+
+    inline bool isServer() const { return (this->type == NET_SERVER)? true:false; }
+    inline bool isActive() const { return this->bActive; }
+
+    inline int getMaxConnections(){ return maxConnections; }
+    void setMaxConnections( int n );
+
+    virtual void processData();
+
+    inline SynchronizeableList::const_iterator getSyncBegin(){ return synchronizeables.begin(); }
+    inline SynchronizeableList::const_iterator getSyncEnd(){ return synchronizeables.end(); }
+    inline int getSyncCount(){ return synchronizeables.size(); }
+
+    inline bool isUserIdActive( int userID ) { if (userID>=networkSockets.size()) return false; else return networkSockets[userID]!=NULL; }
+
+  private:
+    NetworkProtocol*       networkProtocol;
+    ConnectionMonitor*     connectionMonitor;
+    SynchronizeableList    synchronizeables;
+    NetworkSocketVector    networkSockets;
+    HandshakeVector        handshakes;
+    ServerSocket*          serverSocket;
+    int                    type;
+    Header                 packetHeader;
+    bool                   bActive;
+    std::list<int>         freeSocketSlots;
+
+    int                    myHostId;
+    int                    maxConnections;
+
+    NetworkGameManager*   networkGameManager;
+
+    void updateConnectionList();
+};
+#endif /* _NETWORK_STREAM */
Index: branches/network/src/lib/network/server_socket.cc
===================================================================
--- branches/network/src/lib/network/server_socket.cc	(revision 6636)
+++ branches/network/src/lib/network/server_socket.cc	(revision 6636)
@@ -0,0 +1,143 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Christoph Renner
+   co-programmer:
+*/
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+   For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
+
+/* include your own header */
+#include "server_socket.h"
+
+/* header for debug output */
+#include "debug.h"
+
+ServerSocket::ServerSocket(  )
+{
+  init();
+}
+
+ServerSocket::ServerSocket( unsigned int port )
+{
+  init();
+  listen(port);
+}
+
+/**
+ * Default destructor
+ */
+ServerSocket::~ServerSocket( )
+{
+  /* Quit SDL_net */
+  // NOTE: what if other instances of NetworkSocket running?
+  SDLNet_Quit();
+  PRINTF(5)("SDL_net shutdown\n");
+
+  _isListening = false;
+}
+
+void ServerSocket::init( )
+{
+  /* set the class id for the base object */
+  this->setClassID(CL_SERVER_SOCKET, "ServerSocket");
+
+  terminateThread = false;
+  listenSocket = NULL;
+  _isListening = false;
+
+  if(SDLNet_Init()==-1)
+  {
+    PRINTF(1)("SDLNet_Init: %s\n", SDLNet_GetError());
+    return;
+  }
+  else
+    PRINTF(5)("SDL_net initialized\n");
+
+  PRINTF(0)("ServerSocket created\n");
+}
+
+
+/**
+ * Tells the NetworkSocket to listen on a specific port for incoming connections.
+ * NetworkSocket::writeBytes(...) will have no effect until there is a valuable connection.
+ * @param port
+ */
+bool ServerSocket::listen(unsigned int port)
+{
+  PRINTF(0)("ServerSocket::listen()\n");
+  _isListening = true;
+  //check if not already connected or listening
+  if (listenSocket)
+  {
+    PRINTF(1)("ServerSocket::listen: tcpSocket!=NULL! maybe you already called listen or did not call close()!\n");
+    _isListening = false;
+    return false;
+  }
+
+  IPaddress ip;
+
+  if (SDLNet_ResolveHost(&ip, NULL, port)==-1)
+  {
+    PRINTF(1)("SDLNet_ResolveHost: %s\n", SDLNet_GetError());
+    _isListening = false;
+    return false;
+  }
+
+  listenSocket = SDLNet_TCP_Open(&ip);
+
+  if (!listenSocket)
+  {
+    PRINTF(1)("SDLNet_TCP_Open: %s\n", SDLNet_GetError());
+    _isListening = false;
+    return false;
+  }
+
+  return true;
+}
+
+
+NetworkSocket* ServerSocket::getNewSocket( )
+{
+  if ( !listenSocket )
+  {
+    PRINTF(1)("listenSocket == NULL! Maybe you forgot to call listen()\n");
+    close();
+    return NULL;
+  }
+
+  TCPsocket sock = SDLNet_TCP_Accept(listenSocket);
+
+  if ( !sock )
+  {
+    return NULL;
+  }
+  else
+  {
+    return new NetworkSocket(sock);
+  }
+}
+
+void ServerSocket::close( )
+{
+  if ( listenSocket )
+  {
+    SDLNet_TCP_Close( listenSocket );
+    listenSocket = NULL;
+  }
+
+  _isListening = false;
+}
+
Index: branches/network/src/lib/network/server_socket.h
===================================================================
--- branches/network/src/lib/network/server_socket.h	(revision 6636)
+++ branches/network/src/lib/network/server_socket.h	(revision 6636)
@@ -0,0 +1,46 @@
+/*!
+ * @file server_socket.h
+ *  waits for incoming connections
+
+ */
+
+#ifndef _SERVER_SOCKET
+#define _SERVER_SOCKET
+
+#ifdef HAVE_SDL_H
+#include <SDL_thread.h>
+#else
+#include <SDL/SDL_thread.h>
+#endif
+/* include this file, it contains some default definitions */
+#include "netdefs.h"
+
+
+/* include base_object.h since all classes are derived from this one */
+#include "base_object.h"
+#include "network_socket.h"
+
+//sleep when waiting for connections
+#define _MSECONDS_SLEEP_LISTEN 100
+
+class ServerSocket : public BaseObject
+{
+  private:
+    TCPsocket listenSocket;
+    bool terminateThread;
+
+    bool _isListening;
+
+    void init();
+
+  public:
+    ServerSocket();
+    ServerSocket( unsigned int port );
+    ~ServerSocket();
+    bool listen( unsigned int port );
+    NetworkSocket* getNewSocket( void );
+    void close();
+    inline bool isOk(){ return listenSocket!=NULL; }
+};
+
+#endif
Index: branches/network/src/lib/network/synchronizeable.cc
===================================================================
--- branches/network/src/lib/network/synchronizeable.cc	(revision 6636)
+++ branches/network/src/lib/network/synchronizeable.cc	(revision 6636)
@@ -0,0 +1,142 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+
+### File Specific:
+   main-programmer: Silvan Nellen
+   co-programmer: Benjamin Wuest
+*/
+
+#define DEBUG_MODULE_NETWORK
+
+#include "synchronizeable.h"
+#include "netdefs.h"
+#include "network_manager.h"
+#include "network_stream.h"
+
+
+/**
+ *  default constructor
+ */
+Synchronizeable::Synchronizeable()
+{
+  this->setClassID(CL_SYNCHRONIZEABLE, "Synchronizeable");
+  owner = 0;
+  state = 0;
+  hostID = NetworkManager::getInstance()->getHostID();
+  this->setIsServer(this->hostID == 0);
+  uniqueID = -1;
+  this->networkStream = NULL;
+  this->setRequestedSync( false );
+  this->setIsOutOfSync( !(this->isServer()) );
+}
+
+
+
+/**
+ *  default destructor deletes all unneded stuff
+ */
+Synchronizeable::~Synchronizeable()
+{
+  if ( this->networkStream )
+    this->networkStream->disconnectSynchronizeable(*this);
+}
+
+/**
+ *  write data to NetworkStream
+ */
+int Synchronizeable::writeBytes(const byte* data, int length, int sender)
+{
+  PRINTF(5)("Synchronizeable::writeBytes was called\n");
+}
+
+/**
+ *  read data from NetworkStream
+ */
+int Synchronizeable::readBytes(byte* data, int maxLength, int * reciever)
+{
+  PRINTF(5)("Synchronizeable::readBytes was called\n");
+}
+
+
+void Synchronizeable::writeDebug() const
+{}
+
+
+void Synchronizeable::readDebug() const
+{}
+
+
+/**
+ * Sets the server flag to a given value
+ * @param isServer: the boolean value which the server flag is to set to
+ */
+void Synchronizeable::setIsServer(bool isServer)
+{
+  if( isServer )
+    this->state = this->state | STATE_SERVER;
+  else
+    this->state = this->state & (~STATE_SERVER);
+}
+
+/**
+ * Sets the outofsync flag to a given value
+ * @param outOfSync: the boolean value which the outofsync flag is to set to
+ */
+void Synchronizeable::setIsOutOfSync(bool outOfSync)
+{
+  if( outOfSync )
+    this->state = this->state | STATE_OUTOFSYNC;
+  else
+    this->state = this->state & (~STATE_OUTOFSYNC);
+  //PRINTF(0)("isoutofsync %s %d\n", this->getClassName(), state);
+}
+
+/**
+ * Determines if the server flag is set
+ * @return true, if the server flag is true, false else
+ */
+bool Synchronizeable::isServer()
+{
+  return (this->state & STATE_SERVER) >0;
+}
+
+/**
+ * Determines if the outofsync flag is set
+ * @return true, if the outofsync flag is true, false else
+ */
+bool Synchronizeable::isOutOfSync()
+{
+  return (this->state & STATE_OUTOFSYNC) >0;
+}
+
+/**
+ * Determines if the requestedSync flag is set
+ * @return true, if the requestedSync flag is true, false else
+ */
+bool Synchronizeable::requestedSync()
+{
+  return (this->state & STATE_REQUESTEDSYNC) >0;
+}
+
+/**
+ * Sets the requestedsync flag to a given value
+ * @param requestedSync: the boolean value which the requestedsync flag is to set to
+ */
+void Synchronizeable::setRequestedSync( bool requestedSync )
+{
+  if( requestedSync )
+    this->state = this->state | STATE_REQUESTEDSYNC;
+  else
+    this->state = this->state & (~STATE_REQUESTEDSYNC);
+}
+
+
+
Index: branches/network/src/lib/network/synchronizeable.h
===================================================================
--- branches/network/src/lib/network/synchronizeable.h	(revision 6636)
+++ branches/network/src/lib/network/synchronizeable.h	(revision 6636)
@@ -0,0 +1,209 @@
+/*!
+ * @file connection_monitor.h
+    \brief interface for all classes that have to be synchronized
+ */
+
+#ifndef _SYNCHRONIZEABLE_H
+#define _SYNCHRONIZEABLE_H
+
+#include "base_object.h"
+#include "netdefs.h"
+#include "converter.h"
+
+
+
+#include <vector>
+#include <list>
+
+//State constants: They have to be of the form 2^n
+#define STATE_SERVER 1
+#define STATE_OUTOFSYNC 2
+#define STATE_REQUESTEDSYNC 4
+
+
+//macros to help writing data in byte buffer
+/*
+ * Important: these macros must be used in
+ *     SYNCHELP_READ_*:  virtual void      writeBytes(const byte* data, int length, int sender);
+ *     SYNCHELP_WRITE_*: virtual int       readBytes(byte* data, int maxLength, int * reciever);
+ * with the same argument names!
+ *
+ * SYNCHELP_WRITE_BEGIN()
+ * SYNCHELP_WRITE_INT(i)
+ * SYNCHELP_WRITE_FLOAT(f)
+ * SYNCHELP_WRITE_BYTE(b)
+ * SYNCHELP_WRITE_STRING(s)
+ * SYNCHELP_WRITE_N
+ *
+ * SYNCHELP_READ_BEGIN()
+ * SYNCHELP_READ_INT(i)
+ * SYNCHELP_READ_FLOAT(f)
+ * SYNCHELP_READ_STRING(s,l) l = size of buffer s
+ * SYNCHELP_READ_STRINGM(s)  allocates memory for string! you have to free this after
+ * SYNCHELP_READ_BYTE(b)
+ * SYNCHELP_READ_N
+ *
+ *
+ *
+ * Example 1:
+ *  SYNCHELP_READ_BEGIN();
+ *  SYNCHELP_READ_FLOAT(size);
+ *  SYNCHELP_READ_STRING( textureName, 1024 ); //1024 is the length of textureName
+ *
+ * Example 2:
+ *  SYNCHELP_WRITE_BEGIN();
+ *  SYNCHELP_WRITE_FLOAT(this->size);
+ *  SYNCHELP_WRITE_STRING(this->textureName);
+ *  return SYNCHELP_WRITE_N;
+ *
+ */
+#define SYNCHELP_WRITE_BEGIN()    int __synchelp_write_i = 0; \
+                                  int __synchelp_write_n
+#define SYNCHELP_WRITE_INT(i) { __synchelp_write_n = \
+                                Converter::intToByteArray( i, data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
+                                if ( __synchelp_write_n <= 0) \
+{ \
+                                  PRINTF(1)("Buffer is too small to store a int\n"); \
+                                  return 0; \
+} \
+                                __synchelp_write_i += __synchelp_write_n; \
+}
+#define SYNCHELP_WRITE_FLOAT(f) { __synchelp_write_n = \
+                                Converter::floatToByteArray( f, data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
+                                if ( __synchelp_write_n <= 0) \
+{ \
+                                  PRINTF(1)("Buffer is too small to store a float\n"); \
+                                  return 0; \
+} \
+                                __synchelp_write_i += __synchelp_write_n; \
+}
+#define SYNCHELP_WRITE_BYTE(b) { \
+                                if (maxLength - __synchelp_write_i < 1) \
+{ \
+                                  PRINTF(1)("Buffer is too small to store string\n"); \
+                                  return 0; \
+} \
+                                data[__synchelp_write_i] = b; \
+                                __synchelp_write_i++; \
+}
+#define SYNCHELP_WRITE_STRING(s) { if (s!=NULL) \
+                                __synchelp_write_n = \
+                                Converter::stringToByteArray( s, data+__synchelp_write_i, strlen(s), maxLength-__synchelp_write_i ); \
+                                else \
+                                __synchelp_write_n = \
+                                Converter::stringToByteArray( "", data+__synchelp_write_i, strlen(""), maxLength-__synchelp_write_i ); \
+                                if ( __synchelp_write_n <= 0) \
+{ \
+                                  PRINTF(1)("Buffer is too small to store string\n"); \
+                                  return 0; \
+} \
+                                __synchelp_write_i += __synchelp_write_n; \
+}
+#define SYNCHELP_WRITE_N        __synchelp_write_i
+#define SYNCHELP_WRITE_FKT(f)   { \
+                                  __synchelp_write_i += \
+                                  f( data+__synchelp_write_i, maxLength-__synchelp_write_i ); \
+                                }
+
+
+#define SYNCHELP_READ_BEGIN()     int __synchelp_read_i = 0; \
+                                  int __synchelp_read_n
+
+#define SYNCHELP_READ_INT(i)       { \
+                                    if ( length-__synchelp_read_i < INTSIZE ) \
+{ \
+                                      PRINTF(1)("There is not enough data to read an int\n");  \
+                                      return 0; \
+} \
+                                    __synchelp_read_i += Converter::byteArrayToInt( data+__synchelp_read_i, &i );  \
+}
+#define SYNCHELP_READ_FLOAT(f)    { \
+                                    if ( length-__synchelp_read_i < FLOATSIZE ) \
+{ \
+                                      PRINTF(1)("There is not enough data to read a flaot\n");  \
+                                      return 0; \
+} \
+                                    __synchelp_read_i += Converter::byteArrayToFloat( data+__synchelp_read_i, &f );  \
+}
+#define SYNCHELP_READ_STRING(s,l)    { \
+                                    __synchelp_read_n = Converter::byteArrayToString( data+__synchelp_read_i, s, l );  \
+                                    if ( __synchelp_read_n <0 )  \
+{ \
+                                      PRINTF(1)("There is not enough data to read string\n");  \
+                                      return 0; \
+} \
+                                    __synchelp_read_i += __synchelp_read_n; \
+}
+#define SYNCHELP_READ_STRINGM(s)    { \
+                                    __synchelp_read_n = Converter::byteArrayToStringM( data+__synchelp_read_i, s );  \
+                                    if ( __synchelp_read_n <0 )  \
+{ \
+                                      PRINTF(1)("There is not enough data to read string\n");  \
+                                      return 0; \
+} \
+                                    __synchelp_read_i += __synchelp_read_n; \
+}
+#define SYNCHELP_READ_BYTE(b)      { \
+                                    if ( length-__synchelp_read_i < 1 ) \
+{ \
+                                      PRINTF(1)("There is not enough data to read a byte\n");  \
+                                      return 0; \
+} \
+                                    b = data[__synchelp_read_i]; \
+                                    __synchelp_read_i ++;  \
+}
+#define SYNCHELP_READ_FKT(f)   { \
+                                  __synchelp_read_i += \
+                                  f( data+__synchelp_read_i, length-__synchelp_read_i, sender); \
+                                  }
+#define SYNCHELP_READ_N           __synchelp_read_i
+
+class NetworkStream;
+
+
+class Synchronizeable : virtual public BaseObject
+  {
+  public:
+    Synchronizeable();
+    ~Synchronizeable();
+
+    virtual int       writeBytes(const byte* data, int length, int sender);
+    virtual int       readBytes(byte* data, int maxLength, int * reciever);
+    virtual void      writeDebug() const;
+    virtual void      readDebug() const;
+
+    void setIsServer( bool isServer );
+    void setIsOutOfSync( bool outOfSync );
+    void setRequestedSync( bool requestedSync );
+    bool isServer();
+    bool isOutOfSync();
+    bool requestedSync();
+    inline void setUniqueID( int id ){ uniqueID = id; }
+    inline int  getUniqueID() const { return uniqueID; };
+    inline void requestSync( int hostID ){ this->synchronizeRequests.push_back( hostID ); }
+    inline int getRequestSync( void ){ if ( this->synchronizeRequests.size()>0 ){ int n = *(synchronizeRequests.begin()); synchronizeRequests.pop_front(); return n; } else { return -1; } };
+    inline int getHostID() { return this->hostID; }
+
+    inline int getOwner(){ return owner; }
+    inline void setOwner(int owner){ this->owner = owner; }
+
+    inline void setNetworkStream(NetworkStream* stream) { this->networkStream = stream; }
+
+  private:
+
+    int               uniqueID;
+
+
+
+    //static std::vector<Synchronizeable*> classList;
+    int owner;
+    int hostID;
+
+    std::list<int> synchronizeRequests;
+
+  protected:
+    NetworkStream* networkStream;
+    int state;
+
+  };
+#endif /* _SYNCHRONIZEABLE_H */
Index: branches/network/src/lib/parser/Makefile.am
===================================================================
--- branches/network/src/lib/parser/Makefile.am	(revision 6636)
+++ branches/network/src/lib/parser/Makefile.am	(revision 6636)
@@ -0,0 +1,5 @@
+SUBDIRS = \
+          tinyxml \
+	  ini_parser
+
+
Index: branches/network/src/lib/parser/ini_parser/Makefile.am
===================================================================
--- branches/network/src/lib/parser/ini_parser/Makefile.am	(revision 6636)
+++ branches/network/src/lib/parser/ini_parser/Makefile.am	(revision 6636)
@@ -0,0 +1,10 @@
+
+noinst_LIBRARIES = libIniParser.a
+
+libIniParser_a_SOURCES = ini_parser.cc
+
+libIniParser_a_CPPFLAGS = "-DNO_SHELL"
+
+noinst_HEADERS = ini_parser.h
+
+
Index: branches/network/src/lib/parser/ini_parser/ini_parser.cc
===================================================================
--- branches/network/src/lib/parser/ini_parser/ini_parser.cc	(revision 6636)
+++ branches/network/src/lib/parser/ini_parser/ini_parser.cc	(revision 6636)
@@ -0,0 +1,771 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: Christian Meyer
+
+   2005-08-14: complete reimplementation:
+               now the File is parsed at the initialisation,
+               and informations is gathered there.
+*/
+
+
+#include "ini_parser.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef DEBUG
+ #include "../../../defs/debug.h"
+#else
+ #define PRINTF(x) printf
+#endif
+
+using namespace std;
+
+/**
+ * @brief constructs an IniParser using a file
+ * @param fileName: the path and name of the file to parse
+ */
+IniParser::IniParser (const char* fileName)
+{
+  this->fileName = NULL;
+  this->comment = NULL;
+
+  if (fileName != NULL)
+    this->readFile(fileName);
+}
+
+
+/**
+ * @brief removes the IniParser from memory
+ */
+IniParser::~IniParser ()
+{
+  this->deleteSections();
+  this->setFileName(NULL);
+}
+
+
+/**
+ * @brief removes all the sections. This is like delete, but even cooler :)
+ */
+void IniParser::deleteSections()
+{
+  // in all sections
+  while(!this->sections.empty())
+  {
+     IniSection section = this->sections.front();
+
+    // in all entries of the sections
+    while(!section.entries.empty())
+    {
+      // delete all strings of entries.
+      IniEntry entry = section.entries.front();
+      delete[] entry.name;
+      delete[] entry.value;
+      delete[] entry.comment;
+      section.entries.pop_front();
+    }
+    // delete all Sections
+    delete[] section.name;
+    delete[] section.comment;
+    this->sections.pop_front();
+  }
+  this->currentSection = this->sections.end();
+  this->setFileName(NULL);
+}
+
+
+/**
+ * @brief sets the Name of the input-file
+ * @param fileName The new FileName to set to the IniParser
+ * If fileName is NULL the new Name will be set to NULL too.
+ */
+void IniParser::setFileName(const char* fileName)
+{
+  if (this->fileName != NULL)
+    delete[] this->fileName;
+  if  (this->comment != NULL)
+    delete[] this->comment;
+  this->comment = NULL;
+
+  if (fileName != NULL)
+  {
+    this->fileName = new char[strlen(fileName)+1];
+    strcpy(this->fileName, fileName);
+  }
+  else
+    this->fileName = NULL;
+}
+
+
+/**
+ * @brief opens a file to parse
+ * @param fileName: path and name of the new file to parse
+ * @return true on success false otherwise;
+ *
+ * If there was already an opened file, the file will be closed,
+ * and the new one will be opened.
+ */
+bool IniParser::readFile(const char* fileName)
+{
+  FILE*    stream;           //< The stream we use to read the file.
+  int      lineCount = 0;    //< The Count of lines.
+
+  if (this->fileName != NULL)
+    this->deleteSections();
+  if( fileName == NULL)
+    return false;
+
+  if( (stream = fopen (fileName, "r")) == NULL)
+  {
+    PRINTF(1)("IniParser could not open %s\n", fileName);
+    return false;
+  }
+  else
+  {
+    this->setFileName(fileName);
+
+    /////////////////////////////
+    // READING IN THE INI-FILE //
+    /////////////////////////////
+    char lineBuffer[PARSELINELENGHT];
+    char buffer[PARSELINELENGHT];
+    const char* lineBegin;
+    char* ptr;
+
+    while( fgets (lineBuffer, PARSELINELENGHT, stream))
+    {
+      lineBegin = lineBuffer;
+      // remove newline char, and \0-terminate
+      if( (ptr = strchr( lineBuffer, '\n')) != NULL)
+        *ptr = 0;
+      // cut up to the beginning of the line.
+      while((*lineBegin == ' ' || *lineBegin == '\t') && lineBegin < lineBuffer + strlen(lineBuffer))
+        ++lineBegin;
+
+      // check if we have a FileComment
+      if ( (*lineBegin == '#' || *lineBegin == ';'))
+      {
+        char* newCommenLine = new char[strlen(lineBegin)+1];
+        strcpy(newCommenLine, lineBegin);
+        this->commentList.push_back(newCommenLine);
+        continue;
+      }
+      if (lineCount == 0 && !this->commentList.empty())
+      {
+        this->setFileComment();
+        lineCount++;
+      }
+
+      // check for section identifyer
+      else if( sscanf (lineBegin, "[%s", buffer) == 1)
+      {
+        if( (ptr = strchr( buffer, ']')) != NULL)
+        {
+          *ptr = 0;
+          this->addSection(buffer);
+          this->setSectionComment();
+        }
+      }
+      // check for Entry identifier (Entry = Value)
+      else if( (ptr = strchr( lineBegin, '=')) != NULL)
+      {
+        if (currentSection == NULL)
+        {
+          PRINTF(2)("Not in a Section yet for %s\n", lineBegin);
+          lineCount++;
+          continue;
+        }
+        if( ptr == lineBegin) {
+          lineCount++;
+          continue;
+        }
+        char* valueBegin = ptr+1;
+        while ((*valueBegin == ' ' || *valueBegin == '\t') && valueBegin <= lineBegin + strlen(lineBegin))
+          ++valueBegin;
+        char* valueEnd = valueBegin + strlen(valueBegin)-1;
+        while ((*valueEnd == ' ' || *valueEnd == '\t') && valueEnd >= valueBegin)
+          --valueEnd;
+        valueEnd[1] = '\0';
+        char* nameEnd = ptr-1;
+        while ((*nameEnd == ' ' || *nameEnd == '\t' ) && nameEnd >= lineBegin)
+          --nameEnd;
+        nameEnd[1] = '\0';
+
+        this->addVar(lineBegin, valueBegin);
+        this->setEntryComment();
+
+        lineCount++;
+      }
+    }
+  }
+  this->currentSection = this->sections.begin();
+  if (!this->sections.empty())
+    this->currentEntry = (*this->currentSection).entries.begin();
+
+  fclose(stream);
+  return true;
+}
+
+
+/**
+ * @brief opens a file and writes to it
+ * @param fileName: path and name of the new file to write to
+ * @return true on success false otherwise
+ */
+bool IniParser::writeFile(const char* fileName) const
+{
+  FILE*    stream;           //!< The stream we use to read the file.
+  if( fileName == NULL && (fileName = this->fileName) == NULL )
+    return false;
+
+  if( (stream = fopen (fileName, "w")) == NULL)
+  {
+    PRINTF(1)("IniParser could not open %s\n", fileName);
+    return false;
+  }
+  else
+  {
+    if (this->comment != NULL)
+      fprintf(stream, "%s\n\n", this->comment);
+
+    std::list<IniSection>::const_iterator section;
+    for (section = this->sections.begin(); section != this->sections.end(); section++)
+      {
+        if ((*section).comment != NULL)
+          fprintf(stream, "%s", (*section).comment);
+        fprintf(stream, "\n [%s]\n", (*section).name);
+
+        std::list<IniEntry>::const_iterator entry;
+        for (entry = (*section).entries.begin(); entry != (*section).entries.end(); entry++)
+        {
+          if ((*entry).comment != NULL)
+            fprintf(stream, "%s", (*entry).comment);
+          fprintf(stream, "   %s = %s\n", (*entry).name, (*entry).value);
+         }
+      }
+  }
+  fclose(stream);
+}
+
+void IniParser::setFileComment(const char* fileComment)
+{
+  if (this->comment != NULL)
+    delete this->comment;
+
+  if (fileComment != NULL)
+  {
+    this->comment = new char[strlen(fileComment)+1];
+    strcpy(this->comment, fileComment);
+  }
+  else
+    this->comment = NULL;
+}
+
+
+/**
+ * @brief adds a section to the list of Sections,
+ * if no Section list is availiable, it will create it
+ * @param sectionName the Name of the section to add
+ * @return true on success... there is only success or segfault :)
+ */
+bool IniParser::addSection(const char* sectionName)
+{
+  if (sectionName == NULL)
+    return false;
+  this->sections.push_back(IniSection());
+  this->sections.back().comment = NULL;
+  this->sections.back().name = new char[strlen(sectionName)+1];
+  strcpy(this->sections.back().name, sectionName);
+
+  this->currentSection = --this->sections.end();
+  if (!this->sections.empty())
+      this->currentEntry = (*this->currentSection).entries.begin();
+  PRINTF(5)("Added Section %s\n", sectionName);
+  return true;
+}
+
+
+/**
+ * @brief Set the parsing cursor to the specified section
+ * @param sectionName: the name of the section to set the cursor to
+ * @return true on success or false if the section could not be found
+ */
+bool IniParser::getSection(const char* sectionName)
+{
+  this->currentSection = this->getSectionIT(sectionName);
+  if (this->currentSection != this->sections.end())
+  {
+    this->currentEntry = (*this->currentSection).entries.begin();
+    return true;
+  }
+  else
+    return false;
+}
+
+/**
+ *
+ */
+void IniParser::setSectionComment(const char* comment, const char* sectionName)
+{
+  std::list<IniSection>::iterator section = this->getSectionIT(sectionName);
+  if (section == this->sections.end())
+    return;
+
+  if ((*section).comment != NULL)
+    delete[] (*section).comment;
+  if (comment != NULL)
+  {
+    (*section).comment = new char[strlen (comment)+1];
+    strcpy((*section).comment, comment);
+  }
+  else
+    (*section).comment = NULL;
+}
+
+/**
+ * @param sectionName the Section to query for
+ * @returns the Comment, or NULL on error.
+ */
+const char* IniParser::getSectionComment(const char* sectionName) const
+{
+  std::list<IniSection>::const_iterator section = this->getSectionIT(sectionName);
+  if (section != this->sections.end())
+    return (*section).comment;
+  else
+    return NULL;
+}
+
+
+/**
+ * @brief moves to the first section
+ */
+void IniParser::firstSection()
+{
+  this->currentSection = this->sections.begin();
+  if (!this->sections.empty())
+    this->currentEntry = (*this->currentSection).entries.begin();
+}
+
+
+/**
+ * @brief searches the next section
+ * @returns the name of the section if found, NULL otherwise
+ */
+const char* IniParser::nextSection()
+{
+  if (this->currentSection == this->sections.end())
+    return NULL;
+
+  this->currentSection++;
+
+  if (this->currentSection != this->sections.end())
+    {
+      this->currentEntry = (*this->currentSection).entries.begin();
+      return this->currentSection->name;
+    }
+  else
+    return NULL;
+}
+
+
+/**
+ * @brief adds a new Entry to either the currentSection or the section called by sectionName
+ * @param entryName the Name of the Entry to add
+ * @param value the value to assign to this entry
+ * @param sectionName if NULL then this entry will be set to the currentSection
+ * otherwise to the section refered to by sectionName.
+ * If both are NULL no entry will be added
+ * @return true if everything is ok false on error
+ */
+bool IniParser::addVar(const char* entryName, const char* value, const char* sectionName)
+{
+  std::list<IniSection>::iterator section;
+
+  if (sectionName != NULL)
+  {
+    for (section = this->sections.begin(); section != this->sections.end(); section++)
+      if (!strcmp((*section).name, sectionName))
+        break;
+  }
+  else
+    section = this->currentSection;
+
+  if (section == this->sections.end())
+    return false;
+
+  if (section == this->sections.end())
+  {
+    PRINTF(2)("section '%s' not found for value '%s'\n", sectionName, entryName);
+    return false;
+  }
+  else
+  {
+    (*section).entries.push_back(IniEntry());
+    (*section).entries.back().comment = NULL;
+    (*section).entries.back().name = new char[strlen(entryName)+1];
+    strcpy((*section).entries.back().name, entryName);
+    (*section).entries.back().value = new char[strlen(value)+1];
+    strcpy((*section).entries.back().value, value);
+    PRINTF(5)("Added Entry %s with Value '%s' to Section %s\n",
+              (*section).entries.back().name,
+              (*section).entries.back().value,
+              (*section).name);
+    this->currentEntry = --(*section).entries.end();
+    return true;
+  }
+}
+
+
+/**
+ * @brief directly acesses an entry in a section
+ * @param entryName: the name of the entry to find
+ * @param sectionName: the section where the entry is to be found
+ * @param defaultValue: what should be returned in case the entry cannot be found
+ * @return a pointer to a buffer conatining the value of the specified entry. This buffer will contain the data specified in defvalue in case the entry wasn't found
+ *
+ *  The returned pointer points to an internal buffer, so do not free it on your own. Do not give a NULL pointer to defvalue, this will certainly
+ * lead to unwanted behaviour.
+*/
+const char* IniParser::getVar(const char* entryName, const char* sectionName, const char* defaultValue) const
+{
+  if (this->fileName != NULL)
+  {
+    std::list<IniEntry>::const_iterator entry = this->getEntryIT(entryName, sectionName);
+    if (entry != NULL &&  !strcmp((*entry).name, entryName))
+      return (*entry).value;
+    PRINTF(2)("Entry '%s' in section '%s' not found.\n", entryName, sectionName);
+
+  }
+  else
+    PRINTF(2)("no File opened\n");
+
+  return defaultValue;
+
+}
+
+/**
+ * Set the Comment of a specified Entry.
+ * @param comment the Comment to set
+ * @param entryName the Name of the Entry
+ * @param sectionName the Name of the Section
+ */
+void IniParser::setEntryComment(const char* comment, const char* entryName, const char* sectionName)
+{
+  std::list<IniEntry>::iterator entry = this->getEntryIT(entryName, sectionName);
+
+  if ((*entry).comment != NULL)
+    delete[] (*entry).comment;
+  if (comment != NULL)
+  {
+    (*entry).comment = new char[strlen (comment)+1];
+    strcpy((*entry).comment, comment);
+  }
+  else
+    (*entry).comment = NULL;
+
+
+}
+
+/**
+ * @param entryName the Entry to query for
+ * @param sectionName the Section to Query for
+ * @returns the queried Comment.
+ */
+const char* IniParser::getEntryComment(const char* entryName, const char* sectionName) const
+{
+  std::list<IniEntry>::const_iterator entry = this->getEntryIT(entryName, sectionName);
+
+  return (*entry).comment;
+}
+
+
+/**
+ * @brief moves to the first Variable of the current Section
+ */
+void IniParser::firstVar()
+{
+  if (!this->sections.empty() &&
+       this->currentSection != this->sections.end())
+    this->currentEntry = (*this->currentSection).entries.begin();
+}
+
+
+/**
+ * @brief gets the next VarName = VarValue pair from the parsing stream
+ * @return true on success, false otherwise (in the latter case name and value will be NULL)
+ */
+bool IniParser::nextVar()
+{
+  if ( this->sections.empty()
+       || this->currentSection == this->sections.end()
+       || this->currentEntry == (*this->currentSection).entries.end())
+    return false;
+
+  this->currentEntry++;
+
+  if (this->currentEntry == (*this->currentSection).entries.end())
+    return false;
+  else
+    return true;
+}
+
+
+
+/**
+ * @returns the name of the Current selected Section
+ */
+const char* IniParser::getCurrentSection() const
+{
+  if (!this->sections.empty() &&
+      this->currentSection != this->sections.end())
+    return this->currentSection->name;
+  else
+    return NULL;
+ }
+
+
+/**
+ * @returns the current entries Name, or NULL if we havn't selected a Entry
+ */
+const char* IniParser::getCurrentName() const
+{
+ if (!this->sections.empty() &&
+     this->currentSection != this->sections.end() &&
+     this->currentEntry != (*this->currentSection).entries.end())
+   return (*this->currentEntry).name;
+ else
+   return NULL;
+}
+
+/**
+ * @returns the current entries Value, or NULL if we havn't selected a Entry
+ */
+const char* IniParser::getCurrentValue() const
+{
+  if (!this->sections.empty() &&
+      this->currentSection != this->sections.end() &&
+      this->currentEntry != (*this->currentSection).entries.end())
+    return (*this->currentEntry).value;
+  else
+    return NULL;
+}
+
+
+/**
+ * Finds the Section Iterator of the Section Called sectionName
+ * @param sectionName the Name of the Section to get the Iterator from
+ */
+std::list<IniParser::IniSection>::const_iterator IniParser::getSectionIT(const char* sectionName) const
+{
+  std::list<IniSection>::const_iterator section = this->currentSection;
+  if (sectionName == NULL)
+    return this->currentSection;
+  else
+    for (section = this->sections.begin(); section != this->sections.end(); section++)
+      if (!strcmp((*section).name, sectionName))
+        break;
+  return section;
+}
+
+
+/**
+ * Finds the Section Iterator of the Section Called sectionName
+ * @param sectionName the Name of the Section to get the Iterator from
+ */
+std::list<IniParser::IniSection>::iterator IniParser::getSectionIT(const char* sectionName)
+{
+  std::list<IniSection>::iterator section = this->currentSection;
+  if (sectionName == NULL)
+    return this->currentSection;
+  else
+    for (section = this->sections.begin(); section != this->sections.end(); section++)
+      if (!strcmp((*section).name, sectionName))
+        break;
+  return section;
+}
+
+
+/**
+ * Finds the Entry Iterator of the Section Called sectionName and entry called EntryName
+ * @param entryName the Name of the Entry to get the Iterator from
+ * @param sectionName the Name of the Section to get the Iterator from
+ */
+std::list<IniParser::IniEntry>::const_iterator IniParser::getEntryIT(const char* entryName, const char* sectionName) const
+{
+  if (entryName == NULL)
+    return this->currentEntry;
+  std::list<IniSection>::const_iterator section = this->getSectionIT(sectionName);
+  std::list<IniEntry>::const_iterator entry = this->currentEntry;
+
+  if (section != this->sections.end())
+    for (entry = (*section).entries.begin(); entry != (*section).entries.end(); entry++)
+      if (!strcmp((*entry).name, entryName))
+        break;
+  if (entry == (*section).entries.end())
+    return NULL;
+  else
+    return entry;
+}
+
+
+/**
+ * Finds the Entry Iterator of the Section Called sectionName and entry called EntryName
+ * @param entryName the Name of the Entry to get the Iterator from
+ * @param sectionName the Name of the Section to get the Iterator from
+ */
+std::list<IniParser::IniEntry>::iterator IniParser::getEntryIT(const char* entryName, const char* sectionName)
+{
+  if (entryName == NULL)
+    return this->currentEntry;
+  std::list<IniSection>::iterator section = this->getSectionIT(sectionName);
+  std::list<IniEntry>::iterator entry = this->currentEntry;
+
+  if (section != this->sections.end())
+    for (entry = (*section).entries.begin(); entry != (*section).entries.end(); entry++)
+      if (!strcmp((*entry).name, entryName))
+        break;
+  if (entry == (*section).entries.end())
+    return NULL;
+  else
+    return entry;
+}
+
+
+/**
+ * takes lines together to form one FileComment, ereasing the commentList
+ */
+void IniParser::setFileComment()
+{
+  if (this->comment != NULL)
+    delete[] this->comment;
+
+  if (this->commentList.empty()) {
+    this->comment = NULL;
+    return;
+  }
+
+  unsigned int stringLength = 1;
+  std::list<char*>::iterator comment;
+  for (comment = this->commentList.begin(); comment != this->commentList.end(); comment++)
+    stringLength += strlen((*comment)) +1;
+
+  this->comment = new char[stringLength];
+  this->comment[0] = '\0';
+  while (!this->commentList.empty())
+  {
+    if (*this->comment != '\0')
+      strcat(this->comment, "\n");
+    strcat(this->comment, this->commentList.front());
+    delete[] this->commentList.front();
+    this->commentList.pop_front();
+  }
+}
+
+/**
+ * takes lines together to form one SectionComment, ereasing the commentList
+ */
+void IniParser::setSectionComment()
+{
+  if ((*this->currentSection).comment != NULL)
+    delete[] (*this->currentSection).comment;
+
+  if (this->commentList.empty()) {
+    (*this->currentSection).comment = NULL;
+    return;
+  }
+
+  unsigned int stringLength = 1;
+  std::list<char*>::iterator comment;
+  for (comment = this->commentList.begin(); comment != this->commentList.end(); comment++)
+    stringLength += strlen((*comment)) +1;
+
+  (*this->currentSection).comment = new char[stringLength];
+  (*this->currentSection).comment[0] = '\0';
+  while (!this->commentList.empty())
+  {
+    if (*(*this->currentSection).comment != '\0')
+      strcat((*this->currentSection).comment, "\n");
+    strcat((*this->currentSection).comment, this->commentList.front());
+    delete[] this->commentList.front();
+    this->commentList.pop_front();
+  }
+}
+
+/**
+ * takes lines together to form one EntryComment, ereasing the commentList
+ */
+void IniParser::setEntryComment()
+{
+  if ((*this->currentEntry).comment != NULL)
+    delete[] (*this->currentEntry).comment;
+
+  if (this->commentList.empty()) {
+    (*this->currentEntry).comment = NULL;
+    return;
+  }
+
+  unsigned int stringLength = 1;
+  std::list<char*>::iterator comment;
+  for (comment = this->commentList.begin(); comment != this->commentList.end(); comment++)
+    stringLength += strlen((*comment)) +1;
+
+  (*this->currentEntry).comment = new char[stringLength];
+  (*this->currentEntry).comment[0] = '\0';
+  while (!this->commentList.empty())
+  {
+    if (*(*this->currentEntry).comment != '\0')
+      strcat((*this->currentEntry).comment, "\n");
+    strcat((*this->currentEntry).comment, this->commentList.front());
+    delete[] this->commentList.front();
+    this->commentList.pop_front();
+  }
+
+}
+
+
+/**
+ * @brief output the whole tree in a nice and easy way.
+ */
+void IniParser::debug() const
+{
+  PRINTF(0)("Iniparser %s - debug\n", this->fileName);
+  if (this->comment != NULL)
+    PRINTF(0)("FileComment:\n %s\n\n", this->comment);
+
+  if (this->fileName != NULL)
+  {
+    std::list<IniSection>::const_iterator section;
+    for (section = this->sections.begin(); section != this->sections.end(); section++)
+    {
+      if ((*section).comment != NULL)
+        PRINTF(0)(" %s\n", (*section).comment);
+      PRINTF(0)(" [%s]\n", (*section).name);
+
+      std::list<IniEntry>::const_iterator entry;
+      for (entry = (*section).entries.begin(); entry != (*section).entries.end(); entry++)
+      {
+        if ((*entry).comment != NULL)
+          PRINTF(0)(" %s\n", (*entry).comment);
+        PRINTF(0)("   '%s' -> '%s'\n", (*entry).name, (*entry).value);
+      }
+    }
+  }
+  else
+    PRINTF(1)("no opened ini-file.\n");
+}
+
Index: branches/network/src/lib/parser/ini_parser/ini_parser.h
===================================================================
--- branches/network/src/lib/parser/ini_parser/ini_parser.h	(revision 6636)
+++ branches/network/src/lib/parser/ini_parser/ini_parser.h	(revision 6636)
@@ -0,0 +1,112 @@
+/*!
+ * @file ini_parser.h
+ * A small ini file parser
+ *
+ * Can be used to find a defined [Section] in an ini file and get the VarName = Value entries
+ */
+
+#ifndef _INI_PARSER_H
+#define _INI_PARSER_H
+
+#define PARSELINELENGHT     512       //!< how many chars to read at once
+#ifndef NULL
+ #define NULL 0x0                     //!< NULL
+#endif
+
+#include <list>
+
+//! ini-file parser
+/**
+ * This class can be used to load an initializer file and parse it's contents for variablename=value pairs.
+ */
+class IniParser
+{
+  private:
+    ////////////////////////////////////
+    //! a struct for Entries in the Parser's File's Sections
+    struct IniEntry
+    {
+      char*               comment;  //!< A Comment that is appendet to the Top of this Entry.
+      char*               name;     //!< name of a given Entry
+      char*               value;    //!< value of a given Entry
+    };
+
+    //! a struct for Sections in the Parser's file
+    struct IniSection
+    {
+      char*               comment;  //!< A Comment that is appendet to the Top of this Section.
+      char*               name;     //!< name of a given section
+      std::list<IniEntry> entries;  //!< a list of entries for this section
+    };
+    ////////////////////////////////////
+
+  public:
+    IniParser (const char* filename = NULL);
+    ~IniParser ();
+
+    /** @returns true if the file is opened, false otherwise*/
+    bool isOpen() const { return (this->fileName != NULL)? true : false; };
+    /** @returns the fileName we have opened. */
+    const char* getFileName() const { return this->fileName; };
+
+    bool readFile(const char* fileName);
+    bool writeFile(const char* fileName) const;
+
+    void setFileComment(const char* fileComment);
+    const char* getFileComment() const { return this->comment; };
+
+    bool addSection(const char* sectionName);
+    bool getSection(const char* sectionName);
+    void setSectionComment(const char* comment, const char* sectionName);
+    const char* getSectionComment(const char* sectionNane) const;
+
+    // iterate through sections with these Functions
+    void firstSection();
+    const char* nextSection();
+
+
+    bool addVar(const char* entryName, const char* value, const char* sectionName = NULL);
+    const char* getVar(const char* entryName, const char* sectionName, const char* defaultValue = "") const;
+    void setEntryComment(const char* comment, const char* entryName, const char* sectionName);
+    const char* getEntryComment(const char* entryName, const char* sectionName) const;
+
+    // iterate Through Variables with these Functions.
+    void firstVar();
+    bool nextVar();
+
+
+    // retrieving functions when iterating.
+    const char* getCurrentSection() const;
+    const char* getCurrentName() const;
+    const char* getCurrentValue() const;
+
+
+    // maintenance.
+    void debug() const;
+
+
+  private:
+    void deleteSections();
+    void setFileName(const char* fileName);
+
+    void setFileComment();
+    void setSectionComment();
+    void setEntryComment();
+
+    std::list<IniSection>::const_iterator getSectionIT(const char* sectionName) const;
+    std::list<IniSection>::iterator getSectionIT(const char* sectionName);
+
+    std::list<IniEntry>::const_iterator getEntryIT(const char* entryName, const char* sectionName = NULL) const;
+    std::list<IniEntry>::iterator getEntryIT(const char* entryName, const char* sectionName = NULL);
+
+  private:
+    char*                            fileName;        //!< The name of the File that was parsed.
+    char*                            comment;         //!< A Comment for the header of this File.
+    std::list<IniSection>            sections;        //!< a list of all stored Sections of the Parser
+    std::list<IniSection>::iterator  currentSection;  //!< the current selected Section
+    std::list<IniEntry>::iterator    currentEntry;    //!< the current selected entry (in currentSection)
+
+    std::list<char*>                 commentList;     //!< A list of Comments. (this is for temporary saving of Comments, that are inserted in front of Sections/Entries.)
+};
+
+#endif /* _INI_PARSER_H */
Index: branches/network/src/lib/parser/tinyxml/Makefile.am
===================================================================
--- branches/network/src/lib/parser/tinyxml/Makefile.am	(revision 6636)
+++ branches/network/src/lib/parser/tinyxml/Makefile.am	(revision 6636)
@@ -0,0 +1,10 @@
+
+noinst_LIBRARIES = libtinyxml.a 
+
+libtinyxml_a_SOURCES = tinyxml.cc \
+		       tinystr.cc \
+		       tinyxmlerror.cc \
+		       tinyxmlparser.cc
+
+noinst_HEADERS= tinyxml.h \
+		tinystr.h
Index: branches/network/src/lib/parser/tinyxml/tinystr.cc
===================================================================
--- branches/network/src/lib/parser/tinyxml/tinystr.cc	(revision 6636)
+++ branches/network/src/lib/parser/tinyxml/tinystr.cc	(revision 6636)
@@ -0,0 +1,115 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original file by Yves Berquin.
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+/*
+ * THIS FILE WAS ALTERED BY Tyge Løvset, 7. April 2005.
+ */
+
+
+#ifndef TIXML_USE_STL
+
+#include "tinystr.h"
+
+// Error value for find primitive
+const TiXmlString::size_type TiXmlString::npos = static_cast< size_type >(-1);
+
+// Null rep.
+TiXmlString::Rep TiXmlString::nullrep_ = { 0, 0, '\0' };
+
+
+void TiXmlString::reserve (size_type cap)
+{
+	if (cap > capacity())
+	{
+		TiXmlString tmp;
+		tmp.init(length(), cap);
+		memcpy(tmp.start(), data(), length());
+		swap(tmp);
+	}
+}
+
+
+TiXmlString& TiXmlString::assign(const char* str, size_type len)
+{
+	size_type cap = capacity();
+	if (len > cap || cap > 3*(len + 8))
+	{
+		TiXmlString tmp;
+		tmp.init(len);
+		memcpy(tmp.start(), str, len);
+		swap(tmp);
+	}
+	else
+	{
+		memmove(start(), str, len);
+		set_size(len);
+	}
+	return *this;
+}
+
+
+TiXmlString& TiXmlString::append(const char* str, size_type len)
+{
+	size_type newsize = length() + len;
+	if (newsize > capacity())
+	{
+		reserve (newsize + capacity());
+	}
+	memmove(finish(), str, len);
+	set_size(newsize);
+	return *this;
+}
+
+
+TiXmlString operator + (const TiXmlString & a, const TiXmlString & b)
+{
+	TiXmlString tmp;
+	tmp.reserve(a.length() + b.length());
+	tmp += a;
+	tmp += b;
+	return tmp;
+}
+
+TiXmlString operator + (const TiXmlString & a, const char* b)
+{
+	TiXmlString tmp;
+	TiXmlString::size_type b_len = static_cast<TiXmlString::size_type>( strlen(b) );
+	tmp.reserve(a.length() + b_len);
+	tmp += a;
+	tmp.append(b, b_len);
+	return tmp;
+}
+
+TiXmlString operator + (const char* a, const TiXmlString & b)
+{
+	TiXmlString tmp;
+	TiXmlString::size_type a_len = static_cast<TiXmlString::size_type>( strlen(a) );
+	tmp.reserve(a_len + b.length());
+	tmp.append(a, a_len);
+	tmp += b;
+	return tmp;
+}
+
+
+#endif	// TIXML_USE_STL
Index: branches/network/src/lib/parser/tinyxml/tinystr.h
===================================================================
--- branches/network/src/lib/parser/tinyxml/tinystr.h	(revision 6636)
+++ branches/network/src/lib/parser/tinyxml/tinystr.h	(revision 6636)
@@ -0,0 +1,304 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original file by Yves Berquin.
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+/*
+ * THIS FILE WAS ALTERED BY Tyge Lovset, 7. April 2005.
+ *
+ * - completely rewritten. compact, clean, and fast implementation.
+ * - sizeof(TiXmlString) = pointer size (4 bytes on 32-bit systems)
+ * - fixed reserve() to work as per specification.
+ * - fixed buggy compares operator==(), operator<(), and operator>()
+ * - fixed operator+=() to take a const ref argument, following spec.
+ * - added "copy" constructor with length, and most compare operators.
+ * - added swap(), clear(), size(), capacity(), operator+().
+ */
+
+#ifndef TIXML_USE_STL
+
+#ifndef TIXML_STRING_INCLUDED
+#define TIXML_STRING_INCLUDED
+
+#include <assert.h>
+#include <string.h>
+
+/*
+   TiXmlString is an emulation of a subset of the std::string template.
+   Its purpose is to allow compiling TinyXML on compilers with no or poor STL support.
+   Only the member functions relevant to the TinyXML project have been implemented.
+   The buffer allocation is made by a simplistic power of 2 like mechanism : if we increase
+   a string and there's no more room, we allocate a buffer twice as big as we need.
+*/
+class TiXmlString
+{
+  public :
+	// The size type used
+  	typedef unsigned int size_type;
+
+	// Error value for find primitive
+	static const size_type npos; // = -1;
+
+
+	// TiXmlString empty constructor
+	TiXmlString () : rep_(&nullrep_)
+	{
+	}
+
+	// TiXmlString copy constructor
+	TiXmlString (const TiXmlString & copy)
+	{
+		init(copy.length());
+		memcpy(start(), copy.data(), length());
+	}
+
+	// TiXmlString constructor, based on a string
+	TiXmlString (const char * copy)
+	{
+		init( static_cast<size_type>( strlen(copy) ));
+		memcpy(start(), copy, length());
+	}
+
+	// TiXmlString constructor, based on a string
+	TiXmlString (const char * str, size_type len)
+	{
+		init(len);
+		memcpy(start(), str, len);
+	}
+
+	// TiXmlString destructor
+	~TiXmlString ()
+	{
+		quit();
+	}
+
+	// = operator
+	TiXmlString& operator = (const char * copy)
+	{
+		return assign( copy, (size_type)strlen(copy));
+	}
+
+	// = operator
+	TiXmlString& operator = (const TiXmlString & copy)
+	{
+		return assign(copy.start(), copy.length());
+	}
+
+
+	// += operator. Maps to append
+	TiXmlString& operator += (const char * suffix)
+	{
+		return append(suffix, static_cast<size_type>( strlen(suffix) ));
+	}
+
+	// += operator. Maps to append
+	TiXmlString& operator += (char single)
+	{
+		return append(&single, 1);
+	}
+
+	// += operator. Maps to append
+	TiXmlString& operator += (const TiXmlString & suffix)
+	{
+		return append(suffix.data(), suffix.length());
+	}
+
+
+	// Convert a TiXmlString into a null-terminated char *
+	const char * c_str () const { return rep_->str; }
+
+	// Convert a TiXmlString into a char * (need not be null terminated).
+	const char * data () const { return rep_->str; }
+
+	// Return the length of a TiXmlString
+	size_type length () const { return rep_->size; }
+
+	// Alias for length()
+	size_type size () const { return rep_->size; }
+
+	// Checks if a TiXmlString is empty
+	bool empty () const { return rep_->size == 0; }
+
+	// Return capacity of string
+	size_type capacity () const { return rep_->capacity; }
+
+
+	// single char extraction
+	const char& at (size_type index) const
+	{
+		assert( index < length() );
+		return rep_->str[ index ];
+	}
+
+	// [] operator
+	char& operator [] (size_type index) const
+	{
+		assert( index < length() );
+		return rep_->str[ index ];
+	}
+
+	// find a char in a string. Return TiXmlString::npos if not found
+	size_type find (char lookup) const
+	{
+		return find(lookup, 0);
+	}
+
+	// find a char in a string from an offset. Return TiXmlString::npos if not found
+	size_type find (char tofind, size_type offset) const
+	{
+		if (offset >= length()) return npos;
+
+		for (const char* p = c_str() + offset; *p != '\0'; ++p)
+		{
+		   if (*p == tofind) return static_cast< size_type >( p - c_str() );
+		}
+		return npos;
+	}
+
+	void clear ()
+	{
+		//Lee:
+		//The original was just too strange, though correct:
+		//	TiXmlString().swap(*this);
+		//Instead use the quit & re-init:
+		quit();
+		init(0,0);
+	}
+
+	/*	Function to reserve a big amount of data when we know we'll need it. Be aware that this
+		function DOES NOT clear the content of the TiXmlString if any exists.
+	*/
+	void reserve (size_type cap);
+
+	TiXmlString& assign (const char* str, size_type len);
+
+	TiXmlString& append (const char* str, size_type len);
+
+	void swap (TiXmlString& other)
+	{
+		Rep* r = rep_;
+		rep_ = other.rep_;
+		other.rep_ = r;
+	}
+
+  private:
+
+	void init(size_type sz) { init(sz, sz); }
+	void set_size(size_type sz) { rep_->str[ rep_->size = sz ] = '\0'; }
+	char* start() const { return rep_->str; }
+	char* finish() const { return rep_->str + rep_->size; }
+
+	struct Rep
+	{
+		size_type size, capacity;
+		char str[1];
+	};
+
+	void init(size_type sz, size_type cap)
+	{
+		if (cap)
+		{
+			// Lee: the original form:
+			//	rep_ = static_cast<Rep*>(operator new(sizeof(Rep) + cap));
+			// doesn't work in some cases of new being overloaded. Switching
+			// to the normal allocation, although use an 'int' for systems
+			// that are overly picky about structure alignment.
+			const size_type bytesNeeded = sizeof(Rep) + cap;
+			const size_type intsNeeded = ( bytesNeeded + sizeof(int) - 1 ) / sizeof( int ); 
+			rep_ = reinterpret_cast<Rep*>( new int[ intsNeeded ] );
+
+			rep_->str[ rep_->size = sz ] = '\0';
+			rep_->capacity = cap;
+		}
+		else
+		{
+			rep_ = &nullrep_;
+		}
+	}
+
+	void quit()
+	{
+		if (rep_ != &nullrep_)
+		{
+			// The rep_ is really an array of ints. (see the allocator, above).
+			// Cast it back before delete, so the compiler won't incorrectly call destructors.
+			delete [] ( reinterpret_cast<int*>( rep_ ) );
+		}
+	}
+
+	Rep * rep_;
+	static Rep nullrep_;
+
+} ;
+
+
+inline bool operator == (const TiXmlString & a, const TiXmlString & b)
+{
+	return    ( a.length() == b.length() )				// optimization on some platforms
+	       && ( strcmp(a.c_str(), b.c_str()) == 0 );	// actual compare
+}
+inline bool operator < (const TiXmlString & a, const TiXmlString & b)
+{
+	return strcmp(a.c_str(), b.c_str()) < 0;
+}
+
+inline bool operator != (const TiXmlString & a, const TiXmlString & b) { return !(a == b); }
+inline bool operator >  (const TiXmlString & a, const TiXmlString & b) { return b < a; }
+inline bool operator <= (const TiXmlString & a, const TiXmlString & b) { return !(b < a); }
+inline bool operator >= (const TiXmlString & a, const TiXmlString & b) { return !(a < b); }
+
+inline bool operator == (const TiXmlString & a, const char* b) { return strcmp(a.c_str(), b) == 0; }
+inline bool operator == (const char* a, const TiXmlString & b) { return b == a; }
+inline bool operator != (const TiXmlString & a, const char* b) { return !(a == b); }
+inline bool operator != (const char* a, const TiXmlString & b) { return !(b == a); }
+
+TiXmlString operator + (const TiXmlString & a, const TiXmlString & b);
+TiXmlString operator + (const TiXmlString & a, const char* b);
+TiXmlString operator + (const char* a, const TiXmlString & b);
+
+
+/*
+   TiXmlOutStream is an emulation of std::ostream. It is based on TiXmlString.
+   Only the operators that we need for TinyXML have been developped.
+*/
+class TiXmlOutStream : public TiXmlString
+{
+public :
+
+	// TiXmlOutStream << operator.
+	TiXmlOutStream & operator << (const TiXmlString & in)
+	{
+		*this += in;
+		return *this;
+	}
+
+	// TiXmlOutStream << operator.
+	TiXmlOutStream & operator << (const char * in)
+	{
+		*this += in;
+		return *this;
+	}
+
+} ;
+
+#endif	// TIXML_STRING_INCLUDED
+#endif	// TIXML_USE_STL
Index: branches/network/src/lib/parser/tinyxml/tinyxml.cc
===================================================================
--- branches/network/src/lib/parser/tinyxml/tinyxml.cc	(revision 6636)
+++ branches/network/src/lib/parser/tinyxml/tinyxml.cc	(revision 6636)
@@ -0,0 +1,1732 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+#include <ctype.h>
+#include "tinyxml.h"
+
+#ifdef TIXML_USE_STL
+#include <sstream>
+#endif
+
+
+bool TiXmlBase::condenseWhiteSpace = true;
+
+void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_OSTREAM* stream )
+{
+	TIXML_STRING buffer;
+	PutString( str, &buffer );
+	(*stream) << buffer;
+}
+
+void TiXmlBase::PutString( const TIXML_STRING& str, TIXML_STRING* outString )
+{
+	int i=0;
+
+	while( i<(int)str.length() )
+	{
+		unsigned char c = (unsigned char) str[i];
+
+		if (    c == '&' 
+		     && i < ( (int)str.length() - 2 )
+			 && str[i+1] == '#'
+			 && str[i+2] == 'x' )
+		{
+			// Hexadecimal character reference.
+			// Pass through unchanged.
+			// &#xA9;	-- copyright symbol, for example.
+			//
+			// The -1 is a bug fix from Rob Laveaux. It keeps
+			// an overflow from happening if there is no ';'.
+			// There are actually 2 ways to exit this loop -
+			// while fails (error case) and break (semicolon found).
+			// However, there is no mechanism (currently) for
+			// this function to return an error.
+			while ( i<(int)str.length()-1 )
+			{
+				outString->append( str.c_str() + i, 1 );
+				++i;
+				if ( str[i] == ';' )
+					break;
+			}
+		}
+		else if ( c == '&' )
+		{
+			outString->append( entity[0].str, entity[0].strLength );
+			++i;
+		}
+		else if ( c == '<' )
+		{
+			outString->append( entity[1].str, entity[1].strLength );
+			++i;
+		}
+		else if ( c == '>' )
+		{
+			outString->append( entity[2].str, entity[2].strLength );
+			++i;
+		}
+		else if ( c == '\"' )
+		{
+			outString->append( entity[3].str, entity[3].strLength );
+			++i;
+		}
+		else if ( c == '\'' )
+		{
+			outString->append( entity[4].str, entity[4].strLength );
+			++i;
+		}
+		else if ( c < 32 )
+		{
+			// Easy pass at non-alpha/numeric/symbol
+			// Below 32 is symbolic.
+			char buf[ 32 ];
+			
+			#if defined(TIXML_SNPRINTF)		
+				TIXML_SNPRINTF( buf, sizeof(buf), "&#x%02X;", (unsigned) ( c & 0xff ) );
+			#else
+				sprintf( buf, "&#x%02X;", (unsigned) ( c & 0xff ) );
+			#endif		
+
+			//*ME:	warning C4267: convert 'size_t' to 'int'
+			//*ME:	Int-Cast to make compiler happy ...
+			outString->append( buf, (int)strlen( buf ) );
+			++i;
+		}
+		else
+		{
+			//char realc = (char) c;
+			//outString->append( &realc, 1 );
+			*outString += (char) c;	// somewhat more efficient function call.
+			++i;
+		}
+	}
+}
+
+
+// <-- Strange class for a bug fix. Search for STL_STRING_BUG
+TiXmlBase::StringToBuffer::StringToBuffer( const TIXML_STRING& str )
+{
+	buffer = new char[ str.length()+1 ];
+	if ( buffer )
+	{
+		strcpy( buffer, str.c_str() );
+	}
+}
+
+
+TiXmlBase::StringToBuffer::~StringToBuffer()
+{
+	delete [] buffer;
+}
+// End strange bug fix. -->
+
+
+TiXmlNode::TiXmlNode( NodeType _type ) : TiXmlBase()
+{
+	parent = 0;
+	type = _type;
+	firstChild = 0;
+	lastChild = 0;
+	prev = 0;
+	next = 0;
+}
+
+
+TiXmlNode::~TiXmlNode()
+{
+	TiXmlNode* node = firstChild;
+	TiXmlNode* temp = 0;
+
+	while ( node )
+	{
+		temp = node;
+		node = node->next;
+		delete temp;
+	}	
+}
+
+
+void TiXmlNode::CopyTo( TiXmlNode* target ) const
+{
+	target->SetValue (value.c_str() );
+	target->userData = userData; 
+}
+
+
+void TiXmlNode::Clear()
+{
+	TiXmlNode* node = firstChild;
+	TiXmlNode* temp = 0;
+
+	while ( node )
+	{
+		temp = node;
+		node = node->next;
+		delete temp;
+	}	
+
+	firstChild = 0;
+	lastChild = 0;
+}
+
+
+TiXmlNode* TiXmlNode::LinkEndChild( TiXmlNode* node )
+{
+	node->parent = this;
+
+	node->prev = lastChild;
+	node->next = 0;
+
+	if ( lastChild )
+		lastChild->next = node;
+	else
+		firstChild = node;			// it was an empty list.
+
+	lastChild = node;
+	return node;
+}
+
+
+TiXmlNode* TiXmlNode::InsertEndChild( const TiXmlNode& addThis )
+{
+	TiXmlNode* node = addThis.Clone();
+	if ( !node )
+		return 0;
+
+	return LinkEndChild( node );
+}
+
+
+TiXmlNode* TiXmlNode::InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis )
+{	
+	if ( !beforeThis || beforeThis->parent != this )
+		return 0;
+
+	TiXmlNode* node = addThis.Clone();
+	if ( !node )
+		return 0;
+	node->parent = this;
+
+	node->next = beforeThis;
+	node->prev = beforeThis->prev;
+	if ( beforeThis->prev )
+	{
+		beforeThis->prev->next = node;
+	}
+	else
+	{
+		assert( firstChild == beforeThis );
+		firstChild = node;
+	}
+	beforeThis->prev = node;
+	return node;
+}
+
+
+TiXmlNode* TiXmlNode::InsertAfterChild( TiXmlNode* afterThis, const TiXmlNode& addThis )
+{
+	if ( !afterThis || afterThis->parent != this )
+		return 0;
+
+	TiXmlNode* node = addThis.Clone();
+	if ( !node )
+		return 0;
+	node->parent = this;
+
+	node->prev = afterThis;
+	node->next = afterThis->next;
+	if ( afterThis->next )
+	{
+		afterThis->next->prev = node;
+	}
+	else
+	{
+		assert( lastChild == afterThis );
+		lastChild = node;
+	}
+	afterThis->next = node;
+	return node;
+}
+
+
+TiXmlNode* TiXmlNode::ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis )
+{
+	if ( replaceThis->parent != this )
+		return 0;
+
+	TiXmlNode* node = withThis.Clone();
+	if ( !node )
+		return 0;
+
+	node->next = replaceThis->next;
+	node->prev = replaceThis->prev;
+
+	if ( replaceThis->next )
+		replaceThis->next->prev = node;
+	else
+		lastChild = node;
+
+	if ( replaceThis->prev )
+		replaceThis->prev->next = node;
+	else
+		firstChild = node;
+
+	delete replaceThis;
+	node->parent = this;
+	return node;
+}
+
+
+bool TiXmlNode::RemoveChild( TiXmlNode* removeThis )
+{
+	if ( removeThis->parent != this )
+	{	
+		assert( 0 );
+		return false;
+	}
+
+	if ( removeThis->next )
+		removeThis->next->prev = removeThis->prev;
+	else
+		lastChild = removeThis->prev;
+
+	if ( removeThis->prev )
+		removeThis->prev->next = removeThis->next;
+	else
+		firstChild = removeThis->next;
+
+	delete removeThis;
+	return true;
+}
+
+const TiXmlNode* TiXmlNode::FirstChild( const char * _value ) const
+{
+	const TiXmlNode* node;
+	for ( node = firstChild; node; node = node->next )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+TiXmlNode* TiXmlNode::FirstChild( const char * _value )
+{
+	TiXmlNode* node;
+	for ( node = firstChild; node; node = node->next )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+
+const TiXmlNode* TiXmlNode::LastChild( const char * _value ) const
+{
+	const TiXmlNode* node;
+	for ( node = lastChild; node; node = node->prev )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+TiXmlNode* TiXmlNode::LastChild( const char * _value )
+{
+	TiXmlNode* node;
+	for ( node = lastChild; node; node = node->prev )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+const TiXmlNode* TiXmlNode::IterateChildren( const TiXmlNode* previous ) const
+{
+	if ( !previous )
+	{
+		return FirstChild();
+	}
+	else
+	{
+		assert( previous->parent == this );
+		return previous->NextSibling();
+	}
+}
+
+TiXmlNode* TiXmlNode::IterateChildren( TiXmlNode* previous )
+{
+	if ( !previous )
+	{
+		return FirstChild();
+	}
+	else
+	{
+		assert( previous->parent == this );
+		return previous->NextSibling();
+	}
+}
+
+const TiXmlNode* TiXmlNode::IterateChildren( const char * val, const TiXmlNode* previous ) const
+{
+	if ( !previous )
+	{
+		return FirstChild( val );
+	}
+	else
+	{
+		assert( previous->parent == this );
+		return previous->NextSibling( val );
+	}
+}
+
+TiXmlNode* TiXmlNode::IterateChildren( const char * val, TiXmlNode* previous )
+{
+	if ( !previous )
+	{
+		return FirstChild( val );
+	}
+	else
+	{
+		assert( previous->parent == this );
+		return previous->NextSibling( val );
+	}
+}
+
+const TiXmlNode* TiXmlNode::NextSibling( const char * _value ) const 
+{
+	const TiXmlNode* node;
+	for ( node = next; node; node = node->next )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+TiXmlNode* TiXmlNode::NextSibling( const char * _value )
+{
+	TiXmlNode* node;
+	for ( node = next; node; node = node->next )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+const TiXmlNode* TiXmlNode::PreviousSibling( const char * _value ) const
+{
+	const TiXmlNode* node;
+	for ( node = prev; node; node = node->prev )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+TiXmlNode* TiXmlNode::PreviousSibling( const char * _value )
+{
+	TiXmlNode* node;
+	for ( node = prev; node; node = node->prev )
+	{
+		if ( strcmp( node->Value(), _value ) == 0 )
+			return node;
+	}
+	return 0;
+}
+
+void TiXmlElement::RemoveAttribute( const char * name )
+{
+	TiXmlAttribute* node = attributeSet.Find( name );
+	if ( node )
+	{
+		attributeSet.Remove( node );
+		delete node;
+	}
+}
+
+const TiXmlElement* TiXmlNode::FirstChildElement() const
+{
+	const TiXmlNode* node;
+
+	for (	node = FirstChild();
+			node;
+			node = node->NextSibling() )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+TiXmlElement* TiXmlNode::FirstChildElement()
+{
+	TiXmlNode* node;
+
+	for (	node = FirstChild();
+			node;
+			node = node->NextSibling() )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+const TiXmlElement* TiXmlNode::FirstChildElement( const char * _value ) const
+{
+	const TiXmlNode* node;
+
+	for (	node = FirstChild( _value );
+			node;
+			node = node->NextSibling( _value ) )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+TiXmlElement* TiXmlNode::FirstChildElement( const char * _value )
+{
+	TiXmlNode* node;
+
+	for (	node = FirstChild( _value );
+			node;
+			node = node->NextSibling( _value ) )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+const TiXmlElement* TiXmlNode::NextSiblingElement() const
+{
+	const TiXmlNode* node;
+
+	for (	node = NextSibling();
+	node;
+	node = node->NextSibling() )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+TiXmlElement* TiXmlNode::NextSiblingElement()
+{
+	TiXmlNode* node;
+
+	for (	node = NextSibling();
+	node;
+	node = node->NextSibling() )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+const TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value ) const
+{
+	const TiXmlNode* node;
+
+	for (	node = NextSibling( _value );
+	node;
+	node = node->NextSibling( _value ) )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+TiXmlElement* TiXmlNode::NextSiblingElement( const char * _value )
+{
+	TiXmlNode* node;
+
+	for (	node = NextSibling( _value );
+	node;
+	node = node->NextSibling( _value ) )
+	{
+		if ( node->ToElement() )
+			return node->ToElement();
+	}
+	return 0;
+}
+
+
+const TiXmlDocument* TiXmlNode::GetDocument() const
+{
+	const TiXmlNode* node;
+
+	for( node = this; node; node = node->parent )
+	{
+		if ( node->ToDocument() )
+			return node->ToDocument();
+	}
+	return 0;
+}
+
+TiXmlDocument* TiXmlNode::GetDocument()
+{
+	TiXmlNode* node;
+
+	for( node = this; node; node = node->parent )
+	{
+		if ( node->ToDocument() )
+			return node->ToDocument();
+	}
+	return 0;
+}
+
+TiXmlElement::TiXmlElement (const char * _value)
+	: TiXmlNode( TiXmlNode::ELEMENT )
+{
+	firstChild = lastChild = 0;
+	value = _value;
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlElement::TiXmlElement( const std::string& _value ) 
+	: TiXmlNode( TiXmlNode::ELEMENT )
+{
+	firstChild = lastChild = 0;
+	value = _value;
+}
+#endif
+
+
+TiXmlElement::TiXmlElement( const TiXmlElement& copy)
+	: TiXmlNode( TiXmlNode::ELEMENT )
+{
+	firstChild = lastChild = 0;
+	copy.CopyTo( this );	
+}
+
+
+void TiXmlElement::operator=( const TiXmlElement& base )
+{
+	ClearThis();
+	base.CopyTo( this );
+}
+
+
+TiXmlElement::~TiXmlElement()
+{
+	ClearThis();
+}
+
+
+void TiXmlElement::ClearThis()
+{
+	Clear();
+	while( attributeSet.First() )
+	{
+		TiXmlAttribute* node = attributeSet.First();
+		attributeSet.Remove( node );
+		delete node;
+	}
+}
+
+
+const char * TiXmlElement::Attribute( const char * name ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+
+	if ( node )
+		return node->Value();
+
+	return 0;
+}
+
+
+const char * TiXmlElement::Attribute( const char * name, int* i ) const
+{
+	const char * s = Attribute( name );
+	if ( i )
+	{
+		if ( s )
+			*i = atoi( s );
+		else
+			*i = 0;
+	}
+	return s;
+}
+
+
+const char * TiXmlElement::Attribute( const char * name, double* d ) const
+{
+	const char * s = Attribute( name );
+	if ( d )
+	{
+		if ( s )
+			*d = atof( s );
+		else
+			*d = 0;
+	}
+	return s;
+}
+
+
+int TiXmlElement::QueryIntAttribute( const char* name, int* ival ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+	if ( !node )
+		return TIXML_NO_ATTRIBUTE;
+
+	return node->QueryIntValue( ival );
+}
+
+
+int TiXmlElement::QueryDoubleAttribute( const char* name, double* dval ) const
+{
+	const TiXmlAttribute* node = attributeSet.Find( name );
+	if ( !node )
+		return TIXML_NO_ATTRIBUTE;
+
+	return node->QueryDoubleValue( dval );
+}
+
+
+void TiXmlElement::SetAttribute( const char * name, int val )
+{	
+	char buf[64];
+	#if defined(TIXML_SNPRINTF)		
+		TIXML_SNPRINTF( buf, sizeof(buf), "%d", val );
+	#else
+		sprintf( buf, "%d", val );
+	#endif
+	SetAttribute( name, buf );
+}
+
+
+void TiXmlElement::SetDoubleAttribute( const char * name, double val )
+{	
+	char buf[256];
+	#if defined(TIXML_SNPRINTF)		
+		TIXML_SNPRINTF( buf, sizeof(buf), "%f", val );
+	#else
+		sprintf( buf, "%f", val );
+	#endif
+	SetAttribute( name, buf );
+}
+
+
+void TiXmlElement::SetAttribute( const char * name, const char * _value )
+{
+	TiXmlAttribute* node = attributeSet.Find( name );
+	if ( node )
+	{
+		node->SetValue( _value );
+		return;
+	}
+
+	TiXmlAttribute* attrib = new TiXmlAttribute( name, _value );
+	if ( attrib )
+	{
+		attributeSet.Add( attrib );
+	}
+	else
+	{
+		TiXmlDocument* document = GetDocument();
+		if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
+	}
+}
+
+void TiXmlElement::Print( FILE* cfile, int depth ) const
+{
+	int i;
+	for ( i=0; i<depth; i++ )
+	{
+		fprintf( cfile, "    " );
+	}
+
+	fprintf( cfile, "<%s", value.c_str() );
+
+	const TiXmlAttribute* attrib;
+	for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
+	{
+		fprintf( cfile, " " );
+		attrib->Print( cfile, depth );
+	}
+
+	// There are 3 different formatting approaches:
+	// 1) An element without children is printed as a <foo /> node
+	// 2) An element with only a text child is printed as <foo> text </foo>
+	// 3) An element with children is printed on multiple lines.
+	TiXmlNode* node;
+	if ( !firstChild )
+	{
+		fprintf( cfile, " />" );
+	}
+	else if ( firstChild == lastChild && firstChild->ToText() )
+	{
+		fprintf( cfile, ">" );
+		firstChild->Print( cfile, depth + 1 );
+		fprintf( cfile, "</%s>", value.c_str() );
+	}
+	else
+	{
+		fprintf( cfile, ">" );
+
+		for ( node = firstChild; node; node=node->NextSibling() )
+		{
+			if ( !node->ToText() )
+			{
+				fprintf( cfile, "\n" );
+			}
+			node->Print( cfile, depth+1 );
+		}
+		fprintf( cfile, "\n" );
+		for( i=0; i<depth; ++i )
+		fprintf( cfile, "    " );
+		fprintf( cfile, "</%s>", value.c_str() );
+	}
+}
+
+void TiXmlElement::StreamOut( TIXML_OSTREAM * stream ) const
+{
+	(*stream) << "<" << value;
+
+	const TiXmlAttribute* attrib;
+	for ( attrib = attributeSet.First(); attrib; attrib = attrib->Next() )
+	{	
+		(*stream) << " ";
+		attrib->StreamOut( stream );
+	}
+
+	// If this node has children, give it a closing tag. Else
+	// make it an empty tag.
+	TiXmlNode* node;
+	if ( firstChild )
+	{ 		
+		(*stream) << ">";
+
+		for ( node = firstChild; node; node=node->NextSibling() )
+		{
+			node->StreamOut( stream );
+		}
+		(*stream) << "</" << value << ">";
+	}
+	else
+	{
+		(*stream) << " />";
+	}
+}
+
+
+void TiXmlElement::CopyTo( TiXmlElement* target ) const
+{
+	// superclass:
+	TiXmlNode::CopyTo( target );
+
+	// Element class: 
+	// Clone the attributes, then clone the children.
+	const TiXmlAttribute* attribute = 0;
+	for(	attribute = attributeSet.First();
+	attribute;
+	attribute = attribute->Next() )
+	{
+		target->SetAttribute( attribute->Name(), attribute->Value() );
+	}
+
+	TiXmlNode* node = 0;
+	for ( node = firstChild; node; node = node->NextSibling() )
+	{
+		target->LinkEndChild( node->Clone() );
+	}
+}
+
+
+TiXmlNode* TiXmlElement::Clone() const
+{
+	TiXmlElement* clone = new TiXmlElement( Value() );
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+const char* TiXmlElement::GetText() const
+{
+	const TiXmlNode* child = this->FirstChild();
+	if ( child ) {
+		const TiXmlText* childText = child->ToText();
+		if ( childText ) {
+			return childText->Value();
+		}
+	}
+	return 0;
+}
+
+
+TiXmlDocument::TiXmlDocument() : TiXmlNode( TiXmlNode::DOCUMENT )
+{
+	tabsize = 4;
+	useMicrosoftBOM = false;
+	ClearError();
+}
+
+TiXmlDocument::TiXmlDocument( const char * documentName ) : TiXmlNode( TiXmlNode::DOCUMENT )
+{
+	tabsize = 4;
+	useMicrosoftBOM = false;
+	value = documentName;
+	ClearError();
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlDocument::TiXmlDocument( const std::string& documentName ) : TiXmlNode( TiXmlNode::DOCUMENT )
+{
+	tabsize = 4;
+	useMicrosoftBOM = false;
+    value = documentName;
+	ClearError();
+}
+#endif
+
+
+TiXmlDocument::TiXmlDocument( const TiXmlDocument& copy ) : TiXmlNode( TiXmlNode::DOCUMENT )
+{
+	copy.CopyTo( this );
+}
+
+
+void TiXmlDocument::operator=( const TiXmlDocument& copy )
+{
+	Clear();
+	copy.CopyTo( this );
+}
+
+
+bool TiXmlDocument::LoadFile( TiXmlEncoding encoding )
+{
+	// See STL_STRING_BUG below.
+	StringToBuffer buf( value );
+
+	if ( buf.buffer && LoadFile( buf.buffer, encoding ) )
+		return true;
+
+	return false;
+}
+
+
+bool TiXmlDocument::SaveFile() const
+{
+	// See STL_STRING_BUG below.
+	StringToBuffer buf( value );
+
+	if ( buf.buffer && SaveFile( buf.buffer ) )
+		return true;
+
+	return false;
+}
+
+bool TiXmlDocument::LoadFile( const char* filename, TiXmlEncoding encoding )
+{
+	// Delete the existing data:
+	Clear();
+	location.Clear();
+
+	// There was a really terrifying little bug here. The code:
+	//		value = filename
+	// in the STL case, cause the assignment method of the std::string to
+	// be called. What is strange, is that the std::string had the same
+	// address as it's c_str() method, and so bad things happen. Looks
+	// like a bug in the Microsoft STL implementation.
+	// See STL_STRING_BUG above.
+	// Fixed with the StringToBuffer class.
+	value = filename;
+
+	// reading in binary mode so that tinyxml can normalize the EOL
+	FILE* file = fopen( value.c_str (), "rb" );	
+
+	if ( file )
+	{
+		// Get the file size, so we can pre-allocate the string. HUGE speed impact.
+		long length = 0;
+		fseek( file, 0, SEEK_END );
+		length = ftell( file );
+		fseek( file, 0, SEEK_SET );
+
+		// Strange case, but good to handle up front.
+		if ( length == 0 )
+		{
+			fclose( file );
+			return false;
+		}
+
+		// If we have a file, assume it is all one big XML file, and read it in.
+		// The document parser may decide the document ends sooner than the entire file, however.
+		TIXML_STRING data;
+		data.reserve( length );
+
+		// Subtle bug here. TinyXml did use fgets. But from the XML spec:
+		// 2.11 End-of-Line Handling
+		// <snip>
+		// <quote>
+		// ...the XML processor MUST behave as if it normalized all line breaks in external 
+		// parsed entities (including the document entity) on input, before parsing, by translating 
+		// both the two-character sequence #xD #xA and any #xD that is not followed by #xA to 
+		// a single #xA character.
+		// </quote>
+		//
+		// It is not clear fgets does that, and certainly isn't clear it works cross platform. 
+		// Generally, you expect fgets to translate from the convention of the OS to the c/unix
+		// convention, and not work generally.
+
+		/*
+		while( fgets( buf, sizeof(buf), file ) )
+		{
+			data += buf;
+		}
+		*/
+
+		char* buf = new char[ length+1 ];
+		buf[0] = 0;
+
+		if ( fread( buf, length, 1, file ) != 1 ) {
+		//if ( fread( buf, 1, length, file ) != (size_t)length ) {
+			SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
+			fclose( file );
+			return false;
+		}
+		fclose( file );
+
+		const char* lastPos = buf;
+		const char* p = buf;
+
+		buf[length] = 0;
+		while( *p ) {
+			assert( p < (buf+length) );
+			if ( *p == 0xa ) {
+				// Newline character. No special rules for this. Append all the characters
+				// since the last string, and include the newline.
+				data.append( lastPos, p-lastPos+1 );	// append, include the newline
+				++p;									// move past the newline
+				lastPos = p;							// and point to the new buffer (may be 0)
+				assert( p <= (buf+length) );
+			}
+			else if ( *p == 0xd ) {
+				// Carriage return. Append what we have so far, then
+				// handle moving forward in the buffer.
+				if ( (p-lastPos) > 0 ) {
+					data.append( lastPos, p-lastPos );	// do not add the CR
+				}
+				data += (char)0xa;						// a proper newline
+
+				if ( *(p+1) == 0xa ) {
+					// Carriage return - new line sequence
+					p += 2;
+					lastPos = p;
+					assert( p <= (buf+length) );
+				}
+				else {
+					// it was followed by something else...that is presumably characters again.
+					++p;
+					lastPos = p;
+					assert( p <= (buf+length) );
+				}
+			}
+			else {
+				++p;
+			}
+		}
+		// Handle any left over characters.
+		if ( p-lastPos ) {
+			data.append( lastPos, p-lastPos );
+		}		
+		delete [] buf;
+		buf = 0;
+
+		Parse( data.c_str(), 0, encoding );
+
+		if (  Error() )
+            return false;
+        else
+			return true;
+	}
+	SetError( TIXML_ERROR_OPENING_FILE, 0, 0, TIXML_ENCODING_UNKNOWN );
+	return false;
+}
+
+bool TiXmlDocument::SaveFile( const char * filename ) const
+{
+	// The old c stuff lives on...
+	FILE* fp = fopen( filename, "w" );
+	if ( fp )
+	{
+		if ( useMicrosoftBOM ) 
+		{
+			const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
+			const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
+			const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
+
+			fputc( TIXML_UTF_LEAD_0, fp );
+			fputc( TIXML_UTF_LEAD_1, fp );
+			fputc( TIXML_UTF_LEAD_2, fp );
+		}
+		Print( fp, 0 );
+		fclose( fp );
+		return true;
+	}
+	return false;
+}
+
+
+void TiXmlDocument::CopyTo( TiXmlDocument* target ) const
+{
+	TiXmlNode::CopyTo( target );
+
+	target->error = error;
+	target->errorDesc = errorDesc.c_str ();
+
+	TiXmlNode* node = 0;
+	for ( node = firstChild; node; node = node->NextSibling() )
+	{
+		target->LinkEndChild( node->Clone() );
+	}	
+}
+
+
+TiXmlNode* TiXmlDocument::Clone() const
+{
+	TiXmlDocument* clone = new TiXmlDocument();
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+void TiXmlDocument::Print( FILE* cfile, int depth ) const
+{
+	const TiXmlNode* node;
+	for ( node=FirstChild(); node; node=node->NextSibling() )
+	{
+		node->Print( cfile, depth );
+		fprintf( cfile, "\n" );
+	}
+}
+
+void TiXmlDocument::StreamOut( TIXML_OSTREAM * out ) const
+{
+	const TiXmlNode* node;
+	for ( node=FirstChild(); node; node=node->NextSibling() )
+	{
+		node->StreamOut( out );
+
+		// Special rule for streams: stop after the root element.
+		// The stream in code will only read one element, so don't
+		// write more than one.
+		if ( node->ToElement() )
+			break;
+	}
+}
+
+
+const TiXmlAttribute* TiXmlAttribute::Next() const
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( next->value.empty() && next->name.empty() )
+		return 0;
+	return next;
+}
+
+TiXmlAttribute* TiXmlAttribute::Next()
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( next->value.empty() && next->name.empty() )
+		return 0;
+	return next;
+}
+
+const TiXmlAttribute* TiXmlAttribute::Previous() const
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( prev->value.empty() && prev->name.empty() )
+		return 0;
+	return prev;
+}
+
+TiXmlAttribute* TiXmlAttribute::Previous()
+{
+	// We are using knowledge of the sentinel. The sentinel
+	// have a value or name.
+	if ( prev->value.empty() && prev->name.empty() )
+		return 0;
+	return prev;
+}
+
+void TiXmlAttribute::Print( FILE* cfile, int /*depth*/ ) const
+{
+	TIXML_STRING n, v;
+
+	PutString( name, &n );
+	PutString( value, &v );
+
+	if (value.find ('\"') == TIXML_STRING::npos)
+		fprintf (cfile, "%s=\"%s\"", n.c_str(), v.c_str() );
+	else
+		fprintf (cfile, "%s='%s'", n.c_str(), v.c_str() );
+}
+
+
+void TiXmlAttribute::StreamOut( TIXML_OSTREAM * stream ) const
+{
+	if (value.find( '\"' ) != TIXML_STRING::npos)
+	{
+		PutString( name, stream );
+		(*stream) << "=" << "'";
+		PutString( value, stream );
+		(*stream) << "'";
+	}
+	else
+	{
+		PutString( name, stream );
+		(*stream) << "=" << "\"";
+		PutString( value, stream );
+		(*stream) << "\"";
+	}
+}
+
+int TiXmlAttribute::QueryIntValue( int* ival ) const
+{
+	if ( sscanf( value.c_str(), "%d", ival ) == 1 )
+		return TIXML_SUCCESS;
+	return TIXML_WRONG_TYPE;
+}
+
+int TiXmlAttribute::QueryDoubleValue( double* dval ) const
+{
+	if ( sscanf( value.c_str(), "%lf", dval ) == 1 )
+		return TIXML_SUCCESS;
+	return TIXML_WRONG_TYPE;
+}
+
+void TiXmlAttribute::SetIntValue( int _value )
+{
+	char buf [64];
+	#if defined(TIXML_SNPRINTF)		
+		TIXML_SNPRINTF(buf, sizeof(buf), "%d", _value);
+	#else
+		sprintf (buf, "%d", _value);
+	#endif
+	SetValue (buf);
+}
+
+void TiXmlAttribute::SetDoubleValue( double _value )
+{
+	char buf [256];
+	#if defined(TIXML_SNPRINTF)		
+		TIXML_SNPRINTF( buf, sizeof(buf), "%lf", _value);
+	#else
+		sprintf (buf, "%lf", _value);
+	#endif
+	SetValue (buf);
+}
+
+int TiXmlAttribute::IntValue() const
+{
+	return atoi (value.c_str ());
+}
+
+double  TiXmlAttribute::DoubleValue() const
+{
+	return atof (value.c_str ());
+}
+
+
+TiXmlComment::TiXmlComment( const TiXmlComment& copy ) : TiXmlNode( TiXmlNode::COMMENT )
+{
+	copy.CopyTo( this );
+}
+
+
+void TiXmlComment::operator=( const TiXmlComment& base )
+{
+	Clear();
+	base.CopyTo( this );
+}
+
+
+void TiXmlComment::Print( FILE* cfile, int depth ) const
+{
+	for ( int i=0; i<depth; i++ )
+	{
+		fputs( "    ", cfile );
+	}
+	fprintf( cfile, "<!--%s-->", value.c_str() );
+}
+
+void TiXmlComment::StreamOut( TIXML_OSTREAM * stream ) const
+{
+	(*stream) << "<!--";
+	//PutString( value, stream );
+	(*stream) << value;
+	(*stream) << "-->";
+}
+
+
+void TiXmlComment::CopyTo( TiXmlComment* target ) const
+{
+	TiXmlNode::CopyTo( target );
+}
+
+
+TiXmlNode* TiXmlComment::Clone() const
+{
+	TiXmlComment* clone = new TiXmlComment();
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+void TiXmlText::Print( FILE* cfile, int depth ) const
+{
+	if ( cdata )
+	{
+		int i;
+		fprintf( cfile, "\n" );
+		for ( i=0; i<depth; i++ ) {
+			fprintf( cfile, "    " );
+		}
+		fprintf( cfile, "<![CDATA[" );
+		fprintf( cfile, "%s", value.c_str() );	// unformatted output
+		fprintf( cfile, "]]>\n" );
+	}
+	else
+	{
+		TIXML_STRING buffer;
+		PutString( value, &buffer );
+		fprintf( cfile, "%s", buffer.c_str() );
+	}
+}
+
+
+void TiXmlText::StreamOut( TIXML_OSTREAM * stream ) const
+{
+	if ( cdata )
+	{
+		(*stream) << "<![CDATA[" << value << "]]>";
+	}
+	else
+	{
+		PutString( value, stream );
+	}
+}
+
+
+void TiXmlText::CopyTo( TiXmlText* target ) const
+{
+	TiXmlNode::CopyTo( target );
+	target->cdata = cdata;
+}
+
+
+TiXmlNode* TiXmlText::Clone() const
+{	
+	TiXmlText* clone = 0;
+	clone = new TiXmlText( "" );
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+TiXmlDeclaration::TiXmlDeclaration( const char * _version,
+									const char * _encoding,
+									const char * _standalone )
+	: TiXmlNode( TiXmlNode::DECLARATION )
+{
+	version = _version;
+	encoding = _encoding;
+	standalone = _standalone;
+}
+
+
+#ifdef TIXML_USE_STL
+TiXmlDeclaration::TiXmlDeclaration(	const std::string& _version,
+									const std::string& _encoding,
+									const std::string& _standalone )
+	: TiXmlNode( TiXmlNode::DECLARATION )
+{
+	version = _version;
+	encoding = _encoding;
+	standalone = _standalone;
+}
+#endif
+
+
+TiXmlDeclaration::TiXmlDeclaration( const TiXmlDeclaration& copy )
+	: TiXmlNode( TiXmlNode::DECLARATION )
+{
+	copy.CopyTo( this );	
+}
+
+
+void TiXmlDeclaration::operator=( const TiXmlDeclaration& copy )
+{
+	Clear();
+	copy.CopyTo( this );
+}
+
+
+void TiXmlDeclaration::Print( FILE* cfile, int /*depth*/ ) const
+{
+	fprintf (cfile, "<?xml ");
+
+	if ( !version.empty() )
+		fprintf (cfile, "version=\"%s\" ", version.c_str ());
+	if ( !encoding.empty() )
+		fprintf (cfile, "encoding=\"%s\" ", encoding.c_str ());
+	if ( !standalone.empty() )
+		fprintf (cfile, "standalone=\"%s\" ", standalone.c_str ());
+	fprintf (cfile, "?>");
+}
+
+void TiXmlDeclaration::StreamOut( TIXML_OSTREAM * stream ) const
+{
+	(*stream) << "<?xml ";
+
+	if ( !version.empty() )
+	{
+		(*stream) << "version=\"";
+		PutString( version, stream );
+		(*stream) << "\" ";
+	}
+	if ( !encoding.empty() )
+	{
+		(*stream) << "encoding=\"";
+		PutString( encoding, stream );
+		(*stream ) << "\" ";
+	}
+	if ( !standalone.empty() )
+	{
+		(*stream) << "standalone=\"";
+		PutString( standalone, stream );
+		(*stream) << "\" ";
+	}
+	(*stream) << "?>";
+}
+
+
+void TiXmlDeclaration::CopyTo( TiXmlDeclaration* target ) const
+{
+	TiXmlNode::CopyTo( target );
+
+	target->version = version;
+	target->encoding = encoding;
+	target->standalone = standalone;
+}
+
+
+TiXmlNode* TiXmlDeclaration::Clone() const
+{	
+	TiXmlDeclaration* clone = new TiXmlDeclaration();
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+void TiXmlUnknown::Print( FILE* cfile, int depth ) const
+{
+	for ( int i=0; i<depth; i++ )
+		fprintf( cfile, "    " );
+	fprintf( cfile, "<%s>", value.c_str() );
+}
+
+
+void TiXmlUnknown::StreamOut( TIXML_OSTREAM * stream ) const
+{
+	(*stream) << "<" << value << ">";		// Don't use entities here! It is unknown.
+}
+
+
+void TiXmlUnknown::CopyTo( TiXmlUnknown* target ) const
+{
+	TiXmlNode::CopyTo( target );
+}
+
+
+TiXmlNode* TiXmlUnknown::Clone() const
+{
+	TiXmlUnknown* clone = new TiXmlUnknown();
+
+	if ( !clone )
+		return 0;
+
+	CopyTo( clone );
+	return clone;
+}
+
+
+TiXmlAttributeSet::TiXmlAttributeSet()
+{
+	sentinel.next = &sentinel;
+	sentinel.prev = &sentinel;
+}
+
+
+TiXmlAttributeSet::~TiXmlAttributeSet()
+{
+	assert( sentinel.next == &sentinel );
+	assert( sentinel.prev == &sentinel );
+}
+
+
+void TiXmlAttributeSet::Add( TiXmlAttribute* addMe )
+{
+	assert( !Find( addMe->Name() ) );	// Shouldn't be multiply adding to the set.
+
+	addMe->next = &sentinel;
+	addMe->prev = sentinel.prev;
+
+	sentinel.prev->next = addMe;
+	sentinel.prev      = addMe;
+}
+
+void TiXmlAttributeSet::Remove( TiXmlAttribute* removeMe )
+{
+	TiXmlAttribute* node;
+
+	for( node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( node == removeMe )
+		{
+			node->prev->next = node->next;
+			node->next->prev = node->prev;
+			node->next = 0;
+			node->prev = 0;
+			return;
+		}
+	}
+	assert( 0 );		// we tried to remove a non-linked attribute.
+}
+
+const TiXmlAttribute* TiXmlAttributeSet::Find( const char * name ) const
+{
+	const TiXmlAttribute* node;
+
+	for( node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( node->name == name )
+			return node;
+	}
+	return 0;
+}
+
+TiXmlAttribute*	TiXmlAttributeSet::Find( const char * name )
+{
+	TiXmlAttribute* node;
+
+	for( node = sentinel.next; node != &sentinel; node = node->next )
+	{
+		if ( node->name == name )
+			return node;
+	}
+	return 0;
+}
+
+#ifdef TIXML_USE_STL	
+TIXML_ISTREAM & operator >> (TIXML_ISTREAM & in, TiXmlNode & base)
+{
+	TIXML_STRING tag;
+	tag.reserve( 8 * 1000 );
+	base.StreamIn( &in, &tag );
+
+	base.Parse( tag.c_str(), 0, TIXML_DEFAULT_ENCODING );
+	return in;
+}
+#endif
+
+
+TIXML_OSTREAM & operator<< (TIXML_OSTREAM & out, const TiXmlNode & base)
+{
+	base.StreamOut (& out);
+	return out;
+}
+
+
+#ifdef TIXML_USE_STL	
+std::string & operator<< (std::string& out, const TiXmlNode& base )
+{
+   std::ostringstream os_stream( std::ostringstream::out );
+   base.StreamOut( &os_stream );
+   
+   out.append( os_stream.str() );
+   return out;
+}
+#endif
+
+
+TiXmlHandle TiXmlHandle::FirstChild() const
+{
+	if ( node )
+	{
+		TiXmlNode* child = node->FirstChild();
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::FirstChild( const char * value ) const
+{
+	if ( node )
+	{
+		TiXmlNode* child = node->FirstChild( value );
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::FirstChildElement() const
+{
+	if ( node )
+	{
+		TiXmlElement* child = node->FirstChildElement();
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::FirstChildElement( const char * value ) const
+{
+	if ( node )
+	{
+		TiXmlElement* child = node->FirstChildElement( value );
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::Child( int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlNode* child = node->FirstChild();
+		for (	i=0;
+				child && i<count;
+				child = child->NextSibling(), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::Child( const char* value, int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlNode* child = node->FirstChild( value );
+		for (	i=0;
+				child && i<count;
+				child = child->NextSibling( value ), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::ChildElement( int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlElement* child = node->FirstChildElement();
+		for (	i=0;
+				child && i<count;
+				child = child->NextSiblingElement(), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
+
+
+TiXmlHandle TiXmlHandle::ChildElement( const char* value, int count ) const
+{
+	if ( node )
+	{
+		int i;
+		TiXmlElement* child = node->FirstChildElement( value );
+		for (	i=0;
+				child && i<count;
+				child = child->NextSiblingElement( value ), ++i )
+		{
+			// nothing
+		}
+		if ( child )
+			return TiXmlHandle( child );
+	}
+	return TiXmlHandle( 0 );
+}
Index: branches/network/src/lib/parser/tinyxml/tinyxml.h
===================================================================
--- branches/network/src/lib/parser/tinyxml/tinyxml.h	(revision 6636)
+++ branches/network/src/lib/parser/tinyxml/tinyxml.h	(revision 6636)
@@ -0,0 +1,1511 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied
+warranty. In no event will the authors be held liable for any
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any
+purpose, including commercial applications, and to alter it and
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+
+#ifndef TINYXML_INCLUDED
+#define TINYXML_INCLUDED
+
+#ifdef _MSC_VER
+#pragma warning( push )
+#pragma warning( disable : 4530 )
+#pragma warning( disable : 4786 )
+#endif
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+// Help out windows:
+#if defined( _DEBUG ) && !defined( DEBUG )
+#define DEBUG
+#endif
+
+#if defined( DEBUG ) && defined( _MSC_VER )
+#include <windows.h>
+#define TIXML_LOG OutputDebugString
+#else
+#define TIXML_LOG printf
+#endif
+
+#ifdef TIXML_USE_STL
+	#include <string>
+ 	#include <iostream>
+	#define TIXML_STRING	std::string
+	#define TIXML_ISTREAM	std::istream
+	#define TIXML_OSTREAM	std::ostream
+#else
+	#include "tinystr.h"
+	#define TIXML_STRING	TiXmlString
+	#define TIXML_OSTREAM	TiXmlOutStream
+#endif
+
+// Deprecated library function hell. Compilers want to use the
+// new safe versions. This probably doesn't fully address the problem,
+// but it gets closer. There are too many compilers for me to fully
+// test. If you get compilation troubles, undefine TIXML_SAFE
+
+#define TIXML_SAFE		// TinyXml isn't fully buffer overrun protected, safe code. This is work in progress.
+#ifdef TIXML_SAFE
+	#if defined(_MSC_VER) && (_MSC_VER >= 1200 )
+		// Microsoft visual studio, version 6 and higher.
+		//#pragma message( "Using _sn* functions." )
+		#define TIXML_SNPRINTF _snprintf
+		#define TIXML_SNSCANF  _snscanf
+	#elif defined(__GNUC__) && (__GNUC__ >= 3 )
+		// GCC version 3 and higher.s
+		//#warning( "Using sn* functions." )
+		#define TIXML_SNPRINTF snprintf
+		#define TIXML_SNSCANF  snscanf
+	#endif
+#endif	
+
+class TiXmlDocument;
+class TiXmlElement;
+class TiXmlComment;
+class TiXmlUnknown;
+class TiXmlAttribute;
+class TiXmlText;
+class TiXmlDeclaration;
+class TiXmlParsingData;
+
+const int TIXML_MAJOR_VERSION = 2;
+const int TIXML_MINOR_VERSION = 4;
+const int TIXML_PATCH_VERSION = 2;
+
+/*	Internal structure for tracking location of items 
+	in the XML file.
+*/
+struct TiXmlCursor
+{
+	TiXmlCursor()		{ Clear(); }
+	void Clear()		{ row = col = -1; }
+
+	int row;	// 0 based.
+	int col;	// 0 based.
+};
+
+
+// Only used by Attribute::Query functions
+enum 
+{ 
+	TIXML_SUCCESS,
+	TIXML_NO_ATTRIBUTE,
+	TIXML_WRONG_TYPE
+};
+
+
+// Used by the parsing routines.
+enum TiXmlEncoding
+{
+	TIXML_ENCODING_UNKNOWN,
+	TIXML_ENCODING_UTF8,
+	TIXML_ENCODING_LEGACY
+};
+
+const TiXmlEncoding TIXML_DEFAULT_ENCODING = TIXML_ENCODING_UNKNOWN;
+
+/** TiXmlBase is a base class for every class in TinyXml.
+	It does little except to establish that TinyXml classes
+	can be printed and provide some utility functions.
+
+	In XML, the document and elements can contain
+	other elements and other types of nodes.
+
+	@verbatim
+	A Document can contain:	Element	(container or leaf)
+							Comment (leaf)
+							Unknown (leaf)
+							Declaration( leaf )
+
+	An Element can contain:	Element (container or leaf)
+							Text	(leaf)
+							Attributes (not on tree)
+							Comment (leaf)
+							Unknown (leaf)
+
+	A Decleration contains: Attributes (not on tree)
+	@endverbatim
+*/
+class TiXmlBase
+{
+	friend class TiXmlNode;
+	friend class TiXmlElement;
+	friend class TiXmlDocument;
+
+public:
+	TiXmlBase()	:	userData(0) {}
+	virtual ~TiXmlBase()					{}
+
+	/**	All TinyXml classes can print themselves to a filestream.
+		This is a formatted print, and will insert tabs and newlines.
+		
+		(For an unformatted stream, use the << operator.)
+	*/
+	virtual void Print( FILE* cfile, int depth ) const = 0;
+
+	/**	The world does not agree on whether white space should be kept or
+		not. In order to make everyone happy, these global, static functions
+		are provided to set whether or not TinyXml will condense all white space
+		into a single space or not. The default is to condense. Note changing this
+		values is not thread safe.
+	*/
+	static void SetCondenseWhiteSpace( bool condense )		{ condenseWhiteSpace = condense; }
+
+	/// Return the current white space setting.
+	static bool IsWhiteSpaceCondensed()						{ return condenseWhiteSpace; }
+
+	/** Return the position, in the original source file, of this node or attribute.
+		The row and column are 1-based. (That is the first row and first column is
+		1,1). If the returns values are 0 or less, then the parser does not have
+		a row and column value.
+
+		Generally, the row and column value will be set when the TiXmlDocument::Load(),
+		TiXmlDocument::LoadFile(), or any TiXmlNode::Parse() is called. It will NOT be set
+		when the DOM was created from operator>>.
+
+		The values reflect the initial load. Once the DOM is modified programmatically
+		(by adding or changing nodes and attributes) the new values will NOT update to
+		reflect changes in the document.
+
+		There is a minor performance cost to computing the row and column. Computation
+		can be disabled if TiXmlDocument::SetTabSize() is called with 0 as the value.
+
+		@sa TiXmlDocument::SetTabSize()
+	*/
+	int Row() const			{ return location.row + 1; }
+	int Column() const		{ return location.col + 1; }	///< See Row()
+
+	void  SetUserData( void* user )			{ userData = user; }
+	void* GetUserData()						{ return userData; }
+
+	// Table that returs, for a given lead byte, the total number of bytes
+	// in the UTF-8 sequence.
+	static const int utf8ByteTable[256];
+
+	virtual const char* Parse(	const char* p, 
+								TiXmlParsingData* data, 
+								TiXmlEncoding encoding /*= TIXML_ENCODING_UNKNOWN */ ) = 0;
+
+	enum
+	{
+		TIXML_NO_ERROR = 0,
+		TIXML_ERROR,
+		TIXML_ERROR_OPENING_FILE,
+		TIXML_ERROR_OUT_OF_MEMORY,
+		TIXML_ERROR_PARSING_ELEMENT,
+		TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME,
+		TIXML_ERROR_READING_ELEMENT_VALUE,
+		TIXML_ERROR_READING_ATTRIBUTES,
+		TIXML_ERROR_PARSING_EMPTY,
+		TIXML_ERROR_READING_END_TAG,
+		TIXML_ERROR_PARSING_UNKNOWN,
+		TIXML_ERROR_PARSING_COMMENT,
+		TIXML_ERROR_PARSING_DECLARATION,
+		TIXML_ERROR_DOCUMENT_EMPTY,
+		TIXML_ERROR_EMBEDDED_NULL,
+		TIXML_ERROR_PARSING_CDATA,
+
+		TIXML_ERROR_STRING_COUNT
+	};
+
+protected:
+
+	// See STL_STRING_BUG
+	// Utility class to overcome a bug.
+	class StringToBuffer
+	{
+	  public:
+		StringToBuffer( const TIXML_STRING& str );
+		~StringToBuffer();
+		char* buffer;
+	};
+
+	static const char*	SkipWhiteSpace( const char*, TiXmlEncoding encoding );
+	inline static bool	IsWhiteSpace( char c )		
+	{ 
+		return ( isspace( (unsigned char) c ) || c == '\n' || c == '\r' ); 
+	}
+
+	virtual void StreamOut (TIXML_OSTREAM *) const = 0;
+
+	#ifdef TIXML_USE_STL
+	    static bool	StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag );
+	    static bool StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag );
+	#endif
+
+	/*	Reads an XML name into the string provided. Returns
+		a pointer just past the last character of the name,
+		or 0 if the function has an error.
+	*/
+	static const char* ReadName( const char* p, TIXML_STRING* name, TiXmlEncoding encoding );
+
+	/*	Reads text. Returns a pointer past the given end tag.
+		Wickedly complex options, but it keeps the (sensitive) code in one place.
+	*/
+	static const char* ReadText(	const char* in,				// where to start
+									TIXML_STRING* text,			// the string read
+									bool ignoreWhiteSpace,		// whether to keep the white space
+									const char* endTag,			// what ends this text
+									bool ignoreCase,			// whether to ignore case in the end tag
+									TiXmlEncoding encoding );	// the current encoding
+
+	// If an entity has been found, transform it into a character.
+	static const char* GetEntity( const char* in, char* value, int* length, TiXmlEncoding encoding );
+
+	// Get a character, while interpreting entities.
+	// The length can be from 0 to 4 bytes.
+	inline static const char* GetChar( const char* p, char* _value, int* length, TiXmlEncoding encoding )
+	{
+		assert( p );
+		if ( encoding == TIXML_ENCODING_UTF8 )
+		{
+			*length = utf8ByteTable[ *((unsigned char*)p) ];
+			assert( *length >= 0 && *length < 5 );
+		}
+		else
+		{
+			*length = 1;
+		}
+
+		if ( *length == 1 )
+		{
+			if ( *p == '&' )
+				return GetEntity( p, _value, length, encoding );
+			*_value = *p;
+			return p+1;
+		}
+		else if ( *length )
+		{
+			//strncpy( _value, p, *length );	// lots of compilers don't like this function (unsafe),
+												// and the null terminator isn't needed
+			for( int i=0; p[i] && i<*length; ++i ) {
+				_value[i] = p[i];
+			}
+			return p + (*length);
+		}
+		else
+		{
+			// Not valid text.
+			return 0;
+		}
+	}
+
+	// Puts a string to a stream, expanding entities as it goes.
+	// Note this should not contian the '<', '>', etc, or they will be transformed into entities!
+	static void PutString( const TIXML_STRING& str, TIXML_OSTREAM* out );
+
+	static void PutString( const TIXML_STRING& str, TIXML_STRING* out );
+
+	// Return true if the next characters in the stream are any of the endTag sequences.
+	// Ignore case only works for english, and should only be relied on when comparing
+	// to English words: StringEqual( p, "version", true ) is fine.
+	static bool StringEqual(	const char* p,
+								const char* endTag,
+								bool ignoreCase,
+								TiXmlEncoding encoding );
+
+	static const char* errorString[ TIXML_ERROR_STRING_COUNT ];
+
+	TiXmlCursor location;
+
+    /// Field containing a generic user pointer
+	void*			userData;
+	
+	// None of these methods are reliable for any language except English.
+	// Good for approximation, not great for accuracy.
+	static int IsAlpha( unsigned char anyByte, TiXmlEncoding encoding );
+	static int IsAlphaNum( unsigned char anyByte, TiXmlEncoding encoding );
+	inline static int ToLower( int v, TiXmlEncoding encoding )
+	{
+		if ( encoding == TIXML_ENCODING_UTF8 )
+		{
+			if ( v < 128 ) return tolower( v );
+			return v;
+		}
+		else
+		{
+			return tolower( v );
+		}
+	}
+	static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length );
+
+private:
+	TiXmlBase( const TiXmlBase& );				// not implemented.
+	void operator=( const TiXmlBase& base );	// not allowed.
+
+	struct Entity
+	{
+		const char*     str;
+		unsigned int	strLength;
+		char		    chr;
+	};
+	enum
+	{
+		NUM_ENTITY = 5,
+		MAX_ENTITY_LENGTH = 6
+
+	};
+	static Entity entity[ NUM_ENTITY ];
+	static bool condenseWhiteSpace;
+};
+
+
+/** The parent class for everything in the Document Object Model.
+	(Except for attributes).
+	Nodes have siblings, a parent, and children. A node can be
+	in a document, or stand on its own. The type of a TiXmlNode
+	can be queried, and it can be cast to its more defined type.
+*/
+class TiXmlNode : public TiXmlBase
+{
+	friend class TiXmlDocument;
+	friend class TiXmlElement;
+
+public:
+	#ifdef TIXML_USE_STL	
+
+	    /** An input stream operator, for every class. Tolerant of newlines and
+		    formatting, but doesn't expect them.
+	    */
+	    friend std::istream& operator >> (std::istream& in, TiXmlNode& base);
+
+	    /** An output stream operator, for every class. Note that this outputs
+		    without any newlines or formatting, as opposed to Print(), which
+		    includes tabs and new lines.
+
+		    The operator<< and operator>> are not completely symmetric. Writing
+		    a node to a stream is very well defined. You'll get a nice stream
+		    of output, without any extra whitespace or newlines.
+		    
+		    But reading is not as well defined. (As it always is.) If you create
+		    a TiXmlElement (for example) and read that from an input stream,
+		    the text needs to define an element or junk will result. This is
+		    true of all input streams, but it's worth keeping in mind.
+
+		    A TiXmlDocument will read nodes until it reads a root element, and
+			all the children of that root element.
+	    */	
+	    friend std::ostream& operator<< (std::ostream& out, const TiXmlNode& base);
+
+		/// Appends the XML node or attribute to a std::string.
+		friend std::string& operator<< (std::string& out, const TiXmlNode& base );
+
+	#else
+	    // Used internally, not part of the public API.
+	    friend TIXML_OSTREAM& operator<< (TIXML_OSTREAM& out, const TiXmlNode& base);
+	#endif
+
+	/** The types of XML nodes supported by TinyXml. (All the
+			unsupported types are picked up by UNKNOWN.)
+	*/
+	enum NodeType
+	{
+		DOCUMENT,
+		ELEMENT,
+		COMMENT,
+		UNKNOWN,
+		TEXT,
+		DECLARATION,
+		TYPECOUNT
+	};
+
+	virtual ~TiXmlNode();
+
+	/** The meaning of 'value' changes for the specific type of
+		TiXmlNode.
+		@verbatim
+		Document:	filename of the xml file
+		Element:	name of the element
+		Comment:	the comment text
+		Unknown:	the tag contents
+		Text:		the text string
+		@endverbatim
+
+		The subclasses will wrap this function.
+	*/
+	const char *Value() const { return value.c_str (); }
+
+    #ifdef TIXML_USE_STL
+	/** Return Value() as a std::string. If you only use STL,
+	    this is more efficient than calling Value().
+		Only available in STL mode.
+	*/
+	const std::string& ValueStr() const { return value; }
+	#endif
+
+	/** Changes the value of the node. Defined as:
+		@verbatim
+		Document:	filename of the xml file
+		Element:	name of the element
+		Comment:	the comment text
+		Unknown:	the tag contents
+		Text:		the text string
+		@endverbatim
+	*/
+	void SetValue(const char * _value) { value = _value;}
+
+    #ifdef TIXML_USE_STL
+	/// STL std::string form.
+	void SetValue( const std::string& _value )    
+	{	  
+		StringToBuffer buf( _value );
+		SetValue( buf.buffer ? buf.buffer : "" );    	
+	}	
+	#endif
+
+	/// Delete all the children of this node. Does not affect 'this'.
+	void Clear();
+
+	/// One step up the DOM.
+	TiXmlNode* Parent()							{ return parent; }
+	const TiXmlNode* Parent() const				{ return parent; }
+
+	const TiXmlNode* FirstChild()	const	{ return firstChild; }		///< The first child of this node. Will be null if there are no children.
+	TiXmlNode* FirstChild()					{ return firstChild; }
+	const TiXmlNode* FirstChild( const char * value ) const;			///< The first child of this node with the matching 'value'. Will be null if none found.
+	TiXmlNode* FirstChild( const char * value );						///< The first child of this node with the matching 'value'. Will be null if none found.
+
+	const TiXmlNode* LastChild() const	{ return lastChild; }		/// The last child of this node. Will be null if there are no children.
+	TiXmlNode* LastChild()	{ return lastChild; }
+	const TiXmlNode* LastChild( const char * value ) const;			/// The last child of this node matching 'value'. Will be null if there are no children.
+	TiXmlNode* LastChild( const char * value );	
+
+    #ifdef TIXML_USE_STL
+	const TiXmlNode* FirstChild( const std::string& _value ) const	{	return FirstChild (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* FirstChild( const std::string& _value )				{	return FirstChild (_value.c_str ());	}	///< STL std::string form.
+	const TiXmlNode* LastChild( const std::string& _value ) const	{	return LastChild (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* LastChild( const std::string& _value )				{	return LastChild (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/** An alternate way to walk the children of a node.
+		One way to iterate over nodes is:
+		@verbatim
+			for( child = parent->FirstChild(); child; child = child->NextSibling() )
+		@endverbatim
+
+		IterateChildren does the same thing with the syntax:
+		@verbatim
+			child = 0;
+			while( child = parent->IterateChildren( child ) )
+		@endverbatim
+
+		IterateChildren takes the previous child as input and finds
+		the next one. If the previous child is null, it returns the
+		first. IterateChildren will return null when done.
+	*/
+	const TiXmlNode* IterateChildren( const TiXmlNode* previous ) const;
+	TiXmlNode* IterateChildren( TiXmlNode* previous );
+
+	/// This flavor of IterateChildren searches for children with a particular 'value'
+	const TiXmlNode* IterateChildren( const char * value, const TiXmlNode* previous ) const;
+	TiXmlNode* IterateChildren( const char * value, TiXmlNode* previous );
+
+    #ifdef TIXML_USE_STL
+	const TiXmlNode* IterateChildren( const std::string& _value, const TiXmlNode* previous ) const	{	return IterateChildren (_value.c_str (), previous);	}	///< STL std::string form.
+	TiXmlNode* IterateChildren( const std::string& _value, TiXmlNode* previous ) {	return IterateChildren (_value.c_str (), previous);	}	///< STL std::string form.
+	#endif
+
+	/** Add a new node related to this. Adds a child past the LastChild.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* InsertEndChild( const TiXmlNode& addThis );
+
+
+	/** Add a new node related to this. Adds a child past the LastChild.
+
+		NOTE: the node to be added is passed by pointer, and will be
+		henceforth owned (and deleted) by tinyXml. This method is efficient
+		and avoids an extra copy, but should be used with care as it
+		uses a different memory model than the other insert functions.
+
+		@sa InsertEndChild
+	*/
+	TiXmlNode* LinkEndChild( TiXmlNode* addThis );
+
+	/** Add a new node related to this. Adds a child before the specified child.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* InsertBeforeChild( TiXmlNode* beforeThis, const TiXmlNode& addThis );
+
+	/** Add a new node related to this. Adds a child after the specified child.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* InsertAfterChild(  TiXmlNode* afterThis, const TiXmlNode& addThis );
+
+	/** Replace a child of this node.
+		Returns a pointer to the new object or NULL if an error occured.
+	*/
+	TiXmlNode* ReplaceChild( TiXmlNode* replaceThis, const TiXmlNode& withThis );
+
+	/// Delete a child of this node.
+	bool RemoveChild( TiXmlNode* removeThis );
+
+	/// Navigate to a sibling node.
+	const TiXmlNode* PreviousSibling() const			{ return prev; }
+	TiXmlNode* PreviousSibling()						{ return prev; }
+
+	/// Navigate to a sibling node.
+	const TiXmlNode* PreviousSibling( const char * ) const;
+	TiXmlNode* PreviousSibling( const char * );
+
+    #ifdef TIXML_USE_STL
+	const TiXmlNode* PreviousSibling( const std::string& _value ) const	{	return PreviousSibling (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* PreviousSibling( const std::string& _value ) 			{	return PreviousSibling (_value.c_str ());	}	///< STL std::string form.
+	const TiXmlNode* NextSibling( const std::string& _value) const		{	return NextSibling (_value.c_str ());	}	///< STL std::string form.
+	TiXmlNode* NextSibling( const std::string& _value) 					{	return NextSibling (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/// Navigate to a sibling node.
+	const TiXmlNode* NextSibling() const				{ return next; }
+	TiXmlNode* NextSibling()							{ return next; }
+
+	/// Navigate to a sibling node with the given 'value'.
+	const TiXmlNode* NextSibling( const char * ) const;
+	TiXmlNode* NextSibling( const char * );
+
+	/** Convenience function to get through elements.
+		Calls NextSibling and ToElement. Will skip all non-Element
+		nodes. Returns 0 if there is not another element.
+	*/
+	const TiXmlElement* NextSiblingElement() const;
+	TiXmlElement* NextSiblingElement();
+
+	/** Convenience function to get through elements.
+		Calls NextSibling and ToElement. Will skip all non-Element
+		nodes. Returns 0 if there is not another element.
+	*/
+	const TiXmlElement* NextSiblingElement( const char * ) const;
+	TiXmlElement* NextSiblingElement( const char * );
+
+    #ifdef TIXML_USE_STL
+	const TiXmlElement* NextSiblingElement( const std::string& _value) const	{	return NextSiblingElement (_value.c_str ());	}	///< STL std::string form.
+	TiXmlElement* NextSiblingElement( const std::string& _value)				{	return NextSiblingElement (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/// Convenience function to get through elements.
+	const TiXmlElement* FirstChildElement()	const;
+	TiXmlElement* FirstChildElement();
+
+	/// Convenience function to get through elements.
+	const TiXmlElement* FirstChildElement( const char * value ) const;
+	TiXmlElement* FirstChildElement( const char * value );
+
+    #ifdef TIXML_USE_STL
+	const TiXmlElement* FirstChildElement( const std::string& _value ) const	{	return FirstChildElement (_value.c_str ());	}	///< STL std::string form.
+	TiXmlElement* FirstChildElement( const std::string& _value )				{	return FirstChildElement (_value.c_str ());	}	///< STL std::string form.
+	#endif
+
+	/** Query the type (as an enumerated value, above) of this node.
+		The possible types are: DOCUMENT, ELEMENT, COMMENT,
+								UNKNOWN, TEXT, and DECLARATION.
+	*/
+	int Type() const	{ return type; }
+
+	/** Return a pointer to the Document this node lives in.
+		Returns null if not in a document.
+	*/
+	const TiXmlDocument* GetDocument() const;
+	TiXmlDocument* GetDocument();
+
+	/// Returns true if this node has no children.
+	bool NoChildren() const						{ return !firstChild; }
+
+	const TiXmlDocument* ToDocument()	const		{ return ( this && type == DOCUMENT ) ? (const TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	const TiXmlElement*  ToElement() const			{ return ( this && type == ELEMENT  ) ? (const TiXmlElement*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	const TiXmlComment*  ToComment() const			{ return ( this && type == COMMENT  ) ? (const TiXmlComment*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	const TiXmlUnknown*  ToUnknown() const			{ return ( this && type == UNKNOWN  ) ? (const TiXmlUnknown*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	const TiXmlText*	   ToText()    const		{ return ( this && type == TEXT     ) ? (const TiXmlText*)     this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	const TiXmlDeclaration* ToDeclaration() const	{ return ( this && type == DECLARATION ) ? (const TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	TiXmlDocument* ToDocument()			{ return ( this && type == DOCUMENT ) ? (TiXmlDocument*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	TiXmlElement*  ToElement()			{ return ( this && type == ELEMENT  ) ? (TiXmlElement*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	TiXmlComment*  ToComment()			{ return ( this && type == COMMENT  ) ? (TiXmlComment*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	TiXmlUnknown*  ToUnknown()			{ return ( this && type == UNKNOWN  ) ? (TiXmlUnknown*)  this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	TiXmlText*	   ToText()   			{ return ( this && type == TEXT     ) ? (TiXmlText*)     this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+	TiXmlDeclaration* ToDeclaration()	{ return ( this && type == DECLARATION ) ? (TiXmlDeclaration*) this : 0; } ///< Cast to a more defined type. Will return null not of the requested type.
+
+	/** Create an exact duplicate of this node and return it. The memory must be deleted
+		by the caller. 
+	*/
+	virtual TiXmlNode* Clone() const = 0;
+
+protected:
+	TiXmlNode( NodeType _type );
+
+	// Copy to the allocated object. Shared functionality between Clone, Copy constructor,
+	// and the assignment operator.
+	void CopyTo( TiXmlNode* target ) const;
+
+	#ifdef TIXML_USE_STL
+	    // The real work of the input operator.
+	    virtual void StreamIn( TIXML_ISTREAM* in, TIXML_STRING* tag ) = 0;
+	#endif
+
+	// Figure out what is at *p, and parse it. Returns null if it is not an xml node.
+	TiXmlNode* Identify( const char* start, TiXmlEncoding encoding );
+
+	TiXmlNode*		parent;
+	NodeType		type;
+
+	TiXmlNode*		firstChild;
+	TiXmlNode*		lastChild;
+
+	TIXML_STRING	value;
+
+	TiXmlNode*		prev;
+	TiXmlNode*		next;
+
+private:
+	TiXmlNode( const TiXmlNode& );				// not implemented.
+	void operator=( const TiXmlNode& base );	// not allowed.
+};
+
+
+/** An attribute is a name-value pair. Elements have an arbitrary
+	number of attributes, each with a unique name.
+
+	@note The attributes are not TiXmlNodes, since they are not
+		  part of the tinyXML document object model. There are other
+		  suggested ways to look at this problem.
+*/
+class TiXmlAttribute : public TiXmlBase
+{
+	friend class TiXmlAttributeSet;
+
+public:
+	/// Construct an empty attribute.
+	TiXmlAttribute() : TiXmlBase()
+	{
+		document = 0;
+		prev = next = 0;
+	}
+
+	#ifdef TIXML_USE_STL
+	/// std::string constructor.
+	TiXmlAttribute( const std::string& _name, const std::string& _value )
+	{
+		name = _name;
+		value = _value;
+		document = 0;
+		prev = next = 0;
+	}
+	#endif
+
+	/// Construct an attribute with a name and value.
+	TiXmlAttribute( const char * _name, const char * _value )
+	{
+		name = _name;
+		value = _value;
+		document = 0;
+		prev = next = 0;
+	}
+
+	const char*		Name()  const		{ return name.c_str (); }		///< Return the name of this attribute.
+	const char*		Value() const		{ return value.c_str (); }		///< Return the value of this attribute.
+	int				IntValue() const;									///< Return the value of this attribute, converted to an integer.
+	double			DoubleValue() const;								///< Return the value of this attribute, converted to a double.
+
+	/** QueryIntValue examines the value string. It is an alternative to the
+		IntValue() method with richer error checking.
+		If the value is an integer, it is stored in 'value' and 
+		the call returns TIXML_SUCCESS. If it is not
+		an integer, it returns TIXML_WRONG_TYPE.
+
+		A specialized but useful call. Note that for success it returns 0,
+		which is the opposite of almost all other TinyXml calls.
+	*/
+	int QueryIntValue( int* _value ) const;
+	/// QueryDoubleValue examines the value string. See QueryIntValue().
+	int QueryDoubleValue( double* _value ) const;
+
+	void SetName( const char* _name )	{ name = _name; }				///< Set the name of this attribute.
+	void SetValue( const char* _value )	{ value = _value; }				///< Set the value.
+
+	void SetIntValue( int _value );										///< Set the value from an integer.
+	void SetDoubleValue( double _value );								///< Set the value from a double.
+
+    #ifdef TIXML_USE_STL
+	/// STL std::string form.
+	void SetName( const std::string& _name )	
+	{	
+		StringToBuffer buf( _name );
+		SetName ( buf.buffer ? buf.buffer : "error" );	
+	}
+	/// STL std::string form.	
+	void SetValue( const std::string& _value )	
+	{	
+		StringToBuffer buf( _value );
+		SetValue( buf.buffer ? buf.buffer : "error" );	
+	}
+	#endif
+
+	/// Get the next sibling attribute in the DOM. Returns null at end.
+	const TiXmlAttribute* Next() const;
+	TiXmlAttribute* Next();
+	/// Get the previous sibling attribute in the DOM. Returns null at beginning.
+	const TiXmlAttribute* Previous() const;
+	TiXmlAttribute* Previous();
+
+	bool operator==( const TiXmlAttribute& rhs ) const { return rhs.name == name; }
+	bool operator<( const TiXmlAttribute& rhs )	 const { return name < rhs.name; }
+	bool operator>( const TiXmlAttribute& rhs )  const { return name > rhs.name; }
+
+	/*	Attribute parsing starts: first letter of the name
+						 returns: the next char after the value end quote
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+	// Prints this Attribute to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	virtual void StreamOut( TIXML_OSTREAM * out ) const;
+	// [internal use]
+	// Set the document pointer so the attribute can report errors.
+	void SetDocument( TiXmlDocument* doc )	{ document = doc; }
+
+private:
+	TiXmlAttribute( const TiXmlAttribute& );				// not implemented.
+	void operator=( const TiXmlAttribute& base );	// not allowed.
+
+	TiXmlDocument*	document;	// A pointer back to a document, for error reporting.
+	TIXML_STRING name;
+	TIXML_STRING value;
+	TiXmlAttribute*	prev;
+	TiXmlAttribute*	next;
+};
+
+
+/*	A class used to manage a group of attributes.
+	It is only used internally, both by the ELEMENT and the DECLARATION.
+	
+	The set can be changed transparent to the Element and Declaration
+	classes that use it, but NOT transparent to the Attribute
+	which has to implement a next() and previous() method. Which makes
+	it a bit problematic and prevents the use of STL.
+
+	This version is implemented with circular lists because:
+		- I like circular lists
+		- it demonstrates some independence from the (typical) doubly linked list.
+*/
+class TiXmlAttributeSet
+{
+public:
+	TiXmlAttributeSet();
+	~TiXmlAttributeSet();
+
+	void Add( TiXmlAttribute* attribute );
+	void Remove( TiXmlAttribute* attribute );
+
+	const TiXmlAttribute* First()	const	{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
+	TiXmlAttribute* First()					{ return ( sentinel.next == &sentinel ) ? 0 : sentinel.next; }
+	const TiXmlAttribute* Last() const		{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
+	TiXmlAttribute* Last()					{ return ( sentinel.prev == &sentinel ) ? 0 : sentinel.prev; }
+
+	const TiXmlAttribute*	Find( const char * name ) const;
+	TiXmlAttribute*	Find( const char * name );
+
+private:
+	//*ME:	Because of hidden/disabled copy-construktor in TiXmlAttribute (sentinel-element),
+	//*ME:	this class must be also use a hidden/disabled copy-constructor !!!
+	TiXmlAttributeSet( const TiXmlAttributeSet& );	// not allowed
+	void operator=( const TiXmlAttributeSet& );	// not allowed (as TiXmlAttribute)
+
+	TiXmlAttribute sentinel;
+};
+
+
+/** The element is a container class. It has a value, the element name,
+	and can contain other elements, text, comments, and unknowns.
+	Elements also contain an arbitrary number of attributes.
+*/
+class TiXmlElement : public TiXmlNode
+{
+public:
+	/// Construct an element.
+	TiXmlElement (const char * in_value);
+
+	#ifdef TIXML_USE_STL
+	/// std::string constructor.
+	TiXmlElement( const std::string& _value );
+	#endif
+
+	TiXmlElement( const TiXmlElement& );
+
+	void operator=( const TiXmlElement& base );
+
+	virtual ~TiXmlElement();
+
+	/** Given an attribute name, Attribute() returns the value
+		for the attribute of that name, or null if none exists.
+	*/
+	const char* Attribute( const char* name ) const;
+
+	/** Given an attribute name, Attribute() returns the value
+		for the attribute of that name, or null if none exists.
+		If the attribute exists and can be converted to an integer,
+		the integer value will be put in the return 'i', if 'i'
+		is non-null.
+	*/
+	const char* Attribute( const char* name, int* i ) const;
+
+	/** Given an attribute name, Attribute() returns the value
+		for the attribute of that name, or null if none exists.
+		If the attribute exists and can be converted to an double,
+		the double value will be put in the return 'd', if 'd'
+		is non-null.
+	*/
+	const char* Attribute( const char* name, double* d ) const;
+
+	/** QueryIntAttribute examines the attribute - it is an alternative to the
+		Attribute() method with richer error checking.
+		If the attribute is an integer, it is stored in 'value' and 
+		the call returns TIXML_SUCCESS. If it is not
+		an integer, it returns TIXML_WRONG_TYPE. If the attribute
+		does not exist, then TIXML_NO_ATTRIBUTE is returned.
+	*/	
+	int QueryIntAttribute( const char* name, int* _value ) const;
+	/// QueryDoubleAttribute examines the attribute - see QueryIntAttribute().
+	int QueryDoubleAttribute( const char* name, double* _value ) const;
+	/// QueryFloatAttribute examines the attribute - see QueryIntAttribute().
+	int QueryFloatAttribute( const char* name, float* _value ) const {
+		double d;
+		int result = QueryDoubleAttribute( name, &d );
+		if ( result == TIXML_SUCCESS ) {
+			*_value = (float)d;
+		}
+		return result;
+	}
+
+	/** Sets an attribute of name to a given value. The attribute
+		will be created if it does not exist, or changed if it does.
+	*/
+	void SetAttribute( const char* name, const char * _value );
+
+    #ifdef TIXML_USE_STL
+	const char* Attribute( const std::string& name ) const				{ return Attribute( name.c_str() ); }
+	const char* Attribute( const std::string& name, int* i ) const		{ return Attribute( name.c_str(), i ); }
+	const char* Attribute( const std::string& name, double* d ) const	{ return Attribute( name.c_str(), d ); }
+	int QueryIntAttribute( const std::string& name, int* _value ) const	{ return QueryIntAttribute( name.c_str(), _value ); }
+	int QueryDoubleAttribute( const std::string& name, double* _value ) const { return QueryDoubleAttribute( name.c_str(), _value ); }
+
+	/// STL std::string form.
+	void SetAttribute( const std::string& name, const std::string& _value )	
+	{	
+		StringToBuffer n( name );
+		StringToBuffer v( _value );
+		if ( n.buffer && v.buffer )
+			SetAttribute (n.buffer, v.buffer );	
+	}	
+	///< STL std::string form.
+	void SetAttribute( const std::string& name, int _value )	
+	{	
+		StringToBuffer n( name );
+		if ( n.buffer )
+			SetAttribute (n.buffer, _value);	
+	}	
+	#endif
+
+	/** Sets an attribute of name to a given value. The attribute
+		will be created if it does not exist, or changed if it does.
+	*/
+	void SetAttribute( const char * name, int value );
+
+	/** Sets an attribute of name to a given value. The attribute
+		will be created if it does not exist, or changed if it does.
+	*/
+	void SetDoubleAttribute( const char * name, double value );
+
+	/** Deletes an attribute with the given name.
+	*/
+	void RemoveAttribute( const char * name );
+    #ifdef TIXML_USE_STL
+	void RemoveAttribute( const std::string& name )	{	RemoveAttribute (name.c_str ());	}	///< STL std::string form.
+	#endif
+
+	const TiXmlAttribute* FirstAttribute() const	{ return attributeSet.First(); }		///< Access the first attribute in this element.
+	TiXmlAttribute* FirstAttribute() 				{ return attributeSet.First(); }
+	const TiXmlAttribute* LastAttribute()	const 	{ return attributeSet.Last(); }		///< Access the last attribute in this element.
+	TiXmlAttribute* LastAttribute()					{ return attributeSet.Last(); }
+
+	/** Convenience function for easy access to the text inside an element. Although easy
+		and concise, GetText() is limited compared to getting the TiXmlText child
+		and accessing it directly.
+	
+		If the first child of 'this' is a TiXmlText, the GetText()
+		returns the character string of the Text node, else null is returned.
+
+		This is a convenient method for getting the text of simple contained text:
+		@verbatim
+		<foo>This is text</foo>
+		const char* str = fooElement->GetText();
+		@endverbatim
+
+		'str' will be a pointer to "This is text". 
+		
+		Note that this function can be misleading. If the element foo was created from
+		this XML:
+		@verbatim
+		<foo><b>This is text</b></foo> 
+		@endverbatim
+
+		then the value of str would be null. The first child node isn't a text node, it is
+		another element. From this XML:
+		@verbatim
+		<foo>This is <b>text</b></foo> 
+		@endverbatim
+		GetText() will return "This is ".
+
+		WARNING: GetText() accesses a child node - don't become confused with the 
+				 similarly named TiXmlHandle::Text() and TiXmlNode::ToText() which are 
+				 safe type casts on the referenced node.
+	*/
+	const char* GetText() const;
+
+	/// Creates a new Element and returns it - the returned element is a copy.
+	virtual TiXmlNode* Clone() const;
+	// Print the Element to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	/*	Attribtue parsing starts: next char past '<'
+						 returns: next char past '>'
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+protected:
+
+	void CopyTo( TiXmlElement* target ) const;
+	void ClearThis();	// like clear, but initializes 'this' object as well
+
+	// Used to be public [internal use]
+	#ifdef TIXML_USE_STL
+	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+	#endif
+	virtual void StreamOut( TIXML_OSTREAM * out ) const;
+
+	/*	[internal use]
+		Reads the "value" of the element -- another element, or text.
+		This should terminate with the current end tag.
+	*/
+	const char* ReadValue( const char* in, TiXmlParsingData* prevData, TiXmlEncoding encoding );
+
+private:
+
+	TiXmlAttributeSet attributeSet;
+};
+
+
+/**	An XML comment.
+*/
+class TiXmlComment : public TiXmlNode
+{
+public:
+	/// Constructs an empty comment.
+	TiXmlComment() : TiXmlNode( TiXmlNode::COMMENT ) {}
+	TiXmlComment( const TiXmlComment& );
+	void operator=( const TiXmlComment& base );
+
+	virtual ~TiXmlComment()	{}
+
+	/// Returns a copy of this Comment.
+	virtual TiXmlNode* Clone() const;
+	/// Write this Comment to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	/*	Attribtue parsing starts: at the ! of the !--
+						 returns: next char past '>'
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+protected:
+	void CopyTo( TiXmlComment* target ) const;
+
+	// used to be public
+	#ifdef TIXML_USE_STL
+	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+	#endif
+	virtual void StreamOut( TIXML_OSTREAM * out ) const;
+
+private:
+
+};
+
+
+/** XML text. A text node can have 2 ways to output the next. "normal" output 
+	and CDATA. It will default to the mode it was parsed from the XML file and
+	you generally want to leave it alone, but you can change the output mode with 
+	SetCDATA() and query it with CDATA().
+*/
+class TiXmlText : public TiXmlNode
+{
+	friend class TiXmlElement;
+public:
+	/** Constructor for text element. By default, it is treated as 
+		normal, encoded text. If you want it be output as a CDATA text
+		element, set the parameter _cdata to 'true'
+	*/
+	TiXmlText (const char * initValue ) : TiXmlNode (TiXmlNode::TEXT)
+	{
+		SetValue( initValue );
+		cdata = false;
+	}
+	virtual ~TiXmlText() {}
+
+	#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlText( const std::string& initValue ) : TiXmlNode (TiXmlNode::TEXT)
+	{
+		SetValue( initValue );
+		cdata = false;
+	}
+	#endif
+
+	TiXmlText( const TiXmlText& copy ) : TiXmlNode( TiXmlNode::TEXT )	{ copy.CopyTo( this ); }
+	void operator=( const TiXmlText& base )							 	{ base.CopyTo( this ); }
+
+	/// Write this text object to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	/// Queries whether this represents text using a CDATA section.
+	bool CDATA()					{ return cdata; }
+	/// Turns on or off a CDATA representation of text.
+	void SetCDATA( bool _cdata )	{ cdata = _cdata; }
+
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+protected :
+	///  [internal use] Creates a new Element and returns it.
+	virtual TiXmlNode* Clone() const;
+	void CopyTo( TiXmlText* target ) const;
+
+	virtual void StreamOut ( TIXML_OSTREAM * out ) const;
+	bool Blank() const;	// returns true if all white space and new lines
+	// [internal use]
+	#ifdef TIXML_USE_STL
+	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+	#endif
+
+private:
+	bool cdata;			// true if this should be input and output as a CDATA style text element
+};
+
+
+/** In correct XML the declaration is the first entry in the file.
+	@verbatim
+		<?xml version="1.0" standalone="yes"?>
+	@endverbatim
+
+	TinyXml will happily read or write files without a declaration,
+	however. There are 3 possible attributes to the declaration:
+	version, encoding, and standalone.
+
+	Note: In this version of the code, the attributes are
+	handled as special cases, not generic attributes, simply
+	because there can only be at most 3 and they are always the same.
+*/
+class TiXmlDeclaration : public TiXmlNode
+{
+public:
+	/// Construct an empty declaration.
+	TiXmlDeclaration()   : TiXmlNode( TiXmlNode::DECLARATION ) {}
+
+#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlDeclaration(	const std::string& _version,
+						const std::string& _encoding,
+						const std::string& _standalone );
+#endif
+
+	/// Construct.
+	TiXmlDeclaration(	const char* _version,
+						const char* _encoding,
+						const char* _standalone );
+
+	TiXmlDeclaration( const TiXmlDeclaration& copy );
+	void operator=( const TiXmlDeclaration& copy );
+
+	virtual ~TiXmlDeclaration()	{}
+
+	/// Version. Will return an empty string if none was found.
+	const char *Version() const			{ return version.c_str (); }
+	/// Encoding. Will return an empty string if none was found.
+	const char *Encoding() const		{ return encoding.c_str (); }
+	/// Is this a standalone document?
+	const char *Standalone() const		{ return standalone.c_str (); }
+
+	/// Creates a copy of this Declaration and returns it.
+	virtual TiXmlNode* Clone() const;
+	/// Print this declaration to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+protected:
+	void CopyTo( TiXmlDeclaration* target ) const;
+	// used to be public
+	#ifdef TIXML_USE_STL
+	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+	#endif
+	virtual void StreamOut ( TIXML_OSTREAM * out) const;
+
+private:
+
+	TIXML_STRING version;
+	TIXML_STRING encoding;
+	TIXML_STRING standalone;
+};
+
+
+/** Any tag that tinyXml doesn't recognize is saved as an
+	unknown. It is a tag of text, but should not be modified.
+	It will be written back to the XML, unchanged, when the file
+	is saved.
+
+	DTD tags get thrown into TiXmlUnknowns.
+*/
+class TiXmlUnknown : public TiXmlNode
+{
+public:
+	TiXmlUnknown() : TiXmlNode( TiXmlNode::UNKNOWN )	{}
+	virtual ~TiXmlUnknown() {}
+
+	TiXmlUnknown( const TiXmlUnknown& copy ) : TiXmlNode( TiXmlNode::UNKNOWN )		{ copy.CopyTo( this ); }
+	void operator=( const TiXmlUnknown& copy )										{ copy.CopyTo( this ); }
+
+	/// Creates a copy of this Unknown and returns it.
+	virtual TiXmlNode* Clone() const;
+	/// Print this Unknown to a FILE stream.
+	virtual void Print( FILE* cfile, int depth ) const;
+
+	virtual const char* Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding );
+
+protected:
+	void CopyTo( TiXmlUnknown* target ) const;
+
+	#ifdef TIXML_USE_STL
+	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+	#endif
+	virtual void StreamOut ( TIXML_OSTREAM * out ) const;
+
+private:
+
+};
+
+
+/** Always the top level node. A document binds together all the
+	XML pieces. It can be saved, loaded, and printed to the screen.
+	The 'value' of a document node is the xml file name.
+*/
+class TiXmlDocument : public TiXmlNode
+{
+public:
+	/// Create an empty document, that has no name.
+	TiXmlDocument();
+	/// Create a document with a name. The name of the document is also the filename of the xml.
+	TiXmlDocument( const char * documentName );
+
+	#ifdef TIXML_USE_STL
+	/// Constructor.
+	TiXmlDocument( const std::string& documentName );
+	#endif
+
+	TiXmlDocument( const TiXmlDocument& copy );
+	void operator=( const TiXmlDocument& copy );
+
+	virtual ~TiXmlDocument() {}
+
+	/** Load a file using the current document value.
+		Returns true if successful. Will delete any existing
+		document data before loading.
+	*/
+	bool LoadFile( TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+	/// Save a file using the current document value. Returns true if successful.
+	bool SaveFile() const;
+	/// Load a file using the given filename. Returns true if successful.
+	bool LoadFile( const char * filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+	/// Save a file using the given filename. Returns true if successful.
+	bool SaveFile( const char * filename ) const;
+
+	#ifdef TIXML_USE_STL
+	bool LoadFile( const std::string& filename, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING )			///< STL std::string version.
+	{
+		StringToBuffer f( filename );
+		return ( f.buffer && LoadFile( f.buffer, encoding ));
+	}
+	bool SaveFile( const std::string& filename ) const		///< STL std::string version.
+	{
+		StringToBuffer f( filename );
+		return ( f.buffer && SaveFile( f.buffer ));
+	}
+	#endif
+
+	/** Parse the given null terminated block of xml data. Passing in an encoding to this
+		method (either TIXML_ENCODING_LEGACY or TIXML_ENCODING_UTF8 will force TinyXml
+		to use that encoding, regardless of what TinyXml might otherwise try to detect.
+	*/
+	virtual const char* Parse( const char* p, TiXmlParsingData* data = 0, TiXmlEncoding encoding = TIXML_DEFAULT_ENCODING );
+
+	/** Get the root element -- the only top level element -- of the document.
+		In well formed XML, there should only be one. TinyXml is tolerant of
+		multiple elements at the document level.
+	*/
+	const TiXmlElement* RootElement() const		{ return FirstChildElement(); }
+	TiXmlElement* RootElement()					{ return FirstChildElement(); }
+
+	/** If an error occurs, Error will be set to true. Also,
+		- The ErrorId() will contain the integer identifier of the error (not generally useful)
+		- The ErrorDesc() method will return the name of the error. (very useful)
+		- The ErrorRow() and ErrorCol() will return the location of the error (if known)
+	*/	
+	bool Error() const						{ return error; }
+
+	/// Contains a textual (english) description of the error if one occurs.
+	const char * ErrorDesc() const	{ return errorDesc.c_str (); }
+
+	/** Generally, you probably want the error string ( ErrorDesc() ). But if you
+		prefer the ErrorId, this function will fetch it.
+	*/
+	int ErrorId()	const				{ return errorId; }
+
+	/** Returns the location (if known) of the error. The first column is column 1, 
+		and the first row is row 1. A value of 0 means the row and column wasn't applicable
+		(memory errors, for example, have no row/column) or the parser lost the error. (An
+		error in the error reporting, in that case.)
+
+		@sa SetTabSize, Row, Column
+	*/
+	int ErrorRow()	{ return errorLocation.row+1; }
+	int ErrorCol()	{ return errorLocation.col+1; }	///< The column where the error occured. See ErrorRow()
+
+	/** SetTabSize() allows the error reporting functions (ErrorRow() and ErrorCol())
+		to report the correct values for row and column. It does not change the output
+		or input in any way.
+		
+		By calling this method, with a tab size
+		greater than 0, the row and column of each node and attribute is stored
+		when the file is loaded. Very useful for tracking the DOM back in to
+		the source file.
+
+		The tab size is required for calculating the location of nodes. If not
+		set, the default of 4 is used. The tabsize is set per document. Setting
+		the tabsize to 0 disables row/column tracking.
+
+		Note that row and column tracking is not supported when using operator>>.
+
+		The tab size needs to be enabled before the parse or load. Correct usage:
+		@verbatim
+		TiXmlDocument doc;
+		doc.SetTabSize( 8 );
+		doc.Load( "myfile.xml" );
+		@endverbatim
+
+		@sa Row, Column
+	*/
+	void SetTabSize( int _tabsize )		{ tabsize = _tabsize; }
+
+	int TabSize() const	{ return tabsize; }
+
+	/** If you have handled the error, it can be reset with this call. The error
+		state is automatically cleared if you Parse a new XML block.
+	*/
+	void ClearError()						{	error = false; 
+												errorId = 0; 
+												errorDesc = ""; 
+												errorLocation.row = errorLocation.col = 0; 
+												//errorLocation.last = 0; 
+											}
+
+	/** Dump the document to standard out. */
+	void Print() const						{ Print( stdout, 0 ); }
+
+	/// Print this Document to a FILE stream.
+	virtual void Print( FILE* cfile, int depth = 0 ) const;
+	// [internal use]
+	void SetError( int err, const char* errorLocation, TiXmlParsingData* prevData, TiXmlEncoding encoding );
+
+protected :
+	virtual void StreamOut ( TIXML_OSTREAM * out) const;
+	// [internal use]
+	virtual TiXmlNode* Clone() const;
+	#ifdef TIXML_USE_STL
+	    virtual void StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag );
+	#endif
+
+private:
+	void CopyTo( TiXmlDocument* target ) const;
+
+	bool error;
+	int  errorId;
+	TIXML_STRING errorDesc;
+	int tabsize;
+	TiXmlCursor errorLocation;
+	bool useMicrosoftBOM;		// the UTF-8 BOM were found when read. Note this, and try to write.
+};
+
+
+/**
+	A TiXmlHandle is a class that wraps a node pointer with null checks; this is
+	an incredibly useful thing. Note that TiXmlHandle is not part of the TinyXml
+	DOM structure. It is a separate utility class.
+
+	Take an example:
+	@verbatim
+	<Document>
+		<Element attributeA = "valueA">
+			<Child attributeB = "value1" />
+			<Child attributeB = "value2" />
+		</Element>
+	<Document>
+	@endverbatim
+
+	Assuming you want the value of "attributeB" in the 2nd "Child" element, it's very 
+	easy to write a *lot* of code that looks like:
+
+	@verbatim
+	TiXmlElement* root = document.FirstChildElement( "Document" );
+	if ( root )
+	{
+		TiXmlElement* element = root->FirstChildElement( "Element" );
+		if ( element )
+		{
+			TiXmlElement* child = element->FirstChildElement( "Child" );
+			if ( child )
+			{
+				TiXmlElement* child2 = child->NextSiblingElement( "Child" );
+				if ( child2 )
+				{
+					// Finally do something useful.
+	@endverbatim
+
+	And that doesn't even cover "else" cases. TiXmlHandle addresses the verbosity
+	of such code. A TiXmlHandle checks for null	pointers so it is perfectly safe 
+	and correct to use:
+
+	@verbatim
+	TiXmlHandle docHandle( &document );
+	TiXmlElement* child2 = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", 1 ).Element();
+	if ( child2 )
+	{
+		// do something useful
+	@endverbatim
+
+	Which is MUCH more concise and useful.
+
+	It is also safe to copy handles - internally they are nothing more than node pointers.
+	@verbatim
+	TiXmlHandle handleCopy = handle;
+	@endverbatim
+
+	What they should not be used for is iteration:
+
+	@verbatim
+	int i=0; 
+	while ( true )
+	{
+		TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).Child( "Child", i ).Element();
+		if ( !child )
+			break;
+		// do something
+		++i;
+	}
+	@endverbatim
+
+	It seems reasonable, but it is in fact two embedded while loops. The Child method is 
+	a linear walk to find the element, so this code would iterate much more than it needs 
+	to. Instead, prefer:
+
+	@verbatim
+	TiXmlElement* child = docHandle.FirstChild( "Document" ).FirstChild( "Element" ).FirstChild( "Child" ).Element();
+
+	for( child; child; child=child->NextSiblingElement() )
+	{
+		// do something
+	}
+	@endverbatim
+*/
+class TiXmlHandle
+{
+public:
+	/// Create a handle from any node (at any depth of the tree.) This can be a null pointer.
+	TiXmlHandle( TiXmlNode* _node )					{ this->node = _node; }
+	/// Copy constructor
+	TiXmlHandle( const TiXmlHandle& ref )			{ this->node = ref.node; }
+	TiXmlHandle operator=( const TiXmlHandle& ref ) { this->node = ref.node; return *this; }
+
+	/// Return a handle to the first child node.
+	TiXmlHandle FirstChild() const;
+	/// Return a handle to the first child node with the given name.
+	TiXmlHandle FirstChild( const char * value ) const;
+	/// Return a handle to the first child element.
+	TiXmlHandle FirstChildElement() const;
+	/// Return a handle to the first child element with the given name.
+	TiXmlHandle FirstChildElement( const char * value ) const;
+
+	/** Return a handle to the "index" child with the given name. 
+		The first child is 0, the second 1, etc.
+	*/
+	TiXmlHandle Child( const char* value, int index ) const;
+	/** Return a handle to the "index" child. 
+		The first child is 0, the second 1, etc.
+	*/
+	TiXmlHandle Child( int index ) const;
+	/** Return a handle to the "index" child element with the given name. 
+		The first child element is 0, the second 1, etc. Note that only TiXmlElements
+		are indexed: other types are not counted.
+	*/
+	TiXmlHandle ChildElement( const char* value, int index ) const;
+	/** Return a handle to the "index" child element. 
+		The first child element is 0, the second 1, etc. Note that only TiXmlElements
+		are indexed: other types are not counted.
+	*/
+	TiXmlHandle ChildElement( int index ) const;
+
+	#ifdef TIXML_USE_STL
+	TiXmlHandle FirstChild( const std::string& _value ) const				{ return FirstChild( _value.c_str() ); }
+	TiXmlHandle FirstChildElement( const std::string& _value ) const		{ return FirstChildElement( _value.c_str() ); }
+
+	TiXmlHandle Child( const std::string& _value, int index ) const			{ return Child( _value.c_str(), index ); }
+	TiXmlHandle ChildElement( const std::string& _value, int index ) const	{ return ChildElement( _value.c_str(), index ); }
+	#endif
+
+	/// Return the handle as a TiXmlNode. This may return null.
+	TiXmlNode* Node() const			{ return node; } 
+	/// Return the handle as a TiXmlElement. This may return null.
+	TiXmlElement* Element() const	{ return ( ( node && node->ToElement() ) ? node->ToElement() : 0 ); }
+	/// Return the handle as a TiXmlText. This may return null.
+	TiXmlText* Text() const			{ return ( ( node && node->ToText() ) ? node->ToText() : 0 ); }
+	/// Return the handle as a TiXmlUnknown. This may return null;
+	TiXmlUnknown* Unknown() const			{ return ( ( node && node->ToUnknown() ) ? node->ToUnknown() : 0 ); }
+
+private:
+	TiXmlNode* node;
+};
+
+#ifdef _MSC_VER
+#pragma warning( pop )
+#endif
+
+#endif
+
Index: branches/network/src/lib/parser/tinyxml/tinyxmlerror.cc
===================================================================
--- branches/network/src/lib/parser/tinyxml/tinyxmlerror.cc	(revision 6636)
+++ branches/network/src/lib/parser/tinyxml/tinyxmlerror.cc	(revision 6636)
@@ -0,0 +1,52 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied 
+warranty. In no event will the authors be held liable for any 
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any 
+purpose, including commercial applications, and to alter it and 
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source
+distribution.
+*/
+
+#include "tinyxml.h"
+
+// The goal of the seperate error file is to make the first
+// step towards localization. tinyxml (currently) only supports
+// english error messages, but the could now be translated.
+//
+// It also cleans up the code a bit.
+//
+
+const char* TiXmlBase::errorString[ TIXML_ERROR_STRING_COUNT ] =
+{
+	"No error",
+	"Error",
+	"Failed to open file",
+	"Memory allocation failed.",
+	"Error parsing Element.",
+	"Failed to read Element name",
+	"Error reading Element value.",
+	"Error reading Attributes.",
+	"Error: empty tag.",
+	"Error reading end tag.",
+	"Error parsing Unknown.",
+	"Error parsing Comment.",
+	"Error parsing Declaration.",
+	"Error document empty.",
+	"Error null (0) or unexpected EOF found in input stream.",
+	"Error parsing CDATA.",
+};
Index: branches/network/src/lib/parser/tinyxml/tinyxmlparser.cc
===================================================================
--- branches/network/src/lib/parser/tinyxml/tinyxmlparser.cc	(revision 6636)
+++ branches/network/src/lib/parser/tinyxml/tinyxmlparser.cc	(revision 6636)
@@ -0,0 +1,1572 @@
+/*
+www.sourceforge.net/projects/tinyxml
+Original code (2.0 and earlier )copyright (c) 2000-2002 Lee Thomason (www.grinninglizard.com)
+
+This software is provided 'as-is', without any express or implied 
+warranty. In no event will the authors be held liable for any 
+damages arising from the use of this software.
+
+Permission is granted to anyone to use this software for any 
+purpose, including commercial applications, and to alter it and 
+redistribute it freely, subject to the following restrictions:
+
+1. The origin of this software must not be misrepresented; you must 
+not claim that you wrote the original software. If you use this
+software in a product, an acknowledgment in the product documentation
+would be appreciated but is not required.
+
+2. Altered source versions must be plainly marked as such, and 
+must not be misrepresented as being the original software.
+
+3. This notice may not be removed or altered from any source 
+distribution.
+*/
+
+#include "tinyxml.h"
+#include <ctype.h>
+#include <stddef.h>
+
+//#define DEBUG_PARSER
+
+// Note tha "PutString" hardcodes the same list. This
+// is less flexible than it appears. Changing the entries
+// or order will break putstring.	
+TiXmlBase::Entity TiXmlBase::entity[ NUM_ENTITY ] = 
+{
+	{ "&amp;",  5, '&' },
+	{ "&lt;",   4, '<' },
+	{ "&gt;",   4, '>' },
+	{ "&quot;", 6, '\"' },
+	{ "&apos;", 6, '\'' }
+};
+
+// Bunch of unicode info at:
+//		http://www.unicode.org/faq/utf_bom.html
+// Including the basic of this table, which determines the #bytes in the
+// sequence from the lead byte. 1 placed for invalid sequences --
+// although the result will be junk, pass it through as much as possible.
+// Beware of the non-characters in UTF-8:	
+//				ef bb bf (Microsoft "lead bytes")
+//				ef bf be
+//				ef bf bf 
+
+const unsigned char TIXML_UTF_LEAD_0 = 0xefU;
+const unsigned char TIXML_UTF_LEAD_1 = 0xbbU;
+const unsigned char TIXML_UTF_LEAD_2 = 0xbfU;
+
+const int TiXmlBase::utf8ByteTable[256] = 
+{
+	//	0	1	2	3	4	5	6	7	8	9	a	b	c	d	e	f
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x00
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x10
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x20
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x30
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x40
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x50
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x60
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x70	End of ASCII range
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x80 0x80 to 0xc1 invalid
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0x90 
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0xa0 
+		1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	// 0xb0 
+		1,	1,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	// 0xc0 0xc2 to 0xdf 2 byte
+		2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	2,	// 0xd0
+		3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	3,	// 0xe0 0xe0 to 0xef 3 byte
+		4,	4,	4,	4,	4,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1,	1	// 0xf0 0xf0 to 0xf4 4 byte, 0xf5 and higher invalid
+};
+
+
+void TiXmlBase::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length )
+{
+	const unsigned long BYTE_MASK = 0xBF;
+	const unsigned long BYTE_MARK = 0x80;
+	const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC };
+
+	if (input < 0x80) 
+		*length = 1;
+	else if ( input < 0x800 )
+		*length = 2;
+	else if ( input < 0x10000 )
+		*length = 3;
+	else if ( input < 0x200000 )
+		*length = 4;
+	else
+		{ *length = 0; return; }	// This code won't covert this correctly anyway.
+
+	output += *length;
+
+	// Scary scary fall throughs.
+	switch (*length) 
+	{
+		case 4:
+			--output; 
+			*output = (char)((input | BYTE_MARK) & BYTE_MASK); 
+			input >>= 6;
+		case 3:
+			--output; 
+			*output = (char)((input | BYTE_MARK) & BYTE_MASK); 
+			input >>= 6;
+		case 2:
+			--output; 
+			*output = (char)((input | BYTE_MARK) & BYTE_MASK); 
+			input >>= 6;
+		case 1:
+			--output; 
+			*output = (char)(input | FIRST_BYTE_MARK[*length]);
+	}
+}
+
+
+/*static*/ int TiXmlBase::IsAlpha( unsigned char anyByte, TiXmlEncoding /*encoding*/ )
+{
+	// This will only work for low-ascii, everything else is assumed to be a valid
+	// letter. I'm not sure this is the best approach, but it is quite tricky trying
+	// to figure out alhabetical vs. not across encoding. So take a very 
+	// conservative approach.
+
+//	if ( encoding == TIXML_ENCODING_UTF8 )
+//	{
+		if ( anyByte < 127 )
+			return isalpha( anyByte );
+		else
+			return 1;	// What else to do? The unicode set is huge...get the english ones right.
+//	}
+//	else
+//	{
+//		return isalpha( anyByte );
+//	}
+}
+
+
+/*static*/ int TiXmlBase::IsAlphaNum( unsigned char anyByte, TiXmlEncoding /*encoding*/ )
+{
+	// This will only work for low-ascii, everything else is assumed to be a valid
+	// letter. I'm not sure this is the best approach, but it is quite tricky trying
+	// to figure out alhabetical vs. not across encoding. So take a very 
+	// conservative approach.
+
+//	if ( encoding == TIXML_ENCODING_UTF8 )
+//	{
+		if ( anyByte < 127 )
+			return isalnum( anyByte );
+		else
+			return 1;	// What else to do? The unicode set is huge...get the english ones right.
+//	}
+//	else
+//	{
+//		return isalnum( anyByte );
+//	}
+}
+
+
+class TiXmlParsingData
+{
+	friend class TiXmlDocument;
+  public:
+	void Stamp( const char* now, TiXmlEncoding encoding );
+
+	const TiXmlCursor& Cursor()	{ return cursor; }
+
+  private:
+	// Only used by the document!
+	TiXmlParsingData( const char* start, int _tabsize, int row, int col )
+	{
+		assert( start );
+		stamp = start;
+		tabsize = _tabsize;
+		cursor.row = row;
+		cursor.col = col;
+	}
+
+	TiXmlCursor		cursor;
+	const char*		stamp;
+	int				tabsize;
+};
+
+
+void TiXmlParsingData::Stamp( const char* now, TiXmlEncoding encoding )
+{
+	assert( now );
+
+	// Do nothing if the tabsize is 0.
+	if ( tabsize < 1 )
+	{
+		return;
+	}
+
+	// Get the current row, column.
+	int row = cursor.row;
+	int col = cursor.col;
+	const char* p = stamp;
+	assert( p );
+
+	while ( p < now )
+	{
+		// Treat p as unsigned, so we have a happy compiler.
+		const unsigned char* pU = (const unsigned char*)p;
+
+		// Code contributed by Fletcher Dunn: (modified by lee)
+		switch (*pU) {
+			case 0:
+				// We *should* never get here, but in case we do, don't
+				// advance past the terminating null character, ever
+				return;
+
+			case '\r':
+				// bump down to the next line
+				++row;
+				col = 0;				
+				// Eat the character
+				++p;
+
+				// Check for \r\n sequence, and treat this as a single character
+				if (*p == '\n') {
+					++p;
+				}
+				break;
+
+			case '\n':
+				// bump down to the next line
+				++row;
+				col = 0;
+
+				// Eat the character
+				++p;
+
+				// Check for \n\r sequence, and treat this as a single
+				// character.  (Yes, this bizarre thing does occur still
+				// on some arcane platforms...)
+				if (*p == '\r') {
+					++p;
+				}
+				break;
+
+			case '\t':
+				// Eat the character
+				++p;
+
+				// Skip to next tab stop
+				col = (col / tabsize + 1) * tabsize;
+				break;
+
+			case TIXML_UTF_LEAD_0:
+				if ( encoding == TIXML_ENCODING_UTF8 )
+				{
+					if ( *(p+1) && *(p+2) )
+					{
+						// In these cases, don't advance the column. These are
+						// 0-width spaces.
+						if ( *(pU+1)==TIXML_UTF_LEAD_1 && *(pU+2)==TIXML_UTF_LEAD_2 )
+							p += 3;	
+						else if ( *(pU+1)==0xbfU && *(pU+2)==0xbeU )
+							p += 3;	
+						else if ( *(pU+1)==0xbfU && *(pU+2)==0xbfU )
+							p += 3;	
+						else
+							{ p +=3; ++col; }	// A normal character.
+					}
+				}
+				else
+				{
+					++p;
+					++col;
+				}
+				break;
+
+			default:
+				if ( encoding == TIXML_ENCODING_UTF8 )
+				{
+					// Eat the 1 to 4 byte utf8 character.
+					int step = TiXmlBase::utf8ByteTable[*((unsigned char*)p)];
+					if ( step == 0 )
+						step = 1;		// Error case from bad encoding, but handle gracefully.
+					p += step;
+
+					// Just advance one column, of course.
+					++col;
+				}
+				else
+				{
+					++p;
+					++col;
+				}
+				break;
+		}
+	}
+	cursor.row = row;
+	cursor.col = col;
+	assert( cursor.row >= -1 );
+	assert( cursor.col >= -1 );
+	stamp = p;
+	assert( stamp );
+}
+
+
+const char* TiXmlBase::SkipWhiteSpace( const char* p, TiXmlEncoding encoding )
+{
+	if ( !p || !*p )
+	{
+		return 0;
+	}
+	if ( encoding == TIXML_ENCODING_UTF8 )
+	{
+		while ( *p )
+		{
+			const unsigned char* pU = (const unsigned char*)p;
+			
+			// Skip the stupid Microsoft UTF-8 Byte order marks
+			if (	*(pU+0)==TIXML_UTF_LEAD_0
+				 && *(pU+1)==TIXML_UTF_LEAD_1 
+				 && *(pU+2)==TIXML_UTF_LEAD_2 )
+			{
+				p += 3;
+				continue;
+			}
+			else if(*(pU+0)==TIXML_UTF_LEAD_0
+				 && *(pU+1)==0xbfU
+				 && *(pU+2)==0xbeU )
+			{
+				p += 3;
+				continue;
+			}
+			else if(*(pU+0)==TIXML_UTF_LEAD_0
+				 && *(pU+1)==0xbfU
+				 && *(pU+2)==0xbfU )
+			{
+				p += 3;
+				continue;
+			}
+
+			if ( IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' )		// Still using old rules for white space.
+				++p;
+			else
+				break;
+		}
+	}
+	else
+	{
+		while ( *p && IsWhiteSpace( *p ) || *p == '\n' || *p =='\r' )
+			++p;
+	}
+
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+/*static*/ bool TiXmlBase::StreamWhiteSpace( TIXML_ISTREAM * in, TIXML_STRING * tag )
+{
+	for( ;; )
+	{
+		if ( !in->good() ) return false;
+
+		int c = in->peek();
+		// At this scope, we can't get to a document. So fail silently.
+		if ( !IsWhiteSpace( c ) || c <= 0 )
+			return true;
+
+		*tag += (char) in->get();
+	}
+}
+
+/*static*/ bool TiXmlBase::StreamTo( TIXML_ISTREAM * in, int character, TIXML_STRING * tag )
+{
+	//assert( character > 0 && character < 128 );	// else it won't work in utf-8
+	while ( in->good() )
+	{
+		int c = in->peek();
+		if ( c == character )
+			return true;
+		if ( c <= 0 )		// Silent failure: can't get document at this scope
+			return false;
+
+		in->get();
+		*tag += (char) c;
+	}
+	return false;
+}
+#endif
+
+const char* TiXmlBase::ReadName( const char* p, TIXML_STRING * name, TiXmlEncoding encoding )
+{
+	*name = "";
+	assert( p );
+
+	// Names start with letters or underscores.
+	// Of course, in unicode, tinyxml has no idea what a letter *is*. The
+	// algorithm is generous.
+	//
+	// After that, they can be letters, underscores, numbers,
+	// hyphens, or colons. (Colons are valid ony for namespaces,
+	// but tinyxml can't tell namespaces from names.)
+	if (    p && *p 
+		 && ( IsAlpha( (unsigned char) *p, encoding ) || *p == '_' ) )
+	{
+		while(		p && *p
+				&&	(		IsAlphaNum( (unsigned char ) *p, encoding ) 
+						 || *p == '_'
+						 || *p == '-'
+						 || *p == '.'
+						 || *p == ':' ) )
+		{
+			(*name) += *p;
+			++p;
+		}
+		return p;
+	}
+	return 0;
+}
+
+const char* TiXmlBase::GetEntity( const char* p, char* value, int* length, TiXmlEncoding encoding )
+{
+	// Presume an entity, and pull it out.
+    TIXML_STRING ent;
+	int i;
+	*length = 0;
+
+	if ( *(p+1) && *(p+1) == '#' && *(p+2) )
+	{
+		unsigned long ucs = 0;
+		ptrdiff_t delta = 0;
+		unsigned mult = 1;
+
+		if ( *(p+2) == 'x' )
+		{
+			// Hexadecimal.
+			if ( !*(p+3) ) return 0;
+
+			const char* q = p+3;
+			q = strchr( q, ';' );
+
+			if ( !q || !*q ) return 0;
+
+			delta = q-p;
+			--q;
+
+			while ( *q != 'x' )
+			{
+				if ( *q >= '0' && *q <= '9' )
+					ucs += mult * (*q - '0');
+				else if ( *q >= 'a' && *q <= 'f' )
+					ucs += mult * (*q - 'a' + 10);
+				else if ( *q >= 'A' && *q <= 'F' )
+					ucs += mult * (*q - 'A' + 10 );
+				else 
+					return 0;
+				mult *= 16;
+				--q;
+			}
+		}
+		else
+		{
+			// Decimal.
+			if ( !*(p+2) ) return 0;
+
+			const char* q = p+2;
+			q = strchr( q, ';' );
+
+			if ( !q || !*q ) return 0;
+
+			delta = q-p;
+			--q;
+
+			while ( *q != '#' )
+			{
+				if ( *q >= '0' && *q <= '9' )
+					ucs += mult * (*q - '0');
+				else 
+					return 0;
+				mult *= 10;
+				--q;
+			}
+		}
+		if ( encoding == TIXML_ENCODING_UTF8 )
+		{
+			// convert the UCS to UTF-8
+			ConvertUTF32ToUTF8( ucs, value, length );
+		}
+		else
+		{
+			*value = (char)ucs;
+			*length = 1;
+		}
+		return p + delta + 1;
+	}
+
+	// Now try to match it.
+	for( i=0; i<NUM_ENTITY; ++i )
+	{
+		if ( strncmp( entity[i].str, p, entity[i].strLength ) == 0 )
+		{
+			assert( strlen( entity[i].str ) == entity[i].strLength );
+			*value = entity[i].chr;
+			*length = 1;
+			return ( p + entity[i].strLength );
+		}
+	}
+
+	// So it wasn't an entity, its unrecognized, or something like that.
+	*value = *p;	// Don't put back the last one, since we return it!
+	return p+1;
+}
+
+
+bool TiXmlBase::StringEqual( const char* p,
+							 const char* tag,
+							 bool ignoreCase,
+							 TiXmlEncoding encoding )
+{
+	assert( p );
+	assert( tag );
+	if ( !p || !*p )
+	{
+		assert( 0 );
+		return false;
+	}
+
+	const char* q = p;
+
+	if ( ignoreCase )
+	{
+		while ( *q && *tag && ToLower( *q, encoding ) == ToLower( *tag, encoding ) )
+		{
+			++q;
+			++tag;
+		}
+
+		if ( *tag == 0 )
+			return true;
+	}
+	else
+	{
+		while ( *q && *tag && *q == *tag )
+		{
+			++q;
+			++tag;
+		}
+
+		if ( *tag == 0 )		// Have we found the end of the tag, and everything equal?
+			return true;
+	}
+	return false;
+}
+
+const char* TiXmlBase::ReadText(	const char* p, 
+									TIXML_STRING * text, 
+									bool trimWhiteSpace, 
+									const char* endTag, 
+									bool caseInsensitive,
+									TiXmlEncoding encoding )
+{
+    *text = "";
+	if (    !trimWhiteSpace			// certain tags always keep whitespace
+		 || !condenseWhiteSpace )	// if true, whitespace is always kept
+	{
+		// Keep all the white space.
+		while (	   p && *p
+				&& !StringEqual( p, endTag, caseInsensitive, encoding )
+			  )
+		{
+			int len;
+			char cArr[4] = { 0, 0, 0, 0 };
+			p = GetChar( p, cArr, &len, encoding );
+			text->append( cArr, len );
+		}
+	}
+	else
+	{
+		bool whitespace = false;
+
+		// Remove leading white space:
+		p = SkipWhiteSpace( p, encoding );
+		while (	   p && *p
+				&& !StringEqual( p, endTag, caseInsensitive, encoding ) )
+		{
+			if ( *p == '\r' || *p == '\n' )
+			{
+				whitespace = true;
+				++p;
+			}
+			else if ( IsWhiteSpace( *p ) )
+			{
+				whitespace = true;
+				++p;
+			}
+			else
+			{
+				// If we've found whitespace, add it before the
+				// new character. Any whitespace just becomes a space.
+				if ( whitespace )
+				{
+					(*text) += ' ';
+					whitespace = false;
+				}
+				int len;
+				char cArr[4] = { 0, 0, 0, 0 };
+				p = GetChar( p, cArr, &len, encoding );
+				if ( len == 1 )
+					(*text) += cArr[0];	// more efficient
+				else
+					text->append( cArr, len );
+			}
+		}
+	}
+	return p + strlen( endTag );
+}
+
+#ifdef TIXML_USE_STL
+
+void TiXmlDocument::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
+{
+	// The basic issue with a document is that we don't know what we're
+	// streaming. Read something presumed to be a tag (and hope), then
+	// identify it, and call the appropriate stream method on the tag.
+	//
+	// This "pre-streaming" will never read the closing ">" so the
+	// sub-tag can orient itself.
+
+	if ( !StreamTo( in, '<', tag ) ) 
+	{
+		SetError( TIXML_ERROR_PARSING_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return;
+	}
+
+	while ( in->good() )
+	{
+		int tagIndex = (int) tag->length();
+		while ( in->good() && in->peek() != '>' )
+		{
+			int c = in->get();
+			if ( c <= 0 )
+			{
+				SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+				break;
+			}
+			(*tag) += (char) c;
+		}
+
+		if ( in->good() )
+		{
+			// We now have something we presume to be a node of 
+			// some sort. Identify it, and call the node to
+			// continue streaming.
+			TiXmlNode* node = Identify( tag->c_str() + tagIndex, TIXML_DEFAULT_ENCODING );
+
+			if ( node )
+			{
+				node->StreamIn( in, tag );
+				bool isElement = node->ToElement() != 0;
+				delete node;
+				node = 0;
+
+				// If this is the root element, we're done. Parsing will be
+				// done by the >> operator.
+				if ( isElement )
+				{
+					return;
+				}
+			}
+			else
+			{
+				SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN );
+				return;
+			}
+		}
+	}
+	// We should have returned sooner.
+	SetError( TIXML_ERROR, 0, 0, TIXML_ENCODING_UNKNOWN );
+}
+
+#endif
+
+const char* TiXmlDocument::Parse( const char* p, TiXmlParsingData* prevData, TiXmlEncoding encoding )
+{
+	ClearError();
+
+	// Parse away, at the document level. Since a document
+	// contains nothing but other tags, most of what happens
+	// here is skipping white space.
+	if ( !p || !*p )
+	{
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	// Note that, for a document, this needs to come
+	// before the while space skip, so that parsing
+	// starts from the pointer we are given.
+	location.Clear();
+	if ( prevData )
+	{
+		location.row = prevData->cursor.row;
+		location.col = prevData->cursor.col;
+	}
+	else
+	{
+		location.row = 0;
+		location.col = 0;
+	}
+	TiXmlParsingData data( p, TabSize(), location.row, location.col );
+	location = data.Cursor();
+
+	if ( encoding == TIXML_ENCODING_UNKNOWN )
+	{
+		// Check for the Microsoft UTF-8 lead bytes.
+		const unsigned char* pU = (const unsigned char*)p;
+		if (	*(pU+0) && *(pU+0) == TIXML_UTF_LEAD_0
+			 && *(pU+1) && *(pU+1) == TIXML_UTF_LEAD_1
+			 && *(pU+2) && *(pU+2) == TIXML_UTF_LEAD_2 )
+		{
+			encoding = TIXML_ENCODING_UTF8;
+			useMicrosoftBOM = true;
+		}
+	}
+
+    p = SkipWhiteSpace( p, encoding );
+	if ( !p )
+	{
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, TIXML_ENCODING_UNKNOWN );
+		return 0;
+	}
+
+	while ( p && *p )
+	{
+		TiXmlNode* node = Identify( p, encoding );
+		if ( node )
+		{
+			p = node->Parse( p, &data, encoding );
+			LinkEndChild( node );
+		}
+		else
+		{
+			break;
+		}
+
+		// Did we get encoding info?
+		if (    encoding == TIXML_ENCODING_UNKNOWN
+			 && node->ToDeclaration() )
+		{
+			TiXmlDeclaration* dec = node->ToDeclaration();
+			const char* enc = dec->Encoding();
+			assert( enc );
+
+			if ( *enc == 0 )
+				encoding = TIXML_ENCODING_UTF8;
+			else if ( StringEqual( enc, "UTF-8", true, TIXML_ENCODING_UNKNOWN ) )
+				encoding = TIXML_ENCODING_UTF8;
+			else if ( StringEqual( enc, "UTF8", true, TIXML_ENCODING_UNKNOWN ) )
+				encoding = TIXML_ENCODING_UTF8;	// incorrect, but be nice
+			else 
+				encoding = TIXML_ENCODING_LEGACY;
+		}
+
+		p = SkipWhiteSpace( p, encoding );
+	}
+
+	// Was this empty?
+	if ( !firstChild ) {
+		SetError( TIXML_ERROR_DOCUMENT_EMPTY, 0, 0, encoding );
+		return 0;
+	}
+
+	// All is well.
+	return p;
+}
+
+void TiXmlDocument::SetError( int err, const char* pError, TiXmlParsingData* data, TiXmlEncoding encoding )
+{	
+	// The first error in a chain is more accurate - don't set again!
+	if ( error )
+		return;
+
+	assert( err > 0 && err < TIXML_ERROR_STRING_COUNT );
+	error   = true;
+	errorId = err;
+	errorDesc = errorString[ errorId ];
+
+	errorLocation.Clear();
+	if ( pError && data )
+	{
+		data->Stamp( pError, encoding );
+		errorLocation = data->Cursor();
+	}
+}
+
+
+TiXmlNode* TiXmlNode::Identify( const char* p, TiXmlEncoding encoding )
+{
+	TiXmlNode* returnNode = 0;
+
+	p = SkipWhiteSpace( p, encoding );
+	if( !p || !*p || *p != '<' )
+	{
+		return 0;
+	}
+
+	TiXmlDocument* doc = GetDocument();
+	p = SkipWhiteSpace( p, encoding );
+
+	if ( !p || !*p )
+	{
+		return 0;
+	}
+
+	// What is this thing? 
+	// - Elements start with a letter or underscore, but xml is reserved.
+	// - Comments: <!--
+	// - Decleration: <?xml
+	// - Everthing else is unknown to tinyxml.
+	//
+
+	const char* xmlHeader = { "<?xml" };
+	const char* commentHeader = { "<!--" };
+	const char* dtdHeader = { "<!" };
+	const char* cdataHeader = { "<![CDATA[" };
+
+	if ( StringEqual( p, xmlHeader, true, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Declaration\n" );
+		#endif
+		returnNode = new TiXmlDeclaration();
+	}
+	else if ( StringEqual( p, commentHeader, false, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Comment\n" );
+		#endif
+		returnNode = new TiXmlComment();
+	}
+	else if ( StringEqual( p, cdataHeader, false, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing CDATA\n" );
+		#endif
+		TiXmlText* text = new TiXmlText( "" );
+		text->SetCDATA( true );
+		returnNode = text;
+	}
+	else if ( StringEqual( p, dtdHeader, false, encoding ) )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Unknown(1)\n" );
+		#endif
+		returnNode = new TiXmlUnknown();
+	}
+	else if (    IsAlpha( *(p+1), encoding )
+			  || *(p+1) == '_' )
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Element\n" );
+		#endif
+		returnNode = new TiXmlElement( "" );
+	}
+	else
+	{
+		#ifdef DEBUG_PARSER
+			TIXML_LOG( "XML parsing Unknown(2)\n" );
+		#endif
+		returnNode = new TiXmlUnknown();
+	}
+
+	if ( returnNode )
+	{
+		// Set the parent, so it can report errors
+		returnNode->parent = this;
+	}
+	else
+	{
+		if ( doc )
+			doc->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, TIXML_ENCODING_UNKNOWN );
+	}
+	return returnNode;
+}
+
+#ifdef TIXML_USE_STL
+
+void TiXmlElement::StreamIn (TIXML_ISTREAM * in, TIXML_STRING * tag)
+{
+	// We're called with some amount of pre-parsing. That is, some of "this"
+	// element is in "tag". Go ahead and stream to the closing ">"
+	while( in->good() )
+	{
+		int c = in->get();
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+		(*tag) += (char) c ;
+		
+		if ( c == '>' )
+			break;
+	}
+
+	if ( tag->length() < 3 ) return;
+
+	// Okay...if we are a "/>" tag, then we're done. We've read a complete tag.
+	// If not, identify and stream.
+
+	if (    tag->at( tag->length() - 1 ) == '>' 
+		 && tag->at( tag->length() - 2 ) == '/' )
+	{
+		// All good!
+		return;
+	}
+	else if ( tag->at( tag->length() - 1 ) == '>' )
+	{
+		// There is more. Could be:
+		//		text
+		//		closing tag
+		//		another node.
+		for ( ;; )
+		{
+			StreamWhiteSpace( in, tag );
+
+			// Do we have text?
+			if ( in->good() && in->peek() != '<' ) 
+			{
+				// Yep, text.
+				TiXmlText text( "" );
+				text.StreamIn( in, tag );
+
+				// What follows text is a closing tag or another node.
+				// Go around again and figure it out.
+				continue;
+			}
+
+			// We now have either a closing tag...or another node.
+			// We should be at a "<", regardless.
+			if ( !in->good() ) return;
+			assert( in->peek() == '<' );
+			int tagIndex = (int) tag->length();
+
+			bool closingTag = false;
+			bool firstCharFound = false;
+
+			for( ;; )
+			{
+				if ( !in->good() )
+					return;
+
+				int c = in->peek();
+				if ( c <= 0 )
+				{
+					TiXmlDocument* document = GetDocument();
+					if ( document )
+						document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+					return;
+				}
+				
+				if ( c == '>' )
+					break;
+
+				*tag += (char) c;
+				in->get();
+
+				if ( !firstCharFound && c != '<' && !IsWhiteSpace( c ) )
+				{
+					firstCharFound = true;
+					if ( c == '/' )
+						closingTag = true;
+				}
+			}
+			// If it was a closing tag, then read in the closing '>' to clean up the input stream.
+			// If it was not, the streaming will be done by the tag.
+			if ( closingTag )
+			{
+				if ( !in->good() )
+					return;
+
+				int c = in->get();
+				if ( c <= 0 )
+				{
+					TiXmlDocument* document = GetDocument();
+					if ( document )
+						document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+					return;
+				}
+				assert( c == '>' );
+				*tag += (char) c;
+
+				// We are done, once we've found our closing tag.
+				return;
+			}
+			else
+			{
+				// If not a closing tag, id it, and stream.
+				const char* tagloc = tag->c_str() + tagIndex;
+				TiXmlNode* node = Identify( tagloc, TIXML_DEFAULT_ENCODING );
+				if ( !node )
+					return;
+				node->StreamIn( in, tag );
+				delete node;
+				node = 0;
+
+				// No return: go around from the beginning: text, closing tag, or node.
+			}
+		}
+	}
+}
+#endif
+
+const char* TiXmlElement::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	p = SkipWhiteSpace( p, encoding );
+	TiXmlDocument* document = GetDocument();
+
+	if ( !p || !*p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, 0, 0, encoding );
+		return 0;
+	}
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+
+	if ( *p != '<' )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, p, data, encoding );
+		return 0;
+	}
+
+	p = SkipWhiteSpace( p+1, encoding );
+
+	// Read the name.
+	const char* pErr = p;
+
+    p = ReadName( p, &value, encoding );
+	if ( !p || !*p )
+	{
+		if ( document )	document->SetError( TIXML_ERROR_FAILED_TO_READ_ELEMENT_NAME, pErr, data, encoding );
+		return 0;
+	}
+
+    TIXML_STRING endTag ("</");
+	endTag += value;
+	endTag += ">";
+
+	// Check for and read attributes. Also look for an empty
+	// tag or an end tag.
+	while ( p && *p )
+	{
+		pErr = p;
+		p = SkipWhiteSpace( p, encoding );
+		if ( !p || !*p )
+		{
+			if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
+			return 0;
+		}
+		if ( *p == '/' )
+		{
+			++p;
+			// Empty tag.
+			if ( *p  != '>' )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_PARSING_EMPTY, p, data, encoding );		
+				return 0;
+			}
+			return (p+1);
+		}
+		else if ( *p == '>' )
+		{
+			// Done with attributes (if there were any.)
+			// Read the value -- which can include other
+			// elements -- read the end tag, and return.
+			++p;
+			p = ReadValue( p, data, encoding );		// Note this is an Element method, and will set the error if one happens.
+			if ( !p || !*p )
+				return 0;
+
+			// We should find the end tag now
+			if ( StringEqual( p, endTag.c_str(), false, encoding ) )
+			{
+				p += endTag.length();
+				return p;
+			}
+			else
+			{
+				if ( document ) document->SetError( TIXML_ERROR_READING_END_TAG, p, data, encoding );
+				return 0;
+			}
+		}
+		else
+		{
+			// Try to read an attribute:
+			TiXmlAttribute* attrib = new TiXmlAttribute();
+			if ( !attrib )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, pErr, data, encoding );
+				return 0;
+			}
+
+			attrib->SetDocument( document );
+			const char* pErr = p;
+			p = attrib->Parse( p, data, encoding );
+
+			if ( !p || !*p )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_PARSING_ELEMENT, pErr, data, encoding );
+				delete attrib;
+				return 0;
+			}
+
+			// Handle the strange case of double attributes:
+			TiXmlAttribute* node = attributeSet.Find( attrib->Name() );
+			if ( node )
+			{
+				node->SetValue( attrib->Value() );
+				delete attrib;
+				return 0;
+			}
+
+			attributeSet.Add( attrib );
+		}
+	}
+	return p;
+}
+
+
+const char* TiXmlElement::ReadValue( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	TiXmlDocument* document = GetDocument();
+
+	// Read in text and elements in any order.
+	const char* pWithWhiteSpace = p;
+	p = SkipWhiteSpace( p, encoding );
+
+	while ( p && *p )
+	{
+		if ( *p != '<' )
+		{
+			// Take what we have, make a text element.
+			TiXmlText* textNode = new TiXmlText( "" );
+
+			if ( !textNode )
+			{
+				if ( document ) document->SetError( TIXML_ERROR_OUT_OF_MEMORY, 0, 0, encoding );
+				    return 0;
+			}
+
+			if ( TiXmlBase::IsWhiteSpaceCondensed() )
+			{
+				p = textNode->Parse( p, data, encoding );
+			}
+			else
+			{
+				// Special case: we want to keep the white space
+				// so that leading spaces aren't removed.
+				p = textNode->Parse( pWithWhiteSpace, data, encoding );
+			}
+
+			if ( !textNode->Blank() )
+				LinkEndChild( textNode );
+			else
+				delete textNode;
+		} 
+		else 
+		{
+			// We hit a '<'
+			// Have we hit a new element or an end tag? This could also be
+			// a TiXmlText in the "CDATA" style.
+			if ( StringEqual( p, "</", false, encoding ) )
+			{
+				return p;
+			}
+			else
+			{
+				TiXmlNode* node = Identify( p, encoding );
+				if ( node )
+				{
+					p = node->Parse( p, data, encoding );
+					LinkEndChild( node );
+				}				
+				else
+				{
+					return 0;
+				}
+			}
+		}
+		pWithWhiteSpace = p;
+		p = SkipWhiteSpace( p, encoding );
+	}
+
+	if ( !p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ELEMENT_VALUE, 0, 0, encoding );
+	}	
+	return p;
+}
+
+
+#ifdef TIXML_USE_STL
+void TiXmlUnknown::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->get();	
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+		(*tag) += (char) c;
+
+		if ( c == '>' )
+		{
+			// All is well.
+			return;		
+		}
+	}
+}
+#endif
+
+
+const char* TiXmlUnknown::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	TiXmlDocument* document = GetDocument();
+	p = SkipWhiteSpace( p, encoding );
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+	if ( !p || !*p || *p != '<' )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_UNKNOWN, p, data, encoding );
+		return 0;
+	}
+	++p;
+    value = "";
+
+	while ( p && *p && *p != '>' )
+	{
+		value += *p;
+		++p;
+	}
+
+	if ( !p )
+	{
+		if ( document )	document->SetError( TIXML_ERROR_PARSING_UNKNOWN, 0, 0, encoding );
+	}
+	if ( *p == '>' )
+		return p+1;
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlComment::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->get();	
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+
+		(*tag) += (char) c;
+
+		if ( c == '>' 
+			 && tag->at( tag->length() - 2 ) == '-'
+			 && tag->at( tag->length() - 3 ) == '-' )
+		{
+			// All is well.
+			return;		
+		}
+	}
+}
+#endif
+
+
+const char* TiXmlComment::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	TiXmlDocument* document = GetDocument();
+	value = "";
+
+	p = SkipWhiteSpace( p, encoding );
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+	const char* startTag = "<!--";
+	const char* endTag   = "-->";
+
+	if ( !StringEqual( p, startTag, false, encoding ) )
+	{
+		document->SetError( TIXML_ERROR_PARSING_COMMENT, p, data, encoding );
+		return 0;
+	}
+	p += strlen( startTag );
+	p = ReadText( p, &value, false, endTag, false, encoding );
+	return p;
+}
+
+
+const char* TiXmlAttribute::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	p = SkipWhiteSpace( p, encoding );
+	if ( !p || !*p ) return 0;
+
+	int tabsize = 4;
+	if ( document )
+		tabsize = document->TabSize();
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+	// Read the name, the '=' and the value.
+	const char* pErr = p;
+	p = ReadName( p, &name, encoding );
+	if ( !p || !*p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, pErr, data, encoding );
+		return 0;
+	}
+	p = SkipWhiteSpace( p, encoding );
+	if ( !p || !*p || *p != '=' )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
+		return 0;
+	}
+
+	++p;	// skip '='
+	p = SkipWhiteSpace( p, encoding );
+	if ( !p || !*p )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_READING_ATTRIBUTES, p, data, encoding );
+		return 0;
+	}
+	
+	const char* end;
+
+	if ( *p == '\'' )
+	{
+		++p;
+		end = "\'";
+		p = ReadText( p, &value, false, end, false, encoding );
+	}
+	else if ( *p == '"' )
+	{
+		++p;
+		end = "\"";
+		p = ReadText( p, &value, false, end, false, encoding );
+	}
+	else
+	{
+		// All attribute values should be in single or double quotes.
+		// But this is such a common error that the parser will try
+		// its best, even without them.
+		value = "";
+		while (    p && *p										// existence
+				&& !IsWhiteSpace( *p ) && *p != '\n' && *p != '\r'	// whitespace
+				&& *p != '/' && *p != '>' )						// tag end
+		{
+			value += *p;
+			++p;
+		}
+	}
+	return p;
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlText::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
+{
+	if ( cdata )
+	{
+		int c = in->get();	
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+
+		(*tag) += (char) c;
+
+		if ( c == '>' 
+			 && tag->at( tag->length() - 2 ) == ']'
+			 && tag->at( tag->length() - 3 ) == ']' )
+		{
+			// All is well.
+			return;		
+		}
+	}
+	else
+	{
+		while ( in->good() )
+		{
+			int c = in->peek();	
+			if ( c == '<' )
+				return;
+			if ( c <= 0 )
+			{
+				TiXmlDocument* document = GetDocument();
+				if ( document )
+					document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+				return;
+			}
+
+			(*tag) += (char) c;
+			in->get();
+		}
+	}
+}
+#endif
+
+const char* TiXmlText::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding encoding )
+{
+	value = "";
+	TiXmlDocument* document = GetDocument();
+
+	if ( data )
+	{
+		data->Stamp( p, encoding );
+		location = data->Cursor();
+	}
+
+	const char* const startTag = "<![CDATA[";
+	const char* const endTag   = "]]>";
+
+	if ( cdata || StringEqual( p, startTag, false, encoding ) )
+	{
+		cdata = true;
+
+		if ( !StringEqual( p, startTag, false, encoding ) )
+		{
+			document->SetError( TIXML_ERROR_PARSING_CDATA, p, data, encoding );
+			return 0;
+		}
+		p += strlen( startTag );
+
+		// Keep all the white space, ignore the encoding, etc.
+		while (	   p && *p
+				&& !StringEqual( p, endTag, false, encoding )
+			  )
+		{
+			value += *p;
+			++p;
+		}
+
+		TIXML_STRING dummy; 
+		p = ReadText( p, &dummy, false, endTag, false, encoding );
+		return p;
+	}
+	else
+	{
+		bool ignoreWhite = true;
+
+		const char* end = "<";
+		p = ReadText( p, &value, ignoreWhite, end, false, encoding );
+		if ( p )
+			return p-1;	// don't truncate the '<'
+		return 0;
+	}
+}
+
+#ifdef TIXML_USE_STL
+void TiXmlDeclaration::StreamIn( TIXML_ISTREAM * in, TIXML_STRING * tag )
+{
+	while ( in->good() )
+	{
+		int c = in->get();
+		if ( c <= 0 )
+		{
+			TiXmlDocument* document = GetDocument();
+			if ( document )
+				document->SetError( TIXML_ERROR_EMBEDDED_NULL, 0, 0, TIXML_ENCODING_UNKNOWN );
+			return;
+		}
+		(*tag) += (char) c;
+
+		if ( c == '>' )
+		{
+			// All is well.
+			return;
+		}
+	}
+}
+#endif
+
+const char* TiXmlDeclaration::Parse( const char* p, TiXmlParsingData* data, TiXmlEncoding _encoding )
+{
+	p = SkipWhiteSpace( p, _encoding );
+	// Find the beginning, find the end, and look for
+	// the stuff in-between.
+	TiXmlDocument* document = GetDocument();
+	if ( !p || !*p || !StringEqual( p, "<?xml", true, _encoding ) )
+	{
+		if ( document ) document->SetError( TIXML_ERROR_PARSING_DECLARATION, 0, 0, _encoding );
+		return 0;
+	}
+	if ( data )
+	{
+		data->Stamp( p, _encoding );
+		location = data->Cursor();
+	}
+	p += 5;
+
+	version = "";
+	encoding = "";
+	standalone = "";
+
+	while ( p && *p )
+	{
+		if ( *p == '>' )
+		{
+			++p;
+			return p;
+		}
+
+		p = SkipWhiteSpace( p, _encoding );
+		if ( StringEqual( p, "version", true, _encoding ) )
+		{
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p, data, _encoding );		
+			version = attrib.Value();
+		}
+		else if ( StringEqual( p, "encoding", true, _encoding ) )
+		{
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p, data, _encoding );		
+			encoding = attrib.Value();
+		}
+		else if ( StringEqual( p, "standalone", true, _encoding ) )
+		{
+			TiXmlAttribute attrib;
+			p = attrib.Parse( p, data, _encoding );		
+			standalone = attrib.Value();
+		}
+		else
+		{
+			// Read over whatever it is.
+			while( p && *p && *p != '>' && !IsWhiteSpace( *p ) )
+				++p;
+		}
+	}
+	return 0;
+}
+
+bool TiXmlText::Blank() const
+{
+	for ( unsigned i=0; i<value.length(); i++ )
+		if ( !IsWhiteSpace( value[i] ) )
+			return false;
+	return true;
+}
+
Index: branches/network/src/lib/particles/Makefile.am
===================================================================
--- branches/network/src/lib/particles/Makefile.am	(revision 6636)
+++ branches/network/src/lib/particles/Makefile.am	(revision 6636)
@@ -0,0 +1,25 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXparticles.a
+
+libORXparticles_a_SOURCES = \
+			particle_emitter.cc \
+			\
+			particle_system.cc \
+			sprite_particles.cc \
+			spark_particles.cc \
+			model_particles.cc \
+			\
+			quick_animation.cc
+
+
+noinst_HEADERS = \
+			particle_emitter.h \
+			\
+			particle_system.h \
+			sprite_particles.h \
+			spark_particles.h \
+			model_particles.h \
+			\
+			quick_animation.h
Index: branches/network/src/lib/particles/engine/particle_engine.cc
===================================================================
--- branches/network/src/lib/particles/engine/particle_engine.cc	(revision 6636)
+++ branches/network/src/lib/particles/engine/particle_engine.cc	(revision 6636)
@@ -0,0 +1,455 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: ...
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "particle_engine.h"
+
+#include "class_list.h"
+
+#include "list.h"
+#include "debug.h"
+#include "stdlibincl.h"
+#include "load_param.h"
+
+using namespace std;
+
+/**
+ *  standard constructor
+*/
+ParticleEngine::ParticleEngine ()
+{
+   this->setClassID(CL_PARTICLE_ENGINE, "ParticleEngine");
+   this->setName("ParticleEngine");
+
+   this->systemList = new tList<ParticleSystem>;
+   this->emitterList = new tList<ParticleEmitter>;
+   this->connectionList = new tList<ParticleConnection>;
+}
+
+/**
+ *  the singleton reference to this class
+*/
+ParticleEngine* ParticleEngine::singletonRef = NULL;
+
+/**
+ *  deletes all the system, emitters, connections and Lists
+*/
+ParticleEngine::~ParticleEngine ()
+{
+  /// @todo we must not do this, because PNoe does it for us
+  /// or we do this with help from ClassList, which essentially makes much more sense
+
+  // delete all remaining systems
+//   tIterator<ParticleSystem>* sysIt = this->systemList->getIterator();
+//   ParticleSystem* tmpSys = sysIt->firstElement();
+//   while(tmpSys)
+//     {
+//       delete tmpSys;
+//       tmpSys = sysIt->nextElement();
+//     }
+//   delete sysIt;
+   delete this->systemList;
+//
+   // delete all remaining emitters
+   tIterator<ParticleEmitter>* emitIt = this->emitterList->getIterator();
+   ParticleEmitter* tmpEmit = emitIt->firstElement();
+   while(tmpEmit)
+     {
+       delete tmpEmit;
+       tmpEmit = emitIt->nextElement();
+     }
+   delete emitIt;
+   delete this->emitterList;
+
+  // there should be no more Connections
+  if (this->connectionList->getSize() == 0)
+    delete this->connectionList;
+  else
+    PRINTF(2)("The Connection List is not empty. This should not happen.\n");
+
+  ParticleEngine::singletonRef = NULL;
+}
+
+/**
+  \brief loads the ParticleEngines settings and connections between particles and emitters
+* @param root the XML-element to load this from.
+ */
+void ParticleEngine::loadParams(const TiXmlElement* root)
+{
+  LOAD_PARAM_START_CYCLE(root, element);
+  {
+    LoadParam_CYCLE(element, "connect", this, ParticleEngine, addConnection)
+        .describe("connects an Emitter to a System (emitterName, systemName)");
+  }
+  LOAD_PARAM_END_CYCLE(element);
+}
+
+/**
+ *  Adds a System to the System list.
+
+   this is done automatically when creating a ParticleSystem
+*/
+void ParticleEngine::addSystem(ParticleSystem* system)
+{
+  this->systemList->add(system);
+}
+
+/**
+ *  Adds an emitter to the emitterList
+
+   this is done automatically when creating a ParticleEmitter
+*/
+void ParticleEngine::addEmitter(ParticleEmitter* emitter)
+{
+  this->emitterList->add(emitter);
+}
+
+/**
+* @brief Connects a ParticleSystem to a ParticleSystem thus emitting Particles.
+* @param emitter the Emitter to connect to the System
+* @param system the System to connect to the Emitter
+*/
+void ParticleEngine::addConnection(const char* emitter, const char* system)
+{
+  ParticleEmitter* tmpEmit = dynamic_cast<ParticleEmitter*>(ClassList::getObject(emitter, CL_PARTICLE_EMITTER));//this->getEmitterByName(emitter);
+  ParticleSystem* tmpSys = dynamic_cast<ParticleSystem*>(ClassList::getObject(system, CL_PARTICLE_SYSTEM));//this->getSystemByName(system);
+
+  if (tmpEmit != NULL && tmpSys != NULL)
+    this->addConnection(tmpEmit, tmpSys);
+  else
+  {
+    if (tmpEmit == NULL)
+      PRINTF(2)("Emitter %s not found in the List of emitters, not connecting to %s\n", emitter, system);
+    if (tmpEmit == NULL)
+      PRINTF(2)("System %s not found in the List of emitters, not connecting to %s\n", system, emitter);
+  }
+}
+
+/**
+ *  Connects a ParticleSystem to a ParticleSystem thus emitting Particles.
+ * @param emitter the Emitter to connect to the System
+ * @param system the System to connect to the Emitter
+*/
+void ParticleEngine::addConnection(ParticleEmitter* emitter, ParticleSystem* system)
+{
+  // look, if we have already added this connection
+  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
+  ParticleConnection* tmpConnection = tmpConIt->firstElement();
+  while(tmpConnection)
+    {
+      if (tmpConnection->emitter == emitter && tmpConnection->system == system)
+        {
+          PRINTF(2)("Connection between Emitter and System already exists.\n");
+          delete tmpConIt;
+          return;
+        }
+
+      tmpConnection = tmpConIt->nextElement();
+    }
+  delete tmpConIt;
+
+
+
+  ParticleConnection* tmpCon = new ParticleConnection;
+  tmpCon->emitter = emitter;
+  tmpCon->system = system;
+
+  this->connectionList->add(tmpCon);
+}
+
+/**
+ *  Removes a system from the systemList and also removes all Connections to the System
+ * @param system The ParticleSystem to delete
+*/
+bool ParticleEngine::removeSystem(ParticleSystem* system)
+{
+  // remove any connections, that have this system within
+  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
+  ParticleConnection* tmpConnection = tmpConIt->firstElement();
+  while(tmpConnection != NULL)
+    {
+      if (tmpConnection->system == system)
+        this->breakConnection(tmpConnection);
+      tmpConnection = tmpConIt->nextElement();
+    }
+  delete tmpConIt;
+
+  // remove the System from the systemList.
+  this->systemList->remove(system);
+}
+
+/**
+ *  removes an emitter from the emitterList and also from all Connections it is attached to.
+ * @param emitter the ParticleEmitter to remove.
+*/
+bool ParticleEngine::removeEmitter(ParticleEmitter* emitter)
+{
+  // remove any connections, that have this emitter within
+  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
+  ParticleConnection* tmpConnection = tmpConIt->firstElement();
+  while(tmpConnection != NULL)
+    {
+      if (tmpConnection->emitter == emitter)
+        this->breakConnection(tmpConnection);
+      tmpConnection = tmpConIt->nextElement();
+    }
+  delete tmpConIt;
+
+  // remove the emitter from the emitterList
+  this->emitterList->remove(emitter);
+}
+
+
+/**
+ *  removes a Connection between an Emitter and a System
+ * @param connection the connection to remove
+ *
+ * \see bool ParticleEngine::breakConnection(ParticleEmitter* emitter, ParticleSystem* system)
+ */
+bool ParticleEngine::breakConnection(ParticleConnection* connection)
+{
+  this->connectionList->remove(connection);
+  return true;
+}
+
+/**
+ *  removes a Connection between an Emitter and a System
+ * @param emitter The emitter of the connection to remove
+ * @param system The system of the connection to remove
+ * @returns true, if the connection was broken, false if the conntection was not found
+ *
+ * only if both system and emitter are in the connection the Connection will be broken
+*/
+bool ParticleEngine::breakConnection(ParticleEmitter* emitter, ParticleSystem* system)
+{
+  // look, if we have already added this connection
+  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
+  ParticleConnection* tmpConnection = tmpConIt->firstElement();
+  while(tmpConnection)
+    {
+    if (tmpConnection->emitter == emitter && tmpConnection->system == system)
+      {
+        this->breakConnection(tmpConnection);
+        delete tmpConIt;
+        return true;
+      }
+    tmpConnection = tmpConIt->nextElement();
+    }
+  delete tmpConIt;
+  return false;
+}
+
+/**
+ *  removes a Connection between an Emitter and a System
+ * @param emitter The emitter of the connections to remove
+ * @returns the count of connections that were broken, 0 if no conntection was not found
+ */
+unsigned int ParticleEngine::breakConnections(ParticleEmitter* emitter)
+{
+  unsigned int retVal = 0;
+  // look, if we have already added this connection
+  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
+  ParticleConnection* tmpConnection = tmpConIt->firstElement();
+  while(tmpConnection)
+  {
+    if (tmpConnection->emitter == emitter)
+    {
+      this->breakConnection(tmpConnection);
+      retVal++;
+    }
+    tmpConnection = tmpConIt->nextElement();
+  }
+  delete tmpConIt;
+  return retVal;
+}
+
+
+/**
+ *  removes a Connection between an Emitter and a System
+ * @param system The system of the connections to remove
+ * @returns the count of connections that were broken, 0 if no conntection was not found
+ */
+unsigned int ParticleEngine::breakConnections(ParticleSystem* system)
+{
+  unsigned int retVal = 0;
+  // look, if we have already added this connection
+  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
+  ParticleConnection* tmpConnection = tmpConIt->firstElement();
+  while(tmpConnection)
+  {
+    if (tmpConnection->system == system)
+    {
+      this->breakConnection(tmpConnection);
+      retVal++;
+    }
+    tmpConnection = tmpConIt->nextElement();
+  }
+  delete tmpConIt;
+  return retVal;
+}
+
+/**
+ *  this function ticks all the ParticleSystems, so an animation will flow
+ * @param dt passed since last tick
+*/
+void ParticleEngine::tick(float dt)
+{
+  // ticks all the ParticleSystems
+//   tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
+//   ParticleSystem* tmpSys = tmpIt->firstElement();
+//   while(tmpSys)
+//     {
+//       tmpSys->tick(dt);
+//       tmpSys = tmpIt->nextElement();
+//     }
+//   delete tmpIt;
+
+  // add new Particles to each System connected to an Emitter.
+  tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
+  ParticleConnection* tmpConnection = tmpConIt->firstElement();
+  while(tmpConnection)
+    {
+      tmpConnection->emitter->tick(dt, tmpConnection->system);
+      tmpConnection = tmpConIt->nextElement();
+    }
+  delete tmpConIt;
+}
+
+/**
+ *  draws all the systems and their Particles.
+*/
+void ParticleEngine::draw() const
+{
+  /*
+  tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
+  ParticleSystem* tmpSys = tmpIt->firstElement();
+  while(tmpSys)
+    {
+      tmpSys->draw();
+      tmpSys = tmpIt->nextElement();
+    }
+  delete tmpIt;*/
+
+}
+
+/**
+ * @param number the n-th system to return
+ * @returns the system called by number or NULL if not found
+*/
+ParticleSystem* ParticleEngine::getSystemByNumber(unsigned int number) const
+{
+  int count = 0;
+  tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
+  ParticleSystem* tmpSys = tmpIt->firstElement();
+  while(tmpSys)
+    {
+      count++;
+      if ( count == number)
+        {
+          delete tmpIt;
+          return tmpSys;
+        }
+      tmpSys = tmpIt->nextElement();
+    }
+  delete tmpIt;
+  return NULL;
+}
+
+/**
+ * @param number the n-th emitter to return
+ * @returns the emitter called by number or NULL if not found
+*/
+ParticleEmitter* ParticleEngine::getEmitterByNumber(unsigned int number) const
+{
+  int count = 0;
+  tIterator<ParticleEmitter>* tmpIt = emitterList->getIterator();
+  ParticleEmitter* tmpEmit = tmpIt->firstElement();
+  while(tmpEmit)
+    {
+      count++;
+      if ( count == number)
+        {
+          delete tmpIt;
+          return tmpEmit;
+        }
+      tmpEmit = tmpIt->nextElement();
+    }
+  delete tmpIt;
+  return NULL;
+}
+
+/**
+ *  outputs some nice debug information
+*/
+void ParticleEngine::debug()
+{
+  PRINT(0)("+-----------------------------------+\n");
+  PRINT(0)("+ PARTICLE-ENGINE DEBUG INFORMATION +\n");
+  PRINT(0)("+-----------------------------------+\n");
+  PRINT(0)(" Reference: %p\n", ParticleEngine::singletonRef);
+  PRINT(0)(" Count: Emitters: %d; Systems: %d, Connections: %d\n",
+  this->emitterList->getSize(), this->systemList->getSize(), this->connectionList->getSize());
+
+  if (this->connectionList->getSize() > 0)
+  {
+    PRINT(0)(" Connections:\n");
+    PRINT(0)(" -----------------------------------\n");
+
+    tIterator<ParticleConnection>* tmpConIt = connectionList->getIterator();
+    ParticleConnection* tmpConnection = tmpConIt->firstElement();
+    while(tmpConnection)
+    {
+      PRINT(0)(" Emitter '%s' emitts into System '%s'\n", tmpConnection->emitter->getName(), tmpConnection->system->getName());
+      tmpConnection = tmpConIt->nextElement();
+    }
+    delete tmpConIt;
+  }
+
+  if (this->systemList->getSize() > 0)
+  {
+    tIterator<ParticleSystem>* tmpIt = systemList->getIterator();
+    ParticleSystem* tmpSys = tmpIt->firstElement();
+    while(tmpSys)
+    {
+      tmpSys->debug();
+      tmpSys = tmpIt->nextElement();
+    }
+    delete tmpIt;
+  }
+  else
+  {
+    PRINT(0)("NO SYSTEMS\n");
+  }
+  if (this->emitterList->getSize() > 0)
+  {
+    tIterator<ParticleEmitter>* tmpIt = emitterList->getIterator();
+    ParticleEmitter* tmpEmit = tmpIt->firstElement();
+    while(tmpEmit)
+    {
+      tmpEmit->debug();
+      tmpEmit = tmpIt->nextElement();
+    }
+    delete tmpIt;
+  }
+  else
+  {
+    PRINTF(0)("NO EMITTERS\n");
+  }
+
+  PRINT(0)("+--------------------------------PE-+\n");
+
+}
+
Index: branches/network/src/lib/particles/engine/particle_engine.h
===================================================================
--- branches/network/src/lib/particles/engine/particle_engine.h	(revision 6636)
+++ branches/network/src/lib/particles/engine/particle_engine.h	(revision 6636)
@@ -0,0 +1,72 @@
+/*!
+ * @file particle_engine.h
+  *  Definition of the ParticleEngine
+*/
+
+#ifndef _PARTICLE_ENGINE_H
+#define _PARTICLE_ENGINE_H
+
+#include "base_object.h"
+
+#include "particle_system.h"
+#include "particle_emitter.h"
+
+#include "parser/tinyxml/tinyxml.h"
+
+// FORWARD DECLARATION
+template<class T> class tList;
+
+//! A ParticleConnection enables us to emitt from any emitter into any other particleSystem
+typedef struct ParticleConnection
+{
+  ParticleEmitter*    emitter;     //!< The emitter to emit system from.
+  ParticleSystem*     system;      //!< The Particles emitted from emitter.
+};
+
+//! The physicsEngine handles and stores Systems and Emitters.
+/**
+   It is responsible for driving on the Particles (tick)
+   It draw particles (draw)
+   and it emitts particles into the system
+*/
+class ParticleEngine : public BaseObject {
+
+ public:
+  virtual ~ParticleEngine();
+  /** @returns a Pointer to the only object of this Class */
+  inline static ParticleEngine* getInstance() { if (!singletonRef) singletonRef = new ParticleEngine();  return singletonRef; };
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void tick(float dt);
+  void draw() const;
+
+  void addSystem(ParticleSystem* system);
+  void addEmitter(ParticleEmitter* emitter);
+  void addConnection(ParticleEmitter* emitter, ParticleSystem* system);
+  void addConnection(const char* emitter, const char* system);
+
+
+  bool removeSystem(ParticleSystem* system);
+  bool removeEmitter(ParticleEmitter* emitter);
+  bool breakConnection(ParticleConnection* connection);
+  bool breakConnection(ParticleEmitter* emitter, ParticleSystem* system);
+  unsigned int breakConnections(ParticleEmitter* emitter);
+  unsigned int breakConnections(ParticleSystem* system);
+
+   ParticleSystem* getSystemByNumber(unsigned int number) const;
+   ParticleEmitter* getEmitterByNumber(unsigned int number) const;
+
+  void debug();
+
+ private:
+  ParticleEngine();
+  static ParticleEngine* singletonRef;        //!< The reference to the engine.
+
+  tList<ParticleSystem>* systemList;          //!< A list of Systems handled by the ParticleEngine.
+  tList<ParticleEmitter>* emitterList;        //!< A list of Emitters handled by the ParticleEngine.
+
+  tList<ParticleConnection>* connectionList;  //!< A list of Connections between Systems and Emitters.
+};
+
+#endif /* _PARTICLE_ENGINE_H */
Index: branches/network/src/lib/particles/model_particles.cc
===================================================================
--- branches/network/src/lib/particles/model_particles.cc	(revision 6636)
+++ branches/network/src/lib/particles/model_particles.cc	(revision 6636)
@@ -0,0 +1,156 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "model_particles.h"
+
+#include "load_param.h"
+#include "factory.h"
+#include "material.h"
+#include "state.h"
+#include "shell_command.h"
+
+#include "parser/tinyxml/tinyxml.h"
+#include <algorithm>
+
+
+CREATE_FACTORY(ModelParticles, CL_MODEL_PARTICLES);
+
+SHELL_COMMAND(texture, ModelParticles, setMaterialTexture)
+->defaultValues(1, "maps/evil-flower.png");
+
+using namespace std;
+
+/**
+ *  standard constructor
+ * @param maxCount the Count of particles in the System
+ * @param type The Type of the ModelParticles
+*/
+ModelParticles::ModelParticles (unsigned int maxCount)
+    : ParticleSystem(maxCount)
+{
+  this->init();
+}
+
+/**
+ * @brief creates a Particle System out of a XML-element
+ * @param root: the XML-element to load from
+ */
+ModelParticles::ModelParticles(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  standard deconstructor
+*/
+ModelParticles::~ModelParticles()
+{
+  // deleting all the living Particles
+  while (this->particles)
+  {
+    Particle* tmpDelPart = this->particles;
+    this->particles = this->particles->next;
+    delete tmpDelPart;
+  }
+
+  // deleting all the dead particles
+  while (this->deadList)
+  {
+    Particle* tmpDelPart = this->deadList;
+    this->deadList = this->deadList->next;
+    delete tmpDelPart;
+  }
+}
+
+/**
+ * @brief initializes the ModelParticles with default values
+*/
+void ModelParticles::init()
+{
+  this->setClassID(CL_MODEL_PARTICLES, "ModelParticles");
+
+  this->material.setDiffuseMap("maps/radial-trans-noise.png");
+}
+
+
+/**
+ * loads Parameters from a TiXmlElement
+ * @param root the XML-element to load from.
+ */
+void ModelParticles::loadParams(const TiXmlElement* root)
+{
+  ParticleSystem::loadParams(root);
+
+  LoadParam(root, "texture", this, ModelParticles, setMaterialTexture);
+}
+
+/**
+ * @brief sets the Texutre that is placed onto the particles
+ * @param textureFile the Texture to load onto these ModelParticles
+ */
+void ModelParticles::setMaterialTexture(const char* textureFile)
+{
+  this->material.setDiffuseMap(textureFile);
+}
+
+/**
+ * @brief draws all the Particles of this System
+ *
+ * The Cases in this Function all do the same:
+ * Drawing all the particles with the appropriate Type.
+ * This is just the fastest Way to do this, but will most likely be changed in the future.
+ */
+void ModelParticles::draw() const
+{
+  glPushAttrib(GL_ENABLE_BIT);
+  Particle* drawPart = particles;
+
+  GLboolean checkLight = false;
+  glGetBooleanv(GL_LIGHTING, &checkLight);
+  if (checkLight == GL_TRUE)
+    glDisable(GL_LIGHTING);
+  glMatrixMode(GL_MODELVIEW);
+
+  this->material.select();
+  glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
+
+  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+  if (likely(this->getModel() != NULL))
+    while (likely(drawPart != NULL))
+    {
+      glPushMatrix();
+      glMatrixMode(GL_MODELVIEW);
+      /* move */
+      glTranslatef(drawPart->position.x, drawPart->position.y, drawPart->position.z);
+      /* scale */
+      glScalef(drawPart->radius, drawPart->radius, drawPart->radius);
+      /* rotate */
+      Vector tmpRot = drawPart->orientation.getSpacialAxis();
+      glRotatef (drawPart->orientation.getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+
+      this->getModel()->draw();
+
+      glPopMatrix();
+      drawPart = drawPart->next;
+    }
+  else
+    PRINTF(2)("no model loaded onto ParticleSystem-%s\n", this->getName());
+  glPopAttrib();
+}
Index: branches/network/src/lib/particles/model_particles.h
===================================================================
--- branches/network/src/lib/particles/model_particles.h	(revision 6636)
+++ branches/network/src/lib/particles/model_particles.h	(revision 6636)
@@ -0,0 +1,36 @@
+/*!
+ * @file model_particles.h
+
+*/
+
+#ifndef _MODEL_PARTICLE_SYSTEM_H
+#define _MODEL_PARTICLE_SYSTEM_H
+
+#include "particle_system.h"
+#include "material.h"
+
+//! A class to handle ParticleSystems
+class ModelParticles : public ParticleSystem
+{
+public:
+  ModelParticles(unsigned int maxCount = PARTICLE_DEFAULT_MAX_COUNT);
+  ModelParticles(const TiXmlElement* root);
+  virtual ~ModelParticles();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void setMaterialTexture(const char* textureFile);
+
+  /** @returns the Material that lies on this particles */
+  inline const Material* getMaterial() const { return &this->material; };
+
+  virtual void draw() const;
+
+private:
+  void init();
+
+private:
+  Material          material;            //!< A Material for all the Particles.
+};
+
+#endif /* _MODEL_PARTICLE_SYSTEM_H */
Index: branches/network/src/lib/particles/particle_emitter.cc
===================================================================
--- branches/network/src/lib/particles/particle_emitter.cc	(revision 6636)
+++ branches/network/src/lib/particles/particle_emitter.cc	(revision 6636)
@@ -0,0 +1,327 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "particle_emitter.h"
+
+#include "particle_system.h"
+
+#include "load_param.h"
+#include "factory.h"
+#include "debug.h"
+#include "stdlibincl.h"
+
+using namespace std;
+
+
+CREATE_FACTORY(ParticleEmitter, CL_PARTICLE_EMITTER);
+
+/**
+ *  standard constructor
+*/
+ParticleEmitter::ParticleEmitter(const Vector& direction, float angle, float emissionRate,
+                  float velocity)
+{
+  this->init();
+
+  this->direction = direction;
+  this->setSpread(angle);
+  this->setEmissionRate(emissionRate);
+  this->setEmissionVelocity(velocity);
+}
+
+/**
+ *  constructs and loads a ParticleEmitter from a XML-element
+ * @param root the XML-element to load from
+*/
+ParticleEmitter::ParticleEmitter(const TiXmlElement* root)
+{
+  this->init();
+
+   if (root != NULL)
+     this->loadParams(root);
+}
+
+/**
+ *  standard destructor
+
+   removes the EmitterSystem from the ParticleEngine
+*/
+ParticleEmitter::~ParticleEmitter ()
+{
+  this->setSystem(NULL);
+}
+
+/**
+  @brief initializes default values of a ParitcleEmitter
+*/
+void ParticleEmitter::init()
+{
+  this->setClassID(CL_PARTICLE_EMITTER, "ParticleEmitter");
+
+  this->type = PARTICLE_EMITTER_DEFAULT_TYPE;
+  this->emitterSize = PARTICLE_EMITTER_DEFAULT_SIZE;
+  this->setInheritSpeed(PARTICLE_EMITTER_DEFAULT_INHERIT_SPEED);
+  this->setEmissionRate(PARTICLE_EMITTER_DEFAULT_EMISSION_RATE);
+  this->setSize(PARTICLE_EMITTER_DEFAULT_SIZE);
+  this->setEmissionMomentum(0);
+  this->setEmissionVelocity(1.0);
+  this->setSpread(M_PI);
+
+  this->system = NULL;
+
+  this->saveTime = 0.0;
+}
+
+/**
+ *  loads a ParticleEmitter from a XML-element
+ * @param root the XML-element to load from
+*/
+void ParticleEmitter::loadParams(const TiXmlElement* root)
+{
+  PNode::loadParams(root);
+
+  LoadParam(root, "type", this, ParticleEmitter, setType)
+    .describe("What type of emitter is this [dot, plane, cube, sphere].");
+
+  LoadParam(root, "size", this, ParticleEmitter, setSize)
+    .describe("How big the emitter is (no effect on dot-emitters)");
+
+  LoadParam(root, "rate", this, ParticleEmitter, setEmissionRate)
+    .describe("How many particles should be emittet from this emitter");
+
+  LoadParam(root, "inherit-speed", this, ParticleEmitter, setInheritSpeed)
+    .describe("the extent, the speed of the emitter has on the particles");
+
+  LoadParam(root, "emission-velocity", this, ParticleEmitter, setEmissionVelocity)
+    .describe("How fast the particles are emittet (their initial speed)");
+
+  LoadParam(root, "emission-momentum", this, ParticleEmitter, setEmissionMomentum)
+      .describe("How fast the particles rotation is at emissiontime (their initial momentum)");
+
+  LoadParam(root, "spread", this, ParticleEmitter, setSpread)
+    .describe("The angle the particles are emitted from (angle, deviation)");
+
+
+  LoadParam(root, "emission-direction", this, ParticleEmitter, setDirection);
+}
+
+void ParticleEmitter::setSystem(ParticleSystem* system)
+{
+  if (system != NULL)
+    system->addEmitter(this);
+  else if (this->system != NULL)
+    this->system->removeEmitter(this);
+}
+
+/**
+ *  this start the emitter
+*/
+void ParticleEmitter::start() {}
+
+
+/**
+ *  this stops the emitter
+*/
+void ParticleEmitter::stop() {}
+
+
+
+
+
+/**
+ * @param type the new Type of this emitter
+*/
+void ParticleEmitter::setType(EMITTER_TYPE type)
+{
+  this->type = type;
+}
+
+/**
+ *  sets the type of emitter
+ * @param type the type as a const char*
+   dot: EMITTER_DOT, plane: EMITTER_PLANE, cube: EMITTER_CUBE, sphere, EMITTER_SPHERE;
+*/
+void ParticleEmitter::setType(const char* type)
+{
+  if (!strcmp(type, "plane"))
+    this->setType(EMITTER_PLANE);
+  else if (!strcmp(type, "cube"))
+    this->setType(EMITTER_CUBE);
+  else if (!strcmp(type, "sphere"))
+    this->setType(EMITTER_SPHERE);
+  else
+    this->setType(EMITTER_DOT);
+}
+
+const char* ParticleEmitter::getTypeC() const
+{
+  if (this->type == EMITTER_PLANE)
+    return "EMITTER_PLANE";
+  else if (this->type == EMITTER_CUBE)
+    return "EMITTER_CUBE";
+  else if (this->type == EMITTER_SPHERE)
+    return "EMITTER_SPHERE";
+  else
+    return "EMITTER_DOT";
+}
+
+/**
+ *  sets a new size to the emitter
+*/
+void ParticleEmitter::setSize(float emitterSize)
+{
+  if (emitterSize > 0.0)
+    this->emitterSize = emitterSize;
+  else
+    emitterSize = 0.0;
+}
+
+/**
+ *  set the emission rate
+ * @param emissionRate: sets the number of particles emitted per second
+
+   if you want to change the value of this variable during emission time (to make it more dynamic)
+   you may want to use the animation class
+*/
+void ParticleEmitter::setEmissionRate(float emissionRate)
+{
+  if (emissionRate > 0.0)
+    this->emissionRate = emissionRate;
+  else
+    this->emissionRate = 0.0;
+}
+
+/**
+ *  how much of the speed from the ParticleEmitter should flow onto the ParticleSystem
+ * @param value a Value between zero and one
+
+   if you want to change the value of this variable during emission time (to make it more dynamic)
+   you may want to use the animation class
+*/
+void ParticleEmitter::setInheritSpeed(float value)
+{
+  if (unlikely(value > 1.0))
+    this->inheritSpeed = 1;
+  else if (unlikely(value < 0.0))
+    this->inheritSpeed = 0;
+  else
+    this->inheritSpeed = value;
+}
+
+/**
+ *  set the angle of the emitter
+ * @param angle around the direction in which there are particles to be emitted
+ * @param randomAngle A random spread-angle, the +- randomness of this option
+
+   if you want to change the value of this variable during emission time (to make it more dynamic)
+   you may want to use the animation class
+*/
+void ParticleEmitter::setSpread(float angle, float randomAngle)
+{
+  this->angle = angle;
+  this->randomAngle = randomAngle;
+}
+
+/**
+ *  sets the initial velocity of all particles emitted
+ * @param velocity The starting velocity of the emitted particles
+ * @param randomVelocity A random starting velocity, the +- randomness of this option
+
+   if you want to change the value of this variable during emission time (to make it more dynamic)
+   you may want to use the animation class
+*/
+void ParticleEmitter::setEmissionVelocity(float velocity, float randomVelocity)
+{
+  this->velocity = velocity;
+  this->randomVelocity = randomVelocity;
+}
+
+/**
+ *  sets the initial Momentum of all particles emitted
+ * @param momentum the new Momentum (just a float for being not too complicated).
+ * @param randomMomentum variation from the given value.
+ */
+void ParticleEmitter::setEmissionMomentum(float momentum, float randomMomentum)
+{
+  this->momentum = momentum;
+  this->momentumRandom = randomMomentum;
+}
+
+/**
+ *  this set the time to life of a particle, after which it will die
+ * @param dt: the time to live in seconds
+ * @param system: the system into which to emitt
+
+   if you want to change the value of this variable during emission time (to make it more dynamic)
+   you may want to use the animation class
+*/
+void ParticleEmitter::tick(float dt)
+{
+  assert (this->system != NULL);
+  if (likely(dt > 0.0 && this->emissionRate > 0.0))
+  {
+    // saving the time (particles only partly emitted in this timestep)
+    float count = (dt+this->saveTime) * this->emissionRate;
+    this->saveTime = modff(count, &count) / this->emissionRate;
+    PRINTF(5)("emitting %f particles, saving %f seconds for the next timestep\n", count, this->saveTime);
+
+    if (likely(count > 0))
+    {
+      Vector inheritVelocity = this->getVelocity() * this->inheritSpeed;
+      for (int i = 0; i < (int)count; i++)
+      {
+        Vector randDir = Vector(rand()-RAND_MAX/2, rand()-RAND_MAX/2, rand()-RAND_MAX/2);
+        randDir.normalize();
+        randDir = (this->getAbsDir()*Quaternion(angle + randomAngle *((float)rand()/RAND_MAX -.5), randDir)).apply(this->direction);
+        Vector velocityV = randDir.getNormalized()*this->velocity + inheritVelocity;
+
+        // this should spread the Particles evenly. if the Emitter is moved around quickly
+        Vector equalSpread = this->getVelocity() * rand()/RAND_MAX * dt;
+        Vector extension; // the Vector for different fields.
+
+        if (this->type & EMITTER_PLANE)
+        {
+          extension = Vector(this->emitterSize * ((float)rand()/RAND_MAX -.5), 0, this->emitterSize * ((float)rand()/RAND_MAX - .5));
+          extension = this->getAbsDir().apply(extension);
+        }
+        else if (this->type & EMITTER_CUBE)
+        {
+          extension = Vector((float)rand()/RAND_MAX -.5, (float)rand()/RAND_MAX -.5, (float)rand()/RAND_MAX -.5) * this->emitterSize;
+        }
+
+
+        // ROTATIONAL CALCULATION (this must not be done for all types of particles.)
+        randDir = Vector(rand()-RAND_MAX/2, rand()-RAND_MAX/2, rand()-RAND_MAX/2);
+        randDir.normalize();
+        Quaternion orient = Quaternion(M_PI, randDir);
+        Quaternion moment = Quaternion(this->momentum + this->momentumRandom, randDir);
+
+        this->system->addParticle(this->getAbsCoor() + extension - equalSpread, velocityV, orient, moment);
+      }
+    }
+  }
+}
+
+/**
+ *  outputs some nice debug information
+*/
+void ParticleEmitter::debug() const
+{
+  PRINT(0)(" Emitter %s\n", this->getName());
+  PRINT(0)("  EmissionRate: %f, Speed: %f, SpreadAngle: %f\n", this->getEmissionRate(), this->getEmissionVelocity(), this->getSpread());
+  PRINT(0)("  Size %f, Type: %s\n", this->getSize(), this->getTypeC());
+}
Index: branches/network/src/lib/particles/particle_emitter.h
===================================================================
--- branches/network/src/lib/particles/particle_emitter.h	(revision 6636)
+++ branches/network/src/lib/particles/particle_emitter.h	(revision 6636)
@@ -0,0 +1,103 @@
+/*!
+ * @file particle_emitter.h
+  *  Definition of a ParticleEmitter
+*/
+
+#ifndef _PARTICLE_EMITTER_H
+#define _PARTICLE_EMITTER_H
+
+#include "p_node.h"
+
+// FORWARD DECLARATION
+class ParticleSystem;
+class TiXmlElement;
+
+// Default values
+#define PARTICLE_EMITTER_DEFAULT_SIZE              1.0
+#define PARTICLE_EMITTER_DEFAULT_EMISSION_RATE     50
+#define PARTICLE_EMITTER_DEFAULT_TYPE              EMITTER_DOT
+#define PARTICLE_EMITTER_DEFAULT_INHERIT_SPEED     0.0
+#define PARTICLE_EMITTER_DEFAULT_SPREAD            M_PI
+
+//! The form of the Emitter to emit from
+typedef enum EMITTER_TYPE
+{
+  EMITTER_DOT     = 1,
+  EMITTER_PLANE   = 2,
+  EMITTER_SPHERE  = 4,
+  EMITTER_CUBE    = 8
+};
+
+//! A class to handle an Emitter.
+class ParticleEmitter : public PNode
+{
+  friend class ParticleSystem;
+public:
+  ParticleEmitter(const Vector& direction, float angle = .5,
+                  float emissionRate = 1.0, float velocity = 1.0);
+  ParticleEmitter(const TiXmlElement* root);
+  virtual ~ParticleEmitter();
+
+  void init();
+  virtual void loadParams(const TiXmlElement* root);
+
+  /* controlling the emitter: interface */
+  void start();
+  void stop();
+  void tick(float dt);
+
+  void setSystem(ParticleSystem* system);
+  ParticleSystem* getSystem() const { return this->system; };
+
+  /* controlling the behavour: these can be used as Animation interfaces */
+  void setType(EMITTER_TYPE type);
+  void setType(const char* type);
+  void setSize(float emitterSize);
+  void setEmissionRate(float emissionRate);
+  void setInheritSpeed(float value);
+  void setSpread(float angle, float randomAngle = 0.0);
+  void setEmissionVelocity(float velocity, float randomVelocity = 0.0);
+  void setEmissionMomentum(float momentum, float randomMomentum = 0.0);
+
+  void setDirection(float x, float y, float z) { this->direction = Vector(x,y,z); }
+  ; //!< todo this should be done via PNODE
+
+  /** @returns the type of the emitter */
+  inline EMITTER_TYPE getType() const { return this->type; };
+  /** @returns the Type as a const char * */
+  const char* getTypeC() const;
+  /** @returns the Size of the emitter */
+  inline float getSize() const { return this->emitterSize; };
+  /** @returns the emissionRate */
+  inline float getEmissionRate() const { return this->emissionRate; };
+  /** @returns the inherit-speed-factor */
+  inline float getInheritSpeed() const { return this->inheritSpeed; };
+  /** @returns the SpreadAngle of the emitter */
+  inline float getSpread() const { return this->angle; };
+  /** @returns the EmissionVelocity of the emitter */
+  inline float getEmissionVelocity() const { return this->velocity; };
+  /** @returns the EmissionMomentum of this emitter */
+  inline float getEmissionMomentum() const { return this->momentum; };
+
+  void debug() const;
+
+
+private:
+  ParticleSystem* system;            //!< The ParticleSystem this Emitter Emits into.
+
+  EMITTER_TYPE    type;              //!< The type of emitter this is.
+  float           emitterSize;       //!< The size of the emitter (not for EMITTER_DOT).
+  float           inheritSpeed;      //!< How much speed the particle inherits from the Emitters speed.
+  Vector          direction;         //!< emition direction.
+  float           angle;             //!< max angle from the direction of the emitter
+  float           randomAngle;       //!< random emission angle (angle +- angleRandom is the emitted angle.
+  float           emissionRate;      //!< amount of particles per seconds emitted by emitter.
+  float           velocity;          //!< the initial speed of a Particles.
+  float           randomVelocity;    //!< the random variation from the initial Speed.
+  float           momentum;          //!< The Initial spped of the Rotation.
+  float           momentumRandom;    //!< The random variation of the Momentum.
+
+  float           saveTime;          //!< The time that was missing by the last Tick (otherwise there would be no emission when framefate is too big).
+};
+
+#endif /* _PARTICLE_EMITTER_H */
Index: branches/network/src/lib/particles/particle_system.cc
===================================================================
--- branches/network/src/lib/particles/particle_system.cc	(revision 6636)
+++ branches/network/src/lib/particles/particle_system.cc	(revision 6636)
@@ -0,0 +1,488 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "particle_system.h"
+
+#include "particle_emitter.h"
+
+#include "field.h"
+#include "model.h"
+
+#include "load_param.h"
+#include "factory.h"
+#include "material.h"
+#include "state.h"
+#include "shell_command.h"
+
+#include "parser/tinyxml/tinyxml.h"
+#include <algorithm>
+
+using namespace std;
+/**
+ *  standard constructor
+ * @param maxCount the Count of particles in the System
+ * @param type The Type of the ParticleSystem
+*/
+ParticleSystem::ParticleSystem (unsigned int maxCount)
+{
+  this->init();
+
+  this->setMaxCount(maxCount);
+}
+
+/**
+ *  standard deconstructor
+*/
+ParticleSystem::~ParticleSystem()
+{
+  // deleting all the living Particles
+  while (this->particles)
+  {
+    Particle* tmpDelPart = this->particles;
+    this->particles = this->particles->next;
+    delete tmpDelPart;
+  }
+
+  // deleting all the dead particles
+  while (this->deadList)
+  {
+    Particle* tmpDelPart = this->deadList;
+    this->deadList = this->deadList->next;
+    delete tmpDelPart;
+  }
+
+  while(!this->emitters.empty())
+  {
+    this->removeEmitter(this->emitters.front());
+  }
+
+}
+
+/**
+ * @brief initializes the ParticleSystem with default values
+ */
+void ParticleSystem::init()
+{
+  this->setClassID(CL_PARTICLE_SYSTEM, "ParticleSystem");
+
+  this->setMaxCount(PARTICLE_DEFAULT_MAX_COUNT);
+  this->count = 0;
+  this->particles = NULL;
+  this->deadList = NULL;
+  this->setConserve(1);
+  this->setLifeSpan(1);
+
+  this->toList(OM_ENVIRON);
+}
+
+
+/**
+ * loads Parameters from a TiXmlElement
+ * @param root the XML-element to load from.
+ */
+void ParticleSystem::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+  PhysicsInterface::loadParams(root);
+
+  LoadParam(root, "max-count", this, ParticleSystem, setMaxCount)
+  .describe("the maximal count of Particles, that can be emitted into this system");
+
+  LoadParam(root, "life-span", this, ParticleSystem, setLifeSpan)
+  .describe("sets the life-span of the Particles.");
+
+  LoadParam(root, "conserve", this, ParticleSystem, setConserve)
+  .describe("sets the Conserve factor of the Particles (1.0: they keep all their energy, 0.0:they keep no energy)");
+
+  LoadParamXML(root, "emitters", this, ParticleSystem, loadEmitters);
+
+  LOAD_PARAM_START_CYCLE(root, element);
+  {
+    element->ToText();
+    // PER-PARTICLE-ATTRIBUTES:
+    LoadParam_CYCLE(element, "radius", this, ParticleSystem, setRadius)
+    .describe("The Radius of each particle over time (TimeIndex [0-1], radius at TimeIndex, randomRadius at TimeIndex)");
+
+    LoadParam_CYCLE(element, "mass", this, ParticleSystem, setMass)
+    .describe("The Mass of each particle over time (TimeIndex: [0-1], mass at TimeIndex, randomMass at TimeIndex)");
+
+    LoadParam_CYCLE(element, "color", this, ParticleSystem, setColor)
+    .describe("The Color of each particle over time (TimeIndex: [0-1], red: [0-1], green: [0-1], blue: [0-1], alpha: [0-1])");
+  }
+  LOAD_PARAM_END_CYCLE(element);
+
+  LoadParam(root, "precache", this, ParticleSystem, precache)
+      .describe("Precaches the ParticleSystem for %1 seconds, %2 times per Second")
+      .defaultValues(2, 1, 25);
+}
+
+/**
+ * @brief loads the Emitters from An XML-Root
+ * @param root the XML-Element to load all emitters from
+ */
+void ParticleSystem::loadEmitters(const TiXmlElement* root)
+{
+  LOAD_PARAM_START_CYCLE(root, element);
+  {
+    BaseObject* emitter = Factory::fabricate(element);
+    if (emitter->isA(CL_PARTICLE_EMITTER))
+      this->addEmitter(dynamic_cast<ParticleEmitter*>(emitter));
+    else
+    {
+      PRINTF(2)("Tried to load an Element of type '%s' that should be a ParticleEmitter onto '%s::%s'.\n",
+                emitter->getClassName(), this->getClassName(), this->getName());
+      delete emitter;
+    }
+  }
+  LOAD_PARAM_END_CYCLE(element);
+}
+
+/**
+* @param maxCount the maximum count of particles that can be emitted
+ */
+void ParticleSystem::setMaxCount(int maxCount)
+{
+  this->maxCount = maxCount;
+}
+
+// setting properties
+/**
+ *  Sets the lifespan of newly created particles
+*/
+void ParticleSystem::setLifeSpan(float lifeSpan, float randomLifeSpan)
+{
+  this->lifeSpan = lifeSpan;
+  this->randomLifeSpan = randomLifeSpan;
+}
+
+/**
+ *  sets the conserve Factor of newly created particles
+*/
+void ParticleSystem::setConserve(float conserve)
+{
+  if (conserve > 1.0)
+    this->conserve = 1.0;
+  else if (conserve < 0.0)
+    this->conserve = 0.0;
+  else
+    this->conserve = conserve;
+}
+
+/////////////////////////////
+/* Per-Particle Attributes */
+/////////////////////////////
+/**
+ *  sets a key in the radius-animation on a per-particle basis
+ * @param lifeCycleTime the time (partilceLifeTime/particleAge) [0-1]
+ * @param radius the radius at this position
+ * @param randRadius the randRadius at this position
+*/
+void ParticleSystem::setRadius(float lifeCycleTime, float radius, float randRadius)
+{
+  this->radiusAnim.changeEntry(lifeCycleTime, radius);
+  this->randRadiusAnim.changeEntry(lifeCycleTime, randRadius);
+}
+
+/**
+ *  sets a key in the mass-animation on a per-particle basis
+ * @param lifeCycleTime the time (partilceLifeTime/particleAge) [0-1]
+ * @param mass the mass at this position
+ * @param randMass the randomMass at this position
+*/
+void ParticleSystem::setMass(float lifeCycleTime, float mass, float randMass)
+{
+  this->massAnim.changeEntry(lifeCycleTime, mass);
+  this->randMassAnim.changeEntry(lifeCycleTime, randMass);
+}
+
+/**
+ *  sets a key in the color-animation on a per-particle basis
+ * @param lifeCycleTime: the time (partilceLifeTime/particleAge) [0-1]
+ * @param red: red
+ * @param green: green
+ * @param blue: blue
+ * @param alpha: alpha
+*/
+void ParticleSystem::setColor(float lifeCycleTime, float red, float green, float blue, float alpha)
+{
+  this->colorAnim[0].changeEntry(lifeCycleTime, red);
+  this->colorAnim[1].changeEntry(lifeCycleTime, green);
+  this->colorAnim[2].changeEntry(lifeCycleTime, blue);
+  this->colorAnim[3].changeEntry(lifeCycleTime, alpha);
+}
+
+/**
+ * @brief adds an Emitter to this System.
+ * @param emitter the Emitter to add.
+ */
+void ParticleSystem::addEmitter(ParticleEmitter* emitter)
+{
+  assert (emitter != NULL);
+  if (emitter->getSystem() != NULL)
+    emitter->getSystem()->removeEmitter(emitter);
+  emitter->system = this;
+  this->emitters.push_back(emitter);
+}
+
+/**
+ * @brief removes a ParticleEmitter from this System
+ * @param emitter the Emitter to remove
+ */
+void ParticleSystem::removeEmitter(ParticleEmitter* emitter)
+{
+  assert (emitter != NULL);
+  emitter->system = NULL;
+  this->emitters.remove(emitter);
+  /*  std::list<ParticleEmitter*>::iterator it = std::find(this->emitters.begin(), this->emitters.end(), emitter);
+  if (it != this->emitters.end())
+    this->emitters.erase(it);*/
+}
+
+/**
+ * @brief does a Precaching, meaning, that the ParticleSystem(and its emitters) will be ticked force
+ * @param seconds: seconds
+ * @param ticksPerSeconds times per Second.
+ */
+void ParticleSystem::precache(unsigned int seconds, unsigned int ticksPerSecond)
+{
+
+  std::list<ParticleEmitter*>::iterator emitter;
+  for (emitter = this->emitters.begin(); emitter != this->emitters.end(); emitter++)
+    (*emitter)->updateNode(.1), (*emitter)->updateNode(.1);
+
+  PRINTF(4)("Precaching %s::%s %d seconds %d timesPerSecond\n", this->getClassName(), this->getName(), seconds, ticksPerSecond);
+  this->debug();
+  for (unsigned int i = 0; i < seconds*ticksPerSecond; i++)
+    this->tick(1.0/(float)ticksPerSecond);
+}
+
+
+/**
+ *  ticks the system.
+ * @param dt the time to tick all the Particles of the System
+
+   this is used to get all the particles some motion
+*/
+void ParticleSystem::tick(float dt)
+{
+  Particle* tickPart = particles;  // the particle to Tick
+  Particle* prevPart = NULL;
+  while (likely(tickPart != NULL))
+  {
+    // applying force to the System.
+    if (likely (tickPart->mass > 0.0))
+      tickPart->velocity += tickPart->extForce / tickPart->mass * dt;
+    // rendering new position.
+    tickPart->position += tickPart->velocity * dt;
+    tickPart->orientation += tickPart->momentum *dt;
+
+    tickPart->radius = radiusAnim.getValue(tickPart->lifeCycle)
+                       + randRadiusAnim.getValue(tickPart->lifeCycle) * tickPart->radiusRand;
+
+    tickPart->mass = massAnim.getValue(tickPart->lifeCycle)
+                     + randMassAnim.getValue(tickPart->lifeCycle) * tickPart->massRand;
+
+    tickPart->extForce = Vector(0,0,0);
+
+    // applying Color
+    tickPart->color[0] = this->colorAnim[0].getValue(tickPart->lifeCycle);
+    tickPart->color[1] = this->colorAnim[1].getValue(tickPart->lifeCycle);
+    tickPart->color[2] = this->colorAnim[2].getValue(tickPart->lifeCycle);
+    tickPart->color[3] = this->colorAnim[3].getValue(tickPart->lifeCycle);
+
+    // many more to come
+
+    if (this->conserve < 1.0)
+    {
+      tickPart->velocity *= this->conserve;
+      tickPart->momentum *= this->conserve;
+    }
+    // find out if we have to delete tickPart
+    if (unlikely((tickPart->lifeCycle += dt/tickPart->lifeTime) >= 1.0))
+    {
+      // remove the particle from the list
+      if (likely(prevPart != NULL))
+      {
+        prevPart->next = tickPart->next;
+        tickPart->next = this->deadList;
+        this->deadList = tickPart;
+        tickPart = prevPart->next;
+      }
+      else
+      {
+        prevPart = NULL;
+        this->particles = tickPart->next;
+        tickPart->next = this->deadList;
+        this->deadList = tickPart;
+        tickPart = this->particles;
+      }
+      --this->count;
+    }
+    else
+    {
+      prevPart = tickPart;
+      tickPart = tickPart->next;
+    }
+  }
+
+  std::list<ParticleEmitter*>::iterator emitter;
+  for (emitter = this->emitters.begin(); emitter != this->emitters.end(); emitter++)
+    (*emitter)->tick(dt);
+}
+
+/**
+  *  applies some force to a Particle.
+  * @param field the Field to apply.
+ */
+void ParticleSystem::applyField(Field* field)
+{
+  Particle* tickPart = particles;
+  while (tickPart)
+  {
+    tickPart->extForce += field->calcForce(tickPart->position);
+    tickPart = tickPart->next;
+  }
+}
+
+
+/**
+ * @returns the count of Faces of this ParticleSystem
+ */
+unsigned int ParticleSystem::getFaceCount() const
+{
+  return this->count;
+}
+
+
+/**
+ *  draws all the Particles of this System
+
+   The Cases in this Function all do the same:
+   Drawing all the particles with the appropriate Type.
+   This is just the fastest Way to do this, but will most likely be changed in the future.
+ */
+// void ParticleSystem::draw() const
+// {
+//   glPushAttrib(GL_ENABLE_BIT);
+//
+//   Particle* drawPart = particles;
+//
+//   switch (this->particleType)
+//   {
+//
+//     case PARTICLE_MODEL:
+//       {
+//       }
+//       break;
+//
+//     case PARTICLE_DOT:
+//       glDisable(GL_LIGHTING);
+//       glBegin(GL_POINTS);
+//       while (likely(drawPart != NULL))
+//       {
+//         glColor4fv(drawPart->color);
+//
+//         glLineWidth(drawPart->radius);
+//
+//         glVertex3f(drawPart->position.x, drawPart->position.y, drawPart->position.z);
+//         drawPart = drawPart->next;
+//       }
+//       glEnd();
+//       break;
+//   }
+//   glPopAttrib();
+// }
+
+/**
+ *  adds a new Particle to the System
+ * @param position the initial position, where the particle gets emitted.
+ * @param velocity the initial velocity of the particle.
+ * @param orientation the initial orientation of the Paritcle.
+ * @param momentum the initial momentum of the Particle (the speed of its rotation).
+ * @param data some more data given by the emitter
+*/
+void ParticleSystem::addParticle(const Vector& position, const Vector& velocity, const Quaternion& orientation, const Quaternion& momentum, unsigned int data)
+{
+  if (this->count <= this->maxCount)
+  {
+    // if it is the first Particle
+    if (unlikely(particles == NULL))
+    {
+      if (likely(deadList != NULL))
+      {
+        this->particles = this->deadList;
+        deadList = deadList->next;
+      }
+      else
+      {
+        PRINTF(5)("Generating new Particle\n");
+        this->particles = new Particle;
+      }
+      this->particles->next = NULL;
+    }
+    // filling the List from the beginning
+    else
+    {
+      Particle* tmpPart;
+      if (likely(deadList != NULL))
+      {
+        tmpPart = this->deadList;
+        deadList = deadList->next;
+      }
+      else
+      {
+        PRINTF(5)("Generating new Particle\n");
+        tmpPart = new Particle;
+      }
+      tmpPart->next = this->particles;
+      this->particles = tmpPart;
+    }
+    particles->lifeTime = this->lifeSpan + (float)(rand()/RAND_MAX)* this->randomLifeSpan;
+    particles->lifeCycle = 0.0;
+    particles->position = position;
+    particles->velocity = velocity;
+
+    particles->orientation = orientation;
+    particles->momentum = momentum;
+
+    //  particle->rotation = ; //! @todo rotation is once again something to be done.
+    particles->massRand = 2*(float)rand()/RAND_MAX -1;
+    particles->radiusRand = 2* (float)rand()/RAND_MAX -1;
+    particles->mass = this->massAnim.getValue(0.0) + this->randMassAnim.getValue(0.0)*particles->massRand;
+    particles->radius = this->radiusAnim.getValue(0.0) + this->randRadiusAnim.getValue(0.0)*particles->radiusRand;
+
+    ++this->count;
+  }
+  else
+    PRINTF(5)("maximum count of particles reached not adding any more\n");
+}
+
+/**
+ *  outputs some nice debug information
+*/
+void ParticleSystem::debug() const
+{
+  PRINT(0)("  ParticleCount: %d emitters: %d, maximumCount: %d :: filled %d%%\n", this->count, this->emitters.size(), this->maxCount, 100*this->count/this->maxCount);
+  if (deadList)
+  {
+    PRINT(0)("  - ParticleDeadList is used: ");
+    int i = 1;
+    Particle* tmpPart = this->deadList;
+    while (tmpPart = tmpPart->next) ++i;
+    PRINT(0)("count: %d\n", i);
+  }
+}
Index: branches/network/src/lib/particles/particle_system.h
===================================================================
--- branches/network/src/lib/particles/particle_system.h	(revision 6636)
+++ branches/network/src/lib/particles/particle_system.h	(revision 6636)
@@ -0,0 +1,126 @@
+/*!
+ * @file particle_system.h
+
+*/
+
+#ifndef _PARTICLE_SYSTEM_H
+#define _PARTICLE_SYSTEM_H
+
+#include "world_entity.h"
+#include "physics_interface.h"
+
+#include "glincl.h"
+#include "vector.h"
+#include <list>
+
+#include "quick_animation.h"
+
+// Forward Declaration
+class TiXmlElement;
+
+#define PARTICLE_DOT_MASK              0x000001     //!< A Mask if the Particles should be displayed as DOTs
+#define PARTICLE_SPARK_MASK            0x000010     //!< A Mask if the Particles should be displayed as SPARKs
+#define PARTICLE_SPRITE_MASK           0x000100     //!< A Mask if the Particles should be displayed as SPRITESs
+#define PARTICLE_MODEL_MASK            0x001000     //!< A Mask if the Particles should be displayed as MODELSs
+#define PARTICLE_WORDL_ENTITY_MASK     0x010000     //!< A Mask if the Particles should be displayed as WORLD_ENTITIEs
+#define PARTICLE_MULTI_MASK            0x100000     //!< A Mask if they are Multi-partilces
+
+#define PARTICLE_DEFAULT_MAX_COUNT    200               //!< A default count of particles in the system.
+
+// FORWARD DECLARATION
+class Material;
+class ParticleEmitter;
+class Field;
+
+//! A struct for one Particle
+typedef struct Particle
+{
+  float         lifeTime;            //!< The time this particle has to live.
+  float         lifeCycle;           //!< The fraction of time passed. (in percentage of its lifeTime)
+
+  Vector        position;            //!< The current position of this particle.
+  Vector        velocity;            //!< The current velocity of this Particle.
+  Vector        extForce;            //!< The external Force that influences this Particle.
+  Quaternion    orientation;         //!< The current orientation of this Particle.
+  Quaternion    momentum;            //!< The current angular momentum (spin) of this Particle.
+  float         mass;                //!< The mass of this Particle.
+  float         massRand;            //!< A random mass
+  float         radius;              //!< The current size of this Particle.
+  float         radiusRand;          //!< a random Radius
+  GLfloat       color [4];           //!< A Color for the particles.
+
+  Particle*     next;                //!< pointer to the next particle in the List. (NULL if no preceding one)
+};
+
+//! A class to handle ParticleSystems
+class ParticleSystem : public WorldEntity, public PhysicsInterface {
+
+ public:
+  ParticleSystem(unsigned int maxCount = PARTICLE_DEFAULT_MAX_COUNT);
+  virtual ~ParticleSystem();
+
+  void init();
+  virtual void loadParams(const TiXmlElement* root);
+  void loadEmitters(const TiXmlElement* root);
+
+  void setLifeSpan(float lifeSpan, float randomLifeSpan = 0.0);
+  void setConserve(float conserve);
+  void setMaxCount(int maxCount);
+
+  /* Per-Particle-Attributes */
+  void setRadius(float lifeCycleTime, float radius, float randRadius = 0.0);
+  void setMass(float lifeCycleTime, float mass, float randMass = 0.0);
+  void setColor(float lifeCycleTime, float red, float green, float blue, float alpha);
+
+  /** @returns the lifespan of the particles */
+  inline float getLifeSpan() const { return this->lifeSpan; };
+  /** @returns the starting-radius of the particles */
+  inline float getStartRadius() { return this->radiusAnim.getValue(0.0); };
+  /** @returns the end-radius of the particles */
+  inline float getEndRadius() { return this->radiusAnim.getValue(1.0); };
+  /** @returns the conserve-factor of the particles */
+  inline float getConserve() const { return this->conserve; };
+  /** @returns the initial mass of the particles */
+  inline float getMass() const { return this->initialMass; };
+
+  virtual unsigned int getFaceCount() const;
+
+  void addEmitter(ParticleEmitter* emitter);
+  void removeEmitter(ParticleEmitter* emitter);
+
+  virtual void applyField(Field* field);
+  /** @brief this is an empty function, because the Physics are implemented in tick @param dt: useless here */
+  virtual void tickPhys(float dt) {};
+
+  void addParticle(const Vector& position, const Vector& velocity, const Quaternion& orientation, const Quaternion& momentum, unsigned int data = 0);
+
+  void precache(unsigned int seconds, unsigned int ticksPerSecond = 25);
+
+  virtual void tick(float dt);
+  virtual void draw() const = 0;
+
+  void debug() const;
+
+ protected:
+  float             conserve;            //!< How much energy gets conserved to the next Tick.
+  float             lifeSpan;            //!< Initial lifetime of a Particle.
+  float             randomLifeSpan;      //!< A random value for the Lifespan (around the initial lifetime)
+  float             initialMass;         //!< The initial Mass of the Particle
+  float             randomInitialMass;   //!< The random initial Mass of the Particle
+
+  int               maxCount;            //!< The maximum count of Particles.
+  int               count;               //!< The current count of Particles.
+  Particle*         particles;           //!< A list of particles of this System.
+  Particle*         deadList;            //!< A list of dead Particles in the System.
+
+  std::list<ParticleEmitter*> emitters;  //!< The Emitters that do emit into this System.
+
+  // per particle attributes
+  QuickAnimation    radiusAnim;          //!< Animation of the radius
+  QuickAnimation    randRadiusAnim;      //!< Animation of the random Value of the radius
+  QuickAnimation    massAnim;            //!< Animation of the mass
+  QuickAnimation    randMassAnim;        //!< Animation of the random Mass
+  QuickAnimation    colorAnim[4];        //!< Animation of the 4 colors (r,g,b,a)
+};
+
+#endif /* _PARTICLE_SYSTEM_H */
Index: branches/network/src/lib/particles/quick_animation.cc
===================================================================
--- branches/network/src/lib/particles/quick_animation.cc	(revision 6636)
+++ branches/network/src/lib/particles/quick_animation.cc	(revision 6636)
@@ -0,0 +1,243 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: ...
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "quick_animation.h"
+
+#include "compiler.h"
+#include "debug.h"
+#ifndef NULL
+#define NULL 0
+#endif
+
+
+using namespace std;
+
+/**
+ *  standard constructor
+*/
+QuickAnimation::QuickAnimation ()
+{
+   this->setClassID(CL_QUICK_ANIMATION, "QuickAnimation");
+
+   // initialize the First KeyFrame (will be deleted if a new one gets created)
+   this->count = 0;
+   this->first = this->current = new QuickKeyFrame;
+   this->first->next = this->first->prev = this->first;
+   this->first->position = 0.0;
+   this->first->value = 0.0;
+}
+
+/**
+ *  deletes all the deconstructor stuff
+*/
+QuickAnimation::~QuickAnimation ()
+{
+  this->current = this->first;
+  QuickKeyFrame* delKF = this->first;
+
+  do
+  {
+    delKF = this->current;
+    this->current = this->current->next;
+    delete delKF;
+  }  while (this->current != this->first);
+
+}
+
+/**
+ *  adds a new entry to the list of keyframes
+ * @param position the position to add the key to
+ * @param value the Value to set for the position
+ * @returns false if the key existed already for a given position
+*/
+void QuickAnimation::addEntry(float position, float value)
+{
+  // create the new KeyFrame
+  QuickKeyFrame* newKey = new QuickKeyFrame;
+  newKey->position = position;
+  newKey->value = value;
+
+  // if we add a KeyFrame for the first Time:
+  if (unlikely (this->count == 0))
+  {
+    delete this->first;
+
+    newKey->next  = newKey;
+    newKey->prev  = newKey;
+    this->first   = newKey;
+    this->current = newKey;
+  }
+  // if the KeyFrame is in front of the FIRST keyFrame
+  else if (this->first->position > position)
+  {
+    newKey->next = this->first;
+    newKey->prev = this->first->prev;
+    newKey->prev->next = newKey;
+    newKey->next->prev = newKey;
+
+    this->first = newKey; // the new Key becomes the FIRST.
+  }
+  // if the KeyFrame is at the End of the Animation
+  else if (this->first->prev->position < position)
+  {
+    newKey->next = this->first;
+    newKey->prev = this->first->prev;
+    newKey->prev->next = newKey;
+    newKey->next->prev = newKey;
+  }
+  // if the Key is between two frames.
+  else
+  {
+    this->current = this->first;
+    do
+    {
+      if (this->current->position < position && this->current->next->position > position)
+        break;
+      // if it is the same as an already existing keyframe
+      else if (this->current->position == position)
+      {
+        this->current->value = value;
+        delete newKey;
+        return;
+      }
+      this->current = this->current->next;
+    } while (this->current != this->first);
+
+    newKey->next = this->current->next;
+    newKey->prev = this->current;
+    newKey->next->prev = newKey;
+    newKey->prev->next = newKey;
+  }
+  this->current = this->first;
+  ++this->count;
+}
+
+/**
+ *  changes an entry in the region of position
+ * @param position the Position of an existing keyframe
+ * @param region a deviation of the existing keyframe (like a delta in witch to search for
+ * @param value the new Value
+
+   if the Entry at the in the region of the specified position is found, it will be changed.
+    Otherwise a new KeyFrame will be created with value at position.
+   @todo rimplement
+*/
+void QuickAnimation::changeEntry(float position, float value, float region)
+{
+
+  if ((this->first->position > position + region) || this->first->prev->position < position - region || this->count == 0)
+    this->addEntry(position, value);
+  else
+  {
+    this->current = this->first;
+    do
+    {
+      if (this->current->position > position + region)
+      {
+        this->addEntry(position, value);
+        return;
+      }
+      if (this->current->position < position+region && this->current->position > position-region)
+      {
+        this->current->value = value;
+        return;
+      }
+      this->current = this->current->next;
+    }  while (this->current != this->first);
+  }
+}
+
+
+/**
+ * removes a KeyFrame from the List.
+ * @param position
+ * @return
+ */
+void QuickAnimation::removeEntry(float position)
+{
+  this->current = this->first;
+
+  if (this->count <= 0)
+  {
+    this->current->value = 0.0;
+    this->current->position = 0.0;
+    count = 0;
+    return;
+  }
+  else
+  {
+    do
+    {
+      if (this->current->position == position)
+      {
+        if (this->current == this->first)
+          this->first = this->first->next;
+        this->current->next->prev = this->current->prev;
+        this->current->prev->next = this->current->next;
+        delete this->current;
+        break;
+      }
+      this->current = this->current->next;
+    } while (this->current != this->first);
+
+    count --;
+    this->current = this->first;
+  }
+}
+
+
+/**
+ *  returns the value of the animation at a certain position
+ * @param position the position to get the value from :)
+*/
+float QuickAnimation::getValue(float position)
+{
+  while (true)
+  {
+    // if we have a match
+    if (likely(this->current->position <= position && this->current->next->position >= position))
+      return this->current->value + (this->current->next->value - this->current->value)
+          * ((position-this->current->position) / (this->current->next->position -this->current->position));
+
+    else if (unlikely(this->first->prev->position < position))
+      return this->first->prev->value;
+    else if (unlikely(this->first->position > position))
+      return this->first->value;
+    else if(likely(this->current->next->position < position))
+      this->current = this->current->next;
+    else if (likely(this->current->position > position))
+      this->current = this->current->prev;
+  }
+}
+
+/**
+ *  outputs some nice information about this class
+*/
+void QuickAnimation::debug()
+{
+  this->current = this->first;
+
+  PRINT(0)("QuickAnim(entries:%d)::(position, value)", this->count);
+  do
+    {
+      PRINT(0)("->(%f, %f)", this->current->position, this->current->value);
+      this->current = this->current->next;
+    } while(this->current != this->first);
+
+  PRINT(0)("\n");
+  this->current = this->first;
+}
Index: branches/network/src/lib/particles/quick_animation.h
===================================================================
--- branches/network/src/lib/particles/quick_animation.h	(revision 6636)
+++ branches/network/src/lib/particles/quick_animation.h	(revision 6636)
@@ -0,0 +1,59 @@
+/*!
+ * @file quick_animation.h
+  *  Definition of the QuickAnimation-class
+
+*/
+
+#ifndef _QUICK_ANIMATION_H
+#define _QUICK_ANIMATION_H
+
+#include "base_object.h"
+
+// FORWARD DECLARATION
+
+
+
+
+//! A class for that linearely interpolates between multiple values.
+/**
+   to be quick this only has the capability to store very little date
+
+   this class is optimized for a raising value. eg. 100 particles sorted
+   by age.
+*/
+class QuickAnimation : public BaseObject {
+
+ public:
+
+  //! a simple struct that stores keyframes for the QuickAnimation-Class.
+  struct QuickKeyFrame
+  {
+    float            value;             //!< The starting value of this KeyFrame
+    float            position;          //!< The end position of thies KeyFrame
+
+    QuickKeyFrame*   next;              //!< The next Animation
+    QuickKeyFrame*   prev;              //!< The previous QuickKeyFrame
+  };
+
+  QuickAnimation();
+  virtual ~QuickAnimation();
+
+  void addEntry(float position, float value);
+  void changeEntry(float position, float value, float region = .04);
+
+  void removeEntry(float position);
+  /** @todo implemente those functions
+      bool moveEntry(float position);
+  */
+
+  float getValue(float position);
+
+  void debug();
+
+ private:
+  QuickKeyFrame*       first;          //!< The first KeyFrame in a Sequence of Keyframes.
+  QuickKeyFrame*       current;        //!< The currently selected KeyFrame.
+  unsigned int         count;          //!< How many Keyframes the QuickAnimation has.
+};
+
+#endif /* _QUICK_ANIMATION_H */
Index: branches/network/src/lib/particles/spark_particles.cc
===================================================================
--- branches/network/src/lib/particles/spark_particles.cc	(revision 6636)
+++ branches/network/src/lib/particles/spark_particles.cc	(revision 6636)
@@ -0,0 +1,134 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "spark_particles.h"
+
+#include "load_param.h"
+#include "factory.h"
+#include "material.h"
+#include "state.h"
+#include "shell_command.h"
+
+#include "parser/tinyxml/tinyxml.h"
+#include <algorithm>
+
+
+
+using namespace std;
+
+CREATE_FACTORY(SparkParticles, CL_SPARK_PARTICLES);
+
+/**
+ *  standard constructor
+ * @param maxCount the Count of particles in the System
+ * @param type The Type of the SparkParticles
+*/
+SparkParticles::SparkParticles (unsigned int maxCount)
+    : ParticleSystem(maxCount)
+{
+  this->init();
+}
+
+/**
+ * @brief creates a Particle System out of a XML-element
+ * @param root: the XML-element to load from
+ */
+SparkParticles::SparkParticles(const TiXmlElement* root)
+{
+  this->init();
+
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  standard deconstructor
+*/
+SparkParticles::~SparkParticles()
+{
+  // deleting all the living Particles
+  while (this->particles)
+  {
+    Particle* tmpDelPart = this->particles;
+    this->particles = this->particles->next;
+    delete tmpDelPart;
+  }
+
+  // deleting all the dead particles
+  while (this->deadList)
+  {
+    Particle* tmpDelPart = this->deadList;
+    this->deadList = this->deadList->next;
+    delete tmpDelPart;
+  }
+}
+
+/**
+ * @brief initializes the SparkParticles with default values
+*/
+void SparkParticles::init()
+{
+  this->setClassID(CL_SPARK_PARTICLES, "SparkParticles");
+
+  this->material = NULL;
+}
+
+
+/**
+ * loads Parameters from a TiXmlElement
+ * @param root the XML-element to load from.
+ */
+void SparkParticles::loadParams(const TiXmlElement* root)
+{
+  ParticleSystem::loadParams(root);
+}
+
+/**
+ * @brief draws all the Particles of this System
+ *
+ * The Cases in this Function all do the same:
+ * Drawing all the particles with the appropriate Type.
+ * This is just the fastest Way to do this, but will most likely be changed in the future.
+ */
+void SparkParticles::draw() const
+{
+  glPushAttrib(GL_ENABLE_BIT);
+
+  Particle* drawPart = particles;
+
+  glDepthMask(GL_FALSE);
+
+  glDisable(GL_LIGHTING);
+  glEnable(GL_LINE_SMOOTH);
+  glEnable(GL_BLEND);
+  glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
+
+  glBegin(GL_LINES);
+  while (likely(drawPart != NULL))
+  {
+    glColor4fv(drawPart->color);
+    glVertex3f(drawPart->position.x, drawPart->position.y, drawPart->position.z);
+    glVertex3f(drawPart->position.x - drawPart->velocity.x * drawPart->radius,
+               drawPart->position.y - drawPart->velocity.y * drawPart->radius,
+               drawPart->position.z - drawPart->velocity.z * drawPart->radius);
+    drawPart = drawPart->next;
+  }
+  glEnd();
+
+  glDepthMask(GL_TRUE);
+  glPopAttrib();
+}
Index: branches/network/src/lib/particles/spark_particles.h
===================================================================
--- branches/network/src/lib/particles/spark_particles.h	(revision 6636)
+++ branches/network/src/lib/particles/spark_particles.h	(revision 6636)
@@ -0,0 +1,32 @@
+/*!
+ * @file spark_particles.h
+
+*/
+
+#ifndef _SPARK_PARTICLE_SYSTEM_H
+#define _SPARK_PARTICLE_SYSTEM_H
+
+#include "particle_system.h"
+#include "material.h"
+
+//! A class to handle ParticleSystems
+class SparkParticles : public ParticleSystem
+{
+
+public:
+  SparkParticles(unsigned int maxCount = PARTICLE_DEFAULT_MAX_COUNT);
+  SparkParticles(const TiXmlElement* root);
+  virtual ~SparkParticles();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  virtual void draw() const;
+
+private:
+  void init();
+
+private:
+  Material          material;            //!< A Material for all the Particles.
+};
+
+#endif /* _SPARK_PARTICLE_SYSTEM_H */
Index: branches/network/src/lib/particles/sprite_particles.cc
===================================================================
--- branches/network/src/lib/particles/sprite_particles.cc	(revision 6636)
+++ branches/network/src/lib/particles/sprite_particles.cc	(revision 6636)
@@ -0,0 +1,180 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GRAPHICS
+
+#include "sprite_particles.h"
+
+#include "load_param.h"
+#include "factory.h"
+#include "material.h"
+#include "state.h"
+#include "shell_command.h"
+
+#include "parser/tinyxml/tinyxml.h"
+#include <algorithm>
+
+
+CREATE_FACTORY(SpriteParticles, CL_SPRITE_PARTICLES);
+
+SHELL_COMMAND(texture, SpriteParticles, setMaterialTexture)
+    ->defaultValues(1, "maps/evil-flower.png");
+
+using namespace std;
+
+/**
+ *  standard constructor
+ * @param maxCount the Count of particles in the System
+ * @param type The Type of the SpriteParticles
+*/
+SpriteParticles::SpriteParticles (unsigned int maxCount)
+  : ParticleSystem(maxCount)
+{
+  this->init();
+}
+
+/**
+ * @brief creates a Particle System out of a XML-element
+ * @param root: the XML-element to load from
+ */
+SpriteParticles::SpriteParticles(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  standard deconstructor
+*/
+SpriteParticles::~SpriteParticles()
+{
+  // deleting all the living Particles
+  while (this->particles)
+  {
+    Particle* tmpDelPart = this->particles;
+    this->particles = this->particles->next;
+    delete tmpDelPart;
+  }
+
+  // deleting all the dead particles
+  while (this->deadList)
+  {
+    Particle* tmpDelPart = this->deadList;
+    this->deadList = this->deadList->next;
+    delete tmpDelPart;
+  }
+}
+
+/**
+ * @brief initializes the SpriteParticles with default values
+*/
+void SpriteParticles::init()
+{
+  this->setClassID(CL_SPRITE_PARTICLES, "SpriteParticles");
+
+  this->material.setDiffuseMap("maps/radial-trans-noise.png");
+}
+
+
+/**
+ * loads Parameters from a TiXmlElement
+ * @param root the XML-element to load from.
+ */
+void SpriteParticles::loadParams(const TiXmlElement* root)
+{
+  ParticleSystem::loadParams(root);
+
+  LoadParam(root, "texture", this, SpriteParticles, setMaterialTexture);
+}
+
+/**
+ * @brief sets the Texutre that is placed onto the particles
+ * @param textureFile the Texture to load onto these SpriteParticles
+ */
+void SpriteParticles::setMaterialTexture(const char* textureFile)
+{
+  this->material.setDiffuseMap(textureFile);
+}
+
+/**
+ * @brief draws all the Particles of this System
+ *
+ * The Cases in this Function all do the same:
+ * Drawing all the particles with the appropriate Type.
+ * This is just the fastest Way to do this, but will most likely be changed in the future.
+ */
+void SpriteParticles::draw() const
+{
+  glPushAttrib(GL_ENABLE_BIT);
+
+  Particle* drawPart = particles;
+
+  GLboolean checkLight = false;
+  glGetBooleanv(GL_LIGHTING, &checkLight);
+  if (checkLight == GL_TRUE)
+    glDisable(GL_LIGHTING);
+  glMatrixMode(GL_MODELVIEW);
+  glDepthMask(GL_FALSE);
+
+  material.select();
+  glBlendFunc(GL_SRC_ALPHA, GL_DST_ALPHA);
+
+  //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+
+  while (likely(drawPart != NULL))
+  {
+    glColor4fv(drawPart->color);
+    //! @todo implement a faster code for the look-at Camera algorithm.
+
+    const PNode* camera = State::getCamera();  //!< @todo MUST be different
+    Vector cameraPos = camera->getAbsCoor();
+    Vector cameraTargetPos = State::getCameraTarget()->getAbsCoor();
+    Vector view = cameraTargetPos - cameraPos;
+    Vector up = Vector(0, 1, 0);
+    up = camera->getAbsDir().apply(up);
+    Vector h = up.cross(view);
+    Vector v = h.cross(view);
+    h.normalize();
+    v.normalize();
+    v *= .5 * drawPart->radius;
+    h *= .5 * drawPart->radius;
+
+    glBegin(GL_TRIANGLE_STRIP);
+    glTexCoord2i(1, 1);
+    glVertex3f(drawPart->position.x - h.x - v.x,
+               drawPart->position.y - h.y - v.y,
+               drawPart->position.z - h.z - v.z);
+    glTexCoord2i(0, 1);
+    glVertex3f(drawPart->position.x - h.x + v.x,
+               drawPart->position.y - h.y + v.y,
+               drawPart->position.z - h.z + v.z);
+    glTexCoord2i(1, 0);
+    glVertex3f(drawPart->position.x + h.x - v.x,
+               drawPart->position.y + h.y - v.y,
+               drawPart->position.z + h.z - v.z);
+    glTexCoord2i(0, 0);
+    glVertex3f(drawPart->position.x + h.x + v.x,
+               drawPart->position.y + h.y + v.y,
+               drawPart->position.z + h.z + v.z);
+
+    glEnd();
+
+    drawPart = drawPart->next;
+  }
+  glDepthMask(GL_TRUE);
+  glPopAttrib();
+}
Index: branches/network/src/lib/particles/sprite_particles.h
===================================================================
--- branches/network/src/lib/particles/sprite_particles.h	(revision 6636)
+++ branches/network/src/lib/particles/sprite_particles.h	(revision 6636)
@@ -0,0 +1,37 @@
+/*!
+ * @file sprite_particles.h
+
+*/
+
+#ifndef _SPRITE_PARTICLE_SYSTEM_H
+#define _SPRITE_PARTICLE_SYSTEM_H
+
+#include "particle_system.h"
+#include "material.h"
+
+//! A class to handle ParticleSystems
+class SpriteParticles : public ParticleSystem
+{
+
+public:
+  SpriteParticles(unsigned int maxCount = PARTICLE_DEFAULT_MAX_COUNT);
+  SpriteParticles(const TiXmlElement* root);
+  virtual ~SpriteParticles();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void setMaterialTexture(const char* textureFile);
+
+  /** @returns the Material that lies on this particles */
+  inline const Material* getMaterial() const { return &this->material; };
+
+  virtual void draw() const;
+
+private:
+  void init();
+
+private:
+  Material          material;            //!< A Material for all the Particles.
+};
+
+#endif /* _SPRITE_PARTICLE_SYSTEM_H */
Index: branches/network/src/lib/physics/Makefile.am
===================================================================
--- branches/network/src/lib/physics/Makefile.am	(revision 6636)
+++ branches/network/src/lib/physics/Makefile.am	(revision 6636)
@@ -0,0 +1,21 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXphysics.a
+
+libORXphysics_a_SOURCES = physics_interface.cc \
+                          physics_connection.cc \
+                          physics_engine.cc \
+                          fields/field.cc \
+                          fields/gravity.cc \
+                          fields/point_gravity.cc \
+                          fields/twirl.cc
+
+noinst_HEADERS= physics_interface.h \
+                physics_connection.h \
+                physics_engine.h \
+                fields/fields.h \
+                fields/field.h \
+                fields/gravity.h \
+                fields/point_gravity.h \
+                fields/twirl.h
Index: branches/network/src/lib/physics/fields/field.cc
===================================================================
--- branches/network/src/lib/physics/fields/field.cc	(revision 6636)
+++ branches/network/src/lib/physics/fields/field.cc	(revision 6636)
@@ -0,0 +1,85 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_PHYSICS
+
+#include "field.h"
+
+#include "physics_engine.h"
+
+#include "factory.h"
+#include "load_param.h"
+using namespace std;
+
+/**
+ *  standard constructor
+*/
+Field::Field ()
+{
+  this->init();
+}
+
+/**
+ *  standard deconstructor
+
+*/
+Field::~Field ()
+{
+   PhysicsEngine::getInstance()->removeField(this);
+}
+
+/**
+  \brief initializes a Field
+*/
+void Field::init()
+{
+  this->setClassID(CL_FIELD, "Field");
+  this->setMagnitude(1);
+  this->setAttenuation(0);
+
+  PhysicsEngine::getInstance()->addField(this);
+}
+
+/**
+* @param root The XML-element to load settings from
+ */
+void Field::loadParams(const TiXmlElement* root)
+{
+  PNode::loadParams(root);
+
+  LoadParam(root, "magnitude", this, Field, setMagnitude)
+      .describe("sets the magnitude of this Field")
+      .defaultValues(1, 1);
+
+  LoadParam(root, "attenuation", this, Field, setAttenuation)
+      .describe("sets the attenuation of this Field.");
+
+}
+
+/**
+ * @param magnitude the magnitude of the Field.
+*/
+void Field::setMagnitude(float magnitude)
+{
+  this->magnitude = magnitude;
+}
+
+/**
+ * @param attenuation The attenuation of the Field (the bigger the smaller the region of influence)
+*/
+void Field::setAttenuation(float attenuation)
+{
+  this->attenuation = attenuation;
+}
Index: branches/network/src/lib/physics/fields/field.h
===================================================================
--- branches/network/src/lib/physics/fields/field.h	(revision 6636)
+++ branches/network/src/lib/physics/fields/field.h	(revision 6636)
@@ -0,0 +1,62 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+/*!
+ * @file field.h
+  *  abstract definition of a Physical Field
+
+    This is a totally abstract class, that only enables different Physical Fields to
+    exist on a common Level.
+*/
+
+#ifndef _FIELD_H
+#define _FIELD_H
+
+#include "p_node.h"
+
+// FORWARD DECLARATION
+class TiXmlElement;
+
+
+//! An abstract class that represents a Force.
+class Field : public PNode
+{
+ public:
+  Field();
+  virtual ~Field();
+
+  void init();
+  virtual void loadParams(const TiXmlElement* root);
+
+  /**
+    * @param data This is the data given to this force, to calculate the ForceVector
+    * @returns The Force Vector
+  */
+  virtual Vector calcForce(const Vector& data) const = 0;
+
+  void setMagnitude(float magnitude);
+  /** @returns The Magnitude of the Field */
+  inline const float& getMagnitude() const {return this->magnitude;}
+
+  void setAttenuation(float attenuation);
+  /** @returns The Attenuation of the Fiels */
+  inline const float& getAttenuation() const {return this->attenuation;}
+
+ private:
+  float magnitude;                //!< The strength of the field
+  float attenuation;              //!< The Attenuation (the bigger the shorter the influenced distance).
+};
+
+#endif /* _FIELD_H */
Index: branches/network/src/lib/physics/fields/fields.h
===================================================================
--- branches/network/src/lib/physics/fields/fields.h	(revision 6636)
+++ branches/network/src/lib/physics/fields/fields.h	(revision 6636)
@@ -0,0 +1,40 @@
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+/*! 
+ * @file fields.h
+  *  collection of all Headers of all the different fileds there are in the 
+    PhysicsEngine
+*/
+
+
+#ifndef _FILEDS_H
+#define _FIELDS_H
+
+/* The superclass */
+#include "field.h"
+
+/* subclasses Fields without Position */
+#include "gravity.h"
+
+/* subclasses of field with position */
+#include "point_gravity.h"
+#include "twirl.h"
+
+/* many more fields */
+
+
+
+#endif /* _FIELDS_H */
Index: branches/network/src/lib/physics/fields/gravity.cc
===================================================================
--- branches/network/src/lib/physics/fields/gravity.cc	(revision 6636)
+++ branches/network/src/lib/physics/fields/gravity.cc	(revision 6636)
@@ -0,0 +1,59 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_PHYSICS
+
+#include "gravity.h"
+
+#include "load_param.h"
+#include "factory.h"
+
+using namespace std;
+
+CREATE_FACTORY(Gravity, CL_FIELD_GRAVITY);
+
+Gravity::Gravity(const TiXmlElement* root)
+{
+  this->setClassID(CL_FIELD_GRAVITY, "Gravity");
+
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  standard deconstructor
+
+*/
+Gravity::~Gravity ()
+{
+  // delete what has to be deleted here
+}
+
+void Gravity::loadParams(const TiXmlElement* root)
+{
+  Field::loadParams(root);
+}
+
+/**
+ *  calculates the Gravity on any point in space
+ * @param data The Position of the Point in space to attache gravity to.
+ * @returns The force.
+*/
+Vector Gravity::calcForce(const Vector& data) const
+{
+  return Vector(0,-1,0) * this->getMagnitude();
+}
+
+
Index: branches/network/src/lib/physics/fields/gravity.h
===================================================================
--- branches/network/src/lib/physics/fields/gravity.h	(revision 6636)
+++ branches/network/src/lib/physics/fields/gravity.h	(revision 6636)
@@ -0,0 +1,31 @@
+/*!
+ * @file gravity.h
+  *  Definition of ...
+
+*/
+
+#ifndef _GRAVITY_H
+#define _GRAVITY_H
+
+#include "field.h"
+
+// FORWARD DECLARATION
+
+
+
+//! A class for ...
+class Gravity : public Field {
+
+ public:
+  Gravity(const TiXmlElement* root = NULL);
+  virtual ~Gravity();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  virtual Vector calcForce(const Vector& data) const;
+
+ private:
+
+};
+
+#endif /* _GRAVITY_H */
Index: branches/network/src/lib/physics/fields/point_gravity.cc
===================================================================
--- branches/network/src/lib/physics/fields/point_gravity.cc	(revision 6636)
+++ branches/network/src/lib/physics/fields/point_gravity.cc	(revision 6636)
@@ -0,0 +1,52 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: ...
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_PHYSICS
+
+#include "point_gravity.h"
+
+using namespace std;
+
+
+/**
+ *  standard constructor
+   @todo this constructor is not jet implemented - do it
+*/
+PointGravity::PointGravity ()
+{
+   this->setClassID(CL_FIELD_POINT_GRAVITY, "PointGravity");
+}
+
+
+/**
+ *  standard deconstructor
+
+*/
+PointGravity::~PointGravity ()
+{
+  // delete what has to be deleted here
+}
+
+/**
+ *  calculates the PointGravity on any point in space
+ * @param data The Position of the Point in space to attache PointGravity to.
+ * @returns The force.
+*/
+Vector PointGravity::calcForce(const Vector& data) const
+{
+  return (this->getAbsCoor() - data) * this->getMagnitude();
+}
+
+
Index: branches/network/src/lib/physics/fields/point_gravity.h
===================================================================
--- branches/network/src/lib/physics/fields/point_gravity.h	(revision 6636)
+++ branches/network/src/lib/physics/fields/point_gravity.h	(revision 6636)
@@ -0,0 +1,29 @@
+/*! 
+ * @file point_gravity.h
+  *  Definition of ...
+
+*/
+
+#ifndef _POINT_GRAVITY_H
+#define _POINT_GRAVITY_H
+
+#include "field.h"
+
+// FORWARD DECLARATION
+
+
+
+//! A class for ...
+class PointGravity : public Field {
+
+ public:
+  PointGravity();
+  virtual ~PointGravity();
+
+  virtual Vector calcForce(const Vector& data) const;
+
+ private:
+
+};
+
+#endif /* _POINT_GRAVITY_H */
Index: branches/network/src/lib/physics/fields/twirl.cc
===================================================================
--- branches/network/src/lib/physics/fields/twirl.cc	(revision 6636)
+++ branches/network/src/lib/physics/fields/twirl.cc	(revision 6636)
@@ -0,0 +1,53 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: ...
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_PHYSICS
+
+#include "twirl.h"
+
+using namespace std;
+
+
+/**
+ *  standard constructor
+   @todo this constructor is not jet implemented - do it
+*/
+Twirl::Twirl ()
+{
+   this->setClassID(CL_FIELD_TWIRL, "Twirl");
+}
+
+
+/**
+ *  standard deconstructor
+
+*/
+Twirl::~Twirl ()
+{
+  // delete what has to be deleted here
+}
+
+/**
+ *  calculates the Twirl on any point in space
+ * @param data The Position of the Point in space to attache twirl to.
+ * @returns The force.
+*/
+Vector Twirl::calcForce(const Vector& data) const
+{
+  return /*this->getAbsDir()*/ Vector(0,1,0).cross(this->getAbsCoor() - data)
+    * this->getMagnitude();
+}
+
+
Index: branches/network/src/lib/physics/fields/twirl.h
===================================================================
--- branches/network/src/lib/physics/fields/twirl.h	(revision 6636)
+++ branches/network/src/lib/physics/fields/twirl.h	(revision 6636)
@@ -0,0 +1,29 @@
+/*! 
+ * @file twirl.h
+  *  Definition of ...
+
+*/
+
+#ifndef _TWIRL_H
+#define _TWIRL_H
+
+#include "field.h"
+
+// FORWARD DECLARATION
+
+
+
+//! A class for ...
+class Twirl : public Field {
+
+ public:
+  Twirl();
+  virtual ~Twirl();
+
+  virtual Vector calcForce(const Vector& data) const;
+
+ private:
+
+};
+
+#endif /* _TWIRL_H */
Index: branches/network/src/lib/physics/physics_connection.cc
===================================================================
--- branches/network/src/lib/physics/physics_connection.cc	(revision 6636)
+++ branches/network/src/lib/physics/physics_connection.cc	(revision 6636)
@@ -0,0 +1,110 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_PHYSICS
+
+#include "physics_connection.h"
+
+#include "physics_engine.h"
+
+#include "field.h"
+#include "particle_system.h"
+#include "physics_interface.h"
+
+#include "factory.h"
+#include "load_param.h"
+
+using namespace std;
+
+CREATE_FACTORY(PhysicsConnection, CL_PHYSICS_CONNECTION);
+
+/**
+ *  creates a PhysicsConnection
+*/
+PhysicsConnection::PhysicsConnection(PhysicsInterface* subject, Field* field)
+{
+  this->setClassID(CL_PHYSICS_CONNECTION, "PhysicsConnection");
+  this->type = PCON_PhysIField;
+
+  this->subject = subject;
+  this->field = field;
+
+  PhysicsEngine::getInstance()->addConnection(this);
+}
+
+PhysicsConnection::PhysicsConnection(const TiXmlElement* root)
+{
+  this->setClassID(CL_PHYSICS_CONNECTION, "PhysicsConnection");
+  this->type = PCON_PhysIField;
+
+  BaseObject::loadParams(root);
+
+  LoadParam(root, "subject", this, PhysicsConnection, setSubject)
+      .describe("set the subject by a name");
+
+  LoadParam(root, "field", this, PhysicsConnection, setField)
+      .describe("set the field by name");
+
+  PhysicsEngine::getInstance()->addConnection(this);
+}
+
+/**
+ *  standard deconstructor
+
+*/
+PhysicsConnection::~PhysicsConnection ()
+{
+  PhysicsEngine::getInstance()->removeConnection(this);
+}
+
+/**
+ * @param subjectName the name of the Subject for this PhysicsConnection
+*/
+void PhysicsConnection::setSubject(const char* subjectName)
+{
+  this->subject = PhysicsEngine::getInstance()->getPhysicsInterfaceByName(subjectName);
+  if (this->subject == NULL)
+  {
+    PRINTF(2)("subject: (%s) not found for PhysicsConnection\n", subjectName);
+  }
+  else
+    PRINTF(5)("subject::%s\n", this->subject->getName());
+}
+
+/**
+* @param fieldName the Name of the Field for this connection
+*/
+void PhysicsConnection::setField(const char* fieldName)
+{
+  this->field = PhysicsEngine::getInstance()->getFieldByName(fieldName);
+  if (this->field == NULL)
+  {
+        PRINTF(2)("field: (%s) not found for PhysicsConnection\n", fieldName);
+  }
+  else
+    PRINTF(5)("field::%s\n", this->field->getName());
+
+}
+
+/**
+  *  applies the Force to some Object.
+*/
+void PhysicsConnection::apply() const
+{
+  if (likely(this->type == PCON_PhysIField && this->field->getMagnitude() != 0.0
+      && this->subject != NULL && this->field != NULL))
+      this->subject->applyField(this->field);
+  else ;
+}
Index: branches/network/src/lib/physics/physics_connection.h
===================================================================
--- branches/network/src/lib/physics/physics_connection.h	(revision 6636)
+++ branches/network/src/lib/physics/physics_connection.h	(revision 6636)
@@ -0,0 +1,51 @@
+/*!
+ * @file physics_connection.h
+ *  Definition of The Physical Connection Class.
+ * @todo
+*/
+
+#ifndef _PHYSICS_CONNECTION_H
+#define _PHYSICS_CONNECTION_H
+
+#include "base_object.h"
+// Forward Declaration
+class PhysicsInterface;
+class ParticleSystem;
+class Field;
+
+//! An enumerator for different ConnectionTypes
+typedef enum PCON_Type
+{
+  PCON_PhysIPhysI = 1,
+  PCON_PhysIField = 2
+};
+
+
+// Forward Declaration
+
+//! A class that Handles Physical Connection between different subjects
+class PhysicsConnection : public BaseObject
+{
+
+ public:
+  PhysicsConnection(PhysicsInterface* subject, Field* field);
+  //  PhysicsConnection(PhysicsInterface* partnerOne, PhysicsInterface* partnerTwo);
+  PhysicsConnection(const TiXmlElement* root);
+
+  virtual ~PhysicsConnection();
+
+  void setSubject(const char* subjectName);
+  void setField(const char* fieldName);
+
+  void apply() const;
+
+ private:
+  PCON_Type type;                    //!< What kind of connection this is.
+
+  PhysicsInterface* subject;         //!< The main Subject of this Connection.
+  PhysicsInterface* partner2;        //!< The second partner of this Connection.
+
+  Field* field;                      //!< The field to connect either subject of ParticleSystem to.
+};
+
+#endif /* _PHYSICS_CONNECTION_H */
Index: branches/network/src/lib/physics/physics_engine.cc
===================================================================
--- branches/network/src/lib/physics/physics_engine.cc	(revision 6636)
+++ branches/network/src/lib/physics/physics_engine.cc	(revision 6636)
@@ -0,0 +1,251 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: ...
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_PHYSICS
+
+#include "physics_engine.h"
+
+#include "class_list.h"
+#include "list.h"
+#include "parser/tinyxml/tinyxml.h"
+#include "factory.h"
+#include "load_param.h"
+
+using namespace std;
+
+
+/**
+ *  standard constructor
+*/
+PhysicsEngine::PhysicsEngine()
+{
+  this->setClassID(CL_PHYSICS_ENGINE, "PhysicsEngine");
+  this->setName("PhysicsEngine");
+  this->interfaces = NULL;
+}
+
+/**
+ *  the singleton reference to this class
+*/
+PhysicsEngine* PhysicsEngine::singletonRef = NULL;
+
+/**
+ *  standard deconstructor
+
+*/
+PhysicsEngine::~PhysicsEngine()
+{
+  // delete all PhysicsConnections that are still in existence
+  while (this->connections.size() > 0)
+  {
+    PhysicsConnection* connection = this->connections.front();
+    this->connections.pop_front();
+    delete connection;
+  }
+//
+//   // delete all PhysicsInterfaces, still in existence (this could be dangerous)
+//   tIterator<PhysicsInterface>* itPI = this->interfaces->getIterator();
+//   PhysicsInterface* enumPI = itPI->firstElement();
+//   while (enumPI)
+//   {
+//     delete enumPI;
+//
+//     enumPI = itPI->nextElement();
+//   }
+//   delete itPI;
+//
+//   // delete all PhysicsFields, still in existence (this could be dangerous)
+//   tIterator<Field>* itF = this->fields->getIterator();
+//   Field* enumF = itF->firstElement();
+//   while (enumF)
+//   {
+//     delete enumF;
+//
+//     enumF = itF->nextElement();
+//   }
+//   delete itF;
+
+  PhysicsEngine::singletonRef = NULL;
+}
+
+/**
+* @param root the XML-element to load settings from
+ */
+void PhysicsEngine::loadParams(const TiXmlElement* root)
+{
+  LoadParamXML(root, "Fields", this, PhysicsEngine, loadFields)
+      .describe("loads a list of fields");
+
+  LoadParamXML(root, "Connections", this, PhysicsEngine, loadConnections)
+      .describe("loads a list of fields");
+}
+
+/**
+ * @param root the XML-element to Load the PhysicsField from
+ */
+void PhysicsEngine::loadFields(const TiXmlElement* root)
+{
+  PRINTF(4)("Loading Physical Fields\n");
+
+  const TiXmlElement* element = root->FirstChildElement();
+  while (element != NULL)
+  {
+    Factory::fabricate(element);
+
+    element = element->NextSiblingElement();
+  }
+}
+
+/**
+ * @param root the XML-element to load the PhysicsConnection from
+ */
+void PhysicsEngine::loadConnections(const TiXmlElement* root)
+{
+  PRINTF(4)("Loading Physical Connections\n");
+
+  const TiXmlElement* element = root->FirstChildElement();
+  while (element != NULL)
+  {
+    Factory::fabricate(element);
+
+    element = element->NextSiblingElement();
+  }
+}
+
+/**
+* @param physicsInterfaceName the Name of the PhysicsInterface to search for
+  @returns the PhysicsInterface if found, or NULL if not
+ */
+PhysicsInterface* PhysicsEngine::getPhysicsInterfaceByName(const char* physicsInterfaceName) const
+{
+  BaseObject* interface = ClassList::getObject(physicsInterfaceName, CL_PHYSICS_INTERFACE);
+  return (interface != NULL)?  dynamic_cast<PhysicsInterface*>(interface) : NULL;
+}
+
+/**
+ *  adds a Field to the list of handeled fields
+ * @param field the field to add
+
+   this is normally done in the constructor of any Field
+*/
+void PhysicsEngine::addField(Field* field)
+{
+  this->fields.push_back(field);
+}
+
+/**
+ *  removes a Field from the list of handeled fields
+ * @param field the field to remove
+
+   this is normally done in the destructor of any Field
+*/
+void PhysicsEngine::removeField(Field* field)
+{
+  this->fields.remove(field);
+}
+
+/**
+* @param FieldName the Name of the PhysicsInterface to search for
+  @returns the Field if found, or NULL if not
+ */
+Field* PhysicsEngine::getFieldByName(const char* FieldName) const
+{
+  list<Field*>::const_iterator field;
+  for (field = this->fields.begin(); field != this->fields.end(); field++)
+    if (!strcmp(FieldName, (*field)->getName()))
+      return (*field);
+  return NULL;
+}
+
+
+
+/**
+ *  adds A Physical Connection to the List of Connections
+ * @param connection the Connection to add
+
+   Usually this is done through the constructor of PhysicshConnections
+*/
+void PhysicsEngine::addConnection(PhysicsConnection* connection)
+{
+  this->connections.push_back(connection);
+}
+
+/**
+ *  removes A Physical Connection from the List of Connections
+ * @param connection the Connection to remove
+
+   Usually this is done through the destructor of PhysicsConnections
+*/
+void PhysicsEngine::removeConnection(PhysicsConnection* connection)
+{
+  this->connections.remove(connection);
+}
+
+/**
+* @param physicsConnectionName the Name of the PhysicsInterface to search for
+  @returns the PhysicsConnection if found, or NULL if not
+ */
+PhysicsConnection* PhysicsEngine::getPhysicsConnectionByName(const char* physicsConnectionName) const
+{
+  list<PhysicsConnection*>::const_iterator pc;
+  for (pc = this->connections.begin(); pc != this->connections.end(); pc++)
+    if (!strcmp(physicsConnectionName, (*pc)->getName()))
+      delete (*pc);
+  return NULL;
+}
+
+
+
+/**
+ *  Steps through all the Connections and Ticks them
+ * @param dt The time Passed in Seconds
+
+   This function brings a flow into the whole animation
+*/
+void PhysicsEngine::tick(float dt)
+{
+  /* go through all the PhysicsInterface(s) and tick them,
+  meaning let the fields work */
+  list<PhysicsConnection*>::iterator pc;
+  for (pc = this->connections.begin(); pc != this->connections.end(); pc++)
+    (*pc)->apply();
+
+  /* actually tick all the PhysicsInterfaces. Move the objects around */
+  if (this->interfaces != NULL || (this->interfaces = ClassList::getList(CL_PHYSICS_INTERFACE)) != NULL)
+  {
+    list<BaseObject*>::const_iterator tickPhys;
+    for (tickPhys = this->interfaces->begin(); tickPhys != this->interfaces->end(); tickPhys++)
+      dynamic_cast<PhysicsInterface*>(*tickPhys)->tickPhys(dt);
+  }
+}
+
+
+
+/**
+ *  print out interesting debug information of this class
+*/
+void PhysicsEngine::debug() const
+{
+  PRINT(0)("====================================\n");
+  PRINT(0)("= Physics-Engine debug information =\n");
+  PRINT(0)("====================================\n");
+  PRINT(0)(" reference: %p\n", this);
+  if (this->interfaces != NULL)
+    PRINT(0)(" number of Interfaces: %d\n", this->interfaces->size());
+  PRINT(0)(" number of Fields: %d\n", this->fields.size());
+  PRINT(0)(" number of Connections: %d\n", this->connections.size());
+
+  PRINT(0)("==============================PHYS==\n");
+}
Index: branches/network/src/lib/physics/physics_engine.h
===================================================================
--- branches/network/src/lib/physics/physics_engine.h	(revision 6636)
+++ branches/network/src/lib/physics/physics_engine.h	(revision 6636)
@@ -0,0 +1,61 @@
+/*!
+ * @file physics_engine.h
+  *  Definition of the PhysicsEngine-singleton Class
+
+*/
+
+#ifndef _PHYSICS_ENGINE_H
+#define _PHYSICS_ENGINE_H
+
+#include "base_object.h"
+
+#include "physics_connection.h"
+#include "physics_interface.h"
+#include "field.h"
+#include <list>
+
+// Forward Declaration
+template<class T> class tList;
+class TiXmlElement;
+
+//! A class, that brings things into motion through Physics.
+class PhysicsEngine : public BaseObject {
+
+ public:
+  virtual ~PhysicsEngine();
+  /** @returns a Pointer to the only object of this Class */
+  inline static PhysicsEngine* getInstance() { if (!singletonRef) singletonRef = new PhysicsEngine();  return singletonRef; };
+
+  virtual void loadParams(const TiXmlElement* root);
+  void loadFields(const TiXmlElement* root);
+  void loadConnections(const TiXmlElement* root);
+
+  PhysicsInterface*      getPhysicsInterfaceByName(const char* physicsInterfaceName) const;
+
+  void                   addField(Field* field);
+  void                   removeField(Field* field);
+  Field*                 getFieldByName(const char* FieldName) const;
+
+  void                   addConnection(PhysicsConnection* connection);
+  void                   removeConnection(PhysicsConnection* connection);
+  PhysicsConnection*     getPhysicsConnectionByName(const char* physicsConnectionName) const;
+
+
+  void                   tick(float dt);
+
+  void                   debug() const;
+
+ private:
+  PhysicsEngine();
+
+ private:
+  static PhysicsEngine*         singletonRef;         //!< the singleton reference of the PhysicsEngine
+
+  std::list<Field*>             fields;               //!< a list of physicsl fields.
+  std::list<PhysicsConnection*> connections;          //!< a list of physical connections.
+  const std::list<BaseObject*>* interfaces;           //!< The list of physical interfaces.
+};
+
+
+
+#endif /* _PHYSICS_ENGINE_H */
Index: branches/network/src/lib/physics/physics_interface.cc
===================================================================
--- branches/network/src/lib/physics/physics_interface.cc	(revision 6636)
+++ branches/network/src/lib/physics/physics_interface.cc	(revision 6636)
@@ -0,0 +1,124 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: Benjamin Grauer
+
+   bensch: renamed the file
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_PHYSICS
+
+#include "physics_interface.h"
+#include "physics_engine.h"
+
+#include "field.h"
+#include "p_node.h"
+
+#include "list.h"
+#include "string.h"
+#include "stdincl.h"
+
+using namespace std;
+
+
+/**
+ *  standard constructor
+ */
+PhysicsInterface::PhysicsInterface ()
+{
+  this->setClassID(CL_PHYSICS_INTERFACE, "PhysicsInterface");
+
+  this->mass = 1;
+  this->massChildren = 0;
+  this->forceSum = Vector(0, 0, 0);
+  this->bForceApplied = false;
+}
+
+/**
+ *  standard deconstructor
+*/
+PhysicsInterface::~PhysicsInterface ()
+{
+}
+
+/**
+ *  recalculates the total mass of all the children of this node
+
+   (only availiable for PNodes)
+*/
+void PhysicsInterface::recalcMass()
+{
+  /*
+    PNode* massCalcPNode = dynamic_cast<PNode*>(this);  //! @todo not sure if this will work ....
+    float massSum = 0;
+
+    tIterator<PNode>* iterator = massCalcPNode->children->getIterator();
+    PNode* pn = iterator->firstElement();
+    while( pn != NULL)
+    {
+    // todo: find out if children are PhysicsInterface in an efficient way
+    if (strcmp( pn->getClassName(), "PhysicsInterface")) {
+    massSum += ((PhysicsInterface*)pn)->getTotalMass();
+    }
+    pn = iterator->nextElement();
+    }
+    delete iterator;
+
+    if (massSum != this->massChildren ) {
+    this->massChildren = massSum;
+    if (strcmp( massCalcPNode->parent->getClassName(), "PhysicsInterface"))
+    ((PhysicsInterface*)massCalcPNode->parent)->recalcMass();
+    } else {
+    this->massChildren = massSum;
+    }
+  */
+}
+
+/**
+ *  applyes a field to this Object
+ * @param field the field to apply
+ *
+ * this function is virtual, and !must be reimplemented if the Member is !NOT! a PNode
+*/
+void PhysicsInterface::applyField(Field* field)
+{
+  PNode* tmp = dynamic_cast<PNode*>((BaseObject*)this);
+  this->forceSum += field->calcForce(tmp->getAbsCoor());
+  this->bForceApplied = true;
+}
+
+void PhysicsInterface::applyForce(const Vector& force)
+{
+  PNode* tmp = dynamic_cast<PNode*>((BaseObject*)this);
+  this->forceSum += force;
+  this->bForceApplied = true;
+}
+
+/**
+ *  ticks the PhysicsEffect
+ * @param dt: the value about which to tick
+*/
+void PhysicsInterface::tickPhys( float dt )
+{
+  //  Vector acc = this->forceSum / ( this->massChildren + this->mass );
+  PNode* coorTick =  dynamic_cast<PNode*>((BaseObject*)this);
+  if (coorTick != NULL )
+    coorTick->shiftCoor((coorTick->getVelocity()+ this->forceSum/this->mass*dt)*dt);
+
+  if (this->bForceApplied)
+  {
+    this->bForceApplied = false;
+    this->forceSum = Vector(0,0,0);
+  }
+}
Index: branches/network/src/lib/physics/physics_interface.h
===================================================================
--- branches/network/src/lib/physics/physics_interface.h	(revision 6636)
+++ branches/network/src/lib/physics/physics_interface.h	(revision 6636)
@@ -0,0 +1,58 @@
+/*!
+ * @file physics_interface.h
+  *  a physics interface simulating a body with a mass
+*/
+
+#ifndef _PHYSICS_INTERFACE_H
+#define _PHYSICS_INTERFACE_H
+
+#include "base_object.h"
+
+#include "vector.h"
+#include "quaternion.h"
+#ifndef NULL
+#define NULL 0          //!< NULL
+#endif
+
+// Forward Declaration
+class Field;
+
+//! A Physics interface
+/**
+   The PhysicsInterface is an extension to Any other object,
+   that can be used to turn it to be Physcally animated.
+   Still you have to connect fields.
+   IMPORTANT is, that when using PNodes this baseclass is ok.
+   BUT, when using any other class that does not by itself implement
+   PNode you __MUST__ implement all the virtual functions by your own
+*/
+class PhysicsInterface : virtual public BaseObject
+{
+ public:
+  PhysicsInterface();
+  virtual ~PhysicsInterface();
+  /** @param mass the mass to set for this node. */
+  inline void setMass( float mass ) { this->mass = mass; };
+  /** @returns the mass of the node. */
+  inline float getMass( void ) const { return mass; };
+  /** @returns the mass of this node plus all its children (only valid for PNodes). */
+  inline float getTotalMass( void ) const { return mass + massChildren; };
+
+  virtual void applyForce(const Vector& force);
+  virtual void applyField(Field* field);
+  virtual void tickPhys( float dt );
+
+ protected:
+  virtual void recalcMass();
+
+
+ private:
+  float          mass;                  //!< Mass of this object
+  float          massChildren;          //!< Sum of the masses of the children nodes
+
+  Vector         forceSum;              //!< Total central force for this tick
+  Quaternion     momentumSum;           //!< Total momentum in this tick
+  bool           bForceApplied;         //!< If a force was applied to this object.
+};
+
+#endif /* _PHYSICS_INTERFACE_H */
Index: branches/network/src/lib/shell/Makefile.am
===================================================================
--- branches/network/src/lib/shell/Makefile.am	(revision 6636)
+++ branches/network/src/lib/shell/Makefile.am	(revision 6636)
@@ -0,0 +1,19 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXshell.a
+
+libORXshell_a_SOURCES = shell.cc \
+			shell_buffer.cc \
+			shell_input.cc \
+		        shell_command.cc \
+		        shell_command_class.cc \
+			shell_completion.cc
+
+
+noinst_HEADERS= shell.h \
+		shell_buffer.h \
+		shell_input.h \
+                shell_command.h \
+                shell_command_class.h \
+		shell_completion.h
Index: branches/network/src/lib/shell/shell.cc
===================================================================
--- branches/network/src/lib/shell/shell.cc	(revision 6636)
+++ branches/network/src/lib/shell/shell.cc	(revision 6636)
@@ -0,0 +1,554 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "shell.h"
+#include "shell_command.h"
+#include "shell_buffer.h"
+#include "shell_input.h"
+
+
+#include "text.h"
+#include "graphics_engine.h"
+#include "material.h"
+#include "event_handler.h"
+#include "debug.h"
+#include "class_list.h"
+
+#include "key_names.h"
+#include <stdarg.h>
+#include <stdio.h>
+
+using namespace std;
+
+SHELL_COMMAND(clear, Shell, clear)
+    ->describe("Clears the shell from unwanted lines (empties all buffers)")
+    ->setAlias("clear");
+SHELL_COMMAND(deactivate, Shell, deactivate)
+    ->describe("Deactivates the Shell. (moves it into background)")
+    ->setAlias("hide");
+SHELL_COMMAND(textsize, Shell, setTextSize)
+    ->describe("Sets the size of the Text size, linespacing")
+    ->defaultValues(1, 15, 0);
+SHELL_COMMAND(textcolor, Shell, setTextColor)
+    ->describe("Sets the Color of the Shells Text (red, green, blue, alpha)")
+    ->defaultValues(4, SHELL_DEFAULT_TEXT_COLOR);
+SHELL_COMMAND(backgroundcolor, Shell, setBackgroundColor)
+    ->describe("Sets the Color of the Shells Background (red, green, blue, alpha)")
+    ->defaultValues(4, SHELL_DEFAULT_BACKGROUND_COLOR);
+SHELL_COMMAND(backgroundimage, Shell, setBackgroundImage)
+    ->describe("sets the background image to load for the Shell");
+SHELL_COMMAND(font, Shell, setFont)
+    ->describe("Sets the font of the Shell")
+    ->defaultValues(1, SHELL_DEFAULT_FONT);
+
+/**
+ * standard constructor
+ */
+Shell::Shell ()
+{
+  this->setClassID(CL_SHELL, "Shell");
+  this->setName("Shell");
+
+  // EVENT-Handler subscription of '`' to all States.
+  EventHandler::getInstance()->subscribe(this, ES_ALL, SDLK_BACKQUOTE);
+  EventHandler::getInstance()->subscribe(this, ES_ALL, SDLK_F12);
+  EventHandler::getInstance()->subscribe(this, ES_SHELL, SDLK_PAGEUP);
+  EventHandler::getInstance()->subscribe(this, ES_SHELL, SDLK_PAGEDOWN);
+
+  // BUFFER
+  this->bufferText = NULL;
+  this->bufferDisplaySize = 10;
+  this->bufferOffset = 0;
+  this->bufferIterator = ShellBuffer::getInstance()->getBuffer()->begin();
+
+  // INPUT LINE
+  this->shellInput = new ShellInput;
+
+  this->backgroundMaterial = new Material;
+  // Element2D and generals
+  this->setAbsCoor2D(3, -400);
+  this->textSize = 20;
+  this->lineSpacing = 0;
+  this->bActive = true;
+  this->fontFile = new char[strlen(SHELL_DEFAULT_FONT)+1];
+  strcpy(this->fontFile, SHELL_DEFAULT_FONT);
+
+
+  this->rebuildText();
+
+  this->setTextColor(SHELL_DEFAULT_TEXT_COLOR);
+  this->setBackgroundColor(SHELL_DEFAULT_BACKGROUND_COLOR);
+
+  this->deactivate();
+  // register the shell at the ShellBuffer
+  ShellBuffer::getInstance()->registerShell(this);
+}
+
+/**
+ * standard deconstructor
+ */
+Shell::~Shell ()
+{
+  ShellBuffer::getInstance()->unregisterShell(this);
+
+  // delete the displayable Buffers
+  for (unsigned int i = 0; i < this->bufferDisplaySize; i++)
+    delete this->bufferText[i];
+  delete[] this->bufferText;
+  delete[] this->fontFile;
+  // delete the inputLine
+  delete this->shellInput;
+  delete this->backgroundMaterial;
+}
+
+/**
+ * activates the shell
+ *
+ * This also feeds the Last few lines from the main buffers into the displayBuffer
+ */
+void Shell::activate()
+{
+  if (this->bActive == true)
+    PRINTF(3)("The shell is already active\n");
+  this->bActive = true;
+
+  EventHandler::getInstance()->pushState(ES_SHELL);
+  EventHandler::getInstance()->withUNICODE(true);
+
+  this->setRelCoorSoft2D(0, 0, 1, 5);
+
+  list<char*>::const_iterator textLine = --ShellBuffer::getInstance()->getBuffer()->end();
+  bool top = false;
+  for (int i = 0; i < this->bufferDisplaySize; i++)
+  {
+    this->bufferText[i]->setVisibility(true);
+    if (!top)
+    {
+      this->bufferText[i]->setText((*textLine), true);
+    if (textLine != ShellBuffer::getInstance()->getBuffer()->begin())
+      top = true;
+      textLine--;
+    }
+  }
+}
+
+/**
+ * deactiveates the Shell.
+ */
+void Shell::deactivate()
+{
+  if (this->bActive == false)
+    PRINTF(3)("The shell is already inactive\n");
+  this->bActive = false;
+
+  EventHandler::getInstance()->withUNICODE(false);
+  EventHandler::getInstance()->popState();
+
+  this->setRelCoorSoft2D(0, -(int)this->shellHeight, 1, 5);
+
+  list<char*>::const_iterator textLine = --ShellBuffer::getInstance()->getBuffer()->end();
+  for (int i = 0; i < this->bufferDisplaySize; i++)
+  {
+    this->bufferText[i]->setVisibility(false);
+    if (textLine != ShellBuffer::getInstance()->getBuffer()->begin())
+    {
+      this->bufferText[i]->setText((*textLine), false);
+      textLine--;
+    }
+  }
+  this->bufferOffset = 0;
+}
+
+/**
+ * sets the File to load the fonts from
+ * @param fontFile the file to load the font from
+ *
+ * it is quite important, that the font pointed too really exists!
+ * (be aware that within orxonox fontFile is relative to the Data-Dir)
+ */
+void Shell::setFont(const char* fontFile)
+{
+//   if (!ResourceManager::isInDataDir(fontFile))
+//     return false;
+
+  if (this->fontFile != NULL)
+    delete[] this->fontFile;
+
+  this->fontFile = new char[strlen(fontFile)+1];
+  strcpy(this->fontFile, fontFile);
+
+  this->rebuildText();
+}
+
+/**
+ * sets the size of the text and spacing
+ * @param textSize the size of the Text in Pixels
+ * @param lineSpacing the size of the Spacing between two lines in pixels
+ *
+ * this also rebuilds the entire Text, inputLine and displayBuffer,
+ * to be accurate again.
+ */
+void Shell::setTextSize(unsigned int textSize, unsigned int lineSpacing)
+{
+  this->textSize = textSize;
+  this->lineSpacing = lineSpacing;
+  this->resetValues();
+}
+
+/**
+ * sets the color of the Font.
+ * @param r: red
+ * @param g: green
+ * @param b: blue
+ * @param a: alpha-value.
+ */
+void Shell::setTextColor(float r, float g, float b, float a)
+{
+  this->textColor[0] = r;
+  this->textColor[1] = g;
+  this->textColor[2] = b;
+  this->textColor[3] = a;
+
+  this->resetValues();
+}
+
+
+/**
+ * sets the color of the Backgrond.
+ * @param r: red
+ * @param g: green
+ * @param b: blue
+ * @param a: alpha-value.
+ */
+void Shell::setBackgroundColor(float r, float g, float b, float a)
+{
+  this->backgroundMaterial->setDiffuse(r, g, b);
+  this->backgroundMaterial->setTransparency(a);
+}
+
+/**
+ * sets a nice background image to the Shell's background
+ * @param fileName the filename of the Image to load
+ */
+void Shell::setBackgroundImage(const char* fileName)
+{
+  this->backgroundMaterial->setDiffuseMap(fileName);
+}
+
+
+/**
+ * resets the Values of all visible shell's commandos to the Shell's stored values
+ *
+ * this functions synchronizes the stored Data with the visible one.
+ */
+void Shell::resetValues()
+{
+  if (this->shellInput != NULL)
+  {
+    this->shellInput->setSize(this->textSize);
+    this->shellInput->setColor(this->textColor[0], this->textColor[1], this->textColor[2]);
+    this->shellInput->setBlending(this->textColor[3]);
+    this->shellInput->setRelCoor2D(5, (this->textSize + this->lineSpacing)*(this->bufferDisplaySize));
+  }
+
+  if (this->bufferText != NULL)
+  {
+    for (unsigned int i = 0; i < this->bufferDisplaySize; i++)
+    {
+      if (this->bufferText[i] != NULL)
+      {
+        this->bufferText[i]->setSize(this->textSize);
+        this->bufferText[i]->setColor(this->textColor[0], this->textColor[1], this->textColor[2]);
+        this->bufferText[i]->setBlending(this->textColor[3]);
+        this->bufferText[i]->setRelCoor2D(calculateLinePosition(i));
+      }
+    }
+  }
+  this->shellHeight = (this->textSize + this->lineSpacing) * (bufferDisplaySize+1);
+}
+
+/**
+ * rebuilds the Text's
+ *
+ * use this function, if you changed the Font/Size or something else.
+ */
+void Shell::rebuildText()
+{
+  this->shellInput->setFont(this->fontFile, this->textSize);
+  this->shellInput->setAlignment(TEXT_ALIGN_LEFT);
+  if (shellInput->getParent2D() != this)
+    this->shellInput->setParent2D(this);
+
+  this->setBufferDisplaySize(this->bufferDisplaySize);
+}
+
+/**
+ * sets The count of Lines to display in the buffer.
+ * @param bufferDisplaySize the count of lines to display in the Shell-Buffer.
+ */
+void Shell::setBufferDisplaySize(unsigned int bufferDisplaySize)
+{
+  Text** bufferText = this->bufferText;
+  this->bufferText = NULL;
+  if (bufferText != NULL)
+  {
+    for (unsigned int i = 0; i < this->bufferDisplaySize; i++)
+      delete bufferText[i];
+    delete[] bufferText;
+  }
+
+  list<char*>::const_iterator textLine = --ShellBuffer::getInstance()->getBuffer()->end();
+  bufferText = new Text*[bufferDisplaySize];
+  for (unsigned int i = 0; i < bufferDisplaySize; i++)
+  {
+    bufferText[i] = new Text(this->fontFile, this->textSize);
+    bufferText[i]->setAlignment(TEXT_ALIGN_LEFT);
+    bufferText[i]->setParent2D(this);
+    if(textLine != ShellBuffer::getInstance()->getBuffer()->begin())
+    {
+      bufferText[i]->setText(*textLine);
+      textLine--;
+    }
+  }
+  this->bufferDisplaySize = bufferDisplaySize;
+
+  this->bufferText = bufferText;
+  this->shellHeight = (this->textSize + this->lineSpacing) * (bufferDisplaySize+1);
+}
+
+/**
+ * deletes all the Buffers
+ */
+void Shell::flush()
+{
+  // remove all chars from the BufferTexts.
+  if (this->bufferText != NULL)
+    for (int i = 0; i < this->bufferDisplaySize; i++)
+    {
+      this->bufferText[i]->setText(NULL, true);
+    }
+
+    ShellBuffer::getInstance()->flush();
+    // BUFFER FLUSHING
+}
+
+/**
+ * prints out some text to the input-buffers
+ * @param text the text to output.
+ */
+void Shell::printToDisplayBuffer(const char* text)
+{
+  if(likely(bufferText != NULL))
+  {
+    Text* lastText = this->bufferText[this->bufferDisplaySize-1];
+
+    Text* swapText;
+    Text* moveText = this->bufferText[0];
+    for (unsigned int i = 0; i < this->bufferDisplaySize; i++)
+    {
+      if ( i < this->bufferDisplaySize-1)
+        this->bufferText[i]->setRelCoorSoft2D(this->calculateLinePosition(i+1), 5);
+      swapText = this->bufferText[i];
+      this->bufferText[i] = moveText;
+      moveText = swapText;
+    }
+
+  /*  FANCY EFFECTS :)
+    1:
+        lastText->setRelCoor2D(this->calculateLinePosition(0)- Vector(-1000,0,0));
+        lastText->setRelCoorSoft2D(this->calculateLinePosition(0),10);
+    2:
+  */
+    lastText->setRelDir2D(-90);
+    lastText->setRelDirSoft2D(0, 20);
+    lastText->setRelCoor2D(this->calculateLinePosition(0)- Vector(-1000,0,0));
+    lastText->setRelCoorSoft2D(this->calculateLinePosition(0),10);
+
+ //   lastText->setRelCoor2D(this->calculateLinePosition(0));
+    this->bufferText[0] = lastText;
+
+    this->bufferText[0]->setText(text, true);
+  }
+}
+
+/**
+ * moves the Display buffer (up + or down - )
+ * @param lineCount the count by which to shift the InputBuffer.
+ *
+ * @todo make this work
+ */
+void Shell::moveDisplayBuffer(int lineCount)
+{
+  if (this->bufferOffset == 0)
+   {
+     this->bufferIterator = ShellBuffer::getInstance()->getBuffer()->end();
+//     for (unsigned int i = 0; i < this->bufferDisplaySize; i++)
+//       this->bufferIterator->prevStep();
+   }
+
+  // boundraries
+  if (this->bufferOffset + lineCount > (int)ShellBuffer::getInstance()->getBuffer()->size())
+    lineCount = (int)ShellBuffer::getInstance()->getBuffer()->size()- this->bufferOffset;
+  else if (this->bufferOffset + lineCount < 0)
+    lineCount = -bufferOffset;
+  this->bufferOffset += lineCount;
+
+  // moving the iterator to the right position
+  int move = 0;
+  while (move != lineCount)
+  {
+    if (move < lineCount)
+    {
+      ++move;
+      this->bufferIterator--;
+    }
+    else
+    {
+      --move;
+      this->bufferIterator++;
+    }
+  }
+  // redisplay the buffers
+  list<char*>::const_iterator it = this->bufferIterator;
+  for (unsigned int i = 0; i < this->bufferDisplaySize; i++)
+  {
+    this->bufferText[i]->setText((*it), false);
+    it--;
+  }
+}
+
+/**
+ * clears the Shell (empties all buffers)
+ */
+void Shell::clear()
+{
+  this->flush();
+  ShellBuffer::addBufferLineStatic("orxonox - shell\n ==================== \n", NULL);
+}
+
+/**
+ * listens for some event
+ * @param event the Event happened
+ */
+void Shell::process(const Event &event)
+{
+  if (event.bPressed)
+  {
+    if (event.type == SDLK_BACKQUOTE || event.type == SDLK_F12)
+    {
+      if (this->bActive == false)
+        this->activate();
+      else
+        this->deactivate();
+    }
+    else if (event.type == SDLK_PAGEUP)
+    {
+      this->moveDisplayBuffer(+this->bufferDisplaySize-1);
+    }
+    else if (event.type == SDLK_PAGEDOWN)
+    {
+      this->moveDisplayBuffer(-this->bufferDisplaySize+1);
+    }
+  }
+}
+
+/**
+ * displays the Shell
+ */
+void Shell::draw() const
+{
+  glPushMatrix();
+  // transform for alignment.
+  // setting the Blending effects
+
+  this->backgroundMaterial->select();
+
+  glBegin(GL_TRIANGLE_STRIP);
+
+  glTexCoord2f(0, 0);
+  glVertex2f(this->getAbsCoor2D().x,   this->getAbsCoor2D().y  );
+
+  glTexCoord2f(1, 0);
+  glVertex2f(GraphicsEngine::getInstance()->getResolutionX() - this->getAbsCoor2D().x, this->getAbsCoor2D().y  );
+
+  glTexCoord2f(0, 1);
+  glVertex2f(this->getAbsCoor2D().x, this->getAbsCoor2D().y + this->shellHeight);
+
+  glTexCoord2f(1, 1);
+  glVertex2f(GraphicsEngine::getInstance()->getResolutionX() - this->getAbsCoor2D().x, this->getAbsCoor2D().y + this->shellHeight);
+
+  glEnd();
+}
+
+///////////////////////
+// HELPER FUNCTIONS  //
+///////////////////////
+
+/**
+ * calculates the position of a Buffer-Display Line
+ * @param lineNumber the lineNumber from the bottom to calculate the position from
+ * @returns the Position of the Line.
+ */
+Vector Shell::calculateLinePosition(unsigned int lineNumber)
+{
+  return Vector(5, (this->textSize + this->lineSpacing)*(this->bufferDisplaySize - lineNumber - 2) + this->textSize, 0);
+}
+
+
+
+/**
+ * displays some nice output from the Shell
+ */
+void Shell::debug() const
+{
+  PRINT(3)("Debugging output to console (not this shell)\n");
+
+//   if (this->pressedKey != SDLK_FIRST)
+//     printf("%s::%f %f\n", SDLKToKeyname(this->pressedKey), this->delayed, this->repeatDelay);
+
+
+  ShellBuffer::getInstance()->debug();
+}
+
+// void Shell::testI (int i)
+// {
+//   PRINTF(3)("This is the Test for one Int '%d'\n", i);
+// }
+//
+// void Shell::testS (const char* s)
+// {
+//   PRINTF(3)("This is the Test for one String '%s'\n", s);
+// }
+//
+// void Shell::testB (bool b)
+// {
+//   PRINTF(3)("This is the Test for one Bool: ");
+//   if (b)
+//     PRINTF(3)("true\n");
+//   else
+//     PRINTF(3)("false\n");
+// }
+//
+// void Shell::testF (float f)
+// {
+//   PRINTF(3)("This is the Test for one Float '%f'\n", f);
+// }
+//
+// void Shell::testSF (const char* s, float f)
+// {
+//   PRINTF(3)("This is the Test for one String '%s' and one Float '%f'\n",s , f);
+// }
Index: branches/network/src/lib/shell/shell.h
===================================================================
--- branches/network/src/lib/shell/shell.h	(revision 6636)
+++ branches/network/src/lib/shell/shell.h	(revision 6636)
@@ -0,0 +1,109 @@
+/*!
+ * @file shell.h
+ * Definition of a on-screen-shell
+ *
+ * @todo Buffer Display in different Colors for different debug mode.
+ * @todo choose color of the Font and the background.
+ */
+
+#ifndef _SHELL_H
+#define _SHELL_H
+
+#include "element_2d.h"
+#include "event_listener.h"
+
+#include <stdarg.h>
+
+#define         SHELL_DEFAULT_FONT              "fonts/dpquake_.ttf"
+#define         SHELL_DEFAULT_TEXT_COLOR        1.0f, 0.0f, 0.0f, 1.0f
+#define         SHELL_DEFAULT_BACKGROUND_COLOR  0.0f, 0.0f, 0.0f, 1.0f
+
+// FORWARD DECLARATION
+class Text;
+class ShellInput;
+class Material;
+
+//! A class that is able to redirect all output to a openGL-Shell, and that one can use to input some commands
+/**
+ * the major idea is, that all the Output can be redirected to the Shell,
+ * and does not have to be displayed to the opening Shell, this is good,
+ * for developers using Windows, where all output is otherwise redirected
+ * to stdout.txt
+ *
+ * Furthermore the Shell should enable us, to input some simple commands
+ * Each Class can check itself in to the Shell, and listen for commands.
+ *
+ * more info: @see ShellCommand
+ * @see shell_command.h
+ * @see shell_buffer.h
+ * @see shell_input.h
+ *
+ * !! note in order to keep shellbuffer to a minimal (it is included with
+ * !! debug.h) Display of it inside the Shell is located here !!
+ */
+class Shell : public Element2D, public EventListener {
+
+  public:
+    Shell();
+    virtual ~Shell();
+
+    void activate();
+    void deactivate();
+    /** @returns true if the Shell is active, false otherwise. */
+    inline bool isActive() const { return this->bActive; };
+
+    void setFont(const char* fontFile);
+    void setTextSize(unsigned int textSize, unsigned int lineSpacing = 1);
+    void setTextColor(float r, float g, float b, float a);
+    void setBackgroundColor(float r, float g, float b, float a);
+    void setBackgroundImage(const char* fileName);
+
+    void resetValues();
+    void rebuildText();
+
+    // BUFFERS
+    void setBufferDisplaySize(unsigned int bufferDisplaySize);
+    void printToDisplayBuffer(const char* text);
+    void moveDisplayBuffer(int lineCount);
+
+    void flush();
+
+    void clear();
+
+    // EventListener
+    virtual void process(const Event &event);
+    // Element2D-functions
+    virtual void draw() const;
+
+    void debug() const;
+
+  private:
+    // helpers //
+    Vector calculateLinePosition(unsigned int lineNumber);
+
+    //     void testI (int i);
+    //     void testS (const char* s);
+    //     void testB (bool b);
+    //     void testF (float f);
+    //     void testSF (const char* s, float f);
+
+  private:
+    // GENERAL
+    bool                        bActive;                //!< If the shell is active.
+    unsigned int                shellHeight;            //!< The hight of the Shell in Pixels.
+    unsigned int                lineSpacing;            //!< The Spacing between lines.
+    unsigned int                textSize;               //!< The size of the text.
+    float                       textColor[4];           //!< The text's color [r,g,b,a].
+    char*                       fontFile;               //!< The file containing the font.
+    Material*                   backgroundMaterial;     //!< A material for the background.
+
+    // HANDLING TEXT INPUT
+    ShellInput*                 shellInput;             //!< The inputLine of the Shell.
+    // BUFFER
+    unsigned int                bufferDisplaySize;      //!< The Size of the Display-buffer, in lines (not in characters).
+    Text**                      bufferText;             //!< A list of stored bufferTexts for the display of the buffer.
+    int                         bufferOffset;           //!< how many lines from the bottom up we display the Buffer.
+    std::list<char*>::const_iterator  bufferIterator;         //!< used to move through and print the Buffer
+};
+
+#endif /* _SHELL_H */
Index: branches/network/src/lib/shell/shell_buffer.cc
===================================================================
--- branches/network/src/lib/shell/shell_buffer.cc	(revision 6636)
+++ branches/network/src/lib/shell/shell_buffer.cc	(revision 6636)
@@ -0,0 +1,197 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "shell_buffer.h"
+#include "debug.h"
+#include "shell.h"
+
+#include "stdlibincl.h"
+
+using namespace std;
+
+
+/**
+ * standard constructor
+ */
+ShellBuffer::ShellBuffer ()
+{
+  ShellBuffer::singletonRef = this;
+  this->shell = NULL;
+
+  this->lineCount = 0;
+  this->keepBufferArray[0] = '\0';
+  this->bufferArray[0] = '\0';
+  this->keepBuffer = false;
+
+  this->setBufferSize(100);
+}
+
+ShellBuffer* ShellBuffer::singletonRef = NULL;
+
+/**
+ * standard deconstructor
+ */
+ShellBuffer::~ShellBuffer ()
+{
+  if (this->shell != NULL)
+    delete this->shell;
+
+  this->flush();
+
+  ShellBuffer::singletonRef = NULL;
+}
+
+/**
+ * registers the Shell to the Buffer
+ * @param shell the Shell to register.
+ */
+void ShellBuffer::registerShell(Shell* shell)
+{
+  if (this->shell == NULL)
+    this->shell = shell;
+  else
+    PRINTF(1)("already registered a Shell to the ShellBuffer\n");
+}
+
+/**
+ * unregisters the Shell from the Buffer
+ * @param shell the Shell to unregister.
+ */
+void ShellBuffer::unregisterShell(Shell* shell)
+{
+  if (this->shell == shell)
+    this->shell = NULL;
+  else
+    PRINTF(1)("cannot unregister shell, because it is not registered to the ShellBuffer\n");
+}
+
+/**
+ * deletes all the Buffers
+ */
+void ShellBuffer::flush()
+{
+  // delete all the Chars in the Buffers
+  list<char*>::iterator bufferLine;
+  for (bufferLine = this->buffer.begin(); bufferLine != this->buffer.end(); bufferLine++)
+  {
+    delete[] (*bufferLine);
+  }
+  this->buffer.clear();
+}
+
+/**
+ * adds a new Line to the List of Buffers
+ * @param line the Line as in the first argument in printf
+ */
+bool ShellBuffer::addBufferLineStatic(const char* line, ...)
+{
+  va_list arguments;
+  va_start(arguments, line);
+
+#if DEBUG < 3
+  if (ShellBuffer::singletonRef == NULL)
+#endif
+
+    vprintf(line, arguments);
+#if DEBUG < 3
+  else
+#else
+  if (ShellBuffer::singletonRef != NULL)
+#endif
+    ShellBuffer::singletonRef->addBufferLine(line, arguments);
+  return true;
+}
+
+/**
+ * add a Line to the List of Buffers
+ * @param line
+ * @param arguments
+ *
+ * This function Adds one line to the buffer.
+ * and displays the line as the First Line of the display-buffer
+ */
+void ShellBuffer::addBufferLine(const char* line, va_list arguments)
+{
+  char* inputEnd;
+  char* newLineBegin;
+  char* newLineEnd;
+
+  // copy the output to the bufferArray
+  vsprintf(this->bufferArray, line, arguments);
+
+  // check if we have something left in the buffers
+  // if so, append the new String to this one.
+  if (unlikely(this->keepBuffer))
+  {
+    strcat(this->keepBufferArray, this->bufferArray);
+    inputEnd = this->keepBufferArray + strlen(this->bufferArray);
+    newLineBegin = this->keepBufferArray;
+    this->keepBuffer = false;
+  }
+  else
+  {
+    inputEnd = this->bufferArray + strlen(this->bufferArray);
+    newLineBegin = this->bufferArray;
+  }
+
+  // adding all the new Lines
+  while (newLineBegin < inputEnd)
+  {
+    newLineEnd = strchr(newLineBegin, '\n');
+    if (likely(newLineEnd != NULL && *newLineEnd == '\n'))
+      *newLineEnd = '\0';
+    else
+    {
+      unsigned int len = strlen(newLineBegin);
+      char* copyBuffer = new char[len+1];
+      strcpy(copyBuffer, newLineBegin);
+      strncpy(this->keepBufferArray, copyBuffer, len);
+      delete[] copyBuffer;
+      this->keepBufferArray[len] = '\0';
+      this->keepBuffer = true;
+      break;
+    }
+
+    char* addLine = new char[strlen(newLineBegin)+1];
+    strcpy(addLine, newLineBegin);
+
+    this->lineCount++;
+    this->buffer.push_back(addLine);
+    if (likely (this->shell != NULL) && unlikely (this->shell->isActive()))
+      this->shell->printToDisplayBuffer(addLine);
+
+    if (this->buffer.size() > this->bufferSize)
+    {
+      delete[] this->buffer.front();
+      this->buffer.pop_front();
+    }
+
+    newLineBegin = newLineEnd+1;
+  }
+}
+
+/**
+ * displays some nice output from the Shell
+ */
+void ShellBuffer::debug() const
+{
+  PRINT(3)("Debugging output to console (not this shell)\n");
+
+  list<char*>::const_iterator bufferLine;
+  for (bufferLine = this->buffer.begin(); bufferLine != this->buffer.end(); bufferLine++)
+    printf(*bufferLine);
+}
Index: branches/network/src/lib/shell/shell_buffer.h
===================================================================
--- branches/network/src/lib/shell/shell_buffer.h	(revision 6636)
+++ branches/network/src/lib/shell/shell_buffer.h	(revision 6636)
@@ -0,0 +1,64 @@
+/*!
+ * @file shell_buffer.h
+ * @brief The Shell buffer Tasks
+ * @see debug.h
+*/
+
+#ifndef _SHELL_BUFFER_H
+#define _SHELL_BUFFER_H
+
+#include <stdarg.h>
+#include <list>
+
+#define      SHELL_BUFFER_SIZE       16384         //!< The Size of the input-buffers (should be large enough to carry any kind of input)
+
+// FORWARD DECLARATION
+class Shell;
+
+#ifndef NULL
+#define NULL 0            //!< a pointer to NULL
+#endif
+
+//! A class handling output from orxonox via debug.h
+class ShellBuffer {
+
+ public:
+  virtual ~ShellBuffer();
+  /** @returns a Pointer to the only object of this Class */
+  inline static ShellBuffer* getInstance() { if (!ShellBuffer::singletonRef) ShellBuffer::singletonRef = new ShellBuffer();  return ShellBuffer::singletonRef; };
+  /** @returns true if this class is instanciated, false otherwise */
+  inline static bool isInstanciated() { return (ShellBuffer::singletonRef == NULL)?false:true; };
+
+  void registerShell(Shell* shell);
+  void unregisterShell(Shell* shell);
+
+  // BUFFER //
+  /** @param bufferSize the new Buffer-Size */
+  void setBufferSize(unsigned int bufferSize) { this->bufferSize = bufferSize; };
+  void flush();
+  static bool addBufferLineStatic(const char* line, ...);
+  void addBufferLine(const char* line, va_list arg);
+  /** @returns the List of stings from the Buffer */
+  const std::list<char*>* getBuffer() const { return &this->buffer; };
+ /** @returns the Count of lines processed by the Shell. */
+  inline long getLineCount() const { return this->lineCount; };
+
+  void debug() const;
+
+  private:
+    ShellBuffer();
+
+  private:
+    static ShellBuffer*      singletonRef;                       //!< The singleton-reference to the only memeber of this class.
+    unsigned int             bufferSize;                         //!< The Size of the buffer
+    std::list<char*>         buffer;                             //!< A list of stored char-arrays(strings) to store the history
+
+    Shell*                   shell;                              //!< the Registered Shell.
+    char                     bufferArray[SHELL_BUFFER_SIZE];     //!< a BUFFER for fast writing
+    char                     keepBufferArray[SHELL_BUFFER_SIZE]; //!< a BUFFER to have multi-non-newLine commands be copied into the shell.
+    bool                     keepBuffer;                         //!< if the keepbuffer contains unfinished lines.
+
+    unsigned long            lineCount;                          //!< how many Lines have been written out so far.
+};
+
+#endif /* _SHELL_BUFFER_H */
Index: branches/network/src/lib/shell/shell_command.cc
===================================================================
--- branches/network/src/lib/shell/shell_command.cc	(revision 6636)
+++ branches/network/src/lib/shell/shell_command.cc	(revision 6636)
@@ -0,0 +1,382 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "shell_command.h"
+#include "shell_command_class.h"
+
+#include "compiler.h"
+#include "debug.h"
+#include "class_list.h"
+
+#include "key_names.h"
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+using namespace std;
+
+/**
+ * constructs and registers a new Command
+ * @param commandName the name of the Command
+ * @param className the name of the class to apply this command to
+ * @param paramCount the count of parameters this command takes
+ */
+ShellCommand::ShellCommand(const char* commandName, const char* className, const Executor& executor)
+{
+  this->setClassID(CL_SHELL_COMMAND, "ShellCommand");
+  this->setName(commandName);
+  this->description = NULL;
+  this->alias = NULL;
+  this->executor = executor.clone();
+
+//  this->classID = classID;
+  this->shellClass = ShellCommandClass::getCommandClass(className); //ClassList::IDToString(classID);
+  if (this->shellClass != NULL)
+    this->shellClass->commandList.push_back(this);
+}
+
+/**
+ * deconstructs a ShellCommand
+ */
+ShellCommand::~ShellCommand()
+{
+  if (this->alias != NULL && ShellCommandClass::aliasList != NULL)
+  {
+    ShellCommandClass::aliasList->remove(this->alias);
+    delete this->alias;
+  }
+  delete this->executor;
+}
+
+/**
+ * registers a new ShellCommand
+ */
+ShellCommand* ShellCommand::registerCommand(const char* commandName, const char* className, const Executor& executor)
+{
+  if (ShellCommand::isRegistered(commandName, className, executor))
+    return NULL;
+  else
+    return new ShellCommand(commandName, className, executor);
+
+}
+
+/**
+ * unregister an existing commandName
+ * @param className the name of the Class the command belongs to.
+ * @param commandName the name of the command itself
+ */
+void ShellCommand::unregisterCommand(const char* commandName, const char* className)
+{
+  /// FIXME
+/*  if (ShellCommandClass::commandClassList == NULL)
+    ShellCommandClass::initCommandClassList();
+
+ const ShellCommandClass* checkClass = ShellCommandClass::isRegistered(className);
+
+ if (checkClass != NULL)
+  {
+    std::list<ShellCommand*>::iterator elem;
+    for (elem = checkClass->commandList.begin(); elem != checkClass->commandList.end(); elem++)
+    {
+      if (!strcmp(commandName, (*elem)->getName()))
+      {
+        delete (*elem);
+        checkClass->commandList.remove(*elem);
+        break;
+      }
+    }
+
+    if (checkClass->commandList->size() == 0)
+    {
+      ShellCommandClass::commandClassList->remove(checkClass);
+      delete checkClass;
+    }
+  }*/
+}
+
+/**
+ * checks if a command has already been registered.
+ * @param commandName the name of the Command
+ * @param className the name of the Class the command should apply to.
+ * @param paramCount how many arguments the Command takes
+ * @returns true, if the command is registered/false otherwise
+ *
+ * This is used internally, to see, if we have multiple command subscriptions.
+ * This is checked in the registerCommand-function.
+ */
+bool ShellCommand::isRegistered(const char* commandName, const char* className, const Executor& executor)
+{
+  if (ShellCommandClass::commandClassList == NULL)
+  {
+    ShellCommandClass::initCommandClassList();
+    return false;
+  }
+
+  const ShellCommandClass* checkClass = ShellCommandClass::isRegistered(className);
+  if (checkClass != NULL)
+  {
+    std::list<ShellCommand*>::const_iterator elem;
+    for (elem = checkClass->commandList.begin(); elem != checkClass->commandList.end(); elem++)
+    {
+      if (!strcmp(commandName, (*elem)->getName()))
+      {
+        PRINTF(2)("Command '%s::%s' already registered\n", className, commandName);
+        return true;
+      }
+    }
+   return false;
+  }
+  else
+    return false;
+}
+
+
+/**
+ * executes commands
+ * @param executionString the string containing the following input
+ * ClassName [ObjectName] functionName [parameter1[,parameter2[,...]]]
+ * @return true on success, false otherwise.
+ */
+bool ShellCommand::execute(const char* executionString)
+{
+  if (ShellCommandClass::commandClassList == NULL)
+    return false;
+
+  long classID = CL_NULL;                      //< the classID retrieved from the Class.
+  ShellCommandClass* commandClass = NULL;      //< the command class this command applies to.
+  const std::list<BaseObject*>* objectList = NULL;   //< the list of Objects stored in classID
+  BaseObject* objectPointer = NULL;            //< a pointer to th Object to Execute the command on
+  bool emptyComplete = false;                  //< if the completion input is empty string. e.g ""
+  unsigned int fktPos = 1;                     //< the position of the function (needed for finding it)
+//  long completeType = SHELLC_NONE;           //< the Type we'd like to complete.
+  SubString inputSplits(executionString, " \t\n,");
+
+  if (inputSplits.getCount() == 0)
+    return false;
+  if (inputSplits.getCount() >= 1)
+  {
+    // CHECK FOR ALIAS
+    if (ShellCommandClass::aliasList != NULL)
+    {
+      list<ShellCommandAlias*>::iterator alias;
+      for (alias = ShellCommandClass::aliasList->begin(); alias != ShellCommandClass::aliasList->end(); alias++ )
+      {
+        if ((*alias)->getName() != NULL && !strcmp((*alias)->getName(), inputSplits.getString(0)) && (*alias)->getCommand() != NULL &&
+            (*alias)->getCommand()->shellClass != NULL )
+        {
+          objectList = ClassList::getList((*alias)->getCommand()->shellClass->getName());
+          if (objectList != NULL)
+          {
+            if (inputSplits.getCount() > 1)
+              (*alias)->getCommand()->executor->execute(objectList->front(), executionString+inputSplits.getOffset(1));
+            else
+              (*alias)->getCommand()->executor->execute(objectList->front(), "");
+           return true;
+          }
+        }
+      }
+    }
+    // looking for a Matching Class
+    if (likely(ShellCommandClass::commandClassList != NULL))
+    {
+      list<ShellCommandClass*>::iterator commandClassIT;
+      for (commandClassIT = ShellCommandClass::commandClassList->begin(); commandClassIT != ShellCommandClass::commandClassList->end(); commandClassIT++)
+      {
+        if ((*commandClassIT)->getName() && !strcasecmp(inputSplits.getString(0), (*commandClassIT)->getName()))
+        {
+          //elemCL->getName();
+          classID = ClassList::StringToID((*commandClassIT)->getName());
+          commandClass = (*commandClassIT);
+          objectList = ClassList::getList((ClassID)classID);
+          break;
+        }
+      }
+    }
+
+    if (commandClass != NULL && inputSplits.getCount() >= 2)
+    {
+      if (objectList != NULL)
+      {
+        // Checking for a Match in the Objects of classID (else take the first)
+        list<BaseObject*>::const_iterator object;
+        for (object = objectList->begin(); object != objectList->end(); object++)
+        {
+          if ((*object)->getName() != NULL && !strcasecmp((*object)->getName(), inputSplits.getString(1)))
+          {
+            objectPointer = (*object);
+            fktPos = 2;
+            break;
+          }
+         }
+
+      //
+        if (objectPointer == NULL)
+          objectPointer = objectList->front();
+      }
+      // match a function.
+      if (commandClass != NULL && (fktPos == 1 || (fktPos == 2 && inputSplits.getCount() >= 3)))
+      {
+        list<ShellCommand*>::iterator cmdIT;
+        for (cmdIT = commandClass->commandList.begin(); cmdIT != commandClass->commandList.end(); cmdIT++)
+        {
+          if (!strcmp((*cmdIT)->getName(), inputSplits.getString(fktPos)))
+          {
+            if (objectPointer == NULL && (*cmdIT)->executor->getType() & Executor_Objective)
+              return false;
+            if (inputSplits.getCount() > fktPos+1)
+              (*cmdIT)->executor->execute(objectPointer, executionString+inputSplits.getOffset(fktPos +1));
+            else
+              (*cmdIT)->executor->execute(objectPointer, "");
+            return true;
+          }
+        }
+      }
+    }
+  }
+}
+
+/**
+ * lets a command be described
+ * @param description the description of the Given command
+ */
+ShellCommand* ShellCommand::describe(const char* description)
+{
+  if (this == NULL)
+    return NULL;
+ else
+ {
+   this->description = description;
+   return this;
+ }
+}
+
+/**
+ * adds an Alias to this Command
+ * @param alias the name of the Alias to set
+ * @returns itself
+ */
+ShellCommand* ShellCommand::setAlias(const char* alias)
+{
+  if (this == NULL)
+    return NULL;
+
+  if (this->alias != NULL)
+  {
+    PRINTF(2)("not more than one Alias allowed for functions (%s::%s)\n", this->getName(), this->shellClass->getName());
+  }
+  else
+  {
+    if (ShellCommandClass::aliasList == NULL)
+      ShellCommandClass::aliasList = new std::list<ShellCommandAlias*>;
+
+    ShellCommandAlias* aliasCMD = new ShellCommandAlias(alias, this);
+    ShellCommandClass::aliasList->push_back(aliasCMD);
+    this->alias = aliasCMD;
+  }
+  return this;
+}
+
+/**
+ * sets default Values of the Commands
+ * @param count how many default Values to set.
+ * @param ... the default Values in order. They will be cast to the right type
+ * @returns itself
+ *
+ * Be aware, that when you use this Function, you !!MUST!! match the input as
+ * count, [EXACTLY THE SAME AS IF YOU WOULD CALL THE FUNCTION UP TO count ARGUMENTS]
+ */
+ShellCommand* ShellCommand::defaultValues(unsigned int count, ...)
+{
+  if (this == NULL)
+    return NULL;
+
+  va_list values;
+  va_start(values, count);
+
+  this->executor->defaultValues(count, values);
+
+  return this;
+}
+
+/**
+ * prints out nice information about the Shells Commands
+ */
+void ShellCommand::debug()
+{
+  if (ShellCommandClass::commandClassList == NULL)
+  {
+    PRINT(0)("No Command registered.\n");
+    return;
+  }
+
+  list<ShellCommandClass*>::iterator classIT;
+  for (classIT = ShellCommandClass::commandClassList->begin(); classIT != ShellCommandClass::commandClassList->end(); classIT++)
+  {
+    PRINT(0)("Class:'%s' registered %d commands: \n", (*classIT)->className, (*classIT)->commandList.size());
+
+    list<ShellCommand*>::iterator cmdIT;
+    for (cmdIT = (*classIT)->commandList.begin(); cmdIT != (*classIT)->commandList.end(); cmdIT++)
+    {
+      PRINT(0)("  command:'%s' : params:%d: ", (*cmdIT)->getName(), (*cmdIT)->executor->getParamCount());
+      /// FIXME
+      /*      for (unsigned int i = 0; i< elem->paramCount; i++)
+       printf("%s ", ShellCommand::paramToString(elem->parameters[i]));*/
+      if ((*cmdIT)->description != NULL)
+       printf("- %s", (*cmdIT)->description);
+      printf("\n");
+
+    }
+  }
+}
+
+/**
+ * converts a Parameter to a String
+ * @param parameter the Parameter we have.
+ * @returns the Name of the Parameter at Hand
+ */
+const char* ShellCommand::paramToString(long parameter)
+{
+  return MultiType::MultiTypeToString((MT_Type)parameter);
+// FIXME
+  /*  switch (parameter)
+  {
+    case ParameterBool:
+      return "BOOL";
+      break;
+    case ParameterChar:
+      return "CHAR";
+      break;
+    case ParameterString:
+      return "STRING";
+      break;
+    case ParameterInt:
+      return "INT";
+      break;
+    case ParameterUInt:
+      return "UINT";
+      break;
+    case ParameterFloat:
+      return "FLOAT";
+      break;
+    case ParameterLong:
+      return "LONG";
+      break;
+    default:
+      return "NULL";
+      break;
+  }*/
+}
Index: branches/network/src/lib/shell/shell_command.h
===================================================================
--- branches/network/src/lib/shell/shell_command.h	(revision 6636)
+++ branches/network/src/lib/shell/shell_command.h	(revision 6636)
@@ -0,0 +1,113 @@
+/*!
+ * @file shell_command.h
+ * Definition of a on-screen-shell
+ */
+
+#ifndef _SHELL_COMMAND_H
+#define _SHELL_COMMAND_H
+
+#include "base_object.h"
+
+#include "executor/executor.h"
+#include <stdarg.h>
+
+#define     SHELL_COMMAND_MAX_SIZE      //!< The maximum size of a Shell Command
+
+
+
+// FORWARD DECLARATION
+class ShellCommandClass;
+class ShellCommandAlias;
+
+/**
+ * an easy to use Macro to create a Command
+ * @param command the name of the command (without "" around the string)
+ * @param class the name of the class to apply this command to (without the "" around the string)
+ * @param function the function to call
+ *
+ * MEANING:
+ *  ShellCommand* someUniqueVarName =
+ *       ShellCommand<ClassName>::registerCommand("commandNameInShell", "ClassName", &ClassName::FunctionToCall);
+ *
+ * In the Shell you would call this Command using:
+ * $ ClassName [ObjectName] commandNameInShell [parameters]
+ */
+//#define SHELL_COMMAND(command, class, function) \
+//        ShellCommand* shell_command_##class##_##command = ShellCommand<class>::registerCommand(#command, #class, &class::function)
+#define SHELL_COMMAND(command, class, function) \
+           ShellCommand* shell_command_##class##_##command = ShellCommand::registerCommand(#command, #class, ExecutorObjective<class>(&class::function))
+
+/**
+ * an easy to use Macro to create a Command
+ * @param command the name of the command (without "" around the string)
+ * @param class the name of the class to apply this command to (without the "" around the string)
+ * @param function the function to call
+ *
+ * MEANING:
+ *  ShellCommand* someUniqueVarName =
+ *       ShellCommand<ClassName>::registerCommand("commandNameInShell", "ClassName", &ClassName::FunctionToCall);
+ *
+ * In the Shell you would call this Command using:
+ * $ ClassName [ObjectName] commandNameInShell [parameters]
+ */
+#define SHELL_COMMAND_STATIC(command, class, function) \
+           ShellCommand* shell_command_##class##_##command = ShellCommand::registerCommand(#command, #class, ExecutorStatic<class>(function))
+
+
+
+//! a baseClass for all possible ShellCommands
+class ShellCommand : public BaseObject
+{
+  friend class ShellCommandClass;
+  public:
+    static bool execute (const char* executionString);
+
+    ShellCommand* describe(const char* description);
+    ShellCommand* setAlias(const char* alias);
+    ShellCommand* defaultValues(unsigned int count, ...);
+
+    static ShellCommand* registerCommand(const char* commandName, const char* className, const Executor& executor);
+
+    static void unregisterCommand(const char* commandName, const char* className);
+
+    static void debug();
+
+  protected:
+    ShellCommand(const char* commandName, const char* className, const Executor& executor);
+    ~ShellCommand();
+
+    static bool isRegistered(const char* commandName, const char* className, const Executor& executor);
+    static const char* paramToString(long parameter);
+
+  protected:
+    MultiType*                       defaultValue;                         //!< Default Values.
+
+  private:
+    ShellCommandClass*               shellClass;                           //!< A Pointer to the Shell-Class this Command belongs to.
+    ShellCommandAlias*               alias;                                //!< An Alias for the Class.
+
+    const char*                      description;                          //!< A description for this commnand. (initially NULL). Assigned with (create)->describe("blablabla");
+    Executor*                        executor;                             //!< The Executor, that really executes the Function.
+
+};
+
+//! A Class, that handles aliases.
+class ShellCommandAlias
+{
+  friend class ShellCommand;
+  public:
+    /** @returns the Name of the Alias. */
+    const char* getName() const { return this->aliasName; };
+    /** @returns the Command, this Alias is asociated with */
+    ShellCommand* getCommand() const { return this->command; };
+
+  private:
+    /** @param aliasName the name of the Alias @param command the Command, to associate this alias with */
+    ShellCommandAlias(const char* aliasName, ShellCommand* command) { this->aliasName = aliasName; this->command = command; };
+
+  private:
+    const char*     aliasName;       //!< the name of the Alias
+    ShellCommand*   command;         //!< a pointer to the command, this alias executes.
+};
+
+#endif /* _SHELL_COMMAND_H */
Index: branches/network/src/lib/shell/shell_command_class.cc
===================================================================
--- branches/network/src/lib/shell/shell_command_class.cc	(revision 6636)
+++ branches/network/src/lib/shell/shell_command_class.cc	(revision 6636)
@@ -0,0 +1,221 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "shell_command_class.h"
+
+#include "shell_command.h"
+
+#include "debug.h"
+#include "class_list.h"
+#include "compiler.h"
+
+#include <stdio.h>
+#include <string.h>
+
+using namespace std;
+
+std::list<ShellCommandClass*>* ShellCommandClass::commandClassList = NULL;
+std::list<ShellCommandAlias*>* ShellCommandClass::aliasList = NULL;
+
+/**
+ * creates a new ShellCommandClass
+ * @param className the Name of the command-class to create
+ */
+ShellCommandClass::ShellCommandClass(const char* className)
+{
+  this->setClassID(CL_SHELL_COMMAND_CLASS, "ShellCommandClass");
+  this->setName(className);
+
+  this->className = className;
+  this->classID = CL_NULL;
+
+  ShellCommandClass::commandClassList->push_back(this);
+}
+
+/**
+ * destructs the shellCommandClass again
+ */
+ShellCommandClass::~ShellCommandClass()
+{
+  while(this->commandList.size() > 0)
+  {
+    delete this->commandList.front();
+    this->commandList.pop_front();
+  }
+}
+
+/**
+ * collects the Commands registered to some class.
+ * @param className the name of the Class to collect the Commands from.
+ * @param stringList a List to paste the Commands into.
+ * @returns true on success, false otherwise
+ */
+bool ShellCommandClass::getCommandListOfClass(const char* className, std::list<const char*>* stringList)
+{
+  if (stringList == NULL || className == NULL)
+    return false;
+
+  list<ShellCommandClass*>::iterator elem;
+  for(elem = ShellCommandClass::commandClassList->begin(); elem != ShellCommandClass::commandClassList->end(); elem++)
+  {
+    if (!strcmp ((*elem)->getName(), className))
+    {
+      list<ShellCommand*>::iterator command;
+      for(command = (*elem)->commandList.begin(); command != (*elem)->commandList.end(); command++)
+        stringList->push_back((*command)->getName());
+    }
+  }
+  return true;
+}
+
+/**
+ * collects the Aliases registered to the ShellCommands
+ * @param stringList a List to paste the Aliases into.
+ * @returns true on success, false otherwise
+ */
+bool ShellCommandClass::getCommandListOfAlias(std::list<const char*>* stringList)
+{
+  if (stringList == NULL || ShellCommandClass::aliasList == NULL)
+    return false;
+
+  list<ShellCommandAlias*>::iterator alias;
+  for (alias = ShellCommandClass::aliasList->begin(); alias != ShellCommandClass::aliasList->end(); alias++)
+    stringList->push_back((*alias)->getName());
+  return true;
+}
+
+/**
+ * unregisters all Commands that exist
+ */
+void ShellCommandClass::unregisterAllCommands()
+{
+   if (ShellCommandClass::commandClassList != NULL)
+  {
+    // unregister all commands and Classes
+    std::list<ShellCommandClass*>::iterator classIT;
+    for (classIT = ShellCommandClass::commandClassList->begin(); classIT != ShellCommandClass::commandClassList->end(); classIT++)
+      delete (*classIT);
+    delete ShellCommandClass::commandClassList;
+    ShellCommandClass::commandClassList = NULL;
+  }
+
+  // unregister all aliases (there should be nothing to do here :))
+  if (ShellCommandClass::aliasList != NULL)
+  {
+    std::list<ShellCommandAlias*>::iterator alias;
+    for (alias = ShellCommandClass::aliasList->begin(); alias != ShellCommandClass::aliasList->end(); alias++)
+      delete (*alias);
+    delete ShellCommandClass::aliasList;
+    ShellCommandClass::aliasList = NULL;
+  }
+}
+
+/**
+ * checks if a Class is already registered to the Commands' class-stack
+ * @param className the Name of the Class to check for
+ * @returns the CommandClass if found, NULL otherwise
+ */
+const ShellCommandClass* ShellCommandClass::isRegistered(const char* className)
+{
+  if (ShellCommandClass::commandClassList == NULL)
+    initCommandClassList();
+
+  list<ShellCommandClass*>::const_iterator classIT;
+  for (classIT = ShellCommandClass::commandClassList->begin(); classIT != ShellCommandClass::commandClassList->end(); classIT++)
+  {
+    if (!strcmp(className, (*classIT)->className))
+    {
+      if ((*classIT)->classID == CL_NULL)
+        (*classIT)->classID = ClassList::StringToID(className);
+
+      return (*classIT);
+    }
+  }
+  return NULL;
+}
+
+/**
+ * searches for a CommandClass
+ * @param className the name of the CommandClass
+ * @returns the CommandClass if found, or a new CommandClass if not
+ */
+ShellCommandClass* ShellCommandClass::getCommandClass(const char* className)
+{
+  if (ShellCommandClass::commandClassList == NULL)
+    initCommandClassList();
+
+  list<ShellCommandClass*>::iterator classIT;
+  for (classIT = ShellCommandClass::commandClassList->begin(); classIT != ShellCommandClass::commandClassList->end(); classIT++)
+  {
+    if (!strcmp(className, (*classIT)->className))
+    {
+      return (*classIT);
+    }
+  }
+  return new ShellCommandClass(className);
+}
+
+/**
+ * initializes the CommandList (if it is NULL)
+ */
+void ShellCommandClass::initCommandClassList()
+{
+  if (ShellCommandClass::commandClassList == NULL)
+  {
+    ShellCommandClass::commandClassList = new std::list<ShellCommandClass*>;
+    ShellCommand::registerCommand("debug", "ShellCommand", ExecutorStatic<ShellCommand>(ShellCommand::debug));
+  }
+}
+
+/**
+ * displays help about ShellCommandClass
+ * @param className: the Class of Commands to show help about
+ */
+void ShellCommandClass::help(const char* className)
+{
+  if (className == NULL)
+    return;
+  if (likely(ShellCommandClass::commandClassList != NULL))
+  {
+    list<ShellCommandClass*>::iterator classIT;
+    for (classIT = ShellCommandClass::commandClassList->begin(); classIT != ShellCommandClass::commandClassList->end(); classIT++)
+    {
+      if ((*classIT)->className && !strcasecmp(className, (*classIT)->className))
+      {
+        PRINT(0)("Class:'%s' registered %d commands: \n", (*classIT)->className, (*classIT)->commandList.size());
+        list<ShellCommand*>::const_iterator cmdIT;
+        for (cmdIT = (*classIT)->commandList.begin(); cmdIT != (*classIT)->commandList.end(); cmdIT++)
+        {
+          PRINT(0)("  command:'%s' : params:%d: ", (*cmdIT)->getName(), (*cmdIT)->executor->getParamCount());
+          /// FIXME
+          /*          for (unsigned int i = 0; i< elem->paramCount; i++)
+            PRINT(0)("%s ", ShellCommand::paramToString(elem->parameters[i]));*/
+          if ((*cmdIT)->description != NULL)
+            PRINT(0)("- %s", (*cmdIT)->description);
+          PRINT(0)("\n");
+        }
+        return;
+      }
+    }
+    PRINTF(3)("Class %s not found in Command's classes\n", className);
+  }
+  else
+  {
+    PRINTF(1)("List of commandClasses does not exist");
+  }
+}
+
Index: branches/network/src/lib/shell/shell_command_class.h
===================================================================
--- branches/network/src/lib/shell/shell_command_class.h	(revision 6636)
+++ branches/network/src/lib/shell/shell_command_class.h	(revision 6636)
@@ -0,0 +1,52 @@
+/*!
+ * @file shell_command_class.h
+ * Definition of a on-screen-shell
+ */
+
+#ifndef _SHELL_COMMAND_CLASS_H
+#define _SHELL_COMMAND_CLASS_H
+
+#include "base_object.h"
+#include <list>
+
+
+// FORWARD DECLARATION
+
+////////////////
+// BASE CLASS //
+////////////////
+class ShellCommand;
+class ShellCommandAlias;
+
+//! A class to hold all Classes that have (once) registered Commands.
+class ShellCommandClass : public BaseObject
+{
+  friend class ShellCommand;
+
+  public:
+    /** @returns the CommandClassList */
+    static const std::list<ShellCommandClass*>* getCommandClassList() { return ShellCommandClass::commandClassList; };
+    static bool getCommandListOfClass(const char* className, std::list<const char*>* stringList);
+    static bool getCommandListOfAlias(std::list<const char*>* aliasList);
+
+    static ShellCommandClass* getCommandClass(const char* className);
+    static void unregisterAllCommands();
+
+    static void help (const char* className);
+
+  private:
+    ShellCommandClass(const char* className);
+    ~ShellCommandClass();
+
+    static const ShellCommandClass* isRegistered(const char* className);
+    static void initCommandClassList();
+
+  private:
+    const char*                            className;                 //!< The Name of the Class. This should match the ClassName of the Commands Class.
+    long                                   classID;                   //!< The classID of this Class
+    std::list<ShellCommand*>               commandList;               //!< A list of Commands from this Class
+    static std::list<ShellCommandClass*>*  commandClassList;          //!< A list of Classes
+    static std::list<ShellCommandAlias*>*  aliasList;                 //!< An Alias to A Command. (only for classes with one Instance)
+};
+
+#endif /* _SHELL_COMMAND_H */
Index: branches/network/src/lib/shell/shell_completion.cc
===================================================================
--- branches/network/src/lib/shell/shell_completion.cc	(revision 6636)
+++ branches/network/src/lib/shell/shell_completion.cc	(revision 6636)
@@ -0,0 +1,372 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "shell_completion.h"
+#include "shell_command_class.h"
+
+#include "shell_input.h"
+#include "shell_command.h"
+
+#include "substring.h"
+#include "base_object.h"
+#include "class_list.h"
+#include "debug.h"
+
+#include "stdlibincl.h"
+
+using namespace std;
+
+/**
+ * standard constructor
+ */
+ShellCompletion::ShellCompletion(ShellInput* input)
+{
+  this->input = input;
+}
+
+
+/**
+ * standard deconstructor
+ */
+ShellCompletion::~ShellCompletion ()
+{
+}
+
+
+
+/**
+ * autocompletes the Shell's inputLine
+ * @returns true, if a result was found, false otherwise
+ */
+bool ShellCompletion::autoComplete(ShellInput* input)
+{
+  const char* completionLine;           //< the inputLine we complete.
+
+  long classID;                         //< the classID retrieved from the Class.
+  const std::list<BaseObject*>* objectList;   //< the list of Objects stored in classID
+  bool emptyComplete = false;           //< if the completion input is empty string. e.g ""
+  long completeType = SHELLC_NONE;      //< the Type we'd like to complete.
+  const char* completeString;           //< the string to complete.
+
+
+  PRINTF(5)("AutoComplete on input\n");
+  this->emptyCompletionList();
+
+  if (input != NULL)
+    this->input = input;
+  if (this->input == NULL)
+  {
+    PRINTF(2)("No ShellInput supplied\n");
+    return false;
+  }
+
+  // Check if we are in a input. eg. the supplied string "class " and now we complete either function or object
+  if (this->input->getInput() != NULL &&
+      strrchr(this->input->getInput(), ' ') >= this->input->getInput() + strlen(this->input->getInput())-1)
+  {
+    emptyComplete = true;
+  }
+
+  // CREATE INPUTS
+  if (this->input->getInput() == NULL)
+    completionLine = "";
+  else
+    completionLine = this->input->getInput() + strspn(this->input->getInput(), " \t\n");
+  SubString inputSplits(completionLine, " \t\n,");
+
+  // What String will be completed
+  if (emptyComplete == true)
+    completeString = "";
+  else
+    completeString = inputSplits.getString(inputSplits.getCount()-1);
+
+  // CLASS COMPLETION
+  if (inputSplits.getCount() == 0)
+  {
+    completeType |= SHELLC_CLASS;
+    completeType |= SHELLC_ALIAS;
+  }
+  else if (inputSplits.getCount() == 1 && emptyComplete == false)
+  {
+    completeType |= SHELLC_CLASS;
+    completeType |= SHELLC_ALIAS;
+  }
+
+  // OBJECT/FUNCTION COMPLETIONS
+  else if ((inputSplits.getCount() == 1 && emptyComplete == true) ||
+            (inputSplits.getCount() == 2 && emptyComplete == false))
+  {
+    classID = ClassList::StringToID(inputSplits.getString(0));
+    objectList = ClassList::getList((ClassID)classID);
+    if (classID != CL_NULL)
+      completeType |= SHELLC_OBJECT;
+    //if (objectList != NULL && objectList->getSize() == 1)
+      completeType |= SHELLC_FUNCTION;
+  }
+  else if ((inputSplits.getCount() == 2 && emptyComplete == true) ||
+            (inputSplits.getCount() == 3 && emptyComplete == false))
+  {
+    classID = ClassList::StringToID(inputSplits.getString(0));
+    if (classID == CL_NULL)
+      return false;
+    else
+     completeType |= SHELLC_FUNCTION;
+  }
+
+  if (completeType & SHELLC_CLASS)
+    this->objectComplete(completeString, CL_SHELL_COMMAND_CLASS);
+  if (completeType & SHELLC_OBJECT)
+    this->objectComplete(completeString, classID);
+  if (completeType & SHELLC_FUNCTION)
+    this->functionComplete(completeString, inputSplits.getString(0));
+  if (completeType & SHELLC_ALIAS)
+    this->aliasComplete(completeString);
+
+
+  this->generalComplete(completeString);
+  return true;
+}
+
+/**
+ * autocompletes a className
+ * @param classBegin the Beginning of a String to autoComplete
+ * @return true on success, false otherwise
+ */
+bool ShellCompletion::classComplete(const char* classBegin)
+{
+  if (unlikely(classBegin == NULL))
+    return false;
+  const std::list<const char*>* clList = ClassList::getClassNames();
+  if (clList != NULL)
+  {
+    if (!this->addToCompleteList(clList, classBegin, SHELLC_CLASS))
+      return false;
+  }
+  else
+    return false;
+  return true;
+}
+
+/**
+ * autocompletes an ObjectName
+ * @param objectBegin the beginning string of a Object
+ * @param classID the ID of the Class to search for.
+ * @return true on success, false otherwise
+ */
+bool ShellCompletion::objectComplete(const char* objectBegin, long classID)
+{
+  if (unlikely(objectBegin == NULL))
+    return false;
+  const std::list<BaseObject*>* boList = ClassList::getList((ClassID)classID);
+  if (boList != NULL)
+  {
+    SHELLC_TYPE type = SHELLC_OBJECT;
+    if (classID == CL_SHELL_COMMAND_CLASS)
+      type = SHELLC_CLASS;
+    if (!this->addToCompleteList(boList, objectBegin, type))
+      return false;
+  }
+  else
+    return false;
+  return true;
+}
+
+/**
+ * completes a Function
+ * @param functionBegin the beginning of the function String
+ * @param classID the class' ID to complete the function of
+ */
+bool ShellCompletion::functionComplete(const char* functionBegin, const char* className)
+{
+  if (unlikely(functionBegin == NULL))
+    return false;
+  std::list<const char*> fktList;
+  ShellCommandClass::getCommandListOfClass(className, &fktList);
+  //printf("%s\n", boList->firstElement()->getName());
+  if (!this->addToCompleteList(&fktList, functionBegin, SHELLC_FUNCTION))
+    return false;
+  return true;
+}
+
+/**
+ * completes an Alias
+ * @param aliasBegin the beginning of the Alias-String to complete
+ * @returns true on succes, false if something went wrong
+ */
+bool ShellCompletion::aliasComplete(const char* aliasBegin)
+{
+  if (unlikely(aliasBegin == NULL))
+    return false;
+  std::list<const char*> aliasList;
+  ShellCommandClass::getCommandListOfAlias(&aliasList);
+  //printf("%s\n", boList->firstElement()->getName());
+  if (!this->addToCompleteList(&aliasList, aliasBegin, SHELLC_ALIAS))
+    return false;
+  return true;
+}
+
+
+/**
+ * completes the inputline on grounds of an inputList
+ * @param begin the String to search in the inputList, and to extend with it.
+ * @param displayAs how to display the found value to the user, printf-style, !!with only one %s!! ex.: "::%s::"
+ * @param addBack what should be added at the end of the completion
+ * @param addFront what should be added to the front of one finished completion
+ * @return true if ok, false otherwise
+ */
+bool ShellCompletion::generalComplete(const char* begin, const char* displayAs, const char* addBack, const char* addFront)
+{
+  if (this->input == NULL )
+    return false;
+  if (completionList.size() == 0)
+    return false;
+
+  ShellC_Element addElem = completionList.front();
+  const char* addString = addElem.name;
+  unsigned int addLength = 0;
+  unsigned int inputLenght = strlen(begin);
+
+  // Determin the longest Match
+  if (addString != NULL)
+    addLength = strlen(addString);
+
+  SHELLC_TYPE changeType = SHELLC_NONE;
+  list<ShellC_Element>::iterator charIT;
+  for (charIT = completionList.begin(); charIT != completionList.end(); charIT++)
+  {
+    if ((*charIT).type != changeType)
+    {
+      if (changeType != SHELLC_NONE)
+        PRINT(0)("\n");
+      PRINT(0)("%s: ", ShellCompletion::typeToString((*charIT).type));
+      changeType = (*charIT).type;
+    }
+    PRINTF(0)("%s ", (*charIT).name);
+    for (unsigned int i = inputLenght; i < addLength; i++)
+      if (addString[i] != (*charIT).name[i])
+      {
+       addLength = i;
+//       break;
+      }
+  }
+  PRINT(0)("\n");
+
+  if (addLength >= inputLenght)
+  {
+    char* adder = new char[addLength+1];
+    strncpy(adder, addString, addLength);
+    adder[addLength] = '\0';
+
+    if (this->input)
+    {
+     this->input->removeCharacters(inputLenght);
+     this->input->addCharacters(adder);
+
+      if (completionList.size() == 1)
+      {
+        if ( addBack != NULL )
+         this->input->addCharacters(addBack);
+        this->input->addCharacter(' ');
+      }
+     delete[] adder;
+    }
+  }
+  return true;
+}
+
+/**
+ * @brief searches for classes, which beginn with completionBegin
+ * @param inputList the List to parse through
+ * @param completionBegin the beginning string
+ * !! The strings MUST NOT be deleted !!
+ */
+bool ShellCompletion::addToCompleteList(const std::list<const char*>* inputList, const char* completionBegin, SHELLC_TYPE type)
+{
+  if (inputList == NULL || completionBegin == NULL)
+    return false;
+  unsigned int searchLength = strlen(completionBegin);
+
+  list<const char*>::const_iterator string;
+  for (string = inputList->begin(); string != inputList->end(); string++)
+  {
+    if (strlen(*string) >= searchLength &&
+        !strncasecmp(*string, completionBegin, searchLength))
+    {
+      ShellC_Element newElem;
+      newElem.name = *string;
+      newElem.type = type;
+      this->completionList.push_back(newElem);
+    }
+  }
+  return true;
+}
+
+/**
+ * searches for classes, which beginn with completionBegin
+ * @param inputList the List to parse through
+ * @param completionBegin the beginning string
+ * !! The strings MUST NOT be deleted !!
+ */
+bool ShellCompletion::addToCompleteList(const std::list<BaseObject*>* inputList, const char* completionBegin, SHELLC_TYPE type)
+{
+  if (inputList == NULL || completionBegin == NULL)
+    return false;
+  unsigned int searchLength = strlen(completionBegin);
+
+  list<BaseObject*>::const_iterator bo;
+  for(bo = inputList->begin(); bo != inputList->end(); bo++)
+  {
+    if ((*bo)->getName() != NULL &&
+        strlen((*bo)->getName()) >= searchLength &&
+        !strncasecmp((*bo)->getName(), completionBegin, searchLength))
+    {
+      ShellC_Element newElem;
+      newElem.name = (*bo)->getName();
+      newElem.type = type;
+      this->completionList.push_back(newElem);
+    }
+  }
+
+  return true;
+}
+
+/**
+ * deletes the Completion List.
+ *
+ * This is done at the beginning of each completion-run
+ */
+void ShellCompletion::emptyCompletionList()
+{
+  this->completionList.clear();
+}
+
+const char* ShellCompletion::typeToString(SHELLC_TYPE type)
+{
+  switch (type)
+  {
+    default:// SHELLC_NONE
+      return "error";
+    case  SHELLC_CLASS:
+      return "class";
+    case SHELLC_OBJECT:
+      return "object";
+    case SHELLC_FUNCTION:
+      return "function";
+    case SHELLC_ALIAS:
+      return "alias";
+  }
+}
Index: branches/network/src/lib/shell/shell_completion.h
===================================================================
--- branches/network/src/lib/shell/shell_completion.h	(revision 6636)
+++ branches/network/src/lib/shell/shell_completion.h	(revision 6636)
@@ -0,0 +1,65 @@
+/*!
+ * @file shell_completion.h
+ * @brief The Shell Completion Tasks
+ *
+ * @todo if the second string is a Command, the third should not be completed!
+ * @todo also make some completion for registered (or special) Types
+*/
+
+#ifndef _SHELL_COMPLETION_H
+#define _SHELL_COMPLETION_H
+
+#include <list>
+
+// FORWARD DECLARATION
+class BaseObject;
+class ShellInput;
+#ifndef NULL
+#define NULL 0            //!< a pointer to NULL
+#endif
+
+//! an enumerator for different types the Shell can complete.
+typedef enum {
+  SHELLC_NONE        = 0,
+  SHELLC_CLASS       = 1,
+  SHELLC_OBJECT      = 2,
+  SHELLC_FUNCTION    = 4,
+  SHELLC_ALIAS       = 8,
+} SHELLC_TYPE;
+
+//! A struct for ShellElements (these are used as containers to identify an Input for what it is)
+struct ShellC_Element{
+  const char*     name;     //!< the Name of the Element to be completed.
+  SHELLC_TYPE     type;     //!< the type of the Element
+};
+
+//! A class for ...
+class ShellCompletion {
+
+ public:
+  ShellCompletion(ShellInput* input = NULL);
+  virtual ~ShellCompletion();
+
+  bool autoComplete(ShellInput* input = NULL);
+  bool classComplete(const char* classBegin);
+//  long classMatch(const char* input, unsigned int* length);
+  bool objectComplete(const char* objectBegin, long classID);
+//  bool objectMatch(const char* objectBegin, long classID, unsigned int* length);
+  bool functionComplete(const char* functionBegin, const char* className);
+//  bool functionMatch(const char* functionBegin, long classID, unsigned int* length);
+  bool aliasComplete(const char* aliasBegin);
+
+  bool generalComplete(const char* begin, const char* displayAs = "%s", const char* addBack = NULL, const char* addFront = NULL);
+
+  bool addToCompleteList(const std::list<const char*>* inputList, const char* completionBegin, SHELLC_TYPE type);
+  bool addToCompleteList(const std::list<BaseObject*>* inputList, const char* completionBegin, SHELLC_TYPE type);
+  void emptyCompletionList();
+
+  static const char* ShellCompletion::typeToString(SHELLC_TYPE type);
+
+ private:
+   std::list<ShellC_Element>    completionList;          //!< A list of completions, that are io.
+   ShellInput*                  input;                   //!< the input this completion works on.
+};
+
+#endif /* _SHELL_COMPLETION_H */
Index: branches/network/src/lib/shell/shell_input.cc
===================================================================
--- branches/network/src/lib/shell/shell_input.cc	(revision 6636)
+++ branches/network/src/lib/shell/shell_input.cc	(revision 6636)
@@ -0,0 +1,392 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "shell_input.h"
+
+
+
+#include "shell_command.h"
+#include "shell_command_class.h"
+#include "shell_completion.h"
+#include "event_handler.h"
+
+#include "debug.h"
+#include "compiler.h"
+#include "stdlibincl.h"
+#include "key_names.h"
+
+
+using namespace std;
+
+SHELL_COMMAND(help, ShellInput, help)
+    ->describe("retrieve some help about the input mode")
+    ->setAlias("help");
+
+/**
+ * constructor
+ * this also generates a ShellCompletion automatically.
+*/
+ShellInput::ShellInput () : Text ((const char*)NULL)
+{
+  this->pressedKey = SDLK_FIRST;
+  this->setClassID(CL_SHELL_INPUT, "ShellInput");
+
+  this->inputLine = new char[1];
+  this->inputLine[0] = '\0';
+  this->historyIT = this->history.begin();
+  this->setHistoryLength(50);
+  this->historyScrolling = false;
+  this->delayed = 0;
+  this->setRepeatDelay(.3, .05);
+
+  // subscribe all keyboard commands to ES_SEHLL
+  EventHandler* evh = EventHandler::getInstance();
+  for (int i = 1; i < SDLK_LAST; i++)
+  {
+    if (!evh->isSubscribed(ES_SHELL, i))
+      evh->subscribe(this, ES_SHELL, i);
+  }
+  this->completion = new ShellCompletion(this);
+}
+
+/**
+ * standard deconstructor
+*/
+ShellInput::~ShellInput ()
+{
+  // delete what has to be deleted here
+  delete[] this->inputLine;
+  delete this->completion;
+
+  while (!this->history.empty())
+  {
+    delete[] this->history.front();
+    this->history.pop_front();
+  }
+}
+
+/**
+ * sets the Repeate-delay and rate
+ * @param repeatDelay the Delay it takes, to repeate a key
+ * @param repeatRate the rate to repeate a pressed key
+ */
+void ShellInput::setRepeatDelay(float repeatDelay, float repeatRate)
+{
+  this->repeatDelay = repeatDelay;
+  this->repeatRate = repeatRate;
+}
+
+/**
+ * deletes the InputLine
+ */
+void ShellInput::flush()
+{
+  if (likely(this->inputLine != NULL))
+  {
+    delete[] this->inputLine;
+  }
+  this->inputLine = new char[1];
+  *this->inputLine = '\0';
+  this->setText(this->inputLine, true);
+}
+
+/**
+ * sets the entire text of the InputLine to text
+ * @param text the new Text to set as InputLine
+ */
+void ShellInput::setInputText(const char* text)
+{
+  delete[] this->inputLine;
+  if (text == NULL)
+  {
+    this->inputLine = new char[1];
+    this->inputLine[0] = '\0';
+  }
+  else
+  {
+    this->inputLine = new char[strlen(text)+1];
+    strcpy(this->inputLine, text);
+  }
+  this->setText(this->inputLine, true);
+}
+
+
+/**
+ * adds one character to the inputLine
+ * @param character the character to add to the inputLine
+ */
+void ShellInput::addCharacter(char character)
+{
+  if (this->historyScrolling)
+  {
+    delete[] this->history.back();
+    this->history.pop_back();
+    this->historyScrolling = false;
+  }
+
+  char* addCharLine = new char[strlen(this->inputLine)+2];
+
+  sprintf(addCharLine, "%s%c", this->inputLine, character);
+  delete[] this->inputLine;
+  this->inputLine = addCharLine;
+  this->setText(this->inputLine, true);
+}
+
+/**
+ * adds multiple Characters to thr inputLine
+ * @param characters a \\0 terminated char-array to add to the InputLine
+ */
+void ShellInput::addCharacters(const char* characters)
+{
+  if (this->historyScrolling)
+  {
+    delete[] this->history.back();
+    this->history.pop_back();
+    this->historyScrolling = false;
+  }
+
+  char* addCharLine = new char[strlen(this->inputLine)+strlen(characters)+1];
+
+  sprintf(addCharLine, "%s%s", this->inputLine, characters);
+  delete[] this->inputLine;
+  this->inputLine = addCharLine;
+  this->setText(this->inputLine, true);
+}
+
+/**
+ * removes characterCount characters from the InputLine
+ * @param characterCount the count of Characters to remove from the input Line
+ */
+void ShellInput::removeCharacters(unsigned int characterCount)
+{
+  if (this->historyScrolling)
+  {
+    delete[] this->history.back();
+    this->history.pop_back();
+    this->historyScrolling = false;
+  }
+
+  if (strlen(this->inputLine) == 0)
+    return;
+
+  if (characterCount > strlen(this->inputLine))
+    characterCount = strlen(this->inputLine);
+
+  char* removeCharLine = new char[strlen(this->inputLine)-characterCount+1];
+
+  strncpy(removeCharLine, this->inputLine, strlen(this->inputLine)-characterCount);
+  removeCharLine[strlen(this->inputLine)-characterCount] = '\0';
+  delete[] this->inputLine;
+  this->inputLine = removeCharLine;
+  this->setText(this->inputLine, true);
+}
+
+/**
+ * executes the command stored in the inputLine
+ * @return true if the command was commited successfully, false otherwise
+ */
+bool ShellInput::executeCommand()
+{
+  ShellBuffer::addBufferLineStatic("Execute Command: %s\n", this->inputLine);
+
+  if (strlen(this->inputLine) == 0)
+    return false;
+
+  char* newCommand = new char[strlen(this->inputLine)+1];
+  strcpy(newCommand, this->inputLine);
+
+  ShellCommand::execute(newCommand);
+
+  // removing the eventually added Entry (from scrolling) to the List
+  if (this->historyScrolling)
+  {
+    delete[] this->history.back();
+    this->history.pop_back();
+    this->historyScrolling = false;
+  }
+
+  // adding the new Command to the History
+  this->history.push_back(newCommand);
+  if (this->history.size() > this->historyLength)
+  {
+    delete[] this->history.front();
+    this->history.pop_front();
+  }
+
+  this->flush();
+
+  return true;
+}
+
+
+/**
+ * moves one entry up in the history.
+ */
+void ShellInput::historyMoveUp()
+{
+  if (!this->historyScrolling)
+  {
+    char* currentText = new char[strlen(this->inputLine)+1];
+    strcpy(currentText, this->inputLine);
+    this->history.push_back(currentText);
+    this->historyScrolling = true;
+    this->historyIT = --this->history.end();
+  }
+
+  if(this->historyIT != this->history.begin())
+  {
+    char* prevElem = *(--this->historyIT);
+    if (prevElem == NULL)
+      return;
+    else
+    {
+      this->flush();
+      this->setInputText(prevElem);
+    }
+  }
+}
+
+/**
+ * moves one entry down in the history
+ */
+void ShellInput::historyMoveDown()
+{
+  if (!this->historyScrolling)
+    return;
+  if (this->historyIT != this->history.end())
+  {
+    char* nextElem = *(++this->historyIT);
+    if (nextElem == NULL)
+      return;
+    else
+    {
+      this->flush();
+      this->setInputText(nextElem);
+    }
+  }
+}
+
+
+/**
+ * prints out some nice help about the Shell
+ */
+void ShellInput::help(const char* className, const char* functionName)
+{
+  printf("%s::%s\n", className, functionName);
+
+  if (strlen(className) == 0)
+  {
+    PRINT(0)("Help for the most important Shell-commands\n");
+    PRINT(0)("F1 - HELP; F2 - DEBUG; '`' - open/close shell\n");
+    PRINT(0)("input order:\n");
+    PRINT(0)("ClassName [objectName] function [parameter1, [parameter2 ...]]  or\n");
+    PRINT(0)("Alias [parameter]\n");
+    PRINT(0)("- Also try 'help className'");
+  }
+  else if (strlen (className) > 0 && strlen (functionName) == 0)
+  {
+    ShellCommandClass::help(className);
+    //PRINTF(1)("%s::%s\n", className, functionName);
+  }
+}
+
+/**
+ * ticks the ShellInput
+ * @param dt the time passed since the last update
+ */
+void ShellInput::tick(float dt)
+{
+  if (this->delayed > 0.0)
+    this->delayed -= dt;
+  else if (this->pressedKey != SDLK_FIRST )
+  {
+    this->delayed = this->repeatRate;
+    switch (this->pressedKey )
+    {
+      case SDLK_BACKSPACE:
+        this->removeCharacters(1);
+        break;
+      case SDLK_UP:
+        this->historyMoveUp();
+        break;
+      case SDLK_DOWN:
+        this->historyMoveDown();
+        break;
+      default:
+      {
+        if (likely(pressedKey < 127))
+          this->addCharacter(this->pressedKey);
+      }
+    }
+  }
+}
+
+/**
+ * listens for some event
+ * @param event the Event happened
+ */
+void ShellInput::process(const Event &event)
+{
+  if (event.bPressed)
+  {
+    PRINTF(5)("Shell received command %s\n", SDLKToKeyname(event.type));
+    if (event.type == SDLK_F1)
+      this->help();
+    else if (event.type == SDLK_F2)
+    {
+      ;//this->debug();
+    }
+    else if (event.type == SDLK_UP)
+    {
+      this->historyMoveUp();
+      this->pressedKey = event.type;
+    }
+    else if (event.type == SDLK_DOWN)
+    {
+      this->historyMoveDown();
+      this->pressedKey = event.type;
+    }
+    else if (event.type == SDLK_TAB)
+      this->completion->autoComplete();
+    else if (event.type == SDLK_BACKSPACE)
+    {
+      this->delayed = this->repeatDelay;
+      this->pressedKey = SDLK_BACKSPACE;
+      this->removeCharacters(1);
+    }
+    else if (event.type == SDLK_RETURN)
+    {
+      this->executeCommand();
+      this->pressedKey = event.type;
+    }
+    // any other keyboard key
+    else if (likely(event.type < 127))
+    {
+      this->addCharacter(event.x);
+      this->pressedKey = event.x;
+    }
+    this->delayed = this->repeatDelay;
+  }
+  else // if(!event.bPressed)
+  {
+    if (this->pressedKey == event.x || this->pressedKey == event.type)
+    {
+      this->pressedKey = 0;
+      this->delayed = 0.0;
+    }
+  }
+}
Index: branches/network/src/lib/shell/shell_input.h
===================================================================
--- branches/network/src/lib/shell/shell_input.h	(revision 6636)
+++ branches/network/src/lib/shell/shell_input.h	(revision 6636)
@@ -0,0 +1,70 @@
+/*!
+ * @file shell_input.h
+ * @brief Shell Input is an InputLine for the Shell.
+ *
+ * @todo move around in the InputText with the cursor (SDLK_LEFT/SDLK_RIGHT)
+ * @todo blinking curson (can blink with the speed of the RepeatDelay)
+*/
+
+#ifndef _SHELL_INPUT_H
+#define _SHELL_INPUT_H
+
+#include "text.h"
+#include "event_listener.h"
+#include <list>
+
+// FORWARD DECLARATION
+class ShellCompletion;
+
+//! An InputLine for the Shell
+/**
+ * The ShellInput has the ability to catch and display user input.
+ * The ShellInput is auto-completed after the user presses [TAB]
+ * The ShellInput is executed (and sent back to the Application) on Pressing [ENTER]
+ * [UP] and [DOWN] move through the history of allready given commands.
+ */
+class ShellInput : public Text,  public EventListener {
+
+ public:
+  ShellInput();
+  virtual ~ShellInput();
+
+  /** @returns the inputLine */
+  const char* getInput() const { return this->inputLine; };
+
+  // InputLine
+  void flush();
+  void setInputText(const char* text);
+  void addCharacter(char character);
+  void addCharacters(const char* characters);
+  void removeCharacters(unsigned int characterCount = 1);
+  void setRepeatDelay(float repeatDelay, float repeatRate);
+  bool executeCommand();
+
+  /** sets the count of the History's entries */
+  void setHistoryLength(unsigned int historyLength) { this->historyLength = historyLength; };
+  void historyMoveUp();
+  void historyMoveDown();
+
+  void help(const char* className = "", const char* function = "");
+
+  virtual void tick(float dt);
+  virtual void process(const Event &event);
+
+ private:
+    // HANDLING TEXT INPUT
+   ShellCompletion*            completion;             //!< The Completion Interface.
+
+   char*                       inputLine;              //!< the Char-Array of the Buffer
+   float                       repeatRate;             //!< The Repeat-Delay.
+   float                       repeatDelay;            //!< The delay of the first Character of a given Character.
+   float                       delayed;                //!< how much of the delay is remaining.
+   Uint16                      pressedKey;             //!< the pressed key that will be repeated.
+
+   std::list<char*>            history;                //!< The history of given commands.
+   std::list<char*>::iterator  historyIT;
+   unsigned int                historyLength;          //!< The maximum length of the InputHistory.
+   bool                        historyScrolling;       //!< true if we are scrolling through the history.
+};
+
+#endif /* _SHELL_INPUT_H */
Index: branches/network/src/lib/sound/Makefile.am
===================================================================
--- branches/network/src/lib/sound/Makefile.am	(revision 6636)
+++ branches/network/src/lib/sound/Makefile.am	(revision 6636)
@@ -0,0 +1,14 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXsound.a
+
+libORXsound_a_SOURCES = sound_engine.cc \
+			sound_source.cc \
+			sound_buffer.cc \
+                        ogg_player.cc
+
+noinst_HEADERS = sound_engine.h \
+		 sound_source.h \
+		 sound_buffer.h \
+                 ogg_player.h
Index: branches/network/src/lib/sound/ogg_player.cc
===================================================================
--- branches/network/src/lib/sound/ogg_player.cc	(revision 6636)
+++ branches/network/src/lib/sound/ogg_player.cc	(revision 6636)
@@ -0,0 +1,268 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+
+
+   -------------------------------------------------------------------
+   The source of this file comes stright from http://www.devmaster.net
+   Thanks a lot for the nice work, and the easy portability to our Project.
+*/
+
+#include <iostream>
+
+#include "ogg_player.h"
+
+#include "sound_engine.h"
+
+#include "debug.h"
+
+/**
+ * initializes an Ogg-player from a file
+ * @param fileName the file to load
+ */
+OggPlayer::OggPlayer(const char* fileName)
+{
+  this->setClassID(CL_SOUND_OGG_PLAYER, "OggPlayer");
+  if (fileName != NULL)
+  {
+    this->open(fileName);
+    this->setName(fileName);
+  }
+}
+
+/**
+ * opens a file for playback
+ * @param fileName the file to open
+ */
+void OggPlayer::open(const char* fileName)
+{
+    int result;
+
+    if(!(oggFile = fopen(fileName, "rb")))
+        PRINTF(2)("Could not open Ogg file.");
+
+    if((result = ov_open(oggFile, &oggStream, NULL, 0)) < 0)
+    {
+        fclose(oggFile);
+
+        PRINTF(2)("Could not open Ogg stream. %s", errorString(result));
+    }
+
+    vorbisInfo = ov_info(&oggStream, -1);
+    vorbisComment = ov_comment(&oggStream, -1);
+
+    if(vorbisInfo->channels == 1)
+        format = AL_FORMAT_MONO16;
+    else
+        format = AL_FORMAT_STEREO16;
+
+
+    alGenBuffers(2, buffers);
+    check();
+    alGenSources(1, &source);
+    check();
+
+    alSource3f(source, AL_POSITION,        0.0, 0.0, 0.0);
+    alSource3f(source, AL_VELOCITY,        0.0, 0.0, 0.0);
+    alSource3f(source, AL_DIRECTION,       0.0, 0.0, 0.0);
+    alSourcef (source, AL_ROLLOFF_FACTOR,  0.0          );
+    alSourcei (source, AL_SOURCE_RELATIVE, AL_TRUE      );
+    alSourcef (source, AL_GAIN,            SoundEngine::getInstance()->getMusicVolume());
+}
+
+/**
+ * releases a stream
+ */
+void OggPlayer::release()
+{
+    alSourceStop(source);
+    empty();
+    alDeleteSources(1, &source);
+    check();
+    alDeleteBuffers(1, buffers);
+    check();
+
+    ov_clear(&oggStream);
+}
+
+/**
+ * displays some info about the ogg-file
+ */
+void OggPlayer::display()
+{
+    cout
+        << "version         " << vorbisInfo->version         << "\n"
+        << "channels        " << vorbisInfo->channels        << "\n"
+        << "rate (hz)       " << vorbisInfo->rate            << "\n"
+        << "bitrate upper   " << vorbisInfo->bitrate_upper   << "\n"
+        << "bitrate nominal " << vorbisInfo->bitrate_nominal << "\n"
+        << "bitrate lower   " << vorbisInfo->bitrate_lower   << "\n"
+        << "bitrate window  " << vorbisInfo->bitrate_window  << "\n"
+        << "\n"
+        << "vendor " << vorbisComment->vendor << "\n";
+
+    for(int i = 0; i < vorbisComment->comments; i++)
+        cout << "   " << vorbisComment->user_comments[i] << "\n";
+
+    cout << endl;
+}
+
+
+/**
+ * plays back the sound
+ * @return true if running, false otherwise
+ */
+bool OggPlayer::playback()
+{
+    if(playing())
+        return true;
+
+    if(!stream(buffers[0]))
+        return false;
+
+    if(!stream(buffers[1]))
+        return false;
+
+    alSourceQueueBuffers(source, 2, buffers);
+    alSourcePlay(source);
+
+    return true;
+}
+
+/**
+ *
+ * @returns true if the file is playing
+ */
+bool OggPlayer::playing()
+{
+    ALenum state;
+
+    alGetSourcei(source, AL_SOURCE_STATE, &state);
+
+    return (state == AL_PLAYING);
+}
+
+/**
+ * updates the stream, this has to be done every few parts of a second, for sound-consistency
+ * @returns true, if the Sound is playing flawlessly
+ */
+bool OggPlayer::update()
+{
+    int processed;
+    bool active = true;
+
+    alGetSourcei(source, AL_BUFFERS_PROCESSED, &processed);
+
+    while(processed--)
+    {
+        ALuint buffer;
+
+        alSourceUnqueueBuffers(source, 1, &buffer);
+        check();
+
+        active = stream(buffer);
+
+        alSourceQueueBuffers(source, 1, &buffer);
+        check();
+    }
+
+    return active;
+}
+
+/**
+ * gets a new Stream from buffer
+ * @param buffer the buffer to get the stream from
+ * @return true, if everything worked as planed
+ */
+bool OggPlayer::stream(ALuint buffer)
+{
+    char pcm[BUFFER_SIZE];
+    int  size = 0;
+    int  section;
+    int  result;
+
+    while(size < BUFFER_SIZE)
+    {
+        result = ov_read(&oggStream, pcm + size, BUFFER_SIZE - size, 0, 2, 1, &section);
+
+        if(result > 0)
+            size += result;
+        else
+            if(result < 0)
+                throw errorString(result);
+            else
+                break;
+    }
+
+    if(size == 0)
+        return false;
+
+    alBufferData(buffer, format, pcm, size, vorbisInfo->rate);
+    check();
+
+    return true;
+}
+
+
+/**
+ * empties the buffers
+ */
+void OggPlayer::empty()
+{
+    int queued;
+
+    alGetSourcei(source, AL_BUFFERS_QUEUED, &queued);
+
+    while(queued--)
+    {
+        ALuint buffer;
+
+        alSourceUnqueueBuffers(source, 1, &buffer);
+        check();
+    }
+}
+
+/**
+ * checks for errors
+ */
+void OggPlayer::check()
+{
+        int error = alGetError();
+
+        if(error != AL_NO_ERROR)
+                PRINTF(2)("OpenAL error was raised.");
+}
+
+/**
+ * returns errors
+ * @param code the error-code
+ * @return the error as a String
+ */
+const char* OggPlayer::errorString(int code)
+{
+     switch(code)
+     {
+       case OV_EREAD:
+         return ("Read from media.");
+       case OV_ENOTVORBIS:
+         return ("Not Vorbis data.");
+       case OV_EVERSION:
+         return ("Vorbis version mismatch.");
+       case OV_EBADHEADER:
+         return ("Invalid Vorbis header.");
+       case OV_EFAULT:
+         return ("Internal logic fault (bug or heap/stack corruption.");
+       default:
+         return ("Unknown Ogg error.");
+     }
+}
Index: branches/network/src/lib/sound/ogg_player.h
===================================================================
--- branches/network/src/lib/sound/ogg_player.h	(revision 6636)
+++ branches/network/src/lib/sound/ogg_player.h	(revision 6636)
@@ -0,0 +1,58 @@
+/*!
+ * @file ogg_player.h
+ * Ogg-Player definition
+ */
+
+
+#ifndef _OGG_PLAYER_H
+#define _OGG_PLAYER_H
+
+using namespace std;
+
+#include "base_object.h"
+
+#include "alincl.h"
+#include <ogg/ogg.h>
+#include <vorbis/vorbisfile.h>
+
+struct File;
+
+
+
+#define BUFFER_SIZE (4096 * 4)
+
+
+// the definition of a Ogg-Player
+class OggPlayer : public BaseObject
+  {
+  public:
+    OggPlayer(const char* fileName = NULL);
+
+    void open(const char* fileName);
+    void release();
+    void display();
+    bool playback();
+    bool playing();
+    bool update();
+
+  protected:
+
+    bool stream(ALuint buffer);
+    void empty();
+    void check();
+    const char* errorString(int code);
+
+  private:
+
+    FILE*               oggFile;              //!< general file-handler, to open the sound-file
+    OggVorbis_File      oggStream;            //!< The stream this Ogg-player is playing back
+    vorbis_info*        vorbisInfo;           //!< The information held in the opened ogg-file
+    vorbis_comment*     vorbisComment;        //!< Comments about the ogg-file
+
+    ALuint              buffers[2];           //!< buffers that handle sequentially buffering of the audio
+    ALuint              source;               //!< The source we play back on
+    ALenum              format;               //!< The format we play back
+  };
+
+
+#endif /* _OGG_PLAYER_H */
Index: branches/network/src/lib/sound/sound_buffer.cc
===================================================================
--- branches/network/src/lib/sound/sound_buffer.cc	(revision 6636)
+++ branches/network/src/lib/sound/sound_buffer.cc	(revision 6636)
@@ -0,0 +1,74 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SOUND
+
+#include "sound_buffer.h"
+
+#include "sound_engine.h"
+
+using namespace std;
+
+//////////////////
+/* SOUND-BUFFER */
+//////////////////
+/**
+ *  Creates a Soundbuffer out of an inputfile
+ * @param fileName The name of the File
+ */
+SoundBuffer::SoundBuffer(const char* fileName)
+{
+  this->setClassID(CL_SOUND_BUFFER, "SoundBuffer");
+  this->setName(fileName);
+
+  ALenum format;
+  ALvoid* data;
+  ALsizei freq;
+
+  ALenum result;
+
+  // generate a Buffer
+  alGenBuffers(1, &this->bufferID);
+  if ((result = alGetError()) != AL_NO_ERROR)
+    PRINTF(2)("%s\n", SoundEngine::getALErrorString(result));
+
+  // read in the wav data
+  /* according to http://www.edenwaith.com/products/pige/tutorials/openal.php the alutLoadWAVFile differs from platform to platform*/
+#ifdef __APPLE__
+  alutLoadWAVFile((ALbyte*)fileName, &format, &data, &this->size, &freq);
+#elif defined __WIN32__
+  alutLoadWAVFile((ALbyte*)fileName, &format, &data, &size, &freq, &this->loop);
+#else
+  alutLoadWAVFile((ALbyte*)fileName, &format, &data, &this->size, &freq, &this->loop);
+#endif
+  if ((result = alGetError()) != AL_NO_ERROR)
+    PRINTF(2)("%s\n", SoundEngine::getALErrorString(result));
+
+  // send the loaded wav data to the buffer
+  alBufferData(this->bufferID, format, data, this->size, freq);
+  if ((result = alGetError()) != AL_NO_ERROR)
+    PRINTF(2)("%s\n", SoundEngine::getALErrorString(result));
+
+  // remove the wav data (redundant)
+  alutUnloadWAV(format, data, this->size, freq);
+  if ((result = alGetError()) != AL_NO_ERROR)
+    PRINTF(2)("%s\n", SoundEngine::getALErrorString(result));
+}
+
+SoundBuffer::~SoundBuffer()
+{
+//  SoundEngine::getInstance()->removeBuffer(this);
+  alDeleteBuffers(1, &this->bufferID);
+}
Index: branches/network/src/lib/sound/sound_buffer.h
===================================================================
--- branches/network/src/lib/sound/sound_buffer.h	(revision 6636)
+++ branches/network/src/lib/sound/sound_buffer.h	(revision 6636)
@@ -0,0 +1,31 @@
+/*!
+ * @file sound_buffer.h
+ * @brief Definition of the sound-buffer-class
+*/
+
+#ifndef _SOUND_BUFFER_H
+#define _SOUND_BUFFER_H
+
+#include "base_object.h"
+#include "alincl.h"
+
+// FORWARD DECLARATION
+
+//! A class that represents a datastructure to play Sounds.
+class SoundBuffer : public BaseObject
+{
+  public:
+    SoundBuffer(const char* fileName);
+    ~SoundBuffer();
+
+    /** @returns the ID of the buffer used in this SoundBuffer */
+    inline ALuint getID() const { return this->bufferID; }
+
+  private:
+    ALuint        bufferID;             //!< The address of the Buffer.
+
+    ALsizei       size;                 //!< The size of the Buffer.
+    ALboolean     loop;                 //!< loop information.
+};
+
+#endif /* _SOUND_BUFFER_H */
Index: branches/network/src/lib/sound/sound_engine.cc
===================================================================
--- branches/network/src/lib/sound/sound_engine.cc	(revision 6636)
+++ branches/network/src/lib/sound/sound_engine.cc	(revision 6636)
@@ -0,0 +1,397 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+
+   code has been taken from http://www.devmaster.net/articles.php?catID=6
+   The code has been applied to our needs, and many things have been changed.
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SOUND
+
+#include "sound_engine.h"
+
+#include "class_list.h"
+
+#include "p_node.h"
+#include "resource_manager.h"
+#include "debug.h"
+#include "parser/ini_parser/ini_parser.h"
+#include "globals.h"
+
+using namespace std;
+
+
+//////////////////
+/* SOUND-ENGINE */
+//////////////////
+/**
+ *  standard constructor
+*/
+SoundEngine::SoundEngine ()
+{
+  this->setClassID(CL_SOUND_ENGINE, "SoundEngine");
+  this->setName("SoundEngine");
+
+  this->listener = NULL;
+  this->bufferList = NULL;
+  this->sourceList = NULL;
+
+  this->device = NULL;
+  this->context = NULL;
+
+  this->maxSourceCount = 32;
+}
+
+/**
+ *  the singleton reference to this class
+*/
+SoundEngine* SoundEngine::singletonRef = NULL;
+
+/**
+ *  standard deconstructor
+ */
+SoundEngine::~SoundEngine ()
+{
+  // deleting all the SoundSources
+  if(this->sourceList != NULL)
+  {
+    while (this->sourceList->size() > 0)
+      delete dynamic_cast<SoundSource*>(this->sourceList->front());
+  }
+
+  while(!this->ALSources.empty())
+  {
+    alDeleteSources(1, &this->ALSources.top());
+    this->ALSources.pop();
+  }
+
+  // deleting all the SoundBuffers
+  if (this->bufferList != NULL)
+  {
+    while(this->bufferList->size() > 0)
+      ResourceManager::getInstance()->unload(dynamic_cast<SoundBuffer*>(this->bufferList->front()));
+  }
+
+  // removing openAL from AudioResource
+  //! @todo this should be terminated through alc
+  //alutExit();
+
+  SoundEngine::singletonRef = NULL;
+}
+
+/**
+ * loads the settings of the SoundEngine from an ini-file
+ * @param iniParser the IniParser of the inifile
+ */
+void SoundEngine::loadSettings(IniParser* iniParser)
+{
+  const char* channels = iniParser->getVar(CONFIG_NAME_AUDIO_CHANNELS, CONFIG_SECTION_AUDIO, "32");
+  this->maxSourceCount = atoi(channels);
+  const char* musicVolume = iniParser->getVar(CONFIG_NAME_MUSIC_VOLUME, CONFIG_SECTION_AUDIO, "80");
+  this->musicVolume = atof(musicVolume)/100.0;
+
+  const char* effectsVolume = iniParser->getVar(CONFIG_NAME_EFFECTS_VOLUME, CONFIG_SECTION_AUDIO, "80");
+  this->effectsVolume = atof(effectsVolume)/100.0;
+}
+
+/**
+ *  creates a new SoundSource.
+ * @param fileName The Name to load the SoundBuffer from
+ * @param sourceNode The sourceNode to bind this SoundSource to.
+ * @returns The newly created SoundSource
+
+   acctualy this is nothing more than a wrapper around the ResourceManager.
+*/
+SoundSource* SoundEngine::createSource(const char* fileName, PNode* sourceNode)
+{
+  return new SoundSource(sourceNode, (SoundBuffer*)ResourceManager::getInstance()->load(fileName, WAV, RP_LEVEL));
+}
+
+/**
+ *  Sets the doppler values of openAL
+ * @param dopplerFactor the extent of the doppler-effect
+ * @param dopplerVelocity the Speed the sound travels
+*/
+void SoundEngine::setDopplerValues(ALfloat dopplerFactor, ALfloat dopplerVelocity)
+{
+  alDopplerFactor(dopplerFactor);
+  alDopplerVelocity(dopplerVelocity);
+}
+
+
+void SoundEngine::popALSource(ALuint& source)
+{
+  if (source != 0)
+    return;
+  else
+  {
+
+    /// @TODO try to create more sources if needed
+    if (!this->ALSources.empty())
+    {
+      source = this->ALSources.top();
+      this->ALSources.pop();
+    }
+  }
+}
+
+
+/**
+ *  updates all The positions, Directions and Velocities of all Sounds
+*/
+void SoundEngine::update()
+{
+
+  // updating the Listeners Position
+  if (likely(this->listener != NULL))
+    {
+      alListener3f(AL_POSITION,
+                   this->listener->getAbsCoor().x,
+                   this->listener->getAbsCoor().y,
+                   this->listener->getAbsCoor().z);
+      alListener3f(AL_VELOCITY,
+                   this->listener->getVelocity().x,
+                   this->listener->getVelocity().y,
+                   this->listener->getVelocity().z);
+      Vector absDirV = this->listener->getAbsDirV();
+      ALfloat orientation [6] = {1,0,0, absDirV.x, absDirV.y, absDirV.z};
+      alListenerfv(AL_ORIENTATION, orientation);
+    }
+  else
+    PRINTF(2)("no listener defined\n");
+
+  // updating all the Sources positions
+  if (likely(this->sourceList != NULL || (this->sourceList = ClassList::getList(CL_SOUND_SOURCE)) != NULL))
+  {
+    list<BaseObject*>::const_iterator sourceIT;
+    SoundSource* source;
+    for (sourceIT = this->sourceList->begin(); sourceIT != this->sourceList->end(); sourceIT++)
+    {
+      source = static_cast<SoundSource*>(*sourceIT);
+      if (source->isPlaying())
+      {
+        int play = 0x000;
+        alGetSourcei(source->getID(), AL_SOURCE_STATE, &play);
+        if(play == AL_PLAYING)
+        {
+          if (likely(source->getNode() != NULL))
+          {
+            alSource3f(source->getID(), AL_POSITION,
+                       source->getNode()->getAbsCoor().x,
+                       source->getNode()->getAbsCoor().y,
+                       source->getNode()->getAbsCoor().z);
+            alSource3f(source->getID(), AL_VELOCITY,
+                       source->getNode()->getVelocity().x,
+                       source->getNode()->getVelocity().y,
+                       source->getNode()->getVelocity().z);
+          }
+
+        }
+        else
+        {
+          source->stop();
+        }
+      }
+    }
+  }
+}
+
+/**
+ *  Removes all the Buffers that are not anymore needed by any Sources
+*/
+void SoundEngine::flushUnusedBuffers()
+{
+  /// FIXME
+/*  if(this->sourceList && this->bufferList)
+  {
+    tIterator<BaseObject>* bufferIterator = this->bufferList->getIterator();
+    SoundBuffer* enumBuffer = (SoundBuffer*)bufferIterator->firstElement();
+    while (enumBuffer)
+    {
+      tIterator<BaseObject>* sourceIterator = this->sourceList->getIterator();
+      SoundSource* enumSource = (SoundSource*)sourceIterator->firstElement();
+      while (enumSource)
+      {
+        if (enumBuffer == enumSource->getBuffer())
+          break;
+        enumSource = (SoundSource*)sourceIterator->nextElement();
+      }
+      delete sourceIterator;
+      if (enumSource == NULL)
+        ResourceManager::getInstance()->unload(enumBuffer);
+      enumBuffer = (SoundBuffer*)bufferIterator->nextElement();
+    }
+    delete bufferIterator;
+}*/ /// FIXME
+}
+
+/**
+ * flushes all the Buffers
+ * deletes them from the BufferList, and also removes them via the ResourceManager.
+ */
+void SoundEngine::flushAllBuffers()
+{
+  if (this->bufferList)
+  {
+    while (this->bufferList->size() > 0)
+      ResourceManager::getInstance()->unload(static_cast<SoundBuffer*>(this->bufferList->front()), RP_LEVEL);
+  }
+}
+
+/**
+ * deletes all the Sources.
+ */
+void SoundEngine::flushAllSources()
+{
+  if (this->sourceList)
+  {
+    while(this->sourceList->size() > 0)
+      delete this->sourceList->front();
+  }
+}
+
+/**
+ *  initializes Audio in general
+*/
+bool SoundEngine::initAudio()
+{
+  ALenum result;
+  PRINTF(3)("Initialisazing openAL sound engine\n");
+  const char* defaultDevice =(const char*) alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
+  const char* deviceList = (const char*)alcGetString(NULL,ALC_DEVICE_SPECIFIER);
+  const char* devWalk = deviceList;
+//  if (alcIsExtensionPresent(NULL, (const ALCchar*)"ALC_ENUMERATION_EXT") == AL_TRUE)
+{ // try out enumeration extension
+    PRINTF(3)("Enumeration-extension found\n");
+
+    PRINTF(3)("Default device: %s\n", defaultDevice);
+    do
+    {
+      PRINTF(3)("%s\n", devWalk);
+      devWalk += strlen(devWalk)+1;
+    } while (devWalk[0] != '\0');
+
+
+
+  }
+  // INITIALIZING THE DEVICE:
+
+#ifdef AL_VERSION_1_1
+  ALCchar deviceName[] =
+
+#ifdef __WIN32__
+      "Direct3D";
+#else
+      "'( ( devices '( native null ) ) )";
+#endif
+  //
+  this->device = alcOpenDevice(deviceName);
+
+  this->context = alcCreateContext(this->device, NULL);
+
+  alcMakeContextCurrent(this->context);
+#else
+  alutInit(0, NULL);
+#endif
+
+  if ((result = alGetError()) != AL_NO_ERROR)
+    PRINTF(2)("%s\n", SoundEngine::getALErrorString(result));
+
+  this->setDopplerValues(SOUND_DOPPLER_FACTOR, SOUND_DOPPLER_VELOCITY);
+}
+
+
+/**
+ * Allocates openAL sources
+ * @param count how many sources to allocate
+ * @returns true on success, false if at least one source could not be allocated
+ */
+bool SoundEngine::allocateSources(unsigned int count)
+{
+  ALenum result;
+  // Setting default values.
+  for (unsigned int i = 0; i < count; i++)
+  {
+    ALuint source;
+
+    alGenSources(1, &source);
+    if ((result = alGetError()) != AL_NO_ERROR)
+      PRINTF(1)("Error Generating Sources: '%s'\n", SoundEngine::getALErrorString(result));
+
+    alSourcef (source, AL_PITCH,    1.0      );
+    alSourcef (source, AL_GAIN,     this->getEffectsVolume() );
+    alSourcei (source, AL_LOOPING,  AL_FALSE );
+    this->ALSources.push(source);
+  }
+  return true;
+}
+
+/**
+ *  Transforms AL-errors into something readable
+ * @param err The error found
+*/
+const char* SoundEngine::getALErrorString(ALenum err)
+{
+  switch(err)
+    {
+    case AL_NO_ERROR:
+      return ("AL_NO_ERROR");
+    case AL_INVALID_NAME:
+      return ("AL_INVALID_NAME");
+    case AL_INVALID_ENUM:
+      return ("AL_INVALID_ENUM");
+    case AL_INVALID_VALUE:
+      return ("AL_INVALID_VALUE");
+    case AL_INVALID_OPERATION:
+      return ("AL_INVALID_OPERATION");
+    case AL_OUT_OF_MEMORY:
+      return ("AL_OUT_OF_MEMORY");
+    };
+}
+
+void SoundEngine::listDevices()
+{
+  printf("%s\n",(const char*)alcGetString(NULL, ALC_DEVICE_SPECIFIER));
+}
+
+/*
+void SoundEngine::PrintALCErrorString(ALenum err)
+{
+  switch(err)
+    {
+    case ALC_NO_ERROR:
+      PRINTF(4)("AL_NO_ERROR\n");
+      break;
+
+    case ALC_INVALID_DEVICE:
+      PRINTF(2)("ALC_INVALID_DEVICE\n");
+      break;
+
+    case ALC_INVALID_CONTEXT:
+      PRINTF(2)("ALC_INVALID_CONTEXT\n");
+      break;
+
+    case ALC_INVALID_ENUM:
+      PRINTF(2)("ALC_INVALID_ENUM\n");
+      break;
+
+    case ALC_INVALID_VALUE:
+      PRINTF(2)("ALC_INVALID_VALUE\n");
+      break;
+
+    case ALC_OUT_OF_MEMORY:
+      PRINTF(2)("ALC_OUT_OF_MEMORY\n");
+      break;
+    };
+}
+*/
Index: branches/network/src/lib/sound/sound_engine.h
===================================================================
--- branches/network/src/lib/sound/sound_engine.h	(revision 6636)
+++ branches/network/src/lib/sound/sound_engine.h	(revision 6636)
@@ -0,0 +1,85 @@
+/*!
+ * @file sound_engine.h
+ * Definition of the SoundEngine singleton Class
+ */
+
+#ifndef _SOUND_ENGINE_H
+#define _SOUND_ENGINE_H
+
+#include "base_object.h"
+#include "alincl.h"
+
+#include "sound_buffer.h"
+#include "sound_source.h"
+
+#include <list>
+#include <stack>
+
+#define SOUND_DOPPLER_FACTOR       0.001          //!< A factor for the audible doppler effect
+#define SOUND_DOPPLER_VELOCITY     5000000        //!< A factor for the TravelSpeed of sound
+
+// FORWARD DECLARATION
+class PNode;
+class IniParser;
+
+
+//! A class that handles audio via the openAudioLibrary
+class SoundEngine : public BaseObject {
+  public:
+    virtual ~SoundEngine();
+    /** @returns a Pointer to the only object of this Class */
+    inline static SoundEngine* getInstance() { if (!SoundEngine::singletonRef) SoundEngine::singletonRef = new SoundEngine();  return SoundEngine::singletonRef; };
+
+    void loadSettings(IniParser* iniParser);
+
+    SoundSource* createSource(const char* fileName, PNode* sourceNode = NULL);
+
+    /** @param listener the listener in the scene */
+    void setListener(PNode* listener) { this->listener = listener; };
+    void setDopplerValues(ALfloat dopplerFactor, ALfloat dopplerVelocity);
+
+
+    /** @returns the Music Volume in % */
+    inline float getMusicVolume() { return this->musicVolume; };
+    /** @returns the Effects Volume in % */
+    inline float getEffectsVolume() { return this->effectsVolume; };
+
+    void update();
+
+  // administrative
+    void popALSource(ALuint& source);
+    void pushALSource(ALuint& source) { if (source != 0) this->ALSources.push(source); };
+
+    void flushUnusedBuffers();
+    void flushAllBuffers();
+    void flushAllSources();
+
+    bool initAudio();
+    bool allocateSources(unsigned int count);
+
+  // error handling:
+    static const char* getALErrorString(ALenum err);
+
+  private:
+    SoundEngine();
+
+    void listDevices();
+
+  private:
+    static SoundEngine*            singletonRef;             //!< Reference to this class
+
+    ALCdevice*                     device;                   //!< the used audio-device.
+    ALCcontext*                    context;                  //!< the context, currently in use.
+
+    float                          musicVolume;              //!< the maximum volume of the music in % (0f,1f]
+    float                          effectsVolume;            //!< the maximum volume of sound-effects in % (0f,1f]
+    PNode*                         listener;                 //!< The listener of the Scene
+
+    const std::list<BaseObject*>*  bufferList;               //!< A list of buffers
+    const std::list<BaseObject*>*  sourceList;               //!< A list for all the sources in the scene.
+
+    unsigned int                   maxSourceCount;           //!< How many Sources is the Maximum
+    std::stack<ALuint>             ALSources;                //!< A list of real openAL-Sources, the engine allocates, and stores for reuse.
+};
+
+#endif /* _SOUND_ENGINE_H */
Index: branches/network/src/lib/sound/sound_source.cc
===================================================================
--- branches/network/src/lib/sound/sound_source.cc	(revision 6636)
+++ branches/network/src/lib/sound/sound_source.cc	(revision 6636)
@@ -0,0 +1,116 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_SOUND
+
+#include "sound_source.h"
+#include "sound_engine.h"
+
+#include "alincl.h"
+#include "compiler.h"
+
+using namespace std;
+
+/**
+ *  creates a SoundSource at position sourceNode with the SoundBuffer buffer
+ */
+SoundSource::SoundSource(const PNode* sourceNode, const SoundBuffer* buffer)
+{
+  this->setClassID(CL_SOUND_SOURCE, "SoundSource");
+
+  ALenum result;
+
+  // adding the Source to the SourcesList of the SoundEngine
+  this->buffer = buffer;
+  this->sourceNode = sourceNode;
+
+  this->sourceID = 0;
+  this->bPlay = false;
+}
+
+/**
+ *  deletes a SoundSource
+ */
+SoundSource::~SoundSource()
+{
+  SoundEngine::getInstance()->pushALSource(this->sourceID);
+}
+
+/**
+ *  Plays back a SoundSource
+ */
+void SoundSource::play()
+{
+  if (this->sourceID == 0)
+    SoundEngine::getInstance()->popALSource(this->sourceID);
+  alSourcePlay(this->sourceID);
+  this->bPlay = true;
+}
+
+/**
+ * Plays back buffer on this Source
+ * @param buffer the buffer to play back on this Source
+ */
+void SoundSource::play(const SoundBuffer* buffer)
+{
+  if (unlikely(this->sourceID == 0))
+    SoundEngine::getInstance()->popALSource(this->sourceID);
+
+  alSourceStop(this->sourceID);
+  alSourcei (this->sourceID, AL_BUFFER, buffer->getID());
+  alSourcePlay(this->sourceID);
+
+  if (unlikely(this->buffer != NULL))
+    alSourcei (this->sourceID, AL_BUFFER, this->buffer->getID());
+  this->bPlay = true;
+}
+
+/**
+ *  Stops playback of a SoundSource
+ */
+void SoundSource::stop()
+{
+  this->bPlay = false;
+  alSourceStop(this->sourceID);
+  SoundEngine::getInstance()->pushALSource(this->sourceID);
+}
+
+/**
+ *  Pauses Playback of a SoundSource
+ */
+void SoundSource::pause()
+{
+  alSourcePause(this->sourceID);
+}
+
+/**
+ *  Rewinds Playback of a SoundSource
+ */
+void SoundSource::rewind()
+{
+  alSourceRewind(this->sourceID);
+}
+
+/**
+ *  sets the RolloffFactor of the Sound emitted from the SoundSource
+ * @param rolloffFactor The Factor described
+
+   this tells openAL how fast the Sounds decay outward from the Source
+ */
+void SoundSource::setRolloffFactor(ALfloat rolloffFactor)
+{
+  alSourcef(this->sourceID, AL_ROLLOFF_FACTOR, rolloffFactor);
+}
+
Index: branches/network/src/lib/sound/sound_source.h
===================================================================
--- branches/network/src/lib/sound/sound_source.h	(revision 6636)
+++ branches/network/src/lib/sound/sound_source.h	(revision 6636)
@@ -0,0 +1,48 @@
+/*!
+ * @file sound_source.h
+ * @brief Definition of the SoundSource.
+*/
+
+#ifndef _SOUND_SOURCE_H
+#define _SOUND_SOURCE_H
+
+#include "base_object.h"
+#include "alincl.h"
+
+// FORWARD DECLARATION
+class SoundBuffer;
+class PNode;
+
+//! A class that represents a SoundSource
+class SoundSource : public BaseObject
+{
+  public:
+    SoundSource(const PNode* sourceNode = NULL, const SoundBuffer* buffer = NULL);
+    ~SoundSource();
+
+  // user interaction
+    void play();
+    void play(const SoundBuffer* buffer);
+    void stop();
+    void pause();
+    void rewind();
+
+  // development functions
+    /** @returns The ID of this Source */
+    inline ALuint getID() const { return this->sourceID; }
+    /** @returns true, if the Source is Playing */
+    inline bool   isPlaying() const { return this->bPlay; };
+    /** @returns the SoundBuffer of this Source */
+    inline const SoundBuffer* getBuffer() const { return this->buffer; }
+    /** @returns the SourceNode of this Source */
+    inline const PNode* getNode() const { return this->sourceNode;}
+
+    void setRolloffFactor(ALfloat rolloffFactor);
+
+  private:
+    bool                   bPlay;                 //!< If the Source is Playing.
+    ALuint                 sourceID;              //!< The ID of the Source
+    const SoundBuffer*     buffer;                //!< The buffer to play in this source.
+    const PNode*           sourceNode;            //!< The SourceNode representing the position/velocity... of this source.
+};
+#endif /* _SOUND_SOURCE_H */
Index: branches/network/src/lib/util/array.h
===================================================================
--- branches/network/src/lib/util/array.h	(revision 6636)
+++ branches/network/src/lib/util/array.h	(revision 6636)
@@ -0,0 +1,203 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+/*!
+ * @file array.h
+ * @brief Contains the tArray Class that handles arrays of classes.
+ * this class creates a Array of a semi-Dynamic length.
+ * beware, that after finalizing the array may not be resized again.
+ *
+ * This array is very performant and usefull, if you need a Dynamic Array,
+ * that you fill once, and then only read the pushed in values to it again.
+ */
+
+#ifndef _ARRAY_H
+#define _ARRAY_H
+#include "debug.h"
+
+using namespace std;
+
+//! tArray Class that handles dynamic-type arrays.
+template<class T> class tArray
+{
+  public:
+    tArray ();
+    ~tArray();
+
+    void finalizeArray ();
+    void addEntry (T entry);
+    void addEntry(T entry0, T entry1, T entry2);
+
+    /** @returns The array */
+    inline T* getArray () const { return this->array; };
+    inline const T getEntry(unsigned int number) const;
+    /** * @returns The Count of entries in the Array*/
+    inline unsigned int getCount()const { return this->entryCount; };
+    inline int getIndex(T* entry) const;
+    inline bool isFinalized() const { return this->finalized; }
+    void debug() const ;
+
+  private:
+    //! One entry of the Array
+    struct Entry
+    {
+      T            value;          //!< The value of this Entry.
+      Entry*       next;           //!< Pointer to the Next entry.
+    };
+
+    T*            array;           //!< The array that will be produced when finalizing the Array.
+    unsigned int  entryCount;      //!< The count of Entries in this Array.
+    bool          finalized;       //!< If this variable is set to true, the Array can not be changed anymore. true if finalized, false else (initially).
+    Entry*        firstEntry;      //!< Pointer to the first Entry of this Array
+    Entry*        currentEntry;    //!< Pointer to the current Entry of this Array. The one Entry we are working with.
+};
+
+
+/**
+ *  creates a new Array
+*/
+template<class T>
+tArray<T>::tArray ()
+{
+  PRINTF(5)("crating new tArray\n");
+  this->firstEntry = new Entry;
+  this->firstEntry->next =NULL;
+  this->currentEntry = this->firstEntry;
+  this->finalized = false;
+  this->entryCount = 0; //0 means one entry
+}
+
+template<class T>
+    const T tArray<T>::getEntry(unsigned int number) const
+{
+  if (this->finalized && number < this->entryCount)
+    return this->array[number];
+}
+
+/**
+ *  deletes an Array.
+   It does this by first deleting all the array-entries, and then delete the array[] itself
+*/
+template<class T>
+tArray<T>::~tArray()
+{
+  PRINTF(5)("deleting array\n");
+  if (!this->finalized)
+  {
+    Entry* walker = this->firstEntry;
+    Entry* previous;
+    while (walker)
+    {
+      previous = walker;
+      walker = walker->next;
+      delete previous;
+    }
+  }
+  if (this->finalized)
+    delete[] this->array;
+}
+
+/**
+ *  finalizes an array.
+   This Function creates the array, and makes it ready to be sent to the application.
+*/
+template<class T>
+void tArray<T>::finalizeArray ()
+{
+  if (this->finalized)
+    return;
+  PRINTF(5)("Finalizing array. Length: %i\n", entryCount);
+  if (!(this->array = new T [this->entryCount]))
+    PRINTF(1)("could not allocate %i data Blocks\n", this->entryCount);
+  Entry* walker = this->firstEntry;
+  for (int i=0; i < this->entryCount; i++)
+  {
+    this->array[i] = walker->value;
+    walker = walker->next;
+  }
+  walker = this->firstEntry;
+  Entry* previous;
+  while (walker)
+  {
+    previous = walker;
+    walker = walker->next;
+    delete previous;
+  }
+  this->firstEntry = NULL;
+  this->finalized = true;
+}
+
+/**
+ *  adds a new Entry to the Array
+ * @param entry Entry to add.
+*/
+template<class T>
+void tArray<T>::addEntry (T entry)
+{
+  if (!this->finalized)
+  {
+    PRINTF(5)("adding new Entry to Array: %f\n", entry);
+
+    this->currentEntry->value = entry;
+    this->currentEntry->next = new Entry;
+    this->currentEntry = currentEntry->next;
+    this->currentEntry->next = NULL;
+    ++this->entryCount;
+  }
+  else
+    PRINTF(2)("adding failed, because array has already been finalized\n");
+}
+
+/**
+ *  Adds 3 entries at once (convenience)
+*/
+template<class T>
+void tArray<T>::addEntry (T entry0, T entry1, T entry2)
+{
+  this->addEntry(entry0);
+  this->addEntry(entry1);
+  this->addEntry(entry2);
+}
+
+
+/**
+ *  gets back the index of the entry in the array. value check
+ * @param entry: the entry to look up
+ * @returns the index in the array, -1 if not found
+ */
+template<class T>
+int tArray<T>::getIndex(T* entry) const
+{
+  if( unlikely(this->finalized == false))
+    return -1;
+
+  for(int i = 0; i < this->entryCount; ++i)
+  {
+    if( unlikely(*entry == this->array[i]))
+      return i;
+  }
+}
+
+
+/**
+ *  Simple debug info about the Array
+*/
+template<class T>
+void tArray<T>::debug () const
+{
+  PRINT(0)("entryCount=%i, address=%p\n", this->entryCount, this->array);
+}
+
+#endif
Index: branches/network/src/lib/util/color.cc
===================================================================
--- branches/network/src/lib/util/color.cc	(revision 6636)
+++ branches/network/src/lib/util/color.cc	(revision 6636)
@@ -0,0 +1,174 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "color.h"
+#include "vector.h"
+
+using namespace std;
+
+
+
+
+#include <stdio.h>
+
+/**
+ * transforms from RGB to HSVtoRGB
+ * @param RGB the RGB-color [0-1]
+ * @returns HSV: with values (h[0-360(degree)],s[0,1],v[0,1])
+ */
+Vector Color::RGBtoHSV(const Vector& RGB)
+{
+  float r = RGB.x;
+  float g = RGB.y;
+  float b = RGB.z;
+
+  float h=0,s=1.0,v=1.0;
+  float max_v,min_v,diff,r_dist,g_dist,b_dist;
+  float undefined = 0.0;
+
+  max_v = maxrgb(r,g,b);
+  min_v = minrgb(r,g,b);
+  diff = max_v - min_v;
+  v = max_v;
+
+  if( max_v != 0 )
+    s = diff/max_v;
+  else
+    s = 0.0;
+  if( s == 0 )
+    h = undefined;
+  else {
+    r_dist = (max_v - r)/diff;
+    g_dist = (max_v - g)/diff;
+    b_dist = (max_v - b)/diff;
+    if( r == max_v )
+      h = b_dist - g_dist;
+    else
+      if( g == max_v )
+        h = 2 + r_dist - b_dist;
+    else
+      if( b == max_v )
+        h = 4 + g_dist - r_dist;
+    else
+      printf("rgb2hsv::How did I get here?\n");
+    h *= 60.;
+    if( h < 0)
+      h += 360.0;
+  }
+  return Vector(h, s, v);
+}
+
+/**
+ * converts a Color from HSV to RGBtoHSV
+ * @param HSV: Vector with values (h[0-360(degree)],s[0,1],v[0,1])
+ * @returns RGB: Vector [0-1]
+ */
+Vector Color::HSVtoRGB(const Vector& HSV)
+{
+  float h = HSV.x;
+  float s = HSV.y;
+  float v = HSV.z;
+  float r=0, g=0, b=0;
+  float f,p,q,t;
+  int i;
+
+  if( s == 0 ) {
+    r = v;
+    g = v;
+    b = v;
+  }
+  else {
+   if(h == 360.)
+     h = 0.0;
+    h /= 60.;
+    i = (int) h;
+    f = h - i;
+    p = v*(1-s);
+    q = v*(1-(s*f));
+    t = v*(1-s*(1-f));
+    switch(i) {
+      case 0:
+        r = v;
+        g = t;
+        b = p;
+        break;
+      case 1:
+        r = q;
+        g = v;
+        b = p;
+        break;
+      case 2:
+        r = p;
+        g = v;
+        b = t;
+        break;
+      case 3:
+        r = p;
+        g = q;
+        b = v;
+        break;
+      case 4:
+        r = t;
+        g = p;
+        b = v;
+        break;
+      case 5:
+        r = v;
+        g = p;
+        b = q;
+        break;
+      default:
+        r = 1.0;
+        g = 1.0;
+        b = 1.0;
+      //printf("hsv2rgb::How did I get here?\n");
+      // printf("h: %f, s: %f, v: %f; i:  %d\n",hin,s,v,i);
+        break;
+    }
+  }
+  return Vector(r,g,b);
+}
+
+
+// Needed by rgb2hsv()
+float Color::maxrgb(float r, float g, float b)
+{
+  float max;
+  if( r > g)
+    max = r;
+  else
+    max = g;
+  if( b > max )
+    max = b;
+  return( max );
+}
+
+
+// Needed by rgb2hsv()
+float Color::minrgb(float r,float g,float b)
+{
+  float min;
+
+  if( r < g)
+    min = r;
+  else
+    min = g;
+  if( b < min )
+    min = b;
+  return( min );
+}
+
Index: branches/network/src/lib/util/color.h
===================================================================
--- branches/network/src/lib/util/color.h	(revision 6636)
+++ branches/network/src/lib/util/color.h	(revision 6636)
@@ -0,0 +1,26 @@
+/*!
+ * @file color.h
+ * @brief Definition of color-calculations
+ *
+ * code borrowed from:
+ * http://www.easyrgb.com/math.php
+*/
+
+#ifndef _COLOR_H
+#define _COLOR_H
+
+//#include "vector.h"
+class Vector;
+
+//! a very abstract Class that helps transforming Colors into different Systems
+class Color
+{
+  public:
+  static Vector RGBtoHSV (const Vector& RGB);
+  static Vector HSVtoRGB (const Vector& HSV);
+
+  static float minrgb(float r, float g, float b);
+  static float maxrgb(float r, float g, float b);
+};
+
+#endif /* _COLOR_H */
Index: branches/network/src/lib/util/executor/executor.cc
===================================================================
--- branches/network/src/lib/util/executor/executor.cc	(revision 6636)
+++ branches/network/src/lib/util/executor/executor.cc	(revision 6636)
@@ -0,0 +1,177 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "executor.h"
+
+#include "debug.h"
+#include "class_list.h"
+
+#include "key_names.h"
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+
+using namespace std;
+
+////////////////////////
+// SHELL COMMAND BASE //
+////////////////////////
+// empty constructor
+Executor::Executor()
+{
+  this->defaultValue = NULL;
+}
+
+/**
+ * constructs and registers a new Command
+ * @param commandName the name of the Command
+ * @param className the name of the class to apply this command to
+ * @param paramCount the count of parameters this command takes
+ */
+Executor::Executor(unsigned int paramCount, ...)
+{
+  this->setClassID(CL_EXECUTOR, "Executor");
+
+  if (paramCount > FUNCTOR_MAX_ARGUMENTS)
+    paramCount = FUNCTOR_MAX_ARGUMENTS;
+  // reading in Parameters.
+  this->paramCount = paramCount;
+  this->defaultValue = new MultiType[paramCount];
+
+  va_list parameterList;
+  va_start(parameterList, paramCount);
+
+  // What Parameters we have got
+  for (unsigned int i = 0; i < paramCount; i++)
+  {
+    int type = va_arg(parameterList, int);
+    this->defaultValue[i].setType(type);
+  }
+}
+
+/**
+ * deconstructs a Executor
+ */
+Executor::~Executor()
+{
+  delete[] this->defaultValue;
+}
+
+/**
+ * clones this element into executor.
+ */
+void Executor::cloning(Executor* executor) const
+{
+  executor->functorType  = this->functorType;
+  executor->paramCount   = this->paramCount;
+  executor->defaultValue = new MultiType[this->paramCount];
+  for (unsigned int i = 0; i < this->paramCount; i++)
+  {
+    executor->defaultValue[i] =  this->defaultValue[i];
+//    printf("1: %s 2: %s\n", MultiType::MultiTypeToString(this->defaultValue[i].getType()),  MultiType::MultiTypeToString(executor->defaultValue[i].getType()));
+  }
+}
+
+
+
+/**
+ * sets default Values of the Commands
+ * @param count how many default Values to set.
+ * @param ... the default Values in order. They will be cast to the right type
+ * @returns itself
+ *
+ * Be aware, that when you use this Function, you !!MUST!! match the input as
+ * count, [EXACTLY THE SAME AS IF YOU WOULD CALL THE FUNCTION UP TO count ARGUMENTS]
+ */
+Executor* Executor::defaultValues(unsigned int count, ...)
+{
+  va_list values;
+  va_start(values, count);
+
+  this->defaultValues(count, values);
+}
+
+Executor* Executor::defaultValues(unsigned int count, va_list values)
+{
+  if (this == NULL)
+    return NULL;
+  if (count == 0)
+    return this;
+  if (count > this->paramCount)
+    count = this->paramCount;
+
+
+  for (unsigned int i = 0; i < count; i++)
+  {
+    switch (this->defaultValue[i].getType())
+    {
+      case MT_BOOL:
+        this->defaultValue[i].setInt(va_arg(values, int));
+        break;
+      case MT_CHAR:
+        this->defaultValue[i].setChar((char)va_arg(values, int));
+        break;
+      case MT_STRING:
+        this->defaultValue[i].setString(va_arg(values, char*));
+        break;
+      case MT_INT:
+        this->defaultValue[i].setInt(va_arg(values, int));
+        break;
+/*      case MT_UINT:
+        this->defaultValue[i].setInt((int)va_arg(values, unsigned int));
+        break;*/
+      case MT_FLOAT:
+        this->defaultValue[i].setFloat(va_arg(values, double));
+        break;
+/*      case MT_LONG:
+        this->defaultValue[i].setInt((int) va_arg(values, long));
+        break;*/
+      default:
+        break;
+    }
+  }
+  return this;
+}
+
+/**
+ * prints out nice information about the Executor
+ */
+void Executor::debug()
+{
+/*  tIterator<ExecutorClass>* iteratorCL = ExecutorClass::commandClassList->getIterator();
+  ExecutorClass* elemCL = iteratorCL->firstElement();
+  while(elemCL != NULL)
+  {
+    PRINT(0)("Class:'%s' registered %d commands: \n", elemCL->className, elemCL->commandList->getSize());
+    tIterator<Executor>* iterator = elemCL->commandList->getIterator();
+    const Executor* elem = iterator->firstElement();
+    while(elem != NULL)
+    {
+      PRINT(0)("  command:'%s' : params:%d: ", elem->getName(), elem->paramCount);
+      for (unsigned int i = 0; i< elem->paramCount; i++)
+       printf("%s ", Executor::paramToString(elem->parameters[i]));
+      if (elem->description != NULL)
+       printf("- %s", elem->description);
+      printf("\n");
+
+      elem = iterator->nextElement();
+    }
+    delete iterator;
+    elemCL = iteratorCL->nextElement();
+  }
+  delete iteratorCL;*/
+}
Index: branches/network/src/lib/util/executor/executor.h
===================================================================
--- branches/network/src/lib/util/executor/executor.h	(revision 6636)
+++ branches/network/src/lib/util/executor/executor.h	(revision 6636)
@@ -0,0 +1,335 @@
+/*!
+ * @file executor.h
+ * Definition of a on-screen-shell
+ */
+
+#ifndef _EXECUTOR_H
+#define _EXECUTOR_H
+
+#include "base_object.h"
+
+#include "helper_functions.h"
+#include "multi_type.h"
+#include "substring.h"
+#include "functor_list.h" //< MUST BE INCLUDED HERE AT LEAST ONCE.
+
+#include <stdarg.h>
+
+// FORWARD DECLARATION
+template<class T> class tList;
+
+//! an enumerator for the definition of the Type.
+typedef enum {
+  Executor_Objective         = 0x00000001,
+  Executor_Static            = 0x00000002,
+
+  Executor_NoLoadString      = 0x00000010,
+} Executor_Type;
+
+////////////////
+// BASE CLASS //
+////////////////
+//! a baseClass for all possible Executors
+class Executor: public BaseObject
+{
+  public:
+    virtual ~Executor();
+
+    virtual Executor* clone () const = 0;
+
+    Executor* defaultValues(unsigned int count, va_list values);
+    Executor* defaultValues(unsigned int count, ...);
+
+    /** executes a Command @param object the object to apply this to @param parameters the parameters the command takes */
+    virtual void execute (BaseObject* object, const void* parameters = NULL) = 0;
+
+    /** @returns the Type of this Function (either static or objective) */
+    inline long getType() const { return this->functorType; };
+    /** @returns the Count of Parameters this Executor takes */
+    inline unsigned int getParamCount() const { return this->paramCount; };
+
+    static void debug();
+
+  protected:
+    Executor();
+    Executor(unsigned int paramCount, ...);
+
+    void cloning(Executor* executor) const;
+
+//    const SubString& getSubString(const char* string) const { return SubString(string); };
+
+  protected:
+    long                        functorType;      //!< The type of Function we've got (either static or objective).
+    unsigned int                paramCount;       //!< the count of parameters.
+    MultiType*                  defaultValue;     //!< Default Values.
+};
+
+///////////////////////////////////////////////////
+///////////////////////////////////////////////////
+
+/////////////////////////////////
+// MACRO DEFINITION EXTENSIONS //
+/////////////////////////////////
+//! where to chek for default BOOL values
+#define   l_BOOL_DEFGRAB(i)         this->defaultValue[i].getBool()
+//! where to chek for default INT values
+#define   l_INT_DEFGRAB(i)          this->defaultValue[i].getInt()
+//! where to chek for default UINT values
+#define   l_UINT_DEFGRAB(i)         (unsigned int)this->defaultValue[i].getInt()
+//! where to chek for default LONG values
+#define   l_LONG_DEFGRAB(i)         (long)this->defaultValue[i].getInt()
+//! where to chek for default FLOAT values
+#define   l_FLOAT_DEFGRAB(i)        this->defaultValue[i].getFloat()
+//! where to chek for default STRING values
+#define   l_STRING_DEFGRAB(i)       this->defaultValue[i].getString()
+
+//////////////////////////
+// COMMAND REGISTRATION //
+//////////////////////////
+// EXECUTOR             can be redefined as Executor or ExecutorStatic
+// EXECUTOREXECUTER     can be redefined too.
+// EXECUTORINCLASS
+// EXECUTORTYPE
+
+
+///////////////////////
+// FUNCTION POINTERS //
+///////////////////////
+#define ExecutorFunctionPoiter0() \
+  void EXECUTORINCLASS(*functionPointer_0)();
+
+#define ExecutorFunctionPoiter1(t1) \
+  void EXECUTORINCLASS(*functionPointer_1_##t1)(t1##_TYPE);
+
+#define ExecutorFunctionPoiter2(t1, t2) \
+  void EXECUTORINCLASS(*functionPointer_2_##t1##_##t2)(t1##_TYPE, t2##_TYPE);
+
+
+#define ExecutorFunctionPoiter3(t1, t2, t3) \
+  void EXECUTORINCLASS(*functionPointer_3_##t1##_##t2##_##t3)(t1##_TYPE, t2##_TYPE, t3##_TYPE);
+
+#define ExecutorFunctionPoiter4(t1, t2, t3, t4) \
+  void EXECUTORINCLASS(*functionPointer_4_##t1##_##t2##_##t3##_##t4)(t1##_TYPE, t2##_TYPE, t3##_TYPE, t4##_TYPE);
+
+
+#define ExecutorFunctionPoiter5(t1, t2, t3, t4, t5) \
+  void EXECUTORINCLASS(*functionPointer_5_##t1##_##t2##_##t3##_##t4##_##t5)(t1##_TYPE, t2##_TYPE, t3##_TYPE, t4##_TYPE, t5##_TYPE); \
+
+
+//////////////////
+// CONSTRUCTORS //
+/////////////////
+//! creates a command that takes no parameters
+#define ExecutorConstructor0() \
+  EXECUTOR(void EXECUTORINCLASS(*function)()) \
+  : Executor(0) \
+  { \
+    this->functorType = EXECUTORTYPE; \
+    this->fp.functionPointer_0 = function; \
+  }
+
+//! creates a command that takes one parameter
+#define ExecutorConstructor1(t1) \
+  EXECUTOR(void EXECUTORINCLASS(*function)(t1##_TYPE)) \
+  : Executor(1, t1##_PARAM) \
+  { \
+    this->functorType = EXECUTORTYPE; \
+    this->fp.functionPointer_1_##t1 = function; \
+  }
+
+//! creates a command that takes two parameters
+#define ExecutorConstructor2(t1,t2) \
+  EXECUTOR(void EXECUTORINCLASS(*function)(t1##_TYPE, t2##_TYPE)) \
+  : Executor(2, t1##_PARAM, t2##_PARAM) \
+  { \
+    this->functorType = EXECUTORTYPE; \
+    this->fp.functionPointer_2_##t1##_##t2 = function; \
+  }
+
+//! creates a command that takes three parameter
+#define ExecutorConstructor3(t1,t2,t3) \
+  EXECUTOR(void EXECUTORINCLASS(*function)(t1##_TYPE, t2##_TYPE, t3##_TYPE)) \
+  : Executor(3, t1##_PARAM, t2##_PARAM, t3##_PARAM) \
+  { \
+    this->functorType = EXECUTORTYPE; \
+    this->fp.functionPointer_3_##t1##_##t2##_##t3 = function; \
+  }
+
+//! creates a command that takes four parameter
+#define ExecutorConstructor4(t1,t2,t3,t4) \
+  EXECUTOR(void EXECUTORINCLASS(*function)(t1##_TYPE, t2##_TYPE, t3##_TYPE, t4##_TYPE)) \
+  : Executor(4, t1##_PARAM, t2##_PARAM, t3##_PARAM, t4##_PARAM) \
+  { \
+    this->functorType = EXECUTORTYPE; \
+    this->fp.functionPointer_4_##t1##_##t2##_##t3##_##t4 = function; \
+  }
+
+//! creates a command that takes five parameter
+#define ExecutorConstructor5(t1,t2,t3,t4,t5) \
+  EXECUTOR(void EXECUTORINCLASS(*function)(t1##_TYPE, t2##_TYPE, t3##_TYPE, t4##_TYPE, t5##_TYPE)) \
+  : Executor(5, t1##_PARAM, t2##_PARAM, t3##_PARAM, t4##_PARAM, t5##_PARAM) \
+  { \
+    this->functorType = EXECUTORTYPE; \
+    this->fp.functionPointer_5_##t1##_##t2##_##t3##_##t4##_##t5 = function; \
+  }
+
+///////////////
+// EXECUTION //
+///////////////
+//! execute-macro for functions with no parameters
+#define ExecutorExecute0() \
+  if (this->paramCount == 0) \
+    EXECUTOREXECUTER(_0)()
+
+//! execute-macro for functions with one parameter
+#define ExecutorExecute1(t1) \
+   else if (this->paramCount == 1 && this->defaultValue[0].getType() == t1##_PARAM) \
+    EXECUTOREXECUTER(_1_##t1)(t1##_FUNC((const char*)parameters, t1##_DEFGRAB(0)))
+
+//! execute-macro for functions with two parameters
+#define ExecutorExecute2(t1,t2) \
+   else if (this->paramCount == 2 && this->defaultValue[0].getType() == t1##_PARAM && this->defaultValue[1].getType() == t2##_PARAM) \
+    EXECUTOREXECUTER(_2_##t1##_##t2)(t1##_FUNC(sub.getString(0), t1##_DEFGRAB(0)), t2##_FUNC(sub.getString(1), t2##_DEFGRAB(1)))
+
+//! execute-macro for functions with three parameters
+#define ExecutorExecute3(t1,t2,t3) \
+   else if (this->paramCount == 3 && this->defaultValue[0].getType() == t1##_PARAM && this->defaultValue[1].getType() == t2##_PARAM && this->defaultValue[2].getType() == t3##_PARAM) \
+    EXECUTOREXECUTER(_3_##t1##_##t2##_##t3)(t1##_FUNC(sub.getString(0), t1##_DEFGRAB(0)), t2##_FUNC(sub.getString(1), t2##_DEFGRAB(1)), t3##_FUNC(sub.getString(2), t3##_DEFGRAB(2)))
+
+//! execute-macro for functions with four parameters
+#define ExecutorExecute4(t1,t2,t3,t4) \
+   else if (this->paramCount == 4 && this->defaultValue[0].getType() == t1##_PARAM && this->defaultValue[1].getType() == t2##_PARAM && this->defaultValue[2].getType() == t3##_PARAM && this->defaultValue[3].getType() == t4##_PARAM) \
+    EXECUTOREXECUTER(_4_##t1##_##t2##_##t3##_##t4)(t1##_FUNC(sub.getString(0), t1##_DEFGRAB(0)), t2##_FUNC(sub.getString(1), t2##_DEFGRAB(1)), t3##_FUNC(sub.getString(2), t3##_DEFGRAB(2)), t4##_FUNC(sub.getString(3), t4##_DEFGRAB(3))) \
+
+
+//! execute-macro for functions with five parameters
+#define ExecutorExecute5(t1,t2,t3,t4,t5) \
+   else if (this->paramCount == 5 && this->defaultValue[0].getType() == t1##_PARAM && this->defaultValue[1].getType() == t2##_PARAM && this->defaultValue[2].getType() == t3##_PARAM && this->defaultValue[3].getType() == t4##_PARAM && this->defaultValue[4].getType() == t5##_PARAM) \
+    EXECUTOREXECUTER(_5_##t1##_##t2##_##t3##_##t4##_##t5)(t1##_FUNC(sub.getString(0), t1##_DEFGRAB(0)), t2##_FUNC(sub.getString(1), t2##_DEFGRAB(1)), t3##_FUNC(sub.getString(2), t3##_DEFGRAB(2)), t4##_FUNC(sub.getString(3), t4##_DEFGRAB(3)), t5##_FUNC(sub.getString(4), t5##_DEFGRAB(4)))
+
+
+
+
+
+//////////\//////////
+// DYNAMIC FUNCTOR //
+///////////\/////////
+#ifdef FUNCTOR_LIST
+#undef FUNCTOR_LIST
+#endif
+#ifdef EXECUTOR
+#undef EXECUTOR
+#endif
+#define EXECUTOR                       ExecutorObjective
+#ifdef EXECUTOREXECUTER
+#undef EXECUTOREXECUTER
+#endif
+#define EXECUTOREXECUTER(nameExt)      (dynamic_cast<T*>(object)->*(fp.functionPointer##nameExt))
+#ifdef EXECUTORINCLASS
+#undef EXECUTORINCLASS
+#endif
+#define EXECUTORINCLASS(FUNCTION)      (T::FUNCTION)
+#ifdef EXECUTORTYPE
+#undef EXECUTORTYPE
+#endif
+#define EXECUTORTYPE                   Executor_Objective
+//! keeps information about a Executor
+template<class T> class ExecutorObjective : public Executor
+{
+  public:
+    ExecutorObjective() : Executor() { };
+    // COPY constuctor (virtual version)
+    virtual Executor* clone () const
+    {
+      ExecutorObjective<T>* executor = new ExecutorObjective<T>();
+      this->cloning(executor);
+      executor->fp = this->fp;
+      return executor;
+    }
+
+//! FUNCTOR_LIST is the List of CommandConstructors
+#define FUNCTOR_LIST(x) ExecutorConstructor ## x
+#include "functor_list.h"
+#undef FUNCTOR_LIST
+
+  private:
+//! FUNCTOR_LIST is the List of FunctionPointers
+    union FunctionPointers {
+#define FUNCTOR_LIST(x) ExecutorFunctionPoiter ## x
+#include "functor_list.h"
+#undef FUNCTOR_LIST
+    } fp;
+
+    virtual void execute (BaseObject* object, const void* parameters = NULL)
+    {
+      SubString sub((const char*) parameters, " \n\t,", '\\');
+//! FUNCTOR_LIST is the List of Executive Functions
+#define FUNCTOR_LIST(x) ExecutorExecute ## x
+#include "functor_list.h"
+#undef FUNCTOR_LIST
+    }
+};
+
+
+////////////////////
+// STATIC FUNCTOR //
+////////////////////
+#ifdef FUNCTOR_LIST
+#undef FUNCTOR_LIST
+#endif
+#ifdef EXECUTOR
+#undef EXECUTOR
+#endif
+#define EXECUTOR                      ExecutorStatic
+#ifdef EXECUTOREXECUTER
+#undef EXECUTOREXECUTER
+#endif
+#define EXECUTOREXECUTER(nameExt)     fp.functionPointer##nameExt
+#ifdef EXECUTORINCLASS
+#undef EXECUTORINCLASS
+#endif
+#define EXECUTORINCLASS(FUNCTION)     (FUNCTION)
+#ifdef EXECUTORTYPE
+#undef EXECUTORTYPE
+#endif
+#define EXECUTORTYPE                   Executor_Static
+
+//! keeps information about a Executor, that points to a Static Function
+template<class T> class ExecutorStatic : public Executor
+{
+  public:
+    ExecutorStatic() : Executor() { };
+    // COPY constuctor
+    virtual Executor* clone () const
+    {
+      ExecutorStatic<T>* executor = new ExecutorStatic<T>();
+      this->cloning(executor);
+      executor->fp = this->fp;
+      return executor;
+    }
+
+//! FUNCTOR_LIST is the List of CommandConstructors
+#define FUNCTOR_LIST(x) ExecutorConstructor ## x
+#include "functor_list.h"
+#undef FUNCTOR_LIST
+
+  private:
+//! FUNCTOR_LIST is the List of FunctionPointers
+    union FunctionPointers {
+#define FUNCTOR_LIST(x) ExecutorFunctionPoiter ## x
+#include "functor_list.h"
+#undef FUNCTOR_LIST
+    } fp;
+
+
+    virtual void execute (BaseObject* object, const void* parameters = NULL)
+    {
+  SubString sub((const char*)parameters, " \n\t,");
+//! FUNCTOR_LIST is the List of Executive Functions
+#define FUNCTOR_LIST(x) ExecutorExecute ## x
+#include "functor_list.h"
+#undef FUNCTOR_LIST
+    }
+};
+
+#endif /* _EXECUTOR_H */
Index: branches/network/src/lib/util/executor/executor_specials.h
===================================================================
--- branches/network/src/lib/util/executor/executor_specials.h	(revision 6636)
+++ branches/network/src/lib/util/executor/executor_specials.h	(revision 6636)
@@ -0,0 +1,80 @@
+/*!
+ * @file executor.h
+ * Definition of a on-screen-shell
+ */
+
+#ifndef _EXECUTOR_SPECIALS_H
+#define _EXECUTOR_SPECIALS_H
+
+#include "executor.h"
+
+#include "compiler.h"
+#include "parser/tinyxml/tinyxml.h"
+// FORWARD DECLARATION
+
+//! Executes a Function with a const TiXmlElement* parameter.
+/**
+ * This is a Special Executor, that finds ParamName in root as XML-sub-element
+ * This is especially usefull, if you have to Load a SubElement from root in a new Function
+ * What must be defined is a XML-root to search the ParameterName under an  a Function to call.
+ */
+template<class T> class ExecutorXML : public Executor
+{
+  public:
+    /**
+     * Constructor of a ExecutorXML
+     * @param function a Function to call
+     * @param root The XML root to search paramName under
+     * @param paramName the ParameterName the search in root, and lookup the TiXmlElement from
+     */
+    ExecutorXML(void(T::*function)(const TiXmlElement*), const TiXmlElement* root, const char* paramName)
+      : Executor(1, MT_EXT1)
+    {
+      PRINTF(4)("Loading %s from XML-element %p\n", paramName, root);
+
+      if (likely(root != NULL && paramName != NULL))
+        this->element = root->FirstChildElement(paramName);
+      else
+        this->element = NULL;
+
+      this->functionPointer = function;
+      this->functorType = Executor_Objective | Executor_NoLoadString;
+    }
+
+    /**
+     * clones an ExecutorXML, used to copy this Element.
+     * @returns a _new_ Copy of this Executor
+     */
+    virtual Executor* clone () const
+    {
+      ExecutorXML<T>* executor = new ExecutorXML<T>();
+      this->cloning(executor);
+      executor->functionPointer = this->functionPointer;
+      executor->element = this->element;
+      return executor;
+    }
+
+    /**
+     * executes the Command on BaseObject
+     * @param object the BaseObject to execute this Executor on
+     * @param loadString ignored in this case
+     */
+    virtual void execute(BaseObject* object, const void* parameters = NULL)
+    {
+      if (object != NULL && this->element != NULL)
+        (dynamic_cast<T*>(object)->*(functionPointer))(this->element);
+    }
+
+  private:
+    /**
+     * used for the copy-(Clone)-constructor
+     */
+    ExecutorXML() : Executor() { };
+
+
+  private:
+    void    (T::*functionPointer)(const TiXmlElement*);  //!< The functionPointer to the function to be called
+    const   TiXmlElement* element;                       //!< The XML-element to call.
+};
+
+#endif /* _EXECUTOR_SPECIALS_H */
Index: branches/network/src/lib/util/executor/functor_list.h
===================================================================
--- branches/network/src/lib/util/executor/functor_list.h	(revision 6636)
+++ branches/network/src/lib/util/executor/functor_list.h	(revision 6636)
@@ -0,0 +1,144 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+   */
+
+/*!
+ * @file functors_list.h
+ * all the Different types of Functions one can include
+*/
+
+/**
+   useable FunctionParameters are:
+   l_INT:       int
+   l_LONG:      long
+   l_SHORT:     short
+   l_FLOAT:     float
+   l_STRING:    const char*
+   l_XML_ELEM:  TiXmlElement*
+ */
+
+#ifndef __FUNCTOR_PARAMETERS__
+#define __FUNCTOR_PARAMETERS__
+
+//! defines the maximum count of arguments function pointers might have
+#define FUNCTOR_MAX_ARGUMENTS                5
+#include "multi_type.h"
+
+#define l_BOOL_TYPE        bool                 //!< The type of an BOOL
+#define l_BOOL_FUNC        isBool               //!< The function to call to parse BOOL
+#define l_BOOL_NAME        "bool"               //!< The name of an BOOL
+#define l_BOOL_PARAM       MT_BOOL              //!< the type of the parameter BOOL
+#define l_BOOL_DEFAULT     false                //!< a default Value for an BOOL
+
+
+#define l_INT_TYPE         int                  //!< The type of an INT
+#define l_INT_FUNC         isInt                //!< The function to call to parse INT
+#define l_INT_NAME         "int"                //!< The name of an INT
+#define l_INT_PARAM        MT_INT               //!< the type of the parameter INT
+#define l_INT_DEFAULT      0                    //!< a default Value for an INT
+
+#define l_UINT_TYPE        unsigned int         //!< The type of an UINT
+#define l_UINT_FUNC        isInt                //!< The function to call to parse UINT
+#define l_UINT_NAME        "unsigned int"       //!< The name of an UINT
+#define l_UINT_PARAM       MT_INT        //!< the type of the parameter UINT
+#define l_UINT_DEFAULT     0                    //!< a default Value for an UINT
+
+#define l_LONG_TYPE        long                 //!< The type of a LONG
+#define l_LONG_FUNC        isInt                //!< The function to parse a LONG
+#define l_LONG_NAME        "long"               //!< The name of a LONG
+#define l_LONG_PARAM       MT_INT //!< the type of the parameter LONG
+#define l_LONG_DEFAULT     0                    //!< a default Value for a LONG
+
+// #define l_SHORT_TYPE       short                //!< The type of a SHORT
+// #define l_SHORT_FUNC       atoi                 //!< The function to parse a SHORT
+// #define l_SHORT_NAME       "short"              //!< The name of a SHORT
+//#define l_SHORT_PARAM       ParameterShort       //!< the type of the parameter SHORT
+// #define l_SHORT_DEFAULT    0                    //!< a default Value for a SHORT
+
+#define l_FLOAT_TYPE       float                //!< The type of a FLOAT
+#define l_FLOAT_FUNC       isFloat              //!< The function to parse a FLOAT
+#define l_FLOAT_NAME       "float"              //!< The name of a FLOAT
+#define l_FLOAT_PARAM      MT_FLOAT             //!< the type of the parameter FLOAT
+#define l_FLOAT_DEFAULT    0.0                  //!< a default Value for a FLOAT
+
+//#define l_VECTOR_TYPE      const Vector&        //!< The type of a VECTOR
+//#define l_VECTOR_FUNC      isVector             //!< The function to parse a VECTOR
+//#define l_VECTOR_NAME      "Vector[x/y/z]"      //!< The name of a VECTOR
+//#define l_VECTOR_DEFAULT   Vector(0,0,0)        //!< Default value for a VECTOR
+
+#define l_STRING_TYPE      const char*          //!< The type of a STRING
+#define l_STRING_FUNC      isString             //!< The function to parse a STRING
+#define l_STRING_NAME      "string"             //!< The name of a STRING
+#define l_STRING_PARAM     MT_STRING            //!< the type of the parameter STRING
+#define l_STRING_DEFAULT   ""                   //!< a default Value for an STRING
+
+#define l_XML_ELEM_TYPE    const TiXmlElement*  //!< The type of an XML_ELEM
+#define l_XML_ELEM_FUNC                         //!< The function to parse an XML_ELEM
+#define l_XML_ELEM_NAME    "XML"                //!< The name of an XML_ELEM
+//#define l_XML_ELEM_PARAM   Parameter            //!< the type of the parameter XML_ELEM
+#define l_XML_ELEM_DEFAULT NULL                 //!< The dafault Value for an XML_ELEM
+
+#endif /* __FUNCTOR_PARAMETERS__ */
+
+
+#ifdef FUNCTOR_LIST
+
+  FUNCTOR_LIST(0)();
+  //! makes functions with one string
+  FUNCTOR_LIST(1)(l_STRING);
+  //! makes functions with two strings
+  FUNCTOR_LIST(2)(l_STRING, l_STRING);
+  //! makes functions with three strings
+  FUNCTOR_LIST(3)(l_STRING, l_STRING, l_STRING);
+  //! makes functions with four strings
+  FUNCTOR_LIST(4)(l_STRING, l_STRING, l_STRING, l_STRING);
+
+  //! makes functions with one bool
+  FUNCTOR_LIST(1)(l_BOOL);
+
+  //! makes functions with one int
+  FUNCTOR_LIST(1)(l_INT);
+  //! makes functions with two ints
+  FUNCTOR_LIST(2)(l_INT, l_INT);
+  //! makes functions with three ints
+  FUNCTOR_LIST(3)(l_INT, l_INT, l_INT);
+  //! makes functions with four ints
+  FUNCTOR_LIST(4)(l_INT, l_INT, l_INT, l_INT);
+
+
+  //! makes functions with one unsigned int
+  FUNCTOR_LIST(1)(l_UINT);
+  //! makes functions with two unsigned ints
+  FUNCTOR_LIST(2)(l_UINT, l_UINT);
+  //! makes functions with three unsigned ints
+  FUNCTOR_LIST(3)(l_UINT, l_UINT, l_UINT);
+  //! makes functions with four unsigned ints
+  FUNCTOR_LIST(4)(l_UINT, l_UINT, l_UINT, l_UINT);
+
+  //! makes functions with one float
+  FUNCTOR_LIST(1)(l_FLOAT);
+  //! makes functions with two floats
+  FUNCTOR_LIST(2)(l_FLOAT, l_FLOAT);
+  //! makes functions with three floats
+  FUNCTOR_LIST(3)(l_FLOAT, l_FLOAT, l_FLOAT);
+  //! makes functions with four floats
+  FUNCTOR_LIST(4)(l_FLOAT, l_FLOAT, l_FLOAT, l_FLOAT);
+  //! makes functions with four floats
+  FUNCTOR_LIST(5)(l_FLOAT, l_FLOAT, l_FLOAT, l_FLOAT, l_FLOAT);
+
+  //! mixed values:
+  FUNCTOR_LIST(2)(l_STRING, l_FLOAT);
+  FUNCTOR_LIST(2)(l_UINT, l_LONG);
+  FUNCTOR_LIST(2)(l_STRING, l_UINT);
+
+  FUNCTOR_LIST(3)(l_STRING, l_FLOAT, l_UINT);
+
+
+#endif /* FUNCTOR_LIST */
Index: branches/network/src/lib/util/helper_functions.cc
===================================================================
--- branches/network/src/lib/util/helper_functions.cc	(revision 6636)
+++ branches/network/src/lib/util/helper_functions.cc	(revision 6636)
@@ -0,0 +1,96 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "helper_functions.h"
+#include "stdlibincl.h"
+
+using namespace std;
+
+/**
+ * checks if the input was a bool
+ * @param BOOL a String that holds a bool: must be one of those: 1,0,true,false(case-insensitive)
+ * @param defaultValue a default value that is set, if BOOL is corrupt
+ * @return returns the bool, if BOOL was correct otherwise defaultValue
+ */
+bool isBool(const char* BOOL, bool defaultValue)
+{
+  if (BOOL == NULL)
+    return defaultValue;
+  if(!strcmp(BOOL, "1") || !strcasecmp( BOOL, "true") )
+    return true;
+  else if (!strcmp(BOOL, "0") || !strcasecmp( BOOL, "false"))
+    return false;
+  else
+    return defaultValue;
+
+}
+
+
+/**
+ * checks if the input was a int
+ * @param INT a String that holds an int.
+ * @param defaultValue a default value that is set, if INT is corrupt
+ * @return returns the contained int, if INT was correct otherwise defaultValue
+ */
+int isInt(const char* INT, int defaultValue)
+{
+  if (INT == NULL)
+    return defaultValue;
+  char* endPtr = NULL;
+
+  int result = strtol(INT, &endPtr, 10);
+
+  if ( endPtr >= INT && endPtr < INT + strlen(INT))
+    return defaultValue;
+  else
+    return result;
+}
+
+
+/**
+ * checks if the input was a float
+ * @param FLOAT a String that holds an float.
+ * @param defaultValue a default value that is set, if FLOAT is corrupt
+ * @return returns the contained float, if FLOAT was correct otherwise defaultValue
+ */
+float isFloat(const char* FLOAT, float defaultValue)
+{
+  if (FLOAT == NULL)
+    return defaultValue;
+  char* endPtr = NULL;
+  double result = strtod(FLOAT, &endPtr);
+
+  if ( endPtr >= FLOAT && endPtr < FLOAT + strlen(FLOAT))
+    return defaultValue;
+  else
+    return result;
+}
+
+
+/**
+ * checks if the input was a string
+ * @param STING a String(char-array) that holds an string.
+ * @param defaultValue a default value that is set, if STRING is corrupt
+ * @return returns the contained string (char-array), if STRING was correct otherwise defaultValue
+ */
+const char* isString(const char* STRING, const char* defaultValue)
+{
+  if (STRING != NULL && strlen(STRING) > 0)
+    return STRING;
+  else
+    return defaultValue;
+}
Index: branches/network/src/lib/util/helper_functions.h
===================================================================
--- branches/network/src/lib/util/helper_functions.h	(revision 6636)
+++ branches/network/src/lib/util/helper_functions.h	(revision 6636)
@@ -0,0 +1,19 @@
+/*!
+ * @file helper_functions.h
+ * @brief Definition of some minor helper-functions
+*/
+
+#ifndef _HELPER_FUNCTIONS_H
+#define _HELPER_FUNCTIONS_H
+
+// FORWARD DECLARATION
+
+/***********************
+*** HELPER FUNCTIONS ***
+***********************/
+bool          isBool(const char* BOOL, bool defaultValue);
+int           isInt(const char* INT, int defaultValue);
+float         isFloat(const char* FLOAT, float defaultValue);
+const char*   isString(const char* STRING, const char* defaultValue);
+
+#endif /* _HELPER_FUNCTIONS_H */
Index: branches/network/src/lib/util/list.h
===================================================================
--- branches/network/src/lib/util/list.h	(revision 6636)
+++ branches/network/src/lib/util/list.h	(revision 6636)
@@ -0,0 +1,647 @@
+/*!
+ * @file list.h
+ * a File that includes a List-template
+ */
+
+#ifndef _T_LIST_H
+#define _T_LIST_H
+
+#include "compiler.h"
+#ifndef NULL
+#define NULL 0                                       //!< this will define NULL
+#endif
+
+template<class T> class tIterator;
+
+//! a list element of the tList,
+template<class T> struct listElement
+{
+  listElement*        prev;                          //!< pointer to the previous listElement in the list
+  T*                  curr;                          //!< pointer to the list payload/container
+  listElement*        next;                          //!< pointer to the next listElement
+};
+
+/**
+ *  the list template class
+
+   you will use this as a generic list for all type of objects
+ */
+template<class T> class tList
+{
+  friend class tIterator<T>;
+
+  public:
+    tList ();
+    ~tList ();
+
+    void add(T* entity);
+    void addAtBeginning(T* entity); //!< @todo This should be made with an ENUM
+    void addAtIteratorPosition(T* entity, tIterator<T>* itereator);
+    void remove(const T* entity);
+    void removeFromLast(const T* entity);
+    void removeLast();
+    void flush();
+    T* firstElement() const;
+    T* lastElement() const;
+    bool isEmpty() const;
+    unsigned int getSize() const;
+    bool inList(T* entity) const;
+    tIterator<T>* getIterator() const;
+    T* nextElement(T* toEntity);
+    T* toArray();
+
+  private:
+    unsigned int       size;             //!< the size (lenght) of the list
+    listElement<T>*    first;            //!< pointer to the first element
+    listElement<T>*    last;             //!< pointer to the last element
+    listElement<T>*    currentEl;        //!< pointer to the current element
+};
+
+
+/**
+ *  the constructor
+ */
+template<class T>
+    inline tList<T>::tList ()
+{
+  this->currentEl = NULL;
+  this->first = NULL;
+  this->last = NULL;
+  this->size = 0;
+}
+
+
+/**
+ *  the deconstructor
+
+   this will delete only the list. ATTENTION: the list is deleted, but the objects in the list will remain
+ */
+template<class T>
+    inline tList<T>::~tList ()
+{
+  this->currentEl = this->first;
+  listElement<T>* le;
+  while(this->currentEl != NULL)
+  {
+    le = this->currentEl->next;
+    delete this->currentEl;
+    this->currentEl = le;
+  }
+  this->first = NULL;
+  this->last = NULL;
+  this->currentEl = NULL;
+  this->size = 0;
+}
+
+
+/**
+ *  add an entity to the list
+ * @param entity: the entity to add
+ */
+template<class T>
+    inline void tList<T>::add(T* entity)
+{
+  if( unlikely(entity == NULL)) return;
+  listElement<T>* el = new listElement<T>;
+  el->prev = this->last;
+  el->curr = entity;
+  el->next = NULL;
+
+  this->last = el;
+
+  if( unlikely(el->prev == NULL)) this->first = el; /* if first element */
+  else el->prev->next = el;
+  this->size++;
+}
+
+/**
+ *  add an entity to the list
+ * @param entity: the entity to add
+ */
+template<class T>
+    inline void tList<T>::addAtBeginning(T* entity)
+{
+  if( unlikely(entity == NULL)) return;
+
+  listElement<T>* el = new listElement<T>;
+  el->next = this->first;
+  el->curr = entity;
+  el->prev = NULL;
+
+  this->first = el;
+
+  if( unlikely(el->next == NULL)) this->last = el; /* if first element */
+  else el->next->prev = el;
+  this->size++;
+}
+
+/**
+ * add an entity at an iterators position
+ * @param entity the entity to add
+ * @param iterator the iterator get the Positional from
+ *
+ * this works best with an iterator walking with
+ * firstElement() ; nextStep();
+ * or
+ * lastElement(); prevStep();
+ */
+template<class T>
+    inline void tList<T>::addAtIteratorPosition(T* entity, tIterator<T>* iterator)
+{
+  // rule out unusable
+  if (unlikely(entity == NULL))
+    return;
+  // on any error (or next == NULL) add using default add-function
+  if (unlikely(iterator == NULL || iterator->getList() == NULL) ||
+      iterator->tmpEl == NULL || iterator->tmpEl->next == NULL)
+    return this->add(entity);
+  // on prev == NULL add with addAtBeginning-function
+  if (unlikely(iterator->tmpEl->prev == NULL))
+    return addAtBeginning(entity);
+  else
+  {
+    listElement<T>* el = new listElement<T>;
+    el->next = iterator->tmpEl->next;
+    el->curr = entity;
+    el->prev = iterator->tmpEl->prev;
+
+    el->next->prev = el;
+    el->prev->next = el;
+  }
+}
+
+/**
+ * remove an entity from the list
+ * @param entity: the entity to be removed
+ */
+template<class T>
+    inline void tList<T>::remove(const T* entity)
+{
+  this->currentEl = this->first;
+  while( this->currentEl != NULL)
+  {
+    if( unlikely(this->currentEl->curr == entity))
+    {
+      // erstes element?
+      if( unlikely(this->currentEl->prev == NULL)) this->first = this->currentEl->next;
+      else this->currentEl->prev->next = this->currentEl->next;
+
+      // letztes element?
+      if( unlikely(this->currentEl->next == NULL)) this->last = this->currentEl->prev;
+      else this->currentEl->next->prev = this->currentEl->prev;
+
+      delete this->currentEl;
+      this->size--;
+      return;
+    }
+    this->currentEl = this->currentEl->next;
+  }
+}
+
+/**
+ * remove an entity from the list
+ * @param entity: the entity to be removed
+ *
+ * this algorithm starts at the end of the List, working its way to the front
+ * for finding the right entity.
+ */
+template<class T>
+    inline void tList<T>::removeFromLast(const T* entity)
+{
+  this->currentEl = this->last;
+  while( this->currentEl != NULL)
+  {
+    if( unlikely(this->currentEl->curr == entity))
+    {
+      // erstes element?
+      if( unlikely(this->currentEl->prev == NULL)) this->first = this->currentEl->next;
+      else this->currentEl->prev->next = this->currentEl->next;
+
+      // letztes element?
+      if( unlikely(this->currentEl->next == NULL)) this->last = this->currentEl->prev;
+      else this->currentEl->next->prev = this->currentEl->prev;
+
+      delete this->currentEl;
+      this->size--;
+      return;
+    }
+    this->currentEl = this->currentEl->prev;
+  }
+}
+
+
+/**
+ * removes the Last Element of the List
+ */
+ template<class T>
+     inline void tList<T>::removeLast()
+{
+  if( unlikely(this->last == NULL))
+    return;
+
+  // only one element in the list (and its not NULL :D )
+  if( unlikely(this->last == this->first))
+  {
+    delete this->first;
+    this->first = NULL;
+    this->last = NULL;
+    this->size--;
+  }
+  else
+  {
+    listElement<T>* delLast = this->last;
+    this->last->prev->next = NULL;
+    this->last = this->last->prev;
+    delete delLast;
+  }
+}
+
+
+/**
+ *  this will delete all objects from the list, this can be very dangerous if there are ghost objects in the list.
+ */
+template<class T>
+    inline void tList<T>::flush()
+{
+  this->currentEl = this->first;
+
+  listElement<T>* le;
+  while( this->currentEl != NULL)
+  {
+    le = this->currentEl->next;
+    delete this->currentEl->curr;
+    delete this->currentEl;
+    this->currentEl = le;
+  }
+  this->first = NULL;
+  this->last = NULL;
+  this->currentEl = NULL;
+  this->size = 0;
+}
+
+
+/**
+ *  returns the first element of the list
+ * @returns first element
+ */
+template<class T>
+    inline T* tList<T>::firstElement() const
+{
+  return this->first->curr;
+}
+
+
+/**
+ *  function returns the last element of the list
+ * @returns the last element
+ */
+template<class T>
+    inline T* tList<T>::lastElement() const
+{
+  return this->last->curr;
+}
+
+
+/**
+ *  returns true if the list is empty
+ * @returns true if the list is empty
+ */
+template<class T>
+    inline bool tList<T>::isEmpty() const
+{
+  return (this->size == 0)?true:false;
+}
+
+
+/**
+ *  checks if an entity is in the List.
+ * @param entity The entity to check for in the entire List.
+ * @returns true if it is, false otherwise
+ */
+template<class T>
+    inline bool tList<T>::inList(T* entity) const
+{
+  // pre checks
+  if( unlikely(entity == NULL)) return false;
+
+  // search in the List
+  listElement<T>* el = this->first;
+  while( this->currentEl != NULL)
+  {
+    if( this->currentEl->curr == entity)
+      return true;
+
+    el = this->currentEl->next;
+  }
+}
+
+
+/**
+ *  this returns the number of elements in the list
+ * @returns number of elements
+ */
+template<class T>
+    inline unsigned int tList<T>::getSize() const
+{
+  return this->size;
+}
+
+
+/**
+ *  creates an itereator object and returns it
+ * @returns the iterator object to this list
+
+   You will use this, if you want to iterate through the list
+ */
+template<class T>
+    inline tIterator<T>* tList<T>::getIterator() const
+{
+  return new tIterator<T>(this);
+}
+
+
+
+/**
+ *  this returns the next element after toEntity or the first if toEntity is last
+ * @param toEntity: the entity after which is an entity, that has to be returned, sorry, terrible phrase
+ * @returns the element after toEntity
+ */
+template<class T>
+    inline T* tList<T>::nextElement(T* toEntity)
+{
+  //if( this->last == this->first == NULL) return NULL;
+  if(this->size == 0) return NULL;
+  if( toEntity == NULL) return this->first->curr;
+  if( toEntity == this->last->curr ) return this->first->curr;
+  this->currentEl = this->first;
+  while(this->currentEl->curr != toEntity && this->currentEl->next != NULL)
+  {
+    this->currentEl = this->currentEl->next;
+  }
+  if(this->currentEl == NULL) return NULL;
+  return this->currentEl->next->curr;
+}
+
+
+/**
+ *  creates an array out of the list (ATTENTION: not implemented)
+ * @returns pointer to the array beginning
+
+   ATTENTION: function is not implemented and wont do anything
+ */
+template<class T>
+    T* tList<T>::toArray()
+{
+  return NULL;
+}
+
+
+
+
+/**
+    *  an iterator class
+
+   this enables the user to iterate through a list very easely
+ */
+template<class T> class tIterator
+{
+  friend class tList<T>;
+  public:
+    tIterator(const tList<T>* list);
+    ~tIterator();
+
+    T* firstElement();
+    T* lastElement();
+    T* nextElement();
+    T* prevElement();
+    T* seekElement(const T* element);
+    T* iteratorElement(const tIterator<T>* iterator);
+    bool compareListPointer(const tList<T>* list) const;
+    inline const tList<T>* getList() const { return this->list; };
+    /** another way to iterate through the list
+     * !! THIS IS NOT MEANT FOR DELETION
+     */
+    T* prevStep();
+    T* nextStep();
+    T* getCurrent();
+
+  private:
+    listElement<T>*    currentEl;                      //!< pointer to the current list element in the iterator
+    listElement<T>*    tmpEl;                          //!< temp listElemnt pointer
+    const tList<T>*    list;                           //!< The List, that we want to iterate through
+};
+
+
+/**
+ *  iterator constructor
+ * @param startElement:  the first list element from the tList
+ *
+ * normaly you will use it like this:
+ **********************************************************
+ * tIterator<char>* nameIterator = nameList->getIterator();
+ * char name* = nameIterator->firstElement();
+ * while( name != NULL)
+ *  {
+ *   PRINTF(3)("found name: %s in list\n", name);
+ *   name = nameIterator->nextElement();
+ *  }
+ * delete nameIterator;
+ * ********************************************************
+ */
+template<class T>
+  inline tIterator<T>::tIterator (const tList<T>* list)
+{
+  this->currentEl = NULL;
+  this->tmpEl = NULL;
+  this->list = list;
+}
+
+
+/**
+ *  the destructor
+ */
+template<class T>
+    inline tIterator<T>::~tIterator ()
+{
+  this->currentEl = NULL;
+  this->tmpEl = NULL;
+  this->list = NULL;
+}
+
+/**
+ * this returns the first element of the iterator list
+ * @returns first element
+ */
+template<class T>
+    inline T* tIterator<T>::firstElement ()
+{
+  this->tmpEl = this->list->first;
+  if( likely(this->tmpEl != NULL))
+  {
+    this->currentEl = this->tmpEl->next;
+    return this->tmpEl->curr;
+  }
+  else
+    return NULL;
+}
+
+/**
+ * this returns the last element of the iterator list
+ * @returns last element
+ */
+template<class T>
+    inline T* tIterator<T>::lastElement ()
+{
+  this->tmpEl = this->list->last;
+  if( likely(this->tmpEl != NULL))
+  {
+    this->currentEl = tmpEl->prev;
+    return this->tmpEl->curr;
+  }
+  else
+    return NULL;
+}
+
+
+/**
+ *  use it to iterate through the list
+ * @returns next list element
+ */
+template<class T>
+    inline T* tIterator<T>::nextElement ()
+{
+  if( unlikely(this->currentEl == NULL))
+    return NULL;
+
+  this->tmpEl = this->currentEl;
+  this->currentEl = this->currentEl->next;
+
+  return this->tmpEl->curr;
+}
+
+
+/**
+ *  use it to iterate backwards through the list
+ * @returns next list element
+ */
+template<class T>
+    inline T* tIterator<T>::prevElement ()
+{
+  if( unlikely(this->currentEl == NULL))
+    return NULL;
+
+  this->tmpEl = this->currentEl;
+  this->currentEl = this->currentEl->prev;
+
+  return this->tmpEl->curr;
+}
+
+
+/**
+ *  gets the element after the selected one, sets the iterator to this point in the list
+ * @param element the element to seek
+ * @returns current list element
+ */
+template<class T>
+    inline T* tIterator<T>::seekElement (const T* element)
+{
+  if( unlikely(element == NULL))
+  {
+    this->currentEl = NULL;
+    return NULL;
+  }
+  this->tmpEl = this->list->first;
+  while( this->tmpEl != NULL)
+  {
+    if( unlikely(this->tmpEl->curr == element))
+    {
+      this->currentEl = this->tmpEl;
+      return this->currentEl->curr;
+    }
+    this->tmpEl = this->tmpEl->next;
+  }
+  this->currentEl = NULL;
+  return NULL;
+}
+
+/**
+ * grabs the iterator entity from another iterator
+ * @param iterator the iterator to grab the local currentEl from
+ * @returns the grabbed element (current). NULL if not found, or not defined
+ *
+ * Both iterators must be from the same List!
+ */
+template<class T>
+    T* tIterator<T>::iteratorElement(const tIterator<T>* iterator)
+{
+  if( unlikely(iterator != NULL && iterator->list == this->list))
+  {
+    this->currentEl = iterator->currentEl;
+    if (this->currentEl != NULL)
+      return this->currentEl->curr;
+    else
+      return NULL;
+  }
+  else
+  {
+    this->currentEl = NULL;
+    return NULL;
+  }
+}
+
+template<class T>
+    bool tIterator<T>::compareListPointer(const tList<T>* list) const
+{
+  return (this->list == list)?true:false;
+}
+
+
+/**
+ *  use it to move through the list without interfering with the iteration
+ * @returns previous list element
+ *
+ * this stepping mode will !not! step beyond the boundraries of the List!
+ */
+template<class T>
+    inline T* tIterator<T>::nextStep ()
+{
+  if( unlikely(this->tmpEl == NULL || this->tmpEl->next == NULL))
+    return NULL;
+  else
+  {
+    this->tmpEl = this->tmpEl->next;
+    return tmpEl->curr;
+  }
+}
+
+/**
+ *  use it to move backwards through the list without interfering with the itereation
+ * @returns next list element
+ *
+ * this stepping mode will !not! step beyond the boundraries of the List!
+ */
+template<class T>
+    inline T* tIterator<T>::prevStep ()
+{
+  if( unlikely(this->tmpEl == NULL || this->tmpEl->prev == NULL))
+    return NULL;
+  else
+  {
+    this->tmpEl = this->tmpEl->prev;
+    return tmpEl->curr;
+  }
+}
+
+/**
+ * @returns the current Element
+ */
+template<class T>
+    inline T* tIterator<T>::getCurrent()
+{
+  if (likely(this->tmpEl != NULL))
+    return this->tmpEl->curr;
+  else
+    return NULL;
+}
+
+#endif /* _T_LIST_H */
Index: branches/network/src/lib/util/multi_type.cc
===================================================================
--- branches/network/src/lib/util/multi_type.cc	(revision 6636)
+++ branches/network/src/lib/util/multi_type.cc	(revision 6636)
@@ -0,0 +1,429 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "multi_type.h"
+
+//#include "stdincl.h"
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#ifdef DEBUG
+#include "debug.h"
+#endif
+
+using namespace std;
+
+/**
+ * creates a multiType without any stored value at all.
+ */
+MultiType::MultiType()
+{
+  this->init();
+}
+/**
+ * creates a multiType out of a boolean
+ * @param value the Value of this MulitType
+ */
+MultiType::MultiType(bool value)
+{
+  this->init();
+  this->setBool(value);
+}
+
+/**
+ * creates a multiType out of an integer
+ * @param value the Value of this MulitType
+ */
+MultiType::MultiType(int value)
+{
+  this->init();
+  this->setInt(value);
+}
+
+/**
+ * creates a multiType out of a float (double)
+ * @param value the Value of this MulitType
+ */
+MultiType::MultiType(double value)
+{
+  this->init();
+  this->setFloat(value);
+}
+
+/**
+ * creates a multiType out of a char
+ * @param value the Value of this MulitType
+ */
+MultiType::MultiType(char value)
+{
+  this->init();
+  this->setChar(value);
+}
+
+/**
+ * creates a multiType out of a String
+ * @param value the Value of this MulitType
+ */
+MultiType::MultiType(const char* value)
+{
+  this->init();
+  this->setString(value);
+}
+
+MultiType::MultiType(const MultiType& multiType)
+{
+  this->init();
+  printf("test2");
+  *this = multiType;
+}
+
+/**
+ * standard deconstructor
+*/
+MultiType::~MultiType ()
+{
+  if (this->storedString != NULL)
+    delete[] this->storedString;
+}
+
+/**
+ * copy Constructor
+ * @param mt: the entity to copy
+ * @returns a Copy of itself. (strings inside are copied as well)
+ */
+MultiType& MultiType::operator= (const MultiType& mt)
+{
+  this->type = mt.type;
+  this->value = mt.value;
+  if (mt.type == MT_STRING && mt.storedString != NULL)
+  {
+    this->setString(mt.storedString);
+  }
+  else
+    this->storedString = NULL;
+  return *this;
+}
+
+/**
+ * initializes the MultiType
+ */
+void MultiType::init()
+{
+  this->type = MT_NULL;
+  this->storedString = NULL;
+  this->value.Float = 0.0f;
+}
+
+
+/**
+ * sets the type of this MultiType and resets to the default value
+ * @param type the new Type
+ */
+void MultiType::setType(int type)
+{
+  if (this->type != type)
+    this->type = (MT_Type)type;
+}
+
+/**
+ * sets a new Value to the MultiType
+ * @param value the new Value as a bool
+ */
+void MultiType::setBool(bool value)
+{
+  this->type = MT_BOOL;
+  this->value.Bool = value;
+}
+
+/**
+ * sets a new Value to the MultiType
+ * @param value the new Value as an int
+ */
+void MultiType::setInt(int value)
+{
+  this->type = MT_INT;
+  this->value.Int = value;
+}
+
+/**
+ * sets a new Value to the MultiType
+ * @param value the new Value as a float
+ */
+void MultiType::setFloat(float value)
+{
+  this->type = MT_FLOAT;
+  this->value.Float = value;
+}
+
+/**
+ * sets a new Value to the MultiType
+ * @param value the new Value as a char
+ */
+void MultiType::setChar(char value)
+{
+  this->type = MT_CHAR;
+  this->value.Char = value;
+}
+
+/**
+ * sets a new Value to the MultiType
+ * @param value the new Value as a String
+ */
+void MultiType::setString(const char* value)
+{
+  this->type = MT_STRING;
+
+  if (this->storedString != NULL)
+    delete[] this->storedString;
+
+  if (value == NULL)
+  {
+    this->storedString = new char[1];
+    this->storedString[0] = '\0';
+    this->value.String = this->storedString;
+    return;
+  }
+  else
+  {
+    this->storedString = new char[strlen(value)+1];
+    strcpy(storedString, value);
+    this->value.String = this->storedString;
+  }
+}
+
+
+
+
+
+/**
+ * @returns the Value of this MultiType as a int
+ */
+bool MultiType::getBool() const
+{
+  // default case:
+  if (this->type & MT_BOOL)
+    return this->value.Bool;
+  // Special Cases:
+  else if (this->type & MT_INT) return (this->value.Int == 0)? false : true;
+  else if (this->type & MT_FLOAT) return (this->value.Float == 0.0f)? false : true;
+  else if (this->type & MT_CHAR) return (this->value.Char == '\0')? false : true;
+  else if (this->type & MT_STRING) return (!strncmp(this->value.String, "true", 4) || !strncmp(this->value.String, "TRUE", 4) || !strncmp(this->value.String, "1", 1))? true : false; //! @TODO make this better.
+
+  return false;
+}
+
+/**
+ * @returns the Value of this MultiType as a int
+ */
+int MultiType::getInt() const
+{
+  // default case:
+  if (this->type & MT_INT)
+    return this->value.Int;
+  if (this->type & MT_BOOL) return (this->value.Bool)? 1 : 0;
+  else if (this->type & MT_FLOAT) return (int) this->value.Float;
+  else if (this->type & MT_CHAR) return (int) this->value.Char;
+  else if (this->type & MT_STRING) {
+    char* endPtr = NULL;
+    int result = strtol(this->value.String, &endPtr, 10);
+    if ( endPtr >= this->value.String && endPtr < this->value.String + strlen(this->value.String))
+      return 0;
+    else
+      return result;
+  }
+
+  return 0;
+}
+
+/**
+ * @returns the Value of this MultiType as a float
+ */
+float MultiType::getFloat() const
+{
+ // default case:
+  if (this->type & MT_FLOAT)
+    return this->value.Float;
+  if (this->type & MT_BOOL) return (this->value.Bool == true)? 1.0f : 0.0f;
+  else if (this->type & MT_INT) return (float) this->value.Int;
+  else if (this->type & MT_CHAR) return (float) this->value.Char;
+  else if (this->type & MT_STRING) {
+    char* endPtr = NULL;
+    double result = strtod(this->value.String, &endPtr);
+    if ( endPtr >= this->value.String && endPtr < this->value.String + strlen(this->value.String))
+      return 0.0f;
+    else
+      return result;
+  }
+
+  return 0.0f;
+}
+
+
+/**
+ * @returns the Value of this MultiType as a char
+ */
+char MultiType::getChar() const
+{
+ // default case:
+  if (this->type & MT_INT)
+    return this->value.Int;
+  if (this->type & MT_BOOL) return (this->value.Bool)? 'y' : 'n';
+  else if (this->type & MT_INT) return (int) this->value.Int;
+  else if (this->type & MT_FLOAT) return (char) this->value.Float;
+  else if (this->type & MT_STRING) return *this->value.String;
+
+  return '\0';
+}
+
+/**
+ * @returns the Value of this MultiType as a String
+ */
+const char* MultiType::getString()
+{
+ // default case:
+  if (this->type & MT_STRING)
+    return (this->value.String != NULL)? this->value.String : "";
+  else
+  {
+    if (this->type & MT_BOOL) return (this->value.Bool)? "true" : "false";
+    char tmpString[128];
+    if (this->storedString != NULL)
+    {
+      delete[] this->storedString;
+      this->storedString = NULL;
+    }
+    if (this->type & MT_CHAR)
+    {
+      this->storedString = new char[2];
+      this->storedString[0] = this->value.Char;
+      this->storedString[1] = '\0';
+      return this->storedString;
+    }
+    else if (this->type & MT_INT)
+    {
+      sprintf(tmpString, "%d", this->value.Int);
+      this->storedString = new char[strlen(tmpString)+1];
+      strcpy (this->storedString, tmpString);
+      return this->storedString;
+    }
+    if (this->type & MT_FLOAT)
+    {
+      sprintf(tmpString, "%f", this->value.Float);
+      this->storedString = new char[strlen (tmpString)+1];
+      strcpy (this->storedString, tmpString);
+      return this->storedString;
+    }
+  }
+
+  return "";
+}
+
+/**
+ * prints out some nice debug output
+ */
+void MultiType::debug()
+{
+#ifdef DEBUG
+  PRINT(0)
+#else
+  printf
+#endif
+      ("MultiType of Type '%s' :: Values: BOOL: '%d', INT: '%d', FLOAT: '%f', CHAR: '%c', STRING '%s'\n",
+         MultiType::MultiTypeToString(this->type),
+         this->getBool(),
+         this->getInt(),
+         this->getFloat(),
+         this->getChar(),
+         this->getString()
+      );
+
+
+}
+
+/**
+ * Resets the MultiType to default values.
+ */
+void MultiType::reset()
+{
+  switch ( this->type )
+  {
+    case MT_BOOL:
+      this->setBool(false);
+    case MT_INT:
+      this->setInt(0);
+      break;
+    case MT_FLOAT:
+      this->setFloat(0.0f);
+      break;
+    case MT_CHAR:
+      this->setChar('\0');
+      break;
+    case MT_STRING:
+      this->setString("");
+      break;
+    default:
+#ifdef DEBUG
+      PRINTF(2)("Unknown Type not reseting\n");
+#endif
+      break;
+  }
+}
+
+/**
+ * converts a MT_Type into a String
+ * @param type: the MT_Type
+ * @returns: the Type as a constant String (do not delete)
+ */
+const char* MultiType::MultiTypeToString(MT_Type type)
+{
+  switch ( type )
+  {
+   default:
+    return "NONE";
+   case MT_BOOL:
+    return "bool";
+   case MT_INT:
+    return "int";
+   case MT_FLOAT:
+    return "float";
+   case MT_CHAR:
+    return "char";
+   case MT_STRING:
+    return "string";
+  }
+}
+
+/**
+ * converts a String into a MT_Type
+ * @param type: the Type as a String
+ * @returns: the Type as MT_Type
+ */
+MT_Type MultiType::StringToMultiType(const char* type)
+{
+  if (!strncmp(type, "bool", 4))
+    return MT_BOOL;
+  if (!strncmp(type, "int", 3))
+    return MT_INT;
+  if (!strncmp(type, "float", 5))
+    return MT_FLOAT;
+  if (!strncmp(type, "char", 4))
+    return MT_CHAR;
+  if (!strncmp(type, "string", 6))
+    return MT_STRING;
+}
Index: branches/network/src/lib/util/multi_type.h
===================================================================
--- branches/network/src/lib/util/multi_type.h	(revision 6636)
+++ branches/network/src/lib/util/multi_type.h	(revision 6636)
@@ -0,0 +1,99 @@
+/*!
+ * @file multi_type.h
+ * @brief Definition of ...
+ */
+
+#ifndef _MULTI_TYPE_H
+#define _MULTI_TYPE_H
+
+// FORWARD DECLARATION
+
+//! An enumerator defining Types, that can be stored inside a MultiType.
+typedef enum
+{
+  MT_NULL            = 0,                  //!< No Value at all.
+  MT_BOOL            = 1,                  //!< A bool Value.
+  MT_INT             = 2,                  //!< An int Value.
+  MT_UINT            = 2,
+  MT_LONG            = 2,
+  MT_FLOAT           = 4,                  //!< A float Value.
+  MT_CHAR            = 8,                  //!< A single char.
+  MT_STRING          = 16,                 //!< An entire String.
+  MT_EXT1            = 32,                 //!< An external Type.
+  MT_EXT2            = 64,                 //!< An external Type.
+} MT_Type;
+
+
+
+//! A class that encapsulates multiple differen types.
+/**
+ * Only one Value can be Stored inside this Class, but it can have any type: @see MT_Type.
+ */
+class MultiType {
+
+  public:
+    MultiType();
+    MultiType(bool value);
+    MultiType(int value);
+    MultiType(double value);
+    MultiType(char value);
+    MultiType(const char* value);
+    MultiType(const MultiType& multiType);
+    virtual ~MultiType();
+
+    MultiType& operator= (const MultiType& mt);
+
+    void setType(int type);
+
+    void setBool(bool value);
+    void setInt(int value);
+    void setFloat(float value);
+    void setChar(char value);
+    void setString(const char* value);
+
+    inline void setValue(bool value) { this->setBool(value); };
+    inline void setValue(int value) { this->setInt(value); };
+    inline void setValue(float value) { this->setFloat(value); };
+    inline void setValue(char value) { this->setChar(value); };
+    inline void setValue(const char* value) { this->setString(value); };
+
+    /** @returns the Type of the Value stored in this MultiType */
+    inline MT_Type getType() const { return this->type; };
+
+
+    /* RETRIEVING FUNCTIONS */
+    bool getBool() const;
+    int getInt() const;
+    float getFloat() const;
+    char getChar() const;
+    const char* getString();
+
+    void reset();
+
+    void debug();
+
+    static const char* MultiTypeToString(MT_Type type);
+    static MT_Type StringToMultiType(const char* type);
+
+  private:
+    void init();
+
+
+  private:
+
+    union MultiTypeValue
+    {
+      bool              Bool;
+      int               Int;
+      float             Float;
+      char              Char;
+      char*             String;
+
+    }                   value;
+
+    MT_Type             type;
+
+    char*               storedString;
+};
+
+#endif /* _MULTI_TYPE_H */
Index: branches/network/src/lib/util/substring.cc
===================================================================
--- branches/network/src/lib/util/substring.cc	(revision 6636)
+++ branches/network/src/lib/util/substring.cc	(revision 6636)
@@ -0,0 +1,277 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: Benjamin Grauer
+
+   2005-06-10: some naming conventions
+*/
+
+
+/**
+ *  breaks a string into parts that were initially seperated by comma
+ * @param string the string to break into substrings
+*/
+
+#include "substring.h"
+
+#include "debug.h"
+#include <string.h>
+#include <assert.h>
+
+SubString::SubString( const char* string, char splitter)
+{
+  this->splittersCount = 0;
+  if (string == NULL)
+  {
+    this->strings = NULL;
+    this->offsets = NULL;
+    return;
+  }
+
+  for( int i = 0; i < strlen(string); i++)
+    if( string[i] == splitter)
+      this->splittersCount++;
+
+  this->splittersCount += 1;
+
+  this->strings = new char*[this->splittersCount];
+  this->offsets = new unsigned int[this->splittersCount];
+  assert (this->strings != NULL && this->offsets != NULL);
+
+  int i = 0;
+  int l = 0;
+
+  if( this->splittersCount > 1)
+  {
+    const char* offset = string;
+    const char* end = strchr( string, splitter);
+    while( end != NULL)
+    {
+      assert( i < this->splittersCount);
+      l = end - offset;
+      this->strings[i] = new char[l + 1];
+      assert( strings[i] != NULL);
+      strncpy( strings[i], offset, l);
+      strings[i][l] = '\0';
+      this->offsets[i] = offset - string;
+      i++;
+      end++;
+      offset = end;
+      end = strchr( offset, splitter);
+    }
+
+    l = strlen( offset);
+    strings[i] = new char[l + 1];
+    strncpy( strings[i], offset, l);
+    strings[i][l] = '\0';
+    this->offsets[i] = offset - string;
+  }
+  else
+  {
+    this->strings[0] = new char[strlen(string)+1];
+    strcpy(this->strings[0], string);
+    this->offsets[0] = 0;
+  }
+}
+
+
+/**
+ * Splits a String into a Substring removing all whiteSpaces
+ * @param string the String to Split
+ * @param whiteSpaces MUST BE __TRUE__
+ *
+ */
+SubString::SubString(const char* string, bool whiteSpaces)
+{
+  this->splittersCount = 0;
+  if (string == NULL || whiteSpaces == false)
+  {
+    this->strings = NULL;
+    this->offsets = NULL;
+    return;
+  }
+
+  // chop the input to the beginning of something usefull
+  if (strlen(string) > 0)
+    string = string + strspn(string, " \t\n");
+
+  // count the Splitters
+  bool lastWasWhiteSpace = false;
+  for(unsigned int i = 0; i < strlen(string); i++)
+    if( string[i] == ' ' || string[i] == '\t' || string[i] == '\n' )
+      lastWasWhiteSpace = true;
+    else
+    {
+      if (lastWasWhiteSpace)
+        this->splittersCount ++;
+      lastWasWhiteSpace = false;
+    }
+  this->splittersCount += 1;
+
+  // allocate memory
+  this->strings = new char*[this->splittersCount];
+  this->offsets = new unsigned int[this->splittersCount];
+  assert (this->strings != NULL && this->offsets != NULL);
+
+
+  // split the String into substrings
+  int l = 0;
+  unsigned int i = 0;
+  if( this->splittersCount > 1)
+  {
+    const char* offset = string;
+    const char* end = offset + strcspn(offset, " \t\n");
+    for (i = 0; i < this->splittersCount; i++)
+    {
+      assert( i < this->splittersCount);
+      l = end - offset;
+      this->strings[i] = new char[l + 1];
+      assert( strings[i] != NULL);
+      strncpy( strings[i], offset, l);
+      strings[i][l] = '\0';
+      this->offsets[i] = offset - string;
+      end += strspn(end, " \t\n");
+      offset = end;
+      end = offset + strcspn(offset, " \t\n");
+    }
+  }
+  else
+  {
+    unsigned int length = strcspn(string, " \t\n");
+    this->strings[0] = new char[length+1];
+    strncpy(this->strings[0], string, length);
+    this->strings[0][length] = '\0';
+    offsets[0] = 0;
+  }
+}
+
+SubString::SubString(const char* string, const char* splitters, char escapeChar)
+{
+  this->splittersCount = 0;
+  if (string == NULL || splitters == NULL)
+  {
+    this->strings = NULL;
+    this->offsets = NULL;
+    return;
+  }
+
+  // chop the input to the beginning of something usefull
+  if (strlen(string) > 0)
+    string = string + strspn(string, splitters);
+
+  // count the Splitters
+  bool lastWasSplitter = false;
+  for(unsigned int i = 0; i < strlen(string); i++)
+  {
+
+    if( strchr(splitters, string[i] ))
+      lastWasSplitter = true;
+    else
+    {
+      if (lastWasSplitter)
+      {
+        this->splittersCount ++;
+        lastWasSplitter = false;
+      }
+    }
+  }
+  this->splittersCount += 1;
+
+  // allocate memory
+  this->strings = new char*[this->splittersCount];
+  this->offsets = new unsigned int[this->splittersCount];
+  assert (this->strings != NULL && this->offsets != NULL);
+
+
+  // split the String into substrings
+  int l = 0;
+  unsigned int i = 0;
+  if( this->splittersCount > 1)
+  {
+    const char* offset = string;
+    const char* end = offset + strcspn(offset, splitters);
+    for (i = 0; i < this->splittersCount; i++)
+    {
+      assert( i < this->splittersCount);
+      l = end - offset;
+      this->strings[i] = new char[l + 1];
+      assert( strings[i] != NULL);
+      strncpy( strings[i], offset, l);
+      strings[i][l] = '\0';
+      this->offsets[i] = offset - string;
+      end += strspn(end, splitters);
+      offset = end;
+      end = offset + strcspn(offset, splitters);
+    }
+  }
+  else
+  {
+    unsigned int length = strcspn(string, splitters);
+    this->strings[0] = new char[length+1];
+    strncpy(this->strings[0], string, length);
+    this->strings[0][length] = '\0';
+    offsets[0] = 0;
+  }
+}
+
+
+/**
+ *  removes the object from memory
+*/
+SubString::~SubString()
+{
+  if (this->strings)
+  {
+    for(unsigned int i = 0; i < this->splittersCount; i++)
+      delete[] this->strings[i];
+    delete[] this->strings;
+  }
+  delete[] this->offsets;
+}
+
+/**
+ *  get a particular substring
+ * @param i the ID of the substring to return
+ * @returns the designated substring or NULL if an invalid ID was given
+*/
+const char* SubString::getString(unsigned int i)
+{
+  if( i < this->splittersCount && i >= 0)
+    return this->strings[i];
+  else
+    return NULL;
+}
+
+/**
+ * get a particular substring's offset
+ * @param i the ID of the substring to get the offset from
+ * @returns the offset or NULL if an invalid ID was given
+ */
+unsigned int SubString::getOffset(unsigned int i)
+{
+  if( i < this->splittersCount && i >= 0)
+    return this->offsets[i];
+  else
+    return 0;
+}
+
+/**
+ * Some nice debug information about this SubString
+ */
+void SubString::debug() const
+{
+  PRINT(0)("Substring-information::count=%d ::", this->splittersCount);
+  if (this->strings != NULL)
+    for (unsigned int i = 0; i < this->splittersCount; i++)
+     PRINT(0)("s%d='%s'::", i, this->strings[i]);
+  PRINT(0)("\n");
+}
Index: branches/network/src/lib/util/substring.h
===================================================================
--- branches/network/src/lib/util/substring.h	(revision 6636)
+++ branches/network/src/lib/util/substring.h	(revision 6636)
@@ -0,0 +1,30 @@
+/*!
+  \file substring.h
+  \brief a small class to get the parts of a string separated by commas
+*/
+
+#ifndef _SUBSTRING_H
+#define _SUBSTRING_H
+
+//! A class that can load one string and split it in multipe ones
+class SubString
+{
+ public:
+  SubString(const char* string, char splitter = ',');
+  SubString(const char* string, bool whiteSpaces);
+  SubString(const char* string, const char* splitters, char escapeChar ='\\');
+  ~SubString();
+
+  inline unsigned int getCount() { return this->splittersCount; };
+  const char* getString(unsigned int i);
+  unsigned int getOffset(unsigned int i);
+
+  void debug() const;
+
+ private:
+  char**          strings;                      //!< strings produced from a single string splitted in multiple strings
+  unsigned int*   offsets;                      //!< offsets of the beginning of the input-string to the beginning of each substring.
+  unsigned int    splittersCount;               //!< how many splitted parts
+};
+
+#endif /* _SUBSTRING_H */
Index: branches/network/src/lib/util/t_stack.h
===================================================================
--- branches/network/src/lib/util/t_stack.h	(revision 6636)
+++ branches/network/src/lib/util/t_stack.h	(revision 6636)
@@ -0,0 +1,133 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+/*!
+  @file t_stack.h
+  @brief Contains the tStack Class that handles stacks of classes.
+  this class creates a Array of a semi-Dynamic length.
+  beware, that after finalizing the array may not be resized again.
+*/
+
+#ifndef _T_STACK_H
+#define _T_STACK_H
+
+using namespace std;
+
+//! Stack Class that handles dynamic-type Stacks.
+template<typename T>
+    class tStack
+{
+  public:
+    tStack();
+    ~tStack();
+
+    void push(T entry);
+    T pop();
+    T getTop();
+    /** @returns the Size of the Stack (0 if empty) */
+    unsigned int getSize() { return this->entryCount; };
+
+    // stack copying.
+    // tStack<T>& operator= (const tStack<T>& stack);
+
+    void debug() const ;
+
+  private:
+    //! One entry of the Stack
+    struct tStackEntry
+    {
+      T              value;          //!< The value of this Entry.
+      tStackEntry*   next;           //!< Pointer to the Next entry.
+    };
+
+
+    unsigned int     entryCount;      //!< The count of Entries in this Array.
+    tStackEntry*     topEntry;        //!< Pointer to the first Entry of this Array
+};
+
+/**
+ * creates and initializes a Stack
+ */
+template<typename T>
+    tStack<T>::tStack()
+{
+  this->topEntry = NULL;
+  this->entryCount = 0;
+}
+
+/**
+ * delocates alocated memory from a Stack.
+ * This does not delete the entries of the Stack
+ */
+template<typename T>
+    tStack<T>::~tStack()
+{
+  tStackEntry* delEntry;
+  while (this->topEntry != NULL)
+  {
+    delEntry = this->topEntry;
+    this->topEntry = topEntry->next;
+    delete delEntry;
+  }
+}
+
+
+/**
+ * pushes one Entry into the Stack.
+ * @param entry the Entry to push into the Stack
+ */
+template<typename T>
+    void tStack<T>::push(T entry)
+{
+  tStackEntry* newEntry = new tStackEntry;
+  newEntry->value = entry;
+  newEntry->next = this->topEntry;
+  this->topEntry = newEntry;
+
+  this->entryCount++;
+}
+
+
+/**
+ * pops up the topmost enrty of the Stack, and moves the pointer to the next Stack-entry.
+ * @returns the top-most enrty.
+ */
+template<typename T>
+    T tStack<T>::pop()
+{
+  if (this->topEntry == NULL)
+    return 0;
+
+  tStackEntry* retEntry = this->topEntry;
+  T retVal = retEntry->value;
+  this->topEntry = this->topEntry->next;
+  delete retEntry;
+  this->entryCount--;
+  return retVal;
+}
+
+/**
+ * @returns the topMost entry of the Stack without removing it.
+ */
+template<typename T>
+    T tStack<T>::getTop()
+{
+  if (this->topEntry != NULL)
+    return this->topEntry->value;
+  else
+    return NULL;
+}
+
+#endif /* _T_STACK_H */
Index: branches/network/src/orxonox.cc
===================================================================
--- branches/network/src/orxonox.cc	(revision 6636)
+++ branches/network/src/orxonox.cc	(revision 6636)
@@ -0,0 +1,538 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: Christian Meyer
+   co-programmer: Benjamin Grauer: injected ResourceManager/GraphicsEngine/GUI
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_ORXONOX
+#include "orxonox.h"
+
+#include "globals.h"
+
+#include "gui.h"
+
+#include "parser/ini_parser/ini_parser.h"
+#include "game_loader.h"
+
+//ENGINES
+#include "graphics_engine.h"
+#include "sound_engine.h"
+#include "resource_manager.h"
+#include "cd_engine.h"
+#include "text_engine.h"
+#include "event_handler.h"
+
+#include "factory.h"
+#include "fast_factory.h"
+
+#include "benchmark.h"
+
+#include "class_list.h"
+#include "shell_command_class.h"
+#include "shell_command.h"
+#include "shell_buffer.h"
+
+#include "load_param_description.h"
+
+#include "network_manager.h"
+
+#include <string.h>
+
+int verbose = 4;
+
+using namespace std;
+
+SHELL_COMMAND(restart, Orxonox, restart);
+
+/**
+ *  create a new Orxonox
+
+   In this funcitons only global values are set. The game will not be started here.
+*/
+Orxonox::Orxonox ()
+{
+  this->setClassID(CL_ORXONOX, "Orxonox");
+  this->setName("orxonox-main");
+
+  this->iniParser = NULL;
+
+  this->argc = 0;
+  this->argv = NULL;
+
+  /* this way, there is no network enabled: */
+  this->serverName = NULL;
+  this->port = -1;
+
+  this->configFileName = NULL;
+}
+
+/**
+ *  remove Orxonox from memory
+*/
+Orxonox::~Orxonox ()
+{
+  // game-specific
+  delete GameLoader::getInstance();
+
+  // class-less services/factories
+  Factory::deleteFactories();
+  FastFactory::deleteAll();
+  ShellCommandClass::unregisterAllCommands();
+
+  LoadClassDescription::deleteAllDescriptions();
+
+  // engines
+  delete CDEngine::getInstance();
+  delete SoundEngine::getInstance();
+  delete GraphicsEngine::getInstance(); // deleting the Graphics
+  delete EventHandler::getInstance();
+
+  // handlers
+  delete ResourceManager::getInstance(); // deletes the Resource Manager
+  // output-buffer
+  delete ShellBuffer::getInstance();
+
+  // orxonox class-stuff
+  delete this->iniParser;
+  delete[] this->configFileName;
+
+  SDL_QuitSubSystem(SDL_INIT_TIMER);
+  ClassList::debug();
+
+  PRINT(3)
+  (
+    "===================================================\n" \
+    "Thanks for playing orxonox.\n" \
+    "visit: http://www.orxonox.net for new versions.\n" \
+    "===================================================\n" \
+    ORXONOX_LICENSE_SHORT
+  );
+
+  Orxonox::singletonRef = NULL;
+}
+
+/**
+ *  this is a singleton class to prevent duplicates
+ */
+Orxonox* Orxonox::singletonRef = NULL;
+
+// DANGEROUS
+void Orxonox::restart()
+{
+  //   int argc = this->argc;
+  //   char** argv = this->argv;
+  //
+  //   Orxonox *orx = Orxonox::getInstance();
+  //
+  //   delete orx;
+  //
+  //   orx = Orxonox::getInstance();
+  //
+  //   if((*orx).init(argc, argv) == -1)
+  //   {
+  //     PRINTF(1)("! Orxonox initialization failed\n");
+  //     return;
+  //   }
+  //
+  //   printf("finished inizialisation\n");
+  //   orx->start();
+}
+
+/**
+ *  this finds the config file
+ * @returns the new config-fileName
+ * Since the config file varies from user to user and since one may want to specify different config files
+ * for certain occasions or platforms this function finds the right config file for every occasion and stores
+ * it's path and name into configfilename
+*/
+const char* Orxonox::getConfigFile ()
+{
+  if (ResourceManager::isFile("orxonox.conf"))
+  {
+    this->configFileName = new char[strlen("orxonox.conf")+1];
+    strcpy(this->configFileName, "orxonox.conf");
+  }
+  else
+    this->configFileName = ResourceManager::homeDirCheck(DEFAULT_CONFIG_FILE);
+  this->iniParser = new IniParser(this->configFileName);
+  PRINTF(3)("Parsed Config File: '%s'\n", this->configFileName);
+}
+
+/**
+ * initialize Orxonox with command line
+ */
+int Orxonox::init (int argc, char** argv, const char* name, int port)
+{
+  this->argc = argc;
+  this->argv = argv;
+
+  this->serverName = name;
+  this->port = port;
+
+  // initialize the Config-file
+  this->getConfigFile();
+
+  // windows must not write into stdout.txt and stderr.txt
+#ifdef __WIN32__
+  freopen( "CON", "w", stdout );
+  freopen( "CON", "w", stderr );
+#endif
+
+  // initialize everything
+  SDL_Init(0);
+  if( initResources () == -1)
+    return -1;
+  if( initVideo() == -1)
+    return -1;
+  if( initSound() == -1)
+    return -1;
+  if( initInput() == -1)
+    return -1;
+  if( initNetworking () == -1)
+    return -1;
+  if( initMisc () == -1)
+    return -1;
+
+  return 0;
+}
+
+
+/**
+ * initializes SDL and OpenGL
+ */
+int Orxonox::initVideo()
+{
+  PRINTF(3)("> Initializing video\n");
+
+  GraphicsEngine::getInstance();
+
+  GraphicsEngine::getInstance()->initFromIniFile(this->iniParser);
+
+  char* iconName = ResourceManager::getFullName("pictures/fighter-top-32x32.bmp");
+  if (iconName != NULL)
+  {
+    GraphicsEngine::getInstance()->setWindowName(PACKAGE_NAME " " PACKAGE_VERSION, iconName);
+    delete[] iconName;
+  }
+  return 0;
+}
+
+
+/**
+ * initializes the sound engine
+ */
+int Orxonox::initSound()
+{
+  PRINT(3)("> Initializing sound\n");
+  // SDL_InitSubSystem(SDL_INIT_AUDIO);
+  SoundEngine::getInstance()->initAudio();
+  SoundEngine::getInstance()->allocateSources(1);
+
+  SoundEngine::getInstance()->loadSettings(this->iniParser);
+  return 0;
+}
+
+
+/**
+ * initializes input functions
+ */
+int Orxonox::initInput()
+{
+  PRINT(3)("> Initializing input\n");
+
+  EventHandler::getInstance()->init(this->iniParser);
+  EventHandler::getInstance()->subscribe(GraphicsEngine::getInstance(), ES_ALL, EV_VIDEO_RESIZE);
+
+  return 0;
+}
+
+
+/**
+ * initializes network system
+ */
+int Orxonox::initNetworking()
+{
+  PRINT(3)("> Initializing networking\n");
+
+  if( this->serverName != NULL) // we are a client
+    NetworkManager::getInstance()->establishConnection(this->serverName, port);
+  else if( this->port > 0) {    // we are a server
+    NetworkManager::getInstance()->createServer(port);
+  }
+
+  return 0;
+}
+
+
+/**
+ * initializes and loads resource files
+ */
+int Orxonox::initResources()
+{
+  PRINTF(3)("> Initializing resources\n");
+
+  PRINT(3)("initializing ResourceManager\n");
+
+  // init the resource manager
+  const char* dataPath;
+  if ((dataPath = this->iniParser->getVar(CONFIG_NAME_DATADIR, CONFIG_SECTION_DATA))!= NULL)
+  {
+    if (!ResourceManager::getInstance()->setDataDir(dataPath) &&
+        !ResourceManager::getInstance()->verifyDataDir(DEFAULT_DATA_DIR_CHECKFILE))
+    {
+      PRINTF(1)("Data Could not be located in %s\n", dataPath);
+    }
+  }
+
+  if (!ResourceManager::getInstance()->verifyDataDir(DEFAULT_DATA_DIR_CHECKFILE))
+  {
+    PRINTF(1)("The DataDirectory %s could not be verified\n\nh" \
+              "!!!  Please Change in File %s Section %s Entry %s to a suitable value !!!\n",
+              ResourceManager::getInstance()->getDataDir(),
+              this->configFileName,
+              CONFIG_SECTION_DATA,
+              CONFIG_NAME_DATADIR );
+    Gui* gui = new Gui(argc, argv);
+    gui->startGui();
+    delete gui;
+    exit(-1);
+  }
+  //! @todo this is a hack and should be loadable
+  char* imageDir = ResourceManager::getInstance()->getFullName("maps");
+  ResourceManager::getInstance()->addImageDir(imageDir);
+  delete[] imageDir;
+
+  // start the collision detection engine
+  CDEngine::getInstance();
+  return 0;
+}
+
+/**
+ * initializes miscelaneous features
+ * @return -1 on failure
+ */
+int Orxonox::initMisc()
+{
+  ShellBuffer::getInstance();
+  return 0;
+}
+
+/**
+ *  starts the orxonox game or menu
+ * here is the central orxonox state manager. There are currently two states
+ * - menu
+ * - game-play
+ * both states manage their states themselfs again.
+*/
+void Orxonox::start()
+{
+
+  this->gameLoader = GameLoader::getInstance();
+
+  if( this->port != -1)
+    this->gameLoader->loadNetworkCampaign("worlds/DefaultNetworkCampaign.oxc");
+  else
+    this->gameLoader->loadCampaign("worlds/DefaultCampaign.oxc");                       /* start orxonox in single player mode */
+
+  //  this->gameLoader->loadDebugCampaign(DEBUG_CAMPAIGN_0);
+  this->gameLoader->init();
+  this->gameLoader->start();
+}
+
+
+/**
+ * handles sprecial events from localinput
+ * @param event: an event not handled by the CommandNode
+ */
+// void Orxonox::graphicsHandler(SDL_Event* event)
+// {
+//   // Handle special events such as reshape, quit, focus changes
+//   switch (event->type)
+//     {
+//     case SDL_VIDEORESIZE:
+//       GraphicsEngine* tmpGEngine = GraphicsEngine::getInstance();
+//       tmpGEngine->resolutionChanged(event->resize);
+//       break;
+//     }
+// }
+
+
+
+
+
+
+bool showGui = false;
+
+
+
+/**********************************
+*** ORXONOX MAIN STARTING POINT ***
+**********************************/
+/**
+ *
+ *  main function
+ *
+ * here the journey begins
+*/
+int main(int argc, char** argv)
+{
+  int i;
+  for(i = 1; i < argc; ++i)
+  {
+    if(     !strcmp( "--help", argv[i])     || !strcmp("-h", argv[i]))
+      return showHelp(argc, argv);
+    else if(!strcmp( "--gui", argv[i])      || !strcmp("-g", argv[i]))
+      showGui = true;
+    else if(!strcmp( "--client", argv[i])   || !strcmp("-c", argv[i]))
+      return startNetworkOrxonox(argc, argv);
+    else if(!strcmp( "--server", argv[i])   || !strcmp("-s", argv[i]))
+      return startNetworkOrxonox(argc, argv);
+    else if(!strcmp( "--license", argv[i])  || !strcmp("-l", argv[i]))
+      return PRINT(0)(ORXONOX_LICENSE_SHORT);
+  }
+
+  return startOrxonox(argc, argv, NULL, -1);
+}
+
+
+
+int showHelp(int argc, char** argv)
+{
+  PRINT(0)("Orxonox Version %s\n", PACKAGE_VERSION);
+  PRINT(0)(" Starts Orxonox - The most furious 3D Action Game :)\n");
+  PRINT(0)("\n");
+  PRINT(0)("Common options:\n");
+  PRINT(0)(" -g, --gui                        starts the orxonox with the configuration GUI \n");
+  PRINT(0)(" -h, --help                       shows this help\n");
+  PRINT(0)("\n");
+  PRINT(0)("Network options:\n");
+  PRINT(0)(" -s, --server [port]              starts Orxonox and listens on the [port] for players\n");
+  PRINT(0)(" -c, --client [hostname] [port]   starts Orxonox as a Client\n");
+  PRINT(0)(" -c, --client [ip address] [port] starts Orxonox as a Client\n");
+  PRINT(0)("\n");
+  PRINT(0)("Other options:\n");
+  PRINT(0)("     --license     prints the licence and exit\n\n");
+  PRINT(0)("\n");
+
+  //   {
+  //     Gui* gui = new Gui(argc, argv);
+  //     gui->printHelp();
+  //     delete gui;
+  //   }
+}
+
+
+
+
+/**
+ * starts orxonox in network mode
+ * @param argc parameters count given to orxonox
+ * @param argv parameters given to orxonox
+ */
+int startNetworkOrxonox(int argc, char** argv)
+{
+
+  int i;
+  for(i = 0; i < argc; ++i )
+  {
+    if( !strcmp( "--client", argv[i]) || !strcmp("-c", argv[i]))
+    {
+      if( argc <= (i+2))
+      {
+        printf(" Wrong arguments try following notations:\n");
+        printf("   --client [server ip address] [port number]\n");
+        printf("   --client [dns name] [port number]\n");
+        return 0;
+      }
+
+      const char* name = argv[i+1];
+      int port = atoi(argv[i+2]);
+      printf("Starting Orxonox as client: connecting to %s, on port %i\n", name, port);
+
+      startOrxonox(argc, argv, name, port);
+    }
+    else if( !strcmp( "--server", argv[i]) || !strcmp("-s", argv[i]))
+    {
+      if( argc <= (i+1))
+      {
+        printf(" Wrong arguments try following notations:\n");
+        printf("   --server [port number]\n");
+        return 0;
+      }
+
+      int port = atoi(argv[i+1]);
+      printf("Starting Orxonox as server, listening on port %i\n", port);
+
+      startOrxonox(argc, argv, NULL, port);
+    }
+  }
+}
+
+
+
+/**
+ * starts orxonox
+ * @param argc parameters count given to orxonox
+ * @param argv parameters given to orxonox
+ */
+int startOrxonox(int argc, char** argv, const char* name, int port)
+{
+  // checking for existence of the configuration-files, or if the lock file is still used
+  if (showGui || (!ResourceManager::isFile("./orxonox.conf") &&
+                  !ResourceManager::isFile(DEFAULT_CONFIG_FILE))
+#if DEBUG < 3 // developers do not need to see the GUI, when orxonox fails
+      || ResourceManager::isFile(DEFAULT_LOCK_FILE)
+#endif
+     )
+  {
+    if (ResourceManager::isFile(DEFAULT_LOCK_FILE))
+      ResourceManager::deleteFile(DEFAULT_LOCK_FILE);
+
+    // starting the GUI
+    Gui* gui = new Gui(argc, argv);
+    gui->startGui();
+
+    if (! gui->startOrxonox)
+      return 0;
+
+    delete gui;
+  }
+
+  PRINT(0)(">>> Starting Orxonox <<<\n");
+
+  ResourceManager::touchFile(DEFAULT_LOCK_FILE);
+
+  Orxonox *orx = Orxonox::getInstance();
+
+  if( orx->init(argc, argv, name, port) == -1)
+  {
+    PRINTF(1)("! Orxonox initialization failed\n");
+    return -1;
+  }
+
+  printf("finished inizialisation\n");
+  orx->start();
+
+  delete orx;
+  ResourceManager::deleteFile("~/.orxonox/orxonox.lock");
+}
Index: branches/network/src/orxonox.h
===================================================================
--- branches/network/src/orxonox.h	(revision 6636)
+++ branches/network/src/orxonox.h	(revision 6636)
@@ -0,0 +1,69 @@
+/*!
+ * @file orxonox.h
+ * Orxonox core functions
+*/
+
+#ifndef _ORXONOX_H
+#define _ORXONOX_H
+
+#include "base_object.h"
+
+class WorldEntity;
+class GameLoader;
+class IniParser;
+
+//! orxonox core singleton class
+/**
+*/
+class Orxonox : public BaseObject {
+
+ public:
+  virtual ~Orxonox ();
+  /** @returns a Pointer to the only object of this Class */
+  inline static Orxonox* getInstance() { if (!singletonRef) singletonRef = new Orxonox();  return singletonRef; };
+
+  int init(int argc, char** argv, const char* name, int port);
+
+  void restart();
+
+  void start();
+
+ private:
+  Orxonox ();
+
+  void parseIniFile(const char* fileName);
+
+  int initResources ();
+  int initVideo ();
+  int initSound ();
+  int initInput ();
+  int initNetworking ();
+  int initMisc ();
+
+  const char* getConfigFile ();
+
+ private:
+  static Orxonox*   singletonRef;            //!< singleton reference to orxonox
+
+  IniParser*        iniParser;               //!< Reference to the ini-parser used in orxonox
+  char*             configFileName;          //!< Filename of the configuration-file.
+  GameLoader*       gameLoader;              //!< The gameLoader
+
+  unsigned int      argc;                    //!< Count of Arguments of orxonox
+  char**            argv;                    //!< Values of th Arguments of orxonox.
+
+  const char*       serverName;              //!< Name of the Orxonox client if == NULL -> server
+  int               port;                    //!< number of the network port of the server/client if == -1 no network
+};
+
+
+////////////////////////
+// Start-up functions //
+////////////////////////
+int showHelp(int argc, char** argv);
+int showLicense();
+int startNetworkOrxonox(int argc, char** argv);
+int startOrxonox(int argc, char** argv, const char* clientName, int port);
+
+#endif /* _ORXONOX_H */
+
Index: branches/network/src/proto/proto_class.cc
===================================================================
--- branches/network/src/proto/proto_class.cc	(revision 6636)
+++ branches/network/src/proto/proto_class.cc	(revision 6636)
@@ -0,0 +1,50 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: ...
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "proto_class.h"
+
+using namespace std;
+
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+ProtoClass::ProtoClass ()
+{
+   this->setClassID(CL_PROTO_ID, "ProtoClass");
+
+   /* If you make a new class, what is most probably the case when you write this file
+      don't forget to:
+       1. Add the new file new_class.cc to the ./src/Makefile.am
+       2. Add the class identifier to ./src/class_id.h eg. CL_NEW_CLASS
+
+      Advanced Topics:
+      - if you want to let your object be managed via the ObjectManager make sure to read
+        the object_manager.h header comments. You will use this most certanly only if you
+        make many objects of your class, like a weapon bullet.
+   */
+}
+
+
+/**
+ * standard deconstructor
+*/
+ProtoClass::~ProtoClass ()
+{
+  // delete what has to be deleted here
+}
Index: branches/network/src/proto/proto_class.h
===================================================================
--- branches/network/src/proto/proto_class.h	(revision 6636)
+++ branches/network/src/proto/proto_class.h	(revision 6636)
@@ -0,0 +1,27 @@
+/*!
+ * @file proto_class.h
+ * @brief Definition of ...
+*/
+
+#ifndef _PROTO_CLASS_H
+#define _PROTO_CLASS_H
+
+#include "base_object.h"
+
+// FORWARD DECLARATION
+
+
+
+//! A class for ...
+class ProtoClass : public BaseObject {
+
+ public:
+  ProtoClass();
+  virtual ~ProtoClass();
+
+
+ private:
+
+};
+
+#endif /* _PROTO_CLASS_H */
Index: branches/network/src/proto/proto_singleton.cc
===================================================================
--- branches/network/src/proto/proto_singleton.cc	(revision 6636)
+++ branches/network/src/proto/proto_singleton.cc	(revision 6636)
@@ -0,0 +1,56 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: ...
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "proto_singleton.h"
+
+using namespace std;
+
+
+/**
+ * standard constructor
+ */
+ProtoSingleton::ProtoSingleton ()
+{
+   this->setClassID(CL_PROTO_ID, "ProtoSingleton");
+   this->setName("ProtoSingleton");
+
+   /* If you make a new class, what is most probably the case when you write this file
+      don't forget to:
+       1. Add the new file new_class.cc to the ./src/Makefile.am
+       2. Add the class identifier to ./src/class_id.h eg. CL_NEW_CLASS
+   !!!!!!!!!! IMPORTANT FOR SINGLETON !!!!!!!!!!!!!!!!
+        3. SingleTon MUST be CL_NEW_CLASS = 0x00000fxx
+
+      Advanced Topics:
+      - if you want to let your object be managed via the ObjectManager make sure to read
+        the object_manager.h header comments. You will use this most certanly only if you
+        make many objects of your class, like a weapon bullet.
+   */
+}
+
+/**
+ *  the singleton reference to this class
+ */
+ProtoSingleton* ProtoSingleton::singletonRef = NULL;
+
+/**
+   @brief standard deconstructor
+ */
+ProtoSingleton::~ProtoSingleton ()
+{
+  ProtoSingleton::singletonRef = NULL;
+}
Index: branches/network/src/proto/proto_singleton.h
===================================================================
--- branches/network/src/proto/proto_singleton.h	(revision 6636)
+++ branches/network/src/proto/proto_singleton.h	(revision 6636)
@@ -0,0 +1,26 @@
+/*!
+ * @file proto_singleton.h
+ * @brief Definition of the ... singleton Class
+*/
+
+#ifndef _PROTO_SINGLETON_H
+#define _PROTO_SINGLETON_H
+
+#include "base_object.h"
+
+// FORWARD DECLARATION
+
+//! A default singleton class.
+class ProtoSingleton : public BaseObject {
+
+ public:
+  virtual ~ProtoSingleton(void);
+  /** @returns a Pointer to the only object of this Class */
+  inline static ProtoSingleton* getInstance(void) { if (!singletonRef) singletonRef = new ProtoSingleton();  return singletonRef; };
+
+ private:
+  ProtoSingleton(void);
+  static ProtoSingleton* singletonRef;
+};
+
+#endif /* _PROTO_SINGLETON_H */
Index: branches/network/src/proto/proto_world_entity.cc
===================================================================
--- branches/network/src/proto/proto_world_entity.cc	(revision 6636)
+++ branches/network/src/proto/proto_world_entity.cc	(revision 6636)
@@ -0,0 +1,113 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: ...
+   co-programmer: ...
+*/
+
+#include "proto_world_entity.h"
+
+using namespace std;
+
+
+/**
+ * constructs and loads a ProtoWorldEntity from a XML-element
+ * @param root the XML-element to load from
+ */
+ProtoWorldEntity::ProtoWorldEntity(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+
+/**
+ * standard deconstructor
+ */
+ProtoWorldEntity::~ProtoWorldEntity ()
+{
+
+}
+
+
+/**
+ * initializes the ProtoWorldEntity
+ * @todo change this to what you wish
+ */
+void ProtoWorldEntity::init()
+{
+  this->setClassID(CL_PROTO_WORLD_ENTITY, "ProtoWorldEntity");
+
+  /**
+   * @todo: Write CL_PROTO_WORLD_ENTITY INTO THE src/defs/class_id.h (your own definition)
+   */
+
+}
+
+
+/**
+ * loads a ProtoWorldEntity from a XML-element
+ * @param root the XML-element to load from
+ * @todo make the class Loadable
+ */
+void ProtoWorldEntity::loadParams(const TiXmlElement* root)
+{
+  // all the clases this Entity is directly derived from must be called in this way, to load all settings.
+  WorldEntity::loadParam(root);
+
+
+  /**
+   * @todo: make the class Loadable
+   */
+}
+
+
+/**
+ * advances the ProtoWorldEntity about time seconds
+ * @param time the Time to step
+ */
+ProtoWorldEntity::tick(float time)
+{
+
+}
+
+/**
+ * draws this worldEntity
+ */
+void ProtoWorldEntity::draw () const
+{
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  float matrix[4][4];
+
+  /* translate */
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+  /* rotate */
+  this->getAbsDir().matrix(matrix);
+  glMultMatrixf((float*)matrix);
+
+  if (model)
+    model->draw();
+  glPopMatrix();
+}
+
+
+/**
+ *
+ *
+ */
+void ProtoWorldEntity::collidesWith (WorldEntity* entity, const Vector& location)
+{
+
+}
Index: branches/network/src/proto/proto_world_entity.h
===================================================================
--- branches/network/src/proto/proto_world_entity.h	(revision 6636)
+++ branches/network/src/proto/proto_world_entity.h	(revision 6636)
@@ -0,0 +1,34 @@
+/*!
+ * @file proto_world_entity.h
+ * @brief description
+*/
+
+#ifndef _PROTO_WORLD_ENTITY_H
+#define _PROTO_WORLD_ENTITY_H
+
+#include "world_entity.h"
+
+//! A Class to ...
+class ProtoWorldEntity : public WorldEntity
+{
+
+ public:
+  ProtoWorldEntity(const TiXmlElement* root = NULL);
+  virtual ~ProtoWorldEntity();
+
+  virtual void loadParams(const TiXmlElement* root);
+  void init();
+
+  virtual void postSpawn ();
+  virtual void leftWorld ();
+
+
+  virtual void draw() const;
+  virtual void tick(float time);
+  virtual void collidesWith (WorldEntity* entity, const Vector& location);
+
+ private:
+
+};
+
+#endif /* _PROTO_WORLD_ENTITY_H */
Index: branches/network/src/story_entities/Makefile.am
===================================================================
--- branches/network/src/story_entities/Makefile.am	(revision 6636)
+++ branches/network/src/story_entities/Makefile.am	(revision 6636)
@@ -0,0 +1,29 @@
+#MAINSRCDIR=..
+#include $(MAINSRCDIR)/defs/include_paths.am
+
+StoryEntities_SOURCES_ = \
+		story_entities/story_entity.cc \
+		story_entities/campaign.cc \
+		story_entities/campaign_data.cc \
+		story_entities/game_world.cc \
+		story_entities/game_world_data.cc \
+		story_entities/single_player_world.cc \
+		story_entities/single_player_world_data.cc \
+		story_entities/multi_player_world.cc \
+		story_entities/multi_player_world_data.cc \
+		story_entities/movie_loader.cc \
+		story_entities/simple_game_menu.cc
+
+StoryEntities_HEADERS_ = \
+		story_entities/story_entity.h \
+		story_entities/story_def.h \
+		story_entities/campaign.h \
+		story_entities/campaign_data.h \
+		story_entities/game_world.h \
+		story_entities/game_world_data.h \
+		story_entities/single_player_world.h \
+		story_entities/single_player_world_data.h \
+		story_entities/multi_player_world.h \
+		story_entities/multi_player_world_data.h \
+		story_entities/movie_loader.h \
+		story_entities/simple_game_menu.h
Index: branches/network/src/story_entities/campaign.cc
===================================================================
--- branches/network/src/story_entities/campaign.cc	(revision 6636)
+++ branches/network/src/story_entities/campaign.cc	(revision 6636)
@@ -0,0 +1,148 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+
+#include "campaign.h"
+
+#include "factory.h"
+#include "load_param.h"
+
+#include "campaign_data.h"
+
+using namespace std;
+
+
+/**
+ *  the constructor
+ * @param root the XML root element
+ *
+ * this constructor is always called in a XML context (loading procedure)
+ */
+Campaign::Campaign ( TiXmlElement* root)
+{
+  this->setClassID(CL_CAMPAIGN, "Campaign");
+
+  PRINTF(4)("Loading Campaign...\n");
+  assert( root != NULL);
+
+  this->campaignData = new CampaignData(root);
+  this->loadParams(root);
+
+}
+
+
+/**
+ * the campaign destructor
+ */
+Campaign::~Campaign ()
+{
+  if( this->campaignData)
+    delete this->campaignData;
+}
+
+
+/**
+ *  loads the Parameters of a Campaign
+ * @param root: The XML-element to load from
+ */
+void Campaign::loadParams(const TiXmlElement* root)
+{
+  StoryEntity::loadParams(root);
+
+  PRINTF(4)("Loaded Campaign specific stuff\n");
+}
+
+
+/**
+ *  starts the campaing with a specific ID
+ * @param storyID the id of the StoryEntity
+ */
+bool Campaign::start()
+{
+  PRINTF(2)("Starting Campaign nr. %i\n", this->getStoryID());
+
+  this->isRunning = true;
+  this->run();
+}
+
+
+/**
+ *  pauses the campaign
+ */
+bool Campaign::pause()
+{
+  this->isPaused = true;
+}
+
+
+/**
+ *  resumes the campaign after a pause
+ */
+bool Campaign::resume()
+{
+  PRINTF(4)("Resuming the current Campaign\n");
+  this->isPaused = false;
+}
+
+
+/**
+ *  stops the campaign
+ */
+bool Campaign::stop()
+{
+  PRINTF(4)("Stopping the current Campaign\n");
+  this->isRunning = false;
+  if( this->currentEntity != NULL)
+  {
+    this->currentEntity->stop();
+  }
+}
+
+
+/**
+ *  runs the campaign
+ */
+void Campaign::run()
+{
+  ErrorMessage       errorCode;
+  int                storyID = WORLD_ID_0;
+
+  for( this->currentEntity = this->campaignData->getFirstLevel(), this->isRunning = true;
+       this->currentEntity != NULL && this->isRunning;
+       this->currentEntity = this->campaignData->getNextLevel())
+  {
+    PRINTF(0)("Campaign is starting StoryEntity nr:%i\n", this->currentEntity->getStoryID());
+
+    this->currentEntity->init();
+
+    this->currentEntity->loadData();
+    this->currentEntity->start();
+    this->currentEntity->unloadData();
+  }
+  PRINTF(2)("There is no StoryEnity left to play, quitting\n");
+}
+
+
+/**
+ *  this changes to the next level
+ */
+void Campaign::switchToNextLevel()
+{
+  PRINTF(4)("Switching to the next StoryEntity\n");
+  this->currentEntity->stop();
+}
+
+
Index: branches/network/src/story_entities/campaign.h
===================================================================
--- branches/network/src/story_entities/campaign.h	(revision 6636)
+++ branches/network/src/story_entities/campaign.h	(revision 6636)
@@ -0,0 +1,41 @@
+/*!
+ * @file campaign.h
+ * definition of the campaign
+ */
+
+#ifndef _CAMPAIGN_H
+#define _CAMPAIGN_H
+
+
+#include "story_entity.h"
+
+
+class TiXmlElement;
+class CampaignData;
+
+
+//! A class that represents a game Campaign that contains other StoryEntities like GameWorlds, movies, etc.
+class Campaign : public StoryEntity
+{
+
+  public:
+    Campaign( TiXmlElement* root);
+    virtual ~Campaign ();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual bool start();
+    virtual bool stop();
+    virtual bool pause();
+    virtual bool resume();
+    virtual void run();
+
+    void switchToNextLevel();
+
+
+  private:
+    StoryEntity*                        currentEntity;          //!< reference to the current StoryEntity
+    CampaignData*                       campaignData;           //!< reference to the CampaignData
+};
+
+#endif /* _CAMPAIGN_H */
Index: branches/network/src/story_entities/campaign_data.cc
===================================================================
--- branches/network/src/story_entities/campaign_data.cc	(revision 6636)
+++ branches/network/src/story_entities/campaign_data.cc	(revision 6636)
@@ -0,0 +1,141 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+
+#include "campaign_data.h"
+
+#include "factory.h"
+#include "load_param.h"
+
+#include "story_entity.h"
+
+
+using namespace std;
+
+
+/**
+ * constructor for CampaignData
+ */
+CampaignData::CampaignData(const TiXmlElement* root)
+{
+  this->setClassID(CL_CAMPAIGN_DATA, "CampaignData");
+
+  this->currentEntity = NULL;
+
+  this->loadParams(root);
+}
+
+
+/**
+ * destructor for CampaignData
+ */
+CampaignData::~CampaignData()
+{
+  PRINTF(4)("Deleting CampaignData\n");
+  while( !this->storyEntities.empty())
+  {
+    StoryEntity* bo = this->storyEntities.back();
+    this->storyEntities.pop_back();
+    PRINTF(4)("CampaignData is been deleted: nr %i\n", bo->getStoryID());
+    delete bo;
+  }
+}
+
+
+/**
+ *  loads the Parameters of a Campaign
+ * @param root: The XML-element to load from
+ */
+void CampaignData::loadParams(const TiXmlElement* root)
+{
+  LoadParamXML(root, "WorldList", this, CampaignData, loadData)
+      .describe("A List of Worlds to be loaded in this Campaign");
+}
+
+
+/**
+ *  loads a WorldList
+ * @param root: the XML-element to load from
+ */
+void CampaignData::loadData(const TiXmlElement* root)
+{
+  if( root == NULL)
+    return;
+
+  LOAD_PARAM_START_CYCLE(root, element);
+  {
+    StoryEntity* created = dynamic_cast<StoryEntity*>(Factory::fabricate(element));
+    if( created != NULL)
+      this->addStoryEntity(created);
+    PRINTF(4)("Created a new StoryEntity and added it to the Campaign: id=%i\n", created->getStoryID());
+  }
+  LOAD_PARAM_END_CYCLE(element);
+}
+
+
+/**
+ *  add the StoryEntity to the campaign data tank
+ * @param se the StoryEntity to add
+ */
+void CampaignData::addStoryEntity(StoryEntity* se)
+{
+  this->storyEntities.push_back(se);
+}
+
+
+/**
+ *  switch to the next level in the list and return it
+ */
+StoryEntity* CampaignData::getFirstLevel()
+{
+  int                            nextStoryID;
+  int                            storyID;
+  list<StoryEntity*>::iterator   it;
+
+  nextStoryID = 0;
+  this->currentEntity = NULL;
+  for( it = this->storyEntities.begin(); it != this->storyEntities.end(); it++)
+  {
+    storyID = (*it)->getStoryID();
+    if( storyID == nextStoryID)
+      this->currentEntity = (*it);
+  }
+  return this->currentEntity;
+}
+
+
+/**
+ *  switch to the next level in the list and return it
+ */
+StoryEntity* CampaignData::getNextLevel()
+{
+  int                            nextStoryID;
+  int                            storyID;
+  list<StoryEntity*>::iterator   it;
+
+  nextStoryID = this->currentEntity->getNextStoryID();
+  this->currentEntity = NULL;
+  for( it = this->storyEntities.begin(); it != this->storyEntities.end(); it++)
+  {
+    storyID = (*it)->getStoryID();
+    if( storyID == nextStoryID)
+      this->currentEntity = (*it);
+  }
+  return this->currentEntity;
+}
+
+
+
+
+
Index: branches/network/src/story_entities/campaign_data.h
===================================================================
--- branches/network/src/story_entities/campaign_data.h	(revision 6636)
+++ branches/network/src/story_entities/campaign_data.h	(revision 6636)
@@ -0,0 +1,40 @@
+/*!
+ * @file campaign_data.h
+ * definition of the campaign data tank
+ */
+
+#ifndef _CAMPAIGN_DATA_H
+#define _CAMPAIGN_DATA_H
+
+
+#include "data_tank.h"
+#include <list>
+
+class StoryEntity;
+
+//! A class that contains the data of the Campaign object
+class CampaignData : public DataTank
+{
+
+  public:
+    CampaignData(const TiXmlElement* root);
+    virtual ~CampaignData();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    void loadData(const TiXmlElement* root);
+
+    void addStoryEntity(StoryEntity* se);
+
+    StoryEntity* getFirstLevel();
+    StoryEntity* getNextLevel();
+
+
+  private:
+    StoryEntity*                  currentEntity;                //!< reference to the currently used StoryEntity
+    std::list<StoryEntity*>       storyEntities;                //!< list of story entities
+};
+
+
+#endif /* _CAMPAIGN_DATA_H */
+
Index: branches/network/src/story_entities/dedicated_server_world.cc
===================================================================
--- branches/network/src/story_entities/dedicated_server_world.cc	(revision 6636)
+++ branches/network/src/story_entities/dedicated_server_world.cc	(revision 6636)
@@ -0,0 +1,69 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
+
+#include "dedicated_server_world.h"
+
+#include "state.h"
+#include "class_list.h"
+
+#include "load_param.h"
+#include "fast_factory.h"
+#include "factory.h"
+
+#include "world_entity.h"
+#include "npcs/npc_test1.h"
+
+
+using namespace std;
+
+//! This creates a Factory to fabricate a DedicatedServerWorld
+CREATE_FACTORY(DedicatedServerWorld, CL_DEDICATED_SERVER_WORLD);
+
+
+
+DedicatedServerWorld::DedicatedServerWorld(const TiXmlElement* root)
+  : GameWorld(root)
+{
+  this->setClassID(CL_DEDICATED_SERVER_WORLD, "DedicatedServerWorld");
+  this->setName("DedicatedServerWorld uninitialized");
+
+  this->loadParams(root);
+}
+
+
+/**
+ *  remove the DedicatedServerWorld from memory
+ *
+ *  delete everything explicitly, that isn't contained in the parenting tree!
+ *  things contained in the tree are deleted automaticaly
+ */
+DedicatedServerWorld::~DedicatedServerWorld ()
+{
+  PRINTF(3)("DedicatedServerWorld::~DedicatedServerWorld() - deleting current world\n");
+}
+
+
+/**
+ * loads the parameters of a DedicatedServerWorld from an XML-element
+ * @param root the XML-element to load from
+ */
+void DedicatedServerWorld::loadParams(const TiXmlElement* root)
+{
+  GameWorld::loadParams(root);
+
+  PRINTF(4)("Loaded DedicatedServerWorld specific stuff\n");
+}
+
Index: branches/network/src/story_entities/dedicated_server_world.h
===================================================================
--- branches/network/src/story_entities/dedicated_server_world.h	(revision 6636)
+++ branches/network/src/story_entities/dedicated_server_world.h	(revision 6636)
@@ -0,0 +1,33 @@
+/*!
+ * @file dedicated_server_world.h
+ *  Holds and manages all dedicated server data
+ */
+
+#ifndef _DEDICATED_SERVER_WORLD_H
+#define _DEDICATED_SERVER_WORLD_H
+
+#include "game_world.h"
+
+
+class TiXmlElement;
+
+
+//! The game world
+/**
+ *  this class initializes everything that should be displayed inside of the current level.
+ *  it is the main driving factor during gameplay.
+ */
+class DedicatedServerWorld : public GameWorld
+{
+
+  public:
+    DedicatedServerWorld (const TiXmlElement* root = NULL);
+    virtual ~DedicatedServerWorld ();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+  private:
+
+};
+
+#endif /* _DEDICATED_SERVER_WORLD_H */
Index: branches/network/src/story_entities/game_world.cc
===================================================================
--- branches/network/src/story_entities/game_world.cc	(revision 6636)
+++ branches/network/src/story_entities/game_world.cc	(revision 6636)
@@ -0,0 +1,482 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: Christian Meyer
+   co-programmer: Benjamin Grauer
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
+
+#include "game_world.h"
+#include "game_world_data.h"
+
+#include "resource_manager.h"
+#include "state.h"
+#include "class_list.h"
+#include "substring.h"
+
+#include "game_loader.h"
+
+#include "p_node.h"
+#include "world_entity.h"
+#include "player.h"
+#include "camera.h"
+#include "environment.h"
+#include "terrain.h"
+#include "test_entity.h"
+#include "terrain.h"
+#include "md2Model.h"
+#include "world_entities/projectiles/projectile.h"
+#include "npcs/npc_test1.h"
+#include "playable.h"
+
+#include "light.h"
+
+#include "factory.h"
+#include "fast_factory.h"
+#include "load_param.h"
+#include "shell_command.h"
+
+#include "graphics_engine.h"
+#include "event_handler.h"
+#include "sound_engine.h"
+#include "cd_engine.h"
+#include "network_manager.h"
+#include "physics_engine.h"
+#include "fields.h"
+
+#include "glmenu_imagescreen.h"
+#include "shell.h"
+
+#include "animation_player.h"
+#include "animation3d.h"
+
+#include "ogg_player.h"
+#include "shader.h"
+
+
+using namespace std;
+
+
+SHELL_COMMAND(speed, GameWorld, setSpeed);
+SHELL_COMMAND(togglePNodeVisibility, GameWorld, togglePNodeVisibility);
+SHELL_COMMAND(toggleBVVisibility, GameWorld, toggleBVVisibility);
+
+
+
+GameWorld::GameWorld(const TiXmlElement* root)
+    : StoryEntity()
+{
+  this->setClassID(CL_GAME_WORLD, "GameWorld");
+  this->setName("Preloaded World - no name yet");
+
+  this->gameTime = 0.0f;
+  this->setSpeed(1.0f);
+  this->shell = NULL;
+
+  this->showPNodes = false;
+  this->showBV = false;
+
+  this->path = NULL;
+}
+
+/**
+ *  remove the GameWorld from memory
+ *
+ *  delete everything explicitly, that isn't contained in the parenting tree!
+ *  things contained in the tree are deleted automaticaly
+ */
+GameWorld::~GameWorld ()
+{
+  PRINTF(4)("Deleted GameWorld\n");
+}
+
+
+
+/**
+ * loads the parameters of a GameWorld from an XML-element
+ * @param root the XML-element to load from
+ */
+void GameWorld::loadParams(const TiXmlElement* root)
+{
+  StoryEntity::loadParams(root);
+
+  LoadParam(root, "path", this, GameWorld, setPath)
+  .describe("The Filename of this GameWorld (relative from the data-dir)");
+
+//   LoadParam(root, "soundtrack", this->dataTank, GameWorldData, setSoundTrack);
+
+  PRINTF(4)("Loaded GameWorld specific stuff\n");
+}
+
+
+/**
+ * this is executed just before load
+ *
+ * since the load function sometimes needs data, that has been initialized
+ * before the load and after the proceeding storyentity has finished
+*/
+ErrorMessage GameWorld::init()
+{
+  this->cycle = 0;
+  /* init the world interface */
+  this->shell = new Shell();
+
+  State::setCurrentStoryEntity(dynamic_cast<StoryEntity*>(this));
+  this->dataTank->init();
+}
+
+
+/**
+ *  loads the GameWorld by initializing all resources, and set their default values.
+ */
+ErrorMessage GameWorld::loadData()
+{
+  this->displayLoadScreen();
+
+  PRINTF(0)("Loading the GameWorld\n");
+
+  PRINTF(3)("> Loading world: '%s'\n", getPath());
+  TiXmlElement* element;
+  GameLoader* loader = GameLoader::getInstance();
+
+  if( getPath() == NULL)
+  {
+    PRINTF(1)("GameWorld has no path specified for loading\n");
+    return (ErrorMessage){213,"Path not specified","GameWorld::load()"};
+  }
+
+  TiXmlDocument* XMLDoc = new TiXmlDocument( getPath());
+  // load the xml world file for further loading
+  if( !XMLDoc->LoadFile())
+  {
+    PRINTF(1)("loading XML File: %s @ %s:l%d:c%d\n", XMLDoc->ErrorDesc(), this->getPath(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
+    delete XMLDoc;
+    return (ErrorMessage){213,"XML File parsing error","GameWorld::load()"};
+  }
+  // check basic validity
+  TiXmlElement* root = XMLDoc->RootElement();
+  assert( root != NULL);
+  if( root == NULL || root->Value() == NULL || strcmp( root->Value(), "WorldDataFile"))
+  {
+    // report an error
+    PRINTF(1)("Specified XML File is not an orxonox world data file (WorldDataFile element missing)\n");
+    delete XMLDoc;
+    return (ErrorMessage){213,"Path not a WorldDataFile","GameWorld::load()"};
+  }
+  /* the whole loading process for the GameWorld */
+  this->dataTank->loadData(root);
+
+  delete XMLDoc;
+  this->releaseLoadScreen();
+}
+
+
+/**
+ *  unload the data of this GameWorld
+ */
+ErrorMessage GameWorld::unloadData()
+{
+  delete this->shell;
+  PRINTF(3)("GameWorld::~GameWorld() - unloading the current GameWorld\n");
+
+  this->dataTank->unloadData();
+}
+
+
+/**
+ *  starts the GameWorld
+ */
+bool GameWorld::start()
+{
+  this->isPaused = false;
+  this->isRunning = true;
+
+  this->run();
+}
+
+
+/**
+ *  stops the world.
+ */
+bool GameWorld::stop()
+{
+  PRINTF(3)("GameWorld::stop() - got stop signal\n");
+  this->isRunning = false;
+}
+
+
+/**
+ *  pauses the game
+ */
+bool GameWorld::pause()
+{
+  this->isPaused = true;
+}
+
+
+/**
+ *  ends the pause Phase
+ */
+bool GameWorld::resume()
+{
+  this->isPaused = false;
+}
+
+
+/**
+ *  main loop of the world: executing all world relevant function
+ *
+ * in this loop we synchronize (if networked), handle input events, give the heart-beat to
+ * all other member-entities of the world (tick to player, enemies etc.), checking for
+ * collisions drawing everything to the screen.
+ */
+void GameWorld::run()
+{
+  /* start the music */
+  if(this->dataTank->music != NULL)
+    this->dataTank->music->playback();
+
+  this->lastFrame = SDL_GetTicks ();
+  PRINTF(3)("GameWorld::mainLoop() - Entering main loop\n");
+
+  while( this->isRunning) /* @todo implement pause */
+  {
+    ++this->cycle;
+    /* process intput */
+    this->handleInput ();
+    if( !this->isRunning)
+      break;
+
+    /* network synchronisation */
+    this->synchronize ();
+    /* process time */
+    this->tick ();
+    /* process collision */
+    this->collide ();
+    /* update the state */
+    this->update ();
+    /* draw everything */
+    this->display ();
+  }
+
+  PRINTF(3)("GameWorld::mainLoop() - Exiting the main loop\n");
+}
+
+
+/**
+ *  synchronize local data with remote data
+*/
+void GameWorld::synchronize ()
+{}
+
+
+/**
+ *  run all input processing
+
+   the command node is the central input event dispatcher. the node uses the even-queue from
+   sdl and has its own event-passing-queue.
+*/
+void GameWorld::handleInput ()
+{
+  EventHandler::getInstance()->process();
+}
+
+
+/**
+ *  ticks a WorldEntity list
+ * @param entityList list of the WorldEntities
+ * @param dt time passed since last frame
+ */
+void GameWorld::tick(std::list<WorldEntity*> entityList, float dt)
+{
+  std::list<WorldEntity*>::iterator entity;
+  for (entity = entityList.begin(); entity != entityList.end(); entity++)
+    (*entity)->tick(dt);
+
+}
+
+/**
+ *  advance the timeline
+ *
+ * this calculates the time used to process one frame (with all input handling, drawing, etc)
+ * the time is mesured in ms and passed to all world-entities and other classes that need
+ * a heart-beat.
+ */
+void GameWorld::tick ()
+{
+  Uint32 currentFrame = SDL_GetTicks();
+
+  if( !this->isPaused)
+  {
+    this->dt = currentFrame - this->lastFrame;
+
+    /* limit the the frame rate to 100 frames per second (fps) */
+    if( this->dt < 10)
+    {
+      /* the frame-rate is limited to 100 frames per second, all other things are for nothing. */
+      //PRINTF(0)("fps = 1000 - frame rate is adjusted\n");
+      SDL_Delay(10 - dt);
+      this->dt = 10;
+    }
+
+    this->dtS = (float)this->dt / 1000.0f * this->speed;
+    this->gameTime += this->dtS;
+
+    this->tick(this->dataTank->objectManager->getObjectList(OM_DEAD_TICK), this->dtS);
+    this->tick(this->dataTank->objectManager->getObjectList(OM_ENVIRON), this->dtS);
+    this->tick(this->dataTank->objectManager->getObjectList(OM_COMMON), this->dtS);
+    this->tick(this->dataTank->objectManager->getObjectList(OM_GROUP_00), this->dtS);
+    this->tick(this->dataTank->objectManager->getObjectList(OM_GROUP_00_PROJ), this->dtS);
+    this->tick(this->dataTank->objectManager->getObjectList(OM_GROUP_01), this->dtS);
+    this->tick(this->dataTank->objectManager->getObjectList(OM_GROUP_01_PROJ), this->dtS);
+
+    /* update tick the rest */
+    this->dataTank->localCamera->tick(this->dtS);
+    AnimationPlayer::getInstance()->tick(this->dtS);
+    PhysicsEngine::getInstance()->tick(this->dtS);
+
+    GraphicsEngine::getInstance()->tick(this->dtS);
+  }
+  this->lastFrame = currentFrame;
+}
+
+
+/**
+ *  this function gives the world a consistant state
+ *
+ * after ticking (updating the world state) this will give a constistant
+ * state to the whole system.
+ */
+void GameWorld::update()
+{
+  GraphicsEngine::getInstance()->update(this->dtS);
+  PNode::getNullParent()->updateNode (this->dtS);
+  SoundEngine::getInstance()->update();
+  //music->update();
+}
+
+
+/**
+ * kicks the CDEngine to detect the collisions between the object groups in the world
+ */
+void GameWorld::collide()
+{
+  CDEngine::getInstance()->checkCollisions(this->dataTank->objectManager->getObjectList(OM_GROUP_00),
+  this->dataTank->objectManager->getObjectList(OM_GROUP_01_PROJ));
+  CDEngine::getInstance()->checkCollisions(this->dataTank->objectManager->getObjectList(OM_GROUP_01),
+  this->dataTank->objectManager->getObjectList(OM_GROUP_00_PROJ));
+
+  CDEngine::getInstance()->checkCollisions(this->dataTank->objectManager->getObjectList(OM_GROUP_01),
+      this->dataTank->objectManager->getObjectList(OM_COMMON));
+}
+
+/**
+ *  render the current frame
+ *
+ * clear all buffers and draw the world
+ */
+void GameWorld::display ()
+{
+  // clear buffer
+  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+  // set camera
+  this->dataTank->localCamera->apply ();
+  // draw world
+  this->draw();
+  // flip buffers
+  GraphicsEngine::swapBuffers();
+}
+
+
+/**
+ *  runs through all entities calling their draw() methods
+ */
+void GameWorld::draw ()
+{
+  GraphicsEngine* engine = GraphicsEngine::getInstance();
+
+   /* to draw the bounding boxes of the objects at level 2 for debug purp */
+
+  /* debug draw the PNodes */
+
+  /* draw all WorldEntiy groups */
+  engine->draw(State::getObjectManager()->getObjectList(OM_ENVIRON_NOTICK));
+  engine->draw(State::getObjectManager()->getObjectList(OM_ENVIRON));
+  engine->draw(State::getObjectManager()->getObjectList(OM_COMMON));
+  engine->draw(State::getObjectManager()->getObjectList(OM_GROUP_00));
+  engine->draw(State::getObjectManager()->getObjectList(OM_GROUP_00_PROJ));
+  engine->draw(State::getObjectManager()->getObjectList(OM_GROUP_01));
+  engine->draw(State::getObjectManager()->getObjectList(OM_GROUP_01_PROJ));
+
+  if( unlikely( this->showBV))
+  {
+    CDEngine* engine = CDEngine::getInstance();
+    engine->drawBV(State::getObjectManager()->getObjectList(OM_ENVIRON_NOTICK));
+    engine->drawBV(State::getObjectManager()->getObjectList(OM_ENVIRON));
+    engine->drawBV(State::getObjectManager()->getObjectList(OM_COMMON));
+    engine->drawBV(State::getObjectManager()->getObjectList(OM_GROUP_00));
+    engine->drawBV(State::getObjectManager()->getObjectList(OM_GROUP_01));
+    engine->drawBV(State::getObjectManager()->getObjectList(OM_GROUP_01_PROJ));
+  }
+
+  if( unlikely(this->showPNodes))
+    PNode::getNullParent()->debugDraw(0);
+
+  /* final draw command */
+  engine->draw();
+}
+
+
+/**
+ *  sets the track path of this world
+ * @param name the name of the path
+ */
+void GameWorld::setPath( const char* name)
+{
+  if (this->path)
+    delete this->path;
+  if (ResourceManager::isFile(name))
+  {
+    this->path = new char[strlen(name)+1];
+    strcpy(this->path, name);
+  }
+  else
+  {
+    this->path = new char[strlen(ResourceManager::getInstance()->getDataDir()) + strlen(name) +1];
+    sprintf(this->path, "%s%s", ResourceManager::getInstance()->getDataDir(), name);
+  }
+}
+
+
+/**
+ *  shows the loading screen
+ */
+void GameWorld::displayLoadScreen ()
+{
+  PRINTF(3)("GameWorld::displayLoadScreen - start\n");
+  this->dataTank->glmis = new GLMenuImageScreen();
+  this->dataTank->glmis->setMaximum(8);
+  PRINTF(3)("GameWorld::displayLoadScreen - end\n");
+}
+
+
+/**
+ *  removes the loadscreen, and changes over to the game
+ */
+void GameWorld::releaseLoadScreen ()
+{
+  PRINTF(3)("GameWorld::releaseLoadScreen - start\n");
+  this->dataTank->glmis->setValue(this->dataTank->glmis->getMaximum());
+  PRINTF(3)("GameWorld::releaseLoadScreen - end\n");
+}
+
Index: branches/network/src/story_entities/game_world.h
===================================================================
--- branches/network/src/story_entities/game_world.h	(revision 6636)
+++ branches/network/src/story_entities/game_world.h	(revision 6636)
@@ -0,0 +1,97 @@
+/*!
+ * @file game_world.h
+ *  container for all game worlds (singleplayers, multiplayers..)
+ */
+
+#ifndef _GAME_WORLD_H
+#define _GAME_WORLD_H
+
+
+#include "story_entity.h"
+#include "game_world_data.h"
+
+class TiXmlElement;
+class Shell;
+class WorldEntity;
+class GameWorldData;
+
+
+//! The game world
+/**
+ *  this class initializes everything that should be displayed inside of the current level.
+ *  it is the main driving factor during gameplay.
+ */
+class GameWorld : public StoryEntity
+{
+
+  public:
+    GameWorld (const TiXmlElement* root = NULL);
+    virtual ~GameWorld ();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    /* functions from story-entity */
+    virtual ErrorMessage init();
+    virtual ErrorMessage loadData();
+    virtual ErrorMessage unloadData();
+
+    virtual bool start();
+    virtual bool stop();
+    virtual bool pause();
+    virtual bool resume();
+    virtual void run();
+
+    /**  this returns the current game time @returns elapsed game time     */
+    inline double getGameTime() { return this->gameTime; }
+    /** sets the game speed @param speed speed of the Game */
+    inline void setSpeed(float speed) { this->speed = speed; };
+    /**  returns the track path of this world @returns the track path */
+    const char* getPath() { return this->path; }
+    void setPath( const char* name);
+
+    /** toggles the PNode visibility in the world (drawn as boxes) */
+    void togglePNodeVisibility() { this->showPNodes = !this->showPNodes; };
+    /** toggles the bounding volume (BV) visibility */
+    void toggleBVVisibility() { this->showBV = !this->showBV; };
+
+
+    inline void setSky(WorldEntity* sky) { this->dataTank->sky = sky; }
+
+
+  protected:
+    /* world - running functions */
+    virtual void synchronize();
+    virtual void handleInput();
+    virtual void tick(std::list<WorldEntity*> worldEntity, float dt);
+    virtual void tick();
+    virtual void update();
+    virtual void collide();
+    virtual void draw();
+    virtual void display();
+
+
+  private:
+    void displayLoadScreen();
+    void releaseLoadScreen();
+
+
+  protected:
+    GameWorldData*      dataTank;                     //!< reference to the GameWorld Data Tank
+    char*               path;                         //!< The file from which this world is loaded
+
+    bool                showPNodes;                   //!< if the PNodes should be visible.
+    bool                showBV;                       //!< if the Bounding Volumes should be visible.
+
+    /* world timing */
+    Uint32              lastFrame;                    //!< last time of frame
+    Uint32              cycle;                        //!< The cycle we are in (starts with 0 and rises with every frame)
+    Uint32              dt;                           //!< time needed to calculate this frame (in milliSeconds)
+    float               dtS;                          //!< The time needed for caluculations in seconds
+    float               speed;                        //!< how fast the game flows
+    double              gameTime;                     //!< this is where the game time is saved
+
+    /* external modules interfaces */
+    Shell*              shell;
+};
+
+#endif /* _GAME_WORLD_H */
Index: branches/network/src/story_entities/game_world_data.cc
===================================================================
--- branches/network/src/story_entities/game_world_data.cc	(revision 6636)
+++ branches/network/src/story_entities/game_world_data.cc	(revision 6636)
@@ -0,0 +1,311 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
+
+#include "game_world_data.h"
+
+#include "resource_manager.h"
+#include "state.h"
+#include "class_list.h"
+#include "substring.h"
+
+#include "game_loader.h"
+
+#include "p_node.h"
+#include "world_entity.h"
+#include "player.h"
+#include "camera.h"
+#include "environment.h"
+#include "terrain.h"
+#include "test_entity.h"
+#include "terrain.h"
+#include "md2Model.h"
+#include "world_entities/projectiles/projectile.h"
+#include "npcs/npc_test1.h"
+#include "playable.h"
+
+#include "light.h"
+
+#include "factory.h"
+#include "fast_factory.h"
+#include "load_param.h"
+
+#include "graphics_engine.h"
+#include "event_handler.h"
+#include "sound_engine.h"
+#include "cd_engine.h"
+#include "network_manager.h"
+#include "physics_engine.h"
+#include "fields.h"
+
+#include "glmenu_imagescreen.h"
+
+#include "animation_player.h"
+#include "animation3d.h"
+
+#include "ogg_player.h"
+#include "shader.h"
+
+
+
+using namespace std;
+
+
+/**
+ * constructor of the GameWorldData
+ */
+GameWorldData::GameWorldData()
+{
+  this->setClassID(CL_GAME_WORLD_DATA, "GameWorldData");
+
+  this->glmis = NULL;
+
+  this->localCamera = NULL;
+  this->localPlayer = NULL;
+  this->sky = NULL;
+  this->terrain = NULL;
+
+  this->music = NULL;
+  this->objectManager = NULL;
+}
+
+
+/**
+ * destructor for the GameWorldData
+ */
+GameWorldData::~GameWorldData()
+{}
+
+
+
+/**
+ *  initialize the GameWorldData
+ */
+ErrorMessage GameWorldData::init()
+{
+  this->objectManager = new ObjectManager();
+  State::setObjectManager(this->objectManager);
+
+  PNode::getNullParent();
+  this->localCamera = new Camera();
+  this->localCamera->setName ("GameWorld-Camera");
+  State::setCamera(this->localCamera, this->localCamera->getTarget());
+
+  LightManager::getInstance();
+
+  GraphicsEngine::getInstance()->displayFPS(true);
+
+  /* initialize some graphics engines and graphical elements */
+  AnimationPlayer::getInstance();
+  PhysicsEngine::getInstance();
+}
+
+
+/**
+ *  loads the data from the xml file
+ * @param root reference to the xml root element
+ */
+ErrorMessage GameWorldData::loadData(TiXmlElement* root)
+{
+  // load the parameters
+  // name
+  const char* string = grabParameter( root, "name");
+  if( string == NULL)
+  {
+    PRINTF(2)("GameWorld is missing a proper 'name'\n");
+    this->setName("Unknown");
+  }
+  else
+    this->setName(string);
+
+  this->loadGUI(root);
+  this->loadWorldEntities(root);
+  this->loadScene(root);
+}
+
+
+/**
+ *  unloads the data from the xml file
+ */
+ErrorMessage GameWorldData::unloadData()
+{
+  this->unloadGUI();
+  this->unloadWorldEntities();
+  this->unloadScene();
+}
+
+
+/**
+ *  loads the GUI data
+ * @param root reference to the xml root element
+ */
+ErrorMessage GameWorldData::loadGUI(TiXmlElement* root)
+{
+  TiXmlElement* element = root->FirstChildElement("LoadScreen");
+  if( element == NULL)
+  {
+    PRINTF(2)("no LoadScreen specified, loading default\n");
+
+    glmis->setBackgroundImage("pictures/load_screen.jpg");
+    this->glmis->setMaximum(8);
+//     this->glmis->draw();
+  }
+  else
+  {
+    this->glmis->loadParams(element);
+//     this->glmis->draw();
+  }
+  this->glmis->draw();
+}
+
+
+/**
+ *  unloads the GUI data
+ */
+ErrorMessage GameWorldData::unloadGUI()
+{
+  delete this->glmis;
+}
+
+
+/**
+ *  loads the world entities from the xml file
+ * @param root reference to the xml root parameter
+ */
+ErrorMessage GameWorldData::loadWorldEntities(TiXmlElement* root)
+{
+  TiXmlElement* element = root->FirstChildElement("WorldEntities");
+
+  if( element == NULL)
+  {
+    PRINTF(1)("GameWorld is missing 'WorldEntities'\n");
+  }
+  else
+  {
+    element = element->FirstChildElement();
+    // load Players/Objects/Whatever
+    PRINTF(4)("Loading WorldEntities\n");
+    while( element != NULL)
+    {
+      BaseObject* created = Factory::fabricate(element);
+      if( created != NULL )
+        printf("Created a %s: %s\n", created->getClassName(), created->getName());
+
+      //todo do this more elegant
+      if( element->Value() != NULL && !strcmp( element->Value(), "SkyBox"))
+        this->sky = dynamic_cast<WorldEntity*>(created);
+      if( element->Value() != NULL && !strcmp( element->Value(), "Terrain"))
+      {
+        this->terrain = dynamic_cast<Terrain*>(created);
+        CDEngine::getInstance()->setTerrain(terrain);
+      }
+      element = element->NextSiblingElement();
+      this->glmis->step(); //! @todo temporary
+    }
+    PRINTF(4)("Done loading WorldEntities\n");
+  }
+
+  // Create a Player
+  this->localPlayer = new Player();
+
+  Playable* playable;
+  const list<BaseObject*>* playableList = ClassList::getList(CL_PLAYABLE);
+  if (playableList != NULL)
+  {
+    playable = dynamic_cast<Playable*>(playableList->front());
+    this->localPlayer->setControllable(playable);
+  }
+
+  /* init the pnode tree */
+  PNode::getNullParent()->init();
+}
+
+
+/**
+ *  unloads the world entities
+ */
+ErrorMessage GameWorldData::unloadWorldEntities()
+{
+  FastFactory::flushAll(true);
+
+  // erease everything that is left.
+  // delete PNode::getNullParent(); // not needed as this is also done in the next step (and also much cleaner)
+
+  //secondary cleanup of PNodes;
+  const std::list<BaseObject*>* nodeList = ClassList::getList(CL_PARENT_NODE);
+  if (nodeList != NULL)
+    while (!nodeList->empty())
+      delete nodeList->front();
+
+  /* remove the player object */
+  if( this->localPlayer)
+    delete this->localPlayer;
+
+  // unload the resources !!
+  ResourceManager::getInstance()->unloadAllByPriority(RP_LEVEL);
+
+  if (State::getObjectManager() == this->objectManager)
+  {
+    State::setObjectManager(NULL);
+    delete this->objectManager;
+  }
+}
+
+
+/**
+ *  loads the scene data
+ * @param root reference to the xml root element
+ */
+ErrorMessage GameWorldData::loadScene(TiXmlElement* root)
+{
+  LoadParamXML(root, "LightManager", LightManager::getInstance(), LightManager, loadParams);
+
+//  LoadParamXML(root, "ParticleEngine", ParticleEngine::getInstance(), ParticleEngine, loadParams);
+  //LoadParamXML(root, "PhysicsEngine", PhysicsEngine::getInstance(), PhysicsEngine, loadParams);
+
+  this->localCamera->setClipRegion(1, 10000.0);
+  if( this->sky != NULL)
+    this->localCamera->addChild(this->sky);
+  SoundEngine::getInstance()->setListener(this->localCamera);
+}
+
+
+/**
+ *  unloads the scene data
+ */
+ErrorMessage GameWorldData::unloadScene()
+{
+  /* delete some garphics and scene eingines */
+  delete LightManager::getInstance();
+  delete AnimationPlayer::getInstance();
+  delete PhysicsEngine::getInstance();
+
+  /* stop the sound eninge */
+  SoundEngine::getInstance()->flushAllBuffers();
+  SoundEngine::getInstance()->flushAllSources();
+
+  /* unload the shaders */
+  Shader::suspendShader();
+}
+
+
+void GameWorldData::setSoundTrack(const char* name)
+{
+  PRINTF(3)("Setting Sound Track to %s\n", name);
+  this->music = (OggPlayer*)ResourceManager::getInstance()->load(name, OGG, RP_LEVEL);
+}
+
+
Index: branches/network/src/story_entities/game_world_data.h
===================================================================
--- branches/network/src/story_entities/game_world_data.h	(revision 6636)
+++ branches/network/src/story_entities/game_world_data.h	(revision 6636)
@@ -0,0 +1,68 @@
+/*!
+ * @file game_world_data.h
+ *  container for all game world data
+ */
+
+#ifndef _GAME_WORLD_DATA_H
+#define _GAME_WORLD_DATA_H
+
+#include "sdlincl.h"
+#include "data_tank.h"
+#include "error.h"
+
+
+class Camera;
+class Player;
+class Terrain;
+class WorldEntity;
+class ObjectManager;
+
+class GLMenuImageScreen;
+
+class TiXmlElement;
+class OggPlayer;
+
+
+//! The game world data
+/**
+ * this class is a containter for the data of the GameWorld. It just loads and unloads it
+ * the game start/stop process is not contained here and can be found in the GameWorld class.
+ */
+class GameWorldData : public DataTank
+{
+
+  public:
+    GameWorldData();
+    virtual ~GameWorldData();
+
+    virtual ErrorMessage init();
+    virtual ErrorMessage loadData(TiXmlElement* root);
+    virtual ErrorMessage unloadData();
+
+    /* interface functions */
+    void setSoundTrack(const char* name);
+
+  protected:
+    virtual ErrorMessage loadGUI(TiXmlElement* root);
+    virtual ErrorMessage loadWorldEntities(TiXmlElement* root);
+    virtual ErrorMessage loadScene(TiXmlElement* root);
+
+    virtual ErrorMessage unloadGUI();
+    virtual ErrorMessage unloadWorldEntities();
+    virtual ErrorMessage unloadScene();
+
+
+  public:
+    GLMenuImageScreen*  glmis;                       //!< The Level-Loader Display
+
+    Camera*             localCamera;                 //!< The current camera
+    Player*             localPlayer;                 //!< The player, you fly through the level.
+    WorldEntity*        sky;                         //!< The environmental sky of orxonox
+    Terrain*            terrain;                     //!< The terrain - ground
+
+    OggPlayer*          music;                       //!< Reference to the SoundEngine's music player (OggPlayer)
+    ObjectManager*      objectManager;               //!< Reference to the objects manager
+};
+
+#endif /* _GAME_WORLD_DATA_H */
+
Index: branches/network/src/story_entities/movie_loader.cc
===================================================================
--- branches/network/src/story_entities/movie_loader.cc	(revision 6636)
+++ branches/network/src/story_entities/movie_loader.cc	(revision 6636)
@@ -0,0 +1,151 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: David Hasenfratz, Stefan Lienhard
+   co-programmer:
+*/
+
+#include "movie_loader.h"
+
+#include "movie_player.h"
+#include "factory.h"
+#include "graphics_engine.h"
+#include "load_param.h"
+#include "resource_manager.h"
+
+
+using namespace std;
+
+CREATE_FACTORY(MovieLoader, CL_MOVIE_LOADER);
+
+MovieLoader::MovieLoader(const TiXmlElement* root)
+{
+  this->setClassID(CL_MOVIE_LOADER, "MovieLoader");
+
+  movie_player = new MoviePlayer();
+  this->loadParams(root);
+}
+
+MovieLoader::~MovieLoader()
+{
+  PRINTF(4)("Deleted MoviePlayer\n");
+}
+
+
+
+void MovieLoader::loadParams(const TiXmlElement* root)
+{
+  StoryEntity::loadParams(root);
+
+  LoadParam(root, "name", this, MovieLoader, loadMovie);
+}
+
+void MovieLoader::loadMovie(const char* filename)
+{
+  movie_player->loadMovie(filename);
+
+  PRINTF(0)("\nloaded Movie %s\n\n", filename);
+}
+
+
+ErrorMessage MovieLoader::init()
+{
+
+}
+
+
+ErrorMessage MovieLoader::loadData()
+{
+
+}
+
+
+ErrorMessage MovieLoader::unloadData()
+{
+
+}
+
+bool MovieLoader::start()
+{
+  PRINTF(0)("\nMovieLoader INFO:\n");
+  movie_player->printInformation();
+  PRINTF(0)("\n");
+
+  this->isRunning = true;
+
+  this->run();
+}
+
+bool MovieLoader::stop()
+{
+  this->isRunning = false;
+}
+
+bool MovieLoader::pause() { }
+bool MovieLoader::resume() { }
+
+void MovieLoader::run()
+{
+  // first timestamp for t = 0
+  this->lastFrame = SDL_GetTicks ();
+  this->movie_player->start(0);
+
+  while( this->isRunning)
+  {
+
+    this->tick();
+    this->draw();
+
+  }
+}
+
+void MovieLoader::draw() const
+{
+  glClear( GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
+
+
+  GraphicsEngine::enter2DMode();
+
+  glEnable(GL_TEXTURE_2D);
+  glBindTexture(GL_TEXTURE_2D, movie_player->getTexture());
+
+  glColor3f(1.0, 1.0, 1.0);
+
+  glBegin(GL_QUADS);
+    glTexCoord2f(1.0f, 0.0f); glVertex2f( 0, 0);
+    glTexCoord2f(1.0f, 1.0f); glVertex2f( 0, 100);
+    glTexCoord2f(0.0f, 1.0f); glVertex2f( 100, 100);
+    glTexCoord2f(0.0f, 0.0f); glVertex2f( 100, 0);
+  glEnd();
+
+  GraphicsEngine::leave2DMode();
+
+  SDL_GL_SwapBuffers();
+}
+
+
+void MovieLoader::tick()
+{
+  // get timestamp
+  currentFrame = SDL_GetTicks();
+
+  // calculate time difference in milliseconds (Uint32)
+  this->dt = currentFrame - this->lastFrame;
+  // calculate time difference in seconds (float)
+  this->dts = (float)this->dt / 1000.0f;
+
+  movie_player->tick(dts);
+
+  if (movie_player->getStatus() == STOP)
+    this->isRunning = false;
+
+  this->lastFrame = currentFrame;
+}
Index: branches/network/src/story_entities/movie_loader.h
===================================================================
--- branches/network/src/story_entities/movie_loader.h	(revision 6636)
+++ branches/network/src/story_entities/movie_loader.h	(revision 6636)
@@ -0,0 +1,48 @@
+/*!
+ * @file movie_loader.h
+ *  loads a movie
+ */
+
+#ifndef _MOVIE_LOADER_H
+#define _MOVIE_LOADER_H
+
+
+#include "story_entity.h"
+
+class MoviePlayer;
+
+class MovieLoader : public StoryEntity
+{
+  private:
+    MoviePlayer* movie_player;
+
+    Uint32              lastFrame;
+    Uint32              currentFrame;
+    Uint32              dt;                           // time needed to calculate this frame (in milliSeconds)
+    float               dts;
+
+  public:
+    MovieLoader(const TiXmlElement* root);
+    virtual ~MovieLoader();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    /* functions from story-entity */
+    virtual ErrorMessage init();
+    virtual ErrorMessage loadData();
+    virtual ErrorMessage unloadData();
+
+    virtual bool start();
+    virtual bool stop();
+    virtual bool pause();
+    virtual bool resume();
+    virtual void run();
+
+  private:
+    void loadMovie(const char* filename);
+    void tick();
+    void draw() const;
+
+};
+
+#endif /* _MOVIE_LOADER_H */
Index: branches/network/src/story_entities/multi_player_world.cc
===================================================================
--- branches/network/src/story_entities/multi_player_world.cc	(revision 6636)
+++ branches/network/src/story_entities/multi_player_world.cc	(revision 6636)
@@ -0,0 +1,93 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
+
+
+#include "multi_player_world.h"
+#include "multi_player_world_data.h"
+
+#include "factory.h"
+#include "load_param.h"
+#include "shell_command.h"
+
+#include "network_manager.h"
+
+
+using namespace std;
+
+
+//! Register a command to print some multiplayer world infos
+SHELL_COMMAND(debug, MultiPlayerWorld, debug);
+
+
+//! This creates a Factory to fabricate a MultiPlayerWorld
+CREATE_FACTORY(MultiPlayerWorld, CL_MULTI_PLAYER_WORLD);
+
+
+MultiPlayerWorld::MultiPlayerWorld(const TiXmlElement* root)
+  : GameWorld(root)
+{
+  this->setClassID(CL_MULTI_PLAYER_WORLD, "MultiPlayerWorld");
+
+  this->dataTank = new MultiPlayerWorldData();
+
+  this->loadParams(root);
+}
+
+
+/**
+ *  remove the MultiPlayerWorld from memory
+ *
+ *  delete everything explicitly, that isn't contained in the parenting tree!
+ *  things contained in the tree are deleted automaticaly
+ */
+MultiPlayerWorld::~MultiPlayerWorld ()
+{
+  PRINTF(3)("MultiPlayerWorld::~MultiPlayerWorld() - deleting current world\n");
+  if( this->dataTank)
+    delete this->dataTank;
+}
+
+
+/**
+ * loads the parameters of a MultiPlayerWorld from an XML-element
+ * @param root the XML-element to load from
+ */
+void MultiPlayerWorld::loadParams(const TiXmlElement* root)
+{
+  GameWorld::loadParams(root);
+
+  PRINTF(4)("Creating a MultiPlayerWorld\n");
+}
+
+
+/**
+ *  synchronizes the network since this is a network world
+ *
+ * this function overrides the synchrinize from the GameWorld
+ */
+void MultiPlayerWorld::synchronize()
+{
+  NetworkManager::getInstance()->synchronize();
+}
+
+
+/**
+ * some debug ouptut - shell command
+ */
+void MultiPlayerWorld::debug()
+{
+  ((MultiPlayerWorldData*)this->dataTank)->debug();
+}
Index: branches/network/src/story_entities/multi_player_world.h
===================================================================
--- branches/network/src/story_entities/multi_player_world.h	(revision 6636)
+++ branches/network/src/story_entities/multi_player_world.h	(revision 6636)
@@ -0,0 +1,35 @@
+/*!
+ * @file multi_player_world.h
+  *  Holds and manages all game data
+*/
+
+#ifndef _MULTI_PLAYER_WORLD_H
+#define _MULTI_PLAYER_WORLD_H
+
+#include "game_world.h"
+
+
+class TiXmlElement;
+class MultiPlayerWorldData;
+
+
+//! The multiplayer game world
+/**
+ *  this class initializes everything that should be displayed inside of the current level.
+ *  it is the main driving factor during gameplay.
+ */
+class MultiPlayerWorld : public GameWorld {
+
+ public:
+  MultiPlayerWorld (const TiXmlElement* root = NULL);
+  virtual ~MultiPlayerWorld ();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void debug();
+
+  protected:
+    virtual void synchronize();
+};
+
+#endif /* _MULTI_PLAYER_WORLD_H */
Index: branches/network/src/story_entities/multi_player_world_data.cc
===================================================================
--- branches/network/src/story_entities/multi_player_world_data.cc	(revision 6636)
+++ branches/network/src/story_entities/multi_player_world_data.cc	(revision 6636)
@@ -0,0 +1,292 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
+
+
+#include "multi_player_world_data.h"
+
+#include "resource_manager.h"
+#include "state.h"
+#include "class_list.h"
+#include "substring.h"
+
+#include "game_loader.h"
+#include "cd_engine.h"
+
+#include "p_node.h"
+#include "world_entity.h"
+#include "player.h"
+#include "camera.h"
+#include "environment.h"
+#include "terrain.h"
+#include "test_entity.h"
+#include "terrain.h"
+#include "md2Model.h"
+#include "world_entities/projectiles/projectile.h"
+#include "npcs/npc_test1.h"
+#include "playable.h"
+
+#include "factory.h"
+#include "fast_factory.h"
+#include "load_param.h"
+
+#include "network_manager.h"
+#include "network_game_manager.h"
+
+
+#include "glmenu_imagescreen.h"
+
+
+
+using namespace std;
+
+
+/**
+ * constructor of the GameWorldDataData
+ */
+MultiPlayerWorldData::MultiPlayerWorldData()
+    : GameWorldData()
+{
+  this->toggle = false;
+}
+
+
+/**
+ * destructor for the GameWorldDataData
+ */
+MultiPlayerWorldData::~MultiPlayerWorldData()
+{}
+
+
+/**
+ *  initialize the GameWorldDataData
+ */
+ErrorMessage MultiPlayerWorldData::init()
+{
+  /* call underlying function */
+  GameWorldData::init();
+}
+
+
+/**
+ *  loads the GUI data
+ * @param root reference to the xml root element
+ */
+ErrorMessage MultiPlayerWorldData::loadGUI(TiXmlElement* root)
+{
+  /* call underlying function */
+  GameWorldData::loadGUI(root);
+}
+
+
+/**
+ *  unloads the GUI data
+ */
+ErrorMessage MultiPlayerWorldData::unloadGUI()
+{
+  /* call underlying function */
+  GameWorldData::unloadGUI();
+}
+
+
+/**
+ *  overloads the GameWorld::loadWorldEntities(...) class since the network WorldEntity loading is different
+ * @param root reference to the xml root parameter
+ */
+ErrorMessage MultiPlayerWorldData::loadWorldEntities(TiXmlElement* root)
+{
+  /* load the spawning points */
+  TiXmlElement* element = root->FirstChildElement("SpawningPoints");
+  if( element == NULL)
+  {
+    PRINTF(1)("NetworkWorld is missing 'SpawningPoints'\n");
+  }
+  else
+  {
+    element = element->FirstChildElement();
+    // load Players/Objects/Whatever
+    PRINTF(4)("Loading Spawning Points\n");
+    while( element != NULL)
+    {
+      BaseObject* created = Factory::fabricate(element);
+      if( created != NULL )
+        printf("Created a Spawning Point %s: %s\n", created->getClassName(), created->getName());
+
+      element = element->NextSiblingElement();
+      glmis->step();
+    }
+    PRINTF(4)("Done loading Spawning Points\n");
+  }
+
+  /* load the WorldEntities */
+  element = root->FirstChildElement("WorldEntities");
+  if( element == NULL)
+  {
+    PRINTF(1)("NetworkWorld is missing 'WorldEntities'\n");
+  }
+  else
+  {
+    element = element->FirstChildElement();
+
+    while( element != NULL)
+    {
+      if( NetworkManager::getInstance()->isGameServer())
+      {
+        /* pass the entity to the NetworkGameManager to be created */
+        BaseObject* created = NetworkGameManager::getInstance()->createEntity(element);
+        if( created != NULL )
+          PRINTF(1)("Created a %s: %s (0x%8x) from %s\n", created->getClassName(), created->getName(), created->getLeafClassID(), element->Value());
+        else
+          PRINTF(1)("NetworkWorld: could not create this entity\n");
+
+        if( element->Value() != NULL && !strcmp( element->Value(), "SkyBox"))
+          this->sky = dynamic_cast<WorldEntity*>(created);
+        if( element->Value() != NULL && !strcmp( element->Value(), "Terrain"))
+        {
+          this->terrain = dynamic_cast<Terrain*>(created);
+          CDEngine::getInstance()->setTerrain(terrain);
+        }
+      }
+      element = element->NextSiblingElement();
+
+
+      glmis->step();
+      PRINTF(4)("Done loading NetworkWorldEntities\n");
+    }
+
+    if( NetworkManager::getInstance()->isGameServer())
+    {
+      this->localPlayer = new Player();
+      State::setPlayer(this->localPlayer);
+
+      Playable* playable;
+      const std::list<BaseObject*>* playableList = ClassList::getList(CL_PLAYABLE);
+      assert( playableList != NULL);
+
+      if (playableList != NULL)
+      {
+        playable = dynamic_cast<Playable*>(playableList->front());
+        this->localPlayer->setControllable(playable);
+      }
+    }
+    else
+    {
+      /* create a Player */
+      this->localPlayer = new Player();
+      State::setPlayer(this->localPlayer);
+    }
+
+
+    /* init the pnode tree */
+    PNode::getNullParent()->init();
+  }
+}
+
+
+/**
+ *  unloads the world entities from the xml file
+ */
+ErrorMessage MultiPlayerWorldData::unloadWorldEntities()
+{
+  /* call underlying function */
+  GameWorldData::unloadWorldEntities();
+}
+
+
+/**
+ *  loads the scene data
+ * @param root reference to the xml root element
+ */
+ErrorMessage MultiPlayerWorldData::loadScene(TiXmlElement* root)
+{
+  /* call underlying function */
+  GameWorldData::loadScene(root);
+}
+
+
+/**
+ *  unloads the scene data
+ */
+ErrorMessage MultiPlayerWorldData::unloadScene()
+{
+  /* call underlying function */
+  GameWorldData::unloadScene();
+}
+
+
+/**
+ * some debug output
+ */
+void MultiPlayerWorldData::debug()
+{
+  PRINT(0)("==================================================\n");
+  Playable* playable;
+  const std::list<BaseObject*>* playableList = ClassList::getList(CL_PLAYABLE);
+  assert(playableList != NULL);
+  std::list<BaseObject*>::const_iterator entity;
+
+
+
+  for (entity = playableList->begin(); entity != playableList->end(); entity++)
+  {
+    Playable* p = dynamic_cast<Playable*>(*entity);
+    PRINTF(0)("Got a playable, class: %s, name: %s, uid: %i\n", (*entity)->getClassName(), (*entity)->getName(), p->getUniqueID());
+  }
+
+
+  if( this->toggle)
+  {
+    playable = dynamic_cast<Playable*>(playableList->front());
+    this->localPlayer->disconnectControllable();
+    this->localPlayer->setControllable(playable);
+    this->toggle = !this->toggle;
+  }
+  else
+  {
+    playable = dynamic_cast<Playable*>(playableList->back());
+    this->localPlayer->disconnectControllable();
+    this->localPlayer->setControllable(playable);
+    this->toggle = !this->toggle;
+  }
+
+
+  Playable* pl = this->localPlayer->getControllable();
+  PRINTF(0)("The current regisered playable is hid: %i\n", pl->getUniqueID());
+
+
+  PNode* cam = State::getCameraTarget();
+  PRINT(0)("Camera has target - class: %s, name: %s, uid: %i\n", cam->getClassName(), cam->getName(), cam->getUniqueID());
+
+  PRINT(0)("==================================================\n");
+
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: branches/network/src/story_entities/multi_player_world_data.h
===================================================================
--- branches/network/src/story_entities/multi_player_world_data.h	(revision 6636)
+++ branches/network/src/story_entities/multi_player_world_data.h	(revision 6636)
@@ -0,0 +1,42 @@
+/*!
+ * @file multi_player_world_data.h
+ *  container for all multiplayer game world data
+ */
+
+#ifndef _MULTI_PLAYER_WORLD_DATA_H
+#define _MULTI_PLAYER_WORLD_DATA_H
+
+
+#include "game_world_data.h"
+
+
+class TiXmlElement;
+
+
+//! The multiplayer world data
+class MultiPlayerWorldData : public GameWorldData
+{
+
+  public:
+    MultiPlayerWorldData();
+    virtual ~MultiPlayerWorldData();
+
+    virtual ErrorMessage init();
+
+    void debug();
+
+
+  protected:
+    virtual ErrorMessage loadGUI(TiXmlElement* root);
+    virtual ErrorMessage loadWorldEntities(TiXmlElement* root);
+    virtual ErrorMessage loadScene(TiXmlElement* root);
+
+    virtual ErrorMessage unloadGUI();
+    virtual ErrorMessage unloadWorldEntities();
+    virtual ErrorMessage unloadScene();
+
+  private:
+    bool toggle;
+};
+
+#endif /* _MULTI_PLAYER_WORLD_DATA_H */
Index: branches/network/src/story_entities/simple_game_menu.cc
===================================================================
--- branches/network/src/story_entities/simple_game_menu.cc	(revision 6636)
+++ branches/network/src/story_entities/simple_game_menu.cc	(revision 6636)
@@ -0,0 +1,367 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
+
+
+#include "simple_game_menu.h"
+
+#include "state.h"
+#include "class_list.h"
+
+#include "load_param.h"
+#include "fast_factory.h"
+#include "factory.h"
+
+#include "p_node.h"
+#include "world_entity.h"
+#include "image_entity.h"
+#include "terrain.h"
+#include "camera.h"
+
+#include "event_handler.h"
+#include "graphics_engine.h"
+
+#include "cd_engine.h"
+
+
+using namespace std;
+
+
+//! This creates a Factory to fabricate a SimpleGameMenu
+CREATE_FACTORY(SimpleGameMenu, CL_SIMPLE_GAME_MENU);
+
+
+
+SimpleGameMenu::SimpleGameMenu(const TiXmlElement* root)
+  : GameWorld(root)
+{
+  this->setClassID(CL_SIMPLE_GAME_MENU, "SimpleGameMenu");
+  this->setName("SimpleGameMenu uninitialized");
+
+  this->dataTank = new SimpleGameMenuData();
+
+  this->cameraVector = Vector(50.0, 0.0, 0.0);
+
+  this->loadParams(root);
+}
+
+
+/**
+ *  remove the SimpleGameMenu from memory
+ *
+ *  delete everything explicitly, that isn't contained in the parenting tree!
+ *  things contained in the tree are deleted automaticaly
+ */
+SimpleGameMenu::~SimpleGameMenu ()
+{
+  PRINTF(3)("SimpleGameMenu::~SimpleGameMenu() - deleting current world\n");
+
+  if( this->dataTank)
+    delete this->dataTank;
+}
+
+
+/**
+ * loads the parameters of a SimpleGameMenu from an XML-element
+ * @param root the XML-element to load from
+ */
+void SimpleGameMenu::loadParams(const TiXmlElement* root)
+{
+  /* skip the GameWorld, since it does not define any useful loadParams for this class */
+  static_cast<GameWorld*>(this)->loadParams(root);
+
+  PRINTF(4)("Loaded SimpleGameMenu specific stuff\n");
+}
+
+
+/**
+ * this is executed just before load
+ *
+ * since the load function sometimes needs data, that has been initialized
+ * before the load and after the proceeding storyentity has finished
+ */
+ErrorMessage SimpleGameMenu::init()
+{
+  /* call underlying init funciton */
+  GameWorld::init();
+
+  EventHandler::getInstance()->subscribe(this, ES_MENU, SDLK_UP);
+  EventHandler::getInstance()->subscribe(this, ES_MENU, SDLK_DOWN);
+  EventHandler::getInstance()->subscribe(this, ES_MENU, SDLK_RETURN);
+  EventHandler::getInstance()->subscribe(this, ES_MENU, SDLK_SPACE);
+
+  this->dataTank->localCamera->setRelCoor(this->cameraVector);
+
+  GraphicsEngine::getInstance()->displayFPS(false);
+}
+
+
+/**
+ * load the data
+ */
+ErrorMessage SimpleGameMenu::loadData()
+{
+  GameWorld::loadData();
+
+  /* get the menu list */
+  const std::list<BaseObject*>* imageEntityList = ClassList::getList(CL_IMAGE_ENTITY);
+  std::list<BaseObject*>::const_iterator entity;
+  for (entity = imageEntityList->begin(); entity != imageEntityList->end(); entity++)
+  {
+
+    if( !strcmp("Selector_Menu", (*entity)->getName()))
+    {
+      this->menuSelector = dynamic_cast<ImageEntity*>(*entity);
+      PRINTF(0)("Found the selector: %s\n", (*entity)->getName());
+    }
+    else if( !strcmp( "StartGame_Menu", (*entity)->getName()))
+    {
+      PRINTF(0)("Found a StartItem: %s\n", (*entity)->getName());
+      this->menuStartGame = dynamic_cast<ImageEntity*>(*entity);
+      this->menuList.push_back(dynamic_cast<ImageEntity*>(*entity));
+    }
+    else if( !strcmp( "Multiplayer_Menu", (*entity)->getName()))
+    {
+      PRINTF(0)("Found a MultiplayerItem: %s\n", (*entity)->getName());
+      this->menuStartMultiplayerGame = dynamic_cast<ImageEntity*>(*entity);
+      this->menuList.push_back(dynamic_cast<ImageEntity*>(*entity));
+    }
+    else if( !strcmp( "Quit_Menu", (*entity)->getName()))
+    {
+      PRINTF(0)("Found a QuitItem: %s\n", (*entity)->getName());
+      this->menuQuitGame = dynamic_cast<ImageEntity*>(*entity);
+      this->menuList.push_back(dynamic_cast<ImageEntity*>(*entity));
+    }
+  }
+  this->menuSelectedIndex = 0;
+  this->menuSelected = this->menuList[this->menuSelectedIndex];
+  this->menuSelector->setAbsCoor(this->menuSelected->getAbsCoor());
+}
+
+
+
+/**
+ * start the menu
+ */
+bool SimpleGameMenu::start()
+{
+  EventHandler::getInstance()->pushState(ES_MENU);
+
+  /* now call the underlying*/
+  GameWorld::start();
+}
+
+
+
+/**
+ * stop the menu
+ */
+bool SimpleGameMenu::stop()
+{
+  EventHandler::getInstance()->popState();
+
+  /* now call the underlying*/
+  GameWorld::stop();
+}
+
+
+/**
+ *  override the standard tick for more functionality
+ */
+void SimpleGameMenu::tick()
+{
+  GameWorld::tick();
+
+  this->animateScene(this->dt);
+}
+
+
+/**
+ *  no collision detection in the menu
+ */
+void SimpleGameMenu::collide()
+{
+//   this->dataTank->localCamera->
+}
+
+
+/**
+ *  animate the scene
+ */
+void SimpleGameMenu::animateScene(float dt)
+{
+  Quaternion q(/*0.00005*/ 0.0001* dt, Vector(0.0, 1.0, 0.0));
+  this->cameraVector = q.apply(this->cameraVector);
+  this->dataTank->localCamera->setRelCoor(this->cameraVector);
+  this->dataTank->localCamera->getTarget()->setRelCoorSoft(0,0,0);
+}
+
+
+/**
+ * event dispatcher funciton
+ * @param event the incoming event
+ */
+void SimpleGameMenu::process(const Event &event)
+{
+  if( event.type == SDLK_RETURN)
+  {
+    if( this->menuSelected == this->menuQuitGame)
+    {
+      this->setNextStoryID(WORLD_ID_GAMEEND);
+      this->stop();
+    }
+    if( this->menuSelected == this->menuStartGame)
+    {
+      this->stop();
+    }
+  }
+  else if( event.type == SDLK_DOWN && event.bPressed == true)
+  {
+//     ImageEntity*
+    if(this->menuSelectedIndex < (this->menuList.size() - 1))
+    {
+      this->menuSelected = this->menuList[++this->menuSelectedIndex];
+      this->menuSelector->setAbsCoor(this->menuSelected->getAbsCoor());
+    }
+  }
+  else if( event.type == SDLK_UP && event.bPressed == true)
+  {
+    if(this->menuSelectedIndex > 0)
+    {
+      this->menuSelected = this->menuList[--this->menuSelectedIndex];
+      this->menuSelector->setAbsCoor(this->menuSelected->getAbsCoor());
+    }
+  }
+}
+
+
+
+
+
+
+/**********************************************************************************************
+    SimpleGameMenuData
+ **********************************************************************************************/
+
+
+/**
+ * SimpleGameMenuData constructor
+ */
+SimpleGameMenuData::SimpleGameMenuData()
+{}
+
+/**
+ * SimpleGameMenuData decontructor
+ */
+SimpleGameMenuData::~SimpleGameMenuData()
+{}
+
+
+/**
+ *  initialize the GameWorldDataData
+ */
+ErrorMessage SimpleGameMenuData::init()
+{
+  /* call underlying function */
+  GameWorldData::init();
+}
+
+
+/**
+ *  loads the GUI data
+ * @param root reference to the xml root element
+ */
+ErrorMessage SimpleGameMenuData::loadGUI(TiXmlElement* root)
+{
+  /* call underlying function */
+  GameWorldData::loadGUI(root);
+}
+
+
+/**
+ *  unloads the GUI data
+ */
+ErrorMessage SimpleGameMenuData::unloadGUI()
+{
+  /* call underlying function */
+  GameWorldData::unloadGUI();
+}
+
+
+/**
+ *  overloads the GameWorld::loadWorldEntities(...) class since the menu WorldEntity loading is different (less loading stuff)
+ * @param root reference to the xml root parameter
+ */
+ErrorMessage SimpleGameMenuData::loadWorldEntities(TiXmlElement* root)
+{
+  TiXmlElement* element = root->FirstChildElement("WorldEntities");
+
+  if( element != NULL)
+  {
+    element = element->FirstChildElement();
+    PRINTF(4)("Loading WorldEntities\n");
+    while( element != NULL)
+    {
+      BaseObject* created = Factory::fabricate(element);
+      if( created != NULL )
+        printf("Created a %s: %s\n", created->getClassName(), created->getName());
+
+      if( element->Value() != NULL && !strcmp( element->Value(), "SkyBox"))
+        this->sky = dynamic_cast<WorldEntity*>(created);
+      if( element->Value() != NULL && !strcmp( element->Value(), "Terrain"))
+        this->terrain = dynamic_cast<Terrain*>(created);
+      element = element->NextSiblingElement();
+    }
+    PRINTF(4)("Done loading WorldEntities\n");
+  }
+
+  /* init the pnode tree */
+  PNode::getNullParent()->init();
+}
+
+
+/**
+ *  unloads the world entities from the xml file
+ */
+ErrorMessage SimpleGameMenuData::unloadWorldEntities()
+{
+  /* call underlying function */
+  GameWorldData::unloadWorldEntities();
+}
+
+
+/**
+ *  loads the scene data
+ * @param root reference to the xml root element
+ */
+ErrorMessage SimpleGameMenuData::loadScene(TiXmlElement* root)
+{
+  /* call underlying function */
+  GameWorldData::loadScene(root);
+}
+
+
+/**
+ *  unloads the scene data
+ */
+ErrorMessage SimpleGameMenuData::unloadScene()
+{
+  /* call underlying function */
+  GameWorldData::unloadScene();
+}
+
+
+
Index: branches/network/src/story_entities/simple_game_menu.h
===================================================================
--- branches/network/src/story_entities/simple_game_menu.h	(revision 6636)
+++ branches/network/src/story_entities/simple_game_menu.h	(revision 6636)
@@ -0,0 +1,90 @@
+/*!
+ * @file simple_game_menu.h
+ *  a StoryEntity that contains a simple game menu
+ */
+
+#ifndef _SIMPLE_GAME_MENU_H
+#define _SIMPLE_GAME_MENU_H
+
+
+#include "game_world.h"
+#include "event_listener.h"
+#include "game_world_data.h"
+#include <vector>
+#include "vector.h"
+
+
+class SimpleGameMenuData;
+class TiXmlElement;
+class ImageEntity;
+
+//! a simple game menu based on a story entity
+/**
+ * This is a simple menu, that is based on the StoryEntity. Therefore this menu is absolutly
+ * loadable and is exchangeable very easely :D
+ */
+class SimpleGameMenu : virtual public GameWorld, virtual public EventListener
+{
+
+  public:
+    SimpleGameMenu(const TiXmlElement* root = NULL);
+    virtual ~SimpleGameMenu();
+
+    void loadParams(const TiXmlElement* root);
+
+    virtual ErrorMessage init();
+    virtual ErrorMessage loadData();
+
+    virtual bool start();
+    virtual bool stop();
+
+    virtual void process(const Event &event);
+
+
+  protected:
+    virtual void tick();
+    virtual void collide();
+
+
+  private:
+    void animateScene(float dt);
+
+
+  private:
+    std::vector<ImageEntity*>         menuList;                        //!< the list of the menu items
+    ImageEntity*                      menuSelected;                    //!< ref to the selected menu entity
+    ImageEntity*                      menuSelector;                    //!< ref to the selector image
+    ImageEntity*                      menuStartGame;
+    ImageEntity*                      menuStartMultiplayerGame;
+    ImageEntity*                      menuQuitGame;
+    int                               menuSelectedIndex;
+
+    Vector                            cameraVector;
+};
+
+
+
+//! the simple game menu data
+class SimpleGameMenuData : public GameWorldData
+{
+
+  public:
+    SimpleGameMenuData();
+    virtual ~SimpleGameMenuData();
+
+    virtual ErrorMessage init();
+
+
+  protected:
+    virtual ErrorMessage loadGUI(TiXmlElement* root);
+    virtual ErrorMessage loadWorldEntities(TiXmlElement* root);
+    virtual ErrorMessage loadScene(TiXmlElement* root);
+
+    virtual ErrorMessage unloadGUI();
+    virtual ErrorMessage unloadWorldEntities();
+    virtual ErrorMessage unloadScene();
+
+};
+
+
+#endif /* _GAME_WORLD_H */
Index: branches/network/src/story_entities/single_player_world.cc
===================================================================
--- branches/network/src/story_entities/single_player_world.cc	(revision 6636)
+++ branches/network/src/story_entities/single_player_world.cc	(revision 6636)
@@ -0,0 +1,77 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
+
+
+#include "single_player_world.h"
+#include "single_player_world_data.h"
+
+#include "state.h"
+#include "class_list.h"
+
+#include "load_param.h"
+#include "fast_factory.h"
+#include "factory.h"
+
+#include "world_entity.h"
+#include "npcs/npc_test1.h"
+
+
+using namespace std;
+
+
+//! This creates a Factory to fabricate a SinglePlayerWorld
+CREATE_FACTORY(SinglePlayerWorld, CL_SINGLE_PLAYER_WORLD);
+
+
+
+SinglePlayerWorld::SinglePlayerWorld(const TiXmlElement* root)
+  : GameWorld(root)
+{
+  this->setClassID(CL_SINGLE_PLAYER_WORLD, "SinglePlayerWorld");
+  this->setName("SinglePlayerWorld uninitialized");
+
+  this->dataTank = new SinglePlayerWorldData();
+
+  this->loadParams(root);
+}
+
+
+/**
+ *  remove the SinglePlayerWorld from memory
+ *
+ *  delete everything explicitly, that isn't contained in the parenting tree!
+ *  things contained in the tree are deleted automaticaly
+ */
+SinglePlayerWorld::~SinglePlayerWorld ()
+{
+  PRINTF(3)("SinglePlayerWorld::~SinglePlayerWorld() - deleting current world\n");
+
+  if( this->dataTank)
+    delete this->dataTank;
+}
+
+
+/**
+ * loads the parameters of a SinglePlayerWorld from an XML-element
+ * @param root the XML-element to load from
+ */
+void SinglePlayerWorld::loadParams(const TiXmlElement* root)
+{
+  GameWorld::loadParams(root);
+
+  PRINTF(4)("Loaded SinglePlayerWorld specific stuff\n");
+}
+
Index: branches/network/src/story_entities/single_player_world.h
===================================================================
--- branches/network/src/story_entities/single_player_world.h	(revision 6636)
+++ branches/network/src/story_entities/single_player_world.h	(revision 6636)
@@ -0,0 +1,32 @@
+/*!
+ * @file single_player_world.h
+ *  Holds and manages all single player game data
+ */
+
+#ifndef _SINGLE_PLAYER_WORLD_H
+#define _SINGLE_PLAYER_WORLD_H
+
+
+#include "game_world.h"
+
+
+class TiXmlElement;
+class SinglePlayerWorldData;
+
+
+//! The game world
+/**
+ *  this class initializes everything that should be displayed inside of the current level.
+ *  it is the main driving factor during gameplay.
+ */
+class SinglePlayerWorld : public GameWorld
+{
+
+  public:
+    SinglePlayerWorld (const TiXmlElement* root = NULL);
+    virtual ~SinglePlayerWorld ();
+
+    virtual void loadParams(const TiXmlElement* root);
+};
+
+#endif /* _SINGLE_PLAYER_WORLD_H */
Index: branches/network/src/story_entities/single_player_world_data.cc
===================================================================
--- branches/network/src/story_entities/single_player_world_data.cc	(revision 6636)
+++ branches/network/src/story_entities/single_player_world_data.cc	(revision 6636)
@@ -0,0 +1,112 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
+
+
+#include "single_player_world_data.h"
+
+#include "load_param.h"
+
+
+using namespace std;
+
+
+/**
+ * constructor of the GameWorldDataData
+ */
+SinglePlayerWorldData::SinglePlayerWorldData()
+  : GameWorldData()
+{}
+
+
+/**
+ * destructor for the GameWorldDataData
+ */
+SinglePlayerWorldData::~SinglePlayerWorldData()
+{}
+
+
+/**
+ *  initialize the GameWorldDataData
+ */
+ErrorMessage SinglePlayerWorldData::init()
+{
+  /* call underlying function */
+  GameWorldData::init();
+}
+
+
+/**
+ *  loads the GUI data
+ * @param root reference to the xml root element
+ */
+ErrorMessage SinglePlayerWorldData::loadGUI(TiXmlElement* root)
+{
+  /* call underlying function */
+  GameWorldData::loadGUI(root);
+}
+
+
+/**
+ *  unloads the GUI data
+ */
+ErrorMessage SinglePlayerWorldData::unloadGUI()
+{
+  /* call underlying function */
+  GameWorldData::unloadGUI();
+}
+
+
+/**
+ *  overloads the GameWorld::loadWorldEntities(...) class since the network WorldEntity loading is different
+ * @param root reference to the xml root parameter
+ */
+ErrorMessage SinglePlayerWorldData::loadWorldEntities(TiXmlElement* root)
+{
+  /* call underlying function */
+  GameWorldData::loadWorldEntities(root);
+}
+
+
+/**
+ *  unloads the world entities from the xml file
+ */
+ErrorMessage SinglePlayerWorldData::unloadWorldEntities()
+{
+  /* call underlying function */
+  GameWorldData::unloadWorldEntities();
+}
+
+
+/**
+ *  loads the scene data
+ * @param root reference to the xml root element
+ */
+ErrorMessage SinglePlayerWorldData::loadScene(TiXmlElement* root)
+{
+  /* call underlying function */
+  GameWorldData::loadScene(root);
+}
+
+
+/**
+ *  unloads the scene data
+ */
+ErrorMessage SinglePlayerWorldData::unloadScene()
+{
+  /* call underlying function */
+  GameWorldData::unloadScene();
+}
+
Index: branches/network/src/story_entities/single_player_world_data.h
===================================================================
--- branches/network/src/story_entities/single_player_world_data.h	(revision 6636)
+++ branches/network/src/story_entities/single_player_world_data.h	(revision 6636)
@@ -0,0 +1,37 @@
+/*!
+ * @file single_player_world_data.h
+ *  container for all singleplayer game world data
+ */
+
+#ifndef _SINGLE_PLAYER_WORLD_DATA_H
+#define _SINGLE_PLAYER_WORLD_DATA_H
+
+
+#include "game_world_data.h"
+
+
+class TiXmlElement;
+
+
+//! The singleplayer world data
+class SinglePlayerWorldData : public GameWorldData
+{
+
+  public:
+    SinglePlayerWorldData();
+    virtual ~SinglePlayerWorldData();
+
+    virtual ErrorMessage init();
+
+
+  protected:
+    virtual ErrorMessage loadGUI(TiXmlElement* root);
+    virtual ErrorMessage loadWorldEntities(TiXmlElement* root);
+    virtual ErrorMessage loadScene(TiXmlElement* root);
+
+    virtual ErrorMessage unloadGUI();
+    virtual ErrorMessage unloadWorldEntities();
+    virtual ErrorMessage unloadScene();
+};
+
+#endif /* _SINGLE_PLAYER_WORLD_DATA_H */
Index: branches/network/src/story_entities/story_def.h
===================================================================
--- branches/network/src/story_entities/story_def.h	(revision 6636)
+++ branches/network/src/story_entities/story_def.h	(revision 6636)
@@ -0,0 +1,24 @@
+
+#ifndef _STORY_DEF_H
+#define _STORY_DEF_H
+
+
+#define DEBUG_CAMPAIGN_0 1000
+#define DEBUG_CAMPAIGN_1 1001
+#define DEBUG_CAMPAIGN_2 1002
+
+#define DEBUG_WORLD_0 100
+#define DEBUG_WORLD_1 101
+#define DEBUG_WORLD_2 102
+
+#define WORLD_ID_0 0
+#define WORLD_ID_1 1
+#define WORLD_ID_2 2
+#define WORLD_ID_3 3
+#define WORLD_ID_4 4
+#define WORLD_ID_5 5
+#define WORLD_ID_GAMEEND 999
+
+#define MAX_STORY_ENTITIES 99 //!< maximal StoryEntities in a Campaign
+
+#endif /* _STORY_DEF_H */
Index: branches/network/src/story_entities/story_entity.cc
===================================================================
--- branches/network/src/story_entities/story_entity.cc	(revision 6636)
+++ branches/network/src/story_entities/story_entity.cc	(revision 6636)
@@ -0,0 +1,68 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
+
+
+#include "story_entity.h"
+
+#include "load_param.h"
+
+
+using namespace std;
+
+
+/**
+ *  default constructor initializes all needed data
+ */
+StoryEntity::StoryEntity ()
+{
+  this->setClassID(CL_STORY_ENTITY, "StoryEntity");
+
+  this->isInit = false;
+  this->isPaused = false;
+  this->isRunning = false;
+
+  this->storyID = -1;
+  this->nextStoryID = WORLD_ID_GAMEEND;
+}
+
+
+/**
+ *  deconstructor
+ */
+StoryEntity::~StoryEntity ()
+{}
+
+
+/**
+ *  loads the Parameters of a Campaign
+ * @param root: The XML-element to load from
+ */
+void StoryEntity::loadParams(const TiXmlElement* root)
+{
+  BaseObject::loadParams(root);
+
+  LoadParam(root, "identifier", this, StoryEntity, setStoryID)
+      .describe("A Unique Identifier for this StoryEntity");
+
+  LoadParam(root, "nextid", this, StoryEntity, setNextStoryID)
+      .describe("Sets the ID of the next StoryEntity");
+
+  PRINTF(4)("Loaded StoryEntity specific stuff\n");
+}
Index: branches/network/src/story_entities/story_entity.h
===================================================================
--- branches/network/src/story_entities/story_entity.h	(revision 6636)
+++ branches/network/src/story_entities/story_entity.h	(revision 6636)
@@ -0,0 +1,83 @@
+/*!
+ * @file story_entity.h
+ *  holds the base class of everything that is playable - that is part of the story
+ */
+
+
+#ifndef _STORY_ENTITY_H
+#define _STORY_ENTITY_H
+
+#include "base_object.h"
+#include "story_def.h"
+#include "error.h"
+
+
+typedef enum StoryEntityState
+{
+  SE_STATE_RUN     = 0,
+  SE_STATE_STOP,
+  SE_STATE_PAUSE,
+
+  SE_STATE_NUM
+};
+
+
+//! A class that represents something to play in orxonox. it is a container for worlds, movies, mission briefings, etc...
+class StoryEntity : virtual public BaseObject {
+
+ public:
+  StoryEntity ();
+  virtual ~StoryEntity ();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  /* initialisation and loading */
+  /** initializes a Story Entity to the needed values */
+  virtual ErrorMessage init() {};
+  /** called to load the data into the StoryEntity*/
+  virtual ErrorMessage loadData() {};
+  /** function that unloads the data from the StoryEntity */
+  virtual ErrorMessage unloadData() {};
+
+  /* running, stopping and pausing */
+  /** starts the Entity. Starts the main cycle */
+  virtual bool start() = 0;
+  /**  Stops the entity. */
+  virtual bool stop() = 0;
+  /** pauses the Entity, you can resume the game by calling the resume() function */
+  virtual bool pause() = 0;
+  /** resumes a paused StoryEntity */
+  virtual bool resume() = 0;
+  /** function that is been called when the StoryEntity is started via start() */
+  virtual void run() = 0;
+
+  /* properties interface */
+  /** returns the state of this StoryEntity */
+  StoryEntityState getState();
+
+  /** sets the story id of the current entity, this enables it to be identified in a global context.  @param storyID the story id */
+  inline void setStoryID(int storyID) { this->storyID = storyID; }
+  /** sets the story id of the current entity, this enables it to be identified in a  global context. @returns  the story id  */
+  inline int getStoryID() { return this->storyID; }
+  /**  sets the id of the next story entity: StoryEntities can choose their following entity themselfs.
+   * the entity id defined here  will be startet after this entity ends. this can be convenient if you
+   * want to have a non linear story with switches.
+   * @param nextStoryID the story id of the next StoryEntity   */
+  inline void setNextStoryID(int nextStoryID) { this->nextStoryID = nextStoryID; }
+  /**  gets the story id of the current entity @returns story id */
+  inline int getNextStoryID() { return this->nextStoryID; }
+
+
+
+  protected:
+    bool isInit;         //!< if the entity is initialized, this has to be true.
+    bool isRunning;      //!< is true if the entity is running
+    bool isPaused;       //!< is true if the entity is paused
+
+
+ private:
+    int storyID;           //!< this is the number of this entity, identifying it in a list/tree...
+    int nextStoryID;       //!< if this entity has finished, this entity shall be called
+};
+
+#endif /* _STORY_ENTITY_H */
Index: branches/network/src/subprojects/Makefile.am
===================================================================
--- branches/network/src/subprojects/Makefile.am	(revision 6636)
+++ branches/network/src/subprojects/Makefile.am	(revision 6636)
@@ -0,0 +1,10 @@
+SUBDIRS = importer \
+          particles \
+          collision_detection \
+          network \
+          testmain
+
+noinst_HEADERS = framework.h
+
+
+EXTRA_DIST = framework.cc
Index: branches/network/src/subprojects/benchmark.cc
===================================================================
--- branches/network/src/subprojects/benchmark.cc	(revision 6636)
+++ branches/network/src/subprojects/benchmark.cc	(revision 6636)
@@ -0,0 +1,473 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software Foundation,
+   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+
+*/
+
+
+#if defined __linux__
+
+#include "list.h"
+#include "world_entity.h"
+#include "vector.h"
+#include "player.h"
+#include "base_object.h"
+
+#include <stdlib.h>
+#include <asm/msr.h>
+//#include <linux/timex.h>
+
+
+#define LIST_MAX 1000
+#define VECTOR_MAX 1000000
+#define ITERATIONS 10000
+
+
+int startBenchmarks()
+{
+
+  printf("===========================================================\n");
+  printf("=                      BENCHMARKS                         =\n");
+  printf("===========================================================\n");
+  printf(" the author is not paying any attention to cacheing effects\n");
+  printf(" of the CPU.\n\n");
+  printf("[title]\t\t\t\t\t     [cycles]\t[loops]\n\n");
+  //  printf("------------------------------------------------------------\n\n");
+
+  // first measure the time overhead:
+  unsigned long ini, end, dt, tmp;
+  rdtscl(ini); rdtscl(end);
+  dt = end - ini;
+
+  int type = -1;
+  /* type   -1 == all
+     type    0 == framework
+     type    1 == vector
+     type    2 == quaternion
+     type    3 == lists
+  */
+  if(type == 0 || type == -1)
+    {
+      /* framework test*/
+
+      printf("Generating Objects:\t\t\t\t\t%i\n", ITERATIONS);
+      /* ************WorldEntity class test************** */
+      WorldEntity* w = NULL;
+      int i = 0;
+      unsigned long mittel = 0;
+
+      for(i = 0; i < ITERATIONS; ++i)
+        {
+          rdtscl(ini);
+
+          WorldEntity* w = new WorldEntity();
+
+          rdtscl(end);
+          delete w;
+          mittel += (end - ini - dt);
+        }
+      float mi = mittel / (float)ITERATIONS;
+      printf(" Generate a WorldEntity object:\t\t%11.2f\n", mi);
+
+      /*
+        mittel = 0;
+        for(i = 0; i < ITERATIONS; ++i)
+        {
+        rdtscl(ini);
+
+        WorldEntity* w = new Primitive(P_SPHERE);
+
+        rdtscl(end);
+        delete w;
+        mittel += (end - ini - dt);
+        }
+        mi = mittel / (float)ITERATIONS;
+        printf(" Generate a Primitive  object:\t\t%11.2f\n", mi);
+      */
+
+      mittel = 0;
+      for(i = 0; i < ITERATIONS; ++i)
+        {
+          rdtscl(ini);
+
+          Vector* v = new Vector();
+
+          rdtscl(end);
+          delete v;
+          mittel += (end - ini - dt);
+        }
+      mi = mittel / (float)ITERATIONS;
+      printf(" Generate a Vector object:\t\t%11.2f\n", mi);
+
+
+     mittel = 0;
+      for(i = 0; i < ITERATIONS; ++i)
+        {
+          rdtscl(ini);
+
+          Quaternion* q = new Quaternion();
+
+          rdtscl(end);
+          delete q;
+          mittel += (end - ini - dt);
+        }
+      mi = mittel / (float)ITERATIONS;
+      printf(" Generate a Quaternion object:\t\t%11.2f\n", mi);
+
+
+
+
+      printf("\nCalling function inline &| virtual, \t\t\t%i\n", ITERATIONS);
+      mittel = 0;
+      w = new WorldEntity();
+      for(i = 0; i < ITERATIONS; ++i)
+        {
+          rdtscl(ini);
+
+          w->tick(0.0f);
+
+          rdtscl(end);
+          mittel += (end - ini - dt);
+          }
+      //delete w;
+      mi = mittel / (float)ITERATIONS;
+      printf(" Virt funct tick() of WE: \t\t%11.2f\n", mi);
+
+
+      mittel = 0;
+      WorldEntity wo;
+      for(i = 0; i < ITERATIONS; ++i)
+        {
+          rdtscl(ini);
+
+          wo.tick(0.0f);
+
+          rdtscl(end);
+          mittel += (end - ini - dt);
+          }
+      //delete w;
+      mi = mittel / (float)ITERATIONS;
+      printf(" Inl virt funct tick() of WE v2: \t%11.2f\n", mi);
+
+
+      mittel = 0;
+      BaseObject* bo = new BaseObject();
+      for(i = 0; i < ITERATIONS; ++i)
+        {
+          rdtscl(ini);
+
+//          bo->isFinalized();
+
+          rdtscl(end);
+          mittel += (end - ini - dt);
+          }
+      //delete w;
+      mi = mittel / (float)ITERATIONS;
+      printf(" Inl funct BaseObject::isFinazlized(): \t%11.2f\n", mi);
+
+
+      tList<WorldEntity>* list = new tList<WorldEntity>();
+
+
+      /* ************Primitvie class test************** */
+      list = new tList<WorldEntity>();
+
+
+      /*
+        mittel = 0;
+        w = new Primitive(P_SPHERE);
+        for(i = 0; i < ITERATIONS; ++i)
+        {
+        rdtscl(ini);
+
+        w->tick(0.0f);
+
+        rdtscl(end);
+        mittel += (end - ini - dt);
+        }
+        mi = mittel / (float)ITERATIONS;
+        printf(" Call function tick() of Prim:\t\t%11.2f\n", mi);
+      */
+
+    }
+
+  if(type == 1 || type == -1)
+    {
+      printf("\nDoing some simple vector operations: \t\t\t%i\n", VECTOR_MAX);
+      /* vector test */
+      Vector* a = new Vector(1.3, 5.3, 4.1);
+      Vector* b = new Vector(0.4, 2.5, 6.2);
+      Vector* c = new Vector();
+
+      unsigned long mittel, ini, end;
+      float mi;
+      int i = 0;
+      // addition
+      mittel = 0;
+      for(i = 0; i < VECTOR_MAX; ++i)
+        {
+          rdtscl(ini);
+
+          *c = *a + *b;
+
+          rdtscl(end);
+          mittel += (end - ini - dt);
+        }
+      mi = mittel / (float)VECTOR_MAX;
+      printf(" Addition of two vectors:\t\t%11.2f\n", mi);
+
+      // multiplikation
+
+      mittel = 0;
+      for(i = 0; i < VECTOR_MAX; ++i)
+        {
+          rdtscl(ini);
+
+          *c = a->cross( *b);
+
+          rdtscl(end);
+          mittel += (end - ini - dt);
+        }
+      mi = mittel / (float)VECTOR_MAX;
+      printf(" CrossMult of two vectors:\t\t%11.2f\n", mi);
+
+    }
+  if( type == 2 || type == -1)
+    {
+      /* quaternion test */
+      printf("\nDoing some simple quaternion operations: \t\t%i\n", VECTOR_MAX);
+      /* vector test */
+      Quaternion* a = new Quaternion();
+      Quaternion* b = new Quaternion();
+      Quaternion* c = new Quaternion();
+
+      unsigned long mittel, ini, end;
+      float mi;
+      int i = 0;
+      // quaternion generieren mit spez konstruktor
+      mittel = 0;
+      Vector* qa = new Vector(4.6, 9.3, 0.4);
+      Vector* qb = new Vector(3.5, 6.1, 4.3);
+      for(i = 0; i < VECTOR_MAX; ++i)
+        {
+          rdtscl(ini);
+
+          Quaternion* qu = new Quaternion(*qa, *qb);
+
+          rdtscl(end);
+          delete qu;
+          mittel += (end - ini - dt);
+        }
+      delete a;
+      delete b;
+      mi = mittel / (float)VECTOR_MAX;
+      printf(" Gen. quatern. betw. two vectors:\t%11.2f\n", mi);
+
+
+      // multiplication
+      mittel = 0;
+      for(i = 0; i < VECTOR_MAX; ++i)
+        {
+          rdtscl(ini);
+
+          *c = *a * *b;
+
+          rdtscl(end);
+          mittel += (end - ini - dt);
+        }
+      mi = mittel / (float)VECTOR_MAX;
+      printf(" Multiplying two quat.(=rot): a * b\t%11.2f\n", mi);
+
+
+
+      // rotating a vector by a quaternion
+      mittel = 0;
+      for(i = 0; i < VECTOR_MAX; ++i)
+        {
+          rdtscl(ini);
+
+          *qa = a->apply(*qb);
+
+          rdtscl(end);
+          mittel += (end - ini - dt);
+        }
+      mi = mittel / (float)VECTOR_MAX;
+      printf(" Rot a vec by a quat: q->apply(v)\t%11.2f\n", mi);
+
+
+
+      // generate rotation matrix
+      mittel = 0;
+      float matrix[4][4];
+      for(i = 0; i < VECTOR_MAX; ++i)
+        {
+          rdtscl(ini);
+
+          a->matrix(matrix);
+
+          rdtscl(end);
+          mittel += (end - ini - dt);
+        }
+      mi = mittel / (float)VECTOR_MAX;
+      printf(" Generate rot matrix: q->matrix(m)\t%11.2f\n", mi);
+    }
+  if( type == 3 || type == -1)
+    {
+      /* list tests*/
+      printf("\nList operations tests: \t\t\t\t\t%i\n", LIST_MAX);
+      tList<char>* list = new tList<char>();
+      char* name;
+
+      printf(" Adding[1..10] elements to list, found:\n");
+      list->add("1");
+      list->add("2");
+      list->add("3");
+      list->add("4");
+      list->add("5");
+      list->add("6");
+      list->add("7");
+      list->add("8");
+      list->add("9");
+      list->add("10");
+
+      /*give list out */
+      tIterator<char>* iterator = list->getIterator();
+      name = iterator->firstElement();
+      printf("  List Elements: \t\t");
+      while( name != NULL)
+        {
+          printf("%s,", name);
+          name = iterator->nextElement();
+        }
+      delete iterator;
+      printf("\n");
+
+
+      /*removing some elements from the list*/
+      printf(" Removing elements [2,3,6,8,10], adding [11] now found:\n");
+      list->remove("2");
+      list->remove("3");
+      list->remove("6");
+      list->remove("8");
+      list->remove("10");
+      list->add("11");
+      /*give list out */
+      iterator = list->getIterator();
+      name = iterator->firstElement();
+      printf("  List Elements: \t\t");
+      while( name != NULL)
+        {
+          printf("%s,", name);
+          name = iterator->nextElement();
+        }
+      delete iterator;
+      printf("\n");
+
+      delete list;
+      printf("\nChecking list performance:\t\t\t\t%i\n", LIST_MAX);
+
+      tList<int>* plist = new tList<int>();
+      unsigned long mittel, ini, end;
+      float mi;
+      int i = 0;
+      mittel = 0;
+      for(i = 0; i < LIST_MAX; ++i)
+        {
+          rdtscl(ini);
+
+          plist->add(&i);
+
+          rdtscl(end);
+          mittel += (end - ini - dt);
+        }
+      mi = mittel / (float)LIST_MAX;
+      printf(" Adding reference to list:\t\t%11.2f\n", mi);
+
+      mittel = 0;
+      for(i = 0; i < LIST_MAX; ++i)
+        {
+          rdtscl(ini);
+
+          plist->remove(&i);
+
+          rdtscl(end);
+          mittel += (end - ini - dt);
+        }
+      mi = mittel / (float)LIST_MAX;
+      printf(" Removing 1st reference from list:\t%11.2f\n", mi);
+
+
+      printf("\nList operations tests: \t\t\t\t\t%i\n", LIST_MAX);
+      list = new tList<char>();
+      printf(" Adding[1..10] elements to list, found:\n");
+      list->add("1");
+      list->add("2");
+      list->add("3");
+      list->add("4");
+      list->add("5");
+      list->add("6");
+      list->add("7");
+      list->add("8");
+      list->add("9");
+      list->add("10");
+
+      /*give list out */
+      iterator = list->getIterator();
+      name = iterator->firstElement();
+      printf("  List Elements: \t\t");
+      while( name != NULL)
+        {
+          printf("%s,", name);
+          name = iterator->nextElement();
+        }
+      delete iterator;
+      printf("\n");
+
+
+      int c = 0;
+      printf(" Going trough list with nextElement(el) func: ");
+      name = list->firstElement();
+      while(c < 20)
+        {
+          printf("%s,", name);
+          name = list->nextElement(name);
+          c++;
+        }
+      printf("\n");
+
+
+
+    }
+
+}
+
+#else
+
+#include "debug.h"
+
+int startBenchmarks()
+{
+  PRINTF(1)("Benchmark is not implemented in this system\n");
+}
+
+#endif
Index: branches/network/src/subprojects/benchmark.h
===================================================================
--- branches/network/src/subprojects/benchmark.h	(revision 6636)
+++ branches/network/src/subprojects/benchmark.h	(revision 6636)
@@ -0,0 +1,13 @@
+/*!
+ * @file benchmark.h
+  *  benchmark functions
+*/
+
+
+#ifndef _BENCHMARK_H
+#define _BENCHMARK_H
+
+int startBenchmarks();
+
+
+#endif /* _BENCHMARK_H */
Index: branches/network/src/subprojects/collision_detection/Makefile.am
===================================================================
--- branches/network/src/subprojects/collision_detection/Makefile.am	(revision 6636)
+++ branches/network/src/subprojects/collision_detection/Makefile.am	(revision 6636)
@@ -0,0 +1,43 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+
+bin_PROGRAMS = collision
+
+collision_LDADD = $(MAINSRCDIR)/util/libORXutils.a \
+                  $(MAINSRCDIR)/lib/physics/libORXphysics.a \
+                  $(MAINSRCDIR)/lib/collision_detection/libORXcd.a \
+                  $(MAINSRCDIR)/lib/libORXlibs.a \
+                  $(MAINSRCDIR)/lib/physics/libORXphysics.a \
+                  $(MAINSRCDIR)/lib/graphics/importer/libORXimporter.a \
+                  $(MAINSRCDIR)/lib/graphics/libORXgraphics.a \
+                  $(MAINSRCDIR)/lib/shell/libORXshell.a \
+                  $(MAINSRCDIR)/lib/event/libORXevent.a \
+                  $(MAINSRCDIR)/lib/sound/libORXsound.a \
+                  $(MAINSRCDIR)/lib/tinyxml/libtinyxml.a \
+                  $(MAINSRCDIR)/lib/graphics/spatial_separation/libORXquadtree.a \
+                  $(GTK2_LIBS) $(GTHREAD_LIBS) $(CURL_LIBS)
+
+
+collision_CPPFLAGS =  -DGUI_MODULE   \
+                      $(GTK2_CFLAGS) $(GTHREAD_CFLAGS) $(CURL_CFLAGS) $(MSBITFIELDS)
+
+
+collision_SOURCES= ../framework.cc \
+                   collision_detection.cc \
+                   \
+                   $(MAINSRCDIR)/lib/util/helper_functions.cc \
+                   $(MAINSRCDIR)/lib/util/substring.cc \
+                   $(MAINSRCDIR)/lib/parser/ini_parser/ini_parser.cc \
+                   $(MAINSRCDIR)/lib/lang/base_object.cc \
+                   $(MAINSRCDIR)/lib/lang/class_list.cc \
+                   $(MAINSRCDIR)/lib/math/vector.cc \
+                   $(MAINSRCDIR)/lib/util/color.cc \
+                   $(MAINSRCDIR)/lib/coord/p_node.cc \
+                   $(MAINSRCDIR)/lib/gui/gtk_gui/gui_gtk.cc \
+                   \
+                   $(MAINSRCDIR)/world_entities/world_entity.cc \
+                   $(MAINSRCDIR)/world_entities/camera.cc \
+                   collision_test_entity.cc
+
+noinst_HEADERS  =  collision_test_entity.h
Index: branches/network/src/subprojects/collision_detection/collision_detection.cc
===================================================================
--- branches/network/src/subprojects/collision_detection/collision_detection.cc	(revision 6636)
+++ branches/network/src/subprojects/collision_detection/collision_detection.cc	(revision 6636)
@@ -0,0 +1,429 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+
+   this file extends the framework file, so it renders what i want.
+*/
+
+#include "framework.h"
+
+#include "fields.h"
+#include "stdlibincl.h"
+#include "light.h"
+
+#include "cd_engine.h"
+#include "bv_tree.h"
+
+#include "md2Model.h"
+#include "model.h"
+#include "collision_test_entity.h"
+
+
+#include "graphics_engine.h"
+#include "list.h"
+
+
+Model* mod;
+MD2Model* model;
+int drawMode;
+int depth;
+float iterata;
+tList<WorldEntity>* entityList;
+
+int lastFrame, currentFrame, dt;
+bool drawModel = false;
+
+WorldEntity* a;
+WorldEntity* b;
+//Terrain* c;
+bool animateModel = false;
+
+void Framework::moduleInit(int argc, char** argv)
+{
+  GraphicsEngine::getInstance()->setWindowName("Collision Cluster", "collision");
+
+  CDEngine::getInstance();
+
+  /* Primitive Data Test */
+//   sVec3D* data = new sVec3D[6];
+//   float tmp[6][3] = {{0.0, 4.2, 2.4}, {3.0, 3.0, 2.0}, {5.0, 1.0, 6.0}, {6.5, 1.0, 3.0}, {7.0, 3.0, 5.0}, {8.0, 6.0, 6.0}};
+//   for(int i = 0; i < 6; ++i)
+//   {
+//     data[i][0] = tmp[i][0];
+//     data[i][1] = tmp[i][1];
+//     data[i][2] = tmp[i][2];
+//   }
+//   CDEngine::getInstance()->debugSpawnTree(5, data, 6);
+
+  /* MD2 Model Test */
+//   model = new MD2Model("models/tris.md2", "models/tris.pcx");
+//   model->tick(0.1f);
+//   CDEngine::getInstance()->debugSpawnTree(9, model->data->pVertices, model->data->numVertices);
+
+  /* OBJ - Model Test */
+//   mod = (Model*)ResourceManager::getInstance()->load("models/reaplow.obj", OBJ, RP_CAMPAIGN);
+//   CDEngine::getInstance()->debugSpawnTree(9, (sVec3D*)mod->getVertexArray(), mod->getVertexArrayCount());
+
+
+
+  entityList = new tList<WorldEntity>();
+
+//   a = new TestEntity(); a->setName("Clown1");
+   b = new CollisionTestEntity(); b->setName("Jaeger");
+   if (argc > 1)
+   {
+     printf("Loading model %s\n", argv[1]);
+     b->loadModel(argv[1]);
+   }
+//   a = new Terrain();
+
+//   b->setRelCoor(0.0, 0.0, -20.0);
+//   b->setRelDir(Quaternion(-M_PI/2.0f, Vector(0.0, 1.0, 0.0)));
+
+  entityList->add(b);
+//   entityList->add(b);
+
+  CDEngine::getInstance()->setEntityList(entityList);
+
+  LightManager* lightMan = LightManager::getInstance();
+  lightMan->setAmbientColor(.1,.1,.1);
+  (new Light())->setAbsCoor(-5.0, 50.0, -40.0);
+  (new Light())->setAbsCoor(100, 80, 60);
+
+
+  /* properties */
+  drawMode = DRAW_MODEL;
+  depth = 0;
+  dt = lastFrame = currentFrame = 0;
+  iterata = 0.05f;
+
+  moduleHelp();
+}
+
+
+void Framework::moduleEventHandler(SDL_Event* event)
+{
+  switch (event->type)
+  {
+    case SDL_KEYDOWN:
+      switch (event->key.keysym.sym)
+      {
+        case SDLK_a:
+          drawMode |= DRAW_ALL;
+          break;
+        case SDLK_0:
+        {
+          printf("Setting tree depth = 0\n");
+          depth = 0;
+          int temp = drawMode & DRAW_ALL;
+          drawMode ^= temp;
+          drawMode |= DRAW_SINGLE;
+          break;
+        }
+        case SDLK_1:
+        {
+          printf("Setting tree depth = 1\n");
+          depth = 1;
+          int temp = drawMode & DRAW_ALL;
+          drawMode ^= temp;
+          drawMode |= DRAW_SINGLE;
+          break;
+        }
+        case SDLK_2:
+        {
+          printf("Setting tree depth = 2\n");
+          depth = 2;
+          int temp = drawMode & DRAW_ALL;
+          drawMode ^= temp;
+          drawMode |= DRAW_SINGLE;
+          break;
+        }
+        case SDLK_3:
+        {
+          printf("Setting tree depth = 3\n");
+          depth = 3;
+          int temp = drawMode & DRAW_ALL;
+          drawMode ^= temp;
+          drawMode |= DRAW_SINGLE;
+          break;
+        }
+        case SDLK_4:
+        {
+          printf("Setting tree depth = 4\n");
+          depth = 4;
+          int temp = drawMode & DRAW_ALL;
+          drawMode ^= temp;
+          drawMode |= DRAW_SINGLE;
+          break;
+        }
+        case SDLK_5:
+        {
+          printf("Setting tree depth = 5\n");
+          depth = 5;
+          int temp = drawMode & DRAW_ALL;
+          drawMode ^= temp;
+          drawMode |= DRAW_SINGLE;
+          break;
+        }
+        case SDLK_6:
+        {
+          printf("Setting tree depth = 6\n");
+          depth = 6;
+          int temp = drawMode & DRAW_ALL;
+          drawMode ^= temp;
+          drawMode |= DRAW_SINGLE;
+          break;
+        }
+        case SDLK_s:
+          if(drawMode & DRAW_SEPARATING_PLANE)
+          {
+            int temp = drawMode & DRAW_SEPARATING_PLANE;
+            drawMode ^= temp;
+            printf("Removing Separation Plane\n");
+          }
+          else
+          {
+            drawMode |= DRAW_SEPARATING_PLANE;
+            printf("Drawing Separation Plane\n");
+          }
+
+          break;
+        case SDLK_p:
+          if(drawMode & DRAW_BV_POLYGON)
+          {
+            int temp = drawMode & DRAW_BV_POLYGON;
+            drawMode ^= temp;
+            printf("Removing OBB Polygons\n");
+          }
+          else
+          {
+            drawMode |= DRAW_BV_POLYGON;
+            printf("Drawing OBB Polygons\n");
+          }
+          break;
+        case SDLK_o:
+          if(iterata == 0.0f)
+          {
+            iterata = 0.05f;
+          }
+          else
+          {
+            iterata = 0.0f;
+          }
+          break;
+
+      }
+  }
+}
+
+
+void Framework::moduleTick(float dt)
+{
+
+  CDEngine::getInstance()->checkCollisions();
+
+
+ // b->shiftCoor(Vector(0.0, 0.0, iterata * dt * 12.0f));
+
+
+  tIterator<WorldEntity>* iterator = entityList->getIterator();
+  WorldEntity* entity = iterator->firstElement();
+  while( entity != NULL)
+  {
+    if( unlikely(animateModel))
+      entity->tick(dt);
+    entity = iterator->nextElement();
+  }
+  delete iterator;
+}
+
+
+void Framework::moduleDraw() const
+{
+  //CDEngine::getInstance()->debugDraw(depth, drawMode);
+
+  tIterator<WorldEntity>* iterator = entityList->getIterator();
+  WorldEntity* entity = iterator->firstElement();
+  while( entity != NULL)
+  {
+    if( likely(drawModel))
+      entity->draw();
+    entity->drawBVTree(depth, drawMode);
+    printf("%i, %i\n", depth, drawMode);
+    entity = iterator->nextElement();
+  }
+  delete iterator;
+
+  LightManager::getInstance()->draw();
+}
+
+
+void Framework::moduleHelp(void) const
+{
+  printf("\n\n===========================");
+  printf("Collision Detection Modler:\n");
+  printf("Key Bindings:\n");
+  printf(" -| Displaying Polygons\t\t p\n");
+  printf(" -| Displaying Separation Plane\t s\n");
+  printf("\n");
+  printf(" -| Tree Depth 0\t\t 0\n");
+  printf(" -| Tree Depth 1\t\t 1\n");
+  printf(" -| Tree Depth 2\t\t 2\n");
+  printf(" -| Tree Depth 3\t\t 3\n");
+  printf(" -| Tree Depth 4\t\t 4\n");
+  printf(" -| Tree Depth 5\t\t 5\n");
+  printf("===========================\n\n");
+
+}
+
+int boxPolygons(GtkWidget* nonInterest, void* widget)
+{
+  if(drawMode & DRAW_BV_POLYGON)
+  {
+    int temp = drawMode & DRAW_BV_POLYGON;
+    drawMode ^= temp;
+    printf("Removing OBB Polygons\n");
+  }
+  else
+  {
+    drawMode |= DRAW_BV_POLYGON;
+    printf("Drawing OBB Polygons\n");
+  }
+}
+
+int seperatingPlanes(GtkWidget* nonInterest, void* widget)
+{
+  if(drawMode & DRAW_SEPARATING_PLANE)
+  {
+    int temp = drawMode & DRAW_SEPARATING_PLANE;
+    drawMode ^= temp;
+    printf("Removing Separation Plane\n");
+  }
+  else
+  {
+    drawMode |= DRAW_SEPARATING_PLANE;
+    printf("Drawing Separation Plane\n");
+  }
+}
+
+
+int blendedBox(GtkWidget* nonInterest, void* widget)
+{
+  if(drawMode & DRAW_BV_BLENDED)
+  {
+    int temp = drawMode & DRAW_BV_BLENDED;
+    drawMode ^= temp;
+    printf("Removing OBB Polygons\n");
+  }
+  else
+  {
+    drawMode |= DRAW_BV_BLENDED;
+    printf("Drawing OBB Polygons\n");
+  }
+}
+
+
+int drawModels(GtkWidget* nonInterest, void* widget)
+{
+  drawModel = !drawModel;
+}
+
+
+int animateModels(GtkWidget* nonInterest, void* widget)
+{
+  animateModel = !animateModel;
+}
+
+
+int drawPoints(GtkWidget* nonInterest, void* widget)
+{
+  if(drawMode & DRAW_POINTS)
+  {
+    int temp = drawMode & DRAW_POINTS;
+    drawMode ^= temp;
+
+  }
+  else
+  {
+    drawMode |= DRAW_POINTS;
+    printf("Drawing OBB Polygons\n");
+  }
+}
+
+
+int treeDepth(GtkWidget* nonInterest, void* widget)
+{
+  Option* option = (Option*) widget;
+  const char* name = option->getTitle();
+  char* value = option->save();
+
+  depth = atoi(value);
+  printf("Setting tree depth = %i\n", depth);
+  int temp = drawMode & DRAW_ALL;
+  drawMode ^= temp;
+  drawMode |= DRAW_SINGLE;
+
+  delete value;
+}
+
+
+void Framework::moduleInitGui(int argc, char** argv)
+{
+  Window* guiMainWindow = NULL;
+
+  initGUI(0, NULL);
+
+  guiMainWindow = new Window("Collision_detection");
+  {
+    Box* windowBox = new Box('v');
+    {
+      CheckButton* BoxPolygons = new CheckButton("Draw OBB Polygons");
+      BoxPolygons->connectSignal("clicked", (void*)BoxPolygons, boxPolygons);
+      windowBox->fill(BoxPolygons);
+
+
+      CheckButton* BlendedBox = new CheckButton("Draw OBB Blended");
+      BlendedBox->connectSignal("clicked", (void*)BlendedBox, blendedBox);
+      windowBox->fill(BlendedBox);
+
+
+      CheckButton* DrawModels = new CheckButton("Draw Models");
+      DrawModels->connectSignal("clicked", (void*)DrawModels, drawModels);
+      windowBox->fill(DrawModels);
+
+
+
+      CheckButton* AnimateModels = new CheckButton("Animate Models");
+      AnimateModels->connectSignal("clicked", (void*)AnimateModels, animateModels);
+      windowBox->fill(AnimateModels);
+
+
+      CheckButton* DrawPoints = new CheckButton("Draw Points");
+      DrawPoints->connectSignal("clicked", (void*)DrawPoints, drawPoints);
+      windowBox->fill(DrawPoints);
+
+
+      CheckButton* SeperatingPlanes = new CheckButton("SeperatingPlanes");
+      SeperatingPlanes->connectSignal("clicked", (void*)SeperatingPlanes, seperatingPlanes);
+      windowBox->fill(SeperatingPlanes);
+
+
+      Slider* TreeDepth = new Slider("TreeDepth", 0, 17);
+      TreeDepth->connectSignal("value_changed", (void*)TreeDepth, treeDepth);
+      windowBox->fill(TreeDepth);
+    }
+    guiMainWindow->fill(windowBox);
+  }
+  Window::mainWindow->showall();
+  Window::mainWindow->setSize(300, 500);
+}
Index: branches/network/src/subprojects/collision_detection/collision_test_entity.cc
===================================================================
--- branches/network/src/subprojects/collision_detection/collision_test_entity.cc	(revision 6636)
+++ branches/network/src/subprojects/collision_detection/collision_test_entity.cc	(revision 6636)
@@ -0,0 +1,102 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "collision_test_entity.h"
+
+#include "resource_manager.h"
+
+#include "vector.h"
+#include "objModel.h"
+#include "obb_tree.h"
+#include "factory.h"
+
+using namespace std;
+CREATE_FACTORY(CollisionTestEntity, CL_ENVIRONMENT);
+
+/**
+ *  creates an environment
+*/
+CollisionTestEntity::CollisionTestEntity () : WorldEntity()
+{
+  this->init();
+  this->loadModel("models/ships/reaplow.obj");
+  //  this->loadModel("models/ships/figther.obj");
+
+  this->buildObbTree(10);
+}
+
+/**
+ * create an environment out of a XML-element
+ * @param root the XML-element to load the CollisionTestEntity from
+ */
+CollisionTestEntity::CollisionTestEntity(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  deletes an environment
+*/
+CollisionTestEntity::~CollisionTestEntity ()
+{}
+
+/**
+ * initialize an CollisionTestEntity
+ */
+void CollisionTestEntity::init()
+{
+  this->setClassID(CL_ENVIRONMENT, "CollisionTestEntity");
+}
+
+/**
+ * loads the Settings of an CollisionTestEntity from an XML-element.
+ * @param root the XML-element to load the ELements properties from
+ */
+void CollisionTestEntity::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+}
+
+
+/**
+ *  ticks the environment
+ * @param time the time about which to tick
+*/
+void CollisionTestEntity::tick (float time) {}
+
+
+/**
+ *  draws the CollisionTestEntity
+*/
+void CollisionTestEntity::draw ()
+{
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  float matrix[4][4];
+
+  glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z);
+  //rotate
+  this->getAbsDir().matrix (matrix);
+  glMultMatrixf((float*)matrix);
+
+  this->model->draw();
+
+  glPopMatrix();
+}
+
Index: branches/network/src/subprojects/collision_detection/collision_test_entity.h
===================================================================
--- branches/network/src/subprojects/collision_detection/collision_test_entity.h	(revision 6636)
+++ branches/network/src/subprojects/collision_detection/collision_test_entity.h	(revision 6636)
@@ -0,0 +1,36 @@
+/*!
+  \file collision_test_entity.h
+  \brief This file handles the collision_test_entity of the game
+*/
+
+#ifndef _COLLISION_TEST_ENTITY_H
+#define _COLLISION_TEST_ENTITY_H
+
+#include "world_entity.h"
+
+//! collision_test_entity of orxonox
+/**
+   everything that does not interact with the player comes here
+   Collision_Test_Entity is a container for all the worldEntities that are non-interactive
+*/
+class CollisionTestEntity : public WorldEntity
+{
+  friend class World;
+
+ public:
+  CollisionTestEntity ();
+  CollisionTestEntity (const TiXmlElement* root);
+  virtual ~CollisionTestEntity ();
+
+  void init();
+  virtual void loadParams(const TiXmlElement* root);
+
+
+
+  virtual void tick (float time);
+
+  virtual void draw ();
+
+};
+
+#endif /* _COLLISION_TEST_ENTITY_H */
Index: branches/network/src/subprojects/framework.cc
===================================================================
--- branches/network/src/subprojects/framework.cc	(revision 6636)
+++ branches/network/src/subprojects/framework.cc	(revision 6636)
@@ -0,0 +1,352 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#include "framework.h"
+
+
+#include "p_node.h"
+#include "state.h"
+#include "debug.h"
+#include "light.h"
+#include "resource_manager.h"
+#include "camera.h"
+#include "parser/ini_parser/ini_parser.h"
+#include "globals.h"
+
+int verbose;
+
+void Framework::init(void)
+{
+  // create parser
+
+  char* configFileName = ResourceManager::homeDirCheck(DEFAULT_CONFIG_FILE);
+
+  IniParser iniParser (configFileName);
+  delete configFileName;
+
+  GraphicsEngine::getInstance()->initFromIniFile(&iniParser);
+
+  LightManager::getInstance();
+
+  const char* dataPath;
+  if ((dataPath = iniParser.getVar(CONFIG_NAME_DATADIR, CONFIG_SECTION_DATA))!= NULL)
+  {
+    if (!ResourceManager::getInstance()->setDataDir(dataPath))
+    {
+      PRINTF(1)("Data Could not be located\n");
+      exit(-1);
+    }
+  }
+
+  if (!ResourceManager::getInstance()->verifyDataDir(DEFAULT_DATA_DIR_CHECKFILE))
+  {
+    PRINTF(1)("The DataDirectory %s could not be verified\n" \
+        "  Please Change in File %s Section %s Entry %s to a suitable value\n",
+    ResourceManager::getInstance()->getDataDir(),
+    DEFAULT_CONFIG_FILE,
+    CONFIG_SECTION_DATA,
+    CONFIG_NAME_DATADIR);
+    exit(-1);
+  }
+}
+
+
+void* Framework::mainLoop(void* tmp)
+{
+  Framework* framework = Framework::getInstance();
+  while(!framework->isFinished)
+    {
+#ifdef GUI_MODULE
+      while(gtk_events_pending())
+        gtk_main_iteration();
+#endif
+      // keyhandler returns false if sdl gets quit by some event
+      framework->eventHandler();
+
+      // tick the scene
+      float dt = framework->tick();
+
+      PNode::getNullParent()->updateNode(dt);
+
+      // Draw the scene
+      framework->draw(dt);
+
+    }
+}
+
+bool Framework::draw(float dt)
+{
+  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+  glLoadIdentity(); // Reset the view
+
+  this->moduleDraw();
+
+  camera->apply();
+
+  SDL_GL_SwapBuffers(); // Swap the buffers
+}
+
+
+float Framework::tick()
+{
+  currFrame = SDL_GetTicks();
+  float dt = (float)(currFrame - lastFrame) / 1000.0;
+  lastFrame = currFrame;
+
+  this->moduleTick(dt);
+
+  return dt;
+}
+
+
+bool Framework::eventHandler()
+{
+  // This is the main loop for the entire program and it will run until done==TRUE
+  {
+    // And poll for events
+    SDL_Event event;
+    while(SDL_PollEvent(&event))
+    {
+      moduleEventHandler(&event);
+
+      switch (event.type) {
+      case SDL_MOUSEMOTION:
+        {
+          Vector view = camera->getTarget()->getAbsCoor() - camera->getAbsCoor();
+          Vector up = Vector(0, 1, 0);
+          up = camera->getAbsDir().apply(up);
+          Vector h = up.cross(view);
+          Vector v = h.cross(view);
+          h.normalize();
+          v.normalize();
+          float distance = view.len();
+
+          Vector newCameraPos = camera->getAbsCoor();
+          Vector newTargetPos = camera->getTarget()->getAbsCoor();
+          int changed = 0;
+
+          if (mouseDown[1])
+            {
+              newCameraPos = camera->getRelCoor()+ (h * event.motion.xrel - v * event.motion.yrel) * .005 * distance;
+              changed += 1;
+            }
+          if (mouseDown[3])
+            {
+              newTargetPos = camera->getTarget()->getRelCoor() + (h * event.motion.xrel - v * event.motion.yrel) * .005 * distance;
+              changed += 2;
+            }
+
+          Vector newView = newTargetPos - newCameraPos;
+
+          if (changed == 1)
+            camera->setRelCoor(newCameraPos + newView * (1- distance/newView.len()));
+          else if (changed == 2)
+            camera->getTarget()->setRelCoor(newTargetPos - newView * (1-distance/newView.len()));
+          else if (changed == 3)
+            {
+              camera->setRelCoor(newCameraPos);
+              camera->getTarget()->setRelCoor(newTargetPos);
+            }
+
+        }
+        break;
+      case SDL_MOUSEBUTTONDOWN:
+        switch (event.button.button)
+          {
+          case 4:
+            PRINTF(4)("MouseWheel up\n");
+            camera->setRelCoor(camera->getRelCoor() + (camera->getTarget()->getAbsCoor() - camera->getAbsCoor())*.1);
+            break;
+          case 5:
+            PRINTF(4)("MouseWheel down\n");
+            camera->setRelCoor(camera->getRelCoor() - (camera->getTarget()->getAbsCoor() - camera->getAbsCoor())*.1);
+            break;
+          case 1:
+          case 2:
+          case 3:
+            mouseDown[event.button.button] = true;
+            break;
+          }
+
+        break;
+      case SDL_MOUSEBUTTONUP:
+        switch (event.button.button)
+          {
+          case 1:
+          case 2:
+          case 3:
+            mouseDown[event.button.button] = false;
+            break;
+          }
+        break;
+      case SDL_VIDEORESIZE:
+        GraphicsEngine::getInstance()->resolutionChanged(event.resize);
+        break;
+      case SDL_KEYDOWN:
+        switch (event.key.keysym.sym)
+          {
+          case SDLK_q:
+          case SDLK_ESCAPE:
+#ifdef GUI_MODULE
+            quitGui(NULL, NULL);
+#else
+            this->quit();
+#endif
+            break;
+          case SDLK_a:
+            camera->setRelCoor(camera->getRelCoor() + (camera->getTarget()->getAbsCoor() - camera->getAbsCoor())*.1);
+            break;
+          case SDLK_z:
+            camera->setRelCoor(camera->getRelCoor() - (camera->getTarget()->getAbsCoor() - camera->getAbsCoor())*.1);
+            break;
+          case SDLK_r:
+            camera->setAbsCoor(Vector(10, 10, 10));
+            camera->getTarget()->setAbsCoor(Vector());
+            break;
+          case SDLK_h:
+            this->printHelp();
+            break;
+          case SDLK_c:
+            for (int i = 0; i < 3; i++)
+              {
+                backgroundColor[i] += .1;
+                if (backgroundColor[i] > 1.0)
+                  backgroundColor[i] = 1.0;
+                GraphicsEngine::setBackgroundColor(backgroundColor[0], backgroundColor[1], backgroundColor[2], backgroundColor[3]);
+              }
+            break;
+          case SDLK_x:
+            for (int i = 0; i < 3; i++)
+              {
+                backgroundColor[i] -= .1;
+                if (backgroundColor[i] < 0.0)
+                  backgroundColor[i] = 0.0;
+                GraphicsEngine::setBackgroundColor(backgroundColor[0], backgroundColor[1], backgroundColor[2], backgroundColor[3]);
+              }
+            break;
+          }
+        break;
+
+        // If a quit event was recieved
+      case SDL_QUIT:
+        // then we're done and we'll end this program
+#ifdef GUI_MODULE
+            quitGui(NULL, NULL);
+#else
+            this->quit();
+#endif
+        break;
+      default:
+        break;
+      }
+
+    }
+
+    // Get the state of the keyboard keys
+    keys = SDL_GetKeyState(NULL);
+
+    // and check if ESCAPE has been pressed. If so then quit
+    if(keys[SDLK_ESCAPE]) return false;
+  }
+  return true;
+}
+
+void Framework::quit(void)
+{
+  this->isFinished = true;
+}
+
+Framework* Framework::singletonRef = NULL;
+
+Framework::Framework()
+{
+  this->init();
+
+  camera = new Camera();
+  State::setCamera(camera, camera->getTarget());
+  camera->setAbsCoor(Vector(10, 10, 10));
+
+  this->isFinished = false;
+
+  this->lastFrame = 0;
+
+
+  // Build the font from a TGA image font.tga in the data directory
+  // Hide the mouse cursor
+  SDL_ShowCursor(2);
+
+  for (int i = 0; i < MOUSE_BUTTON_COUNT; i++)
+    mouseDown[i] = false;
+  for (int i = 0; i < 4; i++)
+    backgroundColor[i] = 0;
+}
+
+Framework::~Framework()
+{
+  delete GraphicsEngine::getInstance();
+
+}
+
+
+
+void Framework::printHelp(void) const
+{
+  PRINT(0)(" Help for the frameWork\n");
+  PRINT(0)("========================\n");
+  PRINT(0)("h - print this Help\n");
+  PRINT(0)("a - zoom in\n");
+  PRINT(0)("z - zoom out\n");
+  PRINT(0)("r - reset camera position\n");
+  PRINT(0)("x - background color darker\n");
+  PRINT(0)("c - background color brighter\n");
+
+
+  PRINT(0)("\n");
+  PRINT(0)("mouse wheel - zoom\n");
+  PRINT(0)("mouse left button - rotate the camera around its target\n");
+  PRINT(0)("mouse right button - rotate the camera's target around the camera\n");
+  PRINT(0)("mouse left-and-right button - move the camera and the target\n");
+
+  this->moduleHelp();
+
+}
+
+#ifdef GUI_MODULE
+int quitGui(GtkWidget* widget, void* data)
+{
+#ifdef HAVE_GTK2
+  while(gtk_events_pending()) gtk_main_iteration();
+  Framework::getInstance()->quit();
+#endif /* HAVE_GTK2 */
+}
+#endif
+
+int main(int argc, char *argv[])
+{
+  verbose = 3;
+
+  Framework* framework = Framework::getInstance();
+
+  framework->moduleInit(argc, argv);
+#ifdef GUI_MODULE
+  framework->moduleInitGui(argc, argv);
+#endif
+  framework->mainLoop(NULL);
+
+  delete framework;
+  // Kill the GL & SDL screens
+  // And quit
+  return 0;
+}
Index: branches/network/src/subprojects/framework.h
===================================================================
--- branches/network/src/subprojects/framework.h	(revision 6636)
+++ branches/network/src/subprojects/framework.h	(revision 6636)
@@ -0,0 +1,73 @@
+#ifndef _FRAMEWORK_H
+#define _FRAMEWORK_H
+
+#include "vector.h"
+#include "glincl.h"
+#include "debug.h"
+#include "graphics_engine.h"
+
+#ifdef GUI_MODULE
+#include "gui_gtk.h"
+#endif
+
+#define MOUSE_BUTTON_COUNT 3
+
+class Camera;
+
+class Framework {
+  public:
+    ~Framework();
+
+    /** \returns a Pointer to the only object of this Class */
+    inline static    Framework* getInstance(void) { if (!singletonRef) singletonRef = new Framework();  return singletonRef; };
+
+  public:
+    void             moduleInit(int argc, char** argv);
+#ifdef GUI_MODULE
+    void             moduleInitGui(int argc, char** argv);
+#endif
+    void             moduleEventHandler(SDL_Event* event);
+  void               moduleTick(float dt);
+  void               moduleDraw(void) const;
+
+  void               moduleHelp(void) const;
+
+
+  void               init(void);
+  static void*       mainLoop(void* tmp);
+  bool               draw(float dt);
+  float              tick();
+  bool               eventHandler();
+  void               quit();
+
+  static void*       mainloopGui(void* tmp);
+
+  void               printHelp(void) const;
+
+
+  private:
+    Framework();
+
+  private:
+    static Framework*           singletonRef;
+
+    Camera*                     camera;
+
+    bool                        isFinished;
+
+    int                         movement [4];
+    float                       backgroundColor[4];
+
+    Uint32                      lastFrame;
+    Uint32                      currFrame;
+
+    Uint8*                      keys;        // This variable will be used in the keyboard routine
+    bool                        mouseDown[MOUSE_BUTTON_COUNT];
+
+};
+
+#ifdef GUI_MODULE
+int quitGui(GtkWidget* widget, void* data);
+#endif
+
+#endif /* _FRAMEWORK_H */
Index: branches/network/src/subprojects/importer/Makefile.am
===================================================================
--- branches/network/src/subprojects/importer/Makefile.am	(revision 6636)
+++ branches/network/src/subprojects/importer/Makefile.am	(revision 6636)
@@ -0,0 +1,98 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+importer_CPPFLAGS =
+
+importer_LDFLAGS = $(MWINDOWS)
+
+bin_PROGRAMS = importer \
+               multitex \
+							 movie_player_test
+
+importer_LDADD = \
+		$(MAINSRCDIR)/lib/network/libORXnet.a \
+		$(MAINSRCDIR)/lib/event/libORXevent.a \
+                $(MAINSRCDIR)/lib/parser/tinyxml/libtinyxml.a \
+                $(MAINSRCDIR)/lib/graphics/libORXgraphics.a \
+                $(MAINSRCDIR)/lib/shell/libORXshell.a \
+		$(MAINSRCDIR)/lib/sound/libORXsound.a \
+		$(MAINSRCDIR)/lib/graphics/importer/libORXimporter.a
+
+importer_SOURCES= ../framework.cc \
+                  importer.cc \
+		  tc.cc \
+                  $(MAINSRCDIR)/util/state.cc \
+                  $(MAINSRCDIR)/world_entities/camera.cc \
+                  $(MAINSRCDIR)/lib/lang/base_object.cc \
+                  $(MAINSRCDIR)/lib/lang/class_list.cc \
+                  $(MAINSRCDIR)/lib/math/vector.cc \
+                  $(MAINSRCDIR)/lib/math/quaternion.cc \
+                  $(MAINSRCDIR)/util/loading/resource_manager.cc \
+                  $(MAINSRCDIR)/lib/parser/ini_parser/ini_parser.cc \
+                  $(MAINSRCDIR)/lib/coord/p_node.cc \
+                  $(MAINSRCDIR)/util/loading/load_param.cc \
+                  $(MAINSRCDIR)/util/loading/load_param_description.cc \
+                  $(MAINSRCDIR)/lib/util/helper_functions.cc \
+                  $(MAINSRCDIR)/lib/util/substring.cc \
+                  $(MAINSRCDIR)/lib/util/color.cc \
+                  $(MAINSRCDIR)/lib/util/multi_type.cc \
+                  $(MAINSRCDIR)/lib/util/executor/executor.cc \
+                  $(MAINSRCDIR)/util/loading/factory.cc
+
+
+
+multitex_LDADD = $(MAINSRCDIR)/lib/event/libORXevent.a \
+		 $(MAINSRCDIR)/lib/network/libORXnet.a \
+                 $(MAINSRCDIR)/lib/parser/tinyxml/libtinyxml.a \
+                 $(MAINSRCDIR)/lib/graphics/libORXgraphics.a \
+                 $(MAINSRCDIR)/lib/shell/libORXshell.a \
+                 $(MAINSRCDIR)/lib/sound/libORXsound.a \
+                 $(MAINSRCDIR)/lib/graphics/importer/libORXimporter.a
+
+multitex_SOURCES= ../framework.cc \
+                  multitex.cc \
+                  $(MAINSRCDIR)/util/state.cc \
+                  $(MAINSRCDIR)/world_entities/camera.cc \
+                  $(MAINSRCDIR)/lib/lang/base_object.cc \
+                  $(MAINSRCDIR)/lib/lang/class_list.cc \
+                  $(MAINSRCDIR)/lib/math/vector.cc \
+                  $(MAINSRCDIR)/lib/math/quaternion.cc \
+                  $(MAINSRCDIR)/util/loading/resource_manager.cc \
+                  $(MAINSRCDIR)/lib/parser/ini_parser/ini_parser.cc \
+                  $(MAINSRCDIR)/lib/coord/p_node.cc \
+                  $(MAINSRCDIR)/util/loading/load_param.cc \
+                  $(MAINSRCDIR)/util/loading/load_param_description.cc \
+                  $(MAINSRCDIR)/lib/util/helper_functions.cc \
+                  $(MAINSRCDIR)/lib/util/substring.cc \
+                  $(MAINSRCDIR)/lib/util/color.cc \
+                  $(MAINSRCDIR)/lib/util/multi_type.cc \
+                  $(MAINSRCDIR)/lib/util/executor/executor.cc \
+                  $(MAINSRCDIR)/util/loading/factory.cc
+
+movie_player_test_LDADD = $(MAINSRCDIR)/lib/event/libORXevent.a \
+		$(MAINSRCDIR)/lib/network/libORXnet.a \
+			$(MAINSRCDIR)/lib/parser/tinyxml/libtinyxml.a \
+                 					$(MAINSRCDIR)/lib/graphics/libORXgraphics.a \
+                 					$(MAINSRCDIR)/lib/shell/libORXshell.a \
+                 					$(MAINSRCDIR)/lib/sound/libORXsound.a \
+                 					$(MAINSRCDIR)/lib/graphics/importer/libORXimporter.a
+
+movie_player_test_SOURCES= ../framework.cc \
+                  				 movie_player_test.cc \
+                  				 $(MAINSRCDIR)/util/state.cc \
+                  				 $(MAINSRCDIR)/world_entities/camera.cc \
+                  				 $(MAINSRCDIR)/lib/lang/base_object.cc \
+													 $(MAINSRCDIR)/lib/lang/class_list.cc \
+													 $(MAINSRCDIR)/lib/math/vector.cc \
+													 $(MAINSRCDIR)/util/loading/resource_manager.cc \
+													 $(MAINSRCDIR)/lib/parser/ini_parser/ini_parser.cc \
+													 $(MAINSRCDIR)/lib/coord/p_node.cc \
+													 $(MAINSRCDIR)/lib/coord/null_parent.cc \
+													 $(MAINSRCDIR)/util/loading/load_param.cc \
+													 $(MAINSRCDIR)/util/loading/load_param_description.cc \
+													 $(MAINSRCDIR)/lib/util/helper_functions.cc \
+													 $(MAINSRCDIR)/lib/util/substring.cc \
+													 $(MAINSRCDIR)/lib/util/color.cc \
+													 $(MAINSRCDIR)/lib/util/multi_type.cc \
+													 $(MAINSRCDIR)/lib/util/executor/executor.cc \
+													 $(MAINSRCDIR)/util/loading/factory.cc
Index: branches/network/src/subprojects/importer/importer.cc
===================================================================
--- branches/network/src/subprojects/importer/importer.cc	(revision 6636)
+++ branches/network/src/subprojects/importer/importer.cc	(revision 6636)
@@ -0,0 +1,106 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+
+   this file extends the framework file, so it renders what i want.
+*/
+
+#include "framework.h"
+
+#include "light.h"
+
+#include "objModel.h"
+#include "md2Model.h"
+#include "primitive_model.h"
+#include <stdlib.h>
+
+#include "vertex_array_model.h"
+
+#include "resource_manager.h"
+
+Model* obj;
+
+void Framework::moduleInit(int argc, char** argv)
+{
+  ResourceManager::getInstance()->addImageDir("./");
+
+  for (int i = 0; i < argc; i++)
+  {
+    printf("%s\n", argv[i]);
+  }
+  ResourceManager::getInstance()->addImageDir("");
+
+
+  if (argc>=3)
+  {
+    if( strstr(argv[1], ".obj") != NULL)
+      obj = new OBJModel (argv[1], atof(argv[2]));
+    else if( strstr(argv[1], ".md2") != NULL)
+    {
+      obj = new MD2Model(argv[1], argv[2]);
+      ((MD2Model*)obj)->tick(0.1f);
+    }
+  }
+  else if (argc>=2)
+  {
+    if( strstr(argv[1], ".obj") != NULL)
+      obj = new OBJModel(argv[1]);
+    else if( strstr(argv[1], ".md2") != NULL) {
+      obj = new MD2Model(argv[1], "fake_texture.bad");
+      obj = new MD2Model(argv[1], argv[2]);
+      ((MD2Model*)obj)->tick(0.1f);
+    }
+  }
+  else
+    obj = new PrimitiveModel(PRIM_CYLINDER);
+
+  obj = new VertexArrayModel(*obj);
+
+  ResourceManager::getInstance()->debug();
+
+  LightManager* lightMan = LightManager::getInstance();
+  lightMan->setAmbientColor(.1,.1,.1);
+  (new Light())->setAbsCoor(5.0, 10.0, 40.0);
+  (new Light())->setAbsCoor(-10, -20, -100);
+}
+
+void Framework::moduleEventHandler(SDL_Event* event)
+{
+  switch (event->type)
+    {
+    case SDL_KEYDOWN:
+      switch (event->key.keysym.sym)
+        {
+        case SDLK_i:
+          break;
+        }
+    }
+}
+
+void Framework::moduleTick(float dt)
+{
+
+}
+
+void Framework::moduleDraw(void) const
+{
+  obj->draw();
+
+  LightManager::getInstance()->draw();
+}
+
+
+void Framework::moduleHelp(void) const
+{
+
+}
Index: branches/network/src/subprojects/importer/movie_player_test.cc
===================================================================
--- branches/network/src/subprojects/importer/movie_player_test.cc	(revision 6636)
+++ branches/network/src/subprojects/importer/movie_player_test.cc	(revision 6636)
@@ -0,0 +1,85 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: David Hasenfratz
+   co-programmer: ...
+
+   this file extends the framework file, so it renders what i want.
+*/
+
+#include <stdlib.h>
+
+#include "framework.h"
+#include "movie_player.h"
+
+MoviePlayer* movie_player;
+
+void Framework::moduleInit(int argc, char** argv)
+{
+  if( argc <= 1)
+  {
+    printf("Wrong arguments try following notations:\n");
+    printf("./movie_player_test [media_file]\n");
+    exit(0);
+  }
+
+  movie_player = new MoviePlayer(argv[1]);
+
+  
+  movie_player->printInformation();
+}
+
+void Framework::moduleEventHandler(SDL_Event* event)
+{
+  switch (event->type)
+  {
+    case SDL_KEYDOWN:
+      switch (event->key.keysym.sym)
+      {
+        case SDLK_1:
+          movie_player->start(0);
+          break;
+        case SDLK_2:
+          movie_player->resume();
+          break;
+        case SDLK_3:
+          movie_player->pause();
+          break;
+        case SDLK_4:
+          movie_player->stop();
+          break;
+        case SDLK_9:
+          movie_player->setFPS(movie_player->getFPS() - 1);
+          PRINTF(0)("fps: %0.2f\n", movie_player->getFPS());
+          break;
+        case SDLK_0:
+          movie_player->setFPS(movie_player->getFPS() + 1);
+          PRINTF(0)("fps: %0.2f\n", movie_player->getFPS());
+          break;
+      }
+  }
+}
+
+void Framework::moduleTick(float dt)
+{
+  movie_player->tick(dt);
+}
+
+void Framework::moduleDraw(void) const
+{
+  movie_player->draw();
+}
+
+
+void Framework::moduleHelp(void) const
+{
+
+}
Index: branches/network/src/subprojects/importer/multitex.cc
===================================================================
--- branches/network/src/subprojects/importer/multitex.cc	(revision 6636)
+++ branches/network/src/subprojects/importer/multitex.cc	(revision 6636)
@@ -0,0 +1,119 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: David Hasenfratz
+   co-programmer: ...
+
+   this file extends the framework file, so it renders what i want.
+*/
+
+#include "framework.h"
+
+#include "light.h"
+
+#include "material.h"
+#include "primitive_model.h"
+#include <stdlib.h>
+
+#include "media_container.h"
+
+Model* obj;
+Material* testMat;
+MediaContainer* media_container;
+
+int counter = 0;
+float timer = 0;
+float fps;
+
+
+void Framework::moduleInit(int argc, char** argv)
+{
+  if( argc <= 1)
+  {
+    printf("Wrong arguments try following notations:\n");
+    printf("./multitex [media_file]\n");
+    exit(0);
+  }
+
+  media_container = new MediaContainer(argv[1]);
+
+  testMat = new Material;
+  testMat->setDiffuseMap("maps/radialTransparency.png");
+  obj = new PrimitiveModel(PRIM_PLANE, 10.0);
+
+  LightManager* lightMan = LightManager::getInstance();
+  lightMan->setAmbientColor(.1,.1,.1);
+  (new Light())->setAbsCoor(5.0, 10.0, 40.0);
+  (new Light())->setAbsCoor(-10, -20, -100);
+
+  fps = media_container->getFPS();
+}
+
+void Framework::moduleEventHandler(SDL_Event* event)
+{
+  switch (event->type)
+    {
+    case SDL_KEYDOWN:
+      switch (event->key.keysym.sym)
+        {
+        case SDLK_1:
+          obj = new PrimitiveModel(PRIM_CUBE, 10.0);
+          break;
+        case SDLK_2:
+          obj = new PrimitiveModel(PRIM_SPHERE, 10.0);
+          break;
+        case SDLK_3:
+          obj = new PrimitiveModel(PRIM_PLANE, 10.0);
+          break;
+        // increase fps
+        case SDLK_9:
+          fps++;
+          PRINTF(0)("fps: %0.2f\n", fps);
+          break;
+        // decrease fps
+        case SDLK_8:
+          if(fps > 0)
+            fps--;
+          PRINTF(0)("fps: %0.2f\n", fps);
+          break;
+        }
+    }
+}
+
+void Framework::moduleTick(float dt)
+{
+  timer += dt;
+
+  if(counter != fps * timer)
+  {
+    counter = fps * timer;
+
+    if (counter >= media_container->getFrameCount())
+    {
+      timer = 0;
+      counter = 0;
+    }
+  }
+}
+
+void Framework::moduleDraw(void) const
+{
+  testMat->select();
+  glBindTexture(GL_TEXTURE_2D, media_container->getFrameTexture(counter));
+  obj->draw();
+
+  LightManager::getInstance()->draw();
+}
+
+void Framework::moduleHelp(void) const
+{
+
+}
Index: branches/network/src/subprojects/importer/tc.cc
===================================================================
--- branches/network/src/subprojects/importer/tc.cc	(revision 6636)
+++ branches/network/src/subprojects/importer/tc.cc	(revision 6636)
@@ -0,0 +1,1448 @@
+/*
+ * $Header: /home/grantham/cvsroot/projects/modules/tc/tc.c,v 1.27 2000/10/10 16:09:23 grantham Exp $
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include "tc.h"
+
+/* SNIPPET "table.c" Inducted Wed Nov 22 09:36:55 2000 */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#if !defined(MEM_CHART)
+#define chartedSetLabel(a)
+#endif
+
+#define LEVEL1COUNT 16384
+#define LEVEL2COUNT 1024
+#define LEVEL3COUNT 256
+
+typedef struct TableLevel3
+{
+    int EntryCount;
+    void *Table[LEVEL3COUNT];
+    char IsSet[LEVEL3COUNT];
+} TableLevel3;
+
+typedef struct TableLevel2
+{
+    int EntryCount;
+    TableLevel3 *Table[LEVEL2COUNT];
+} TableLevel2;
+
+typedef struct TableRoot
+{
+    size_t EntryCount;
+    size_t TotalEntryCount;
+    size_t TotalAllocatedBytes;
+    int EmptyEntryCount;
+    TableLevel2 *Table[LEVEL1COUNT];
+} TableRoot;
+
+typedef struct TableIterator {
+    int i1, i2, i3;
+    unsigned int i;
+    TableLevel3 *CurLevel3;
+    int CheckLevel1, CheckLevel2;
+} TableIterator;
+
+TableRoot *tableNew(void)
+{
+    TableRoot *tr;
+
+    chartedSetLabel("table root");
+    tr = (TableRoot *)calloc(sizeof(TableRoot), 1);
+    return tr;
+}
+
+TableIterator *tableNewIterator(void)
+{
+    TableIterator *ti;
+
+    chartedSetLabel("table iterator");
+    ti = (TableIterator *)malloc(sizeof(TableIterator));
+    return ti;
+}
+
+int tableRetrieve(unsigned int a, TableRoot *table, void **ref)
+{
+    int i1 = a / (LEVEL2COUNT * LEVEL3COUNT);
+    int i2 = (a / LEVEL3COUNT) % LEVEL2COUNT;
+    int i3 = a % LEVEL3COUNT;
+
+    if(table->Table[i1] == NULL)
+        return 0;
+    if(table->Table[i1]->Table[i2] == NULL)
+        return 0;
+    if(!table->Table[i1]->Table[i2]->IsSet[i3])
+        return 0;
+    if(ref != NULL)
+        *ref = table->Table[i1]->Table[i2]->Table[i3];
+    return 1;
+}
+
+int tableInsert(unsigned int a, TableRoot *table, void *ref)
+{
+    int i1 = a / (LEVEL2COUNT * LEVEL3COUNT);
+    int i2 = (a / LEVEL3COUNT) % LEVEL2COUNT;
+    int i3 = a % LEVEL3COUNT;
+
+    if(table->Table[i1] == NULL) {
+        chartedSetLabel("table level 2");
+        table->Table[i1] = (TableLevel2 *)calloc(1, sizeof(TableLevel2));
+        table->TotalAllocatedBytes += sizeof(TableLevel2);
+        if(table->Table[i1] == NULL)
+            return 0;
+    }
+    if(table->Table[i1]->Table[i2] == NULL) {
+        chartedSetLabel("table level 3");
+        table->Table[i1]->Table[i2] =
+            (TableLevel3 *)calloc(1, sizeof(TableLevel3));
+        table->TotalAllocatedBytes += sizeof(TableLevel3);
+        if(table->Table[i1]->Table[i2] == NULL)
+            return 0;
+        table->Table[i1]->EntryCount++;
+        table->TotalEntryCount += LEVEL3COUNT;
+        table->EmptyEntryCount += LEVEL3COUNT;
+    }
+    if(!table->Table[i1]->Table[i2]->IsSet[i3]) {
+        table->Table[i1]->Table[i2]->EntryCount++;
+        table->EmptyEntryCount --;
+        table->Table[i1]->Table[i2]->IsSet[i3] = 1;
+    }
+    table->Table[i1]->Table[i2]->Table[i3] = ref;
+    return 1;
+}
+
+int tableRemove(unsigned int a, TableRoot *table, void **wasref)
+{
+    int i1 = a / (LEVEL2COUNT * LEVEL3COUNT);
+    int i2 = (a / LEVEL3COUNT) % LEVEL2COUNT;
+    int i3 = a % LEVEL3COUNT;
+
+    if(table->Table[i1] == NULL)
+        return 0;
+    if(table->Table[i1]->Table[i2] == NULL)
+        return 0;
+    if(!table->Table[i1]->Table[i2]->IsSet[i3])
+        return 0;
+    if(wasref != NULL)
+        *wasref = table->Table[i1]->Table[i2]->Table[i3];
+    table->Table[i1]->Table[i2]->IsSet[i3] = 0;
+    table->EmptyEntryCount ++;
+    if(--table->Table[i1]->Table[i2]->EntryCount == 0) {
+        table->EmptyEntryCount -= LEVEL3COUNT;
+        table->TotalEntryCount -= LEVEL3COUNT;
+        free(table->Table[i1]->Table[i2]);
+        table->TotalAllocatedBytes -= sizeof(TableLevel3);
+        table->Table[i1]->Table[i2] = NULL;
+        if(--table->Table[i1]->EntryCount == 0) {
+            table->TotalAllocatedBytes -= sizeof(TableLevel2);
+            free(table->Table[i1]);
+            table->Table[i1] = NULL;
+        }
+    }
+    return 1;
+}
+
+void tableResetIterator(TableIterator *ti)
+{
+    ti->i1 = 0;
+    ti->i2 = 0;
+    ti->i3 = 0;
+    ti->i = 0;
+    ti->CheckLevel1 = 1;
+    ti->CheckLevel2 = 1;
+}
+
+int tableIterate(TableRoot *table, TableIterator *ti, unsigned int *i, void **ref)
+{
+    int done;
+
+    done = 0;
+    while(ti->i1 < LEVEL1COUNT) {
+        if(ti->CheckLevel1 && table->Table[ti->i1] == NULL) {
+            ti->i += LEVEL2COUNT * LEVEL3COUNT;
+            ti->i1++;
+            continue;
+        } else
+            ti->CheckLevel1 = 0;
+        if(ti->CheckLevel2 && table->Table[ti->i1]->Table[ti->i2] == NULL) {
+            ti->i += LEVEL3COUNT;
+            if(++ti->i2 >= LEVEL2COUNT) {
+                ti->i2 = 0;
+                ti->i1++;
+                ti->CheckLevel1 = 1;
+            }
+            continue;
+        } else
+            ti->CheckLevel2 = 0;
+        if(ti->i3 == 0)
+            ti->CurLevel3 = table->Table[ti->i1]->Table[ti->i2];
+        if(ti->CurLevel3->IsSet[ti->i3]) {
+            if(ref != NULL)
+                *ref = ti->CurLevel3->Table[ti->i3];
+            if(i != NULL)
+                *i = ti->i;
+            done = 1;
+        }
+        ti->i++;
+        if(++ti->i3 >= LEVEL3COUNT) {
+            ti->i3 = 0;
+            ti->CheckLevel2 = 1;
+            if(++ti->i2 >= LEVEL2COUNT) {
+                ti->i2 = 0;
+                ti->i1++;
+                ti->CheckLevel1 = 1;
+            }
+        }
+        if(done)
+            return 1;
+    }
+    return 0;
+}
+
+void tableDelete(TableRoot *table, void (*datumDelete)(void *datum))
+{
+    int i1, i2, i3;
+
+    for(i1 = 0; i1 < LEVEL1COUNT; i1++) {
+        if(table->Table[i1] != NULL) {
+            for(i2 = 0; i2 < LEVEL2COUNT; i2++) {
+                if(table->Table[i1]->Table[i2] != NULL) {
+                    for(i3 = 0; i3 < LEVEL3COUNT; i3++) {
+                        if(table->Table[i1]->Table[i2]->IsSet[i3])
+                            datumDelete(table->Table[i1]->Table[i2]->Table[i3]);
+                    }
+                    free(table->Table[i1]->Table[i2]);
+                }
+            }
+            free(table->Table[i1]);
+            table->Table[i1] = NULL;
+        }
+    }
+    table->TotalEntryCount = 0;
+    table->EmptyEntryCount = 0;
+    table->TotalAllocatedBytes = 0;
+}
+
+void tableGetStats(TableRoot *table, size_t *totalBytes, size_t *emptyCount,
+    size_t *totalCount)
+{
+    if(emptyCount != NULL)
+        *emptyCount = table->EmptyEntryCount;
+    if(totalCount != NULL)
+        *totalCount = table->TotalEntryCount;
+    if(totalBytes != NULL)
+        *totalBytes = table->TotalAllocatedBytes;
+}
+
+size_t tableGetIteratorSize(void)
+{
+    return sizeof(TableIterator);
+}
+
+/* "table.c" ENDSNIPPET */
+
+#if !defined(MEM_CHART)
+#define chartedSetLabel(a)
+#endif
+
+#if defined(DEBUG)
+#define ACTC_DEBUG(a) a
+#else
+#define ACTC_DEBUG(a)
+#endif
+
+#if defined(INFO)
+#define ACTC_INFO(a) a
+#else
+#define ACTC_INFO(a)
+#endif
+
+
+#define ACTC_CHECK(a) \
+    { \
+        int theErrorNow; \
+        theErrorNow = (a); \
+        if(theErrorNow < 0) \
+            return theErrorNow; \
+    }
+
+typedef struct {
+    struct ACTCVertex *FinalVert;
+} ACTCTriangle;
+
+typedef struct {
+    struct ACTCVertex *V2;
+    int Count;
+    int TriangleCount;
+    ACTCTriangle *Triangles;
+} ACTCEdge;
+
+typedef struct ACTCVertex {
+    unsigned int V;
+    int Count;
+    struct ACTCVertex **PointsToMe;
+    struct ACTCVertex *Next;
+    int EdgeCount;
+    ACTCEdge *Edges;
+} ACTCVertex;
+
+/* private tokens */
+#define ACTC_NO_MATCHING_VERT           -0x3000
+#define ACTC_FWD_ORDER                  0
+#define ACTC_REV_ORDER                  1
+
+#define MAX_STATIC_VERTS                10000000 /* buh? */
+
+struct _ACTCData {
+
+    /* vertex and edge database */
+    int VertexCount;
+    TableRoot *Vertices;
+    TableIterator *VertexIterator;
+    int CurMaxVertValence;
+    int CurMinVertValence;
+    ACTCVertex **VertexBins;
+
+    /* alternate vertex array if range small enough */
+    ACTCVertex *StaticVerts;
+    int UsingStaticVerts;
+    unsigned int VertRange;
+
+    /* During consolidation */
+    int CurWindOrder;
+    int PrimType;
+    ACTCVertex *V1;
+    ACTCVertex *V2;
+    int VerticesSoFar;
+
+    /* Error and state handling */
+    int IsInputting;
+    int IsOutputting;
+    int Error;
+
+    /* actcParam-settable parameters */
+    unsigned int MinInputVert;
+    unsigned int MaxInputVert;
+    int MaxVertShare;
+    int MaxEdgeShare;
+    int MinFanVerts;
+    int MaxPrimVerts;
+    int HonorWinding;
+};
+
+#if defined(DEBUG) || defined(INFO)
+
+static void dumpTriangles(ACTCEdge *e, FILE *fp)
+{
+    int i;
+    int c;
+    char v[12];
+
+    c = fprintf(fp, "      %d triangles: ");
+    for(i = 0; i < e->TriangleCount; i++) {
+        if(c + 1 + sprintf(v, "%u", e->Triangles[i].FinalVert) > 78) {
+            fputs("\n", fp);
+            c = fprintf(fp, "        ");
+        }
+        c += fprintf(fp, " %s", v);
+    }
+    fputs("\n", fp);
+}
+
+static void dumpEdges(ACTCVertex *vert, FILE *fp)
+{
+    int i;
+    int c;
+    char v[26]; /* two signed ints plus x plus NUL */
+
+    for(i = 0; i < vert->EdgeCount; i++) {
+        fprintf(fp, "    %u->%u (%d times)\n", vert->V, vert->Edges[i].V2->V,
+            vert->Edges[i].Count);
+        dumpTriangles(&vert->Edges[i], fp);
+    }
+    fputs("\n", fp);
+}
+
+static void dumpVertices(ACTCData *tc, FILE *fp)
+{
+    int i;
+    ACTCVertex *v;
+
+    if(!tc->UsingStaticVerts)
+        tableResetIterator(tc->VertexIterator);
+
+    fprintf(fp, "%d vertices in valences list\n", tc->VertexCount);
+    if(tc->UsingStaticVerts) {
+        for(i = 0; i < tc->VertRange; i++) {
+            v = &tc->StaticVerts[i];
+            if(v->Count > 0) {
+                fprintf(fp, "  vertex %u, valence %d, %d edges\n", v->V,
+                    v->Count, v->EdgeCount);
+                dumpEdges(v, fp);
+            }
+        }
+    } else {
+        for(i = 0; i < tc->VertexCount; i++) {
+            if(tableIterate(tc->Vertices, tc->VertexIterator, NULL,
+                (void **)&v) == 0) {
+                fprintf(fp, "ACTC::dumpVertices : fewer vertices in the table "
+                    "than we expected!\n");
+                fprintf(stderr, "ACTC::dumpVertices : fewer vertices in the table "
+                    "than we expected!\n");
+            }
+            if(v == NULL) {
+                fprintf(fp, "ACTC::dumpVertices : did not expect to get a NULL"
+                    "Vertex from the table iterator!\n");
+                fprintf(stderr, "ACTC::dumpVertices : did not expect to get a NULL"
+                    "Vertex from the table iterator!\n");
+            }
+            fprintf(fp, "  vertex %u, valence %d, %d edges\n", v->V, v->Count,
+                v->EdgeCount);
+            dumpEdges(v, fp);
+        }
+    }
+}
+
+static void dumpVertexBins(ACTCData *tc, FILE *fp)
+{
+    ACTCVertex *cur;
+    int i;
+    int c;
+    char v[26]; /* two signed ints plus x plus NUL */
+
+    fprintf(fp, "vertex bins:\n");
+    if(tc->VertexBins == NULL) {
+        fprintf(fp, "        empty.\n");
+        return;
+    }
+    for(i = 1; i <= tc->CurMaxVertValence; i++) {
+        cur = tc->VertexBins[i];
+        c = fprintf(fp, "        bin %d -> ", i);
+        while(cur != NULL) {
+            if(c + 1 + sprintf(v, "%ux%d", cur->V, cur->Count) > 78) {
+                fputs("\n", fp);
+                c = fprintf(fp, "          ");
+            }
+            c += fprintf(fp, " %s", v);
+            cur = cur->Next;
+        }
+        fputs("\n", fp);
+    }
+}
+
+void actcDumpState(ACTCData *tc, FILE *fp)
+{
+    dumpVertices(tc, fp);
+    dumpVertexBins(tc, fp);
+}
+
+#endif /* DEBUG || INFO */
+
+#if defined(DEBUG)
+
+static int abortWithOptionalDump(ACTCData *tc)
+{
+    ACTC_INFO(actcDumpState(tc, stderr));
+    abort();
+}
+
+#endif /* defined(DEBUG) */
+
+int actcGetError(ACTCData *tc)
+{
+    int error = tc->Error;
+    tc->Error = ACTC_NO_ERROR;
+    return error;
+}
+
+static void *reallocAndAppend(void **ptr, unsigned int *itemCount, size_t itemBytes,
+    void *append)
+{
+    void *t;
+
+    t = realloc(*ptr, itemBytes * (*itemCount + 1));
+    if(t == NULL)
+        return NULL;
+    *ptr = t;
+
+    memcpy((unsigned char *)*ptr + *itemCount * itemBytes, append, itemBytes);
+    (*itemCount) += 1;
+
+    return *ptr;
+}
+
+/*
+ * Call only during input; changes vertices' valences and does not
+ * fix the bins that are ordered by vertex valence.  (It's usually cheaper
+ * to traverse the vertex list once after all are added, since that's
+ * linear in the NUMBER OF UNIQUE VERTEX INDICES, which is almost always
+ * going to be less than the number of vertices.)
+ */
+static int incVertexValence(ACTCData *tc, unsigned int v, ACTCVertex **found)
+{
+    ACTCVertex *vertex;
+
+    if(tc->UsingStaticVerts) {
+        vertex = &tc->StaticVerts[v];
+        vertex->Count++;
+        if(vertex->Count == 1) {
+            vertex->V = v;
+            tc->VertexCount++;
+        }
+    } else {
+        if(tableRetrieve(v, tc->Vertices, (void **)&vertex) == 1) {
+            if(vertex->V != v) {
+                ACTC_DEBUG(
+                    fprintf(stderr, "ACTC::incVertexValence : Got vertex %d when "
+                        "looking for vertex %d?!?\n", vertex->V, v);
+                    abortWithOptionalDump(tc);
+                )
+                return tc->Error = ACTC_DATABASE_CORRUPT;
+            }
+            vertex->Count++;
+        } else {
+            chartedSetLabel("new Vertex");
+            vertex = (ACTCVertex *)malloc(sizeof(ACTCVertex));
+            vertex->V = v;
+            vertex->Count = 1;
+            vertex->Edges = NULL;
+            vertex->EdgeCount = 0;
+            if(tableInsert(v, tc->Vertices, vertex) == 0) {
+                ACTC_DEBUG(fprintf(stderr, "ACTC::incVertexValence : Failed "
+                    "to insert vertex into table\n");)
+                return tc->Error = ACTC_ALLOC_FAILED;
+            }
+            tc->VertexCount++;
+        }
+    }
+    if(vertex->Count > tc->CurMaxVertValence)
+        tc->CurMaxVertValence = vertex->Count;
+
+    *found = vertex;
+
+    return ACTC_NO_ERROR;
+}
+
+static int decVertexValence(ACTCData *tc, ACTCVertex **vptr)
+{
+    ACTCVertex *v = *vptr;
+
+    v->Count--;
+    if(v->Count < 0) {
+        ACTC_DEBUG(
+            fprintf(stderr, "ACTC::decVertexValence : Valence went "
+                "negative?!?\n");
+            abortWithOptionalDump(tc);
+        )
+        return tc->Error = ACTC_DATABASE_CORRUPT;
+    }
+
+    if(v->PointsToMe != NULL) {
+        *v->PointsToMe = v->Next;
+        if(v->Next != NULL)
+            v->Next->PointsToMe = v->PointsToMe;
+        v->Next = NULL;
+    }
+
+    if(v->Count == 0) {
+        tc->VertexCount--;
+        if(v->Edges != NULL)
+            free(v->Edges);
+        if(!tc->UsingStaticVerts) {
+            tableRemove(v->V, tc->Vertices, NULL);
+            free(v);
+        }
+        *vptr = NULL;
+    } else {
+        if(tc->VertexBins != NULL) {
+            v->Next = tc->VertexBins[v->Count];
+            v->PointsToMe = &tc->VertexBins[v->Count];
+            if(v->Next != NULL)
+                v->Next->PointsToMe = &v->Next;
+            tc->VertexBins[v->Count] = v;
+            if(v->Count < tc->CurMinVertValence)
+                tc->CurMinVertValence = v->Count;
+        }
+    }
+
+    return ACTC_NO_ERROR;
+}
+
+static int findNextFanVertex(ACTCData *tc, ACTCVertex **vert)
+{
+    if(tc->CurMaxVertValence < tc->MinFanVerts) {
+        return ACTC_NO_MATCHING_VERT;
+    }
+    while(tc->VertexBins[tc->CurMaxVertValence] == NULL) {
+        tc->CurMaxVertValence--;
+        if(tc->CurMaxVertValence < tc->CurMinVertValence) {
+            if(tc->VertexCount > 0) {
+                ACTC_DEBUG(fprintf(stderr, "tc::findNextFanVertex : no more "
+                    "vertices in bins but VertexCount > 0\n");)
+                return tc->Error = ACTC_DATABASE_CORRUPT;
+            }
+            return ACTC_NO_MATCHING_VERT;
+        }
+    }
+    *vert = tc->VertexBins[tc->CurMaxVertValence];
+    return ACTC_NO_ERROR;
+}
+
+static int findNextStripVertex(ACTCData *tc, ACTCVertex **vert)
+{
+    while(tc->VertexBins[tc->CurMinVertValence] == NULL) {
+        tc->CurMinVertValence++;
+        if(tc->CurMinVertValence > tc->CurMaxVertValence) {
+            if(tc->VertexCount > 0) {
+                ACTC_DEBUG(fprintf(stderr, "tc::findNextStripVertex : no more "
+                    "vertices in bins but VertexCount > 0\n");)
+                return tc->Error = ACTC_DATABASE_CORRUPT;
+            }
+            return ACTC_NO_MATCHING_VERT;
+        }
+    }
+    *vert = tc->VertexBins[tc->CurMinVertValence];
+    return ACTC_NO_ERROR;
+}
+
+int actcGetIsDuringInput(ACTCData *tc) {
+    return tc->IsInputting;
+}
+
+int actcBeginInput(ACTCData *tc)
+{
+    if(tc->IsOutputting) {
+        ACTC_DEBUG(fprintf(stderr, "actcBeginInput : called within "
+            "BeginOutput/EndOutput\n");)
+        return tc->Error = ACTC_DURING_INPUT;
+    }
+
+    if(tc->IsInputting) {
+        ACTC_DEBUG(fprintf(stderr, "actcBeginInput : called within "
+            "BeginInput/EndInput\n");)
+        return tc->Error = ACTC_DURING_INPUT;
+    }
+
+    tc->IsInputting = 1;
+    tc->CurMaxVertValence = 0;
+
+    if(tc->MaxInputVert < MAX_STATIC_VERTS - 1) {
+        size_t byteCount;
+        tc->UsingStaticVerts = 1;
+        tc->VertRange = tc->MaxInputVert + 1;
+        byteCount = sizeof(ACTCVertex) * tc->VertRange;
+        chartedSetLabel("static verts");
+        tc->StaticVerts = (ACTCVertex *)calloc(sizeof(ACTCVertex), tc->VertRange);
+        if(tc->StaticVerts == NULL) {
+            ACTC_INFO(printf("Couldn't allocate static %d vert block of %u "
+                "bytes\n", tc->VertRange, byteCount);)
+            tc->UsingStaticVerts = 0;
+        }
+    } else
+        tc->UsingStaticVerts = 0;
+
+    return ACTC_NO_ERROR;
+}
+
+int actcEndInput(ACTCData *tc)
+{
+    if(tc->IsOutputting) {
+        ACTC_DEBUG(fprintf(stderr, "actcEndInput : called within "
+            "BeginOutput/EndOutput\n");)
+        return tc->Error = ACTC_DURING_OUTPUT;
+    }
+
+    if(!tc->IsInputting) {
+        ACTC_DEBUG(fprintf(stderr, "actcEndInput : called outside "
+            "BeginInput/EndInput\n");)
+        return tc->Error = ACTC_IDLE;
+    }
+
+    tc->IsInputting = 0;
+
+    return ACTC_NO_ERROR;
+}
+
+int actcGetIsDuringOutput(ACTCData *tc) {
+    return tc->IsOutputting;
+}
+
+int actcBeginOutput(ACTCData *tc)
+{
+    ACTCVertex *v;
+    int i;
+
+    if(tc->IsInputting) {
+        ACTC_DEBUG(fprintf(stderr, "actcBeginOutput : called within "
+            "BeginInput/EndInput\n");)
+        return tc->Error = ACTC_DURING_INPUT;
+    }
+
+    if(tc->IsOutputting) {
+        ACTC_DEBUG(fprintf(stderr, "actcBeginOutput : called within "
+            "BeginOutput/EndOutput\n");)
+        return tc->Error = ACTC_DURING_OUTPUT;
+    }
+
+    tc->IsOutputting = 1;
+
+    tc->CurMinVertValence = INT_MAX;
+    chartedSetLabel("vertex bins");
+    tc->VertexBins = (ACTCVertex **)calloc(sizeof(ACTCVertex *), tc->CurMaxVertValence + 1);
+    if(tc->VertexBins == NULL) {
+        ACTC_DEBUG(fprintf(stderr, "actcBeginOutput : couldn't allocate %d bytes "
+            "for Vertex Bins\n",
+            sizeof(ACTCVertex *) * tc->CurMaxVertValence);)
+        return tc->Error = ACTC_ALLOC_FAILED;
+    }
+
+    if(tc->UsingStaticVerts) {
+        double edgeTotal;
+        for(i = 0; i < tc->VertRange; i++) {
+            v = &tc->StaticVerts[i];
+            if(v->Count > 0) {
+                v->Next = tc->VertexBins[v->Count];
+                v->PointsToMe = &tc->VertexBins[v->Count];
+                tc->VertexBins[v->Count] = v;
+                if(v->Next != NULL)
+                    v->Next->PointsToMe = &v->Next;
+                if(v->Count < tc->CurMinVertValence)
+                    tc->CurMinVertValence = v->Count;
+                edgeTotal += v->EdgeCount;
+            }
+        }
+    } else {
+        tableResetIterator(tc->VertexIterator);
+        for(i = 0; i < tc->VertexCount; i++) {
+            if(tableIterate(tc->Vertices, tc->VertexIterator, NULL, (void **)&v)
+                == 0) {
+                ACTC_DEBUG(fprintf(stderr, "actcBeginOutput : fewer vertices in "
+                    "the table than we expected!\n");)
+                return tc->Error = ACTC_DATABASE_CORRUPT;
+            }
+            v->Next = tc->VertexBins[v->Count];
+            v->PointsToMe = &tc->VertexBins[v->Count];
+            tc->VertexBins[v->Count] = v;
+            if(v->Next != NULL)
+                v->Next->PointsToMe = &v->Next;
+            if(v->Count < tc->CurMinVertValence)
+                tc->CurMinVertValence = v->Count;
+        }
+    }
+
+    return ACTC_NO_ERROR;
+}
+
+int actcEndOutput(ACTCData *tc)
+{
+    if(tc->IsInputting) {
+        ACTC_DEBUG(fprintf(stderr, "actcEndOutput : called within "
+            "BeginInput/EndInput\n");)
+        return tc->Error = ACTC_DURING_INPUT;
+    }
+
+    if(!tc->IsOutputting) {
+        ACTC_DEBUG(fprintf(stderr, "actcEndOutput : called outside "
+            "BeginOutput/EndOutput\n");)
+        return tc->Error = ACTC_IDLE;
+    }
+
+    tc->IsOutputting = 0;
+
+    if(tc->UsingStaticVerts) {
+        free(tc->StaticVerts);
+        tc->StaticVerts = NULL;
+        tc->UsingStaticVerts = 0;
+    }
+
+    free(tc->VertexBins);
+    tc->VertexBins = NULL;
+
+    return ACTC_NO_ERROR;
+}
+
+ACTCData *actcNew(void)
+{
+    ACTCData *tc;
+#if defined(DEBUG) || defined(INFO)
+    static int didPrintVersion = 0;
+
+    if(!didPrintVersion) {
+        int verMinor, verMajor;
+        didPrintVersion = 1;
+
+        actcGetParami(tc, ACTC_MAJOR_VERSION, &verMajor);
+        actcGetParami(tc, ACTC_MINOR_VERSION, &verMinor);
+        fprintf(stderr, "TC Version %d.%d\n", verMajor, verMinor);
+    }
+#endif /* defined(DEBUG) || defined(INFO) */
+
+    chartedSetLabel("the tc struct");
+    tc = (ACTCData *)calloc(sizeof(*tc), 1);
+
+    if(tc == NULL) {
+        ACTC_DEBUG(fprintf(stderr, "actcNew : couldn't allocate %d bytes "
+            "for new ACTCData\n", sizeof(*tc));)
+        return NULL;
+    }
+
+    tc->Vertices = tableNew();
+    tc->VertexIterator = tableNewIterator();
+
+    tc->MinFanVerts = INT_MAX;
+    tc->MaxPrimVerts = INT_MAX;
+    tc->MaxInputVert = INT_MAX;
+    tc->MaxEdgeShare = INT_MAX;
+    tc->MaxVertShare = INT_MAX;
+    tc->HonorWinding = 1;
+    /* seed = 0 handled by calloc */
+    /* XXX grantham 20000615 - seed ignored for now */
+
+    return tc;
+}
+
+static size_t allocatedForTriangles(ACTCEdge *e)
+{
+    return sizeof(ACTCTriangle) * e->TriangleCount;
+}
+
+static size_t allocatedForEdges(ACTCVertex *vert)
+{
+    int i;
+    size_t size;
+
+    size = sizeof(ACTCEdge) * vert->EdgeCount;
+    for(i = 0; i < vert->EdgeCount; i++) {
+        size += allocatedForTriangles(&vert->Edges[i]);
+    }
+    return size;
+}
+
+static size_t allocatedForVertices(ACTCData *tc)
+{
+    int i;
+    int size;
+    ACTCVertex *v;
+
+    if(!tc->UsingStaticVerts)
+        tableResetIterator(tc->VertexIterator);
+
+    if(tc->UsingStaticVerts) {
+        size = tc->VertRange * sizeof(ACTCVertex);
+        for(i = 0; i < tc->VertRange; i++) {
+            v = &tc->StaticVerts[i];
+            if(v->Count > 0)
+                size += allocatedForEdges(v);
+        }
+    } else {
+        for(i = 0; i < tc->VertexCount; i++) {
+            tableIterate(tc->Vertices, tc->VertexIterator, NULL, (void **)&v);
+            size += allocatedForEdges(v);
+        }
+    }
+    return size;
+}
+
+int actcGetMemoryAllocation(ACTCData *tc, size_t *bytesAllocated)
+{
+    size_t tableBytes;
+
+    tableGetStats(tc->Vertices, NULL, NULL, &tableBytes);
+    *bytesAllocated = sizeof(ACTCData);
+    *bytesAllocated += tableBytes;
+    *bytesAllocated += allocatedForVertices(tc); /* recurses */
+
+    return ACTC_NO_ERROR;
+}
+
+static void freeVertex(void *p)
+{
+    ACTCVertex *v = (ACTCVertex *)p;
+    int i;
+
+    for(i = 0; i < v->EdgeCount; i++)
+        free(v->Edges[i].Triangles);
+    free(v->Edges);
+    free(v);
+}
+
+int actcMakeEmpty(ACTCData *tc)
+{
+    tc->VertexCount = 0;
+    if(!tc->UsingStaticVerts)
+        tableDelete(tc->Vertices, freeVertex);
+    if(tc->VertexBins != NULL) {
+        free(tc->VertexBins);
+        tc->VertexBins = NULL;
+    }
+    tc->IsOutputting = 0;
+    tc->IsInputting = 0;
+    return ACTC_NO_ERROR;
+}
+
+void actcDelete(ACTCData *tc)
+{
+    actcMakeEmpty(tc);
+    free(tc->VertexIterator);
+    free(tc->Vertices);
+    free(tc);
+}
+
+int actcParami(ACTCData *tc, int param, int value)
+{
+    if(tc->IsInputting) {
+        ACTC_DEBUG(fprintf(stderr, "actcParami : within BeginInput/"
+            "EndInput\n");)
+        return tc->Error = ACTC_DURING_INPUT;
+    }
+    if(tc->IsOutputting) {
+        ACTC_DEBUG(fprintf(stderr, "actcParami : within BeginOutput/"
+            "EndOutput\n");)
+        return tc->Error = ACTC_DURING_OUTPUT;
+    }
+    switch(param) {
+        case ACTC_OUT_MIN_FAN_VERTS:
+            tc->MinFanVerts = value;
+            break;
+
+        case ACTC_IN_MAX_VERT:
+            if(value < tc->MinInputVert) {
+                ACTC_DEBUG(fprintf(stderr, "actcParami : tried to set "
+                    "MAX_INPUT_VERT to %d, less than MIN_INPUT_VERT (%d)\n",
+                    value, tc->MinInputVert);)
+                return tc->Error = ACTC_INVALID_VALUE;
+            }
+            tc->MaxInputVert = value;
+            break;
+
+        case ACTC_IN_MIN_VERT:
+            if(value > tc->MaxInputVert) {
+                ACTC_DEBUG(fprintf(stderr, "actcParami : tried to set "
+                    "MIN_INPUT_VERT to %d, greater than MAX_INPUT_VERT (%d)\n",
+                    value, tc->MaxInputVert);)
+                return tc->Error = ACTC_INVALID_VALUE;
+            }
+            tc->MinInputVert = value;
+            break;
+
+        case ACTC_IN_MAX_EDGE_SHARING:
+            tc->MaxEdgeShare = value;
+            break;
+
+        case ACTC_IN_MAX_VERT_SHARING:
+            tc->MaxVertShare = value;
+            break;
+
+        case ACTC_OUT_HONOR_WINDING:
+            tc->HonorWinding = value;
+            break;
+
+        case ACTC_OUT_MAX_PRIM_VERTS:
+            if(value < 3) {
+                ACTC_DEBUG(fprintf(stderr, "actcParami : tried to set "
+                    "MAX_PRIM_VERTS to %d (needed to be 3 or more)\n", value);)
+                return tc->Error = ACTC_INVALID_VALUE;
+            }
+            tc->MaxPrimVerts = value;
+            break;
+
+    }
+    return ACTC_NO_ERROR;
+}
+
+int actcParamu(ACTCData *tc, int param, unsigned int value)
+{
+    /*
+     * XXX - yes, this is questionable, but I consulted industry
+     * experts and we agreed that most common behavior is to copy the
+     * bits directly, which is what I want.
+     */
+    return actcParami(tc, param, (int)value);
+}
+
+int actcGetParami(ACTCData *tc, int param, int *value)
+{
+    switch(param) {
+        case ACTC_MAJOR_VERSION:
+            *value = 1;
+            break;
+
+        case ACTC_MINOR_VERSION:
+            *value = 1;
+            break;
+
+        case ACTC_IN_MAX_VERT:
+            *value = tc->MaxInputVert;
+            break;
+
+        case ACTC_IN_MIN_VERT:
+            *value = tc->MinInputVert;
+            break;
+
+        case ACTC_IN_MAX_EDGE_SHARING:
+            *value = tc->MaxEdgeShare;
+            break;
+
+        case ACTC_IN_MAX_VERT_SHARING:
+            *value = tc->MaxVertShare;
+            break;
+
+        case ACTC_OUT_MIN_FAN_VERTS:
+            *value = tc->MinFanVerts;
+            break;
+
+        case ACTC_OUT_HONOR_WINDING:
+            *value = tc->HonorWinding;
+            break;
+
+        case ACTC_OUT_MAX_PRIM_VERTS:
+            *value = tc->MaxPrimVerts;
+            break;
+
+        default:
+            *value = 0;
+            return tc->Error = ACTC_INVALID_VALUE;
+            /* break; */
+    }
+    return ACTC_NO_ERROR;
+}
+
+int actcGetParamu(ACTCData *tc, int param, unsigned int *value)
+{
+    return actcGetParami(tc, param, (int *)value);
+}
+
+static int mapEdgeTriangle(ACTCData *tc, ACTCEdge *edge, ACTCVertex *v3)
+{
+    ACTCTriangle tmp;
+    void *r;
+
+    tmp.FinalVert = v3;
+    chartedSetLabel("triangle list");
+    r = reallocAndAppend((void **)&edge->Triangles, (unsigned int*)&edge->TriangleCount,
+        sizeof(tmp), &tmp);
+    if(r == NULL) {
+        ACTC_DEBUG(fprintf(stderr, "ACTC::mapEdgeTriangle : Couldn't allocate "
+            "%d bytes for triangles\n", sizeof(tmp) *
+            (edge->TriangleCount + 1));)
+        return tc->Error = ACTC_ALLOC_FAILED;
+    }
+
+    return ACTC_NO_ERROR;
+}
+
+static int unmapEdgeTriangle(ACTCData *tc, ACTCEdge *edge, ACTCVertex *v3)
+{
+    int i;
+
+    for(i = 0; i < edge->TriangleCount; i++)
+        if(edge->Triangles[i].FinalVert == v3)
+            break;
+
+    if(i == edge->TriangleCount) {
+        ACTC_DEBUG(
+            fprintf(stderr, "ACTC::unmapEdgeTriangle : Couldn't find third vertex"
+                " from edge in order to delete it?!?\n");
+            abortWithOptionalDump(tc);
+        )
+        return tc->Error = ACTC_DATABASE_CORRUPT;
+    }
+
+    edge->Triangles[i] = edge->Triangles[edge->TriangleCount - 1];
+    edge->TriangleCount --;
+
+    return ACTC_NO_ERROR;
+}
+
+static int mapVertexEdge(ACTCData *tc, ACTCVertex *v1, ACTCVertex *v2, ACTCEdge **edge)
+{
+    unsigned int i;
+    ACTCEdge tmp;
+    void *r;
+
+    for(i = 0; i < v1->EdgeCount; i++)
+        if(v1->Edges[i].V2 == v2) {
+            v1->Edges[i].Count++;
+            break;
+        }
+
+    if(i == v1->EdgeCount) {
+
+        tmp.V2 = v2;
+        tmp.Count = 1;
+        tmp.Triangles = NULL;
+        tmp.TriangleCount = 0;
+
+        chartedSetLabel("vert-to-edge mapping");
+        r = reallocAndAppend((void **)&v1->Edges, (unsigned int*)&v1->EdgeCount,
+            sizeof(tmp), &tmp);
+        if(r == NULL) {
+            ACTC_DEBUG(fprintf(stderr, "ACTC::mapVertexEdge : Couldn't reallocate "
+                "to %d bytes for vertex's edge list\n", sizeof(tmp) *
+                v1->EdgeCount);)
+            return tc->Error = ACTC_ALLOC_FAILED;
+        }
+    }
+    *edge = &v1->Edges[i];
+
+    return ACTC_NO_ERROR;
+}
+
+static int unmapVertexEdge(ACTCData *tc, ACTCVertex *v1, ACTCVertex *v2)
+{
+    int i;
+
+    for(i = 0; i < v1->EdgeCount; i++)
+        if(v1->Edges[i].V2 == v2)
+            break;
+
+    if(i == v1->EdgeCount) {
+        ACTC_DEBUG(
+            fprintf(stderr, "ACTC::unmapVertexEdge : Couldn't find edge %d,%d"
+                " from vertex in order to unmap it?!?\n", v1->V, v2->V);
+            abortWithOptionalDump(tc);
+        )
+        return tc->Error = ACTC_DATABASE_CORRUPT;
+    }
+
+    v1->Edges[i].Count --;
+    if(v1->Edges[i].Count == 0) {
+        if(v1->Edges[i].Triangles != NULL)
+            free(v1->Edges[i].Triangles);
+        v1->Edges[i] = v1->Edges[v1->EdgeCount - 1];
+        v1->EdgeCount --;
+    }
+
+    return ACTC_NO_ERROR;
+}
+
+int actcAddTriangle(ACTCData *tc, unsigned int v1, unsigned int v2, unsigned int v3)
+{
+    ACTCVertex *vertexRec1;
+    ACTCVertex *vertexRec2;
+    ACTCVertex *vertexRec3;
+
+    ACTCEdge *edge12;
+    ACTCEdge *edge23;
+    ACTCEdge *edge31;
+
+    if(tc->IsOutputting) {
+        ACTC_DEBUG(fprintf(stderr, "actcAddTriangle : inside "
+            "BeginOutput/EndOutput\n");)
+        return tc->Error = ACTC_IDLE;
+    }
+    if(!tc->IsInputting) {
+        ACTC_DEBUG(fprintf(stderr, "actcAddTriangle : outside "
+            "BeginInput/EndInput\n");)
+        return tc->Error = ACTC_DURING_INPUT;
+    }
+
+    if(incVertexValence(tc, v1, &vertexRec1) != ACTC_NO_ERROR) goto returnError1;
+    if(incVertexValence(tc, v2, &vertexRec2) != ACTC_NO_ERROR) goto free1;
+    if(incVertexValence(tc, v3, &vertexRec3) != ACTC_NO_ERROR) goto free2;
+
+    if(mapVertexEdge(tc, vertexRec1, vertexRec2, &edge12) != ACTC_NO_ERROR)
+        goto free3;
+    if(mapVertexEdge(tc, vertexRec2, vertexRec3, &edge23) != ACTC_NO_ERROR)
+        goto free4;
+    if(mapVertexEdge(tc, vertexRec3, vertexRec1, &edge31) != ACTC_NO_ERROR)
+        goto free5;
+
+    if(mapEdgeTriangle(tc, edge12, vertexRec3) != ACTC_NO_ERROR) goto free6;
+    if(mapEdgeTriangle(tc, edge23, vertexRec1) != ACTC_NO_ERROR) goto free7;
+    if(mapEdgeTriangle(tc, edge31, vertexRec2) != ACTC_NO_ERROR) goto free8;
+
+    return ACTC_NO_ERROR;
+
+    /*
+     * XXX Unfortunately, while backing out during the following
+     * statements, we might encounter errors in the database which
+     * will not get returned properly to the caller; I take heart in
+     * the fact that if such an error occurs, TC is just a moment from
+     * core dumping anyway. XXX grantham 20000615
+     */
+
+free8:
+    unmapEdgeTriangle(tc, edge23, vertexRec1);
+free7:
+    unmapEdgeTriangle(tc, edge12, vertexRec3);
+free6:
+    unmapVertexEdge(tc, vertexRec3, vertexRec1);
+free5:
+    unmapVertexEdge(tc, vertexRec2, vertexRec3);
+free4:
+    unmapVertexEdge(tc, vertexRec1, vertexRec2);
+free3:
+    decVertexValence(tc, &vertexRec3);
+free2:
+    decVertexValence(tc, &vertexRec2);
+free1:
+    decVertexValence(tc, &vertexRec1);
+returnError1:
+    return tc->Error;
+}
+
+int actcStartNextPrim(ACTCData *tc, unsigned int *v1Return, unsigned int *v2Return)
+{
+    ACTCVertex *v1 = NULL;
+    ACTCVertex *v2 = NULL;
+    int findResult;
+
+    if(tc->IsInputting) {
+        ACTC_DEBUG(fprintf(stderr, "actcStartNextPrim : within "
+            "BeginInput/EndInput\n");)
+        return tc->Error = ACTC_DURING_INPUT;
+    }
+    if(!tc->IsOutputting) {
+        ACTC_DEBUG(fprintf(stderr, "actcStartNextPrim : outside "
+            "BeginOutput/EndOutput\n");)
+        return tc->Error = ACTC_IDLE;
+    }
+
+    findResult = findNextFanVertex(tc, &v1);
+    if(findResult == ACTC_NO_ERROR)
+        tc->PrimType = ACTC_PRIM_FAN;
+    else if(findResult != ACTC_NO_MATCHING_VERT) {
+        ACTC_DEBUG(fprintf(stderr, "actcStartNextPrim : internal "
+            "error finding next appropriate vertex\n");)
+        return tc->Error = findResult;
+    } else {
+        findResult = findNextStripVertex(tc, &v1);
+        if(findResult != ACTC_NO_ERROR && findResult != ACTC_NO_MATCHING_VERT) {
+            ACTC_DEBUG(fprintf(stderr, "actcStartNextPrim : internal "
+                "error finding next appropriate vertex\n");)
+            return tc->Error = findResult;
+        }
+        tc->PrimType = ACTC_PRIM_STRIP;
+    }
+
+    if(findResult == ACTC_NO_MATCHING_VERT) {
+        *v1Return = -1;
+        *v2Return = -1;
+        return tc->Error = ACTC_DATABASE_EMPTY;
+    }
+
+    v2 = v1->Edges[0].V2;
+
+    tc->CurWindOrder = ACTC_FWD_ORDER;
+    tc->VerticesSoFar = 2;
+
+    tc->V1 = v1;
+    tc->V2 = v2;
+
+    *v1Return = v1->V;
+    *v2Return = v2->V;
+
+    ACTC_INFO(printf("starting with edge %u, %u\n", tc->V1->V, tc->V2->V);)
+
+    return tc->PrimType;
+}
+
+static int findEdge(ACTCVertex *v1, ACTCVertex *v2, ACTCEdge **edge)
+{
+    int i;
+
+    for(i = 0; i < v1->EdgeCount; i++)
+        if(v1->Edges[i].V2 == v2) {
+            *edge = &v1->Edges[i];
+            return 1;
+        }
+    return 0;
+}
+
+int unmapEdgeTriangleByVerts(ACTCData *tc, ACTCVertex *v1, ACTCVertex *v2,
+    ACTCVertex *v3)
+{
+    ACTCEdge *e;
+
+    ACTC_CHECK(findEdge(v1, v2, &e));
+    unmapEdgeTriangle(tc, e, v3);
+    return ACTC_NO_ERROR;
+}
+
+int actcGetNextVert(ACTCData *tc, unsigned int *vertReturn)
+{
+    ACTCEdge *edge;
+    int wasEdgeFound = 0;
+    ACTCVertex *thirdVertex;
+    int wasFoundReversed;
+
+    if(tc->IsInputting) {
+        ACTC_DEBUG(fprintf(stderr, "actcGetNextVert : within BeginInput/"
+            "EndInput\n");)
+        return tc->Error = ACTC_DURING_INPUT;
+    }
+    if(!tc->IsOutputting) {
+        ACTC_DEBUG(fprintf(stderr, "actcGetNextVert : outside BeginOutput/"
+            "EndOutput\n");)
+        return tc->Error = ACTC_IDLE;
+    }
+    if(tc->PrimType == -1) {
+        ACTC_DEBUG(fprintf(stderr, "actcGetNextVert : Asked for next vertex "
+            "without a primitive (got last\n    vertex already?)\n");)
+        return tc->Error = ACTC_INVALID_VALUE;
+    }
+
+    if(tc->VerticesSoFar >= tc->MaxPrimVerts) {
+        tc->PrimType = -1;
+        return tc->Error = ACTC_PRIM_COMPLETE;
+    }
+
+    if(tc->V1 == NULL || tc->V2 == NULL) {
+        tc->PrimType = -1;
+        return tc->Error = ACTC_PRIM_COMPLETE;
+    }
+
+    ACTC_INFO(printf("looking for edge %u, %u\n", tc->V1->V, tc->V2->V);)
+
+    wasFoundReversed = 0;
+
+    if(findEdge(tc->V1, tc->V2, &edge) != 0) {
+        wasEdgeFound = 1;
+    } else if(!tc->HonorWinding) {
+        wasFoundReversed = 1;
+        if(findEdge(tc->V2, tc->V1, &edge) != 0) {
+            wasEdgeFound = 1;
+        }
+    }
+
+    if(!wasEdgeFound) {
+        tc->PrimType = -1;
+        return tc->Error = ACTC_PRIM_COMPLETE;
+    }
+
+    thirdVertex = edge->Triangles[edge->TriangleCount - 1].FinalVert;
+
+    ACTC_INFO(printf("third vertex = %u\n", thirdVertex->V);)
+    *vertReturn = thirdVertex->V;
+
+    if(wasFoundReversed) {
+        ACTC_CHECK(unmapEdgeTriangle(tc, edge, thirdVertex));
+        ACTC_CHECK(unmapEdgeTriangleByVerts(tc, tc->V1, thirdVertex, tc->V2));
+        ACTC_CHECK(unmapEdgeTriangleByVerts(tc, thirdVertex, tc->V2, tc->V1));
+        ACTC_CHECK(unmapVertexEdge(tc, tc->V2, tc->V1));
+        ACTC_CHECK(unmapVertexEdge(tc, tc->V1, thirdVertex));
+        ACTC_CHECK(unmapVertexEdge(tc, thirdVertex, tc->V2));
+    } else {
+        ACTC_CHECK(unmapEdgeTriangle(tc, edge, thirdVertex));
+        ACTC_CHECK(unmapEdgeTriangleByVerts(tc, tc->V2, thirdVertex, tc->V1));
+        ACTC_CHECK(unmapEdgeTriangleByVerts(tc, thirdVertex, tc->V1, tc->V2));
+        ACTC_CHECK(unmapVertexEdge(tc, tc->V1, tc->V2));
+        ACTC_CHECK(unmapVertexEdge(tc, tc->V2, thirdVertex));
+        ACTC_CHECK(unmapVertexEdge(tc, thirdVertex, tc->V1));
+    }
+    ACTC_CHECK(decVertexValence(tc, &tc->V1));
+    ACTC_CHECK(decVertexValence(tc, &tc->V2));
+    ACTC_CHECK(decVertexValence(tc, &thirdVertex));
+
+    if(tc->PrimType == ACTC_PRIM_FAN) {
+        tc->V2 = thirdVertex;
+    } else /* PRIM_STRIP */ {
+        if(tc->CurWindOrder == ACTC_FWD_ORDER)
+            tc->V1 = thirdVertex;
+        else
+            tc->V2 = thirdVertex;
+        tc->CurWindOrder = !tc->CurWindOrder;
+    }
+
+    tc->VerticesSoFar++;
+    return ACTC_NO_ERROR;
+}
+
+int actcTrianglesToPrimitives(ACTCData *tc, int triangleCount,
+    unsigned int (*triangles)[3], int primTypes[], int primLengths[], unsigned int vertices[],
+    int maxBatchSize)
+{
+    int r;
+    int curTriangle;
+    int curPrimitive;
+    unsigned int curVertex;
+    int prim;
+    unsigned int v1, v2, v3;
+    int lastPrim;
+    int passesWithoutPrims;
+    int trisSoFar;
+
+    if(tc->IsInputting) {
+        ACTC_DEBUG(fprintf(stderr, "actcTrianglesToPrimitives : within BeginInput/"
+            "EndInput\n");)
+        return tc->Error = ACTC_DURING_INPUT;
+    }
+    if(tc->IsOutputting) {
+        ACTC_DEBUG(fprintf(stderr, "actcTrianglesToPrimitives : within"
+            "BeginOutput/EndOutput\n");)
+        return tc->Error = ACTC_DURING_OUTPUT;
+    }
+    curTriangle = 0;
+    curPrimitive = 0;
+    curVertex = 0;
+    passesWithoutPrims = 0;
+
+    actcMakeEmpty(tc);
+
+    ACTC_CHECK(actcBeginInput(tc));
+    trisSoFar = 0;
+    while(curTriangle < triangleCount) {
+        r = actcAddTriangle(tc, triangles[curTriangle][0],
+            triangles[curTriangle][1], triangles[curTriangle][2]);
+        trisSoFar++;
+        curTriangle++;
+        if((trisSoFar >= maxBatchSize) ||
+            (r == ACTC_ALLOC_FAILED && curTriangle != triangleCount) ||
+            (r == ACTC_NO_ERROR && curTriangle == triangleCount)) {
+
+            /* drain what we got */
+            trisSoFar = 0;
+            ACTC_CHECK(actcEndInput(tc));
+            ACTC_CHECK(actcBeginOutput(tc));
+            lastPrim = curPrimitive;
+            while((prim = actcStartNextPrim(tc, &v1, &v2)) != ACTC_DATABASE_EMPTY) {
+                ACTC_CHECK(prim);
+                primTypes[curPrimitive] = prim;
+                primLengths[curPrimitive] = 2;
+                vertices[curVertex++] = v1;
+                vertices[curVertex++] = v2;
+                while((r = actcGetNextVert(tc, &v3)) != ACTC_PRIM_COMPLETE) {
+                    ACTC_CHECK(r);
+                    vertices[curVertex++] = v3;
+                    primLengths[curPrimitive]++;
+                }
+                curPrimitive++;
+            }
+            ACTC_CHECK(actcEndOutput(tc));
+            if(r == ACTC_ALLOC_FAILED && curPrimitive == lastPrim) {
+                if(passesWithoutPrims == 0) {
+                    /* not enough memory to add a triangle and */
+                    /* nothing in the database, better free everything */
+                    /* and try again */
+                    actcMakeEmpty(tc);
+                } else {
+                    /* cleaned up and STILL couldn't get a triangle in; */
+                    /* give up */
+                    return tc->Error = ACTC_ALLOC_FAILED;
+                }
+                passesWithoutPrims++;
+            }
+            ACTC_CHECK(actcBeginInput(tc));
+        } else
+            ACTC_CHECK(r);
+        if(r == ACTC_ALLOC_FAILED)
+            curTriangle--;
+    }
+    ACTC_CHECK(actcEndInput(tc));
+
+    actcMakeEmpty(tc);
+
+    return curPrimitive;
+}
+
+/* vi:tabstop=8
+ */
Index: branches/network/src/subprojects/network/Makefile.am
===================================================================
--- branches/network/src/subprojects/network/Makefile.am	(revision 6636)
+++ branches/network/src/subprojects/network/Makefile.am	(revision 6636)
@@ -0,0 +1,42 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+bin_PROGRAMS = network
+
+
+network_CPPFLAGS = -DNO_SHELL -DNO_SHELL_COMMAND
+
+network_LDFLAGS = $(MWINDOWS)
+
+network_LDADD = $(MAINSRCDIR)/lib/network/libORXnet.a \
+                \
+                $(MAINSRCDIR)/lib/parser/tinyxml/libtinyxml.a
+
+network_SOURCES=  network_unit_test.cc \
+                  simple_sync.cc \
+		  read_sync.cc \
+		  write_sync.cc \
+                  \
+                  \
+                  $(MAINSRCDIR)/lib/lang/base_object.cc \
+                  $(MAINSRCDIR)/lib/lang/class_list.cc \
+                  $(MAINSRCDIR)/util/loading/load_param.cc \
+                  $(MAINSRCDIR)/util/loading/factory.cc \
+                  $(MAINSRCDIR)/lib/util/substring.cc \
+                  $(MAINSRCDIR)/util/loading/load_param_description.cc \
+                  $(MAINSRCDIR)/lib/util/helper_functions.cc \
+                  $(MAINSRCDIR)/lib/util/executor/executor.cc \
+                  $(MAINSRCDIR)/lib/util/multi_type.cc \
+                  \
+                  \
+                  $(MAINSRCDIR)/lib/coord/p_node.cc        \
+                  $(MAINSRCDIR)/world_entities/world_entity.cc
+                  
+
+
+
+noinst_HEADERS  =  network_unit_test.h \
+                   simple_sync.h \
+		   read_sync.h \
+		   write_sync.h
+
Index: branches/network/src/subprojects/network/README
===================================================================
--- branches/network/src/subprojects/network/README	(revision 6636)
+++ branches/network/src/subprojects/network/README	(revision 6636)
@@ -0,0 +1,21 @@
+
+To use the NetworkUnitTest:
+
+1. Compile and link Orxonox (following the guide you find on www.orxonox.net)
+2. Compile the network binary by typing: make
+
+Now will want to do some of the following:
+
+Distributed Network Test:
+=========================
+1. Start the server: 
+
+./network --server 9999
+
+2. Start the client on an other console/host: 
+
+./network --client dns-name-of-other-host.com 9999
+
+have fun seeing the msgs floating around
+
+
Index: branches/network/src/subprojects/network/isolated_unit_test.cc
===================================================================
--- branches/network/src/subprojects/network/isolated_unit_test.cc	(revision 6636)
+++ branches/network/src/subprojects/network/isolated_unit_test.cc	(revision 6636)
@@ -0,0 +1,15 @@
+
+
+
+#include "../../lib/network/converter.h"
+
+
+int main(int argc, char** argv)
+{
+ 
+  float x = 3234.0f;
+  
+  byte* b = Converter::floatToByteArray(x);
+  
+  return 0;
+}
Index: branches/network/src/subprojects/network/network_unit_test.cc
===================================================================
--- branches/network/src/subprojects/network/network_unit_test.cc	(revision 6636)
+++ branches/network/src/subprojects/network/network_unit_test.cc	(revision 6636)
@@ -0,0 +1,442 @@
+
+#include "stdlibincl.h"
+#include <stdarg.h>
+#include <stdio.h>
+#include "shell_buffer.h"
+#include "class_list.h"
+
+#include "network_manager.h"
+#include "network_socket.h"
+#include "server_socket.h"
+#include "network_stream.h"
+#include "synchronizeable.h"
+#include "converter.h"
+
+#include "simple_sync.h"
+#include "read_sync.h"
+
+int verbose = 4;
+
+
+/* outputs the help */
+int startHelp(int argc, char** argv)
+{
+  printf("Network is a network unit test\n");
+  printf(" --help                     this output\n");
+  printf(" -st,  --sockettest         test network_socket\n");
+  printf(" -ft,  --frameworktest      test the network module\n");
+  printf(" --server [port number]     creates a test server\n");
+  printf(" --client [address] [port]  connects to a server\n");
+  printf(" --listen [address] [port]  just listens to this connection");
+  printf("\n");
+}
+
+
+/* test SDL network socket */
+int testSocket(int argc, char** argv)
+{
+  IPaddress ip;
+  SDLNet_ResolveHost(&ip, "127.0.0.1", 9999);
+  ServerSocket server;
+  server.listen(9999);
+
+  NetworkSocket* client1 = new NetworkSocket(ip);
+
+  NetworkSocket* server1 = server.getNewSocket();
+
+  NetworkSocket* client2 = new NetworkSocket(ip);
+
+  NetworkSocket* server2 = server.getNewSocket();
+
+  char buf[1024];
+
+  printf("read from client1 before sending data\n");
+  printf("result: %d bytes\n", client1->readPacket((byte*)buf, 1024));
+
+  printf("read from client2 before sending data\n");
+  printf("result: %d bytes\n", client2->readPacket((byte*)buf, 1024));
+
+  int n;
+  char * str1 = "client1 to server";
+  char * str2 = "server1 to client";
+  char * str3 = "client2 to server";
+  char * str4 = "server2 to client";
+  n = client1->writePacket((byte*)str1, strlen(str1)+1);
+  printf("%d bytes send from client1\n", n);
+  n = server1->writePacket((byte*)str2, strlen(str2)+1);
+  printf("%d bytes send from server1\n", n);
+  n = client2->writePacket((byte*)str3, strlen(str3)+1);
+  printf("%d bytes send from client2\n", n);
+  n = server2->writePacket((byte*)str4, strlen(str4)+1);
+  printf("%d bytes send from server2\n", n);
+  SDL_Delay(1000);
+
+  printf("read from server1\n");
+  n = server1->readPacket((byte*)buf, 1024);
+  printf("read %d bytes\n", n);
+  if (n<0)
+    return -1;
+
+  printf("data: '%s'\n", buf);
+
+  printf("read from server2\n");
+  n = server2->readPacket((byte*)buf, 1024);
+  printf("read %d bytes\n", n);
+  if (n<0)
+    return -1;
+
+  printf("data: '%s'\n", buf);
+
+  printf("read from client1\n");
+  n = client1->readPacket((byte*)buf, 1024);
+  printf("read %d bytes\n", n);
+  if (n<0)
+    return -1;
+
+  printf("data: '%s'\n", buf);
+
+  printf("read from client2\n");
+  n = client2->readPacket((byte*)buf, 1024);
+  printf("read %d bytes\n", n);
+  if (n<0)
+    return -1;
+
+  printf("data: '%s'\n", buf);
+
+  //sending bigger packets than 255 is not supported
+
+  printf("try to send more than 255 bytes\n");
+  printf("result: %d\n", client1->writePacket((byte*)buf, 1000));
+
+  server1->writePacket((byte*)str1, strlen(str1)+1);
+  SDL_Delay(500);
+  printf("try to read with a too small buffer\n");
+  printf("result: %d\n", client1->readPacket((byte*)buf, strlen(str1)));
+
+  return 0;
+}
+
+
+int testFramework(int argc, char** argv)
+{
+  printf("=================\n");
+  printf("TestFramework\n");
+  printf("=================\n");
+
+  Synchronizeable* clientSync = new SimpleSync("Client\0");
+  Synchronizeable* serverSync = new SimpleSync("Server\0");
+
+  unsigned int port = 9999;
+
+  /* create the network manager */
+  NetworkManager* nm = NetworkManager::getInstance();
+
+  /* initialize the network manager */
+  nm->initialize();
+
+  /* create a server stream */
+  nm->createServer(port);
+
+  /* esatblish a connection */
+  IPaddress ip;
+  int error = SDLNet_ResolveHost(&ip, "127.0.0.1", port);
+  //SDLNet_ResolveHost(&ip, "localhost", port);
+  if(error == -1)
+    printf("\n\nerror on address resolution, program inconsistancy\n\n");
+  nm->establishConnection(ip, *clientSync);
+  /* adding some break for connection setup */
+  SDL_Delay(20);
+
+  /* synchronize the data 1 time (increment for longer tests) */
+  for( int i = 0; i < 3; i++)
+  {
+    nm->synchronize();
+    /* simulate the network delay */
+    SDL_Delay(50);
+  }
+
+  printf("Test finished\n");
+
+
+  /* delete the network manager again */
+  delete nm;
+
+  delete clientSync;
+  delete serverSync;
+
+  return 0;
+}
+
+
+
+/**
+ *
+ * @param argc
+ * @param argv
+ * @return
+ */
+int startServer(int argc, char** argv)
+{
+  if( argc <= 2)
+  {
+    printf(" Wrong arguments try following notations:\n");
+    printf("   --server [port number]\n");
+    return 0;
+  }
+
+  int port = atoi(argv[2]);
+  printf("Starting Server on port %i\n", port);
+
+  NetworkManager* netMan = NetworkManager::getInstance();
+  Synchronizeable* ss = new SimpleSync("Server\0");
+
+  netMan->createServer(/**ss, */port);
+  SDL_Delay(20);
+
+  for(;;)
+  {
+    netMan->synchronize();
+    SDL_Delay(1000);
+  }
+
+  delete netMan;
+  delete ss;
+
+
+  return 0;
+}
+
+
+int startClient(int argc, char** argv)
+{
+  if( argc < 3)
+  {
+    printf(" Wrong arguments try following notations:\n");
+    printf("   --client [server ip] [port number]\n");
+    printf("   --client [server name] [port number]\n");
+    return 0;
+  }
+
+  char* name = argv[2];
+  int port = atoi(argv[3]);
+  printf("Connecting to %s, on port %i\n", name, port);
+
+  IPaddress ip;
+  int error = SDLNet_ResolveHost(&ip, name, port);
+  if(error == -1)
+    printf("\n\nerror on address resolution, program inconsistancy\n\n");
+
+  NetworkManager* netMan = NetworkManager::getInstance();
+  Synchronizeable* ss = new SimpleSync("Client\0");
+
+  netMan->establishConnection((const char*)"localhost", port/*,ip, *ss*/);
+
+  for(;;)
+  {
+    netMan->synchronize();
+    SDL_Delay(500);
+  }
+
+
+  delete netMan;
+  delete ss;
+
+  return 0;
+}
+
+
+
+int startListen(int argc, char** argv)
+{
+  if( argc < 3)
+  {
+    printf(" Wrong arguments try following notations:\n");
+    printf("   --listen [server ip] [port number]\n");
+    printf("   --listen [server name] [port number]\n");
+    return 0;
+  }
+
+  char* name = argv[2];
+  int port = atoi(argv[3]);
+  printf("Connecting to %s, on port %i\n", name, port);
+
+  IPaddress ip;
+  int error = SDLNet_ResolveHost(&ip, name, port);
+  if(error == -1)
+    printf("\n\nerror on address resolution, program inconsistancy\n\n");
+
+  NetworkManager* netMan = NetworkManager::getInstance();
+  Synchronizeable* ss = new ReadSync("WriteSync\0");
+
+  netMan->establishConnection(ip, *ss);
+
+  for(;;)
+  {
+    netMan->synchronize();
+    SDL_Delay(10);
+  }
+
+
+  delete netMan;
+  delete ss;
+
+  return 0;
+}
+
+void testFloatConverter(float f)
+{
+  char* s = Converter::floatToBinString(f);
+  printf("%f = ", f);
+  printf(s); printf("\n");
+
+  byte* res = Converter::floatToByteArray(f);
+  printf("Byte Array: ");
+  for (int i = 0; i < 4; i++)
+    printf("%i  ", res[i]);
+  printf("\n");
+
+  float b = Converter::byteArrayToFloat(res);
+  printf("ReConvert: %f \n", b);
+}
+
+void testFloatConverter2(float f)
+{
+  char* s = Converter::floatToBinString(f);
+  printf("### %f = ", f);
+  printf(s); printf("\n");
+
+  byte* res = Converter::_floatToByteArray(f);
+  printf("Byte Array: ");
+  for (int i = 0; i < 4; i++)
+    printf("%i  ", res[i]);
+  printf("\n");
+
+  float b = Converter::_byteArrayToFloat(res);
+  printf("ReConvert: %f \n", b);
+}
+int converter(int argc, char** argv)
+{
+  /*
+  int x = 200564786;
+  printf("To convert: %i\n", x);
+  byte* res = Converter::intToByteArray(x);
+  for (int i = 0; i < 4; i++)
+    printf("%i  ", res[i]);
+  printf("\n");
+
+  int z = Converter::byteArrayToInt(res);
+
+  printf("ReConvert: %i\n", z);
+
+
+  //float a = 5.4f;
+  //float b = 2.0f;
+  //printf("%f mod %f = %f", a, b, a % b);
+
+  printf("\n");
+
+  */
+  /*
+  float y;
+  char* s;
+
+  y = 12.0f;
+  s = Converter::floatToBinString(y);
+  printf("%f = ", y);
+  printf(s); printf("\n");
+
+  y = 24549026.0f;
+  s = Converter::floatToBinString(y);
+  printf("%f = ", y);
+  printf(s); printf("\n");
+
+  y = 12.4e20f;
+  s = Converter::floatToBinString(y);
+  printf("%f = ", y);
+  printf(s); printf("\n");
+
+  y = 4.7824f;
+  s = Converter::floatToBinString(y);
+  printf("%f = ", y);
+  printf(s); printf("\n");
+
+  y = -4.7824f;
+  s = Converter::floatToBinString(y);
+  printf("%f = ", y);
+  printf(s); printf("\n");
+
+  y = -14.35e14f;
+  s = Converter::floatToBinString(y);
+  printf("%f = ", y);
+  printf(s); printf("\n");
+                                                            */
+
+
+  /*
+  float a = 12.3f;
+
+  char* s = Converter::floatToBinString(a);
+  printf("%f = ", a);
+  printf(s); printf("\n");
+
+  byte* res = Converter::floatToByteArray(a);
+  printf("Byte Array: \n");
+  for (int i = 0; i < 4; i++)
+    printf("%i  ", res[i]);
+  printf("\n");
+
+  float b = Converter::byteArrayToFloat(res);
+  printf("ReConvert: %f \n", b);
+  */
+//  testFloatConverter(12.3e-53f); printf("\n");
+//  testFloatConverter(134.26455646546548741661675165f); printf("\n");
+ // testFloatConverter(35.67e14f); printf("\n");
+
+  testFloatConverter(12.3e-7f); printf("\n");
+  testFloatConverter(134.26455646546548741661675165f); printf("\n");
+  testFloatConverter(35.67e14f); printf("\n");
+
+  return 0;
+}
+
+
+
+/**
+ *
+ *  main function
+ *
+ * here the journey begins
+ */
+int main(int argc, char** argv)
+{
+  int i;
+  // here the pre-arguments are loaded, these are needed to go either to orxonx itself, Help, or Benchmark.
+  for(i = 1; i < argc; ++i)
+  {
+    //else if(!strcmp( "--gui", argv[i]) || !strcmp("-g", argv[i])) showGui = true;
+    if (! strcmp( "--sockettest", argv[i]) || !strcmp("-st", argv[i]))
+      return testSocket(argc, argv);
+    else if (! strcmp( "--frameworktest", argv[i]) || !strcmp("-ft", argv[i]))
+      return testFramework(argc, argv);
+    else if (! strcmp( "--server", argv[i]) || !strcmp("-s", argv[i]))
+      return startServer(argc, argv);
+    else if (! strcmp( "--client", argv[i]) || !strcmp("-c", argv[i]))
+      return startClient(argc, argv);
+    else if (! strcmp( "--listen", argv[i]) || !strcmp("-l", argv[i]))
+      return startListen(argc, argv);
+    else if (! strcmp( "--converter", argv[i]) || !strcmp("-o", argv[i]))
+      return converter(argc, argv);
+  }
+
+  startHelp(argc, argv);
+
+  return 0;
+}
+
+
+bool ShellBuffer::addBufferLineStatic(const char* line, ...)
+{
+  //va_list arguments;
+  //vprintf(line, arguments);
+  printf("%s", line);
+}
Index: branches/network/src/subprojects/network/network_unit_test.h
===================================================================
--- branches/network/src/subprojects/network/network_unit_test.h	(revision 6636)
+++ branches/network/src/subprojects/network/network_unit_test.h	(revision 6636)
@@ -0,0 +1,24 @@
+/*!
+ * @file network_unit_test.h
+ * A network unit test modules: to test the the network lib without starting orxonox
+ */
+
+/* you will want to add such a a line at your header file also, since it will
+   prevent c++ from including your code twice*/
+#ifndef _NETWORK_UNIT_TEST_H
+#define _NETWORK_UNIT_TEST_H
+
+
+
+class NetworkUnitTest
+{
+  public:
+    NetworkUnitTest();
+    ~NetworkUnitTest();
+
+    void start();
+    void stop();
+
+};
+
+#endif /* _NETWORK_UNIT_TEST */
Index: branches/network/src/subprojects/network/read_sync.cc
===================================================================
--- branches/network/src/subprojects/network/read_sync.cc	(revision 6636)
+++ branches/network/src/subprojects/network/read_sync.cc	(revision 6636)
@@ -0,0 +1,100 @@
+/*
+  orxonox - the future of 3D-vertical-scrollers
+
+  Copyright (C) 2004 orx
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+      the Free Software Foundation; either version 2, or (at your option)
+      any later version.
+
+### File Specific:
+    main-programmer: Patrick Boenzli
+    co-programmer:
+*/
+
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+          For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
+#include "read_sync.h"
+
+#include "debug.h"
+
+
+/**
+ *  default constructor
+ */
+ReadSync::ReadSync(const char* name)
+  : Synchronizeable()
+{
+  /* define the local buffer size */
+
+  this->inLength = 100;
+  this->recLength = 0;
+  this->inData = new byte[this->inLength];
+
+  /* init the buffer data */
+  for( int i = 0; i < this->inLength; i++)
+  {
+    this->inData[i] = 0;
+  }
+
+}
+
+
+/**
+ *  default destructor deletes all unneded stuff
+ */
+ReadSync::~ReadSync()
+{
+
+  if( this->inData)
+    delete[] this->inData;
+}
+
+
+/**
+ *  write data to Synchronizeable
+ */
+int ReadSync::writeBytes(const byte* data, int length, int sender)
+{
+  PRINTF(0)("ReadSync: got %i bytes of data\n", length);
+  this->recLength = length;
+  if(this->inLength < length)
+    PRINTF(0)("ERROR: local buffer is smaller than the data to receive.\n");
+
+  /* copy the data localy */
+  for( int i = 0; i < length; i++)
+  {
+    this->inData[i] = data[i];
+  }
+  /* and debug output */
+  this->writeDebug();
+}
+
+
+/**
+ *  read data from Synchronizeable
+ */
+int ReadSync::readBytes(byte* data, int maxLength, int * reciever)
+{
+  return 0;
+}
+
+
+void ReadSync::writeDebug() const
+{
+  PRINTF(0)("Write in bytes: \t(0 <-) |");
+  for(int i = 0; i < this->recLength; i++)
+  {
+    PRINT(0)(" [%u] ",this->inData[i]);
+  }
+  PRINT(0)("|\n");
+}
+
+
+void ReadSync::readDebug() const
+{}
Index: branches/network/src/subprojects/network/read_sync.h
===================================================================
--- branches/network/src/subprojects/network/read_sync.h	(revision 6636)
+++ branches/network/src/subprojects/network/read_sync.h	(revision 6636)
@@ -0,0 +1,33 @@
+/*!
+ * @file simple_sync.h
+ *  implementation of a network sync test
+ */
+
+#ifndef _READ_SYNC
+#define _READ_SYNC
+
+#include "synchronizeable.h"
+
+
+class ReadSync : public Synchronizeable
+  {
+  public:
+    ReadSync(const char* name);
+    ~ReadSync();
+
+    virtual int writeBytes(const byte* data, int length, int sender);
+    virtual int readBytes(byte* data, int maxLength, int * reciever);
+
+
+  private:
+    virtual void writeDebug() const;
+    virtual void readDebug() const;
+
+
+  private:
+    byte* inData;
+    int   inLength;
+    int   recLength;
+  };
+
+#endif /* _READ_SYNC */
Index: branches/network/src/subprojects/network/simple_sync.cc
===================================================================
--- branches/network/src/subprojects/network/simple_sync.cc	(revision 6636)
+++ branches/network/src/subprojects/network/simple_sync.cc	(revision 6636)
@@ -0,0 +1,123 @@
+/*
+  orxonox - the future of 3D-vertical-scrollers
+
+  Copyright (C) 2004 orx
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+      the Free Software Foundation; either version 2, or (at your option)
+      any later version.
+
+### File Specific:
+    main-programmer: Patrick Boenzli
+    co-programmer:
+*/
+
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+          For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
+#include "simple_sync.h"
+
+#include "debug.h"
+
+
+/**
+ *  default constructor
+ */
+SimpleSync::SimpleSync(const char* name)
+  : Synchronizeable()
+{
+  /* define the local buffer size */
+  this->outLength = 10;
+  this->recLength = 0;
+  this->inLength = 40;
+  this->outData = new byte[this->outLength];
+  this->inData = new byte[this->inLength];
+
+  /* init the buffer data */
+  for( int i = 0; i < this->outLength; i++)
+  {
+    this->outData[i] = i;
+  }
+  for( int i = 0; i < this->inLength; i++)
+  {
+    this->inData[i] = 0;
+  }
+
+}
+
+
+/**
+ *  default destructor deletes all unneded stuff
+ */
+SimpleSync::~SimpleSync()
+{
+  if( this->outData)
+    delete[] this->outData;
+  if( this->inData)
+    delete[] this->inData;
+}
+
+
+/**
+ *  write data to Synchronizeable
+ */
+int SimpleSync::writeBytes(const byte* data, int length, int sender)
+{
+  PRINTF(0)("SimpleSync: got %i bytes of data\n", length);
+  this->recLength = length;
+  if(this->inLength < length)
+    PRINTF(0)("ERROR: local buffer is smaller than the data to receive.\n");
+
+  /* copy the data localy */
+  for( int i = 0; i < length; i++)
+  {
+    this->inData[i] = data[i];
+  }
+  /* and debug output */
+  this->writeDebug();
+}
+
+
+/**
+ *  read data from Synchronizeable
+ */
+int SimpleSync::readBytes(byte* data, int maxLength, int * reciever)
+{
+  PRINTF(0)("SimpleSync: sent %i bytes of data\n", this->outLength);
+
+  /* debug msg */
+  this->readDebug();
+
+  /* write the test message */
+  for( int i = 0; i < this->outLength; i++)
+    data[i] = this->outData[i];
+
+  /* return the length of the test */
+  return this->outLength;
+}
+
+
+void SimpleSync::writeDebug() const
+{
+  PRINTF(0)("Write in bytes: \t(0 <-) |");
+  for(int i = 0; i < this->recLength; i++)
+  {
+    PRINT(0)(" [%u] ",this->inData[i]);
+  }
+  PRINT(0)("|\n");
+}
+
+
+void SimpleSync::readDebug() const
+{
+  PRINTF(0)("Read out bytes: \t(0 ->) |");
+  for(int i = 0; i < this->outLength; i++)
+  {
+    PRINT(0)(" [%u] ",this->outData[i]);
+  }
+  PRINT(0)("|\n");
+}
Index: branches/network/src/subprojects/network/simple_sync.h
===================================================================
--- branches/network/src/subprojects/network/simple_sync.h	(revision 6636)
+++ branches/network/src/subprojects/network/simple_sync.h	(revision 6636)
@@ -0,0 +1,35 @@
+/*!
+ * @file simple_sync.h
+ *  implementation of a network sync test
+ */
+
+#ifndef _SIMPLE_SYNC
+#define _SIMPLE_SYNC
+
+#include "synchronizeable.h"
+
+
+class SimpleSync : public Synchronizeable
+  {
+  public:
+    SimpleSync(const char* name);
+    ~SimpleSync();
+
+    virtual int writeBytes(const byte* data, int length, int sender);
+    virtual int readBytes(byte* data, int maxLength, int * reciever);
+
+
+  private:
+    virtual void writeDebug() const;
+    virtual void readDebug() const;
+
+
+  private:
+    byte* inData;
+    int   inLength;
+    int   recLength;
+    byte* outData;
+    int   outLength;
+  };
+
+#endif /* _SIMPLE_SYNC */
Index: branches/network/src/subprojects/network/write_sync.cc
===================================================================
--- branches/network/src/subprojects/network/write_sync.cc	(revision 6636)
+++ branches/network/src/subprojects/network/write_sync.cc	(revision 6636)
@@ -0,0 +1,123 @@
+/*
+  orxonox - the future of 3D-vertical-scrollers
+
+  Copyright (C) 2004 orx
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+      the Free Software Foundation; either version 2, or (at your option)
+      any later version.
+
+### File Specific:
+    main-programmer: Patrick Boenzli
+    co-programmer:
+*/
+
+
+/* this is for debug output. It just says, that all calls to PRINT() belong to the DEBUG_MODULE_NETWORK module
+          For more information refere to https://www.orxonox.net/cgi-bin/trac.cgi/wiki/DebugOutput
+*/
+#define DEBUG_MODULE_NETWORK
+
+#include "write_sync.h"
+
+#include "debug.h"
+
+
+/**
+ *  default constructor
+ */
+WriteSync::WriteSync(const char* name)
+  : Synchronizeable()
+{
+  /* define the local buffer size */
+  this->outLength = 10;
+  this->recLength = 0;
+  this->inLength = 40;
+  this->outData = new byte[this->outLength];
+  this->inData = new byte[this->inLength];
+
+  /* init the buffer data */
+  for( int i = 0; i < this->outLength; i++)
+  {
+    this->outData[i] = i;
+  }
+  for( int i = 0; i < this->inLength; i++)
+  {
+    this->inData[i] = 0;
+  }
+
+}
+
+
+/**
+ *  default destructor deletes all unneded stuff
+ */
+WriteSync::~WriteSync()
+{
+  if( this->outData)
+    delete[] this->outData;
+  if( this->inData)
+    delete[] this->inData;
+}
+
+
+/**
+ *  write data to Synchronizeable
+ */
+int WriteSync::writeBytes(const byte* data, int length, int sender)
+{
+  PRINTF(0)("WriteSync: got %i bytes of data\n", length);
+  this->recLength = length;
+  if(this->inLength < length)
+    PRINTF(0)("ERROR: local buffer is smaller than the data to receive.\n");
+
+  /* copy the data localy */
+  for( int i = 0; i < length; i++)
+  {
+    this->inData[i] = data[i];
+  }
+  /* and debug output */
+  this->writeDebug();
+}
+
+
+/**
+ *  read data from Synchronizeable
+ */
+int WriteSync::readBytes(byte* data, int maxLength, int * reciever)
+{
+  PRINTF(0)("WriteSync: sent %i bytes of data\n", this->outLength);
+
+  /* debug msg */
+  this->readDebug();
+
+  /* write the test message */
+  for( int i = 0; i < this->outLength; i++)
+    data[i] = this->outData[i];
+
+  /* return the length of the test */
+  return this->outLength;
+}
+
+
+void WriteSync::writeDebug() const
+{
+  PRINTF(0)("Write in bytes: \t(0 <-) |");
+  for(int i = 0; i < this->recLength; i++)
+  {
+    PRINT(0)(" [%u] ",this->inData[i]);
+  }
+  PRINT(0)("|\n");
+}
+
+
+void WriteSync::readDebug() const
+{
+  PRINTF(0)("Read out bytes: \t(0 ->) |");
+  for(int i = 0; i < this->outLength; i++)
+  {
+    PRINT(0)(" [%u] ",this->outData[i]);
+  }
+  PRINT(0)("|\n");
+}
Index: branches/network/src/subprojects/network/write_sync.h
===================================================================
--- branches/network/src/subprojects/network/write_sync.h	(revision 6636)
+++ branches/network/src/subprojects/network/write_sync.h	(revision 6636)
@@ -0,0 +1,35 @@
+/*!
+ * @file simple_sync.h
+ *  implementation of a network sync test
+ */
+
+#ifndef _WRITE_SYNC
+#define _WRITE_SYNC
+
+#include "synchronizeable.h"
+
+
+class WriteSync : public Synchronizeable
+  {
+  public:
+    WriteSync(const char* name);
+    ~WriteSync();
+
+    virtual int writeBytes(const byte* data, int length, int sender);
+    virtual int readBytes(byte* data, int maxLength, int * reciever);
+
+
+  private:
+    virtual void writeDebug() const;
+    virtual void readDebug() const;
+
+
+  private:
+    byte* inData;
+    int   inLength;
+    int   recLength;
+    byte* outData;
+    int   outLength;
+  };
+
+#endif /* _WRITE_SYNC */
Index: branches/network/src/subprojects/others/TTFtoIMG.cc
===================================================================
--- branches/network/src/subprojects/others/TTFtoIMG.cc	(revision 6636)
+++ branches/network/src/subprojects/others/TTFtoIMG.cc	(revision 6636)
@@ -0,0 +1,89 @@
+
+#include <SDL/SDL.h>
+#include <SDL/SDL_ttf.h>
+
+
+
+TTF_Font* fontTTF = NULL;
+
+int getMaxHeight()
+{
+  if (fontTTF != NULL)
+    return TTF_FontHeight(fontTTF);
+  else
+    return 0;
+}
+
+
+void createAsciiImage(const char* fileName, unsigned int size)
+{
+  if (fontTTF == NULL)
+    return;
+  int height = getMaxHeight();
+
+  //
+  SDL_Color tmpColor = {0, 0, 0};
+  // Surface definition.
+  SDL_Rect tmpRect; // this represents a Rectangle for blitting.
+  SDL_Surface* tmpSurf =  SDL_CreateRGBSurface(SDL_SWSURFACE,
+                                               height*16, height*16,
+                                               32,
+#if SDL_BYTEORDER == SDL_LIL_ENDIAN /* OpenGL RGBA masks */
+                                               0x000000FF,
+                                               0x0000FF00,
+                                               0x00FF0000,
+                                               0xFF000000
+#else
+                                               0xFF000000,
+                                               0x00FF0000,
+                                               0x0000FF00,
+                                               0x000000FF
+#endif
+                                              );
+  tmpRect.x = 0; tmpRect.y = 0; tmpRect.w = tmpSurf->w; tmpRect.h = tmpSurf->h;
+  SDL_SetClipRect(tmpSurf, &tmpRect);
+  int maxLineHeight = 0;
+
+  int posX, posY;
+  // all the interessting Glyphs
+  for (posY = 0; posY < 16; posY++)
+  {
+    for (posX = 0; posX < 16; posX++)
+    {
+      SDL_Surface* glyphSurf = NULL;
+      if (fontTTF != NULL)
+      {
+        SDL_Color white = {255, 255, 255};
+        glyphSurf = TTF_RenderGlyph_Blended(fontTTF, posX+16*posY, white);
+      }
+      if( glyphSurf != NULL )
+      {
+        tmpRect.x = height*posX;
+        tmpRect.y = height*posY;
+        SDL_SetAlpha(glyphSurf, 0, 0);
+
+        SDL_BlitSurface(glyphSurf, NULL, tmpSurf, &tmpRect);
+        SDL_FreeSurface(glyphSurf);
+      }
+    }
+  }
+  SDL_SaveBMP(tmpSurf, fileName);
+  SDL_FreeSurface(tmpSurf);
+}
+
+
+
+int main (int argc, const char** argv)
+{
+  SDL_Init(0);
+  TTF_Init();
+  unsigned int renderSize = 32;
+
+  fontTTF = TTF_OpenFont(argv[1], renderSize);
+  
+  createAsciiImage(argv[2], renderSize);
+  
+  //  delete fontTTF;
+  TTF_Quit();
+  SDL_Quit();
+}
Index: branches/network/src/subprojects/particles/Makefile.am
===================================================================
--- branches/network/src/subprojects/particles/Makefile.am	(revision 6636)
+++ branches/network/src/subprojects/particles/Makefile.am	(revision 6636)
@@ -0,0 +1,42 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+
+bin_PROGRAMS = particles
+
+particles_LDADD = $(MAINSRCDIR)/lib/physics/libORXphysics.a \
+                  $(MAINSRCDIR)/lib/event/libORXevent.a \
+                  $(MAINSRCDIR)/lib/particles/libORXparticles.a \
+                  $(MAINSRCDIR)/lib/shell/libORXshell.a \
+                  $(MAINSRCDIR)/lib/sound/libORXsound.a \
+                  $(MAINSRCDIR)/lib/graphics/libORXgraphics.a \
+                  $(MAINSRCDIR)/lib/graphics/importer/libORXimporter.a \
+                  $(MAINSRCDIR)/lib/physics/libORXphysics.a \
+                  $(MAINSRCDIR)/lib/tinyxml/libtinyxml.a \
+                  $(MAINSRCDIR)/lib/collision_detection/libORXcd.a \
+                  $(GTK2_LIBS) $(GTHREAD_LIBS) $(CURL_LIBS)
+
+particles_CPPFLAGS =  -DGUI_MODULE  \
+                      $(GTK2_CFLAGS) $(GTHREAD_CFLAGS) $(CURL_CFLAGS) $(MSBITFIELDS)
+
+particles_SOURCES= ../framework.cc \
+                   particle_fun.cc \
+                   $(MAINSRCDIR)/lib/graphics/light.cc \
+                   $(MAINSRCDIR)/util/state.cc \
+                   $(MAINSRCDIR)/world_entities/camera.cc \
+                   $(MAINSRCDIR)/world_entities/world_entity.cc \
+                   $(MAINSRCDIR)/lib/graphics/graphics_engine.cc \
+                   $(MAINSRCDIR)/lib/lang/base_object.cc \
+                   $(MAINSRCDIR)/lib/lang/class_list.cc \
+                   $(MAINSRCDIR)/lib/math/vector.cc \
+                   $(MAINSRCDIR)/util/loading/resource_manager.cc \
+                   $(MAINSRCDIR)/lib/coord/p_node.cc \
+                   $(MAINSRCDIR)/lib/gui/gtk_gui/gui_gtk.cc \
+                   $(MAINSRCDIR)/lib/util/substring.cc \
+                   $(MAINSRCDIR)/util/loading/load_param.cc \
+                   $(MAINSRCDIR)/util/loading/load_param_description.cc \
+		   $(MAINSRCDIR)/lib/util/helper_functions.cc \
+                   $(MAINSRCDIR)/util/loading/factory.cc \
+                   $(MAINSRCDIR)/lib/util/color.cc \
+                   $(MAINSRCDIR)/lib/parser/ini_parser/ini_parser.cc
+
Index: branches/network/src/subprojects/particles/particle_fun.cc
===================================================================
--- branches/network/src/subprojects/particles/particle_fun.cc	(revision 6636)
+++ branches/network/src/subprojects/particles/particle_fun.cc	(revision 6636)
@@ -0,0 +1,470 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+
+   this file extends the framework file, so it renders what i want.
+*/
+
+#include "framework.h"
+
+#include "physics_engine.h"
+#include "particle_engine.h"
+#include "fields.h"
+#include "stdlibincl.h"
+#include "graphics_engine.h"
+#include "light.h"
+#include "resource_manager.h"
+
+#include <dirent.h>
+
+#define PINIT_EMISSION_RATE          50
+#define PINIT_EMISSION_VELOCITY      5.0
+#define PINIT_EMISSION_MOMENTUM      1.0
+#define PINIT_SPREAD_ANGLE           0.1
+#define PINIT_EMITTER_TYPE           EMITTER_DOT
+#define PINIT_EMITTER_SIZE           1.0
+#define PINIT_START_RADIUS           5.0
+#define PINIT_END_RADIUS             0.0
+#define PINIT_LIFESPAN               1.0
+#define PINIT_CONSERVE_FACTOR        1.0
+#define PINIT_PARTICLE_TYPE          PARTICLE_SPRITE
+#define PINIT_INHERIT_SPEED          0.0
+#define PINIT_PARTICLE_MASS          1.0
+#define PINIT_MODEL_DIRECTORY        "models/"
+
+
+Field* twirl;
+Field* gravity;
+Field* pointGravity;
+
+void Framework::moduleInit(int argc, char** argv)
+{
+  GraphicsEngine::getInstance()->setWindowName("ParticlesFun", "particles");
+
+  verbose = 5;
+  ParticleEngine::getInstance();
+  PhysicsEngine::getInstance();
+
+
+  // Creating a Test Particle System
+
+  ParticleSystem* system = new ParticleSystem(100000, PINIT_PARTICLE_TYPE);
+  system->setRadius(0, PINIT_START_RADIUS, 0 );
+  system->setRadius(1, PINIT_END_RADIUS, 0 );
+  system->setLifeSpan(PINIT_LIFESPAN);
+
+  system->setConserve(PINIT_CONSERVE_FACTOR);
+  //system->setMass(5,3,6);
+
+  // Creating a Test Particle Emitter
+  ParticleEmitter* emitter = new ParticleEmitter(Vector(0 , 1, 0));
+  emitter->setEmissionRate(PINIT_EMISSION_RATE);
+  emitter->setEmissionVelocity(PINIT_EMISSION_VELOCITY ,0);
+  emitter->setSpread(PINIT_SPREAD_ANGLE ,0);
+  emitter->setType(PINIT_EMITTER_TYPE);
+  emitter->setSize(PINIT_EMITTER_SIZE);
+  emitter->setAbsCoor(Vector(3,0,0));
+  // Add the Flow from the Emitter into the System
+  ParticleEngine::getInstance()->addConnection(emitter, system);
+
+
+  twirl = new Twirl();
+  twirl->setMagnitude(0);
+  gravity = new Gravity();
+  gravity->setMagnitude(0);
+  pointGravity = new PointGravity();
+  pointGravity->setMagnitude(0);
+
+  new PhysicsConnection(system, gravity);
+  new PhysicsConnection(system, twirl);
+  new PhysicsConnection(system, pointGravity);
+
+  (new Light)->setAbsCoor(10, 10, 10);
+
+}
+
+void Framework::moduleEventHandler(SDL_Event* event)
+{
+  switch (event->type)
+    {
+    case SDL_KEYDOWN:
+      switch (event->key.keysym.sym)
+        {
+        case SDLK_i:
+          ParticleEngine::getInstance()->debug();
+          PhysicsEngine::getInstance()->debug();
+          break;
+        }
+    }
+}
+
+void Framework::moduleTick(float dt)
+{
+  PhysicsEngine::getInstance()->tick(dt);
+  ParticleEngine::getInstance()->tick(dt);
+}
+
+void Framework::moduleDraw() const
+{
+  ParticleEngine::getInstance()->draw();
+}
+
+
+void Framework::moduleHelp(void) const
+{
+  PRINT(0)("\n");
+  PRINT(0)("i - Particle-state Information\n\n");
+  PRINT(0)("\n");
+}
+
+int emitterChange(GtkWidget* nonInterest, void* widget)
+{
+  Option* option = (Option*) widget;
+  const char* name = option->getTitle();
+  char* value = option->save();
+
+  ParticleEmitter* tmpEmit = ParticleEngine::getInstance()->getEmitterByNumber(1);
+  if (tmpEmit)
+    {
+      if (!strcmp(name, "EmissionRate"))
+        {
+          tmpEmit->setEmissionRate(atof(value));
+          PRINT(4)("EmissionRate set to %f\n", atof(value));
+        }
+      else if (!strcmp(name, "Velocity"))
+        {
+          tmpEmit->setEmissionVelocity(atof(value));
+          PRINT(4)("Velocity set to %f\n", atof(value));
+        }
+      else if (!strcmp(name, "Momentum"))
+        {
+          tmpEmit->setEmissionMomentum(atof(value));
+          PRINT(4)("Momentum set to %f\n", atof(value));
+        }
+      else if(!strcmp(name, "SpreadAngle"))
+        {
+          tmpEmit->setSpread(atof(value), 0);
+          PRINT(4)("SpreadAngle set to %f\n", atof(value));
+        }
+      else if(!strcmp(name, "EmitterType"))
+        {
+          if (!strcmp(value, "EMITTER_DOT"))
+            tmpEmit->setType(EMITTER_DOT);
+          else if (!strcmp(value, "EMITTER_PLANE"))
+            tmpEmit->setType(EMITTER_PLANE);
+          else if (!strcmp(value, "EMITTER_CUBE"))
+            tmpEmit->setType(EMITTER_CUBE);
+          PRINT(4)("EmitterType set to %s\n", value);
+        }
+      else if(!strcmp(name, "EmitterSize"))
+        {
+          tmpEmit->setSize(atof(value));
+          PRINT(4)("EmitterSize set to %f\n", atof(value));
+        }
+        else if (!strcmp(name, "InheritSpeed"))
+        {
+          tmpEmit->setInheritSpeed(atof(value));
+          PRINT(4)("ParticleInheritSpeed set to %f\n", atof(value));
+        }
+    }
+  delete value;
+}
+
+
+int systemChange(GtkWidget* nonInterest, void* widget)
+{
+  Option* option = (Option*) widget;
+  const char* name = option->getTitle();
+  char* value = option->save();
+
+  ParticleSystem* tmpSys = ParticleEngine::getInstance()->getSystemByNumber(1);
+  if (tmpSys)
+    {
+      if (!strcmp(name, "StartRadius"))
+        {
+          tmpSys->setRadius(0, atof(value));
+          PRINT(4)("ParticleStartRadius set to %f\n", atof(value));
+        }
+      else if (!strcmp(name, "EndRadius"))
+        {
+          tmpSys->setRadius( 1, atof(value));
+          PRINT(4)("ParticleEndRadius set to %f\n", atof(value));
+        }
+
+      else if (!strcmp(name, "LifeSpan"))
+        {
+          tmpSys->setLifeSpan(atof(value));
+          PRINT(4)("ParticleLifeSpan set to %f\n", atof(value));
+        }
+
+      else if (!strcmp(name, "Mass"))
+        {
+          tmpSys->setMass(0, atof(value));
+          PRINT(4)("ParticleMass set to %f\n", atof(value));
+        }
+
+      else if (!strcmp(name, "ConserveFactor"))
+        {
+          tmpSys->setConserve(atof(value));
+          PRINT(4)("ParticleConserveFactor set to %f\n", atof(value));
+        }
+
+      else if (!strcmp(name, "ParticleType"))
+        {
+          if (!strcmp(value, "PARTICLE_DOT"))
+            tmpSys->setType(PARTICLE_DOT);
+          else if (!strcmp(value, "PARTICLE_SPARK"))
+            tmpSys->setType(PARTICLE_SPARK);
+          else if (!strcmp(value, "PARTICLE_SPRITE"))
+            tmpSys->setType(PARTICLE_SPRITE);
+
+          PRINT(4)("ParticleType set to %s\n", value);
+        }
+        else if(!strcmp(name, "ParticleModel"))
+        {
+          char* modelName = new char[strlen(PINIT_MODEL_DIRECTORY) + strlen(value)+1];
+          sprintf(modelName, "%s%s", PINIT_MODEL_DIRECTORY, value);
+          tmpSys->loadModel(modelName);
+          delete modelName;
+        }
+      else if (!strcmp(name, "RandomColor"))
+        {
+          tmpSys->setColor(0, (float)rand()/RAND_MAX, (float)rand()/RAND_MAX, (float)rand()/RAND_MAX, 1);
+          tmpSys->setColor(.5, (float)rand()/RAND_MAX, (float)rand()/RAND_MAX, (float)rand()/RAND_MAX, .5);
+          tmpSys->setColor(.5, (float)rand()/RAND_MAX, (float)rand()/RAND_MAX, (float)rand()/RAND_MAX, 0);
+        }
+    }
+  delete value;
+}
+
+int fieldsChange(GtkWidget* nonInterest, void* widget)
+{
+  Option* option = (Option*) widget;
+  const char* name = option->getTitle();
+  char* value = option->save();
+
+
+  if (!strcmp(name, "Gravity"))
+    {
+      gravity->setMagnitude(atof(value));
+    }
+
+  else if (!strcmp(name, "Twirl"))
+    {
+      twirl->setMagnitude(atof(value));
+    }
+
+  else if (!strcmp(name, "PointGravity"))
+    {
+      pointGravity->setMagnitude(atof(value));
+    }
+
+}
+
+void Framework::moduleInitGui(int argc, char** argv)
+{
+  Window* guiMainWindow = NULL;
+
+  initGUI(0, NULL);
+
+  guiMainWindow = new Window("ParticlesFUN");
+  {
+    Box* windowBox = new Box('h');
+    {
+      Frame* emitterFrame = new Frame("emitter-settings");
+      {
+        Box* emitterBox = new Box('v');
+        {
+          emitterBox->fill(new Label("EmissionRate"));
+          Slider* EmissionRate = new Slider("EmissionRate", 0, 1000);
+          EmissionRate->connectSignal("value_changed", (void*)EmissionRate, emitterChange );
+          EmissionRate->setValue(PINIT_EMISSION_RATE);
+          EmissionRate->redraw();
+          emitterBox->fill(EmissionRate);
+
+          emitterBox->fill(new Label("Velocity"));
+          Slider* velocity = new Slider("Velocity", 0, 20);
+          velocity->setExactness(2);
+          velocity->connectSignal("value_changed", (void*)velocity, emitterChange );
+          velocity->setValue(PINIT_EMISSION_VELOCITY);
+          velocity->redraw();
+          emitterBox->fill(velocity);
+
+          emitterBox->fill(new Label("Momentum"));
+          Slider* Momentum = new Slider("Momentum", 0, 20);
+          Momentum->setExactness(2);
+          Momentum->connectSignal("value_changed", (void*)Momentum, emitterChange );
+          Momentum->setValue(PINIT_EMISSION_MOMENTUM);
+          Momentum->redraw();
+          emitterBox->fill(Momentum);
+
+          emitterBox->fill(new Label("SpreadAngle"));
+          Slider* SpreadAngle = new Slider("SpreadAngle", 0, M_PI);
+          SpreadAngle->setExactness(3);
+          SpreadAngle->connectSignal("value_changed", (void*)SpreadAngle, emitterChange );
+          SpreadAngle->setValue(PINIT_SPREAD_ANGLE);
+          SpreadAngle->redraw();
+          emitterBox->fill(SpreadAngle);
+
+          emitterBox->fill(new Label("EmitterType"));
+          Menu* EmitterType = new Menu("EmitterType");
+          EmitterType->addItem("EMITTER_DOT");
+          EmitterType->addItem("EMITTER_PLANE");
+          EmitterType->addItem("EMITTER_CUBE");
+          EmitterType->connectSignal("changed", (void*)EmitterType, emitterChange );
+          EmitterType->load("EMITTER_DOT");
+          emitterBox->fill(EmitterType);
+
+          emitterBox->fill(new Label("EmitterSize"));
+          Slider* EmitterSize = new Slider("EmitterSize", 0, 100);
+          EmitterSize->setExactness(1);
+          EmitterSize->connectSignal("value_changed", (void*)EmitterSize, emitterChange );
+          EmitterSize->setValue(PINIT_EMITTER_SIZE);
+          EmitterSize->redraw();
+          emitterBox->fill(EmitterSize);
+
+          emitterBox->fill(new Label("InheritSpeed"));
+          Slider* InheritSpeed = new Slider("InheritSpeed", 0, 1);
+          InheritSpeed->setExactness(3);
+          InheritSpeed->connectSignal("value_changed", (void*)InheritSpeed, emitterChange );
+          emitterBox->fill(InheritSpeed);
+        }
+        emitterFrame->fill(emitterBox);
+      }
+      windowBox->fill(emitterFrame);
+
+      Frame* systemFrame = new Frame("system-settings");
+      {
+        Box* systemBox = new Box('v');
+        {
+          systemBox->fill(new Label("StartRadius"));
+          Slider* StartRadius = new Slider("StartRadius", 0, 10);
+          StartRadius->setExactness(3);
+          StartRadius->connectSignal("value_changed", (void*)StartRadius, systemChange );
+          StartRadius->setValue(PINIT_START_RADIUS);
+          StartRadius->redraw();
+          systemBox->fill(StartRadius);
+
+          systemBox->fill(new Label("EndRadius"));
+          Slider* EndRadius = new Slider("EndRadius", 0, 10);
+          EndRadius->setExactness(3);
+          EndRadius->connectSignal("value_changed", (void*)EndRadius, systemChange );
+          EndRadius->setValue(PINIT_END_RADIUS);
+          EndRadius->redraw();
+          systemBox->fill(EndRadius);
+
+          systemBox->fill(new Label("ParticleMass"));
+          Slider* Mass = new Slider("Mass", 0, 10);
+          Mass->setExactness(2);
+          Mass->connectSignal("value_changed", (void*)Mass, systemChange );
+          Mass->setValue(PINIT_PARTICLE_MASS);
+          Mass->redraw();
+          systemBox->fill(Mass);
+
+
+          systemBox->fill(new Label("LifeSpan"));
+          Slider* LifeSpan = new Slider("LifeSpan", 0, 10);
+          LifeSpan->setExactness(3);
+          LifeSpan->connectSignal("value_changed", (void*)LifeSpan, systemChange );
+          LifeSpan->setValue(PINIT_LIFESPAN);
+          LifeSpan->redraw();
+          systemBox->fill(LifeSpan);
+
+          systemBox->fill(new Label("ConserveFactor"));
+          Slider* ConserveFactor = new Slider("ConserveFactor", 0, 1);
+          ConserveFactor->setExactness(3);
+          ConserveFactor->connectSignal("value_changed", (void*)ConserveFactor, systemChange );
+          ConserveFactor->setValue(PINIT_CONSERVE_FACTOR);
+          ConserveFactor->redraw();
+          systemBox->fill(ConserveFactor);
+
+          systemBox->fill(new Label("ParticleType"));
+          Menu* ParticleType = new Menu("ParticleType");
+          ParticleType->addItem("PARTICLE_DOT");
+          ParticleType->addItem("PARTICLE_SPARK");
+          ParticleType->addItem("PARTICLE_SPRITE");
+          ParticleType->connectSignal("changed", (void*)ParticleType, systemChange );
+          ParticleType->load("PARTICLE_SPRITE");
+          systemBox->fill(ParticleType);
+
+          systemBox->fill(new Label("ParticleModel"));
+          Menu* ParticleModel = new Menu("ParticleModel");
+          {
+            DIR* directory;
+            directory = opendir(ResourceManager::getFullName(PINIT_MODEL_DIRECTORY));
+            dirent* file;
+            while(file = readdir(directory))
+              if(strstr(file->d_name, ".obj"))
+                 ParticleModel->addItem(file->d_name);
+          }
+          ParticleModel->connectSignal("changed", (void*)ParticleModel, systemChange );
+          systemBox->fill(ParticleModel);
+
+
+          Button* RandomColor = new Button("RandomColor");
+          RandomColor->connectSignal("released", (void*)RandomColor, systemChange);
+          systemBox->fill(RandomColor);
+
+        }
+        systemFrame->fill(systemBox);
+      }
+      windowBox->fill(systemFrame);
+
+      Frame* fieldsFrame = new Frame("Field-Settings");
+      {
+        Box* fieldsBox = new Box('v');
+        {
+          fieldsBox->fill(new Label("Gravity"));
+          Slider* Gravity = new Slider("Gravity", 0, 10);
+          Gravity->setExactness(1);
+          Gravity->connectSignal("value_changed", (void*)Gravity, fieldsChange );
+          Gravity->setValue(0);
+          Gravity->redraw();
+          fieldsBox->fill(Gravity);
+
+
+          fieldsBox->fill(new Label("Twirl"));
+          Slider* Twirl = new Slider("Twirl", 0, 10);
+          Twirl->setExactness(1);
+          Twirl->connectSignal("value_changed", (void*)Twirl, fieldsChange );
+          Twirl->setValue(0);
+          Twirl->redraw();
+          fieldsBox->fill(Twirl);
+
+
+          fieldsBox->fill(new Label("PointGravity"));
+          Slider* PointGravity = new Slider("PointGravity", 0, 10);
+          PointGravity->setExactness(1);
+          PointGravity->connectSignal("value_changed", (void*)PointGravity, fieldsChange );
+          PointGravity->setValue(0);
+          PointGravity->redraw();
+          fieldsBox->fill(PointGravity);
+
+        }
+        fieldsFrame->fill(fieldsBox);
+      }
+      windowBox->fill(fieldsFrame);
+
+      Button* quitButton = new Button("quit");
+
+      quitButton->connectSignal("clicked", NULL, quitGui);
+      //  Window::mainWindow->connectSignal("remove", this, GuiExec::quitGui);
+      Window::mainWindow->connectSignal("destroy", NULL, quitGui);
+      windowBox->fill(quitButton);
+
+    }
+    guiMainWindow->fill(windowBox);
+  }
+  Window::mainWindow->showall();
+  Window::mainWindow->setSize(300, 500);
+}
Index: branches/network/src/subprojects/testmain/Makefile.am
===================================================================
--- branches/network/src/subprojects/testmain/Makefile.am	(revision 6636)
+++ branches/network/src/subprojects/testmain/Makefile.am	(revision 6636)
@@ -0,0 +1,13 @@
+MAINSRCDIR=../..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+
+AM_LDFLAGS=$(MWINDOWS)
+
+#"-O3 -pedantic -fPIC -ffast-math -I/usr/X11R6/include"
+
+
+bin_PROGRAMS=testmain
+testmain_SOURCES= testmain.cc
+
+noinst_HEADERS= 
Index: branches/network/src/subprojects/testmain/testmain.cc
===================================================================
--- branches/network/src/subprojects/testmain/testmain.cc	(revision 6636)
+++ branches/network/src/subprojects/testmain/testmain.cc	(revision 6636)
@@ -0,0 +1,16 @@
+#include <dirent.h>
+#include <stdio.h>
+
+int main(int argc, char** argv)
+{
+  DIR* directory;
+  directory = opendir("/");
+  dirent* test;
+
+  while(test = readdir(directory))
+  {
+    printf("%s\n", test->d_name);
+  }
+
+
+}
Index: branches/network/src/util/Makefile.am
===================================================================
--- branches/network/src/util/Makefile.am	(revision 6636)
+++ branches/network/src/util/Makefile.am	(revision 6636)
@@ -0,0 +1,37 @@
+MAINSRCDIR=..
+include $(MAINSRCDIR)/defs/include_paths.am
+
+noinst_LIBRARIES = libORXutils.a
+
+libORXutils_a_SOURCES = fast_factory.cc \
+			object_manager.cc \
+                        loading/factory.cc \
+			state.cc \
+			hud.cc \
+			animation/animation3d.cc \
+			animation/animation.cc \
+			animation/animation_player.cc \
+			loading/resource_manager.cc \
+			loading/game_loader.cc \
+			loading/load_param.cc \
+			loading/load_param_description.cc \
+			track/pilot_node.cc \
+			track/track_manager.cc \
+			track/track_node.cc
+
+noinst_HEADERS =        fast_factory.h \
+			object_manager.h \
+			state.h \
+			hud.h \
+			animation/animation3d.h \
+			animation/animation.h \
+			animation/animation_player.h \
+			animation/t_animation.h \
+			loading/resource_manager.h \
+			loading/factory.h \
+			loading/game_loader.h \
+			loading/load_param.h \
+			loading/load_param_description.h \
+			track/pilot_node.h \
+			track/track_manager.h \
+			track/track_node.h
Index: branches/network/src/util/animation/animation.cc
===================================================================
--- branches/network/src/util/animation/animation.cc	(revision 6636)
+++ branches/network/src/util/animation/animation.cc	(revision 6636)
@@ -0,0 +1,134 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_ANIM
+
+#include "animation.h"
+#include "debug.h"
+#include "animation_player.h"
+
+/**
+ *  creates a new Animation
+
+   This also adds the Animation automatically to the AnimationPlayer's list
+*/
+Animation::Animation()
+{
+  this->setClassID(CL_ANIMATION, "Animation");
+
+  // initialize a beginning KeyFrame, that will be deleted afterwards
+  this->keyFrameCount = 0;
+  this->bDelete = false;
+  this->baseObject = NULL;
+
+  // setting default values
+  this->keyFramesToPlay = -1;
+  this->localTime = 0.0;
+  this->bRunning = false;
+
+  AnimationPlayer::getInstance()->addAnimation(this);
+}
+
+/**
+ *  destructs the Animation
+
+   this also takes the animation out of the AnimationPlayer's list (if it is there)
+*/
+Animation::~Animation()
+{
+  AnimationPlayer::getInstance()->removeAnimation(this);
+}
+
+
+/**
+ *  Sets the infinitymode
+ * @param postInfinity How the Animation should advance after the last Keyframe
+*/
+void Animation::setInfinity(ANIM_INFINITY postInfinity)
+{
+  this->postInfinity = postInfinity;
+}
+
+/**
+ *  handles the Animation if it gets out of boundraries eg. if animation is finished.
+*/
+void Animation::handleInfinity()
+{
+  switch (this->postInfinity)
+    {
+    case ANIM_INF_CONSTANT:
+      this->localTime = 0.0;
+      this->bRunning = false;
+      break;
+    case ANIM_INF_REPLAY:
+      this->rewind();
+      this->bRunning = true;
+      break;
+    case ANIM_INF_REWIND:
+      this->stop();
+      break;
+    case ANIM_INF_DELETE: // this will possibly never be made
+      this->bDelete = true;
+      break;
+    }
+}
+
+/**
+ *  plays the animation back from the current Time forward
+*/
+void Animation::play()
+{
+  this->keyFramesToPlay = -1;
+  this->bRunning = true;
+}
+
+/**
+ *  plays the Next n keyframes
+ * @param n the Count of keyFrames to play.
+*/
+void Animation::playNextKeyframes(int n)
+{
+  this->keyFramesToPlay = n-1;
+  this->bRunning = true;
+}
+
+/**
+ *  Stops the animation. eg. pause(); rewind();
+*/
+void Animation::stop()
+{
+  this->keyFramesToPlay = -1;
+  this->rewind();
+  this->bRunning = true;
+  this->tick(0.0);
+  this->bRunning = false;
+}
+
+/**
+ *  Pauses the animation. Stays at the current Time
+*/
+void Animation::pause()
+{
+  this->bRunning = false;
+}
+
+/**
+ *  replays the animation, eg. rewind();play();
+*/
+void Animation::replay()
+{
+  this->rewind();
+  this->play();
+}
Index: branches/network/src/util/animation/animation.h
===================================================================
--- branches/network/src/util/animation/animation.h	(revision 6636)
+++ branches/network/src/util/animation/animation.h	(revision 6636)
@@ -0,0 +1,138 @@
+/*!
+ * @file animation.h
+    A Subclass for all animations in orxonox
+*/
+
+#ifndef _ANIMATION_H
+#define _ANIMATION_H
+
+#include "base_object.h"
+#include "debug.h"
+
+#include "list.h"
+// FORWARD DECLARATION
+
+//! An enumerator of Functions to describe the flow of the Animation
+/**
+   @todo check with Patrick it of
+
+   description in speed to the next keyframe:
+   ANIM_CONSTANT: 0, infinity.
+   ANIM_LINEAR: equal
+   ANIM_SINE: fast, slow, fast
+   ANIM_COSINE: slow, fast, slow
+   ANIM_EXP: slow, fast
+   ANIM_NEG_EXP: fast, slow
+   ANIM_RANDOM: eratic
+
+   ANIM_NULL: !!DO NOT USE THIS!! only for internal handling
+
+   deprecated QUADRATIC
+*/
+typedef enum ANIM_FUNCTION
+{
+  ANIM_NULL         = 0,
+  ANIM_CONSTANT     = 1,
+  ANIM_LINEAR       = 2,
+  ANIM_SINE         = 3,
+  ANIM_COSINE       = 4,
+  ANIM_EXP          = 5,
+  ANIM_NEG_EXP      = 6,
+  ANIM_QUADRATIC    = 7,
+  ANIM_RANDOM       = 8,
+};
+
+#define ANIM_DEFAULT_FUNCTION ANIM_LINEAR      //!< A default function to choose from the above set
+
+//! An enumerator describing what the animation should do after the last keyframe.
+/**
+   ANIM_INF_CONSTANT stays at the end of the animation
+   ANIM_INF_REPLAY loops back to the beginning and replays the animation
+   ANIM_INF_REWIND loops back to the beginning and then stops the animation
+   ANIM_INF_DELETE deletes the animation. !! THIS IS DANGEROUS !! only do this with non-class variables
+*/
+typedef enum ANIM_INFINITY
+{
+  ANIM_INF_CONSTANT,
+  ANIM_INF_REPLAY,
+  ANIM_INF_REWIND,
+  ANIM_INF_DELETE
+}; //, ANIM_INF_LINEAR, ANIM_INF_PINGPONG};
+
+//! A Superclass for describing an animation (all animations will be derived from this one)
+/** implement in subclasses:
+ *
+ * De-/Constructor
+ * Animation Functions
+ * virtual tick
+ * addKeyFrame
+ * List of keyFrames
+ * currentKeyFrame/nextKeyFrame
+ * virtual rewind, to go to the first Keyframe. (other functions will call this one)
+*/
+class Animation : public BaseObject
+{
+ public:
+  virtual ~Animation();
+
+  void setInfinity(ANIM_INFINITY postInfinity = ANIM_INF_CONSTANT);
+
+  void play(); // equals resume();
+  void playNextKeyframes(int n = 1);
+  void stop();
+  void pause();
+  void replay();
+  //! A virtual function that should change to the first keyframe.
+  virtual void rewind() = 0;
+
+  /** A virtual function that ticks the animation @param dt the time passed */
+  virtual void tick(float dt) = 0;
+
+  /** @returns the BaseObject, this animation operates on */
+  BaseObject* getBaseObject() const { return this->baseObject; };
+
+  /** @returns if the Animation should be deleted */
+  inline bool ifDelete() { return bDelete; };
+
+ protected:
+  Animation();
+
+  void handleInfinity();
+
+ protected:
+  // variables
+  float                 localTime;              //!< The Time passed since the beginning of the currentKeyFrame.
+  ANIM_INFINITY         postInfinity;           //!< describing what the animation should do after the last keyframe.
+
+  BaseObject*           baseObject;             //!< The same as object in the derived classes, but with reference to BaseObject
+  unsigned int          keyFrameCount;          //!< The Count of KeyFrames.
+  int                   keyFramesToPlay;        //!< How many more Keyframes to play. if negative it will be ignored if 0 stop.
+  bool                  bRunning;               //!< If the animation is running
+  bool                  bDelete;                //!< If true, the animation will be deleted through the AnimationPlayer.
+};
+
+
+
+
+/**********************TEST*******************************/
+//! a simple testClass for the animation
+class aTest
+{
+ public:
+  inline aTest() { last = 0.0;}
+  /** a little debug information to show the results of this class @param f new value */
+  inline void littleDebug(float f) {  diff = f - last; printf("f=%f, diff=%f\n", f,diff); last = f;}
+ private:
+  float     diff;           //!< difference from the last value
+  float     last;           //!< the last calculated value
+};
+
+//aTest::aTest() {}
+//aTest::~aTest() {}
+
+//void aTest::littleDebug(float f)
+
+/**********************TEST*******************************/
+
+
+#endif /* _ANIMATION_H */
Index: branches/network/src/util/animation/animation3d.cc
===================================================================
--- branches/network/src/util/animation/animation3d.cc	(revision 6636)
+++ branches/network/src/util/animation/animation3d.cc	(revision 6636)
@@ -0,0 +1,486 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: Benjamin Grauer
+
+   2005-04-17: Benjamin Grauer
+          Rewritte all functions, so it will fit into the Animation-class
+   2005-04-25: Patrick Boenzli
+          Extended the framework to support quatSlerp rotations. Each frame now supports diff mov/rot types. Implemented mov/rot functions
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_ANIM
+
+#include "animation3d.h"
+
+#include "p_node.h"
+
+using namespace std;
+
+/**
+ *  standard constructor
+*/
+Animation3D::Animation3D(PNode* object)
+{
+  this->object = object;
+
+  // create a new List
+  this->keyFrameList = new tList<KeyFrame3D>();
+  KeyFrame3D* tmpKeyFrame = new KeyFrame3D;
+  tmpKeyFrame->position = Vector();
+  tmpKeyFrame->direction = Quaternion();
+  keyFrameList->add(tmpKeyFrame);
+
+  this->currentKeyFrame = tmpKeyFrame;
+  this->nextKeyFrame = tmpKeyFrame;
+
+  this->animFuncMov = NULL;//&Animation3D::mLinear;
+  this->animFuncRot = NULL;//&Animation3D::rLinear;
+
+}
+
+/**
+ *  standard deconstructor
+
+   deletes all the Keyframes
+*/
+Animation3D::~Animation3D()
+{
+  // delete all the KeyFrames
+  tIterator<KeyFrame3D>* itKF = keyFrameList->getIterator();
+  KeyFrame3D*  enumKF = itKF->firstElement();
+  while (enumKF)
+    {
+      delete enumKF;
+      enumKF = itKF->nextElement();
+    }
+  delete itKF;
+  delete this->keyFrameList;
+}
+
+/**
+ *  rewinds the Animation to the beginning (first KeyFrame and time == 0)
+*/
+void Animation3D::rewind()
+{
+  this->currentKeyFrame = keyFrameList->firstElement();
+  this->nextKeyFrame = keyFrameList->nextElement(keyFrameList->firstElement());
+  this->localTime = 0.0;
+  this->setAnimFuncMov(this->currentKeyFrame->animFuncMov);
+  this->setAnimFuncRot(this->currentKeyFrame->animFuncRot);
+}
+
+/**
+ *  Appends a new Keyframe
+ * @param position The position of the new Keyframe
+ * @param direction The direction of the new Keyframe.
+ * @param duration The duration from the new KeyFrame to the next one
+ * @param animFuncMov The function to animate position between this keyFrame and the next one
+ * @param animFuncRot The function to animate rotation between this keyFrame and the next one
+*/
+void Animation3D::addKeyFrame(Vector position, Quaternion direction, float duration,
+                              ANIM_FUNCTION animFuncMov, ANIM_FUNCTION animFuncRot)
+{
+  // some small check
+  if (duration <= 0.0)
+    duration = 1.0;
+  // if the Rotation-Animation-function is set ANIM_NULL, animFuncRot will match animFuncRot
+//  if (animFuncMov == ANIM_NULL)
+//    animFuncMov = ANIM_DEFAULT_FUNCTION;
+//  if (animFuncRot == ANIM_NULL)
+//    animFuncRot = animFuncMov;
+
+  KeyFrame3D* tmpKeyFrame;
+
+  // when adding the first frame
+  if (this->keyFrameCount == 0)
+    {
+      tmpKeyFrame = this->keyFrameList->firstElement();
+      //this->setAnimFuncMov(animFuncMov);
+      //this->setAnimFuncRot(animFuncRot);
+    }
+  else
+    {
+      tmpKeyFrame = new KeyFrame3D;
+      // when adding the second frame
+      if (this->currentKeyFrame == this->nextKeyFrame)
+        this->nextKeyFrame = tmpKeyFrame;
+      this->keyFrameList->add(tmpKeyFrame);
+    }
+
+  tmpKeyFrame->position = position;
+  //tmpKeyFrame->lastPosition = position;
+  tmpKeyFrame->direction = direction;
+  tmpKeyFrame->duration = duration;
+  tmpKeyFrame->animFuncMov = animFuncMov;
+  tmpKeyFrame->animFuncRot = animFuncRot;
+  this->keyFrameCount++;
+}
+
+/**
+ *  ticks the Animation
+ * @param dt how much time to tick
+*/
+void Animation3D::tick(float dt)
+{
+  if (this->bRunning)
+    {
+      this->localTime += dt;
+      if (localTime >= this->currentKeyFrame->duration)
+        {
+          if (likely(this->keyFramesToPlay != 0))
+            {
+              if (unlikely(this->keyFramesToPlay > 0))
+                --this->keyFramesToPlay;
+              // switching to the next Key-Frame
+              this->localTime -= this->currentKeyFrame->duration;
+              this->currentKeyFrame = this->nextKeyFrame;
+              // checking, if we should still Play the animation
+              if (this->currentKeyFrame == this->keyFrameList->lastElement())
+                this->handleInfinity();
+              this->nextKeyFrame = this->keyFrameList->nextElement(this->currentKeyFrame);
+              this->setAnimFuncMov(this->currentKeyFrame->animFuncMov);
+              this->setAnimFuncRot(this->currentKeyFrame->animFuncRot);
+            }
+          else
+            this->pause();
+        }
+      /* now animate it */
+      if (likely(this->animFuncMov != NULL))
+        (this->*animFuncMov)(this->localTime);
+      if (likely(this->animFuncRot != NULL))
+        (this->*animFuncRot)(this->localTime);
+    }
+}
+
+
+/*==Movement Section==========================================================*/
+
+/**
+ *  Sets The kind of movment Animation between this keyframe and the next one
+ * @param animFuncMov: The Type of Animation to set
+*/
+void Animation3D::setAnimFuncMov(ANIM_FUNCTION animFuncMov)
+{
+  switch (animFuncMov)
+    {
+    case ANIM_CONSTANT:
+      this->animFuncMov = &Animation3D::mConstant;
+      break;
+    case ANIM_LINEAR:
+      this->animFuncMov = &Animation3D::mLinear;
+      this->object->setRelCoor(this->currentKeyFrame->position);
+      this->currentKeyFrame->lastPosition = Vector();
+      break;
+    case ANIM_SINE:
+      this->animFuncMov = &Animation3D::mSine;
+      this->object->setRelCoor(this->currentKeyFrame->position);
+      this->currentKeyFrame->lastPosition = Vector();
+      break;
+    case ANIM_COSINE:
+      this->animFuncMov = &Animation3D::mCosine;
+      this->object->setRelCoor(this->currentKeyFrame->position);
+      this->currentKeyFrame->lastPosition = Vector();
+      break;
+    case ANIM_EXP:
+      this->object->setRelCoor(this->currentKeyFrame->position);
+      this->animFuncMov = &Animation3D::mExp;
+      break;
+    case ANIM_NEG_EXP:
+      this->animFuncMov = &Animation3D::mNegExp;
+      this->object->setRelCoor(this->currentKeyFrame->position);
+      this->expFactorMov = -1.0 / this->currentKeyFrame->duration * logf(DELTA_X_3D);
+      this->currentKeyFrame->lastPosition = Vector();
+      break;
+    case ANIM_QUADRATIC:
+      this->object->setRelCoor(this->currentKeyFrame->position);
+      this->animFuncMov = &Animation3D::mQuadratic;
+      break;
+    case ANIM_RANDOM:
+      this->object->setRelCoor(this->currentKeyFrame->position);
+      this->animFuncMov = &Animation3D::mRandom;
+      break;
+    default:
+      this->animFuncMov = NULL;
+      break;
+    }
+}
+
+/**
+ *  stays at the value of the currentKeyFrame
+ * @param timePassed The time passed since this Keyframe began
+*/
+void Animation3D::mConstant(float timePassed) const
+{
+  //this->object->setRelCoor(this->currentKeyFrame->position);
+
+  /*
+    this->tmpVect = this->nextKeyFrame->position - this->currentKeyFrame->position;
+    this->tmpVect = this->tmpVect * this->localTime / this->currentKeyFrame->duration;
+    this->currentFrame->object->setRelCoor(*this->lastFrame->position + *this->tmpVect);
+    this->lastPosition = this->tmpVect;
+  */
+}
+
+/**
+ *  linear interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+
+   @todo implement also do this for direction
+*/
+void Animation3D::mLinear(float timePassed) const
+{
+  Vector v = (this->nextKeyFrame->position - this->currentKeyFrame->position) * (timePassed/this->currentKeyFrame->duration);
+  this->object->shiftCoor(v - this->currentKeyFrame->lastPosition);
+  this->currentKeyFrame->lastPosition = v;
+}
+
+/**
+ *  a Sinusodial Interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+
+   @todo implement
+*/
+void Animation3D::mSine(float timePassed) const
+{
+  Vector v;
+  if( timePassed  < this->currentKeyFrame->duration/2.0)
+    v = (this->nextKeyFrame->position - this->currentKeyFrame->position) * sin( M_PI * timePassed /this->currentKeyFrame->duration) / 2.0;
+  else
+    v = (this->nextKeyFrame->position - this->currentKeyFrame->position) * (2.0 + sin( M_PI * (- timePassed /this->currentKeyFrame->duration)) )/ 2.0;
+
+  this->object->shiftCoor(v - this->currentKeyFrame->lastPosition);
+  this->currentKeyFrame->lastPosition = v;
+}
+
+
+/**
+ *  a cosine interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+
+   @todo implement
+*/
+void Animation3D::mCosine(float timePassed) const
+{
+  Vector v;
+  v = (this->nextKeyFrame->position - this->currentKeyFrame->position) * (1.0 + cos( M_PI * timePassed / this->currentKeyFrame->duration))/2.0;
+  this->object->shiftCoor(v - this->currentKeyFrame->lastPosition);
+  this->currentKeyFrame->lastPosition = v;
+
+
+  /*
+  this->object->setRelCoor( this->nextKeyFrame->position -
+                            (this->nextKeyFrame->position - this->currentKeyFrame->position) *
+                            (1.0 + cos( M_PI * timePassed / this->currentKeyFrame->duration))/2.0);
+  */
+}
+
+
+
+/**
+ *  an exponential interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+*/
+void Animation3D::mExp(float timePassed) const
+{
+  PRINTF(0)("no exp animation3d defined\n");
+  this->mLinear(timePassed);
+}
+
+/**
+ *  a negative exponential interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+*/
+void Animation3D::mNegExp(float timePassed) const
+{
+  Vector v;
+  v = (this->nextKeyFrame->position - this->currentKeyFrame->position) * (1.0 - expf(- timePassed * expFactorMov));
+  this->object->shiftCoor(v - this->currentKeyFrame->lastPosition);
+  this->currentKeyFrame->lastPosition = v;
+
+  /*
+  this->object->setRelCoor( this->currentKeyFrame->position +
+                            (this->nextKeyFrame->position - this->currentKeyFrame->position) *
+                            (1.0 - expf(- timePassed * expFactorMov)) );
+  */
+}
+
+
+/**
+ *  a quadratic interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+
+   @todo implement
+*/
+void Animation3D::mQuadratic(float timePassed) const
+{
+  PRINTF(0)("no quadratic animation3d defined\n");
+  this->mLinear(timePassed);
+}
+
+/**
+ *  some random animation (fluctuating)
+ * @param timePassed The time passed since this Keyframe began
+*/
+void Animation3D::mRandom(float timePassed) const
+{
+  /*
+  this->object->setRelCoor(this->currentKeyFrame->position +
+                           (this->nextKeyFrame->position - this->currentKeyFrame->position) * (float)rand()/(float)RAND_MAX);
+  this->object->setRelDir(this->currentKeyFrame->direction +
+                          (this->nextKeyFrame->direction - this->currentKeyFrame->direction)* (float)rand()/(float)RAND_MAX);
+  */
+}
+
+
+/*==Rotation Section==========================================================*/
+
+
+/**
+ *  Sets The kind of rotation Animation between this keyframe and the next one
+ * @param animFuncRot: The Type of Animation to set
+*/
+void Animation3D::setAnimFuncRot(ANIM_FUNCTION animFuncRot)
+{
+  switch (animFuncRot)
+    {
+    case ANIM_CONSTANT:
+      this->animFuncRot = &Animation3D::rConstant;
+      break;
+    case ANIM_LINEAR:
+      this->animFuncRot = &Animation3D::rLinear;
+      break;
+    case ANIM_SINE:
+      this->animFuncRot = &Animation3D::rSine;
+      break;
+    case ANIM_COSINE:
+      this->animFuncRot = &Animation3D::rCosine;
+      break;
+    case ANIM_EXP:
+      this->animFuncRot = &Animation3D::rExp;
+      break;
+    case ANIM_NEG_EXP:
+      this->animFuncRot = &Animation3D::rNegExp;
+      this->expFactorRot = -1.0 / this->currentKeyFrame->duration * logf(DELTA_X_3D);
+      break;
+    case ANIM_QUADRATIC:
+      this->animFuncRot = &Animation3D::rQuadratic;
+      break;
+    case ANIM_RANDOM:
+      this->animFuncRot = &Animation3D::rRandom;
+      break;
+
+    default:
+      this->animFuncRot = NULL;
+    }
+}
+
+
+/**
+ *  stays at the value of the currentKeyFrame
+ * @param timePassed The time passed since this Keyframe began
+*/
+void Animation3D::rConstant(float timePassed) const
+{
+  this->object->setRelDir(this->currentKeyFrame->direction);
+}
+
+/**
+ *  linear interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+
+   @todo implement also do this for direction
+*/
+void Animation3D::rLinear(float timePassed) const
+{
+  this->object->setRelDir(Quaternion::quatSlerp( this->nextKeyFrame->direction,
+                          this->currentKeyFrame->direction,
+                          timePassed/this->currentKeyFrame->duration) );
+}
+
+/**
+ *  a Sinusodial Interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+
+   @todo implement
+*/
+void Animation3D::rSine(float timePassed) const
+{
+  float scale;
+  if( timePassed < this->currentKeyFrame->duration / 2.0)
+    scale = sin( M_PI * timePassed / this->currentKeyFrame->duration);
+  else
+    scale = 1.0 - sin( M_PI * timePassed / this->currentKeyFrame->duration);
+
+  this->object->setRelDir(Quaternion::quatSlerp( this->nextKeyFrame->direction,
+                          this->currentKeyFrame->direction,
+                          scale) );
+}
+
+
+/**
+ *  a cosine interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+
+   @todo implement
+*/
+void Animation3D::rCosine(float timePassed) const
+{
+  float scale = cos(M_PI * timePassed / this->currentKeyFrame->duration);
+  this->object->setRelDir(Quaternion::quatSlerp( this->nextKeyFrame->direction,
+                          this->currentKeyFrame->direction,
+                          scale) );
+}
+
+
+
+/**
+ *  an exponential interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+*/
+void Animation3D::rExp(float timePassed) const
+{
+  PRINTF(2)("exp rotation function not implemented\n");
+}
+
+/**
+ *  a negative exponential interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+*/
+void Animation3D::rNegExp(float timePassed) const
+{
+  float scale = (1.0 - expf(- timePassed * expFactorRot));
+  this->object->setRelDir(Quaternion::quatSlerp( this->nextKeyFrame->direction,
+                          this->currentKeyFrame->direction,
+                          scale) );
+}
+
+
+/**
+ *  a quadratic interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+
+   @todo implement
+*/
+void Animation3D::rQuadratic(float timePassed) const
+{
+  PRINTF(0)("quadratic rotation alg not implemented\n");
+}
+
+/**
+ *  some random animation (fluctuating)
+ * @param timePassed The time passed since this Keyframe began
+*/
+void Animation3D::rRandom(float timePassed) const
+{
+  PRINTF(0)("random rotation alg not implemented\n");
+}
Index: branches/network/src/util/animation/animation3d.h
===================================================================
--- branches/network/src/util/animation/animation3d.h	(revision 6636)
+++ branches/network/src/util/animation/animation3d.h	(revision 6636)
@@ -0,0 +1,84 @@
+/*!
+ * @file animation3d.h
+*/
+
+
+#include "animation.h"
+
+#include "vector.h"
+#include "quaternion.h"
+class PNode;
+
+#define DELTA_X_3D 0.05  //!< the percentag of the distance that doesn't have to be done by neg_exp (asymptotical) ~ maschinendelta
+
+//! KeyFrame3D Struct
+/**
+   This represents one point with direction of the animation
+*/
+typedef struct KeyFrame3D {
+  float             duration;              //!< The duration of this KeyFrame
+  Vector            position;              //!< The position of this KeyFrame
+  Vector            lastPosition;          //!< The last known position
+  Quaternion        direction;             //!< The direction of this KeyFrame
+  ANIM_FUNCTION     animFuncMov;           //!< with whitch function to iterate movement to the next KeyFrame3D
+  ANIM_FUNCTION     animFuncRot;           //!< with whitch function to iterate rotation to the next KeyFrame3D
+};
+
+//! Animation Class for 3D-transformations (movement and rotation)
+/**
+   This represents an animation for a object
+*/
+class Animation3D : public Animation
+{
+ public:
+  Animation3D(PNode* object);
+  virtual ~Animation3D();
+
+  virtual void rewind();
+
+  void addKeyFrame(Vector position, Quaternion direction,
+                   float time, ANIM_FUNCTION animFuncMov = ANIM_DEFAULT_FUNCTION,
+                   ANIM_FUNCTION animFuncRot = ANIM_NULL);
+  //  void addKeyFrame(KeyFrame3D* frame);
+
+  virtual void tick(float dt);
+
+ private:
+  // animation functions
+  void setAnimFuncMov(ANIM_FUNCTION animFunc);
+  void setAnimFuncRot(ANIM_FUNCTION animFunc);
+  void mConstant(float timePassed) const;
+  void mLinear(float timePassed) const;
+  void mSine(float timePassed) const;
+  void mCosine(float timePassed) const;
+  void mExp(float timePassed) const;
+  void mNegExp(float timePassed) const;
+  void mQuadratic(float timePassed) const;
+  void mRandom(float timePassed) const;
+  void rConstant(float timePassed) const;
+  void rLinear(float timePassed) const;
+  void rSine(float timePassed) const;
+  void rCosine(float timePassed) const;
+  void rExp(float timePassed) const;
+  void rNegExp(float timePassed) const;
+  void rQuadratic(float timePassed) const;
+  void rRandom(float timePassed) const;
+  //  ANIM_FUNCTION animFunc;
+  void (Animation3D::*animFuncMov)(float) const;      //!< A Function for the AnimationType
+  void (Animation3D::*animFuncRot)(float) const;      //!< A Function for the AnimationType
+
+
+ private:
+  KeyFrame3D*          currentKeyFrame;               //!< The current KeyFrame
+  KeyFrame3D*          nextKeyFrame;                  //!< The KeyFrame we iterate to
+  tList<KeyFrame3D>*   keyFrameList;                  //!< The KeyFrameList
+
+
+  // more class-local description
+  PNode*               object;                        //!< The Object from which to Animate something
+  Vector               lastPosition;                  //!< last Object
+  Vector               tmpVect;                       //!< temporary vector
+  float                deltaT;                        //!< time passed since last
+  float                expFactorMov;                  //!< exponential Factor for movement
+  float                expFactorRot;                  //!< exponential Factor for rotation
+};
Index: branches/network/src/util/animation/animation_player.cc
===================================================================
--- branches/network/src/util/animation/animation_player.cc	(revision 6636)
+++ branches/network/src/util/animation/animation_player.cc	(revision 6636)
@@ -0,0 +1,164 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_ANIM
+
+#include "animation_player.h"
+
+#include "compiler.h"
+
+using namespace std;
+
+
+/**
+ *  standard constructor
+*/
+AnimationPlayer::AnimationPlayer ()
+{
+  this->setClassID(CL_ANIMATION_PLAYER, "AnimationPlayer");
+  this->setName("AnimationPlayer");
+
+  this->play();
+}
+
+/**
+ *  the singleton reference to this class
+*/
+AnimationPlayer* AnimationPlayer::singletonRef = NULL;
+
+/**
+ *  standard deconstructor
+
+   !! DANGER !! when unloading the AnimationPlayer no other Function
+   should reference any Animations, from the animationList because it
+   automatically deletes them.
+   This usually happens when unloading a World.
+*/
+AnimationPlayer::~AnimationPlayer ()
+{
+  // deleting the Animation List AND all the elements of the List
+  this->flush();
+
+  AnimationPlayer::singletonRef = NULL;
+}
+
+/**
+ *  adds an Animation to the AnimationList.
+ * @param animation the Animation to handle
+
+   when adding a Animation the Animation will too be deleted when
+   the AnimationPlayer gets deleted. Consider not adding it, or
+   unadding it with animation->notHandled();
+*/
+void AnimationPlayer::addAnimation(Animation* animation)
+{
+  this->animationList.push_back(animation);
+}
+
+/**
+ *  removes an Animation from the Animation List, WITHOUT deleting it.
+ * @param animation the Anmination to remove from the List
+*/
+void AnimationPlayer::removeAnimation(Animation* animation)
+{
+  this->animationList.remove(animation);
+}
+
+/**
+ *  empties the list AND deletes all the Animations
+*/
+void AnimationPlayer::flush()
+{
+  // deleting the Animation List AND all the elements of the List
+  while(this->animationList.size() > 0)
+  {
+    Animation* anim = this->animationList.front();
+    this->animationList.pop_front();
+    delete anim;
+  }
+}
+
+/**
+ *  Ticks all the animations in animationList
+ * @param timePassed the time passed since the last tick.
+ */
+void AnimationPlayer::tick(float timePassed)
+{
+  if (this->bRunning)
+  {
+      // iterate through all the animations and tick them.
+    list<Animation*>::iterator anim;
+    for (anim = this->animationList.begin(); anim != this->animationList.end(); anim++)
+    {
+      (*anim)->tick(timePassed);
+      if(unlikely((*anim)->ifDelete()))
+      {
+        this->animationList.remove(*anim);
+        delete *anim;
+      }
+    }
+  }
+}
+/**
+ *  starts playing the AnimationPlayer
+ */
+void AnimationPlayer::play()
+{
+  this->bRunning = true;
+}
+
+/**
+ *  pauses playing of the AnimationPlayer
+ */
+void AnimationPlayer::pause()
+{
+  this->bRunning = false;
+}
+
+/**
+ * @returns the animation from a certain baseobject
+   if multiple are found, it just retruns the first one
+   if none is found it returns NULL
+*/
+Animation* AnimationPlayer::getAnimationFromBaseObject(const BaseObject* baseObject) const
+{
+  list<Animation*>::const_iterator anim;
+  for (anim = this->animationList.begin(); anim != this->animationList.end(); anim++)
+    if((*anim)->getBaseObject() == baseObject)
+      return *anim;
+  return NULL;
+}
+
+
+
+/**
+ *  Outputs some nice debug-information
+*/
+void AnimationPlayer::debug()
+{
+  PRINT(0)("+------------------------------------+\n");
+  PRINT(0)("+ ANIMATION PLAYER DEBUG INFORMATION +\n");
+  PRINT(0)("+------------------------------------+\n");
+  PRINT(0)("| Reference: %p\n", this);
+  PRINT(0)("| CountOfAnims %d\n", this->animationList.size());
+  PRINT(0)("-Animation Information---------------+\n");
+  // Per ANIMATION DEBUG
+  list<Animation*>::iterator anim;
+  for (anim = this->animationList.begin(); anim != this->animationList.end(); anim++)
+    {
+      //      anim->debug();
+    }
+  PRINT(0)("+--------------------------------AP--+\n");
+}
Index: branches/network/src/util/animation/animation_player.h
===================================================================
--- branches/network/src/util/animation/animation_player.h	(revision 6636)
+++ branches/network/src/util/animation/animation_player.h	(revision 6636)
@@ -0,0 +1,63 @@
+/*!
+ * @file animation_player.h
+*/
+
+#ifndef _ANIMATION_PLAYER_H
+#define _ANIMATION_PLAYER_H
+
+#include "base_object.h"
+#include "animation.h"
+
+#include <list>
+
+/* FORWARD DECLARATION */
+
+//! A AnimationPlayer, that handles the animation of all the Animations in the scene.
+/**
+   <b>AnimationPlayer usage:</b> \n
+
+   <b>Initialisation</b>: AnimationPlayer::getInstance() does the trick this is
+   usually done when initializing a world \n
+   <b>Adding Animations</b>: create an Animation the following Way:
+   \li Anim* animation = new Anim(); // also use any other Subclass of Animation to initialize this
+   \li set some parameters: also see the specific classes for more info
+   \n
+   if you do not want a specific Animation to be handled by the AnimationPlayer, you have to
+   unload it explicitely with animation->doNotHandle();
+   \n
+   eveything else will be done by the AnimationPlayer itself.\n
+*/
+class AnimationPlayer : public BaseObject {
+
+ public:
+  /** @returns a Pointer to the only object of this Class */
+  inline static AnimationPlayer* getInstance() { if (!singletonRef) singletonRef = new AnimationPlayer();  return singletonRef; };
+
+  virtual ~AnimationPlayer();
+
+  // animation handling
+  void addAnimation(Animation* animation);
+  void removeAnimation(Animation* animation);
+  void flush();
+
+  // time functions
+  void tick(float timePassed);
+  void play();
+  void pause();
+
+  Animation* getAnimationFromBaseObject(const BaseObject* baseObject) const;
+
+  void debug();
+
+ private:
+  /* singleton */
+  AnimationPlayer();
+  static AnimationPlayer*      singletonRef;          //!< SingletonReference to this class.
+
+  /* class specific */
+  std::list<Animation*>        animationList;         //!< A List of Animations to be handled.
+  bool                         bRunning;              //!< If the AnimationPlayer is running.
+};
+
+
+#endif /* _ANIMATION_PLAYER_H */
Index: branches/network/src/util/animation/t_animation.h
===================================================================
--- branches/network/src/util/animation/t_animation.h	(revision 6636)
+++ branches/network/src/util/animation/t_animation.h	(revision 6636)
@@ -0,0 +1,357 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+/*!
+ * @file t_animation.h
+*/
+
+#ifndef _T_ANIMATION_H
+#define _T_ANIMATION_H
+
+#include "animation.h"
+
+#define DELTA_X 0.05  //!< the percentag of the distance that doesnt have to be done by neg_exp (asymptotical) ~ maschinendelta
+
+//! A Struct for Keyframes that simply hold a float
+typedef struct KeyFrameF
+{
+  float duration;             //!< duration of this keyframe
+  float value;                //!< value of this keyframe
+  ANIM_FUNCTION animFunc;     //!< with whitch function to iterate to the next KeyFrameF
+};
+
+
+//! A Class to handle some animation for single floated values.
+template<class T> class tAnimation : public Animation
+{
+ public:
+  tAnimation(T* object = NULL, void (T::*funcToAnim)(float) = NULL);
+  virtual ~tAnimation();
+
+  void setFuncToAnim(T* object, void (T::*funcToAnim)(float));
+
+  void addKeyFrame(float value, float duration, ANIM_FUNCTION animFunc = ANIM_DEFAULT_FUNCTION);
+
+  virtual void rewind();
+  virtual void tick(float dt);
+
+ private:
+  // animation functions
+  void setAnimFunc(ANIM_FUNCTION animFunc);
+  float constant(float timePassed) const;
+  float linear(float timePassed) const;
+  float sine(float timePassed) const;
+  float cosine(float timePassed) const;
+  float exp(float timePassed) const;
+  float negExp(float timePassed) const;
+  float quadratic(float timePassed) const;
+  float random(float timePassed) const;
+
+
+  //  ANIM_FUNCTION animFunc
+  float (tAnimation<T>::*animFunc)(float) const;  //!< A Function for the AnimationType
+
+  KeyFrameF* currentKeyFrame;                     //!< The current KeyFrame
+  KeyFrameF* nextKeyFrame;                        //!< The KeyFrame we iterate to
+  tList<KeyFrameF>* keyFrameList;                 //!< The KeyFrameList
+
+  T* object;                                      //!< The Object from which to Animate something
+  void (T::*funcToAnim)(float);                   //!< The function to Animate
+
+  float expFactor;                                //!< some factors
+};
+
+
+
+/**
+ *  standard constructor
+*/
+template<class T>
+tAnimation<T>::tAnimation (T* object, void (T::*funcToAnim)(float))
+{
+  // create a new List
+  this->keyFrameList = new tList<KeyFrameF>();
+  KeyFrameF* tmpKeyFrame = new KeyFrameF;
+  tmpKeyFrame->value = 0.0;
+  tmpKeyFrame->duration = 1.0;
+  keyFrameList->add(tmpKeyFrame);
+
+  this->currentKeyFrame = tmpKeyFrame;
+  this->nextKeyFrame = tmpKeyFrame;
+
+  this->animFunc = &tAnimation<T>::linear;
+
+  this->setFuncToAnim(object, funcToAnim);
+}
+
+
+/**
+ *  standard deconstructor
+
+   deletes all the Keyframes
+*/
+template<class T>
+tAnimation<T>::~tAnimation ()
+{
+  // delete all the KeyFrames
+  tIterator<KeyFrameF>* itKF = keyFrameList->getIterator();
+  KeyFrameF*  enumKF = itKF->firstElement();
+  while (enumKF)
+    {
+      delete enumKF;
+      enumKF = itKF->nextElement();
+    }
+  delete itKF;
+  delete this->keyFrameList;
+}
+
+/**
+ *  rewinds the Animation to the beginning (first KeyFrame and time == 0)
+*/
+template<class T>
+void tAnimation<T>::rewind()
+{
+  this->currentKeyFrame = keyFrameList->firstElement();
+  this->nextKeyFrame = keyFrameList->nextElement(keyFrameList->firstElement());
+  this->localTime = 0.0;
+  this->setAnimFunc(this->currentKeyFrame->animFunc);
+}
+
+/**
+ *  sets the Function we want to animate
+ * @param object from what object do we want to animate
+ * @param funcToAnim which function
+*/
+template<class T>
+void tAnimation<T>::setFuncToAnim(T* object, void (T::*funcToAnim)(float))
+{
+  this->baseObject = this->object = object;
+  this->funcToAnim = funcToAnim;
+}
+
+/**
+ *  Appends a new Keyframe
+ * @param value the value of the new KeyFrame
+ * @param duration The duration from the new KeyFrame to the next one
+ * @param animFunc The function to animate between this keyFrame and the next one
+*/
+template<class T>
+void tAnimation<T>::addKeyFrame(float value, float duration, ANIM_FUNCTION animFunc)
+{
+  // some small check
+  if (duration <= 0.0)
+    duration = 1.0;
+  if (animFunc == ANIM_NULL)
+    animFunc = ANIM_DEFAULT_FUNCTION;
+
+  KeyFrameF* tmpKeyFrame;
+
+  // when adding the first frame
+  if (this->keyFrameCount == 0)
+    {
+      tmpKeyFrame = this->keyFrameList->firstElement();
+      this->setAnimFunc(animFunc);
+    }
+  else
+    {
+      tmpKeyFrame = new KeyFrameF;
+      // when adding the second frame
+      if (this->currentKeyFrame == this->nextKeyFrame)
+        this->nextKeyFrame = tmpKeyFrame;
+      this->keyFrameList->add(tmpKeyFrame);
+    }
+
+  tmpKeyFrame->value = value;
+  tmpKeyFrame->duration = duration;
+  tmpKeyFrame->animFunc = animFunc;
+  this->keyFrameCount++;
+}
+
+/**
+ *  ticks the Animation
+ * @param dt how much time to tick
+*/
+template<class T>
+void tAnimation<T>::tick(float dt)
+{
+  if (this->bRunning)
+    {
+      this->localTime += dt;
+      if (localTime >= this->currentKeyFrame->duration)
+        {
+          if (likely(this->keyFramesToPlay != 0))
+            {
+              if (unlikely(this->keyFramesToPlay > 0))
+                --this->keyFramesToPlay;
+              // switching to the next Key-Frame
+              this->localTime -= this->currentKeyFrame->duration;
+
+              this->currentKeyFrame = this->nextKeyFrame;
+              // checking, if we should still Play the animation
+              if (this->currentKeyFrame == this->keyFrameList->lastElement())
+                this->handleInfinity();
+              this->nextKeyFrame = this->keyFrameList->nextElement(this->currentKeyFrame);
+
+              //printf("%p from:%f to:%f\n", this->currentKeyFrame,this->currentKeyFrame->value, this->nextKeyFrame->value);
+              this->setAnimFunc(this->currentKeyFrame->animFunc);
+            }
+          else
+            this->pause();
+        }
+
+      (this->object->*(funcToAnim))((this->*animFunc)(this->localTime));
+    }
+}
+
+/**
+ *  Sets The kind of Animation between this keyframe and the next one
+ * @param animFunc The Type of Animation to set
+*/
+template<class T>
+void tAnimation<T>::setAnimFunc(ANIM_FUNCTION animFunc)
+{
+  switch (animFunc)
+    {
+    default:
+    case ANIM_CONSTANT:
+      this->animFunc = &tAnimation<T>::constant;
+      break;
+    case ANIM_LINEAR:
+      this->animFunc = &tAnimation<T>::linear;
+      break;
+    case ANIM_SINE:
+      this->animFunc = &tAnimation<T>::sine;
+      break;
+    case ANIM_COSINE:
+      this->animFunc = &tAnimation<T>::cosine;
+      break;
+    case ANIM_EXP:
+      this->animFunc = &tAnimation<T>::exp;
+      break;
+    case ANIM_NEG_EXP:
+      {
+        this->animFunc = &tAnimation<T>::negExp;
+        expFactor =  - 1.0 / this->currentKeyFrame->duration * logf(DELTA_X);
+        break;
+      }
+    case ANIM_QUADRATIC:
+      this->animFunc = &tAnimation<T>::quadratic;
+      break;
+    case ANIM_RANDOM:
+      this->animFunc = &tAnimation<T>::random;
+      break;
+    }
+}
+
+
+// animation functions
+/**
+ *  stays at the value of the currentKeyFrame
+ * @param timePassed The time passed since this Keyframe began
+*/
+template<class T>
+float tAnimation<T>::constant(float timePassed) const
+{
+  return this->currentKeyFrame->value;
+}
+
+/**
+ *  linear interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+*/
+template<class T>
+float tAnimation<T>::linear(float timePassed) const
+{
+  return this->currentKeyFrame->value + (this->nextKeyFrame->value - this->currentKeyFrame->value)
+    * (timePassed / this->currentKeyFrame->duration);
+}
+
+/**
+ *  a Sinusodial Interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+*/
+template<class T>
+float tAnimation<T>::sine(float timePassed) const
+{
+  if (timePassed * 2.0 < this->currentKeyFrame->duration)
+    return this->currentKeyFrame->value + (this->nextKeyFrame->value - this->currentKeyFrame->value)
+      * sin( M_PI * timePassed / this->currentKeyFrame->duration)/2;
+  else
+    return this->nextKeyFrame->value - (this->nextKeyFrame->value - this->currentKeyFrame->value)
+      * sin( M_PI * (1.0 - timePassed / this->currentKeyFrame->duration))/2;
+  /*
+  printf("::%f::::%f::\n",timePassed/this->currentKeyFrame->duration,retVal);
+  return retVal;
+  */
+}
+
+/**
+ *  a cosine interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+*/
+template<class T>
+float tAnimation<T>::cosine(float timePassed) const
+{
+  return ((this->nextKeyFrame->value + this->currentKeyFrame->value) +
+    (this->currentKeyFrame->value - this->nextKeyFrame->value) *
+    cos( M_PI * timePassed / this->currentKeyFrame->duration))/2;
+}
+
+/**
+ *  an exponential interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+*/
+template<class T>
+float tAnimation<T>::exp(float timePassed) const
+{
+  return this->linear(timePassed);
+
+}
+
+/**
+ *  a negative exponential interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+*/
+template<class T>
+float tAnimation<T>::negExp(float timePassed) const
+{
+  float d = this->currentKeyFrame->value - this->nextKeyFrame->value;
+  float e = d * (1.0 - expf(- timePassed * expFactor));
+  return  this->currentKeyFrame->value - e;
+}
+
+/**
+ *  a quadratic interpolation between this keyframe and the next one
+ * @param timePassed The time passed since this Keyframe began
+*/
+template<class T>
+float tAnimation<T>::quadratic(float timePassed) const
+{
+  this->linear(timePassed);
+}
+
+/**
+ *  some random animation (fluctuating)
+ * @param timePassed The time passed since this Keyframe began
+*/
+template<class T>
+float tAnimation<T>::random(float timePassed) const
+{
+  return this->currentKeyFrame->value +
+    (this->nextKeyFrame->value - this->currentKeyFrame->value) *
+    (float)rand()/(float)RAND_MAX;
+}
+
+#endif /* _T_ANIMATION_H */
Index: branches/network/src/util/fast_factory.cc
===================================================================
--- branches/network/src/util/fast_factory.cc	(revision 6636)
+++ branches/network/src/util/fast_factory.cc	(revision 6636)
@@ -0,0 +1,283 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_LOAD
+
+#include "fast_factory.h"
+
+#include "compiler.h"
+#include "debug.h"
+#include <string.h>
+
+using namespace std;
+
+/**
+ * Initializes a FastFactory
+ * @param classID the ClassID this Class belongs to (the top-most)
+ * @param fastFactoryName the Name of the ObjectClass-handled here
+ * @return a new FastFactory
+ */
+FastFactory::FastFactory (ClassID classID, const char* fastFactoryName)
+{
+  this->setClassID(CL_FAST_FACTORY, "FastFactory");
+  this->setName(fastFactoryName);
+
+  this->storedClassID = classID;
+  this->next = NULL;
+
+  this->deadList = NULL;
+  this->unusedContainers = NULL;
+
+  this->storedDeadObjects = 0;
+
+  FastFactory::registerFastFactory(this);
+}
+
+/** a reference to the First FastFactory */
+FastFactory* FastFactory::first = NULL;
+
+/**
+ *  destructor
+ * deletes all the Instances of the FastFactory.
+ */
+FastFactory::~FastFactory ()
+{
+  if (this == first)
+    this->first = NULL;
+  this->flush();
+
+  if (this->next)
+    delete this->next;
+}
+
+/**
+ * deletes all FastFactories
+ */
+void FastFactory::deleteAll()
+{
+  if (FastFactory::first)
+    delete FastFactory::first;
+}
+
+/**
+ * registers a Factory to the List of known factories.
+ * @param fastFactory The factory to add
+ *
+ * needed, to step through all the FastFactories.
+ */
+void FastFactory::registerFastFactory(FastFactory* fastFactory)
+{
+  PRINTF(4)("Registered FastFactory for '%s'\n", fastFactory->getName());
+
+  if( FastFactory::first == NULL)
+    FastFactory::first = fastFactory;
+  else
+  {
+    FastFactory* tmpFac = FastFactory::first;
+    while( tmpFac->next != NULL)
+      tmpFac = tmpFac->next;
+    tmpFac->setNext(fastFactory);
+  }
+}
+
+/**
+ * searches for a FastFactory
+ * @param classID the ClassID of the FastFactory to search for
+ * @returns true if found, false otherwise.
+ */
+FastFactory* FastFactory::searchFastFactory(ClassID classID)
+{
+  if (FastFactory::first == NULL)
+    return NULL;
+  else
+  {
+    FastFactory* tmpFac = FastFactory::first;
+    while (tmpFac != NULL)
+    {
+      if (tmpFac->storedClassID == classID)
+        return tmpFac;
+      tmpFac = tmpFac->next;
+    }
+  }
+  return NULL;
+}
+
+/**
+ * searches for a FastFactory
+ * @param classID the ClassID of the FastFactory to search for
+ * @returns true if found, false otherwise.
+ */
+FastFactory* FastFactory::searchFastFactory(const char* fastFactoryName)
+{
+  if (FastFactory::first == NULL)
+    return NULL;
+  else
+  {
+    FastFactory* tmpFac = FastFactory::first;
+    while (tmpFac != NULL)
+    {
+      if (strcmp(tmpFac->getName(), fastFactoryName))
+        return tmpFac;
+      tmpFac = tmpFac->next;
+    }
+  }
+  return NULL;
+}
+
+/**
+ * Removes all the stored Containers, and sets the Lists back to emptienes.
+ * @param hardFLUSH if true the containing Objects will also be deleted !! THIS IS DANGEROUS !!
+ */
+void FastFactory::flushAll(bool hardFLUSH)
+{
+  FastFactory* tmpFac = FastFactory::first;
+  while (tmpFac != NULL)
+  {
+    PRINTF(4)("DELETEING ALL OF %s\n",tmpFac->getName());
+    tmpFac->flush(hardFLUSH);
+    tmpFac = tmpFac->next;
+  }
+}
+
+/**
+ * ereases all the remaining containers, without deleting the stored Objects inside of them.
+ * @param hardFLUSH if the the containing Objects will also be deleted !! THIS IS DANGEROUS !!
+ */
+void FastFactory::flush(bool hardFLUSH)
+{
+  FastObjectMember* tmpMember = this->deadList, *delMember = NULL;
+  while (tmpMember != NULL)
+  {
+    delMember = tmpMember;
+    tmpMember = tmpMember->next;
+    if (hardFLUSH)
+    {
+      delete delMember->objectPointer;
+    }
+    delete delMember;
+  }
+  this->deadList = NULL;
+
+  tmpMember = this->unusedContainers;
+  while (tmpMember != NULL)
+  {
+    delMember = tmpMember;
+    tmpMember = tmpMember->next;
+    delete delMember;
+  }
+  this->unusedContainers = NULL;
+}
+
+/**
+ * generates count new Object of the Corresponding class. (precaching)
+ * @param count How many instances of the class should be generated.
+ */
+void FastFactory::prepare(unsigned int count)
+{
+/*  if (this->storedDeadObjects + this->storedLivingObjects >= count)
+  {
+  PRINTF(3)("not creating new Objects for class %s, because the requested count already exists\n", this->getClassName());
+}*/
+  for (int i = this->storedDeadObjects; i < count; i++)
+  {
+    this->fabricate();
+  }
+}
+
+/**
+ * gives back live to one Object.
+ * @return the Object to resurrect.
+ */
+BaseObject* FastFactory::resurrect()
+{
+  PRINTF(4)("Resurecting Object of type %s\n", this->getName());
+  if (unlikely(this->deadList == NULL))
+  {
+    PRINTF(3)("The deadList of Class %s is empty, this may be either because it has not been filled yet, or the cache is to small.\n" \
+        "  Developer: try increasing the count with FastFactory::prepare(contHigher than actual)\n" \
+        "    Fabricating a new %s\n", this->getName(), this->getName());
+    this->fabricate();
+    return this->resurrect();
+  }
+  else
+  {
+    FastObjectMember* tmpC = this->deadList;
+    this->deadList = this->deadList->next;
+
+    tmpC->next = this->unusedContainers;
+    this->unusedContainers = tmpC;
+
+    return tmpC->objectPointer;
+  }
+}
+
+/**
+ * gives back live to one Object.
+ * @param classID the class From which to resurrect an Object.
+ * @return the Object to resurrect, NULL if classID is not found.
+ */
+BaseObject* FastFactory::resurrect(ClassID classID)
+{
+  FastFactory* tmpFac = FastFactory::getFirst();
+
+  while (tmpFac != NULL)
+  {
+    if (classID == tmpFac->storedClassID)
+      return tmpFac->resurrect();
+    tmpFac = tmpFac->next;
+  }
+  return NULL;
+}
+
+/**
+ * kills Object object, meaning, that it will be stored in the deadList of the FastFactory, and waiting for resurrection
+ * @param object the Object to kill.
+ *
+ * synony that would be really grate would be abolish, but this is more like exterminate than pause-mode.
+ */
+void FastFactory::kill(BaseObject* object)
+{
+  FastObjectMember* tmpC;
+  if (unlikely(this->unusedContainers == NULL))
+  {
+    tmpC = new FastObjectMember;
+  }
+  else
+  {
+    tmpC = this->unusedContainers;
+    this->unusedContainers = this->unusedContainers->next;
+  }
+
+  tmpC->next = this->deadList;
+  tmpC->objectPointer = object;
+  this->deadList = tmpC;
+}
+
+
+void FastFactory::kill(BaseObject* object, bool searchForFastFactory)
+{
+  if (likely(searchForFastFactory == true))
+  {
+    FastFactory* tmpFac = FastFactory::first;
+    while (tmpFac != NULL)
+    {
+      if (object->isA(tmpFac->storedClassID))
+      {
+        tmpFac->kill(object);
+        return;
+      }
+      tmpFac = tmpFac->next;
+    }
+  }
+}
Index: branches/network/src/util/fast_factory.h
===================================================================
--- branches/network/src/util/fast_factory.h	(revision 6636)
+++ branches/network/src/util/fast_factory.h	(revision 6636)
@@ -0,0 +1,175 @@
+/*!
+ * @file fast_factory.h
+ * The ObjectManager (FastFactory) is designed, to automatically generate and remove
+ * (without to much overhead) many instances of different classes.
+ *
+ * It is especially usefull for objects, that come only for a short time into existence,
+ * and get killed after a small amount of time (like shots).
+ *
+ * The Creation of an Object is usually done in the Weapon Class, where one subscribes
+ * a Projectile with:
+ * this->bulletFactory = tFastFactory<TestBullet>::getFastFactory(CL_TEST_BULLET, "TestBullet");
+ * (this might change over time).
+ * Then you can at loading time initialize an amount of the class with something like:
+ * this->bulletFactory->prepare(100); // creates 100 entities of TestBullet (dead ones)
+ * afterwards one can just retrieve an Object form the Class with
+ * this->bulletFactory->resurrect();  // this returns a BaseObject an Object of the class.
+ *
+ * The big difference to the FastFactory-class is, that this one is used more for the purpose
+ * of fast game-interaction than for loading. althought one can also load FastFactorized classes
+ * it is not the main topic.
+ */
+
+#ifndef _FAST_FACTORY_H
+#define _FAST_FACTORY_H
+
+#include "base_object.h"
+/**
+ * Creates a FastFactory to a Createable FastFactory.
+ */
+#define CREATE_FAST_FACTORY(CLASS_NAME, CLASS_ID) \
+  FastFactory* global_##CLASS_NAME##_FastFactory = tFastFactory<CLASS_NAME>::getFastFactory(CLASS_ID, #CLASS_NAME)
+/**
+ * Creates a FastFactory for a Class' static function named ClassName::fastFactory.
+ * @param CLASS_NAME the name of the Class to create the fast-factory for.
+ * @param CLASS_ID the ID of the class to create the fast-factory for @see "class_id.h"
+ *
+ * notice, that the Class to be called, must implement:
+ * static FastFactory*         fastFactory;
+ */
+#define CREATE_FAST_FACTORY_STATIC(CLASS_NAME, CLASS_ID) \
+  FastFactory* CLASS_NAME::fastFactory = tFastFactory<CLASS_NAME>::getFastFactory(CLASS_ID, #CLASS_NAME)
+
+//! A struct, that holds Lists of Objects of a certain type.
+typedef struct FastObjectMember
+  {
+    BaseObject*          objectPointer;      //!< Pointer to the Object Stored in this Class (if it is the DeadList, else it is bork)
+
+    FastObjectMember*    next;               //!< the next stored FastObjectMember. (or NULL if this is the last one stored in either the deadList or the unusedContainers)
+  };
+
+//! The FastFactory is a fast loadable object creator, and Dynamic List of dead object handler.
+/**
+ * The ObjectManager (FastFactory) is designed, to automatically generate and remove
+ * (without to much overhead) many instances of different classes.
+ *
+ * FastFactory is needed to glue all the tFastFactories together.
+ * It is also the general class that implements the necessary functions
+ * to generate, resurrect kill and stuff...
+ */
+class FastFactory : public BaseObject
+  {
+
+  public:
+    virtual ~FastFactory ();
+    static void deleteAll();
+
+    // functions to push and pop elements of this class
+    BaseObject* resurrect();
+    static BaseObject* resurrect(ClassID classID);
+    void kill(BaseObject* object);
+    static void kill(BaseObject* object, bool searchForFastFactory);
+
+    void prepare(unsigned int count);
+
+    static void flushAll(bool hardFLUSH = false);
+    void flush(bool hardFLUSH = false);
+
+    /** @returns the first FastFactory */
+    inline static FastFactory* getFirst() { return FastFactory::first; };
+
+    static FastFactory* searchFastFactory(ClassID classID);
+    static FastFactory* searchFastFactory(const char* fastFactoryName);
+
+    ClassID getStoredID() const { return this->storedClassID; };
+
+  protected:
+    FastFactory (ClassID classID, const char* fastFactoryName = NULL);
+
+    /** sets the Next factory in the list @param nextFactory the next factory */
+    inline void setNext( FastFactory* nextFastFactory) { this->next = nextFastFactory; };
+    /** @returns the next FastFactory */
+    FastFactory* getNext() const { return this->next; };
+
+    /** generates a new Object of the Class T */
+    virtual void fabricate() = 0;
+
+  private:
+    static void registerFastFactory(FastFactory* fastFactory);
+
+  protected:
+    ClassID               storedClassID;        //!< The classID of the specified class.
+    unsigned int          storedDeadObjects;    //!< How many dead objects are stored in this class
+
+    FastObjectMember*     deadList;             //!< A List of all stored dead Objects of this class.
+    FastObjectMember*     unusedContainers;     //!< This is a List of unused containers, that will be reused by kill.
+
+  private:
+    static FastFactory*   first;                //!< A pointer to the first FastFactory.
+
+    FastFactory*          next;                 //!< pointer to the next FastFactory.
+  };
+
+
+
+/**
+ *  a FastFactory that is able to load any kind of Object from a ClassID
+ * (this is a Functor)
+ */
+template<class T>
+class tFastFactory : public FastFactory
+  {
+  public:
+    static tFastFactory<T>* getFastFactory(ClassID classID, const char* fastFactoryName = NULL);
+
+  private:
+    tFastFactory(ClassID classID, const char* fastFactoryName);
+
+    virtual void fabricate();
+  };
+
+/**
+ * construnts a FastFactory with
+ * @param fastFactoryName the name of the FastFactory
+ * @param fastFactory the ID of the class
+ * @todo (can this be written in another form??)
+ */
+template<class T>
+tFastFactory<T>::tFastFactory(ClassID classID, const char* fastFactoryName)
+    : FastFactory(classID, fastFactoryName)
+{}
+
+/**
+ * creates (if not existent) a Factory of Class T, and assigns some values to it
+ * @param classID the ClassID to assign to this class
+ * @param fastFactoryName the name to assign
+ * @returns The FastFactory if existent a new Factory if not.
+ */
+template<class T>
+tFastFactory<T>* tFastFactory<T>::getFastFactory(ClassID classID, const char* fastFactoryName)
+{
+  tFastFactory<T>* tmpFac = NULL;
+  if (FastFactory::getFirst() != NULL)
+    tmpFac = static_cast<tFastFactory<T>*>(FastFactory::getFirst()->searchFastFactory(classID));
+
+  if (tmpFac != NULL)
+    return tmpFac;
+  else
+    return new tFastFactory<T>(classID, fastFactoryName);
+}
+
+/**
+ * fabricates an Object of Class T, that corresponds to classID.
+ */
+template<class T>
+void tFastFactory<T>::fabricate()
+{
+  FastObjectMember* tmpFirstDead = new FastObjectMember;
+  tmpFirstDead->objectPointer = new T();
+  tmpFirstDead->next = this->deadList;
+  ++this->storedDeadObjects;
+
+  this->deadList = tmpFirstDead;
+}
+
+#endif /* _FAST_FACTORY_H */
Index: branches/network/src/util/hud.cc
===================================================================
--- branches/network/src/util/hud.cc	(revision 6636)
+++ branches/network/src/util/hud.cc	(revision 6636)
@@ -0,0 +1,186 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
+
+#include "hud.h"
+
+#include "state.h"
+
+#include "world_entities/weapons/weapon_manager.h"
+
+using namespace std;
+
+
+/**
+ * standard constructor
+ * @todo this constructor is not jet implemented - do it
+*/
+Hud::Hud ()
+{
+  this->setClassID(CL_HUD, "Hud");
+
+  //this->setSize2D(
+  this->weaponManager = NULL;
+  this->energyWidget = NULL;
+  this->shieldWidget = NULL;
+  this->armorWidget = NULL;
+  this->resX = 1;
+  this->resY = 1;
+
+}
+
+
+/**
+ * standard deconstructor
+*/
+Hud::~Hud ()
+{
+  // delete what has to be deleted here
+}
+
+
+void Hud::loadParams(const TiXmlElement* root)
+{
+  Element2D::loadParams(root);
+}
+
+void Hud::setBackGround()
+{
+}
+
+void Hud::setEnergyWidget(GLGuiWidget* widget)
+{
+  // decopple old widget
+  if (this->energyWidget != NULL)
+  {
+    this->energyWidget->hide();
+  }
+
+  this->energyWidget = widget;
+  if (this->energyWidget != NULL)
+  {
+    this->energyWidget->show();
+  }
+
+  this->updateResolution();
+}
+
+void Hud::setShiledWidget(GLGuiWidget* widget)
+{
+}
+
+void Hud::setArmorWidget(GLGuiWidget* widget)
+{
+}
+
+void Hud::setWeaponManager(WeaponManager* weaponMan)
+{
+  if (this->weaponManager != NULL)
+  {
+    for (unsigned int i = 0; i < this->weaponManager->getSlotCount(); i++)
+    {
+      Weapon* weapon = this->weaponManager->getWeapon(i);
+      if (weapon != NULL)
+      {
+        weapon->getEnergyWidget()->hide();
+        this->weaponsWidgets.remove(weapon->getEnergyWidget());
+      }
+    }
+  }
+
+  this->weaponManager = weaponMan;
+
+  this->updateWeaponManager();
+  this->updateResolution();
+}
+
+void Hud::updateWeaponManager()
+{
+  // hide all the Widgets
+  std::list<GLGuiWidget*>::iterator weaponWidget;
+  for (weaponWidget = this->weaponsWidgets.begin(); weaponWidget != this->weaponsWidgets.end(); weaponWidget++)
+  {
+    (*weaponWidget)->hide();
+  }
+  this->weaponsWidgets.clear();
+
+  // add all that we need again.
+  if (this->weaponManager != NULL)
+    for (unsigned int i = 0; i < this->weaponManager->getSlotCount(); i++)
+  {
+    Weapon* weapon = this->weaponManager->getWeapon(i);
+    if (weapon != NULL)
+    {
+      weapon->getEnergyWidget()->show();
+      weapon->getLoadedEnergyWidget()->show();
+      this->weaponsWidgets.push_back(weapon->getEnergyWidget());
+      this->weaponsWidgets.push_back(weapon->getLoadedEnergyWidget());
+    }
+  }
+  this->updateResolution();
+}
+
+void Hud::addWeaponWidget(GLGuiWidget* widget)
+{
+}
+
+void Hud::removeWeaponWidget(GLGuiWidget* widget)
+{
+}
+
+void Hud::updateResolution()
+{
+  this->resX = State::getResX();
+  this->resY = State::getResY();
+  if (this->energyWidget != NULL)
+  {
+    this->energyWidget->setAbsCoor2D(.02 * this->resX, .4 * this->resY);
+    this->energyWidget->setSize2D(.05 * this->resX, .55 * this->resY);
+  }
+
+  this->setSize2D(.2 * this->resX, this->resY);
+
+  std::list<GLGuiWidget*>::iterator weaponWidget;
+  float pos = .2;
+  bool test = true;
+  for (weaponWidget = this->weaponsWidgets.begin(); weaponWidget != this->weaponsWidgets.end(); weaponWidget++, pos+=.03, test = !test)
+  {
+    if (test)
+    {
+      (*weaponWidget)->setSize2D(.02*this->resX, .2 *this->resY);
+      (*weaponWidget)->setAbsCoor2D(pos*this->resX, .75*this->resY);
+    }
+    else
+    {
+      (*weaponWidget)->setSize2D(.02*this->resX, .17*this->resY);
+      (*weaponWidget)->setAbsCoor2D((pos-.008)*this->resX, .75*this->resY);
+    }
+  }
+}
+
+
+void Hud::tick(float dt)
+{
+  if (this->resY != State::getResY() || this->resX != State::getResY())
+    this->updateResolution();
+}
+
+void Hud::draw() const
+{
+  GLGuiWidget::draw();
+}
+
+
Index: branches/network/src/util/hud.h
===================================================================
--- branches/network/src/util/hud.h	(revision 6636)
+++ branches/network/src/util/hud.h	(revision 6636)
@@ -0,0 +1,56 @@
+/*!
+ * @file hud.h
+ * @brief Definition of the ingame HUD.
+*/
+
+#ifndef _HUD_H
+#define _HUD_H
+
+#include "glgui_widget.h"
+#include <list>
+
+// FORWARD DECLARATION
+class TiXmlElement;
+class WeaponManager;
+
+//! A class that renders a HUD.
+class Hud : public GLGuiWidget
+{
+
+public:
+  Hud();
+  virtual ~Hud();
+
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void setBackGround();
+  void setEnergyWidget(GLGuiWidget* widget);
+  void setShiledWidget(GLGuiWidget* widget);
+  void setArmorWidget(GLGuiWidget* widget);
+  void setWeaponManager(WeaponManager* weaponMan);
+
+  void addWeaponWidget(GLGuiWidget* widget);
+  void removeWeaponWidget(GLGuiWidget* widget);
+
+  void updateWeaponManager();
+
+  void tick(float dt);
+  void draw() const;
+
+  private:
+    void updateResolution();
+private:
+  unsigned int             resX;
+  unsigned int             resY;
+
+  GLGuiWidget*             energyWidget;
+  GLGuiWidget*             shieldWidget;
+  GLGuiWidget*             armorWidget;
+
+  WeaponManager*           weaponManager;
+
+  std::list<GLGuiWidget*>  weaponsWidgets; //!< WeaponWidgets will be displayed one after another
+};
+
+#endif /* _HUD_H */
Index: branches/network/src/util/loading/factory.cc
===================================================================
--- branches/network/src/util/loading/factory.cc	(revision 6636)
+++ branches/network/src/util/loading/factory.cc	(revision 6636)
@@ -0,0 +1,183 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: Benjamin Grauer
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_LOADING
+
+#include "factory.h"
+
+//#include "shell_command.h"
+
+using namespace std;
+
+//SHELL_COMMAND(create, Factory, fabricate);
+
+
+/*  --------------------------------------------------
+ *               Factory
+ *   --------------------------------------------------
+ */
+
+/**
+ *  constructor
+
+   set everything to zero and define factoryName
+*/
+Factory::Factory (const char* factoryName, ClassID classID)
+{
+  this->setClassID(CL_FACTORY, "Factory");
+  this->setName(factoryName);
+
+  this->classID = classID;
+  this->className = factoryName;
+
+  if( Factory::factoryList == NULL)
+    Factory::factoryList = new std::list<Factory*>;
+
+  Factory::factoryList->push_back(this);
+}
+
+/** a reference to the First Factory */
+std::list<Factory*>* Factory::factoryList = NULL;
+
+/**
+ *  destructor
+ *
+ * clear the Q
+ */
+Factory::~Factory ()
+{
+  //  printf("%s\n", this->factoryName);
+  //  Factory* tmpDel = this->next;
+  //  this->next = NULL;
+}
+
+/**
+ * deletes all the Factories. (cleanup)
+ */
+void Factory::deleteFactories()
+{
+  if (Factory::factoryList != NULL)
+  {
+    while(!Factory::factoryList->empty())
+    {
+      delete Factory::factoryList->front();
+      Factory::factoryList->pop_front();
+    }
+    delete Factory::factoryList;
+    Factory::factoryList = NULL;
+  }
+}
+
+/**
+ * @param classID match a classID with this classID
+ * @returns true on match, false otherwise
+ */
+bool Factory::operator==(ClassID classID) const
+{
+  return (this->classID == classID);
+}
+
+/**
+ * Compares the Factories Name against a given ClassName
+ * @param className the Name of the Class to Query
+ * @returns true on match, false otherwise.
+ */
+bool Factory::operator==(const char* className) const
+{
+  return(className != NULL && !strcmp(className, this->className));
+}
+
+
+/**
+ * Creates a new Object of type root->Value() (name)
+ * @param root the XML-Root to match for the newly created Object
+ * @returns a new Object of Type root->Value() on match, NULL otherwise
+ */
+ BaseObject* Factory::fabricate(const TiXmlElement* root)
+{
+  if (root == NULL || Factory::factoryList == NULL)
+    return NULL;
+
+  std::list<Factory*>::const_iterator factory;
+  for (factory = Factory::factoryList->begin(); factory != Factory::factoryList->end(); factory++)
+    if (*(*factory) == root->Value())
+      break;
+
+  if (factory != Factory::factoryList->end())
+  {
+    PRINTF(4)("Create a new Object of type %s\n", (*factory)->getName());
+    return (*factory)->fabricateObject(root);
+  }
+  else
+  {
+    PRINTF(2)("Could not Fabricate an Object of Class '%s'\n", root->Value());
+    return NULL;
+  }
+}
+
+
+/**
+ * Creates a new Object of type className
+ * @param className the ClassName to match for the newly created Object
+ * @returns a new Object of Type className on match, NULL otherwise
+ */
+ BaseObject* Factory::fabricate(const char* className)
+{
+  if (className == NULL || Factory::factoryList == NULL)
+    return NULL;
+
+  std::list<Factory*>::const_iterator factory;
+  for (factory = Factory::factoryList->begin(); factory != Factory::factoryList->end(); factory++)
+    if (*(*factory) == className)
+      break;
+
+  if (factory != Factory::factoryList->end())
+  {
+    PRINTF(4)("Create a new Object of type %s\n", (*factory)->getName());
+    return (*factory)->fabricateObject(NULL);
+  }
+  else
+  {
+    PRINTF(2)("Could not Fabricate an Object of Class '%s'\n", className);
+    return NULL;
+  }
+}
+
+
+/**
+ * Creates a new Object of type classID
+ * @param classID the ClassID to match for the newly created Object
+ * @returns a new Object of Type classID on match, NULL otherwise
+ */
+BaseObject* Factory::fabricate(ClassID classID)
+{
+  if (Factory::factoryList == NULL)
+    return NULL;
+
+  std::list<Factory*>::const_iterator factory;
+  for (factory = Factory::factoryList->begin(); factory != Factory::factoryList->end(); factory++)
+    if (*(*factory) == classID)
+      break;
+
+  if (factory != Factory::factoryList->end())
+  {
+    PRINTF(4)("Create a new Object of type %s\n", (*factory)->getName());
+    return (*factory)->fabricateObject(NULL);
+  }
+  else
+  {
+    PRINTF(2)("Could not Fabricate an Object of ClassID '%h'\n", classID);
+    return NULL;
+  }
+}
Index: branches/network/src/util/loading/factory.h
===================================================================
--- branches/network/src/util/loading/factory.h	(revision 6636)
+++ branches/network/src/util/loading/factory.h	(revision 6636)
@@ -0,0 +1,95 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: Benjamin Grauer
+*/
+
+/*!
+ * @file factory.h
+ * @brief A loadable object handler
+*/
+
+
+#ifndef _FACTORY_H
+#define _FACTORY_H
+
+class BaseObject;
+
+#include "parser/tinyxml/tinyxml.h"
+#include "base_object.h"
+#include "debug.h"
+#include <vector>
+#include <list>
+
+/**
+ * Creates a factory to a Loadable Class.
+ * this should be used at the beginning of all the Classes that should be loadable (in the cc-file)
+*/
+#define CREATE_FACTORY(CLASS_NAME, CLASS_ID) \
+    tFactory<CLASS_NAME>* global_##CLASS_NAME##_Factory = new tFactory<CLASS_NAME>(#CLASS_NAME, CLASS_ID)
+
+//! The Factory is a loadable object handler
+class Factory : public BaseObject {
+
+ public:
+  Factory (const char* factoryName, ClassID classID);
+  virtual ~Factory ();
+
+  static void deleteFactories();
+
+  static  BaseObject* fabricate(const char* className);
+  static  BaseObject* fabricate(ClassID classID);
+  static  BaseObject* fabricate(const TiXmlElement* root = NULL);
+
+
+  bool operator==(ClassID classID) const;
+  bool operator==(const char* className) const;
+
+  protected:
+    virtual BaseObject* fabricateObject(const TiXmlElement* root = NULL) const = 0;
+
+  protected:
+    ClassID                       classID;              //!< The Class-Identifyer of the Factory.
+    const char*                   className;            //!< The name of the Class.
+    static std::list<Factory*>*   factoryList;          //!< List of Registered Factories
+};
+
+/**
+ *  a factory that is able to load any kind of Object
+ * (this is a Functor)
+ */
+template<class T> class tFactory : public Factory
+{
+ public:
+ /**
+  * creates a new type Factory to enable the loading of T
+  * @param factoryName the Name of the Factory to load.
+  * @param classID the ID of the Class to be created.
+  */
+  tFactory (const char* factoryName, ClassID classID)
+   : Factory(factoryName, classID)
+  {  }
+
+  private:
+   /**
+    * fabricates an Object of type T, with the constructor T::T(const TiXmlElemnt*)
+    * @param root the TiXmlElement T should load parameters from.
+    * @return the newly fabricated T.
+    */
+    virtual BaseObject* fabricateObject(const TiXmlElement* root = NULL) const
+    {
+      return new T(root);
+    }
+};
+
+#endif /* _FACTORY_H */
+
Index: branches/network/src/util/loading/game_loader.cc
===================================================================
--- branches/network/src/util/loading/game_loader.cc	(revision 6636)
+++ branches/network/src/util/loading/game_loader.cc	(revision 6636)
@@ -0,0 +1,307 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_LOAD
+
+#include "game_loader.h"
+#include "load_param.h"
+
+#include "shell_command.h"
+#include "campaign.h"
+
+#include "resource_manager.h"
+
+#include "event_handler.h"
+
+
+using namespace std;
+
+
+SHELL_COMMAND(quit, GameLoader, stop)
+    ->describe("quits the game")
+    ->setAlias("orxoquit");
+
+
+GameLoader* GameLoader::singletonRef = NULL;
+
+
+/**
+ *  simple constructor
+ */
+GameLoader::GameLoader ()
+{
+  this->setClassID(CL_GAME_LOADER, "GameLoader");
+  this->setName("GameLoader");
+
+}
+
+
+/**
+ *  simple deconstructor
+ */
+GameLoader::~GameLoader ()
+{
+  if( this->currentCampaign)
+    delete this->currentCampaign;
+  this->currentCampaign = NULL;
+}
+
+
+/**
+ *  initializes the GameLoader
+ */
+ErrorMessage GameLoader::init()
+{
+  if(this->currentCampaign != NULL)
+    this->currentCampaign->init();
+
+  this->eventHandler = EventHandler::getInstance();
+  this->eventHandler->subscribe(this, ES_GAME, KeyMapper::PEV_PAUSE);
+  this->eventHandler->subscribe(this, ES_ALL, EV_MAIN_QUIT);          //< External Quit Event
+  this->eventHandler->subscribe(this, ES_ALL, KeyMapper::PEV_QUIT);
+  this->eventHandler->subscribe(this, ES_GAME, KeyMapper::PEV_NEXT_WORLD);
+  this->eventHandler->subscribe(this, ES_GAME, KeyMapper::PEV_PREVIOUS_WORLD);
+}
+
+
+/**
+ *  reads a campaign definition file into a campaign class
+ * @param fileName to be loaded
+ * @returns the loaded campaign
+ *
+ * this will interprete the map/campaign files and recursivly load a tree of worlds/campaigns
+ */
+ErrorMessage GameLoader::loadCampaign(const char* fileName)
+{
+  ErrorMessage errorCode;
+  char* campaignName = ResourceManager::getFullName(fileName);
+  if (campaignName)
+    {
+      this->currentCampaign = this->fileToCampaign(campaignName);
+      delete[] campaignName;
+    }
+}
+
+
+/**
+ *  reads a campaign definition file into a campaign class
+ * @param fileName to be loaded
+ * @returns the loaded campaign
+ *
+ * this will interprete the map/campaign files and recursivly load a tree of worlds/campaigns
+ */
+ErrorMessage GameLoader::loadNetworkCampaign(const char* fileName)
+{
+  ErrorMessage errorCode;
+  char* campaignName = ResourceManager::getFullName(fileName);
+  if (campaignName)
+  {
+    this->currentCampaign = this->fileToCampaign(campaignName);
+    delete[] campaignName;
+  }
+}
+
+
+/**
+ *  loads a debug campaign for test purposes only.
+ * @param campaignID the identifier of the campaign.
+ * @returns error message if not able to do so.
+ */
+ErrorMessage GameLoader::loadDebugCampaign(Uint32 campaignID)
+{
+  switch(campaignID)
+    {
+      /*
+         Debug Level 0: Debug level used to test the base frame work.
+         As you can see, all storyentity data is allocated before game
+         start. the storyentity will load themselfs shortly before start
+         through the StoryEntity::init() funtion.
+      */
+    case DEBUG_CAMPAIGN_0:
+      {
+/*        Campaign* debugCampaign = new Campaign();
+
+        World* world0 = new World(DEBUG_WORLD_0);
+        world0->setNextStoryID(WORLD_ID_1);
+        debugCampaign->addEntity(world0, WORLD_ID_0);
+
+        World* world1 = new World(DEBUG_WORLD_1);
+        world1->setNextStoryID(WORLD_ID_2);
+        debugCampaign->addEntity(world1, WORLD_ID_1);
+
+        World* world2 = new World(DEBUG_WORLD_2);
+        world2->setNextStoryID(WORLD_ID_GAMEEND);
+        debugCampaign->addEntity(world2, WORLD_ID_2);
+
+        this->currentCampaign = debugCampaign;
+        break;*/
+      }
+    }
+}
+
+
+/**
+ *  starts the current entity
+ * @returns error code if this action has caused a error
+ */
+ErrorMessage GameLoader::start()
+{
+  if(this->currentCampaign != NULL)
+    this->currentCampaign->start();
+}
+
+
+/**
+ *  stops the current entity
+ * @returns error code if this action has caused a error
+ *
+ *  ATTENTION: this function shouldn't call other functions, or if so, they must return
+ *  after finishing. If you ignore or forget to do so, the current entity is not able to
+ *  terminate and it will run in the background or the ressources can't be freed or even
+ *  worse: are freed and the program will end in a segmentation fault!
+ *  hehehe, have ya seen it... :)
+ */
+void GameLoader::stop()
+{
+  if(this->currentCampaign != NULL)
+    this->currentCampaign->stop();
+}
+
+
+/**
+ *  pause the current entity
+ * @returns error code if this action has caused a error
+ *
+ * this pauses the current entity or passes this call forth to the running entity.
+ */
+ErrorMessage GameLoader::pause()
+{
+  this->isPaused = true;
+  if(this->currentCampaign != NULL)
+    this->currentCampaign->pause();
+}
+
+
+/**
+ *  resumes a pause
+ * @returns error code if this action has caused a error
+ *
+ *  this resumess the current entity or passes this call forth to the running entity.
+ */
+ErrorMessage GameLoader::resume()
+{
+  this->isPaused = false;
+  if(this->currentCampaign != NULL)
+    this->currentCampaign->resume();
+}
+
+
+/**
+ *  reads a campaign definition file into a campaign class
+ * @param fileName to be loaded
+ * @returns the loaded campaign
+ *
+ * this will interprete the map/campaign files and recursivly load a tree of worlds/campaigns
+ */
+Campaign* GameLoader::fileToCampaign(const char* fileName)
+{
+  /* do not entirely load the campaign. just the current world
+     before start of each world, it has to be initialized so it
+     can load everything it needs into memory then.
+  */
+
+  if( fileName == NULL)
+    {
+      PRINTF(2)("No filename specified for loading");
+      return NULL;
+    }
+
+  TiXmlDocument* XMLDoc = new TiXmlDocument( fileName);
+  // load the campaign document
+  if( !XMLDoc->LoadFile())
+    {
+      // report an error
+      PRINTF(1)("Could not load XML File %s: %s @ %d:%d\n", fileName, XMLDoc->ErrorDesc(), XMLDoc->ErrorRow(), XMLDoc->ErrorCol());
+      delete XMLDoc;
+      return NULL;
+    }
+
+  // check basic validity
+  TiXmlElement* root = XMLDoc->RootElement();
+  assert( root != NULL);
+
+  if( strcmp( root->Value(), "Campaign"))
+    {
+      // report an error
+      PRINTF(2)("Specified XML File is not an orxonox campaign file (Campaign element missing)\n");
+      delete XMLDoc;
+      return NULL;
+    }
+
+  // construct campaign
+  Campaign* c = new Campaign( root);
+
+  // free the XML data
+  delete XMLDoc;
+
+  return c;
+}
+
+
+
+/**
+ *  handle keyboard commands
+ * @param event the event to handle
+ */
+void GameLoader::process(const Event& event)
+{
+  if( event.type == KeyMapper::PEV_NEXT_WORLD)
+  {
+    if( likely(event.bPressed))
+    {
+      this->switchToNextLevel();
+    }
+  }
+  else if( event.type == KeyMapper::PEV_PAUSE)
+  {
+    if( likely(event.bPressed))
+    {
+      if(this->isPaused)
+        this->resume();
+      else
+        this->pause();
+    }
+  }
+  else if( event.type == KeyMapper::PEV_QUIT)
+  {
+    if( event.bPressed) this->stop();
+  }
+  else if (event.type == EV_MAIN_QUIT)
+    this->stop();
+}
+
+
+/**
+ *  this changes to the next level
+ */
+void GameLoader::switchToNextLevel()
+{
+  if(this->currentCampaign != NULL)
+    this->currentCampaign->switchToNextLevel();
+}
+
+
Index: branches/network/src/util/loading/game_loader.h
===================================================================
--- branches/network/src/util/loading/game_loader.h	(revision 6636)
+++ branches/network/src/util/loading/game_loader.h	(revision 6636)
@@ -0,0 +1,78 @@
+/*!
+ * @file game_loader.h
+ *  loads campaigns, worlds and all other story_entities
+*/
+
+#ifndef _GAME_LOADER_H
+#define _GAME_LOADER_H
+
+//#include "stdincl.h"
+#include "story_def.h"
+#include "comincl.h"
+#include "event_listener.h"
+
+#include "error.h"
+
+//-----------------------------------------------------------------------------
+// Forward declarations
+//-----------------------------------------------------------------------------
+class Campaign;
+class World;
+class Factory;
+class TiXmlElement;
+class BaseObject;
+class Event;
+class EventHandler;
+
+//! The GameLoader
+/**
+ *  The game loader loads all game date. this is performed in the following way:
+ * 1. Read the structure of campaings and worlds
+ * 2. Create the instances of the tree: here _ALL_ StoryEntities are created
+ *    also if they are not yet used. the worlds should load their data in
+ *    the StoryEntity::load() and StoryEntity::init() functions! NOWHERE ELSE!
+ *    Elsewhere, all the data will be allocated at the beginning... mess...
+ * 3. StoryEntities are load() and init() before they start
+ * 4. once the gamloader starts the game there will be a campaing starting a
+ *    world. this is done by callaing those StoryEntity::start()
+*/
+class GameLoader : public EventListener
+{
+ public:
+  ~GameLoader ();
+  /**  this class is a singleton class @returns an instance of itself  */
+  static GameLoader* getInstance() { if(singletonRef == NULL) singletonRef = new GameLoader(); return singletonRef; }
+
+  ErrorMessage loadCampaign(const char* name);
+  ErrorMessage loadDebugCampaign(Uint32 campaignID);
+  ErrorMessage loadNetworkCampaign(const char* fileName);
+
+  ErrorMessage init();
+  ErrorMessage start();
+  void stop();
+  ErrorMessage pause();
+  ErrorMessage resume();
+
+  void switchToNextLevel();
+
+  void process(const Event &event);
+
+
+ private:
+  GameLoader ();
+
+  Campaign* fileToCampaign(const char* name);
+
+
+ private:
+  static GameLoader*     singletonRef;         //!< The singleton-reference to this object
+
+  Uint32                 startTime;            //!< start time of the campaign
+  bool                   isPaused;             //!< if the game is paused
+
+  Campaign*              currentCampaign;      //!< reference to the current campaign playing
+
+  EventHandler*          eventHandler;         //!< reference to the eventHandler
+};
+
+#endif /* _GAME_LOADER_H */
Index: branches/network/src/util/loading/load_param.cc
===================================================================
--- branches/network/src/util/loading/load_param.cc	(revision 6636)
+++ branches/network/src/util/loading/load_param.cc	(revision 6636)
@@ -0,0 +1,277 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_LOADING
+
+#include "load_param.h"
+#include "load_param_description.h"
+
+#include "list.h"
+
+#include <stdarg.h>
+
+/**
+ * Constructs a new LoadParameter
+ * @param root the XML-element to load this Parameter from
+ * @param paramName the Parameter to load
+ * @param object the BaseObject, to load this parameter on to (will be cast to executor's Parameter)
+ * @param executor the Executor, that executes the loading procedure.
+ */
+CLoadParam::CLoadParam(const TiXmlElement* root, const char* paramName, BaseObject* object, const Executor& executor, bool inLoadCycle)
+{
+  this->paramName = paramName;
+  this->object = object;
+  this->inLoadCycle = inLoadCycle;
+
+  // determin the LoadString.
+  if (likely(!inLoadCycle))
+    this->loadElem = grabParameterElement(root, paramName);
+  //this->loadString = grabParameter(root, paramName);
+  else if (!strcmp(root->Value(), paramName))
+    this->loadElem = (TiXmlElement*)root->FirstChild();
+  else
+    this->loadElem = NULL;
+
+  // set the Executor.
+  this->executor = executor.clone();
+}
+
+/**
+ * This is a VERY SPECIAL deconsrtuctor.
+ * It is made, so that it loads the Parameters on destruction.
+ * meaning, if an Executor a valid Object exist, and all
+ * Execution-Conditions are met, they are executed here.
+ */
+CLoadParam::~CLoadParam()
+{
+  if (likely(this->executor != NULL))
+  {
+    if (this->loadElem != NULL &&  this->loadElem->ToText())
+      this->loadString = this->loadElem->Value();
+    else
+      this->loadString = NULL;
+    if (likely(this->object != NULL) &&
+        ( this->loadString != NULL ||
+         ((this->executor->getType() & Executor_NoLoadString) == Executor_NoLoadString)))
+    {
+      PRINTF(4)("Loading '%s' with Parameters '%s' onto: '%s'(%s)\n", this->paramName, this->loadString, this->object->getName(), this->object->getClassName());
+      this->executor->execute(this->object, this->loadString);
+    }
+    delete this->executor;
+  }
+}
+
+/**
+ * set the default values of the executor
+ * @param count how many default values to set.
+ * @param ... the default values !! must be at least count parameters!!
+ */
+CLoadParam& CLoadParam::defaultValues(unsigned int count, ...)
+{
+  va_list values;
+  va_start(values, count);
+
+  assert(executor != NULL);
+  this->executor->defaultValues(count, values);
+
+  return *this;
+}
+
+
+
+/**
+ * @param descriptionText The text to set as a description for this Parameter
+ * @returns a pointer to itself.
+*/
+CLoadParam& CLoadParam::describe(const char* descriptionText)
+{
+  if (LoadClassDescription::parametersDescription && this->paramDesc && !this->paramDesc->getDescription())
+    {
+      this->paramDesc->setDescription(descriptionText);
+    }
+  return *this;
+}
+
+// const LoadParamDescription* LoadParamDescription::getClass(const char* className)
+// {
+//   tIterator<LoadClassDescription>* iterator = LoadClassDescription::classList->getIterator();
+//   LoadClassDescription* enumClassDesc = iterator->firstElement();
+//   while (enumClassDesc)
+//   {
+//     if (!strcmp(enumClassDesc->className, classNameBegin, className))
+//     {
+//       delete iterator;
+//       return enumClassDesc;
+//     }
+//     enumClassDesc = iterator->nextElement();
+//   }
+//   delete iterator;
+//
+//   return NULL;
+// }
+
+
+
+
+/*
+ * @param object The object this Parameter is loaded too.
+ * @param root: the XML-element to load this option from.
+ * @param paramName: The name of the parameter loaded.
+ * @param paramCount: how many parameters this loading-function takes
+ * @param multi: if false LoadParam assumes only one occurence of this parameter in root, if true it assumes multiple occurences.
+ * @param ...: the parameter information (1. Parameter, 2. Default Value for the Parameter, ...)
+*/
+/*LoadParam::LoadParam(const TiXmlElement* root, BaseObject* object, const char* paramName,
+                             int paramCount, bool multi, const void* pointerToParam, ...)
+{
+  this->setClassID(CL_LOAD_PARAM, "LoadParam");
+  this->executor = NULL;
+
+  this->loadString = NULL;
+  this->pointerToParam = pointerToParam;
+
+  if (paramCount == 0 || this->pointerToParam != NULL)
+    this->loadString = "none";
+  else
+{
+      if (likely(!multi))
+        this->loadString = grabParameter(root, paramName);
+      else
+{
+          if (!strcmp(root->Value(), paramName))
+{
+              const TiXmlNode* val = root->FirstChild();
+              if( val->ToText())
+                this->loadString = val->Value();
+}
+}
+}
+
+  this->paramDesc = NULL;
+  if (LoadClassDescription::parametersDescription)
+{
+    // locating the class
+    this->classDesc = LoadClassDescription::addClass(object->getClassName());
+
+    if ((this->paramDesc = this->classDesc->addParam(paramName)) != NULL)
+{
+
+      this->paramDesc->paramCount = paramCount;
+      this->paramDesc->types = new int[paramCount];
+      this->paramDesc->defaultValues = new char*[paramCount];
+
+      va_list types;
+      va_start (types, pointerToParam);
+      char defaultVal[512];
+      for(int i = 0; i < paramCount; i++)
+{
+        defaultVal[0] = '\0';
+          // parameters parsed
+        int tmpType = va_arg (types, int);
+        this->paramDesc->types[i] = tmpType;
+        switch (tmpType)
+{
+  case MT_INT:
+            sprintf(defaultVal, "%d", va_arg(types, int));
+            break;
+//          case MT_LONG:
+//            sprintf(defaultVal, "%0.3f", va_arg(types, l_LONG_TYPE));
+//            break;
+  case MT_FLOAT:
+            sprintf(defaultVal, "%0.3f", va_arg(types, double));
+            break;
+  case MT_STRING:
+            sprintf(defaultVal, "%s", va_arg(types, l_STRING_TYPE));
+            break;
+  case MT_EXT1:
+            sprintf(defaultVal, "");
+            break;
+}
+        this->paramDesc->defaultValues[i] = new char[strlen(defaultVal)+1];
+        strcpy(this->paramDesc->defaultValues[i], defaultVal);
+}
+      va_end(types);
+
+      int argCount = 0;
+}
+}
+}*/
+
+
+
+
+
+
+
+
+
+
+//////////////////////
+// HELPER FUNCTIONS //
+//////////////////////
+/**
+ * @param root: The XML-element to grab a parameter from
+ * @param parameterName: the parameter to grab
+ * @returns the Value of the parameter if found, NULL otherwise
+*/
+const char* grabParameter(const TiXmlElement* root, const char* parameterName)
+{
+  const TiXmlElement* element;
+  const TiXmlNode* node;
+
+  if (root == NULL || parameterName == NULL)
+    return NULL;
+  assert( parameterName != NULL);
+
+  element = root->FirstChildElement( parameterName);
+  if( element == NULL) return NULL;
+
+  node = element->FirstChild();
+  while( node != NULL)
+    {
+      if( node->ToText()) return node->Value();
+      node = node->NextSibling();
+    }
+  return NULL;
+}
+
+/**
+ * @param root: The XML-element to grab a parameter from
+ * @param parameterName: the parameter to grab
+ * @returns the Element of the parameter if found, NULL otherwise
+ */
+const TiXmlElement* grabParameterElement(const TiXmlElement* root, const char* parameterName)
+{
+  const TiXmlElement* element;
+  const TiXmlNode* node;
+
+  if (root == NULL || parameterName == NULL)
+    return NULL;
+  assert( parameterName != NULL);
+
+  element = root->FirstChildElement( parameterName);
+  if( element == NULL) return NULL;
+
+  node = element->FirstChild();
+  while( node != NULL)
+  {
+    if( node->ToText()) return (TiXmlElement*)node;
+    node = node->NextSibling();
+  }
+  return NULL;
+}
+
+
+
Index: branches/network/src/util/loading/load_param.h
===================================================================
--- branches/network/src/util/loading/load_param.h	(revision 6636)
+++ branches/network/src/util/loading/load_param.h	(revision 6636)
@@ -0,0 +1,118 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+/*!
+ * @file load_param.h
+ * A Class and macro-functions, that makes our lives easy to load-in parameters
+ */
+
+#ifndef _LOAD_PARAM_H
+#define _LOAD_PARAM_H
+
+#include "base_object.h"
+
+#include "executor/executor.h"
+#include "executor/executor_specials.h"
+
+#include "helper_functions.h"
+
+// Forward Declaration //
+template<class T> class tList;
+class LoadClassDescription;
+class LoadParamDescription;
+class MultiType;
+
+
+/**
+ * Loads a Parameter from ROOT named PARAMETER_NAME
+ * onto OBJECT of CLASS, trough the FUNCTION
+ * @param ROOT the TiXmlElement to load the Parameter from
+ * @param PARAMETER_NAME the Name of the Parameter to load
+ * @param OBJECT The BaseObject to load the new setting to.
+ * @param CLASS What Class the BaseObejct is of (this is for identifying the Functuon)
+ * @param FUNCTION The function of Class to Load (if you want to call &CLASS::FUNCTION write FUNCTION here).
+ */
+#define LoadParam(ROOT, PARAMETER_NAME, OBJECT, CLASS, FUNCTION) \
+         CLoadParam(ROOT, PARAMETER_NAME, OBJECT, ExecutorObjective<CLASS>(&CLASS::FUNCTION), false)
+
+#define LoadParam_CYCLE(ROOT, PARAMETER_NAME, OBJECT, CLASS, FUNCTION) \
+         CLoadParam(ROOT, PARAMETER_NAME, OBJECT, ExecutorObjective<CLASS>(&CLASS::FUNCTION), true)
+
+#define LoadParamXML(ROOT, PARAMETER_NAME, OBJECT, CLASS, FUNCTION) \
+         CLoadParam(ROOT, PARAMETER_NAME, OBJECT, ExecutorXML<CLASS>(&CLASS::FUNCTION, ROOT, PARAMETER_NAME), false)
+
+#define LoadParamXML_CYCLE(ROOT, PARAMETER_NAME, OBJECT, CLASS, FUNCTION) \
+         CLoadParam(ROOT, PARAMETER_NAME, OBJECT, ExecutorXML<CLASS>(&CLASS::FUNCTION, ROOT, PARAMETER_NAME), true)
+
+
+/**
+ * this Starts a Cycle in the Loading Process
+ * be aware, that in the cycle the first parameter of load_param should because
+ * called element, and that you must say true at the Fith parameter, or it will fail
+ * also you will have to close the Cycle again with LOAD_PARAM_END_CYCLE
+ *
+ * @param ROOT The root XLM-element to search element under.
+ * @param ELEMENT the element to search
+ */
+#define LOAD_PARAM_START_CYCLE(ROOT, ELEMENT) \
+  const TiXmlElement* ELEMENT; \
+  ELEMENT= ROOT->FirstChildElement(); \
+  while( ELEMENT != NULL) \
+{
+/**
+   * closes a LoadParam Loop
+   * @see LOAD_PARAM_START_CYCLE
+   * @param ELEMENT the Element to step through.
+ */
+#define LOAD_PARAM_END_CYCLE(ELEMENT) \
+  ELEMENT = ELEMENT->NextSiblingElement(); \
+}
+
+/**************************
+**** REAL DECLARATIONS ****
+**************************/
+//! abstract Base class for a Loadable parameter
+class CLoadParam : public BaseObject
+{
+  public:
+    CLoadParam(const TiXmlElement* root, const char* paramName, BaseObject* object, const Executor& executor, bool inLoadCycle = false);
+    ~CLoadParam();
+
+    CLoadParam& describe(const char* descriptionText);
+    CLoadParam& defaultValues(unsigned int count, ...);
+    CLoadParam& attribute(const char* attributeName, const Executor& executor);
+
+
+  private:
+    bool                     inLoadCycle;
+    Executor*                executor;
+    BaseObject*              object;
+    const char*              paramName;
+
+    LoadClassDescription*    classDesc;            //!< The LoadClassDescription of this CLoadParameter
+    LoadParamDescription*    paramDesc;            //!< The LoadParameterDescription of this LoadParameter
+    const TiXmlElement*      loadElem;             //!< The Element to load.
+    const char*              loadString;           //!< The string loaded by this LoadParam
+    const void*              pointerToParam;       //!< A Pointer to a Parameter.
+
+    MultiType*               defaultValue;
+};
+
+// helper function
+
+const char* grabParameter(const TiXmlElement* root, const char* parameterName);
+const TiXmlElement* grabParameterElement(const TiXmlElement* root, const char* parameterName);
+
+#endif /* _LOAD_PARAM_H */
Index: branches/network/src/util/loading/load_param_description.cc
===================================================================
--- branches/network/src/util/loading/load_param_description.cc	(revision 6636)
+++ branches/network/src/util/loading/load_param_description.cc	(revision 6636)
@@ -0,0 +1,304 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#include "load_param_description.h"
+
+#include "multi_type.h"
+#include "list.h"
+#include <stdarg.h>
+#include "stdlibincl.h"
+/**
+ * @param paramName the name of the parameter to load
+ */
+LoadParamDescription::LoadParamDescription(const char* paramName)
+{
+  this->types = NULL;
+  this->description = NULL;
+  this->defaultValues = NULL;
+  this->paramName = new char[strlen(paramName)+1];
+  strcpy(this->paramName, paramName);
+}
+
+/**
+ *  removes all the alocated memory
+ */
+LoadParamDescription::~LoadParamDescription()
+{
+  if (this->defaultValues != NULL)
+  {
+    for(int i = 0; i < this->paramCount; i++)
+    {
+      delete[] this->defaultValues[i];
+    }
+  }
+
+  delete[] this->types;
+  delete[] this->defaultValues;
+  delete[] this->paramName;
+  delete[] this->description;
+}
+
+/**
+ * @param descriptionText The text to set as a description for this Parameter
+ */
+void LoadParamDescription::setDescription(const char* descriptionText)
+{
+  this->description = new char[strlen(descriptionText)+1];
+  strcpy(this->description, descriptionText);
+}
+
+/**
+ *  prints out this parameter, its input method and the description (if availiable)
+ */
+void LoadParamDescription::print() const
+{
+  PRINT(3)(" <%s>", this->paramName);
+  for (int i = 0; i < this->paramCount; i++)
+  {
+    if (i > 0)
+      PRINT(3)(",");
+    // FIXME
+    //     switch (this->types[i])
+//     {
+//       default:
+//         PRINTF(3)("none");
+//         break;
+//       case ParameterBool:
+//         PRINT(3)("bool");
+//         break;
+//       case ParameterChar:
+//         PRINT(3)("char");
+//         break;
+//       case ParameterString:
+//         PRINT(3)("string");
+//         break;
+//       case ParameterInt:
+//         PRINT(3)("int");
+//         break;
+//       case ParameterUInt:
+//         PRINT(3)("Uint");
+//         break;
+//       case ParameterFloat:
+//         PRINT(3)("float");
+//         break;
+//       case ParameterLong:
+//         PRINT(3)("long");
+//         break;
+//       case ParameterXML:
+//         PRINT(3)("XML");
+//         break;
+//     }
+  }
+  PRINT(3)("</%s>", this->paramName);
+  if (this->description)
+    PRINT(3)(" -- %s", this->description);
+  // default values
+  if (this->paramCount > 0)
+  {
+    PRINT(3)(" (Default: ");
+    for (int i = 0; i < this->paramCount; i++)
+    {
+      if (i > 0)
+        PRINT(3)(", ");
+      if (this->types[i] & MT_STRING)
+      { // leave brackets !!
+        PRINT(3)("\"%s\"", this->defaultValues[i]);
+      }
+      else
+      {
+        PRINT(3)("%s", this->defaultValues[i]);
+      }
+    }
+    PRINT(3)(")");
+  }
+  PRINT(3)("\n");
+}
+
+/**
+ *  A list, that holds all the classes that are loadable (classes not objects!!)
+ */
+tList<LoadClassDescription>* LoadClassDescription::classList = NULL;
+
+/**
+ *  if the description of Parameters should be executed
+ */
+bool LoadClassDescription::parametersDescription = false;
+
+/**
+ * @param className the name of the class to be loadable
+ */
+LoadClassDescription::LoadClassDescription(const char* className)
+{
+  this->className = new char[strlen(className)+1];
+  strcpy(this->className, className);
+
+  if (LoadClassDescription::classList == NULL)
+    LoadClassDescription::classList = new tList<LoadClassDescription>;
+
+  LoadClassDescription::classList->add(this);
+
+  this->paramList = new tList<LoadParamDescription>;
+}
+
+/**
+ *  deletes a classDescription (deletes all the parameterDescriptions as well
+ */
+LoadClassDescription::~LoadClassDescription()
+{
+  tIterator<LoadParamDescription>* iterator = this->paramList->getIterator();
+  LoadParamDescription* enumParamDesc = iterator->firstElement();
+  while (enumParamDesc)
+  {
+    delete enumParamDesc;
+    enumParamDesc = iterator->nextElement();
+  }
+  delete iterator;
+  delete this->paramList;
+
+  delete[] this->className;
+}
+
+void LoadClassDescription::deleteAllDescriptions()
+{
+  if (LoadClassDescription::classList != NULL)
+  {
+    tIterator<LoadClassDescription>* iterator = LoadClassDescription::classList->getIterator();
+    LoadClassDescription* delElem = iterator->firstElement();
+    while (delElem != NULL)
+    {
+      delete delElem;
+      delElem = iterator->nextElement();
+    }
+    delete iterator;
+    delete LoadClassDescription::classList;
+  }
+  LoadClassDescription::classList = NULL;
+}
+
+
+/**
+ *  adds a class to the list of loadable classes
+ * @param className The name of the class to add
+
+   this function searches for the className string, and if found just returns the appropriate Class.
+   Otherwise it returns a new classDescription
+ */
+LoadClassDescription* LoadClassDescription::addClass(const char* className)
+{
+  if (LoadClassDescription::classList != NULL)
+  {
+    tIterator<LoadClassDescription>* iterator = LoadClassDescription::classList->getIterator();
+    LoadClassDescription* enumClassDesc = iterator->firstElement();
+    while (enumClassDesc)
+    {
+      if (!strcmp(enumClassDesc->className, className))
+      {
+        delete iterator;
+        return enumClassDesc;
+      }
+      enumClassDesc = iterator->nextElement();
+    }
+    delete iterator;
+  }
+  return new LoadClassDescription(className);
+}
+
+/**
+ *  does the same as addClass(const char* className), but with params
+ * @param paramName the name of the parameter to add.
+ */
+LoadParamDescription* LoadClassDescription::addParam(const char* paramName)
+{
+  tIterator<LoadParamDescription>* iterator = this->paramList->getIterator();
+  LoadParamDescription* enumParamDesc = iterator->firstElement();
+  while (enumParamDesc)
+  {
+    if (!strcmp(enumParamDesc->paramName, paramName))
+    {
+      delete iterator;
+          //return enumParamDesc;
+      return NULL;
+    }
+    enumParamDesc = iterator->nextElement();
+  }
+  delete iterator;
+
+  LoadParamDescription* newParam = new LoadParamDescription(paramName);
+
+  this->paramList->add(newParam);
+  return newParam;
+}
+
+/**
+ *  prints out all loadable Classes, and their parameters
+ * @param fileName prints the output to a File
+ * @todo implement it
+ */
+void LoadClassDescription::printAll(const char* fileName)
+{
+  PRINT(3)("===============================================================\n");
+  PRINT(3)(" Listing all the Loadable Options (loaded since Game started).\n\n");
+  if (LoadClassDescription::classList != NULL)
+  {
+    tIterator<LoadClassDescription>* classIT = LoadClassDescription::classList->getIterator();
+    LoadClassDescription* enumClassDesc = classIT->firstElement();
+    while (enumClassDesc)
+    {
+      PRINT(3)("<%s>\n", enumClassDesc->className);
+      tIterator<LoadParamDescription>* paramIT = enumClassDesc->paramList->getIterator();
+      LoadParamDescription* enumParamDesc = paramIT->firstElement();
+      while (enumParamDesc)
+      {
+        enumParamDesc->print();
+        enumParamDesc = paramIT->nextElement();
+      }
+      delete paramIT;
+
+      PRINT(3)("</%s>\n\n", enumClassDesc->className);
+      enumClassDesc = classIT->nextElement();
+    }
+    delete classIT;
+  }
+  else
+    PRINT(3)("no Classes defined so far\n");
+  PRINT(3)("===============================================================\n");
+}
+
+/**
+ * searches for classes, which beginn with classNameBegin
+ * @param classNameBegin the beginning string of a Class
+ * @return a NEW char-array with ClassNames. The LIST should be deleted afterwards,
+ * !! The strings MUST NOT be deleted !!
+ */
+tList<const char>* LoadClassDescription::searchClassWithShort(const char* classNameBegin)
+{
+  unsigned int searchLength = strlen(classNameBegin);
+  tList<const char>* retVal = new tList<const char>;
+
+  tIterator<LoadClassDescription>* iterator = LoadClassDescription::classList->getIterator();
+  LoadClassDescription* enumClassDesc = iterator->firstElement();
+  while (enumClassDesc)
+  {
+    if (strlen(enumClassDesc->className)>searchLength+1 &&
+        !strncasecmp(enumClassDesc->className, classNameBegin, searchLength))
+    {
+      retVal->add(enumClassDesc->className);
+    }
+    enumClassDesc = iterator->nextElement();
+  }
+  delete iterator;
+
+  return retVal;
+}
Index: branches/network/src/util/loading/load_param_description.h
===================================================================
--- branches/network/src/util/loading/load_param_description.h	(revision 6636)
+++ branches/network/src/util/loading/load_param_description.h	(revision 6636)
@@ -0,0 +1,81 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+/*!
+ * @file load_param.h
+ * A Class and macro-functions, that makes our lives easy to load-in parameters
+ */
+
+#ifndef _LOAD_PARAM_DESCRIPTION_H
+#define _LOAD_PARAM_DESCRIPTION_H
+
+#include "base_object.h"
+
+// Forward Declaration //
+template<class T> class tList;
+class MultiType;
+
+/************************
+*** DESCRIPTION STUFF ***
+************************/
+//! A class that handles the description of loadable parameters
+class LoadParamDescription
+{
+  friend class LoadParam;
+  friend class LoadClassDescription;
+ public:
+  LoadParamDescription(const char* paramName);
+  ~LoadParamDescription();
+
+  void setDescription(const char* descriptionText);
+  /** @returns the descriptionString */
+  const char* getDescription() { return this->description; };
+
+  void print() const;
+
+ private:
+  char*         paramName;             //!< The name of the parameter.
+  int           paramCount;            //!< The count of parameters.
+  int*          types;                 //!< What kind of parameters does this function take ??
+  char*         description;           //!< A longer description about this function.
+  char**        defaultValues;         //!< The 'Default Values'. @TODO MAKE THIS A MULTITYPE
+};
+
+//! A class for descriptions of a loadable module
+class LoadClassDescription
+{
+  friend class CLoadParam;
+ public:
+  LoadClassDescription(const char* className);
+  ~LoadClassDescription();
+
+  static LoadClassDescription* addClass(const char* className);
+  LoadParamDescription* addParam(const char* paramName);
+
+  static void deleteAllDescriptions();
+
+  static void printAll(const char* fileName = NULL);
+  static tList<const char>* searchClassWithShort(const char* classNameBegin);
+//  static const LoadParamDescription* getClass(const char* className);
+
+ private:
+  static bool                          parametersDescription;  //!< if parameter-description should be enabled.
+  static tList<LoadClassDescription>*  classList;              //!< a list, that stores all the loadable classes. (after one instance has been loaded)
+  char*                                className;              //!< name of the class
+
+  tList<LoadParamDescription>*         paramList;              //!< List of parameters this class knows.
+};
+
+#endif /* _LOAD_PARAM_DESCRIPTION_H */
Index: branches/network/src/util/loading/resource_manager.cc
===================================================================
--- branches/network/src/util/loading/resource_manager.cc	(revision 6636)
+++ branches/network/src/util/loading/resource_manager.cc	(revision 6636)
@@ -0,0 +1,1004 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: Patrick Boenzli
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_LOAD
+
+#include "resource_manager.h"
+
+#include "debug.h"
+
+#include <algorithm>
+
+// different resource Types
+#ifndef NO_MODEL
+#include "objModel.h"
+#include "primitive_model.h"
+#include "md2Model.h"
+#endif /* NO_MODEL */
+#ifndef NO_TEXTURES
+#include "texture.h"
+#endif /* NO_TEXTURES */
+#ifndef NO_TEXT
+#include "font.h"
+#endif /* NO_TEXT */
+#ifndef NO_AUDIO
+#include "sound_buffer.h"
+#include "ogg_player.h"
+#endif /* NO_AUDIO */
+#ifndef NO_SHADERS
+#include "shader.h"
+#endif /* NO_SHADERS */
+
+// File Handling Includes
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+using namespace std;
+
+/**
+ *  standard constructor
+*/
+ResourceManager::ResourceManager ()
+{
+  this->setClassID(CL_RESOURCE_MANAGER, "ResourceManager");
+  this->setName("ResourceManager");
+
+  this->dataDir = new char[3];
+  strcpy(this->dataDir, "./");
+  this->tryDataDir("./data");
+}
+
+//! Singleton Reference to the ResourceManager
+ResourceManager* ResourceManager::singletonRef = NULL;
+
+/**
+ *  standard destructor
+*/
+ResourceManager::~ResourceManager ()
+{
+  // deleting the Resources-List
+  this->unloadAllByPriority(RP_GAME);
+
+  if (!this->resourceList.empty())
+    PRINTF(1)("Not removed all Resources, since there are still %d resources registered\n", this->resourceList.size());
+
+  // deleting the Directorie Lists
+  while (!this->imageDirs.empty())
+    {
+      delete[] this->imageDirs.front();
+      this->imageDirs.pop_front();
+    }
+
+  delete[] this->dataDir;
+
+  ResourceManager::singletonRef = NULL;
+}
+
+/**
+ *  sets the data main directory
+ * @param dataDir the DataDirectory.
+ */
+bool ResourceManager::setDataDir(const char* dataDir)
+{
+  char* realDir = ResourceManager::homeDirCheck(dataDir);
+  if (isDir(realDir))
+  {
+    delete[] this->dataDir;
+    if (dataDir[strlen(dataDir)-1] == '/' || dataDir[strlen(dataDir)-1] == '\\')
+    {
+      this->dataDir = new char[strlen(realDir)+1];
+      strcpy(this->dataDir, realDir);
+    }
+    else
+    {
+      this->dataDir = new char[strlen(realDir)+2];
+      strcpy(this->dataDir, realDir);
+      this->dataDir[strlen(realDir)] = '/';
+      this->dataDir[strlen(realDir)+1] = '\0';
+    }
+    delete[] realDir;
+    return true;
+  }
+  else
+  {
+    PRINTF(1)("%s is not a Directory, and can not be the Data Directory, leaving as %s \n", realDir, this->dataDir);
+    delete[] realDir;
+    return false;
+  }
+}
+
+/**
+ * sets the data main directory
+ * @param dataDir the DataDirectory.
+ *
+ * this is essentially the same as setDataDir, but it ommits the error-message
+ */
+bool ResourceManager::tryDataDir(const char* dataDir)
+{
+  char* realDir = ResourceManager::homeDirCheck(dataDir);
+  if (isDir(realDir))
+  {
+    delete[] this->dataDir;
+    if (dataDir[strlen(dataDir)-1] == '/' || dataDir[strlen(dataDir)-1] == '\\')
+    {
+      this->dataDir = new char[strlen(realDir)+1];
+      strcpy(this->dataDir, realDir);
+    }
+    else
+    {
+      this->dataDir = new char[strlen(realDir)+2];
+      strcpy(this->dataDir, realDir);
+      this->dataDir[strlen(realDir)] = '/';
+      this->dataDir[strlen(realDir)+1] = '\0';
+    }
+    delete[] realDir;
+    return true;
+  }
+  delete[] realDir;
+  return false;
+}
+
+
+
+/**
+ * checks for the DataDirectory, by looking if
+ * @param fileInside is iniside of the given directory.
+*/
+bool ResourceManager::verifyDataDir(const char* fileInside)
+{
+  bool retVal;
+  if (!isDir(this->dataDir))
+    {
+      PRINTF(1)("%s is not a directory\n", this->dataDir);
+      return false;
+    }
+
+  char* testFile = new char[strlen(this->dataDir)+strlen(fileInside)+1];
+  sprintf(testFile, "%s%s", this->dataDir, fileInside);
+  retVal = isFile(testFile);
+  delete[] testFile;
+  return retVal;
+}
+
+#ifndef NO_TEXTURES
+/**
+ *  adds a new Path for Images
+ * @param imageDir The path to insert
+ * @returns true, if the Path was well and injected (or already existent within the list)
+   false otherwise
+*/
+bool ResourceManager::addImageDir(const char* imageDir)
+{
+  if (imageDir == NULL)
+    return false;
+
+  char* newDir;
+  if (imageDir[strlen(imageDir)-1] == '/' || imageDir[strlen(imageDir)-1] == '\\')
+  {
+    newDir = new char[strlen(imageDir)+1];
+    strcpy(newDir, imageDir);
+  }
+  else
+  {
+    newDir = new char[strlen(imageDir)+2];
+    strcpy(newDir, imageDir);
+    newDir[strlen(imageDir)] = '/';
+    newDir[strlen(imageDir)+1] = '\0';
+  }
+  // check if the param is a Directory
+  if (isDir(newDir))
+    {
+      // check if the Directory has been added before
+      std::list<char*>::const_iterator imageDir;
+      for (imageDir = this->imageDirs.begin(); imageDir != this->imageDirs.end(); imageDir++)
+      {
+         if (!strcmp(*imageDir, newDir))
+         {
+           PRINTF(3)("Path %s already loaded\n", newDir);
+           delete[] newDir;
+           return true;
+         }
+      }
+      // adding the directory to the List
+      this->imageDirs.push_back(newDir);
+      return true;
+    }
+  else
+    {
+      PRINTF(1)("%s is not a Directory, and can not be added to the Paths of Images\n", newDir);
+      delete[] newDir;
+      return false;
+    }
+}
+#endif /* NO_TEXTURES */
+
+/**
+ *  loads resources
+ * @param fileName: The fileName of the resource to load
+ * @param prio: The ResourcePriority of this resource (will only be increased)
+ * @param param1: an additional option to parse (see the constuctors for more help)
+ * @param param2: an additional option to parse (see the constuctors for more help)
+ * @param param3: an additional option to parse (see the constuctors for more help)
+ * @returns a pointer to a desired Resource.
+*/
+BaseObject* ResourceManager::load(const char* fileName, ResourcePriority prio, void* param1, void* param2, void* param3)
+{
+  if (fileName == NULL)
+    return NULL;
+  ResourceType tmpType;
+#ifndef NO_MODEL
+#define __IF_OK
+  if (!strncasecmp(fileName+(strlen(fileName)-4), ".obj", 4))
+    tmpType = OBJ;
+  else if (!strncmp(fileName+(strlen(fileName)-4), ".md2", 4))
+    tmpType = MD2;
+  else if (!strcasecmp(fileName, "cube") ||
+           !strcasecmp(fileName, "sphere") ||
+           !strcasecmp(fileName, "plane") ||
+           !strcasecmp(fileName, "cylinder") ||
+           !strcasecmp(fileName, "cone"))
+    tmpType = PRIM;
+#endif /* NO_MODEL */
+#ifndef NO_AUDIO
+#ifdef __IF_OK
+  else
+#endif
+#define __IF_OK
+  if (!strncasecmp(fileName+(strlen(fileName)-4), ".wav", 4))
+    tmpType = WAV;
+  else if (!strncasecmp(fileName+(strlen(fileName)-4), ".mp3", 4))
+    tmpType = MP3;
+  else if (!strncasecmp(fileName+(strlen(fileName)-4), ".ogg", 4))
+    tmpType = OGG;
+#endif /* NO_AUDIO */
+#ifndef NO_TEXT
+#ifdef __IF_OK
+  else
+#endif
+#define __IF_OK
+ if (!strncasecmp(fileName+(strlen(fileName)-4), ".ttf", 4))
+    tmpType = TTF;
+#endif /* NO_TEXT */
+#ifndef NO_SHADERS
+#ifdef __IF_OK
+  else
+#endif
+#define __IF_OK
+ if (!strncasecmp(fileName+(strlen(fileName)-5), ".vert", 5))
+    tmpType = SHADER;
+#endif /* NO_SHADERS */
+#ifndef NO_TEXTURES
+#ifdef __IF_OK
+  else
+#else
+  if
+#endif
+   tmpType = IMAGE;
+#endif /* NO_TEXTURES */
+#undef __IF_OK
+  return this->load(fileName, tmpType, prio, param1, param2, param3);
+}
+
+/**
+ * loads resources
+ * @param fileName: The fileName of the resource to load
+ * @param type: The Type of Resource to load.
+ * @param prio: The ResourcePriority of this resource (will only be increased)
+ * @param param1: an additional option to parse (see the constuctors for more help)
+ * @param param2: an additional option to parse (see the constuctors for more help)
+ * @param param3: an additional option to parse (see the constuctors for more help)
+ * @returns a pointer to a desired Resource.
+*/
+BaseObject* ResourceManager::load(const char* fileName, ResourceType type, ResourcePriority prio,
+                            void* param1, void* param2, void* param3)
+{
+  if (fileName == NULL)
+    return NULL;
+
+  // searching if the resource was loaded before.
+  Resource* tmpResource = this->locateResourceByInfo(fileName, type, param1, param2, param3);
+  if (tmpResource != NULL) // if the resource was loaded before.
+    {
+      PRINTF(4)("not loading cached resource %s\n", tmpResource->name);
+      tmpResource->count++;
+      if(tmpResource->prio < prio)
+        tmpResource->prio = prio;
+    }
+  else
+    {
+      // Setting up the new Resource
+      tmpResource = new Resource;
+      tmpResource->count = 1;
+      tmpResource->type = type;
+      tmpResource->prio = prio;
+      tmpResource->pointer = NULL;
+      tmpResource->name = new char[strlen(fileName)+1];
+      strcpy(tmpResource->name, fileName);
+
+      // creating the full name. (directoryName + FileName)
+      char* fullName = ResourceManager::getFullName(fileName);
+      // Checking for the type of resource \see ResourceType
+      switch(type)
+        {
+#ifndef NO_MODEL
+        case OBJ:
+          if (param1)
+            tmpResource->modelSize = *(float*)param1;
+          else
+            tmpResource->modelSize = 1.0;
+
+          if(ResourceManager::isFile(fullName))
+            tmpResource->pointer = new OBJModel(fullName, tmpResource->modelSize);
+          else
+            {
+              PRINTF(2)("File %s in %s does not exist. Loading a cube-Model instead\n", fileName, dataDir);
+              tmpResource->pointer = ResourceManager::load("cube", PRIM, prio, &tmpResource->modelSize);
+            }
+          break;
+        case PRIM:
+          if (param1)
+            tmpResource->modelSize = *(float*)param1;
+          else
+            tmpResource->modelSize = 1.0;
+
+          if (!strcmp(tmpResource->name, "cube"))
+            tmpResource->pointer = new PrimitiveModel(PRIM_CUBE, tmpResource->modelSize);
+          else if (!strcmp(tmpResource->name, "sphere"))
+            tmpResource->pointer = new PrimitiveModel(PRIM_SPHERE, tmpResource->modelSize);
+          else if (!strcmp(tmpResource->name, "plane"))
+            tmpResource->pointer = new PrimitiveModel(PRIM_PLANE, tmpResource->modelSize);
+          else if (!strcmp(tmpResource->name, "cylinder"))
+            tmpResource->pointer = new PrimitiveModel(PRIM_CYLINDER, tmpResource->modelSize);
+          else if (!strcmp(tmpResource->name, "cone"))
+            tmpResource->pointer = new PrimitiveModel(PRIM_CONE, tmpResource->modelSize);
+          break;
+        case MD2:
+          if(ResourceManager::isFile(fullName))
+            {
+              if (param1 != NULL)
+                {
+                  tmpResource->secFileName = new char[strlen((const char*)param1)+1];
+                  strcpy(tmpResource->secFileName, (const char*) param1);
+                }
+              else
+                tmpResource->secFileName = NULL;
+                tmpResource->pointer = new MD2Data(fullName, tmpResource->secFileName);
+//               tmpResource->pointer = new MD2Model(fullName, tmpResource->secFileName);
+
+            }
+              break;
+#endif /* NO_MODEL */
+#ifndef NO_TEXT
+        case TTF:
+            if (param1 != NULL)
+              tmpResource->ttfSize = *(unsigned int*)param1;
+            else
+              tmpResource->ttfSize = FONT_DEFAULT_RENDER_SIZE;
+
+          if(isFile(fullName))
+            tmpResource->pointer = new Font(fullName, tmpResource->ttfSize);
+          else
+            PRINTF(2)("%s does not exist in %s. Not loading Font\n", fileName, this->dataDir);
+          break;
+#endif /* NO_TEXT */
+#ifndef NO_AUDIO
+        case WAV:
+          if(isFile(fullName))
+            tmpResource->pointer = new SoundBuffer(fullName);
+          break;
+        case OGG:
+          if (isFile(fullName))
+            tmpResource->pointer = new OggPlayer(fullName);
+          break;
+#endif /* NO_AUDIO */
+#ifndef NO_TEXTURES
+        case IMAGE:
+          if (param1 != NULL)
+            tmpResource->texTarget = *(GLenum*)param1;
+          else
+            tmpResource->texTarget = GL_TEXTURE_2D;
+          if(isFile(fullName))
+            {
+              PRINTF(4)("Image %s resides to %s\n", fileName, fullName);
+              tmpResource->pointer = new Texture(fullName);
+            }
+          else
+            {
+              std::list<char*>::iterator imageDir;
+              for (imageDir = this->imageDirs.begin(); imageDir != this->imageDirs.end(); imageDir++)
+                {
+                  char* imgName = new char[strlen(*imageDir)+strlen(fileName)+1];
+                  sprintf(imgName, "%s%s", *imageDir, fileName);
+                  if(isFile(imgName))
+                    {
+                      PRINTF(4)("Image %s resides to %s\n", fileName, imgName);
+                      tmpResource->pointer = new Texture(imgName, tmpResource->texTarget);
+                      delete[] imgName;
+                      break;
+                    }
+                  delete[] imgName;
+                }
+            }
+          if(!tmpResource)
+             PRINTF(2)("!!Image %s not Found!!\n", fileName);
+          break;
+#endif /* NO_TEXTURES */
+#ifndef NO_SHADERS
+          case SHADER:
+            if(ResourceManager::isFile(fullName))
+            {
+              if (param1 != NULL)
+              {
+                char* secFullName = ResourceManager::getFullName((const char*)param1);
+                if (ResourceManager::isFile(secFullName))
+                {
+                  tmpResource->secFileName = new char[strlen((const char*)param1)+1];
+                  strcpy(tmpResource->secFileName, (const char*) param1);
+                  tmpResource->pointer = new Shader(fullName, secFullName);
+                }
+                delete[] secFullName;
+              }
+              else
+              {
+                tmpResource->secFileName = NULL;
+                tmpResource->pointer = new Shader(fullName, NULL);
+              }
+            }
+            break;
+#endif /* NO_SHADERS */
+        default:
+          tmpResource->pointer = NULL;
+          PRINTF(1)("No type found for %s.\n   !!This should not happen unless the Type is not supported yet. JUST DO IT!!\n", tmpResource->name);
+          break;
+        }
+      if (tmpResource->pointer != NULL)
+        this->resourceList.push_back(tmpResource);
+      delete[] fullName;
+    }
+  if (tmpResource->pointer != NULL)
+    return tmpResource->pointer;
+  else
+    {
+      PRINTF(2)("Resource %s could not be loaded\n", fileName);
+      delete[] tmpResource->name;
+      delete tmpResource;
+      return NULL;
+    }
+}
+
+/**
+ * unloads a Resource
+ * @param pointer: The pointer to free
+ * @param prio: the PriorityLevel to unload this resource
+ * @returns true if successful (pointer found, and deleted), false otherwise
+*/
+bool ResourceManager::unload(void* pointer, ResourcePriority prio)
+{
+  if (pointer == NULL)
+    return false;
+  // if pointer is existent. and only one resource of this type exists.
+  Resource* tmpResource = this->locateResourceByPointer(pointer);
+  if (tmpResource != NULL)
+    return unload(tmpResource, prio);
+  else
+  {
+    PRINTF(2)("Resource not Found %p\n", pointer);
+    return false;
+  }
+}
+
+/**
+ * unloads a Resource
+ * @param resource: The resource to unloade
+ * @param prio the PriorityLevel to unload this resource
+ * @returns true on success, false otherwise.
+*/
+bool ResourceManager::unload(Resource* resource, ResourcePriority prio)
+{
+  if (resource == NULL)
+    return false;
+  if (resource->count > 0)
+    resource->count--;
+
+  if (resource->prio <= prio)
+    {
+      if (resource->count == 0)
+        {
+          // deleting the Resource
+          switch(resource->type)
+            {
+#ifndef NO_MODEL
+            case OBJ:
+            case PRIM:
+              delete (Model*)resource->pointer;
+              break;
+            case MD2:
+              delete (MD2Data*)resource->pointer;
+              break;
+#endif /* NO_MODEL */
+#ifndef NO_AUDIO
+            case WAV:
+              delete (SoundBuffer*)resource->pointer;
+              break;
+            case OGG:
+              delete (OggPlayer*)resource->pointer;
+              break;
+#endif /* NO_AUDIO */
+#ifndef NO_TEXT
+            case TTF:
+              delete (Font*)resource->pointer;
+              break;
+#endif /* NO_TEXT */
+#ifndef NO_TEXTURES
+            case IMAGE:
+              delete (Texture*)resource->pointer;
+              break;
+#endif /* NO_TEXTURES */
+#ifndef NO_SHADERS
+            case SHADER:
+              delete (Shader*)resource->pointer;
+              break;
+#endif /* NO_SHADERS */
+            default:
+              PRINTF(2)("NOT YET IMPLEMENTED !!FIX FIX!!\n");
+              return false;
+              break;
+            }
+          // deleting the List Entry:
+          PRINTF(4)("Resource %s safely removed.\n", resource->name);
+          delete[] resource->name;
+          std::list<Resource*>::iterator resourceIT = std::find(this->resourceList.begin(), this->resourceList.end(), resource);
+          this->resourceList.erase(resourceIT);
+          delete resource;
+        }
+      else
+        PRINTF(4)("Resource %s not removed, because there are still %d References to it.\n", resource->name, resource->count);
+    }
+  else
+    PRINTF(4)("not deleting resource %s because DeleteLevel to high\n", resource->name);
+  return true;
+}
+
+
+/**
+ * unloads all alocated Memory of Resources with a pririty lower than prio
+ * @param prio The priority to delete
+*/
+bool ResourceManager::unloadAllByPriority(ResourcePriority prio)
+{
+  std::list<Resource*>::iterator resource, pre;
+  pre = --this->resourceList.end();
+  unsigned int removeCount;
+  for (unsigned int round = 0; round < 3; round++)
+  {
+    removeCount = 0;
+    while (pre != resourceList.end())
+    {
+      resource = pre;
+      pre--;
+        if ((*resource)->prio <= prio)
+        {
+          if ((*resource)->count == 0)
+            unload((*resource), prio);
+          else
+          {
+            PRINTF(2)("unable to unload %s because there are still %d references to it\n",
+                     (*resource)->name, (*resource)->count);
+            removeCount++;
+          }
+        }
+     }
+     if (removeCount == 0) break;
+  }
+}
+
+
+/**
+ * Searches for a Resource by some information
+ * @param fileName: The name to look for
+ * @param type the Type of resource to locate.
+ * @param param1: an additional option to parse (see the constuctors for more help)
+ * @param param2: an additional option to parse (see the constuctors for more help)
+ * @param param3: an additional option to parse (see the constuctors for more help)
+ * @returns a Pointer to the Resource if found, NULL otherwise.
+*/
+Resource* ResourceManager::locateResourceByInfo(const char* fileName, ResourceType type,
+                                                void* param1, void* param2, void* param3) const
+{
+  std::list<Resource*>::const_iterator resource;
+  for (resource = this->resourceList.begin(); resource != this->resourceList.end(); resource++)
+  {
+    if ((*resource)->type == type && !strcmp(fileName, (*resource)->name))
+        {
+          bool match = false;
+
+          switch (type)
+            {
+#ifndef NO_MODEL
+            case PRIM:
+            case OBJ:
+              if (!param1)
+                {
+                  if ((*resource)->modelSize == 1.0)
+                    match = true;
+                }
+              else if ((*resource)->modelSize == *(float*)param1)
+                match = true;
+              break;
+            case MD2:
+              if (!param1)
+                {
+                  if ((*resource)->secFileName == NULL)
+                    match = true;
+                }
+              else if (!strcmp((*resource)->secFileName, (const char*)param1))
+                match = true;
+              break;
+#endif /* NO_MODEL */
+#ifndef NO_TEXT
+            case TTF:
+              if (param1 == NULL)
+                {
+                  if ((*resource)->ttfSize == FONT_DEFAULT_RENDER_SIZE)
+                    match = true;
+                }
+              else if ((*resource)->ttfSize == *(unsigned int*)param1)
+                match = true;
+              break;
+#endif /* NO_TEXT */
+#ifndef NO_SHADERS
+              case SHADER:
+                if (!param1)
+                {
+                  if ((*resource)->secFileName == NULL)
+                    match = true;
+                }
+                else if (!strcmp((*resource)->secFileName, (const char*)param1))
+                  match = true;
+#endif /* NO_SHADERS */
+#ifndef NO_TEXTURES
+              case IMAGE:
+                if (!param1)
+                {
+                  if ((*resource)->texTarget == GL_TEXTURE_2D)
+                    match = true;
+                }
+                else if ((*resource)->texTarget ==  *(GLenum*)param1)
+                  match = true;
+#endif /* NO_TEXTURES */
+            default:
+              match = true;
+              break;
+            }
+          if (match)
+            {
+              return (*resource);
+            }
+        }
+    }
+  return NULL;
+}
+
+/**
+ * Searches for a Resource by Pointer
+ * @param pointer the Pointer to search for
+ * @returns a Pointer to the Resource if found, NULL otherwise.
+*/
+Resource* ResourceManager::locateResourceByPointer(const void* pointer) const
+{
+  //  Resource* enumRes = resourceList->enumerate();
+  std::list<Resource*>::const_iterator resource;
+  for (resource = this->resourceList.begin(); resource != this->resourceList.end(); resource++)
+    if (pointer == (*resource)->pointer)
+        return (*resource);
+  return NULL;
+}
+
+/**
+ * Checks if it is a Directory
+ * @param directoryName the Directory to check for
+ * @returns true if it is a directory/symlink false otherwise
+*/
+bool ResourceManager::isDir(const char* directoryName)
+{
+  if (directoryName == NULL)
+    return false;
+
+  char* tmpDirName = NULL;
+  struct stat status;
+
+  // checking for the termination of the string given. If there is a "/" at the end cut it away
+  if (directoryName[strlen(directoryName)-1] == '/' ||
+      directoryName[strlen(directoryName)-1] == '\\')
+    {
+      tmpDirName = new char[strlen(directoryName)];
+      strncpy(tmpDirName, directoryName, strlen(directoryName)-1);
+      tmpDirName[strlen(directoryName)-1] = '\0';
+    }
+  else
+    {
+      tmpDirName = new char[strlen(directoryName)+1];
+      strcpy(tmpDirName, directoryName);
+    }
+
+  if(!stat(tmpDirName, &status))
+    {
+      if (status.st_mode & (S_IFDIR
+#ifndef __WIN32__
+                            | S_IFLNK
+#endif
+                            ))
+        {
+          delete[] tmpDirName;
+          return true;
+        }
+      else
+        {
+          delete[] tmpDirName;
+          return false;
+        }
+    }
+  else
+  {
+    delete[] tmpDirName;
+    return false;
+  }
+}
+
+/**
+ * Checks if the file is either a Regular file or a Symlink
+ * @param fileName the File to check for
+ * @returns true if it is a regular file/symlink, false otherwise
+*/
+bool ResourceManager::isFile(const char* fileName)
+{
+  if (fileName == NULL)
+    return false;
+  char* tmpFileName = ResourceManager::homeDirCheck(fileName);
+  // actually checks the File
+  struct stat status;
+  if (!stat(tmpFileName, &status))
+    {
+      if (status.st_mode & (S_IFREG
+#ifndef __WIN32__
+                            | S_IFLNK
+#endif
+                            ))
+        {
+          delete[] tmpFileName;
+          return true;
+        }
+      else
+        {
+          delete[] tmpFileName;
+          return false;
+        }
+    }
+  else
+    {
+      delete[] tmpFileName;
+      return false;
+    }
+}
+
+/**
+ * touches a File on the disk (thereby creating it)
+ * @param fileName The file to touch
+*/
+bool ResourceManager::touchFile(const char* fileName)
+{
+  char* tmpName = ResourceManager::homeDirCheck(fileName);
+  if (tmpName == NULL)
+    return false;
+  FILE* stream;
+  if( (stream = fopen (tmpName, "w")) == NULL)
+    {
+      PRINTF(1)("could not open %s fro writing\n", fileName);
+      delete[] tmpName;
+      return false;
+    }
+  fclose(stream);
+
+  delete[] tmpName;
+}
+
+/**
+ * deletes a File from disk
+ * @param fileName the File to delete
+*/
+bool ResourceManager::deleteFile(const char* fileName)
+{
+  if (fileName == NULL)
+    return false;
+  char* tmpName = ResourceManager::homeDirCheck(fileName);
+  unlink(tmpName);
+  delete[] tmpName;
+}
+
+/**
+ * @param name the Name of the file to check
+ * @returns The name of the file, including the HomeDir
+ * IMPORTANT: this has to be deleted from the outside
+ */
+char* ResourceManager::homeDirCheck(const char* name)
+{
+  if (name == NULL)
+    return NULL;
+  char* retName;
+  if (!strncmp(name, "~/", 2))
+    {
+      char tmpFileName[500];
+#ifdef __WIN32__
+      strcpy(tmpFileName, getenv("USERPROFILE"));
+#else
+      strcpy(tmpFileName, getenv("HOME"));
+#endif
+      retName = new char[strlen(tmpFileName)+strlen(name)];
+      sprintf(retName, "%s%s", tmpFileName, name+1);
+    }
+  else
+    {
+      retName = new char[strlen(name)+1];
+      strcpy(retName, name);
+    }
+  return retName;
+}
+
+/**
+ * @param fileName the Name of the File to check
+ * @returns The full name of the file, including the DataDir, and NULL if the file does not exist
+ * !!IMPORTANT: this has to be deleted from the outside!!
+*/
+char* ResourceManager::getFullName(const char* fileName)
+{
+  if (fileName == NULL || ResourceManager::getInstance()->getDataDir() == NULL)
+    return NULL;
+
+  char* retName = new char[strlen(ResourceManager::getInstance()->getDataDir())
+                           + strlen(fileName) + 1];
+  sprintf(retName, "%s%s", ResourceManager::getInstance()->getDataDir(), fileName);
+  if (ResourceManager::isFile(retName) || ResourceManager::isDir(retName))
+    return retName;
+  else
+    {
+      delete[] retName;
+      return NULL;
+    }
+}
+
+
+/**
+ * checks wether a file is in the DataDir.
+ * @param fileName the File to check if it is in the Data-Dir structure.
+ * @returns true if the file exists, false otherwise
+ */
+bool ResourceManager::isInDataDir(const char* fileName)
+{
+  if (fileName == NULL || ResourceManager::getInstance()->getDataDir() == NULL)
+    return false;
+
+  bool retVal = false;
+  char* checkFile = new char[strlen(ResourceManager::getInstance()->getDataDir())
+      + strlen(fileName) + 1];
+  sprintf(checkFile, "%s%s", ResourceManager::getInstance()->getDataDir(), fileName);
+
+  if (ResourceManager::isFile(checkFile) || ResourceManager::isDir(checkFile))
+    retVal = true;
+  else
+    retVal = false;
+  delete[] checkFile;
+  return retVal;
+}
+
+
+/**
+ * outputs debug information about the ResourceManager
+*/
+void ResourceManager::debug() const
+{
+  PRINT(0)("=RM===================================\n");
+  PRINT(0)("= RESOURCE-MANAGER DEBUG INFORMATION =\n");
+  PRINT(0)("======================================\n");
+  // if it is not initialized
+  PRINT(0)(" Reference is: %p\n", ResourceManager::singletonRef);
+  PRINT(0)(" Data-Directory is: %s\n", this->dataDir);
+  PRINT(0)(" List of Image-Directories: ");
+  std::list<char*>::const_iterator imageDir;
+  for (imageDir = this->imageDirs.begin(); imageDir != this->imageDirs.end(); imageDir++)
+      PRINT(0)("%s ", (*imageDir));
+  PRINT(0)("\n");
+
+  PRINT(0)("List of all stored Resources:\n");
+  std::list<Resource*>::const_iterator resource;
+  for (resource = this->resourceList.begin(); resource != this->resourceList.end(); resource++)
+
+    {
+      PRINT(0)("-----------------------------------------\n");
+      PRINT(0)("Name: %s; References: %d; Type: %s ", (*resource)->name, (*resource)->count, ResourceManager::ResourceTypeToChar((*resource)->type));
+
+      PRINT(0)("gets deleted at ");
+      switch((*resource)->prio)
+        {
+        default:
+        case RP_NO:
+          PRINT(0)("first posibility (0)\n");
+          break;
+        case RP_LEVEL:
+          PRINT(0)("the end of the Level (1)\n");
+          break;
+        case RP_CAMPAIGN:
+          PRINT(0)("the end of the campaign (2)\n");
+          break;
+        case RP_GAME:
+          PRINT(0)("when leaving the game (3)\n");
+          break;
+        }
+    }
+
+
+
+  PRINT(0)("==================================RM==\n");
+}
+
+
+/**
+ * converts a ResourceType into the corresponding String
+ * @param type the ResourceType to translate
+ * @returns the converted String.
+ */
+const char* ResourceManager::ResourceTypeToChar(ResourceType type)
+{
+  switch (type)
+  {
+#ifndef NO_MODEL
+    case OBJ:
+      return "ObjectModel";
+      break;
+    case PRIM:
+      return "PrimitiveModel";
+      break;
+    case MD2:
+      return "MD2-Data";
+      break;
+#endif
+#ifndef NO_TEXTURES
+    case IMAGE:
+      return "ImageFile (Texture)";
+      break;
+#endif
+#ifndef NO_AUDIO
+    case WAV:
+      return "SoundFile";
+      break;
+    case OGG:
+      return "MusicFile";
+      break;
+#endif
+#ifndef NO_TEXT
+    case TTF:
+      return "Font (TTF)";
+      break;
+#endif
+#ifndef NO_SHADERS
+    case SHADER:
+      return "Shader";
+      break;
+#endif
+    default:
+      return "unknown Format";
+      break;
+  }
+}
Index: branches/network/src/util/loading/resource_manager.h
===================================================================
--- branches/network/src/util/loading/resource_manager.h	(revision 6636)
+++ branches/network/src/util/loading/resource_manager.h	(revision 6636)
@@ -0,0 +1,154 @@
+/*!
+ * @file resource_manager.h
+  *  The Resource Manager checks if a file/resource is loaded.
+
+    If a file/resource was already loaded the resourceManager will
+    return a void pointer to the desired resource.
+    Otherwise it will instruct the coresponding resource-loader to load,
+    and receive a pointer to it.
+
+    it is possible to compile the resource Manager without some modules by
+    just adding the compile flag -D....
+    (NO_MODEL)
+    (NO_AUDIO)
+    (NO_TEXT)
+    (NO_TEXTURES)
+*/
+
+#ifndef _RESOURCE_MANAGER_H
+#define _RESOURCE_MANAGER_H
+
+#include "base_object.h"
+
+
+#include <list>
+
+//! An eumerator for different fileTypes the resourceManager supports
+typedef enum ResourceType
+{
+#ifndef NO_MODEL
+  OBJ,                  //!< loading .obj file
+  PRIM,                 //!< loading primitive model
+  MD2,                  //!< loading md2-file
+#endif /* NO_MODEL */
+#ifndef NO_TEXT
+  TTF,                  //!< loading a TrueTypeFont
+#endif /* NO_TEXT */
+#ifndef NO_AUDIO
+  WAV,                  //!< loading wav
+  MP3,                  //!< loading mp3
+  OGG,                  //!< loading ogg
+#endif /* NO_AUDIO */
+#ifndef NO_TEXTURES
+  IMAGE,                //!< loading an image
+#endif /* NO_TEXTURES */
+#ifndef NO_SHADERS
+  SHADER,               //!< openGL-shader program
+#endif /* NO_SHADERS */
+};
+
+//! An enumerator for different UNLOAD-types.
+/**
+   RP_NO:        will be unloaded on request
+   RP_LEVEL:     will be unloaded at the end of a Level
+   RP_CAMPAIGN:  will be unloaded at the end of a Campaign
+   RP_GAME:      will be unloaded at the end of the whole Game (when closing orxonox)
+*/
+typedef enum ResourcePriority
+{
+  RP_NO        =   0,
+  RP_LEVEL     =   1,
+  RP_CAMPAIGN  =   2,
+  RP_GAME      =   4
+};
+
+//! A Struct that keeps track about A resource its name its Type, and so on
+struct Resource
+{
+  BaseObject*       pointer;           //!< Pointer to the Resource.
+  unsigned int      count;             //!< How many times this Resource has been loaded.
+
+  char*             name;              //!< Name of the Resource.
+  ResourceType      type;              //!< ResourceType of this Resource.
+  ResourcePriority  prio;              //!< The Priority of this resource. (This will only be increased)
+
+  // more specific
+  union {
+#ifndef NO_MODEL
+  float             modelSize;         //!< the size of the model (OBJ/PRIM)
+  char*             secFileName;       //!< a seconf fileName
+#endif /* NO_MODEL */
+#ifndef NO_TEXT
+  unsigned int      ttfSize;           //!< the size of the ttf-font (TTF)
+#endif /* NO_TEXT */
+#ifndef NO_TEXTURES
+  GLenum            texTarget;
+#endif /* NO_TEXTURES */
+  };
+};
+
+
+//! The ResourceManager is a class, that decides if a file/resource should be loaded
+/**
+ * If a file/resource was already loaded the resourceManager will
+ * return a pointer to the desired resource.
+ * Otherwise it will instruct the corresponding resource-loader to load,
+ * and receive the pointer to it.
+ *
+ * It does it by looking, if a desired file has already been loaded.
+ * There is also the possibility to check for some variables
+ */
+class ResourceManager : public BaseObject
+{
+ public:
+  virtual ~ResourceManager();
+  /** @returns a Pointer to the only object of this Class */
+  inline static ResourceManager* getInstance() { if (!singletonRef) singletonRef = new ResourceManager();  return singletonRef; };
+
+  bool setDataDir(const char* dataDir);
+  /** @returns the Name of the data directory */
+  inline const char* getDataDir() const { return this->dataDir; };
+
+
+  bool tryDataDir(const char* dataDir);
+  bool verifyDataDir(const char* fileInside);
+  bool addImageDir(const char* imageDir);
+  BaseObject* load(const char* fileName, ResourcePriority prio = RP_NO,
+               void* param1 = NULL, void* param2 = NULL, void* param3 = NULL);
+  BaseObject* load(const char* fileName, ResourceType type, ResourcePriority prio = RP_NO,
+               void* param1 = NULL, void* param2 = NULL, void* param3 = NULL);
+  bool unload(void* pointer, ResourcePriority prio = RP_NO);
+  bool unload(Resource* resource, ResourcePriority = RP_NO);
+  bool unloadAllByPriority(ResourcePriority prio);
+
+  Resource* locateResourceByInfo(const char* fileName, ResourceType type, void* param1, void* param2, void* param3) const;
+  Resource* locateResourceByPointer(const void* pointer) const;
+
+  void debug() const;
+
+
+  // utility functions for handling files in and around the data-directory
+  static bool isDir(const char* directory);
+  static bool isFile(const char* fileName);
+  static bool touchFile(const char* fileName);
+  static bool deleteFile(const char* fileName);
+  static char* homeDirCheck(const char* fileName);
+  static char* getFullName(const char* fileName);
+  static bool isInDataDir(const char* fileName);
+
+  static const char* ResourceTypeToChar(ResourceType type);
+
+
+ private:
+  ResourceManager();
+
+ private:
+  static ResourceManager*  singletonRef;       //!< singleton Reference
+
+  char*                    dataDir;            //!< The Data Directory, where all relevant Data is stored.
+  std::list<Resource*>     resourceList;       //!< The List of Resources, that has already been loaded.
+  std::list<char*>         imageDirs;          //!< A list of directories in which images are stored.
+
+};
+
+#endif /* _RESOURCE_MANAGER_H */
Index: branches/network/src/util/object_manager.cc
===================================================================
--- branches/network/src/util/object_manager.cc	(revision 6636)
+++ branches/network/src/util/object_manager.cc	(revision 6636)
@@ -0,0 +1,245 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "object_manager.h"
+#include "class_list.h"
+
+#include "world_entity.h"
+
+#include "shell_command.h"
+
+#include <assert.h>
+
+using namespace std;
+SHELL_COMMAND(debug, ObjectManager, debug)
+    ->defaultValues(2, NULL, 0);
+
+/**
+ * @brief standard constructor
+ */
+ObjectManager::ObjectManager ()
+{
+   this->setClassID(CL_OBJECT_MANAGER, "ObjectManager");
+   this->setName("ObjectManager");
+
+   pNodeList = NULL;
+}
+
+
+/**
+ * @brief standard deconstructor
+ *
+ * this also removes ALL entitites in existence.
+ */
+ObjectManager::~ObjectManager ()
+{
+  this->flush();
+}
+
+/**
+ * @brief flushes all entities
+ *
+ * this function deletes all entities that exist within the ObjectManager.
+ * It does this by poping each list from the front, and delete the given object.
+ *
+ * automatically called by a destructor.
+ */
+void ObjectManager::flush()
+{
+  for (unsigned int i = 0; i < OM_SIZE; ++i)
+    while(!this->objectLists[i].empty())
+      delete this->objectLists[i].front();
+}
+
+
+/**
+ * @brief moves an Entity from an old list to a new One
+ * @param entity the entity to move.
+ * @param omList the new List to move the entity to.
+ *
+ * this will erase the entity from the old list
+ */
+void ObjectManager::toList (WorldEntity* entity, OM_LIST omList)
+{
+  assert (omList != OM_SIZE);
+
+  if (likely(entity->getOMListNumber() != OM_INIT))
+    this->objectLists[entity->getOMListNumber()].erase(entity->getEntityIterator());
+
+  if (likely(omList != OM_INIT))
+  {
+    this->objectLists[omList].push_back(entity);
+    entity->getEntityIterator() = --this->objectLists[omList].end();
+    entity->getOMListNumber() = omList;
+  }
+}
+
+
+/**
+ * @see ObjectManager::toList(WorldEntity* OM_LIST)
+ * @param entity the entity to move.
+ * @param omList the new List to move the entity to.
+ *
+ * this function also does a transformation from omList as char* to OM_LIST.
+ */
+void ObjectManager::toList (WorldEntity* entity, const char* omList)
+{
+  this->toList(entity, ObjectManager::StringToOMList(omList));
+}
+
+
+
+/**
+ * returns a new List with a list of WorldEntities of distance Radius from center
+ */
+std::list<WorldEntity*>* ObjectManager::distanceFromObject(const PNode& center, float radius, ClassID classID)
+{
+  const std::list<BaseObject*>* objectList = ClassList::getList(classID);
+  if (objectList != NULL)
+  {
+    std::list<WorldEntity*>* newList = new std::list<WorldEntity*>;
+
+    list<BaseObject*>::const_iterator node;
+    for (node = objectList->begin(); node != objectList->end(); node++)
+      if ((dynamic_cast<PNode*>(*node)->getAbsCoor() - center.getAbsCoor()).len() < radius)
+        newList->push_back(dynamic_cast<WorldEntity*>(*node));
+    return newList;
+  }
+  return NULL;
+}
+
+
+/**
+ * @brief print out nice debug information about Elements in the list OM_LIST
+ * @param omList the List to debug.
+ * @param level: level 0: only show list info; level 1: also show entities and their names.
+ */
+void ObjectManager::debug(OM_LIST omList, unsigned int level) const
+{
+  if (omList != OM_INIT || omList == OM_SIZE)
+  {
+    PRINT(0)(" +ObjectManager-LIST: '%s'==size='%d'==---\n", ObjectManager::OMListToString((OM_LIST)omList), this->objectLists[omList].size());
+  //  if (level >= 1)
+    {
+      std::list<WorldEntity*>::const_iterator entity;
+      for (entity = this->objectLists[omList].begin(); entity != this->objectLists[omList].end(); entity++)
+      {
+        PRINT(0)(" | %s::%s\n",(*entity)->getClassName(), (*entity)->getName());
+      }
+    }
+  }
+  else
+    PRINTF(2)("Invalid query. for OM_INIT-LIST or OM_SIZE\n");
+}
+
+
+/**
+ * @brief prints out very nice debug information
+ * @param listName the Name of the list to get Debug information from
+ * @param level: level 0: only show list info; level 1: also show entities and their names.
+ */
+void ObjectManager::debug(const char* listName, unsigned int level)
+{
+  PRINT(0)("=================================\n");
+  PRINT(0)("=ObjectManager-DEBUG=============\n");
+  PRINT(0)("=================================\n");
+  if (listName == NULL || listName[0] == '\0')
+    for (unsigned int i = 0; i < OM_SIZE; ++i)
+      debug((OM_LIST) i, level);
+  else
+    debug(ObjectManager::StringToOMList(listName));
+  PRINT(0)("=========================== OM ==\n");
+}
+
+
+
+/**
+ * @brief transforms an omList into a String (usefull for debugging).
+ * @param omList the OM_LIST to be transformed into a String.
+ * @returns the String transformed from omList.
+ */
+const char* ObjectManager::OMListToString(OM_LIST omList)
+{
+  if (omList == OM_INIT || omList == OM_SIZE)
+    return "===invalid===";
+
+  printf("%d\n", omList);
+  return ObjectManager::objectManagerListNames[omList];
+}
+
+
+
+/**
+ * @brief transforms a String into an OM_LIST (usefull for debugging/Loading).
+ * @param listName the OM_LIST-name to be transformed into an OM_LIST.
+ * @returns the OM_LIST transformed from listName. or the default, if not found or NULL.
+ */
+OM_LIST ObjectManager::StringToOMList(const char* listName)
+{
+  if (unlikely(listName == NULL)) return OM_DEFAULT_LIST;
+
+  for(unsigned int i = 0; i < OM_SIZE; ++i) {
+    if(!strcmp(listName, ObjectManager::objectManagerListNames[i])) {
+      return (OM_LIST)i;
+    }
+  }
+  return OM_DEFAULT_LIST;
+}
+
+
+
+const char* ObjectManager::objectManagerListNames[] = {
+    "null",
+    "dead",
+    "dead-tick",
+    "environ-notick",
+    "environ",
+    "common",
+
+    "group00",
+    "group00-proj",
+    "group01",
+    "group01-proj",
+    "group02",
+    "group02-proj",
+    "group03",
+    "group03-proj",
+    "group04",
+    "group04-proj",
+    "group05",
+    "group05-proj",
+    "group06",
+    "group06-proj",
+    "group07",
+    "group07-proj",
+    "group08",
+    "group08-proj",
+    "group09",
+    "group09-proj",
+    "group10",
+    "group10-proj",
+    "group11",
+    "group11-proj",
+    "group12",
+    "group12-proj",
+    "group13",
+    "group13-proj",
+    "group14",
+    "group14-proj",
+    "group15",
+    "group15-proj"
+};
Index: branches/network/src/util/object_manager.h
===================================================================
--- branches/network/src/util/object_manager.h	(revision 6636)
+++ branches/network/src/util/object_manager.h	(revision 6636)
@@ -0,0 +1,101 @@
+/*!
+ * @file object_manager.h
+ * @brief Definition of the ObjectManager.
+ */
+
+#ifndef _OBJECT_MANAGER_H
+#define _OBJECT_MANAGER_H
+
+#include "base_object.h"
+#include <list>
+#include <vector>
+
+/// Enumerator for Managed Object Lists
+typedef enum {
+  OM_NULL             =  0,
+  OM_DEAD,
+  OM_DEAD_TICK,
+  OM_ENVIRON_NOTICK,
+  OM_ENVIRON,
+  OM_COMMON,
+
+  OM_GROUP_00,
+  OM_GROUP_00_PROJ,
+  OM_GROUP_01,
+  OM_GROUP_01_PROJ,
+  OM_GROUP_02,
+  OM_GROUP_02_PROJ,
+  OM_GROUP_03,
+  OM_GROUP_03_PROJ,
+  OM_GROUP_04,
+  OM_GROUP_04_PROJ,
+  OM_GROUP_05,
+  OM_GROUP_05_PROJ,
+  OM_GROUP_06,
+  OM_GROUP_06_PROJ,
+  OM_GROUP_07,
+  OM_GROUP_07_PROJ,
+  OM_GROUP_08,
+  OM_GROUP_08_PROJ,
+  OM_GROUP_09,
+  OM_GROUP_09_PROJ,
+  OM_GROUP_10,
+  OM_GROUP_10_PROJ,
+  OM_GROUP_11,
+  OM_GROUP_11_PROJ,
+  OM_GROUP_12,
+  OM_GROUP_12_PROJ,
+  OM_GROUP_13,
+  OM_GROUP_13_PROJ,
+  OM_GROUP_14,
+  OM_GROUP_14_PROJ,
+  OM_GROUP_15,
+  OM_GROUP_15_PROJ,
+
+  OM_SIZE,
+
+
+  OM_INIT             = -1, //!< DO NOT USE THIS. (WorldEntity Internal).
+} OM_LIST;
+
+#define OM_DEFAULT_LIST  OM_NULL
+
+
+// FORWARD DECLARATION
+class PNode;
+class WorldEntity;
+
+//! A powerfull handler for the Object (WorldEntities) in the World.
+class ObjectManager : public BaseObject {
+
+ public:
+   ObjectManager();
+   virtual ~ObjectManager();
+
+  void flush();
+
+  void toList (WorldEntity* entity, OM_LIST omList = OM_DEFAULT_LIST);
+  void toList (WorldEntity* entity, const char* omList);
+
+
+  std::list<WorldEntity*>& getObjectList(OM_LIST listNumber) { return this->objectLists[listNumber]; }
+  const std::list<WorldEntity*>& getObjectList(OM_LIST listNumber) const { return this->objectLists[listNumber]; }
+
+  static std::list<WorldEntity*>* distanceFromObject(const PNode& center, float radius, ClassID classID);
+
+  void debug(OM_LIST omList, unsigned int level = 0) const;
+  void debug(const char* listName = NULL, unsigned int level = 0);
+
+  static OM_LIST StringToOMList(const char* listName);
+  static const char* OMListToString(OM_LIST omList);
+
+ private:
+  const std::list<BaseObject>*            pNodeList;
+
+
+  std::list<WorldEntity*>                 objectLists[OM_SIZE];
+
+  static const char*                      objectManagerListNames[]; //!< Names of all the lists
+};
+
+#endif /* _OBJECT_MANAGER_H */
Index: branches/network/src/util/state.cc
===================================================================
--- branches/network/src/util/state.cc	(revision 6636)
+++ branches/network/src/util/state.cc	(revision 6636)
@@ -0,0 +1,51 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "state.h"
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+using namespace std;
+
+
+
+PNode* State::camera = NULL;
+PNode* State::cameraTarget = NULL;
+
+SkyBox* State::skyBox = NULL;
+
+ObjectManager* State::objectManager = NULL;
+
+
+unsigned int State::resX = 1;
+unsigned int State::resY = 1;
+
+StoryEntity* State::storyEntity = NULL;
+
+Player* State::player = NULL;
+
+
+/**
+ *  sets camera and target of the current Camera
+*/
+void State::setCamera(PNode* camera, PNode* cameraTarget)
+{
+  State::camera = camera;
+  State::cameraTarget = cameraTarget;
+}
Index: branches/network/src/util/state.h
===================================================================
--- branches/network/src/util/state.h	(revision 6636)
+++ branches/network/src/util/state.h	(revision 6636)
@@ -0,0 +1,91 @@
+/*!
+ * @file state.h
+ * Definition of the States Class
+*/
+
+#ifndef _STATE_H
+#define _STATE_H
+
+
+// FORWARD DECLARATION
+class PNode;
+class WorldEntity;
+class Player;
+class SkyBox;
+class StoryEntity;
+class ObjectManager;
+
+
+//! handles states about orxonox's most importatn objects
+/**
+ * This is an abstract Class-container, not really a Class.
+ * in this Class only static references to the most important
+ * Objects/List/etc. are stored.
+ */
+class State {
+
+ public:
+   //////////////
+   /// CAMERA ///
+   //////////////
+  /** @param camera the PNode to the Camera, @param cameraTarget the PNode to the Camera's target */
+  static void setCamera(PNode* camera, PNode* cameraTarget);
+  /** @returns a Pointer to the PNode of the Camera */
+  static inline PNode* getCamera() { return State::camera; };
+  /** @returns a Pointer to the CameraTarget */
+  static inline PNode* getCameraTarget() { return State::cameraTarget; };
+
+  ////////////////
+  /// SKYBOX   ///
+  ////////////////
+  /** @returns the current SkyBox */
+  static inline SkyBox* getSkyBox() { return State::skyBox; };
+  /** @param skyBox the SkyBox */
+  static inline SkyBox* setSkyBox(SkyBox* skyBox) { State::skyBox = skyBox; };
+
+  //////////////////////
+  /// OBJECT-MANAGER ///
+  //////////////////////
+  /** @param objectManager the new Current ObjectManager */
+  static inline void setObjectManager(ObjectManager* objectManager) { State::objectManager = objectManager; };
+  /** @returns the current ObjectManager. */
+  static inline ObjectManager* getObjectManager() { return State::objectManager; };
+
+  static inline void setResolution(unsigned int resX, unsigned int resY) { State::resX = resX; State::resY = resY; };
+  static inline unsigned int getResX() { return State::resX; };
+  static inline unsigned int getResY() { return State::resY; };
+
+  //////////////////////
+  /// STORY-ENTITY   ///
+  //////////////////////
+  /** @param storyEntity sets the current StoryEntity that is been played */
+  static inline void setCurrentStoryEntity(StoryEntity* storyEntity) { State::storyEntity = storyEntity; };
+  /** @returns the current StoryEntity played */
+  static inline StoryEntity* getCurrentStoryEntity() { return State::storyEntity; };
+
+  //////////////
+  /// PLAYER ///
+  //////////////
+  /** @param player sets the current local player */
+  static inline void setPlayer(Player* player) { State::player = player; };
+  /** @returns the local player*/
+  static inline Player* getPlayer() { return State::player; };
+
+
+
+ private:
+  State();
+
+  static PNode*                 camera;             //!< A reference to the camera
+  static PNode*                 cameraTarget;       //!< A reference to the cameraTarget
+  static PNode*                 nullParent;         //!< A reference to the Null-PNode.
+  static ObjectManager*         objectManager;      //!< A reference to the current ObjectManager
+  static StoryEntity*           storyEntity;        //!< A reference to the current StoryEntity played
+  static Player*                player;             //!< A reference to the Player
+
+  static SkyBox*                skyBox;            //!< The SkyBox used in the current world.
+  static unsigned int           resX;              //!< The X Resolution of the screen.
+  static unsigned int           resY;              //!< The Y Resolution of the screen.
+  };
+
+#endif /* _STATE_H */
Index: branches/network/src/util/track/pilot_node.cc
===================================================================
--- branches/network/src/util/track/pilot_node.cc	(revision 6636)
+++ branches/network/src/util/track/pilot_node.cc	(revision 6636)
@@ -0,0 +1,126 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+
+   bensch: added comments
+*/
+
+
+#include "pilot_node.h"
+#include "event_handler.h"
+#include "event.h"
+
+using namespace std;
+
+/**
+ *  standard constructor
+*/
+PilotNode::PilotNode ()
+{
+   this->setClassID(CL_PILOT_PARENT, "PilotNode");
+   this->setName("PilotNode");
+
+   travelSpeed = 30.0;
+   velocity = new Vector();
+   bUp = bDown = bLeft = bRight = false;
+}
+
+/**
+ *  standard deconstructor
+*/
+PilotNode::~PilotNode ()
+{
+
+}
+
+/**
+  *  ticks the node
+  * @param time the time about whitch to tick                                           \
+*/
+void PilotNode::tick(float time)
+{
+  this->move(time);
+}
+
+
+/**
+ *  action if player moves
+ * @param time the timeslice since the last frame
+*/
+void PilotNode::move (float time)
+{
+  Vector accel(0.0, 0.0, 0.0);
+  /* FIXME: calculating the direction and orthDirection every timeSlice is redundant! save it somewhere */
+  /* calculate the direction in which the craft is heading  */
+  //Vector direction (1.0, 0.0, 0.0);
+  //direction = this->absDirection.apply (direction);
+  //Vector orthDirection (0.0, 0.0, 1.0);
+  //orthDirection = orthDirection.cross (direction);
+
+   Quaternion q = this->getAbsDir();
+   Vector direction(1,0,0);
+   direction = q.apply(direction);
+
+
+
+   Vector orthDirection(0,0,1);
+   orthDirection = q.apply(orthDirection);
+
+   if( this->bUp)
+     accel = accel+(direction*acceleration);
+   if( this->bDown)
+     accel = accel -(direction*acceleration);
+   if( this->bLeft)
+     accel = accel - (orthDirection*acceleration);
+   if( this->bRight)
+     accel = accel + (orthDirection*acceleration);
+
+   Vector move = accel * time;
+   this->shiftCoor (move);
+
+   Quaternion q1(-M_PI/4 * this->roll/40000.0, Vector(0,0,1));
+   Quaternion q2(-M_PI/4 * this->pitch/30000.0, Vector(0,1,0));
+   //this->shiftDir(q1*q2);
+   this->shiftDir(q1*q2);
+}
+
+/**
+ *  handles events
+ * @param event the event that occured
+*/
+void PilotNode::process( const Event &event)
+{
+  if( event.type == KeyMapper::PEV_UP)
+    {
+      this->bUp = event.bPressed;
+    }
+  else if( event.type == KeyMapper::PEV_DOWN)
+    {
+      this->bDown = event.bPressed;
+    }
+  else if( event.type == KeyMapper::PEV_RIGHT)
+    {
+      this->bRight= event.bPressed;
+    }
+  else if( event.type == KeyMapper::PEV_LEFT)
+    {
+      this->bLeft = event.bPressed;
+    }
+  else if( event.type == EV_MOUSE_MOTION)
+    {
+      this->pitch = event.x - 400;
+      this->roll = event.y - 300;
+    }
+}
Index: branches/network/src/util/track/pilot_node.h
===================================================================
--- branches/network/src/util/track/pilot_node.h	(revision 6636)
+++ branches/network/src/util/track/pilot_node.h	(revision 6636)
@@ -0,0 +1,45 @@
+/*!
+ * @file pilot_node.h
+  *  Definition of a PilotNode
+*/
+
+
+#ifndef _PILOT_NODE_H
+#define _PILOT_NODE_H
+
+#include "world_entity.h"
+#include "event_listener.h"
+
+class Event;
+
+//! The PilotNode is a node that enables the is driven by the Mouse
+class PilotNode : public WorldEntity, public EventListener {
+
+ public:
+  PilotNode ();
+  virtual ~PilotNode ();
+
+  virtual void tick(float time);
+
+  virtual void process(const Event &event);
+
+ private:
+  void move(float time);
+
+ private:
+  bool        bUp;            //!< up button pressed.
+  bool        bDown;          //!< down button pressed.
+  bool        bLeft;          //!< left button pressed.
+  bool        bRight;         //!< right button pressed.
+
+  int         pitch;          //!< the pitch of the node
+  int         roll;           //!< the roll of the node
+
+  Vector*     velocity;       //!< the velocity of the player.
+  float       travelSpeed;    //!< the current speed of the player (to make soft movement)
+  float       acceleration;   //!< the acceleration of the player.
+
+
+};
+
+#endif /* _PILOT_NODE_H */
Index: branches/network/src/util/track/track_manager.cc
===================================================================
--- branches/network/src/util/track/track_manager.cc	(revision 6636)
+++ branches/network/src/util/track/track_manager.cc	(revision 6636)
@@ -0,0 +1,1205 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_TRACK_MANAGER
+
+#include "track_manager.h"
+
+#include "base_object.h"
+#include "load_param.h"
+#include "p_node.h"
+#include "track_node.h"
+#include "stdincl.h"
+#include "list.h"
+#include "text.h"
+#include "t_animation.h"
+
+
+#include "parser/tinyxml/tinyxml.h"
+#include "substring.h"
+
+#include <stdarg.h>
+
+using namespace std;
+
+/**
+ *  initializes a TrackElement (sets the default values)
+*/
+TrackElement::TrackElement()
+{
+  this->setClassID(CL_TRACK_ELEMENT, "TrackElement");
+
+  this->isFresh = true;
+  this->isHotPoint = false;
+  this->isSavePoint = false;
+  this->isFork = false;
+  this->isJoined = false;
+  this->mainJoin = false;
+  this->ID = -1;
+  this->startingTime = 0;
+  this->duration = TMAN_DEFAULT_DURATION;
+  this->endTime = 1;
+  this->jumpTime = 0;
+  this->width = TMAN_DEFAULT_WIDTH;
+  this->nodeCount = 0;
+  this->curve = NULL;
+  this->childCount = 0;
+  this->children = NULL;
+
+  this->history = NULL;
+
+  this->subject = NULL;
+  this->condFunc = &TrackElement::random;
+}
+
+/**
+  *  destroys all alocated memory)
+    @todo eventually when deleting a TrackElement you would not like to delete all its preceding TrackElements
+*/
+TrackElement::~TrackElement()
+{
+  // deleting the Curve
+  delete this->curve;
+
+  // deleting all the Children of this TrackNode.
+  if ((!this->isJoined &&this->childCount > 0)
+      || (this->isJoined && this->mainJoin)) // only if this is the MainJoin.
+    {
+      tIterator<TrackElement>* iterator = this->children->getIterator();
+      TrackElement* enumElem = iterator->firstElement();
+      while (enumElem)
+        {
+          delete enumElem;
+          enumElem = iterator->nextElement();
+        }
+      delete iterator;
+      delete this->children;
+    }
+}
+
+/**
+ * Searches through all the TrackElements for trackID.
+ * @param trackID The ID to search for.
+ * @returns The TrackElement if Found, NULL otherwise.
+*/
+TrackElement* TrackElement::findByID(unsigned int trackID)
+{
+  // return if Found.
+  if (this->ID == trackID)
+    return this;
+  // search all children
+  if (this->childCount > 0)
+    {
+      tIterator<TrackElement>* iterator = this->children->getIterator();
+      TrackElement* enumElem = iterator->firstElement();
+      TrackElement* tmpElem = NULL;
+      while (enumElem)
+        {
+          if ((tmpElem = enumElem->findByID(trackID)) != NULL)
+            return tmpElem;
+          enumElem = iterator->nextElement();
+        }
+      delete iterator;
+    }
+  // if not found
+  return NULL;
+}
+
+
+/**
+ *  Searches through all the TrackElements for a trackName
+ * @param trackName The name to search for.
+ * @returns The TrackElement if Found, NULL otherwise.
+*/
+TrackElement* TrackElement::findByName(const char* trackName)
+{
+  // return if Found.
+  if (this->getName() && !strcmp(this->getName(), trackName))
+    return this;
+  // search all children
+  if (this->childCount > 0)
+    {
+      tIterator<TrackElement>* iterator = this->children->getIterator();
+      TrackElement* enumElem = iterator->firstElement();
+      TrackElement* tmpElem;
+      while (enumElem)
+        {
+          if ((tmpElem = enumElem->findByName(trackName)))
+            return tmpElem;
+          enumElem = iterator->nextElement();
+        }
+      delete iterator;
+    }
+  // if not found
+  return NULL;
+}
+
+/**
+ *  checks if there are any BackLoops in the Track
+ * @returns true if NO loop was found, false Otherwise
+   You actually have to act on false!!
+*/
+bool TrackElement::backLoopCheck() const
+{
+  tList<const TrackElement>* trackList = new tList<const TrackElement>;
+
+  this->backLoopCheckAtomic(trackList);
+
+  delete trackList;
+  // only returns if everything worked out
+  return true;
+}
+
+/**
+ *  checks if there are any BackLoops in the Track.
+ * @param trackList A list of stored tracks, to search in.
+ * @returns true if NO loop was found, false Otherwise
+   You actually have to act on false!!
+*/
+bool TrackElement::backLoopCheckAtomic(tList<const TrackElement>* trackList) const
+{
+  if (trackList->inList(this))
+    return false;
+
+  trackList->add(this);
+
+  if (this->children)
+    {
+      tIterator<TrackElement>* iterator = this->children->getIterator();
+      TrackElement* enumElem = iterator->firstElement();
+      while (enumElem)
+        {
+          if (!enumElem->backLoopCheckAtomic(trackList))
+            return false;
+        }
+      delete iterator;
+    }
+  return true;
+}
+
+
+/**
+ * @param childCount which child to return
+ * @returns the n-the children (starting at 0).
+   Be aware, that when the trackElement has no Children, NULL will be returned
+*/
+TrackElement* TrackElement::getChild(unsigned int childCount) const
+{
+  // if the the trackElement has no children return NULL.
+  if (this->childCount == 0)
+    return NULL;
+  // we cannot return the childCount+m's Child, so we return the last.
+  if (childCount > this->childCount)
+    childCount = this->childCount;
+
+  tIterator<TrackElement>* iterator = this->children->getIterator();
+  TrackElement* enumElem = iterator->firstElement();
+  for (unsigned int i = 0; i < childCount; i++)
+    enumElem = iterator->nextElement();
+  delete iterator;
+  return enumElem;
+}
+
+/**
+ *  prints out debug information about this TrackElement
+*/
+void TrackElement::debug() const
+{
+  PRINT(0)("--== TrackElement:%i ==--", this->ID);
+  if(this->getName())
+    PRINT(0)("--++Name: %s++--", this->getName());
+  if(this->isFresh)
+    PRINT(0)("  -- has not jet eddited in any way --\n");
+  PRINT(0)("\n   TimeTable: startingTime=%f; endTime=%f; duration=%f; jumpTime=%f\n", this->startingTime, this->endTime, this->duration, this->jumpTime);
+  PRINT(0)("   consists of %d Points\n", this->nodeCount);
+  if (this->childCount == 0)
+    PRINT(0)("   has no child\n");
+  else if (this->childCount == 1)
+    PRINT(0)("   has 1 child: =%d=\n", this->getChild(0)->ID);
+  else if (this->childCount > 1)
+    {
+      PRINT(0)("   has %d children: ", this->childCount);
+      //TrackElement* enumElem = this->children->enumerate();
+      tIterator<TrackElement>* iterator = this->children->getIterator();
+      TrackElement* enumElem = iterator->firstElement();
+      while (enumElem)
+        {
+          PRINT(0)("=%d= ", enumElem->ID);
+          enumElem = iterator->nextElement();
+        }
+      delete iterator;
+      PRINT(0)("\n");
+    }
+
+  if(this->isHotPoint)
+    PRINT(0)("   is a special Point:\n");
+  if(this->isSavePoint)
+    PRINT(0)("    is a SavePoint\n");
+  if(this->isFork)
+    {
+      PRINT(0)("    is A Fork with with %d children.\n", this->childCount);
+    }
+  if(this->isJoined)
+    PRINT(0)("   is Joined at the End\n");
+
+  if(!this->backLoopCheck()) /* this should not happen */
+    PRINT(2)(" THERE IS A BACKLOOP TO THIS ELEMENT\n");
+}
+
+/**
+ *  CONDITION that chooses the first child for the decision (static)
+ * @param nothing Nothing in this function
+ * @returns the chosen child
+*/
+int TrackElement::lowest(const void* nothing) const
+{
+  return 0;
+}
+
+/**
+ *  CONDITION that chooses the last child for the decision (static)
+ * @param nothing Nothing in this function
+ * @returns the chosen child
+*/
+int TrackElement::highest(const void* nothing) const
+{
+  return this->childCount-1;
+}
+
+/**
+ *  CONDITION that chooses a random child for the decision (static)
+ * @param nothing Nothing in this function
+ * @returns the chosen child
+*/
+int TrackElement::random(const void* nothing) const
+{
+  int i = (int)floor ((float)rand()/(float)RAND_MAX * (float)this->childCount);
+  if (i >= this->childCount)
+    return this->childCount-1;
+  else
+    return i;
+}
+
+/**
+ *  CONDITION that chooses child 0, if the node(probably Player)
+   is left of its parent (z<0)) and 1/right otherwise.
+ * @param node The node to act upon.
+ * @returns the chosen child
+*/
+int TrackElement::leftRight(const void* node) const
+{
+  PNode* tmpNode = (PNode*)node;
+
+  if (tmpNode->getRelCoor().z < 0)
+    return 0;
+  else
+    return 1;
+}
+
+
+/**
+ *  CONDITION that chooses the child, that has the nearest distance to the node (probably player).
+ * @param node The node to act upon.
+ * @returns the chosen child
+
+   This is rather dangerous, because one must carefully set the points on the curve.
+   The best Way is to set the nodes as wide away of each other as possible,
+   but take into consideration, that if the nodes are to far from a center node, the center will be chosen.
+   (play with this!!).
+*/
+int TrackElement::nearest(const void* node) const
+{
+  PNode* tmpNode = (PNode*)node;
+
+  Vector nodeRelCoord = tmpNode->getRelCoor();
+  float minDist = 100000000;
+  int childNumber = 0;
+  int i = 0;
+
+  //TrackElement* enumElem = this->children->enumerate();
+  tIterator<TrackElement>* iterator = this->children->getIterator();
+  TrackElement* enumElem = iterator->firstElement();
+  while (enumElem)
+    {
+      float dist = (nodeRelCoord - enumElem->curve->getNode(4)).len();
+      if (dist < minDist)
+        {
+          minDist = dist;
+          childNumber = i;
+        }
+      i++;
+      enumElem = iterator->nextElement();
+    }
+  delete iterator;
+
+  PRINTF(4)("PathDecision with nearest algorithm: %d\n", childNumber);
+  return childNumber;
+}
+
+
+////////////////////////
+///// TRACKMANAGER /////
+////////////////////////
+/**
+ *  standard constructor
+
+*/
+TrackManager::TrackManager()
+{
+  this->setClassID(CL_TRACK_MANAGER, "TrackManager");
+  this->setName("TrackManager");
+
+  TrackManager::singletonRef = this; // do this because otherwise the TrackNode cannot get The instance of the TrackManager
+
+  PRINTF(3)("Initializing the TrackManager\n");
+  // setting up the First TrackElement
+  this->firstTrackElem = new TrackElement();
+  this->firstTrackElem->ID = 1;
+  this->firstTrackElem->setName("root");
+
+  this->currentTrackElem = firstTrackElem;
+
+  this->curveType = CURVE_BEZIER;
+  this->localTime = 0;
+  this->maxTime = 0;
+  this->trackElemCount = 1;
+
+  this->trackNode = new TrackNode();
+  this->setBindSlave(this->trackNode);
+  // initializing the Text
+  this->trackText = new Text("fonts/earth.ttf", 30);
+  this->trackText->setAlignment(E2D_ALIGN_SCREEN_CENTER);
+  // initializing the Animation for the Text.
+  this->textAnimation = new tAnimation<Text>(this->trackText, &Text::setBlending);
+  this->textAnimation->addKeyFrame(1.0, 3.0, ANIM_NEG_EXP);
+  this->textAnimation->addKeyFrame(0.0, .001);
+  this->textAnimation->setInfinity(ANIM_INF_CONSTANT);
+}
+
+
+/**
+ *  loads a trackElement from a TiXmlElement
+ * @param root the TiXmlElement to load the Data from
+*/
+void TrackManager::loadParams(const TiXmlElement* root)
+{
+  double x, y, z, d;
+
+  LOAD_PARAM_START_CYCLE(root, element);
+  {
+
+    LoadParam_CYCLE(element, "WorkOn", this, TrackManager, workOnS)
+        .describe("Selects a TrackElement (by name) to work on");
+
+    LoadParam_CYCLE(element, "Point", this, TrackManager, addPoint)
+        .describe("Adds a new Point to the currently selected TrackElement");
+
+    LoadParam_CYCLE(element, "Duration", this, TrackManager, setDuration)
+        .describe("Sets the Duration of the currently selected TrackElement");
+
+    LoadParam_CYCLE(element, "HotPoint", this, TrackManager, addHotPoint)
+        .describe("Sets a new Point that acts as a hot point. meaning, the curve will flow through this Point");
+
+    LoadParam_CYCLE(element, "SavePoint", this, TrackManager, setSavePointS)
+        .describe("Sets the current selected Point to a Savepoint, meaning that the curve will be ended and a new one starts, and that one starts again from this point on");
+
+    LoadParam_CYCLE(element, "Fork", this, TrackManager, forkS)
+        .describe("Forks the Path into multiple forked Path names seperated by ','");
+
+    LoadParam_CYCLE(element, "Join", this, TrackManager, joinS)
+        .describe("Joins multiple joining Path names seperated by ','");
+
+      /*
+    if( !strcmp( element->Value(), "Fork"))
+    {
+    container = element->FirstChild();
+    if( container->ToText())
+        {
+        assert( container->Value() != NULL);
+        PRINTF(4)("Loaded Fork: %s\n", container->Value());
+        forkS(container->Value());
+        }
+        }
+      */
+      /*
+        if( !strcmp( element->Value(), "Join"))
+        {
+        container = element->FirstChild();
+        if( container->ToText())
+        {
+        assert( container->Value() != NULL);
+        PRINTF0("Loaded Join: %s\n", container->Value());
+        joinS(container->Value());
+        }
+        }
+      */
+  }
+  LOAD_PARAM_END_CYCLE(element);
+}
+
+/**
+ *  standard destructor
+*/
+TrackManager::~TrackManager()
+{
+  PRINTF(3)("Destruct TrackManager\n");
+
+  PRINTF(4)("Deleting all the TrackElements\n");
+  delete this->firstTrackElem;
+
+  delete this->trackText;
+  // the tracknode should be deleted here, but is deleted by pNode: -> null_parent
+
+  // we do not have a TrackManager anymore
+  TrackManager::singletonRef = NULL;
+}
+
+//! Singleton Reference to TrackManager
+TrackManager* TrackManager::singletonRef = NULL;
+
+// INITIALIZE //
+/**
+ *  reserves Space for childCount children
+ * @param childCount The Count of children to make space for.
+ * @param trackElem The TrackElement to appy this to. (if NULL chose this->currentTrackElement)
+*/
+void TrackManager::initChildren(unsigned int childCount, TrackElement* trackElem)
+{
+  if (!trackElem)
+    trackElem = this->currentTrackElem;
+
+  trackElem->childCount = childCount;
+  trackElem->mainJoin = true;  // this tells join, that this one is the Main Join, if it tries to join multiple Tracks
+  trackElem->children =  new tList<TrackElement>();
+  for (int i = 0; i < childCount; i++)
+    {
+      // create a new Element
+      TrackElement* newElem = new TrackElement();
+      // setting up the new ID
+      newElem->ID = ++trackElemCount;
+      // setting up the Time
+      newElem->startingTime = trackElem->endTime + trackElem->jumpTime;
+      // adds the conection Point
+      this->addPointV(trackElem->curve->getNode(trackElem->curve->getNodeCount()),
+                     newElem);
+      // add the new child to the childList.
+      trackElem->children->add(newElem);
+    }
+
+  // setting the Name of the new TrackElement to the name of the last one + _childI
+
+  if (trackElem->getName())
+    {
+      for (int i = 0; i < trackElem->childCount; i++)
+      {
+        char* childName = new char[strlen(trackElem->getName())+10];
+        sprintf(childName, "%s_child%d", trackElem->getName(), i);
+        trackElem->getChild(i)->setName(childName);
+      }
+    }
+  // select the first Child to work on.
+  this->currentTrackElem = trackElem->getChild(0);
+}
+
+
+/**
+ *  Sets the trackID we are working on.
+ * @param trackID the trackID we are working on
+*/
+void TrackManager::workOn(unsigned int trackID)
+{
+  TrackElement* tmpElem = this->firstTrackElem->findByID(trackID);
+  if (tmpElem)
+    this->currentTrackElem = tmpElem;
+  else
+    PRINTF(2)("TrackElement %d not Found, leaving unchanged\n", trackID);
+  PRINTF(4)("now Working on %d\n", this->currentTrackElem->ID);
+}
+
+/**
+ *  Sets the TrackElement to work on
+ * @param trackName the Name of the Track to work on
+*/
+void TrackManager::workOnS(const char* trackName)
+{
+  TrackElement* tmpElem = this->firstTrackElem->findByName(trackName);
+  if (tmpElem)
+    this->currentTrackElem = tmpElem;
+  else
+    PRINTF(2)("TrackElement %s not Found, leaving unchanged\n", trackName);
+  PRINTF(4)("now Working on %d\n", this->currentTrackElem->ID);
+}
+
+/**
+ *  Sets the Type of the Curve
+ * @param curveType The Type to set
+ * @param trackElem the TrackElement that should get a new Curve.
+
+ *  this will possibly get obsolete during the process.
+*/
+void TrackManager::setCurveType(CurveType curveType, TrackElement* trackElem)
+{
+  if (!trackElem->isFresh)
+    {
+      PRINTF(2)("It is not possible to change the type of a Curve after you have have appended some points to it\n");
+      return;
+    }
+  this->curveType = curveType;
+  switch (curveType)
+    {
+    case CURVE_BEZIER:
+      trackElem->curve = new BezierCurve();
+      break;
+    }
+}
+
+/**
+ * @param duration the duration of the TrackElement
+   \see void TrackManager::setDuration(float duration, TrackElement* trackElem)
+*/
+void TrackManager::setDuration(float duration)
+{
+  this->setDuration(duration, NULL);
+}
+
+/**
+ *  Sets the duration of the current path in seconds.
+ * @param duration The duration in seconds.
+ * @param trackElem The TrackElement to apply this to.
+*/
+void TrackManager::setDuration(float duration, TrackElement* trackElem)
+{
+  if (!trackElem)
+    trackElem = this->currentTrackElem;
+
+  trackElem->duration = duration;
+  trackElem->endTime = trackElem->startingTime + duration;
+}
+
+/**
+ *  adds a point to trackElem
+ * @param x x coord
+ * @param y y coord
+ * @param z z coord
+ * @param trackElem The TrackElement to add the Point to
+*/
+void TrackManager::addPoint(float x, float y, float z)
+{
+  this->addPointV(Vector(x,y,z));
+}
+
+/**
+ *  adds a point to trackElem
+ * @param newPoint The point to add.
+ * @param trackElem The TrackElement to add the Point to
+*/
+void TrackManager::addPointV(Vector newPoint, TrackElement* trackElem)
+{
+  if (!trackElem)
+    trackElem = this->currentTrackElem;
+
+  if (trackElem->isFresh)
+    {
+      this->setCurveType(TMAN_DEFAULT_CURVETYPE, trackElem);
+      trackElem->isFresh = false;
+    }
+  trackElem->curve->addNode(newPoint);
+  trackElem->nodeCount++;
+}
+
+/**
+ *  adds a new Hot Point
+ * @param x: the x coordinate of the hotpoint
+ * @param y: the y coordinate of the hotpoint
+ * @param z: the z coordinate of the hotpoint
+   \see int TrackManager::addHotPointV(Vector newPoint, TrackElement* trackElem)
+*/
+void TrackManager::addHotPoint(float x, float y, float z)
+{
+  this->addHotPointV(Vector(x, y, z));
+}
+
+/**
+ *  adds save/splitpoint.
+ * @param newPoint The point to add.
+ * @param trackElem if supplied it will add a hotpoint on this TrackElement
+ * @returns A Pointer to a newly appended Curve
+*/
+int TrackManager::addHotPointV(Vector newPoint, TrackElement* trackElem)
+{
+  if (!trackElem)
+    trackElem = this->currentTrackElem;
+
+  PRINTF(4)("setting up a HotPoint\n");
+  if (trackElem->isFresh)
+    {
+      trackElem->isFresh = false;
+    }
+
+  // @todo HotPoint Handling.
+  trackElem->curve->addNode(newPoint);
+  trackElem->nodeCount++;
+  this->initChildren(1, trackElem);
+}
+
+/**
+   @todo this must be better
+*/
+void TrackManager::setSavePointS(const char* nextElementName)
+{
+  this->setSavePoint(NULL);
+  if (strcmp(nextElementName, ""))
+    this->firstTrackElem->findByID(this->trackElemCount)->setName(nextElementName);
+}
+
+/**
+ *  Sets the last HotPoint into a savePoint.
+ * @param trackElem The TrackElement to appy this to. (if NULL chose this->currentTrackElement)
+ * @returns A Pointer to a newly appended Curve
+
+   If no HotPoint was defined the last added Point will be rendered into a savePoint. \n
+   If the HotPoint was defined as a fork the Point will \b not be set into a savePoint.
+*/
+void TrackManager::setSavePoint(TrackElement* trackElem)
+{
+  if (!trackElem)
+    trackElem = this->currentTrackElem;
+
+  PRINTF(4)("setting up a SavePoint.\n");
+  if (trackElem->isFork || trackElem->isSavePoint)
+    {
+      PRINTF(2)("%d is already finished \n", trackElem->ID);
+      return;
+    }
+  trackElem->isSavePoint = true;
+  trackElem->isHotPoint = true;
+
+  this->initChildren(1, trackElem);
+}
+
+/**
+ *  adds some interessting non-linear movments through the level.
+ * @param count The Count of children the fork will produce
+
+   If no HotPoint was defined the last added Point will be rendered into a fork. \n
+   If the HotPoint was defined as a savePoint the Point will \b not be set into a fork.
+*/
+void TrackManager::fork(unsigned int count, ...)
+{
+  int* trackIDs = new int[count];
+  this->forkV(count, trackIDs, NULL);
+  va_list ID;
+  va_start (ID, count);
+  for(int i = 0; i < count; i++)
+    {
+      *va_arg (ID, int*) = trackIDs[i];
+    }
+  va_end(ID);
+  delete []trackIDs;
+}
+
+/**
+ * @param count how many children to produce
+ * @param ... the information on the children (these are the Stings of their names
+   \see TrackManager::fork(unsigned int count, ...)
+
+   does the same as fork, but has an array of strings as an input.
+*/
+void TrackManager::forkS(unsigned int count, ...)
+{
+  int* trackIDs = new int[count];
+  this->forkV(count, trackIDs, NULL);
+  va_list name;
+  va_start (name, count);
+  for(int i = 0; i < count; i++)
+    {
+      this->firstTrackElem->findByID(trackIDs[i])->setName(va_arg(name, const char*));
+    }
+  va_end(name);
+  delete []trackIDs;
+}
+
+/**
+   \see TrackManager::fork(unsigned int count, ...)
+*/
+void TrackManager::forkS(const char* forkString)
+{
+  SubString strings(forkString, ',');
+
+  int* trackIDs = new int[strings.getCount()];
+  this->forkV(strings.getCount(), trackIDs, NULL);
+
+  for(int i = 0; i < strings.getCount(); i++)
+    {
+      this->firstTrackElem->findByID(trackIDs[i])->setName(strings.getString(i));
+    }
+  delete []trackIDs;
+}
+
+/**
+ *  adds some interessting non-linear movments through the level.
+ * @param count The Count of childrens the current HotPoint will have.
+ * @param trackIDs A Pointer to an Array of ints which will hold the trackID's (the user will have to reserve space for this).
+ * @param trackNames the names for the tracks as a char-arrey-array
+ * @param trackElem The TrackElement to appy this to. (if NULL choose this->currentTrackElement)
+   \see TrackManager::fork(unsigned int count, ...)
+*/
+void TrackManager::forkV(unsigned int count, int* trackIDs, char** trackNames, TrackElement* trackElem)
+{
+  if (!trackElem)
+    trackElem = this->currentTrackElem;
+
+  PRINTF(4)("Forking with %d children\n", count);
+  if (trackElem->isSavePoint)
+    return;
+  trackElem->isFork = true;
+  trackElem->isHotPoint = true;
+  for(int i = 0; i < count; i++)
+    trackIDs[i]=this->trackElemCount+1+i;
+  this->initChildren(count, trackElem);
+}
+
+/**
+ *  decides under what condition a certain Path will be chosen.
+ * @param trackID the trackID to apply this to.
+ * @param cond the CONDITION of the decision
+ * @param subject the Subject that will be decided upon with CONDITION cond.
+*/
+void TrackManager::condition(unsigned int trackID, CONDITION cond, void* subject)
+{
+  this->condition(cond, subject, this->firstTrackElem->findByID(trackID));
+}
+
+/**
+ *  decides under what condition a certain Path will be chosen.
+ * @param cond the CONDITION of the decision
+ * @param subject the Subject that will be decided upon with CONDITION cond.
+ * @param trackElem The TrackElement to appy this to. (if NULL chose this->currentTrackElement)
+*/
+void TrackManager::condition(CONDITION cond, void* subject, TrackElement* trackElem)
+{
+  if (!trackElem)
+    trackElem = this->currentTrackElem;
+
+  if (!trackElem->isFork)
+    {
+      PRINTF(2)("%d is not a Fork, and no condition can be set in this case\n", trackElem->ID);
+      return;
+    }
+  else
+    {
+      switch (cond)
+        {
+        case LOWEST:
+          trackElem->condFunc = &TrackElement::lowest;
+          break;
+        case HIGHEST:
+          trackElem->condFunc = &TrackElement::highest;
+          break;
+        case RANDOM:
+          trackElem->condFunc = &TrackElement::random;
+          break;
+        case LEFTRIGHT:
+          trackElem->condFunc = &TrackElement::leftRight;
+          break;
+        case NEAREST:
+          trackElem->condFunc = &TrackElement::nearest;
+          break;
+        case ENEMYKILLED:
+          break;
+        }
+      trackElem->subject=subject;
+    }
+}
+
+/**
+ *  joins some tracks together again.
+ * @param count The count of Paths to join.
+
+   Join will set the localTime to the longest time a Path has to get to this Point. \n
+   Join will join all curves to the first curve, meaning that all the tangents will be matched.
+*/
+void TrackManager::join(unsigned int count, ...)
+{
+  int* trackIDs = new int [count];
+  va_list ID;
+  va_start (ID, count);
+  for(int i = 0; i < count; i++)
+    {
+      trackIDs[i] = va_arg (ID, int);
+    }
+  va_end(ID);
+  this->joinV(count, trackIDs);
+  delete []trackIDs;
+}
+
+/**
+ *  Joins some Tracks together again.
+ * @param count The count of trackElements to join
+   \see void TrackManager::join(unsigned int count, ...)
+
+   The difference to void TrackManager::join(unsigned int count, ...) is, that this function takes
+   the Names of the TrackElements as inputs and not their ID
+*/
+void TrackManager::joinS(unsigned int count, ...)
+{
+  int* trackIDs = new int [count];
+  va_list NAME;
+  va_start (NAME, count);
+  for(int i = 0; i < count; i++)
+    {
+      const char* name = va_arg (NAME, char*);
+      TrackElement* tmpElem = this->firstTrackElem->findByName(name);
+      if (tmpElem)
+        trackIDs[i] = tmpElem->ID;
+      else
+        PRINTF(1)("Trying to join a Track, of which the name does not exist: %s\n", name);
+    }
+  va_end(NAME);
+  this->joinV(count, trackIDs);
+  delete []trackIDs;
+}
+
+/**
+   \see void TrackManager::join(unsigned int count, ...)
+*/
+void TrackManager::joinS(const char* joinString)
+{
+  SubString strings(joinString, ',');
+
+  int* trackIDs = new int[strings.getCount()];
+  this->joinV(strings.getCount(), trackIDs);
+
+  for(unsigned int i = 0; i < strings.getCount(); i++)
+    {
+      TrackElement* tmpElem = this->firstTrackElem->findByName(strings.getString(i));
+      if (tmpElem != NULL)
+        trackIDs[i] = tmpElem->ID;
+      else
+      {
+        PRINTF(1)("Trying to join a Track, of which the name does not exist: %s\n", strings.getString(i));
+        trackIDs[i] = -1;
+      }
+    }
+  this->joinV(strings.getCount(), trackIDs);
+  delete []trackIDs;
+}
+
+/**
+ *  joins some tracks together again.
+ * @param count The count of Paths to join.
+ * @param trackIDs an Array with the trackID's to join
+ *
+ * @see void TrackManager::join(unsigned int count, ...)
+*/
+void TrackManager::joinV(unsigned int count, int* trackIDs)
+{
+  TrackElement* tmpTrackElem;
+  TrackElement* tmpJoinElem;
+  for (unsigned int i = 0; i < count; i++)
+    if (!this->firstTrackElem->findByID(trackIDs[i]))
+      {
+        PRINTF(1)("Trying to Connect Paths that do not exist yet: %d\n Not Joining Anything\n", trackIDs[i]);
+        return;
+      }
+
+
+  PRINTF(3)("Joining %d tracks and merging to Track %d\n", count, trackIDs[0]);
+
+  // checking if there is a back-loop-connection and ERROR if it is.
+  tmpTrackElem = this->firstTrackElem->findByID(trackIDs[0]);
+  if (!tmpTrackElem->backLoopCheck())
+    {
+      PRINTF(2)("Backloop connection detected at joining trackElements\n -> TRACK WILL NOT BE JOINED\n");
+      return;
+    }
+
+  TrackElement* firstJoint =   this->firstTrackElem->findByID(trackIDs[0]);
+  float tmpLatestTime = firstJoint->endTime;
+
+  Vector tmpEndPoint = firstJoint->curve->getNode(firstJoint->curve->getNodeCount());
+  Vector tmpTangentPoint = firstJoint->curve->getNode(firstJoint->curve->getNodeCount()-1);
+  Vector tmpc2Point = firstJoint->curve->getNode(firstJoint->curve->getNodeCount()-2);
+  firstJoint->isJoined = true;
+  //  firstJoint->mainJoin = true;
+  if(!firstJoint->isHotPoint)
+    this->setSavePoint(firstJoint);
+  // Timing:
+  for (unsigned int i = 0; i < count; i++)
+    {
+      if(tmpJoinElem = this->firstTrackElem->findByID(trackIDs[i]))
+        {
+          if (tmpJoinElem->childCount == 0
+              && tmpJoinElem->endTime > tmpLatestTime)
+            tmpLatestTime = tmpJoinElem->endTime;
+        }
+    }
+  // time the main Join.
+  firstJoint->jumpTime = tmpLatestTime - firstJoint->endTime;
+
+  // Joining:
+  for (int i = 1; i < count; i++)
+    {
+      if( tmpJoinElem = this->firstTrackElem->findByID(trackIDs[i]))
+        {
+          if (tmpJoinElem->childCount > 0)
+            printf("!!This Curve has children, and as such will not be joined!!\n You can try joining other childless TrackElements to this one!");
+          else
+            {
+              this->addPointV(tmpc2Point, tmpJoinElem);
+              this->addPointV(tmpTangentPoint, tmpJoinElem);
+              this->addPointV(tmpEndPoint, tmpJoinElem);
+              // time all other Joins
+              tmpJoinElem->jumpTime = tmpLatestTime - tmpJoinElem->endTime;
+
+              //Copying Joint-Info
+              tmpJoinElem->children = firstJoint->children;
+              tmpJoinElem->childCount = firstJoint->childCount;
+              tmpJoinElem->isSavePoint = firstJoint->isSavePoint;
+              tmpJoinElem->isFork = firstJoint->isFork;
+
+              tmpJoinElem->isJoined = true;
+            }
+        }
+    }
+  if(firstJoint->children)
+    {
+      //TrackElement* enumElem = firstJoint->children->enumerate();
+      tIterator<TrackElement>* iterator = firstJoint->children->getIterator();
+      TrackElement* enumElem = iterator->firstElement();
+      while (enumElem)
+        {
+          PRINTF(5)("Setting startingTime of %d to %f.\n", enumElem->ID, tmpLatestTime);
+          enumElem->startingTime = tmpLatestTime;
+          enumElem->endTime = tmpLatestTime + enumElem->duration;
+
+          enumElem = iterator->nextElement();
+        }
+      delete iterator;
+    }
+}
+
+/**
+ *  finalizes the TrackSystem. after this it will not be editable anymore
+
+   @todo check for any inconsistencies, output errors
+*/
+void TrackManager::finalize()
+{
+  for (int i = 1; i<= trackElemCount ;i++)
+    {
+      TrackElement* tmpElem = this->firstTrackElem->findByID(i);
+      if( tmpElem->childCount > 0 && tmpElem->mainJoin)
+        {
+          tIterator<TrackElement>* iterator = tmpElem->children->getIterator();
+          TrackElement* enumElem = iterator->firstElement();
+          //TrackElement* enumElem = tmpElem->children->enumerate();
+          while (enumElem)
+            {
+
+              // c1-continuity
+              enumElem->curve->addNode(enumElem->curve->getNode(0) +
+                                                   ((enumElem->curve->getNode(0) -
+                                                    tmpElem->curve->getNode(tmpElem->curve->getNodeCount()-1))
+                                                    ),2);
+              enumElem->nodeCount++;
+              // c2-continuity
+              enumElem->curve->addNode((tmpElem->curve->getNode(tmpElem->curve->getNodeCount())-
+                                                    tmpElem->curve->getNode(tmpElem->curve->getNodeCount()-1)) * 4 +
+                                                   tmpElem->curve->getNode(tmpElem->curve->getNodeCount()-2), 3);
+              enumElem->nodeCount++;
+              PRINTF(5)("accelerations: %d-in: count: %d, %f, %f, %f\n                  %d-out: count: %d %f, %f, %f\n",
+                     tmpElem->ID, tmpElem->nodeCount,
+                     tmpElem->curve->calcAcc(0.999).x, tmpElem->curve->calcAcc(0.999).y, tmpElem->curve->calcAcc(0.999).z,
+                     enumElem->ID, enumElem->nodeCount,
+                     enumElem->curve->calcAcc(0).x, enumElem->curve->calcAcc(0).y, enumElem->curve->calcAcc(0).z);
+
+              enumElem = iterator->nextElement();
+            }
+          delete iterator;
+        }
+    }
+  for (int i = 1; i <= trackElemCount;i++)
+    if (this->firstTrackElem->findByID(i)->endTime > this->maxTime)
+      this->maxTime = this->firstTrackElem->findByID(i)->endTime; // very bad implemented :/
+}
+
+
+// RUNTIME //
+
+/**
+ *  calculates the Position for the localTime of the Track.
+ * @returns the calculated Position
+*/
+Vector TrackManager::calcPos() const
+{
+  return this->currentTrackElem->curve->calcPos((this->localTime-this->currentTrackElem->startingTime)/this->currentTrackElem->duration);
+}
+
+/**
+ *  calculates the Rotation for the localTime of the Track.
+ * @returns the calculated Rotation
+*/
+Vector TrackManager::calcDir() const
+{
+  return this->currentTrackElem->curve->calcDir((this->localTime - this->currentTrackElem->startingTime)/this->currentTrackElem->duration);
+}
+
+/**
+ * @returns the current Width of the track
+*/
+float TrackManager::getWidth() const
+{
+  return this->currentTrackElem->width;
+}
+
+/**
+ *  Advances the local-time of the Track around dt
+ * @param dt The time about which to advance.
+
+   This function also checks, if the TrackElement has to be changed.
+*/
+void TrackManager::tick(float dt)
+{
+  PRINTF(4)("CurrentTrackID: %d, LocalTime is: %f, timestep is: %f\n", this->currentTrackElem->ID, this->localTime, dt);
+  if (this->localTime <= this->firstTrackElem->duration)
+    this->jumpTo(this->localTime);
+  if (this->localTime <= this->maxTime)
+    this->localTime += dt;
+  if (this->localTime > this->currentTrackElem->endTime
+      && this->currentTrackElem->children)
+    {
+      if (this->currentTrackElem->jumpTime != 0.0)
+        this->jumpTo(this->localTime + this->currentTrackElem->jumpTime);
+      // jump to the next TrackElement and also set the history of the new Element to the old one.
+      TrackElement* tmpHistoryElem = this->currentTrackElem;
+      this->currentTrackElem = this->currentTrackElem->getChild(this->choosePath(this->currentTrackElem));
+      this->currentTrackElem->history = tmpHistoryElem;
+      if (this->currentTrackElem->getName())
+        {
+          this->trackText->setText(this->currentTrackElem->getName());
+          this->textAnimation->replay();
+        }
+    }
+  if (this->bindSlave)
+    {
+      Vector tmp = this->calcPos();
+      Quaternion quat = Quaternion(this->calcDir(), Vector(this->currentTrackElem->curve->calcAcc((localTime-this->currentTrackElem->startingTime)/this->currentTrackElem->duration).x,1,this->currentTrackElem->curve->calcAcc((localTime-this->currentTrackElem->startingTime)/this->currentTrackElem->duration).z));
+
+      Vector v(0.0, 1.0, 0.0);
+      Quaternion q(-PI/2, v);
+      quat = quat * q;
+
+      this->bindSlave->setAbsCoor(tmp);
+      this->bindSlave->setAbsDir(quat);
+    }
+}
+
+/**
+ *  Jumps to a certain point on the Track.
+ * @param time The time on the Track to jump to.
+
+   This should be used to Jump backwards on a Track, because moving forward means to change between the Path. (it then tries to choose the default.)
+   Max is trackLengthMax.
+*/
+void TrackManager::jumpTo(float time)
+{
+  if (time == 0)
+    {
+      this->currentTrackElem = this->firstTrackElem;
+      if (this->currentTrackElem->getName())
+        {
+          this->trackText->setText(this->currentTrackElem->getName());
+          this->textAnimation->play();
+        }
+    }
+  this->localTime = time;
+}
+
+/**
+ *  a Function that decides which Path we should follow.
+ * @param trackElem The Path to choose.
+
+*/
+int TrackManager::choosePath(TrackElement* trackElem)
+{
+  return (trackElem->*(trackElem->condFunc))(trackElem->subject);
+}
+
+/**
+ *  Sets the PNode, that should be moved along the Tack
+ * @param bindSlave the PNode to set
+*/
+void TrackManager::setBindSlave(PNode* bindSlave)
+{
+  this->bindSlave = bindSlave;
+}
+
+/**
+ * @returns the main TrackNode
+*/
+PNode* TrackManager::getTrackNode()
+{
+  return this->trackNode;
+}
+
+// DEBUG //
+
+/**
+ *  Imports a model of the Graph into the OpenGL-environment.
+ * @param dt The Iterator used in seconds for Painting the Graph.
+
+   This is for testing facility only. Do this if you want to see the Path inside the Level.
+   eventually this will all be packed into a gl-list.
+*/
+void TrackManager::drawGraph(float dt) const
+{
+  for (int i = 1; i <= trackElemCount; i++)
+    {
+      glBegin(GL_LINE_STRIP);
+      TrackElement* tmpElem = this->firstTrackElem->findByID(i);
+      if (tmpElem->curve)
+        for(float f = 0.0; f < 1.0; f+=dt)
+          {
+            //      printf("%f, %f, %f\n",trackManager->calcPos().x, trackManager->calcPos().y, trackManager->calcPos().z);
+            Vector tmpVector = tmpElem->curve->calcPos(f);
+            glVertex3f(tmpVector.x, tmpVector.y, tmpVector.z);
+          }
+      glEnd();
+    }
+}
+
+/**
+ *  outputs debug information about the trackManager
+ * @param level how much debug
+*/
+void TrackManager::debug(unsigned int level) const
+{
+  PRINT(0)("=========================================\n");
+  PRINT(0)("= CLASS TRACKMANAGER::debug information =\n");
+  PRINT(0)("=========================================\n");
+  //  PRINT(0)("Status is: %
+  PRINT(0)(" Consists of %d elements\n", this->trackElemCount);
+  PRINT(0)(" localTime is: %f\n", this->localTime);
+  if (level >= 2)
+    {
+      for (int i = 1; i <= trackElemCount; i++)
+        {
+          TrackElement* tmpElem = this->firstTrackElem->findByID(i);
+          tmpElem->debug();
+        }
+    }
+  PRINT(0)("-----------------------------------------\n");
+}
Index: branches/network/src/util/track/track_manager.h
===================================================================
--- branches/network/src/util/track/track_manager.h	(revision 6636)
+++ branches/network/src/util/track/track_manager.h	(revision 6636)
@@ -0,0 +1,206 @@
+/*!
+ * @file track_manager.h
+ *  manages all tracks defined in the world and the path the player takes
+ *
+ * it is a container for all tracks and all track-nodes. it manages the movement of
+ * the track helper-parent (that drives the player). it is responsable for calculating
+ * smooth curves etc.
+*/
+
+
+#ifndef _TRACK_MANAGER_H
+#define _TRACK_MANAGER_H
+
+#include "curve.h"
+#include "base_object.h"
+
+#ifndef NULL
+#define NULL   0  //!< NULL
+#endif
+
+// Forward Definition
+class PNode;
+class Text;
+class TiXmlElement;
+template<class T> class tAnimation;
+template<class T> class tList;
+
+// Static Definitions
+
+//! The default Curve-Type to set for the whole path (if not chosen otherwise).
+#define     TMAN_DEFAULT_CURVETYPE    CURVE_BEZIER
+//! A default value for the duration for each TrackElement
+#define     TMAN_DEFAULT_DURATION     10
+//! A default width for the width of a TrackElement
+#define     TMAN_DEFAULT_WIDTH        10
+
+//! A Graph-Element, that holds the curve-structure of a Level.
+/**
+   A TrackElement is used, to define the structure of the Track itself.
+   It is a graph and not a tree, because paths can fork and join again.
+*/
+class TrackElement : public BaseObject
+{
+ public:
+  TrackElement();
+  ~TrackElement();
+
+  TrackElement* findByID(unsigned int trackID);
+  TrackElement* findByName(const char* trackName);
+  bool backLoopCheck() const;
+
+  TrackElement* getChild(unsigned int childNumber) const;
+
+ private:
+  bool backLoopCheckAtomic(tList<const TrackElement>* trackList) const;
+
+ public:
+  // atributes
+  bool                  isFresh;              //!< If no Points where added until now
+  bool                  isHotPoint;           //!< If the first node is a specialPoint;
+  bool                  isSavePoint;          //!< If the first node is a savePoint
+  bool                  isFork;               //!< If the first node is a Fork
+  bool                  isJoined;             //!< If the End of the Curve is joined.
+  bool                  mainJoin;             //!< If the End of the Curve is joined, and this is the one Curve the others join to.
+  int                   ID;                   //!< The ID of this TrackElement
+  float                 startingTime;         //!< The time at which this Track begins.
+  float                 duration;             //!< The time used to cross this TrackElement (curve).
+  float                 endTime;              //!< The time at which this Track ends.
+  float                 jumpTime;             //!< The Time this Track has to jump to its preceding Track (only >0 if Track isJoined==true)
+  float                 width;                //!< Th width of the Path. This tells the Player(s), how far he(they) can go to the left/right.
+  int                   nodeCount;            //!< The count of points this TrackElement has.
+  Curve*                curve;                //!< The Curve of this TrackElement
+  int                   childCount;           //!< The number of Children This TrackElement has.
+  tList<TrackElement>*  children;             //!< A TrackElement can have a Tree of following TrackElements.
+
+
+  // runtime
+  TrackElement* history;     //!< a pointer to the last TrackElement we were on. This is if you want to walk the path backwards again.
+
+  void debug() const;
+
+  // CONDITION FUNCTIONS and STUFF
+  void* subject;             //!< The Subject the Condition should act upon.
+  int (TrackElement::*condFunc)(const void*) const; //!< Pointer to the condition function
+
+  int lowest(const void* nothing) const;
+  int highest(const void* nothing) const;
+  int random(const void* nothing) const;
+
+  int leftRight(const void* node) const;
+  int nearest(const void* node) const;
+  // todo  int enemyKilled(void* entity);
+
+};
+
+//! the Condition to choose between the different ways of the game.
+enum CONDITION {LOWEST, HIGHEST, RANDOM, LEFTRIGHT, NEAREST, ENEMYKILLED};
+
+//! The TrackManager handles the flow of the Players through the game.
+/**
+
+   <b>The TrackManager works as followed:</b> \n
+     \n
+   <b>1. Initialize it, by setting up the Graph. You can do this by using the following Commands.</b>
+    \li workOn(): changes the ID that will be altered through the changes.
+    \li setCurveType(): lets you set the CurveType of the Curve we are Working on. (default is BezierCurve, set this as early as possible, for this uses resources).
+    \li setDuration(): sets the length of the current path in seconds.
+    \li addPoint(): adds a point to the Curve.
+    \li addHotPoint(): adds save/splitpoint.\n
+    \li fork(): adds some interessting non-linear movments through the level (fork will force addHotPoint if not done then).
+    \li condition(): decides under what condition a certain Path will be chosen.
+    \li join(): joins some tracks together again. Join will set the localTime to the longest time a Path has to get to this Point)
+    \li setSavePoint(): Sets a HotPoint into a savePoint. A Savepoint can be used as a rollbackpoint if a Player gets shot.
+
+    HotPoints and Joins are at the beginning of a TrackElement. \n
+    SavePoints and Forks are at the end of a TrackElement \n
+    look out: <b>SAVEPOINTS CAN NOT BE FORKS</b> (but joins), because the condition is really hard to guess if you do not give some impuls. \n
+\n
+   <b> 2. Runtime knows the following: </b>
+    \li calcPos(): returns the current position on the track
+    \li calcDir(): returns the current Direction the track is flying on.
+    \li tick(): makes a Step on the Path. increases localTime by dt.
+    \li choosePath(): a Function that decides which Path we should follow.
+
+   TrackManager can be handled as a StateMachine.
+   \n\n
+    Names:
+    \li TrackManager: handles Tracks
+    \li Track:        The Track that the ship can follow
+    \li Path:         one way through the Level, that is dependent on conditionals.
+    \li Conditional:  A decition making device, that chooses betwen different TrackElements for the Path.
+    \li TrackElement: A Part of A whole Track
+*/
+class TrackManager : public BaseObject
+{
+ public:
+  virtual ~TrackManager();
+  /** @returns a Pointer to the only object of this Class */
+  inline static TrackManager* getInstance() { if (!singletonRef) singletonRef = new TrackManager();  return singletonRef; };
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  // Methods to change the Path (initialisation)
+  void workOn(unsigned int trackID);
+  void workOnS(const char* trackName);
+
+  /** \see setCurveType(CurveType curveType, TrackElement* trackElem); @param curveType the type of the Curve */
+  inline void setCurveType(CurveType curveType) { this->setCurveType (curveType, this->currentTrackElem);};
+  void setCurveType(CurveType curveType, TrackElement* trackElem);
+  void setDuration(float duration);
+  void setDuration(float duration, TrackElement* trackElem);
+  void addPoint(float x, float y, float z);
+  void addPointV(Vector newPoint, TrackElement* trackElem = NULL);
+  void addHotPoint(float x, float y, float z);
+  int addHotPointV(Vector newPoint, TrackElement* trackElem = NULL);
+  void setSavePointS(const char* nextElementName);
+  void setSavePoint(TrackElement* trackElem = NULL);
+  void fork(unsigned int count, ...);
+  void forkS(unsigned int count, ...);
+  void forkS(const char* forkString);
+  void forkV(unsigned int count, int* trackIDs, char** trackNames, TrackElement* trackElem = NULL);
+  void condition(unsigned int trackID, CONDITION cond, void* subject);
+  void condition(CONDITION cond, void* subject, TrackElement* trackElem = NULL);
+  void join(unsigned int count, ...);
+  void joinS(const char* joinString);
+  void joinS(unsigned int cound, ...);
+  void joinV(unsigned int count, int* trackIDs);
+  void finalize();
+
+  // Methods to calculate the position on the Path (runtime)
+  inline Vector calcPos() const;
+  inline Vector calcDir() const;
+  float getWidth() const;
+  void tick(float dt);
+  void jumpTo(float time);
+  inline int choosePath(TrackElement* trackElem);
+
+  void setBindSlave(PNode* bindSlave);
+  PNode* getTrackNode();
+
+  // DEBUG //
+  void drawGraph(float dt) const;
+  void debug(unsigned int level) const;
+
+ private:
+  TrackManager();
+  void initChildren(unsigned int childCount, TrackElement* trackElem = NULL);
+
+ private:
+  static TrackManager* singletonRef;           //!< There may only be one TrackManager.
+
+  TrackElement*        firstTrackElem;         //!< The first TrackElement that exists.
+  TrackElement*        currentTrackElem;       //!< The TrackElement we are working on.
+  CurveType            curveType;              //!< The CurveType the entire TrackSystem will have.
+  float                localTime;              //!< The time that has been passed since the traveling the Track.
+  float                maxTime;                //!< The maximal time the track has.
+  int                  trackElemCount;         //!< The count of TrackElements that exist.
+
+  // external
+  PNode*               bindSlave;              //!< The node that is slave to the TrackManager. This node will be moved while update the TrackManager, and must NOT move itself.
+  PNode*               trackNode;              //!< The main TrackNode of this Track.
+  Text*                trackText;              //!< The text to display when switching between Worlds.
+  tAnimation<Text>*    textAnimation;          //!< An Animation for the Text. (for fading it out on trackName-change)
+};
+
+#endif /* _TRACK_MANAGER_H */
Index: branches/network/src/util/track/track_node.cc
===================================================================
--- branches/network/src/util/track/track_node.cc	(revision 6636)
+++ branches/network/src/util/track/track_node.cc	(revision 6636)
@@ -0,0 +1,44 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+
+#include "track_node.h"
+
+#include "track_manager.h"
+
+using namespace std;
+
+/**
+ *  standard constructor
+*/
+TrackNode::TrackNode ()
+{
+  this->setClassID(CL_TRACK_NODE, "TrackNode");
+  this->setName("TrackNode");
+
+  PNode::getNullParent()->addChild(this);
+  this->trackManager = TrackManager::getInstance();
+  this->setParentMode(PNODE_ALL);
+}
+
+/**
+ *  standard deconstructor
+*/
+TrackNode::~TrackNode ()
+{
+
+}
Index: branches/network/src/util/track/track_node.h
===================================================================
--- branches/network/src/util/track/track_node.h	(revision 6636)
+++ branches/network/src/util/track/track_node.h	(revision 6636)
@@ -0,0 +1,32 @@
+/*! 
+ * @file track_node.h
+  *  Definition of the TrackNode are located here
+    
+    the TrackNode is the node, that follows the Track (and the TrackManager) 
+    through the level.
+    Under normal confitions the Plyaer(s) are 
+*/
+
+
+#ifndef _TRACK_NODE_H
+#define _TRACK_NODE_H
+
+#include "p_node.h"
+
+/* FORWARD DECLARATION */
+class TrackManager;
+
+//! A node that follows the track.
+class TrackNode : public PNode 
+{
+
+ public:
+  TrackNode ();
+  virtual ~TrackNode ();
+
+ private:
+  TrackManager* trackManager;         //!< reference to the TrackManager
+
+};
+
+#endif /* _TRACK_NODE_H */
Index: branches/network/src/world_entities/Makefile.am
===================================================================
--- branches/network/src/world_entities/Makefile.am	(revision 6636)
+++ branches/network/src/world_entities/Makefile.am	(revision 6636)
@@ -0,0 +1,108 @@
+#MAINSRCDIR=..
+#include $(MAINSRCDIR)/defs/include_paths.am
+
+#noinst_LIBRARIES = libORXworld_entities.a
+#libORXworld_entities_a_SOURCES =
+#subdirs = .
+
+WorldEntities_SOURCES_ = \
+                  world_entities/world_entity.cc \
+                  world_entities/camera.cc \
+                  world_entities/playable.cc \
+                  world_entities/player.cc \
+                  world_entities/npcs/npc.cc \
+                  world_entities/npcs/npc_test1.cc \
+                  world_entities/npcs/npc_test.cc \
+                  world_entities/npcs/ground_turret.cc \
+                  world_entities/environment.cc \
+                  world_entities/skysphere.cc \
+                  world_entities/skybox.cc \
+                  world_entities/terrain.cc \
+                  world_entities/satellite.cc \
+                  world_entities/movie_entity.cc \
+                  world_entities/character_attributes.cc \
+                  world_entities/test_entity.cc \
+		  world_entities/image_entity.cc \
+		  world_entities/planet.cc \
+                  \
+                  world_entities/weapons/weapon_manager.cc \
+                  world_entities/weapons/weapon.cc \
+                  world_entities/weapons/test_gun.cc \
+                  world_entities/weapons/turret.cc \
+                  world_entities/weapons/aiming_turret.cc \
+                  world_entities/weapons/targeting_turret.cc \
+                  world_entities/weapons/cannon.cc \
+                  world_entities/weapons/aim.cc \
+                  world_entities/weapons/crosshair.cc \
+                  \
+                  world_entities/projectiles/projectile.cc \
+                  world_entities/projectiles/bomb.cc \
+                  world_entities/projectiles/laser.cc \
+                  world_entities/projectiles/test_bullet.cc \
+                  world_entities/projectiles/rocket.cc \
+                  world_entities/projectiles/guided_missile.cc \
+                  \
+                  world_entities/power_ups/power_up.cc \
+                  world_entities/power_ups/turret_power_up.cc \
+                  world_entities/power_ups/laser_power_up.cc \
+                  world_entities/power_ups/weapon_power_up.cc \
+                  world_entities/power_ups/param_power_up.cc \
+                  \
+                  world_entities/space_ships/space_ship.cc \
+                  world_entities/space_ships/helicopter.cc \
+                  world_entities/creatures/md2_creature.cc \
+                  \
+                  world_entities/spawning_point.cc \
+                  \
+                  world_entities/environments/water.cc
+
+WorldEntities_HEADERS_ = \
+                 world_entities/world_entity.h \
+                 world_entities/camera.h \
+                 world_entities/extendable.h \
+                 world_entities/playable.h \
+                 world_entities/player.h \
+                 world_entities/npcs/npc.h \
+                 world_entities/npcs/npc_test.h \
+                 world_entities/npcs/npc_test1.h \
+                 world_entities/environment.h \
+                 world_entities/skysphere.h \
+                 world_entities/skybox.h \
+                 world_entities/terrain.h \
+                 world_entities/satellite.h \
+                 world_entities/movie_entity.h \
+                 world_entities/character_attributes.h \
+                 world_entities/test_entity.h \
+                 world_entities/image_entity.h \
+                 world_entities/planet.h \
+                 \
+                 world_entities/weapons/weapon_manager.h \
+                 world_entities/weapons/weapon.h \
+                 world_entities/weapons/test_gun.h \
+                 world_entities/weapons/cannon.h \
+                 world_entities/weapons/turret.h \
+                 world_entities/weapons/aiming_turret.h \
+                 world_entities/weapons/targeting_turret.h \
+                 world_entities/weapons/aim.h \
+                 world_entities/weapons/crosshair.h \
+                 \
+                 world_entities/projectiles/projectile.h \
+                 world_entities/projectiles/bomb.h \
+                 world_entities/projectiles/laser.h \
+                 world_entities/projectiles/test_bullet.h \
+                 world_entities/projectiles/rocket.h \
+                 world_entities/projectiles/guided_missile.h \
+                 \
+                 world_entities/power_ups/power_up.h \
+                 world_entities/power_ups/turret_power_up.h \
+                 world_entities/power_ups/laser_power_up.h \
+                 world_entities/power_ups/param_power_up.h \
+                 world_entities/power_ups/weapon_power_up.h \
+                 \
+                 world_entities/space_ships/space_ship.h \
+                 world_entities/space_ships/helicopter.h \
+                 world_entities/creatures/md2_creature.h \
+                 \
+                 world_entities/spawning_point.h \
+                 \
+                 world_entities/environments/water.h
Index: branches/network/src/world_entities/camera.cc
===================================================================
--- branches/network/src/world_entities/camera.cc	(revision 6636)
+++ branches/network/src/world_entities/camera.cc	(revision 6636)
@@ -0,0 +1,256 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Christian Meyer
+   co-programmer: Benjamin Grauer
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "camera.h"
+
+#include "event_handler.h"
+
+using namespace std;
+
+
+/**
+ *  creates a Camera
+*/
+Camera::Camera()
+{
+  this->setClassID(CL_CAMERA, "Camera");
+  this->setName("camera");
+  this->target = new CameraTarget();
+
+  EventHandler::getInstance()->subscribe(this, ES_GAME, KeyMapper::PEV_VIEW0);
+  EventHandler::getInstance()->subscribe(this, ES_GAME, KeyMapper::PEV_VIEW1);
+  EventHandler::getInstance()->subscribe(this, ES_GAME, KeyMapper::PEV_VIEW2);
+  EventHandler::getInstance()->subscribe(this, ES_GAME, KeyMapper::PEV_VIEW3);
+  EventHandler::getInstance()->subscribe(this, ES_GAME, KeyMapper::PEV_VIEW4);
+  EventHandler::getInstance()->subscribe(this, ES_GAME, KeyMapper::PEV_VIEW5);
+
+  this->setFovy(90);
+  this->setAspectRatio(1.2f);
+  this->setClipRegion(.1, 2000);
+
+  this->setViewMode(VIEW_NORMAL);
+
+  this->setParentMode(PNODE_ALL);
+}
+
+/**
+ *  default destructor
+*/
+Camera::~Camera()
+{}
+
+/**
+ *  focuses the Camera onto a Target
+ * @param target the new PNode the Camera should look at.
+*/
+void Camera::lookAt(PNode* target)
+{
+  this->target->setParent(target);
+}
+
+/**
+ * @returns The PNode of the Target (from there you can get position and so on
+*/
+PNode* Camera::getTarget()
+{
+  return (PNode*)this->target;
+}
+
+/**
+ *  sets a new AspectRatio
+ * @param aspectRatio the new aspect ratio to set (width / height)
+*/
+void Camera::setAspectRatio(float aspectRatio)
+{
+  this->aspectRatio = aspectRatio;
+}
+
+/**
+ *  sets the Field of View to fofy
+ * @param fovy new field of view factor (in degrees)
+*/
+void Camera::setFovy(float fovy)
+{
+  this->fovy = fovy;
+}
+
+/**
+ * Sets a new clipping region
+ * @param nearClip The near clip plane
+ * @param farClip The far clip plane
+*/
+void Camera::setClipRegion(float nearClip, float farClip)
+{
+  this->nearClip = nearClip;
+  this->farClip = farClip;
+}
+
+/**
+ *  sets the new VideoMode and initializes iteration to it.
+ * @param mode the mode to change to.
+*/
+void Camera::setViewMode(ViewMode mode)
+{
+  currentMode = mode;
+  switch (mode)
+  {
+    default:
+    case VIEW_NORMAL:
+      this->toFovy = 60.0;
+      /*      this->setParentSoft("TrackNode");
+            this->target->setParentSoft("TrackNode"); */
+      this->setRelCoorSoft(-10, 5, 0);
+      this->target->setRelCoorSoft(0,0,0);
+      break;
+    case VIEW_BEHIND:
+      //      this->toFovy = 120.0;
+      //      this->setRelCoorSoft(Vector(3.5, 0, 0));
+      //    this->target->setRelCoorSoft(Vector(10,0,0));
+
+      //       if (!strcmp(this->target->getParent()->getName(), "Player"))
+      //         this->target->setParentSoft("TrackNode");
+      //       else
+      //         this->target->setParentSoft("Player");
+      //       this->getParent()->debugNode(0);
+
+      //      this->setParent("main-Turret");
+      //      this->setParentMode(PNODE_ALL);
+      //      this->target->setParentSoft("Player");
+
+      break;
+    case VIEW_FRONT:
+      this->toFovy = 120.0;
+      /*       this->setParentSoft("Player");
+             this->target->setParentSoft("Player");*/
+      this->setRelCoorSoft(4, 0, 0, 5);
+      this->target->setRelCoorSoft(Vector(10,0,0), 5);
+      //      this->target->setRelDirSoft(Quaternion(M_PI/4.0, Vector(0,1,0)));
+      break;
+    case VIEW_LEFT:
+      this->toFovy = 90;
+      /*      this->setParentSoft("TrackNode");
+            this->target->setParentSoft("TrackNode");*/
+      this->setRelCoorSoft(0, 1, -10, .5);
+      this->target->setRelCoorSoft(0,0,0);
+      break;
+    case VIEW_RIGHT:
+      this->toFovy = 90;
+      /*      this->setParentSoft("TrackNode");
+            this->target->setParentSoft("TrackNode");*/
+      this->setRelCoorSoft(Vector(0, 1, 10));
+      this->target->setRelCoorSoft(0,0,0);
+      break;
+    case VIEW_TOP:
+      this->toFovy= 120;
+      /*      this->setParentSoft("TrackNode");
+            this->target->setParentSoft("TrackNode");*/
+      this->setRelCoorSoft(Vector(30, 50, 0));
+      this->target->setRelCoorSoft(35,0,0);
+  }
+}
+
+
+/**
+ *  Updates the position of the camera.
+ * @param dt: The time that elapsed.
+*/
+void Camera::tick(float dt)
+{
+  float tmpFovy = (this->toFovy - this->fovy) ;
+  if (tmpFovy > 0.01)
+    this->fovy += tmpFovy * fabsf(dt);
+}
+
+
+/**
+ *  initialize rendering perspective according to this camera
+
+   This is called immediately before the rendering cycle starts, it sets all global
+   rendering options as well as the GL_PROJECTION matrix according to the camera.
+*/
+void Camera::apply ()
+{
+  // switching to Projection Matrix
+  glMatrixMode (GL_PROJECTION);
+  glLoadIdentity ();
+
+  // setting up the perspective
+  gluPerspective(this->fovy,
+                 this->aspectRatio,
+                 this->nearClip,
+                 this->farClip);
+
+  // speed-up feature
+  Vector cameraPosition = this->getAbsCoor();
+  Vector targetPosition = this->target->getAbsCoor();
+  Vector up = this->getAbsDirV();
+  Vector delay = Vector(0,0,0);
+  if( currentMode != VIEW_FRONT) delay = (this->target->getVelocity())/25;
+
+  // Setting the Camera Eye, lookAt and up Vectors
+  gluLookAt(cameraPosition.x - delay.x, cameraPosition.y - delay.y, cameraPosition.z - delay.z,
+            targetPosition.x, targetPosition.y, targetPosition.z,
+            up.x, up.y, up.z);
+
+  // switching back to Modeling Matrix
+  glMatrixMode (GL_MODELVIEW);
+  //  this->target->getParent()->getParent()->debugDraw(0, 2, Vector(1,0,0));
+}
+
+/**
+ *  processes an event
+ * @param event: the event to process
+*/
+void Camera::process(const Event &event)
+{
+  if( event.type == KeyMapper::PEV_VIEW0)
+  {
+    this->setViewMode(VIEW_NORMAL);
+  }
+  else if( event.type == KeyMapper::PEV_VIEW1)
+  {
+    this->setViewMode(VIEW_BEHIND);
+  }
+  else if( event.type == KeyMapper::PEV_VIEW2)
+  {
+    this->setViewMode(VIEW_FRONT);
+  }
+  else if( event.type == KeyMapper::PEV_VIEW3)
+  {
+    this->setViewMode(VIEW_LEFT);
+  }
+  else if( event.type == KeyMapper::PEV_VIEW4)
+  {
+    this->setViewMode(VIEW_RIGHT);
+  }
+  else if( event.type == KeyMapper::PEV_VIEW5)
+  {
+    this->setViewMode(VIEW_TOP);
+  }
+}
+
+
+///////////////////
+// CAMERA-TARGET //
+///////////////////
+
+
+CameraTarget::CameraTarget()
+{
+  this->setClassID(CL_CAMERA_TARGET, "CameraTarget");
+  //  this->setParentMode(PNODE_MOVEMENT);
+}
+
Index: branches/network/src/world_entities/camera.h
===================================================================
--- branches/network/src/world_entities/camera.h	(revision 6636)
+++ branches/network/src/world_entities/camera.h	(revision 6636)
@@ -0,0 +1,74 @@
+/*!
+ * @file camera.h
+ * Viewpoint controlling class definitions
+*/
+
+#ifndef _CAMERA_H
+#define _CAMERA_H
+
+#include "p_node.h"
+#include "event_listener.h"
+
+class World;
+class CameraTarget;
+class Event;
+
+//! an enumerator for different types of view
+typedef enum ViewMode
+{
+  VIEW_NORMAL,
+  VIEW_BEHIND,
+  VIEW_FRONT,
+  VIEW_LEFT,
+  VIEW_RIGHT,
+  VIEW_TOP
+};
+
+//! Camera
+/**
+ * This class controls the viewpoint from which the World is rendered.
+*/
+class Camera : public PNode, public EventListener
+{
+ public:
+  Camera();
+  virtual ~Camera();
+
+  void lookAt(PNode* target);
+  PNode* getTarget();
+
+  void setAspectRatio(float aspectRatio);
+  void setFovy(float fovy);
+  void setClipRegion(float nearClip, float farClip);
+
+  void setViewMode(ViewMode mode);
+  void tick(float dt);
+  void apply ();
+
+  void process(const Event &event);
+
+ private:
+  CameraTarget*     target;          //!< The Target of the Camera (where this Camera Looks at)
+
+  float             fovy;            //!< The field of view Angle (in degrees).
+  float             aspectRatio;     //!< The aspect ratio (width / height).
+  float             nearClip;        //!< The near clipping plane.
+  float             farClip;         //!< The far clipping plane.
+
+  float             toFovy;          //!< The fovy-mode to iterate to.
+  ViewMode          currentMode;     //!< The ViewMode the camera is in
+};
+
+//! A CameraTarget is where the Camera is looking at.
+class CameraTarget : public PNode
+{
+  friend class Camera;             //! The CameraTarget is a friend of Camera. noone else needs a CameraTarget, so noone else can create it.
+
+ private:
+  CameraTarget();
+
+ public:
+};
+
+
+#endif /* _CAMERA_H */
Index: branches/network/src/world_entities/character_attributes.cc
===================================================================
--- branches/network/src/world_entities/character_attributes.cc	(revision 6636)
+++ branches/network/src/world_entities/character_attributes.cc	(revision 6636)
@@ -0,0 +1,378 @@
+
+
+/* 
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+
+#include "character_attributes.h"
+#include "stdincl.h" 
+
+using namespace std;
+
+
+/**
+ *  standard constructor
+   @todo this constructor is not jet implemented - do it
+*/
+CharacterAttributes::CharacterAttributes () 
+{
+   this->setClassID(CL_CHARACTER_ATTRIBUTES, "CharacterAttributes");
+}
+
+
+/**
+ *  standard deconstructor
+
+*/
+CharacterAttributes::~CharacterAttributes () 
+{
+}
+
+
+/*=====================health=====================*/
+
+/**
+ *  sets the health of the character
+ * @param helath
+ */
+void CharacterAttributes::setHealth(int health)
+{
+  this->health = health;
+}
+
+/**
+ *  adds health to the charater
+ * @param health
+ * @returns health that couldnt be added due to healt limit, 0 if everything worked as normal
+ */
+int CharacterAttributes::addHealth(int health)
+{
+  this->health += health;
+  int rest = this->healthMax - this->health;
+  if( rest < 0)
+    {
+      this->health = this->healthMax;
+      return 0;
+    }
+  return rest;
+}
+
+/**
+ *  remove health due to damager for example
+ * @param amount of health
+ * @returns false if health is zero -> dead
+ */
+bool CharacterAttributes::substractHealth(int health)
+{
+  this->health -= health;
+  if( this->health < 0)
+    {
+      this->health = 0;
+      return false;
+    }
+  return true;
+}
+
+/**
+ *  gets the current amount of health
+ * @returns health
+ */
+int CharacterAttributes::getHealth()
+{
+  return this->health;
+}
+
+
+/**
+ *  sets maximum health 
+ * @param health
+
+   if healthMax = 0 -> unlimited
+ */
+void CharacterAttributes::setHealthMax(int healthMax)
+{
+  this->healthMax = healthMax;
+}
+
+/**
+ *  gets health maximium
+ * @returns the health maximum
+ */
+int CharacterAttributes::getHealthMax()
+{
+  return this->healthMax;
+}
+
+
+/*======================armor/ shields===================== */
+/**
+ *  sets the shild strength
+ * @param strength
+ */
+void CharacterAttributes::setShieldStrength(int shieldStrength)
+{
+  this->shieldStrength = shieldStrength;
+}
+
+/**
+ *  adds shield strength
+ * @param strength
+   
+   there is currently no limit to shieldstrength
+ */
+void CharacterAttributes::addShieldStrength(int shiledStrength)
+{
+  this->shieldStrength += shieldStrength;
+}
+
+/**
+ *  substracts shield strength
+ * @param strength
+ * @returns amount of shield strength below zero after substraction. Magic: Troumble. if everything works allright, it returns 0
+ */
+int CharacterAttributes::substractShieldStrength(int shieldStrength)
+{
+  int rest = this->shieldStrength -= shieldStrength;
+  if( rest < 0)
+    {
+      this->shieldStrength = 0;
+      return -rest;
+    }
+  return 0;
+}
+
+/**
+ *  gets shield strength
+ * @returns the shield strength
+ */
+int CharacterAttributes::getShieldStrength()
+{
+  return this->shieldStrength;
+}
+
+
+/*=====================damage=====================*/
+/**
+ *  sets the amount of base damage dealt to all aircrafts
+ * @param damage
+
+   There can be a difference between arms that hit a ground/air craft. Eg.
+   a tank will react differently to explosives than something in the air
+   (think about physics)
+ */
+void CharacterAttributes::setDamageToAirCraft(int damage)
+{
+  this->damageToAirCraft = damage;
+}
+
+/**
+ *  gets the amount of base damage
+ * @returns base damage to aircrafts
+
+   There can be a difference between arms that hit a ground/air craft. Eg.
+   a tank will react differently to explosives than something in the air
+   (think about physics)
+ */
+int CharacterAttributes::getDamageToAirCraft()
+{
+  return this->damageToAirCraft;
+}
+
+
+/**
+ *  sets the amount of base damage dealt to all groundcrafts
+ * @param damage
+
+   There can be a difference between arms that hit a ground/air craft. Eg.
+   a tank will react differently to explosives than something in the air
+   (think about physics)
+ */
+void CharacterAttributes::setDamageToGroundCraft(int damage)
+{
+  this->damageToGroundCraft = damage;
+}
+
+/**
+ * gets the amount of base damage
+ * @returns base damage to groundcrafts
+
+   There can be a difference between arms that hit a ground/air craft. Eg.
+   a tank will react differently to explosives than something in the air
+   (think about physics)
+ */
+int CharacterAttributes::getDamageToGroundCraft()
+{
+  return this->damageToGroundCraft;
+}
+
+
+/**
+ *  sets the damage modifier to the damage that is dealed via laser weapons
+ * @param modifier [0..1]
+
+   eg. the damage is calculated after: damage = modifier * damageToGroundCraft
+ */
+void CharacterAttributes::setDamageLaserModifier(float modifier)
+{
+  this->damageLaserModifier = modifier;
+}
+
+/**
+ *  gets the damage modifier to the damage that is dealed via laser weapons
+ * @returns damage modifier
+
+   eg. the damage is calculated after: damage = modifier * damageToGroundCraft
+ */
+float CharacterAttributes::getDamageLaserModifier()
+{
+  return this->damageLaserModifier;
+}
+
+
+/**
+ *  sets the damage modifier to the damage that is dealed via plasma weapons
+ * @param damage modifier
+
+   eg. the damage is calculated after: damage = modifier * damageToGroundCraft
+ */
+void CharacterAttributes::setDamagePlasmaModifier(float modifier)
+{
+  this->damagePlasmaModifier = modifier;
+}
+
+/**
+ *  gets the damage modifier to the damage that is dealed plasma weapons
+ * @returns damage modifier
+
+   eg. the damage is calculated after: damage = modifier * damageToGroundCraft
+ */
+float CharacterAttributes::getDamagePlasmaModifier()
+{
+  return this->damagePlasmaModifier;
+}
+
+
+/**
+ *  sets the damage modifier to the damage that is dealed via explosives
+ * @param damage modifier
+
+   eg. the damage is calculated after: damage = modifier * damageToGroundCraft
+ */
+void CharacterAttributes::setDamageExplosiveModifier(float modifier)
+{
+  this->damageExplosiveModifier = modifier;
+}
+
+/**
+ *  sets the damage modifier to the damage that is dealed via explosives
+ * @returns damage modifier
+
+   eg. the damage is calculated after: damage = modifier * damageToGroundCraft
+ */
+float CharacterAttributes::getDamageExplosiveModifier()
+{
+  return this->damageExplosiveModifier;
+}
+
+
+/*=====================energy=====================*/
+/**
+ *  sets the amount of energy 
+ * @param energy
+ */
+void CharacterAttributes::setEnergy(int energy)
+{
+  this->energy = energy;
+}
+
+/**
+ *  adds energy to the system
+ * @param amount of energy
+ * @returns amount of energy that is too much due to energy limit
+ */
+int CharacterAttributes::addEnergy(int addEnergy)
+{
+  this->energy += addEnergy;
+  int rest = this->energyMax - this->energy;
+  if(rest < 0)
+    {
+      this->energy = 0;
+      return rest;
+    }
+  return 0;
+}
+
+/**
+ *  substracts energy from a system
+ * @param amount of energy
+ * @returns false if there is no energy anymore
+ */
+bool CharacterAttributes::substractEnergy(int subEnergy)
+{
+  this->energy -= subEnergy;
+  if(this->energy < 0)
+    {
+      this->energy = 0;
+      return false;
+    }
+  return true;
+}
+
+/**
+ *  gets the amount of energy 
+ * @returns energy
+ */
+int CharacterAttributes::getEnergy()
+{
+  return this->energy;
+}
+
+
+/**
+ *  sets the energy consumption
+ * @param amount of energy
+*/
+void CharacterAttributes::setEnergyConsumption(int energy)
+{
+  this->energyConsumption = energy;
+}
+
+/**
+ *  gets the energy consumption
+ * @returns amount of energy
+*/
+int CharacterAttributes::getEnergyConsumption()
+{
+  return this->energyConsumption;
+}
+  
+
+/**
+ *  sets the maximum energy level
+ * @param amount of energy
+*/
+void CharacterAttributes::setEnergyMax(int energy)
+{
+  this->energyMax = energy;
+}
+
+/**
+ *  gets the max energy level
+ * @returns amount of energy
+*/
+int CharacterAttributes::getEnergyMax()
+{
+  return this->energyMax;
+}
Index: branches/network/src/world_entities/character_attributes.h
===================================================================
--- branches/network/src/world_entities/character_attributes.h	(revision 6636)
+++ branches/network/src/world_entities/character_attributes.h	(revision 6636)
@@ -0,0 +1,91 @@
+/*!
+ * @file character_attributes.h
+ * Definition of the attributes of a character (healt, armor,.. ) whatever is important to the character
+ */
+
+#ifndef _CHARACTER_ATTRIBUTES_H
+#define _CHARACTER_ATTRIBUTES_H
+
+#include "base_object.h"
+
+
+//! A class including all important information about a character
+/**
+  its not yet clear, what the character-attributes will be.
+*/
+class CharacterAttributes : public BaseObject {
+
+ public:
+  CharacterAttributes();
+  virtual ~CharacterAttributes();
+
+  /* health */
+  void setHealth(int health);
+  int addHealth(int health);
+  bool substractHealth(int health);
+  int getHealth();
+
+  void setHealthMax(int healthMax);
+  int getHealthMax();
+
+
+  /* armor/ shields */
+  void setShieldStrength(int shieldStrength);
+  void addShieldStrength(int shiledStrength);
+  int substractShieldStrength(int shieldStrength);
+  int getShieldStrength();
+
+
+  /* damage */
+  void setDamageToAirCraft(int damage);
+  int getDamageToAirCraft();
+
+  void setDamageToGroundCraft(int damage);
+  int getDamageToGroundCraft();
+
+  void setDamageLaserModifier(float modifier);
+  float getDamageLaserModifier();
+
+  void setDamagePlasmaModifier(float modifier);
+  float getDamagePlasmaModifier();
+
+  void setDamageExplosiveModifier(float modifier);
+  float getDamageExplosiveModifier();
+
+
+  /* energy */
+  void setEnergy(int energy);
+  int addEnergy(int addEnergy);
+  bool substractEnergy(int subEnergy);
+  int getEnergy();
+
+  void setEnergyConsumption(int energy);
+  int getEnergyConsumption();
+
+  void setEnergyMax(int energy);
+  int getEnergyMax();
+
+
+ private:
+  /* healt */
+  int health;                        //<! the healt of a projectile
+  int healthMax;                     //<! the max healt of a projectile, =0 if no limit
+
+  /* armor/ shields */
+  int shieldStrength;                //<! the shiled strength of a character, =0 if no shields
+
+  /* damage */
+  int damageToAirCraft;              //<! damage dealt to a air craft in case of a hit
+  int damageToGroundCraft;           //<! damage dealt to a ground craft in case of a hit
+
+  float damageLaserModifier;         //<! [0..1] the damage from laser is multiplied with this modifier. there can be things in the world, that are immune to certain damage
+  float damagePlasmaModifier;        //<! [0..1] the damage from plasma is multiplied with this modifier. there can be things in the world, that are immune to certain damage
+  float damageExplosiveModifier;      //<! [0..1] the damage from exposives (rockets, tnt,...) is multiplied with this modifier. there can be things in the world, that are immune to certain damage
+
+  /* energy */
+  int energyConsumption;             //<! if the character defines an action, it will consume energy
+  int energy;                        //<! the current amount of energy saved in this part
+  int energyMax;                     //<! the maximal energy a character can handle
+};
+
+#endif /* _CHARACTER_ATTRIBUTES_H */
Index: branches/network/src/world_entities/creatures/md2_creature.cc
===================================================================
--- branches/network/src/world_entities/creatures/md2_creature.cc	(revision 6636)
+++ branches/network/src/world_entities/creatures/md2_creature.cc	(revision 6636)
@@ -0,0 +1,424 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer:
+
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "executor/executor.h"
+#include "md2_creature.h"
+
+#include "objModel.h"
+#include "md2Model.h"
+#include "resource_manager.h"
+#include "state.h"
+
+#include "weapons/weapon_manager.h"
+#include "weapons/test_gun.h"
+#include "weapons/turret.h"
+#include "weapons/cannon.h"
+
+#include "factory.h"
+#include "key_mapper.h"
+#include "event_handler.h"
+
+#include "graphics_engine.h"
+
+using namespace std;
+
+CREATE_FACTORY(MD2Creature, CL_MD2_CREATURE);
+
+/**
+ *  creates the controlable MD2Creature
+ */
+MD2Creature::MD2Creature()
+{
+  this->init();
+}
+
+/**
+ *  destructs the MD2Creature, deletes alocated memory
+ */
+MD2Creature::~MD2Creature ()
+{
+}
+
+/**
+ * loads a MD2Creatures information from a specified file.
+ * @param fileName the name of the File to load the MD2Creature from (absolute path)
+ */
+MD2Creature::MD2Creature(const char* fileName)
+{
+  this->init();
+  TiXmlDocument doc(fileName);
+
+  if(!doc.LoadFile())
+  {
+    PRINTF(2)("Loading file %s failed for md2 creature.\n", fileName);
+    return;
+  }
+
+  this->loadParams(doc.RootElement());
+}
+
+/**
+ *  creates a new MD2Creature from Xml Data
+ * @param root the xml element containing MD2Creature data
+
+   @todo add more parameters to load
+*/
+MD2Creature::MD2Creature(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+
+  //weapons:
+  Weapon* wpRight = new TestGun(0);
+  wpRight->setName("testGun Right");
+  Weapon* wpLeft = new TestGun(1);
+  wpLeft->setName("testGun Left");
+  Weapon* cannon = dynamic_cast<Weapon*>(Factory::fabricate(CL_CANNON));
+
+  cannon->setName("BFG");
+
+   this->getWeaponManager()->addWeapon(wpLeft, 1, 0);
+   this->getWeaponManager()->addWeapon(wpRight,1 ,1);
+//   this->getWeaponManager()->addWeapon(cannon, 0, 6);
+
+  //this->getWeaponManager()->addWeapon(turret, 3, 0);
+
+  this->getWeaponManager()->changeWeaponConfig(0);
+}
+
+
+/**
+ * initializes a MD2Creature
+ */
+void MD2Creature::init()
+{
+//  this->setRelDir(Quaternion(M_PI, Vector(1,0,0)));
+  this->setClassID(CL_MD2_CREATURE, "MD2Creature");
+
+  PRINTF(4)("MD2CREATURE INIT\n");
+
+  EventHandler::getInstance()->grabEvents(true);
+
+  this->mouseDirX *= Quaternion( M_PI * 0.75f, Vector(0,1,0));
+
+  bUp = bDown = bLeft = bRight = bAscend = bDescend = bRollL = bRollR = bStrafeL = bStrafeR = bJump = false;
+  bFire = false;
+  xMouse = yMouse = 0;
+  mouseSensitivity = 0.003;
+  airViscosity = 0.0;
+  cycle = 0.0;
+
+  this->cameraConnNode.addNodeFlags(PNODE_PROHIBIT_DELETE_WITH_PARENT);
+  this->cameraConnNode.setName("CameraConnectorNode");
+  this->addChild(&this->cameraConnNode);
+  this->cameraConnNode.addChild(State::getCameraTarget());
+  this->cameraConnNode.addChild(State::getCamera());
+  State::getCameraTarget()->setRelCoor(10,0,0);
+
+  travelSpeed = 15.0;
+  this->velocity = Vector(0.0,0.0,0.0);
+
+//   GLGuiButton* button = new GLGuiPushButton();
+//   button->show();
+//   button->setLabel("orxonox");
+//   button->setBindNode(this);
+
+  //add events to the eventlist
+  this->registerEvent(SDLK_w);
+  this->registerEvent(SDLK_s);
+  this->registerEvent(SDLK_a);
+  this->registerEvent(SDLK_d);
+  this->registerEvent(SDLK_SPACE);
+  this->registerEvent(SDLK_q);
+  this->registerEvent(SDLK_e);
+  this->registerEvent(KeyMapper::PEV_FIRE1);
+  this->registerEvent(KeyMapper::PEV_NEXT_WEAPON);
+  this->registerEvent(KeyMapper::PEV_PREVIOUS_WEAPON);
+  this->registerEvent(EV_MOUSE_MOTION);
+
+
+
+  this->getWeaponManager()->setSlotCount(7);
+
+  this->getWeaponManager()->setSlotPosition(0, Vector(-0.5, .2, -1.9));
+  this->getWeaponManager()->setSlotCapability(0, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+
+  this->getWeaponManager()->setSlotPosition(1, Vector(-0.5, .2, 1.9));
+  this->getWeaponManager()->setSlotCapability(1, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+
+  this->getWeaponManager()->setSlotPosition(2, Vector(-1.5, .5, -.5));
+  this->getWeaponManager()->setSlotDirection(2, Quaternion(-M_PI_4*.5, Vector(1,0,0)));
+
+  this->getWeaponManager()->setSlotPosition(3, Vector(-1.5, .5, .5));
+  this->getWeaponManager()->setSlotDirection(3, Quaternion(M_PI_4*.5, Vector(1,0,0)));
+
+  this->getWeaponManager()->setSlotPosition(4, Vector(-1.5, -.5, .5));
+  this->getWeaponManager()->setSlotDirection(4, Quaternion(-M_PI_4*.5+M_PI, Vector(1,0,0)));
+
+  this->getWeaponManager()->setSlotPosition(5, Vector(-1.5, -.5, -.5));
+  this->getWeaponManager()->setSlotDirection(5, Quaternion(+M_PI_4*.5-M_PI, Vector(1,0,0)));
+//
+   this->getWeaponManager()->setSlotPosition(6, Vector(-1, 0.0, 0));
+   this->getWeaponManager()->setSlotCapability(6, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+   //
+
+   this->cameraConnNode.addChild(this->getWeaponManager()->getFixedTarget());
+  this->getWeaponManager()->getFixedTarget()->setRelCoor(10,0,0);
+
+}
+
+
+void MD2Creature::enter()
+{
+  dynamic_cast<Element2D*>(this->getWeaponManager()->getFixedTarget())->setVisibility( true);
+
+
+}
+
+void MD2Creature::leave()
+{
+  dynamic_cast<Element2D*>(this->getWeaponManager()->getFixedTarget())->setVisibility( false);
+
+
+}
+
+/**
+ * loads the Settings of a MD2Creature from an XML-element.
+ * @param root the XML-element to load the MD2Creature's properties from
+ */
+void MD2Creature::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+}
+
+
+/**
+ *  effect that occurs after the MD2Creature is spawned
+*/
+void MD2Creature::postSpawn ()
+{
+  //setCollision(new CollisionCluster(1.0, Vector(0,0,0)));
+}
+
+/**
+ *  the action occuring if the MD2Creature left the game
+*/
+void MD2Creature::leftWorld ()
+{}
+
+/**
+ *  this function is called, when two entities collide
+ * @param entity: the world entity with whom it collides
+ *
+ * Implement behaviour like damage application or other miscellaneous collision stuff in this function
+ */
+void MD2Creature::collidesWith(WorldEntity* entity, const Vector& location)
+{
+  if (entity->isA(CL_TURRET_POWER_UP) )
+  {
+    this->ADDWEAPON();
+    }
+//  PRINTF(3)("collision %s vs %s @ (%f,%f,%f)\n", this->getClassName(), entity->getClassName(), location.x, location.y, location.z);
+}
+
+/**
+ *  draws the MD2Creature after transforming it.
+*/
+void MD2Creature::draw () const
+{
+  WorldEntity::draw();
+//  this->cameraConnNode.debugDraw(0);
+}
+
+
+/**
+ *  the function called for each passing timeSnap
+ * @param time The timespan passed since last update
+*/
+void MD2Creature::tick (float time)
+{
+  if( likely(this->getModel(0) != NULL))
+    ((MD2Model*)this->getModel(0))->tick(time);
+
+
+  // MD2Creature controlled movement
+  this->calculateVelocity(time);
+  Vector move = this->velocity * time;
+  this->shiftCoor (move);
+
+  if( this->bJump)
+  {
+    ((MD2Model*)this->getModel(0))->setAnim(JUMP);
+  }
+  else if( this->bFire)
+  {
+    if( ((MD2Model*)this->getModel(0))->getAnim() != ATTACK) ((MD2Model*)this->getModel(0))->setAnim(ATTACK);
+  }
+  else if( fabs(move.len()) > 0.0f)
+  {
+    if( ((MD2Model*)this->getModel(0))->getAnim() != RUN) ((MD2Model*)this->getModel(0))->setAnim(RUN);
+  }
+  else
+  {
+    if( ((MD2Model*)this->getModel(0))->getAnim() != STAND) ((MD2Model*)this->getModel(0))->setAnim(STAND);
+  }
+
+
+  //orient the MD2Creature in direction of the mouse
+  this->setAbsDir(mouseDirX);
+  this->cameraConnNode.setRelDir(mouseDirY);
+
+  this->getWeaponManager()->tick(time);
+  // weapon system manipulation
+  this->weaponAction();
+}
+
+
+/**
+ *  calculate the velocity
+ * @param time the timeslice since the last frame
+*/
+void MD2Creature::calculateVelocity (float time)
+{
+  Vector accel(0.0, 0.0, 0.0);
+  /*
+  Vector rot(0.0, 0.0, 0.0); // wird benötigt für Helicopter
+  */
+  //float rotVal = 0.0;
+  /* FIXME: calculating the direction and orthDirection every timeSlice is redundant! save it somewhere */
+  /* calculate the direction in which the craft is heading  */
+
+  if( this->bUp )
+   {
+     accel += (this->getAbsDirX())*2;
+   }
+
+  if( this->bDown )
+   {
+     accel -= (this->getAbsDirX())*2;
+   }
+
+  if( this->bLeft/* > -this->getRelCoor().z*2*/)
+  {
+    this->shiftDir(Quaternion(time, Vector(0,1,0)));
+  }
+  if( this->bRight /* > this->getRelCoor().z*2*/)
+  {
+    this->shiftDir(Quaternion(-time, Vector(0,1,0)));
+  }
+
+
+  if( this->bStrafeL /* > -this->getRelCoor().z*2*/)
+  {
+    accel -= this->getAbsDirZ() * 2.0f;
+  }
+  if( this->bStrafeR /* > this->getRelCoor().z*2*/)
+  {
+    accel += this->getAbsDirZ() * 2.0f;
+  }
+  if (this->bAscend )
+  {
+    this->shiftDir(Quaternion(time, Vector(0,0,1)));
+  }
+  if (this->bDescend )
+  {
+    this->shiftDir(Quaternion(-time, Vector(0,0,1)));
+  }
+
+  velocity = accel * 20.0f;
+  //rot.normalize();
+  //this->setRelDirSoft(Quaternion(rotVal, rot), 5);
+}
+
+
+/**
+ * weapon manipulation by the player
+*/
+void MD2Creature::weaponAction()
+{
+  if( this->bFire)
+    {
+      this->getWeaponManager()->fire();
+    }
+}
+
+/**
+ * @todo switch statement ??
+ */
+void MD2Creature::process(const Event &event)
+{
+  if( event.type == SDLK_a)
+      this->bStrafeL = event.bPressed;
+  else if( event.type == SDLK_d)
+      this->bStrafeR = event.bPressed;
+  else if( event.type == KeyMapper::PEV_FIRE1)
+      this->bFire = event.bPressed;
+  else if( event.type == KeyMapper::PEV_NEXT_WEAPON && event.bPressed)
+    this->getWeaponManager()->nextWeaponConfig();//if( !event.bPressed) this->bWeaponChange = !this->bWeaponChange;
+  else if ( event.type == KeyMapper::PEV_PREVIOUS_WEAPON && event.bPressed)
+    this->getWeaponManager()->previousWeaponConfig();
+  else if( event.type == SDLK_w)
+    this->bUp = event.bPressed; //this->shiftCoor(0,.1,0);
+  else if( event.type == SDLK_s)
+    this->bDown = event.bPressed; //this->shiftCoor(0,-.1,0);
+  else if( event.type == SDLK_SPACE)
+    this->bJump = event.bPressed;
+  else if( event.type == EV_MOUSE_MOTION)
+  {
+    this->xMouse = event.xRel;
+    this->yMouse = event.yRel;
+    this->mouseDirX *= Quaternion(-M_PI/4*this->xMouse*mouseSensitivity, Vector(0,1,0));
+    this->mouseDirY *= Quaternion(-M_PI/4*this->yMouse*mouseSensitivity, Vector(0,0,1));
+//     if( xMouse*xMouse < 0.9)
+//      this->setAbsDir(mouseDir);
+  }
+}
+
+#include "weapons/aiming_turret.h"
+// FIXME THIS MIGHT BE CONSIDERED EITHER A FEATURE, OR A BUG
+void MD2Creature::ADDWEAPON()
+{
+  Weapon* turret = NULL;
+
+  if ((float)rand()/RAND_MAX < .1)
+  {
+    //if (this->getWeaponManager()->hasFreeSlot(2, WTYPE_TURRET))
+    {
+      turret = new Turret();
+      this->getWeaponManager()->addWeapon(turret, 2);
+      this->getWeaponManager()->changeWeaponConfig(2);
+    }
+  }
+  else
+  {
+    //if (this->getWeaponManager()->hasFreeSlot(3))
+    {
+      turret = new AimingTurret();
+      this->getWeaponManager()->addWeapon(turret, 3);
+
+      this->getWeaponManager()->changeWeaponConfig(3);
+    }
+  }
+
+  if(turret != NULL)
+  {
+    turret->setName("Turret");
+    turret->setStateDuration(WS_SHOOTING, (float)rand()/RAND_MAX*.5+.1);
+  }
+}
Index: branches/network/src/world_entities/creatures/md2_creature.h
===================================================================
--- branches/network/src/world_entities/creatures/md2_creature.h	(revision 6636)
+++ branches/network/src/world_entities/creatures/md2_creature.h	(revision 6636)
@@ -0,0 +1,81 @@
+/*!
+ * @file md2_creature.h
+ * Implements the control of a md2 model
+ */
+
+#ifndef _MD2_CREATURE_H
+#define _MD2_CREATURE_H
+
+#include "playable.h"
+
+
+template<class T> class tList;
+class Vector;
+class Event;
+
+class MD2Creature : public Playable
+{
+
+  public:
+
+    MD2Creature();
+    MD2Creature(const char* fileName);
+    MD2Creature(const TiXmlElement* root);
+    virtual ~MD2Creature();
+
+    void init();
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual void enter();
+    virtual void leave();
+
+    virtual void postSpawn();
+    virtual void leftWorld();
+
+    virtual void collidesWith(WorldEntity* entity, const Vector& location);
+    virtual void tick(float time);
+    virtual void draw() const;
+
+    virtual void process(const Event &event);
+
+
+
+  private:
+
+    void calculateVelocity(float time);
+    void weaponAction();
+
+    // !! temporary !!
+    void ADDWEAPON();
+
+    bool                  bUp;                //!< up button pressed.
+    bool                  bDown;              //!< down button pressed.
+    bool                  bLeft;              //!< left button pressed.
+    bool                  bRight;             //!< right button pressed.
+    bool                  bAscend;            //!< ascend button pressed.
+    bool                  bDescend;           //!< descend button presses.
+    bool                  bFire;              //!< fire button pressed.
+    bool                  bRollL;             //!< rolling button pressed (left)
+    bool                  bRollR;             //!< rolling button pressed (right)
+    bool                  bStrafeL;           //!< strafe to the left side
+    bool                  bStrafeR;           //!< strafe to the rith side
+    bool                  bJump;              //!< jump
+
+    PNode                 cameraConnNode;     //!< The Node the camera is connected to.
+
+    float                 xMouse;             //!< mouse moved in x-Direction
+    float                 yMouse;             //!< mouse moved in y-Direction
+    float                 mouseSensitivity;   //!< the mouse sensitivity
+    float                 cycle;              //!< hovercycle
+
+    Vector                velocity;           //!< the velocity of the player.
+    Quaternion            mouseDirX;           //!< the direction where the player wants to fly
+    Quaternion            mouseDirY;           //!< the direction where the player wants to fly
+    float                 travelSpeed;        //!< the current speed of the player (to make soft movement)
+    float                 acceleration;       //!< the acceleration of the player.
+
+    float                 airViscosity;
+
+};
+
+#endif /* _MD2_CREATURE_H */
Index: branches/network/src/world_entities/environment.cc
===================================================================
--- branches/network/src/world_entities/environment.cc	(revision 6636)
+++ branches/network/src/world_entities/environment.cc	(revision 6636)
@@ -0,0 +1,83 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "environment.h"
+
+#include "resource_manager.h"
+
+#include "vector.h"
+#include "objModel.h"
+#include "obb_tree.h"
+#include "factory.h"
+
+using namespace std;
+CREATE_FACTORY(Environment, CL_ENVIRONMENT);
+
+/**
+ *  creates an environment
+*/
+Environment::Environment () : WorldEntity()
+{
+  this->init();
+  this->loadModel("models/ships/bolido.obj");
+}
+
+/**
+ * create an environment out of a XML-element
+ * @param root the XML-element to load the Environment from
+ */
+Environment::Environment(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  deletes an environment
+*/
+Environment::~Environment ()
+{}
+
+/**
+ * initialize an Environment
+ */
+void Environment::init()
+{
+  this->setClassID(CL_ENVIRONMENT, "Environment");
+  this->toList(OM_ENVIRON);
+}
+
+/**
+ * loads the Settings of an Environment from an XML-element.
+ * @param root the XML-element to load the ELements properties from
+ */
+void Environment::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+}
+
+
+/**
+ *  ticks the environment
+ * @param time the time about which to tick
+*/
+void Environment::tick (float time) {}
+
+
Index: branches/network/src/world_entities/environment.h
===================================================================
--- branches/network/src/world_entities/environment.h	(revision 6636)
+++ branches/network/src/world_entities/environment.h	(revision 6636)
@@ -0,0 +1,34 @@
+/*!
+  \file environment.h
+  \brief This file handles the environment of the game
+*/
+
+#ifndef _ENVIRONEMENT_H
+#define _ENVIRONEMENT_H
+
+#include "world_entity.h"
+
+//! environment of orxonox
+/**
+   everything that does not interact with the player comes here
+   Environment is a container for all the worldEntities that are non-interactive
+*/
+class Environment : public WorldEntity
+{
+  friend class World;
+
+ public:
+  Environment ();
+  Environment (const TiXmlElement* root);
+  virtual ~Environment ();
+
+  void init();
+  virtual void loadParams(const TiXmlElement* root);
+
+
+
+  virtual void tick (float time);
+
+};
+
+#endif /* _ENVIRONEMENT_H */
Index: branches/network/src/world_entities/environments/water.cc
===================================================================
--- branches/network/src/world_entities/environments/water.cc	(revision 6636)
+++ branches/network/src/world_entities/environments/water.cc	(revision 6636)
@@ -0,0 +1,220 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "water.h"
+#include "factory.h"
+#include "load_param.h"
+
+#include "grid.h"
+#include "material.h"
+
+#include "resource_manager.h"
+#include "shader.h"
+
+#include "skybox.h"
+
+
+using namespace std;
+
+CREATE_FACTORY(Water, CL_WATER);
+
+
+Water::Water(const TiXmlElement* root)
+{
+  this->setClassID(CL_WATER, "Water");
+  this->toList(OM_ENVIRON);
+
+  this->resX = this->resY = 10;
+  this->sizeX = this->sizeY = 1.0f;
+  this->height = 0.5f;
+  this->grid = NULL;
+
+  this->velocities = NULL;
+  this->viscosity = 5;
+  this->cohesion = .0000000001;
+
+  if (root != NULL)
+    this->loadParams(root);
+
+  this->rebuildGrid();
+  this->waterMaterial = new Material();
+  this->waterShader = (Shader*)ResourceManager::getInstance()->load("shaders/water.vert", SHADER, RP_GAME, (void*)"shaders/water.frag");
+
+  this->grid->height(this->grid->columns()/2,this->grid->rows()/2) = 100;
+}
+
+Water::~Water()
+{
+  delete this->grid;
+  delete this->waterMaterial;
+}
+
+void Water::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+
+  LoadParam(root, "size", this, Water, setSize)
+      .describe("the size of the WaterSurface")
+      .defaultValues(2, 1.0f, 1.0f);
+
+  LoadParam(root, "resolution", this, Water, setResolution)
+      .describe("sets the resolution of the water surface")
+      .defaultValues(2, 10, 10);
+
+  LoadParam(root, "height", this, Water, setHeight)
+      .describe("the height of the Waves")
+      .defaultValues(1, 0.5f);
+}
+
+void Water::rebuildGrid()
+{
+  if (this->velocities != NULL)
+  {
+    assert (this->grid != NULL);
+    for (unsigned int i = 0; i < this->grid->rows(); i++)
+      delete[] this->velocities[i];
+    delete[] this->velocities;
+  }
+
+//   WE DO NOT NEED THIS AS IT IS DONE IN WORLDENTITY->setModel();
+//   if (this->grid != NULL)
+//     this->grid = NULL;
+
+  this->grid = new Grid(this->sizeX, this->sizeY, this->resX, this->resY);
+  this->velocities = new float*[this->resX];
+  for (unsigned int i = 0; i < this->grid->rows(); i++)
+  {
+    this->velocities[i] = new float[this->resY];
+    for (unsigned int j = 0; j < this->resY; j++)
+      this->velocities[i][j] = 0.0;
+  }
+  this->setModel(this->grid, 0);
+}
+
+void Water::setResolution(unsigned int resX, unsigned int resY)
+{
+  this->resX = resX;
+  this->resY = resY;
+}
+
+void Water::setSize(float sizeX, float sizeY)
+{
+  this->sizeX = sizeX;
+  this->sizeY = sizeY;
+}
+
+void Water::setHeight(float height)
+{
+  this->height = height;
+}
+
+
+void Water::draw() const
+{
+  //SkyBox::enableCubeMap();
+
+  glBindTexture(GL_TEXTURE_2D, 15);
+  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
+
+  glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+  glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+  glEnable(GL_TEXTURE_GEN_S);
+  glEnable(GL_TEXTURE_GEN_T);
+
+  glEnable(GL_BLEND);
+  glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+  // this->waterShader->activateShader();
+//  this->waterMaterial->select();
+  WorldEntity::draw();
+  //Shader::deactivateShader();
+
+  SkyBox::disableCubeMap();
+}
+
+void Water::tick(float dt)
+{
+/*
+    THE OLD USELESS ALGORITHM
+  phase += dt *.1;
+  for (unsigned int i = 0; i < this->grid->rows(); i++)
+  {
+    for (unsigned int j = 0; j < this->grid->columns(); j++)
+    {
+      this->grid->height(i,j) = this->height*sin(((float)i/(float)this->grid->rows() *phase)+
+          this->height*cos((float)j/(float)this->grid->columns()) * phase * 2.0);
+    }
+  }
+  this->grid->rebuildNormals(this->height);*/
+
+
+  unsigned int i, j;
+  float u;
+
+  // wave/advection
+  // calc movement
+  for(j = 1; j < this->grid->rows() - 1; j++) {
+    for(i = 1; i < this->grid->columns() - 1; i++) {
+      u =  this->grid->height(i+1,j)+ this->grid->height(i-1, j) +
+          this->grid->height(i, j+1) + this->grid->height(i, j-1) -
+          4 * this->grid->height(i, j);
+      this->velocities[i][j] += dt * this->viscosity * this->viscosity * u / this->height;
+      this->grid->height(i, j) += dt * this->velocities[i][j];
+    }
+  }
+/*  // advect
+  for(j = 1; j < this->grid->rows() - 1; j++) {
+    for(i = 1; i < this->grid->columns() - 1; i++) {
+      this->grid->height(i, j) += dt * this->velocities[i][j];
+    }
+  }*/
+  // bound
+//   unsigned int w = this->grid->columns - 1;
+//   for(i = 0; i < this->grid->columns; i++) {
+//     _map[i][0].u[1] = _map[i][1  ].u[1];
+//     _map[i][w].u[1] = _map[i][w-1].u[1];
+//     _map[0][i].u[1] = _map[1  ][i].u[1];
+//     _map[w][i].u[1] = _map[w-1][i].u[1];
+//   }
+
+  // diffusion
+  for(j = 1; j < this->grid->rows() - 1; j++) {
+    for(i = 1; i < this->grid->columns() - 1 ; i++) {
+      u = this->grid->height(i+1, j) + this->grid->height(i-1, j) +
+          this->grid->height(i, j+1) + this->grid->height(i, j-1) -
+          4* this->grid->height(i, j);
+      this->grid->height(i,j) += dt * this->cohesion * u / this->height;
+    }
+  }
+
+  // calc normals
+//   float l[3];
+//   float m[3];
+//   for(j = 1; j < this->grid->rows() -1; j++) {
+//     for(i = 1; i < this->grid->columns() - 1; i++) {
+//       l[0] = this->grid->vertexG(i, j-1).x - this->grid->vertexG(i, j+1).x;
+//       l[1] = this->grid->vertexG(i, j-1).y - this->grid->vertexG(i, j+1).y;
+//       l[2] = this->grid->vertexG(i, j-1).z - this->grid->vertexG(i, j+1).z;
+//       m[0] = this->grid->vertexG(i-1,j).x - this->grid->vertexG(i+1, j).x;
+//       m[1] = this->grid->vertexG(i-1,j).y - this->grid->vertexG(i+1, j).y;
+//       m[2] = this->grid->vertexG(i-1,j).z - this->grid->vertexG(i+1, j).z;
+//       this->grid->normalG(i, j).x = l[1] * m[2] - l[2] * m[1];
+//       this->grid->normalG(i, j).y = l[2] * m[0] - l[0] * m[2];
+//       this->grid->normalG(i, j).z = l[0] * m[1] - l[1] * m[0];
+//     }
+//   }
+  this->grid->rebuildNormals(this->height);
+}
Index: branches/network/src/world_entities/environments/water.h
===================================================================
--- branches/network/src/world_entities/environments/water.h	(revision 6636)
+++ branches/network/src/world_entities/environments/water.h	(revision 6636)
@@ -0,0 +1,56 @@
+/*!
+ * @file water.h
+ *  Definition of the SkyBox, that handles the Display of an atmosphere for orxonox.
+ *
+ * A SkyBox is always centered at the current working Camera, and will only obey the cameras
+ * movment but not its rotation.
+*/
+
+#ifndef _WATER_H
+#define _WATER_H
+
+/* INCLUDES */
+#include "world_entity.h"
+
+/* FORWARD DECLARATION */
+class Material;
+class Grid;
+class Shader;
+
+//! A Class to handle a WaterEffects
+class Water : public WorldEntity
+{
+ public:
+   Water(const TiXmlElement* root = NULL);
+   ~Water();
+
+   void loadParams(const TiXmlElement* root);
+
+   void setResolution(unsigned int resX, unsigned int resY);
+   void setSize(float sizeX, float sizeY);
+   void setHeight(float height);
+   void rebuildGrid();
+
+   void draw() const;
+   void tick(float dt);
+
+  private:
+    Grid*           grid;            //!< The water-surface-model to render with
+    float**         velocities;      //!< Velocities.
+    float           viscosity;       //!< Viscosity (bigger more like honey, smaller more like water).
+    float           cohesion;        //!< Cohesion.
+
+    Material*       waterMaterial;
+    Shader*         waterShader;
+    float           height;          //!< The hight of the Water
+
+    unsigned int    resX, resY;
+    float           sizeX, sizeY;
+
+    float phase;
+};
+
+#endif  /* _WATER_H */
+
+
+
Index: branches/network/src/world_entities/extendable.h
===================================================================
--- branches/network/src/world_entities/extendable.h	(revision 6636)
+++ branches/network/src/world_entities/extendable.h	(revision 6636)
@@ -0,0 +1,30 @@
+/*!
+ * @file proto_class.h
+ * @brief Interface for Worldentities that can picku up powerups.
+*/
+
+#ifndef _EXTENDABLE_H
+#define _EXTENDABLE_H
+
+#include "base_object.h"
+
+// FORWARD DECLARATION
+class PowerUp;
+
+#include "power_ups/power_up.h"
+
+//! A class for ...
+class Extendable : virtual public BaseObject {
+
+  public:
+   //   virtual ~Extendable();
+   virtual bool pickup(PowerUp* powerUp) { return false; };
+
+  protected:
+    Extendable() { this->setClassID(CL_EXTENDABLE, "Extendable"); };
+
+  private:
+
+};
+
+#endif /* _EXTENDABLE_H */
Index: branches/network/src/world_entities/image_entity.cc
===================================================================
--- branches/network/src/world_entities/image_entity.cc	(revision 6636)
+++ branches/network/src/world_entities/image_entity.cc	(revision 6636)
@@ -0,0 +1,184 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "image_entity.h"
+
+#include "load_param.h"
+#include "factory.h"
+
+#include "graphics_engine.h"
+#include "material.h"
+#include "glincl.h"
+#include "state.h"
+
+
+using namespace std;
+
+
+CREATE_FACTORY(ImageEntity, CL_IMAGE_ENTITY);
+
+
+/**
+ * standart constructor
+ */
+ImageEntity::ImageEntity (const TiXmlElement* root)
+{
+  this->init();
+  this->loadParams(root);
+}
+
+
+/**
+ * destroys a ImageEntity
+*/
+ImageEntity::~ImageEntity ()
+{
+  if (this->material)
+  delete this->material;
+
+  // delete what has to be deleted here
+
+  GraphicsEngine::showMouse(true);
+  GraphicsEngine::stealWMEvents(false);
+}
+
+
+/**
+ * initializes the ImageEntity
+ */
+void ImageEntity::init()
+{
+  this->setClassID(CL_IMAGE_ENTITY, "ImageEntity");
+  this->setName("ImageEntity");
+
+  this->setLayer(E2D_LAYER_TOP);
+  this->setRotationSpeed(5);
+  this->setSize(GraphicsEngine::getInstance()->getResolutionX()/10.0, GraphicsEngine::getInstance()->getResolutionY()/10.0);
+
+  this->setBindNode(this);
+  this->material = new Material;
+  this->setTexture("pictures/error_texture.png");
+  this->bBillboarding = false;
+}
+
+
+void ImageEntity::loadParams(const TiXmlElement* root)
+{
+  static_cast<PNode*>(this)->loadParams(root);
+
+  LoadParam(root, "texture", this, ImageEntity, setTexture)
+      .describe("the texture-file to load onto the ImageEntity");
+
+  LoadParam(root, "size", this, ImageEntity, setSize)
+      .describe("the size of the ImageEntity in Pixels");
+
+  LoadParam(root, "rotation-speed", this, ImageEntity, setRotationSpeed)
+      .describe("the Speed with which the ImageEntity should rotate");
+
+  LoadParam(root, "billboarding", this, ImageEntity, toggleBillboard)
+      .describe("sets the ImageEntity to always look in the direction of the Player");
+}
+
+
+/**
+ * sets the size of the ImageEntity.
+ * @param size the size in pixels
+ */
+void ImageEntity::setSize(float sizeX, float sizeY)
+{
+  this->setSize2D(sizeX, sizeY);
+}
+
+
+/**
+ * sets the material to load
+ * @param textureFile The texture-file to load onto the crosshair
+ */
+void ImageEntity::setTexture(const char* textureFile)
+{
+  this->material->setDiffuseMap(textureFile);
+}
+
+
+/** this turns on/off the billboarding of this WorldEntity
+ *
+ * This means that the image will always look in the direction of the Player
+ */
+void ImageEntity::toggleBillboard()
+{
+  this->bBillboarding = !this->bBillboarding;
+}
+
+
+/**
+ * ticks the ImageEntity
+ * @param dt the time to ticks
+ */
+void ImageEntity::tick(float dt)
+{
+  // let the crosshair rotate
+  //this->shiftDir2D(dt * rotationSpeed);
+
+
+  float z = 0.0f;
+  glReadPixels ((int)this->getAbsCoor2D().x,
+                 GraphicsEngine::getInstance()->getResolutionY()-(int)this->getAbsCoor2D().y-1,
+                 1,
+                 1,
+                 GL_DEPTH_COMPONENT,
+                 GL_FLOAT,
+                 &z);
+
+
+  GLdouble objX=.0, objY=.0, objZ=.0;
+  gluUnProject(this->getAbsCoor2D().x,
+               GraphicsEngine::getInstance()->getResolutionY()-this->getAbsCoor2D().y-1,
+               .99,  // z
+               GraphicsEngine::modMat,
+               GraphicsEngine::projMat,
+               GraphicsEngine::viewPort,
+               &objX,
+               &objY,
+               &objZ );
+
+  //this->setAbsCoor(objX, objY, objZ);
+}
+
+
+/**
+ * draws the crosshair
+ */
+void ImageEntity::draw() const
+{
+  glPushMatrix();
+  glTranslatef(this->getAbsCoor2D().x, this->getAbsCoor2D().y, 0);
+
+  //glRotatef(this->getAbsDir2D(), 0,0,1);
+  this->material->select();
+  glBegin(GL_TRIANGLE_STRIP);
+  glTexCoord2f(0, 0);
+  glVertex2f(-this->getSizeX2D(), -this->getSizeY2D());
+  glTexCoord2f(1, 0);
+  glVertex2f(this->getSizeX2D(), -this->getSizeY2D());
+  glTexCoord2f(0, 1);
+  glVertex2f(-this->getSizeX2D(), this->getSizeY2D());
+  glTexCoord2f(1, 1);
+  glVertex2f(this->getSizeX2D(), this->getSizeY2D());
+  glEnd();
+  glPopMatrix();
+
+}
Index: branches/network/src/world_entities/image_entity.h
===================================================================
--- branches/network/src/world_entities/image_entity.h	(revision 6636)
+++ branches/network/src/world_entities/image_entity.h	(revision 6636)
@@ -0,0 +1,47 @@
+/*!
+ * @file crosshair.h
+  *  Definition of ...
+
+*/
+
+#ifndef _IMAGE_ENTITY_H
+#define _IMAGE_ENTITY_H
+
+#include "p_node.h"
+#include "element_2d.h"
+#include "event_listener.h"
+
+#include "vector.h"
+
+
+// FORWARD DECLARATION
+class Model;
+class Material;
+class TiXmlElement;
+
+//! A class that enables the
+class ImageEntity : public PNode, public Element2D {
+
+ public:
+  ImageEntity(const TiXmlElement* root = NULL);
+  virtual ~ImageEntity();
+
+  void init();
+  void loadParams(const TiXmlElement* root);
+
+  void setSize(float sizeX, float sizeY);
+  void setTexture(const char* textureFile);
+  /** @param rotationSpeed the speed at what the crosshair should rotate */
+  void setRotationSpeed(float rotationSpeed) { this->rotationSpeed = rotationSpeed; };
+  void toggleBillboard();
+
+  virtual void tick(float dt);
+  virtual void draw() const;
+
+ private:
+   Material*        material;             //!< a material for the Aim.
+   float            rotationSpeed;        //!< Speed of the Rotation.
+   bool             bBillboarding;        //!< true if billboarding is on
+};
+
+#endif /* _IMAGE_ENTITY_H */
Index: branches/network/src/world_entities/movie_entity.cc
===================================================================
--- branches/network/src/world_entities/movie_entity.cc	(revision 6636)
+++ branches/network/src/world_entities/movie_entity.cc	(revision 6636)
@@ -0,0 +1,152 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2005 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: David Hasenfratz, Stefan Lienhard
+   co-programmer:
+*/
+
+#include "movie_entity.h"
+
+#include "media_container.h"
+#include "load_param.h"
+#include "factory.h"
+
+#include "network_game_manager.h"
+#include "converter.h"
+
+using namespace std;
+
+CREATE_FACTORY(MovieEntity, CL_MOVIE_ENTITY);
+
+/**
+ *  standard constructor
+ */
+MovieEntity::MovieEntity (const TiXmlElement* root)
+{
+  this->setClassID(CL_MOVIE_ENTITY, "MovieEntity");
+
+  media_container = new MediaContainer();
+
+  axis = 0;
+  rotation = 0;
+  height = 20;
+  width = 20;
+
+  this->toList(OM_COMMON);
+
+  this->loadParams(root);
+
+  counter = 0;
+  timer = 0;
+  fps = media_container->getFPS();
+}
+
+/**
+ *  standard destructor
+ */
+MovieEntity::~MovieEntity ()
+{
+  delete this->media_container;
+}
+
+void MovieEntity::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+
+  LoadParam(root, "name", this, MovieEntity, loadMovie);
+  LoadParam(root, "axis", this, MovieEntity, setAxis);
+  LoadParam(root, "rotation", this, MovieEntity, setRotation);
+  LoadParam(root, "size", this, MovieEntity, setSize);
+}
+
+void MovieEntity::loadMovie(const char* filename)
+{
+  media_container->loadMedia(filename);
+}
+
+void MovieEntity::setAxis(float axis)
+{
+  this->axis = axis;
+}
+
+// Seconds for one loop
+void MovieEntity::setRotation(float rotation)
+{
+  this->rotation = rotation;
+}
+
+void MovieEntity::setSize(float width, float height)
+{
+  this->width = width;
+  this->height = height;
+}
+
+/**
+ *  this method is called every frame
+ * @param time: the time in seconds that has passed since the last tick
+
+   Handle all stuff that should update with time inside this method (movement, animation, etc.)
+ */
+void MovieEntity::tick(float time)
+{
+  timer += time;
+
+  if(counter != fps * timer)
+  {
+    counter = (int)(fps * timer);
+
+    if (counter >= media_container->getFrameCount())
+    {
+      timer = 0;
+      counter = 0;
+    }
+  }
+
+  if(rotation != 0)
+    axis = (int)(axis + (time * 360/rotation))%360;
+}
+
+
+/**
+ *  the entity is drawn onto the screen with this function
+
+   This is a central function of an entity: call it to let the entity painted to the screen. Just override this function with whatever you want to be drawn.
+ */
+void MovieEntity::draw() const
+{
+
+  glPushMatrix();
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+  glRotatef(axis, 0.0f, 1.0f, 0.0f);
+//PRINTF(0)("axis: %f\n", axis);
+
+  glPushAttrib(GL_ENABLE_BIT);
+  glDisable(GL_LIGHTING);
+
+  glEnable(GL_TEXTURE_2D);
+  glBindTexture(GL_TEXTURE_2D, media_container->getFrameTexture(counter));
+
+  glColor3f(1.0, 1.0, 1.0);
+
+  glBegin(GL_QUADS);
+    glTexCoord2f(1.0f, 1.0f); glVertex3f(-width/2, -height/2,  0.0f);
+    glTexCoord2f(0.0f, 1.0f); glVertex3f( width/2, -height/2,  0.0f);
+    glTexCoord2f(0.0f, 0.0f); glVertex3f( width/2,  height/2,  0.0f);
+    glTexCoord2f(1.0f, 0.0f); glVertex3f(-width/2,  height/2,  0.0f);
+  glEnd();
+
+  glPopAttrib();
+
+  glPopMatrix();
+
+}
Index: branches/network/src/world_entities/movie_entity.h
===================================================================
--- branches/network/src/world_entities/movie_entity.h	(revision 6636)
+++ branches/network/src/world_entities/movie_entity.h	(revision 6636)
@@ -0,0 +1,44 @@
+/*!
+ * @file movie_entity.h
+ *  Definition of a Movie Screen
+ */
+
+#ifndef _MOVIE_ENTITY_H
+#define _MOVIE_ENTITY_H
+
+#include "world_entity.h"
+
+
+class MediaContainer;
+
+class MovieEntity : public WorldEntity
+{
+  private:
+    MediaContainer* media_container;
+
+    int counter;
+    float timer;
+    float fps;
+
+    float axis;
+    float rotation;
+    float height;
+    float width;
+
+  public:
+    MovieEntity (const TiXmlElement* root = NULL);
+    ~MovieEntity ();
+
+    virtual void draw () const;
+    virtual void tick (float time);
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    void loadMovie(const char* filename);
+    void setAxis(float axis);
+    void setRotation(float rotation);
+    void setSize(float width, float height);
+
+};
+
+#endif /* _MOVIE_ENTITY_H */
Index: branches/network/src/world_entities/npcs/ground_turret.cc
===================================================================
--- branches/network/src/world_entities/npcs/ground_turret.cc	(revision 6636)
+++ branches/network/src/world_entities/npcs/ground_turret.cc	(revision 6636)
@@ -0,0 +1,215 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Manuel Leuenberger
+   co-programmer: ...
+*/
+
+#include "ground_turret.h"
+#include "model.h"
+#include "world_entities/weapons/turret.h"
+
+#include "factory.h"
+#include "network_game_manager.h"
+#include "load_param.h"
+
+CREATE_FACTORY(GroundTurret, CL_GROUND_TURRET);
+
+using namespace std;
+
+
+/**
+ * constructs and loads a GroundTurret from a XML-element
+ * @param root the XML-element to load from
+ */
+GroundTurret::GroundTurret(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+
+/**
+ * standard deconstructor
+ */
+GroundTurret::~GroundTurret ()
+{
+
+}
+
+
+/**
+ * initializes the GroundTurret
+ * @todo change this to what you wish
+ */
+void GroundTurret::init()
+{
+  this->setClassID(CL_GROUND_TURRET, "GroundTurret");
+  this->loadModel("models/ground_turret.obj", 5);
+  this->left = NULL;
+  this->right = NULL;
+
+  /*  left = new Turret();
+  left->setParent(this);
+  left->setRelCoor(0,10,0);
+  right = new Turret();
+  right->setParent(this);
+  right->setRelCoor(0,10,0);*/
+}
+
+
+/**
+ * loads a GroundTurret from a XML-element
+ * @param root the XML-element to load from
+ * @todo make the class Loadable
+ */
+void GroundTurret::loadParams(const TiXmlElement* root)
+{
+  // all the clases this Entity is directly derived from must be called in this way, to load all settings.
+  NPC::loadParams(root);
+
+
+  /**
+   * @todo: make the class Loadable
+   */
+  const TiXmlElement* element;
+
+  element = root->FirstChildElement("weapon-left");
+  if (element != NULL) element = element->FirstChildElement();
+  this->left = dynamic_cast<Weapon*>( Factory::fabricate( element) );
+  if (this->left)
+  {
+    this->left->setParent(this);
+    this->left->toList(this->getOMListNumber());
+    this->left->setRelCoor(0,10,-5);
+    this->left->requestAction( WA_ACTIVATE);
+  }
+
+  element = root->FirstChildElement("weapon-right");
+  if (element != NULL)  if (element != NULL) element = element->FirstChildElement();
+  this->right = dynamic_cast<Weapon*>( Factory::fabricate( element) );
+  if (this->right)
+  {
+    this->right->setParent(this);
+    this->right->toList(this->getOMListNumber());
+    this->right->setRelCoor(0,10,5);
+    this->left->requestAction( WA_ACTIVATE);
+  }
+}
+
+/**
+ * advances the GroundTurret about time seconds
+ * @param time the Time to step
+ */
+void GroundTurret::tick(float dt)
+{
+  if (likely(this->left != NULL))
+  {
+    this->left->tickW(dt);
+    this->left->requestAction(WA_SHOOT);
+  }
+  if (likely(this->right != NULL))
+  {
+    this->right->tickW(dt);
+    this->right->requestAction(WA_SHOOT);
+  }
+
+}
+
+/**
+ * draws this worldEntity
+ */
+void GroundTurret::draw () const
+{
+  WorldEntity::draw();
+
+  if (this->left != NULL)
+    this->left->draw();
+  if (this->right != NULL)
+    this->right->draw();
+}
+
+
+/**
+ *
+ *
+ */
+void GroundTurret::collidesWith (WorldEntity* entity, const Vector& location)
+{
+  if (entity->isA(CL_PROJECTILE))
+    this->setAbsDirSoft(Quaternion(-90, Vector(0,0,1)), 90);
+}
+
+/**
+ *
+ *
+ */
+void GroundTurret::postSpawn ()
+{
+
+}
+
+/**
+ *
+ *
+ */
+void GroundTurret::leftWorld ()
+{
+
+}
+
+/**
+ * Writes data from network containing information about the state
+ * @param data pointer to data
+ * @param length length of data
+ * @param sender hostID of sender
+ */
+int GroundTurret::writeBytes( const byte * data, int length, int sender )
+{
+  setRequestedSync( false );
+  setIsOutOfSync( false );
+
+  SYNCHELP_READ_BEGIN();
+
+  SYNCHELP_READ_FKT( WorldEntity::writeState );
+
+  return SYNCHELP_READ_N;
+}
+
+/**
+ * data copied in data will bee sent to another host
+ * @param data pointer to data
+ * @param maxLength max length of data
+ * @return the number of bytes writen
+ */
+int GroundTurret::readBytes( byte * data, int maxLength, int * reciever )
+{
+  SYNCHELP_WRITE_BEGIN();
+
+  if ( isOutOfSync() && !requestedSync() && this->getHostID()!=this->getOwner() )
+  {
+    (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
+    setRequestedSync( true );
+  }
+
+  int rec = this->getRequestSync();
+  if ( rec > 0 )
+  {
+    *reciever = rec;
+
+    SYNCHELP_WRITE_FKT( WorldEntity::readState );
+
+  }
+
+  *reciever = 0;
+  return SYNCHELP_WRITE_N;
+}
Index: branches/network/src/world_entities/npcs/ground_turret.h
===================================================================
--- branches/network/src/world_entities/npcs/ground_turret.h	(revision 6636)
+++ branches/network/src/world_entities/npcs/ground_turret.h	(revision 6636)
@@ -0,0 +1,39 @@
+/*!
+ * @file ground_turret.h
+ * @brief description
+*/
+
+#ifndef _GROUND_TURRET_H
+#define _GROUND_TURRET_H
+
+#include "npcs/npc.h"
+
+class Weapon;
+
+//! A Class to ...
+class GroundTurret : public NPC
+{
+
+ public:
+  GroundTurret(const TiXmlElement* root = NULL);
+  virtual ~GroundTurret();
+
+  void init();
+  virtual void loadParams(const TiXmlElement* root);
+
+  virtual void postSpawn ();
+  virtual void leftWorld ();
+
+
+  virtual void draw() const;
+  virtual void tick(float time);
+  virtual void collidesWith (WorldEntity* entity, const Vector& location);
+
+  virtual int writeBytes(const byte* data, int length, int sender);
+  virtual int readBytes(byte* data, int maxLength, int * reciever);
+
+ private:
+   Weapon *left, *right;
+};
+
+#endif /* _GROUND_TURRET_H */
Index: branches/network/src/world_entities/npcs/npc.cc
===================================================================
--- branches/network/src/world_entities/npcs/npc.cc	(revision 6636)
+++ branches/network/src/world_entities/npcs/npc.cc	(revision 6636)
@@ -0,0 +1,72 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "npc.h"
+#include "obb_tree.h"
+
+#include "state.h"
+#include "stdlibincl.h"
+#include "power_ups/turret_power_up.h"
+#include "power_ups/laser_power_up.h"
+
+using namespace std;
+
+
+NPC::NPC()
+{
+  this->setClassID(CL_NPC, "NPC");
+  this->toList(OM_GROUP_00);
+}
+
+
+NPC::~NPC () {}
+
+
+void NPC::collidesWith(WorldEntity* entity, const Vector& location)
+{
+  if (entity->isA(CL_PROJECTILE) && entity != this->collider)
+  {
+//    PRINTF(3)("collision %s vs %s @ (%f,%f,%f)\n", this->getName(), entity->getName(), location.x, location.y, location.z);
+//    this->applyForce(Vector(0,0,0)-location*1000);
+    if ((float)rand()/RAND_MAX < .3)
+    {
+      WorldEntity* powerUp = new TurretPowerUp();
+      powerUp->setAbsCoor(this->getAbsCoor());
+//      powerUp->toList(OM_COMMON);
+    }
+    else if ((float)rand()/RAND_MAX < .3)
+    {
+      WorldEntity* powerUp = new LaserPowerUp();
+      powerUp->setAbsCoor(this->getAbsCoor());
+      powerUp->toList(OM_COMMON);
+    }
+    this->toList(OM_DEAD);
+    this->removeNode();
+
+      this->collider = entity;
+  }
+  //  else if (entity->isA(CL_PLAYER))
+  //    this->applyForce(Vector(0,0,0)-location*100);
+  else if (entity->isA(CL_NPC))
+  {
+    this->setVisibiliy(false);
+    this->toList(OM_DEAD);
+    this->removeNode();
+  }
+}
Index: branches/network/src/world_entities/npcs/npc.h
===================================================================
--- branches/network/src/world_entities/npcs/npc.h	(revision 6636)
+++ branches/network/src/world_entities/npcs/npc.h	(revision 6636)
@@ -0,0 +1,28 @@
+
+#ifndef _NPC_H
+#define _NPC_H
+
+#include "world_entity.h"
+#include "physics_interface.h"
+
+class AI;
+
+class NPC : public WorldEntity {
+
+ public:
+  NPC ();
+  ~NPC ();
+
+
+  void addAI(AI* ai);
+
+  virtual void collidesWith (WorldEntity* entity, const Vector& location);
+
+
+ private:
+
+   WorldEntity* collider;
+
+};
+
+#endif /* _NPC_H */
Index: branches/network/src/world_entities/npcs/npc_test.cc
===================================================================
--- branches/network/src/world_entities/npcs/npc_test.cc	(revision 6636)
+++ branches/network/src/world_entities/npcs/npc_test.cc	(revision 6636)
@@ -0,0 +1,103 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "npc_test.h"
+#include "obb_tree.h"
+
+#include "shader.h"
+#include "state.h"
+#include "stdlibincl.h"
+#include "debug.h"
+
+
+using namespace std;
+
+
+NPC2::NPC2()
+{
+  this->setClassID(CL_NPC_TEST2, "NPC2");
+
+  if ((float)rand()/RAND_MAX > .5f)
+    this->loadModel("models/ships/bolido.obj", 3);
+  else
+    this->loadModel("models/ships/gobblin.obj", 3);
+
+  this->shader = NULL;
+  if (likely(Shader::checkShaderAbility()))
+    this->shader = Shader::getShader("shaders/toon.vert", "shaders/toon.frag");
+
+  this->obj = gluNewQuadric();
+
+  this->randomRotAxis = VECTOR_RAND(1);
+}
+
+
+NPC2::~NPC2 ()
+{
+  if (this->shader)
+    Shader::unload(this->shader);
+  gluDeleteQuadric(this->obj);
+}
+
+
+
+/**
+ *  the entity is drawn onto the screen with this function
+ *
+ * This is a central function of an entity: call it to let the entity painted to the screen.
+ * Just override this function with whatever you want to be drawn.
+ */
+void NPC2::draw() const
+{
+//   glMatrixMode(GL_MODELVIEW);
+//   glPushMatrix();
+//   float matrix[4][4];
+//
+//   /* translate */
+//   glTranslatef (this->getAbsCoor ().x,
+//                 this->getAbsCoor ().y,
+//                 this->getAbsCoor ().z);
+//   /* rotate */
+//   this->getAbsDir ().matrix (matrix);
+//   glMultMatrixf((float*)matrix);
+//
+//   if (this->shader != NULL && this->shader != Shader::getActiveShader())
+//     shader->activateShader();
+//   gluSphere(this->obj, 3, 10, 10);
+//   shader->deactivateShader();
+//
+//
+// /*  if (this->model)
+//     this->model->draw();*/
+//   glPopMatrix();
+}
+
+
+void NPC2::tick(float dt)
+{
+//  Vector direction = (State::getCameraTarget()->getAbsCoor() - this->getAbsCoor());
+
+  //if (directin.len() < 100)
+//  this->shiftCoor(direction *dt * 5 * exp(-direction.len() / 30.0));
+  this->shiftDir(Quaternion(dt, this->randomRotAxis));
+
+}
+
+
+
Index: branches/network/src/world_entities/npcs/npc_test.h
===================================================================
--- branches/network/src/world_entities/npcs/npc_test.h	(revision 6636)
+++ branches/network/src/world_entities/npcs/npc_test.h	(revision 6636)
@@ -0,0 +1,29 @@
+
+#ifndef _NPC22_H
+#define _NPC2_H
+
+#include "npc.h"
+
+class AI;
+class Shader;
+
+class NPC2 : public NPC {
+
+ public:
+  NPC2 ();
+  ~NPC2 ();
+
+
+  void addAI(AI* ai);
+
+  virtual void tick(float dt);
+  virtual void draw() const;
+
+ private:
+   Vector   randomRotAxis;
+   Shader*  shader;
+   GLUquadricObj* obj;
+
+};
+
+#endif /* _NPC2_H */
Index: branches/network/src/world_entities/npcs/npc_test1.cc
===================================================================
--- branches/network/src/world_entities/npcs/npc_test1.cc	(revision 6636)
+++ branches/network/src/world_entities/npcs/npc_test1.cc	(revision 6636)
@@ -0,0 +1,53 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "npc_test1.h"
+#include "obb_tree.h"
+
+#include "state.h"
+#include "power_ups/turret_power_up.h"
+#include "power_ups/laser_power_up.h"
+
+using namespace std;
+
+
+NPCTest1::NPCTest1()
+{
+  this->setClassID(CL_NPC_TEST1, "NPCTest1");
+
+  if ((float)rand()/RAND_MAX > .5f)
+    this->loadModel("models/ships/bolido.obj", 2);
+  else
+    this->loadModel("models/ships/gobblin.obj", 2);
+
+  this->randomRotAxis =  VECTOR_RAND(1).getNormalized();
+}
+
+
+NPCTest1::~NPCTest1 () {}
+
+
+
+void NPCTest1::tick(float dt)
+{
+  this->shiftDir(Quaternion(dt, this->randomRotAxis));
+}
+
+
+
Index: branches/network/src/world_entities/npcs/npc_test1.h
===================================================================
--- branches/network/src/world_entities/npcs/npc_test1.h	(revision 6636)
+++ branches/network/src/world_entities/npcs/npc_test1.h	(revision 6636)
@@ -0,0 +1,27 @@
+
+#ifndef _NPC_Test1_H
+#define _NPC_Test1_H
+
+#include "npc.h"
+
+class AI;
+
+class NPCTest1 : public NPC {
+
+ public:
+  NPCTest1 ();
+  ~NPCTest1 ();
+
+
+  void addAI(AI* ai);
+
+  virtual void tick(float dt);
+
+ private:
+   Vector   randomRotAxis;
+
+   WorldEntity* collider;
+
+};
+
+#endif /* _NPC_Test1_H */
Index: branches/network/src/world_entities/planet.cc
===================================================================
--- branches/network/src/world_entities/planet.cc	(revision 6636)
+++ branches/network/src/world_entities/planet.cc	(revision 6636)
@@ -0,0 +1,182 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "planet.h"
+
+#include "load_param.h"
+#include "factory.h"
+#include "static_model.h"
+
+#include "material.h"
+#include "texture.h"
+
+#include "network_game_manager.h"
+#include "converter.h"
+
+using namespace std;
+
+
+CREATE_FACTORY(Planet, CL_PLANET);
+
+
+
+/**
+ *  initializes a skybox from a XmlElement
+*/
+Planet::Planet(const TiXmlElement* root)
+{
+  this->setClassID(CL_PLANET, "Planet");
+  this->toList(OM_GROUP_01);
+
+  this->material = new Material();
+  this->material->setIllum(10);
+
+  this->loadParams(root);
+}
+
+
+/**
+ *  default destructor
+*/
+Planet::~Planet()
+{
+  PRINTF(5)("Deleting Planet\n");
+  if( this->material)
+    delete this->material;
+}
+
+
+void Planet::loadParams(const TiXmlElement* root)
+{
+  static_cast<WorldEntity*>(this)->loadParams(root);
+
+  LoadParam(root, "texture", this, Planet, setTexture)
+      .describe("Sets the material on the Planet. The string must be the path relative to the data-dir, and without a trailing .jpg");
+
+  LoadParam(root, "size", this, Planet, setSize)
+      .describe("Sets the Size of the Planet (normally this should be 90% of the maximal viewing Distance).");
+}
+
+
+/**
+ *  Defines which textures should be loaded onto the Planet.
+ * @param textureName the top texture.
+*/
+void Planet::setTexture(const char* textureName)
+{
+  this->material->setDiffuseMap(textureName);
+}
+
+
+/**
+ * @param size The new size of the Planet
+
+ * do not forget to rebuild the Planet after this.
+*/
+void Planet::setSize(float size)
+{
+  this->size = size;
+}
+
+
+
+void Planet::draw() const
+{
+
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+
+  /* translate */
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+
+
+  this->material->select();
+
+
+  Vector c;
+  double r = this->size;
+  int n = 200;
+  int method = 1;
+  double theta1 = 0;
+  double theta2 = 2 * M_PI;
+  double phi1 = -M_PI/2.0;
+  double phi2 = M_PI/2.0;
+
+
+  int i,j;
+  double jdivn,j1divn,idivn,dosdivn,unodivn=1/(double)n,ndiv2=(double)n/2,t1,t2,t3,cost1,cost2,cte1,cte3;
+  cte3 = (theta2-theta1)/n;
+  cte1 = (phi2-phi1)/ndiv2;
+  dosdivn = 2*unodivn;
+  Vector e,p,e2,p2;
+
+
+  t2=phi1;
+  cost2=cos(phi1);
+  j1divn=0;
+  for (j=0;j<ndiv2;j++) {
+    t1 = t2;//t1 = phi1 + j * cte1;
+    t2 += cte1;//t2 = phi1 + (j + 1) * cte1;
+    t3 = theta1 - cte3;
+    cost1 = cost2;//cost1=cos(t1);
+    cost2 = cos(t2);
+    e.y = sin(t1);
+    e2.y = sin(t2);
+    p.y = c.y + r * e.y;
+    p2.y = c.y + r * e2.y;
+
+    if (method == 0)
+      glBegin(GL_QUAD_STRIP);
+    else
+      glBegin(GL_TRIANGLE_STRIP);
+
+    idivn=0;
+    jdivn=j1divn;
+    j1divn+=dosdivn;//=2*(j+1)/(double)n;
+    for (i=0;i<=n;i++) {
+       //t3 = theta1 + i * (theta2 - theta1) / n;
+      t3 += cte3;
+      e.x = cost1 * cos(t3);
+       //e.y = sin(t1);
+      e.z = cost1 * sin(t3);
+      p.x = c.x + r * e.x;
+       //p.y = c.y + r * e.y;
+      p.z = c.z + r * e.z;
+      glNormal3f(e.x,e.y,e.z);
+      glTexCoord2f(idivn,jdivn);
+      glVertex3f(p.x,p.y,p.z);
+
+
+      e2.x = cost2 * cos(t3);
+       //e.y = sin(t2);
+      e2.z = cost2 * sin(t3);
+      p2.x = c.x + r * e2.x;
+       //p.y = c.y + r * e.y;
+      p2.z = c.z + r * e2.z;
+      glNormal3f(e2.x,e2.y,e2.z);
+      glTexCoord2f(idivn,j1divn);
+      glVertex3f(p2.x,p2.y,p2.z);
+      idivn += unodivn;
+    }
+    glEnd();
+  }
+}
+
+
+
Index: branches/network/src/world_entities/planet.h
===================================================================
--- branches/network/src/world_entities/planet.h	(revision 6636)
+++ branches/network/src/world_entities/planet.h	(revision 6636)
@@ -0,0 +1,48 @@
+/*!
+ * @file planet.h
+ *  Definition of the Planet, that handles the Display of an atmosphere for orxonox.
+ */
+
+#ifndef _PLANET_H
+#define _PLANET_H
+
+/* INCLUDES */
+#include "world_entity.h"
+
+/* FORWARD DECLARATION */
+class Material;
+class Texture;
+
+//! A Class to handle a Planet
+class Planet : public WorldEntity
+{
+ public:
+  Planet(const TiXmlElement* root);
+
+  virtual ~Planet();
+
+  void loadParams(const TiXmlElement* root);
+
+  void setSize(float size);
+  /** assumes jpg as input-format */
+  void setTexture(const char* textureName);
+
+
+  virtual void draw() const;
+
+
+
+ private:
+  Material*       material;        //!< Materials for the Planet. sorted by number (0-5) top, bottom, left, right, front, back
+  Texture*        texture;         //!< Textures for the CubeMap.
+
+  float           size;            //!< Size of the Planet. This should match the frustum maximum range.
+  float           textureSize;     //!< this is the length of a texture (assumes a square texture)
+  char*           textureName;     //!< Name of the Texture
+
+};
+
+#endif  /* _PLANET_H */
+
+
+
Index: branches/network/src/world_entities/playable.cc
===================================================================
--- branches/network/src/world_entities/playable.cc	(revision 6636)
+++ branches/network/src/world_entities/playable.cc	(revision 6636)
@@ -0,0 +1,204 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Silvan Nellen
+   co-programmer: Benjamin Knecht
+*/
+
+
+#include "playable.h"
+
+#include "weapons/weapon_manager.h"
+#include "event_handler.h"
+#include "player.h"
+#include "state.h"
+
+#include "power_ups/weapon_power_up.h"
+#include "power_ups/param_power_up.h"
+
+
+Playable::Playable()
+{
+  this->setClassID(CL_PLAYABLE, "Playable");
+  PRINTF(4)("PLAYABLE INIT\n");
+
+  this->toList(OM_GROUP_01);
+  this->weaponMan = new WeaponManager(this);
+
+  // the reference to the Current Player is NULL, because we dont have one at the beginning.
+  this->currentPlayer = NULL;
+}
+
+Playable::~Playable()
+{
+  delete this->weaponMan;
+
+  if (this->currentPlayer)
+  {
+    PRINTF(2)("There is Still a Player subscribed to this Playable (%s::%s)\n", this->getClassName(), this->getName());
+
+  }
+}
+
+
+void Playable::addWeapon(Weapon* weapon, int configID, int slotID)
+{
+  this->weaponMan->addWeapon(weapon, configID, slotID);
+
+  this->weaponConfigChanged();
+}
+
+void Playable::removeWeapon(Weapon* weapon)
+{
+  this->weaponMan->removeWeapon(weapon);
+
+    this->weaponConfigChanged();
+}
+
+void Playable::nextWeaponConfig()
+{
+  this->weaponMan->nextWeaponConfig();
+    this->weaponConfigChanged();
+}
+
+void Playable::previousWeaponConfig()
+{
+  this->weaponMan->previousWeaponConfig();
+    this->weaponConfigChanged();
+}
+
+void Playable::weaponConfigChanged()
+{
+  if (this->currentPlayer != NULL)
+    this->currentPlayer->weaponConfigChanged();
+}
+
+/**
+ * @brief helps us colliding Playables
+ */
+void Playable::collidesWith(WorldEntity* entity, const Vector& location)
+{
+  if (entity->isA(CL_PROJECTILE))
+    this->removeEnergy(entity->getEnergy());
+
+  // EXTREME HACK
+  if (this->getEnergy() == 0.0f)
+    this->deactivateNode();
+}
+
+/**
+ * subscribe to all events the controllable needs
+ * @param player the player that shall controll this Playable
+ */
+bool Playable::subscribePlayer(Player* player)
+{
+  if (this->currentPlayer != NULL)
+  {
+    PRINTF(1)("Already registered Player:%s to this Playable (%s:%s)\n", this->currentPlayer->getName(), this->getClassName(), this->getName());
+    return false;
+  }
+  else
+  {
+    this->currentPlayer = player;
+    /*EventHandler*/
+    EventHandler* evh = EventHandler::getInstance();
+    std::list<int>::iterator ev;
+    for (ev = this->events.begin(); ev != events.end(); ev++)
+      evh->subscribe(player, ES_GAME, (*ev));
+    this->enter();
+    return true;
+  }
+}
+
+/**
+ * unsubscribe from all events the controllable needs
+ * @param player the Player, that controlled this Ship.
+ */
+bool Playable::unsubscribePlayer(Player* player)
+{
+  if (this->currentPlayer != player)
+  {
+    PRINTF(1)("not the right Player to unregister from this Playable (%s:%s)\n", this->currentPlayer->getName(), this->getClassName(), this->getName());
+    return false;
+  }
+
+  else
+  {
+    /*EventHandler*/
+    EventHandler* evh = EventHandler::getInstance();
+    std::list<int>::iterator ev;
+    for (ev = this->events.begin(); ev != events.end(); ev++)
+      evh->unsubscribe( ES_GAME, (*ev));
+
+    this->leave();
+    this->currentPlayer = NULL;
+    return true;
+  }
+}
+
+bool Playable::pickup(PowerUp* powerUp)
+{
+  if(powerUp->isA(CL_WEAPON_POWER_UP)) {
+    Weapon* weapon = dynamic_cast<WeaponPowerUp*>(powerUp)->getWeapon();
+    WeaponManager* manager = this->getWeaponManager();
+    manager->addWeapon(weapon, 2, -1);
+    return true;
+  }
+  else if(powerUp->isA(CL_PARAM_POWER_UP)) {
+    ParamPowerUp* ppu = dynamic_cast<ParamPowerUp*>(powerUp);
+    switch(ppu->getType()) {
+      case POWERUP_PARAM_HEALTH:
+        this->addEnergy(ppu->getValue());
+        return true;
+      case POWERUP_PARAM_MAX_HEALTH:
+        this->setMaxEnergy(this->getMaxEnergy() + ppu->getValue());
+        return true;
+    }
+  }
+  return false;
+}
+
+/**
+ * add an event to the event list of events this Playable can capture
+ * @param eventType the Type of event to add
+ */
+void Playable::registerEvent(int eventType)
+{
+  this->events.push_back(eventType);
+
+  if (this->currentPlayer != NULL)
+    EventHandler::getInstance()->subscribe(this->currentPlayer, ES_GAME, eventType);
+}
+
+/**
+ * remove an event to the event list this Playable can capture.
+ * @param event the event to unregister.
+ */
+void Playable::unregisterEvent(int eventType)
+{
+  this->events.remove(eventType);
+
+  if (this->currentPlayer != NULL)
+    EventHandler::getInstance()->unsubscribe(ES_GAME, eventType);
+}
+
+
+void  Playable::attachCamera()
+{
+  State::getCamera()->setParentSoft(this);
+  State::getCameraTarget()->setParentSoft(this);
+
+}
+
+
+void  Playable::detachCamera()
+{
+}
Index: branches/network/src/world_entities/playable.h
===================================================================
--- branches/network/src/world_entities/playable.h	(revision 6636)
+++ branches/network/src/world_entities/playable.h	(revision 6636)
@@ -0,0 +1,70 @@
+
+/*!
+ * @file playable.h
+ * Interface for a basic controllable WorldEntity
+ */
+#ifndef _PLAYABLE_H
+#define _PLAYABLE_H
+
+#include "world_entity.h"
+#include "extendable.h"
+#include "event.h"
+#include <list>
+
+#include "world_entities/weapons/weapon_manager.h"
+
+class Weapon;
+
+class Player;
+
+//! Basic controllable WorldEntity
+/**
+ *
+ */
+class Playable : public WorldEntity, public Extendable
+{
+  public:
+    Playable();
+    virtual ~Playable();
+
+    virtual void enter()=0;
+    virtual void leave()=0;
+
+    virtual bool pickup(PowerUp* powerUp);
+
+    void addWeapon(Weapon* weapon, int configID = -1, int slotID = -1);
+    void removeWeapon(Weapon* weapon);
+    void nextWeaponConfig();
+    void previousWeaponConfig();
+
+    inline WeaponManager* getWeaponManager() const { return this->weaponMan; };
+    void weaponConfigChanged();
+
+
+    bool subscribePlayer(Player* player);
+    bool unsubscribePlayer(Player* player);
+
+    void attachCamera();
+    void detachCamera();
+
+    virtual void collidesWith(WorldEntity* entity, const Vector& location);
+    virtual void process(const Event &event) = 0;
+
+
+
+    /** @return a List of Events in PEV_* sytle */
+    inline const std::list<int>& getEventList() { return this->events; };
+
+  protected:
+    void registerEvent(int eventType);
+    void unregisterEvent(int eventType);
+
+  private:
+    WeaponManager*        weaponMan;          //!< the weapon manager: managing a list of weapon to wepaon-slot mapping
+    std::list<int>        events;             //!< A list of Events, that are captured for this playable
+
+    Player*               currentPlayer;      //!< The Player currently connected to this Playable (the one that has controll) otherwise NULL
+
+};
+
+#endif /* _PLAYABLE_H */
Index: branches/network/src/world_entities/player.cc
===================================================================
--- branches/network/src/world_entities/player.cc	(revision 6636)
+++ branches/network/src/world_entities/player.cc	(revision 6636)
@@ -0,0 +1,112 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Silvan Nellen
+   co-programmer: Benjamin Knecht
+*/
+
+#include "player.h"
+#include "playable.h"
+
+#include "event_handler.h"
+
+
+#include "class_list.h"
+#include "state.h"
+#include "util/hud.h"
+
+using namespace std;
+
+
+/**
+ * creates a new Player
+*/
+Player::Player()
+{
+//  this->setRelDir(Quaternion(M_PI, Vector(1,0,0)));
+  this->setClassID(CL_PLAYER, "Player");
+
+  PRINTF(4)("PLAYER INIT\n");
+
+  this->controllable = NULL;
+  this->hud.show();
+
+  EventHandler::getInstance()->subscribe(this, ES_GAME, SDLK_l);
+}
+
+
+/**
+ *  destructs the player, deletes alocated memory
+ */
+Player::~Player ()
+{
+
+}
+
+
+bool Player::setControllable(Playable* controllable)
+{
+  if(controllable != NULL && controllable->subscribePlayer(this))
+  {
+      this->controllable = controllable;
+      this->hud.setEnergyWidget(this->controllable->getEnergyWidget());
+      this->hud.setWeaponManager(this->controllable->getWeaponManager());
+      return true;
+  }
+  else
+    return false;
+}
+
+bool Player::disconnectControllable()
+ {
+   if(this->controllable == NULL) return true;
+
+   if(this->controllable->unsubscribePlayer(this))
+   {
+     this->controllable = NULL;
+     this->hud.setEnergyWidget(NULL);
+     this->hud.setWeaponManager(NULL);
+     return true;
+   }
+   else
+     return false;
+ }
+
+ void Player::weaponConfigChanged()
+ {
+   this->hud.updateWeaponManager();
+ }
+
+ void Player::process(const Event &event)
+ {
+   if (event.type == SDLK_l && event.bPressed)
+   {
+     /// FIXME this should be in the ObjectManager
+     const std::list<BaseObject*>* objectList = ClassList::getList(CL_PLAYABLE);
+     if (objectList != NULL)
+     {
+       list<BaseObject*>::const_iterator node;
+       for (node = objectList->begin(); node != objectList->end(); node++)
+         if (this->controllable != (*node) && (dynamic_cast<PNode*>(*node)->getAbsCoor() - this->controllable->getAbsCoor()).len() < 10.0)
+       {
+
+         this->disconnectControllable();
+         this->setControllable(dynamic_cast<Playable*>(*node));
+
+         break;
+       }
+     }
+   }
+
+   if (likely(this->controllable != NULL))
+     this->controllable->process(event);
+ }
+
Index: branches/network/src/world_entities/player.h
===================================================================
--- branches/network/src/world_entities/player.h	(revision 6636)
+++ branches/network/src/world_entities/player.h	(revision 6636)
@@ -0,0 +1,44 @@
+/*!
+ * @file player.h
+ * Implements a basic controllable WorldEntity
+ */
+
+#ifndef _PLAYER_H
+#define _PLAYER_H
+
+#include "event_listener.h"
+
+#include "util/hud.h"
+
+/* Forward Declaration */
+class Playable;
+
+
+//! Basic controllable WorldEntity
+/**
+  *  this is the debug player - actualy we would have to make a new
+     class derivated from Player for each player. for now, we just use
+     the player.cc for debug also
+*/
+class Player : public EventListener
+{
+
+  public:
+    Player();
+    virtual ~Player();
+
+    bool              setControllable(Playable* controllalble);
+    inline Playable*  getControllable() { return this->controllable; };
+
+    void              weaponConfigChanged();
+    bool              disconnectControllable();
+
+    // eventListener extension.
+    virtual void      process(const Event &event);
+
+  private:
+    Playable*         controllable;                  //!< The one we controll or NULL if none
+    Hud               hud;                           //!< The HUD to be displayed for this Player.
+};
+
+#endif /* _PLAYER_H */
Index: branches/network/src/world_entities/power_ups/laser_power_up.cc
===================================================================
--- branches/network/src/world_entities/power_ups/laser_power_up.cc	(revision 6636)
+++ branches/network/src/world_entities/power_ups/laser_power_up.cc	(revision 6636)
@@ -0,0 +1,158 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "laser_power_up.h"
+#include "factory.h"
+#include "state.h"
+#include "network_game_manager.h"
+
+#include "primitive_model.h"
+
+using namespace std;
+
+CREATE_FACTORY(LaserPowerUp, CL_LASER_POWER_UP);
+
+LaserPowerUp::LaserPowerUp () : PowerUp(0.0, 1.0, 0.0)
+{
+  this->init();
+}
+
+LaserPowerUp::LaserPowerUp(const TiXmlElement* root) : PowerUp(0.0, 1.0, 0.0)
+{
+  this->init();
+
+  this->loadParams(root);
+}
+
+
+LaserPowerUp::~LaserPowerUp ()
+{
+  delete this->sphereModel;
+  delete this->sphereMaterial;
+}
+
+
+void LaserPowerUp::init()
+{
+  this->setClassID(CL_LASER_POWER_UP, "LaserPowerUp");
+  this->loadModel("models/guns/test_gun.obj", 2.0);
+
+  this->sphereModel = new PrimitiveModel(PRIM_SPHERE, 7, 5);
+  this->sphereMaterial = new Material;
+  this->sphereMaterial->setTransparency(.1);
+  this->sphereMaterial->setDiffuse(.7, .7, .1);
+
+  this->rotation = Vector(0,1,0);
+  this->cycle    = (float)rand()/RAND_MAX*M_2_PI;
+  this->shiftDir(Quaternion((float)rand()/RAND_MAX*M_2_PI, this->rotation));
+}
+
+
+void LaserPowerUp::loadParams(const TiXmlElement* root)
+{
+  PowerUp::loadParams(root);
+
+}
+
+
+/**
+ * this function is called, when two entities collide
+ * @param entity: the world entity with whom it collides
+ *
+ * Implement behaviour like damage application or other miscellaneous collision stuff in this function
+ */
+void LaserPowerUp::collidesWith(WorldEntity* entity, const Vector& location)
+{
+ // PRINTF(3)("collision %s vs %s @ (%f,%f,%f)\n", this->getClassName(), entity->getClassName(), location.x, location.y, location.z);
+ if (entity->isA(CL_PLAYABLE))
+  this->toList(OM_DEAD);
+}
+
+/**
+ *  this method is called every frame
+ * @param time: the time in seconds that has passed since the last tick
+ *
+ * Handle all stuff that should update with time inside this method (movement, animation, etc.)
+*/
+void LaserPowerUp::tick(float dt)
+{
+  this->shiftDir(Quaternion(dt, this->rotation));
+  this->cycle+=dt;
+
+}
+
+/**
+ *  the entity is drawn onto the screen with this function
+ *
+ * This is a central function of an entity: call it to let the entity painted to the screen.
+ * Just override this function with whatever you want to be drawn.
+*/
+void LaserPowerUp::draw() const
+{  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  /* translate */
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y + cos(this->cycle*3.0)*2.0,
+                this->getAbsCoor ().z);
+  /* rotate */
+  Vector tmpRot = this->getAbsDir().getSpacialAxis();
+  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+  this->getModel()->draw();
+
+  this->sphereMaterial->select();
+  this->sphereModel->draw();
+  glPopMatrix();
+}
+
+int LaserPowerUp::writeBytes( const byte * data, int length, int sender )
+{
+  setRequestedSync( false );
+  setIsOutOfSync( false );
+
+  SYNCHELP_READ_BEGIN();
+
+  SYNCHELP_READ_FKT( PowerUp::writeState );
+
+  return SYNCHELP_READ_N;
+}
+
+
+
+int LaserPowerUp::readBytes( byte * data, int maxLength, int * reciever )
+{
+  if ( isOutOfSync() && !requestedSync() && this->getHostID()!=this->getOwner() )
+  {
+    (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
+    setRequestedSync( true );
+  }
+
+  int rec = this->getRequestSync();
+  if ( rec > 0 )
+  {
+    *reciever = rec;
+
+    SYNCHELP_WRITE_BEGIN();
+
+    SYNCHELP_WRITE_FKT( PowerUp::readState );
+
+    return SYNCHELP_WRITE_N;
+  }
+
+  *reciever = 0;
+  return 0;
+}
+
Index: branches/network/src/world_entities/power_ups/laser_power_up.h
===================================================================
--- branches/network/src/world_entities/power_ups/laser_power_up.h	(revision 6636)
+++ branches/network/src/world_entities/power_ups/laser_power_up.h	(revision 6636)
@@ -0,0 +1,42 @@
+/*!
+ * @file laser_power_up.h
+ * @brief A class representing a PowerUp in the world.
+*/
+
+#ifndef _LASER_POWER_UP_H
+#define _LASER_POWER_UP_H
+
+#include "power_up.h"
+
+/* FORWARD DEFINITION */
+class Material;
+
+class LaserPowerUp : public PowerUp {
+
+ public:
+  LaserPowerUp();
+  LaserPowerUp(const TiXmlElement* root);
+  virtual ~LaserPowerUp ();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+
+  virtual void LaserPowerUp::collidesWith(WorldEntity* entity, const Vector& location);
+  virtual void tick(float dt);
+  virtual void draw() const;
+
+  virtual int writeBytes(const byte* data, int length, int sender);
+  virtual int readBytes(byte* data, int maxLength, int * reciever );
+
+  private:
+   void init();
+
+  private:
+   Vector              rotation;
+   float               cycle;
+
+   Model*              sphereModel;
+   Material*           sphereMaterial;
+};
+
+#endif /* _LASER_POWER_UP_H */
Index: branches/network/src/world_entities/power_ups/param_power_up.cc
===================================================================
--- branches/network/src/world_entities/power_ups/param_power_up.cc	(revision 6636)
+++ branches/network/src/world_entities/power_ups/param_power_up.cc	(revision 6636)
@@ -0,0 +1,184 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "param_power_up.h"
+#include "factory.h"
+#include "state.h"
+#include "list.h"
+
+#include "primitive_model.h"
+
+#include "factory.h"
+#include "load_param.h"
+#include "network_game_manager.h"
+
+using namespace std;
+
+CREATE_FACTORY(ParamPowerUp, CL_PARAM_POWER_UP);
+
+const char* ParamPowerUp::paramTypes[] = {
+  "shield",
+  "max-shield",
+  "health",
+  "max-health",
+};
+
+ParamPowerUp::ParamPowerUp () : PowerUp(0.0, 1.0, 0.0)
+{
+  this->init();
+}
+
+ParamPowerUp::ParamPowerUp(const TiXmlElement* root) : PowerUp(0.0, 1.0, 0.0)
+{
+  this->init();
+  this->loadParams(root);
+}
+
+
+ParamPowerUp::~ParamPowerUp ()
+{
+}
+
+
+void ParamPowerUp::init()
+{
+  this->setClassID(CL_PARAM_POWER_UP, "ParamPowerUp");
+  this->value = 0;
+  this->max_value = 0;
+  this->min_value = 0;
+}
+
+
+void ParamPowerUp::loadParams(const TiXmlElement* root)
+{
+  PowerUp::loadParams(root);
+  LoadParam(root, "type", this, ParamPowerUp, setType);
+
+  if( root != NULL && root->FirstChildElement("value") != NULL) {
+
+    LoadParam(root, "value", this, ParamPowerUp, setValue);
+  }
+  else {
+    LoadParam(root, "max-value", this, ParamPowerUp, setMaxValue);
+    LoadParam(root, "min-value", this, ParamPowerUp, setMinValue);
+    respawn();
+  }
+}
+
+void ParamPowerUp::setValue(float value)
+{
+  this->value = value;
+}
+
+void ParamPowerUp::setType(const char* type)
+{
+  for(int i = 0; i < POWERUP_PARAM_size; ++i) {
+    if(strcmp(type, paramTypes[i]) == 0) {
+      this->type = (EnumParamPowerUpType)i;
+      break;
+    }
+  }
+}
+
+void ParamPowerUp::setMaxValue(float value)
+{
+  this->max_value = value;
+}
+
+void ParamPowerUp::setMinValue(float value)
+{
+  this->min_value = value;
+}
+
+float ParamPowerUp::getValue()
+{
+  return this->value;
+}
+
+EnumParamPowerUpType ParamPowerUp::getType()
+{
+  return this->type;
+}
+
+void ParamPowerUp::respawn()
+{
+  if(this->min_value != this->max_value)
+  {
+    this->value = this->min_value + rand() * (this->max_value - this->min_value);
+  }
+}
+
+int ParamPowerUp::writeBytes( const byte * data, int length, int sender )
+{
+  setRequestedSync( false );
+  setIsOutOfSync( false );
+
+  SYNCHELP_READ_BEGIN();
+
+  SYNCHELP_READ_FKT( PowerUp::writeState );
+
+  int i;
+  SYNCHELP_READ_INT( i );
+  this->type = (EnumParamPowerUpType)i;
+  SYNCHELP_READ_FLOAT( this->value );
+
+  if ( this->value != 0 )
+  {
+    SYNCHELP_READ_FLOAT( this->min_value );
+    SYNCHELP_READ_FLOAT( this->max_value );
+    respawn();
+  }
+
+  return SYNCHELP_READ_N;
+}
+
+
+
+int ParamPowerUp::readBytes( byte * data, int maxLength, int * reciever )
+{
+  if ( isOutOfSync() && !requestedSync() && this->getHostID()!=this->getOwner() )
+  {
+    (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
+    setRequestedSync( true );
+  }
+
+  int rec = this->getRequestSync();
+  if ( rec > 0 )
+  {
+    *reciever = rec;
+
+    SYNCHELP_WRITE_BEGIN();
+
+    SYNCHELP_WRITE_FKT( PowerUp::readState );
+
+    int i = (int)this->type;
+    SYNCHELP_WRITE_INT( i );
+    SYNCHELP_WRITE_FLOAT( this->value );
+
+    if ( this->value != 0 )
+    {
+      SYNCHELP_WRITE_FLOAT( this->min_value );
+      SYNCHELP_WRITE_FLOAT( this->max_value );
+    }
+
+    return SYNCHELP_WRITE_N;
+  }
+
+  *reciever = 0;
+  return 0;
+}
+
Index: branches/network/src/world_entities/power_ups/param_power_up.h
===================================================================
--- branches/network/src/world_entities/power_ups/param_power_up.h	(revision 6636)
+++ branches/network/src/world_entities/power_ups/param_power_up.h	(revision 6636)
@@ -0,0 +1,53 @@
+/*!
+ * @file weapon_power_up.h
+ * @brief A class representing a PowerUp modifying parameters.
+*/
+
+#ifndef _PARAM_POWER_UP_H
+#define _PARAM_POWER_UP_H
+
+#include "power_up.h"
+
+/* FORWARD DEFINITION */
+
+typedef enum EnumParamPowerUpType {
+  POWERUP_PARAM_SHIELD,
+  POWERUP_PARAM_MAX_SHIELD,
+  POWERUP_PARAM_HEALTH,
+  POWERUP_PARAM_MAX_HEALTH,
+  POWERUP_PARAM_size
+} EnumParamPowerUpType;
+
+class ParamPowerUp : public PowerUp {
+
+public:
+  ParamPowerUp();
+  ParamPowerUp(const TiXmlElement* root);
+  virtual ~ParamPowerUp ();
+
+  void setValue(float value);
+  void setMaxValue(float value);
+  void setMinValue(float value);
+  void setType(const char* type);
+  EnumParamPowerUpType getType();
+  float getValue();
+
+  virtual int writeBytes(const byte* data, int length, int sender);
+  virtual int readBytes(byte* data, int maxLength, int * reciever );
+
+protected:
+  virtual void respawn();
+
+private:
+  void init();
+  virtual void loadParams(const TiXmlElement* root);
+
+private:
+  static const char* paramTypes[];
+  EnumParamPowerUpType type;
+  float value;
+  float max_value;
+  float min_value;
+};
+
+#endif /* _PARAM_POWER_UP_H */
Index: branches/network/src/world_entities/power_ups/power_up.cc
===================================================================
--- branches/network/src/world_entities/power_ups/power_up.cc	(revision 6636)
+++ branches/network/src/world_entities/power_ups/power_up.cc	(revision 6636)
@@ -0,0 +1,143 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Manuel Leuenberger
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "power_up.h"
+#include "extendable.h"
+#include "primitive_model.h"
+
+using namespace std;
+
+PowerUp::PowerUp(float r, float g, float b)
+{
+  this->setClassID(CL_POWER_UP, "PowerUp");
+
+  this->respawnType = RESPAWN_NONE;
+  this->respawnStart = 10;
+  this->model = NULL;
+/*  if(!PowerUp::sphereModel) {*/
+
+  Model* sphereModel = new PrimitiveModel(PRIM_SPHERE, 7, 5);
+
+  this->setModel(sphereModel);
+  this->buildObbTree( 4);
+  this->sphereMaterial = new Material;
+  this->sphereMaterial->setTransparency(.1);
+  this->sphereMaterial->setDiffuse(r, g, b);
+  this->toList(OM_COMMON);
+}
+
+PowerUp::~PowerUp ()
+{
+  delete this->sphereMaterial;
+}
+
+
+void PowerUp::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+}
+
+
+void PowerUp::collidesWith (WorldEntity* entity, const Vector& location)
+{
+  if(entity->isA(CL_EXTENDABLE))
+  {
+    if(dynamic_cast<Extendable*>(entity)->pickup(this))
+    {
+      this->respawnTime = this->respawnStart;
+      this->toList(OM_DEAD_TICK);
+    }
+  }
+}
+
+void PowerUp::tick(float dt) {
+  if(this->getOMListNumber() != OM_COMMON) {
+    this->respawnTime -= dt;
+    if(this->respawnTime <= 0) {
+      this->toList(OM_COMMON);
+      this->respawn();
+    }
+  }
+}
+
+void PowerUp::draw() const
+{
+  if(this->model != NULL) {
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+    glTranslatef (this->getAbsCoor ().x,
+                  this->getAbsCoor ().y,
+                  this->getAbsCoor ().z);
+    Vector tmpRot = this->getAbsDir().getSpacialAxis();
+    glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+    this->model->draw();
+    glPopMatrix();
+  }
+  this->sphereMaterial->select();
+  WorldEntity::draw();
+}
+
+const char* PowerUp::respawnTypes[] = {
+  "none",
+  "time"
+};
+
+void PowerUp::setRespawnType(const char* type)
+{
+  for(int i = 0; i < RESPAWN_size; ++i) {
+    if(!strcmp(type, respawnTypes[i])) {
+      this->respawnType = (PowerUpRespawn)i;
+      break;
+    }
+  }
+}
+
+
+
+/********************************************************************************************
+ NETWORK STUFF
+ ********************************************************************************************/
+
+
+/**
+ * data copied in data will bee sent to another host
+ * @param data pointer to data
+ * @param maxLength max length of data
+ * @return the number of bytes writen
+ */
+int PowerUp::readState( byte * data, int maxLength )
+{
+  SYNCHELP_WRITE_BEGIN();
+  SYNCHELP_WRITE_FKT( WorldEntity::readState );
+  return SYNCHELP_WRITE_N;
+}
+
+
+/**
+ * Writes data from network containing information about the state
+ * @param data pointer to data
+ * @param length length of data
+ * @param sender hostID of sender
+ */
+int PowerUp::writeState( const byte * data, int length, int sender )
+{
+  SYNCHELP_READ_BEGIN();
+  SYNCHELP_READ_FKT( WorldEntity::writeState );
+  return SYNCHELP_READ_N;
+}
+
Index: branches/network/src/world_entities/power_ups/power_up.h
===================================================================
--- branches/network/src/world_entities/power_ups/power_up.h	(revision 6636)
+++ branches/network/src/world_entities/power_ups/power_up.h	(revision 6636)
@@ -0,0 +1,46 @@
+/*!
+ * @file power_up.h
+ * @brief A class representing a PowerUp in the world.
+*/
+
+#ifndef _POWER_UP_H
+#define _POWER_UP_H
+
+#include "world_entity.h"
+
+class Material;
+
+typedef enum PowerUpRespawn {
+  RESPAWN_NONE,
+  RESPAWN_TIME,
+  RESPAWN_size
+} PowerUpRespawn;
+
+class PowerUp : public WorldEntity {
+
+public:
+  virtual void loadParams(const TiXmlElement* root);
+  void collidesWith (WorldEntity* entity, const Vector& location);
+
+  virtual void draw () const;
+  virtual void tick(float dt);
+  void setRespawnType(const char* type);
+
+  int       writeState(const byte* data, int length, int sender);
+  int       readState(byte* data, int maxLength );
+
+protected:
+  PowerUp(float r, float g, float b);
+  virtual ~PowerUp ();
+  virtual void respawn() {};
+  Model* model;
+
+private:
+  Material* sphereMaterial;
+  PowerUpRespawn respawnType;
+  float respawnTime;
+  float respawnStart;
+  static const char* respawnTypes[];
+};
+
+#endif /* _POWER_UP_H */
Index: branches/network/src/world_entities/power_ups/turret_power_up.cc
===================================================================
--- branches/network/src/world_entities/power_ups/turret_power_up.cc	(revision 6636)
+++ branches/network/src/world_entities/power_ups/turret_power_up.cc	(revision 6636)
@@ -0,0 +1,164 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "turret_power_up.h"
+#include "factory.h"
+#include "network_game_manager.h"
+#include "state.h"
+
+#include "primitive_model.h"
+
+using namespace std;
+
+CREATE_FACTORY(TurretPowerUp, CL_TURRET_POWER_UP);
+
+TurretPowerUp::TurretPowerUp () : PowerUp(0.0, 1.0, 0.0)
+{
+  this->init();
+}
+
+TurretPowerUp::TurretPowerUp(const TiXmlElement* root) : PowerUp(0.0, 1.0, 0.0)
+{
+  this->init();
+
+  this->loadParams(root);
+}
+
+
+TurretPowerUp::~TurretPowerUp ()
+{
+  delete this->sphereModel;
+  delete this->sphereMaterial;
+}
+
+
+void TurretPowerUp::init()
+{
+  this->setClassID(CL_TURRET_POWER_UP, "TurretPowerUp");
+  this->loadModel("models/guns/turret1.obj", 2.0);
+
+  this->sphereModel = new PrimitiveModel(PRIM_SPHERE, 7, 5);
+  this->sphereMaterial = new Material;
+  this->sphereMaterial->setTransparency(.1);
+  this->sphereMaterial->setDiffuse(.1, .1, .8);
+
+  this->rotation = Vector(0,1,0);
+  this->cycle    = (float)rand()/RAND_MAX*M_2_PI;
+  this->shiftDir(Quaternion((float)rand()/RAND_MAX*M_2_PI, this->rotation));
+}
+
+
+void TurretPowerUp::loadParams(const TiXmlElement* root)
+{
+  PowerUp::loadParams(root);
+
+}
+
+
+/**
+ * this function is called, when two entities collide
+ * @param entity: the world entity with whom it collides
+ *
+ * Implement behaviour like damage application or other miscellaneous collision stuff in this function
+ */
+void TurretPowerUp::collidesWith(WorldEntity* entity, const Vector& location)
+{
+ // PRINTF(3)("collision %s vs %s @ (%f,%f,%f)\n", this->getClassName(), entity->getClassName(), location.x, location.y, location.z);
+ if (entity->isA(CL_PLAYABLE))
+   this->toList(OM_DEAD);
+}
+
+/**
+ *  this method is called every frame
+ * @param time: the time in seconds that has passed since the last tick
+ *
+ * Handle all stuff that should update with time inside this method (movement, animation, etc.)
+*/
+void TurretPowerUp::tick(float dt)
+{
+  this->shiftDir(Quaternion(dt, this->rotation));
+  this->cycle+=dt;
+
+}
+
+/**
+ *  the entity is drawn onto the screen with this function
+ *
+ * This is a central function of an entity: call it to let the entity painted to the screen.
+ * Just override this function with whatever you want to be drawn.
+*/
+void TurretPowerUp::draw() const
+{  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  /* translate */
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y + cos(this->cycle*3.0)*2.0,
+                this->getAbsCoor ().z);
+  /* rotate */
+  Vector tmpRot = this->getAbsDir().getSpacialAxis();
+  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+  this->getModel()->draw();
+
+  this->sphereMaterial->select();
+  this->sphereModel->draw();
+  glPopMatrix();
+}
+
+
+
+
+/********************************************************************************************
+ NETWORK STUFF
+ ********************************************************************************************/
+
+
+int TurretPowerUp::writeBytes( const byte * data, int length, int sender )
+{
+  setRequestedSync( false );
+  setIsOutOfSync( false );
+
+  SYNCHELP_READ_BEGIN();
+
+  SYNCHELP_READ_FKT( PowerUp::writeState );
+
+  return SYNCHELP_READ_N;
+}
+
+
+int TurretPowerUp::readBytes( byte * data, int maxLength, int * reciever )
+{
+  if ( isOutOfSync() && !requestedSync() && this->getHostID()!=this->getOwner() )
+  {
+    (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
+    setRequestedSync( true );
+  }
+
+  int rec = this->getRequestSync();
+  if ( rec > 0 )
+  {
+    *reciever = rec;
+
+    SYNCHELP_WRITE_BEGIN();
+
+    SYNCHELP_WRITE_FKT( PowerUp::readState );
+
+    return SYNCHELP_WRITE_N;
+  }
+
+  *reciever = 0;
+  return 0;
+}
Index: branches/network/src/world_entities/power_ups/turret_power_up.h
===================================================================
--- branches/network/src/world_entities/power_ups/turret_power_up.h	(revision 6636)
+++ branches/network/src/world_entities/power_ups/turret_power_up.h	(revision 6636)
@@ -0,0 +1,41 @@
+/*!
+ * @file turret_power_up.h
+ * @brief A class representing a PowerUp in the world.
+*/
+
+#ifndef _TURRET_POWER_UP_H
+#define _TURRET_POWER_UP_H
+
+#include "power_up.h"
+
+/* FORWARD DEFINITION */
+class Material;
+
+class TurretPowerUp : public PowerUp {
+
+ public:
+  TurretPowerUp();
+  TurretPowerUp(const TiXmlElement* root);
+  virtual ~TurretPowerUp ();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  virtual void TurretPowerUp::collidesWith(WorldEntity* entity, const Vector& location);
+  virtual void tick(float dt);
+  virtual void draw() const;
+
+  virtual int writeBytes(const byte* data, int length, int sender);
+  virtual int readBytes(byte* data, int maxLength, int * reciever );
+
+  private:
+   void init();
+
+  private:
+   Vector              rotation;
+   float               cycle;
+
+   Model*              sphereModel;
+   Material*           sphereMaterial;
+};
+
+#endif /* _TURRET_POWER_UP_H */
Index: branches/network/src/world_entities/power_ups/weapon_power_up.cc
===================================================================
--- branches/network/src/world_entities/power_ups/weapon_power_up.cc	(revision 6636)
+++ branches/network/src/world_entities/power_ups/weapon_power_up.cc	(revision 6636)
@@ -0,0 +1,131 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "weapon_power_up.h"
+#include "factory.h"
+#include "state.h"
+#include "list.h"
+#include "network_game_manager.h"
+
+#include "primitive_model.h"
+
+#include "factory.h"
+#include "load_param.h"
+
+using namespace std;
+
+CREATE_FACTORY(WeaponPowerUp, CL_WEAPON_POWER_UP);
+
+WeaponPowerUp::WeaponPowerUp () : PowerUp(1.0, 1.0, 0.0)
+{
+  this->init();
+}
+
+WeaponPowerUp::WeaponPowerUp(const TiXmlElement* root) : PowerUp(1.0, 1.0, 0.0)
+{
+  this->init();
+  this->loadParams(root);
+}
+
+
+WeaponPowerUp::~WeaponPowerUp ()
+{
+}
+
+
+void WeaponPowerUp::init()
+{
+  this->setClassID(CL_WEAPON_POWER_UP, "WeaponPowerUp");
+  this->weaponXML = NULL;
+  this->weapon = NULL;
+}
+
+
+void WeaponPowerUp::loadParams(const TiXmlElement* root)
+{
+  PowerUp::loadParams(root);
+  const TiXmlElement* elem = root->FirstChildElement("weapon");
+  if(elem != NULL && (elem = elem->FirstChildElement()) != NULL)
+  {
+    this->weaponXML = elem;
+    respawn();
+  }
+  else
+  {
+    LoadParam(root, "weaponID", this, WeaponPowerUp, setWeaponClass);
+  }
+  this->model = this->weapon->getModel(0);
+}
+
+Weapon* WeaponPowerUp::getWeapon()
+{
+  return this->weapon;
+}
+
+void WeaponPowerUp::respawn()
+{
+  this->weapon = dynamic_cast<Weapon*>((weaponXML == NULL)
+      ? Factory::fabricate(static_cast<ClassID>(this->weapon->getClassID()))
+      : Factory::fabricate(weaponXML));
+}
+
+void WeaponPowerUp::setWeaponClass(const char* name)
+{
+  this->weapon = dynamic_cast<Weapon*>(Factory::fabricate(name));
+}
+
+int WeaponPowerUp::writeBytes( const byte * data, int length, int sender )
+{
+  setRequestedSync( false );
+  setIsOutOfSync( false );
+
+  SYNCHELP_READ_BEGIN();
+
+  SYNCHELP_READ_FKT( PowerUp::writeState );
+
+  //TODO: sync weapon class ( see loadParams )
+
+  return SYNCHELP_READ_N;
+}
+
+
+
+int WeaponPowerUp::readBytes( byte * data, int maxLength, int * reciever )
+{
+  if ( isOutOfSync() && !requestedSync() && this->getHostID()!=this->getOwner() )
+  {
+    (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
+    setRequestedSync( true );
+  }
+
+  int rec = this->getRequestSync();
+  if ( rec > 0 )
+  {
+    *reciever = rec;
+
+    SYNCHELP_WRITE_BEGIN();
+
+    SYNCHELP_WRITE_FKT( PowerUp::readState );
+
+    //TODO: sync weapon class ( see loadParams )
+
+    return SYNCHELP_WRITE_N;
+  }
+
+  *reciever = 0;
+  return 0;
+}
Index: branches/network/src/world_entities/power_ups/weapon_power_up.h
===================================================================
--- branches/network/src/world_entities/power_ups/weapon_power_up.h	(revision 6636)
+++ branches/network/src/world_entities/power_ups/weapon_power_up.h	(revision 6636)
@@ -0,0 +1,41 @@
+/*!
+ * @file weapon_power_up.h
+ * @brief A class representing a PowerUp containing a weapon.
+*/
+
+#ifndef _WEAPON_POWER_UP_H
+#define _WEAPON_POWER_UP_H
+
+#include "power_up.h"
+#include "weapons/weapon.h"
+
+/* FORWARD DEFINITION */
+
+class WeaponPowerUp : public PowerUp {
+
+public:
+  WeaponPowerUp();
+  WeaponPowerUp(const TiXmlElement* root);
+  virtual ~WeaponPowerUp ();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  Weapon* getWeapon();
+  void setWeaponClass(const char* name);
+
+  virtual int writeBytes(const byte* data, int length, int sender);
+  virtual int readBytes(byte* data, int maxLength, int * reciever );
+
+protected:
+  virtual void respawn();
+
+private:
+  void init();
+private:
+  Weapon* weapon;
+  const TiXmlElement* weaponXML;
+
+  void createWeapon();
+};
+
+#endif /* _WEAPON_POWER_UP_H */
Index: branches/network/src/world_entities/projectiles/bomb.cc
===================================================================
--- branches/network/src/world_entities/projectiles/bomb.cc	(revision 6636)
+++ branches/network/src/world_entities/projectiles/bomb.cc	(revision 6636)
@@ -0,0 +1,198 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Stefan Lienhard
+   co-programmer: ...
+*/
+
+#include "bomb.h"
+#include "glincl.h"
+#include "state.h"
+#include "model.h"
+#include "primitive_model.h"
+
+#include "fast_factory.h"
+
+
+#include "object_manager.h"
+
+#include "particle_emitter.h"
+#include "particle_system.h"
+
+using namespace std;
+
+CREATE_FAST_FACTORY_STATIC(Bomb, CL_BOMB);
+
+/**
+ * constructs and loads a Bomb from a XML-element
+ * @param root the XML-element to load from
+ */
+Bomb::Bomb(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+
+  float modelSize = 1.0;
+  this->loadModel("models/projectiles/RadioActiveBomb.obj", 1.0);
+
+  this->setMinEnergy(1);
+  this->setMaxEnergy(10);
+
+  this->lifeSpan = 15;
+
+  this->emitter = new ParticleEmitter(Vector(0,1,0), M_2_PI, 100, 5);
+  this->emitter->setParent(this);
+  this->emitter->setSpread(M_PI, M_PI);
+}
+
+
+/**
+ * standard deconstructor
+ */
+Bomb::~Bomb ()
+{
+  delete this->detonationSphere;
+  delete this->detonationMaterial;
+
+}
+
+
+/**
+ * initializes the Bomb
+ * @todo change this to what you wish
+ */
+void Bomb::init()
+{
+  this->setClassID(CL_BOMB, "Bomb");
+
+
+  this->detonationSphere = new PrimitiveModel(PRIM_SPHERE);
+  this->detonationMaterial = new Material();
+  this->detonationMaterial->setDiffuse(1, 0, 0);
+  //   this->detonationMaterial->setTransparency(.1);
+  /**
+   * @todo: Write CL_PROTO_WORLD_ENTITY INTO THE src/defs/class_id.h (your own definition)
+   */
+
+}
+
+
+/**
+ * loads a Bomb from a XML-element
+ * @param root the XML-element to load from
+ * @todo make the class Loadable
+ */
+void Bomb::loadParams(const TiXmlElement* root)
+{
+  // all the clases this Entity is directly derived from must be called in this way, to load all settings.
+  Projectile::loadParams(root);
+
+
+  /**
+   * @todo: make the class Loadable
+   */
+}
+
+
+/**
+ * advances the Bomb about time seconds
+ * @param time the Time to step
+ */
+void Bomb::tick(float time)
+{
+  this->lifeCycle += time/this->lifeSpan;
+  if( this->lifeCycle >= 1.0)
+    {
+      PRINTF(5)("FINALIZE==========================\n");
+      PRINTF(5)("current life cycle is: %f\n", this->lifeCycle);
+      PRINTF(5)("FINALIZE===========================\n");
+
+      this->deactivate();
+    }
+  else if (this->lifeCycle > 0.9f)
+    this->detonate ((this->lifeCycle-.89) *1000.0);
+  else
+  {
+    Vector v = this->velocity * (time);
+    this->shiftCoor(v);
+  }
+}
+
+/**
+ * draws this worldEntity
+ */
+void Bomb::draw () const
+{
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  float matrix[4][4];
+
+  /* translate */
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+  /* rotate */
+  this->getAbsDir().matrix(matrix);
+  glMultMatrixf((float*)matrix);
+
+  if (this->lifeCycle < .9)
+  {
+    if (this->getModel() != NULL)
+      this->getModel()->draw();
+  }
+  else
+  {
+    glScalef((this->lifeCycle-.89) *1000.0,
+              (this->lifeCycle-.89) *1000.0,
+              (this->lifeCycle-.89) *1000.0);
+    this->detonationMaterial->select();
+    this->detonationSphere->draw();
+  }
+  glPopMatrix();
+}
+
+
+/**
+ *
+ *
+ */
+void Bomb::collidesWith (WorldEntity* entity, const Vector& location)
+{
+  if (this->lifeCycle < .9f && entity->isA(CL_NPC))
+    this->lifeCycle = 0.9f;
+}
+
+void Bomb::activate()
+{
+
+}
+
+void Bomb::deactivate()
+{
+  this->toList(OM_DEAD);
+  this->lifeCycle = 0.0f;
+  Bomb::fastFactory->kill(this);
+}
+
+void Bomb::detonate(float size)
+{
+  std::list<WorldEntity*>* detonationList = ObjectManager::distanceFromObject(*this, size, CL_NPC);
+  if (detonationList != NULL)
+  {
+    while( !detonationList->empty() )
+    {
+      detonationList->front()->collidesWith(this, Vector(0,0,0));
+      detonationList->pop_front();
+    }
+    delete detonationList;
+  }
+}
Index: branches/network/src/world_entities/projectiles/bomb.h
===================================================================
--- branches/network/src/world_entities/projectiles/bomb.h	(revision 6636)
+++ branches/network/src/world_entities/projectiles/bomb.h	(revision 6636)
@@ -0,0 +1,49 @@
+/*!
+ * @file bomb.h
+ * @brief description
+*/
+
+#ifndef _BOMB_H
+#define _BOMB_H
+
+#include "projectile.h"
+
+class FastFactory;
+class SpriteParticles;
+class ParticleEmitter;
+class Material;
+
+//! A Class to ...
+class Bomb : public Projectile
+{
+
+ public:
+  Bomb(const TiXmlElement* root = NULL);
+  virtual ~Bomb();
+
+  virtual void loadParams(const TiXmlElement* root);
+  void init();
+
+//  virtual void postSpawn ();
+//  virtual void leftWorld ();
+
+
+  virtual void draw() const;
+  virtual void tick(float time);
+  virtual void collidesWith (WorldEntity* entity, const Vector& location);
+  virtual void activate();
+  virtual void deactivate();
+
+  void detonate(float size);
+
+ private:
+  static FastFactory*               fastFactory;
+  static SpriteParticles*           trailParticles;
+  static SpriteParticles*           explosionParticles;
+
+  ParticleEmitter*                  emitter;
+  Model*                            detonationSphere;
+  Material*                         detonationMaterial;
+};
+
+#endif /* BOMB */
Index: branches/network/src/world_entities/projectiles/guided_missile.cc
===================================================================
--- branches/network/src/world_entities/projectiles/guided_missile.cc	(revision 6636)
+++ branches/network/src/world_entities/projectiles/guided_missile.cc	(revision 6636)
@@ -0,0 +1,209 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Silvan Nellen
+   co-programmer:
+
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "guided_missile.h"
+
+#include "fast_factory.h"
+
+#include "state.h"
+#include "class_list.h"
+
+#include "particle_emitter.h"
+#include "sprite_particles.h"
+
+using namespace std;
+
+CREATE_FAST_FACTORY_STATIC(GuidedMissile, CL_GUIDED_MISSILE);
+
+/**
+ *  standard constructor
+*/
+GuidedMissile::GuidedMissile () : Projectile()
+{
+  this->setClassID(CL_GUIDED_MISSILE, "GuidedMissile");
+
+  float modelSize = .3;
+  this->loadModel("models/projectiles/orx-rocket.obj", .3);
+
+  this->setMinEnergy(1);
+  this->setMaxEnergy(10);
+  this->lifeSpan = 10.0;
+  this->agility = 500;
+  this->maxVelocity = 75;
+
+  this->emitter = new ParticleEmitter(Vector(0,1,0), M_2_PI, 100, 5);
+  this->emitter->setParent(this);
+  this->emitter->setSpread(M_PI, M_PI);
+}
+
+
+/**
+ *  standard deconstructor
+*/
+GuidedMissile::~GuidedMissile ()
+{
+  // delete this->emitter;
+
+  /* this is normaly done by World.cc by deleting the ParticleEngine */
+  if (GuidedMissile::trailParticles != NULL && ClassList::getList(CL_GUIDED_MISSILE)->size() <= 1)
+  {
+    if (ClassList::exists(GuidedMissile::trailParticles, CL_PARTICLE_SYSTEM))
+      delete GuidedMissile::trailParticles;
+    GuidedMissile::trailParticles = NULL;
+  }
+  if (GuidedMissile::explosionParticles != NULL && ClassList::getList(CL_GUIDED_MISSILE)->size() <= 1)
+  {
+    if (ClassList::exists(GuidedMissile::explosionParticles, CL_PARTICLE_SYSTEM))
+      delete GuidedMissile::explosionParticles;
+    GuidedMissile::explosionParticles = NULL;
+  }
+
+}
+
+SpriteParticles* GuidedMissile::trailParticles = NULL;
+SpriteParticles* GuidedMissile::explosionParticles = NULL;
+
+
+
+void GuidedMissile::activate()
+{
+  if (unlikely(GuidedMissile::trailParticles == NULL))
+  {
+    GuidedMissile::trailParticles = new SpriteParticles(2000);
+    GuidedMissile::trailParticles->setName("GuidedMissileTrailParticles");
+    GuidedMissile::trailParticles->setMaterialTexture("maps/radial-trans-noise.png");
+    GuidedMissile::trailParticles->setLifeSpan(1.0, .3);
+    GuidedMissile::trailParticles->setRadius(0.0, .5);
+    GuidedMissile::trailParticles->setRadius(0.2, 2.0);
+    GuidedMissile::trailParticles->setRadius(.5, .8);
+    GuidedMissile::trailParticles->setRadius(1.0, .8);
+    GuidedMissile::trailParticles->setColor(0.0, 1,0,0,.7);
+    GuidedMissile::trailParticles->setColor(0.2, .8,.8,0,.5);
+    GuidedMissile::trailParticles->setColor(0.5, .8,.8,.8,.8);
+    GuidedMissile::trailParticles->setColor(1.0, .8,.8,.8,.0);
+  }
+  if (unlikely(GuidedMissile::explosionParticles == NULL))
+  {
+    GuidedMissile::explosionParticles = new SpriteParticles(200);
+    GuidedMissile::explosionParticles->setName("GuidedMissileExplosionParticles");
+    GuidedMissile::explosionParticles->setMaterialTexture("maps/radial-trans-noise.png");
+    GuidedMissile::explosionParticles->setLifeSpan(.5, .3);
+    GuidedMissile::explosionParticles->setRadius(0.0, 10);
+    GuidedMissile::explosionParticles->setRadius(.5, 15.0);
+    GuidedMissile::explosionParticles->setRadius(1.0, 10.0);
+    GuidedMissile::explosionParticles->setColor(0.0, 0,1,0,1);
+    GuidedMissile::explosionParticles->setColor(0.5, .8,.8,0,.8);
+    GuidedMissile::explosionParticles->setColor(0.8, .8,.8,.3,.8);
+    GuidedMissile::explosionParticles->setColor(1.0, 1,1,1,.0);
+  }
+
+  this->emitter->setSystem(GuidedMissile::trailParticles);
+
+  this->updateNode(0);
+  this->emitter->setEmissionRate(45.0);
+  this->emitter->setEmissionVelocity(0.0);
+}
+
+
+void GuidedMissile::deactivate()
+{
+  this->emitter->setSystem(NULL);
+  this->lifeCycle = 0.0;
+
+  this->toList(OM_DEAD);
+  this->removeNode();
+  GuidedMissile::fastFactory->kill(this);
+}
+
+
+void GuidedMissile::collidesWith(WorldEntity* entity, const Vector& location)
+{
+  if (this->hitEntity != entity)
+    this->destroy();
+  this->hitEntity = entity;
+}
+
+/**
+ *  signal tick, time dependent things will be handled here
+ * @param time since last tick
+*/
+void GuidedMissile::tick (float time)
+{
+
+
+if (this->target != NULL && this->target->getParent() != PNode::getNullParent())
+   {
+    speed = velocity.len();
+    diffVector = ((target->getAbsCoor() - this->getAbsCoor()).getNormalized());
+
+    if(velocity.dot(diffVector) != 0)
+     {
+     correctionVector = (( ( diffVector *  (speed * speed/( velocity.dot(diffVector ) ) )) - velocity).getNormalized()) * agility;
+
+      if( (diffVector *  (speed * speed/( velocity.dot(diffVector ) ) ) -velocity).len() < agility )
+       velocity = ((diffVector *  (speed * speed/( velocity.dot(diffVector ) ) )).getNormalized())*agility;
+      else if(velocity.dot(diffVector) > 0)
+        velocity += correctionVector;
+      else if (velocity.dot(diffVector) < 0)
+        velocity -= correctionVector;
+     }
+    else
+      velocity += diffVector * agility;
+
+     this->setAbsDir(Quaternion(velocity, Vector(0,1,0)) * Quaternion ( -M_PI_2, Vector(0,1,0)));
+   }
+
+  velocity *= maxVelocity/velocity.len();
+  Vector v = this->velocity * (time);
+  this->shiftCoor(v);
+
+  if(this->tickLifeCycle(time))
+    this->deactivate();
+}
+
+/**
+ *  the function gets called, when the projectile is destroyed
+ */
+void GuidedMissile::destroy ()
+{
+  PRINTF(5)("DESTROY GuidedMissile\n");
+  this->lifeCycle = .95; //!< @todo calculate this usefully.
+  this->emitter->setSystem(GuidedMissile::explosionParticles);
+
+  this->emitter->setEmissionRate(1000.0);
+  this->emitter->setEmissionVelocity(50.0);
+//  this->deactivate();
+
+}
+
+
+void GuidedMissile::draw () const
+{
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+
+  float matrix[4][4];
+  glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z);
+  this->getAbsDir().matrix (matrix);
+  glMultMatrixf((float*)matrix);
+  glScalef(2.0, 2.0, 2.0);
+  this->getModel()->draw();
+
+  glPopMatrix();
+
+}
+
Index: branches/network/src/world_entities/projectiles/guided_missile.h
===================================================================
--- branches/network/src/world_entities/projectiles/guided_missile.h	(revision 6636)
+++ branches/network/src/world_entities/projectiles/guided_missile.h	(revision 6636)
@@ -0,0 +1,50 @@
+/*!
+ * @file guided_missile.h
+ * @brief a GuidedMissile Projectile
+*/
+
+#ifndef _GUIDED_MISSILE_H
+#define _GUIDED_MISSILE_H
+
+#include "projectile.h"
+
+class Weapon;
+class SpriteParticles;
+class ParticleEmitter;
+class FastFactory;
+class Aim;
+
+class GuidedMissile : public Projectile
+{
+  public:
+    GuidedMissile ();
+    virtual ~GuidedMissile ();
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void collidesWith(WorldEntity* entity, const Vector& location);
+
+    virtual void destroy ();
+
+    virtual void tick (float time);
+    virtual void draw () const;
+
+
+  private:
+    static FastFactory*               fastFactory;
+    static SpriteParticles*           trailParticles;
+    static SpriteParticles*           explosionParticles;
+
+    ParticleEmitter*                  emitter;
+    float                             agility;
+    float                             maxVelocity;
+    float                             speed;
+    Vector                            diffVector ;
+    Vector                            correctionVector;
+
+    WorldEntity* hitEntity; // FIXME TEMPORARY
+
+};
+
+#endif /* _GUIDED_MISSILE_H */
Index: branches/network/src/world_entities/projectiles/laser.cc
===================================================================
--- branches/network/src/world_entities/projectiles/laser.cc	(revision 6636)
+++ branches/network/src/world_entities/projectiles/laser.cc	(revision 6636)
@@ -0,0 +1,153 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer: Benjamin Grauer
+
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "laser.h"
+
+#include "fast_factory.h"
+
+#include "state.h"
+#include "class_list.h"
+#include "model.h"
+
+#include "particle_emitter.h"
+#include "sprite_particles.h"
+
+
+using namespace std;
+
+CREATE_FAST_FACTORY_STATIC(Laser, CL_LASER);
+
+/**
+ *  standard constructor
+*/
+Laser::Laser () : Projectile()
+{
+  this->setClassID(CL_LASER, "Laser");
+
+  this->loadModel("models/projectiles/laser.obj");
+
+  this->setMinEnergy(1);
+  this->setMaxEnergy(10);
+  this->lifeSpan = 5.0;
+
+  this->emitter = new ParticleEmitter(Vector(0,1,0), M_2_PI, 100, 5);
+  this->emitter->setParent(this);
+  this->emitter->setSpread(M_PI, M_PI);
+  this->emitter->setEmissionRate(300.0);
+  this->emitter->setEmissionVelocity(50.0);
+}
+
+
+/**
+ *  standard deconstructor
+*/
+Laser::~Laser ()
+{
+  // delete this->emitter;
+
+  /* this is normaly done by World.cc by deleting the ParticleEngine */
+  if (Laser::explosionParticles != NULL && ClassList::getList(CL_LASER)->size() <= 1)
+  {
+    //if (ClassList::exists(Laser::explosionParticles, CL_PARTICLE_SYSTEM))
+    //  delete Laser::explosionParticles;
+    PRINTF(1)("Deleting Laser Particles\n");
+    Laser::explosionParticles = NULL;
+  }
+
+}
+
+SpriteParticles* Laser::explosionParticles = NULL;
+
+void Laser::activate()
+{
+  if (unlikely(Laser::explosionParticles == NULL))
+  {
+    Laser::explosionParticles = new SpriteParticles(1000);
+    Laser::explosionParticles->setName("LaserExplosionParticles");
+    Laser::explosionParticles->setLifeSpan(.5, .3);
+    Laser::explosionParticles->setRadius(0.0, 10.0);
+    Laser::explosionParticles->setRadius(.5, 6.0);
+    Laser::explosionParticles->setRadius(1.0, 3.0);
+    Laser::explosionParticles->setColor(0.0, 1,1,0,.9);
+    Laser::explosionParticles->setColor(0.5, .8,.8,0,.5);
+    Laser::explosionParticles->setColor(1.0, .8,.8,.7,.0);
+  }
+}
+
+
+void Laser::deactivate()
+{
+  assert (Laser::explosionParticles != NULL);
+  Laser::explosionParticles->removeEmitter(this->emitter);
+  this->lifeCycle = 0.0;
+
+  this->toList(OM_NULL);
+  this->removeNode();
+  Laser::fastFactory->kill(this);
+}
+
+
+void Laser::collidesWith(WorldEntity* entity, const Vector& location)
+{
+  if (this->hitEntity != entity && entity->isA(CL_NPC))
+    this->destroy();
+  this->hitEntity = entity;
+}
+
+/**
+ *  signal tick, time dependent things will be handled here
+ * @param dt time since last tick
+*/
+void Laser::tick (float dt)
+{
+  //Vector v = *this->flightDirection * ( this->speed * time * 1000 + 0.1);
+  Vector v = this->velocity * dt;
+  this->shiftCoor(v);
+
+  if (this->tickLifeCycle(dt))
+    this->deactivate();
+}
+
+/**
+ *  the function gets called, when the projectile is destroyed
+*/
+void Laser::destroy ()
+{
+  PRINTF(5)("DESTROY Laser\n");
+  this->lifeCycle = .95; //!< @todo calculate this usefully.
+
+  this->emitter->setSystem(Laser::explosionParticles);
+}
+
+
+void Laser::draw () const
+{
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  glPushAttrib(GL_ENABLE_BIT);
+  glDisable(GL_LIGHTING);
+
+  float matrix[4][4];
+  glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z);
+  this->getAbsDir().matrix (matrix);
+  glMultMatrixf((float*)matrix);
+  glScalef(2.0, 2.0, 2.0);
+  this->getModel()->draw();
+  glPopAttrib();
+  glPopMatrix();
+}
+
Index: branches/network/src/world_entities/projectiles/laser.h
===================================================================
--- branches/network/src/world_entities/projectiles/laser.h	(revision 6636)
+++ branches/network/src/world_entities/projectiles/laser.h	(revision 6636)
@@ -0,0 +1,46 @@
+/*!
+ * @file laser.h
+ * @brief a projectile, that is been shooted by a weapon
+*/
+
+#ifndef _LASER_H
+#define _LASER_H
+
+#include "projectile.h"
+
+class Vector;
+class Weapon;
+class SpriteParticles;
+class ParticleEmitter;
+class FastFactory;
+
+class Laser : public Projectile
+{
+  public:
+    Laser ();
+    virtual ~Laser ();
+
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void collidesWith(WorldEntity* entity, const Vector& location);
+
+    virtual void destroy ();
+
+    virtual void tick (float dt);
+    virtual void draw () const;
+
+
+  private:
+    static FastFactory*               fastFactory;
+
+    static SpriteParticles*           explosionParticles;
+
+    ParticleEmitter*                  emitter;
+
+
+    WorldEntity* hitEntity; // FIXME TEMPORARY
+};
+
+#endif /* _LASER_H */
Index: branches/network/src/world_entities/projectiles/projectile.cc
===================================================================
--- branches/network/src/world_entities/projectiles/projectile.cc	(revision 6636)
+++ branches/network/src/world_entities/projectiles/projectile.cc	(revision 6636)
@@ -0,0 +1,117 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "projectile.h"
+
+#include "world_entity.h"
+#include "world_entities/weapons/weapon.h"
+#include "model.h"
+
+using namespace std;
+
+
+/**
+ *  standard constructor
+*/
+Projectile::Projectile () : WorldEntity()
+{
+  this->setClassID(CL_PROJECTILE, "Projectile");
+
+  this->lifeCycle = 0.0;
+  this->lifeSpan = 1.0f; /* sec */
+  this->target = NULL;
+  this->removeNode();
+}
+
+
+/**
+ *  standard deconstructor
+*/
+Projectile::~Projectile ()
+{
+  /*
+     do not delete the test projectModel, since it is pnode
+     and will be cleaned out by world
+  */
+  //delete this->projectileModel;
+}
+
+
+void Projectile::setMinEnergy(float energyMin)
+{
+  this->energyMin = energyMin;
+}
+
+
+/**
+ *  this sets the flight direction of the projectile
+ * @param directin in which to flight
+
+   this function will calculate a vector out of this to be used in the
+   tick function
+*/
+void Projectile::setFlightDirection(const Quaternion& flightDirection)
+{
+  Vector v(1, 0, 0);
+  this->flightDirection = flightDirection.apply(v);
+  this->flightDirection.normalize();
+}
+
+/**
+ *  sets the velocity vector to a spec speed
+ * @param velocity: vector of the velocity
+*/
+void Projectile::setVelocity(const Vector &velocity)
+{
+  //Vector offsetVel =
+  this->velocity = velocity;
+ // offsetVel.normalize();
+  //this->velocity += (offsetVel * 50.0);
+}
+
+
+
+void Projectile::setTarget(PNode* target)
+{
+  if (this->target == NULL)
+    this->target = new PNode(target, PNODE_PARENT_MODE_DEFAULT | PNODE_REPARENT_ON_PARENTS_REMOVE);
+  else
+    this->target->setParent(target);
+}
+
+
+/**
+ * signal tick, time dependent things will be handled here
+ * @param dt since last tick
+*/
+void Projectile::tick (float dt)
+{
+  Vector v = this->velocity * (dt);
+  this->shiftCoor(v);
+
+  if (this->tickLifeCycle(dt))
+    this->destroy();
+}
+
+
+/**
+ *  the function gets called, when the projectile is destroyed
+*/
+void Projectile::destroy ()
+{}
+
Index: branches/network/src/world_entities/projectiles/projectile.h
===================================================================
--- branches/network/src/world_entities/projectiles/projectile.h	(revision 6636)
+++ branches/network/src/world_entities/projectiles/projectile.h	(revision 6636)
@@ -0,0 +1,62 @@
+/*!
+ * @file projectile.h
+ * a projectile, that is been shooted by a weapon
+ *
+ * You can use this class to make some Projectiles/Bullets/Lasers/Rockets/etc.
+ *
+ */
+
+#ifndef _PROJECTILE_H
+#define _PROJECTILE_H
+
+#include "world_entity.h"
+
+class Projectile : public WorldEntity
+{
+  public:
+    Projectile ();
+    virtual ~Projectile ();
+
+    void setFlightDirection(const Quaternion& flightDirection);
+    void setVelocity(const Vector &velocity);
+    void setLifeSpan(float lifeSpan);
+
+
+    void setMinEnergy(float energyMin);
+    /** @returns the minimal charched energy */
+    inline float getMinEnergy() { return this->energyMin; };
+    /** @returns if the Projectile can be charged */
+    inline bool isChageable() { return this->bChargeable; };
+
+    void setTarget(PNode* target);
+
+    /** @brief This is called, when the Projectile is Emitted */
+    virtual void activate() = 0;
+    /** @brief This is called, when the Projectile is being destroyed, or deleted */
+    virtual void deactivate() = 0;
+
+    virtual void destroy ();
+
+    virtual void tick (float dt);
+    /** @brief convenience function
+     * @param dt the Time passed
+     * @returns true if the Projectile is past its lifeTime, false if it shall still live */
+    inline bool tickLifeCycle(float dt ) { this->lifeCycle += dt/this->lifeSpan;  return(unlikely(this->lifeCycle >= 1)); }
+
+
+  protected:
+    // energy
+    float                 energyMin;                 //!< The minimal Energy a Projectile needs to be emitted.
+    bool                  bChargeable;               //!< if the Projectile is Charegeable
+
+    float                 lifeCycle;                 //!< The percentage of the Lifetime done [0-1]
+    float                 lifeSpan;                  //!< The entire lifespan of the Shoot. in seconds
+
+    Vector                flightDirection;           //!< DOF direction in which the shoot flighs
+
+    Vector                velocity;                  //!< velocity of the projectile.
+
+    PNode*                target;                    //!< A target for guided Weapons.
+};
+
+#endif /* _PROJECTILE_H */
Index: branches/network/src/world_entities/projectiles/rocket.cc
===================================================================
--- branches/network/src/world_entities/projectiles/rocket.cc	(revision 6636)
+++ branches/network/src/world_entities/projectiles/rocket.cc	(revision 6636)
@@ -0,0 +1,182 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer: Benjamin Grauer
+
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "rocket.h"
+
+#include "fast_factory.h"
+
+#include "state.h"
+#include "class_list.h"
+
+#include "particle_emitter.h"
+#include "sprite_particles.h"
+
+
+using namespace std;
+
+CREATE_FAST_FACTORY_STATIC(Rocket, CL_ROCKET);
+
+/**
+ *  standard constructor
+*/
+Rocket::Rocket () : Projectile()
+{
+  this->setClassID(CL_ROCKET, "Rocket");
+
+  float modelSize = .3;
+  this->loadModel("models/projectiles/orx-rocket.obj", .3);
+
+  this->setMinEnergy(1);
+  this->setMaxEnergy(10);
+  this->lifeSpan = 5;
+
+  this->emitter = new ParticleEmitter(Vector(0,1,0), M_2_PI, 100, 5);
+  this->emitter->setParent(this);
+  this->emitter->setSpread(M_PI, M_PI);
+}
+
+
+/**
+ *  standard deconstructor
+*/
+Rocket::~Rocket ()
+{
+  // delete this->emitter;
+
+  /* this is normaly done by World.cc by deleting the ParticleEngine */
+  if (Rocket::trailParticles != NULL && ClassList::getList(CL_ROCKET)->size() <= 1)
+  {
+/*    if (ClassList::exists(Rocket::trailParticles, CL_PARTICLE_SYSTEM))
+      delete Rocket::trailParticles;*/
+    Rocket::trailParticles = NULL;
+  }
+  if (Rocket::explosionParticles != NULL && ClassList::getList(CL_ROCKET)->size() <= 1)
+  {
+/*    if (ClassList::exists(Rocket::explosionParticles, CL_PARTICLE_SYSTEM))
+      delete Rocket::explosionParticles;*/
+    Rocket::explosionParticles = NULL;
+  }
+
+}
+
+SpriteParticles* Rocket::trailParticles = NULL;
+SpriteParticles* Rocket::explosionParticles = NULL;
+
+void Rocket::activate()
+{
+  if (unlikely(Rocket::trailParticles == NULL))
+  {
+    Rocket::trailParticles = new SpriteParticles(2000);
+    Rocket::trailParticles->setName("RocketTrailParticles");
+    Rocket::trailParticles->setMaterialTexture("maps/radial-trans-noise.png");
+    Rocket::trailParticles->setLifeSpan(1.0, .3);
+    Rocket::trailParticles->setRadius(0.0, .5);
+    Rocket::trailParticles->setRadius(0.2, 2.0);
+    Rocket::trailParticles->setRadius(.5, .8);
+    Rocket::trailParticles->setRadius(1.0, .8);
+    Rocket::trailParticles->setColor(0.0, 1,0,0,.7);
+    Rocket::trailParticles->setColor(0.2, .8,.8,0,.5);
+    Rocket::trailParticles->setColor(0.5, .8,.8,.8,.8);
+    Rocket::trailParticles->setColor(1.0, .8,.8,.8,.0);
+  }
+  if (unlikely(Rocket::explosionParticles == NULL))
+  {
+    Rocket::explosionParticles = new SpriteParticles(200);
+    Rocket::explosionParticles->setName("RocketExplosionParticles");
+    Rocket::explosionParticles->setMaterialTexture("maps/radial-trans-noise.png");
+    Rocket::explosionParticles->setLifeSpan(.5, .3);
+    Rocket::explosionParticles->setRadius(0.0, 10);
+    Rocket::explosionParticles->setRadius(.5, 15.0);
+    Rocket::explosionParticles->setRadius(1.0, 10.0);
+    Rocket::explosionParticles->setColor(0.0, 0,1,0,1);
+    Rocket::explosionParticles->setColor(0.5, .8,.8,0,.8);
+    Rocket::explosionParticles->setColor(0.8, .8,.8,.3,.8);
+    Rocket::explosionParticles->setColor(1.0, 1,1,1,.0);
+  }
+
+  this->emitter->setSystem(Rocket::trailParticles);
+
+  this->updateNode(0);
+  this->emitter->setEmissionRate(45.0);
+  this->emitter->setEmissionVelocity(0.0);
+}
+
+
+void Rocket::deactivate()
+{
+  this->emitter->setSystem(NULL);
+  this->lifeCycle = 0.0;
+  this->toList(OM_NULL);
+
+//  GarbageCollector::getInstance()->collect(this);
+  this->toList(OM_DEAD);
+  Rocket::fastFactory->kill(this);
+}
+
+
+void Rocket::collidesWith(WorldEntity* entity, const Vector& location)
+{
+  if (this->hitEntity != entity)
+    this->destroy();
+  this->hitEntity = entity;
+}
+
+/**
+ *  signal tick, time dependent things will be handled here
+ * @param time since last tick
+*/
+void Rocket::tick (float dt)
+{
+  //Vector v = *this->flightDirection * ( this->speed * time * 1000 + 0.1);
+  Vector v = this->velocity * (dt);
+  this->shiftCoor(v);
+
+  if(this->tickLifeCycle(dt))
+    this->deactivate();
+}
+
+/**
+ *  the function gets called, when the projectile is destroyed
+*/
+void Rocket::destroy ()
+{
+  PRINTF(5)("DESTROY Rocket\n");
+  this->lifeCycle = .95; //!< @todo calculate this usefully.
+  this->emitter->setSystem(Rocket::explosionParticles);
+
+  this->emitter->setEmissionRate(1000.0);
+  this->emitter->setEmissionVelocity(50.0);
+//  this->deactivate();
+
+}
+
+
+void Rocket::draw () const
+{
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+
+  float matrix[4][4];
+  glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z);
+  this->getAbsDir().matrix (matrix);
+  glMultMatrixf((float*)matrix);
+  glScalef(2.0, 2.0, 2.0);
+  this->getModel()->draw();
+
+  glPopMatrix();
+}
+
Index: branches/network/src/world_entities/projectiles/rocket.h
===================================================================
--- branches/network/src/world_entities/projectiles/rocket.h	(revision 6636)
+++ branches/network/src/world_entities/projectiles/rocket.h	(revision 6636)
@@ -0,0 +1,47 @@
+/*!
+ * @file rocket.h
+ * @brief a Rocket Projectile
+*/
+
+#ifndef _ROCKET_H
+#define _ROCKET_H
+
+#include "projectile.h"
+
+class Vector;
+class Weapon;
+class SpriteParticles;
+class ParticleEmitter;
+class FastFactory;
+
+class Rocket : public Projectile
+{
+  public:
+    Rocket ();
+    virtual ~Rocket ();
+
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void collidesWith(WorldEntity* entity, const Vector& location);
+
+    virtual void destroy ();
+
+    virtual void tick (float time);
+    virtual void draw () const;
+
+
+  private:
+    static FastFactory*               fastFactory;
+    static SpriteParticles*           trailParticles;
+    static SpriteParticles*           explosionParticles;
+
+    ParticleEmitter*                  emitter;
+
+
+    WorldEntity* hitEntity; // FIXME TEMPORARY
+
+};
+
+#endif /* _ROCKET_H */
Index: branches/network/src/world_entities/projectiles/test_bullet.cc
===================================================================
--- branches/network/src/world_entities/projectiles/test_bullet.cc	(revision 6636)
+++ branches/network/src/world_entities/projectiles/test_bullet.cc	(revision 6636)
@@ -0,0 +1,181 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer: Benjamin Grauer
+
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "test_bullet.h"
+
+#include "fast_factory.h"
+
+#include "state.h"
+#include "class_list.h"
+
+#include "particle_emitter.h"
+#include "sprite_particles.h"
+
+
+using namespace std;
+
+CREATE_FAST_FACTORY_STATIC(TestBullet, CL_TEST_BULLET);
+
+/**
+ *  standard constructor
+*/
+TestBullet::TestBullet () : Projectile()
+{
+  this->setClassID(CL_TEST_BULLET, "TestBullet");
+
+  float modelSize = .3;
+  this->loadModel("models/projectiles/orx-rocket.obj", .3);
+
+  this->setMinEnergy(1);
+  this->setMaxEnergy(10);
+  this->lifeSpan = 2;
+
+  this->emitter = new ParticleEmitter(Vector(0,1,0), M_2_PI, 100, 5);
+  this->emitter->setParent(this);
+  this->emitter->setSpread(M_PI, M_PI);
+}
+
+
+/**
+ *  standard deconstructor
+*/
+TestBullet::~TestBullet ()
+{
+  // delete this->emitter;
+
+  /* this is normaly done by World.cc by deleting the ParticleEngine */
+  if (TestBullet::trailParticles != NULL && ClassList::getList(CL_TEST_BULLET)->size() <= 1)
+  {
+    if (ClassList::exists(TestBullet::trailParticles, CL_PARTICLE_SYSTEM))
+      delete TestBullet::trailParticles;
+    TestBullet::trailParticles = NULL;
+  }
+  if (TestBullet::explosionParticles != NULL && ClassList::getList(CL_TEST_BULLET)->size() <= 1)
+  {
+    if (ClassList::exists(TestBullet::explosionParticles, CL_PARTICLE_SYSTEM))
+      delete TestBullet::explosionParticles;
+    TestBullet::explosionParticles = NULL;
+  }
+
+}
+
+SpriteParticles* TestBullet::trailParticles = NULL;
+SpriteParticles* TestBullet::explosionParticles = NULL;
+
+void TestBullet::activate()
+{
+  if (unlikely(TestBullet::trailParticles == NULL))
+  {
+    TestBullet::trailParticles = new SpriteParticles(1000);
+    TestBullet::trailParticles->setName("TestBulletTrailParticles");
+    TestBullet::trailParticles->setLifeSpan(.5, .3);
+    TestBullet::trailParticles->setRadius(0.0, .5);
+    TestBullet::trailParticles->setRadius(0.5, 2.0);
+    TestBullet::trailParticles->setRadius(1.0, 5.0);
+    TestBullet::trailParticles->setColor(0.0, 1,0,0,.7);
+    TestBullet::trailParticles->setColor(0.5, .8,.8,0,.5);
+    TestBullet::trailParticles->setColor(1.0, .7,.7,.7,.0);
+  }
+  if (unlikely(TestBullet::explosionParticles == NULL))
+  {
+    TestBullet::explosionParticles = new SpriteParticles(1000);
+    TestBullet::explosionParticles->setName("TestBulletExplosionParticles");
+    TestBullet::explosionParticles->setLifeSpan(.5, .3);
+    TestBullet::explosionParticles->setRadius(0.0, 10);
+    TestBullet::explosionParticles->setRadius(.5, 20.0);
+    TestBullet::explosionParticles->setRadius(1.0, 3.0);
+    TestBullet::explosionParticles->setColor(0.0, 0,1,0,.9);
+    TestBullet::explosionParticles->setColor(0.5, .8,.8,0,.5);
+    TestBullet::explosionParticles->setColor(1.0, 1,1,1,.0);
+  }
+
+  this->emitter->setSystem(TestBullet::trailParticles);
+
+  this->emitter->setEmissionRate(20.0);
+  this->emitter->setEmissionVelocity(3.0);
+}
+
+
+void TestBullet::deactivate()
+{
+  this->emitter->setSystem(NULL);
+  this->lifeCycle = 0.0;
+  this->toList(OM_NULL);
+
+  TestBullet::fastFactory->kill(this);
+}
+
+
+void TestBullet::collidesWith(WorldEntity* entity, const Vector& location)
+{
+  if (this->hitEntity != entity && entity->isA(CL_NPC))
+    this->destroy();
+  this->hitEntity = entity;
+}
+
+/**
+ *  signal tick, time dependent things will be handled here
+ * @param time since last tick
+*/
+void TestBullet::tick (float time)
+{
+  //Vector v = *this->flightDirection * ( this->speed * time * 1000 + 0.1);
+  Vector v = this->velocity * (time);
+  this->shiftCoor(v);
+
+  this->lifeCycle += time/this->lifeSpan;
+  if( this->lifeCycle >= 1.0)
+    {
+      PRINTF(5)("FINALIZE==========================\n");
+      PRINTF(5)("current life cycle is: %f\n", this->lifeCycle);
+      PRINTF(5)("FINALIZE===========================\n");
+
+      this->deactivate();
+    }
+}
+
+/**
+ *  the function gets called, when the projectile is destroyed
+*/
+void TestBullet::destroy ()
+{
+  PRINTF(5)("DESTROY TestBullet\n");
+  this->lifeCycle = .95; //!< @todo calculate this usefully.
+  this->emitter->setSystem(TestBullet::explosionParticles);
+
+  this->emitter->setEmissionRate(30.0);
+  this->emitter->setEmissionVelocity(50.0);
+//  this->deactivate();
+
+}
+
+
+void TestBullet::draw () const
+{
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+
+  float matrix[4][4];
+  glTranslatef (this->getAbsCoor ().x, this->getAbsCoor ().y, this->getAbsCoor ().z);
+  this->getAbsDir().matrix (matrix);
+  glMultMatrixf((float*)matrix);
+  glScalef(2.0, 2.0, 2.0);
+  this->getModel()->draw();
+
+  glPopMatrix();
+}
+
Index: branches/network/src/world_entities/projectiles/test_bullet.h
===================================================================
--- branches/network/src/world_entities/projectiles/test_bullet.h	(revision 6636)
+++ branches/network/src/world_entities/projectiles/test_bullet.h	(revision 6636)
@@ -0,0 +1,46 @@
+/*!
+    \projectile.h
+  *  a projectile, that is been shooted by a weapon
+*/
+
+#ifndef _TEST_BULLET_H
+#define _TEST_BULLET_H
+
+#include "projectile.h"
+
+class Vector;
+class Weapon;
+class SpriteParticles;
+class ParticleEmitter;
+class FastFactory;
+
+class TestBullet : public Projectile
+{
+  public:
+    TestBullet ();
+    virtual ~TestBullet ();
+
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void collidesWith(WorldEntity* entity, const Vector& location);
+
+    virtual void destroy ();
+
+    virtual void tick (float time);
+    virtual void draw () const;
+
+  private:
+    static FastFactory*               fastFactory;
+    static SpriteParticles*           trailParticles;
+    static SpriteParticles*           explosionParticles;
+
+    ParticleEmitter*                  emitter;
+
+
+    WorldEntity* hitEntity; // FIXME TEMPORARY
+
+};
+
+#endif /* _TEST_BULLET_H */
Index: branches/network/src/world_entities/satellite.cc
===================================================================
--- branches/network/src/world_entities/satellite.cc	(revision 6636)
+++ branches/network/src/world_entities/satellite.cc	(revision 6636)
@@ -0,0 +1,64 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "satellite.h"
+
+#include "objModel.h"
+#include "vector.h"
+
+
+using namespace std;
+
+/**
+ *  standard constructor
+*/
+Satellite::Satellite (Vector axis, float speed)
+{
+  this->setClassID(CL_SATELLITE, "Satellite");
+
+  this->loadModel("cube");
+  this->speed = speed;
+  this->axis = new Vector();
+  *this->axis = axis;
+}
+
+/**
+ *  standard destructor
+*/
+Satellite::~Satellite ()
+{
+}
+
+
+/**
+ *  this method is called every frame
+ * @param time: the time in seconds that has passed since the last tick
+
+   Handle all stuff that should update with time inside this method (movement, animation, etc.)
+*/
+void Satellite::tick(float time)
+{
+  float w = this->speed * M_PI;
+
+  Quaternion rotation(w * time, *this->axis);
+  Quaternion v = this->getRelDir();
+
+  this->setRelDir(v * rotation);
+}
+
Index: branches/network/src/world_entities/satellite.h
===================================================================
--- branches/network/src/world_entities/satellite.h	(revision 6636)
+++ branches/network/src/world_entities/satellite.h	(revision 6636)
@@ -0,0 +1,36 @@
+/*!
+ * @file world_entity.h
+  *  Definition of the basic WorldEntity
+*/
+
+#ifndef _SATELLITE_H
+#define _SATELLITE_H
+
+#include "world_entity.h"
+#include "comincl.h"
+#include "resource_manager.h"
+
+
+class CharacterAttributes;
+class Model;
+
+
+//! Basic class from which all interactive stuff in the world is derived from
+class Satellite : public WorldEntity
+{
+  friend class World;
+
+ public:
+  Satellite (Vector axis, float speed);
+  virtual ~Satellite ();
+
+  virtual void tick (float time);
+
+ private:
+  Vector*       axis;
+  float         speed;
+
+
+};
+
+#endif /* _SATELLITE_H */
Index: branches/network/src/world_entities/skybox.cc
===================================================================
--- branches/network/src/world_entities/skybox.cc	(revision 6636)
+++ branches/network/src/world_entities/skybox.cc	(revision 6636)
@@ -0,0 +1,346 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "skybox.h"
+
+#include "load_param.h"
+#include "factory.h"
+#include "static_model.h"
+
+#include "material.h"
+#include "texture.h"
+
+#include "network_game_manager.h"
+#include "converter.h"
+
+using namespace std;
+
+CREATE_FACTORY(SkyBox, CL_SKYBOX);
+
+/**
+ * Constructs a SkyBox and takes fileName as a map.
+ * @param fileName the file to take as input for the SkyBox
+*/
+SkyBox::SkyBox(const char* fileName)
+{
+  this->preInit();
+  if (fileName)
+    this->setTextureAndType(fileName, ".jpg");
+  this->postInit();
+}
+
+/**
+ *  initializes a skybox from a XmlElement
+*/
+SkyBox::SkyBox(const TiXmlElement* root)
+{
+  this->preInit();
+
+  this->loadParams(root);
+
+  this->postInit();
+}
+
+void SkyBox::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+
+  LoadParam(root, "Materialset", this, SkyBox, setTexture)
+      .describe("Sets the material on the SkyBox. The string must be the path relative to the data-dir, and without a trailing .jpg");
+
+  LoadParam(root, "Size", this, SkyBox, setSize)
+      .describe("Sets the Size of the SkyBox (normally this should be 90% of the maximal viewing Distance).");
+}
+
+void SkyBox::preInit()
+{
+  this->setClassID(CL_SKYBOX, "SkyBox");
+  this->toList(OM_ENVIRON_NOTICK);
+  //this->size = 100.0;
+  this->textureSize = 1024.0f;
+
+  for (int i = 0; i < 6; i++)
+    {
+      this->material[i] = new Material();
+      this->material[i]->setIllum(3);
+      this->material[i]->setDiffuse(0.0,0.0,0.0);
+      this->material[i]->setSpecular(0.0,0.0,0.0);
+      this->material[i]->setAmbient(2.0, 2.0, 2.0);
+
+      this->cubeTexture[i] = NULL;
+    }
+  this->setParentMode(PNODE_MOVEMENT);
+
+  this->textureName = NULL;
+}
+
+void SkyBox::postInit()
+{
+  this->rebuild();
+}
+
+
+/**
+ *  default destructor
+*/
+SkyBox::~SkyBox()
+{
+  PRINTF(5)("Deleting SkyBox\n");
+  this->setModel(NULL); //< so that WorldEntity does not try to delete it again.
+  for (int i = 0; i < 6; i++)
+  {
+    delete this->material[i];
+    delete this->cubeTexture[i];
+  }
+}
+
+/**
+ *  sets A set of textures when just giving a Name and an extension:
+
+   usage: give this function an argument like
+   setTexture("skybox", "jpg");
+   and it will convert this to
+   setTextures("skybox_top.jpg", "skybox_bottom.jpg", "skybox_left.jpg",
+               "skybox_right.jpg", "skybox_front.jpg", "skybox_back.jpg");
+*/
+void SkyBox::setTextureAndType(const char* name, const char* extension)
+{
+  char* top    = new char[strlen(name)+strlen(extension)+ 10];
+  char* bottom = new char[strlen(name)+strlen(extension)+ 10];
+  char* left   = new char[strlen(name)+strlen(extension)+ 10];
+  char* right  = new char[strlen(name)+strlen(extension)+ 10];
+  char* front  = new char[strlen(name)+strlen(extension)+ 10];
+  char* back   = new char[strlen(name)+strlen(extension)+ 10];
+
+  sprintf(top, "%s_top.%s", name, extension);
+  sprintf(bottom, "%s_bottom.%s", name, extension);
+  sprintf(left, "%s_left.%s", name, extension);
+  sprintf(right, "%s_right.%s", name, extension);
+  sprintf(front, "%s_front.%s", name, extension);
+  sprintf(back, "%s_back.%s", name, extension);
+
+  this->setTextures(top, bottom, left, right, front, back);
+
+  // deleted alocated memory of this function
+  delete []top;
+  delete []bottom;
+  delete []left;
+  delete []right;
+  delete []front;
+  delete []back;
+}
+
+/**
+ *  Defines which textures should be loaded onto the SkyBox.
+ * @param top the top texture.
+ * @param bottom the bottom texture.
+ * @param left the left texture.
+ * @param right the right texture.
+ * @param front the front texture.
+ * @param back the back texture.
+*/
+void SkyBox::setTextures(const char* top, const char* bottom, const char* left,
+                          const char* right, const char* front, const char* back)
+{
+  this->material[0]->setDiffuseMap(top);
+  this->material[1]->setDiffuseMap(bottom);
+  this->material[2]->setDiffuseMap(left);
+  this->material[3]->setDiffuseMap(right);
+  this->material[4]->setDiffuseMap(front);
+  this->material[5]->setDiffuseMap(back);
+  if (GLEW_EXT_texture_cube_map)
+    this->loadCubeMapTextures(top, bottom, left, right, front, back);
+}
+
+void SkyBox::loadCubeMapTextures(const char* top, const char* bottom, const char* left,
+                                  const char* right, const char* front, const char* back)
+{
+  this->cubeTexture[0] = new Texture (top, GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT);
+  this->cubeTexture[1] = new Texture (bottom, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT);
+  this->cubeTexture[2] = new Texture (left, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT);
+  this->cubeTexture[3] = new Texture (right, GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT);
+  this->cubeTexture[4] = new Texture (front, GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT);
+  this->cubeTexture[5] = new Texture (back, GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT);
+}
+
+void SkyBox::enableCubeMap()
+{
+  glEnable(GL_TEXTURE_2D);
+  glEnable(GL_TEXTURE_CUBE_MAP_EXT);
+  glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT);
+  glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT);
+  glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT);
+  glEnable(GL_TEXTURE_GEN_S);
+  glEnable(GL_TEXTURE_GEN_T);
+  glEnable(GL_TEXTURE_GEN_R);
+
+}
+
+void SkyBox::disableCubeMap()
+{
+  glDisable(GL_TEXTURE_CUBE_MAP_EXT);
+  glDisable(GL_TEXTURE_2D);
+  glDisable(GL_TEXTURE_GEN_S);
+  glDisable(GL_TEXTURE_GEN_T);
+  glDisable(GL_TEXTURE_GEN_R);
+
+  glDisable(GL_TEXTURE_GEN_S);
+  glDisable(GL_TEXTURE_GEN_T);
+  glDisable(GL_TEXTURE_GEN_R);
+}
+
+
+
+/**
+ * @param size The new size of the SkyBox
+
+ * do not forget to rebuild the SkyBox after this.
+*/
+void SkyBox::setSize(float size)
+{
+  this->size = size;
+}
+
+
+
+void SkyBox::draw()
+{
+  glPushAttrib(GL_ENABLE_BIT);
+//   glPushAttrib(GL_LIGHTING_BIT);
+  glDisable(GL_LIGHTING);
+
+  WorldEntity::draw();
+
+  glPopAttrib();
+
+}
+
+
+/**
+ *  rebuilds the SkyBox
+
+   this must be done, when changing the Size of the Skybox (runtime-efficency)
+*/
+void SkyBox::rebuild()
+{
+  StaticModel* model = new StaticModel();
+
+  model->addVertex (-0.5*size, -0.5*size, 0.5*size);
+  model->addVertex (0.5*size, -0.5*size, 0.5*size);
+  model->addVertex (-0.5*size, 0.5*size, 0.5*size);
+  model->addVertex (0.5*size, 0.5*size, 0.5*size);
+  model->addVertex (-0.5*size, 0.5*size, -0.5*size);
+  model->addVertex (0.5*size, 0.5*size, -0.5*size);
+  model->addVertex (-0.5*size, -0.5*size, -0.5*size);
+  model->addVertex (0.5*size, -0.5*size, -0.5*size);
+
+//   model->addVertexTexture (0.0, 1.0);
+//   model->addVertexTexture (1.0, 1.0);
+//   model->addVertexTexture (1.0, 0.0);
+//   model->addVertexTexture (0.0, 0.0);
+
+  model->addVertexTexture (1.0/this->textureSize, (this->textureSize - 1.0)/this->textureSize);
+  model->addVertexTexture ((this->textureSize - 1.0)/this->textureSize, (this->textureSize - 1.0)/this->textureSize);
+  model->addVertexTexture ((this->textureSize - 1.0)/this->textureSize, 1.0/this->textureSize);
+  model->addVertexTexture (1.0/this->textureSize, 1.0/this->textureSize);
+
+
+  model->addVertexNormal (0.0, 0.0, 1.0);
+  model->addVertexNormal (0.0, 1.0, 0.0);
+  model->addVertexNormal (0.0, 0.0, -1.0);
+  model->addVertexNormal (0.0, -1.0, 0.0);
+  model->addVertexNormal (1.0, 0.0, 0.0);
+  model->addVertexNormal (-1.0, 0.0, 0.0);
+
+  model->setMaterial(material[0]);
+  model->addFace (4, VERTEX_TEXCOORD_NORMAL, 2,0,3, 3,1,3, 5,2,3, 4,3,3); // top
+  model->setMaterial(material[1]);
+  model->addFace (4, VERTEX_TEXCOORD_NORMAL, 6,0,1, 7,1,1, 1,2,1, 0,3,1); // bottom
+  model->setMaterial(material[2]);
+  model->addFace (4, VERTEX_TEXCOORD_NORMAL, 4,2,2, 5,3,2, 7,0,2, 6,1,2); // left
+  model->setMaterial(material[3]);
+  model->addFace (4, VERTEX_TEXCOORD_NORMAL, 0,0,0, 1,1,0, 3,2,0, 2,3,0); // right
+  model->setMaterial(material[4]);
+  model->addFace (4, VERTEX_TEXCOORD_NORMAL, 1,0,5, 7,1,5, 5,2,5, 3,3,5); // front
+  model->setMaterial(material[5]);
+  model->addFace (4, VERTEX_TEXCOORD_NORMAL, 6,0,4, 0,1,4, 2,2,4, 4,3,4); // back
+
+  model->finalize();
+
+  this->setModel(model);
+}
+
+int SkyBox::writeBytes( const byte * data, int length, int sender )
+{
+  setRequestedSync( false );
+  setIsOutOfSync( false );
+
+  SYNCHELP_READ_BEGIN();
+
+  SYNCHELP_READ_FKT( WorldEntity::writeState );
+
+  SYNCHELP_READ_FLOAT( size );
+  if ( textureName )
+  {
+    delete[] textureName;
+    textureName = NULL;
+  }
+  SYNCHELP_READ_STRINGM( textureName );
+
+  this->setSize( size );
+  this->setTextureAndType( textureName, "jpg" );
+  this->rebuild();
+
+  return SYNCHELP_READ_N;
+}
+
+
+
+int SkyBox::readBytes( byte * data, int maxLength, int * reciever )
+{
+  if ( isOutOfSync() && !requestedSync() && this->getHostID()!=this->getOwner() )
+  {
+    (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
+    setRequestedSync( true );
+  }
+
+  int rec = this->getRequestSync();
+  if ( rec > 0 )
+  {
+    *reciever = rec;
+
+    SYNCHELP_WRITE_BEGIN();
+
+    SYNCHELP_WRITE_FKT( WorldEntity::readState );
+
+    SYNCHELP_WRITE_FLOAT(this->size);
+    SYNCHELP_WRITE_STRING(this->textureName);
+
+    return SYNCHELP_WRITE_N;
+  }
+
+  *reciever = 0;
+  return 0;
+}
+
+void SkyBox::writeDebug( ) const
+{
+}
+
+void SkyBox::readDebug( ) const
+{
+}
Index: branches/network/src/world_entities/skybox.h
===================================================================
--- branches/network/src/world_entities/skybox.h	(revision 6636)
+++ branches/network/src/world_entities/skybox.h	(revision 6636)
@@ -0,0 +1,71 @@
+/*!
+ * @file skybox.h
+ *  Definition of the SkyBox, that handles the Display of an atmosphere for orxonox.
+ *
+ * A SkyBox is always centered at the current working Camera, and will only obey the cameras
+ * movment but not its rotation.
+*/
+
+#ifndef _SKYBOX_H
+#define _SKYBOX_H
+
+/* INCLUDES */
+#include "world_entity.h"
+
+/* FORWARD DECLARATION */
+class Material;
+class Texture;
+
+//! A Class to handle a SkyBox
+class SkyBox : public WorldEntity
+{
+ public:
+  SkyBox(const char* fileName = NULL);
+  SkyBox(const TiXmlElement* root);
+
+  virtual ~SkyBox();
+
+  void init();
+  void preInit();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void postInit();
+
+  virtual void draw();
+
+  void setSize(float size);
+  /** assumes jpg as input-format */
+  void setTexture(const char* name) { if (textureName) delete[] textureName; textureName = new char[strlen(name)+1]; strcpy(textureName, name); this->setTextureAndType (name, "jpg"); };
+
+  void setTextureAndType(const char* name, const char* extension);
+  void setTextures(const char* top, const char* bottom, const char* left,
+                   const char* right, const char* front, const char* back);
+
+  void loadCubeMapTextures(const char* top, const char* bottom, const char* left,
+                           const char* right, const char* front, const char* back);
+
+  static void enableCubeMap();
+  static void disableCubeMap();
+
+  virtual int       writeBytes(const byte* data, int length, int sender);
+  virtual int       readBytes(byte* data, int maxLength, int * reciever);
+  virtual void      writeDebug() const;
+  virtual void      readDebug() const;
+
+ private:
+  void rebuild();
+
+  Material*       material[6];     //!< Materials for the SkyBox. sorted by number (0-5) top, bottom, left, right, front, back
+  Texture*        cubeTexture[6];  //!< Textures for the CubeMap.
+
+  float           size;            //!< Size of the SkyBox. This should match the frustum maximum range.
+  float           textureSize;     //!< this is the length of a texture (assumes a square texture)
+  char*           textureName;     //!< Name of the Texture
+
+};
+
+#endif  /* _SKYBOX_H */
+
+
+
Index: branches/network/src/world_entities/skysphere.cc
===================================================================
--- branches/network/src/world_entities/skysphere.cc	(revision 6636)
+++ branches/network/src/world_entities/skysphere.cc	(revision 6636)
@@ -0,0 +1,121 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: David Gruetter
+   co-programmer: Benjamin Grauer
+
+   Created by Dave: this file is actually quite similar to player.cc and so is
+   skybox.h similar to player.h
+   With that said, things should be clear:)
+
+   Edited:
+   Bensch: more constructors, changeability, comments...
+   Patrick: giving it the common orxonox style, not much to do... good work Dave!
+
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "skysphere.h"
+#include "stdincl.h"
+
+#include "material.h"
+#include "debug.h"
+
+
+using namespace std;
+
+/**
+ *  Constructs a SkySphere and takes fileName as a map.
+ * @param fileName the file to take as input for the skysphere
+*/
+Skysphere::Skysphere(char* fileName)
+{
+  this->setClassID(CL_SKYSPHERE, "SkySphere");
+  this->toList(OM_ENVIRON_NOTICK);
+  if (fileName == NULL)
+    this->initialize("pictures/sky-replace.jpg");
+  else
+    this->initialize(fileName);
+}
+
+
+/**
+ *  default destructor
+*/
+Skysphere::~Skysphere()
+{
+  PRINTF(3)("Deleting the SkySphere\n");
+  delete this->skyMaterial;
+  gluDeleteQuadric(this->sphereObj);
+}
+
+/**
+ *  initializes the Skysphere.
+ * @param fileName the file to take as input for the skysphere
+*/
+void Skysphere::initialize(char* fileName)
+{
+  PRINTF(1)("initializing the Skysphere with Material %s.\n", fileName);
+  this->sphereObj = gluNewQuadric();
+  this->setParentMode(PNODE_MOVEMENT);
+
+  gluQuadricTexture(this->sphereObj, GL_TRUE);
+  this->setRadius(1900.0);
+
+  this->skyMaterial = new Material("Sky");
+  this->setTexture(fileName);
+  this->skyMaterial->setIllum(3);
+  this->skyMaterial->setAmbient(1.0, 1.0, 1.0);
+}
+
+
+/**
+ *  Defines which texture should be loaded onto the skysphere.
+ * @param fileName The filename of the Texture
+*/
+void Skysphere::setTexture(char* fileName)
+{
+  this->skyMaterial->setDiffuseMap(fileName);
+}
+
+
+/**
+ *  draws the Skysphere
+
+   This part is normally precessed in the "Painting Phase".
+*/
+void Skysphere::draw() const
+{
+  glPushMatrix();
+  glMatrixMode(GL_MODELVIEW);
+  Vector r = this->getAbsCoor();
+  glTranslatef(r.x, r.y, r.z);
+
+  //glRotatef(-30, 1, 0, 0);
+  //glRotatef(95.0f, 0.0f, 0.0f, 1.0f);
+  //glRotatef(-250.0f, 0.0, 1.0f, 0.0f);
+
+  skyMaterial->select();
+  gluSphere(this->sphereObj, this->sphereRadius, 20, 20);
+  glPopMatrix();
+}
+
+
+/**
+ *  sets the Radius of the Sphere.
+ * @param radius The Radius of The Sphere
+*/
+void Skysphere::setRadius(float radius)
+{
+  this->sphereRadius = radius;
+}
Index: branches/network/src/world_entities/skysphere.h
===================================================================
--- branches/network/src/world_entities/skysphere.h	(revision 6636)
+++ branches/network/src/world_entities/skysphere.h	(revision 6636)
@@ -0,0 +1,49 @@
+/*!
+ * @file skysphere.h
+  *  Definition of the Skysphere, that handles the Display of an atmosphere of orxonox.
+
+    A SkySphere is always centered at the current working Camera, and will only obey the cameras
+    movment but not its rotation.
+
+    @todo self-rotation
+    @todo handle reference to parent-object
+*/
+
+#ifndef _SKYSPHERE_H
+#define _SKYSPHERE_H
+
+/* INCLUDES */
+#include "world_entity.h"
+#include "glincl.h"
+
+/* FORWARD DECLARATION */
+class Material;
+class Vector;
+
+//! A Class to handle a SkySphere
+class Skysphere : public WorldEntity
+{
+
+ public:
+  Skysphere(char* fileName = NULL);
+  virtual ~Skysphere();
+  void destroy();
+
+  void setRadius(float radius);
+  void setTexture(char* fileName);
+
+  virtual void draw() const;
+
+  private:
+    void initialize(char* fileName);
+
+ private:
+  GLUquadricObj*    sphereObj;           //!< A Placeholder for the SkySphere.
+  Material*         skyMaterial;         //!< A Material for the SkySphere.
+  float             sphereRadius;        //!< Radius of the SkySphere. This should match the frustum maximum range.
+};
+
+#endif  /* _SKYSPHERE_H */
+
+
+
Index: branches/network/src/world_entities/space_ships/helicopter.cc
===================================================================
--- branches/network/src/world_entities/space_ships/helicopter.cc	(revision 6636)
+++ branches/network/src/world_entities/space_ships/helicopter.cc	(revision 6636)
@@ -0,0 +1,489 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "helicopter.h"
+
+#include "weapons/weapon_manager.h"
+#include "weapons/test_gun.h"
+#include "weapons/turret.h"
+#include "weapons/cannon.h"
+
+#include "factory.h"
+#include "key_mapper.h"
+#include "event_handler.h"
+#include "state.h"
+
+#include "graphics_engine.h"
+
+using namespace std;
+
+CREATE_FACTORY(Helicopter, CL_HELICOPTER);
+
+/**
+ *  creates the controlable Spaceship
+ */
+Helicopter::Helicopter()
+{
+  this->init();
+}
+
+/**
+ *  destructs the spaceship, deletes alocated memory
+ */
+Helicopter::~Helicopter ()
+{
+}
+
+/**
+ * loads a Spaceships information from a specified file.
+ * @param fileName the name of the File to load the spaceship from (absolute path)
+ */
+Helicopter::Helicopter(const char* fileName)
+{
+  this->init();
+  TiXmlDocument doc(fileName);
+
+  if(!doc.LoadFile())
+  {
+    PRINTF(2)("Loading file %s failed for Helicopter.\n", fileName);
+    return;
+  }
+
+  this->loadParams(doc.RootElement());
+}
+
+/**
+ *  creates a new Spaceship from Xml Data
+ * @param root the xml element containing spaceship data
+
+   @todo add more parameters to load
+*/
+Helicopter::Helicopter(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+
+  //weapons:
+  Weapon* wpRight = new TestGun(0);
+  wpRight->setName("testGun Right");
+  Weapon* wpLeft = new TestGun(1);
+  wpLeft->setName("testGun Left");
+  Weapon* cannon = dynamic_cast<Weapon*>(Factory::fabricate(CL_CANNON));
+
+  cannon->setName("BFG");
+
+  this->addWeapon(wpLeft, 1, 0);
+  this->addWeapon(wpRight,1 ,1);
+  this->addWeapon(cannon, 0, 6);
+
+  //this->addWeapon(turret, 3, 0);
+
+  this->getWeaponManager()->changeWeaponConfig(1);
+  dynamic_cast<Element2D*>(this->getWeaponManager()->getFixedTarget())->setVisibility( false);
+}
+
+
+/**
+ * initializes a Helicopter
+ */
+void Helicopter::init()
+{
+//  this->setRelDir(Quaternion(M_PI, Vector(1,0,0)));
+  this->setClassID(CL_HELICOPTER, "Helicopter");
+
+  PRINTF(4)("SPACESHIP INIT\n");
+
+  this->loadModel("models/ships/helicopter_#.obj", 1.0);
+
+  EventHandler::getInstance()->grabEvents(true);
+
+  bUp = bDown = bLeft = bRight = bAscend = bDescend = bRollL = bRollR = false;
+  bFire = false;
+  xMouse = yMouse = 0;
+  mouseSensitivity = 0.001;
+  rotorspeed = 1;
+  tailrotorspeed = 0;
+
+  cycle = 0.0;
+
+
+  travelSpeed = 15.0;
+  this->velocity = Vector(0.0,0.0,0.0);
+  this->velocityDir = Vector(1.0,0.0,0.0);
+
+//   GLGuiButton* button = new GLGuiPushButton();
+//   button->show();
+//   button->setLabel("orxonox");
+//   button->setBindNode(this);
+
+  //add events to the eventlist
+  registerEvent(SDLK_w);
+  registerEvent(SDLK_s);
+  registerEvent(SDLK_a);
+  registerEvent(SDLK_d);
+  registerEvent(SDLK_q);
+  registerEvent(SDLK_e);
+  registerEvent(SDLK_c);
+  registerEvent(KeyMapper::PEV_FIRE1);
+  registerEvent(KeyMapper::PEV_NEXT_WEAPON);
+  registerEvent(KeyMapper::PEV_PREVIOUS_WEAPON);
+  registerEvent(SDLK_PAGEUP);
+  registerEvent(SDLK_PAGEDOWN);
+  registerEvent(EV_MOUSE_MOTION);
+
+  this->getWeaponManager()->setSlotCount(7);
+
+  this->getWeaponManager()->setSlotPosition(0, Vector(-2.6, .1, -3.0));
+  this->getWeaponManager()->setSlotCapability(0, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+
+  this->getWeaponManager()->setSlotPosition(1, Vector(-2.6, .1, 3.0));
+  this->getWeaponManager()->setSlotCapability(1, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+
+  this->getWeaponManager()->setSlotPosition(2, Vector(-1.5, .5, -.5));
+  this->getWeaponManager()->setSlotDirection(2, Quaternion(-M_PI_4*.5, Vector(1,0,0)));
+
+  this->getWeaponManager()->setSlotPosition(3, Vector(-1.5, .5, .5));
+  this->getWeaponManager()->setSlotDirection(3, Quaternion(M_PI_4*.5, Vector(1,0,0)));
+
+  this->getWeaponManager()->setSlotPosition(4, Vector(-1.5, -.5, .5));
+  this->getWeaponManager()->setSlotDirection(4, Quaternion(-M_PI_4*.5+M_PI, Vector(1,0,0)));
+
+  this->getWeaponManager()->setSlotPosition(5, Vector(-1.5, -.5, -.5));
+  this->getWeaponManager()->setSlotDirection(5, Quaternion(+M_PI_4*.5-M_PI, Vector(1,0,0)));
+//
+   this->getWeaponManager()->setSlotPosition(6, Vector(-1, 0.0, 0));
+   this->getWeaponManager()->setSlotCapability(6, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+   //
+//   this->getWeaponManager()->setSlotPosition(8, Vector(-2.5, -0.3, -2.0));
+//   this->getWeaponManager()->setSlotDirection(8, Quaternion(-M_PI, Vector(1,0,0)));
+//
+//   this->getWeaponManager()->setSlotPosition(9, Vector(-2.5, -0.3, 2.0));
+//   this->getWeaponManager()->setSlotDirection(9, Quaternion(+M_PI, Vector(1,0,0)));:
+
+  this->getWeaponManager()->getFixedTarget()->setParent(this);
+  this->getWeaponManager()->getFixedTarget()->setRelCoor(100000,0,0);
+
+  dynamic_cast<Element2D*>(this->getWeaponManager()->getFixedTarget())->setVisibility( false);
+
+}
+
+/**
+ * loads the Settings of a Helicopter from an XML-element.
+ * @param root the XML-element to load the Spaceship's properties from
+ */
+void Helicopter::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+}
+
+
+
+
+void Helicopter::enter()
+{
+  dynamic_cast<Element2D*>(this->getWeaponManager()->getFixedTarget())->setVisibility( true);
+  this->attachCamera();
+
+
+}
+
+void Helicopter::leave()
+{
+  dynamic_cast<Element2D*>(this->getWeaponManager()->getFixedTarget())->setVisibility( false);
+  this->detachCamera();
+
+}
+
+
+/**
+ *  effect that occurs after the Helicopter is spawned
+*/
+void Helicopter::postSpawn ()
+{
+  //setCollision(new CollisionCluster(1.0, Vector(0,0,0)));
+}
+
+/**
+ *  the action occuring if the spaceship left the game
+*/
+void Helicopter::leftWorld ()
+{}
+
+/**
+ *  this function is called, when two entities collide
+ * @param entity: the world entity with whom it collides
+ *
+ * Implement behaviour like damage application or other miscellaneous collision stuff in this function
+ */
+void Helicopter::collidesWith(WorldEntity* entity, const Vector& location)
+{
+  if (entity->isA(CL_TURRET_POWER_UP))
+  {
+    this->ADDWEAPON();
+    }
+//  PRINTF(3)("collision %s vs %s @ (%f,%f,%f)\n", this->getClassName(), entity->getClassName(), location.x, location.y, location.z);
+}
+
+
+
+/**
+ *  the function called for each passing timeSnap
+ * @param time The timespan passed since last update
+*/
+void Helicopter::tick (float time)
+{
+  tailrotorspeed += xMouse/20;
+  if (tailrotorspeed >= 0.07) tailrotorspeed = 0.07;
+  else if (tailrotorspeed <= -0.07) tailrotorspeed = -0.07;
+
+  if (tailrotorspeed > 0.0008) tailrotorspeed -= 0.001;
+  else if (tailrotorspeed < -0.0008) tailrotorspeed += 0.001;
+  if (tailrotorspeed <= 0.001 && tailrotorspeed >= -0.001) tailrotorspeed = 0;
+
+  // spaceship controlled movement
+  this->calculateVelocity(time);
+
+  Vector move = (velocity);
+
+  // this is the air friction (necessary for a smooth control)
+  if(velocity.len() != 0) velocity -= velocity*0.1;
+
+  //physics: Gravity
+  this->shiftCoor(Vector(0,-1,0));
+
+  this->shiftCoor(getAbsDirY()*rotorspeed);
+
+  //hoover effect
+  cycle += time;
+  this->shiftCoor(Vector(0,1,0)*cos(this->cycle*2.0)*0.02);
+
+  //readjust
+ // if (this->getAbsDirZ().y > 0.1) this->shiftDir(Quaternion(time*0.3, Vector(1,0,0)));
+  //else if (this->getAbsDirZ().y < -0.1) this->shiftDir(Quaternion(-time*0.3, Vector(1,0,0)));
+
+  //SDL_WarpMouse(GraphicsEngine::getInstance()->getResolutionX()/2, GraphicsEngine::getInstance()->getResolutionY()/2);
+
+  this->shiftCoor (move);
+  this->shiftDir(Quaternion(-M_PI/4*tailrotorspeed, Vector(0,1,0)));
+
+  this->getWeaponManager()->tick(time);
+  // weapon system manipulation
+  this->weaponAction();
+}
+
+/**
+ *  calculate the velocity
+ * @param time the timeslice since the last frame
+*/
+void Helicopter::calculateVelocity (float time)
+{
+  Vector accel(0.0, 0.0, 0.0);
+  Vector rot(0.0, 0.0, 0.0);
+  float rotVal = 0.0;
+  /* FIXME: calculating the direction and orthDirection every timeSlice is redundant! save it somewhere */
+  /* calculate the direction in which the craft is heading  */
+
+  if( this->bUp )
+   {
+     //this->shiftCoor(this->getAbsDirX());
+     //accel -= this->getAbsDirY();
+     rot += Vector (0,0,1);
+     rotVal -= time/5;
+   }
+   else
+   {
+       if(this->getAbsDirX().y < -.02) this->shiftDir(Quaternion(time/8, Vector(0,0,1)));
+   }
+
+  if( this->bDown )
+   {
+     //this->shiftCoor((this->getAbsDirX())*-1);
+     //accel -= this->getAbsDirY();
+     rot += Vector (0,0,1);
+     rotVal += time/5;
+   }
+   else
+   {
+         if(this->getAbsDirX().y > 0.02) this->shiftDir(Quaternion(-time/8, Vector(0,0,1)));
+   }
+
+  if( this->bLeft /* > -this->getRelCoor().z*2*/)
+  {
+    //this->shiftDir(Quaternion(time, Vector(0,1,0)));
+    //accel -= this->getAbsDirY();
+    //velocityDir.normalize();
+    rot += Vector(1,0,0);
+    rotVal -= time/5;
+  }
+  else
+   {
+         if(this->getAbsDirZ().y > 0.02) this->shiftDir(Quaternion(time/5, Vector(1,0,0)));
+   }
+
+  if( this->bRight /* > this->getRelCoor().z*2*/)
+  {
+    //this->shiftDir(Quaternion(-time, Vector(0,1,0)));
+    accel += this->getAbsDirY();
+    //velocityDir.normalize();
+    rot += Vector(1,0,0);
+    rotVal += time/5;
+  }
+  else
+   {
+         if(this->getAbsDirZ().y < -0.02) this->shiftDir(Quaternion(-time/5, Vector(1,0,0)));
+   }
+
+  if( this->bRollL /* > -this->getRelCoor().z*2*/)
+  {
+    this->shiftDir(Quaternion(-time, Vector(1,0,0)));
+    //accel -= rightDirection;
+    //velocityDir.normalize();
+    //rot +=Vector(1,0,0);
+    //rotVal -= .4;
+  }
+  if( this->bRollR /* > this->getRelCoor().z*2*/)
+  {
+    this->shiftDir(Quaternion(time, Vector(1,0,0)));
+
+    //accel += rightDirection;
+    //velocityDir.normalize();
+    //rot += Vector(1,0,0);
+    //rotVal += .4;
+  }
+  if (this->bAscend )
+  {
+    //this->shiftDir(Quaternion(time, Vector(0,0,1)));
+
+    rotorspeed += 0.05;
+    if (rotorspeed >= 2) rotorspeed = 2;
+    //velocityDir.normalize();
+    //rot += Vector(0,0,1);
+    //rotVal += .4;
+  }
+  else
+  {
+    if(rotorspeed >= 1.05) rotorspeed -= 0.05;
+  }
+
+  if (this->bDescend )
+  {
+    //this->shiftDir(Quaternion(-time, Vector(0,0,1)));
+
+    rotorspeed -= 0.05;
+    if (rotorspeed <= 0) rotorspeed = 0;
+    //velocityDir.normalize();
+    //rot += Vector(0,0,1);
+    //rotVal -= .4;
+  }
+  else
+  {
+    if(rotorspeed <= 0.05) rotorspeed += 0.05;
+  }
+
+  //velocity += accel;
+  rot.normalize();
+  this->shiftDir(Quaternion(rotVal, rot));
+}
+
+
+void Helicopter::draw() const
+{
+  WorldEntity::draw();
+
+  this->getWeaponManager()->draw();
+}
+
+
+/**
+ * weapon manipulation by the player
+*/
+void Helicopter::weaponAction()
+{
+  if( this->bFire)
+    {
+      this->getWeaponManager()->fire();
+    }
+}
+
+/**
+ * @todo switch statement ??
+ */
+void Helicopter::process(const Event &event)
+{
+
+
+  if( event.type == SDLK_a)
+      this->bLeft = event.bPressed;
+  else if( event.type == SDLK_d)
+      this->bRight = event.bPressed;
+  else if( event.type == KeyMapper::PEV_FIRE1)
+      this->bFire = event.bPressed;
+  else if( event.type == KeyMapper::PEV_NEXT_WEAPON && event.bPressed)
+    this->getWeaponManager()->nextWeaponConfig();//if( !event.bPressed) this->bWeaponChange = !this->bWeaponChange;
+  else if ( event.type == KeyMapper::PEV_PREVIOUS_WEAPON && event.bPressed)
+    this->getWeaponManager()->previousWeaponConfig();
+  else if( event.type == SDLK_e)
+    this->bAscend = event.bPressed; //this->shiftCoor(0,.1,0);
+  else if( event.type == SDLK_c)
+    this->bDescend = event.bPressed; //this->shiftCoor(0,-.1,0);
+  else if( event.type == SDLK_w)
+    this->bUp = event.bPressed; //this->shiftCoor(0,.1,0);
+  else if( event.type == SDLK_s)
+    this->bDown = event.bPressed; //this->shiftCoor(0,-.1,0);
+  else if( event.type == EV_MOUSE_MOTION)
+  {
+    this->xMouse = event.xRel*mouseSensitivity;
+    this->yMouse = event.yRel*mouseSensitivity;
+
+    //this->shiftDir(Quaternion(-M_PI/4*xMouse*mouseSensitivity, Vector(0,1,0))*Quaternion(-M_PI/4*yMouse*mouseSensitivity, Vector(0,0,1)));
+  }
+}
+
+#include "weapons/aiming_turret.h"
+// FIXME THIS MIGHT BE CONSIDERED EITHER A FEATURE, OR A BUG
+void Helicopter::ADDWEAPON()
+{
+  Weapon* turret = NULL;
+
+  if ((float)rand()/RAND_MAX < .1)
+  {
+    //if (this->getWeaponManager()->hasFreeSlot(2, WTYPE_TURRET))
+    {
+      turret = new Turret();
+      this->addWeapon(turret, 2);
+      this->getWeaponManager()->changeWeaponConfig(2);
+    }
+  }
+  else
+  {
+    //if (this->getWeaponManager()->hasFreeSlot(3))
+    {
+      turret = new AimingTurret();
+      this->addWeapon(turret, 3);
+
+      this->getWeaponManager()->changeWeaponConfig(3);
+    }
+  }
+
+  if(turret != NULL)
+  {
+    turret->setName("Turret");
+    turret->setStateDuration(WS_SHOOTING, (float)rand()/RAND_MAX*.5+.1);
+  }
+}
Index: branches/network/src/world_entities/space_ships/helicopter.h
===================================================================
--- branches/network/src/world_entities/space_ships/helicopter.h	(revision 6636)
+++ branches/network/src/world_entities/space_ships/helicopter.h	(revision 6636)
@@ -0,0 +1,73 @@
+
+/*!
+ * @file helicopter.h
+ * Implements the Control of a Helicopter
+ */
+
+#ifndef _HELICOPTER_H
+#define _HELICOPTER_H
+
+#include "playable.h"
+
+
+class Helicopter : public Playable
+{
+
+  public:
+
+    Helicopter();
+    Helicopter(const char* fileName);
+    Helicopter(const TiXmlElement* root);
+    virtual ~Helicopter();
+
+    void init();
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual void enter();
+    virtual void leave();
+
+    virtual void postSpawn();
+    virtual void leftWorld();
+
+    virtual void collidesWith(WorldEntity* entity, const Vector& location);
+    virtual void tick(float time);
+    virtual void draw() const;
+
+    virtual void process(const Event &event);
+
+
+
+  private:
+    void calculateVelocity(float time);
+    void weaponAction();
+
+    // !! temporary !!
+    void ADDWEAPON();
+
+    bool                  bUp;                //!< up button pressed.
+    bool                  bDown;              //!< down button pressed.
+    bool                  bLeft;              //!< left button pressed.
+    bool                  bRight;             //!< right button pressed.
+    bool                  bAscend;            //!< ascend button pressed.
+    bool                  bDescend;           //!< descend button presses.
+    bool                  bFire;              //!< fire button pressed.
+    bool                  bRollL;             //!< rolling button pressed (left)
+    bool                  bRollR;             //!< rolling button pressed (right)
+
+    float                 xMouse;             //!< mouse moved in x-Direction
+    float                 yMouse;             //!< mouse moved in y-Direction
+    float                 mouseSensitivity;   //!< the mouse sensitivity
+    float                 cycle;              //!< hovercycle
+
+    Vector                velocity;           //!< the velocity of the player.
+    Vector                velocityDir;        //!< the direction of the velocity of the spaceship
+    float                 travelSpeed;        //!< the current speed of the player (to make soft movement)
+    float                 acceleration;       //!< the acceleration of the player.
+    float                 rotorspeed;         //!< the speed of the rotor.
+    float                 tailrotorspeed;     //!< the relativ speed ot the tail rotor
+
+    float                 airViscosity;
+
+};
+
+#endif /* _HELICOPTERS_H */
Index: branches/network/src/world_entities/space_ships/space_ship.cc
===================================================================
--- branches/network/src/world_entities/space_ships/space_ship.cc	(revision 6636)
+++ branches/network/src/world_entities/space_ships/space_ship.cc	(revision 6636)
@@ -0,0 +1,646 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Benjamin Knecht
+   co-programmer: Silvan Nellen
+
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "executor/executor.h"
+#include "space_ship.h"
+
+#include "objModel.h"
+#include "resource_manager.h"
+
+#include "weapons/weapon_manager.h"
+#include "weapons/test_gun.h"
+#include "weapons/turret.h"
+#include "weapons/cannon.h"
+
+#include "factory.h"
+#include "key_mapper.h"
+#include "event_handler.h"
+
+#include "network_game_manager.h"
+
+#include "power_ups/weapon_power_up.h"
+#include "power_ups/param_power_up.h"
+
+#include "graphics_engine.h"
+
+#include "plane.h"
+
+#include "state.h"
+#include "player.h"
+
+
+// #include "lib/gui/gl_gui/glgui_bar.h"
+// #include "lib/gui/gl_gui/glgui_pushbutton.h"
+
+
+using namespace std;
+
+CREATE_FACTORY(SpaceShip, CL_SPACE_SHIP);
+
+/**
+ *  creates the controlable Spaceship
+ */
+SpaceShip::SpaceShip()
+{
+  this->init();
+}
+
+/**
+ *  destructs the spaceship, deletes alocated memory
+ */
+SpaceShip::~SpaceShip ()
+{
+}
+
+/**
+ * loads a Spaceships information from a specified file.
+ * @param fileName the name of the File to load the spaceship from (absolute path)
+ */
+SpaceShip::SpaceShip(const char* fileName)
+{
+  this->init();
+  TiXmlDocument doc(fileName);
+
+  if(!doc.LoadFile())
+  {
+    PRINTF(2)("Loading file %s failed for spaceship.\n", fileName);
+    return;
+  }
+
+  this->loadParams(doc.RootElement());
+}
+
+/**
+ *  creates a new Spaceship from Xml Data
+ * @param root the xml element containing spaceship data
+
+   @todo add more parameters to load
+*/
+SpaceShip::SpaceShip(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+
+  //weapons:
+  Weapon* wpRight = new TestGun(0);
+  wpRight->setName("testGun Right");
+  Weapon* wpLeft = new TestGun(1);
+  wpLeft->setName("testGun Left");
+  Weapon* cannon = dynamic_cast<Weapon*>(Factory::fabricate(CL_CANNON));
+
+  cannon->setName("BFG");
+
+  this->addWeapon(wpLeft, 1, 0);
+  this->addWeapon(wpRight,1 ,1);
+  this->addWeapon(cannon, 0, 6);
+
+  //this->addWeapon(turret, 3, 0);
+
+  this->getWeaponManager()->changeWeaponConfig(1);
+}
+
+
+/**
+ * initializes a Spaceship
+ */
+void SpaceShip::init()
+{
+//  this->setRelDir(Quaternion(M_PI, Vector(1,0,0)));
+  this->setClassID(CL_SPACE_SHIP, "SpaceShip");
+
+  PRINTF(4)("SPACESHIP INIT\n");
+
+  EventHandler::getInstance()->grabEvents(true);
+
+  bUp = bDown = bLeft = bRight = bAscend = bDescend = bRollL = bRollR = false;
+  bFire = false;
+  xMouse = yMouse = 0;
+  mouseSensitivity = 0.001;
+  airViscosity = 1.0;
+  cycle = 0.0;
+
+  this->setMaxEnergy(100);
+  this->setEnergy(80);
+
+  travelSpeed = 15.0;
+  this->velocity = Vector(0.0,0.0,0.0);
+  this->mouseDir = this->getAbsDir();
+
+//   GLGuiButton* button = new GLGuiPushButton();
+//    button->show();
+//    button->setLabel("orxonox");
+//    button->setBindNode(this);
+//     GLGuiBar* bar = new GLGuiBar();
+//     bar->show();
+//     bar->setValue(7.0);
+//     bar->setMaximum(10);
+//     bar->setSize2D( 20, 100);
+//     bar->setAbsCoor2D( 10, 200);
+
+  //add events to the eventlist
+  registerEvent(SDLK_w);
+  registerEvent(SDLK_s);
+  registerEvent(SDLK_a);
+  registerEvent(SDLK_d);
+  registerEvent(SDLK_q);
+  registerEvent(SDLK_e);
+  registerEvent(KeyMapper::PEV_FIRE1);
+  registerEvent(KeyMapper::PEV_NEXT_WEAPON);
+  registerEvent(KeyMapper::PEV_PREVIOUS_WEAPON);
+  registerEvent(SDLK_PAGEUP);
+  registerEvent(SDLK_PAGEDOWN);
+  registerEvent(EV_MOUSE_MOTION);
+
+  this->getWeaponManager()->setSlotCount(7);
+
+  this->getWeaponManager()->setSlotPosition(0, Vector(-2.6, .1, -3.0));
+  this->getWeaponManager()->setSlotCapability(0, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+
+  this->getWeaponManager()->setSlotPosition(1, Vector(-2.6, .1, 3.0));
+  this->getWeaponManager()->setSlotCapability(1, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+
+  this->getWeaponManager()->setSlotPosition(2, Vector(-1.5, .5, -.5));
+  this->getWeaponManager()->setSlotDirection(2, Quaternion(-M_PI_4*.5, Vector(1,0,0)));
+
+  this->getWeaponManager()->setSlotPosition(3, Vector(-1.5, .5, .5));
+  this->getWeaponManager()->setSlotDirection(3, Quaternion(M_PI_4*.5, Vector(1,0,0)));
+
+  this->getWeaponManager()->setSlotPosition(4, Vector(-1.5, -.5, .5));
+  this->getWeaponManager()->setSlotDirection(4, Quaternion(-M_PI_4*.5+M_PI, Vector(1,0,0)));
+
+  this->getWeaponManager()->setSlotPosition(5, Vector(-1.5, -.5, -.5));
+  this->getWeaponManager()->setSlotDirection(5, Quaternion(+M_PI_4*.5-M_PI, Vector(1,0,0)));
+//
+   this->getWeaponManager()->setSlotPosition(6, Vector(-1, 0.0, 0));
+   this->getWeaponManager()->setSlotCapability(6, WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+   //
+//   this->getWeaponManager()->setSlotPosition(8, Vector(-2.5, -0.3, -2.0));
+//   this->getWeaponManager()->setSlotDirection(8, Quaternion(-M_PI, Vector(1,0,0)));
+//
+//   this->getWeaponManager()->setSlotPosition(9, Vector(-2.5, -0.3, 2.0));
+//   this->getWeaponManager()->setSlotDirection(9, Quaternion(+M_PI, Vector(1,0,0)));:
+
+  this->getWeaponManager()->getFixedTarget()->setParent(this);
+  this->getWeaponManager()->getFixedTarget()->setRelCoor(100000,0,0);
+
+  dynamic_cast<Element2D*>(this->getWeaponManager()->getFixedTarget())->setVisibility( false);
+}
+
+/**
+ * loads the Settings of a SpaceShip from an XML-element.
+ * @param root the XML-element to load the Spaceship's properties from
+ */
+void SpaceShip::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+}
+
+
+void SpaceShip::enter()
+{
+  dynamic_cast<Element2D*>(this->getWeaponManager()->getFixedTarget())->setVisibility( true);
+  this->attachCamera();
+}
+
+void SpaceShip::leave()
+{
+  dynamic_cast<Element2D*>(this->getWeaponManager()->getFixedTarget())->setVisibility( false);
+  this->detachCamera();
+}
+
+
+/**
+ *  effect that occurs after the SpaceShip is spawned
+*/
+void SpaceShip::postSpawn ()
+{
+  //setCollision(new CollisionCluster(1.0, Vector(0,0,0)));
+}
+
+/**
+ *  the action occuring if the spaceship left the game
+*/
+void SpaceShip::leftWorld ()
+{}
+
+WorldEntity* ref = NULL;
+/**
+ *  this function is called, when two entities collide
+ * @param entity: the world entity with whom it collides
+ *
+ * Implement behaviour like damage application or other miscellaneous collision stuff in this function
+ */
+void SpaceShip::collidesWith(WorldEntity* entity, const Vector& location)
+{
+  Playable::collidesWith(entity, location);
+  if (entity->isA(CL_TURRET_POWER_UP) && entity != ref)
+  {
+    this->ADDWEAPON();
+    ref = entity;
+    }
+//  PRINTF(3)("collision %s vs %s @ (%f,%f,%f)\n", this->getClassName(), entity->getClassName(), location.x, location.y, location.z);
+}
+
+/**
+ *  draws the spaceship after transforming it.
+*/
+void SpaceShip::draw () const
+{
+  WorldEntity::draw();
+  this->getWeaponManager()->draw();
+
+  //this->debug(0);
+}
+
+/**
+ *  the function called for each passing timeSnap
+ * @param time The timespan passed since last update
+*/
+void SpaceShip::tick (float time)
+{
+  this->getWeaponManager()->tick(time);
+  // weapon system manipulation
+  this->weaponAction();
+
+//   if( this != State::getPlayer()->getControllable())
+//     return;
+
+  // spaceship controlled movement
+  this->calculateVelocity(time);
+
+  Vector move = (velocity)*time;
+
+  //orient the velocity in the direction of the spaceship.
+  travelSpeed = velocity.len();
+  velocity += ((this->getAbsDirX())*travelSpeed-velocity)*airViscosity;
+  velocity = (velocity.getNormalized())*travelSpeed;
+
+  //orient the spaceship in direction of the mouse
+   rotQuat = Quaternion::quatSlerp( this->getAbsDir(), mouseDir, fabsf(time)*3.0);
+   if (this->getAbsDir().distance(rotQuat) > 0.00000000000001)
+    this->setAbsDir( rotQuat);
+   //this->setAbsDirSoft(mouseDir,5);
+
+  // this is the air friction (necessary for a smooth control)
+  if(velocity.len() != 0) velocity -= velocity*0.01;
+
+  //hoover effect
+  //cycle += time;
+  //this->shiftCoor(Vector(0,1,0)*cos(this->cycle*2.0)*0.02);
+
+  //readjust
+
+  /*
+    In the game "Yager" the spaceship gets readjusted when the player moves the mouse.
+    I (bknecht) go and check it out how they do it, we could probably use this also in Orxonox.
+  */
+  //if (xMouse != 0 && yMouse != 0)
+
+  //if (this->getAbsDirZ().y > 0.1) this->shiftDir(Quaternion(time*0.3, Vector(1,0,0)));
+  //else if (this->getAbsDirZ().y < -0.1) this->shiftDir(Quaternion(-time*0.3, Vector(1,0,0)));
+
+  //SDL_WarpMouse(GraphicsEngine::getInstance()->getResolutionX()/2, GraphicsEngine::getInstance()->getResolutionY()/2);
+
+  this->shiftCoor (move);
+
+
+}
+
+/**
+ *  calculate the velocity
+ * @param time the timeslice since the last frame
+*/
+void SpaceShip::calculateVelocity (float time)
+{
+  Vector accel(0.0, 0.0, 0.0);
+  /*
+  Vector rot(0.0, 0.0, 0.0); // wird benötigt für Helicopter
+  */
+  //float rotVal = 0.0;
+  /* FIXME: calculating the direction and orthDirection every timeSlice is redundant! save it somewhere */
+  /* calculate the direction in which the craft is heading  */
+
+  Plane plane(Vector(0,1,0), Vector(0,0,0));
+
+  if( this->bUp )
+   {
+     //this->shiftCoor(this->getAbsDirX());
+      accel += (this->getAbsDirX())*2;
+
+      /* Heli-Steuerung
+         accel += (this->getAbsDirX()*2;
+         if(
+      */
+   }
+
+  if( this->bDown )
+   {
+     //this->shiftCoor((this->getAbsDirX())*-1);
+     accel -= (this->getAbsDirX())*2;
+   }
+
+  if( this->bLeft/* > -this->getRelCoor().z*2*/)
+  {
+    this->shiftDir(Quaternion(time, Vector(0,1,0)));
+//    accel -= rightDirection;
+    //velocityDir.normalize();
+    //rot +=Vector(1,0,0);
+    //rotVal -= .4;
+  }
+  if( this->bRight /* > this->getRelCoor().z*2*/)
+  {
+    this->shiftDir(Quaternion(-time, Vector(0,1,0)));
+
+    //    accel += rightDirection;
+    //velocityDir.normalize();
+    //rot += Vector(1,0,0);
+    //rotVal += .4;
+  }
+
+
+  if( this->bRollL /* > -this->getRelCoor().z*2*/)
+  {
+    mouseDir *= Quaternion(-time, Vector(1,0,0));
+//    accel -= rightDirection;
+    //velocityDir.normalize();
+    //rot +=Vector(1,0,0);
+    //rotVal -= .4;
+  }
+  if( this->bRollR /* > this->getRelCoor().z*2*/)
+  {
+    mouseDir *= Quaternion(time, Vector(1,0,0));
+
+    //    accel += rightDirection;
+    //velocityDir.normalize();
+    //rot += Vector(1,0,0);
+    //rotVal += .4;
+  }
+  if (this->bAscend )
+  {
+    this->shiftDir(Quaternion(time, Vector(0,0,1)));
+
+//    accel += upDirection;
+    //velocityDir.normalize();
+    //rot += Vector(0,0,1);
+    //rotVal += .4;
+  }
+  if (this->bDescend )
+  {
+    this->shiftDir(Quaternion(-time, Vector(0,0,1)));
+
+    //    accel -= upDirection;
+    //velocityDir.normalize();
+    //rot += Vector(0,0,1);
+    //rotVal -= .4;
+  }
+
+  velocity += accel;
+  //rot.normalize();
+  //this->setRelDirSoft(Quaternion(rotVal, rot), 5);
+}
+
+/**
+ * weapon manipulation by the player
+*/
+void SpaceShip::weaponAction()
+{
+  if( this->bFire)
+    {
+      this->getWeaponManager()->fire();
+    }
+}
+
+/**
+ * @todo switch statement ??
+ */
+void SpaceShip::process(const Event &event)
+{
+
+
+  if( event.type == SDLK_a)
+      this->bRollL = event.bPressed;
+  else if( event.type == SDLK_d)
+      this->bRollR = event.bPressed;
+  else if( event.type == KeyMapper::PEV_FIRE1)
+      this->bFire = event.bPressed;
+  else if( event.type == KeyMapper::PEV_NEXT_WEAPON && event.bPressed)
+  {
+    this->nextWeaponConfig();//if( !event.bPressed) this->bWeaponChange = !this->bWeaponChange;
+  }
+  else if ( event.type == KeyMapper::PEV_PREVIOUS_WEAPON && event.bPressed)
+    this->previousWeaponConfig();
+  else if( event.type == SDLK_w)
+    this->bUp = event.bPressed; //this->shiftCoor(0,.1,0);
+  else if( event.type == SDLK_s)
+    this->bDown = event.bPressed; //this->shiftCoor(0,-.1,0);
+  else if( event.type == EV_MOUSE_MOTION)
+  {
+    this->xMouse = event.xRel;
+    this->yMouse = event.yRel;
+    mouseDir *= (Quaternion(-M_PI/4*xMouse*mouseSensitivity, Vector(0,1,0))*Quaternion(-M_PI/4*yMouse*mouseSensitivity, Vector(0,0,1)));
+   // if( xMouse*xMouse + yMouse*yMouse < 0.9)
+     //this->setAbsDir(mouseDir);
+  }
+}
+
+#include "weapons/aiming_turret.h"
+// FIXME THIS MIGHT BE CONSIDERED EITHER A FEATURE, OR A BUG
+void SpaceShip::ADDWEAPON()
+{
+  Weapon* turret = NULL;
+
+  if ((float)rand()/RAND_MAX < .9)
+  {
+    //if (this->getWeaponManager()->hasFreeSlot(2, WTYPE_TURRET))
+    {
+      turret = new Turret();
+      this->addWeapon(turret, 2);
+      this->getWeaponManager()->changeWeaponConfig(2);
+    }
+  }
+  else
+  {
+    //if (this->getWeaponManager()->hasFreeSlot(3))
+    {
+      turret = dynamic_cast<Weapon*>(Factory::fabricate(CL_TARGETING_TURRET));
+      if (turret != NULL)
+      this->addWeapon(turret, 3);
+
+      this->getWeaponManager()->changeWeaponConfig(3);
+    }
+  }
+
+  if(turret != NULL)
+  {
+    turret->setName("Turret");
+    turret->setStateDuration(WS_SHOOTING, (float)rand()/RAND_MAX*.5+.1);
+  }
+}
+
+#define MASK_bUp         1
+#define MASK_bDown       2
+#define MASK_bLeft       4
+#define MASK_bRight      8
+#define MASK_bAscend    16
+#define MASK_bDescend   32
+#define MASK_bFire      64
+#define MASK_bRollL    128
+#define MASK_bRollR    256
+
+#define DATA_state       1
+#define DATA_flags       2
+#define DATA_mouse       3
+
+int SpaceShip::writeBytes( const byte * data, int length, int sender )
+{
+  SYNCHELP_READ_BEGIN();
+
+  byte b;
+  SYNCHELP_READ_BYTE( b );
+
+  if ( b == DATA_state /*&& (this->getHostID()!=this->getOwner() || sender==0)*/ )
+  {
+    PRINTF(0)("GOT STATE %d\n", this->getUniqueID());
+    setRequestedSync( false );
+    setIsOutOfSync( false );
+    SYNCHELP_READ_FKT( WorldEntity::writeState );
+    //SYNCHELP_READ_FLOAT( cycle );
+
+    return SYNCHELP_READ_N;
+  }
+
+
+  if ( b == DATA_flags /*&& this->getHostID()!=this->getOwner()*/ )
+  {
+    int flags = 0;
+    SYNCHELP_READ_INT( flags );
+
+    bUp = (flags & MASK_bUp) != 0;
+    bDown = (flags & MASK_bDown) != 0;
+    bLeft = (flags & MASK_bLeft) != 0;
+    bRight = (flags & MASK_bRight) != 0;
+    bAscend = (flags & MASK_bAscend) != 0;
+    bDescend = (flags & MASK_bDescend) != 0;
+    bFire = (flags & MASK_bFire) != 0;
+    bRollL = (flags & MASK_bRollL) != 0;
+    bRollR = (flags & MASK_bRollR) != 0;
+
+  }
+
+  /*if ( b == DATA_mouse && this->getHostID()!=this->getOwner() )
+  {
+    SYNCHELP_READ_FLOAT( xMouse );
+    SYNCHELP_READ_FLOAT( yMouse );
+    SYNCHELP_READ_FLOAT( mouseSensitivity );
+    SYNCHELP_READ_FLOAT( cycle );
+}*/
+
+  if ( this->getOwner() != this->getHostID() )
+    SYNCHELP_READ_FKT( PNode::writeSync );
+
+  return SYNCHELP_READ_N;
+}
+
+
+
+int SpaceShip::readBytes( byte * data, int maxLength, int * reciever )
+{
+  SYNCHELP_WRITE_BEGIN();
+
+  if ( isOutOfSync() && !requestedSync() /*&& this->getHostID()!=this->getOwner()*/ )
+  {
+    (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
+    setRequestedSync( true );
+    PRINTF(0)("REQUESTED STATE %d\n", this->getUniqueID());
+  }
+
+  int rec = this->getRequestSync();
+  if ( rec > 0 )
+  {
+    *reciever = rec;
+
+    PRINTF(0)("SEND STATE %d %d\n", this->getUniqueID(), rec);
+
+    SYNCHELP_WRITE_BYTE( (byte)DATA_state );
+
+    SYNCHELP_WRITE_FKT( WorldEntity::readState );
+    //SYNCHELP_WRITE_FLOAT( cycle );
+
+    return SYNCHELP_WRITE_N;
+  }
+
+  *reciever = 0;
+
+  if ( this->getHostID()==this->getOwner() )
+  {
+    int mask = 0;
+
+    if ( bUp )
+      mask |= MASK_bUp;
+    if ( bDown )
+      mask |= MASK_bDown;
+    if ( bLeft )
+      mask |= MASK_bLeft;
+    if ( bRight )
+      mask |= MASK_bRight;
+    if ( bAscend )
+      mask |= MASK_bAscend;
+    if ( bFire )
+      mask |= MASK_bFire;
+    if ( bRollL )
+      mask |= MASK_bRollL;
+    if ( bRollR )
+      mask |= MASK_bRollR;
+
+
+    //static float oldxMouse = xMouse + 1.0;
+    //static float oldyMouse = yMouse + 1.0;
+
+    if ( mask != oldMask )
+    {
+      oldMask = mask;
+      SYNCHELP_WRITE_BYTE( DATA_flags );
+      SYNCHELP_WRITE_INT( mask );
+    }
+    else
+    {
+      SYNCHELP_WRITE_BYTE( 0 );
+    }
+
+    /*if ( oldxMouse != xMouse || oldyMouse != yMouse )
+    {
+      oldxMouse = xMouse;
+      oldyMouse = yMouse;
+      SYNCHELP_WRITE_BYTE( DATA_mouse );
+      SYNCHELP_WRITE_FLOAT( xMouse );
+      SYNCHELP_WRITE_FLOAT( yMouse );
+      SYNCHELP_WRITE_FLOAT( mouseSensitivity );
+      SYNCHELP_WRITE_FLOAT( cycle );
+    }*/
+  }
+  else
+  {
+    SYNCHELP_WRITE_BYTE( 0 );
+  }
+
+  if ( this->getOwner() == this->getHostID() )
+    SYNCHELP_WRITE_FKT( PNode::readSync );
+
+  return SYNCHELP_WRITE_N;
+}
Index: branches/network/src/world_entities/space_ships/space_ship.h
===================================================================
--- branches/network/src/world_entities/space_ships/space_ship.h	(revision 6636)
+++ branches/network/src/world_entities/space_ships/space_ship.h	(revision 6636)
@@ -0,0 +1,81 @@
+/*!
+ * @file space_ship.h
+ * Implements the Control of a Spaceship
+ */
+
+#ifndef _SPACE_SHIP_H
+#define _SPACE_SHIP_H
+
+#include "playable.h"
+#include "extendable.h"
+
+
+template<class T> class tList;
+class Vector;
+class Event;
+
+class SpaceShip : public Playable
+{
+
+  public:
+
+    SpaceShip();
+    SpaceShip(const char* fileName);
+    SpaceShip(const TiXmlElement* root);
+    virtual ~SpaceShip();
+
+    void init();
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual void enter();
+    virtual void leave();
+
+    virtual void postSpawn();
+    virtual void leftWorld();
+
+    virtual void collidesWith(WorldEntity* entity, const Vector& location);
+    virtual void tick(float time);
+    virtual void draw() const;
+
+    virtual void process(const Event &event);
+
+    virtual int       writeBytes(const byte* data, int length, int sender);
+    virtual int       readBytes(byte* data, int maxLength, int * reciever);
+
+
+  private:
+
+    void calculateVelocity(float time);
+    void weaponAction();
+
+    // !! temporary !!
+    void ADDWEAPON();
+
+    bool                  bUp;                //!< up button pressed.
+    bool                  bDown;              //!< down button pressed.
+    bool                  bLeft;              //!< left button pressed.
+    bool                  bRight;             //!< right button pressed.
+    bool                  bAscend;            //!< ascend button pressed.
+    bool                  bDescend;           //!< descend button presses.
+    bool                  bFire;              //!< fire button pressed.
+    bool                  bRollL;             //!< rolling button pressed (left)
+    bool                  bRollR;             //!< rolling button pressed (right)
+
+    float                 xMouse;             //!< mouse moved in x-Direction
+    float                 yMouse;             //!< mouse moved in y-Direction
+    float                 mouseSensitivity;   //!< the mouse sensitivity
+    float                 cycle;              //!< hovercycle
+
+    Vector                velocity;           //!< the velocity of the player.
+    Quaternion            mouseDir;           //!< the direction where the player wants to fly
+    Quaternion            rotQuat;
+    float                 travelSpeed;        //!< the current speed of the player (to make soft movement)
+    float                 acceleration;       //!< the acceleration of the player.
+
+    float                 airViscosity;
+
+    int oldMask;
+
+};
+
+#endif /* _SPACE_SHIPS_H */
Index: branches/network/src/world_entities/spawning_point.cc
===================================================================
--- branches/network/src/world_entities/spawning_point.cc	(revision 6636)
+++ branches/network/src/world_entities/spawning_point.cc	(revision 6636)
@@ -0,0 +1,131 @@
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+
+#include "spawning_point.h"
+
+#include "load_param.h"
+#include "factory.h"
+
+#include "compiler.h"
+
+
+/**
+ *  standard constructor
+ */
+SpawningPoint::SpawningPoint (World* world, const Vector& absCoordinate)
+{
+  this->world = world;
+  this->frequency = 0.5f;
+  this->seed = 0.0f;
+
+  this->init();
+}
+
+
+/**
+ *  constructor
+ */
+SpawningPoint::SpawningPoint (const Vector& position, float frequency,
+                              float seed, ClassID classID, World* world)
+{
+  this->frequency = frequency;
+  this->seed = seed;
+  this->classID = classID;
+  this->world = world;
+
+  this->init();
+}
+
+
+void SpawningPoint::init()
+{
+  this->countDown = 0.0f;
+}
+
+
+/**
+ *  deconstructor
+ */
+SpawningPoint::~SpawningPoint ()
+{}
+
+
+/**
+ * loads the WorldEntity Specific Parameters.
+ * @param root: the XML-Element to load the Data From
+ */
+void SpawningPoint::loadParams(const TiXmlElement* root)
+{
+  /* let the world entity its stuff first */
+  WorldEntity::loadParams(root);
+
+  /* now load the frequency */
+  LoadParam(root, "frequency", this, SpawningPoint, setSpawningFrequency)
+  .describe("sets the frequency of the spawning point")
+  .defaultValues(1, 1.0f);
+
+
+  /* now load the seed */
+  LoadParam(root, "randomseed", this, SpawningPoint, setPositionSeed)
+      .describe("sets the random position seed (variance in the spawning location around the position)")
+      .defaultValues(1, 0.0f);
+
+  /* now load the seed */
+/*  LoadParam(root, "classid", this, SpawningPoint, setSpawningEntity)
+      .describe("sets the class id of the entity to spawn")
+      .defaultValues(1, CL_WORLD_ENTITY);*/
+}
+
+
+/**
+ *  spawn the entity
+ */
+void SpawningPoint::spawn()
+{
+  PRINTF(5)("Spangingpoint creates a new Entity (id: %i, frequency: %f, seed: %f)\n", this->classID,
+            this->frequency, this->seed);
+  BaseObject* spawningEntity = Factory::fabricate(this->classID);
+
+//   if( likely(this->world != NULL))
+//     this->world->spawn(dynamic_cast<WorldEntity*>(spawningEntity));
+}
+
+
+/**
+ *  this method is called every frame
+ * @param time: the time in seconds that has passed since the last tick
+ *
+ * Handle all stuff that should update with time inside this method (movement, animation, etc.)
+ */
+void SpawningPoint::tick(float dt)
+{
+  this->countDown += dt;
+  if( this->countDown > this->frequency)
+  {
+    this->spawn();
+    this->countDown = 0.0f;
+  }
+}
+
+
+/**
+ *  the entity is drawn onto the screen with this function
+ *
+ * This is a central function of an entity: call it to let the entity painted to the screen.
+ * Just override this function with whatever you want to be drawn.
+ */
+void SpawningPoint::draw()
+{}
Index: branches/network/src/world_entities/spawning_point.h
===================================================================
--- branches/network/src/world_entities/spawning_point.h	(revision 6636)
+++ branches/network/src/world_entities/spawning_point.h	(revision 6636)
@@ -0,0 +1,47 @@
+/*!
+ * @file spawning_point.h
+ *  Definition of a spawning point within the game, used for network game
+ */
+
+
+#ifndef _SPAWNING_POINT
+#define _SPAWNING_POINT
+
+#include "world_entity.h"
+
+class World;
+class TiXmlElement;
+
+//! The spawning point for world entities
+class SpawningPoint : public WorldEntity {
+
+  public:
+    SpawningPoint (World* world, const Vector& absCoordinate = Vector(0.0, 0.0, 0.0));
+    SpawningPoint (const Vector& position, float frequency, float seed, ClassID classID, World* world);
+    virtual ~SpawningPoint ();
+    void init();
+
+    virtual void loadParams(const TiXmlElement* root);
+
+    /**  sets the entity that is going to be spawned by this point @param classID: the id from the class_id.h file */
+    void SpawningPoint::setSpawningEntity(ClassID classID) { this->classID = classID; }
+    /** sets the frequency with which the point is going to spawn entities (1/sec) @param frequency: the frequency */
+    void SpawningPoint::setSpawningFrequency(float frequency) { this->frequency = frequency; }
+    /**  sets the seed of the position vector @param seed: the random seed around the given vector */
+    void SpawningPoint::setPositionSeed(float seed) { this->seed = seed; }
+
+    void spawn();
+
+    virtual void tick(float dt);
+    virtual void draw();
+
+  private:
+    float                frequency;                      //!< the frequency for entity spawning
+    float                countDown;                      //!< the timer that counts down until the next spawn
+    float                seed;                           //!< the random seed of the position
+    ClassID              classID;                        //!< the classid of the entity to spawn
+    World*               world;                          //!< reference to the world it belongs to (or in the future: the object manager)
+
+};
+
+#endif /* _SPAWNING_POINT */
Index: branches/network/src/world_entities/terrain.cc
===================================================================
--- branches/network/src/world_entities/terrain.cc	(revision 6636)
+++ branches/network/src/world_entities/terrain.cc	(revision 6636)
@@ -0,0 +1,359 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "terrain.h"
+
+#include "load_param.h"
+#include "factory.h"
+#include "spatial_separation.h"
+
+#include "resource_manager.h"
+#include "model.h"
+#include "network_game_manager.h"
+
+
+#include "glincl.h"
+
+using namespace std;
+
+CREATE_FACTORY(Terrain, CL_TERRAIN);
+
+/**
+ *  standard constructor
+ */
+Terrain::Terrain (const TiXmlElement* root)
+{
+  this->init();
+  this->loadParams(root);
+
+//  if (this->model != NULL)
+    //this->ssp = new SpatialSeparation((Model*)this->model, 10.0f);
+}
+
+
+/**
+ *  Constructor for loading a Terrain out of a file
+ * @param fileName The file to load data from.
+
+   this either loads out of an OBJ-file, or loads a heightmap if no .obj-extension is found.
+*/
+Terrain::Terrain(const char* fileName)
+{
+  this->init();
+
+  if (!strstr(fileName, ".obj") || !strstr(fileName, ".OBJ") )
+    {
+      this->loadModel(fileName);
+    }
+  else
+    {
+      // load the hightMap here.
+    }
+}
+
+/**
+ *  a Constructor for the Debug-Worlds
+ */
+Terrain::Terrain(DebugTerrain debugTerrain)
+{
+  this->init();
+  this->buildDebugTerrain(debugTerrain);
+}
+
+/**
+ *  standard deconstructor
+
+*/
+Terrain::~Terrain ()
+{
+  if (objectList)
+    glDeleteLists(this->objectList, 1);
+  if( this->ssp)
+    delete ssp;
+  if (this->vegetation)
+  {
+    ResourceManager::getInstance()->unload(this->vegetation);
+  }
+}
+
+
+void Terrain::init()
+{
+  this->setClassID(CL_TERRAIN, "Terrain");
+  this->toList(OM_ENVIRON_NOTICK);
+
+  this->objectList = 0;
+  this->ssp = NULL;
+  this->vegetation = NULL;
+}
+
+
+void Terrain::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+
+  LoadParam(root, "vegetation", this, Terrain, loadVegetation)
+      .describe("the fileName of the vegetation, that should be loaded onto this terrain. (must be relative to the data-dir)") ;
+}
+
+void Terrain::loadVegetation(const char* vegetationFile)
+{
+  PRINTF(0)("loadVegetation: %s\n", vegetationFile);
+  if (this->vegetation)
+    ResourceManager::getInstance()->unload(this->vegetation, RP_LEVEL);
+  if (vegetationFile != NULL)
+  {
+    PRINTF(4)("fetching %s\n", vegetationFile);
+    this->vegetation = (Model*)ResourceManager::getInstance()->load(vegetationFile, OBJ, RP_CAMPAIGN);
+  }
+  else
+    this->vegetation = NULL;
+}
+
+
+
+void Terrain::draw () const
+{
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+
+  /* translate */
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+  /* rotate */
+  Vector tmpRot = this->getAbsDir().getSpacialAxis();
+  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+
+  if (this->objectList)
+    glCallList(this->objectList);
+  else if (this->getModel())
+    this->getModel()->draw();
+  if (this->vegetation)
+    this->vegetation->draw();
+  glPopMatrix();
+
+  /* THIS IS ONLY FOR DEBUGGING INFORMATION */
+  if (this->ssp != NULL)
+    this->ssp->drawQuadtree();
+}
+
+
+void Terrain::buildDebugTerrain(DebugTerrain debugTerrain)
+{
+  // if the terrain is the Terrain of Dave
+  if (debugTerrain == TERRAIN_DAVE)
+    {
+      objectList = glGenLists(1);
+      glNewList (objectList, GL_COMPILE);
+
+      glColor3f(1.0,0,0);
+
+      int sizeX = 100;
+      int sizeZ = 80;
+      float length = 1000;
+      float width = 200;
+      float widthX = float (length /sizeX);
+      float widthZ = float (width /sizeZ);
+
+      float height [sizeX][sizeZ];
+      Vector normal_vectors[sizeX][sizeZ];
+
+
+      for ( int i = 0; i<sizeX-1; i+=1)
+        for (int j = 0; j<sizeZ-1;j+=1)
+          //height[i][j] = rand()/20046 + (j-25)*(j-25)/30;
+#ifdef __WIN32__
+          height[i][j]=(sin((float)j/3)*rand()*i/182400)*.5;
+#else
+      height[i][j]=(sin((float)j/3)*rand()*(long)i/6282450500.0)*.5;
+#endif
+
+      //Die Huegel ein wenig glaetten
+      for (int h=1; h<2;h++)
+        for (int i=1;i<sizeX-2 ;i+=1 )
+          for(int j=1;j<sizeZ-2;j+=1)
+            height[i][j]=(height[i+1][j]+height[i][j+1]+height[i-1][j]+height[i][j-1])/4;
+
+      //Berechnung von normalen Vektoren
+      for(int i=1;i<sizeX-2;i+=1)
+        for(int j=1;j<sizeZ-2 ;j+=1)
+          {
+            Vector v1 = Vector (widthX*(1),      height[i][j],      widthZ*(j) );
+            Vector v2 = Vector (widthX*(i-1),    height[i-1][j],    widthZ*(j));
+            Vector v3 = Vector (widthX*(i),      height[i][j+1],    widthZ*(j+1));
+            Vector v4 = Vector (widthX*(i+1),    height[i+1][j],    widthZ*(j));
+            Vector v5 = Vector (widthX*(i),      height[i][j-1],    widthZ*(j-1));
+
+            Vector c1 = v2 - v1;
+            Vector c2 = v3 - v1;
+            Vector c3=  v4 - v1;
+            Vector c4 = v5 - v1;
+            Vector zero = Vector (0,0,0);
+            normal_vectors[i][j]=c1.cross(v3-v5)+c2.cross(v4-v2)+c3.cross(v5-v3)+c4.cross(v2-v4);
+            normal_vectors[i][j].normalize();
+          }
+
+      glBegin(GL_QUADS);
+      int snowheight=3;
+      for ( int i = 0; i<sizeX; i+=1)
+        for (int j = 0; j<sizeZ;j+=1)
+          {
+            Vector v1 = Vector (widthX*(i),      height[i][j]-20,       widthZ*(j)  -width/2);
+            Vector v2 = Vector (widthX*(i+1),    height[i+1][j]-20,     widthZ*(j)  -width/2);
+            Vector v3 = Vector (widthX*(i+1),    height[i+1][j+1]-20,   widthZ*(j+1)-width/2);
+            Vector v4 = Vector (widthX*(i),      height[i][j+1]-20,     widthZ*(j+1)-width/2);
+            float a[3];
+            if(height[i][j]<snowheight){
+              a[0]=0;
+              a[1]=1.0-height[i][j]/10-.3;
+              a[2]=0;
+              glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
+            }
+            else{
+              a[0]=1.0;
+              a[1]=1.0;
+              a[2]=1.0;
+              glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
+
+            }
+            glNormal3f(normal_vectors[i][j].x, normal_vectors[i][j].y, normal_vectors[i][j].z);
+            glVertex3f(v1.x, v1.y, v1.z);
+            if(height[i+1][j]<snowheight){
+              a[0]=0;
+              a[1] =1.0-height[i+1][j]/10-.3;
+              a[2]=0;
+              glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
+            }
+            else{
+              a[0]=1.0;
+              a[1]=1.0;
+              a[2]=1.0;
+              glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
+
+            }
+            glNormal3f(normal_vectors[i+1][j].x, normal_vectors[i+1][j].y, normal_vectors[i+1][j].z);
+            glVertex3f(v2.x, v2.y, v2.z);
+            if(height[i+1][j+1]<snowheight){
+              a[0]=0;
+              a[1] =1.0-height[i+1][j+1]/10-.3;
+              a[2]=0;
+              glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
+            }
+            else{
+              a[0]=1.0;
+              a[1]=1.0;
+              a[2]=1.0;
+              glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
+
+
+            }
+            glNormal3f(normal_vectors[i+1][j+1].x, normal_vectors[i+1][j+1].y, normal_vectors[i+1][j+1].z);
+            glVertex3f(v3.x, v3.y, v3.z);
+            if(height[i][j+1]<snowheight){
+              a[0]=0;
+              a[1] =1.0-height[i+1][j+1]/10-.3;
+              a[2]=0;
+              glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
+            }
+            else{
+              a[0]=1.0;
+              a[1]=1.0;
+              a[2]=1.0;
+              glMaterialfv(GL_FRONT,GL_DIFFUSE,a);
+            }
+            glNormal3f(normal_vectors[i][j+1].x, normal_vectors[i][j+1].y, normal_vectors[i][j+1].z);
+            glVertex3f(v4.x, v4.y, v4.z);
+
+          }
+      glEnd();
+      glEndList();
+    }
+
+  if (debugTerrain == TERRAIN_BENSCH)
+    {
+      /*
+        this->model = (OBJModel*) new Model();
+      this->model->setName("CUBE");
+      this->model->addVertex (-0.5, -0.5, 0.5);
+      this->model->addVertex (0.5, -0.5, 0.5);
+      this->model->addVertex (-0.5, 0.5, 0.5);
+      this->model->addVertex (0.5, 0.5, 0.5);
+      this->model->addVertex (-0.5, 0.5, -0.5);
+      this->model->addVertex (0.5, 0.5, -0.5);
+      this->model->addVertex (-0.5, -0.5, -0.5);
+      this->model->addVertex (0.5, -0.5, -0.5);
+
+      this->model->addVertexTexture (0.0, 0.0);
+      this->model->addVertexTexture (1.0, 0.0);
+      this->model->addVertexTexture (0.0, 1.0);
+      this->model->addVertexTexture (1.0, 1.0);
+      this->model->addVertexTexture (0.0, 2.0);
+      this->model->addVertexTexture (1.0, 2.0);
+      this->model->addVertexTexture (0.0, 3.0);
+      this->model->addVertexTexture (1.0, 3.0);
+      this->model->addVertexTexture (0.0, 4.0);
+      this->model->addVertexTexture (1.0, 4.0);
+      this->model->addVertexTexture (2.0, 0.0);
+      this->model->addVertexTexture (2.0, 1.0);
+      this->model->addVertexTexture (-1.0, 0.0);
+      this->model->addVertexTexture (-1.0, 1.0);
+
+      this->model->finalize();
+      */
+    }
+}
+
+int Terrain::writeBytes( const byte * data, int length, int sender )
+{
+  setRequestedSync( false );
+  setIsOutOfSync( false );
+
+  SYNCHELP_READ_BEGIN();
+  SYNCHELP_READ_FKT( WorldEntity::writeState );
+
+  return SYNCHELP_READ_N;
+}
+
+int Terrain::readBytes( byte * data, int maxLength, int * reciever )
+{
+  if ( isOutOfSync() && !requestedSync() && this->getHostID()!=this->getOwner() )
+  {
+    (NetworkGameManager::getInstance())->sync( this->getUniqueID(), this->getOwner() );
+    setRequestedSync( true );
+  }
+
+  int rec = this->getRequestSync();
+  if ( rec > 0 )
+  {
+    *reciever = rec;
+
+    return WorldEntity::readState( data, maxLength );
+
+  }
+
+  *reciever = 0;
+  return 0;
+}
+
+void Terrain::writeDebug( ) const
+{
+}
+
+void Terrain::readDebug( ) const
+{
+}
Index: branches/network/src/world_entities/terrain.h
===================================================================
--- branches/network/src/world_entities/terrain.h	(revision 6636)
+++ branches/network/src/world_entities/terrain.h	(revision 6636)
@@ -0,0 +1,54 @@
+/*!
+ * @file terrain.h
+  *  Defines and handles the terrain of the World
+
+    @todo implement it
+
+    The terrain should either be build from a Model a OBJModel or from a HeightMap.
+*/
+
+#ifndef _TERRAIN_H
+#define _TERRAIN_H
+
+#include "world_entity.h"
+
+// FORWARD DECLARATION
+class SpatialSeparation;
+
+//! A simple method to call a desired debug world.
+enum DebugTerrain {TERRAIN_DAVE, TERRAIN_BENSCH};
+
+
+//! A Class to handle Terrain of orxonox
+class Terrain : public WorldEntity
+{
+
+ public:
+  Terrain(const TiXmlElement* root = NULL);
+  Terrain(const char* fileName);
+  Terrain(DebugTerrain debugTerrain);
+  virtual ~Terrain();
+
+  virtual int       writeBytes(const byte* data, int length, int sender);
+  virtual int       readBytes(byte* data, int maxLength, int * reciever);
+  virtual void      writeDebug() const;
+  virtual void      readDebug() const;
+
+  void init();
+  virtual void loadParams(const TiXmlElement* root);
+
+  void loadVegetation(const char* vegetationFile);
+
+  void buildDebugTerrain(DebugTerrain debugTerrain);
+  virtual void draw() const;
+
+  public:
+    SpatialSeparation* ssp;
+
+ private:
+   Model*              vegetation;
+   int                 objectList;
+
+};
+
+#endif /* _TERRAIN_H */
Index: branches/network/src/world_entities/test_entity.cc
===================================================================
--- branches/network/src/world_entities/test_entity.cc	(revision 6636)
+++ branches/network/src/world_entities/test_entity.cc	(revision 6636)
@@ -0,0 +1,96 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+
+#include "executor/executor.h"
+#include "factory.h"
+#include "load_param.h"
+
+#include "test_entity.h"
+#include "stdincl.h"
+#include "model.h"
+#include "md2Model.h"
+#include "obb_tree.h"
+#include "state.h"
+
+using namespace std;
+
+
+CREATE_FACTORY(TestEntity, CL_TEST_ENTITY);
+
+
+TestEntity::TestEntity ()
+{
+  this->init();
+}
+
+
+
+TestEntity::TestEntity(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+
+TestEntity::~TestEntity ()
+{}
+
+
+
+void TestEntity::init()
+{
+  this->setClassID(CL_TEST_ENTITY, "TestEntity");
+  this->toList(OM_COMMON);
+}
+
+/**
+ * loads the Settings of a MD2Creature from an XML-element.
+ * @param root the XML-element to load the MD2Creature's properties from
+ */
+void TestEntity::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+
+  LoadParam(root, "md2animation", this, TestEntity, setAnim)
+      .describe("sets the animation of the md2 model")
+      .defaultValues(1, 1);
+
+}
+
+
+void  TestEntity::setAnim(int animationIndex)
+{
+  if( likely(this->getModel(0) != NULL))
+    ((MD2Model*)this->getModel(0))->setAnim(animationIndex);
+}
+
+
+void TestEntity::tick (float time)
+{
+  if( likely(this->getModel(0) != NULL))
+    ((MD2Model*)this->getModel(0))->tick(time);
+
+}
+
+
+void TestEntity::collidesWith(WorldEntity* entity, const Vector& location)
+{}
+
+
Index: branches/network/src/world_entities/test_entity.h
===================================================================
--- branches/network/src/world_entities/test_entity.h	(revision 6636)
+++ branches/network/src/world_entities/test_entity.h	(revision 6636)
@@ -0,0 +1,39 @@
+#ifndef _TEST_ENTITY_H
+#define _TEST_ENTITY_H
+
+#include "world_entity.h"
+#include "physics_interface.h"
+
+class MD2Loader;
+class MD2Model;
+class MD2Model2;
+struct t3DModel;
+class Material;
+class TiXmlElement;
+
+class TestEntity : public WorldEntity, public PhysicsInterface
+{
+  friend class World;
+
+ public:
+  TestEntity ();
+  TestEntity(const TiXmlElement* root);
+  virtual ~TestEntity ();
+
+  void init();
+  virtual void loadParams(const TiXmlElement* root);
+
+  void setAnim(int animationIndex);
+
+  virtual void tick (float time);
+  virtual void collidesWith(WorldEntity* entity, const Vector& location);
+
+ private:
+  /* TESTING TESTING TESTING */
+  t3DModel* model;
+  MD2Model* md2Model;
+  Material* material;
+
+};
+
+#endif /* _TEST_ENTITY_H */
Index: branches/network/src/world_entities/weapons/aim.cc
===================================================================
--- branches/network/src/world_entities/weapons/aim.cc	(revision 6636)
+++ branches/network/src/world_entities/weapons/aim.cc	(revision 6636)
@@ -0,0 +1,206 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "aim.h"
+
+#include "load_param.h"
+#include "graphics_engine.h"
+#include "state.h"
+#include "material.h"
+#include "t_animation.h"
+#include "text.h"
+
+#include "world_entity.h"
+
+using namespace std;
+
+
+/**
+ * standart constructor
+ */
+Aim::Aim (PNode* source, const TiXmlElement* root)
+{
+  this->init();
+
+  this->source = source;
+
+  if (root)
+    this->loadParams(root);
+  else
+    this->setTexture("maps/aim.png");
+}
+
+/**
+ * destroys a Aim
+*/
+Aim::~Aim ()
+{
+  if (this->material)
+    delete this->material;
+
+/*  if (this->text != NULL)
+    delete this->text;*/
+}
+
+/**
+ * initializes the Aim
+ */
+void Aim::init()
+{
+  this->setClassID(CL_CROSSHAIR, "Aim");
+  this->setName("Aim");
+
+  this->setLayer(E2D_LAYER_TOP);
+  this->setRotationSpeed(30.0* (float)rand()/RAND_MAX + 10.0);
+  this->setSize(GraphicsEngine::getInstance()->getResolutionX()/10.0);
+
+  this->setBindNode(this);
+  this->material = new Material;
+  this->source = NULL;
+
+  this->anim = new tAnimation<Aim>(this, &Aim::setSize);
+  this->anim->setInfinity(ANIM_INF_CONSTANT);
+  this->anim->addKeyFrame(500, .3, ANIM_LINEAR);
+  this->anim->addKeyFrame(100, .2, ANIM_LINEAR);
+  this->anim->addKeyFrame(50, .01, ANIM_LINEAR);
+
+/*  this->text = new Text();
+  this->text->setLayer(this->getLayer());
+  this->text->setParent2D(this);
+  this->text->setRelCoor2D(10, -50);
+  this->text->setParentMode2D(E2D_PARENT_MOVEMENT);
+  this->text->setText("Testing");*/
+}
+
+void Aim::loadParams(const TiXmlElement* root)
+{
+  PNode::loadParams(root);
+
+  LoadParam(root, "texture", this, Aim, setTexture)
+      .describe("the texture-file to load onto the Aim");
+
+  LoadParam(root, "size", this, Aim, setSize)
+      .describe("the size of the Aim in Pixels");
+
+  LoadParam(root, "rotation-speed", this, Aim, setRotationSpeed)
+      .describe("the Speed with which the Aim should rotate");
+}
+
+void Aim::searchTarget(float range)
+{
+  std::list<WorldEntity*>::iterator entity;
+
+  for (entity = State::getObjectManager()->getObjectList(OM_GROUP_00).begin();
+       entity != State::getObjectManager()->getObjectList(OM_GROUP_00).end();
+       entity ++)
+  {
+    if (this->source->getAbsCoor().x < (*entity)->getAbsCoor().x && (this->source->getAbsCoor() - (*entity)->getAbsCoor()).len() < range)
+    {
+      if (this->getParent() != (*entity))
+      {
+        this->anim->replay();
+        this->setParentSoft(*entity, 5);
+        return;
+      }
+    }
+  }
+}
+
+
+
+/**
+ * @brief sets the size of the Aim.
+ * @param size the size in pixels
+ */
+void Aim::setSize(float size)
+{
+  this->setSize2D(size/2, size/2);
+}
+
+/**
+ * sets the material to load
+ * @param textureFile The texture-file to load onto the crosshair
+ */
+void Aim::setTexture(const char* textureFile)
+{
+  this->material->setDiffuseMap(textureFile);
+}
+
+/**
+ * ticks the Aim
+ * @param dt the time to ticks
+ */
+void Aim::tick(float dt)
+{
+  // let the crosshair rotate
+  this->shiftDir2D(dt * rotationSpeed);
+
+//   char outputText[100];
+//   sprintf(outputText, "%s - distance: %f\n", this->getParent()->getName(), (this->source->getAbsCoor() - this->getAbsCoor()).len());
+//   this->text->setText(outputText);
+
+
+  if (this->source->getAbsCoor().x > this->getAbsCoor().x )
+    this->searchTarget(1000);
+//   float z = 0.0f;
+//   glReadPixels ((int)this->getAbsCoor2D().x,
+//                  GraphicsEngine::getInstance()->getResolutionY()-(int)this->getAbsCoor2D().y-1,
+//                  1,
+//                  1,
+//                  GL_DEPTH_COMPONENT,
+//                  GL_FLOAT,
+//                  &z);
+//
+//
+//   GLdouble objX=.0, objY=.0, objZ=.0;
+//   gluUnProject(this->getAbsCoor2D().x,
+//                GraphicsEngine::getInstance()->getResolutionY()-this->getAbsCoor2D().y-1,
+//                .99,  // z
+//                GraphicsEngine::modMat,
+//                GraphicsEngine::projMat,
+//                GraphicsEngine::viewPort,
+//                &objX,
+//                &objY,
+//                &objZ );
+//
+//   this->setAbsCoor(objX, objY, objZ);
+}
+
+/**
+ * draws the crosshair
+ */
+void Aim::draw() const
+{
+
+  glPushMatrix();
+  glTranslatef(this->getAbsCoor2D().x, this->getAbsCoor2D().y, 0);
+
+  glRotatef(this->getAbsDir2D(), 0,0,1);
+  this->material->select();
+  glBegin(GL_TRIANGLE_STRIP);
+  glTexCoord2f(0, 0);
+  glVertex2f(-this->getSizeX2D(), -this->getSizeY2D());
+  glTexCoord2f(1, 0);
+  glVertex2f(this->getSizeX2D(), -this->getSizeY2D());
+  glTexCoord2f(0, 1);
+  glVertex2f(-this->getSizeX2D(), this->getSizeY2D());
+  glTexCoord2f(1, 1);
+  glVertex2f(this->getSizeX2D(), this->getSizeY2D());
+  glEnd();
+  glPopMatrix();
+
+}
Index: branches/network/src/world_entities/weapons/aim.h
===================================================================
--- branches/network/src/world_entities/weapons/aim.h	(revision 6636)
+++ branches/network/src/world_entities/weapons/aim.h	(revision 6636)
@@ -0,0 +1,60 @@
+/*!
+ * @file aim.h
+ *  Definition of
+ */
+
+#ifndef _AIM_H
+#define _AIM_H
+
+#include "p_node.h"
+#include "element_2d.h"
+
+// FORWARD DECLARATION
+class Model;
+class Text;
+class Material;
+class TiXmlElement;
+template<class T> class tAnimation;
+
+//! An Aim for zooming in on Targets.
+/**
+ * An Aim is a PNode, that is connected, to the Target, it has aquired
+ * The target becomes, if selected its Parent.
+ *
+ * Also the Aim is a Element2D, as it draws a cross onto the Target.
+ */
+class Aim : public PNode, public Element2D {
+
+ public:
+  Aim(PNode* source, const TiXmlElement* root = NULL);
+  virtual ~Aim();
+
+  void init();
+  virtual void loadParams(const TiXmlElement* root);
+
+  inline void setSource(PNode* source) { this->source = source; };
+
+  inline void selectTarget(PNode* target) { this->setParent(target); };
+  inline PNode* getTarget(PNode* target) { return this->getParent(); };
+
+  void searchTarget(float range);
+
+  void setSize(float size);
+  void setTexture(const char* textureFile);
+  /** @param rotationSpeed the speed at what the crosshair should rotate */
+  inline void setRotationSpeed(float rotationSpeed) { this->rotationSpeed = rotationSpeed; };
+
+  virtual void tick(float dt);
+  virtual void draw() const;
+
+ private:
+   Material*        material;             //!< a material for the Aim.
+   float            rotationSpeed;        //!< Speed of the Rotation.
+   tAnimation<Aim>* anim;
+
+   PNode*           source;               //!< Where this Shot has come from.
+
+   Text*            text;                 //!< A Text to display onto this Node. (distance to Target)
+};
+
+#endif /* _AIM_H */
Index: branches/network/src/world_entities/weapons/aiming_turret.cc
===================================================================
--- branches/network/src/world_entities/weapons/aiming_turret.cc	(revision 6636)
+++ branches/network/src/world_entities/weapons/aiming_turret.cc	(revision 6636)
@@ -0,0 +1,171 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Benjamin Grauer
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "aiming_turret.h"
+
+#include "weapon_manager.h"
+#include "aim.h"
+#include "world_entities/projectiles/projectile.h"
+
+#include "model.h"
+
+#include "animation3d.h"
+
+#include "factory.h"
+
+CREATE_FACTORY(AimingTurret, CL_AIMING_TURRET);
+
+using namespace std;
+
+
+/**
+ *  standard constructor
+
+   creates a new weapon
+*/
+AimingTurret::AimingTurret ()
+  : Weapon()
+{
+  this->init();
+
+  this->loadModel("models/guns/turret2.obj");
+
+
+  this->setActionSound(WA_SHOOT, "sound/shot1.wav");
+  this->setActionSound(WA_ACTIVATE, "sound/voices/rockets.wav");
+  this->setActionSound(WA_RELOAD, "sound/vocals/reload.wav");
+}
+
+
+AimingTurret::AimingTurret(const TiXmlElement* root)
+{
+  this->init();
+  this->loadParams(root);
+}
+
+/**
+ *  standard deconstructor
+*/
+AimingTurret::~AimingTurret ()
+{
+  // model will be deleted from WorldEntity-destructor
+//  delete this->target;
+}
+
+void AimingTurret::init()
+{
+  this->setClassID(CL_AIMING_TURRET, "AimingTurret");
+
+  Animation3D* animation1 = this->getAnimation(WS_ACTIVATING, this);
+  Animation3D* animation2 = this->getAnimation(WS_DEACTIVATING, this);
+
+  animation1->addKeyFrame(Vector(0, -.5, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+  animation1->addKeyFrame(Vector(0, 0, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+  animation2->addKeyFrame(Vector(0, 0, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+  animation2->addKeyFrame(Vector(0, -.5, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+
+  animation1->setInfinity(ANIM_INF_CONSTANT);
+  animation2->setInfinity(ANIM_INF_CONSTANT);
+
+  this->setStateDuration(WS_SHOOTING, .1);
+  this->setStateDuration(WS_RELOADING, .1);
+  this->setStateDuration(WS_ACTIVATING, .4);
+  this->setStateDuration(WS_DEACTIVATING, .4);
+
+  this->setMaximumEnergy(10000, 50);
+  this->increaseEnergy(100000);
+
+  this->setCapability(WTYPE_ALLDIRS | WTYPE_TURRET);
+  this->setProjectileType(CL_ROCKET);
+
+
+  this->setEmissionPoint(1.684, 0.472, 0);
+  //this->getProjectileFactory()->prepare(100);
+
+  this->target = new Aim(this);
+  this->target->setVisibility(false);
+}
+
+void AimingTurret::loadParams(const TiXmlElement* root)
+{
+  Weapon::loadParams(root);
+
+}
+
+void AimingTurret::activate()
+{
+  this->target->setVisibility(true);
+}
+
+void AimingTurret::deactivate()
+{
+  this->target->setVisibility(false);
+}
+
+void AimingTurret::tick(float dt)
+{
+  Quaternion quat;
+  Vector direction = this->target->getAbsCoor() - this->getAbsCoor();
+
+  direction.normalize();
+
+  if (likely (this->getParent() != NULL))
+    quat = Quaternion(direction, this->getParent()->getAbsDir().apply(Vector(0,1,0))) * Quaternion ( -M_PI_2, Vector(0,1,0)) ;
+  else
+    quat = Quaternion(direction, Vector(0,1,0)) * Quaternion ( -M_PI_2, Vector(0,1,0)) ;
+
+  this->setAbsDirSoft(quat, 5);
+
+  this->target->tick(dt);
+}
+
+void AimingTurret::fire()
+{
+  Projectile* pj = this->getProjectile();
+  if (pj == NULL)
+    return;
+
+  pj->setVelocity(/*this->getVelocity()+*/(this->getAbsDir().apply(Vector(1,0,0))*250.0 + VECTOR_RAND(13)
+            /*target->getAbsCoor() - this->getAbsCoor()*/)*.5);//this->getVelocity());
+
+  pj->setParent(PNode::getNullParent());
+  pj->setAbsCoor(this->getEmissionPoint());
+  pj->setAbsDir(this->getAbsDir());
+  pj->activate();
+  this->target->searchTarget(100);
+}
+
+void AimingTurret::destroy ()
+{}
+
+/**
+ * draws the AimingTurret
+*/
+void AimingTurret::draw () const
+{
+  /* draw gun body */
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+  Vector tmpRot = this->getAbsDir().getSpacialAxis();
+  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+
+  this->getModel()->draw();
+  glPopMatrix();
+}
+
Index: branches/network/src/world_entities/weapons/aiming_turret.h
===================================================================
--- branches/network/src/world_entities/weapons/aiming_turret.h	(revision 6636)
+++ branches/network/src/world_entities/weapons/aiming_turret.h	(revision 6636)
@@ -0,0 +1,37 @@
+/*!
+ * @file aiming_turret.h
+*/
+
+
+#ifndef _AIMING_TURRET_H
+#define _AIMING_TURRET_H
+
+#include "weapon.h"
+
+/* FORWARD DECLARATION */
+class Aim;
+
+class AimingTurret : public Weapon
+  {
+  public:
+    AimingTurret ();
+    AimingTurret(const TiXmlElement* root);
+    virtual ~AimingTurret ();
+
+    void init();
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void tick(float dt);
+    virtual void fire();
+    virtual void destroy();
+
+    virtual void draw() const;
+
+  private:
+    Aim*          target;
+  };
+
+#endif /* _AIMING_TURRET_H */
Index: branches/network/src/world_entities/weapons/cannon.cc
===================================================================
--- branches/network/src/world_entities/weapons/cannon.cc	(revision 6636)
+++ branches/network/src/world_entities/weapons/cannon.cc	(revision 6636)
@@ -0,0 +1,209 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer:
+
+
+   @todo: direction in which the projectile flights
+   @todo: a target to set/hit
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "cannon.h"
+
+#include "world_entity.h"
+#include "model.h"
+#include "world_entities/projectiles/projectile.h"
+#include "weapon_manager.h"
+#include "factory.h"
+
+#include "vector.h"
+#include "list.h"
+#include "animation3d.h"
+
+#include "fast_factory.h"
+
+
+using namespace std;
+
+CREATE_FACTORY(Cannon, CL_CANNON);
+
+/**
+ *  standard constructor
+
+   creates a new weapon
+*/
+Cannon::Cannon ()
+  : Weapon()
+{
+  this->init();
+}
+
+
+Cannon::Cannon(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  standard deconstructor
+*/
+Cannon::~Cannon ()
+{
+  // model will be deleted from WorldEntity-destructor
+}
+
+
+void Cannon::init()
+{
+  this->setClassID(CL_CANNON, "Cannon");
+
+//  this->model = (Model*)ResourceManager::getInstance()->load("models/guns/test_gun.obj", OBJ, RP_CAMPAIGN);
+
+  this->loadModel("models/guns/cannon.obj");
+
+  this->setStateDuration(WS_SHOOTING, 2.0);
+  this->setStateDuration(WS_RELOADING, .1);
+  this->setStateDuration(WS_ACTIVATING, .1);
+  this->setStateDuration(WS_DEACTIVATING, .4);
+
+  this->setMaximumEnergy(100, 20);
+  this->increaseEnergy(100);
+  //this->minCharge = 2;
+
+  this->setActionSound(WA_SHOOT, "sound/explo.wav");
+  this->setActionSound(WA_ACTIVATE, "sound/voices/cannon.wav");
+
+  this->setCapability(WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+  this->setProjectileType(CL_BOMB);
+  this->prepareProjectiles(5);
+
+//  this->objectComponent1 = new PNode();
+//  Animation3D* animation1 = this->getAnimation(WS_SHOOTING, this->objectComponent1);
+  Animation3D* animation2 = this->getAnimation(WS_ACTIVATING, this);
+  Animation3D* animation3 = this->getAnimation(WS_DEACTIVATING, this);
+  //parent->addChild(this->objectComponent1, PNODE_ALL);
+//  this->addChild(this->objectComponent1);
+
+//  animation1->setInfinity(ANIM_INF_CONSTANT);
+  animation2->setInfinity(ANIM_INF_CONSTANT);
+  animation3->setInfinity(ANIM_INF_CONSTANT);
+
+  this->setEmissionPoint(3.8, 1.2, 0);
+
+//     animation1->addKeyFrame(Vector(0, -1.5, 0), Quaternion(), 0.1, ANIM_LINEAR, ANIM_NULL);
+//     animation1->addKeyFrame(Vector(0, 0, 0), Quaternion(), 0.1, ANIM_LINEAR, ANIM_NULL);
+//     animation1->addKeyFrame(Vector(0, 0, 0), Quaternion(), 0.0, ANIM_LINEAR, ANIM_NULL);
+
+  animation2->addKeyFrame(Vector(0.0, -1.0, 0.0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+  animation2->addKeyFrame(Vector(0.0, 0.0, 0.0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+
+  animation3->addKeyFrame(Vector(0.0, 0.0, 0.0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+  animation3->addKeyFrame(Vector(0.0, -1.0, 0.0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+}
+
+
+void Cannon::loadParams(const TiXmlElement* root)
+{
+  Weapon::loadParams(root);
+}
+
+
+/**
+ *  this activates the weapon
+
+   This is needed, since there can be more than one weapon on a ship. the
+   activation can be connected with an animation. for example the weapon is
+   been armed out.
+*/
+void Cannon::activate()
+{
+}
+
+
+/**
+ *  this deactivates the weapon
+
+   This is needed, since there can be more than one weapon on a ship. the
+   activation can be connected with an animation. for example the weapon is
+   been armed out.
+*/
+void Cannon::deactivate()
+{
+}
+
+
+/**
+ *  fires the weapon
+
+   this is called from the player.cc, when fire-button is been pushed
+   @todo: the ObjectManager deliveres Projectiles not TestBullets! this should be diffrent
+*/
+void Cannon::fire()
+{
+  Projectile* pj =  this->getProjectile();
+  if (pj == NULL)
+    return;
+
+  pj->setParent(PNode::getNullParent());
+
+  pj->setVelocity(this->getVelocity() + this->getAbsDir().apply(Vector(1,0,0))*15+VECTOR_RAND(5));
+
+  pj->setAbsCoor(this->getEmissionPoint());
+  pj->setAbsDir(this->getAbsDir());
+  pj->activate();
+}
+
+/**
+ *  is called, when the weapon is destroyed
+ *
+ * this is in conjunction with the hit function, so when a weapon is able to get
+ * hit, it can also be destoryed.
+*/
+void Cannon::destroy ()
+{}
+
+/**
+ *  this will draw the weapon
+*/
+void Cannon::draw () const
+{
+  /* draw gun body */
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+
+  Vector tmpRot = this->getAbsDir().getSpacialAxis();
+  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+
+  this->getModel()->draw();
+  glPopMatrix();
+
+  /* draw objectComponent1: gun coil - animated stuff */
+/*  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  glTranslatef (this->objectComponent1->getAbsCoor ().x,
+                this->objectComponent1->getAbsCoor ().y,
+                this->objectComponent1->getAbsCoor ().z);
+  tmpRot = this->objectComponent1->getAbsDir().getSpacialAxis();
+  glRotatef (this->objectComponent1->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+  this->model->draw(0);
+
+  glPopMatrix();*/
+}
+
Index: branches/network/src/world_entities/weapons/cannon.h
===================================================================
--- branches/network/src/world_entities/weapons/cannon.h	(revision 6636)
+++ branches/network/src/world_entities/weapons/cannon.h	(revision 6636)
@@ -0,0 +1,33 @@
+/*!
+ * @file cannon.h
+ * a weapon that is fix on top of the player to fire heavy weaponary.
+*/
+
+
+#ifndef _CANNON_H
+#define _CANNON_H
+
+#include "weapon.h"
+
+class Cannon : public Weapon
+  {
+  public:
+    Cannon ();
+    Cannon (const TiXmlElement* root);
+    virtual ~Cannon ();
+
+    void init();
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void fire();
+    virtual void destroy();
+
+    virtual void draw() const;
+
+  private:
+//     PNode* objectComponent1;         //<! the gun is made of multiple parts, these PNodes represent their location and orientation
+  };
+#endif /* _CANNON_H */
Index: branches/network/src/world_entities/weapons/crosshair.cc
===================================================================
--- branches/network/src/world_entities/weapons/crosshair.cc	(revision 6636)
+++ branches/network/src/world_entities/weapons/crosshair.cc	(revision 6636)
@@ -0,0 +1,184 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Benjamin Grauer
+   co-programmer: ...
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "crosshair.h"
+#include "event_handler.h"
+
+#include "load_param.h"
+#include "graphics_engine.h"
+#include "glincl.h"
+#include "state.h"
+#include "material.h"
+
+using namespace std;
+
+
+/**
+ * standart constructor
+ */
+Crosshair::Crosshair (const TiXmlElement* root)
+{
+  this->init();
+
+  if (root)
+    this->loadParams(root);
+  else
+    this->setTexture("maps/aim.png");
+}
+
+/**
+ * destroys a Crosshair
+*/
+Crosshair::~Crosshair ()
+{
+  if (this->material)
+  delete this->material;
+
+  // delete what has to be deleted here
+
+  GraphicsEngine::showMouse(true);
+  GraphicsEngine::stealWMEvents(false);
+}
+
+/**
+ * initializes the Crosshair
+ */
+void Crosshair::init()
+{
+  this->setClassID(CL_CROSSHAIR, "Crosshair");
+  this->setName("Crosshair");
+
+  this->setLayer(E2D_LAYER_TOP);
+  this->setRotationSpeed(5);
+  this->setSize(GraphicsEngine::getInstance()->getResolutionX()/10.0);
+
+  this->setBindNode(this);
+  this->material = new Material;
+
+  //EventHandler::getInstance()->subscribe(this, ES_GAME, EV_MOUSE_MOTION);
+
+  // center the mouse on the screen, and also hide the cursors
+  SDL_WarpMouse(GraphicsEngine::getInstance()->getResolutionX()/2, GraphicsEngine::getInstance()->getResolutionY()/2);
+  GraphicsEngine::showMouse(false);
+  GraphicsEngine::stealWMEvents(true);
+  SDL_WarpMouse(GraphicsEngine::getInstance()->getResolutionX()/2, GraphicsEngine::getInstance()->getResolutionY()/2);
+}
+
+
+void Crosshair::loadParams(const TiXmlElement* root)
+{
+  PNode::loadParams(root);
+  EventListener::loadParams(root);
+
+  LoadParam(root, "texture", this, Crosshair, setTexture)
+      .describe("the texture-file to load onto the Crosshair");
+
+  LoadParam(root, "size", this, Crosshair, setSize)
+      .describe("the size of the Crosshair in Pixels");
+
+  LoadParam(root, "rotation-speed", this, Crosshair, setRotationSpeed)
+      .describe("the Speed with which the Crosshair should rotate");
+}
+
+
+/**
+ * sets the size of the Crosshair.
+ * @param size the size in pixels
+ */
+void Crosshair::setSize(float size)
+{
+  this->setSize2D(size/2, size/2);
+}
+
+/**
+ * sets the material to load
+ * @param textureFile The texture-file to load onto the crosshair
+ */
+void Crosshair::setTexture(const char* textureFile)
+{
+  this->material->setDiffuseMap(textureFile);
+}
+
+/**
+ * processes the input
+ * @param event the Event coming as input
+ */
+void Crosshair::process(const Event &event)
+{
+  if  (event.type == EV_MOUSE_MOTION)
+  {
+    //this->setAbsCoor2D(event.x, event.y);
+  }
+}
+
+/**
+ * ticks the Crosshair
+ * @param dt the time to ticks
+ */
+void Crosshair::tick(float dt)
+{
+  // let the crosshair rotate
+  this->shiftDir2D(dt * rotationSpeed);
+
+
+  float z = 0.0f;
+  glReadPixels ((int)this->getAbsCoor2D().x,
+                 GraphicsEngine::getInstance()->getResolutionY()-(int)this->getAbsCoor2D().y-1,
+                 1,
+                 1,
+                 GL_DEPTH_COMPONENT,
+                 GL_FLOAT,
+                 &z);
+
+
+  GLdouble objX=.0, objY=.0, objZ=.0;
+  gluUnProject(this->getAbsCoor2D().x,
+               GraphicsEngine::getInstance()->getResolutionY()-this->getAbsCoor2D().y-1,
+               .99,  // z
+               GraphicsEngine::modMat,
+               GraphicsEngine::projMat,
+               GraphicsEngine::viewPort,
+               &objX,
+               &objY,
+               &objZ );
+
+  //this->setAbsCoor(objX, objY, objZ);
+}
+
+/**
+ * draws the crosshair
+ */
+void Crosshair::draw() const
+{
+  glPushMatrix();
+  glTranslatef(this->getAbsCoor2D().x, this->getAbsCoor2D().y, 0);
+
+  glRotatef(this->getAbsDir2D(), 0,0,1);
+  this->material->select();
+  glBegin(GL_TRIANGLE_STRIP);
+  glTexCoord2f(0, 0);
+  glVertex2f(-this->getSizeX2D(), -this->getSizeY2D());
+  glTexCoord2f(1, 0);
+  glVertex2f(this->getSizeX2D(), -this->getSizeY2D());
+  glTexCoord2f(0, 1);
+  glVertex2f(-this->getSizeX2D(), this->getSizeY2D());
+  glTexCoord2f(1, 1);
+  glVertex2f(this->getSizeX2D(), this->getSizeY2D());
+  glEnd();
+  glPopMatrix();
+
+}
Index: branches/network/src/world_entities/weapons/crosshair.h
===================================================================
--- branches/network/src/world_entities/weapons/crosshair.h	(revision 6636)
+++ branches/network/src/world_entities/weapons/crosshair.h	(revision 6636)
@@ -0,0 +1,46 @@
+/*!
+ * @file crosshair.h
+  *  Definition of ...
+
+*/
+
+#ifndef _CROSSHAIR_H
+#define _CROSSHAIR_H
+
+#include "p_node.h"
+#include "element_2d.h"
+#include "event_listener.h"
+
+#include "vector.h"
+
+
+// FORWARD DECLARATION
+class Model;
+class Material;
+class TiXmlElement;
+
+//! A class that enables the
+class Crosshair : public PNode, public Element2D, public EventListener {
+
+ public:
+  Crosshair(const TiXmlElement* root = NULL);
+  virtual ~Crosshair();
+
+  void init();
+  virtual void loadParams(const TiXmlElement* root);
+
+  void setSize(float size);
+  void setTexture(const char* textureFile);
+  /** @param rotationSpeed the speed at what the crosshair should rotate */
+  void setRotationSpeed(float rotationSpeed) { this->rotationSpeed = rotationSpeed; };
+
+  virtual void process(const Event &event);
+  virtual void tick(float dt);
+  virtual void draw() const;
+
+ private:
+   Material*        material;             //!< a material for the Aim.
+   float            rotationSpeed;        //!< Speed of the Rotation.
+};
+
+#endif /* _CROSSHAIR_H */
Index: branches/network/src/world_entities/weapons/targeting_turret.cc
===================================================================
--- branches/network/src/world_entities/weapons/targeting_turret.cc	(revision 6636)
+++ branches/network/src/world_entities/weapons/targeting_turret.cc	(revision 6636)
@@ -0,0 +1,162 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Benjamin Grauer
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "targeting_turret.h"
+
+#include "weapon_manager.h"
+#include "aim.h"
+#include "world_entities/projectiles/projectile.h"
+
+#include "model.h"
+
+#include "animation3d.h"
+
+#include "factory.h"
+
+CREATE_FACTORY(TargetingTurret, CL_TARGETING_TURRET);
+
+using namespace std;
+
+
+/**
+ *  standard constructor
+
+   creates a new weapon
+*/
+TargetingTurret::TargetingTurret ()
+  : Weapon()
+{
+  this->init();
+
+}
+
+
+TargetingTurret::TargetingTurret(const TiXmlElement* root)
+{
+  this->init();
+  this->loadParams(root);
+}
+
+/**
+ *  standard deconstructor
+*/
+TargetingTurret::~TargetingTurret ()
+{
+  // model will be deleted from WorldEntity-destructor
+//  delete this->target;
+}
+
+void TargetingTurret::init()
+{
+  this->setClassID(CL_TARGETING_TURRET, "TargetingTurret");
+
+  Animation3D* animation1 = this->getAnimation(WS_ACTIVATING, this);
+  Animation3D* animation2 = this->getAnimation(WS_DEACTIVATING, this);
+
+  animation1->addKeyFrame(Vector(0, -.5, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+  animation1->addKeyFrame(Vector(0, 0, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+  animation2->addKeyFrame(Vector(0, 0, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+  animation2->addKeyFrame(Vector(0, -.5, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+
+  animation1->setInfinity(ANIM_INF_CONSTANT);
+  animation2->setInfinity(ANIM_INF_CONSTANT);
+
+  this->setStateDuration(WS_SHOOTING, .1);
+  this->setStateDuration(WS_RELOADING, .1);
+  this->setStateDuration(WS_ACTIVATING, .4);
+  this->setStateDuration(WS_DEACTIVATING, .4);
+
+  this->setMaximumEnergy(10000, 50);
+  this->increaseEnergy(100000);
+
+  this->setCapability(WTYPE_ALLDIRS | WTYPE_TURRET);
+  this->setProjectileType(CL_GUIDED_MISSILE);
+
+
+  this->setEmissionPoint(1.684, 0.472, 0);
+  //this->getProjectileFactory()->prepare(100);
+
+  this->target = new Aim(this);
+  this->target->setVisibility(false);
+
+  this->loadModel("models/guns/turret2.obj");
+
+
+  this->setActionSound(WA_SHOOT, "sound/shot1.wav");
+  this->setActionSound(WA_ACTIVATE, "sound/voices/rockets.wav");
+  this->setActionSound(WA_RELOAD, "sound/vocals/reload.wav");
+}
+
+void TargetingTurret::loadParams(const TiXmlElement* root)
+{
+  Weapon::loadParams(root);
+
+}
+
+void TargetingTurret::activate()
+{
+  this->target->setVisibility(true);
+}
+
+void TargetingTurret::deactivate()
+{
+  this->target->setVisibility(false);
+}
+
+void TargetingTurret::tick(float dt)
+{
+
+  this->target->tick(dt);
+}
+
+void TargetingTurret::fire()
+{
+  Projectile* pj = this->getProjectile();
+  if (pj == NULL)
+    return;
+
+  pj->setVelocity(this->getVelocity() + /*this->getVelocity()+*/(this->getAbsDir().apply(Vector(1,0,0))*250.0 + VECTOR_RAND(13)
+            /*target->getAbsCoor() - this->getAbsCoor()*/)*.5);//this->getVelocity());
+
+  pj->setTarget(this->target->getParent());
+  pj->setParent(PNode::getNullParent());
+  pj->setAbsCoor(this->getEmissionPoint());
+  pj->setAbsDir(this->getAbsDir());
+  pj->activate();
+  this->target->searchTarget(100);
+}
+
+void TargetingTurret::destroy ()
+{}
+
+/**
+ * draws the TargetingTurret
+*/
+void TargetingTurret::draw () const
+{
+  /* draw gun body */
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+  Vector tmpRot = this->getAbsDir().getSpacialAxis();
+  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+  if (this->getModel() != NULL)
+    this->getModel()->draw();
+  glPopMatrix();
+}
+
Index: branches/network/src/world_entities/weapons/targeting_turret.h
===================================================================
--- branches/network/src/world_entities/weapons/targeting_turret.h	(revision 6636)
+++ branches/network/src/world_entities/weapons/targeting_turret.h	(revision 6636)
@@ -0,0 +1,37 @@
+/*!
+ * @file aiming_turret.h
+*/
+
+
+#ifndef _TARGETING_TURRET_H
+#define _TARGETING_TURRET_H
+
+#include "weapon.h"
+
+/* FORWARD DECLARATION */
+class Aim;
+
+class TargetingTurret : public Weapon
+  {
+  public:
+    TargetingTurret ();
+    TargetingTurret(const TiXmlElement* root);
+    virtual ~TargetingTurret ();
+
+    void init();
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void tick(float dt);
+    virtual void fire();
+    virtual void destroy();
+
+    virtual void draw() const;
+
+  private:
+    Aim*          target;
+  };
+
+#endif /* _TARGETING_TURRET_H */
Index: branches/network/src/world_entities/weapons/test_gun.cc
===================================================================
--- branches/network/src/world_entities/weapons/test_gun.cc	(revision 6636)
+++ branches/network/src/world_entities/weapons/test_gun.cc	(revision 6636)
@@ -0,0 +1,231 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer:
+
+
+   @todo: direction in which the projectile flights
+   @todo: a target to set/hit
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "test_gun.h"
+#include "world_entities/projectiles/projectile.h"
+
+#include "world_entity.h"
+#include "static_model.h"
+#include "weapon_manager.h"
+#include "factory.h"
+
+#include "animation3d.h"
+
+#include "fast_factory.h"
+
+
+using namespace std;
+
+CREATE_FACTORY(TestGun, CL_TEST_GUN);
+
+/**
+ *  standard constructor
+
+   creates a new weapon
+*/
+TestGun::TestGun ( int leftRight)
+  : Weapon()
+{
+  this->init();
+
+
+  this->leftRight = leftRight;
+
+  this->objectComponent1 = new PNode();
+  Animation3D* animation1 = this->getAnimation(WS_SHOOTING, this->objectComponent1);
+  Animation3D* animation2 = this->getAnimation(WS_ACTIVATING, this);
+  Animation3D* animation3 = this->getAnimation(WS_DEACTIVATING, this);
+  //parent->addChild(this->objectComponent1, PNODE_ALL);
+  this->addChild(this->objectComponent1);
+
+  animation1->setInfinity(ANIM_INF_CONSTANT);
+  animation2->setInfinity(ANIM_INF_CONSTANT);
+  animation3->setInfinity(ANIM_INF_CONSTANT);
+
+  if( this->leftRight == W_LEFT)
+  {
+    this->setEmissionPoint(1.0, -0.6, -0.2);
+
+    animation1->addKeyFrame(Vector(0, 0, 0), Quaternion(), 0.1, ANIM_LINEAR, ANIM_NULL);
+    animation1->addKeyFrame(Vector(-0.4, 0, 0), Quaternion(), 0.1, ANIM_LINEAR, ANIM_NULL);
+    animation1->addKeyFrame(Vector(0, 0, 0), Quaternion(), 0.0, ANIM_LINEAR, ANIM_NULL);
+
+    animation2->addKeyFrame(Vector(0.0, 0.0, -1.0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+    animation2->addKeyFrame(Vector(0.0, 0.0, 0.0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+
+    animation3->addKeyFrame(Vector(0.0, 0.0, 0.0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+    animation3->addKeyFrame(Vector(0.0, 0.0, -1.0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+  }
+  else if( this->leftRight == W_RIGHT)
+  {
+    this->setEmissionPoint(1.0, -0.6, 0.3);
+
+    this->objectComponent1->setRelCoor(Vector(0,0,0.35));
+    animation1->addKeyFrame(Vector(0, 0, .5), Quaternion(), 0.1, ANIM_LINEAR, ANIM_NULL);
+    animation1->addKeyFrame(Vector(-0.4, 0, .5), Quaternion(), 0.1, ANIM_LINEAR, ANIM_NULL);
+    animation1->addKeyFrame(Vector(0, 0, .5), Quaternion(), 0.0, ANIM_LINEAR, ANIM_NULL);
+
+    animation2->addKeyFrame(Vector(.0, .0, 1.0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+    animation2->addKeyFrame(Vector(.0, .0, .0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+
+    animation3->addKeyFrame(Vector(.0, .0, 0.0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+    animation3->addKeyFrame(Vector(.0, .0, 1.0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_NULL);
+  }
+}
+
+
+TestGun::TestGun(const TiXmlElement* root)
+{
+  this->init();
+  this->loadParams(root);
+}
+
+/**
+ *  standard deconstructor
+*/
+TestGun::~TestGun ()
+{
+  // model will be deleted from WorldEntity-destructor
+}
+
+
+void TestGun::init()
+{
+  this->setClassID(CL_TEST_GUN, "TestGun");
+
+//  this->model = (Model*)ResourceManager::getInstance()->load("models/guns/test_gun.obj", OBJ, RP_CAMPAIGN);
+
+  this->loadModel("models/guns/test_gun.obj");
+
+  this->setStateDuration(WS_SHOOTING, .1);
+  this->setStateDuration(WS_RELOADING, .1);
+  this->setStateDuration(WS_ACTIVATING, .4);
+  this->setStateDuration(WS_DEACTIVATING, .4);
+
+  this->setMaximumEnergy(1000, 100);
+  this->increaseEnergy(1000);
+  //this->minCharge = 2;
+
+  this->setActionSound(WA_SHOOT, "sound/laser.wav");
+  this->setActionSound(WA_ACTIVATE, "sound/voices/lasers.wav");
+
+
+  this->setCapability(WTYPE_ALLDIRS | WTYPE_DIRECTIONAL);
+  this->setProjectileType(CL_LASER);
+  this->prepareProjectiles(20);
+
+}
+
+
+void TestGun::loadParams(const TiXmlElement* root)
+{
+  Weapon::loadParams(root);
+
+}
+
+
+/**
+ *  this activates the weapon
+
+   This is needed, since there can be more than one weapon on a ship. the
+   activation can be connected with an animation. for example the weapon is
+   been armed out.
+*/
+void TestGun::activate()
+{
+}
+
+
+/**
+ *  this deactivates the weapon
+
+   This is needed, since there can be more than one weapon on a ship. the
+   activation can be connected with an animation. for example the weapon is
+   been armed out.
+*/
+void TestGun::deactivate()
+{
+}
+
+
+/**
+ *  fires the weapon
+
+   this is called from the player.cc, when fire-button is been pushed
+   @todo: the ObjectManager deliveres Projectiles not TestBullets! this should be diffrent
+*/
+void TestGun::fire()
+{
+  Projectile* pj =  this->getProjectile();
+  if (pj == NULL)
+    return;
+
+  pj->setParent(PNode::getNullParent());
+
+  pj->setVelocity(this->getAbsDir().apply(Vector(1,0,0))*250 + VECTOR_RAND(5));
+
+  pj->setAbsCoor(this->getEmissionPoint());
+  pj->setAbsDir(this->getAbsDir());
+  pj->activate();
+}
+
+/**
+ *  is called, when the weapon is destroyed
+ *
+ * this is in conjunction with the hit function, so when a weapon is able to get
+ * hit, it can also be destoryed.
+*/
+void TestGun::destroy ()
+{}
+
+/**
+ *  this will draw the weapon
+*/
+void TestGun::draw () const
+{
+  /* draw gun body */
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+
+  Vector tmpRot = this->getAbsDir().getSpacialAxis();
+  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+
+  if( this->leftRight == W_RIGHT)
+    glScalef(1.0, 1.0, -1.0);
+  static_cast<StaticModel*>(this->getModel())->draw(1);
+  glPopMatrix();
+
+  /* draw objectComponent1: gun coil - animated stuff */
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  glTranslatef (this->objectComponent1->getAbsCoor ().x,
+                this->objectComponent1->getAbsCoor ().y,
+                this->objectComponent1->getAbsCoor ().z);
+  tmpRot = this->objectComponent1->getAbsDir().getSpacialAxis();
+  glRotatef (this->objectComponent1->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+  static_cast<StaticModel*>(this->getModel())->draw(0);
+  glPopMatrix();
+}
+
Index: branches/network/src/world_entities/weapons/test_gun.h
===================================================================
--- branches/network/src/world_entities/weapons/test_gun.h	(revision 6636)
+++ branches/network/src/world_entities/weapons/test_gun.h	(revision 6636)
@@ -0,0 +1,60 @@
+/*!
+    @file weapon.h
+  *  a weapon that a player can use
+
+    A Player has a list of weapons, that can be choosen to shoot projectiles
+    (projectiles.{cc,h}) at enemies. These weapons can be shooted sequentially
+    or (if able) combined. Therefore you can choose the weapon mode = choose
+    a weapon.
+
+    A weapon is characterized by:
+     o firing-rate: the initial firing rate of a weapon (1/s = Herz)
+     o slowdown-factor: this is a factor d: exp(-d*x), d is element of all positive R. it determines how fast the firing-rate will slow down. if no slowdown: d=0, the bigger d is, the faster the weapon will slow down!
+     o energy-consumption: this determines the energy that has to be used to produce this projectile = costs per projectile
+
+    Furthermore there are some other attributes, that will help to represent a firing
+    weapon in this world:
+     o sound file/ressource: this is a pointer to the sound-file/ressource. however it may be represented
+     o shooting animation
+
+*/
+
+
+#ifndef _TEST_GUN_H
+#define _TEST_GUN_H
+
+#include "weapon.h"
+
+
+//! a weapon can be left or right sided
+/**
+ * @todo this will be reset with mirror X/Y/Z
+ */
+#define    W_LEFT        0
+#define    W_RIGHT       1
+
+
+class TestGun : public Weapon
+  {
+  public:
+    TestGun (int leftRight);
+    TestGun (const TiXmlElement* root);
+    virtual ~TestGun ();
+
+    void init();
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void fire();
+    virtual void destroy();
+
+    virtual void draw() const;
+
+  private:
+    PNode* objectComponent1;         //<! the gun is made of multiple parts, these PNodes represent their location and orientation
+
+    int leftRight;   // this will become an enum
+  };
+#endif /* _TEST_GUN_H */
Index: branches/network/src/world_entities/weapons/turret.cc
===================================================================
--- branches/network/src/world_entities/weapons/turret.cc	(revision 6636)
+++ branches/network/src/world_entities/weapons/turret.cc	(revision 6636)
@@ -0,0 +1,149 @@
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific
+   main-programmer: Benjamin Grauer
+   co-programmer:
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "turret.h"
+
+#include "weapon_manager.h"
+#include "world_entities/projectiles/projectile.h"
+
+#include "model.h"
+
+#include "state.h"
+#include "animation3d.h"
+
+#include "factory.h"
+
+CREATE_FACTORY(Turret, CL_TURRET);
+
+using namespace std;
+
+/**
+ *  standard constructor
+ *
+ * creates a new Turret
+ */
+Turret::Turret ()
+  : Weapon()
+{
+  this->init();
+
+  this->setActionSound(WA_SHOOT, "sound/shot1.wav");
+  this->setActionSound(WA_ACTIVATE, "sound/vocals/missiles.wav");
+  this->setActionSound(WA_RELOAD, "sound/vocals/reload.wav");
+
+}
+
+/**
+ * creates a new Turret from a TiXmlElement
+ */
+Turret::Turret(const TiXmlElement* root)
+{
+  this->init();
+  if (root != NULL)
+    this->loadParams(root);
+}
+
+/**
+ *  standard deconstructor
+*/
+Turret::~Turret ()
+{
+  // model will be deleted from WorldEntity-destructor
+}
+
+void Turret::init()
+{
+  this->setClassID(CL_TURRET, "Turret");
+
+
+  Animation3D* animation1 = this->getAnimation(WS_ACTIVATING, this);
+  Animation3D* animation2 = this->getAnimation(WS_DEACTIVATING, this);
+
+  animation1->addKeyFrame(Vector(0, -.5, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+  animation1->addKeyFrame(Vector(0, 0, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+  animation2->addKeyFrame(Vector(0, 0, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+  animation2->addKeyFrame(Vector(0, -.5, 0), Quaternion(), 0.3, ANIM_LINEAR, ANIM_CONSTANT);
+
+  animation1->setInfinity(ANIM_INF_CONSTANT);
+  animation2->setInfinity(ANIM_INF_CONSTANT);
+
+  this->setStateDuration(WS_SHOOTING, .1);
+  this->setStateDuration(WS_RELOADING, 1.0f);
+  this->setStateDuration(WS_ACTIVATING, .4);
+  this->setStateDuration(WS_DEACTIVATING, .4);
+
+  this->setMaximumEnergy(100, 5);
+  this->increaseEnergy(100);
+  //this->minCharge = 2;
+
+  this->setCapability(WTYPE_ALLDIRS | WTYPE_TURRET);
+  this->setProjectileType(CL_ROCKET);
+
+  this->loadModel("models/guns/turret1.obj");
+
+  this->setEmissionPoint(1.684, 0.472, 0);
+  //this->getProjectileFactory()->prepare(100);
+  this->loadModel("models/guns/turret1.obj");
+
+}
+
+void Turret::loadParams(const TiXmlElement* root)
+{
+  Weapon::loadParams(root);
+}
+
+void Turret::activate()
+{
+}
+
+void Turret::deactivate()
+{
+}
+
+void Turret::tick(float dt)
+{
+/*
+  Quaternion quat;
+  Vector direction = this->getAbsCoor();/*this->getWeaponManager()->getFixedTarget()->getAbsCoor() - this->getAbsCoor();
+
+  direction.normalize();
+
+  if (likely (this->getParent() != NULL))
+    quat = Quaternion(direction, this->getParent()->getAbsDir().apply(Vector(0,1,0))) * Quaternion ( -M_PI_2, Vector(0,1,0)) ;
+  else
+    quat = Quaternion(direction, Vector(0,1,0)) * Quaternion ( -M_PI_2, Vector(0,1,0)) ;
+
+  this->setAbsDirSoft(quat, 5);*/
+}
+
+void Turret::fire()
+{
+  Projectile* pj = this->getProjectile();
+  if (pj == NULL)
+    return;
+
+  pj->setVelocity(this->getVelocity()+(this->getAbsDir().apply(Vector(1,0,0))*100.0 /*+ VECTOR_RAND(13) */
+            /*target->getAbsCoor() - this->getAbsCoor()*/)*.5);//this->getVelocity());
+
+
+  pj->setParent(PNode::getNullParent());
+  pj->setAbsCoor(this->getEmissionPoint());
+  pj->setAbsDir(this->getAbsDir());
+  pj->activate();
+}
+
+void Turret::destroy ()
+{}
Index: branches/network/src/world_entities/weapons/turret.h
===================================================================
--- branches/network/src/world_entities/weapons/turret.h	(revision 6636)
+++ branches/network/src/world_entities/weapons/turret.h	(revision 6636)
@@ -0,0 +1,32 @@
+/*!
+ * @file turret.h
+*/
+
+
+#ifndef _TURRET_H
+#define _TURRET_H
+
+#include "weapon.h"
+
+class Turret : public Weapon
+  {
+  public:
+    Turret ();
+    Turret(const TiXmlElement* root);
+    virtual ~Turret ();
+
+    void init();
+    virtual void loadParams(const TiXmlElement* root);
+
+    virtual void activate();
+    virtual void deactivate();
+
+    virtual void tick(float dt);
+    virtual void fire();
+    virtual void destroy();
+
+
+  private:
+  };
+
+#endif /* _TURRET_H */
Index: branches/network/src/world_entities/weapons/weapon.cc
===================================================================
--- branches/network/src/world_entities/weapons/weapon.cc	(revision 6636)
+++ branches/network/src/world_entities/weapons/weapon.cc	(revision 6636)
@@ -0,0 +1,750 @@
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer: Benjamin Grauer
+
+   2005-07-15: Benjamin Grauer: restructurating the entire Class
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "weapon.h"
+
+#include "fast_factory.h"
+#include "world_entities/projectiles/projectile.h"
+
+#include "resource_manager.h"
+#include "class_list.h"
+#include "load_param.h"
+#include "state.h"
+#include "animation3d.h"
+#include "vector.h"
+
+#include "sound_source.h"
+#include "sound_buffer.h"
+
+#include "glgui_bar.h"
+
+////////////////////
+// INITAILISATION //
+// SETTING VALUES //
+////////////////////
+/**
+ * standard constructor
+ *
+ * creates a new weapon
+*/
+Weapon::Weapon ()
+{
+  this->init();
+}
+
+/**
+ * standard deconstructor
+*/
+Weapon::~Weapon ()
+{
+  for (int i = 0; i < WS_STATE_COUNT; i++)
+    if (this->animation[i] && ClassList::exists(animation[i], CL_ANIMATION))  //!< @todo this should check animation3D
+      delete this->animation[i];
+  for (int i = 0; i < WA_ACTION_COUNT; i++)
+    if (this->soundBuffers[i] != NULL && ClassList::exists(this->soundBuffers[i], CL_SOUND_BUFFER))
+      ResourceManager::getInstance()->unload(this->soundBuffers[i]);
+
+  if (ClassList::exists(this->soundSource, CL_SOUND_SOURCE))
+    delete this->soundSource;
+}
+
+/**
+ * initializes the Weapon with ALL default values
+ *
+ * This Sets the default values of the Weapon
+ */
+void Weapon::init()
+{
+  this->currentState     = WS_INACTIVE;            //< Normaly the Weapon is Inactive
+  this->requestedAction  = WA_NONE;                //< No action is requested by default
+  this->stateDuration    = 0.0;                    //< All the States have zero duration
+  for (int i = 0; i < WS_STATE_COUNT; i++)         //< Every State has:
+  {
+    this->times[i] = 0.0;                        //< An infinitesimal duration
+    this->animation[i] = NULL;                   //< No animation
+  }
+  for (int i = 0; i < WA_ACTION_COUNT; i++)
+    this->soundBuffers[i] = NULL;                  //< No Sounds
+
+  this->soundSource = new SoundSource(this);       //< Every Weapon has exacty one SoundSource.
+  this->emissionPoint.setParent(this);             //< One EmissionPoint, that is a PNode connected to the weapon. You can set this to the exitting point of the Projectiles
+
+  this->projectile = CL_NULL;                      //< No Projectile Class is Connected to this weapon
+  this->projectileFactory = NULL;                  //< No Factory generating Projectiles is selected.
+
+  this->hideInactive = true;                       //< The Weapon will be hidden if it is inactive (by default)
+
+  this->minCharge = 1.0;                           //< The minimum charge the Weapon can hold is 1 unit.
+  this->maxCharge = 1.0;                           //< The maximum charge is also one unit.
+
+  this->energyLoaded = .0;                         //< How much energy is loaded in the Gun. (Weapons must be charged befor usage)
+  this->energyLoadedMax = 5.0;                     //< Each Weapon has a Maximum energy that can be charged onto it
+  this->energy = .0;                               //< The secondary Buffer (before we have to reload)
+  this->energyMax = 10.0;                          //< How much energy can be carried
+  this->capability = WTYPE_ALL;                    //< The Weapon has all capabilities @see W_Capability.
+
+  this->energyWidget = NULL;
+  this->energyLoadedWidget = NULL;
+}
+
+/**
+ * loads the Parameters of a Weapon
+ * @param root the XML-Element to load the Weapons settings from
+ */
+void Weapon::loadParams(const TiXmlElement* root)
+{
+  WorldEntity::loadParams(root);
+
+  LoadParam(root, "projectile", this, Weapon, setProjectileType)
+  .describe("Sets the name of the Projectile to load onto the Entity");
+
+  LoadParam(root, "emission-point", this, Weapon, setEmissionPoint)
+  .describe("Sets the Point of emission of this weapon");
+
+  LoadParam(root, "state-duration", this, Weapon, setStateDuration)
+  .describe("Sets the duration of a given state (1: state-Name; 2: duration in seconds)");
+
+  LoadParam(root, "action-sound", this, Weapon, setActionSound)
+  .describe("Sets a given sound to an action (1: action-Name; 2: name of the sound (relative to the Data-Path))");
+}
+
+/**
+ * sets the Projectile to use for this weapon.
+ * @param projectile The ID of the Projectile to use
+ * @returns true, if it was sucessfull, false on error
+ *
+ * be aware, that this function does not create Factories, as this is job of Projecitle/Bullet-classes.
+ * What it does, is telling the Weapon what Projectiles it can Emit.
+ */
+void Weapon::setProjectileType(ClassID projectile)
+{
+  if (projectile == CL_NULL)
+    return;
+  this->projectile = projectile;
+  this->projectileFactory = FastFactory::searchFastFactory(projectile);
+  if (this->projectileFactory == NULL)
+  {
+    PRINTF(1)("unable to find FastFactory for the Projectile.\n");
+    return;
+  }
+  else
+  {
+    // grabbing Parameters from the Projectile to have them at hand here.
+    Projectile* pj = dynamic_cast<Projectile*>(this->projectileFactory->resurrect());
+    this->minCharge = pj->getMinEnergy();
+    this->maxCharge = pj->getMaxEnergy();
+    this->chargeable = pj->isChageable();
+    this->projectileFactory->kill(pj);
+  }
+}
+
+/**
+ * @see bool Weapon::setProjectile(ClassID projectile)
+ * @param projectile the Name of the Projectile.
+ */
+void Weapon::setProjectileType(const char* projectile)
+{
+  if (projectile == NULL)
+    return;
+  FastFactory* tmpFac = FastFactory::searchFastFactory(projectile);
+  if (tmpFac != NULL)
+  {
+    this->setProjectileType(tmpFac->getStoredID());
+  }
+  else
+  {
+    PRINTF(1)("Projectile %s does not exist for weapon %s\n", projectile, this->getName());
+  }
+}
+
+/**
+ * prepares Projectiles of the Weapon
+ * @param count how many Projectiles to create (they will be stored in the ProjectileFactory)
+ */
+void Weapon::prepareProjectiles(unsigned int count)
+{
+  if (likely(this->projectileFactory != NULL))
+    projectileFactory->prepare(count);
+  else
+    PRINTF(2)("unable to create %d projectile for Weapon %s (%s)\n", count, this->getName(), this->getClassName());
+}
+
+/**
+ * resurects and returns a Projectile
+ * @returns a Projectile on success, NULL on error
+ *
+ * errors: 1. (ProjectileFastFactory not Found)
+ *         2. No more Projectiles availiable.
+ */
+Projectile* Weapon::getProjectile()
+{
+  if (likely (this->projectileFactory != NULL))
+  {
+    Projectile* pj = dynamic_cast<Projectile*>(this->projectileFactory->resurrect());
+    pj->toList((OM_LIST)(this->getOMListNumber()+1));
+    return pj;
+  }
+  else
+  {
+    PRINTF(2)("No projectile defined for Weapon %s(%s) can't return any\n", this->getName(), this->getClassName());
+    return NULL;
+  }
+}
+
+
+/**
+ * sets the emissionPoint's relative position from the Weapon
+ * @param point the Point relative to the mass-point of the Weapon
+ */
+void Weapon::setEmissionPoint(const Vector& point)
+{
+  this->emissionPoint.setRelCoor(point);
+}
+
+/**
+ * assigns a Sound-file to an action
+ * @param action the action the sound should be assigned too
+ * @param soundFile the soundFile's relative position to the data-directory (will be looked for by the ResourceManager)
+ */
+void Weapon::setActionSound(WeaponAction action, const char* soundFile)
+{
+  if (action >= WA_ACTION_COUNT)
+    return;
+  if (this->soundBuffers[action] != NULL)
+    ResourceManager::getInstance()->unload(this->soundBuffers[action]);
+
+  else if (soundFile != NULL)
+  {
+    this->soundBuffers[action] = (SoundBuffer*)ResourceManager::getInstance()->load(soundFile, WAV);
+    if (this->soundBuffers[action] != NULL)
+    {
+      PRINTF(4)("Loaded sound %s to action %s.\n", soundFile, actionToChar(action));
+    }
+    else
+    {
+      PRINTF(2)("Failed to load sound %s to %s.\n.", soundFile, actionToChar(action));
+    }
+  }
+  else
+    this->soundBuffers[action] = NULL;
+}
+
+/**
+ * creates/returns an Animation3D for a certain State.
+ * @param state what State should the Animation be created/returned for
+ * @param node the node this Animation should apply to. (NULL is fine if the animation was already created)
+ * @returns The created animation.Animation(), NULL on error (or if the animation does not yet exist).
+ *
+ * This function does only generate the Animation Object, and if set it will
+ * automatically be executed, when a certain State is reached.
+ * What this does not do, is set keyframes, you have to operate on the returned animation.
+ */
+Animation3D* Weapon::getAnimation(WeaponState state, PNode* node)
+{
+  if (state >= WS_STATE_COUNT) // if the state is not known
+    return NULL;
+
+  if (unlikely(this->animation[state] == NULL)) // if the animation does not exist yet create it.
+  {
+    if (likely(node != NULL))
+      return this->animation[state] = new Animation3D(node);
+    else
+    {
+      PRINTF(2)("Node not defined for the Creation of the 3D-animation of state %s\n", stateToChar(state));
+      return NULL;
+    }
+  }
+  else
+    return this->animation[state];
+}
+
+GLGuiWidget* Weapon::getEnergyWidget()
+{
+  if (this->energyWidget == NULL)
+  {
+    this->energyWidget = new GLGuiBar;
+    this->energyWidget->setSize2D( 20, 100);
+    this->energyWidget->setMaximum(this->getEnergyMax());
+    this->energyWidget->setValue(this->getEnergy());
+  }
+  return this->energyWidget;
+}
+
+
+GLGuiWidget* Weapon::getLoadedEnergyWidget()
+{
+  if (this->energyLoadedWidget == NULL)
+  {
+    this->energyLoadedWidget = new GLGuiBar;
+    //this->energyLoadedWidget->setParent2D(this->bar);
+    this->energyLoadedWidget->setRelCoor2D(20,0);
+    this->energyLoadedWidget->setSize2D(10,50);
+    this->energyLoadedWidget->setMaximum(this->getLoadedEnergyMax());
+  }
+  return this->energyLoadedWidget;
+}
+
+void Weapon::updateWidgets()
+{
+  if (this->energyWidget != NULL)
+  {
+    this->energyWidget->setMaximum(this->energyMax);
+    this->energyWidget->setValue(this->energy);
+  }
+  if (this->energyLoadedWidget != NULL)
+  {
+    this->energyLoadedWidget->setMaximum(this->energyLoadedMax);
+    this->energyLoadedWidget->setValue(this->energyLoaded);
+  }
+}
+
+/////////////////
+//  EXECUTION  //
+// GAME ACTION //
+/////////////////
+/**
+ * request an action that should be executed,
+ * @param action the next action to take
+ *
+ * This function must be called instead of the actions (like fire/reload...)
+ * to make all the checks needed to have a usefull WeaponSystem.
+ */
+void Weapon::requestAction(WeaponAction action)
+{
+  if (likely(this->isActive()))
+  {
+    if (this->requestedAction != WA_NONE)
+      return;
+    PRINTF(5)("next action will be %s in %f seconds\n", actionToChar(action), this->stateDuration);
+    this->requestedAction = action;
+  }
+  //else
+  else if (unlikely(action == WA_ACTIVATE))
+  {
+    this->currentState = WS_ACTIVATING;
+    this->requestedAction = WA_ACTIVATE;
+  }
+}
+
+/**
+ * adds energy to the Weapon
+ * @param energyToAdd The amount of energy
+ * @returns the amount of energy we did not pick up, because the weapon is already full
+ */
+float Weapon::increaseEnergy(float energyToAdd)
+{
+  float maxAddEnergy = this->energyMax - this->energy;
+
+  if (maxAddEnergy >= energyToAdd)
+  {
+    this->energy += energyToAdd;
+    return 0.0;
+  }
+  else
+  {
+    this->energy += maxAddEnergy;
+    return energyToAdd - maxAddEnergy;
+  }
+}
+
+////////////////////////////////////////////////////////////
+// WEAPON INTERNALS                                       //
+// These are functions, that no other Weapon should over- //
+// write. No class has direct Access to them, as it is    //
+// quite a complicated process, handling a Weapon from    //
+// the outside                                            //
+////////////////////////////////////////////////////////////
+/**
+ * executes an action, and with it starts a new State.
+ * @return true, if it worked, false otherwise
+ *
+ * This function checks, wheter the possibility of executing an action is valid,
+ * and does all the necessary stuff, to execute them. If an action does not succeed,
+ * it tries to go around it. (ex. shoot->noAmo->reload()->wait until shoot comes again)
+ */
+bool Weapon::execute()
+{
+#if DEBUG > 4
+  PRINTF(4)("trying to execute action %s\n", actionToChar(this->requestedAction));
+  this->debug();
+#endif
+
+  WeaponAction action = this->requestedAction;
+  this->requestedAction = WA_NONE;
+
+  switch (action)
+  {
+    case WA_SHOOT:
+      return this->fireW();
+      break;
+    case WA_CHARGE:
+      return this->chargeW();
+      break;
+    case WA_RELOAD:
+      return this->reloadW();
+      break;
+    case WA_DEACTIVATE:
+      return this->deactivateW();
+      break;
+    case WA_ACTIVATE:
+      return this->activateW();
+      break;
+  }
+}
+
+/**
+ * checks and activates the Weapon.
+ * @return true on success.
+ */
+bool Weapon::activateW()
+{
+  //  if (this->currentState == WS_INACTIVE)
+  {
+    // play Sound
+    if (likely(this->soundBuffers[WA_ACTIVATE] != NULL))
+      this->soundSource->play(this->soundBuffers[WA_ACTIVATE]);
+    this->updateWidgets();
+    // activate
+    PRINTF(4)("Activating the Weapon %s\n", this->getName());
+    this->activate();
+    // setting up for next action
+    this->enterState(WS_ACTIVATING);
+  }
+}
+
+/**
+ * checks and deactivates the Weapon
+ * @return true on success.
+ */
+bool Weapon::deactivateW()
+{
+  //  if (this->currentState != WS_INACTIVE)
+  {
+    PRINTF(4)("Deactivating the Weapon %s\n", this->getName());
+    // play Sound
+    if (this->soundBuffers[WA_DEACTIVATE] != NULL)
+      this->soundSource->play(this->soundBuffers[WA_DEACTIVATE]);
+    // deactivate
+    this->deactivate();
+    this->enterState(WS_DEACTIVATING);
+  }
+}
+
+/**
+ * checks and charges the Weapon
+ * @return true on success.
+ */
+bool Weapon::chargeW()
+{
+  if ( this->currentState != WS_INACTIVE && this->energyLoaded >= this->minCharge)
+  {
+    // playing Sound
+    if (this->soundBuffers[WA_CHARGE] != NULL)
+      this->soundSource->play(this->soundBuffers[WA_CHARGE]);
+
+    // charge
+    this->charge();
+    // setting up for the next state
+    this->enterState(WS_CHARGING);
+  }
+  else // deactivate the Weapon if we do not have enough energy
+  {
+    this->requestAction(WA_RELOAD);
+  }
+}
+
+/**
+ * checks and fires the Weapon
+ * @return true on success.
+ */
+bool Weapon::fireW()
+{
+  //if (likely(this->currentState != WS_INACTIVE))
+  if (this->minCharge <= this->energyLoaded)
+  {
+    // playing Sound
+    if (this->soundBuffers[WA_SHOOT] != NULL)
+      this->soundSource->play(this->soundBuffers[WA_SHOOT]);
+    this->updateWidgets();
+    // fire
+    this->energyLoaded -= this->minCharge;
+    this->fire();
+    // setting up for the next state
+    this->enterState(WS_SHOOTING);
+  }
+  else  // reload if we still have the charge
+  {
+    this->requestAction(WA_RELOAD);
+    this->execute();
+  }
+}
+
+/**
+ * checks and Reloads the Weapon
+ * @return true on success.
+ */
+bool Weapon::reloadW()
+{
+  PRINTF(4)("Reloading Weapon %s\n", this->getName());
+  if (unlikely(this->energy + this->energyLoaded < this->minCharge))
+  {
+    this->requestAction(WA_DEACTIVATE);
+    this->execute();
+    return false;
+  }
+
+  float chargeSize = this->energyLoadedMax - this->energyLoaded;       //!< The energy to be charged
+
+  if (this->soundBuffers[WA_RELOAD] != NULL)
+    this->soundSource->play(this->soundBuffers[WA_RELOAD]);
+
+  if (chargeSize > this->energy)
+  {
+    this->energyLoaded += this->energy;
+    this->energy = 0.0;
+    PRINT(5)("Energy depleted\n");
+  }
+  else
+  {
+    PRINTF(5)("Loaded %f energy into the Guns Buffer\n", chargeSize);
+    this->energyLoaded += chargeSize;
+    this->energy -= chargeSize;
+  }
+
+  this->updateWidgets();
+  this->reload();
+  this->enterState(WS_RELOADING);
+}
+
+/**
+ * enters the requested State, plays back animations updates the timing.
+ * @param state the state to enter.
+ */
+inline void Weapon::enterState(WeaponState state)
+{
+  PRINTF(4)("ENTERING STATE %s\n", stateToChar(state));
+  // playing animation if availiable
+  if (likely(this->animation[state] != NULL))
+    this->animation[state]->replay();
+
+  this->stateDuration = this->times[state] + this->stateDuration;
+  this->currentState = state;
+}
+
+///////////////////
+//  WORLD-ENTITY //
+// FUNCTIONALITY //
+///////////////////
+/**
+ * tick signal for time dependent/driven stuff
+*/
+void Weapon::tickW(float dt)
+{
+  //printf("%s ", stateToChar(this->currentState));
+
+  // setting up the timing properties
+  this->stateDuration -= dt;
+
+  if (this->stateDuration <= 0.0)
+  {
+    if (unlikely (this->currentState == WS_DEACTIVATING))
+    {
+      this->currentState = WS_INACTIVE;
+      return;
+    }
+    else
+      this->currentState = WS_IDLE;
+
+    if (this->requestedAction != WA_NONE)
+    {
+      this->stateDuration = -dt;
+      this->execute();
+    }
+  }
+  tick(dt);
+}
+
+
+
+
+//////////////////////
+// HELPER FUNCTIONS //
+//////////////////////
+/**
+ * checks wether all the Weapons functions are valid, and if it is possible to go to action with it.
+ * @todo IMPLEMENT the Weapons Check
+ */
+bool Weapon::check() const
+{
+  bool retVal = true;
+
+  //  if (this->projectile == NULL)
+  {
+    PRINTF(1)("There was no projectile assigned to the Weapon.\n");
+    retVal = false;
+  }
+
+
+
+
+  return retVal;
+}
+
+/**
+ * some nice debugging information about this Weapon
+ */
+void Weapon::debug() const
+{
+  PRINT(0)("Weapon-Debug %s, state: %s (duration: %fs), nextAction: %s\n", this->getName(), Weapon::stateToChar(this->currentState), this->stateDuration, Weapon::actionToChar(requestedAction));
+  PRINT(0)("Energy: max: %f; current: %f;  loadedMax: %f; loadedCurrent: %f; chargeMin: %f, chargeMax %f\n",
+           this->energyMax, this->energy, this->energyLoadedMax, this->energyLoaded, this->minCharge, this->maxCharge);
+
+
+}
+
+////////////////////////////////////////////////////////
+// static Definitions (transormators for readability) //
+////////////////////////////////////////////////////////
+/**
+ * Converts a String into an Action.
+ * @param action the String input holding the Action.
+ * @return The Action if known, WA_NONE otherwise.
+ */
+WeaponAction Weapon::charToAction(const char* action)
+{
+  if (!strcmp(action, "none"))
+    return WA_NONE;
+  else if (!strcmp(action, "shoot"))
+    return WA_SHOOT;
+  else if (!strcmp(action, "charge"))
+    return WA_CHARGE;
+  else if (!strcmp(action, "reload"))
+    return WA_RELOAD;
+  else if (!strcmp(action, "acitvate"))
+    return WA_ACTIVATE;
+  else if (!strcmp(action, "deactivate"))
+    return WA_DEACTIVATE;
+  else if (!strcmp(action, "special1"))
+    return WA_SPECIAL1;
+  else
+  {
+    PRINTF(2)("action %s could not be identified.\n", action);
+    return WA_NONE;
+  }
+}
+
+/**
+ * converts an action into a String
+ * @param action the action to convert
+ * @return a String matching the name of the action
+ */
+const char* Weapon::actionToChar(WeaponAction action)
+{
+  switch (action)
+  {
+    case WA_SHOOT:
+      return "shoot";
+      break;
+    case WA_CHARGE:
+      return "charge";
+      break;
+    case WA_RELOAD:
+      return "reload";
+      break;
+    case WA_ACTIVATE:
+      return "activate";
+      break;
+    case WA_DEACTIVATE:
+      return "deactivate";
+      break;
+    case WA_SPECIAL1:
+      return "special1";
+      break;
+    default:
+      return "none";
+      break;
+  }
+}
+
+/**
+ * Converts a String into a State.
+ * @param state the String input holding the State.
+ * @return The State if known, WS_NONE otherwise.
+ */
+WeaponState Weapon::charToState(const char* state)
+{
+  if (!strcmp(state, "none"))
+    return WS_NONE;
+  else if (!strcmp(state, "shooting"))
+    return WS_SHOOTING;
+  else if (!strcmp(state, "charging"))
+    return WS_CHARGING;
+  else if (!strcmp(state, "reloading"))
+    return WS_RELOADING;
+  else if (!strcmp(state, "activating"))
+    return WS_ACTIVATING;
+  else if (!strcmp(state, "deactivating"))
+    return WS_DEACTIVATING;
+  else if (!strcmp(state, "inactive"))
+    return WS_INACTIVE;
+  else if (!strcmp(state, "idle"))
+    return WS_IDLE;
+  else
+  {
+    PRINTF(2)("state %s could not be identified.\n", state);
+    return WS_NONE;
+  }
+}
+
+/**
+ * converts a State into a String
+ * @param state the state to convert
+ * @return a String matching the name of the state
+ */
+const char* Weapon::stateToChar(WeaponState state)
+{
+  switch (state)
+  {
+    case WS_SHOOTING:
+      return "shooting";
+      break;
+    case WS_CHARGING:
+      return "charging";
+      break;
+    case WS_RELOADING:
+      return "reloading";
+      break;
+    case WS_ACTIVATING:
+      return "activating";
+      break;
+    case WS_DEACTIVATING:
+      return "deactivating";
+      break;
+    case WS_IDLE:
+      return "idle";
+      break;
+    case WS_INACTIVE:
+      return "inactive";
+      break;
+    default:
+      return "none";
+      break;
+  }
+}
Index: branches/network/src/world_entities/weapons/weapon.h
===================================================================
--- branches/network/src/world_entities/weapons/weapon.h	(revision 6636)
+++ branches/network/src/world_entities/weapons/weapon.h	(revision 6636)
@@ -0,0 +1,232 @@
+/*!
+ * @file weapon.h
+ *
+ * Weapon is the mayor baseclass for all weapons. it is quite extensive, and expensive in use,
+ * because each weapon will know virutal functions for the WorldEntity's part, and also virtuals
+ * for Fireing/Reloading/...,
+ * quickly said: Weapon is a wrapper for weapons, that makes it easy to very quickly implement
+ * new Weapons, and with them make this game better, than any game before it, because still
+ * Weapons (GUNS) are the most important thing in life :?... no to be serious
+ * @see Weapon
+ */
+
+
+#ifndef _WEAPON_H
+#define _WEAPON_H
+
+#include "world_entity.h"
+
+// FORWARD DECLARATION
+class Projectile;
+class WeaponManager;
+class Animation3D;
+class TiXmlElement;
+class FastFactory;
+template<class T> class tFastFactory;
+class GLGuiWidget;
+
+//! An enumerator defining Actions a Weapon can take
+typedef enum {
+  WA_NONE          =    0,    //!< No Action taken
+  WA_SHOOT         =    1,    //!< emitting Shot
+  WA_CHARGE        =    2,    //!< charge action (one click before the shot)
+  WA_RELOAD        =    3,    //!< reload right after shoot is finished
+  WA_ACTIVATE      =    4,    //!< activate the GUN
+  WA_DEACTIVATE    =    5,    //!< deactivate the GUN
+  WA_SPECIAL1      =    6,    //!< Special Action taken
+
+  WA_ACTION_COUNT  =    7     //!< This must match the count of enumerations-members.
+} WeaponAction;
+
+//! An enumerator defining the States of a Weapon
+typedef enum {
+  WS_NONE          =    0,    //!< No State at all (if set, there is something wrong, or the weapon is not yet availiable)
+  WS_SHOOTING      =    1,    //!< The State of the Shooting
+  WS_CHARGING      =    2,    //!< The state of charging th weapon
+  WS_RELOADING     =    3,    //!< The State of the Reloading
+  WS_ACTIVATING    =    4,    //!< The State in which the weapon gets activated
+  WS_DEACTIVATING  =    5,    //!< The State in which the weapon gets deactivated
+  WS_INACTIVE      =    6,    //!< The State where the weapon is inactive (unable to shoot)
+  WS_IDLE          =    7,    //!< The State where the weapon is idle
+
+  WS_STATE_COUNT  =     8     //!< This must match the count of enumerations-members.
+} WeaponState;
+
+//! an enumerator defining capabilities of a WeaponSlot
+typedef enum
+{
+  WTYPE_DIRECTIONAL   = 0x00000001,           //!< Weapon is directional/Slot is able to carry directional weapons
+  WTYPE_TURRET        = 0x00000002,           //!< Weapon is a turret/slot is able to carry turrets
+  WTYPE_ALLKINDS      = 0x0000000f,           //!< Weapon is all types/Slot is able to carry all kinds of weapons
+
+  WTYPE_FORWARD       = 0x00000010,           //!< Weapon fires forwards/Slot is able to carry weapons firing forwards
+  WTYPE_BACKWARD      = 0x00000020,           //!< Weapon fires backwards/Slot is able to carry weapons firing backwards
+  WTYPE_LEFT          = 0x00000040,           //!< Weapon fires to the left/Slot is able to carry weapons firing to the left
+  WTYPE_RIGHT         = 0x00000080,           //!< Weapon fires to the right/Slot is able to carry weapons firing to the right
+  WTYPE_ALLDIRS       = 0x000000f0,           //!< Weapon has no specific firing direction/Slot can fire into all directions
+
+  WTYPE_ALL           = 0x000000ff,           //!< Weapon has no limitations/Slot can handle all kinds of Weapon.
+} W_Capability;
+
+//! An abstract class, that describes weapons
+/**
+ * This is used as a container for all the different kinds of weapons that may exist
+ *
+ * Weapons have certain states, and actions, that can inflict them.
+ * ex. Action WA_SHOOT leeds to State WS_SHOOTING.
+ * each action has a sound connected to it,
+ * each state a time and an animation.
+ */
+class Weapon : public WorldEntity
+{
+  public:
+    // INITIALISATION //
+    Weapon ();
+    virtual ~Weapon ();
+
+    void init();
+    virtual void loadParams(const TiXmlElement* root);
+    ////////////////////
+
+    // INTERACTIVITY //
+    void requestAction(WeaponAction action);
+    float increaseEnergy(float energyToAdd);
+    ///////////////////
+
+    /** @returns true if the Weapon is Active  (this is used to check if the weapon must be drawn)*/
+    inline bool isActive() const { return (this->currentState == WS_INACTIVE)? false : true; };
+    /** @returns true if the weapon must be drawn */
+    inline bool isVisible() const { return (this->currentState != WS_INACTIVE || !this->hideInactive) ? true : false; };
+    /** @returns true if the Weapon is chargeable */
+    inline bool isChargeable() const { return this->chargeable; };
+
+    // FUNCTIONS TO SET THE WEAPONS PROPERTIES.
+    /** sets the Weapons Capabilities */
+    inline void setCapability(long capabilities) { this->capability = capabilities; };
+    /** @returns the Capabilities of this Weapon */
+    inline long getCapability() { return this->capability; };
+    void setProjectileType(ClassID projectile);
+    void setProjectileType(const char* projectile);
+    /** @returns The projectile's classID */
+    inline ClassID getProjectileType() { return this->projectile; };
+    /** @returns the FastFactory, that creates Projectiles of type getProjectile */
+    inline FastFactory* getProjectileFactory() { return this->projectileFactory; };
+    void prepareProjectiles(unsigned int count);
+    Projectile* getProjectile();
+
+
+    // EMISSION
+    void setEmissionPoint(const Vector& point);
+    /** @see void setEmissionPoint(const Vector& point); */
+    inline void setEmissionPoint(float x, float y, float z) { this->setEmissionPoint(Vector(x, y, z)); };
+    /** @returns the absolute Position of the EmissionPoint */
+    inline const Vector& getEmissionPoint() const { return this->emissionPoint.getAbsCoor(); };
+
+    // STATE CHANGES //
+    /** @param state the State to time @param duration the duration of the State */
+    inline void setStateDuration(const char* state, float duration) { setStateDuration(charToState(state), duration); };
+    /** @param state the State to time @param duration the duration of the State */
+    inline void setStateDuration(WeaponState state, float duration) { /*(state < WS_STATE_COUNT)?*/this->times[state] = duration; };
+    /** @param state The state to query @returns the Time the queried State takes to complete */
+    inline float getStateDuration(WeaponState state) const { return (state < WS_STATE_COUNT)? this->times[state] : 0.0; };
+    /** @returns true if the time of the currentState is elapsed, false otherwise */
+    inline bool stateTimeElapsed() const { return (this->stateDuration > this->times[currentState])? true : false; };
+    /** @returns the current State of the Weapon */
+    inline WeaponState getCurrentState() const { return this->currentState; };
+
+    /** @param energyMax the maximum energy the Weapon can have @param energyLoadedMax the maximum energy in the weapon buffers */
+    inline void setMaximumEnergy(float energyMax, float energyLoadedMax) { this->energyMax = energyMax; this->energyLoadedMax = energyLoadedMax; };
+    inline float getLoadedEnergyMax() const { return this->energyLoadedMax; };
+    inline float getEnergyMax() const { return this->energyMax; };
+    inline float getEnergy() const { return this->energy; };
+    inline float getLoadedEnergy() const { return this->energyLoaded; };
+
+    void setActionSound(WeaponAction action, const char* soundFile);
+    /** @see void setActionSound(WeaponAction action, const char* soundFile); */
+    void setActionSound(const char* action, const char* soundFile) { this->setActionSound(charToAction(action), soundFile); };
+
+    Animation3D* getAnimation(WeaponState state, PNode* node = NULL);
+    Animation3D* copyAnimation(WeaponState from, WeaponState to);
+
+    GLGuiWidget* getEnergyWidget();
+    GLGuiWidget* getLoadedEnergyWidget();
+
+    // FLOW
+    void tickW(float dt); //!< this is a function that must be called by the weaponManager, or any other weaponHandler, all other functions are handled from within
+
+    virtual void tick(float dt) {};
+
+    bool check() const;
+    void debug() const;
+
+  protected:
+    //! ACTION: these functions are handled by the Weapon itself, and must be called by requestAction(WeaponAction);
+    virtual void activate() {};
+    virtual void deactivate() {};
+    virtual void charge() {};
+    virtual void fire() {};
+    virtual void reload() {};
+    virtual void destroy() {};
+
+
+    // utility:
+    static WeaponAction  charToAction(const char* action);
+    static const char*   actionToChar(WeaponAction action);
+    static WeaponState   charToState(const char* state);
+    static const char*   stateToChar(WeaponState state);
+
+  private:
+    /** executive functions, that handle timing with actions.
+     * This is for the action-functions in derived functions to be easy
+     * The main function is execute, that calls all the other functions
+     * for being fast, the Functions are private and as such will be inlined
+     * into the execute function. (this is work of the compiler)
+     */
+    bool execute();
+    bool activateW();
+    bool deactivateW();
+    bool chargeW();
+    bool fireW();
+    bool reloadW();
+    inline void enterState(WeaponState state);
+
+    void updateWidgets();
+
+  private:
+    // type of Weapon
+    long                 capability;                       //!< what capabilities the Weapon has @see W_Capability
+
+    // it is all about energy
+    float                energy;                           //!< The energy stored in the weapons secondary buffers (reserve)
+    float                energyLoaded;                     //!< The energy stored in the weapons primary buffers (fire without reload)
+    float                energyMax;                        //!< The maximal energy that can be stored in the secondary buffers (reserveMax)
+    float                energyLoadedMax;                  //!< The maximal energy that can be stored in the primary buffers
+    //! @todo move this to projectile
+    float                minCharge;                        //!< The minimal energy to be loaded onto one projectile if chargeable otherwise the power consumed by one projectile
+    float                maxCharge;                        //!< The maximal energy to be loaded onto one projectile (this is only availible if chargeable is enabled)
+
+    GLGuiBar*            energyWidget;
+    GLGuiBar*            energyLoadedWidget;
+
+    ////////////
+    // PHASES //
+    ////////////
+    SoundSource*         soundSource;                      //!< A SoundSource to play sound from (this is connected to the PNode of the Weapon)
+
+    WeaponState          currentState;                     //!< The State the weapon is in.
+    WeaponAction         requestedAction;                  //!< An action to try to Engage after the currentState ends.
+    float                stateDuration;                    //!< how long the state has taken until now.
+    float                times[WS_STATE_COUNT];            //!< Times to stay in the different States @see WeaponState.
+    Animation3D*         animation[WS_STATE_COUNT];        //!< Animations for all the States (you can say yourself on what part of the gun this animation acts).
+    SoundBuffer*         soundBuffers[WA_ACTION_COUNT];    //!< SoundBuffers for all actions @see WeaponAction.
+
+    PNode                emissionPoint;                   //!< The point, where the projectiles are emitted. (this is coppled with the Weapon by default)
+
+    bool                 hideInactive;                    //!< Hides the Weapon if it is inactive
+    bool                 chargeable;                      //!< if the Weapon is charcheable (if true, the weapon will charge before it fires.)
+
+    ClassID              projectile;                      //!< the projectile used for this weapon (since they should be generated via macro and the FastFactory, only the ClassID must be known.)
+    FastFactory*         projectileFactory;               //!< A factory, that produces and handles the projectiles.
+  };
+
+#endif /* _WEAPON_H */
Index: branches/network/src/world_entities/weapons/weapon_manager.cc
===================================================================
--- branches/network/src/world_entities/weapons/weapon_manager.cc	(revision 6636)
+++ branches/network/src/world_entities/weapons/weapon_manager.cc	(revision 6636)
@@ -0,0 +1,455 @@
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+### File Specific
+   main-programmer: Patrick Boenzli
+   co-programmer: Benjamin Grauer
+
+   2005-07-24: Benjamin Grauer: restructurate, so it can handle the new Weapons.
+*/
+
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WEAPON
+
+#include "weapon_manager.h"
+#include "weapon.h"
+#include "crosshair.h"
+
+#include "playable.h"
+
+#include "load_param.h"
+#include "factory.h"
+
+#include "t_animation.h"
+
+using namespace std;
+
+
+/**
+ * @brief this initializes the weaponManager for a given nnumber of weapon slots
+ * @param number of weapon slots of the model/ship <= 8 (limitied)
+ */
+WeaponManager::WeaponManager(WorldEntity* parent)
+{
+  this->init();
+  this->setParent(parent);
+}
+
+WeaponManager::WeaponManager(const TiXmlElement* root)
+{
+  this->init();
+  this->loadParams(root);
+}
+
+/**
+ * @brief Destroys a WeaponManager
+ */
+WeaponManager::~WeaponManager()
+{
+  // crosshair being a PNode it must not be deleted (this is because PNodes delete themselves.)
+  //delete this->crosshair;
+}
+
+/**
+ * @brief initializes the WeaponManager
+ */
+void WeaponManager::init()
+{
+  this->setClassID(CL_WEAPON_MANAGER, "WeaponManager");
+
+  this->parent = NULL;
+
+  for (int i = 0; i < WM_MAX_CONFIGS; i++)
+    for (int j = 0; j < WM_MAX_SLOTS; j++)
+      this->configs[i][j] = NULL;
+
+  for (int i = 0; i < WM_MAX_SLOTS; i++)
+  {
+    this->currentSlotConfig[i].capability = WTYPE_ALL;
+    this->currentSlotConfig[i].currentWeapon = NULL;
+    this->currentSlotConfig[i].nextWeapon = NULL;
+
+    // NAMING
+    char* tmpName;
+    if (this->getName())
+    {
+      tmpName = new char[strlen(this->getName()) + 10];
+      sprintf(tmpName, "%s_slot%d", this->getName(), i);
+    }
+    else
+    {
+      tmpName = new char[30];
+      sprintf(tmpName, "WeaponMan_slot%d", i);
+    }
+    this->currentSlotConfig[i].position.setName(tmpName);
+    this->currentSlotConfig[i].position.deactivateNode();
+    delete[] tmpName;
+  }
+
+  for (int i = 0; i < WM_MAX_LOADED_WEAPONS; i++)
+    this->availiableWeapons[i] = NULL;
+
+
+  this->currentConfigID = 0;
+  this->slotCount = 2;
+  this->weaponChange;
+
+  // CROSSHAIR INITIALISATION
+  this->crosshair = new Crosshair();
+
+  this->crossHairSizeAnim = new tAnimation<Crosshair>(this->crosshair, &Crosshair::setSize);
+  this->crossHairSizeAnim->setInfinity(ANIM_INF_REWIND);
+  this->crossHairSizeAnim->addKeyFrame(50, .1, ANIM_LINEAR);
+  this->crossHairSizeAnim->addKeyFrame(100, .05, ANIM_LINEAR);
+  this->crossHairSizeAnim->addKeyFrame(50, .01, ANIM_LINEAR);
+}
+
+/**
+ * loads the settings of the WeaponManager
+ * @param root the XML-element to load from
+ */
+void WeaponManager::loadParams(const TiXmlElement* root)
+{
+  BaseObject::loadParams(root);
+
+  LoadParam(root, "slot-count", this, WeaponManager, setSlotCount)
+      .describe("how many slots(cannons) the WeaponManager can handle");
+
+  LOAD_PARAM_START_CYCLE(root, element);
+  {
+    // CHECK IF THIS WORKS....
+    LoadParamXML_CYCLE(element, "weapons", this, WeaponManager, loadWeapons)
+        .describe("loads Weapons");
+  }
+  LOAD_PARAM_END_CYCLE(element);
+}
+
+/**
+ * loads a Weapon onto the WeaponManager
+ * @param root the XML-element to load the Weapons from
+ */
+void WeaponManager::loadWeapons(const TiXmlElement* root)
+{
+  LOAD_PARAM_START_CYCLE(root, element);
+
+  Weapon* newWeapon = dynamic_cast<Weapon*>(Factory::fabricate(element));
+  /// @todo implement this !!
+
+
+  LOAD_PARAM_END_CYCLE(element);
+}
+
+/**
+ * sets the Parent of the WeaponManager.
+ * @param parent the parent of the WeaponManager
+ *
+ * this is used, to identify to which ship/man/whatever this WeaponManager is connected.
+ * also all the Slots will be subconnected to this parent.
+ *
+ * The reason this function exists is that the WeaponManager is neither a WorldEntity nor
+ * a PNode.
+ */
+void WeaponManager::setParent(WorldEntity* parent)
+{
+  this->parent = parent;
+  if (this->parent != NULL)
+  {
+    for (int i = 0; i < WM_MAX_SLOTS; i++)
+      this->parent->addChild(&this->currentSlotConfig[i].position);
+  }
+}
+
+/**
+ * sets the number of Slots the WeaponManager has
+ * @param slotCount the number of slots
+ */
+void WeaponManager::setSlotCount(unsigned int slotCount)
+{
+  if (slotCount <= WM_MAX_SLOTS)
+    this->slotCount = slotCount;
+  else
+    this->slotCount = WM_MAX_SLOTS;
+}
+
+
+/**
+ * sets the position of the Slot relative to the parent
+ * @param slot the slot to set-up
+ * @param position the position of the given slot
+ */
+void WeaponManager::setSlotPosition(int slot, const Vector& position)
+{
+  if (slot < this->slotCount)
+    this->currentSlotConfig[slot].position.setRelCoor(position);
+}
+
+
+/**
+ * sets the relative rotation of the slot to its parent
+ * @param slot the slot to set-up
+ * @param rotation the relative rotation of the given slot
+ */
+void WeaponManager::setSlotDirection(int slot, const Quaternion& rotation)
+{
+  if (slot < this->slotCount)
+    this->currentSlotConfig[slot].position.setRelDir(rotation);
+}
+
+
+/**
+ * adds a weapon to the selected weaponconfiguration into the selected slot
+ * @param weapon the weapon to add
+ * @param configID an identifier for the slot: number between 0..7 if not specified: slotID=next free slot
+ * @param slotID an identifier for the weapon configuration, number between 0..3
+ *
+ * if you add explicitly a weapon at config:n, slot:m, the weapon placed at this location will be
+ * replaced by the weapon specified. if you use the WM_FREE_SLOT, the manager will look for a free
+ * slot in this weaponconfiguration. if there is non, the weapon won't be added and there will be
+ * a error message.
+ */
+bool WeaponManager::addWeapon(Weapon* weapon, int configID, int slotID)
+{
+  if (unlikely(configID >= WM_MAX_CONFIGS || slotID >= (int)this->slotCount))
+  {
+    PRINTF(2)("Slot %d of config %d is not availiabe (max: %d)\n", slotID, configID, this->slotCount);
+    return false;
+  }
+
+  if (this->configs[configID][slotID] != NULL && configID > 0 && slotID > 0)
+    PRINTF(3)("Weapon-slot %d/%d of %s already poulated, overwriting\n", configID, slotID, this->getName());
+
+  if (slotID == -1) // WM_FREE_SLOT
+  {
+    slotID = this->getNextFreeSlot(configID, weapon->getCapability());
+    if( slotID < 0 || slotID >= this->slotCount)
+    {
+      PRINTF(1)("There is no free slot in this WeaponConfig to dock this weapon at! Aborting\n");
+      return false;
+    }
+  }
+
+  if (!(this->currentSlotConfig[slotID].capability & weapon->getCapability() & WTYPE_ALLKINDS) &&
+        this->currentSlotConfig[slotID].capability & weapon->getCapability() & WTYPE_ALLDIRS)
+  {
+    PRINTF(2)("Unable to add Weapon with wrong capatibility to Slot %d (W:%d M:%d)\n",
+              slotID, weapon->getCapability(), this->currentSlotConfig[slotID].capability);
+    return false;
+  }
+
+  //! @todo check if the weapon is already assigned to another config in another slot
+  this->configs[configID][slotID] = weapon;
+  if (this->parent != NULL)
+  {
+    this->parent->addChild(weapon);
+  }
+  PRINTF(3)("Added a new Weapon to the WeaponManager: config %i/ slot %i\n", configID, slotID);
+  return true;
+}
+
+/**
+ * sets the capabilities of a Slot
+ * @param slot the slot to set the capability
+ * @param slotCapability the capability @see WM_SlotCapability
+ */
+void WeaponManager::setSlotCapability(int slot, long slotCapability)
+{
+  if (slot > slotCount)
+    return;
+  this->currentSlotConfig[slot].capability = slotCapability;
+}
+
+
+/**
+ * removes a Weapon from the WeaponManager
+ *
+ * !! The weapon must be inactive before you can delete it,    !!
+ * !! because it will still be deactivated (if it is selected) !!
+ */
+void WeaponManager::removeWeapon(Weapon* weapon, int configID)
+{
+  if (weapon == NULL)
+    return;
+  if (configID < 0)
+  {
+    for (int j = 0; j < WM_MAX_SLOTS; j++)
+    {
+      for (int i = 0; i < WM_MAX_CONFIGS; i++)
+      {
+        if (this->configs[i][j] == weapon)
+          this->configs[i][j] = NULL;
+      }
+      if (this->currentSlotConfig[j].currentWeapon == weapon)
+      {
+        this->currentSlotConfig[j].nextWeapon = NULL;
+      }
+    }
+  }
+}
+
+
+/**
+ * changes to the next weapon configuration
+ */
+void WeaponManager::nextWeaponConfig()
+{
+  ++this->currentConfigID;
+  if (this->currentConfigID >= WM_MAX_CONFIGS)
+    this->currentConfigID = 0;
+  this->changeWeaponConfig(this->currentConfigID);
+}
+
+/**
+ * changes to the previous configuration
+ */
+void WeaponManager::previousWeaponConfig()
+{
+  --this->currentConfigID;
+  if (this->currentConfigID < 0)
+    this->currentConfigID = WM_MAX_CONFIGS -1;
+  this->changeWeaponConfig(this->currentConfigID);
+}
+
+/**
+ * change to a desired configuration
+ * @param weaponConfig the configuration to jump to.
+ */
+void WeaponManager::changeWeaponConfig(int weaponConfig)
+{
+  this->currentConfigID = weaponConfig;
+  PRINTF(4)("Changing weapon configuration: to %i\n", this->currentConfigID);
+  for (int i = 0; i < WM_MAX_SLOTS; i++)
+  {
+    this->currentSlotConfig[i].nextWeapon = this->configs[currentConfigID][i];
+    if (this->currentSlotConfig[i].currentWeapon != this->currentSlotConfig[i].nextWeapon)
+    {
+      if (this->currentSlotConfig[i].currentWeapon != NULL)
+        (this->currentSlotConfig[i].currentWeapon->requestAction(WA_DEACTIVATE));
+      if (this->currentSlotConfig[i].nextWeapon != NULL && this->currentSlotConfig[i].nextWeapon->isActive())
+        this->currentSlotConfig[i].nextWeapon = NULL;
+    }
+  }
+}
+
+
+/**
+ * triggers fire of all weapons in the current weaponconfig
+ */
+void WeaponManager::fire()
+{
+  Weapon* firingWeapon;
+  for(int i = 0; i < this->slotCount; i++)
+  {
+    firingWeapon = this->currentSlotConfig[i].currentWeapon;
+    if( firingWeapon != NULL) firingWeapon->requestAction(WA_SHOOT);
+  }
+  this->crosshair->setRotationSpeed(500);
+  this->crossHairSizeAnim->replay();
+}
+
+
+/**
+ * triggers tick of all weapons in the current weaponconfig
+ * @param second passed since last tick
+ */
+void WeaponManager::tick(float dt)
+{
+  Weapon* tickWeapon;
+
+  // all weapons
+  for(int i = 0; i < this->slotCount; i++)
+  {
+
+    tickWeapon = this->currentSlotConfig[i].currentWeapon;
+    if (tickWeapon != this->currentSlotConfig[i].nextWeapon) // if no change occures
+    {
+      if (tickWeapon != NULL && tickWeapon->isActive())
+      {
+        tickWeapon->requestAction(WA_DEACTIVATE);
+      }
+      else
+      {
+        if (this->currentSlotConfig[i].currentWeapon != NULL)
+          this->currentSlotConfig[i].currentWeapon->toList(OM_NULL);
+        tickWeapon = this->currentSlotConfig[i].currentWeapon = this->currentSlotConfig[i].nextWeapon;
+        if (tickWeapon != NULL)
+        {
+          tickWeapon->requestAction(WA_ACTIVATE);
+          tickWeapon->setParent(&this->currentSlotConfig[i].position);
+          tickWeapon->toList(this->parent->getOMListNumber());
+          this->currentSlotConfig[i].position.activateNode();
+          if (this->parent->isA(CL_PLAYABLE))
+          {
+            dynamic_cast<Playable*>(this->parent)->weaponConfigChanged();
+          }
+        }
+        else
+          this->currentSlotConfig[i].position.deactivateNode();
+      }
+    }
+
+    if( tickWeapon != NULL && tickWeapon->isActive())
+      tickWeapon->tickW(dt);
+  }
+
+  crosshair->setRotationSpeed(5);
+}
+
+
+/**
+ * triggers draw of all weapons in the current weaponconfig
+ */
+void WeaponManager::draw() const
+{
+  Weapon* drawWeapon;
+  for (int i = 0; i < this->slotCount; i++)
+  {
+    drawWeapon = this->currentSlotConfig[i].currentWeapon;
+    if( drawWeapon != NULL && drawWeapon->isVisible())
+      drawWeapon->draw();
+  }
+}
+
+
+/**
+ * private gets the next free slot in a certain weaponconfig
+ * @param the selected weaponconfig
+ */
+int WeaponManager::getNextFreeSlot(int configID, long capability)
+{
+  for( int i = 0; i < this->slotCount; ++i)
+  {
+    if( this->configs[configID][i] == NULL &&
+        (this->currentSlotConfig[i].capability & capability & WTYPE_ALLKINDS) &&
+        (this->currentSlotConfig[i].capability & capability & WTYPE_ALLDIRS))
+      return i;
+  }
+  return -1;
+}
+
+
+
+/**
+ * outputs some nice debug information about the WeaponManager
+ */
+void WeaponManager::debug() const
+{
+  PRINT(3)("WeaponManager Debug Information\n");
+  PRINT(3)("-------------------------------\n");
+  PRINT(3)("current Config is %d\n", this->currentConfigID);
+  for (int i = 0; i < WM_MAX_CONFIGS; i++)
+  {
+    PRINT(3)("Listing Weapons in Configuration %d\n", i);
+    for (int j = 0; j < WM_MAX_SLOTS; j++)
+    {
+      if (this->configs[i][j] != NULL)
+        PRINT(3)("Slot %d loaded a %s\n", j, this->configs[i][j]->getClassName());
+    }
+  }
+}
Index: branches/network/src/world_entities/weapons/weapon_manager.h
===================================================================
--- branches/network/src/world_entities/weapons/weapon_manager.h	(revision 6636)
+++ branches/network/src/world_entities/weapons/weapon_manager.h	(revision 6636)
@@ -0,0 +1,117 @@
+/*!
+ * @file weapon_manager.h
+ * every big WorldEntity has the ability to carry many different Weapons.
+ * for this to be easy there is the WeaponManager, that handels these weapons,
+ * and changes between them.
+ *
+ *
+ *
+ * @TODO 1. WeaponManager should also handle a List of availiableWeapons.
+ */
+
+#ifndef _WEAPON_MANAGER_H
+#define _WEAPON_MANAGER_H
+
+#include "base_object.h"
+
+#include "crosshair.h"
+#include "weapon.h"
+
+// FORWARD DECLARATION
+template <class T> class tAnimation;
+
+#define    WM_MAX_SLOTS            10             //!< How many slots the WeaponManager has at its max
+#define    WM_MAX_CONFIGS          4              //!< The maximum number of predefined Configurations
+#define    WM_MAX_LOADED_WEAPONS   20             //!< The
+
+//! This is a special class, that can handle many different Weapons of a ship/man/whatever.
+/**
+ * this class is designed to interactively changeing multiple weapons (or just one),
+ * and to allow the Weapon itself to enable/disable itself.
+ *
+ * How to configure
+ * 1. set the default values.
+ * 2. define weapons. connect them to the WeaponManager's configurations (have a look at "player.cc", to see how it works)
+ * 3. go on and run :)....
+ */
+class WeaponManager : public BaseObject {
+
+  //! an enumerator defining a Slot, where a Weapon can be stored inside.
+  typedef struct
+  {
+    PNode         position;               //!< the relative Position to the position of the carrying entity. (const PNode* parent; of WeaponManager)
+    long          capability;             //!< the capabilities of the Slot @see WM_SlotCapability.
+
+    Weapon*       currentWeapon;          //!< The current weapon this slot is carrying.
+    Weapon*       nextWeapon;             //!< either NULL or the next weapon that will be set (require currentWeapon to deactivate)
+  } WM_Slot;
+
+  public:
+    WeaponManager(WorldEntity* parent);
+    WeaponManager(const TiXmlElement* root);
+    ~WeaponManager();
+
+    void init();
+    virtual void loadParams(const TiXmlElement* root);
+    void loadWeapons(const TiXmlElement* root);
+
+    void setSlotCount(unsigned int slotCount);
+    unsigned int getSlotCount() const { return this->slotCount; };
+    // setting up the WeaponManager with the following functions
+    void setSlotPosition(int slot, const Vector& position);
+    void setSlotDirection(int slot, const Quaternion& rotation);
+    /** @param slot the slot to get the relative position from @returns the relative position of the Carrier to the Slot */
+    const Vector& getSlotPosition(int slot) const { return this->currentSlotConfig[slot].position.getRelCoor(); };
+    void setSlotCapability(int slot, long slotCapability);
+    /** @param slot the slot to get the capabilities from @returns the capabilies */
+    long getSlotCapability(int slot) const { return this->currentSlotConfig[slot].capability; };
+
+    void setParent(WorldEntity* parent);
+    /** @returns the Parent (carrier) of this WeaponManager */
+    PNode* getParent() const { return this->parent; };
+
+    bool addWeapon(Weapon* weapon);
+    bool addWeapon(Weapon* weapon, int configID = -1, int slotID = -1);
+    void removeWeapon(Weapon* weapon, int configID = -1);
+    Weapon* getWeapon(int slotID) const { return (slotID >= 0 && slotID < this->slotCount)? this->currentSlotConfig[slotID].nextWeapon: NULL; };
+
+    // FIXME ::
+//    bool hasFreeSlot(int configID, long capability = WTYPE_ALL) { return ( getNextFreeSlot(configID, capability ) != -1)? true : false; };
+
+    void nextWeaponConfig();
+    void previousWeaponConfig();
+    void changeWeaponConfig(int weaponConfig);
+
+    /** @returns a fixed target namely the Crosshair's 3D position */
+    inline PNode* getFixedTarget() const { return this->crosshair; };
+
+    void fire();
+    //! @TODO: implement this function (maybe also in Weapon itself)
+    void releaseFire();
+
+    void tick(float dt);
+    void draw() const;
+
+    void debug() const;
+
+ // private:
+    int getNextFreeSlot(int configID, long capability = WTYPE_ALL);
+
+  private:
+    WorldEntity*            parent;                                   //!< The parent, this WeaponManager is connected to.
+
+    int                     slotCount;                                //!< number of weapon slots the ship has.
+    int                     currentConfigID;                          //!< the currently selected config.
+    Weapon*                 configs[WM_MAX_CONFIGS][WM_MAX_SLOTS];    //!< An array of predefined configurations and assigned weapon.
+    WM_Slot                 currentSlotConfig[WM_MAX_SLOTS];          //!< The currentConfigureation.
+
+    Weapon*                 availiableWeapons[WM_MAX_LOADED_WEAPONS]; //!< The availiable Weapons of this WeaponManager
+
+    bool                    weaponChange;
+
+    Crosshair*              crosshair;                                //!< an aim.
+    tAnimation<Crosshair>*  crossHairSizeAnim;                        //!< An animation for the crosshair (scaling)
+};
+
+
+#endif /* _WEAPON_MANAGER_H */
Index: branches/network/src/world_entities/world_entity.cc
===================================================================
--- branches/network/src/world_entities/world_entity.cc	(revision 6636)
+++ branches/network/src/world_entities/world_entity.cc	(revision 6636)
@@ -0,0 +1,580 @@
+
+
+/*
+   orxonox - the future of 3D-vertical-scrollers
+
+   Copyright (C) 2004 orx
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   ### File Specific:
+   main-programmer: Patrick Boenzli
+   co-programmer: Christian Meyer
+*/
+#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD_ENTITY
+
+#include "world_entity.h"
+#include "shell_command.h"
+
+#include "model.h"
+#include "md2Model.h"
+#include "resource_manager.h"
+#include "load_param.h"
+#include "vector.h"
+#include "obb_tree.h"
+
+#include "glgui_bar.h"
+
+#include "state.h"
+
+using namespace std;
+
+SHELL_COMMAND(model, WorldEntity, loadModel)
+->describe("sets the Model of the WorldEntity")
+->defaultValues(2, "models/ships/fighter.obj", 1.0);
+
+SHELL_COMMAND(debugEntity, WorldEntity, debugWE);
+
+/**
+ *  Loads the WordEntity-specific Part of any derived Class
+ *
+ * @param root: Normally NULL, as the Derived Entities define a loadParams Function themeselves,
+ *              that can calls WorldEntities loadParams for itself.
+ */
+WorldEntity::WorldEntity()
+    : Synchronizeable()
+{
+  this->setClassID(CL_WORLD_ENTITY, "WorldEntity");
+
+  this->obbTree = NULL;
+  this->energyWidget = NULL;
+  this->energyMax = 1.0f;
+  this->energy = 1.0f;
+
+  this->md2TextureFileName = NULL;
+
+
+  this->setVisibiliy(true);
+
+  this->objectListNumber = OM_INIT;
+  this->objectListIterator = NULL;
+
+  this->toList(OM_NULL);
+}
+
+/**
+ *  standard destructor
+*/
+WorldEntity::~WorldEntity ()
+{
+  // Delete the obbTree
+  if( this->obbTree != NULL)
+    delete this->obbTree;
+
+  if (this->energyWidget != NULL)
+    delete this->energyWidget;
+
+  // Delete the model (unregister it with the ResourceManager)
+  for (unsigned int i = 0; i < this->models.size(); i++)
+    this->setModel(NULL, i);
+
+  State::getObjectManager()->toList(this, OM_INIT);
+}
+
+/**
+ * loads the WorldEntity Specific Parameters.
+ * @param root: the XML-Element to load the Data From
+ */
+void WorldEntity::loadParams(const TiXmlElement* root)
+{
+  // Do the PNode loading stuff
+  PNode::loadParams(root);
+
+  LoadParam(root, "md2texture", this, WorldEntity, loadMD2Texture)
+  .describe("the fileName of the texture, that should be loaded onto this world-entity. (must be relative to the data-dir)")
+  .defaultValues(1, NULL);
+
+  // Model Loading
+  LoadParam(root, "model", this, WorldEntity, loadModel)
+  .describe("the fileName of the model, that should be loaded onto this world-entity. (must be relative to the data-dir)")
+  .defaultValues(3, NULL, 1.0f, 0);
+
+  LoadParam(root, "maxEnergy", this, WorldEntity, setMaxEnergy)
+  .describe("The Maximum energy that can be loaded onto this entity")
+  .defaultValues(1, 1.0f);
+
+  LoadParam(root, "energy", this, WorldEntity, setEnergy)
+  .describe("The Energy the WorldEntity has at this moment")
+  .defaultValues(1, 1.0f);
+}
+
+
+/**
+ * loads a Model onto a WorldEntity
+ * @param fileName the name of the model to load
+ * @param scaling the Scaling of the model
+ *
+ * @todo fix this, so it only has one loadModel-Function.
+*/
+void WorldEntity::loadModel(const char* fileName, float scaling, unsigned int modelNumber)
+{
+  this->scaling = scaling;
+  if ( fileName != NULL && strcmp(fileName, "") )
+  {
+    // search for the special character # in the LoadParam
+    if (strchr(fileName, '#') != NULL)
+    {
+      PRINTF(4)("Found # in %s... searching for LOD's\n", fileName);
+      char* lodFile = new char[strlen(fileName)+1];
+      strcpy(lodFile, fileName);
+      char* depth = strchr(lodFile, '#');
+      for (unsigned int i = 0; i < 5; i++)
+      {
+        *depth = 48+(int)i;
+        printf("-------%s\n", lodFile);
+        if (ResourceManager::isInDataDir(lodFile))
+          this->loadModel(lodFile, scaling, i);
+      }
+      return;
+    }
+    if (scaling == 0.0)
+    {
+      scaling = 1.0;
+      PRINTF(1)("YOU GAVE ME A CRAPY SCALE resetting to 1\n");
+    }
+    if(strstr(fileName, ".obj"))
+    {
+      PRINTF(4)("fetching OBJ file: %s\n", fileName);
+      if (scaling == 1.0)
+        this->setModel((Model*)ResourceManager::getInstance()->load(fileName, OBJ, RP_CAMPAIGN), modelNumber);
+      else
+        this->setModel((Model*)ResourceManager::getInstance()->load(fileName, OBJ, RP_CAMPAIGN, &scaling), modelNumber);
+
+      if( modelNumber == 0)
+        this->buildObbTree(4);
+    }
+    else if(strstr(fileName, ".md2"))
+    {
+      PRINTF(4)("fetching MD2 file: %s\n", fileName);
+      Model* m = new MD2Model(fileName, this->md2TextureFileName);
+      //this->setModel((Model*)ResourceManager::getInstance()->load(fileName, MD2, RP_CAMPAIGN), 0);
+      this->setModel(m, 0);
+    }
+  }
+  else
+  {
+    this->setModel(NULL);
+  }
+}
+
+/**
+ * sets a specific Model for the Object.
+ * @param model The Model to set
+ * @param modelNumber the n'th model in the List to get.
+ */
+void WorldEntity::setModel(Model* model, unsigned int modelNumber)
+{
+  if (this->models.size() <= modelNumber)
+    this->models.resize(modelNumber+1, NULL);
+
+  if (this->models[modelNumber] != NULL)
+  {
+    Resource* resource = ResourceManager::getInstance()->locateResourceByPointer(this->models[modelNumber]);
+    //     if (resource != NULL)
+    ResourceManager::getInstance()->unload(resource, RP_LEVEL);
+  }
+  else
+    delete this->models[modelNumber];
+
+  this->models[modelNumber] = model;
+
+
+  //   if (this->model != NULL)
+  //     this->buildObbTree(4);
+}
+
+
+/**
+ * builds the obb-tree
+ * @param depth the depth to calculate
+ */
+bool WorldEntity::buildObbTree(unsigned int depth)
+{
+  if (this->obbTree)
+    delete this->obbTree;
+
+  if (this->models[0] != NULL)
+  {
+    PRINTF(4)("creating obb tree\n");
+
+
+    this->obbTree = new OBBTree(depth, (sVec3D*)this->models[0]->getVertexArray(), this->models[0]->getVertexCount());
+    return true;
+  }
+  else
+  {
+    PRINTF(2)("could not create obb-tree, because no model was loaded yet\n");
+    this->obbTree = NULL;
+    return false;
+  }
+}
+
+/**
+ * @brief moves this entity to the List OM_List
+ * @param list the list to set this Entity to.
+ *
+ * this is the same as a call to State::getObjectManager()->toList(entity , list);
+ * directly, but with an easier interface.
+ *
+ * @todo inline this (peut etre)
+ */
+void WorldEntity::toList(OM_LIST list)
+{
+  State::getObjectManager()->toList(this, list);
+}
+
+
+
+/**
+ * sets the character attributes of a worldentity
+ * @param character attributes
+ *
+ * these attributes don't have to be set, only use them, if you need them
+*/
+//void WorldEntity::setCharacterAttributes(CharacterAttributes* charAttr)
+//{}
+
+
+/**
+ *  this function is called, when two entities collide
+ * @param entity: the world entity with whom it collides
+ *
+ * Implement behaviour like damage application or other miscellaneous collision stuff in this function
+ */
+void WorldEntity::collidesWith(WorldEntity* entity, const Vector& location)
+{
+  /**
+   * THIS IS A DEFAULT COLLISION-Effect.
+   * IF YOU WANT TO CREATE A SPECIFIC COLLISION ON EACH OBJECT
+   * USE::
+   * if (entity->isA(CL_WHAT_YOU_ARE_LOOKING_FOR)) { printf "dothings"; };
+   *
+   * You can always define a default Action.... don't be affraid just test it :)
+   */
+  //  PRINTF(3)("collision %s vs %s @ (%f,%f,%f)\n", this->getClassName(), entity->getClassName(), location.x, location.y, location.z);
+}
+
+
+/**
+ *  this is called immediately after the Entity has been constructed, initialized and then Spawned into the World
+ *
+ */
+void WorldEntity::postSpawn ()
+{}
+
+
+/**
+ *  this method is called by the world if the WorldEntity leaves valid gamespace
+ *
+ * For free entities this means it left the Track boundaries. With bound entities it means its Location adresses a
+ * place that is not in the world anymore. In both cases you might have to take extreme measures (a.k.a. call destroy).
+ *
+ * NOT YET IMPLEMENTED
+ */
+void WorldEntity::leftWorld ()
+{}
+
+
+/**
+ *  this method is called every frame
+ * @param time: the time in seconds that has passed since the last tick
+ *
+ * Handle all stuff that should update with time inside this method (movement, animation, etc.)
+*/
+void WorldEntity::tick(float time)
+{}
+
+
+/**
+ *  the entity is drawn onto the screen with this function
+ *
+ * This is a central function of an entity: call it to let the entity painted to the screen.
+ * Just override this function with whatever you want to be drawn.
+*/
+void WorldEntity::draw() const
+{
+  //PRINTF(0)("(%s::%s)\n", this->getClassName(), this->getName());
+  //  assert(!unlikely(this->models.empty()));
+  {
+    glMatrixMode(GL_MODELVIEW);
+    glPushMatrix();
+
+    /* translate */
+    glTranslatef (this->getAbsCoor ().x,
+                  this->getAbsCoor ().y,
+                  this->getAbsCoor ().z);
+    Vector tmpRot = this->getAbsDir().getSpacialAxis();
+    glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+
+
+    // This Draws the LOD's
+    float cameraDistance = (State::getCamera()->getAbsCoor() - this->getAbsCoor()).len();
+    if (cameraDistance > 30 && this->models.size() >= 3 && this->models[2] != NULL)
+    {
+      this->models[2]->draw();
+    }
+    else if (cameraDistance > 10 && this->models.size() >= 2 && this->models[1] != NULL)
+    {
+      this->models[1]->draw();
+    }
+    else if (this->models.size() >= 1 && this->models[0] != NULL)
+    {
+      this->models[0]->draw();
+    }
+    glPopMatrix();
+  }
+}
+
+/**
+ * @param energy the Energy to add.
+ * @returns the energy left (this->energyMax - energy+this->energy)
+ */
+float WorldEntity::addEnergy(float energy)
+{
+  this->energy += energy;
+  if (this->energy > this->energyMax)
+  {
+    float retEnergy = this->energyMax - this->energy;
+    this->energy = this->energyMax;
+    this->updateEnergyWidget();
+    return retEnergy;
+  }
+  this->updateEnergyWidget();
+  return 0.0;
+}
+
+/**
+ * @param energy the Energy to be removed
+ * @returns 0.0 or the rest, that was not substracted (bellow 0.0)
+ */
+float WorldEntity::removeEnergy(float energy)
+{
+  this->energy -= energy;
+
+  if (this->energy < 0)
+  {
+    float retEnergy = -this->energy;
+    this->energy = 0.0f;
+    this->updateEnergyWidget();
+    return retEnergy;
+  }
+  this->updateEnergyWidget();
+  return 0.0;
+
+}
+
+/**
+ * @param maxEnergy the maximal energy that can be loaded onto the entity.
+ */
+void WorldEntity::setMaxEnergy(float maxEnergy)
+{
+  this->energyMax = maxEnergy;
+  if (this->energy > this->energyMax)
+  {
+    PRINTF(3)("new maxEnergy is bigger as the old energy. Did you really intend to do this for (%s::%s)\n", this->getClassName(), this->getName());
+    this->energy = this->energyMax;
+  }
+  this->updateEnergyWidget();
+}
+
+/**
+ * @brief creates the EnergyWidget
+ *
+ * since not all entities need an EnergyWidget, it is only created on request.
+ */
+void WorldEntity::createEnergyWidget()
+{
+  if (this->energyWidget == NULL)
+  {
+    this->energyWidget = new GLGuiBar();
+    this->energyWidget->setSize2D(30,400);
+    this->energyWidget->setAbsCoor2D(10,100);
+
+    this->updateEnergyWidget();
+  }
+  else
+    PRINTF(3)("Allready created the EnergyWidget for %s::%s\n", this->getClassName(), this->getName());
+}
+
+GLGuiWidget* WorldEntity::getEnergyWidget()
+{
+  this->createEnergyWidget();
+  return this->energyWidget;
+}
+
+/**
+ * @param visibility shows or hides the energy-bar
+ * (creates the widget if needed)
+ */
+void WorldEntity::setEnergyWidgetVisibilit(bool visibility)
+{
+    if (visibility)
+    {
+      if (this->energyWidget != NULL)
+        this->energyWidget->show();
+      else
+      {
+        this->createEnergyWidget();
+        this->updateEnergyWidget();
+        this->energyWidget->show();
+      }
+    }
+    else if (this->energyWidget != NULL)
+      this->energyWidget->hide();
+}
+
+/**
+ * @brief updates the EnergyWidget
+ */
+void WorldEntity::updateEnergyWidget()
+{
+  if (this->energyWidget != NULL)
+  {
+    this->energyWidget->setMaximum(this->energyMax);
+    this->energyWidget->setValue(this->energy);
+  }
+}
+
+
+/**
+ * DEBUG-DRAW OF THE BV-Tree.
+ * @param depth What depth to draw
+ * @param drawMode the mode to draw this entity under
+ */
+void WorldEntity::drawBVTree(unsigned int depth, int drawMode) const
+{
+  glMatrixMode(GL_MODELVIEW);
+  glPushMatrix();
+  /* translate */
+  glTranslatef (this->getAbsCoor ().x,
+                this->getAbsCoor ().y,
+                this->getAbsCoor ().z);
+  /* rotate */
+  Vector tmpRot = this->getAbsDir().getSpacialAxis();
+  glRotatef (this->getAbsDir().getSpacialAxisAngle(), tmpRot.x, tmpRot.y, tmpRot.z );
+
+  if (this->obbTree)
+    this->obbTree->drawBV(depth, drawMode);
+  glPopMatrix();
+}
+
+
+/**
+ * Debug the WorldEntity
+ */
+void WorldEntity::debugEntity() const
+{
+  PRINT(0)("WorldEntity %s::%s  (DEBUG)\n", this->getClassName(), this->getName());
+  this->debugNode();
+  PRINT(0)("List: %s ; ModelCount %d - ", ObjectManager::OMListToString(this->objectListNumber) , this->models.size());
+  for (unsigned int i = 0; i < this->models.size(); i++)
+  {
+    if (models[i] != NULL)
+      PRINT(0)(" : %d:%s", i, this->models[i]->getName());
+  }
+  PRINT(0)("\n");
+
+}
+
+
+
+
+/********************************************************************************************
+ NETWORK STUFF
+ ********************************************************************************************/
+
+
+/**
+ * Writes data from network containing information about the state
+ * @param data pointer to data
+ * @param length length of data
+ * @param sender hostID of sender
+ */
+int WorldEntity::writeState( const byte * data, int length, int sender )
+{
+  char* modelFileName;
+  SYNCHELP_READ_BEGIN();
+
+  SYNCHELP_READ_FKT( PNode::writeState );
+
+  SYNCHELP_READ_STRINGM( modelFileName );
+  SYNCHELP_READ_FLOAT( scaling );
+  //check if modelFileName is relative to datadir or absolute
+
+  if ( strcmp(modelFileName, "") )
+  {
+    loadModel( modelFileName, scaling );
+  }
+  delete[] modelFileName;
+
+  /*SYNCHELP_READ_STRINGM( modelFileName );
+
+  if ( strcmp(modelFileName, "") )
+    if ( strstr(modelFileName, ResourceManager::getInstance()->getDataDir()) )
+    {
+      this->md2TextureFileName = new char[strlen(modelFileName)-strlen(ResourceManager::getInstance()->getDataDir())+1];
+      strcpy((char*)this->md2TextureFileName, modelFileName+strlen(ResourceManager::getInstance()->getDataDir()));
+    }
+    else
+    {
+      this->md2TextureFileName = modelFileName;
+    }
+  */
+
+  return SYNCHELP_READ_N;
+}
+
+
+/**
+ * data copied in data will bee sent to another host
+ * @param data pointer to data
+ * @param maxLength max length of data
+ * @return the number of bytes writen
+ */
+int WorldEntity::readState( byte * data, int maxLength )
+{
+  SYNCHELP_WRITE_BEGIN();
+
+  SYNCHELP_WRITE_FKT( PNode::readState );
+
+  if ( getModel(0) && getModel(0)->getName() )
+  {
+    char* name = (char*)(getModel( 0 )->getName());
+
+    if ( strstr(name, ResourceManager::getInstance()->getDataDir()) )
+    {
+      name += strlen(ResourceManager::getInstance()->getDataDir());
+    }
+
+    SYNCHELP_WRITE_STRING( name );
+  }
+  else
+  {
+    SYNCHELP_WRITE_STRING("");
+  }
+
+  SYNCHELP_WRITE_FLOAT( scaling );
+  /*if ( this->md2TextureFileName!=NULL && strcmp(this->md2TextureFileName, "") )
+  {
+    SYNCHELP_WRITE_STRING(this->md2TextureFileName);
+  }
+  else
+  {
+    SYNCHELP_WRITE_STRING("");
+}*/
+
+  return SYNCHELP_WRITE_N;
+}
Index: branches/network/src/world_entities/world_entity.h
===================================================================
--- branches/network/src/world_entities/world_entity.h	(revision 6636)
+++ branches/network/src/world_entities/world_entity.h	(revision 6636)
@@ -0,0 +1,126 @@
+/*!
+ * @file world_entity.h
+ * Definition of the basic WorldEntity
+*/
+
+#ifndef _WORLD_ENTITY_H
+#define _WORLD_ENTITY_H
+
+#include "p_node.h"
+#include "synchronizeable.h"
+#include "model.h"
+
+#include "object_manager.h"
+#include "glincl.h"
+#include <vector>
+
+// FORWARD DECLARATION
+class SoundBuffer;
+class SoundSource;
+class BVTree;
+class Model;
+
+class GLGuiWidget;
+class GLGuiBar;
+
+//class CharacterAttributes;
+
+
+//! Basis-class all interactive stuff in the world is derived from
+class WorldEntity : public PNode
+{
+public:
+  WorldEntity();
+  virtual ~WorldEntity ();
+
+  virtual void loadParams(const TiXmlElement* root);
+
+  void loadModel(const char* fileName, float scaling = 1.0f, unsigned int modelNumber = 0);
+  void setModel(Model* model, unsigned int modelNumber = 0);
+  Model* getModel(unsigned int modelNumber = 0) const { return (this->models.size() > modelNumber)? this->models[modelNumber] : NULL; };
+
+  inline void loadMD2Texture(const char* fileName) { this->md2TextureFileName = fileName; }
+
+  bool buildObbTree(unsigned int depth);
+  /** @returns a reference to the obb tree of this worldentity */
+  BVTree* getOBBTree() const { return this->obbTree; };
+
+  /** @param visibility if the Entity should be visible (been draw) */
+  void setVisibiliy (bool visibility) { this->bVisible = visibility; };
+  /** @returns true if the entity is visible, false otherwise */
+  inline bool isVisible() const { return this->bVisible; };
+
+
+
+  virtual void postSpawn ();
+  virtual void leftWorld ();
+
+  virtual void tick (float time);
+
+  virtual void draw () const;
+
+  virtual void collidesWith (WorldEntity* entity, const Vector& location);
+  void drawBVTree(unsigned int depth, int drawMode) const;
+
+
+  void debugWE() { this->debugEntity(); }
+  ;  ///FIXME
+  void debugEntity() const;
+
+
+  /* @returns the Count of Faces on this WorldEntity */
+  //unsigned int getFaceCount () const { return (this->model != NULL)?this->model->getFaceCount():0; };
+  //  void addAbility(Ability* ability);
+  //  void removeAbility(Ability* ability);
+  //  void setCharacterAttributes(CharacterAttributes* charAttr);
+  //  CharacterAttributes* getCharacterAttributes();
+
+  void toList(OM_LIST list);
+
+  /** @returns a Reference to the objectListNumber to set. */
+  OM_LIST& getOMListNumber() { return this->objectListNumber; }
+  /** @returns a Reference to the Iterator */
+  std::list<WorldEntity*>::iterator& getEntityIterator() { return this->objectListIterator; }
+
+  int       writeState(const byte* data, int length, int sender);
+  int       readState(byte* data, int maxLength );
+
+  /** @returns the Energy of the entity */
+  float getEnergy() const { return this->energy; };
+  /** @returns the Maximum energy this entity can be charged with */
+  float getMaxEnergy() const { return this->energyMax; }
+  float addEnergy(float energy);
+  float removeEnergy(float energy);
+  void setMaxEnergy(float maxEnergy);
+  GLGuiWidget* getEnergyWidget();
+
+protected:
+  void setEnergy(float energy) { this->energy = energy; };
+  void setEnergyWidgetVisibilit(bool visibility);
+  void createEnergyWidget();
+  //  CharacterAttributes*    charAttr;         //!< the character attributes of a world_entity
+private:
+  void updateEnergyWidget();
+
+private:
+  /// TODO maybe we will move the following three entries and the corresponding functions to Playable AND NPC
+  float                   energy;             //!< The Energy of this Entity, if the Entity has any energy at all.
+  float                   energyMax;          //!< The Maximal energy this entity can take.
+  GLGuiBar*               energyWidget;       //!< The Slider (if wanted).
+
+  std::vector<Model*>     models;             //!< The model that should be loaded for this entity.
+  const char*             md2TextureFileName; //!< the file name of the md2 model texture, only if this
+  BVTree*                 obbTree;            //!< this is the obb tree reference needed for collision detection
+
+  bool                    bCollide;           //!< If it should be considered for the collisiontest.
+  bool                    bVisible;           //!< If it should be visible.
+
+  OM_LIST                           objectListNumber;   //!< The ObjectList from ObjectManager this Entity is in.
+  std::list<WorldEntity*>::iterator objectListIterator; //!< The iterator position of this Entity in the given list of the ObjectManager.
+
+  float                   scaling;
+
+
+};
+
+#endif /* _WORLD_ENTITY_H */
