[Scummvm-git-logs] scummvm master -> 007baa9541c8e5831316ec0efabf275f111ee925
dreammaster
noreply at scummvm.org
Thu Apr 14 04:55:31 UTC 2022
This automated email contains information about 8 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
aeddd232e0 AGS: Removed animating buttons limit
14209fafed AGS: Removed arbitrary character followers limit
b13b75712f AGS: Updated build version (3.6.0.19)
596ddd0be6 AGS: Added some utf-8 utils and moved ConvertUtf8ToAscii to StrUtil
1ec52936d2 AGS: Added utf8->wcstr conversions to StrUtils
0e0063bb6b AGS: String.AppendChar, ReplaceChar, Chars[] support unicode
9fe89e4f1d AGS: String.Format treats %c as possibly unicode
007baa9541 AGS: Restore proper text format in close_translation()
Commit: aeddd232e0e743eedb479e2bf7229289845107ce
https://github.com/scummvm/scummvm/commit/aeddd232e0e743eedb479e2bf7229289845107ce
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-13T21:55:18-07:00
Commit Message:
AGS: Removed animating buttons limit
>From upstream 484f6d3f44c7dbb361ddeebd8bb46862760501bc
Changed paths:
engines/ags/engine/ac/button.cpp
engines/ags/engine/ac/button.h
engines/ags/engine/ac/game.cpp
engines/ags/engine/ac/runtime_defines.h
engines/ags/engine/game/savegame_components.cpp
engines/ags/engine/game/savegame_v321.cpp
engines/ags/engine/main/game_run.cpp
engines/ags/globals.cpp
engines/ags/globals.h
engines/ags/shared/gui/gui_object.cpp
engines/ags/shared/gui/gui_object.h
diff --git a/engines/ags/engine/ac/button.cpp b/engines/ags/engine/ac/button.cpp
index e63f7c8ed4c..937138758df 100644
--- a/engines/ags/engine/ac/button.cpp
+++ b/engines/ags/engine/ac/button.cpp
@@ -56,28 +56,27 @@ void Button_Animate(GUIButton *butt, int view, int loop, int speed, int repeat)
// if it's already animating, stop it
FindAndRemoveButtonAnimation(guin, objn);
- if (_G(numAnimButs) >= MAX_ANIMATING_BUTTONS)
- quit("!AnimateButton: too many animating GUI buttons at once");
-
int buttonId = _GP(guis)[guin].GetControlID(objn);
_GP(guibuts)[buttonId].PushedImage = 0;
_GP(guibuts)[buttonId].MouseOverImage = 0;
- _G(animbuts)[_G(numAnimButs)].ongui = guin;
- _G(animbuts)[_G(numAnimButs)].onguibut = objn;
- _G(animbuts)[_G(numAnimButs)].buttonid = buttonId;
- _G(animbuts)[_G(numAnimButs)].view = view;
- _G(animbuts)[_G(numAnimButs)].loop = loop;
- _G(animbuts)[_G(numAnimButs)].speed = speed;
- _G(animbuts)[_G(numAnimButs)].repeat = repeat;
- _G(animbuts)[_G(numAnimButs)].frame = -1;
- _G(animbuts)[_G(numAnimButs)].wait = 0;
- _G(numAnimButs)++;
+ AnimatingGUIButton abtn;
+ abtn.ongui = guin;
+ abtn.onguibut = objn;
+ abtn.buttonid = buttonId;
+ abtn.view = view;
+ abtn.loop = loop;
+ abtn.speed = speed;
+ abtn.repeat = repeat;
+ abtn.frame = -1;
+ abtn.wait = 0;
+ _GP(animbuts).push_back(abtn);
// launch into the first frame
- if (UpdateAnimatingButton(_G(numAnimButs) - 1)) {
- debug_script_warn("AnimateButton: no frames to animate");
- StopButtonAnimation(_G(numAnimButs) - 1);
+ if (UpdateAnimatingButton(_GP(animbuts).size() - 1)) {
+ debug_script_warn("AnimateButton: no frames to animate (button: %s, view: %d, loop: %d)",
+ butt->GetScriptName().GetCStr(), view, loop);
+ StopButtonAnimation(_GP(animbuts).size() - 1);
}
}
@@ -194,56 +193,72 @@ void Button_SetTextColor(GUIButton *butt, int newcol) {
// ** start animating buttons code
+size_t GetAnimatingButtonCount() {
+ return _GP(animbuts).size();
+}
+
+AnimatingGUIButton *GetAnimatingButtonByIndex(int idxn) {
+ return idxn >= 0 && (size_t)idxn < _GP(animbuts).size() ?
+ &_GP(animbuts)[idxn] : nullptr;
+}
+
+void AddButtonAnimation(const AnimatingGUIButton &abtn) {
+ _GP(animbuts).push_back(abtn);
+}
+
// returns 1 if animation finished
int UpdateAnimatingButton(int bu) {
- if (_G(animbuts)[bu].wait > 0) {
- _G(animbuts)[bu].wait--;
+ AnimatingGUIButton &abtn = _GP(animbuts)[bu];
+
+ if (abtn.wait > 0) {
+ abtn.wait--;
return 0;
}
- ViewStruct *tview = &_GP(views)[_G(animbuts)[bu].view];
+ ViewStruct *tview = &_GP(views)[abtn.view];
- _G(animbuts)[bu].frame++;
+ abtn.frame++;
- if (_G(animbuts)[bu].frame >= tview->loops[_G(animbuts)[bu].loop].numFrames) {
- if (tview->loops[_G(animbuts)[bu].loop].RunNextLoop()) {
+ if (abtn.frame >= tview->loops[abtn.loop].numFrames) {
+ if (tview->loops[abtn.loop].RunNextLoop()) {
// go to next loop
- _G(animbuts)[bu].loop++;
- _G(animbuts)[bu].frame = 0;
- } else if (_G(animbuts)[bu].repeat) {
- _G(animbuts)[bu].frame = 0;
+ abtn.loop++;
+ abtn.frame = 0;
+ } else if (abtn.repeat) {
+ abtn.frame = 0;
// multi-loop anim, go back
- while ((_G(animbuts)[bu].loop > 0) &&
- (tview->loops[_G(animbuts)[bu].loop - 1].RunNextLoop()))
- _G(animbuts)[bu].loop--;
+ while ((abtn.loop > 0) &&
+ (tview->loops[abtn.loop - 1].RunNextLoop()))
+ abtn.loop--;
} else
return 1;
}
- CheckViewFrame(_G(animbuts)[bu].view, _G(animbuts)[bu].loop, _G(animbuts)[bu].frame);
+ CheckViewFrame(abtn.view, abtn.loop, abtn.frame);
// update the button's image
- _GP(guibuts)[_G(animbuts)[bu].buttonid].Image = tview->loops[_G(animbuts)[bu].loop].frames[_G(animbuts)[bu].frame].pic;
- _GP(guibuts)[_G(animbuts)[bu].buttonid].CurrentImage = _GP(guibuts)[_G(animbuts)[bu].buttonid].Image;
- _GP(guibuts)[_G(animbuts)[bu].buttonid].PushedImage = 0;
- _GP(guibuts)[_G(animbuts)[bu].buttonid].MouseOverImage = 0;
- _GP(guibuts)[_G(animbuts)[bu].buttonid].NotifyParentChanged();
+ _GP(guibuts)[abtn.buttonid].Image = tview->loops[abtn.loop].frames[abtn.frame].pic;
+ _GP(guibuts)[abtn.buttonid].CurrentImage = _GP(guibuts)[abtn.buttonid].Image;
+ _GP(guibuts)[abtn.buttonid].PushedImage = 0;
+ _GP(guibuts)[abtn.buttonid].MouseOverImage = 0;
+ _GP(guibuts)[abtn.buttonid].NotifyParentChanged();
- _G(animbuts)[bu].wait = _G(animbuts)[bu].speed + tview->loops[_G(animbuts)[bu].loop].frames[_G(animbuts)[bu].frame].speed;
+ abtn.wait = abtn.speed + tview->loops[abtn.loop].frames[abtn.frame].speed;
return 0;
}
void StopButtonAnimation(int idxn) {
- _G(numAnimButs)--;
- for (int aa = idxn; aa < _G(numAnimButs); aa++) {
- _G(animbuts)[aa] = _G(animbuts)[aa + 1];
- }
+ _GP(animbuts).erase(_GP(animbuts).begin() + idxn);
+}
+
+void RemoveAllButtonAnimations() {
+ _GP(animbuts).clear();
}
// Returns the index of the AnimatingGUIButton object corresponding to the
// given button ID; returns -1 if no such animation exists
int FindAnimatedButton(int guin, int objn) {
- for (int i = 0; i < _G(numAnimButs); ++i) {
- if (_G(animbuts)[i].ongui == guin && _G(animbuts)[i].onguibut == objn)
+ for (size_t i = 0; i < _GP(animbuts).size(); ++i) {
+ if (_GP(animbuts)[i].ongui == guin && _GP(animbuts)[i].onguibut == objn)
return i;
}
return -1;
@@ -254,6 +269,7 @@ void FindAndRemoveButtonAnimation(int guin, int objn) {
if (idx >= 0)
StopButtonAnimation(idx);
}
+
// ** end animating buttons code
void Button_Click(GUIButton *butt, int mbut) {
@@ -269,17 +285,17 @@ bool Button_IsAnimating(GUIButton *butt) {
// zero-based index and 0 in case of no animation.
int Button_GetAnimView(GUIButton *butt) {
int idx = FindAnimatedButton(butt->ParentId, butt->Id);
- return idx >= 0 ? _G(animbuts)[idx].view + 1 : 0;
+ return idx >= 0 ? _GP(animbuts)[idx].view + 1 : 0;
}
int Button_GetAnimLoop(GUIButton *butt) {
int idx = FindAnimatedButton(butt->ParentId, butt->Id);
- return idx >= 0 ? _G(animbuts)[idx].loop : 0;
+ return idx >= 0 ? _GP(animbuts)[idx].loop : 0;
}
int Button_GetAnimFrame(GUIButton *butt) {
int idx = FindAnimatedButton(butt->ParentId, butt->Id);
- return idx >= 0 ? _G(animbuts)[idx].frame : 0;
+ return idx >= 0 ? _GP(animbuts)[idx].frame : 0;
}
int Button_GetTextAlignment(GUIButton *butt) {
diff --git a/engines/ags/engine/ac/button.h b/engines/ags/engine/ac/button.h
index 98ddd7a3b7e..b0ecbcc652b 100644
--- a/engines/ags/engine/ac/button.h
+++ b/engines/ags/engine/ac/button.h
@@ -28,6 +28,7 @@
namespace AGS3 {
using AGS::Shared::GUIButton;
+struct AnimatingGUIButton;
void Button_Animate(GUIButton *butt, int view, int loop, int speed, int repeat);
const char *Button_GetText_New(GUIButton *butt);
@@ -48,8 +49,12 @@ int Button_GetTextColor(GUIButton *butt);
void Button_SetTextColor(GUIButton *butt, int newcol);
int UpdateAnimatingButton(int bu);
-void StopButtonAnimation(int idxn);
-void FindAndRemoveButtonAnimation(int guin, int objn);
+size_t GetAnimatingButtonCount();
+AnimatingGUIButton *GetAnimatingButtonByIndex(int idxn);
+void AddButtonAnimation(const AnimatingGUIButton &abtn);
+void StopButtonAnimation(int idxn);
+void FindAndRemoveButtonAnimation(int guin, int objn);
+void RemoveAllButtonAnimations();
} // namespace AGS3
diff --git a/engines/ags/engine/ac/game.cpp b/engines/ags/engine/ac/game.cpp
index e82ba0a3bf8..124331b6e0d 100644
--- a/engines/ags/engine/ac/game.cpp
+++ b/engines/ags/engine/ac/game.cpp
@@ -24,6 +24,7 @@
#include "ags/shared/ac/common.h"
#include "ags/shared/ac/view.h"
#include "ags/engine/ac/audio_channel.h"
+#include "ags/engine/ac/button.h"
#include "ags/engine/ac/character.h"
#include "ags/engine/ac/character_cache.h"
#include "ags/shared/ac/dialog_topic.h"
diff --git a/engines/ags/engine/ac/runtime_defines.h b/engines/ags/engine/ac/runtime_defines.h
index c88fda4c634..1e27e341e36 100644
--- a/engines/ags/engine/ac/runtime_defines.h
+++ b/engines/ags/engine/ac/runtime_defines.h
@@ -145,7 +145,6 @@ const int LegacyRoomVolumeFactor = 30;
#define MAX_DYNAMIC_SURFACES 20
-#define MAX_ANIMATING_BUTTONS 15
#define RESTART_POINT_SAVE_GAME_NUMBER 999
#define MAX_OPEN_SCRIPT_FILES 10
diff --git a/engines/ags/engine/game/savegame_components.cpp b/engines/ags/engine/game/savegame_components.cpp
index 68782e4cdd1..8111b8fbede 100644
--- a/engines/ags/engine/game/savegame_components.cpp
+++ b/engines/ags/engine/game/savegame_components.cpp
@@ -21,9 +21,10 @@
#include "ags/lib/std/map.h"
#include "ags/shared/ac/audio_clip_type.h"
-#include "ags/engine/ac/character.h"
#include "ags/shared/ac/common.h"
#include "ags/shared/ac/dialog_topic.h"
+#include "ags/engine/ac/button.h"
+#include "ags/engine/ac/character.h"
#include "ags/engine/ac/draw.h"
#include "ags/engine/ac/dynamic_sprite.h"
#include "ags/engine/ac/game.h"
@@ -567,9 +568,10 @@ HSaveError WriteGUI(Stream *out) {
// Animated buttons
WriteFormatTag(out, "AnimatedButtons");
- out->WriteInt32(_G(numAnimButs));
- for (int i = 0; i < _G(numAnimButs); ++i)
- _G(animbuts)[i].WriteToFile(out);
+ size_t num_abuts = GetAnimatingButtonCount();
+ out->WriteInt32(num_abuts);
+ for (size_t i = 0; i < num_abuts; ++i)
+ GetAnimatingButtonByIndex(i)->WriteToFile(out);
return HSaveError::None();
}
@@ -629,13 +631,13 @@ HSaveError ReadGUI(Stream *in, int32_t cmp_ver, const PreservedParams &pp, Resto
// Animated buttons
if (!AssertFormatTagStrict(err, in, "AnimatedButtons"))
return err;
+ RemoveAllButtonAnimations();
int anim_count = in->ReadInt32();
- if (!AssertCompatLimit(err, anim_count, MAX_ANIMATING_BUTTONS, "animated buttons"))
- return err;
- _G(numAnimButs) = anim_count;
- for (int i = 0; i < _G(numAnimButs); ++i)
- _G(animbuts)[i].ReadFromFile(in);
- return err;
+ for (int i = 0; i < anim_count; ++i) {
+ AnimatingGUIButton abut;
+ abut.ReadFromFile(in);
+ AddButtonAnimation(abut);
+ } return err;
}
HSaveError WriteInventory(Stream *out) {
diff --git a/engines/ags/engine/game/savegame_v321.cpp b/engines/ags/engine/game/savegame_v321.cpp
index 82321432b30..a5e0792cd15 100644
--- a/engines/ags/engine/game/savegame_v321.cpp
+++ b/engines/ags/engine/game/savegame_v321.cpp
@@ -32,6 +32,7 @@
#include "ags/engine/ac/character_extras.h"
#include "ags/shared/ac/common.h"
#include "ags/shared/ac/dialog_topic.h"
+#include "ags/engine/ac/button.h"
#include "ags/engine/ac/dynamic_sprite.h"
#include "ags/engine/ac/game.h"
#include "ags/shared/ac/game_setup_struct.h"
@@ -211,10 +212,12 @@ static void restore_game_more_dynamic_values(Stream *in) {
_G(game_paused) = in->ReadInt32();
}
-static void ReadAnimatedButtons_Aligned(Stream *in) {
+void ReadAnimatedButtons_Aligned(Stream *in, int num_abuts) {
AlignedStream align_s(in, Shared::kAligned_Read);
- for (int i = 0; i < _G(numAnimButs); ++i) {
- _G(animbuts)[i].ReadFromFile(&align_s);
+ for (int i = 0; i < num_abuts; ++i) {
+ AnimatingGUIButton abtn;
+ abtn.ReadFromFile(&align_s);
+ AddButtonAnimation(abtn);
align_s.Reset();
}
}
@@ -229,8 +232,9 @@ static HSaveError restore_game_gui(Stream *in, int numGuisWas) {
return new SavegameError(kSvgErr_GameContentAssertion, "Mismatching number of GUI.");
}
- _G(numAnimButs) = in->ReadInt32();
- ReadAnimatedButtons_Aligned(in);
+ RemoveAllButtonAnimations();
+ int anim_count = in->ReadInt32();
+ ReadAnimatedButtons_Aligned(in, anim_count);
return HSaveError::None();
}
diff --git a/engines/ags/engine/main/game_run.cpp b/engines/ags/engine/main/game_run.cpp
index 5830f9dc780..6957ad27aef 100644
--- a/engines/ags/engine/main/game_run.cpp
+++ b/engines/ags/engine/main/game_run.cpp
@@ -580,10 +580,10 @@ static void game_loop_update_animated_buttons() {
// update animating GUI buttons
// this bit isn't in update_stuff because it always needs to
// happen, even when the game is paused
- for (int aa = 0; aa < _G(numAnimButs); aa++) {
- if (UpdateAnimatingButton(aa)) {
- StopButtonAnimation(aa);
- aa--;
+ for (size_t i = 0; i < GetAnimatingButtonCount(); ++i) {
+ if (UpdateAnimatingButton(i)) {
+ StopButtonAnimation(i);
+ i--;
}
}
}
diff --git a/engines/ags/globals.cpp b/engines/ags/globals.cpp
index b160bb3aabc..bc226ee9b56 100644
--- a/engines/ags/globals.cpp
+++ b/engines/ags/globals.cpp
@@ -126,7 +126,7 @@ Globals::Globals() {
_scrAudioChannel = new ScriptAudioChannel[MAX_GAME_CHANNELS];
// button.cpp globals
- _animbuts = new AnimatingGUIButton[MAX_ANIMATING_BUTTONS];
+ _animbuts = new std::vector<AnimatingGUIButton>();
// cc_instance.cpp globals
_GlobalReturnValue = new RuntimeScriptValue();
@@ -387,7 +387,7 @@ Globals::~Globals() {
delete[] _scrAudioChannel;
// button.cpp globals
- delete[] _animbuts;
+ delete _animbuts;
// cc_instance.cpp globals
delete _GlobalReturnValue;
diff --git a/engines/ags/globals.h b/engines/ags/globals.h
index 7e2e6b46f43..c656b992117 100644
--- a/engines/ags/globals.h
+++ b/engines/ags/globals.h
@@ -106,7 +106,6 @@ class SplitLines;
class TTFFontRenderer;
class WFNFontRenderer;
-struct ActiveDisplaySetting;
struct AGSDeSerializer;
struct AGSPlatformDriver;
struct AGSStaticObject;
@@ -324,8 +323,7 @@ public:
* @{
*/
- AnimatingGUIButton *_animbuts;
- int _numAnimButs = 0;
+ std::vector<AnimatingGUIButton> *_animbuts;
/**@}*/
diff --git a/engines/ags/shared/gui/gui_object.cpp b/engines/ags/shared/gui/gui_object.cpp
index ba05e51cab4..a52aeabffd9 100644
--- a/engines/ags/shared/gui/gui_object.cpp
+++ b/engines/ags/shared/gui/gui_object.cpp
@@ -41,6 +41,10 @@ GUIObject::GUIObject() {
_scEventCount = 0;
}
+String GUIObject::GetScriptName() const {
+ return Name;
+}
+
int GUIObject::GetEventCount() const {
return _scEventCount;
}
diff --git a/engines/ags/shared/gui/gui_object.h b/engines/ags/shared/gui/gui_object.h
index 4d74e1675e6..346ba7f7238 100644
--- a/engines/ags/shared/gui/gui_object.h
+++ b/engines/ags/shared/gui/gui_object.h
@@ -46,6 +46,8 @@ public:
GUIObject();
virtual ~GUIObject() {}
+ String GetScriptName() const;
+
String GetEventArgs(int event) const;
int GetEventCount() const;
String GetEventName(int event) const;
Commit: 14209fafed0493cfcf85d53b564ab178046ad184
https://github.com/scummvm/scummvm/commit/14209fafed0493cfcf85d53b564ab178046ad184
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-13T21:55:19-07:00
Commit Message:
AGS: Removed arbitrary character followers limit
>From upstream c64850badd610b3ce90821a080e7e6b04d65193e
Changed paths:
engines/ags/engine/ac/character_info_engine.cpp
engines/ags/engine/main/update.cpp
engines/ags/engine/main/update.h
engines/ags/shared/ac/character_info.h
diff --git a/engines/ags/engine/ac/character_info_engine.cpp b/engines/ags/engine/ac/character_info_engine.cpp
index 1e069308e9b..14fdae64f36 100644
--- a/engines/ags/engine/ac/character_info_engine.cpp
+++ b/engines/ags/engine/ac/character_info_engine.cpp
@@ -63,7 +63,7 @@ int CharacterInfo::get_blocking_bottom() {
return y + 3;
}
-void CharacterInfo::UpdateMoveAndAnim(int &char_index, CharacterExtras *chex, int &numSheep, int *followingAsSheep) {
+void CharacterInfo::UpdateMoveAndAnim(int &char_index, CharacterExtras *chex, std::vector<int> &followingAsSheep) {
int res;
if (on != 1) return;
@@ -102,7 +102,7 @@ void CharacterInfo::UpdateMoveAndAnim(int &char_index, CharacterExtras *chex, in
return; // must be careful not to screw things up
}
- update_character_follower(char_index, numSheep, followingAsSheep, doing_nothing);
+ update_character_follower(char_index, followingAsSheep, doing_nothing);
update_character_idle(chex, doing_nothing);
@@ -372,14 +372,12 @@ int CharacterInfo::update_character_animating(int &aa, int &doing_nothing) {
return 0;
}
-void CharacterInfo::update_character_follower(int &aa, int &numSheep, int *followingAsSheep, int &doing_nothing) {
+void CharacterInfo::update_character_follower(int &aa, std::vector<int> &followingAsSheep, int &doing_nothing) {
if ((following >= 0) && (followinfo == FOLLOW_ALWAYSONTOP)) {
// an always-on-top follow
- if (numSheep >= MAX_SHEEP)
- quit("too many sheep");
- followingAsSheep[numSheep] = aa;
- numSheep++;
+ followingAsSheep.push_back(aa);
}
+
// not moving, but should be following another character
else if ((following >= 0) && (doing_nothing == 1)) {
short distaway = (followinfo >> 8) & 0x00ff;
diff --git a/engines/ags/engine/main/update.cpp b/engines/ags/engine/main/update.cpp
index 506cf5eecfc..4847bf06252 100644
--- a/engines/ags/engine/main/update.cpp
+++ b/engines/ags/engine/main/update.cpp
@@ -197,7 +197,7 @@ void update_shadow_areas() {
}
}
-void update_character_move_and_anim(int &numSheep, int *followingAsSheep) {
+void update_character_move_and_anim(std::vector<int> &followingAsSheep) {
// move & animate characters
for (int aa = 0; aa < _GP(game).numcharacters; aa++) {
if (_GP(game).chars[aa].on != 1) continue;
@@ -205,14 +205,14 @@ void update_character_move_and_anim(int &numSheep, int *followingAsSheep) {
CharacterInfo *chi = &_GP(game).chars[aa];
CharacterExtras *chex = &_G(charextra)[aa];
- chi->UpdateMoveAndAnim(aa, chex, numSheep, followingAsSheep);
+ chi->UpdateMoveAndAnim(aa, chex, followingAsSheep);
}
}
-void update_following_exactly_characters(int &numSheep, int *followingAsSheep) {
+void update_following_exactly_characters(const std::vector<int> &followingAsSheep) {
// update location of all following_exactly characters
- for (int aa = 0; aa < numSheep; aa++) {
- CharacterInfo *chi = &_GP(game).chars[followingAsSheep[aa]];
+ for (size_t i = 0; i < followingAsSheep.size(); ++i) {
+ CharacterInfo *chi = &_GP(game).chars[followingAsSheep[i]];
chi->UpdateFollowingExactlyCharacter();
}
@@ -431,12 +431,11 @@ void update_stuff() {
_G(our_eip) = 22;
- int numSheep = 0;
- int followingAsSheep[MAX_SHEEP];
+ std::vector<int> followingAsSheep;
- update_character_move_and_anim(numSheep, followingAsSheep);
+ update_character_move_and_anim(followingAsSheep);
- update_following_exactly_characters(numSheep, followingAsSheep);
+ update_following_exactly_characters(followingAsSheep);
_G(our_eip) = 23;
diff --git a/engines/ags/engine/main/update.h b/engines/ags/engine/main/update.h
index 9ae7c7de6f2..af804c571a9 100644
--- a/engines/ags/engine/main/update.h
+++ b/engines/ags/engine/main/update.h
@@ -24,8 +24,6 @@
namespace AGS3 {
-#define MAX_SHEEP 30 // sheep == follower
-
int do_movelist_move(short *mlnum, int *xx, int *yy);
void update_stuff();
diff --git a/engines/ags/shared/ac/character_info.h b/engines/ags/shared/ac/character_info.h
index 1f4ae82b648..9f856544c22 100644
--- a/engines/ags/shared/ac/character_info.h
+++ b/engines/ags/shared/ac/character_info.h
@@ -22,6 +22,7 @@
#ifndef AGS_SHARED_AC_CHARACTER_INFO_H
#define AGS_SHARED_AC_CHARACTER_INFO_H
+#include "ags/lib/std/vector.h"
#include "ags/shared/ac/common_defines.h" // constants
namespace AGS3 {
@@ -120,14 +121,14 @@ struct CharacterInfo {
//
// [IKM] 2016-08-26: these methods should NOT be in CharacterInfo class,
// bit in distinct runtime character class!
- void UpdateMoveAndAnim(int &char_index, CharacterExtras *chex, int &numSheep, int *followingAsSheep);
+ void UpdateMoveAndAnim(int &char_index, CharacterExtras *chex, std::vector<int> &followingAsSheep);
void UpdateFollowingExactlyCharacter();
int update_character_walking(CharacterExtras *chex);
void update_character_moving(int &char_index, CharacterExtras *chex, int &doing_nothing);
int update_character_animating(int &char_index, int &doing_nothing);
void update_character_idle(CharacterExtras *chex, int &doing_nothing);
- void update_character_follower(int &char_index, int &numSheep, int *followingAsSheep, int &doing_nothing);
+ void update_character_follower(int &char_index, std::vector<int> &followingAsSheep, int &doing_nothing);
void ReadFromFile(Shared::Stream *in);
void WriteToFile(Shared::Stream *out);
Commit: b13b75712f47c0317cca0d614ab42fafe9b255dc
https://github.com/scummvm/scummvm/commit/b13b75712f47c0317cca0d614ab42fafe9b255dc
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-13T21:55:19-07:00
Commit Message:
AGS: Updated build version (3.6.0.19)
>From upstream 230795414b676a2c1e84ae72488af18b90f71692
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 9da371f8590..a47916eb3d3 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.18"
+#define ACI_VERSION_STR "3.6.0.19"
#if defined (RC_INVOKED) // for MSVC resource compiler
-#define ACI_VERSION_MSRC_DEF 3.6.0.18
+#define ACI_VERSION_MSRC_DEF 3.6.0.19
#endif
#define SPECIAL_VERSION ""
Commit: 596ddd0be6f65a35a8041502616a29c9168af5ba
https://github.com/scummvm/scummvm/commit/596ddd0be6f65a35a8041502616a29c9168af5ba
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-13T21:55:19-07:00
Commit Message:
AGS: Added some utf-8 utils and moved ConvertUtf8ToAscii to StrUtil
>From upstream 307d40d4b6808ed906e918dd6dcc0332b1d6baa2
Changed paths:
A engines/ags/shared/util/utf8.h
engines/ags/engine/ac/translation.cpp
engines/ags/shared/util/string_utils.cpp
engines/ags/shared/util/string_utils.h
diff --git a/engines/ags/engine/ac/translation.cpp b/engines/ags/engine/ac/translation.cpp
index ac6704789d1..a00adef38da 100644
--- a/engines/ags/engine/ac/translation.cpp
+++ b/engines/ags/engine/ac/translation.cpp
@@ -29,9 +29,11 @@
#include "ags/engine/ac/runtime_defines.h"
#include "ags/engine/ac/translation.h"
#include "ags/shared/ac/words_dictionary.h"
+#include "ags/shared/core/asset_manager.h"
#include "ags/shared/debugging/out.h"
#include "ags/shared/game/tra_file.h"
#include "ags/shared/util/stream.h"
+#include "ags/shared/util/string_utils.h"
#include "ags/shared/core/asset_manager.h"
#include "ags/globals.h"
@@ -39,13 +41,6 @@ namespace AGS3 {
using namespace AGS::Shared;
-// TODO: Since ScummVM can't use uconvert, this is a dummy implementation for now
-const char *convert_utf8_to_ascii(const char *mbstr, const char *loc_name) {
- _G(mbbuf).resize(strlen(mbstr) + 1);
- strcpy(&_G(mbbuf)[0], mbstr);
- return &_G(mbbuf)[0];
-}
-
void close_translation() {
_GP(transtree).clear();
_GP(trans) = Translation();
@@ -124,9 +119,11 @@ bool init_translation(const String &lang, const String &fallback_lang) {
_GP(trans).StrOptions["gameencoding"];
if (!key_enc.IsEmpty()) {
StringMap conv_map;
+ std::vector<char> ascii; // ascii buffer
for (const auto &item : _GP(trans).Dict) {
- String key = convert_utf8_to_ascii(item._key.GetCStr(), key_enc.GetCStr());
- conv_map.insert(std::make_pair(key, item._value));
+ ascii.resize(item._key.GetLength()); // ascii len will be <= utf-8 len
+ StrUtil::ConvertUtf8ToAscii(item._key.GetCStr(), key_enc.GetCStr(), &ascii[0], ascii.size());
+ conv_map.insert(std::make_pair(String(&ascii[0]), item._value));
}
_GP(trans).Dict = conv_map;
}
diff --git a/engines/ags/shared/util/string_utils.cpp b/engines/ags/shared/util/string_utils.cpp
index e06dbf8c622..44c61176194 100644
--- a/engines/ags/shared/util/string_utils.cpp
+++ b/engines/ags/shared/util/string_utils.cpp
@@ -20,6 +20,7 @@
*/
#include "ags/shared/util/string_utils.h"
+#include "ags/shared/util/utf8.h"
#include "ags/shared/core/platform.h"
#include "ags/lib/std/regex.h"
#include "ags/shared/util/math.h"
@@ -220,6 +221,25 @@ void StrUtil::WriteStringMap(const StringMap &map, Stream *out) {
}
}
+size_t StrUtil::ConvertUtf8ToAscii(const char *mbstr, const char *loc_name, char *out_cstr, size_t out_sz) {
+ // TODO: later consider using C++11 conversion methods
+ // First convert utf-8 string into widestring;
+ std::vector<wchar_t> wcsbuf; // widechar buffer
+ wcsbuf.resize(Utf8::GetLength(mbstr) + 1);
+ // NOTE: we don't use mbstowcs, because unfortunately ".utf-8" locale
+ // is not normally supported on all systems (e.g. Windows 7 and earlier)
+ for (size_t at = 0, chr_sz = 0; *mbstr; mbstr += chr_sz, ++at) {
+ Utf8::Rune r;
+ chr_sz = Utf8::GetChar(mbstr, Utf8::UtfSz, &r);
+ wcsbuf[at] = static_cast<wchar_t>(r);
+ }
+ // Then convert widestring to single-byte string using specified locale
+ setlocale(LC_CTYPE, loc_name);
+ size_t res_sz = wcstombs(out_cstr, &wcsbuf[0], out_sz);
+ setlocale(LC_CTYPE, "");
+ return res_sz;
+}
+
} // namespace Shared
} // namespace AGS
} // namespace AGS3
diff --git a/engines/ags/shared/util/string_utils.h b/engines/ags/shared/util/string_utils.h
index 2cf9255c667..c08268858f7 100644
--- a/engines/ags/shared/util/string_utils.h
+++ b/engines/ags/shared/util/string_utils.h
@@ -83,6 +83,10 @@ void WriteCStr(const String &s, Stream *out);
void ReadStringMap(StringMap &map, Stream *in);
void WriteStringMap(const StringMap &map, Stream *out);
+// Convert utf-8 string to ascii/ansi representation;
+ // writes into out_cstr buffer limited by out_sz bytes; returns bytes written.
+size_t ConvertUtf8ToAscii(const char *mbstr, const char *loc_name, char *out_cstr, size_t out_sz);
+
} // namespace StrUtil
} // namespace Shared
} // namespace AGS
diff --git a/engines/ags/shared/util/utf8.h b/engines/ags/shared/util/utf8.h
new file mode 100644
index 00000000000..33bad60dbdb
--- /dev/null
+++ b/engines/ags/shared/util/utf8.h
@@ -0,0 +1,115 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+ //=============================================================================
+ //
+ // UTF-8 utilities.
+ // Based on utf8 code from https://c9x.me/git/irc.git/tree/irc.c
+ //
+ //=============================================================================
+
+#ifndef AGS_SHARED_UTIL_UTF8_H
+#define AGS_SHARED_UTIL_UTF8_H
+
+#include "ags/lib/std/algorithm.h"
+#include "ags/shared/core/types.h"
+
+namespace AGS3 {
+namespace Utf8 {
+
+typedef int32_t Rune;
+const size_t UtfSz = 4;
+const Rune RuneInvalid = 0xFFFD;
+
+const unsigned char utfbyte[UtfSz + 1] = { 0x80, 0, 0xC0, 0xE0, 0xF0 };
+const unsigned char utfmask[UtfSz + 1] = { 0xC0, 0x80, 0xE0, 0xF0, 0xF8 };
+const Rune utfmin[UtfSz + 1] = { 0, 0, 0x80, 0x800, 0x10000 };
+const Rune utfmax[UtfSz + 1] = { 0x10FFFF, 0x7F, 0x7FF, 0xFFFF, 0x10FFFF };
+
+
+inline size_t Validate(Rune *u, size_t i) {
+ if (*u < utfmin[i] || *u > utfmax[i] || (0xD800 <= *u && *u <= 0xDFFF))
+ *u = RuneInvalid;
+ for (i = 1; *u > utfmax[i]; ++i)
+ ;
+ return i;
+}
+
+inline Rune DecodeByte(unsigned char c, size_t *i) {
+ for (*i = 0; *i < UtfSz + 1; ++(*i))
+ if ((c & utfmask[*i]) == utfbyte[*i])
+ return c & ~utfmask[*i];
+ return 0;
+}
+
+inline char EncodeByte(Rune u, size_t i) {
+ return utfbyte[i] | (u & ~utfmask[i]);
+}
+
+// Read a single utf8 codepoint from the c-string;
+// returns codepoint's size in bytes (may be used to advance string pos)
+inline size_t GetChar(const char *c, size_t clen, Rune *u) {
+ size_t i, j, len, type;
+ Rune udecoded;
+ *u = RuneInvalid;
+ if (!clen || !*c)
+ return 0;
+ udecoded = DecodeByte(c[0], &len);
+ if (len < 1 || len > UtfSz)
+ return 1;
+ for (i = 1, j = 1; i < clen && j < len; ++i, ++j) {
+ udecoded = (udecoded << 6) | DecodeByte(c[i], &type);
+ if (type != 0)
+ return j;
+ }
+ if (j < len)
+ return 0;
+ *u = udecoded;
+ Validate(u, len);
+ return len;
+}
+
+// Convert utf8 codepoint to the string representation and write to the buffer
+inline size_t SetChar(Rune u, char *c, size_t clen) {
+ size_t len, i;
+ len = Validate(&u, 0);
+ if (len > UtfSz || len > clen)
+ return 0;
+ for (i = len - 1; i != 0; --i) {
+ c[i] = EncodeByte(u, 0);
+ u >>= 6;
+ }
+ c[0] = EncodeByte(u, len);
+ return len;
+}
+
+// Calculates utf8 string length in characters
+inline size_t GetLength(const char *c) {
+ size_t len = 0;
+ Rune r;
+ for (size_t chr_sz = 0; (chr_sz = GetChar(c, UtfSz, &r)) > 0; c += chr_sz, ++len);
+ return len;
+}
+
+} // namespace Utf8
+} // namespace AGS3
+
+#endif
Commit: 1ec52936d278e7356bf7529a223c782c1f41ae19
https://github.com/scummvm/scummvm/commit/1ec52936d278e7356bf7529a223c782c1f41ae19
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-13T21:55:19-07:00
Commit Message:
AGS: Added utf8->wcstr conversions to StrUtils
>From upstream 4c2bb8ba25fa651175a854b7f0117bfb37a76d4e
Changed paths:
engines/ags/shared/util/string_utils.cpp
engines/ags/shared/util/string_utils.h
diff --git a/engines/ags/shared/util/string_utils.cpp b/engines/ags/shared/util/string_utils.cpp
index 44c61176194..66bbc07f7bd 100644
--- a/engines/ags/shared/util/string_utils.cpp
+++ b/engines/ags/shared/util/string_utils.cpp
@@ -240,6 +240,28 @@ size_t StrUtil::ConvertUtf8ToAscii(const char *mbstr, const char *loc_name, char
return res_sz;
}
+size_t StrUtil::ConvertUtf8ToWstr(const char *mbstr, wchar_t *out_wcstr, size_t out_sz) {
+ size_t len = 0;
+ for (size_t mb_sz = 1; *mbstr && (mb_sz > 0) && (len < out_sz);
+ mbstr += mb_sz, ++out_wcstr, ++len) {
+ Utf8::Rune r;
+ mb_sz = Utf8::GetChar(mbstr, Utf8::UtfSz, &r);
+ *out_wcstr = static_cast<wchar_t>(r);
+ }
+ *out_wcstr = 0;
+ return len;
+}
+
+size_t StrUtil::ConvertWstrToUtf8(const wchar_t *wcstr, char *out_mbstr, size_t out_sz) {
+ size_t len = 0;
+ for (size_t mb_sz = 1; *wcstr && (mb_sz > 0) && (len + mb_sz < out_sz);
+ ++wcstr, out_mbstr += mb_sz, len += mb_sz) {
+ mb_sz = Utf8::SetChar(*wcstr, out_mbstr, out_sz - len);
+ }
+ *out_mbstr = 0;
+ return len;
+}
+
} // namespace Shared
} // namespace AGS
} // namespace AGS3
diff --git a/engines/ags/shared/util/string_utils.h b/engines/ags/shared/util/string_utils.h
index c08268858f7..623961a77ed 100644
--- a/engines/ags/shared/util/string_utils.h
+++ b/engines/ags/shared/util/string_utils.h
@@ -86,6 +86,12 @@ void WriteStringMap(const StringMap &map, Stream *out);
// Convert utf-8 string to ascii/ansi representation;
// writes into out_cstr buffer limited by out_sz bytes; returns bytes written.
size_t ConvertUtf8ToAscii(const char *mbstr, const char *loc_name, char *out_cstr, size_t out_sz);
+// Convert utf-8 string to wide-string (16-bit char);
+// writes into out_wcstr buffer limited by out_sz *wchars*; returns *wchars* written.
+size_t ConvertUtf8ToWstr(const char *mbstr, wchar_t *out_wcstr, size_t out_sz);
+// Convert wide-string to utf-8 string;
+// writes into out_mbstr buffer limited by out_sz *bytes*; returns *bytes* written.
+size_t ConvertWstrToUtf8(const wchar_t *wcstr, char *out_mbstr, size_t out_sz);
} // namespace StrUtil
} // namespace Shared
Commit: 0e0063bb6bb13e6ea17938f96251a681b4c1c50d
https://github.com/scummvm/scummvm/commit/0e0063bb6bb13e6ea17938f96251a681b4c1c50d
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-13T21:55:19-07:00
Commit Message:
AGS: String.AppendChar, ReplaceChar, Chars[] support unicode
>From upstream 072ed5716639e2b65a16037dd81e2a332a78611b
Changed paths:
engines/ags/engine/ac/string.cpp
engines/ags/engine/ac/string.h
engines/ags/lib/allegro/unicode.cpp
engines/ags/lib/allegro/unicode.h
diff --git a/engines/ags/engine/ac/string.cpp b/engines/ags/engine/ac/string.cpp
index 5e32d87e8bd..dc5dda16662 100644
--- a/engines/ags/engine/ac/string.cpp
+++ b/engines/ags/engine/ac/string.cpp
@@ -22,6 +22,7 @@
#include "ags/lib/std/algorithm.h"
#include "ags/engine/ac/string.h"
#include "ags/shared/ac/common.h"
+#include "ags/shared/util/utf8.h"
#include "ags/engine/ac/display.h"
#include "ags/shared/ac/game_setup_struct.h"
#include "ags/engine/ac/game_state.h"
@@ -58,13 +59,19 @@ const char *String_Append(const char *thisString, const char *extrabit) {
return CreateNewScriptString(buffer, false);
}
-const char *String_AppendChar(const char *thisString, char extraOne) {
- char *buffer = (char *)malloc(strlen(thisString) + 2);
- sprintf(buffer, "%s%c", thisString, extraOne);
+const char *String_AppendChar(const char *thisString, int extraOne) {
+ size_t chw = 1;
+ char chr[Utf8::UtfSz + 1]{};
+ if (get_uformat() == U_UTF8)
+ chw = Utf8::SetChar(extraOne, chr, sizeof(chr));
+ else
+ chr[0] = extraOne;
+ char *buffer = (char *)malloc(strlen(thisString) + chw + 1);
+ sprintf(buffer, "%s%s", thisString, chr);
return CreateNewScriptString(buffer, false);
}
-const char *String_ReplaceCharAt(const char *thisString, int index, char newChar) {
+const char *String_ReplaceCharAt(const char *thisString, int index, int newChar) {
size_t len = ustrlen(thisString);
if ((index < 0) || ((size_t)index >= len))
quit("!String.ReplaceCharAt: index outside range of string");
@@ -73,12 +80,17 @@ const char *String_ReplaceCharAt(const char *thisString, int index, char newChar
int uchar = ugetc(thisString + off);
size_t remain_sz = strlen(thisString + off);
size_t old_sz = ucwidth(uchar);
- size_t new_sz = sizeof(char); // TODO: support unicode char in API
- size_t total_sz = off + remain_sz + new_sz - old_sz + 1;
+ size_t new_chw = 1;
+ char new_chr[Utf8::UtfSz + 1]{};
+ if (get_uformat() == U_UTF8)
+ new_chw = Utf8::SetChar(newChar, new_chr, sizeof(new_chr));
+ else
+ new_chr[0] = newChar;
+ size_t total_sz = off + remain_sz + new_chw - old_sz + 1;
char *buffer = (char *)malloc(total_sz);
memcpy(buffer, thisString, off);
- usetc(buffer + off, newChar);
- memcpy(buffer + off + new_sz, thisString + off + old_sz, remain_sz - old_sz + 1);
+ memcpy(buffer + off, new_chr, new_chw);
+ memcpy(buffer + off + new_chw, thisString + off + old_sz, remain_sz - old_sz + 1);
return CreateNewScriptString(buffer, false);
}
@@ -194,11 +206,10 @@ const char *String_UpperCase(const char *thisString) {
}
int String_GetChars(const char *texx, int index) {
- if ((index < 0) || (index >= (int)strlen(texx)))
+ if ((index < 0) || (index >= ustrlen(texx)))
return 0;
- return texx[index];
+ return ugetat(texx, index);
}
-
int StringToInt(const char *stino) {
return atoi(stino);
}
diff --git a/engines/ags/engine/ac/string.h b/engines/ags/engine/ac/string.h
index eb13551a75e..abc93a49f22 100644
--- a/engines/ags/engine/ac/string.h
+++ b/engines/ags/engine/ac/string.h
@@ -33,13 +33,13 @@ namespace AGS3 {
int String_IsNullOrEmpty(const char *thisString);
const char *String_Copy(const char *srcString);
const char *String_Append(const char *thisString, const char *extrabit);
-const char *String_AppendChar(const char *thisString, char extraOne);
-const char *String_ReplaceCharAt(const char *thisString, int index, char newChar);
+const char *String_AppendChar(const char *thisString, int extraOne);
+const char *String_ReplaceCharAt(const char *thisString, int index, int newChar);
const char *String_Truncate(const char *thisString, int length);
const char *String_Substring(const char *thisString, int index, int length);
int String_CompareTo(const char *thisString, const char *otherString, bool caseSensitive);
int String_StartsWith(const char *thisString, const char *checkForString, bool caseSensitive);
-int String_EfndsWith(const char *thisString, const char *checkForString, bool caseSensitive);
+int String_EndsWith(const char *thisString, const char *checkForString, bool caseSensitive);
const char *String_Replace(const char *thisString, const char *lookForText, const char *replaceWithText, bool caseSensitive);
const char *String_LowerCase(const char *thisString);
const char *String_UpperCase(const char *thisString);
diff --git a/engines/ags/lib/allegro/unicode.cpp b/engines/ags/lib/allegro/unicode.cpp
index 1726b7825a3..4fe5b991092 100644
--- a/engines/ags/lib/allegro/unicode.cpp
+++ b/engines/ags/lib/allegro/unicode.cpp
@@ -1206,6 +1206,11 @@ int uoffset(const char *s, int index) {
return (intptr_t)s - (intptr_t)orig;
}
+int ugetat(const char *s, int index) {
+ assert(s);
+ return ugetc(s + uoffset(s, index));
+}
+
char *ustrlwr(char *s) {
int pos = 0;
int c, lc;
diff --git a/engines/ags/lib/allegro/unicode.h b/engines/ags/lib/allegro/unicode.h
index ef1175d524e..b3310f27b99 100644
--- a/engines/ags/lib/allegro/unicode.h
+++ b/engines/ags/lib/allegro/unicode.h
@@ -113,6 +113,12 @@ extern int ustrnicmp(const char *s1, const char *s2, int n);
* last character).
*/
extern int uoffset(const char *s, int index);
+
+/* ugetat:
+ * Returns the character from the specified index within the string.
+ */
+extern int ugetat(const char *s, int idx);
+
/* ustrlwr:
* Unicode-aware version of the ANSI strlwr() function.
*/
Commit: 9fe89e4f1dae9768769c13313d4a76a8479fb952
https://github.com/scummvm/scummvm/commit/9fe89e4f1dae9768769c13313d4a76a8479fb952
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-13T21:55:19-07:00
Commit Message:
AGS: String.Format treats %c as possibly unicode
>From upstream fe4afad4edecac5724711adb1d801dfb973effff
Changed paths:
engines/ags/engine/script/script_api.cpp
diff --git a/engines/ags/engine/script/script_api.cpp b/engines/ags/engine/script/script_api.cpp
index ecef4e14c43..e478e37d82d 100644
--- a/engines/ags/engine/script/script_api.cpp
+++ b/engines/ags/engine/script/script_api.cpp
@@ -24,6 +24,7 @@
#include "ags/engine/script/runtime_script_value.h"
#include "ags/engine/script/script_api.h"
#include "ags/shared/util/math.h"
+#include "ags/shared/util/utf8.h"
#include "ags/globals.h"
namespace AGS3 {
@@ -36,6 +37,7 @@ enum FormatParseResult {
kFormatParseLiteralPercent,
kFormatParseArgInteger,
kFormatParseArgFloat,
+ kFormatParseArgCharacter,
kFormatParseArgString,
kFormatParseArgPointer,
@@ -131,9 +133,11 @@ const char *ScriptSprintf(char *buffer, size_t buf_length, const char *format,
case 'u':
case 'x':
case 'X':
- case 'c':
fmt_done = kFormatParseArgInteger;
break;
+ case 'c':
+ fmt_done = kFormatParseArgCharacter;
+ break;
case 'e':
case 'E':
case 'f':
@@ -176,15 +180,28 @@ const char *ScriptSprintf(char *buffer, size_t buf_length, const char *format,
// NOTE: snprintf is called with avail_outbuf + 1 here, because we let it use our reserved
// character for null-terminator, in case we are at the end of the buffer
*fmt_bufptr = 0; // terminate the format buffer, we are going to use it
- if (fmt_done == kFormatParseArgInteger)
- snprintf_res = snprintf(out_ptr, avail_outbuf + 1, fmtbuf, GetArgInt(sc_args, varg_ptr, arg_idx));
- else if (fmt_done == kFormatParseArgFloat)
- snprintf_res = snprintf(out_ptr, avail_outbuf + 1, fmtbuf, GetArgFloat(sc_args, varg_ptr, arg_idx));
- else {
+ switch (fmt_done) {
+ case kFormatParseArgInteger:
+ snprintf_res = snprintf(out_ptr, avail_outbuf + 1, fmtbuf, GetArgInt(sc_args, varg_ptr, arg_idx)); break;
+ case kFormatParseArgFloat:
+ snprintf_res = snprintf(out_ptr, avail_outbuf + 1, fmtbuf, GetArgFloat(sc_args, varg_ptr, arg_idx)); break;
+ case kFormatParseArgCharacter:
+ {
+ int chr = GetArgInt(sc_args, varg_ptr, arg_idx);
+ char cbuf[Utf8::UtfSz + 1]{};
+ if (get_uformat() == U_UTF8)
+ Utf8::SetChar(chr, cbuf, Utf8::UtfSz);
+ else
+ cbuf[0] = chr;
+ snprintf_res = snprintf(out_ptr, avail_outbuf + 1, "%s", cbuf);
+ break;
+ }
+ case kFormatParseArgString:
+ {
const char *p = GetArgPtr(sc_args, varg_ptr, arg_idx);
// Do extra checks for %s placeholder
if (fmt_done == kFormatParseArgString && !p) {
- if (_G(loaded_game_file_version) < kGameVersion_320) {
+ if (loaded_game_file_version < kGameVersion_320) {
// explicitly put "(null)" into the placeholder
p = "(null)";
} else {
@@ -196,6 +213,11 @@ const char *ScriptSprintf(char *buffer, size_t buf_length, const char *format,
return "";
}
snprintf_res = snprintf(out_ptr, avail_outbuf + 1, fmtbuf, p);
+ break;
+ }
+ case kFormatParseArgPointer:
+ snprintf_res = snprintf(out_ptr, avail_outbuf + 1, fmtbuf, GetArgPtr(sc_args, varg_ptr, arg_idx)); break;
+ default: /* should not happen */ break;
}
arg_idx++;
Commit: 007baa9541c8e5831316ec0efabf275f111ee925
https://github.com/scummvm/scummvm/commit/007baa9541c8e5831316ec0efabf275f111ee925
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2022-04-13T21:55:20-07:00
Commit Message:
AGS: Restore proper text format in close_translation()
>From upstream b83d8567ae76c3840784f55aa8d06ffd9a7fdf91
Changed paths:
engines/ags/engine/ac/translation.cpp
diff --git a/engines/ags/engine/ac/translation.cpp b/engines/ags/engine/ac/translation.cpp
index a00adef38da..e177d09f378 100644
--- a/engines/ags/engine/ac/translation.cpp
+++ b/engines/ags/engine/ac/translation.cpp
@@ -48,7 +48,10 @@ void close_translation() {
_G(trans_filename) = "";
// Return back to default game's encoding
- set_uformat(U_ASCII);
+ if (_GP(game).options[OPT_GAMETEXTENCODING] == 65001) // utf-8 codepage number
+ set_uformat(U_UTF8);
+ else
+ set_uformat(U_ASCII);
}
bool init_translation(const String &lang, const String &fallback_lang) {
More information about the Scummvm-git-logs
mailing list