src/Terrain.hh
changeset 406 a2e35ca66c74
parent 370 39e59dd36b6e
child 408 e6cfc44266af
--- a/src/Terrain.hh	Sat Jan 17 02:58:36 2009 +0200
+++ b/src/Terrain.hh	Tue Jan 20 22:00:24 2009 +0200
@@ -8,13 +8,26 @@
 #include "Types.hh"
 #include "Config.hh"
 
+/**
+ * Different types of terrain available
+ */
 enum TerrainType {
-    TERRAIN_EMPTY, 
-    TERRAIN_DIRT, 
-    TERRAIN_ROCK
+    /** Empty space, air */
+    TERRAIN_EMPTY   = 0x00,
+
+    /** Dirt, which can be destroyed/dug through */
+    TERRAIN_DIRT    = 0x01,
+
+    /** Indestructible rock */
+    TERRAIN_ROCK    = 0x02
 };
 
 /**
+ * Terrain "pixel" type
+ */
+typedef uint8_t TerrainPixel;
+
+/**
  * Terrain class. Represents game terrain and contains member
  * functions to manipulate terrain and get info about it.
  * 
@@ -25,57 +38,78 @@
  * and it uses pixelcoordinates internally.
  */ 
 class Terrain {
-public: // XXX: until we fix Network's access to this
-    std::vector<std::vector<TerrainType> > terrain;    
+protected:
+    /** The terrain data is stored as a linear array in row-major order, with width*height elements */
+    TerrainPixel *terrain_buf;
+
+    /** Terrain dimensions */
+    PixelDimension width, height;
     
-    /**
-     * Generates pixelbuffer from terrain. Should be used only on
-     * constructors because this is expected to be slow.
-     */
-    void generatePixelBuffer();
-
-protected:
-    // terrain dimensions
-    PixelDimension map_width, map_height;
-
-    // We can pre-render the terrain as a pixel buffer and then just modify this
+    /** We pre-render the textured terrain data for display */
     CL_PixelBuffer pixbuf;
 
-    // terrain texture
+    // XXX: terrain texture
     std::vector<std::vector<int> > texture;
 
     /**
      * Default constructor. The width/height are set to zero and the terrain is invalid until it gets updated
-     *
-     * @param scale The "real" width and height of the terrain.
      */
     Terrain (void);
 
     /**
      * Constructor.
      *
-     * @param scale The "real" width and height of the terrain.
-     * @param seed Random number generator seed used to create the
-     * terrain.
+     * @param width terrain width
+     * @param height terrain height
+     * @param seed andom number generator seed used to generate the random terrain.
      */
-    Terrain (PixelDimension map_width, PixelDimension map_height, int seed);
-
-    /**
-     * Copy constructor.
-     *
-     * @param t Terrain to be copied.
-     */
-    Terrain (const Terrain &t);
+    Terrain (PixelDimension width, PixelDimension height, int seed);
 
     /**
      * Destructor
      */
-    ~Terrain (void) {}
+    ~Terrain (void);
+
+private:
+    /* No copying */
+    Terrain (const Terrain &copy);
+    Terrain &operator= (const Terrain &copy);
 
 protected:
-    void generate_texture();
-    void noisifyPixel(CL_Color& col, PixelCoordinate pc);
+    /**
+     * Set induvidual pixel value, updates both terrain_buf and pixbuf
+     */
+    inline void setType (PixelDimension x, PixelDimension y, TerrainType t) {
+        terrain_buf[y * width + x] = (TerrainPixel) t;
 
+        // XXX: locking?
+        pixbuf.draw_pixel(x, y, getTexturePixel(x, y));
+    }
+
+    /**
+     * Generate random terrain using given seed
+     *
+     * @param seed seed for the random number generator
+     */
+    void generateTerrain (int seed);
+
+    /**
+     * Regenerates our pixbuf from the current terrain. This is a slow process, but using the pixbuffer directly
+     * greatly speeds up drawing.
+     */
+    void generatePixelBuffer (void);
+
+    /**
+     * Generates an area of random texture using a fractal-based algorithm, this can then be applied to the terrain
+     * pixels using noisifyPixel
+     */
+    void generateTexture();
+    
+    /**
+     * Applies noise generated using generateTexture to generate a slightly varying color for the terrain pixel
+     * at \a pc.
+     */
+    CL_Color getTexturePixel (PixelDimension x, PixelDimension y);
 
     /**
      * Scale parameter to "pixels"
@@ -83,12 +117,9 @@
      * @param x Scaled value
      * @return Corresponding value in pixels
      */
-    PixelDimension scale (float x) const;
-
-    /**
-     * Sets to color the correct color of pixel in (x,y)
-     */
-    void loadPixelColor (CL_Color& color, PixelCoordinate pc);
+    inline PixelDimension scale (float x) const {
+        return (int) x;
+    }
 
  public:
     /**
@@ -97,92 +128,94 @@
      * @param point Point in "real" units
      * @return Int vector
      */
-    PixelCoordinate getPixelCoordinate (Vector point) const;
+    inline PixelCoordinate getPixelCoordinate (Vector point) const {
+        return PixelCoordinate(scale(point.x), scale(point.y));
+    }
 
     /**
      * Return the terrain dimensions à la a PixelCoordinate
      */
-    PixelCoordinate getDimensions (void) const;
+    inline PixelCoordinate getDimensions (void) const {
+        return PixelCoordinate(width, height);
+    }
 
     /**
-     * Return the type of terrain at given position. Returns ROCK if
-     * given point is not inside terrain area.
+     * Return the type of terrain at given position. Returns TERRAIN_ROCK if given point is not inside terrain area.
      *
-     * @param x X coordinate
-     * @param y Y coordinate
-     * @return Terrain type
+     * @param x terrain x coordinate
+     * @param y terrain x coordinate
+     * @return terrain pixel type
      */
-    TerrainType getType (PixelDimension px, PixelDimension py) const;
-    TerrainType getType (PixelCoordinate pc) const;
-    TerrainType getType (Vector point) const;
+    TerrainType getType (PixelDimension x, PixelDimension y) const {
+        // XXX: optimize access by removing error checking?
+        if (x < 0 || y < 0 || x >= width || y >= height)
+            return TERRAIN_ROCK;
+
+        return (TerrainType) terrain_buf[y * width + x];
+    }
+
+    inline TerrainType getType (PixelCoordinate pc) const {
+        return getType(pc.x, pc.y);
+    }
+    
+    
+    inline TerrainType getType (Vector point) const {
+        return getType(getPixelCoordinate(point));
+    }
 
     /**
-     * Check if given point has some terrain.
+     * Get raw read-only terrain data buffer
      *
-     * @param point Point that is in scaled units.
+     * @see terrain_buf
+     */
+    const TerrainPixel* getTerrainBuffer (void) const;
+
+    /**
+     * Load new terrain data from given buffer. Must be the right size
+     *
+     * @see terrain_buf
+     */
+    void loadFromBuffer (const TerrainPixel *buf);
+
+    /**
+     * Check if the given point is terrain
      */
     bool collides (const Vector &point) const;
+
     /**
-     * Check if given line collides with terrain.
+     * Check if the given line collides with terrain
      *
-     * @param begin Line begin point in scaled units.
-     * @param end Line end point in scaled units.
+     * @param begin line starting point
+     * @param end line ending point
      */
     bool collides (const Vector &begin, const Vector &end) const;
     
     /**
-     * Remove a circular area from terrain.
+     * Remove a circular area of terrain
      *
-     * @param pos Circle center
-     * @param r Circle radius
+     * @param pos circle center
+     * @param r circle radius
      */ 
     void removeGround (const Vector &pos, float r);
 
     /**
-     * Return normal for the given point.
+     * Returns direction normal vector for the given \a point. 
      *
-     * @param point Point for which the normal is calculated.
-     * @return Normal vector ((0,0) if there's no terrain)
+     * \a point should be ground, and \a prevPoint air.
+     *
+     * @param point the ground that we collided into
+     * @param prevPoint position in air where we were before the collision
+     * @return direction ormal vector, or (0,0) if there's no terrain
      */
     Vector getNormal (Vector point, Vector prevPoint) const;
 
     /**
-     * Generate random terrain.
+     * Draw the terrain onto the given graphics context
      *
-     * @param seed Seed for the randomnumber generator.
-     */
-    void generateTerrain (int seed);
-
-    /**
-     * Draw the terrain for given graphicscontext.
-     *
-     * @param gc CL_GraphicContext
-     * @param camera - upper left corner of screen
+     * @param gc Graphics to draw on
+     * @param camera view position
      */
     virtual void draw (Graphics *g, PixelCoordinate camera = PixelCoordinate(0, 0));
-
-    /**
-     * Draw part of the terrain for given graphiscontext.
-     *
-     * @param gc CL_GraphicContext
-     * @param center Center of the rectangle drawn.
-     * @param dimension Dimensions of the rectangle.
-     */
-    //void draw(CL_GraphicContext &gc, Vector center, Vector dimensions);
-
-    /**
-     * Set terrain.
-     *
-     * @param terrain Terrain.
-     */
-    void setTerrain (const std::vector<std::vector<TerrainType> > &terrain);
-    
-    /**
-     * Get terrain.
-     *
-     * @return Terrain.
-     */
-    std::vector<std::vector<TerrainType> > getTerrain() const;
 };
 
 #endif