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 #ifndef SHAPESLOADERS_H
20 #define SHAPESLOADERS_H
22 #include "wx/wxprec.h"
25 #include "wx/clipbrd.h"
29 #include "../BigEndianBuffer.h"
31 #define COLLECTIONS_PER_FILE 32
33 #define SIZEOF_collection_header 32
41 // So that subclasses can change their status
45 ShapesElement(bool verbose): mVerboseLoading(verbose), mGoodData(false) {}
46 ~ShapesElement(void) {}
48 bool IsGood() const { return mGoodData; }
49 bool IsVerbose() const { return mVerboseLoading; }
52 // internal-use utility constants
54 COLL_VERSION_8BIT = 0,
55 COLL_VERSION_TRUECOLOR
59 class ShapesColor: public ShapesElement
64 unsigned short mRed, mGreen, mBlue;
67 // constructor/destructor
68 ShapesColor(bool verbose = false);
69 ShapesColor(unsigned int r, unsigned int g, unsigned int b, unsigned int value, bool luminescent = false, bool verbose = false);
73 bool operator==(const ShapesColor& other) const;
74 bool operator!=(const ShapesColor& other) const { return !(*this == other); }
76 bool Luminescent(void) const { return mLuminescent; }
77 unsigned char Value(void) const { return mValue; }
78 unsigned short Red(void) const { return mRed; }
79 unsigned short Green(void) const { return mGreen; }
80 unsigned short Blue(void) const { return mBlue; }
81 void SetLuminescent(bool l) { mLuminescent = l; }
82 void SetRed(unsigned short c) { mRed = c; }
83 void SetGreen(unsigned short c) { mGreen = c; }
84 void SetBlue(unsigned short c) { mBlue = c; }
86 BigEndianBuffer& SaveObject(BigEndianBuffer& buffer);
87 BigEndianBuffer& LoadObject(BigEndianBuffer& buffer);
91 class ShapesColorTable: public ShapesElement
94 vector<ShapesColor*> mColors;
97 ShapesColorTable(bool verbose = false);
98 ShapesColorTable(std::ifstream& ifs, wxString file_ext);
99 ~ShapesColorTable(void);
102 bool operator==(const ShapesColorTable& other) const;
103 bool operator!=(const ShapesColorTable& other) const { return !(*this == other); }
105 unsigned int ColorCount(void) const { return mColors.size(); }
106 ShapesColor *GetColor(unsigned int index) const { return mColors[index]; }
107 void InsertColor(ShapesColor *color) { mColors.push_back(color); }
109 unsigned int SizeInFile() const;
111 BigEndianBuffer& SaveObject(BigEndianBuffer& buffer);
112 BigEndianBuffer& LoadObject(BigEndianBuffer& buffer, unsigned int offset, unsigned int color_count);
113 BigEndianBuffer& SavePatch(BigEndianBuffer& buffer, int index);
114 int SaveToGimp(wxString path) const;
115 int SaveToPhotoshop(wxString path) const;
119 class ShapesBitmap: public ShapesElement
122 short mWidth, mHeight,
123 mBytesPerRow, // width for uncompressed bitmaps, -1 for compressed ones
125 bool mColumnOrder, // store in column-order format
127 unsigned char *mPixels;
128 // list of frames referencing this bitmap
132 // constructor/destructor
133 ShapesBitmap(bool verbose = false);
134 ShapesBitmap(wxImage image, ShapesColorTable *colortable);
138 bool operator==(const ShapesBitmap& other) const;
139 bool operator!=(const ShapesBitmap& other) const { return !(*this == other); }
142 short Width(void) const { return mWidth; }
143 short Height(void) const { return mHeight; }
144 short BytesPerRow(void) const { return mBytesPerRow; }
145 short BitDepth(void) const { return mBitDepth; }
146 bool IsColumnOrdered(void) const { return mColumnOrder; }
147 bool IsTransparent(void) const { return mTransparent; }
148 unsigned char* Pixels(void) const { return mPixels; }
150 void SetWidth(short w) { mWidth = w; }
151 void SetHeight(short h) { mHeight = h; }
152 void SetBytesPerRow(short b) { mBytesPerRow = b; }
153 void SetBitDepth(short b) { mBitDepth = b; }
154 void SetColumnOrdered(bool b) { mColumnOrder = b; }
155 void SetTransparent(bool n) { mTransparent = n; }
157 void ClipboardCopy(ShapesColorTable* colorTable) const;
158 void ClipboardPaste(ShapesColorTable* colorTable);
159 void FromImage(wxImage image, ShapesColorTable* colorTable);
160 unsigned int SizeInFile() const;
161 unsigned int SizeInPatch() const { return SizeInFile() + 12; }
162 BigEndianBuffer& SaveObject(BigEndianBuffer& buffer);
163 BigEndianBuffer& LoadObject(BigEndianBuffer& buffer, unsigned int offset);
164 BigEndianBuffer& SavePatch(BigEndianBuffer& buffer, int index);
165 void SaveToBMP(wxString path, ShapesColorTable *colorTable) const;
166 void SaveMaskToBMP(wxString path) const;
169 // a frame, aka "low level shape definition"
170 class ShapesFrame : public ShapesElement
176 float mMinimumLightIntensity;
178 // bitmap scale factor. Computed when loading Shapes
179 // using world_* fields and associated bitmap dimensions
182 short mOriginX, mOriginY;
183 // keypoint. Used in player legs shapes to specify where to attach torso shapes
185 // FIXME do we really need to store these fields here?
186 // scaled bitmap rectangle in world coordinates. The physical bitmap rectangle
187 // is scaled around the frame origin position, which gets translated to (0,0).
189 // world_left = -scale_factor * origin_x
190 // world_top = scale_factor * origin_y
191 // world_right = scale_factor * (width - origin_x)
192 // world_bottom = -scale_factor * (height - origin_y)
193 short mWorldLeft, mWorldRight, mWorldTop, mWorldBottom;
194 // scaled keypoint position in world coordinates. Computed as:
195 // world_x0 = scale_factor * (key_x - origin_x)
196 // world_y0 = -scale_factor * (key_y - origin_y)
197 short mWorldX0, mWorldY0;
198 // list of sequences referencing this frame
202 // constructor/destructor
203 ShapesFrame(bool verbose = false);
206 bool operator==(const ShapesFrame& other) const;
207 bool operator!=(const ShapesFrame& other) const { return !(*this == other); }
209 bool IsXmirrored(void) const {return mXmirror;}
210 bool IsYmirrored(void) const {return mYmirror;}
211 bool IsKeypointObscured(void) const {return mKeypointObscured;}
212 float MinimumLightIntensity(void) const {return mMinimumLightIntensity;}
213 int ScaleFactor(void) const {return mScaleFactor;}
214 short BitmapIndex(void) const {return mBitmapIndex;}
215 short OriginX(void) const {return mOriginX;}
216 short OriginY(void) const {return mOriginY;}
217 short KeyX(void) const {return mKeyX;}
218 short KeyY(void) const {return mKeyY;}
219 short WorldLeft(void) const {return mWorldLeft;}
220 short WorldRight(void) const {return mWorldRight;}
221 short WorldTop(void) const {return mWorldTop;}
222 short WorldBottom(void) const {return mWorldBottom;}
223 short WorldX0(void) const {return mWorldX0;}
224 short WorldY0(void) const {return mWorldY0;}
226 void SetXmirrored(bool b) {mXmirror = b;}
227 void SetYmirrored(bool b) {mYmirror = b;}
228 void SetKeypointObscured(bool b) {mKeypointObscured = b;}
229 void SetMinimumLightIntensity(float v) {mMinimumLightIntensity = v;}
230 void SetBitmapIndex(short i) {mBitmapIndex = i;}
231 void SetScaleFactor(int s) {mScaleFactor = s;}
232 void SetOriginX(short x) {mOriginX = x;}
233 void SetOriginY(short y) {mOriginY = y;}
234 void SetKeyX(short x) {mKeyX = x;}
235 void SetKeyY(short y) {mKeyY = y;}
236 void SetWorldLeft(short s) {mWorldLeft = s;}
237 void SetWorldRight(short s) {mWorldRight = s;}
238 void SetWorldTop(short s) {mWorldTop = s;}
239 void SetWorldBottom(short s) {mWorldBottom = s;}
240 void SetWorldX0(short s) {mWorldX0 = s;}
241 void SetWorldY0(short s) {mWorldY0 = s;}
243 unsigned int SizeInFile() const;
244 BigEndianBuffer& SaveObject(BigEndianBuffer& buffer);
245 BigEndianBuffer& SavePatch(BigEndianBuffer& buffer, int index);
246 BigEndianBuffer& LoadObject(BigEndianBuffer& buffer, unsigned int offset);
249 // sequence types (ShapesSequence.number_of_views). Nobody
250 // seems to know what these values really mean, they just
251 // tell the actual number of views in a redundant way
253 ANIMATED_1 = 1, // simple isotropic animation
254 ANIMATED_2TO8 = 2, // 8 view animation
255 ANIMATED_3TO4 = 3, // 4 view animation
256 ANIMATED_4 = 4, // 4 view animation
257 ANIMATED_5TO8 = 5, // 8 view animation
258 ANIMATED_8 = 8, // 8 view animation
259 ANIMATED_3TO5 = 9, // 5 view animation
260 UNANIMATED = 10, // no animation, choose a random frame
261 ANIMATED_5 = 11 // 5 view animation
264 // a sequence, aka "high level shape definition"
265 class ShapesSequence: public ShapesElement
269 unsigned short mFlags;
271 short mNumberOfViews,
282 //FIXME This could be made private
284 vector<short> mFrameIndexes;
287 // constructor/destructor
288 ShapesSequence(bool verbose = false);
289 ~ShapesSequence(void);
291 bool operator==(const ShapesSequence& other) const;
292 bool operator!=(const ShapesSequence& other) const { return !(*this == other); }
294 short Type(void) const {return mType;}
295 unsigned short Flags(void) const {return mFlags;}
296 wxString Name(void) const {return mName;}
297 short NumberOfViews(void) const {return mNumberOfViews;}
298 short FramesPerView(void) const {return mFramesPerView;}
299 short TicksPerFrame(void) const {return mTicksPerFrame;}
300 short KeyFrame(void) const {return mKeyFrame;}
301 short TransferMode(void) const {return mTransferMode;}
302 short TransferModePeriod(void) const {return mTransferModePeriod;}
303 short FirstFrameSound(void) const {return mFirstFrameSound;}
304 short KeyFrameSound(void) const {return mKeyFrameSound;}
305 short LastFrameSound(void) const {return mLastFrameSound;}
306 short PixelsToWorld(void) const {return mPixelsToWorld;}
307 short LoopFrame(void) const {return mLoopFrame;}
308 unsigned int FrameIndexCount(void) const {return mFrameIndexes.size();}
309 short GetFrameIndex(unsigned int index) const {return mFrameIndexes[index];}
311 void SetType(short t) {mType = t;}
312 void SetFlags(unsigned short f) {mFlags = f;}
313 void SetName(wxString name) {mName = name;}
314 void SetNumberOfViews(short n) {mNumberOfViews = n;}
315 void SetFramesPerView(short n) {mFramesPerView = n;}
316 void SetTicksPerFrame(short n) {mTicksPerFrame = n;}
317 void SetKeyFrame(short n) {mKeyFrame = n;}
318 void SetTransferMode(short n) {mTransferMode = n;}
319 void SetTransferModePeriod(short n) {mTransferModePeriod = n;}
320 void SetFirstFrameSound(short n) {mFirstFrameSound = n;}
321 void SetKeyFrameSound(short n) {mKeyFrameSound = n;}
322 void SetLastFrameSound(short n) {mLastFrameSound = n;}
323 void SetPixelsToWorld(short n) {mPixelsToWorld = n;}
324 void SetLoopFrame(short n) {mLoopFrame = n;}
325 void SetFrameIndex(unsigned int index, short value) {mFrameIndexes[index] = value;}
327 unsigned int SizeInFile() const;
328 unsigned int SizeInPatch() const { return SizeInFile() + 12; }
329 BigEndianBuffer& SaveObject(BigEndianBuffer& buffer);
330 BigEndianBuffer& LoadObject(BigEndianBuffer& buffer, long offset);
331 BigEndianBuffer& SavePatch(BigEndianBuffer& buffer, int index);
334 int ActualNumberOfViews(int t);
336 // chunk types. Bitmap encoding seems to depend on this setting
338 _unused_collection = 0, // plain
339 _wall_collection, // plain
340 _object_collection, // RLE
341 _interface_collection, // plain
342 _scenery_collection // RLE
346 class ShapesChunk: public ShapesElement
349 short mVersion; // COLLECTION_VERSION (same for all Marathon games)
351 unsigned short mFlags; // unused; 0 in Durandal/Infinity, 1 in Rubicon and others
352 short mPixelsToWorld;
354 vector<ShapesColorTable*> mColorTables;
355 vector<ShapesSequence*> mSequences;
356 vector<ShapesFrame*> mFrames;
357 vector<ShapesBitmap*> mBitmaps;
360 // constructor/destructor
361 ShapesChunk(bool verbose = false);
364 bool operator==(const ShapesChunk& other) const;
365 bool operator!=(const ShapesChunk& other) const { return !(*this == other); }
367 int Version() const {return mVersion;}
368 int Type() const {return mType;}
369 int Flags() const {return mFlags;}
370 int ScaleFactor() const {return mPixelsToWorld;}
371 unsigned int ColorTableCount() const {return mColorTables.size();}
372 unsigned int BitmapCount() const {return mBitmaps.size();}
373 unsigned int FrameCount() const {return mFrames.size();}
374 unsigned int SequenceCount() const {return mSequences.size();}
375 ShapesColorTable* GetColorTable(unsigned int index) const;
376 ShapesBitmap* GetBitmap(unsigned int index) const;
377 ShapesFrame* GetFrame(unsigned int index) const;
378 ShapesSequence* GetSequence(unsigned int index) const;
380 void InsertColorTable(ShapesColorTable *ct);
381 void DeleteColorTable(unsigned int ct);
382 void InsertBitmap(ShapesBitmap *b);
383 void DeleteBitmap(unsigned int b);
384 void InsertFrame(ShapesFrame *f);
385 void DeleteFrame(unsigned int f);
386 void InsertSequence(ShapesSequence *s);
387 void DeleteSequence(unsigned int s);
390 void ClipboardCopy();
391 void ClipboardPaste();
392 unsigned int SizeInFile() const;
393 unsigned int SizeInPatch(const ShapesChunk* other) const;
394 BigEndianBuffer& SaveObject(BigEndianBuffer& stream);
395 BigEndianBuffer& SavePatch(BigEndianBuffer& stream, const ShapesChunk* other);
396 BigEndianBuffer& LoadObject(BigEndianBuffer& stream);
397 BigEndianBuffer& LoadPatch(BigEndianBuffer& buffer);
400 // a Shapes collection
401 class ShapesCollection: public ShapesElement
405 unsigned short mFlags;
406 ShapesChunk *mChunks[2]; // chunks for 8-bit and truecolor game
409 ShapesCollection(bool verbose = false);
410 ~ShapesCollection(void);
412 int Status(void) const {return mStatus;}
413 int Flags(void) const {return mFlags;}
414 // collection data access
415 bool Defined(unsigned int chunk) const;
416 int Version(unsigned int chunk) const;
417 int Type(unsigned int chunk) const;
418 int Flags(unsigned int chunk) const;
419 int ScaleFactor(unsigned int chunk) const;
420 int ColorTableCount(unsigned int chunk) const;
421 int BitmapCount(unsigned int chunk) const;
422 int FrameCount(unsigned int chunk) const;
423 int SequenceCount(unsigned int chunk) const;
424 ShapesColorTable* GetColorTable(unsigned int chunk, unsigned int index) const;
425 ShapesBitmap* GetBitmap(unsigned int chunk, unsigned int index) const;
426 ShapesFrame* GetFrame(unsigned int chunk, unsigned int index) const;
427 ShapesSequence* GetSequence(unsigned int chunk, unsigned int index) const;
428 ShapesChunk* GetChunk(unsigned int chunk) const;
429 // collection alteration
430 void InsertColorTable(ShapesColorTable *ct, unsigned int chunk);
431 void DeleteColorTable(unsigned int chunk, unsigned int ct);
432 void InsertBitmap(ShapesBitmap *b, unsigned int chunk);
433 void DeleteBitmap(unsigned int chunk, unsigned int b);
434 void InsertFrame(ShapesFrame *f, unsigned int chunk);
435 void DeleteFrame(unsigned int chunk, unsigned int f);
436 void InsertSequence(ShapesSequence *s, unsigned int chunk);
437 void DeleteSequence(unsigned int chunk, unsigned int s);
439 unsigned int SizeInFile(unsigned int chunk) const;
441 #if wxUSE_STD_IOSTREAM
442 wxSTD ostream& SaveObject(wxSTD ostream& stream);
443 wxSTD ostream& SavePatch(wxSTD ostream& stream, const ShapesCollection& other, int index, int depth);
444 wxSTD istream& LoadObject(wxSTD istream& stream);
446 wxOutputStream& SaveObject(wxOutputStream& stream);
447 wxOutputStream& SavePatch(wxOutputStream& stream, const ShapesCollection& other, int index, int depth);
448 wxInputStream& LoadObject(wxInputStream& stream);
450 BigEndianBuffer& LoadPatch(BigEndianBuffer& buffer);