[Scummvm-git-logs] scummvm branch-2-6 -> 6cfb6dbef8e2fd6b8653492cd95e29ce73552ce1
criezy
noreply at scummvm.org
Sun Jun 19 20:01:25 UTC 2022
This automated email contains information about 12 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
f1ba20cefd AGS: Fixes for MemoryStream: proper seek support for writing mode
ffefd81c6b AGS: Refactored do_conversation()
006b96ccc3 AGS: Fixed renderer error if room backgrounds are of different size
e4c42034ac AGS: Fixed frame delay was skipped each time the game speed changes
5a3ce2831c AGS: Fixed sprite cache limit was reset on sprite file open
2da9b88588 AGS: Fixed CreateTextCore not passing room layer flag further
966cd9038e AGS: Fixed rendering scaled up WFN fonts
2b8a7be704 AGS: Fixed trying to erase background speech overlays twice
18db659ae3 AGS: Fix implementation of std::list::insert
08ebc88612 AGS: In unload_game_file() don't error if quit during the of dialog
a4fb95365b AGS: Store camera & viewport handles, not script ptrs, for safety
6cfb6dbef8 AGS: Store certain overlay handles, not script ptrs, for safety
Commit: f1ba20cefd6420520b28c98fb018e71a1ca73a3f
https://github.com/scummvm/scummvm/commit/f1ba20cefd6420520b28c98fb018e71a1ca73a3f
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-19T20:53:13+01:00
Commit Message:
AGS: Fixes for MemoryStream: proper seek support for writing mode
>From upstream 80a17c94f6fc44955dcee5c559247ea73a8c0a76
Changed paths:
engines/ags/shared/util/memory_stream.cpp
engines/ags/shared/util/memory_stream.h
diff --git a/engines/ags/shared/util/memory_stream.cpp b/engines/ags/shared/util/memory_stream.cpp
index 69bcd01f1bd..08fb485afc9 100644
--- a/engines/ags/shared/util/memory_stream.cpp
+++ b/engines/ags/shared/util/memory_stream.cpp
@@ -31,19 +31,25 @@ MemoryStream::MemoryStream(const uint8_t *cbuf, size_t buf_sz, DataEndianess str
, _cbuf(cbuf)
, _buf_sz(buf_sz)
, _len(buf_sz)
- , _buf(nullptr)
, _mode(kStream_Read)
- , _pos(0) {
+ , _pos(0)
+ , _buf(nullptr) {
}
MemoryStream::MemoryStream(uint8_t *buf, size_t buf_sz, StreamWorkMode mode, DataEndianess stream_endianess)
: DataStream(stream_endianess)
- , _buf(buf)
+ , _cbuf(nullptr)
, _buf_sz(buf_sz)
, _len(0)
- , _cbuf(nullptr)
, _mode(mode)
- , _pos(0) {
+ , _pos(0)
+ , _buf(nullptr) {
+ if (mode == kStream_Read) {
+ _cbuf = buf;
+ _len = buf_sz;
+ } else {
+ _buf = buf;
+ }
}
void MemoryStream::Close() {
@@ -83,7 +89,7 @@ bool MemoryStream::CanWrite() const {
}
bool MemoryStream::CanSeek() const {
- return CanRead(); // TODO: support seeking in writable stream?
+ return true;
}
size_t MemoryStream::Read(void *buffer, size_t size) {
@@ -123,20 +129,25 @@ bool MemoryStream::Seek(soff_t offset, StreamSeek origin) {
}
size_t MemoryStream::Write(const void *buffer, size_t size) {
- if (_pos >= _buf_sz) {
+ if (!_buf || (_pos >= _buf_sz)) {
return 0;
}
size = MIN(size, _buf_sz - _pos);
memcpy(_buf + _pos, buffer, size);
_pos += size;
- _len += size;
+ // will increase len if writing after eos, otherwise = overwrite at pos
+ _len = MAX(_len, _pos);
return size;
}
int32_t MemoryStream::WriteByte(uint8_t val) {
- if (_pos >= _buf_sz) { return -1; }
+ if (!_buf || (_pos >= _buf_sz)) {
+ return -1;
+ }
*(_buf + _pos) = val;
- _pos++; _len++;
+ _pos++;
+ // will increase len if writing after eos, otherwise = overwrite at pos
+ _len = MAX(_len, _pos);
return val;
}
@@ -147,7 +158,7 @@ VectorStream::VectorStream(const std::vector<uint8_t> &cbuf, DataEndianess strea
}
VectorStream::VectorStream(std::vector<uint8_t> &buf, StreamWorkMode mode, DataEndianess stream_endianess)
- : MemoryStream((mode == kStream_Read) ? &buf.front() : nullptr, buf.size(), mode, stream_endianess)
+ : MemoryStream(((mode == kStream_Read) && (buf.size() > 0)) ? &buf.front() : nullptr, buf.size(), mode, stream_endianess)
, _vec(&buf) {
}
@@ -156,17 +167,32 @@ void VectorStream::Close() {
MemoryStream::Close();
}
+bool VectorStream::CanRead() const {
+ return _mode == kStream_Read;
+}
+
+bool VectorStream::CanWrite() const {
+ return _mode == kStream_Write;
+}
+
size_t VectorStream::Write(const void *buffer, size_t size) {
- _vec->resize(_vec->size() + size);
+ if (_pos + size > _len) {
+ _vec->resize(_pos + size);
+ _len = _pos + size;
+ }
memcpy(_vec->data() + _pos, buffer, size);
_pos += size;
- _len += size;
return size;
}
int32_t VectorStream::WriteByte(uint8_t val) {
- _vec->push_back(val);
- _pos++; _len++;
+ if (_pos == _len) {
+ _vec->push_back(val);
+ _len++;
+ } else {
+ (*_vec)[_pos] = val;
+ }
+ _pos++;
return val;
}
diff --git a/engines/ags/shared/util/memory_stream.h b/engines/ags/shared/util/memory_stream.h
index 5cba412d206..d3394412b8d 100644
--- a/engines/ags/shared/util/memory_stream.h
+++ b/engines/ags/shared/util/memory_stream.h
@@ -78,14 +78,14 @@ public:
bool Seek(soff_t offset, StreamSeek origin) override;
protected:
- const uint8_t *_cbuf;
- size_t _buf_sz; // hard buffer limit
- size_t _len; // calculated length of stream
+ const uint8_t *_cbuf = nullptr; // readonly buffer ptr
+ size_t _buf_sz = 0u; // hard buffer limit
+ size_t _len = 0u; // calculated length of stream
const StreamWorkMode _mode;
- size_t _pos; // current stream pos
+ size_t _pos = 0u; // current stream pos
private:
- uint8_t *_buf;
+ uint8_t *_buf = nullptr; // writeable buffer ptr
};
@@ -101,11 +101,14 @@ public:
void Close() override;
+ bool CanRead() const override;
+ bool CanWrite() const override;
+
size_t Write(const void *buffer, size_t size) override;
int32_t WriteByte(uint8_t b) override;
private:
- std::vector<uint8_t> *_vec; // writeable vector (may be null)
+ std::vector<uint8_t> *_vec = nullptr; // writeable vector (may be null)
};
} // namespace Shared
Commit: ffefd81c6b857b6ae016091a94831f7e1af9a89f
https://github.com/scummvm/scummvm/commit/ffefd81c6b857b6ae016091a94831f7e1af9a89f
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-19T20:53:34+01:00
Commit Message:
AGS: Refactored do_conversation()
Split do_conversation into multiple functions, simplified the running
the dialog topics chain code and removed code duplication as possible.
+ Removed the limit of nested dialogs.
+ This also fixes "goto-previous" not working from the first sub-dialog.
>From upstream 7bb167f5f6ee6a1976b829a1d67423d69346dc6e
Changed paths:
engines/ags/engine/ac/dialog.cpp
diff --git a/engines/ags/engine/ac/dialog.cpp b/engines/ags/engine/ac/dialog.cpp
index 6719c366edb..a12373db57b 100644
--- a/engines/ags/engine/ac/dialog.cpp
+++ b/engines/ags/engine/ac/dialog.cpp
@@ -19,6 +19,7 @@
*
*/
+#include "common/stack.h"
#include "ags/engine/ac/dialog.h"
#include "ags/shared/ac/common.h"
#include "ags/engine/ac/character.h"
@@ -390,7 +391,6 @@ bool get_custom_dialog_options_dimensions(int dlgnum) {
return false;
}
-#define MAX_TOPIC_HISTORY 50
#define DLG_OPTION_PARSER 99
struct DialogOptions {
@@ -1048,69 +1048,65 @@ int show_dialog_options(int _dlgnum, int sayChosenOption, bool _runGameLoopsInBa
return dialog_choice;
}
-void do_conversation(int dlgnum) {
- EndSkippingUntilCharStops();
-
- // AGS 2.x always makes the mouse cursor visible when displaying a dialog.
- if (_G(loaded_game_file_version) <= kGameVersion_272)
- _GP(play).mouse_cursor_hidden = 0;
-
- int dlgnum_was = dlgnum;
- int previousTopics[MAX_TOPIC_HISTORY];
- int numPrevTopics = 0;
- DialogTopic *dtop = &_G(dialog)[dlgnum];
+// Dialog execution state
+struct DialogExec {
+ int DlgNum = -1;
+ int DlgWas = -1;
+ // CHECKME: this may be unnecessary, investigate later
+ bool IsFirstEntry = true;
+ // nested dialogs "stack"
+ Common::Stack<int> TopicHist;
+
+ DialogExec(int start_dlgnum) : DlgNum(start_dlgnum) {}
+ int HandleDialogResult(int res);
+ void Run();
+};
- // run the startup script
- int tocar = run_dialog_script(dlgnum, dtop->startupentrypoint, 0);
- if ((tocar == RUN_DIALOG_STOP_DIALOG) ||
- (tocar == RUN_DIALOG_GOTO_PREVIOUS)) {
- // 'stop' or 'goto-previous' from first startup script
- remove_screen_overlay(OVER_COMPLETE);
- _GP(play).in_conversation--;
- return;
- } else if (tocar >= 0)
- dlgnum = tocar;
-
- while (dlgnum >= 0) {
- if (dlgnum >= _GP(game).numdialog)
- quit("!RunDialog: invalid dialog number specified");
-
- dtop = &_G(dialog)[dlgnum];
-
- if (dlgnum != dlgnum_was) {
- // dialog topic changed, so play the startup
- // script for the new topic
- tocar = run_dialog_script(dlgnum, dtop->startupentrypoint, 0);
- dlgnum_was = dlgnum;
- if (tocar == RUN_DIALOG_GOTO_PREVIOUS) {
- if (numPrevTopics < 1) {
- // goto-previous on first topic -- end dialog
- tocar = RUN_DIALOG_STOP_DIALOG;
- } else {
- tocar = previousTopics[numPrevTopics - 1];
- numPrevTopics--;
- }
- }
- if (tocar == RUN_DIALOG_STOP_DIALOG)
- break;
- else if (tocar >= 0) {
- // save the old topic number in the history
- if (numPrevTopics < MAX_TOPIC_HISTORY) {
- previousTopics[numPrevTopics] = dlgnum;
- numPrevTopics++;
- }
- dlgnum = tocar;
- continue;
- }
+int DialogExec::HandleDialogResult(int res) {
+ // Handle goto-previous, see if there's any previous dialog in history
+ if (res == RUN_DIALOG_GOTO_PREVIOUS) {
+ if (TopicHist.size() == 0)
+ return RUN_DIALOG_STOP_DIALOG;
+ res = TopicHist.top();
+ TopicHist.pop();
+ }
+ // Continue to the next dialog
+ if (res >= 0) {
+ // save the old topic number in the history, and switch to the new one
+ TopicHist.push(DlgNum);
+ DlgNum = res;
+ return DlgNum;
+ }
+ return res;
+ }
+
+void DialogExec::Run() {
+ while (DlgNum >= 0) {
+ if (DlgNum < 0 || DlgNum >= _GP(game).numdialog)
+ quitprintf("!RunDialog: invalid dialog number specified: %d", DlgNum);
+
+ // current dialog object
+ DialogTopic *dtop = &_G(dialog)[DlgNum];
+ int res = 0; // dialog execution result
+ // If a new dialog topic: run dialog entry point
+ if (DlgNum != DlgWas) {
+ res = run_dialog_script(DlgNum, dtop->startupentrypoint, 0);
+ DlgWas = DlgNum;
+
+ // Handle the dialog entry's result
+ res = HandleDialogResult(res);
+ if (res == RUN_DIALOG_STOP_DIALOG)
+ return; // stop the dialog
+ IsFirstEntry = false;
+ if (res != RUN_DIALOG_STAY)
+ continue; // skip to the next dialog
}
- int chose = show_dialog_options(dlgnum, SAYCHOSEN_USEFLAG, (_GP(game).options[OPT_RUNGAMEDLGOPTS] != 0));
-
+ // Show current dialog's options
+ int chose = show_dialog_options(DlgNum, SAYCHOSEN_USEFLAG, (_GP(game).options[OPT_RUNGAMEDLGOPTS] != 0));
if (chose == CHOSE_TEXTPARSER) {
_G(said_speech_line) = 0;
-
- tocar = run_dialog_request(dlgnum);
-
+ res = run_dialog_request(DlgNum);
if (_G(said_speech_line) > 0) {
// fix the problem with the close-up face remaining on screen
DisableInterface();
@@ -1119,28 +1115,34 @@ void do_conversation(int dlgnum) {
set_mouse_cursor(CURS_ARROW);
}
} else if (chose >= 0) {
- tocar = run_dialog_script(dlgnum, dtop->entrypoints[chose], chose + 1);
+ // chose some option - run its script
+ res = run_dialog_script(DlgNum, dtop->entrypoints[chose], chose + 1);
} else {
- tocar = RUN_DIALOG_STOP_DIALOG;
+ return; // no option chosen? - stop the dialog
}
- if (tocar == RUN_DIALOG_GOTO_PREVIOUS) {
- if (numPrevTopics < 1) {
- tocar = RUN_DIALOG_STOP_DIALOG;
- } else {
- tocar = previousTopics[numPrevTopics - 1];
- numPrevTopics--;
- }
- }
- if (tocar == RUN_DIALOG_STOP_DIALOG) break;
- else if (tocar >= 0) {
- // save the old topic number in the history
- if (numPrevTopics < MAX_TOPIC_HISTORY) {
- previousTopics[numPrevTopics] = dlgnum;
- numPrevTopics++;
- }
- dlgnum = tocar;
- }
+ // Handle the dialog option's result
+ res = HandleDialogResult(res);
+ if (res == RUN_DIALOG_STOP_DIALOG)
+ return; // stop the dialog
+ // continue to the next dialog or show same dialog's options again
+ }
+}
+
+void do_conversation(int dlgnum) {
+ EndSkippingUntilCharStops();
+
+ // AGS 2.x always makes the mouse cursor visible when displaying a dialog.
+ if (_G(loaded_game_file_version) <= kGameVersion_272)
+ _GP(play).mouse_cursor_hidden = 0;
+
+ DialogExec dlgexec(dlgnum);
+ dlgexec.Run();
+ // CHECKME: find out if this is safe to do always, regardless of number of iterations
+ if (dlgexec.IsFirstEntry) {
+ // bail out from first startup script
+ remove_screen_overlay(OVER_COMPLETE);
+ _GP(play).in_conversation--;
}
}
Commit: 006b96ccc3c64253b8ba319167c707fd2e1e266c
https://github.com/scummvm/scummvm/commit/006b96ccc3c64253b8ba319167c707fd2e1e266c
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-19T20:53:45+01:00
Commit Message:
AGS: Fixed renderer error if room backgrounds are of different size
>From upstream 660857d193b9bcac3a7bb1bba70be8149b1e2d7e
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 5660172d894..bbe69d33a46 100644
--- a/engines/ags/engine/ac/draw.cpp
+++ b/engines/ags/engine/ac/draw.cpp
@@ -1690,12 +1690,11 @@ void prepare_room_sprites() {
// Background sprite is required for the non-software renderers always,
// and for software renderer in case there are overlapping viewports.
// Note that software DDB is just a tiny wrapper around bitmap, so overhead is negligible.
- if (_G(roomBackgroundBmp) == nullptr) {
+ if (_G(current_background_is_dirty) || !_G(roomBackgroundBmp)) {
update_polled_stuff_if_runtime();
- _G(roomBackgroundBmp) = _G(gfxDriver)->CreateDDBFromBitmap(_GP(thisroom).BgFrames[_GP(play).bg_frame].Graphic.get(), false, true);
- } else if (_G(current_background_is_dirty)) {
- update_polled_stuff_if_runtime();
- _G(gfxDriver)->UpdateDDBFromBitmap(_G(roomBackgroundBmp), _GP(thisroom).BgFrames[_GP(play).bg_frame].Graphic.get(), false);
+ _G(roomBackgroundBmp) =
+ recycle_ddb_bitmap(_G(roomBackgroundBmp), _GP(thisroom).BgFrames[_GP(play).bg_frame].Graphic.get(), false, true);
+
}
if (_G(gfxDriver)->RequiresFullRedrawEachFrame()) {
if (_G(current_background_is_dirty) || _G(walkBehindsCachedForBgNum) != _GP(play).bg_frame) {
Commit: e4c42034ac8f9744b0ea6a1c53460098a539f570
https://github.com/scummvm/scummvm/commit/e4c42034ac8f9744b0ea6a1c53460098a539f570
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-19T20:53:56+01:00
Commit Message:
AGS: Fixed frame delay was skipped each time the game speed changes
This was not correct, and could cause endless frame skipping if
SetGameSpeed() is called repeatedly in game script.
>From upstream 690f08b8468dd61ae570c7480098708ba6dc669f
Changed paths:
engines/ags/engine/ac/timer.cpp
diff --git a/engines/ags/engine/ac/timer.cpp b/engines/ags/engine/ac/timer.cpp
index 281d119ced4..05ec0b3b9cd 100644
--- a/engines/ags/engine/ac/timer.cpp
+++ b/engines/ags/engine/ac/timer.cpp
@@ -30,7 +30,7 @@
namespace AGS3 {
namespace {
-const auto MAXIMUM_FALL_BEHIND = 3;
+const auto MAXIMUM_FALL_BEHIND = 3; // number of full frames
}
std::chrono::microseconds GetFrameDuration() {
@@ -46,8 +46,8 @@ int setTimerFps(int new_fps) {
_G(framerate) = new_fps;
_G(framerate_maxed) = new_fps >= 1000;
- _G(last_tick_time) = AGS_Clock::now();
- _G(next_frame_timestamp) = AGS_Clock::now();
+ // Update next frame time
+ _G(next_frame_timestamp) = _G(last_tick_time) + _G(tick_duration);
return old_fps;
}
@@ -56,11 +56,12 @@ bool isTimerFpsMaxed() {
}
void WaitForNextFrame() {
- auto now = AGS_Clock::now();
- auto frameDuration = GetFrameDuration();
+ const auto now = AGS_Clock::now();
+ const auto frameDuration = GetFrameDuration();
// early exit if we're trying to maximise framerate
if (frameDuration <= std::chrono::milliseconds::zero()) {
+ _G(last_tick_time) = _G(next_frame_timestamp);
_G(next_frame_timestamp) = now;
// suspend while the game is being switched out
while (_G(game_update_suspend)) {
@@ -80,6 +81,7 @@ void WaitForNextFrame() {
std::this_thread::sleep_for(frame_time_remaining);
}
+ _G(last_tick_time) = _G(next_frame_timestamp);
_G(next_frame_timestamp) += frameDuration;
// suspend while the game is being switched out
Commit: 5a3ce2831c3ee906574abcd594d84c532813abf2
https://github.com/scummvm/scummvm/commit/5a3ce2831c3ee906574abcd594d84c532813abf2
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-19T20:54:08+01:00
Commit Message:
AGS: Fixed sprite cache limit was reset on sprite file open
>From upstream 4f57730e2b3d41af4fd0300e8b092d31d448f544
Changed paths:
engines/ags/engine/ac/game_setup.h
engines/ags/engine/ac/global_debug.cpp
engines/ags/engine/main/config.cpp
engines/ags/engine/main/engine.cpp
engines/ags/shared/ac/sprite_cache.cpp
engines/ags/shared/ac/sprite_cache.h
diff --git a/engines/ags/engine/ac/game_setup.h b/engines/ags/engine/ac/game_setup.h
index d1d703656e7..ce0edb245e0 100644
--- a/engines/ags/engine/ac/game_setup.h
+++ b/engines/ags/engine/ac/game_setup.h
@@ -92,6 +92,7 @@ struct GameSetup {
MouseSpeedDef mouse_speed_def;
bool RenderAtScreenRes; // render sprites at screen resolution, as opposed to native one
int Supersampling;
+ size_t SpriteCacheSize = 0u;
bool clear_cache_on_room_change; // for low-end devices: clear resource caches on room change
bool load_latest_save; // load latest saved game on launch
ScreenRotation rotation;
diff --git a/engines/ags/engine/ac/global_debug.cpp b/engines/ags/engine/ac/global_debug.cpp
index 7874a530fb6..a0df887f507 100644
--- a/engines/ags/engine/ac/global_debug.cpp
+++ b/engines/ags/engine/ac/global_debug.cpp
@@ -59,7 +59,7 @@ String GetRuntimeInfo() {
"Adventure Game Studio run-time engine[ACI version %s"
"[Game resolution %d x %d (%d-bit)"
"[Running %d x %d at %d-bit%s[GFX: %s; %s[Draw frame %d x %d["
- "Sprite cache size: %d KB (limit %d KB; %d locked)",
+ "Sprite cache size: %d KB (limit %d KB; %d KB locked)",
_G(EngineVersion).LongString.GetCStr(), _GP(game).GetGameRes().Width, _GP(game).GetGameRes().Height, _GP(game).GetColorDepth(),
mode.Width, mode.Height, mode.ColorDepth,
mode.IsWindowed() ? " W" : "",
diff --git a/engines/ags/engine/main/config.cpp b/engines/ags/engine/main/config.cpp
index 709ff95c9cb..37ce15c2c7d 100644
--- a/engines/ags/engine/main/config.cpp
+++ b/engines/ags/engine/main/config.cpp
@@ -326,7 +326,7 @@ void apply_config(const ConfigTree &cfg) {
int cache_size_kb = CfgReadInt(cfg, "misc", "cachemax", DEFAULTCACHESIZE_KB);
if (cache_size_kb > 0)
- _GP(spriteset).SetMaxCacheSize((size_t)cache_size_kb * 1024);
+ _GP(usetup).SpriteCacheSize = cache_size_kb * 1024;
_GP(usetup).mouse_auto_lock = CfgReadBoolInt(cfg, "mouse", "auto_lock");
diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp
index c7aeee52c71..73ebbd5f8c8 100644
--- a/engines/ags/engine/main/engine.cpp
+++ b/engines/ags/engine/main/engine.cpp
@@ -509,7 +509,6 @@ void show_preload() {
int engine_init_sprites() {
Debug::Printf(kDbgMsg_Info, "Initialize sprites");
-
HError err = _GP(spriteset).InitFile(SpriteFile::DefaultSpriteFileName, SpriteFile::DefaultSpriteIndexName);
if (!err) {
sys_main_shutdown();
@@ -521,6 +520,8 @@ int engine_init_sprites() {
return EXIT_ERROR;
}
+ if (_GP(usetup).SpriteCacheSize > 0)
+ _GP(spriteset).SetMaxCacheSize(_GP(usetup).SpriteCacheSize);
return 0;
}
diff --git a/engines/ags/shared/ac/sprite_cache.cpp b/engines/ags/shared/ac/sprite_cache.cpp
index 2940e93d8a8..ff375e35731 100644
--- a/engines/ags/shared/ac/sprite_cache.cpp
+++ b/engines/ags/shared/ac/sprite_cache.cpp
@@ -68,8 +68,8 @@ SpriteCache::SpriteData::~SpriteData() {
}
SpriteCache::SpriteCache(std::vector<SpriteInfo> &sprInfos)
- : _sprInfos(sprInfos) {
- Init();
+ : _sprInfos(sprInfos), _maxCacheSize(DEFAULTCACHESIZE_KB * 1024u),
+ _cacheSize(0u), _lockedSize(0u), _liststart(-1), _listend(-1) {
}
SpriteCache::~SpriteCache() {
@@ -96,14 +96,6 @@ void SpriteCache::SetMaxCacheSize(size_t size) {
_maxCacheSize = size;
}
-void SpriteCache::Init() {
- _cacheSize = 0;
- _lockedSize = 0;
- _maxCacheSize = (size_t)DEFAULTCACHESIZE_KB * 1024;
- _liststart = -1;
- _listend = -1;
-}
-
void SpriteCache::Reset() {
_file.Close();
// TODO: find out if it's safe to simply always delete _spriteData.Image with array element
@@ -115,10 +107,13 @@ void SpriteCache::Reset() {
}
_spriteData.clear();
+ _cacheSize = 0;
+ _lockedSize = 0;
_mrulist.clear();
_mrubacklink.clear();
- Init();
+ _liststart = -1;
+ _listend = -1;
}
void SpriteCache::SetSprite(sprkey_t index, Bitmap *sprite) {
diff --git a/engines/ags/shared/ac/sprite_cache.h b/engines/ags/shared/ac/sprite_cache.h
index 93b63d83773..d2a1b5b2412 100644
--- a/engines/ags/shared/ac/sprite_cache.h
+++ b/engines/ags/shared/ac/sprite_cache.h
@@ -146,7 +146,6 @@ public:
Shared::Bitmap *operator[](sprkey_t index);
private:
- void Init();
// Load sprite from game resource
size_t LoadSprite(sprkey_t index);
// Gets the index of a sprite which data is used for the given slot;
Commit: 2da9b88588eac33ffd4b17224c21d8bd6161a405
https://github.com/scummvm/scummvm/commit/2da9b88588eac33ffd4b17224c21d8bd6161a405
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-19T20:54:20+01:00
Commit Message:
AGS: Fixed CreateTextCore not passing room layer flag further
>From upstream e5aaa87573c6357edeb50a526892619ff748ea12
Changed paths:
engines/ags/engine/ac/overlay.cpp
diff --git a/engines/ags/engine/ac/overlay.cpp b/engines/ags/engine/ac/overlay.cpp
index 770d8a7689a..7716fc504c4 100644
--- a/engines/ags/engine/ac/overlay.cpp
+++ b/engines/ags/engine/ac/overlay.cpp
@@ -213,7 +213,7 @@ ScreenOverlay *Overlay_CreateTextCore(bool room_layer, int x, int y, int width,
if (width < 8) width = _GP(play).GetUIViewport().GetWidth() / 2;
if (x < 0) x = _GP(play).GetUIViewport().GetWidth() / 2 - width / 2;
if (text_color == 0) text_color = 16;
- return _display_main(x, y, width, text, disp_type, font, -text_color, 0, allow_shrink, false);
+ return _display_main(x, y, width, text, disp_type, font, -text_color, 0, allow_shrink, false, room_layer);
}
ScriptOverlay *Overlay_CreateGraphicalEx(bool room_layer, int x, int y, int slot, int transparent, bool clone) {
Commit: 966cd9038e56fc90a297dc05851f901a86a96485
https://github.com/scummvm/scummvm/commit/966cd9038e56fc90a297dc05851f901a86a96485
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-19T20:54:33+01:00
Commit Message:
AGS: Fixed rendering scaled up WFN fonts
>From upstream adc9121f30c028a071783ffb6645bb72aee482ea
Changed paths:
engines/ags/shared/font/wfn_font_renderer.cpp
diff --git a/engines/ags/shared/font/wfn_font_renderer.cpp b/engines/ags/shared/font/wfn_font_renderer.cpp
index e5eb6d6d140..1cca2fc4763 100644
--- a/engines/ags/shared/font/wfn_font_renderer.cpp
+++ b/engines/ags/shared/font/wfn_font_renderer.cpp
@@ -111,7 +111,7 @@ static int RenderChar(Bitmap *ds, const int at_x, const int at_y, Rect clip,
for (int w = sw, x = sx; w < width && x < ex; ++w, x += scale) {
if (((actdata[h * bytewid + (w / 8)] & (0x80 >> (w % 8))) != 0)) {
if (scale > 1) {
- ds->FillRect(RectWH(x, y, scale - 1, scale - 1), text_color);
+ ds->FillRect(RectWH(x, y, scale, scale), text_color);
} else {
ds->PutPixel(x, y, text_color);
}
Commit: 2b8a7be704fc54080003b91f473f300643e49a65
https://github.com/scummvm/scummvm/commit/2b8a7be704fc54080003b91f473f300643e49a65
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-19T20:54:47+01:00
Commit Message:
AGS: Fixed trying to erase background speech overlays twice
>From upstream 5f137874738c86852b5ef7da2933fab7e78ae89b
Changed paths:
engines/ags/engine/ac/overlay.cpp
diff --git a/engines/ags/engine/ac/overlay.cpp b/engines/ags/engine/ac/overlay.cpp
index 7716fc504c4..6c98bbddaa4 100644
--- a/engines/ags/engine/ac/overlay.cpp
+++ b/engines/ags/engine/ac/overlay.cpp
@@ -291,7 +291,11 @@ static void invalidate_and_subref(ScreenOverlay &over, ScriptOverlay **scover) {
if (scover && (*scover)) {
(*scover)->overlayId = -1;
*scover = nullptr;
+ } else if (over.associatedOverlayHandle > 0) {
+ ScriptOverlay *scoverlay = const_cast<ScriptOverlay*>((const ScriptOverlay* )ccGetObjectAddressFromHandle(over.associatedOverlayHandle));
+ if (scoverlay) scoverlay->overlayId = -1;
}
+
if (over.associatedOverlayHandle > 0) {
ccReleaseObjectReference(over.associatedOverlayHandle);
over.associatedOverlayHandle = 0;
@@ -313,6 +317,9 @@ static void dispose_overlay(ScreenOverlay &over) {
}
void remove_screen_overlay_index(size_t over_idx) {
+ assert(over_idx < _GP(screenover).size());
+ if (over_idx >= _GP(screenover).size())
+ return; // something is wrong
ScreenOverlay &over = _GP(screenover)[over_idx];
// TODO: move these custom settings outside of this function
if (over.type == _GP(play).complete_overlay_on) {
@@ -323,7 +330,7 @@ void remove_screen_overlay_index(size_t over_idx) {
} else if (over.type == OVER_PICTURE) { // release internal ref for speech face
invalidate_and_subref(over, &_GP(play).speech_face_scover);
_G(face_talking) = -1;
- } else if (over.bgSpeechForChar > 0) { // release internal ref for bg speech
+ } else if (over.bgSpeechForChar >= 0) { // release internal ref for bg speech
invalidate_and_subref(over, nullptr);
}
dispose_overlay(over);
Commit: 18db659ae350af3ec7235a46a08f02998d49c807
https://github.com/scummvm/scummvm/commit/18db659ae350af3ec7235a46a08f02998d49c807
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-19T20:54:58+01:00
Commit Message:
AGS: Fix implementation of std::list::insert
Instead of returning an iterator to the inserted item, it was
returning an iterator to the next item. This was for example causing
bugs in the SpriteCache.
Changed paths:
engines/ags/lib/std/list.h
diff --git a/engines/ags/lib/std/list.h b/engines/ags/lib/std/list.h
index d0e037bdcbb..86be1e580f2 100644
--- a/engines/ags/lib/std/list.h
+++ b/engines/ags/lib/std/list.h
@@ -59,7 +59,7 @@ public:
typename Common::List<T>::iterator insert(typename Common::List<T>::iterator pos,
const T &element) {
Common::List<T>::insert(pos, element);
- return pos;
+ return --pos;
}
reverse_iterator rbegin() {
Commit: 08ebc886124cb6799733b1eea7ffdee09920cb65
https://github.com/scummvm/scummvm/commit/08ebc886124cb6799733b1eea7ffdee09920cb65
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-19T20:55:08+01:00
Commit Message:
AGS: In unload_game_file() don't error if quit during the of dialog
>From upstream c7bd448dfffc197c4398a38395b444457c958d24
Changed paths:
engines/ags/engine/ac/game.cpp
diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp
index f5818ca7dff..8f7e1589b43 100644
--- a/engines/ags/engine/ac/game.cpp
+++ b/engines/ags/engine/ac/game.cpp
@@ -355,7 +355,6 @@ void free_do_once_tokens() {
// Free all the memory associated with the game
-// TODO: call this when exiting the game (currently only called in RunAGSGame)
void unload_game_file() {
close_translation();
@@ -371,16 +370,10 @@ void unload_game_file() {
delete _G(gameinst);
_G(gameinstFork) = nullptr;
_G(gameinst) = nullptr;
-
_GP(gamescript).reset();
- if ((_G(dialogScriptsInst) != nullptr) && (_G(dialogScriptsInst)->pc != 0)) {
- quit("Error: unload_game called while dialog script still running");
- } else if (_G(dialogScriptsInst) != nullptr) {
- delete _G(dialogScriptsInst);
- _G(dialogScriptsInst) = nullptr;
- }
-
+ delete _G(dialogScriptsInst);
+ _G(dialogScriptsInst) = nullptr;
_GP(dialogScriptsScript).reset();
for (size_t i = 0; i < _G(numScriptModules); ++i) {
Commit: a4fb95365b8f624dddc217e31fe82bb05825df1f
https://github.com/scummvm/scummvm/commit/a4fb95365b8f624dddc217e31fe82bb05825df1f
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-19T20:55:18+01:00
Commit Message:
AGS: Store camera & viewport handles, not script ptrs, for safety
>From ustream dc1421a88cd620bd1d34f8bf856e8baa57a50904
Also includes upstream 09c27c38c3afa27194b0b5dd9276036b76267488
Changed paths:
engines/ags/engine/ac/game_state.cpp
engines/ags/engine/ac/game_state.h
diff --git a/engines/ags/engine/ac/game_state.cpp b/engines/ags/engine/ac/game_state.cpp
index 25481f57330..f55a403acb8 100644
--- a/engines/ags/engine/ac/game_state.cpp
+++ b/engines/ags/engine/ac/game_state.cpp
@@ -242,9 +242,8 @@ PViewport GameState::CreateRoomViewport() {
PViewport viewport(new Viewport());
viewport->SetID(index);
viewport->SetRect(_mainViewport.GetRect());
- ScriptViewport *scv = new ScriptViewport(index);
_roomViewports.push_back(viewport);
- _scViewportRefs.push_back(std::make_pair<ScriptViewport*, int32_t>(scv, 0));
+ _scViewportHandles.push_back(0);
_roomViewportsSorted.push_back(viewport);
_roomViewportZOrderChanged = true;
on_roomviewport_created(index);
@@ -254,32 +253,37 @@ PViewport GameState::CreateRoomViewport() {
ScriptViewport *GameState::RegisterRoomViewport(int index, int32_t handle) {
if (index < 0 || (size_t)index >= _roomViewports.size())
return nullptr;
- auto &scobj = _scViewportRefs[index];
+ auto scview = new ScriptViewport(index);
if (handle == 0) {
- handle = ccRegisterManagedObject(scobj.first, scobj.first);
+ handle = ccRegisterManagedObject(scview, scview);
ccAddObjectReference(handle); // one reference for the GameState
} else {
- ccRegisterUnserializedObject(handle, scobj.first, scobj.first);
+ ccRegisterUnserializedObject(handle, scview, scview);
}
- scobj.second = handle;
- return scobj.first;
+ _scViewportHandles[index] = handle; // save handle for us
+ return scview;
}
void GameState::DeleteRoomViewport(int index) {
// NOTE: viewport 0 can not be deleted
if (index <= 0 || (size_t)index >= _roomViewports.size())
return;
- auto scobj = _scViewportRefs[index];
- scobj.first->Invalidate();
- ccReleaseObjectReference(scobj.second);
+ auto handle = _scViewportHandles[index];
+ auto scobj = const_cast<ScriptViewport*>((const ScriptViewport*)ccGetObjectAddressFromHandle(handle));
+ if (scobj)
+ scobj->Invalidate();
+ ccReleaseObjectReference(handle);
auto cam = _roomViewports[index]->GetCamera();
if (cam)
cam->UnlinkFromViewport(index);
_roomViewports.erase(_roomViewports.begin() + index);
- _scViewportRefs.erase(_scViewportRefs.begin() + index);
+ _scViewportHandles.erase(_scViewportHandles.begin() + index);
for (size_t i = index; i < _roomViewports.size(); ++i) {
_roomViewports[i]->SetID(i);
- _scViewportRefs[i].first->SetID(i);
+ handle = _scViewportHandles[index];
+ scobj = const_cast<ScriptViewport*>((const ScriptViewport*)ccGetObjectAddressFromHandle(handle));
+ if (scobj)
+ scobj->SetID(i);
}
for (size_t i = 0; i < _roomViewportsSorted.size(); ++i) {
if (_roomViewportsSorted[i]->GetID() == index) {
@@ -300,8 +304,7 @@ PCamera GameState::CreateRoomCamera() {
camera->SetID(index);
camera->SetAt(0, 0);
camera->SetSize(_mainViewport.GetRect().GetSize());
- ScriptCamera *scam = new ScriptCamera(index);
- _scCameraRefs.push_back(std::make_pair<ScriptCamera*, int32_t>(scam, 0));
+ _scCameraHandles.push_back(0);
_roomCameras.push_back(camera);
return camera;
}
@@ -309,34 +312,39 @@ PCamera GameState::CreateRoomCamera() {
ScriptCamera *GameState::RegisterRoomCamera(int index, int32_t handle) {
if (index < 0 || (size_t)index >= _roomCameras.size())
return nullptr;
- auto &scobj = _scCameraRefs[index];
+ auto sccamera = new ScriptCamera(index);
if (handle == 0) {
- handle = ccRegisterManagedObject(scobj.first, scobj.first);
+ handle = ccRegisterManagedObject(sccamera, sccamera);
ccAddObjectReference(handle); // one reference for the GameState
} else {
- ccRegisterUnserializedObject(handle, scobj.first, scobj.first);
+ ccRegisterUnserializedObject(handle, sccamera, sccamera);
}
- scobj.second = handle;
- return scobj.first;
+ _scCameraHandles[index] = handle;
+ return sccamera;
}
void GameState::DeleteRoomCamera(int index) {
// NOTE: camera 0 can not be deleted
if (index <= 0 || (size_t)index >= _roomCameras.size())
return;
- auto scobj = _scCameraRefs[index];
- scobj.first->Invalidate();
- ccReleaseObjectReference(scobj.second);
+ auto handle = _scCameraHandles[index];
+ auto scobj = const_cast<ScriptCamera*>((const ScriptCamera*)ccGetObjectAddressFromHandle(handle));
+ if (scobj)
+ scobj->Invalidate();
+ ccReleaseObjectReference(handle);
for (auto &viewref : _roomCameras[index]->GetLinkedViewports()) {
auto view = viewref.lock();
if (view)
view->LinkCamera(nullptr);
}
_roomCameras.erase(_roomCameras.begin() + index);
- _scCameraRefs.erase(_scCameraRefs.begin() + index);
+ _scCameraHandles.erase(_scCameraHandles.begin() + index);
for (size_t i = index; i < _roomCameras.size(); ++i) {
_roomCameras[i]->SetID(i);
- _scCameraRefs[i].first->SetID(i);
+ handle = _scCameraHandles[index];
+ scobj = const_cast<ScriptCamera*>((const ScriptCamera*)ccGetObjectAddressFromHandle(handle));
+ if (scobj)
+ scobj->SetID(i);
}
}
@@ -347,13 +355,13 @@ int GameState::GetRoomCameraCount() const {
ScriptViewport *GameState::GetScriptViewport(int index) {
if (index < 0 || (size_t)index >= _roomViewports.size())
return nullptr;
- return _scViewportRefs[index].first;
+ return const_cast<ScriptViewport*>((const ScriptViewport*)ccGetObjectAddressFromHandle(_scViewportHandles[index]));
}
ScriptCamera *GameState::GetScriptCamera(int index) {
if (index < 0 || (size_t)index >= _roomCameras.size())
return nullptr;
- return _scCameraRefs[index].first;
+ return const_cast<ScriptCamera*>((const ScriptCamera*)ccGetObjectAddressFromHandle(_scCameraHandles[index]));
}
bool GameState::IsIgnoringInput() const {
@@ -818,17 +826,21 @@ void GameState::FreeProperties() {
void GameState::FreeViewportsAndCameras() {
_roomViewports.clear();
_roomViewportsSorted.clear();
- for (auto &scobj : _scViewportRefs) {
- scobj.first->Invalidate();
- ccReleaseObjectReference(scobj.second);
+ for (auto handle : _scViewportHandles) {
+ auto scview = const_cast<ScriptViewport*>((const ScriptViewport*)ccGetObjectAddressFromHandle(handle));
+ if (scview)
+ scview->Invalidate();
+ ccReleaseObjectReference(handle);
}
- _scViewportRefs.clear();
+ _scViewportHandles.clear();
_roomCameras.clear();
- for (auto &scobj : _scCameraRefs) {
- scobj.first->Invalidate();
- ccReleaseObjectReference(scobj.second);
+ for (auto handle : _scCameraHandles) {
+ auto sccam = const_cast<ScriptCamera*>((const ScriptCamera*)ccGetObjectAddressFromHandle(handle));
+ if (sccam)
+ sccam->Invalidate();
+ ccReleaseObjectReference(handle);
}
- _scCameraRefs.clear();
+ _scCameraHandles.clear();
}
void GameState::ReadCustomProperties_v340(Shared::Stream *in) {
diff --git a/engines/ags/engine/ac/game_state.h b/engines/ags/engine/ac/game_state.h
index cddf8991b65..f8db2536781 100644
--- a/engines/ags/engine/ac/game_state.h
+++ b/engines/ags/engine/ac/game_state.h
@@ -404,11 +404,10 @@ private:
std::vector<PViewport> _roomViewportsSorted;
// Cameras defines the position of a "looking eye" inside the room.
std::vector<PCamera> _roomCameras;
- // Script viewports and cameras are references to real data export to
- // user script. They became invalidated as the actual object gets
- // destroyed, but are kept in memory to prevent script errors.
- std::vector<std::pair<ScriptViewport *, int32_t>> _scViewportRefs;
- std::vector<std::pair<ScriptCamera *, int32_t>> _scCameraRefs;
+ // We keep handles to the script refs to viewports and cameras, so that we
+ // could address them and invalidate as the actual object gets destroyed.
+ std::vector<int32_t> _scViewportHandles;
+ std::vector<int32_t> _scCameraHandles;
// Tells that the main viewport's position has changed since last game update
bool _mainViewportHasChanged = false;
Commit: 6cfb6dbef8e2fd6b8653492cd95e29ce73552ce1
https://github.com/scummvm/scummvm/commit/6cfb6dbef8e2fd6b8653492cd95e29ce73552ce1
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-19T20:55:24+01:00
Commit Message:
AGS: Store certain overlay handles, not script ptrs, for safety
>From upstream b73553d6b4655feec2f82ee1feaa67a6bc9fca23
Changed paths:
engines/ags/engine/ac/game_state.cpp
engines/ags/engine/ac/game_state.h
engines/ags/engine/ac/overlay.cpp
engines/ags/engine/ac/speech.cpp
diff --git a/engines/ags/engine/ac/game_state.cpp b/engines/ags/engine/ac/game_state.cpp
index f55a403acb8..7f3e3a27cb9 100644
--- a/engines/ags/engine/ac/game_state.cpp
+++ b/engines/ags/engine/ac/game_state.cpp
@@ -270,9 +270,10 @@ void GameState::DeleteRoomViewport(int index) {
return;
auto handle = _scViewportHandles[index];
auto scobj = const_cast<ScriptViewport*>((const ScriptViewport*)ccGetObjectAddressFromHandle(handle));
- if (scobj)
+ if (scobj) {
scobj->Invalidate();
- ccReleaseObjectReference(handle);
+ ccReleaseObjectReference(handle);
+ }
auto cam = _roomViewports[index]->GetCamera();
if (cam)
cam->UnlinkFromViewport(index);
@@ -329,9 +330,10 @@ void GameState::DeleteRoomCamera(int index) {
return;
auto handle = _scCameraHandles[index];
auto scobj = const_cast<ScriptCamera*>((const ScriptCamera*)ccGetObjectAddressFromHandle(handle));
- if (scobj)
+ if (scobj) {
scobj->Invalidate();
- ccReleaseObjectReference(handle);
+ ccReleaseObjectReference(handle);
+ }
for (auto &viewref : _roomCameras[index]->GetLinkedViewports()) {
auto view = viewref.lock();
if (view)
@@ -828,17 +830,19 @@ void GameState::FreeViewportsAndCameras() {
_roomViewportsSorted.clear();
for (auto handle : _scViewportHandles) {
auto scview = const_cast<ScriptViewport*>((const ScriptViewport*)ccGetObjectAddressFromHandle(handle));
- if (scview)
+ if (scview) {
scview->Invalidate();
- ccReleaseObjectReference(handle);
+ ccReleaseObjectReference(handle);
+ }
}
_scViewportHandles.clear();
_roomCameras.clear();
for (auto handle : _scCameraHandles) {
auto sccam = const_cast<ScriptCamera*>((const ScriptCamera*)ccGetObjectAddressFromHandle(handle));
- if (sccam)
+ if (sccam) {
sccam->Invalidate();
- ccReleaseObjectReference(handle);
+ ccReleaseObjectReference(handle);
+ }
}
_scCameraHandles.clear();
}
diff --git a/engines/ags/engine/ac/game_state.h b/engines/ags/engine/ac/game_state.h
index f8db2536781..1cefd30ef6d 100644
--- a/engines/ags/engine/ac/game_state.h
+++ b/engines/ags/engine/ac/game_state.h
@@ -254,12 +254,12 @@ struct GameState {
int complete_overlay_on = 0;
// Is there a blocking text overlay on screen (contains overlay ID)
int text_overlay_on = 0;
- // Script overlay objects, because we must return same pointers
+ // Script overlay handles, because we must return same script objects
// whenever user script queries for them.
- // Blocking speech overlay managed object, for accessing in scripts
- ScriptOverlay *speech_text_scover = nullptr;
- // Speech portrait overlay managed object
- ScriptOverlay *speech_face_scover = nullptr;
+ // Blocking speech overlay managed handle
+ int speech_text_schandle = 0;
+ // Speech portrait overlay managed handle
+ int speech_face_schandle = 0;
int shake_screen_yoff = 0; // y offset of the shaking screen
diff --git a/engines/ags/engine/ac/overlay.cpp b/engines/ags/engine/ac/overlay.cpp
index 6c98bbddaa4..8911b7eca1d 100644
--- a/engines/ags/engine/ac/overlay.cpp
+++ b/engines/ags/engine/ac/overlay.cpp
@@ -279,27 +279,24 @@ ScriptOverlay *create_scriptoverlay(ScreenOverlay &over, bool internal_ref) {
ScriptOverlay *scover = new ScriptOverlay();
scover->overlayId = over.type;
int handl = ccRegisterManagedObject(scover, scover);
- over.associatedOverlayHandle = handl;
- if (internal_ref)
+ over.associatedOverlayHandle = handl; // save the handle for access
+ if (internal_ref) // requested additional ref
ccAddObjectReference(handl);
return scover;
}
// Invalidates existing script object to let user know that previous overlay is gone,
// and releases engine's internal reference (script object may exist while there are user refs)
-static void invalidate_and_subref(ScreenOverlay &over, ScriptOverlay **scover) {
- if (scover && (*scover)) {
- (*scover)->overlayId = -1;
- *scover = nullptr;
- } else if (over.associatedOverlayHandle > 0) {
- ScriptOverlay *scoverlay = const_cast<ScriptOverlay*>((const ScriptOverlay* )ccGetObjectAddressFromHandle(over.associatedOverlayHandle));
- if (scoverlay) scoverlay->overlayId = -1;
- }
+static void invalidate_and_subref(ScreenOverlay &over) {
+ if (over.associatedOverlayHandle <= 0)
+ return; // invalid handle
- if (over.associatedOverlayHandle > 0) {
+ ScriptOverlay *scover = const_cast<ScriptOverlay*>((const ScriptOverlay*)ccGetObjectAddressFromHandle(over.associatedOverlayHandle));
+ if (scover) {
+ scover->overlayId = -1; // invalidate script object
ccReleaseObjectReference(over.associatedOverlayHandle);
- over.associatedOverlayHandle = 0;
}
+ over.associatedOverlayHandle = 0; // reset internal handle
}
// Frees overlay resources and tell to dispose script object if there are no refs left
@@ -325,13 +322,15 @@ void remove_screen_overlay_index(size_t over_idx) {
if (over.type == _GP(play).complete_overlay_on) {
_GP(play).complete_overlay_on = 0;
} else if (over.type == _GP(play).text_overlay_on) { // release internal ref for speech text
- invalidate_and_subref(over, &_GP(play).speech_text_scover);
+ invalidate_and_subref(over);
+ _GP(play).speech_text_schandle = 0;
_GP(play).text_overlay_on = 0;
} else if (over.type == OVER_PICTURE) { // release internal ref for speech face
- invalidate_and_subref(over, &_GP(play).speech_face_scover);
+ invalidate_and_subref(over);
+ _GP(play).speech_face_schandle = 0;
_G(face_talking) = -1;
} else if (over.bgSpeechForChar >= 0) { // release internal ref for bg speech
- invalidate_and_subref(over, nullptr);
+ invalidate_and_subref(over);
}
dispose_overlay(over);
_GP(screenover).erase(_GP(screenover).begin() + over_idx);
@@ -393,10 +392,13 @@ size_t add_screen_overlay_impl(bool roomlayer, int x, int y, int type, int sprnu
_GP(play).text_overlay_on = type;
// only make script object for blocking speech now, because messagebox blocks all script
// and therefore cannot be accessed, so no practical reason for that atm
- if (type == OVER_TEXTSPEECH)
- _GP(play).speech_text_scover = create_scriptoverlay(over, true);
+ if (type == OVER_TEXTSPEECH) {
+ create_scriptoverlay(over, true);
+ _GP(play).speech_text_schandle = over.associatedOverlayHandle;
+ }
} else if (type == OVER_PICTURE) {
- _GP(play).speech_face_scover = create_scriptoverlay(over, true);
+ create_scriptoverlay(over, true);
+ _GP(play).speech_face_schandle = over.associatedOverlayHandle;
}
over.MarkChanged();
_GP(screenover).push_back(std::move(over));
diff --git a/engines/ags/engine/ac/speech.cpp b/engines/ags/engine/ac/speech.cpp
index 17efec2e829..b6f2167b53b 100644
--- a/engines/ags/engine/ac/speech.cpp
+++ b/engines/ags/engine/ac/speech.cpp
@@ -28,6 +28,7 @@
#include "ags/engine/ac/game_state.h"
#include "ags/engine/ac/global_audio.h"
#include "ags/engine/ac/global_display.h"
+#include "ags/engine/ac/dynobj/cc_dynamic_object.h"
#include "ags/shared/debugging/out.h"
#include "ags/engine/script/script_api.h"
#include "ags/engine/script/script_runtime.h"
@@ -149,11 +150,11 @@ String get_voice_assetpath() {
//=============================================================================
ScriptOverlay *Speech_GetTextOverlay() {
- return _GP(play).speech_text_scover;
+ return const_cast<ScriptOverlay*>((const ScriptOverlay*)ccGetObjectAddressFromHandle(_GP(play).speech_text_schandle));
}
ScriptOverlay *Speech_GetPortraitOverlay() {
- return _GP(play).speech_face_scover;
+ return const_cast<ScriptOverlay*>((const ScriptOverlay*)ccGetObjectAddressFromHandle(_GP(play).speech_face_schandle));
}
RuntimeScriptValue Sc_Speech_GetAnimationStopTimeMargin(const RuntimeScriptValue *params, int32_t param_count) {
More information about the Scummvm-git-logs
mailing list