[Scummvm-git-logs] scummvm master -> 2bcaa19756fa64e3119195fb34c630dd462e7892
tag2015
noreply at scummvm.org
Thu Mar 28 11:06:02 UTC 2024
This automated email contains information about 20 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
0f438f51c7 AGS: Common: fix String::IsNullOrSpace() to avoid asserts for extended chars
a1ae05f537 AGS: Fix uninitialized value
5d7c835c53 AGS: fixed wrong offset calculation when writing TRA
dfb4598c31 AGS: Common: fix String::Trim*() to avoid asserts for extended chars
092ef64fc6 AGS: Engine: fixed speech stuck in "post state" under some conditions
42a26dc75b AGS: Engine: renamed cant_skip_speech to speech_skip_style for clarity
dacccc343e AGS: Engine: fix use of global "walkspeed" variables in the pathfinder
0b50067abb AGS: Engine: implement add_waypoint_direct(), fix AddWaypoint's resolution
2e5560fd1e AGS: Remove no longer used move_speed global vars
de31994dd0 AGS: Engine: safeguard Overlay.Create in case of non-existing sprite
d30db56310 AGS: Updated build version (3.6.0.57)
bb72a09404 AGS: Engine: fixed "lowest compatible save version"
27aceb5888 AGS: Engine: fixed text parser in Dialog Options in "new key handling" mode
9d0e82c4d3 AGS: Engine: fixed camera may fail to restore its position in the room
59e2d4955e AGS: Common: fix all_buttons_disabled's type, for clarity
ecc7642775 AGS: Engine: fixed kGuiDis_Blackout in "draw controls as textures" mode
79f3b6eec5 AGS: Engine: for Software mode fixed disabled controls leaving traces on gui
f09519834c AGS: Engine: updated unload_game_file(), fix few things not reset
6c8e783e4a AGS: Engine: add hotspot id assertion to GetHotspotProperty
2bcaa19756 AGS: fix all_buttons_disabled check condition
Commit: 0f438f51c717a6fec6dc3d7bb8ee4f35e7a28a73
https://github.com/scummvm/scummvm/commit/0f438f51c717a6fec6dc3d7bb8ee4f35e7a28a73
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2024-03-28T12:00:55+01:00
Commit Message:
AGS: Common: fix String::IsNullOrSpace() to avoid asserts for extended chars
>From upstream 4aa8d0ce7324dafcbd528ca904189604c5a9fe0d
Changed paths:
engines/ags/shared/util/string.cpp
diff --git a/engines/ags/shared/util/string.cpp b/engines/ags/shared/util/string.cpp
index 09d9b30cfe7..257d4b458e9 100644
--- a/engines/ags/shared/util/string.cpp
+++ b/engines/ags/shared/util/string.cpp
@@ -89,7 +89,7 @@ bool String::IsNullOrSpace() const {
if (_len == 0)
return true;
for (const char *ptr = _cstr; *ptr; ++ptr) {
- if (!Common::isSpace(*ptr))
+ if (!Common::isSpace(static_cast<uint8_t>(*ptr)))
return false;
}
return true;
Commit: a1ae05f53717f044bf94a85296d637cd28b7e0ed
https://github.com/scummvm/scummvm/commit/a1ae05f53717f044bf94a85296d637cd28b7e0ed
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2024-03-28T12:00:55+01:00
Commit Message:
AGS: Fix uninitialized value
Partially from upstream 8ccd9fde8817df951146da7c94a6b3330397a062
Changed paths:
engines/ags/shared/game/tra_file.h
diff --git a/engines/ags/shared/game/tra_file.h b/engines/ags/shared/game/tra_file.h
index 145b55f34da..525ea0f5eef 100644
--- a/engines/ags/shared/game/tra_file.h
+++ b/engines/ags/shared/game/tra_file.h
@@ -63,7 +63,7 @@ typedef TypedCodeError<TraFileErrorType, GetTraFileErrorText> TraFileError;
struct Translation {
// Game identifiers, for matching the translation file with the game
- int GameUid;
+ int GameUid = 0;
String GameName;
// Translation dictionary in source/dest pairs
StringMap Dict;
Commit: 5d7c835c53d5cbed1a5f3729ad150f07edb6b48d
https://github.com/scummvm/scummvm/commit/5d7c835c53d5cbed1a5f3729ad150f07edb6b48d
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2024-03-28T12:00:55+01:00
Commit Message:
AGS: fixed wrong offset calculation when writing TRA
This was broken at some point... see commits:
f93f44c, e74b5ca
>From upstream f49c8c90a198dbe187d811ea861afd19f094acdd
Changed paths:
engines/ags/shared/util/data_ext.cpp
engines/ags/shared/util/data_ext.h
diff --git a/engines/ags/shared/util/data_ext.cpp b/engines/ags/shared/util/data_ext.cpp
index 7b7bfdeb140..953ed491c78 100644
--- a/engines/ags/shared/util/data_ext.cpp
+++ b/engines/ags/shared/util/data_ext.cpp
@@ -123,27 +123,31 @@ HError DataExtReader::Read() {
// Generic function that saves a block and automatically adds its size into header
void WriteExtBlock(int block, const String &ext_id, const PfnWriteExtBlock &writer, int flags, Stream *out) {
+ const bool is_id32 = (flags & kDataExt_NumID32) != 0;
+ // 64-bit file offsets are written for blocks with ext_id, OR File64 flag
+ const bool is_file64 = (block == 0) || ((flags & kDataExt_File64) != 0);
// Write block's header
- (flags & kDataExt_NumID32) != 0 ?
+ is_id32 != 0 ?
out->WriteInt32(block) :
out->WriteInt8(static_cast<int8_t>(block));
if (block == 0) // new-style string id
ext_id.WriteCount(out, 16);
soff_t sz_at = out->GetPosition();
// block size placeholder
- ((flags & kDataExt_File64) != 0) ?
+ is_file64 ?
out->WriteInt64(0) :
out->WriteInt32(0);
+ soff_t start_at = out->GetPosition();
// Call writer to save actual block contents
writer(out);
// Now calculate the block's size...
soff_t end_at = out->GetPosition();
- soff_t block_size = (end_at - sz_at) - sizeof(int64_t);
+ soff_t block_size = (end_at - start_at);
// ...return back and write block's size in the placeholder
out->Seek(sz_at, Shared::kSeekBegin);
- ((flags & kDataExt_File64) != 0) ?
+ is_file64 ?
out->WriteInt64(block_size) :
out->WriteInt32((int32_t)block_size);
// ...and get back to the end of the file
diff --git a/engines/ags/shared/util/data_ext.h b/engines/ags/shared/util/data_ext.h
index 6eb5399ce33..7bd487b5bbd 100644
--- a/engines/ags/shared/util/data_ext.h
+++ b/engines/ags/shared/util/data_ext.h
@@ -69,6 +69,8 @@ enum DataExtFlags {
kDataExt_NumID8 = 0x0000, // default
kDataExt_NumID32 = 0x0001,
// 32-bit or 64-bit file offset support
+ // NOTE: for historical reasons this refers to blocks with numeric ID ONLY;
+ // new-style blocks with a 16-char ID always write 64-bit offset
kDataExt_File32 = 0x0000, // default
kDataExt_File64 = 0x0002
};
Commit: dfb4598c31137a4e4609783652c73ed257883653
https://github.com/scummvm/scummvm/commit/dfb4598c31137a4e4609783652c73ed257883653
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2024-03-28T12:00:55+01:00
Commit Message:
AGS: Common: fix String::Trim*() to avoid asserts for extended chars
This complements 82abea8
>From upstream 82ffab07df0bdf4a016addcc6050ba7f2b5e8fdc
Changed paths:
engines/ags/shared/util/string.cpp
diff --git a/engines/ags/shared/util/string.cpp b/engines/ags/shared/util/string.cpp
index 257d4b458e9..8d932100f90 100644
--- a/engines/ags/shared/util/string.cpp
+++ b/engines/ags/shared/util/string.cpp
@@ -780,7 +780,7 @@ void String::TrimLeft(char c) {
if (c && t != c) {
break;
}
- if (!c && !Common::isSpace(t)) {
+ if (!c && !Common::isSpace(static_cast<uint8_t>(t))) {
break;
}
trim_ptr++;
@@ -807,7 +807,7 @@ void String::TrimRight(char c) {
if (c && t != c) {
break;
}
- if (!c && !Common::isSpace(t)) {
+ if (!c && !Common::isSpace(static_cast<uint8_t>(t))) {
break;
}
trim_ptr--;
Commit: 092ef64fc6c3abdb8993894ad11edafc3ff2889f
https://github.com/scummvm/scummvm/commit/092ef64fc6c3abdb8993894ad11edafc3ff2889f
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2024-03-28T12:00:55+01:00
Commit Message:
AGS: Engine: fixed speech stuck in "post state" under some conditions
This fixes repeated post-state on/off switching, and as a consequence - endless loop
in cause of a "..." sentence, that is run until messagetime reaches -1 on its own,
which did not happen because of repeated post-state.
NOTE: looks like an original bug introduced along with the DisplayPostTimeMs property.
>From upstream 37360990b22a79380f2a5b34e686a2d2fbcf7de1
Changed paths:
engines/ags/engine/ac/character.cpp
engines/ags/engine/ac/display.cpp
engines/ags/engine/ac/display.h
engines/ags/engine/main/update.cpp
diff --git a/engines/ags/engine/ac/character.cpp b/engines/ags/engine/ac/character.cpp
index 7a430a4e132..a849d2f6ac3 100644
--- a/engines/ags/engine/ac/character.cpp
+++ b/engines/ags/engine/ac/character.cpp
@@ -2329,7 +2329,10 @@ void _displayspeech(const char *texx, int aschar, int xx, int yy, int widd, int
if (isPause) {
postpone_scheduled_music_update_by(std::chrono::milliseconds(_GP(play).messagetime * 1000 / _G(frames_per_second)));
+ // Set a post-state right away, as we only need to wait for a messagetime timer
+ _GP(play).speech_in_post_state = true;
GameLoopUntilValueIsNegative(&_GP(play).messagetime);
+ post_display_cleanup();
return;
}
diff --git a/engines/ags/engine/ac/display.cpp b/engines/ags/engine/ac/display.cpp
index 768ebd83e4b..919820acafa 100644
--- a/engines/ags/engine/ac/display.cpp
+++ b/engines/ags/engine/ac/display.cpp
@@ -292,7 +292,7 @@ ScreenOverlay *_display_main(int xx, int yy, int wii, const char *text, int disp
if (_GP(play).fast_forward) {
remove_screen_overlay(OVER_TEXTMSG);
_GP(play).SetWaitSkipResult(SKIP_AUTOTIMER);
- _GP(play).messagetime = -1;
+ post_display_cleanup();
return nullptr;
}
@@ -383,9 +383,7 @@ ScreenOverlay *_display_main(int xx, int yy, int wii, const char *text, int disp
//
// Post-message cleanup
//
-
- ags_clear_input_buffer();
- _GP(play).messagetime = -1;
+ post_display_cleanup();
return nullptr;
}
@@ -408,6 +406,12 @@ void _display_at(int xx, int yy, int wii, const char *text, int disp_type, int a
stop_voice_speech();
}
+void post_display_cleanup() {
+ ags_clear_input_buffer();
+ _GP(play).messagetime = -1;
+ _GP(play).speech_in_post_state = false;
+}
+
bool try_auto_play_speech(const char *text, const char *&replace_text, int charid) {
const char *src = text;
if (src[0] != '&')
diff --git a/engines/ags/engine/ac/display.h b/engines/ags/engine/ac/display.h
index b1dca4c19bf..121e46a1bfe 100644
--- a/engines/ags/engine/ac/display.h
+++ b/engines/ags/engine/ac/display.h
@@ -48,6 +48,8 @@ Shared::Bitmap *create_textual_image(const char *text, int asspch, int isThought
ScreenOverlay *_display_main(int xx, int yy, int wii, const char *text, int disp_type, int usingfont,
int asspch, int isThought, int allowShrink, bool overlayPositionFixed, bool roomlayer = false);
void _display_at(int xx, int yy, int wii, const char *text, int disp_type, int asspch, int isThought, int allowShrink, bool overlayPositionFixed);
+// Cleans up display message state
+void post_display_cleanup();
// Tests the given string for the voice-over tags and plays cue clip for the given character;
// will assign replacement string, which will be blank string if game is in "voice-only" mode
// and clip was started, or string cleaned from voice-over tags which is safe to display on screen.
diff --git a/engines/ags/engine/main/update.cpp b/engines/ags/engine/main/update.cpp
index 2e7babf2449..a3381515d74 100644
--- a/engines/ags/engine/main/update.cpp
+++ b/engines/ags/engine/main/update.cpp
@@ -254,12 +254,12 @@ void update_speech_and_messages() {
_GP(play).messagetime = 0;
}
- if (_GP(play).messagetime < 1 && _GP(play).speech_display_post_time_ms > 0 &&
- _GP(play).fast_forward == 0) {
- if (!_GP(play).speech_in_post_state) {
+ // Enter speech post-state: optionally increase final waiting time
+ if (!_GP(play).speech_in_post_state && (_GP(play).fast_forward == 0) && (_GP(play).messagetime < 1)) {
+ _GP(play).speech_in_post_state = true;
+ if (_GP(play).speech_display_post_time_ms > 0) {
_GP(play).messagetime = ::lround(_GP(play).speech_display_post_time_ms * get_current_fps() / 1000.0f);
}
- _GP(play).speech_in_post_state = !_GP(play).speech_in_post_state;
}
if (_GP(play).messagetime < 1) {
Commit: 42a26dc75b06095d0e5ae3fe3154cb31c06a4b1d
https://github.com/scummvm/scummvm/commit/42a26dc75b06095d0e5ae3fe3154cb31c06a4b1d
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2024-03-28T12:01:51+01:00
Commit Message:
AGS: Engine: renamed cant_skip_speech to speech_skip_style for clarity
Also... the old name had inverse meaning to what the variable really did.
>From upstream 44f1188992691c118aea15cffa0a73d6d4302601
Changed paths:
engines/ags/engine/ac/game_state.cpp
engines/ags/engine/ac/game_state.h
engines/ags/engine/ac/global_display.cpp
engines/ags/engine/main/engine.cpp
engines/ags/engine/main/game_run.cpp
engines/ags/engine/main/update.cpp
diff --git a/engines/ags/engine/ac/game_state.cpp b/engines/ags/engine/ac/game_state.cpp
index 90ce15f656b..750d3b5a0f8 100644
--- a/engines/ags/engine/ac/game_state.cpp
+++ b/engines/ags/engine/ac/game_state.cpp
@@ -537,7 +537,7 @@ void GameState::ReadFromSavegame(Shared::Stream *in, GameDataVersion data_ver, G
entered_at_y = in->ReadInt32();
entered_edge = in->ReadInt32();
speech_mode = (SpeechMode)in->ReadInt32();
- cant_skip_speech = in->ReadInt32();
+ speech_skip_style = in->ReadInt32();
in->ReadArrayOfInt32(script_timers, MAX_TIMERS);
sound_volume = in->ReadInt32();
speech_volume = in->ReadInt32();
@@ -741,7 +741,7 @@ void GameState::WriteForSavegame(Shared::Stream *out) const {
out->WriteInt32(entered_at_y);
out->WriteInt32(entered_edge);
out->WriteInt32(speech_mode);
- out->WriteInt32(cant_skip_speech);
+ out->WriteInt32(speech_skip_style);
out->WriteArrayOfInt32(script_timers, MAX_TIMERS);
out->WriteInt32(sound_volume);
out->WriteInt32(speech_volume);
diff --git a/engines/ags/engine/ac/game_state.h b/engines/ags/engine/ac/game_state.h
index d7b0ac17d98..f6d0479da45 100644
--- a/engines/ags/engine/ac/game_state.h
+++ b/engines/ags/engine/ac/game_state.h
@@ -174,7 +174,7 @@ struct GameState {
int entered_at_x = 0, entered_at_y = 0, entered_edge = 0;
bool voice_avail; // whether voice-over is available
SpeechMode speech_mode; // speech mode (text, voice, or both)
- int cant_skip_speech = 0;
+ int speech_skip_style = 0;
int32_t script_timers[MAX_TIMERS];
int sound_volume = 0, speech_volume = 0;
int normal_font = 0, speech_font = 0;
diff --git a/engines/ags/engine/ac/global_display.cpp b/engines/ags/engine/ac/global_display.cpp
index 543e44f5cfa..1b3fe53a818 100644
--- a/engines/ags/engine/ac/global_display.cpp
+++ b/engines/ags/engine/ac/global_display.cpp
@@ -79,7 +79,7 @@ void DisplayTopBar(int ypos, int ttexcol, int backcol, const char *title, const
_GP(topBar).font = _GP(play).top_bar_font;
// DisplaySpeech normally sets this up, but since we're not going via it...
- if (_GP(play).cant_skip_speech & SKIP_AUTOTIMER)
+ if (_GP(play).speech_skip_style & SKIP_AUTOTIMER)
_GP(play).messagetime = GetTextDisplayTime(text);
DisplayAtY(_GP(play).top_bar_ypos, text);
@@ -194,11 +194,11 @@ void SetSkipSpeech(SkipSpeechStyle newval) {
quit("!SetSkipSpeech: invalid skip mode specified");
debug_script_log("SkipSpeech style set to %d", newval);
- _GP(play).cant_skip_speech = user_to_internal_skip_speech((SkipSpeechStyle)newval);
+ _GP(play).speech_skip_style = user_to_internal_skip_speech((SkipSpeechStyle)newval);
}
SkipSpeechStyle GetSkipSpeech() {
- return internal_skip_speech_to_user(_GP(play).cant_skip_speech);
+ return internal_skip_speech_to_user(_GP(play).speech_skip_style);
}
} // namespace AGS3
diff --git a/engines/ags/engine/main/engine.cpp b/engines/ags/engine/main/engine.cpp
index 43dcef76aec..ef611c98d56 100644
--- a/engines/ags/engine/main/engine.cpp
+++ b/engines/ags/engine/main/engine.cpp
@@ -663,7 +663,7 @@ void engine_init_game_settings() {
_GP(play).digital_master_volume = 100;
_GP(play).screen_flipped = 0;
_GP(play).speech_mode = kSpeech_VoiceText;
- _GP(play).cant_skip_speech = user_to_internal_skip_speech((SkipSpeechStyle)_GP(game).options[OPT_NOSKIPTEXT]);
+ _GP(play).speech_skip_style = user_to_internal_skip_speech((SkipSpeechStyle)_GP(game).options[OPT_NOSKIPTEXT]);
_GP(play).sound_volume = 255;
_GP(play).speech_volume = 255;
_GP(play).normal_font = 0;
diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp
index dfde76d5996..1ecce7d80fc 100644
--- a/engines/ags/engine/main/game_run.cpp
+++ b/engines/ags/engine/main/game_run.cpp
@@ -209,7 +209,7 @@ static void check_mouse_controls() {
} else if ((_GP(play).wait_counter != 0) && (_GP(play).key_skip_wait & SKIP_MOUSECLICK) != 0) {
_GP(play).SetWaitSkipResult(SKIP_MOUSECLICK, mbut);
} else if (_GP(play).text_overlay_on > 0) {
- if (_GP(play).cant_skip_speech & SKIP_MOUSECLICK) {
+ if (_GP(play).speech_skip_style & SKIP_MOUSECLICK) {
remove_screen_overlay(_GP(play).text_overlay_on);
_GP(play).SetWaitSkipResult(SKIP_MOUSECLICK, mbut);
}
@@ -437,7 +437,7 @@ static void check_keyboard_controls() {
}
// skip speech if desired by Speech.SkipStyle
- if ((_GP(play).text_overlay_on > 0) && (_GP(play).cant_skip_speech & SKIP_KEYPRESS) && !IsAGSServiceKey(ki.Key)) {
+ if ((_GP(play).text_overlay_on > 0) && (_GP(play).speech_skip_style & SKIP_KEYPRESS) && !IsAGSServiceKey(ki.Key)) {
// only allow a key to remove the overlay if the icon bar isn't up
if (IsGamePaused() == 0) {
// check if it requires a specific keypress
diff --git a/engines/ags/engine/main/update.cpp b/engines/ags/engine/main/update.cpp
index a3381515d74..c0b9f6f819d 100644
--- a/engines/ags/engine/main/update.cpp
+++ b/engines/ags/engine/main/update.cpp
@@ -266,7 +266,7 @@ void update_speech_and_messages() {
if (_GP(play).fast_forward > 0) {
remove_screen_overlay(_GP(play).text_overlay_on);
_GP(play).SetWaitSkipResult(SKIP_AUTOTIMER);
- } else if (_GP(play).cant_skip_speech & SKIP_AUTOTIMER) {
+ } else if (_GP(play).speech_skip_style & SKIP_AUTOTIMER) {
remove_screen_overlay(_GP(play).text_overlay_on);
_GP(play).SetWaitSkipResult(SKIP_AUTOTIMER);
_GP(play).SetIgnoreInput(_GP(play).ignore_user_input_after_text_timeout_ms);
Commit: dacccc343e06a52f1c6997262639fa18248ae416
https://github.com/scummvm/scummvm/commit/dacccc343e06a52f1c6997262639fa18248ae416
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2024-03-28T12:01:52+01:00
Commit Message:
AGS: Engine: fix use of global "walkspeed" variables in the pathfinder
These variables had to be set using set_route_move_speed() call in order for
the find_route() and calculate_move_stage() work properly.
But it's not obvious, and easy to forget. So turn them into function arguments instead.
This fixes Character.AddWaypoint potentially using wrong walkspeed, if there are
multiple characters or objects moving simultaneously.
An example of a script that would cause a bug:
cEgo.AddWaypoint(20, 20);
oObject0.Move(0, 160, 1, eNoBlock, eAnywhere);
cEgo.AddWaypoint(200, 200);
from upstream 9a00255a2699845bd0e53054d81c24e6955f663e
Changed paths:
engines/ags/engine/ac/character.cpp
engines/ags/engine/ac/object.cpp
engines/ags/engine/ac/route_finder.cpp
engines/ags/engine/ac/route_finder.h
engines/ags/engine/ac/route_finder_impl.cpp
engines/ags/engine/ac/route_finder_impl.h
engines/ags/engine/ac/route_finder_impl_legacy.cpp
engines/ags/engine/ac/route_finder_impl_legacy.h
engines/ags/shared/ac/character_info.h
diff --git a/engines/ags/engine/ac/character.cpp b/engines/ags/engine/ac/character.cpp
index a849d2f6ac3..246da2276cc 100644
--- a/engines/ags/engine/ac/character.cpp
+++ b/engines/ags/engine/ac/character.cpp
@@ -149,7 +149,7 @@ void Character_AddWaypoint(CharacterInfo *chaa, int x, int y) {
MoveList *cmls = &_GP(mls)[chaa->walking % TURNING_AROUND];
if (cmls->numstage >= MAXNEEDSTAGES) {
- debug_script_warn("Character_AddWaypoint: move is too complex, cannot add any further paths");
+ debug_script_warn("Character::AddWaypoint: move is too complex, cannot add any further paths");
return;
}
@@ -158,9 +158,14 @@ void Character_AddWaypoint(CharacterInfo *chaa, int x, int y) {
if (cmls->pos[cmls->numstage] == cmls->pos[cmls->numstage - 1])
return;
- calculate_move_stage(cmls, cmls->numstage - 1);
- cmls->numstage ++;
+ int move_speed_x, move_speed_y;
+ chaa->get_effective_walkspeeds(move_speed_x, move_speed_y);
+ if ((move_speed_x == 0) && (move_speed_y == 0)) {
+ debug_script_warn("Character::AddWaypoint: called for '%s' with walk speed 0", chaa->scrname);
+ }
+ calculate_move_stage(cmls, cmls->numstage - 1, move_speed_x, move_speed_y);
+ cmls->numstage++;
}
void Character_AnimateEx(CharacterInfo *chaa, int loop, int delay, int repeat,
@@ -1623,20 +1628,15 @@ void walk_character(int chac, int tox, int toy, int ignwal, bool autoWalkAnims)
// are still displayed as such
debug_script_log("%s: Start move to %d,%d", chin->scrname, toxPassedIn, toyPassedIn);
- int move_speed_x = chin->walkspeed;
- int move_speed_y = chin->walkspeed;
-
- if (chin->walkspeed_y != UNIFORM_WALK_SPEED)
- move_speed_y = chin->walkspeed_y;
-
+ int move_speed_x, move_speed_y;
+ chin->get_effective_walkspeeds(move_speed_x, move_speed_y);
if ((move_speed_x == 0) && (move_speed_y == 0)) {
- debug_script_warn("Warning: MoveCharacter called for '%s' with walk speed 0", chin->name);
+ debug_script_warn("MoveCharacter: called for '%s' with walk speed 0", chin->scrname);
}
- set_route_move_speed(move_speed_x, move_speed_y);
- set_color_depth(8);
- int mslot = find_route(charX, charY, tox, toy, prepare_walkable_areas(chac), chac + CHMLSOFFS, 1, ignwal);
- set_color_depth(_GP(game).GetColorDepth());
+ int mslot = find_route(charX, charY, tox, toy, move_speed_x, move_speed_y,
+ prepare_walkable_areas(chac), chac + CHMLSOFFS, 1, ignwal);
+
if (mslot > 0) {
chin->walking = mslot;
_GP(mls)[mslot].direct = ignwal;
diff --git a/engines/ags/engine/ac/object.cpp b/engines/ags/engine/ac/object.cpp
index 7a5cc0341d4..cf8530a762f 100644
--- a/engines/ags/engine/ac/object.cpp
+++ b/engines/ags/engine/ac/object.cpp
@@ -418,10 +418,8 @@ void move_object(int objj, int tox, int toy, int spee, int ignwal) {
tox = room_to_mask_coord(tox);
toy = room_to_mask_coord(toy);
- set_route_move_speed(spee, spee);
- set_color_depth(8);
- int mslot = find_route(objX, objY, tox, toy, prepare_walkable_areas(-1), objj + 1, 1, ignwal);
- set_color_depth(_GP(game).GetColorDepth());
+ int mslot = find_route(objX, objY, tox, toy, spee, spee, prepare_walkable_areas(-1), objj + 1, 1, ignwal);
+
if (mslot > 0) {
_G(objs)[objj].moving = mslot;
_GP(mls)[mslot].direct = ignwal;
diff --git a/engines/ags/engine/ac/route_finder.cpp b/engines/ags/engine/ac/route_finder.cpp
index 7b59d7d9d4b..ed8882e4fcc 100644
--- a/engines/ags/engine/ac/route_finder.cpp
+++ b/engines/ags/engine/ac/route_finder.cpp
@@ -48,14 +48,11 @@ public:
void get_lastcpos(int &lastcx, int &lastcy) override {
AGS::Engine::RouteFinder::get_lastcpos(lastcx, lastcy);
}
- void set_route_move_speed(int speed_x, int speed_y) override {
- AGS::Engine::RouteFinder::set_route_move_speed(speed_x, speed_y);
+ int find_route(short srcx, short srcy, short xx, short yy, int move_speed_x, int move_speed_y, Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0) override {
+ return AGS::Engine::RouteFinder::find_route(srcx, srcy, xx, yy, move_speed_x, move_speed_y, onscreen, movlst, nocross, ignore_walls);
}
- int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0) override {
- return AGS::Engine::RouteFinder::find_route(srcx, srcy, xx, yy, onscreen, movlst, nocross, ignore_walls);
- }
- void calculate_move_stage(MoveList *mlsp, int aaa) override {
- AGS::Engine::RouteFinder::calculate_move_stage(mlsp, aaa);
+ void calculate_move_stage(MoveList *mlsp, int aaa, int move_speed_x, int move_speed_y) override {
+ AGS::Engine::RouteFinder::calculate_move_stage(mlsp, aaa, move_speed_x, move_speed_y);
}
};
@@ -78,14 +75,11 @@ public:
void get_lastcpos(int &lastcx, int &lastcy) override {
AGS::Engine::RouteFinderLegacy::get_lastcpos(lastcx, lastcy);
}
- void set_route_move_speed(int speed_x, int speed_y) override {
- AGS::Engine::RouteFinderLegacy::set_route_move_speed(speed_x, speed_y);
- }
- int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0) override {
- return AGS::Engine::RouteFinderLegacy::find_route(srcx, srcy, xx, yy, onscreen, movlst, nocross, ignore_walls);
+ int find_route(short srcx, short srcy, short xx, short yy, int move_speed_x, int move_speed_y, Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0) override {
+ return AGS::Engine::RouteFinderLegacy::find_route(srcx, srcy, xx, yy, move_speed_x, move_speed_y, onscreen, movlst, nocross, ignore_walls);
}
- void calculate_move_stage(MoveList *mlsp, int aaa) override {
- AGS::Engine::RouteFinderLegacy::calculate_move_stage(mlsp, aaa);
+ void calculate_move_stage(MoveList *mlsp, int aaa, int move_speed_x, int move_speed_y) override {
+ AGS::Engine::RouteFinderLegacy::calculate_move_stage(mlsp, aaa, move_speed_x, move_speed_y);
}
};
@@ -118,16 +112,12 @@ void get_lastcpos(int &lastcx, int &lastcy) {
_GP(route_finder_impl)->get_lastcpos(lastcx, lastcy);
}
-void set_route_move_speed(int speed_x, int speed_y) {
- _GP(route_finder_impl)->set_route_move_speed(speed_x, speed_y);
-}
-
-int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int movlst, int nocross, int ignore_walls) {
- return _GP(route_finder_impl)->find_route(srcx, srcy, xx, yy, onscreen, movlst, nocross, ignore_walls);
+int find_route(short srcx, short srcy, short xx, short yy, int move_speed_x, int move_speed_y, Bitmap *onscreen, int movlst, int nocross, int ignore_walls) {
+ return _GP(route_finder_impl)->find_route(srcx, srcy, xx, yy, move_speed_x, move_speed_y, onscreen, movlst, nocross, ignore_walls);
}
-void calculate_move_stage(MoveList *mlsp, int aaa) {
- _GP(route_finder_impl)->calculate_move_stage(mlsp, aaa);
+void calculate_move_stage(MoveList *mlsp, int aaa, int move_speed_x, int move_speed_y) {
+ _GP(route_finder_impl)->calculate_move_stage(mlsp, aaa, move_speed_x, move_speed_y);
}
} // namespace AGS3
diff --git a/engines/ags/engine/ac/route_finder.h b/engines/ags/engine/ac/route_finder.h
index a2dcb2a3099..5d23971ee60 100644
--- a/engines/ags/engine/ac/route_finder.h
+++ b/engines/ags/engine/ac/route_finder.h
@@ -45,9 +45,8 @@ public:
virtual void set_wallscreen(AGS::Shared::Bitmap *wallscreen) = 0;
virtual int can_see_from(int x1, int y1, int x2, int y2) = 0;
virtual void get_lastcpos(int &lastcx, int &lastcy) = 0;
- virtual void set_route_move_speed(int speed_x, int speed_y) = 0;
- virtual int find_route(short srcx, short srcy, short xx, short yy, AGS::Shared::Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0) = 0;
- virtual void calculate_move_stage(MoveList *mlsp, int aaa) = 0;
+ virtual int find_route(short srcx, short srcy, short xx, short yy, int move_speed_x, int move_speed_y, AGS::Shared::Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0) = 0;
+ virtual void calculate_move_stage(MoveList *mlsp, int aaa, int move_speed_x, int move_speed_y) = 0;
};
void init_pathfinder(GameDataVersion game_file_version);
@@ -57,11 +56,9 @@ void set_wallscreen(AGS::Shared::Bitmap *wallscreen);
int can_see_from(int x1, int y1, int x2, int y2);
void get_lastcpos(int &lastcx, int &lastcy);
-// NOTE: pathfinder implementation mostly needs to know proportion between x and y speed
-void set_route_move_speed(int speed_x, int speed_y);
-int find_route(short srcx, short srcy, short xx, short yy, AGS::Shared::Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0);
-void calculate_move_stage(MoveList *mlsp, int aaa);
+int find_route(short srcx, short srcy, short xx, short yy, int move_speed_x, int move_speed_y, AGS::Shared::Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0);
+void calculate_move_stage(MoveList *mlsp, int aaa, int move_speed_x, int move_speed_y);
} // namespace AGS3
diff --git a/engines/ags/engine/ac/route_finder_impl.cpp b/engines/ags/engine/ac/route_finder_impl.cpp
index a12e5bf8e16..b85f2fd5059 100644
--- a/engines/ags/engine/ac/route_finder_impl.cpp
+++ b/engines/ags/engine/ac/route_finder_impl.cpp
@@ -107,24 +107,17 @@ static int find_route_jps(int fromx, int fromy, int destx, int desty) {
return 1;
}
-void set_route_move_speed(int speed_x, int speed_y) {
+inline fixed input_speed_to_fixed(int speed_val) {
// negative move speeds like -2 get converted to 1/2
- if (speed_x < 0) {
- _G(move_speed_x) = itofix(1) / (-speed_x);
+ if (speed_val < 0) {
+ return itofix(1) / (-speed_val);
} else {
- _G(move_speed_x) = itofix(speed_x);
- }
-
- if (speed_y < 0) {
- _G(move_speed_y) = itofix(1) / (-speed_y);
- } else {
- _G(move_speed_y) = itofix(speed_y);
+ return itofix(speed_val);
}
}
-// Calculates the X and Y per game loop, for this stage of the
-// movelist
-void calculate_move_stage(MoveList *mlsp, int aaa) {
+// Calculates the X and Y per game loop, for this stage of the movelist
+void calculate_move_stage_intern(MoveList *mlsp, int aaa, fixed move_speed_x, fixed move_speed_y) {
// work out the x & y per move. First, opp/adj=tan, so work out the angle
if (mlsp->pos[aaa] == mlsp->pos[aaa + 1]) {
mlsp->xpermove[aaa] = 0;
@@ -196,9 +189,11 @@ void calculate_move_stage(MoveList *mlsp, int aaa) {
mlsp->ypermove[aaa] = newymove;
}
+void calculate_move_stage(MoveList *mlsp, int aaa, int move_speed_x, int move_speed_y) {
+ calculate_move_stage_intern(mlsp, aaa, input_speed_to_fixed(move_speed_x), input_speed_to_fixed(move_speed_y));
+}
-int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int movlst, int nocross, int ignore_walls) {
- int i;
+int find_route(short srcx, short srcy, short xx, short yy, int move_speed_x, int move_speed_y, Bitmap *onscreen, int movlst, int nocross, int ignore_walls) {
_G(wallscreen) = onscreen;
@@ -235,8 +230,11 @@ int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int
AGS::Shared::Debug::Printf("stages: %d\n", _G(num_navpoints));
#endif
- for (i = 0; i < _G(num_navpoints) - 1; i++)
- calculate_move_stage(&_GP(mls)[mlist], i);
+ const fixed fix_speed_x = input_speed_to_fixed(move_speed_x);
+ const fixed fix_speed_y = input_speed_to_fixed(move_speed_y);
+ for (int i = 0; i < _G(num_navpoints) - 1; i++) {
+ calculate_move_stage_intern(&_GP(mls)[mlist], i, fix_speed_x, fix_speed_y);
+ }
_GP(mls)[mlist].fromx = srcx;
_GP(mls)[mlist].fromy = srcy;
@@ -248,7 +246,6 @@ int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int
return mlist;
}
-
} // namespace RouteFinder
} // namespace Engine
} // namespace AGS
diff --git a/engines/ags/engine/ac/route_finder_impl.h b/engines/ags/engine/ac/route_finder_impl.h
index afc341ccc29..7389f66d25e 100644
--- a/engines/ags/engine/ac/route_finder_impl.h
+++ b/engines/ags/engine/ac/route_finder_impl.h
@@ -47,10 +47,8 @@ void set_wallscreen(AGS::Shared::Bitmap *wallscreen);
int can_see_from(int x1, int y1, int x2, int y2);
void get_lastcpos(int &lastcx, int &lastcy);
-void set_route_move_speed(int speed_x, int speed_y);
-
-int find_route(short srcx, short srcy, short xx, short yy, AGS::Shared::Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0);
-void calculate_move_stage(MoveList *mlsp, int aaa);
+int find_route(short srcx, short srcy, short xx, short yy, int move_speed_x, int move_speed_y, AGS::Shared::Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0);
+void calculate_move_stage(MoveList *mlsp, int aaa, int move_speed_x, int move_speed_y);
} // namespace RouteFinder
} // namespace Engine
diff --git a/engines/ags/engine/ac/route_finder_impl_legacy.cpp b/engines/ags/engine/ac/route_finder_impl_legacy.cpp
index f0073f87050..967b1825237 100644
--- a/engines/ags/engine/ac/route_finder_impl_legacy.cpp
+++ b/engines/ags/engine/ac/route_finder_impl_legacy.cpp
@@ -627,24 +627,17 @@ findroutebk:
return 1;
}
-void set_route_move_speed(int speed_x, int speed_y) {
+inline fixed input_speed_to_fixed(int speed_val) {
// negative move speeds like -2 get converted to 1/2
- if (speed_x < 0) {
- _G(move_speed_x) = itofix(1) / (-speed_x);
+ if (speed_val < 0) {
+ return itofix(1) / (-speed_val);
} else {
- _G(move_speed_x) = itofix(speed_x);
- }
-
- if (speed_y < 0) {
- _G(move_speed_y) = itofix(1) / (-speed_y);
- } else {
- _G(move_speed_y) = itofix(speed_y);
+ return itofix(speed_val);
}
}
-// Calculates the X and Y per game loop, for this stage of the
-// movelist
-void calculate_move_stage(MoveList *mlsp, int aaa) {
+// Calculates the X and Y per game loop, for this stage of the movelist
+void calculate_move_stage_intern(MoveList *mlsp, int aaa, fixed move_speed_x, fixed move_speed_y) {
assert(mlsp != nullptr);
// work out the x & y per move. First, opp/adj=tan, so work out the angle
@@ -724,10 +717,13 @@ void calculate_move_stage(MoveList *mlsp, int aaa) {
#endif
}
+void calculate_move_stage(MoveList *mlsp, int aaa, int move_speed_x, int move_speed_y) {
+ calculate_move_stage_intern(mlsp, aaa, input_speed_to_fixed(move_speed_x), input_speed_to_fixed(move_speed_y));
+}
#define MAKE_INTCOORD(x,y) (((unsigned short)x << 16) | ((unsigned short)y))
-int find_route(short srcx, short srcy, short xx, short yy, Bitmap *onscreen, int movlst, int nocross, int ignore_walls) {
+int find_route(short srcx, short srcy, short xx, short yy, int move_speed_x, int move_speed_y, Bitmap *onscreen, int movlst, int nocross, int ignore_walls) {
assert(onscreen != nullptr);
assert((int)_GP(mls).size() > movlst);
assert(pathbackx != nullptr);
@@ -845,8 +841,10 @@ stage_again:
AGS::Shared::Debug::Printf("stages: %d\n", numstages);
#endif
+ const fixed fix_speed_x = input_speed_to_fixed(move_speed_x);
+ const fixed fix_speed_y = input_speed_to_fixed(move_speed_y);
for (aaa = 0; aaa < numstages - 1; aaa++) {
- calculate_move_stage(&_GP(mls)[mlist], aaa);
+ calculate_move_stage_intern(&_GP(mls)[mlist], aaa, fix_speed_x, fix_speed_y);
}
_GP(mls)[mlist].fromx = orisrcx;
diff --git a/engines/ags/engine/ac/route_finder_impl_legacy.h b/engines/ags/engine/ac/route_finder_impl_legacy.h
index be2640250ee..fc29fee79d9 100644
--- a/engines/ags/engine/ac/route_finder_impl_legacy.h
+++ b/engines/ags/engine/ac/route_finder_impl_legacy.h
@@ -45,10 +45,8 @@ void set_wallscreen(AGS::Shared::Bitmap *wallscreen);
int can_see_from(int x1, int y1, int x2, int y2);
void get_lastcpos(int &lastcx, int &lastcy);
-void set_route_move_speed(int speed_x, int speed_y);
-
-int find_route(short srcx, short srcy, short xx, short yy, AGS::Shared::Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0);
-void calculate_move_stage(MoveList *mlsp, int aaa);
+int find_route(short srcx, short srcy, short xx, short yy, int move_speed_x, int move_speed_y, AGS::Shared::Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0);
+void calculate_move_stage(MoveList *mlsp, int aaa, int move_speed_x, int move_speed_y);
} // namespace RouteFinderLegacy
} // namespace Engine
diff --git a/engines/ags/shared/ac/character_info.h b/engines/ags/shared/ac/character_info.h
index d3c4f89d642..93a022b3fd9 100644
--- a/engines/ags/shared/ac/character_info.h
+++ b/engines/ags/shared/ac/character_info.h
@@ -112,6 +112,12 @@ struct CharacterInfo {
int get_blocking_top(); // return Y - BlockingHeight/2
int get_blocking_bottom(); // return Y + BlockingHeight/2
+ // Returns effective x/y walkspeeds for this character
+ void get_effective_walkspeeds(int &walk_speed_x, int &walk_speed_y) const {
+ walk_speed_x = walkspeed;
+ walk_speed_y = ((walkspeed_y == UNIFORM_WALK_SPEED) ? walkspeed : walkspeed_y);
+ }
+
inline bool has_explicit_light() const {
return (flags & CHF_HASLIGHT) != 0;
}
Commit: 0b50067abb702248edea51339e73f677c4864f1c
https://github.com/scummvm/scummvm/commit/0b50067abb702248edea51339e73f677c4864f1c
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2024-03-28T12:01:52+01:00
Commit Message:
AGS: Engine: implement add_waypoint_direct(), fix AddWaypoint's resolution
This fixes Character.AddWaypoint not applying room<->mask resolution conversion,
which result in character's speed being different if room has non 1:1 mask resolution.
Hide calculate_move_stage() inside pathfinder, and expose add_waypoint_direct()
in the pathfinder interface instead.
>From upstream 093354d78849dc3b4f13a244d4400c4e71f7d687
Changed paths:
engines/ags/engine/ac/character.cpp
engines/ags/engine/ac/object.cpp
engines/ags/engine/ac/room.cpp
engines/ags/engine/ac/room.h
engines/ags/engine/ac/route_finder.cpp
engines/ags/engine/ac/route_finder.h
engines/ags/engine/ac/route_finder_impl.cpp
engines/ags/engine/ac/route_finder_impl.h
engines/ags/engine/ac/route_finder_impl_legacy.cpp
engines/ags/engine/ac/route_finder_impl_legacy.h
diff --git a/engines/ags/engine/ac/character.cpp b/engines/ags/engine/ac/character.cpp
index 246da2276cc..2b3ae923285 100644
--- a/engines/ags/engine/ac/character.cpp
+++ b/engines/ags/engine/ac/character.cpp
@@ -153,9 +153,8 @@ void Character_AddWaypoint(CharacterInfo *chaa, int x, int y) {
return;
}
- cmls->pos[cmls->numstage] = (x << 16) + y;
// They're already walking there anyway
- if (cmls->pos[cmls->numstage] == cmls->pos[cmls->numstage - 1])
+ if (cmls->lastx == x && cmls->lasty == y)
return;
int move_speed_x, move_speed_y;
@@ -164,8 +163,17 @@ void Character_AddWaypoint(CharacterInfo *chaa, int x, int y) {
debug_script_warn("Character::AddWaypoint: called for '%s' with walk speed 0", chaa->scrname);
}
- calculate_move_stage(cmls, cmls->numstage - 1, move_speed_x, move_speed_y);
- cmls->numstage++;
+ // There's an issue: the existing movelist is converted to room resolution,
+ // so we do this trick: convert last step to mask resolution, before calling
+ // a pathfinder api, and then we'll convert old and new last step back.
+ // TODO: figure out a better way of processing this!
+ const int last_stage = cmls->numstage - 1;
+ cmls->pos[last_stage] = ((room_to_mask_coord(cmls->pos[last_stage] >> 16)) << 16) | ((room_to_mask_coord(cmls->pos[last_stage] & 0xFFFF)) & 0xFFFF);
+ const int dst_x = room_to_mask_coord(x);
+ const int dst_y = room_to_mask_coord(y);
+ if (add_waypoint_direct(cmls, dst_x, dst_y, move_speed_x, move_speed_y)) {
+ convert_move_path_to_room_resolution(cmls, last_stage, last_stage + 1);
+ }
}
void Character_AnimateEx(CharacterInfo *chaa, int loop, int delay, int repeat,
@@ -1592,13 +1600,7 @@ void walk_character(int chac, int tox, int toy, int ignwal, bool autoWalkAnims)
chin->flags &= ~CHF_MOVENOTWALK;
- int toxPassedIn = tox, toyPassedIn = toy;
- int charX = room_to_mask_coord(chin->x);
- int charY = room_to_mask_coord(chin->y);
- tox = room_to_mask_coord(tox);
- toy = room_to_mask_coord(toy);
-
- if ((tox == charX) && (toy == charY)) {
+ if ((tox == chin->x) && (toy == chin->y)) {
StopMoving(chac);
debug_script_log("%s already at destination, not moving", chin->scrname);
return;
@@ -1626,7 +1628,7 @@ void walk_character(int chac, int tox, int toy, int ignwal, bool autoWalkAnims)
chin->frame = oldframe;
// use toxPassedIn cached variable so the hi-res co-ordinates
// are still displayed as such
- debug_script_log("%s: Start move to %d,%d", chin->scrname, toxPassedIn, toyPassedIn);
+ debug_script_log("%s: Start move to %d,%d", chin->scrname, tox, toy);
int move_speed_x, move_speed_y;
chin->get_effective_walkspeeds(move_speed_x, move_speed_y);
@@ -1634,8 +1636,13 @@ void walk_character(int chac, int tox, int toy, int ignwal, bool autoWalkAnims)
debug_script_warn("MoveCharacter: called for '%s' with walk speed 0", chin->scrname);
}
- int mslot = find_route(charX, charY, tox, toy, move_speed_x, move_speed_y,
- prepare_walkable_areas(chac), chac + CHMLSOFFS, 1, ignwal);
+ // Convert src and dest coords to the mask resolution, for pathfinder
+ const int src_x = room_to_mask_coord(chin->x);
+ const int src_y = room_to_mask_coord(chin->y);
+ const int dst_x = room_to_mask_coord(tox);
+ const int dst_y = room_to_mask_coord(toy);
+
+ int mslot = find_route(src_x, src_y, dst_x, dst_y, move_speed_x, move_speed_y, prepare_walkable_areas(chac), chac + CHMLSOFFS, 1, ignwal);
if (mslot > 0) {
chin->walking = mslot;
diff --git a/engines/ags/engine/ac/object.cpp b/engines/ags/engine/ac/object.cpp
index cf8530a762f..1ac2ec86b82 100644
--- a/engines/ags/engine/ac/object.cpp
+++ b/engines/ags/engine/ac/object.cpp
@@ -413,12 +413,13 @@ void move_object(int objj, int tox, int toy, int spee, int ignwal) {
debug_script_log("Object %d start move to %d,%d", objj, tox, toy);
- int objX = room_to_mask_coord(_G(objs)[objj].x);
- int objY = room_to_mask_coord(_G(objs)[objj].y);
- tox = room_to_mask_coord(tox);
- toy = room_to_mask_coord(toy);
+ // Convert src and dest coords to the mask resolution, for pathfinder
+ const int src_x = room_to_mask_coord(_G(objs)[objj].x);
+ const int src_y = room_to_mask_coord(_G(objs)[objj].y);
+ const int dst_x = room_to_mask_coord(tox);
+ const int dst_y = room_to_mask_coord(toy);
- int mslot = find_route(objX, objY, tox, toy, spee, spee, prepare_walkable_areas(-1), objj + 1, 1, ignwal);
+ int mslot = find_route(src_x, src_y, dst_x, dst_y, spee, spee, prepare_walkable_areas(-1), objj + 1, 1, ignwal);
if (mslot > 0) {
_G(objs)[objj].moving = mslot;
diff --git a/engines/ags/engine/ac/room.cpp b/engines/ags/engine/ac/room.cpp
index ddf4ee0e378..833ae6db21f 100644
--- a/engines/ags/engine/ac/room.cpp
+++ b/engines/ags/engine/ac/room.cpp
@@ -1006,33 +1006,42 @@ AGS_INLINE int mask_to_room_coord(int coord) {
return coord * _GP(thisroom).MaskResolution / _GP(game).GetDataUpscaleMult();
}
-void convert_move_path_to_room_resolution(MoveList *ml) {
+void convert_move_path_to_room_resolution(MoveList *ml, int from_step, int to_step) {
+ if (to_step < 0)
+ to_step = ml->numstage;
+ to_step = CLIP(to_step, 0, ml->numstage - 1);
+ from_step = CLIP(from_step, 0, to_step);
+
+ // If speed is independent from MaskResolution...
if ((_GP(game).options[OPT_WALKSPEEDABSOLUTE] != 0) && _GP(game).GetDataUpscaleMult() > 1) {
- // Speeds are independent from MaskResolution
- for (int i = 0; i < ml->numstage; i++) {
- // ...so they are not multiplied by MaskResolution factor when converted to room coords
+ for (int i = from_step; i <= to_step; i++) { // ...so they are not multiplied by MaskResolution factor when converted to room coords
ml->xpermove[i] = ml->xpermove[i] / _GP(game).GetDataUpscaleMult();
ml->ypermove[i] = ml->ypermove[i] / _GP(game).GetDataUpscaleMult();
}
}
+ // Skip the conversion if these are equal, as they are multiplier and divisor
if (_GP(thisroom).MaskResolution == _GP(game).GetDataUpscaleMult())
return;
- ml->fromx = mask_to_room_coord(ml->fromx);
- ml->fromy = mask_to_room_coord(ml->fromy);
- ml->lastx = mask_to_room_coord(ml->lastx);
- ml->lasty = mask_to_room_coord(ml->lasty);
+ if (from_step == 0) {
+ ml->fromx = mask_to_room_coord(ml->fromx);
+ ml->fromy = mask_to_room_coord(ml->fromy);
+ }
+ if (to_step == ml->numstage - 1) {
+ ml->lastx = mask_to_room_coord(ml->lastx);
+ ml->lasty = mask_to_room_coord(ml->lasty);
+ }
- for (int i = 0; i < ml->numstage; i++) {
+ for (int i = from_step; i <= to_step; i++) {
uint16_t lowPart = mask_to_room_coord(ml->pos[i] & 0x0000ffff);
uint16_t highPart = mask_to_room_coord((ml->pos[i] >> 16) & 0x0000ffff);
ml->pos[i] = ((int)highPart << 16) | (lowPart & 0x0000ffff);
}
+ // If speed is scaling with MaskResolution...
if (_GP(game).options[OPT_WALKSPEEDABSOLUTE] == 0) {
- // Speeds are scaling with MaskResolution
- for (int i = 0; i < ml->numstage; i++) {
+ for (int i = from_step; i <= to_step; i++) {
ml->xpermove[i] = mask_to_room_coord(ml->xpermove[i]);
ml->ypermove[i] = mask_to_room_coord(ml->ypermove[i]);
}
diff --git a/engines/ags/engine/ac/room.h b/engines/ags/engine/ac/room.h
index bfae9f72d97..58174c83e01 100644
--- a/engines/ags/engine/ac/room.h
+++ b/engines/ags/engine/ac/room.h
@@ -70,8 +70,6 @@ void croom_ptr_clear();
// In legacy games with low-res data resolution there's additional conversion
// between data and room coordinates.
//
-// gets multiplier for converting from room mask to data coordinate
-extern AGS_INLINE int get_roommask_to_data_mul();
// coordinate conversion data ---> room ---> mask
extern AGS_INLINE int room_to_mask_coord(int coord);
// coordinate conversion mask ---> room ---> data
@@ -79,7 +77,7 @@ extern AGS_INLINE int mask_to_room_coord(int coord);
struct MoveList;
// Convert move path from room's mask resolution to room resolution
-void convert_move_path_to_room_resolution(MoveList *ml);
+void convert_move_path_to_room_resolution(MoveList *ml, int from_step = 0, int to_step = -1);
} // namespace AGS3
diff --git a/engines/ags/engine/ac/route_finder.cpp b/engines/ags/engine/ac/route_finder.cpp
index ed8882e4fcc..d936f969815 100644
--- a/engines/ags/engine/ac/route_finder.cpp
+++ b/engines/ags/engine/ac/route_finder.cpp
@@ -51,8 +51,8 @@ public:
int find_route(short srcx, short srcy, short xx, short yy, int move_speed_x, int move_speed_y, Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0) override {
return AGS::Engine::RouteFinder::find_route(srcx, srcy, xx, yy, move_speed_x, move_speed_y, onscreen, movlst, nocross, ignore_walls);
}
- void calculate_move_stage(MoveList *mlsp, int aaa, int move_speed_x, int move_speed_y) override {
- AGS::Engine::RouteFinder::calculate_move_stage(mlsp, aaa, move_speed_x, move_speed_y);
+ bool add_waypoint_direct(MoveList *mlsp, short x, short y, int move_speed_x, int move_speed_y) override {
+ return AGS::Engine::RouteFinder::add_waypoint_direct(mlsp, x, y, move_speed_x, move_speed_y);
}
};
@@ -78,8 +78,8 @@ public:
int find_route(short srcx, short srcy, short xx, short yy, int move_speed_x, int move_speed_y, Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0) override {
return AGS::Engine::RouteFinderLegacy::find_route(srcx, srcy, xx, yy, move_speed_x, move_speed_y, onscreen, movlst, nocross, ignore_walls);
}
- void calculate_move_stage(MoveList *mlsp, int aaa, int move_speed_x, int move_speed_y) override {
- AGS::Engine::RouteFinderLegacy::calculate_move_stage(mlsp, aaa, move_speed_x, move_speed_y);
+ bool add_waypoint_direct(MoveList *mlsp, short x, short y, int move_speed_x, int move_speed_y) override {
+ return AGS::Engine::RouteFinder::add_waypoint_direct(mlsp, x, y, move_speed_x, move_speed_y);
}
};
@@ -116,8 +116,8 @@ int find_route(short srcx, short srcy, short xx, short yy, int move_speed_x, int
return _GP(route_finder_impl)->find_route(srcx, srcy, xx, yy, move_speed_x, move_speed_y, onscreen, movlst, nocross, ignore_walls);
}
-void calculate_move_stage(MoveList *mlsp, int aaa, int move_speed_x, int move_speed_y) {
- _GP(route_finder_impl)->calculate_move_stage(mlsp, aaa, move_speed_x, move_speed_y);
+bool add_waypoint_direct(MoveList *mlsp, short x, short y, int move_speed_x, int move_speed_y) {
+ return _GP(route_finder_impl)->add_waypoint_direct(mlsp, x, y, move_speed_x, move_speed_y);
}
} // namespace AGS3
diff --git a/engines/ags/engine/ac/route_finder.h b/engines/ags/engine/ac/route_finder.h
index 5d23971ee60..f52d112737d 100644
--- a/engines/ags/engine/ac/route_finder.h
+++ b/engines/ags/engine/ac/route_finder.h
@@ -46,7 +46,7 @@ public:
virtual int can_see_from(int x1, int y1, int x2, int y2) = 0;
virtual void get_lastcpos(int &lastcx, int &lastcy) = 0;
virtual int find_route(short srcx, short srcy, short xx, short yy, int move_speed_x, int move_speed_y, AGS::Shared::Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0) = 0;
- virtual void calculate_move_stage(MoveList *mlsp, int aaa, int move_speed_x, int move_speed_y) = 0;
+ virtual bool add_waypoint_direct(MoveList *mlsp, short x, short y, int move_speed_x, int move_speed_y) = 0;
};
void init_pathfinder(GameDataVersion game_file_version);
@@ -58,7 +58,8 @@ int can_see_from(int x1, int y1, int x2, int y2);
void get_lastcpos(int &lastcx, int &lastcy);
int find_route(short srcx, short srcy, short xx, short yy, int move_speed_x, int move_speed_y, AGS::Shared::Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0);
-void calculate_move_stage(MoveList *mlsp, int aaa, int move_speed_x, int move_speed_y);
+// Append a waypoint to the move list, skip pathfinding
+bool add_waypoint_direct(MoveList *mlsp, short x, short y, int move_speed_x, int move_speed_y);
} // namespace AGS3
diff --git a/engines/ags/engine/ac/route_finder_impl.cpp b/engines/ags/engine/ac/route_finder_impl.cpp
index b85f2fd5059..fb9bafeaaf5 100644
--- a/engines/ags/engine/ac/route_finder_impl.cpp
+++ b/engines/ags/engine/ac/route_finder_impl.cpp
@@ -117,7 +117,7 @@ inline fixed input_speed_to_fixed(int speed_val) {
}
// Calculates the X and Y per game loop, for this stage of the movelist
-void calculate_move_stage_intern(MoveList *mlsp, int aaa, fixed move_speed_x, fixed move_speed_y) {
+void calculate_move_stage(MoveList *mlsp, int aaa, fixed move_speed_x, fixed move_speed_y) {
// work out the x & y per move. First, opp/adj=tan, so work out the angle
if (mlsp->pos[aaa] == mlsp->pos[aaa + 1]) {
mlsp->xpermove[aaa] = 0;
@@ -189,10 +189,6 @@ void calculate_move_stage_intern(MoveList *mlsp, int aaa, fixed move_speed_x, fi
mlsp->ypermove[aaa] = newymove;
}
-void calculate_move_stage(MoveList *mlsp, int aaa, int move_speed_x, int move_speed_y) {
- calculate_move_stage_intern(mlsp, aaa, input_speed_to_fixed(move_speed_x), input_speed_to_fixed(move_speed_y));
-}
-
int find_route(short srcx, short srcy, short xx, short yy, int move_speed_x, int move_speed_y, Bitmap *onscreen, int movlst, int nocross, int ignore_walls) {
_G(wallscreen) = onscreen;
@@ -233,7 +229,7 @@ int find_route(short srcx, short srcy, short xx, short yy, int move_speed_x, int
const fixed fix_speed_x = input_speed_to_fixed(move_speed_x);
const fixed fix_speed_y = input_speed_to_fixed(move_speed_y);
for (int i = 0; i < _G(num_navpoints) - 1; i++) {
- calculate_move_stage_intern(&_GP(mls)[mlist], i, fix_speed_x, fix_speed_y);
+ calculate_move_stage(&_GP(mls)[mlist], i, fix_speed_x, fix_speed_y);
}
_GP(mls)[mlist].fromx = srcx;
@@ -246,6 +242,20 @@ int find_route(short srcx, short srcy, short xx, short yy, int move_speed_x, int
return mlist;
}
+bool add_waypoint_direct(MoveList *mlsp, short x, short y, int move_speed_x, int move_speed_y) {
+ if (mlsp->numstage >= MAXNEEDSTAGES)
+ return false;
+
+ const fixed fix_speed_x = input_speed_to_fixed(move_speed_x);
+ const fixed fix_speed_y = input_speed_to_fixed(move_speed_y);
+ mlsp->pos[mlsp->numstage] = MAKE_INTCOORD(x, y);
+ calculate_move_stage(mlsp, mlsp->numstage - 1, fix_speed_x, fix_speed_y);
+ mlsp->numstage++;
+ mlsp->lastx = x;
+ mlsp->lasty = y;
+ return true;
+}
+
} // namespace RouteFinder
} // namespace Engine
} // namespace AGS
diff --git a/engines/ags/engine/ac/route_finder_impl.h b/engines/ags/engine/ac/route_finder_impl.h
index 7389f66d25e..03683611662 100644
--- a/engines/ags/engine/ac/route_finder_impl.h
+++ b/engines/ags/engine/ac/route_finder_impl.h
@@ -48,7 +48,7 @@ int can_see_from(int x1, int y1, int x2, int y2);
void get_lastcpos(int &lastcx, int &lastcy);
int find_route(short srcx, short srcy, short xx, short yy, int move_speed_x, int move_speed_y, AGS::Shared::Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0);
-void calculate_move_stage(MoveList *mlsp, int aaa, int move_speed_x, int move_speed_y);
+bool add_waypoint_direct(MoveList *mlsp, short x, short y, int move_speed_x, int move_speed_y);
} // namespace RouteFinder
} // namespace Engine
diff --git a/engines/ags/engine/ac/route_finder_impl_legacy.cpp b/engines/ags/engine/ac/route_finder_impl_legacy.cpp
index 967b1825237..15b8ba40a2e 100644
--- a/engines/ags/engine/ac/route_finder_impl_legacy.cpp
+++ b/engines/ags/engine/ac/route_finder_impl_legacy.cpp
@@ -637,7 +637,7 @@ inline fixed input_speed_to_fixed(int speed_val) {
}
// Calculates the X and Y per game loop, for this stage of the movelist
-void calculate_move_stage_intern(MoveList *mlsp, int aaa, fixed move_speed_x, fixed move_speed_y) {
+void calculate_move_stage(MoveList *mlsp, int aaa, fixed move_speed_x, fixed move_speed_y) {
assert(mlsp != nullptr);
// work out the x & y per move. First, opp/adj=tan, so work out the angle
@@ -717,10 +717,6 @@ void calculate_move_stage_intern(MoveList *mlsp, int aaa, fixed move_speed_x, fi
#endif
}
-void calculate_move_stage(MoveList *mlsp, int aaa, int move_speed_x, int move_speed_y) {
- calculate_move_stage_intern(mlsp, aaa, input_speed_to_fixed(move_speed_x), input_speed_to_fixed(move_speed_y));
-}
-
#define MAKE_INTCOORD(x,y) (((unsigned short)x << 16) | ((unsigned short)y))
int find_route(short srcx, short srcy, short xx, short yy, int move_speed_x, int move_speed_y, Bitmap *onscreen, int movlst, int nocross, int ignore_walls) {
@@ -844,7 +840,7 @@ stage_again:
const fixed fix_speed_x = input_speed_to_fixed(move_speed_x);
const fixed fix_speed_y = input_speed_to_fixed(move_speed_y);
for (aaa = 0; aaa < numstages - 1; aaa++) {
- calculate_move_stage_intern(&_GP(mls)[mlist], aaa, fix_speed_x, fix_speed_y);
+ calculate_move_stage(&_GP(mls)[mlist], aaa, fix_speed_x, fix_speed_y);
}
_GP(mls)[mlist].fromx = orisrcx;
@@ -868,6 +864,20 @@ stage_again:
#endif
}
+bool add_waypoint_direct(MoveList *mlsp, short x, short y, int move_speed_x, int move_speed_y) {
+ if (mlsp->numstage >= MAXNEEDSTAGES)
+ return false;
+
+ const fixed fix_speed_x = input_speed_to_fixed(move_speed_x);
+ const fixed fix_speed_y = input_speed_to_fixed(move_speed_y);
+ mlsp->pos[mlsp->numstage] = MAKE_INTCOORD(x, y);
+ calculate_move_stage(mlsp, mlsp->numstage - 1, fix_speed_x, fix_speed_y);
+ mlsp->numstage++;
+ mlsp->lastx = x;
+ mlsp->lasty = y;
+ return true;
+}
+
void shutdown_pathfinder() {
if (pathbackx != nullptr) {
free(pathbackx);
diff --git a/engines/ags/engine/ac/route_finder_impl_legacy.h b/engines/ags/engine/ac/route_finder_impl_legacy.h
index fc29fee79d9..cd7ce505a22 100644
--- a/engines/ags/engine/ac/route_finder_impl_legacy.h
+++ b/engines/ags/engine/ac/route_finder_impl_legacy.h
@@ -46,7 +46,7 @@ int can_see_from(int x1, int y1, int x2, int y2);
void get_lastcpos(int &lastcx, int &lastcy);
int find_route(short srcx, short srcy, short xx, short yy, int move_speed_x, int move_speed_y, AGS::Shared::Bitmap *onscreen, int movlst, int nocross = 0, int ignore_walls = 0);
-void calculate_move_stage(MoveList *mlsp, int aaa, int move_speed_x, int move_speed_y);
+bool add_waypoint_direct(MoveList *mlsp, short x, short y, int move_speed_x, int move_speed_y);
} // namespace RouteFinderLegacy
} // namespace Engine
Commit: 2e5560fd1e8732f8cd78e68c6e30abe3fe3d90e8
https://github.com/scummvm/scummvm/commit/2e5560fd1e8732f8cd78e68c6e30abe3fe3d90e8
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2024-03-28T12:01:52+01:00
Commit Message:
AGS: Remove no longer used move_speed global vars
Changed paths:
engines/ags/engine/ac/route_finder_impl.cpp
engines/ags/engine/ac/route_finder_impl_legacy.cpp
engines/ags/globals.h
diff --git a/engines/ags/engine/ac/route_finder_impl.cpp b/engines/ags/engine/ac/route_finder_impl.cpp
index fb9bafeaaf5..129bd3e4a54 100644
--- a/engines/ags/engine/ac/route_finder_impl.cpp
+++ b/engines/ags/engine/ac/route_finder_impl.cpp
@@ -133,7 +133,7 @@ void calculate_move_stage(MoveList *mlsp, int aaa, fixed move_speed_x, fixed mov
// Special case for vertical and horizontal movements
if (ourx == destx) {
mlsp->xpermove[aaa] = 0;
- mlsp->ypermove[aaa] = _G(move_speed_y);
+ mlsp->ypermove[aaa] = move_speed_y;
if (desty < oury)
mlsp->ypermove[aaa] = -mlsp->ypermove[aaa];
@@ -141,7 +141,7 @@ void calculate_move_stage(MoveList *mlsp, int aaa, fixed move_speed_x, fixed mov
}
if (oury == desty) {
- mlsp->xpermove[aaa] = _G(move_speed_x);
+ mlsp->xpermove[aaa] = move_speed_x;
mlsp->ypermove[aaa] = 0;
if (destx < ourx)
mlsp->xpermove[aaa] = -mlsp->xpermove[aaa];
@@ -154,19 +154,19 @@ void calculate_move_stage(MoveList *mlsp, int aaa, fixed move_speed_x, fixed mov
fixed useMoveSpeed;
- if (_G(move_speed_x) == _G(move_speed_y)) {
- useMoveSpeed = _G(move_speed_x);
+ if (move_speed_x == move_speed_y) {
+ useMoveSpeed = move_speed_x;
} else {
// different X and Y move speeds
// the X proportion of the movement is (x / (x + y))
fixed xproportion = fixdiv(xdist, (xdist + ydist));
- if (_G(move_speed_x) > _G(move_speed_y)) {
+ if (move_speed_x > move_speed_y) {
// speed = y + ((1 - xproportion) * (x - y))
- useMoveSpeed = _G(move_speed_y) + fixmul(xproportion, _G(move_speed_x) - _G(move_speed_y));
+ useMoveSpeed = move_speed_y + fixmul(xproportion, move_speed_x - move_speed_y);
} else {
// speed = x + (xproportion * (y - x))
- useMoveSpeed = _G(move_speed_x) + fixmul(itofix(1) - xproportion, _G(move_speed_y) - _G(move_speed_x));
+ useMoveSpeed = move_speed_x + fixmul(itofix(1) - xproportion, move_speed_y - move_speed_x);
}
}
diff --git a/engines/ags/engine/ac/route_finder_impl_legacy.cpp b/engines/ags/engine/ac/route_finder_impl_legacy.cpp
index 15b8ba40a2e..c45be220664 100644
--- a/engines/ags/engine/ac/route_finder_impl_legacy.cpp
+++ b/engines/ags/engine/ac/route_finder_impl_legacy.cpp
@@ -655,7 +655,7 @@ void calculate_move_stage(MoveList *mlsp, int aaa, fixed move_speed_x, fixed mov
// Special case for vertical and horizontal movements
if (ourx == destx) {
mlsp->xpermove[aaa] = 0;
- mlsp->ypermove[aaa] = _G(move_speed_y);
+ mlsp->ypermove[aaa] = move_speed_y;
if (desty < oury)
mlsp->ypermove[aaa] = -mlsp->ypermove[aaa];
@@ -663,7 +663,7 @@ void calculate_move_stage(MoveList *mlsp, int aaa, fixed move_speed_x, fixed mov
}
if (oury == desty) {
- mlsp->xpermove[aaa] = _G(move_speed_x);
+ mlsp->xpermove[aaa] = move_speed_x;
mlsp->ypermove[aaa] = 0;
if (destx < ourx)
mlsp->xpermove[aaa] = -mlsp->xpermove[aaa];
@@ -676,19 +676,19 @@ void calculate_move_stage(MoveList *mlsp, int aaa, fixed move_speed_x, fixed mov
fixed useMoveSpeed;
- if (_G(move_speed_x) == _G(move_speed_y)) {
- useMoveSpeed = _G(move_speed_x);
+ if (move_speed_x == move_speed_y) {
+ useMoveSpeed = move_speed_x;
} else {
// different X and Y move speeds
// the X proportion of the movement is (x / (x + y))
fixed xproportion = fixdiv(xdist, (xdist + ydist));
- if (_G(move_speed_x) > _G(move_speed_y)) {
+ if (move_speed_x > move_speed_y) {
// speed = y + ((1 - xproportion) * (x - y))
- useMoveSpeed = _G(move_speed_y) + fixmul(xproportion, _G(move_speed_x) - _G(move_speed_y));
+ useMoveSpeed = move_speed_y + fixmul(xproportion, move_speed_x - move_speed_y);
} else {
// speed = x + (xproportion * (y - x))
- useMoveSpeed = _G(move_speed_x) + fixmul(itofix(1) - xproportion, _G(move_speed_y) - _G(move_speed_x));
+ useMoveSpeed = move_speed_x + fixmul(itofix(1) - xproportion, move_speed_y - move_speed_x);
}
}
diff --git a/engines/ags/globals.h b/engines/ags/globals.h
index 421b80a29f1..a40febbbba3 100644
--- a/engines/ags/globals.h
+++ b/engines/ags/globals.h
@@ -1235,7 +1235,6 @@ public:
int32_t *_navpoints;
Navigation *_nav;
int _num_navpoints = 0;
- fixed _move_speed_x = 0, _move_speed_y = 0;
AGS::Shared::Bitmap *_wallscreen = nullptr;
int _lastcx = 0, _lastcy = 0;
std::unique_ptr<IRouteFinder> *_route_finder_impl;
Commit: de31994dd0d46b870421afffbe1f5ea8700ec670
https://github.com/scummvm/scummvm/commit/de31994dd0d46b870421afffbe1f5ea8700ec670
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2024-03-28T12:01:52+01:00
Commit Message:
AGS: Engine: safeguard Overlay.Create in case of non-existing sprite
>From upstream 57e21b06b99b53f38d0491e5cb17991738f552bd
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 0f4a76aa4fd..a39c9746858 100644
--- a/engines/ags/engine/ac/overlay.cpp
+++ b/engines/ags/engine/ac/overlay.cpp
@@ -213,6 +213,11 @@ int Overlay_GetValid(ScriptOverlay *scover) {
}
ScreenOverlay *Overlay_CreateGraphicCore(bool room_layer, int x, int y, int slot, bool transparent, bool clone) {
+ if (!_GP(spriteset).DoesSpriteExist(slot)) {
+ debug_script_warn("Overlay.CreateGraphical: sprite %d is invalid", slot);
+ return nullptr;
+ }
+
data_to_game_coords(&x, &y);
size_t overid;
// We clone only dynamic sprites, because it makes no sense to clone normal ones
Commit: d30db56310d15788cba6cf2180a3b923dd2b50bf
https://github.com/scummvm/scummvm/commit/d30db56310d15788cba6cf2180a3b923dd2b50bf
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2024-03-28T12:02:39+01:00
Commit Message:
AGS: Updated build version (3.6.0.57)
Partially from upstream eaec1e8f3843a719a32640a18f88fae88f8d29f4
Changed paths:
engines/ags/shared/core/def_version.h
diff --git a/engines/ags/shared/core/def_version.h b/engines/ags/shared/core/def_version.h
index 82725fe8f64..78ddfe82d41 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.56"
+#define ACI_VERSION_STR "3.6.0.57"
#if defined (RC_INVOKED) // for MSVC resource compiler
-#define ACI_VERSION_MSRC_DEF 3.6.0.56
+#define ACI_VERSION_MSRC_DEF 3.6.0.57
#endif
#define SPECIAL_VERSION ""
Commit: bb72a094047d23a759dba8f2eb1f5afdb91e99ab
https://github.com/scummvm/scummvm/commit/bb72a094047d23a759dba8f2eb1f5afdb91e99ab
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2024-03-28T12:02:39+01:00
Commit Message:
AGS: Engine: fixed "lowest compatible save version"
This was broken by a typo made in fac1a5b
>From upstream 44a3fcd03b4df0f16faee4ce70ca2c4c7b0469ab
Changed paths:
engines/ags/engine/game/savegame.cpp
diff --git a/engines/ags/engine/game/savegame.cpp b/engines/ags/engine/game/savegame.cpp
index f73409eb53a..a9e2ee40a38 100644
--- a/engines/ags/engine/game/savegame.cpp
+++ b/engines/ags/engine/game/savegame.cpp
@@ -238,7 +238,9 @@ HSaveError ReadDescription_v321(Stream *in, SavegameVersion &svg_ver, SavegameDe
else
SkipSaveImage(in);
- const Version low_compat_version(3, 2, 0, 1123);
+ // This is the lowest legacy save format we support,
+ // judging by the engine code received from CJ.
+ const Version low_compat_version(3, 2, 0, 1103);
String version_str = String::FromStream(in);
Version eng_version(version_str);
if (eng_version > _G(EngineVersion) || eng_version < low_compat_version) {
Commit: 27aceb588810d6d17571d52f0cd066d915274326
https://github.com/scummvm/scummvm/commit/27aceb588810d6d17571d52f0cd066d915274326
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2024-03-28T12:02:40+01:00
Commit Message:
AGS: Engine: fixed text parser in Dialog Options in "new key handling" mode
from upstream b9c3bb51e6f437ee574f550956b34a672b47b5e5
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 36ecd2469e0..1334d5c27b5 100644
--- a/engines/ags/engine/ac/dialog.cpp
+++ b/engines/ags/engine/ac/dialog.cpp
@@ -986,7 +986,7 @@ bool DialogOptions::RunKey(const KeyInput &ki) {
}
needRedraw = true;
return true; // continue running loop
- } else if ((agskey >= eAGSKeyCodeSpace) || (agskey == eAGSKeyCodeReturn) || (agskey == eAGSKeyCodeBackspace)) {
+ } else if ((ki.UChar > 0) || (agskey == eAGSKeyCodeReturn) || (agskey == eAGSKeyCodeBackspace)) {
parserInput->OnKeyPress(ki);
if (!parserInput->IsActivated) {
needRedraw = true;
Commit: 9d0e82c4d317c66dfaf8aee6b3733d4b70b48cbd
https://github.com/scummvm/scummvm/commit/9d0e82c4d317c66dfaf8aee6b3733d4b70b48cbd
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2024-03-28T12:02:40+01:00
Commit Message:
AGS: Engine: fixed camera may fail to restore its position in the room
Changed paths:
engines/ags/engine/game/savegame.cpp
diff --git a/engines/ags/engine/game/savegame.cpp b/engines/ags/engine/game/savegame.cpp
index a9e2ee40a38..386c7c0b958 100644
--- a/engines/ags/engine/game/savegame.cpp
+++ b/engines/ags/engine/game/savegame.cpp
@@ -406,8 +406,9 @@ void RestoreViewportsAndCameras(const RestoredData &r_data) {
cam->Lock();
else
cam->Release();
- cam->SetAt(cam_dat.Left, cam_dat.Top);
+ // Set size first, or offset position may clamp to the room
cam->SetSize(Size(cam_dat.Width, cam_dat.Height));
+ cam->SetAt(cam_dat.Left, cam_dat.Top);
}
for (size_t i = 0; i < r_data.Viewports.size(); ++i) {
const auto &view_dat = r_data.Viewports[i];
Commit: 59e2d4955ee91a63b3bd6dd78e08191a892fd164
https://github.com/scummvm/scummvm/commit/59e2d4955ee91a63b3bd6dd78e08191a892fd164
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2024-03-28T12:02:40+01:00
Commit Message:
AGS: Common: fix all_buttons_disabled's type, for clarity
from upstream a60eb5d2f484c1783f4a52f46dfcae94f5e07865
Changed paths:
engines/ags/engine/ac/gui.cpp
engines/ags/globals.h
engines/ags/shared/gui/gui_defines.h
diff --git a/engines/ags/engine/ac/gui.cpp b/engines/ags/engine/ac/gui.cpp
index c66931b6ef0..42d508f637e 100644
--- a/engines/ags/engine/ac/gui.cpp
+++ b/engines/ags/engine/ac/gui.cpp
@@ -435,14 +435,9 @@ void unexport_gui_controls(int ee) {
}
void update_gui_disabled_status() {
- // update GUI display status (perhaps we've gone into
- // an interface disabled state)
- int all_buttons_was = _G(all_buttons_disabled);
- _G(all_buttons_disabled) = -1;
-
- if (!IsInterfaceEnabled()) {
- _G(all_buttons_disabled) = GUI::Options.DisabledStyle;
- }
+ // update GUI display status (perhaps we've gone into an interface disabled state)
+ const GuiDisableStyle all_buttons_was = _G(all_buttons_disabled);
+ _G(all_buttons_disabled) = IsInterfaceEnabled() ? kGuiDis_Undefined : GUI::Options.DisabledStyle;
if (all_buttons_was != _G(all_buttons_disabled)) {
// Mark guis for redraw and reset control-under-mouse detection
diff --git a/engines/ags/globals.h b/engines/ags/globals.h
index a40febbbba3..62c0916d8fa 100644
--- a/engines/ags/globals.h
+++ b/engines/ags/globals.h
@@ -1033,7 +1033,8 @@ public:
*/
int _guis_need_update = 1;
- int _all_buttons_disabled = -1, _gui_inv_pic = -1;
+ AGS::Shared::GuiDisableStyle _all_buttons_disabled = AGS::Shared::kGuiDis_Undefined;
+ int _gui_inv_pic = -1;
/**@}*/
diff --git a/engines/ags/shared/gui/gui_defines.h b/engines/ags/shared/gui/gui_defines.h
index a6fa2d11b19..97d0bc9521b 100644
--- a/engines/ags/shared/gui/gui_defines.h
+++ b/engines/ags/shared/gui/gui_defines.h
@@ -190,11 +190,13 @@ enum GuiSvgVersion {
kGuiSvgVersion_36025
};
+// Style of GUI drawing in disabled state
enum GuiDisableStyle {
- kGuiDis_Greyout = 0,
- kGuiDis_Blackout = 1,
- kGuiDis_Unchanged = 2,
- kGuiDis_Off = 3
+ kGuiDis_Undefined = -1, // this is for marking not-disabled state
+ kGuiDis_Greyout = 0, // paint "gisabled" effect over controls
+ kGuiDis_Blackout = 1, // invisible controls (but guis are shown
+ kGuiDis_Unchanged = 2, // no change, display normally
+ kGuiDis_Off = 3 // fully invisible guis
};
// Global GUI options
Commit: ecc76427750f29857b01ce6cea26ad1462834baf
https://github.com/scummvm/scummvm/commit/ecc76427750f29857b01ce6cea26ad1462834baf
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2024-03-28T12:03:32+01:00
Commit Message:
AGS: Engine: fixed kGuiDis_Blackout in "draw controls as textures" mode
partially from upstream 21664626e69e559a14c9159ceaa7a10eef681867
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 e63cdb6b0ff..9df39b98bf7 100644
--- a/engines/ags/engine/ac/draw.cpp
+++ b/engines/ags/engine/ac/draw.cpp
@@ -1872,7 +1872,7 @@ void draw_fps(const Rect &viewport) {
// Draw GUI controls as separate sprites
void draw_gui_controls(GUIMain &gui) {
- if (_G(all_buttons_disabled) && (GUI::Options.DisabledStyle == kGuiDis_Blackout))
+ if (_G(all_buttons_disabled >= 0) && (GUI::Options.DisabledStyle == kGuiDis_Blackout))
return; // don't draw GUI controls
int draw_index = _GP(guiobjddbref)[gui.ID];
Commit: 79f3b6eec5ee0e2cbdc8e5dcf2415abbcbca9955
https://github.com/scummvm/scummvm/commit/79f3b6eec5ee0e2cbdc8e5dcf2415abbcbca9955
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2024-03-28T12:03:32+01:00
Commit Message:
AGS: Engine: for Software mode fixed disabled controls leaving traces on gui
from upstream fb15befa124a9b3202263eb79e20e0060de5410a
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 9df39b98bf7..1cd92cba3f7 100644
--- a/engines/ags/engine/ac/draw.cpp
+++ b/engines/ags/engine/ac/draw.cpp
@@ -934,6 +934,7 @@ Bitmap *recycle_bitmap(Bitmap *bimp, int coldep, int wid, int hit, bool make_tra
// same colour depth, width and height -> reuse
if ((bimp->GetColorDepth() == coldep) && (bimp->GetWidth() == wid)
&& (bimp->GetHeight() == hit)) {
+ bimp->ResetClip();
if (make_transparent) {
bimp->ClearTransparent();
}
Commit: f09519834c3cd0adc96b566f4290c52e52c0b12a
https://github.com/scummvm/scummvm/commit/f09519834c3cd0adc96b566f4290c52e52c0b12a
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2024-03-28T12:03:33+01:00
Commit Message:
AGS: Engine: updated unload_game_file(), fix few things not reset
This is not as important in case of game quit, as it is in case of RunAGSGame().
* Adjusted order of data release in unload_game_file() to be in sync with 3.6.1 (as much as possible).
* Fixed GameSetupStruct not releasing some of the data in Free().
Noteably this fixes font infos to not getting fully reset on RunAGSGame().
from upstream 1cc9d22095d0ee90541ce506fa54c538de7ca4ad
Changed paths:
engines/ags/engine/ac/game.cpp
engines/ags/engine/ac/game_state.cpp
engines/ags/engine/main/quit.cpp
engines/ags/shared/ac/game_setup_struct.cpp
diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp
index 575a995c0ed..ed316da0be2 100644
--- a/engines/ags/engine/ac/game.cpp
+++ b/engines/ags/engine/ac/game.cpp
@@ -367,15 +367,17 @@ void free_do_once_tokens() {
// Free all the memory associated with the game
void unload_game_file() {
+ dispose_game_drawdata();
+ // NOTE: fonts should be freed prior to stopping plugins,
+ // as plugins may provide font renderer interface.
+ free_all_fonts();
close_translation();
- _GP(play).FreeViewportsAndCameras();
-
- _GP(charextra).clear();
- _GP(mls).clear();
-
- dispose_game_drawdata();
+ ccRemoveAllSymbols();
+ ccUnregisterAllObjects();
+ pl_stop_plugins();
+ // Free all script instances and script modules
delete _G(gameinstFork);
delete _G(gameinst);
_G(gameinstFork) = nullptr;
@@ -407,8 +409,10 @@ void unload_game_file() {
_GP(runDialogOptionCloseFunc).moduleHasFunction.resize(0);
_G(numScriptModules) = 0;
+ _GP(charextra).clear();
+ _GP(mls).clear();
_GP(views).clear();
-
+ // Free lipsync
if (_G(splipsync) != nullptr) {
for (int i = 0; i < _G(numLipLines); ++i) {
free(_G(splipsync)[i].endtimeoffs);
@@ -432,25 +436,19 @@ void unload_game_file() {
delete[] _G(scrGui);
_G(scrGui) = nullptr;
- free_all_fonts();
-
- ccRemoveAllSymbols();
- ccUnregisterAllObjects();
- pl_stop_plugins();
-
- free_do_once_tokens();
- _GP(play).gui_draw_order.clear();
+ remove_screen_overlay(-1);
resetRoomStatuses();
+ _GP(thisroom).Free();
// free game struct last because it contains object counts
_GP(game).Free();
-}
-
-
-
-
+ _GP(play).Free();
+ // Reset all resource caches
+ // IMPORTANT: this is hard reset, including locked items
+ _GP(spriteset).Reset();
+}
const char *Game_GetGlobalStrings(int index) {
if ((index < 0) || (index >= MAXGLOBALSTRINGS))
diff --git a/engines/ags/engine/ac/game_state.cpp b/engines/ags/engine/ac/game_state.cpp
index 750d3b5a0f8..22081cfde8d 100644
--- a/engines/ags/engine/ac/game_state.cpp
+++ b/engines/ags/engine/ac/game_state.cpp
@@ -67,8 +67,11 @@ GameState::GameState() {
}
void GameState::Free() {
+ _GP(play).FreeProperties();
+ _GP(play).FreeViewportsAndCameras();
+ do_once_tokens.clear();
raw_drawing_surface.reset();
- FreeProperties();
+ gui_draw_order.clear();
}
bool GameState::IsAutoRoomViewport() const {
diff --git a/engines/ags/engine/main/quit.cpp b/engines/ags/engine/main/quit.cpp
index 24dc0d219f1..765d91f1371 100644
--- a/engines/ags/engine/main/quit.cpp
+++ b/engines/ags/engine/main/quit.cpp
@@ -143,9 +143,6 @@ QuitReason quit_check_for_error_state(const char *qmsg, String &errmsg, String &
}
void quit_release_data() {
- resetRoomStatuses();
- _GP(thisroom).Free();
- _GP(play).Free();
unload_game_file();
}
diff --git a/engines/ags/shared/ac/game_setup_struct.cpp b/engines/ags/shared/ac/game_setup_struct.cpp
index b2436234325..6291d22f7ef 100644
--- a/engines/ags/shared/ac/game_setup_struct.cpp
+++ b/engines/ags/shared/ac/game_setup_struct.cpp
@@ -50,16 +50,25 @@ GameSetupStruct::~GameSetupStruct() {
void GameSetupStruct::Free() {
GameSetupStructBase::Free();
+ fonts.clear();
+ mcurs.clear();
+
intrChar.clear();
charScripts.clear();
+ charProps.clear();
numcharacters = 0;
// TODO: find out if it really needs to begin with 1 here?
- for (size_t i = 1; i < (size_t)MAX_INV; i++)
+ for (size_t i = 1; i < (size_t)MAX_INV; i++) {
intrInv[i].reset();
+ invProps[i].clear();
+ }
invScripts.clear();
numinvitems = 0;
+ viewNames.clear();
+ dialogScriptNames.clear();
+
roomNames.clear();
roomNumbers.clear();
roomCount = 0;
@@ -67,8 +76,7 @@ void GameSetupStruct::Free() {
audioClips.clear();
audioClipTypes.clear();
- charProps.clear();
- viewNames.clear();
+ SpriteInfos.clear();
}
// Assigns font info parameters using legacy flags value read from the game data
Commit: 6c8e783e4a7ec5cfc8f2edc108aea67d2b9f7bfb
https://github.com/scummvm/scummvm/commit/6c8e783e4a7ec5cfc8f2edc108aea67d2b9f7bfb
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2024-03-28T12:03:33+01:00
Commit Message:
AGS: Engine: add hotspot id assertion to GetHotspotProperty
This is made in line with previously added AssertObject().
from upstream 99f94c469636522bd2d89923901659476d816577
Changed paths:
engines/ags/engine/ac/global_hotspot.cpp
engines/ags/engine/ac/hotspot.cpp
engines/ags/engine/ac/hotspot.h
diff --git a/engines/ags/engine/ac/global_hotspot.cpp b/engines/ags/engine/ac/global_hotspot.cpp
index fc9392a3446..d76de2e3e65 100644
--- a/engines/ags/engine/ac/global_hotspot.cpp
+++ b/engines/ags/engine/ac/global_hotspot.cpp
@@ -139,10 +139,14 @@ void RunHotspotInteraction(int hotspothere, int mood) {
}
int GetHotspotProperty(int hss, const char *property) {
+ if (!AssertHotspot("GetHotspotProperty", hss))
+ return 0;
return get_int_property(_GP(thisroom).Hotspots[hss].Properties, _G(croom)->hsProps[hss], property);
}
void GetHotspotPropertyText(int item, const char *property, char *bufer) {
+ if (!AssertHotspot("GetHotspotPropertyText", item))
+ return;
get_text_property(_GP(thisroom).Hotspots[item].Properties, _G(croom)->hsProps[item], property, bufer);
}
diff --git a/engines/ags/engine/ac/hotspot.cpp b/engines/ags/engine/ac/hotspot.cpp
index 9a50a308081..725fdc54554 100644
--- a/engines/ags/engine/ac/hotspot.cpp
+++ b/engines/ags/engine/ac/hotspot.cpp
@@ -28,6 +28,7 @@
#include "ags/engine/ac/room.h"
#include "ags/engine/ac/room_status.h"
#include "ags/engine/ac/string.h"
+#include "ags/engine/debugging/debug_log.h"
#include "ags/shared/game/room_struct.h"
#include "ags/shared/gfx/bitmap.h"
#include "ags/shared/gui/gui_main.h"
@@ -42,6 +43,13 @@ namespace AGS3 {
using namespace AGS::Shared;
+bool AssertHotspot(const char *apiname, int hot_id) {
+ if ((hot_id >= 0) && (static_cast<uint32_t>(hot_id) < _GP(thisroom).HotspotCount))
+ return true;
+ debug_script_warn("%s: invalid hotspot id %d (range is 0..%d)", apiname, hot_id, _GP(thisroom).HotspotCount - 1);
+ return false;
+}
+
void Hotspot_SetEnabled(ScriptHotspot *hss, int newval) {
if (newval)
EnableHotspot(hss->id);
diff --git a/engines/ags/engine/ac/hotspot.h b/engines/ags/engine/ac/hotspot.h
index 2559c5189fc..d19ac3fb1b8 100644
--- a/engines/ags/engine/ac/hotspot.h
+++ b/engines/ags/engine/ac/hotspot.h
@@ -26,6 +26,9 @@
namespace AGS3 {
+// Asserts the hotspot ID is valid in the current room,
+// if not then prints a warning to the log; returns assertion result
+bool AssertHotspot(const char *apiname, int hot_id);
void Hotspot_SetEnabled(ScriptHotspot *hss, int newval);
int Hotspot_GetEnabled(ScriptHotspot *hss);
int Hotspot_GetID(ScriptHotspot *hss);
Commit: 2bcaa19756fa64e3119195fb34c630dd462e7892
https://github.com/scummvm/scummvm/commit/2bcaa19756fa64e3119195fb34c630dd462e7892
Author: Walter Agazzi (walter.agazzi at protonmail.com)
Date: 2024-03-28T12:03:33+01:00
Commit Message:
AGS: fix all_buttons_disabled check condition
completes commit c77989f2603cc1ff6d8ca27bf62668b16707bcb6
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 1cd92cba3f7..90c21b1556a 100644
--- a/engines/ags/engine/ac/draw.cpp
+++ b/engines/ags/engine/ac/draw.cpp
@@ -1993,7 +1993,7 @@ void draw_gui_and_overlays() {
// If not adding gui controls as textures, simply move the resulting sprlist to render
if (!draw_controls_as_textures ||
- (_G(all_buttons_disabled) && (GUI::Options.DisabledStyle == kGuiDis_Blackout))) {
+ (_G(all_buttons_disabled >= 0) && (GUI::Options.DisabledStyle == kGuiDis_Blackout))) {
draw_sprite_list(false);
put_sprite_list_on_screen(false);
return;
More information about the Scummvm-git-logs
mailing list