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@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@1: float posx = (x - xsz / 2) * cell_size; nuclear@1: float posy = (y - ysz / 2) * cell_size; 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@1: void Level::draw() const nuclear@1: { nuclear@1: glMatrixMode(GL_MODELVIEW); nuclear@1: nuclear@10: //draw_grid(); 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@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; idraw(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: }