[Scummvm-git-logs] scummvm master -> 1607b2530bf3e43d5bd6636843821277978a8d0d
dreammaster
noreply at scummvm.org
Sun May 8 18:39:43 UTC 2022
This automated email contains information about 6 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
3ac6998a98 AGS: Support Overlays not copying the image, but storing a sprite id
a8ebf2b41b AGS: Added "clone" parameter to Overlay.CreateGraphical()
f782f0f2b2 AGS: Implemented Overlay.Graphic
c143ceb01b AGS: Tidied and fixed InputBox to work with SDL2 input
a123a7473f AGS: Updated build version (3.6.0.25)
1607b2530b AGS: Fixed script errors when non-obligatory callbacks are missing
Commit: 3ac6998a98792b1b7835010707f56e45c0df0343
https://github.com/scummvm/scummvm/commit/3ac6998a98792b1b7835010707f56e45c0df0343
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-05-08T11:37:49-07:00
Commit Message:
AGS: Support Overlays not copying the image, but storing a sprite id
>From upstream fd14bd4075bd9e6a577235f2434275b260250c46
Changed paths:
engines/ags/engine/ac/draw.cpp
engines/ags/engine/ac/overlay.cpp
engines/ags/engine/ac/overlay.h
engines/ags/engine/ac/screen_overlay.cpp
engines/ags/engine/ac/screen_overlay.h
engines/ags/engine/game/savegame_components.cpp
engines/ags/engine/game/savegame_v321.cpp
engines/ags/engine/main/update.cpp
diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp
index 59c2a2c257d..5660172d894 100644
--- a/engines/ags/engine/ac/draw.cpp
+++ b/engines/ags/engine/ac/draw.cpp
@@ -2114,13 +2114,13 @@ static void construct_overlays() {
if (has_changed) {
// For software mode - prepare transformed bitmap if necessary
Bitmap *use_bmp = is_software_mode ?
- transform_sprite(over.pic, over.HasAlphaChannel(), _GP(overlaybmp)[i], Size(over.scaleWidth, over.scaleHeight)) :
- over.pic;
+ transform_sprite(over.GetImage(), over.HasAlphaChannel(), _GP(overlaybmp)[i], Size(over.scaleWidth, over.scaleHeight)) :
+ over.GetImage();
if ((_G(walkBehindMethod) == DrawOverCharSprite) && over.IsRoomLayer()) {
if (use_bmp != _GP(overlaybmp)[i].get()) {
- recycle_bitmap(_GP(overlaybmp)[i], over.pic->GetColorDepth(), over.pic->GetWidth(), over.pic->GetHeight(), true);
- _GP(overlaybmp)[i]->Blit(over.pic);
+ recycle_bitmap(_GP(overlaybmp)[i], use_bmp->GetColorDepth(), use_bmp->GetWidth(), use_bmp->GetHeight(), true);
+ _GP(overlaybmp)[i]->Blit(use_bmp);
}
Point pos = get_overlay_position(over);
walkbehinds_cropout(_GP(overlaybmp)[i].get(), pos.X, pos.Y, over.zorder);
diff --git a/engines/ags/engine/ac/overlay.cpp b/engines/ags/engine/ac/overlay.cpp
index dbe8a6daef6..39e30e30a58 100644
--- a/engines/ags/engine/ac/overlay.cpp
+++ b/engines/ags/engine/ac/overlay.cpp
@@ -126,14 +126,14 @@ int Overlay_GetGraphicWidth(ScriptOverlay *scover) {
int ovri = find_overlay_of_type(scover->overlayId);
if (ovri < 0)
quit("!invalid overlay ID specified");
- return game_to_data_coord(_GP(screenover)[ovri].pic->GetWidth());
+ return game_to_data_coord(_GP(screenover)[ovri].GetImage()->GetWidth());
}
int Overlay_GetGraphicHeight(ScriptOverlay *scover) {
int ovri = find_overlay_of_type(scover->overlayId);
if (ovri < 0)
quit("!invalid overlay ID specified");
- return game_to_data_coord(_GP(screenover)[ovri].pic->GetHeight());
+ return game_to_data_coord(_GP(screenover)[ovri].GetImage()->GetHeight());
}
void Overlay_SetScaledSize(ScreenOverlay &over, int width, int height) {
@@ -177,11 +177,17 @@ int Overlay_GetValid(ScriptOverlay *scover) {
ScreenOverlay *Overlay_CreateGraphicCore(bool room_layer, int x, int y, int slot, bool transparent) {
data_to_game_coords(&x, &y);
- Bitmap *screeno = BitmapHelper::CreateTransparentBitmap(_GP(game).SpriteInfos[slot].Width, _GP(game).SpriteInfos[slot].Height, _GP(game).GetColorDepth());
- screeno->Blit(_GP(spriteset)[slot], 0, 0, transparent ? kBitmap_Transparency : kBitmap_Copy);
- size_t nse = add_screen_overlay(room_layer, x, y, OVER_CUSTOM, screeno,
- (_GP(game).SpriteInfos[slot].Flags & SPF_ALPHACHANNEL) != 0);
- return nse < SIZE_MAX ? &_GP(screenover)[nse] : nullptr;
+ size_t overid;
+ // We clone only dynamic sprites, because it makes no sense to clone normal ones
+ if ((_GP(game).SpriteInfos[slot].Flags & SPF_DYNAMICALLOC) != 0) {
+ Bitmap *screeno = BitmapHelper::CreateTransparentBitmap(_GP(game).SpriteInfos[slot].Width, _GP(game).SpriteInfos[slot].Height, _GP(game).GetColorDepth());
+ screeno->Blit(_GP(spriteset)[slot], 0, 0, transparent ? kBitmap_Transparency : kBitmap_Copy);
+ overid = add_screen_overlay(room_layer, x, y, OVER_CUSTOM, screeno,
+ (_GP(game).SpriteInfos[slot].Flags & SPF_ALPHACHANNEL) != 0);
+ } else {
+ overid = add_screen_overlay(room_layer, x, y, OVER_CUSTOM, slot);
+ }
+ return overid < SIZE_MAX ? &_GP(screenover)[overid] : nullptr;
}
ScreenOverlay *Overlay_CreateTextCore(bool room_layer, int x, int y, int width, int font, int text_color,
@@ -276,8 +282,7 @@ static void invalidate_and_subref(ScreenOverlay &over, ScriptOverlay **scover) {
// Frees overlay resources and tell to dispose script object if there are no refs left
static void dispose_overlay(ScreenOverlay &over) {
- delete over.pic;
- over.pic = nullptr;
+ over.SetImage(nullptr);
if (over.ddb != nullptr)
_G(gfxDriver)->DestroyDDB(over.ddb);
over.ddb = nullptr;
@@ -326,12 +331,8 @@ int find_overlay_of_type(int type) {
}
return -1;
}
-
-size_t add_screen_overlay(bool roomlayer, int x, int y, int type, Bitmap *piccy, bool alphaChannel) {
- return add_screen_overlay(roomlayer, x, y, type, piccy, 0, 0, alphaChannel);
-}
-
-size_t add_screen_overlay(bool roomlayer, int x, int y, int type, Bitmap *piccy, int pic_offx, int pic_offy, bool alphaChannel) {
+size_t add_screen_overlay_impl(bool roomlayer, int x, int y, int type, int sprnum, Bitmap *piccy,
+ int pic_offx, int pic_offy, bool has_alpha) {
if (type == OVER_CUSTOM) {
// find an unused custom ID; TODO: find a better approach!
for (int id = OVER_CUSTOM + 1; (size_t)id <= _GP(screenover).size() + OVER_CUSTOM + 1; ++id) {
@@ -340,16 +341,21 @@ size_t add_screen_overlay(bool roomlayer, int x, int y, int type, Bitmap *piccy,
}
}
}
-
ScreenOverlay over;
- over.pic = piccy;
+ if (piccy) {
+ over.SetImage(piccy);
+ over.SetAlphaChannel(has_alpha);
+ } else {
+ over.SetSpriteNum(sprnum);
+ over.SetAlphaChannel((_GP(game).SpriteInfos[sprnum].Flags & SPF_ALPHACHANNEL) != 0);
+ }
over.ddb = nullptr; // is generated during first draw pass
over.x = x;
over.y = y;
over.offsetX = pic_offx;
over.offsetY = pic_offy;
- over.scaleWidth = piccy->GetWidth();
- over.scaleHeight = piccy->GetHeight();
+ over.scaleWidth = over.GetImage()->GetWidth();
+ over.scaleHeight = over.GetImage()->GetHeight();
// by default draw speech and portraits over GUI, and the rest under GUI
over.zorder = (roomlayer || type == OVER_TEXTMSG || type == OVER_PICTURE || type == OVER_TEXTSPEECH) ?
INT_MAX : INT_MIN;
@@ -357,7 +363,6 @@ size_t add_screen_overlay(bool roomlayer, int x, int y, int type, Bitmap *piccy,
over.timeout = 0;
over.bgSpeechForChar = -1;
over.associatedOverlayHandle = 0;
- over.SetAlphaChannel(alphaChannel);
over.SetRoomLayer(roomlayer);
// TODO: move these custom settings outside of this function
if (type == OVER_COMPLETE) _GP(play).complete_overlay_on = type;
@@ -370,12 +375,23 @@ size_t add_screen_overlay(bool roomlayer, int x, int y, int type, Bitmap *piccy,
} else if (type == OVER_PICTURE) {
_GP(play).speech_face_scover = create_scriptoverlay(over, true);
}
-
over.MarkChanged();
_GP(screenover).push_back(std::move(over));
return _GP(screenover).size() - 1;
}
+size_t add_screen_overlay(bool roomlayer, int x, int y, int type, int sprnum) {
+ return add_screen_overlay_impl(roomlayer, x, y, type, sprnum, nullptr, 0, 0, false);
+}
+
+size_t add_screen_overlay(bool roomlayer, int x, int y, int type, Bitmap *piccy, bool has_alpha) {
+ return add_screen_overlay_impl(roomlayer, x, y, type, -1, piccy, 0, 0, has_alpha);
+}
+
+size_t add_screen_overlay(bool roomlayer, int x, int y, int type, Shared::Bitmap *piccy, int pic_offx, int pic_offy, bool has_alpha) {
+ return add_screen_overlay_impl(roomlayer, x, y, type, -1, piccy, pic_offx, pic_offy, has_alpha);
+}
+
Point get_overlay_position(const ScreenOverlay &over) {
if (over.IsRoomLayer()) {
return Point(over.x + over.offsetX, over.y + over.offsetY);
@@ -392,16 +408,17 @@ Point get_overlay_position(const ScreenOverlay &over) {
Point screenpt = view->RoomToScreen(
data_to_game_coord(_GP(game).chars[charid].x),
data_to_game_coord(_GP(game).chars[charid].get_effective_y()) - height).first;
- int tdxp = MAX(0, screenpt.X - over.pic->GetWidth() / 2);
+ Bitmap *pic = over.GetImage();
+ int tdxp = std::max(0, screenpt.X - pic->GetWidth() / 2);
int tdyp = screenpt.Y - get_fixed_pixel_size(5);
- tdyp -= over.pic->GetHeight();
- tdyp = MAX(5, tdyp);
+ tdyp -= pic->GetHeight();
+ tdyp = std::max(5, tdyp);
- if ((tdxp + over.pic->GetWidth()) >= ui_view.GetWidth())
- tdxp = (ui_view.GetWidth() - over.pic->GetWidth()) - 1;
+ if ((tdxp + pic->GetWidth()) >= ui_view.GetWidth())
+ tdxp = (ui_view.GetWidth() - pic->GetWidth()) - 1;
if (_GP(game).chars[charid].room != _G(displayed_room)) {
- tdxp = ui_view.GetWidth() / 2 - over.pic->GetWidth() / 2;
- tdyp = ui_view.GetHeight() / 2 - over.pic->GetHeight() / 2;
+ tdxp = ui_view.GetWidth() / 2 - pic->GetWidth() / 2;
+ tdyp = ui_view.GetHeight() / 2 - pic->GetHeight() / 2;
}
return Point(tdxp, tdyp);
} else {
diff --git a/engines/ags/engine/ac/overlay.h b/engines/ags/engine/ac/overlay.h
index 48d277b07bd..4bc2fdf6b9c 100644
--- a/engines/ags/engine/ac/overlay.h
+++ b/engines/ags/engine/ac/overlay.h
@@ -53,8 +53,9 @@ int find_overlay_of_type(int type);
void remove_screen_overlay(int type);
// Calculates overlay position in its respective layer (screen or room)
Point get_overlay_position(const ScreenOverlay &over);
-size_t add_screen_overlay(bool roomlayer, int x, int y, int type, Shared::Bitmap *piccy, bool alphaChannel = false);
-size_t add_screen_overlay(bool roomlayer, int x, int y, int type, Shared::Bitmap *piccy, int pic_offx, int pic_offy, bool alphaChannel = false);
+size_t add_screen_overlay(bool roomlayer, int x, int y, int type, int sprnum);
+size_t add_screen_overlay(bool roomlayer, int x, int y, int type, Shared::Bitmap *piccy, bool has_alpha);
+size_t add_screen_overlay(bool roomlayer, int x, int y, int type, Shared::Bitmap *piccy, int pic_offx, int pic_offy, bool has_alpha);
void remove_screen_overlay_index(size_t over_idx);
// Creates and registers a managed script object for // Creates and registers a managed script object for existing overlay object;
// optionally adds an internal engine reference to prevent object's disposal
diff --git a/engines/ags/engine/ac/screen_overlay.cpp b/engines/ags/engine/ac/screen_overlay.cpp
index 928aa3c9385..1727d95b169 100644
--- a/engines/ags/engine/ac/screen_overlay.cpp
+++ b/engines/ags/engine/ac/screen_overlay.cpp
@@ -19,18 +19,39 @@
*
*/
+#include "ags/lib/std/utility.h"
#include "ags/engine/ac/screen_overlay.h"
+#include "ags/shared/ac/sprite_cache.h"
#include "ags/shared/util/stream.h"
+#include "ags/globals.h"
namespace AGS3 {
-using AGS::Shared::Stream;
+using namespace AGS::Shared;
+
+Bitmap *ScreenOverlay::GetImage() const {
+ return IsSpriteReference() ?
+ _GP(spriteset)[_sprnum] :
+ _pic.get();
+}
+
+void ScreenOverlay::SetImage(Shared::Bitmap *pic) {
+ _flags &= ~kOver_SpriteReference;
+ _pic.reset(pic);
+ _sprnum = -1;
+}
+
+void ScreenOverlay::SetSpriteNum(int sprnum) {
+ _flags |= kOver_SpriteReference;
+ _pic.reset();
+ _sprnum = sprnum;
+}
void ScreenOverlay::ReadFromFile(Stream *in, bool &has_bitmap, int32_t cmp_ver) {
- pic = nullptr;
+ _pic.reset();
ddb = nullptr;
in->ReadInt32(); // ddb 32-bit pointer value (nasty legacy format)
- has_bitmap = in->ReadInt32() != 0;
+ int pic = in->ReadInt32();
type = in->ReadInt32();
x = in->ReadInt32();
y = in->ReadInt32();
@@ -56,11 +77,22 @@ void ScreenOverlay::ReadFromFile(Stream *in, bool &has_bitmap, int32_t cmp_ver)
scaleWidth = in->ReadInt32();
scaleHeight = in->ReadInt32();
}
+
+ if (_flags & kOver_SpriteReference) {
+ _sprnum = pic;
+ has_bitmap = false;
+ } else {
+ _sprnum = -1;
+ has_bitmap = pic != 0;
+ }
}
void ScreenOverlay::WriteToFile(Stream *out) const {
out->WriteInt32(0); // ddb 32-bit pointer value (nasty legacy format)
- out->WriteInt32(pic ? 1 : 0); // has bitmap
+ if (_flags & kOver_SpriteReference)
+ out->WriteInt32(_sprnum); // sprite reference
+ else
+ out->WriteInt32(_pic ? 1 : 0); // has bitmap
out->WriteInt32(type);
out->WriteInt32(x);
out->WriteInt32(y);
diff --git a/engines/ags/engine/ac/screen_overlay.h b/engines/ags/engine/ac/screen_overlay.h
index 2425f98be8b..f38f730dcd9 100644
--- a/engines/ags/engine/ac/screen_overlay.h
+++ b/engines/ags/engine/ac/screen_overlay.h
@@ -20,10 +20,14 @@
*/
// ScreenOverlay is a simple sprite container with no advanced functions.
+// May contain owned bitmap or reference persistent sprite's id, similar to how
+// other game objects do that.
+// May logically exist either on UI or room layer.
#ifndef AGS_ENGINE_AC_SCREEN_OVERLAY_H
#define AGS_ENGINE_AC_SCREEN_OVERLAY_H
+#include "ags/lib/std/memory.h"
#include "ags/shared/core/types.h"
namespace AGS3 {
@@ -47,22 +51,13 @@ using namespace AGS; // FIXME later
enum OverlayFlags {
kOver_AlphaChannel = 0x0001,
kOver_PositionAtRoomXY = 0x0002, // room-relative position, may be in ui
- kOver_RoomLayer = 0x0004 // work in room layer (as opposed to UI)
+ kOver_RoomLayer = 0x0004, // work in room layer (as opposed to UI)
+ kOver_SpriteReference = 0x0008 // reference persistent sprite
};
-// Overlay class.
-// TODO: currently overlay creates and stores its own bitmap, even if
-// created using existing sprite. As a side-effect, changing that sprite
-// (if it were a dynamic one) will not affect overlay (unlike other objects).
-// For future perfomance optimization it may be desired to store sprite index
-// instead; but that would mean that overlay will have to receive sprite
-// changes. For backward compatibility there may be a game switch that
-// forces it to make a copy.
struct ScreenOverlay {
// Texture
Engine::IDriverDependantBitmap *ddb = nullptr;
- // Original bitmap
- Shared::Bitmap *pic = nullptr;
int type = 0, timeout = 0;
// Note that x,y are overlay's properties, that define its position in script;
// but real drawn position is x + offsetX, y + offsetY;
@@ -79,6 +74,9 @@ struct ScreenOverlay {
bool HasAlphaChannel() const {
return (_flags & kOver_AlphaChannel) != 0;
}
+ bool IsSpriteReference() const {
+ return (_flags & kOver_SpriteReference) != 0;
+ }
bool IsRoomRelative() const {
return (_flags & kOver_PositionAtRoomXY) != 0;
}
@@ -95,7 +93,14 @@ struct ScreenOverlay {
on ? _flags |= (kOver_RoomLayer | kOver_PositionAtRoomXY) :
_flags &= ~(kOver_RoomLayer | kOver_PositionAtRoomXY);
}
-
+ // Gets actual overlay's image, whether owned by overlay or by a sprite reference
+ Shared::Bitmap *GetImage() const;
+ // Get sprite reference id, or -1 if none set
+ int GetSpriteNum() const {
+ return _sprnum;
+ }
+ void SetImage(Shared::Bitmap *pic);
+ void SetSpriteNum(int sprnum);
// Tells if Overlay has graphically changed recently
bool HasChanged() const {
return _hasChanged;
@@ -115,6 +120,8 @@ struct ScreenOverlay {
private:
int _flags = 0; // OverlayFlags
bool _hasChanged = false;
+ std::shared_ptr<Shared::Bitmap> _pic; // owned bitmap
+ int _sprnum = -1; // sprite reference
};
} // namespace AGS3
diff --git a/engines/ags/engine/game/savegame_components.cpp b/engines/ags/engine/game/savegame_components.cpp
index 11c0cf89593..f0ce10426d7 100644
--- a/engines/ags/engine/game/savegame_components.cpp
+++ b/engines/ags/engine/game/savegame_components.cpp
@@ -759,10 +759,10 @@ HSaveError ReadDynamicSprites(Stream *in, int32_t /*cmp_ver*/, const PreservedPa
}
HSaveError WriteOverlays(Stream *out) {
- out->WriteInt32(_GP(screenover).size());
for (const auto &over : _GP(screenover)) {
over.WriteToFile(out);
- serialize_bitmap(over.pic, out);
+ if (!over.IsSpriteReference())
+ serialize_bitmap(over.GetImage(), out);
}
return HSaveError::None();
}
@@ -774,12 +774,12 @@ HSaveError ReadOverlays(Stream *in, int32_t cmp_ver, const PreservedParams & /*p
bool has_bitmap;
over.ReadFromFile(in, has_bitmap, cmp_ver);
if (has_bitmap)
- over.pic = read_serialized_bitmap(in);
+ over.SetImage(read_serialized_bitmap(in));
if (over.scaleWidth <= 0 || over.scaleHeight <= 0) {
- over.scaleWidth = over.pic->GetWidth();
- over.scaleHeight = over.pic->GetHeight();
+ over.scaleWidth = over.GetImage()->GetWidth();
+ over.scaleHeight = over.GetImage()->GetHeight();
}
- _GP(screenover).push_back(over);
+ _GP(screenover).push_back(std::move(over));
}
return HSaveError::None();
}
diff --git a/engines/ags/engine/game/savegame_v321.cpp b/engines/ags/engine/game/savegame_v321.cpp
index 6c50d338d98..b2f329f96b8 100644
--- a/engines/ags/engine/game/savegame_v321.cpp
+++ b/engines/ags/engine/game/savegame_v321.cpp
@@ -287,7 +287,7 @@ static void restore_game_overlays(Stream *in) {
ReadOverlays_Aligned(in, has_bitmap, num_overs);
for (size_t i = 0; i < num_overs; ++i) {
if (has_bitmap[i])
- _GP(screenover)[i].pic = read_serialized_bitmap(in);
+ _GP(screenover)[i].SetImage(read_serialized_bitmap(in));
}
}
diff --git a/engines/ags/engine/main/update.cpp b/engines/ags/engine/main/update.cpp
index 3e93fd7d6f6..648021e3dac 100644
--- a/engines/ags/engine/main/update.cpp
+++ b/engines/ags/engine/main/update.cpp
@@ -383,6 +383,7 @@ void update_sierra_speech() {
int view_frame_x = 0;
int view_frame_y = 0;
+ Bitmap *frame_pic = _GP(screenover)[_G(face_talking)].GetImage();
if (_GP(game).options[OPT_SPEECHTYPE] == 3) {
// QFG4-style fullscreen dialog
if (_G(facetalk_qfg4_override_placement_x)) {
@@ -391,14 +392,13 @@ void update_sierra_speech() {
if (_G(facetalk_qfg4_override_placement_y)) {
view_frame_y = _GP(play).speech_portrait_y;
} else {
- view_frame_y = (_GP(screenover)[_G(face_talking)].pic->GetHeight() / 2) - (_GP(game).SpriteInfos[thisPic].Height / 2);
+ view_frame_y = (frame_pic->GetHeight() / 2) - (_GP(game).SpriteInfos[thisPic].Height / 2);
}
- _GP(screenover)[_G(face_talking)].pic->Clear(0);
+ frame_pic->Clear(0);
} else {
- _GP(screenover)[_G(face_talking)].pic->ClearTransparent();
+ frame_pic->ClearTransparent();
}
- Bitmap *frame_pic = _GP(screenover)[_G(face_talking)].pic;
const ViewFrame *face_vf = &_GP(views)[_G(facetalkview)].loops[_G(facetalkloop)].frames[_G(facetalkframe)];
bool face_has_alpha = (_GP(game).SpriteInfos[face_vf->pic].Flags & SPF_ALPHACHANNEL) != 0;
DrawViewFrame(frame_pic, face_vf, view_frame_x, view_frame_y);
Commit: a8ebf2b41b1a5b721e6edec29dd6079985985e61
https://github.com/scummvm/scummvm/commit/a8ebf2b41b1a5b721e6edec29dd6079985985e61
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-05-08T11:37:49-07:00
Commit Message:
AGS: Added "clone" parameter to Overlay.CreateGraphical()
>From upstream 2a7adfb6a3424017913c9a6c240525029debf1e0
Changed paths:
engines/ags/engine/ac/game.cpp
engines/ags/engine/ac/global_overlay.cpp
engines/ags/engine/ac/overlay.cpp
engines/ags/engine/ac/overlay.h
diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp
index 3fcb319b723..4fe72fbdfbd 100644
--- a/engines/ags/engine/ac/game.cpp
+++ b/engines/ags/engine/ac/game.cpp
@@ -1361,6 +1361,11 @@ void game_sprite_updated(int sprnum) {
_GP(guislider)[i].MarkChanged();
}
}
+ // overlays
+ for (auto &over : _GP(screenover)) {
+ if (over.GetSpriteNum() == sprnum)
+ over.MarkChanged();
+ }
}
void game_sprite_deleted(int sprnum) {
@@ -1412,6 +1417,11 @@ void game_sprite_deleted(int sprnum) {
}
}
}
+ // overlays
+ for (auto &over : _GP(screenover)) {
+ if (over.GetSpriteNum() == sprnum)
+ over.SetSpriteNum(0);
+ }
}
//=============================================================================
diff --git a/engines/ags/engine/ac/global_overlay.cpp b/engines/ags/engine/ac/global_overlay.cpp
index 81bce47e535..e4150854d3e 100644
--- a/engines/ags/engine/ac/global_overlay.cpp
+++ b/engines/ags/engine/ac/global_overlay.cpp
@@ -36,8 +36,8 @@ void RemoveOverlay(int ovrid) {
remove_screen_overlay(ovrid);
}
-int CreateGraphicOverlay(int xx, int yy, int slott, int trans) {
- auto *over = Overlay_CreateGraphicCore(false, xx, yy, slott, trans);
+int CreateGraphicOverlay(int x, int y, int slott, int trans) {
+ auto *over = Overlay_CreateGraphicCore(false, x, y, slott, trans != 0, true); // always clone
return over ? over->type : 0;
}
diff --git a/engines/ags/engine/ac/overlay.cpp b/engines/ags/engine/ac/overlay.cpp
index 39e30e30a58..e4990fc6aa2 100644
--- a/engines/ags/engine/ac/overlay.cpp
+++ b/engines/ags/engine/ac/overlay.cpp
@@ -175,11 +175,11 @@ int Overlay_GetValid(ScriptOverlay *scover) {
return 1;
}
-ScreenOverlay *Overlay_CreateGraphicCore(bool room_layer, int x, int y, int slot, bool transparent) {
+ScreenOverlay *Overlay_CreateGraphicCore(bool room_layer, int x, int y, int slot, bool transparent, bool clone) {
data_to_game_coords(&x, &y);
size_t overid;
// We clone only dynamic sprites, because it makes no sense to clone normal ones
- if ((_GP(game).SpriteInfos[slot].Flags & SPF_DYNAMICALLOC) != 0) {
+ if (clone && (_GP(game).SpriteInfos[slot].Flags & SPF_DYNAMICALLOC) != 0) {
Bitmap *screeno = BitmapHelper::CreateTransparentBitmap(_GP(game).SpriteInfos[slot].Width, _GP(game).SpriteInfos[slot].Height, _GP(game).GetColorDepth());
screeno->Blit(_GP(spriteset)[slot], 0, 0, transparent ? kBitmap_Transparency : kBitmap_Copy);
overid = add_screen_overlay(room_layer, x, y, OVER_CUSTOM, screeno,
@@ -198,13 +198,13 @@ ScreenOverlay *Overlay_CreateTextCore(bool room_layer, int x, int y, int width,
return _display_main(x, y, width, text, disp_type, font, -text_color, 0, allow_shrink, false);
}
-ScriptOverlay *Overlay_CreateGraphicalEx(bool room_layer, int x, int y, int slot, int transparent) {
- auto *over = Overlay_CreateGraphicCore(room_layer, x, y, slot, transparent != 0);
+ScriptOverlay *Overlay_CreateGraphicalEx(bool room_layer, int x, int y, int slot, int transparent, bool clone) {
+ auto *over = Overlay_CreateGraphicCore(room_layer, x, y, slot, transparent != 0, clone);
return over ? create_scriptoverlay(*over) : nullptr;
}
ScriptOverlay *Overlay_CreateGraphical(int x, int y, int slot, int transparent) {
- auto *over = Overlay_CreateGraphicCore(false, x, y, slot, transparent != 0);
+ auto *over = Overlay_CreateGraphicCore(false, x, y, slot, transparent != 0, true); // always clone
return over ? create_scriptoverlay(*over) : nullptr;
}
@@ -451,14 +451,21 @@ void recreate_overlay_ddbs() {
RuntimeScriptValue Sc_Overlay_CreateGraphical(const RuntimeScriptValue *params, int32_t param_count) {
ASSERT_PARAM_COUNT(FUNCTION, 4);
ScriptOverlay *overlay = Overlay_CreateGraphicalEx(false, params[0].IValue, params[1].IValue, params[2].IValue,
- params[3].IValue);
+ params[3].IValue, true); // always clone image
+ return RuntimeScriptValue().SetDynamicObject(overlay, overlay);
+}
+
+RuntimeScriptValue Sc_Overlay_CreateGraphicalRef(const RuntimeScriptValue *params, int32_t param_count) {
+ ASSERT_PARAM_COUNT(FUNCTION, 5);
+ ScriptOverlay *overlay = Overlay_CreateGraphicalEx(false, params[0].IValue, params[1].IValue, params[2].IValue,
+ params[3].IValue, params[4].GetAsBool());
return RuntimeScriptValue().SetDynamicObject(overlay, overlay);
}
RuntimeScriptValue Sc_Overlay_CreateRoomGraphical(const RuntimeScriptValue *params, int32_t param_count) {
- ASSERT_PARAM_COUNT(FUNCTION, 4);
+ ASSERT_PARAM_COUNT(FUNCTION, 5);
ScriptOverlay *overlay = Overlay_CreateGraphicalEx(true, params[0].IValue, params[1].IValue, params[2].IValue,
- params[3].IValue);
+ params[3].IValue, params[4].GetAsBool());
return RuntimeScriptValue().SetDynamicObject(overlay, overlay);
}
@@ -573,8 +580,9 @@ void ScPl_Overlay_SetText(ScriptOverlay *scover, int wii, int fontid, int clr, c
void RegisterOverlayAPI() {
ccAddExternalStaticFunction("Overlay::CreateGraphical^4", Sc_Overlay_CreateGraphical);
+ ccAddExternalStaticFunction("Overlay::CreateGraphical^5", Sc_Overlay_CreateGraphicalRef);
ccAddExternalStaticFunction("Overlay::CreateTextual^106", Sc_Overlay_CreateTextual);
- ccAddExternalStaticFunction("Overlay::CreateRoomGraphical^4", Sc_Overlay_CreateRoomGraphical);
+ ccAddExternalStaticFunction("Overlay::CreateRoomGraphical^5", Sc_Overlay_CreateRoomGraphical);
ccAddExternalStaticFunction("Overlay::CreateRoomTextual^106", Sc_Overlay_CreateRoomTextual);
ccAddExternalObjectFunction("Overlay::SetText^104", Sc_Overlay_SetText);
ccAddExternalObjectFunction("Overlay::Remove^0", Sc_Overlay_Remove);
diff --git a/engines/ags/engine/ac/overlay.h b/engines/ags/engine/ac/overlay.h
index 4bc2fdf6b9c..f9b3cd507d1 100644
--- a/engines/ags/engine/ac/overlay.h
+++ b/engines/ags/engine/ac/overlay.h
@@ -45,7 +45,7 @@ void Overlay_SetY(ScriptOverlay *scover, int newy);
int Overlay_GetValid(ScriptOverlay *scover);
ScriptOverlay *Overlay_CreateGraphical(int x, int y, int slot, int transparent);
ScriptOverlay *Overlay_CreateTextual(int x, int y, int width, int font, int colour, const char *text);
-ScreenOverlay *Overlay_CreateGraphicCore(bool room_layer, int x, int y, int slot, bool transparent);
+ScreenOverlay *Overlay_CreateGraphicCore(bool room_layer, int x, int y, int slot, bool transparent, bool clone);
ScreenOverlay *Overlay_CreateTextCore(bool room_layer, int x, int y, int width, int font, int text_color,
const char *text, int disp_type, int allow_shrink);
Commit: f782f0f2b29c5bf651cc734c75ae71018e1b9f87
https://github.com/scummvm/scummvm/commit/f782f0f2b29c5bf651cc734c75ae71018e1b9f87
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-05-08T11:37:49-07:00
Commit Message:
AGS: Implemented Overlay.Graphic
>From upstream b3ca7d110664f29f54c11315400486a0fc11d33a
Changed paths:
engines/ags/engine/ac/overlay.cpp
engines/ags/engine/ac/screen_overlay.cpp
diff --git a/engines/ags/engine/ac/overlay.cpp b/engines/ags/engine/ac/overlay.cpp
index e4990fc6aa2..a236892a8bc 100644
--- a/engines/ags/engine/ac/overlay.cpp
+++ b/engines/ags/engine/ac/overlay.cpp
@@ -101,6 +101,24 @@ void Overlay_SetY(ScriptOverlay *scover, int newy) {
_GP(screenover)[ovri].y = data_to_game_coord(newy);
}
+int Overlay_GetGraphic(ScriptOverlay *scover) {
+ int ovri = find_overlay_of_type(scover->overlayId);
+ if (ovri < 0)
+ quit("!invalid overlay ID specified");
+ return _GP(screenover)[ovri].GetSpriteNum();
+}
+
+void Overlay_SetGraphic(ScriptOverlay *scover, int slot) {
+ if (!_GP(spriteset).DoesSpriteExist(slot)) {
+ debug_script_warn("Overlay.SetGraphic: sprite %d is invalid", slot);
+ slot = 0;
+ }
+ int ovri = find_overlay_of_type(scover->overlayId);
+ if (ovri < 0)
+ quit("!invalid overlay ID specified");
+ _GP(screenover)[ovri].SetSpriteNum(slot);
+}
+
bool Overlay_InRoom(ScriptOverlay *scover) {
int ovri = find_overlay_of_type(scover->overlayId);
if (ovri < 0)
@@ -354,8 +372,6 @@ size_t add_screen_overlay_impl(bool roomlayer, int x, int y, int type, int sprnu
over.y = y;
over.offsetX = pic_offx;
over.offsetY = pic_offy;
- over.scaleWidth = over.GetImage()->GetWidth();
- over.scaleHeight = over.GetImage()->GetHeight();
// by default draw speech and portraits over GUI, and the rest under GUI
over.zorder = (roomlayer || type == OVER_TEXTMSG || type == OVER_PICTURE || type == OVER_TEXTSPEECH) ?
INT_MAX : INT_MIN;
@@ -521,6 +537,14 @@ RuntimeScriptValue Sc_Overlay_SetY(void *self, const RuntimeScriptValue *params,
API_OBJCALL_VOID_PINT(ScriptOverlay, Overlay_SetY);
}
+RuntimeScriptValue Sc_Overlay_GetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) {
+ API_OBJCALL_INT(ScriptOverlay, Overlay_GetGraphic);
+}
+
+RuntimeScriptValue Sc_Overlay_SetGraphic(void *self, const RuntimeScriptValue *params, int32_t param_count) {
+ API_OBJCALL_VOID_PINT(ScriptOverlay, Overlay_SetGraphic);
+}
+
RuntimeScriptValue Sc_Overlay_InRoom(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_BOOL(ScriptOverlay, Overlay_InRoom);
}
@@ -591,6 +615,8 @@ void RegisterOverlayAPI() {
ccAddExternalObjectFunction("Overlay::set_X", Sc_Overlay_SetX);
ccAddExternalObjectFunction("Overlay::get_Y", Sc_Overlay_GetY);
ccAddExternalObjectFunction("Overlay::set_Y", Sc_Overlay_SetY);
+ ccAddExternalObjectFunction("Overlay::get_Graphic", Sc_Overlay_GetGraphic);
+ ccAddExternalObjectFunction("Overlay::set_Graphic", Sc_Overlay_SetGraphic);
ccAddExternalObjectFunction("Overlay::get_InRoom", Sc_Overlay_InRoom);
ccAddExternalObjectFunction("Overlay::get_Width", Sc_Overlay_GetWidth);
ccAddExternalObjectFunction("Overlay::set_Width", Sc_Overlay_SetWidth);
diff --git a/engines/ags/engine/ac/screen_overlay.cpp b/engines/ags/engine/ac/screen_overlay.cpp
index 1727d95b169..8a286b47b0c 100644
--- a/engines/ags/engine/ac/screen_overlay.cpp
+++ b/engines/ags/engine/ac/screen_overlay.cpp
@@ -39,12 +39,28 @@ void ScreenOverlay::SetImage(Shared::Bitmap *pic) {
_flags &= ~kOver_SpriteReference;
_pic.reset(pic);
_sprnum = -1;
+ offsetX = offsetY = 0;
+ scaleWidth = scaleHeight = 0;
+ const auto *img = GetImage();
+ if (img) {
+ scaleWidth = img->GetWidth();
+ scaleHeight = img->GetHeight();
+ }
+ MarkChanged();
}
void ScreenOverlay::SetSpriteNum(int sprnum) {
_flags |= kOver_SpriteReference;
_pic.reset();
_sprnum = sprnum;
+ offsetX = offsetY = 0;
+ scaleWidth = scaleHeight = 0;
+ const auto *img = GetImage();
+ if (img) {
+ scaleWidth = img->GetWidth();
+ scaleHeight = img->GetHeight();
+ }
+ MarkChanged();
}
void ScreenOverlay::ReadFromFile(Stream *in, bool &has_bitmap, int32_t cmp_ver) {
Commit: c143ceb01b19e7bc40a5d55512489029ab7e7efe
https://github.com/scummvm/scummvm/commit/c143ceb01b19e7bc40a5d55512489029ab7e7efe
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-05-08T11:37:49-07:00
Commit Message:
AGS: Tidied and fixed InputBox to work with SDL2 input
>From upstream adec08a02664c0ab35ab358ca255ca6f2e3801b1
Changed paths:
engines/ags/engine/gui/csci_dialog.cpp
engines/ags/engine/gui/my_textbox.cpp
diff --git a/engines/ags/engine/gui/csci_dialog.cpp b/engines/ags/engine/gui/csci_dialog.cpp
index ca49b26d7c8..089992feddd 100644
--- a/engines/ags/engine/gui/csci_dialog.cpp
+++ b/engines/ags/engine/gui/csci_dialog.cpp
@@ -137,6 +137,7 @@ int CSCIWaitMessage(CSCIMessage *cscim) {
KeyInput ki;
if (run_service_key_controls(ki) && !_GP(play).IsIgnoringInput()) {
int keywas = ki.Key;
+ int uchar = ki.UChar;
if (keywas == eAGSKeyCodeReturn) {
cscim->id = finddefaultcontrol(CNF_DEFAULT);
cscim->code = CM_COMMAND;
@@ -147,7 +148,7 @@ int CSCIWaitMessage(CSCIMessage *cscim) {
else if ((keywas >= eAGSKeyCodeUpArrow) & (keywas <= eAGSKeyCodePageDown) & (finddefaultcontrol(CNT_LISTBOX) >= 0))
_G(vobjs)[finddefaultcontrol(CNT_LISTBOX)]->processmessage(CTB_KEYPRESS, keywas, 0);
else if (finddefaultcontrol(CNT_TEXTBOX) >= 0)
- _G(vobjs)[finddefaultcontrol(CNT_TEXTBOX)]->processmessage(CTB_KEYPRESS, keywas, 0);
+ _G(vobjs)[finddefaultcontrol(CNT_TEXTBOX)]->processmessage(CTB_KEYPRESS, keywas, uchar);
if (cscim->id < 0) {
cscim->code = CM_KEYPRESS;
diff --git a/engines/ags/engine/gui/my_textbox.cpp b/engines/ags/engine/gui/my_textbox.cpp
index 98ba424a20b..0737aeb6ff4 100644
--- a/engines/ags/engine/gui/my_textbox.cpp
+++ b/engines/ags/engine/gui/my_textbox.cpp
@@ -59,28 +59,35 @@ int MyTextBox::pressedon(int /*mx*/, int /*my*/) {
}
int MyTextBox::processmessage(int mcode, int wParam, NumberPtr lParam) {
+
if (mcode == CTB_SETTEXT) {
- strcpy(text, (char *)lParam._ptr);
+ snprintf(text, sizeof(text), "%s", (const char *)lParam._ptr);
needredraw = 1;
} else if (mcode == CTB_GETTEXT)
- strcpy((char *)lParam._ptr, text);
+ strcpy((char *)lParam._ptr, text); // FIXME! dangerous
else if (mcode == CTB_KEYPRESS) {
+ // NOTE: this deprecated control does not support UTF-8
+ //int key = wParam;
+ int uchar = lParam;
+ size_t len = strlen(text);
if (wParam == eAGSKeyCodeBackspace) {
- if (text[0] != 0)
- text[strlen(text) - 1] = 0;
-
- drawandmouse();
- } else if (strlen(text) >= TEXTBOX_MAXLEN - 1)
- ;
- else if (get_text_width(text, _G(cbuttfont)) >= wid - 5)
- ;
- else if (wParam > 127)
- ; // font only has 128 chars
- else {
- text[strlen(text) + 1] = 0;
- text[strlen(text)] = wParam;
+ if (len > 0)
+ text[len - 1] = 0;
drawandmouse();
+ return 0;
}
+
+ if (len >= TEXTBOX_MAXLEN - 1)
+ return 0; // buffer full;
+ if (uchar == 0)
+ return 0; // not a textual event
+ if ((uchar >= 128) && (!font_supports_extended_characters(_G(cbuttfont))))
+ return 0; // unsupported letter
+ if (get_text_width(text, _G(cbuttfont)) >= wid - 5)
+ return 0; // not enough control space
+ text[len] = uchar;
+ text[len + 1] = 0;
+ drawandmouse();
} else
return -1;
Commit: a123a7473f9034c837fee3b13e280c1d04d4e35a
https://github.com/scummvm/scummvm/commit/a123a7473f9034c837fee3b13e280c1d04d4e35a
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-05-08T11:37:49-07:00
Commit Message:
AGS: Updated build version (3.6.0.25)
>From upstream 7e426edb3530e9d89120f614c33e52ddf13881d9
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 280071ee0f1..bfdda2ca64c 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.0.24"
+#define ACI_VERSION_STR "3.6.0.25"
#if defined (RC_INVOKED) // for MSVC resource compiler
-#define ACI_VERSION_MSRC_DEF 3.6.0.24
+#define ACI_VERSION_MSRC_DEF 3.6.0.25
#endif
#define SPECIAL_VERSION ""
Commit: 1607b2530bf3e43d5bd6636843821277978a8d0d
https://github.com/scummvm/scummvm/commit/1607b2530bf3e43d5bd6636843821277978a8d0d
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-05-08T11:37:49-07:00
Commit Message:
AGS: Fixed script errors when non-obligatory callbacks are missing
>From upstream 29aaa19d712c3edf5701c648833283011c2f7298
Changed paths:
engines/ags/engine/script/script.cpp
engines/ags/shared/script/cc_common.cpp
engines/ags/shared/script/cc_common.h
diff --git a/engines/ags/engine/script/script.cpp b/engines/ags/engine/script/script.cpp
index 75dbe6a1a62..56161a4d6f4 100644
--- a/engines/ags/engine/script/script.cpp
+++ b/engines/ags/engine/script/script.cpp
@@ -343,13 +343,21 @@ static int PrepareTextScript(ccInstance *sci, const char **tsname) {
int RunScriptFunction(ccInstance *sci, const char *tsname, size_t numParam, const RuntimeScriptValue *params) {
int oldRestoreCount = _G(gameHasBeenRestored);
+ // TODO: research why this is really necessary, and refactor to avoid such hacks!
+ // First, save the current ccError state
+ // This is necessary because we might be attempting
+ // to run Script B, while Script A is still running in the
+ // background.
+ // If CallInstance here has an error, it would otherwise
+ // also abort Script A because ccError is a global variable.
+ ScriptError cachedCcError = cc_get_error();
cc_clear_error();
int toret = PrepareTextScript(sci, &tsname);
if (toret) {
+ cc_error(cachedCcError);
return -18;
}
-
cc_clear_error();
toret = _G(curscript)->inst->CallScriptFunction(tsname, numParam, params);
@@ -367,6 +375,9 @@ int RunScriptFunction(ccInstance *sci, const char *tsname, size_t numParam, cons
_G(post_script_cleanup_stack)--;
+ // restore cached error state
+ cc_error(cachedCcError);
+
// if the game has been restored, ensure that any further scripts are not run
if ((oldRestoreCount != _G(gameHasBeenRestored)) && (_G(eventClaimed) == EVENT_INPROGRESS))
_G(eventClaimed) = EVENT_CLAIMED;
diff --git a/engines/ags/shared/script/cc_common.cpp b/engines/ags/shared/script/cc_common.cpp
index 76bc36a3415..1c7af24d48d 100644
--- a/engines/ags/shared/script/cc_common.cpp
+++ b/engines/ags/shared/script/cc_common.cpp
@@ -74,4 +74,8 @@ void cc_error(const char *descr, ...) {
_GP(ccError).Line = _G(currentline);
}
+void cc_error(const ScriptError &err) {
+ _GP(ccError) = err;
+}
+
} // namespace AGS3
diff --git a/engines/ags/shared/script/cc_common.h b/engines/ags/shared/script/cc_common.h
index e2a2b6cc242..19c758a29fa 100644
--- a/engines/ags/shared/script/cc_common.h
+++ b/engines/ags/shared/script/cc_common.h
@@ -55,6 +55,7 @@ void cc_clear_error();
bool cc_has_error();
const ScriptError &cc_get_error();
void cc_error(const char *, ...);
+void cc_error(const ScriptError &err);
// Project-dependent script error formatting
AGS::Shared::String cc_format_error(const AGS::Shared::String &message);
More information about the Scummvm-git-logs
mailing list