You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
157 lines
3.9 KiB
157 lines
3.9 KiB
//----------------------------------------------------------------------------
|
|
//
|
|
// rampmap.cpp
|
|
//
|
|
// Implements required RLDDI stuff for rampmaps.
|
|
//
|
|
// Copyright (C) Microsoft Corporation, 1997.
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#include "pch.cpp"
|
|
#pragma hdrstop
|
|
|
|
static RLDDIRamp* NewRamp(int base, int size);
|
|
|
|
RLDDIRampmap* RLDDICreateRampmap(RLDDIColormap* cmap)
|
|
{
|
|
RLDDIRampmap* rampmap;
|
|
RLDDIRamp* ramp;
|
|
|
|
if (D3DMalloc((void**) &rampmap, sizeof(RLDDIRampmap)))
|
|
return NULL;
|
|
|
|
CIRCLE_QUEUE_INITIALIZE(&rampmap->free,RLDDIRamp);
|
|
CIRCLE_QUEUE_INITIALIZE(&rampmap->allocated,RLDDIRamp);
|
|
|
|
rampmap->cmap = cmap;
|
|
ramp = NewRamp(0, cmap->size);
|
|
if (ramp == NULL)
|
|
{
|
|
D3DFree(rampmap);
|
|
return NULL;
|
|
}
|
|
CIRCLE_QUEUE_INSERT_ROOT(&rampmap->free, RLDDIRamp, ramp, queue);
|
|
|
|
return rampmap;
|
|
}
|
|
|
|
void RLDDIDestroyRampmap(RLDDIRampmap* rampmap)
|
|
{
|
|
RLDDIRamp* ramp;
|
|
RLDDIRamp* ramp_next;
|
|
|
|
if (!rampmap)
|
|
return ;
|
|
|
|
for (ramp = CIRCLE_QUEUE_FIRST(&rampmap->allocated); ramp;
|
|
ramp = ramp_next)
|
|
{
|
|
ramp_next = CIRCLE_QUEUE_NEXT(&rampmap->allocated,ramp,queue);
|
|
D3DFree(ramp);
|
|
}
|
|
for (ramp = CIRCLE_QUEUE_FIRST(&rampmap->free); ramp;
|
|
ramp = ramp_next)
|
|
{
|
|
ramp_next = CIRCLE_QUEUE_NEXT(&rampmap->free,ramp,queue);
|
|
D3DFree(ramp);
|
|
}
|
|
D3DFree(rampmap);
|
|
}
|
|
|
|
RLDDIRamp* RLDDIRampmapAllocate(RLDDIRampmap* rampmap, int size)
|
|
{
|
|
RLDDIRamp* ramp;
|
|
RLDDIRamp* newramp;
|
|
RLDDIRamp* ramp_next;
|
|
|
|
if (!rampmap)
|
|
return NULL;
|
|
|
|
ramp = CIRCLE_QUEUE_FIRST(&rampmap->free);
|
|
if (!ramp) return NULL;
|
|
|
|
/*
|
|
* cycle thru free rampmaps
|
|
*/
|
|
for (; ramp && ramp->size < size; ramp = ramp_next)
|
|
{
|
|
ramp_next = CIRCLE_QUEUE_NEXT(&rampmap->free,ramp,queue);
|
|
}
|
|
/*
|
|
* if we can't find a large enough ramp give up,
|
|
* should try coalescing but it is non functional
|
|
*/
|
|
if (!ramp || size > ramp->size)
|
|
return NULL;
|
|
|
|
/*
|
|
* Remove the ramp from the freelist and add it to the allocated list.
|
|
*/
|
|
CIRCLE_QUEUE_DELETE(&rampmap->free, ramp, queue);
|
|
CIRCLE_QUEUE_INSERT_ROOT(&rampmap->allocated, RLDDIRamp, ramp, queue);
|
|
ramp->free = FALSE;
|
|
|
|
/*
|
|
* If the size is right, return it.
|
|
*/
|
|
if (size == ramp->size)
|
|
return ramp;
|
|
|
|
/*
|
|
* Otherwise create a new ramp from the unneeded tail of this one and
|
|
* throw it back into the freelist.
|
|
*/
|
|
newramp = NewRamp(ramp->base + size, ramp->size - size);
|
|
ramp->size = size;
|
|
RLDDIRampmapFree(rampmap, newramp);
|
|
|
|
return ramp;
|
|
}
|
|
|
|
void RLDDIRampmapFree(RLDDIRampmap* rampmap, RLDDIRamp* ramp)
|
|
{
|
|
RLDDIRamp* free;
|
|
|
|
if (!rampmap || !ramp)
|
|
return ;
|
|
|
|
DDASSERT(!ramp->free);
|
|
ramp->free = TRUE;
|
|
if (CIRCLE_QUEUE_NEXT(&rampmap->free,ramp,queue))
|
|
{
|
|
CIRCLE_QUEUE_DELETE(&rampmap->allocated, ramp, queue);
|
|
}
|
|
for (free = CIRCLE_QUEUE_FIRST(&rampmap->free); free;
|
|
free = CIRCLE_QUEUE_NEXT(&rampmap->free,free,queue))
|
|
{
|
|
if (free->size > ramp->size)
|
|
{
|
|
/*
|
|
* Add this ramp before the current one.
|
|
*/
|
|
CIRCLE_QUEUE_INSERT_PREVIOUS(&rampmap->free, free, ramp, queue);
|
|
return;
|
|
}
|
|
}
|
|
/*
|
|
* Must be the smallest so far, so add it to the end.
|
|
*/
|
|
CIRCLE_QUEUE_INSERT_END(&rampmap->free, RLDDIRamp, ramp, queue);
|
|
}
|
|
|
|
static RLDDIRamp* NewRamp(int base, int size)
|
|
{
|
|
RLDDIRamp* ramp;
|
|
|
|
if (D3DMalloc((void**) &ramp, sizeof(RLDDIRamp)))
|
|
return NULL;
|
|
|
|
CIRCLE_QUEUE_INITIALIZE_MEMBER(ramp,queue);
|
|
ramp->base = base;
|
|
ramp->size = size;
|
|
ramp->free = FALSE;
|
|
return ramp;
|
|
}
|
|
|
|
|