forked from mirror/OpenTTD
(svn r3017) -NewGRF: Implement sprite group unreferencing and unloading.
This commit is contained in:
70
sprite.c
70
sprite.c
@@ -4,6 +4,7 @@
|
||||
#include "openttd.h"
|
||||
#include "sprite.h"
|
||||
#include "variables.h"
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
SpriteGroup *EvalDeterministicSpriteGroup(const DeterministicSpriteGroup *dsg, int value)
|
||||
@@ -96,3 +97,72 @@ byte RandomizedSpriteGroupTriggeredBits(const RandomizedSpriteGroup *rsg,
|
||||
|
||||
return (rsg->num_groups - 1) << rsg->lowest_randbit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverse a sprite group and release its and its child's memory.
|
||||
* A group is only released if its reference count is zero.
|
||||
* We pass a pointer to a pointer so that the original reference can be set to NULL.
|
||||
* @param group_ptr Pointer to sprite group reference.
|
||||
*/
|
||||
void UnloadSpriteGroup(SpriteGroup **group_ptr)
|
||||
{
|
||||
SpriteGroup *group;
|
||||
int i;
|
||||
|
||||
assert(group_ptr != NULL);
|
||||
assert(*group_ptr != NULL);
|
||||
|
||||
group = *group_ptr;
|
||||
*group_ptr = NULL; // Remove this reference.
|
||||
|
||||
group->ref_count--;
|
||||
if (group->ref_count > 0) {
|
||||
DEBUG(grf, 6)("UnloadSpriteGroup: Group at `%p' (type %d) has %d reference(s) left.", group, group->type, group->ref_count);
|
||||
return; // Still some references left, so don't clear up.
|
||||
}
|
||||
|
||||
DEBUG(grf, 6)("UnloadSpriteGroup: Releasing group at `%p'.", group);
|
||||
switch (group->type) {
|
||||
case SGT_REAL:
|
||||
{
|
||||
RealSpriteGroup *rsg = &group->g.real;
|
||||
for (i = 0; i < rsg->loading_count; i++) {
|
||||
UnloadSpriteGroup(&rsg->loading[i]);
|
||||
}
|
||||
for (i = 0; i < rsg->loaded_count; i++) {
|
||||
UnloadSpriteGroup(&rsg->loaded[i]);
|
||||
}
|
||||
free(group);
|
||||
return;
|
||||
}
|
||||
|
||||
case SGT_DETERMINISTIC:
|
||||
{
|
||||
DeterministicSpriteGroup *dsg = &group->g.determ;
|
||||
for (i = 0; i < group->g.determ.num_ranges; i++) {
|
||||
UnloadSpriteGroup(&dsg->ranges[i].group);
|
||||
}
|
||||
UnloadSpriteGroup(&dsg->default_group);
|
||||
free(group->g.determ.ranges);
|
||||
free(group);
|
||||
return;
|
||||
}
|
||||
|
||||
case SGT_RANDOMIZED:
|
||||
{
|
||||
for (i = 0; i < group->g.random.num_groups; i++) {
|
||||
UnloadSpriteGroup(&group->g.random.groups[i]);
|
||||
}
|
||||
free(group->g.random.groups);
|
||||
free(group);
|
||||
return;
|
||||
}
|
||||
|
||||
case SGT_CALLBACK:
|
||||
case SGT_RESULT:
|
||||
free(group);
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG(grf, 1)("Unable to remove unknown sprite group type `0x%x'.", group->type);
|
||||
}
|
||||
|
Reference in New Issue
Block a user