nuclear@1: #include nuclear@1: #include nuclear@5: #include nuclear@1: #include "opengl.h" nuclear@1: #include "level.h" nuclear@1: #include "tile.h" nuclear@5: #include "tileset.h" nuclear@1: nuclear@1: Level::Level() nuclear@1: { nuclear@1: cell_size = 1.0; nuclear@1: nuclear@1: cells = 0; nuclear@1: xsz = ysz = 0; nuclear@1: } nuclear@1: nuclear@1: Level::~Level() nuclear@1: { nuclear@1: delete [] cells; nuclear@38: nuclear@38: for(auto cell : cell_list) { nuclear@38: delete cell; nuclear@38: } nuclear@1: } nuclear@1: nuclear@1: bool Level::load(const char *fname) nuclear@1: { nuclear@5: if(!fname) { nuclear@5: return false; nuclear@5: } nuclear@5: nuclear@5: TileSet *tileset = get_active_tileset(); nuclear@5: if(!tileset) { nuclear@5: fprintf(stderr, "level loading failed: no active tileset\n"); nuclear@5: return false; nuclear@5: } nuclear@5: Tile *deftile = tileset->get_tile("default"); nuclear@5: if(!deftile) { nuclear@5: fprintf(stderr, "level loading failed: active tileset has no default tile\n"); nuclear@5: return false; nuclear@5: } nuclear@5: nuclear@5: FILE *fp = fopen(fname, "r"); nuclear@5: if(!fp) { nuclear@5: fprintf(stderr, "failed to open level: %s: %s\n", fname, strerror(errno)); nuclear@5: return false; nuclear@5: } nuclear@5: nuclear@5: char buf[512]; nuclear@5: fgets(buf, sizeof buf, fp); nuclear@5: if(sscanf(buf, "SIZE %dx%d", &xsz, &ysz) != 2) { nuclear@5: fprintf(stderr, "invalid or corrupt level file: %s\n", fname); nuclear@5: fclose(fp); nuclear@5: return false; nuclear@5: } nuclear@5: printf("level size: %dx%d\n", xsz, ysz); nuclear@1: nuclear@1: cells = new GridCell*[xsz * ysz]; nuclear@1: memset(cells, 0, xsz * ysz * sizeof *cells); nuclear@1: nuclear@5: int y = 0; nuclear@5: GridCell **grid_row = cells; nuclear@5: nuclear@5: while(fgets(buf, sizeof buf, fp)) { nuclear@5: for(int i=0; i= ysz) { nuclear@5: break; nuclear@5: } nuclear@5: } nuclear@5: fclose(fp); nuclear@1: nuclear@1: return true; nuclear@1: } nuclear@1: nuclear@1: bool Level::save(const char *fname) const nuclear@1: { nuclear@1: return false; nuclear@1: } nuclear@1: nuclear@1: const GridCell *Level::get_cell(int x, int y) const nuclear@1: { nuclear@1: if(x < 0 || x >= xsz || y < 0 || y >= ysz) { nuclear@1: return 0; nuclear@1: } nuclear@1: return cells[y * xsz + x]; nuclear@1: } nuclear@1: nuclear@1: Vector3 Level::get_cell_pos(int x, int y) const nuclear@1: { nuclear@46: float posx = (float)x * cell_size; nuclear@46: float posy = (float)y * cell_size; nuclear@46: posx -= cell_size * (float)xsz / 2.0f; nuclear@46: posy -= cell_size * (float)ysz / 2.0f; nuclear@1: return Vector3(posx, 0, posy); nuclear@1: } nuclear@1: nuclear@23: unsigned int Level::get_cell_dirmask(int x, int y) const nuclear@23: { nuclear@23: unsigned int dmask = TILE_ALL; nuclear@23: if(y > 0 && get_cell(x, y - 1)) { nuclear@23: dmask &= ~TILE_NORTH; nuclear@23: } nuclear@23: if(y < ysz - 1 && get_cell(x, y + 1)) { nuclear@23: dmask &= ~TILE_SOUTH; nuclear@23: } nuclear@23: if(x > 0 && get_cell(x - 1, y)) { nuclear@23: dmask &= ~TILE_WEST; nuclear@23: } nuclear@23: if(x < xsz - 1 && get_cell(x + 1, y)) { nuclear@23: dmask &= ~TILE_EAST; nuclear@23: } nuclear@23: return dmask; nuclear@23: } nuclear@23: nuclear@38: void Level::update(unsigned long msec, float dt) nuclear@38: { nuclear@38: for(auto cell : cell_list) { nuclear@38: cell->update(msec, dt); nuclear@38: } nuclear@38: } nuclear@38: nuclear@1: void Level::draw() const nuclear@1: { nuclear@1: glMatrixMode(GL_MODELVIEW); nuclear@1: nuclear@1: for(int i=0; idraw(dmask); nuclear@1: glPopMatrix(); nuclear@1: } nuclear@1: } nuclear@1: } nuclear@1: } nuclear@1: nuclear@23: void Level::draw_lights() const nuclear@23: { nuclear@23: glMatrixMode(GL_MODELVIEW); nuclear@23: nuclear@23: for(int i=0; idraw_lights(dmask); nuclear@23: nuclear@23: glPopMatrix(); nuclear@23: } nuclear@23: } nuclear@23: } nuclear@23: } nuclear@23: nuclear@46: void Level::draw_post() const nuclear@46: { nuclear@46: glMatrixMode(GL_MODELVIEW); nuclear@46: nuclear@46: for(int i=0; idraw_post(dmask); nuclear@46: glPopMatrix(); nuclear@46: } nuclear@46: } nuclear@46: } nuclear@46: } nuclear@46: nuclear@1: void Level::draw_grid() const nuclear@1: { nuclear@1: float xlen = xsz * cell_size; nuclear@1: float ylen = ysz * cell_size; nuclear@1: nuclear@1: glPushAttrib(GL_ENABLE_BIT); nuclear@1: glDisable(GL_LIGHTING); nuclear@1: nuclear@1: glBegin(GL_LINES); nuclear@1: glColor3f(0.4, 0.4, 0.4); nuclear@1: nuclear@1: float y = -ylen / 2.0 - cell_size / 2.0; nuclear@1: for(int i=0; iget_unique_psys(); nuclear@45: int num_psattr = tile->get_unique_psys_count(); nuclear@45: nuclear@45: for(int i=0; iattr = *psattr[i]; nuclear@45: psys.push_back(emitter); nuclear@45: } nuclear@1: } nuclear@1: nuclear@38: void GridCell::update(unsigned long msec, float dt) nuclear@38: { nuclear@45: for(auto ps : psys) { nuclear@45: psys_update(ps, (float)msec / 1000.0f); nuclear@45: } nuclear@38: } nuclear@38: nuclear@5: void GridCell::draw(unsigned int draw_mask) const nuclear@1: { nuclear@23: for(auto tile : tiles) { nuclear@23: tile->draw(draw_mask); nuclear@1: } nuclear@1: } nuclear@23: nuclear@23: void GridCell::draw_lights(unsigned int draw_mask) const nuclear@23: { nuclear@23: for(auto tile : tiles) { nuclear@23: tile->draw_lights(draw_mask); nuclear@23: } nuclear@23: } nuclear@45: nuclear@45: void GridCell::draw_post(unsigned int draw_mask) const nuclear@45: { nuclear@45: for(auto tile : tiles) { nuclear@45: tile->draw_post(draw_mask); nuclear@45: } nuclear@45: for(auto ps : psys) { nuclear@45: psys_draw(ps); nuclear@45: } nuclear@45: }