summaryrefslogtreecommitdiff
path: root/3dc/win95/CHUNKPAL.CPP
diff options
context:
space:
mode:
authorRebellion Developments <rebellion@nomail>2000-03-16 11:25:00 +0100
committerPatryk Obara <dreamer.tan@gmail.com>2019-08-19 05:45:17 +0200
commit218ca90543758a20ac326e444ca0643174ca7384 (patch)
tree16bfe3e5307f9f515489000f28728224291a0e3b /3dc/win95/CHUNKPAL.CPP
Import Aliens vs Predator - Gold (Build 116)
Source code release, imported from: https://www.gamefront.com/games/aliens-vs-predator-3/file/avp-gold-complete-source-code All text files were converted to Unix format.
Diffstat (limited to '3dc/win95/CHUNKPAL.CPP')
-rw-r--r--3dc/win95/CHUNKPAL.CPP1007
1 files changed, 1007 insertions, 0 deletions
diff --git a/3dc/win95/CHUNKPAL.CPP b/3dc/win95/CHUNKPAL.CPP
new file mode 100644
index 0000000..0cf1185
--- /dev/null
+++ b/3dc/win95/CHUNKPAL.CPP
@@ -0,0 +1,1007 @@
+#include "chunkpal.hpp"
+#include "mishchnk.hpp"
+
+#if engine
+
+#ifndef UseLocalAssert
+#define UseLocalAssert 1
+#endif
+#include "ourasert.h"
+#define assert(x) GLOBALASSERT(x)
+
+#else
+
+#if cencon
+#include "ccassert.h"
+#else
+#include <assert.h>
+#endif
+
+#endif
+//macro for helping to force inclusion of chunks when using libraries
+FORCE_CHUNK_INCLUDE_IMPLEMENT(chunkpal)
+
+///////////////////////////////////////
+
+// Class Environment_Palette_Chunk functions
+
+
+void Palette_Outdated(Chunk_With_Children * parent)
+{
+ if (parent)
+ {
+ List<Chunk *> plist;
+ parent->lookup_child("ENVPALET",plist);
+ for (LIF<Chunk *> plit(&plist); !plit.done(); plit.next())
+ {
+ ((Environment_Palette_Chunk *)plit())->flags &= ~EnvPalFlag_UpToDate;
+ }
+ }
+}
+
+void FixedPalette_Outdated(Chunk_With_Children * parent)
+{
+ if (parent)
+ {
+ List<Chunk *> plist;
+ parent->lookup_child("PRSETPAL",plist);
+ for (LIF<Chunk *> plit(&plist); !plit.done(); plit.next())
+ {
+ for (LIF<Preset_Palette> findconst(&((Preset_Palette_Chunk *)plit())->pplist); !findconst.done(); findconst.next())
+ {
+ Preset_Palette temp = findconst();
+ if (temp.flags & PrePalFlag_Reserved)
+ {
+ temp.flags &= ~PrePalFlag_UpToDate;
+ findconst.change_current(temp);
+ }
+ }
+ }
+ }
+}
+
+BOOL IsFixedPalette(Chunk_With_Children * parent)
+{
+ if (parent)
+ {
+ List<Chunk *> plist;
+ parent->lookup_child("PRSETPAL",plist);
+ for (LIF<Chunk *> plit(&plist); !plit.done(); plit.next())
+ {
+ for (LIF<Preset_Palette> findconst(&((Preset_Palette_Chunk *)plit())->pplist); !findconst.done(); findconst.next())
+ {
+ if (findconst().flags & PrePalFlag_Reserved)
+ {
+ return TRUE;
+ }
+ }
+ }
+ parent->lookup_child("SETPALST",plist);
+ for (plit = LIF<Chunk *> (&plist); !plit.done(); plit.next())
+ {
+ for (LIF<Preset_Palette> findconst(&((Preset_Palette_Store_Chunk *)plit())->pplist); !findconst.done(); findconst.next())
+ {
+ if (findconst().flags & PrePalFlag_Reserved)
+ {
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+RIF_IMPLEMENT_DYNCREATE("ENVPALET",Environment_Palette_Chunk)
+
+Environment_Palette_Chunk::~Environment_Palette_Chunk ()
+{
+ if (pixel_data)
+ {
+ unsigned char * temp_pd = (unsigned char *)pixel_data;
+ delete [] temp_pd;
+ }
+}
+
+size_t Environment_Palette_Chunk::size_chunk()
+{
+ chunk_size = 12 + 8 + (width * height * 3 + 3 & ~3);
+ return chunk_size;
+}
+
+void Environment_Palette_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) = width * height;
+ *((int*)(data_start+4)) = flags;
+
+ data_start += 8;
+
+ for (int i=0; i<(width*height*3); i++)
+ {
+ data_start[i] = pixel_data[i];
+ }
+
+}
+
+
+///////////////////////////////////////
+
+// Class Preset_Palette_Chunk functions
+
+
+Preset_Palette::~Preset_Palette ()
+{
+ if (pixel_data)
+ {
+ unsigned char * temp_pd = (unsigned char *)pixel_data;
+ delete [] temp_pd;
+ }
+ if (name) delete[] name;
+}
+
+Preset_Palette::Preset_Palette (Preset_Palette const & c)
+: size(c.size)
+, flags(c.flags)
+, reserved1(c.reserved1)
+, reserved2(c.reserved2)
+, startpos(c.startpos)
+, pixel_data(grab_pixel_data(c.size, c.pixel_data))
+, name(0)
+{
+ if (c.name)
+ {
+ name = new char[strlen(c.name)+1];
+ strcpy(name,c.name);
+ }
+}
+
+Preset_Palette & Preset_Palette::operator = (Preset_Palette const & c)
+{
+ if (pixel_data)
+ {
+ unsigned char * temp_pd = (unsigned char *)pixel_data;
+ delete [] temp_pd;
+ }
+ if (name)
+ {
+ delete[] name;
+ name = 0;
+ }
+ if (c.name)
+ {
+ name = new char[strlen(c.name)+1];
+ strcpy(name,c.name);
+ }
+
+ *(int *)&size = c.size;
+ *(int *)&flags = c.flags;
+ *(int *)&reserved1 = c.reserved1;
+ *(int *)&reserved2 = c.reserved2;
+ *(int *)&startpos = c.startpos;
+
+ *(const unsigned char * *)&pixel_data = grab_pixel_data(c.size,c.pixel_data);
+
+ return *this;
+}
+
+
+
+size_t Preset_Palette::size_chunk() const
+{
+ return 20 + (size * 3 + (name ? strlen(name)+1 : 8) +3 &~3);
+}
+
+void Preset_Palette::fill_data_block (char * data_start)
+{
+ *(int*)data_start = size;
+ *(int*)(data_start+4) = flags;
+ *(int*)(data_start+8) = reserved1;
+ *(int*)(data_start+12) = reserved2;
+ *(int*)(data_start+16) = startpos;
+
+ data_start += 20;
+
+ unsigned char const * sptr = pixel_data;
+
+ for (int i=size*3; i; --i, ++sptr, ++data_start)
+ {
+ *data_start = *sptr;
+ }
+ strcpy(data_start,name ? name : "unnamed");
+}
+
+RIF_IMPLEMENT_DYNCREATE("PRSETPAL",Preset_Palette_Chunk)
+
+Preset_Palette_Chunk::Preset_Palette_Chunk(Chunk_With_Children * const parent, char const * sdata, size_t const /*ssize*/)
+: Chunk(parent,"PRSETPAL")
+, version_num(*(int *)sdata)
+, flags(*(int *)(sdata+4))
+, reserved1(*(int *)(sdata+8))
+, reserved2(*(int *)(sdata+12))
+, reserved3(*(int *)(sdata+16))
+{
+ int const pplistsize = *(int *)(sdata+20);
+ sdata += 24;
+
+ for (int i = pplistsize; i; --i)
+ {
+ Preset_Palette current(sdata);
+ sdata += current.size_chunk();
+ pplist.add_entry(current);
+ }
+}
+
+
+size_t Preset_Palette_Chunk::size_chunk ()
+{
+ chunk_size = 12 + 24;
+
+ for (LIF<Preset_Palette> li(&pplist); !li.done(); li.next())
+ {
+ chunk_size += li().size_chunk();
+ }
+
+ return chunk_size;
+}
+
+void Preset_Palette_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;
+ *(int*)(data_start+4) = flags;
+ *(int*)(data_start+8) = reserved1;
+ *(int*)(data_start+12) = reserved2;
+ *(int*)(data_start+16) = reserved3;
+ *(int*)(data_start+20) = pplist.size();
+
+ data_start += 24;
+
+ for (LIF<Preset_Palette> li(&pplist); !li.done(); li.next())
+ {
+ Preset_Palette current(li());
+
+ current.fill_data_block(data_start);
+ data_start += current.size_chunk();
+ }
+}
+
+
+///////////////////////////////////////
+
+// Class Environment_TLT_Chunk functions
+
+
+RIF_IMPLEMENT_DYNCREATE("ENVTXLIT",Environment_TLT_Chunk)
+
+Environment_TLT_Chunk::Environment_TLT_Chunk (Chunk_With_Children * parent, const char * sdata, size_t ssize)
+: Chunk (parent, "ENVTXLIT"), width (*((int*)(sdata))),
+ num_levels (*((int*)(sdata+4))), flags(*(int *)(sdata+28)), table (0), filename(0)
+{
+ for (int i=0; i<ChunkTLT_NumReserved; ++i) reserved[i] = *(int *)(sdata+8+(i<<2));
+
+ if (flags & ChunkTLTFlag_ExternalFile)
+ {
+ filename = new char[strlen(sdata+32)+1];
+ strcpy(filename,sdata+32);
+ }
+ else if ((signed) ssize >= 32 + width*num_levels)
+ {
+ table = new unsigned char [width*num_levels];
+ unsigned char * tableptr = table;
+ unsigned char const * sdataptr = (unsigned char *)(sdata+32);
+ for (i=width*num_levels; i; --i)
+ {
+ *tableptr++ = *sdataptr++;
+ }
+ }
+
+}
+
+Environment_TLT_Chunk::~Environment_TLT_Chunk ()
+{
+ if (table) delete[] table;
+ if (filename) delete[] filename;
+}
+
+size_t Environment_TLT_Chunk::size_chunk()
+{
+ if (flags & ChunkTLTFlag_ExternalFile)
+ {
+ if (filename)
+ {
+ chunk_size = 12 + 32 + (strlen(filename)+4 & ~3);
+ }
+ else
+ {
+ chunk_size = 12 + 32 + 4;
+ }
+ }
+ else
+ {
+ chunk_size = 12 + 32 + width * num_levels;
+ }
+ return(chunk_size);
+
+}
+
+void Environment_TLT_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) = width;
+ *((int*)(data_start+4)) = num_levels;
+
+ data_start += 8;
+
+ for (int i=0; i < ChunkTLT_NumReserved ; ++i, data_start+=4)
+ *((int *)data_start) = reserved[i];
+
+ *(int *)data_start = flags;
+ data_start+=4;
+
+ if (flags & ChunkTLTFlag_ExternalFile)
+ {
+ if (filename)
+ strcpy(data_start,filename);
+ else
+ *data_start = 0;
+ }
+ else
+ {
+ if (table)
+ {
+ unsigned char * tableptr = table;
+
+ for (i=width*num_levels; i; --i)
+ {
+ *data_start++ = *tableptr++;
+ }
+ }
+ else
+ {
+ for (i=width*num_levels; i; --i)
+ {
+ *data_start++ = 0;
+ }
+ }
+ }
+}
+
+
+///////////////////////////////////////
+
+// Class TLT_Config_Chunk functions
+
+TLTCC_Flags::TLTCC_Flags(unsigned int data)
+: allow_v2 (data & 0x00000001 ? 1 : 0)
+, nodefault (data & 0x00000002 ? 1 : 0)
+{
+}
+
+TLTCC_Flags::operator unsigned int () const
+{
+ return
+ allow_v2 * 0x00000001 +
+ nodefault * 0x00000002 ;
+}
+
+RIF_IMPLEMENT_DYNCREATE("TLTCONFG",TLT_Config_Chunk)
+
+TLT_Config_Chunk::TLT_Config_Chunk (Chunk_With_Children * parent, const char * sdata, size_t ssize)
+: Chunk (parent, "TLTCONFG")
+, num_shades_white(*(unsigned int const *)sdata)
+, table_size(*(unsigned int const *)(sdata+4))
+, flags(*(unsigned int const *)(sdata+8))
+, palette_size(*(unsigned int const *)(sdata+12))
+{
+ if (!table_size) table_size = 256;
+
+ sdata+=16;
+
+ for (int i=0; i<3; ++i, sdata+=4) reserved[i] = *(int *)sdata;
+
+ unsigned int const len = strlen(sdata)+4&~3;
+ srcrifname = new char[len];
+ memcpy(srcrifname,sdata,len);
+ sdata += len;
+
+ unsigned int listsize = *(int *)sdata;
+ sdata += 4;
+
+ while (listsize)
+ {
+ TLTConfigBlock block(sdata);
+ sdata += block.Size();
+ blocks.add_entry_end(block);
+ listsize--;
+ }
+
+ // hmm, size_chunk was wrong so allow sizes which were wrong in that way to pass
+ assert (ssize + 12 == size_chunk() || ssize + 12 + (44+strlen(srcrifname)+4&~3) - (44+strlen(srcrifname)+4&~4) == size_chunk());
+}
+
+size_t TLT_Config_Chunk::size_chunk()
+{
+ chunk_size = 44 + (srcrifname ? strlen(srcrifname) : 0) + 4 &~3;
+ for (LIF<TLTConfigBlock> tbli(&blocks); !tbli.done(); tbli.next())
+ {
+ chunk_size += tbli().Size();
+ }
+ return chunk_size;
+}
+
+void TLT_Config_Chunk::fill_data_block (char * data_start)
+{
+ strncpy (data_start, identifier, 8);
+ data_start += 8;
+
+ *((int *) data_start) = chunk_size;
+ data_start += 4;
+
+ *(unsigned int *)data_start = num_shades_white;
+ data_start += 4;
+
+ *(unsigned int *)data_start = table_size;
+ data_start += 4;
+
+ *(unsigned int *)data_start = flags;
+ data_start += 4;
+
+ *(unsigned int *)data_start = palette_size;
+ data_start += 4;
+
+ for (int i=0; i<3 ; ++i, data_start+=4)
+ *(int *)data_start = reserved[i];
+
+ strcpy(data_start,srcrifname ? srcrifname : "");
+
+ data_start += strlen(data_start) + 4 &~3;
+
+ *(int *)data_start = blocks.size();
+ data_start+=4;
+
+ for (LIF<TLTConfigBlock> tbli(&blocks); !tbli.done(); tbli.next())
+ {
+ tbli().WriteData(data_start);
+ data_start += tbli().Size();
+ }
+}
+
+
+///////////////////////////////////////
+
+// Class Environment_Data_Chunk functions
+
+// constructor from buffer
+
+RIF_IMPLEMENT_DYNCREATE("GAMEMODE",Environment_Game_Mode_Chunk)
+
+/*
+Children For Environment_Game_Mode_Chunk :
+
+
+"GMODHEAD" Environment_Game_Mode_Header_Chunk
+"ENVPALET" Environment_Palette_Chunk
+"ENVTXLIT" Environment_TLT_Chunk
+"TLTCONFG" TLT_Config_Chunk
+"CLRLOOKP" Coloured_Polygons_Lookup_Chunk
+"MATCHIMG" Matching_Images_Chunk
+"SHBMPNAM" External_Shape_BMPs_Store_Chunk
+"RIFCHILD" RIF_Child_Chunk
+"SETPALST" Preset_Palette_Store_Chunk
+"BMPMD5ID" Bitmap_MD5_Chunk
+*/
+
+
+Environment_Game_Mode_Chunk::Environment_Game_Mode_Chunk(Chunk_With_Children* const parent,const char* data,size_t const size)
+:Chunk_With_Children(parent,"GAMEMODE") , envd_parent((Environment_Data_Chunk *)parent)
+{
+ const char * buffer_ptr = data;
+ while ((data-buffer_ptr)< (signed) size) {
+ if ((*(int *)(data + 8)) + (data-buffer_ptr) > (signed) size) {
+ Parent_File->error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
+ break;
+ }
+
+ DynCreate(data);
+ data += *(int *)(data + 8);
+ }
+}
+
+char * Environment_Game_Mode_Chunk::ExpandedIdentifier() const
+{
+ char const * full_fname = header->flags & GameModeFlag_Editable ? ((File_Chunk *)GetRootChunk())->filename : header->get_safe_source();
+ char const * skip = strrchr(full_fname,'\\');
+ if (skip) full_fname = skip+1;
+ skip = strrchr(full_fname,'/');
+ if (skip) full_fname = skip+1;
+ skip = strrchr(full_fname,':');
+ if (skip) full_fname = skip+1;
+ char * retp = new char[strlen(full_fname)+strlen(header->mode_identifier)+3];
+ strcpy(retp,full_fname);
+ char * dotpos = strrchr(retp,'.');
+ if (dotpos) *dotpos = 0;
+ strcat(retp,"::");
+ strcat(retp,header->mode_identifier);
+ return retp;
+}
+
+// header chunk
+RIF_IMPLEMENT_DYNCREATE("GMODHEAD",Environment_Game_Mode_Header_Chunk)
+
+Environment_Game_Mode_Header_Chunk::Environment_Game_Mode_Header_Chunk(Chunk_With_Children * const parent, const char * pdata, size_t const /*psize*/)
+: Chunk (parent, "GMODHEAD"), flags(0), rif_files()
+{
+ flags = *((int *) pdata);
+
+ pdata+=4;
+
+ for (int i=0; i<ChunkGMod_NumReserved; i++, pdata+=4)
+ {
+ reserved[i] = *((int *) pdata);
+ }
+
+ version_num = *(int *)pdata;
+ pdata+=4;
+
+ mode_identifier = new char[strlen(pdata)+1];
+
+ strcpy (mode_identifier, (pdata));
+
+ pdata += strlen(mode_identifier) + 1;
+
+ while (*pdata)
+ {
+ unsigned int len = strlen(pdata)+1;
+
+ char * riffn = new char[len];
+ strcpy(riffn,pdata);
+ rif_files.add_entry(riffn);
+
+ pdata += len;
+ }
+
+ ((Environment_Game_Mode_Chunk*)parent)->header = this;
+}
+
+
+Environment_Game_Mode_Header_Chunk::~Environment_Game_Mode_Header_Chunk()
+{
+ if (mode_identifier) delete[] mode_identifier;
+
+ while (rif_files.size())
+ {
+ delete [] rif_files.first_entry();
+ rif_files.delete_first_entry();
+ }
+}
+
+
+
+void Environment_Game_Mode_Header_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) = flags;
+ data_start+=4;
+
+ for (int i=0; i<ChunkGMod_NumReserved; i++, data_start+=4)
+ {
+ *((int *) data_start) = reserved[i];
+ }
+ *(int *)data_start = version_num;
+ data_start+=4;
+
+ strcpy ((data_start), mode_identifier);
+
+ data_start += strlen(mode_identifier) + 1;
+
+ for (LIF<char *> li(&rif_files); !li.done(); li.next())
+ {
+ strcpy(data_start,li());
+
+ data_start += strlen(li())+1;
+ }
+
+ *data_start = 0; // double 0-byte terminator
+}
+
+
+size_t Environment_Game_Mode_Header_Chunk::size_chunk ()
+{
+ chunk_size = 12+20+(strlen(mode_identifier)+1);
+
+ for (LIF<char *> li(&rif_files); !li.done(); li.next())
+ {
+ chunk_size += strlen(li())+1;
+ }
+
+ chunk_size += 4; // 1 byte terminator, 3(max) to pad
+ chunk_size &= ~3;
+ return chunk_size;
+}
+
+
+
+////////////////////////////////////////
+
+// Class RIF_Child_Chunk - for RIFs in game modes containing graphics
+RIF_IMPLEMENT_DYNCREATE("RIFCHILD",RIF_Child_Chunk)
+
+RIF_Child_Chunk::~RIF_Child_Chunk()
+{
+ if (filename) delete[] filename;
+ if (rifname) delete[] rifname;
+}
+
+size_t RIF_Child_Chunk::size_chunk()
+{
+ chunk_size = 12 + 12 + (strlen(rifname)+1 +3 &~3) + 4 + (strlen(filename)+1 +3 &~3) + 4;
+
+ for (LIF<BMP_Flags> li(&bmps); !li.done(); li.next())
+ {
+ chunk_size += 8 + strlen(li().filename)+1 +3 & ~3;
+ }
+
+ return chunk_size;
+}
+
+void RIF_Child_Chunk::fill_data_block(char * data_start)
+{
+ strncpy (data_start, identifier, 8);
+
+ data_start += 8;
+
+ *((int *) data_start) = chunk_size;
+
+ data_start += 4;
+
+ for (int i=0; i<ChunkRIFChild_NumReserved; i++, data_start+=4)
+ {
+ *((int *) data_start) = reserved[i];
+ }
+
+ *(RCC_Flags *)data_start = flags;
+ data_start += 4;
+
+ strcpy(data_start,rifname);
+ data_start += strlen(rifname)+1 +3 &~3;
+
+ *((int *) data_start) = version_num;
+
+ data_start += 4;
+
+ strcpy(data_start,filename);
+ data_start += strlen(filename)+1 +3 &~3;
+
+ *((int *) data_start) = bmps.size();
+ data_start += 4;
+
+ for (LIF<BMP_Flags> li(&bmps); !li.done(); li.next())
+ {
+ *((int *) data_start) = li().flags;
+ data_start += 4;
+ *((int *) data_start) = li().version_num & BMPFLAGS_VERSION_NUM_MASK | li().enum_id << BMPFLAGS_ENUMID_SHIFT;
+ data_start += 4;
+
+ strcpy(data_start, li().filename);
+ data_start += strlen(li().filename)+1 +3 &~3;
+ }
+
+}
+
+int const * RIF_Child_Chunk::GetMD5Val(BMP_Flags const & rcbmp)
+{
+ Bitmap_MD5_Chunk * md5c = GetMD5Chunk(rcbmp.filename);
+ if (md5c)
+ if (rcbmp.version_num == md5c->version_num)
+ return md5c->md5_val;
+ return 0;
+}
+
+void RIF_Child_Chunk::RemoveMD5Val(char const * bname)
+{
+ Bitmap_MD5_Chunk * md5c = GetMD5Chunk(bname);
+ if (md5c)
+ delete md5c;
+}
+
+void RIF_Child_Chunk::SetMD5Val(BMP_Flags const & rcbmp, int const * md5id)
+{
+ Bitmap_MD5_Chunk * md5c = GetMD5Chunk(rcbmp.filename);
+ if (md5c)
+ {
+ if (rcbmp.version_num == md5c->version_num)
+ {
+ memcpy(md5c->md5_val,md5id,16);
+ return;
+ }
+ else
+ delete md5c;
+ }
+ CreateMD5Chunk(rcbmp,md5id);
+}
+
+Bitmap_MD5_Chunk * RIF_Child_Chunk::GetMD5Chunk(char const * bname)
+{
+ List<Chunk *> chlst;
+ parent->lookup_child("BMPMD5ID",chlst);
+
+ for (LIF<Chunk *> i_chlst(&chlst); !i_chlst.done(); i_chlst.next())
+ {
+ Bitmap_MD5_Chunk * md5c = (Bitmap_MD5_Chunk *)i_chlst();
+
+ if (!strcmp(md5c->bmpname,bname))
+ if (!(md5c->rifname ? rifname ? strcmp(rifname,md5c->rifname) : *md5c->rifname : rifname ? *rifname : 0) &&
+ !(md5c->shapename ? *md5c->shapename : 1))
+ return md5c;
+ }
+
+ return 0;
+}
+
+void RIF_Child_Chunk::CreateMD5Chunk(BMP_Flags const & rcbmp, int const * md5id)
+{
+ new Bitmap_MD5_Chunk(parent,md5id,rcbmp,rifname);
+}
+
+RIF_Child_Chunk::RIF_Child_Chunk (Chunk_With_Children * const parent, const char * sdata, size_t const /*ssize*/)
+: Chunk(parent,"RIFCHILD"), egm_parent((Environment_Game_Mode_Chunk * const)parent)
+{
+ for (int i=0; i<ChunkRIFChild_NumReserved; i++, sdata+=4)
+ {
+ reserved[i] = *((int *) sdata);
+ }
+ flags = *(RCC_Flags *)sdata;
+ sdata += 4;
+
+ unsigned int len = strlen(sdata)+1;
+ rifname = new char[len];
+ strcpy(rifname,sdata);
+ sdata += len+3 &~3;
+
+ version_num = *(int *)sdata;
+ sdata += 4;
+
+ len = strlen(sdata)+1;
+ filename = new char[len];
+ strcpy(filename,sdata);
+ sdata += len+3 &~3;
+
+ int listsize = *(int *)sdata;
+ sdata+=4;
+
+ for (i = listsize; i; --i)
+ {
+ BMP_Flags temp;
+ temp.flags = *(BMPN_Flags *)sdata;
+ sdata += 4;
+ temp.enum_id = (int)(*(unsigned int *)sdata >> BMPFLAGS_ENUMID_SHIFT);
+ temp.version_num = *(int *)sdata & BMPFLAGS_VERSION_NUM_MASK;
+ sdata += 4;
+
+ len = strlen(sdata)+1;
+ temp.filename = new char[len];
+ strcpy(temp.filename,sdata);
+ sdata += len+3 &~3;
+
+ bmps.add_entry(temp);
+ }
+
+}
+
+/////////////////////////////////
+// Preset_Palette_Store_Chunk
+// ties in with RIF_Child_Chunk
+// the filenames (-dirname) should match
+
+RIF_IMPLEMENT_DYNCREATE("SETPALST",Preset_Palette_Store_Chunk)
+
+Preset_Palette_Store_Chunk::Preset_Palette_Store_Chunk(Chunk_With_Children * const parent, char const * sdata, size_t const /*ssize*/)
+: Chunk(parent,"SETPALST")
+, version_num(*(int *)sdata)
+, flags(*(int *)(sdata+4))
+, reserved1(*(int *)(sdata+8))
+, reserved2(*(int *)(sdata+12))
+, reserved3(*(int *)(sdata+16))
+{
+ sdata += 20;
+
+ unsigned int const len = strlen(sdata)+1;
+ rifname = new char[len];
+ strcpy(rifname,sdata);
+ sdata += len + 3 &~3;
+
+ int const pplistsize = *(int *)sdata;
+ sdata += 4;
+
+ for (int i = pplistsize; i; --i)
+ {
+ Preset_Palette current(sdata);
+ sdata += current.size_chunk();
+ pplist.add_entry(current);
+ }
+}
+
+
+size_t Preset_Palette_Store_Chunk::size_chunk ()
+{
+ chunk_size = 12 + 24 + strlen(rifname)+1+3 &~3;
+
+ for (LIF<Preset_Palette> li(&pplist); !li.done(); li.next())
+ {
+ chunk_size += li().size_chunk();
+ }
+
+ return chunk_size;
+}
+
+void Preset_Palette_Store_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;
+ *(int*)(data_start+4) = flags;
+ *(int*)(data_start+8) = reserved1;
+ *(int*)(data_start+12) = reserved2;
+ *(int*)(data_start+16) = reserved3;
+ data_start += 20;
+
+ strcpy(data_start,rifname);
+ data_start+=strlen(rifname)+1+3 &~3;
+
+ *(int*)(data_start) = pplist.size();
+ data_start += 4;
+
+ for (LIF<Preset_Palette> li(&pplist); !li.done(); li.next())
+ {
+ Preset_Palette current(li());
+
+ current.fill_data_block(data_start);
+ data_start += current.size_chunk();
+ }
+}
+
+
+
+
+
+///////////////////////////////////////
+
+// Class Coloured_Polygons_Lookup_Chunk functions
+
+// simple 32K tables for palettes to quickly map coloured
+// polygons to the right palette colour on loading, with 15-bit definition
+
+
+RIF_IMPLEMENT_DYNCREATE("CLRLOOKP",Coloured_Polygons_Lookup_Chunk)
+
+Coloured_Polygons_Lookup_Chunk::Coloured_Polygons_Lookup_Chunk (Chunk_With_Children * parent, const char * sdata, size_t /*ssize*/)
+: Chunk (parent, "CLRLOOKP"), flags (*((int*)(sdata))),
+ filename(0), table (0)
+{
+ for (int i=0; i<ChunkCPLU_NumReserved; ++i) reserved[i] = *(int *)(sdata+4+(i<<2));
+
+ if (flags & ChunkCPLUFlag_ExternalFile)
+ {
+ filename = new char[strlen(sdata+32)+1];
+ strcpy(filename,sdata+32);
+ }
+ else
+ {
+ table = new unsigned char [1<<15];
+ unsigned char * tableptr = table;
+ unsigned char const * sdataptr = (unsigned char *)(sdata+32);
+ for (i=1<<15; i; --i)
+ {
+ *tableptr++ = *sdataptr++;
+ }
+ }
+
+}
+
+Coloured_Polygons_Lookup_Chunk::~Coloured_Polygons_Lookup_Chunk ()
+{
+ if (table) delete [] table;
+ if (filename) delete [] filename;
+}
+
+size_t Coloured_Polygons_Lookup_Chunk::size_chunk()
+{
+ if (flags & ChunkCPLUFlag_ExternalFile)
+ {
+ if (filename)
+ {
+ chunk_size = 12 + 32 + (strlen(filename)+4 & ~3);
+ }
+ else
+ {
+ chunk_size = 12 + 32 + 4;
+ }
+ }
+ else
+ {
+ chunk_size = 12 + 32 + (1<<15);
+ }
+ return(chunk_size);
+
+}
+
+void Coloured_Polygons_Lookup_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) = flags;
+
+ data_start += 4;
+
+ for (int i=0; i < ChunkCPLU_NumReserved ; ++i, data_start+=4)
+ *((int *)data_start) = reserved[i];
+
+ if (flags & ChunkCPLUFlag_ExternalFile)
+ {
+ if (filename)
+ strcpy(data_start,filename);
+ else // escape
+ *data_start = 0;
+ }
+ else
+ {
+ if (table)
+ {
+ unsigned char * tableptr = table;
+
+ for (i=1<<15; i; --i)
+ {
+ *data_start++ = *tableptr++;
+ }
+ }
+ else // escape
+ {
+ for (i=1<<15; i; --i)
+ {
+ *data_start++ = 0;
+ }
+ }
+ }
+}
+
+