Commit Graph
26 Commits
Author SHA1 Message Date
mausimus 8211a5fc25 AGS: fix DynamicSprite.Flip() to use CreateTransparentBitmap 2025-03-09 14:12:20 +02:00
Walter Agazzi 92809e3114 AGS: Engine: rewrote dynamic sprite to texture notification mechanism
The previous attempt, using a boolean spritemodified array, proved to be having logical
loopholes. In simple words, because spritemodified flag was resetting each draw pass, it won't
affect objects that are temporarily not visible, and they failed to reupdate when becoming
visible again. This affected Software renderer.

Texture-based renderers have a different problem, where they fail to recognize when an old
sprite was deleted and a completely new dynamic sprite created accidentally with the same ID.
The cause was simply that the check for this was done inside sync_object_texture(), but
sync_object_texture itself was not called unless draw() function thought that object had
changed. So there has to be a check outside too...

Here I decided to reimplement notification mechanism, and use it for both types of renderers,
for the sake of more straightforward code logic. (Although, strictly speaking, texture-based
renderers could check their texture's "ref id" instead.)

The idea of a new implementation is this:
1. There's a map of "control blocks" per each active sprite (that is - sprite that was drawn as a
part of object). The "control block" is simply a integer with a sprite ID in it, allocated and
wrapped by shared_ptr.
2. When the ObjectTexture syncs its texture with a new sprite, the control block is retrieved (or
new created), and from now on it may be shared among multiple objects which display same
sprite.
3. When the sprite gets either updated or deleted two things happen: the previous control
block is assigned an "invalid value", serving as a marker, and then it is removed from the map,
left only if referenced by any ObjectTexture.
4. When checking whether texture needs to be re-synced we test the control block too, to see
if it was invalidated. In such case this tells us to call sync_object_texture() again.

NOTE that dynamic sprites that do not appear on screen, and are only used for drawing on
another surface, do not allocate control blocks, nor notify anything.

From upstream ab2dd5846075a73e3a3415c45c37fe6b37805964
2024-10-30 18:07:42 +02:00
Walter Agazzi 7af9888de2 AGS: Engine: rewrote dynamic sprite change notification method
Previous existing method ran through virtually all the game objects that may reference a sprite, and
checked each one of them. Those who did reference the modified dynamic sprite were marked for
update and/or had their draw caches cleared.
Furthermore, for safety reasons, the Graphic properties of these objects were reset to 0.

This process was slow under two conditions:
- if there are alot of objects (especially overlays which may be created at runtime in large quantities);
- if there are alot of temporary dynamic sprites created and deleted per game frame (for example,
when drawing something complicated).

The new method:
1. We no longer reset object properties, this turned to be a bad design. There's another safety fix done
in the SpriteCache, which returns a placeholder sprite for any invalid sprite ID. This should make things
simpler and faster.
2. For the texture-based renderers, it turned out that updating the shared texture entries was enough
to make objects using them redraw. So for these renderers we don't need to reset any more caches.
3. For software renderer, introduced a GameState::spritemodified vector of bools. Whenever a sprite is
modified or deleted, engine sets a corresponding flag in this vector, and that triggers an update at the
next draw pass for all the objects that still reference that sprite.

GUI PROBLEM: because GUIs rendering is still different from other objects, even in texture render
mode, they are still marked for update the old way.
This should be addressed separately in the future.
From upstream 0b84a21cfb486e3a9fa03e6c2b354750742ed3fd
and 3f70782761a698a69d31af77833c05bf38eb7394
2024-10-30 18:07:42 +02:00
Walter Agazzi dc30f4e2a8 AGS: Engine: Overlay uses ObjTexture similar to object and chars
+ fix free_dynamic_sprite in previous commit

From upstream 84432448725c77fbd3448a8d9c92e7e44e07a217
2024-10-30 18:07:42 +02:00
Walter Agazzi 2d2755f491 AGS; Engine: changed ScreenOverlay to store owned images as dynamic sprites
From upstream 4728d57086b7eedf112796da011f3c7b0dd3ad30
2024-10-30 18:07:42 +02:00
Walter Agazzi 3078b207d3 AGS: Engine: refactor around add_dynamic_sprite()
* separate variant of add_dynamic_sprite() that searches for the free slot itself,
not requiring user to do this;
* the previously existing variant is used for: replacing modified dynamic sprite
and restoring sprites from save.
* add_dynamic_sprite() accepts unique_ptr<Bitmap>, explicitly saying that the
ownership will be taken by the spriteset.
* sprite info and SPF_* flags are set inside spriteset, instead of hacking them in
add_dynamic_sprite().
* simplified LoadSaveSlotScreenshot()

