Files
firestorm/Gameleap/code/mw4/Libraries/Compost/TerrainTextureLogistic.cpp
T
Cyd 2b8ca921cb Initial full mirror of c:\VWE (source + assets + toolchain + outputs) via Git LFS
Complete disaster-recovery snapshot: engine/game source, game data assets,
VC6 toolchain + DX SDKs, build outputs, deployed game, and _UNUSED archive.
Large binaries in Git LFS; text preserved byte-for-byte (core.autocrlf=false,
no eol attributes). See RECOVERY.md for the one-clone rebuild procedure.
2026-06-24 21:28:16 -05:00

2154 lines
59 KiB
C++

#include "CompostHeaders.hpp"
#include <ElementRenderer\ListElement.hpp>
#include <ElementRenderer\ShapeElement.hpp>
#include <ElementRenderer\GridElement.hpp>
#include <MLR\MLRTexture.hpp>
#include <MLR\MLRTexturePool.hpp>
#include <MLR\MLRShape.hpp>
#include <MLR\MLR_Terrain2.hpp>
#include <Adept\Tile.hpp>
using namespace MidLevelRenderer;
//#define HUNT_FOR_THE_RED_TILE "micgaert"
TerrainTextureLogistic *TerrainTextureLogistic::Instance = NULL;
#ifdef LAB_ONLY
DWORD TerrainTextureLogistic::borderColor;
bool TerrainTextureLogistic::borderKey;
#endif
const unsigned char BasePriority = 32;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
CompostQueue::CompostQueue()
{
firstInQueue = 0;
lastInQueue = 0;
flipAround = 0;
int i;
for(i=0;i<Length_Of_Compost_Queue;i++)
{
compostQueuePointer[i] = NULL;
}
for(i=0;i<Length_Of_Compost_Queue_Tracker;i++)
{
compostQueueTracker[i] = 0;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
CompostQueue::Restart()
{
firstInQueue = 0;
lastInQueue = 0;
flipAround = 0;
int i, j, k;
for(i=0,k=0;i<Length_Of_Compost_Queue_Tracker;i++)
{
if(compostQueueTracker[i] > 0)
{
int mask = 1;
for(j=0;j<sizeof(DWORD)*8;j++,k++,mask<<=1)
{
if(mask & compostQueueTracker[i])
{
compostQueue[k].textureHolder->ShutDown();
}
}
}
else
{
k += sizeof(DWORD)*8;
}
}
for(i=0;i<Length_Of_Compost_Queue;i++)
{
compostQueuePointer[i] = NULL;
}
for(i=0;i<Length_Of_Compost_Queue_Tracker;i++)
{
compostQueueTracker[i] = 0;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
int
CompostQueue::GetFirstFreeSpot()
{
int i, j;
for(i=0;i<Length_Of_Compost_Queue_Tracker;i++)
{
if(compostQueueTracker[i] == 0)
{
compostQueueTracker[i] |= 1;
return i*sizeof(DWORD)*8;
}
if(compostQueueTracker[i] < 0xffffffff)
{
int mask = 1;
for(j=0;j<sizeof(DWORD)*8;j++,mask<<=1)
{
if(!(mask & compostQueueTracker[i]))
{
compostQueueTracker[i] |= mask;
return i*sizeof(DWORD)*8+j;
}
}
}
}
return -1;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
CompostQueue::SetCompostQueue(
FeatureGrid *featureGrid,
int row,
int column,
TextureHolder *textureHolder,
int downSample,
int type
)
{
#if 1
int freeSpot = GetFirstFreeSpot();
if(freeSpot<0)
{
return false;
}
compostQueue[freeSpot].featureGrid = featureGrid;
compostQueue[freeSpot].row = row;
compostQueue[freeSpot].column = column;
Verify(textureHolder->pix_dest != NULL);
#ifdef LAB_ONLY
if(textureHolder->flags != TextureHolder::Free)
{
PAUSE(("Compost: Trying to work on a piece of texture already %s !",
textureHolder->flags == TextureHolder::InWork?"in work":"done" ));
}
#endif
textureHolder->flags = TextureHolder::InWork;
compostQueue[freeSpot].textureHolder = textureHolder;
compostQueue[freeSpot].downSample = downSample;
compostQueue[freeSpot].type = type;
compostQueue[freeSpot].done = freeSpot;
#ifdef _ARMOR
compostQueue[freeSpot].textureHolder->queuePosition = freeSpot;
#endif
#else
compostQueue[lastInQueue].featureGrid = featureGrid;
compostQueue[lastInQueue].row = row;
compostQueue[lastInQueue].column = column;
compostQueue[lastInQueue].textureHolder = textureHolder;
compostQueue[lastInQueue].downSample = downSample;
compostQueue[lastInQueue].type = type;
compostQueue[lastInQueue].done = done;
#ifdef _ARMOR
compostQueue[lastInQueue].textureHolder->queuePosition = lastInQueue;
#endif
if(++lastInQueue>=Length_Of_Compost_Queue)
{
lastInQueue = 0;
flipAround++;
}
#endif
return true;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
CompostQueue::DoWork()
{
#if 1
int i, j, k, workToDo = 0;
for(i=0,k=0;i<Length_Of_Compost_Queue_Tracker;i++)
{
if(compostQueueTracker[i] > 0)
{
int mask = 1;
for(j=0;j<sizeof(DWORD)*8;j++,k++,mask<<=1)
{
if(mask & compostQueueTracker[i])
{
if(
(*compostQueue[k].textureHolder->priority < 0) ||
(compostQueue[k].textureHolder->pix_dest == NULL)
)
{
compostQueueTracker[i] &= ~mask;
}
else
{
compostQueuePointer[workToDo++] = &compostQueue[k];
}
}
}
}
else
{
k += sizeof(DWORD)*8;
}
}
if(workToDo == 0)
{
return;
}
int ii, jj, hh;
CompostQueueStruct *tempCQS;
for(hh=1;hh<workToDo/9;hh=3*hh+1);
for(;hh>0;hh/=3)
{
for(ii=hh;ii<workToDo;ii++)
{
tempCQS = compostQueuePointer[ii];
jj = ii;
while(jj>=hh && *compostQueuePointer[jj-hh]->textureHolder->priority < *tempCQS->textureHolder->priority)
{
compostQueuePointer[jj] = compostQueuePointer[jj-hh];
jj -= hh;
}
compostQueuePointer[jj] = tempCQS;
}
}
int workNotToDo = 0;
while((workNotToDo<workToDo) && (*compostQueuePointer[workNotToDo]->textureHolder->priority <= 0))
{
// do something with prio 0 one's
EraseCompostQueueFlag(compostQueuePointer[workNotToDo]->done);
workNotToDo++;
}
Set_Statistic(Number_Of_Worked_On_Textures, workToDo-workNotToDo);
if(workToDo-workNotToDo <= 0)
{
return;
}
int advanceInQueue = 1;
if(workToDo-workNotToDo > 32)
{
advanceInQueue = 4;
}
else if(workToDo-workNotToDo > 16)
{
advanceInQueue = 2;
}
else
{
advanceInQueue = 1;
}
for(i=workToDo-1,j=0;(i>=0)&&(j<advanceInQueue)&&(i>=workNotToDo);i--)
{
if(compostQueuePointer[i]->textureHolder->lastLine < 256)
{
Verify(compostQueuePointer[i]->textureHolder->pix_dest != NULL);
compostQueuePointer[i]->Compose();
}
else
{
int index = compostQueuePointer[i]->textureHolder->textureHandle;
if(index>0)
{
MLRTexture *texture = (*MidLevelRenderer::MLRTexturePool::Instance)[index];
GOSImage *image = texture->GetImage();
#ifdef LAB_ONLY
static char str[128];
sprintf(str, "l:%d r:%d c:%d",
compostQueuePointer[i]->downSample ? 2 : 3,
compostQueuePointer[i]->row,
compostQueuePointer[i]->column
);
Check_Object(image);
gos_SetTextureName(image->GetHandle(), str);
#ifdef HUNT_FOR_THE_RED_TILE
SPEWALWAYS((HUNT_FOR_THE_RED_TILE, "%s", str));
#endif
#endif
image->UnlockImage();
}
compostQueuePointer[i]->textureHolder->flags = TextureHolder::Done;
if(compostQueuePointer[i]->textureHolder->aelp!=NULL)
{
compostQueuePointer[i]->textureHolder->aelp_ptr = compostQueuePointer[i]->textureHolder->aelp;
while(compostQueuePointer[i]->textureHolder->aelp_ptr->next!=NULL)
{
compostQueuePointer[i]->textureHolder->aelp_ptr = compostQueuePointer[i]->textureHolder->aelp_ptr->next;
}
while(compostQueuePointer[i]->textureHolder->aelp_ptr->prev!=NULL)
{
compostQueuePointer[i]->textureHolder->taelp = compostQueuePointer[i]->textureHolder->aelp_ptr->prev;
Unregister_Pointer(compostQueuePointer[i]->textureHolder->aelp_ptr);
delete compostQueuePointer[i]->textureHolder->aelp_ptr;
compostQueuePointer[i]->textureHolder->aelp_ptr = compostQueuePointer[i]->textureHolder->taelp;
compostQueuePointer[i]->textureHolder->aelp_ptr->next = NULL;
}
Unregister_Pointer(compostQueuePointer[i]->textureHolder->aelp_ptr);
delete compostQueuePointer[i]->textureHolder->aelp_ptr;
compostQueuePointer[i]->textureHolder->aelp_ptr = NULL;
}
EraseCompostQueueFlag(compostQueuePointer[i]->done);
}
}
#else
// let compose a bit
int advanceInQueue = 1;
if(lastInQueue+flipAround*Length_Of_Compost_Queue - firstInQueue > 32)
{
advanceInQueue = 4;
}
else if(lastInQueue+flipAround*Length_Of_Compost_Queue - firstInQueue > 16)
{
advanceInQueue = 2;
}
else
{
advanceInQueue = 1;
}
// SPEW(("micgaert", "%d %d", firstInQueue, lastInQueue));
if(firstInQueue < lastInQueue+flipAround*Length_Of_Compost_Queue)
{
while(compostQueue[firstInQueue].done==true)
{
firstInQueue++;
if(firstInQueue>=Length_Of_Compost_Queue)
{
firstInQueue = 0;
flipAround--;
}
if(firstInQueue>=lastInQueue+flipAround*Length_Of_Compost_Queue)
{
break;
}
}
}
int i, j, k;
i = k = firstInQueue;
j = firstInQueue+advanceInQueue;
for(;i<j;i++)
{
if(k>=lastInQueue+flipAround*Length_Of_Compost_Queue)
{
break;
}
if(*compostQueue[k].textureHolder->priority>0)
{
if(compostQueue[k].textureHolder->lastLine < 256)
{
compostQueue[k].Compose();
}
else
{
int index = compostQueue[k].textureHolder->textureHandle;
if(index>0)
{
MLRTexture *texture = (*MidLevelRenderer::MLRTexturePool::Instance)[index];
GOSImage *image = texture->GetImage();
#ifdef LAB_ONLY
static char str[128];
sprintf(str, "l:%d r:%d c:%d",
compostQueuePointer[i]->downSample ? 2 : 3,
compostQueuePointer[i]->row,
compostQueuePointer[i]->column
);
Check_Object(image);
gos_SetTextureName(image->GetHandle(), str);
#ifdef HUNT_FOR_THE_RED_TILE
SPEWALWAYS((HUNT_FOR_THE_RED_TILE, "%s", str));
#endif
#endif
image->UnlockImage();
}
compostQueue[k].textureHolder->flags = TextureHolder::Done;
if(compostQueue[k].textureHolder->aelp!=NULL)
{
compostQueue[k].textureHolder->aelp_ptr = compostQueue[k].textureHolder->aelp;
while(compostQueue[k].textureHolder->aelp_ptr->next!=NULL)
{
compostQueue[k].textureHolder->aelp_ptr = compostQueue[k].textureHolder->aelp_ptr->next;
}
while(compostQueue[k].textureHolder->aelp_ptr->prev!=NULL)
{
compostQueue[k].textureHolder->taelp = compostQueue[k].textureHolder->aelp_ptr->prev;
Unregister_Pointer(compostQueue[k].textureHolder->aelp_ptr);
delete compostQueue[k].textureHolder->aelp_ptr;
compostQueue[k].textureHolder->aelp_ptr = compostQueue[k].textureHolder->taelp;
compostQueue[k].textureHolder->aelp_ptr->next = NULL;
}
Unregister_Pointer(compostQueue[k].textureHolder->aelp_ptr);
delete compostQueue[k].textureHolder->aelp_ptr;
compostQueue[k].textureHolder->aelp_ptr = NULL;
}
compostQueue[k].done = true;
if(firstInQueue>=Length_Of_Compost_Queue)
{
firstInQueue = 0;
flipAround--;
}
}
}
else
{
compostQueue[k].done = true;
}
if(++k>=Length_Of_Compost_Queue)
{
k = 0;
}
}
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
CompostQueueStruct*
CompostQueue::IsInQueue(int row, int column, int downSample)
{
int i, k;
for(i=firstInQueue,k=firstInQueue;i<lastInQueue+flipAround*Length_Of_Compost_Queue;i++)
{
if( compostQueue[k].row==row &&
compostQueue[k].column==column &&
compostQueue[k].downSample==downSample
)
{
return &compostQueue[k];
}
if(++k>=Length_Of_Compost_Queue)
{
k = 0;
}
}
return NULL;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
TerrainTextureLogistic::TerrainTextureLogistic(
int xg, int zg,
Scalar xl, Scalar zl,
const char *fileName
) : x_grid(xg), z_grid(zg), x_grid_length(xl), z_grid_length(zl)
{
Verify(gos_GetCurrentHeap() == Heap);
Verify(Instance == NULL);
featurePool = new FeaturePool();
Register_Pointer(featurePool);
Stuff::FileStream fstr(fileName);
featurePool->LoadIndex(&fstr);
featureGrid = new FeatureGrid(&fstr, featurePool);
Register_Pointer(featureGrid);
fstr.Close();
int i, j;
terrainMeshes.SetLength(x_grid*z_grid);
textureHolder[0].SetLength(x_grid*z_grid);
textureHolder[1].SetLength(x_grid*z_grid);
if(featureGrid->gridSize > 256)
{
textureHolder[2].SetLength(x_grid*z_grid);
}
resolutionTracker[DesiredResolution].SetLength(x_grid*z_grid);
resolutionTracker[CurrentResolution].SetLength(x_grid*z_grid);
resolutionTracker[Priority].SetLength(x_grid*z_grid);
resolutionTracker[DirtyFlag].SetLength(x_grid*z_grid);
for(i=0;i<x_grid*z_grid;i++)
{
terrainMeshes[i].SetLength(0);
resolutionTracker[CurrentResolution][i] = 0;
resolutionTracker[Priority][i] = 0;
resolutionTracker[DirtyFlag][i] = 0;
textureHolder[0][i].priority = &resolutionTracker[Priority][i];
textureHolder[1][i].priority = &resolutionTracker[Priority][i];
}
int endres = featureGrid->gridSize > 256 ? 5 : 4;
for(j=2;j<endres;j++)
{
nrOfAllocatedTexture[j] = (unsigned char)((Number_Of_Reserved_Textures/8) << (5-j));
nrOfUsedTextures[j] = 0;
firstUnusedTexture[j] = 0;
// SPEWALWAYS((0, "%d true", j));
textureAvailable[j] = true;
textures[j].SetLength(nrOfAllocatedTexture[j]);
textureFlags[j].SetLength(nrOfAllocatedTexture[j]);
char str[256];
for(i=0;i<nrOfAllocatedTexture[j];i++)
{
sprintf(str, "tex_%1d_%03d", j, i);
DWORD hints =
// gosHint_DisableMipmap |
// gosHint_UserMipMaps |
gosHint_AGPMemory;
textures[j][i] = MLRTexturePool::Instance->Add(str, gos_Texture_Solid, 32<<j, (gos_TextureHints)hints);
textureFlags[j][i] = 0;
}
}
Verify(x_grid == featureGrid->GetColumns());
Verify(z_grid == featureGrid->GetRows());
#ifdef LAB_ONLY
borderKey = false;
borderColor = 0;
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
TerrainTextureLogistic::TerrainTextureLogistic(
int xg, int zg,
Scalar xl, Scalar zl,
Stuff::MemoryStream *stream
) : x_grid(xg), z_grid(zg), x_grid_length(xl), z_grid_length(zl)
{
Verify(gos_GetCurrentHeap() == Heap);
Verify(Instance == NULL);
#ifdef THE03HACK
x_grid *= 2;
z_grid *= 2;
x_grid_length /= 2.0f;
z_grid_length /= 2.0f;
#endif
featurePool = new FeaturePool();
Register_Pointer(featurePool);
featurePool->LoadIndex(stream);
featureGrid = new FeatureGrid(stream, featurePool);
Register_Pointer(featureGrid);
Verify(x_grid == featureGrid->GetColumns());
Verify(z_grid == featureGrid->GetRows());
int i, j;
terrainMeshes.SetLength(x_grid*z_grid);
textureHolder[0].SetLength(x_grid*z_grid);
textureHolder[1].SetLength(x_grid*z_grid);
if(featureGrid->gridSize > 256)
{
textureHolder[2].SetLength(x_grid*z_grid);
}
resolutionTracker[DesiredResolution].SetLength(x_grid*z_grid);
resolutionTracker[CurrentResolution].SetLength(x_grid*z_grid);
resolutionTracker[Priority].SetLength(x_grid*z_grid);
resolutionTracker[DirtyFlag].SetLength(x_grid*z_grid);
for(i=0;i<x_grid*z_grid;i++)
{
terrainMeshes[i].SetLength(0);
resolutionTracker[CurrentResolution][i] = 0;
resolutionTracker[Priority][i] = 0;
resolutionTracker[DirtyFlag][i] = 0;
textureHolder[0][i].priority = &resolutionTracker[Priority][i];
textureHolder[1][i].priority = &resolutionTracker[Priority][i];
}
int endres = featureGrid->gridSize > 256 ? 5 : 4;
for(j=2;j<endres;j++)
{
nrOfAllocatedTexture[j] = (unsigned char)((Number_Of_Reserved_Textures/8) << (5-j));
nrOfUsedTextures[j] = 0;
firstUnusedTexture[j] = 0;
// SPEWALWAYS((0, "%d true", j));
textureAvailable[j] = true;
textures[j].SetLength(nrOfAllocatedTexture[j]);
textureFlags[j].SetLength(nrOfAllocatedTexture[j]);
gos_PushCurrentHeap(MidLevelRenderer::TexturePoolHeap);
char str[256];
for(i=0;i<nrOfAllocatedTexture[j];i++)
{
sprintf(str, "image_%1d_%03d", j, i);
DWORD hints =
// gosHint_DisableMipmap |
// gosHint_UserMipMaps |
gosHint_AGPMemory | gosHint_DontShrink;
textures[j][i] = MLRTexturePool::Instance->Add(str, gos_Texture_Solid, 32<<j, (gos_TextureHints)hints);
textureFlags[j][i] = 0;
}
gos_PopCurrentHeap();
}
#ifdef LAB_ONLY
borderKey = false;
borderColor = 0;
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
TerrainTextureLogistic::TerrainTextureLogistic(
int xg, int zg,
Scalar xl, Scalar zl,
Stuff::NotationFile *notation
) : x_grid(xg), z_grid(zg), x_grid_length(xl), z_grid_length(zl)
{
Verify(gos_GetCurrentHeap() == Heap);
Verify(Instance == NULL);
#ifdef THE03HACK
x_grid *= 2;
z_grid *= 2;
x_grid_length /= 2.0f;
z_grid_length /= 2.0f;
#endif
featurePool = new FeaturePool();
Register_Pointer(featurePool);
featurePool->LoadIndex(notation);
featureGrid = new FeatureGrid(notation, featurePool);
Register_Pointer(featureGrid);
Verify(x_grid == featureGrid->GetColumns());
Verify(z_grid == featureGrid->GetRows());
int i, j;
terrainMeshes.SetLength(x_grid*z_grid);
textureHolder[0].SetLength(x_grid*z_grid);
textureHolder[1].SetLength(x_grid*z_grid);
if(featureGrid->gridSize > 256)
{
textureHolder[2].SetLength(x_grid*z_grid);
}
resolutionTracker[DesiredResolution].SetLength(x_grid*z_grid);
resolutionTracker[CurrentResolution].SetLength(x_grid*z_grid);
resolutionTracker[Priority].SetLength(x_grid*z_grid);
resolutionTracker[DirtyFlag].SetLength(x_grid*z_grid);
for(i=0;i<x_grid*z_grid;i++)
{
terrainMeshes[i].SetLength(0);
resolutionTracker[CurrentResolution][i] = 0;
resolutionTracker[Priority][i] = 0;
resolutionTracker[DirtyFlag][i] = 0;
textureHolder[0][i].priority = &resolutionTracker[Priority][i];
textureHolder[1][i].priority = &resolutionTracker[Priority][i];
}
int endres = featureGrid->gridSize > 256 ? 5 : 4;
for(j=2;j<endres;j++)
{
nrOfAllocatedTexture[j] = (unsigned char)((Number_Of_Reserved_Textures/8) << (5-j));
nrOfUsedTextures[j] = 0;
firstUnusedTexture[j] = 0;
// SPEWALWAYS((0, "%d true", j));
textureAvailable[j] = true;
textures[j].SetLength(nrOfAllocatedTexture[j]);
textureFlags[j].SetLength(nrOfAllocatedTexture[j]);
gos_PushCurrentHeap(MidLevelRenderer::TexturePoolHeap);
char str[256];
for(i=0;i<nrOfAllocatedTexture[j];i++)
{
sprintf(str, "image_%1d_%03d", j, i);
DWORD hints =
// gosHint_DisableMipmap |
// gosHint_UserMipMaps |
gosHint_AGPMemory | gosHint_DontShrink;
textures[j][i] = MLRTexturePool::Instance->Add(str, gos_Texture_Solid, 32<<j, (gos_TextureHints)hints);
textureFlags[j][i] = 0;
}
gos_PopCurrentHeap();
}
#ifdef LAB_ONLY
borderKey = false;
borderColor = 0;
#endif
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
TerrainTextureLogistic::~TerrainTextureLogistic()
{
int i, j, len = terrainMeshes.GetLength();
//---------------------
// Unlock all textures
//---------------------
GOSImage *image = NULL;
for(j=2;j<4;j++)
{
for(i=0;i<nrOfAllocatedTexture[j];i++)
{
image = textures[j][i]->GetImage();
image->UnlockImage();
}
}
for(i=0;i<len;i++)
{
terrainMeshes[i].SetLength(0);
}
len = textureHolder[0].GetLength();
for(i=0;i<len;i++)
{
if(textureHolder[0][i].lastLine >= 0 && textureHolder[0][i].lastLine < featureGrid->gridSize)
{
// gos_UnLockTexture(textureHolder[0][i].imageHandle);
int index = textureHolder[0][i].textureHandle;
if(index > 0)
{
MLRTexture *texture = (*MidLevelRenderer::MLRTexturePool::Instance)[index];
GOSImage *image = texture->GetImage();
image->flags &= ~GOSImage::Locked;
}
if(textureHolder[0][i].aelp!=NULL)
{
textureHolder[0][i].aelp_ptr = textureHolder[0][i].aelp;
while(textureHolder[0][i].aelp_ptr->next!=NULL)
{
textureHolder[0][i].aelp_ptr = textureHolder[0][i].aelp_ptr->next;
}
while(textureHolder[0][i].aelp_ptr->prev!=NULL)
{
textureHolder[0][i].taelp = textureHolder[0][i].aelp_ptr->prev;
Unregister_Pointer(textureHolder[0][i].aelp_ptr);
delete textureHolder[0][i].aelp_ptr;
textureHolder[0][i].aelp_ptr = textureHolder[0][i].taelp;
textureHolder[0][i].aelp_ptr->next = NULL;
}
Unregister_Pointer(textureHolder[0][i].aelp_ptr);
delete textureHolder[0][i].aelp_ptr;
textureHolder[0][i].aelp_ptr = NULL;
}
}
}
textureHolder[0].SetLength(0);
len = textureHolder[1].GetLength();
for(i=0;i<len;i++)
{
if(textureHolder[1][i].lastLine >= 0 && textureHolder[1][i].lastLine < featureGrid->gridSize)
{
// gos_UnLockTexture(textureHolder[1][i].imageHandle);
int index = textureHolder[1][i].textureHandle;
if(index > 0)
{
MLRTexture *texture = (*MidLevelRenderer::MLRTexturePool::Instance)[textureHolder[1][i].textureHandle];
GOSImage *image = texture->GetImage();
image->flags &= ~GOSImage::Locked;
}
if(textureHolder[1][i].aelp!=NULL)
{
textureHolder[1][i].aelp_ptr = textureHolder[1][i].aelp;
while(textureHolder[1][i].aelp_ptr->next!=NULL)
{
textureHolder[1][i].aelp_ptr = textureHolder[1][i].aelp_ptr->next;
}
while(textureHolder[1][i].aelp_ptr->prev!=NULL)
{
textureHolder[1][i].taelp = textureHolder[1][i].aelp_ptr->prev;
Unregister_Pointer(textureHolder[1][i].aelp_ptr);
delete textureHolder[1][i].aelp_ptr;
textureHolder[1][i].aelp_ptr = textureHolder[1][i].taelp;
textureHolder[1][i].aelp_ptr->next = NULL;
}
Unregister_Pointer(textureHolder[1][i].aelp_ptr);
delete textureHolder[1][i].aelp_ptr;
textureHolder[1][i].aelp_ptr = NULL;
}
}
}
textureHolder[1].SetLength(0);
for(i=0;i<4;i++)
{
textures[i].SetLength(0);
textureFlags[i].SetLength(0);
}
Unregister_Pointer(featureGrid);
delete featureGrid;
Unregister_Pointer(featurePool);
delete featurePool;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
TerrainTextureLogistic::Restart()
{
Verify(gos_GetCurrentHeap() == Heap);
compostQueue.Restart();
int i, j;
terrainMeshes.SetLength(x_grid*z_grid);
j = resolutionTracker[DesiredResolution].GetLength();
for(i=0;i<j;i++)
{
resolutionTracker[DesiredResolution][i] = 0xff;
resolutionTracker[CurrentResolution][i] = 0xff;
resolutionTracker[Priority][i] = 0;
}
int endres = (featureGrid->gridSize > 256 ? 5 : 4) - 2;
for(i=0;i<endres;i++)
{
nrOfUsedTextures[i+2] = 0;
firstUnusedTexture[i+2] = 0;
for(j=0;j<nrOfAllocatedTexture[i+2];j++)
{
textureFlags[i+2][j] = 0;
textureHolder[i][j].ShutDown();
}
}
}
void
ExtractAllMeshes(ElementRenderer::GroupElement*, DynamicArrayOf<MidLevelRenderer::MLR_Terrain2*>&, int&);
void
ExtractAllMeshes(ElementRenderer::ListElement*, DynamicArrayOf<MidLevelRenderer::MLR_Terrain2*>&, int&);
void
ExtractAllMeshes(ElementRenderer::ShapeElement*, DynamicArrayOf<MidLevelRenderer::MLR_Terrain2*>&, int&);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ExtractAllMeshes(ElementRenderer::GroupElement *gelement, DynamicArrayOf<MidLevelRenderer::MLR_Terrain2*>& array, int& count)
{
Stuff::ChainIteratorOf<ElementRenderer::Element*> *gelements = gelement->MakeIterator();
Register_Object(gelements);
ElementRenderer::Element *element = NULL;
while((element = gelements->ReadAndNext())!=NULL)
{
switch(element->GetClassID())
{
case ElementRenderer::GroupElementClassID:
ExtractAllMeshes(Cast_Pointer(ElementRenderer::GroupElement*, element), array, count);
break;
case ElementRenderer::ListElementClassID:
ExtractAllMeshes(Cast_Pointer(ElementRenderer::ListElement*, element), array, count);
break;
case ElementRenderer::ShapeElementClassID:
ExtractAllMeshes(Cast_Pointer(ElementRenderer::ShapeElement*, element), array, count);
break;
}
}
Unregister_Object(gelements);
delete gelements;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ExtractAllMeshes(ElementRenderer::ListElement *lelement, DynamicArrayOf<MidLevelRenderer::MLR_Terrain2*>& array, int& count)
{
WORD i, len = lelement->GetActiveCount();
for(i=0;i<len;i++)
{
ElementRenderer::Element *element = lelement->GetIndexedElement(i);
switch(element->GetClassID())
{
case ElementRenderer::GroupElementClassID:
ExtractAllMeshes(Cast_Pointer(ElementRenderer::GroupElement*, element), array, count);
break;
case ElementRenderer::ListElementClassID:
ExtractAllMeshes(Cast_Pointer(ElementRenderer::ListElement*, element), array, count);
break;
case ElementRenderer::ShapeElementClassID:
ExtractAllMeshes(Cast_Pointer(ElementRenderer::ShapeElement*, element), array, count);
break;
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ExtractAllMeshes(ElementRenderer::ShapeElement *selement, DynamicArrayOf<MidLevelRenderer::MLR_Terrain2*>& array, int& count)
{
MLRShape *shape = selement->GetMLRShape();
int i, len = shape->GetNum();
MidLevelRenderer::MLRPrimitiveBase *mesh = NULL;
for(i=0;i<len;i++)
{
mesh = shape->Find(i);
Check_Object(mesh);
if(mesh->GetClassID() == MidLevelRenderer::MLR_Terrain2ClassID)
{
array[count] = Cast_Pointer(MLR_Terrain2*, mesh);
array[count]->SetDepthData(3, 3);
count++;
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
ExtractAllMeshes(ElementRenderer::Element *element, DynamicArrayOf<MidLevelRenderer::MLR_Terrain2*>& array, int& count)
{
switch(element->GetClassID())
{
case ElementRenderer::GroupElementClassID:
ExtractAllMeshes(Cast_Pointer(ElementRenderer::GroupElement*, element), array, count);
break;
case ElementRenderer::ListElementClassID:
ExtractAllMeshes(Cast_Pointer(ElementRenderer::ListElement*, element), array, count);
break;
case ElementRenderer::ShapeElementClassID:
ExtractAllMeshes(Cast_Pointer(ElementRenderer::ShapeElement*, element), array, count);
break;
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
TerrainTextureLogistic::AttachZone(ElementRenderer::GridElement *grid, BYTE z_off, BYTE x_off)
{
gos_PushCurrentHeap(Heap);
Check_Object(grid);
Check_Pointer(this);
BYTE x_size, z_size;
grid->GetSize(&z_size, &x_size);
#ifdef LAB_ONLY
Scalar xdim, zdim, s1, s2;
grid->GetDimensions(&s1, &s2, &zdim, &xdim);
#ifndef THE03HACK
Verify(xdim==x_grid_length);
Verify(zdim==z_grid_length);
Verify(x_off+x_size<=x_grid);
Verify(z_off+z_size<=z_grid);
#else
Verify(xdim==2*x_grid_length);
Verify(zdim==2*z_grid_length);
Verify(x_off+x_size<=x_grid/2);
Verify(z_off+z_size<=z_grid/2);
#endif
#endif
Adept::Tile *element;
BYTE i, j;
int k, count;
for(j=z_off;j<z_off+z_size;j++)
{
for(i=x_off;i<x_off+x_size;i++)
{
count = 0;
#ifndef THE03HACK
terrainMeshes[j*x_grid + i].SetLength(32);
element = Cast_Pointer(Adept::Tile*, grid->GetIndexedElement(static_cast<BYTE>(j-z_off), static_cast<BYTE>(i-x_off)));
ExtractAllMeshes(element->m_ground, terrainMeshes[j*x_grid + i], count);
terrainMeshes[j*x_grid + i].SetLength(count);
for(k=0;k<count;k++)
{
Check_Object(terrainMeshes[j*x_grid + i][k]);
terrainMeshes[j*x_grid + i][k]->SetCurrentDepth(0);
terrainMeshes[j*x_grid + i][k]->CalculateUVs();
}
#else
terrainMeshes[2*j*x_grid + 2*i].SetLength(32);
element = Cast_Pointer(Adept::Tile*, grid->GetIndexedElement(j-z_off, i-x_off));
ExtractAllMeshes(element->m_ground, terrainMeshes[2*j*x_grid + 2*i], count);
Verify(count==4);
Scalar x0, x1, z0, z1;
x0 = terrainMeshes[2*j*x_grid + 2*i][0]->GetFrame(2, 0);
z0 = terrainMeshes[2*j*x_grid + 2*i][0]->GetFrame(2, 1);
x1 = terrainMeshes[2*j*x_grid + 2*i][0]->GetFrame(2, 2);
z1 = terrainMeshes[2*j*x_grid + 2*i][0]->GetFrame(2, 3);
Verify(xdim == x1 - x0);
Verify(zdim == z1 - z0);
#ifdef _ARMOR
for(k=0;k<4;k++)
{
for(int l=2;l<8;l++)
{
Verify(x0 == terrainMeshes[2*j*x_grid + 2*i][k]->GetFrame(l, 0));
Verify(z0 == terrainMeshes[2*j*x_grid + 2*i][k]->GetFrame(l, 1));
Verify(x1 == terrainMeshes[2*j*x_grid + 2*i][k]->GetFrame(l, 2));
Verify(z1 == terrainMeshes[2*j*x_grid + 2*i][k]->GetFrame(l, 3));
}
SPEW(("micgaert", "%d %d %d %x", i, j, k, (int)&terrainMeshes[2*j*x_grid + 2*i][k]));
}
#endif
Stuff::ExtentBox box;
terrainMeshes[2*j*x_grid + 2*i + 1].SetLength(1);
terrainMeshes[2*j*x_grid + 2*i + 1][0] = terrainMeshes[2*j*x_grid + 2*i][1];
terrainMeshes[2*j*x_grid + 2*i + 1][0]->GetExtend(&box);
Verify(box.minX>=x0+x_grid_length);
Verify(box.maxX<=x1);
Verify(box.minZ>=z0);
Verify(box.maxZ<=z0+z_grid_length);
for(k=2;k<8;k++)
{
terrainMeshes[2*j*x_grid + 2*i + 1][0]->SetFrame(k, x0+x_grid_length, z0, x1, z0+z_grid_length);
}
terrainMeshes[2*j*x_grid + 2*i + 1][0]->SetCurrentDepth(0);
terrainMeshes[2*j*x_grid + 2*i + 1][0]->CalculateUVs();
terrainMeshes[(2*j+1)*x_grid + 2*i].SetLength(1);
terrainMeshes[(2*j+1)*x_grid + 2*i][0] = terrainMeshes[2*j*x_grid + 2*i][2];
terrainMeshes[(2*j+1)*x_grid + 2*i][0]->GetExtend(&box);
Verify(box.minX>=x0);
Verify(box.maxX<=x0+x_grid_length);
Verify(box.minZ>=z0+x_grid_length);
Verify(box.maxZ<=z1);
for(k=2;k<8;k++)
{
terrainMeshes[(2*j+1)*x_grid + 2*i][0]->SetFrame(k, x0, z0+z_grid_length, x0+x_grid_length, z1);
}
terrainMeshes[(2*j+1)*x_grid + 2*i][0]->SetCurrentDepth(0);
terrainMeshes[(2*j+1)*x_grid + 2*i][0]->CalculateUVs();
terrainMeshes[(2*j+1)*x_grid + 2*i + 1].SetLength(1);
terrainMeshes[(2*j+1)*x_grid + 2*i + 1][0] = terrainMeshes[2*j*x_grid + 2*i][3];
terrainMeshes[(2*j+1)*x_grid + 2*i + 1][0]->GetExtend(&box);
Verify(box.minX>=x0+x_grid_length);
Verify(box.maxX<=x1);
Verify(box.minZ>=z0+z_grid_length);
Verify(box.maxZ<=z1);
for(k=2;k<8;k++)
{
terrainMeshes[(2*j+1)*x_grid + 2*i + 1][0]->SetFrame(k, x0+x_grid_length, z0+z_grid_length, x1, z1);
}
terrainMeshes[(2*j+1)*x_grid + 2*i + 1][0]->SetCurrentDepth(0);
terrainMeshes[(2*j+1)*x_grid + 2*i + 1][0]->CalculateUVs();
terrainMeshes[2*j*x_grid + 2*i][0] = terrainMeshes[2*j*x_grid + 2*i][0];
terrainMeshes[2*j*x_grid + 2*i].SetLength(1);
terrainMeshes[2*j*x_grid + 2*i][0]->GetExtend(&box);
Verify(box.minX>=x0);
Verify(box.maxX<=x0+x_grid_length);
Verify(box.minZ>=z0);
Verify(box.maxZ<=z0+z_grid_length);
for(k=2;k<8;k++)
{
terrainMeshes[2*j*x_grid + 2*i][0]->SetFrame(k, x0, z0, x0+x_grid_length, z0+z_grid_length);
}
terrainMeshes[2*j*x_grid + 2*i][0]->SetCurrentDepth(0);
terrainMeshes[2*j*x_grid + 2*i][0]->CalculateUVs();
#endif
}
}
gos_PopCurrentHeap();
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
TerrainTextureLogistic::DetachMeshes(int z_off, int x_off, int z_size, int x_size)
{
Check_Pointer(this);
int i, j;
Verify(x_off+x_size<=x_grid);
Verify(z_off+z_size<=z_grid);
for(j=z_off;j<z_off+z_size;j++)
{
for(i=x_off;i<x_off+x_size;i++)
{
terrainMeshes[j*x_grid + i].SetLength(0);
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
TerrainTextureLogistic::NextUnusedTexture(int res, int lastUnused)
{
textureFlags[res][lastUnused] |= 1;
unsigned char i;
for(i=0;i<nrOfAllocatedTexture[res];i++)
{
if(!(textureFlags[res][i] & 1))
{
firstUnusedTexture[res] = i;
// SPEWALWAYS((0, "%d true, %d", res, i));
textureAvailable[res] = true;
return;
}
}
// SPEWALWAYS((0, "%d false, %d", res, nrOfAllocatedTexture[res]));
textureAvailable[res] = false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
TerrainTextureLogistic::FreeUsedTexture(int res, int lastUsed)
{
textureFlags[res][lastUsed] &= ~1;
unsigned char i;
for(i=0;i<nrOfAllocatedTexture[res];i++)
{
if(!(textureFlags[res][i] & 1))
{
firstUnusedTexture[res] = i;
// SPEWALWAYS((0, "%d true, %d", res, i));
textureAvailable[res] = true;
return;
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
bool
TerrainTextureLogistic::AddFeature(int index, Scalar x, Scalar z, int scale)
{
Feature *feature = featurePool->GetFeature(index);
if(feature==NULL)
{
return false;
}
int xg = (int)( ((x_grid*x_grid_length-(x-x_offset))*256.0f)/x_grid_length);
int zg = (int)( ((z_grid*z_grid_length-(z-z_offset))*256.0f)/z_grid_length);
xg -= feature->GetFeatureWidth()/2;
zg -= feature->GetFeatureHeight()/2;
xg &= ~3;
zg &= ~3;
gos_PushCurrentHeap(Compost::Heap);
featureGrid->Add( feature, (WORD)xg, (WORD)zg );
gos_PopCurrentHeap();
compostQueue.Restart();
int i, j, r_start, r_end, c_start, c_end;
r_start = zg>>featureGrid->GetGridShift();
r_start = r_start<0 ? 0 : r_start;
r_end = ((zg+feature->GetFeatureHeight())>>featureGrid->GetGridShift())+1;
r_end = r_end>featureGrid->GetRows() ? featureGrid->GetRows() : r_end;
c_start = xg>>featureGrid->GetGridShift();
c_start = c_start<0 ? 0 : c_start;
c_end = ((xg+feature->GetFeatureWidth())>>featureGrid->GetGridShift())+1;
c_end = c_end>featureGrid->GetColumns() ? featureGrid->GetColumns() : c_end;
for(j=r_start;j<r_end;j++)
{
for(i=c_start;i<c_end;i++)
{
// mark tiles as dirty
int offset = (z_grid-j-1)*x_grid + (x_grid-i-1);
resolutionTracker[CurrentResolution][offset] = 0;
resolutionTracker[DirtyFlag][offset] = 1;
// textureHolder[1][offset].textureHandle = -1;
// textureHolder[0][offset].textureHandle = -1;
}
}
return false;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//
void
TerrainTextureLogistic::SetNewPosition(
const Stuff::LinearMatrix4D *now,
const Stuff::LinearMatrix4D *soon,
const Stuff::LinearMatrix4D *later
)
{
Check_Object(now);
if(soon!=NULL)
{
Check_Object(soon);
}
if(later!=NULL)
{
Check_Object(later);
}
static LinearMatrix4D lastPosition = LinearMatrix4D::Identity;
static double lastTime = -1.0;
double nowTime = gos_GetElapsedTime();
Point3D gridLoc = Point3D::Identity, loc = Point3D::Identity, diff = Point3D::Identity;
UnitVector3D forward;
loc = *now;
now->GetLocalForwardInWorld(&forward);
// int column = (int)floor(loc.x/x_grid_length);
// int row = (int)floor(loc.z/z_grid_length);
// lets find out what we really want for a resolution
int i, j, k, d, len;
Scalar squaredDistance, dot;
int count[5] = {0, 0, 0, 0, 0};
for(j=0;j<z_grid;j++)
{
for(i=0;i<x_grid;i++)
{
gridLoc.x = (i+0.5f)*x_grid_length + x_offset;
gridLoc.y = 0.0f;
gridLoc.z = (j+0.5f)*z_grid_length + z_offset;
diff.Subtract(gridLoc, loc);
squaredDistance = diff.GetLengthSquared();
dot = diff*forward;
dot *= 2.0f*static_cast<Scalar>(fabs(dot));
resolutionTracker[Priority][j*x_grid + i] = BasePriority;
Scalar stretch = 1.0f;
if(dot>squaredDistance)
{
resolutionTracker[Priority][j*x_grid + i] += 4;
} else if(dot>0.0f)
{
resolutionTracker[Priority][j*x_grid + i] += 2;
} else if(dot>-squaredDistance)
{
resolutionTracker[Priority][j*x_grid + i] -= 2;
}
else
{
resolutionTracker[Priority][j*x_grid + i] -= 4;
}
if(squaredDistance < 10000.f*stretch)
{
resolutionTracker[DesiredResolution][j*x_grid + i] = 4;
count[4]++;
} else if(squaredDistance < 55000.f*stretch)
{
resolutionTracker[DesiredResolution][j*x_grid + i] = 3;
count[3]++;
} else if(squaredDistance < 300000.f*stretch)
{
resolutionTracker[DesiredResolution][j*x_grid + i] = 2;
count[2]++;
} else if(squaredDistance < 1440000.f*stretch)
{
resolutionTracker[DesiredResolution][j*x_grid + i] = 1;
count[1]++;
} else {
resolutionTracker[DesiredResolution][j*x_grid + i] = 0;
count[0]++;
}
}
#if 0
SPEW(("micgaert", "%3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) %3x(%1d) ",
resolutionTracker[Priority][j*x_grid + 0], resolutionTracker[DesiredResolution][j*x_grid + 0],
resolutionTracker[Priority][j*x_grid + 1], resolutionTracker[DesiredResolution][j*x_grid + 1],
resolutionTracker[Priority][j*x_grid + 2], resolutionTracker[DesiredResolution][j*x_grid + 2],
resolutionTracker[Priority][j*x_grid + 3], resolutionTracker[DesiredResolution][j*x_grid + 3],
resolutionTracker[Priority][j*x_grid + 4], resolutionTracker[DesiredResolution][j*x_grid + 4],
resolutionTracker[Priority][j*x_grid + 5], resolutionTracker[DesiredResolution][j*x_grid + 5],
resolutionTracker[Priority][j*x_grid + 6], resolutionTracker[DesiredResolution][j*x_grid + 6],
resolutionTracker[Priority][j*x_grid + 7], resolutionTracker[DesiredResolution][j*x_grid + 7],
resolutionTracker[Priority][j*x_grid + 8], resolutionTracker[DesiredResolution][j*x_grid + 8],
resolutionTracker[Priority][j*x_grid + 9], resolutionTracker[DesiredResolution][j*x_grid + 9],
resolutionTracker[Priority][j*x_grid + 10], resolutionTracker[DesiredResolution][j*x_grid + 10],
resolutionTracker[Priority][j*x_grid + 11], resolutionTracker[DesiredResolution][j*x_grid + 11],
resolutionTracker[Priority][j*x_grid + 12], resolutionTracker[DesiredResolution][j*x_grid + 12],
resolutionTracker[Priority][j*x_grid + 13], resolutionTracker[DesiredResolution][j*x_grid + 13],
resolutionTracker[Priority][j*x_grid + 14], resolutionTracker[DesiredResolution][j*x_grid + 14],
resolutionTracker[Priority][j*x_grid + 15], resolutionTracker[DesiredResolution][j*x_grid + 15],
resolutionTracker[Priority][j*x_grid + 16], resolutionTracker[DesiredResolution][j*x_grid + 16],
resolutionTracker[Priority][j*x_grid + 17], resolutionTracker[DesiredResolution][j*x_grid + 17],
resolutionTracker[Priority][j*x_grid + 18], resolutionTracker[DesiredResolution][j*x_grid + 18],
resolutionTracker[Priority][j*x_grid + 19], resolutionTracker[DesiredResolution][j*x_grid + 19],
resolutionTracker[Priority][j*x_grid + 20], resolutionTracker[DesiredResolution][j*x_grid + 20],
resolutionTracker[Priority][j*x_grid + 21], resolutionTracker[DesiredResolution][j*x_grid + 21],
resolutionTracker[Priority][j*x_grid + 22], resolutionTracker[DesiredResolution][j*x_grid + 22],
resolutionTracker[Priority][j*x_grid + 23], resolutionTracker[DesiredResolution][j*x_grid + 23],
resolutionTracker[Priority][j*x_grid + 24], resolutionTracker[DesiredResolution][j*x_grid + 24],
resolutionTracker[Priority][j*x_grid + 25], resolutionTracker[DesiredResolution][j*x_grid + 25],
resolutionTracker[Priority][j*x_grid + 26], resolutionTracker[DesiredResolution][j*x_grid + 26],
resolutionTracker[Priority][j*x_grid + 27], resolutionTracker[DesiredResolution][j*x_grid + 27],
resolutionTracker[Priority][j*x_grid + 28], resolutionTracker[DesiredResolution][j*x_grid + 28],
resolutionTracker[Priority][j*x_grid + 29], resolutionTracker[DesiredResolution][j*x_grid + 29],
resolutionTracker[Priority][j*x_grid + 30], resolutionTracker[DesiredResolution][j*x_grid + 30],
resolutionTracker[Priority][j*x_grid + 31], resolutionTracker[DesiredResolution][j*x_grid + 31]
));
#endif
}
// SPEW(("micgaert", "\n"));
// SPEW(("micgaert", "%d %d %d %d %d", count[0], count[1], count[2], count[3], count[4]));
// lets see what we can do about it
for(j=0;j<z_grid;j++)
{
for(i=0;i<x_grid;i++)
{
int offset = j*x_grid + i;
len = terrainMeshes[offset].GetLength();
d = 0;
int res = resolutionTracker[DesiredResolution][offset] > terrainTextureResolution ? terrainTextureResolution : resolutionTracker[DesiredResolution][offset];
while(res>1 && textureAvailable[res]==false)
{
// SPEWALWAYS((0, "%d down", res));
res--;
}
switch(res)
{
case 3:
{
if(resolutionTracker[CurrentResolution][offset] !=3)
{
if(textureHolder[1][offset].textureHandle < 0)
{
textureHolder[1][offset].handle = firstUnusedTexture[3];
textureHolder[1][offset].textureHandle = textures[3][firstUnusedTexture[3]]->GetTextureHandle();
MLRTexture *texture = (*MidLevelRenderer::MLRTexturePool::Instance)[textureHolder[1][offset].textureHandle];
GOSImage *image = texture->GetImage();
textureHolder[1][offset].linesToProcess = 16;
#ifdef LAB_ONLY
textureHolder[1][offset].borderKey = borderKey;
textureHolder[1][offset].borderColor = borderColor;
#endif
image->LockImage();
textureHolder[1][offset].lastLine = -1;
textureHolder[1][offset].aelp = NULL;
textureHolder[1][offset].aelp_ptr = NULL;
textureHolder[1][offset].taelp = NULL;
textureHolder[1][offset].pix_dest = image->GetImagePtr();
textureHolder[1][offset].pitch = image->GetPitch();
compostQueue.SetCompostQueue(
featureGrid,
z_grid-j-1,
x_grid-i-1,
&textureHolder[1][offset],
0,
0
);
NextUnusedTexture(3, firstUnusedTexture[3]);
}
else
{
if(textureHolder[1][offset].lastLine >= featureGrid->gridSize && textureHolder[1][offset].flags == TextureHolder::Done)
{
textureHolder[1][offset].flags = TextureHolder::Free;
if(resolutionTracker[DirtyFlag][offset] > 0)
{
MLRTexture *texture = (*MidLevelRenderer::MLRTexturePool::Instance)[textureHolder[1][offset].textureHandle];
GOSImage *image = texture->GetImage();
textureHolder[1][offset].linesToProcess = 16;
#ifdef LAB_ONLY
textureHolder[1][offset].borderKey = borderKey;
textureHolder[1][offset].borderColor = borderColor;
#endif
image->LockImage();
textureHolder[1][offset].lastLine = -1;
textureHolder[1][offset].aelp = NULL;
textureHolder[1][offset].aelp_ptr = NULL;
textureHolder[1][offset].taelp = NULL;
textureHolder[1][offset].pix_dest = image->GetImagePtr();
textureHolder[1][offset].pitch = image->GetPitch();
compostQueue.SetCompostQueue(
featureGrid,
z_grid-j-1,
x_grid-i-1,
&textureHolder[1][offset],
0,
0
);
resolutionTracker[DirtyFlag][offset] = 0;
}
else
{
#if defined(LAB_ONLY) && defined(HUNT_FOR_THE_RED_TILE)
MLRTexture *tex = (*MLRTexturePool::Instance)[textureHolder[1][offset].textureHandle];
GOSImage *image = tex->GetImage();
const char *tex_name = gos_GetTextureName(image->GetHandle());
int lev, tX, tZ;
sscanf(tex_name, "l:%d r:%d c:%d", &lev, &tZ, &tX);
if(lev!=3 || tZ!=(z_grid-j-1) || tX!=(x_grid-i-1))
{
SPEWALWAYS((HUNT_FOR_THE_RED_TILE, "l:%d r:%d c:%d - %s", 3, z_grid-j-1, x_grid-i-1, tex_name));
}
else
{
SPEWALWAYS((HUNT_FOR_THE_RED_TILE, "l:%d r:%d c:%d - Y", 3, z_grid-j-1, x_grid-i-1));
}
#endif
for(k=0;k<len;k++)
{
// get here composed texture
#if defined(LAB_ONLY) && defined(HUNT_FOR_THE_RED_TILE)
BYTE itX, itZ;
terrainMeshes[offset][k]->GetTileData(itX, itZ);
if((tZ&0x7)!=(7-itZ) || (tX&0x7)!=(7-itX))
{
SPEWALWAYS((HUNT_FOR_THE_RED_TILE, "k:%d l:%d r:%d c:%d - N %d %d", k, 3, z_grid-j-1, x_grid-i-1, (7-itZ), (7-itX)));
}
else
{
SPEWALWAYS((HUNT_FOR_THE_RED_TILE, "k:%d l:%d r:%d c:%d - Y", k, 3, z_grid-j-1, x_grid-i-1, tex_name));
}
#endif
terrainMeshes[offset][k]->SetLevelTexture(3, textureHolder[1][offset].textureHandle);
// terrainMeshes[offset][k]->SetBorderPixel(1.0f/256.0f);
terrainMeshes[offset][k]->SetCurrentDepth(3);
}
}
resolutionTracker[CurrentResolution][offset] = 3;
}
else
{
if(resolutionTracker[DirtyFlag][offset] > 0)
{
MLRTexture *texture = (*MidLevelRenderer::MLRTexturePool::Instance)[textureHolder[1][offset].textureHandle];
GOSImage *image = texture->GetImage();
Check_Object(image);
image->LockImage();
if(textureHolder[1][offset].aelp!=NULL)
{
textureHolder[1][offset].aelp_ptr = textureHolder[1][offset].aelp;
while(textureHolder[1][offset].aelp_ptr->next!=NULL)
{
textureHolder[1][offset].aelp_ptr = textureHolder[1][offset].aelp_ptr->next;
}
while(textureHolder[1][offset].aelp_ptr->prev!=NULL)
{
textureHolder[1][offset].taelp = textureHolder[1][offset].aelp_ptr->prev;
Unregister_Pointer(textureHolder[1][offset].aelp_ptr);
delete textureHolder[1][offset].aelp_ptr;
textureHolder[1][offset].aelp_ptr = textureHolder[1][offset].taelp;
textureHolder[1][offset].aelp_ptr->next = NULL;
}
Unregister_Pointer(textureHolder[1][offset].aelp_ptr);
delete textureHolder[1][offset].aelp_ptr;
textureHolder[1][offset].aelp_ptr = NULL;
}
textureHolder[1][offset].flags = TextureHolder::Free;
textureHolder[1][offset].linesToProcess = 16;
#ifdef LAB_ONLY
textureHolder[1][offset].borderKey = borderKey;
textureHolder[1][offset].borderColor = borderColor;
#endif
textureHolder[1][offset].lastLine = -1;
textureHolder[1][offset].aelp = NULL;
textureHolder[1][offset].aelp_ptr = NULL;
textureHolder[1][offset].taelp = NULL;
textureHolder[1][offset].pix_dest = image->GetImagePtr();
textureHolder[1][offset].pitch = image->GetPitch();
compostQueue.SetCompostQueue(
featureGrid,
z_grid-j-1,
x_grid-i-1,
&textureHolder[1][offset],
0,
0
);
resolutionTracker[DirtyFlag][offset] = 0;
}
#ifdef _ARMOR
/* else
{
int ii, jj, kk;
ii = kk = firstInQueue;
jj = lastInQueue+flipAround*Length_Of_Compost_Queue;
// SPEW(("micgaert", "%d %d", firstInQueue, lastInQueue));
if(kk>=lastInQueue+flipAround*Length_Of_Compost_Queue)
{
STOP(("Compost should process tile %d x %d !", i, j));
}
for(;ii<jj;ii++)
{
if(compostQueue[kk].textureHolder == &textureHolder[1][offset])
{
break;
}
if(++kk>=Length_Of_Compost_Queue)
{
kk = 0;
}
}
if(ii>=jj)
{
STOP(("Compost should process tile %d x %d !", i, j));
}
}
*/
#endif
}
}
}
}
break;
case 2:
{
if(resolutionTracker[CurrentResolution][offset]!=2)
{
if(textureHolder[0][offset].textureHandle < 0)
{
textureHolder[0][offset].handle = firstUnusedTexture[2];
textureHolder[0][offset].textureHandle = textures[2][firstUnusedTexture[2]]->GetTextureHandle();
MLRTexture *texture = (*MidLevelRenderer::MLRTexturePool::Instance)[textureHolder[0][offset].textureHandle];
GOSImage *image = texture->GetImage();
textureHolder[0][offset].lastLine = -1;
textureHolder[0][offset].linesToProcess = 32;
#ifdef LAB_ONLY
textureHolder[0][offset].borderKey = borderKey;
textureHolder[0][offset].borderColor = borderColor;
#endif
image->LockImage();
textureHolder[0][offset].aelp = NULL;
textureHolder[0][offset].aelp_ptr = NULL;
textureHolder[0][offset].taelp = NULL;
textureHolder[0][offset].pix_dest = image->GetImagePtr();
textureHolder[0][offset].pitch = image->GetPitch();
compostQueue.SetCompostQueue(
featureGrid,
z_grid-j-1,
x_grid-i-1,
&textureHolder[0][offset],
1,
0
);
NextUnusedTexture(2, firstUnusedTexture[2]);
}
else
{
if(textureHolder[0][offset].lastLine >= featureGrid->gridSize && textureHolder[0][offset].flags == TextureHolder::Done)
{
textureHolder[0][offset].flags = TextureHolder::Free;
if(resolutionTracker[DirtyFlag][offset] > 0)
{
MLRTexture *texture = (*MidLevelRenderer::MLRTexturePool::Instance)[textureHolder[0][offset].textureHandle];
GOSImage *image = texture->GetImage();
textureHolder[0][offset].lastLine = -1;
textureHolder[0][offset].linesToProcess = 32;
#ifdef LAB_ONLY
textureHolder[0][offset].borderKey = borderKey;
textureHolder[0][offset].borderColor = borderColor;
#endif
image->LockImage();
textureHolder[0][offset].aelp = NULL;
textureHolder[0][offset].aelp_ptr = NULL;
textureHolder[0][offset].taelp = NULL;
textureHolder[0][offset].pix_dest = image->GetImagePtr();
textureHolder[0][offset].pitch = image->GetPitch();
compostQueue.SetCompostQueue(
featureGrid,
z_grid-j-1,
x_grid-i-1,
&textureHolder[0][offset],
1,
0
);
}
else
{
#if defined(LAB_ONLY) && defined(HUNT_FOR_THE_RED_TILE)
MLRTexture *tex = (*MLRTexturePool::Instance)[textureHolder[0][offset].textureHandle];
GOSImage *image = tex->GetImage();
const char *tex_name = gos_GetTextureName(image->GetHandle());
int lev, tX, tZ;
sscanf(tex_name, "l:%d r:%d c:%d", &lev, &tZ, &tX);
if(lev!=2 || tZ!=(z_grid-j-1) || tX!=(x_grid-i-1))
{
SPEWALWAYS((HUNT_FOR_THE_RED_TILE, "l:%d r:%d c:%d - %s", 2, z_grid-j-1, x_grid-i-1, tex_name));
}
else
{
SPEWALWAYS((HUNT_FOR_THE_RED_TILE, "l:%d r:%d c:%d - Y", 2, z_grid-j-1, x_grid-i-1));
}
#endif
for(k=0;k<len;k++)
{
// get here composed texture
#if defined(LAB_ONLY) && defined(HUNT_FOR_THE_RED_TILE)
BYTE itX, itZ;
terrainMeshes[offset][k]->GetTileData(itX, itZ);
if((tZ&0x7)!=(7-itZ) || (tX&0x7)!=(7-itX))
{
SPEWALWAYS((HUNT_FOR_THE_RED_TILE, "k:%d l:%d r:%d c:%d - N %d %d", k, 2, z_grid-j-1, x_grid-i-1, (7-itZ), (7-itX)));
}
else
{
SPEWALWAYS((HUNT_FOR_THE_RED_TILE, "k:%d l:%d r:%d c:%d - Y", k, 2, z_grid-j-1, x_grid-i-1, tex_name));
}
#endif
terrainMeshes[offset][k]->SetLevelTexture(3, textureHolder[0][offset].textureHandle);
/*
#ifdef _DEBUG
// Verify(textureHolder[0][offset].
MLRTexture *texture = (*MidLevelRenderer::MLRTexturePool::Instance)[textureHolder[0][offset].textureHandle];
GOSImage *image = texture->GetImage();
int l1, r1, c1;
const char *img_name = gos_GetTextureName(image->GetHandle());
SPEW(("micgaert", "%s", img_name));
if(img_name[0]=='l' && img_name[1]==':')
{
sscanf(img_name, "l:%d r:%d c:%d", &l1, &r1, &c1);
Verify(l1==2);
Verify(r1==z_grid-j-1);
Verify(c1==x_grid-i-1);
}
#endif
*/
// terrainMeshes[offset][k]->SetBorderPixel(0.0f);
terrainMeshes[offset][k]->SetCurrentDepth(3);
}
resolutionTracker[CurrentResolution][offset] = 2;
}
}
else
{
if(resolutionTracker[DirtyFlag][offset] > 0)
{
MLRTexture *texture = (*MidLevelRenderer::MLRTexturePool::Instance)[textureHolder[0][offset].textureHandle];
GOSImage *image = texture->GetImage();
Check_Object(image);
image->LockImage();
if(textureHolder[0][offset].aelp!=NULL)
{
textureHolder[0][offset].aelp_ptr = textureHolder[0][offset].aelp;
while(textureHolder[0][offset].aelp_ptr->next!=NULL)
{
textureHolder[0][offset].aelp_ptr = textureHolder[0][offset].aelp_ptr->next;
}
while(textureHolder[0][offset].aelp_ptr->prev!=NULL)
{
textureHolder[0][offset].taelp = textureHolder[0][offset].aelp_ptr->prev;
Unregister_Pointer(textureHolder[0][offset].aelp_ptr);
delete textureHolder[0][offset].aelp_ptr;
textureHolder[0][offset].aelp_ptr = textureHolder[0][offset].taelp;
textureHolder[0][offset].aelp_ptr->next = NULL;
}
Unregister_Pointer(textureHolder[0][offset].aelp_ptr);
delete textureHolder[0][offset].aelp_ptr;
textureHolder[0][offset].aelp_ptr = NULL;
}
textureHolder[0][offset].flags = TextureHolder::Free;
textureHolder[0][offset].linesToProcess = 16;
#ifdef LAB_ONLY
textureHolder[0][offset].borderKey = borderKey;
textureHolder[0][offset].borderColor = borderColor;
#endif
textureHolder[0][offset].lastLine = -1;
textureHolder[0][offset].aelp = NULL;
textureHolder[0][offset].aelp_ptr = NULL;
textureHolder[0][offset].taelp = NULL;
textureHolder[0][offset].pix_dest = image->GetImagePtr();
textureHolder[0][offset].pitch = image->GetPitch();
compostQueue.SetCompostQueue(
featureGrid,
z_grid-j-1,
x_grid-i-1,
&textureHolder[0][offset],
1,
0
);
resolutionTracker[DirtyFlag][offset] = 0;
}
#ifdef _ARMOR
/* else
{
int ii, jj, kk;
ii = kk = firstInQueue;
jj = lastInQueue+flipAround*Length_Of_Compost_Queue;
// SPEW(("micgaert", "%d %d", firstInQueue, lastInQueue));
if(kk>=lastInQueue+flipAround*Length_Of_Compost_Queue)
{
STOP(("Compost should process tile %d x %d !", i, j));
}
for(;ii<jj;ii++)
{
if(compostQueue[kk].textureHolder == &textureHolder[0][offset])
{
break;
}
if(++kk>=Length_Of_Compost_Queue)
{
kk = 0;
}
}
if(ii>=jj)
{
STOP(("Compost should process tile %d x %d !", i, j));
}
}
*/
#endif
}
}
}
}
break;
case 1:
{
resolutionTracker[Priority][offset] = 0; // not interesting anymore
if(resolutionTracker[CurrentResolution][offset]!=1)
{
for(k=0;k<len;k++)
{
#ifdef BORDERPIXEL
terrainMeshes[j*x_grid + i][k]->SetBorderPixel(0.0f);
#endif
terrainMeshes[j*x_grid + i][k]->SetCurrentDepth(1);
}
resolutionTracker[CurrentResolution][offset] = 1;
}
}
break;
default:
{
resolutionTracker[Priority][offset] = 0; // not interesting anymore
if(resolutionTracker[CurrentResolution][offset]!=0)
{
for(k=0;k<len;k++)
{
#ifdef BORDERPIXEL
terrainMeshes[j*x_grid + i][k]->SetBorderPixel(0.0f);
#endif
terrainMeshes[j*x_grid + i][k]->SetCurrentDepth(0);
}
resolutionTracker[CurrentResolution][offset] = 0;
}
}
break;
}
#if 0
for(k=0;k<len;k++)
{
MLRState state;
state = terrainMeshes[j*x_grid + i][k]->GetReferenceState();
MLRTexture *texture = (*MidLevelRenderer::MLRTexturePool::Instance)[state.GetTextureHandle()];
SPEW(("jmalbert", "%d %d %d %d %s", i, j, resolutionTracker[DesiredResolution][offset], resolutionTracker[CurrentResolution][offset], texture->GetTextureName()));
}
#endif
}
}
#if defined(LAB_ONLY) && defined(HUNT_FOR_THE_RED_TILE)
for(int jj=0;jj<z_grid;jj++)
{
for(int ii=0;ii<x_grid;ii++)
{
int offoff = jj*x_grid + ii;
int lenlen = terrainMeshes[offoff].GetLength();
for(k=0;k<lenlen;k++)
{
MLRTexture *tex = (*MLRTexturePool::Instance)[&terrainMeshes[offoff][k]->GetReferenceState()];
GOSImage *image = tex->GetImage();
const char *tex_name = gos_GetTextureName(image->GetHandle());
int lev, tX, tZ;
if(*tex_name=='l')
{
sscanf(tex_name, "l:%d r:%d c:%d", &lev, &tZ, &tX);
if(tZ!=(z_grid-jj-1) || tX!=(x_grid-ii-1))
{
SPEWALWAYS((HUNT_FOR_THE_RED_TILE, "!r:%d c:%d - %s", z_grid-jj-1, x_grid-ii-1, tex_name));
}
else
{
// SPEWALWAYS((HUNT_FOR_THE_RED_TILE, "l:%d r:%d c:%d - Y", 2, z_grid-j-1, x_grid-i-1));
}
// get here composed texture
BYTE itX, itZ;
terrainMeshes[offoff][k]->GetTileData(itX, itZ);
if((tZ&0x7)!=(7-itZ) || (tX&0x7)!=(7-itX))
{
SPEWALWAYS((HUNT_FOR_THE_RED_TILE, "!k:%d r:%d c:%d - N %d %d", k, z_grid-jj-1, x_grid-ii-1, (7-itZ), (7-itX)));
}
else
{
// SPEWALWAYS((HUNT_FOR_THE_RED_TILE, "k:%d l:%d r:%d c:%d - Y", k, 2, z_grid-j-1, x_grid-i-1, tex_name));
}
}
}
}
}
#endif
compostQueue.DoWork();
// free what we dont need
int subtractor = 1;
if(lastTime > 0.0f)
{
subtractor = (int)(30 * (nowTime-lastTime));
if(subtractor<1)
{
subtractor = 1;
}
}
for(j=0;j<z_grid;j++)
{
for(i=0;i<x_grid;i++)
{
int offset = j*x_grid + i;
if(resolutionTracker[Priority][offset]>0)
{
resolutionTracker[Priority][offset] = (BYTE)(resolutionTracker[Priority][offset] - (subtractor<256 ? subtractor : 255));
}
for(k=0;k<2;k++)
{
if(textureHolder[k][offset].textureHandle>0 && resolutionTracker[Priority][offset]<=0)
{
#if defined(LAB_ONLY) && defined(HUNT_FOR_THE_RED_TILE)
MLRTexture *tex = (*MLRTexturePool::Instance)[textureHolder[k][offset].textureHandle];
GOSImage *image = tex->GetImage();
const char *tex_name = gos_GetTextureName(image->GetHandle());
SPEWALWAYS((HUNT_FOR_THE_RED_TILE, "Free: %s", tex_name));
#endif
FreeUsedTexture(k+2, textureHolder[k][offset].handle);
textureHolder[k][offset].ShutDown();
}
}
if(resolutionTracker[Priority][offset]<=0 && resolutionTracker[CurrentResolution][offset]>1)
{
len = terrainMeshes[offset].GetLength();
for(k=0;k<len;k++)
{
#ifdef BORDERPIXEL
terrainMeshes[offset][k]->SetBorderPixel(0.0f);
#endif
terrainMeshes[offset][k]->SetCurrentDepth(1);
}
resolutionTracker[CurrentResolution][offset] = 1;
}
}
}
#ifdef LAB_ONLY
for(i=0;i<nrOfAllocatedTexture[2];i++)
{
if(textureFlags[2][i] & 1)
{
Number_Of_Used_128_Textures++;
}
}
for(i=0;i<nrOfAllocatedTexture[3];i++)
{
if(textureFlags[3][i] & 1)
{
Number_Of_Used_256_Textures++;
}
}
#endif
lastTime = nowTime;
lastPosition = *now;
}