965 lines
21 KiB
C++
965 lines
21 KiB
C++
![]() |
#include <string.h>
|
||
|
#include "bmpnames.hpp"
|
||
|
#include "mishchnk.hpp"
|
||
|
|
||
|
#if engine
|
||
|
#define UseLocalAssert No
|
||
|
#include "ourasert.h"
|
||
|
#define assert(x) GLOBALASSERT(x)
|
||
|
#else
|
||
|
#if cencon
|
||
|
#include "ccassert.h"
|
||
|
#else
|
||
|
#include <assert.h>
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#ifdef cencon
|
||
|
#define new my_new
|
||
|
#endif
|
||
|
|
||
|
//macro for helping to force inclusion of chunks when using libraries
|
||
|
FORCE_CHUNK_INCLUDE_IMPLEMENT(bmpnames)
|
||
|
|
||
|
|
||
|
BMP_Name::BMP_Name (const char * fname, int const gbnc_version)
|
||
|
: flags((BMPN_Flags)DEFAULT_BMPN_FLAGS), index(0), version_num (gbnc_version << BMPNAME_PARENT_VER_SHIFT), priority (DEFAULT_BMPN_PRIORITY), transparency_colour_union(0), enum_id(0)
|
||
|
#if cencon
|
||
|
, md5val(0)
|
||
|
#endif
|
||
|
{
|
||
|
filename = new char [strlen(fname)+1];
|
||
|
strcpy (filename, fname);
|
||
|
}
|
||
|
|
||
|
BMP_Name::BMP_Name (const char * fname)
|
||
|
: flags((BMPN_Flags)DEFAULT_BMPN_FLAGS), index(0), version_num (0), priority (DEFAULT_BMPN_PRIORITY), transparency_colour_union(0), enum_id(0)
|
||
|
#if cencon
|
||
|
, md5val(0)
|
||
|
#endif
|
||
|
{
|
||
|
filename = new char [strlen(fname)+1];
|
||
|
strcpy (filename, fname);
|
||
|
}
|
||
|
|
||
|
BMP_Name::~BMP_Name ()
|
||
|
{
|
||
|
if (filename)
|
||
|
delete [] filename;
|
||
|
}
|
||
|
|
||
|
BMP_Name::BMP_Name (const BMP_Name & bn)
|
||
|
{
|
||
|
if (&bn == this) return;
|
||
|
|
||
|
filename = new char [strlen(bn.filename)+1];
|
||
|
strcpy (filename, bn.filename);
|
||
|
flags = bn.flags;
|
||
|
index = bn.index;
|
||
|
version_num = bn.version_num;
|
||
|
enum_id = bn.enum_id;
|
||
|
priority = bn.priority;
|
||
|
transparency_colour_union = bn.transparency_colour_union;
|
||
|
#if cencon
|
||
|
md5val = bn.md5val;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void BMP_Name::Validate(void)
|
||
|
{
|
||
|
if (flags & ChunkBMPFlag_PriorityAndTransparencyAreValid) return;
|
||
|
|
||
|
priority = DEFAULT_BMPN_PRIORITY;
|
||
|
flags = (BMPN_Flags)(flags | DEFAULT_BMPN_FLAGS);
|
||
|
}
|
||
|
|
||
|
const BMP_Name & BMP_Name::operator=(const BMP_Name & bn)
|
||
|
{
|
||
|
if (&bn == this) return(*this);
|
||
|
|
||
|
if (filename)
|
||
|
delete [] filename;
|
||
|
|
||
|
filename = new char [strlen(bn.filename)+1];
|
||
|
strcpy (filename, bn.filename);
|
||
|
flags = bn.flags;
|
||
|
index = bn.index;
|
||
|
version_num = bn.version_num;
|
||
|
enum_id = bn.enum_id;
|
||
|
priority = bn.priority;
|
||
|
transparency_colour_union = bn.transparency_colour_union;
|
||
|
#if cencon
|
||
|
md5val = bn.md5val;
|
||
|
#endif
|
||
|
|
||
|
return(*this);
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
BOOL operator==(const BMP_Name &o1, const BMP_Name &o2)
|
||
|
{
|
||
|
if (o1.filename && o2.filename) return _stricmp(o1.filename,o2.filename) ? FALSE : TRUE;
|
||
|
else return &o1 == &o2;
|
||
|
}
|
||
|
|
||
|
BOOL operator!=(const BMP_Name &o1, const BMP_Name &o2)
|
||
|
{
|
||
|
if (o1.filename && o2.filename) return _stricmp(o1.filename,o2.filename) ? TRUE : FALSE;
|
||
|
else return &o1 != &o2;
|
||
|
}
|
||
|
|
||
|
|
||
|
///////////////////////////////////////
|
||
|
|
||
|
// Class Chunk_With_BMPs functions
|
||
|
|
||
|
|
||
|
|
||
|
Chunk_With_BMPs::Chunk_With_BMPs (Chunk_With_Children * parent, const char * const ident, const char * bdata, size_t /*bsize*/)
|
||
|
: Chunk (parent, ident), max_index (0)
|
||
|
{
|
||
|
int temp = *(int *)bdata;
|
||
|
|
||
|
int num = temp & 0xffff;
|
||
|
|
||
|
int ver_num = temp >> 16 & 0xffff; // the remains of a previous mistake - not really necessary anymore
|
||
|
|
||
|
bdata += 4;
|
||
|
|
||
|
for (int i=0; i<num; i++)
|
||
|
{
|
||
|
int f,i,d1,d2,d3;
|
||
|
|
||
|
f = *((int *)bdata);
|
||
|
bdata += 4;
|
||
|
i = *((int *)bdata);
|
||
|
bdata += 4;
|
||
|
d1 = *((int *)bdata);
|
||
|
bdata += 4;
|
||
|
d2 = *((int *)bdata);
|
||
|
bdata += 4;
|
||
|
d3 = *((int *)bdata);
|
||
|
bdata += 4;
|
||
|
|
||
|
BMP_Name bn (bdata);
|
||
|
bdata += (4-strlen(bn.filename)%4) + strlen(bn.filename);
|
||
|
|
||
|
bn.flags = (BMPN_Flags)f;
|
||
|
bn.index = i;
|
||
|
bn.version_num = d1 & BMPNAME_VERSION_NUM_MASK;
|
||
|
bn.enum_id = (int)((unsigned int)d1 >> BMPNAME_ENUMID_SHIFT);
|
||
|
bn.priority = d2;
|
||
|
bn.transparency_colour_union = d3;
|
||
|
|
||
|
max_index = max (bn.index, max_index);
|
||
|
|
||
|
bmps.add_entry (bn);
|
||
|
}
|
||
|
|
||
|
if (ver_num)
|
||
|
{
|
||
|
set_version_num(ver_num);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
size_t Chunk_With_BMPs::size_chunk ()
|
||
|
{
|
||
|
int sz = 12 + 4;
|
||
|
|
||
|
for (LIF<BMP_Name> bl(&bmps); !bl.done(); bl.next())
|
||
|
{
|
||
|
sz += (4-strlen(bl().filename)%4) + strlen(bl().filename) + 20;
|
||
|
}
|
||
|
|
||
|
chunk_size = sz;
|
||
|
|
||
|
return (chunk_size);
|
||
|
|
||
|
}
|
||
|
|
||
|
void Chunk_With_BMPs::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) = bmps.size();
|
||
|
|
||
|
data_start += 4;
|
||
|
|
||
|
for (LIF<BMP_Name> bl(&bmps); !bl.done(); bl.next())
|
||
|
{
|
||
|
*((int *) data_start) = bl().flags;
|
||
|
data_start += 4;
|
||
|
*((int *) data_start) = bl().index;
|
||
|
data_start += 4;
|
||
|
*((int *) data_start) = bl().version_num & BMPNAME_VERSION_NUM_MASK | bl().enum_id << BMPNAME_ENUMID_SHIFT;
|
||
|
data_start += 4;
|
||
|
*((int *) data_start) = bl().priority;
|
||
|
data_start += 4;
|
||
|
*((int *) data_start) = bl().transparency_colour_union;
|
||
|
data_start += 4;
|
||
|
|
||
|
strcpy (data_start, bl().filename);
|
||
|
data_start += (4-strlen(bl().filename)%4) + strlen(bl().filename);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
int Chunk_With_BMPs::get_version_num(void)
|
||
|
{
|
||
|
if (parent)
|
||
|
{
|
||
|
List<Chunk *> verlist;
|
||
|
parent->lookup_child("BMNAMVER",verlist);
|
||
|
while (verlist.size()>1)
|
||
|
{
|
||
|
Chunk * v1 = verlist.first_entry();
|
||
|
Chunk * v2 = verlist[1];
|
||
|
if (((BMP_Names_Version_Chunk *)v1)->version_num > ((BMP_Names_Version_Chunk *)v2)->version_num)
|
||
|
{
|
||
|
delete verlist.last_entry();
|
||
|
verlist.delete_last_entry();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
delete v1;
|
||
|
verlist.delete_first_entry();
|
||
|
}
|
||
|
}
|
||
|
if (verlist.size())
|
||
|
{
|
||
|
int rv = ((BMP_Names_Version_Chunk *)verlist.first_entry())->version_num;
|
||
|
return rv;
|
||
|
}
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void Chunk_With_BMPs::set_version_num(int v)
|
||
|
{
|
||
|
if (parent)
|
||
|
{
|
||
|
List<Chunk *> verlist;
|
||
|
parent->lookup_child("BMNAMVER",verlist);
|
||
|
while (verlist.size()>1)
|
||
|
{
|
||
|
Chunk * v1 = verlist.first_entry();
|
||
|
Chunk * v2 = verlist[1];
|
||
|
if (((BMP_Names_Version_Chunk *)v1)->version_num > ((BMP_Names_Version_Chunk *)v2)->version_num)
|
||
|
{
|
||
|
delete verlist.last_entry();
|
||
|
verlist.delete_last_entry();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
delete v1;
|
||
|
verlist.delete_first_entry();
|
||
|
}
|
||
|
}
|
||
|
if (verlist.size())
|
||
|
{
|
||
|
((BMP_Names_Version_Chunk *)verlist.first_entry())->version_num = v;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
(new BMP_Names_Version_Chunk(parent))->version_num = v;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Chunk_With_BMPs::inc_version_num(void)
|
||
|
{
|
||
|
if (parent)
|
||
|
{
|
||
|
List<Chunk *> verlist;
|
||
|
parent->lookup_child("BMNAMVER",verlist);
|
||
|
while (verlist.size()>1)
|
||
|
{
|
||
|
Chunk * v1 = verlist.first_entry();
|
||
|
Chunk * v2 = verlist[1];
|
||
|
if (((BMP_Names_Version_Chunk *)v1)->version_num > ((BMP_Names_Version_Chunk *)v2)->version_num)
|
||
|
{
|
||
|
delete verlist.last_entry();
|
||
|
verlist.delete_last_entry();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
delete v1;
|
||
|
verlist.delete_first_entry();
|
||
|
}
|
||
|
}
|
||
|
if (verlist.size())
|
||
|
{
|
||
|
((BMP_Names_Version_Chunk *)verlist.first_entry())->version_num ++;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
(new BMP_Names_Version_Chunk(parent))->version_num ++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
BMP_Names_ExtraData * Chunk_With_BMPs::GetExtendedData(void)
|
||
|
{
|
||
|
if (parent)
|
||
|
{
|
||
|
List<Chunk *> verlist;
|
||
|
parent->lookup_child("BMNAMEXT",verlist);
|
||
|
if (verlist.size())
|
||
|
{
|
||
|
return (BMP_Names_ExtraData_Chunk *) verlist.first_entry();
|
||
|
}
|
||
|
return new BMP_Names_ExtraData_Chunk(parent);
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int const * Chunk_With_BMPs::GetMD5Val(BMP_Name 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 Chunk_With_BMPs::RemoveMD5Val(char const * bname)
|
||
|
{
|
||
|
Bitmap_MD5_Chunk * md5c = GetMD5Chunk(bname);
|
||
|
if (md5c)
|
||
|
delete md5c;
|
||
|
}
|
||
|
|
||
|
void Chunk_With_BMPs::SetMD5Val(BMP_Name 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);
|
||
|
}
|
||
|
|
||
|
|
||
|
/////////////////////////////////////
|
||
|
// Global_BMP_Name_Chunk
|
||
|
/////////////////////////////////////
|
||
|
RIF_IMPLEMENT_DYNCREATE("BMPNAMES",Global_BMP_Name_Chunk)
|
||
|
|
||
|
Bitmap_MD5_Chunk * Global_BMP_Name_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 ? *md5c->rifname : 1) && !(md5c->shapename ? *md5c->shapename : 1))
|
||
|
return md5c;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void Global_BMP_Name_Chunk::CreateMD5Chunk(BMP_Name const & rcbmp, int const * md5id)
|
||
|
{
|
||
|
new Bitmap_MD5_Chunk(parent,md5id,rcbmp);
|
||
|
}
|
||
|
|
||
|
/////////////////////////////////////
|
||
|
// Bitmap_List_Store_Chunk
|
||
|
/////////////////////////////////////
|
||
|
RIF_IMPLEMENT_DYNCREATE("BMPLSTST",Bitmap_List_Store_Chunk)
|
||
|
|
||
|
Bitmap_MD5_Chunk * Bitmap_List_Store_Chunk::GetMD5Chunk(char const * bname)
|
||
|
{
|
||
|
List<Chunk *> chlst;
|
||
|
parent->lookup_child("BMPMD5ID",chlst);
|
||
|
|
||
|
List<Chunk *> rnlst;
|
||
|
parent->lookup_child("RIFFNAME",rnlst);
|
||
|
char const * rname = 0;
|
||
|
if (rnlst.size())
|
||
|
{
|
||
|
rname = ((RIF_Name_Chunk *)rnlst.first_entry())->rif_name;
|
||
|
}
|
||
|
|
||
|
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 ? rname ? strcmp(rname,md5c->rifname) : *md5c->rifname : rname ? *rname : 0) &&
|
||
|
!(md5c->shapename ? *md5c->shapename : 1))
|
||
|
return md5c;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void Bitmap_List_Store_Chunk::CreateMD5Chunk(BMP_Name const & rcbmp, int const * md5id)
|
||
|
{
|
||
|
List<Chunk *> rnlst;
|
||
|
parent->lookup_child("RIFFNAME",rnlst);
|
||
|
char const * rname = 0;
|
||
|
if (rnlst.size())
|
||
|
{
|
||
|
rname = ((RIF_Name_Chunk *)rnlst.first_entry())->rif_name;
|
||
|
}
|
||
|
new Bitmap_MD5_Chunk(parent,md5id,rcbmp,rname);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
///////////////////////////////////////
|
||
|
|
||
|
// Class BMP_Names_Version_Chunk functions
|
||
|
|
||
|
RIF_IMPLEMENT_DYNCREATE("BMNAMVER",BMP_Names_Version_Chunk)
|
||
|
|
||
|
|
||
|
size_t BMP_Names_Version_Chunk::size_chunk ()
|
||
|
{
|
||
|
chunk_size = 12+4;
|
||
|
|
||
|
return (chunk_size);
|
||
|
|
||
|
}
|
||
|
|
||
|
void BMP_Names_Version_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;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
///////////////////////////////////////
|
||
|
|
||
|
// Class BMP_Names_ExtraData_Chunk functions
|
||
|
|
||
|
RIF_IMPLEMENT_DYNCREATE("BMNAMEXT",BMP_Names_ExtraData_Chunk)
|
||
|
|
||
|
|
||
|
size_t BMP_Names_ExtraData_Chunk::size_chunk ()
|
||
|
{
|
||
|
chunk_size = 12+52;
|
||
|
|
||
|
return (chunk_size);
|
||
|
|
||
|
}
|
||
|
|
||
|
void BMP_Names_ExtraData_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<12; ++i, data_start+=4)
|
||
|
{
|
||
|
*(int *)data_start = reserved[i];
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
///////////////////////////////////////
|
||
|
|
||
|
// Class External_Shape_BMPs_Store_Chunk functions
|
||
|
RIF_IMPLEMENT_DYNCREATE("SHBMPNAM",External_Shape_BMPs_Store_Chunk)
|
||
|
|
||
|
External_Shape_BMPs_Store_Chunk::External_Shape_BMPs_Store_Chunk (Chunk_With_Children * parent, char const * rifn, char const * shapen)
|
||
|
: Chunk_With_BMPs (parent, "SHBMPNAM"), rifname(0), shapename(0), version_num(0)
|
||
|
{
|
||
|
for (int i=0; i<12; ++i)
|
||
|
reserved[i] = 0;
|
||
|
|
||
|
flags = GBF_NONE;
|
||
|
|
||
|
if (rifn)
|
||
|
{
|
||
|
rifname = new char [strlen(rifn)+1];
|
||
|
strcpy(rifname,rifn);
|
||
|
}
|
||
|
if (shapen)
|
||
|
{
|
||
|
shapename = new char [strlen(shapen)+1];
|
||
|
strcpy(shapename,shapen);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
External_Shape_BMPs_Store_Chunk::~External_Shape_BMPs_Store_Chunk()
|
||
|
{
|
||
|
if (rifname) delete[] rifname;
|
||
|
if (shapename) delete[] shapename;
|
||
|
}
|
||
|
|
||
|
void External_Shape_BMPs_Store_Chunk::fill_data_block(char * data_start)
|
||
|
{
|
||
|
Chunk_With_BMPs::fill_data_block(data_start);
|
||
|
data_start += Chunk_With_BMPs::size_chunk();
|
||
|
size_chunk(); // resize it just in case
|
||
|
|
||
|
strcpy(data_start,rifname ? rifname : "");
|
||
|
unsigned int const l1 = rifname ? strlen(rifname)+1 : 1;
|
||
|
|
||
|
strcpy(data_start+l1,shapename ? shapename : "");
|
||
|
unsigned int const l2 = shapename ? strlen(shapename)+1 : 1;
|
||
|
|
||
|
data_start += l1+l2 +3&~3;
|
||
|
|
||
|
*(int *)data_start = flags;
|
||
|
data_start+=4;
|
||
|
|
||
|
*(int *)data_start = version_num;
|
||
|
data_start+=4;
|
||
|
|
||
|
for (int i=0; i<12; ++i, data_start+=4)
|
||
|
*(int *)data_start = reserved[i];
|
||
|
}
|
||
|
|
||
|
External_Shape_BMPs_Store_Chunk::External_Shape_BMPs_Store_Chunk (Chunk_With_Children * parent, const char * sdata, size_t ssize)
|
||
|
: Chunk_With_BMPs (parent, "SHBMPNAM", sdata, ssize)
|
||
|
{
|
||
|
sdata += Chunk_With_BMPs::size_chunk() -12;
|
||
|
unsigned int const l1 = strlen(sdata)+1;
|
||
|
rifname = new char [l1];
|
||
|
strcpy(rifname,sdata);
|
||
|
unsigned int const l2 = strlen(sdata+l1)+1;
|
||
|
shapename = new char [l2];
|
||
|
strcpy(shapename,sdata+l1);
|
||
|
|
||
|
sdata += l1+l2 +3&~3;
|
||
|
|
||
|
flags = (GlobalBMPFlags)(*(int *)sdata & GBF_MASK);
|
||
|
sdata+=4;
|
||
|
|
||
|
version_num = *(int *)sdata;
|
||
|
sdata+=4;
|
||
|
|
||
|
for (int i=0; i<12; ++i, sdata+=4)
|
||
|
reserved[i] = *(int *)sdata;
|
||
|
}
|
||
|
|
||
|
|
||
|
Bitmap_MD5_Chunk * External_Shape_BMPs_Store_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 ? shapename ? strcmp(shapename,md5c->shapename) : *md5c->shapename : shapename ? *shapename : 0) &&
|
||
|
(flags & GBF_SPRITE && md5c->flags & BMD5F_SPRITE || !(flags & GBF_SPRITE) && !(md5c->flags & BMD5F_SPRITE)))
|
||
|
|
||
|
return md5c;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void External_Shape_BMPs_Store_Chunk::CreateMD5Chunk(BMP_Name const & rcbmp, int const * md5id)
|
||
|
{
|
||
|
Bitmap_MD5_Chunk * md5c = new Bitmap_MD5_Chunk(parent,md5id,rcbmp,rifname,shapename);
|
||
|
md5c->flags = flags & GBF_SPRITE ? BMD5F_SPRITE : BMD5F_0;
|
||
|
}
|
||
|
|
||
|
|
||
|
/*************************/
|
||
|
/* matching images stuff */
|
||
|
/*************************/
|
||
|
|
||
|
// class ImageDescriptor
|
||
|
// ---------------------
|
||
|
ImageDescriptor::ImageDescriptor()
|
||
|
: filename(0)
|
||
|
, rifname(0)
|
||
|
, fixrifname(0)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
ImageDescriptor::ImageDescriptor(ImageDescriptor const & id2)
|
||
|
: flags(id2.flags)
|
||
|
, filename(0)
|
||
|
, rifname(0)
|
||
|
, fixrifname(0)
|
||
|
{
|
||
|
spares[0] = id2.spares[0];
|
||
|
spares[1] = id2.spares[1];
|
||
|
spares[2] = id2.spares[2];
|
||
|
|
||
|
if (id2.filename)
|
||
|
{
|
||
|
filename = new char [strlen(id2.filename)+1];
|
||
|
strcpy(filename,id2.filename);
|
||
|
}
|
||
|
if (id2.rifname)
|
||
|
{
|
||
|
rifname = new char [strlen(id2.rifname)+1];
|
||
|
strcpy(rifname,id2.rifname);
|
||
|
}
|
||
|
if (id2.fixrifname)
|
||
|
{
|
||
|
fixrifname = new char [strlen(id2.fixrifname)+1];
|
||
|
strcpy(fixrifname,id2.fixrifname);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ImageDescriptor::ImageDescriptor(IDscFlags idscf, char const * fname, char const * rname, char const * xname)
|
||
|
: flags(idscf)
|
||
|
, filename(0)
|
||
|
, rifname(0)
|
||
|
, fixrifname(0)
|
||
|
{
|
||
|
spares[0] = 0;
|
||
|
spares[1] = 0;
|
||
|
spares[2] = 0;
|
||
|
|
||
|
if (fname)
|
||
|
{
|
||
|
filename = new char [strlen(fname)+1];
|
||
|
strcpy(filename,fname);
|
||
|
}
|
||
|
if (rname)
|
||
|
{
|
||
|
rifname = new char [strlen(rname)+1];
|
||
|
strcpy(rifname,rname);
|
||
|
}
|
||
|
if (xname)
|
||
|
{
|
||
|
fixrifname = new char [strlen(xname)+1];
|
||
|
strcpy(fixrifname,xname);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ImageDescriptor::~ImageDescriptor()
|
||
|
{
|
||
|
if (filename) delete[] filename;
|
||
|
if (rifname) delete[] rifname;
|
||
|
if (fixrifname) delete[] fixrifname;
|
||
|
}
|
||
|
|
||
|
ImageDescriptor & ImageDescriptor::operator = (ImageDescriptor const & id2)
|
||
|
{
|
||
|
if (&id2 != this)
|
||
|
{
|
||
|
flags = id2.flags;
|
||
|
spares[0] = id2.spares[0];
|
||
|
spares[1] = id2.spares[1];
|
||
|
spares[2] = id2.spares[2];
|
||
|
|
||
|
if (filename)
|
||
|
{
|
||
|
delete[] filename;
|
||
|
filename = 0;
|
||
|
}
|
||
|
if (rifname)
|
||
|
{
|
||
|
delete[] rifname;
|
||
|
rifname = 0;
|
||
|
}
|
||
|
if (fixrifname)
|
||
|
{
|
||
|
delete[] fixrifname;
|
||
|
fixrifname = 0;
|
||
|
}
|
||
|
|
||
|
if (id2.filename)
|
||
|
{
|
||
|
filename = new char [strlen(id2.filename)+1];
|
||
|
strcpy(filename,id2.filename);
|
||
|
}
|
||
|
if (id2.rifname)
|
||
|
{
|
||
|
rifname = new char [strlen(id2.rifname)+1];
|
||
|
strcpy(rifname,id2.rifname);
|
||
|
}
|
||
|
if (id2.fixrifname)
|
||
|
{
|
||
|
fixrifname = new char [strlen(id2.fixrifname)+1];
|
||
|
strcpy(fixrifname,id2.fixrifname);
|
||
|
}
|
||
|
}
|
||
|
return *this;
|
||
|
}
|
||
|
|
||
|
|
||
|
// I/O
|
||
|
ImageDescriptor::ImageDescriptor(char const * datablock)
|
||
|
: flags((IDscFlags)(*(int const *)datablock & IDSCF_MASK))
|
||
|
{
|
||
|
spares[0] = *(int const *)(datablock+4);
|
||
|
spares[1] = *(int const *)(datablock+8);
|
||
|
spares[2] = *(int const *)(datablock+12);
|
||
|
datablock += 16;
|
||
|
|
||
|
size_t len = strlen(datablock)+1;
|
||
|
filename = new char[len];
|
||
|
strcpy(filename,datablock);
|
||
|
datablock += len;
|
||
|
|
||
|
len = strlen(datablock)+1;
|
||
|
rifname = new char[len];
|
||
|
strcpy(rifname,datablock);
|
||
|
datablock += len;
|
||
|
|
||
|
len = strlen(datablock)+1;
|
||
|
fixrifname = new char[len];
|
||
|
strcpy(fixrifname,datablock);
|
||
|
}
|
||
|
|
||
|
size_t ImageDescriptor::Size() const
|
||
|
{
|
||
|
return 16
|
||
|
+ (filename ? strlen(filename) : 0)
|
||
|
+ (rifname ? strlen(rifname) : 0)
|
||
|
+ (fixrifname ? strlen(fixrifname) : 0)
|
||
|
+ 3
|
||
|
+3&~3;
|
||
|
}
|
||
|
|
||
|
void ImageDescriptor::WriteData(char * datablock) const
|
||
|
{
|
||
|
*(int *)datablock = flags;
|
||
|
*(int *)(datablock+4) = spares[0];
|
||
|
*(int *)(datablock+8) = spares[1];
|
||
|
*(int *)(datablock+12) = spares[2];
|
||
|
datablock+=16;
|
||
|
|
||
|
strcpy(datablock,filename ? filename : "");
|
||
|
datablock += strlen(datablock)+1;
|
||
|
|
||
|
strcpy(datablock,rifname ? rifname : "");
|
||
|
datablock += strlen(datablock)+1;
|
||
|
|
||
|
strcpy(datablock,fixrifname ? fixrifname : "");
|
||
|
}
|
||
|
|
||
|
// operators
|
||
|
BOOL ImageDescriptor::operator == (ImageDescriptor const & id2) const
|
||
|
{
|
||
|
if (flags!=id2.flags) return FALSE;
|
||
|
if (_stricmp(filename ? filename : "",id2.filename ? id2.filename : "")) return FALSE;
|
||
|
if (_stricmp(rifname ? rifname : "",id2.rifname ? id2.rifname : "")) return FALSE;
|
||
|
if (_stricmp(fixrifname ? fixrifname : "",id2.fixrifname ? id2.fixrifname : "")) return FALSE;
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
// class MatchingImages
|
||
|
// --------------------
|
||
|
|
||
|
// constructos;
|
||
|
MatchingImages::MatchingImages(ImageDescriptor const & _load, ImageDescriptor const & _insteadof)
|
||
|
: load(_load)
|
||
|
, insteadof(_insteadof)
|
||
|
{
|
||
|
spares[0] = 0;
|
||
|
spares[1] = 0;
|
||
|
spares[2] = 0;
|
||
|
}
|
||
|
|
||
|
// I/O
|
||
|
MatchingImages::MatchingImages(char const * datablock)
|
||
|
: load(datablock+12)
|
||
|
, insteadof(datablock+12+load.Size())
|
||
|
{
|
||
|
spares[0] = *(int const *)datablock;
|
||
|
spares[1] = *(int const *)(datablock+4);
|
||
|
spares[2] = *(int const *)(datablock+8);
|
||
|
}
|
||
|
|
||
|
size_t MatchingImages::Size() const
|
||
|
{
|
||
|
return 12 + load.Size() + insteadof.Size();
|
||
|
}
|
||
|
|
||
|
void MatchingImages::WriteData(char * datablock) const
|
||
|
{
|
||
|
*(int *)datablock = spares[0];
|
||
|
*(int *)(datablock+4) = spares[1];
|
||
|
*(int *)(datablock+8) = spares[2];
|
||
|
|
||
|
load.WriteData(datablock+12);
|
||
|
insteadof.WriteData(datablock+12+load.Size());
|
||
|
}
|
||
|
|
||
|
|
||
|
// class Matching_Images_Chunk : public Chunk
|
||
|
// ------------------------------------------
|
||
|
RIF_IMPLEMENT_DYNCREATE("MATCHIMG",Matching_Images_Chunk)
|
||
|
|
||
|
// I/O
|
||
|
Matching_Images_Chunk::Matching_Images_Chunk(Chunk_With_Children * parent, char const * datablock, size_t size)
|
||
|
: Chunk(parent,"MATCHIMG")
|
||
|
, flags ((MICFlags)(*(int *)(datablock+8) & MICF_MASK))
|
||
|
{
|
||
|
char const * datastart = datablock;
|
||
|
|
||
|
spares[0] = *(int *)datablock;
|
||
|
spares[1] = *(int *)(datablock+4);
|
||
|
|
||
|
int listsize = *(int *)(datablock+12);
|
||
|
datablock += 16;
|
||
|
|
||
|
for (;listsize; --listsize)
|
||
|
{
|
||
|
mlist.add_entry_end(datablock);
|
||
|
datablock += mlist.last_entry().Size();
|
||
|
}
|
||
|
|
||
|
assert(datastart + size == datablock);
|
||
|
}
|
||
|
|
||
|
size_t Matching_Images_Chunk::size_chunk()
|
||
|
{
|
||
|
chunk_size = 28; // 2dw spares, 1dw flags, 1dw list size, 12b header
|
||
|
|
||
|
for (LIF<MatchingImages> mlit(&mlist); !mlit.done(); mlit.next())
|
||
|
{
|
||
|
chunk_size += mlit().Size();
|
||
|
}
|
||
|
|
||
|
return chunk_size;
|
||
|
}
|
||
|
|
||
|
void Matching_Images_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 = spares[0];
|
||
|
*(int *)(data_start+4) = spares[1];
|
||
|
*(int *)(data_start+8) = flags;
|
||
|
|
||
|
*(int *)(data_start+12) = mlist.size();
|
||
|
|
||
|
data_start += 16;
|
||
|
|
||
|
for (LIF<MatchingImages> mlit(&mlist); !mlit.done(); mlit.next())
|
||
|
{
|
||
|
mlit().WriteData(data_start);
|
||
|
data_start += mlit().Size();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
ImageDescriptor const & Matching_Images_Chunk::GetLoadImage(ImageDescriptor const & _insteadof)
|
||
|
{
|
||
|
for (LIF<MatchingImages> mlit(&mlist); !mlit.done(); mlit.next())
|
||
|
{
|
||
|
if (_insteadof == mlit().insteadof) return mlit().load;
|
||
|
}
|
||
|
return _insteadof;
|
||
|
}
|
||
|
|
||
|
// Bitmap MD5 Chunk
|
||
|
RIF_IMPLEMENT_DYNCREATE("BMPMD5ID",Bitmap_MD5_Chunk)
|
||
|
|
||
|
Bitmap_MD5_Chunk::Bitmap_MD5_Chunk(Chunk_With_Children * parent, int const * md5id, BMP_Name const & rcbmp, char const * rname, char const * sname)
|
||
|
: Chunk(parent,"BMPMD5ID"), spare(0), flags(BMD5F_0), version_num(rcbmp.version_num)
|
||
|
{
|
||
|
memcpy(md5_val,md5id,16);
|
||
|
|
||
|
char const * bname = rcbmp.filename;
|
||
|
if (!bname) bname = "";
|
||
|
bmpname = new char[strlen(bname)+1];
|
||
|
strcpy(bmpname,bname);
|
||
|
|
||
|
if (!rname) rname = "";
|
||
|
rifname = new char[strlen(rname)+1];
|
||
|
strcpy(rifname,rname);
|
||
|
|
||
|
if (!sname) sname = "";
|
||
|
shapename = new char[strlen(sname)+1];
|
||
|
strcpy(shapename,sname);
|
||
|
}
|
||
|
|
||
|
Bitmap_MD5_Chunk::Bitmap_MD5_Chunk(Chunk_With_Children * parent, char const * datablock, size_t)
|
||
|
: Chunk(parent,"BMPMD5ID"), spare(*(int *)datablock), flags((BMPMD5_Flags)(*(int *)(datablock+4) & BMD5F_MASK)), version_num(*(int *)(datablock+8))
|
||
|
{
|
||
|
memcpy(md5_val,datablock+12,16);
|
||
|
datablock += 28;
|
||
|
unsigned int const blen = strlen(datablock)+1;
|
||
|
bmpname = new char [blen];
|
||
|
strcpy(bmpname,datablock);
|
||
|
datablock += blen;
|
||
|
unsigned int const rlen = strlen(datablock)+1;
|
||
|
rifname = new char [rlen];
|
||
|
strcpy(rifname,datablock);
|
||
|
datablock += rlen;
|
||
|
unsigned int const slen = strlen(datablock)+1;
|
||
|
shapename = new char [slen];
|
||
|
strcpy(shapename,datablock);
|
||
|
}
|
||
|
|
||
|
Bitmap_MD5_Chunk::~Bitmap_MD5_Chunk()
|
||
|
{
|
||
|
delete [] bmpname;
|
||
|
delete [] rifname;
|
||
|
delete [] shapename;
|
||
|
}
|
||
|
|
||
|
void Bitmap_MD5_Chunk::fill_data_block(char * datastart)
|
||
|
{
|
||
|
strncpy (datastart, identifier, 8);
|
||
|
datastart += 8;
|
||
|
*((int *) datastart) = chunk_size;
|
||
|
datastart += 4;
|
||
|
|
||
|
*(int *)datastart = spare;
|
||
|
*(int *)(datastart+4) = flags;
|
||
|
*(int *)(datastart+8) = version_num;
|
||
|
memcpy(datastart+12,md5_val,16);
|
||
|
datastart += 28;
|
||
|
strcpy(datastart,bmpname ? bmpname : "");
|
||
|
datastart += strlen(datastart)+1;
|
||
|
strcpy(datastart,rifname ? rifname : "");
|
||
|
datastart += strlen(datastart)+1;
|
||
|
strcpy(datastart,shapename ? shapename : "");
|
||
|
}
|
||
|
|
||
|
size_t Bitmap_MD5_Chunk::size_chunk()
|
||
|
{
|
||
|
return chunk_size = 12+28
|
||
|
+(bmpname ? strlen(bmpname) : 0)
|
||
|
+(rifname ? strlen(rifname) : 0)
|
||
|
+(shapename ? strlen(shapename) : 0)
|
||
|
+3 +3&~3;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|