示例#1
0
bool MusBinOutput::WriteElementAttr( const MusElement *element )
{
	Write( &element->liaison , 1 );
	Write( &element->dliai , 1 );
	Write( &element->fliai , 1 );
	Write( &element->lie_up , 1 );
	Write( &element->rel , 1 );
	Write( &element->drel , 1 );
	Write( &element->frel , 1 );
	Write( &element->oct , 1 );
	Write( &element->dimin , 1 );
	Write( &element->grp , 1 );
	Write( &element->_shport , 1 );
	Write( &element->ligat , 1 );
	Write( &element->ElemInvisible , 1 );
	Write( &element->pointInvisible , 1 );
	Write( &element->existDebord , 1 );
	Write( &element->fligat , 1 );
	Write( &element->notschowgrp , 1 );
	Write( &element->cone , 1 );
	Write( &element->liaisonPointil , 1 );
	Write( &element->reserve1 , 1 );
	Write( &element->reserve2 , 1 );
	Write( &element->ottava , 1 );
	uint16 = wxUINT16_SWAP_ON_BE( element->durNum );
	Write( &uint16, 2 );
	uint16 = wxUINT16_SWAP_ON_BE( element->durDen );
	Write( &uint16, 2 );
	uint16 = wxUINT16_SWAP_ON_BE( element->offset );
	Write( &uint16, 2 );
	int32 = wxINT32_SWAP_ON_BE( element->xrel );
	Write( &int32, 4 );
	
	return true;
}
示例#2
0
bool MusBinInput::ReadElementAttr( MusElement *element )
{
	Read( &element->liaison , 1 );
	Read( &element->dliai , 1 );
	Read( &element->fliai , 1 );
	Read( &element->lie_up , 1 );
	Read( &element->rel , 1 );
	Read( &element->drel , 1 );
	Read( &element->frel , 1 );
	Read( &element->oct , 1 );
	Read( &element->dimin , 1 );
	Read( &element->grp , 1 );
	Read( &element->_shport , 1 );
	Read( &element->ligat , 1 );
	Read( &element->ElemInvisible , 1 );
	Read( &element->pointInvisible , 1 );
	Read( &element->existDebord , 1 );
	Read( &element->fligat , 1 );
	Read( &element->notschowgrp , 1 );
	Read( &element->cone , 1 );
	Read( &element->liaisonPointil , 1 );
	Read( &element->reserve1 , 1 );
	Read( &element->reserve2 , 1 );
	Read( &element->ottava , 1 );
	Read( &uint16, 2 );
	element->durNum = wxUINT16_SWAP_ON_BE( uint16 );
	Read( &uint16, 2 );
	element->durDen = wxUINT16_SWAP_ON_BE( uint16 );
	Read( &uint16, 2 );
	element->offset = wxUINT16_SWAP_ON_BE( uint16 );
	Read( &int32, 4 );
	element->xrel = wxINT32_SWAP_ON_BE( int32 );
	
	return true;
}
示例#3
0
void MyApp::DoByteOrderDemo(wxCommandEvent& WXUNUSED(event))
{
    wxTextCtrl& textCtrl = * GetTextCtrl();

    textCtrl.Clear();
    textCtrl << _T("\nTest byte order macros:\n\n");

    #if wxBYTE_ORDER == wxLITTLE_ENDIAN
        textCtrl << _T("This is a little endian system.\n\n");
    #else
        textCtrl << _T("This is a big endian system.\n\n");
    #endif

    wxString text;

    wxInt32 var = 0xF1F2F3F4;
    text = wxEmptyString;
    text.Printf( _T("Value of wxInt32 is now: %#x.\n\n"), var );
    textCtrl.WriteText( text );

    text = wxEmptyString;
    text.Printf( _T("Value of swapped wxInt32 is: %#x.\n\n"), wxINT32_SWAP_ALWAYS( var ) );
    textCtrl.WriteText( text );

    text = wxEmptyString;
    text.Printf( _T("Value of wxInt32 swapped on little endian is: %#x.\n\n"), wxINT32_SWAP_ON_LE( var ) );
    textCtrl.WriteText( text );

    text = wxEmptyString;
    text.Printf( _T("Value of wxInt32 swapped on big endian is: %#x.\n\n"), wxINT32_SWAP_ON_BE( var ) );
    textCtrl.WriteText( text );
}
示例#4
0
/* RffArchive::isRffArchive
 * Checks if the given data is a valid Duke Nukem 3D grp archive
 *******************************************************************/
bool RffArchive::isRffArchive(MemChunk& mc)
{
	// Check size
	if (mc.getSize() < 12)
		return false;

	// Read grp header
	uint8_t magic[4];
	uint32_t version, dir_offset, num_lumps;

	mc.seek(0, SEEK_SET);
	mc.read(magic, 4);			// Should be "RFF\x18"
	mc.read(&version, 4);		// 0x01 0x03 \x00 \x00
	mc.read(&dir_offset, 4);	// Offset to directory
	mc.read(&num_lumps, 4);		// No. of lumps in rff

	// Byteswap values for big endian if needed
	dir_offset = wxINT32_SWAP_ON_BE(dir_offset);
	num_lumps = wxINT32_SWAP_ON_BE(num_lumps);
	version = wxINT32_SWAP_ON_BE(version);

	// Check the header
	if (magic[0] != 'R' || magic[1] != 'F' || magic[2] != 'F' || magic[3] != 0x1A || version != 0x301)
		return false;


	// Compute total size
	RFFLump* lumps = new RFFLump[num_lumps];
	mc.seek(dir_offset, SEEK_SET);
	theSplashWindow->setProgressMessage("Reading rff archive data");
	mc.read (lumps, num_lumps * sizeof(RFFLump));
	BloodCrypt (lumps, dir_offset, num_lumps * sizeof(RFFLump));
	uint32_t totalsize = 12 + num_lumps * sizeof(RFFLump);
	uint32_t size = 0;
	for (uint32_t a = 0; a < num_lumps; ++a)
	{
		totalsize += lumps[a].Size;
	}

	// Check if total size is correct
	if (totalsize > mc.getSize())
		return false;

	// If it's passed to here it's probably a grp file
	return true;
}
示例#5
0
bool MusBinOutput::WriteLyric( const MusElement *element )
{
	int32 = wxINT32_SWAP_ON_BE( (int)element->m_debord_str.Length() );
	Write( &int32, 4 );
	
	Write( element->m_debord_str.c_str(), (int)element->m_debord_str.Length() + 1 );
	return true;
}
示例#6
0
/* GobArchive::isGobArchive
 * Checks if the file at [filename] is a valid Dark Forces gob archive
 *******************************************************************/
