Template Magic
Removed need to allocate a fake meta block by using templates to provide a version of the code that does not use metas. Also changed the function to a template argument to make sure that the compilier is able to inline it.
This commit is contained in:
parent
744e00c904
commit
a42480cf82
|
@ -13,18 +13,20 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// This wild construct allows us to pass a function argument and still have it inlined by the compiler :)
|
// This wild construct allows us to pass a function argument and still have it inlined by the compiler :)
|
||||||
/// Merges two blocktypes and blockmetas of the specified sizes and offsets using the specified combinator function
|
/// Merges two blocktypes and blockmetas of the specified sizes and offsets using the specified combinator function
|
||||||
template<typename Combinator> void InternalMergeBlocks(
|
|
||||||
|
typedef void (CombinatorFunc)(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta);
|
||||||
|
|
||||||
|
template<bool MetasValid, CombinatorFunc Combinator>
|
||||||
|
void InternalMergeBlocks(
|
||||||
BLOCKTYPE * a_DstTypes, const BLOCKTYPE * a_SrcTypes,
|
BLOCKTYPE * a_DstTypes, const BLOCKTYPE * a_SrcTypes,
|
||||||
NIBBLETYPE * a_DstMetas, const NIBBLETYPE * a_SrcMetas,
|
NIBBLETYPE * a_DstMetas, const NIBBLETYPE * a_SrcMetas,
|
||||||
int a_SizeX, int a_SizeY, int a_SizeZ,
|
int a_SizeX, int a_SizeY, int a_SizeZ,
|
||||||
int a_SrcOffX, int a_SrcOffY, int a_SrcOffZ,
|
int a_SrcOffX, int a_SrcOffY, int a_SrcOffZ,
|
||||||
int a_DstOffX, int a_DstOffY, int a_DstOffZ,
|
int a_DstOffX, int a_DstOffY, int a_DstOffZ,
|
||||||
int a_SrcSizeX, int a_SrcSizeY, int a_SrcSizeZ,
|
int a_SrcSizeX, int a_SrcSizeY, int a_SrcSizeZ,
|
||||||
int a_DstSizeX, int a_DstSizeY, int a_DstSizeZ,
|
int a_DstSizeX, int a_DstSizeY, int a_DstSizeZ
|
||||||
Combinator a_Combinator
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UNUSED(a_SrcSizeY);
|
UNUSED(a_SrcSizeY);
|
||||||
|
@ -41,7 +43,15 @@ template<typename Combinator> void InternalMergeBlocks(
|
||||||
int DstIdx = DstBaseZ + a_DstOffX;
|
int DstIdx = DstBaseZ + a_DstOffX;
|
||||||
for (int x = 0; x < a_SizeX; x++)
|
for (int x = 0; x < a_SizeX; x++)
|
||||||
{
|
{
|
||||||
a_Combinator(a_DstTypes[DstIdx], a_SrcTypes[SrcIdx], a_DstMetas[DstIdx], a_SrcMetas[SrcIdx]);
|
if (MetasValid)
|
||||||
|
{
|
||||||
|
Combinator(a_DstTypes[DstIdx], a_SrcTypes[SrcIdx], a_DstMetas[DstIdx], a_SrcMetas[SrcIdx]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BLOCKTYPE FakeDestMeta = 0;
|
||||||
|
Combinator(a_DstTypes[DstIdx], a_SrcTypes[SrcIdx], FakeDestMeta, (NIBBLETYPE)0);
|
||||||
|
}
|
||||||
++DstIdx;
|
++DstIdx;
|
||||||
++SrcIdx;
|
++SrcIdx;
|
||||||
} // for x
|
} // for x
|
||||||
|
@ -51,13 +61,12 @@ template<typename Combinator> void InternalMergeBlocks(
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// Combinator used for cBlockArea::msOverwrite merging
|
/// Combinator used for cBlockArea::msOverwrite merging
|
||||||
|
template<bool MetaValid>
|
||||||
static inline void MergeCombinatorOverwrite(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta)
|
static inline void MergeCombinatorOverwrite(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta)
|
||||||
{
|
{
|
||||||
a_DstType = a_SrcType;
|
a_DstType = a_SrcType;
|
||||||
a_DstMeta = a_SrcMeta;
|
if (MetaValid) a_DstMeta = a_SrcMeta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,12 +74,13 @@ static inline void MergeCombinatorOverwrite(BLOCKTYPE & a_DstType, BLOCKTYPE a_S
|
||||||
|
|
||||||
|
|
||||||
/// Combinator used for cBlockArea::msFillAir merging
|
/// Combinator used for cBlockArea::msFillAir merging
|
||||||
|
template<bool MetaValid>
|
||||||
static inline void MergeCombinatorFillAir(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta)
|
static inline void MergeCombinatorFillAir(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta)
|
||||||
{
|
{
|
||||||
if (a_DstType == E_BLOCK_AIR)
|
if (a_DstType == E_BLOCK_AIR)
|
||||||
{
|
{
|
||||||
a_DstType = a_SrcType;
|
a_DstType = a_SrcType;
|
||||||
a_DstMeta = a_SrcMeta;
|
if (MetaValid) a_DstMeta = a_SrcMeta;
|
||||||
}
|
}
|
||||||
// "else" is the default, already in place
|
// "else" is the default, already in place
|
||||||
}
|
}
|
||||||
|
@ -80,12 +90,13 @@ static inline void MergeCombinatorFillAir(BLOCKTYPE & a_DstType, BLOCKTYPE a_Src
|
||||||
|
|
||||||
|
|
||||||
/// Combinator used for cBlockArea::msImprint merging
|
/// Combinator used for cBlockArea::msImprint merging
|
||||||
|
template<bool MetaValid>
|
||||||
static inline void MergeCombinatorImprint(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta)
|
static inline void MergeCombinatorImprint(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta)
|
||||||
{
|
{
|
||||||
if (a_SrcType != E_BLOCK_AIR)
|
if (a_SrcType != E_BLOCK_AIR)
|
||||||
{
|
{
|
||||||
a_DstType = a_SrcType;
|
a_DstType = a_SrcType;
|
||||||
a_DstMeta = a_SrcMeta;
|
if (MetaValid) a_DstMeta = a_SrcMeta;
|
||||||
}
|
}
|
||||||
// "else" is the default, already in place
|
// "else" is the default, already in place
|
||||||
}
|
}
|
||||||
|
@ -95,6 +106,7 @@ static inline void MergeCombinatorImprint(BLOCKTYPE & a_DstType, BLOCKTYPE a_Src
|
||||||
|
|
||||||
|
|
||||||
/// Combinator used for cBlockArea::msLake merging
|
/// Combinator used for cBlockArea::msLake merging
|
||||||
|
template<bool MetaValid>
|
||||||
static inline void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta)
|
static inline void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta)
|
||||||
{
|
{
|
||||||
// Sponge is the NOP block
|
// Sponge is the NOP block
|
||||||
|
@ -107,7 +119,7 @@ static inline void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcTyp
|
||||||
if (a_SrcType == E_BLOCK_AIR)
|
if (a_SrcType == E_BLOCK_AIR)
|
||||||
{
|
{
|
||||||
a_DstType = E_BLOCK_AIR;
|
a_DstType = E_BLOCK_AIR;
|
||||||
a_DstMeta = 0;
|
if (MetaValid) a_DstMeta = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +144,7 @@ static inline void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcTyp
|
||||||
case E_BLOCK_STATIONARY_LAVA:
|
case E_BLOCK_STATIONARY_LAVA:
|
||||||
{
|
{
|
||||||
a_DstType = a_SrcType;
|
a_DstType = a_SrcType;
|
||||||
a_DstMeta = a_SrcMeta;
|
if (MetaValid) a_DstMeta = a_SrcMeta;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -146,7 +158,7 @@ static inline void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcTyp
|
||||||
case E_BLOCK_MYCELIUM:
|
case E_BLOCK_MYCELIUM:
|
||||||
{
|
{
|
||||||
a_DstType = E_BLOCK_STONE;
|
a_DstType = E_BLOCK_STONE;
|
||||||
a_DstMeta = 0;
|
if (MetaValid) a_DstMeta = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,13 +171,14 @@ static inline void MergeCombinatorLake(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcTyp
|
||||||
|
|
||||||
|
|
||||||
/** Combinator used for cBlockArea::msSpongePrint merging */
|
/** Combinator used for cBlockArea::msSpongePrint merging */
|
||||||
|
template<bool MetaValid>
|
||||||
static inline void MergeCombinatorSpongePrint(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta)
|
static inline void MergeCombinatorSpongePrint(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta)
|
||||||
{
|
{
|
||||||
// Sponge overwrites nothing, everything else overwrites anything
|
// Sponge overwrites nothing, everything else overwrites anything
|
||||||
if (a_SrcType != E_BLOCK_SPONGE)
|
if (a_SrcType != E_BLOCK_SPONGE)
|
||||||
{
|
{
|
||||||
a_DstType = a_SrcType;
|
a_DstType = a_SrcType;
|
||||||
a_DstMeta = a_SrcMeta;
|
if (MetaValid) a_DstMeta = a_SrcMeta;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,17 +187,18 @@ static inline void MergeCombinatorSpongePrint(BLOCKTYPE & a_DstType, BLOCKTYPE a
|
||||||
|
|
||||||
|
|
||||||
/** Combinator used for cBlockArea::msDifference merging */
|
/** Combinator used for cBlockArea::msDifference merging */
|
||||||
|
template<bool MetaValid>
|
||||||
static inline void MergeCombinatorDifference(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta)
|
static inline void MergeCombinatorDifference(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta)
|
||||||
{
|
{
|
||||||
if ((a_DstType == a_SrcType) && (a_DstMeta == a_SrcMeta))
|
if ((a_DstType == a_SrcType) && (!MetaValid || (a_DstMeta == a_SrcMeta)))
|
||||||
{
|
{
|
||||||
a_DstType = E_BLOCK_AIR;
|
a_DstType = E_BLOCK_AIR;
|
||||||
a_DstMeta = 0;
|
if (MetaValid) a_DstMeta = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
a_DstType = a_SrcType;
|
a_DstType = a_SrcType;
|
||||||
a_DstMeta = a_SrcMeta;
|
if (MetaValid) a_DstMeta = a_SrcMeta;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -193,13 +207,14 @@ static inline void MergeCombinatorDifference(BLOCKTYPE & a_DstType, BLOCKTYPE a_
|
||||||
|
|
||||||
|
|
||||||
/** Combinator used for cBlockArea::msMask merging */
|
/** Combinator used for cBlockArea::msMask merging */
|
||||||
|
template<bool MetaValid>
|
||||||
static inline void MergeCombinatorMask(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta)
|
static inline void MergeCombinatorMask(BLOCKTYPE & a_DstType, BLOCKTYPE a_SrcType, NIBBLETYPE & a_DstMeta, NIBBLETYPE a_SrcMeta)
|
||||||
{
|
{
|
||||||
// If the blocks are the same, keep the dest; otherwise replace with air
|
// If the blocks are the same, keep the dest; otherwise replace with air
|
||||||
if ((a_SrcType != a_DstType) || (a_SrcMeta != a_DstMeta))
|
if ((a_SrcType != a_DstType) || !MetaValid || (a_SrcMeta != a_DstMeta))
|
||||||
{
|
{
|
||||||
a_DstType = E_BLOCK_AIR;
|
a_DstType = E_BLOCK_AIR;
|
||||||
a_DstMeta = 0;
|
if (MetaValid) a_DstMeta = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -484,7 +499,7 @@ void cBlockArea::CopyTo(cBlockArea & a_Into) const
|
||||||
a_Into.Clear();
|
a_Into.Clear();
|
||||||
a_Into.SetSize(m_Size.x, m_Size.y, m_Size.z, GetDataTypes());
|
a_Into.SetSize(m_Size.x, m_Size.y, m_Size.z, GetDataTypes());
|
||||||
a_Into.m_Origin = m_Origin;
|
a_Into.m_Origin = m_Origin;
|
||||||
int BlockCount = GetBlockCount();
|
size_t BlockCount = GetBlockCount();
|
||||||
if (HasBlockTypes())
|
if (HasBlockTypes())
|
||||||
{
|
{
|
||||||
memcpy(a_Into.m_BlockTypes, m_BlockTypes, BlockCount * sizeof(BLOCKTYPE));
|
memcpy(a_Into.m_BlockTypes, m_BlockTypes, BlockCount * sizeof(BLOCKTYPE));
|
||||||
|
@ -532,7 +547,7 @@ void cBlockArea::DumpToRawFile(const AString & a_FileName)
|
||||||
f.Write(&SizeZ, 4);
|
f.Write(&SizeZ, 4);
|
||||||
unsigned char DataTypes = (unsigned char)GetDataTypes();
|
unsigned char DataTypes = (unsigned char)GetDataTypes();
|
||||||
f.Write(&DataTypes, 1);
|
f.Write(&DataTypes, 1);
|
||||||
int NumBlocks = GetBlockCount();
|
size_t NumBlocks = GetBlockCount();
|
||||||
if (HasBlockTypes())
|
if (HasBlockTypes())
|
||||||
{
|
{
|
||||||
f.Write(m_BlockTypes, NumBlocks * sizeof(BLOCKTYPE));
|
f.Write(m_BlockTypes, NumBlocks * sizeof(BLOCKTYPE));
|
||||||
|
@ -637,160 +652,19 @@ void cBlockArea::Expand(int a_SubMinX, int a_AddMaxX, int a_SubMinY, int a_AddMa
|
||||||
|
|
||||||
void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy)
|
void cBlockArea::Merge(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy)
|
||||||
{
|
{
|
||||||
// Block types are compulsory, block metas are voluntary
|
|
||||||
if (!HasBlockTypes() || !a_Src.HasBlockTypes())
|
|
||||||
{
|
|
||||||
LOGWARNING("%s: cannot merge because one of the areas doesn't have blocktypes.", __FUNCTION__);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dst is *this, Src is a_Src
|
|
||||||
int SrcOffX = std::max(0, -a_RelX); // Offset in Src where to start reading
|
|
||||||
int DstOffX = std::max(0, a_RelX); // Offset in Dst where to start writing
|
|
||||||
int SizeX = std::min(a_Src.GetSizeX() - SrcOffX, GetSizeX() - DstOffX); // How many blocks to copy
|
|
||||||
|
|
||||||
int SrcOffY = std::max(0, -a_RelY); // Offset in Src where to start reading
|
|
||||||
int DstOffY = std::max(0, a_RelY); // Offset in Dst where to start writing
|
|
||||||
int SizeY = std::min(a_Src.GetSizeY() - SrcOffY, GetSizeY() - DstOffY); // How many blocks to copy
|
|
||||||
|
|
||||||
int SrcOffZ = std::max(0, -a_RelZ); // Offset in Src where to start reading
|
|
||||||
int DstOffZ = std::max(0, a_RelZ); // Offset in Dst where to start writing
|
|
||||||
int SizeZ = std::min(a_Src.GetSizeZ() - SrcOffZ, GetSizeZ() - DstOffZ); // How many blocks to copy
|
|
||||||
|
|
||||||
const NIBBLETYPE * SrcMetas = a_Src.GetBlockMetas();
|
const NIBBLETYPE * SrcMetas = a_Src.GetBlockMetas();
|
||||||
NIBBLETYPE * DstMetas = m_BlockMetas;
|
NIBBLETYPE * DstMetas = m_BlockMetas;
|
||||||
|
|
||||||
bool IsDummyMetas = ((SrcMetas == NULL) || (DstMetas == NULL));
|
bool IsDummyMetas = ((SrcMetas == NULL) || (DstMetas == NULL));
|
||||||
|
|
||||||
if (IsDummyMetas)
|
if (IsDummyMetas)
|
||||||
{
|
{
|
||||||
size_t SrcCount = a_Src.GetBlockCount();
|
MergeByStrategy<true>(a_Src, a_RelX, a_RelY, a_RelZ, a_Strategy, SrcMetas, DstMetas);
|
||||||
size_t DestCount = GetBlockCount();
|
|
||||||
NIBBLETYPE * tempSrcMetas = new NIBBLETYPE[SrcCount];
|
|
||||||
memset(tempSrcMetas, 0, SrcCount);
|
|
||||||
SrcMetas = tempSrcMetas;
|
|
||||||
DstMetas = new NIBBLETYPE[DestCount];
|
|
||||||
memset(DstMetas, 0, DestCount);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
switch (a_Strategy)
|
|
||||||
{
|
{
|
||||||
case msOverwrite:
|
MergeByStrategy<false>(a_Src, a_RelX, a_RelY, a_RelZ, a_Strategy, SrcMetas, DstMetas);
|
||||||
{
|
|
||||||
InternalMergeBlocks(
|
|
||||||
m_BlockTypes, a_Src.GetBlockTypes(),
|
|
||||||
DstMetas, SrcMetas,
|
|
||||||
SizeX, SizeY, SizeZ,
|
|
||||||
SrcOffX, SrcOffY, SrcOffZ,
|
|
||||||
DstOffX, DstOffY, DstOffZ,
|
|
||||||
a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
|
|
||||||
m_Size.x, m_Size.y, m_Size.z,
|
|
||||||
MergeCombinatorOverwrite
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
} // case msOverwrite
|
|
||||||
|
|
||||||
case msFillAir:
|
|
||||||
{
|
|
||||||
InternalMergeBlocks(
|
|
||||||
m_BlockTypes, a_Src.GetBlockTypes(),
|
|
||||||
DstMetas, SrcMetas,
|
|
||||||
SizeX, SizeY, SizeZ,
|
|
||||||
SrcOffX, SrcOffY, SrcOffZ,
|
|
||||||
DstOffX, DstOffY, DstOffZ,
|
|
||||||
a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
|
|
||||||
m_Size.x, m_Size.y, m_Size.z,
|
|
||||||
MergeCombinatorFillAir
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
} // case msFillAir
|
|
||||||
|
|
||||||
case msImprint:
|
|
||||||
{
|
|
||||||
InternalMergeBlocks(
|
|
||||||
m_BlockTypes, a_Src.GetBlockTypes(),
|
|
||||||
DstMetas, SrcMetas,
|
|
||||||
SizeX, SizeY, SizeZ,
|
|
||||||
SrcOffX, SrcOffY, SrcOffZ,
|
|
||||||
DstOffX, DstOffY, DstOffZ,
|
|
||||||
a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
|
|
||||||
m_Size.x, m_Size.y, m_Size.z,
|
|
||||||
MergeCombinatorImprint
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
} // case msImprint
|
|
||||||
|
|
||||||
case msLake:
|
|
||||||
{
|
|
||||||
InternalMergeBlocks(
|
|
||||||
m_BlockTypes, a_Src.GetBlockTypes(),
|
|
||||||
DstMetas, SrcMetas,
|
|
||||||
SizeX, SizeY, SizeZ,
|
|
||||||
SrcOffX, SrcOffY, SrcOffZ,
|
|
||||||
DstOffX, DstOffY, DstOffZ,
|
|
||||||
a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
|
|
||||||
m_Size.x, m_Size.y, m_Size.z,
|
|
||||||
MergeCombinatorLake
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
} // case msLake
|
|
||||||
|
|
||||||
case msSpongePrint:
|
|
||||||
{
|
|
||||||
InternalMergeBlocks(
|
|
||||||
m_BlockTypes, a_Src.GetBlockTypes(),
|
|
||||||
DstMetas, SrcMetas,
|
|
||||||
SizeX, SizeY, SizeZ,
|
|
||||||
SrcOffX, SrcOffY, SrcOffZ,
|
|
||||||
DstOffX, DstOffY, DstOffZ,
|
|
||||||
a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
|
|
||||||
m_Size.x, m_Size.y, m_Size.z,
|
|
||||||
MergeCombinatorSpongePrint
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
} // case msSpongePrint
|
|
||||||
|
|
||||||
case msDifference:
|
|
||||||
{
|
|
||||||
InternalMergeBlocks(
|
|
||||||
m_BlockTypes, a_Src.GetBlockTypes(),
|
|
||||||
DstMetas, SrcMetas,
|
|
||||||
SizeX, SizeY, SizeZ,
|
|
||||||
SrcOffX, SrcOffY, SrcOffZ,
|
|
||||||
DstOffX, DstOffY, DstOffZ,
|
|
||||||
a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
|
|
||||||
m_Size.x, m_Size.y, m_Size.z,
|
|
||||||
MergeCombinatorDifference
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
} // case msDifference
|
|
||||||
|
|
||||||
case msMask:
|
|
||||||
{
|
|
||||||
InternalMergeBlocks(
|
|
||||||
m_BlockTypes, a_Src.GetBlockTypes(),
|
|
||||||
DstMetas, SrcMetas,
|
|
||||||
SizeX, SizeY, SizeZ,
|
|
||||||
SrcOffX, SrcOffY, SrcOffZ,
|
|
||||||
DstOffX, DstOffY, DstOffZ,
|
|
||||||
a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
|
|
||||||
m_Size.x, m_Size.y, m_Size.z,
|
|
||||||
MergeCombinatorMask
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
} // case msMask
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
LOGWARNING("Unknown block area merge strategy: %d", a_Strategy);
|
|
||||||
ASSERT(!"Unknown block area merge strategy");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} // switch (a_Strategy)
|
|
||||||
|
|
||||||
if (IsDummyMetas)
|
|
||||||
{
|
|
||||||
delete[] SrcMetas;
|
|
||||||
delete[] DstMetas;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2084,7 +1958,7 @@ void cBlockArea::ExpandBlockTypes(int a_SubMinX, int a_AddMaxX, int a_SubMinY, i
|
||||||
int NewSizeX = m_Size.x + a_SubMinX + a_AddMaxX;
|
int NewSizeX = m_Size.x + a_SubMinX + a_AddMaxX;
|
||||||
int NewSizeY = m_Size.y + a_SubMinY + a_AddMaxY;
|
int NewSizeY = m_Size.y + a_SubMinY + a_AddMaxY;
|
||||||
int NewSizeZ = m_Size.z + a_SubMinZ + a_AddMaxZ;
|
int NewSizeZ = m_Size.z + a_SubMinZ + a_AddMaxZ;
|
||||||
int BlockCount = NewSizeX * NewSizeY * NewSizeZ;
|
size_t BlockCount = (size_t)NewSizeX * NewSizeY * NewSizeZ;
|
||||||
BLOCKTYPE * NewBlockTypes = new BLOCKTYPE[BlockCount];
|
BLOCKTYPE * NewBlockTypes = new BLOCKTYPE[BlockCount];
|
||||||
memset(NewBlockTypes, 0, BlockCount * sizeof(BLOCKTYPE));
|
memset(NewBlockTypes, 0, BlockCount * sizeof(BLOCKTYPE));
|
||||||
int OldIndex = 0;
|
int OldIndex = 0;
|
||||||
|
@ -2114,7 +1988,7 @@ void cBlockArea::ExpandNibbles(NIBBLEARRAY & a_Array, int a_SubMinX, int a_AddMa
|
||||||
int NewSizeX = m_Size.x + a_SubMinX + a_AddMaxX;
|
int NewSizeX = m_Size.x + a_SubMinX + a_AddMaxX;
|
||||||
int NewSizeY = m_Size.y + a_SubMinY + a_AddMaxY;
|
int NewSizeY = m_Size.y + a_SubMinY + a_AddMaxY;
|
||||||
int NewSizeZ = m_Size.z + a_SubMinZ + a_AddMaxZ;
|
int NewSizeZ = m_Size.z + a_SubMinZ + a_AddMaxZ;
|
||||||
int BlockCount = NewSizeX * NewSizeY * NewSizeZ;
|
size_t BlockCount = (size_t)NewSizeX * NewSizeY * NewSizeZ;
|
||||||
NIBBLETYPE * NewNibbles = new NIBBLETYPE[BlockCount];
|
NIBBLETYPE * NewNibbles = new NIBBLETYPE[BlockCount];
|
||||||
memset(NewNibbles, 0, BlockCount * sizeof(NIBBLETYPE));
|
memset(NewNibbles, 0, BlockCount * sizeof(NIBBLETYPE));
|
||||||
int OldIndex = 0;
|
int OldIndex = 0;
|
||||||
|
@ -2166,4 +2040,137 @@ void cBlockArea::RelSetData(
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template<bool MetasValid>
|
||||||
|
void cBlockArea::MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy, const NIBBLETYPE * SrcMetas, NIBBLETYPE * DstMetas)
|
||||||
|
{
|
||||||
|
// Block types are compulsory, block metas are voluntary
|
||||||
|
if (!HasBlockTypes() || !a_Src.HasBlockTypes())
|
||||||
|
{
|
||||||
|
LOGWARNING("%s: cannot merge because one of the areas doesn't have blocktypes.", __FUNCTION__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dst is *this, Src is a_Src
|
||||||
|
int SrcOffX = std::max(0, -a_RelX); // Offset in Src where to start reading
|
||||||
|
int DstOffX = std::max(0, a_RelX); // Offset in Dst where to start writing
|
||||||
|
int SizeX = std::min(a_Src.GetSizeX() - SrcOffX, GetSizeX() - DstOffX); // How many blocks to copy
|
||||||
|
|
||||||
|
int SrcOffY = std::max(0, -a_RelY); // Offset in Src where to start reading
|
||||||
|
int DstOffY = std::max(0, a_RelY); // Offset in Dst where to start writing
|
||||||
|
int SizeY = std::min(a_Src.GetSizeY() - SrcOffY, GetSizeY() - DstOffY); // How many blocks to copy
|
||||||
|
|
||||||
|
int SrcOffZ = std::max(0, -a_RelZ); // Offset in Src where to start reading
|
||||||
|
int DstOffZ = std::max(0, a_RelZ); // Offset in Dst where to start writing
|
||||||
|
int SizeZ = std::min(a_Src.GetSizeZ() - SrcOffZ, GetSizeZ() - DstOffZ); // How many blocks to copy
|
||||||
|
|
||||||
|
switch (a_Strategy)
|
||||||
|
{
|
||||||
|
case cBlockArea::msOverwrite:
|
||||||
|
{
|
||||||
|
InternalMergeBlocks<MetasValid, MergeCombinatorOverwrite<MetasValid> >(
|
||||||
|
m_BlockTypes, a_Src.GetBlockTypes(),
|
||||||
|
DstMetas, SrcMetas,
|
||||||
|
SizeX, SizeY, SizeZ,
|
||||||
|
SrcOffX, SrcOffY, SrcOffZ,
|
||||||
|
DstOffX, DstOffY, DstOffZ,
|
||||||
|
a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
|
||||||
|
m_Size.x, m_Size.y, m_Size.z
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
} // case msOverwrite
|
||||||
|
|
||||||
|
case cBlockArea::msFillAir:
|
||||||
|
{
|
||||||
|
InternalMergeBlocks<MetasValid, MergeCombinatorFillAir<MetasValid> >(
|
||||||
|
m_BlockTypes, a_Src.GetBlockTypes(),
|
||||||
|
DstMetas, SrcMetas,
|
||||||
|
SizeX, SizeY, SizeZ,
|
||||||
|
SrcOffX, SrcOffY, SrcOffZ,
|
||||||
|
DstOffX, DstOffY, DstOffZ,
|
||||||
|
a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
|
||||||
|
m_Size.x, m_Size.y, m_Size.z
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
} // case msFillAir
|
||||||
|
|
||||||
|
case cBlockArea::msImprint:
|
||||||
|
{
|
||||||
|
InternalMergeBlocks<MetasValid, MergeCombinatorImprint<MetasValid> >(
|
||||||
|
m_BlockTypes, a_Src.GetBlockTypes(),
|
||||||
|
DstMetas, SrcMetas,
|
||||||
|
SizeX, SizeY, SizeZ,
|
||||||
|
SrcOffX, SrcOffY, SrcOffZ,
|
||||||
|
DstOffX, DstOffY, DstOffZ,
|
||||||
|
a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
|
||||||
|
m_Size.x, m_Size.y, m_Size.z
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
} // case msImprint
|
||||||
|
|
||||||
|
case cBlockArea::msLake:
|
||||||
|
{
|
||||||
|
InternalMergeBlocks<MetasValid, MergeCombinatorLake<MetasValid> >(
|
||||||
|
m_BlockTypes, a_Src.GetBlockTypes(),
|
||||||
|
DstMetas, SrcMetas,
|
||||||
|
SizeX, SizeY, SizeZ,
|
||||||
|
SrcOffX, SrcOffY, SrcOffZ,
|
||||||
|
DstOffX, DstOffY, DstOffZ,
|
||||||
|
a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
|
||||||
|
m_Size.x, m_Size.y, m_Size.z
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
} // case msLake
|
||||||
|
|
||||||
|
case cBlockArea::msSpongePrint:
|
||||||
|
{
|
||||||
|
InternalMergeBlocks<MetasValid, MergeCombinatorSpongePrint<MetasValid> >(
|
||||||
|
m_BlockTypes, a_Src.GetBlockTypes(),
|
||||||
|
DstMetas, SrcMetas,
|
||||||
|
SizeX, SizeY, SizeZ,
|
||||||
|
SrcOffX, SrcOffY, SrcOffZ,
|
||||||
|
DstOffX, DstOffY, DstOffZ,
|
||||||
|
a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
|
||||||
|
m_Size.x, m_Size.y, m_Size.z
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
} // case msSpongePrint
|
||||||
|
|
||||||
|
case cBlockArea::msDifference:
|
||||||
|
{
|
||||||
|
InternalMergeBlocks<MetasValid, MergeCombinatorDifference<MetasValid> >(
|
||||||
|
m_BlockTypes, a_Src.GetBlockTypes(),
|
||||||
|
DstMetas, SrcMetas,
|
||||||
|
SizeX, SizeY, SizeZ,
|
||||||
|
SrcOffX, SrcOffY, SrcOffZ,
|
||||||
|
DstOffX, DstOffY, DstOffZ,
|
||||||
|
a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
|
||||||
|
m_Size.x, m_Size.y, m_Size.z
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
} // case msDifference
|
||||||
|
|
||||||
|
case cBlockArea::msMask:
|
||||||
|
{
|
||||||
|
InternalMergeBlocks<MetasValid, MergeCombinatorMask<MetasValid> >(
|
||||||
|
m_BlockTypes, a_Src.GetBlockTypes(),
|
||||||
|
DstMetas, SrcMetas,
|
||||||
|
SizeX, SizeY, SizeZ,
|
||||||
|
SrcOffX, SrcOffY, SrcOffZ,
|
||||||
|
DstOffX, DstOffY, DstOffZ,
|
||||||
|
a_Src.GetSizeX(), a_Src.GetSizeY(), a_Src.GetSizeZ(),
|
||||||
|
m_Size.x, m_Size.y, m_Size.z
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
} // case msMask
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
LOGWARNING("Unknown block area merge strategy: %d", a_Strategy);
|
||||||
|
ASSERT(!"Unknown block area merge strategy");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} // switch (a_Strategy)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -294,7 +294,7 @@ public:
|
||||||
NIBBLETYPE * GetBlockMetas (void) const { return m_BlockMetas; } // NOTE: one byte per block!
|
NIBBLETYPE * GetBlockMetas (void) const { return m_BlockMetas; } // NOTE: one byte per block!
|
||||||
NIBBLETYPE * GetBlockLight (void) const { return m_BlockLight; } // NOTE: one byte per block!
|
NIBBLETYPE * GetBlockLight (void) const { return m_BlockLight; } // NOTE: one byte per block!
|
||||||
NIBBLETYPE * GetBlockSkyLight(void) const { return m_BlockSkyLight; } // NOTE: one byte per block!
|
NIBBLETYPE * GetBlockSkyLight(void) const { return m_BlockSkyLight; } // NOTE: one byte per block!
|
||||||
int GetBlockCount(void) const { return m_Size.x * m_Size.y * m_Size.z; }
|
size_t GetBlockCount(void) const { return m_Size.x * m_Size.y * m_Size.z; }
|
||||||
int MakeIndex(int a_RelX, int a_RelY, int a_RelZ) const;
|
int MakeIndex(int a_RelX, int a_RelY, int a_RelZ) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -363,6 +363,9 @@ protected:
|
||||||
int a_DataTypes, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta,
|
int a_DataTypes, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta,
|
||||||
NIBBLETYPE a_BlockLight, NIBBLETYPE a_BlockSkyLight
|
NIBBLETYPE a_BlockLight, NIBBLETYPE a_BlockSkyLight
|
||||||
);
|
);
|
||||||
|
|
||||||
|
template<bool MetasValid>
|
||||||
|
void MergeByStrategy(const cBlockArea & a_Src, int a_RelX, int a_RelY, int a_RelZ, eMergeStrategy a_Strategy, const NIBBLETYPE * SrcMetas, NIBBLETYPE * DstMetas);
|
||||||
// tolua_begin
|
// tolua_begin
|
||||||
} ;
|
} ;
|
||||||
// tolua_end
|
// tolua_end
|
||||||
|
|
|
@ -143,7 +143,7 @@ bool cFile::IsEOF(void) const
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int cFile::Read (void * iBuffer, int iNumBytes)
|
int cFile::Read (void * iBuffer, size_t iNumBytes)
|
||||||
{
|
{
|
||||||
ASSERT(IsOpen());
|
ASSERT(IsOpen());
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ int cFile::Read (void * iBuffer, int iNumBytes)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int cFile::Write(const void * iBuffer, int iNumBytes)
|
int cFile::Write(const void * iBuffer, size_t iNumBytes)
|
||||||
{
|
{
|
||||||
ASSERT(IsOpen());
|
ASSERT(IsOpen());
|
||||||
|
|
||||||
|
|
|
@ -80,10 +80,10 @@ public:
|
||||||
bool IsEOF(void) const;
|
bool IsEOF(void) const;
|
||||||
|
|
||||||
/** Reads up to iNumBytes bytes into iBuffer, returns the number of bytes actually read, or -1 on failure; asserts if not open */
|
/** Reads up to iNumBytes bytes into iBuffer, returns the number of bytes actually read, or -1 on failure; asserts if not open */
|
||||||
int Read (void * iBuffer, int iNumBytes);
|
int Read (void * iBuffer, size_t iNumBytes);
|
||||||
|
|
||||||
/** Writes up to iNumBytes bytes from iBuffer, returns the number of bytes actually written, or -1 on failure; asserts if not open */
|
/** Writes up to iNumBytes bytes from iBuffer, returns the number of bytes actually written, or -1 on failure; asserts if not open */
|
||||||
int Write(const void * iBuffer, int iNumBytes);
|
int Write(const void * iBuffer, size_t iNumBytes);
|
||||||
|
|
||||||
/** Seeks to iPosition bytes from file start, returns old position or -1 for failure; asserts if not open */
|
/** Seeks to iPosition bytes from file start, returns old position or -1 for failure; asserts if not open */
|
||||||
int Seek (int iPosition);
|
int Seek (int iPosition);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user