summaryrefslogtreecommitdiff
path: root/src/win95/sprchunk.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/win95/sprchunk.cpp')
-rw-r--r--src/win95/sprchunk.cpp964
1 files changed, 964 insertions, 0 deletions
diff --git a/src/win95/sprchunk.cpp b/src/win95/sprchunk.cpp
new file mode 100644
index 0000000..c8f74f3
--- /dev/null
+++ b/src/win95/sprchunk.cpp
@@ -0,0 +1,964 @@
+#include "sprchunk.hpp"
+#include "mishchnk.hpp"
+
+#if cencon
+#include "fnamefnc.hpp"
+#include "bmpnames.hpp"
+#include "shpchunk.hpp"
+#endif
+
+#ifdef cencon
+#define new my_new
+#endif
+//macro for helping to force inclusion of chunks when using libraries
+FORCE_CHUNK_INCLUDE_IMPLEMENT(sprchunk)
+
+extern Chunk* Parent_File;
+
+RIF_IMPLEMENT_DYNCREATE("SPRACTIO",Sprite_Action_Chunk)
+
+Sprite_Action_Chunk::Sprite_Action_Chunk(Chunk_With_Children* parent,const char* data,size_t /*datasize*/)
+: Chunk(parent, "SPRACTIO")
+{
+ Action=*((int*)data);
+ data+=4;
+ NumYaw=*((int*)data);
+ data+=4;
+ NumPitch=*((int*)data);
+ data+=4;
+ NumFrames=*((int*)data);
+ data+=4;
+ Flags=*((int*)data);
+ data+=4;
+ FrameTime=*((int*)data);
+ data+=4;
+ FrameList=new Frame**[NumYaw];
+ for(int i=0;i<NumYaw;i++)
+ {
+ FrameList[i]=new Frame*[NumPitch];
+ for(int j=0;j<NumPitch;j++)
+ {
+ FrameList[i][j]=new Frame[NumFrames];
+ for(int k=0;k<NumFrames;k++)
+ {
+ Frame* f=&FrameList[i][j][k];
+ f->Texture=*((int*)data);
+ data+=4;
+ f->CentreX=*((int*)data);
+ data+=4;
+ f->CentreY=*((int*)data);
+ data+=4;
+ for(int l=0;l<4;l++)
+ {
+ f->UVCoords[l][0]=*((int*)data);
+ data+=4;
+ f->UVCoords[l][1]=*((int*)data);
+ data+=4;
+ }
+ }
+ }
+ }
+}
+Sprite_Action_Chunk::Sprite_Action_Chunk(Chunk_With_Children* parent)
+: Chunk(parent, "SPRACTIO")
+{
+ Action=-1;
+ NumPitch=0;
+ NumYaw=0;
+ NumFrames=0;
+ FrameList=0;
+ Flags=0;
+ FrameTime=200;
+}
+size_t Sprite_Action_Chunk::size_chunk()
+{
+ chunk_size=36+NumFrames*NumPitch*NumYaw*44;
+ return chunk_size;
+}
+
+Sprite_Action_Chunk::~Sprite_Action_Chunk()
+{
+ for(int i=0;i<NumYaw;i++)
+ {
+ for(int j=0;j<NumPitch;j++)
+ {
+ delete [] FrameList[i][j];
+ }
+ delete[] FrameList[i];
+ }
+ delete [] FrameList;
+}
+
+
+BOOL Sprite_Action_Chunk::output_chunk (HANDLE &hand)
+{
+ unsigned long junk;
+ BOOL ok;
+ char * data_block;
+
+ data_block = this->make_data_block_from_chunk();
+
+ ok = WriteFile (hand, (long *) data_block, (unsigned long) chunk_size, &junk, 0);
+
+ delete [] data_block;
+
+ if (!ok) return FALSE;
+
+ return TRUE;
+}
+
+void Sprite_Action_Chunk::fill_data_block(char* data_start)
+{
+ strncpy (data_start, identifier, 8);
+
+ data_start += 8;
+
+ *((int *) data_start) = chunk_size;
+
+ data_start += 4;
+
+ *(int*)data_start=Action;
+ data_start += 4;
+ *(int*)data_start=NumYaw;
+ data_start += 4;
+ *(int*)data_start=NumPitch;
+ data_start += 4;
+ *(int*)data_start=NumFrames;
+ data_start += 4;
+ *(int*)data_start=Flags;
+ data_start += 4;
+ *(int*)data_start=FrameTime;
+ data_start += 4;
+
+ for(int i=0;i<NumYaw;i++)
+ {
+ for(int j=0;j<NumPitch;j++)
+ {
+ for(int k=0;k<NumFrames;k++)
+ {
+ Frame* f=&FrameList[i][j][k];
+ *(int*)data_start=f->Texture;
+ data_start += 4;
+ *(int*)data_start=f->CentreX;
+ data_start +=4;
+ *(int*)data_start=f->CentreY;
+ data_start +=4;
+ for(int l=0;l<4;l++)
+ {
+ *(int*)data_start=f->UVCoords[l][0];
+ data_start+=4;
+ *(int*)data_start=f->UVCoords[l][1];
+ data_start+=4;
+ }
+ }
+ }
+ }
+}
+
+//////////////////////////////////////////////////
+//Class Sprite_Header_Chunk
+RIF_IMPLEMENT_DYNCREATE("SPRIHEAD",Sprite_Header_Chunk)
+CHUNK_WITH_CHILDREN_LOADER("SPRIHEAD",Sprite_Header_Chunk)
+
+/*
+Children for Sprite_Header_Chunk :
+
+"SPRITVER" Sprite_Version_Number_Chunk
+"SPRITEPC" PC_Sprite_Chunk
+"SPRITEPS" Playstation_Sprite_Chunk
+"SPRITESA" Saturn_Sprite_Chunk
+"BMPLSTST" Bitmap_List_Store_Chunk
+"BMNAMVER" BMP_Names_Version_Chunk
+"BMNAMEXT" BMP_Names_ExtraData_Chunk
+"RIFFNAME" RIF_Name_Chunk
+"SHPEXTFN" Shape_External_Filename_Chunk
+"SPRISIZE" Sprite_Size_Chunk
+"BMPMD5ID" Bitmap_MD5_Chunk
+"SPRBMPSC" Sprite_Bitmap_Scale_Chunk
+"SPRBMPCE" Sprite_Bitmap_Centre_Chunk
+"SPREXTEN" Sprite_Extent_Chunk
+*/
+
+
+Sprite_Header_Chunk::Sprite_Header_Chunk(const char * file_name, Chunk_With_Children * parent)
+: Chunk_With_Children(parent,"SPRIHEAD")
+{
+// Load in whole chunk and traverse
+ HANDLE rif_file;
+ DWORD file_size;
+ DWORD file_size_from_file;
+ unsigned long bytes_read;
+ char * buffer;
+ char * buffer_ptr;
+ char id_buffer[9];
+
+ Parent_File = this;
+
+ error_code = 0;
+
+
+ rif_file = CreateFileA (file_name, GENERIC_READ, 0, 0, OPEN_EXISTING,
+ FILE_FLAG_RANDOM_ACCESS, 0);
+
+ if (rif_file == INVALID_HANDLE_VALUE) {
+ return;
+ }
+
+ file_size = GetFileSize (rif_file, NULL);
+
+
+ if (!ReadFile(rif_file, id_buffer, 8, &bytes_read, 0)) {
+ error_code = CHUNK_FAILED_ON_LOAD;
+ CloseHandle (rif_file);
+ return;
+ }
+
+ if (strncmp (id_buffer, "SPRIHEAD", 8)) {
+ error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
+ CloseHandle (rif_file);
+ return;
+ }
+
+ if (!ReadFile(rif_file, &file_size_from_file, 4, &bytes_read, 0)) {
+ error_code = CHUNK_FAILED_ON_LOAD;
+ CloseHandle (rif_file);
+ return;
+ }
+
+ if (file_size != file_size_from_file) {
+ error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
+ CloseHandle (rif_file);
+ return;
+ }
+
+
+ buffer = new char [file_size];
+
+ if (!ReadFile(rif_file, buffer, (file_size-12), &bytes_read, 0)) {
+ error_code = CHUNK_FAILED_ON_LOAD;
+ CloseHandle (rif_file);
+ return;
+ }
+
+ // Process the file
+
+ buffer_ptr = buffer;
+
+
+ // The start of the first chunk
+
+ while ((buffer_ptr-buffer)< ((signed) file_size-12) && !error_code) {
+
+ if ((*(int *)(buffer_ptr + 8)) + (buffer_ptr-buffer) > ((signed) file_size-12)) {
+ error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
+ break;
+ }
+
+ DynCreate(buffer_ptr);
+ buffer_ptr += *(int *)(buffer_ptr + 8);
+
+ }
+
+ delete [] buffer;
+
+ CloseHandle (rif_file);
+
+}
+
+
+Sprite_Header_Chunk::write_file(const char* fname)
+{
+ HANDLE rif_file;
+
+ rif_file = CreateFileA (fname, GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
+ FILE_FLAG_RANDOM_ACCESS, 0);
+
+ if (rif_file == INVALID_HANDLE_VALUE) {
+ return CHUNK_FAILED_ON_WRITE;
+ }
+
+ size_chunk();
+
+ if (!(this->output_chunk(rif_file)))
+ return CHUNK_FAILED_ON_WRITE;
+
+ CloseHandle (rif_file);
+
+ return 0;
+}
+
+Sprite_Header_Chunk::output_chunk(HANDLE & hand)
+{
+ unsigned long junk;
+ BOOL ok;
+ char * data_block;
+
+ data_block = this->make_data_block_from_chunk();
+
+ ok = WriteFile (hand, (long *) data_block, (unsigned long) chunk_size, &junk, 0);
+
+ delete [] data_block;
+
+ if (!ok) return FALSE;
+
+ return TRUE;
+}
+
+#if cencon
+void Sprite_Header_Chunk::post_input_processing()
+{
+ if (parent)
+ {
+ List<Chunk *> chlst;
+ GetRootChunk()->lookup_child("REBENVDT",chlst);
+ Lockable_Chunk_With_Children * envd = 0;
+ if (chlst.size()) envd = (Lockable_Chunk_With_Children *) chlst.first_entry();
+
+ BOOL fixpal = IsFixedPalette(envd);
+
+ lookup_child("SHPEXTFN",chlst);
+
+ if (chlst.size())
+ {
+ Shape_External_Filename_Chunk * sefc = (Shape_External_Filename_Chunk *)chlst.first_entry();
+
+ #if cencon
+ twprintf("Locating %s\n",sefc->file_name);
+ char * locatedfile = FindExistingFileInPath_PreferWriteable(CWnd::GetActiveWindow(),sefc->file_name,"RifSearchPath");
+ twprintf("Loading %s\n",locatedfile ? locatedfile : sefc->file_name);
+ Sprite_Header_Chunk rfc(locatedfile ? locatedfile : sefc->file_name);
+ if (locatedfile)
+ {
+ delete[] locatedfile;
+ }
+ #else
+ Sprite_Header_Chunk rfc(sefc->file_name);
+ #endif
+
+ if (rfc.error_code != 0)
+ {
+ return;
+ }
+
+ lookup_child("SPRITVER",chlst);
+ int myver = -2;
+ if (chlst.size())
+ {
+ Sprite_Version_Number_Chunk * svnc = (Sprite_Version_Number_Chunk *)chlst.first_entry();
+ myver = svnc->version_num;
+ }
+ rfc.lookup_child("SPRITVER",chlst);
+ int yourver = -1;
+ if (chlst.size())
+ {
+ Sprite_Version_Number_Chunk * svnc = (Sprite_Version_Number_Chunk *)chlst.first_entry();
+ yourver = svnc->version_num;
+ }
+
+ if (yourver != myver)
+ {
+ #define NOT_A_BITMAP_RELATED_CHUNK \
+ strncmp ("BMPLSTST", child_ptr->identifier, 8) && \
+ strncmp ("BMNAMVER", child_ptr->identifier, 8) && \
+ strncmp ("BMNAMEXT", child_ptr->identifier, 8) && \
+ strncmp ("RIFFNAME", child_ptr->identifier, 8) && \
+ strncmp ("SHPEXTFN", child_ptr->identifier, 8) && \
+ strncmp ("BMPMD5ID", child_ptr->identifier, 8)
+
+ Chunk * child_ptr = children;
+ List <Chunk *> chunks_to_delete;
+ while (child_ptr != NULL)
+ {
+ if (NOT_A_BITMAP_RELATED_CHUNK)
+ {
+ chunks_to_delete.add_entry(child_ptr);
+ }
+ child_ptr = child_ptr->next;
+ }
+ for (LIF<Chunk *> delchunks(&chunks_to_delete); !delchunks.done(); delchunks.next())
+ {
+ delete delchunks();
+ }
+
+ child_ptr = rfc.children;
+ while (child_ptr != NULL)
+ {
+ if (NOT_A_BITMAP_RELATED_CHUNK)
+ {
+ #define CREATE_CHUNK_END(_datablock) \
+ new Miscellaneous_Chunk(this,_datablock,_datablock+12,*(int *)(_datablock+8)-12);
+
+ #define CREATE_CHUNK_FOR(_datablock,_id,_chunkclass) \
+ if (!strncmp(_datablock,_id,8)) { \
+ new _chunkclass(this,_datablock+12,*(int *)(_datablock+8)-12); \
+ } else
+
+ child_ptr->prepare_for_output();
+ char * datablock = child_ptr->make_data_block_from_chunk();
+
+ CREATE_CHUNK_FOR(datablock,"SPRITVER",Sprite_Version_Number_Chunk)
+ CREATE_CHUNK_FOR(datablock,"SPRITEPC",PC_Sprite_Chunk)
+ CREATE_CHUNK_FOR(datablock,"SPRITEPS",Playstation_Sprite_Chunk)
+ CREATE_CHUNK_FOR(datablock,"SPRITESA",Saturn_Sprite_Chunk)
+ CREATE_CHUNK_FOR(datablock,"SPRISIZE",Sprite_Size_Chunk)
+ CREATE_CHUNK_FOR(datablock,"SPRBMPSC",Sprite_Bitmap_Scale_Chunk)
+ CREATE_CHUNK_FOR(datablock,"SPRBMPCE",Sprite_Bitmap_Centre_Chunk)
+ CREATE_CHUNK_FOR(datablock,"SPREXTEN",Sprite_Extent_Chunk)
+ CREATE_CHUNK_END(datablock)
+
+ delete[] datablock;
+ }
+ child_ptr = child_ptr->next;
+ }
+
+ }
+
+ Chunk_With_BMPs * blsc = 0;
+ Chunk_With_BMPs * gbnc = 0;
+
+ rfc.lookup_child("BMPLSTST",chlst);
+ if (chlst.size())
+ {
+ gbnc = (Chunk_With_BMPs *) chlst.first_entry();
+ if (!gbnc->bmps.size()) gbnc = 0;
+ }
+
+ List<Chunk *> oldlst;
+ lookup_child("BMPLSTST",oldlst);
+ assert (oldlst.size()<2);
+
+ if (oldlst.size())
+ {
+ blsc = (Bitmap_List_Store_Chunk *)oldlst.first_entry();
+ }
+ else
+ {
+ if (gbnc) blsc = new Bitmap_List_Store_Chunk(this);
+ }
+
+ BMP_Names_ExtraData * extended = 0;
+ if (blsc)
+ {
+ extended = blsc->GetExtendedData();
+ if (fixpal)
+ extended->flags = (GlobalBMPFlags)(extended->flags | GBF_FIXEDPALETTE);
+ else
+ extended->flags = (GlobalBMPFlags)(extended->flags & ~GBF_FIXEDPALETTE);
+ }
+ if (gbnc)
+ {
+ if ((gbnc->get_version_num()!=blsc->get_version_num()) || (gbnc->bmps.size() != blsc->bmps.size()))
+ { // other checks could be done as well
+ if (blsc->bmps.size())
+ {
+ BOOL neednewpalette = FALSE;
+
+ List<BMP_Name> newlist = gbnc->bmps;
+ for (LIF<BMP_Name> newLIF(&newlist); !newLIF.done(); newLIF.next())
+ {
+ BMP_Name newcur = newLIF();
+ newcur.flags = (BMPN_Flags) (newcur.flags & ~(COMPLETED_BMPN_FLAGS | ChunkBMPFlag_FixedPalette));
+ if (fixpal) newcur.flags = (BMPN_Flags) (newcur.flags | ChunkBMPFlag_FixedPalette);
+ for (LIF<BMP_Name> oldLIF(&blsc->bmps); !oldLIF.done(); oldLIF.next())
+ {
+ BMP_Name oldcur = oldLIF();
+ if (newcur == oldcur)
+ {
+ // do we need to requantize?
+ if ((oldcur.flags ^ newcur.flags) & CHECKMODIFY_BMPN_FLAGS
+ || newcur.flags & ChunkBMPFlag_UsesTransparency
+ && !(newcur.flags & ChunkBMPFlag_IFF)
+ && !(oldcur.flags & ChunkBMPFlag_IFF)
+ && oldcur.DifferentTransparencyColour(newcur))
+ oldcur.flags = (BMPN_Flags)(oldcur.flags & ~COMPLETED_BMPN_FLAGS);
+ // keep some of the old flags - the ones that can differ
+ newcur.flags = (BMPN_Flags)(newcur.flags & COPY_BMPN_FLAGS);
+ newcur.flags = (BMPN_Flags)(newcur.flags | oldcur.flags & ~COPY_BMPN_FLAGS);
+ if (oldcur.version_num != newcur.version_num)
+ {
+ neednewpalette = TRUE;
+ newcur.flags = (BMPN_Flags)(newcur.flags & ~ChunkBMPFlag_HistogramExists);
+ extended->flags = (GlobalBMPFlags)(extended->flags & ~GBF_HISTOGRAMEXISTS);
+ }
+ break;
+ }
+ }
+ if (oldLIF.done())
+ {
+ // reset palette up to date flag
+ neednewpalette = TRUE;
+ newcur.flags = (BMPN_Flags)(newcur.flags & ~(ChunkBMPFlag_HistogramExists | COMPLETED_BMPN_FLAGS));
+ extended->flags = (GlobalBMPFlags)(extended->flags & ~GBF_HISTOGRAMEXISTS);
+ }
+ newLIF.change_current(newcur);
+ }
+
+ // check if any bitmaps have been removed
+ for (LIF<BMP_Name> bli(&blsc->bmps); !bli.done(); bli.next())
+ {
+ if (!newlist.contains(bli()))
+ {
+ // delete assoc files
+ neednewpalette = TRUE;
+ extended->flags = (GlobalBMPFlags)(extended->flags & ~GBF_HISTOGRAMEXISTS);
+ }
+ }
+
+ if (neednewpalette)
+ {
+ Palette_Outdated(envd);
+ if (fixpal) FixedPalette_Outdated(envd);
+ envd->updated = TRUE;
+ }
+ blsc->bmps = newlist;
+ }
+ else
+ {
+ blsc->bmps = gbnc->bmps;
+ for (LIF<BMP_Name> flagresetLIF(&blsc->bmps); !flagresetLIF.done(); flagresetLIF.next())
+ {
+ BMP_Name current = flagresetLIF();
+ current.flags = (BMPN_Flags)(current.flags & (COPY_BMPN_FLAGS & ~ChunkBMPFlag_FixedPalette));
+ if (fixpal) current.flags = (BMPN_Flags) (current.flags | ChunkBMPFlag_FixedPalette);
+ flagresetLIF.change_current(current);
+ }
+ // reset palette up to date flag
+ extended->flags = (GlobalBMPFlags)(extended->flags & ~GBF_HISTOGRAMEXISTS);
+ Palette_Outdated(envd);
+ if (fixpal) FixedPalette_Outdated(envd);
+ envd->updated = TRUE;
+ }
+ blsc->max_index = gbnc->max_index;
+ blsc->set_version_num(gbnc->get_version_num());
+ assert (!strcmp("RSPRITES",parent->identifier));
+ ((Lockable_Chunk_With_Children *)parent)->updated = TRUE;
+ }
+ }
+ else
+ {
+ if (blsc)
+ {
+ if (blsc->bmps.size())
+ {
+ // reset palette up to date flag
+ extended->flags = (GlobalBMPFlags)(extended->flags & ~GBF_HISTOGRAMEXISTS);
+ Palette_Outdated(envd);
+ if (fixpal) FixedPalette_Outdated(envd);
+ envd->updated = TRUE;
+ assert (!strcmp("RSPRITES",parent->identifier));
+ ((Lockable_Chunk_With_Children *)parent)->updated = TRUE;
+ }
+ delete blsc;
+ }
+ }
+
+ }
+
+ }
+ Chunk_With_Children::post_input_processing();
+}
+#endif
+RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SPRITEPC",PC_Sprite_Chunk,"SPRIHEAD",Sprite_Header_Chunk)
+
+PC_Sprite_Chunk::PC_Sprite_Chunk(Sprite_Header_Chunk* parent,const char* data,size_t datasize)
+:Chunk_With_Children(parent,"SPRITEPC")
+{
+ const char * buffer_ptr = data;
+
+
+ while ((data-buffer_ptr)< (signed) datasize) {
+
+ if ((*(int *)(data + 8)) + (data-buffer_ptr) > (signed) datasize) {
+ Parent_File->error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
+ break;
+ }
+
+ if (!strncmp(data, "SPRACTIO",8)) {
+ new Sprite_Action_Chunk (this, (data + 12), (*(int *) (data + 8))-12);
+ data += *(int *)(data + 8);
+ }
+ else {
+ new Miscellaneous_Chunk (this, data, (data + 12), (*(int *) (data + 8)) -12 );
+ data += *(int *)(data + 8);
+ }
+
+ }
+}
+/////////////////////////////////////////
+RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SPRITESA",Saturn_Sprite_Chunk,"SPRIHEAD",Sprite_Header_Chunk)
+
+
+Saturn_Sprite_Chunk::Saturn_Sprite_Chunk(Sprite_Header_Chunk* parent,const char* data,size_t datasize)
+:Chunk_With_Children(parent,"SPRITESA")
+{
+ const char * buffer_ptr = data;
+
+
+ while ((data-buffer_ptr)< (signed) datasize) {
+
+ if ((*(int *)(data + 8)) + (data-buffer_ptr) > (signed) datasize) {
+ Parent_File->error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
+ break;
+ }
+
+ if (!strncmp(data, "SPRACTIO",8)) {
+ new Sprite_Action_Chunk (this, (data + 12), (*(int *) (data + 8))-12);
+ data += *(int *)(data + 8);
+ }
+ else {
+ new Miscellaneous_Chunk (this, data, (data + 12), (*(int *) (data + 8)) -12 );
+ data += *(int *)(data + 8);
+ }
+
+ }
+}
+/////////////////////////////////////////////
+RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SPRITEPS",Playstation_Sprite_Chunk,"SPRIHEAD",Sprite_Header_Chunk)
+
+Playstation_Sprite_Chunk::Playstation_Sprite_Chunk(Sprite_Header_Chunk* parent,const char* data,size_t datasize)
+:Chunk_With_Children(parent,"SPRITEPS")
+{
+ const char * buffer_ptr = data;
+
+
+ while ((data-buffer_ptr)< (signed) datasize) {
+
+ if ((*(int *)(data + 8)) + (data-buffer_ptr) > (signed) datasize) {
+ Parent_File->error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
+ break;
+ }
+
+ if (!strncmp(data, "SPRACTIO",8)) {
+ new Sprite_Action_Chunk (this, (data + 12), (*(int *) (data + 8))-12);
+ data += *(int *)(data + 8);
+ }
+ else {
+ new Miscellaneous_Chunk (this, data, (data + 12), (*(int *) (data + 8)) -12 );
+ data += *(int *)(data + 8);
+ }
+
+ }
+}
+
+
+
+////////////////////////////////////////////////////////////
+RIF_IMPLEMENT_DYNCREATE("SPRISIZE",Sprite_Size_Chunk)
+
+
+Sprite_Size_Chunk::Sprite_Size_Chunk(Chunk_With_Children* parent,const char* data,size_t /*datasize*/)
+: Chunk(parent, "SPRISIZE")
+{
+ scale=*(double*)data;
+ data+=8;
+ maxy=*(double*)data;
+ data+=8;
+ maxx=*(double*)data;
+ data+=8;
+ radius=*(int*)data;
+ data+=4;
+ Flags=*(int*)data;
+ data+=4;
+}
+
+Sprite_Size_Chunk::Sprite_Size_Chunk(Chunk_With_Children* parent)
+: Chunk(parent, "SPRISIZE")
+{
+ scale=15.625;
+ maxy=1000;
+ maxx=500;
+ radius=0;
+ Flags=0;
+}
+
+BOOL Sprite_Size_Chunk::output_chunk (HANDLE &hand)
+{
+ unsigned long junk;
+ BOOL ok;
+ char * data_block;
+
+ data_block = this->make_data_block_from_chunk();
+
+ ok = WriteFile (hand, (long *) data_block, (unsigned long) chunk_size, &junk, 0);
+
+ delete [] data_block;
+
+ if (!ok) return FALSE;
+
+ return TRUE;
+}
+
+size_t Sprite_Size_Chunk::size_chunk()
+{
+ chunk_size=44;
+ return chunk_size;
+}
+
+void Sprite_Size_Chunk::fill_data_block(char* data_start)
+{
+ strncpy (data_start, identifier, 8);
+
+ data_start += 8;
+
+ *((int *) data_start) = chunk_size;
+
+ data_start += 4;
+
+ *(double*)data_start=scale;
+ data_start+=8;
+ *(double*)data_start=maxy;
+ data_start+=8;
+ *(double*)data_start=maxx;
+ data_start+=8;
+ *(int*)data_start=radius;
+ data_start+=4;
+ *(int*)data_start=Flags;
+ data_start+=4;
+}
+///////////////////////////////////////////////
+RIF_IMPLEMENT_DYNCREATE("SPRITVER",Sprite_Version_Number_Chunk)
+
+Sprite_Version_Number_Chunk::Sprite_Version_Number_Chunk(Chunk_With_Children* parent,const char* data,size_t /*datasize*/)
+: Chunk(parent, "SPRITVER")
+{
+ version_num=*(int*)data;
+ data+=4;
+}
+
+Sprite_Version_Number_Chunk::Sprite_Version_Number_Chunk(Chunk_With_Children* parent)
+: Chunk(parent, "SPRITVER")
+{
+ version_num=0;
+}
+
+BOOL Sprite_Version_Number_Chunk::output_chunk (HANDLE &hand)
+{
+ unsigned long junk;
+ BOOL ok;
+ char * data_block;
+
+ data_block = this->make_data_block_from_chunk();
+
+ ok = WriteFile (hand, (long *) data_block, (unsigned long) chunk_size, &junk, 0);
+
+ delete [] data_block;
+
+ if (!ok) return FALSE;
+
+ return TRUE;
+}
+
+size_t Sprite_Version_Number_Chunk::size_chunk()
+{
+ chunk_size=16;
+ return chunk_size;
+}
+
+void Sprite_Version_Number_Chunk::fill_data_block(char* data_start)
+{
+ strncpy (data_start, identifier, 8);
+
+ data_start += 8;
+
+ *((int *) data_start) = chunk_size;
+
+ data_start += 4;
+
+ *(int*)data_start=version_num;
+}
+
+
+//////////////////////////////////////////////////////////
+RIF_IMPLEMENT_DYNCREATE("SPRBMPSC",Sprite_Bitmap_Scale_Chunk)
+
+
+Sprite_Bitmap_Scale_Chunk::Sprite_Bitmap_Scale_Chunk(Chunk_With_Children* parent,const char* data,size_t /*datasize*/)
+: Chunk(parent, "SPRBMPSC")
+{
+ NumBitmaps=*(int*)data;
+ data+=4;
+ if(NumBitmaps)
+ {
+ Scale=new float[NumBitmaps];
+ for(int i=0;i<NumBitmaps;i++)
+ {
+ Scale[i]=*(float*)data;
+ data+=sizeof(float);
+ }
+ }
+ else
+ Scale=0;
+}
+Sprite_Bitmap_Scale_Chunk::Sprite_Bitmap_Scale_Chunk(Chunk_With_Children* parent)
+: Chunk(parent, "SPRBMPSC")
+{
+ NumBitmaps=0;
+ Scale=0;
+}
+Sprite_Bitmap_Scale_Chunk::~Sprite_Bitmap_Scale_Chunk()
+{
+ delete [] Scale;
+}
+size_t Sprite_Bitmap_Scale_Chunk::size_chunk()
+{
+ chunk_size=16+sizeof(float)*NumBitmaps;
+ return chunk_size;
+}
+
+void Sprite_Bitmap_Scale_Chunk::fill_data_block(char* data_start)
+{
+ strncpy (data_start, identifier, 8);
+
+ data_start += 8;
+
+ *((int *) data_start) = chunk_size;
+
+ data_start += 4;
+
+ *(int*)data_start=NumBitmaps;
+ data_start+=4;
+ for(int i=0;i<NumBitmaps;i++)
+ {
+ *(float*)data_start=Scale[i];
+ data_start+=sizeof(float);
+ }
+}
+/////////////////////////////////////////////////////
+RIF_IMPLEMENT_DYNCREATE("SPRBMPCE",Sprite_Bitmap_Centre_Chunk)
+
+Sprite_Bitmap_Centre_Chunk::Sprite_Bitmap_Centre_Chunk(Chunk_With_Children* parent,const char* data,size_t /*datasize*/)
+: Chunk(parent, "SPRBMPCE")
+{
+ NumBitmaps=*(int*)data;
+ data+=4;
+ if(NumBitmaps)
+ {
+ CentreX=new int[NumBitmaps];
+ CentreY=new int[NumBitmaps];
+ OffsetX=new int[NumBitmaps];
+ OffsetY=new int[NumBitmaps];
+
+ for(int i=0;i<NumBitmaps;i++)
+ {
+ CentreX[i]=*(int*)data;
+ data+=4;
+ CentreY[i]=*(int*)data;
+ data+=4;
+ OffsetX[i]=*(int*)data;
+ data+=4;
+ OffsetY[i]=*(int*)data;
+ data+=4;
+ }
+ }
+ else
+ {
+ CentreX=0;
+ CentreY=0;
+ OffsetX=0;
+ OffsetY=0;
+ }
+ spare=*(int*)data;
+}
+Sprite_Bitmap_Centre_Chunk::Sprite_Bitmap_Centre_Chunk(Chunk_With_Children* parent)
+: Chunk(parent, "SPRBMPCE")
+{
+ NumBitmaps=0;
+ CentreX=CentreY=0;
+ OffsetX=OffsetY=0;
+ spare=0;
+}
+Sprite_Bitmap_Centre_Chunk::~Sprite_Bitmap_Centre_Chunk()
+{
+ delete [] CentreX;
+ delete [] CentreY;
+ delete [] OffsetX;
+ delete [] OffsetY;
+}
+size_t Sprite_Bitmap_Centre_Chunk::size_chunk()
+{
+ chunk_size=20+16*NumBitmaps;
+ return chunk_size;
+}
+
+void Sprite_Bitmap_Centre_Chunk::fill_data_block(char* data_start)
+{
+ strncpy (data_start, identifier, 8);
+
+ data_start += 8;
+
+ *((int *) data_start) = chunk_size;
+
+ data_start += 4;
+
+ *(int*)data_start=NumBitmaps;
+ data_start+=4;
+ for(int i=0;i<NumBitmaps;i++)
+ {
+ *(int*)data_start=CentreX[i];
+ data_start+=4;
+ *(int*)data_start=CentreY[i];
+ data_start+=4;
+ *(int*)data_start=OffsetX[i];
+ data_start+=4;
+ *(int*)data_start=OffsetY[i];
+ data_start+=4;
+ }
+ *(int*)data_start=spare;
+}
+/////////////////////////////////////////////////////
+RIF_IMPLEMENT_DYNCREATE("SPREXTEN",Sprite_Extent_Chunk)
+
+Sprite_Extent_Chunk::Sprite_Extent_Chunk(Chunk_With_Children* parent,const char* data,size_t /*datasize*/)
+: Chunk(parent, "SPREXTEN")
+{
+ minx=*(double*)data;
+ data+=8;
+ maxx=*(double*)data;
+ data+=8;
+ miny=*(double*)data;
+ data+=8;
+ maxy=*(double*)data;
+ data+=8;
+ spare1=*(int*)data;
+ data+=4;
+ spare2=*(int*)data;
+ data+=4;
+}
+Sprite_Extent_Chunk::Sprite_Extent_Chunk(Chunk_With_Children* parent)
+: Chunk(parent, "SPREXTEN")
+{
+ minx=miny=-1000;
+ maxx=maxy=1000;
+ spare1=spare2=0;
+}
+size_t Sprite_Extent_Chunk::size_chunk()
+{
+ chunk_size=12+40;
+ return chunk_size;
+}
+
+void Sprite_Extent_Chunk::fill_data_block(char* data_start)
+{
+ strncpy (data_start, identifier, 8);
+
+ data_start += 8;
+
+ *((int *) data_start) = chunk_size;
+
+ data_start += 4;
+
+ *(double*)data_start=minx;
+ data_start+=8;
+ *(double*)data_start=maxx;
+ data_start+=8;
+ *(double*)data_start=miny;
+ data_start+=8;
+ *(double*)data_start=maxy;
+ data_start+=8;
+
+ *(int*)data_start=spare1;
+ data_start+=4;
+ *(int*)data_start=spare2;
+ data_start+=4;
+
+}