bool GobArchive::isGobArchive(string filename)
{
	// Open file for reading
	wxFile file(filename);

	// Check it opened ok
	if (!file.IsOpened())
		return false;

	// Check size
	if (file.Length() < 12)
		return false;

	// Read header
	char header[4];
	file.Read(header, 4);

	// Check magic header
	if (header[0] != 'G' || header[1] != 'O' || header[2] != 'B' || header[3] != 0xA)
		return false;

	// Get directory offset
	uint32_t dir_offset = 0;
	file.Seek(4, wxFromStart);
	file.Read(&dir_offset, 4);
	dir_offset = wxINT32_SWAP_ON_BE(dir_offset);

	// Check size
	if ((unsigned)file.Length() < (dir_offset + 4))
		return false;

	// Get number of lumps
	uint32_t num_lumps = 0;
	file.Seek(dir_offset, wxFromStart);
	file.Read(&num_lumps, 4);
	num_lumps = wxINT32_SWAP_ON_BE(num_lumps);

	// Compute directory size
	uint32_t dir_size = (num_lumps * 21) + 4;
	if ((unsigned)file.Length() < (dir_offset + dir_size))
		return false;

	// If it's passed to here it's probably a gob file
	return true;
}
示例#7
0
bool ResArchive::isResArchive(MemChunk& mc, size_t& dir_offset, size_t& num_lumps)
{
	// Check size
	if (mc.getSize() < 12)
		return false;

	// Check for "Res!" header
	if (!(mc[0] == 'R' && mc[1] == 'e' && mc[2] == 's' && mc[3] == '!'))
		return false;

	// Get number of lumps and directory offset
	uint32_t offset_offset = 0;
	uint32_t rel_offset = 0;
	uint32_t dir_size = 0;
	mc.seek(4, SEEK_SET);
	mc.read(&dir_offset, 4);
	mc.read(&dir_size, 4);

	// Byteswap values for big endian if needed
	dir_size = wxINT32_SWAP_ON_BE(dir_size);
	dir_offset = wxINT32_SWAP_ON_BE(dir_offset);

	// A&A contains nested resource files. The offsets are then always relative to
	// the top-level file. This causes problem with the embedded archive system
	// used by SLADE3. The solution is to compute the offset offset. :)
	offset_offset = dir_offset - (mc.getSize() - dir_size);
	rel_offset = dir_offset - offset_offset;

	// Check directory offset and size are both decent
	if (dir_size % RESDIRENTRYSIZE || (rel_offset + dir_size) > mc.getSize())
		return false;

	num_lumps = dir_size / RESDIRENTRYSIZE;

	// Reset MemChunk (just in case)
	mc.seek(0, SEEK_SET);

	// If it's passed to here it's probably a res file
	return true;
}
示例#8
0
/* ADatArchive::isADatArchive
 * Checks if the file at [filename] is a valid Anachronox dat archive
 *******************************************************************/
bool ADatArchive::isADatArchive(string filename)
{
	// Open file for reading
	wxFile file(filename);

	// Check it opened ok
	if (!file.IsOpened() || file.Length() < 16)
		return false;

	// Read dat header
	char magic[4];
	long dir_offset;
	long dir_size;
	long version;
	file.Seek(0, wxFromStart);
	file.Read(magic, 4);
	file.Read(&dir_offset, 4);
	file.Read(&dir_size, 4);
	file.Read(&version, 4);

	// Byteswap values for big endian if needed
	dir_size = wxINT32_SWAP_ON_BE(dir_size);
	dir_offset = wxINT32_SWAP_ON_BE(dir_offset);

	// Check version
	if (wxINT32_SWAP_ON_BE(version) != 9)
		return false;

	// Check header
	if (magic[0] != 'A' || magic[1] != 'D' || magic[2] != 'A' || magic[3] != 'T')
		return false;

	// Check directory is sane
	if (dir_offset < 16 || dir_offset + dir_size > file.Length())
		return false;

	// That'll do
	return true;
}
示例#9
0
/* LfdArchive::isLfdArchive
 * Checks if the given data is a valid Dark Forces lfd archive
 *******************************************************************/
bool LfdArchive::isLfdArchive(MemChunk& mc)
{
	// Check size
	if (mc.getSize() < 12)
		return false;

	// Check magic header
	if (mc[0] != 'R' || mc[1] != 'M' || mc[2] != 'A' || mc[3] != 'P')
		return false;

	// Get offset of first entry
	uint32_t dir_offset = 0;
	mc.seek(12, SEEK_SET);
	mc.read(&dir_offset, 4);
	dir_offset = wxINT32_SWAP_ON_BE(dir_offset) + 16;
	if (dir_offset % 16) return false;
	char type1[5]; char type2[5];
	char name1[9]; char name2[9];
	uint32_t len1; uint32_t len2;
	mc.read(type1, 4); type1[4] = 0;
	mc.read(name1, 8); name1[8] = 0;
	mc.read(&len1, 4); len1 = wxINT32_SWAP_ON_BE(len1);

	// Check size
	if ((unsigned)mc.getSize() < (dir_offset + 16 + len1))
		return false;

	// Compare
	mc.seek(dir_offset, SEEK_SET);
	mc.read(type2, 4); type2[4] = 0;
	mc.read(name2, 8); name2[8] = 0;
	mc.read(&len2, 4); len2 = wxINT32_SWAP_ON_BE(len2);

	if (strcmp(type1, type2) || strcmp(name1, name2) || len1 != len2)
		return false;

	// If it's passed to here it's probably a lfd file
	return true;
}
示例#10
0
/* HogArchive::write
 * Writes the hog archive to a MemChunk
 * Returns true if successful, false otherwise
 *******************************************************************/
bool HogArchive::write(MemChunk& mc, bool update)
{
	// Determine individual lump offsets
	uint32_t offset = 3;
	ArchiveEntry* entry = NULL;
	for (uint32_t l = 0; l < numEntries(); l++)
	{
		offset += 17;
		entry = getEntry(l);
		setEntryOffset(entry, offset);
		if (update)
		{
			entry->setState(0);
			entry->exProp("Offset") = (int)offset;
		}
		offset += entry->getSize();
	}

	// Clear/init MemChunk
	mc.clear();
	mc.seek(0, SEEK_SET);
	mc.reSize(offset);

	// Write the header
	char header[3] = { 'D', 'H', 'F' };
	mc.write(header, 3);

	// Write the lumps
	for (uint32_t l = 0; l < numEntries(); l++)
	{
		entry = getEntry(l);
		mc.write(entry->getData(), entry->getSize());
	}

	// Write the directory
	for (uint32_t l = 0; l < numEntries(); l++)
	{
		entry = getEntry(l);
		char name[13] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
		long size = wxINT32_SWAP_ON_BE(entry->getSize());

		for (size_t c = 0; c < entry->getName().length() && c < 13; c++)
			name[c] = entry->getName()[c];

		mc.write(name, 13);
		mc.write(&size, 4);
		mc.write(entry->getData(), entry->getSize());
	}

	return true;
}
示例#11
0
/* ResArchive::isResArchive
 * Checks if the file at [filename] is a valid A&A res archive
 *******************************************************************/
