AGS: fixed object cache may sometimes keep an old dynsprite ref

This may result in object texture not updating if the old sprite was deleted but a new dynamic sprite was created right after having same ID.

Was broken by upstream 9dffb04 in 3.5.1, and also some later changes in 3.6.0.

From upstream 7ed51861898d864902b0f61b0cb7d0acadef1fe3
This commit is contained in:
Thierry Crozat 2022-10-09 23:37:33 +01:00
parent 6163d4880a
commit 483ff1bc30
3 changed files with 11 additions and 6 deletions

View File

@ -603,19 +603,24 @@ void mark_object_changed(int objid) {
_G(objcache)[objid].y = -9999;
}
void reset_objcache_for_sprite(int sprnum) {
// Check if this sprite is assigned to any game object, and update them if necessary
void reset_objcache_for_sprite(int sprnum, bool deleted) {
// Check if this sprite is assigned to any game object, and mark these for update;
// if the sprite was deleted, also dispose shared textures
// room objects cache
if (_G(croom) != nullptr) {
for (size_t i = 0; i < (size_t)_G(croom)->numobj; ++i) {
if (_G(objs)[i].num == sprnum)
if (_G(objcache)[i].sppic == sprnum)
_G(objcache)[i].sppic = -1;
if (deleted && (_GP(actsps)[i].SpriteID == sprnum))
_GP(actsps)[i] = ObjTexture();
}
}
// character cache
for (size_t i = 0; i < (size_t)_GP(game).numcharacters; ++i) {
if (_GP(charcache)[i].sppic == sprnum)
_GP(charcache)[i].sppic = -1;
if (deleted && (_GP(actsps)[ACTSP_OBJSOFF + i].SpriteID == sprnum))
_GP(actsps)[i] = ObjTexture();
}
}

View File

@ -132,7 +132,7 @@ void on_roomcamera_changed(Camera *cam);
// Marks particular object as need to update the texture
void mark_object_changed(int objid);
// Resets all object caches which reference this sprite
void reset_objcache_for_sprite(int sprnum);
void reset_objcache_for_sprite(int sprnum, bool deleted);
// whether there are currently remnants of a DisplaySpeech
void mark_screen_dirty();

View File

@ -1347,7 +1347,7 @@ void game_sprite_updated(int sprnum) {
_G(gfxDriver)->UpdateSharedDDB(sprnum, _GP(spriteset)[sprnum], (_GP(game).SpriteInfos[sprnum].Flags & SPF_ALPHACHANNEL) != 0, false);
// character and object draw caches
reset_objcache_for_sprite(sprnum);
reset_objcache_for_sprite(sprnum, false);
// gui backgrounds
for (auto &gui : _GP(guis)) {
@ -1378,7 +1378,7 @@ void game_sprite_deleted(int sprnum) {
// clear from texture cache
_G(gfxDriver)->ClearSharedDDB(sprnum);
// character and object draw caches
reset_objcache_for_sprite(sprnum);
reset_objcache_for_sprite(sprnum, true);
// room object graphics
if (_G(croom) != nullptr) {
for (size_t i = 0; i < (size_t)_G(croom)->numobj; ++i) {