VarAction2: Add support for more varaction2 types
Add CB failure and deterministic relative types
This commit is contained in:
120
src/newgrf.cpp
120
src/newgrf.cpp
@@ -5789,6 +5789,17 @@ static void ProcessDeterministicSpriteGroupRanges(const std::vector<Deterministi
|
||||
}
|
||||
}
|
||||
|
||||
static VarSpriteGroupScopeOffset ParseRelativeScopeByte(byte relative)
|
||||
{
|
||||
VarSpriteGroupScopeOffset var_scope_count = (GB(relative, 6, 2) << 8);
|
||||
if ((relative & 0xF) == 0) {
|
||||
SetBit(var_scope_count, 15);
|
||||
} else {
|
||||
var_scope_count |= (relative & 0xF);
|
||||
}
|
||||
return var_scope_count;
|
||||
}
|
||||
|
||||
/* Action 0x02 */
|
||||
static void NewSpriteGroup(ByteReader *buf)
|
||||
{
|
||||
@@ -5819,6 +5830,16 @@ static void NewSpriteGroup(ByteReader *buf)
|
||||
* we do not need to delete anything if there is an exception from the
|
||||
* ByteReader. */
|
||||
|
||||
/* Decoded sprite type */
|
||||
enum SpriteType {
|
||||
STYPE_NORMAL,
|
||||
STYPE_DETERMINISTIC,
|
||||
STYPE_DETERMINISTIC_RELATIVE,
|
||||
STYPE_DETERMINISTIC_RELATIVE_2,
|
||||
STYPE_RANDOMIZED,
|
||||
STYPE_CB_FAILURE,
|
||||
};
|
||||
SpriteType stype = STYPE_NORMAL;
|
||||
switch (type) {
|
||||
/* Deterministic Sprite Group */
|
||||
case 0x81: // Self scope, byte
|
||||
@@ -5827,7 +5848,73 @@ static void NewSpriteGroup(ByteReader *buf)
|
||||
case 0x86: // Parent scope, word
|
||||
case 0x89: // Self scope, dword
|
||||
case 0x8A: // Parent scope, dword
|
||||
stype = STYPE_DETERMINISTIC;
|
||||
break;
|
||||
|
||||
/* Randomized Sprite Group */
|
||||
case 0x80: // Self scope
|
||||
case 0x83: // Parent scope
|
||||
case 0x84: // Relative scope
|
||||
stype = STYPE_RANDOMIZED;
|
||||
break;
|
||||
|
||||
/* Extension type */
|
||||
case 0x87:
|
||||
if (HasBit(_cur.grffile->observed_feature_tests, GFTOF_MORE_VARACTION2_TYPES)) {
|
||||
byte subtype = buf->ReadByte();
|
||||
switch (subtype) {
|
||||
case 0:
|
||||
stype = STYPE_CB_FAILURE;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
stype = STYPE_DETERMINISTIC_RELATIVE;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
stype = STYPE_DETERMINISTIC_RELATIVE_2;
|
||||
break;
|
||||
|
||||
default:
|
||||
grfmsg(1, "NewSpriteGroup: Unknown 0x87 extension subtype %02X for feature %s, handling as CB failure", subtype, GetFeatureString(feature));
|
||||
stype = STYPE_CB_FAILURE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (stype) {
|
||||
/* Deterministic Sprite Group */
|
||||
case STYPE_DETERMINISTIC:
|
||||
case STYPE_DETERMINISTIC_RELATIVE:
|
||||
case STYPE_DETERMINISTIC_RELATIVE_2:
|
||||
{
|
||||
VarSpriteGroupScopeOffset var_scope_count = 0;
|
||||
if (stype == STYPE_DETERMINISTIC_RELATIVE) {
|
||||
var_scope_count = ParseRelativeScopeByte(buf->ReadByte());
|
||||
} else if (stype == STYPE_DETERMINISTIC_RELATIVE_2) {
|
||||
uint8 mode = buf->ReadByte();
|
||||
uint8 offset = buf->ReadByte();
|
||||
bool invalid = false;
|
||||
if ((mode & 0x7F) >= VSGSRM_END) {
|
||||
invalid = true;
|
||||
}
|
||||
if (HasBit(mode, 7)) {
|
||||
/* Use variable 0x100 */
|
||||
if (offset != 0) invalid = true;
|
||||
}
|
||||
if (invalid) {
|
||||
grfmsg(1, "NewSpriteGroup: Unknown 0x87 extension subtype 2 relative mode: %02X %02X for feature %s, handling as CB failure", mode, offset, GetFeatureString(feature));
|
||||
act_group = NewCallbackResultSpriteGroupNoTransform(CALLBACK_FAILED);
|
||||
break;
|
||||
}
|
||||
var_scope_count = (mode << 8) | offset;
|
||||
}
|
||||
|
||||
byte varadjust;
|
||||
byte varsize;
|
||||
|
||||
@@ -5839,13 +5926,22 @@ static void NewSpriteGroup(ByteReader *buf)
|
||||
group->feature = feature;
|
||||
if (_action6_override_active) group->sg_flags |= SGF_ACTION6;
|
||||
act_group = group;
|
||||
group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
|
||||
|
||||
switch (GB(type, 2, 2)) {
|
||||
default: NOT_REACHED();
|
||||
case 0: group->size = DSG_SIZE_BYTE; varsize = 1; break;
|
||||
case 1: group->size = DSG_SIZE_WORD; varsize = 2; break;
|
||||
case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break;
|
||||
if (stype == STYPE_DETERMINISTIC_RELATIVE || stype == STYPE_DETERMINISTIC_RELATIVE_2) {
|
||||
group->var_scope = (feature <= GSF_AIRCRAFT) ? VSG_SCOPE_RELATIVE : VSG_SCOPE_SELF;
|
||||
group->var_scope_count = var_scope_count;
|
||||
|
||||
group->size = DSG_SIZE_DWORD;
|
||||
varsize = 4;
|
||||
} else {
|
||||
group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF;
|
||||
|
||||
switch (GB(type, 2, 2)) {
|
||||
default: NOT_REACHED();
|
||||
case 0: group->size = DSG_SIZE_BYTE; varsize = 1; break;
|
||||
case 1: group->size = DSG_SIZE_WORD; varsize = 2; break;
|
||||
case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break;
|
||||
}
|
||||
}
|
||||
|
||||
const VarAction2AdjustInfo info = { feature, GetGrfSpecFeatureForScope(feature, group->var_scope), varsize };
|
||||
@@ -5962,9 +6058,7 @@ static void NewSpriteGroup(ByteReader *buf)
|
||||
}
|
||||
|
||||
/* Randomized Sprite Group */
|
||||
case 0x80: // Self scope
|
||||
case 0x83: // Parent scope
|
||||
case 0x84: // Relative scope
|
||||
case STYPE_RANDOMIZED:
|
||||
{
|
||||
assert(RandomizedSpriteGroup::CanAllocateItem());
|
||||
RandomizedSpriteGroup *group = new RandomizedSpriteGroup();
|
||||
@@ -5975,7 +6069,7 @@ static void NewSpriteGroup(ByteReader *buf)
|
||||
|
||||
if (HasBit(type, 2)) {
|
||||
if (feature <= GSF_AIRCRAFT) group->var_scope = VSG_SCOPE_RELATIVE;
|
||||
group->count = buf->ReadByte();
|
||||
group->var_scope_count = ParseRelativeScopeByte(buf->ReadByte());
|
||||
}
|
||||
|
||||
uint8 triggers = buf->ReadByte();
|
||||
@@ -6005,8 +6099,12 @@ static void NewSpriteGroup(ByteReader *buf)
|
||||
break;
|
||||
}
|
||||
|
||||
case STYPE_CB_FAILURE:
|
||||
act_group = NewCallbackResultSpriteGroupNoTransform(CALLBACK_FAILED);
|
||||
break;
|
||||
|
||||
/* Neither a variable or randomized sprite group... must be a real group */
|
||||
default:
|
||||
case STYPE_NORMAL:
|
||||
{
|
||||
switch (feature) {
|
||||
case GSF_TRAINS:
|
||||
|
Reference in New Issue
Block a user