bool ResArchive::isResArchive(string filename)
{
	// Open file for reading
	wxFile file(filename);

	// Check it opened ok
	if (!file.IsOpened())
		return false;

	file.Seek(0, wxFromStart);

	// Read header
	char header[5];
	file.Read(header, 4);
	header[4] = 0;

	// Check for "Res!" header
	if (!(header[0] == 'R' && header[1] == 'e' && header[2] == 's' && header[3] == '!'))
		return false;

	// Get number of lumps and directory offset
	uint32_t dir_offset = 0;
	uint32_t dir_size = 0;
	file.Read(&dir_offset, 4);
	file.Read(&dir_size, 4);

	// Byteswap values for big endian if needed
	dir_size = wxINT32_SWAP_ON_BE(dir_size);
	dir_offset = wxINT32_SWAP_ON_BE(dir_offset);

	// Check directory offset and size are both decent
	if (dir_size % RESDIRENTRYSIZE || (dir_offset + dir_size) > file.Length())
		return false;

	// If it's passed to here it's probably a res file
	return true;
}
示例#12
0
bool MusBinInput::ReadFileHeader( MusFileHeader *header )
{
	Read( &int32, 4 ); 
	m_flag = wxINT32_SWAP_ON_BE( int32 ); 
	Read( &int32, 4 ); 
	m_vmaj = wxINT32_SWAP_ON_BE( int32 ); 
    Read( &int32, 4 ); 
	m_vmin = wxINT32_SWAP_ON_BE( int32 ); 
    Read( &int32, 4 ); 
	m_vrev = wxINT32_SWAP_ON_BE( int32 ); 
	Read( &uint16, 2 ); 
	header->nbpage = wxUINT16_SWAP_ON_BE( uint16 ); // nbpage
	Read( &uint16, 2 ); 
	header->nopage = wxUINT16_SWAP_ON_BE( uint16 ); // nopage
	Read( &uint16, 2 ); 
	header->noligne = wxUINT16_SWAP_ON_BE( uint16 ); // noligne
	Read( &uint32, 4 );
	header->xpos = wxUINT32_SWAP_ON_BE( uint32 );  // xpso
	Read( &header->param.orientation, 1 ); // param - orientation
	Read( &header->param.EpLignesPortee, 1 ); // param - epLignesPortee
    header->param.EpLignesPortee = 1;	
	Read( &header->param.EpQueueNote, 1 ); // param - epQueueNotes
    header->param.EpQueueNote = 2;
	Read( &header->param.EpBarreMesure, 1 ); // param - epBarreMesure
	Read( &header->param.EpBarreValeur, 1 ); // param - epBarreValeur
	Read( &header->param.EpBlancBarreValeur, 1 ); // param - epBlancBarreValeur
	Read( &int32, 4 );
	header->param.pageFormatHor = wxINT32_SWAP_ON_BE( int32 ); // param - pageFormatHor
	Read( &int32, 4 );
	header->param.pageFormatVer = wxINT32_SWAP_ON_BE( int32 ); // param - pageFormatVer
	Read( &int16, 2 );
	header->param.MargeSOMMET = wxINT16_SWAP_ON_BE( int16 ); // param - margeSommet
	Read( &int16, 2 );
	header->param.MargeGAUCHEIMPAIRE = wxINT16_SWAP_ON_BE( int16 ); // param - margeGaucheImpaire
	Read( &int16, 2 );
	header->param.MargeGAUCHEPAIRE = wxINT16_SWAP_ON_BE( int16 ); // param - margeGauchePaire
    
	Read( &header->param.rapportPorteesNum, 1 ); // rpPorteesNum
	Read( &header->param.rapportPorteesDen, 1 ); // rpPorteesDen
	Read( &header->param.rapportDiminNum, 1 ); // rpDiminNum
	Read( &header->param.rapportDiminDen, 1 ); // rpDiminDen	
	Read( &header->param.hampesCorr, 1 ); // hampesCorr
    header->param.hampesCorr = 1;	 
    
	if ( AxFile::FormatVersion(m_vmaj, m_vmin, m_vrev) < AxFile::FormatVersion(1, 6, 1) )
		return true; // following values where added in 1.6.1
    // 1.6.1
    Read( &int32, 4 );
    header->param.notationMode = wxINT32_SWAP_ON_BE( int32 );

	return true;
}
示例#13
0
/* ADatArchive::isADatArchive
 * Checks if the given data is a valid Anachronox dat archive
 *******************************************************************/
bool ADatArchive::isADatArchive(MemChunk& mc)
{
	// Check it opened ok
	if (mc.getSize() < 16)
		return false;

	// Read dat header
	char magic[4];
	long dir_offset;
	long dir_size;
	long version;
	mc.seek(0, SEEK_SET);
	mc.read(magic, 4);
	mc.read(&dir_offset, 4);
	mc.read(&dir_size, 4);
	mc.read(&version, 4);

	// Byteswap values for big endian if needed
	dir_size = wxINT32_SWAP_ON_BE(dir_size);
	dir_offset = wxINT32_SWAP_ON_BE(dir_offset);

	// Check version
	if (wxINT32_SWAP_ON_BE(version) != 9)
		return false;

	// Check header
	if (magic[0] != 'A' || magic[1] != 'D' || magic[2] != 'A' || magic[3] != 'T')
		return false;

	// Check directory is sane
	if (dir_offset < 16 || (unsigned)(dir_offset + dir_size) > mc.getSize())
		return false;

	// That'll do
	return true;
}
示例#14
0
/* WadArchive::isWadArchive
 * Checks if the file at [filename] is a valid Doom wad archive
 *******************************************************************/
