mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-04 06:00:15 +00:00
(svn r4537) - NewGRF: replace if cascade with a switch block in the sprite group loader
This commit is contained in:
parent
52d790f8e2
commit
925ab8403d
281
newgrf.c
281
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;
|
||||
switch (type) {
|
||||
/* Deterministic Sprite Group */
|
||||
case 0x81: // Self scope, byte
|
||||
case 0x82: // Parent scope, byte
|
||||
{
|
||||
DeterministicSpriteGroup *dg;
|
||||
uint16 groupid;
|
||||
int i;
|
||||
|
||||
// Ok, this is gonna get a little wild, so hold your breath...
|
||||
check_length(bufend - buf, 6, "NewSpriteGroup 0x81/0x82");
|
||||
|
||||
/* This stuff is getting actually evaluated in
|
||||
* EvalDeterministicSpriteGroup(). */
|
||||
group = AllocateSpriteGroup();
|
||||
group->type = SGT_DETERMINISTIC;
|
||||
dg = &group->g.determ;
|
||||
|
||||
buf += 4; len -= 4;
|
||||
check_length(len, 6, "NewSpriteGroup 0x81/0x82");
|
||||
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);
|
||||
|
||||
group = AllocateSpriteGroup();
|
||||
group->type = SGT_DETERMINISTIC;
|
||||
dg = &group->g.determ;
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
/* (groupid & 0x8000) means this is callback result. */
|
||||
|
||||
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);
|
||||
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];
|
||||
}
|
||||
|
||||
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->ranges[i].low = grf_load_byte(&buf);
|
||||
dg->ranges[i].high = 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);
|
||||
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);
|
||||
break;
|
||||
}
|
||||
|
||||
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];
|
||||
}
|
||||
/* Randomized Sprite Group */
|
||||
case 0x80: // Self scope
|
||||
case 0x83: // Parent scope
|
||||
{
|
||||
RandomizedSpriteGroup *rg;
|
||||
int i;
|
||||
|
||||
_cur_grffile->spritegroups[setid] = group;
|
||||
return;
|
||||
/* This stuff is getting actually evaluated in
|
||||
* EvalRandomizedSpriteGroup(). */
|
||||
|
||||
} else if (numloaded == 0x80 || numloaded == 0x83) {
|
||||
RandomizedSpriteGroup *rg;
|
||||
int i;
|
||||
check_length(bufend - buf, 6, "NewSpriteGroup 0x80/0x83");
|
||||
|
||||
/* This stuff is getting actually evaluated in
|
||||
* EvalRandomizedSpriteGroup(). */
|
||||
group = AllocateSpriteGroup();
|
||||
group->type = SGT_RANDOMIZED;
|
||||
rg = &group->g.random;
|
||||
|
||||
buf += 4;
|
||||
len -= 4;
|
||||
check_length(len, 6, "NewSpriteGroup 0x80/0x83");
|
||||
rg->var_scope = type == 0x83 ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
|
||||
|
||||
group = AllocateSpriteGroup();
|
||||
group->type = SGT_RANDOMIZED;
|
||||
rg = &group->g.random;
|
||||
rg->triggers = grf_load_byte(&buf);
|
||||
rg->cmp_mode = rg->triggers & 0x80;
|
||||
rg->triggers &= 0x7F;
|
||||
|
||||
/* 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 */
|
||||
rg->lowest_randbit = grf_load_byte(&buf);
|
||||
rg->num_groups = grf_load_byte(&buf);
|
||||
|
||||
rg->var_scope = numloaded == 0x83 ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
|
||||
rg->groups = calloc(rg->num_groups, sizeof(*rg->groups));
|
||||
for (i = 0; i < rg->num_groups; i++) {
|
||||
uint16 groupid = grf_load_word(&buf);
|
||||
|
||||
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->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);
|
||||
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);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
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);
|
||||
}
|
||||
DEBUG(grf, 8) ("NewSpriteGroup: + rg->loading[%i] = %u (subset %u)", i, rg->loading[i]->g.result.result, spriteset_id);
|
||||
}
|
||||
|
||||
_cur_grffile->spritegroups[setid] = group;
|
||||
|
Loading…
Reference in New Issue
Block a user