dungeon_crawler

annotate prototype/src/level.cc @ 46:f3030df27110

debugging the particles
author John Tsiombikas <nuclear@mutantstargoat.com>
date Thu, 13 Sep 2012 06:33:51 +0300
parents dfd3a413ef9e
children aa9e28670ae2
rev   line source
nuclear@1 1 #include <stdio.h>
nuclear@1 2 #include <string.h>
nuclear@5 3 #include <errno.h>
nuclear@1 4 #include "opengl.h"
nuclear@1 5 #include "level.h"
nuclear@1 6 #include "tile.h"
nuclear@5 7 #include "tileset.h"
nuclear@1 8
nuclear@1 9 Level::Level()
nuclear@1 10 {
nuclear@1 11 cell_size = 1.0;
nuclear@1 12
nuclear@1 13 cells = 0;
nuclear@1 14 xsz = ysz = 0;
nuclear@1 15 }
nuclear@1 16
nuclear@1 17 Level::~Level()
nuclear@1 18 {
nuclear@1 19 delete [] cells;
nuclear@38 20
nuclear@38 21 for(auto cell : cell_list) {
nuclear@38 22 delete cell;
nuclear@38 23 }
nuclear@1 24 }
nuclear@1 25
nuclear@1 26 bool Level::load(const char *fname)
nuclear@1 27 {
nuclear@5 28 if(!fname) {
nuclear@5 29 return false;
nuclear@5 30 }
nuclear@5 31
nuclear@5 32 TileSet *tileset = get_active_tileset();
nuclear@5 33 if(!tileset) {
nuclear@5 34 fprintf(stderr, "level loading failed: no active tileset\n");
nuclear@5 35 return false;
nuclear@5 36 }
nuclear@5 37 Tile *deftile = tileset->get_tile("default");
nuclear@5 38 if(!deftile) {
nuclear@5 39 fprintf(stderr, "level loading failed: active tileset has no default tile\n");
nuclear@5 40 return false;
nuclear@5 41 }
nuclear@5 42
nuclear@5 43 FILE *fp = fopen(fname, "r");
nuclear@5 44 if(!fp) {
nuclear@5 45 fprintf(stderr, "failed to open level: %s: %s\n", fname, strerror(errno));
nuclear@5 46 return false;
nuclear@5 47 }
nuclear@5 48
nuclear@5 49 char buf[512];
nuclear@5 50 fgets(buf, sizeof buf, fp);
nuclear@5 51 if(sscanf(buf, "SIZE %dx%d", &xsz, &ysz) != 2) {
nuclear@5 52 fprintf(stderr, "invalid or corrupt level file: %s\n", fname);
nuclear@5 53 fclose(fp);
nuclear@5 54 return false;
nuclear@5 55 }
nuclear@5 56 printf("level size: %dx%d\n", xsz, ysz);
nuclear@1 57
nuclear@1 58 cells = new GridCell*[xsz * ysz];
nuclear@1 59 memset(cells, 0, xsz * ysz * sizeof *cells);
nuclear@1 60
nuclear@5 61 int y = 0;
nuclear@5 62 GridCell **grid_row = cells;
nuclear@5 63
nuclear@5 64 while(fgets(buf, sizeof buf, fp)) {
nuclear@5 65 for(int i=0; i<xsz; i++) {
nuclear@5 66 if(!buf[i] || buf[i] == '\r' || buf[i] == '\n') {
nuclear@5 67 grid_row += xsz - i;
nuclear@5 68 break;
nuclear@5 69 }
nuclear@5 70
nuclear@5 71 if(isalpha(buf[i]) || buf[i] == ' ') {
nuclear@38 72 GridCell *cell = new GridCell(deftile);
nuclear@38 73 *grid_row = cell;
nuclear@38 74 cell_list.push_back(*grid_row);
nuclear@5 75 }
nuclear@5 76 grid_row++;
nuclear@5 77 }
nuclear@5 78
nuclear@5 79 if(++y >= ysz) {
nuclear@5 80 break;
nuclear@5 81 }
nuclear@5 82 }
nuclear@5 83 fclose(fp);
nuclear@1 84
nuclear@1 85 return true;
nuclear@1 86 }
nuclear@1 87
nuclear@1 88 bool Level::save(const char *fname) const
nuclear@1 89 {
nuclear@1 90 return false;
nuclear@1 91 }
nuclear@1 92
nuclear@1 93 const GridCell *Level::get_cell(int x, int y) const
nuclear@1 94 {
nuclear@1 95 if(x < 0 || x >= xsz || y < 0 || y >= ysz) {
nuclear@1 96 return 0;
nuclear@1 97 }
nuclear@1 98 return cells[y * xsz + x];
nuclear@1 99 }
nuclear@1 100
nuclear@1 101 Vector3 Level::get_cell_pos(int x, int y) const
nuclear@1 102 {
nuclear@46 103 float posx = (float)x * cell_size;
nuclear@46 104 float posy = (float)y * cell_size;
nuclear@46 105 posx -= cell_size * (float)xsz / 2.0f;
nuclear@46 106 posy -= cell_size * (float)ysz / 2.0f;
nuclear@1 107 return Vector3(posx, 0, posy);
nuclear@1 108 }
nuclear@1 109
nuclear@23 110 unsigned int Level::get_cell_dirmask(int x, int y) const
nuclear@23 111 {
nuclear@23 112 unsigned int dmask = TILE_ALL;
nuclear@23 113 if(y > 0 && get_cell(x, y - 1)) {
nuclear@23 114 dmask &= ~TILE_NORTH;
nuclear@23 115 }
nuclear@23 116 if(y < ysz - 1 && get_cell(x, y + 1)) {
nuclear@23 117 dmask &= ~TILE_SOUTH;
nuclear@23 118 }
nuclear@23 119 if(x > 0 && get_cell(x - 1, y)) {
nuclear@23 120 dmask &= ~TILE_WEST;
nuclear@23 121 }
nuclear@23 122 if(x < xsz - 1 && get_cell(x + 1, y)) {
nuclear@23 123 dmask &= ~TILE_EAST;
nuclear@23 124 }
nuclear@23 125 return dmask;
nuclear@23 126 }
nuclear@23 127
nuclear@38 128 void Level::update(unsigned long msec, float dt)
nuclear@38 129 {
nuclear@38 130 for(auto cell : cell_list) {
nuclear@38 131 cell->update(msec, dt);
nuclear@38 132 }
nuclear@38 133 }
nuclear@38 134
nuclear@1 135 void Level::draw() const
nuclear@1 136 {
nuclear@1 137 glMatrixMode(GL_MODELVIEW);
nuclear@1 138
nuclear@1 139 for(int i=0; i<ysz; i++) {
nuclear@1 140 for(int j=0; j<xsz; j++) {
nuclear@1 141 const GridCell *cell = get_cell(j, i);
nuclear@1 142 if(cell) {
nuclear@1 143 Vector3 pos = get_cell_pos(j, i);
nuclear@1 144 glPushMatrix();
nuclear@1 145 glTranslatef(pos.x, pos.y, pos.z);
nuclear@1 146 glScalef(cell_size, cell_size, cell_size);
nuclear@5 147
nuclear@23 148 unsigned int dmask = get_cell_dirmask(j, i);
nuclear@5 149
nuclear@5 150 cell->draw(dmask);
nuclear@1 151 glPopMatrix();
nuclear@1 152 }
nuclear@1 153 }
nuclear@1 154 }
nuclear@1 155 }
nuclear@1 156
nuclear@23 157 void Level::draw_lights() const
nuclear@23 158 {
nuclear@23 159 glMatrixMode(GL_MODELVIEW);
nuclear@23 160
nuclear@23 161 for(int i=0; i<ysz; i++) {
nuclear@23 162 for(int j=0; j<xsz; j++) {
nuclear@23 163 const GridCell *cell = get_cell(j, i);
nuclear@23 164 if(cell) {
nuclear@23 165 Vector3 pos = get_cell_pos(j, i);
nuclear@23 166
nuclear@23 167 glPushMatrix();
nuclear@23 168 glTranslatef(pos.x, pos.y, pos.z);
nuclear@23 169 glScalef(cell_size, cell_size, cell_size);
nuclear@23 170
nuclear@23 171 unsigned int dmask = get_cell_dirmask(j, i);
nuclear@23 172 cell->draw_lights(dmask);
nuclear@23 173
nuclear@23 174 glPopMatrix();
nuclear@23 175 }
nuclear@23 176 }
nuclear@23 177 }
nuclear@23 178 }
nuclear@23 179
nuclear@46 180 void Level::draw_post() const
nuclear@46 181 {
nuclear@46 182 glMatrixMode(GL_MODELVIEW);
nuclear@46 183
nuclear@46 184 for(int i=0; i<ysz; i++) {
nuclear@46 185 for(int j=0; j<xsz; j++) {
nuclear@46 186 const GridCell *cell = get_cell(j, i);
nuclear@46 187 if(cell) {
nuclear@46 188 Vector3 pos = get_cell_pos(j, i);
nuclear@46 189 glPushMatrix();
nuclear@46 190 glTranslatef(pos.x, pos.y, pos.z);
nuclear@46 191 glScalef(cell_size, cell_size, cell_size);
nuclear@46 192
nuclear@46 193 unsigned int dmask = get_cell_dirmask(j, i);
nuclear@46 194
nuclear@46 195 cell->draw_post(dmask);
nuclear@46 196 glPopMatrix();
nuclear@46 197 }
nuclear@46 198 }
nuclear@46 199 }
nuclear@46 200 }
nuclear@46 201
nuclear@1 202 void Level::draw_grid() const
nuclear@1 203 {
nuclear@1 204 float xlen = xsz * cell_size;
nuclear@1 205 float ylen = ysz * cell_size;
nuclear@1 206
nuclear@1 207 glPushAttrib(GL_ENABLE_BIT);
nuclear@1 208 glDisable(GL_LIGHTING);
nuclear@1 209
nuclear@1 210 glBegin(GL_LINES);
nuclear@1 211 glColor3f(0.4, 0.4, 0.4);
nuclear@1 212
nuclear@1 213 float y = -ylen / 2.0 - cell_size / 2.0;
nuclear@1 214 for(int i=0; i<ysz; i++) {
nuclear@1 215 glVertex3f(-xlen / 2.0, 0, y);
nuclear@1 216 glVertex3f(xlen / 2.0, 0, y);
nuclear@1 217 y += cell_size;
nuclear@1 218 }
nuclear@1 219
nuclear@1 220 float x = -xlen / 2.0 - cell_size / 2.0;
nuclear@1 221 for(int i=0; i<xsz; i++) {
nuclear@1 222 glVertex3f(x, 0, -ylen / 2.0);
nuclear@1 223 glVertex3f(x, 0, ylen / 2.0);
nuclear@1 224 x += cell_size;
nuclear@1 225 }
nuclear@1 226 glEnd();
nuclear@1 227
nuclear@1 228 glPopAttrib();
nuclear@1 229 }
nuclear@1 230
nuclear@5 231
nuclear@38 232 GridCell::GridCell(Tile *tile)
nuclear@5 233 {
nuclear@5 234 if(tile) {
nuclear@45 235 add_tile(tile);
nuclear@5 236 }
nuclear@5 237 }
nuclear@5 238
nuclear@38 239 void GridCell::add_tile(Tile *tile)
nuclear@1 240 {
nuclear@45 241 if(!tile) {
nuclear@45 242 return;
nuclear@45 243 }
nuclear@45 244
nuclear@1 245 tiles.push_back(tile);
nuclear@45 246
nuclear@45 247 /* instanciate any particle systems */
nuclear@46 248 const struct psys_attributes * const *psattr = tile->get_unique_psys();
nuclear@45 249 int num_psattr = tile->get_unique_psys_count();
nuclear@45 250
nuclear@45 251 for(int i=0; i<num_psattr; i++) {
nuclear@45 252 struct psys_emitter *emitter = psys_create();
nuclear@45 253 emitter->attr = *psattr[i];
nuclear@45 254 psys.push_back(emitter);
nuclear@45 255 }
nuclear@1 256 }
nuclear@1 257
nuclear@38 258 void GridCell::update(unsigned long msec, float dt)
nuclear@38 259 {
nuclear@45 260 for(auto ps : psys) {
nuclear@45 261 psys_update(ps, (float)msec / 1000.0f);
nuclear@45 262 }
nuclear@38 263 }
nuclear@38 264
nuclear@5 265 void GridCell::draw(unsigned int draw_mask) const
nuclear@1 266 {
nuclear@23 267 for(auto tile : tiles) {
nuclear@23 268 tile->draw(draw_mask);
nuclear@1 269 }
nuclear@1 270 }
nuclear@23 271
nuclear@23 272 void GridCell::draw_lights(unsigned int draw_mask) const
nuclear@23 273 {
nuclear@23 274 for(auto tile : tiles) {
nuclear@23 275 tile->draw_lights(draw_mask);
nuclear@23 276 }
nuclear@23 277 }
nuclear@45 278
nuclear@45 279 void GridCell::draw_post(unsigned int draw_mask) const
nuclear@45 280 {
nuclear@45 281 for(auto tile : tiles) {
nuclear@45 282 tile->draw_post(draw_mask);
nuclear@45 283 }
nuclear@45 284 for(auto ps : psys) {
nuclear@45 285 psys_draw(ps);
nuclear@45 286 }
nuclear@45 287 }