bool WadArchive::isWadArchive(string filename)
{
	// Open file for reading
	wxFile file(filename);

	// Check it opened ok
	if (!file.IsOpened())
		return false;

	// Read header
	char header[4];
	file.Read(header, 4);

	// Check for IWAD/PWAD header
	if (!(header[1] == 'W' && header[2] == 'A' && header[3] == 'D' &&
	        (header[0] == 'P' || header[0] == 'I')))
		return false;

	// Get number of lumps and directory offset
	uint32_t num_lumps = 0;
	uint32_t dir_offset = 0;
	file.Read(&num_lumps, 4);
	file.Read(&dir_offset, 4);

	// Byteswap values for big endian if needed
	num_lumps = wxINT32_SWAP_ON_BE(num_lumps);
	dir_offset = wxINT32_SWAP_ON_BE(dir_offset);

	// Check directory offset is decent
	if ((dir_offset + (num_lumps * 16)) > file.Length() ||
	        dir_offset < 12)
		return false;

	// If it's passed to here it's probably a wad file
	return true;
}
bool CRemoteProtocolHandler::readUnlink(wxString& callsign, PROTOCOL& protocol, wxString& reflector)
{
	if (m_type != RPHT_UNLINK)
		return false;

	callsign = wxString((char*)(m_inBuffer + 3U), wxConvLocal, LONG_CALLSIGN_LENGTH);

	wxInt32 temp;
	::memcpy(&temp, m_inBuffer + 3U + LONG_CALLSIGN_LENGTH, sizeof(wxInt32));
	protocol = PROTOCOL(wxINT32_SWAP_ON_BE(temp));

	reflector = wxString((char*)(m_inBuffer + 3U + LONG_CALLSIGN_LENGTH + sizeof(wxInt32)), wxConvLocal, LONG_CALLSIGN_LENGTH);

	return true;
}
示例#16
0
// -----------------------------------------------------------------------------
// Checks if the file at [filename] is a valid DN3D grp archive
// -----------------------------------------------------------------------------
bool GrpArchive::isGrpArchive(const string& filename)
{
	// Open file for reading
	wxFile file(filename);

	// Check it opened ok
	if (!file.IsOpened())
		return false;

	// Check size
	if (file.Length() < 16)
		return false;

	// Get number of lumps
	uint32_t num_lumps     = 0;
	char     ken_magic[13] = "";
	file.Seek(0, wxFromStart);
	file.Read(ken_magic, 12); // "KenSilverman"
	file.Read(&num_lumps, 4); // No. of lumps in grp

	// Byteswap values for big endian if needed
	num_lumps = wxINT32_SWAP_ON_BE(num_lumps);

	// Null-terminate the magic header
	ken_magic[12] = 0;

	// Check the header
	if (!(S_CMP(wxString::From8BitData(ken_magic), "KenSilverman")))
		return false;

	// Compute total size
	uint32_t totalsize = (1 + num_lumps) * 16;
	uint32_t size      = 0;
	for (uint32_t a = 0; a < num_lumps; ++a)
	{
		file.Read(ken_magic, 12);
		file.Read(&size, 4);
		totalsize += size;
	}

	// Check if total size is correct
	if (totalsize > file.Length())
		return false;

	// If it's passed to here it's probably a grp file
	return true;
}
bool CRemoteProtocolHandler::readLink(wxString& callsign, RECONNECT& reconnect, wxString& reflector)
{
	if (m_type != RPHT_LINK)
		return false;

	callsign = wxString((char*)(m_inBuffer + 3U), wxConvLocal, LONG_CALLSIGN_LENGTH);

	wxInt32 temp;
	::memcpy(&temp, m_inBuffer + 3U + LONG_CALLSIGN_LENGTH, sizeof(wxInt32));
	reconnect = RECONNECT(wxINT32_SWAP_ON_BE(temp));

	reflector = wxString((char*)(m_inBuffer + 3U + LONG_CALLSIGN_LENGTH + sizeof(wxInt32)), wxConvLocal, LONG_CALLSIGN_LENGTH);

	if (reflector.IsSameAs(wxT("        ")))
		reflector.Clear();

	return true;
}
示例#18
0
bool MusBinOutput::WriteFileHeader( const MusFileHeader *header )
{
	int32 = wxINT32_SWAP_ON_BE( m_flag );
	Write( &int32, 4 );
	int32 = wxINT32_SWAP_ON_BE( AxApp::s_version_major );
	Write( &int32, 4 );
	int32 = wxINT32_SWAP_ON_BE( AxApp::s_version_minor );
	Write( &int32, 4 );
	int32 = wxINT32_SWAP_ON_BE( AxApp::s_version_revision );
	Write( &int32, 4 );
	uint16 = wxUINT16_SWAP_ON_BE( header->nbpage ); // nbpage
	Write( &uint16, 2 ); 
	uint16 = wxUINT16_SWAP_ON_BE( header->nopage ); // nopage
	Write( &uint16, 2 ); 
	uint16 = wxUINT16_SWAP_ON_BE( header->noligne ); // noligne
	Write( &uint16, 2 ); 
	uint32 = wxUINT32_SWAP_ON_BE( header->xpos ); // xpso
	Write( &uint32, 4 );
	Write( &header->param.orientation, 1 ); // param - orientation
	Write( &header->param.EpLignesPortee, 1 ); // param - epLignesPortee
	Write( &header->param.EpQueueNote, 1 ); // param - epQueueNotes
	Write( &header->param.EpBarreMesure, 1 ); // param - epBarreMesure
	Write( &header->param.EpBarreValeur, 1 ); // param - epBarreValeur
	Write( &header->param.EpBlancBarreValeur, 1 ); // param - epBlancBarreValeur
	int32 = wxINT32_SWAP_ON_BE( header->param.pageFormatHor ); // param - pageFormatHor
	Write( &int32, 4 );
	int32 = wxINT32_SWAP_ON_BE( header->param.pageFormatVer ); // param - pageFormatVer
	Write( &int32, 4 );
	int16 = wxINT16_SWAP_ON_BE( header->param.MargeSOMMET ); // param - margeSommet
	Write( &int16, 2 );
	int16 = wxINT16_SWAP_ON_BE( header->param.MargeGAUCHEIMPAIRE ); // param - margeGaucheImpaire
	Write( &int16, 2 );
	int16 = wxINT16_SWAP_ON_BE( header->param.MargeGAUCHEPAIRE ); // param - margeGauchePaire
	Write( &int16, 2 );
    
	Write( &header->param.rapportPorteesNum, 1 ); // rpPorteesNum
	Write( &header->param.rapportPorteesDen, 1 ); // rpPorteesDen
	Write( &header->param.rapportDiminNum, 1 ); // rpDiminNum
	Write( &header->param.rapportDiminDen, 1 ); // rpDiminDen
	Write( &header->param.hampesCorr, 1 ); // hampesCorr
    
	int32 = wxINT32_SWAP_ON_BE( header->param.notationMode ); // param - pageFormatVer
	Write( &int32, 4 );    
    
	return true;
}
示例#19
0
// -----------------------------------------------------------------------------
// Checks if the given data is a valid Duke Nukem 3D grp archive
// -----------------------------------------------------------------------------
bool GrpArchive::isGrpArchive(MemChunk& mc)
{
	// Check size
	if (mc.size() < 16)
		return false;

	// Get number of lumps
	uint32_t num_lumps     = 0;
	char     ken_magic[13] = "";
	mc.seek(0, SEEK_SET);
	mc.read(ken_magic, 12); // "KenSilverman"
	mc.read(&num_lumps, 4); // No. of lumps in grp

	// Byteswap values for big endian if needed
	num_lumps = wxINT32_SWAP_ON_BE(num_lumps);

	// Null-terminate the magic header
	ken_magic[12] = 0;

	// Check the header
	if (!(S_CMP(wxString::From8BitData(ken_magic), "KenSilverman")))
		return false;

	// Compute total size
	uint32_t totalsize = (1 + num_lumps) * 16;
	uint32_t size      = 0;
	for (uint32_t a = 0; a < num_lumps; ++a)
	{
		mc.read(ken_magic, 12);
		mc.read(&size, 4);
		totalsize += size;
	}

	// Check if total size is correct
	if (totalsize > mc.size())
		return false;

	// If it's passed to here it's probably a grp file
	return true;
}
示例#20
0
bool MusBinInput::ReadSymbol( MusSymbol *symbol )
{
	ReadElementAttr( symbol );
	Read( &symbol->flag , 1 );
	we also need to convert LEIPZIG_METER_SYMB_CUT into METER_SYMB_CUT for IND_MES
	Read( &symbol->calte , 1 );
	Read( &symbol->carStyle , 1 );
	Read( &symbol->carOrient , 1 );
	Read( &symbol->fonte , 1 );
	Read( &symbol->s_lie_l , 1 );
	Read( &symbol->point , 1 );
	Read( &uint16, 2 );
	symbol->code = wxUINT16_SWAP_ON_BE( uint16 );
	Read( &uint16, 2 );
	symbol->l_ptch = wxUINT16_SWAP_ON_BE( uint16 );
	Read( &int32, 4 );
	symbol->dec_y = wxINT32_SWAP_ON_BE( int32 );
	if ( symbol->IsLyric() )
        ReadLyric( symbol );
     
	return true;
}
示例#21
0
/* HogArchive::isHogArchive
 * Checks if the file at [filename] is a valid Descent hog archive
 *******************************************************************/
bool HogArchive::isHogArchive(string filename)
{
	// Open file for reading
	wxFile file(filename);

	// Check it opened ok
	if (!file.IsOpened())
		return false;

	// Check size
	size_t size = file.Length();
	if (size < 3)
		return false;

	// Check magic header
	char magic[3] = "";
	file.Seek(0, wxFromStart);
	file.Read(magic, 3);
	if (magic[0] != 'D' || magic[1] != 'H' || magic[2] != 'F')
		return false;

	// Iterate through files to see if the size seems okay
	size_t offset = 3;
	while (offset < size)
	{
		// Enough room for the header?
		if (offset + 17 > size)
			return false;
		// Read entry size to compute next offset
		uint32_t lumpsize;
		file.Seek(offset + 13, wxFromStart);
		file.Read(&lumpsize, 4);
		offset += 17 + wxINT32_SWAP_ON_BE(lumpsize);
	}

	// We should end on at exactly the end of the file
	return (offset == size);
}
示例#22
0
bool MusBinOutput::WriteSymbol( const MusSymbol *symbol )
{
	Write( &symbol->TYPE, 1 );
	WriteElementAttr( symbol );
	Write( &symbol->flag , 1 );
	Write( &symbol->calte , 1 );
	Write( &symbol->carStyle , 1 );
	Write( &symbol->carOrient , 1 );
	Write( &symbol->fonte , 1 );
	Write( &symbol->s_lie_l , 1 );
	Write( &symbol->point , 1 );
	uint16 = wxUINT16_SWAP_ON_BE( symbol->code );
	Write( &uint16, 2 );
	uint16 = wxUINT16_SWAP_ON_BE( symbol->l_ptch );
	Write( &uint16, 2 );	
	int32 = wxINT32_SWAP_ON_BE( symbol->dec_y );
	Write( &int32, 4 );
    // if ( symbol->IsLyric() ) // To be fixed ??
    if ( (symbol->flag == CHAINE) && (symbol->fonte == LYRIC) )
		WriteLyric( symbol );
	
	return true;
}
示例#23
0
inline static wxInt32 CacheReadInt32(wxInputStream *f)
{
    wxInt32 x;
    f->Read(&x, sizeof(x));
    return wxINT32_SWAP_ON_BE(x);
}
示例#24
0
inline static void CacheWriteInt32(wxOutputStream *f, wxInt32 value)
{
    wxInt32 x = wxINT32_SWAP_ON_BE(value);
    f->Write(&x, sizeof(x));
}
示例#25
0
/* DatArchive::open
 * Reads wad format data from a MemChunk
 * Returns true if successful, false otherwise
 *******************************************************************/
