Order mat-tex combinations by appearance in texture map instead of by palette index when zooming map to landscape.

This should simplify insertion of new textures at arbitrary drawing orders without reassigning palette indices (the latter would invalidate all old maps).
lights3
Sven Eberhardt 2015-08-10 00:34:43 -04:00
parent 5e03c9a8db
commit 0d16e67066
4 changed files with 38 additions and 6 deletions

View File

@ -12,7 +12,8 @@
<dt id="TexMaptxt"><img height="16" src="../../images/icon_text.png" width="16"/>TexMap.txt</dt>
<dd>
<text>Lookup table for color indices in static and dynamic landscapes. Colors 0-255 are matched to a material-texture-reference, except in Map.bmp static landscapes, where colors 0-127 are matched to a material-texture reference, and 128-255 are matched to the same list of references, except they are marked 'underground'.</text>
<text>The engine will draw materials with a higher index above those with a lower index so that, e.g. using the standard table, rough chunks of earth will overlap water which has a smooth border. Mineral resources have an even higher index so that their rough border overlaps the earth and not the other way around. This is also the reason why there might be differing numbers of total pixels of a given material drawn than you might expect just from calculating the square sizes of the unzoomed map materials.</text>
<text>Each line may contain one material-texture-entry in the format Index=Material-Texture. For example, 12=Earth-earth-topsoil would define color index 12 as earth material with the texture taken from a file called earth-topsoil.png.</text>
<text>The engine will draw materials in the order they are defined in the TexMap file, irrespective of assigned palette indices. Materials drawn late overwrite materials drawn early so that, e.g. using the standard table, rough chunks of earth will overlap water which has a smooth border. Mineral resources have an even higher index so that their rough border overlaps the earth and not the other way around. For this reason, there might be differing numbers of total pixels of a given material drawn than you might expect just from calculating the square sizes of the unzoomed map materials.</text>
<text>If a custom map fails with the message 'texture n undefined' you should define the specified texture in the TexMap. You should always use a paint program capable of editing indexed color palettes without modifying the palette (MS Paint is not suited for this).</text>
</dd>
<dt id="ocm"><img height="16" src="../../images/icon_material.png" width="16"/><emlink href="material/ocm.html">*.ocm</emlink></dt>

View File

@ -2239,12 +2239,15 @@ bool C4Landscape::TexOZoom(CSurface8 * sfcMap, CSurface8 * sfcMapBkg, int32_t iM
int32_t iIndex;
// ChunkOZoom all used textures
for (iIndex=1; iIndex<C4M_MaxTexIndex; iIndex++)
if (dwpTextureUsage[iIndex]>0)
for (auto i = ::TextureMap.Order.begin(); i != ::TextureMap.Order.end(); ++i)
{
iIndex = *i;
if (dwpTextureUsage[iIndex] > 0)
{
// ChunkOZoom map to landscape
ChunkOZoom(sfcMap,sfcMapBkg,iMapX,iMapY,iMapWdt,iMapHgt,iIndex,iToX,iToY);
ChunkOZoom(sfcMap, sfcMapBkg, iMapX, iMapY, iMapWdt, iMapHgt, iIndex, iToX, iToY);
}
}
// Done
return true;

View File

@ -123,6 +123,8 @@ bool C4TextureMap::AddEntry(BYTE byIndex, const char *szMaterial, const char *sz
// Landscape must be notified (new valid pixel clr)
::Landscape.HandleTexMapUpdate();
}
// Add last in order list
Order.push_back(byIndex);
return true;
}
@ -180,6 +182,8 @@ void C4TextureMap::Clear()
}
FirstTexture=NULL;
fInitialized = false;
Order.clear();
Order.reserve(C4M_MaxTexIndex);
}
bool C4TextureMap::LoadFlags(C4Group &hGroup, const char *szEntryName, bool *pOverloadMaterials, bool *pOverloadTextures)
@ -316,12 +320,15 @@ bool C4TextureMap::SaveMap(C4Group &hGroup, const char *szEntryName)
if (fOverloadTextures) sTexMapFile.Append("# Import textures from global file as well" LineFeed "OverloadTextures" LineFeed);
sTexMapFile.Append(LineFeed);
// add entries
for (int32_t i = 0; i < C4M_MaxTexIndex; i++)
for (auto iter = Order.begin(); iter != Order.end(); ++iter)
{
int32_t i = *iter;
if (!Entry[i].isNull())
{
// compose line
sTexMapFile.AppendFormat("%d=%s-%s" LineFeed, i, Entry[i].GetMaterialName(), Entry[i].GetTextureName());
}
}
// create new buffer allocated with new [], because C4Group cannot handle StdStrBuf-buffers
size_t iBufSize = sTexMapFile.getLength();
BYTE *pBuf = new BYTE[iBufSize];
@ -372,7 +379,12 @@ bool C4TextureMap::HasTextures(C4Group &hGroup)
void C4TextureMap::MoveIndex(BYTE byOldIndex, BYTE byNewIndex)
{
if (byNewIndex == byOldIndex) return;
Entry[byNewIndex] = Entry[byOldIndex];
Entry[byOldIndex].Clear();
auto old_entry = std::find_if(Order.begin(), Order.end(),
[byOldIndex](const int32_t &entry) { return entry == byOldIndex; });
if (old_entry != Order.end()) *old_entry = byNewIndex;
fEntriesAdded = true;
}
@ -494,6 +506,20 @@ void C4TextureMap::Default()
fOverloadMaterials=false;
fOverloadTextures=false;
fInitialized = false;
Order.clear();
Order.reserve(C4M_MaxTexIndex);
}
void C4TextureMap::RemoveEntry(int32_t iIndex)
{
// remove entry from table and order vector
if (Inside<int32_t>(iIndex, 1, C4M_MaxTexIndex - 1))
{
Entry[iIndex].Clear();
auto last_entry = std::remove_if(Order.begin(), Order.end(),
[iIndex](const int32_t &entry) { return entry == iIndex; });
Order.erase(last_entry, Order.end());
}
}
void C4TextureMap::StoreMapPalette(CStdPalette *Palette, C4MaterialMap &rMaterial)

View File

@ -69,6 +69,7 @@ public:
~C4TextureMap();
protected:
C4TexMapEntry Entry[C4M_MaxTexIndex];
std::vector<int32_t> Order; // drawing order in map2landscape. Reflects order in MatMap.txt file.
C4Texture *FirstTexture;
bool fOverloadMaterials;
bool fOverloadTextures;
@ -77,7 +78,7 @@ public:
bool fEntriesAdded;
public:
const C4TexMapEntry *GetEntry(int32_t iIndex) const { return Inside<int32_t>(iIndex, 0, C4M_MaxTexIndex-1) ? &Entry[iIndex] : NULL; }
void RemoveEntry(int32_t iIndex) { if (Inside<int32_t>(iIndex, 1, C4M_MaxTexIndex-1)) Entry[iIndex].Clear(); }
void RemoveEntry(int32_t iIndex);
void Default();
void Clear();
void StoreMapPalette(CStdPalette *, C4MaterialMap &rMaterials);
@ -98,6 +99,7 @@ public:
int32_t GetTextureIndex(const char *pTexName);
BYTE DefaultBkgMatTex(BYTE fg) const;
protected:
friend class C4Landscape;
};
extern C4TextureMap TextureMap;