sprite.c
changeset 3595 a0acdb23e662
parent 3593 7ec7431c7a94
child 3668 42325f12e7d8
equal deleted inserted replaced
3594:3c4e4feea80a 3595:a0acdb23e662
    95 
    95 
    96 	*waiting_triggers &= ~match;
    96 	*waiting_triggers &= ~match;
    97 
    97 
    98 	return (rsg->num_groups - 1) << rsg->lowest_randbit;
    98 	return (rsg->num_groups - 1) << rsg->lowest_randbit;
    99 }
    99 }
   100 
       
   101 /**
       
   102  * Traverse a sprite group and release its and its child's memory.
       
   103  * A group is only released if its reference count is zero.
       
   104  * We pass a pointer to a pointer so that the original reference can be set to NULL.
       
   105  * @param group_ptr Pointer to sprite group reference.
       
   106  */
       
   107 void UnloadSpriteGroup(SpriteGroup **group_ptr)
       
   108 {
       
   109 	SpriteGroup *group;
       
   110 	int i;
       
   111 
       
   112 	assert(group_ptr != NULL);
       
   113 	assert(*group_ptr != NULL);
       
   114 
       
   115 	group = *group_ptr;
       
   116 	*group_ptr = NULL; // Remove this reference.
       
   117 
       
   118 	group->ref_count--;
       
   119 	if (group->ref_count > 0) {
       
   120 		DEBUG(grf, 6)("UnloadSpriteGroup: Group at `%p' (type %d) has %d reference(s) left.", group, group->type, group->ref_count);
       
   121 		return; // Still some references left, so don't clear up.
       
   122 	}
       
   123 
       
   124 	DEBUG(grf, 6)("UnloadSpriteGroup: Releasing group at `%p'.", group);
       
   125 	switch (group->type) {
       
   126 		case SGT_REAL:
       
   127 		{
       
   128 			RealSpriteGroup *rsg = &group->g.real;
       
   129 			for (i = 0; i < rsg->loading_count; i++) {
       
   130 				if (rsg->loading[i] != NULL) UnloadSpriteGroup(&rsg->loading[i]);
       
   131 			}
       
   132 			for (i = 0; i < rsg->loaded_count; i++) {
       
   133 				if (rsg->loaded[i] != NULL) UnloadSpriteGroup(&rsg->loaded[i]);
       
   134 			}
       
   135 			free(group->g.real.loaded);
       
   136 			free(group->g.real.loading);
       
   137 			free(group);
       
   138 			return;
       
   139 		}
       
   140 
       
   141 		case SGT_DETERMINISTIC:
       
   142 		{
       
   143 			DeterministicSpriteGroup *dsg = &group->g.determ;
       
   144 			for (i = 0; i < group->g.determ.num_ranges; i++) {
       
   145 				if (dsg->ranges[i].group != NULL) UnloadSpriteGroup(&dsg->ranges[i].group);
       
   146 			}
       
   147 			if (dsg->default_group != NULL) UnloadSpriteGroup(&dsg->default_group);
       
   148 			free(group->g.determ.ranges);
       
   149 			free(group);
       
   150 			return;
       
   151 		}
       
   152 
       
   153 		case SGT_RANDOMIZED:
       
   154 		{
       
   155 			for (i = 0; i < group->g.random.num_groups; i++) {
       
   156 				if (group->g.random.groups[i] != NULL) UnloadSpriteGroup(&group->g.random.groups[i]);
       
   157 			}
       
   158 			free(group->g.random.groups);
       
   159 			free(group);
       
   160 			return;
       
   161 		}
       
   162 
       
   163 		case SGT_CALLBACK:
       
   164 		case SGT_RESULT:
       
   165 			free(group);
       
   166 			return;
       
   167 	}
       
   168 
       
   169 	DEBUG(grf, 1)("Unable to remove unknown sprite group type `0x%x'.", group->type);
       
   170 }