r139 - in trunk: . src src/objects tools

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Sat Sep 3 08:40:32 EDT 2005


Author: jonas
Date: 2005-09-03 08:40:31 -0400 (Sat, 03 Sep 2005)
New Revision: 139

Modified:
   trunk/TODO
   trunk/src/animation.cpp
   trunk/src/animation.h
   trunk/src/characters_common.cpp
   trunk/src/characters_common.h
   trunk/src/common.cpp
   trunk/src/common.h
   trunk/src/events.cpp
   trunk/src/gfxeng.cpp
   trunk/src/imgcache.cpp
   trunk/src/imgcache.h
   trunk/src/lost_penguins.cpp
   trunk/src/monsters_common.cpp
   trunk/src/monsters_common.h
   trunk/src/objects/baleog.cpp
   trunk/src/objects/erik.cpp
   trunk/src/objects/fang.cpp
   trunk/src/objects/olaf.cpp
   trunk/src/objects/olaf.h
   trunk/src/objects/scorch.cpp
   trunk/src/objects/zombie.cpp
   trunk/src/objects_common.cpp
   trunk/src/objects_common.h
   trunk/src/physics.cpp
   trunk/src/players_common.cpp
   trunk/src/players_common.h
   trunk/tools/lvl2magick.c
Log:
Huge REWRITE of the Animation and ImageCache class:

  o Introduced the struct Image: An image is composed of an SDL_Surface* and a
    corresponding description of it's frames (std::vector<SDL_Rect>).
  o Added constructors to the Frame struct to ease creation.
  o Introduce animation type: It describe?\209?\149 what type of animation we have
    (once/loop/swing/backwards/etc)
  o Introduced BasePointType and AllignType to specify how animations should be
    positioned wrt to their current base position (see animation.h).
  o ImageCache (basically a rewrite):
      - ImageCache now uses Images as a base, not SDL_Surface* and is also
        responsible to load the image description besides the surface.
      - Support for description file loading (compatible with the output of
        lvl2magick) => we should be able to easily load animations from
        a lvl2magick generated image
      - Support for description generation based on: base rectangles, number of
        frames, width and shift, direct specification (see imgcache.h)
      - Support for _Image_ scaling (including description)
  o Animation (complete rewrite): check animation.h!!
  o Updated the rest of the code to support the new ImageCache and Animation
    classes:
      - Removed all occurencies of curpos/getCurPos() (we don't need them
        anymore, to get the draw position of an animation we use getDrawPos())
      - As a consequence we can get rid of 3 shiftMapArea
      - Added/Changed getFrame()/getDrawPos() as a function of each object to
        allow the gfxeng to get the draw position and frame
      - Removed all occurencies of anim->getWidth()/getHeight() (we use
        getBaseDim() now)
      - updated updateAnimState(), resetAnimState(), setAnim(), we don't need
        the change parameter of updateAnimState() anymore (maybe check the
        two changes in physics.cpp)
      - Introduced a Object::loadAnimation(...) function (loads an animation
        and sets the corresponding base position to the object position)
      - Added all Animation loadings everywhere accordingly (to match the
        Animation class)
      - As there is no more getFrame(nr) function, Animation has now a
        getBaseFrame() function to allow the loading of icons (HACK)
  o Updated the TODO accordingly
  o Updated lvl2magick to write a proper parsable description header for
    description files which are now have the extension .dsc
  o A few cosmetic changes



Modified: trunk/TODO
===================================================================
--- trunk/TODO	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/TODO	2005-09-03 12:40:31 UTC (rev 139)
@@ -4,6 +4,7 @@
  o memleaks, segfaults?
  o left/right move + switchPlayer (keeps moving)
  o key vs. trigger in map2
+ o fall event (DONE?)
 
 
 Code
@@ -35,75 +36,18 @@
          possible. If it's not possible, do sthg else (stop the elevator and hit the
          object/whatever)...
 
- o Animations/Events:
-     o Allow as complex Images as possible:
-       Introduce some image info structure that gives an array of subimages
-       Animations can then easily be specified by giving the start and end number in the
-       array. A subimage is defined by sthg like SDL_rect relative to the base image
-     o As the images of an animation (as in above) may vary in size we should introduce
-       sthg like a "base point" type: center/left/right (x) center/top/bottom (y)
-       => total: 9 types. Find a default base point...
-       which is a point in the animation that stays fixed (related to pos)
-     o Using the "base point" type => introduce corresponding drawing methode, which
-       consists of a rule on how to map the base point to the position (allignment):
-         center/left/right (x) center/top/bottom (y)
-         maybe introduce delta values for correction shifts
-       => most times the x-alignment probably corresponds to the base point, but the
-          y-allignment will almost always be bottom (top: sthg that hangs on a rope)
-     o Is the alignment a property of the object (state) or of the animation? => suggest animation
-     o Idea: introduce two type of animation for a simple triggered anim:
-         still anim: eg. 1 image, trig anim:  animation starting with the still one
-       => get rid of once, running
-       More generally: do the logic about that outside of the animation structure
-     o Maybe introduce an animation base class and do the base_point/allignment logic
-       in derived classes somehow? Or use another pattern for this...
+ o Events/Animations:
      o Allow empty animation, decouple (put more logic in) these relations:
        object (pos, draw?), game(time, state, handler), gfxeng(draw), animation(empty,
        frame, update, time, draw)?, frame, global/current (public, private) properties
-
-     o New anim class/struct:
-        /* Global properties */
-        SDL_Surface* base_image (or in Frame struct)
-        Uint16 start_pos
-        Uint16 end_pos / or Uint16 frames
-        enum base_point_type
-        enum allignment_type
-        Uint16 allignment_delta
-        Uint16 length
-        /* Global Helper values */
-        // maybe: bool empty?
-        bool still (if frames==1)
-        (see above) Uint16 frames / or Uint16 end_pos
-
-        /* (Current) public properties */
-	void update(Uint16 dt)
-        void draw() <- friend in gfxeng (shift, screen, etc)?
-          //information about the current graphic (frame)
-          //information about where to draw it (draw_pos)
-
-        /* Current private properties */
-        Uint16 cur_im_pos / or Uint16 cur_frame / or Uint16 cur_time
-        SDL_Rect* owner_pos (position of the owner) / or const SDL_Rect& owner_pos
-        /* Current helper values */
-        Frame cur_frame (using private + image info) => w,h (or + Base Image)
-        (see above) Uint16 cur_pos / or Uint16 cur_frame / or Uint16 cur_time
-        SDL_Rect* (or SDL_Rect& ) draw_pos (using
-          (allignment/base_point)_(type/delta) + frame + owner_pos)
-
      o Make all events quite short, ie. almost all events become animation
        events
-     o Maybe: Improve the (very simple) image format:
-        - All frame in one sprite sheet for each character (image matrices
-          using two description vectors or even more general: offset matrices)
-          => see above
-        - store rects in an array/vector/whatever or use offset matrices
-          => see above
-        - do some column/row logics to easy the access
+     o Do some column/row logics to easy the access? => NO
         - eg. set offsets for left, right, mleft, mright...
-        - IDEA: just store one side and add some flipping logic to the image
+     o IDEA: just store one side and add some flipping logic to the image
           loading process...
-     o IDEA: change Animation* pointers to Animation (or references), leave only
-       animation as a pointer and get the address each time...
+     o IDEA: change Animation* pointers to Animation (or references or auto_ptr),
+       leave only animation as a pointer and get the address each time...
      o introduce animation events that play an animation and end when it's
        finnished (always ESTATE_BUSY or abort animation?)
      o allow an event length depending on animation length, or: relate events more
@@ -138,6 +82,7 @@
  o DONE?: players, object, item, ai, weapons, character
  o PART DONE: effect management (periodic events, permanent effects, etc)
  o DONE: hitlogic
+ o IMPROVE!: move logic
 
 
 Features/Ideas
@@ -145,12 +90,11 @@
 
  o Make water movements possible (eric)
  o Add better graphics
- o finnish the map editor
- o OpenGL
+ o improve the map editor
  o Simple AI
 
  o Finnish the vikings:
-     - weapons: run, jump2, fart, sword, arm, fire, claws
+     - weapons: better run, jump2, fart, arm, fire
      - baleog swing (hard one)
 
  o Add new objects:
@@ -161,7 +105,6 @@
 
  o Monsters?:
      - stone?
-     - plant
      - knight
      - dragon
      - skeleton -> zombie

Modified: trunk/src/animation.cpp
===================================================================
--- trunk/src/animation.cpp	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/src/animation.cpp	2005-09-03 12:40:31 UTC (rev 139)
@@ -1,65 +1,271 @@
 #include "common.h"
 #include "animation.h"
 
