Update to 1.8.0

--HG--
branch : openttd
This commit is contained in:
Pavel Stupnikov
2018-04-06 21:26:22 +03:00
parent c13f57641c
commit 42ec3bd611
221 changed files with 2325 additions and 1788 deletions

View File

@@ -1,4 +1,4 @@
/* $Id: newgrf_spritegroup.cpp 27600 2016-06-13 17:34:18Z frosch $ */
/* $Id: newgrf_spritegroup.cpp 27989 2018-03-11 15:08:51Z frosch $ */
/*
* This file is part of OpenTTD.
@@ -10,6 +10,7 @@
/** @file newgrf_spritegroup.cpp Handling of primarily NewGRF action 2. */
#include "stdafx.h"
#include <algorithm>
#include "debug.h"
#include "newgrf_spritegroup.h"
#include "core/pool_func.hpp"
@@ -60,11 +61,7 @@ RandomizedSpriteGroup::~RandomizedSpriteGroup()
static inline uint32 GetVariable(const ResolverObject &object, ScopeResolver *scope, byte variable, uint32 parameter, bool *available)
{
/* First handle variables common with Action7/9/D */
uint32 value;
if (GetGlobalVariable(variable, &value, object.grffile)) return value;
/* Non-common variable */
switch (variable) {
case 0x0C: return object.callback;
case 0x10: return object.callback_param1;
@@ -79,18 +76,14 @@ static inline uint32 GetVariable(const ResolverObject &object, ScopeResolver *sc
if (object.grffile == NULL) return 0;
return object.grffile->GetParam(parameter);
/* Not a common variable, so evaluate the feature specific variables */
default: return scope->GetVariable(variable, parameter, available);
default:
/* First handle variables common with Action7/9/D */
if (variable < 0x40 && GetGlobalVariable(variable, &value, object.grffile)) return value;
/* Not a common variable, so evaluate the feature specific variables */
return scope->GetVariable(variable, parameter, available);
}
}
ScopeResolver::ScopeResolver(ResolverObject &ro)
: ro(ro)
{
}
ScopeResolver::~ScopeResolver() {}
/**
* Get a few random bits. Default implementation has no random bits.
* @return Random bits.
@@ -109,12 +102,6 @@ ScopeResolver::~ScopeResolver() {}
return 0;
}
/**
* Set the triggers. Base class implementation does nothing.
* @param triggers Triggers to set.
*/
/* virtual */ void ScopeResolver::SetTriggers(int triggers) const {}
/**
* Get a variable value. Default implementation has no available variables.
* @param variable Variable to read
@@ -136,27 +123,6 @@ ScopeResolver::~ScopeResolver() {}
*/
/* virtual */ void ScopeResolver::StorePSA(uint reg, int32 value) {}
/**
* Resolver constructor.
* @param grffile NewGRF file associated with the object (or \c NULL if none).
* @param callback Callback code being resolved (default value is #CBID_NO_CALLBACK).
* @param callback_param1 First parameter (var 10) of the callback (only used when \a callback is also set).
* @param callback_param2 Second parameter (var 18) of the callback (only used when \a callback is also set).
*/
ResolverObject::ResolverObject(const GRFFile *grffile, CallbackID callback, uint32 callback_param1, uint32 callback_param2)
: default_scope(*this)
{
this->callback = callback;
this->callback_param1 = callback_param1;
this->callback_param2 = callback_param2;
this->ResetState();
this->grffile = grffile;
this->root_spritegroup = NULL;
}
ResolverObject::~ResolverObject() {}
/**
* Get the real sprites of the grf.
* @param group Group to get.
@@ -201,11 +167,9 @@ static U EvalAdjustT(const DeterministicSpriteGroupAdjust *adjust, ScopeResolver
value >>= adjust->shift_num;
value &= adjust->and_mask;
if (adjust->type != DSGA_TYPE_NONE) value += (S)adjust->add_val;
switch (adjust->type) {
case DSGA_TYPE_DIV: value = (S)value / (S)adjust->divmod_val; break;
case DSGA_TYPE_MOD: value = (S)value % (S)adjust->divmod_val; break;
case DSGA_TYPE_DIV: value = ((S)value + (S)adjust->add_val) / (S)adjust->divmod_val; break;
case DSGA_TYPE_MOD: value = ((S)value + (S)adjust->add_val) % (S)adjust->divmod_val; break;
case DSGA_TYPE_NONE: break;
}
@@ -238,6 +202,11 @@ static U EvalAdjustT(const DeterministicSpriteGroupAdjust *adjust, ScopeResolver
}
static bool RangeHighComparator(const DeterministicSpriteGroupRange& range, uint32 value)
{
return range.high < value;
}
const SpriteGroup *DeterministicSpriteGroup::Resolve(ResolverObject &object) const
{
uint32 last_value = 0;
@@ -269,7 +238,7 @@ const SpriteGroup *DeterministicSpriteGroup::Resolve(ResolverObject &object) con
if (!available) {
/* Unsupported variable: skip further processing and return either
* the group from the first range or the default group. */
return SpriteGroup::Resolve(this->num_ranges > 0 ? this->ranges[0].group : this->default_group, object, false);
return SpriteGroup::Resolve(this->error_group, object, false);
}
switch (this->size) {
@@ -283,7 +252,7 @@ const SpriteGroup *DeterministicSpriteGroup::Resolve(ResolverObject &object) con
object.last_value = last_value;
if (this->num_ranges == 0) {
if (this->calculated_result) {
/* nvar == 0 is a special case -- we turn our value into a callback result */
if (value != CALLBACK_FAILED) value = GB(value, 0, 15);
static CallbackResultSpriteGroup nvarzero(0, true);
@@ -291,9 +260,17 @@ const SpriteGroup *DeterministicSpriteGroup::Resolve(ResolverObject &object) con
return &nvarzero;
}
for (i = 0; i < this->num_ranges; i++) {
if (this->ranges[i].low <= value && value <= this->ranges[i].high) {
return SpriteGroup::Resolve(this->ranges[i].group, object, false);
if (this->num_ranges > 4) {
DeterministicSpriteGroupRange *lower = std::lower_bound(this->ranges + 0, this->ranges + this->num_ranges, value, RangeHighComparator);
if (lower != this->ranges + this->num_ranges && lower->low <= value) {
assert(lower->low <= value && value <= lower->high);
return SpriteGroup::Resolve(lower->group, object, false);
}
} else {
for (i = 0; i < this->num_ranges; i++) {
if (this->ranges[i].low <= value && value <= this->ranges[i].high) {
return SpriteGroup::Resolve(this->ranges[i].group, object, false);
}
}
}
@@ -304,21 +281,15 @@ const SpriteGroup *DeterministicSpriteGroup::Resolve(ResolverObject &object) con
const SpriteGroup *RandomizedSpriteGroup::Resolve(ResolverObject &object) const
{
ScopeResolver *scope = object.GetScope(this->var_scope, this->count);
if (object.trigger != 0) {
if (object.callback == CBID_RANDOM_TRIGGER) {
/* Handle triggers */
/* Magic code that may or may not do the right things... */
byte waiting_triggers = scope->GetTriggers();
byte match = this->triggers & (waiting_triggers | object.trigger);
byte match = this->triggers & object.waiting_triggers;
bool res = (this->cmp_mode == RSG_CMP_ANY) ? (match != 0) : (match == this->triggers);
if (res) {
waiting_triggers &= ~match;
object.used_triggers |= match;
object.reseed[this->var_scope] |= (this->num_groups - 1) << this->lowest_randbit;
} else {
waiting_triggers |= object.trigger;
}
scope->SetTriggers(waiting_triggers);
}
uint32 mask = (this->num_groups - 1) << this->lowest_randbit;