2 * This file is part of ShapeFusion (Copyright 2000 Tito Dal Canton)
4 * ShapeFusion is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * ShapeFusion is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with ShapeFusion; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "wx/wxprec.h"
24 #include "wx/datstrm.h"
25 #include "ShapesDocument.h"
27 IMPLEMENT_DYNAMIC_CLASS(ShapesDocument, wxDocument)
29 ShapesDocument::ShapesDocument():
30 wxDocument(), ShapesElement(false)
35 ShapesDocument::~ShapesDocument()
40 unsigned int ShapesDocument::CollectionCount(void) const
42 return mCollections.size();
45 // collection data access
46 int ShapesDocument::CollectionStatus(unsigned int id)
48 return mCollections[id]->Status();
51 unsigned int ShapesDocument::CollectionFlags(unsigned int id) const
53 return mCollections[id]->Flags();
56 bool ShapesDocument::CollectionDefined(unsigned int id, unsigned int chunk) const
58 return mCollections[id]->Defined(chunk);
61 int ShapesDocument::CollectionVersion(unsigned int id, unsigned int chunk) const
63 return mCollections[id]->Version(chunk);
66 int ShapesDocument::CollectionType(unsigned int id, unsigned int chunk) const
68 return mCollections[id]->Type(chunk);
71 unsigned int ShapesDocument::CollectionFlags(unsigned int id, unsigned int chunk) const
73 return mCollections[id]->Flags(chunk);
76 int ShapesDocument::CollectionScaleFactor(unsigned int id, unsigned int chunk) const
78 return mCollections[id]->ScaleFactor(chunk);
81 unsigned int ShapesDocument::CollectionBitmapCount(unsigned int id, unsigned int chunk) const
83 return mCollections[id]->BitmapCount(chunk);
86 unsigned int ShapesDocument::CollectionColorTableCount(unsigned int id, unsigned int chunk) const
88 return mCollections[id]->ColorTableCount(chunk);
91 unsigned int ShapesDocument::CollectionFrameCount(unsigned int id, unsigned int chunk) const
93 return mCollections[id]->FrameCount(chunk);
96 unsigned int ShapesDocument::CollectionSequenceCount(unsigned int id, unsigned int chunk) const
98 return mCollections[id]->SequenceCount(chunk);
101 ShapesColorTable *ShapesDocument::GetColorTable(unsigned int coll, unsigned int chunk, unsigned int ct) const
103 return mCollections[coll]->GetColorTable(chunk, ct);
106 ShapesBitmap *ShapesDocument::GetBitmap(unsigned int coll, unsigned int chunk, unsigned int bitmap) const
108 return mCollections[coll]->GetBitmap(chunk, bitmap);
111 ShapesFrame *ShapesDocument::GetFrame(unsigned int coll, unsigned int chunk, unsigned int frame) const
113 return mCollections[coll]->GetFrame(chunk, frame);
116 ShapesSequence *ShapesDocument::GetSequence(unsigned int coll, unsigned int chunk, unsigned int seq) const
118 return mCollections[coll]->GetSequence(chunk, seq);
121 ShapesChunk* ShapesDocument::GetChunk(unsigned int coll, unsigned int chunk) const
123 return mCollections[coll]->GetChunk(chunk);
126 // collection alteration
127 void ShapesDocument::InsertColorTable(ShapesColorTable *ct, unsigned int coll, unsigned int chunk)
129 mCollections[coll]->InsertColorTable(ct, chunk);
132 void ShapesDocument::DeleteColorTable(unsigned int coll, unsigned int chunk, unsigned int ct)
134 mCollections[coll]->DeleteColorTable(chunk, ct);
137 void ShapesDocument::InsertBitmap(ShapesBitmap *b, unsigned int coll, unsigned int chunk)
139 mCollections[coll]->InsertBitmap(b, chunk);
142 void ShapesDocument::DeleteBitmap(unsigned int coll, unsigned int chunk, unsigned int b)
144 mCollections[coll]->DeleteBitmap(chunk, b);
147 void ShapesDocument::InsertFrame(ShapesFrame *f, unsigned int coll, unsigned int chunk)
149 mCollections[coll]->InsertFrame(f, chunk);
152 void ShapesDocument::DeleteFrame(unsigned int coll, unsigned int chunk, unsigned int f)
154 mCollections[coll]->DeleteFrame(chunk, f);
157 void ShapesDocument::InsertSequence(ShapesSequence *s, unsigned int coll, unsigned int chunk)
159 mCollections[coll]->InsertSequence(s, chunk);
162 void ShapesDocument::DeleteSequence(unsigned int coll, unsigned int chunk, unsigned int s)
164 mCollections[coll]->DeleteSequence(chunk, s);
167 bool ShapesDocument::DoOpenDocument(const wxString& file)
169 bool wxOpen = wxDocument::DoOpenDocument(file);
171 if (!(wxOpen && mGoodData)) {
172 wxLogError(wxT("[ShapesDocument] There was an error while loading, see log"));
178 #if wxUSE_STD_IOSTREAM
179 wxSTD ostream& ShapesDocument::SaveObject(wxSTD ostream& stream)
181 wxOutputStream& ShapesDocument::SaveObject(wxOutputStream& stream)
184 unsigned int collectionCount = CollectionCount();
186 // compose and write the collection header block
187 BigEndianBuffer raw_headers(SIZEOF_collection_header * collectionCount);
188 long running_offset = SIZEOF_collection_header * collectionCount;
190 for (unsigned int i = 0; i < collectionCount; i++) {
191 ShapesCollection *coll = mCollections[i];
193 raw_headers.WriteShort(coll->Status());
194 raw_headers.WriteUShort(coll->Flags());
196 if (coll->Defined(COLL_VERSION_8BIT)) {
197 unsigned int collSize = coll->SizeInFile(COLL_VERSION_8BIT);
199 raw_headers.WriteLong(running_offset);
200 raw_headers.WriteLong(collSize);
201 running_offset += collSize;
203 raw_headers.WriteLong(-1);
204 raw_headers.WriteLong(0);
207 if (coll->Defined(COLL_VERSION_TRUECOLOR)) {
208 unsigned int collSize = coll->SizeInFile(COLL_VERSION_TRUECOLOR);
210 raw_headers.WriteLong(running_offset);
211 raw_headers.WriteLong(collSize);
212 running_offset += collSize;
214 raw_headers.WriteLong(-1);
215 raw_headers.WriteLong(0);
217 raw_headers.WriteZeroes(12);
219 #if wxUSE_STD_IOSTREAM
220 stream.write((char *)raw_headers.Data(), raw_headers.Size());
222 stream.Write((char *)raw_headers.Data(), raw_headers.Size());
226 for (unsigned int i = 0; i < collectionCount; i++)
227 mCollections[i]->SaveObject(stream);
232 #if wxUSE_STD_IOSTREAM
233 wxSTD ostream& ShapesDocument::SavePatch(wxSTD ostream& stream, const ShapesDocument& other)
235 wxOutputStream& ShapesDocument::SavePatch(wxOutputStream& stream, const ShapesDocument& other)
238 if (mCollections.size() != other.mCollections.size()) {
239 wxLogError(wxT("[ShapesDocument] Shapes files must contain the same number of collections to generate a patch"));
244 for (unsigned int i = 0; i < mCollections.size(); ++i) {
245 mCollections[i]->SavePatch(stream, *other.mCollections[i], i, 0);
248 for (unsigned int i = 0; i < mCollections.size(); ++i) {
249 mCollections[i]->SavePatch(stream, *other.mCollections[i], i, 1);
255 #if wxUSE_STD_IOSTREAM
256 wxSTD istream& ShapesDocument::LoadObject(wxSTD istream& stream)
258 wxInputStream& ShapesDocument::LoadObject(wxInputStream& stream)
263 // first check file size to immediately rule out invalid stuff
264 #if wxUSE_STD_IOSTREAM
265 stream.seekg(0, std::ios::end);
266 wxInt32 filesize = stream.tellg();
267 stream.seekg(0, std::ios::beg);
269 wxInt32 filesize = stream.GetSize();
271 if (filesize < COLLECTIONS_PER_FILE * SIZEOF_collection_header) {
272 wxLogError(wxT("[ShapesDocument] File too small to be a Marathon shapes file"));
276 // find how many collections are stored and load them
280 ShapesCollection *c = new ShapesCollection(IsVerbose());
283 wxLogDebug(wxT("[ShapesDocument] Trying to load collection %d"), i);
285 #if wxUSE_STD_IOSTREAM
286 stream.seekg(i * SIZEOF_collection_header, std::ios::beg);
288 stream.SeekI(i * SIZEOF_collection_header);
290 c->LoadObject(stream);
293 mCollections.push_back(c);
299 if (i >= COLLECTIONS_PER_FILE)
302 wxLogError(wxT("[ShapesDocument] Could not find enough collections. This may not be a Marathon Shapes file."));
307 #if wxUSE_STD_IOSTREAM
308 bool ShapesDocument::LoadPatch(wxSTD istream& stream)
310 bool ShapesDocument::LoadPatch(wxInputStream& stream)
313 #if wxUSE_STD_IOSTREAM
314 stream.seekg(0, std::ios::end);
315 wxInt32 filesize = stream.tellg();
316 stream.seekg(0, std::ios::beg);
318 wxInt32 filesize = stream.GetSize();
321 // memory is cheap, read the whole thing in
322 BigEndianBuffer buffer(filesize);
324 #if wxUSE_STD_IOSTREAM
325 stream.read((char *) buffer.Data(), buffer.Size());
327 stream.Read((char *) buffer.Data(), buffer.Size());
330 while (buffer.Position() < buffer.Size()) {
331 long collection = buffer.ReadLong();
332 if (collection < mCollections.size()) {
333 mCollections[collection]->LoadPatch(buffer);
334 if (!mCollections[collection]->IsGood()) {
338 wxLogError(wxT("Shapes patches cannot add entire collections"));