[Scummvm-git-logs] scummvm master -> 08db4be24cd87829d3ddc2be1286fb922b44d589
criezy
noreply at scummvm.org
Thu Jun 23 23:00:31 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:
305fdb853a AGS: Abort current scripts on close window event
8b8a7fffbf AGS: Tidied code around GameSetup a tiny bit
dd9df96e74 AGS: Tidied code around debugger init a tiny bit, added log
3a4d94bf0b AGS: Updated Multitasking setting
29505204c1 AGS: Turned want_exit and abort_engine vars from int to bool
40c85968e1 AGS: Fixed restoring a exclusive fullscreen mode on switch in
aa9983c28d AGS: Update commented out exception handling code
6f665dfe68 AGS: Test for hanging script using timeout instead of while loops
7372aa4040 AGS: Updated build version (3.6.0.28)
08db4be24c AGS: As a hotfix, restored the old way to test for hung script loops
Commit: 305fdb853a6a99d28851c8bb8c492f9b1147fbbe
https://github.com/scummvm/scummvm/commit/305fdb853a6a99d28851c8bb8c492f9b1147fbbe
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-23T23:57:26+01:00
Commit Message:
AGS: Abort current scripts on close window event
This helps kill "hanging" scripts if user closed the window while
there's no real engine update.
>From upstream a758fd6de2dccd0c948fc7f9e5b65200df902a65
Changed paths:
engines/ags/engine/ac/global_game.cpp
engines/ags/engine/ac/global_game.h
engines/ags/engine/main/engine.cpp
engines/ags/engine/script/cc_instance.cpp
engines/ags/engine/script/script.cpp
diff --git a/engines/ags/engine/ac/global_game.cpp b/engines/ags/engine/ac/global_game.cpp
index f75a0651f73..251b1536f14 100644
--- a/engines/ags/engine/ac/global_game.cpp
+++ b/engines/ags/engine/ac/global_game.cpp
@@ -77,6 +77,11 @@ namespace AGS3 {
using namespace AGS::Shared;
+void AbortGame() {
+ // make sure scripts stop at the next step
+ cancel_all_scripts();
+}
+
void GiveScore(int amnt) {
GUI::MarkSpecialLabelsForUpdate(kLabelMacro_AllScore);
_GP(play).score += amnt;
diff --git a/engines/ags/engine/ac/global_game.h b/engines/ags/engine/ac/global_game.h
index 5da6fa48827..3fb06debd3b 100644
--- a/engines/ags/engine/ac/global_game.h
+++ b/engines/ags/engine/ac/global_game.h
@@ -43,7 +43,8 @@ struct SaveListItem {
}
};
-
+// Notify the running game that the engine requested immediate stop
+void AbortGame();
void GiveScore(int amnt);
void restart_game();
void RestoreGameSlot(int slnum);
diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp
index f6afcf00cd1..e758d2d4491 100644
--- a/engines/ags/engine/main/engine.cpp
+++ b/engines/ags/engine/main/engine.cpp
@@ -107,6 +107,7 @@ void winclosehook() {
_G(want_exit) = 1;
_G(abort_engine) = 1;
_G(check_dynamic_sprites_at_exit) = 0;
+ AbortGame();
}
void engine_setup_window() {
diff --git a/engines/ags/engine/script/cc_instance.cpp b/engines/ags/engine/script/cc_instance.cpp
index d2a08dc877a..dba0966ea19 100644
--- a/engines/ags/engine/script/cc_instance.cpp
+++ b/engines/ags/engine/script/cc_instance.cpp
@@ -444,7 +444,7 @@ int ccInstance::Run(int32_t curpc) {
FunctionCallStack func_callstack;
- while (1) {
+ while ((flags & INSTF_ABORTED) == 0) {
if (_G(abort_engine))
return -1;
@@ -970,9 +970,6 @@ int ccInstance::Run(int32_t curpc) {
runningInst = wasRunning;
- if (flags & INSTF_ABORTED)
- return 0;
-
if (oldstack != registers[SREG_SP]) {
cc_error("stack corrupt after function call");
return -1;
@@ -1219,11 +1216,9 @@ int ccInstance::Run(int32_t curpc) {
return -1;
}
- if (flags & INSTF_ABORTED)
- return 0;
-
pc += codeOp.ArgCount + 1;
}
+ return 0;
}
String ccInstance::GetCallStack(int maxLines) const {
diff --git a/engines/ags/engine/script/script.cpp b/engines/ags/engine/script/script.cpp
index 56161a4d6f4..7fe41a74acb 100644
--- a/engines/ags/engine/script/script.cpp
+++ b/engines/ags/engine/script/script.cpp
@@ -251,9 +251,7 @@ int create_global_script() {
}
void cancel_all_scripts() {
- int aa;
-
- for (aa = 0; aa < _G(num_scripts); aa++) {
+ for (int aa = 0; aa < _G(num_scripts); aa++) {
if (_G(scripts)[aa].forked)
_G(scripts)[aa].inst->AbortAndDestroy();
else
@@ -261,8 +259,10 @@ void cancel_all_scripts() {
_G(scripts)[aa].numanother = 0;
}
_G(num_scripts) = 0;
- /* if (_G(gameinst)!=NULL) ->Abort(_G(gameinst));
- if (_G(roominst)!=NULL) ->Abort(_G(roominst));*/
+ // in case the script is running on non-blocking thread (rep-exec-always etc)
+ auto inst = ccInstance::GetCurrentInstance();
+ if (inst)
+ inst->Abort();
}
ccInstance *GetScriptInstanceByType(ScriptInstType sc_inst) {
@@ -481,10 +481,14 @@ void post_script_cleanup() {
// should do any post-script stuff here, like go to new room
if (cc_has_error())
quit(cc_get_error().ErrorString);
- ExecutingScript copyof = _G(scripts)[_G(num_scripts) - 1];
- if (_G(scripts)[_G(num_scripts) - 1].forked)
- delete _G(scripts)[_G(num_scripts) - 1].inst;
- _G(num_scripts)--;
+
+ ExecutingScript copyof;
+ if (_G(num_scripts) > 0) {
+ copyof = _G(scripts)[_G(num_scripts) - 1];
+ if (_G(scripts)[_G(num_scripts) - 1].forked)
+ delete _G(scripts)[_G(num_scripts) - 1].inst;
+ _G(num_scripts)--;
+ }
_G(inside_script)--;
if (_G(num_scripts) > 0)
@@ -548,8 +552,7 @@ void post_script_cleanup() {
}
- int jj;
- for (jj = 0; jj < copyof.numanother; jj++) {
+ for (int jj = 0; jj < copyof.numanother; jj++) {
old_room_number = _G(displayed_room);
QueuedScript &script = copyof.ScFnQueue[jj];
RunScriptFunctionAuto(script.Instance, script.FnName.GetCStr(), script.ParamCount, script.Params);
Commit: 8b8a7fffbf2743ac57db7af2879c888aeff14d4f
https://github.com/scummvm/scummvm/commit/8b8a7fffbf2743ac57db7af2879c888aeff14d4f
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-23T23:57:26+01:00
Commit Message:
AGS: Tidied code around GameSetup a tiny bit
>From upstream 850ae917fe7477dd83cc905cdb48982ef107877c
Changed paths:
engines/ags/engine/ac/game_setup.h
engines/ags/engine/main/config.cpp
diff --git a/engines/ags/engine/ac/game_setup.h b/engines/ags/engine/ac/game_setup.h
index 4eefbf3bef9..a54d7547106 100644
--- a/engines/ags/engine/ac/game_setup.h
+++ b/engines/ags/engine/ac/game_setup.h
@@ -52,13 +52,11 @@ enum ScreenRotation {
using AGS::Shared::String;
-// TODO: reconsider the purpose of this struct.
-// Earlier I was trying to remove the uses of this struct from the engine
-// and restrict it to only config/init stage, while applying its values to
-// respective game/engine subcomponents at init stage.
-// However, it did not work well at all times, and consequently I thought
-// that engine may use a "config" object or combo of objects to store
-// current user config, which may also be changed from script, and saved.
+// TODO: reconsider the purpose of this struct in the future.
+ // Currently it's been used as both initial storage for config options
+ // before they are used to initialize engine, and as persistent storage
+ // for options that may be changed at runtime (and later written back
+ // to the config file).
struct GameSetup {
bool audio_enabled;
String audio_driver;
@@ -83,9 +81,6 @@ struct GameSetup {
String shared_data_dir; // directory to write shared game files to
String translation;
bool mouse_auto_lock;
- int override_script_os;
- int8_t override_multitasking;
- bool override_upscale;
float mouse_speed;
MouseControlWhen mouse_ctrl_when;
bool mouse_ctrl_enabled;
@@ -101,6 +96,11 @@ struct GameSetup {
DisplayModeSetup Screen;
String software_render_driver;
+ // User's overrides and hacks
+ int override_script_os; // pretend engine is running on this eScriptSystemOSID
+ char override_multitasking; // -1 for none, 0 or 1 to lock in the on/off mode
+ bool override_upscale; // whether upscale old games that supported that
+
// Optional keys for calling built-in save/restore dialogs;
// primarily meant for the test runs of the games where save functionality
// is not implemented (or does not work correctly).
diff --git a/engines/ags/engine/main/config.cpp b/engines/ags/engine/main/config.cpp
index fb525be80ce..70e7e5f733d 100644
--- a/engines/ags/engine/main/config.cpp
+++ b/engines/ags/engine/main/config.cpp
@@ -267,15 +267,18 @@ void override_config_ext(ConfigTree &cfg) {
}
void apply_config(const ConfigTree &cfg) {
+ // Legacy graphics settings has to be translated into new options;
+ // they must be read first, to let newer options override them, if ones are present
+ read_legacy_graphics_config(cfg);
+
{
+ // Audio options
_GP(usetup).audio_enabled = CfgReadBoolInt(cfg, "sound", "enabled", _GP(usetup).audio_enabled);
_GP(usetup).audio_driver = CfgReadString(cfg, "sound", "driver");
+ // This option is backwards (usevox is 0 if no_speech_pack)
+ _GP(usetup).no_speech_pack = !CfgReadBoolInt(cfg, "sound", "usespeech", true);
- // Legacy graphics settings has to be translated into new options;
- // they must be read first, to let newer options override them, if ones are present
- read_legacy_graphics_config(cfg);
-
- // Graphics mode
+ // Graphics mode and options
_GP(usetup).Screen.DriverID = CfgReadString(cfg, "graphics", "driver", _GP(usetup).Screen.DriverID);
_GP(usetup).Screen.Windowed = CfgReadBoolInt(cfg, "graphics", "windowed", _GP(usetup).Screen.Windowed);
_GP(usetup).Screen.FsSetup =
@@ -283,16 +286,11 @@ void apply_config(const ConfigTree &cfg) {
_GP(usetup).Screen.WinSetup =
parse_window_mode(CfgReadString(cfg, "graphics", "window", "default"), true, _GP(usetup).Screen.WinSetup);
- // TODO: move to config overrides (replace values during config load)
-#if AGS_PLATFORM_OS_MACOS
- _GP(usetup).Screen.Filter.ID = "none";
-#else
_GP(usetup).Screen.Filter.ID = CfgReadString(cfg, "graphics", "filter", "StdScale");
_GP(usetup).Screen.FsGameFrame =
parse_scaling_option(CfgReadString(cfg, "graphics", "game_scale_fs", "proportional"), _GP(usetup).Screen.FsGameFrame);
_GP(usetup).Screen.WinGameFrame =
parse_scaling_option(CfgReadString(cfg, "graphics", "game_scale_win", "round"), _GP(usetup).Screen.WinGameFrame);
-#endif
_GP(usetup).Screen.Params.RefreshRate = CfgReadInt(cfg, "graphics", "refresh");
_GP(usetup).Screen.Params.VSync = CfgReadBoolInt(cfg, "graphics", "vsync");
@@ -309,27 +307,27 @@ void apply_config(const ConfigTree &cfg) {
#endif
_GP(usetup).enable_antialiasing = CfgReadBoolInt(cfg, "misc", "antialias");
- // This option is backwards (usevox is 0 if no_speech_pack)
- _GP(usetup).no_speech_pack = !CfgReadBoolInt(cfg, "sound", "usespeech", true);
-
- _GP(usetup).clear_cache_on_room_change = CfgReadBoolInt(cfg, "misc", "clear_cache_on_room_change", _GP(usetup).clear_cache_on_room_change);
+ // Custom paths
_GP(usetup).load_latest_save = CfgReadBoolInt(cfg, "misc", "load_latest_save", _GP(usetup).load_latest_save);
_GP(usetup).user_data_dir = CfgReadString(cfg, "misc", "user_data_dir");
_GP(usetup).shared_data_dir = CfgReadString(cfg, "misc", "shared_data_dir");
_GP(usetup).show_fps = CfgReadBoolInt(cfg, "misc", "show_fps");
+ // Translation / localization
Common::String translation;
if (ConfMan.getActiveDomain()->tryGetVal("translation", translation) && !translation.empty())
_GP(usetup).translation = translation;
else
_GP(usetup).translation = CfgReadString(cfg, "language", "translation");
+ // Resource caches and options
+ _GP(usetup).clear_cache_on_room_change = CfgReadBoolInt(cfg, "misc", "clear_cache_on_room_change", _GP(usetup).clear_cache_on_room_change);
int cache_size_kb = CfgReadInt(cfg, "misc", "cachemax", DEFAULTCACHESIZE_KB);
if (cache_size_kb > 0)
_GP(usetup).SpriteCacheSize = cache_size_kb * 1024;
+ // Mouse options
_GP(usetup).mouse_auto_lock = CfgReadBoolInt(cfg, "mouse", "auto_lock");
-
_GP(usetup).mouse_speed = CfgReadFloat(cfg, "mouse", "speed", 1.f);
if (_GP(usetup).mouse_speed <= 0.f)
_GP(usetup).mouse_speed = 1.f;
@@ -351,6 +349,7 @@ void apply_config(const ConfigTree &cfg) {
}
}
+ // User's overrides and hacks
_GP(usetup).override_multitasking = CfgReadInt(cfg, "override", "multitasking", -1);
String override_os = CfgReadString(cfg, "override", "os");
_GP(usetup).override_script_os = -1;
Commit: dd9df96e74be672afc8e7b5ba6b63b34d2088e5a
https://github.com/scummvm/scummvm/commit/dd9df96e74be672afc8e7b5ba6b63b34d2088e5a
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-23T23:57:26+01:00
Commit Message:
AGS: Tidied code around debugger init a tiny bit, added log
>From upstream 408f139d86b5d812fe3674901cadae6ae6573036
Changed paths:
engines/ags/engine/debugging/debug.cpp
engines/ags/engine/main/game_start.cpp
diff --git a/engines/ags/engine/debugging/debug.cpp b/engines/ags/engine/debugging/debug.cpp
index 200812bd2b0..3fe977138ea 100644
--- a/engines/ags/engine/debugging/debug.cpp
+++ b/engines/ags/engine/debugging/debug.cpp
@@ -360,9 +360,11 @@ bool init_editor_debugging() {
}
send_message_to_editor("START");
+ Debug::Printf(kDbgMsg_Info, "External debugger initialized");
return true;
}
+ Debug::Printf(kDbgMsg_Error, "Failed to initialize external debugger");
return false;
}
diff --git a/engines/ags/engine/main/game_start.cpp b/engines/ags/engine/main/game_start.cpp
index a5872459a2d..571abb28c48 100644
--- a/engines/ags/engine/main/game_start.cpp
+++ b/engines/ags/engine/main/game_start.cpp
@@ -27,6 +27,7 @@
#include "ags/shared/ac/character_info.h"
#include "ags/engine/ac/game.h"
#include "ags/shared/ac/game_setup_struct.h"
+#include "ags/engine/ac/game_setup.h"
#include "ags/engine/ac/game_state.h"
#include "ags/engine/ac/global_game.h"
#include "ags/engine/ac/mouse.h"
@@ -51,18 +52,21 @@ using namespace AGS::Shared;
using namespace AGS::Engine;
void start_game_init_editor_debugging() {
- if (_G(editor_debugging_enabled)) {
- SetMultitasking(1);
- if (init_editor_debugging()) {
- auto waitUntil = AGS_Clock::now() + std::chrono::milliseconds(500);
- while (waitUntil > AGS_Clock::now()) {
- // pick up any breakpoints in game_start
- check_for_messages_from_editor();
- }
-
- ccSetDebugHook(scriptDebugHook);
- }
+ Debug::Printf(kDbgMsg_Info, "Try connect to the external debugger");
+ if (!init_editor_debugging())
+ return;
+
+ // Debugger expects strict multitasking
+ _GP(usetup).override_multitasking = -1;
+ SetMultitasking(1);
+
+ auto waitUntil = AGS_Clock::now() + std::chrono::milliseconds(500);
+ while (waitUntil > AGS_Clock::now()) {
+ // pick up any breakpoints in game_start
+ check_for_messages_from_editor();
}
+
+ ccSetDebugHook(scriptDebugHook);
}
static void start_game_load_savegame_on_startup(int loadSave) {
@@ -111,7 +115,8 @@ void initialize_start_and_play_game(int override_start_room, int loadSave) {
Debug::Printf(kDbgMsg_Info, "Engine initialization complete");
Debug::Printf(kDbgMsg_Info, "Starting game");
- start_game_init_editor_debugging();
+ if (_G(editor_debugging_enabled))
+ start_game_init_editor_debugging();
start_game_load_savegame_on_startup(loadSave);
Commit: 3a4d94bf0bb7ff6a538a6e4c3f03701c7951b655
https://github.com/scummvm/scummvm/commit/3a4d94bf0bb7ff6a538a6e4c3f03701c7951b655
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-23T23:57:27+01:00
Commit Message:
AGS: Updated Multitasking setting
* Added `[misc] multitasking=[0,1]` to config, acting as a *starting*
setting, which may be changed by runtime call to `SetMultitaskingMode`;
* Ensure multitasking mode is overridden by connected external debugger
(always on, if possible);
* Let multitasking mode work in "fullscreen desktop" gfx mode (still
disabled in exclusive fullscreen);
* Now correctly reset multitasking mode if gfx mode changes.
>From upstream 9f091926e393f75c90c951f9597710bf17395332
Changed paths:
engines/ags/engine/ac/game.cpp
engines/ags/engine/ac/game_setup.h
engines/ags/engine/ac/global_game.cpp
engines/ags/engine/main/config.cpp
engines/ags/engine/main/engine.cpp
engines/ags/engine/main/engine_setup.cpp
engines/ags/engine/main/game_start.cpp
engines/ags/engine/main/graphics_mode.cpp
diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp
index adee37d2a81..d175a1b5a69 100644
--- a/engines/ags/engine/ac/game.cpp
+++ b/engines/ags/engine/ac/game.cpp
@@ -1219,9 +1219,6 @@ void display_switch_out_suspend() {
}
}
- // restore the callbacks
- SetMultitasking(0);
-
_G(switching_away_from_game)--;
}
diff --git a/engines/ags/engine/ac/game_setup.h b/engines/ags/engine/ac/game_setup.h
index a54d7547106..e772ae06667 100644
--- a/engines/ags/engine/ac/game_setup.h
+++ b/engines/ags/engine/ac/game_setup.h
@@ -92,6 +92,7 @@ struct GameSetup {
bool load_latest_save; // load latest saved game on launch
ScreenRotation rotation;
bool show_fps;
+ bool multitasking = false; // whether run on background, when game is switched out
DisplayModeSetup Screen;
String software_render_driver;
diff --git a/engines/ags/engine/ac/global_game.cpp b/engines/ags/engine/ac/global_game.cpp
index 251b1536f14..c557edf4ab7 100644
--- a/engines/ags/engine/ac/global_game.cpp
+++ b/engines/ags/engine/ac/global_game.cpp
@@ -643,19 +643,26 @@ void SetMultitasking(int mode) {
if ((mode < 0) | (mode > 1))
quit("!SetMultitasking: invalid mode parameter");
- if (_GP(usetup).override_multitasking >= 0) {
+ // Account for the override config option (must be checked first!)
+ if ((_GP(usetup).override_multitasking >= 0) && (mode != _GP(usetup).override_multitasking)) {
Debug::Printf("SetMultitasking: overridden by user config: %d -> %d", mode, _GP(usetup).override_multitasking);
mode = _GP(usetup).override_multitasking;
}
- // Don't allow background running if full screen
- if ((mode == 1) && (!_GP(scsystem).windowed)) {
- Debug::Printf("SetMultitasking: overridden by fullscreen: %d -> %d", mode, 0);
+ // Must run on background if debugger is connected
+ if ((mode == 0) && (_G(editor_debugging_initialized) != 0)) {
+ Debug::Printf("SetMultitasking: overridden by the external debugger: %d -> 1", mode);
+ mode = 1;
+ }
+
+ // Regardless, don't allow background running if exclusive full screen
+ if ((mode == 1) && _G(gfxDriver)->GetDisplayMode().IsRealFullscreen()) {
+ Debug::Printf("SetMultitasking: overridden by fullscreen: %d -> 0", mode);
mode = 0;
}
// Install engine callbacks for switching in and out the window
- Debug::Printf("SetMultitasking: mode %d", mode);
+ Debug::Printf(kDbgMsg_Info, "Multitasking mode set: %d", mode);
if (mode == 0) {
sys_set_background_mode(false);
sys_evt_set_focus_callbacks(display_switch_in_resume, display_switch_out_suspend);
diff --git a/engines/ags/engine/main/config.cpp b/engines/ags/engine/main/config.cpp
index 70e7e5f733d..9e3ad21d84e 100644
--- a/engines/ags/engine/main/config.cpp
+++ b/engines/ags/engine/main/config.cpp
@@ -349,6 +349,9 @@ void apply_config(const ConfigTree &cfg) {
}
}
+ // Various system options
+ _GP(usetup).multitasking = CfgReadInt(cfg, "misc", "multitasking", 0) != 0;
+
// User's overrides and hacks
_GP(usetup).override_multitasking = CfgReadInt(cfg, "override", "multitasking", -1);
String override_os = CfgReadString(cfg, "override", "os");
diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp
index e758d2d4491..d01a069fab1 100644
--- a/engines/ags/engine/main/engine.cpp
+++ b/engines/ags/engine/main/engine.cpp
@@ -1176,7 +1176,7 @@ int initialize_engine(const ConfigTree &startup_opts) {
// Configure game window after renderer was initialized
engine_setup_window();
- SetMultitasking(0);
+ SetMultitasking(_GP(usetup).multitasking);
sys_window_show_cursor(false); // hide the system cursor
diff --git a/engines/ags/engine/main/engine_setup.cpp b/engines/ags/engine/main/engine_setup.cpp
index 12542f3e73b..c02f19e9481 100644
--- a/engines/ags/engine/main/engine_setup.cpp
+++ b/engines/ags/engine/main/engine_setup.cpp
@@ -27,6 +27,7 @@
#include "ags/engine/ac/game_setup.h"
#include "ags/shared/ac/game_setup_struct.h"
#include "ags/engine/ac/game_state.h"
+#include "ags/engine/ac/global_game.h"
#include "ags/engine/ac/mouse.h"
#include "ags/engine/ac/runtime_defines.h"
#include "ags/engine/ac/walk_behind.h"
@@ -270,6 +271,9 @@ void engine_post_gfxmode_setup(const Size &init_desktop) {
}
engine_post_gfxmode_mouse_setup(init_desktop);
+ // reset multitasking (may be overridden by the current display mode)
+ SetMultitasking(_GP(usetup).multitasking);
+
invalidate_screen();
}
diff --git a/engines/ags/engine/main/game_start.cpp b/engines/ags/engine/main/game_start.cpp
index 571abb28c48..ec904a1a986 100644
--- a/engines/ags/engine/main/game_start.cpp
+++ b/engines/ags/engine/main/game_start.cpp
@@ -26,6 +26,7 @@
#include "ags/shared/ac/common.h"
#include "ags/shared/ac/character_info.h"
#include "ags/engine/ac/game.h"
+#include "ags/engine/ac/game_setup.h"
#include "ags/shared/ac/game_setup_struct.h"
#include "ags/engine/ac/game_setup.h"
#include "ags/engine/ac/game_state.h"
@@ -57,6 +58,7 @@ void start_game_init_editor_debugging() {
return;
// Debugger expects strict multitasking
+ _GP(usetup).multitasking = true;
_GP(usetup).override_multitasking = -1;
SetMultitasking(1);
diff --git a/engines/ags/engine/main/graphics_mode.cpp b/engines/ags/engine/main/graphics_mode.cpp
index 98adb998923..e9d68418e10 100644
--- a/engines/ags/engine/main/graphics_mode.cpp
+++ b/engines/ags/engine/main/graphics_mode.cpp
@@ -473,8 +473,9 @@ bool graphics_mode_set_dm(const DisplayMode &dm) {
_GP(SavedWindowedSetting).Dm = rdm;
else
_GP(SavedFullscreenSetting).Dm = rdm;
- Debug::Printf("Succeeded. Using gfx mode %d x %d (%d-bit) %s",
- rdm.Width, rdm.Height, rdm.ColorDepth, rdm.IsWindowed() ? "windowed" : "fullscreen");
+ Debug::Printf(kDbgMsg_Info, "Graphics mode set: %d x %d (%d-bit) %s",
+ rdm.Width, rdm.Height, rdm.ColorDepth,
+ rdm.IsWindowed() ? "windowed" : (rdm.IsRealFullscreen() ? "fullscreen" : "fullscreen desktop"));
return true;
}
Commit: 29505204c1bd4b1073d85d3b8189be081c43465b
https://github.com/scummvm/scummvm/commit/29505204c1bd4b1073d85d3b8189be081c43465b
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-23T23:57:27+01:00
Commit Message:
AGS: Turned want_exit and abort_engine vars from int to bool
>From upstream e924778ce3f88a4c821a4eecfea8edc353a6807b
In ScummVM they were already bools, but where still assigned values
of 0 and 1 instead of false and true in some places.
Changed paths:
engines/ags/engine/debugging/debug.cpp
engines/ags/engine/main/engine.cpp
engines/ags/engine/main/game_run.cpp
diff --git a/engines/ags/engine/debugging/debug.cpp b/engines/ags/engine/debugging/debug.cpp
index 3fe977138ea..11a0237df43 100644
--- a/engines/ags/engine/debugging/debug.cpp
+++ b/engines/ags/engine/debugging/debug.cpp
@@ -430,8 +430,8 @@ int check_for_messages_from_editor() {
_G(game_paused_in_debugger) = 0;
_G(break_on_next_script_step) = 1;
} else if (strncmp(msgPtr, "EXIT", 4) == 0) {
- _G(want_exit) = 1;
- _G(abort_engine) = 1;
+ _G(want_exit) = true;
+ _G(abort_engine) = true;
_G(check_dynamic_sprites_at_exit) = 0;
}
@@ -447,7 +447,7 @@ int check_for_messages_from_editor() {
bool send_exception_to_editor(const char *qmsg) {
#if AGS_PLATFORM_OS_WINDOWS
- _G(want_exit) = 0;
+ _G(want_exit) = false;
// allow the editor to break with the error message
if (editor_window_handle != NULL)
SetForegroundWindow(editor_window_handle);
@@ -455,7 +455,7 @@ bool send_exception_to_editor(const char *qmsg) {
if (!send_message_to_editor("ERROR", qmsg))
return false;
- while ((check_for_messages_from_editor() == 0) && (_G(want_exit) == 0)) {
+ while ((check_for_messages_from_editor() == 0) && (!_G(want_exit))) {
_G(platform)->Delay(10);
}
#endif
diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp
index d01a069fab1..6b630dcb9ae 100644
--- a/engines/ags/engine/main/engine.cpp
+++ b/engines/ags/engine/main/engine.cpp
@@ -104,8 +104,8 @@ bool engine_init_backend() {
}
void winclosehook() {
- _G(want_exit) = 1;
- _G(abort_engine) = 1;
+ _G(want_exit) = true;
+ _G(abort_engine) = true;
_G(check_dynamic_sprites_at_exit) = 0;
AbortGame();
}
diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp
index 2a12ecc0512..91bc2adc8bd 100644
--- a/engines/ags/engine/main/game_run.cpp
+++ b/engines/ags/engine/main/game_run.cpp
@@ -86,7 +86,7 @@ static bool ShouldStayInWaitMode();
#define UNTIL_ANIMBTNEND 9
static void ProperExit() {
- _G(want_exit) = 0;
+ _G(want_exit) = false;
_G(proper_exit) = 1;
quit("||exit!");
}
@@ -1042,7 +1042,7 @@ void update_polled_stuff_if_runtime() {
::AGS::g_events->pollEvents();
if (_G(want_exit)) {
- _G(want_exit) = 0;
+ _G(want_exit) = false;
quit("||exit!");
} else if (_G(editor_debugging_initialized))
Commit: 40c85968e16fee4cd4e6865fb5c3c763c1bddac5
https://github.com/scummvm/scummvm/commit/40c85968e16fee4cd4e6865fb5c3c763c1bddac5
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-23T23:57:27+01:00
Commit Message:
AGS: Fixed restoring a exclusive fullscreen mode on switch in
Fixed getting stuck in a render attempt loop, because the window
events are not being processed.
>From upstream 25329949f4d4a17ea8e6ad11fc7bd0ecccdfaca7
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 8caa8119aec..5b6c7e6f786 100644
--- a/engines/ags/engine/ac/draw.cpp
+++ b/engines/ags/engine/ac/draw.cpp
@@ -696,7 +696,7 @@ void render_to_screen() {
_G(gfxDriver)->SetVsync((_GP(scsystem).vsync > 0) && (!_GP(scsystem).windowed));
bool succeeded = false;
- while (!succeeded) {
+ while (!succeeded && !_G(want_exit) && !_G(abort_engine)) {
// try
// {
// For software renderer, need to blacken upper part of the game frame when shaking screen moves image down
@@ -717,13 +717,10 @@ void render_to_screen() {
/*}
catch (Ali3DFullscreenLostException e) {
Debug::Printf("Renderer exception: %s", e._message);
- platform->Delay(500);
- }
- catch (Ali3DException e) {
- Debug::Printf("Renderer exception: %s", e._message);
- }
- catch (...) {
- Debug::Printf("Unknown renderer exception");
+ while (_G(game_update_suspend) && (!_G(want_exit)) && (!_G(abort_engine))) {
+ sys_evt_process_pending();
+ platform->Delay(300);
+ }
}*/
}
}
Commit: aa9983c28ddee7139daef15581b929a334c5c895
https://github.com/scummvm/scummvm/commit/aa9983c28ddee7139daef15581b929a334c5c895
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-23T23:57:27+01:00
Commit Message:
AGS: Update commented out exception handling code
This code is not used in ScummVM, but since it was still there in
comments it's probably better to keep it in sync with upstream.
The code was updated in upstream 0d1034df1a0e6593e7e61bbdb75d2996b8721b14
(tidy Direct3D renderer code, remove redundant parts, etc)
and 2f04e3b81db598eb7950668ce9d88a145f796f2c
(fixed Ali3DException's message string misuse)
Changed paths:
engines/ags/engine/ac/draw.cpp
engines/ags/engine/main/game_start.cpp
diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp
index 5b6c7e6f786..cb6b49d435e 100644
--- a/engines/ags/engine/ac/draw.cpp
+++ b/engines/ags/engine/ac/draw.cpp
@@ -344,7 +344,7 @@ void create_blank_image(int coldepth) {
/*}
catch (Ali3DException gfxException)
{
- quit((char*)gfxException._message);
+ quit(gfxException._message.GetCStr());
}*/
}
diff --git a/engines/ags/engine/main/game_start.cpp b/engines/ags/engine/main/game_start.cpp
index ec904a1a986..b1b671a0d3f 100644
--- a/engines/ags/engine/main/game_start.cpp
+++ b/engines/ags/engine/main/game_start.cpp
@@ -129,7 +129,7 @@ void initialize_start_and_play_game(int override_start_room, int loadSave) {
RunGameUntilAborted();
/*} catch (Ali3DException gfxException) {
- quit((char *)gfxException._message);
+ quit(gfxException._message.GetCStr());
}*/
}
Commit: 6f665dfe68952c4d90624eff796744af5eeb7c36
https://github.com/scummvm/scummvm/commit/6f665dfe68952c4d90624eff796744af5eeb7c36
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-23T23:57:27+01:00
Commit Message:
AGS: Test for hanging script using timeout instead of while loops
>From upstream c34f0c96596f1a7814c15e7a06c2c498cb95ebfc
Changed paths:
engines/ags/engine/game/game_init.cpp
engines/ags/engine/script/cc_instance.cpp
engines/ags/engine/script/cc_instance.h
engines/ags/engine/script/script_runtime.cpp
engines/ags/engine/script/script_runtime.h
engines/ags/globals.h
diff --git a/engines/ags/engine/game/game_init.cpp b/engines/ags/engine/game/game_init.cpp
index 8573b9281e1..e28c73557c3 100644
--- a/engines/ags/engine/game/game_init.cpp
+++ b/engines/ags/engine/game/game_init.cpp
@@ -417,7 +417,7 @@ HGameInitError InitGameState(const LoadedGameEntities &ents, GameDataVersion dat
// NOTE: we must do this before plugin start, because some plugins may
// require access to script API at initialization time.
//
- ccSetScriptAliveTimer(150000);
+ ccSetScriptAliveTimer(10u, 1000u);
ccSetStringClassImpl(&_GP(myScriptStringImpl));
setup_script_exports(base_api, compat_api);
diff --git a/engines/ags/engine/script/cc_instance.cpp b/engines/ags/engine/script/cc_instance.cpp
index dba0966ea19..59a87cfeffa 100644
--- a/engines/ags/engine/script/cc_instance.cpp
+++ b/engines/ags/engine/script/cc_instance.cpp
@@ -39,6 +39,7 @@
#include "ags/engine/ac/dynobj/script_user_object.h"
#include "ags/engine/ac/statobj/ags_static_object.h"
#include "ags/engine/ac/statobj/static_array.h"
+#include "ags/engine/ac/sys_events.h"
#include "ags/engine/ac/dynobj/cc_dynamic_object_addr_and_manager.h"
#include "ags/shared/util/memory.h"
#include "ags/shared/util/string_utils.h" // linux strnicmp definition
@@ -206,7 +207,6 @@ struct FunctionCallStack {
int Count;
};
-
ccInstance *ccInstance::GetCurrentInstance() {
return _GP(InstThreads).size() > 0 ? _GP(InstThreads).back() : nullptr;
}
@@ -226,6 +226,11 @@ ccInstance *ccInstance::CreateEx(PScript scri, ccInstance *joined) {
return cinst;
}
+void ccInstance::SetExecTimeout(unsigned sys_poll_ms, unsigned abort_ms) {
+ _G(timeoutCheckMs) = sys_poll_ms;
+ _G(timeoutAbortMs) = abort_ms;
+}
+
ccInstance::ccInstance() {
flags = 0;
globaldata = nullptr;
@@ -431,7 +436,6 @@ int ccInstance::Run(int32_t curpc) {
int32_t thisbase[MAXNEST], funcstart[MAXNEST];
int was_just_callas = -1;
int curnest = 0;
- int loopIterations = 0;
int num_args_to_func = -1;
int next_call_needs_object = 0;
int loopIterationCheckDisabled = 0;
@@ -441,9 +445,13 @@ int ccInstance::Run(int32_t curpc) {
bool write_debug_dump = ccGetOption(SCOPT_DEBUGRUN) ||
(gDebugLevel > 0 && DebugMan.isDebugChannelEnabled(::AGS::kDebugScript));
ScriptOperation codeOp;
-
FunctionCallStack func_callstack;
+ const auto timeout = std::chrono::milliseconds(_G(timeoutCheckMs));
+ const auto timeout_abort = std::chrono::milliseconds(_G(timeoutAbortMs));
+ _lastAliveTs = AGS_Clock::now();
+ bool timeout_warn = false;
+
while ((flags & INSTF_ABORTED) == 0) {
if (_G(abort_engine))
return -1;
@@ -774,15 +782,30 @@ int ccInstance::Run(int32_t curpc) {
case SCMD_JMP:
pc += arg1.IValue;
- if ((arg1.IValue < 0) && (_G(maxWhileLoops) > 0) && (loopIterationCheckDisabled == 0)) {
- // Make sure it's not stuck in a While loop
- loopIterations ++;
+ // Make sure it's not stuck in a While loop
+ if (arg1.IValue < 0) {
+ auto now = AGS_Clock::now();
+ auto test_dur = std::chrono::duration_cast<std::chrono::milliseconds>(now - _lastAliveTs);
if (flags & INSTF_RUNNING) {
- loopIterations = 0;
+ // was notified still running, don't do anything
flags &= ~INSTF_RUNNING;
- } else if (loopIterations > _G(maxWhileLoops)) {
- cc_error("!Script appears to be hung (a while loop ran %d times). The problem may be in a calling function; check the call stack.", loopIterations);
- return -1;
+ _lastAliveTs = now;
+ timeout_warn = false;
+ } else if (test_dur > timeout) {
+ // minimal timeout occured
+ if (test_dur.count() > timeout_abort.count()) {
+ // critical timeout occured
+ if (loopIterationCheckDisabled == 0) {
+ cc_error("!Script appears to be hung (no game update for %lld ms). The problem may be in a calling function; check the call stack.", test_dur.count());
+ return -1;
+ }
+ if (!timeout_warn) {
+ debug_script_warn("WARNING: script execution hung? (%lld ms)", test_dur.count());
+ timeout_warn = true;
+ }
+ }
+ // at least let user to manipulate the game window
+ sys_evt_process_pending();
}
}
break;
diff --git a/engines/ags/engine/script/cc_instance.h b/engines/ags/engine/script/cc_instance.h
index 7bcf0bc20ae..6eaa63b79fd 100644
--- a/engines/ags/engine/script/cc_instance.h
+++ b/engines/ags/engine/script/cc_instance.h
@@ -24,6 +24,7 @@
#include "ags/lib/std/memory.h"
#include "ags/lib/std/map.h"
+#include "ags/engine/ac/timer.h"
#include "ags/shared/script/cc_internal.h"
#include "ags/shared/script/cc_script.h" // ccScript
#include "ags/engine/script/non_blocking_script_function.h"
@@ -144,6 +145,7 @@ public:
// create a runnable instance of the supplied script
static ccInstance *CreateFromScript(PScript script);
static ccInstance *CreateEx(PScript scri, ccInstance *joined);
+ static void SetExecTimeout(unsigned sys_poll_ms, unsigned abort_ms);
ccInstance();
~ccInstance();
@@ -176,7 +178,7 @@ public:
// Also change CALLEXT op-codes to CALLAS when they pertain to a script instance
bool ResolveImportFixups(const ccScript *scri);
-protected:
+private:
bool _Create(PScript scri, ccInstance *joined);
// free the memory associated with the instance
void Free();
@@ -213,6 +215,9 @@ protected:
// Function call stack processing
void PushToFuncCallStack(FunctionCallStack &func_callstack, const RuntimeScriptValue &rval);
void PopFromFuncCallStack(FunctionCallStack &func_callstack, int32_t num_entries);
+
+ // Last time the script was noted of being "alive"
+ AGS_Clock::time_point _lastAliveTs;
};
extern void script_commands_init();
diff --git a/engines/ags/engine/script/script_runtime.cpp b/engines/ags/engine/script/script_runtime.cpp
index 668bc788caf..be541c3776b 100644
--- a/engines/ags/engine/script/script_runtime.cpp
+++ b/engines/ags/engine/script/script_runtime.cpp
@@ -42,8 +42,6 @@
namespace AGS3 {
-// static const char ccRunnerCopyright[] = "ScriptExecuter32 v" SCOM_VERSIONSTR " (c) 2001 Chris Jones";
-
bool ccAddExternalStaticFunction(const String &name, ScriptAPIFunction *pfn) {
return _GP(simp).add(name, RuntimeScriptValue().SetStaticFunction(pfn), nullptr) != UINT32_MAX;
}
@@ -115,9 +113,9 @@ Plugins::PluginMethod ccGetSymbolAddressForPlugin(const String &name) {
// If a while loop does this many iterations without the
// NofityScriptAlive function getting called, the script
// aborts. Set to 0 to disable.
-void ccSetScriptAliveTimer(int numloop) {
- _G(maxWhileLoops) = numloop;
-}
+void ccSetScriptAliveTimer(unsigned sys_poll_timeout, unsigned abort_timeout) {
+ ccInstance::SetExecTimeout(sys_poll_timeout, abort_timeout);
+ }
void ccNotifyScriptStillAlive() {
ccInstance *cur_inst = ccInstance::GetCurrentInstance();
diff --git a/engines/ags/engine/script/script_runtime.h b/engines/ags/engine/script/script_runtime.h
index fd104279666..00e6eba5d5b 100644
--- a/engines/ags/engine/script/script_runtime.h
+++ b/engines/ags/engine/script/script_runtime.h
@@ -77,8 +77,10 @@ extern Plugins::PluginMethod ccGetSymbolAddressForPlugin(const String &name);
typedef void (*new_line_hook_type)(ccInstance *, int);
extern void ccSetDebugHook(new_line_hook_type jibble);
-// Set the number of while loop iterations that aborts the script
-extern void ccSetScriptAliveTimer(int);
+// Set the script interpreter timeout values, in milliseconds:
+// * sys_poll_timeout - defines the timeout at which the interpreter will run system events poll;
+// * abort_timeout - defines the timeout at which the interpreter will cancel with error.
+extern void ccSetScriptAliveTimer(unsigned sys_poll_timeout, unsigned abort_timeout);
// reset the current while loop counter
extern void ccNotifyScriptStillAlive();
// for calling exported plugin functions old-style
diff --git a/engines/ags/globals.h b/engines/ags/globals.h
index 15bad25e80b..663edbc6029 100644
--- a/engines/ags/globals.h
+++ b/engines/ags/globals.h
@@ -1279,7 +1279,12 @@ public:
*/
new_line_hook_type _new_line_hook = nullptr;
- int _maxWhileLoops = 0;
+ // Minimal timeout: how much time may pass without any engine update
+ // before we want to check on the situation and do system poll
+ unsigned _timeoutCheckMs = 60u;
+ // Critical timeout: how much time may pass without any engine update
+ // before we abort or post a warning
+ unsigned _timeoutAbortMs = 60u * 10;
ccInstance *_loadedInstances[MAX_LOADED_INSTANCES];
/**@}*/
Commit: 7372aa4040571bb9cebcb1d267a8da943834e9a2
https://github.com/scummvm/scummvm/commit/7372aa4040571bb9cebcb1d267a8da943834e9a2
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-23T23:57:27+01:00
Commit Message:
AGS: Updated build version (3.6.0.28)
>From upstream ad7c27a8bbf8a9e827ebd052472887cf4f47a299
Changed paths:
engines/ags/engine/ac/draw.cpp
engines/ags/engine/main/game_start.cpp
engines/ags/shared/core/def_version.h
diff --git a/engines/ags/engine/ac/draw.cpp b/engines/ags/engine/ac/draw.cpp
index cb6b49d435e..455bbad155b 100644
--- a/engines/ags/engine/ac/draw.cpp
+++ b/engines/ags/engine/ac/draw.cpp
@@ -344,7 +344,7 @@ void create_blank_image(int coldepth) {
/*}
catch (Ali3DException gfxException)
{
- quit(gfxException._message.GetCStr());
+ quit(gfxException.Message.GetCStr());
}*/
}
@@ -716,7 +716,7 @@ void render_to_screen() {
succeeded = true;
/*}
catch (Ali3DFullscreenLostException e) {
- Debug::Printf("Renderer exception: %s", e._message);
+ Debug::Printf("Renderer exception: %s", e.Message.GetCStr());
while (_G(game_update_suspend) && (!_G(want_exit)) && (!_G(abort_engine))) {
sys_evt_process_pending();
platform->Delay(300);
diff --git a/engines/ags/engine/main/game_start.cpp b/engines/ags/engine/main/game_start.cpp
index b1b671a0d3f..63ec5b344e2 100644
--- a/engines/ags/engine/main/game_start.cpp
+++ b/engines/ags/engine/main/game_start.cpp
@@ -129,7 +129,7 @@ void initialize_start_and_play_game(int override_start_room, int loadSave) {
RunGameUntilAborted();
/*} catch (Ali3DException gfxException) {
- quit(gfxException._message.GetCStr());
+ quit(gfxException.Message.GetCStr());
}*/
}
diff --git a/engines/ags/shared/core/def_version.h b/engines/ags/shared/core/def_version.h
index 41de73a167a..fc2d0e6f735 100644
--- a/engines/ags/shared/core/def_version.h
+++ b/engines/ags/shared/core/def_version.h
@@ -22,9 +22,9 @@
#ifndef AGS_SHARED_CORE_DEFVERSION_H
#define AGS_SHARED_CORE_DEFVERSION_H
-#define ACI_VERSION_STR "3.6.0.27"
+#define ACI_VERSION_STR "3.6.0.28"
#if defined (RC_INVOKED) // for MSVC resource compiler
-#define ACI_VERSION_MSRC_DEF 3.6.0.27
+#define ACI_VERSION_MSRC_DEF 3.6.0.28
#endif
#define SPECIAL_VERSION ""
Commit: 08db4be24cd87829d3ddc2be1286fb922b44d589
https://github.com/scummvm/scummvm/commit/08db4be24cd87829d3ddc2be1286fb922b44d589
Author: Thierry Crozat (criezy at scummvm.org)
Date: 2022-06-23T23:57:49+01:00
Commit Message:
AGS: As a hotfix, restored the old way to test for hung script loops
The timeout method introduced by 6f665dfe is not working very well and
gives "false positives", so I'll disable it for the time being.
>From upstream e0edb28b6606c360a1ea3fdcc487c2b05929ed02
Changed paths:
engines/ags/engine/game/game_init.cpp
engines/ags/engine/script/cc_instance.cpp
engines/ags/engine/script/cc_instance.h
engines/ags/engine/script/script_runtime.cpp
engines/ags/engine/script/script_runtime.h
engines/ags/globals.h
diff --git a/engines/ags/engine/game/game_init.cpp b/engines/ags/engine/game/game_init.cpp
index e28c73557c3..09fa9c04ef5 100644
--- a/engines/ags/engine/game/game_init.cpp
+++ b/engines/ags/engine/game/game_init.cpp
@@ -417,7 +417,7 @@ HGameInitError InitGameState(const LoadedGameEntities &ents, GameDataVersion dat
// NOTE: we must do this before plugin start, because some plugins may
// require access to script API at initialization time.
//
- ccSetScriptAliveTimer(10u, 1000u);
+ ccSetScriptAliveTimer(10u, 1000u, 150000u);
ccSetStringClassImpl(&_GP(myScriptStringImpl));
setup_script_exports(base_api, compat_api);
diff --git a/engines/ags/engine/script/cc_instance.cpp b/engines/ags/engine/script/cc_instance.cpp
index 59a87cfeffa..d3b41f125bb 100644
--- a/engines/ags/engine/script/cc_instance.cpp
+++ b/engines/ags/engine/script/cc_instance.cpp
@@ -226,9 +226,10 @@ ccInstance *ccInstance::CreateEx(PScript scri, ccInstance *joined) {
return cinst;
}
-void ccInstance::SetExecTimeout(unsigned sys_poll_ms, unsigned abort_ms) {
+void ccInstance::SetExecTimeout(unsigned sys_poll_ms, unsigned abort_ms, unsigned abort_loops) {
_G(timeoutCheckMs) = sys_poll_ms;
_G(timeoutAbortMs) = abort_ms;
+ _G(maxWhileLoops) = abort_loops;
}
ccInstance::ccInstance() {
@@ -436,6 +437,7 @@ int ccInstance::Run(int32_t curpc) {
int32_t thisbase[MAXNEST], funcstart[MAXNEST];
int was_just_callas = -1;
int curnest = 0;
+ int loopIterations = 0;
int num_args_to_func = -1;
int next_call_needs_object = 0;
int loopIterationCheckDisabled = 0;
@@ -791,14 +793,20 @@ int ccInstance::Run(int32_t curpc) {
flags &= ~INSTF_RUNNING;
_lastAliveTs = now;
timeout_warn = false;
+ loopIterations = 0;
+ } else if ((loopIterationCheckDisabled == 0) && (++loopIterations > _G(maxWhileLoops))) {
+ cc_error("!Script appears to be hung (a while loop ran %d times). The problem may be in a calling function; check the call stack.", loopIterations);
+ return -1;
} else if (test_dur > timeout) {
// minimal timeout occured
if (test_dur.count() > timeout_abort.count()) {
// critical timeout occured
+ /* CHECKME: disabled, because not working well
if (loopIterationCheckDisabled == 0) {
cc_error("!Script appears to be hung (no game update for %lld ms). The problem may be in a calling function; check the call stack.", test_dur.count());
return -1;
}
+ */
if (!timeout_warn) {
debug_script_warn("WARNING: script execution hung? (%lld ms)", test_dur.count());
timeout_warn = true;
diff --git a/engines/ags/engine/script/cc_instance.h b/engines/ags/engine/script/cc_instance.h
index 6eaa63b79fd..98000131175 100644
--- a/engines/ags/engine/script/cc_instance.h
+++ b/engines/ags/engine/script/cc_instance.h
@@ -145,7 +145,7 @@ public:
// create a runnable instance of the supplied script
static ccInstance *CreateFromScript(PScript script);
static ccInstance *CreateEx(PScript scri, ccInstance *joined);
- static void SetExecTimeout(unsigned sys_poll_ms, unsigned abort_ms);
+ static void SetExecTimeout(unsigned sys_poll_ms, unsigned abort_ms, unsigned abort_loops);
ccInstance();
~ccInstance();
diff --git a/engines/ags/engine/script/script_runtime.cpp b/engines/ags/engine/script/script_runtime.cpp
index be541c3776b..139cc1d7fc5 100644
--- a/engines/ags/engine/script/script_runtime.cpp
+++ b/engines/ags/engine/script/script_runtime.cpp
@@ -110,11 +110,8 @@ Plugins::PluginMethod ccGetSymbolAddressForPlugin(const String &name) {
return Plugins::PluginMethod();
}
-// If a while loop does this many iterations without the
-// NofityScriptAlive function getting called, the script
-// aborts. Set to 0 to disable.
-void ccSetScriptAliveTimer(unsigned sys_poll_timeout, unsigned abort_timeout) {
- ccInstance::SetExecTimeout(sys_poll_timeout, abort_timeout);
+void ccSetScriptAliveTimer(unsigned sys_poll_timeout, unsigned abort_timeout, unsigned abort_loops) {
+ ccInstance::SetExecTimeout(sys_poll_timeout, abort_timeout, abort_loops);
}
void ccNotifyScriptStillAlive() {
diff --git a/engines/ags/engine/script/script_runtime.h b/engines/ags/engine/script/script_runtime.h
index 00e6eba5d5b..a16338058b1 100644
--- a/engines/ags/engine/script/script_runtime.h
+++ b/engines/ags/engine/script/script_runtime.h
@@ -77,10 +77,11 @@ extern Plugins::PluginMethod ccGetSymbolAddressForPlugin(const String &name);
typedef void (*new_line_hook_type)(ccInstance *, int);
extern void ccSetDebugHook(new_line_hook_type jibble);
-// Set the script interpreter timeout values, in milliseconds:
-// * sys_poll_timeout - defines the timeout at which the interpreter will run system events poll;
-// * abort_timeout - defines the timeout at which the interpreter will cancel with error.
-extern void ccSetScriptAliveTimer(unsigned sys_poll_timeout, unsigned abort_timeout);
+// Set the script interpreter timeout values:
+// * sys_poll_timeout - defines the timeout (ms) at which the interpreter will run system events poll;
+// * abort_timeout - [temp disabled] defines the timeout (ms) at which the interpreter will cancel with error.
+// * abort_loops - max script loops without an engine update after which the interpreter will error;
+extern void ccSetScriptAliveTimer(unsigned sys_poll_timeout, unsigned abort_timeout, unsigned abort_loops);
// reset the current while loop counter
extern void ccNotifyScriptStillAlive();
// for calling exported plugin functions old-style
diff --git a/engines/ags/globals.h b/engines/ags/globals.h
index 663edbc6029..ae63f666452 100644
--- a/engines/ags/globals.h
+++ b/engines/ags/globals.h
@@ -1285,6 +1285,9 @@ public:
// Critical timeout: how much time may pass without any engine update
// before we abort or post a warning
unsigned _timeoutAbortMs = 60u * 10;
+ // Maximal while loops without any engine update in between,
+ // after which the interpreter will abort
+ unsigned _maxWhileLoops = 150000u;
ccInstance *_loadedInstances[MAX_LOADED_INSTANCES];
/**@}*/
More information about the Scummvm-git-logs
mailing list