VarAction2: Re-use allocated callback result sprite groups
This commit is contained in:
@@ -79,6 +79,8 @@ const std::vector<GRFFile *> &GetAllGRFFiles()
|
|||||||
return _grf_files;
|
return _grf_files;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static btree::btree_map<uint16, const CallbackResultSpriteGroup *> _callback_result_cache;
|
||||||
|
|
||||||
/** Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E */
|
/** Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E */
|
||||||
byte _misc_grf_features = 0;
|
byte _misc_grf_features = 0;
|
||||||
|
|
||||||
@@ -5522,13 +5524,24 @@ static void SkipAct1(ByteReader *buf)
|
|||||||
grfmsg(3, "SkipAct1: Skipping %d sprites", _cur.skip_sprites);
|
grfmsg(3, "SkipAct1: Skipping %d sprites", _cur.skip_sprites);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const CallbackResultSpriteGroup *NewCallbackResultSpriteGroup(uint16 groupid)
|
||||||
|
{
|
||||||
|
uint16 result = CallbackResultSpriteGroup::TransformResultValue(groupid, _cur.grffile->grf_version >= 8);
|
||||||
|
|
||||||
|
const CallbackResultSpriteGroup *&ptr = _callback_result_cache[result];
|
||||||
|
if (ptr == nullptr) {
|
||||||
|
assert(CallbackResultSpriteGroup::CanAllocateItem());
|
||||||
|
ptr = new CallbackResultSpriteGroup(result);
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
/* Helper function to either create a callback or link to a previously
|
/* Helper function to either create a callback or link to a previously
|
||||||
* defined spritegroup. */
|
* defined spritegroup. */
|
||||||
static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
|
static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 groupid)
|
||||||
{
|
{
|
||||||
if (HasBit(groupid, 15)) {
|
if (HasBit(groupid, 15)) {
|
||||||
assert(CallbackResultSpriteGroup::CanAllocateItem());
|
return NewCallbackResultSpriteGroup(groupid);
|
||||||
return new CallbackResultSpriteGroup(groupid, _cur.grffile->grf_version >= 8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == nullptr) {
|
if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == nullptr) {
|
||||||
@@ -5576,8 +5589,7 @@ static const SpriteGroup *GetGroupByID(uint16 groupid)
|
|||||||
static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid)
|
static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte type, uint16 spriteid)
|
||||||
{
|
{
|
||||||
if (HasBit(spriteid, 15)) {
|
if (HasBit(spriteid, 15)) {
|
||||||
assert(CallbackResultSpriteGroup::CanAllocateItem());
|
return NewCallbackResultSpriteGroup(spriteid);
|
||||||
return new CallbackResultSpriteGroup(spriteid, _cur.grffile->grf_version >= 8);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_cur.IsValidSpriteSet(feature, spriteid)) {
|
if (!_cur.IsValidSpriteSet(feature, spriteid)) {
|
||||||
@@ -11195,6 +11207,7 @@ void ResetNewGRFData()
|
|||||||
|
|
||||||
InitializeSoundPool();
|
InitializeSoundPool();
|
||||||
_spritegroup_pool.CleanPool();
|
_spritegroup_pool.CleanPool();
|
||||||
|
_callback_result_cache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -12443,6 +12456,7 @@ void LoadNewGRF(uint load_index, uint num_baseset)
|
|||||||
for (GRFFile * const file : _grf_files) {
|
for (GRFFile * const file : _grf_files) {
|
||||||
file->string_map.clear();
|
file->string_map.clear();
|
||||||
}
|
}
|
||||||
|
_callback_result_cache.clear();
|
||||||
|
|
||||||
/* Call any functions that should be run after GRFs have been loaded. */
|
/* Call any functions that should be run after GRFs have been loaded. */
|
||||||
AfterLoadGRFs();
|
AfterLoadGRFs();
|
||||||
|
@@ -259,7 +259,7 @@ const SpriteGroup *DeterministicSpriteGroup::Resolve(ResolverObject &object) con
|
|||||||
if (this->calculated_result) {
|
if (this->calculated_result) {
|
||||||
/* nvar == 0 is a special case -- we turn our value into a callback result */
|
/* nvar == 0 is a special case -- we turn our value into a callback result */
|
||||||
if (value != CALLBACK_FAILED) value = GB(value, 0, 15);
|
if (value != CALLBACK_FAILED) value = GB(value, 0, 15);
|
||||||
static CallbackResultSpriteGroup nvarzero(0, true);
|
static CallbackResultSpriteGroup nvarzero(0);
|
||||||
nvarzero.result = value;
|
nvarzero.result = value;
|
||||||
return &nvarzero;
|
return &nvarzero;
|
||||||
}
|
}
|
||||||
|
@@ -369,19 +369,25 @@ protected:
|
|||||||
struct CallbackResultSpriteGroup : SpriteGroup {
|
struct CallbackResultSpriteGroup : SpriteGroup {
|
||||||
/**
|
/**
|
||||||
* Creates a spritegroup representing a callback result
|
* Creates a spritegroup representing a callback result
|
||||||
|
* @param result The result as returned from TransformResultValue
|
||||||
|
*/
|
||||||
|
CallbackResultSpriteGroup(uint16 result) :
|
||||||
|
SpriteGroup(SGT_CALLBACK),
|
||||||
|
result(result) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transforms a callback result value
|
||||||
* @param value The value that was used to represent this callback result
|
* @param value The value that was used to represent this callback result
|
||||||
* @param grf_version8 True, if we are dealing with a new NewGRF which uses GRF version >= 8.
|
* @param grf_version8 True, if we are dealing with a new NewGRF which uses GRF version >= 8.
|
||||||
*/
|
*/
|
||||||
CallbackResultSpriteGroup(uint16 value, bool grf_version8) :
|
static uint16 TransformResultValue(uint16 value, bool grf_version8)
|
||||||
SpriteGroup(SGT_CALLBACK),
|
|
||||||
result(value)
|
|
||||||
{
|
{
|
||||||
/* Old style callback results (only valid for version < 8) have the highest byte 0xFF so signify it is a callback result.
|
/* Old style callback results (only valid for version < 8) have the highest byte 0xFF so signify it is a callback result.
|
||||||
* New style ones only have the highest bit set (allows 15-bit results, instead of just 8) */
|
* New style ones only have the highest bit set (allows 15-bit results, instead of just 8) */
|
||||||
if (!grf_version8 && (this->result >> 8) == 0xFF) {
|
if (!grf_version8 && (value >> 8) == 0xFF) {
|
||||||
this->result &= ~0xFF00;
|
return value & ~0xFF00;
|
||||||
} else {
|
} else {
|
||||||
this->result &= ~0x8000;
|
return value & ~0x8000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user