[Scummvm-git-logs] scummvm master -> b07b63920a7977c36b7d47905e11e8e502512626
dreammaster
noreply at scummvm.org
Wed Mar 16 05:29:46 UTC 2022
This automated email contains information about 10 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
6bf83c7f39 AGS: Removed Overlays' arbitrary limit
bde0988e08 AGS: fixed speech overlays drawn behind GUI
8c60e694cc AGS: Simplified SpriteListEntry use
d4e81c2ecb AGS: Moved irrelevant code out from draw_sprite_list()
2b7e671eb7 AGS: Remade VideoMemDDB class into BaseDDB, tidy ddb declarations
ccb87178d5 AGS: Simplified add_to_sprite_list() argument list
46f1f776c9 AGS: Sort overlays along with GUI
796c2dcd0e AGS: Overlay.ZOrder and use zorder for custom overlays
731db80bb4 AGS: Script API Overlay.Transparency
b07b63920a AGS: Serialize overlay.z and transparency
Commit: 6bf83c7f391548dad8a8c06f7277b42699b75508
https://github.com/scummvm/scummvm/commit/6bf83c7f391548dad8a8c06f7277b42699b75508
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-03-15T22:28:36-07:00
Commit Message:
AGS: Removed Overlays' arbitrary limit
>From upstream 735dcfb14069b38aace4cef9468d44b63349d1bd
Changed paths:
engines/ags/engine/ac/character.cpp
engines/ags/engine/ac/display.cpp
engines/ags/engine/ac/draw.cpp
engines/ags/engine/ac/dynobj/script_overlay.cpp
engines/ags/engine/ac/global_character.cpp
engines/ags/engine/ac/global_overlay.cpp
engines/ags/engine/ac/overlay.cpp
engines/ags/engine/ac/overlay.h
engines/ags/engine/ac/runtime_defines.h
engines/ags/engine/game/savegame_components.cpp
engines/ags/engine/game/savegame_v321.cpp
engines/ags/engine/main/update.cpp
engines/ags/globals.cpp
engines/ags/globals.h
diff --git a/engines/ags/engine/ac/character.cpp b/engines/ags/engine/ac/character.cpp
index 705639a4778..17247d1e723 100644
--- a/engines/ags/engine/ac/character.cpp
+++ b/engines/ags/engine/ac/character.cpp
@@ -707,7 +707,7 @@ ScriptOverlay *Character_SayBackground(CharacterInfo *chaa, const char *texx) {
if (ovri < 0)
quit("!SayBackground internal error: no overlay");
- ScriptOverlay *scOver = create_scriptobj_for_overlay(_G(screenover)[ovri]);
+ ScriptOverlay *scOver = create_scriptobj_for_overlay(_GP(screenover)[ovri]);
scOver->borderHeight = 0;
scOver->borderWidth = 0;
scOver->isBackgroundSpeech = 1;
@@ -2265,14 +2265,13 @@ void _displayspeech(const char *texx, int aschar, int xx, int yy, int widd, int
_G(said_speech_line) = 1;
- int aa;
if (_GP(play).bgspeech_stay_on_display == 0) {
// remove any background speech
- for (aa = 0; aa < _G(numscreenover); aa++) {
- if (_G(screenover)[aa].timeout > 0) {
- remove_screen_overlay(_G(screenover)[aa].type);
- aa--;
- }
+ for (size_t i = 0; i < _GP(screenover).size();) {
+ if (_GP(screenover)[i].timeout > 0)
+ remove_screen_overlay(_GP(screenover)[i].type);
+ else
+ i++;
}
}
_G(said_text) = 1;
@@ -2283,7 +2282,7 @@ void _displayspeech(const char *texx, int aschar, int xx, int yy, int widd, int
int isPause = 1;
// if the message is all .'s, don't display anything
- for (aa = 0; texx[aa] != 0; aa++) {
+ for (size_t aa = 0; texx[aa] != 0; aa++) {
if (texx[aa] != '.') {
isPause = 0;
break;
diff --git a/engines/ags/engine/ac/display.cpp b/engines/ags/engine/ac/display.cpp
index 4734132dac1..62a7d458bec 100644
--- a/engines/ags/engine/ac/display.cpp
+++ b/engines/ags/engine/ac/display.cpp
@@ -258,7 +258,7 @@ int _display_main(int xx, int yy, int wii, const char *text, int disp_type, int
// we should not delete text_window_ds here, because it is now owned by Overlay
if (disp_type >= DISPLAYTEXT_NORMALOVERLAY) {
- return _G(screenover)[nse].type;
+ return _GP(screenover)[nse].type;
}
//
@@ -346,10 +346,10 @@ int _display_main(int xx, int yy, int wii, const char *text, int disp_type, int
_GP(play).messagetime = 2;
if (!overlayPositionFixed) {
- _G(screenover)[nse].positionRelativeToScreen = false;
- VpPoint vpt = _GP(play).GetRoomViewport(0)->ScreenToRoom(_G(screenover)[nse].x, _G(screenover)[nse].y, false);
- _G(screenover)[nse].x = vpt.first.X;
- _G(screenover)[nse].y = vpt.first.Y;
+ _GP(screenover)[nse].positionRelativeToScreen = false;
+ VpPoint vpt = _GP(play).GetRoomViewport(0)->ScreenToRoom(_GP(screenover)[nse].x, _GP(screenover)[nse].y, false);
+ _GP(screenover)[nse].x = vpt.first.X;
+ _GP(screenover)[nse].y = vpt.first.Y;
}
GameLoopUntilNoOverlay();
diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp
index fd26f053966..7cc060ae416 100644
--- a/engines/ags/engine/ac/draw.cpp
+++ b/engines/ags/engine/ac/draw.cpp
@@ -1954,20 +1954,18 @@ void draw_fps(const Rect &viewport) {
// Draw GUI and overlays of all kinds, anything outside the room space
void draw_gui_and_overlays() {
- int gg;
-
if (pl_any_want_hook(AGSE_PREGUIDRAW))
add_thing_to_draw(nullptr, AGSE_PREGUIDRAW, 0, TRANS_RUN_PLUGIN, false);
// draw overlays, except text boxes and portraits
- for (gg = 0; gg < _G(numscreenover); gg++) {
+ for (const auto &over : _GP(screenover)) {
// complete overlay draw in non-transparent mode
- if (_G(screenover)[gg].type == OVER_COMPLETE)
- add_thing_to_draw(_G(screenover)[gg].bmp, _G(screenover)[gg].x, _G(screenover)[gg].y, TRANS_OPAQUE, false);
- else if (_G(screenover)[gg].type != OVER_TEXTMSG && _G(screenover)[gg].type != OVER_PICTURE) {
+ if (over.type == OVER_COMPLETE)
+ add_thing_to_draw(over.bmp, over.x, over.y, TRANS_OPAQUE, false);
+ else if (over.type != OVER_TEXTMSG && over.type != OVER_PICTURE) {
int tdxp, tdyp;
- get_overlay_position(_G(screenover)[gg], &tdxp, &tdyp);
- add_thing_to_draw(_G(screenover)[gg].bmp, tdxp, tdyp, 0, _G(screenover)[gg].hasAlphaChannel);
+ get_overlay_position(over, &tdxp, &tdyp);
+ add_thing_to_draw(over.bmp, tdxp, tdyp, 0, over.hasAlphaChannel);
}
}
@@ -2024,7 +2022,7 @@ void draw_gui_and_overlays() {
}
_G(our_eip) = 38;
// Draw the GUIs
- for (gg = 0; gg < _GP(game).numgui; gg++) {
+ for (int gg = 0; gg < _GP(game).numgui; gg++) {
aa = _GP(play).gui_draw_order[gg];
if (!_GP(guis)[aa].IsDisplayed()) continue;
if (_GP(guis)[aa].Transparency == 255) continue;
@@ -2045,11 +2043,11 @@ void draw_gui_and_overlays() {
}
// draw speech and portraits (so that they appear over GUIs)
- for (gg = 0; gg < _G(numscreenover); gg++) {
- if (_G(screenover)[gg].type == OVER_TEXTMSG || _G(screenover)[gg].type == OVER_PICTURE) {
+ for (const auto &over : _GP(screenover)) {
+ if (over.type == OVER_TEXTMSG || over.type == OVER_PICTURE) {
int tdxp, tdyp;
- get_overlay_position(_G(screenover)[gg], &tdxp, &tdyp);
- add_thing_to_draw(_G(screenover)[gg].bmp, tdxp, tdyp, 0, false);
+ get_overlay_position(over, &tdxp, &tdyp);
+ add_thing_to_draw(over.bmp, tdxp, tdyp, 0, false);
}
}
diff --git a/engines/ags/engine/ac/dynobj/script_overlay.cpp b/engines/ags/engine/ac/dynobj/script_overlay.cpp
index e6d887c31a0..f28cd5e3aa3 100644
--- a/engines/ags/engine/ac/dynobj/script_overlay.cpp
+++ b/engines/ags/engine/ac/dynobj/script_overlay.cpp
@@ -35,7 +35,7 @@ int ScriptOverlay::Dispose(const char *address, bool force) {
// with that handle later
int overlayIndex = find_overlay_of_type(overlayId);
if (overlayIndex >= 0) {
- _G(screenover)[overlayIndex].associatedOverlayHandle = 0;
+ _GP(screenover)[overlayIndex].associatedOverlayHandle = 0;
}
// if this is being removed voluntarily (ie. pointer out of
diff --git a/engines/ags/engine/ac/global_character.cpp b/engines/ags/engine/ac/global_character.cpp
index d0756c7aa18..5f3e26687b0 100644
--- a/engines/ags/engine/ac/global_character.cpp
+++ b/engines/ags/engine/ac/global_character.cpp
@@ -548,20 +548,19 @@ void DisplaySpeechAt(int xx, int yy, int wii, int aschar, const char *spch) {
int DisplaySpeechBackground(int charid, const char *speel) {
// remove any previous background speech for this character
- int cc;
- for (cc = 0; cc < _G(numscreenover); cc++) {
- if (_G(screenover)[cc].bgSpeechForChar == charid) {
- remove_screen_overlay_index(cc);
- cc--;
- }
+ for (size_t i = 0; i < _GP(screenover).size();) {
+ if (_GP(screenover)[i].bgSpeechForChar == charid)
+ remove_screen_overlay_index(i);
+ else
+ i++;
}
int ovrl = CreateTextOverlay(OVR_AUTOPLACE, charid, _GP(play).GetUIViewport().GetWidth() / 2, FONT_SPEECH,
-_GP(game).chars[charid].talkcolor, get_translation(speel), DISPLAYTEXT_NORMALOVERLAY);
int scid = find_overlay_of_type(ovrl);
- _G(screenover)[scid].bgSpeechForChar = charid;
- _G(screenover)[scid].timeout = GetTextDisplayTime(speel, 1);
+ _GP(screenover)[scid].bgSpeechForChar = charid;
+ _GP(screenover)[scid].timeout = GetTextDisplayTime(speel, 1);
return ovrl;
}
diff --git a/engines/ags/engine/ac/global_overlay.cpp b/engines/ags/engine/ac/global_overlay.cpp
index 01466e9aa3a..c2c26a2cbbf 100644
--- a/engines/ags/engine/ac/global_overlay.cpp
+++ b/engines/ags/engine/ac/global_overlay.cpp
@@ -52,7 +52,7 @@ int CreateGraphicOverlay(int xx, int yy, int slott, int trans) {
wputblock(screeno, 0, 0, _GP(spriteset)[slott], trans);
bool hasAlpha = (_GP(game).SpriteInfos[slott].Flags & SPF_ALPHACHANNEL) != 0;
int nse = add_screen_overlay(xx, yy, OVER_CUSTOM, screeno, hasAlpha);
- return _G(screenover)[nse].type;
+ return _GP(screenover)[nse].type;
}
int CreateTextOverlayCore(int xx, int yy, int wii, int fontid, int text_color, const char *text, int disp_type, int allowShrink) {
@@ -86,8 +86,8 @@ void MoveOverlay(int ovrid, int newx, int newy) {
int ovri = find_overlay_of_type(ovrid);
if (ovri < 0) quit("!MoveOverlay: invalid overlay ID specified");
- _G(screenover)[ovri].x = newx;
- _G(screenover)[ovri].y = newy;
+ _GP(screenover)[ovri].x = newx;
+ _GP(screenover)[ovri].y = newy;
}
int IsOverlayValid(int ovrid) {
diff --git a/engines/ags/engine/ac/overlay.cpp b/engines/ags/engine/ac/overlay.cpp
index 7aa8743de39..af73beca9ec 100644
--- a/engines/ags/engine/ac/overlay.cpp
+++ b/engines/ags/engine/ac/overlay.cpp
@@ -54,8 +54,8 @@ void Overlay_SetText(ScriptOverlay *scover, int wii, int fontid, int text_color,
int ovri = find_overlay_of_type(scover->overlayId);
if (ovri < 0)
quit("!Overlay.SetText: invalid overlay ID specified");
- int xx = game_to_data_coord(_G(screenover)[ovri].x) - scover->borderWidth;
- int yy = game_to_data_coord(_G(screenover)[ovri].y) - scover->borderHeight;
+ int xx = game_to_data_coord(_GP(screenover)[ovri].x) - scover->borderWidth;
+ int yy = game_to_data_coord(_GP(screenover)[ovri].y) - scover->borderHeight;
RemoveOverlay(scover->overlayId);
const int disp_type = scover->overlayId;
@@ -70,7 +70,7 @@ int Overlay_GetX(ScriptOverlay *scover) {
quit("!invalid overlay ID specified");
int tdxp, tdyp;
- get_overlay_position(_G(screenover)[ovri], &tdxp, &tdyp);
+ get_overlay_position(_GP(screenover)[ovri], &tdxp, &tdyp);
return game_to_data_coord(tdxp);
}
@@ -80,7 +80,7 @@ void Overlay_SetX(ScriptOverlay *scover, int newx) {
if (ovri < 0)
quit("!invalid overlay ID specified");
- _G(screenover)[ovri].x = data_to_game_coord(newx);
+ _GP(screenover)[ovri].x = data_to_game_coord(newx);
}
int Overlay_GetY(ScriptOverlay *scover) {
@@ -89,7 +89,7 @@ int Overlay_GetY(ScriptOverlay *scover) {
quit("!invalid overlay ID specified");
int tdxp, tdyp;
- get_overlay_position(_G(screenover)[ovri], &tdxp, &tdyp);
+ get_overlay_position(_GP(screenover)[ovri], &tdxp, &tdyp);
return game_to_data_coord(tdyp);
}
@@ -99,21 +99,21 @@ void Overlay_SetY(ScriptOverlay *scover, int newy) {
if (ovri < 0)
quit("!invalid overlay ID specified");
- _G(screenover)[ovri].y = data_to_game_coord(newy);
+ _GP(screenover)[ovri].y = data_to_game_coord(newy);
}
int Overlay_GetWidth(ScriptOverlay *scover) {
int ovri = find_overlay_of_type(scover->overlayId);
if (ovri < 0)
quit("!invalid overlay ID specified");
- return game_to_data_coord(_G(screenover)[ovri].pic->GetWidth());
+ return game_to_data_coord(_GP(screenover)[ovri].pic->GetWidth());
}
int Overlay_GetHeight(ScriptOverlay *scover) {
int ovri = find_overlay_of_type(scover->overlayId);
if (ovri < 0)
quit("!invalid overlay ID specified");
- return game_to_data_coord(_G(screenover)[ovri].pic->GetHeight());
+ return game_to_data_coord(_GP(screenover)[ovri].pic->GetHeight());
}
int Overlay_GetValid(ScriptOverlay *scover) {
@@ -148,8 +148,8 @@ ScriptOverlay *Overlay_CreateTextual(int x, int y, int width, int font, int colo
sco->overlayId = CreateTextOverlayCore(x, y, width, font, colour, text, DISPLAYTEXT_NORMALOVERLAY, 0);
int ovri = find_overlay_of_type(sco->overlayId);
- sco->borderWidth = game_to_data_coord(_G(screenover)[ovri].x - x);
- sco->borderHeight = game_to_data_coord(_G(screenover)[ovri].y - y);
+ sco->borderWidth = game_to_data_coord(_GP(screenover)[ovri].x - x);
+ sco->borderHeight = game_to_data_coord(_GP(screenover)[ovri].y - y);
sco->isBackgroundSpeech = 0;
ccRegisterManagedObject(sco, sco);
@@ -194,8 +194,8 @@ static void dispose_overlay(ScreenOverlay &over) {
ccAttemptDisposeObject(over.associatedOverlayHandle);
}
-void remove_screen_overlay_index(int over_idx) {
- ScreenOverlay &over = _G(screenover)[over_idx];
+void remove_screen_overlay_index(size_t over_idx) {
+ ScreenOverlay &over = _GP(screenover)[over_idx];
// TODO: move these custom settings outside of this function
if (over.type == _GP(play).complete_overlay_on) {
_GP(play).complete_overlay_on = 0;
@@ -209,18 +209,16 @@ void remove_screen_overlay_index(int over_idx) {
_G(face_talking) = -1;
}
dispose_overlay(over);
- _G(numscreenover)--;
- for (int i = over_idx; i < _G(numscreenover); ++i)
- _G(screenover)[i] = _G(screenover)[i + 1];
+ _GP(screenover).erase(_GP(screenover).begin() + over_idx);
// if an overlay before the sierra-style speech one is removed, update the index
// TODO: this is bad, need more generic system to store overlay references
- if (_G(face_talking) > over_idx)
+ if ((size_t)_G(face_talking) > over_idx)
_G(face_talking)--;
}
void remove_screen_overlay(int type) {
- for (int i = 0; i < _G(numscreenover);) {
- if (type < 0 || _G(screenover)[i].type == type)
+ for (size_t i = 0; i < _GP(screenover).size();) {
+ if (type < 0 || _GP(screenover)[i].type == type)
remove_screen_overlay_index(i);
else
i++;
@@ -228,28 +226,27 @@ void remove_screen_overlay(int type) {
}
int find_overlay_of_type(int type) {
- for (int i = 0; i < _G(numscreenover); ++i) {
- if (_G(screenover)[i].type == type) return i;
+ for (size_t i = 0; i < _GP(screenover).size(); ++i) {
+ if (_GP(screenover)[i].type == type) return i;
}
return -1;
}
-int add_screen_overlay(int x, int y, int type, Bitmap *piccy, bool alphaChannel) {
+size_t add_screen_overlay(int x, int y, int type, Bitmap *piccy, bool alphaChannel) {
return add_screen_overlay(x, y, type, piccy, 0, 0, alphaChannel);
}
-int add_screen_overlay(int x, int y, int type, Shared::Bitmap *piccy, int pic_offx, int pic_offy, bool alphaChannel) {
+size_t add_screen_overlay(int x, int y, int type, Shared::Bitmap *piccy, int pic_offx, int pic_offy, bool alphaChannel) {
if (type == OVER_CUSTOM) {
// find an unused custom ID; TODO: find a better approach!
- for (int id = OVER_CUSTOM + 1; id < OVER_CUSTOM + 100; ++id) {
+ for (uint id = OVER_CUSTOM + 1; id <= _GP(screenover).size() + OVER_CUSTOM + 1; ++id) {
if (find_overlay_of_type(id) == -1) {
- type = id;
- break;
+ type = id; break;
}
}
}
- ScreenOverlay &over = _G(screenover)[_G(numscreenover)++];
+ ScreenOverlay over;
over.pic = piccy;
over.bmp = _G(gfxDriver)->CreateDDBFromBitmap(piccy, alphaChannel);
over.x = x;
@@ -273,7 +270,9 @@ int add_screen_overlay(int x, int y, int type, Shared::Bitmap *piccy, int pic_of
} else if (type == OVER_PICTURE) {
_GP(play).speech_face_scover = create_scriptobj_addref(over);
}
- return _G(numscreenover) - 1;
+
+ _GP(screenover).push_back(std::move(over));
+ return _GP(screenover).size() - 1;
}
void get_overlay_position(const ScreenOverlay &over, int *x, int *y) {
@@ -319,13 +318,13 @@ void get_overlay_position(const ScreenOverlay &over, int *x, int *y) {
}
void recreate_overlay_ddbs() {
- for (int i = 0; i < _G(numscreenover); ++i) {
- if (_G(screenover)[i].bmp)
- _G(gfxDriver)->DestroyDDB(_G(screenover)[i].bmp);
- if (_G(screenover)[i].pic)
- _G(screenover)[i].bmp = _G(gfxDriver)->CreateDDBFromBitmap(_G(screenover)[i].pic, false);
+ for (auto &over : _GP(screenover)) {
+ if (over.bmp)
+ _G(gfxDriver)->DestroyDDB(over.bmp);
+ if (over.pic)
+ over.bmp = _G(gfxDriver)->CreateDDBFromBitmap(over.pic, false);
else
- _G(screenover)[i].bmp = nullptr;
+ over.bmp = nullptr;
}
}
diff --git a/engines/ags/engine/ac/overlay.h b/engines/ags/engine/ac/overlay.h
index 8c181124db4..bd7f07bb72d 100644
--- a/engines/ags/engine/ac/overlay.h
+++ b/engines/ags/engine/ac/overlay.h
@@ -22,7 +22,6 @@
#ifndef AGS_ENGINE_AC_OVERLAY_H
#define AGS_ENGINE_AC_OVERLAY_H
-#include "ags/engine/ac/runtime_defines.h"
#include "ags/engine/ac/screen_overlay.h"
#include "ags/engine/ac/dynobj/script_overlay.h"
@@ -50,9 +49,9 @@ int find_overlay_of_type(int type);
void remove_screen_overlay(int type);
// Calculates overlay position in screen coordinates
void get_overlay_position(const ScreenOverlay &over, int *x, int *y);
-int add_screen_overlay(int x, int y, int type, Shared::Bitmap *piccy, bool alphaChannel = false);
-int add_screen_overlay(int x, int y, int type, Shared::Bitmap *piccy, int pic_offx, int pic_offy, bool alphaChannel = false);
-void remove_screen_overlay_index(int over_idx);
+size_t add_screen_overlay(int x, int y, int type, Shared::Bitmap *piccy, bool alphaChannel = false);
+size_t add_screen_overlay(int x, int y, int type, Shared::Bitmap *piccy, int pic_offx, int pic_offy, bool alphaChannel = false);
+void remove_screen_overlay_index(size_t over_idx);
// Creates and registers a managed script object for existing overlay object
ScriptOverlay *create_scriptobj_for_overlay(ScreenOverlay &over);
void recreate_overlay_ddbs();
diff --git a/engines/ags/engine/ac/runtime_defines.h b/engines/ags/engine/ac/runtime_defines.h
index 78dddc288a7..76c8802e0a8 100644
--- a/engines/ags/engine/ac/runtime_defines.h
+++ b/engines/ags/engine/ac/runtime_defines.h
@@ -118,7 +118,6 @@ const int LegacyRoomVolumeFactor = 30;
#define FOR_SCRIPT 2
#define FOR_EXITLOOP 3
#define CHMLSOFFS (MAX_ROOM_OBJECTS+1) // reserve this many movelists for objects & stuff
-#define MAX_SCREEN_OVERLAYS 20
#define abort_all_conditions _G(restrict_until)
#define MAX_SCRIPT_AT_ONCE 10
#define EVENT_NONE 0
diff --git a/engines/ags/engine/game/savegame_components.cpp b/engines/ags/engine/game/savegame_components.cpp
index 23d559e83de..80f13a7504f 100644
--- a/engines/ags/engine/game/savegame_components.cpp
+++ b/engines/ags/engine/game/savegame_components.cpp
@@ -746,24 +746,23 @@ HSaveError ReadDynamicSprites(Stream *in, int32_t cmp_ver, const PreservedParams
}
HSaveError WriteOverlays(Stream *out) {
- out->WriteInt32(_G(numscreenover));
- for (int i = 0; i < _G(numscreenover); ++i) {
- _G(screenover)[i].WriteToFile(out);
- serialize_bitmap(_G(screenover)[i].pic, out);
+ out->WriteInt32(_GP(screenover).size());
+ for (const auto &over : _GP(screenover)) {
+ over.WriteToFile(out);
+ serialize_bitmap(over.pic, out);
}
return HSaveError::None();
}
HSaveError ReadOverlays(Stream *in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) {
HSaveError err;
- int over_count = in->ReadInt32();
- if (!AssertCompatLimit(err, over_count, MAX_SCREEN_OVERLAYS, "overlays"))
- return err;
- _G(numscreenover) = over_count;
- for (int i = 0; i < _G(numscreenover); ++i) {
- _G(screenover)[i].ReadFromFile(in, cmp_ver);
- if (_G(screenover)[i].hasSerializedBitmap)
- _G(screenover)[i].pic = read_serialized_bitmap(in);
+ size_t over_count = in->ReadInt32();
+ for (size_t i = 0; i < over_count; ++i) {
+ ScreenOverlay over;
+ over.ReadFromFile(in, cmp_ver);
+ if (over.hasSerializedBitmap)
+ over.pic = read_serialized_bitmap(in);
+ _GP(screenover).push_back(over);
}
return err;
}
diff --git a/engines/ags/engine/game/savegame_v321.cpp b/engines/ags/engine/game/savegame_v321.cpp
index 815bffe669f..8e849caef7d 100644
--- a/engines/ags/engine/game/savegame_v321.cpp
+++ b/engines/ags/engine/game/savegame_v321.cpp
@@ -267,20 +267,21 @@ static void restore_game_ambientsounds(Stream *in, RestoredData &r_data) {
}
}
-static void ReadOverlays_Aligned(Stream *in) {
+static void ReadOverlays_Aligned(Stream *in, size_t num_overs) {
AlignedStream align_s(in, Shared::kAligned_Read);
- for (int i = 0; i < _G(numscreenover); ++i) {
- _G(screenover)[i].ReadFromFile(&align_s, 0);
+ for (size_t i = 0; i < num_overs; ++i) {
+ _GP(screenover)[i].ReadFromFile(&align_s, 0);
align_s.Reset();
}
}
static void restore_game_overlays(Stream *in) {
- _G(numscreenover) = in->ReadInt32();
- ReadOverlays_Aligned(in);
- for (int bb = 0; bb < _G(numscreenover); bb++) {
- if (_G(screenover)[bb].hasSerializedBitmap)
- _G(screenover)[bb].pic = read_serialized_bitmap(in);
+ size_t num_overs = in->ReadInt32();
+ _GP(screenover).resize(num_overs);
+ ReadOverlays_Aligned(in, num_overs);
+ for (size_t i = 0; i < num_overs; ++i) {
+ if (_GP(screenover)[i].hasSerializedBitmap)
+ _GP(screenover)[i].pic = read_serialized_bitmap(in);
}
}
diff --git a/engines/ags/engine/main/update.cpp b/engines/ags/engine/main/update.cpp
index 2cab5a488d2..a927dbb9eb0 100644
--- a/engines/ags/engine/main/update.cpp
+++ b/engines/ags/engine/main/update.cpp
@@ -220,12 +220,15 @@ void update_following_exactly_characters(int &numSheep, int *followingAsSheep) {
void update_overlay_timers() {
// update overlay timers
- for (int aa = 0; aa < _G(numscreenover); aa++) {
- if (_G(screenover)[aa].timeout > 0) {
- _G(screenover)[aa].timeout--;
- if (_G(screenover)[aa].timeout == 0)
- remove_screen_overlay(_G(screenover)[aa].type);
+ for (size_t i = 0; i < _GP(screenover).size();) {
+ if (_GP(screenover)[i].timeout > 0) {
+ _GP(screenover)[i].timeout--;
+ if (_GP(screenover)[i].timeout == 0) {
+ remove_screen_overlay_index(i);
+ continue;
+ }
}
+ i++;
}
}
@@ -390,14 +393,14 @@ void update_sierra_speech() {
if (_G(facetalk_qfg4_override_placement_y)) {
view_frame_y = _GP(play).speech_portrait_y;
} else {
- view_frame_y = (_G(screenover)[_G(face_talking)].pic->GetHeight() / 2) - (_GP(game).SpriteInfos[thisPic].Height / 2);
+ view_frame_y = (_GP(screenover)[_G(face_talking)].pic->GetHeight() / 2) - (_GP(game).SpriteInfos[thisPic].Height / 2);
}
- _G(screenover)[_G(face_talking)].pic->Clear(0);
+ _GP(screenover)[_G(face_talking)].pic->Clear(0);
} else {
- _G(screenover)[_G(face_talking)].pic->ClearTransparent();
+ _GP(screenover)[_G(face_talking)].pic->ClearTransparent();
}
- Bitmap *frame_pic = _G(screenover)[_G(face_talking)].pic;
+ Bitmap *frame_pic = _GP(screenover)[_G(face_talking)].pic;
const ViewFrame *face_vf = &_G(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);
@@ -409,7 +412,7 @@ void update_sierra_speech() {
DrawViewFrame(frame_pic, blink_vf, view_frame_x, view_frame_y, face_has_alpha);
}
- _G(gfxDriver)->UpdateDDBFromBitmap(_G(screenover)[_G(face_talking)].bmp, _G(screenover)[_G(face_talking)].pic, face_has_alpha);
+ _G(gfxDriver)->UpdateDDBFromBitmap(_GP(screenover)[_G(face_talking)].bmp, _GP(screenover)[_G(face_talking)].pic, face_has_alpha);
} // end if updatedFrame
}
}
diff --git a/engines/ags/globals.cpp b/engines/ags/globals.cpp
index 613366bda3b..2e42791721d 100644
--- a/engines/ags/globals.cpp
+++ b/engines/ags/globals.cpp
@@ -303,7 +303,7 @@ Globals::Globals() {
_mouse = new Mouse();
// overlay.cpp globals
- _screenover = new ScreenOverlay[MAX_SCREEN_OVERLAYS];
+ _screenover = new std::vector<ScreenOverlay>();
// plugins globals
_engineExports = new Plugins::Core::EngineExports();
@@ -540,7 +540,7 @@ Globals::~Globals() {
delete _mouse;
// overlay.cpp globals
- delete[] _screenover;
+ delete _screenover;
// plugins globals
delete _engineExports;
diff --git a/engines/ags/globals.h b/engines/ags/globals.h
index 18ed2a1d4ee..fff26b1577f 100644
--- a/engines/ags/globals.h
+++ b/engines/ags/globals.h
@@ -1149,9 +1149,8 @@ public:
* @{
*/
- ScreenOverlay *_screenover;
+ std::vector<ScreenOverlay> *_screenover;
int _is_complete_overlay = 0;
- int _numscreenover = 0;
/**@}*/
Commit: bde0988e0894d1a317e4111dc93a3107a90ac965
https://github.com/scummvm/scummvm/commit/bde0988e0894d1a317e4111dc93a3107a90ac965
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-03-15T22:28:36-07:00
Commit Message:
AGS: fixed speech overlays drawn behind GUI
>From upstream d651448d16fd3a72d5ede24ee6ad4c87a7d3d7d1
Was broken by d7c091890d2cde07776cca4ebbed7352d379612d
Changed paths:
engines/ags/engine/ac/draw.cpp
diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp
index 7cc060ae416..15832695fac 100644
--- a/engines/ags/engine/ac/draw.cpp
+++ b/engines/ags/engine/ac/draw.cpp
@@ -1952,6 +1952,10 @@ void draw_fps(const Rect &viewport) {
invalidate_sprite_glob(1, yp, ddb);
}
+static inline bool is_over_above_gui(int type) {
+ return type == OVER_TEXTMSG || type == OVER_PICTURE || type == OVER_TEXTSPEECH;
+}
+
// Draw GUI and overlays of all kinds, anything outside the room space
void draw_gui_and_overlays() {
if (pl_any_want_hook(AGSE_PREGUIDRAW))
@@ -1962,7 +1966,7 @@ void draw_gui_and_overlays() {
// complete overlay draw in non-transparent mode
if (over.type == OVER_COMPLETE)
add_thing_to_draw(over.bmp, over.x, over.y, TRANS_OPAQUE, false);
- else if (over.type != OVER_TEXTMSG && over.type != OVER_PICTURE) {
+ else if (!is_over_above_gui(over.type)) {
int tdxp, tdyp;
get_overlay_position(over, &tdxp, &tdyp);
add_thing_to_draw(over.bmp, tdxp, tdyp, 0, over.hasAlphaChannel);
@@ -2044,7 +2048,7 @@ void draw_gui_and_overlays() {
// draw speech and portraits (so that they appear over GUIs)
for (const auto &over : _GP(screenover)) {
- if (over.type == OVER_TEXTMSG || over.type == OVER_PICTURE) {
+ if (is_over_above_gui(over.type)) {
int tdxp, tdyp;
get_overlay_position(over, &tdxp, &tdyp);
add_thing_to_draw(over.bmp, tdxp, tdyp, 0, false);
Commit: 8c60e694cc814e0a4114fffe55181e7cdee0523f
https://github.com/scummvm/scummvm/commit/8c60e694cc814e0a4114fffe55181e7cdee0523f
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-03-15T22:28:37-07:00
Commit Message:
AGS: Simplified SpriteListEntry use
>From upstream 69a32a7a123e346f4ad724ed31f400f26d926280
Changed paths:
engines/ags/engine/ac/draw.cpp
engines/ags/engine/ac/draw.h
engines/ags/engine/ac/runtime_defines.h
engines/ags/engine/ac/sprite_list_entry.h
engines/ags/globals.h
diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp
index 15832695fac..03ca6901eb4 100644
--- a/engines/ags/engine/ac/draw.cpp
+++ b/engines/ags/engine/ac/draw.cpp
@@ -77,14 +77,6 @@ namespace AGS3 {
using namespace AGS::Shared;
using namespace AGS::Engine;
-SpriteListEntry::SpriteListEntry()
- : bmp(nullptr)
- , pic(nullptr)
- , baseline(0), x(0), y(0)
- , transparent(0)
- , takesPriorityIfEqual(false), hasAlphaChannel(false) {
-}
-
void setpal() {
set_palette_range(_G(palette), 0, 255, 0);
}
@@ -763,6 +755,57 @@ IDriverDependantBitmap *recycle_ddb_bitmap(IDriverDependantBitmap *bimp, Bitmap
return bimp;
}
+//------------------------------------------------------------------------
+// Functions for filling the lists of sprites to render
+
+static void clear_draw_list() {
+ _GP(thingsToDrawList).clear();
+}
+
+static void add_thing_to_draw(IDriverDependantBitmap *bmp, int x, int y, int trans) {
+ SpriteListEntry sprite;
+ sprite.bmp = bmp;
+ sprite.x = x;
+ sprite.y = y;
+ sprite.transparent = trans;
+ _GP(thingsToDrawList).push_back(sprite);
+}
+
+static void add_render_stage(int stage) {
+ SpriteListEntry sprite;
+ sprite.renderStage = stage;
+ _GP(thingsToDrawList).push_back(sprite);
+}
+
+static void clear_sprite_list() {
+ _GP(sprlist).clear();
+}
+
+static void add_to_sprite_list(IDriverDependantBitmap *spp, int xx, int yy, int baseline, int trans, bool isWalkBehind) {
+ if (spp == nullptr)
+ quit("add_to_sprite_list: attempted to draw NULL sprite");
+ // completely invisible, so don't draw it at all
+ if (trans == 255)
+ return;
+
+ SpriteListEntry sprite;
+ sprite.bmp = spp;
+ sprite.baseline = baseline;
+ sprite.x = xx;
+ sprite.y = yy;
+ sprite.transparent = trans;
+
+ if (_G(walkBehindMethod) == DrawAsSeparateSprite)
+ sprite.takesPriorityIfEqual = !isWalkBehind;
+ else
+ sprite.takesPriorityIfEqual = isWalkBehind;
+
+ _GP(sprlist).push_back(sprite);
+}
+
+//
+//------------------------------------------------------------------------
+
void invalidate_cached_walkbehinds() {
memset(&_GP(actspswbcache)[0], 0, sizeof(CachedActSpsData) * _GP(actspswbcache).size());
}
@@ -901,58 +944,10 @@ void sort_out_char_sprite_walk_behind(int actspsIndex, int xx, int yy, int basel
}
if (_GP(actspswbcache)[actspsIndex].isWalkBehindHere) {
- add_to_sprite_list(_GP(actspswbbmp)[actspsIndex], xx, yy, basel, 0, -1, true);
+ add_to_sprite_list(_GP(actspswbbmp)[actspsIndex], xx, yy, basel, 0, true);
}
}
-void clear_draw_list() {
- _GP(thingsToDrawList).clear();
-}
-void add_thing_to_draw(IDriverDependantBitmap *bmp, int x, int y, int trans, bool alphaChannel) {
- SpriteListEntry sprite;
- sprite.pic = nullptr;
- sprite.bmp = bmp;
- sprite.x = x;
- sprite.y = y;
- sprite.transparent = trans;
- sprite.hasAlphaChannel = alphaChannel;
- _GP(thingsToDrawList).push_back(sprite);
-}
-
-// the sprite list is an intermediate list used to order
-// objects and characters by their baselines before everything
-// is added to the Thing To Draw List
-void clear_sprite_list() {
- _GP(sprlist).clear();
-}
-void add_to_sprite_list(IDriverDependantBitmap *spp, int xx, int yy, int baseline, int trans, int sprNum, bool isWalkBehind) {
-
- if (spp == nullptr)
- quit("add_to_sprite_list: attempted to draw NULL sprite");
- // completely invisible, so don't draw it at all
- if (trans == 255)
- return;
-
- SpriteListEntry sprite;
- if ((sprNum >= 0) && ((_GP(game).SpriteInfos[sprNum].Flags & SPF_ALPHACHANNEL) != 0))
- sprite.hasAlphaChannel = true;
- else
- sprite.hasAlphaChannel = false;
-
- sprite.bmp = spp;
- sprite.baseline = baseline;
- sprite.x = xx;
- sprite.y = yy;
- sprite.transparent = trans;
-
- if (_G(walkBehindMethod) == DrawAsSeparateSprite)
- sprite.takesPriorityIfEqual = !isWalkBehind;
- else
- sprite.takesPriorityIfEqual = isWalkBehind;
-
- _GP(sprlist).push_back(sprite);
-}
-
void repair_alpha_channel(Bitmap *dest, Bitmap *bgpic) {
// Repair the alpha channel, because sprites may have been drawn
// over it by the buttons, etc
@@ -1008,12 +1003,11 @@ bool spritelistentry_less(const SpriteListEntry &e1, const SpriteListEntry &e2)
void draw_sprite_list() {
-
if (_G(walkBehindMethod) == DrawAsSeparateSprite) {
for (int ee = 1; ee < MAX_WALK_BEHINDS; ee++) {
if (_G(walkBehindBitmap)[ee] != nullptr) {
add_to_sprite_list(_G(walkBehindBitmap)[ee], _G(walkBehindLeft)[ee], _G(walkBehindTop)[ee],
- _G(croom)->walkbehind_base[ee], 0, -1, true);
+ _G(croom)->walkbehind_base[ee], 0, true);
}
}
}
@@ -1021,7 +1015,7 @@ void draw_sprite_list() {
std::sort(_GP(sprlist).begin(), _GP(sprlist).end(), spritelistentry_less);
if (pl_any_want_hook(AGSE_PRESCREENDRAW))
- add_thing_to_draw(nullptr, AGSE_PRESCREENDRAW, 0, TRANS_RUN_PLUGIN, false);
+ add_render_stage(AGSE_PRESCREENDRAW);
// copy the sorted sprites into the Things To Draw list
_GP(thingsToDrawList).insert(_GP(thingsToDrawList).end(), _GP(sprlist).begin(), _GP(sprlist).end());
@@ -1523,7 +1517,7 @@ void prepare_objects_for_drawing() {
_GP(actspsbmp)[useindx]->SetLightLevel(0);
}
- add_to_sprite_list(_GP(actspsbmp)[useindx], atxp, atyp, usebasel, _G(objs)[aa].transparent, _G(objs)[aa].num);
+ add_to_sprite_list(_GP(actspsbmp)[useindx], atxp, atyp, usebasel, _G(objs)[aa].transparent, false);
}
}
@@ -1815,7 +1809,7 @@ void prepare_characters_for_drawing() {
chin->actx = atxp;
chin->acty = atyp;
- add_to_sprite_list(_GP(actspsbmp)[useindx], bgX, bgY, usebasel, chin->transparency, sppic);
+ add_to_sprite_list(_GP(actspsbmp)[useindx], bgX, bgY, usebasel, chin->transparency, false);
}
}
@@ -1845,7 +1839,7 @@ void prepare_room_sprites() {
update_walk_behind_images();
}
}
- add_thing_to_draw(_G(roomBackgroundBmp), 0, 0, 0, false);
+ add_thing_to_draw(_G(roomBackgroundBmp), 0, 0, 0);
}
_G(current_background_is_dirty) = false; // Note this is only place where this flag is checked
@@ -1959,17 +1953,17 @@ static inline bool is_over_above_gui(int type) {
// Draw GUI and overlays of all kinds, anything outside the room space
void draw_gui_and_overlays() {
if (pl_any_want_hook(AGSE_PREGUIDRAW))
- add_thing_to_draw(nullptr, AGSE_PREGUIDRAW, 0, TRANS_RUN_PLUGIN, false);
+ add_render_stage(AGSE_PREGUIDRAW);
// draw overlays, except text boxes and portraits
for (const auto &over : _GP(screenover)) {
// complete overlay draw in non-transparent mode
if (over.type == OVER_COMPLETE)
- add_thing_to_draw(over.bmp, over.x, over.y, TRANS_OPAQUE, false);
+ add_thing_to_draw(over.bmp, over.x, over.y, 0);
else if (!is_over_above_gui(over.type)) {
int tdxp, tdyp;
get_overlay_position(over, &tdxp, &tdyp);
- add_thing_to_draw(over.bmp, tdxp, tdyp, 0, over.hasAlphaChannel);
+ add_thing_to_draw(over.bmp, tdxp, tdyp, 0);
}
}
@@ -2037,7 +2031,7 @@ void draw_gui_and_overlays() {
(_GP(guis)[aa].PopupStyle != kGUIPopupNoAutoRemove))
continue;
- add_thing_to_draw(_GP(guibgbmp)[aa], _GP(guis)[aa].X, _GP(guis)[aa].Y, _GP(guis)[aa].Transparency, _GP(guis)[aa].HasAlphaChannel());
+ add_thing_to_draw(_GP(guibgbmp)[aa], _GP(guis)[aa].X, _GP(guis)[aa].Y, _GP(guis)[aa].Transparency);
// only poll if the interface is enabled (mouseovers should not
// work while in Wait state)
@@ -2051,7 +2045,7 @@ void draw_gui_and_overlays() {
if (is_over_above_gui(over.type)) {
int tdxp, tdyp;
get_overlay_position(over, &tdxp, &tdyp);
- add_thing_to_draw(over.bmp, tdxp, tdyp, 0, false);
+ add_thing_to_draw(over.bmp, tdxp, tdyp, 0);
}
}
@@ -2060,17 +2054,13 @@ void draw_gui_and_overlays() {
// Push the gathered list of sprites into the active graphic renderer
void put_sprite_list_on_screen(bool in_room) {
- // *** Draw the Things To Draw List ***
-
- SpriteListEntry *thisThing;
-
for (size_t i = 0; i < _GP(thingsToDrawList).size(); ++i) {
- thisThing = &_GP(thingsToDrawList)[i];
+ const auto *thisThing = &_GP(thingsToDrawList)[i];
if (thisThing->bmp != nullptr) {
// mark the image's region as dirty
invalidate_sprite(thisThing->x, thisThing->y, thisThing->bmp, in_room);
- } else if ((thisThing->transparent != TRANS_RUN_PLUGIN) &&
+ } else if ((thisThing->renderStage < 0) &&
(thisThing->bmp == nullptr)) {
quit("Null pointer added to draw list");
}
@@ -2081,9 +2071,9 @@ void put_sprite_list_on_screen(bool in_room) {
}
_G(gfxDriver)->DrawSprite(thisThing->x, thisThing->y, thisThing->bmp);
- } else if (thisThing->transparent == TRANS_RUN_PLUGIN) {
+ } else if (thisThing->renderStage >= 0) {
// meta entry to run the plugin hook
- _G(gfxDriver)->DrawSprite(thisThing->x, thisThing->y, nullptr);
+ _G(gfxDriver)->DrawSprite(thisThing->renderStage, 0, nullptr);
} else
quit("Unknown entry in draw list");
}
diff --git a/engines/ags/engine/ac/draw.h b/engines/ags/engine/ac/draw.h
index 9a5bccce96d..fd3b0342a49 100644
--- a/engines/ags/engine/ac/draw.h
+++ b/engines/ags/engine/ac/draw.h
@@ -127,7 +127,6 @@ void construct_engine_overlay();
// Clears black game borders in legacy letterbox mode
void clear_letterbox_borders();
-void add_to_sprite_list(Engine::IDriverDependantBitmap *spp, int xx, int yy, int baseline, int trans, int sprNum, bool isWalkBehind = false);
void tint_image(Shared::Bitmap *g, Shared::Bitmap *source, int red, int grn, int blu, int light_level, int luminance = 255);
void draw_sprite_support_alpha(Shared::Bitmap *ds, bool ds_has_alpha, int xpos, int ypos, Shared::Bitmap *image, bool src_has_alpha,
Shared::BlendMode blend_mode = Shared::kBlendMode_Alpha, int alpha = 0xFF);
diff --git a/engines/ags/engine/ac/runtime_defines.h b/engines/ags/engine/ac/runtime_defines.h
index 76c8802e0a8..c88fda4c634 100644
--- a/engines/ags/engine/ac/runtime_defines.h
+++ b/engines/ags/engine/ac/runtime_defines.h
@@ -139,11 +139,6 @@ const int LegacyRoomVolumeFactor = 30;
#define MAX_PLUGIN_OBJECT_READERS 50
-#define TRANS_ALPHA_CHANNEL 20000
-#define TRANS_OPAQUE 20001
-#define TRANS_RUN_PLUGIN 20002
-
-
#define LOCTYPE_HOTSPOT 1
#define LOCTYPE_CHAR 2
#define LOCTYPE_OBJ 3
diff --git a/engines/ags/engine/ac/sprite_list_entry.h b/engines/ags/engine/ac/sprite_list_entry.h
index aa59d981c91..382bf77c664 100644
--- a/engines/ags/engine/ac/sprite_list_entry.h
+++ b/engines/ags/engine/ac/sprite_list_entry.h
@@ -27,15 +27,16 @@
namespace AGS3 {
struct SpriteListEntry {
- AGS::Engine::IDriverDependantBitmap *bmp;
- AGS::Shared::Bitmap *pic;
- int baseline;
- int x, y;
- int transparent;
- bool takesPriorityIfEqual;
- bool hasAlphaChannel;
-
- SpriteListEntry();
+ Engine::IDriverDependantBitmap *bmp = nullptr;
+ AGS::Shared::Bitmap *pic = nullptr;
+ int transparent = 0;
+ int x = 0, y = 0;
+ int baseline = 0;
+ // Tells if this item should take priority during sort if z1 == z2
+ // TODO: this is some compatibility feature - find out if may be omited and done without extra struct?
+ bool takesPriorityIfEqual = false;
+ // Mark for the render stage callback (if >= 0 other fields are ignored)
+ int renderStage = -1;
};
} // namespace AGS3
diff --git a/engines/ags/globals.h b/engines/ags/globals.h
index fff26b1577f..545a011b04a 100644
--- a/engines/ags/globals.h
+++ b/engines/ags/globals.h
@@ -559,8 +559,10 @@ public:
*/
std::vector<RoomCameraDrawData> *_CameraDrawData;
- std::vector<SpriteListEntry> *_sprlist;
+ // Two lists of sprites to push into renderer during next render pass
+ // thingsToDrawList - is the main list, unsorted, drawn in the index order
std::vector<SpriteListEntry> *_thingsToDrawList;
+ std::vector<SpriteListEntry> *_sprlist;
AGS::Engine::IGraphicsDriver *_gfxDriver = nullptr;
AGS::Engine::IDriverDependantBitmap *_blankImage = nullptr;
Commit: d4e81c2ecb33ec52bf98ec4a8e7223b4a992ef1e
https://github.com/scummvm/scummvm/commit/d4e81c2ecb33ec52bf98ec4a8e7223b4a992ef1e
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-03-15T22:28:37-07:00
Commit Message:
AGS: Moved irrelevant code out from draw_sprite_list()
>From upstream 8c01d1f60449ab99c0ee09d29318214a2795d2dc
Changed paths:
engines/ags/engine/ac/draw.cpp
diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp
index 03ca6901eb4..51e48246ad6 100644
--- a/engines/ags/engine/ac/draw.cpp
+++ b/engines/ags/engine/ac/draw.cpp
@@ -803,6 +803,23 @@ static void add_to_sprite_list(IDriverDependantBitmap *spp, int xx, int yy, int
_GP(sprlist).push_back(sprite);
}
+// function to sort the sprites into baseline order
+static bool spritelistentry_less(const SpriteListEntry &e1, const SpriteListEntry &e2) {
+ if (e1.baseline == e2.baseline) {
+ if (e1.takesPriorityIfEqual)
+ return false;
+ if (e2.takesPriorityIfEqual)
+ return true;
+ }
+ return e1.baseline < e2.baseline;
+}
+
+// copy the sorted sprites into the Things To Draw list
+static void draw_sprite_list() {
+ std::sort(_GP(sprlist).begin(), _GP(sprlist).end(), spritelistentry_less);
+ _GP(thingsToDrawList).insert(_GP(thingsToDrawList).end(), _GP(sprlist).begin(), _GP(sprlist).end());
+}
+
//
//------------------------------------------------------------------------
@@ -988,39 +1005,6 @@ void draw_gui_sprite_v330(Bitmap *ds, int pic, int x, int y, bool use_alpha, Ble
draw_gui_sprite(ds, pic, x, y, use_alpha && (_G(loaded_game_file_version) >= kGameVersion_330), blend_mode);
}
-// function to sort the sprites into baseline order
-bool spritelistentry_less(const SpriteListEntry &e1, const SpriteListEntry &e2) {
- if (e1.baseline == e2.baseline) {
- if (e1.takesPriorityIfEqual)
- return false;
- if (e2.takesPriorityIfEqual)
- return true;
- }
- return e1.baseline < e2.baseline;
-}
-
-
-
-
-void draw_sprite_list() {
- if (_G(walkBehindMethod) == DrawAsSeparateSprite) {
- for (int ee = 1; ee < MAX_WALK_BEHINDS; ee++) {
- if (_G(walkBehindBitmap)[ee] != nullptr) {
- add_to_sprite_list(_G(walkBehindBitmap)[ee], _G(walkBehindLeft)[ee], _G(walkBehindTop)[ee],
- _G(croom)->walkbehind_base[ee], 0, true);
- }
- }
- }
-
- std::sort(_GP(sprlist).begin(), _GP(sprlist).end(), spritelistentry_less);
-
- if (pl_any_want_hook(AGSE_PRESCREENDRAW))
- add_render_stage(AGSE_PRESCREENDRAW);
-
- // copy the sorted sprites into the Things To Draw list
- _GP(thingsToDrawList).insert(_GP(thingsToDrawList).end(), _GP(sprlist).begin(), _GP(sprlist).end());
-}
-
// Avoid freeing and reallocating the memory if possible
Bitmap *recycle_bitmap(Bitmap *bimp, int coldep, int wid, int hit, bool make_transparent) {
if (bimp != nullptr) {
@@ -1851,6 +1835,19 @@ void prepare_room_sprites() {
if ((_G(debug_flags) & DBG_NODRAWSPRITES) == 0) {
_G(our_eip) = 34;
+
+ if (_G(walkBehindMethod) == DrawAsSeparateSprite) {
+ for (int ee = 1; ee < MAX_WALK_BEHINDS; ee++) {
+ if (_G(walkBehindBitmap)[ee] != nullptr) {
+ add_to_sprite_list(_G(walkBehindBitmap)[ee], _G(walkBehindLeft)[ee], _G(walkBehindTop)[ee],
+ _G(croom)->walkbehind_base[ee], 0, true);
+ }
+ }
+ }
+
+ if (pl_any_want_hook(AGSE_PRESCREENDRAW))
+ add_render_stage(AGSE_PRESCREENDRAW);
+
draw_sprite_list();
}
}
Commit: 2b7e671eb7cef6e03328b3db99c8cd79572ae5ab
https://github.com/scummvm/scummvm/commit/2b7e671eb7cef6e03328b3db99c8cd79572ae5ab
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-03-15T22:28:38-07:00
Commit Message:
AGS: Remade VideoMemDDB class into BaseDDB, tidy ddb declarations
>From upstream 6faef191c6f5728d0e10fd2ed29f3adb0013496c
Changed paths:
engines/ags/engine/gfx/ali_3d_scummvm.cpp
engines/ags/engine/gfx/ali_3d_scummvm.h
engines/ags/engine/gfx/ddb.h
engines/ags/engine/gfx/gfx_driver_base.cpp
engines/ags/engine/gfx/gfx_driver_base.h
diff --git a/engines/ags/engine/gfx/ali_3d_scummvm.cpp b/engines/ags/engine/gfx/ali_3d_scummvm.cpp
index 90bf5ceee7a..876ede6e096 100644
--- a/engines/ags/engine/gfx/ali_3d_scummvm.cpp
+++ b/engines/ags/engine/gfx/ali_3d_scummvm.cpp
@@ -225,7 +225,7 @@ void ScummVMRendererGraphicsDriver::UpdateDDBFromBitmap(IDriverDependantBitmap *
}
void ScummVMRendererGraphicsDriver::DestroyDDB(IDriverDependantBitmap *bitmap) {
- delete bitmap;
+ delete (ALSoftwareBitmap *)bitmap;
}
void ScummVMRendererGraphicsDriver::InitSpriteBatch(size_t index, const SpriteBatchDesc &desc) {
diff --git a/engines/ags/engine/gfx/ali_3d_scummvm.h b/engines/ags/engine/gfx/ali_3d_scummvm.h
index 24629259882..b0e02e51252 100644
--- a/engines/ags/engine/gfx/ali_3d_scummvm.h
+++ b/engines/ags/engine/gfx/ali_3d_scummvm.h
@@ -57,9 +57,8 @@ enum RendererFlip {
FLIP_VERTICAL = 0x00000002 /**< flip vertically */
};
-class ALSoftwareBitmap : public IDriverDependantBitmap {
+class ALSoftwareBitmap : public BaseDDB {
public:
- // NOTE by CJ:
// Transparency is a bit counter-intuitive
// 0=not transparent, 255=invisible, 1..254 barely visible .. mostly visible
void SetTransparency(int transparency) override {
@@ -72,23 +71,12 @@ public:
_stretchToWidth = width;
_stretchToHeight = height;
}
- int GetWidth() override {
- return _width;
- }
- int GetHeight() override {
- return _height;
- }
- int GetColorDepth() override {
- return _colDepth;
- }
void SetLightLevel(int lightLevel) override {
}
void SetTint(int red, int green, int blue, int tintSaturation) override {
}
Bitmap *_bmp;
- int _width, _height;
- int _colDepth;
bool _flipped;
int _stretchToWidth, _stretchToHeight;
bool _opaque; // no mask color
diff --git a/engines/ags/engine/gfx/ddb.h b/engines/ags/engine/gfx/ddb.h
index 6b4c7e1e5e0..a057221abd3 100644
--- a/engines/ags/engine/gfx/ddb.h
+++ b/engines/ags/engine/gfx/ddb.h
@@ -23,6 +23,10 @@
//
// Driver-dependant bitmap interface
//
+// TODO: split into texture object that has only tex data
+// and object describing a drawing operation, with ref to texture and
+// drawing parameters (modes, shaders, etc).
+// Then we will also be able to share one texture among multiple game entities.
//=============================================================================
#ifndef AGS_ENGINE_GFX_DDB_H
@@ -34,17 +38,19 @@ namespace Engine {
class IDriverDependantBitmap {
public:
- virtual ~IDriverDependantBitmap() {}
-
virtual void SetTransparency(int transparency) = 0; // 0-255
virtual void SetFlippedLeftRight(bool isFlipped) = 0;
virtual void SetStretch(int width, int height, bool useResampler = true) = 0;
virtual void SetLightLevel(int light_level) = 0; // 0-255
virtual void SetTint(int red, int green, int blue, int tintSaturation) = 0; // 0-255
- virtual int GetWidth() = 0;
- virtual int GetHeight() = 0;
- virtual int GetColorDepth() = 0;
+ virtual int GetWidth() const = 0;
+ virtual int GetHeight() const = 0;
+ virtual int GetColorDepth() const = 0;
+
+protected:
+ IDriverDependantBitmap() {}
+ virtual ~IDriverDependantBitmap() {}
};
} // namespace Engine
diff --git a/engines/ags/engine/gfx/gfx_driver_base.cpp b/engines/ags/engine/gfx/gfx_driver_base.cpp
index d8ba240c482..9f73ca50c41 100644
--- a/engines/ags/engine/gfx/gfx_driver_base.cpp
+++ b/engines/ags/engine/gfx/gfx_driver_base.cpp
@@ -292,7 +292,7 @@ __inline void get_pixel_if_not_transparent32(const unsigned int *pixel, unsigned
( (((a) & 0xFF) << _vmem_a_shift_32) | (((r) & 0xFF) << _vmem_r_shift_32) | (((g) & 0xFF) << _vmem_g_shift_32) | (((b) & 0xFF) << _vmem_b_shift_32) )
-void VideoMemoryGraphicsDriver::BitmapToVideoMem(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile, const VideoMemDDB *target,
+void VideoMemoryGraphicsDriver::BitmapToVideoMem(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile,
char *dst_ptr, const int dst_pitch, const bool usingLinearFiltering) {
const int src_depth = bitmap->GetColorDepth();
bool lastPixelWasTransparent = false;
@@ -409,7 +409,7 @@ void VideoMemoryGraphicsDriver::BitmapToVideoMem(const Bitmap *bitmap, const boo
}
}
-void VideoMemoryGraphicsDriver::BitmapToVideoMemOpaque(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile, const VideoMemDDB *target,
+void VideoMemoryGraphicsDriver::BitmapToVideoMemOpaque(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile,
char *dst_ptr, const int dst_pitch) {
const int src_depth = bitmap->GetColorDepth();
for (int y = 0; y < tile->height; y++) {
diff --git a/engines/ags/engine/gfx/gfx_driver_base.h b/engines/ags/engine/gfx/gfx_driver_base.h
index 3b762e08fcc..e872316a576 100644
--- a/engines/ags/engine/gfx/gfx_driver_base.h
+++ b/engines/ags/engine/gfx/gfx_driver_base.h
@@ -173,21 +173,26 @@ struct TextureTile {
};
// Parent class for the video memory DDBs
-class VideoMemDDB : public IDriverDependantBitmap {
+class BaseDDB : public IDriverDependantBitmap {
public:
- int GetWidth() override {
+ int GetWidth() const override {
return _width;
}
- int GetHeight() override {
+ int GetHeight() const override {
return _height;
}
- int GetColorDepth() override {
+ int GetColorDepth() const override {
return _colDepth;
}
- int _width, _height;
- int _colDepth;
- bool _opaque; // no mask color
+ int _width = 0, _height = 0;
+ int _colDepth = 0;
+ bool _hasAlpha = false; // has meaningful alpha channel
+ bool _opaque = false; // no mask color
+
+protected:
+ BaseDDB() {}
+ virtual ~BaseDDB() {}
};
// VideoMemoryGraphicsDriver - is the parent class for the graphic drivers
@@ -228,11 +233,11 @@ protected:
void DestroyFxPool();
// Prepares bitmap to be applied to the texture, copies pixels to the provided buffer
- void BitmapToVideoMem(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile, const VideoMemDDB *target,
- char *dst_ptr, const int dst_pitch, const bool usingLinearFiltering);
+ void BitmapToVideoMem(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile,
+ char *dst_ptr, const int dst_pitch, const bool usingLinearFiltering);
// Same but optimized for opaque source bitmaps which ignore transparent "mask color"
- void BitmapToVideoMemOpaque(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile, const VideoMemDDB *target,
- char *dst_ptr, const int dst_pitch);
+ void BitmapToVideoMemOpaque(const Bitmap *bitmap, const bool has_alpha, const TextureTile *tile,
+ char *dst_ptr, const int dst_pitch);
// Stage virtual screen is used to let plugins draw custom graphics
// in between render stages (between room and GUI, after GUI, and so on)
Commit: ccb87178d50fe2146124fbdffbc2b183da309a2b
https://github.com/scummvm/scummvm/commit/ccb87178d50fe2146124fbdffbc2b183da309a2b
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-03-15T22:28:38-07:00
Commit Message:
AGS: Simplified add_to_sprite_list() argument list
>From upstream 172466469dca450a05ba97fab85dcf747d344b02
Changed paths:
engines/ags/engine/ac/draw.cpp
engines/ags/engine/ac/sprite_list_entry.h
engines/ags/engine/gfx/ali_3d_scummvm.h
engines/ags/engine/gfx/ddb.h
diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp
index 51e48246ad6..5ae8ad72240 100644
--- a/engines/ags/engine/ac/draw.cpp
+++ b/engines/ags/engine/ac/draw.cpp
@@ -762,12 +762,11 @@ static void clear_draw_list() {
_GP(thingsToDrawList).clear();
}
-static void add_thing_to_draw(IDriverDependantBitmap *bmp, int x, int y, int trans) {
+static void add_thing_to_draw(IDriverDependantBitmap *bmp, int x, int y) {
SpriteListEntry sprite;
sprite.bmp = bmp;
sprite.x = x;
sprite.y = y;
- sprite.transparent = trans;
_GP(thingsToDrawList).push_back(sprite);
}
@@ -781,11 +780,11 @@ static void clear_sprite_list() {
_GP(sprlist).clear();
}
-static void add_to_sprite_list(IDriverDependantBitmap *spp, int xx, int yy, int baseline, int trans, bool isWalkBehind) {
+static void add_to_sprite_list(IDriverDependantBitmap *spp, int xx, int yy, int baseline, bool isWalkBehind) {
if (spp == nullptr)
quit("add_to_sprite_list: attempted to draw NULL sprite");
// completely invisible, so don't draw it at all
- if (trans == 255)
+ if (spp->GetTransparency() == 255)
return;
SpriteListEntry sprite;
@@ -793,7 +792,6 @@ static void add_to_sprite_list(IDriverDependantBitmap *spp, int xx, int yy, int
sprite.baseline = baseline;
sprite.x = xx;
sprite.y = yy;
- sprite.transparent = trans;
if (_G(walkBehindMethod) == DrawAsSeparateSprite)
sprite.takesPriorityIfEqual = !isWalkBehind;
@@ -961,7 +959,7 @@ void sort_out_char_sprite_walk_behind(int actspsIndex, int xx, int yy, int basel
}
if (_GP(actspswbcache)[actspsIndex].isWalkBehindHere) {
- add_to_sprite_list(_GP(actspswbbmp)[actspsIndex], xx, yy, basel, 0, true);
+ add_to_sprite_list(_GP(actspswbbmp)[actspsIndex], xx, yy, basel, true);
}
}
@@ -1501,7 +1499,8 @@ void prepare_objects_for_drawing() {
_GP(actspsbmp)[useindx]->SetLightLevel(0);
}
- add_to_sprite_list(_GP(actspsbmp)[useindx], atxp, atyp, usebasel, _G(objs)[aa].transparent, false);
+ _GP(actspsbmp)[useindx]->SetTransparency(_G(objs)[aa].transparent);
+ add_to_sprite_list(_GP(actspsbmp)[useindx], atxp, atyp, usebasel, false);
}
}
@@ -1793,7 +1792,8 @@ void prepare_characters_for_drawing() {
chin->actx = atxp;
chin->acty = atyp;
- add_to_sprite_list(_GP(actspsbmp)[useindx], bgX, bgY, usebasel, chin->transparency, false);
+ _GP(actspsbmp)[useindx]->SetTransparency(chin->transparency);
+ add_to_sprite_list(_GP(actspsbmp)[useindx], bgX, bgY, usebasel, false);
}
}
@@ -1823,7 +1823,7 @@ void prepare_room_sprites() {
update_walk_behind_images();
}
}
- add_thing_to_draw(_G(roomBackgroundBmp), 0, 0, 0);
+ add_thing_to_draw(_G(roomBackgroundBmp), 0, 0);
}
_G(current_background_is_dirty) = false; // Note this is only place where this flag is checked
@@ -1840,7 +1840,7 @@ void prepare_room_sprites() {
for (int ee = 1; ee < MAX_WALK_BEHINDS; ee++) {
if (_G(walkBehindBitmap)[ee] != nullptr) {
add_to_sprite_list(_G(walkBehindBitmap)[ee], _G(walkBehindLeft)[ee], _G(walkBehindTop)[ee],
- _G(croom)->walkbehind_base[ee], 0, true);
+ _G(croom)->walkbehind_base[ee], true);
}
}
}
@@ -1956,11 +1956,11 @@ void draw_gui_and_overlays() {
for (const auto &over : _GP(screenover)) {
// complete overlay draw in non-transparent mode
if (over.type == OVER_COMPLETE)
- add_thing_to_draw(over.bmp, over.x, over.y, 0);
+ add_thing_to_draw(over.bmp, over.x, over.y);
else if (!is_over_above_gui(over.type)) {
int tdxp, tdyp;
get_overlay_position(over, &tdxp, &tdyp);
- add_thing_to_draw(over.bmp, tdxp, tdyp, 0);
+ add_thing_to_draw(over.bmp, tdxp, tdyp);
}
}
@@ -2028,7 +2028,8 @@ void draw_gui_and_overlays() {
(_GP(guis)[aa].PopupStyle != kGUIPopupNoAutoRemove))
continue;
- add_thing_to_draw(_GP(guibgbmp)[aa], _GP(guis)[aa].X, _GP(guis)[aa].Y, _GP(guis)[aa].Transparency);
+ _GP(guibgbmp)[aa]->SetTransparency(_GP(guis)[aa].Transparency);
+ add_thing_to_draw(_GP(guibgbmp)[aa], _GP(guis)[aa].X, _GP(guis)[aa].Y);
// only poll if the interface is enabled (mouseovers should not
// work while in Wait state)
@@ -2042,7 +2043,7 @@ void draw_gui_and_overlays() {
if (is_over_above_gui(over.type)) {
int tdxp, tdyp;
get_overlay_position(over, &tdxp, &tdyp);
- add_thing_to_draw(over.bmp, tdxp, tdyp, 0);
+ add_thing_to_draw(over.bmp, tdxp, tdyp);
}
}
@@ -2055,24 +2056,19 @@ void put_sprite_list_on_screen(bool in_room) {
const auto *thisThing = &_GP(thingsToDrawList)[i];
if (thisThing->bmp != nullptr) {
+ if (thisThing->bmp->GetTransparency() == 255)
+ continue; // skip completely invisible things
// mark the image's region as dirty
invalidate_sprite(thisThing->x, thisThing->y, thisThing->bmp, in_room);
- } else if ((thisThing->renderStage < 0) &&
- (thisThing->bmp == nullptr)) {
- quit("Null pointer added to draw list");
- }
-
- if (thisThing->bmp != nullptr) {
- if (thisThing->transparent <= 255) {
- thisThing->bmp->SetTransparency(thisThing->transparent);
- }
+ // push to the graphics driver
_G(gfxDriver)->DrawSprite(thisThing->x, thisThing->y, thisThing->bmp);
} else if (thisThing->renderStage >= 0) {
// meta entry to run the plugin hook
_G(gfxDriver)->DrawSprite(thisThing->renderStage, 0, nullptr);
- } else
- quit("Unknown entry in draw list");
+ } else {
+ quit("Null pointer added to draw list");
+ }
}
_G(our_eip) = 1100;
diff --git a/engines/ags/engine/ac/sprite_list_entry.h b/engines/ags/engine/ac/sprite_list_entry.h
index 382bf77c664..bed6acc9d9b 100644
--- a/engines/ags/engine/ac/sprite_list_entry.h
+++ b/engines/ags/engine/ac/sprite_list_entry.h
@@ -29,7 +29,6 @@ namespace AGS3 {
struct SpriteListEntry {
Engine::IDriverDependantBitmap *bmp = nullptr;
AGS::Shared::Bitmap *pic = nullptr;
- int transparent = 0;
int x = 0, y = 0;
int baseline = 0;
// Tells if this item should take priority during sort if z1 == z2
diff --git a/engines/ags/engine/gfx/ali_3d_scummvm.h b/engines/ags/engine/gfx/ali_3d_scummvm.h
index b0e02e51252..07fa98ee01d 100644
--- a/engines/ags/engine/gfx/ali_3d_scummvm.h
+++ b/engines/ags/engine/gfx/ali_3d_scummvm.h
@@ -61,6 +61,9 @@ class ALSoftwareBitmap : public BaseDDB {
public:
// Transparency is a bit counter-intuitive
// 0=not transparent, 255=invisible, 1..254 barely visible .. mostly visible
+ int GetTransparency() const override {
+ return _transparency;
+ }
void SetTransparency(int transparency) override {
_transparency = transparency;
}
diff --git a/engines/ags/engine/gfx/ddb.h b/engines/ags/engine/gfx/ddb.h
index a057221abd3..2945d6bb93c 100644
--- a/engines/ags/engine/gfx/ddb.h
+++ b/engines/ags/engine/gfx/ddb.h
@@ -38,6 +38,7 @@ namespace Engine {
class IDriverDependantBitmap {
public:
+ virtual int GetTransparency() const = 0;
virtual void SetTransparency(int transparency) = 0; // 0-255
virtual void SetFlippedLeftRight(bool isFlipped) = 0;
virtual void SetStretch(int width, int height, bool useResampler = true) = 0;
Commit: 46f1f776c96fda3d9d55294813d03000c2cd951f
https://github.com/scummvm/scummvm/commit/46f1f776c96fda3d9d55294813d03000c2cd951f
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-03-15T22:28:38-07:00
Commit Message:
AGS: Sort overlays along with GUI
>From upstream 6b41b1f86ab2f6840c324d98e8e96ae5c61dad9f
Changed paths:
engines/ags/engine/ac/draw.cpp
engines/ags/engine/ac/sprite_list_entry.h
diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp
index 5ae8ad72240..137b1ac592f 100644
--- a/engines/ags/engine/ac/draw.cpp
+++ b/engines/ags/engine/ac/draw.cpp
@@ -780,7 +780,7 @@ static void clear_sprite_list() {
_GP(sprlist).clear();
}
-static void add_to_sprite_list(IDriverDependantBitmap *spp, int xx, int yy, int baseline, bool isWalkBehind) {
+static void add_to_sprite_list(IDriverDependantBitmap *spp, int xx, int yy, int zorder, bool isWalkBehind) {
if (spp == nullptr)
quit("add_to_sprite_list: attempted to draw NULL sprite");
// completely invisible, so don't draw it at all
@@ -789,7 +789,7 @@ static void add_to_sprite_list(IDriverDependantBitmap *spp, int xx, int yy, int
SpriteListEntry sprite;
sprite.bmp = spp;
- sprite.baseline = baseline;
+ sprite.zorder = zorder;
sprite.x = xx;
sprite.y = yy;
@@ -801,15 +801,15 @@ static void add_to_sprite_list(IDriverDependantBitmap *spp, int xx, int yy, int
_GP(sprlist).push_back(sprite);
}
-// function to sort the sprites into baseline order
+// function to sort the sprites into zorder order
static bool spritelistentry_less(const SpriteListEntry &e1, const SpriteListEntry &e2) {
- if (e1.baseline == e2.baseline) {
+ if (e1.zorder == e2.zorder) {
if (e1.takesPriorityIfEqual)
return false;
if (e2.takesPriorityIfEqual)
return true;
}
- return e1.baseline < e2.baseline;
+ return e1.zorder < e2.zorder;
}
// copy the sorted sprites into the Things To Draw list
@@ -1952,20 +1952,23 @@ void draw_gui_and_overlays() {
if (pl_any_want_hook(AGSE_PREGUIDRAW))
add_render_stage(AGSE_PREGUIDRAW);
- // draw overlays, except text boxes and portraits
- for (const auto &over : _GP(screenover)) {
+ clear_sprite_list();
+
+ // Add active overlays to the sprite list
+ for (auto &over : _GP(screenover)) {
+ int tdxp, tdyp;
+ get_overlay_position(over, &tdxp, &tdyp);
// complete overlay draw in non-transparent mode
- if (over.type == OVER_COMPLETE)
- add_thing_to_draw(over.bmp, over.x, over.y);
- else if (!is_over_above_gui(over.type)) {
- int tdxp, tdyp;
- get_overlay_position(over, &tdxp, &tdyp);
- add_thing_to_draw(over.bmp, tdxp, tdyp);
+ if (over.type == OVER_COMPLETE) {
+ add_to_sprite_list(over.bmp, tdxp, tdyp, INT_MIN, false);
+ } else {
+ // draw speech and portraits over GUI and the rest under GUI
+ int zorder = is_over_above_gui(over.type) ? INT_MAX : INT_MIN;
+ add_to_sprite_list(over.bmp, tdxp, tdyp, zorder, false);
}
}
- // Draw GUIs - they should always be on top of overlays like
- // speech background text
+ // Add GUIs
_G(our_eip) = 35;
if (((_G(debug_flags) & DBG_NOIFACE) == 0) && (_G(displayed_room) >= 0)) {
int aa;
@@ -2029,7 +2032,7 @@ void draw_gui_and_overlays() {
continue;
_GP(guibgbmp)[aa]->SetTransparency(_GP(guis)[aa].Transparency);
- add_thing_to_draw(_GP(guibgbmp)[aa], _GP(guis)[aa].X, _GP(guis)[aa].Y);
+ add_to_sprite_list(_GP(guibgbmp)[aa], _GP(guis)[aa].X, _GP(guis)[aa].Y, _GP(guis)[aa].ZOrder, false);
// only poll if the interface is enabled (mouseovers should not
// work while in Wait state)
@@ -2038,14 +2041,8 @@ void draw_gui_and_overlays() {
}
}
- // draw speech and portraits (so that they appear over GUIs)
- for (const auto &over : _GP(screenover)) {
- if (is_over_above_gui(over.type)) {
- int tdxp, tdyp;
- get_overlay_position(over, &tdxp, &tdyp);
- add_thing_to_draw(over.bmp, tdxp, tdyp);
- }
- }
+ // sort and append ui sprites to the global draw things list
+ draw_sprite_list();
_G(our_eip) = 1099;
}
@@ -2090,7 +2087,7 @@ void GfxDriverOnInitCallback(void *data) {
static void construct_room_view() {
draw_preroom_background();
prepare_room_sprites();
- // reset the Baselines Changed flag now that we've drawn stuff
+ // reset the zorders Changed flag now that we've drawn stuff
_G(walk_behind_baselines_changed) = 0;
for (const auto &viewport : _GP(play).GetRoomViewportsZOrdered()) {
diff --git a/engines/ags/engine/ac/sprite_list_entry.h b/engines/ags/engine/ac/sprite_list_entry.h
index bed6acc9d9b..3d6d061708a 100644
--- a/engines/ags/engine/ac/sprite_list_entry.h
+++ b/engines/ags/engine/ac/sprite_list_entry.h
@@ -30,7 +30,7 @@ struct SpriteListEntry {
Engine::IDriverDependantBitmap *bmp = nullptr;
AGS::Shared::Bitmap *pic = nullptr;
int x = 0, y = 0;
- int baseline = 0;
+ int zorder = 0;
// Tells if this item should take priority during sort if z1 == z2
// TODO: this is some compatibility feature - find out if may be omited and done without extra struct?
bool takesPriorityIfEqual = false;
Commit: 796c2dcd0e6bcc9c51d1563bd96bb86851c2d6c5
https://github.com/scummvm/scummvm/commit/796c2dcd0e6bcc9c51d1563bd96bb86851c2d6c5
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-03-15T22:28:39-07:00
Commit Message:
AGS: Overlay.ZOrder and use zorder for custom overlays
>From upstream 4be229bfbfe808384cea8ea724d72fcd6a0ca094
Changed paths:
engines/ags/engine/ac/draw.cpp
engines/ags/engine/ac/overlay.cpp
engines/ags/engine/ac/screen_overlay.h
diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp
index 137b1ac592f..09377f1f3f6 100644
--- a/engines/ags/engine/ac/draw.cpp
+++ b/engines/ags/engine/ac/draw.cpp
@@ -1943,10 +1943,6 @@ void draw_fps(const Rect &viewport) {
invalidate_sprite_glob(1, yp, ddb);
}
-static inline bool is_over_above_gui(int type) {
- return type == OVER_TEXTMSG || type == OVER_PICTURE || type == OVER_TEXTSPEECH;
-}
-
// Draw GUI and overlays of all kinds, anything outside the room space
void draw_gui_and_overlays() {
if (pl_any_want_hook(AGSE_PREGUIDRAW))
@@ -1958,14 +1954,7 @@ void draw_gui_and_overlays() {
for (auto &over : _GP(screenover)) {
int tdxp, tdyp;
get_overlay_position(over, &tdxp, &tdyp);
- // complete overlay draw in non-transparent mode
- if (over.type == OVER_COMPLETE) {
- add_to_sprite_list(over.bmp, tdxp, tdyp, INT_MIN, false);
- } else {
- // draw speech and portraits over GUI and the rest under GUI
- int zorder = is_over_above_gui(over.type) ? INT_MAX : INT_MIN;
- add_to_sprite_list(over.bmp, tdxp, tdyp, zorder, false);
- }
+ add_to_sprite_list(over.bmp, tdxp, tdyp, over.zorder, false);
}
// Add GUIs
diff --git a/engines/ags/engine/ac/overlay.cpp b/engines/ags/engine/ac/overlay.cpp
index af73beca9ec..fe51e692612 100644
--- a/engines/ags/engine/ac/overlay.cpp
+++ b/engines/ags/engine/ac/overlay.cpp
@@ -156,6 +156,22 @@ ScriptOverlay *Overlay_CreateTextual(int x, int y, int width, int font, int colo
return sco;
}
+int Overlay_GetZOrder(ScriptOverlay *scover) {
+ int ovri = find_overlay_of_type(scover->overlayId);
+ if (ovri < 0)
+ quit("!invalid overlay ID specified");
+
+ return _GP(screenover)[ovri].zorder;
+}
+
+void Overlay_SetZOrder(ScriptOverlay *scover, int zorder) {
+ int ovri = find_overlay_of_type(scover->overlayId);
+ if (ovri < 0)
+ quit("!invalid overlay ID specified");
+
+ _GP(screenover)[ovri].zorder = zorder;
+}
+
//=============================================================================
// Creates and registers a managed script object for existing overlay object
@@ -253,6 +269,9 @@ size_t add_screen_overlay(int x, int y, int type, Shared::Bitmap *piccy, int pic
over.y = y;
over._offsetX = pic_offx;
over._offsetY = pic_offy;
+ // by default draw speech and portraits over GUI, and the rest under GUI
+ over.zorder = (type == OVER_TEXTMSG || type == OVER_PICTURE || type == OVER_TEXTSPEECH) ?
+ INT_MAX : INT_MIN;
over.type = type;
over.timeout = 0;
over.bgSpeechForChar = -1;
@@ -392,6 +411,14 @@ RuntimeScriptValue Sc_Overlay_GetHeight(void *self, const RuntimeScriptValue *pa
API_OBJCALL_INT(ScriptOverlay, Overlay_GetHeight);
}
+RuntimeScriptValue Sc_Overlay_GetZOrder(void *self, const RuntimeScriptValue *params, int32_t param_count) {
+ API_OBJCALL_INT(ScriptOverlay, Overlay_GetZOrder);
+}
+
+RuntimeScriptValue Sc_Overlay_SetZOrder(void *self, const RuntimeScriptValue *params, int32_t param_count) {
+ API_OBJCALL_VOID_PINT(ScriptOverlay, Overlay_SetZOrder);
+}
+
//=============================================================================
//
// Exclusive API for Plugins
@@ -417,6 +444,8 @@ void RegisterOverlayAPI() {
ccAddExternalObjectFunction("Overlay::set_Y", Sc_Overlay_SetY);
ccAddExternalObjectFunction("Overlay::get_Width", Sc_Overlay_GetWidth);
ccAddExternalObjectFunction("Overlay::get_Height", Sc_Overlay_GetHeight);
+ ccAddExternalObjectFunction("Overlay::get_ZOrder", Sc_Overlay_GetZOrder);
+ ccAddExternalObjectFunction("Overlay::set_ZOrder", Sc_Overlay_SetZOrder);
}
} // namespace AGS3
diff --git a/engines/ags/engine/ac/screen_overlay.h b/engines/ags/engine/ac/screen_overlay.h
index 4160cd18063..24aefd47740 100644
--- a/engines/ags/engine/ac/screen_overlay.h
+++ b/engines/ags/engine/ac/screen_overlay.h
@@ -46,10 +46,11 @@ using namespace AGS; // FIXME later
struct ScreenOverlay {
Engine::IDriverDependantBitmap *bmp = nullptr;
Shared::Bitmap *pic = nullptr;
+ bool hasAlphaChannel = false;
int type = 0, x = 0, y = 0, timeout = 0;
int bgSpeechForChar = 0;
int associatedOverlayHandle = 0;
- bool hasAlphaChannel = false;
+ int zorder = INT_MIN;
bool positionRelativeToScreen = false;
bool hasSerializedBitmap = false;
int _offsetX = 0, _offsetY = 0;
Commit: 731db80bb467290a1602d32db238d41c70c44aff
https://github.com/scummvm/scummvm/commit/731db80bb467290a1602d32db238d41c70c44aff
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-03-15T22:28:39-07:00
Commit Message:
AGS: Script API Overlay.Transparency
>From upstream c2d63eb32ec9c8653f0b0b24f7a1b4e1fc24aa89
Changed paths:
engines/ags/engine/ac/draw.cpp
engines/ags/engine/ac/gui.cpp
engines/ags/engine/ac/overlay.cpp
engines/ags/engine/ac/screen_overlay.h
diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp
index 09377f1f3f6..7e446775295 100644
--- a/engines/ags/engine/ac/draw.cpp
+++ b/engines/ags/engine/ac/draw.cpp
@@ -1952,6 +1952,10 @@ void draw_gui_and_overlays() {
// Add active overlays to the sprite list
for (auto &over : _GP(screenover)) {
+ if (over.transparency == 255)
+ continue; // skip fully transparent
+ over.bmp->SetTransparency(over.transparency);
+
int tdxp, tdyp;
get_overlay_position(over, &tdxp, &tdyp);
add_to_sprite_list(over.bmp, tdxp, tdyp, over.zorder, false);
diff --git a/engines/ags/engine/ac/gui.cpp b/engines/ags/engine/ac/gui.cpp
index 6e011ac4729..d5f3b50714e 100644
--- a/engines/ags/engine/ac/gui.cpp
+++ b/engines/ags/engine/ac/gui.cpp
@@ -192,12 +192,7 @@ void GUI_SetTransparency(ScriptGUI *tehgui, int trans) {
}
int GUI_GetTransparency(ScriptGUI *tehgui) {
- if (_GP(guis)[tehgui->id].Transparency == 0)
- return 0;
- if (_GP(guis)[tehgui->id].Transparency == 255)
- return 100;
-
- return 100 - ((_GP(guis)[tehgui->id].Transparency * 10) / 25);
+ return GfxDef::LegacyTrans255ToTrans100(_GP(guis)[tehgui->id].Transparency);
}
void GUI_Centre(ScriptGUI *sgui) {
diff --git a/engines/ags/engine/ac/overlay.cpp b/engines/ags/engine/ac/overlay.cpp
index fe51e692612..2811fe99fa1 100644
--- a/engines/ags/engine/ac/overlay.cpp
+++ b/engines/ags/engine/ac/overlay.cpp
@@ -156,6 +156,24 @@ ScriptOverlay *Overlay_CreateTextual(int x, int y, int width, int font, int colo
return sco;
}
+int Overlay_GetTransparency(ScriptOverlay *scover) {
+ int ovri = find_overlay_of_type(scover->overlayId);
+ if (ovri < 0)
+ quit("!invalid overlay ID specified");
+
+ return GfxDef::LegacyTrans255ToTrans100(_GP(screenover)[ovri].transparency);
+}
+
+void Overlay_SetTransparency(ScriptOverlay *scover, int trans) {
+ int ovri = find_overlay_of_type(scover->overlayId);
+ if (ovri < 0)
+ quit("!invalid overlay ID specified");
+ if ((trans < 0) | (trans > 100))
+ quit("!SetTransparency: transparency value must be between 0 and 100");
+
+ _GP(screenover)[ovri].transparency = GfxDef::Trans100ToLegacyTrans255(trans);
+}
+
int Overlay_GetZOrder(ScriptOverlay *scover) {
int ovri = find_overlay_of_type(scover->overlayId);
if (ovri < 0)
@@ -411,6 +429,14 @@ RuntimeScriptValue Sc_Overlay_GetHeight(void *self, const RuntimeScriptValue *pa
API_OBJCALL_INT(ScriptOverlay, Overlay_GetHeight);
}
+RuntimeScriptValue Sc_Overlay_GetTransparency(void *self, const RuntimeScriptValue *params, int32_t param_count) {
+ API_OBJCALL_INT(ScriptOverlay, Overlay_GetTransparency);
+}
+
+RuntimeScriptValue Sc_Overlay_SetTransparency(void *self, const RuntimeScriptValue *params, int32_t param_count) {
+ API_OBJCALL_VOID_PINT(ScriptOverlay, Overlay_SetTransparency);
+}
+
RuntimeScriptValue Sc_Overlay_GetZOrder(void *self, const RuntimeScriptValue *params, int32_t param_count) {
API_OBJCALL_INT(ScriptOverlay, Overlay_GetZOrder);
}
@@ -444,6 +470,8 @@ void RegisterOverlayAPI() {
ccAddExternalObjectFunction("Overlay::set_Y", Sc_Overlay_SetY);
ccAddExternalObjectFunction("Overlay::get_Width", Sc_Overlay_GetWidth);
ccAddExternalObjectFunction("Overlay::get_Height", Sc_Overlay_GetHeight);
+ ccAddExternalObjectFunction("Overlay::get_Transparency", Sc_Overlay_GetTransparency);
+ ccAddExternalObjectFunction("Overlay::set_Transparency", Sc_Overlay_SetTransparency);
ccAddExternalObjectFunction("Overlay::get_ZOrder", Sc_Overlay_GetZOrder);
ccAddExternalObjectFunction("Overlay::set_ZOrder", Sc_Overlay_SetZOrder);
}
diff --git a/engines/ags/engine/ac/screen_overlay.h b/engines/ags/engine/ac/screen_overlay.h
index 24aefd47740..c40a0c8d2b2 100644
--- a/engines/ags/engine/ac/screen_overlay.h
+++ b/engines/ags/engine/ac/screen_overlay.h
@@ -54,6 +54,7 @@ struct ScreenOverlay {
bool positionRelativeToScreen = false;
bool hasSerializedBitmap = false;
int _offsetX = 0, _offsetY = 0;
+ int transparency = 0;
void ReadFromFile(Shared::Stream *in, int32_t cmp_ver);
void WriteToFile(Shared::Stream *out) const;
Commit: b07b63920a7977c36b7d47905e11e8e502512626
https://github.com/scummvm/scummvm/commit/b07b63920a7977c36b7d47905e11e8e502512626
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-03-15T22:28:39-07:00
Commit Message:
AGS: Serialize overlay.z and transparency
>From upstream bb07262a81a57ca6abc700af178a06e4879abdc9
Changed paths:
engines/ags/engine/ac/screen_overlay.cpp
engines/ags/engine/game/savegame_components.cpp
diff --git a/engines/ags/engine/ac/screen_overlay.cpp b/engines/ags/engine/ac/screen_overlay.cpp
index 2de0404ca07..546610e854e 100644
--- a/engines/ags/engine/ac/screen_overlay.cpp
+++ b/engines/ags/engine/ac/screen_overlay.cpp
@@ -45,6 +45,12 @@ void ScreenOverlay::ReadFromFile(Stream *in, int32_t cmp_ver) {
_offsetX = in->ReadInt32();
_offsetY = in->ReadInt32();
}
+ if (cmp_ver >= 2) {
+ zorder = in->ReadInt32();
+ transparency = in->ReadInt32();
+ in->ReadInt32(); // reserve 2 ints
+ in->ReadInt32();
+ }
}
void ScreenOverlay::WriteToFile(Stream *out) const {
@@ -62,6 +68,11 @@ void ScreenOverlay::WriteToFile(Stream *out) const {
// since cmp_ver = 1
out->WriteInt32(_offsetX);
out->WriteInt32(_offsetY);
+ // since cmp_ver = 2
+ out->WriteInt32(zorder);
+ out->WriteInt32(transparency);
+ out->WriteInt32(0); // reserve 2 ints
+ out->WriteInt32(0);
}
} // namespace AGS3
diff --git a/engines/ags/engine/game/savegame_components.cpp b/engines/ags/engine/game/savegame_components.cpp
index 80f13a7504f..d8c687b0e4b 100644
--- a/engines/ags/engine/game/savegame_components.cpp
+++ b/engines/ags/engine/game/savegame_components.cpp
@@ -755,7 +755,6 @@ HSaveError WriteOverlays(Stream *out) {
}
HSaveError ReadOverlays(Stream *in, int32_t cmp_ver, const PreservedParams &pp, RestoredData &r_data) {
- HSaveError err;
size_t over_count = in->ReadInt32();
for (size_t i = 0; i < over_count; ++i) {
ScreenOverlay over;
@@ -764,7 +763,7 @@ HSaveError ReadOverlays(Stream *in, int32_t cmp_ver, const PreservedParams &pp,
over.pic = read_serialized_bitmap(in);
_GP(screenover).push_back(over);
}
- return err;
+ return HSaveError::None();
}
HSaveError WriteDynamicSurfaces(Stream *out) {
@@ -1071,7 +1070,7 @@ ComponentHandler ComponentHandlers[] = {
},
{
"Overlays",
- 1,
+ 2,
0,
WriteOverlays,
ReadOverlays
More information about the Scummvm-git-logs
mailing list