nuclear@0: #include nuclear@0: #include nuclear@0: #include "level.h" nuclear@2: #include "datapath.h" nuclear@3: #include "opengl.h" nuclear@2: nuclear@2: using namespace tinyxml2; nuclear@0: nuclear@0: Level::Level() nuclear@0: { nuclear@0: } nuclear@0: nuclear@0: Level::~Level() nuclear@0: { nuclear@0: } nuclear@0: nuclear@0: bool Level::load(const char *fname) nuclear@0: { nuclear@2: push_data_path(); nuclear@2: add_data_path(fname); nuclear@2: nuclear@2: if(xml.LoadFile(fname) != 0) { nuclear@0: fprintf(stderr, "failed to load level: %s\n", fname); nuclear@2: pop_data_path(); nuclear@0: return false; nuclear@0: } nuclear@0: nuclear@1: if(strcmp(xml.RootElement()->Name(), "level") != 0) { nuclear@0: fprintf(stderr, "invalid level file: %s\n", fname); nuclear@2: pop_data_path(); nuclear@0: return false; nuclear@0: } nuclear@2: nuclear@2: XMLNode *node = xml.RootElement()->FirstChild(); nuclear@2: do { nuclear@2: XMLElement *elem = node->ToElement(); nuclear@2: if(elem) { nuclear@2: if(strcmp(elem->Name(), "map") == 0) { nuclear@2: LevelMap map; nuclear@2: nuclear@2: if(!map.load(elem)) { nuclear@2: pop_data_path(); nuclear@2: return false; nuclear@2: } nuclear@2: levelmaps[map.get_name()] = std::move(map); nuclear@2: nuclear@2: } else { nuclear@2: fprintf(stderr, "ignoring unrecognized element: %s\n", elem->Name()); nuclear@2: } nuclear@2: } nuclear@2: } while((node = node->NextSibling())); nuclear@2: nuclear@2: pop_data_path(); nuclear@2: return true; nuclear@2: } nuclear@2: nuclear@3: void Level::draw() const nuclear@3: { nuclear@3: auto iter = levelmaps.find("height"); nuclear@3: if(iter == levelmaps.end()) { nuclear@3: return; nuclear@3: } nuclear@3: nuclear@3: img_pixmap *hmap = (img_pixmap*)iter->second.get_pixmap(); nuclear@3: nuclear@3: glBegin(GL_POINTS); nuclear@3: for(int i=0; iheight; i++) { nuclear@3: for(int j=0; jwidth; j++) { nuclear@3: int height; nuclear@3: img_getpixel1i(hmap, j, i, &height); nuclear@3: nuclear@3: float x = (float)j / (float)hmap->width - 0.5; nuclear@3: float y = height / 255.0; nuclear@3: float z = (float)i / (float)hmap->height - 0.5; nuclear@3: nuclear@3: glColor3f(y, 0.0, 1.0 - y); nuclear@3: glVertex3f(x, y, z); nuclear@3: } nuclear@3: } nuclear@3: glEnd(); nuclear@3: } nuclear@3: nuclear@2: nuclear@2: LevelMap::LevelMap() nuclear@2: { nuclear@2: init(); nuclear@2: } nuclear@2: nuclear@2: void LevelMap::init() nuclear@2: { nuclear@2: scale = 1.0f; nuclear@2: img_init(&img); nuclear@2: name = 0; nuclear@2: } nuclear@2: nuclear@2: LevelMap::~LevelMap() nuclear@2: { nuclear@2: destroy(); nuclear@2: } nuclear@2: nuclear@2: void LevelMap::destroy() nuclear@2: { nuclear@2: if(img.pixels) { nuclear@2: img_destroy(&img); nuclear@2: } nuclear@2: delete [] name; nuclear@2: } nuclear@2: nuclear@2: // copy nuclear@2: LevelMap::LevelMap(const LevelMap &map) nuclear@2: { nuclear@2: init(); nuclear@2: *this = map; nuclear@2: } nuclear@2: nuclear@2: LevelMap &LevelMap::operator =(const LevelMap &map) nuclear@2: { nuclear@2: if(this != &map) { nuclear@2: destroy(); nuclear@2: nuclear@2: scale = map.scale; nuclear@2: img_init(&img); nuclear@2: img_copy(&img, (img_pixmap*)&map.img); nuclear@2: nuclear@2: name = new char[strlen(map.name) + 1]; nuclear@2: strcpy(name, map.name); nuclear@2: } nuclear@2: return *this; nuclear@2: } nuclear@2: nuclear@2: // move semantics nuclear@2: LevelMap::LevelMap(LevelMap &&map) nuclear@2: { nuclear@2: init(); nuclear@2: *this = std::move(map); nuclear@2: } nuclear@2: nuclear@2: LevelMap &LevelMap::operator =(LevelMap &&map) nuclear@2: { nuclear@2: if(this != &map) { nuclear@2: destroy(); nuclear@2: nuclear@2: scale = map.scale; nuclear@2: nuclear@2: img = map.img; nuclear@2: map.img.pixels = 0; nuclear@2: map.img.name = 0; nuclear@2: nuclear@2: name = map.name; nuclear@2: map.name = 0; nuclear@2: } nuclear@2: nuclear@2: return *this; nuclear@2: } nuclear@2: nuclear@2: bool LevelMap::load(XMLElement *xelem) nuclear@2: { nuclear@2: char fname[PATH_MAX]; nuclear@2: nuclear@2: const char *attr = xelem->Attribute("type"); nuclear@2: if(!attr) { nuclear@2: fprintf(stderr, "map element without a type attribute\n"); nuclear@2: return false; nuclear@2: } nuclear@2: name = new char[strlen(attr) + 1]; nuclear@2: strcpy(name, attr); nuclear@2: nuclear@2: attr = xelem->Attribute("file"); nuclear@2: if(!attr) { nuclear@2: fprintf(stderr, "map element without a file attribute\n"); nuclear@2: return false; nuclear@2: } nuclear@2: if(!find_file(attr, fname)) { nuclear@2: fprintf(stderr, "failed to locate image: %s\n", attr); nuclear@2: return false; nuclear@2: } nuclear@2: nuclear@2: if(img_load(&img, fname) == -1) { nuclear@2: fprintf(stderr, "failed to load image: %s\n", fname); nuclear@2: return false; nuclear@2: } nuclear@2: nuclear@2: float val; nuclear@2: if(xelem->QueryFloatAttribute("scale", &val) == 0) { nuclear@2: scale = val; nuclear@2: } nuclear@1: return true; nuclear@0: } nuclear@2: nuclear@2: float LevelMap::get_scale() const nuclear@2: { nuclear@2: return scale; nuclear@2: } nuclear@2: nuclear@2: const img_pixmap *LevelMap::get_pixmap() const nuclear@2: { nuclear@2: return &img; nuclear@2: } nuclear@2: nuclear@2: const char *LevelMap::get_name() const nuclear@2: { nuclear@2: return name; nuclear@2: }