Completely integrated the new axis ordering. Will update worlds accordingly
git-svn-id: http://mc-server.googlecode.com/svn/trunk@396 0a769ca7-a7f5-676a-18bf-c427514a06d6
This commit is contained in:
parent
4004129e11
commit
f90a8928e7
@ -323,6 +323,12 @@ cWSSCompact::cPAKFile::cPAKFile(const AString & a_FileName, int a_LayerX, int a_
|
|||||||
{
|
{
|
||||||
UpdateChunk1To2();
|
UpdateChunk1To2();
|
||||||
}
|
}
|
||||||
|
#if AXIS_ORDER == AXIS_ORDER_XZY
|
||||||
|
if( m_ChunkVersion == 2 ) // Convert chunks to version 3
|
||||||
|
{
|
||||||
|
UpdateChunk2To3();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -536,6 +542,144 @@ void cWSSCompact::cPAKFile::UpdateChunk1To2()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cWSSCompact::cPAKFile::UpdateChunk2To3()
|
||||||
|
{
|
||||||
|
int Offset = 0;
|
||||||
|
AString NewDataContents;
|
||||||
|
int ChunksConverted = 0;
|
||||||
|
for (sChunkHeaders::iterator itr = m_ChunkHeaders.begin(); itr != m_ChunkHeaders.end(); ++itr)
|
||||||
|
{
|
||||||
|
sChunkHeader * Header = *itr;
|
||||||
|
|
||||||
|
if( ChunksConverted % 32 == 0 )
|
||||||
|
{
|
||||||
|
LOGINFO("Updating \"%s\" version 2 to version 3: %d %%", m_FileName.c_str(), (ChunksConverted * 100) / m_ChunkHeaders.size() );
|
||||||
|
}
|
||||||
|
ChunksConverted++;
|
||||||
|
|
||||||
|
AString Data;
|
||||||
|
int UncompressedSize = Header->m_UncompressedSize;
|
||||||
|
Data.assign(m_DataContents, Offset, Header->m_CompressedSize);
|
||||||
|
Offset += Header->m_CompressedSize;
|
||||||
|
|
||||||
|
// Crude data integrity check:
|
||||||
|
int ExpectedSize = (16*256*16)*2 + (16*256*16)/2; // For version 2
|
||||||
|
if (UncompressedSize < ExpectedSize)
|
||||||
|
{
|
||||||
|
LOGWARNING("Chunk [%d, %d] has too short decompressed data (%d bytes out of %d needed), erasing",
|
||||||
|
Header->m_ChunkX, Header->m_ChunkZ,
|
||||||
|
UncompressedSize, ExpectedSize
|
||||||
|
);
|
||||||
|
Offset += Header->m_CompressedSize;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decompress the data:
|
||||||
|
AString UncompressedData;
|
||||||
|
{
|
||||||
|
int errorcode = UncompressString(Data.data(), Data.size(), UncompressedData, UncompressedSize);
|
||||||
|
if (errorcode != Z_OK)
|
||||||
|
{
|
||||||
|
LOGERROR("Error %d decompressing data for chunk [%d, %d]",
|
||||||
|
errorcode,
|
||||||
|
Header->m_ChunkX, Header->m_ChunkZ
|
||||||
|
);
|
||||||
|
Offset += Header->m_CompressedSize;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UncompressedSize != (int)UncompressedData.size())
|
||||||
|
{
|
||||||
|
LOGWARNING("Uncompressed data size differs (exp %d bytes, got %d) for chunk [%d, %d]",
|
||||||
|
UncompressedSize, UncompressedData.size(),
|
||||||
|
Header->m_ChunkX, Header->m_ChunkZ
|
||||||
|
);
|
||||||
|
Offset += Header->m_CompressedSize;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::auto_ptr<char> ConvertedData(new char[ ExpectedSize ]);
|
||||||
|
memset( ConvertedData.get(), 0, ExpectedSize );
|
||||||
|
|
||||||
|
// Cannot use cChunk::MakeIndex because it might change again?????????
|
||||||
|
// For compatibility, use what we know is current
|
||||||
|
#define MAKE_2_INDEX( x, y, z ) ( y + (z * 256) + (x * 256 * 16) )
|
||||||
|
#define MAKE_3_INDEX( x, y, z ) ( x + (z * 16) + (y * 16 * 16) )
|
||||||
|
|
||||||
|
unsigned int InChunkOffset = 0;
|
||||||
|
for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) for( int y = 0; y < 256; ++y ) // YZX Loop order is important, in 1.1 Y was first then Z then X
|
||||||
|
{
|
||||||
|
ConvertedData.get()[ MAKE_3_INDEX(x, y, z) ] = UncompressedData[InChunkOffset];
|
||||||
|
++InChunkOffset;
|
||||||
|
} // for y, z, x
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int index2 = 0;
|
||||||
|
for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) for( int y = 0; y < 256; ++y )
|
||||||
|
{
|
||||||
|
ConvertedData.get()[ InChunkOffset + MAKE_3_INDEX(x, y, z)/2 ] |= ( (UncompressedData[ InChunkOffset + index2/2 ] >> ((index2&1)*4) ) & 0x0f ) << ((x&1)*4);
|
||||||
|
++index2;
|
||||||
|
}
|
||||||
|
InChunkOffset += index2/2;
|
||||||
|
index2 = 0;
|
||||||
|
|
||||||
|
for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) for( int y = 0; y < 256; ++y )
|
||||||
|
{
|
||||||
|
ConvertedData.get()[ InChunkOffset + MAKE_3_INDEX(x, y, z)/2 ] |= ( (UncompressedData[ InChunkOffset + index2/2 ] >> ((index2&1)*4) ) & 0x0f ) << ((x&1)*4);
|
||||||
|
++index2;
|
||||||
|
}
|
||||||
|
InChunkOffset += index2/2;
|
||||||
|
index2 = 0;
|
||||||
|
|
||||||
|
for( int x = 0; x < 16; ++x ) for( int z = 0; z < 16; ++z ) for( int y = 0; y < 256; ++y )
|
||||||
|
{
|
||||||
|
ConvertedData.get()[ InChunkOffset + MAKE_3_INDEX(x, y, z)/2 ] |= ( (UncompressedData[ InChunkOffset + index2/2 ] >> ((index2&1)*4) ) & 0x0f ) << ((x&1)*4);
|
||||||
|
++index2;
|
||||||
|
}
|
||||||
|
InChunkOffset += index2/2;
|
||||||
|
index2 = 0;
|
||||||
|
|
||||||
|
AString Converted(ConvertedData.get(), ExpectedSize);
|
||||||
|
|
||||||
|
// Add JSON data afterwards
|
||||||
|
if (UncompressedData.size() > InChunkOffset)
|
||||||
|
{
|
||||||
|
Converted.append( UncompressedData.begin() + InChunkOffset, UncompressedData.end() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-compress data
|
||||||
|
AString CompressedData;
|
||||||
|
{
|
||||||
|
int errorcode = CompressString(Converted.data(), Converted.size(), CompressedData);
|
||||||
|
if (errorcode != Z_OK)
|
||||||
|
{
|
||||||
|
LOGERROR("Error %d compressing data for chunk [%d, %d]",
|
||||||
|
errorcode,
|
||||||
|
Header->m_ChunkX, Header->m_ChunkZ
|
||||||
|
);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save into file's cache
|
||||||
|
Header->m_UncompressedSize = Converted.size();
|
||||||
|
Header->m_CompressedSize = CompressedData.size();
|
||||||
|
NewDataContents.append( CompressedData );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Done converting
|
||||||
|
m_DataContents = NewDataContents;
|
||||||
|
m_ChunkVersion = 3;
|
||||||
|
SynchronizeFile();
|
||||||
|
|
||||||
|
LOGINFO("Updated \"%s\" version 2 to version 3", m_FileName.c_str() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bool cWSSCompact::LoadChunkFromData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, const AString & a_Data, cWorld * a_World)
|
bool cWSSCompact::LoadChunkFromData(const cChunkCoords & a_Chunk, int & a_UncompressedSize, const AString & a_Data, cWorld * a_World)
|
||||||
{
|
{
|
||||||
// Crude data integrity check:
|
// Crude data integrity check:
|
||||||
|
@ -48,7 +48,11 @@ protected:
|
|||||||
int GetLayerZ(void) const {return m_LayerZ; }
|
int GetLayerZ(void) const {return m_LayerZ; }
|
||||||
|
|
||||||
static const int PAK_VERSION = 1;
|
static const int PAK_VERSION = 1;
|
||||||
|
#if AXIS_ORDER == AXIS_ORDER_XZY
|
||||||
|
static const int CHUNK_VERSION = 3;
|
||||||
|
#elif AXIS_ORDER == AXIS_ORDER_YZX
|
||||||
static const int CHUNK_VERSION = 2;
|
static const int CHUNK_VERSION = 2;
|
||||||
|
#endif
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
AString m_FileName;
|
AString m_FileName;
|
||||||
@ -67,7 +71,8 @@ protected:
|
|||||||
bool SaveChunkToData(const cChunkCoords & a_Chunk, cWorld * a_World); // Saves the chunk to m_DataContents, updates headers and m_NumDirty
|
bool SaveChunkToData(const cChunkCoords & a_Chunk, cWorld * a_World); // Saves the chunk to m_DataContents, updates headers and m_NumDirty
|
||||||
void SynchronizeFile(void); // Writes m_DataContents along with the headers to file, resets m_NumDirty
|
void SynchronizeFile(void); // Writes m_DataContents along with the headers to file, resets m_NumDirty
|
||||||
|
|
||||||
void UpdateChunk1To2(void);
|
void UpdateChunk1To2(void); // Height from 128 to 256
|
||||||
|
void UpdateChunk2To3(void); // Axis order from YZX to XZY
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
typedef std::list<cPAKFile *> cPAKFiles;
|
typedef std::list<cPAKFile *> cPAKFiles;
|
||||||
|
@ -29,7 +29,7 @@ It will help us when the new chunk format comes out and we need to patch everyth
|
|||||||
// Used to smoothly convert to new axis ordering. One will be removed when deemed stable.
|
// Used to smoothly convert to new axis ordering. One will be removed when deemed stable.
|
||||||
#define AXIS_ORDER_YZX 1 // Original (1.1-)
|
#define AXIS_ORDER_YZX 1 // Original (1.1-)
|
||||||
#define AXIS_ORDER_XZY 2 // New (1.2+)
|
#define AXIS_ORDER_XZY 2 // New (1.2+)
|
||||||
#define AXIS_ORDER AXIS_ORDER_YZX
|
#define AXIS_ORDER AXIS_ORDER_XZY
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user