Just had to add my voice to the chorus of praise for your work to date. Excellent detective work, keep it up.
Originally posted by Gathenhielm
Too bad it will be moved to the OT forum![]()
![]()
Originally posted by andrashi
A Comp.crash robbed us of 99% of oure files and drawings .
void CGameMapCodec::DecompressBlock(int wx, int wy, int zoom)
{
#ifndef _BUILDMAP
int a, b = 4711;
if (wx < 0)
wx += MAP_WIDTH;
if (wx >= MAP_WIDTH)
wx -= MAP_WIDTH;
ASSERT(wy >= 0 && wy < MAP_HEIGHT);
wx >>= zoom;
wy >>= zoom;
int mappitch = MAP_WIDTH >> zoom;
int index = MapTrees[zoom].Offsets[(((wx)>>5) + ((wy)>>5) * ((mappitch>>5)))*3] + (MapTrees[zoom].Offsets[(((wx)>>5) + ((wy)>>5) * ((mappitch>>5)))*3+1]<<8) + (MapTrees[zoom].Offsets[(((wx)>>5) + ((wy)>>5) * ((mappitch>>5)))*3+2]<<16);
int size = MapTrees[zoom].Offsets[(((wx)>>5) + ((wy)>>5) * ((mappitch>>5)))*3+3] + (MapTrees[zoom].Offsets[(((wx)>>5) + ((wy)>>5) * ((mappitch>>5)))*3+4]<<8) + (MapTrees[zoom].Offsets[(((wx)>>5) + ((wy)>>5) * ((mappitch>>5)))*3+5]<<16) - index;
// The id list is the first thing in the compressed block
BlockCompressed.IdTable = &MapTrees[zoom].Trees[index];
// Build an id table out of the bit7-terminated list
BlockDecompressed.NumOfIds = -1;
do
{
BlockDecompressed.NumOfIds++;
BlockDecompressed.IdTable[BlockDecompressed.NumOfIds] = BlockCompressed.IdTable[(BlockDecompressed.NumOfIds<<1)] | ((BlockCompressed.IdTable[(BlockDecompressed.NumOfIds<<1)+1]&127)<<8);
if (BlockDecompressed.IdTable[BlockDecompressed.NumOfIds]>MAX_PROVINCE)
int r = 0;
index += 2;
}
while(BlockCompressed.IdTable[(BlockDecompressed.NumOfIds<<1)+1] < TERMINATOR);
BlockDecompressed.NumOfIds++;
for(a = 0; a < BlockDecompressed.NumOfIds; a++)
{
if (BlockDecompressed.IdTable[a] > MAX_PROVINCE)
{
int color = BlockDecompressed.IdTable[a] & 1;
int id1 = BlockDecompressed.IdTable[((BlockDecompressed.IdTable[a]>>9)&63)-4];
int id2 = Province[id1].GetNeighbor((BlockDecompressed.IdTable[a]>>1)&15);
int river = (BlockDecompressed.IdTable[a]>>5)&15;
if ((!(gpMap->MapMode._DrawFlags & PROVINCE_DRAW_BORDERS)) || Province[id1].GetBorderStatus() == Province[id2].GetBorderStatus())
{
if (river != INVALID_ADJ)
id1 = Province[id1].GetNeighbor(river);
BlockDecompressed.IdTable[a] = id1;
}
else
{
if (Province[id1].IsViewable())
BlockDecompressed.IdTable[a] = MAX_PROVINCE;//+color;
else
BlockDecompressed.IdTable[a] = MAX_PROVINCE+2;//color;//+2;
}
}
}
// The tree structure pointer
BlockCompressed.Nodes = &MapTrees[zoom].Trees[index];
BlockDecompressed.NumOfLeafs = 0;
BlockDecompressed.SizeOfLeafs = 0;
BlockCompressed.NodeIndex = 0;
BlockCompressed.NodeMask = 1;
TreeInfo(5);
index += BlockCompressed.NodeIndex;
if (BlockCompressed.NodeMask > 1)
index++;
// The id information pointer
BlockCompressed.Ids = &MapTrees[zoom].Trees[index];
// Read the id stream diffrently depending on bit depth
if (BlockDecompressed.NumOfIds == 1)
{
b = 0;
for (a = 0; a < BlockDecompressed.NumOfLeafs; a++)
BlockDecompressed.Ids[a] = 0;//BlockDecompressed.IdTable[0];
}
else if (BlockDecompressed.NumOfIds == 2)
{
a = b = 0;
while (a < BlockDecompressed.NumOfLeafs)
{
BlockDecompressed.Ids[a++] = BlockCompressed.Ids[b] & 1;
BlockDecompressed.Ids[a++] = (BlockCompressed.Ids[b] & 2)>>1;
BlockDecompressed.Ids[a++] = (BlockCompressed.Ids[b] & 4)>>2;
BlockDecompressed.Ids[a++] = (BlockCompressed.Ids[b] & 8)>>3;
BlockDecompressed.Ids[a++] = (BlockCompressed.Ids[b] & 16)>>4;
BlockDecompressed.Ids[a++] = (BlockCompressed.Ids[b] & 32)>>5;
BlockDecompressed.Ids[a++] = (BlockCompressed.Ids[b] & 64)>>6;
BlockDecompressed.Ids[a++] = (BlockCompressed.Ids[b] & 128)>>7;
b++;
}
}
else if (BlockDecompressed.NumOfIds > 2 && BlockDecompressed.NumOfIds <= 4)
{
a = b = 0;
while (a < BlockDecompressed.NumOfLeafs)
{
BlockDecompressed.Ids[a++] = BlockCompressed.Ids[b] & 3;
BlockDecompressed.Ids[a++] = (BlockCompressed.Ids[b] & 12)>>2;
BlockDecompressed.Ids[a++] = (BlockCompressed.Ids[b] & 48)>>4;
BlockDecompressed.Ids[a++] = (BlockCompressed.Ids[b] & 192)>>6;
b++;
}
}
else if (BlockDecompressed.NumOfIds > 4 && BlockDecompressed.NumOfIds <= 16)
{
a = b = 0;
while (a < BlockDecompressed.NumOfLeafs)
{
BlockDecompressed.Ids[a++] = BlockCompressed.Ids[b] & 15;
BlockDecompressed.Ids[a++] = (BlockCompressed.Ids[b] & 240)>>4;
b++;
}
}
else if (BlockDecompressed.NumOfIds > 16)
{
a = b = 0;
while (a < BlockDecompressed.NumOfLeafs)
{
BlockDecompressed.Ids[a++] = BlockCompressed.Ids[b];
b++;
}
}
index += b;
// The leafs pointer
BlockCompressed.Leafs = &MapTrees[zoom].Trees[index];
// Read the leaf stream
a = b = 0;
while(a < BlockDecompressed.SizeOfLeafs)
{
BlockDecompressed.Leafs[a++] = BlockCompressed.Leafs[b] & 63;
BlockDecompressed.Leafs[a++] = (BlockCompressed.Leafs[b] >> 6 | BlockCompressed.Leafs[b+1] << 2) & 63;
BlockDecompressed.Leafs[a++] = (BlockCompressed.Leafs[b+1] >> 4 | BlockCompressed.Leafs[b+2] << 4) & 63;
BlockDecompressed.Leafs[a++] = BlockCompressed.Leafs[b+2] >> 2;
b += 3;
}
// Initialize the tree bitstream counters
BlockCompressed.NodeIndex = 0;
BlockCompressed.NodeMask = 1;
BlockDecompressed.LeafIndex = 0;
BlockDecompressed.IdIndex = 0;
#endif
}
could say that yes.Inferis said:Johan, am I looking in the right direction when I say "Quad Tree"?
AndrewT said:I have a slightly OT question for Inferis. We have people in the Bug Report forum saying that province.csv values for Terrain type do not actually govern things like attrition and movement rates. So we have some provinces that appear as desert but don't cause desert attrition, and others vice versa.
AndrewT said:Thanks for dropping in! And the effect of that terrain is read right out of that column in province.csv, I think it's N from memory?
IOW when, say, attrition is calculated for a given unit, the code looks in province.csv to see what terrain is listed there and then some internal terrain-attrition table to see how much effect there is?
If so I wonder how it is these people are so convinced of this? I mean they've taken notes and everything:
"for example Alexandria, Nile and Jordan, all of which are defined as Plains in province.csv and displayed as such on the map, do suffer from the desert-attrition penalty, so this attrition must be defined elsewhere".
tombom said:Sounds excellent. How much RAM do you have?
Inferis said:Also, there are still minor glitches having to do with borders (you can see this when loading up the game and looking at the Jaron province: the borders are not how they should be). This probably has something to do with the "finding the closest land" algorithm used when compressing.
WiSK said:So what do I want to know? Anything to make it go fasterWell, in your hint you suggested that I could somehow predict the moments to split the quadnodes by looking for "drempels" (dunno what that is in English; "bumps?"). But I'm not sure how to determine what kind of values would trigger a split; and where to split; and how much of the neighbouring values to look at; and in which directions would I need to scan.
I'll hold you to that!Birger said:Ok, I'm buying the beers next time we're going drinking!
Inferis, time to update the editor of yours.![]()