#include "M2File.h" #include "File.h" #include "Model2D.h" #include "Text.h" using namespace Framework; // Contents of the M2File class from M2File.h // Constructor M2File::M2File() : ReferenceCounter() { pfad = new Text(); modelName = new RCArray(); modelPos = new Array<__int64>(); } M2File::M2File(const char* pfad) : ReferenceCounter() { this->pfad = new Text(pfad); modelName = new RCArray(); modelPos = new Array<__int64>(); } M2File::M2File(Text* pfad) : ReferenceCounter() { this->pfad = pfad; modelName = new RCArray(); modelPos = new Array<__int64>(); } // Destructor M2File::~M2File() { pfad->release(); modelName->release(); modelPos->release(); } // non-constant void M2File::setPfad(const char* pfad) { this->pfad->setText(pfad); } void M2File::setPfadZ(Text* pfad) { if (this->pfad) this->pfad->release(); this->pfad = pfad; } void M2File::readData() { File d; d.setFile(pfad->getText()); d.open(File::Style::readAll); char anz = 0; d.read(&anz, 1); modelName->clear(); modelPos->clear(); for (int i = 0; i < anz; i++) { char len = 0; d.read(&len, 1); char* txt = new char[len + 1]; d.read(txt, len); txt[(int)len] = 0; modelName->set(new Text(txt), i); delete[] txt; __int64 pos = 0; d.read((char*)&pos, 8); modelPos->set(pos, i); } d.close(); } bool M2File::saveModel(Model2DData* zMdr, Text* name) { bool ret = saveModel(zMdr, name->getText()); name->release(); return ret; } bool M2File::saveModel(Model2DData* zMdr, const char* name) { int anz = modelName->getEntryCount(); for (int i = 0; i < anz; i++) { if (modelName->z(i)->isEqual(name)) { if (!removeModel(name)) return 0; break; } } anz = modelName->getEntryCount(); File d; d.setFile(pfad->getText()); d.open(File::Style::readAll); File neu; neu.setFile(pfad->getText()); neu.zPfad()->append("0"); while (neu.exists()) neu.zPfad()->append("0"); if (!neu.open(File::Style::schreiben)) { if (d.isOpen()) d.close(); return 0; } modelName->add(new Text(name)); int offs = textLength(name) + 9; for (int i = 0; i < anz; i++) modelPos->set(modelPos->get(i) + offs, i); if (d.getSize() < 0) modelPos->add(offs + 1); else modelPos->add(d.getSize() + offs); anz++; char tmp = (char)anz; neu.write(&tmp, 1); for (int i = 0; i < anz; i++) { char len = (char)modelName->z(i)->getLength(); neu.write(&len, 1); neu.write(modelName->z(i)->getText(), len); __int64 pos = modelPos->get(i); neu.write((char*)&pos, 8); } if (d.exists()) { d.setLPosition(modelPos->get(0) - offs, 0); __int64 dl = d.getSize() - d.getLPosition(); char bytes[2048]; while (dl) { int l = dl > 2048 ? 2048 : (int)dl; d.read(bytes, l); neu.write(bytes, l); dl -= l; } } d.close(); char pAnz = (char)zMdr->polygons->getEntryCount(); neu.write(&pAnz, 1); for (int p = 0; p < pAnz; p++) { char pNameL = (char)zMdr->polygons->get(p).name->getLength(); int vAnz = zMdr->polygons->get(p).vertex->getEntryCount(); char options = 1; for (int i = 0; i < vAnz; i++) options = (char)(options & (char)zMdr->polygons->get(p).tCoordinates->has(i)); if (pNameL != 0) options |= 2; if (zMdr->polygons->get(p).transparent) options |= 4; neu.write(&options, 1); if ((options | 2) == options) // name { neu.write(&pNameL, 1); neu.write(zMdr->polygons->get(p).name->getText(), pNameL); } neu.write((char*)&vAnz, 4); for (int i = 0; i < vAnz; i++) { float v = zMdr->polygons->get(p).vertex->get(i).x; neu.write((char*)&v, 4); v = zMdr->polygons->get(p).vertex->get(i).y; neu.write((char*)&v, 4); if ((options | 1) == options) // textur { float t = zMdr->polygons->get(p).tCoordinates->get(i).x; neu.write((char*)&t, 4); t = zMdr->polygons->get(p).tCoordinates->get(i).y; neu.write((char*)&t, 4); } } } d.remove(); neu.close(); neu.rename(pfad->getText()); readData(); return 1; } bool M2File::removeModel(Text* name) { bool ret = removeModel(name->getText()); name->release(); return ret; } bool M2File::removeModel(const char* name) { int anz = modelName->getEntryCount(); int p = -1; for (int i = 0; i < anz; i++) { if (modelName->z(i)->isEqual(name)) { p = i; break; } } if (p < 0) return 0; File d; d.setFile(pfad->getText()); if (!d.open(File::Style::readAll)) return 0; File neu; neu.setFile(pfad->getText()); neu.zPfad()->append("0"); while (neu.exists()) neu.zPfad()->append("0"); if (!neu.open(File::Style::schreiben)) { if (d.isOpen()) d.close(); return 0; } char nAnz = (char)(anz - 1); neu.write(&nAnz, 1); int offs = modelName->z(p)->getLength() + 9; __int64 startP = 0, endP = 0, start2P = 0; for (int i = 0; i < anz; i++) { char nLen = (char)modelName->z(i)->getLength(); const char* n = modelName->z(i)->getText(); __int64 pos = modelPos->get(i); if (!startP) startP = pos; if (i == p + 1) start2P = pos; if (i == p) { if (!endP) endP = pos; if (i < anz - 1) offs += (int)(modelPos->get(i + 1) - pos); } if (i != p) { pos -= offs; neu.write(&nLen, 1); neu.write(n, nLen); neu.write((char*)&pos, 8); } } if (d.isOpen()) { d.setLPosition(startP, 0); __int64 bLen = endP - startP; char bytes[2048]; while (bLen > 0) { int l = 2048 > bLen ? (int)bLen : 2048; d.read(bytes, l); neu.write(bytes, l); bLen -= l; } if (start2P) { d.setLPosition(start2P, 0); bLen = d.getSize() - start2P; while (bLen > 0) { int l = 2048 > bLen ? (int)bLen : 2048; d.read(bytes, l); neu.write(bytes, l); bLen -= l; } } d.close(); } d.remove(); neu.close(); neu.rename(pfad->getText()); readData(); return 1; } // constant Model2DData* M2File::loadModel(Text* name) const { Model2DData* ret = loadModel(name->getText()); name->release(); return ret; } Model2DData* M2File::loadModel(const char* name) const { File d; d.setFile(pfad->getText()); if (!d.open(File::Style::readAll)) return 0; int anz = modelName->getEntryCount(); for (int i = 0; i < anz; i++) { if (modelName->z(i)->isEqual(name)) { d.setLPosition(modelPos->get(i), 0); break; } } if (!d.getLPosition()) { d.close(); return 0; } char pAnz = 0; d.read(&pAnz, 1); Array* polygons = new Array(); for (int p = 0; p < pAnz; p++) { char options = 0; d.read(&options, 1); Polygon2D polygon; polygon.center = new Vertex(0, 0); polygon.transparent = (options | 4) == options; polygon.name = new Text(); if ((options | 2) == options) { char nameL = 0; d.read(&nameL, 1); char* name = new char[nameL + 1]; name[(int)nameL] = 0; d.read(name, nameL); polygon.name->setText(name); delete[] name; } int vAnz = 0; d.read((char*)&vAnz, 4); if (polygons->has(p)) { if (polygons->get(p).vertex) polygons->get(p).vertex->release(); if (polygons->get(p).tCoordinates) polygons->get(p).tCoordinates->release(); } polygon.vertex = new Array(); if ((options | 1) == options) // wenn textur polygon.tCoordinates = new Array(); else polygon.tCoordinates = 0; for (int v = 0; v < vAnz; v++) { Vertex p; d.read((char*)&p.x, 4); d.read((char*)&p.y, 4); *polygon.center += p * (float)(1.0 / vAnz); polygon.vertex->add(p); if ((options | 1) == options) // wenn textur { Vertex tp; d.read((char*)&tp.x, 4); d.read((char*)&tp.y, 4); polygon.tCoordinates->add(tp); } } polygons->add(polygon); } d.close(); Model2DData* ret = new Model2DData(); ret->createModell(polygons); return ret; } bool M2File::hasModel(const char* name) const { int anz = modelName->getEntryCount(); for (int i = 0; i < anz; i++) { if (modelName->z(i)->isEqual(name)) return 1; } return 0; } int M2File::getModelCount() const { return modelName->getEntryCount(); } Text* M2File::zModelName(int i) const { return modelName->z(i); }