Changeset - r2490:4a9082968d2a
[Not reviewed]
master
0 3 0
peter1138 - 19 years ago 2005-10-04 20:58:10
peter1138@openttd.org
(svn r3016) -NewGRF: Implement the start of reference counting for sprite groups. This will allow unloading.
3 files changed with 15 insertions and 2 deletions:
0 comments (0 inline, 0 general)
engine.c
Show inline comments
 
@@ -263,12 +263,13 @@ void SetWagonOverrideSprites(EngineID en
 

	
 
	wo = &wos->overrides[wos->overrides_count - 1];
 
	/* FIXME: If we are replacing an override, release original SpriteGroup
 
	 * to prevent leaks. But first we need to refcount the SpriteGroup.
 
	 * --pasky */
 
	wo->group = group;
 
	group->ref_count++;
 
	wo->trains = trains;
 
	wo->train_id = malloc(trains);
 
	memcpy(wo->train_id, train_id, trains);
 
}
 

	
 
static const SpriteGroup *GetWagonOverrideSpriteSet(EngineID engine, byte overriding_engine)
 
@@ -303,12 +304,13 @@ static SpriteGroup *engine_custom_sprite
 
void SetCustomEngineSprites(EngineID engine, byte cargo, SpriteGroup *group)
 
{
 
	/* FIXME: If we are replacing an override, release original SpriteGroup
 
	 * to prevent leaks. But first we need to refcount the SpriteGroup.
 
	 * --pasky */
 
	engine_custom_sprites[engine][cargo] = group;
 
	group->ref_count++;
 
}
 

	
 
typedef SpriteGroup *(*resolve_callback)(const SpriteGroup *spritegroup,
 
	const Vehicle *veh, uint16 callback_info, void *resolve_func); /* XXX data pointer used as function pointer */
 

	
 
