summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--newgrf.c289
1 files changed, 137 insertions, 152 deletions
diff --git a/newgrf.c b/newgrf.c
index 9d3cb38a9..2d83e53c1 100644
--- a/newgrf.c
+++ b/newgrf.c
@@ -1302,8 +1302,6 @@ static void NewSpriteSet(byte *buf, int len)
/* Action 0x02 */
static void NewSpriteGroup(byte *buf, int len)
{
- byte *bufend = buf + len;
-
/* <02> <feature> <set-id> <type/num-entries> <feature-specific-data...>
*
* B feature see action 1
@@ -1314,26 +1312,18 @@ static void NewSpriteGroup(byte *buf, int len)
* otherwise it specifies a number of entries, the exact
* meaning depends on the feature
* V feature-specific-data (huge mess, don't even look it up --pasky) */
- /* TODO: No 0x80-types (ugh). */
- /* TODO: Also, empty sprites aren't handled for now. Need to investigate
- * the "opacity" rules for these, that is which sprite to fall back to
- * when. --pasky */
uint8 feature;
uint8 setid;
- /* XXX: For stations, these two are "little cargo" and "lotsa cargo" sets. */
- uint8 numloaded;
- uint8 numloading;
- SpriteGroup *group;
- RealSpriteGroup *rg;
- byte *loaded_ptr;
- byte *loading_ptr;
- int i;
+ uint8 type;
+ SpriteGroup *group = NULL;
+ byte *bufend = buf + len;
check_length(len, 5, "NewSpriteGroup");
- feature = buf[1];
- setid = buf[2];
- numloaded = buf[3];
- numloading = buf[4];
+ buf++;
+
+ feature = grf_load_byte(&buf);
+ setid = grf_load_byte(&buf);
+ type = grf_load_byte(&buf);
if (setid >= _cur_grffile->spritegroups_count) {
// Allocate memory for new sprite group references.
@@ -1343,173 +1333,168 @@ static void NewSpriteGroup(byte *buf, int len)
_cur_grffile->spritegroups[_cur_grffile->spritegroups_count] = NULL;
}
- if (numloaded == 0x81 || numloaded == 0x82) {
- DeterministicSpriteGroup *dg;
- uint16 groupid;
- int i;
-
- // Ok, this is gonna get a little wild, so hold your breath...
-
- /* This stuff is getting actually evaluated in
- * EvalDeterministicSpriteGroup(). */
-
- buf += 4; len -= 4;
- check_length(len, 6, "NewSpriteGroup 0x81/0x82");
-
- group = AllocateSpriteGroup();
- group->type = SGT_DETERMINISTIC;
- dg = &group->g.determ;
-
- /* XXX: We don't free() anything, assuming that if there was
- * some action here before, it got associated by action 3.
- * We should perhaps keep some refcount? --pasky */
-
- dg->var_scope = numloaded == 0x82 ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
- dg->variable = grf_load_byte(&buf);
- /* Variables 0x60 - 0x7F include an extra parameter */
- if (IS_BYTE_INSIDE(dg->variable, 0x60, 0x80))
- dg->parameter = grf_load_byte(&buf);
+ switch (type) {
+ /* Deterministic Sprite Group */
+ case 0x81: // Self scope, byte
+ case 0x82: // Parent scope, byte
+ {
+ DeterministicSpriteGroup *dg;
+ uint16 groupid;
+ int i;
+
+ check_length(bufend - buf, 6, "NewSpriteGroup 0x81/0x82");
+
+ group = AllocateSpriteGroup();
+ group->type = SGT_DETERMINISTIC;
+ dg = &group->g.determ;
+
+ dg->var_scope = type == 0x82 ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
+ dg->variable = grf_load_byte(&buf);
+ /* Variables 0x60 - 0x7F include an extra parameter */
+ if (IS_BYTE_INSIDE(dg->variable, 0x60, 0x80))
+ dg->parameter = grf_load_byte(&buf);
+
+ dg->shift_num = grf_load_byte(&buf);
+ dg->and_mask = grf_load_byte(&buf);
+ dg->operation = dg->shift_num >> 6; /* w00t */
+ dg->shift_num &= 0x3F;
+ if (dg->operation != DSG_OP_NONE) {
+ dg->add_val = grf_load_byte(&buf);
+ dg->divmod_val = grf_load_byte(&buf);
+ }
- dg->shift_num = grf_load_byte(&buf);
- dg->and_mask = grf_load_byte(&buf);
- dg->operation = dg->shift_num >> 6; /* w00t */
- dg->shift_num &= 0x3F;
- if (dg->operation != DSG_OP_NONE) {
- dg->add_val = grf_load_byte(&buf);
- dg->divmod_val = grf_load_byte(&buf);
- }
+ /* (groupid & 0x8000) means this is callback result. */
+
+ 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);
+ } else if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
+ grfmsg(GMS_WARN, "NewSpriteGroup(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty.", setid, type, groupid);
+ dg->ranges[i].group = NULL;
+ } else {
+ dg->ranges[i].group = _cur_grffile->spritegroups[groupid];
+ }
- /* (groupid & 0x8000) means this is callback result. */
+ dg->ranges[i].low = grf_load_byte(&buf);
+ dg->ranges[i].high = grf_load_byte(&buf);
+ }
- 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->default_group = NewCallBackResultSpriteGroup(groupid);
} else if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
- grfmsg(GMS_WARN, "NewSpriteGroup(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty.", setid, numloaded, groupid);
- dg->ranges[i].group = NULL;
+ grfmsg(GMS_WARN, "NewSpriteGroup(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty.", setid, type, groupid);
+ dg->default_group = NULL;
} else {
- dg->ranges[i].group = _cur_grffile->spritegroups[groupid];
+ dg->default_group = _cur_grffile->spritegroups[groupid];
}
- dg->ranges[i].low = grf_load_byte(&buf);
- dg->ranges[i].high = grf_load_byte(&buf);
- }
-
- groupid = grf_load_word(&buf);
- if (HASBIT(groupid, 15)) {
- dg->default_group = NewCallBackResultSpriteGroup(groupid);
- } else if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
- grfmsg(GMS_WARN, "NewSpriteGroup(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty.", setid, numloaded, groupid);
- dg->default_group = NULL;
- } else {
- dg->default_group = _cur_grffile->spritegroups[groupid];
+ break;
}
- _cur_grffile->spritegroups[setid] = group;
- return;
-
- } else if (numloaded == 0x80 || numloaded == 0x83) {
- RandomizedSpriteGroup *rg;
- int i;
-
- /* This stuff is getting actually evaluated in
- * EvalRandomizedSpriteGroup(). */
+ /* Randomized Sprite Group */
+ case 0x80: // Self scope
+ case 0x83: // Parent scope
+ {
+ RandomizedSpriteGroup *rg;
+ int i;
- buf += 4;
- len -= 4;
- check_length(len, 6, "NewSpriteGroup 0x80/0x83");
+ /* This stuff is getting actually evaluated in
+ * EvalRandomizedSpriteGroup(). */
- group = AllocateSpriteGroup();
- group->type = SGT_RANDOMIZED;
- rg = &group->g.random;
+ check_length(bufend - buf, 6, "NewSpriteGroup 0x80/0x83");
- /* XXX: We don't free() anything, assuming that if there was
- * some action here before, it got associated by action 3.
- * We should perhaps keep some refcount? --pasky */
+ group = AllocateSpriteGroup();
+ group->type = SGT_RANDOMIZED;
+ rg = &group->g.random;
- rg->var_scope = numloaded == 0x83 ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
+ rg->var_scope = type == 0x83 ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
- rg->triggers = grf_load_byte(&buf);
- rg->cmp_mode = rg->triggers & 0x80;
- rg->triggers &= 0x7F;
+ rg->triggers = grf_load_byte(&buf);
+ rg->cmp_mode = rg->triggers & 0x80;
+ rg->triggers &= 0x7F;
- rg->lowest_randbit = grf_load_byte(&buf);
- rg->num_groups = grf_load_byte(&buf);
+ rg->lowest_randbit = grf_load_byte(&buf);
+ rg->num_groups = grf_load_byte(&buf);
- 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 = 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);
- } else if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
- grfmsg(GMS_WARN, "NewSpriteGroup(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty.", setid, numloaded, groupid);
- rg->groups[i] = NULL;
- } else {
- rg->groups[i] = _cur_grffile->spritegroups[groupid];
+ if (HASBIT(groupid, 15)) {
+ rg->groups[i] = NewCallBackResultSpriteGroup(groupid);
+ } else if (groupid >= _cur_grffile->spritegroups_count || _cur_grffile->spritegroups[groupid] == NULL) {
+ grfmsg(GMS_WARN, "NewSpriteGroup(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty.", setid, type, groupid);
+ rg->groups[i] = NULL;
+ } else {
+ rg->groups[i] = _cur_grffile->spritegroups[groupid];
+ }
}
+
+ break;
}
- _cur_grffile->spritegroups[setid] = group;
- return;
- }
+ default:
+ {
+ RealSpriteGroup *rg;
+ byte num_loaded = type;
+ byte num_loading = grf_load_byte(&buf);
+ uint i;
- if (!_cur_grffile->spriteset_start) {
- grfmsg(GMS_ERROR, "NewSpriteGroup: No sprite set to work on! Skipping.");
- return;
- }
+ if (!_cur_grffile->spriteset_start) {
+ grfmsg(GMS_ERROR, "NewSpriteGroup: No sprite set to work on! Skipping.");
+ return;
+ }
- if (_cur_grffile->spriteset_feature != feature) {
- grfmsg(GMS_ERROR, "NewSpriteGroup: Group feature 0x%02X doesn't match set feature 0x%X! Playing it risky and trying to use it anyway.", feature, _cur_grffile->spriteset_feature);
- // return; // XXX: we can't because of MB's newstats.grf --pasky
- }
+ if (_cur_grffile->spriteset_feature != feature) {
+ grfmsg(GMS_ERROR, "NewSpriteGroup: Group feature 0x%02X doesn't match set feature 0x%X! Playing it risky and trying to use it anyway.", feature, _cur_grffile->spriteset_feature);
+ // return; // XXX: we can't because of MB's newstats.grf --pasky
+ }
- check_length(bufend - buf, 5, "NewSpriteGroup");
- buf += 5;
- check_length(bufend - buf, 2 * numloaded, "NewSpriteGroup");
- loaded_ptr = buf;
- loading_ptr = buf + 2 * numloaded;
+ if (_cur_grffile->first_spriteset == 0)
+ _cur_grffile->first_spriteset = _cur_grffile->spriteset_start;
- if (_cur_grffile->first_spriteset == 0)
- _cur_grffile->first_spriteset = _cur_grffile->spriteset_start;
+ group = AllocateSpriteGroup();
+ group->type = SGT_REAL;
+ rg = &group->g.real;
- group = AllocateSpriteGroup();
- group->type = SGT_REAL;
- rg = &group->g.real;
+ rg->sprites_per_set = _cur_grffile->spriteset_numents;
+ rg->loaded_count = num_loaded;
+ rg->loading_count = num_loading;
- rg->sprites_per_set = _cur_grffile->spriteset_numents;
- rg->loaded_count = numloaded;
- rg->loading_count = numloading;
+ rg->loaded = calloc(rg->loaded_count, sizeof(*rg->loaded));
+ rg->loading = calloc(rg->loading_count, sizeof(*rg->loading));
- rg->loaded = calloc(rg->loaded_count, sizeof(*rg->loaded));
- rg->loading = calloc(rg->loading_count, sizeof(*rg->loading));
+ DEBUG(grf, 6) ("NewSpriteGroup: New SpriteGroup 0x%02hhx, %u views, %u loaded, %u loading, sprites %u - %u",
+ setid, rg->sprites_per_set, rg->loaded_count, rg->loading_count,
+ _cur_grffile->spriteset_start - _cur_grffile->sprite_offset,
+ _cur_grffile->spriteset_start + (_cur_grffile->spriteset_numents * (num_loaded + num_loading)) - _cur_grffile->sprite_offset);
- DEBUG(grf, 6) ("NewSpriteGroup: New SpriteGroup 0x%02hhx, %u views, %u loaded, %u loading, sprites %u - %u",
- setid, rg->sprites_per_set, rg->loaded_count, rg->loading_count,
- _cur_grffile->spriteset_start - _cur_grffile->sprite_offset,
- _cur_grffile->spriteset_start + (_cur_grffile->spriteset_numents * (numloaded + numloading)) - _cur_grffile->sprite_offset);
+ for (i = 0; i < num_loaded; i++) {
+ uint16 spriteset_id = grf_load_word(&buf);
+ 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);
+ }
+ DEBUG(grf, 8) ("NewSpriteGroup: + rg->loaded[%i] = %u (subset %u)", i, rg->loaded[i]->g.result.result, spriteset_id);
+ }
- for (i = 0; i < numloaded; i++) {
- 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);
- }
- DEBUG(grf, 8) ("NewSpriteGroup: + rg->loaded[%i] = %u (subset %u)", i, rg->loaded[i]->g.result.result, spriteset_id);
- }
+ for (i = 0; i < num_loading; i++) {
+ uint16 spriteset_id = grf_load_word(&buf);
+ 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);
+ }
+ DEBUG(grf, 8) ("NewSpriteGroup: + rg->loading[%i] = %u (subset %u)", i, rg->loading[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);
+ break;
}
- DEBUG(grf, 8) ("NewSpriteGroup: + rg->loading[%i] = %u (subset %u)", i, rg->loading[i]->g.result.result, spriteset_id);
}
_cur_grffile->spritegroups[setid] = group;