1 /* map.h
2    Handles all information about the current map, including the individual cells.
3 
4    Copyright (C) 2000  Mathias Broxvall
5                        Yannick Perret
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 */
21 
22 #ifndef MAP_H
23 #define MAP_H
24 
25 #include <map>
26 #include "glHelp.h"
27 
28 // more simple like this...
29 #define CELL_ICE (1 << 0)
30 #define CELL_ACID (1 << 1)
31 #define CELL_SAND (1 << 2)
32 #define CELL_KILL (1 << 3)
33 #define CELL_TRAMPOLINE (1 << 4)
34 #define CELL_NOGRID (1 << 5)
35 #define CELL_TRACK (1 << 6)
36 #define CELL_NOLINENORTH (1 << 7)
37 #define CELL_NOLINESOUTH (1 << 8)
38 #define CELL_NOLINEEAST (1 << 9)
39 #define CELL_NOLINEWEST (1 << 10)
40 #define CELL_SHADE_FLAT (1 << 11)
41 
42 typedef struct gzFile_s *gzFile;
43 
44 class Cell {
45  public:
46   /* Note. if you add fields here you must update the dump, load functions as well as
47    * editMode::pasteRegion */
48 
49   float velocity[2], heights[5];
50   Color colors[5];
51   Color wallColors[4];
52   float sunken;           // used for trampoline effect
53   float waterHeights[5];  // absolute height of water in cell, values <= -100.0 is treated as
54                           // no water.
55 
56   int flags, texture;
57   bool displayListDirty;
58 
59   void dump(gzFile gp) const;
60   void load(class Map *map, gzFile gp, int version);
61 
62   Cell();
63   void getNormals(Coord3d normals[5]) const;
64   void getWaterNormals(Coord3d normals[5]) const;
65   Real getHeight(Real x, Real y) const;
66   Real getWaterHeight(Real x, Real y) const;
isWaterVisible()67   inline int isWaterVisible() const {
68     return heights[0] < waterHeights[0] || heights[1] < waterHeights[1] ||
69            heights[2] < waterHeights[2] || heights[3] < waterHeights[3] ||
70            heights[4] < waterHeights[4];
71   }
72   /*
73    * (0,1) NW---NE (1,1) = (x,y)
74    *       | \ / |
75    *       |  C  | C=(0.5,0.5)
76    *       | / \ |
77    * (0,0) SW---SE (1,0)
78    */
79   static const int NORTH = 1, SOUTH = 0, EAST = 2, WEST = 0, CENTER = 4;
80   static const int SW = SOUTH + WEST, NW = NORTH + WEST, SE = SOUTH + EAST, NE = NORTH + EAST;
81 };
82 
83 class Chunk {
84  public:
85   Chunk();
86   ~Chunk();
87   int xm, ym;
88   GLuint wall_vbo[2];
89   GLuint tile_vbo[2];
90   GLuint flag_vbo[2];
91   GLuint flui_vbo[2];
92   GLuint line_vbo[2];
93   GLuint wall_vao, tile_vao, flag_vao, flui_vao, line_vao;
94   GLfloat maxHeight, minHeight;
95   bool is_active, is_visible, is_updated;
96   int last_shown;
97 };
98 
99 class Map {
100  public:
101   explicit Map(char *mapname);
102   virtual ~Map();
103 
cell(int x,int y)104   inline Cell &cell(int x, int y) const {
105     int lx = std::max(std::min(x, width - 1), 0);
106     int ly = std::max(std::min(y, height - 1), 0);
107     return cells[lx + width * ly];
108   };
109   inline Chunk *chunk(int x, int y) const;
110   void markCellsUpdated(int x1, int y1, int x2, int y2, bool changed_walls);
111   int save(char *name, int x, int y);
112   void draw(int stage, const Coord3d &focus, GLfloat gameTime);
113   void fillChunkVBO(Chunk *c) const;
114   void drawFootprint(int x1, int y1, int x2, int y2, int kind);
115   void drawLoop(int x1, int y1, int x2, int y2, int kind);
116   void drawSpotRing(Real x1, Real y1, Real r, int kind);
getHeight(Real x,Real y)117   inline Real getHeight(Real x, Real y) const {
118     // the obvious alternative (int)-cast gets misoptimized under -O3
119     int ix = std::floor(x);
120     int iy = std::floor(y);
121     return cell(ix, iy).getHeight(x - ix, y - iy);
122   }
getWaterHeight(Real x,Real y)123   inline Real getWaterHeight(Real x, Real y) const {
124     int ix = std::floor(x);
125     int iy = std::floor(y);
126     return cell(ix, iy).getWaterHeight(x - ix, y - iy);
127   }
128 
129   int width;
130   int height;
131   int flags, isBonus;
132   char mapname[256], author[256];
133   int indexTranslation[256];  // translates indices when reading map.
134 
135   int tx_Ice, tx_Acid, tx_Sand, tx_Track, tx_Water, tx_1, tx_2, tx_3, tx_4;
136   Coord3d startPosition;
137   GLuint texture_Array;
138   GLuint flag_Array;
139 
140   static const int flagNone, flagFlashCenter, flagTranslucent, flagShowCross;
141   static const int mapFormatVersion;
142 
143  protected:
144  private:
145   Cell *cells;
146   mutable std::map<std::pair<int, int>, Chunk> chunks;
147 };
148 
149 #endif
150