VarAction2: Add support for more varaction2 types
Add CB failure and deterministic relative types
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
#include "newgrf_extension.h"
|
||||
#include "scope.h"
|
||||
#include "debug_settings.h"
|
||||
#include "newgrf_engine.h"
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
@@ -165,7 +166,7 @@ static inline uint32 GetVariable(const ResolverObject &object, ScopeResolver *sc
|
||||
* @param relative Additional parameter for #VSG_SCOPE_RELATIVE.
|
||||
* @return The resolver for the requested scope.
|
||||
*/
|
||||
/* virtual */ ScopeResolver *ResolverObject::GetScope(VarSpriteGroupScope scope, byte relative)
|
||||
/* virtual */ ScopeResolver *ResolverObject::GetScope(VarSpriteGroupScope scope, VarSpriteGroupScopeOffset relative)
|
||||
{
|
||||
return &this->default_scope;
|
||||
}
|
||||
@@ -259,7 +260,7 @@ const SpriteGroup *DeterministicSpriteGroup::Resolve(ResolverObject &object) con
|
||||
uint32 last_value = 0;
|
||||
uint32 value = 0;
|
||||
|
||||
ScopeResolver *scope = object.GetScope(this->var_scope);
|
||||
ScopeResolver *scope = object.GetScope(this->var_scope, this->var_scope_count);
|
||||
|
||||
const DeterministicSpriteGroupAdjust *end = this->adjusts.data() + this->adjusts.size();
|
||||
for (const DeterministicSpriteGroupAdjust *iter = this->adjusts.data(); iter != end; ++iter) {
|
||||
@@ -271,6 +272,17 @@ const SpriteGroup *DeterministicSpriteGroup::Resolve(ResolverObject &object) con
|
||||
/* Try to get the variable. We shall assume it is available, unless told otherwise. */
|
||||
GetVariableExtra extra(adjust.and_mask << adjust.shift_num);
|
||||
if (adjust.variable == 0x7E) {
|
||||
const Vehicle *relative_scope_vehicle = nullptr;
|
||||
VarSpriteGroupScopeOffset relative_scope_cached_count = 0;
|
||||
if (this->var_scope == VSG_SCOPE_RELATIVE) {
|
||||
/* Save relative scope vehicle in case it will be changed during the procedure */
|
||||
VehicleResolverObject *veh_object = dynamic_cast<VehicleResolverObject *>(&object);
|
||||
if (veh_object != nullptr) {
|
||||
relative_scope_vehicle = veh_object->relative_scope.v;
|
||||
relative_scope_cached_count = veh_object->cached_relative_count;
|
||||
}
|
||||
}
|
||||
|
||||
const SpriteGroup *subgroup = SpriteGroup::Resolve(adjust.subroutine, object, false);
|
||||
if (subgroup == nullptr) {
|
||||
value = CALLBACK_FAILED;
|
||||
@@ -278,6 +290,13 @@ const SpriteGroup *DeterministicSpriteGroup::Resolve(ResolverObject &object) con
|
||||
value = subgroup->GetCallbackResult();
|
||||
}
|
||||
|
||||
if (relative_scope_vehicle != nullptr) {
|
||||
/* Reset relative scope vehicle in case it was changed during the procedure */
|
||||
VehicleResolverObject *veh_object = static_cast<VehicleResolverObject *>(&object);
|
||||
veh_object->relative_scope.v = relative_scope_vehicle;
|
||||
veh_object->cached_relative_count = relative_scope_cached_count;
|
||||
}
|
||||
|
||||
/* Note: 'last_value' and 'reseed' are shared between the main chain and the procedure */
|
||||
} else if (adjust.variable == 0x7B) {
|
||||
_sprite_group_resolve_check_veh_check = false;
|
||||
@@ -338,7 +357,7 @@ bool DeterministicSpriteGroup::GroupMayBeBypassed() const
|
||||
|
||||
const SpriteGroup *RandomizedSpriteGroup::Resolve(ResolverObject &object) const
|
||||
{
|
||||
ScopeResolver *scope = object.GetScope(this->var_scope, this->count);
|
||||
ScopeResolver *scope = object.GetScope(this->var_scope, this->var_scope_count);
|
||||
if (object.callback == CBID_RANDOM_TRIGGER) {
|
||||
/* Handle triggers */
|
||||
byte match = this->triggers & object.waiting_triggers;
|
||||
@@ -445,6 +464,14 @@ static const char *_sg_size_names[] {
|
||||
"DWORD",
|
||||
};
|
||||
|
||||
static const char *_sg_relative_scope_modes[] {
|
||||
"BACKWARD_SELF",
|
||||
"FORWARD_SELF",
|
||||
"BACKWARD_ENGINE",
|
||||
"BACKWARD_SAMEID",
|
||||
};
|
||||
static_assert(lengthof(_sg_relative_scope_modes) == VSGSRM_END);
|
||||
|
||||
static char *GetAdjustOperationName(char *str, const char *last, DeterministicSpriteGroupAdjustOperation operation)
|
||||
{
|
||||
if (operation < DSGA_OP_END) return strecat(str, _dsg_op_names[operation], last);
|
||||
@@ -601,6 +628,23 @@ void SpriteGroupDumper::DumpSpriteGroup(const SpriteGroup *sg, const char *paddi
|
||||
if (sg->sg_flags & SGF_INLINING) strecat(extra_info, " (inlining)", lastof(extra_info));
|
||||
}
|
||||
|
||||
char scope_buffer[64] = "";
|
||||
auto get_scope_name = [&](VarSpriteGroupScope var_scope, VarSpriteGroupScopeOffset var_scope_count) -> const char * {
|
||||
if (var_scope == VSG_SCOPE_RELATIVE) {
|
||||
char *b = scope_buffer;
|
||||
b += seprintf(b, lastof(scope_buffer), "%s[%s, ", _sg_scope_names[var_scope], _sg_relative_scope_modes[GB(var_scope_count, 8, 2)]);
|
||||
byte offset = GB(var_scope_count, 0, 8);
|
||||
if (HasBit(var_scope_count, 15)) {
|
||||
b += seprintf(b, lastof(scope_buffer), "var 0x100]");
|
||||
} else {
|
||||
b += seprintf(b, lastof(scope_buffer), "%u]", offset);
|
||||
}
|
||||
return scope_buffer;
|
||||
} else {
|
||||
return _sg_scope_names[var_scope];
|
||||
}
|
||||
};
|
||||
|
||||
switch (sg->type) {
|
||||
case SGT_REAL: {
|
||||
const RealSpriteGroup *rsg = (const RealSpriteGroup*)sg;
|
||||
@@ -660,26 +704,26 @@ void SpriteGroupDumper::DumpSpriteGroup(const SpriteGroup *sg, const char *paddi
|
||||
}
|
||||
if (dsg == this->top_default_group && !((flags & SGDF_DEFAULT) && strlen(padding) == 2)) {
|
||||
seprintf(this->buffer, lastof(this->buffer), "%sTOP LEVEL DEFAULT GROUP: Deterministic (%s, %s), [%u]",
|
||||
padding, _sg_scope_names[dsg->var_scope], _sg_size_names[dsg->size], dsg->nfo_line);
|
||||
padding, get_scope_name(dsg->var_scope, dsg->var_scope_count), _sg_size_names[dsg->size], dsg->nfo_line);
|
||||
print();
|
||||
return;
|
||||
}
|
||||
if (dsg == this->top_graphics_group && !((flags & SGDF_RANGE) && strlen(padding) == 2)) {
|
||||
seprintf(this->buffer, lastof(this->buffer), "%sTOP LEVEL GRAPHICS GROUP: Deterministic (%s, %s), [%u]",
|
||||
padding, _sg_scope_names[dsg->var_scope], _sg_size_names[dsg->size], dsg->nfo_line);
|
||||
padding, get_scope_name(dsg->var_scope, dsg->var_scope_count), _sg_size_names[dsg->size], dsg->nfo_line);
|
||||
print();
|
||||
return;
|
||||
}
|
||||
auto res = this->seen_dsgs.insert(dsg);
|
||||
if (!res.second) {
|
||||
seprintf(this->buffer, lastof(this->buffer), "%sGROUP SEEN ABOVE: Deterministic (%s, %s), [%u]",
|
||||
padding, _sg_scope_names[dsg->var_scope], _sg_size_names[dsg->size], dsg->nfo_line);
|
||||
padding, get_scope_name(dsg->var_scope, dsg->var_scope_count), _sg_size_names[dsg->size], dsg->nfo_line);
|
||||
print();
|
||||
return;
|
||||
}
|
||||
char *p = this->buffer;
|
||||
p += seprintf(p, lastof(this->buffer), "%sDeterministic (%s, %s)%s [%u]",
|
||||
padding, _sg_scope_names[dsg->var_scope], _sg_size_names[dsg->size], extra_info, dsg->nfo_line);
|
||||
padding, get_scope_name(dsg->var_scope, dsg->var_scope_count), _sg_size_names[dsg->size], extra_info, dsg->nfo_line);
|
||||
if (HasBit(_misc_debug_flags, MDF_NEWGRF_SG_DUMP_MORE_DETAIL)) {
|
||||
if (dsg->dsg_flags & DSGF_NO_DSE) p += seprintf(p, lastof(this->buffer), ", NO_DSE");
|
||||
if (dsg->dsg_flags & DSGF_VAR_TRACKING_PENDING) p += seprintf(p, lastof(this->buffer), ", VAR_PENDING");
|
||||
@@ -752,9 +796,9 @@ void SpriteGroupDumper::DumpSpriteGroup(const SpriteGroup *sg, const char *paddi
|
||||
}
|
||||
}
|
||||
|
||||
seprintf(this->buffer, lastof(this->buffer), "%sRandom (%s, %s, triggers: %X, count: %X, lowest_randbit: %X, groups: %u)%s [%u]",
|
||||
padding, _sg_scope_names[rsg->var_scope], rsg->cmp_mode == RSG_CMP_ANY ? "ANY" : "ALL",
|
||||
rsg->triggers, rsg->count, rsg->lowest_randbit, (uint)rsg->groups.size(), extra_info, rsg->nfo_line);
|
||||
seprintf(this->buffer, lastof(this->buffer), "%sRandom (%s, %s, triggers: %X, lowest_randbit: %X, groups: %u)%s [%u]",
|
||||
padding, get_scope_name(rsg->var_scope, rsg->var_scope_count), rsg->cmp_mode == RSG_CMP_ANY ? "ANY" : "ALL",
|
||||
rsg->triggers, rsg->lowest_randbit, (uint)rsg->groups.size(), extra_info, rsg->nfo_line);
|
||||
print();
|
||||
emit_start();
|
||||
std::string sub_padding(padding);
|
||||
|
Reference in New Issue
Block a user