bool DatArchive::open(MemChunk& mc)
{
	// Check data was given
	if (!mc.hasData())
		return false;

	const uint8_t* mcdata = mc.getData();

	// Read dat header
	mc.seek(0, SEEK_SET);
	uint16_t num_lumps;
	uint32_t dir_offset, unknown;
	mc.read(&num_lumps, 2);		// Size
	mc.read(&dir_offset, 4);	// Directory offset
	mc.read(&unknown, 4);		// Unknown value
	num_lumps	= wxINT16_SWAP_ON_BE(num_lumps);
	dir_offset	= wxINT32_SWAP_ON_BE(dir_offset);
	unknown		= wxINT32_SWAP_ON_BE(unknown);
	string lastname(wxString::FromAscii("-noname-"));
	size_t namecount = 0;

	// Stop announcements (don't want to be announcing modification due to entries being added etc)
	setMuted(true);

	// Read the directory
	mc.seek(dir_offset, SEEK_SET);
	theSplashWindow->setProgressMessage("Reading dat archive data");
	for (uint32_t d = 0; d < num_lumps; d++)
	{
		// Update splash window progress
		theSplashWindow->setProgress(((float)d / (float)num_lumps));

		// Read lump info
		uint32_t offset = 0;
		uint32_t size = 0;
		uint16_t nameofs = 0;
		uint16_t flags = 0;

		mc.read(&offset,	4);		// Offset
		mc.read(&size,		4);		// Size
		mc.read(&nameofs,	2);		// Name offset
		mc.read(&flags,		2);		// Flags (only one: RLE encoded)

		// Byteswap values for big endian if needed
		offset = wxINT32_SWAP_ON_BE(offset);
		size = wxINT32_SWAP_ON_BE(size);
		nameofs = wxINT16_SWAP_ON_BE(nameofs);
		flags = wxINT16_SWAP_ON_BE(flags);

		// If the lump data goes past the directory,
		// the data file is invalid
		if (offset + size > mc.getSize())
		{
			wxLogMessage("DatArchive::open: Dat archive is invalid or corrupt at entry %i", d);
			Global::error = "Archive is invalid and/or corrupt";
			setMuted(false);
			return false;
		}

		string myname;
		if (nameofs != 0)
		{
			size_t len = 1;
			size_t start = nameofs+dir_offset;
			for (size_t i = start; mcdata[i] != 0; ++i) { ++len; }
			lastname = myname = wxString::FromAscii(mcdata+start, len);
			namecount = 0;
		}
		else
		{
			myname = S_FMT("%s+%d", lastname, ++namecount);
		}

		// Create & setup lump
		ArchiveEntry* nlump = new ArchiveEntry(myname, size);
		nlump->setLoaded(false);
		nlump->exProp("Offset") = (int)offset;
		nlump->setState(0);

		if (flags & 1) nlump->setEncryption(ENC_SCRLE0);

		// Check for markers
		if (!nlump->getName().Cmp("startflats"))
			flats[0] = d;
		if (!nlump->getName().Cmp("endflats"))
			flats[1] = d;
		if (!nlump->getName().Cmp("startsprites"))
			sprites[0] = d;
		if (!nlump->getName().Cmp("endmonsters"))
			sprites[1] = d;
		if (!nlump->getName().Cmp("startwalls"))
			walls[0] = d;
		if (!nlump->getName().Cmp("endwalls"))
			walls[1] = d;

		// Add to entry list
		getRoot()->addEntry(nlump);
	}

	// Detect all entry types
	MemChunk edata;
	theSplashWindow->setProgressMessage("Detecting entry types");
	for (size_t a = 0; a < numEntries(); a++)
	{
		// Update splash window progress
		theSplashWindow->setProgress((((float)a / (float)num_lumps)));

		// Get entry
		ArchiveEntry* entry = getEntry(a);

		// Read entry data if it isn't zero-sized
		if (entry->getSize() > 0)
		{
			// Read the entry data
			mc.exportMemChunk(edata, getEntryOffset(entry), entry->getSize());
			entry->importMemChunk(edata);
		}

		// Detect entry type
		EntryType::detectEntryType(entry);

		// Set entry to unchanged
		entry->setState(0);
	}

	// Detect maps (will detect map entry types)
	//theSplashWindow->setProgressMessage("Detecting maps");
	//detectMaps();

	// Setup variables
	setMuted(false);
	setModified(false);
	announce("opened");

	theSplashWindow->setProgressMessage("");

	return true;
}
示例#26
0
/* DatArchive::isDatArchive
 * Checks if the file at [filename] is a valid Shadowcaster dat archive
 *******************************************************************/
bool DatArchive::isDatArchive(string filename)
{
	// Open file for reading
	wxFile file(filename);

	// Check it opened ok
	if (!file.IsOpened())
		return false;

	// Read dat header
	file.Seek(0, wxFromStart);
	uint16_t num_lumps;
	uint32_t dir_offset, junk;
	file.Read(&num_lumps, 2);	// Size
	file.Read(&dir_offset, 4);	// Directory offset
	file.Read(&junk, 4);		// Unknown value
	num_lumps	= wxINT16_SWAP_ON_BE(num_lumps);
	dir_offset	= wxINT32_SWAP_ON_BE(dir_offset);
	junk		= wxINT32_SWAP_ON_BE(junk);

	if (dir_offset >= file.Length())
		return false;

	// Read the directory
	file.Seek(dir_offset, wxFromStart);
	// Read lump info
	uint32_t offset = 0;
	uint32_t size = 0;
	uint16_t nameofs = 0;
	uint16_t flags = 0;

	file.Read(&offset,	4);		// Offset
	file.Read(&size,	4);		// Size
	file.Read(&nameofs,	2);		// Name offset
	file.Read(&flags,	2);		// Flags

	// Byteswap values for big endian if needed
	offset	= wxINT32_SWAP_ON_BE(offset);
	size	= wxINT32_SWAP_ON_BE(size);
	nameofs = wxINT16_SWAP_ON_BE(nameofs);
	flags	= wxINT16_SWAP_ON_BE(flags);

	// The first lump should have a name (subsequent lumps need not have one).
	// Also, sanity check the values.
	if (nameofs == 0 || nameofs >=  file.Length() || offset + size >= file.Length())
	{
		return false;
	}

	string name;
	size_t len = 1;
	size_t start = nameofs+dir_offset;
	// Sanity checks again. Make sure there is actually a name.
	if (start > file.Length())
		return false;
	uint8_t temp;
	file.Seek(start, wxFromStart);
	file.Read(&temp, 1);
	if (temp < 33)
		return false;
	for (size_t i = start; i < file.Length(); ++i, ++len)
	{
		file.Read(&temp, 1);
		// Found end of name
		if (temp == 0)
			break;
		// Names should not contain garbage characters
		if (temp < 32 || temp > 126)
			return false;
	}
	// Let's be reasonable here. While names aren't limited, if it's too long, it's suspicious.
	if (len > 60)
		return false;
	return true;
}
示例#27
0
/* DatArchive::write
 * Writes the dat archive to a MemChunk
 * Returns true if successful, false otherwise
 *******************************************************************/