-Animation::Animation(SDL_Surface* anim_image, Uint16 max_num, Uint16 total_time, bool an_once):
-  size(max_num),
-  time(total_time),
-  num(0),
-  tcurrent(0),
-  once(an_once) {
-    if (time==0 || once) running=false;
-    else running=true;
-    frame.image=anim_image;
-    w=(Uint16)((frame.image->w)/size);
-    h=frame.image->h;
-    frame.pos.x=0;
-    frame.pos.y=0;
-    frame.pos.w=w;
-    frame.pos.h=h;
+Animation::Animation(const Image& abase_image,
+          Uint32 aduration,
+          Uint16 aframes,
+          Uint16 aanimation_type,
+          Uint16 astart_pos,
+          BasePointType abp_type,
+          AllignType aallign_type,
+          Sint16 ashift_x,
+          Sint16 ashift_y):
+  base_image(abase_image),
+  duration(aduration),
+  frames(aframes),
+  animation_type(aanimation_type),
+  start_pos(astart_pos),
+  bp_type(abp_type),
+  allign_type(aallign_type),
+  shift_x(ashift_x),
+  shift_y(ashift_y),
+  end_pos(start_pos+frames),
+  base_pos(NULL) {
+    checkAnim();
 }
+Animation::~Animation() { }
+void Animation::runAnim() {
+    if (!isValid()) {
+        cout << "Starting an invalid animation!" << endl;
+        return;
+    }
+    is_running=true;
+    cur_time=0;
+    if (animation_type&ATYPE_ALL_NORMAL) {
+        forward=true;
+        cur_frame_num=0;
+        cur_im_pos=start_pos;
+    } else {
+        forward=false;
+        cur_frame_num=frames-1;
+        cur_im_pos=end_pos;
+    }
+}
+bool Animation::stopAnim() {
+    if (!isValid()) {
+        cout << "Stopping an invalid animation!" << endl;
+        return is_running=false;
+    } else if (animation_type&ATYPE_ALL_ONCE) {
+        is_running=false;
+        cur_time=0;
+        if (animation_type&ATYPE_ALL_LSTART) {
+            cur_frame_num=0;
+            cur_im_pos=start_pos;
+        } else {
+            cur_frame_num=frames-1;
+            cur_im_pos=end_pos;
+        }
+    }
+    return isRunning();
+}
 
-Animation::Animation(Uint16 width, SDL_Surface* anim_image, Uint16 max_num, Uint16 total_time, bool an_once):
-  size(max_num),
-  time(total_time),
-  num(0),
-  tcurrent(0),
-  once(an_once) {
-    if (time==0 || once) running=false;
-    else running=true;
-    frame.image=anim_image;
-    w=width;
-    h=frame.image->h;
-    frame.pos.x=0;
-    frame.pos.y=0;
-    frame.pos.w=w;
-    frame.pos.h=h;
+bool Animation::updateAnim(Uint16 dt) {
+    if (!isValid()) {
+        cout << "Updating an invalid animation!" << endl;
+        return false;
+    }
+    if (!isRunning()) return false;
+    cur_time+=dt;
+    Uint32 durationh=(Uint32)duration/2;
+
+    if        (animation_type&ATYPE_ONCE || animation_type&ATYPE_ONCE_END) {
+        if (cur_time>=duration) {
+            return stopAnim();
+        } else {
+            cur_frame_num=(Uint16)(cur_time*frames/duration);
+        }
+    } else if (animation_type&ATYPE_LOOP) {
+        if (cur_time>=duration) {
+            while(cur_time>=duration) cur_time-=duration;
+        }
+        cur_frame_num=(Uint16)(cur_time*frames/duration);
+    } else if (animation_type&ATYPE_ONCE_REV || animation_type&ATYPE_ONCE_END_REV) {
+        if (cur_time>=duration) {
+            return stopAnim();
+        } else {
+            cur_frame_num=(Uint16)((duration-cur_time-1)*frames/duration);
+        }
+    } else if (animation_type&ATYPE_LOOP_REV) {
+        if (cur_time>=duration) {
+            while(cur_time>=duration) cur_time-=duration;
+        }
+        cur_frame_num=(Uint16)((duration-cur_time-1)*frames/duration);
+    } else if (animation_type&ATYPE_SWING && forward) {
+        if (cur_time>=durationh) {
+            forward=false;
+            cur_frame_num=(Uint16)((duration-cur_time-1)*frames/durationh);
+        } else {
+            cur_frame_num=(Uint16)(cur_time*frames/durationh);
+        }
+    } else if (animation_type&ATYPE_SWING) {
+        if (cur_time>=duration) {
+            while(cur_time>=duration) cur_time-=duration;
+            forward=true;
+            cur_frame_num=(Uint16)(cur_time*frames/durationh);
+        } else {
+            cur_frame_num=(Uint16)((duration-cur_time-1)*frames/durationh);
+        }
+    } else if (animation_type&ATYPE_SWING_REV && forward) {
+        if (cur_time>=duration) {
+            while(cur_time>=duration) cur_time-=duration;
+            forward=false;
+            cur_frame_num=(Uint16)((duration-cur_time-1)*frames/durationh);
+        } else {
+            cur_frame_num=(Uint16)(cur_time*frames/durationh);
+        }
+    } else if (animation_type&ATYPE_SWING_REV) {
+        if (cur_time>=durationh) {
+            forward=true;
+            cur_frame_num=(Uint16)(cur_time*frames/durationh);
+        } else {
+            cur_frame_num=(Uint16)((duration-cur_time-1)*frames/durationh);
+        }
+    } else {
+        cout << "This shouldn't happen: Unknown animation_type!" << endl;
+        return stopAnim();
+    }
+    return isRunning();
 }
+Frame Animation::getFrame() const {
+    if (!isValid()) cout << "Invalid Frame of an invalid animation!" << endl;
+    return Frame(base_image.surface,base_image.description[cur_frame_num]);
+}
+Frame Animation::getBaseFrame() const {
+    if (!isValid()) cout << "Invalid Base Frame of an invalid animation!" << endl;
+    Uint16 num;
+    if (animation_type&ATYPE_ALL_NORMAL) num=start_pos;
+    else num=end_pos;
+    return Frame(base_image.surface,base_image.description[num]);
+}
+SDL_Rect Animation::getDrawPos() const {
+    SDL_Rect draw_pos=base_image.description[cur_frame_num];
+    if (!base_pos || !isValid()) {
+        if (!isValid()) cout << "Invalid DrawPos of an invalid animation!" << endl;
+        else cout << "Invalid DrawPos!" << endl;
+        draw_pos.x=draw_pos.y=draw_pos.w=draw_pos.h=0;
+        return draw_pos;
+    }
+    draw_pos.x=base_pos->x;
+    draw_pos.y=base_pos->y;
 
-Animation::~Animation() { }
+    /* calculate the base point */
+    Sint16 base_point_x=0;
+    Sint16 base_point_y=0;
 
-bool Animation::updateAnim(Uint16 dt) {
-    if (!running) return false;
-    tcurrent+=dt;
-    if (tcurrent < time) {
-        num=(Uint16)((tcurrent*size)/time);
-        if (num>=size) num=0;
-    } else if (once || time==0) {
-        num=size;
-        tcurrent=time;
-        running=false;
+    /* BP_MD is used most times */
+    if        (bp_type==BP_MD) {
+        base_point_x=(Uint16)draw_pos.w/2;
+        base_point_y=draw_pos.h;
+    } else if (bp_type==BP_LU) {
+        base_point_x=0;
+        base_point_y=0;
+    } else if (bp_type==BP_LM) {
+        base_point_x=0;
+        base_point_y=(Uint16)draw_pos.h/2;
+    } else if (bp_type==BP_LD) {
+        base_point_x=0;
+        base_point_y=draw_pos.h;
+    } else if (bp_type==BP_MU) {
+        base_point_x=(Uint16)draw_pos.w/2;
+        base_point_y=0;
+    } else if (bp_type==BP_MM) {
+        base_point_x=(Uint16)draw_pos.w/2;
+        base_point_y=(Uint16)draw_pos.h/2;
+    } else if (bp_type==BP_RU) {
+        base_point_x=draw_pos.w;
+        base_point_y=0;
+    } else if (bp_type==BP_RM) {
+        base_point_x=draw_pos.w;
+        base_point_y=(Uint16)draw_pos.h/2;
+    } else if (bp_type==BP_RD) {
+        base_point_x=draw_pos.w;
+        base_point_y=draw_pos.h;
     } else {
-        num=0;
-        tcurrent=0;
+        cout << "This shouldn't happen: Unknown base point type!" << endl;
+        base_point_x=(Uint16)draw_pos.w/2;
+        base_point_y=draw_pos.h;
     }
-    frame.pos.x=num*w;
-    if (running) return true;
-    else return false;
-//The solution below would be better but it won't work with the 2nd constructor
-//    frame.pos.x=(Uint16)((num*frame.image->w)/size);
+
+    /* calculate the draw_pos using the allignment type */
+    if        (allign_type==AT_MD) {
+        draw_pos.x+=(Uint16)base_pos->w/2-base_point_x;
+        draw_pos.y+=base_pos->h-base_point_y;
+    } else if (allign_type==AT_LU) {
+        draw_pos.x-=base_point_x;
+        draw_pos.y-=base_point_y;
+    } else if (allign_type==AT_LM) {
+        draw_pos.x-=base_point_x;
+        draw_pos.y+=(Uint16)base_pos->h/2-base_point_y;
+    } else if (allign_type==AT_LD) {
+        draw_pos.x-=base_point_x;
+        draw_pos.y+=base_pos->h-base_point_y;
+    } else if (allign_type==AT_MU) {
+        draw_pos.x+=(Uint16)base_pos->w/2-base_point_x;
+        draw_pos.y-=base_point_y;
+    } else if (allign_type==AT_MM) {
+        draw_pos.x+=(Uint16)base_pos->w/2-base_point_x;
+        draw_pos.y+=(Uint16)base_pos->h/2-base_point_y;
+    } else if (allign_type==AT_RU) {
+        draw_pos.x+=base_pos->w-base_point_x;
+        draw_pos.y-=base_point_y;
+    } else if (allign_type==AT_RM) {
+        draw_pos.x+=base_pos->w-base_point_x;
+        draw_pos.y+=(Uint16)base_pos->h/2-base_point_y;
+    } else if (allign_type==AT_RD) {
+        draw_pos.x+=base_pos->w-base_point_x;
+        draw_pos.y+=base_pos->h-base_point_y;
+    } else {
+        cout << "This shouldn't happen: Unknown allign type!" << endl;
+        draw_pos.x+=(Uint16)base_pos->w/2-base_point_x;
+        draw_pos.y+=base_pos->h-base_point_y;
+    }
+
+    /* substract shift ("add" it to the bp position) */
+    draw_pos.x-=shift_x;
+    draw_pos.y-=shift_y;
+
+    return draw_pos;
 }
 
-const Frame& Animation::setFrame(Uint16 num) {
-    frame.pos.x=num*w;
-    return frame;
+SDL_Rect Animation::getFrameDim() const {
+    if (!isFixed()) cout << "Invalid Frame dimension of an invalid animation!" << endl;
+    SDL_Rect rect;
+    rect.x=rect.y=0;
+    rect.w=base_image.description[start_pos].w;
+    rect.h=base_image.description[start_pos].h;
+    return rect;
 }
 
+bool Animation::checkAnim() {
+    if (base_image.surface==NULL || base_image.description.empty()) {
+        is_valid=false;
+    } else if (base_image.description.size()==1 || duration==0 || frames==1) {
+        is_image=true;
+        cur_time=0;
+        forward=true;
+        cur_frame_num=0;
+        cur_im_pos=start_pos;
+        is_running=false;
+        is_fixed=true;
+        is_valid=true;
+    } else if (frames==0 || start_pos>end_pos || (start_pos+frames)>base_image.description.size()) {
+        is_valid=false;
+    } else {
+        is_valid=true;
+        is_image=false;
+        is_fixed=false;
+        if (animation_type&ATYPE_ALL_ONCE) is_running=false;
+        else is_running=true;
+        cur_time=0;
+        if (animation_type&ATYPE_ALL_NORMAL) {
+            forward=true;
+            cur_frame_num=0;
+            cur_im_pos=start_pos;
+        } else {
+            forward=false;
+            cur_frame_num=frames-1;
+            cur_im_pos=end_pos;
+        }
+    }
+    return is_valid;
+}

Modified: trunk/src/animation.h
===================================================================
--- trunk/src/animation.h	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/src/animation.h	2005-09-03 12:40:31 UTC (rev 139)
@@ -1,76 +1,138 @@
 #ifndef DEF_ANIMATION_H
 #define DEF_ANIMATION_H 1
 
-/** \brief A container for frames.
+/** \brief Animation is responsible to return the correct frame of an animation
 
-    Animation format: a horizontal strip (image) with (num) frames
-    \todo Change this to an offset matrix or something similar or give each row a different animation
 */
 class Animation {
     public:
         /// \brief Initialize the animation
-        /// \param image Image used for the animation
-        /// \param max_num Number of frames (will devide the image horizontally accordingly)
-        /// \param total_time Duration of the animation, if set to 0 assume it's one still image
-        /// \param once If true it run the animation only once when called by \fn start()
-        Animation(SDL_Surface* image, Uint16 max_num=1, Uint16 total_time=0, bool once=false);
-        /// \brief Initialize the animation
-        /// \param width Image width used from the left side
-        /// \param image Image used for the animation
-        /// \param max_num Number of frames (will devide the image horizontally accordingly)
-        /// \param total_time Duration of the animation, if set to 0 assume it's one still image
-        /// \param once If true: Run the animation only once when called by \fn start()
-        Animation(Uint16 width, SDL_Surface* image, Uint16 max_num=1, Uint16 total_time=0, bool once=false);
+        /// \param abase_image Base image used for the animation
+        /// \param aduration Duration of the animation
+        /// \param aframes Number of frames
+        /// \param aanimation_type Animation type
+        /// \param astart_pos Start position from the frame array of the base_image
+        /// \param abp_type Base point type
+        /// \param aallign_type Allignment type
+        /// \param ashift_x x shift value
+        /// \param ashift_y y shift value
+        ///
+        /// To load one still image simply use: Animation(loadImage(1,"image_name.png"))
+        Animation(const Image& abase_image,
+                  Uint32 aduration=0,
+                  Uint16 aframes=1,
+                  Uint16 aanimation_type=ATYPE_LOOP,
+                  Uint16 astart_pos=0,
+                  BasePointType abp_type=BP_MD,
+                  AllignType aallign_type=AT_MD,
+                  Sint16 ashift_x=0,
+                  Sint16 ashift_y=0);
         ~Animation();
+        /// Set the base position of the animation
+        void setBasePos(SDL_Rect* abase_pos) {
+            base_pos=abase_pos;
+            checkAnim();
+        }
+        /// Unsets the base position of the animation
+        void unsetBasePos() {
+            base_pos=NULL;
+        }
+        /// Start the animation from the beginning (used when the animation was still)
+        void runAnim();
         /// Updates a running animation and stops it if necessary
         /// return True if the animation is still running
-        /// \todo This should be more advanced
         bool updateAnim(Uint16 dt);
-        /// Updates the frame status of a frame series (usually when not running)
-        /// return Current frame
-        const Frame& setFrame(Uint16 nr);
-        /// Starts an (usually non running) animation
-        void start() {
-            num=0;
-            tcurrent=0;  
-            running=true;
+        /// Calculates and returns the current frame
+        Frame getFrame() const;
+        /// Calculates and returns the current draw position using:
+        /// base_pos,bp_type,allign_type,shift,cur_im_pos
+        SDL_Rect getDrawPos() const;
+        /// HACK: Return the dimensions of the first frame
+        SDL_Rect getFrameDim() const;
+        /// HACK: Return the base frame
+        Frame getBaseFrame() const;
+        /// return True if the animation is valid
+        bool isValid() const {
+            return is_valid;
         }
-        const Frame& getFrame() const {
-            return frame;
-        }
-        Frame getFrame(Uint16 nr) const {
-            Frame newframe=frame;
-            newframe.pos.x=nr*w;
-            return newframe;
-        }
-        Uint16 getWidth() const {
-            return w;
-        }
-        Uint16 getHeight() const {
-            return h;
-        }
         /// return True if the animation is running
         bool isRunning() const {
-            return running;
+            return is_running;
         }   
+        /// return True if the animation is a still image
+        bool isImage() const {
+            return is_image;
+        }   
+        /// return True if the animation dimensions stay the same
+        bool isFixed() const {
+            return is_fixed;
+        }   
     private:
-        /// Frame pointer
-        Frame frame;
+        /// Helper function to stop an animation
+        bool stopAnim();
+        /// check validity of the animation
+        bool checkAnim();
+    private:
+        /// Base image for the animation (big)
+        Image base_image;
+        /// Duration of the animation in ms
+        Uint32 duration;
         /// Number of frames
-        Uint16 size;
-        /// Total time (in ms)
-        Uint16 time;  
-        /// Frame size
-        Uint16 w;
-        Uint16 h;
+        Uint16 frames;
+        /// Animation type: ATYPE_ONCE (play once), ATYPE_ONCE_END (play once and stop at end),
+        /// ATYPE_LOOP (always play, jump back to the beginning), ATYPE_SWING (always play,
+        /// reverse direction when finnished). The appended _REV means that the animation is
+        /// started at the end and played backwards.
+        Uint16 animation_type;
+        /// Start position from the frame array of the base_image
+        Uint16 start_pos;
+        ///\brief The base point of the animation
+        ///
+        /// The base point always stays fixed during the animation.
+        /// It's types are: BP_xy, where x may be either L,M or R and y may be either
+        /// U, M or D. L: left end, M: middle, R: right end, U: upper end, D: lower end
+        ///
+        /// Example: BP_MU means the BP is the upper middle point of each frame.
+        /// Default: BP_MD
+        BasePointType bp_type;
+        ///\brief Allignment of the base point onto the base_pos
+        ///
+        /// The allignment specifies how the base point should be positioned wrt to the
+        /// base_pos: It's type are basically the same as in BasePointType.
+        ///
+        /// Example: (Assuming BP_MD) AT_LD means the middle point of each frame (BP_MD)
+        ///          is mapped onto the lower left edge of the base_pos
+        /// Default: AT_MD
+        AllignType allign_type;
+        //@{
+        /// shift is added as an additional value to the designated BP position.
+        Sint16 shift_x;
+        Sint16 shift_y;
+        //@}
+        
+        /* calculated or given values/functions */
+        /// End position from the frame array of the base_image
+        Uint16 end_pos;
+        /// True if the animation consist of one still image (frames=1,still=true)
+        bool is_image;
+        /// True if the sanity checks suceeded
+        bool is_valid;
+        /// True if the image dimensions stay fixed during the whole animation (unused)
+        bool is_fixed;
+
+        /* temporary values */
+        /// Pointer to the current base position of the animation
+        SDL_Rect* base_pos;
+        /// True if the animation is running
+        bool is_running;
+        /// True if the animation is running forward at the moment
+        bool forward;
         /// Current frame number
-        Uint16 num;
-        /// Current time position (in ms)
-        Uint16 tcurrent;
-        /// frame series or running?
-        bool running;
-        /// play the animation only once?
-        bool once;
+        Uint16 cur_frame_num;
+        /// Current position of the base_image_desc array
+        Uint16 cur_im_pos;
+        /// Current time
+        Uint32 cur_time;
 };
 
 #endif

Modified: trunk/src/characters_common.cpp
===================================================================
--- trunk/src/characters_common.cpp	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/src/characters_common.cpp	2005-09-03 12:40:31 UTC (rev 139)
@@ -64,12 +64,8 @@
     enter.erase(obj);
 }
 
-void Character::updateAnimState(bool change) {
-    if (change) animation=im_orig;
-    curpos.w=animation->getWidth();
-    curpos.h=animation->getHeight();
-    curpos.x=(Uint16)((pos.w-curpos.w)/2); 
-    curpos.y=(pos.h-curpos.h);
+void Character::updateAnimState() {
+    animation=im_orig;
 }
 
 void Character::idle(Uint16) {

Modified: trunk/src/characters_common.h
===================================================================
--- trunk/src/characters_common.h	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/src/characters_common.h	2005-09-03 12:40:31 UTC (rev 139)
@@ -105,12 +105,11 @@
         virtual void removedObject(Object*);
         ///\brief Updates the current animation
         ///
-        /// Checks the state and changes the animation and curpos correpspondingly
-        /// \param change False if only the curpos should be changed and not the animation.
-        virtual void updateAnimState(bool change=true);
+        /// Checks the state and changes the animation correpspondingly
+        virtual void updateAnimState();
         virtual void resetAnimState() {
             Object::resetAnimState();
-            updateAnimState(true);
+            updateAnimState();
         }
         //Define these for each character, the base function must be run for all derived classes
         virtual void idle(Uint16);

Modified: trunk/src/common.cpp
===================================================================
--- trunk/src/common.cpp	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/src/common.cpp	2005-09-03 12:40:31 UTC (rev 139)
@@ -1,5 +1,4 @@
 #include "common.h"
-#include "menu.h"
 
 ImageCache* imgcache;
 SoundCache* sndcache;
@@ -64,3 +63,12 @@
         SDL_ShowCursor(SDL_DISABLE);
     }
 }
+
+Frame::Frame(SDL_Surface* surface,SDL_Rect rect):
+  image(surface),
+  pos(rect) { }
+
+Frame::Frame():
+  image(NULL) {
+    pos.x=pos.y=pos.w=pos.h=0;
+}

Modified: trunk/src/common.h
===================================================================
--- trunk/src/common.h	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/src/common.h	2005-09-03 12:40:31 UTC (rev 139)
@@ -20,7 +20,6 @@
 #include <SDL_image.h>
 #endif
 
-using std::string;
 using namespace std;
 
 class Object;
@@ -50,26 +49,44 @@
 typedef std::set<Monster *>::iterator monster_iterator;
 
 //General definitions
-#define NOTHING             0x00000000
-#define ALL                 0xFFFFFFFF
-#define DIR_RIGHT           0x00000001
-#define DIR_LEFT            0x00000002
-#define DIR_UP              0x00000004
-#define DIR_DOWN            0x00000008
-#define DIR_ALL             0x0000000F
-#define DIR_UPR             0x00000005
-#define DIR_UPL             0x00000006
-#define DIR_DWR             0x00000009
-#define DIR_DWL             0x0000000A
-#define DIR_LR              0x00000003
+#define NOTHING                 0x00000000
+#define ALL                     0xFFFFFFFF
+#define DIR_RIGHT               0x00000001
+#define DIR_LEFT                0x00000002
+#define DIR_UP                  0x00000004
+#define DIR_DOWN                0x00000008
+#define DIR_ALL                 0x0000000F
+#define DIR_UPR                 0x00000005
+#define DIR_UPL                 0x00000006
+#define DIR_DWR                 0x00000009
+#define DIR_DWL                 0x0000000A
+#define DIR_LR                  0x00000003
 
-#define GAME_PAUSED         0x00000001
-#define GAME_PLAY           0x00000002
-#define GAME_MENU           0x00000004
-#define GAME_EDIT           0x00000008
-#define GAME_EDIT_NOANIM    0x00000010
-#define GAME_TEXT_INPUT     0x00000020
+//Game states
+#define GAME_PAUSED             0x00000001
+#define GAME_PLAY               0x00000002
+#define GAME_MENU               0x00000004
+#define GAME_EDIT               0x00000008
+#define GAME_EDIT_NOANIM        0x00000010
+#define GAME_TEXT_INPUT         0x00000020
 
+//Animation types
+#define ATYPE_ONCE              0x00000001
+#define ATYPE_ONCE_END          0x00000002
+#define ATYPE_LOOP              0x00000004
+#define ATYPE_SWING             0x00000008
+#define ATYPE_ONCE_REV          0x00000010
+#define ATYPE_ONCE_END_REV      0x00000020
+#define ATYPE_LOOP_REV          0x00000040
+#define ATYPE_SWING_REV         0x00000080
+#define ATYPE_ALL_ONCE          0x00000033
+#define ATYPE_ALL_LSTART        0x00000021
+#define ATYPE_ALL_LEND          0x00000012
+#define ATYPE_ALL_LOOP          0x00000044
+#define ATYPE_ALL_SWING         0x00000088
+#define ATYPE_ALL_NORMAL        0x0000000F
+#define ATYPE_ALL_REV           0x000000F0
+
 enum ConfigKey {
     KEY_START,
     KEY_LEFT,
@@ -91,6 +108,30 @@
     KEY_NOANIM
 };
 
+enum BasePointType {
+    BP_LU,
+    BP_LM,
+    BP_LD,
+    BP_MU,
+    BP_MM,
+    BP_MD,
+    BP_RU,
+    BP_RM,
+    BP_RD
+};
+
+enum AllignType {
+    AT_LU,
+    AT_LM,
+    AT_LD,
+    AT_MU,
+    AT_MM,
+    AT_MD,
+    AT_RU,
+    AT_RM,
+    AT_RD
+};
+
 /**\brief Collision type
 
 */
@@ -118,11 +159,21 @@
 
 */
 struct Frame {
-    SDL_Surface* image;
-    //Frame position (Source Rectangle)
-    SDL_Rect    pos;
+        Frame(SDL_Surface*,SDL_Rect);
+        Frame();
+        SDL_Surface* image;
+        //Frame position (Source Rectangle)
+        SDL_Rect    pos;
 };
 
+/**\brief Image structure
+
+*/
+struct Image {
+    SDL_Surface* surface;
+    std::vector<SDL_Rect> description;
+};
+
 //global functions
 //@{
 /// Quits the game with a error code

Modified: trunk/src/events.cpp
===================================================================
--- trunk/src/events.cpp	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/src/events.cpp	2005-09-03 12:40:31 UTC (rev 139)
@@ -57,8 +57,10 @@
   anim(runanim),
   del(delanim),
   sound(asound) {
-    if (anim) state|=ESTATE_ANIM;
-    if (anim!=NULL) duration=30000;
+    if (anim) {
+        state|=ESTATE_ANIM;
+        duration=30000;
+    }
 }
 Uint16 AnimEvent::update(Uint16 dt) {
     Uint16 evstate=Event::update(dt);

Modified: trunk/src/gfxeng.cpp
===================================================================
--- trunk/src/gfxeng.cpp	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/src/gfxeng.cpp	2005-09-03 12:40:31 UTC (rev 139)
@@ -23,7 +23,7 @@
     shift.x=0;
     shift.y=0;
     resize(config.width, config.height);
-    lifeimage=new Animation(imgcache->loadImage("life.bmp"));
+    lifeimage=new Animation(imgcache->loadImage(1,"life.bmp"));
 }
 
 GraphicsEngine::~GraphicsEngine() {
@@ -155,22 +155,19 @@
 
     tmprect=*scenario->area;
     srcpos=scenario->background->getFrame().pos;
-    shiftMapArea(tmprect,*scenario->background->getCurPos());
     SDL_BlitSurface(scenario->background->getFrame().image,&srcpos,screen,shiftMapArea(tmprect,shift));
     
     object_iterator obit=scenario->pool->objectspool.begin();
     while (obit!=scenario->pool->objectspool.end()) {
-        tmprect=*((*obit)->getPos());
+        tmprect=((*obit)->getDrawPos());
         srcpos=(*obit)->getFrame().pos;
-        shiftMapArea(tmprect,*((*obit)->getCurPos()));
         SDL_BlitSurface((*obit)->getFrame().image,&srcpos,screen,shiftMapArea(tmprect,shift));
         ++obit;
     }
 
     if (game_mode&GAME_PLAY && scenario->player!=NULL) {
-        tmprect=*(scenario->player->getPos());
+        tmprect=(scenario->player->getDrawPos());
         srcpos=scenario->player->getFrame().pos;
-        shiftMapArea(tmprect,*(scenario->player->getCurPos()));
         SDL_BlitSurface(scenario->player->getFrame().image,&srcpos,screen,shiftMapArea(tmprect,shift));
     }
 }

Modified: trunk/src/imgcache.cpp
===================================================================
--- trunk/src/imgcache.cpp	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/src/imgcache.cpp	2005-09-03 12:40:31 UTC (rev 139)
@@ -3,37 +3,62 @@
 #include "imgcache.h"
 
 
-ImageCache::ImageCache() {
-    not_found="no_file.bmp";
+ImageCache::ImageCache():
+  not_found("no_file.bmp") {
 }
 ImageCache::~ImageCache() {
-    map<pair<string,double>, SDL_Surface*>::iterator imgit=imgcache.begin();
+    map<pair<string,double>, Image>::iterator imgit=imgcache.begin();
     while (imgit != imgcache.end()) {
-        SDL_FreeSurface((*imgit).second);
-        imgcache.erase(imgit++);
+        SDL_FreeSurface((*imgit).second.surface);
+        imgcache.erase(imgit);
+        imgit=imgcache.begin();
     }
 }
 
-//TODO: maybe replace double scale_factor by string scale_format or sthg like that
-SDL_Surface* ImageCache::loadImage(string imagename, double scale_factor) {
+SDL_Rect& ImageCache::scaleRectangle(SDL_Rect& base_rect, double scale_factor) {
+    base_rect.x=(Sint16)(base_rect.x*scale_factor);
+    base_rect.y=(Sint16)(base_rect.y*scale_factor);
+    base_rect.w=(Uint16)(base_rect.w*scale_factor);
+    base_rect.h=(Uint16)(base_rect.h*scale_factor);
+    return base_rect;
+}
+
+std::vector<SDL_Rect>& ImageCache::scaleDescription(std::vector<SDL_Rect>& description, double scale_factor) {
+    for (Uint16 i=0; i<description.size(); i++) {
+        scaleRectangle(description[i],scale_factor);
+    }
+    return description;
+}
+
+Image& ImageCache::scaleImage(Image& original_image, double scale_factor) {
+    SDL_Surface* newsurface=zoomSurface(original_image.surface, scale_factor, scale_factor, 1);
+    SDL_FreeSurface(original_image.surface);
+    original_image.surface=newsurface;
+    scaleDescription(original_image.description, scale_factor);
+    return original_image;
+}
+
+Image& ImageCache::loadImage(std::vector<SDL_Rect> image_desc, string imagename, double scale_factor) {
+    //negative values are taken as positive reciproc
+    if (scale_factor<0) scale_factor=-1/scale_factor;
     //default is not_found
     if (imagename=="") {
         imagename=not_found;
         scale_factor=1;
     }
         
-    map<pair<string,double>, SDL_Surface*>::iterator imgit=imgcache.find(make_pair(imagename,scale_factor));
+    map<pair<string,double>, Image>::iterator imgit=imgcache.find(make_pair(imagename,scale_factor));
     
     // Image is not yet cached
     if (imgit==imgcache.end()) {
         string loadfile=config.datadir+imagename;
-        SDL_Surface* tmpimg=NULL;
-        SDL_Surface* returnimg=NULL;
+        SDL_Surface* tmp_surface=NULL;
+        Image return_image;
         // Loading
         #ifdef SDL_IMAGE
-        if ((tmpimg=IMG_Load(loadfile.c_str())) == NULL) {
+        if ((tmp_surface=IMG_Load(loadfile.c_str())) == NULL) {
         #else
-        if ((tmpimg=SDL_LoadBMP(loadfile.c_str())) == NULL) {
+        if ((tmp_surface=SDL_LoadBMP(loadfile.c_str())) == NULL) {
         #endif
             cout << "Couldn't load the image: " << imagename << endl;
             //Even the fallback image was not found
@@ -41,47 +66,184 @@
                 quitGame(3);
             //Try to load the fallback image...
             } else {
-                return loadImage(not_found);
+                std::vector<SDL_Rect> empty_vector;
+                return loadImage(empty_vector,not_found);
             }
         // Preprocessing
         } else {
+            return_image.surface=tmp_surface;
+            // if no description is given consider this as one big image
+            if (image_desc.empty()) {
+                SDL_Rect whole_image_rect;
+                whole_image_rect.x=0;
+                whole_image_rect.y=0;
+                whole_image_rect.w=return_image.surface->w;
+                whole_image_rect.h=return_image.surface->h;
+                image_desc.push_back(whole_image_rect);
+            }
+            return_image.description=image_desc;
             // About ColorKeys: I'm not sure anymore what is necessary and what not, as some stuff is now
             // also done in SDL_rotozoom.cpp, at least it seems to work this way...
             // Image's colorkey have to be set before (if unset) as the SCALING changes the color values
             #ifdef ALPHA
-            if (!(tmpimg->flags & (SDL_SRCCOLORKEY|SDL_SRCALPHA))) {
+            if (!(tmp_surface->flags & (SDL_SRCCOLORKEY|SDL_SRCALPHA))) {
             #else
-            if (!(tmpimg->flags & (SDL_SRCCOLORKEY))) {
+            if (!(tmp_surface->flags & (SDL_SRCCOLORKEY))) {
             #endif
-                SDL_SetColorKey(tmpimg, SDL_SRCCOLORKEY|SDL_RLEACCEL, SDL_MapRGB(tmpimg->format,255,0,255));
+                SDL_SetColorKey(return_image.surface, SDL_SRCCOLORKEY|SDL_RLEACCEL, SDL_MapRGB(return_image.surface->format,255,0,255));
             }
-            // SCALING
-            if (scale_factor!=1) tmpimg=scaleImage(tmpimg,scale_factor);
+            // SCALING (we need to assign tmp_surface a value again to have a valid SDL_FreeSurface...)
+            if (scale_factor!=1) tmp_surface=(scaleImage(return_image,scale_factor)).surface;
             // Image's colorkey
-            if (tmpimg->flags & SDL_SRCCOLORKEY) {
-                SDL_SetColorKey(tmpimg, SDL_SRCCOLORKEY|SDL_RLEACCEL, tmpimg->format->colorkey);
-                returnimg=SDL_DisplayFormat(tmpimg);
+            if (return_image.surface->flags & SDL_SRCCOLORKEY) {
+                SDL_SetColorKey(return_image.surface, SDL_SRCCOLORKEY|SDL_RLEACCEL, return_image.surface->format->colorkey);
+                return_image.surface=SDL_DisplayFormat(return_image.surface);
             #ifdef ALPHA
             // Alpha
-            } else if (tmpimg->flags & SDL_SRCALPHA) {
-                SDL_SetAlpha(tmpimg, SDL_SRCALPHA|SDL_RLEACCEL, tmpimg->format->alpha);
-                returnimg=SDL_DisplayFormatAlpha(tmpimg);
+            } else if (return_image.surface->flags & SDL_SRCALPHA) {
+                SDL_SetAlpha(return_image.surface, SDL_SRCALPHA|SDL_RLEACCEL, return_image.surface->format->alpha);
+                return_image.surface=SDL_DisplayFormatAlpha(return_image.surface);
             #endif
             // Our own colorkey (0xff00ff)
             } else {
-                SDL_SetColorKey(tmpimg, SDL_SRCCOLORKEY|SDL_RLEACCEL, SDL_MapRGB(tmpimg->format,255,0,255));
-                returnimg=SDL_DisplayFormat(tmpimg);
+                SDL_SetColorKey(return_image.surface, SDL_SRCCOLORKEY|SDL_RLEACCEL, SDL_MapRGB(return_image.surface->format,255,0,255));
+                return_image.surface=SDL_DisplayFormat(return_image.surface);
             }
-            SDL_FreeSurface(tmpimg);
+            SDL_FreeSurface(tmp_surface);
         }
-        imgcache.insert(make_pair(make_pair(imagename,scale_factor),returnimg));
-        return returnimg;
+        // Nice return statement, isn't it ;-)))
+        return (*(imgcache.insert(make_pair(make_pair(imagename,scale_factor),return_image))).first).second;
     // Return the existing Image in cache...
     } else return (*imgit).second;
 }
 
-inline SDL_Surface* ImageCache::scaleImage(SDL_Surface* original_image, double scale_factor) {
-    SDL_Surface* scaled_image=zoomSurface(original_image, scale_factor, scale_factor, 1);
-    SDL_FreeSurface(original_image);
-    return scaled_image;
+Image& ImageCache::loadImage(string imagename, double scale_factor, string image_desc_file) {
+    //negative values are taken as positive reciproc
+    if (scale_factor<0) scale_factor=-1/scale_factor;
+    if (image_desc_file.empty()) image_desc_file=imagename+".dsc";
+
+    /* Parse image_desc_file */
+    ifstream file;
+    string tmpline;  
+    string loadfile=config.datadir+image_desc_file;
+    std::vector<SDL_Rect> description;
+    SDL_Rect tmp_rect;
+
+    file.open(loadfile.c_str());
+    if (!file) {
+        cout << "Failed to open the image description file: " << loadfile << " not found!" << endl;
+    } else {
+        cout << "Loading image description: " << loadfile << endl;
+
+        string arg1,arg2,arg3,arg4,arg5,arg6;
+        Uint16 description_type=DESC_NONE;
+
+        while (getline(file,tmpline)) {
+            arg1=arg2=arg3=arg4=arg5=arg6="";
+            std::istringstream tmpstream(tmpline);
+            tmpstream >> arg1 >> arg2 >> arg3 >> arg4 >> arg5 >> arg6;
+
+            if (arg1 == "DESCRIPTION") {
+                if (arg2 == "LVLANIM") {
+                    description_type=DESC_LVLANIM;
+                } else if (arg2 == "FIX_RECT") {
+                    if (arg3.empty() || arg4.empty() || arg5.empty() || arg6.empty()) {
+                        description_type=DESC_NONE;
+                    } else {
+                        tmp_rect.x=atoi(arg3.c_str());
+                        tmp_rect.y=atoi(arg4.c_str());
+                        tmp_rect.w=atoi(arg5.c_str());
+                        tmp_rect.h=atoi(arg6.c_str());
+                        /* Load Image Case 2*/
+                        return loadImage(tmp_rect,imagename,scale_factor);
+                    }
+                } else if (arg2 == "FIX_HOR_WS") {
+                    if (arg3.empty() || arg4.empty()) {
+                        description_type=DESC_NONE;
+                    } else {
+                        /* Load Image Case 3*/
+                        return loadImage(atoi(arg3.c_str()),atoi(arg4.c_str()),imagename,scale_factor);
+                    }
+                } else if (arg2 == "FIX_HOR_NUM") {
+                    if (arg3.empty()) {
+                        description_type=DESC_NONE;
+                    } else {
+                        /* Load Image Case 4*/
+                        return loadImage(atoi(arg3.c_str()),imagename,scale_factor);
+                    }
+                } else {
+                    description_type=DESC_NONE;
+                }
+            }
+        
+            if (description_type==DESC_LVLANIM) {
+                if (arg1.empty() || arg2.empty() || arg3.empty() || arg4.empty()) {
+                } else {
+                    tmp_rect.x=atoi(arg1.c_str());
+                    tmp_rect.y=atoi(arg2.c_str());
+                    tmp_rect.w=atoi(arg3.c_str());
+                    tmp_rect.h=atoi(arg4.c_str());
+                    description.push_back(tmp_rect);
+                }
+            }
+        }
+
+        file.close();
+        file.clear();
+    }
+
+    /* Load Image Case 1 */
+    return loadImage(description,imagename,scale_factor);
 }
+
+Image& ImageCache::loadImage(SDL_Rect base_rect, string imagename, double scale_factor) {
+    //negative values are taken as positive reciproc
+    if (scale_factor<0) scale_factor=-1/scale_factor;
+    std::vector<SDL_Rect> description;
+    if (imagename=="" || base_rect.w==0 || base_rect.h==0) return loadImage(description,imagename,scale_factor);
+    Image& img=loadImage(description,imagename,scale_factor);
+    if (scale_factor != 1) scaleRectangle(base_rect,scale_factor);
+    SDL_Rect cur_rect=base_rect;
+
+    Uint16 x=base_rect.x;
+    Uint16 y=base_rect.y;
+    while (y<=(img.surface->h-base_rect.h)) {
+        cur_rect.y=y;
+        x=base_rect.x;
+        while (x<=(img.surface->w-base_rect.w)) {
+            cur_rect.x=x;
+            description.push_back(cur_rect);
+            x+=base_rect.w;
+        }
+        y+=base_rect.h;
+    }
+
+    img.description=description;
+    return img;
+}
+
+Image& ImageCache::loadImage(Uint16 num_frames, string imagename, double scale_factor) {
+    //negative values are taken as positive reciproc
+    if (scale_factor<0) scale_factor=-1/scale_factor;
+    std::vector<SDL_Rect> description;
+    Image& img=loadImage(description,imagename,scale_factor);
+    SDL_Rect base_rectangle;
+    base_rectangle.x=0;
+    base_rectangle.y=0;
+    base_rectangle.w=(Uint16)(img.surface->w*1.0/num_frames/scale_factor);
+    base_rectangle.h=(Uint16)(img.surface->h*1.0/scale_factor);
+    return loadImage(base_rectangle,imagename,scale_factor);
+}
+
+Image& ImageCache::loadImage(Uint16 width, Uint16 shift, string imagename, double scale_factor) {
+    //negative values are taken as positive reciproc
+    if (scale_factor<0) scale_factor=-1/scale_factor;
+    std::vector<SDL_Rect> description;
+    Image& img=loadImage(description,imagename,scale_factor);
+    SDL_Rect base_rectangle;
+    base_rectangle.x=shift;
+    base_rectangle.y=0;
+    base_rectangle.w=(Uint16)(width*1.0/scale_factor);
+    base_rectangle.h=(Uint16)(img.surface->h*1.0/scale_factor);
+    return loadImage(base_rectangle,imagename,scale_factor);
+}

Modified: trunk/src/imgcache.h
===================================================================
--- trunk/src/imgcache.h	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/src/imgcache.h	2005-09-03 12:40:31 UTC (rev 139)
@@ -1,6 +1,9 @@
 #ifndef DEF_IMGCACHE_H
 #define DEF_IMGCACHE_H 1
 
+#define DESC_NONE               0x00000000
+#define DESC_LVLANIM            0x00000001
+
 /** \brief Caches images.
 
     Caches images supported by SDL_image according to their name
@@ -13,12 +16,20 @@
         /// Loads an image if it isn't already contained in the pool
         /// according to it's image name. If the image is not found
         /// it tries to load a fallback image (not_found).
-        SDL_Surface* loadImage(string imagename="", double scale_factor=1);
+        //@{
+        Image& loadImage(std::vector<SDL_Rect> image_desc, string imagename, double scale_factor=1);
+        Image& loadImage(string imagename, double scale_factor=1, string image_desc_file="");
+        Image& loadImage(Uint16 num_frames, string imagename, double scale_factor=1);
+        Image& loadImage(Uint16 width, Uint16 shift, string imagename, double scale_factor=1);
+        Image& loadImage(SDL_Rect base_rect, string imagename, double scale_factor=1);
+        //@}
     private:
-        std::map<pair<string,double>,SDL_Surface*> imgcache;
+        std::map<pair<string,double>,Image> imgcache;
         string not_found;
     private:
-        inline SDL_Surface* scaleImage(SDL_Surface* original_image, double scale_factor);
+        SDL_Rect& scaleRectangle(SDL_Rect& base_rect, double scale_factor);
+        std::vector<SDL_Rect>& scaleDescription(std::vector<SDL_Rect>& description, double scale_factor);
+        Image& scaleImage(Image& original_image, double scale_factor);
 };
 
 #endif

Modified: trunk/src/lost_penguins.cpp
===================================================================
--- trunk/src/lost_penguins.cpp	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/src/lost_penguins.cpp	2005-09-03 12:40:31 UTC (rev 139)
@@ -44,8 +44,8 @@
     cout << "SoundEngine...\n";
     sfxeng=new SoundsEngine();
     cout << "Fonts...\n";
-    font=new Font(imgcache->loadImage("font_arial_white_16_01.png"));
-    font2=new Font(imgcache->loadImage("font_arial_red_16_01.png"));
+    font=new Font(imgcache->loadImage(1,"font_arial_white_16_01.png").surface);
+    font2=new Font(imgcache->loadImage(1,"font_arial_red_16_01.png").surface);
     cout << "InputHandler...\n";
     input=new InputHandler();
     cout << "Initializing Scenario...\n";

Modified: trunk/src/monsters_common.cpp
===================================================================
--- trunk/src/monsters_common.cpp	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/src/monsters_common.cpp	2005-09-03 12:40:31 UTC (rev 139)
@@ -73,17 +73,12 @@
     }
 }
 
-void Monster::updateAnimState(bool change) {
-    if (!change) {
-    } else if (state&STATE_LEFT) {
+void Monster::updateAnimState() {
+    if (state&STATE_LEFT) {
         animation=im_left;   
     } else {   
         animation=im_right;
     }
-    curpos.w=animation->getWidth();
-    curpos.h=animation->getHeight();   
-    curpos.x=(Uint16)((pos.w-curpos.w)/2);
-    curpos.y=(pos.h-curpos.h);
 }
 
 void Monster::idle(Uint16 dt) {

Modified: trunk/src/monsters_common.h
===================================================================
--- trunk/src/monsters_common.h	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/src/monsters_common.h	2005-09-03 12:40:31 UTC (rev 139)
@@ -12,7 +12,7 @@
         Monster(string img, Sint16 xpos=0, Sint16 ypos=0, string name="Monster");
         virtual ~Monster();
         virtual void removedObject(Object*);
-        virtual void updateAnimState(bool change=true);
+        virtual void updateAnimState();
         virtual void idle(Uint16);
         virtual void fall(Uint16);
         virtual Uint16 hit(Uint16 direction, Weapon& weap);

Modified: trunk/src/objects/baleog.cpp
===================================================================
--- trunk/src/objects/baleog.cpp	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/src/objects/baleog.cpp	2005-09-03 12:40:31 UTC (rev 139)
@@ -10,19 +10,19 @@
 
 Baleog::Baleog(string imagename, Sint16 xcord, Sint16 ycord, string pname):
   Player(imagename,xcord,ycord,pname) {
-    im_left=new Animation(scenario->imgcache->loadImage("baleog1_left.bmp"));
-    im_right=new Animation(scenario->imgcache->loadImage("baleog1_right.bmp"));
-    im_run_left=new Animation(scenario->imgcache->loadImage("baleog1-run_left.png"),8,1000);
-    im_run_right=new Animation(scenario->imgcache->loadImage("baleog1-run_right.png"),8,1000);
+    im_left=loadAnimation(scenario->imgcache->loadImage(1,"baleog1_left.bmp"));
+    im_right=loadAnimation(scenario->imgcache->loadImage(1,"baleog1_right.bmp"));
+    im_run_left=loadAnimation(scenario->imgcache->loadImage(8,"baleog1-run_left.png"),1000,8);
+    im_run_right=loadAnimation(scenario->imgcache->loadImage(8,"baleog1-run_right.png"),1000,8);
     im_fall_left=im_left;
     im_fall_right=im_right;
     im_krit_left=im_left;
     im_krit_right=im_right;
-    im_land_left=new Animation(scenario->imgcache->loadImage("olaf1_land_left.bmp"),1,T_IRR,true);
-    im_land_right=new Animation(scenario->imgcache->loadImage("olaf1_land_right.bmp"),1,T_IRR,true);
+    im_land_left=loadAnimation(scenario->imgcache->loadImage(1,"olaf1_land_left.bmp"),T_IRR,1,ATYPE_ONCE_END);
+    im_land_right=loadAnimation(scenario->imgcache->loadImage(1,"olaf1_land_right.bmp"),T_IRR,1,ATYPE_ONCE_END);
     weapon=Weapon(-1,W_STRIKE);
-    im_sword_left=new Animation(scenario->imgcache->loadImage("BaleogCyborg_Slash_left.png"),8,1000,true);
-    im_sword_right=new Animation(scenario->imgcache->loadImage("BaleogCyborg_Slash_right.png"),8,1000,true);
+    im_sword_left=loadAnimation(scenario->imgcache->loadImage(8,"BaleogCyborg_Slash_left.png"),1000,8,ATYPE_ONCE_END);
+    im_sword_right=loadAnimation(scenario->imgcache->loadImage(8,"BaleogCyborg_Slash_right.png"),1000,8,ATYPE_ONCE_END);
     au_sword=scenario->sndcache->loadWAV("swrdsw2.wav");
 }
 

Modified: trunk/src/objects/erik.cpp
===================================================================
--- trunk/src/objects/erik.cpp	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/src/objects/erik.cpp	2005-09-03 12:40:31 UTC (rev 139)
@@ -15,16 +15,16 @@
   jump(V_JUMP),
   jump2(V_JUMP2) {
     weapon=Weapon(-1,W_PRESSURE,WS_PRESSURE);
-    im_left=new Animation(scenario->imgcache->loadImage("erik1_left.bmp"));
-    im_right=new Animation(scenario->imgcache->loadImage("erik1_right.bmp"));
+    im_left=loadAnimation(scenario->imgcache->loadImage("erik1_left.bmp"));
+    im_right=loadAnimation(scenario->imgcache->loadImage(1,"erik1_right.bmp"));
     im_run_right=im_right;
     im_run_left=im_left;
     im_fall_left=im_left;
     im_fall_right=im_right;
     im_krit_left=im_left;
     im_krit_right=im_right;
-    im_land_left=new Animation(scenario->imgcache->loadImage("olaf1_land_left.bmp"),1,T_IRR,true);
-    im_land_right=new Animation(scenario->imgcache->loadImage("olaf1_land_right.bmp"),1,T_IRR,true);
+    im_land_left=loadAnimation(scenario->imgcache->loadImage(1,"olaf1_land_left.bmp"),T_IRR,1,ATYPE_ONCE_END);
+    im_land_right=loadAnimation(scenario->imgcache->loadImage(1,"olaf1_land_right.bmp"),T_IRR,1,ATYPE_ONCE_END);
     au_jump=scenario->sndcache->loadWAV("rboots.wav");
     au_hit=scenario->sndcache->loadWAV("erikhit.wav");
     au_run=NULL;

Modified: trunk/src/objects/fang.cpp
===================================================================
--- trunk/src/objects/fang.cpp	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/src/objects/fang.cpp	2005-09-03 12:40:31 UTC (rev 139)
@@ -12,18 +12,18 @@
   Player(imagename,xcord,ycord,pname),
   jump(V_JUMP) {
     weapon=Weapon(-1,W_STRIKE);
-    im_left=new Animation(scenario->imgcache->loadImage("Fang_Breath_left.png"),4,1000);
-    im_right=new Animation(scenario->imgcache->loadImage("Fang_Breath_right.png"),4,1000);
-    im_run_left=new Animation(scenario->imgcache->loadImage("Fang_walk_left.png"),8,1000);
-    im_run_right=new Animation(scenario->imgcache->loadImage("Fang_walk_right.png"),8,1000);
+    im_left=loadAnimation(scenario->imgcache->loadImage(4,"Fang_Breath_left.png"),1000,4);
+    im_right=loadAnimation(scenario->imgcache->loadImage(4,"Fang_Breath_right.png"),1000,4);
+    im_run_left=loadAnimation(scenario->imgcache->loadImage(8,"Fang_walk_left.png"),1000,8);
+    im_run_right=loadAnimation(scenario->imgcache->loadImage(8,"Fang_walk_right.png"),1000,8);
     im_fall_left=im_left;
     im_fall_right=im_right;
     im_krit_left=im_left;
     im_krit_right=im_right;
-    im_land_left=new Animation(scenario->imgcache->loadImage("olaf1_land_left.bmp"),1,T_IRR,true);
-    im_land_right=new Animation(scenario->imgcache->loadImage("olaf1_land_right.bmp"),1,T_IRR,true);
-    im_claw_left=new Animation(scenario->imgcache->loadImage("Fang_Clawslash_left.png"),8,1000,true);
-    im_claw_right=new Animation(scenario->imgcache->loadImage("Fang_Clawslash_right.png"),8,1000,true);
+    im_land_left=loadAnimation(scenario->imgcache->loadImage(1,"olaf1_land_left.bmp"),T_IRR,1,ATYPE_ONCE_END);
+    im_land_right=loadAnimation(scenario->imgcache->loadImage(1,"olaf1_land_right.bmp"),T_IRR,1,ATYPE_ONCE_END);
+    im_claw_left=loadAnimation(scenario->imgcache->loadImage(8,"Fang_Clawslash_left.png"),1000,8,ATYPE_ONCE_END);
+    im_claw_right=loadAnimation(scenario->imgcache->loadImage(8,"Fang_Clawslash_right.png"),1000,8,ATYPE_ONCE_END);
     au_hit=scenario->sndcache->loadWAV("wolfhit.wav");
     au_claw=scenario->sndcache->loadWAV("wolfjmp1.wav");
     au_jump=scenario->sndcache->loadWAV("fangjump.wav");

Modified: trunk/src/objects/olaf.cpp
===================================================================
--- trunk/src/objects/olaf.cpp	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/src/objects/olaf.cpp	2005-09-03 12:40:31 UTC (rev 139)
@@ -12,28 +12,28 @@
 Olaf::Olaf(string imagename, Sint16 xcord, Sint16 ycord, string pname):
   Player(imagename,xcord,ycord,pname),
   fart(V_FART) {
-    im_left=new Animation(scenario->imgcache->loadImage("olaf1_left.bmp"));
-    im_right=new Animation(scenario->imgcache->loadImage("olaf1_right.bmp"));
-    im_run_left=new Animation(scenario->imgcache->loadImage("olaf1-run_left.png"),8,1000);
-    im_run_right=new Animation(scenario->imgcache->loadImage("olaf1-run_right.png"),8,1000);
+    im_left=loadAnimation(scenario->imgcache->loadImage(1,"olaf1_left.bmp"));
+    im_right=loadAnimation(scenario->imgcache->loadImage(1,"olaf1_right.bmp"));
+    im_run_left=loadAnimation(scenario->imgcache->loadImage(8,"olaf1-run_left.png"),1000,8);
+    im_run_right=loadAnimation(scenario->imgcache->loadImage(8,"olaf1-run_right.png"),1000,8);
     im_fall_left=im_left;
     im_fall_right=im_right;
     im_krit_left=im_left;
     im_krit_right=im_right;
-    im_land_left=new Animation(scenario->imgcache->loadImage("olaf1_land_left.bmp"),1,T_IRR,true);
-    im_land_right=new Animation(scenario->imgcache->loadImage("olaf1_land_right.bmp"),1,T_IRR,true);
+    im_land_left=loadAnimation(scenario->imgcache->loadImage(1,"olaf1_land_left.bmp"),T_IRR,1,ATYPE_ONCE_END);
+    im_land_right=loadAnimation(scenario->imgcache->loadImage(1,"olaf1_land_right.bmp"),T_IRR,1,ATYPE_ONCE_END);
 
-    im_small_left=new Animation(scenario->imgcache->loadImage("Olaf_Small_Walk_left.png"),7,0);
-    im_small_right=new Animation(scenario->imgcache->loadImage("Olaf_Small_Walk_right.png"),7,0);
-    im_run_small_left=new Animation(scenario->imgcache->loadImage("Olaf_Small_Walk_left.png"),7,500);
-    im_run_small_right=new Animation(scenario->imgcache->loadImage("Olaf_Small_Walk_right.png"),7,500);
-    im_shield_right=new Animation(scenario->imgcache->loadImage("olaf1_fall_shield_right.bmp"));
-    im_shield_left=new Animation(scenario->imgcache->loadImage("olaf1_fall_shield_left.bmp"));
+    im_small_left=loadAnimation(scenario->imgcache->loadImage(7,"Olaf_Small_Walk_left.png"),0,1);
+    im_small_right=loadAnimation(scenario->imgcache->loadImage(7,"Olaf_Small_Walk_right.png"),0,1);
+    im_run_small_left=loadAnimation(scenario->imgcache->loadImage(7,"Olaf_Small_Walk_left.png"),500,7);
+    im_run_small_right=loadAnimation(scenario->imgcache->loadImage(7,"Olaf_Small_Walk_right.png"),500,7);
+    im_shield_right=loadAnimation(scenario->imgcache->loadImage(1,"olaf1_fall_shield_right.bmp"));
+    im_shield_left=loadAnimation(scenario->imgcache->loadImage(1,"olaf1_fall_shield_left.bmp"));
     im_run_shield_right=im_shield_right;
     im_run_shield_left=im_shield_left;
     im_fall_shield_left=im_shield_left;
     im_fall_shield_right=im_shield_right;
-    im_die=new Animation(60,scenario->imgcache->loadImage("kuru.bmp"),12,2000,true);
+    im_die=loadAnimation(scenario->imgcache->loadImage(60,"kuru.bmp"),2000,12,0,ATYPE_ONCE_END);
     au_small=scenario->sndcache->loadWAV("blob.wav");
     au_big=scenario->sndcache->loadWAV("unblob.wav");
     au_fart=scenario->sndcache->loadWAV("fart1.wav");
@@ -54,9 +54,8 @@
     delete im_shield_left;
 }
 
-void Olaf::updateAnimState(bool change) {
-    if (!change) {
-    } else if (state&STATE_SMALL) {
+void Olaf::updateAnimState() {
+    if (state&STATE_SMALL) {
         if (state&STATE_LEFT) {
             if (state&STATE_MLEFT) animation=im_run_small_left;
             else animation=im_small_left;
@@ -85,10 +84,6 @@
         otype&=~OTYPE_DENSE_D;
         Player::updateAnimState();
     }
-    curpos.w=animation->getWidth();
-    curpos.h=animation->getHeight();
-    curpos.x=(Uint16)((pos.w-curpos.w)/2);
-    curpos.y=(pos.h-curpos.h);
 }
 
 void Olaf::in_left(Uint16 dt) {
@@ -114,10 +109,10 @@
     //Assume both images have the same dimension
     else tmpanim=im_orig;
     //IDEA: left/right edge instead of bottom?
-    tmppos.x+=(Sint16)((tmppos.w-tmpanim->getWidth())/2);
-    tmppos.y+=tmppos.h-tmpanim->getHeight();
-    tmppos.w=tmpanim->getWidth();
-    tmppos.h=tmpanim->getHeight();
+    tmppos.x+=(Sint16)((tmppos.w-tmpanim->getFrameDim().w)/2);
+    tmppos.y+=tmppos.h-tmpanim->getFrameDim().h;
+    tmppos.w=tmpanim->getFrameDim().w;
+    tmppos.h=tmpanim->getFrameDim().h;
     if (!(checkMove(tmppos,true).enter&DIR_ALL)) {
         pos=tmppos;
         if (small) {

Modified: trunk/src/objects/olaf.h
===================================================================
--- trunk/src/objects/olaf.h	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/src/objects/olaf.h	2005-09-03 12:40:31 UTC (rev 139)
@@ -19,7 +19,7 @@
         Olaf(string imagename, Sint16 xpos=0, Sint16 ypos=0, string name="Olaf");
         virtual ~Olaf();
         /// Additionally checks if Olaf is small and how he wears his shield
-        virtual void updateAnimState(bool change=true);
+        virtual void updateAnimState();
         virtual void in_left(Uint16);
         virtual void in_right(Uint16);
         /// \brief Olaf tries to shrink (if he was big)

Modified: trunk/src/objects/scorch.cpp
===================================================================
--- trunk/src/objects/scorch.cpp	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/src/objects/scorch.cpp	2005-09-03 12:40:31 UTC (rev 139)
@@ -12,16 +12,16 @@
   Player(imagename,xcord,ycord,pname),
   left_wings(SCORCH_MAX_WINGS),
   wing(V_FLY) {
-    im_left=new Animation(scenario->imgcache->loadImage("baleog1_left.bmp"));
-    im_right=new Animation(scenario->imgcache->loadImage("baleog1_right.bmp"));
-    im_run_left=new Animation(scenario->imgcache->loadImage("baleog1-run_left.png"),8,1000);
-    im_run_right=new Animation(scenario->imgcache->loadImage("baleog1-run_right.png"),8,1000);
+    im_left=loadAnimation(scenario->imgcache->loadImage(1,"baleog1_left.bmp"));
+    im_right=loadAnimation(scenario->imgcache->loadImage(1,"baleog1_right.bmp"));
+    im_run_left=loadAnimation(scenario->imgcache->loadImage(8,"baleog1-run_left.png"),1000,8);
+    im_run_right=loadAnimation(scenario->imgcache->loadImage(8,"baleog1-run_right.png"),1000,8);
     im_fall_left=im_left;
     im_fall_right=im_right;
     im_krit_left=im_left;
     im_krit_right=im_right;
-    im_land_left=new Animation(scenario->imgcache->loadImage("olaf1_land_left.bmp"),1,T_IRR,true);
-    im_land_right=new Animation(scenario->imgcache->loadImage("olaf1_land_right.bmp"),1,T_IRR,true);
+    im_land_left=loadAnimation(scenario->imgcache->loadImage(1,"olaf1_land_left.bmp"),T_IRR,1,ATYPE_ONCE_END);
+    im_land_right=loadAnimation(scenario->imgcache->loadImage(1,"olaf1_land_right.bmp"),T_IRR,1,ATYPE_ONCE_END);
     au_swing=scenario->sndcache->loadWAV("flapwngs.wav");
     au_tired=scenario->sndcache->loadWAV("flwings.wav");
     au_hit=scenario->sndcache->loadWAV("draghit.wav");

Modified: trunk/src/objects/zombie.cpp
===================================================================
--- trunk/src/objects/zombie.cpp	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/src/objects/zombie.cpp	2005-09-03 12:40:31 UTC (rev 139)
@@ -15,8 +15,8 @@
   au_attack(scenario->sndcache->loadWAV("clang.wav")),
   T_Attack_Bite(1500) {
     maxspeedx=80;
-    im_left=new Animation(scenario->imgcache->loadImage("olaf1_left.bmp"),2,1000);
-    im_right=new Animation(scenario->imgcache->loadImage("olaf1_right.bmp"),2,1000);
+    im_left=loadAnimation(scenario->imgcache->loadImage(2,"olaf1_left.bmp"),1000,2);
+    im_right=loadAnimation(scenario->imgcache->loadImage(2,"olaf1_right.bmp"),1000,2);
     weapon=Weapon(-1,W_STRIKE);
 }
 

Modified: trunk/src/objects_common.cpp
===================================================================
--- trunk/src/objects_common.cpp	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/src/objects_common.cpp	2005-09-03 12:40:31 UTC (rev 139)
@@ -10,19 +10,14 @@
 Object::Object(string imagename, Sint16 xcord, Sint16 ycord, string oname):
   state(NOTHING),
   event(NULL),
-  im_orig(new Animation(scenario->imgcache->loadImage(imagename))),
+  im_orig(loadAnimation(scenario->imgcache->loadImage(1,imagename))),
   otype(NOTHING),
   name(oname),
   delete_flag(false) {
     animation=im_orig;
+    pos=animation->getFrameDim();
     pos.x=xcord;
     pos.y=ycord;
-    pos.w=animation->getWidth();
-    pos.h=animation->getHeight();
-    curpos.w=pos.w;
-    curpos.h=pos.h;
-    curpos.x=0;
-    curpos.y=0;
     onum=++scenario->max_obj_num;
 }
 
@@ -64,7 +59,24 @@
     return ok;
 }
 
-const Frame& Object::getFrame() const {
+Animation* Object::loadAnimation(const Image& abase_image,
+                         Uint32 aduration,
+                         Uint16 aframes,
+                         Uint16 aanimation_type,
+                         Uint16 astart_pos,
+                         BasePointType abp_type, 
+                         AllignType aallign_type,
+                         Sint16 ashift_x, 
+                         Sint16 ashift_y) {
+    Animation* anim=new Animation(abase_image,aduration,aframes,aanimation_type,astart_pos,abp_type,aallign_type,ashift_x,ashift_y);
+    anim->setBasePos(&pos);
+    return anim;
+}
+
+SDL_Rect Object::getDrawPos() const {
+    return animation->getDrawPos();
+}
+const Frame Object::getFrame() const {
     return animation->getFrame();
 }
 bool Object::updateAnim(Uint16 dt) {
@@ -72,11 +84,13 @@
 }
 void Object::setAnim(Animation* anim) {
     animation=anim;
-    animation->start();
+    animation->setBasePos(&pos);
+    animation->runAnim();
 }
 void Object::resetAnimState() {
     animation=im_orig;
-    animation->setFrame(0);
+    animation->setBasePos(&pos);
+    animation->runAnim();
 }
 bool Object::isRunning() const {
     return animation->isRunning();

Modified: trunk/src/objects_common.h
===================================================================
--- trunk/src/objects_common.h	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/src/objects_common.h	2005-09-03 12:40:31 UTC (rev 139)
@@ -61,12 +61,8 @@
         SDL_Rect* getPos() {
             return &pos;
         }
-        //we want: bottom-middle of pos
-        //animation (image) changes (depending on State changes)
-        SDL_Rect* getCurPos() {
-            return &curpos;
-        }
-        const Frame& getFrame() const;
+        SDL_Rect getDrawPos() const;
+        const Frame getFrame() const;
         //@{
         Uint16 getType() const {
             return otype;
@@ -109,6 +105,16 @@
             delete this;
         }
         //@}
+        /// Load an animation bound onto this object
+        Animation* loadAnimation(const Image& abase_image,
+                                 Uint32 aduration=0,
+                                 Uint16 aframes=1,
+                                 Uint16 aanimation_type=ATYPE_LOOP,
+                                 Uint16 astart_pos=0,
+                                 BasePointType abp_type=BP_MD,
+                                 AllignType aallign_type=AT_MD,
+                                 Sint16 ashift_x=0,
+                                 Sint16 ashift_y=0);
         //Events (triggered animations/effects)
         //@{
         /// Clears the event field (sets it to NULL). This should only be used by
@@ -171,9 +177,6 @@
         Animation* im_orig;
         Animation* animation;
         ///\todo Document this!
-        //temporary information about where to _draw_ the animation frame:
-        //curpos.wh <= pos.wh, curpos.xy = positive dxy
-        SDL_Rect curpos;
         /// Upper left logical position of the object (used for decisions)
         SDL_Rect pos;
         //Object type

Modified: trunk/src/physics.cpp
===================================================================
--- trunk/src/physics.cpp	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/src/physics.cpp	2005-09-03 12:40:31 UTC (rev 139)
@@ -104,7 +104,7 @@
     character_iterator cit=scenario->pool->characterspool.begin();
     while (cit!=scenario->pool->characterspool.end()) {
         (*cit)->fall(dt);
-        (*cit)->updateAnimState(!((*cit)->getState(ESTATE_ANIM)));
+        if (!((*cit)->getState(ESTATE_ANIM))) (*cit)->updateAnimState();
         ++cit;
     }
     //update the animations of all objects
@@ -113,6 +113,7 @@
         if ((*obit)->getState(ESTATE_ANIM)) { 
             bool runs=(*obit)->updateAnim(dt);
             if (!runs) (*obit)->stopEvent();
+
         } else if ((*obit)->isRunning()) (*obit)->updateAnim(dt);
         ++obit;
     }
@@ -136,7 +137,7 @@
     character_iterator cit=scenario->pool->characterspool.begin();
     while (cit!=scenario->pool->characterspool.end()) {
         (*cit)->fall(dt);
-        (*cit)->updateAnimState(!((*cit)->getState(ESTATE_ANIM)));
+        if (!((*cit)->getState(ESTATE_ANIM))) (*cit)->updateAnimState();
         ++cit;
     }
     //update the animations of all objects

Modified: trunk/src/players_common.cpp
===================================================================
--- trunk/src/players_common.cpp	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/src/players_common.cpp	2005-09-03 12:40:31 UTC (rev 139)
@@ -57,7 +57,7 @@
 }
 
 Frame Player::getIcon() const {
-    return (im_right->getFrame(0));
+    return (im_right->getBaseFrame());
 }
 
 void Player::addEnter(std::set<Object *>& aset) {
@@ -146,9 +146,8 @@
     Character::setEvent(ev);
 }
 
-void Player::updateAnimState(bool change) {
-    if (!change) {
-    } else if (state&STATE_LEFT) {
+void Player::updateAnimState() {
+    if (state&STATE_LEFT) {
         if (state&STATE_FALL) {
             if (speed>V_KRIT) {
                 animation=im_krit_left;
@@ -173,10 +172,6 @@
             animation=im_right;
         }
     }
-    curpos.w=animation->getWidth();
-    curpos.h=animation->getHeight();
-    curpos.x=(Uint16)((pos.w-curpos.w)/2);
-    curpos.y=(pos.h-curpos.h);
 }
 
 void Player::idle(Uint16 dt) {

Modified: trunk/src/players_common.h
===================================================================
--- trunk/src/players_common.h	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/src/players_common.h	2005-09-03 12:40:31 UTC (rev 139)
@@ -56,7 +56,7 @@
         //@}
         //VIRTUAL METHODS
         //@{
-        virtual void updateAnimState(bool change=true);
+        virtual void updateAnimState();
         virtual void idle(Uint16);
         virtual void fall(Uint16);
         virtual Uint16 hit(Uint16 direction, Weapon& weap);

Modified: trunk/tools/lvl2magick.c
===================================================================
--- trunk/tools/lvl2magick.c	2005-09-03 11:58:44 UTC (rev 138)
+++ trunk/tools/lvl2magick.c	2005-09-03 12:40:31 UTC (rev 139)
@@ -278,7 +278,7 @@
     if (strcmp(config.data_file,"")==0) {
         snprintf(config.data_file,16,"%s.dat",config.basename);
     }
-    snprintf(config.geom_file,16,"%s.txt",config.basename);
+    snprintf(config.geom_file,16,"%s.dsc",config.basename);
 
     /* set colorkey in palette */
     lvl_palette[0][red]   = (unsigned char)(config.colorkey.red*255/MaxRGB);
@@ -651,11 +651,11 @@
     }
 
     /* Create the geometry file */
-    snprintf(buf,16,"%s.txt",config.basename);
+    snprintf(buf,16,"%s.dsc",config.basename);
     geom_file = fopen(buf,"w");
     geom_file = freopen(buf,"a",geom_file);
 
-    fprintf(geom_file,"LVLGEOM\n");
+    fprintf(geom_file,"DESCRIPTION LVLANIM\n");
     fprintf(geom_file,"Size %u %u\n\n",lvlanim_size,num_entries);
     for (i=0; i<lvlanim_size; i++) {
         fprintf(geom_file,"%s %u {\n",lvlanims[i].name,lvlanims[i].size);




More information about the lostpenguins-commits mailing list