#include "FileManager.h" #include "Window.h" bool FileManager::writeTriangle(xmlTextWriterPtr writer, const Triangle &triangle, float height) { // if(xmlTextWriterStartElement(writer, (xmlChar*)"triangle") < 0) return false; //if(xmlTextWriterWriteAttribute(writer, (xmlChar*)"texture", (xmlChar*)"t0") < 0) // return false; float y = 0.0f; if(triangle.getDirection() == Triangle::CW) y = height; if(!writeVertex(writer, triangle.getVertexA().getX(), y, triangle.getVertexA().getY())) return false; //if(!writeTexCoords(writer, triangle.getVertexA().getX(), triangle.getVertexA().getY())) // return false; if(!writeVertex(writer, triangle.getVertexB().getX(), y, triangle.getVertexB().getY())) return false; //if(!writeTexCoords(writer, triangle.getVertexB().getX(), triangle.getVertexB().getY())) // return false; if(!writeVertex(writer, triangle.getVertexC().getX(), y, triangle.getVertexC().getY())) return false; //if(!writeTexCoords(writer, triangle.getVertexC().getX(), triangle.getVertexC().getY())) // return false; // if(xmlTextWriterEndElement(writer) < 0) return false; // if(xmlTextWriterStartElement(writer, (xmlChar*)"triangle") < 0) return false; //if(xmlTextWriterWriteAttribute(writer, (xmlChar*)"texture", (xmlChar*)"t0") < 0) // return false; y = height; if(triangle.getDirection() == Triangle::CW) y = 0.0f; if(!writeVertex(writer, triangle.getVertexC().getX(), y, triangle.getVertexC().getY())) return false; //if(!writeTexCoords(writer, triangle.getVertexC().getX(), triangle.getVertexC().getY())) // return false; if(!writeVertex(writer, triangle.getVertexB().getX(), y, triangle.getVertexB().getY())) return false; //if(!writeTexCoords(writer, triangle.getVertexB().getX(), triangle.getVertexB().getY())) // return false; if(!writeVertex(writer, triangle.getVertexA().getX(), y, triangle.getVertexA().getY())) return false; //if(!writeTexCoords(writer, triangle.getVertexA().getX(), triangle.getVertexA().getY())) // return false; // if(xmlTextWriterEndElement(writer) < 0) return false; return true; } bool FileManager::writeSide(xmlTextWriterPtr writer, const Vertex &v1, const Vertex &v2, float height) { // if(xmlTextWriterStartElement(writer, (xmlChar*)"triangle") < 0) return false; //if(xmlTextWriterWriteAttribute(writer, (xmlChar*)"texture", (xmlChar*)"t0") < 0) // return false; if(!writeVertex(writer, v1.getX(), 0, v1.getY())) return false; if(!writeTexCoords(writer, v1.getX(), v1.getY())) return false; if(!writeVertex(writer, v2.getX(), 0, v2.getY())) return false; if(!writeTexCoords(writer, v2.getX(), v2.getY())) return false; if(!writeVertex(writer, v2.getX(), height, v2.getY())) return false; if(!writeTexCoords(writer, v2.getX(), v2.getY())) return false; // if(xmlTextWriterEndElement(writer) < 0) return false; // if(xmlTextWriterStartElement(writer, (xmlChar*)"triangle") < 0) return false; //if(xmlTextWriterWriteAttribute(writer, (xmlChar*)"texture", (xmlChar*)"t0") < 0) // return false; if(!writeVertex(writer, v2.getX(), height, v2.getY())) return false; if(!writeTexCoords(writer, v2.getX(), v2.getY())) return false; if(!writeVertex(writer, v1.getX(), height, v1.getY())) return false; if(!writeTexCoords(writer, v1.getX(), v1.getY())) return false; if(!writeVertex(writer, v1.getX(), 0, v1.getY())) return false; if(!writeTexCoords(writer, v1.getX(), v1.getY())) return false; // if(xmlTextWriterEndElement(writer) < 0) return false; return true; } bool FileManager::writeVertex(xmlTextWriterPtr writer, float x, float y, float z) { // if(xmlTextWriterStartElement(writer, (xmlChar*)"vertex") < 0) return false; if(xmlTextWriterWriteFormatAttribute(writer, (xmlChar*)"x", "%f", x) < 0) return false; if(xmlTextWriterWriteFormatAttribute(writer, (xmlChar*)"y", "%f", y) < 0) return false; if(xmlTextWriterWriteFormatAttribute(writer, (xmlChar*)"z", "%f", z) < 0) return false; // if(xmlTextWriterEndElement(writer) < 0) return false; return true; } bool FileManager::writeTexCoords(xmlTextWriterPtr writer, float s, float t) { // if(xmlTextWriterStartElement(writer, (xmlChar*)"texcoords") < 0) return false; if(xmlTextWriterWriteFormatAttribute(writer, (xmlChar*)"s", "%f", s) < 0) return false; if(xmlTextWriterWriteFormatAttribute(writer, (xmlChar*)"t", "%f", t) < 0) return false; // if(xmlTextWriterEndElement(writer) < 0) return false; return true; } bool FileManager::writeStart(xmlTextWriterPtr writer, const Vertex3d &start) { // if(xmlTextWriterStartElement(writer, (xmlChar*)"start") < 0) return false; if(xmlTextWriterWriteFormatAttribute(writer, (xmlChar*)"x", "%f", start.getX()) < 0) return false; if(xmlTextWriterWriteFormatAttribute(writer, (xmlChar*)"y", "%f", start.getY()) < 0) return false; if(xmlTextWriterWriteFormatAttribute(writer, (xmlChar*)"z", "%f", start.getZ()) < 0) return false; // if(xmlTextWriterEndElement(writer) < 0) return false; return true; } FileManager::FileManager(Window *window) { this->window = window; filename = NULL; dirty = false; } FileManager::~FileManager() { if(filename) g_free(filename); } bool FileManager::save(GtkWindow *parent) { if(filename == NULL) return saveAs(parent); return write(); } bool FileManager::saveAs(GtkWindow *parent) { GtkWidget *dialog = gtk_file_chooser_dialog_new(NULL, parent, GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, NULL); gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE); if(filename) gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog), filename); else gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), "level.lvl"); if(gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) { gtk_widget_destroy(dialog); return false; } if(filename) g_free(filename); filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)); gtk_widget_destroy(dialog); if(!filename) return false; return write(); } bool FileManager::write() { xmlTextWriterPtr writer; writer = xmlNewTextWriterFilename(filename, 9); if(!writer) return false; if(xmlTextWriterStartDocument(writer, NULL, "UTF-8", NULL) < 0) { xmlFreeTextWriter(writer); return false; } if(xmlTextWriterStartDTD(writer, (xmlChar*)"level", (xmlChar*)"-//libzoom//DTD level 0.1//EN", (xmlChar*)"level.dtd") < 0) { xmlFreeTextWriter(writer); return false; } if(xmlTextWriterSetIndent(writer, 1) < 0) { xmlFreeTextWriter(writer); return false; } if(xmlTextWriterSetIndentString(writer, (xmlChar*)" ") < 0) { xmlFreeTextWriter(writer); return false; } if(xmlTextWriterEndDTD(writer) < 0) { xmlFreeTextWriter(writer); return false; } // if(xmlTextWriterStartElement(writer, (xmlChar*)"level") < 0) { xmlFreeTextWriter(writer); return false; } // if(xmlTextWriterStartElement(writer, (xmlChar*)"info") < 0) { xmlFreeTextWriter(writer); return false; } if(xmlTextWriterWriteElement(writer, (xmlChar*)"name", (xmlChar*)"Level") < 0) { xmlFreeTextWriter(writer); return false; } if(xmlTextWriterWriteElement(writer, (xmlChar*)"desc", (xmlChar*)"Description") < 0) { xmlFreeTextWriter(writer); return false; } for(Level::iterator object = window->getLevel().begin(); ; object++) { if(object == window->getLevel().end()) { xmlFreeTextWriter(writer); return false; } if(!(*object)->isOfType("PlayerStart")) continue; if(!writeStart(writer, *(PlayerStart*)&**object)) { xmlFreeTextWriter(writer); return false; } break; } // if(xmlTextWriterEndElement(writer) < 0) { xmlFreeTextWriter(writer); return false; } // if(xmlTextWriterStartElement(writer, (xmlChar*)"rooms") < 0) { xmlFreeTextWriter(writer); return false; } for(Level::iterator object = window->getLevel().begin(); object != window->getLevel().end(); object++) { if(!(*object)->isOfType("Room")) continue; Room *room = (Room*)&**object; // if(xmlTextWriterStartElement(writer, (xmlChar*)"room") < 0) { xmlFreeTextWriter(writer); return false; } if(xmlTextWriterWriteAttribute(writer, (xmlChar*)"id", (xmlChar*)room->getName().c_str()) < 0) { xmlFreeTextWriter(writer); return false; } std::vector triangles; room->getPolygon().triangulate(triangles); for(std::vector::iterator triangle = triangles.begin(); triangle != triangles.end(); triangle++) { if(!writeTriangle(writer, *triangle, room->getHeight())) { xmlFreeTextWriter(writer); return false; } } std::vector vertices = room->getPolygon(); if(room->getPolygon().getDirection() == Triangle::CCW) { vertices = std::vector(vertices.rbegin(), vertices.rend()); } for(std::vector::iterator v1 = vertices.begin(); v1 != vertices.end(); v1++) { std::vector::iterator v2 = v1+1; if(v2 == vertices.end()) v2 = vertices.begin(); if(!writeSide(writer, *v1, *v2, room->getHeight())) { xmlFreeTextWriter(writer); return false; } } // if(xmlTextWriterEndElement(writer) < 0) { xmlFreeTextWriter(writer); return false; } } // if(xmlTextWriterEndElement(writer) < 0) { xmlFreeTextWriter(writer); return false; } // if(xmlTextWriterStartElement(writer, (xmlChar*)"gates") < 0) { xmlFreeTextWriter(writer); return false; } // if(xmlTextWriterEndElement(writer) < 0) { xmlFreeTextWriter(writer); return false; } // if(xmlTextWriterStartElement(writer, (xmlChar*)"textures") < 0) { xmlFreeTextWriter(writer); return false; } // if(xmlTextWriterEndElement(writer) < 0) { xmlFreeTextWriter(writer); return false; } // if(xmlTextWriterEndElement(writer) < 0) { xmlFreeTextWriter(writer); return false; } if(xmlTextWriterEndDocument(writer) < 0) { xmlFreeTextWriter(writer); return false; } xmlFreeTextWriter(writer); return true; }