bool DatArchive::write(MemChunk& mc, bool update)
{
	// Only two bytes are used for storing entry amount,
	// so abort for excessively large files:
	if (numEntries() > 65535)
		return false;

	// Determine directory offset, name offsets & individual lump offsets
	uint32_t dir_offset = 10;
	uint16_t name_offset = numEntries() * 12;
	uint32_t name_size = 0;
	string previousname = "";
	uint16_t* nameoffsets = new uint16_t[numEntries()];
	ArchiveEntry* entry = NULL;
	for (uint16_t l = 0; l < numEntries(); l++)
	{
		entry = getEntry(l);
		setEntryOffset(entry, dir_offset);
		dir_offset += entry->getSize();

		// Does the entry has a name?
		string name = entry->getName();
		if (l > 0 && previousname.length() > 0 && name.length() > previousname.length() &&
		        !previousname.compare(0, previousname.length(), name, 0, previousname.length()) &&
		        name.at(previousname.length()) == '+')
		{
			// This is a fake name
			name = "";
			nameoffsets[l] = 0;
		}
		else
		{
			// This is a true name
			previousname = name;
			nameoffsets[l] = uint16_t(name_offset + name_size);
			name_size += name.length() + 1;
		}
	}

	// Clear/init MemChunk
	mc.clear();
	mc.seek(0, SEEK_SET);
	mc.reSize(dir_offset + name_size + numEntries() * 12);

	// Write the header
	uint16_t num_lumps = wxINT16_SWAP_ON_BE(numEntries());
	dir_offset = wxINT32_SWAP_ON_BE(dir_offset);
	uint32_t unknown = 0;
	mc.write(&num_lumps, 2);
	mc.write(&dir_offset, 4);
	mc.write(&unknown, 4);

	// Write the lumps
	for (uint16_t l = 0; l < numEntries(); l++)
	{
		entry = getEntry(l);
		mc.write(entry->getData(), entry->getSize());
	}

	// Write the directory
	for (uint16_t l = 0; l < num_lumps; l++)
	{
		entry = getEntry(l);

		uint32_t offset = wxINT32_SWAP_ON_BE(getEntryOffset(entry));
		uint32_t size = wxINT32_SWAP_ON_BE(entry->getSize());
		uint16_t nameofs = wxINT16_SWAP_ON_BE(nameoffsets[l]);
		uint16_t flags = wxINT16_SWAP_ON_BE((entry->isEncrypted() == ENC_SCRLE0) ? 1 : 0);

		mc.write(&offset,	4);		// Offset
		mc.write(&size,		4);		// Size
		mc.write(&nameofs,	2);		// Name offset
		mc.write(&flags,	2);		// Flags

		if (update)
		{
			entry->setState(0);
			entry->exProp("Offset") = (int)wxINT32_SWAP_ON_BE(offset);
		}
	}

	// Write the names
	for (uint16_t l = 0; l < num_lumps; l++)
	{
		uint8_t zero = 0;
		entry = getEntry(l);
		if (nameoffsets[l])
		{
			mc.write(CHR(entry->getName()), entry->getName().length());
			mc.write(&zero, 1);
		}
	}

	// Clean-up
	delete[] nameoffsets;

	// Finished!
	return true;
}
示例#28
0
bool wxBMPHandler::DoLoadDib(wxImage * image, int width, int height,
                             int bpp, int ncolors, int comp,
                             wxFileOffset bmpOffset, wxInputStream& stream,
                             bool verbose, bool IsBmp, bool hasPalette)
{
    wxInt32         aDword, rmask = 0, gmask = 0, bmask = 0, amask = 0;
    int             rshift = 0, gshift = 0, bshift = 0, ashift = 0;
    int             rbits = 0, gbits = 0, bbits = 0;
    wxInt32         dbuf[4];
    wxInt8          bbuf[4];
    wxUint8         aByte;
    wxUint16        aWord;

    // allocate space for palette if needed:
    BMPPalette *cmap;

    if ( bpp < 16 )
    {
        cmap = new BMPPalette[ncolors];
        if ( !cmap )
        {
            if (verbose)
            {
                wxLogError(_("BMP: Couldn't allocate memory."));
            }
            return false;
        }
    }
    else // no palette
    {
        cmap = NULL;
    }

    wxON_BLOCK_EXIT1(&BMPPalette::Free, cmap);

    // destroy existing here instead of:
    image->Destroy();
    image->Create(width, height);

    unsigned char *ptr = image->GetData();

    if ( !ptr )
    {
        if ( verbose )
        {
            wxLogError( _("BMP: Couldn't allocate memory.") );
        }
        return false;
    }

    unsigned char *alpha;
    if ( bpp == 32 )
    {
        // tell the image to allocate an alpha buffer
        image->SetAlpha();
        alpha = image->GetAlpha();
        if ( !alpha )
        {
            if ( verbose )
            {
                wxLogError(_("BMP: Couldn't allocate memory."));
            }
            return false;
        }
    }
    else // no alpha
    {
        alpha = NULL;
    }

    // Reading the palette, if it exists:
    if ( bpp < 16 && ncolors != 0 )
    {
        unsigned char* r = new unsigned char[ncolors];
        unsigned char* g = new unsigned char[ncolors];
        unsigned char* b = new unsigned char[ncolors];
        for (int j = 0; j < ncolors; j++)
        {
            if (hasPalette)
            {
                stream.Read(bbuf, 4);
                cmap[j].b = bbuf[0];
                cmap[j].g = bbuf[1];
                cmap[j].r = bbuf[2];

                r[j] = cmap[j].r;
                g[j] = cmap[j].g;
                b[j] = cmap[j].b;
            }
            else
            {
                //used in reading .ico file mask
                r[j] = cmap[j].r =
                g[j] = cmap[j].g =
                b[j] = cmap[j].b = ( j ? 255 : 0 );
            }
        }

#if wxUSE_PALETTE
        // Set the palette for the wxImage
        image->SetPalette(wxPalette(ncolors, r, g, b));
#endif // wxUSE_PALETTE

        delete[] r;
        delete[] g;
        delete[] b;
    }
    else if ( bpp == 16 || bpp == 32 )
    {
        if ( comp == BI_BITFIELDS )
        {
            int bit;
            stream.Read(dbuf, 4 * 3);
            rmask = wxINT32_SWAP_ON_BE(dbuf[0]);
            gmask = wxINT32_SWAP_ON_BE(dbuf[1]);
            bmask = wxINT32_SWAP_ON_BE(dbuf[2]);
            // find shift amount (Least significant bit of mask)
            for (bit = bpp-1; bit>=0; bit--)
            {
                if (bmask & (1 << bit))
                    bshift = bit;
                if (gmask & (1 << bit))
                    gshift = bit;
                if (rmask & (1 << bit))
                    rshift = bit;
            }
            // Find number of bits in mask (MSB-LSB+1)
            for (bit = 0; bit < bpp; bit++)
            {
                if (bmask & (1 << bit))
                    bbits = bit-bshift+1;
                if (gmask & (1 << bit))
                    gbits = bit-gshift+1;
                if (rmask & (1 << bit))
                    rbits = bit-rshift+1;
            }
        }
        else if ( bpp == 16 )
        {
            rmask = 0x7C00;
            gmask = 0x03E0;
            bmask = 0x001F;
            rshift = 10;
            gshift = 5;
            bshift = 0;
            rbits = 5;
            gbits = 5;
            bbits = 5;
        }
        else if ( bpp == 32 )
        {
            rmask = 0x00FF0000;
            gmask = 0x0000FF00;
            bmask = 0x000000FF;
            amask = 0xFF000000;

            ashift = 24;
            rshift = 16;
            gshift = 8;
            bshift = 0;
            rbits = 8;
            gbits = 8;
            bbits = 8;
        }
    }

    /*
     * Reading the image data
     */
    if ( IsBmp )
    {
        // NOTE: seeking a positive amount in wxFromCurrent mode allows us to
        //       load even non-seekable streams (see wxInputStream::SeekI docs)!
        const wxFileOffset pos = stream.TellI();
        if (pos != wxInvalidOffset && bmpOffset > pos)
            if (stream.SeekI(bmpOffset - pos, wxFromCurrent) == wxInvalidOffset)
                return false;
        //else: icon, just carry on
    }

    unsigned char *data = ptr;

    /* set the whole image to the background color */
    if ( bpp < 16 && (comp == BI_RLE4 || comp == BI_RLE8) )
    {
        for (int i = 0; i < width * height; i++)
        {
            *ptr++ = cmap[0].r;
            *ptr++ = cmap[0].g;
            *ptr++ = cmap[0].b;
        }
        ptr = data;
    }

    int linesize = ((width * bpp + 31) / 32) * 4;

    /* BMPs are stored upside down */
    for ( int line = (height - 1); line >= 0; line-- )
    {
        int linepos = 0;
        for ( int column = 0; column < width ; )
        {
            if ( bpp < 16 )
            {
                linepos++;
                aByte = stream.GetC();
                if ( bpp == 1 )
                {
                    for (int bit = 0; bit < 8 && column < width; bit++)
                    {
                        int index = ((aByte & (0x80 >> bit)) ? 1 : 0);
                        ptr[poffset] = cmap[index].r;
                        ptr[poffset + 1] = cmap[index].g;
                        ptr[poffset + 2] = cmap[index].b;
                        column++;
                    }
                }
                else if ( bpp == 4 )
                {
                    if ( comp == BI_RLE4 )
                    {
                        wxUint8 first;
                        first = aByte;
                        aByte = stream.GetC();
                        if ( first == 0 )
                        {
                            if ( aByte == 0 )
                            {
                                if ( column > 0 )
                                    column = width;
                            }
                            else if ( aByte == 1 )
                            {
                                column = width;
                                line = -1;
                            }
                            else if ( aByte == 2 )
                            {
                                aByte = stream.GetC();
                                column += aByte;
                                linepos = column * bpp / 4;
                                aByte = stream.GetC();
                                line -= aByte; // upside down
                            }
                            else
                            {
                                int absolute = aByte;
                                wxUint8 nibble[2] ;
                                int readBytes = 0 ;
                                for (int k = 0; k < absolute; k++)
                                {
                                    if ( !(k % 2 ) )
                                    {
                                        ++readBytes ;
                                        aByte = stream.GetC();
                                        nibble[0] = (wxUint8)( (aByte & 0xF0) >> 4 ) ;
                                        nibble[1] = (wxUint8)( aByte & 0x0F ) ;
                                    }
                                    ptr[poffset    ] = cmap[nibble[k%2]].r;
                                    ptr[poffset + 1] = cmap[nibble[k%2]].g;
                                    ptr[poffset + 2] = cmap[nibble[k%2]].b;
                                    column++;
                                    if ( k % 2 )
                                        linepos++;
                                }
                                if ( readBytes & 0x01 )
                                    aByte = stream.GetC();
                            }
                        }
                        else
                        {
                            wxUint8 nibble[2] ;
                            nibble[0] = (wxUint8)( (aByte & 0xF0) >> 4 ) ;
                            nibble[1] = (wxUint8)( aByte & 0x0F ) ;

                            for ( int l = 0; l < first && column < width; l++ )
                            {
                                ptr[poffset    ] = cmap[nibble[l%2]].r;
                                ptr[poffset + 1] = cmap[nibble[l%2]].g;
                                ptr[poffset + 2] = cmap[nibble[l%2]].b;
                                column++;
                                if ( l % 2 )
                                    linepos++;
                            }
                        }
                    }
示例#29
0
/* TextureXList::writeTEXTUREXData
 * Writes the texture list in TEXTUREX format to [texturex], using
 * [patch_table] for patch information. Returns true on success,
 * false otherwise
 *******************************************************************/
bool TextureXList::writeTEXTUREXData(ArchiveEntry* texturex, PatchTable& patch_table) {
	// Check entry was given
	if (!texturex)
		return false;

	if (texturex->isLocked())
		return false;

	wxLogMessage("Writing " + getTextureXFormatString() + " format TEXTUREx entry");

	/* Total size of a TEXTUREx lump, in bytes:
		Header: 4 + (4 * numtextures)
		Textures:
			22 * numtextures (normal format)
			14 * numtextures (nameless format)
			18 * numtextures (Strife 1.1 format)
		Patches:
			10 * sum of patchcounts (normal and nameless formats)
			 6 * sum of patchcounts (Strife 1.1 format)
	*/
	size_t numpatchrefs = 0;
	size_t numtextures = textures.size();
	for (size_t i = 0; i < numtextures; ++i) {
		numpatchrefs += textures[i]->nPatches();
	}
	wxLogMessage("%i patch references in %i textures", numpatchrefs, numtextures);

	size_t datasize = 0;
	size_t headersize = 4 + (4 * numtextures);
	switch (txformat) {
		case TXF_NORMAL:	datasize = 4 + (26 * numtextures) + (10 * numpatchrefs); break;
		case TXF_NAMELESS:	datasize = 4 + (18 * numtextures) + (10 * numpatchrefs); break;
		case TXF_STRIFE11:	datasize = 4 + (22 * numtextures) + ( 6 * numpatchrefs); break;
		// Some compilers insist on having default cases.
		default: return false;
	}

	MemChunk txdata(datasize);
	int32_t* offsets = new int32_t[numtextures];
	int32_t foo = wxINT32_SWAP_ON_BE((signed) numtextures);

	// Write header
	txdata.seek(0, SEEK_SET);
	SAFEFUNC(txdata.write(&foo, 4));

	// Go to beginning of texture definitions
	SAFEFUNC(txdata.seek(4 + (numtextures*4), SEEK_SET));

	// Write texture entries
	for (size_t i = 0; i < numtextures; ++i) {
		// Get texture to write
		CTexture* tex = textures[i];

		// Set offset
		offsets[i] = (signed)txdata.currentPos();

		// Write texture entry
		switch (txformat) {
			case TXF_NORMAL:
			{
				// Create 'normal' doom format texture definition
				ftdef_t txdef;
				memset(txdef.name, 0, 8); // Set texture name to all 0's (to ensure compatibility with XWE)
				strncpy(txdef.name, CHR(tex->getName().Upper()), tex->getName().Len());
				txdef.flags			= 0;
				txdef.scale[0]		= (tex->getScaleX()*8);
				txdef.scale[1]		= (tex->getScaleY()*8);
				txdef.width			= tex->getWidth();
				txdef.height		= tex->getHeight();
				txdef.columndir[0]	= 0;
				txdef.columndir[1]	= 0;
				txdef.patchcount	= tex->nPatches();

				// Check for WorldPanning flag
				if (tex->world_panning)
					txdef.flags |= TX_WORLDPANNING;

				// Write texture definition
				SAFEFUNC(txdata.write(&txdef, 22));

				break;
			}
			case TXF_NAMELESS:
			{
				// Create nameless texture definition
				nltdef_t txdef;
				txdef.flags			= 0;
				txdef.scale[0]		= (tex->getScaleX()*8);
				txdef.scale[1]		= (tex->getScaleY()*8);
				txdef.width			= tex->getWidth();
				txdef.height		= tex->getHeight();
				txdef.columndir[0]	= 0;
				txdef.columndir[1]	= 0;
				txdef.patchcount	= tex->nPatches();

				// Write texture definition
				SAFEFUNC(txdata.write(&txdef, 8));

				break;
			}
			case TXF_STRIFE11:
			{
				// Create strife format texture definition
				stdef_t txdef;
				memset(txdef.name, 0, 8); // Set texture name to all 0's (to ensure compatibility with XWE)
				strncpy(txdef.name, CHR(tex->getName().Upper()), tex->getName().Len());
				txdef.flags			= 0;
				txdef.scale[0]		= (tex->getScaleX()*8);
				txdef.scale[1]		= (tex->getScaleY()*8);
				txdef.width			= tex->getWidth();
				txdef.height		= tex->getHeight();
				txdef.patchcount	= tex->nPatches();

				// Check for WorldPanning flag
				if (tex->world_panning)
					txdef.flags |= TX_WORLDPANNING;

				// Write texture definition
				SAFEFUNC(txdata.write(&txdef, 18));

				break;
			}
			default: return false;
		}

		// Write patch references
		for (size_t k = 0; k < tex->nPatches(); ++k) {
			// Get patch to write
			CTPatch* patch = tex->getPatch(k);

			// Create patch definition
			tx_patch_t pdef;
			pdef.left = patch->xOffset();
			pdef.top = patch->yOffset();

			// Check for 'invalid' patch
			if (patch->getName().StartsWith("INVPATCH")) {
				// Get raw patch index from name
				string number = patch->getName();
				number.Replace("INVPATCH", "");
				long index;
				number.ToLong(&index);
				pdef.patch = index;
			}
			else
				pdef.patch = patch_table.patchIndex(patch->getName());	// Note this will be -1 if the patch doesn't exist in the patch table. This should never happen with the texture editor, though.

			// Write common data
			SAFEFUNC(txdata.write(&pdef, 6));

			// In non-Strife formats, there's some added rubbish
			if (txformat != TXF_STRIFE11) {
				foo = 0;
				SAFEFUNC(txdata.write(&foo, 4));
			}
		}
	}

	// Write offsets
	SAFEFUNC(txdata.seek(4, SEEK_SET));
	SAFEFUNC(txdata.write(offsets, 4*numtextures));

	// Write data to the TEXTUREx entry
	texturex->importMemChunk(txdata);

	// Update entry type
	EntryType::detectEntryType(texturex);

	// Clean up
	delete[] offsets;

	return true;
}
示例#30
0
/* TextureXList::readTEXTUREXData
 * Reads in a doom-format TEXTUREx entry. Returns true on success,
 * false otherwise
 *******************************************************************/
bool TextureXList::readTEXTUREXData(ArchiveEntry* texturex, PatchTable& patch_table, bool add) {
	// Check entries were actually given
	if (!texturex)
		return false;

	// Clear current textures if needed
	if (!add) clear();

	// Update palette
	theMainWindow->getPaletteChooser()->setGlobalFromArchive(texturex->getParent());

	// Read TEXTUREx

	// Read header
	texturex->seek(0, SEEK_SET);
	int32_t		n_tex = 0;
	int32_t*	offsets = NULL;

	// Number of textures
	if (!texturex->read(&n_tex, 4)) {
		wxLogMessage("Error: TEXTUREx entry is corrupt (can't read texture count)");
		return false;
	}
	n_tex = wxINT32_SWAP_ON_BE(n_tex);

	// If it's an empty TEXTUREx entry, stop here
	if (n_tex == 0)
		return true;

	// Texture definition offsets
	offsets = new int32_t[n_tex];
	if (!texturex->read(offsets, n_tex * 4)) {
		wxLogMessage("Error: TEXTUREx entry is corrupt (can't read first offset)");
		return false;
	}

	// Read the first texture definition to try to identify the format
	if (!texturex->seek(wxINT32_SWAP_ON_BE(offsets[0]), SEEK_SET)) {
		wxLogMessage("Error: TEXTUREx entry is corrupt (can't read first definition)");
		return false;
	}
	// Look at the name field. Is it present or not?
	char tempname[8];
	if (!texturex->read(&tempname, 8)) {
		wxLogMessage("Error: TEXTUREx entry is corrupt (can't read first name)");
		return false;
	}
	// Let's pretend it is and see what happens.
	txformat = TXF_NORMAL;

	// Only the characters A-Z (uppercase), 0-9, and [ ] - _ should be used in texture names.
	for (uint8_t a = 0; a < 8; ++a) {
		if (a > 0 && tempname[a] == 0)
			// We found a null-terminator for the string, so we can assume it's okay.
			break;
		if (tempname[a] >= 'a' && tempname[a] <= 'z') {
			txformat = TXF_JAGUAR;
			//wxLogMessage("Jaguar texture");
			break;
		}
		else if (!((tempname[a] >= 'A' && tempname[a] <= '[') ||
			  (tempname[a] >= '0' && tempname[a] <= '9') ||
			   tempname[a] == ']' || tempname[a] == '-' || tempname[a] == '_'))
			// We're out of character range, so this is probably not a texture name.
		{
			txformat = TXF_NAMELESS;
			//wxLogMessage("Nameless texture");
			break;
		}
	}

	// Now let's see if it is the abridged Strife format or not.
	if (txformat == TXF_NORMAL) {
		// No need to test this again since it was already tested before.
		texturex->seek(offsets[0], SEEK_SET);
		ftdef_t temp;
		if (!texturex->read(&temp, 22)) {
			wxLogMessage("Error: TEXTUREx entry is corrupt (can't test definition)");
			return false;
		}
		// Test condition adapted from ZDoom; apparently the first two bytes of columndir
		// may be set to garbage values by some editors and are therefore unreliable.
		if (wxINT16_SWAP_ON_BE(temp.patchcount <= 0) || (temp.columndir[1] != 0))
			txformat = TXF_STRIFE11;
	}

	// Read all texture definitions
	for (int32_t a = 0; a < n_tex; a++) {
		// Skip to texture definition
		if (!texturex->seek(offsets[a], SEEK_SET)) {
			wxLogMessage("Error: TEXTUREx entry is corrupt (can't find definition)");
			return false;
		}

		// Read definition
		tdef_t tdef;
		if (txformat == TXF_NAMELESS) {
			nltdef_t nameless;
			// Auto-naming mechanism taken from DeuTex
			if (a > 99999) {
				wxLogMessage("Error: More than 100000 nameless textures");
				return false;
			}
			char temp[9] = "";
			sprintf (temp, "TEX%05d", a);
			memcpy(tdef.name, temp, 8);

			// Read texture info
			if (!texturex->read(&nameless, 8)) {
				wxLogMessage("Error: TEXTUREx entry is corrupt (can't read nameless definition #%d)", a);
				return false;
			}

			// Copy data to permanent structure
			tdef.flags = nameless.flags;
			tdef.scale[0] = nameless.scale[0];
			tdef.scale[1] = nameless.scale[1];
			tdef.width = nameless.width;
			tdef.height = nameless.height;
		}
		else if (!texturex->read(&tdef, 16)) {
			wxLogMessage("Error: TEXTUREx entry is corrupt, (can't read texture definition #%d)", a);
			return false;
		}

		// Skip unused
		if (txformat != TXF_STRIFE11) {
			if (!texturex->seek(4, SEEK_CUR)) {
				wxLogMessage("Error: TEXTUREx entry is corrupt (can't skip dummy data past #%d)", a);
				return false;
			}
		}

		// Create texture
		CTexture* tex = new CTexture();
		tex->name = wxString::FromAscii(tdef.name, 8);
		tex->width = wxINT16_SWAP_ON_BE(tdef.width);
		tex->height = wxINT16_SWAP_ON_BE(tdef.height);
		tex->scale_x = tdef.scale[0]/8.0;
		tex->scale_y = tdef.scale[1]/8.0;

		// Set flags
		if (tdef.flags & TX_WORLDPANNING)
			tex->world_panning = true;

		// Read patches
		int16_t n_patches = 0;
		if (!texturex->read(&n_patches, 2)) {
			wxLogMessage("Error: TEXTUREx entry is corrupt (can't read patchcount #%d)", a);
			return false;
		}

		//wxLogMessage("Texture #%d: %d patch%s", a, n_patches, n_patches == 1 ? "" : "es");

		for (uint16_t p = 0; p < n_patches; p++) {
			// Read patch definition
			tx_patch_t pdef;
			if (!texturex->read(&pdef, 6)) {
				wxLogMessage("Error: TEXTUREx entry is corrupt (can't read patch definition #%d:%d)", a, p);
				wxLogMessage("Lump size %d, offset %d", texturex->getSize(), texturex->currentPos());
				return false;
			}

			// Skip unused
			if (txformat != TXF_STRIFE11) {
				if (!texturex->seek(4, SEEK_CUR)) {
					wxLogMessage("Error: TEXTUREx entry is corrupt (can't skip dummy data past #%d:%d)", a, p);
					return false;
				}
			}


			// Add it to the texture
			string patch;
			if (txformat == TXF_JAGUAR) {
				patch = tex->name.Upper();
			} else {
				patch = patch_table.patchName(pdef.patch);
			}
			if (patch.IsEmpty()) {
				//wxLogMessage("Warning: Texture %s contains patch %d which is invalid - may be incorrect PNAMES entry", CHR(tex->getName()), pdef.patch);
				patch = S_FMT("INVPATCH%04d", pdef.patch);
			}

			tex->addPatch(patch, pdef.left, pdef.top);
		}

		// Add texture to list
		addTexture(tex);
	}

	// Clean up
	delete[] offsets;

	return true;
}