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 } |
|