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.
2154 lines
59 KiB
C++
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;
|
|
}
|