From upstream 0913f49e4212fea3a48539251ffc1ab92518a231
and aca47b9f466fe41d73d99a15b9f0ae41e65c6926
+ minor changes
2024-10-30 18:07:42 +02:00
Walter Agazzi 7a0876b6b0 AGS: Engine: in CopyScreenIntoBitmap support src rect for legacy letterbox
Partially From upstream 6c028465648be5afe20eef34f0e5d0955329d3dd
2024-10-30 18:07:42 +02:00
Walter Agazzi 73526c8f1c AGS: Engine: add SPF_OBJECTOWNED flag for dyn sprites owned by Overlays
Currently this is only to skip checking them when exiting the game.

Partially from upstream f535a4b7fec65bb00b13c883a0b3e1154509f651
2024-10-30 18:07:42 +02:00
Walter Agazzi 567b5bb54b AGS: Engine: in DynamicSprite.CreateFrom* functions fixup bad sprite size
From upstream 83e78fb1341b6852fb13366bae5aaed340571651
2024-10-30 18:07:42 +02:00
Walter Agazzi 2fbeea1840 AGS: SpriteCache: SetSprite() disposes old sprite in the same slot itself
From upstream 68f1e1a141e53c525b26e8b8f32f81eaa590d299
2024-10-30 18:07:42 +02:00
Walter Agazzi cec77078f6 AGS: Convert several files to new API registering 2024-10-30 18:07:42 +02:00
Walter Agazzi 0f437fb44a AGS: Engine: simplify free_dynamic_sprite(), also don't quit on bad index
From upstream 38eaa36a2422327f6feebe497a44f5205eff7f95
2024-10-30 18:07:42 +02:00
Walter Agazzi 90f94f74c0 AGS: Engine: reduced spriteset's [] operator use where possible
The spriteset's [] operator loads a sprite, but some operations may
 omit that and check the preloaded information instead.
This also makes it more certain where the actual sprite's bitmap is necessary.
From upstream df30fc1edd30d4f334addaf7883286e745dea2c3
2024-10-30 18:07:42 +02:00
Walter Agazzi 3d981f1159 AGS: SpriteCache: separated Remove() and Dispose() methods for convenience
From upstream 92c0f64e47c782e2532760a6b3a10a1b0b5978b6
2024-10-30 18:07:42 +02:00
Walter Agazzi 3a5ccd4cba AGS: Engine: moved dynamic object management functions to a separate unit
From upstream 1a9df937e3ac9eba0c2f5b663507a52569d635e0
2024-10-30 18:07:42 +02:00
Thierry Crozat 4dcde68f4a AGS: Remove unnecessary include of std/math.h 2023-06-06 08:59:58 +01:00
Walter Agazzi bb3e0ed9fe AGS: Engine: in DynamicSprite.Create() adjust invalid sizes to min valid
Historically, this function could *happen* to create bitmaps of
0x0 or even -1x-1 sizes and return a valid DynamicSprite
object. Try to ensure the image library is passed valid
parameters in such case, and keep going, for backwards compatibility.
From upstream 82194b261b4649281742c45498a4c34f452fd350
2023-05-14 23:04:38 +02:00
Walter Agazzi c366ce5eef AGS: Removed update_polled_stuff_if_runtime() from data loading functions
Leave it with a new name as `update_polled_stuff()` only in functions
related to the game update.
From upstream 95dc139f51e704da19792e5480e69bbfe7ec27aa
2023-03-12 20:58:28 +00:00
Thierry Crozat e9c84767f7 AGS: Merged BitmapFlip with engine's GlobalFlipType (same values)
From upstream a747deafe67d536b6bcaf408077ca83f6e61a33d
2022-06-24 20:54:47 +01:00
Paul Gilbert 97c12e8435 AGS: Merged Character and ObjectCache structs, and hid in draw.cpp
From upstream 753d47d975b10666702c47a22cbc4e68847787f1
2022-05-05 22:41:09 -07:00
Paul Gilbert 3b91a1124f AGS: Made internal BitmapFlip enum match the script, for convenience
From upstream 8be85c08ed87a56265d2f18fb798ec463edb3ef7
2022-05-01 17:23:25 -07:00
Paul Gilbert 14cffd13e7 AGS: Use String::NoIndex instead of -1 where necessary
From upstream 56275cb1f58f630082f3f51ab8e2c0ab5b021b16
2022-04-24 16:00:04 -07:00
Paul Gilbert 2d995bbe07 AGS: Simplified use of ReplaceBitmapWithSupportedFormat()
From upstream 2132ba833b9d4508ed3f81a65f531b88f6087cb5
2022-03-14 21:33:38 -07:00
Eugene Sandulenko abea37c9bb ALL: Update ScummVM project license to GPLv3+ 2021-12-26 18:48:43 +01:00
Paul Gilbert 9742dfb163 AGS: Shifting multiple classes to plugins/core/ 2021-07-16 19:48:14 -07:00
Paul Gilbert 701396361c AGS: Import of fresh codebase 2021-06-13 21:08:44 -07:00