@@ -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)
{
engine_custom_sprites[engine][cargo] = group;
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,
@@ -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].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;
dg->default_group = _cur_grffile->spritegroups[groupid];
dg->default_group->ref_count++;
_cur_grffile->spritegroups[setid] = group;
} 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);
rg->groups[i] = NewCallBackResultSpriteGroup(groupid);
rg->groups[i]->ref_count++;
i--;
rg->num_groups--;
rg->groups[i] = _cur_grffile->spritegroups[groupid];
if (!_cur_grffile->spriteset_start) {
grfmsg(GMS_ERROR, "NewSpriteGroup: No sprite set to work on! Skipping.");
@@ -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);
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);
rg->loading[i] = NewCallBackResultSpriteGroup(spriteset_id);
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);
/* 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. */
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;
@@ -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;
Status change: