[Scummvm-git-logs] scummvm master -> 191438f3e04523f39b3983c606f02b30cb054a3e
tag2015
noreply at scummvm.org
Mon May 5 12:23:59 UTC 2025
This automated email contains information about 19 new commits which have been
pushed to the 'scummvm' repo located at https://api.github.com/repos/scummvm/scummvm .
Summary:
badff4a21c AGS: Engine: fixed inventory cursor hotspot drawing over 32-bit ARGB sprites
133295ab10 AGS: Updated build version (3.6.1.31 P9)
fe6ffd1d7b AGS: Engine: fix a case when new sprite is matching object graphic property
4bc3dd3cb8 AGS: Engine: correct game process spawning and winsetup exit
c98cb88b8b AGS: Common: fix FontInfo::Outline to be int instead of int8
56bfc02e25 AGS: Common: renamed 2 SpriteCache methods for clarity, add DisposeCached()
730d91625d AGS: Engine: removed couple of unused variables
96b245ffbd AGS: Updated build version (3.6.1.32 P10)
cba7ba2359 AGS: Common: fix empty string handling in StrUtil::StringTo*() functions
d73386c543 AGS: Engine: fix Button resized to sprite 0 if NormalGraphic set to 0
5148aa9c6e AGS: Engine: removed redundant fonts_engine.cpp
26e8b6b0b1 AGS: Engine: fix more warnings related to type comparisons
04fbffa9d2 AGS: Engine: hotfix translation entries were limited to 1024 bytes
594a7abd27 AGS: Engine: fixed a crash when running invitem 0 interaction, add checks
a5f5d74f05 AGS: Engine: fixed move speed recalc in case of a 45-deg diagonal movement
37798d7e0b AGS: Engine: fixed 8-bit fade effect not having a frame delay
72fd04e46a AGS: Add parenthesis, fix warning
7f60d6618e AGS: Engine: fix solid char gets ignored when inside walking char's zone
191438f3e0 AGS: Engine: fixed old room script run if a room was changed in on_event()
Commit: badff4a21c2236a825bb35cf8ab588eab0c93fe3
https://github.com/scummvm/scummvm/commit/badff4a21c2236a825bb35cf8ab588eab0c93fe3
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2025-05-05T14:23:17+02:00
Commit Message:
AGS: Engine: fixed inventory cursor hotspot drawing over 32-bit ARGB sprites
>From upstream 5628477ec7b366a5d6355dc77d241629ce194820
Changed paths:
engines/ags/engine/ac/draw.cpp
engines/ags/engine/ac/draw.h
engines/ags/engine/ac/mouse.cpp
diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp
index 6b4893ba5a7..117a9e23a6a 100644
--- a/engines/ags/engine/ac/draw.cpp
+++ b/engines/ags/engine/ac/draw.cpp
@@ -778,13 +778,8 @@ void draw_game_screen_callback() {
construct_game_screen_overlay(false);
}
-void putpixel_compensate(Bitmap *ds, int xx, int yy, int col) {
- if ((ds->GetColorDepth() == 32) && (col != 0)) {
- // ensure the alpha channel is preserved if it has one
- int alphaval = geta32(ds->GetPixel(xx, yy));
- col = makeacol32(getr32(col), getg32(col), getb32(col), alphaval);
- }
- ds->FillRect(Rect(xx, yy, xx + get_fixed_pixel_size(1) - 1, yy + get_fixed_pixel_size(1) - 1), col);
+void putpixel_scaled(Bitmap *ds, int x, int y, int col) {
+ ds->FillRect(Rect(x, y, x + get_fixed_pixel_size(1) - 1, y + get_fixed_pixel_size(1) - 1), col);
}
void draw_sprite_support_alpha(Bitmap *ds, bool ds_has_alpha, int xpos, int ypos, Bitmap *image, bool src_has_alpha,
diff --git a/engines/ags/engine/ac/draw.h b/engines/ags/engine/ac/draw.h
index 6766662f61e..105e2f65f2f 100644
--- a/engines/ags/engine/ac/draw.h
+++ b/engines/ags/engine/ac/draw.h
@@ -242,7 +242,9 @@ void draw_sprite_slot_support_alpha(Shared::Bitmap *ds, bool ds_has_alpha, int x
void draw_gui_sprite(Shared::Bitmap *ds, int pic, int x, int y, bool use_alpha = true, Shared::BlendMode blend_mode = Shared::kBlendMode_Alpha);
void draw_gui_sprite_v330(Shared::Bitmap *ds, int pic, int x, int y, bool use_alpha = true, Shared::BlendMode blend_mode = Shared::kBlendMode_Alpha);
void draw_gui_sprite(Shared::Bitmap *ds, bool use_alpha, int xpos, int ypos,
- Shared::Bitmap *image, bool src_has_alpha, Shared::BlendMode blend_mode = Shared::kBlendMode_Alpha, int alpha = 0xFF);
+ Shared::Bitmap *image, bool src_has_alpha, Shared::BlendMode blend_mode = Shared::kBlendMode_Alpha, int alpha = 0xFF);
+// Puts a pixel of certain color, scales it if running in upscaled resolution (legacy feature)
+void putpixel_scaled(Shared::Bitmap *ds, int x, int y, int col);
// Render game on screen
void render_to_screen();
@@ -250,7 +252,7 @@ void render_to_screen();
void draw_game_screen_callback();
void GfxDriverOnInitCallback(void *data);
bool GfxDriverSpriteEvtCallback(int evt, int data);
-void putpixel_compensate(Shared::Bitmap *g, int xx, int yy, int col);
+
// Create the actsps[objid] image with the object drawn correctly.
// Returns true if nothing at all has changed and actsps is still
// intact from last time; false otherwise.
diff --git a/engines/ags/engine/ac/mouse.cpp b/engines/ags/engine/ac/mouse.cpp
index 65721178002..451390aeba0 100644
--- a/engines/ags/engine/ac/mouse.cpp
+++ b/engines/ags/engine/ac/mouse.cpp
@@ -133,15 +133,15 @@ void set_mouse_cursor(int newcurs, bool force_update) {
hotspoty - _GP(game).SpriteInfos[_GP(game).invhotdotsprite].Height / 2,
_GP(game).invhotdotsprite);
} else {
- putpixel_compensate(_G(dotted_mouse_cursor), hotspotx, hotspoty, MakeColor(_GP(game).hotdot));
+ putpixel_scaled(_G(dotted_mouse_cursor), hotspotx, hotspoty, MakeColor(_GP(game).hotdot));
if (_GP(game).hotdotouter > 0) {
- int outercol = MakeColor(_GP(game).hotdotouter);
+ const int outercol = MakeColor(_GP(game).hotdotouter);
- putpixel_compensate(_G(dotted_mouse_cursor), hotspotx + get_fixed_pixel_size(1), hotspoty, outercol);
- putpixel_compensate(_G(dotted_mouse_cursor), hotspotx, hotspoty + get_fixed_pixel_size(1), outercol);
- putpixel_compensate(_G(dotted_mouse_cursor), hotspotx - get_fixed_pixel_size(1), hotspoty, outercol);
- putpixel_compensate(_G(dotted_mouse_cursor), hotspotx, hotspoty - get_fixed_pixel_size(1), outercol);
+ putpixel_scaled(_G(dotted_mouse_cursor), hotspotx + get_fixed_pixel_size(1), hotspoty, outercol);
+ putpixel_scaled(_G(dotted_mouse_cursor), hotspotx, hotspoty + get_fixed_pixel_size(1), outercol);
+ putpixel_scaled(_G(dotted_mouse_cursor), hotspotx - get_fixed_pixel_size(1), hotspoty, outercol);
+ putpixel_scaled(_G(dotted_mouse_cursor), hotspotx, hotspoty - get_fixed_pixel_size(1), outercol);
}
}
_G(mousecurs)[0] = _G(dotted_mouse_cursor);
Commit: 133295ab10ed2c120f7bf6c9ae4b79a278f12a9b
https://github.com/scummvm/scummvm/commit/133295ab10ed2c120f7bf6c9ae4b79a278f12a9b
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2025-05-05T14:23:17+02:00
Commit Message:
AGS: Updated build version (3.6.1.31 P9)
Partially from upstream 50da366d94f6ac0c04104290d9a153103beef87d
Changed paths:
engines/ags/shared/core/def_version.h
diff --git a/engines/ags/shared/core/def_version.h b/engines/ags/shared/core/def_version.h
index 42aca660019..7502405ba74 100644
--- a/engines/ags/shared/core/def_version.h
+++ b/engines/ags/shared/core/def_version.h
@@ -22,9 +22,9 @@
#ifndef AGS_SHARED_CORE_DEFVERSION_H
#define AGS_SHARED_CORE_DEFVERSION_H
-#define ACI_VERSION_STR "3.6.1.30"
+#define ACI_VERSION_STR "3.6.1.31"
#if defined (RC_INVOKED) // for MSVC resource compiler
-#define ACI_VERSION_MSRC_DEF 3.6.1.30
+#define ACI_VERSION_MSRC_DEF 3.6.1.31
#endif
#define SPECIAL_VERSION ""
Commit: fe6ffd1d7b36a42f2ec537cc53d002383311bb0b
https://github.com/scummvm/scummvm/commit/fe6ffd1d7b36a42f2ec537cc53d002383311bb0b
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2025-05-05T14:23:17+02:00
Commit Message:
AGS: Engine: fix a case when new sprite is matching object graphic property
Another problem with dynamic sprite since 3.6.1...
Case:
- an object has a dynamic sprite assigned;
- dynamic sprite gets deleted, object redrawn, its texture updated etc,
all good (displays safe placeholder);
- new dynamic sprite created, with same index by coincidence,
and assigned to the object;
- object fails to redraw, because sprite's number is the same as saved
in property value, and there's no notification on sprite *creation*.
Solution:
- make a "sprite updated" notification on sprite creation too.
>From upstream 1a565d48d71031dcc7bb93286c367682bb58167b
Changed paths:
engines/ags/engine/ac/dynamic_sprite.cpp
engines/ags/engine/ac/game.cpp
diff --git a/engines/ags/engine/ac/dynamic_sprite.cpp b/engines/ags/engine/ac/dynamic_sprite.cpp
index 804694d534e..455b3445179 100644
--- a/engines/ags/engine/ac/dynamic_sprite.cpp
+++ b/engines/ags/engine/ac/dynamic_sprite.cpp
@@ -112,7 +112,6 @@ void DynamicSprite_Resize(ScriptDynamicSprite *sds, int width, int height) {
RectWH(0, 0, width, height));
add_dynamic_sprite(sds->slot, std::move(new_pic), (_GP(game).SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0);
- game_sprite_updated(sds->slot);
}
void DynamicSprite_Flip(ScriptDynamicSprite *sds, int direction) {
@@ -129,7 +128,6 @@ void DynamicSprite_Flip(ScriptDynamicSprite *sds, int direction) {
new_pic->FlipBlt(sprite, 0, 0, static_cast<GraphicFlip>(direction));
add_dynamic_sprite(sds->slot, std::move(new_pic), (_GP(game).SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0);
- game_sprite_updated(sds->slot);
}
void DynamicSprite_CopyTransparencyMask(ScriptDynamicSprite *sds, int sourceSprite) {
@@ -157,7 +155,6 @@ void DynamicSprite_CopyTransparencyMask(ScriptDynamicSprite *sds, int sourceSpri
}
BitmapHelper::CopyTransparency(target, source, dst_has_alpha, src_has_alpha);
- game_sprite_updated(sds->slot);
}
void DynamicSprite_ChangeCanvasSize(ScriptDynamicSprite *sds, int width, int height, int x, int y) {
@@ -176,7 +173,6 @@ void DynamicSprite_ChangeCanvasSize(ScriptDynamicSprite *sds, int width, int hei
// replace the bitmap in the sprite set
add_dynamic_sprite(sds->slot, std::move(new_pic), (_GP(game).SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0);
- game_sprite_updated(sds->slot);
}
void DynamicSprite_Crop(ScriptDynamicSprite *sds, int x1, int y1, int width, int height) {
@@ -198,7 +194,6 @@ void DynamicSprite_Crop(ScriptDynamicSprite *sds, int x1, int y1, int width, int
// replace the bitmap in the sprite set
add_dynamic_sprite(sds->slot, std::move(new_pic), (_GP(game).SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0);
- game_sprite_updated(sds->slot);
}
void DynamicSprite_Rotate(ScriptDynamicSprite *sds, int angle, int width, int height) {
@@ -239,7 +234,6 @@ void DynamicSprite_Rotate(ScriptDynamicSprite *sds, int angle, int width, int he
// replace the bitmap in the sprite set
add_dynamic_sprite(sds->slot, std::move(new_pic), (_GP(game).SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0);
- game_sprite_updated(sds->slot);
}
void DynamicSprite_Tint(ScriptDynamicSprite *sds, int red, int green, int blue, int saturation, int luminance) {
@@ -249,7 +243,6 @@ void DynamicSprite_Tint(ScriptDynamicSprite *sds, int red, int green, int blue,
tint_image(new_pic.get(), source, red, green, blue, saturation, (luminance * 25) / 10);
add_dynamic_sprite(sds->slot, std::move(new_pic), (_GP(game).SpriteInfos[sds->slot].Flags & SPF_ALPHACHANNEL) != 0);
- game_sprite_updated(sds->slot);
}
int DynamicSprite_SaveToFile(ScriptDynamicSprite *sds, const char *namm) {
@@ -447,6 +440,11 @@ int add_dynamic_sprite(int slot, std::unique_ptr<Bitmap> image, bool has_alpha,
if(!_GP(spriteset).SetSprite(slot, std::move(image), flags))
return 0; // failed to add the sprite, bad image or realloc failed
+
+ // Notify a new (normal) dynamic sprite in case some objects
+ // have this number assigned to their Graphic property
+ if ((extra_flags & SPF_OBJECTOWNED) == 0)
+ game_sprite_updated(slot);
return slot;
}
diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp
index e80d693f417..38ab365ae61 100644
--- a/engines/ags/engine/ac/game.cpp
+++ b/engines/ags/engine/ac/game.cpp
@@ -1335,6 +1335,8 @@ void game_sprite_updated(int sprnum, bool deleted) {
// GUI still have a special draw route, so cannot rely on object caches;
// will have to do a per-GUI and per-control check.
+ // TODO: devise a way to speed this iteration up, perhaps link GUI objects
+ // to the sprite notification block somehow, etc...?
//
// gui backgrounds
for (auto &gui : _GP(guis)) {
Commit: 4bc3dd3cb864e4db43670a0cd0677244d7b90a8d
https://github.com/scummvm/scummvm/commit/4bc3dd3cb864e4db43670a0cd0677244d7b90a8d
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2025-05-05T14:23:17+02:00
Commit Message:
AGS: Engine: correct game process spawning and winsetup exit
This has no effect in ScummVM
>From upstream f758cf796dc7f6a59caa57b3c2581d47ffdf42f7
Changed paths:
engines/ags/engine/main/engine.cpp
diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp
index 018ab96764c..971ed4bb650 100644
--- a/engines/ags/engine/main/engine.cpp
+++ b/engines/ags/engine/main/engine.cpp
@@ -138,8 +138,7 @@ static void fill_game_properties(StringOrderMap &map) {
// Starts up setup application, if capable.
// Returns TRUE if should continue running the game, otherwise FALSE.
-bool engine_run_setup(const ConfigTree &cfg, int &app_res) {
- app_res = EXIT_NORMAL;
+bool engine_run_setup(const ConfigTree &cfg) {
#if AGS_PLATFORM_OS_WINDOWS
{
Debug::Printf(kDbgMsg_Info, "Running Setup");
@@ -161,15 +160,10 @@ bool engine_run_setup(const ConfigTree &cfg, int &app_res) {
if (res != kSetup_RunGame)
return false;
- // TODO: investigate if the full program restart may (should) be avoided
-
- // Just re-reading the config file seems to cause a caching
- // problem on Win9x, so let's restart the process.
- sys_main_shutdown();
- allegro_exit();
- char quotedpath[MAX_PATH];
- snprintf(quotedpath, MAX_PATH, "\"%s\"", _G(appPath).GetCStr());
- _spawnl(_P_OVERLAY, _G(appPath), quotedpath, NULL);
+ // Start the game in the new process, and close the current one afterwards
+ String args = String::FromFormat("\"%s\"", appPath.GetCStr());
+ _spawnl(_P_NOWAIT, appPath.GetCStr(), args.GetCStr(), NULL);
+ return false;
}
#endif
return true;
@@ -1062,9 +1056,8 @@ int initialize_engine(const ConfigTree &startup_opts) {
engine_prepare_config(cfg, startup_opts);
// Test if need to run built-in setup program (where available)
if (!_G(justTellInfo) && _G(justRunSetup)) {
- int res;
- if (!engine_run_setup(cfg, res))
- return res;
+ if (!engine_run_setup(cfg))
+ return EXIT_NORMAL;
}
// Set up game options from user config
engine_set_config(cfg);
Commit: c98cb88b8b180aa5eb5c586e48c6638833f4340b
https://github.com/scummvm/scummvm/commit/c98cb88b8b180aa5eb5c586e48c6638833f4340b
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2025-05-05T14:23:17+02:00
Commit Message:
AGS: Common: fix FontInfo::Outline to be int instead of int8
Firstly, the outline font index is int32, and that's how it is saved in
the game data now since v3.5.0.
Secondly, there are platforms where "char" is an unsigned type,
which causes conflicts with the outline constants which have negative values.
>From upstream 18f9d9e9f67d1af2f0a38ea60dc14f5ff97633b5
Changed paths:
engines/ags/shared/ac/game_struct_defines.h
diff --git a/engines/ags/shared/ac/game_struct_defines.h b/engines/ags/shared/ac/game_struct_defines.h
index 43aa0d57b30..dcef2c04651 100644
--- a/engines/ags/shared/ac/game_struct_defines.h
+++ b/engines/ags/shared/ac/game_struct_defines.h
@@ -278,7 +278,7 @@ struct FontInfo {
// Factor to multiply base font size by
int SizeMultiplier;
// Outlining font index, or auto-outline flag
- int8 Outline;
+ int Outline;
// Custom vertical render offset, used mainly for fixing broken fonts
int YOffset;
// Custom line spacing between two lines of text (0 = use font height)
Commit: 56bfc02e25287f0d46f889857ced682bb9d83106
https://github.com/scummvm/scummvm/commit/56bfc02e25287f0d46f889857ced682bb9d83106
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2025-05-05T14:23:17+02:00
Commit Message:
AGS: Common: renamed 2 SpriteCache methods for clarity, add DisposeCached()
>From upstream 69d3881792a11bd3a3b6044983afd103f91fed14
Changed paths:
engines/ags/engine/ac/dynamic_sprite.cpp
engines/ags/engine/ac/room.cpp
engines/ags/shared/ac/sprite_cache.cpp
engines/ags/shared/ac/sprite_cache.h
diff --git a/engines/ags/engine/ac/dynamic_sprite.cpp b/engines/ags/engine/ac/dynamic_sprite.cpp
index 455b3445179..1a58c783613 100644
--- a/engines/ags/engine/ac/dynamic_sprite.cpp
+++ b/engines/ags/engine/ac/dynamic_sprite.cpp
@@ -455,7 +455,7 @@ void free_dynamic_sprite(int slot, bool notify_all) {
(_GP(game).SpriteInfos[slot].Flags & SPF_DYNAMICALLOC) == 0)
return;
- _GP(spriteset).DisposeSprite(slot);
+ _GP(spriteset).DeleteSprite(slot);
if (notify_all)
game_sprite_updated(slot, true);
}
diff --git a/engines/ags/engine/ac/room.cpp b/engines/ags/engine/ac/room.cpp
index c5a85f05def..d68c7e73435 100644
--- a/engines/ags/engine/ac/room.cpp
+++ b/engines/ags/engine/ac/room.cpp
@@ -900,7 +900,7 @@ void new_room(int newnum, CharacterInfo *forchar) {
if (_GP(usetup).clear_cache_on_room_change) {
// Delete all cached sprites
- _GP(spriteset).DisposeAllCached();
+ _GP(spriteset).DisposeAllFreeCached();
}
load_new_room(newnum, forchar);
diff --git a/engines/ags/shared/ac/sprite_cache.cpp b/engines/ags/shared/ac/sprite_cache.cpp
index 001c2da65b5..5d66b68557a 100644
--- a/engines/ags/shared/ac/sprite_cache.cpp
+++ b/engines/ags/shared/ac/sprite_cache.cpp
@@ -114,7 +114,7 @@ bool SpriteCache::SetSprite(sprkey_t index, std::unique_ptr<Bitmap> image, int f
return false;
}
if (!image || image->GetSize().IsNull() || image->GetColorDepth() <= 0) {
- DisposeSprite(index); // free previous item in this slot anyway
+ DeleteSprite(index); // free previous item in this slot anyway
Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "SetSprite: attempt to assign an invalid bitmap to index %d", index);
return false;
}
@@ -148,7 +148,7 @@ Bitmap *SpriteCache::RemoveSprite(sprkey_t index) {
return image;
}
-void SpriteCache::DisposeSprite(sprkey_t index) {
+void SpriteCache::DeleteSprite(sprkey_t index) {
assert(index >= 0); // out of positive range indexes are valid to fail
if (index < 0 || (size_t)index >= _spriteData.size())
return;
@@ -245,7 +245,7 @@ void SpriteCache::FreeMem(size_t space) {
DisposeOldest();
if (tries > 1000) { // ???
Debug::Printf(kDbgGroup_SprCache, kDbgMsg_Error, "RUNTIME CACHE ERROR: STUCK IN FREE_UP_MEM; RESETTING CACHE");
- DisposeAllCached();
+ DisposeAllFreeCached();
}
}
}
@@ -285,7 +285,15 @@ void SpriteCache::DisposeOldest() {
_spriteData[sprnum].MruIt._node = nullptr;
}
-void SpriteCache::DisposeAllCached() {
+void SpriteCache::DisposeCached(sprkey_t index) {
+ if (IsAssetSprite(index)) {
+ _spriteData[index].Flags &= ~SPRCACHEFLAG_LOCKED;
+ _spriteData[index].Image.reset();
+ }
+ _cacheSize = _lockedSize;
+}
+
+void SpriteCache::DisposeAllFreeCached() {
for (size_t i = 0; i < _spriteData.size(); ++i) {
if (!_spriteData[i].IsLocked() && // not locked
_spriteData[i].IsAssetSprite()) // sprite from game resource
diff --git a/engines/ags/shared/ac/sprite_cache.h b/engines/ags/shared/ac/sprite_cache.h
index 997278497a9..fd097a8a76c 100644
--- a/engines/ags/shared/ac/sprite_cache.h
+++ b/engines/ags/shared/ac/sprite_cache.h
@@ -153,10 +153,15 @@ public:
// Unregisters sprite from the bank and returns the bitmap
Bitmap *RemoveSprite(sprkey_t index);
// Deletes particular sprite, marks slot as unused
- void DisposeSprite(sprkey_t index);
- // Deletes all loaded asset (non-locked, non-external) images from the cache;
- // this keeps all the auxiliary sprite information intact
- void DisposeAllCached();
+ void DeleteSprite(sprkey_t index);
+ // Deletes a loaded asset image (non-external) from memory, ignoring its
+ // locked status; this keeps an auxiliary sprite information intact,
+ // so that the same sprite can be cached back later.
+ void DisposeCached(sprkey_t index);
+ // Deletes all free cached asset images (non-locked, non-external)
+ // from memory; this keeps all the auxiliary sprite information intact,
+ // so that the same sprite(s) can be cached back later.
+ void DisposeAllFreeCached();
// Deletes all data and resets cache to the clear state
void Reset();
// Assigns new sprite for the given index; this sprite won't be auto disposed.
Commit: 730d91625d966fea9144d2d035e28f66d204b856
https://github.com/scummvm/scummvm/commit/730d91625d966fea9144d2d035e28f66d204b856
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2025-05-05T14:23:17+02:00
Commit Message:
AGS: Engine: removed couple of unused variables
>From upstream 349030122a811faba7e7631f35727e56bacbb84a
Changed paths:
engines/ags/engine/main/engine.cpp
engines/ags/globals.h
diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp
index 971ed4bb650..bb406b57fd9 100644
--- a/engines/ags/engine/main/engine.cpp
+++ b/engines/ags/engine/main/engine.cpp
@@ -756,7 +756,6 @@ void engine_init_game_settings() {
update_invorder();
_G(displayed_room) = -10;
- _G(currentcursor) = 0;
set_our_eip(-4);
_G(mousey) = 100; // stop icon bar popping up
diff --git a/engines/ags/globals.h b/engines/ags/globals.h
index 6afa7dfb9eb..5dacdcb85e8 100644
--- a/engines/ags/globals.h
+++ b/engines/ags/globals.h
@@ -1148,13 +1148,12 @@ public:
* @{
*/
- int8 _currentcursor = 0;
// virtual mouse cursor coordinates
int _mousex = 0, _mousey = 0, _numcurso = -1, _hotx = 0, _hoty = 0;
// real mouse coordinates and bounds (in window coords)
int _real_mouse_x = 0, _real_mouse_y = 0;
int _boundx1 = 0, _boundx2 = 99999, _boundy1 = 0, _boundy2 = 99999;
- int8 _ignore_bounds = 0;
+ int _ignore_bounds = 0; // FIXME: this currently works as a counter, not bool?
AGS::Shared::Bitmap *_mousecurs[MAXCURSORS];
ScriptMouse *_scmouse;
Commit: 96b245ffbd20f6cd526be759869c960b65934066
https://github.com/scummvm/scummvm/commit/96b245ffbd20f6cd526be759869c960b65934066
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2025-05-05T14:23:17+02:00
Commit Message:
AGS: Updated build version (3.6.1.32 P10)
Partially from upstream d83c1e396cd151904aab9bda08718f04b5e7a8bc
Changed paths:
engines/ags/shared/core/def_version.h
diff --git a/engines/ags/shared/core/def_version.h b/engines/ags/shared/core/def_version.h
index 7502405ba74..87ca448cef1 100644
--- a/engines/ags/shared/core/def_version.h
+++ b/engines/ags/shared/core/def_version.h
@@ -22,9 +22,9 @@
#ifndef AGS_SHARED_CORE_DEFVERSION_H
#define AGS_SHARED_CORE_DEFVERSION_H
-#define ACI_VERSION_STR "3.6.1.31"
+#define ACI_VERSION_STR "3.6.1.32"
#if defined (RC_INVOKED) // for MSVC resource compiler
-#define ACI_VERSION_MSRC_DEF 3.6.1.31
+#define ACI_VERSION_MSRC_DEF 3.6.1.32
#endif
#define SPECIAL_VERSION ""
Commit: cba7ba2359439d8e761d51ffb3ecd069c744d896
https://github.com/scummvm/scummvm/commit/cba7ba2359439d8e761d51ffb3ecd069c744d896
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2025-05-05T14:23:17+02:00
Commit Message:
AGS: Common: fix empty string handling in StrUtil::StringTo*() functions
>From upstream 56445dfa1c8f99bbf56ca963f3709aad03068dfa
Changed paths:
engines/ags/shared/util/string_utils.cpp
diff --git a/engines/ags/shared/util/string_utils.cpp b/engines/ags/shared/util/string_utils.cpp
index 8b93a52910f..a0f0813d0c6 100644
--- a/engines/ags/shared/util/string_utils.cpp
+++ b/engines/ags/shared/util/string_utils.cpp
@@ -40,7 +40,7 @@ String StrUtil::IntToString(int d) {
}
int StrUtil::StringToInt(const String &s, int def_val) {
- if (!s.GetCStr())
+ if (s.IsEmpty())
return def_val;
char *stop_ptr;
int val = strtol(s.GetCStr(), &stop_ptr, 0);
@@ -49,7 +49,7 @@ int StrUtil::StringToInt(const String &s, int def_val) {
StrUtil::ConversionError StrUtil::StringToInt(const String &s, int &val, int def_val) {
val = def_val;
- if (!s.GetCStr())
+ if (s.IsEmpty())
return StrUtil::kFailed;
char *stop_ptr;
_G(errnum) = 0;
@@ -63,7 +63,7 @@ StrUtil::ConversionError StrUtil::StringToInt(const String &s, int &val, int def
}
float StrUtil::StringToFloat(const String &s, float def_val) {
- if (!s.GetCStr())
+ if (s.IsEmpty())
return def_val;
char *stop_ptr;
float val = strtof(s.GetCStr(), &stop_ptr);
Commit: d73386c5435c634e2154ad99c4c4de0a8c6d4111
https://github.com/scummvm/scummvm/commit/d73386c5435c634e2154ad99c4c4de0a8c6d4111
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2025-05-05T14:23:18+02:00
Commit Message:
AGS: Engine: fix Button resized to sprite 0 if NormalGraphic set to 0
It's supposed to become a standard colored button, so no resize is needed.
>From upstream 89b127a2bf19e1ac6284505a38d429bead8ce7e5
Changed paths:
engines/ags/engine/ac/button.cpp
diff --git a/engines/ags/engine/ac/button.cpp b/engines/ags/engine/ac/button.cpp
index bf97c0bf094..7121fe46633 100644
--- a/engines/ags/engine/ac/button.cpp
+++ b/engines/ags/engine/ac/button.cpp
@@ -149,7 +149,7 @@ int Button_GetMouseOverGraphic(GUIButton *butt) {
void Button_SetMouseOverGraphic(GUIButton *guil, int slotn) {
debug_script_log("GUI %d Button %d mouseover set to slot %d", guil->ParentId, guil->Id, slotn);
-
+ slotn = std::max(0, slotn);
guil->SetMouseOverImage(slotn);
FindAndRemoveButtonAnimation(guil->ParentId, guil->Id);
}
@@ -158,24 +158,22 @@ int Button_GetNormalGraphic(GUIButton *butt) {
return butt->GetNormalImage();
}
-void Button_SetNormalGraphic(GUIButton *guil, int slotn) {
- debug_script_log("GUI %d Button %d normal set to slot %d", guil->ParentId, guil->Id, slotn);
- // update the clickable area to the same size as the graphic
- int width, height;
- if (slotn < 0 || (size_t)slotn >= _GP(game).SpriteInfos.size()) {
- width = 0;
- height = 0;
- } else {
- width = _GP(game).SpriteInfos[slotn].Width;
- height = _GP(game).SpriteInfos[slotn].Height;
+void Button_SetNormalGraphic(GUIButton *butt, int slotn) {
+ debug_script_log("GUI %d Button %d normal set to slot %d", butt->ParentId, butt->Id, slotn);
+ slotn = std::max(0, slotn);
+ // NormalGraphic = 0 will turn the Button into a standard colored button
+ if (slotn == 0) {
+ butt->SetNormalImage(slotn);
}
-
- if ((slotn != guil->GetNormalImage()) || (width != guil->GetWidth()) || (height != guil->GetHeight())) {
- guil->SetNormalImage(slotn);
- guil->SetSize(width, height);
+ // Any other sprite - update the clickable area to the same size as the graphic
+ else {
+ const int width = slotn < (int)_GP(game).SpriteInfos.size() ? _GP(game).SpriteInfos[slotn].Width : 0;
+ const int height = slotn < (int)_GP(game).SpriteInfos.size() ? _GP(game).SpriteInfos[slotn].Height : 0;
+ butt->SetNormalImage(slotn);
+ butt->SetSize(width, height);
}
- FindAndRemoveButtonAnimation(guil->ParentId, guil->Id);
+ FindAndRemoveButtonAnimation(butt->ParentId, butt->Id);
}
int Button_GetPushedGraphic(GUIButton *butt) {
@@ -184,7 +182,7 @@ int Button_GetPushedGraphic(GUIButton *butt) {
void Button_SetPushedGraphic(GUIButton *guil, int slotn) {
debug_script_log("GUI %d Button %d pushed set to slot %d", guil->ParentId, guil->Id, slotn);
-
+ slotn = std::max(0, slotn);
guil->SetPushedImage(slotn);
FindAndRemoveButtonAnimation(guil->ParentId, guil->Id);
}
Commit: 5148aa9c6e208bbc72cd1db4f030c3d280b9cf3b
https://github.com/scummvm/scummvm/commit/5148aa9c6e208bbc72cd1db4f030c3d280b9cf3b
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2025-05-05T14:23:18+02:00
Commit Message:
AGS: Engine: removed redundant fonts_engine.cpp
>From upstream 08ebf49de4cdad3c46396a6dc7b0648a307c59da
Changed paths:
R engines/ags/engine/font/fonts_engine.cpp
engines/ags/module.mk
diff --git a/engines/ags/engine/font/fonts_engine.cpp b/engines/ags/engine/font/fonts_engine.cpp
deleted file mode 100644
index b6d5c0ecdbe..00000000000
--- a/engines/ags/engine/font/fonts_engine.cpp
+++ /dev/null
@@ -1,33 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-//=============================================================================
-//
-// Implementation from acfonts.cpp specific to Engine runtime
-//
-//=============================================================================
-
-//include <alfont.h>
-#include "ags/shared/ac/game_setup_struct.h"
-
-namespace AGS3 {
-
-} // namespace AGS3
diff --git a/engines/ags/module.mk b/engines/ags/module.mk
index 93483d90d08..43cce99c107 100644
--- a/engines/ags/module.mk
+++ b/engines/ags/module.mk
@@ -228,7 +228,6 @@ MODULE_OBJS = \
engine/debugging/log_file.o \
engine/debugging/message_buffer.o \
engine/device/mouse_w32.o \
- engine/font/fonts_engine.o \
engine/game/game_init.o \
engine/game/savegame.o \
engine/game/savegame_components.o \
Commit: 26e8b6b0b1c49308f5501a69a248d9fbba1be2a6
https://github.com/scummvm/scummvm/commit/26e8b6b0b1c49308f5501a69a248d9fbba1be2a6
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2025-05-05T14:23:18+02:00
Commit Message:
AGS: Engine: fix more warnings related to type comparisons
>From upstream 97920fdaf9a3f65d059c57be901f63619d4daf3f
Changed paths:
engines/ags/engine/ac/button.cpp
engines/ags/engine/ac/game.cpp
engines/ags/engine/ac/screen_overlay.cpp
engines/ags/engine/game/savegame.cpp
engines/ags/plugins/ags_plugin.cpp
engines/ags/plugins/plugin_engine.h
diff --git a/engines/ags/engine/ac/button.cpp b/engines/ags/engine/ac/button.cpp
index 7121fe46633..f27b7e008ab 100644
--- a/engines/ags/engine/ac/button.cpp
+++ b/engines/ags/engine/ac/button.cpp
@@ -167,8 +167,8 @@ void Button_SetNormalGraphic(GUIButton *butt, int slotn) {
}
// Any other sprite - update the clickable area to the same size as the graphic
else {
- const int width = slotn < (int)_GP(game).SpriteInfos.size() ? _GP(game).SpriteInfos[slotn].Width : 0;
- const int height = slotn < (int)_GP(game).SpriteInfos.size() ? _GP(game).SpriteInfos[slotn].Height : 0;
+ const int width = static_cast<size_t>(slotn) < _GP(game).SpriteInfos.size() ? _GP(game).SpriteInfos[slotn].Width : 0;
+ const int height = static_cast<size_t>(slotn) < _GP(game).SpriteInfos.size() ? _GP(game).SpriteInfos[slotn].Height : 0;
butt->SetNormalImage(slotn);
butt->SetSize(width, height);
}
diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp
index 38ab365ae61..574cc9ede18 100644
--- a/engines/ags/engine/ac/game.cpp
+++ b/engines/ags/engine/ac/game.cpp
@@ -1255,7 +1255,7 @@ void display_switch_in_resume() {
}
void replace_tokens(const char *srcmes, char *destm, size_t maxlen) {
- int indxdest = 0, indxsrc = 0;
+ size_t indxdest = 0, indxsrc = 0;
const char *srcp;
char *destp;
while (srcmes[indxsrc] != 0) {
@@ -1290,7 +1290,7 @@ void replace_tokens(const char *srcmes, char *destm, size_t maxlen) {
indxdest++;
indxsrc++;
}
- if (indxdest >= (int)maxlen - 3)
+ if (indxdest >= maxlen - 3)
break;
}
destm[indxdest] = 0;
diff --git a/engines/ags/engine/ac/screen_overlay.cpp b/engines/ags/engine/ac/screen_overlay.cpp
index fc843b451e4..3d51a7bd6d1 100644
--- a/engines/ags/engine/ac/screen_overlay.cpp
+++ b/engines/ags/engine/ac/screen_overlay.cpp
@@ -79,8 +79,8 @@ void ScreenOverlay::SetImage(std::unique_ptr<Shared::Bitmap> pic, bool has_alpha
void ScreenOverlay::SetSpriteNum(int sprnum, int offx, int offy) {
ResetImage();
- assert(sprnum >= 0 && sprnum < (int)_GP(game).SpriteInfos.size());
- if (sprnum < 0 || sprnum >= (int)_GP(game).SpriteInfos.size())
+ assert(sprnum >= 0 && static_cast<size_t>(sprnum) < _GP(game).SpriteInfos.size());
+ if (sprnum < 0 || static_cast<size_t>(sprnum) >= _GP(game).SpriteInfos.size())
return;
_flags |= kOver_SpriteShared | kOver_AlphaChannel * ((_GP(game).SpriteInfos[sprnum].Flags & SPF_ALPHACHANNEL) != 0);
diff --git a/engines/ags/engine/game/savegame.cpp b/engines/ags/engine/game/savegame.cpp
index 483548f30c0..8997e1d672e 100644
--- a/engines/ags/engine/game/savegame.cpp
+++ b/engines/ags/engine/game/savegame.cpp
@@ -775,7 +775,7 @@ void ReadPluginSaveData(Stream *in, PluginSvgVersion svg_ver, soff_t max_size) {
const soff_t end_pos = start_pos + max_size;
if (svg_ver >= kPluginSvgVersion_36115) {
- int num_plugins_read = in->ReadInt32();
+ uint32_t num_plugins_read = in->ReadInt32();
soff_t cur_pos = start_pos;
while ((num_plugins_read--) > 0 && (cur_pos < end_pos)) {
String pl_name = StrUtil::ReadString(in);
@@ -793,7 +793,7 @@ void ReadPluginSaveData(Stream *in, PluginSvgVersion svg_ver, soff_t max_size) {
}
} else {
String pl_name;
- for (int pl_index = 0; pl_query_next_plugin_for_event(AGSE_RESTOREGAME, pl_index, pl_name); ++pl_index) {
+ for (uint32_t pl_index = 0; pl_query_next_plugin_for_event(AGSE_RESTOREGAME, pl_index, pl_name); ++pl_index) {
auto pl_handle = AGSE_RESTOREGAME;
pl_set_file_handle(pl_handle, in);
pl_run_plugin_hook_by_index(pl_index, AGSE_RESTOREGAME, pl_handle);
@@ -806,9 +806,9 @@ void WritePluginSaveData(Stream *out) {
soff_t pluginnum_pos = out->GetPosition();
out->WriteInt32(0); // number of plugins which wrote data
- int num_plugins_wrote = 0;
+ uint32_t num_plugins_wrote = 0;
String pl_name;
- for (int pl_index = 0; pl_query_next_plugin_for_event(AGSE_SAVEGAME, pl_index, pl_name); ++pl_index) {
+ for (uint32_t pl_index = 0; pl_query_next_plugin_for_event(AGSE_SAVEGAME, pl_index, pl_name); ++pl_index) {
// NOTE: we don't care if they really write anything,
// but count them so long as they subscribed to AGSE_SAVEGAME
num_plugins_wrote++;
diff --git a/engines/ags/plugins/ags_plugin.cpp b/engines/ags/plugins/ags_plugin.cpp
index 2384db4b472..a7e28b68fb2 100644
--- a/engines/ags/plugins/ags_plugin.cpp
+++ b/engines/ags/plugins/ags_plugin.cpp
@@ -825,8 +825,8 @@ int pl_run_plugin_debug_hooks(const char *scriptfile, int linenum) {
return 0;
}
-bool pl_query_next_plugin_for_event(int event, int &pl_index, String &pl_name) {
- for (int i = pl_index; i < (int)_GP(plugins).size(); ++i) {
+bool pl_query_next_plugin_for_event(int event, uint32_t &pl_index, String &pl_name) {
+ for (uint32_t i = pl_index; i < _GP(plugins).size(); ++i) {
if (_GP(plugins)[i].wantHook & event) {
pl_index = i;
pl_name = _GP(plugins)[i].filename;
@@ -836,8 +836,8 @@ bool pl_query_next_plugin_for_event(int event, int &pl_index, String &pl_name) {
return false;
}
-int pl_run_plugin_hook_by_index(int pl_index, int event, int data) {
- if (pl_index < 0 || pl_index >= (int)_GP(plugins).size())
+int pl_run_plugin_hook_by_index(uint32_t pl_index, int event, int data) {
+ if (pl_index >= _GP(plugins).size())
return 0;
auto &plugin = _GP(plugins)[pl_index];
if (plugin.wantHook & event) {
diff --git a/engines/ags/plugins/plugin_engine.h b/engines/ags/plugins/plugin_engine.h
index 3e0ca400c58..4f9464bd6bc 100644
--- a/engines/ags/plugins/plugin_engine.h
+++ b/engines/ags/plugins/plugin_engine.h
@@ -66,9 +66,9 @@ int pl_run_plugin_debug_hooks(const char *scriptfile, int linenum);
// Finds a plugin that wants this event, starting with pl_index;
// returns TRUE on success and fills its index and name;
// returns FALSE if no more suitable plugins found.
-bool pl_query_next_plugin_for_event(int event, int &pl_index, Shared::String &pl_name);
+bool pl_query_next_plugin_for_event(int event, uint32_t &pl_index, Shared::String &pl_name);
// Runs event for a plugin identified by an index it was registered under.
-int pl_run_plugin_hook_by_index(int pl_index, int event, int data);
+int pl_run_plugin_hook_by_index(uint32_t pl_index, int event, int data);
// Runs event for a plugin identified by its name.
int pl_run_plugin_hook_by_name(Shared::String &pl_name, int event, int data);
Commit: 04fbffa9d22232025e439dec94eb7d9acf19d542
https://github.com/scummvm/scummvm/commit/04fbffa9d22232025e439dec94eb7d9acf19d542
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2025-05-05T14:23:18+02:00
Commit Message:
AGS: Engine: hotfix translation entries were limited to 1024 bytes
>From upstream e532c16a3bf6c03f7a6514aeca726f6b402cc283
Changed paths:
engines/ags/shared/ac/words_dictionary.cpp
engines/ags/shared/ac/words_dictionary.h
engines/ags/shared/game/tra_file.cpp
diff --git a/engines/ags/shared/ac/words_dictionary.cpp b/engines/ags/shared/ac/words_dictionary.cpp
index adeb91c49ad..b4a370926c2 100644
--- a/engines/ags/shared/ac/words_dictionary.cpp
+++ b/engines/ags/shared/ac/words_dictionary.cpp
@@ -27,7 +27,7 @@
namespace AGS3 {
-using AGS::Shared::Stream;
+using namespace AGS::Shared;
WordsDictionary::WordsDictionary()
: num_words(0)
@@ -118,6 +118,15 @@ void read_string_decrypt(Stream *in, char *buf, size_t buf_sz) {
buf[slen] = 0;
}
+String read_string_decrypt(Stream *in, std::vector<char> &dec_buf) {
+ size_t len = in->ReadInt32();
+ dec_buf.resize(len + 1);
+ in->Read(dec_buf.data(), len);
+ decrypt_text(dec_buf.data(), len);
+ dec_buf.back() = 0; // null terminate in case read string does not have one
+ return String(dec_buf.data());
+}
+
void read_dictionary(WordsDictionary *dict, Stream *out) {
int ii;
diff --git a/engines/ags/shared/ac/words_dictionary.h b/engines/ags/shared/ac/words_dictionary.h
index dfe081d1bbd..6a3f187fe97 100644
--- a/engines/ags/shared/ac/words_dictionary.h
+++ b/engines/ags/shared/ac/words_dictionary.h
@@ -22,7 +22,9 @@
#ifndef AGS_SHARED_AC_WORDS_DICTIONARY_H
#define AGS_SHARED_AC_WORDS_DICTIONARY_H
+#include "common/std/vector.h"
#include "ags/shared/core/types.h"
+#include "ags/shared/util/string.h"
namespace AGS3 {
@@ -51,8 +53,13 @@ struct WordsDictionary {
int find_index(const char *);
};
-extern void decrypt_text(char *toenc, size_t buf_sz);
+// Decrypts text found in the given buffer, writes back to the same buffer
+extern void decrypt_text(char *buf, size_t buf_sz);
+// Reads an encrypted string from the stream and decrypts into the provided buffer
extern void read_string_decrypt(Shared::Stream *in, char *buf, size_t buf_sz);
+// Reads an encrypted string from the stream and returns as a string;
+// uses provided vector as a temporary decryption buffer (avoid extra allocs)
+extern Shared::String read_string_decrypt(Shared::Stream *in, std::vector<char> &dec_buf);
extern void read_dictionary(WordsDictionary *dict, Shared::Stream *in);
#if defined (OBSOLETE)
diff --git a/engines/ags/shared/game/tra_file.cpp b/engines/ags/shared/game/tra_file.cpp
index aac43647dbd..f230ff30f03 100644
--- a/engines/ags/shared/game/tra_file.cpp
+++ b/engines/ags/shared/game/tra_file.cpp
@@ -74,17 +74,15 @@ HError OpenTraFile(Stream *in) {
HError ReadTraBlock(Translation &tra, Stream *in, TraFileBlock block, const String &ext_id, soff_t /*block_len*/) {
switch (block) {
- case kTraFblk_Dict:
- {
- char original[1024];
- char translation[1024];
+ case kTraFblk_Dict: {
+ std::vector<char> buf;
// Read lines until we find zero-length key & value
while (true) {
- read_string_decrypt(in, original, sizeof(original));
- read_string_decrypt(in, translation, sizeof(translation));
- if (!original[0] && !translation[0])
+ String src_line = read_string_decrypt(in, buf);
+ String dst_line = read_string_decrypt(in, buf);
+ if (src_line.IsEmpty() || dst_line.IsEmpty())
break;
- tra.Dict.insert(std::make_pair(String(original), String(translation)));
+ tra.Dict.insert(std::make_pair(src_line, dst_line));
}
return HError::None();
}
Commit: 594a7abd2775c32b545da0fef4b88890708f0733
https://github.com/scummvm/scummvm/commit/594a7abd2775c32b545da0fef4b88890708f0733
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2025-05-05T14:23:18+02:00
Commit Message:
AGS: Engine: fixed a crash when running invitem 0 interaction, add checks
>From upstream 10b0d39d2cbffa306aa2c2c19823311ba7124bba
Changed paths:
engines/ags/engine/ac/global_inventory_item.cpp
engines/ags/engine/script/script.cpp
diff --git a/engines/ags/engine/ac/global_inventory_item.cpp b/engines/ags/engine/ac/global_inventory_item.cpp
index 89606ede584..1df559b1327 100644
--- a/engines/ags/engine/ac/global_inventory_item.cpp
+++ b/engines/ags/engine/ac/global_inventory_item.cpp
@@ -31,6 +31,7 @@
#include "ags/engine/ac/properties.h"
#include "ags/engine/ac/string.h"
#include "ags/engine/ac/dynobj/cc_inventory.h"
+#include "ags/engine/debugging/debug_log.h"
#include "ags/shared/gui/gui_main.h"
#include "ags/shared/gui/gui_inv.h"
#include "ags/engine/script/script.h"
@@ -40,9 +41,18 @@ namespace AGS3 {
using namespace AGS::Shared;
+bool ValidateInventoryItem(const char *api_name, int invitem) {
+ // Inventory Item 0 is a "dummy" slot in AGS historically (idk why)
+ if ((invitem < 1) || (invitem >= _GP(game).numinvitems)) {
+ debug_script_warn("%s: invalid inventory item specified, id %d, valid range is 1..%d", invitem, _GP(game).numinvitems - 1);
+ return false;
+ }
+ return true;
+}
+
void set_inv_item_pic(int invi, int piccy) {
- if ((invi < 1) || (invi > _GP(game).numinvitems))
- quit("!SetInvItemPic: invalid inventory item specified");
+ if (!ValidateInventoryItem("SetInvItemPic", invi))
+ return;
if (_GP(game).invinfo[invi].pic == piccy)
return;
@@ -58,8 +68,8 @@ void set_inv_item_pic(int invi, int piccy) {
}
void SetInvItemName(int invi, const char *newName) {
- if ((invi < 1) || (invi > _GP(game).numinvitems))
- quit("!SetInvName: invalid inventory item specified");
+ if (!ValidateInventoryItem("SetInvName", invi))
+ return;
_GP(game).invinfo[invi].name = newName;
// might need to redraw the GUI if it has the inv item name on it
@@ -84,19 +94,21 @@ int GetInvAt(int atx, int aty) {
void GetInvName(int indx, char *buff) {
VALIDATE_STRING(buff);
- if ((indx < 0) | (indx >= _GP(game).numinvitems)) quit("!GetInvName: invalid inventory item specified");
+ if (!ValidateInventoryItem("GetInvName", indx))
+ return;
snprintf(buff, MAX_MAXSTRLEN, "%s", get_translation(_GP(game).invinfo[indx].name.GetCStr()));
}
int GetInvGraphic(int indx) {
- if ((indx < 0) | (indx >= _GP(game).numinvitems)) quit("!GetInvGraphic: invalid inventory item specified");
+ if (!ValidateInventoryItem("GetInvGraphic", indx))
+ return 0;
return _GP(game).invinfo[indx].pic;
}
void RunInventoryInteraction(int iit, int mood) {
- if ((iit < 0) || (iit >= _GP(game).numinvitems))
- quit("!RunInventoryInteraction: invalid inventory number");
+ if (!ValidateInventoryItem("RunInventoryInteraction", iit))
+ return;
// convert cursor mode to event index (in inventoryitem event table)
// TODO: probably move this conversion table elsewhere? should be a global info
@@ -129,8 +141,8 @@ void RunInventoryInteraction(int iit, int mood) {
}
int IsInventoryInteractionAvailable(int item, int mood) {
- if ((item < 0) || (item >= MAX_INV))
- quit("!IsInventoryInteractionAvailable: invalid inventory number");
+ if (!ValidateInventoryItem("IsInventoryInteractionAvailable", item))
+ return 0;
_GP(play).check_interaction_only = 1;
@@ -146,10 +158,16 @@ int IsInventoryInteractionAvailable(int item, int mood) {
}
int GetInvProperty(int item, const char *property) {
+ if (!ValidateInventoryItem("GetInvProperty", item))
+ return 0;
+
return get_int_property(_GP(game).invProps[item], _GP(play).invProps[item], property);
}
void GetInvPropertyText(int item, const char *property, char *bufer) {
+ if (!ValidateInventoryItem("GetInvPropertyText", item))
+ return;
+
get_text_property(_GP(game).invProps[item], _GP(play).invProps[item], property, bufer);
}
diff --git a/engines/ags/engine/script/script.cpp b/engines/ags/engine/script/script.cpp
index dc8e9f672d8..3dd16b67b03 100644
--- a/engines/ags/engine/script/script.cpp
+++ b/engines/ags/engine/script/script.cpp
@@ -105,6 +105,9 @@ void run_function_on_non_blocking_thread(NonBlockingScriptFunction *funcToRun) {
}
int run_interaction_event(const ObjectEvent &obj_evt, Interaction *nint, int evnt, int chkAny, bool isInv) {
+ assert(nint);
+ if (!nint)
+ return 0;
if (evnt < 0 || (size_t)evnt >= nint->Events.size() ||
(nint->Events[evnt].Response.get() == nullptr) || (nint->Events[evnt].Response->Cmds.size() == 0)) {
@@ -145,6 +148,9 @@ int run_interaction_event(const ObjectEvent &obj_evt, Interaction *nint, int evn
// become invalid and don't run another interaction on it
// (eg. a room change occurred)
int run_interaction_script(const ObjectEvent &obj_evt, InteractionScripts *nint, int evnt, int chkAny) {
+ assert(nint);
+ if (!nint)
+ return 0;
if (evnt < 0 || static_cast<size_t>(evnt) >= nint->ScriptFuncNames.size() || nint->ScriptFuncNames[evnt].IsEmpty()) {
// no response defined for this event
Commit: a5f5d74f053f5f9b09ad3a2e74b4b7c28572831a
https://github.com/scummvm/scummvm/commit/a5f5d74f053f5f9b09ad3a2e74b4b7c28572831a
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2025-05-05T14:23:18+02:00
Commit Message:
AGS: Engine: fixed move speed recalc in case of a 45-deg diagonal movement
>From upstream 3be0392357292f5340205e0f3ded2de8dd5c3302
Changed paths:
engines/ags/engine/ac/character.cpp
engines/ags/engine/ac/route_finder_impl.cpp
diff --git a/engines/ags/engine/ac/character.cpp b/engines/ags/engine/ac/character.cpp
index bec23ee0274..2103c69c9b4 100644
--- a/engines/ags/engine/ac/character.cpp
+++ b/engines/ags/engine/ac/character.cpp
@@ -879,7 +879,7 @@ void Character_SetSpeed(CharacterInfo *chaa, int xspeed, int yspeed) {
else
chaa->walkspeed_y = yspeed;
- if (chaa->walking > 0) {
+ if (chaa->walking > 0 && (old_speedx != xspeed || old_speedy != yspeed)) {
recalculate_move_speeds(&_GP(mls)[chaa->walking % TURNING_AROUND], old_speedx, old_speedy, xspeed, yspeed);
}
}
diff --git a/engines/ags/engine/ac/route_finder_impl.cpp b/engines/ags/engine/ac/route_finder_impl.cpp
index 8e30c265546..1c7668d1f08 100644
--- a/engines/ags/engine/ac/route_finder_impl.cpp
+++ b/engines/ags/engine/ac/route_finder_impl.cpp
@@ -208,9 +208,9 @@ void recalculate_move_speeds(MoveList *mlsp, int old_speed_x, int old_speed_y, i
for (int i = 0; (i < mlsp->numstage) && ((mlsp->xpermove[i] != 0) || (mlsp->ypermove[i] != 0)); ++i) {
// First three cases where the speed is a plain factor, therefore
// we may simply divide on old one and multiple on a new one
- if ((old_movspeed_x == old_movspeed_y) || // diagonal move at straight 45 degrees
- (mlsp->xpermove[i] == 0) || // straight vertical move
- (mlsp->ypermove[i] == 0)) // straight horizontal move
+ if ((old_movspeed_x == old_movspeed_y) && (new_movspeed_x == new_movspeed_y) // diagonal move at straight 45 degrees
+ || (mlsp->xpermove[i] == 0) // straight vertical move
+ || (mlsp->ypermove[i] == 0)) // straight horizontal move
{
mlsp->xpermove[i] = fixdiv(fixmul(mlsp->xpermove[i], new_movspeed_x), old_movspeed_x);
mlsp->ypermove[i] = fixdiv(fixmul(mlsp->ypermove[i], new_movspeed_y), old_movspeed_y);
Commit: 37798d7e0b90dfd2c1b852c68077ba06bbcd2d6d
https://github.com/scummvm/scummvm/commit/37798d7e0b90dfd2c1b852c68077ba06bbcd2d6d
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2025-05-05T14:23:18+02:00
Commit Message:
AGS: Engine: fixed 8-bit fade effect not having a frame delay
Changed paths:
engines/ags/engine/gfx/ali_3d_scummvm.cpp
diff --git a/engines/ags/engine/gfx/ali_3d_scummvm.cpp b/engines/ags/engine/gfx/ali_3d_scummvm.cpp
index ee12a64c109..ba0260bace1 100644
--- a/engines/ags/engine/gfx/ali_3d_scummvm.cpp
+++ b/engines/ags/engine/gfx/ali_3d_scummvm.cpp
@@ -804,6 +804,7 @@ void ScummVMRendererGraphicsDriver::__fade_from_range(PALETTE source, PALETTE de
sys_evt_process_pending();
if (_pollingCallback)
_pollingCallback();
+ WaitForNextFrame();
}
set_palette_range(dest, from, to, TRUE);
Commit: 72fd04e46ab4edc7a6d7a50898412981cad47c0c
https://github.com/scummvm/scummvm/commit/72fd04e46ab4edc7a6d7a50898412981cad47c0c
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2025-05-05T14:23:18+02:00
Commit Message:
AGS: Add parenthesis, fix warning
Changed paths:
engines/ags/engine/ac/route_finder_impl.cpp
diff --git a/engines/ags/engine/ac/route_finder_impl.cpp b/engines/ags/engine/ac/route_finder_impl.cpp
index 1c7668d1f08..68630a47676 100644
--- a/engines/ags/engine/ac/route_finder_impl.cpp
+++ b/engines/ags/engine/ac/route_finder_impl.cpp
@@ -208,7 +208,7 @@ void recalculate_move_speeds(MoveList *mlsp, int old_speed_x, int old_speed_y, i
for (int i = 0; (i < mlsp->numstage) && ((mlsp->xpermove[i] != 0) || (mlsp->ypermove[i] != 0)); ++i) {
// First three cases where the speed is a plain factor, therefore
// we may simply divide on old one and multiple on a new one
- if ((old_movspeed_x == old_movspeed_y) && (new_movspeed_x == new_movspeed_y) // diagonal move at straight 45 degrees
+ if (((old_movspeed_x == old_movspeed_y) && (new_movspeed_x == new_movspeed_y)) // diagonal move at straight 45 degrees
|| (mlsp->xpermove[i] == 0) // straight vertical move
|| (mlsp->ypermove[i] == 0)) // straight horizontal move
{
Commit: 7f60d6618e8b355705c7e7a6f9778df98d65e1eb
https://github.com/scummvm/scummvm/commit/7f60d6618e8b355705c7e7a6f9778df98d65e1eb
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2025-05-05T14:23:18+02:00
Commit Message:
AGS: Engine: fix solid char gets ignored when inside walking char's zone
For some reason engine was testing 2 conditions:
- walking character is inside other char's blocking rect;
- other char is inside walking character's blocking rect.
If any of the above is true, then the "other char" was disabled from the obstacles list.
In effect, if the walking character's blocking rectangle is large enough compared to the
standing character's blocking rectangle, then the character will be able to pass through.
I believe that's illogical, so removed the second test.
>From upstream 5d88a9df1304ffd935fe4e117501691050402c7f
Changed paths:
engines/ags/engine/ac/character.cpp
engines/ags/engine/ac/character.h
engines/ags/engine/ac/walkable_area.cpp
diff --git a/engines/ags/engine/ac/character.cpp b/engines/ags/engine/ac/character.cpp
index 2103c69c9b4..fa5cc64fbf9 100644
--- a/engines/ags/engine/ac/character.cpp
+++ b/engines/ags/engine/ac/character.cpp
@@ -1794,7 +1794,7 @@ void fix_player_sprite(MoveList *cmls, CharacterInfo *chinf) {
// Check whether two characters have walked into each other
int has_hit_another_character(int sourceChar) {
- // if the character who's moving doesn't Bitmap *, don't bother checking
+ // if the character who's moving doesn't block, don't bother checking
if (_GP(game).chars[sourceChar].flags & CHF_NOBLOCKING)
return -1;
@@ -1804,7 +1804,7 @@ int has_hit_another_character(int sourceChar) {
if (ww == sourceChar) continue;
if (_GP(game).chars[ww].flags & CHF_NOBLOCKING) continue;
- if (is_char_on_another(sourceChar, ww, nullptr, nullptr)) {
+ if (is_char_in_blocking_rect(sourceChar, ww, nullptr, nullptr)) {
// we are now overlapping character 'ww'
if ((_GP(game).chars[ww].walking) &&
((_GP(game).chars[ww].flags & CHF_AWAITINGMOVE) == 0))
@@ -2248,12 +2248,12 @@ void get_char_blocking_rect(int charid, int *x1, int *y1, int *width, int *y2) {
*y2 = char1->get_blocking_bottom();
}
-// Check whether the source char has walked onto character ww
-int is_char_on_another(int sourceChar, int ww, int *fromxptr, int *cwidptr) {
+// Check whether the source char is standing inside otherChar's blocking rectangle
+int is_char_in_blocking_rect(int sourceChar, int otherChar, int *fromxptr, int *cwidptr) {
int fromx, cwidth;
int y1, y2;
- get_char_blocking_rect(ww, &fromx, &y1, &cwidth, &y2);
+ get_char_blocking_rect(otherChar, &fromx, &y1, &cwidth, &y2);
if (fromxptr)
fromxptr[0] = fromx;
diff --git a/engines/ags/engine/ac/character.h b/engines/ags/engine/ac/character.h
index 1fc4f0ec665..c72f4ba16af 100644
--- a/engines/ags/engine/ac/character.h
+++ b/engines/ags/engine/ac/character.h
@@ -217,10 +217,9 @@ CharacterInfo *GetCharacterAtRoom(int x, int y);
// Get character ID at the given room coordinates
int is_pos_on_character(int xx, int yy);
void get_char_blocking_rect(int charid, int *x1, int *y1, int *width, int *y2);
-// Check whether the source char has walked onto character ww
-int is_char_on_another(int sourceChar, int ww, int *fromxptr, int *cwidptr);
+// Check whether the source char is standing inside otherChar's blocking rectangle
+int is_char_in_blocking_rect(int sourceChar, int otherChar, int *fromxptr, int *cwidptr);
int my_getpixel(Shared::Bitmap *blk, int x, int y);
-// X and Y co-ordinates must be in 320x200 format
int check_click_on_character(int xx, int yy, int mood);
void _DisplaySpeechCore(int chid, const char *displbuf);
void _DisplayThoughtCore(int chid, const char *displbuf);
diff --git a/engines/ags/engine/ac/walkable_area.cpp b/engines/ags/engine/ac/walkable_area.cpp
index 837d35e0f07..9bf24155dfe 100644
--- a/engines/ags/engine/ac/walkable_area.cpp
+++ b/engines/ags/engine/ac/walkable_area.cpp
@@ -148,9 +148,9 @@ Bitmap *prepare_walkable_areas(int sourceChar) {
CharacterInfo *char1 = &_GP(game).chars[ww];
int cwidth, fromx;
- if (is_char_on_another(sourceChar, ww, &fromx, &cwidth))
- continue;
- if ((sourceChar >= 0) && (is_char_on_another(ww, sourceChar, nullptr, nullptr)))
+ // If walking character is already inside that other character's blocking rect,
+ // then ignore that blocking rect (otherwise character may get stuck forever)
+ if (is_char_in_blocking_rect(sourceChar, ww, &fromx, &cwidth))
continue;
remove_walkable_areas_from_temp(fromx, cwidth, char1->get_blocking_top(), char1->get_blocking_bottom());
Commit: 191438f3e04523f39b3983c606f02b30cb054a3e
https://github.com/scummvm/scummvm/commit/191438f3e04523f39b3983c606f02b30cb054a3e
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2025-05-05T14:23:18+02:00
Commit Message:
AGS: Engine: fixed old room script run if a room was changed in on_event()
This fixes a case when the room was changed in a on_event while the current room's
own script callback is scheduled to run after.
For example:
- Room is entered.
- Engine wants to run on_event with eEventEnterRoomAfterFadein, and then room's
"After Fade-in" script.
- ChangeRoom is called inside on_event.
- A new room is loaded after on_event completes.
- Engine proceeds executing scheduled "After Fade-in" callback, but it's a new room,
and "After Fade-in" gets called before "Load", possibly causing script mistakes
(or maybe could be called twice in the new room).
>From upstream 7c17f6d2d23e8ebe8d301b9d866b53967821b4dd
Changed paths:
engines/ags/engine/ac/event.cpp
engines/ags/engine/script/script.cpp
diff --git a/engines/ags/engine/ac/event.cpp b/engines/ags/engine/ac/event.cpp
index 3002df10e81..1b8383b8918 100644
--- a/engines/ags/engine/ac/event.cpp
+++ b/engines/ags/engine/ac/event.cpp
@@ -125,6 +125,8 @@ void force_event(int evtyp, int ev1, int ev2, int ev3) {
}
void process_event(const EventHappened *evp) {
+ const int room_was = _GP(play).room_changes;
+
RuntimeScriptValue rval_null;
if (evp->type == EV_TEXTSCRIPT) {
cc_clear_error();
@@ -171,6 +173,14 @@ void process_event(const EventHappened *evp) {
quit("process_event: RunEvBlock: unknown evb type");
}
+ // If the room was changed inside a on_event call above,
+ // then skip running further interaction scripts
+ if (room_was != _GP(play).room_changes) {
+ if ((evp->data1 == EVB_ROOM) && (evp->data3 == EVROM_BEFOREFADEIN))
+ _G(in_enters_screen)--;
+ return;
+ }
+
assert(scriptPtr || evpt);
if (scriptPtr != nullptr) {
run_interaction_script(obj_evt, scriptPtr.get(), evp->data3);
@@ -356,7 +366,7 @@ void processallevents() {
// TODO: need to redesign engine events system?
std::vector<EventHappened> evtCopy = _GP(events);
- int room_was = _GP(play).room_changes;
+ const int room_was = _GP(play).room_changes;
_G(inside_processevent)++;
diff --git a/engines/ags/engine/script/script.cpp b/engines/ags/engine/script/script.cpp
index 3dd16b67b03..47422dad216 100644
--- a/engines/ags/engine/script/script.cpp
+++ b/engines/ags/engine/script/script.cpp
@@ -702,7 +702,7 @@ int run_interaction_commandlist(const ObjectEvent &obj_evt, InteractionCommandLi
const int evblocknum = obj_evt.BlockID;
for (size_t i = 0; i < nicl->Cmds.size(); i++) {
cmdsrun[0] ++;
- int room_was = _GP(play).room_changes;
+ const int room_was = _GP(play).room_changes;
switch (nicl->Cmds[i].Type) {
case 0: // Do nothing
More information about the Scummvm-git-logs
mailing list