summaryrefslogtreecommitdiffstats
path: root/FileManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'FileManager.cpp')
-rw-r--r--FileManager.cpp390
1 files changed, 390 insertions, 0 deletions
diff --git a/FileManager.cpp b/FileManager.cpp
new file mode 100644
index 0000000..7650a2f
--- /dev/null
+++ b/FileManager.cpp
@@ -0,0 +1,390 @@
+#include "FileManager.h"
+#include "Window.h"
+
+
+bool FileManager::writeTriangle(xmlTextWriterPtr writer, const Triangle &triangle, float height) {
+ // <triangle>
+ 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;
+
+ // </triangle>
+ if(xmlTextWriterEndElement(writer) < 0)
+ return false;
+
+ // <triangle>
+ 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;
+
+ // </triangle>
+ if(xmlTextWriterEndElement(writer) < 0)
+ return false;
+
+ return true;
+}
+
+bool FileManager::writeSide(xmlTextWriterPtr writer, const Vertex &v1, const Vertex &v2, float height) {
+ // <triangle>
+ 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;
+
+ // </triangle>
+ if(xmlTextWriterEndElement(writer) < 0)
+ return false;
+
+ // <triangle>
+ 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;
+
+ // </triangle>
+ if(xmlTextWriterEndElement(writer) < 0)
+ return false;
+
+ return true;
+}
+
+bool FileManager::writeVertex(xmlTextWriterPtr writer, float x, float y, float z) {
+ // <vertex>
+ 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;
+
+ // </vertex>
+ if(xmlTextWriterEndElement(writer) < 0)
+ return false;
+
+ return true;
+}
+
+bool FileManager::writeTexCoords(xmlTextWriterPtr writer, float s, float t) {
+ // <texcoords>
+ 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;
+
+ // </texcoords>
+ 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_OK, GTK_RESPONSE_ACCEPT, GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL);
+
+ 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;
+ }
+
+ // <level>
+ if(xmlTextWriterStartElement(writer, (xmlChar*)"level") < 0) {
+ xmlFreeTextWriter(writer);
+ return false;
+ }
+
+ // <info>
+ 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;
+ }
+
+ // <start>
+ if(xmlTextWriterStartElement(writer, (xmlChar*)"start") < 0) {
+ xmlFreeTextWriter(writer);
+ return false;
+ }
+
+ if(xmlTextWriterWriteAttribute(writer, (xmlChar*)"x", (xmlChar*)"0.0") < 0) {
+ xmlFreeTextWriter(writer);
+ return false;
+ }
+
+ if(xmlTextWriterWriteAttribute(writer, (xmlChar*)"y", (xmlChar*)"2.0") < 0) {
+ xmlFreeTextWriter(writer);
+ return false;
+ }
+
+ if(xmlTextWriterWriteAttribute(writer, (xmlChar*)"z", (xmlChar*)"0.0") < 0) {
+ xmlFreeTextWriter(writer);
+ return false;
+ }
+
+ // </start>
+ if(xmlTextWriterEndElement(writer) < 0) {
+ xmlFreeTextWriter(writer);
+ return false;
+ }
+
+ // </info>
+ if(xmlTextWriterEndElement(writer) < 0) {
+ xmlFreeTextWriter(writer);
+ return false;
+ }
+
+ // <rooms>
+ if(xmlTextWriterStartElement(writer, (xmlChar*)"rooms") < 0) {
+ xmlFreeTextWriter(writer);
+ return false;
+ }
+
+ for(Level::iterator room = window->getLevel().begin(); room != window->getLevel().end(); room++) {
+ // <room>
+ 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<Triangle> triangles;
+ room->triangulate(triangles);
+
+ for(std::vector<Triangle>::iterator triangle = triangles.begin(); triangle != triangles.end(); triangle++) {
+ if(!writeTriangle(writer, *triangle, room->getHeight())) {
+ xmlFreeTextWriter(writer);
+ return false;
+ }
+ }
+
+ std::vector<Vertex> vertices = *room;
+
+ if(room->getDirection() == Triangle::CCW) {
+ vertices = std::vector<Vertex>(vertices.rbegin(), vertices.rend());
+ }
+
+ for(std::vector<Vertex>::iterator v1 = vertices.begin(); v1 != vertices.end(); v1++) {
+ std::vector<Vertex>::iterator v2 = v1+1;
+ if(v2 == vertices.end()) v2 = vertices.begin();
+
+ if(!writeSide(writer, *v1, *v2, room->getHeight())) {
+ xmlFreeTextWriter(writer);
+ return false;
+ }
+ }
+
+ // </room>
+ if(xmlTextWriterEndElement(writer) < 0) {
+ xmlFreeTextWriter(writer);
+ return false;
+ }
+ }
+
+ // </rooms>
+ if(xmlTextWriterEndElement(writer) < 0) {
+ xmlFreeTextWriter(writer);
+ return false;
+ }
+
+ // <gates>
+ if(xmlTextWriterStartElement(writer, (xmlChar*)"gates") < 0) {
+ xmlFreeTextWriter(writer);
+ return false;
+ }
+
+ // </gates>
+ if(xmlTextWriterEndElement(writer) < 0) {
+ xmlFreeTextWriter(writer);
+ return false;
+ }
+
+ // <textures>
+ if(xmlTextWriterStartElement(writer, (xmlChar*)"textures") < 0) {
+ xmlFreeTextWriter(writer);
+ return false;
+ }
+
+ // </textures>
+ if(xmlTextWriterEndElement(writer) < 0) {
+ xmlFreeTextWriter(writer);
+ return false;
+ }
+
+ // </level>
+ if(xmlTextWriterEndElement(writer) < 0) {
+ xmlFreeTextWriter(writer);
+ return false;
+ }
+
+ if(xmlTextWriterEndDocument(writer) < 0) {
+ xmlFreeTextWriter(writer);
+ return false;
+ }
+
+ xmlFreeTextWriter(writer);
+
+ return true;
+}