static const SpriteGroup* ResolveVehicleSpriteGroup(const SpriteGroup *spritegroup,
newgrf.c
Show inline comments
 
@@ -1371,21 +1371,23 @@ static void NewSpriteGroup(byte *buf, in
 
		dg->num_ranges = grf_load_byte(&buf);
 
		dg->ranges = calloc(dg->num_ranges, sizeof(*dg->ranges));
 
		for (i = 0; i < dg->num_ranges; i++) {
 
			groupid = grf_load_word(&buf);
 
			if (HASBIT(groupid, 15)) {
 
				dg->ranges[i].group = NewCallBackResultSpriteGroup(groupid);
 
				dg->ranges[i].group->ref_count++;
 
			} else if (groupid >= _cur_grffile->spritegroups_count) {
 
				/* This doesn't exist for us. */
 
				grf_load_word(&buf); // skip range
 
				i--; dg->num_ranges--;
 
				continue;
 
			} else {
 
			/* XXX: If multiple surreal sets attach a surreal
 
			 * set this way, we are in trouble. */
 
				dg->ranges[i].group = _cur_grffile->spritegroups[groupid];
 
				dg->ranges[i].group->ref_count++;
 
			}
 

	
 
			dg->ranges[i].low = grf_load_byte(&buf);
 
			dg->ranges[i].high = grf_load_byte(&buf);
 
		}
 

	
 
@@ -1397,14 +1399,16 @@ static void NewSpriteGroup(byte *buf, in
 
			free(dg->ranges), dg->ranges = NULL;
 
			grfmsg(GMS_WARN, "NewSpriteGroup(%02x:0x%x): Default groupid %04x is cargo callback or unknown, ignoring spritegroup.", setid, numloaded, groupid);
 
			return;
 
		} else {
 
			dg->default_group = _cur_grffile->spritegroups[groupid];
 
		}
 
		dg->default_group->ref_count++;
 

	
 
		_cur_grffile->spritegroups[setid] = group;
 
		group->ref_count++;
 
		return;
 

	
 
	} else if (numloaded == 0x80 || numloaded == 0x83) {
 
		RandomizedSpriteGroup *rg;
 
		int i;
 

	
 
@@ -1435,25 +1439,26 @@ static void NewSpriteGroup(byte *buf, in
 
		rg->groups = calloc(rg->num_groups, sizeof(*rg->groups));
 
		for (i = 0; i < rg->num_groups; i++) {
 
			uint16 groupid = grf_load_word(&buf);
 

	
 
			if (HASBIT(groupid, 15)) {
 
				rg->groups[i] = NewCallBackResultSpriteGroup(groupid);
 
				rg->groups[i]->ref_count++;
 
			} else if (groupid >= _cur_grffile->spritegroups_count) {
 
				/* This doesn't exist for us. */
 
				i--;
 
				rg->num_groups--;
 
				continue;
 
			} else {
 
				/* XXX: If multiple surreal sets attach a surreal
 
				 * set this way, we are in trouble. */
 
				rg->groups[i] = _cur_grffile->spritegroups[groupid];
 
				rg->groups[i]->ref_count++;
 
			}
 
		}
 

	
 
		_cur_grffile->spritegroups[setid] = group;
 
		group->ref_count++;
 
		return;
 
	}
 

	
 
	if (!_cur_grffile->spriteset_start) {
 
		grfmsg(GMS_ERROR, "NewSpriteGroup: No sprite set to work on! Skipping.");
 
		return;
 
@@ -1496,26 +1501,29 @@ static void NewSpriteGroup(byte *buf, in
 
		uint16 spriteset_id = grf_load_word(&loaded_ptr);
 
		if (HASBIT(spriteset_id, 15)) {
 
			rg->loaded[i] = NewCallBackResultSpriteGroup(spriteset_id);
 
		} else {
 
			rg->loaded[i] = NewResultSpriteGroup(_cur_grffile->spriteset_start + spriteset_id * _cur_grffile->spriteset_numents, rg->sprites_per_set);
 
		}
 
		rg->loaded[i]->ref_count++;
 
		DEBUG(grf, 8) ("NewSpriteGroup: + rg->loaded[%i]  = %u (subset %u)", i, rg->loaded[i]->g.result.result, spriteset_id);
 
	}
 

	
 
	for (i = 0; i < numloading; i++) {
 
		uint16 spriteset_id = grf_load_word(&loading_ptr);
 
		if (HASBIT(spriteset_id, 15)) {
 
			rg->loading[i] = NewCallBackResultSpriteGroup(spriteset_id);
 
		} else {
 
			rg->loading[i] = NewResultSpriteGroup(_cur_grffile->spriteset_start + spriteset_id * _cur_grffile->spriteset_numents, rg->sprites_per_set);
 
		}
 
		rg->loading[i]->ref_count++;
 
		DEBUG(grf, 8) ("NewSpriteGroup: + rg->loading[%i] = %u (subset %u)", i, rg->loading[i]->g.result.result, spriteset_id);
 
	}
 

	
 
	_cur_grffile->spritegroups[setid] = group;
 
	group->ref_count++;
 
}
 

	
 
/* Action 0x03 */
 
static void NewVehicle_SpriteGroupMapping(byte *buf, int len)
 
{
 
	/* <03> <feature> <n-id> <ids>... <num-cid> [<cargo-type> <cid>]... <def-cid>
 
@@ -1581,12 +1589,13 @@ static void NewVehicle_SpriteGroupMappin
 
				if (ctype != 0xFF) {
 
					/* TODO: No support for any other cargo. */
 
					continue;
 
				}
 

	
 
				stat->spritegroup[1] = _cur_grffile->spritegroups[groupid];
 
				stat->spritegroup[1]->ref_count++;
 
			}
 
		}
 

	
 
		{
 
			byte *bp = buf + 4 + idcount + cidcount * 3;
 
			uint16 groupid = grf_load_word(&bp);
 
@@ -1599,12 +1608,13 @@ static void NewVehicle_SpriteGroupMappin
 

	
 
			for (i = 0; i < idcount; i++) {
 
				uint8 stid = buf[3 + i];
 
				StationSpec *stat = &_cur_grffile->stations[stid];
 

	
 
				stat->spritegroup[0] = _cur_grffile->spritegroups[groupid];
 
				stat->spritegroup[0]->ref_count++;
 
				stat->grfid = _cur_grffile->grfid;
 
				SetCustomStation(stid, stat);
 
				stat->sclass = STAT_CLASS_NONE;
 
			}
 
		}
 
		return;
sprite.h
Show inline comments
 
@@ -126,12 +126,13 @@ typedef enum SpriteGroupType {
 
	SGT_CALLBACK,
 
	SGT_RESULT,
 
} SpriteGroupType;
 

	
 
struct SpriteGroup {
 
	SpriteGroupType type;
 
	byte ref_count;
 

	
 
	union {
 
		RealSpriteGroup real;
 
		DeterministicSpriteGroup determ;
 
		RandomizedSpriteGroup random;
 
		CallbackResultSpriteGroup callback;
0 comments (0 inline, 0 general)