Add NewGRF VarAction2 variable remapping infrastructure
This commit is contained in:
149
src/newgrf.cpp
149
src/newgrf.cpp
@@ -5295,6 +5295,17 @@ static void NewSpriteGroup(ByteReader *buf)
|
||||
adjust.type = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2);
|
||||
adjust.and_mask = buf->ReadVarSize(varsize);
|
||||
|
||||
if (adjust.variable == 0x11) {
|
||||
for (const GRFVariableMapEntry &remap : _cur.grffile->grf_variable_remaps) {
|
||||
if (remap.feature == feature && remap.input_shift == adjust.shift_num && remap.input_mask == adjust.and_mask) {
|
||||
adjust.variable = remap.id;
|
||||
adjust.shift_num = remap.output_shift;
|
||||
adjust.and_mask = remap.output_mask;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (adjust.type != DSGA_TYPE_NONE) {
|
||||
adjust.add_val = buf->ReadVarSize(varsize);
|
||||
adjust.divmod_val = buf->ReadVarSize(varsize);
|
||||
@@ -8668,6 +8679,10 @@ struct GRFPropertyMapAction {
|
||||
std::string name;
|
||||
GRFPropertyMapFallbackMode fallback_mode;
|
||||
uint8 ttd_ver_var_bit;
|
||||
uint8 input_shift;
|
||||
uint8 output_shift;
|
||||
uint input_mask;
|
||||
uint output_mask;
|
||||
|
||||
void Reset(const char *tag, const char *desc)
|
||||
{
|
||||
@@ -8679,6 +8694,10 @@ struct GRFPropertyMapAction {
|
||||
this->name.clear();
|
||||
this->fallback_mode = GPMFM_IGNORE;
|
||||
this->ttd_ver_var_bit = 0;
|
||||
this->input_shift = 0;
|
||||
this->output_shift = 0;
|
||||
this->input_mask = 0;
|
||||
this->output_mask = 0;
|
||||
}
|
||||
|
||||
void ExecutePropertyRemapping()
|
||||
@@ -8733,6 +8752,34 @@ struct GRFPropertyMapAction {
|
||||
}
|
||||
}
|
||||
|
||||
void ExecuteVariableRemapping()
|
||||
{
|
||||
if (this->feature < 0) {
|
||||
grfmsg(2, "Action 14 %s remapping: no feature defined, doing nothing", this->descriptor);
|
||||
return;
|
||||
}
|
||||
if (this->name.empty()) {
|
||||
grfmsg(2, "Action 14 %s remapping: no name defined, doing nothing", this->descriptor);
|
||||
return;
|
||||
}
|
||||
bool success = false;
|
||||
const char *str = this->name.c_str();
|
||||
extern const GRFVariableMapDefinition _grf_action2_remappable_variables[];
|
||||
for (const GRFVariableMapDefinition *info = _grf_action2_remappable_variables; info->name != nullptr; info++) {
|
||||
if (info->feature == this->feature && strcmp(info->name, str) == 0) {
|
||||
_cur.grffile->grf_variable_remaps.push_back({ info->id, (uint8) this->feature, this->input_shift, this->output_shift, this->input_mask, this->output_mask });
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (this->ttd_ver_var_bit > 0) {
|
||||
SB(_cur.grffile->var8D_overlay, this->ttd_ver_var_bit, 1, success ? 1 : 0);
|
||||
}
|
||||
if (!success) {
|
||||
grfmsg(2, "Unimplemented mapped %s: %s, feature: %X, mapped to 0", this->descriptor, str, this->feature);
|
||||
}
|
||||
}
|
||||
|
||||
void ExecuteAction5TypeRemapping()
|
||||
{
|
||||
if (this->prop_id < 0) {
|
||||
@@ -8869,6 +8916,82 @@ static bool ChangePropertyRemapSetTTDVerVarBit(size_t len, ByteReader *buf)
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Callback function for ->'RSFT' to set the input shift value for variable remapping. */
|
||||
static bool ChangePropertyRemapSetInputShift(size_t len, ByteReader *buf)
|
||||
{
|
||||
GRFPropertyMapAction &action = _current_grf_property_map_action;
|
||||
if (len != 1) {
|
||||
grfmsg(2, "Action 14 %s mapping: expected 1 byte for '%s'->'RSFT' but got " PRINTF_SIZE ", ignoring this field", action.descriptor, action.tag_name, len);
|
||||
buf->Skip(len);
|
||||
} else {
|
||||
uint8 input_shift = buf->ReadByte();
|
||||
if (input_shift < 0x20) {
|
||||
action.input_shift = input_shift;
|
||||
} else {
|
||||
grfmsg(2, "Action 14 %s mapping: expected a shift value < 0x20 for '%s'->'RSFT' but got %u, ignoring this field", action.descriptor, action.tag_name, input_shift);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Callback function for ->'VSFT' to set the output shift value for variable remapping. */
|
||||
static bool ChangePropertyRemapSetOutputShift(size_t len, ByteReader *buf)
|
||||
{
|
||||
GRFPropertyMapAction &action = _current_grf_property_map_action;
|
||||
if (len != 1) {
|
||||
grfmsg(2, "Action 14 %s mapping: expected 1 byte for '%s'->'VSFT' but got " PRINTF_SIZE ", ignoring this field", action.descriptor, action.tag_name, len);
|
||||
buf->Skip(len);
|
||||
} else {
|
||||
uint8 output_shift = buf->ReadByte();
|
||||
if (output_shift < 0x20) {
|
||||
action.output_shift = output_shift;
|
||||
} else {
|
||||
grfmsg(2, "Action 14 %s mapping: expected a shift value < 0x20 for '%s'->'VSFT' but got %u, ignoring this field", action.descriptor, action.tag_name, output_shift);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Callback function for ->'RMSK' to set the input mask value for variable remapping. */
|
||||
static bool ChangePropertyRemapSetInputMask(size_t len, ByteReader *buf)
|
||||
{
|
||||
GRFPropertyMapAction &action = _current_grf_property_map_action;
|
||||
if (len != 4) {
|
||||
grfmsg(2, "Action 14 %s mapping: expected 4 bytes for '%s'->'RMSK' but got " PRINTF_SIZE ", ignoring this field", action.descriptor, action.tag_name, len);
|
||||
buf->Skip(len);
|
||||
} else {
|
||||
action.input_mask = buf->ReadDWord();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Callback function for ->'VMSK' to set the output mask value for variable remapping. */
|
||||
static bool ChangePropertyRemapSetOutputMask(size_t len, ByteReader *buf)
|
||||
{
|
||||
GRFPropertyMapAction &action = _current_grf_property_map_action;
|
||||
if (len != 4) {
|
||||
grfmsg(2, "Action 14 %s mapping: expected 4 bytes for '%s'->'VMSK' but got " PRINTF_SIZE ", ignoring this field", action.descriptor, action.tag_name, len);
|
||||
buf->Skip(len);
|
||||
} else {
|
||||
action.output_mask = buf->ReadDWord();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Callback function for ->'VPRM' to set the output parameter value for variable remapping. */
|
||||
static bool ChangePropertyRemapSetOutputParam(size_t len, ByteReader *buf)
|
||||
{
|
||||
GRFPropertyMapAction &action = _current_grf_property_map_action;
|
||||
if (len != 4) {
|
||||
grfmsg(2, "Action 14 %s mapping: expected 4 bytes for '%s'->'VPRM' but got " PRINTF_SIZE ", ignoring this field", action.descriptor, action.tag_name, len);
|
||||
buf->Skip(len);
|
||||
} else {
|
||||
buf->ReadDWord();
|
||||
/* This is not implemented yet, so just do nothing, but still validate that the format is correct */
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Action14 tags for the A0PM node */
|
||||
AllowedSubtags _tags_a0pm[] = {
|
||||
AllowedSubtags('NAME', ChangePropertyRemapName),
|
||||
@@ -8890,6 +9013,30 @@ static bool HandleAction0PropertyMap(ByteReader *buf)
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Action14 tags for the A2VM node */
|
||||
AllowedSubtags _tags_a2vm[] = {
|
||||
AllowedSubtags('NAME', ChangePropertyRemapName),
|
||||
AllowedSubtags('FEAT', ChangePropertyRemapFeature),
|
||||
AllowedSubtags('RSFT', ChangePropertyRemapSetInputShift),
|
||||
AllowedSubtags('RMSK', ChangePropertyRemapSetInputMask),
|
||||
AllowedSubtags('VSFT', ChangePropertyRemapSetOutputShift),
|
||||
AllowedSubtags('VMSK', ChangePropertyRemapSetOutputMask),
|
||||
AllowedSubtags('VPRM', ChangePropertyRemapSetOutputParam),
|
||||
AllowedSubtags('SETT', ChangePropertyRemapSetTTDVerVarBit),
|
||||
AllowedSubtags()
|
||||
};
|
||||
|
||||
/**
|
||||
* Callback function for 'A2VM' (action 2 variable mapping)
|
||||
*/
|
||||
static bool HandleAction2VariableMap(ByteReader *buf)
|
||||
{
|
||||
_current_grf_property_map_action.Reset("A2VM", "variable");
|
||||
HandleNodes(buf, _tags_a2vm);
|
||||
_current_grf_property_map_action.ExecuteVariableRemapping();
|
||||
return true;
|
||||
}
|
||||
|
||||
/** Action14 tags for the A5TM node */
|
||||
AllowedSubtags _tags_a5tm[] = {
|
||||
AllowedSubtags('NAME', ChangePropertyRemapName),
|
||||
@@ -8915,6 +9062,7 @@ AllowedSubtags _tags_root_static[] = {
|
||||
AllowedSubtags('INFO', _tags_info),
|
||||
AllowedSubtags('FTST', SkipInfoChunk),
|
||||
AllowedSubtags('A0PM', SkipInfoChunk),
|
||||
AllowedSubtags('A2VM', SkipInfoChunk),
|
||||
AllowedSubtags('A5TM', SkipInfoChunk),
|
||||
AllowedSubtags()
|
||||
};
|
||||
@@ -8924,6 +9072,7 @@ AllowedSubtags _tags_root_feature_tests[] = {
|
||||
AllowedSubtags('INFO', SkipInfoChunk),
|
||||
AllowedSubtags('FTST', HandleFeatureTestInfo),
|
||||
AllowedSubtags('A0PM', HandleAction0PropertyMap),
|
||||
AllowedSubtags('A2VM', HandleAction2VariableMap),
|
||||
AllowedSubtags('A5TM', HandleAction5TypeMap),
|
||||
AllowedSubtags()
|
||||
};
|
||||
|
Reference in New Issue
Block a user